~ubuntu-branches/ubuntu/quantal/linux-linaro-mx51/quantal

« back to all changes in this revision

Viewing changes to drivers/staging/rt2860/sta/rtmp_data.c

  • Committer: Package Import Robot
  • Author(s): John Rigby, John Rigby
  • Date: 2011-09-26 10:44:23 UTC
  • Revision ID: package-import@ubuntu.com-20110926104423-3o58a3c1bj7x00rs
Tags: 3.0.0-1007.9
[ John Rigby ]

Enable crypto modules and remove crypto-modules from
exclude-module files
LP: #826021

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *************************************************************************
3
 
 * Ralink Tech Inc.
4
 
 * 5F., No.36, Taiyuan St., Jhubei City,
5
 
 * Hsinchu County 302,
6
 
 * Taiwan, R.O.C.
7
 
 *
8
 
 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9
 
 *
10
 
 * This program is free software; you can redistribute it and/or modify  *
11
 
 * it under the terms of the GNU General Public License as published by  *
12
 
 * the Free Software Foundation; either version 2 of the License, or     *
13
 
 * (at your option) any later version.                                   *
14
 
 *                                                                       *
15
 
 * This program is distributed in the hope that it will be useful,       *
16
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18
 
 * GNU General Public License for more details.                          *
19
 
 *                                                                       *
20
 
 * You should have received a copy of the GNU General Public License     *
21
 
 * along with this program; if not, write to the                         *
22
 
 * Free Software Foundation, Inc.,                                       *
23
 
 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
24
 
 *                                                                       *
25
 
 *************************************************************************
26
 
 
27
 
        Module Name:
28
 
        rtmp_data.c
29
 
 
30
 
        Abstract:
31
 
        Data path subroutines
32
 
 
33
 
        Revision History:
34
 
        Who                     When            What
35
 
        Justin P. Mattock       11/07/2010      Fix typos
36
 
        --------        ----------              ----------------------------------------------
37
 
*/
38
 
#include "../rt_config.h"
39
 
#include <linux/kernel.h>
40
 
 
41
 
void STARxEAPOLFrameIndicate(struct rt_rtmp_adapter *pAd,
42
 
                             struct rt_mac_table_entry *pEntry,
43
 
                             struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
44
 
{
45
 
        PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
46
 
        struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
47
 
        u8 *pTmpBuf;
48
 
 
49
 
        if (pAd->StaCfg.WpaSupplicantUP) {
50
 
                /* All EAPoL frames have to pass to upper layer (ex. WPA_SUPPLICANT daemon) */
51
 
                /* TBD : process fragmented EAPol frames */
52
 
                {
53
 
                        /* In 802.1x mode, if the received frame is EAP-SUCCESS packet, turn on the PortSecured variable */
54
 
                        if (pAd->StaCfg.IEEE8021X == TRUE &&
55
 
                            (EAP_CODE_SUCCESS ==
56
 
                             WpaCheckEapCode(pAd, pRxBlk->pData,
57
 
                                             pRxBlk->DataSize,
58
 
                                             LENGTH_802_1_H))) {
59
 
                                u8 *Key;
60
 
                                u8 CipherAlg;
61
 
                                int idx = 0;
62
 
 
63
 
                                DBGPRINT_RAW(RT_DEBUG_TRACE,
64
 
                                             ("Receive EAP-SUCCESS Packet\n"));
65
 
                                /*pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
66
 
                                STA_PORT_SECURED(pAd);
67
 
 
68
 
                                if (pAd->StaCfg.IEEE8021x_required_keys ==
69
 
                                    FALSE) {
70
 
                                        idx = pAd->StaCfg.DesireSharedKeyId;
71
 
                                        CipherAlg =
72
 
                                            pAd->StaCfg.DesireSharedKey[idx].
73
 
                                            CipherAlg;
74
 
                                        Key =
75
 
                                            pAd->StaCfg.DesireSharedKey[idx].
76
 
                                            Key;
77
 
 
78
 
                                        if (pAd->StaCfg.DesireSharedKey[idx].
79
 
                                            KeyLen > 0) {
80
 
#ifdef RTMP_MAC_PCI
81
 
                                                struct rt_mac_table_entry *pEntry =
82
 
                                                    &pAd->MacTab.
83
 
                                                    Content[BSSID_WCID];
84
 
 
85
 
                                                /* Set key material and cipherAlg to Asic */
86
 
                                                AsicAddSharedKeyEntry(pAd, BSS0,
87
 
                                                                      idx,
88
 
                                                                      CipherAlg,
89
 
                                                                      Key, NULL,
90
 
                                                                      NULL);
91
 
 
92
 
                                                /* Assign group key info */
93
 
                                                RTMPAddWcidAttributeEntry(pAd,
94
 
                                                                          BSS0,
95
 
                                                                          idx,
96
 
                                                                          CipherAlg,
97
 
                                                                          NULL);
98
 
 
99
 
                                                /* Assign pairwise key info */
100
 
                                                RTMPAddWcidAttributeEntry(pAd,
101
 
                                                                          BSS0,
102
 
                                                                          idx,
103
 
                                                                          CipherAlg,
104
 
                                                                          pEntry);
105
 
 
106
 
                                                pAd->IndicateMediaState =
107
 
                                                    NdisMediaStateConnected;
108
 
                                                pAd->ExtraInfo =
109
 
                                                    GENERAL_LINK_UP;
110
 
#endif /* RTMP_MAC_PCI // */
111
 
#ifdef RTMP_MAC_USB
112
 
                                                union {
113
 
                                                        char buf[sizeof
114
 
                                                                 (struct rt_ndis_802_11_wep)
115
 
                                                                 +
116
 
                                                                 MAX_LEN_OF_KEY
117
 
                                                                 - 1];
118
 
                                                        struct rt_ndis_802_11_wep keyinfo;
119
 
                                                }
120
 
                                                WepKey;
121
 
                                                int len;
122
 
 
123
 
                                                NdisZeroMemory(&WepKey,
124
 
                                                               sizeof(WepKey));
125
 
                                                len =
126
 
                                                    pAd->StaCfg.
127
 
                                                    DesireSharedKey[idx].KeyLen;
128
 
 
129
 
                                                NdisMoveMemory(WepKey.keyinfo.
130
 
                                                               KeyMaterial,
131
 
                                                               pAd->StaCfg.
132
 
                                                               DesireSharedKey
133
 
                                                               [idx].Key,
134
 
                                                               pAd->StaCfg.
135
 
                                                               DesireSharedKey
136
 
                                                               [idx].KeyLen);
137
 
 
138
 
                                                WepKey.keyinfo.KeyIndex =
139
 
                                                    0x80000000 + idx;
140
 
                                                WepKey.keyinfo.KeyLength = len;
141
 
                                                pAd->SharedKey[BSS0][idx].
142
 
                                                    KeyLen =
143
 
                                                    (u8)(len <= 5 ? 5 : 13);
144
 
 
145
 
                                                pAd->IndicateMediaState =
146
 
                                                    NdisMediaStateConnected;
147
 
                                                pAd->ExtraInfo =
148
 
                                                    GENERAL_LINK_UP;
149
 
                                                /* need to enqueue cmd to thread */
150
 
                                                RTUSBEnqueueCmdFromNdis(pAd,
151
 
                                                                        OID_802_11_ADD_WEP,
152
 
                                                                        TRUE,
153
 
                                                                        &WepKey,
154
 
                                                                        sizeof
155
 
                                                                        (WepKey.
156
 
                                                                         keyinfo)
157
 
                                                                        + len -
158
 
                                                                        1);
159
 
#endif /* RTMP_MAC_USB // */
160
 
                                                /* For Preventing ShardKey Table is cleared by remove key procedure. */
161
 
                                                pAd->SharedKey[BSS0][idx].
162
 
                                                    CipherAlg = CipherAlg;
163
 
                                                pAd->SharedKey[BSS0][idx].
164
 
                                                    KeyLen =
165
 
                                                    pAd->StaCfg.
166
 
                                                    DesireSharedKey[idx].KeyLen;
167
 
                                                NdisMoveMemory(pAd->
168
 
                                                               SharedKey[BSS0]
169
 
                                                               [idx].Key,
170
 
                                                               pAd->StaCfg.
171
 
                                                               DesireSharedKey
172
 
                                                               [idx].Key,
173
 
                                                               pAd->StaCfg.
174
 
                                                               DesireSharedKey
175
 
                                                               [idx].KeyLen);
176
 
                                        }
177
 
                                }
178
 
                        }
179
 
 
180
 
                        Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
181
 
                        return;
182
 
                }
183
 
        } else {
184
 
                /* Special DATA frame that has to pass to MLME */
185
 
                /*       1. Cisco Aironet frames for CCX2. We need pass it to MLME for special process */
186
 
                /*       2. EAPOL handshaking frames when driver supplicant enabled, pass to MLME for special process */
187
 
                {
188
 
                        pTmpBuf = pRxBlk->pData - LENGTH_802_11;
189
 
                        NdisMoveMemory(pTmpBuf, pRxBlk->pHeader, LENGTH_802_11);
190
 
                        REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID,
191
 
                                                  pTmpBuf,
192
 
                                                  pRxBlk->DataSize +
193
 
                                                  LENGTH_802_11, pRxWI->RSSI0,
194
 
                                                  pRxWI->RSSI1, pRxWI->RSSI2,
195
 
                                                  pRxD->PlcpSignal);
196
 
                        DBGPRINT_RAW(RT_DEBUG_TRACE,
197
 
                                     ("report EAPOL/AIRONET DATA to MLME (len=%d) !\n",
198
 
                                      pRxBlk->DataSize));
199
 
                }
200
 
        }
201
 
 
202
 
        RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
203
 
        return;
204
 
 
205
 
}
206
 
 
207
 
void STARxDataFrameAnnounce(struct rt_rtmp_adapter *pAd,
208
 
                            struct rt_mac_table_entry *pEntry,
209
 
                            struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
210
 
{
211
 
 
212
 
        /* non-EAP frame */
213
 
        if (!RTMPCheckWPAframe
214
 
            (pAd, pEntry, pRxBlk->pData, pRxBlk->DataSize, FromWhichBSSID)) {
215
 
 
216
 
                {
217
 
                        /* drop all non-EAP DATA frame before */
218
 
                        /* this client's Port-Access-Control is secured */
219
 
                        if (pRxBlk->pHeader->FC.Wep) {
220
 
                                /* unsupported cipher suite */
221
 
                                if (pAd->StaCfg.WepStatus ==
222
 
                                    Ndis802_11EncryptionDisabled) {
223
 
                                        /* release packet */
224
 
                                        RELEASE_NDIS_PACKET(pAd,
225
 
                                                            pRxBlk->pRxPacket,
226
 
                                                            NDIS_STATUS_FAILURE);
227
 
                                        return;
228
 
                                }
229
 
                        } else {
230
 
                                /* encryption in-use but receive a non-EAPOL clear text frame, drop it */
231
 
                                if ((pAd->StaCfg.WepStatus !=
232
 
                                     Ndis802_11EncryptionDisabled)
233
 
                                    && (pAd->StaCfg.PortSecured ==
234
 
                                        WPA_802_1X_PORT_NOT_SECURED)) {
235
 
                                        /* release packet */
236
 
                                        RELEASE_NDIS_PACKET(pAd,
237
 
                                                            pRxBlk->pRxPacket,
238
 
                                                            NDIS_STATUS_FAILURE);
239
 
                                        return;
240
 
                                }
241
 
                        }
242
 
                }
243
 
                RX_BLK_CLEAR_FLAG(pRxBlk, fRX_EAP);
244
 
                if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_ARALINK)) {
245
 
                        /* Normal legacy, AMPDU or AMSDU */
246
 
                        CmmRxnonRalinkFrameIndicate(pAd, pRxBlk,
247
 
                                                    FromWhichBSSID);
248
 
 
249
 
                } else {
250
 
                        /* ARALINK */
251
 
                        CmmRxRalinkFrameIndicate(pAd, pEntry, pRxBlk,
252
 
                                                 FromWhichBSSID);
253
 
                }
254
 
        } else {
255
 
                RX_BLK_SET_FLAG(pRxBlk, fRX_EAP);
256
 
 
257
 
                if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU)
258
 
                    && (pAd->CommonCfg.bDisableReordering == 0)) {
259
 
                        Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
260
 
                } else {
261
 
                        /* Determine the destination of the EAP frame */
262
 
                        /* to WPA state machine or upper layer */
263
 
                        STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk,
264
 
                                                FromWhichBSSID);
265
 
                }
266
 
        }
267
 
}
268
 
 
269
 
/* For TKIP frame, calculate the MIC value */
270
 
BOOLEAN STACheckTkipMICValue(struct rt_rtmp_adapter *pAd,
271
 
                             struct rt_mac_table_entry *pEntry, struct rt_rx_blk *pRxBlk)
272
 
{
273
 
        struct rt_header_802_11 * pHeader = pRxBlk->pHeader;
274
 
        u8 *pData = pRxBlk->pData;
275
 
        u16 DataSize = pRxBlk->DataSize;
276
 
        u8 UserPriority = pRxBlk->UserPriority;
277
 
        struct rt_cipher_key *pWpaKey;
278
 
        u8 *pDA, *pSA;
279
 
 
280
 
        pWpaKey = &pAd->SharedKey[BSS0][pRxBlk->pRxWI->KeyIndex];
281
 
 
282
 
        pDA = pHeader->Addr1;
283
 
        if (RX_BLK_TEST_FLAG(pRxBlk, fRX_INFRA)) {
284
 
                pSA = pHeader->Addr3;
285
 
        } else {
286
 
                pSA = pHeader->Addr2;
287
 
        }
288
 
 
289
 
        if (RTMPTkipCompareMICValue(pAd,
290
 
                                    pData,
291
 
                                    pDA,
292
 
                                    pSA,
293
 
                                    pWpaKey->RxMic,
294
 
                                    UserPriority, DataSize) == FALSE) {
295
 
                DBGPRINT_RAW(RT_DEBUG_ERROR, ("Rx MIC Value error 2\n"));
296
 
 
297
 
                if (pAd->StaCfg.WpaSupplicantUP) {
298
 
                        WpaSendMicFailureToWpaSupplicant(pAd,
299
 
                                                         (pWpaKey->Type ==
300
 
                                                          PAIRWISEKEY) ? TRUE :
301
 
                                                         FALSE);
302
 
                } else {
303
 
                        RTMPReportMicError(pAd, pWpaKey);
304
 
                }
305
 
 
306
 
                /* release packet */
307
 
                RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
308
 
                                    NDIS_STATUS_FAILURE);
309
 
                return FALSE;
310
 
        }
311
 
 
312
 
        return TRUE;
313
 
}
314
 
 
315
 
/* */
316
 
/* All Rx routines use struct rt_rx_blk structure to hande rx events */
317
 
/* It is very important to build pRxBlk attributes */
318
 
/*  1. pHeader pointer to 802.11 Header */
319
 
/*  2. pData pointer to payload including LLC (just skip Header) */
320
 
/*  3. set payload size including LLC to DataSize */
321
 
/*  4. set some flags with RX_BLK_SET_FLAG() */
322
 
/* */
323
 
void STAHandleRxDataFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
324
 
{
325
 
        PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
326
 
        struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
327
 
        struct rt_header_802_11 * pHeader = pRxBlk->pHeader;
328
 
        void *pRxPacket = pRxBlk->pRxPacket;
329
 
        BOOLEAN bFragment = FALSE;
330
 
        struct rt_mac_table_entry *pEntry = NULL;
331
 
        u8 FromWhichBSSID = BSS0;
332
 
        u8 UserPriority = 0;
333
 
 
334
 
        {
335
 
                /* before LINK UP, all DATA frames are rejected */
336
 
                if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
337
 
                        /* release packet */
338
 
                        RELEASE_NDIS_PACKET(pAd, pRxPacket,
339
 
                                            NDIS_STATUS_FAILURE);
340
 
                        return;
341
 
                }
342
 
                /* Drop not my BSS frames */
343
 
                if (pRxD->MyBss == 0) {
344
 
                        {
345
 
                                /* release packet */
346
 
                                RELEASE_NDIS_PACKET(pAd, pRxPacket,
347
 
                                                    NDIS_STATUS_FAILURE);
348
 
                                return;
349
 
                        }
350
 
                }
351
 
 
352
 
                pAd->RalinkCounters.RxCountSinceLastNULL++;
353
 
                if (pAd->CommonCfg.bAPSDCapable
354
 
                    && pAd->CommonCfg.APEdcaParm.bAPSDCapable
355
 
                    && (pHeader->FC.SubType & 0x08)) {
356
 
                        u8 *pData;
357
 
                        DBGPRINT(RT_DEBUG_INFO, ("bAPSDCapable\n"));
358
 
 
359
 
                        /* Qos bit 4 */
360
 
                        pData = (u8 *)pHeader + LENGTH_802_11;
361
 
                        if ((*pData >> 4) & 0x01) {
362
 
                                DBGPRINT(RT_DEBUG_INFO,
363
 
                                         ("RxDone- Rcv EOSP frame, driver may fall into sleep\n"));
364
 
                                pAd->CommonCfg.bInServicePeriod = FALSE;
365
 
 
366
 
                                /* Force driver to fall into sleep mode when rcv EOSP frame */
367
 
                                if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
368
 
                                        u16 TbttNumToNextWakeUp;
369
 
                                        u16 NextDtim =
370
 
                                            pAd->StaCfg.DtimPeriod;
371
 
                                        unsigned long Now;
372
 
 
373
 
                                        NdisGetSystemUpTime(&Now);
374
 
                                        NextDtim -=
375
 
                                            (u16)(Now -
376
 
                                                      pAd->StaCfg.
377
 
                                                      LastBeaconRxTime) /
378
 
                                            pAd->CommonCfg.BeaconPeriod;
379
 
 
380
 
                                        TbttNumToNextWakeUp =
381
 
                                            pAd->StaCfg.DefaultListenCount;
382
 
                                        if (OPSTATUS_TEST_FLAG
383
 
                                            (pAd, fOP_STATUS_RECEIVE_DTIM)
384
 
                                            && (TbttNumToNextWakeUp > NextDtim))
385
 
                                                TbttNumToNextWakeUp = NextDtim;
386
 
 
387
 
                                        RTMP_SET_PSM_BIT(pAd, PWR_SAVE);
388
 
                                        /* if WMM-APSD is failed, try to disable following line */
389
 
                                        AsicSleepThenAutoWakeup(pAd,
390
 
                                                                TbttNumToNextWakeUp);
391
 
                                }
392
 
                        }
393
 
 
394
 
                        if ((pHeader->FC.MoreData)
395
 
                            && (pAd->CommonCfg.bInServicePeriod)) {
396
 
                                DBGPRINT(RT_DEBUG_TRACE,
397
 
                                         ("Sending another trigger frame when More Data bit is set to 1\n"));
398
 
                        }
399
 
                }
400
 
                /* Drop NULL, CF-ACK(no data), CF-POLL(no data), and CF-ACK+CF-POLL(no data) data frame */
401
 
                if ((pHeader->FC.SubType & 0x04))       /* bit 2 : no DATA */
402
 
                {
403
 
                        /* release packet */
404
 
                        RELEASE_NDIS_PACKET(pAd, pRxPacket,
405
 
                                            NDIS_STATUS_FAILURE);
406
 
                        return;
407
 
                }
408
 
                /* Drop not my BSS frame (we can not only check the MyBss bit in RxD) */
409
 
 
410
 
                if (INFRA_ON(pAd)) {
411
 
                        /* Infrastructure mode, check address 2 for BSSID */
412
 
                        if (!RTMPEqualMemory
413
 
                            (&pHeader->Addr2, &pAd->CommonCfg.Bssid, 6)) {
414
 
                                /* Receive frame not my BSSID */
415
 
                                /* release packet */
416
 
                                RELEASE_NDIS_PACKET(pAd, pRxPacket,
417
 
                                                    NDIS_STATUS_FAILURE);
418
 
                                return;
419
 
                        }
420
 
                } else          /* Ad-Hoc mode or Not associated */
421
 
                {
422
 
                        /* Ad-Hoc mode, check address 3 for BSSID */
423
 
                        if (!RTMPEqualMemory
424
 
                            (&pHeader->Addr3, &pAd->CommonCfg.Bssid, 6)) {
425
 
                                /* Receive frame not my BSSID */
426
 
                                /* release packet */
427
 
                                RELEASE_NDIS_PACKET(pAd, pRxPacket,
428
 
                                                    NDIS_STATUS_FAILURE);
429
 
                                return;
430
 
                        }
431
 
                }
432
 
 
433
 
                /* */
434
 
                /* find pEntry */
435
 
                /* */
436
 
                if (pRxWI->WirelessCliID < MAX_LEN_OF_MAC_TABLE) {
437
 
                        pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];
438
 
                } else {
439
 
                        /* 1. release packet if infra mode */
440
 
                        /* 2. new a pEntry if ad-hoc mode */
441
 
                        RELEASE_NDIS_PACKET(pAd, pRxPacket,
442
 
                                            NDIS_STATUS_FAILURE);
443
 
                        return;
444
 
                }
445
 
 
446
 
                /* infra or ad-hoc */
447
 
                if (INFRA_ON(pAd)) {
448
 
                        RX_BLK_SET_FLAG(pRxBlk, fRX_INFRA);
449
 
                        ASSERT(pRxWI->WirelessCliID == BSSID_WCID);
450
 
                }
451
 
                /* check Atheros Client */
452
 
                if ((pEntry->bIAmBadAtheros == FALSE) && (pRxD->AMPDU == 1)
453
 
                    && (pHeader->FC.Retry)) {
454
 
                        pEntry->bIAmBadAtheros = TRUE;
455
 
                        pAd->CommonCfg.IOTestParm.bCurrentAtheros = TRUE;
456
 
                        pAd->CommonCfg.IOTestParm.bLastAtheros = TRUE;
457
 
                        if (!STA_AES_ON(pAd)) {
458
 
                                AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, TRUE,
459
 
                                                  FALSE);
460
 
                        }
461
 
                }
462
 
        }
463
 
 
464
 
        pRxBlk->pData = (u8 *) pHeader;
465
 
 
466
 
        /* */
467
 
        /* update RxBlk->pData, DataSize */
468
 
        /* 802.11 Header, QOS, HTC, Hw Padding */
469
 
        /* */
470
 
 
471
 
        /* 1. skip 802.11 HEADER */
472
 
        {
473
 
                pRxBlk->pData += LENGTH_802_11;
474
 
                pRxBlk->DataSize -= LENGTH_802_11;
475
 
        }
476
 
 
477
 
        /* 2. QOS */
478
 
        if (pHeader->FC.SubType & 0x08) {
479
 
                RX_BLK_SET_FLAG(pRxBlk, fRX_QOS);
480
 
                UserPriority = *(pRxBlk->pData) & 0x0f;
481
 
                /* bit 7 in QoS Control field signals the HT A-MSDU format */
482
 
                if ((*pRxBlk->pData) & 0x80) {
483
 
                        RX_BLK_SET_FLAG(pRxBlk, fRX_AMSDU);
484
 
                }
485
 
                /* skip QOS contorl field */
486
 
                pRxBlk->pData += 2;
487
 
                pRxBlk->DataSize -= 2;
488
 
        }
489
 
        pRxBlk->UserPriority = UserPriority;
490
 
 
491
 
        /* check if need to resend PS Poll when received packet with MoreData = 1 */
492
 
        if ((pAd->StaCfg.Psm == PWR_SAVE) && (pHeader->FC.MoreData == 1)) {
493
 
                if ((((UserPriority == 0) || (UserPriority == 3)) &&
494
 
                     pAd->CommonCfg.bAPSDAC_BE == 0) ||
495
 
                    (((UserPriority == 1) || (UserPriority == 2)) &&
496
 
                     pAd->CommonCfg.bAPSDAC_BK == 0) ||
497
 
                    (((UserPriority == 4) || (UserPriority == 5)) &&
498
 
                     pAd->CommonCfg.bAPSDAC_VI == 0) ||
499
 
                    (((UserPriority == 6) || (UserPriority == 7)) &&
500
 
                     pAd->CommonCfg.bAPSDAC_VO == 0)) {
501
 
                        /* non-UAPSD delivery-enabled AC */
502
 
                        RTMP_PS_POLL_ENQUEUE(pAd);
503
 
                }
504
 
        }
505
 
        /* 3. Order bit: A-Ralink or HTC+ */
506
 
        if (pHeader->FC.Order) {
507
 
#ifdef AGGREGATION_SUPPORT
508
 
                if ((pRxWI->PHYMODE <= MODE_OFDM)
509
 
                    && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)))
510
 
                {
511
 
                        RX_BLK_SET_FLAG(pRxBlk, fRX_ARALINK);
512
 
                } else
513
 
#endif /* AGGREGATION_SUPPORT // */
514
 
                {
515
 
                        RX_BLK_SET_FLAG(pRxBlk, fRX_HTC);
516
 
                        /* skip HTC contorl field */
517
 
                        pRxBlk->pData += 4;
518
 
                        pRxBlk->DataSize -= 4;
519
 
                }
520
 
        }
521
 
        /* 4. skip HW padding */
522
 
        if (pRxD->L2PAD) {
523
 
                /* just move pData pointer */
524
 
                /* because DataSize excluding HW padding */
525
 
                RX_BLK_SET_FLAG(pRxBlk, fRX_PAD);
526
 
                pRxBlk->pData += 2;
527
 
        }
528
 
 
529
 
        if (pRxD->BA) {
530
 
                RX_BLK_SET_FLAG(pRxBlk, fRX_AMPDU);
531
 
        }
532
 
        /* */
533
 
        /* Case I  Process Broadcast & Multicast data frame */
534
 
        /* */
535
 
        if (pRxD->Bcast || pRxD->Mcast) {
536
 
                INC_COUNTER64(pAd->WlanCounters.MulticastReceivedFrameCount);
537
 
 
538
 
                /* Drop Mcast/Bcast frame with fragment bit on */
539
 
                if (pHeader->FC.MoreFrag) {
540
 
                        /* release packet */
541
 
                        RELEASE_NDIS_PACKET(pAd, pRxPacket,
542
 
                                            NDIS_STATUS_FAILURE);
543
 
                        return;
544
 
                }
545
 
                /* Filter out Bcast frame which AP relayed for us */
546
 
                if (pHeader->FC.FrDs
547
 
                    && MAC_ADDR_EQUAL(pHeader->Addr3, pAd->CurrentAddress)) {
548
 
                        /* release packet */
549
 
                        RELEASE_NDIS_PACKET(pAd, pRxPacket,
550
 
                                            NDIS_STATUS_FAILURE);
551
 
                        return;
552
 
                }
553
 
 
554
 
                Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
555
 
                return;
556
 
        } else if (pRxD->U2M) {
557
 
                pAd->LastRxRate =
558
 
                    (u16)((pRxWI->MCS) + (pRxWI->BW << 7) +
559
 
                              (pRxWI->ShortGI << 8) + (pRxWI->PHYMODE << 14));
560
 
 
561
 
                if (ADHOC_ON(pAd)) {
562
 
                        pEntry = MacTableLookup(pAd, pHeader->Addr2);
563
 
                        if (pEntry)
564
 
                                Update_Rssi_Sample(pAd, &pEntry->RssiSample,
565
 
                                                   pRxWI);
566
 
                }
567
 
 
568
 
                Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
569
 
 
570
 
                pAd->StaCfg.LastSNR0 = (u8)(pRxWI->SNR0);
571
 
                pAd->StaCfg.LastSNR1 = (u8)(pRxWI->SNR1);
572
 
 
573
 
                pAd->RalinkCounters.OneSecRxOkDataCnt++;
574
 
 
575
 
                if (!((pHeader->Frag == 0) && (pHeader->FC.MoreFrag == 0))) {
576
 
                        /* re-assemble the fragmented packets */
577
 
                        /* return complete frame (pRxPacket) or NULL */
578
 
                        bFragment = TRUE;
579
 
                        pRxPacket = RTMPDeFragmentDataFrame(pAd, pRxBlk);
580
 
                }
581
 
 
582
 
                if (pRxPacket) {
583
 
                        pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];
584
 
 
585
 
                        /* process complete frame */
586
 
                        if (bFragment && (pRxD->Decrypted)
587
 
                            && (pEntry->WepStatus ==
588
 
                                Ndis802_11Encryption2Enabled)) {
589
 
                                /* Minus MIC length */
590
 
                                pRxBlk->DataSize -= 8;
591
 
 
592
 
                                /* For TKIP frame, calculate the MIC value */
593
 
                                if (STACheckTkipMICValue(pAd, pEntry, pRxBlk) ==
594
 
                                    FALSE) {
595
 
                                        return;
596
 
                                }
597
 
                        }
598
 
 
599
 
                        STARxDataFrameAnnounce(pAd, pEntry, pRxBlk,
600
 
                                               FromWhichBSSID);
601
 
                        return;
602
 
                } else {
603
 
                        /* just return */
604
 
                        /* because RTMPDeFragmentDataFrame() will release rx packet, */
605
 
                        /* if packet is fragmented */
606
 
                        return;
607
 
                }
608
 
        }
609
 
 
610
 
        ASSERT(0);
611
 
        /* release packet */
612
 
        RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
613
 
}
614
 
 
615
 
void STAHandleRxMgmtFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
616
 
{
617
 
        PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
618
 
        struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
619
 
        struct rt_header_802_11 * pHeader = pRxBlk->pHeader;
620
 
        void *pRxPacket = pRxBlk->pRxPacket;
621
 
 
622
 
        do {
623
 
 
624
 
                /* check if need to resend PS Poll when received packet with MoreData = 1 */
625
 
                if ((pAd->StaCfg.Psm == PWR_SAVE)
626
 
                    && (pHeader->FC.MoreData == 1)) {
627
 
                        /* for UAPSD, all management frames will be VO priority */
628
 
                        if (pAd->CommonCfg.bAPSDAC_VO == 0) {
629
 
                                /* non-UAPSD delivery-enabled AC */
630
 
                                RTMP_PS_POLL_ENQUEUE(pAd);
631
 
                        }
632
 
                }
633
 
 
634
 
                /* TODO: if MoreData == 0, station can go to sleep */
635
 
 
636
 
                /* We should collect RSSI not only U2M data but also my beacon */
637
 
                if ((pHeader->FC.SubType == SUBTYPE_BEACON)
638
 
                    && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2))
639
 
                    && (pAd->RxAnt.EvaluatePeriod == 0)) {
640
 
                        Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
641
 
 
642
 
                        pAd->StaCfg.LastSNR0 = (u8)(pRxWI->SNR0);
643
 
                        pAd->StaCfg.LastSNR1 = (u8)(pRxWI->SNR1);
644
 
                }
645
 
 
646
 
                /* First check the size, it MUST not exceed the mlme queue size */
647
 
                if (pRxWI->MPDUtotalByteCount > MGMT_DMA_BUFFER_SIZE) {
648
 
                        DBGPRINT_ERR("STAHandleRxMgmtFrame: frame too large, size = %d \n", pRxWI->MPDUtotalByteCount);
649
 
                        break;
650
 
                }
651
 
 
652
 
                REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pHeader,
653
 
                                          pRxWI->MPDUtotalByteCount,
654
 
                                          pRxWI->RSSI0, pRxWI->RSSI1,
655
 
                                          pRxWI->RSSI2, pRxD->PlcpSignal);
656
 
        } while (FALSE);
657
 
 
658
 
        RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
659
 
}
660
 
 
661
 
void STAHandleRxControlFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
662
 
{
663
 
        struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
664
 
        struct rt_header_802_11 * pHeader = pRxBlk->pHeader;
665
 
        void *pRxPacket = pRxBlk->pRxPacket;
666
 
 
667
 
        switch (pHeader->FC.SubType) {
668
 
        case SUBTYPE_BLOCK_ACK_REQ:
669
 
                {
670
 
                        CntlEnqueueForRecv(pAd, pRxWI->WirelessCliID,
671
 
                                           (pRxWI->MPDUtotalByteCount),
672
 
                                           (struct rt_frame_ba_req *) pHeader);
673
 
                }
674
 
                break;
675
 
        case SUBTYPE_BLOCK_ACK:
676
 
        case SUBTYPE_ACK:
677
 
        default:
678
 
                break;
679
 
        }
680
 
 
681
 
        RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
682
 
}
683
 
 
684
 
/*
685
 
        ========================================================================
686
 
 
687
 
        Routine Description:
688
 
                Process RxDone interrupt, running in DPC level
689
 
 
690
 
        Arguments:
691
 
                pAd Pointer to our adapter
692
 
 
693
 
        Return Value:
694
 
                None
695
 
 
696
 
        IRQL = DISPATCH_LEVEL
697
 
 
698
 
        Note:
699
 
                This routine has to maintain Rx ring read pointer.
700
 
                Need to consider QOS DATA format when converting to 802.3
701
 
        ========================================================================
702
 
*/
703
 
BOOLEAN STARxDoneInterruptHandle(struct rt_rtmp_adapter *pAd, IN BOOLEAN argc)
704
 
{
705
 
        int Status;
706
 
        u32 RxProcessed, RxPending;
707
 
        BOOLEAN bReschedule = FALSE;
708
 
        PRT28XX_RXD_STRUC pRxD;
709
 
        u8 *pData;
710
 
        struct rt_rxwi * pRxWI;
711
 
        void *pRxPacket;
712
 
        struct rt_header_802_11 * pHeader;
713
 
        struct rt_rx_blk RxCell;
714
 
 
715
 
        RxProcessed = RxPending = 0;
716
 
 
717
 
        /* process whole rx ring */
718
 
        while (1) {
719
 
 
720
 
                if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF |
721
 
                                   fRTMP_ADAPTER_RESET_IN_PROGRESS |
722
 
                                   fRTMP_ADAPTER_HALT_IN_PROGRESS |
723
 
                                   fRTMP_ADAPTER_NIC_NOT_EXIST) ||
724
 
                    !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) {
725
 
                        break;
726
 
                }
727
 
#ifdef RTMP_MAC_PCI
728
 
                if (RxProcessed++ > MAX_RX_PROCESS_CNT) {
729
 
                        /* need to reschedule rx handle */
730
 
                        bReschedule = TRUE;
731
 
                        break;
732
 
                }
733
 
#endif /* RTMP_MAC_PCI // */
734
 
 
735
 
                RxProcessed++;  /* test */
736
 
 
737
 
                /* 1. allocate a new data packet into rx ring to replace received packet */
738
 
                /*    then processing the received packet */
739
 
                /* 2. the callee must take charge of release of packet */
740
 
                /* 3. As far as driver is concerned , */
741
 
                /*    the rx packet must */
742
 
                /*      a. be indicated to upper layer or */
743
 
                /*      b. be released if it is discarded */
744
 
                pRxPacket =
745
 
                    GetPacketFromRxRing(pAd, &(RxCell.RxD), &bReschedule,
746
 
                                        &RxPending);
747
 
                if (pRxPacket == NULL) {
748
 
                        /* no more packet to process */
749
 
                        break;
750
 
                }
751
 
                /* get rx ring descriptor */
752
 
                pRxD = &(RxCell.RxD);
753
 
                /* get rx data buffer */
754
 
                pData = GET_OS_PKT_DATAPTR(pRxPacket);
755
 
                pRxWI = (struct rt_rxwi *) pData;
756
 
                pHeader = (struct rt_header_802_11 *) (pData + RXWI_SIZE);
757
 
 
758
 
                /* build RxCell */
759
 
                RxCell.pRxWI = pRxWI;
760
 
                RxCell.pHeader = pHeader;
761
 
                RxCell.pRxPacket = pRxPacket;
762
 
                RxCell.pData = (u8 *) pHeader;
763
 
                RxCell.DataSize = pRxWI->MPDUtotalByteCount;
764
 
                RxCell.Flags = 0;
765
 
 
766
 
                /* Increase Total receive byte counter after real data received no mater any error or not */
767
 
                pAd->RalinkCounters.ReceivedByteCount +=
768
 
                    pRxWI->MPDUtotalByteCount;
769
 
                pAd->RalinkCounters.OneSecReceivedByteCount +=
770
 
                    pRxWI->MPDUtotalByteCount;
771
 
                pAd->RalinkCounters.RxCount++;
772
 
 
773
 
                INC_COUNTER64(pAd->WlanCounters.ReceivedFragmentCount);
774
 
 
775
 
                if (pRxWI->MPDUtotalByteCount < 14)
776
 
                        Status = NDIS_STATUS_FAILURE;
777
 
 
778
 
                if (MONITOR_ON(pAd)) {
779
 
                        send_monitor_packets(pAd, &RxCell);
780
 
                        break;
781
 
                }
782
 
 
783
 
                /* STARxDoneInterruptHandle() is called in rtusb_bulk.c */
784
 
 
785
 
                /* Check for all RxD errors */
786
 
                Status = RTMPCheckRxError(pAd, pHeader, pRxWI, pRxD);
787
 
 
788
 
                /* Handle the received frame */
789
 
                if (Status == NDIS_STATUS_SUCCESS) {
790
 
                        switch (pHeader->FC.Type) {
791
 
                                /* CASE I, receive a DATA frame */
792
 
                        case BTYPE_DATA:
793
 
                                {
794
 
                                        /* process DATA frame */
795
 
                                        STAHandleRxDataFrame(pAd, &RxCell);
796
 
                                }
797
 
                                break;
798
 
                                /* CASE II, receive a MGMT frame */
799
 
                        case BTYPE_MGMT:
800
 
                                {
801
 
                                        STAHandleRxMgmtFrame(pAd, &RxCell);
802
 
                                }
803
 
                                break;
804
 
                                /* CASE III. receive a CNTL frame */
805
 
                        case BTYPE_CNTL:
806
 
                                {
807
 
                                        STAHandleRxControlFrame(pAd, &RxCell);
808
 
                                }
809
 
                                break;
810
 
                                /* discard other type */
811
 
                        default:
812
 
                                RELEASE_NDIS_PACKET(pAd, pRxPacket,
813
 
                                                    NDIS_STATUS_FAILURE);
814
 
                                break;
815
 
                        }
816
 
                } else {
817
 
                        pAd->Counters8023.RxErrors++;
818
 
                        /* discard this frame */
819
 
                        RELEASE_NDIS_PACKET(pAd, pRxPacket,
820
 
                                            NDIS_STATUS_FAILURE);
821
 
                }
822
 
        }
823
 
 
824
 
        return bReschedule;
825
 
}
826
 
 
827
 
/*
828
 
        ========================================================================
829
 
 
830
 
        Routine Description:
831
 
        Arguments:
832
 
                pAd     Pointer to our adapter
833
 
 
834
 
        IRQL = DISPATCH_LEVEL
835
 
 
836
 
        ========================================================================
837
 
*/
838
 
void RTMPHandleTwakeupInterrupt(struct rt_rtmp_adapter *pAd)
839
 
{
840
 
        AsicForceWakeup(pAd, FALSE);
841
 
}
842
 
 
843
 
/*
844
 
========================================================================
845
 
Routine Description:
846
 
    Early checking and OS-depened parsing for Tx packet send to our STA driver.
847
 
 
848
 
Arguments:
849
 
    void *      MiniportAdapterContext  Pointer refer to the device handle, i.e., the pAd.
850
 
        void ** ppPacketArray                   The packet array need to do transmission.
851
 
        u32                     NumberOfPackets                 Number of packet in packet array.
852
 
 
853
 
Return Value:
854
 
        NONE
855
 
 
856
 
Note:
857
 
        This function does early checking and classification for send-out packet.
858
 
        You only can put OS-depened & STA related code in here.
859
 
========================================================================
860
 
*/
861
 
void STASendPackets(void *MiniportAdapterContext,
862
 
                    void **ppPacketArray, u32 NumberOfPackets)
863
 
{
864
 
        u32 Index;
865
 
        struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)MiniportAdapterContext;
866
 
        void *pPacket;
867
 
        BOOLEAN allowToSend = FALSE;
868
 
 
869
 
        for (Index = 0; Index < NumberOfPackets; Index++) {
870
 
                pPacket = ppPacketArray[Index];
871
 
 
872
 
                do {
873
 
                        if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)
874
 
                            || RTMP_TEST_FLAG(pAd,
875
 
                                              fRTMP_ADAPTER_HALT_IN_PROGRESS)
876
 
                            || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) {
877
 
                                /* Drop send request since hardware is in reset state */
878
 
                                break;
879
 
                        } else if (!INFRA_ON(pAd) && !ADHOC_ON(pAd)) {
880
 
                                /* Drop send request since there are no physical connection yet */
881
 
                                break;
882
 
                        } else {
883
 
                                /* Record that orignal packet source is from NDIS layer,so that */
884
 
                                /* later on driver knows how to release this NDIS PACKET */
885
 
                                RTMP_SET_PACKET_WCID(pPacket, 0);       /* this field is useless when in STA mode */
886
 
                                RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
887
 
                                NDIS_SET_PACKET_STATUS(pPacket,
888
 
                                                       NDIS_STATUS_PENDING);
889
 
                                pAd->RalinkCounters.PendingNdisPacketCount++;
890
 
 
891
 
                                allowToSend = TRUE;
892
 
                        }
893
 
                } while (FALSE);
894
 
 
895
 
                if (allowToSend == TRUE)
896
 
                        STASendPacket(pAd, pPacket);
897
 
                else
898
 
                        RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
899
 
        }
900
 
 
901
 
        /* Dequeue outgoing frames from TxSwQueue[] and process it */
902
 
        RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
903
 
 
904
 
}
905
 
 
906
 
/*
907
 
========================================================================
908
 
Routine Description:
909
 
        This routine is used to do packet parsing and classification for Tx packet
910
 
        to STA device, and it will en-queue packets to our TxSwQueue depends on AC
911
 
        class.
912
 
 
913
 
Arguments:
914
 
        pAd             Pointer to our adapter
915
 
        pPacket         Pointer to send packet
916
 
 
917
 
Return Value:
918
 
        NDIS_STATUS_SUCCESS                     If success to queue the packet into TxSwQueue.
919
 
        NDIS_STATUS_FAILURE                     If failed to do en-queue.
920
 
 
921
 
Note:
922
 
        You only can put OS-indepened & STA related code in here.
923
 
========================================================================
924
 
*/
925
 
int STASendPacket(struct rt_rtmp_adapter *pAd, void *pPacket)
926
 
{
927
 
        struct rt_packet_info PacketInfo;
928
 
        u8 *pSrcBufVA;
929
 
        u32 SrcBufLen;
930
 
        u32 AllowFragSize;
931
 
        u8 NumberOfFrag;
932
 
        u8 RTSRequired;
933
 
        u8 QueIdx, UserPriority;
934
 
        struct rt_mac_table_entry *pEntry = NULL;
935
 
        unsigned int IrqFlags;
936
 
        u8 FlgIsIP = 0;
937
 
        u8 Rate;
938
 
 
939
 
        /* Prepare packet information structure for buffer descriptor */
940
 
        /* chained within a single NDIS packet. */
941
 
        RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
942
 
 
943
 
        if (pSrcBufVA == NULL) {
944
 
                DBGPRINT(RT_DEBUG_ERROR,
945
 
                         ("STASendPacket --> pSrcBufVA == NULL !SrcBufLen=%x\n",
946
 
                          SrcBufLen));
947
 
                /* Resource is low, system did not allocate virtual address */
948
 
                /* return NDIS_STATUS_FAILURE directly to upper layer */
949
 
                RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
950
 
                return NDIS_STATUS_FAILURE;
951
 
        }
952
 
 
953
 
        if (SrcBufLen < 14) {
954
 
                DBGPRINT(RT_DEBUG_ERROR,
955
 
                         ("STASendPacket --> Ndis Packet buffer error!\n"));
956
 
                RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
957
 
                return (NDIS_STATUS_FAILURE);
958
 
        }
959
 
        /* In HT rate adhoc mode, A-MPDU is often used. So need to lookup BA Table and MAC Entry. */
960
 
        /* Note multicast packets in adhoc also use BSSID_WCID index. */
961
 
        {
962
 
                if (INFRA_ON(pAd)) {
963
 
                        {
964
 
                                pEntry = &pAd->MacTab.Content[BSSID_WCID];
965
 
                                RTMP_SET_PACKET_WCID(pPacket, BSSID_WCID);
966
 
                                Rate = pAd->CommonCfg.TxRate;
967
 
                        }
968
 
                } else if (ADHOC_ON(pAd)) {
969
 
                        if (*pSrcBufVA & 0x01) {
970
 
                                RTMP_SET_PACKET_WCID(pPacket, MCAST_WCID);
971
 
                                pEntry = &pAd->MacTab.Content[MCAST_WCID];
972
 
                        } else {
973
 
                                pEntry = MacTableLookup(pAd, pSrcBufVA);
974
 
                        }
975
 
                        Rate = pAd->CommonCfg.TxRate;
976
 
                }
977
 
        }
978
 
 
979
 
        if (!pEntry) {
980
 
                DBGPRINT(RT_DEBUG_ERROR,
981
 
                        ("STASendPacket->Cannot find pEntry(%pM) in MacTab!\n",
982
 
                                pSrcBufVA));
983
 
                /* Resource is low, system did not allocate virtual address */
984
 
                /* return NDIS_STATUS_FAILURE directly to upper layer */
985
 
                RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
986
 
                return NDIS_STATUS_FAILURE;
987
 
        }
988
 
 
989
 
        if (ADHOC_ON(pAd)
990
 
            ) {
991
 
                RTMP_SET_PACKET_WCID(pPacket, (u8)pEntry->Aid);
992
 
        }
993
 
        /* */
994
 
        /* Check the Ethernet Frame type of this packet, and set the RTMP_SET_PACKET_SPECIFIC flags. */
995
 
        /*              Here we set the PACKET_SPECIFIC flags(LLC, VLAN, DHCP/ARP, EAPOL). */
996
 
        RTMPCheckEtherType(pAd, pPacket);
997
 
 
998
 
        /* */
999
 
        /* WPA 802.1x secured port control - drop all non-802.1x frame before port secured */
1000
 
        /* */
1001
 
        if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
1002
 
             (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
1003
 
             (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
1004
 
             (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
1005
 
             || (pAd->StaCfg.IEEE8021X == TRUE)
1006
 
            )
1007
 
            && ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)
1008
 
                || (pAd->StaCfg.MicErrCnt >= 2))
1009
 
            && (RTMP_GET_PACKET_EAPOL(pPacket) == FALSE)
1010
 
            ) {
1011
 
                DBGPRINT(RT_DEBUG_TRACE,
1012
 
                         ("STASendPacket --> Drop packet before port secured!\n"));
1013
 
                RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1014
 
 
1015
 
                return (NDIS_STATUS_FAILURE);
1016
 
        }
1017
 
 
1018
 
        /* STEP 1. Decide number of fragments required to deliver this MSDU. */
1019
 
        /*         The estimation here is not very accurate because difficult to */
1020
 
        /*         take encryption overhead into consideration here. The result */
1021
 
        /*         "NumberOfFrag" is then just used to pre-check if enough free */
1022
 
        /*         TXD are available to hold this MSDU. */
1023
 
 
1024
 
        if (*pSrcBufVA & 0x01)  /* fragmentation not allowed on multicast & broadcast */
1025
 
                NumberOfFrag = 1;
1026
 
        else if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED))
1027
 
                NumberOfFrag = 1;       /* Aggregation overwhelms fragmentation */
1028
 
        else if (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED))
1029
 
                NumberOfFrag = 1;       /* Aggregation overwhelms fragmentation */
1030
 
        else if ((pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTMIX)
1031
 
                 || (pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTGREENFIELD))
1032
 
                NumberOfFrag = 1;       /* MIMO RATE overwhelms fragmentation */
1033
 
        else {
1034
 
                /* The calculated "NumberOfFrag" is a rough estimation because of various */
1035
 
                /* encryption/encapsulation overhead not taken into consideration. This number is just */
1036
 
                /* used to make sure enough free TXD are available before fragmentation takes place. */
1037
 
                /* In case the actual required number of fragments of an NDIS packet */
1038
 
                /* excceeds "NumberOfFrag"caculated here and not enough free TXD available, the */
1039
 
                /* last fragment (i.e. last MPDU) will be dropped in RTMPHardTransmit() due to out of */
1040
 
                /* resource, and the NDIS packet will be indicated NDIS_STATUS_FAILURE. This should */
1041
 
                /* rarely happen and the penalty is just like a TX RETRY fail. Affordable. */
1042
 
 
1043
 
                AllowFragSize =
1044
 
                    (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 -
1045
 
                    LENGTH_CRC;
1046
 
                NumberOfFrag =
1047
 
                    ((PacketInfo.TotalPacketLength - LENGTH_802_3 +
1048
 
                      LENGTH_802_1_H) / AllowFragSize) + 1;
1049
 
                /* To get accurate number of fragmentation, Minus 1 if the size just match to allowable fragment size */
1050
 
                if (((PacketInfo.TotalPacketLength - LENGTH_802_3 +
1051
 
                      LENGTH_802_1_H) % AllowFragSize) == 0) {
1052
 
                        NumberOfFrag--;
1053
 
                }
1054
 
        }
1055
 
 
1056
 
        /* Save fragment number to Ndis packet reserved field */
1057
 
        RTMP_SET_PACKET_FRAGMENTS(pPacket, NumberOfFrag);
1058
 
 
1059
 
        /* STEP 2. Check the requirement of RTS: */
1060
 
        /*         If multiple fragment required, RTS is required only for the first fragment */
1061
 
        /*         if the fragment size is larger than RTS threshold */
1062
 
        /*     For RT28xx, Let ASIC send RTS/CTS */
1063
 
        /*      RTMP_SET_PACKET_RTS(pPacket, 0); */
1064
 
        if (NumberOfFrag > 1)
1065
 
                RTSRequired =
1066
 
                    (pAd->CommonCfg.FragmentThreshold >
1067
 
                     pAd->CommonCfg.RtsThreshold) ? 1 : 0;
1068
 
        else
1069
 
                RTSRequired =
1070
 
                    (PacketInfo.TotalPacketLength >
1071
 
                     pAd->CommonCfg.RtsThreshold) ? 1 : 0;
1072
 
 
1073
 
        /* Save RTS requirement to Ndis packet reserved field */
1074
 
        RTMP_SET_PACKET_RTS(pPacket, RTSRequired);
1075
 
        RTMP_SET_PACKET_TXRATE(pPacket, pAd->CommonCfg.TxRate);
1076
 
 
1077
 
        /* */
1078
 
        /* STEP 3. Traffic classification. outcome = <UserPriority, QueIdx> */
1079
 
        /* */
1080
 
        UserPriority = 0;
1081
 
        QueIdx = QID_AC_BE;
1082
 
        if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
1083
 
            CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE)) {
1084
 
                u16 Protocol;
1085
 
                u8 LlcSnapLen = 0, Byte0, Byte1;
1086
 
                do {
1087
 
                        /* get Ethernet protocol field */
1088
 
                        Protocol =
1089
 
                            (u16)((pSrcBufVA[12] << 8) + pSrcBufVA[13]);
1090
 
                        if (Protocol <= 1500) {
1091
 
                                /* get Ethernet protocol field from LLC/SNAP */
1092
 
                                if (Sniff2BytesFromNdisBuffer
1093
 
                                    (PacketInfo.pFirstBuffer, LENGTH_802_3 + 6,
1094
 
                                     &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
1095
 
                                        break;
1096
 
 
1097
 
                                Protocol = (u16)((Byte0 << 8) + Byte1);
1098
 
                                LlcSnapLen = 8;
1099
 
                        }
1100
 
                        /* always AC_BE for non-IP packet */
1101
 
                        if (Protocol != 0x0800)
1102
 
                                break;
1103
 
 
1104
 
                        /* get IP header */
1105
 
                        if (Sniff2BytesFromNdisBuffer
1106
 
                            (PacketInfo.pFirstBuffer, LENGTH_802_3 + LlcSnapLen,
1107
 
                             &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
1108
 
                                break;
1109
 
 
1110
 
                        /* return AC_BE if packet is not IPv4 */
1111
 
                        if ((Byte0 & 0xf0) != 0x40)
1112
 
                                break;
1113
 
 
1114
 
                        FlgIsIP = 1;
1115
 
                        UserPriority = (Byte1 & 0xe0) >> 5;
1116
 
                        QueIdx = MapUserPriorityToAccessCategory[UserPriority];
1117
 
 
1118
 
                        /* TODO: have to check ACM bit. apply TSPEC if ACM is ON */
1119
 
                        /* TODO: downgrade UP & QueIdx before passing ACM */
1120
 
                        /*
1121
 
                           Under WMM ACM control, we dont need to check the bit;
1122
 
                           Or when a TSPEC is built for VO but we will change to issue
1123
 
                           BA session for BE here, so we will not use BA to send VO packets.
1124
 
                         */
1125
 
                        if (pAd->CommonCfg.APEdcaParm.bACM[QueIdx]) {
1126
 
                                UserPriority = 0;
1127
 
                                QueIdx = QID_AC_BE;
1128
 
                        }
1129
 
                } while (FALSE);
1130
 
        }
1131
 
 
1132
 
        RTMP_SET_PACKET_UP(pPacket, UserPriority);
1133
 
 
1134
 
        /* Make sure SendTxWait queue resource won't be used by other threads */
1135
 
        RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
1136
 
        if (pAd->TxSwQueue[QueIdx].Number >= MAX_PACKETS_IN_QUEUE) {
1137
 
                RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
1138
 
                RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1139
 
 
1140
 
                return NDIS_STATUS_FAILURE;
1141
 
        } else {
1142
 
                InsertTailQueueAc(pAd, pEntry, &pAd->TxSwQueue[QueIdx],
1143
 
                                  PACKET_TO_QUEUE_ENTRY(pPacket));
1144
 
        }
1145
 
        RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
1146
 
 
1147
 
        if ((pAd->CommonCfg.BACapability.field.AutoBA == TRUE) &&
1148
 
            IS_HT_STA(pEntry)) {
1149
 
                /*struct rt_mac_table_entry *pMacEntry = &pAd->MacTab.Content[BSSID_WCID]; */
1150
 
                if (((pEntry->TXBAbitmap & (1 << UserPriority)) == 0) &&
1151
 
                    ((pEntry->BADeclineBitmap & (1 << UserPriority)) == 0) &&
1152
 
                    (pEntry->PortSecured == WPA_802_1X_PORT_SECURED)
1153
 
                    /* For IOT compatibility, if */
1154
 
                    /* 1. It is Ralink chip or */
1155
 
                    /* 2. It is OPEN or AES mode, */
1156
 
                    /* then BA session can be bulit. */
1157
 
                    && ((pEntry->ValidAsCLI && pAd->MlmeAux.APRalinkIe != 0x0)
1158
 
                        || (pEntry->WepStatus != Ndis802_11WEPEnabled
1159
 
                            && pEntry->WepStatus !=
1160
 
                            Ndis802_11Encryption2Enabled))
1161
 
                    ) {
1162
 
                        BAOriSessionSetUp(pAd, pEntry, UserPriority, 0, 10,
1163
 
                                          FALSE);
1164
 
                }
1165
 
        }
1166
 
 
1167
 
        pAd->RalinkCounters.OneSecOsTxCount[QueIdx]++;  /* TODO: for debug only. to be removed */
1168
 
        return NDIS_STATUS_SUCCESS;
1169
 
}
1170
 
 
1171
 
/*
1172
 
        ========================================================================
1173
 
 
1174
 
        Routine Description:
1175
 
                This subroutine will scan through relative ring descriptor to find
1176
 
                out available free ring descriptor and compare with request size.
1177
 
 
1178
 
        Arguments:
1179
 
                pAd Pointer to our adapter
1180
 
                QueIdx          Selected TX Ring
1181
 
 
1182
 
        Return Value:
1183
 
                NDIS_STATUS_FAILURE     Not enough free descriptor
1184
 
                NDIS_STATUS_SUCCESS     Enough free descriptor
1185
 
 
1186
 
        IRQL = PASSIVE_LEVEL
1187
 
        IRQL = DISPATCH_LEVEL
1188
 
 
1189
 
        Note:
1190
 
 
1191
 
        ========================================================================
1192
 
*/
1193
 
#ifdef RTMP_MAC_PCI
1194
 
int RTMPFreeTXDRequest(struct rt_rtmp_adapter *pAd,
1195
 
                               u8 QueIdx,
1196
 
                               u8 NumberRequired, u8 *FreeNumberIs)
1197
 
{
1198
 
        unsigned long FreeNumber = 0;
1199
 
        int Status = NDIS_STATUS_FAILURE;
1200
 
 
1201
 
        switch (QueIdx) {
1202
 
        case QID_AC_BK:
1203
 
        case QID_AC_BE:
1204
 
        case QID_AC_VI:
1205
 
        case QID_AC_VO:
1206
 
                if (pAd->TxRing[QueIdx].TxSwFreeIdx >
1207
 
                    pAd->TxRing[QueIdx].TxCpuIdx)
1208
 
                        FreeNumber =
1209
 
                            pAd->TxRing[QueIdx].TxSwFreeIdx -
1210
 
                            pAd->TxRing[QueIdx].TxCpuIdx - 1;
1211
 
                else
1212
 
                        FreeNumber =
1213
 
                            pAd->TxRing[QueIdx].TxSwFreeIdx + TX_RING_SIZE -
1214
 
                            pAd->TxRing[QueIdx].TxCpuIdx - 1;
1215
 
 
1216
 
                if (FreeNumber >= NumberRequired)
1217
 
                        Status = NDIS_STATUS_SUCCESS;
1218
 
                break;
1219
 
 
1220
 
        case QID_MGMT:
1221
 
                if (pAd->MgmtRing.TxSwFreeIdx > pAd->MgmtRing.TxCpuIdx)
1222
 
                        FreeNumber =
1223
 
                            pAd->MgmtRing.TxSwFreeIdx - pAd->MgmtRing.TxCpuIdx -
1224
 
                            1;
1225
 
                else
1226
 
                        FreeNumber =
1227
 
                            pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE -
1228
 
                            pAd->MgmtRing.TxCpuIdx - 1;
1229
 
 
1230
 
                if (FreeNumber >= NumberRequired)
1231
 
                        Status = NDIS_STATUS_SUCCESS;
1232
 
                break;
1233
 
 
1234
 
        default:
1235
 
                DBGPRINT(RT_DEBUG_ERROR,
1236
 
                         ("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx));
1237
 
                break;
1238
 
        }
1239
 
        *FreeNumberIs = (u8)FreeNumber;
1240
 
 
1241
 
        return (Status);
1242
 
}
1243
 
#endif /* RTMP_MAC_PCI // */
1244
 
#ifdef RTMP_MAC_USB
1245
 
/*
1246
 
        Actually, this function used to check if the TxHardware Queue still has frame need to send.
1247
 
        If no frame need to send, go to sleep, else, still wake up.
1248
 
*/
1249
 
int RTMPFreeTXDRequest(struct rt_rtmp_adapter *pAd,
1250
 
                               u8 QueIdx,
1251
 
                               u8 NumberRequired, u8 *FreeNumberIs)
1252
 
{
1253
 
        /*unsigned long         FreeNumber = 0; */
1254
 
        int Status = NDIS_STATUS_FAILURE;
1255
 
        unsigned long IrqFlags;
1256
 
        struct rt_ht_tx_context *pHTTXContext;
1257
 
 
1258
 
        switch (QueIdx) {
1259
 
        case QID_AC_BK:
1260
 
        case QID_AC_BE:
1261
 
        case QID_AC_VI:
1262
 
        case QID_AC_VO:
1263
 
                {
1264
 
                        pHTTXContext = &pAd->TxContext[QueIdx];
1265
 
                        RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx],
1266
 
                                      IrqFlags);
1267
 
                        if ((pHTTXContext->CurWritePosition !=
1268
 
                             pHTTXContext->ENextBulkOutPosition)
1269
 
                            || (pHTTXContext->IRPPending == TRUE)) {
1270
 
                                Status = NDIS_STATUS_FAILURE;
1271
 
                        } else {
1272
 
                                Status = NDIS_STATUS_SUCCESS;
1273
 
                        }
1274
 
                        RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx],
1275
 
                                        IrqFlags);
1276
 
                }
1277
 
                break;
1278
 
        case QID_MGMT:
1279
 
                if (pAd->MgmtRing.TxSwFreeIdx != MGMT_RING_SIZE)
1280
 
                        Status = NDIS_STATUS_FAILURE;
1281
 
                else
1282
 
                        Status = NDIS_STATUS_SUCCESS;
1283
 
                break;
1284
 
        default:
1285
 
                DBGPRINT(RT_DEBUG_ERROR,
1286
 
                         ("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx));
1287
 
                break;
1288
 
        }
1289
 
 
1290
 
        return (Status);
1291
 
}
1292
 
#endif /* RTMP_MAC_USB // */
1293
 
 
1294
 
void RTMPSendDisassociationFrame(struct rt_rtmp_adapter *pAd)
1295
 
{
1296
 
}
1297
 
 
1298
 
void RTMPSendNullFrame(struct rt_rtmp_adapter *pAd,
1299
 
                       u8 TxRate, IN BOOLEAN bQosNull)
1300
 
{
1301
 
        u8 NullFrame[48];
1302
 
        unsigned long Length;
1303
 
        struct rt_header_802_11 * pHeader_802_11;
1304
 
 
1305
 
        /* WPA 802.1x secured port control */
1306
 
        if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
1307
 
             (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
1308
 
             (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
1309
 
             (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
1310
 
             || (pAd->StaCfg.IEEE8021X == TRUE)
1311
 
            ) && (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)) {
1312
 
                return;
1313
 
        }
1314
 
 
1315
 
        NdisZeroMemory(NullFrame, 48);
1316
 
        Length = sizeof(struct rt_header_802_11);
1317
 
 
1318
 
        pHeader_802_11 = (struct rt_header_802_11 *) NullFrame;
1319
 
 
1320
 
        pHeader_802_11->FC.Type = BTYPE_DATA;
1321
 
        pHeader_802_11->FC.SubType = SUBTYPE_NULL_FUNC;
1322
 
        pHeader_802_11->FC.ToDs = 1;
1323
 
        COPY_MAC_ADDR(pHeader_802_11->Addr1, pAd->CommonCfg.Bssid);
1324
 
        COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
1325
 
        COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
1326
 
 
1327
 
        if (pAd->CommonCfg.bAPSDForcePowerSave) {
1328
 
                pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
1329
 
        } else {
1330
 
                pHeader_802_11->FC.PwrMgmt =
1331
 
                    (pAd->StaCfg.Psm == PWR_SAVE) ? 1 : 0;
1332
 
        }
1333
 
        pHeader_802_11->Duration =
1334
 
            pAd->CommonCfg.Dsifs + RTMPCalcDuration(pAd, TxRate, 14);
1335
 
 
1336
 
        pAd->Sequence++;
1337
 
        pHeader_802_11->Sequence = pAd->Sequence;
1338
 
 
1339
 
        /* Prepare QosNull function frame */
1340
 
        if (bQosNull) {
1341
 
                pHeader_802_11->FC.SubType = SUBTYPE_QOS_NULL;
1342
 
 
1343
 
                /* copy QOS control bytes */
1344
 
                NullFrame[Length] = 0;
1345
 
                NullFrame[Length + 1] = 0;
1346
 
                Length += 2;    /* if pad with 2 bytes for alignment, APSD will fail */
1347
 
        }
1348
 
 
1349
 
        HAL_KickOutNullFrameTx(pAd, 0, NullFrame, Length);
1350
 
 
1351
 
}
1352
 
 
1353
 
/* IRQL = DISPATCH_LEVEL */
1354
 
void RTMPSendRTSFrame(struct rt_rtmp_adapter *pAd,
1355
 
                      u8 *pDA,
1356
 
                      IN unsigned int NextMpduSize,
1357
 
                      u8 TxRate,
1358
 
                      u8 RTSRate,
1359
 
                      u16 AckDuration, u8 QueIdx, u8 FrameGap)
1360
 
{
1361
 
}
1362
 
 
1363
 
/* -------------------------------------------------------- */
1364
 
/*  FIND ENCRYPT KEY AND DECIDE CIPHER ALGORITHM */
1365
 
/*              Find the WPA key, either Group or Pairwise Key */
1366
 
/*              LEAP + TKIP also use WPA key. */
1367
 
/* -------------------------------------------------------- */
1368
 
/* Decide WEP bit and cipher suite to be used. Same cipher suite should be used for whole fragment burst */
1369
 
/* In Cisco CCX 2.0 Leap Authentication */
1370
 
/*                 WepStatus is Ndis802_11Encryption1Enabled but the key will use PairwiseKey */
1371
 
/*                 Instead of the SharedKey, SharedKey Length may be Zero. */
1372
 
void STAFindCipherAlgorithm(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
1373
 
{
1374
 
        NDIS_802_11_ENCRYPTION_STATUS Cipher;   /* To indicate cipher used for this packet */
1375
 
        u8 CipherAlg = CIPHER_NONE;     /* cipher alogrithm */
1376
 
        u8 KeyIdx = 0xff;
1377
 
        u8 *pSrcBufVA;
1378
 
        struct rt_cipher_key *pKey = NULL;
1379
 
 
1380
 
        pSrcBufVA = GET_OS_PKT_DATAPTR(pTxBlk->pPacket);
1381
 
 
1382
 
        {
1383
 
                /* Select Cipher */
1384
 
                if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd)))
1385
 
                        Cipher = pAd->StaCfg.GroupCipher;       /* Cipher for Multicast or Broadcast */
1386
 
                else
1387
 
                        Cipher = pAd->StaCfg.PairCipher;        /* Cipher for Unicast */
1388
 
 
1389
 
                if (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket)) {
1390
 
                        ASSERT(pAd->SharedKey[BSS0][0].CipherAlg <=
1391
 
                               CIPHER_CKIP128);
1392
 
 
1393
 
                        /* 4-way handshaking frame must be clear */
1394
 
                        if (!(TX_BLK_TEST_FLAG(pTxBlk, fTX_bClearEAPFrame))
1395
 
                            && (pAd->SharedKey[BSS0][0].CipherAlg)
1396
 
                            && (pAd->SharedKey[BSS0][0].KeyLen)) {
1397
 
                                CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
1398
 
                                KeyIdx = 0;
1399
 
                        }
1400
 
                } else if (Cipher == Ndis802_11Encryption1Enabled) {
1401
 
                        KeyIdx = pAd->StaCfg.DefaultKeyId;
1402
 
                } else if ((Cipher == Ndis802_11Encryption2Enabled) ||
1403
 
                           (Cipher == Ndis802_11Encryption3Enabled)) {
1404
 
                        if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd)))     /* multicast */
1405
 
                                KeyIdx = pAd->StaCfg.DefaultKeyId;
1406
 
                        else if (pAd->SharedKey[BSS0][0].KeyLen)
1407
 
                                KeyIdx = 0;
1408
 
                        else
1409
 
                                KeyIdx = pAd->StaCfg.DefaultKeyId;
1410
 
                }
1411
 
 
1412
 
                if (KeyIdx == 0xff)
1413
 
                        CipherAlg = CIPHER_NONE;
1414
 
                else if ((Cipher == Ndis802_11EncryptionDisabled)
1415
 
                         || (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 0))
1416
 
                        CipherAlg = CIPHER_NONE;
1417
 
                else if (pAd->StaCfg.WpaSupplicantUP &&
1418
 
                         (Cipher == Ndis802_11Encryption1Enabled) &&
1419
 
                         (pAd->StaCfg.IEEE8021X == TRUE) &&
1420
 
                         (pAd->StaCfg.PortSecured ==
1421
 
                          WPA_802_1X_PORT_NOT_SECURED))
1422
 
                        CipherAlg = CIPHER_NONE;
1423
 
                else {
1424
 
                        /*Header_802_11.FC.Wep = 1; */
1425
 
                        CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
1426
 
                        pKey = &pAd->SharedKey[BSS0][KeyIdx];
1427
 
                }
1428
 
        }
1429
 
 
1430
 
        pTxBlk->CipherAlg = CipherAlg;
1431
 
        pTxBlk->pKey = pKey;
1432
 
}
1433
 
 
1434
 
void STABuildCommon802_11Header(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
1435
 
{
1436
 
        struct rt_header_802_11 *pHeader_802_11;
1437
 
 
1438
 
        /* */
1439
 
        /* MAKE A COMMON 802.11 HEADER */
1440
 
        /* */
1441
 
 
1442
 
        /* normal wlan header size : 24 octets */
1443
 
        pTxBlk->MpduHeaderLen = sizeof(struct rt_header_802_11);
1444
 
 
1445
 
        pHeader_802_11 =
1446
 
            (struct rt_header_802_11 *) & pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
1447
 
 
1448
 
        NdisZeroMemory(pHeader_802_11, sizeof(struct rt_header_802_11));
1449
 
 
1450
 
        pHeader_802_11->FC.FrDs = 0;
1451
 
        pHeader_802_11->FC.Type = BTYPE_DATA;
1452
 
        pHeader_802_11->FC.SubType =
1453
 
            ((TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) ? SUBTYPE_QDATA :
1454
 
             SUBTYPE_DATA);
1455
 
 
1456
 
        if (pTxBlk->pMacEntry) {
1457
 
                if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bForceNonQoS)) {
1458
 
                        pHeader_802_11->Sequence =
1459
 
                            pTxBlk->pMacEntry->NonQosDataSeq;
1460
 
                        pTxBlk->pMacEntry->NonQosDataSeq =
1461
 
                            (pTxBlk->pMacEntry->NonQosDataSeq + 1) & MAXSEQ;
1462
 
                } else {
1463
 
                        {
1464
 
                                pHeader_802_11->Sequence =
1465
 
                                    pTxBlk->pMacEntry->TxSeq[pTxBlk->
1466
 
                                                             UserPriority];
1467
 
                                pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority] =
1468
 
                                    (pTxBlk->pMacEntry->
1469
 
                                     TxSeq[pTxBlk->UserPriority] + 1) & MAXSEQ;
1470
 
                        }
1471
 
                }
1472
 
        } else {
1473
 
                pHeader_802_11->Sequence = pAd->Sequence;
1474
 
                pAd->Sequence = (pAd->Sequence + 1) & MAXSEQ;   /* next sequence */
1475
 
        }
1476
 
 
1477
 
        pHeader_802_11->Frag = 0;
1478
 
 
1479
 
        pHeader_802_11->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
1480
 
 
1481
 
        {
1482
 
                if (INFRA_ON(pAd)) {
1483
 
                        {
1484
 
                                COPY_MAC_ADDR(pHeader_802_11->Addr1,
1485
 
                                              pAd->CommonCfg.Bssid);
1486
 
                                COPY_MAC_ADDR(pHeader_802_11->Addr2,
1487
 
                                              pAd->CurrentAddress);
1488
 
                                COPY_MAC_ADDR(pHeader_802_11->Addr3,
1489
 
                                              pTxBlk->pSrcBufHeader);
1490
 
                                pHeader_802_11->FC.ToDs = 1;
1491
 
                        }
1492
 
                } else if (ADHOC_ON(pAd)) {
1493
 
                        COPY_MAC_ADDR(pHeader_802_11->Addr1,
1494
 
                                      pTxBlk->pSrcBufHeader);
1495
 
                        COPY_MAC_ADDR(pHeader_802_11->Addr2,
1496
 
                                      pAd->CurrentAddress);
1497
 
                        COPY_MAC_ADDR(pHeader_802_11->Addr3,
1498
 
                                      pAd->CommonCfg.Bssid);
1499
 
                        pHeader_802_11->FC.ToDs = 0;
1500
 
                }
1501
 
        }
1502
 
 
1503
 
        if (pTxBlk->CipherAlg != CIPHER_NONE)
1504
 
                pHeader_802_11->FC.Wep = 1;
1505
 
 
1506
 
        /* ----------------------------------------------------------------- */
1507
 
        /* STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later. */
1508
 
        /* ----------------------------------------------------------------- */
1509
 
        if (pAd->CommonCfg.bAPSDForcePowerSave)
1510
 
                pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
1511
 
        else
1512
 
                pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
1513
 
}
1514
 
 
1515
 
void STABuildCache802_11Header(struct rt_rtmp_adapter *pAd,
1516
 
                               struct rt_tx_blk *pTxBlk, u8 * pHeader)
1517
 
{
1518
 
        struct rt_mac_table_entry *pMacEntry;
1519
 
        struct rt_header_802_11 * pHeader80211;
1520
 
 
1521
 
        pHeader80211 = (struct rt_header_802_11 *) pHeader;
1522
 
        pMacEntry = pTxBlk->pMacEntry;
1523
 
 
1524
 
        /* */
1525
 
        /* Update the cached 802.11 HEADER */
1526
 
        /* */
1527
 
 
1528
 
        /* normal wlan header size : 24 octets */
1529
 
        pTxBlk->MpduHeaderLen = sizeof(struct rt_header_802_11);
1530
 
 
1531
 
        /* More Bit */
1532
 
        pHeader80211->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
1533
 
 
1534
 
        /* Sequence */
1535
 
        pHeader80211->Sequence = pMacEntry->TxSeq[pTxBlk->UserPriority];
1536
 
        pMacEntry->TxSeq[pTxBlk->UserPriority] =
1537
 
            (pMacEntry->TxSeq[pTxBlk->UserPriority] + 1) & MAXSEQ;
1538
 
 
1539
 
        {
1540
 
                /* Check if the frame can be sent through DLS direct link interface */
1541
 
                /* If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability) */
1542
 
 
1543
 
                /* The addr3 of normal packet send from DS is Dest Mac address. */
1544
 
                if (ADHOC_ON(pAd))
1545
 
                        COPY_MAC_ADDR(pHeader80211->Addr3,
1546
 
                                      pAd->CommonCfg.Bssid);
1547
 
                else
1548
 
                        COPY_MAC_ADDR(pHeader80211->Addr3,
1549
 
                                      pTxBlk->pSrcBufHeader);
1550
 
        }
1551
 
 
1552
 
        /* ----------------------------------------------------------------- */
1553
 
        /* STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later. */
1554
 
        /* ----------------------------------------------------------------- */
1555
 
        if (pAd->CommonCfg.bAPSDForcePowerSave)
1556
 
                pHeader80211->FC.PwrMgmt = PWR_SAVE;
1557
 
        else
1558
 
                pHeader80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
1559
 
}
1560
 
 
1561
 
static inline u8 *STA_Build_ARalink_Frame_Header(struct rt_rtmp_adapter *pAd,
1562
 
                                                    struct rt_tx_blk *pTxBlk)
1563
 
{
1564
 
        u8 *pHeaderBufPtr;
1565
 
        struct rt_header_802_11 *pHeader_802_11;
1566
 
        void *pNextPacket;
1567
 
        u32 nextBufLen;
1568
 
        struct rt_queue_entry *pQEntry;
1569
 
 
1570
 
        STAFindCipherAlgorithm(pAd, pTxBlk);
1571
 
        STABuildCommon802_11Header(pAd, pTxBlk);
1572
 
 
1573
 
        pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
1574
 
        pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr;
1575
 
 
1576
 
        /* steal "order" bit to mark "aggregation" */
1577
 
        pHeader_802_11->FC.Order = 1;
1578
 
 
1579
 
        /* skip common header */
1580
 
        pHeaderBufPtr += pTxBlk->MpduHeaderLen;
1581
 
 
1582
 
        if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) {
1583
 
                /* */
1584
 
                /* build QOS Control bytes */
1585
 
                /* */
1586
 
                *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
1587
 
 
1588
 
                *(pHeaderBufPtr + 1) = 0;
1589
 
                pHeaderBufPtr += 2;
1590
 
                pTxBlk->MpduHeaderLen += 2;
1591
 
        }
1592
 
        /* padding at front of LLC header. LLC header should at 4-bytes alignment. */
1593
 
        pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
1594
 
        pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
1595
 
        pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);
1596
 
 
1597
 
        /* For RA Aggregation, */
1598
 
        /* put the 2nd MSDU length(extra 2-byte field) after struct rt_qos_control in little endian format */
1599
 
        pQEntry = pTxBlk->TxPacketList.Head;
1600
 
        pNextPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
1601
 
        nextBufLen = GET_OS_PKT_LEN(pNextPacket);
1602
 
        if (RTMP_GET_PACKET_VLAN(pNextPacket))
1603
 
                nextBufLen -= LENGTH_802_1Q;
1604
 
 
1605
 
        *pHeaderBufPtr = (u8)nextBufLen & 0xff;
1606
 
        *(pHeaderBufPtr + 1) = (u8)(nextBufLen >> 8);
1607
 
 
1608
 
        pHeaderBufPtr += 2;
1609
 
        pTxBlk->MpduHeaderLen += 2;
1610
 
 
1611
 
        return pHeaderBufPtr;
1612
 
 
1613
 
}
1614
 
 
1615
 
static inline u8 *STA_Build_AMSDU_Frame_Header(struct rt_rtmp_adapter *pAd,
1616
 
                                                  struct rt_tx_blk *pTxBlk)
1617
 
{
1618
 
        u8 *pHeaderBufPtr;      /*, pSaveBufPtr; */
1619
 
        struct rt_header_802_11 *pHeader_802_11;
1620
 
 
1621
 
        STAFindCipherAlgorithm(pAd, pTxBlk);
1622
 
        STABuildCommon802_11Header(pAd, pTxBlk);
1623
 
 
1624
 
        pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
1625
 
        pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr;
1626
 
 
1627
 
        /* skip common header */
1628
 
        pHeaderBufPtr += pTxBlk->MpduHeaderLen;
1629
 
 
1630
 
        /* */
1631
 
        /* build QOS Control bytes */
1632
 
        /* */
1633
 
        *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
1634
 
 
1635
 
        /* */
1636
 
        /* A-MSDU packet */
1637
 
        /* */
1638
 
        *pHeaderBufPtr |= 0x80;
1639
 
 
1640
 
        *(pHeaderBufPtr + 1) = 0;
1641
 
        pHeaderBufPtr += 2;
1642
 
        pTxBlk->MpduHeaderLen += 2;
1643
 
 
1644
 
        /*pSaveBufPtr = pHeaderBufPtr; */
1645
 
 
1646
 
        /* */
1647
 
        /* padding at front of LLC header */
1648
 
        /* LLC header should locate at 4-octets aligment */
1649
 
        /* */
1650
 
        /* @@@ MpduHeaderLen excluding padding @@@ */
1651
 
        /* */
1652
 
        pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
1653
 
        pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
1654
 
        pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);
1655
 
 
1656
 
        return pHeaderBufPtr;
1657
 
 
1658
 
}
1659
 
 
1660
 
void STA_AMPDU_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
1661
 
{
1662
 
        struct rt_header_802_11 *pHeader_802_11;
1663
 
        u8 *pHeaderBufPtr;
1664
 
        u16 FreeNumber;
1665
 
        struct rt_mac_table_entry *pMacEntry;
1666
 
        BOOLEAN bVLANPkt;
1667
 
        struct rt_queue_entry *pQEntry;
1668
 
 
1669
 
        ASSERT(pTxBlk);
1670
 
 
1671
 
        while (pTxBlk->TxPacketList.Head) {
1672
 
                pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
1673
 
                pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
1674
 
                if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) {
1675
 
                        RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket,
1676
 
                                            NDIS_STATUS_FAILURE);
1677
 
                        continue;
1678
 
                }
1679
 
 
1680
 
                bVLANPkt =
1681
 
                    (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
1682
 
 
1683
 
                pMacEntry = pTxBlk->pMacEntry;
1684
 
                if (pMacEntry->isCached) {
1685
 
                        /* NOTE: Please make sure the size of pMacEntry->CachedBuf[] is smaller than pTxBlk->HeaderBuf[]! */
1686
 
                        NdisMoveMemory((u8 *)& pTxBlk->
1687
 
                                       HeaderBuf[TXINFO_SIZE],
1688
 
                                       (u8 *)& pMacEntry->CachedBuf[0],
1689
 
                                       TXWI_SIZE + sizeof(struct rt_header_802_11));
1690
 
                        pHeaderBufPtr =
1691
 
                            (u8 *)(&pTxBlk->
1692
 
                                      HeaderBuf[TXINFO_SIZE + TXWI_SIZE]);
1693
 
                        STABuildCache802_11Header(pAd, pTxBlk, pHeaderBufPtr);
1694
 
                } else {
1695
 
                        STAFindCipherAlgorithm(pAd, pTxBlk);
1696
 
                        STABuildCommon802_11Header(pAd, pTxBlk);
1697
 
 
1698
 
                        pHeaderBufPtr =
1699
 
                            &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
1700
 
                }
1701
 
 
1702
 
                pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr;
1703
 
 
1704
 
                /* skip common header */
1705
 
                pHeaderBufPtr += pTxBlk->MpduHeaderLen;
1706
 
 
1707
 
                /* */
1708
 
                /* build QOS Control bytes */
1709
 
                /* */
1710
 
                *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
1711
 
                *(pHeaderBufPtr + 1) = 0;
1712
 
                pHeaderBufPtr += 2;
1713
 
                pTxBlk->MpduHeaderLen += 2;
1714
 
 
1715
 
                /* */
1716
 
                /* build HTC+ */
1717
 
                /* HTC control filed following QoS field */
1718
 
                /* */
1719
 
                if ((pAd->CommonCfg.bRdg == TRUE)
1720
 
                    && CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry,
1721
 
                                               fCLIENT_STATUS_RDG_CAPABLE)) {
1722
 
                        if (pMacEntry->isCached == FALSE) {
1723
 
                                /* mark HTC bit */
1724
 
                                pHeader_802_11->FC.Order = 1;
1725
 
 
1726
 
                                NdisZeroMemory(pHeaderBufPtr, 4);
1727
 
                                *(pHeaderBufPtr + 3) |= 0x80;
1728
 
                        }
1729
 
                        pHeaderBufPtr += 4;
1730
 
                        pTxBlk->MpduHeaderLen += 4;
1731
 
                }
1732
 
                /*pTxBlk->MpduHeaderLen = pHeaderBufPtr - pTxBlk->HeaderBuf - TXWI_SIZE - TXINFO_SIZE; */
1733
 
                ASSERT(pTxBlk->MpduHeaderLen >= 24);
1734
 
 
1735
 
                /* skip 802.3 header */
1736
 
                pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
1737
 
                pTxBlk->SrcBufLen -= LENGTH_802_3;
1738
 
 
1739
 
                /* skip vlan tag */
1740
 
                if (bVLANPkt) {
1741
 
                        pTxBlk->pSrcBufData += LENGTH_802_1Q;
1742
 
                        pTxBlk->SrcBufLen -= LENGTH_802_1Q;
1743
 
                }
1744
 
                /* */
1745
 
                /* padding at front of LLC header */
1746
 
                /* LLC header should locate at 4-octets aligment */
1747
 
                /* */
1748
 
                /* @@@ MpduHeaderLen excluding padding @@@ */
1749
 
                /* */
1750
 
                pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
1751
 
                pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
1752
 
                pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);
1753
 
 
1754
 
                {
1755
 
 
1756
 
                        /* */
1757
 
                        /* Insert LLC-SNAP encapsulation - 8 octets */
1758
 
                        /* */
1759
 
                        EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->
1760
 
                                                            pSrcBufData - 2,
1761
 
                                                            pTxBlk->
1762
 
                                                            pExtraLlcSnapEncap);
1763
 
                        if (pTxBlk->pExtraLlcSnapEncap) {
1764
 
                                NdisMoveMemory(pHeaderBufPtr,
1765
 
                                               pTxBlk->pExtraLlcSnapEncap, 6);
1766
 
                                pHeaderBufPtr += 6;
1767
 
                                /* get 2 octets (TypeofLen) */
1768
 
                                NdisMoveMemory(pHeaderBufPtr,
1769
 
                                               pTxBlk->pSrcBufData - 2, 2);
1770
 
                                pHeaderBufPtr += 2;
1771
 
                                pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
1772
 
                        }
1773
 
 
1774
 
                }
1775
 
 
1776
 
                if (pMacEntry->isCached) {
1777
 
                        RTMPWriteTxWI_Cache(pAd,
1778
 
                                            (struct rt_txwi *) (&pTxBlk->
1779
 
                                                           HeaderBuf
1780
 
                                                           [TXINFO_SIZE]),
1781
 
                                            pTxBlk);
1782
 
                } else {
1783
 
                        RTMPWriteTxWI_Data(pAd,
1784
 
                                           (struct rt_txwi *) (&pTxBlk->
1785
 
                                                          HeaderBuf
1786
 
                                                          [TXINFO_SIZE]),
1787
 
                                           pTxBlk);
1788
 
 
1789
 
                        NdisZeroMemory((u8 *)(&pMacEntry->CachedBuf[0]),
1790
 
                                       sizeof(pMacEntry->CachedBuf));
1791
 
                        NdisMoveMemory((u8 *)(&pMacEntry->CachedBuf[0]),
1792
 
                                       (u8 *)(&pTxBlk->
1793
 
                                                 HeaderBuf[TXINFO_SIZE]),
1794
 
                                       (pHeaderBufPtr -
1795
 
                                        (u8 *)(&pTxBlk->
1796
 
                                                  HeaderBuf[TXINFO_SIZE])));
1797
 
                        pMacEntry->isCached = TRUE;
1798
 
                }
1799
 
 
1800
 
                /* calculate Transmitted AMPDU count and ByteCount */
1801
 
                {
1802
 
                        pAd->RalinkCounters.TransmittedMPDUsInAMPDUCount.u.
1803
 
                            LowPart++;
1804
 
                        pAd->RalinkCounters.TransmittedOctetsInAMPDUCount.
1805
 
                            QuadPart += pTxBlk->SrcBufLen;
1806
 
                }
1807
 
 
1808
 
                /*FreeNumber = GET_TXRING_FREENO(pAd, QueIdx); */
1809
 
 
1810
 
                HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
1811
 
 
1812
 
                /* */
1813
 
                /* Kick out Tx */
1814
 
                /* */
1815
 
                if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
1816
 
                        HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
1817
 
 
1818
 
                pAd->RalinkCounters.KickTxCount++;
1819
 
                pAd->RalinkCounters.OneSecTxDoneCount++;
1820
 
        }
1821
 
 
1822
 
}
1823
 
 
1824
 
void STA_AMSDU_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
1825
 
{
1826
 
        u8 *pHeaderBufPtr;
1827
 
        u16 FreeNumber;
1828
 
        u16 subFramePayloadLen = 0;     /* AMSDU Subframe length without AMSDU-Header / Padding. */
1829
 
        u16 totalMPDUSize = 0;
1830
 
        u8 *subFrameHeader;
1831
 
        u8 padding = 0;
1832
 
        u16 FirstTx = 0, LastTxIdx = 0;
1833
 
        BOOLEAN bVLANPkt;
1834
 
        int frameNum = 0;
1835
 
        struct rt_queue_entry *pQEntry;
1836
 
 
1837
 
        ASSERT(pTxBlk);
1838
 
 
1839
 
        ASSERT((pTxBlk->TxPacketList.Number > 1));
1840
 
 
1841
 
        while (pTxBlk->TxPacketList.Head) {
1842
 
                pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
1843
 
                pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
1844
 
                if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) {
1845
 
                        RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket,
1846
 
                                            NDIS_STATUS_FAILURE);
1847
 
                        continue;
1848
 
                }
1849
 
 
1850
 
                bVLANPkt =
1851
 
                    (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
1852
 
 
1853
 
                /* skip 802.3 header */
1854
 
                pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
1855
 
                pTxBlk->SrcBufLen -= LENGTH_802_3;
1856
 
 
1857
 
                /* skip vlan tag */
1858
 
                if (bVLANPkt) {
1859
 
                        pTxBlk->pSrcBufData += LENGTH_802_1Q;
1860
 
                        pTxBlk->SrcBufLen -= LENGTH_802_1Q;
1861
 
                }
1862
 
 
1863
 
                if (frameNum == 0) {
1864
 
                        pHeaderBufPtr =
1865
 
                            STA_Build_AMSDU_Frame_Header(pAd, pTxBlk);
1866
 
 
1867
 
                        /* NOTE: TxWI->MPDUtotalByteCount will be updated after final frame was handled. */
1868
 
                        RTMPWriteTxWI_Data(pAd,
1869
 
                                           (struct rt_txwi *) (&pTxBlk->
1870
 
                                                          HeaderBuf
1871
 
                                                          [TXINFO_SIZE]),
1872
 
                                           pTxBlk);
1873
 
                } else {
1874
 
                        pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
1875
 
                        padding =
1876
 
                            ROUND_UP(LENGTH_AMSDU_SUBFRAMEHEAD +
1877
 
                                     subFramePayloadLen,
1878
 
                                     4) - (LENGTH_AMSDU_SUBFRAMEHEAD +
1879
 
                                           subFramePayloadLen);
1880
 
                        NdisZeroMemory(pHeaderBufPtr,
1881
 
                                       padding + LENGTH_AMSDU_SUBFRAMEHEAD);
1882
 
                        pHeaderBufPtr += padding;
1883
 
                        pTxBlk->MpduHeaderLen = padding;
1884
 
                }
1885
 
 
1886
 
                /* */
1887
 
                /* A-MSDU subframe */
1888
 
                /*   DA(6)+SA(6)+Length(2) + LLC/SNAP Encap */
1889
 
                /* */
1890
 
                subFrameHeader = pHeaderBufPtr;
1891
 
                subFramePayloadLen = pTxBlk->SrcBufLen;
1892
 
 
1893
 
                NdisMoveMemory(subFrameHeader, pTxBlk->pSrcBufHeader, 12);
1894
 
 
1895
 
                pHeaderBufPtr += LENGTH_AMSDU_SUBFRAMEHEAD;
1896
 
                pTxBlk->MpduHeaderLen += LENGTH_AMSDU_SUBFRAMEHEAD;
1897
 
 
1898
 
                /* */
1899
 
                /* Insert LLC-SNAP encapsulation - 8 octets */
1900
 
                /* */
1901
 
                EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData - 2,
1902
 
                                                    pTxBlk->pExtraLlcSnapEncap);
1903
 
 
1904
 
                subFramePayloadLen = pTxBlk->SrcBufLen;
1905
 
 
1906
 
                if (pTxBlk->pExtraLlcSnapEncap) {
1907
 
                        NdisMoveMemory(pHeaderBufPtr,
1908
 
                                       pTxBlk->pExtraLlcSnapEncap, 6);
1909
 
                        pHeaderBufPtr += 6;
1910
 
                        /* get 2 octets (TypeofLen) */
1911
 
                        NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData - 2,
1912
 
                                       2);
1913
 
                        pHeaderBufPtr += 2;
1914
 
                        pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
1915
 
                        subFramePayloadLen += LENGTH_802_1_H;
1916
 
                }
1917
 
                /* update subFrame Length field */
1918
 
                subFrameHeader[12] = (subFramePayloadLen & 0xFF00) >> 8;
1919
 
                subFrameHeader[13] = subFramePayloadLen & 0xFF;
1920
 
 
1921
 
                totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
1922
 
 
1923
 
                if (frameNum == 0)
1924
 
                        FirstTx =
1925
 
                            HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum,
1926
 
                                                     &FreeNumber);
1927
 
                else
1928
 
                        LastTxIdx =
1929
 
                            HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum,
1930
 
                                                     &FreeNumber);
1931
 
 
1932
 
                frameNum++;
1933
 
 
1934
 
                pAd->RalinkCounters.KickTxCount++;
1935
 
                pAd->RalinkCounters.OneSecTxDoneCount++;
1936
 
 
1937
 
                /* calculate Transmitted AMSDU Count and ByteCount */
1938
 
                {
1939
 
                        pAd->RalinkCounters.TransmittedAMSDUCount.u.LowPart++;
1940
 
                        pAd->RalinkCounters.TransmittedOctetsInAMSDU.QuadPart +=
1941
 
                            totalMPDUSize;
1942
 
                }
1943
 
 
1944
 
        }
1945
 
 
1946
 
        HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
1947
 
        HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
1948
 
 
1949
 
        /* */
1950
 
        /* Kick out Tx */
1951
 
        /* */
1952
 
        if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
1953
 
                HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
1954
 
}
1955
 
 
1956
 
void STA_Legacy_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
1957
 
{
1958
 
        struct rt_header_802_11 *pHeader_802_11;
1959
 
        u8 *pHeaderBufPtr;
1960
 
        u16 FreeNumber;
1961
 
        BOOLEAN bVLANPkt;
1962
 
        struct rt_queue_entry *pQEntry;
1963
 
 
1964
 
        ASSERT(pTxBlk);
1965
 
 
1966
 
        pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
1967
 
        pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
1968
 
        if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) {
1969
 
                RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
1970
 
                return;
1971
 
        }
1972
 
 
1973
 
        if (pTxBlk->TxFrameType == TX_MCAST_FRAME) {
1974
 
                INC_COUNTER64(pAd->WlanCounters.MulticastTransmittedFrameCount);
1975
 
        }
1976
 
 
1977
 
        if (RTMP_GET_PACKET_RTS(pTxBlk->pPacket))
1978
 
                TX_BLK_SET_FLAG(pTxBlk, fTX_bRtsRequired);
1979
 
        else
1980
 
                TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bRtsRequired);
1981
 
 
1982
 
        bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
1983
 
 
1984
 
        if (pTxBlk->TxRate < pAd->CommonCfg.MinTxRate)
1985
 
                pTxBlk->TxRate = pAd->CommonCfg.MinTxRate;
1986
 
 
1987
 
        STAFindCipherAlgorithm(pAd, pTxBlk);
1988
 
        STABuildCommon802_11Header(pAd, pTxBlk);
1989
 
 
1990
 
        /* skip 802.3 header */
1991
 
        pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
1992
 
        pTxBlk->SrcBufLen -= LENGTH_802_3;
1993
 
 
1994
 
        /* skip vlan tag */
1995
 
        if (bVLANPkt) {
1996
 
                pTxBlk->pSrcBufData += LENGTH_802_1Q;
1997
 
                pTxBlk->SrcBufLen -= LENGTH_802_1Q;
1998
 
        }
1999
 
 
2000
 
        pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
2001
 
        pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr;
2002
 
 
2003
 
        /* skip common header */
2004
 
        pHeaderBufPtr += pTxBlk->MpduHeaderLen;
2005
 
 
2006
 
        if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) {
2007
 
                /* */
2008
 
                /* build QOS Control bytes */
2009
 
                /* */
2010
 
                *(pHeaderBufPtr) =
2011
 
                    ((pTxBlk->UserPriority & 0x0F) | (pAd->CommonCfg.
2012
 
                                                      AckPolicy[pTxBlk->
2013
 
                                                                QueIdx] << 5));
2014
 
                *(pHeaderBufPtr + 1) = 0;
2015
 
                pHeaderBufPtr += 2;
2016
 
                pTxBlk->MpduHeaderLen += 2;
2017
 
        }
2018
 
        /* The remaining content of MPDU header should locate at 4-octets alignment */
2019
 
        pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
2020
 
        pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
2021
 
        pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);
2022
 
 
2023
 
        {
2024
 
 
2025
 
                /* */
2026
 
                /* Insert LLC-SNAP encapsulation - 8 octets */
2027
 
                /* */
2028
 
                /* */
2029
 
                /* if original Ethernet frame contains no LLC/SNAP, */
2030
 
                /* then an extra LLC/SNAP encap is required */
2031
 
                /* */
2032
 
                EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader,
2033
 
                                                   pTxBlk->pExtraLlcSnapEncap);
2034
 
                if (pTxBlk->pExtraLlcSnapEncap) {
2035
 
                        u8 vlan_size;
2036
 
 
2037
 
                        NdisMoveMemory(pHeaderBufPtr,
2038
 
                                       pTxBlk->pExtraLlcSnapEncap, 6);
2039
 
                        pHeaderBufPtr += 6;
2040
 
                        /* skip vlan tag */
2041
 
                        vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0;
2042
 
                        /* get 2 octets (TypeofLen) */
2043
 
                        NdisMoveMemory(pHeaderBufPtr,
2044
 
                                       pTxBlk->pSrcBufHeader + 12 + vlan_size,
2045
 
                                       2);
2046
 
                        pHeaderBufPtr += 2;
2047
 
                        pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
2048
 
                }
2049
 
 
2050
 
        }
2051
 
 
2052
 
        /* */
2053
 
        /* prepare for TXWI */
2054
 
        /* use Wcid as Key Index */
2055
 
        /* */
2056
 
 
2057
 
        RTMPWriteTxWI_Data(pAd, (struct rt_txwi *) (&pTxBlk->HeaderBuf[TXINFO_SIZE]),
2058
 
                           pTxBlk);
2059
 
 
2060
 
        /*FreeNumber = GET_TXRING_FREENO(pAd, QueIdx); */
2061
 
 
2062
 
        HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
2063
 
 
2064
 
        pAd->RalinkCounters.KickTxCount++;
2065
 
        pAd->RalinkCounters.OneSecTxDoneCount++;
2066
 
 
2067
 
        /* */
2068
 
        /* Kick out Tx */
2069
 
        /* */
2070
 
        if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
2071
 
                HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
2072
 
}
2073
 
 
2074
 
void STA_ARalink_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
2075
 
{
2076
 
        u8 *pHeaderBufPtr;
2077
 
        u16 FreeNumber;
2078
 
        u16 totalMPDUSize = 0;
2079
 
        u16 FirstTx, LastTxIdx;
2080
 
        int frameNum = 0;
2081
 
        BOOLEAN bVLANPkt;
2082
 
        struct rt_queue_entry *pQEntry;
2083
 
 
2084
 
        ASSERT(pTxBlk);
2085
 
 
2086
 
        ASSERT((pTxBlk->TxPacketList.Number == 2));
2087
 
 
2088
 
        FirstTx = LastTxIdx = 0;        /* Is it ok init they as 0? */
2089
 
        while (pTxBlk->TxPacketList.Head) {
2090
 
                pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
2091
 
                pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
2092
 
 
2093
 
                if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) {
2094
 
                        RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket,
2095
 
                                            NDIS_STATUS_FAILURE);
2096
 
                        continue;
2097
 
                }
2098
 
 
2099
 
                bVLANPkt =
2100
 
                    (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
2101
 
 
2102
 
                /* skip 802.3 header */
2103
 
                pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
2104
 
                pTxBlk->SrcBufLen -= LENGTH_802_3;
2105
 
 
2106
 
                /* skip vlan tag */
2107
 
                if (bVLANPkt) {
2108
 
                        pTxBlk->pSrcBufData += LENGTH_802_1Q;
2109
 
                        pTxBlk->SrcBufLen -= LENGTH_802_1Q;
2110
 
                }
2111
 
 
2112
 
                if (frameNum == 0) {    /* For first frame, we need to create the 802.11 header + padding(optional) + RA-AGG-LEN + SNAP Header */
2113
 
 
2114
 
                        pHeaderBufPtr =
2115
 
                            STA_Build_ARalink_Frame_Header(pAd, pTxBlk);
2116
 
 
2117
 
                        /* It's ok write the TxWI here, because the TxWI->MPDUtotalByteCount */
2118
 
                        /* will be updated after final frame was handled. */
2119
 
                        RTMPWriteTxWI_Data(pAd,
2120
 
                                           (struct rt_txwi *) (&pTxBlk->
2121
 
                                                          HeaderBuf
2122
 
                                                          [TXINFO_SIZE]),
2123
 
                                           pTxBlk);
2124
 
 
2125
 
                        /* */
2126
 
                        /* Insert LLC-SNAP encapsulation - 8 octets */
2127
 
                        /* */
2128
 
                        EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->
2129
 
                                                            pSrcBufData - 2,
2130
 
                                                            pTxBlk->
2131
 
                                                            pExtraLlcSnapEncap);
2132
 
 
2133
 
                        if (pTxBlk->pExtraLlcSnapEncap) {
2134
 
                                NdisMoveMemory(pHeaderBufPtr,
2135
 
                                               pTxBlk->pExtraLlcSnapEncap, 6);
2136
 
                                pHeaderBufPtr += 6;
2137
 
                                /* get 2 octets (TypeofLen) */
2138
 
                                NdisMoveMemory(pHeaderBufPtr,
2139
 
                                               pTxBlk->pSrcBufData - 2, 2);
2140
 
                                pHeaderBufPtr += 2;
2141
 
                                pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
2142
 
                        }
2143
 
                } else {        /* For second aggregated frame, we need create the 802.3 header to headerBuf, because PCI will copy it to SDPtr0. */
2144
 
 
2145
 
                        pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
2146
 
                        pTxBlk->MpduHeaderLen = 0;
2147
 
 
2148
 
                        /* A-Ralink sub-sequent frame header is the same as 802.3 header. */
2149
 
                        /*   DA(6)+SA(6)+FrameType(2) */
2150
 
                        NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader,
2151
 
                                       12);
2152
 
                        pHeaderBufPtr += 12;
2153
 
                        /* get 2 octets (TypeofLen) */
2154
 
                        NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData - 2,
2155
 
                                       2);
2156
 
                        pHeaderBufPtr += 2;
2157
 
                        pTxBlk->MpduHeaderLen = LENGTH_ARALINK_SUBFRAMEHEAD;
2158
 
                }
2159
 
 
2160
 
                totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
2161
 
 
2162
 
                /*FreeNumber = GET_TXRING_FREENO(pAd, QueIdx); */
2163
 
                if (frameNum == 0)
2164
 
                        FirstTx =
2165
 
                            HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum,
2166
 
                                                     &FreeNumber);
2167
 
                else
2168
 
                        LastTxIdx =
2169
 
                            HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum,
2170
 
                                                     &FreeNumber);
2171
 
 
2172
 
                frameNum++;
2173
 
 
2174
 
                pAd->RalinkCounters.OneSecTxAggregationCount++;
2175
 
                pAd->RalinkCounters.KickTxCount++;
2176
 
                pAd->RalinkCounters.OneSecTxDoneCount++;
2177
 
 
2178
 
        }
2179
 
 
2180
 
        HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
2181
 
        HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
2182
 
 
2183
 
        /* */
2184
 
        /* Kick out Tx */
2185
 
        /* */
2186
 
        if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
2187
 
                HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
2188
 
 
2189
 
}
2190
 
 
2191
 
void STA_Fragment_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
2192
 
{
2193
 
        struct rt_header_802_11 *pHeader_802_11;
2194
 
        u8 *pHeaderBufPtr;
2195
 
        u16 FreeNumber;
2196
 
        u8 fragNum = 0;
2197
 
        struct rt_packet_info PacketInfo;
2198
 
        u16 EncryptionOverhead = 0;
2199
 
        u32 FreeMpduSize, SrcRemainingBytes;
2200
 
        u16 AckDuration;
2201
 
        u32 NextMpduSize;
2202
 
        BOOLEAN bVLANPkt;
2203
 
        struct rt_queue_entry *pQEntry;
2204
 
        HTTRANSMIT_SETTING *pTransmit;
2205
 
 
2206
 
        ASSERT(pTxBlk);
2207
 
 
2208
 
        pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
2209
 
        pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
2210
 
        if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) {
2211
 
                RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
2212
 
                return;
2213
 
        }
2214
 
 
2215
 
        ASSERT(TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag));
2216
 
        bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
2217
 
 
2218
 
        STAFindCipherAlgorithm(pAd, pTxBlk);
2219
 
        STABuildCommon802_11Header(pAd, pTxBlk);
2220
 
 
2221
 
        if (pTxBlk->CipherAlg == CIPHER_TKIP) {
2222
 
                pTxBlk->pPacket =
2223
 
                    duplicate_pkt_with_TKIP_MIC(pAd, pTxBlk->pPacket);
2224
 
                if (pTxBlk->pPacket == NULL)
2225
 
                        return;
2226
 
                RTMP_QueryPacketInfo(pTxBlk->pPacket, &PacketInfo,
2227
 
                                     &pTxBlk->pSrcBufHeader,
2228
 
                                     &pTxBlk->SrcBufLen);
2229
 
        }
2230
 
        /* skip 802.3 header */
2231
 
        pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
2232
 
        pTxBlk->SrcBufLen -= LENGTH_802_3;
2233
 
 
2234
 
        /* skip vlan tag */
2235
 
        if (bVLANPkt) {
2236
 
                pTxBlk->pSrcBufData += LENGTH_802_1Q;
2237
 
                pTxBlk->SrcBufLen -= LENGTH_802_1Q;
2238
 
        }
2239
 
 
2240
 
        pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
2241
 
        pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr;
2242
 
 
2243
 
        /* skip common header */
2244
 
        pHeaderBufPtr += pTxBlk->MpduHeaderLen;
2245
 
 
2246
 
        if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) {
2247
 
                /* */
2248
 
                /* build QOS Control bytes */
2249
 
                /* */
2250
 
                *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
2251
 
 
2252
 
                *(pHeaderBufPtr + 1) = 0;
2253
 
                pHeaderBufPtr += 2;
2254
 
                pTxBlk->MpduHeaderLen += 2;
2255
 
        }
2256
 
        /* */
2257
 
        /* padding at front of LLC header */
2258
 
        /* LLC header should locate at 4-octets aligment */
2259
 
        /* */
2260
 
        pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
2261
 
        pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
2262
 
        pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);
2263
 
 
2264
 
        /* */
2265
 
        /* Insert LLC-SNAP encapsulation - 8 octets */
2266
 
        /* */
2267
 
        /* */
2268
 
        /* if original Ethernet frame contains no LLC/SNAP, */
2269
 
        /* then an extra LLC/SNAP encap is required */
2270
 
        /* */
2271
 
        EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader,
2272
 
                                           pTxBlk->pExtraLlcSnapEncap);
2273
 
        if (pTxBlk->pExtraLlcSnapEncap) {
2274
 
                u8 vlan_size;
2275
 
 
2276
 
                NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
2277
 
                pHeaderBufPtr += 6;
2278
 
                /* skip vlan tag */
2279
 
                vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0;
2280
 
                /* get 2 octets (TypeofLen) */
2281
 
                NdisMoveMemory(pHeaderBufPtr,
2282
 
                               pTxBlk->pSrcBufHeader + 12 + vlan_size, 2);
2283
 
                pHeaderBufPtr += 2;
2284
 
                pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
2285
 
        }
2286
 
 
2287
 
        /* If TKIP is used and fragmentation is required. Driver has to */
2288
 
        /*      append TKIP MIC at tail of the scatter buffer */
2289
 
        /*      MAC ASIC will only perform IV/EIV/ICV insertion but no TKIP MIC */
2290
 
        if (pTxBlk->CipherAlg == CIPHER_TKIP) {
2291
 
                RTMPCalculateMICValue(pAd, pTxBlk->pPacket,
2292
 
                                      pTxBlk->pExtraLlcSnapEncap, pTxBlk->pKey,
2293
 
                                      0);
2294
 
 
2295
 
                /* NOTE: DON'T refer the skb->len directly after following copy. Because the length is not adjusted */
2296
 
                /*                      to correct length, refer to pTxBlk->SrcBufLen for the packet length in following progress. */
2297
 
                NdisMoveMemory(pTxBlk->pSrcBufData + pTxBlk->SrcBufLen,
2298
 
                               &pAd->PrivateInfo.Tx.MIC[0], 8);
2299
 
                /*skb_put((RTPKT_TO_OSPKT(pTxBlk->pPacket))->tail, 8); */
2300
 
                pTxBlk->SrcBufLen += 8;
2301
 
                pTxBlk->TotalFrameLen += 8;
2302
 
                pTxBlk->CipherAlg = CIPHER_TKIP_NO_MIC;
2303
 
        }
2304
 
        /* */
2305
 
        /* calculate the overhead bytes that encryption algorithm may add. This */
2306
 
        /* affects the calculate of "duration" field */
2307
 
        /* */
2308
 
        if ((pTxBlk->CipherAlg == CIPHER_WEP64)
2309
 
            || (pTxBlk->CipherAlg == CIPHER_WEP128))
2310
 
                EncryptionOverhead = 8; /*WEP: IV[4] + ICV[4]; */
2311
 
        else if (pTxBlk->CipherAlg == CIPHER_TKIP_NO_MIC)
2312
 
                EncryptionOverhead = 12;        /*TKIP: IV[4] + EIV[4] + ICV[4], MIC will be added to TotalPacketLength */
2313
 
        else if (pTxBlk->CipherAlg == CIPHER_TKIP)
2314
 
                EncryptionOverhead = 20;        /*TKIP: IV[4] + EIV[4] + ICV[4] + MIC[8] */
2315
 
        else if (pTxBlk->CipherAlg == CIPHER_AES)
2316
 
                EncryptionOverhead = 16;        /* AES: IV[4] + EIV[4] + MIC[8] */
2317
 
        else
2318
 
                EncryptionOverhead = 0;
2319
 
 
2320
 
        pTransmit = pTxBlk->pTransmit;
2321
 
        /* Decide the TX rate */
2322
 
        if (pTransmit->field.MODE == MODE_CCK)
2323
 
                pTxBlk->TxRate = pTransmit->field.MCS;
2324
 
        else if (pTransmit->field.MODE == MODE_OFDM)
2325
 
                pTxBlk->TxRate = pTransmit->field.MCS + RATE_FIRST_OFDM_RATE;
2326
 
        else
2327
 
                pTxBlk->TxRate = RATE_6_5;
2328
 
 
2329
 
        /* decide how much time an ACK/CTS frame will consume in the air */
2330
 
        if (pTxBlk->TxRate <= RATE_LAST_OFDM_RATE)
2331
 
                AckDuration =
2332
 
                    RTMPCalcDuration(pAd,
2333
 
                                     pAd->CommonCfg.ExpectedACKRate[pTxBlk->
2334
 
                                                                    TxRate],
2335
 
                                     14);
2336
 
        else
2337
 
                AckDuration = RTMPCalcDuration(pAd, RATE_6_5, 14);
2338
 
 
2339
 
        /* Init the total payload length of this frame. */
2340
 
        SrcRemainingBytes = pTxBlk->SrcBufLen;
2341
 
 
2342
 
        pTxBlk->TotalFragNum = 0xff;
2343
 
 
2344
 
        do {
2345
 
 
2346
 
                FreeMpduSize = pAd->CommonCfg.FragmentThreshold - LENGTH_CRC;
2347
 
 
2348
 
                FreeMpduSize -= pTxBlk->MpduHeaderLen;
2349
 
 
2350
 
                if (SrcRemainingBytes <= FreeMpduSize) {        /* this is the last or only fragment */
2351
 
 
2352
 
                        pTxBlk->SrcBufLen = SrcRemainingBytes;
2353
 
 
2354
 
                        pHeader_802_11->FC.MoreFrag = 0;
2355
 
                        pHeader_802_11->Duration =
2356
 
                            pAd->CommonCfg.Dsifs + AckDuration;
2357
 
 
2358
 
                        /* Indicate the lower layer that this's the last fragment. */
2359
 
                        pTxBlk->TotalFragNum = fragNum;
2360
 
                } else {        /* more fragment is required */
2361
 
 
2362
 
                        pTxBlk->SrcBufLen = FreeMpduSize;
2363
 
 
2364
 
                        NextMpduSize =
2365
 
                            min(((u32)SrcRemainingBytes - pTxBlk->SrcBufLen),
2366
 
                                ((u32)pAd->CommonCfg.FragmentThreshold));
2367
 
                        pHeader_802_11->FC.MoreFrag = 1;
2368
 
                        pHeader_802_11->Duration =
2369
 
                            (3 * pAd->CommonCfg.Dsifs) + (2 * AckDuration) +
2370
 
                            RTMPCalcDuration(pAd, pTxBlk->TxRate,
2371
 
                                             NextMpduSize + EncryptionOverhead);
2372
 
                }
2373
 
 
2374
 
                if (fragNum == 0)
2375
 
                        pTxBlk->FrameGap = IFS_HTTXOP;
2376
 
                else
2377
 
                        pTxBlk->FrameGap = IFS_SIFS;
2378
 
 
2379
 
                RTMPWriteTxWI_Data(pAd,
2380
 
                                   (struct rt_txwi *) (&pTxBlk->
2381
 
                                                  HeaderBuf[TXINFO_SIZE]),
2382
 
                                   pTxBlk);
2383
 
 
2384
 
                HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, &FreeNumber);
2385
 
 
2386
 
                pAd->RalinkCounters.KickTxCount++;
2387
 
                pAd->RalinkCounters.OneSecTxDoneCount++;
2388
 
 
2389
 
                /* Update the frame number, remaining size of the NDIS packet payload. */
2390
 
 
2391
 
                /* space for 802.11 header. */
2392
 
                if (fragNum == 0 && pTxBlk->pExtraLlcSnapEncap)
2393
 
                        pTxBlk->MpduHeaderLen -= LENGTH_802_1_H;
2394
 
 
2395
 
                fragNum++;
2396
 
                SrcRemainingBytes -= pTxBlk->SrcBufLen;
2397
 
                pTxBlk->pSrcBufData += pTxBlk->SrcBufLen;
2398
 
 
2399
 
                pHeader_802_11->Frag++; /* increase Frag # */
2400
 
 
2401
 
        } while (SrcRemainingBytes > 0);
2402
 
 
2403
 
        /* */
2404
 
        /* Kick out Tx */
2405
 
        /* */
2406
 
        if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
2407
 
                HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
2408
 
}
2409
 
 
2410
 
#define RELEASE_FRAMES_OF_TXBLK(_pAd, _pTxBlk, _pQEntry, _Status)                                                                               \
2411
 
                while(_pTxBlk->TxPacketList.Head)                                                                                                               \
2412
 
                {                                                                                                                                                                               \
2413
 
                        _pQEntry = RemoveHeadQueue(&_pTxBlk->TxPacketList);                                                                     \
2414
 
                        RELEASE_NDIS_PACKET(_pAd, QUEUE_ENTRY_TO_PACKET(_pQEntry), _Status);    \
2415
 
                }
2416
 
 
2417
 
/*
2418
 
        ========================================================================
2419
 
 
2420
 
        Routine Description:
2421
 
                Copy frame from waiting queue into relative ring buffer and set
2422
 
        appropriate ASIC register to kick hardware encryption before really
2423
 
        sent out to air.
2424
 
 
2425
 
        Arguments:
2426
 
                pAd     Pointer to our adapter
2427
 
                void *  Pointer to outgoing Ndis frame
2428
 
                NumberOfFrag    Number of fragment required
2429
 
 
2430
 
        Return Value:
2431
 
                None
2432
 
 
2433
 
        IRQL = DISPATCH_LEVEL
2434
 
 
2435
 
        Note:
2436
 
 
2437
 
        ========================================================================
2438
 
*/
2439
 
int STAHardTransmit(struct rt_rtmp_adapter *pAd,
2440
 
                            struct rt_tx_blk *pTxBlk, u8 QueIdx)
2441
 
{
2442
 
        char *pPacket;
2443
 
        struct rt_queue_entry *pQEntry;
2444
 
 
2445
 
        /* --------------------------------------------- */
2446
 
        /* STEP 0. DO SANITY CHECK AND SOME EARLY PREPARATION. */
2447
 
        /* --------------------------------------------- */
2448
 
        /* */
2449
 
        ASSERT(pTxBlk->TxPacketList.Number);
2450
 
        if (pTxBlk->TxPacketList.Head == NULL) {
2451
 
                DBGPRINT(RT_DEBUG_ERROR,
2452
 
                         ("pTxBlk->TotalFrameNum == %ld!\n",
2453
 
                          pTxBlk->TxPacketList.Number));
2454
 
                return NDIS_STATUS_FAILURE;
2455
 
        }
2456
 
 
2457
 
        pPacket = QUEUE_ENTRY_TO_PACKET(pTxBlk->TxPacketList.Head);
2458
 
 
2459
 
        /* ------------------------------------------------------------------ */
2460
 
        /* STEP 1. WAKE UP PHY */
2461
 
        /*              outgoing frame always wakeup PHY to prevent frame lost and */
2462
 
        /*              turn off PSM bit to improve performance */
2463
 
        /* ------------------------------------------------------------------ */
2464
 
        /* not to change PSM bit, just send this frame out? */
2465
 
        if ((pAd->StaCfg.Psm == PWR_SAVE)
2466
 
            && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
2467
 
                DBGPRINT_RAW(RT_DEBUG_INFO, ("AsicForceWakeup At HardTx\n"));
2468
 
#ifdef RTMP_MAC_PCI
2469
 
                AsicForceWakeup(pAd, TRUE);
2470
 
#endif /* RTMP_MAC_PCI // */
2471
 
#ifdef RTMP_MAC_USB
2472
 
                RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_FORCE_WAKE_UP, NULL, 0);
2473
 
#endif /* RTMP_MAC_USB // */
2474
 
        }
2475
 
        /* It should not change PSM bit, when APSD turn on. */
2476
 
        if ((!
2477
 
             (pAd->CommonCfg.bAPSDCapable
2478
 
              && pAd->CommonCfg.APEdcaParm.bAPSDCapable)
2479
 
             && (pAd->CommonCfg.bAPSDForcePowerSave == FALSE))
2480
 
            || (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket))
2481
 
            || (RTMP_GET_PACKET_WAI(pTxBlk->pPacket))) {
2482
 
                if ((pAd->StaCfg.Psm == PWR_SAVE) &&
2483
 
                    (pAd->StaCfg.WindowsPowerMode ==
2484
 
                     Ndis802_11PowerModeFast_PSP))
2485
 
                        RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE);
2486
 
        }
2487
 
 
2488
 
        switch (pTxBlk->TxFrameType) {
2489
 
        case TX_AMPDU_FRAME:
2490
 
                STA_AMPDU_Frame_Tx(pAd, pTxBlk);
2491
 
                break;
2492
 
        case TX_AMSDU_FRAME:
2493
 
                STA_AMSDU_Frame_Tx(pAd, pTxBlk);
2494
 
                break;
2495
 
        case TX_LEGACY_FRAME:
2496
 
                STA_Legacy_Frame_Tx(pAd, pTxBlk);
2497
 
                break;
2498
 
        case TX_MCAST_FRAME:
2499
 
                STA_Legacy_Frame_Tx(pAd, pTxBlk);
2500
 
                break;
2501
 
        case TX_RALINK_FRAME:
2502
 
                STA_ARalink_Frame_Tx(pAd, pTxBlk);
2503
 
                break;
2504
 
        case TX_FRAG_FRAME:
2505
 
                STA_Fragment_Frame_Tx(pAd, pTxBlk);
2506
 
                break;
2507
 
        default:
2508
 
                {
2509
 
                        /* It should not happened! */
2510
 
                        DBGPRINT(RT_DEBUG_ERROR,
2511
 
                                 ("Send a packet was not classified! It should not happen!\n"));
2512
 
                        while (pTxBlk->TxPacketList.Number) {
2513
 
                                pQEntry =
2514
 
                                    RemoveHeadQueue(&pTxBlk->TxPacketList);
2515
 
                                pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
2516
 
                                if (pPacket)
2517
 
                                        RELEASE_NDIS_PACKET(pAd, pPacket,
2518
 
                                                            NDIS_STATUS_FAILURE);
2519
 
                        }
2520
 
                }
2521
 
                break;
2522
 
        }
2523
 
 
2524
 
        return (NDIS_STATUS_SUCCESS);
2525
 
 
2526
 
}
2527
 
 
2528
 
unsigned long HashBytesPolynomial(u8 * value, unsigned int len)
2529
 
{
2530
 
        unsigned char *word = value;
2531
 
        unsigned int ret = 0;
2532
 
        unsigned int i;
2533
 
 
2534
 
        for (i = 0; i < len; i++) {
2535
 
                int mod = i % 32;
2536
 
                ret ^= (unsigned int)(word[i]) << mod;
2537
 
                ret ^= (unsigned int)(word[i]) >> (32 - mod);
2538
 
        }
2539
 
        return ret;
2540
 
}
2541
 
 
2542
 
void Sta_Announce_or_Forward_802_3_Packet(struct rt_rtmp_adapter *pAd,
2543
 
                                          void *pPacket,
2544
 
                                          u8 FromWhichBSSID)
2545
 
{
2546
 
        if (TRUE) {
2547
 
                announce_802_3_packet(pAd, pPacket);
2548
 
        } else {
2549
 
                /* release packet */
2550
 
                RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
2551
 
        }
2552
 
}