Merge branch 'fujitsu' into release
[sfrench/cifs-2.6.git] / drivers / staging / rt3090 / ap_uapsd.h
1 /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
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.                                   *
14  *                                                                       *
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.                          *
19  *                                                                       *
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.             *
24  *                                                                       *
25  *************************************************************************
26
27     Module Name:
28     ap_uapsd.h
29
30     Abstract:
31     Miniport generic portion header file
32
33     Revision History:
34     Who         When          What
35     --------    ----------    ----------------------------------------------
36 */
37
38 /* only for UAPSD_TIMING_RECORD */
39
40 //#define UAPSD_TIMING_RECORD_FUNC
41
42 #define UAPSD_TIMING_RECORD_MAX                         1000
43 #define UAPSD_TIMING_RECORD_DISPLAY_TIMES       10
44
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
50
51 #define UAPSD_TIMING_CTRL_STOP                          0
52 #define UAPSD_TIMING_CTRL_START                         1
53 #define UAPSD_TIMING_CTRL_SUSPEND                       2
54
55 #define UAPSD_TIMESTAMP_GET(__pAd, __TimeStamp)                 \
56         {                                                                                                       \
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);                               \
63         }
64
65 #ifdef LINUX
66 #define UAPSD_TIME_GET(__pAd, __Time)                                   \
67                 __Time = jiffies
68 #endif // LINUX //
69
70
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);
80 #else
81
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 //
87
88
89 #ifndef MODULE_WMM_UAPSD
90
91 #define UAPSD_EXTERN                    extern
92
93 /* Public Marco list */
94
95 /*
96         Init some parameters in packet structure for QoS Null frame;
97         purpose: is for management frame tx done use
98 */
99 #define UAPSD_MR_QOS_NULL_HANDLE(__pAd, __pData, __pPacket)                                     \
100         {                                                                                                                                               \
101                 PHEADER_802_11 __pHeader = (PHEADER_802_11)(__pData);                           \
102                 MAC_TABLE_ENTRY *__pEntry;                                                                                      \
103                 if (__pHeader->FC.SubType == SUBTYPE_QOS_NULL)                                          \
104                 {                                                                                                                                       \
105                         RTMP_SET_PACKET_QOS_NULL((__pPacket));                                                  \
106                         __pEntry = MacTableLookup((__pAd), __pHeader->Addr1);                   \
107                         if (__pEntry != NULL)                                                                                   \
108                         {                                                                                                                               \
109                                 RTMP_SET_PACKET_WCID((__pPacket), __pEntry->Aid);                       \
110                         }                                                                                                                               \
111                 }                                                                                                                                       \
112                 else                                                                                                                            \
113                 {                                                                                                                                       \
114                         RTMP_SET_PACKET_NON_QOS_NULL((__pPacket));                                              \
115                 }                                                                                                                                       \
116         }
117
118 /*
119         Init MAC entry UAPSD parameters;
120         purpose: initialize UAPSD PS queue and control parameters
121 */
122 #define UAPSD_MR_ENTRY_INIT(__pEntry)                                                                           \
123         {                                                                                                                                               \
124                 UINT16  __IdAc;                                                                                                         \
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;                                                                            \
132         }
133
134 /*
135         Reset MAC entry UAPSD parameters;
136    purpose: clean all UAPSD PS queue; release the EOSP frame if exists;
137                         reset control parameters
138 */
139 #define UAPSD_MR_ENTRY_RESET(__pAd, __pEntry)                                                           \
140         {                                                                                                                                               \
141                 MAC_TABLE_ENTRY *__pSta;                                                                                        \
142                 UINT32 __IdAc;                                                                                                          \
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; }
156
157 /*
158         Enable or disable UAPSD flag in WMM element in beacon frame;
159         purpose: set UAPSD enable/disable bit
160 */
161 #define UAPSD_MR_IE_FILL(__QosCtrlField, __pAd)                                                         \
162                 (__QosCtrlField) |= ((__pAd)->CommonCfg.bAPSDCapable) ? 0x80 : 0x00;
163
164 /*
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
167 */
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])
175
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)])
181
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))
185
186 /* suspend SP */
187 #define UAPSD_MR_SP_SUSPEND(__pAd)                                                                                      \
188                 (__pAd)->bAPSDFlagSPSuspend = 1;
189
190 /* resume SP */
191 #define UAPSD_MR_SP_RESUME(__pAd)                                                                                       \
192                 (__pAd)->bAPSDFlagSPSuspend = 0;
193
194 /* mark PS poll frame sent in mix mode */
195 #ifdef RTMP_MAC_PCI
196 /*
197         Note:
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.
201 */
202 #define UAPSD_MR_MIX_PS_POLL_RCV(__pAd, __pMacEntry)                                            \
203                 if ((__pMacEntry)->bAPSDFlagSpRoughUse == 0)                                            \
204                 {                                                                                                                                       \
205                         if ((__pMacEntry)->bAPSDFlagSPStart == 0)                                               \
206                         {                                                                                                                               \
207                                 if ((__pMacEntry)->bAPSDFlagLegacySent == 1)                            \
208                                         NICUpdateFifoStaCounters((__pAd));                                              \
209                                 (__pMacEntry)->bAPSDFlagLegacySent = 1;                                         \
210                         }                                                                                                                               \
211                         else                                                                                                                    \
212                         {                                                                                                                               \
213                                 (__pMacEntry)->UAPSDTxNum ++;                                                           \
214                         }                                                                                                                               \
215                 }
216 #endif // RTMP_MAC_PCI //
217
218
219 #else
220
221 #define UAPSD_EXTERN
222 #define UAPSD_QOS_NULL_QUE_ID   0x7f
223
224 #ifdef RTMP_MAC_PCI
225 /*
226         In RT2870, FIFO counter is for all stations, not for per-entry,
227         so we can not use accurate method in RT2870
228 */
229
230 /*
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.
235
236                 Solution:
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.
240
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.
245
246                 Solution:
247                 Use old DMA UAPSD mechanism.
248
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.
252
253                 Solution:
254                 Cound the legacy PS packet.
255
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.
259
260                 Solution:
261                 Suspend SP handle before rx done and resume SP handle after rx done.
262 */
263 #define UAPSD_SP_ACCURATE               /* use more accurate method to send EOSP */
264 #endif // RTMP_MAC_PCI //
265
266 #define UAPSD_EPT_SP_INT                (100000/(1000000/OS_HZ)) /* 100ms */
267
268 #endif // MODULE_WMM_UAPSD //
269
270
271 /* max UAPSD buffer queue size */
272 #define MAX_PACKETS_IN_UAPSD_QUEUE      16      /* for each AC = 16*4 = 64 */
273
274
275 /* Public function list */
276 /*
277 ========================================================================
278 Routine Description:
279         UAPSD Module Init.
280
281 Arguments:
282         pAd             Pointer to our adapter
283
284 Return Value:
285         None
286
287 Note:
288 ========================================================================
289 */
290 UAPSD_EXTERN VOID UAPSD_Init(
291         IN      PRTMP_ADAPTER           pAd);
292
293
294 /*
295 ========================================================================
296 Routine Description:
297         UAPSD Module Release.
298
299 Arguments:
300         pAd             Pointer to our adapter
301
302 Return Value:
303         None
304
305 Note:
306 ========================================================================
307 */
308 UAPSD_EXTERN VOID UAPSD_Release(
309         IN      PRTMP_ADAPTER           pAd);
310
311
312 /*
313 ========================================================================
314 Routine Description:
315         Free all EOSP frames and close all SP.
316
317 Arguments:
318         pAd             Pointer to our adapter
319
320 Return Value:
321         None
322
323 Note:
324 ========================================================================
325 */
326 UAPSD_EXTERN VOID UAPSD_FreeAll(
327         IN      PRTMP_ADAPTER           pAd);
328
329
330 /*
331 ========================================================================
332 Routine Description:
333         Close current Service Period.
334
335 Arguments:
336         pAd                             Pointer to our adapter
337         pEntry                  Close the SP of the entry
338
339 Return Value:
340         None
341
342 Note:
343 ========================================================================
344 */
345 UAPSD_EXTERN VOID UAPSD_SP_Close(
346     IN  PRTMP_ADAPTER       pAd,
347         IN      MAC_TABLE_ENTRY         *pEntry);
348
349
350 /*
351 ========================================================================
352 Routine Description:
353         Deliver all queued packets.
354
355 Arguments:
356         pAd            Pointer to our adapter
357         *pEntry        STATION
358
359 Return Value:
360         None
361
362 Note:
363         SMP protection by caller for packet enqueue.
364 ========================================================================
365 */
366 UAPSD_EXTERN VOID UAPSD_AllPacketDeliver(
367         IN      PRTMP_ADAPTER           pAd,
368         IN      MAC_TABLE_ENTRY         *pEntry);
369
370
371 /*
372 ========================================================================
373 Routine Description:
374         Parse the UAPSD field in WMM element in (re)association request frame.
375
376 Arguments:
377         pAd                             Pointer to our adapter
378         *pEntry                 STATION
379         *pElm                   QoS information field
380
381 Return Value:
382         None
383
384 Note:
385         No protection is needed.
386
387         1. Association -> TSPEC:
388                 use static UAPSD settings in Association
389                 update UAPSD settings in TSPEC
390
391         2. Association -> TSPEC(11r) -> Reassociation:
392                 update UAPSD settings in TSPEC
393                 backup static UAPSD settings in Reassociation
394
395         3. Association -> Reassociation:
396                 update UAPSD settings in TSPEC
397                 backup static UAPSD settings in Reassociation
398 ========================================================================
399 */
400 UAPSD_EXTERN VOID UAPSD_AssocParse(
401         IN      PRTMP_ADAPTER           pAd,
402         IN      MAC_TABLE_ENTRY         *pEntry,
403         IN      UCHAR                           *pElm);
404
405
406 /*
407 ========================================================================
408 Routine Description:
409         Enqueue a UAPSD packet.
410
411 Arguments:
412         pAd                             Pointer to our adapter
413         *pEntry                 STATION
414         pPacket                 UAPSD dnlink packet
415         IdAc                    UAPSD AC ID (0 ~ 3)
416
417 Return Value:
418         None
419
420 Note:
421 ========================================================================
422 */
423 UAPSD_EXTERN VOID UAPSD_PacketEnqueue(
424         IN      PRTMP_ADAPTER           pAd,
425         IN      MAC_TABLE_ENTRY         *pEntry,
426         IN      PNDIS_PACKET            pPacket,
427         IN      UINT32                          IdAc);
428
429
430 /*
431 ========================================================================
432 Routine Description:
433         Handle QoS Null Frame Tx Done or Management Tx Done interrupt.
434
435 Arguments:
436         pAd                             Pointer to our adapter
437         pPacket                 Completed TX packet
438         pDstMac                 Destinated MAC address
439
440 Return Value:
441         None
442
443 Note:
444 ========================================================================
445 */
446 UAPSD_EXTERN VOID UAPSD_QoSNullTxMgmtTxDoneHandle(
447         IN      PRTMP_ADAPTER           pAd,
448         IN      PNDIS_PACKET            pPacket,
449         IN      UCHAR                           *pDstMac);
450
451
452 /*
453 ========================================================================
454 Routine Description:
455         Maintenance our UAPSD PS queue.  Release all queued packet if timeout.
456
457 Arguments:
458         pAd                             Pointer to our adapter
459         *pEntry                 STATION
460
461 Return Value:
462         None
463
464 Note:
465         If in RT2870, pEntry can not be removed during UAPSD_QueueMaintenance()
466 ========================================================================
467 */
468 UAPSD_EXTERN VOID UAPSD_QueueMaintenance(
469         IN      PRTMP_ADAPTER           pAd,
470         IN      MAC_TABLE_ENTRY         *pEntry);
471
472
473 /*
474 ========================================================================
475 Routine Description:
476         Close SP in Tx Done, not Tx DMA Done.
477
478 Arguments:
479         pAd            Pointer to our adapter
480         pEntry                  destination entry
481         FlgSuccess              0:tx success, 1:tx fail
482
483 Return Value:
484     None
485
486 Note:
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.
491
492         So if the tx rate is 1Mbps for a entry, we will use DMA done, not
493         use UAPSD_SP_AUE_Handle().
494 ========================================================================
495 */
496 UAPSD_EXTERN VOID UAPSD_SP_AUE_Handle(
497         IN RTMP_ADAPTER         *pAd,
498     IN MAC_TABLE_ENTRY  *pEntry,
499         IN UCHAR                        FlgSuccess);
500
501
502 /*
503 ========================================================================
504 Routine Description:
505         Close current Service Period.
506
507 Arguments:
508         pAd                             Pointer to our adapter
509
510 Return Value:
511         None
512
513 Note:
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.
517
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 ========================================================================
521 */
522 UAPSD_EXTERN VOID UAPSD_SP_CloseInRVDone(
523         IN      PRTMP_ADAPTER           pAd);
524
525
526 /*
527 ========================================================================
528 Routine Description:
529         Check if we need to close current SP.
530
531 Arguments:
532         pAd                             Pointer to our adapter
533         pPacket                 Completed TX packet
534         pDstMac                 Destinated MAC address
535
536 Return Value:
537         None
538
539 Note:
540         1. We need to call the function in TxDone ISR.
541         2. SMP protection by caller for packet enqueue.
542 ========================================================================
543 */
544 UAPSD_EXTERN VOID UAPSD_SP_PacketCheck(
545         IN      PRTMP_ADAPTER           pAd,
546         IN      PNDIS_PACKET            pPacket,
547         IN      UCHAR                           *pDstMac);
548
549
550 #ifdef UAPSD_TIMING_RECORD_FUNC
551 /*
552 ========================================================================
553 Routine Description:
554         Enable/Disable Timing Record Function.
555
556 Arguments:
557         pAd                             Pointer to our adapter
558         Flag                    1 (Enable) or 0 (Disable)
559
560 Return Value:
561         None
562
563 Note:
564 ========================================================================
565 */
566 UAPSD_EXTERN VOID UAPSD_TimingRecordCtrl(
567         IN      UINT32                          Flag);
568
569 /*
570 ========================================================================
571 Routine Description:
572         Record some timings.
573
574 Arguments:
575         pAd                             Pointer to our adapter
576         Type                    The timing is for what type
577
578 Return Value:
579         None
580
581 Note:
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 ========================================================================
588 */
589 UAPSD_EXTERN VOID UAPSD_TimingRecord(
590         IN      PRTMP_ADAPTER           pAd,
591         IN      UINT32                          Type);
592
593 /*
594 ========================================================================
595 Routine Description:
596         Record the loop index for received packet handle.
597
598 Arguments:
599         pAd                             Pointer to our adapter
600         LoopIndex               The RxProcessed in APRxDoneInterruptHandle()
601
602 Return Value:
603         None
604
605 Note:
606 ========================================================================
607 */
608 UAPSD_EXTERN VOID UAPSD_TimeingRecordLoopIndex(
609         IN      UINT32                          LoopIndex);
610 #endif // UAPSD_TIMING_RECORD_FUNC //
611
612
613 /*
614 ========================================================================
615 Routine Description:
616         Handle UAPSD Trigger Frame.
617
618 Arguments:
619         pAd                             Pointer to our adapter
620         *pEntry                 the source STATION
621         UpOfFrame               the UP of the trigger frame
622
623 Return Value:
624         None
625
626 Note:
627 ========================================================================
628 */
629 UAPSD_EXTERN VOID UAPSD_TriggerFrameHandle(
630         IN      PRTMP_ADAPTER           pAd,
631         IN      MAC_TABLE_ENTRY         *pEntry,
632         IN      UCHAR                           UpOfFrame);
633
634
635
636 /* End of ap_uapsd.h */