~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

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