Merge branch 'for-2.6.31' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6
[pandora-kernel.git] / drivers / staging / rt2860 / common / cmm_data.c
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
28 #include "../rt_config.h"
29
30 #define MAX_TX_IN_TBTT          (16)
31
32
33 UCHAR   SNAP_802_1H[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
34 UCHAR   SNAP_BRIDGE_TUNNEL[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8};
35 // Add Cisco Aironet SNAP heade for CCX2 support
36 UCHAR   SNAP_AIRONET[] = {0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x00};
37 UCHAR   CKIP_LLC_SNAP[] = {0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02};
38 UCHAR   EAPOL_LLC_SNAP[]= {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e};
39 UCHAR   EAPOL[] = {0x88, 0x8e};
40 UCHAR   TPID[] = {0x81, 0x00}; /* VLAN related */
41
42 UCHAR   IPX[] = {0x81, 0x37};
43 UCHAR   APPLE_TALK[] = {0x80, 0xf3};
44 UCHAR   RateIdToPlcpSignal[12] = {
45          0, /* RATE_1 */        1, /* RATE_2 */         2, /* RATE_5_5 */       3, /* RATE_11 */        // see BBP spec
46         11, /* RATE_6 */   15, /* RATE_9 */    10, /* RATE_12 */   14, /* RATE_18 */    // see IEEE802.11a-1999 p.14
47          9, /* RATE_24 */  13, /* RATE_36 */    8, /* RATE_48 */   12  /* RATE_54 */ }; // see IEEE802.11a-1999 p.14
48
49 UCHAR    OfdmSignalToRateId[16] = {
50         RATE_54,  RATE_54,      RATE_54,  RATE_54,      // OFDM PLCP Signal = 0,  1,  2,  3 respectively
51         RATE_54,  RATE_54,      RATE_54,  RATE_54,      // OFDM PLCP Signal = 4,  5,  6,  7 respectively
52         RATE_48,  RATE_24,      RATE_12,  RATE_6,       // OFDM PLCP Signal = 8,  9,  10, 11 respectively
53         RATE_54,  RATE_36,      RATE_18,  RATE_9,       // OFDM PLCP Signal = 12, 13, 14, 15 respectively
54 };
55
56 UCHAR    OfdmRateToRxwiMCS[12] = {
57         0,  0,  0,  0,
58         0,  1,  2,  3,  // OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3
59         4,  5,  6,  7,  // OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7
60 };
61 UCHAR    RxwiMCSToOfdmRate[12] = {
62         RATE_6,  RATE_9,        RATE_12,  RATE_18,
63         RATE_24,  RATE_36,      RATE_48,  RATE_54,      // OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3
64         4,  5,  6,  7,  // OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7
65 };
66
67 char*   MCSToMbps[] = {"1Mbps","2Mbps","5.5Mbps","11Mbps","06Mbps","09Mbps","12Mbps","18Mbps","24Mbps","36Mbps","48Mbps","54Mbps","MM-0","MM-1","MM-2","MM-3","MM-4","MM-5","MM-6","MM-7","MM-8","MM-9","MM-10","MM-11","MM-12","MM-13","MM-14","MM-15","MM-32","ee1","ee2","ee3"};
68
69 UCHAR default_cwmin[]={CW_MIN_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1, CW_MIN_IN_BITS-2};
70 UCHAR default_sta_aifsn[]={3,7,2,2};
71
72 UCHAR MapUserPriorityToAccessCategory[8] = {QID_AC_BE, QID_AC_BK, QID_AC_BK, QID_AC_BE, QID_AC_VI, QID_AC_VI, QID_AC_VO, QID_AC_VO};
73
74
75 /*
76         ========================================================================
77
78         Routine Description:
79                 API for MLME to transmit management frame to AP (BSS Mode)
80         or station (IBSS Mode)
81
82         Arguments:
83                 pAd Pointer to our adapter
84                 pData           Pointer to the outgoing 802.11 frame
85                 Length          Size of outgoing management frame
86
87         Return Value:
88                 NDIS_STATUS_FAILURE
89                 NDIS_STATUS_PENDING
90                 NDIS_STATUS_SUCCESS
91
92         IRQL = PASSIVE_LEVEL
93         IRQL = DISPATCH_LEVEL
94
95         Note:
96
97         ========================================================================
98 */
99 NDIS_STATUS MiniportMMRequest(
100         IN      PRTMP_ADAPTER   pAd,
101         IN      UCHAR                   QueIdx,
102         IN      PUCHAR                  pData,
103         IN      UINT                    Length)
104 {
105         PNDIS_PACKET    pPacket;
106         NDIS_STATUS     Status = NDIS_STATUS_SUCCESS;
107         ULONG                   FreeNum;
108 #ifdef RT2860
109         unsigned long   IrqFlags = 0;
110 #endif
111         UCHAR                   IrqState;
112         UCHAR                   rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
113
114         ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
115
116         QueIdx=3;
117
118         // 2860C use Tx Ring
119
120         IrqState = pAd->irq_disabled;
121
122 #ifdef RT2860
123         if ((pAd->MACVersion == 0x28600100) && (!IrqState))
124                 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
125 #endif
126         do
127         {
128                 // Reset is in progress, stop immediately
129                 if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
130                          RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
131                          !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
132                 {
133                         Status = NDIS_STATUS_FAILURE;
134                         break;
135                 }
136
137                 // Check Free priority queue
138                 // Since we use PBF Queue2 for management frame.  Its corresponding DMA ring should be using TxRing.
139
140                 // 2860C use Tx Ring
141                 if (pAd->MACVersion == 0x28600100)
142                 {
143                         FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
144                 }
145                 else
146                 {
147                         FreeNum = GET_MGMTRING_FREENO(pAd);
148                 }
149
150                 if ((FreeNum > 0))
151                 {
152                         // We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870
153                         NdisZeroMemory(&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE));
154                         Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE), pData, Length);
155                         if (Status != NDIS_STATUS_SUCCESS)
156                         {
157                                 DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
158                                 break;
159                         }
160
161                         //pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
162                         //pAd->CommonCfg.MlmeRate = RATE_2;
163
164
165                         Status = MlmeHardTransmit(pAd, QueIdx, pPacket);
166                         if (Status != NDIS_STATUS_SUCCESS)
167                                 RTMPFreeNdisPacket(pAd, pPacket);
168                 }
169                 else
170                 {
171                         pAd->RalinkCounters.MgmtRingFullCount++;
172                         DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing, MgmtRingFullCount=%ld!\n",
173                                                                                 QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
174                 }
175
176         } while (FALSE);
177
178 #ifdef RT2860
179         // 2860C use Tx Ring
180         if ((pAd->MACVersion == 0x28600100) && (!IrqState))
181                 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
182 #endif
183         return Status;
184 }
185
186 #ifdef RT2860
187 NDIS_STATUS MiniportMMRequestUnlock(
188         IN      PRTMP_ADAPTER   pAd,
189         IN      UCHAR                   QueIdx,
190         IN      PUCHAR                  pData,
191         IN      UINT                    Length)
192 {
193         PNDIS_PACKET    pPacket;
194         NDIS_STATUS  Status = NDIS_STATUS_SUCCESS;
195         ULONG    FreeNum;
196         TXWI_STRUC              TXWI;
197         ULONG   SW_TX_IDX;
198         PTXD_STRUC              pTxD;
199
200         QueIdx = 3;
201         ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
202
203         do
204         {
205                 // Reset is in progress, stop immediately
206                 if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
207                          RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
208                          !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
209                 {
210                         Status = NDIS_STATUS_FAILURE;
211                         break;
212                 }
213
214                 // Check Free priority queue
215                 // Since we use PBF Queue2 for management frame.  Its corresponding DMA ring should be using TxRing.
216                 // 2860C use Tx Ring
217                 if (pAd->MACVersion == 0x28600100)
218                 {
219                         FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
220                         SW_TX_IDX = pAd->TxRing[QueIdx].TxCpuIdx;
221                         pTxD  = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SW_TX_IDX].AllocVa;
222                 }
223                 else
224                 {
225                         FreeNum = GET_MGMTRING_FREENO(pAd);
226                         SW_TX_IDX = pAd->MgmtRing.TxCpuIdx;
227                         pTxD  = (PTXD_STRUC) pAd->MgmtRing.Cell[SW_TX_IDX].AllocVa;
228                 }
229                 if ((FreeNum > 0))
230                 {
231                         NdisZeroMemory(&TXWI, TXWI_SIZE);
232                         Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&TXWI, TXWI_SIZE, pData, Length);
233                         if (Status != NDIS_STATUS_SUCCESS)
234                         {
235                                 DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
236                                 break;
237                         }
238
239                         Status = MlmeHardTransmit(pAd, QueIdx, pPacket);
240                         if (Status != NDIS_STATUS_SUCCESS)
241                                 RTMPFreeNdisPacket(pAd, pPacket);
242                 }
243                 else
244                 {
245                         pAd->RalinkCounters.MgmtRingFullCount++;
246                         DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing\n", QueIdx));
247                 }
248
249         } while (FALSE);
250
251
252         return Status;
253 }
254 #endif
255 #ifdef RT30xx
256 NDIS_STATUS MlmeDataHardTransmit(
257         IN      PRTMP_ADAPTER   pAd,
258         IN      UCHAR   QueIdx,
259         IN      PNDIS_PACKET    pPacket);
260
261 #define MAX_DATAMM_RETRY        3
262 /*
263         ========================================================================
264
265         Routine Description:
266                 API for MLME to transmit management frame to AP (BSS Mode)
267         or station (IBSS Mode)
268
269         Arguments:
270                 pAd Pointer to our adapter
271                 pData           Pointer to the outgoing 802.11 frame
272                 Length          Size of outgoing management frame
273
274         Return Value:
275                 NDIS_STATUS_FAILURE
276                 NDIS_STATUS_PENDING
277                 NDIS_STATUS_SUCCESS
278
279         IRQL = PASSIVE_LEVEL
280         IRQL = DISPATCH_LEVEL
281
282         Note:
283
284         ========================================================================
285 */
286 NDIS_STATUS MiniportDataMMRequest(
287                                                          IN  PRTMP_ADAPTER   pAd,
288                                                          IN  UCHAR           QueIdx,
289                                                          IN  PUCHAR          pData,
290                                                          IN  UINT            Length)
291 {
292         PNDIS_PACKET    pPacket;
293         NDIS_STATUS  Status = NDIS_STATUS_SUCCESS;
294         ULONG    FreeNum;
295         int     retry = 0;
296         UCHAR           IrqState;
297         UCHAR                   rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
298
299         ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
300
301         // 2860C use Tx Ring
302         IrqState = pAd->irq_disabled;
303
304         do
305         {
306                 // Reset is in progress, stop immediately
307                 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
308                          RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
309                         !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
310                 {
311                         Status = NDIS_STATUS_FAILURE;
312                         break;
313                 }
314
315                 // Check Free priority queue
316                 // Since we use PBF Queue2 for management frame.  Its corresponding DMA ring should be using TxRing.
317
318                 // 2860C use Tx Ring
319
320                 // free Tx(QueIdx) resources
321                 FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
322
323                 if ((FreeNum > 0))
324                 {
325                         // We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870
326                         NdisZeroMemory(&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE));
327                         Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE), pData, Length);
328                         if (Status != NDIS_STATUS_SUCCESS)
329                         {
330                                 DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
331                                 break;
332                         }
333
334                         //pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
335                         //pAd->CommonCfg.MlmeRate = RATE_2;
336
337
338                         Status = MlmeDataHardTransmit(pAd, QueIdx, pPacket);
339                         if (Status != NDIS_STATUS_SUCCESS)
340                                 RTMPFreeNdisPacket(pAd, pPacket);
341                         retry = MAX_DATAMM_RETRY;
342                 }
343                 else
344                 {
345                         retry ++;
346
347                         printk("retry %d\n", retry);
348                         pAd->RalinkCounters.MgmtRingFullCount++;
349
350                         if (retry >= MAX_DATAMM_RETRY)
351                         {
352                                 DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in DataRing, MgmtRingFullCount=%ld!\n",
353                                                                                         QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
354                         }
355                 }
356
357         } while (retry < MAX_DATAMM_RETRY);
358
359
360         return Status;
361 }
362 #endif /* RT30xx */
363
364 /*
365         ========================================================================
366
367         Routine Description:
368                 Copy frame from waiting queue into relative ring buffer and set
369         appropriate ASIC register to kick hardware transmit function
370
371         Arguments:
372                 pAd Pointer to our adapter
373                 pBuffer         Pointer to      memory of outgoing frame
374                 Length          Size of outgoing management frame
375
376         Return Value:
377                 NDIS_STATUS_FAILURE
378                 NDIS_STATUS_PENDING
379                 NDIS_STATUS_SUCCESS
380
381         IRQL = PASSIVE_LEVEL
382         IRQL = DISPATCH_LEVEL
383
384         Note:
385
386         ========================================================================
387 */
388 NDIS_STATUS MlmeHardTransmit(
389         IN      PRTMP_ADAPTER   pAd,
390         IN      UCHAR                   QueIdx,
391         IN      PNDIS_PACKET    pPacket)
392 {
393         if (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
394         {
395                 return NDIS_STATUS_FAILURE;
396         }
397
398 #ifdef RT2860
399         if ( pAd->MACVersion == 0x28600100 )
400                 return MlmeHardTransmitTxRing(pAd,QueIdx,pPacket);
401         else
402 #endif
403                 return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
404
405 }
406
407 #ifdef RT2860
408 NDIS_STATUS MlmeHardTransmitTxRing(
409         IN      PRTMP_ADAPTER   pAd,
410         IN      UCHAR   QueIdx,
411         IN      PNDIS_PACKET    pPacket)
412 {
413         PACKET_INFO     PacketInfo;
414         PUCHAR                  pSrcBufVA;
415         UINT                    SrcBufLen;
416         PTXD_STRUC              pTxD;
417         PHEADER_802_11  pHeader_802_11;
418         BOOLEAN                 bAckRequired, bInsertTimestamp;
419         ULONG                   SrcBufPA;
420         UCHAR                   MlmeRate;
421         ULONG                   SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
422         PTXWI_STRUC     pFirstTxWI;
423         ULONG    FreeNum;
424         MAC_TABLE_ENTRY *pMacEntry = NULL;
425
426
427         RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
428
429         if (pSrcBufVA == NULL)
430         {
431                 // The buffer shouldn't be NULL
432                 return NDIS_STATUS_FAILURE;
433         }
434
435         // Make sure MGMT ring resource won't be used by other threads
436         //NdisAcquireSpinLock(&pAd->TxRingLock);
437
438         FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
439
440         if (FreeNum == 0)
441         {
442                 //NdisReleaseSpinLock(&pAd->TxRingLock);
443                 return NDIS_STATUS_FAILURE;
444         }
445
446         SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
447
448         pTxD  = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa;
449
450         if (pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket)
451         {
452                 printk("MlmeHardTransmit Error\n");
453                 return NDIS_STATUS_FAILURE;
454         }
455
456         // outgoing frame always wakeup PHY to prevent frame lost
457         if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
458                 AsicForceWakeup(pAd, FROM_TX);
459
460         pFirstTxWI      =(PTXWI_STRUC)pSrcBufVA;
461
462         pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXWI_SIZE);
463         if (pHeader_802_11->Addr1[0] & 0x01)
464         {
465                 MlmeRate = pAd->CommonCfg.BasicMlmeRate;
466         }
467         else
468         {
469                 MlmeRate = pAd->CommonCfg.MlmeRate;
470         }
471
472         if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
473                 (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))
474         {
475                 pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
476         }
477
478         // Verify Mlme rate for a / g bands.
479         if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band
480                 MlmeRate = RATE_6;
481
482         //
483         // Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)
484         // Snice it's been set to 0 while on MgtMacHeaderInit
485         // By the way this will cause frame to be send on PWR_SAVE failed.
486         //
487         //
488         // In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
489
490     // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
491         if (pHeader_802_11->FC.Type != BTYPE_DATA)
492     {
493         if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) || !(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
494         {
495                 pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
496         }
497         else
498         {
499                 pHeader_802_11->FC.PwrMgmt = pAd->CommonCfg.bAPSDForcePowerSave;
500         }
501     }
502
503         bInsertTimestamp = FALSE;
504         if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
505         {
506                 bAckRequired = FALSE;
507         }
508         else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
509         {
510                 if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
511                 {
512                         bAckRequired = FALSE;
513                         pHeader_802_11->Duration = 0;
514                 }
515                 else
516                 {
517                         bAckRequired = TRUE;
518                         pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
519                         if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
520                         {
521                                 bInsertTimestamp = TRUE;
522                         }
523                 }
524         }
525         pHeader_802_11->Sequence = pAd->Sequence++;
526         if (pAd->Sequence > 0xfff)
527                 pAd->Sequence = 0;
528         // Before radar detection done, mgmt frame can not be sent but probe req
529         // Because we need to use probe req to trigger driver to send probe req in passive scan
530         if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
531                 && (pAd->CommonCfg.bIEEE80211H == 1)
532                 && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
533         {
534                 DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
535                 return (NDIS_STATUS_FAILURE);
536         }
537
538         //
539         // fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
540         // should always has only one ohysical buffer, and the whole frame size equals
541         // to the first scatter buffer size
542         //
543
544         // Initialize TX Descriptor
545         // For inter-frame gap, the number is for this frame and next frame
546         // For MLME rate, we will fix as 2Mb to match other vendor's implement
547
548 // management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
549         // Only beacon use Nseq=TRUE. So here we use Nseq=FALSE.
550         if (pMacEntry == NULL)
551         {
552                 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
553                 0, RESERVED_WCID, (SrcBufLen - TXWI_SIZE), PID_MGMT, 0,  (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
554         }
555         else
556         {
557                 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
558                                         bInsertTimestamp, FALSE, bAckRequired, FALSE,
559                                         0, pMacEntry->Aid, (SrcBufLen - TXWI_SIZE),
560                                         pMacEntry->MaxHTPhyMode.field.MCS, 0,
561                                         (UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
562                                         IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
563         }
564
565         pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket = pPacket;
566         pAd->TxRing[QueIdx].Cell[SwIdx].pNextNdisPacket = NULL;
567
568         SrcBufPA = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
569
570
571         RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_EDCA);
572         pTxD->LastSec0 = 1;
573         pTxD->LastSec1 = 1;
574         pTxD->SDLen0 = SrcBufLen;
575         pTxD->SDLen1 = 0;
576         pTxD->SDPtr0 = SrcBufPA;
577         pTxD->DMADONE = 0;
578
579         pAd->RalinkCounters.KickTxCount++;
580         pAd->RalinkCounters.OneSecTxDoneCount++;
581
582         // Increase TX_CTX_IDX, but write to register later.
583         INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE);
584
585         RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx*0x10,  pAd->TxRing[QueIdx].TxCpuIdx);
586
587         return NDIS_STATUS_SUCCESS;
588 }
589 #endif /* RT2860 */
590
591 #ifdef RT30xx
592 NDIS_STATUS MlmeDataHardTransmit(
593         IN      PRTMP_ADAPTER   pAd,
594         IN      UCHAR   QueIdx,
595         IN      PNDIS_PACKET    pPacket)
596 {
597         if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
598                 )
599         {
600                 return NDIS_STATUS_FAILURE;
601         }
602
603 #ifdef RT2870
604         return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
605 #endif // RT2870 //
606 }
607 #endif /* RT30xx */
608
609 NDIS_STATUS MlmeHardTransmitMgmtRing(
610         IN      PRTMP_ADAPTER   pAd,
611         IN      UCHAR   QueIdx,
612         IN      PNDIS_PACKET    pPacket)
613 {
614         PACKET_INFO     PacketInfo;
615         PUCHAR                  pSrcBufVA;
616         UINT                    SrcBufLen;
617         PHEADER_802_11  pHeader_802_11;
618         BOOLEAN                 bAckRequired, bInsertTimestamp;
619         UCHAR                   MlmeRate;
620         PTXWI_STRUC     pFirstTxWI;
621         MAC_TABLE_ENTRY *pMacEntry = NULL;
622
623         RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
624                 RTMP_SEM_LOCK(&pAd->MgmtRingLock);
625
626
627         if (pSrcBufVA == NULL)
628         {
629                 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
630                 return NDIS_STATUS_FAILURE;
631         }
632
633         // outgoing frame always wakeup PHY to prevent frame lost
634         if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
635 #ifdef RT2860
636                 AsicForceWakeup(pAd, FROM_TX);
637 #endif
638 #ifdef RT2870
639                 AsicForceWakeup(pAd, TRUE);
640 #endif
641
642         pFirstTxWI = (PTXWI_STRUC)(pSrcBufVA +  TXINFO_SIZE);
643         pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); //TXWI_SIZE);
644
645         if (pHeader_802_11->Addr1[0] & 0x01)
646         {
647                 MlmeRate = pAd->CommonCfg.BasicMlmeRate;
648         }
649         else
650         {
651                 MlmeRate = pAd->CommonCfg.MlmeRate;
652         }
653
654         // Verify Mlme rate for a / g bands.
655         if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band
656                 MlmeRate = RATE_6;
657
658         if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
659                 (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))
660         {
661                 pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
662         }
663
664         {
665                 // Fixed W52 with Activity scan issue in ABG_MIXED and ABGN_MIXED mode.
666                 if (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED
667                         || pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED
668                 )
669                 {
670                         if (pAd->LatchRfRegs.Channel > 14)
671                                 pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
672                         else
673                                 pAd->CommonCfg.MlmeTransmit.field.MODE = 0;
674                 }
675         }
676
677         //
678         // Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)
679         // Snice it's been set to 0 while on MgtMacHeaderInit
680         // By the way this will cause frame to be send on PWR_SAVE failed.
681         //
682         // pHeader_802_11->FC.PwrMgmt = 0; // (pAd->StaCfg.Psm == PWR_SAVE);
683         //
684         // In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
685
686     // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
687         if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL))
688         {
689                 if ((pAd->StaCfg.Psm == PWR_SAVE) &&
690                         (pHeader_802_11->FC.SubType == SUBTYPE_ACTION))
691                         pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
692                 else
693                         pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
694         }
695
696         bInsertTimestamp = FALSE;
697         if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
698         {
699                 //Set PM bit in ps-poll, to fix WLK 1.2  PowerSaveMode_ext failure issue.
700                 if ((pAd->OpMode == OPMODE_STA) && (pHeader_802_11->FC.SubType == SUBTYPE_PS_POLL))
701                 {
702                         pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
703                 }
704                 bAckRequired = FALSE;
705         }
706         else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
707         {
708                 if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
709                 {
710                         bAckRequired = FALSE;
711                         pHeader_802_11->Duration = 0;
712                 }
713                 else
714                 {
715                         bAckRequired = TRUE;
716                         pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
717                         if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
718                         {
719                                 bInsertTimestamp = TRUE;
720                         }
721                 }
722         }
723
724         pHeader_802_11->Sequence = pAd->Sequence++;
725         if (pAd->Sequence >0xfff)
726                 pAd->Sequence = 0;
727
728         // Before radar detection done, mgmt frame can not be sent but probe req
729         // Because we need to use probe req to trigger driver to send probe req in passive scan
730         if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
731                 && (pAd->CommonCfg.bIEEE80211H == 1)
732                 && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
733         {
734                 DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
735                 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
736                 return (NDIS_STATUS_FAILURE);
737         }
738
739         //
740         // fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
741         // should always has only one ohysical buffer, and the whole frame size equals
742         // to the first scatter buffer size
743         //
744
745         // Initialize TX Descriptor
746         // For inter-frame gap, the number is for this frame and next frame
747         // For MLME rate, we will fix as 2Mb to match other vendor's implement
748
749 // management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
750         if (pMacEntry == NULL)
751         {
752                 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
753                 0, RESERVED_WCID, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID_MGMT, 0,  (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
754         }
755         else
756         {
757                 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
758                                         bInsertTimestamp, FALSE, bAckRequired, FALSE,
759                                         0, pMacEntry->Aid, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE),
760                                         pMacEntry->MaxHTPhyMode.field.MCS, 0,
761                                         (UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
762                                         IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
763         }
764
765         // Now do hardware-depened kick out.
766         HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen);
767
768         // Make sure to release MGMT ring resource
769         RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
770         return NDIS_STATUS_SUCCESS;
771 }
772
773
774 /********************************************************************************
775
776         New DeQueue Procedures.
777
778  ********************************************************************************/
779
780 #define DEQUEUE_LOCK(lock, bIntContext, IrqFlags)                               \
781                         do{                                                                                                     \
782                                 if (bIntContext == FALSE)                                               \
783                                 RTMP_IRQ_LOCK((lock), IrqFlags);                \
784                         }while(0)
785
786 #define DEQUEUE_UNLOCK(lock, bIntContext, IrqFlags)                             \
787                         do{                                                                                                     \
788                                 if (bIntContext == FALSE)                                               \
789                                         RTMP_IRQ_UNLOCK((lock), IrqFlags);      \
790                         }while(0)
791
792 /*
793         ========================================================================
794         Tx Path design algorithm:
795                 Basically, we divide the packets into four types, Broadcast/Multicast, 11N Rate(AMPDU, AMSDU, Normal), B/G Rate(ARALINK, Normal),
796                 Specific Packet Type. Following show the classification rule and policy for each kinds of packets.
797                                 Classification Rule=>
798                                         Multicast: (*addr1 & 0x01) == 0x01
799                                         Specific : bDHCPFrame, bARPFrame, bEAPOLFrame, etc.
800                                         11N Rate : If peer support HT
801                                                                 (1).AMPDU  -- If TXBA is negotiated.
802                                                                 (2).AMSDU  -- If AMSDU is capable for both peer and ourself.
803                                                                                         *). AMSDU can embedded in a AMPDU, but now we didn't support it.
804                                                                 (3).Normal -- Other packets which send as 11n rate.
805
806                                         B/G Rate : If peer is b/g only.
807                                                                 (1).ARALINK-- If both of peer/us supprot Ralink proprietary Aggregation and the TxRate is large than RATE_6
808                                                                 (2).Normal -- Other packets which send as b/g rate.
809                                         Fragment:
810                                                                 The packet must be unicast, NOT A-RALINK, NOT A-MSDU, NOT 11n, then can consider about fragment.
811
812                                 Classified Packet Handle Rule=>
813                                         Multicast:
814                                                                 No ACK,                 //pTxBlk->bAckRequired = FALSE;
815                                                                 No WMM,                 //pTxBlk->bWMM = FALSE;
816                                                                 No piggyback,   //pTxBlk->bPiggyBack = FALSE;
817                                                                 Force LowRate,  //pTxBlk->bForceLowRate = TRUE;
818                                         Specific :      Basically, for specific packet, we should handle it specifically, but now all specific packets are use
819                                                                         the same policy to handle it.
820                                                                 Force LowRate,  //pTxBlk->bForceLowRate = TRUE;
821
822                                         11N Rate :
823                                                                 No piggyback,   //pTxBlk->bPiggyBack = FALSE;
824
825                                                                 (1).AMSDU
826                                                                         pTxBlk->bWMM = TRUE;
827                                                                 (2).AMPDU
828                                                                         pTxBlk->bWMM = TRUE;
829                                                                 (3).Normal
830
831                                         B/G Rate :
832                                                                 (1).ARALINK
833
834                                                                 (2).Normal
835         ========================================================================
836 */
837 static UCHAR TxPktClassification(
838         IN RTMP_ADAPTER *pAd,
839         IN PNDIS_PACKET  pPacket)
840 {
841         UCHAR                   TxFrameType = TX_UNKOWN_FRAME;
842         UCHAR                   Wcid;
843         MAC_TABLE_ENTRY *pMacEntry = NULL;
844         BOOLEAN                 bHTRate = FALSE;
845
846         Wcid = RTMP_GET_PACKET_WCID(pPacket);
847         if (Wcid == MCAST_WCID)
848         {       // Handle for RA is Broadcast/Multicast Address.
849                 return TX_MCAST_FRAME;
850         }
851
852         // Handle for unicast packets
853         pMacEntry = &pAd->MacTab.Content[Wcid];
854         if (RTMP_GET_PACKET_LOWRATE(pPacket))
855         {       // It's a specific packet need to force low rate, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame
856                 TxFrameType = TX_LEGACY_FRAME;
857         }
858         else if (IS_HT_RATE(pMacEntry))
859         {       // it's a 11n capable packet
860
861                 // Depends on HTPhyMode to check if the peer support the HTRate transmission.
862                 //      Currently didn't support A-MSDU embedded in A-MPDU
863                 bHTRate = TRUE;
864                 if (RTMP_GET_PACKET_MOREDATA(pPacket) || (pMacEntry->PsMode == PWR_SAVE))
865                         TxFrameType = TX_LEGACY_FRAME;
866 #ifdef UAPSD_AP_SUPPORT
867                 else if (RTMP_GET_PACKET_EOSP(pPacket))
868                         TxFrameType = TX_LEGACY_FRAME;
869 #endif // UAPSD_AP_SUPPORT //
870                 else if((pMacEntry->TXBAbitmap & (1<<(RTMP_GET_PACKET_UP(pPacket)))) != 0)
871                         return TX_AMPDU_FRAME;
872                 else if(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AMSDU_INUSED))
873                         return TX_AMSDU_FRAME;
874                 else
875                         TxFrameType = TX_LEGACY_FRAME;
876         }
877         else
878         {       // it's a legacy b/g packet.
879                 if ((CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE) && pAd->CommonCfg.bAggregationCapable) &&
880                         (RTMP_GET_PACKET_TXRATE(pPacket) >= RATE_6) &&
881                         (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
882                 {       // if peer support Ralink Aggregation, we use it.
883                         TxFrameType = TX_RALINK_FRAME;
884                 }
885                 else
886                 {
887                         TxFrameType = TX_LEGACY_FRAME;
888                 }
889         }
890
891         // Currently, our fragment only support when a unicast packet send as NOT-ARALINK, NOT-AMSDU and NOT-AMPDU.
892         if ((RTMP_GET_PACKET_FRAGMENTS(pPacket) > 1) && (TxFrameType == TX_LEGACY_FRAME))
893                 TxFrameType = TX_FRAG_FRAME;
894
895         return TxFrameType;
896 }
897
898
899 BOOLEAN RTMP_FillTxBlkInfo(
900         IN RTMP_ADAPTER *pAd,
901         IN TX_BLK *pTxBlk)
902 {
903         PACKET_INFO                     PacketInfo;
904         PNDIS_PACKET            pPacket;
905         PMAC_TABLE_ENTRY        pMacEntry = NULL;
906
907         pPacket = pTxBlk->pPacket;
908         RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen);
909
910         pTxBlk->Wcid                            = RTMP_GET_PACKET_WCID(pPacket);
911         pTxBlk->apidx                           = RTMP_GET_PACKET_IF(pPacket);
912         pTxBlk->UserPriority            = RTMP_GET_PACKET_UP(pPacket);
913         pTxBlk->FrameGap = IFS_HTTXOP;          // ASIC determine Frame Gap
914
915         if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pTxBlk->pPacket))
916                 TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame);
917         else
918                 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bClearEAPFrame);
919
920         // Default to clear this flag
921         TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bForceNonQoS);
922
923
924         if (pTxBlk->Wcid == MCAST_WCID)
925         {
926                 pTxBlk->pMacEntry = NULL;
927                 {
928 #ifdef MCAST_RATE_SPECIFIC
929                         PUCHAR pDA = GET_OS_PKT_DATAPTR(pPacket);
930                         if (((*pDA & 0x01) == 0x01) && (*pDA != 0xff))
931                                 pTxBlk->pTransmit = &pAd->CommonCfg.MCastPhyMode;
932                         else
933 #endif // MCAST_RATE_SPECIFIC //
934                                 pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
935                 }
936
937                 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);    // AckRequired = FALSE, when broadcast packet in Adhoc mode.
938                 //TX_BLK_SET_FLAG(pTxBlk, fTX_bForceLowRate);
939                 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAllowFrag);
940                 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
941                 if (RTMP_GET_PACKET_MOREDATA(pPacket))
942                 {
943                         TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
944                 }
945
946         }
947         else
948         {
949                 pTxBlk->pMacEntry = &pAd->MacTab.Content[pTxBlk->Wcid];
950                 pTxBlk->pTransmit = &pTxBlk->pMacEntry->HTPhyMode;
951
952                 pMacEntry = pTxBlk->pMacEntry;
953
954
955                 // For all unicast packets, need Ack unless the Ack Policy is not set as NORMAL_ACK.
956                 if (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx] != NORMAL_ACK)
957                         TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);
958                 else
959                         TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired);
960
961                 {
962                         // If support WMM, enable it.
963 #ifdef RT2860
964                         if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
965 #endif
966 #ifdef RT2870
967                         if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
968                                 CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))
969 #endif
970                                 TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM);
971                 }
972
973                 if (pTxBlk->TxFrameType == TX_LEGACY_FRAME)
974                 {
975                         if ( (RTMP_GET_PACKET_LOWRATE(pPacket)) ||
976                 ((pAd->OpMode == OPMODE_AP) && (pMacEntry->MaxHTPhyMode.field.MODE == MODE_CCK) && (pMacEntry->MaxHTPhyMode.field.MCS == RATE_1)))
977                         {       // Specific packet, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame, need force low rate.
978                                 pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
979
980                                 // Modify the WMM bit for ICV issue. If we have a packet with EOSP field need to set as 1, how to handle it???
981                                 if (IS_HT_STA(pTxBlk->pMacEntry) &&
982                                         (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RALINK_CHIPSET)) &&
983                                         ((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RDG_CAPABLE)))
984                                 {
985                                         TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
986                                         TX_BLK_SET_FLAG(pTxBlk, fTX_bForceNonQoS);
987                                 }
988                         }
989
990                         if ( (IS_HT_RATE(pMacEntry) == FALSE) &&
991                                 (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE)))
992                         {       // Currently piggy-back only support when peer is operate in b/g mode.
993                                 TX_BLK_SET_FLAG(pTxBlk, fTX_bPiggyBack);
994                         }
995
996                         if (RTMP_GET_PACKET_MOREDATA(pPacket))
997                         {
998                                 TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
999                         }
1000 #ifdef UAPSD_AP_SUPPORT
1001                         if (RTMP_GET_PACKET_EOSP(pPacket))
1002                         {
1003                                 TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP);
1004                         }
1005 #endif // UAPSD_AP_SUPPORT //
1006                 }
1007                 else if (pTxBlk->TxFrameType == TX_FRAG_FRAME)
1008                 {
1009                         TX_BLK_SET_FLAG(pTxBlk, fTX_bAllowFrag);
1010                 }
1011
1012                 pMacEntry->DebugTxCount++;
1013         }
1014
1015         return TRUE;
1016
1017 #ifdef RT30xx
1018 FillTxBlkErr:
1019         return FALSE;
1020 #endif
1021 }
1022
1023
1024 BOOLEAN CanDoAggregateTransmit(
1025         IN RTMP_ADAPTER *pAd,
1026         IN NDIS_PACKET *pPacket,
1027         IN TX_BLK               *pTxBlk)
1028 {
1029
1030         //printk("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType);
1031
1032         if (RTMP_GET_PACKET_WCID(pPacket) == MCAST_WCID)
1033                 return FALSE;
1034
1035         if (RTMP_GET_PACKET_DHCP(pPacket) ||
1036                 RTMP_GET_PACKET_EAPOL(pPacket) ||
1037                 RTMP_GET_PACKET_WAI(pPacket))
1038                 return FALSE;
1039
1040         if ((pTxBlk->TxFrameType == TX_AMSDU_FRAME) &&
1041                 ((pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))> (RX_BUFFER_AGGRESIZE - 100)))
1042         {       // For AMSDU, allow the packets with total length < max-amsdu size
1043                 return FALSE;
1044         }
1045
1046         if ((pTxBlk->TxFrameType == TX_RALINK_FRAME) &&
1047                 (pTxBlk->TxPacketList.Number == 2))
1048         {       // For RALINK-Aggregation, allow two frames in one batch.
1049                 return FALSE;
1050         }
1051
1052         if ((INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) // must be unicast to AP
1053                 return TRUE;
1054         else
1055                 return FALSE;
1056 }
1057
1058
1059 /*
1060         ========================================================================
1061
1062         Routine Description:
1063                 To do the enqueue operation and extract the first item of waiting
1064                 list. If a number of available shared memory segments could meet
1065                 the request of extracted item, the extracted item will be fragmented
1066                 into shared memory segments.
1067
1068         Arguments:
1069                 pAd Pointer to our adapter
1070                 pQueue          Pointer to Waiting Queue
1071
1072         Return Value:
1073                 None
1074
1075         IRQL = DISPATCH_LEVEL
1076
1077         Note:
1078
1079         ========================================================================
1080 */
1081 VOID RTMPDeQueuePacket(
1082         IN  PRTMP_ADAPTER   pAd,
1083         IN  BOOLEAN         bIntContext,
1084         IN  UCHAR                       QIdx, /* BulkOutPipeId */
1085         IN  UCHAR           Max_Tx_Packets)
1086 {
1087         PQUEUE_ENTRY    pEntry = NULL;
1088         PNDIS_PACKET    pPacket;
1089         NDIS_STATUS     Status = NDIS_STATUS_SUCCESS;
1090         UCHAR           Count=0;
1091         PQUEUE_HEADER   pQueue;
1092         ULONG           FreeNumber[NUM_OF_TX_RING];
1093         UCHAR                   QueIdx, sQIdx, eQIdx;
1094         unsigned long   IrqFlags = 0;
1095         BOOLEAN                 hasTxDesc = FALSE;
1096         TX_BLK                  TxBlk;
1097         TX_BLK                  *pTxBlk;
1098
1099 #ifdef DBG_DIAGNOSE
1100         BOOLEAN                 firstRound;
1101         RtmpDiagStruct  *pDiagStruct = &pAd->DiagStruct;
1102 #endif
1103
1104
1105         if (QIdx == NUM_OF_TX_RING)
1106         {
1107                 sQIdx = 0;
1108 //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
1109                 eQIdx = 3;      // 4 ACs, start from 0.
1110         }
1111         else
1112         {
1113                 sQIdx = eQIdx = QIdx;
1114         }
1115
1116         for (QueIdx=sQIdx; QueIdx <= eQIdx; QueIdx++)
1117         {
1118                 Count=0;
1119
1120                 RT28XX_START_DEQUEUE(pAd, QueIdx, IrqFlags);
1121
1122 #ifdef DBG_DIAGNOSE
1123                 firstRound = ((QueIdx == 0) ? TRUE : FALSE);
1124 #endif // DBG_DIAGNOSE //
1125
1126                 while (1)
1127                 {
1128                         if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS |
1129                                                                                 fRTMP_ADAPTER_RADIO_OFF |
1130                                                                                 fRTMP_ADAPTER_RESET_IN_PROGRESS |
1131                                                                                 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1132                                                                                 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1133                         {
1134                                 RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
1135                                 return;
1136                         }
1137
1138                         if (Count >= Max_Tx_Packets)
1139                                 break;
1140
1141                         DEQUEUE_LOCK(&pAd->irq_lock, bIntContext, IrqFlags);
1142                         if (&pAd->TxSwQueue[QueIdx] == NULL)
1143                         {
1144 #ifdef DBG_DIAGNOSE
1145                                 if (firstRound == TRUE)
1146                                         pDiagStruct->TxSWQueCnt[pDiagStruct->ArrayCurIdx][0]++;
1147 #endif // DBG_DIAGNOSE //
1148                                 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
1149                                 break;
1150                         }
1151 #ifdef RT2860
1152                         FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
1153
1154 #ifdef DBG_DIAGNOSE
1155                         if (firstRound == TRUE)
1156                         {
1157                                 UCHAR   txDescNumLevel, txSwQNumLevel;
1158
1159                                 txDescNumLevel = (TX_RING_SIZE - FreeNumber[QueIdx]); // Number of occupied hw desc.
1160                                 txDescNumLevel = ((txDescNumLevel <=15) ? txDescNumLevel : 15);
1161                                 pDiagStruct->TxDescCnt[pDiagStruct->ArrayCurIdx][txDescNumLevel]++;
1162
1163                                 txSwQNumLevel = ((pAd->TxSwQueue[QueIdx].Number <=7) ? pAd->TxSwQueue[QueIdx].Number : 8);
1164                                 pDiagStruct->TxSWQueCnt[pDiagStruct->ArrayCurIdx][txSwQNumLevel]++;
1165
1166                                 firstRound = FALSE;
1167                         }
1168 #endif // DBG_DIAGNOSE //
1169
1170                         if (FreeNumber[QueIdx] <= 5)
1171                         {
1172                                 // free Tx(QueIdx) resources
1173                                 RTMPFreeTXDUponTxDmaDone(pAd, QueIdx);
1174                                 FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
1175                         }
1176 #endif /* RT2860 */
1177                         // probe the Queue Head
1178                         pQueue = &pAd->TxSwQueue[QueIdx];
1179                         if ((pEntry = pQueue->Head) == NULL)
1180                         {
1181                                 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
1182                                 break;
1183                         }
1184
1185                         pTxBlk = &TxBlk;
1186                         NdisZeroMemory((PUCHAR)pTxBlk, sizeof(TX_BLK));
1187                         pTxBlk->QueIdx = QueIdx;
1188
1189                         pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
1190
1191                         // Early check to make sure we have enoguh Tx Resource.
1192                         hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
1193                         if (!hasTxDesc)
1194                         {
1195                                 pAd->PrivateInfo.TxRingFullCnt++;
1196
1197                                 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
1198
1199                                 break;
1200                         }
1201
1202                         pTxBlk->TxFrameType = TxPktClassification(pAd, pPacket);
1203                         pEntry = RemoveHeadQueue(pQueue);
1204                         pTxBlk->TotalFrameNum++;
1205                         pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket);     // The real fragment number maybe vary
1206                         pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
1207                         pTxBlk->pPacket = pPacket;
1208                         InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
1209
1210                         if (pTxBlk->TxFrameType == TX_RALINK_FRAME || pTxBlk->TxFrameType == TX_AMSDU_FRAME)
1211                         {
1212                                 // Enhance SW Aggregation Mechanism
1213                                 if (NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, FreeNumber[QueIdx], pTxBlk->TxFrameType))
1214                                 {
1215                                         InsertHeadQueue(pQueue, PACKET_TO_QUEUE_ENTRY(pPacket));
1216                                         DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
1217                                         break;
1218                                 }
1219
1220                                 do{
1221                                         if((pEntry = pQueue->Head) == NULL)
1222                                                 break;
1223
1224                                         // For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation.
1225                                         pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
1226                                         FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
1227                                         hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
1228                                         if ((hasTxDesc == FALSE) || (CanDoAggregateTransmit(pAd, pPacket, pTxBlk) == FALSE))
1229                                                 break;
1230
1231                                         //Remove the packet from the TxSwQueue and insert into pTxBlk
1232                                         pEntry = RemoveHeadQueue(pQueue);
1233                                         ASSERT(pEntry);
1234                                         pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
1235                                         pTxBlk->TotalFrameNum++;
1236                                         pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket);     // The real fragment number maybe vary
1237                                         pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
1238                                         InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
1239                                 }while(1);
1240
1241                                 if (pTxBlk->TxPacketList.Number == 1)
1242                                         pTxBlk->TxFrameType = TX_LEGACY_FRAME;
1243                         }
1244
1245 #ifdef RT2870
1246                         DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
1247 #endif // RT2870 //
1248
1249                         Count += pTxBlk->TxPacketList.Number;
1250
1251                         // Do HardTransmit now.
1252                         Status = STAHardTransmit(pAd, pTxBlk, QueIdx);
1253
1254 #ifdef RT2860
1255                         DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
1256                         // static rate also need NICUpdateFifoStaCounters() function.
1257                         //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
1258                                 NICUpdateFifoStaCounters(pAd);
1259 #endif
1260                 }
1261
1262                 RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
1263
1264 #ifdef RT2870
1265                 if (!hasTxDesc)
1266                         RTUSBKickBulkOut(pAd);
1267 #endif // RT2870 //
1268         }
1269
1270 }
1271
1272
1273 /*
1274         ========================================================================
1275
1276         Routine Description:
1277                 Calculates the duration which is required to transmit out frames
1278         with given size and specified rate.
1279
1280         Arguments:
1281                 pAd     Pointer to our adapter
1282                 Rate                    Transmit rate
1283                 Size                    Frame size in units of byte
1284
1285         Return Value:
1286                 Duration number in units of usec
1287
1288         IRQL = PASSIVE_LEVEL
1289         IRQL = DISPATCH_LEVEL
1290
1291         Note:
1292
1293         ========================================================================
1294 */
1295 USHORT  RTMPCalcDuration(
1296         IN      PRTMP_ADAPTER   pAd,
1297         IN      UCHAR                   Rate,
1298         IN      ULONG                   Size)
1299 {
1300         ULONG   Duration = 0;
1301
1302         if (Rate < RATE_FIRST_OFDM_RATE) // CCK
1303         {
1304                 if ((Rate > RATE_1) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED))
1305                         Duration = 96;  // 72+24 preamble+plcp
1306                 else
1307                         Duration = 192; // 144+48 preamble+plcp
1308
1309                 Duration += (USHORT)((Size << 4) / RateIdTo500Kbps[Rate]);
1310                 if ((Size << 4) % RateIdTo500Kbps[Rate])
1311                         Duration ++;
1312         }
1313         else if (Rate <= RATE_LAST_OFDM_RATE)// OFDM rates
1314         {
1315                 Duration = 20 + 6;              // 16+4 preamble+plcp + Signal Extension
1316                 Duration += 4 * (USHORT)((11 + Size * 4) / RateIdTo500Kbps[Rate]);
1317                 if ((11 + Size * 4) % RateIdTo500Kbps[Rate])
1318                         Duration += 4;
1319         }
1320         else    //mimo rate
1321         {
1322                 Duration = 20 + 6;              // 16+4 preamble+plcp + Signal Extension
1323         }
1324
1325         return (USHORT)Duration;
1326 }
1327
1328
1329 /*
1330         ========================================================================
1331
1332         Routine Description:
1333                 Calculates the duration which is required to transmit out frames
1334         with given size and specified rate.
1335
1336         Arguments:
1337                 pTxWI           Pointer to head of each MPDU to HW.
1338                 Ack             Setting for Ack requirement bit
1339                 Fragment        Setting for Fragment bit
1340                 RetryMode       Setting for retry mode
1341                 Ifs             Setting for IFS gap
1342                 Rate            Setting for transmit rate
1343                 Service         Setting for service
1344                 Length          Frame length
1345                 TxPreamble      Short or Long preamble when using CCK rates
1346                 QueIdx - 0-3, according to 802.11e/d4.4 June/2003
1347
1348         Return Value:
1349                 None
1350
1351         IRQL = PASSIVE_LEVEL
1352         IRQL = DISPATCH_LEVEL
1353
1354     See also : BASmartHardTransmit()    !!!
1355
1356         ========================================================================
1357 */
1358 VOID RTMPWriteTxWI(
1359         IN      PRTMP_ADAPTER   pAd,
1360         IN      PTXWI_STRUC     pOutTxWI,
1361         IN      BOOLEAN                 FRAG,
1362         IN      BOOLEAN                 CFACK,
1363         IN      BOOLEAN                 InsTimestamp,
1364         IN      BOOLEAN                 AMPDU,
1365         IN      BOOLEAN                 Ack,
1366         IN      BOOLEAN                 NSeq,           // HW new a sequence.
1367         IN      UCHAR                   BASize,
1368         IN      UCHAR                   WCID,
1369         IN      ULONG                   Length,
1370         IN      UCHAR                   PID,
1371         IN      UCHAR                   TID,
1372         IN      UCHAR                   TxRate,
1373         IN      UCHAR                   Txopmode,
1374         IN      BOOLEAN                 CfAck,
1375         IN      HTTRANSMIT_SETTING      *pTransmit)
1376 {
1377         PMAC_TABLE_ENTRY        pMac = NULL;
1378         TXWI_STRUC              TxWI;
1379         PTXWI_STRUC     pTxWI;
1380
1381         if (WCID < MAX_LEN_OF_MAC_TABLE)
1382                 pMac = &pAd->MacTab.Content[WCID];
1383
1384         //
1385         // Always use Long preamble before verifiation short preamble functionality works well.
1386         // Todo: remove the following line if short preamble functionality works
1387         //
1388         OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1389         NdisZeroMemory(&TxWI, TXWI_SIZE);
1390         pTxWI = &TxWI;
1391
1392         pTxWI->FRAG= FRAG;
1393
1394         pTxWI->CFACK = CFACK;
1395         pTxWI->TS= InsTimestamp;
1396         pTxWI->AMPDU = AMPDU;
1397         pTxWI->ACK = Ack;
1398         pTxWI->txop= Txopmode;
1399
1400         pTxWI->NSEQ = NSeq;
1401         // John tune the performace with Intel Client in 20 MHz performance
1402         BASize = pAd->CommonCfg.TxBASize;
1403
1404         if( BASize >7 )
1405                 BASize =7;
1406         pTxWI->BAWinSize = BASize;
1407         pTxWI->ShortGI = pTransmit->field.ShortGI;
1408         pTxWI->STBC = pTransmit->field.STBC;
1409
1410         pTxWI->WirelessCliID = WCID;
1411         pTxWI->MPDUtotalByteCount = Length;
1412         pTxWI->PacketId = PID;
1413
1414         // If CCK or OFDM, BW must be 20
1415         pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1416
1417         pTxWI->MCS = pTransmit->field.MCS;
1418         pTxWI->PHYMODE = pTransmit->field.MODE;
1419         pTxWI->CFACK = CfAck;
1420
1421         if (pMac)
1422         {
1423                 if (pAd->CommonCfg.bMIMOPSEnable)
1424                 {
1425                         if ((pMac->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1426                         {
1427                                 // Dynamic MIMO Power Save Mode
1428                                 pTxWI->MIMOps = 1;
1429                         }
1430                         else if (pMac->MmpsMode == MMPS_STATIC)
1431                         {
1432                                 // Static MIMO Power Save Mode
1433                                 if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
1434                                 {
1435                                         pTxWI->MCS = 7;
1436                                         pTxWI->MIMOps = 0;
1437                                 }
1438                         }
1439                 }
1440                 //pTxWI->MIMOps = (pMac->PsMode == PWR_MMPS)? 1:0;
1441                 if (pMac->bIAmBadAtheros && (pMac->WepStatus != Ndis802_11WEPDisabled))
1442                 {
1443                         pTxWI->MpduDensity = 7;
1444                 }
1445                 else
1446                 {
1447                         pTxWI->MpduDensity = pMac->MpduDensity;
1448                 }
1449         }
1450
1451         pTxWI->PacketId = pTxWI->MCS;
1452         NdisMoveMemory(pOutTxWI, &TxWI, sizeof(TXWI_STRUC));
1453 }
1454
1455
1456 VOID RTMPWriteTxWI_Data(
1457         IN      PRTMP_ADAPTER           pAd,
1458         IN      OUT PTXWI_STRUC         pTxWI,
1459         IN      TX_BLK                          *pTxBlk)
1460 {
1461         HTTRANSMIT_SETTING      *pTransmit;
1462         PMAC_TABLE_ENTRY        pMacEntry;
1463         UCHAR                           BASize;
1464
1465         ASSERT(pTxWI);
1466
1467         pTransmit = pTxBlk->pTransmit;
1468         pMacEntry = pTxBlk->pMacEntry;
1469
1470
1471         //
1472         // Always use Long preamble before verifiation short preamble functionality works well.
1473         // Todo: remove the following line if short preamble functionality works
1474         //
1475         OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1476         NdisZeroMemory(pTxWI, TXWI_SIZE);
1477
1478         pTxWI->FRAG             = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag);
1479         pTxWI->ACK              = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAckRequired);
1480         pTxWI->txop             = pTxBlk->FrameGap;
1481
1482                 pTxWI->WirelessCliID            = pTxBlk->Wcid;
1483
1484         pTxWI->MPDUtotalByteCount       = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
1485         pTxWI->CFACK                            = TX_BLK_TEST_FLAG(pTxBlk, fTX_bPiggyBack);
1486
1487         // If CCK or OFDM, BW must be 20
1488         pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1489         pTxWI->AMPDU    = ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) ? TRUE : FALSE);
1490
1491         // John tune the performace with Intel Client in 20 MHz performance
1492         BASize = pAd->CommonCfg.TxBASize;
1493         if((pTxBlk->TxFrameType == TX_AMPDU_FRAME) && (pMacEntry))
1494         {
1495                 UCHAR           RABAOriIdx = 0; //The RA's BA Originator table index.
1496
1497                 RABAOriIdx = pTxBlk->pMacEntry->BAOriWcidArray[pTxBlk->UserPriority];
1498                 BASize = pAd->BATable.BAOriEntry[RABAOriIdx].BAWinSize;
1499         }
1500
1501         pTxWI->TxBF = pTransmit->field.TxBF;
1502         pTxWI->BAWinSize = BASize;
1503         pTxWI->ShortGI = pTransmit->field.ShortGI;
1504         pTxWI->STBC = pTransmit->field.STBC;
1505
1506         pTxWI->MCS = pTransmit->field.MCS;
1507         pTxWI->PHYMODE = pTransmit->field.MODE;
1508
1509         if (pMacEntry)
1510         {
1511                 if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1512                 {
1513                         // Dynamic MIMO Power Save Mode
1514                         pTxWI->MIMOps = 1;
1515                 }
1516                 else if (pMacEntry->MmpsMode == MMPS_STATIC)
1517                 {
1518                         // Static MIMO Power Save Mode
1519                         if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
1520                         {
1521                                 pTxWI->MCS = 7;
1522                                 pTxWI->MIMOps = 0;
1523                         }
1524                 }
1525
1526                 if (pMacEntry->bIAmBadAtheros && (pMacEntry->WepStatus != Ndis802_11WEPDisabled))
1527                 {
1528                         pTxWI->MpduDensity = 7;
1529                 }
1530                 else
1531                 {
1532                         pTxWI->MpduDensity = pMacEntry->MpduDensity;
1533                 }
1534         }
1535
1536 #ifdef DBG_DIAGNOSE
1537                 if (pTxBlk->QueIdx== 0)
1538                 {
1539                         pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
1540                         pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
1541                 }
1542 #endif // DBG_DIAGNOSE //
1543
1544         // for rate adapation
1545         pTxWI->PacketId = pTxWI->MCS;
1546 }
1547
1548
1549 VOID RTMPWriteTxWI_Cache(
1550         IN      PRTMP_ADAPTER           pAd,
1551         IN      OUT PTXWI_STRUC         pTxWI,
1552         IN      TX_BLK                          *pTxBlk)
1553 {
1554         PHTTRANSMIT_SETTING     pTransmit;
1555         PMAC_TABLE_ENTRY        pMacEntry;
1556
1557         //
1558         // update TXWI
1559         //
1560         pMacEntry = pTxBlk->pMacEntry;
1561         pTransmit = pTxBlk->pTransmit;
1562
1563         if (pMacEntry->bAutoTxRateSwitch)
1564         {
1565                 pTxWI->txop = IFS_HTTXOP;
1566
1567                 // If CCK or OFDM, BW must be 20
1568                 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1569                 pTxWI->ShortGI = pTransmit->field.ShortGI;
1570                 pTxWI->STBC = pTransmit->field.STBC;
1571
1572                 pTxWI->MCS = pTransmit->field.MCS;
1573                 pTxWI->PHYMODE = pTransmit->field.MODE;
1574
1575                 // set PID for TxRateSwitching
1576                 pTxWI->PacketId = pTransmit->field.MCS;
1577         }
1578
1579         pTxWI->AMPDU = ((pMacEntry->NoBADataCountDown == 0) ? TRUE: FALSE);
1580         pTxWI->MIMOps = 0;
1581
1582         if (pAd->CommonCfg.bMIMOPSEnable)
1583         {
1584                 // MIMO Power Save Mode
1585                 if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1586                 {
1587                         // Dynamic MIMO Power Save Mode
1588                         pTxWI->MIMOps = 1;
1589                 }
1590                 else if (pMacEntry->MmpsMode == MMPS_STATIC)
1591                 {
1592                         // Static MIMO Power Save Mode
1593                         if ((pTransmit->field.MODE >= MODE_HTMIX) && (pTransmit->field.MCS > 7))
1594                         {
1595                                 pTxWI->MCS = 7;
1596                                 pTxWI->MIMOps = 0;
1597                         }
1598                 }
1599         }
1600
1601 #ifdef DBG_DIAGNOSE
1602         if (pTxBlk->QueIdx== 0)
1603         {
1604                 pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
1605                 pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
1606         }
1607 #endif // DBG_DIAGNOSE //
1608
1609         pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
1610
1611 }
1612
1613
1614 /*
1615         ========================================================================
1616
1617         Routine Description:
1618                 Calculates the duration which is required to transmit out frames
1619         with given size and specified rate.
1620
1621         Arguments:
1622                 pTxD            Pointer to transmit descriptor
1623                 Ack             Setting for Ack requirement bit
1624                 Fragment        Setting for Fragment bit
1625                 RetryMode       Setting for retry mode
1626                 Ifs             Setting for IFS gap
1627                 Rate            Setting for transmit rate
1628                 Service         Setting for service
1629                 Length          Frame length
1630                 TxPreamble      Short or Long preamble when using CCK rates
1631                 QueIdx - 0-3, according to 802.11e/d4.4 June/2003
1632
1633         Return Value:
1634                 None
1635
1636         IRQL = PASSIVE_LEVEL
1637         IRQL = DISPATCH_LEVEL
1638
1639         ========================================================================
1640 */
1641 VOID RTMPWriteTxDescriptor(
1642         IN      PRTMP_ADAPTER   pAd,
1643         IN      PTXD_STRUC              pTxD,
1644         IN      BOOLEAN                 bWIV,
1645         IN      UCHAR                   QueueSEL)
1646 {
1647         //
1648         // Always use Long preamble before verifiation short preamble functionality works well.
1649         // Todo: remove the following line if short preamble functionality works
1650         //
1651         OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1652
1653         pTxD->WIV       = (bWIV) ? 1: 0;
1654         pTxD->QSEL= (QueueSEL);
1655         if (pAd->bGenOneHCCA == TRUE)
1656                 pTxD->QSEL= FIFO_HCCA;
1657         pTxD->DMADONE = 0;
1658 }
1659
1660
1661 // should be called only when -
1662 // 1. MEADIA_CONNECTED
1663 // 2. AGGREGATION_IN_USED
1664 // 3. Fragmentation not in used
1665 // 4. either no previous frame (pPrevAddr1=NULL) .OR. previoud frame is aggregatible
1666 BOOLEAN TxFrameIsAggregatible(
1667         IN      PRTMP_ADAPTER   pAd,
1668         IN      PUCHAR                  pPrevAddr1,
1669         IN      PUCHAR                  p8023hdr)
1670 {
1671
1672         // can't aggregate EAPOL (802.1x) frame
1673         if ((p8023hdr[12] == 0x88) && (p8023hdr[13] == 0x8e))
1674                 return FALSE;
1675
1676         // can't aggregate multicast/broadcast frame
1677         if (p8023hdr[0] & 0x01)
1678                 return FALSE;
1679
1680         if (INFRA_ON(pAd)) // must be unicast to AP
1681                 return TRUE;
1682         else if ((pPrevAddr1 == NULL) || MAC_ADDR_EQUAL(pPrevAddr1, p8023hdr)) // unicast to same STA
1683                 return TRUE;
1684         else
1685                 return FALSE;
1686 }
1687
1688
1689 /*
1690         ========================================================================
1691
1692         Routine Description:
1693            Check the MSDU Aggregation policy
1694         1.HT aggregation is A-MSDU
1695         2.legaacy rate aggregation is software aggregation by Ralink.
1696
1697         Arguments:
1698
1699         Return Value:
1700
1701         Note:
1702
1703         ========================================================================
1704 */
1705 BOOLEAN PeerIsAggreOn(
1706         IN      PRTMP_ADAPTER   pAd,
1707         IN      ULONG              TxRate,
1708         IN      PMAC_TABLE_ENTRY pMacEntry)
1709 {
1710         ULONG   AFlags = (fCLIENT_STATUS_AMSDU_INUSED | fCLIENT_STATUS_AGGREGATION_CAPABLE);
1711
1712         if (pMacEntry != NULL && CLIENT_STATUS_TEST_FLAG(pMacEntry, AFlags))
1713         {
1714                 if (pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
1715                 {
1716                         return TRUE;
1717                 }
1718
1719 #ifdef AGGREGATION_SUPPORT
1720                 if (TxRate >= RATE_6 && pAd->CommonCfg.bAggregationCapable && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
1721                 {       // legacy  Ralink Aggregation support
1722                         return TRUE;
1723                 }
1724 #endif // AGGREGATION_SUPPORT //
1725         }
1726
1727         return FALSE;
1728
1729 }
1730
1731
1732 /*
1733         ========================================================================
1734
1735         Routine Description:
1736                 Check and fine the packet waiting in SW queue with highest priority
1737
1738         Arguments:
1739                 pAd Pointer to our adapter
1740
1741         Return Value:
1742                 pQueue          Pointer to Waiting Queue
1743
1744         IRQL = DISPATCH_LEVEL
1745
1746         Note:
1747
1748         ========================================================================
1749 */
1750 PQUEUE_HEADER   RTMPCheckTxSwQueue(
1751         IN      PRTMP_ADAPTER   pAd,
1752         OUT PUCHAR                      pQueIdx)
1753 {
1754
1755         ULONG   Number;
1756
1757         Number = pAd->TxSwQueue[QID_AC_BK].Number
1758                          + pAd->TxSwQueue[QID_AC_BE].Number
1759                          + pAd->TxSwQueue[QID_AC_VI].Number
1760                          + pAd->TxSwQueue[QID_AC_VO].Number
1761                          + pAd->TxSwQueue[QID_HCCA].Number;
1762
1763         if (pAd->TxSwQueue[QID_AC_VO].Head != NULL)
1764         {
1765                 *pQueIdx = QID_AC_VO;
1766                 return (&pAd->TxSwQueue[QID_AC_VO]);
1767         }
1768         else if (pAd->TxSwQueue[QID_AC_VI].Head != NULL)
1769         {
1770                 *pQueIdx = QID_AC_VI;
1771                 return (&pAd->TxSwQueue[QID_AC_VI]);
1772         }
1773         else if (pAd->TxSwQueue[QID_AC_BE].Head != NULL)
1774         {
1775                 *pQueIdx = QID_AC_BE;
1776                 return (&pAd->TxSwQueue[QID_AC_BE]);
1777         }
1778         else if (pAd->TxSwQueue[QID_AC_BK].Head != NULL)
1779         {
1780                 *pQueIdx = QID_AC_BK;
1781                 return (&pAd->TxSwQueue[QID_AC_BK]);
1782         }
1783         else if (pAd->TxSwQueue[QID_HCCA].Head != NULL)
1784         {
1785                 *pQueIdx = QID_HCCA;
1786                 return (&pAd->TxSwQueue[QID_HCCA]);
1787         }
1788
1789         // No packet pending in Tx Sw queue
1790         *pQueIdx = QID_AC_BK;
1791
1792         return (NULL);
1793 }
1794
1795 #ifdef RT2860
1796 BOOLEAN  RTMPFreeTXDUponTxDmaDone(
1797         IN PRTMP_ADAPTER        pAd,
1798         IN UCHAR                        QueIdx)
1799 {
1800         PRTMP_TX_RING pTxRing;
1801         PTXD_STRUC        pTxD;
1802         PNDIS_PACKET  pPacket;
1803         UCHAR   FREE = 0;
1804         TXD_STRUC       TxD, *pOriTxD;
1805         //ULONG         IrqFlags;
1806         BOOLEAN                 bReschedule = FALSE;
1807
1808
1809         ASSERT(QueIdx < NUM_OF_TX_RING);
1810         pTxRing = &pAd->TxRing[QueIdx];
1811
1812         RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF, &pTxRing->TxDmaIdx);
1813         while (pTxRing->TxSwFreeIdx != pTxRing->TxDmaIdx)
1814         {
1815                 // static rate also need NICUpdateFifoStaCounters() function.
1816                 //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
1817                         NICUpdateFifoStaCounters(pAd);
1818
1819                 /* Note : If (pAd->ate.bQATxStart == TRUE), we will never reach here. */
1820                 FREE++;
1821                 pTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
1822                 pOriTxD = pTxD;
1823                 NdisMoveMemory(&TxD, pTxD, sizeof(TXD_STRUC));
1824                 pTxD = &TxD;
1825
1826                 pTxD->DMADONE = 0;
1827
1828 /*====================================================================*/
1829                 {
1830                         pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket;
1831                         if (pPacket)
1832                         {
1833 #ifdef CONFIG_5VT_ENHANCE
1834                                 if (RTMP_GET_PACKET_5VT(pPacket))
1835                                         PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, 16, PCI_DMA_TODEVICE);
1836                                 else
1837 #endif // CONFIG_5VT_ENHANCE //
1838                                         PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
1839                                 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1840                         }
1841                         //Always assign pNdisPacket as NULL after clear
1842                         pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket = NULL;
1843
1844                         pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket;
1845
1846                         ASSERT(pPacket == NULL);
1847                         if (pPacket)
1848                         {
1849 #ifdef CONFIG_5VT_ENHANCE
1850                                 if (RTMP_GET_PACKET_5VT(pPacket))
1851                                         PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, 16, PCI_DMA_TODEVICE);
1852                                 else
1853 #endif // CONFIG_5VT_ENHANCE //
1854                                         PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
1855                                 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1856                         }
1857                         //Always assign pNextNdisPacket as NULL after clear
1858                         pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL;
1859                 }
1860 /*====================================================================*/
1861
1862                 pAd->RalinkCounters.TransmittedByteCount +=  (pTxD->SDLen1 + pTxD->SDLen0);
1863                 pAd->RalinkCounters.OneSecDmaDoneCount[QueIdx] ++;
1864                 INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE);
1865                 /* get tx_tdx_idx again */
1866                 RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF ,  &pTxRing->TxDmaIdx);
1867
1868         NdisMoveMemory(pOriTxD, pTxD, sizeof(TXD_STRUC));
1869         }
1870
1871
1872         return  bReschedule;
1873
1874 }
1875
1876
1877 /*
1878         ========================================================================
1879
1880         Routine Description:
1881                 Process TX Rings DMA Done interrupt, running in DPC level
1882
1883         Arguments:
1884                 Adapter         Pointer to our adapter
1885
1886         Return Value:
1887                 None
1888
1889         IRQL = DISPATCH_LEVEL
1890
1891         ========================================================================
1892 */
1893 BOOLEAN RTMPHandleTxRingDmaDoneInterrupt(
1894         IN      PRTMP_ADAPTER   pAd,
1895         IN      INT_SOURCE_CSR_STRUC TxRingBitmap)
1896 {
1897     unsigned long       IrqFlags;
1898         BOOLEAN                 bReschedule = FALSE;
1899
1900         // Make sure Tx ring resource won't be used by other threads
1901
1902         RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
1903
1904         if (TxRingBitmap.field.Ac0DmaDone)
1905                 bReschedule = RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BE);
1906
1907         if (TxRingBitmap.field.HccaDmaDone)
1908                 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_HCCA);
1909
1910         if (TxRingBitmap.field.Ac3DmaDone)
1911                 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VO);
1912
1913         if (TxRingBitmap.field.Ac2DmaDone)
1914                 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VI);
1915
1916         if (TxRingBitmap.field.Ac1DmaDone)
1917                 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BK);
1918
1919         // Make sure to release Tx ring resource
1920         RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
1921
1922         // Dequeue outgoing frames from TxSwQueue[] and process it
1923         RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1924
1925         return  bReschedule;
1926 }
1927
1928
1929 /*
1930         ========================================================================
1931
1932         Routine Description:
1933                 Process MGMT ring DMA done interrupt, running in DPC level
1934
1935         Arguments:
1936                 pAd     Pointer to our adapter
1937
1938         Return Value:
1939                 None
1940
1941         IRQL = DISPATCH_LEVEL
1942
1943         Note:
1944
1945         ========================================================================
1946 */
1947 VOID    RTMPHandleMgmtRingDmaDoneInterrupt(
1948         IN      PRTMP_ADAPTER   pAd)
1949 {
1950         PTXD_STRUC       pTxD;
1951         PNDIS_PACKET pPacket;
1952         UCHAR   FREE = 0;
1953         PRTMP_MGMT_RING pMgmtRing = &pAd->MgmtRing;
1954
1955         NdisAcquireSpinLock(&pAd->MgmtRingLock);
1956
1957         RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pMgmtRing->TxDmaIdx);
1958         while (pMgmtRing->TxSwFreeIdx!= pMgmtRing->TxDmaIdx)
1959         {
1960                 FREE++;
1961                 pTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa);
1962                 pTxD->DMADONE = 0;
1963                 pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket;
1964
1965
1966                 if (pPacket)
1967                 {
1968                         PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
1969                         RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1970                 }
1971                 pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket = NULL;
1972
1973                 pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket;
1974                 if (pPacket)
1975                 {
1976                         PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
1977                         RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1978                 }
1979                 pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket = NULL;
1980                 INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE);
1981         }
1982         NdisReleaseSpinLock(&pAd->MgmtRingLock);
1983
1984 }
1985
1986
1987 /*
1988         ========================================================================
1989
1990         Routine Description:
1991         Arguments:
1992                 Adapter         Pointer to our adapter. Dequeue all power safe delayed braodcast frames after beacon.
1993
1994         IRQL = DISPATCH_LEVEL
1995
1996         ========================================================================
1997 */
1998 VOID    RTMPHandleTBTTInterrupt(
1999         IN PRTMP_ADAPTER pAd)
2000 {
2001         {
2002                 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
2003                 {
2004                 }
2005         }
2006 }
2007
2008
2009 /*
2010         ========================================================================
2011
2012         Routine Description:
2013         Arguments:
2014                 Adapter         Pointer to our adapter. Rewrite beacon content before next send-out.
2015
2016         IRQL = DISPATCH_LEVEL
2017
2018         ========================================================================
2019 */
2020 VOID    RTMPHandlePreTBTTInterrupt(
2021         IN PRTMP_ADAPTER pAd)
2022 {
2023         {
2024                 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
2025                 {
2026                         DBGPRINT(RT_DEBUG_TRACE, ("RTMPHandlePreTBTTInterrupt...\n"));
2027                 }
2028         }
2029
2030
2031 }
2032
2033 VOID    RTMPHandleRxCoherentInterrupt(
2034         IN      PRTMP_ADAPTER   pAd)
2035 {
2036         WPDMA_GLO_CFG_STRUC     GloCfg;
2037
2038         if (pAd == NULL)
2039         {
2040                 DBGPRINT(RT_DEBUG_TRACE, ("====> pAd is NULL, return.\n"));
2041                 return;
2042         }
2043
2044         DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPHandleRxCoherentInterrupt \n"));
2045
2046         RTMP_IO_READ32(pAd, WPDMA_GLO_CFG , &GloCfg.word);
2047
2048         GloCfg.field.EnTXWriteBackDDONE = 0;
2049         GloCfg.field.EnableRxDMA = 0;
2050         GloCfg.field.EnableTxDMA = 0;
2051         RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
2052
2053         RTMPRingCleanUp(pAd, QID_AC_BE);
2054         RTMPRingCleanUp(pAd, QID_AC_BK);
2055         RTMPRingCleanUp(pAd, QID_AC_VI);
2056         RTMPRingCleanUp(pAd, QID_AC_VO);
2057         RTMPRingCleanUp(pAd, QID_HCCA);
2058         RTMPRingCleanUp(pAd, QID_MGMT);
2059         RTMPRingCleanUp(pAd, QID_RX);
2060
2061         RTMPEnableRxTx(pAd);
2062
2063         DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPHandleRxCoherentInterrupt \n"));
2064 }
2065
2066
2067 VOID DBGPRINT_TX_RING(
2068         IN PRTMP_ADAPTER  pAd,
2069         IN UCHAR          QueIdx)
2070 {
2071         UINT32          Ac0Base;
2072         UINT32          Ac0HwIdx = 0, Ac0SwIdx = 0, AC0freeIdx;
2073         int                     i;
2074         PULONG  ptemp;
2075
2076         DBGPRINT_RAW(RT_DEBUG_TRACE, ("=====================================================\n "  ));
2077         switch (QueIdx)
2078         {
2079                 case QID_AC_BE:
2080                         RTMP_IO_READ32(pAd, TX_BASE_PTR0, &Ac0Base);
2081                         RTMP_IO_READ32(pAd, TX_CTX_IDX0, &Ac0SwIdx);
2082                         RTMP_IO_READ32(pAd, TX_DTX_IDX0, &Ac0HwIdx);
2083                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_BE DESCRIPTOR  \n "  ));
2084                         for (i=0;i<TX_RING_SIZE;i++)
2085                         {
2086                                 ptemp= (PULONG)pAd->TxRing[QID_AC_BE].Cell[i].AllocVa;
2087                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
2088                         }
2089                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("  \n "  ));
2090                         break;
2091                 case QID_AC_BK:
2092                         RTMP_IO_READ32(pAd, TX_BASE_PTR1, &Ac0Base);
2093                         RTMP_IO_READ32(pAd, TX_CTX_IDX1, &Ac0SwIdx);
2094                         RTMP_IO_READ32(pAd, TX_DTX_IDX1, &Ac0HwIdx);
2095                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_BK DESCRIPTOR  \n "  ));
2096                         for (i=0;i<TX_RING_SIZE;i++)
2097                         {
2098                                 ptemp= (PULONG)pAd->TxRing[QID_AC_BK].Cell[i].AllocVa;
2099                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
2100                         }
2101                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("  \n "  ));
2102                         break;
2103                 case QID_AC_VI:
2104                         RTMP_IO_READ32(pAd, TX_BASE_PTR2, &Ac0Base);
2105                         RTMP_IO_READ32(pAd, TX_CTX_IDX2, &Ac0SwIdx);
2106                         RTMP_IO_READ32(pAd, TX_DTX_IDX2, &Ac0HwIdx);
2107                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_VI DESCRIPTOR \n "  ));
2108                         for (i=0;i<TX_RING_SIZE;i++)
2109                         {
2110                                 ptemp= (PULONG)pAd->TxRing[QID_AC_VI].Cell[i].AllocVa;
2111                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
2112                         }
2113                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("  \n "  ));
2114                         break;
2115                 case QID_AC_VO:
2116                         RTMP_IO_READ32(pAd, TX_BASE_PTR3, &Ac0Base);
2117                         RTMP_IO_READ32(pAd, TX_CTX_IDX3, &Ac0SwIdx);
2118                         RTMP_IO_READ32(pAd, TX_DTX_IDX3, &Ac0HwIdx);
2119                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_VO DESCRIPTOR \n "  ));
2120                         for (i=0;i<TX_RING_SIZE;i++)
2121                         {
2122                                 ptemp= (PULONG)pAd->TxRing[QID_AC_VO].Cell[i].AllocVa;
2123                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
2124                         }
2125                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("  \n "  ));
2126                         break;
2127                 case QID_MGMT:
2128                         RTMP_IO_READ32(pAd, TX_BASE_PTR5, &Ac0Base);
2129                         RTMP_IO_READ32(pAd, TX_CTX_IDX5, &Ac0SwIdx);
2130                         RTMP_IO_READ32(pAd, TX_DTX_IDX5, &Ac0HwIdx);
2131                         DBGPRINT_RAW(RT_DEBUG_TRACE, (" All QID_MGMT  DESCRIPTOR \n "  ));
2132                         for (i=0;i<MGMT_RING_SIZE;i++)
2133                         {
2134                                 ptemp= (PULONG)pAd->MgmtRing.Cell[i].AllocVa;
2135                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
2136                         }
2137                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("  \n "  ));
2138                         break;
2139
2140                 default:
2141                         DBGPRINT_ERR(("DBGPRINT_TX_RING(Ring %d) not supported\n", QueIdx));
2142                         break;
2143         }
2144         AC0freeIdx = pAd->TxRing[QueIdx].TxSwFreeIdx;
2145
2146         DBGPRINT(RT_DEBUG_TRACE,("TxRing%d, TX_DTX_IDX=%d, TX_CTX_IDX=%d\n", QueIdx, Ac0HwIdx, Ac0SwIdx));
2147         DBGPRINT_RAW(RT_DEBUG_TRACE,("  TxSwFreeIdx[%d]", AC0freeIdx));
2148         DBGPRINT_RAW(RT_DEBUG_TRACE,("  pending-NDIS=%ld\n", pAd->RalinkCounters.PendingNdisPacketCount));
2149
2150
2151 }
2152
2153
2154 VOID DBGPRINT_RX_RING(
2155         IN PRTMP_ADAPTER  pAd)
2156 {
2157         UINT32          Ac0Base;
2158         UINT32          Ac0HwIdx = 0, Ac0SwIdx = 0, AC0freeIdx;
2159         int                     i;
2160         UINT32  *ptemp;
2161
2162         DBGPRINT_RAW(RT_DEBUG_TRACE, ("=====================================================\n "  ));
2163         RTMP_IO_READ32(pAd, RX_BASE_PTR, &Ac0Base);
2164         RTMP_IO_READ32(pAd, RX_CRX_IDX, &Ac0SwIdx);
2165         RTMP_IO_READ32(pAd, RX_DRX_IDX, &Ac0HwIdx);
2166         AC0freeIdx = pAd->RxRing.RxSwReadIdx;
2167
2168         DBGPRINT_RAW(RT_DEBUG_TRACE, ("All RX DSP  \n "  ));
2169         for (i=0;i<RX_RING_SIZE;i++)
2170         {
2171                 ptemp = (UINT32 *)pAd->RxRing.Cell[i].AllocVa;
2172                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08x: %08x: %08x: %08x\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
2173         }
2174         DBGPRINT(RT_DEBUG_TRACE,("RxRing, RX_DRX_IDX=%d, RX_CRX_IDX=%d \n", Ac0HwIdx, Ac0SwIdx));
2175         DBGPRINT_RAW(RT_DEBUG_TRACE,("  RxSwReadIdx [%d]=", AC0freeIdx));
2176         DBGPRINT_RAW(RT_DEBUG_TRACE,("  pending-NDIS=%ld\n", pAd->RalinkCounters.PendingNdisPacketCount));
2177 }
2178 #endif /* RT2860 */
2179
2180 /*
2181         ========================================================================
2182
2183         Routine Description:
2184                 Suspend MSDU transmission
2185
2186         Arguments:
2187                 pAd     Pointer to our adapter
2188
2189         Return Value:
2190                 None
2191
2192         Note:
2193
2194         ========================================================================
2195 */
2196 VOID    RTMPSuspendMsduTransmission(
2197         IN      PRTMP_ADAPTER   pAd)
2198 {
2199         DBGPRINT(RT_DEBUG_TRACE,("SCANNING, suspend MSDU transmission ...\n"));
2200
2201
2202         //
2203         // Before BSS_SCAN_IN_PROGRESS, we need to keep Current R66 value and
2204         // use Lowbound as R66 value on ScanNextChannel(...)
2205         //
2206         RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
2207
2208         // set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning)
2209         RTMPSetAGCInitValue(pAd, BW_20);
2210
2211         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2212 }
2213
2214
2215 /*
2216         ========================================================================
2217
2218         Routine Description:
2219                 Resume MSDU transmission
2220
2221         Arguments:
2222                 pAd     Pointer to our adapter
2223
2224         Return Value:
2225                 None
2226
2227         IRQL = DISPATCH_LEVEL
2228
2229         Note:
2230
2231         ========================================================================
2232 */
2233 VOID RTMPResumeMsduTransmission(
2234         IN      PRTMP_ADAPTER   pAd)
2235 {
2236         DBGPRINT(RT_DEBUG_TRACE,("SCAN done, resume MSDU transmission ...\n"));
2237
2238 #ifdef RT30xx
2239         // After finish BSS_SCAN_IN_PROGRESS, we need to restore Current R66 value
2240         // R66 should not be 0
2241         if (pAd->BbpTuning.R66CurrentValue == 0)
2242         {
2243                 pAd->BbpTuning.R66CurrentValue = 0x38;
2244                 DBGPRINT_ERR(("RTMPResumeMsduTransmission, R66CurrentValue=0...\n"));
2245         }
2246 #endif
2247         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, pAd->BbpTuning.R66CurrentValue);
2248
2249         RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2250         RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
2251 }
2252
2253
2254 UINT deaggregate_AMSDU_announce(
2255         IN      PRTMP_ADAPTER   pAd,
2256         PNDIS_PACKET            pPacket,
2257         IN      PUCHAR                  pData,
2258         IN      ULONG                   DataSize)
2259 {
2260         USHORT                  PayloadSize;
2261         USHORT                  SubFrameSize;
2262         PHEADER_802_3   pAMSDUsubheader;
2263         UINT                    nMSDU;
2264     UCHAR                       Header802_3[14];
2265
2266         PUCHAR                  pPayload, pDA, pSA, pRemovedLLCSNAP;
2267         PNDIS_PACKET    pClonePacket;
2268
2269
2270
2271         nMSDU = 0;
2272
2273         while (DataSize > LENGTH_802_3)
2274         {
2275
2276                 nMSDU++;
2277
2278                 pAMSDUsubheader = (PHEADER_802_3)pData;
2279                 PayloadSize = pAMSDUsubheader->Octet[1] + (pAMSDUsubheader->Octet[0]<<8);
2280                 SubFrameSize = PayloadSize + LENGTH_802_3;
2281
2282
2283                 if ((DataSize < SubFrameSize) || (PayloadSize > 1518 ))
2284                 {
2285                         break;
2286                 }
2287
2288                 pPayload = pData + LENGTH_802_3;
2289                 pDA = pData;
2290                 pSA = pData + MAC_ADDR_LEN;
2291
2292                 // convert to 802.3 header
2293         CONVERT_TO_802_3(Header802_3, pDA, pSA, pPayload, PayloadSize, pRemovedLLCSNAP);
2294
2295                 if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E) )
2296                 {
2297                     // avoid local heap overflow, use dyanamic allocation
2298                    MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
2299                    memmove(Elem->Msg+(LENGTH_802_11 + LENGTH_802_1_H), pPayload, PayloadSize);
2300                    Elem->MsgLen = LENGTH_802_11 + LENGTH_802_1_H + PayloadSize;
2301                    WpaEAPOLKeyAction(pAd, Elem);
2302                    kfree(Elem);
2303                 }
2304
2305                 {
2306                         if (pRemovedLLCSNAP)
2307                         {
2308                                 pPayload -= LENGTH_802_3;
2309                                 PayloadSize += LENGTH_802_3;
2310                                 NdisMoveMemory(pPayload, &Header802_3[0], LENGTH_802_3);
2311                         }
2312                 }
2313
2314                 pClonePacket = ClonePacket(pAd, pPacket, pPayload, PayloadSize);
2315                 if (pClonePacket)
2316                 {
2317                         ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pClonePacket, RTMP_GET_PACKET_IF(pPacket));
2318                 }
2319
2320
2321                 // A-MSDU has padding to multiple of 4 including subframe header.
2322                 // align SubFrameSize up to multiple of 4
2323                 SubFrameSize = (SubFrameSize+3)&(~0x3);
2324
2325
2326                 if (SubFrameSize > 1528 || SubFrameSize < 32)
2327                 {
2328                         break;
2329                 }
2330
2331                 if (DataSize > SubFrameSize)
2332                 {
2333                         pData += SubFrameSize;
2334                         DataSize -= SubFrameSize;
2335                 }
2336                 else
2337                 {
2338                         // end of A-MSDU
2339                         DataSize = 0;
2340                 }
2341         }
2342
2343         // finally release original rx packet
2344         RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
2345
2346         return nMSDU;
2347 }
2348
2349
2350 UINT BA_Reorder_AMSDU_Annnounce(
2351         IN      PRTMP_ADAPTER   pAd,
2352         IN      PNDIS_PACKET    pPacket)
2353 {
2354         PUCHAR                  pData;
2355         USHORT                  DataSize;
2356         UINT                    nMSDU = 0;
2357
2358         pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
2359         DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
2360
2361         nMSDU = deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
2362
2363         return nMSDU;
2364 }
2365
2366
2367 /*
2368         ==========================================================================
2369         Description:
2370                 Look up the MAC address in the MAC table. Return NULL if not found.
2371         Return:
2372                 pEntry - pointer to the MAC entry; NULL is not found
2373         ==========================================================================
2374 */
2375 MAC_TABLE_ENTRY *MacTableLookup(
2376         IN PRTMP_ADAPTER pAd,
2377         PUCHAR pAddr)
2378 {
2379         ULONG HashIdx;
2380         MAC_TABLE_ENTRY *pEntry = NULL;
2381
2382         HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
2383         pEntry = pAd->MacTab.Hash[HashIdx];
2384
2385         while (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsWDS || pEntry->ValidAsApCli || pEntry->ValidAsMesh))
2386         {
2387                 if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
2388                 {
2389                         break;
2390                 }
2391                 else
2392                         pEntry = pEntry->pNext;
2393         }
2394
2395         return pEntry;
2396 }
2397
2398 MAC_TABLE_ENTRY *MacTableInsertEntry(
2399         IN  PRTMP_ADAPTER   pAd,
2400         IN  PUCHAR                      pAddr,
2401         IN      UCHAR                   apidx,
2402         IN BOOLEAN      CleanAll)
2403 {
2404         UCHAR HashIdx;
2405         int i, FirstWcid;
2406         MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
2407
2408         // if FULL, return
2409         if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
2410                 return NULL;
2411
2412         FirstWcid = 1;
2413
2414         if (pAd->StaCfg.BssType == BSS_INFRA)
2415                 FirstWcid = 2;
2416
2417         // allocate one MAC entry
2418         NdisAcquireSpinLock(&pAd->MacTabLock);
2419         for (i = FirstWcid; i< MAX_LEN_OF_MAC_TABLE; i++)   // skip entry#0 so that "entry index == AID" for fast lookup
2420         {
2421                 // pick up the first available vacancy
2422                 if ((pAd->MacTab.Content[i].ValidAsCLI == FALSE) &&
2423                         (pAd->MacTab.Content[i].ValidAsWDS == FALSE) &&
2424                         (pAd->MacTab.Content[i].ValidAsApCli== FALSE) &&
2425                         (pAd->MacTab.Content[i].ValidAsMesh == FALSE)
2426                         )
2427                 {
2428                         pEntry = &pAd->MacTab.Content[i];
2429                         if (CleanAll == TRUE)
2430                         {
2431                                 pEntry->MaxSupportedRate = RATE_11;
2432                                 pEntry->CurrTxRate = RATE_11;
2433                                 NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
2434                                 pEntry->PairwiseKey.KeyLen = 0;
2435                                 pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
2436                         }
2437                         {
2438                                 {
2439                                         pEntry->ValidAsCLI = TRUE;
2440                                         pEntry->ValidAsWDS = FALSE;
2441                                         pEntry->ValidAsApCli = FALSE;
2442                                         pEntry->ValidAsMesh = FALSE;
2443                                         pEntry->ValidAsDls = FALSE;
2444                                 }
2445                         }
2446
2447                         pEntry->bIAmBadAtheros = FALSE;
2448                         pEntry->pAd = pAd;
2449                         pEntry->CMTimerRunning = FALSE;
2450                         pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
2451                         pEntry->RSNIE_Len = 0;
2452                         NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter));
2453                         pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
2454
2455                         if (pEntry->ValidAsMesh)
2456                                 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_MESH);
2457                         else if (pEntry->ValidAsApCli)
2458                                 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_APCLI);
2459                         else if (pEntry->ValidAsWDS)
2460                                 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_WDS);
2461                         else
2462                                 pEntry->apidx = apidx;
2463
2464                         {
2465                                 {
2466                                         pEntry->AuthMode = pAd->StaCfg.AuthMode;
2467                                         pEntry->WepStatus = pAd->StaCfg.WepStatus;
2468                                         pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
2469 #ifdef RT2860
2470                                         AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)i);
2471 #endif
2472                                 }
2473                         }
2474
2475                         pEntry->GTKState = REKEY_NEGOTIATING;
2476                         pEntry->PairwiseKey.KeyLen = 0;
2477                         pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
2478
2479 #ifdef RT2860
2480                         if ((pAd->OpMode == OPMODE_STA) &&
2481                                 (pAd->StaCfg.BssType == BSS_ADHOC))
2482                                 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
2483                         else
2484 #endif
2485                         pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2486
2487                         pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
2488                         COPY_MAC_ADDR(pEntry->Addr, pAddr);
2489                         pEntry->Sst = SST_NOT_AUTH;
2490                         pEntry->AuthState = AS_NOT_AUTH;
2491                         pEntry->Aid = (USHORT)i;  //0;
2492                         pEntry->CapabilityInfo = 0;
2493                         pEntry->PsMode = PWR_ACTIVE;
2494                         pEntry->PsQIdleCount = 0;
2495                         pEntry->NoDataIdleCount = 0;
2496                         pEntry->ContinueTxFailCnt = 0;
2497                         InitializeQueueHeader(&pEntry->PsQueue);
2498
2499
2500                         pAd->MacTab.Size ++;
2501                         // Add this entry into ASIC RX WCID search table
2502                         RT28XX_STA_ENTRY_ADD(pAd, pEntry);
2503
2504
2505
2506                         DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertEntry - allocate entry #%d, Total= %d\n",i, pAd->MacTab.Size));
2507                         break;
2508                 }
2509         }
2510
2511         // add this MAC entry into HASH table
2512         if (pEntry)
2513         {
2514                 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
2515                 if (pAd->MacTab.Hash[HashIdx] == NULL)
2516                 {
2517                         pAd->MacTab.Hash[HashIdx] = pEntry;
2518                 }
2519                 else
2520                 {
2521                         pCurrEntry = pAd->MacTab.Hash[HashIdx];
2522                         while (pCurrEntry->pNext != NULL)
2523                                 pCurrEntry = pCurrEntry->pNext;
2524                         pCurrEntry->pNext = pEntry;
2525                 }
2526         }
2527
2528         NdisReleaseSpinLock(&pAd->MacTabLock);
2529         return pEntry;
2530 }
2531
2532 /*
2533         ==========================================================================
2534         Description:
2535                 Delete a specified client from MAC table
2536         ==========================================================================
2537  */
2538 BOOLEAN MacTableDeleteEntry(
2539         IN PRTMP_ADAPTER pAd,
2540         IN USHORT wcid,
2541         IN PUCHAR pAddr)
2542 {
2543         USHORT HashIdx;
2544         MAC_TABLE_ENTRY *pEntry, *pPrevEntry, *pProbeEntry;
2545         BOOLEAN Cancelled;
2546
2547         if (wcid >= MAX_LEN_OF_MAC_TABLE)
2548                 return FALSE;
2549
2550         NdisAcquireSpinLock(&pAd->MacTabLock);
2551
2552         HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
2553         pEntry = &pAd->MacTab.Content[wcid];
2554
2555         if (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsApCli || pEntry->ValidAsWDS || pEntry->ValidAsMesh
2556                 ))
2557         {
2558                 if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
2559                 {
2560
2561                         // Delete this entry from ASIC on-chip WCID Table
2562                         RT28XX_STA_ENTRY_MAC_RESET(pAd, wcid);
2563
2564                         // free resources of BA
2565                         BASessionTearDownALL(pAd, pEntry->Aid);
2566
2567                         pPrevEntry = NULL;
2568                         pProbeEntry = pAd->MacTab.Hash[HashIdx];
2569                         ASSERT(pProbeEntry);
2570
2571                         // update Hash list
2572                         do
2573                         {
2574                                 if (pProbeEntry == pEntry)
2575                                 {
2576                                         if (pPrevEntry == NULL)
2577                                         {
2578                                                 pAd->MacTab.Hash[HashIdx] = pEntry->pNext;
2579                                         }
2580                                         else
2581                                         {
2582                                                 pPrevEntry->pNext = pEntry->pNext;
2583                                         }
2584                                         break;
2585                                 }
2586
2587                                 pPrevEntry = pProbeEntry;
2588                                 pProbeEntry = pProbeEntry->pNext;
2589                         } while (pProbeEntry);
2590
2591                         // not found !!!
2592                         ASSERT(pProbeEntry != NULL);
2593
2594                         RT28XX_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid);
2595
2596
2597                 if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
2598                 {
2599                         RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
2600                         pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
2601                 }
2602
2603
2604                         NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
2605                         pAd->MacTab.Size --;
2606                         DBGPRINT(RT_DEBUG_TRACE, ("MacTableDeleteEntry1 - Total= %d\n", pAd->MacTab.Size));
2607                 }
2608                 else
2609                 {
2610                         printk("\n%s: Impossible Wcid = %d !!!!!\n", __func__, wcid);
2611                 }
2612         }
2613
2614         NdisReleaseSpinLock(&pAd->MacTabLock);
2615
2616         //Reset operating mode when no Sta.
2617         if (pAd->MacTab.Size == 0)
2618         {
2619                 pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0;
2620 #ifndef RT30xx
2621                 AsicUpdateProtect(pAd, 0 /*pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode*/, (ALLN_SETPROTECT), TRUE, 0 /*pAd->MacTab.fAnyStationNonGF*/);
2622 #endif
2623 #ifdef RT30xx
2624                 RT28XX_UPDATE_PROTECT(pAd);  // edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
2625 #endif
2626         }
2627
2628         return TRUE;
2629 }
2630
2631
2632 /*
2633         ==========================================================================
2634         Description:
2635                 This routine reset the entire MAC table. All packets pending in
2636                 the power-saving queues are freed here.
2637         ==========================================================================
2638  */
2639 VOID MacTableReset(
2640         IN  PRTMP_ADAPTER  pAd)
2641 {
2642         int         i;
2643
2644         DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n"));
2645         //NdisAcquireSpinLock(&pAd->MacTabLock);
2646
2647         for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
2648         {
2649 #ifdef RT2860
2650                 RT28XX_STA_ENTRY_MAC_RESET(pAd, i);
2651 #endif
2652                 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
2653            {
2654                         // free resources of BA
2655                         BASessionTearDownALL(pAd, i);
2656
2657                         pAd->MacTab.Content[i].ValidAsCLI = FALSE;
2658
2659
2660
2661 #ifdef RT2870
2662                         NdisZeroMemory(pAd->MacTab.Content[i].Addr, 6);
2663                         RT28XX_STA_ENTRY_MAC_RESET(pAd, i);
2664 #endif // RT2870 //
2665
2666                         //AsicDelWcidTab(pAd, i);
2667                 }
2668         }
2669
2670         return;
2671 }
2672
2673 /*
2674         ==========================================================================
2675         Description:
2676
2677         IRQL = DISPATCH_LEVEL
2678
2679         ==========================================================================
2680 */
2681 VOID AssocParmFill(
2682         IN PRTMP_ADAPTER pAd,
2683         IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq,
2684         IN PUCHAR                     pAddr,
2685         IN USHORT                     CapabilityInfo,
2686         IN ULONG                      Timeout,
2687         IN USHORT                     ListenIntv)
2688 {
2689         COPY_MAC_ADDR(AssocReq->Addr, pAddr);
2690         // Add mask to support 802.11b mode only
2691         AssocReq->CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; // not cf-pollable, not cf-poll-request
2692         AssocReq->Timeout = Timeout;
2693         AssocReq->ListenIntv = ListenIntv;
2694 }
2695
2696
2697 /*
2698         ==========================================================================
2699         Description:
2700
2701         IRQL = DISPATCH_LEVEL
2702
2703         ==========================================================================
2704 */
2705 VOID DisassocParmFill(
2706         IN PRTMP_ADAPTER pAd,
2707         IN OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq,
2708         IN PUCHAR pAddr,
2709         IN USHORT Reason)
2710 {
2711         COPY_MAC_ADDR(DisassocReq->Addr, pAddr);
2712         DisassocReq->Reason = Reason;
2713 }
2714
2715
2716 /*
2717         ========================================================================
2718
2719         Routine Description:
2720                 Check the out going frame, if this is an DHCP or ARP datagram
2721         will be duplicate another frame at low data rate transmit.
2722
2723         Arguments:
2724                 pAd             Pointer to our adapter
2725                 pPacket         Pointer to outgoing Ndis frame
2726
2727         Return Value:
2728                 TRUE            To be duplicate at Low data rate transmit. (1mb)
2729                 FALSE           Do nothing.
2730
2731         IRQL = DISPATCH_LEVEL
2732
2733         Note:
2734
2735                 MAC header + IP Header + UDP Header
2736                   14 Bytes        20 Bytes
2737
2738                 UDP Header
2739                 00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|
2740                                                 Source Port
2741                 16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|
2742                                         Destination Port
2743
2744                 port 0x43 means Bootstrap Protocol, server.
2745                 Port 0x44 means Bootstrap Protocol, client.
2746
2747         ========================================================================
2748 */
2749
2750 BOOLEAN RTMPCheckDHCPFrame(
2751         IN      PRTMP_ADAPTER   pAd,
2752         IN      PNDIS_PACKET    pPacket)
2753 {
2754         PACKET_INFO     PacketInfo;
2755         ULONG                   NumberOfBytesRead = 0;
2756         ULONG                   CurrentOffset = 0;
2757         PVOID                   pVirtualAddress = NULL;
2758         UINT                    NdisBufferLength;
2759         PUCHAR                  pSrc;
2760         USHORT                  Protocol;
2761         UCHAR                   ByteOffset36 = 0;
2762         UCHAR                   ByteOffset38 = 0;
2763         BOOLEAN                 ReadFirstParm = TRUE;
2764
2765         RTMP_QueryPacketInfo(pPacket, &PacketInfo, (PUCHAR *)&pVirtualAddress, &NdisBufferLength);
2766
2767         NumberOfBytesRead += NdisBufferLength;
2768         pSrc = (PUCHAR) pVirtualAddress;
2769         Protocol = *(pSrc + 12) * 256 + *(pSrc + 13);
2770
2771         //
2772         // Check DHCP & BOOTP protocol
2773         //
2774         while (NumberOfBytesRead <= PacketInfo.TotalPacketLength)
2775         {
2776                 if ((NumberOfBytesRead >= 35) && (ReadFirstParm == TRUE))
2777                 {
2778                         CurrentOffset = 35 - (NumberOfBytesRead - NdisBufferLength);
2779                         ByteOffset36 = *(pSrc + CurrentOffset);
2780                         ReadFirstParm = FALSE;
2781                 }
2782
2783                 if (NumberOfBytesRead >= 37)
2784                 {
2785                         CurrentOffset = 37 - (NumberOfBytesRead - NdisBufferLength);
2786                         ByteOffset38 = *(pSrc + CurrentOffset);
2787                         //End of Read
2788                         break;
2789                 }
2790                 return FALSE;
2791         }
2792
2793         // Check for DHCP & BOOTP protocol
2794         if ((ByteOffset36 != 0x44) || (ByteOffset38 != 0x43))
2795                 {
2796                 //
2797                 // 2054 (hex 0806) for ARP datagrams
2798                 // if this packet is not ARP datagrams, then do nothing
2799                 // ARP datagrams will also be duplicate at 1mb broadcast frames
2800                 //
2801                 if (Protocol != 0x0806 )
2802                         return FALSE;
2803                 }
2804
2805         return TRUE;
2806 }
2807
2808
2809 BOOLEAN RTMPCheckEtherType(
2810         IN      PRTMP_ADAPTER   pAd,
2811         IN      PNDIS_PACKET    pPacket)
2812 {
2813         USHORT  TypeLen;
2814         UCHAR   Byte0, Byte1;
2815         PUCHAR  pSrcBuf;
2816         UINT32  pktLen;
2817         UINT16  srcPort, dstPort;
2818         BOOLEAN status = TRUE;
2819
2820
2821         pSrcBuf = GET_OS_PKT_DATAPTR(pPacket);
2822         pktLen = GET_OS_PKT_LEN(pPacket);
2823
2824         ASSERT(pSrcBuf);
2825
2826         RTMP_SET_PACKET_SPECIFIC(pPacket, 0);
2827
2828         // get Ethernet protocol field
2829         TypeLen = (pSrcBuf[12] << 8) + pSrcBuf[13];
2830
2831         pSrcBuf += LENGTH_802_3;        // Skip the Ethernet Header.
2832
2833         if (TypeLen <= 1500)
2834         {       // 802.3, 802.3 LLC
2835                 /*
2836                         DestMAC(6) + SrcMAC(6) + Lenght(2) +
2837                         DSAP(1) + SSAP(1) + Control(1) +
2838                         if the DSAP = 0xAA, SSAP=0xAA, Contorl = 0x03, it has a 5-bytes SNAP header.
2839                                 => + SNAP (5, OriginationID(3) + etherType(2))
2840                 */
2841                 if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA && pSrcBuf[2] == 0x03)
2842                 {
2843                         Sniff2BytesFromNdisBuffer(pSrcBuf, 6, &Byte0, &Byte1);
2844                         RTMP_SET_PACKET_LLCSNAP(pPacket, 1);
2845                         TypeLen = (USHORT)((Byte0 << 8) + Byte1);
2846                         pSrcBuf += 8; // Skip this LLC/SNAP header
2847                 }
2848                 else
2849                 {
2850                         //It just has 3-byte LLC header, maybe a legacy ether type frame. we didn't handle it.
2851                 }
2852         }
2853
2854         // If it's a VLAN packet, get the real Type/Length field.
2855         if (TypeLen == 0x8100)
2856         {
2857                 /* 0x8100 means VLAN packets */
2858
2859                 /* Dest. MAC Address (6-bytes) +
2860                    Source MAC Address (6-bytes) +
2861                    Length/Type = 802.1Q Tag Type (2-byte) +
2862                    Tag Control Information (2-bytes) +
2863                    Length / Type (2-bytes) +
2864                    data payload (0-n bytes) +
2865                    Pad (0-p bytes) +
2866                    Frame Check Sequence (4-bytes) */
2867
2868                 RTMP_SET_PACKET_VLAN(pPacket, 1);
2869                 Sniff2BytesFromNdisBuffer(pSrcBuf, 2, &Byte0, &Byte1);
2870                 TypeLen = (USHORT)((Byte0 << 8) + Byte1);
2871
2872                 pSrcBuf += 4; // Skip the VLAN Header.
2873         }
2874
2875         switch (TypeLen)
2876         {
2877                 case 0x0800:
2878                         {
2879                                 ASSERT((pktLen > 34));
2880                                 if (*(pSrcBuf + 9) == 0x11)
2881                                 {       // udp packet
2882                                         ASSERT((pktLen > 34));  // 14 for ethernet header, 20 for IP header
2883
2884                                         pSrcBuf += 20;  // Skip the IP header
2885                                         srcPort = OS_NTOHS(*((UINT16 *)pSrcBuf));
2886                                         dstPort = OS_NTOHS(*((UINT16 *)(pSrcBuf +2)));
2887
2888                                         if ((srcPort==0x44 && dstPort==0x43) || (srcPort==0x43 && dstPort==0x44))
2889                                         {       //It's a BOOTP/DHCP packet
2890                                                 RTMP_SET_PACKET_DHCP(pPacket, 1);
2891                                         }
2892                                 }
2893                         }
2894                         break;
2895                 case 0x0806:
2896                         {
2897                                 //ARP Packet.
2898                                 RTMP_SET_PACKET_DHCP(pPacket, 1);
2899                         }
2900                         break;
2901                 case 0x888e:
2902                         {
2903                                 // EAPOL Packet.
2904                                 RTMP_SET_PACKET_EAPOL(pPacket, 1);
2905                         }
2906                         break;
2907                 default:
2908                         status = FALSE;
2909                         break;
2910         }
2911
2912         return status;
2913
2914 }
2915
2916
2917
2918 VOID Update_Rssi_Sample(
2919         IN PRTMP_ADAPTER        pAd,
2920         IN RSSI_SAMPLE          *pRssi,
2921         IN PRXWI_STRUC          pRxWI)
2922                 {
2923         CHAR    rssi0 = pRxWI->RSSI0;
2924         CHAR    rssi1 = pRxWI->RSSI1;
2925         CHAR    rssi2 = pRxWI->RSSI2;
2926
2927         if (rssi0 != 0)
2928         {
2929                 pRssi->LastRssi0        = ConvertToRssi(pAd, (CHAR)rssi0, RSSI_0);
2930                 pRssi->AvgRssi0X8       = (pRssi->AvgRssi0X8 - pRssi->AvgRssi0) + pRssi->LastRssi0;
2931                 pRssi->AvgRssi0 = pRssi->AvgRssi0X8 >> 3;
2932         }
2933
2934         if (rssi1 != 0)
2935         {
2936                 pRssi->LastRssi1        = ConvertToRssi(pAd, (CHAR)rssi1, RSSI_1);
2937                 pRssi->AvgRssi1X8       = (pRssi->AvgRssi1X8 - pRssi->AvgRssi1) + pRssi->LastRssi1;
2938                 pRssi->AvgRssi1 = pRssi->AvgRssi1X8 >> 3;
2939         }
2940
2941         if (rssi2 != 0)
2942         {
2943                 pRssi->LastRssi2        = ConvertToRssi(pAd, (CHAR)rssi2, RSSI_2);
2944                 pRssi->AvgRssi2X8  = (pRssi->AvgRssi2X8 - pRssi->AvgRssi2) + pRssi->LastRssi2;
2945                 pRssi->AvgRssi2 = pRssi->AvgRssi2X8 >> 3;
2946         }
2947 }
2948
2949
2950
2951 // Normal legacy Rx packet indication
2952 VOID Indicate_Legacy_Packet(
2953         IN      PRTMP_ADAPTER   pAd,
2954         IN      RX_BLK                  *pRxBlk,
2955         IN      UCHAR                   FromWhichBSSID)
2956 {
2957         PNDIS_PACKET    pRxPacket = pRxBlk->pRxPacket;
2958         UCHAR                   Header802_3[LENGTH_802_3];
2959
2960         // 1. get 802.3 Header
2961         // 2. remove LLC
2962         //              a. pointer pRxBlk->pData to payload
2963         //      b. modify pRxBlk->DataSize
2964         RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
2965
2966         if (pRxBlk->DataSize > MAX_RX_PKT_LEN)
2967         {
2968
2969                 // release packet
2970                 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
2971                 return;
2972         }
2973
2974
2975         STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
2976
2977 #ifdef RT2870
2978         if (pAd->CommonCfg.bDisableReordering == 0)
2979         {
2980                 PBA_REC_ENTRY           pBAEntry;
2981                 ULONG                           Now32;
2982                 UCHAR                           Wcid = pRxBlk->pRxWI->WirelessCliID;
2983                 UCHAR                           TID = pRxBlk->pRxWI->TID;
2984                 USHORT                          Idx;
2985
2986 #define REORDERING_PACKET_TIMEOUT               ((100 * HZ)/1000)       // system ticks -- 100 ms
2987
2988                 if (Wcid < MAX_LEN_OF_MAC_TABLE)
2989                 {
2990                         Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
2991                         if (Idx != 0)
2992                         {
2993                                 pBAEntry = &pAd->BATable.BARecEntry[Idx];
2994                                 // update last rx time
2995                                 NdisGetSystemUpTime(&Now32);
2996                                 if ((pBAEntry->list.qlen > 0) &&
2997                                          RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT)))
2998                                         )
2999                                 {
3000                                         printk("Indicate_Legacy_Packet():flush reordering_timeout_mpdus! RxWI->Flags=%d, pRxWI.TID=%d, RxD->AMPDU=%d!\n", pRxBlk->Flags, pRxBlk->pRxWI->TID, pRxBlk->RxD.AMPDU);
3001                                         hex_dump("Dump the legacy Packet:", GET_OS_PKT_DATAPTR(pRxBlk->pRxPacket), 64);
3002                                         ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
3003                                 }
3004                         }
3005                 }
3006         }
3007 #endif // RT2870 //
3008
3009         wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
3010
3011         //
3012         // pass this 802.3 packet to upper layer or forward this packet to WM directly
3013         //
3014         ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxPacket, FromWhichBSSID);
3015 }
3016
3017
3018 // Normal, AMPDU or AMSDU
3019 VOID CmmRxnonRalinkFrameIndicate(
3020         IN      PRTMP_ADAPTER   pAd,
3021         IN      RX_BLK                  *pRxBlk,
3022         IN      UCHAR                   FromWhichBSSID)
3023 {
3024         if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
3025         {
3026                 Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
3027         }
3028         else
3029         {
3030                 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
3031                 {
3032                         // handle A-MSDU
3033                         Indicate_AMSDU_Packet(pAd, pRxBlk, FromWhichBSSID);
3034                 }
3035                 else
3036                 {
3037                         Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
3038                 }
3039         }
3040 }
3041
3042
3043 VOID CmmRxRalinkFrameIndicate(
3044         IN      PRTMP_ADAPTER   pAd,
3045         IN      MAC_TABLE_ENTRY *pEntry,
3046         IN      RX_BLK                  *pRxBlk,
3047         IN      UCHAR                   FromWhichBSSID)
3048 {
3049         UCHAR                   Header802_3[LENGTH_802_3];
3050         UINT16                  Msdu2Size;
3051         UINT16                  Payload1Size, Payload2Size;
3052         PUCHAR                  pData2;
3053         PNDIS_PACKET    pPacket2 = NULL;
3054
3055
3056
3057         Msdu2Size = *(pRxBlk->pData) + (*(pRxBlk->pData+1) << 8);
3058
3059         if ((Msdu2Size <= 1536) && (Msdu2Size < pRxBlk->DataSize))
3060         {
3061                 /* skip two byte MSDU2 len */
3062                 pRxBlk->pData += 2;
3063                 pRxBlk->DataSize -= 2;
3064         }
3065         else
3066         {
3067                 // release packet
3068                 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
3069                 return;
3070         }
3071
3072         // get 802.3 Header and  remove LLC
3073         RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
3074
3075         ASSERT(pRxBlk->pRxPacket);
3076
3077         // Ralink Aggregation frame
3078         pAd->RalinkCounters.OneSecRxAggregationCount ++;
3079         Payload1Size = pRxBlk->DataSize - Msdu2Size;
3080         Payload2Size = Msdu2Size - LENGTH_802_3;
3081
3082         pData2 = pRxBlk->pData + Payload1Size + LENGTH_802_3;
3083
3084         pPacket2 = duplicate_pkt(pAd, (pData2-LENGTH_802_3), LENGTH_802_3, pData2, Payload2Size, FromWhichBSSID);
3085
3086         if (!pPacket2)
3087         {
3088                 // release packet
3089                 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
3090                 return;
3091         }
3092
3093         // update payload size of 1st packet
3094         pRxBlk->DataSize = Payload1Size;
3095         wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
3096
3097         ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxBlk->pRxPacket, FromWhichBSSID);
3098
3099         if (pPacket2)
3100         {
3101                 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket2, FromWhichBSSID);
3102         }
3103 }
3104
3105
3106 #define RESET_FRAGFRAME(_fragFrame) \
3107         {                                                               \
3108                 _fragFrame.RxSize = 0;          \
3109                 _fragFrame.Sequence = 0;        \
3110                 _fragFrame.LastFrag = 0;        \
3111                 _fragFrame.Flags = 0;           \
3112         }
3113
3114
3115 PNDIS_PACKET RTMPDeFragmentDataFrame(
3116         IN      PRTMP_ADAPTER   pAd,
3117         IN      RX_BLK                  *pRxBlk)
3118 {
3119         PHEADER_802_11  pHeader = pRxBlk->pHeader;
3120         PNDIS_PACKET    pRxPacket = pRxBlk->pRxPacket;
3121         UCHAR                   *pData = pRxBlk->pData;
3122         USHORT                  DataSize = pRxBlk->DataSize;
3123         PNDIS_PACKET    pRetPacket = NULL;
3124         UCHAR                   *pFragBuffer = NULL;
3125         BOOLEAN                 bReassDone = FALSE;
3126         UCHAR                   HeaderRoom = 0;
3127
3128
3129         ASSERT(pHeader);
3130
3131         HeaderRoom = pData - (UCHAR *)pHeader;
3132
3133         // Re-assemble the fragmented packets
3134         if (pHeader->Frag == 0)         // Frag. Number is 0 : First frag or only one pkt
3135         {
3136                 // the first pkt of fragment, record it.
3137                 if (pHeader->FC.MoreFrag)
3138                 {
3139                         ASSERT(pAd->FragFrame.pFragPacket);
3140                         pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
3141                         pAd->FragFrame.RxSize   = DataSize + HeaderRoom;
3142                         NdisMoveMemory(pFragBuffer,      pHeader, pAd->FragFrame.RxSize);
3143                         pAd->FragFrame.Sequence = pHeader->Sequence;
3144                         pAd->FragFrame.LastFrag = pHeader->Frag;           // Should be 0
3145                         ASSERT(pAd->FragFrame.LastFrag == 0);
3146                         goto done;      // end of processing this frame
3147                 }
3148         }
3149         else    //Middle & End of fragment
3150         {
3151                 if ((pHeader->Sequence != pAd->FragFrame.Sequence) ||
3152                         (pHeader->Frag != (pAd->FragFrame.LastFrag + 1)))
3153                 {
3154                         // Fragment is not the same sequence or out of fragment number order
3155                         // Reset Fragment control blk
3156                         RESET_FRAGFRAME(pAd->FragFrame);
3157                         DBGPRINT(RT_DEBUG_ERROR, ("Fragment is not the same sequence or out of fragment number order.\n"));
3158                         goto done; // give up this frame
3159                 }
3160                 else if ((pAd->FragFrame.RxSize + DataSize) > MAX_FRAME_SIZE)
3161                 {
3162                         // Fragment frame is too large, it exeeds the maximum frame size.
3163                         // Reset Fragment control blk
3164                         RESET_FRAGFRAME(pAd->FragFrame);
3165                         DBGPRINT(RT_DEBUG_ERROR, ("Fragment frame is too large, it exeeds the maximum frame size.\n"));
3166                         goto done; // give up this frame
3167                 }
3168
3169         //
3170                 // Broadcom AP(BCM94704AGR) will send out LLC in fragment's packet, LLC only can accpet at first fragment.
3171                 // In this case, we will dropt it.
3172                 //
3173                 if (NdisEqualMemory(pData, SNAP_802_1H, sizeof(SNAP_802_1H)))
3174                 {
3175                         DBGPRINT(RT_DEBUG_ERROR, ("Find another LLC at Middle or End fragment(SN=%d, Frag=%d)\n", pHeader->Sequence, pHeader->Frag));
3176                         goto done; // give up this frame
3177                 }
3178
3179                 pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
3180
3181                 // concatenate this fragment into the re-assembly buffer
3182                 NdisMoveMemory((pFragBuffer + pAd->FragFrame.RxSize), pData, DataSize);
3183                 pAd->FragFrame.RxSize  += DataSize;
3184                 pAd->FragFrame.LastFrag = pHeader->Frag;           // Update fragment number
3185
3186                 // Last fragment
3187                 if (pHeader->FC.MoreFrag == FALSE)
3188                 {
3189                         bReassDone = TRUE;
3190                 }
3191         }
3192
3193 done:
3194         // always release rx fragmented packet
3195         RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
3196
3197         // return defragmented packet if packet is reassembled completely
3198         // otherwise return NULL
3199         if (bReassDone)
3200         {
3201                 PNDIS_PACKET pNewFragPacket;
3202
3203                 // allocate a new packet buffer for fragment
3204                 pNewFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
3205                 if (pNewFragPacket)
3206                 {
3207                         // update RxBlk
3208                         pRetPacket = pAd->FragFrame.pFragPacket;
3209                         pAd->FragFrame.pFragPacket = pNewFragPacket;
3210                         pRxBlk->pHeader = (PHEADER_802_11) GET_OS_PKT_DATAPTR(pRetPacket);
3211                         pRxBlk->pData = (UCHAR *)pRxBlk->pHeader + HeaderRoom;
3212                         pRxBlk->DataSize = pAd->FragFrame.RxSize - HeaderRoom;
3213                         pRxBlk->pRxPacket = pRetPacket;
3214                 }
3215                 else
3216                 {
3217                         RESET_FRAGFRAME(pAd->FragFrame);
3218                 }
3219         }
3220
3221         return pRetPacket;
3222 }
3223
3224
3225 VOID Indicate_AMSDU_Packet(
3226         IN      PRTMP_ADAPTER   pAd,
3227         IN      RX_BLK                  *pRxBlk,
3228         IN      UCHAR                   FromWhichBSSID)
3229 {
3230         UINT                    nMSDU;
3231
3232         update_os_packet_info(pAd, pRxBlk, FromWhichBSSID);
3233         RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
3234         nMSDU = deaggregate_AMSDU_announce(pAd, pRxBlk->pRxPacket, pRxBlk->pData, pRxBlk->DataSize);
3235 }
3236
3237 VOID Indicate_EAPOL_Packet(
3238         IN      PRTMP_ADAPTER   pAd,
3239         IN      RX_BLK                  *pRxBlk,
3240         IN      UCHAR                   FromWhichBSSID)
3241 {
3242         MAC_TABLE_ENTRY *pEntry = NULL;
3243
3244         {
3245                 pEntry = &pAd->MacTab.Content[BSSID_WCID];
3246                 STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
3247                 return;
3248         }
3249
3250         if (pEntry == NULL)
3251         {
3252                 DBGPRINT(RT_DEBUG_WARN, ("Indicate_EAPOL_Packet: drop and release the invalid packet.\n"));
3253                 // release packet
3254                 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
3255                 return;
3256         }
3257 }
3258
3259 #define BCN_TBTT_OFFSET         64      //defer 64 us
3260 VOID ReSyncBeaconTime(
3261         IN  PRTMP_ADAPTER   pAd)
3262 {
3263
3264         UINT32  Offset;
3265
3266
3267         Offset = (pAd->TbttTickCount) % (BCN_TBTT_OFFSET);
3268
3269         pAd->TbttTickCount++;
3270
3271         //
3272         // The updated BeaconInterval Value will affect Beacon Interval after two TBTT
3273         // beacasue the original BeaconInterval had been loaded into next TBTT_TIMER
3274         //
3275         if (Offset == (BCN_TBTT_OFFSET-2))
3276         {
3277                 BCN_TIME_CFG_STRUC csr;
3278                 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
3279                 csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod << 4) - 1 ;     // ASIC register in units of 1/16 TU = 64us
3280                 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
3281         }
3282         else
3283         {
3284                 if (Offset == (BCN_TBTT_OFFSET-1))
3285                 {
3286                         BCN_TIME_CFG_STRUC csr;
3287
3288                         RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
3289                         csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod) << 4; // ASIC register in units of 1/16 TU
3290                         RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
3291                 }
3292         }
3293 }
3294