]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - drivers/staging/rt2860/common/cmm_data_pci.c
Fix common misspellings
[mirror_ubuntu-zesty-kernel.git] / drivers / staging / rt2860 / common / cmm_data_pci.c
CommitLineData
ca97b838
BZ
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
62eb734b
BZ
35u16 RtmpPCI_WriteTxResource(struct rt_rtmp_adapter *pAd,
36 struct rt_tx_blk *pTxBlk,
51126deb 37 IN BOOLEAN bIsLast, u16 * FreeNumber)
ca97b838
BZ
38{
39
51126deb
BZ
40 u8 *pDMAHeaderBufVA;
41 u16 TxIdx, RetTxIdx;
62eb734b 42 struct rt_txd * pTxD;
51126deb 43 u32 BufBasePaLow;
62eb734b 44 struct rt_rtmp_tx_ring *pTxRing;
51126deb 45 u16 hwHeaderLen;
ca97b838 46
ec278fa2
BZ
47 /* */
48 /* get Tx Ring Resource */
49 /* */
ca97b838
BZ
50 pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
51 TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
51126deb 52 pDMAHeaderBufVA = (u8 *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
96b3c83d
BZ
53 BufBasePaLow =
54 RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
ca97b838 55
ec278fa2 56 /* copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */
96b3c83d 57 if (pTxBlk->TxFrameType == TX_AMSDU_FRAME) {
ec278fa2 58 /*hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD; */
96b3c83d
BZ
59 hwHeaderLen =
60 pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD +
61 pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
62 } else {
ec278fa2 63 /*hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
ca97b838
BZ
64 hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
65 }
96b3c83d
BZ
66 NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf,
67 TXINFO_SIZE + TXWI_SIZE + hwHeaderLen);
ca97b838
BZ
68
69 pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
70 pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
71
ec278fa2
BZ
72 /* */
73 /* build Tx Descriptor */
74 /* */
ca97b838 75
62eb734b 76 pTxD = (struct rt_txd *) pTxRing->Cell[TxIdx].AllocVa;
ca97b838
BZ
77 NdisZeroMemory(pTxD, TXD_SIZE);
78
79 pTxD->SDPtr0 = BufBasePaLow;
ec278fa2 80 pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; /* include padding */
ca97b838
BZ
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;
ec278fa2
BZ
89 /* */
90 /* Update Tx index */
91 /* */
ca97b838
BZ
92 INC_RING_INDEX(TxIdx, TX_RING_SIZE);
93 pTxRing->TxCpuIdx = TxIdx;
94
95 *FreeNumber -= 1;
96
97 return RetTxIdx;
98}
99
62eb734b
BZ
100u16 RtmpPCI_WriteSingleTxResource(struct rt_rtmp_adapter *pAd,
101 struct rt_tx_blk *pTxBlk,
96b3c83d 102 IN BOOLEAN bIsLast,
51126deb 103 u16 * FreeNumber)
ca97b838
BZ
104{
105
51126deb
BZ
106 u8 *pDMAHeaderBufVA;
107 u16 TxIdx, RetTxIdx;
62eb734b 108 struct rt_txd * pTxD;
51126deb 109 u32 BufBasePaLow;
62eb734b 110 struct rt_rtmp_tx_ring *pTxRing;
51126deb 111 u16 hwHeaderLen;
ca97b838 112
ec278fa2
BZ
113 /* */
114 /* get Tx Ring Resource */
115 /* */
ca97b838
BZ
116 pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
117 TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
51126deb 118 pDMAHeaderBufVA = (u8 *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
96b3c83d
BZ
119 BufBasePaLow =
120 RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
ca97b838 121
ec278fa2
BZ
122 /* copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */
123 /*hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
ca97b838
BZ
124 hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
125
96b3c83d
BZ
126 NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf,
127 TXINFO_SIZE + TXWI_SIZE + hwHeaderLen);
ca97b838
BZ
128
129 pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
130 pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
131
ec278fa2
BZ
132 /* */
133 /* build Tx Descriptor */
134 /* */
62eb734b 135 pTxD = (struct rt_txd *) pTxRing->Cell[TxIdx].AllocVa;
ca97b838
BZ
136 NdisZeroMemory(pTxD, TXD_SIZE);
137
138 pTxD->SDPtr0 = BufBasePaLow;
ec278fa2 139 pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; /* include padding */
859171ca 140 pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
ca97b838
BZ
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;
ec278fa2
BZ
148 /* */
149 /* Update Tx index */
150 /* */
ca97b838
BZ
151 INC_RING_INDEX(TxIdx, TX_RING_SIZE);
152 pTxRing->TxCpuIdx = TxIdx;
153
154 *FreeNumber -= 1;
155
156 return RetTxIdx;
157}
158
62eb734b
BZ
159u16 RtmpPCI_WriteMultiTxResource(struct rt_rtmp_adapter *pAd,
160 struct rt_tx_blk *pTxBlk,
51126deb 161 u8 frameNum, u16 * FreeNumber)
ca97b838
BZ
162{
163 BOOLEAN bIsLast;
51126deb
BZ
164 u8 *pDMAHeaderBufVA;
165 u16 TxIdx, RetTxIdx;
62eb734b 166 struct rt_txd * pTxD;
51126deb 167 u32 BufBasePaLow;
62eb734b 168 struct rt_rtmp_tx_ring *pTxRing;
51126deb
BZ
169 u16 hwHdrLen;
170 u32 firstDMALen;
ca97b838
BZ
171
172 bIsLast = ((frameNum == (pTxBlk->TotalFrameNum - 1)) ? 1 : 0);
173
ec278fa2
BZ
174 /* */
175 /* get Tx Ring Resource */
176 /* */
ca97b838
BZ
177 pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
178 TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
51126deb 179 pDMAHeaderBufVA = (u8 *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
96b3c83d
BZ
180 BufBasePaLow =
181 RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
ca97b838 182
96b3c83d 183 if (frameNum == 0) {
ec278fa2 184 /* copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */
ca97b838 185 if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
ec278fa2 186 /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD; */
96b3c83d
BZ
187 hwHdrLen =
188 pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD +
189 pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
ca97b838 190 else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)
ec278fa2 191 /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD; */
96b3c83d
BZ
192 hwHdrLen =
193 pTxBlk->MpduHeaderLen -
194 LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen +
195 LENGTH_ARALINK_HEADER_FIELD;
ca97b838 196 else
ec278fa2 197 /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
ca97b838
BZ
198 hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
199
200 firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;
96b3c83d 201 } else {
ca97b838
BZ
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
ec278fa2
BZ
210 /* */
211 /* build Tx Descriptor */
212 /* */
62eb734b 213 pTxD = (struct rt_txd *) pTxRing->Cell[TxIdx].AllocVa;
ca97b838
BZ
214 NdisZeroMemory(pTxD, TXD_SIZE);
215
216 pTxD->SDPtr0 = BufBasePaLow;
ec278fa2 217 pTxD->SDLen0 = firstDMALen; /* include padding */
859171ca 218 pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
ca97b838
BZ
219 pTxD->SDLen1 = pTxBlk->SrcBufLen;
220 pTxD->LastSec0 = 0;
221 pTxD->LastSec1 = (bIsLast) ? 1 : 0;
222
223 RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
224
ca97b838 225 RetTxIdx = TxIdx;
ec278fa2
BZ
226 /* */
227 /* Update Tx index */
228 /* */
ca97b838
BZ
229 INC_RING_INDEX(TxIdx, TX_RING_SIZE);
230 pTxRing->TxCpuIdx = TxIdx;
231
232 *FreeNumber -= 1;
233
234 return RetTxIdx;
235
236}
237
62eb734b
BZ
238void RtmpPCI_FinalWriteTxResource(struct rt_rtmp_adapter *pAd,
239 struct rt_tx_blk *pTxBlk,
51126deb 240 u16 totalMPDUSize, u16 FirstTxIdx)
ca97b838
BZ
241{
242
62eb734b
BZ
243 struct rt_txwi * pTxWI;
244 struct rt_rtmp_tx_ring *pTxRing;
ca97b838 245
ec278fa2
BZ
246 /* */
247 /* get Tx Ring Resource */
248 /* */
ca97b838 249 pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
62eb734b 250 pTxWI = (struct rt_txwi *) pTxRing->Cell[FirstTxIdx].DmaBuf.AllocVa;
ca97b838
BZ
251 pTxWI->MPDUtotalByteCount = totalMPDUSize;
252
253}
254
62eb734b 255void RtmpPCIDataLastTxIdx(struct rt_rtmp_adapter *pAd,
51126deb 256 u8 QueIdx, u16 LastTxIdx)
ca97b838 257{
62eb734b
BZ
258 struct rt_txd * pTxD;
259 struct rt_rtmp_tx_ring *pTxRing;
ca97b838 260
ec278fa2
BZ
261 /* */
262 /* get Tx Ring Resource */
263 /* */
ca97b838
BZ
264 pTxRing = &pAd->TxRing[QueIdx];
265
ec278fa2
BZ
266 /* */
267 /* build Tx Descriptor */
268 /* */
62eb734b 269 pTxD = (struct rt_txd *) pTxRing->Cell[LastTxIdx].AllocVa;
ca97b838
BZ
270
271 pTxD->LastSec1 = 1;
272
ca97b838
BZ
273}
274
62eb734b
BZ
275u16 RtmpPCI_WriteFragTxResource(struct rt_rtmp_adapter *pAd,
276 struct rt_tx_blk *pTxBlk,
51126deb 277 u8 fragNum, u16 * FreeNumber)
ca97b838 278{
51126deb
BZ
279 u8 *pDMAHeaderBufVA;
280 u16 TxIdx, RetTxIdx;
62eb734b 281 struct rt_txd * pTxD;
51126deb 282 u32 BufBasePaLow;
62eb734b 283 struct rt_rtmp_tx_ring *pTxRing;
51126deb
BZ
284 u16 hwHeaderLen;
285 u32 firstDMALen;
ca97b838 286
ec278fa2
BZ
287 /* */
288 /* Get Tx Ring Resource */
289 /* */
ca97b838
BZ
290 pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
291 TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
51126deb 292 pDMAHeaderBufVA = (u8 *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
96b3c83d
BZ
293 BufBasePaLow =
294 RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
ca97b838 295
ec278fa2
BZ
296 /* */
297 /* Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */
298 /* */
299 /*hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
ca97b838
BZ
300 hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
301
302 firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen;
303 NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen);
304
ec278fa2
BZ
305 /* */
306 /* Build Tx Descriptor */
307 /* */
62eb734b 308 pTxD = (struct rt_txd *) pTxRing->Cell[TxIdx].AllocVa;
ca97b838
BZ
309 NdisZeroMemory(pTxD, TXD_SIZE);
310
96b3c83d 311 if (fragNum == pTxBlk->TotalFragNum) {
ca97b838
BZ
312 pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
313 pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
314 }
315
316 pTxD->SDPtr0 = BufBasePaLow;
ec278fa2 317 pTxD->SDLen0 = firstDMALen; /* include padding */
ca97b838
BZ
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
ca97b838
BZ
325 RetTxIdx = TxIdx;
326 pTxBlk->Priv += pTxBlk->SrcBufLen;
327
ec278fa2
BZ
328 /* */
329 /* Update Tx index */
330 /* */
ca97b838
BZ
331 INC_RING_INDEX(TxIdx, TX_RING_SIZE);
332 pTxRing->TxCpuIdx = TxIdx;
333
334 *FreeNumber -= 1;
335
336 return RetTxIdx;
337
338}
339
ca97b838
BZ
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 */
62eb734b 344int RtmpPCIMgmtKickOut(struct rt_rtmp_adapter *pAd,
51126deb 345 u8 QueIdx,
8a10a546 346 void *pPacket,
51126deb 347 u8 *pSrcBufVA, u32 SrcBufLen)
ca97b838 348{
62eb734b 349 struct rt_txd * pTxD;
51126deb 350 unsigned long SwIdx = pAd->MgmtRing.TxCpuIdx;
ca97b838 351
62eb734b 352 pTxD = (struct rt_txd *) pAd->MgmtRing.Cell[SwIdx].AllocVa;
ca97b838
BZ
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;
96b3c83d
BZ
362 pTxD->SDPtr0 =
363 PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
ca97b838
BZ
364 pTxD->SDLen0 = SrcBufLen;
365
ec278fa2 366/*================================================================== */
ca97b838
BZ
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 "));*/
ec278fa2 378/*======================================================================= */
ca97b838
BZ
379
380 pAd->RalinkCounters.KickTxCount++;
381 pAd->RalinkCounters.OneSecTxDoneCount++;
382
ec278fa2 383 /* Increase TX_CTX_IDX, but write to register later. */
ca97b838
BZ
384 INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
385
96b3c83d 386 RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx);
ca97b838
BZ
387
388 return 0;
389}
390
ca97b838
BZ
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*/
62eb734b
BZ
408int RTMPCheckRxError(struct rt_rtmp_adapter *pAd,
409 struct rt_header_802_11 * pHeader,
410 struct rt_rxwi * pRxWI, IN PRT28XX_RXD_STRUC pRxD)
ca97b838 411{
62eb734b 412 struct rt_cipher_key *pWpaKey;
51126deb 413 int dBm;
ca97b838 414
ec278fa2 415 /* Phy errors & CRC errors */
96b3c83d 416 if ( /*(pRxD->PhyErr) || */ (pRxD->Crc)) {
ec278fa2 417 /* Check RSSI for Noise Hist statistic collection. */
51126deb 418 dBm = (int)(pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta;
ca97b838
BZ
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
96b3c83d 436 return (NDIS_STATUS_FAILURE);
ca97b838 437 }
ec278fa2 438 /* Add Rx size to channel load counter, we should ignore error counts */
ca97b838
BZ
439 pAd->StaCfg.CLBusyBytes += (pRxD->SDL0 + 14);
440
25985edc 441 /* Drop ToDs promiscuous frame, it is opened due to CCX 2 channel load statistics */
96b3c83d
BZ
442 if (pHeader != NULL) {
443 if (pHeader->FC.ToDs) {
444 return (NDIS_STATUS_FAILURE);
ca97b838
BZ
445 }
446 }
25985edc 447 /* Drop not U2M frames, can't's drop here because we will drop beacon in this case */
ec278fa2
BZ
448 /* I am kind of doubting the U2M bit operation */
449 /* if (pRxD->U2M == 0) */
450 /* return(NDIS_STATUS_FAILURE); */
ca97b838 451
ec278fa2 452 /* drop decyption fail frame */
96b3c83d
BZ
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,
ec278fa2 474/* CipherName[pRxD->CipherAlg], */
96b3c83d 475 pRxWI->KeyIndex));
ca97b838 476
ec278fa2
BZ
477 /* */
478 /* MIC Error */
479 /* */
96b3c83d 480 if (pRxD->CipherErr == 2) {
ca97b838 481 pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
96b3c83d
BZ
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"));
ca97b838
BZ
500 }
501
502 if (pHeader == NULL)
96b3c83d 503 return (NDIS_STATUS_SUCCESS);
ca97b838 504 /*if ((pRxD->CipherAlg == CIPHER_AES) &&
96b3c83d
BZ
505 (pHeader->Sequence == pAd->FragFrame.Sequence))
506 {
507 //
508 // Acceptable since the First FragFrame no CipherErr problem.
509 //
510 return(NDIS_STATUS_SUCCESS);
511 } */
ca97b838 512
96b3c83d 513 return (NDIS_STATUS_FAILURE);
ca97b838
BZ
514 }
515
96b3c83d 516 return (NDIS_STATUS_SUCCESS);
ca97b838
BZ
517}
518
62eb734b 519BOOLEAN RTMPFreeTXDUponTxDmaDone(struct rt_rtmp_adapter *pAd, u8 QueIdx)
ca97b838 520{
62eb734b
BZ
521 struct rt_rtmp_tx_ring *pTxRing;
522 struct rt_txd * pTxD;
8a10a546 523 void *pPacket;
51126deb 524 u8 FREE = 0;
62eb734b 525 struct rt_txd TxD, *pOriTxD;
51126deb 526 /*unsigned long IrqFlags; */
96b3c83d 527 BOOLEAN bReschedule = FALSE;
ca97b838
BZ
528
529 ASSERT(QueIdx < NUM_OF_TX_RING);
530 pTxRing = &pAd->TxRing[QueIdx];
531
96b3c83d
BZ
532 RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF,
533 &pTxRing->TxDmaIdx);
534 while (pTxRing->TxSwFreeIdx != pTxRing->TxDmaIdx) {
ec278fa2 535/* RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); */
ca97b838 536
ec278fa2
BZ
537 /* static rate also need NICUpdateFifoStaCounters() function. */
538 /*if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) */
96b3c83d 539 NICUpdateFifoStaCounters(pAd);
ca97b838
BZ
540
541 /* Note : If (pAd->ate.bQATxStart == TRUE), we will never reach here. */
542 FREE++;
96b3c83d 543 pTxD =
62eb734b 544 (struct rt_txd *) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
ca97b838 545 pOriTxD = pTxD;
62eb734b 546 NdisMoveMemory(&TxD, pTxD, sizeof(struct rt_txd));
ca97b838
BZ
547 pTxD = &TxD;
548
549 pTxD->DMADONE = 0;
550
ca97b838 551 {
96b3c83d
BZ
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);
ca97b838 560 }
ec278fa2 561 /*Always assign pNdisPacket as NULL after clear */
ca97b838
BZ
562 pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket = NULL;
563
96b3c83d
BZ
564 pPacket =
565 pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket;
ca97b838
BZ
566
567 ASSERT(pPacket == NULL);
96b3c83d
BZ
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);
ca97b838 574 }
ec278fa2 575 /*Always assign pNextNdisPacket as NULL after clear */
96b3c83d
BZ
576 pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket =
577 NULL;
ca97b838
BZ
578 }
579
96b3c83d
BZ
580 pAd->RalinkCounters.TransmittedByteCount +=
581 (pTxD->SDLen1 + pTxD->SDLen0);
582 pAd->RalinkCounters.OneSecDmaDoneCount[QueIdx]++;
ca97b838
BZ
583 INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE);
584 /* get tx_tdx_idx again */
96b3c83d
BZ
585 RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF,
586 &pTxRing->TxDmaIdx);
62eb734b 587 NdisMoveMemory(pOriTxD, pTxD, sizeof(struct rt_txd));
ca97b838 588
ec278fa2 589/* RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); */
ca97b838
BZ
590 }
591
96b3c83d 592 return bReschedule;
ca97b838
BZ
593
594}
595
ca97b838
BZ
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*/
62eb734b 612BOOLEAN RTMPHandleTxRingDmaDoneInterrupt(struct rt_rtmp_adapter *pAd,
51126deb 613 INT_SOURCE_CSR_STRUC TxRingBitmap)
ca97b838 614{
51126deb 615/* u8 Count = 0; */
96b3c83d
BZ
616 unsigned long IrqFlags;
617 BOOLEAN bReschedule = FALSE;
ca97b838 618
ec278fa2
BZ
619 /* Make sure Tx ring resource won't be used by other threads */
620 /*NdisAcquireSpinLock(&pAd->TxRingLock); */
ca97b838
BZ
621
622 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
623
624 if (TxRingBitmap.field.Ac0DmaDone)
625 bReschedule = RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BE);
626
ca97b838
BZ
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
ec278fa2
BZ
636 /* Make sure to release Tx ring resource */
637 /*NdisReleaseSpinLock(&pAd->TxRingLock); */
ca97b838
BZ
638 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
639
ec278fa2 640 /* Dequeue outgoing frames from TxSwQueue[] and process it */
ca97b838
BZ
641 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
642
96b3c83d 643 return bReschedule;
ca97b838
BZ
644}
645
ca97b838
BZ
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*/
62eb734b 664void RTMPHandleMgmtRingDmaDoneInterrupt(struct rt_rtmp_adapter *pAd)
ca97b838 665{
62eb734b 666 struct rt_txd * pTxD;
8a10a546 667 void *pPacket;
ec278fa2 668/* int i; */
51126deb 669 u8 FREE = 0;
62eb734b 670 struct rt_rtmp_mgmt_ring *pMgmtRing = &pAd->MgmtRing;
ca97b838
BZ
671
672 NdisAcquireSpinLock(&pAd->MgmtRingLock);
673
674 RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pMgmtRing->TxDmaIdx);
96b3c83d 675 while (pMgmtRing->TxSwFreeIdx != pMgmtRing->TxDmaIdx) {
ca97b838 676 FREE++;
96b3c83d 677 pTxD =
62eb734b 678 (struct rt_txd *) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].
96b3c83d 679 AllocVa);
ca97b838
BZ
680 pTxD->DMADONE = 0;
681 pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket;
682
96b3c83d
BZ
683 if (pPacket) {
684 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0,
685 PCI_DMA_TODEVICE);
ca97b838
BZ
686 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
687 }
688 pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket = NULL;
689
96b3c83d
BZ
690 pPacket =
691 pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket;
692 if (pPacket) {
693 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1,
694 PCI_DMA_TODEVICE);
ca97b838
BZ
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
ca97b838
BZ
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*/
62eb734b 716void RTMPHandleTBTTInterrupt(struct rt_rtmp_adapter *pAd)
ca97b838
BZ
717{
718 {
96b3c83d 719 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
ca97b838
BZ
720 }
721 }
722}
723
ca97b838
BZ
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*/
62eb734b 735void RTMPHandlePreTBTTInterrupt(struct rt_rtmp_adapter *pAd)
ca97b838
BZ
736{
737 {
96b3c83d
BZ
738 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
739 DBGPRINT(RT_DEBUG_TRACE,
740 ("RTMPHandlePreTBTTInterrupt...\n"));
ca97b838
BZ
741 }
742 }
743
ca97b838
BZ
744}
745
62eb734b 746void RTMPHandleRxCoherentInterrupt(struct rt_rtmp_adapter *pAd)
ca97b838 747{
96b3c83d 748 WPDMA_GLO_CFG_STRUC GloCfg;
ca97b838 749
96b3c83d 750 if (pAd == NULL) {
ca97b838
BZ
751 DBGPRINT(RT_DEBUG_TRACE, ("====> pAd is NULL, return.\n"));
752 return;
753 }
754
755 DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPHandleRxCoherentInterrupt \n"));
756
96b3c83d 757 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
ca97b838
BZ
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);
ca97b838
BZ
768 RTMPRingCleanUp(pAd, QID_MGMT);
769 RTMPRingCleanUp(pAd, QID_RX);
770
771 RTMPEnableRxTx(pAd);
772
773 DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPHandleRxCoherentInterrupt \n"));
774}
775
62eb734b 776void *GetPacketFromRxRing(struct rt_rtmp_adapter *pAd,
96b3c83d
BZ
777 OUT PRT28XX_RXD_STRUC pSaveRxD,
778 OUT BOOLEAN * pbReschedule,
51126deb 779 IN u32 * pRxPending)
ca97b838 780{
62eb734b 781 struct rt_rxd * pRxD;
8a10a546
BZ
782 void *pRxPacket = NULL;
783 void *pNewPacket;
51126deb 784 void *AllocVa;
8a10a546 785 dma_addr_t AllocPa;
96b3c83d 786 BOOLEAN bReschedule = FALSE;
62eb734b 787 struct rt_rtmp_dmacb *pRxCell;
ca97b838
BZ
788
789 RTMP_SEM_LOCK(&pAd->RxRingLock);
790
96b3c83d 791 if (*pRxPending == 0) {
ec278fa2 792 /* Get how may packets had been received */
96b3c83d 793 RTMP_IO_READ32(pAd, RX_DRX_IDX, &pAd->RxRing.RxDmaIdx);
ca97b838 794
96b3c83d 795 if (pAd->RxRing.RxSwReadIdx == pAd->RxRing.RxDmaIdx) {
ec278fa2 796 /* no more rx packets */
ca97b838
BZ
797 bReschedule = FALSE;
798 goto done;
799 }
ec278fa2 800 /* get rx pending count */
ca97b838 801 if (pAd->RxRing.RxDmaIdx > pAd->RxRing.RxSwReadIdx)
96b3c83d
BZ
802 *pRxPending =
803 pAd->RxRing.RxDmaIdx - pAd->RxRing.RxSwReadIdx;
ca97b838 804 else
96b3c83d
BZ
805 *pRxPending =
806 pAd->RxRing.RxDmaIdx + RX_RING_SIZE -
807 pAd->RxRing.RxSwReadIdx;
ca97b838
BZ
808
809 }
810
811 pRxCell = &pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx];
812
ec278fa2 813 /* Point to Rx indexed rx ring descriptor */
62eb734b 814 pRxD = (struct rt_rxd *) pRxCell->AllocVa;
ca97b838 815
96b3c83d 816 if (pRxD->DDONE == 0) {
ca97b838 817 *pRxPending = 0;
ec278fa2 818 /* DMAIndx had done but DDONE bit not ready */
ca97b838
BZ
819 bReschedule = TRUE;
820 goto done;
821 }
822
ec278fa2 823 /* return rx descriptor */
ca97b838
BZ
824 NdisMoveMemory(pSaveRxD, pRxD, RXD_SIZE);
825
96b3c83d
BZ
826 pNewPacket =
827 RTMP_AllocateRxPacketBuffer(pAd, RX_BUFFER_AGGRESIZE, FALSE,
828 &AllocVa, &AllocPa);
ca97b838 829
96b3c83d 830 if (pNewPacket) {
ec278fa2 831 /* unmap the rx buffer */
ca97b838 832 PCI_UNMAP_SINGLE(pAd, pRxCell->DmaBuf.AllocPa,
96b3c83d 833 pRxCell->DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
ca97b838
BZ
834 pRxPacket = pRxCell->pNdisPacket;
835
96b3c83d 836 pRxCell->DmaBuf.AllocSize = RX_BUFFER_AGGRESIZE;
8a10a546 837 pRxCell->pNdisPacket = (void *)pNewPacket;
96b3c83d
BZ
838 pRxCell->DmaBuf.AllocVa = AllocVa;
839 pRxCell->DmaBuf.AllocPa = AllocPa;
ca97b838
BZ
840 /* update SDP0 to new buffer of rx packet */
841 pRxD->SDP0 = AllocPa;
96b3c83d 842 } else {
ec278fa2 843 /*DBGPRINT(RT_DEBUG_TRACE,("No Rx Buffer\n")); */
ca97b838
BZ
844 pRxPacket = NULL;
845 bReschedule = TRUE;
846 }
847
848 pRxD->DDONE = 0;
849
ec278fa2 850 /* had handled one rx packet */
ca97b838
BZ
851 *pRxPending = *pRxPending - 1;
852
ec278fa2 853 /* update rx descriptor and kick rx */
ca97b838
BZ
854 INC_RING_INDEX(pAd->RxRing.RxSwReadIdx, RX_RING_SIZE);
855
96b3c83d
BZ
856 pAd->RxRing.RxCpuIdx =
857 (pAd->RxRing.RxSwReadIdx ==
858 0) ? (RX_RING_SIZE - 1) : (pAd->RxRing.RxSwReadIdx - 1);
ca97b838
BZ
859 RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
860
861done:
862 RTMP_SEM_UNLOCK(&pAd->RxRingLock);
863 *pbReschedule = bReschedule;
864 return pRxPacket;
865}
866
62eb734b 867int MlmeHardTransmitTxRing(struct rt_rtmp_adapter *pAd,
8a10a546 868 u8 QueIdx, void *pPacket)
ca97b838 869{
62eb734b 870 struct rt_packet_info PacketInfo;
51126deb
BZ
871 u8 *pSrcBufVA;
872 u32 SrcBufLen;
62eb734b
BZ
873 struct rt_txd * pTxD;
874 struct rt_header_802_11 * pHeader_802_11;
96b3c83d 875 BOOLEAN bAckRequired, bInsertTimestamp;
51126deb
BZ
876 unsigned long SrcBufPA;
877 /*u8 TxBufIdx; */
878 u8 MlmeRate;
879 unsigned long SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
62eb734b 880 struct rt_txwi * pFirstTxWI;
51126deb 881 /*unsigned long i; */
ec278fa2 882 /*HTTRANSMIT_SETTING MlmeTransmit; //Rate for this MGMT frame. */
51126deb 883 unsigned long FreeNum;
62eb734b 884 struct rt_mac_table_entry *pMacEntry = NULL;
ca97b838
BZ
885
886 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
887
96b3c83d 888 if (pSrcBufVA == NULL) {
ec278fa2 889 /* The buffer shouldn't be NULL */
ca97b838
BZ
890 return NDIS_STATUS_FAILURE;
891 }
ec278fa2
BZ
892 /* Make sure MGMT ring resource won't be used by other threads */
893 /*NdisAcquireSpinLock(&pAd->TxRingLock); */
ca97b838
BZ
894
895 FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
896
96b3c83d 897 if (FreeNum == 0) {
ec278fa2 898 /*NdisReleaseSpinLock(&pAd->TxRingLock); */
ca97b838
BZ
899 return NDIS_STATUS_FAILURE;
900 }
901
902 SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
903
62eb734b 904 pTxD = (struct rt_txd *) pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa;
ca97b838 905
96b3c83d 906 if (pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket) {
ca97b838 907 DBGPRINT(RT_DEBUG_OFF, ("MlmeHardTransmit Error\n"));
ec278fa2 908 /*NdisReleaseSpinLock(&pAd->TxRingLock); */
ca97b838
BZ
909 return NDIS_STATUS_FAILURE;
910 }
911
912 {
ec278fa2
BZ
913 /* outgoing frame always wakeup PHY to prevent frame lost */
914 /* if (pAd->StaCfg.Psm == PWR_SAVE) */
ca97b838
BZ
915 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
916 AsicForceWakeup(pAd, TRUE);
917 }
62eb734b 918 pFirstTxWI = (struct rt_txwi *) pSrcBufVA;
ca97b838 919
62eb734b 920 pHeader_802_11 = (struct rt_header_802_11 *) (pSrcBufVA + TXWI_SIZE);
96b3c83d 921 if (pHeader_802_11->Addr1[0] & 0x01) {
ca97b838 922 MlmeRate = pAd->CommonCfg.BasicMlmeRate;
96b3c83d 923 } else {
ca97b838
BZ
924 MlmeRate = pAd->CommonCfg.MlmeRate;
925 }
926
927 if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
96b3c83d 928 (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL)) {
ca97b838
BZ
929 pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
930 }
ec278fa2
BZ
931 /* Verify Mlme rate for a / g bands. */
932 if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) /* 11A band */
ca97b838
BZ
933 MlmeRate = RATE_6;
934
ec278fa2
BZ
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 */
25985edc 942 /* Data-Null packets also pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD */
96b3c83d
BZ
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 }
ca97b838 952 }
ca97b838
BZ
953
954 bInsertTimestamp = FALSE;
ec278fa2 955 if (pHeader_802_11->FC.Type == BTYPE_CNTL) /* must be PS-POLL */
ca97b838
BZ
956 {
957 bAckRequired = FALSE;
ec278fa2 958 } else /* BTYPE_MGMT or BTYPE_DATA(must be NULL frame) */
ca97b838 959 {
ec278fa2 960 if (pHeader_802_11->Addr1[0] & 0x01) /* MULTICAST, BROADCAST */
ca97b838
BZ
961 {
962 bAckRequired = FALSE;
963 pHeader_802_11->Duration = 0;
96b3c83d 964 } else {
ca97b838 965 bAckRequired = TRUE;
96b3c83d
BZ
966 pHeader_802_11->Duration =
967 RTMPCalcDuration(pAd, MlmeRate, 14);
968 if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP) {
ca97b838
BZ
969 bInsertTimestamp = TRUE;
970 }
971 }
972 }
973 pHeader_802_11->Sequence = pAd->Sequence++;
974 if (pAd->Sequence > 0xfff)
975 pAd->Sequence = 0;
ec278fa2
BZ
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 */
ca97b838 978 if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
96b3c83d
BZ
979 && (pAd->CommonCfg.bIEEE80211H == 1)
980 && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)) {
981 DBGPRINT(RT_DEBUG_ERROR,
06aea994 982 ("MlmeHardTransmit --> radar detect not in normal mode!\n"));
ec278fa2 983 /*NdisReleaseSpinLock(&pAd->TxRingLock); */
ca97b838
BZ
984 return (NDIS_STATUS_FAILURE);
985 }
ec278fa2
BZ
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. */
96b3c83d
BZ
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,
51126deb 1003 (u8)pAd->CommonCfg.MlmeTransmit.field.MCS,
96b3c83d
BZ
1004 IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
1005 } else {
ca97b838 1006 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
96b3c83d
BZ
1007 bInsertTimestamp, FALSE, bAckRequired, FALSE,
1008 0, pMacEntry->Aid, (SrcBufLen - TXWI_SIZE),
1009 pMacEntry->MaxHTPhyMode.field.MCS, 0,
51126deb 1010 (u8)pMacEntry->MaxHTPhyMode.field.MCS,
96b3c83d 1011 IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
ca97b838
BZ
1012 }
1013
1014 pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket = pPacket;
1015 pAd->TxRing[QueIdx].Cell[SwIdx].pNextNdisPacket = NULL;
ec278fa2 1016/* pFirstTxWI->MPDUtotalByteCount = SrcBufLen - TXWI_SIZE; */
96b3c83d
BZ
1017 SrcBufPA =
1018 PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
ca97b838
BZ
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
ca97b838
BZ
1028 pAd->RalinkCounters.KickTxCount++;
1029 pAd->RalinkCounters.OneSecTxDoneCount++;
1030
ec278fa2 1031 /* Increase TX_CTX_IDX, but write to register later. */
ca97b838
BZ
1032 INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE);
1033
96b3c83d
BZ
1034 RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx * 0x10,
1035 pAd->TxRing[QueIdx].TxCpuIdx);
ca97b838 1036
ec278fa2
BZ
1037 /* Make sure to release MGMT ring resource */
1038/* NdisReleaseSpinLock(&pAd->TxRingLock); */
ca97b838
BZ
1039
1040 return NDIS_STATUS_SUCCESS;
1041}
1042
62eb734b 1043int MlmeDataHardTransmit(struct rt_rtmp_adapter *pAd,
8a10a546 1044 u8 QueIdx, void *pPacket)
ca97b838
BZ
1045{
1046 if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
96b3c83d 1047 ) {
ca97b838
BZ
1048 return NDIS_STATUS_FAILURE;
1049 }
1050
96b3c83d 1051 return MlmeHardTransmitTxRing(pAd, QueIdx, pPacket);
ca97b838
BZ
1052}
1053
ca97b838
BZ
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*/
62eb734b
BZ
1081void RTMPWriteTxDescriptor(struct rt_rtmp_adapter *pAd,
1082 struct rt_txd * pTxD,
51126deb 1083 IN BOOLEAN bWIV, u8 QueueSEL)
ca97b838 1084{
ec278fa2
BZ
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 /* */
ca97b838
BZ
1089 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1090
96b3c83d
BZ
1091 pTxD->WIV = (bWIV) ? 1 : 0;
1092 pTxD->QSEL = (QueueSEL);
ec278fa2
BZ
1093 /*RT2860c?? fixed using EDCA queue for test... We doubt Queue1 has problem. 2006-09-26 Jan */
1094 /*pTxD->QSEL= FIFO_EDCA; */
ca97b838
BZ
1095 pTxD->DMADONE = 0;
1096}