]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/staging/rt2860/common/cmm_data_usb.c
Fix common misspellings
[mirror_ubuntu-bionic-kernel.git] / drivers / staging / rt2860 / common / cmm_data_usb.c
CommitLineData
c55519ff
GKH
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*/
ca97b838 27
c55519ff
GKH
28/*
29 All functions in this file must be USB-depended, or you should out your function
30 in other files.
31
32*/
ca97b838
BZ
33
34#ifdef RTMP_MAC_USB
35
ca97b838 36#include "../rt_config.h"
c55519ff 37
c55519ff
GKH
38/*
39 We can do copy the frame into pTxContext when match following conditions.
40 =>
41 =>
42 =>
43*/
62eb734b 44static inline int RtmpUSBCanDoWrite(struct rt_rtmp_adapter *pAd,
51126deb 45 u8 QueIdx,
62eb734b 46 struct rt_ht_tx_context *pHTTXContext)
c55519ff 47{
51126deb 48 int canWrite = NDIS_STATUS_RESOURCES;
96b3c83d
BZ
49
50 if (((pHTTXContext->CurWritePosition) <
51 pHTTXContext->NextBulkOutPosition)
52 && (pHTTXContext->CurWritePosition + LOCAL_TXBUF_SIZE) >
53 pHTTXContext->NextBulkOutPosition) {
54 DBGPRINT(RT_DEBUG_ERROR, ("RtmpUSBCanDoWrite c1!\n"));
55 RTUSB_SET_BULK_FLAG(pAd,
56 (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
57 } else if ((pHTTXContext->CurWritePosition == 8)
58 && (pHTTXContext->NextBulkOutPosition < LOCAL_TXBUF_SIZE)) {
59 DBGPRINT(RT_DEBUG_ERROR, ("RtmpUSBCanDoWrite c2!\n"));
60 RTUSB_SET_BULK_FLAG(pAd,
61 (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
62 } else if (pHTTXContext->bCurWriting == TRUE) {
63 DBGPRINT(RT_DEBUG_ERROR, ("RtmpUSBCanDoWrite c3!\n"));
64 } else {
c55519ff
GKH
65 canWrite = NDIS_STATUS_SUCCESS;
66 }
67
c55519ff
GKH
68 return canWrite;
69}
70
62eb734b
BZ
71u16 RtmpUSB_WriteSubTxResource(struct rt_rtmp_adapter *pAd,
72 struct rt_tx_blk *pTxBlk,
51126deb 73 IN BOOLEAN bIsLast, u16 * FreeNumber)
c55519ff
GKH
74{
75
ec278fa2 76 /* Dummy function. Should be removed in the future. */
c55519ff
GKH
77 return 0;
78
79}
80
62eb734b
BZ
81u16 RtmpUSB_WriteFragTxResource(struct rt_rtmp_adapter *pAd,
82 struct rt_tx_blk *pTxBlk,
51126deb 83 u8 fragNum, u16 * FreeNumber)
c55519ff 84{
62eb734b 85 struct rt_ht_tx_context *pHTTXContext;
51126deb
BZ
86 u16 hwHdrLen; /* The hwHdrLen consist of 802.11 header length plus the header padding length. */
87 u32 fillOffset;
62eb734b
BZ
88 struct rt_txinfo *pTxInfo;
89 struct rt_txwi *pTxWI;
51126deb
BZ
90 u8 *pWirelessPacket = NULL;
91 u8 QueIdx;
92 int Status;
96b3c83d 93 unsigned long IrqFlags;
51126deb 94 u32 USBDMApktLen = 0, DMAHdrLen, padding;
96b3c83d 95 BOOLEAN TxQLastRound = FALSE;
c55519ff 96
ec278fa2
BZ
97 /* */
98 /* get Tx Ring Resource & Dma Buffer address */
99 /* */
c55519ff 100 QueIdx = pTxBlk->QueIdx;
96b3c83d 101 pHTTXContext = &pAd->TxContext[QueIdx];
c55519ff
GKH
102
103 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
104
96b3c83d 105 pHTTXContext = &pAd->TxContext[QueIdx];
c55519ff
GKH
106 fillOffset = pHTTXContext->CurWritePosition;
107
96b3c83d 108 if (fragNum == 0) {
ec278fa2 109 /* Check if we have enough space for this bulk-out batch. */
c55519ff 110 Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
96b3c83d 111 if (Status == NDIS_STATUS_SUCCESS) {
c55519ff
GKH
112 pHTTXContext->bCurWriting = TRUE;
113
ec278fa2 114 /* Reserve space for 8 bytes padding. */
96b3c83d
BZ
115 if ((pHTTXContext->ENextBulkOutPosition ==
116 pHTTXContext->CurWritePosition)) {
c55519ff
GKH
117 pHTTXContext->ENextBulkOutPosition += 8;
118 pHTTXContext->CurWritePosition += 8;
119 fillOffset += 8;
120 }
121 pTxBlk->Priv = 0;
96b3c83d
BZ
122 pHTTXContext->CurWriteRealPos =
123 pHTTXContext->CurWritePosition;
124 } else {
125 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx],
126 IrqFlags);
127
128 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket,
129 NDIS_STATUS_FAILURE);
130 return (Status);
c55519ff 131 }
96b3c83d 132 } else {
ec278fa2 133 /* For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer. */
96b3c83d
BZ
134 Status =
135 ((pHTTXContext->bCurWriting ==
136 TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
137 if (Status == NDIS_STATUS_SUCCESS) {
c55519ff 138 fillOffset += pTxBlk->Priv;
96b3c83d
BZ
139 } else {
140 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx],
141 IrqFlags);
c55519ff 142
96b3c83d
BZ
143 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket,
144 NDIS_STATUS_FAILURE);
145 return (Status);
c55519ff
GKH
146 }
147 }
148
51126deb 149 NdisZeroMemory((u8 *)(&pTxBlk->HeaderBuf[0]), TXINFO_SIZE);
62eb734b
BZ
150 pTxInfo = (struct rt_txinfo *)(&pTxBlk->HeaderBuf[0]);
151 pTxWI = (struct rt_txwi *) (&pTxBlk->HeaderBuf[TXINFO_SIZE]);
c55519ff 152
96b3c83d
BZ
153 pWirelessPacket =
154 &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
c55519ff 155
ec278fa2
BZ
156 /* copy TXWI + WLAN Header + LLC into DMA Header Buffer */
157 /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
c55519ff
GKH
158 hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
159
ec278fa2 160 /* Build our URB for USBD */
c55519ff
GKH
161 DMAHdrLen = TXWI_SIZE + hwHdrLen;
162 USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
ec278fa2 163 padding = (4 - (USBDMApktLen % 4)) & 0x03; /* round up to 4 byte alignment */
c55519ff
GKH
164 USBDMApktLen += padding;
165
166 pTxBlk->Priv += (TXINFO_SIZE + USBDMApktLen);
167
ec278fa2 168 /* For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload */
51126deb 169 RTMPWriteTxInfo(pAd, pTxInfo, (u16)(USBDMApktLen), FALSE, FIFO_EDCA,
96b3c83d 170 FALSE /*NextValid */ , FALSE);
c55519ff 171
96b3c83d 172 if (fragNum == pTxBlk->TotalFragNum) {
c55519ff 173 pTxInfo->USBDMATxburst = 0;
96b3c83d
BZ
174 if ((pHTTXContext->CurWritePosition + pTxBlk->Priv + 3906) >
175 MAX_TXBULK_LIMIT) {
c55519ff
GKH
176 pTxInfo->SwUseLastRound = 1;
177 TxQLastRound = TRUE;
178 }
96b3c83d 179 } else {
c55519ff
GKH
180 pTxInfo->USBDMATxburst = 1;
181 }
182
96b3c83d
BZ
183 NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf,
184 TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
c55519ff
GKH
185 pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
186 pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
187
188 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
189
190 NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
191
ec278fa2 192 /* Zero the last padding. */
c55519ff
GKH
193 pWirelessPacket += pTxBlk->SrcBufLen;
194 NdisZeroMemory(pWirelessPacket, padding + 8);
195
96b3c83d 196 if (fragNum == pTxBlk->TotalFragNum) {
c55519ff
GKH
197 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
198
ec278fa2 199 /* Update the pHTTXContext->CurWritePosition. 3906 used to prevent the NextBulkOut is a A-RALINK/A-MSDU Frame. */
c55519ff
GKH
200 pHTTXContext->CurWritePosition += pTxBlk->Priv;
201 if (TxQLastRound == TRUE)
202 pHTTXContext->CurWritePosition = 8;
203 pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
204
ec278fa2 205 /* Finally, set bCurWriting as FALSE */
96b3c83d 206 pHTTXContext->bCurWriting = FALSE;
c55519ff
GKH
207
208 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
209
ec278fa2 210 /* succeed and release the skb buffer */
c55519ff
GKH
211 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
212 }
213
96b3c83d 214 return (Status);
c55519ff
GKH
215
216}
217
62eb734b
BZ
218u16 RtmpUSB_WriteSingleTxResource(struct rt_rtmp_adapter *pAd,
219 struct rt_tx_blk *pTxBlk,
96b3c83d 220 IN BOOLEAN bIsLast,
51126deb 221 u16 * FreeNumber)
c55519ff 222{
62eb734b 223 struct rt_ht_tx_context *pHTTXContext;
51126deb
BZ
224 u16 hwHdrLen;
225 u32 fillOffset;
62eb734b
BZ
226 struct rt_txinfo *pTxInfo;
227 struct rt_txwi *pTxWI;
51126deb
BZ
228 u8 *pWirelessPacket;
229 u8 QueIdx;
96b3c83d 230 unsigned long IrqFlags;
51126deb
BZ
231 int Status;
232 u32 USBDMApktLen = 0, DMAHdrLen, padding;
96b3c83d 233 BOOLEAN bTxQLastRound = FALSE;
c55519ff 234
ec278fa2
BZ
235 /* For USB, didn't need PCI_MAP_SINGLE() */
236 /*SrcBufPA = PCI_MAP_SINGLE(pAd, (char *) pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, PCI_DMA_TODEVICE); */
c55519ff 237
ec278fa2
BZ
238 /* */
239 /* get Tx Ring Resource & Dma Buffer address */
240 /* */
c55519ff
GKH
241 QueIdx = pTxBlk->QueIdx;
242
243 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
96b3c83d 244 pHTTXContext = &pAd->TxContext[QueIdx];
c55519ff
GKH
245 fillOffset = pHTTXContext->CurWritePosition;
246
ec278fa2 247 /* Check ring full. */
c55519ff 248 Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
96b3c83d 249 if (Status == NDIS_STATUS_SUCCESS) {
c55519ff
GKH
250 pHTTXContext->bCurWriting = TRUE;
251
62eb734b
BZ
252 pTxInfo = (struct rt_txinfo *)(&pTxBlk->HeaderBuf[0]);
253 pTxWI = (struct rt_txwi *) (&pTxBlk->HeaderBuf[TXINFO_SIZE]);
c55519ff 254
ec278fa2 255 /* Reserve space for 8 bytes padding. */
96b3c83d
BZ
256 if ((pHTTXContext->ENextBulkOutPosition ==
257 pHTTXContext->CurWritePosition)) {
c55519ff
GKH
258 pHTTXContext->ENextBulkOutPosition += 8;
259 pHTTXContext->CurWritePosition += 8;
260 fillOffset += 8;
261 }
262 pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
263
96b3c83d
BZ
264 pWirelessPacket =
265 &pHTTXContext->TransferBuffer->field.
266 WirelessPacket[fillOffset];
c55519ff 267
ec278fa2
BZ
268 /* copy TXWI + WLAN Header + LLC into DMA Header Buffer */
269 /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
c55519ff
GKH
270 hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
271
ec278fa2 272 /* Build our URB for USBD */
c55519ff
GKH
273 DMAHdrLen = TXWI_SIZE + hwHdrLen;
274 USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
ec278fa2 275 padding = (4 - (USBDMApktLen % 4)) & 0x03; /* round up to 4 byte alignment */
c55519ff
GKH
276 USBDMApktLen += padding;
277
278 pTxBlk->Priv = (TXINFO_SIZE + USBDMApktLen);
279
ec278fa2 280 /* For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload */
51126deb 281 RTMPWriteTxInfo(pAd, pTxInfo, (u16)(USBDMApktLen), FALSE,
96b3c83d 282 FIFO_EDCA, FALSE /*NextValid */ , FALSE);
c55519ff 283
96b3c83d
BZ
284 if ((pHTTXContext->CurWritePosition + 3906 + pTxBlk->Priv) >
285 MAX_TXBULK_LIMIT) {
c55519ff
GKH
286 pTxInfo->SwUseLastRound = 1;
287 bTxQLastRound = TRUE;
288 }
96b3c83d
BZ
289 NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf,
290 TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
c55519ff
GKH
291 pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
292
ec278fa2
BZ
293 /* We unlock it here to prevent the first 8 bytes maybe over-writed issue. */
294 /* 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxcontext. */
295 /* 2. An interrupt break our routine and handle bulk-out complete. */
296 /* 3. In the bulk-out compllete, it need to do another bulk-out, */
297 /* if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition, */
298 /* but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE. */
299 /* 4. Interrupt complete. */
300 /* 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext. */
301 /* 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition. */
302 /* and the packet will wrong. */
96b3c83d
BZ
303 pHTTXContext->CurWriteRealPos +=
304 (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
c55519ff
GKH
305 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
306
96b3c83d
BZ
307 NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData,
308 pTxBlk->SrcBufLen);
c55519ff
GKH
309 pWirelessPacket += pTxBlk->SrcBufLen;
310 NdisZeroMemory(pWirelessPacket, padding + 8);
311
312 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
313
314 pHTTXContext->CurWritePosition += pTxBlk->Priv;
315 if (bTxQLastRound)
316 pHTTXContext->CurWritePosition = 8;
317 pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
318
96b3c83d 319 pHTTXContext->bCurWriting = FALSE;
c55519ff
GKH
320 }
321
c55519ff
GKH
322 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
323
ec278fa2 324 /* succeed and release the skb buffer */
c55519ff
GKH
325 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
326
96b3c83d 327 return (Status);
c55519ff
GKH
328
329}
330
62eb734b
BZ
331u16 RtmpUSB_WriteMultiTxResource(struct rt_rtmp_adapter *pAd,
332 struct rt_tx_blk *pTxBlk,
51126deb 333 u8 frameNum, u16 * FreeNumber)
c55519ff 334{
62eb734b 335 struct rt_ht_tx_context *pHTTXContext;
51126deb
BZ
336 u16 hwHdrLen; /* The hwHdrLen consist of 802.11 header length plus the header padding length. */
337 u32 fillOffset;
62eb734b
BZ
338 struct rt_txinfo *pTxInfo;
339 struct rt_txwi *pTxWI;
51126deb
BZ
340 u8 *pWirelessPacket = NULL;
341 u8 QueIdx;
342 int Status;
96b3c83d 343 unsigned long IrqFlags;
51126deb 344 /*u32 USBDMApktLen = 0, DMAHdrLen, padding; */
c55519ff 345
ec278fa2
BZ
346 /* */
347 /* get Tx Ring Resource & Dma Buffer address */
348 /* */
c55519ff 349 QueIdx = pTxBlk->QueIdx;
96b3c83d 350 pHTTXContext = &pAd->TxContext[QueIdx];
c55519ff
GKH
351
352 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
353
96b3c83d 354 if (frameNum == 0) {
ec278fa2 355 /* Check if we have enough space for this bulk-out batch. */
c55519ff 356 Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
96b3c83d 357 if (Status == NDIS_STATUS_SUCCESS) {
c55519ff
GKH
358 pHTTXContext->bCurWriting = TRUE;
359
62eb734b
BZ
360 pTxInfo = (struct rt_txinfo *)(&pTxBlk->HeaderBuf[0]);
361 pTxWI = (struct rt_txwi *) (&pTxBlk->HeaderBuf[TXINFO_SIZE]);
c55519ff 362
ec278fa2 363 /* Reserve space for 8 bytes padding. */
96b3c83d
BZ
364 if ((pHTTXContext->ENextBulkOutPosition ==
365 pHTTXContext->CurWritePosition)) {
c55519ff
GKH
366
367 pHTTXContext->CurWritePosition += 8;
368 pHTTXContext->ENextBulkOutPosition += 8;
369 }
370 fillOffset = pHTTXContext->CurWritePosition;
96b3c83d
BZ
371 pHTTXContext->CurWriteRealPos =
372 pHTTXContext->CurWritePosition;
c55519ff 373
96b3c83d
BZ
374 pWirelessPacket =
375 &pHTTXContext->TransferBuffer->field.
376 WirelessPacket[fillOffset];
c55519ff 377
ec278fa2
BZ
378 /* */
379 /* Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */
380 /* */
c55519ff 381 if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
ec278fa2 382 /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD; */
96b3c83d
BZ
383 hwHdrLen =
384 pTxBlk->MpduHeaderLen -
385 LENGTH_AMSDU_SUBFRAMEHEAD +
386 pTxBlk->HdrPadLen +
387 LENGTH_AMSDU_SUBFRAMEHEAD;
c55519ff 388 else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)
ec278fa2 389 /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD; */
96b3c83d
BZ
390 hwHdrLen =
391 pTxBlk->MpduHeaderLen -
392 LENGTH_ARALINK_HEADER_FIELD +
393 pTxBlk->HdrPadLen +
394 LENGTH_ARALINK_HEADER_FIELD;
c55519ff 395 else
ec278fa2 396 /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
96b3c83d
BZ
397 hwHdrLen =
398 pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
c55519ff 399
ec278fa2 400 /* Update the pTxBlk->Priv. */
c55519ff
GKH
401 pTxBlk->Priv = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;
402
ec278fa2 403 /* pTxInfo->USBDMApktLen now just a temp value and will to correct latter. */
51126deb 404 RTMPWriteTxInfo(pAd, pTxInfo, (u16)(pTxBlk->Priv),
96b3c83d
BZ
405 FALSE, FIFO_EDCA, FALSE /*NextValid */ ,
406 FALSE);
c55519ff 407
ec278fa2 408 /* Copy it. */
96b3c83d
BZ
409 NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf,
410 pTxBlk->Priv);
c55519ff
GKH
411 pHTTXContext->CurWriteRealPos += pTxBlk->Priv;
412 pWirelessPacket += pTxBlk->Priv;
413 }
ec278fa2 414 } else { /* For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer. */
96b3c83d
BZ
415
416 Status =
417 ((pHTTXContext->bCurWriting ==
418 TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
419 if (Status == NDIS_STATUS_SUCCESS) {
420 fillOffset =
421 (pHTTXContext->CurWritePosition + pTxBlk->Priv);
422 pWirelessPacket =
423 &pHTTXContext->TransferBuffer->field.
424 WirelessPacket[fillOffset];
c55519ff 425
ec278fa2 426 /*hwHdrLen = pTxBlk->MpduHeaderLen; */
96b3c83d
BZ
427 NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf,
428 pTxBlk->MpduHeaderLen);
c55519ff
GKH
429 pWirelessPacket += (pTxBlk->MpduHeaderLen);
430 pTxBlk->Priv += pTxBlk->MpduHeaderLen;
ec278fa2 431 } else { /* It should not happened now unless we are going to shutdown. */
96b3c83d
BZ
432 DBGPRINT(RT_DEBUG_ERROR,
433 ("WriteMultiTxResource():bCurWriting is FALSE when handle sub-sequent frames.\n"));
c55519ff
GKH
434 Status = NDIS_STATUS_FAILURE;
435 }
436 }
437
ec278fa2
BZ
438 /* We unlock it here to prevent the first 8 bytes maybe over-write issue. */
439 /* 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxContext. */
440 /* 2. An interrupt break our routine and handle bulk-out complete. */
441 /* 3. In the bulk-out compllete, it need to do another bulk-out, */
442 /* if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition, */
443 /* but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE. */
444 /* 4. Interrupt complete. */
445 /* 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext. */
446 /* 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition. */
447 /* and the packet will wrong. */
c55519ff
GKH
448 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
449
96b3c83d
BZ
450 if (Status != NDIS_STATUS_SUCCESS) {
451 DBGPRINT(RT_DEBUG_ERROR,
452 ("WriteMultiTxResource: CWPos = %ld, NBOutPos = %ld.\n",
453 pHTTXContext->CurWritePosition,
454 pHTTXContext->NextBulkOutPosition));
c55519ff
GKH
455 goto done;
456 }
ec278fa2 457 /* Copy the frame content into DMA buffer and update the pTxBlk->Priv */
c55519ff
GKH
458 NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
459 pWirelessPacket += pTxBlk->SrcBufLen;
460 pTxBlk->Priv += pTxBlk->SrcBufLen;
461
462done:
ec278fa2 463 /* Release the skb buffer here */
c55519ff
GKH
464 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
465
96b3c83d 466 return (Status);
c55519ff
GKH
467
468}
469
62eb734b
BZ
470void RtmpUSB_FinalWriteTxResource(struct rt_rtmp_adapter *pAd,
471 struct rt_tx_blk *pTxBlk,
51126deb 472 u16 totalMPDUSize, u16 TxIdx)
c55519ff 473{
51126deb 474 u8 QueIdx;
62eb734b 475 struct rt_ht_tx_context *pHTTXContext;
51126deb 476 u32 fillOffset;
62eb734b
BZ
477 struct rt_txinfo *pTxInfo;
478 struct rt_txwi *pTxWI;
51126deb 479 u32 USBDMApktLen, padding;
96b3c83d 480 unsigned long IrqFlags;
51126deb 481 u8 *pWirelessPacket;
c55519ff
GKH
482
483 QueIdx = pTxBlk->QueIdx;
96b3c83d 484 pHTTXContext = &pAd->TxContext[QueIdx];
c55519ff
GKH
485
486 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
487
96b3c83d 488 if (pHTTXContext->bCurWriting == TRUE) {
c55519ff 489 fillOffset = pHTTXContext->CurWritePosition;
96b3c83d
BZ
490 if (((pHTTXContext->ENextBulkOutPosition ==
491 pHTTXContext->CurWritePosition)
492 || ((pHTTXContext->ENextBulkOutPosition - 8) ==
493 pHTTXContext->CurWritePosition))
494 && (pHTTXContext->bCopySavePad == TRUE))
51126deb 495 pWirelessPacket = (u8 *)(&pHTTXContext->SavedPad[0]);
c55519ff 496 else
96b3c83d 497 pWirelessPacket =
51126deb 498 (u8 *)(&pHTTXContext->TransferBuffer->field.
96b3c83d 499 WirelessPacket[fillOffset]);
c55519ff 500
ec278fa2
BZ
501 /* */
502 /* Update TxInfo->USBDMApktLen , */
503 /* the length = TXWI_SIZE + 802.11_hdr + 802.11_hdr_pad + payload_of_all_batch_frames + Bulk-Out-padding */
504 /* */
62eb734b 505 pTxInfo = (struct rt_txinfo *)(pWirelessPacket);
c55519ff 506
ec278fa2 507 /* Calculate the bulk-out padding */
c55519ff 508 USBDMApktLen = pTxBlk->Priv - TXINFO_SIZE;
ec278fa2 509 padding = (4 - (USBDMApktLen % 4)) & 0x03; /* round up to 4 byte alignment */
c55519ff
GKH
510 USBDMApktLen += padding;
511
512 pTxInfo->USBDMATxPktLen = USBDMApktLen;
513
ec278fa2
BZ
514 /* */
515 /* Update TXWI->MPDUtotalByteCount , */
516 /* the length = 802.11 header + payload_of_all_batch_frames */
62eb734b 517 pTxWI = (struct rt_txwi *) (pWirelessPacket + TXINFO_SIZE);
c55519ff
GKH
518 pTxWI->MPDUtotalByteCount = totalMPDUSize;
519
ec278fa2
BZ
520 /* */
521 /* Update the pHTTXContext->CurWritePosition */
522 /* */
c55519ff 523 pHTTXContext->CurWritePosition += (TXINFO_SIZE + USBDMApktLen);
ec278fa2 524 if ((pHTTXContext->CurWritePosition + 3906) > MAX_TXBULK_LIMIT) { /* Add 3906 for prevent the NextBulkOut packet size is a A-RALINK/A-MSDU Frame. */
c55519ff
GKH
525 pHTTXContext->CurWritePosition = 8;
526 pTxInfo->SwUseLastRound = 1;
527 }
528 pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
529
ec278fa2
BZ
530 /* */
531 /* Zero the last padding. */
532 /* */
96b3c83d
BZ
533 pWirelessPacket =
534 (&pHTTXContext->TransferBuffer->field.
535 WirelessPacket[fillOffset + pTxBlk->Priv]);
c55519ff
GKH
536 NdisZeroMemory(pWirelessPacket, padding + 8);
537
ec278fa2 538 /* Finally, set bCurWriting as FALSE */
c55519ff
GKH
539 pHTTXContext->bCurWriting = FALSE;
540
ec278fa2 541 } else { /* It should not happened now unless we are going to shutdown. */
96b3c83d
BZ
542 DBGPRINT(RT_DEBUG_ERROR,
543 ("FinalWriteTxResource():bCurWriting is FALSE when handle last frames.\n"));
c55519ff
GKH
544 }
545
546 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
547
548}
549
62eb734b 550void RtmpUSBDataLastTxIdx(struct rt_rtmp_adapter *pAd,
51126deb 551 u8 QueIdx, u16 TxIdx)
c55519ff 552{
ec278fa2 553 /* DO nothing for USB. */
c55519ff
GKH
554}
555
c55519ff
GKH
556/*
557 When can do bulk-out:
558 1. TxSwFreeIdx < TX_RING_SIZE;
559 It means has at least one Ring entity is ready for bulk-out, kick it out.
560 2. If TxSwFreeIdx == TX_RING_SIZE
561 Check if the CurWriting flag is FALSE, if it's FALSE, we can do kick out.
562
563*/
62eb734b
BZ
564void RtmpUSBDataKickOut(struct rt_rtmp_adapter *pAd,
565 struct rt_tx_blk *pTxBlk, u8 QueIdx)
c55519ff
GKH
566{
567 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
568 RTUSBKickBulkOut(pAd);
569
570}
571
c55519ff
GKH
572/*
573 Must be run in Interrupt context
574 This function handle RT2870 specific TxDesc and cpu index update and kick the packet out.
575 */
62eb734b 576int RtmpUSBMgmtKickOut(struct rt_rtmp_adapter *pAd,
51126deb 577 u8 QueIdx,
8a10a546 578 void *pPacket,
51126deb 579 u8 *pSrcBufVA, u32 SrcBufLen)
c55519ff 580{
62eb734b 581 struct rt_txinfo *pTxInfo;
51126deb
BZ
582 unsigned long BulkOutSize;
583 u8 padLen;
584 u8 *pDest;
585 unsigned long SwIdx = pAd->MgmtRing.TxCpuIdx;
62eb734b
BZ
586 struct rt_tx_context *pMLMEContext =
587 (struct rt_tx_context *)pAd->MgmtRing.Cell[SwIdx].AllocVa;
96b3c83d 588 unsigned long IrqFlags;
c55519ff 589
62eb734b 590 pTxInfo = (struct rt_txinfo *)(pSrcBufVA);
c55519ff 591
ec278fa2 592 /* Build our URB for USBD */
c55519ff
GKH
593 BulkOutSize = SrcBufLen;
594 BulkOutSize = (BulkOutSize + 3) & (~3);
51126deb 595 RTMPWriteTxInfo(pAd, pTxInfo, (u16)(BulkOutSize - TXINFO_SIZE),
96b3c83d 596 TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
c55519ff 597
ec278fa2 598 BulkOutSize += 4; /* Always add 4 extra bytes at every packet. */
c55519ff 599
ec278fa2 600 /* If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again. */
c55519ff
GKH
601 if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0)
602 BulkOutSize += 4;
603
604 padLen = BulkOutSize - SrcBufLen;
605 ASSERT((padLen <= RTMP_PKT_TAIL_PADDING));
606
ec278fa2 607 /* Now memzero all extra padding bytes. */
51126deb 608 pDest = (u8 *)(pSrcBufVA + SrcBufLen);
c55519ff
GKH
609 skb_put(GET_OS_PKT_TYPE(pPacket), padLen);
610 NdisZeroMemory(pDest, padLen);
611
612 RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
613
614 pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket;
96b3c83d 615 pMLMEContext->TransferBuffer =
62eb734b 616 (struct rt_tx_buffer *)(GET_OS_PKT_DATAPTR(pPacket));
c55519ff 617
ec278fa2 618 /* Length in TxInfo should be 8 less than bulkout size. */
c55519ff
GKH
619 pMLMEContext->BulkOutSize = BulkOutSize;
620 pMLMEContext->InUse = TRUE;
621 pMLMEContext->bWaitingBulkOut = TRUE;
622
ec278fa2
BZ
623 /*for debug */
624 /*hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize)); */
c55519ff 625
ec278fa2
BZ
626 /*pAd->RalinkCounters.KickTxCount++; */
627 /*pAd->RalinkCounters.OneSecTxDoneCount++; */
c55519ff 628
ec278fa2
BZ
629 /*if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE) */
630 /* needKickOut = TRUE; */
c55519ff 631
ec278fa2 632 /* Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX */
c55519ff
GKH
633 pAd->MgmtRing.TxSwFreeIdx--;
634 INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
635
636 RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
637
638 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
ec278fa2 639 /*if (needKickOut) */
c55519ff
GKH
640 RTUSBKickBulkOut(pAd);
641
642 return 0;
643}
644
62eb734b 645void RtmpUSBNullFrameKickOut(struct rt_rtmp_adapter *pAd,
51126deb
BZ
646 u8 QueIdx,
647 u8 * pNullFrame, u32 frameLen)
c55519ff 648{
96b3c83d 649 if (pAd->NullContext.InUse == FALSE) {
62eb734b
BZ
650 struct rt_tx_context *pNullContext;
651 struct rt_txinfo *pTxInfo;
652 struct rt_txwi * pTxWI;
51126deb 653 u8 *pWirelessPkt;
c55519ff
GKH
654
655 pNullContext = &(pAd->NullContext);
656
ec278fa2 657 /* Set the in use bit */
c55519ff 658 pNullContext->InUse = TRUE;
96b3c83d 659 pWirelessPkt =
51126deb 660 (u8 *)& pNullContext->TransferBuffer->field.
96b3c83d 661 WirelessPacket[0];
c55519ff
GKH
662
663 RTMPZeroMemory(&pWirelessPkt[0], 100);
62eb734b 664 pTxInfo = (struct rt_txinfo *)& pWirelessPkt[0];
96b3c83d 665 RTMPWriteTxInfo(pAd, pTxInfo,
62eb734b 666 (u16)(sizeof(struct rt_header_802_11) + TXWI_SIZE),
96b3c83d 667 TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
c55519ff 668 pTxInfo->QSEL = FIFO_EDCA;
62eb734b 669 pTxWI = (struct rt_txwi *) & pWirelessPkt[TXINFO_SIZE];
96b3c83d 670 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE,
62eb734b 671 FALSE, 0, BSSID_WCID, (sizeof(struct rt_header_802_11)), 0,
51126deb 672 0, (u8)pAd->CommonCfg.MlmeTransmit.field.MCS,
96b3c83d 673 IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
ca97b838 674
96b3c83d 675 RTMPMoveMemory(&pWirelessPkt[TXWI_SIZE + TXINFO_SIZE],
62eb734b 676 &pAd->NullFrame, sizeof(struct rt_header_802_11));
96b3c83d
BZ
677 pAd->NullContext.BulkOutSize =
678 TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
c55519ff 679
ec278fa2
BZ
680 /* Fill out frame length information for global Bulk out arbitor */
681 /*pNullContext->BulkOutSize = TransferBufferLength; */
96b3c83d
BZ
682 DBGPRINT(RT_DEBUG_TRACE,
683 ("SYNC - send NULL Frame @%d Mbps...\n",
684 RateIdToMbps[pAd->CommonCfg.TxRate]));
c55519ff
GKH
685 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
686
ec278fa2 687 /* Kick bulk out */
c55519ff
GKH
688 RTUSBKickBulkOut(pAd);
689 }
690
691}
692
ca97b838
BZ
693/*
694========================================================================
695Routine Description:
696 Get a received packet.
697
698Arguments:
699 pAd device control block
700 pSaveRxD receive descriptor information
701 *pbReschedule need reschedule flag
702 *pRxPending pending received packet flag
703
704Return Value:
25985edc 705 the received packet
ca97b838
BZ
706
707Note:
708========================================================================
709*/
62eb734b 710void *GetPacketFromRxRing(struct rt_rtmp_adapter *pAd,
96b3c83d
BZ
711 OUT PRT28XX_RXD_STRUC pSaveRxD,
712 OUT BOOLEAN * pbReschedule,
51126deb 713 IN u32 * pRxPending)
ca97b838 714{
62eb734b 715 struct rt_rx_context *pRxContext;
8a10a546 716 void *pSkb;
51126deb
BZ
717 u8 *pData;
718 unsigned long ThisFrameLen;
719 unsigned long RxBufferLength;
62eb734b 720 struct rt_rxwi * pRxWI;
ca97b838
BZ
721
722 pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex];
723 if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE))
724 return NULL;
725
726 RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition;
96b3c83d 727 if (RxBufferLength <
62eb734b
BZ
728 (RT2870_RXDMALEN_FIELD_SIZE + sizeof(struct rt_rxwi) +
729 sizeof(struct rt_rxinfo))) {
ca97b838
BZ
730 goto label_null;
731 }
732
96b3c83d 733 pData = &pRxContext->TransferBuffer[pAd->ReadPosition]; /* 4KB */
ec278fa2 734 /* The RXDMA field is 4 bytes, now just use the first 2 bytes. The Length including the (RXWI + MSDU + Padding) */
96b3c83d
BZ
735 ThisFrameLen = *pData + (*(pData + 1) << 8);
736 if (ThisFrameLen == 0) {
737 DBGPRINT(RT_DEBUG_TRACE,
738 ("BIRIdx(%d): RXDMALen is zero.[%ld], BulkInBufLen = %ld)\n",
739 pAd->NextRxBulkInReadIndex, ThisFrameLen,
740 pRxContext->BulkInOffset));
ca97b838
BZ
741 goto label_null;
742 }
96b3c83d
BZ
743 if ((ThisFrameLen & 0x3) != 0) {
744 DBGPRINT(RT_DEBUG_ERROR,
745 ("BIRIdx(%d): RXDMALen not multiple of 4.[%ld], BulkInBufLen = %ld)\n",
746 pAd->NextRxBulkInReadIndex, ThisFrameLen,
747 pRxContext->BulkInOffset));
ca97b838
BZ
748 goto label_null;
749 }
750
62eb734b 751 if ((ThisFrameLen + 8) > RxBufferLength) /* 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(struct rt_rxinfo)) */
ca97b838 752 {
96b3c83d
BZ
753 DBGPRINT(RT_DEBUG_TRACE,
754 ("BIRIdx(%d):FrameLen(0x%lx) outranges. BulkInLen=0x%lx, remaining RxBufLen=0x%lx, ReadPos=0x%lx\n",
755 pAd->NextRxBulkInReadIndex, ThisFrameLen,
756 pRxContext->BulkInOffset, RxBufferLength,
757 pAd->ReadPosition));
ca97b838 758
ec278fa2 759 /* error frame. finish this loop */
ca97b838
BZ
760 goto label_null;
761 }
ec278fa2 762 /* skip USB frame length field */
ca97b838 763 pData += RT2870_RXDMALEN_FIELD_SIZE;
62eb734b 764 pRxWI = (struct rt_rxwi *) pData;
96b3c83d
BZ
765 if (pRxWI->MPDUtotalByteCount > ThisFrameLen) {
766 DBGPRINT(RT_DEBUG_ERROR,
767 ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n",
768 __FUNCTION__, pRxWI->MPDUtotalByteCount,
769 ThisFrameLen));
ca97b838
BZ
770 goto label_null;
771 }
ec278fa2 772 /* allocate a rx packet */
ca97b838 773 pSkb = dev_alloc_skb(ThisFrameLen);
96b3c83d
BZ
774 if (pSkb == NULL) {
775 DBGPRINT(RT_DEBUG_ERROR,
776 ("%s():Cannot Allocate sk buffer for this Bulk-In buffer!\n",
777 __FUNCTION__));
ca97b838
BZ
778 goto label_null;
779 }
ec278fa2 780 /* copy the rx packet */
ca97b838
BZ
781 memcpy(skb_put(pSkb, ThisFrameLen), pData, ThisFrameLen);
782 RTPKT_TO_OSPKT(pSkb)->dev = get_netdev_from_bssid(pAd, BSS0);
783 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pSkb), PKTSRC_NDIS);
784
ec278fa2 785 /* copy RxD */
62eb734b 786 *pSaveRxD = *(struct rt_rxinfo *) (pData + ThisFrameLen);
ca97b838 787
ec278fa2 788 /* update next packet read position. */
62eb734b 789 pAd->ReadPosition += (ThisFrameLen + RT2870_RXDMALEN_FIELD_SIZE + RXINFO_SIZE); /* 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(struct rt_rxinfo)) */
ca97b838
BZ
790
791 return pSkb;
792
793label_null:
794
795 return NULL;
796}
797
c55519ff
GKH
798/*
799 ========================================================================
800
801 Routine Description:
802 Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
803
804 Arguments:
805 pRxD Pointer to the Rx descriptor
806
807 Return Value:
808 NDIS_STATUS_SUCCESS No err
809 NDIS_STATUS_FAILURE Error
810
811 Note:
812
813 ========================================================================
814*/
62eb734b
BZ
815int RTMPCheckRxError(struct rt_rtmp_adapter *pAd,
816 struct rt_header_802_11 * pHeader,
817 struct rt_rxwi * pRxWI, IN PRT28XX_RXD_STRUC pRxINFO)
c55519ff 818{
62eb734b 819 struct rt_cipher_key *pWpaKey;
51126deb 820 int dBm;
c55519ff
GKH
821
822 if (pAd->bPromiscuous == TRUE)
96b3c83d
BZ
823 return (NDIS_STATUS_SUCCESS);
824 if (pRxINFO == NULL)
825 return (NDIS_STATUS_FAILURE);
c55519ff 826
ec278fa2 827 /* Phy errors & CRC errors */
96b3c83d 828 if (pRxINFO->Crc) {
ec278fa2 829 /* Check RSSI for Noise Hist statistic collection. */
51126deb 830 dBm = (int)(pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta;
c55519ff
GKH
831 if (dBm <= -87)
832 pAd->StaCfg.RPIDensity[0] += 1;
833 else if (dBm <= -82)
834 pAd->StaCfg.RPIDensity[1] += 1;
835 else if (dBm <= -77)
836 pAd->StaCfg.RPIDensity[2] += 1;
837 else if (dBm <= -72)
838 pAd->StaCfg.RPIDensity[3] += 1;
839 else if (dBm <= -67)
840 pAd->StaCfg.RPIDensity[4] += 1;
841 else if (dBm <= -62)
842 pAd->StaCfg.RPIDensity[5] += 1;
843 else if (dBm <= -57)
844 pAd->StaCfg.RPIDensity[6] += 1;
845 else if (dBm > -57)
846 pAd->StaCfg.RPIDensity[7] += 1;
847
96b3c83d 848 return (NDIS_STATUS_FAILURE);
c55519ff 849 }
ec278fa2 850 /* Add Rx size to channel load counter, we should ignore error counts */
96b3c83d 851 pAd->StaCfg.CLBusyBytes += (pRxWI->MPDUtotalByteCount + 14);
c55519ff 852
25985edc 853 /* Drop ToDs promiscuous frame, it is opened due to CCX 2 channel load statistics */
96b3c83d 854 if (pHeader->FC.ToDs) {
c55519ff
GKH
855 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Err;FC.ToDs\n"));
856 return NDIS_STATUS_FAILURE;
857 }
ec278fa2 858 /* Paul 04-03 for OFDM Rx length issue */
96b3c83d 859 if (pRxWI->MPDUtotalByteCount > MAX_AGGREGATION_SIZE) {
c55519ff
GKH
860 DBGPRINT_RAW(RT_DEBUG_ERROR, ("received packet too long\n"));
861 return NDIS_STATUS_FAILURE;
862 }
25985edc 863 /* Drop not U2M frames, can't's drop here because we will drop beacon in this case */
ec278fa2
BZ
864 /* I am kind of doubting the U2M bit operation */
865 /* if (pRxD->U2M == 0) */
866 /* return(NDIS_STATUS_FAILURE); */
c55519ff 867
ec278fa2 868 /* drop decyption fail frame */
96b3c83d
BZ
869 if (pRxINFO->Decrypted && pRxINFO->CipherErr) {
870
871 if (((pRxINFO->CipherErr & 1) == 1)
872 && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
873 RTMPSendWirelessEvent(pAd, IW_ICV_ERROR_EVENT_FLAG,
874 pAd->MacTab.Content[BSSID_WCID].
875 Addr, BSS0, 0);
876
877 if (((pRxINFO->CipherErr & 2) == 2)
878 && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
879 RTMPSendWirelessEvent(pAd, IW_MIC_ERROR_EVENT_FLAG,
880 pAd->MacTab.Content[BSSID_WCID].
881 Addr, BSS0, 0);
ec278fa2
BZ
882 /* */
883 /* MIC Error */
884 /* */
96b3c83d 885 if ((pRxINFO->CipherErr == 2) && pRxINFO->MyBss) {
c55519ff
GKH
886 pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
887 RTMPReportMicError(pAd, pWpaKey);
96b3c83d 888 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Rx MIC Value error\n"));
c55519ff
GKH
889 }
890
891 if (pRxINFO->Decrypted &&
96b3c83d
BZ
892 (pAd->SharedKey[BSS0][pRxWI->KeyIndex].CipherAlg ==
893 CIPHER_AES)
894 && (pHeader->Sequence == pAd->FragFrame.Sequence)) {
ec278fa2
BZ
895 /* */
896 /* Acceptable since the First FragFrame no CipherErr problem. */
897 /* */
96b3c83d 898 return (NDIS_STATUS_SUCCESS);
c55519ff
GKH
899 }
900
96b3c83d 901 return (NDIS_STATUS_FAILURE);
c55519ff
GKH
902 }
903
96b3c83d 904 return (NDIS_STATUS_SUCCESS);
c55519ff
GKH
905}
906
51126deb
BZ
907void RtmpUsbStaAsicForceWakeupTimeout(void *SystemSpecific1,
908 void *FunctionContext,
909 void *SystemSpecific2,
910 void *SystemSpecific3)
ca97b838 911{
62eb734b 912 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
ca97b838 913
96b3c83d 914 if (pAd && pAd->Mlme.AutoWakeupTimerRunning) {
ca97b838
BZ
915 AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
916
917 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
918 pAd->Mlme.AutoWakeupTimerRunning = FALSE;
919 }
920}
921
62eb734b 922void RT28xxUsbStaAsicForceWakeup(struct rt_rtmp_adapter *pAd, IN BOOLEAN bFromTx)
c55519ff 923{
96b3c83d 924 BOOLEAN Canceled;
c55519ff 925
ca97b838
BZ
926 if (pAd->Mlme.AutoWakeupTimerRunning)
927 RTMPCancelTimer(&pAd->Mlme.AutoWakeupTimer, &Canceled);
c55519ff 928
ffbc7b85 929 AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
c55519ff
GKH
930
931 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
932}
933
62eb734b 934void RT28xxUsbStaAsicSleepThenAutoWakeup(struct rt_rtmp_adapter *pAd,
51126deb 935 u16 TbttNumToNextWakeUp)
c55519ff 936{
ca97b838 937
ec278fa2 938 /* we have decided to SLEEP, so at least do it for a BEACON period. */
c55519ff
GKH
939 if (TbttNumToNextWakeUp == 0)
940 TbttNumToNextWakeUp = 1;
941
ca97b838
BZ
942 RTMPSetTimer(&pAd->Mlme.AutoWakeupTimer, AUTO_WAKEUP_TIMEOUT);
943 pAd->Mlme.AutoWakeupTimerRunning = TRUE;
c55519ff 944
ec278fa2 945 AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); /* send POWER-SAVE command to MCU. Timeout 40us. */
c55519ff
GKH
946
947 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
948
949}
c55519ff 950
ec278fa2 951#endif /* RTMP_MAC_USB // */