2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 *************************************************************************
31 Miniport generic portion header file
35 -------- ---------- ----------------------------------------------
38 /* only for UAPSD_TIMING_RECORD */
40 //#define UAPSD_TIMING_RECORD_FUNC
42 #define UAPSD_TIMING_RECORD_MAX 1000
43 #define UAPSD_TIMING_RECORD_DISPLAY_TIMES 10
45 #define UAPSD_TIMING_RECORD_ISR 1
46 #define UAPSD_TIMING_RECORD_TASKLET 2
47 #define UAPSD_TIMING_RECORD_TRG_RCV 3
48 #define UAPSD_TIMING_RECORD_MOVE2TX 4
49 #define UAPSD_TIMING_RECORD_TX2AIR 5
51 #define UAPSD_TIMING_CTRL_STOP 0
52 #define UAPSD_TIMING_CTRL_START 1
53 #define UAPSD_TIMING_CTRL_SUSPEND 2
55 #define UAPSD_TIMESTAMP_GET(__pAd, __TimeStamp) \
57 UINT32 __CSR=0; UINT64 __Value64; \
58 RTMP_IO_READ32((__pAd), TSF_TIMER_DW0, &__CSR); \
59 __TimeStamp = (UINT64)__CSR; \
60 RTMP_IO_READ32((__pAd), TSF_TIMER_DW1, &__CSR); \
61 __Value64 = (UINT64)__CSR; \
62 __TimeStamp |= (__Value64 << 32); \
66 #define UAPSD_TIME_GET(__pAd, __Time) \
71 #ifdef UAPSD_TIMING_RECORD_FUNC
72 #define UAPSD_TIMING_RECORD_START() \
73 UAPSD_TimingRecordCtrl(UAPSD_TIMING_CTRL_START);
74 #define UAPSD_TIMING_RECORD_STOP() \
75 UAPSD_TimingRecordCtrl(UAPSD_TIMING_CTRL_STOP);
76 #define UAPSD_TIMING_RECORD(__pAd, __Type) \
77 UAPSD_TimingRecord(__pAd, __Type);
78 #define UAPSD_TIMING_RECORD_INDEX(__LoopIndex) \
79 UAPSD_TimeingRecordLoopIndex(__LoopIndex);
82 #define UAPSD_TIMING_RECORD_START()
83 #define UAPSD_TIMING_RECORD_STOP()
84 #define UAPSD_TIMING_RECORD(__pAd, __type)
85 #define UAPSD_TIMING_RECORD_INDEX(__LoopIndex)
86 #endif // UAPSD_TIMING_RECORD_FUNC //
89 #ifndef MODULE_WMM_UAPSD
91 #define UAPSD_EXTERN extern
93 /* Public Marco list */
96 Init some parameters in packet structure for QoS Null frame;
97 purpose: is for management frame tx done use
99 #define UAPSD_MR_QOS_NULL_HANDLE(__pAd, __pData, __pPacket) \
101 PHEADER_802_11 __pHeader = (PHEADER_802_11)(__pData); \
102 MAC_TABLE_ENTRY *__pEntry; \
103 if (__pHeader->FC.SubType == SUBTYPE_QOS_NULL) \
105 RTMP_SET_PACKET_QOS_NULL((__pPacket)); \
106 __pEntry = MacTableLookup((__pAd), __pHeader->Addr1); \
107 if (__pEntry != NULL) \
109 RTMP_SET_PACKET_WCID((__pPacket), __pEntry->Aid); \
114 RTMP_SET_PACKET_NON_QOS_NULL((__pPacket)); \
119 Init MAC entry UAPSD parameters;
120 purpose: initialize UAPSD PS queue and control parameters
122 #define UAPSD_MR_ENTRY_INIT(__pEntry) \
125 for(__IdAc=0; __IdAc<WMM_NUM_OF_AC; __IdAc++) \
126 InitializeQueueHeader(&(__pEntry)->UAPSDQueue[__IdAc]); \
127 (__pEntry)->UAPSDTxNum = 0; \
128 (__pEntry)->pUAPSDEOSPFrame = NULL; \
129 (__pEntry)->bAPSDFlagSPStart = 0; \
130 (__pEntry)->bAPSDFlagEOSPOK = 0; \
131 (__pEntry)->MaxSPLength = 0; \
135 Reset MAC entry UAPSD parameters;
136 purpose: clean all UAPSD PS queue; release the EOSP frame if exists;
137 reset control parameters
139 #define UAPSD_MR_ENTRY_RESET(__pAd, __pEntry) \
141 MAC_TABLE_ENTRY *__pSta; \
143 __pSta = (__pEntry); \
144 /* clear all U-APSD queues */ \
145 for(__IdAc=0; __IdAc<WMM_NUM_OF_AC; __IdAc++) \
146 APCleanupPsQueue((__pAd), &__pSta->UAPSDQueue[__IdAc]); \
147 /* clear EOSP frame */ \
148 __pSta->UAPSDTxNum = 0; \
149 if (__pSta->pUAPSDEOSPFrame != NULL) { \
150 RELEASE_NDIS_PACKET((__pAd), \
151 QUEUE_ENTRY_TO_PACKET(__pSta->pUAPSDEOSPFrame), \
152 NDIS_STATUS_FAILURE); \
153 __pSta->pUAPSDEOSPFrame = NULL; } \
154 __pSta->bAPSDFlagSPStart = 0; \
155 __pSta->bAPSDFlagEOSPOK = 0; }
158 Enable or disable UAPSD flag in WMM element in beacon frame;
159 purpose: set UAPSD enable/disable bit
161 #define UAPSD_MR_IE_FILL(__QosCtrlField, __pAd) \
162 (__QosCtrlField) |= ((__pAd)->CommonCfg.bAPSDCapable) ? 0x80 : 0x00;
165 Check if we do NOT need to control TIM bit for the station;
166 note: we control TIM bit only when all AC are UAPSD AC
168 #define UAPSD_MR_IS_NOT_TIM_BIT_NEEDED_HANDLED(__pMacEntry, __QueIdx) \
169 (CLIENT_STATUS_TEST_FLAG((__pMacEntry), fCLIENT_STATUS_APSD_CAPABLE) && \
170 (!(__pMacEntry)->bAPSDDeliverEnabledPerAC[QID_AC_VO] || \
171 !(__pMacEntry)->bAPSDDeliverEnabledPerAC[QID_AC_VI] || \
172 !(__pMacEntry)->bAPSDDeliverEnabledPerAC[QID_AC_BE] || \
173 !(__pMacEntry)->bAPSDDeliverEnabledPerAC[QID_AC_BK]) && \
174 (__pMacEntry)->bAPSDDeliverEnabledPerAC[__QueIdx])
176 /* check if the AC is UAPSD delivery-enabled AC */
177 #define UAPSD_MR_IS_UAPSD_AC(__pMacEntry, __AcId) \
178 (CLIENT_STATUS_TEST_FLAG((__pMacEntry), fCLIENT_STATUS_APSD_CAPABLE) && \
179 ((0 <= (__AcId)) && ((__AcId) < WMM_NUM_OF_AC)) && /* 0 ~ 3 */ \
180 (__pMacEntry)->bAPSDDeliverEnabledPerAC[(__AcId)])
182 /* check if all AC are UAPSD delivery-enabled AC */
183 #define UAPSD_MR_IS_ALL_AC_UAPSD(__FlgIsActive, __pMacEntry) \
184 (((__FlgIsActive) == FALSE) && ((__pMacEntry)->bAPSDAllAC == 1))
187 #define UAPSD_MR_SP_SUSPEND(__pAd) \
188 (__pAd)->bAPSDFlagSPSuspend = 1;
191 #define UAPSD_MR_SP_RESUME(__pAd) \
192 (__pAd)->bAPSDFlagSPSuspend = 0;
194 /* mark PS poll frame sent in mix mode */
198 (1) When SP is not started, try to mark a flag to record if the legacy ps
199 packet is handled in statistics handler;
200 (2) When SP is started, increase the UAPSD count number for the legacy PS.
202 #define UAPSD_MR_MIX_PS_POLL_RCV(__pAd, __pMacEntry) \
203 if ((__pMacEntry)->bAPSDFlagSpRoughUse == 0) \
205 if ((__pMacEntry)->bAPSDFlagSPStart == 0) \
207 if ((__pMacEntry)->bAPSDFlagLegacySent == 1) \
208 NICUpdateFifoStaCounters((__pAd)); \
209 (__pMacEntry)->bAPSDFlagLegacySent = 1; \
213 (__pMacEntry)->UAPSDTxNum ++; \
216 #endif // RTMP_MAC_PCI //
222 #define UAPSD_QOS_NULL_QUE_ID 0x7f
226 In RT2870, FIFO counter is for all stations, not for per-entry,
227 so we can not use accurate method in RT2870
231 Note for SP ACCURATE Mechanism:
232 1. When traffic is busy for the PS station
233 Statistics FIFO counter maybe overflow before we read it, so UAPSD
234 counting mechanism will not accurately.
237 We need to avoid the worse case so we suggest a maximum interval for
238 a SP that the interval between last frame from QAP and data frame from
239 QSTA is larger than UAPSD_EPT_SP_INT.
241 2. When traffic use CCK/1Mbps from QAP
242 Statistics FIFO will not count the packet. There are 2 cases:
243 (1) We force to downgrage ARP response & DHCP packet to 1Mbps;
244 (2) After rate switch mechanism, tx rate is fixed to 1Mbps.
247 Use old DMA UAPSD mechanism.
249 3. When part of AC uses legacy PS mode
250 Statistics count will inclue packet statistics for legacy PS packets
251 so we can not know which one is UAPSD, which one is legacy.
254 Cound the legacy PS packet.
256 4. Check FIFO statistics count in Rx Done function
257 We can not to check TX FIFO statistics count in Rx Done function or
258 the real packet tx/rx sequence will be disarranged.
261 Suspend SP handle before rx done and resume SP handle after rx done.
263 #define UAPSD_SP_ACCURATE /* use more accurate method to send EOSP */
264 #endif // RTMP_MAC_PCI //
266 #define UAPSD_EPT_SP_INT (100000/(1000000/OS_HZ)) /* 100ms */
268 #endif // MODULE_WMM_UAPSD //
271 /* max UAPSD buffer queue size */
272 #define MAX_PACKETS_IN_UAPSD_QUEUE 16 /* for each AC = 16*4 = 64 */
275 /* Public function list */
277 ========================================================================
282 pAd Pointer to our adapter
288 ========================================================================
290 UAPSD_EXTERN VOID
UAPSD_Init(
291 IN PRTMP_ADAPTER pAd
);
295 ========================================================================
297 UAPSD Module Release.
300 pAd Pointer to our adapter
306 ========================================================================
308 UAPSD_EXTERN VOID
UAPSD_Release(
309 IN PRTMP_ADAPTER pAd
);
313 ========================================================================
315 Free all EOSP frames and close all SP.
318 pAd Pointer to our adapter
324 ========================================================================
326 UAPSD_EXTERN VOID
UAPSD_FreeAll(
327 IN PRTMP_ADAPTER pAd
);
331 ========================================================================
333 Close current Service Period.
336 pAd Pointer to our adapter
337 pEntry Close the SP of the entry
343 ========================================================================
345 UAPSD_EXTERN VOID
UAPSD_SP_Close(
346 IN PRTMP_ADAPTER pAd
,
347 IN MAC_TABLE_ENTRY
*pEntry
);
351 ========================================================================
353 Deliver all queued packets.
356 pAd Pointer to our adapter
363 SMP protection by caller for packet enqueue.
364 ========================================================================
366 UAPSD_EXTERN VOID
UAPSD_AllPacketDeliver(
367 IN PRTMP_ADAPTER pAd
,
368 IN MAC_TABLE_ENTRY
*pEntry
);
372 ========================================================================
374 Parse the UAPSD field in WMM element in (re)association request frame.
377 pAd Pointer to our adapter
379 *pElm QoS information field
385 No protection is needed.
387 1. Association -> TSPEC:
388 use static UAPSD settings in Association
389 update UAPSD settings in TSPEC
391 2. Association -> TSPEC(11r) -> Reassociation:
392 update UAPSD settings in TSPEC
393 backup static UAPSD settings in Reassociation
395 3. Association -> Reassociation:
396 update UAPSD settings in TSPEC
397 backup static UAPSD settings in Reassociation
398 ========================================================================
400 UAPSD_EXTERN VOID
UAPSD_AssocParse(
401 IN PRTMP_ADAPTER pAd
,
402 IN MAC_TABLE_ENTRY
*pEntry
,
407 ========================================================================
409 Enqueue a UAPSD packet.
412 pAd Pointer to our adapter
414 pPacket UAPSD dnlink packet
415 IdAc UAPSD AC ID (0 ~ 3)
421 ========================================================================
423 UAPSD_EXTERN VOID
UAPSD_PacketEnqueue(
424 IN PRTMP_ADAPTER pAd
,
425 IN MAC_TABLE_ENTRY
*pEntry
,
426 IN PNDIS_PACKET pPacket
,
431 ========================================================================
433 Handle QoS Null Frame Tx Done or Management Tx Done interrupt.
436 pAd Pointer to our adapter
437 pPacket Completed TX packet
438 pDstMac Destinated MAC address
444 ========================================================================
446 UAPSD_EXTERN VOID
UAPSD_QoSNullTxMgmtTxDoneHandle(
447 IN PRTMP_ADAPTER pAd
,
448 IN PNDIS_PACKET pPacket
,
453 ========================================================================
455 Maintenance our UAPSD PS queue. Release all queued packet if timeout.
458 pAd Pointer to our adapter
465 If in RT2870, pEntry can not be removed during UAPSD_QueueMaintenance()
466 ========================================================================
468 UAPSD_EXTERN VOID
UAPSD_QueueMaintenance(
469 IN PRTMP_ADAPTER pAd
,
470 IN MAC_TABLE_ENTRY
*pEntry
);
474 ========================================================================
476 Close SP in Tx Done, not Tx DMA Done.
479 pAd Pointer to our adapter
480 pEntry destination entry
481 FlgSuccess 0:tx success, 1:tx fail
487 For RT28xx series, for packetID=0 or multicast frame, no statistics
488 count can be got, ex: ARP response or DHCP packets, we will use
489 low rate to set (CCK, MCS=0=packetID).
490 So SP will not be close until UAPSD_EPT_SP_INT timeout.
492 So if the tx rate is 1Mbps for a entry, we will use DMA done, not
493 use UAPSD_SP_AUE_Handle().
494 ========================================================================
496 UAPSD_EXTERN VOID
UAPSD_SP_AUE_Handle(
497 IN RTMP_ADAPTER
*pAd
,
498 IN MAC_TABLE_ENTRY
*pEntry
,
499 IN UCHAR FlgSuccess
);
503 ========================================================================
505 Close current Service Period.
508 pAd Pointer to our adapter
514 When we receive EOSP frame tx done interrupt and a uplink packet
515 from the station simultaneously, we will regard it as a new trigger
516 frame because the packet is received when EOSP frame tx done interrupt.
518 We can not sure the uplink packet is sent after old SP or in the old SP.
519 So we must close the old SP in receive done ISR to avoid the problem.
520 ========================================================================
522 UAPSD_EXTERN VOID
UAPSD_SP_CloseInRVDone(
523 IN PRTMP_ADAPTER pAd
);
527 ========================================================================
529 Check if we need to close current SP.
532 pAd Pointer to our adapter
533 pPacket Completed TX packet
534 pDstMac Destinated MAC address
540 1. We need to call the function in TxDone ISR.
541 2. SMP protection by caller for packet enqueue.
542 ========================================================================
544 UAPSD_EXTERN VOID
UAPSD_SP_PacketCheck(
545 IN PRTMP_ADAPTER pAd
,
546 IN PNDIS_PACKET pPacket
,
550 #ifdef UAPSD_TIMING_RECORD_FUNC
552 ========================================================================
554 Enable/Disable Timing Record Function.
557 pAd Pointer to our adapter
558 Flag 1 (Enable) or 0 (Disable)
564 ========================================================================
566 UAPSD_EXTERN VOID
UAPSD_TimingRecordCtrl(
570 ========================================================================
575 pAd Pointer to our adapter
576 Type The timing is for what type
582 UAPSD_TIMING_RECORD_ISR
583 UAPSD_TIMING_RECORD_TASKLET
584 UAPSD_TIMING_RECORD_TRG_RCV
585 UAPSD_TIMING_RECORD_MOVE2TX
586 UAPSD_TIMING_RECORD_TX2AIR
587 ========================================================================
589 UAPSD_EXTERN VOID
UAPSD_TimingRecord(
590 IN PRTMP_ADAPTER pAd
,
594 ========================================================================
596 Record the loop index for received packet handle.
599 pAd Pointer to our adapter
600 LoopIndex The RxProcessed in APRxDoneInterruptHandle()
606 ========================================================================
608 UAPSD_EXTERN VOID
UAPSD_TimeingRecordLoopIndex(
609 IN UINT32 LoopIndex
);
610 #endif // UAPSD_TIMING_RECORD_FUNC //
614 ========================================================================
616 Handle UAPSD Trigger Frame.
619 pAd Pointer to our adapter
620 *pEntry the source STATION
621 UpOfFrame the UP of the trigger frame
627 ========================================================================
629 UAPSD_EXTERN VOID
UAPSD_TriggerFrameHandle(
630 IN PRTMP_ADAPTER pAd
,
631 IN MAC_TABLE_ENTRY
*pEntry
,
636 /* End of ap_uapsd.h */