~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to drivers/staging/rt3090/common/cmm_data.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno, Martin Michlmayr
  • Date: 2011-04-06 13:53:30 UTC
  • mfrom: (43.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110406135330-wjufxhd0tvn3zx4z
Tags: 2.6.38-3
[ Ben Hutchings ]
* [ppc64] Add to linux-tools package architectures (Closes: #620124)
* [amd64] Save cr4 to mmu_cr4_features at boot time (Closes: #620284)
* appletalk: Fix bugs introduced when removing use of BKL
* ALSA: Fix yet another race in disconnection
* cciss: Fix lost command issue
* ath9k: Fix kernel panic in AR2427
* ses: Avoid kernel panic when lun 0 is not mapped
* PCI/ACPI: Report ASPM support to BIOS if not disabled from command line

[ Aurelien Jarno ]
* rtlwifi: fix build when PCI is not enabled.

[ Martin Michlmayr ]
* rtlwifi: Eliminate udelay calls with too large values (Closes: #620204)

Show diffs side-by-side

added added

removed removed

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