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