Staging: rt28x0: run common/*.c files through Lindent
[sfrench/cifs-2.6.git] / drivers / staging / rt2860 / 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 USHORT RtmpPCI_WriteTxResource(IN PRTMP_ADAPTER pAd,
36                                IN TX_BLK * pTxBlk,
37                                IN BOOLEAN bIsLast, OUT USHORT * FreeNumber)
38 {
39
40         UCHAR *pDMAHeaderBufVA;
41         USHORT TxIdx, RetTxIdx;
42         PTXD_STRUC pTxD;
43         UINT32 BufBasePaLow;
44         PRTMP_TX_RING pTxRing;
45         USHORT hwHeaderLen;
46
47         //
48         // get Tx Ring Resource
49         //
50         pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
51         TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
52         pDMAHeaderBufVA = (PUCHAR) 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 = (PTXD_STRUC) 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 USHORT RtmpPCI_WriteSingleTxResource(IN PRTMP_ADAPTER pAd,
101                                      IN TX_BLK * pTxBlk,
102                                      IN BOOLEAN bIsLast,
103                                      OUT USHORT * FreeNumber)
104 {
105
106         UCHAR *pDMAHeaderBufVA;
107         USHORT TxIdx, RetTxIdx;
108         PTXD_STRUC pTxD;
109         UINT32 BufBasePaLow;
110         PRTMP_TX_RING pTxRing;
111         USHORT hwHeaderLen;
112
113         //
114         // get Tx Ring Resource
115         //
116         pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
117         TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
118         pDMAHeaderBufVA = (PUCHAR) 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 = (PTXD_STRUC) 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 USHORT RtmpPCI_WriteMultiTxResource(IN PRTMP_ADAPTER pAd,
160                                     IN TX_BLK * pTxBlk,
161                                     IN UCHAR frameNum, OUT USHORT * FreeNumber)
162 {
163         BOOLEAN bIsLast;
164         UCHAR *pDMAHeaderBufVA;
165         USHORT TxIdx, RetTxIdx;
166         PTXD_STRUC pTxD;
167         UINT32 BufBasePaLow;
168         PRTMP_TX_RING pTxRing;
169         USHORT hwHdrLen;
170         UINT32 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 = (PUCHAR) 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 = (PTXD_STRUC) 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(IN PRTMP_ADAPTER pAd,
239                                   IN TX_BLK * pTxBlk,
240                                   IN USHORT totalMPDUSize, IN USHORT FirstTxIdx)
241 {
242
243         PTXWI_STRUC pTxWI;
244         PRTMP_TX_RING pTxRing;
245
246         //
247         // get Tx Ring Resource
248         //
249         pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
250         pTxWI = (PTXWI_STRUC) pTxRing->Cell[FirstTxIdx].DmaBuf.AllocVa;
251         pTxWI->MPDUtotalByteCount = totalMPDUSize;
252
253 }
254
255 VOID RtmpPCIDataLastTxIdx(IN PRTMP_ADAPTER pAd,
256                           IN UCHAR QueIdx, IN USHORT LastTxIdx)
257 {
258         PTXD_STRUC pTxD;
259         PRTMP_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 = (PTXD_STRUC) pTxRing->Cell[LastTxIdx].AllocVa;
270
271         pTxD->LastSec1 = 1;
272
273 }
274
275 USHORT RtmpPCI_WriteFragTxResource(IN PRTMP_ADAPTER pAd,
276                                    IN TX_BLK * pTxBlk,
277                                    IN UCHAR fragNum, OUT USHORT * FreeNumber)
278 {
279         UCHAR *pDMAHeaderBufVA;
280         USHORT TxIdx, RetTxIdx;
281         PTXD_STRUC pTxD;
282         UINT32 BufBasePaLow;
283         PRTMP_TX_RING pTxRing;
284         USHORT hwHeaderLen;
285         UINT32 firstDMALen;
286
287         //
288         // Get Tx Ring Resource
289         //
290         pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
291         TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
292         pDMAHeaderBufVA = (PUCHAR) 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 = (PTXD_STRUC) 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(IN RTMP_ADAPTER * pAd,
345                        IN UCHAR QueIdx,
346                        IN PNDIS_PACKET pPacket,
347                        IN PUCHAR pSrcBufVA, IN UINT SrcBufLen)
348 {
349         PTXD_STRUC pTxD;
350         ULONG SwIdx = pAd->MgmtRing.TxCpuIdx;
351
352         pTxD = (PTXD_STRUC) 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 NDIS_STATUS RTMPCheckRxError(IN PRTMP_ADAPTER pAd,
409                              IN PHEADER_802_11 pHeader,
410                              IN PRXWI_STRUC pRxWI, IN PRT28XX_RXD_STRUC pRxD)
411 {
412         PCIPHER_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 promiscous 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, cant's 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(IN PRTMP_ADAPTER pAd, IN UCHAR QueIdx)
520 {
521         PRTMP_TX_RING pTxRing;
522         PTXD_STRUC pTxD;
523         PNDIS_PACKET pPacket;
524         UCHAR FREE = 0;
525         TXD_STRUC TxD, *pOriTxD;
526         //ULONG         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                     (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
545                 pOriTxD = pTxD;
546                 NdisMoveMemory(&TxD, pTxD, sizeof(TXD_STRUC));
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(TXD_STRUC));
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(IN PRTMP_ADAPTER pAd,
613                                          IN INT_SOURCE_CSR_STRUC TxRingBitmap)
614 {
615 //      UCHAR                   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(IN PRTMP_ADAPTER pAd)
665 {
666         PTXD_STRUC pTxD;
667         PNDIS_PACKET pPacket;
668 //      int              i;
669         UCHAR FREE = 0;
670         PRTMP_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                     (PTXD_STRUC) (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(IN PRTMP_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(IN PRTMP_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(IN PRTMP_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 PNDIS_PACKET GetPacketFromRxRing(IN PRTMP_ADAPTER pAd,
777                                  OUT PRT28XX_RXD_STRUC pSaveRxD,
778                                  OUT BOOLEAN * pbReschedule,
779                                  IN OUT UINT32 * pRxPending)
780 {
781         PRXD_STRUC pRxD;
782         PNDIS_PACKET pRxPacket = NULL;
783         PNDIS_PACKET pNewPacket;
784         PVOID AllocVa;
785         NDIS_PHYSICAL_ADDRESS AllocPa;
786         BOOLEAN bReschedule = FALSE;
787         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 = (PRXD_STRUC) 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 = (PNDIS_PACKET) 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 NDIS_STATUS MlmeHardTransmitTxRing(IN PRTMP_ADAPTER pAd,
868                                    IN UCHAR QueIdx, IN PNDIS_PACKET pPacket)
869 {
870         PACKET_INFO PacketInfo;
871         PUCHAR pSrcBufVA;
872         UINT SrcBufLen;
873         PTXD_STRUC pTxD;
874         PHEADER_802_11 pHeader_802_11;
875         BOOLEAN bAckRequired, bInsertTimestamp;
876         ULONG SrcBufPA;
877         //UCHAR                 TxBufIdx;
878         UCHAR MlmeRate;
879         ULONG SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
880         PTXWI_STRUC pFirstTxWI;
881         //ULONG i;
882         //HTTRANSMIT_SETTING    MlmeTransmit;   //Rate for this MGMT frame.
883         ULONG FreeNum;
884         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 = (PTXD_STRUC) 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 = (PTXWI_STRUC) pSrcBufVA;
919
920         pHeader_802_11 = (PHEADER_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 alse 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                               (UCHAR) 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                               (UCHAR) 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 NDIS_STATUS MlmeDataHardTransmit(IN PRTMP_ADAPTER pAd,
1044                                  IN UCHAR QueIdx, IN PNDIS_PACKET 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(IN PRTMP_ADAPTER pAd,
1082                            IN PTXD_STRUC pTxD,
1083                            IN BOOLEAN bWIV, IN UCHAR 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 }