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