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

« back to all changes in this revision

Viewing changes to drivers/staging/rt2860/common/cmm_data_pci.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
 
 
28
 
/*
29
 
   All functions in this file must be PCI-depended, or you should out your function
30
 
        in other files.
31
 
 
32
 
*/
33
 
#include        "../rt_config.h"
34
 
 
35
 
u16 RtmpPCI_WriteTxResource(struct rt_rtmp_adapter *pAd,
36
 
                               struct rt_tx_blk *pTxBlk,
37
 
                               IN BOOLEAN bIsLast, u16 * FreeNumber)
38
 
{
39
 
 
40
 
        u8 *pDMAHeaderBufVA;
41
 
        u16 TxIdx, RetTxIdx;
42
 
        struct rt_txd * pTxD;
43
 
        u32 BufBasePaLow;
44
 
        struct rt_rtmp_tx_ring *pTxRing;
45
 
        u16 hwHeaderLen;
46
 
 
47
 
        /* */
48
 
        /* get Tx Ring Resource */
49
 
        /* */
50
 
        pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
51
 
        TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
52
 
        pDMAHeaderBufVA = (u8 *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
53
 
        BufBasePaLow =
54
 
            RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
55
 
 
56
 
        /* copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */
57
 
        if (pTxBlk->TxFrameType == TX_AMSDU_FRAME) {
58
 
                /*hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD; */
59
 
                hwHeaderLen =
60
 
                    pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD +
61
 
                    pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
62
 
        } else {
63
 
                /*hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
64
 
                hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
65
 
        }
66
 
        NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf,
67
 
                       TXINFO_SIZE + TXWI_SIZE + hwHeaderLen);
68
 
 
69
 
        pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
70
 
        pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
71
 
 
72
 
        /* */
73
 
        /* build Tx Descriptor */
74
 
        /* */
75
 
 
76
 
        pTxD = (struct rt_txd *) pTxRing->Cell[TxIdx].AllocVa;
77
 
        NdisZeroMemory(pTxD, TXD_SIZE);
78
 
 
79
 
        pTxD->SDPtr0 = BufBasePaLow;
80
 
        pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen;   /* include padding */
81
 
        pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
82
 
        pTxD->SDLen1 = pTxBlk->SrcBufLen;
83
 
        pTxD->LastSec0 = 0;
84
 
        pTxD->LastSec1 = (bIsLast) ? 1 : 0;
85
 
 
86
 
        RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
87
 
 
88
 
        RetTxIdx = TxIdx;
89
 
        /* */
90
 
        /* Update Tx index */
91
 
        /* */
92
 
        INC_RING_INDEX(TxIdx, TX_RING_SIZE);
93
 
        pTxRing->TxCpuIdx = TxIdx;
94
 
 
95
 
        *FreeNumber -= 1;
96
 
 
97
 
        return RetTxIdx;
98
 
}
99
 
 
100
 
u16 RtmpPCI_WriteSingleTxResource(struct rt_rtmp_adapter *pAd,
101
 
                                     struct rt_tx_blk *pTxBlk,
102
 
                                     IN BOOLEAN bIsLast,
103
 
                                     u16 * FreeNumber)
104
 
{
105
 
 
106
 
        u8 *pDMAHeaderBufVA;
107
 
        u16 TxIdx, RetTxIdx;
108
 
        struct rt_txd * pTxD;
109
 
        u32 BufBasePaLow;
110
 
        struct rt_rtmp_tx_ring *pTxRing;
111
 
        u16 hwHeaderLen;
112
 
 
113
 
        /* */
114
 
        /* get Tx Ring Resource */
115
 
        /* */
116
 
        pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
117
 
        TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
118
 
        pDMAHeaderBufVA = (u8 *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
119
 
        BufBasePaLow =
120
 
            RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
121
 
 
122
 
        /* copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */
123
 
        /*hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
124
 
        hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
125
 
 
126
 
        NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf,
127
 
                       TXINFO_SIZE + TXWI_SIZE + hwHeaderLen);
128
 
 
129
 
        pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
130
 
        pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
131
 
 
132
 
        /* */
133
 
        /* build Tx Descriptor */
134
 
        /* */
135
 
        pTxD = (struct rt_txd *) pTxRing->Cell[TxIdx].AllocVa;
136
 
        NdisZeroMemory(pTxD, TXD_SIZE);
137
 
 
138
 
        pTxD->SDPtr0 = BufBasePaLow;
139
 
        pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen;   /* include padding */
140
 
        pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
141
 
        pTxD->SDLen1 = pTxBlk->SrcBufLen;
142
 
        pTxD->LastSec0 = 0;
143
 
        pTxD->LastSec1 = (bIsLast) ? 1 : 0;
144
 
 
145
 
        RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
146
 
 
147
 
        RetTxIdx = TxIdx;
148
 
        /* */
149
 
        /* Update Tx index */
150
 
        /* */
151
 
        INC_RING_INDEX(TxIdx, TX_RING_SIZE);
152
 
        pTxRing->TxCpuIdx = TxIdx;
153
 
 
154
 
        *FreeNumber -= 1;
155
 
 
156
 
        return RetTxIdx;
157
 
}
158
 
 
159
 
u16 RtmpPCI_WriteMultiTxResource(struct rt_rtmp_adapter *pAd,
160
 
                                    struct rt_tx_blk *pTxBlk,
161
 
                                    u8 frameNum, u16 * FreeNumber)
162
 
{
163
 
        BOOLEAN bIsLast;
164
 
        u8 *pDMAHeaderBufVA;
165
 
        u16 TxIdx, RetTxIdx;
166
 
        struct rt_txd * pTxD;
167
 
        u32 BufBasePaLow;
168
 
        struct rt_rtmp_tx_ring *pTxRing;
169
 
        u16 hwHdrLen;
170
 
        u32 firstDMALen;
171
 
 
172
 
        bIsLast = ((frameNum == (pTxBlk->TotalFrameNum - 1)) ? 1 : 0);
173
 
 
174
 
        /* */
175
 
        /* get Tx Ring Resource */
176
 
        /* */
177
 
        pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
178
 
        TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
179
 
        pDMAHeaderBufVA = (u8 *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
180
 
        BufBasePaLow =
181
 
            RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
182
 
 
183
 
        if (frameNum == 0) {
184
 
                /* copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */
185
 
                if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
186
 
                        /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD; */
187
 
                        hwHdrLen =
188
 
                            pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD +
189
 
                            pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
190
 
                else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)
191
 
                        /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD; */
192
 
                        hwHdrLen =
193
 
                            pTxBlk->MpduHeaderLen -
194
 
                            LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen +
195
 
                            LENGTH_ARALINK_HEADER_FIELD;
196
 
                else
197
 
                        /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
198
 
                        hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
199
 
 
200
 
                firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;
201
 
        } else {
202
 
                firstDMALen = pTxBlk->MpduHeaderLen;
203
 
        }
204
 
 
205
 
        NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen);
206
 
 
207
 
        pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
208
 
        pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
209
 
 
210
 
        /* */
211
 
        /* build Tx Descriptor */
212
 
        /* */
213
 
        pTxD = (struct rt_txd *) pTxRing->Cell[TxIdx].AllocVa;
214
 
        NdisZeroMemory(pTxD, TXD_SIZE);
215
 
 
216
 
        pTxD->SDPtr0 = BufBasePaLow;
217
 
        pTxD->SDLen0 = firstDMALen;     /* include padding */
218
 
        pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
219
 
        pTxD->SDLen1 = pTxBlk->SrcBufLen;
220
 
        pTxD->LastSec0 = 0;
221
 
        pTxD->LastSec1 = (bIsLast) ? 1 : 0;
222
 
 
223
 
        RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
224
 
 
225
 
        RetTxIdx = TxIdx;
226
 
        /* */
227
 
        /* Update Tx index */
228
 
        /* */
229
 
        INC_RING_INDEX(TxIdx, TX_RING_SIZE);
230
 
        pTxRing->TxCpuIdx = TxIdx;
231
 
 
232
 
        *FreeNumber -= 1;
233
 
 
234
 
        return RetTxIdx;
235
 
 
236
 
}
237
 
 
238
 
void RtmpPCI_FinalWriteTxResource(struct rt_rtmp_adapter *pAd,
239
 
                                  struct rt_tx_blk *pTxBlk,
240
 
                                  u16 totalMPDUSize, u16 FirstTxIdx)
241
 
{
242
 
 
243
 
        struct rt_txwi * pTxWI;
244
 
        struct rt_rtmp_tx_ring *pTxRing;
245
 
 
246
 
        /* */
247
 
        /* get Tx Ring Resource */
248
 
        /* */
249
 
        pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
250
 
        pTxWI = (struct rt_txwi *) pTxRing->Cell[FirstTxIdx].DmaBuf.AllocVa;
251
 
        pTxWI->MPDUtotalByteCount = totalMPDUSize;
252
 
 
253
 
}
254
 
 
255
 
void RtmpPCIDataLastTxIdx(struct rt_rtmp_adapter *pAd,
256
 
                          u8 QueIdx, u16 LastTxIdx)
257
 
{
258
 
        struct rt_txd * pTxD;
259
 
        struct rt_rtmp_tx_ring *pTxRing;
260
 
 
261
 
        /* */
262
 
        /* get Tx Ring Resource */
263
 
        /* */
264
 
        pTxRing = &pAd->TxRing[QueIdx];
265
 
 
266
 
        /* */
267
 
        /* build Tx Descriptor */
268
 
        /* */
269
 
        pTxD = (struct rt_txd *) pTxRing->Cell[LastTxIdx].AllocVa;
270
 
 
271
 
        pTxD->LastSec1 = 1;
272
 
 
273
 
}
274
 
 
275
 
u16 RtmpPCI_WriteFragTxResource(struct rt_rtmp_adapter *pAd,
276
 
                                   struct rt_tx_blk *pTxBlk,
277
 
                                   u8 fragNum, u16 * FreeNumber)
278
 
{
279
 
        u8 *pDMAHeaderBufVA;
280
 
        u16 TxIdx, RetTxIdx;
281
 
        struct rt_txd * pTxD;
282
 
        u32 BufBasePaLow;
283
 
        struct rt_rtmp_tx_ring *pTxRing;
284
 
        u16 hwHeaderLen;
285
 
        u32 firstDMALen;
286
 
 
287
 
        /* */
288
 
        /* Get Tx Ring Resource */
289
 
        /* */
290
 
        pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
291
 
        TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
292
 
        pDMAHeaderBufVA = (u8 *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
293
 
        BufBasePaLow =
294
 
            RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
295
 
 
296
 
        /* */
297
 
        /* Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */
298
 
        /* */
299
 
        /*hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
300
 
        hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
301
 
 
302
 
        firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen;
303
 
        NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen);
304
 
 
305
 
        /* */
306
 
        /* Build Tx Descriptor */
307
 
        /* */
308
 
        pTxD = (struct rt_txd *) pTxRing->Cell[TxIdx].AllocVa;
309
 
        NdisZeroMemory(pTxD, TXD_SIZE);
310
 
 
311
 
        if (fragNum == pTxBlk->TotalFragNum) {
312
 
                pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
313
 
                pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
314
 
        }
315
 
 
316
 
        pTxD->SDPtr0 = BufBasePaLow;
317
 
        pTxD->SDLen0 = firstDMALen;     /* include padding */
318
 
        pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
319
 
        pTxD->SDLen1 = pTxBlk->SrcBufLen;
320
 
        pTxD->LastSec0 = 0;
321
 
        pTxD->LastSec1 = 1;
322
 
 
323
 
        RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
324
 
 
325
 
        RetTxIdx = TxIdx;
326
 
        pTxBlk->Priv += pTxBlk->SrcBufLen;
327
 
 
328
 
        /* */
329
 
        /* Update Tx index */
330
 
        /* */
331
 
        INC_RING_INDEX(TxIdx, TX_RING_SIZE);
332
 
        pTxRing->TxCpuIdx = TxIdx;
333
 
 
334
 
        *FreeNumber -= 1;
335
 
 
336
 
        return RetTxIdx;
337
 
 
338
 
}
339
 
 
340
 
/*
341
 
        Must be run in Interrupt context
342
 
        This function handle PCI specific TxDesc and cpu index update and kick the packet out.
343
 
 */
344
 
int RtmpPCIMgmtKickOut(struct rt_rtmp_adapter *pAd,
345
 
                       u8 QueIdx,
346
 
                       void *pPacket,
347
 
                       u8 *pSrcBufVA, u32 SrcBufLen)
348
 
{
349
 
        struct rt_txd * pTxD;
350
 
        unsigned long SwIdx = pAd->MgmtRing.TxCpuIdx;
351
 
 
352
 
        pTxD = (struct rt_txd *) pAd->MgmtRing.Cell[SwIdx].AllocVa;
353
 
 
354
 
        pAd->MgmtRing.Cell[SwIdx].pNdisPacket = pPacket;
355
 
        pAd->MgmtRing.Cell[SwIdx].pNextNdisPacket = NULL;
356
 
 
357
 
        RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_MGMT);
358
 
        pTxD->LastSec0 = 1;
359
 
        pTxD->LastSec1 = 1;
360
 
        pTxD->DMADONE = 0;
361
 
        pTxD->SDLen1 = 0;
362
 
        pTxD->SDPtr0 =
363
 
            PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
364
 
        pTxD->SDLen0 = SrcBufLen;
365
 
 
366
 
/*================================================================== */
367
 
/*      DBGPRINT_RAW(RT_DEBUG_TRACE, ("MLMEHardTransmit\n"));
368
 
        for (i = 0; i < (TXWI_SIZE+24); i++)
369
 
        {
370
 
 
371
 
                DBGPRINT_RAW(RT_DEBUG_TRACE, ("%x:", *(pSrcBufVA+i)));
372
 
                if ( i%4 == 3)
373
 
                        DBGPRINT_RAW(RT_DEBUG_TRACE, (" :: "));
374
 
                if ( i%16 == 15)
375
 
                        DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n      "));
376
 
        }
377
 
        DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n      "));*/
378
 
/*======================================================================= */
379
 
 
380
 
        pAd->RalinkCounters.KickTxCount++;
381
 
        pAd->RalinkCounters.OneSecTxDoneCount++;
382
 
 
383
 
        /* Increase TX_CTX_IDX, but write to register later. */
384
 
        INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
385
 
 
386
 
        RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx);
387
 
 
388
 
        return 0;
389
 
}
390
 
 
391
 
/*
392
 
        ========================================================================
393
 
 
394
 
        Routine Description:
395
 
                Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
396
 
 
397
 
        Arguments:
398
 
                pRxD            Pointer to the Rx descriptor
399
 
 
400
 
        Return Value:
401
 
                NDIS_STATUS_SUCCESS     No err
402
 
                NDIS_STATUS_FAILURE     Error
403
 
 
404
 
        Note:
405
 
 
406
 
        ========================================================================
407
 
*/
408
 
int RTMPCheckRxError(struct rt_rtmp_adapter *pAd,
409
 
                             struct rt_header_802_11 * pHeader,
410
 
                             struct rt_rxwi * pRxWI, IN PRT28XX_RXD_STRUC pRxD)
411
 
{
412
 
        struct rt_cipher_key *pWpaKey;
413
 
        int dBm;
414
 
 
415
 
        /* Phy errors & CRC errors */
416
 
        if ( /*(pRxD->PhyErr) || */ (pRxD->Crc)) {
417
 
                /* Check RSSI for Noise Hist statistic collection. */
418
 
                dBm = (int)(pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta;
419
 
                if (dBm <= -87)
420
 
                        pAd->StaCfg.RPIDensity[0] += 1;
421
 
                else if (dBm <= -82)
422
 
                        pAd->StaCfg.RPIDensity[1] += 1;
423
 
                else if (dBm <= -77)
424
 
                        pAd->StaCfg.RPIDensity[2] += 1;
425
 
                else if (dBm <= -72)
426
 
                        pAd->StaCfg.RPIDensity[3] += 1;
427
 
                else if (dBm <= -67)
428
 
                        pAd->StaCfg.RPIDensity[4] += 1;
429
 
                else if (dBm <= -62)
430
 
                        pAd->StaCfg.RPIDensity[5] += 1;
431
 
                else if (dBm <= -57)
432
 
                        pAd->StaCfg.RPIDensity[6] += 1;
433
 
                else if (dBm > -57)
434
 
                        pAd->StaCfg.RPIDensity[7] += 1;
435
 
 
436
 
                return (NDIS_STATUS_FAILURE);
437
 
        }
438
 
        /* Add Rx size to channel load counter, we should ignore error counts */
439
 
        pAd->StaCfg.CLBusyBytes += (pRxD->SDL0 + 14);
440
 
 
441
 
        /* Drop ToDs promiscuous frame, it is opened due to CCX 2 channel load statistics */
442
 
        if (pHeader != NULL) {
443
 
                if (pHeader->FC.ToDs) {
444
 
                        return (NDIS_STATUS_FAILURE);
445
 
                }
446
 
        }
447
 
        /* Drop not U2M frames, can't drop here because we will drop beacon in this case */
448
 
        /* I am kind of doubting the U2M bit operation */
449
 
        /* if (pRxD->U2M == 0) */
450
 
        /*      return(NDIS_STATUS_FAILURE); */
451
 
 
452
 
        /* drop decyption fail frame */
453
 
        if (pRxD->CipherErr) {
454
 
                if (pRxD->CipherErr == 2) {
455
 
                        DBGPRINT_RAW(RT_DEBUG_TRACE,
456
 
                                     ("pRxD ERROR: ICV ok but MICErr "));
457
 
                } else if (pRxD->CipherErr == 1) {
458
 
                        DBGPRINT_RAW(RT_DEBUG_TRACE, ("pRxD ERROR: ICV Err "));
459
 
                } else if (pRxD->CipherErr == 3)
460
 
                        DBGPRINT_RAW(RT_DEBUG_TRACE,
461
 
                                     ("pRxD ERROR: Key not valid "));
462
 
 
463
 
                if (((pRxD->CipherErr & 1) == 1)
464
 
                    && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
465
 
                        RTMPSendWirelessEvent(pAd, IW_ICV_ERROR_EVENT_FLAG,
466
 
                                              pAd->MacTab.Content[BSSID_WCID].
467
 
                                              Addr, BSS0, 0);
468
 
 
469
 
                DBGPRINT_RAW(RT_DEBUG_TRACE,
470
 
                             (" %d (len=%d, Mcast=%d, MyBss=%d, Wcid=%d, KeyId=%d)\n",
471
 
                              pRxD->CipherErr, pRxD->SDL0,
472
 
                              pRxD->Mcast | pRxD->Bcast, pRxD->MyBss,
473
 
                              pRxWI->WirelessCliID,
474
 
/*                      CipherName[pRxD->CipherAlg], */
475
 
                              pRxWI->KeyIndex));
476
 
 
477
 
                /* */
478
 
                /* MIC Error */
479
 
                /* */
480
 
                if (pRxD->CipherErr == 2) {
481
 
                        pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
482
 
                        if (pAd->StaCfg.WpaSupplicantUP)
483
 
                                WpaSendMicFailureToWpaSupplicant(pAd,
484
 
                                                                 (pWpaKey->
485
 
                                                                  Type ==
486
 
                                                                  PAIRWISEKEY) ?
487
 
                                                                 TRUE : FALSE);
488
 
                        else
489
 
                                RTMPReportMicError(pAd, pWpaKey);
490
 
 
491
 
                        if (((pRxD->CipherErr & 2) == 2)
492
 
                            && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
493
 
                                RTMPSendWirelessEvent(pAd,
494
 
                                                      IW_MIC_ERROR_EVENT_FLAG,
495
 
                                                      pAd->MacTab.
496
 
                                                      Content[BSSID_WCID].Addr,
497
 
                                                      BSS0, 0);
498
 
 
499
 
                        DBGPRINT_RAW(RT_DEBUG_ERROR, ("Rx MIC Value error\n"));
500
 
                }
501
 
 
502
 
                if (pHeader == NULL)
503
 
                        return (NDIS_STATUS_SUCCESS);
504
 
                /*if ((pRxD->CipherAlg == CIPHER_AES) &&
505
 
                   (pHeader->Sequence == pAd->FragFrame.Sequence))
506
 
                   {
507
 
                   //
508
 
                   // Acceptable since the First FragFrame no CipherErr problem.
509
 
                   //
510
 
                   return(NDIS_STATUS_SUCCESS);
511
 
                   } */
512
 
 
513
 
                return (NDIS_STATUS_FAILURE);
514
 
        }
515
 
 
516
 
        return (NDIS_STATUS_SUCCESS);
517
 
}
518
 
 
519
 
BOOLEAN RTMPFreeTXDUponTxDmaDone(struct rt_rtmp_adapter *pAd, u8 QueIdx)
520
 
{
521
 
        struct rt_rtmp_tx_ring *pTxRing;
522
 
        struct rt_txd * pTxD;
523
 
        void *pPacket;
524
 
        u8 FREE = 0;
525
 
        struct rt_txd TxD, *pOriTxD;
526
 
        /*unsigned long         IrqFlags; */
527
 
        BOOLEAN bReschedule = FALSE;
528
 
 
529
 
        ASSERT(QueIdx < NUM_OF_TX_RING);
530
 
        pTxRing = &pAd->TxRing[QueIdx];
531
 
 
532
 
        RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF,
533
 
                       &pTxRing->TxDmaIdx);
534
 
        while (pTxRing->TxSwFreeIdx != pTxRing->TxDmaIdx) {
535
 
/*              RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); */
536
 
 
537
 
                /* static rate also need NICUpdateFifoStaCounters() function. */
538
 
                /*if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) */
539
 
                NICUpdateFifoStaCounters(pAd);
540
 
 
541
 
                /* Note : If (pAd->ate.bQATxStart == TRUE), we will never reach here. */
542
 
                FREE++;
543
 
                pTxD =
544
 
                    (struct rt_txd *) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
545
 
                pOriTxD = pTxD;
546
 
                NdisMoveMemory(&TxD, pTxD, sizeof(struct rt_txd));
547
 
                pTxD = &TxD;
548
 
 
549
 
                pTxD->DMADONE = 0;
550
 
 
551
 
                {
552
 
                        pPacket =
553
 
                            pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket;
554
 
                        if (pPacket) {
555
 
                                PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1,
556
 
                                                 pTxD->SDLen1,
557
 
                                                 PCI_DMA_TODEVICE);
558
 
                                RELEASE_NDIS_PACKET(pAd, pPacket,
559
 
                                                    NDIS_STATUS_SUCCESS);
560
 
                        }
561
 
                        /*Always assign pNdisPacket as NULL after clear */
562
 
                        pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket = NULL;
563
 
 
564
 
                        pPacket =
565
 
                            pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket;
566
 
 
567
 
                        ASSERT(pPacket == NULL);
568
 
                        if (pPacket) {
569
 
                                PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1,
570
 
                                                 pTxD->SDLen1,
571
 
                                                 PCI_DMA_TODEVICE);
572
 
                                RELEASE_NDIS_PACKET(pAd, pPacket,
573
 
                                                    NDIS_STATUS_SUCCESS);
574
 
                        }
575
 
                        /*Always assign pNextNdisPacket as NULL after clear */
576
 
                        pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket =
577
 
                            NULL;
578
 
                }
579
 
 
580
 
                pAd->RalinkCounters.TransmittedByteCount +=
581
 
                    (pTxD->SDLen1 + pTxD->SDLen0);
582
 
                pAd->RalinkCounters.OneSecDmaDoneCount[QueIdx]++;
583
 
                INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE);
584
 
                /* get tx_tdx_idx again */
585
 
                RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF,
586
 
                               &pTxRing->TxDmaIdx);
587
 
                NdisMoveMemory(pOriTxD, pTxD, sizeof(struct rt_txd));
588
 
 
589
 
/*         RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); */
590
 
        }
591
 
 
592
 
        return bReschedule;
593
 
 
594
 
}
595
 
 
596
 
/*
597
 
        ========================================================================
598
 
 
599
 
        Routine Description:
600
 
                Process TX Rings DMA Done interrupt, running in DPC level
601
 
 
602
 
        Arguments:
603
 
                Adapter         Pointer to our adapter
604
 
 
605
 
        Return Value:
606
 
                None
607
 
 
608
 
        IRQL = DISPATCH_LEVEL
609
 
 
610
 
        ========================================================================
611
 
*/
612
 
BOOLEAN RTMPHandleTxRingDmaDoneInterrupt(struct rt_rtmp_adapter *pAd,
613
 
                                         INT_SOURCE_CSR_STRUC TxRingBitmap)
614
 
{
615
 
/*      u8                   Count = 0; */
616
 
        unsigned long IrqFlags;
617
 
        BOOLEAN bReschedule = FALSE;
618
 
 
619
 
        /* Make sure Tx ring resource won't be used by other threads */
620
 
        /*NdisAcquireSpinLock(&pAd->TxRingLock); */
621
 
 
622
 
        RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
623
 
 
624
 
        if (TxRingBitmap.field.Ac0DmaDone)
625
 
                bReschedule = RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BE);
626
 
 
627
 
        if (TxRingBitmap.field.Ac3DmaDone)
628
 
                bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VO);
629
 
 
630
 
        if (TxRingBitmap.field.Ac2DmaDone)
631
 
                bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VI);
632
 
 
633
 
        if (TxRingBitmap.field.Ac1DmaDone)
634
 
                bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BK);
635
 
 
636
 
        /* Make sure to release Tx ring resource */
637
 
        /*NdisReleaseSpinLock(&pAd->TxRingLock); */
638
 
        RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
639
 
 
640
 
        /* Dequeue outgoing frames from TxSwQueue[] and process it */
641
 
        RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
642
 
 
643
 
        return bReschedule;
644
 
}
645
 
 
646
 
/*
647
 
        ========================================================================
648
 
 
649
 
        Routine Description:
650
 
                Process MGMT ring DMA done interrupt, running in DPC level
651
 
 
652
 
        Arguments:
653
 
                pAd     Pointer to our adapter
654
 
 
655
 
        Return Value:
656
 
                None
657
 
 
658
 
        IRQL = DISPATCH_LEVEL
659
 
 
660
 
        Note:
661
 
 
662
 
        ========================================================================
663
 
*/
664
 
void RTMPHandleMgmtRingDmaDoneInterrupt(struct rt_rtmp_adapter *pAd)
665
 
{
666
 
        struct rt_txd * pTxD;
667
 
        void *pPacket;
668
 
/*      int              i; */
669
 
        u8 FREE = 0;
670
 
        struct rt_rtmp_mgmt_ring *pMgmtRing = &pAd->MgmtRing;
671
 
 
672
 
        NdisAcquireSpinLock(&pAd->MgmtRingLock);
673
 
 
674
 
        RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pMgmtRing->TxDmaIdx);
675
 
        while (pMgmtRing->TxSwFreeIdx != pMgmtRing->TxDmaIdx) {
676
 
                FREE++;
677
 
                pTxD =
678
 
                    (struct rt_txd *) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].
679
 
                                  AllocVa);
680
 
                pTxD->DMADONE = 0;
681
 
                pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket;
682
 
 
683
 
                if (pPacket) {
684
 
                        PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0,
685
 
                                         PCI_DMA_TODEVICE);
686
 
                        RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
687
 
                }
688
 
                pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket = NULL;
689
 
 
690
 
                pPacket =
691
 
                    pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket;
692
 
                if (pPacket) {
693
 
                        PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1,
694
 
                                         PCI_DMA_TODEVICE);
695
 
                        RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
696
 
                }
697
 
                pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket = NULL;
698
 
                INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE);
699
 
 
700
 
        }
701
 
        NdisReleaseSpinLock(&pAd->MgmtRingLock);
702
 
 
703
 
}
704
 
 
705
 
/*
706
 
        ========================================================================
707
 
 
708
 
        Routine Description:
709
 
        Arguments:
710
 
                Adapter         Pointer to our adapter. Dequeue all power safe delayed braodcast frames after beacon.
711
 
 
712
 
        IRQL = DISPATCH_LEVEL
713
 
 
714
 
        ========================================================================
715
 
*/
716
 
void RTMPHandleTBTTInterrupt(struct rt_rtmp_adapter *pAd)
717
 
{
718
 
        {
719
 
                if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
720
 
                }
721
 
        }
722
 
}
723
 
 
724
 
/*
725
 
        ========================================================================
726
 
 
727
 
        Routine Description:
728
 
        Arguments:
729
 
                pAd             Pointer to our adapter. Rewrite beacon content before next send-out.
730
 
 
731
 
        IRQL = DISPATCH_LEVEL
732
 
 
733
 
        ========================================================================
734
 
*/
735
 
void RTMPHandlePreTBTTInterrupt(struct rt_rtmp_adapter *pAd)
736
 
{
737
 
        {
738
 
                if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
739
 
                        DBGPRINT(RT_DEBUG_TRACE,
740
 
                                 ("RTMPHandlePreTBTTInterrupt...\n"));
741
 
                }
742
 
        }
743
 
 
744
 
}
745
 
 
746
 
void RTMPHandleRxCoherentInterrupt(struct rt_rtmp_adapter *pAd)
747
 
{
748
 
        WPDMA_GLO_CFG_STRUC GloCfg;
749
 
 
750
 
        if (pAd == NULL) {
751
 
                DBGPRINT(RT_DEBUG_TRACE, ("====> pAd is NULL, return.\n"));
752
 
                return;
753
 
        }
754
 
 
755
 
        DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPHandleRxCoherentInterrupt \n"));
756
 
 
757
 
        RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
758
 
 
759
 
        GloCfg.field.EnTXWriteBackDDONE = 0;
760
 
        GloCfg.field.EnableRxDMA = 0;
761
 
        GloCfg.field.EnableTxDMA = 0;
762
 
        RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
763
 
 
764
 
        RTMPRingCleanUp(pAd, QID_AC_BE);
765
 
        RTMPRingCleanUp(pAd, QID_AC_BK);
766
 
        RTMPRingCleanUp(pAd, QID_AC_VI);
767
 
        RTMPRingCleanUp(pAd, QID_AC_VO);
768
 
        RTMPRingCleanUp(pAd, QID_MGMT);
769
 
        RTMPRingCleanUp(pAd, QID_RX);
770
 
 
771
 
        RTMPEnableRxTx(pAd);
772
 
 
773
 
        DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPHandleRxCoherentInterrupt \n"));
774
 
}
775
 
 
776
 
void *GetPacketFromRxRing(struct rt_rtmp_adapter *pAd,
777
 
                                 OUT PRT28XX_RXD_STRUC pSaveRxD,
778
 
                                 OUT BOOLEAN * pbReschedule,
779
 
                                 IN u32 * pRxPending)
780
 
{
781
 
        struct rt_rxd * pRxD;
782
 
        void *pRxPacket = NULL;
783
 
        void *pNewPacket;
784
 
        void *AllocVa;
785
 
        dma_addr_t AllocPa;
786
 
        BOOLEAN bReschedule = FALSE;
787
 
        struct rt_rtmp_dmacb *pRxCell;
788
 
 
789
 
        RTMP_SEM_LOCK(&pAd->RxRingLock);
790
 
 
791
 
        if (*pRxPending == 0) {
792
 
                /* Get how may packets had been received */
793
 
                RTMP_IO_READ32(pAd, RX_DRX_IDX, &pAd->RxRing.RxDmaIdx);
794
 
 
795
 
                if (pAd->RxRing.RxSwReadIdx == pAd->RxRing.RxDmaIdx) {
796
 
                        /* no more rx packets */
797
 
                        bReschedule = FALSE;
798
 
                        goto done;
799
 
                }
800
 
                /* get rx pending count */
801
 
                if (pAd->RxRing.RxDmaIdx > pAd->RxRing.RxSwReadIdx)
802
 
                        *pRxPending =
803
 
                            pAd->RxRing.RxDmaIdx - pAd->RxRing.RxSwReadIdx;
804
 
                else
805
 
                        *pRxPending =
806
 
                            pAd->RxRing.RxDmaIdx + RX_RING_SIZE -
807
 
                            pAd->RxRing.RxSwReadIdx;
808
 
 
809
 
        }
810
 
 
811
 
        pRxCell = &pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx];
812
 
 
813
 
        /* Point to Rx indexed rx ring descriptor */
814
 
        pRxD = (struct rt_rxd *) pRxCell->AllocVa;
815
 
 
816
 
        if (pRxD->DDONE == 0) {
817
 
                *pRxPending = 0;
818
 
                /* DMAIndx had done but DDONE bit not ready */
819
 
                bReschedule = TRUE;
820
 
                goto done;
821
 
        }
822
 
 
823
 
        /* return rx descriptor */
824
 
        NdisMoveMemory(pSaveRxD, pRxD, RXD_SIZE);
825
 
 
826
 
        pNewPacket =
827
 
            RTMP_AllocateRxPacketBuffer(pAd, RX_BUFFER_AGGRESIZE, FALSE,
828
 
                                        &AllocVa, &AllocPa);
829
 
 
830
 
        if (pNewPacket) {
831
 
                /* unmap the rx buffer */
832
 
                PCI_UNMAP_SINGLE(pAd, pRxCell->DmaBuf.AllocPa,
833
 
                                 pRxCell->DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
834
 
                pRxPacket = pRxCell->pNdisPacket;
835
 
 
836
 
                pRxCell->DmaBuf.AllocSize = RX_BUFFER_AGGRESIZE;
837
 
                pRxCell->pNdisPacket = (void *)pNewPacket;
838
 
                pRxCell->DmaBuf.AllocVa = AllocVa;
839
 
                pRxCell->DmaBuf.AllocPa = AllocPa;
840
 
                /* update SDP0 to new buffer of rx packet */
841
 
                pRxD->SDP0 = AllocPa;
842
 
        } else {
843
 
                /*DBGPRINT(RT_DEBUG_TRACE,("No Rx Buffer\n")); */
844
 
                pRxPacket = NULL;
845
 
                bReschedule = TRUE;
846
 
        }
847
 
 
848
 
        pRxD->DDONE = 0;
849
 
 
850
 
        /* had handled one rx packet */
851
 
        *pRxPending = *pRxPending - 1;
852
 
 
853
 
        /* update rx descriptor and kick rx */
854
 
        INC_RING_INDEX(pAd->RxRing.RxSwReadIdx, RX_RING_SIZE);
855
 
 
856
 
        pAd->RxRing.RxCpuIdx =
857
 
            (pAd->RxRing.RxSwReadIdx ==
858
 
             0) ? (RX_RING_SIZE - 1) : (pAd->RxRing.RxSwReadIdx - 1);
859
 
        RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
860
 
 
861
 
done:
862
 
        RTMP_SEM_UNLOCK(&pAd->RxRingLock);
863
 
        *pbReschedule = bReschedule;
864
 
        return pRxPacket;
865
 
}
866
 
 
867
 
int MlmeHardTransmitTxRing(struct rt_rtmp_adapter *pAd,
868
 
                                   u8 QueIdx, void *pPacket)
869
 
{
870
 
        struct rt_packet_info PacketInfo;
871
 
        u8 *pSrcBufVA;
872
 
        u32 SrcBufLen;
873
 
        struct rt_txd * pTxD;
874
 
        struct rt_header_802_11 * pHeader_802_11;
875
 
        BOOLEAN bAckRequired, bInsertTimestamp;
876
 
        unsigned long SrcBufPA;
877
 
        /*u8                 TxBufIdx; */
878
 
        u8 MlmeRate;
879
 
        unsigned long SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
880
 
        struct rt_txwi * pFirstTxWI;
881
 
        /*unsigned long i; */
882
 
        /*HTTRANSMIT_SETTING    MlmeTransmit;   //Rate for this MGMT frame. */
883
 
        unsigned long FreeNum;
884
 
        struct rt_mac_table_entry *pMacEntry = NULL;
885
 
 
886
 
        RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
887
 
 
888
 
        if (pSrcBufVA == NULL) {
889
 
                /* The buffer shouldn't be NULL */
890
 
                return NDIS_STATUS_FAILURE;
891
 
        }
892
 
        /* Make sure MGMT ring resource won't be used by other threads */
893
 
        /*NdisAcquireSpinLock(&pAd->TxRingLock); */
894
 
 
895
 
        FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
896
 
 
897
 
        if (FreeNum == 0) {
898
 
                /*NdisReleaseSpinLock(&pAd->TxRingLock); */
899
 
                return NDIS_STATUS_FAILURE;
900
 
        }
901
 
 
902
 
        SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
903
 
 
904
 
        pTxD = (struct rt_txd *) pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa;
905
 
 
906
 
        if (pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket) {
907
 
                DBGPRINT(RT_DEBUG_OFF, ("MlmeHardTransmit Error\n"));
908
 
                /*NdisReleaseSpinLock(&pAd->TxRingLock); */
909
 
                return NDIS_STATUS_FAILURE;
910
 
        }
911
 
 
912
 
        {
913
 
                /* outgoing frame always wakeup PHY to prevent frame lost */
914
 
                /* if (pAd->StaCfg.Psm == PWR_SAVE) */
915
 
                if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
916
 
                        AsicForceWakeup(pAd, TRUE);
917
 
        }
918
 
        pFirstTxWI = (struct rt_txwi *) pSrcBufVA;
919
 
 
920
 
        pHeader_802_11 = (struct rt_header_802_11 *) (pSrcBufVA + TXWI_SIZE);
921
 
        if (pHeader_802_11->Addr1[0] & 0x01) {
922
 
                MlmeRate = pAd->CommonCfg.BasicMlmeRate;
923
 
        } else {
924
 
                MlmeRate = pAd->CommonCfg.MlmeRate;
925
 
        }
926
 
 
927
 
        if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
928
 
            (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL)) {
929
 
                pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
930
 
        }
931
 
        /* Verify Mlme rate for a / g bands. */
932
 
        if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6))     /* 11A band */
933
 
                MlmeRate = RATE_6;
934
 
 
935
 
        /* */
936
 
        /* Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE) */
937
 
        /* Snice it's been set to 0 while on MgtMacHeaderInit */
938
 
        /* By the way this will cause frame to be send on PWR_SAVE failed. */
939
 
        /* */
940
 
        /* */
941
 
        /* In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame */
942
 
        /* Data-Null packets also pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD */
943
 
        if (pHeader_802_11->FC.Type != BTYPE_DATA) {
944
 
                if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ)
945
 
                    || !(pAd->CommonCfg.bAPSDCapable
946
 
                         && pAd->CommonCfg.APEdcaParm.bAPSDCapable)) {
947
 
                        pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
948
 
                } else {
949
 
                        pHeader_802_11->FC.PwrMgmt =
950
 
                            pAd->CommonCfg.bAPSDForcePowerSave;
951
 
                }
952
 
        }
953
 
 
954
 
        bInsertTimestamp = FALSE;
955
 
        if (pHeader_802_11->FC.Type == BTYPE_CNTL)      /* must be PS-POLL */
956
 
        {
957
 
                bAckRequired = FALSE;
958
 
        } else                  /* BTYPE_MGMT or BTYPE_DATA(must be NULL frame) */
959
 
        {
960
 
                if (pHeader_802_11->Addr1[0] & 0x01)    /* MULTICAST, BROADCAST */
961
 
                {
962
 
                        bAckRequired = FALSE;
963
 
                        pHeader_802_11->Duration = 0;
964
 
                } else {
965
 
                        bAckRequired = TRUE;
966
 
                        pHeader_802_11->Duration =
967
 
                            RTMPCalcDuration(pAd, MlmeRate, 14);
968
 
                        if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP) {
969
 
                                bInsertTimestamp = TRUE;
970
 
                        }
971
 
                }
972
 
        }
973
 
        pHeader_802_11->Sequence = pAd->Sequence++;
974
 
        if (pAd->Sequence > 0xfff)
975
 
                pAd->Sequence = 0;
976
 
        /* Before radar detection done, mgmt frame can not be sent but probe req */
977
 
        /* Because we need to use probe req to trigger driver to send probe req in passive scan */
978
 
        if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
979
 
            && (pAd->CommonCfg.bIEEE80211H == 1)
980
 
            && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)) {
981
 
                DBGPRINT(RT_DEBUG_ERROR,
982
 
                         ("MlmeHardTransmit --> radar detect not in normal mode!\n"));
983
 
                /*NdisReleaseSpinLock(&pAd->TxRingLock); */
984
 
                return (NDIS_STATUS_FAILURE);
985
 
        }
986
 
        /* */
987
 
        /* fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET */
988
 
        /* should always has only one ohysical buffer, and the whole frame size equals */
989
 
        /* to the first scatter buffer size */
990
 
        /* */
991
 
 
992
 
        /* Initialize TX Descriptor */
993
 
        /* For inter-frame gap, the number is for this frame and next frame */
994
 
        /* For MLME rate, we will fix as 2Mb to match other vendor's implement */
995
 
/*      pAd->CommonCfg.MlmeTransmit.field.MODE = 1; */
996
 
 
997
 
/* management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not. */
998
 
        /* Only beacon use Nseq=TRUE. So here we use Nseq=FALSE. */
999
 
        if (pMacEntry == NULL) {
1000
 
                RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp,
1001
 
                              FALSE, bAckRequired, FALSE, 0, RESERVED_WCID,
1002
 
                              (SrcBufLen - TXWI_SIZE), PID_MGMT, 0,
1003
 
                              (u8)pAd->CommonCfg.MlmeTransmit.field.MCS,
1004
 
                              IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
1005
 
        } else {
1006
 
                RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
1007
 
                              bInsertTimestamp, FALSE, bAckRequired, FALSE,
1008
 
                              0, pMacEntry->Aid, (SrcBufLen - TXWI_SIZE),
1009
 
                              pMacEntry->MaxHTPhyMode.field.MCS, 0,
1010
 
                              (u8)pMacEntry->MaxHTPhyMode.field.MCS,
1011
 
                              IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
1012
 
        }
1013
 
 
1014
 
        pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket = pPacket;
1015
 
        pAd->TxRing[QueIdx].Cell[SwIdx].pNextNdisPacket = NULL;
1016
 
/*      pFirstTxWI->MPDUtotalByteCount = SrcBufLen - TXWI_SIZE; */
1017
 
        SrcBufPA =
1018
 
            PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
1019
 
 
1020
 
        RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_EDCA);
1021
 
        pTxD->LastSec0 = 1;
1022
 
        pTxD->LastSec1 = 1;
1023
 
        pTxD->SDLen0 = SrcBufLen;
1024
 
        pTxD->SDLen1 = 0;
1025
 
        pTxD->SDPtr0 = SrcBufPA;
1026
 
        pTxD->DMADONE = 0;
1027
 
 
1028
 
        pAd->RalinkCounters.KickTxCount++;
1029
 
        pAd->RalinkCounters.OneSecTxDoneCount++;
1030
 
 
1031
 
        /* Increase TX_CTX_IDX, but write to register later. */
1032
 
        INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE);
1033
 
 
1034
 
        RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx * 0x10,
1035
 
                        pAd->TxRing[QueIdx].TxCpuIdx);
1036
 
 
1037
 
        /* Make sure to release MGMT ring resource */
1038
 
/*      NdisReleaseSpinLock(&pAd->TxRingLock); */
1039
 
 
1040
 
        return NDIS_STATUS_SUCCESS;
1041
 
}
1042
 
 
1043
 
int MlmeDataHardTransmit(struct rt_rtmp_adapter *pAd,
1044
 
                                 u8 QueIdx, void *pPacket)
1045
 
{
1046
 
        if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
1047
 
            ) {
1048
 
                return NDIS_STATUS_FAILURE;
1049
 
        }
1050
 
 
1051
 
        return MlmeHardTransmitTxRing(pAd, QueIdx, pPacket);
1052
 
}
1053
 
 
1054
 
/*
1055
 
        ========================================================================
1056
 
 
1057
 
        Routine Description:
1058
 
                Calculates the duration which is required to transmit out frames
1059
 
        with given size and specified rate.
1060
 
 
1061
 
        Arguments:
1062
 
                pTxD            Pointer to transmit descriptor
1063
 
                Ack             Setting for Ack requirement bit
1064
 
                Fragment        Setting for Fragment bit
1065
 
                RetryMode       Setting for retry mode
1066
 
                Ifs             Setting for IFS gap
1067
 
                Rate            Setting for transmit rate
1068
 
                Service         Setting for service
1069
 
                Length          Frame length
1070
 
                TxPreamble      Short or Long preamble when using CCK rates
1071
 
                QueIdx - 0-3, according to 802.11e/d4.4 June/2003
1072
 
 
1073
 
        Return Value:
1074
 
                None
1075
 
 
1076
 
        IRQL = PASSIVE_LEVEL
1077
 
        IRQL = DISPATCH_LEVEL
1078
 
 
1079
 
        ========================================================================
1080
 
*/
1081
 
void RTMPWriteTxDescriptor(struct rt_rtmp_adapter *pAd,
1082
 
                           struct rt_txd * pTxD,
1083
 
                           IN BOOLEAN bWIV, u8 QueueSEL)
1084
 
{
1085
 
        /* */
1086
 
        /* Always use Long preamble before verifiation short preamble functionality works well. */
1087
 
        /* Todo: remove the following line if short preamble functionality works */
1088
 
        /* */
1089
 
        OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1090
 
 
1091
 
        pTxD->WIV = (bWIV) ? 1 : 0;
1092
 
        pTxD->QSEL = (QueueSEL);
1093
 
        /*RT2860c??  fixed using EDCA queue for test...  We doubt Queue1 has problem.  2006-09-26 Jan */
1094
 
        /*pTxD->QSEL= FIFO_EDCA; */
1095
 
        pTxD->DMADONE = 0;
1096
 
}