Linux-libre 2.6.32.58-gnu1
[librecmc/linux-libre.git] / drivers / staging / rt3090 / common / cmm_data_pci.c
1 /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
10  * This program is free software; you can redistribute it and/or modify  *
11  * it under the terms of the GNU General Public License as published by  *
12  * the Free Software Foundation; either version 2 of the License, or     *
13  * (at your option) any later version.                                   *
14  *                                                                       *
15  * This program is distributed in the hope that it will be useful,       *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  * GNU General Public License for more details.                          *
19  *                                                                       *
20  * You should have received a copy of the GNU General Public License     *
21  * along with this program; if not, write to the                         *
22  * Free Software Foundation, Inc.,                                       *
23  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
24  *                                                                       *
25  *************************************************************************
26 */
27
28 /*
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
36 USHORT RtmpPCI_WriteTxResource(
37         IN      PRTMP_ADAPTER   pAd,
38         IN      TX_BLK                  *pTxBlk,
39         IN      BOOLEAN                 bIsLast,
40         OUT     USHORT                  *FreeNumber)
41 {
42
43         UCHAR                   *pDMAHeaderBufVA;
44         USHORT                  TxIdx, RetTxIdx;
45         PTXD_STRUC              pTxD;
46         UINT32                  BufBasePaLow;
47         PRTMP_TX_RING   pTxRing;
48         USHORT                  hwHeaderLen;
49
50         //
51         // get Tx Ring Resource
52         //
53         pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
54         TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
55         pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
56         BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
57
58         // copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
59         if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
60         {
61                 //hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD;
62                 hwHeaderLen = pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
63         }
64         else
65         {
66                 //hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
67                 hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
68         }
69         NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHeaderLen);
70
71         pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
72         pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
73
74         //
75         // build Tx Descriptor
76         //
77
78         pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
79         NdisZeroMemory(pTxD, TXD_SIZE);
80
81         pTxD->SDPtr0 = BufBasePaLow;
82         pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; // include padding
83         pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
84         pTxD->SDLen1 = pTxBlk->SrcBufLen;
85         pTxD->LastSec0 = 0;
86         pTxD->LastSec1 = (bIsLast) ? 1 : 0;
87
88         RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
89
90         RetTxIdx = TxIdx;
91         //
92         // Update Tx index
93         //
94         INC_RING_INDEX(TxIdx, TX_RING_SIZE);
95         pTxRing->TxCpuIdx = TxIdx;
96
97         *FreeNumber -= 1;
98
99         return RetTxIdx;
100 }
101
102
103 USHORT RtmpPCI_WriteSingleTxResource(
104         IN      PRTMP_ADAPTER   pAd,
105         IN      TX_BLK                  *pTxBlk,
106         IN      BOOLEAN                 bIsLast,
107         OUT     USHORT                  *FreeNumber)
108 {
109
110         UCHAR                   *pDMAHeaderBufVA;
111         USHORT                  TxIdx, RetTxIdx;
112         PTXD_STRUC              pTxD;
113 #ifdef RT_BIG_ENDIAN
114     PTXD_STRUC      pDestTxD;
115     TXD_STRUC       TxD;
116 #endif
117         UINT32                  BufBasePaLow;
118         PRTMP_TX_RING   pTxRing;
119         USHORT                  hwHeaderLen;
120
121         //
122         // get Tx Ring Resource
123         //
124         pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
125         TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
126         pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
127         BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
128
129         // copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
130         //hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
131         hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
132
133         NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHeaderLen);
134
135         pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
136         pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
137
138         //
139         // build Tx Descriptor
140         //
141 #ifndef RT_BIG_ENDIAN
142         pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
143 #else
144         pDestTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
145         TxD = *pDestTxD;
146         pTxD = &TxD;
147 #endif
148         NdisZeroMemory(pTxD, TXD_SIZE);
149
150         pTxD->SDPtr0 = BufBasePaLow;
151         pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; // include padding
152         pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);;
153         pTxD->SDLen1 = pTxBlk->SrcBufLen;
154         pTxD->LastSec0 = 0;
155         pTxD->LastSec1 = (bIsLast) ? 1 : 0;
156
157         RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
158 #ifdef RT_BIG_ENDIAN
159         RTMPWIEndianChange((PUCHAR)(pDMAHeaderBufVA + TXINFO_SIZE), TYPE_TXWI);
160         RTMPFrameEndianChange(pAd, (PUCHAR)(pDMAHeaderBufVA + TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
161         RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
162         WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
163 #endif // RT_BIG_ENDIAN //
164
165         RetTxIdx = TxIdx;
166         //
167         // Update Tx index
168         //
169         INC_RING_INDEX(TxIdx, TX_RING_SIZE);
170         pTxRing->TxCpuIdx = TxIdx;
171
172         *FreeNumber -= 1;
173
174         return RetTxIdx;
175 }
176
177
178 USHORT RtmpPCI_WriteMultiTxResource(
179         IN      PRTMP_ADAPTER   pAd,
180         IN      TX_BLK                  *pTxBlk,
181         IN      UCHAR                   frameNum,
182         OUT     USHORT                  *FreeNumber)
183 {
184         BOOLEAN bIsLast;
185         UCHAR                   *pDMAHeaderBufVA;
186         USHORT                  TxIdx, RetTxIdx;
187         PTXD_STRUC              pTxD;
188 #ifdef RT_BIG_ENDIAN
189     PTXD_STRUC      pDestTxD;
190     TXD_STRUC       TxD;
191 #endif
192         UINT32                  BufBasePaLow;
193         PRTMP_TX_RING   pTxRing;
194         USHORT                  hwHdrLen;
195         UINT32                  firstDMALen;
196
197         bIsLast = ((frameNum == (pTxBlk->TotalFrameNum - 1)) ? 1 : 0);
198
199         //
200         // get Tx Ring Resource
201         //
202         pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
203         TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
204         pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
205         BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
206
207         if (frameNum == 0)
208         {
209                 // copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
210                 if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
211                         //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD;
212                         hwHdrLen = pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
213                 else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)
214                         //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD;
215                         hwHdrLen = pTxBlk->MpduHeaderLen - LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen + LENGTH_ARALINK_HEADER_FIELD;
216                 else
217                         //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
218                         hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
219
220                 firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;
221         }
222         else
223         {
224                 firstDMALen = pTxBlk->MpduHeaderLen;
225         }
226
227         NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen);
228
229         pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
230         pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
231
232         //
233         // build Tx Descriptor
234         //
235 #ifndef RT_BIG_ENDIAN
236         pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
237 #else
238         pDestTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
239         TxD = *pDestTxD;
240         pTxD = &TxD;
241 #endif
242         NdisZeroMemory(pTxD, TXD_SIZE);
243
244         pTxD->SDPtr0 = BufBasePaLow;
245         pTxD->SDLen0 = firstDMALen; // include padding
246         pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);;
247         pTxD->SDLen1 = pTxBlk->SrcBufLen;
248         pTxD->LastSec0 = 0;
249         pTxD->LastSec1 = (bIsLast) ? 1 : 0;
250
251         RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
252
253 #ifdef RT_BIG_ENDIAN
254         if (frameNum == 0)
255                 RTMPFrameEndianChange(pAd, (PUCHAR)(pDMAHeaderBufVA+ TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
256
257         if (frameNum != 0)
258                 RTMPWIEndianChange((PUCHAR)(pDMAHeaderBufVA + TXINFO_SIZE), TYPE_TXWI);
259
260         RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
261         WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
262 #endif // RT_BIG_ENDIAN //
263
264         RetTxIdx = TxIdx;
265         //
266         // Update Tx index
267         //
268         INC_RING_INDEX(TxIdx, TX_RING_SIZE);
269         pTxRing->TxCpuIdx = TxIdx;
270
271         *FreeNumber -= 1;
272
273         return RetTxIdx;
274
275 }
276
277
278 VOID RtmpPCI_FinalWriteTxResource(
279         IN      PRTMP_ADAPTER   pAd,
280         IN      TX_BLK                  *pTxBlk,
281         IN      USHORT                  totalMPDUSize,
282         IN      USHORT                  FirstTxIdx)
283 {
284
285         PTXWI_STRUC             pTxWI;
286         PRTMP_TX_RING   pTxRing;
287
288         //
289         // get Tx Ring Resource
290         //
291         pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
292         pTxWI = (PTXWI_STRUC) pTxRing->Cell[FirstTxIdx].DmaBuf.AllocVa;
293         pTxWI->MPDUtotalByteCount = totalMPDUSize;
294 #ifdef RT_BIG_ENDIAN
295         RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
296 #endif // RT_BIG_ENDIAN //
297
298 }
299
300
301 VOID RtmpPCIDataLastTxIdx(
302         IN      PRTMP_ADAPTER   pAd,
303         IN      UCHAR                   QueIdx,
304         IN      USHORT                  LastTxIdx)
305 {
306         PTXD_STRUC              pTxD;
307 #ifdef RT_BIG_ENDIAN
308     PTXD_STRUC      pDestTxD;
309     TXD_STRUC       TxD;
310 #endif
311         PRTMP_TX_RING   pTxRing;
312
313         //
314         // get Tx Ring Resource
315         //
316         pTxRing = &pAd->TxRing[QueIdx];
317
318         //
319         // build Tx Descriptor
320         //
321 #ifndef RT_BIG_ENDIAN
322         pTxD = (PTXD_STRUC) pTxRing->Cell[LastTxIdx].AllocVa;
323 #else
324         pDestTxD = (PTXD_STRUC) pTxRing->Cell[LastTxIdx].AllocVa;
325         TxD = *pDestTxD;
326         pTxD = &TxD;
327 #endif
328
329         pTxD->LastSec1 = 1;
330
331 #ifdef RT_BIG_ENDIAN
332         RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
333         WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
334 #endif // RT_BIG_ENDIAN //
335
336 }
337
338
339 USHORT  RtmpPCI_WriteFragTxResource(
340         IN      PRTMP_ADAPTER   pAd,
341         IN      TX_BLK                  *pTxBlk,
342         IN      UCHAR                   fragNum,
343         OUT     USHORT                  *FreeNumber)
344 {
345         UCHAR                   *pDMAHeaderBufVA;
346         USHORT                  TxIdx, RetTxIdx;
347         PTXD_STRUC              pTxD;
348 #ifdef RT_BIG_ENDIAN
349     PTXD_STRUC      pDestTxD;
350     TXD_STRUC       TxD;
351 #endif
352         UINT32                  BufBasePaLow;
353         PRTMP_TX_RING   pTxRing;
354         USHORT                  hwHeaderLen;
355         UINT32                  firstDMALen;
356
357         //
358         // Get Tx Ring Resource
359         //
360         pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
361         TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
362         pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
363         BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
364
365         //
366         // Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
367         //
368         //hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
369         hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
370
371         firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen;
372         NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen);
373
374
375         //
376         // Build Tx Descriptor
377         //
378 #ifndef RT_BIG_ENDIAN
379         pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
380 #else
381         pDestTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
382         TxD = *pDestTxD;
383         pTxD = &TxD;
384 #endif
385         NdisZeroMemory(pTxD, TXD_SIZE);
386
387         if (fragNum == pTxBlk->TotalFragNum)
388         {
389                 pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
390                 pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
391         }
392
393         pTxD->SDPtr0 = BufBasePaLow;
394         pTxD->SDLen0 = firstDMALen; // include padding
395         pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
396         pTxD->SDLen1 = pTxBlk->SrcBufLen;
397         pTxD->LastSec0 = 0;
398         pTxD->LastSec1 = 1;
399
400         RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
401
402 #ifdef RT_BIG_ENDIAN
403         RTMPWIEndianChange((PUCHAR)(pDMAHeaderBufVA + TXINFO_SIZE), TYPE_TXWI);
404         RTMPFrameEndianChange(pAd, (PUCHAR)(pDMAHeaderBufVA + TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
405         RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
406     WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
407 #endif // RT_BIG_ENDIAN //
408
409         RetTxIdx = TxIdx;
410         pTxBlk->Priv += pTxBlk->SrcBufLen;
411
412         //
413         // Update Tx index
414         //
415         INC_RING_INDEX(TxIdx, TX_RING_SIZE);
416         pTxRing->TxCpuIdx = TxIdx;
417
418         *FreeNumber -= 1;
419
420         return RetTxIdx;
421
422 }
423
424
425 /*
426         Must be run in Interrupt context
427         This function handle PCI specific TxDesc and cpu index update and kick the packet out.
428  */
429 int RtmpPCIMgmtKickOut(
430         IN RTMP_ADAPTER         *pAd,
431         IN UCHAR                        QueIdx,
432         IN PNDIS_PACKET         pPacket,
433         IN PUCHAR                       pSrcBufVA,
434         IN UINT                         SrcBufLen)
435 {
436         PTXD_STRUC              pTxD;
437 #ifdef RT_BIG_ENDIAN
438     PTXD_STRUC      pDestTxD;
439     TXD_STRUC       TxD;
440 #endif
441         ULONG                   SwIdx = pAd->MgmtRing.TxCpuIdx;
442
443 #ifdef RT_BIG_ENDIAN
444     pDestTxD  = (PTXD_STRUC)pAd->MgmtRing.Cell[SwIdx].AllocVa;
445     TxD = *pDestTxD;
446     pTxD = &TxD;
447     RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
448 #else
449         pTxD  = (PTXD_STRUC) pAd->MgmtRing.Cell[SwIdx].AllocVa;
450 #endif
451
452         pAd->MgmtRing.Cell[SwIdx].pNdisPacket = pPacket;
453         pAd->MgmtRing.Cell[SwIdx].pNextNdisPacket = NULL;
454
455         RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_MGMT);
456         pTxD->LastSec0 = 1;
457         pTxD->LastSec1 = 1;
458         pTxD->DMADONE = 0;
459         pTxD->SDLen1 = 0;
460         pTxD->SDPtr0 = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
461         pTxD->SDLen0 = SrcBufLen;
462
463 #ifdef RT_BIG_ENDIAN
464         RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
465     WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
466 #endif
467
468 //==================================================================
469 /*      DBGPRINT_RAW(RT_DEBUG_TRACE, ("MLMEHardTransmit\n"));
470         for (i = 0; i < (TXWI_SIZE+24); i++)
471         {
472
473                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("%x:", *(pSrcBufVA+i)));
474                 if ( i%4 == 3)
475                         DBGPRINT_RAW(RT_DEBUG_TRACE, (" :: "));
476                 if ( i%16 == 15)
477                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n      "));
478         }
479         DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n      "));*/
480 //=======================================================================
481
482         pAd->RalinkCounters.KickTxCount++;
483         pAd->RalinkCounters.OneSecTxDoneCount++;
484
485         // Increase TX_CTX_IDX, but write to register later.
486         INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
487
488         RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX,  pAd->MgmtRing.TxCpuIdx);
489
490         return 0;
491 }
492
493
494 #ifdef CONFIG_STA_SUPPORT
495 /*
496         ========================================================================
497
498         Routine Description:
499                 Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
500
501         Arguments:
502                 pRxD            Pointer to the Rx descriptor
503
504         Return Value:
505                 NDIS_STATUS_SUCCESS     No err
506                 NDIS_STATUS_FAILURE     Error
507
508         Note:
509
510         ========================================================================
511 */
512 NDIS_STATUS RTMPCheckRxError(
513         IN      PRTMP_ADAPTER           pAd,
514         IN      PHEADER_802_11          pHeader,
515         IN      PRXWI_STRUC             pRxWI,
516         IN  PRT28XX_RXD_STRUC   pRxD)
517 {
518         PCIPHER_KEY pWpaKey;
519         INT dBm;
520
521         // Phy errors & CRC errors
522         if (/*(pRxD->PhyErr) ||*/ (pRxD->Crc))
523         {
524                 // Check RSSI for Noise Hist statistic collection.
525                 dBm = (INT) (pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta;
526                 if (dBm <= -87)
527                         pAd->StaCfg.RPIDensity[0] += 1;
528                 else if (dBm <= -82)
529                         pAd->StaCfg.RPIDensity[1] += 1;
530                 else if (dBm <= -77)
531                         pAd->StaCfg.RPIDensity[2] += 1;
532                 else if (dBm <= -72)
533                         pAd->StaCfg.RPIDensity[3] += 1;
534                 else if (dBm <= -67)
535                         pAd->StaCfg.RPIDensity[4] += 1;
536                 else if (dBm <= -62)
537                         pAd->StaCfg.RPIDensity[5] += 1;
538                 else if (dBm <= -57)
539                         pAd->StaCfg.RPIDensity[6] += 1;
540                 else if (dBm > -57)
541                         pAd->StaCfg.RPIDensity[7] += 1;
542
543                 return(NDIS_STATUS_FAILURE);
544         }
545
546         // Add Rx size to channel load counter, we should ignore error counts
547         pAd->StaCfg.CLBusyBytes += (pRxD->SDL0 + 14);
548
549         // Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics
550         if (pHeader != NULL)
551         {
552                 if (pHeader->FC.ToDs)
553                 {
554                         return(NDIS_STATUS_FAILURE);
555                 }
556         }
557
558         // Drop not U2M frames, cant's drop here because we will drop beacon in this case
559         // I am kind of doubting the U2M bit operation
560         // if (pRxD->U2M == 0)
561         //      return(NDIS_STATUS_FAILURE);
562
563         // drop decyption fail frame
564         if (pRxD->CipherErr)
565         {
566                 if (pRxD->CipherErr == 2)
567                         {DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: ICV ok but MICErr "));}
568                 else if (pRxD->CipherErr == 1)
569                         {DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: ICV Err "));}
570                 else if (pRxD->CipherErr == 3)
571                         DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: Key not valid "));
572
573         if (((pRxD->CipherErr & 1) == 1) && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
574             RTMPSendWirelessEvent(pAd, IW_ICV_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
575
576                 DBGPRINT_RAW(RT_DEBUG_TRACE,(" %d (len=%d, Mcast=%d, MyBss=%d, Wcid=%d, KeyId=%d)\n",
577                         pRxD->CipherErr,
578                         pRxD->SDL0,
579                         pRxD->Mcast | pRxD->Bcast,
580                         pRxD->MyBss,
581                         pRxWI->WirelessCliID,
582 //                      CipherName[pRxD->CipherAlg],
583                         pRxWI->KeyIndex));
584
585                 //
586                 // MIC Error
587                 //
588                 if (pRxD->CipherErr == 2)
589                 {
590                         pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
591 #ifdef WPA_SUPPLICANT_SUPPORT
592             if (pAd->StaCfg.WpaSupplicantUP)
593                 WpaSendMicFailureToWpaSupplicant(pAd,
594                                    (pWpaKey->Type == PAIRWISEKEY) ? TRUE:FALSE);
595             else
596 #endif // WPA_SUPPLICANT_SUPPORT //
597                             RTMPReportMicError(pAd, pWpaKey);
598
599             if (((pRxD->CipherErr & 2) == 2) && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
600                 RTMPSendWirelessEvent(pAd, IW_MIC_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
601
602                         DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error\n"));
603                 }
604
605                 if (pHeader == NULL)
606                         return(NDIS_STATUS_SUCCESS);
607                 /*if ((pRxD->CipherAlg == CIPHER_AES) &&
608                         (pHeader->Sequence == pAd->FragFrame.Sequence))
609                 {
610                         //
611                         // Acceptable since the First FragFrame no CipherErr problem.
612                         //
613                         return(NDIS_STATUS_SUCCESS);
614                 }*/
615
616                 return(NDIS_STATUS_FAILURE);
617         }
618
619         return(NDIS_STATUS_SUCCESS);
620 }
621 #endif // CONFIG_STA_SUPPORT //
622
623
624 BOOLEAN  RTMPFreeTXDUponTxDmaDone(
625         IN PRTMP_ADAPTER        pAd,
626         IN UCHAR                        QueIdx)
627 {
628         PRTMP_TX_RING pTxRing;
629         PTXD_STRUC        pTxD;
630 #ifdef  RT_BIG_ENDIAN
631     PTXD_STRUC      pDestTxD;
632 #endif
633         PNDIS_PACKET  pPacket;
634         UCHAR   FREE = 0;
635         TXD_STRUC       TxD, *pOriTxD;
636         //ULONG         IrqFlags;
637         BOOLEAN                 bReschedule = FALSE;
638
639
640         ASSERT(QueIdx < NUM_OF_TX_RING);
641         pTxRing = &pAd->TxRing[QueIdx];
642
643         RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF, &pTxRing->TxDmaIdx);
644         while (pTxRing->TxSwFreeIdx != pTxRing->TxDmaIdx)
645         {
646 //              RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
647 #ifdef RALINK_ATE
648 #ifdef RALINK_28xx_QA
649                 PHEADER_802_11  pHeader80211;
650
651                 if ((ATE_ON(pAd)) && (pAd->ate.bQATxStart == TRUE))
652                 {
653                         if (pAd->ate.QID == QueIdx)
654                         {
655                                 pAd->ate.TxDoneCount++;
656                                 pAd->RalinkCounters.KickTxCount++;
657
658                                 /* always use QID_AC_BE and FIFO_EDCA */
659                                 ASSERT(pAd->ate.QID == 0);
660                                 pAd->ate.TxAc0++;
661
662                                 FREE++;
663 #ifndef RT_BIG_ENDIAN
664                                 pTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
665                                 pOriTxD = pTxD;
666                         NdisMoveMemory(&TxD, pTxD, sizeof(TXD_STRUC));
667                                 pTxD = &TxD;
668 #else
669                         pDestTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
670                         pOriTxD = pDestTxD ;
671                         TxD = *pDestTxD;
672                         pTxD = &TxD;
673                         RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
674 #endif
675                                 pTxD->DMADONE = 0;
676
677                                 pHeader80211 = pTxRing->Cell[pTxRing->TxSwFreeIdx].DmaBuf.AllocVa + sizeof(TXWI_STRUC);
678 #ifdef RT_BIG_ENDIAN
679                                 RTMPFrameEndianChange(pAd, (PUCHAR)pHeader80211, DIR_READ, FALSE);
680 #endif
681                                 pHeader80211->Sequence = ++pAd->ate.seq;
682 #ifdef RT_BIG_ENDIAN
683                                 RTMPFrameEndianChange(pAd, (PUCHAR)pHeader80211, DIR_WRITE, FALSE);
684 #endif
685
686                                 if  ((pAd->ate.bQATxStart == TRUE) && (pAd->ate.Mode & ATE_TXFRAME) && (pAd->ate.TxDoneCount < pAd->ate.TxCount))
687                                 {
688                                         pAd->RalinkCounters.TransmittedByteCount +=  (pTxD->SDLen1 + pTxD->SDLen0);
689                                         pAd->RalinkCounters.OneSecTransmittedByteCount += (pTxD->SDLen1 + pTxD->SDLen0);
690                                         pAd->RalinkCounters.OneSecDmaDoneCount[QueIdx] ++;
691                                         INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE);
692
693                                         /* get TX_DTX_IDX again */
694                                         RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF ,  &pTxRing->TxDmaIdx);
695                                         goto kick_out;
696                                 }
697                                 else if ((pAd->ate.TxStatus == 1)/* or (pAd->ate.bQATxStart == TRUE) ??? */ && (pAd->ate.TxDoneCount == pAd->ate.TxCount))
698                                 {
699                                         DBGPRINT(RT_DEBUG_TRACE,("all Tx is done\n"));
700
701                                         // Tx status enters idle mode.
702                                         pAd->ate.TxStatus = 0;
703                                 }
704                                 else if (!(pAd->ate.Mode & ATE_TXFRAME))
705                                 {
706                                         /* not complete sending yet, but someone press the Stop TX botton */
707                                         DBGPRINT(RT_DEBUG_ERROR,("not complete sending yet, but someone pressed the Stop TX bottom\n"));
708                                         DBGPRINT(RT_DEBUG_ERROR,("pAd->ate.Mode = 0x%02x\n", pAd->ate.Mode));
709                                 }
710                                 else
711                                 {
712                                         DBGPRINT(RT_DEBUG_OFF,("pTxRing->TxSwFreeIdx = %d\n", pTxRing->TxSwFreeIdx));
713                                 }
714
715 #ifndef RT_BIG_ENDIAN
716                         NdisMoveMemory(pOriTxD, pTxD, sizeof(TXD_STRUC));
717 #else
718                         RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
719                         *pDestTxD = TxD;
720 #endif // RT_BIG_ENDIAN //
721
722                                 INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE);
723                                 continue;
724                         }
725                 }
726 #endif // RALINK_28xx_QA //
727 #endif // RALINK_ATE //
728
729                 // static rate also need NICUpdateFifoStaCounters() function.
730                 //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
731                         NICUpdateFifoStaCounters(pAd);
732
733                 /* Note : If (pAd->ate.bQATxStart == TRUE), we will never reach here. */
734                 FREE++;
735 #ifndef RT_BIG_ENDIAN
736                 pTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
737                 pOriTxD = pTxD;
738                 NdisMoveMemory(&TxD, pTxD, sizeof(TXD_STRUC));
739                 pTxD = &TxD;
740 #else
741         pDestTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
742         pOriTxD = pDestTxD ;
743         TxD = *pDestTxD;
744         pTxD = &TxD;
745         RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
746 #endif
747
748                 pTxD->DMADONE = 0;
749
750
751 #ifdef RALINK_ATE
752                 /* Execution of this block is not allowed when ATE is running. */
753                 if (!(ATE_ON(pAd)))
754 #endif // RALINK_ATE //
755                 {
756                         pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket;
757                         if (pPacket)
758                         {
759 #ifdef CONFIG_5VT_ENHANCE
760                                 if (RTMP_GET_PACKET_5VT(pPacket))
761                                         PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, 16, PCI_DMA_TODEVICE);
762                                 else
763 #endif // CONFIG_5VT_ENHANCE //
764                                         PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
765                                 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
766                         }
767                         //Always assign pNdisPacket as NULL after clear
768                         pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket = NULL;
769
770                         pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket;
771
772                         ASSERT(pPacket == NULL);
773                         if (pPacket)
774                         {
775 #ifdef CONFIG_5VT_ENHANCE
776                                 if (RTMP_GET_PACKET_5VT(pPacket))
777                                         PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, 16, PCI_DMA_TODEVICE);
778                                 else
779 #endif // CONFIG_5VT_ENHANCE //
780                                         PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
781                                 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
782                         }
783                         //Always assign pNextNdisPacket as NULL after clear
784                         pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL;
785                 }
786
787                 pAd->RalinkCounters.TransmittedByteCount +=  (pTxD->SDLen1 + pTxD->SDLen0);
788                 pAd->RalinkCounters.OneSecDmaDoneCount[QueIdx] ++;
789                 INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE);
790                 /* get tx_tdx_idx again */
791                 RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF ,  &pTxRing->TxDmaIdx);
792 #ifdef RT_BIG_ENDIAN
793         RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
794         *pDestTxD = TxD;
795 #else
796         NdisMoveMemory(pOriTxD, pTxD, sizeof(TXD_STRUC));
797 #endif
798
799 #ifdef RALINK_ATE
800 #ifdef RALINK_28xx_QA
801 kick_out:
802 #endif // RALINK_28xx_QA //
803
804                 /*
805                         ATE_TXCONT mode also need to send some normal frames, so let it in.
806                         ATE_STOP must be changed not to be 0xff
807                         to prevent it from running into this block.
808                 */
809                 if ((pAd->ate.Mode & ATE_TXFRAME) && (pAd->ate.QID == QueIdx))
810                 {
811                         // TxDoneCount++ has been done if QA is used.
812                         if (pAd->ate.bQATxStart == FALSE)
813                         {
814                                 pAd->ate.TxDoneCount++;
815                         }
816                         if (((pAd->ate.TxCount - pAd->ate.TxDoneCount + 1) >= TX_RING_SIZE))
817                         {
818                                 /* Note : We increase TxCpuIdx here, not TxSwFreeIdx ! */
819                                 INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE);
820 #ifndef RT_BIG_ENDIAN
821                                 pTxD = (PTXD_STRUC) (pTxRing->Cell[pAd->TxRing[QueIdx].TxCpuIdx].AllocVa);
822                                 pOriTxD = pTxD;
823                         NdisMoveMemory(&TxD, pTxD, sizeof(TXD_STRUC));
824                                 pTxD = &TxD;
825 #else
826                         pDestTxD = (PTXD_STRUC) (pTxRing->Cell[pAd->TxRing[QueIdx].TxCpuIdx].AllocVa);
827                         pOriTxD = pDestTxD ;
828                         TxD = *pDestTxD;
829                         pTxD = &TxD;
830                         RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
831 #endif
832                                 pTxD->DMADONE = 0;
833 #ifndef RT_BIG_ENDIAN
834                         NdisMoveMemory(pOriTxD, pTxD, sizeof(TXD_STRUC));
835 #else
836                         RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
837                         *pDestTxD = TxD;
838 #endif
839                                 // kick Tx-Ring
840                                 RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx * RINGREG_DIFF, pAd->TxRing[QueIdx].TxCpuIdx);
841                                 pAd->RalinkCounters.KickTxCount++;
842                         }
843                 }
844 #endif // RALINK_ATE //
845 //         RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
846         }
847
848
849         return  bReschedule;
850
851 }
852
853
854 /*
855         ========================================================================
856
857         Routine Description:
858                 Process TX Rings DMA Done interrupt, running in DPC level
859
860         Arguments:
861                 Adapter         Pointer to our adapter
862
863         Return Value:
864                 None
865
866         IRQL = DISPATCH_LEVEL
867
868         ========================================================================
869 */
870 BOOLEAN RTMPHandleTxRingDmaDoneInterrupt(
871         IN      PRTMP_ADAPTER   pAd,
872         IN      INT_SOURCE_CSR_STRUC TxRingBitmap)
873 {
874 //      UCHAR                   Count = 0;
875     unsigned long       IrqFlags;
876         BOOLEAN                 bReschedule = FALSE;
877
878         // Make sure Tx ring resource won't be used by other threads
879         //NdisAcquireSpinLock(&pAd->TxRingLock);
880
881         RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
882
883         if (TxRingBitmap.field.Ac0DmaDone)
884                 bReschedule = RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BE);
885 /*
886         if (TxRingBitmap.field.HccaDmaDone)
887                 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_HCCA);
888 */
889
890         if (TxRingBitmap.field.Ac3DmaDone)
891                 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VO);
892
893         if (TxRingBitmap.field.Ac2DmaDone)
894                 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VI);
895
896         if (TxRingBitmap.field.Ac1DmaDone)
897                 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BK);
898
899         // Make sure to release Tx ring resource
900         //NdisReleaseSpinLock(&pAd->TxRingLock);
901         RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
902
903         // Dequeue outgoing frames from TxSwQueue[] and process it
904         RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
905
906         return  bReschedule;
907 }
908
909
910 /*
911         ========================================================================
912
913         Routine Description:
914                 Process MGMT ring DMA done interrupt, running in DPC level
915
916         Arguments:
917                 pAd     Pointer to our adapter
918
919         Return Value:
920                 None
921
922         IRQL = DISPATCH_LEVEL
923
924         Note:
925
926         ========================================================================
927 */
928 VOID    RTMPHandleMgmtRingDmaDoneInterrupt(
929         IN      PRTMP_ADAPTER   pAd)
930 {
931         PTXD_STRUC       pTxD;
932 #ifdef RT_BIG_ENDIAN
933     PTXD_STRUC      pDestTxD;
934     TXD_STRUC       TxD;
935 #endif
936         PNDIS_PACKET pPacket;
937 //      int              i;
938         UCHAR   FREE = 0;
939         PRTMP_MGMT_RING pMgmtRing = &pAd->MgmtRing;
940
941         NdisAcquireSpinLock(&pAd->MgmtRingLock);
942
943         RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pMgmtRing->TxDmaIdx);
944         while (pMgmtRing->TxSwFreeIdx!= pMgmtRing->TxDmaIdx)
945         {
946                 FREE++;
947 #ifdef RT_BIG_ENDIAN
948         pDestTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa);
949         TxD = *pDestTxD;
950         pTxD = &TxD;
951                 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
952 #else
953                 pTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa);
954 #endif
955                 pTxD->DMADONE = 0;
956                 pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket;
957
958
959                 if (pPacket)
960                 {
961                         PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
962                         RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
963                 }
964                 pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket = NULL;
965
966                 pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket;
967                 if (pPacket)
968                 {
969                         PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
970                         RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
971                 }
972                 pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket = NULL;
973                 INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE);
974
975 #ifdef RT_BIG_ENDIAN
976         RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
977         WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, TRUE, TYPE_TXD);
978 #endif
979         }
980         NdisReleaseSpinLock(&pAd->MgmtRingLock);
981
982 #ifdef CONFIG_STA_SUPPORT
983 #endif // CONFIG_STA_SUPPORT //
984 }
985
986
987 /*
988         ========================================================================
989
990         Routine Description:
991         Arguments:
992                 Adapter         Pointer to our adapter. Dequeue all power safe delayed braodcast frames after beacon.
993
994         IRQL = DISPATCH_LEVEL
995
996         ========================================================================
997 */
998 VOID    RTMPHandleTBTTInterrupt(
999         IN PRTMP_ADAPTER pAd)
1000 {
1001         {
1002                 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
1003                 {
1004                 }
1005         }
1006 }
1007
1008
1009 /*
1010         ========================================================================
1011
1012         Routine Description:
1013         Arguments:
1014                 pAd             Pointer to our adapter. Rewrite beacon content before next send-out.
1015
1016         IRQL = DISPATCH_LEVEL
1017
1018         ========================================================================
1019 */
1020 VOID    RTMPHandlePreTBTTInterrupt(
1021         IN PRTMP_ADAPTER pAd)
1022 {
1023         {
1024                 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
1025                 {
1026                         DBGPRINT(RT_DEBUG_TRACE, ("RTMPHandlePreTBTTInterrupt...\n"));
1027                 }
1028         }
1029
1030
1031 }
1032
1033 VOID    RTMPHandleRxCoherentInterrupt(
1034         IN      PRTMP_ADAPTER   pAd)
1035 {
1036         WPDMA_GLO_CFG_STRUC     GloCfg;
1037
1038         if (pAd == NULL)
1039         {
1040                 DBGPRINT(RT_DEBUG_TRACE, ("====> pAd is NULL, return.\n"));
1041                 return;
1042         }
1043
1044         DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPHandleRxCoherentInterrupt \n"));
1045
1046         RTMP_IO_READ32(pAd, WPDMA_GLO_CFG , &GloCfg.word);
1047
1048         GloCfg.field.EnTXWriteBackDDONE = 0;
1049         GloCfg.field.EnableRxDMA = 0;
1050         GloCfg.field.EnableTxDMA = 0;
1051         RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
1052
1053         RTMPRingCleanUp(pAd, QID_AC_BE);
1054         RTMPRingCleanUp(pAd, QID_AC_BK);
1055         RTMPRingCleanUp(pAd, QID_AC_VI);
1056         RTMPRingCleanUp(pAd, QID_AC_VO);
1057         /*RTMPRingCleanUp(pAd, QID_HCCA);*/
1058         RTMPRingCleanUp(pAd, QID_MGMT);
1059         RTMPRingCleanUp(pAd, QID_RX);
1060
1061         RTMPEnableRxTx(pAd);
1062
1063         DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPHandleRxCoherentInterrupt \n"));
1064 }
1065
1066
1067
1068
1069 VOID DBGPRINT_TX_RING(
1070         IN PRTMP_ADAPTER  pAd,
1071         IN UCHAR          QueIdx)
1072 {
1073         UINT32          Ac0Base;
1074         UINT32          Ac0HwIdx = 0, Ac0SwIdx = 0, AC0freeIdx;
1075         int                     i;
1076 //      PULONG          pTxD;
1077         PULONG  ptemp;
1078
1079         DBGPRINT_RAW(RT_DEBUG_TRACE, ("=====================================================\n "  ));
1080         switch (QueIdx)
1081         {
1082                 case QID_AC_BE:
1083                         RTMP_IO_READ32(pAd, TX_BASE_PTR0, &Ac0Base);
1084                         RTMP_IO_READ32(pAd, TX_CTX_IDX0, &Ac0SwIdx);
1085                         RTMP_IO_READ32(pAd, TX_DTX_IDX0, &Ac0HwIdx);
1086                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_BE DESCRIPTOR  \n "  ));
1087                         for (i=0;i<TX_RING_SIZE;i++)
1088                         {
1089                                 ptemp= (PULONG)pAd->TxRing[QID_AC_BE].Cell[i].AllocVa;
1090                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
1091                         }
1092                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("  \n "  ));
1093                         break;
1094                 case QID_AC_BK:
1095                         RTMP_IO_READ32(pAd, TX_BASE_PTR1, &Ac0Base);
1096                         RTMP_IO_READ32(pAd, TX_CTX_IDX1, &Ac0SwIdx);
1097                         RTMP_IO_READ32(pAd, TX_DTX_IDX1, &Ac0HwIdx);
1098                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_BK DESCRIPTOR  \n "  ));
1099                         for (i=0;i<TX_RING_SIZE;i++)
1100                         {
1101                                 ptemp= (PULONG)pAd->TxRing[QID_AC_BK].Cell[i].AllocVa;
1102                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
1103                         }
1104                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("  \n "  ));
1105                         break;
1106                 case QID_AC_VI:
1107                         RTMP_IO_READ32(pAd, TX_BASE_PTR2, &Ac0Base);
1108                         RTMP_IO_READ32(pAd, TX_CTX_IDX2, &Ac0SwIdx);
1109                         RTMP_IO_READ32(pAd, TX_DTX_IDX2, &Ac0HwIdx);
1110                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_VI DESCRIPTOR \n "  ));
1111                         for (i=0;i<TX_RING_SIZE;i++)
1112                         {
1113                                 ptemp= (PULONG)pAd->TxRing[QID_AC_VI].Cell[i].AllocVa;
1114                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
1115                         }
1116                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("  \n "  ));
1117                         break;
1118                 case QID_AC_VO:
1119                         RTMP_IO_READ32(pAd, TX_BASE_PTR3, &Ac0Base);
1120                         RTMP_IO_READ32(pAd, TX_CTX_IDX3, &Ac0SwIdx);
1121                         RTMP_IO_READ32(pAd, TX_DTX_IDX3, &Ac0HwIdx);
1122                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_VO DESCRIPTOR \n "  ));
1123                         for (i=0;i<TX_RING_SIZE;i++)
1124                         {
1125                                 ptemp= (PULONG)pAd->TxRing[QID_AC_VO].Cell[i].AllocVa;
1126                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
1127                         }
1128                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("  \n "  ));
1129                         break;
1130                 case QID_MGMT:
1131                         RTMP_IO_READ32(pAd, TX_BASE_PTR5, &Ac0Base);
1132                         RTMP_IO_READ32(pAd, TX_CTX_IDX5, &Ac0SwIdx);
1133                         RTMP_IO_READ32(pAd, TX_DTX_IDX5, &Ac0HwIdx);
1134                         DBGPRINT_RAW(RT_DEBUG_TRACE, (" All QID_MGMT  DESCRIPTOR \n "  ));
1135                         for (i=0;i<MGMT_RING_SIZE;i++)
1136                         {
1137                                 ptemp= (PULONG)pAd->MgmtRing.Cell[i].AllocVa;
1138                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
1139                         }
1140                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("  \n "  ));
1141                         break;
1142
1143                 default:
1144                         DBGPRINT_ERR(("DBGPRINT_TX_RING(Ring %d) not supported\n", QueIdx));
1145                         break;
1146         }
1147         AC0freeIdx = pAd->TxRing[QueIdx].TxSwFreeIdx;
1148
1149         DBGPRINT(RT_DEBUG_TRACE,("TxRing%d, TX_DTX_IDX=%d, TX_CTX_IDX=%d\n", QueIdx, Ac0HwIdx, Ac0SwIdx));
1150         DBGPRINT_RAW(RT_DEBUG_TRACE,("  TxSwFreeIdx[%d]", AC0freeIdx));
1151         DBGPRINT_RAW(RT_DEBUG_TRACE,("  pending-NDIS=%ld\n", pAd->RalinkCounters.PendingNdisPacketCount));
1152
1153
1154 }
1155
1156
1157 VOID DBGPRINT_RX_RING(
1158         IN PRTMP_ADAPTER  pAd)
1159 {
1160         UINT32          Ac0Base;
1161         UINT32          Ac0HwIdx = 0, Ac0SwIdx = 0, AC0freeIdx;
1162 //      PULONG   pTxD;
1163         int                     i;
1164         UINT32  *ptemp;
1165 //      PRXD_STRUC              pRxD;
1166
1167         DBGPRINT_RAW(RT_DEBUG_TRACE, ("=====================================================\n "  ));
1168         RTMP_IO_READ32(pAd, RX_BASE_PTR, &Ac0Base);
1169         RTMP_IO_READ32(pAd, RX_CRX_IDX, &Ac0SwIdx);
1170         RTMP_IO_READ32(pAd, RX_DRX_IDX, &Ac0HwIdx);
1171         AC0freeIdx = pAd->RxRing.RxSwReadIdx;
1172
1173         DBGPRINT_RAW(RT_DEBUG_TRACE, ("All RX DSP  \n "  ));
1174         for (i=0;i<RX_RING_SIZE;i++)
1175         {
1176                 ptemp = (UINT32 *)pAd->RxRing.Cell[i].AllocVa;
1177                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08x: %08x: %08x: %08x\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
1178         }
1179         DBGPRINT(RT_DEBUG_TRACE,("RxRing, RX_DRX_IDX=%d, RX_CRX_IDX=%d \n", Ac0HwIdx, Ac0SwIdx));
1180         DBGPRINT_RAW(RT_DEBUG_TRACE,("  RxSwReadIdx [%d]=", AC0freeIdx));
1181         DBGPRINT_RAW(RT_DEBUG_TRACE,("  pending-NDIS=%ld\n", pAd->RalinkCounters.PendingNdisPacketCount));
1182 }
1183
1184
1185 PNDIS_PACKET GetPacketFromRxRing(
1186         IN              PRTMP_ADAPTER   pAd,
1187         OUT             PRT28XX_RXD_STRUC       pSaveRxD,
1188         OUT             BOOLEAN                 *pbReschedule,
1189         IN OUT  UINT32                  *pRxPending)
1190 {
1191         PRXD_STRUC                              pRxD;
1192 #ifdef RT_BIG_ENDIAN
1193         PRXD_STRUC                              pDestRxD;
1194         RXD_STRUC                               RxD;
1195 #endif
1196         PNDIS_PACKET                    pRxPacket = NULL;
1197         PNDIS_PACKET                    pNewPacket;
1198         PVOID                                   AllocVa;
1199         NDIS_PHYSICAL_ADDRESS   AllocPa;
1200         BOOLEAN                                 bReschedule = FALSE;
1201
1202         RTMP_SEM_LOCK(&pAd->RxRingLock);
1203
1204         if (*pRxPending == 0)
1205         {
1206                 // Get how may packets had been received
1207                 RTMP_IO_READ32(pAd, RX_DRX_IDX , &pAd->RxRing.RxDmaIdx);
1208
1209                 if (pAd->RxRing.RxSwReadIdx == pAd->RxRing.RxDmaIdx)
1210                 {
1211                         // no more rx packets
1212                         bReschedule = FALSE;
1213                         goto done;
1214                 }
1215
1216                 // get rx pending count
1217                 if (pAd->RxRing.RxDmaIdx > pAd->RxRing.RxSwReadIdx)
1218                         *pRxPending = pAd->RxRing.RxDmaIdx - pAd->RxRing.RxSwReadIdx;
1219                 else
1220                         *pRxPending     = pAd->RxRing.RxDmaIdx + RX_RING_SIZE - pAd->RxRing.RxSwReadIdx;
1221
1222         }
1223
1224 #ifdef RT_BIG_ENDIAN
1225         pDestRxD = (PRXD_STRUC) pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].AllocVa;
1226         RxD = *pDestRxD;
1227         pRxD = &RxD;
1228         RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
1229 #else
1230         // Point to Rx indexed rx ring descriptor
1231         pRxD = (PRXD_STRUC) pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].AllocVa;
1232 #endif
1233
1234         if (pRxD->DDONE == 0)
1235         {
1236                 *pRxPending = 0;
1237                 // DMAIndx had done but DDONE bit not ready
1238                 bReschedule = TRUE;
1239                 goto done;
1240         }
1241
1242
1243         // return rx descriptor
1244         NdisMoveMemory(pSaveRxD, pRxD, RXD_SIZE);
1245
1246         pNewPacket = RTMP_AllocateRxPacketBuffer(pAd, RX_BUFFER_AGGRESIZE, FALSE, &AllocVa, &AllocPa);
1247
1248         if (pNewPacket)
1249         {
1250                 // unmap the rx buffer
1251                 PCI_UNMAP_SINGLE(pAd, pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocPa,
1252                                          pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
1253                 pRxPacket = pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].pNdisPacket;
1254
1255                 pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocSize      = RX_BUFFER_AGGRESIZE;
1256                 pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].pNdisPacket           = (PNDIS_PACKET) pNewPacket;
1257                 pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocVa        = AllocVa;
1258                 pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocPa        = AllocPa;
1259                 /* update SDP0 to new buffer of rx packet */
1260                 pRxD->SDP0 = AllocPa;
1261         }
1262         else
1263         {
1264                 //DBGPRINT(RT_DEBUG_TRACE,("No Rx Buffer\n"));
1265                 pRxPacket = NULL;
1266                 bReschedule = TRUE;
1267         }
1268
1269         pRxD->DDONE = 0;
1270
1271         // had handled one rx packet
1272         *pRxPending = *pRxPending - 1;
1273
1274         // update rx descriptor and kick rx
1275 #ifdef RT_BIG_ENDIAN
1276         RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
1277         WriteBackToDescriptor((PUCHAR)pDestRxD, (PUCHAR)pRxD, FALSE, TYPE_RXD);
1278 #endif
1279         INC_RING_INDEX(pAd->RxRing.RxSwReadIdx, RX_RING_SIZE);
1280
1281         pAd->RxRing.RxCpuIdx = (pAd->RxRing.RxSwReadIdx == 0) ? (RX_RING_SIZE-1) : (pAd->RxRing.RxSwReadIdx-1);
1282         RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
1283
1284 done:
1285         RTMP_SEM_UNLOCK(&pAd->RxRingLock);
1286         *pbReschedule = bReschedule;
1287         return pRxPacket;
1288 }
1289
1290
1291 NDIS_STATUS MlmeHardTransmitTxRing(
1292         IN      PRTMP_ADAPTER   pAd,
1293         IN      UCHAR   QueIdx,
1294         IN      PNDIS_PACKET    pPacket)
1295 {
1296         PACKET_INFO     PacketInfo;
1297         PUCHAR                  pSrcBufVA;
1298         UINT                    SrcBufLen;
1299         PTXD_STRUC              pTxD;
1300 #ifdef RT_BIG_ENDIAN
1301     PTXD_STRUC      pDestTxD;
1302     TXD_STRUC       TxD;
1303 #endif
1304         PHEADER_802_11  pHeader_802_11;
1305         BOOLEAN                 bAckRequired, bInsertTimestamp;
1306         ULONG                   SrcBufPA;
1307         //UCHAR                 TxBufIdx;
1308         UCHAR                   MlmeRate;
1309         ULONG                   SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
1310         PTXWI_STRUC     pFirstTxWI;
1311         //ULONG i;
1312         //HTTRANSMIT_SETTING    MlmeTransmit;   //Rate for this MGMT frame.
1313         ULONG    FreeNum;
1314         MAC_TABLE_ENTRY *pMacEntry = NULL;
1315
1316
1317         RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
1318
1319
1320         if (pSrcBufVA == NULL)
1321         {
1322                 // The buffer shouldn't be NULL
1323                 return NDIS_STATUS_FAILURE;
1324         }
1325
1326         // Make sure MGMT ring resource won't be used by other threads
1327         //NdisAcquireSpinLock(&pAd->TxRingLock);
1328
1329         FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
1330
1331         if (FreeNum == 0)
1332         {
1333                 //NdisReleaseSpinLock(&pAd->TxRingLock);
1334                 return NDIS_STATUS_FAILURE;
1335         }
1336
1337         SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
1338
1339 #ifndef RT_BIG_ENDIAN
1340         pTxD  = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa;
1341 #else
1342     pDestTxD  = (PTXD_STRUC)pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa;
1343     TxD = *pDestTxD;
1344     pTxD = &TxD;
1345     RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1346 #endif
1347
1348         if (pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket)
1349         {
1350                 DBGPRINT(RT_DEBUG_OFF, ("MlmeHardTransmit Error\n"));
1351                 //NdisReleaseSpinLock(&pAd->TxRingLock);
1352                 return NDIS_STATUS_FAILURE;
1353         }
1354
1355
1356 #ifdef CONFIG_STA_SUPPORT
1357         IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1358         {
1359                 // outgoing frame always wakeup PHY to prevent frame lost
1360                 // if (pAd->StaCfg.Psm == PWR_SAVE)
1361                 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
1362                         AsicForceWakeup(pAd, TRUE);
1363         }
1364 #endif // CONFIG_STA_SUPPORT //
1365         pFirstTxWI      =(PTXWI_STRUC)pSrcBufVA;
1366
1367         pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXWI_SIZE);
1368         if (pHeader_802_11->Addr1[0] & 0x01)
1369         {
1370                 MlmeRate = pAd->CommonCfg.BasicMlmeRate;
1371         }
1372         else
1373         {
1374                 MlmeRate = pAd->CommonCfg.MlmeRate;
1375         }
1376
1377         if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
1378                 (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))
1379         {
1380                 pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
1381         }
1382
1383         // Verify Mlme rate for a / g bands.
1384         if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band
1385                 MlmeRate = RATE_6;
1386
1387         //
1388         // Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)
1389         // Snice it's been set to 0 while on MgtMacHeaderInit
1390         // By the way this will cause frame to be send on PWR_SAVE failed.
1391         //
1392         //
1393         // In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
1394 #ifdef CONFIG_STA_SUPPORT
1395     // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
1396         if (pHeader_802_11->FC.Type != BTYPE_DATA)
1397     {
1398         if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) || !(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
1399         {
1400                 pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
1401         }
1402         else
1403         {
1404                 pHeader_802_11->FC.PwrMgmt = pAd->CommonCfg.bAPSDForcePowerSave;
1405         }
1406     }
1407 #endif // CONFIG_STA_SUPPORT //
1408
1409         bInsertTimestamp = FALSE;
1410         if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
1411         {
1412                 bAckRequired = FALSE;
1413         }
1414         else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
1415         {
1416                 if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
1417                 {
1418                         bAckRequired = FALSE;
1419                         pHeader_802_11->Duration = 0;
1420                 }
1421                 else
1422                 {
1423                         bAckRequired = TRUE;
1424                         pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
1425                         if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
1426                         {
1427                                 bInsertTimestamp = TRUE;
1428                         }
1429                 }
1430         }
1431         pHeader_802_11->Sequence = pAd->Sequence++;
1432         if (pAd->Sequence > 0xfff)
1433                 pAd->Sequence = 0;
1434         // Before radar detection done, mgmt frame can not be sent but probe req
1435         // Because we need to use probe req to trigger driver to send probe req in passive scan
1436         if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
1437                 && (pAd->CommonCfg.bIEEE80211H == 1)
1438                 && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
1439         {
1440                 DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
1441                 //NdisReleaseSpinLock(&pAd->TxRingLock);
1442                 return (NDIS_STATUS_FAILURE);
1443         }
1444
1445 #ifdef RT_BIG_ENDIAN
1446         RTMPFrameEndianChange(pAd, (PUCHAR)pHeader_802_11, DIR_WRITE, FALSE);
1447 #endif
1448         //
1449         // fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
1450         // should always has only one ohysical buffer, and the whole frame size equals
1451         // to the first scatter buffer size
1452         //
1453
1454         // Initialize TX Descriptor
1455         // For inter-frame gap, the number is for this frame and next frame
1456         // For MLME rate, we will fix as 2Mb to match other vendor's implement
1457 //      pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
1458
1459 // management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
1460         // Only beacon use Nseq=TRUE. So here we use Nseq=FALSE.
1461         if (pMacEntry == NULL)
1462         {
1463         RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
1464                 0, RESERVED_WCID, (SrcBufLen - TXWI_SIZE), PID_MGMT, 0,  (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
1465         }
1466         else
1467         {
1468                 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
1469                                         bInsertTimestamp, FALSE, bAckRequired, FALSE,
1470                                         0, pMacEntry->Aid, (SrcBufLen - TXWI_SIZE),
1471                                         pMacEntry->MaxHTPhyMode.field.MCS, 0,
1472                                         (UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
1473                                         IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
1474         }
1475
1476         pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket = pPacket;
1477         pAd->TxRing[QueIdx].Cell[SwIdx].pNextNdisPacket = NULL;
1478 //      pFirstTxWI->MPDUtotalByteCount = SrcBufLen - TXWI_SIZE;
1479 #ifdef RT_BIG_ENDIAN
1480         RTMPWIEndianChange((PUCHAR)pFirstTxWI, TYPE_TXWI);
1481 #endif
1482         SrcBufPA = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
1483
1484
1485         RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_EDCA);
1486         pTxD->LastSec0 = 1;
1487         pTxD->LastSec1 = 1;
1488         pTxD->SDLen0 = SrcBufLen;
1489         pTxD->SDLen1 = 0;
1490         pTxD->SDPtr0 = SrcBufPA;
1491         pTxD->DMADONE = 0;
1492
1493 #ifdef RT_BIG_ENDIAN
1494     RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1495     WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
1496 #endif
1497
1498         pAd->RalinkCounters.KickTxCount++;
1499         pAd->RalinkCounters.OneSecTxDoneCount++;
1500
1501         // Increase TX_CTX_IDX, but write to register later.
1502         INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE);
1503
1504         RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx*0x10,  pAd->TxRing[QueIdx].TxCpuIdx);
1505
1506         // Make sure to release MGMT ring resource
1507 //      NdisReleaseSpinLock(&pAd->TxRingLock);
1508
1509         return NDIS_STATUS_SUCCESS;
1510 }
1511
1512
1513 NDIS_STATUS MlmeDataHardTransmit(
1514         IN      PRTMP_ADAPTER   pAd,
1515         IN      UCHAR   QueIdx,
1516         IN      PNDIS_PACKET    pPacket)
1517 {
1518         if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
1519                 )
1520         {
1521                 return NDIS_STATUS_FAILURE;
1522         }
1523
1524         return MlmeHardTransmitTxRing(pAd,QueIdx,pPacket);
1525 }
1526
1527
1528 /*
1529         ========================================================================
1530
1531         Routine Description:
1532                 Calculates the duration which is required to transmit out frames
1533         with given size and specified rate.
1534
1535         Arguments:
1536                 pTxD            Pointer to transmit descriptor
1537                 Ack             Setting for Ack requirement bit
1538                 Fragment        Setting for Fragment bit
1539                 RetryMode       Setting for retry mode
1540                 Ifs             Setting for IFS gap
1541                 Rate            Setting for transmit rate
1542                 Service         Setting for service
1543                 Length          Frame length
1544                 TxPreamble      Short or Long preamble when using CCK rates
1545                 QueIdx - 0-3, according to 802.11e/d4.4 June/2003
1546
1547         Return Value:
1548                 None
1549
1550         IRQL = PASSIVE_LEVEL
1551         IRQL = DISPATCH_LEVEL
1552
1553         ========================================================================
1554 */
1555 VOID RTMPWriteTxDescriptor(
1556         IN      PRTMP_ADAPTER   pAd,
1557         IN      PTXD_STRUC              pTxD,
1558         IN      BOOLEAN                 bWIV,
1559         IN      UCHAR                   QueueSEL)
1560 {
1561         //
1562         // Always use Long preamble before verifiation short preamble functionality works well.
1563         // Todo: remove the following line if short preamble functionality works
1564         //
1565         OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1566
1567         pTxD->WIV       = (bWIV) ? 1: 0;
1568         pTxD->QSEL= (QueueSEL);
1569         //RT2860c??  fixed using EDCA queue for test...  We doubt Queue1 has problem.  2006-09-26 Jan
1570         //pTxD->QSEL= FIFO_EDCA;
1571         /*
1572         if (pAd->bGenOneHCCA == TRUE)
1573                 pTxD->QSEL= FIFO_HCCA;
1574         */
1575         pTxD->DMADONE = 0;
1576 }