diff options
Diffstat (limited to 'drivers/staging/rt3090/ap_uapsd.h')
-rw-r--r-- | drivers/staging/rt3090/ap_uapsd.h | 636 |
1 files changed, 636 insertions, 0 deletions
diff --git a/drivers/staging/rt3090/ap_uapsd.h b/drivers/staging/rt3090/ap_uapsd.h new file mode 100644 index 0000000..d49a9e7 --- /dev/null +++ b/drivers/staging/rt3090/ap_uapsd.h @@ -0,0 +1,636 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + ap_uapsd.h + + Abstract: + Miniport generic portion header file + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + +/* only for UAPSD_TIMING_RECORD */ + +//#define UAPSD_TIMING_RECORD_FUNC + +#define UAPSD_TIMING_RECORD_MAX 1000 +#define UAPSD_TIMING_RECORD_DISPLAY_TIMES 10 + +#define UAPSD_TIMING_RECORD_ISR 1 +#define UAPSD_TIMING_RECORD_TASKLET 2 +#define UAPSD_TIMING_RECORD_TRG_RCV 3 +#define UAPSD_TIMING_RECORD_MOVE2TX 4 +#define UAPSD_TIMING_RECORD_TX2AIR 5 + +#define UAPSD_TIMING_CTRL_STOP 0 +#define UAPSD_TIMING_CTRL_START 1 +#define UAPSD_TIMING_CTRL_SUSPEND 2 + +#define UAPSD_TIMESTAMP_GET(__pAd, __TimeStamp) \ + { \ + UINT32 __CSR=0; UINT64 __Value64; \ + RTMP_IO_READ32((__pAd), TSF_TIMER_DW0, &__CSR); \ + __TimeStamp = (UINT64)__CSR; \ + RTMP_IO_READ32((__pAd), TSF_TIMER_DW1, &__CSR); \ + __Value64 = (UINT64)__CSR; \ + __TimeStamp |= (__Value64 << 32); \ + } + +#ifdef LINUX +#define UAPSD_TIME_GET(__pAd, __Time) \ + __Time = jiffies +#endif // LINUX // + + +#ifdef UAPSD_TIMING_RECORD_FUNC +#define UAPSD_TIMING_RECORD_START() \ + UAPSD_TimingRecordCtrl(UAPSD_TIMING_CTRL_START); +#define UAPSD_TIMING_RECORD_STOP() \ + UAPSD_TimingRecordCtrl(UAPSD_TIMING_CTRL_STOP); +#define UAPSD_TIMING_RECORD(__pAd, __Type) \ + UAPSD_TimingRecord(__pAd, __Type); +#define UAPSD_TIMING_RECORD_INDEX(__LoopIndex) \ + UAPSD_TimeingRecordLoopIndex(__LoopIndex); +#else + +#define UAPSD_TIMING_RECORD_START() +#define UAPSD_TIMING_RECORD_STOP() +#define UAPSD_TIMING_RECORD(__pAd, __type) +#define UAPSD_TIMING_RECORD_INDEX(__LoopIndex) +#endif // UAPSD_TIMING_RECORD_FUNC // + + +#ifndef MODULE_WMM_UAPSD + +#define UAPSD_EXTERN extern + +/* Public Marco list */ + +/* + Init some parameters in packet structure for QoS Null frame; + purpose: is for management frame tx done use +*/ +#define UAPSD_MR_QOS_NULL_HANDLE(__pAd, __pData, __pPacket) \ + { \ + PHEADER_802_11 __pHeader = (PHEADER_802_11)(__pData); \ + MAC_TABLE_ENTRY *__pEntry; \ + if (__pHeader->FC.SubType == SUBTYPE_QOS_NULL) \ + { \ + RTMP_SET_PACKET_QOS_NULL((__pPacket)); \ + __pEntry = MacTableLookup((__pAd), __pHeader->Addr1); \ + if (__pEntry != NULL) \ + { \ + RTMP_SET_PACKET_WCID((__pPacket), __pEntry->Aid); \ + } \ + } \ + else \ + { \ + RTMP_SET_PACKET_NON_QOS_NULL((__pPacket)); \ + } \ + } + +/* + Init MAC entry UAPSD parameters; + purpose: initialize UAPSD PS queue and control parameters +*/ +#define UAPSD_MR_ENTRY_INIT(__pEntry) \ + { \ + UINT16 __IdAc; \ + for(__IdAc=0; __IdAc<WMM_NUM_OF_AC; __IdAc++) \ + InitializeQueueHeader(&(__pEntry)->UAPSDQueue[__IdAc]); \ + (__pEntry)->UAPSDTxNum = 0; \ + (__pEntry)->pUAPSDEOSPFrame = NULL; \ + (__pEntry)->bAPSDFlagSPStart = 0; \ + (__pEntry)->bAPSDFlagEOSPOK = 0; \ + (__pEntry)->MaxSPLength = 0; \ + } + +/* + Reset MAC entry UAPSD parameters; + purpose: clean all UAPSD PS queue; release the EOSP frame if exists; + reset control parameters +*/ +#define UAPSD_MR_ENTRY_RESET(__pAd, __pEntry) \ + { \ + MAC_TABLE_ENTRY *__pSta; \ + UINT32 __IdAc; \ + __pSta = (__pEntry); \ + /* clear all U-APSD queues */ \ + for(__IdAc=0; __IdAc<WMM_NUM_OF_AC; __IdAc++) \ + APCleanupPsQueue((__pAd), &__pSta->UAPSDQueue[__IdAc]); \ + /* clear EOSP frame */ \ + __pSta->UAPSDTxNum = 0; \ + if (__pSta->pUAPSDEOSPFrame != NULL) { \ + RELEASE_NDIS_PACKET((__pAd), \ + QUEUE_ENTRY_TO_PACKET(__pSta->pUAPSDEOSPFrame), \ + NDIS_STATUS_FAILURE); \ + __pSta->pUAPSDEOSPFrame = NULL; } \ + __pSta->bAPSDFlagSPStart = 0; \ + __pSta->bAPSDFlagEOSPOK = 0; } + +/* + Enable or disable UAPSD flag in WMM element in beacon frame; + purpose: set UAPSD enable/disable bit +*/ +#define UAPSD_MR_IE_FILL(__QosCtrlField, __pAd) \ + (__QosCtrlField) |= ((__pAd)->CommonCfg.bAPSDCapable) ? 0x80 : 0x00; + +/* + Check if we do NOT need to control TIM bit for the station; + note: we control TIM bit only when all AC are UAPSD AC +*/ +#define UAPSD_MR_IS_NOT_TIM_BIT_NEEDED_HANDLED(__pMacEntry, __QueIdx) \ + (CLIENT_STATUS_TEST_FLAG((__pMacEntry), fCLIENT_STATUS_APSD_CAPABLE) && \ + (!(__pMacEntry)->bAPSDDeliverEnabledPerAC[QID_AC_VO] || \ + !(__pMacEntry)->bAPSDDeliverEnabledPerAC[QID_AC_VI] || \ + !(__pMacEntry)->bAPSDDeliverEnabledPerAC[QID_AC_BE] || \ + !(__pMacEntry)->bAPSDDeliverEnabledPerAC[QID_AC_BK]) && \ + (__pMacEntry)->bAPSDDeliverEnabledPerAC[__QueIdx]) + +/* check if the AC is UAPSD delivery-enabled AC */ +#define UAPSD_MR_IS_UAPSD_AC(__pMacEntry, __AcId) \ + (CLIENT_STATUS_TEST_FLAG((__pMacEntry), fCLIENT_STATUS_APSD_CAPABLE) && \ + ((0 <= (__AcId)) && ((__AcId) < WMM_NUM_OF_AC)) && /* 0 ~ 3 */ \ + (__pMacEntry)->bAPSDDeliverEnabledPerAC[(__AcId)]) + +/* check if all AC are UAPSD delivery-enabled AC */ +#define UAPSD_MR_IS_ALL_AC_UAPSD(__FlgIsActive, __pMacEntry) \ + (((__FlgIsActive) == FALSE) && ((__pMacEntry)->bAPSDAllAC == 1)) + +/* suspend SP */ +#define UAPSD_MR_SP_SUSPEND(__pAd) \ + (__pAd)->bAPSDFlagSPSuspend = 1; + +/* resume SP */ +#define UAPSD_MR_SP_RESUME(__pAd) \ + (__pAd)->bAPSDFlagSPSuspend = 0; + +/* mark PS poll frame sent in mix mode */ +#ifdef RTMP_MAC_PCI +/* + Note: + (1) When SP is not started, try to mark a flag to record if the legacy ps + packet is handled in statistics handler; + (2) When SP is started, increase the UAPSD count number for the legacy PS. +*/ +#define UAPSD_MR_MIX_PS_POLL_RCV(__pAd, __pMacEntry) \ + if ((__pMacEntry)->bAPSDFlagSpRoughUse == 0) \ + { \ + if ((__pMacEntry)->bAPSDFlagSPStart == 0) \ + { \ + if ((__pMacEntry)->bAPSDFlagLegacySent == 1) \ + NICUpdateFifoStaCounters((__pAd)); \ + (__pMacEntry)->bAPSDFlagLegacySent = 1; \ + } \ + else \ + { \ + (__pMacEntry)->UAPSDTxNum ++; \ + } \ + } +#endif // RTMP_MAC_PCI // + + +#else + +#define UAPSD_EXTERN +#define UAPSD_QOS_NULL_QUE_ID 0x7f + +#ifdef RTMP_MAC_PCI +/* + In RT2870, FIFO counter is for all stations, not for per-entry, + so we can not use accurate method in RT2870 +*/ + +/* + Note for SP ACCURATE Mechanism: + 1. When traffic is busy for the PS station + Statistics FIFO counter maybe overflow before we read it, so UAPSD + counting mechanism will not accurately. + + Solution: + We need to avoid the worse case so we suggest a maximum interval for + a SP that the interval between last frame from QAP and data frame from + QSTA is larger than UAPSD_EPT_SP_INT. + + 2. When traffic use CCK/1Mbps from QAP + Statistics FIFO will not count the packet. There are 2 cases: + (1) We force to downgrage ARP response & DHCP packet to 1Mbps; + (2) After rate switch mechanism, tx rate is fixed to 1Mbps. + + Solution: + Use old DMA UAPSD mechanism. + + 3. When part of AC uses legacy PS mode + Statistics count will inclue packet statistics for legacy PS packets + so we can not know which one is UAPSD, which one is legacy. + + Solution: + Cound the legacy PS packet. + + 4. Check FIFO statistics count in Rx Done function + We can not to check TX FIFO statistics count in Rx Done function or + the real packet tx/rx sequence will be disarranged. + + Solution: + Suspend SP handle before rx done and resume SP handle after rx done. +*/ +#define UAPSD_SP_ACCURATE /* use more accurate method to send EOSP */ +#endif // RTMP_MAC_PCI // + +#define UAPSD_EPT_SP_INT (100000/(1000000/OS_HZ)) /* 100ms */ + +#endif // MODULE_WMM_UAPSD // + + +/* max UAPSD buffer queue size */ +#define MAX_PACKETS_IN_UAPSD_QUEUE 16 /* for each AC = 16*4 = 64 */ + + +/* Public function list */ +/* +======================================================================== +Routine Description: + UAPSD Module Init. + +Arguments: + pAd Pointer to our adapter + +Return Value: + None + +Note: +======================================================================== +*/ +UAPSD_EXTERN VOID UAPSD_Init( + IN PRTMP_ADAPTER pAd); + + +/* +======================================================================== +Routine Description: + UAPSD Module Release. + +Arguments: + pAd Pointer to our adapter + +Return Value: + None + +Note: +======================================================================== +*/ +UAPSD_EXTERN VOID UAPSD_Release( + IN PRTMP_ADAPTER pAd); + + +/* +======================================================================== +Routine Description: + Free all EOSP frames and close all SP. + +Arguments: + pAd Pointer to our adapter + +Return Value: + None + +Note: +======================================================================== +*/ +UAPSD_EXTERN VOID UAPSD_FreeAll( + IN PRTMP_ADAPTER pAd); + + +/* +======================================================================== +Routine Description: + Close current Service Period. + +Arguments: + pAd Pointer to our adapter + pEntry Close the SP of the entry + +Return Value: + None + +Note: +======================================================================== +*/ +UAPSD_EXTERN VOID UAPSD_SP_Close( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry); + + +/* +======================================================================== +Routine Description: + Deliver all queued packets. + +Arguments: + pAd Pointer to our adapter + *pEntry STATION + +Return Value: + None + +Note: + SMP protection by caller for packet enqueue. +======================================================================== +*/ +UAPSD_EXTERN VOID UAPSD_AllPacketDeliver( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry); + + +/* +======================================================================== +Routine Description: + Parse the UAPSD field in WMM element in (re)association request frame. + +Arguments: + pAd Pointer to our adapter + *pEntry STATION + *pElm QoS information field + +Return Value: + None + +Note: + No protection is needed. + + 1. Association -> TSPEC: + use static UAPSD settings in Association + update UAPSD settings in TSPEC + + 2. Association -> TSPEC(11r) -> Reassociation: + update UAPSD settings in TSPEC + backup static UAPSD settings in Reassociation + + 3. Association -> Reassociation: + update UAPSD settings in TSPEC + backup static UAPSD settings in Reassociation +======================================================================== +*/ +UAPSD_EXTERN VOID UAPSD_AssocParse( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN UCHAR *pElm); + + +/* +======================================================================== +Routine Description: + Enqueue a UAPSD packet. + +Arguments: + pAd Pointer to our adapter + *pEntry STATION + pPacket UAPSD dnlink packet + IdAc UAPSD AC ID (0 ~ 3) + +Return Value: + None + +Note: +======================================================================== +*/ +UAPSD_EXTERN VOID UAPSD_PacketEnqueue( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN PNDIS_PACKET pPacket, + IN UINT32 IdAc); + + +/* +======================================================================== +Routine Description: + Handle QoS Null Frame Tx Done or Management Tx Done interrupt. + +Arguments: + pAd Pointer to our adapter + pPacket Completed TX packet + pDstMac Destinated MAC address + +Return Value: + None + +Note: +======================================================================== +*/ +UAPSD_EXTERN VOID UAPSD_QoSNullTxMgmtTxDoneHandle( + IN PRTMP_ADAPTER pAd, + IN PNDIS_PACKET pPacket, + IN UCHAR *pDstMac); + + +/* +======================================================================== +Routine Description: + Maintenance our UAPSD PS queue. Release all queued packet if timeout. + +Arguments: + pAd Pointer to our adapter + *pEntry STATION + +Return Value: + None + +Note: + If in RT2870, pEntry can not be removed during UAPSD_QueueMaintenance() +======================================================================== +*/ +UAPSD_EXTERN VOID UAPSD_QueueMaintenance( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry); + + +/* +======================================================================== +Routine Description: + Close SP in Tx Done, not Tx DMA Done. + +Arguments: + pAd Pointer to our adapter + pEntry destination entry + FlgSuccess 0:tx success, 1:tx fail + +Return Value: + None + +Note: + For RT28xx series, for packetID=0 or multicast frame, no statistics + count can be got, ex: ARP response or DHCP packets, we will use + low rate to set (CCK, MCS=0=packetID). + So SP will not be close until UAPSD_EPT_SP_INT timeout. + + So if the tx rate is 1Mbps for a entry, we will use DMA done, not + use UAPSD_SP_AUE_Handle(). +======================================================================== +*/ +UAPSD_EXTERN VOID UAPSD_SP_AUE_Handle( + IN RTMP_ADAPTER *pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN UCHAR FlgSuccess); + + +/* +======================================================================== +Routine Description: + Close current Service Period. + +Arguments: + pAd Pointer to our adapter + +Return Value: + None + +Note: + When we receive EOSP frame tx done interrupt and a uplink packet + from the station simultaneously, we will regard it as a new trigger + frame because the packet is received when EOSP frame tx done interrupt. + + We can not sure the uplink packet is sent after old SP or in the old SP. + So we must close the old SP in receive done ISR to avoid the problem. +======================================================================== +*/ +UAPSD_EXTERN VOID UAPSD_SP_CloseInRVDone( + IN PRTMP_ADAPTER pAd); + + +/* +======================================================================== +Routine Description: + Check if we need to close current SP. + +Arguments: + pAd Pointer to our adapter + pPacket Completed TX packet + pDstMac Destinated MAC address + +Return Value: + None + +Note: + 1. We need to call the function in TxDone ISR. + 2. SMP protection by caller for packet enqueue. +======================================================================== +*/ +UAPSD_EXTERN VOID UAPSD_SP_PacketCheck( + IN PRTMP_ADAPTER pAd, + IN PNDIS_PACKET pPacket, + IN UCHAR *pDstMac); + + +#ifdef UAPSD_TIMING_RECORD_FUNC +/* +======================================================================== +Routine Description: + Enable/Disable Timing Record Function. + +Arguments: + pAd Pointer to our adapter + Flag 1 (Enable) or 0 (Disable) + +Return Value: + None + +Note: +======================================================================== +*/ +UAPSD_EXTERN VOID UAPSD_TimingRecordCtrl( + IN UINT32 Flag); + +/* +======================================================================== +Routine Description: + Record some timings. + +Arguments: + pAd Pointer to our adapter + Type The timing is for what type + +Return Value: + None + +Note: + UAPSD_TIMING_RECORD_ISR + UAPSD_TIMING_RECORD_TASKLET + UAPSD_TIMING_RECORD_TRG_RCV + UAPSD_TIMING_RECORD_MOVE2TX + UAPSD_TIMING_RECORD_TX2AIR +======================================================================== +*/ +UAPSD_EXTERN VOID UAPSD_TimingRecord( + IN PRTMP_ADAPTER pAd, + IN UINT32 Type); + +/* +======================================================================== +Routine Description: + Record the loop index for received packet handle. + +Arguments: + pAd Pointer to our adapter + LoopIndex The RxProcessed in APRxDoneInterruptHandle() + +Return Value: + None + +Note: +======================================================================== +*/ +UAPSD_EXTERN VOID UAPSD_TimeingRecordLoopIndex( + IN UINT32 LoopIndex); +#endif // UAPSD_TIMING_RECORD_FUNC // + + +/* +======================================================================== +Routine Description: + Handle UAPSD Trigger Frame. + +Arguments: + pAd Pointer to our adapter + *pEntry the source STATION + UpOfFrame the UP of the trigger frame + +Return Value: + None + +Note: +======================================================================== +*/ +UAPSD_EXTERN VOID UAPSD_TriggerFrameHandle( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN UCHAR UpOfFrame); + + + +/* End of ap_uapsd.h */ |