MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / net / wireless / rtlink / Module / rtmp_data.c
blob7630a65348e3d2a4a5292633ad8df420d53f9ce1
1 /*************************************************************************
2 * Ralink Tech Inc. *
3 * 4F, No. 2 Technology 5th Rd. *
4 * Science-based Industrial Park *
5 * Hsin-chu, Taiwan, R.O.C. *
6 * *
7 * (c) Copyright 2002, Ralink Technology, Inc. *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
18 * *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program; if not, write to the *
21 * Free Software Foundation, Inc., *
22 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
23 * *
24 *************************************************************************
26 Module Name:
27 rtmp_data.c
29 Abstract:
30 Data path subroutines
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs
36 HK Initial
37 Paul 10/02/02 Merge & modify
38 John 02/25/03 Modified for RT2560
40 #include "rt_config.h"
42 static UCHAR SNAP_802_1H[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
43 static UCHAR SNAP_BRIDGE_TUNNEL[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8};
44 static UCHAR EAPOL[] = {0x88, 0x8e};
46 static UCHAR IPX[] = {0x81, 0x37};
47 static UCHAR APPLE_TALK[] = {0x80, 0xf3};
48 static UCHAR PlcpSignal[12] = {
49 0, /* RATE_1 */ 1, /* RATE_2 */ 2, /* RATE_5_5 */ 3, /* RATE_11 */ // see BBP spec
50 11, /* RATE_6 */ 15, /* RATE_9 */ 10, /* RATE_12 */ 14, /* RATE_18 */ // see IEEE802.11a-1999 p.14
51 9, /* RATE_24 */ 13, /* RATE_36 */ 8, /* RATE_48 */ 12 /* RATE_54 */ }; // see IEEE802.11a-1999 p.14
53 #define COLLECT_RX_ANTENNA_AVERAGE_RSSI(_pAd, _RxAnt, _rssi) \
54 { \
55 USHORT AvgRssi; \
56 if (_RxAnt.PrimaryInUsed) \
57 { \
58 AvgRssi = _RxAnt.AvgRssi[_RxAnt.PrimaryRxAnt]; \
59 if (AvgRssi > 0) \
60 AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi; \
61 else \
62 AvgRssi = _rssi << 3; \
63 _RxAnt.AvgRssi[_RxAnt.PrimaryRxAnt] = AvgRssi; \
64 } \
65 else \
66 { \
67 AvgRssi = _RxAnt.AvgRssi[_RxAnt.SecondaryRxAnt]; \
68 _RxAnt.RcvPktNumWhenEvaluate++;\
69 if ((AvgRssi > 0) && (_RxAnt.FirstPktArrivedWhenEvaluate)) \
70 AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi; \
71 else \
72 { \
73 _RxAnt.FirstPktArrivedWhenEvaluate = TRUE; \
74 AvgRssi = _rssi << 3; \
75 DBGPRINT(RT_DEBUG_TRACE,"Reset RSSI(%d) when first packet is rcved \n",_rssi-_pAd->PortCfg.RssiToDbm); \
76 } \
77 _RxAnt.AvgRssi[_RxAnt.SecondaryRxAnt] = AvgRssi; \
78 } \
82 ========================================================================
84 Routine Description:
85 Process RxDone interrupt, running in DPC level
87 Arguments:
88 pAdapter Pointer to our adapter
90 Return Value:
91 None
93 Note:
94 This routine has to maintain Rx ring read pointer.
95 ========================================================================
97 VOID RTMPHandleRxDoneInterrupt(
98 IN PRTMP_ADAPTER pAdapter)
100 PRXD_STRUC pRxD;
101 #ifdef BIG_ENDIAN
102 PRXD_STRUC pDestRxD;
103 RXD_STRUC RxD;
104 #endif
105 PHEADER_802_11 pHeader;
106 PUCHAR pData;
107 PUCHAR pDestMac, pSrcMac;
108 UCHAR Count;
109 UCHAR KeyIdx;
110 PWPA_KEY pWpaKey;
111 NDIS_STATUS Status;
112 BOOLEAN bDropFrame;
113 ULONG RegValue;//, Address;
114 ULONG HwDecryptIndex;
115 ULONG IrqFlags;
117 // Make sure Rx ring resource won't be used by other threads
118 NdisAcquireSpinLock(&pAdapter->RxRingLock, IrqFlags);
120 // Verify Hardware Decryption pointer with Software Decryption pointer
121 RTMP_IO_READ32(pAdapter, SECCSR0, &RegValue);
122 HwDecryptIndex = (RegValue - pAdapter->RxRing[0].pa_addr) / RING_DESCRIPTOR_SIZE;
123 #if 0
124 Address = pAdapter->RxRing[pAdapter->CurDecryptIndex].pa_addr;
125 if (Address != RegValue)
127 DBGPRINT(RT_DEBUG_ERROR,"Decrypt pointer not matched SW = 0x%x, HW = 0x%x\n", Address, RegValue);
128 DBGPRINT(RT_DEBUG_ERROR,"Sw Decr Ptr = %d, Rx ptr = %d Hw ptr = %d\n",
129 pAdapter->CurDecryptIndex, pAdapter->CurRxIndex, HwDecryptIndex);
131 #endif
132 Count = 0;
135 // Point to Rx indexed rx ring descriptor
136 #ifndef BIG_ENDIAN
137 pRxD = (PRXD_STRUC) pAdapter->RxRing[pAdapter->CurRxIndex].va_addr;
138 #else
139 pDestRxD = (PRXD_STRUC) pAdapter->RxRing[pAdapter->CurRxIndex].va_addr;
140 RxD = *pDestRxD;
141 pRxD = &RxD;
142 RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
143 #endif
144 // Initialize drop frame flag
145 bDropFrame = FALSE;
147 // In case of false alarm or processed at last instance
148 if (pRxD->Owner != DESC_OWN_HOST)
150 break;
153 // Decrypt engine stuck
154 if (pRxD->CipherOwner != DESC_OWN_HOST)
156 pAdapter->RalinkCounters.RxRingErrCount++;
157 break;
160 #ifdef RALINK_ATE
161 if(pAdapter->ate.Mode == ATE_RXFRAME)
163 bDropFrame = TRUE;
165 #endif //#ifdef RALINK_ATE
167 // Point to Rx ring buffer where stores the real data frame
168 pData = (PUCHAR) (pAdapter->RxRing[pAdapter->CurRxIndex].va_data_addr);
169 // Cast to 802.11 header for flags checking
170 pHeader = (PHEADER_802_11) pData;
172 #ifdef BIG_ENDIAN
173 RTMPFrameEndianChange(pAdapter, (PUCHAR)pHeader, DIR_READ, TRUE);
174 #endif
176 // Increase Total receive byte counter after real data received no mater any error or not
177 pAdapter->RalinkCounters.ReceivedByteCount += pRxD->DataByteCnt;
179 // Check for all RxD errors
180 Status = RTMPCheckRxDescriptor(pRxD);
182 // Apply packet filtering rule based on microsoft requirements.
183 if (Status == NDIS_STATUS_SUCCESS)
184 Status = RTMPApplyPacketFilter(pAdapter, pRxD, pHeader);
186 // Add receive counters
187 if (Status == NDIS_STATUS_SUCCESS)
189 // Increase 802.11 counters & general receive counters
190 INC_COUNTER(pAdapter->WlanCounters.ReceivedFragmentCount);
192 // collect current antenna's average RSSI for software-based RX Antenna diversity
193 if ((pRxD->U2M)
194 || ((pHeader->Controlhead.Frame.Subtype == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL(&pAdapter->PortCfg.Bssid, &pHeader->Controlhead.Addr2))))
196 //DBGPRINT(RT_DEBUG_TRACE, "COLLECT_RSSI:(%d)\n", pRxD->BBR1 - pAdapter->PortCfg.RssiToDbm);
197 pAdapter->PortCfg.NumOfAvgRssiSample ++;
198 COLLECT_RX_ANTENNA_AVERAGE_RSSI(pAdapter, pAdapter->PortCfg.RxAnt, pRxD->BBR1);
201 else
203 // Increase general counters
204 pAdapter->Counters.RxErrors++;
207 // Check for retry bit, if this bit is on, search the cache with SA & sequence
208 // as index, if matched, discard this frame, otherwise, update cache
209 // This check only apply to unicast data & management frames
210 if ((Status == NDIS_STATUS_SUCCESS) && (pRxD->U2M) && (pHeader->Controlhead.Frame.Type != BTYPE_CNTL))
212 if (pHeader->Controlhead.Frame.Retry)
214 if (RTMPSearchTupleCache(pAdapter, pHeader) == TRUE)
216 // Found retry frame in tuple cache, Discard this frame / fragment
217 // Increase 802.11 counters
218 INC_COUNTER(pAdapter->WlanCounters.FrameDuplicateCount);
219 Status = NDIS_STATUS_FAILURE;
221 else
222 RTMPUpdateTupleCache(pAdapter, pHeader);
224 else // Update Tuple Cache
225 RTMPUpdateTupleCache(pAdapter, pHeader);
229 // Do RxD release operation for all failure frames
231 pRxD->CipherAlg = CIPHER_NONE;
232 if (Status == NDIS_STATUS_SUCCESS)
234 // pData : Pointer skip the first 24 bytes, 802.11 HEADER
235 pData += LENGTH_802_11;
238 // Start of main loop to parse receiving frames.
239 // The sequence will be Type first, then subtype...
241 switch (pHeader->Controlhead.Frame.Type)
243 // Frame with data type
244 case BTYPE_DATA:
245 // Drop not my BSS frame
246 if (INFRA_ON(pAdapter))
248 // Infrastructure mode, check address 2 for BSSID
249 if (!RTMPEqualMemory(&pHeader->Controlhead.Addr2, &pAdapter->PortCfg.Bssid, 6))
251 // Receive frame not my BSSID
252 bDropFrame = TRUE;
253 break;
256 else // Ad-Hoc mode or Not associated
258 // Ad-Hoc mode, check address 3 for BSSID
259 if (!RTMPEqualMemory(&pHeader->Addr3, &pAdapter->PortCfg.Bssid, 6))
261 // Receive frame not my BSSID
262 bDropFrame = TRUE;
263 break;
266 // Drop frame from AP while we are in Ad-hoc mode or not associated
267 if (pHeader->Controlhead.Frame.FrDs)
269 bDropFrame = TRUE;
270 break;
274 // Drop Null data frame, or CF with NULL data frame
275 if ((pHeader->Controlhead.Frame.Subtype == SUBTYPE_NULL_FUNC) ||
276 (pHeader->Controlhead.Frame.Subtype == SUBTYPE_CFACK) ||
277 (pHeader->Controlhead.Frame.Subtype == SUBTYPE_CFPOLL) ||
278 (pHeader->Controlhead.Frame.Subtype == SUBTYPE_CFACK_CFPOLL))
280 bDropFrame = TRUE;
281 break;
284 // Process Multicast data frame
285 if (pRxD->Mcast)
287 // Multicast 802.11 Counter
288 INC_COUNTER(pAdapter->WlanCounters.MulticastReceivedFrameCount);
289 DBGPRINT(RT_DEBUG_INFO,"Receiving multicast frame\n");
292 // Init WPA Key to NULL
293 pWpaKey = (PWPA_KEY) NULL;
295 // Find the WPA key, either Group or Pairwise Key
296 if ((pAdapter->PortCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pHeader->Controlhead.Frame.Wep))
298 INT idx;
300 // First lookup the DA, if it's a group address, use GROUP key
301 if (pRxD->Bcast || pRxD->Mcast)
304 idx = (*(pData + 3) & 0xc0) >> 6;
305 if ((pAdapter->PortCfg.GroupKey[idx].KeyLen != 0) &&
306 ((INFRA_ON(pAdapter) && (NdisEqualMemory(&pHeader->Controlhead.Addr2, &pAdapter->PortCfg.Bssid, 6))) ||
307 (ADHOC_ON(pAdapter) && (NdisEqualMemory(&pHeader->Addr3, &pAdapter->PortCfg.Bssid, 6)))))
309 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.GroupKey[idx];
310 pWpaKey->Type = GROUP_KEY;
311 DBGPRINT(RT_DEBUG_INFO, "Rx Use Group Key %d\n", idx);
314 // Try to find the Pairwise Key
315 else
317 for (idx = 0; idx < PAIRWISE_KEY_NO; idx++)
319 if ((NdisEqualMemory(&pHeader->Controlhead.Addr2, pAdapter->PortCfg.PairwiseKey[idx].BssId, 6)) &&
320 (pAdapter->PortCfg.PairwiseKey[idx].KeyLen != 0))
322 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.PairwiseKey[idx];
323 pWpaKey->Type = PAIRWISE_KEY;
324 DBGPRINT(RT_DEBUG_INFO, "Rx Use Pairwise Key\n");
325 break;
328 #if 1
329 // Use default Group Key if there is no Pairwise key present
330 if ((pWpaKey == NULL) && (pAdapter->PortCfg.GroupKey[pAdapter->PortCfg.DefaultKeyId].KeyLen != 0))
332 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.GroupKey[pAdapter->PortCfg.DefaultKeyId];
333 pWpaKey->Type = GROUP_KEY;
334 DBGPRINT(RT_DEBUG_INFO, "Rx Use Group Key\n");
336 #endif
340 // Process Broadcast & Multicast data frame
341 if (pRxD->Bcast || pRxD->Mcast)
343 // Drop Mcast / Bcast frame with fragment bit on
344 if (pHeader->Controlhead.Frame.MoreFrag)
346 DBGPRINT(RT_DEBUG_ERROR,"Receiving multicast frame with fragment bit on\n");
347 Status = NDIS_STATUS_FAILURE;
348 bDropFrame = TRUE;
349 break;
352 // Filter out Bcast frame which AP relayed for us
353 if (pHeader->Controlhead.Frame.FrDs && RTMPEqualMemory(&pHeader->Addr3, pAdapter->CurrentAddress, 6))
355 Status = NDIS_STATUS_FAILURE;
356 bDropFrame = TRUE;
357 break;
360 // WEP encrypted frame
361 if (pHeader->Controlhead.Frame.Wep)
363 // Check our WEP setting, if no WEP turning on, just drop this frame
364 if (pAdapter->PortCfg.WepStatus == Ndis802_11Encryption1Enabled) // WEP
366 KeyIdx = (*(pData + 3) & 0xc0) >> 6;
367 NdisMoveMemory((PUCHAR) &pRxD->Iv, pData, 4); //Get WEP IV
368 NdisMoveMemory(pRxD->Key, pAdapter->PortCfg.SharedKey[KeyIdx].Key, pAdapter->PortCfg.SharedKey[KeyIdx].KeyLen);
369 if (pAdapter->PortCfg.SharedKey[KeyIdx].KeyLen == 5)
370 pRxD->CipherAlg = CIPHER_WEP64;
371 else
372 pRxD->CipherAlg = CIPHER_WEP128;
374 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) && (pWpaKey != NULL)) // TKIP
376 UCHAR Eiv_Tmp[4];
378 NdisMoveMemory((PUCHAR) &pRxD->Iv, pData, 4); //Get WEP IV
379 // Swap EIV byte order, due to ASIC's bug.
380 Eiv_Tmp[0] = *(pData + 7);
381 Eiv_Tmp[1] = *(pData + 6);
382 Eiv_Tmp[2] = *(pData + 5);
383 Eiv_Tmp[3] = *(pData + 4);
384 NdisMoveMemory((PUCHAR) &pRxD->Eiv, Eiv_Tmp, 4); //Get WEP EIV
385 // Copy TA into RxD
386 NdisMoveMemory(pRxD->TA, &pHeader->Controlhead.Addr2, 6);
387 KeyIdx = (*(pData + 3) & 0xc0) >> 6;
388 NdisMoveMemory(pRxD->Key, pWpaKey->Key, 16);
389 pRxD->CipherAlg = CIPHER_TKIP;
391 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled) && (pWpaKey != NULL)) // AES
393 NdisMoveMemory((PUCHAR) &pRxD->Iv, pData, 4); //Get WEP IV
394 NdisMoveMemory((PUCHAR) &pRxD->Eiv, (pData + 4), 4); //Get WEP EIV
395 // Copy TA into RxD
396 NdisMoveMemory(pRxD->TA, &pHeader->Controlhead.Addr2, 6);
397 KeyIdx = (*(pData + 3) & 0xc0) >> 6;
398 NdisMoveMemory(pRxD->Key, pWpaKey->Key, 16);
399 pRxD->CipherAlg = CIPHER_AES;
401 else
403 // Add error counter
404 Status = NDIS_STATUS_FAILURE;
405 bDropFrame = TRUE;
406 break;
409 else // Not encrypted frames
411 pRxD->CipherAlg = CIPHER_NONE;
415 // Begin process unicast to me frame
416 else if (pRxD->U2M)
418 // Send PS-Poll for AP to send next data frame
419 if ((pHeader->Controlhead.Frame.MoreData) && INFRA_ON(pAdapter) && (pAdapter->PortCfg.Psm == PWR_SAVE))
421 EnqueuePsPoll(pAdapter);
422 DBGPRINT(RT_DEBUG_TRACE, "Sending PS-POLL\n");
426 // Begin frame processing
428 pDestMac = (PUCHAR) &(pHeader->Controlhead.Addr1); // DA is always address 1
429 if (INFRA_ON(pAdapter)) // For infrastructure, SA is address 3
430 pSrcMac = (PUCHAR) &(pHeader->Addr3);
431 else // For IBSS mode, SA is address 2
432 pSrcMac = (PUCHAR) &(pHeader->Controlhead.Addr2);
434 // WEP encrypted frame
435 if (pAdapter->PortCfg.WepStatus == Ndis802_11Encryption1Enabled) // WEP
437 if (pHeader->Controlhead.Frame.Wep)
439 KeyIdx = (*(pData + 3) & 0xc0) >> 6;
441 NdisMoveMemory((PUCHAR) &pRxD->Iv, pData, 4); //Get WEP IV
442 NdisMoveMemory(pRxD->Key, pAdapter->PortCfg.SharedKey[KeyIdx].Key, pAdapter->PortCfg.SharedKey[KeyIdx].KeyLen);
443 if (pAdapter->PortCfg.SharedKey[KeyIdx].KeyLen == 5)
444 pRxD->CipherAlg = CIPHER_WEP64;
445 else
446 pRxD->CipherAlg = CIPHER_WEP128;
448 else if ((pAdapter->PortCfg.PrivacyFilter == Ndis802_11PrivFilter8021xWEP) &&
449 (pHeader->Frag == 0))
451 // Check 802.1x frame, if not drop it.
452 if (!RTMPEqualMemory(EAPOL, pData + 6, 2))
454 // Not 802.1X frames
455 // Add error counter
456 Status = NDIS_STATUS_FAILURE;
457 bDropFrame = TRUE;
458 break;
462 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) && (pWpaKey != NULL)) // TKIP
464 if (pHeader->Controlhead.Frame.Wep)
466 UCHAR Eiv_Tmp[4];
468 NdisMoveMemory((PUCHAR) &pRxD->Iv, pData, 4); //Get WEP IV
469 // Swap EIV byte order, due to ASIC's bug.
470 Eiv_Tmp[0] = *(pData + 7);
471 Eiv_Tmp[1] = *(pData + 6);
472 Eiv_Tmp[2] = *(pData + 5);
473 Eiv_Tmp[3] = *(pData + 4);
474 NdisMoveMemory((PUCHAR) &pRxD->Eiv, Eiv_Tmp, 4); //Get WEP EIV
475 KeyIdx = (*(pData + 3) & 0xc0) >> 6;
476 // Copy TA into RxD
477 NdisMoveMemory(pRxD->TA, &pHeader->Controlhead.Addr2, 6);
478 NdisMoveMemory(pRxD->Key, pWpaKey->Key, 16);
479 pRxD->CipherAlg = CIPHER_TKIP;
481 else if ((pAdapter->PortCfg.PrivacyFilter == Ndis802_11PrivFilter8021xWEP) &&
482 (pHeader->Frag == 0))
484 // Check 802.1x frame, if not drop it.
485 if (!RTMPEqualMemory(EAPOL, pData + 6, 2))
487 // Not 802.1X frames
488 // Add error counter
489 Status = NDIS_STATUS_FAILURE;
490 bDropFrame = TRUE;
491 break;
495 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled) && (pWpaKey != NULL)) // AES
497 if (pHeader->Controlhead.Frame.Wep)
499 NdisMoveMemory((PUCHAR) &pRxD->Iv, pData, 4); //Get WEP IV
500 NdisMoveMemory((PUCHAR) &pRxD->Eiv, (pData + 4), 4); //Get WEP EIV
501 // Copy TA into RxD
502 NdisMoveMemory(pRxD->TA, &pHeader->Controlhead.Addr2, 6);
503 KeyIdx = (*(pData + 3) & 0xc0) >> 6;
504 NdisMoveMemory(pRxD->Key, pWpaKey->Key, 16);
505 pRxD->CipherAlg = CIPHER_AES;
507 else if ((pAdapter->PortCfg.PrivacyFilter == Ndis802_11PrivFilter8021xWEP) &&
508 (pHeader->Frag == 0))
510 // Check 802.1x frame, if not drop it.
511 if (!RTMPEqualMemory(EAPOL, pData + 6, 2))
513 // Not 802.1X frames
514 // Add error counter
515 Status = NDIS_STATUS_FAILURE;
516 bDropFrame = TRUE;
517 break;
521 else if (pHeader->Controlhead.Frame.Wep)
523 // Drop WEP frame when PrivacyInvoked is FALSE
524 Status = NDIS_STATUS_FAILURE;
525 bDropFrame = TRUE;
526 break;
528 else // Not encryptrd frames
530 pRxD->CipherAlg = CIPHER_NONE;
533 break;
535 case BTYPE_MGMT:
536 // Always None encrypted
537 pRxD->CipherAlg = CIPHER_NONE;
538 break;
540 case BTYPE_CNTL:
541 // Ignore ???
542 bDropFrame = TRUE;
543 break;
545 default :
546 bDropFrame = TRUE;
547 break;
550 else
551 bDropFrame = TRUE;
553 // Packet will still do NULL cipher operation and drop afterward
554 if (bDropFrame == TRUE)
556 pRxD->Drop = 1;
557 pRxD->CipherAlg = CIPHER_NONE;
559 else
561 pRxD->Drop = 0;
562 pRxD->IvOffset = LENGTH_802_11;
565 pRxD->CipherOwner = DESC_OWN_NIC;
567 #ifdef BIG_ENDIAN
568 RTMPFrameEndianChange(pAdapter, (PUCHAR)pHeader, DIR_WRITE, TRUE);
569 RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
570 //*pDestRxD = RxD;
571 WriteBackToDescriptor((PUCHAR)pDestRxD, (PUCHAR)pRxD, TRUE, TYPE_RXD);
572 #endif
574 pAdapter->CurRxIndex++;
575 if (pAdapter->CurRxIndex >= RX_RING_SIZE)
577 pAdapter->CurRxIndex = 0;
579 Count++;
581 pAdapter->RalinkCounters.RxCount ++;
583 } while (Count < MAX_RX_PROCESS);
585 // Kick Decrypt Control Register, based on ASIC's implementation
586 // We have to kick decrypt & encrypt every frame.
587 RTMP_IO_WRITE32(pAdapter, SECCSR0, 0x1);
589 // Make sure to release Rx ring resource
590 NdisReleaseSpinLock(&pAdapter->RxRingLock, IrqFlags);
594 ========================================================================
596 Routine Description:
597 Process TxRing TxDone interrupt, running in DPC level
599 Arguments:
600 Adapter Pointer to our adapter
602 Return Value:
603 None
605 Note:
607 ========================================================================
609 VOID RTMPHandleTxRingTxDoneInterrupt(
610 IN PRTMP_ADAPTER pAdapter)
612 PTXD_STRUC pTxD;
613 #ifdef BIG_ENDIAN
614 PTXD_STRUC pDestTxD;
615 TXD_STRUC TxD;
616 #endif
617 UCHAR Count;
618 ULONG IrqFlags;
620 // Make sure Tx ring resource won't be used by other threads
621 NdisAcquireSpinLock(&pAdapter->TxRingLock, IrqFlags);
623 Count = 0;
626 #ifndef BIG_ENDIAN
627 pTxD = (PTXD_STRUC) (pAdapter->TxRing[pAdapter->NextTxDoneIndex].va_addr);
628 #else
629 pDestTxD = (PTXD_STRUC) (pAdapter->TxRing[pAdapter->NextTxDoneIndex].va_addr);
630 TxD = *pDestTxD;
631 pTxD = &TxD;
632 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
633 #endif
635 if ((pTxD->Owner == DESC_OWN_NIC) || (pTxD->CipherOwn == DESC_OWN_NIC) || (pTxD->Valid == FALSE))
637 break;
640 RTMPHardTransmitDone(
641 pAdapter,
642 pTxD,
643 pAdapter->TxRing[pAdapter->NextTxDoneIndex].FrameType);
645 // It might happend with no Ndis packet to indicate back to upper layer
646 // Clear for NdisSendComplete request
647 pTxD->Valid = FALSE;
649 // Increase Total transmit byte counter after real data sent out
650 pAdapter->RalinkCounters.TransmittedByteCount += pTxD->DataByteCnt;
652 #ifdef BIG_ENDIAN
653 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
654 *pDestTxD = TxD;
655 #endif
657 pAdapter->NextTxDoneIndex++;
658 if (pAdapter->NextTxDoneIndex >= TX_RING_SIZE)
660 pAdapter->NextTxDoneIndex = 0;
662 } while (++Count < MAX_TX_PROCESS);
664 #ifdef RALINK_ATE
665 if((pAdapter->ate.Mode == ATE_TXCONT) || (pAdapter->ate.Mode == ATE_TXCARR) || ((pAdapter->ate.Mode == ATE_TXFRAME)))
667 if (pAdapter->ate.TxDoneCount < pAdapter->ate.TxCount)
669 pAdapter->ate.TxDoneCount++;
670 DBGPRINT(RT_DEBUG_INFO, "pAdapter->ate.TxDoneCount = %d, Preamble=%d\n", pAdapter->ate.TxDoneCount, pAdapter->PortCfg.TxPreambleInUsed);
671 pTxD = (PTXD_STRUC)pAdapter->TxRing[pAdapter->CurEncryptIndex].va_addr;
673 RTMPWriteTxDescriptor(pTxD, TRUE, CIPHER_NONE, FALSE, FALSE, FALSE,
674 SHORT_RETRY, IFS_BACKOFF, pAdapter->ate.TxRate, 4,
675 pAdapter->ate.TxLength, Rt802_11PreambleLong, 0);
677 pAdapter->CurEncryptIndex++;
678 if (pAdapter->CurEncryptIndex >= TX_RING_SIZE)
680 pAdapter->CurEncryptIndex = 0;
683 RTMP_IO_WRITE32(pAdapter, SECCSR1, 0x1);
685 else if (pAdapter->ate.Mode == ATE_TXFRAME)
687 DBGPRINT(RT_DEBUG_TRACE, "ATE TXFRAME completed!\n");
690 #endif //#ifdef RALINK_ATE
692 // Make sure to release Tx ring resource
693 NdisReleaseSpinLock(&pAdapter->TxRingLock, IrqFlags);
695 if(pAdapter->bNetDeviceStopQueue)
697 if(pAdapter->TxSwQueue0.Number < (MAX_PACKETS_IN_QUEUE >> 2))
699 DBGPRINT(RT_DEBUG_TRACE, "NetDevice start queue!!!\n\n");
700 pAdapter->bNetDeviceStopQueue = FALSE;
701 netif_start_queue(pAdapter->net_dev);
705 // Some Tx ring resource freed, check for pending send frame for hard transmit
706 if ((!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
707 (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF)) &&
708 (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS)))
710 // RTMPDeQueuePacket(pAdapter, &pAdapter->TxSwQueue0);
711 // Call dequeue without selected queue, let the subroutine select the right priority
712 // Tx software queue
713 RTMPDeQueuePacket(pAdapter);
718 ========================================================================
720 Routine Description:
721 Process Priority ring TxDone interrupt, running in DPC level
723 Arguments:
724 Adapter Pointer to our adapter
726 Return Value:
727 None
729 Note:
731 ========================================================================
733 VOID RTMPHandlePrioRingTxDoneInterrupt(
734 IN PRTMP_ADAPTER pAdapter)
736 PTXD_STRUC pTxD;
737 #ifdef BIG_ENDIAN
738 PTXD_STRUC pDestTxD;
739 TXD_STRUC TxD;
740 #endif
741 UCHAR Count;
742 PMGMT_STRUC pMgmt;
743 ULONG IrqFlags;
745 // Make sure Prio ring resource won't be used by other threads
746 NdisAcquireSpinLock(&pAdapter->PrioRingLock, IrqFlags);
748 Count = 0;
751 #ifndef BIG_ENDIAN
752 pTxD = (PTXD_STRUC) (pAdapter->PrioRing[pAdapter->NextPrioDoneIndex].va_addr);
753 #else
754 pDestTxD = (PTXD_STRUC) (pAdapter->PrioRing[pAdapter->NextPrioDoneIndex].va_addr);
755 TxD = *pDestTxD;
756 pTxD = &TxD;
757 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
758 #endif
760 // Check for the descriptor ownership
761 if ((pTxD->Owner == DESC_OWN_NIC) || (pTxD->Valid == FALSE))
763 #ifdef BIG_ENDIAN
764 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
765 *pDestTxD = TxD;
766 #endif
767 break;
770 // No need to put in reply for MLME
771 RTMPHardTransmitDone(
772 pAdapter,
773 pTxD,
774 pAdapter->PrioRing[pAdapter->NextPrioDoneIndex].FrameType);
776 // It might happend with no Ndis packet to indicate back to upper layer
777 pTxD->Valid = FALSE;
779 // Increase Total transmit byte counter after real data sent out
780 pAdapter->RalinkCounters.TransmittedByteCount += pTxD->DataByteCnt;
782 #ifdef BIG_ENDIAN
783 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
784 *pDestTxD = TxD;
785 #endif
787 pAdapter->NextPrioDoneIndex++;
788 if (pAdapter->NextPrioDoneIndex >= PRIO_RING_SIZE)
790 pAdapter->NextPrioDoneIndex = 0;
792 } while (++Count < MAX_TX_PROCESS);
794 // Make sure to release Prio ring resource
795 NdisReleaseSpinLock(&pAdapter->PrioRingLock, IrqFlags);
797 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF))
798 return;
800 if (pAdapter->PushMgmtIndex != pAdapter->PopMgmtIndex)
802 if (RTMPFreeDescriptorRequest(pAdapter, PRIO_RING, 1) == NDIS_STATUS_SUCCESS)
804 pMgmt = (PMGMT_STRUC) &pAdapter->MgmtRing[pAdapter->PopMgmtIndex];
805 if (pMgmt->Valid == TRUE)
807 MlmeHardTransmit(pAdapter, pMgmt->pBuffer, pMgmt->Length);
808 MlmeFreeMemory(pAdapter, pMgmt->pBuffer);
809 pMgmt->Valid = FALSE;
810 NdisAcquireSpinLock(&pAdapter->PrioRingLock, IrqFlags);
811 pAdapter->PopMgmtIndex++;
812 pAdapter->MgmtQueueSize--;
813 if (pAdapter->PopMgmtIndex >= MGMT_RING_SIZE)
815 pAdapter->PopMgmtIndex = 0;
817 NdisReleaseSpinLock(&pAdapter->PrioRingLock, IrqFlags);
824 ========================================================================
826 Routine Description:
827 Process Atim ring TxDone interrupt, running in DPC level
829 Arguments:
830 Adapter Pointer to our adapter
832 Return Value:
833 None
835 Note:
837 ========================================================================
839 VOID RTMPHandleAtimRingTxDoneInterrupt(
840 IN PRTMP_ADAPTER pAdapter)
842 // PTXD_STRUC pTxD;
843 // UCHAR Count;
845 // Make sure Atim ring resource won't be used by other threads
846 //NdisAcquireSpinLock(&pAdapter->AtimRingLock);
848 // Did not support ATIM, remove everything.
850 // Make sure to release Atim ring resource
851 //NdisReleaseSpinLock(&pAdapter->AtimRingLock);
855 ========================================================================
857 Routine Description:
858 Process Rx ring DecryptionDone interrupt, running in DPC level
860 Arguments:
861 Adapter Pointer to our adapter
863 Return Value:
864 None
866 Note:
868 ========================================================================
870 VOID RTMPHandleDecryptionDoneInterrupt(
871 IN PRTMP_ADAPTER pAdapter)
873 PRXD_STRUC pRxD;
874 #ifdef BIG_ENDIAN
875 PRXD_STRUC pDestRxD;
876 RXD_STRUC RxD;
877 #endif
878 PHEADER_802_11 pHeader;
879 PUCHAR pData;
880 PVOID pManage;
881 PUCHAR pDestMac, pSrcMac;
882 UCHAR Header802_3[14];
883 UCHAR LLC_Len[2];
884 USHORT PacketSize;
885 ULONG High32TSF, Low32TSF;
886 UCHAR Count;
887 PWPA_KEY pWpaKey;
888 NDIS_STATUS Status;
889 ULONG RegValue;
890 ULONG HwDecryptIndex;
891 ULONG i;
892 struct sk_buff *skb;
893 ULONG IrqFlags;
895 // Make sure Rx ring resource won't be used by other threads
896 NdisAcquireSpinLock(&pAdapter->RxRingLock, IrqFlags);
898 RTMP_IO_READ32(pAdapter, SECCSR0, &RegValue);
899 HwDecryptIndex = (RegValue - pAdapter->RxRing[0].pa_addr) / RING_DESCRIPTOR_SIZE;
901 Count = 0;
902 //do
903 while (pAdapter->CurDecryptIndex != HwDecryptIndex)
905 // Point to Rx indexed rx ring descriptor
906 #ifndef BIG_ENDIAN
907 pRxD = (PRXD_STRUC) pAdapter->RxRing[pAdapter->CurDecryptIndex].va_addr;
908 #else
909 pDestRxD = (PRXD_STRUC) pAdapter->RxRing[pAdapter->CurDecryptIndex].va_addr;
910 RxD = *pDestRxD;
911 pRxD = &RxD;
912 RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
913 #endif
915 // In case of false alarm or processed at last instance
916 if ((pRxD->Owner != DESC_OWN_HOST) || (pRxD->CipherOwner != DESC_OWN_HOST))
917 break;
919 // Point to Rx ring buffer where stores the real data frame
920 pData = (PUCHAR) (pAdapter->RxRing[pAdapter->CurDecryptIndex].va_data_addr);
921 // Cast to 802.11 header for flags checking
922 pHeader = (PHEADER_802_11) pData;
924 #ifdef BIG_ENDIAN
925 RTMPFrameEndianChange(pAdapter, (PUCHAR)pHeader, DIR_READ, FALSE);
926 #endif
927 // Driver will check the decrypt algorithm and decide whether this ICV is true or not
928 if ((pRxD->IcvError == 1) && (pRxD->CipherAlg == CIPHER_NONE))
929 pRxD->IcvError = 0;
931 // Since we already process header at RxDone interrupt, there is no need to proces
932 // header sanity again, the only thing we have to check is icv_err bit
933 //if (pRxD->IcvError == 1)
934 if ((pRxD->IcvError == 1) && (pRxD->CipherAlg != CIPHER_NONE))
936 DBGPRINT(RT_DEBUG_TRACE,"Rx DecryptDone - ICV error (len %d)\n", pRxD->DataByteCnt);
937 pRxD->Drop =1; // Drop frame with icv error
939 // Saved data pointer for management frame which will pass to MLME block
940 pManage = (PVOID) pData;
942 // pData : Pointer skip the first 24 bytes, 802.11 HEADER
943 pData += LENGTH_802_11;
945 // The total available payload should exclude 24-byte 802.11 Header
946 // If Security is enabled, IV, EIV, ICV size is excluded by ASIC
947 PacketSize = (USHORT) pRxD->DataByteCnt - LENGTH_802_11;
949 // Find the WPA key, either Group or Pairwise Key
950 // Although the data has been decrypted by ASIC,
951 // driver has to calculate the RxMIC which required the key.
952 // The failed case should not happen. If it did, drop it.
953 // Init WPA Key
954 pWpaKey = (PWPA_KEY) NULL;
955 if ((pAdapter->PortCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pHeader->Controlhead.Frame.Wep))
957 INT idx;
959 // First lookup the DA, if it's a group address, use GROUP key
960 if (pRxD->Bcast || pRxD->Mcast)
962 // Get the IV index from RxD descriptor
963 #ifdef BIG_ENDIAN
964 idx = (pRxD->Iv & 0x000000c0) >> 6;
965 #else
966 idx = (pRxD->Iv & 0xc0000000) >> 30;
967 #endif
968 if ((pAdapter->PortCfg.GroupKey[idx].KeyLen != 0) &&
969 ((INFRA_ON(pAdapter) && (NdisEqualMemory(&pHeader->Controlhead.Addr2, &pAdapter->PortCfg.Bssid, 6))) ||
970 (ADHOC_ON(pAdapter) && (NdisEqualMemory(&pHeader->Addr3, &pAdapter->PortCfg.Bssid, 6)))))
972 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.GroupKey[idx];
973 pWpaKey->Type = GROUP_KEY;
974 DBGPRINT(RT_DEBUG_INFO, "Decrypt Done: Rx Use Group Key %d\n", idx);
977 // Try to find the Pairwise Key
978 else
980 for (idx = 0; idx < PAIRWISE_KEY_NO; idx++)
982 if ((NdisEqualMemory(&pHeader->Controlhead.Addr2, pAdapter->PortCfg.PairwiseKey[idx].BssId, 6)) &&
983 (pAdapter->PortCfg.PairwiseKey[idx].KeyLen != 0))
985 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.PairwiseKey[idx];
986 pWpaKey->Type = PAIRWISE_KEY;
987 DBGPRINT(RT_DEBUG_INFO, "Rx Use Pairwise Key\n");
988 break;
991 #if 1
992 // Use default Group Key if there is no Pairwise key present
993 if ((pWpaKey == NULL) && (pAdapter->PortCfg.GroupKey[pAdapter->PortCfg.DefaultKeyId].KeyLen != 0))
995 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.GroupKey[pAdapter->PortCfg.DefaultKeyId];
996 pWpaKey->Type = GROUP_KEY;
997 DBGPRINT(RT_DEBUG_INFO, "Rx Use Group Key\n");
999 #endif
1002 // If there is no WPA key matched, this frame should be dropped
1003 if (pWpaKey == NULL)
1004 pRxD->Drop = 1;
1008 // Start of main loop to parse receiving frames.
1009 // The sequence will be Type first, then subtype...
1011 if (pRxD->Drop == 0)
1013 switch (pHeader->Controlhead.Frame.Type)
1015 // Frame with data type
1016 case BTYPE_DATA:
1017 // DA is always address 1
1018 // For infrastructure, SA is address 3. For IBSS mode, SA is address 2
1019 pDestMac = (PUCHAR) &(pHeader->Controlhead.Addr1);
1020 if (INFRA_ON(pAdapter))
1021 pSrcMac = (PUCHAR) &(pHeader->Addr3);
1022 else
1023 pSrcMac = (PUCHAR) &(pHeader->Controlhead.Addr2);
1025 // Process Broadcast & Multicast data frame
1026 if (pRxD->Bcast || pRxD->Mcast)
1028 // For TKIP frame, calculate the MIC value
1029 if (pRxD->CipherAlg == CIPHER_TKIP)
1031 INT i = 0;
1033 if (pWpaKey == NULL)
1035 DBGPRINT(RT_DEBUG_ERROR,"No matched TKIP in decryption done calculate MIC routine!!!\n");
1036 Status = NDIS_STATUS_FAILURE;
1037 break;
1040 // Minus MIC length
1041 PacketSize -= 8;
1042 if (RTMPTkipCompareMICValue(
1043 pAdapter,
1044 pData,
1045 pDestMac,
1046 pSrcMac,
1047 pWpaKey->RxMic,
1048 PacketSize) == FALSE)
1050 DBGPRINT(RT_DEBUG_ERROR,"Rx MIC Value error\n");
1051 RTMPReportMicError(pAdapter, pWpaKey);
1052 Status = NDIS_STATUS_FAILURE;
1053 break;
1056 // Second, increase RxTsc value for next transmission
1057 while (++pWpaKey->RxTsc[i] == 0x0)
1059 i++;
1060 if (i == 6)
1061 break;
1063 // Rx TSC has done one full cycle, since re-key is done by transmitter
1064 // We did not do anything for Rx path
1067 // build 802.3 header and decide if remove the 8-byte LLC/SNAP encapsulation
1068 CONVERT_TO_802_3(Header802_3, pDestMac, pSrcMac, pData, PacketSize);
1070 pAdapter->PortCfg.LedCntl.fRxActivity = TRUE; // for RX ACTIVITY LED
1072 // For miniportTransferData
1073 pAdapter->pRxData = pData;
1075 // Acknolwdge upper layer the received frame
1076 if ((skb = __dev_alloc_skb(PacketSize + LENGTH_802_3 + 2, GFP_DMA|GFP_ATOMIC)) != NULL)
1078 skb->dev = pAdapter->net_dev;
1079 skb_reserve(skb, 2); // 16 byte align the IP header
1080 memcpy(skb_put(skb, LENGTH_802_3), Header802_3, LENGTH_802_3);
1081 memcpy(skb_put(skb, PacketSize), pData, PacketSize);
1082 skb->protocol = eth_type_trans(skb, pAdapter->net_dev);
1083 netif_rx(skb);
1084 pAdapter->net_dev->last_rx = jiffies;
1085 pAdapter->stats.rx_packets++;
1088 DBGPRINT(RT_DEBUG_INFO, "!!! Broadcast Ethenet rx Indicated !!!\n");
1091 // Begin process unicast to me frame
1092 else if (pRxD->U2M)
1094 // Update Rx data rate first.
1095 if (pRxD->Ofdm == 1)
1097 for (i = 4; i < 12; i++)
1099 if (pRxD->BBR0 == PlcpSignal[i])
1100 break;
1102 if (i < 12)
1103 pAdapter->LastRxRate = i;
1105 else // receive CCK encoding
1107 if (pRxD->BBR0 == 10)
1108 pAdapter->LastRxRate = 0;
1109 else if (pRxD->BBR0 == 20)
1110 pAdapter->LastRxRate = 1;
1111 else if (pRxD->BBR0 == 55)
1112 pAdapter->LastRxRate = 2;
1113 else if (pRxD->BBR0 == 110)
1114 pAdapter->LastRxRate = 3;
1117 if (pHeader->Frag == 0) // First or Only fragment
1119 // For TKIP frame, calculate the MIC value
1120 if ((pHeader->Controlhead.Frame.MoreFrag == FALSE) &&
1121 (pRxD->CipherAlg == CIPHER_TKIP) &&
1122 (pHeader->Controlhead.Frame.Wep))
1124 if (pWpaKey == NULL)
1126 DBGPRINT(RT_DEBUG_ERROR,"No matched TKIP in decryption done calculate MIC routine!!!\n");
1127 Status = NDIS_STATUS_FAILURE;
1128 break;
1130 // Minus MIC length
1131 PacketSize -= 8;
1132 if (RTMPTkipCompareMICValue(
1133 pAdapter,
1134 pData,
1135 pDestMac,
1136 pSrcMac,
1137 pWpaKey->RxMic,
1138 PacketSize) == FALSE)
1140 DBGPRINT(RT_DEBUG_ERROR,"Rx MIC Value error\n");
1141 RTMPReportMicError(pAdapter, pWpaKey);
1142 Status = NDIS_STATUS_FAILURE;
1143 break;
1147 pAdapter->FragFrame.Flags &= 0xFFFFFFFE;
1149 // Check for encapsulation other than RFC1042 & Bridge tunnel
1150 if ((!RTMPEqualMemory(SNAP_802_1H, pData, 6)) &&
1151 (!RTMPEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6)))
1153 LLC_Len[0] = PacketSize / 256;
1154 LLC_Len[1] = PacketSize % 256;
1155 MAKE_802_3_HEADER(Header802_3, pDestMac, pSrcMac, ((PUCHAR) LLC_Len));
1157 else
1159 char *pProto = pData + 6;
1161 // Remove 802.11 H header & reconstruct 802.3 header
1162 // pData += (LENGTH_802_1_H - LENGTH_802_3_TYPE);
1163 // Check for EAPOL frame when driver supplicant enabled
1164 // TODO: It is not strickly correct. There is no fragment handling. It might damage driver
1165 // TODO: But for WPAPSK, it's not likely fragment on EAPOL frame will happen
1166 if (RTMPEqualMemory(EAPOL, pProto, 2) && ((pAdapter->PortCfg.WpaState != SS_NOTUSE)))
1168 RTMP_IO_READ32(pAdapter, CSR17, &High32TSF); // TSF value
1169 RTMP_IO_READ32(pAdapter, CSR16, &Low32TSF); // TSF vlaue
1170 PacketSize += LENGTH_802_11;
1171 // Enqueue this frame to MLME engine
1172 MlmeEnqueueForRecv(
1173 pAdapter,
1174 &pAdapter->Mlme.Queue,
1175 High32TSF,
1176 Low32TSF,
1177 (UCHAR)pRxD->BBR1,
1178 PacketSize,
1179 pManage);
1180 break;
1183 if ((RTMPEqualMemory(IPX, pProto, 2) || RTMPEqualMemory(APPLE_TALK, pProto, 2)) &&
1184 RTMPEqualMemory(SNAP_802_1H, pData, 6))
1186 // preserved the LLC/SNAP filed
1187 LLC_Len[0] = PacketSize / 256;
1188 LLC_Len[1] = PacketSize % 256;
1189 MAKE_802_3_HEADER(Header802_3, pDestMac, pSrcMac, ((PUCHAR) LLC_Len));
1191 else
1193 // remove the LLC/SNAP field
1194 MAKE_802_3_HEADER(Header802_3, pDestMac, pSrcMac, pProto);
1195 NdisMoveMemory(pAdapter->FragFrame.Header_LLC, pData, 8);
1196 PacketSize -= LENGTH_802_1_H;
1197 pData += LENGTH_802_1_H;
1198 pAdapter->FragFrame.Flags |= 0x01;
1202 // One & The only fragment
1203 if (pHeader->Controlhead.Frame.MoreFrag == FALSE)
1205 // For miniportTransferData
1206 pAdapter->pRxData = pData;
1208 pAdapter->PortCfg.LedCntl.fRxActivity = TRUE; // for RX ACTIVITY LED
1210 // Acknowledge upper layer the received frame
1211 if ((skb = __dev_alloc_skb(PacketSize + LENGTH_802_3 + 2, GFP_DMA|GFP_ATOMIC)) != NULL)
1213 skb->dev = pAdapter->net_dev;
1214 skb_reserve(skb, 2); // 16 byte align the IP header
1215 memcpy(skb_put(skb, LENGTH_802_3), Header802_3, LENGTH_802_3);
1216 memcpy(skb_put(skb, PacketSize), pData, PacketSize);
1217 skb->protocol = eth_type_trans(skb, pAdapter->net_dev);
1218 netif_rx(skb);
1219 pAdapter->net_dev->last_rx = jiffies;
1220 pAdapter->stats.rx_packets++;
1223 // NdisZeroMemory(Header802_3, LENGTH_802_3);
1224 DBGPRINT(RT_DEBUG_INFO, "!!! Frame without Fragment Indicated !!!\n");
1226 // Increase general counters
1227 pAdapter->Counters.GoodReceives++;
1230 // First fragment of fragmented frames
1231 else
1233 NdisMoveMemory(&pAdapter->FragFrame.Buffer[LENGTH_802_3], pData, PacketSize);
1234 NdisMoveMemory(pAdapter->FragFrame.Header802_3, Header802_3, LENGTH_802_3);
1235 //NdisZeroMemory(Header802_3, LENGTH_802_3);
1236 pAdapter->FragFrame.RxSize = PacketSize;
1237 pAdapter->FragFrame.Sequence = pHeader->Sequence;
1238 pAdapter->FragFrame.LastFrag = pHeader->Frag; // Should be 0
1241 // Middle & End of fragment burst fragments
1242 else
1244 // No LLC-SNAP header in except the first fragment frame
1246 if ((pHeader->Sequence != pAdapter->FragFrame.Sequence) ||
1247 (pHeader->Frag != (pAdapter->FragFrame.LastFrag + 1)))
1249 // Fragment is not the same sequence or out of fragment number order
1250 // Clear Fragment frame contents
1251 NdisZeroMemory(&pAdapter->FragFrame, sizeof(FRAGMENT_FRAME));
1252 Status = NDIS_STATUS_FAILURE;
1253 break;
1255 else if ((pAdapter->FragFrame.RxSize + PacketSize) > MAX_FRAME_SIZE)
1257 // Fragment frame is too large, it exeeds the maximum frame size.
1258 // We have to drop it.
1259 // Clear Fragment frame contents
1260 NdisZeroMemory(&pAdapter->FragFrame, sizeof(FRAGMENT_FRAME));
1261 Status = NDIS_STATUS_FAILURE;
1262 break;
1265 // concatenate this fragment into the re-assembly buffer
1266 NdisMoveMemory(&pAdapter->FragFrame.Buffer[LENGTH_802_3 + pAdapter->FragFrame.RxSize], pData, PacketSize);
1267 pAdapter->FragFrame.RxSize += PacketSize;
1268 pAdapter->FragFrame.LastFrag = pHeader->Frag; // Update fragment number
1270 // Last fragment
1271 if (pHeader->Controlhead.Frame.MoreFrag == FALSE)
1273 // For TKIP frame, calculate the MIC value
1274 if ((pRxD->CipherAlg == CIPHER_TKIP) && (pHeader->Controlhead.Frame.Wep))
1276 if (pWpaKey == NULL)
1278 DBGPRINT(RT_DEBUG_ERROR,"No matched TKIP in decryption done calculate MIC routine!!!\n");
1279 Status = NDIS_STATUS_FAILURE;
1280 break;
1282 // Minus MIC length
1283 pAdapter->FragFrame.RxSize -= 8;
1285 if (pAdapter->FragFrame.Flags & 0x00000001)
1287 // originally there's an LLC/SNAP field in the first fragment
1288 // but been removed in re-assembly buffer. here we have to include
1289 // this LLC/SNAP field upon calculating TKIP MIC
1290 // Copy LLC data to the position in front of real data for MIC calculation
1291 NdisMoveMemory(&pAdapter->FragFrame.Buffer[LENGTH_802_3 - LENGTH_802_1_H],
1292 pAdapter->FragFrame.Header_LLC,
1293 LENGTH_802_1_H);
1294 pData = (PUCHAR) &pAdapter->FragFrame.Buffer[LENGTH_802_3 - LENGTH_802_1_H];
1295 PacketSize = (USHORT)pAdapter->FragFrame.RxSize + LENGTH_802_1_H;
1296 //cketSize = (USHORT)pAdapter->FragFrame.RxSize + 8;
1298 else
1300 pData = &pAdapter->FragFrame.Buffer[LENGTH_802_3];
1301 PacketSize = (USHORT)pAdapter->FragFrame.RxSize;
1304 if (RTMPTkipCompareMICValue(
1305 pAdapter,
1306 pData,
1307 pDestMac,
1308 pSrcMac,
1309 pWpaKey->RxMic,
1310 PacketSize) == FALSE)
1312 DBGPRINT(RT_DEBUG_ERROR,"Rx MIC Value error 2\n");
1313 RTMPReportMicError(pAdapter, pWpaKey);
1314 Status = NDIS_STATUS_FAILURE;
1315 break;
1318 // TODO:
1319 // Getting RxTSC from Rx descriptor
1322 // for RX ACTIVITY LED
1323 pAdapter->PortCfg.LedCntl.fRxActivity = TRUE;
1325 // For miniportTransferData
1326 pAdapter->pRxData = &pAdapter->FragFrame.Buffer[LENGTH_802_3];
1328 NdisMoveMemory(pAdapter->FragFrame.Buffer, pAdapter->FragFrame.Header802_3, LENGTH_802_3);
1329 // Acknowledge upper layer the received frame
1330 if ((skb = __dev_alloc_skb(pAdapter->FragFrame.RxSize + LENGTH_802_3 + 2, GFP_DMA|GFP_ATOMIC)) != NULL)
1332 skb->dev = pAdapter->net_dev;
1333 skb_reserve(skb, 2); /* 16 byte align the IP header */
1334 memcpy(skb_put(skb, LENGTH_802_3), (PVOID) &pAdapter->FragFrame.Buffer[0], LENGTH_802_3);
1335 memcpy(skb_put(skb, pAdapter->FragFrame.RxSize), (PVOID) &pAdapter->FragFrame.Buffer[LENGTH_802_3], pAdapter->FragFrame.RxSize);
1336 skb->protocol = eth_type_trans(skb, pAdapter->net_dev);
1337 netif_rx(skb);
1338 pAdapter->net_dev->last_rx = jiffies;
1339 pAdapter->stats.rx_packets++;
1342 // Increase general counters
1343 pAdapter->Counters.GoodReceives++;
1345 // Clear Fragment frame contents
1346 NdisZeroMemory(&pAdapter->FragFrame, sizeof(FRAGMENT_FRAME));
1347 DBGPRINT(RT_DEBUG_INFO, "!!! Frame with Fragment Indicated !!!\n");
1351 break;
1353 case BTYPE_MGMT:
1354 // Read required regsiter for MLME engine
1355 RTMP_IO_READ32(pAdapter, CSR17, &High32TSF); // TSF value
1356 RTMP_IO_READ32(pAdapter, CSR16, &Low32TSF); // TSF vlaue
1358 // Enqueue this frame to MLME engine
1359 MlmeEnqueueForRecv(
1360 pAdapter,
1361 &pAdapter->Mlme.Queue,
1362 High32TSF,
1363 Low32TSF,
1364 (UCHAR)pRxD->BBR1,
1365 pRxD->DataByteCnt,
1366 pManage);
1367 break;
1369 case BTYPE_CNTL:
1370 // Ignore ???
1371 break;
1373 default :
1374 break;
1378 pAdapter->CurDecryptIndex++;
1379 if (pAdapter->CurDecryptIndex >= RX_RING_SIZE)
1381 pAdapter->CurDecryptIndex = 0;
1383 Count++;
1385 pAdapter->RalinkCounters.DecryptCount ++;
1387 // Clear Cipherowner bit & Rx Owner bit for all drop & non-drop frames
1388 pRxD->CipherOwner = DESC_OWN_HOST;
1389 pRxD->Owner = DESC_OWN_NIC;
1390 #ifdef BIG_ENDIAN
1391 RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
1392 //*pDestRxD = RxD;
1393 WriteBackToDescriptor((PUCHAR)pDestRxD, (PUCHAR)pRxD, FALSE, TYPE_RXD);
1394 #endif
1396 //} while (Count < RX_RING_SIZE);
1397 //} while (pAdapter->CurDecryptIndex != HwDecryptIndex);
1399 // Make sure to release Rx ring resource
1400 NdisReleaseSpinLock(&pAdapter->RxRingLock, IrqFlags);
1404 ========================================================================
1406 Routine Description:
1407 Process Tx ring EncryptionDone interrupt, running in DPC level
1409 Arguments:
1410 Adapter Pointer to our adapter
1412 Return Value:
1413 None
1415 Note:
1417 ========================================================================
1419 VOID RTMPHandleEncryptionDoneInterrupt(
1420 IN PRTMP_ADAPTER pAdapter)
1422 PTXD_STRUC pTxD;
1423 #ifdef BIG_ENDIAN
1424 PTXD_STRUC pDestTxD;
1425 TXD_STRUC TxD;
1426 #endif
1427 UCHAR Count;
1428 ULONG RegValue;
1429 ULONG HwEncryptIndex;
1430 ULONG IrqFlags;
1432 // Make sure Prio ring resource won't be used by other threads
1433 NdisAcquireSpinLock(&pAdapter->TxRingLock, IrqFlags);
1435 RTMP_IO_READ32(pAdapter, SECCSR1, &RegValue);
1436 HwEncryptIndex = (RegValue - pAdapter->TxRing[0].pa_addr) / RING_DESCRIPTOR_SIZE;
1438 Count = 0;
1439 //do
1440 while (pAdapter->NextEncryptDoneIndex != HwEncryptIndex)
1442 #ifndef BIG_ENDIAN
1443 pTxD = (PTXD_STRUC) (pAdapter->TxRing[pAdapter->NextEncryptDoneIndex].va_addr);
1444 #else
1445 pDestTxD = (PTXD_STRUC) (pAdapter->TxRing[pAdapter->NextEncryptDoneIndex].va_addr);
1446 TxD = *pDestTxD;
1447 pTxD = &TxD;
1448 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1449 #endif
1451 // Check for the descriptor cipher ownership
1452 if ((pTxD->CipherOwn == DESC_OWN_NIC) || (pTxD->Owner == DESC_OWN_NIC))
1454 pAdapter->RalinkCounters.TxRingErrCount++;
1455 #ifdef BIG_ENDIAN
1456 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1457 *pDestTxD = TxD;
1458 #endif
1459 break;
1462 // Alter EIV due to ASIC's bug
1463 if (pTxD->CipherAlg == CIPHER_TKIP)
1465 UCHAR Eiv_Tmp[4];
1466 PUCHAR pTmp;
1468 NdisMoveMemory(Eiv_Tmp, &pTxD->Eiv, 4);
1469 pTmp = (PUCHAR) &pTxD->Eiv;
1470 *pTmp = Eiv_Tmp[3];
1471 *(pTmp + 1) = Eiv_Tmp[2];
1472 *(pTmp + 2) = Eiv_Tmp[1];
1473 *(pTmp + 3) = Eiv_Tmp[0];
1475 // Sanity Check, CurTxIndex should equal to NextEncryptDoneIndex
1476 // ASSERT(pAdapter->CurTxIndex == pAdapter->NextEncryptDoneIndex);
1478 pTxD->Valid = TRUE;
1479 pTxD->Owner = DESC_OWN_NIC;
1481 #ifdef BIG_ENDIAN
1482 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1483 //*pDestTxD = TxD;
1484 WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
1485 #endif
1487 pAdapter->NextEncryptDoneIndex++;
1488 if (pAdapter->NextEncryptDoneIndex >= TX_RING_SIZE)
1490 pAdapter->NextEncryptDoneIndex = 0;
1492 pAdapter->CurTxIndex = pAdapter->NextEncryptDoneIndex;
1493 pAdapter->RalinkCounters.KickTxCount++;
1495 if (pAdapter->CurTxIndex == pAdapter->CurEncryptIndex)
1496 break;
1498 //} while (++Count < MAX_TX_PROCESS);
1499 //} while (pAdapter->NextEncryptDoneIndex != HwEncryptIndex);
1501 // Kick Tx Control Register at the end of all ring buffer preparation
1502 RTMP_IO_WRITE32(pAdapter, TXCSR0, 0x1);
1504 // Make sure to release Tx ring resource
1505 NdisReleaseSpinLock(&pAdapter->TxRingLock, IrqFlags);
1509 ========================================================================
1511 Routine Description:
1512 Arguments:
1513 Adapter Pointer to our adapter
1514 ========================================================================
1516 void RTMPHandleTbcnInterrupt(IN PRTMP_ADAPTER pAdapter)
1518 if (ADHOC_ON(pAdapter))
1520 MACHDR *pBcnHdr = (MACHDR *)pAdapter->BeaconRing.va_data_addr;
1522 // update BEACON frame's sequence number
1523 pAdapter->Sequence = ((pAdapter->Sequence) + 1) & (MAX_SEQ_NUMBER);
1524 pBcnHdr->Seq = pAdapter->Sequence;
1526 #ifdef BIG_ENDIAN
1527 *(USHORT *)((UCHAR *)pBcnHdr + 22) = SWAP16(*(USHORT *)((UCHAR *)pBcnHdr + 22));
1528 #endif
1533 ========================================================================
1535 Routine Description:
1536 Arguments:
1537 Adapter Pointer to our adapter
1538 ========================================================================
1540 void RTMPHandleTwakeupInterrupt(IN PRTMP_ADAPTER pAdapter)
1542 // DBGPRINT(RT_DEBUG_ERROR, ("Twakeup Expired... !!!\n"));
1543 pAdapter->PortCfg.Pss = PWR_ACTIVE;
1547 ========================================================================
1549 Routine Description:
1550 Process all transmit ring Tx Done interrupt, running in DPC level
1552 Arguments:
1553 Adapter Pointer to our adapter
1555 Return Value:
1556 None
1558 Note:
1560 ========================================================================
1562 VOID RTMPHardTransmitDone(
1563 IN PRTMP_ADAPTER pAdapter,
1564 IN PTXD_STRUC pTxD,
1565 IN UCHAR FrameType)
1568 switch (pTxD->TxResult)
1570 case SUCCESS_WITHOUT_RETRY: // Success without any retry
1571 // Return send complete status
1572 // DBGPRINT(RT_DEBUG_INFO, "TX Success without retry<<<\n");
1573 if (pTxD->RTS)
1575 // Increase 802.11 counters
1576 INC_COUNTER(pAdapter->WlanCounters.RTSSuccessCount);
1577 pTxD->RTS = 0;
1580 // Increase general counters
1581 pAdapter->Counters.GoodTransmits++;
1582 INC_COUNTER(pAdapter->WlanCounters.TransmittedFragmentCount);
1584 // update DRS related counters
1585 if (pTxD->ACK && (FrameType == BTYPE_DATA))
1587 pAdapter->DrsCounters.OneSecTxOkCount ++;
1589 break;
1591 case SUCCESS_WITH_RETRY: // Success with some retry
1592 // DBGPRINT(RT_DEBUG_INFO, "TX Success with retry(=%d)<<<\n",pTxD->RetryCount);
1593 // Increase 802.11 counters
1594 INC_COUNTER(pAdapter->WlanCounters.RetryCount);
1595 INC_COUNTER(pAdapter->WlanCounters.ACKFailureCount);
1596 INC_COUNTER(pAdapter->WlanCounters.TransmittedFragmentCount);
1598 // Increase general counters
1599 pAdapter->Counters.GoodTransmits++;
1601 if (pTxD->RetryCount > 1)
1603 // Increase 802.11 counters
1604 INC_COUNTER(pAdapter->WlanCounters.MultipleRetryCount);
1606 // Increase general counters
1607 pAdapter->Counters.MoreCollisions++;
1609 else
1611 // Increase general counters
1612 pAdapter->Counters.OneCollision++;
1615 if (pTxD->RTS)
1617 INC_COUNTER(pAdapter->WlanCounters.RTSSuccessCount);
1618 pTxD->RTS = 0;
1621 // update DRS related counters
1622 if (pTxD->ACK && (FrameType == BTYPE_DATA))
1624 if (pTxD->TxRate > pAdapter->PortCfg.TxRate)
1626 // DRS - must be NULL frame retried @ UpRate; downgrade
1627 // TxQuality[UpRate] so that not upgrade TX rate
1628 pAdapter->DrsCounters.TxQuality[pTxD->TxRate] += 2;
1629 if (pAdapter->DrsCounters.TxQuality[pTxD->TxRate] > DRS_TX_QUALITY_WORST_BOUND)
1630 pAdapter->DrsCounters.TxQuality[pTxD->TxRate] = DRS_TX_QUALITY_WORST_BOUND;
1632 else if (pTxD->TxRate == pAdapter->PortCfg.TxRate)
1633 pAdapter->DrsCounters.OneSecTxRetryOkCount ++;
1635 break;
1637 case FAIL_RETRY_LIMIT: // Fail on hitting retry count limit
1638 // DBGPRINT(RT_DEBUG_WARN, ("TX Failed (RETRY LIMIT)<<<\n"));
1639 // Increase 802.11 counters
1640 INC_COUNTER(pAdapter->WlanCounters.FailedCount);
1641 INC_COUNTER(pAdapter->WlanCounters.ACKFailureCount);
1643 // Increase general counters
1644 pAdapter->Counters.TxErrors++;
1646 if (pTxD->RTS)
1648 INC_COUNTER(pAdapter->WlanCounters.RTSFailureCount);
1649 pTxD->RTS = 0;
1652 // update DRS related counters
1653 if (pTxD->ACK && (FrameType == BTYPE_DATA))
1655 if (pTxD->TxRate > pAdapter->PortCfg.TxRate)
1657 // DRS - must be NULL frame failed @ UpRate; downgrade
1658 // TxQuality[UpRate] so that not upgrade TX rate
1659 pAdapter->DrsCounters.TxQuality[pTxD->TxRate] = DRS_TX_QUALITY_WORST_BOUND;
1661 else if (pTxD->TxRate == pAdapter->PortCfg.TxRate)
1663 pAdapter->DrsCounters.OneSecTxFailCount ++;
1666 break;
1668 case FAIL_INVALID:
1669 // DBGPRINT(RT_DEBUG_WARN, ("TX Failed (INVALID)<<<\n"));
1670 // Increase general counters
1671 pAdapter->Counters.TxErrors++;
1673 if (pTxD->RTS)
1675 INC_COUNTER(pAdapter->WlanCounters.RTSFailureCount);
1676 pTxD->RTS = 0;
1678 break;
1680 case FAIL_OTHER:
1681 default:
1682 // DBGPRINT(RT_DEBUG_ERROR, ("TX Failed (other=%d)<<<\n",pTxD->TxResult));
1683 // Increase 802.11 counters
1684 INC_COUNTER(pAdapter->WlanCounters.FailedCount);
1685 INC_COUNTER(pAdapter->WlanCounters.ACKFailureCount);
1687 // Increase general counters
1688 pAdapter->Counters.TxErrors++;
1690 if (pTxD->RTS)
1692 INC_COUNTER(pAdapter->WlanCounters.RTSFailureCount);
1693 pTxD->RTS = 0;
1695 break;
1700 ========================================================================
1702 Routine Description:
1703 API for MLME to transmit management frame to AP (BSS Mode)
1704 or station (IBSS Mode)
1706 Arguments:
1707 pAdapter Pointer to our adapter
1708 Buffer Pointer to memory of outgoing frame
1709 Length Size of outgoing management frame
1711 Return Value:
1712 NDIS_STATUS_FAILURE
1713 NDIS_STATUS_PENDING
1714 NDIS_STATUS_SUCCESS
1716 Note:
1718 ========================================================================
1720 NDIS_STATUS MiniportMMRequest(
1721 IN PRTMP_ADAPTER pAdapter,
1722 IN PVOID pBuffer,
1723 IN ULONG Length)
1725 PMGMT_STRUC pMgmt;
1726 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
1727 ULONG IrqFlags;
1729 DBGPRINT(RT_DEBUG_INFO, "---> MiniportMMRequest\n");
1730 // Check management ring free avaliability
1731 pMgmt = (PMGMT_STRUC) &pAdapter->MgmtRing[pAdapter->PushMgmtIndex];
1733 // This management cell has been occupied
1734 if (pMgmt->Valid == TRUE)
1736 // No Management ring buffer avaliable
1737 MlmeFreeMemory(pAdapter, pBuffer);
1738 Status = NDIS_STATUS_FAILURE;
1739 DBGPRINT(RT_DEBUG_WARN, "<--- MiniportMMRequest (error:: MgmtRing full)\n");
1740 pAdapter->RalinkCounters.MgmtRingFullCount++;
1741 return (Status);
1744 // Insert this request into software managemnet ring
1745 if (pBuffer)
1747 pMgmt->pBuffer = pBuffer;
1748 pMgmt->Length = Length;
1749 pMgmt->Valid = TRUE;
1750 pAdapter->PushMgmtIndex++;
1751 pAdapter->MgmtQueueSize++;
1752 if (pAdapter->PushMgmtIndex >= MGMT_RING_SIZE)
1754 pAdapter->PushMgmtIndex = 0;
1757 else
1759 // Null pBuffer, no need to free memory buffer.
1760 // This should not happen
1761 DBGPRINT(RT_DEBUG_WARN, "<--- MiniportMMRequest (error:: NULL msg)\n");
1762 Status = NDIS_STATUS_FAILURE;
1763 return (Status);
1766 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF))
1767 return (Status);
1769 // Check Free priority queue
1770 if (RTMPFreeDescriptorRequest(pAdapter, PRIO_RING, 1) == NDIS_STATUS_SUCCESS)
1772 pMgmt = (PMGMT_STRUC) &pAdapter->MgmtRing[pAdapter->PopMgmtIndex];
1773 if (pMgmt->Valid == TRUE)
1775 MlmeHardTransmit(pAdapter, pMgmt->pBuffer, pMgmt->Length);
1776 MlmeFreeMemory(pAdapter, pMgmt->pBuffer);
1777 pMgmt->Valid = FALSE;
1778 NdisAcquireSpinLock(&pAdapter->PrioRingLock, IrqFlags);
1779 pAdapter->PopMgmtIndex++;
1780 pAdapter->MgmtQueueSize--;
1781 if (pAdapter->PopMgmtIndex >= MGMT_RING_SIZE)
1783 pAdapter->PopMgmtIndex = 0;
1785 NdisReleaseSpinLock(&pAdapter->PrioRingLock, IrqFlags);
1788 else
1790 DBGPRINT(RT_DEBUG_TRACE, "not enough space in PrioRing\n");
1793 DBGPRINT(RT_DEBUG_INFO, "<--- MiniportMMRequest\n");
1794 return (Status);
1798 ========================================================================
1800 Routine Description:
1801 Copy frame from waiting queue into relative ring buffer and set
1802 appropriate ASIC register to kick hardware transmit function
1804 Arguments:
1805 pAdapter Pointer to our adapter
1806 pBuffer Pointer to memory of outgoing frame
1807 Length Size of outgoing management frame
1809 Return Value:
1810 NDIS_STATUS_FAILURE
1811 NDIS_STATUS_PENDING
1812 NDIS_STATUS_SUCCESS
1814 Note:
1816 ========================================================================
1818 VOID MlmeHardTransmit(
1819 IN PRTMP_ADAPTER pAdapter,
1820 IN PVOID pBuffer,
1821 IN ULONG Length)
1823 PTXD_STRUC pTxD;
1824 #ifdef BIG_ENDIAN
1825 PTXD_STRUC pDestTxD;
1826 TXD_STRUC TxD;
1827 #endif
1828 PUCHAR pDest;
1829 PHEADER_802_11 pHeader_802_11;
1830 BOOLEAN AckRequired, InsertTimestamp;
1831 ULONG IrqFlags;
1833 DBGPRINT(RT_DEBUG_INFO, "MlmeHardTransmit\n");
1835 // Make sure Prio ring resource won't be used by other threads
1836 NdisAcquireSpinLock(&pAdapter->PrioRingLock, IrqFlags);
1838 pDest = (PUCHAR) pAdapter->PrioRing[pAdapter->CurPrioIndex].va_data_addr;
1839 #ifndef BIG_ENDIAN
1840 pTxD = (PTXD_STRUC) pAdapter->PrioRing[pAdapter->CurPrioIndex].va_addr;
1841 #else
1842 pDestTxD = (PTXD_STRUC) pAdapter->PrioRing[pAdapter->CurPrioIndex].va_addr;
1843 TxD = *pDestTxD;
1844 pTxD = &TxD;
1845 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1846 #endif
1848 if (pTxD->Owner == DESC_OWN_NIC)
1850 // Descriptor owned by NIC. No descriptor avaliable
1851 // This should not happen since caller guaranteed.
1852 // Make sure to release Prio ring resource
1853 NdisReleaseSpinLock(&pAdapter->PrioRingLock, IrqFlags);
1854 return;
1856 if (pTxD->Valid == TRUE)
1858 // Ndis packet of last round did not cleared.
1859 // This should not happen since caller guaranteed.
1860 // Make sure to release Prio ring resource
1861 NdisReleaseSpinLock(&pAdapter->PrioRingLock, IrqFlags);
1862 return;
1864 if (pBuffer == NULL)
1866 // The buffer shouldn't be NULL
1867 NdisReleaseSpinLock(&pAdapter->PrioRingLock, IrqFlags);
1868 return;
1871 // outgoing frame always wakeup PHY to prevent frame lost
1872 AsicForceWakeup(pAdapter);
1874 pHeader_802_11 = (PHEADER_802_11) pBuffer;
1875 pHeader_802_11->Controlhead.Frame.PwrMgt = 0; // (pAdapter->PortCfg.Psm == PWR_SAVE);
1876 InsertTimestamp = FALSE;
1877 if (pHeader_802_11->Controlhead.Frame.Type == BTYPE_CNTL) // must be PS-POLL
1879 AckRequired = FALSE;
1880 pAdapter->PrioRing[pAdapter->CurPrioIndex].FrameType = BTYPE_CNTL;
1882 else // BTYPE_MGMT or BMGMT_DATA(must be NULL frame)
1884 pAdapter->PrioRing[pAdapter->CurPrioIndex].FrameType = BTYPE_MGMT;
1885 pAdapter->Sequence = ((pAdapter->Sequence) + 1) & (MAX_SEQ_NUMBER);
1886 pHeader_802_11->Sequence = pAdapter->Sequence;
1888 if (pHeader_802_11->Controlhead.Addr1.Octet[0] & 0x01) // MULTICAST, BROADCAST
1890 AckRequired = FALSE;
1891 pHeader_802_11->Controlhead.Duration = 0;
1893 else
1895 AckRequired = TRUE;
1896 pHeader_802_11->Controlhead.Duration = RTMPCalcDuration(pAdapter, pAdapter->PortCfg.MlmeRate, 14);
1897 if (pHeader_802_11->Controlhead.Frame.Subtype == SUBTYPE_PROBE_RSP)
1899 InsertTimestamp = TRUE;
1903 #ifdef BIG_ENDIAN
1904 RTMPFrameEndianChange(pAdapter, (PUCHAR)pBuffer, DIR_WRITE, FALSE);
1905 #endif
1906 NdisMoveMemory(pDest, pBuffer, Length);
1908 // Initialize Priority Descriptor
1909 // For inter-frame gap, the number is for this frame and next frame
1910 // For MLME rate, we will fix as 2Mb to match other vendor's implement
1911 #ifdef BIG_ENDIAN
1912 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1913 *pDestTxD = TxD;
1914 pTxD = pDestTxD;
1915 #endif
1916 RTMPWriteTxDescriptor(pTxD, FALSE, CIPHER_NONE, AckRequired, FALSE, InsertTimestamp,
1917 SHORT_RETRY, IFS_BACKOFF, pAdapter->PortCfg.MlmeRate, 4, Length, pAdapter->PortCfg.TxPreambleInUsed, 0);
1919 // Increase & maintain Tx Ring Index
1920 pAdapter->CurPrioIndex++;
1921 if (pAdapter->CurPrioIndex >= PRIO_RING_SIZE)
1923 pAdapter->CurPrioIndex = 0;
1926 // Kick priority ring transmit
1927 RTMP_IO_WRITE32(pAdapter,TXCSR0,0x4);
1929 // Make sure to release Prio ring resource
1930 NdisReleaseSpinLock(&pAdapter->PrioRingLock, IrqFlags);
1933 ========================================================================
1935 Routine Description:
1936 This routine is used to en-queue outgoing packets when
1937 there is no enough shread memory
1939 Arguments:
1940 pAdapter Pointer to our adapter
1941 pPacket Pointer to send packet
1943 Return Value:
1944 None
1946 Note:
1948 ========================================================================
1950 NDIS_STATUS RTMPSendPacket(
1951 IN PRTMP_ADAPTER pAdapter,
1952 IN struct sk_buff *skb)
1954 PVOID pVirtualAddress;
1955 UINT AllowFragSize;
1956 UCHAR NumberOfFrag;
1957 UCHAR RTSRequired;
1958 NDIS_STATUS Status = NDIS_STATUS_FAILURE;
1959 UCHAR PsMode;
1961 PQUEUE_HEADER pTxQueue = NULL;
1962 ULONG Priority;
1963 UCHAR AccessCategory;
1964 ULONG IrqFlags;
1966 DBGPRINT(RT_DEBUG_INFO, "<==== RTMPSendPacket\n");
1968 // Init priority value
1969 Priority = 0;
1970 AccessCategory = 0;
1972 if (skb)
1974 Priority = skb->priority;
1975 // 802.11e/d4.4 June, 2003
1976 if (Priority <=2)
1977 AccessCategory = 0;
1978 else if (Priority == 3)
1979 AccessCategory = 1;
1980 else if (Priority <= 5)
1981 AccessCategory = 2;
1982 else
1983 AccessCategory = 3;
1984 DBGPRINT(RT_DEBUG_INFO, "Priority = %d, AC = %d\n", Priority, AccessCategory);
1987 // For TKIP, MIC value is treated as payload, it might be fragmented through
1988 // different MPDUs.
1989 if (pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled)
1991 skb->data_len += 8;
1994 pVirtualAddress = (PVOID)skb->data;
1996 // Check for virtual address allocation, it might fail !!!
1997 if (pVirtualAddress == NULL)
1999 // Resourece is low, system did not allocation virtual address
2000 // return NDIS_STATUS_FAILURE directly to upper layer
2001 return (Status);
2004 // Store Ethernet MAC address when APClinet mode on
2005 if ((pAdapter->PortCfg.StaWithEtherBridge.Enable)
2006 && ((*((PUCHAR) pVirtualAddress) & 0x01) == 0)
2007 && !MAC_ADDR_EQUAL(&pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr, ((PUCHAR) pVirtualAddress) + 6)
2008 /*&& !MAC_ADDR_EQUAL(&pAdapter->PermanentAddress, ((PUCHAR) pVirtualAddress) + 6)*/)
2010 CSR3_STRUC StaMacReg0;
2011 CSR4_STRUC StaMacReg1;
2013 COPY_MAC_ADDR(&pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr, ((PUCHAR) pVirtualAddress) + 6);
2015 StaMacReg0.field.Byte0 = pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr.Octet[0];
2016 StaMacReg0.field.Byte1 = pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr.Octet[1];
2017 StaMacReg0.field.Byte2 = pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr.Octet[2];
2018 StaMacReg0.field.Byte3 = pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr.Octet[3];
2020 StaMacReg1.field.Byte4 = pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr.Octet[4];
2021 StaMacReg1.field.Byte5 = pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr.Octet[5];
2023 pAdapter->CurrentAddress[0] = StaMacReg0.field.Byte0;
2024 pAdapter->CurrentAddress[1] = StaMacReg0.field.Byte1;
2025 pAdapter->CurrentAddress[2] = StaMacReg0.field.Byte2;
2026 pAdapter->CurrentAddress[3] = StaMacReg0.field.Byte3;
2027 pAdapter->CurrentAddress[4] = StaMacReg1.field.Byte4;
2028 pAdapter->CurrentAddress[5] = StaMacReg1.field.Byte5;
2030 RTMP_IO_WRITE32(pAdapter, CSR3, StaMacReg0.word);
2031 RTMP_IO_WRITE32(pAdapter, CSR4, StaMacReg1.word);
2033 DBGPRINT(RT_DEBUG_TRACE, "StaWithEtherBridge - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
2034 pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr.Octet[0],pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr.Octet[1],pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr.Octet[2],
2035 pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr.Octet[3],pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr.Octet[4],pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr.Octet[5]);
2039 // Check for multicast or broadcast (First byte of DA)
2041 if ((*((PUCHAR) pVirtualAddress) & 0x01) != 0)
2043 // For multicast & broadcast, there is no fragment allowed
2044 NumberOfFrag = 1;
2046 else
2048 // Check for payload allowed for each fragment
2049 AllowFragSize = (pAdapter->PortCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;
2051 // Calculate fragments required
2052 NumberOfFrag = ((skb->data_len - LENGTH_802_3 + LENGTH_802_1_H) / AllowFragSize) + 1;
2053 // Minus 1 if the size just match to allowable fragment size
2054 if (((skb->data_len - LENGTH_802_3 + LENGTH_802_1_H) % AllowFragSize) == 0)
2056 NumberOfFrag--;
2060 // Check for requirement of RTS
2061 if (NumberOfFrag > 1)
2063 // If multiple fragment required, RTS is required only for the first fragment
2064 // if the fragment size large than RTS threshold
2065 RTSRequired = (pAdapter->PortCfg.FragmentThreshold > pAdapter->PortCfg.RtsThreshold) ? 1 : 0;
2067 else
2069 RTSRequired = (skb->data_len > pAdapter->PortCfg.RtsThreshold) ? 1 : 0;
2071 DBGPRINT(RT_DEBUG_INFO, "Number of fragments include RTS :%d\n", NumberOfFrag + RTSRequired);
2073 // RTS/CTS may also be required in order to protect OFDM frame
2074 if ((pAdapter->PortCfg.TxRate >= RATE_FIRST_OFDM_RATE) && pAdapter->PortCfg.BGProtectionInUsed)
2075 RTSRequired = 1;
2077 // Save framnet number to Ndis packet reserved field
2078 RTMP_SET_PACKET_FRAGMENTS(skb, NumberOfFrag);
2080 // Save RTS requirement to Ndis packet reserved field
2081 RTMP_SET_PACKET_RTS(skb, RTSRequired);
2083 // Make sure SendTxWait queue resource won't be used by other threads
2084 NdisAcquireSpinLock(&pAdapter->TxSwQueueLock, IrqFlags);
2086 // Select the right priority queue
2087 // There should be no else statement since it should always fall within 0-3
2088 if (AccessCategory== 0)
2089 pTxQueue = &pAdapter->TxSwQueue0;
2090 else if (AccessCategory== 1)
2091 pTxQueue = &pAdapter->TxSwQueue1;
2092 else if (AccessCategory== 2)
2093 pTxQueue = &pAdapter->TxSwQueue2;
2094 else if (AccessCategory== 3)
2095 pTxQueue = &pAdapter->TxSwQueue3;
2098 // For infrastructure mode, enqueue this frame immediately to sendwaitqueue
2099 // For Ad-hoc mode, check the DA power state, then decide which queue to enqueue
2101 if (INFRA_ON(pAdapter))
2103 if(pTxQueue->Number > MAX_PACKETS_IN_QUEUE)
2105 DBGPRINT(RT_DEBUG_WARN, "pTxQueue is full!!!\n\n");
2106 pAdapter->bNetDeviceStopQueue = TRUE;
2107 netif_stop_queue(pAdapter->net_dev);
2110 // In infrastructure mode, simply enqueue the packet into Tx waiting queue.
2111 DBGPRINT(RT_DEBUG_INFO, "Infrastructure -> Enqueue one frame\n");
2113 // Enqueue Ndis packet to end of Tx wait queue
2114 InsertTailQueue(pTxQueue, skb);
2115 Status = NDIS_STATUS_SUCCESS;
2117 else
2119 if(pTxQueue->Number > MAX_PACKETS_IN_QUEUE)
2121 DBGPRINT(RT_DEBUG_WARN, "pTxQueue is full!!!\n\n");
2122 pAdapter->bNetDeviceStopQueue = TRUE;
2123 netif_stop_queue(pAdapter->net_dev);
2126 // In IBSS mode, power state of destination should be considered.
2127 PsMode = PWR_ACTIVE; // Faked
2128 if (PsMode == PWR_ACTIVE)
2130 DBGPRINT(RT_DEBUG_INFO,"Ad-Hoc -> Enqueue one frame\n");
2132 // Enqueue Ndis packet to end of Tx wait queue
2133 InsertTailQueue(pTxQueue, skb);
2134 Status = NDIS_STATUS_SUCCESS;
2138 NdisReleaseSpinLock(&pAdapter->TxSwQueueLock, IrqFlags);
2139 return (Status);
2143 ========================================================================
2145 Routine Description:
2146 To do the enqueue operation and extract the first item of waiting
2147 list. If a number of available shared memory segments could meet
2148 the request of extracted item, the extracted item will be fragmented
2149 into shared memory segments.
2151 Arguments:
2152 pAdapter Pointer to our adapter
2153 pQueue Pointer to Waiting Queue
2155 Return Value:
2156 None
2158 Note:
2160 ========================================================================
2162 VOID RTMPDeQueuePacket(
2163 IN PRTMP_ADAPTER pAdapter)
2165 UCHAR FragmentRequired;
2166 NDIS_STATUS Status;
2167 UCHAR Count = 0;
2168 PQUEUE_HEADER pQueue;
2169 ULONG Number;
2170 UCHAR AccessCategory;
2171 struct sk_buff *skb;
2172 ULONG IrqFlags;
2174 // Make sure SendTxWait queue resource won't be used by other threads
2175 NdisAcquireSpinLock(&pAdapter->TxSwQueueLock, IrqFlags);
2177 while (((pQueue = RTMPCheckTxSwQueue(pAdapter, &Number, &AccessCategory)) != NULL) && (Count < MAX_TX_PROCESS))
2178 // Check queue before dequeue
2179 // while ((pQueue->Head != NULL) && (Count < MAX_TX_PROCESS))
2181 // Reset is in progress, stop immediately
2182 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS))
2184 break;
2187 // Dequeue the first entry from head of queue list
2188 skb = (struct sk_buff *)RemoveHeadQueue(pQueue);
2190 // RTS or CTS-to-self for B/G protection mode has been set already.
2191 // There is no need to re-do it here.
2192 // Total fragment required = number of fragment + RST if required
2193 FragmentRequired = RTMP_GET_PACKET_FRAGMENTS(skb) + RTMP_GET_PACKET_RTS(skb);
2195 if (RTMPFreeDescriptorRequest(pAdapter, TX_RING, FragmentRequired) == NDIS_STATUS_SUCCESS)
2197 // Avaliable ring descriptors are enough for this frame
2198 // Call hard transmit
2199 // Nitro mode / Normal mode selection
2200 if ((pAdapter->PortCfg.EnableTxBurst == 1) && (Number > 1))
2201 Status = RTMPHardEncrypt(pAdapter, skb, FragmentRequired, TRUE, AccessCategory);
2202 else
2203 Status = RTMPHardEncrypt(pAdapter, skb, FragmentRequired, FALSE, AccessCategory);
2204 if (Status == NDIS_STATUS_FAILURE)
2206 // Packet failed due to various Ndis Packet error
2207 RTMPFreeSkbBuffer(skb);
2208 break;
2210 else if (Status == NDIS_STATUS_RESOURCES)
2212 // Not enough free tx ring, it might happen due to free descriptor inquery might be not correct
2213 // It also might change to NDIS_STATUS_FAILURE to simply drop the frame
2214 // Put the frame back into head of queue
2215 InsertHeadQueue(pQueue, skb);
2216 break;
2218 Count++;
2220 else
2222 InsertHeadQueue(pQueue, skb);
2223 pAdapter->PrivateInfo.TxRingFullCnt++;
2224 DBGPRINT(RT_DEBUG_INFO,"RTMPDequeuePacket --> Not enough free Tx Ring descriptor (CurEncryptIndex=%d,CurTxIndex=%d, NextTxDoneIndex=%d)!!!\n",
2225 pAdapter->CurEncryptIndex, pAdapter->CurTxIndex, pAdapter->NextTxDoneIndex);
2226 break;
2230 // Release TxSwQueue0 resources
2231 NdisReleaseSpinLock(&pAdapter->TxSwQueueLock, IrqFlags);
2235 ========================================================================
2237 Routine Description:
2238 This subroutine will scan through releative ring descriptor to find
2239 out avaliable free ring descriptor and compare with request size.
2241 Arguments:
2242 pAdapter Pointer to our adapter
2243 RingType Selected Ring
2245 Return Value:
2246 NDIS_STATUS_FAILURE Not enough free descriptor
2247 NDIS_STATUS_SUCCESS Enough free descriptor
2249 Note:
2251 ========================================================================
2253 NDIS_STATUS RTMPFreeDescriptorRequest(
2254 IN PRTMP_ADAPTER pAdapter,
2255 IN UCHAR RingType,
2256 IN UCHAR NumberRequired)
2258 UCHAR FreeNumber = 0;
2259 UINT Index;
2260 PTXD_STRUC pTxD;
2261 #ifdef BIG_ENDIAN
2262 PTXD_STRUC pDestTxD;
2263 TXD_STRUC TxD;
2264 #endif
2265 NDIS_STATUS Status = NDIS_STATUS_FAILURE;
2266 ULONG IrqFlags;
2268 switch (RingType)
2270 case TX_RING:
2271 NdisAcquireSpinLock(&pAdapter->TxRingLock, IrqFlags);
2272 Index = pAdapter->CurEncryptIndex;
2275 #ifndef BIG_ENDIAN
2276 pTxD = (PTXD_STRUC) pAdapter->TxRing[Index].va_addr;
2277 #else
2278 pDestTxD = (PTXD_STRUC) pAdapter->TxRing[Index].va_addr;
2279 TxD = *pDestTxD;
2280 pTxD = &TxD;
2281 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2282 #endif
2284 // While Owner bit is NIC, obviously ASIC still need it.
2285 // If valid bit is TRUE, indicate that TxDone has not process yet
2286 // We should not use it until TxDone finish cleanup job
2287 if ((pTxD->Owner == DESC_OWN_HOST) && (pTxD->CipherOwn == DESC_OWN_HOST) && (pTxD->Valid == FALSE))
2289 // This one is free
2290 FreeNumber++;
2292 else
2294 DBGPRINT(RT_DEBUG_INFO,"RTMPFreeDescriptorRequest fail - Owner=%d,CipherOwn=%d,Valid=%d\n",pTxD->Owner, pTxD->CipherOwn, pTxD->Valid);
2295 break;
2298 Index++;
2299 if (Index >= TX_RING_SIZE) // Wrap around issue
2301 Index = 0;
2304 } while (FreeNumber < NumberRequired); // Quit here ! Free number is enough !
2306 if (FreeNumber >= NumberRequired)
2308 Status = NDIS_STATUS_SUCCESS;
2311 // Make sure to release Tx ring resource
2312 NdisReleaseSpinLock(&pAdapter->TxRingLock, IrqFlags);
2313 break;
2315 case PRIO_RING:
2316 NdisAcquireSpinLock(&pAdapter->PrioRingLock, IrqFlags);
2317 Index = pAdapter->CurPrioIndex;
2320 #ifndef BIG_ENDIAN
2321 pTxD = (PTXD_STRUC) pAdapter->PrioRing[Index].va_addr;
2322 #else
2323 pDestTxD = (PTXD_STRUC) pAdapter->PrioRing[Index].va_addr;
2324 TxD = *pDestTxD;
2325 pTxD = &TxD;
2326 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2327 #endif
2329 // While Owner bit is NIC, obviously ASIC still need it.
2330 // If valid bit is TRUE, indicate that TxDone has not process yet
2331 // We should not use it until TxDone finish cleanup job
2332 if ((pTxD->Owner == DESC_OWN_HOST) && (pTxD->Valid == FALSE))
2334 // This one is free
2335 FreeNumber++;
2337 else
2339 break;
2342 Index++;
2343 if (Index >= PRIO_RING_SIZE) // Wrap around issue
2345 Index = 0;
2348 } while (FreeNumber < NumberRequired); // Quit here ! Free number is enough !
2350 if (FreeNumber >= NumberRequired)
2352 Status = NDIS_STATUS_SUCCESS;
2355 // Make sure to release Prio ring resource
2356 NdisReleaseSpinLock(&pAdapter->PrioRingLock, IrqFlags);
2357 break;
2359 default:
2360 break;
2363 return (Status);
2366 VOID RTMPSendNullFrame(
2367 IN PRTMP_ADAPTER pAdapter,
2368 IN PVOID pBuffer,
2369 IN ULONG Length,
2370 IN UCHAR TxRate)
2372 PUCHAR pDest;
2373 PTXD_STRUC pTxD;
2374 UCHAR FrameGap;
2375 #ifdef BIG_ENDIAN
2376 PTXD_STRUC pDestTxD;
2377 TXD_STRUC TxD;
2378 #endif
2379 ULONG IrqFlags;
2381 if (pBuffer == NULL)
2383 return;
2386 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS))
2388 MlmeFreeMemory(pAdapter, pBuffer);
2389 return;
2392 // WPA 802.1x secured port control
2393 if (((pAdapter->PortCfg.AuthMode == Ndis802_11AuthModeWPA) ||
2394 (pAdapter->PortCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) &&
2395 (pAdapter->PortCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
2397 MlmeFreeMemory(pAdapter, pBuffer);
2398 return;
2401 FrameGap = IFS_BACKOFF; // Default frame gap mode
2403 // outgoing frame always wakeup PHY to prevent frame lost and
2404 // turn off PSM bit to improve performance
2405 AsicForceWakeup(pAdapter);
2406 #if 0
2407 if ((pAdapter->TxSwQueue0.Number != 0) || (pAdapter->TxSwQueue1.Number != 0) ||
2408 (pAdapter->TxSwQueue2.Number != 0) || (pAdapter->TxSwQueue3.Number != 0))
2410 DBGPRINT(RT_DEBUG_TRACE,("Drop Null frame due to Tx queue not empty!\n"));
2412 else
2413 #endif
2415 // Make sure Tx ring resource won't be used by other threads
2416 NdisAcquireSpinLock(&pAdapter->TxRingLock, IrqFlags);
2418 // Get the Tx Ring descriptor & Dma Buffer address
2419 pDest = (PUCHAR) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_data_addr;
2420 #ifndef BIG_ENDIAN
2421 pTxD = (PTXD_STRUC) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_addr;
2422 #else
2423 pDestTxD = (PTXD_STRUC) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_addr;
2424 TxD = *pDestTxD;
2425 pTxD = &TxD;
2426 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2427 #endif
2429 if ((pTxD->Owner == DESC_OWN_HOST) && (pTxD->CipherOwn == DESC_OWN_HOST) && (pTxD->Valid == FALSE))
2431 HEADER_802_11 *pHeader_802_11;
2433 DBGPRINT(RT_DEBUG_TRACE, "SYNC - send NULL Frame @%d Mbps...\n", RateIdToMbps[TxRate]);
2434 #ifdef BIG_ENDIAN
2435 RTMPFrameEndianChange(pAdapter, (PUCHAR)pBuffer, DIR_WRITE, FALSE);
2436 #endif
2437 NdisMoveMemory(pDest, pBuffer, Length);
2438 pAdapter->TxRing[pAdapter->CurEncryptIndex].FrameType = BTYPE_DATA;
2440 pHeader_802_11 = (PHEADER_802_11) pDest;
2441 pHeader_802_11->Controlhead.Frame.PwrMgt = (pAdapter->PortCfg.Psm == PWR_SAVE);
2443 #ifdef BIG_ENDIAN
2444 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2445 *pDestTxD = TxD;
2446 pTxD = pDestTxD;
2447 #endif
2449 RTMPWriteTxDescriptor(pTxD, TRUE, CIPHER_NONE, TRUE, FALSE, FALSE, LONG_RETRY, IFS_BACKOFF,
2450 TxRate, 4, Length, pAdapter->PortCfg.TxPreambleInUsed, 0);
2452 // Increase & maintain Tx Ring Index
2453 pAdapter->CurEncryptIndex++;
2454 if (pAdapter->CurEncryptIndex >= TX_RING_SIZE)
2456 pAdapter->CurEncryptIndex = 0;
2459 pAdapter->RalinkCounters.EncryptCount++;
2461 // Kick Encrypt Control Register at the end of all ring buffer preparation
2462 RTMP_IO_WRITE32(pAdapter, SECCSR1, 0x1);
2465 NdisReleaseSpinLock(&pAdapter->TxRingLock, IrqFlags);
2467 MlmeFreeMemory(pAdapter, pBuffer);
2471 ========================================================================
2473 Routine Description:
2474 Copy frame from waiting queue into relative ring buffer and set
2475 appropriate ASIC register to kick hardware encryption before really
2476 sent out to air.
2478 Arguments:
2479 pAdapter Pointer to our adapter
2480 PNDIS_PACKET Pointer to outgoing Ndis frame
2481 NumberOfFrag Number of fragment required
2483 Return Value:
2484 None
2486 Note:
2488 ========================================================================
2490 NDIS_STATUS RTMPHardEncrypt(
2491 IN PRTMP_ADAPTER pAdapter,
2492 IN struct sk_buff *skb,
2493 IN UCHAR NumberRequired,
2494 IN ULONG EnableTxBurst,
2495 IN UCHAR AccessCategory)
2497 PVOID pVirtualAddress;
2498 UINT NdisBufferLength;
2499 UINT BytesCopied;
2500 UINT TxSize;
2501 UINT FreeFragSize;
2502 UINT RemainSize;
2503 USHORT Protocol;
2504 UCHAR FrameGap;
2505 HEADER_802_11 Header_802_11;
2506 PUCHAR pDest;
2507 PUCHAR pSrc;
2508 PUCHAR pEncap;
2509 UCHAR CipherAlg;
2510 PTXD_STRUC pTxD;
2511 BOOLEAN StartOfFrame;
2512 BOOLEAN EAPOLFrame;
2513 BOOLEAN Encapped;
2514 ULONG Iv16;
2515 ULONG Iv32;
2516 BOOLEAN MICFrag;
2517 PWPA_KEY pWpaKey = NULL;
2518 UCHAR RetryMode = SHORT_RETRY;
2519 UCHAR AckRate = RATE_2;
2520 USHORT AckDuration = 0;
2521 USHORT EncryptionOverhead = 0;
2522 #ifdef BIG_ENDIAN
2523 PTXD_STRUC pDestTxD;
2524 TXD_STRUC TxD;
2525 PUCHAR pOriginDest;
2526 #endif
2527 ULONG IrqFlags;
2529 // Make sure Tx ring resource won't be used by other threads
2530 NdisAcquireSpinLock(&pAdapter->TxRingLock, IrqFlags);
2532 if(skb->data == NULL)
2534 DBGPRINT(RT_DEBUG_ERROR, "Error, Null skb data buffer!!!\n");
2536 NdisReleaseSpinLock(&pAdapter->TxRingLock, IrqFlags);
2537 return (NDIS_STATUS_FAILURE);
2540 if (EnableTxBurst == 1)
2541 FrameGap = IFS_SIFS;
2542 else
2543 FrameGap = IFS_BACKOFF; // Default frame gap mode
2545 // outgoing frame always wakeup PHY to prevent frame lost and
2546 // turn off PSM bit to improve performance
2547 if (pAdapter->PortCfg.Psm == PWR_SAVE)
2549 MlmeSetPsmBit(pAdapter, PWR_ACTIVE);
2551 AsicForceWakeup(pAdapter);
2553 // Sequence Number is identical for all fragments belonged to the same frame
2554 // Sequence is 0 - 4095
2555 pAdapter->Sequence = ((pAdapter->Sequence) + 1) & (MAX_SEQ_NUMBER);
2557 AckRate = pAdapter->PortCfg.ExpectedACKRate[pAdapter->PortCfg.TxRate];
2558 AckDuration = RTMPCalcDuration(pAdapter, AckRate, 14);
2560 pVirtualAddress = skb->data;
2561 NdisBufferLength = skb->len;
2563 if ((*((PUCHAR) pVirtualAddress) & 0x01) != 0) // Multicast or Broadcast
2565 INC_COUNTER(pAdapter->WlanCounters.MulticastTransmittedFrameCount);
2568 if (NdisBufferLength < 14)
2570 DBGPRINT(RT_DEBUG_ERROR,"RTMPHardTransmit --> Ndis Packet buffer error !!!\n");
2571 // Make sure to release Tx ring resource
2572 NdisReleaseSpinLock(&pAdapter->TxRingLock, IrqFlags);
2573 return (NDIS_STATUS_FAILURE);
2577 // Start making 802.11 frame header
2579 NdisZeroMemory(&Header_802_11, sizeof(HEADER_802_11)); // Initialize 802.11 header for each fragment
2580 if (INFRA_ON(pAdapter))
2582 // Address 1 - AP, Address 2 - this STA, Address 3 - DA
2583 NdisMoveMemory(&Header_802_11.Controlhead.Addr1, &pAdapter->PortCfg.Bssid, ETH_LENGTH_OF_ADDRESS);
2584 NdisMoveMemory(&Header_802_11.Addr3, (PUCHAR) pVirtualAddress, ETH_LENGTH_OF_ADDRESS);
2585 Header_802_11.Controlhead.Frame.ToDs = 1;
2587 else
2589 // Address 1 - DA, Address 2 - this STA, Address 3 - BSSID
2590 NdisMoveMemory(&Header_802_11.Controlhead.Addr1, (PUCHAR) pVirtualAddress, ETH_LENGTH_OF_ADDRESS);
2591 NdisMoveMemory(&Header_802_11.Addr3, &pAdapter->PortCfg.Bssid, ETH_LENGTH_OF_ADDRESS);
2593 NdisMoveMemory(&Header_802_11.Controlhead.Addr2, pAdapter->CurrentAddress, ETH_LENGTH_OF_ADDRESS);
2595 Header_802_11.Sequence = pAdapter->Sequence; // Sequence number
2596 Header_802_11.Controlhead.Frame.Type = BTYPE_DATA; // Frame type
2597 Header_802_11.Controlhead.Frame.PwrMgt = (pAdapter->PortCfg.Psm == PWR_SAVE);
2599 // Add 802.11x protocol check.
2600 // For non-WPA network, 802.1x message should not encrypt even
2601 // the privacy is on.
2602 if (RTMPEqualMemory(EAPOL, ((PUCHAR) pVirtualAddress) + 12, 2))
2604 EAPOLFrame = TRUE;
2605 if (pAdapter->PortCfg.MicErrCnt >= 2)
2606 pAdapter->PortCfg.MicErrCnt++;
2608 else
2609 EAPOLFrame = FALSE;
2611 // WPA 802.1x secured port control
2612 if (((pAdapter->PortCfg.AuthMode == Ndis802_11AuthModeWPA) ||
2613 (pAdapter->PortCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) &&
2614 ((pAdapter->PortCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) || (pAdapter->PortCfg.MicErrCnt >= 2)) &&
2615 (EAPOLFrame == FALSE))
2617 DBGPRINT(RT_DEBUG_TRACE,"RTMPHardEncrypt --> Drop packet before port secured !!!\n");
2618 // Make sure to release Tx ring resource
2619 NdisReleaseSpinLock(&pAdapter->TxRingLock, IrqFlags);
2620 return (NDIS_STATUS_FAILURE);
2623 MICFrag = FALSE; // Flag to indicate MIC shall spread into two MPDUs
2624 Encapped = FALSE;
2625 pEncap = NULL;
2627 pSrc = (PUCHAR) pVirtualAddress;
2628 Protocol = *(pSrc + 12) * 256 + *(pSrc + 13);
2629 if (Protocol > 1500) // CHeck for LLC encaped
2631 pEncap = SNAP_802_1H;
2632 Encapped = TRUE;
2633 if (RTMPEqualMemory(IPX, pSrc + 12, 2) ||
2634 RTMPEqualMemory(APPLE_TALK, pSrc + 12, 2))
2636 pEncap = SNAP_BRIDGE_TUNNEL;
2640 if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption1Enabled) &&
2641 (pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].KeyLen != 0))
2642 EncryptionOverhead = 8; // WEP: IV + ICV
2643 else if (pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled)
2644 EncryptionOverhead = 12; // TKIP: IV + EIV + ICV, MIC already added to TotalPacketLength
2645 else if (pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled)
2646 EncryptionOverhead = 16; // AES: IV + EIV + Hardware MIC
2647 else
2648 EncryptionOverhead = 0;
2651 // Make RTS frame if required
2653 if (RTMP_GET_PACKET_RTS(skb))
2655 PCONTROL_HEADER pControlHeader;
2656 ULONG NextFragSize;
2658 // RTS-protected frame should use LONG_RETRY (=4), other frames use SHORT_RETRY (=7)
2659 RetryMode = LONG_RETRY;
2661 pDest = (PUCHAR) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_data_addr;
2662 #ifndef BIG_ENDIAN
2663 pTxD = (PTXD_STRUC) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_addr;
2664 #else
2665 pDestTxD = (PTXD_STRUC) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_addr;
2666 TxD = *pDestTxD;
2667 pTxD = &TxD;
2668 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2669 #endif
2671 if ((pTxD->Owner == DESC_OWN_NIC) || (pTxD->CipherOwn == DESC_OWN_NIC))
2673 // Descriptor owned by NIC. No descriptor avaliable
2674 // This should not happen since caller guaranteed.
2675 // Make sure to release Tx ring resource
2676 NdisReleaseSpinLock(&pAdapter->TxRingLock, IrqFlags);
2677 return (NDIS_STATUS_RESOURCES);
2679 if (pTxD->Valid == TRUE)
2681 // This might happen when HardTransmit process faster than TxDone interrupt.
2682 // However, Since we did call free descriptor number check before Tx HardTransmit.
2683 // This case should not happened. We should return to higher caller and requeue this
2684 // acket until next Tx hardtransmit. Hopefully this situation is corrected then.
2685 // Ndis packet of last round did not cleared.
2686 // This should not happen since caller guaranteed.
2687 // Make sure to release Tx ring resource
2688 pTxD->Valid = FALSE;
2689 #ifdef BIG_ENDIAN
2690 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2691 *pDestTxD = TxD;
2692 #endif
2694 NdisReleaseSpinLock(&pAdapter->TxRingLock, IrqFlags);
2695 return (NDIS_STATUS_RESOURCES);
2698 pAdapter->TxRing[pAdapter->CurEncryptIndex].FrameType = BTYPE_CNTL;
2699 pControlHeader = (PCONTROL_HEADER) pDest;
2700 NdisZeroMemory(pControlHeader, sizeof(CONTROL_HEADER));
2701 pControlHeader->Frame.Type = BTYPE_CNTL;
2703 // Calculate duration = 2 SIFS + CTS + Data Frame size
2704 if (RTMP_GET_PACKET_FRAGMENTS(skb) > 1)
2706 // If fragment required, size is maximum fragment size
2707 NextFragSize = pAdapter->PortCfg.FragmentThreshold;
2709 else
2711 // Size should be frame with 802.11 header & CRC
2712 NextFragSize = skb->data_len + LENGTH_802_11 + LENGTH_CRC - LENGTH_802_3;
2714 if (Encapped)
2715 NextFragSize += LENGTH_802_1_H;
2717 pControlHeader->Duration = 2 * (pAdapter->PortCfg.Dsifs)
2718 + RTMPCalcDuration(pAdapter, pAdapter->PortCfg.TxRate, NextFragSize + EncryptionOverhead)
2719 + AckDuration;
2721 // Write Tx descriptor
2722 // Don't kick tx start until all frames are prepared
2723 // RTS has to set more fragment bit for fragment burst
2724 // RTS did not encrypt
2725 if (pAdapter->PortCfg.BGProtectionInUsed == 1)
2727 DBGPRINT(RT_DEBUG_TRACE,"Making CTS-to-self Frame\n");
2728 pControlHeader->Frame.Subtype = SUBTYPE_CTS;
2729 NdisMoveMemory(&pControlHeader->Addr1, pAdapter->CurrentAddress, ETH_LENGTH_OF_ADDRESS);
2731 // Write Tx descriptor
2732 // Don't kick tx start until all frames are prepared
2733 // CTS has to set more fragment bit for fragment burst
2734 // CTS did not encrypt
2735 // CTS-to-self will never receive ACK
2736 #ifdef BIG_ENDIAN
2737 RTMPFrameEndianChange(pAdapter, (PUCHAR)pControlHeader, DIR_WRITE, FALSE);
2738 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2739 *pDestTxD = TxD;
2740 pTxD = pDestTxD;
2741 #endif
2743 #ifdef WIFI_TEST
2744 RTMPWriteTxDescriptor(pTxD, TRUE, CIPHER_NONE, FALSE, FALSE, FALSE, SHORT_RETRY,
2745 FrameGap, pAdapter->PortCfg.RtsRate, 4, 10, Rt802_11PreambleShort,
2746 AccessCategory);
2747 #else
2748 RTMPWriteTxDescriptor(pTxD, TRUE, CIPHER_NONE, FALSE, FALSE, FALSE, SHORT_RETRY,
2749 FrameGap, pAdapter->PortCfg.RtsRate, 4, 10, pAdapter->PortCfg.TxPreambleInUsed,
2750 AccessCategory);
2751 #endif
2753 else
2755 DBGPRINT(RT_DEBUG_TRACE,"Making RTS Frame\n");
2756 pControlHeader->Frame.Subtype = SUBTYPE_RTS;
2757 if (INFRA_ON(pAdapter))
2758 NdisMoveMemory(&pControlHeader->Addr1, &pAdapter->PortCfg.Bssid, ETH_LENGTH_OF_ADDRESS);
2759 else
2760 NdisMoveMemory(&pControlHeader->Addr1, (PUCHAR) pVirtualAddress, ETH_LENGTH_OF_ADDRESS);
2761 NdisMoveMemory(&pControlHeader->Addr2, pAdapter->CurrentAddress, ETH_LENGTH_OF_ADDRESS);
2763 // Write Tx descriptor
2764 // Don't kick tx start until all frames are prepared
2765 // RTS has to set more fragment bit for fragment burst
2766 // RTS did not encrypt
2767 pTxD->RTS = 1;
2768 #ifdef BIG_ENDIAN
2769 RTMPFrameEndianChange(pAdapter, (PUCHAR)pControlHeader, DIR_WRITE, FALSE);
2770 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2771 *pDestTxD = TxD;
2772 pTxD = pDestTxD;
2773 #endif
2774 RTMPWriteTxDescriptor(pTxD, TRUE, CIPHER_NONE, TRUE, TRUE, FALSE, SHORT_RETRY,
2775 FrameGap, pAdapter->PortCfg.RtsRate, 4, sizeof(CONTROL_HEADER),
2776 pAdapter->PortCfg.TxPreambleInUsed, AccessCategory);
2781 FrameGap = IFS_SIFS; // Init frame gap for coming data after RTS
2782 NumberRequired--;
2784 // Increase & maintain Tx Ring Index
2785 pAdapter->CurEncryptIndex++;
2786 if (pAdapter->CurEncryptIndex >= TX_RING_SIZE)
2788 pAdapter->CurEncryptIndex = 0;
2790 pAdapter->RalinkCounters.EncryptCount++;
2793 // Find the WPA key, either Group or Pairwise Key
2794 if (pAdapter->PortCfg.AuthMode >= Ndis802_11AuthModeWPA)
2796 INT idx;
2798 pWpaKey = (PWPA_KEY) NULL;
2799 // First lookup the DA, if it's a group address, use GROUP key
2800 if (Header_802_11.Controlhead.Addr1.Octet[0] & 0x01)
2802 if (pAdapter->PortCfg.GroupKey[pAdapter->PortCfg.DefaultKeyId].KeyLen != 0)
2804 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.GroupKey[pAdapter->PortCfg.DefaultKeyId];
2805 pWpaKey->Type = GROUP_KEY;
2806 DBGPRINT(RT_DEBUG_INFO, "Tx Use Group Key\n");
2809 // Try to find the Pairwise Key
2810 else
2812 for (idx = 0; idx < PAIRWISE_KEY_NO; idx++)
2814 if ((NdisEqualMemory(&Header_802_11.Controlhead.Addr1, pAdapter->PortCfg.PairwiseKey[idx].BssId, 6)) &&
2815 (pAdapter->PortCfg.PairwiseKey[idx].KeyLen != 0))
2817 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.PairwiseKey[idx];
2818 pWpaKey->Type = PAIRWISE_KEY;
2819 DBGPRINT(RT_DEBUG_INFO, "Tx Use Pairwise Key\n");
2820 break;
2823 // Use default Group Key if there is no Pairwise key present
2824 if ((pAdapter->PortCfg.GroupKey[pAdapter->PortCfg.DefaultKeyId].KeyLen != 0) && (pWpaKey == NULL))
2826 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.GroupKey[pAdapter->PortCfg.DefaultKeyId];
2827 pWpaKey->Type = GROUP_KEY;
2828 DBGPRINT(RT_DEBUG_INFO, "Tx Use Group Key\n");
2833 // For the purpose to calculate duration for the second last fragment
2834 RemainSize = skb->data_len - LENGTH_802_3 + LENGTH_CRC;
2836 StartOfFrame = TRUE;
2837 // Start Copy Ndis Packet into Ring buffer.
2838 // For frame required more than one ring buffer (fragment), all ring buffers
2839 // have to be filled before kicking start tx bit.
2842 // Get the Tx Ring descriptor & Dma Buffer address
2843 #ifndef BIG_ENDIAN
2844 pDest = (PUCHAR) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_data_addr;
2845 pTxD = (PTXD_STRUC) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_addr;
2846 #else
2847 pDest = (PUCHAR) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_data_addr;
2848 pOriginDest = pDest;
2849 pDestTxD = (PTXD_STRUC) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_addr;
2850 TxD = *pDestTxD;
2851 pTxD = &TxD;
2852 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2853 #endif
2855 if ((pTxD->Owner == DESC_OWN_NIC) || (pTxD->CipherOwn == DESC_OWN_NIC))
2857 // Descriptor owned by NIC. No descriptor avaliable
2858 // This should not happen since caller guaranteed.
2859 // Make sure to release Tx ring resource
2860 pAdapter->RalinkCounters.TxRingErrCount++;
2861 NdisReleaseSpinLock(&pAdapter->TxRingLock, IrqFlags);
2862 return (NDIS_STATUS_RESOURCES);
2864 if (pTxD->Valid == TRUE)
2866 // Ndis packet of last round did not cleared.
2867 // This should not happen since caller guaranteed.
2868 // Make sure to release Tx ring resource
2869 pTxD->Valid = FALSE;
2871 #ifdef BIG_ENDIAN
2872 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2873 *pDestTxD = TxD;
2874 #endif
2876 pAdapter->RalinkCounters.TxRingErrCount++;
2877 NdisReleaseSpinLock(&pAdapter->TxRingLock, IrqFlags);
2878 return (NDIS_STATUS_RESOURCES);
2880 pAdapter->TxRing[pAdapter->CurEncryptIndex].FrameType = BTYPE_DATA;
2882 // Make fragment number & more fragment bit of 802.11 header
2883 if (StartOfFrame == TRUE)
2884 Header_802_11.Frag = 0; // Start of fragment burst / Single Frame
2885 else
2886 Header_802_11.Frag++; // Rest of fragmented frames.
2888 // Maximum allowable payload with one ring buffer, bound by fragment size
2889 FreeFragSize = pAdapter->PortCfg.FragmentThreshold - LENGTH_CRC;
2892 // calculate "duration" field of this fragment
2894 if (NumberRequired > 1)
2896 ULONG NextFragSize;
2897 Header_802_11.Controlhead.Frame.MoreFrag = 1;
2899 if (NumberRequired == 2)
2900 NextFragSize = RemainSize - pAdapter->PortCfg.FragmentThreshold + LENGTH_802_11 + LENGTH_802_11 + LENGTH_CRC;
2901 else
2902 NextFragSize = pAdapter->PortCfg.FragmentThreshold;
2904 Header_802_11.Controlhead.Duration = 3 * pAdapter->PortCfg.Dsifs
2905 + 2 * AckDuration
2906 + RTMPCalcDuration(pAdapter, pAdapter->PortCfg.TxRate, NextFragSize + EncryptionOverhead);
2908 else // this is the last or only fragment
2910 Header_802_11.Controlhead.Frame.MoreFrag = 0;
2912 if (Header_802_11.Controlhead.Addr1.Octet[0] & 0x01) // multicast/broadcast
2913 Header_802_11.Controlhead.Duration = 0;
2914 else
2915 Header_802_11.Controlhead.Duration = pAdapter->PortCfg.Dsifs + AckDuration;
2918 // Check for WEP enable bit and prepare for software WEP
2919 if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption1Enabled) && (EAPOLFrame == FALSE) &&
2920 (pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].KeyLen != 0))
2921 Header_802_11.Controlhead.Frame.Wep = 1;
2922 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) && (pWpaKey != NULL))
2923 Header_802_11.Controlhead.Frame.Wep = 1;
2924 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled) && (pWpaKey != NULL))
2925 Header_802_11.Controlhead.Frame.Wep = 1;
2928 // Copy 802.11 header to Tx ring buffer
2930 NdisMoveMemory(pDest, &Header_802_11, sizeof(Header_802_11));
2931 pDest += sizeof(Header_802_11);
2932 FreeFragSize -= sizeof(Header_802_11);
2934 DBGPRINT(RT_DEBUG_INFO,"pWpaKey = %s\n", pWpaKey == NULL ? "NULL" : "not NULL");
2936 if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption1Enabled) && (EAPOLFrame == FALSE) &&
2937 (pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].KeyLen != 0))
2939 DBGPRINT(RT_DEBUG_INFO,"Ndis802_11Encryption1Enabled::DefaultKeyId = %d\n", pAdapter->PortCfg.DefaultKeyId);
2941 // Prepare IV, IV offset, Key for Hardware encryption
2942 RTMPInitWepEngine(
2943 pAdapter,
2944 pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].Key,
2945 pAdapter->PortCfg.DefaultKeyId,
2946 pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].KeyLen,
2947 (PUCHAR) &pTxD->Iv);
2949 if (pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].KeyLen == 5)
2950 CipherAlg = CIPHER_WEP64;
2951 else
2952 CipherAlg = CIPHER_WEP128;
2954 // Set Iv offset in TxD
2955 pTxD->IvOffset = LENGTH_802_11;
2956 // Copy Encrypt Key to TxD
2957 NdisMoveMemory(
2958 pTxD->Key,
2959 pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].Key,
2960 pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].KeyLen);
2962 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) && (pWpaKey != NULL))
2964 INT i = 0;
2966 DBGPRINT(RT_DEBUG_INFO,"Ndis802_11Encryption2Enabled::DefaultKeyId = %d\n", pAdapter->PortCfg.DefaultKeyId);
2968 // Prepare 8 bytes TKIP encapsulation for MPDU
2970 TKIP_IV tkipIv;
2972 tkipIv.IV16.field.rc0 = *(pWpaKey->TxTsc + 1);
2973 tkipIv.IV16.field.rc1 = (tkipIv.IV16.field.rc0 | 0x20) & 0x7f;
2974 tkipIv.IV16.field.rc2 = *pWpaKey->TxTsc;
2975 tkipIv.IV16.field.ExtIV = 1; // 0: non-extended IV, 1: an extended IV
2976 tkipIv.IV16.field.KeyID = pAdapter->PortCfg.DefaultKeyId;
2977 //tkipIv.IV32 = *(PULONG)(pWpaKey->TxTsc + 2);
2978 NdisMoveMemory(&tkipIv.IV32, &pWpaKey->TxTsc[2], 4);
2980 #ifdef BIG_ENDIAN
2981 pTxD->Iv = SWAP32(tkipIv.IV16.word);
2982 #else
2983 pTxD->Iv = tkipIv.IV16.word;
2984 #endif
2986 *((PUCHAR) &pTxD->Eiv) = *((PUCHAR) &tkipIv.IV32 + 3);
2987 *((PUCHAR) &pTxD->Eiv + 1) = *((PUCHAR) &tkipIv.IV32 + 2);
2988 *((PUCHAR) &pTxD->Eiv + 2) = *((PUCHAR) &tkipIv.IV32 + 1);
2989 *((PUCHAR) &pTxD->Eiv + 3) = *((PUCHAR) &tkipIv.IV32);
2992 // Increase TxTsc value for next transmission
2993 while (++pWpaKey->TxTsc[i] == 0x0)
2995 i++;
2996 if (i == 6)
2997 break;
3000 // Set IV offset
3001 pTxD->IvOffset = LENGTH_802_11;
3003 // Copy TKey
3004 NdisMoveMemory(pTxD->Key, pWpaKey->Key, 16);
3006 // Set Cipher suite
3007 CipherAlg = CIPHER_TKIP;
3009 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled) && (pWpaKey != NULL))
3011 INT i;
3012 PUCHAR pTmp;
3014 DBGPRINT(RT_DEBUG_INFO,"Ndis802_11Encryption3Enabled::DefaultKeyId = %d\n", pAdapter->PortCfg.DefaultKeyId);
3016 i = 0;
3017 pTmp = (PUCHAR) &Iv16;
3018 *pTmp = pWpaKey->TxTsc[0];
3019 *(pTmp + 1) = pWpaKey->TxTsc[1];
3020 *(pTmp + 2) = 0;
3021 *(pTmp + 3) = (pAdapter->PortCfg.DefaultKeyId << 6) | 0x20;
3023 //Iv32 = *(PULONG)(&pWpaKey->TxTsc[2]);
3024 NdisMoveMemory(&Iv32, &pWpaKey->TxTsc[2], 4);
3026 // Increase TxTsc value for next transmission
3027 while (++pWpaKey->TxTsc[i] == 0x0)
3029 i++;
3030 if (i == 6)
3031 break;
3033 if (i == 6)
3035 // TODO: TSC has done one full cycle, do re-keying stuff follow specs
3036 // Should send a special event microsoft defined to request re-key
3039 NdisMoveMemory(&pTxD->Iv, &Iv16, 4); // Copy IV
3040 NdisMoveMemory(&pTxD->Eiv, &Iv32, 4); // Copy EIV
3041 pTxD->IvOffset = LENGTH_802_11; // Set IV offset
3042 NdisMoveMemory(pTxD->Key, pWpaKey->Key, 16); // Copy TKey
3043 CipherAlg = CIPHER_AES; // Set Cipher suite
3045 else
3046 CipherAlg = CIPHER_NONE;
3049 // Only the first fragment required LLC-SNAP header !!!
3051 if ((StartOfFrame == TRUE) && (Encapped == TRUE))
3053 // For WEP & no encryption required frame, just copy LLC header into buffer,
3054 // Hardware will do the encryption job.
3055 // For TKIP, we have to calculate MIC and store it first
3056 if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) && (pWpaKey != NULL))
3058 // Calculate MSDU MIC Value
3059 RTMPCalculateMICValue(pAdapter, skb, pEncap, 6, pWpaKey);
3062 // Copy LLC header
3063 NdisMoveMemory(pDest, pEncap, 6);
3064 pDest += 6;
3066 // Copy protocol type
3067 pSrc = (PUCHAR) pVirtualAddress;
3068 NdisMoveMemory(pDest, pSrc + 12, 2);
3069 pDest += 2;
3071 // Exclude 802.3 header size, we will recalculate the size at
3072 // the end of fragment preparation.
3073 NdisBufferLength -= LENGTH_802_3;
3074 pSrc += LENGTH_802_3;
3075 FreeFragSize -= LENGTH_802_1_H;
3077 else if ((StartOfFrame == TRUE) && (Encapped == FALSE))
3079 if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) && (pWpaKey != NULL))
3081 // Calculate MSDU MIC Value
3082 RTMPCalculateMICValue(pAdapter, skb, pEncap, 0, pWpaKey);
3085 pSrc = (PUCHAR) pVirtualAddress + LENGTH_802_3;
3086 NdisBufferLength -= LENGTH_802_3;
3089 // Start copying payload
3090 BytesCopied = 0;
3093 if (NdisBufferLength >= FreeFragSize)
3095 // Copy only the free fragment size, and save the pointer
3096 // of current buffer descriptor for next fragment buffer.
3097 NdisMoveMemory(pDest, pSrc, FreeFragSize);
3098 BytesCopied += FreeFragSize;
3099 pSrc += FreeFragSize;
3100 pDest += FreeFragSize;
3101 NdisBufferLength -= FreeFragSize;
3102 break;
3104 else
3106 // Copy the rest of this buffer descriptor pointed data
3107 // into ring buffer.
3108 NdisMoveMemory(pDest, pSrc, NdisBufferLength);
3109 BytesCopied += NdisBufferLength;
3110 pDest += NdisBufferLength;
3111 FreeFragSize -= NdisBufferLength;
3114 // No more buffer descriptor
3115 // Add MIC value if needed
3116 if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
3117 (MICFrag == FALSE) &&
3118 (pWpaKey != NULL))
3120 INT i;
3122 NdisBufferLength = 8; // Set length to MIC length
3123 DBGPRINT(RT_DEBUG_INFO, "Calculated TX MIC value =");
3124 for (i = 0; i < 8; i++)
3126 DBGPRINT(RT_DEBUG_INFO, "%02x:", pAdapter->PrivateInfo.Tx.MIC[i]);
3128 DBGPRINT(RT_DEBUG_INFO, "\n");
3130 if (FreeFragSize >= NdisBufferLength)
3132 NdisMoveMemory(pDest, pAdapter->PrivateInfo.Tx.MIC, NdisBufferLength);
3133 BytesCopied += NdisBufferLength;
3134 pDest += NdisBufferLength;
3135 FreeFragSize -= NdisBufferLength;
3136 NdisBufferLength = 0;
3137 RemainSize += 8; // Need to add MIC as payload
3139 else
3141 NdisMoveMemory(pDest, pAdapter->PrivateInfo.Tx.MIC, FreeFragSize);
3142 BytesCopied += FreeFragSize;
3143 pSrc = pAdapter->PrivateInfo.Tx.MIC + FreeFragSize;
3144 pDest += FreeFragSize;
3145 NdisBufferLength -= FreeFragSize;
3146 MICFrag = TRUE;
3147 RemainSize += (8 - FreeFragSize); // Need to add MIC as payload
3150 } while (FALSE); // End of copying payload
3152 // Real packet size, No 802.1H header for fragments except the first one.
3153 if ((StartOfFrame == TRUE) && (Encapped == TRUE))
3155 TxSize = BytesCopied + LENGTH_802_11 + LENGTH_802_1_H;
3157 else
3159 TxSize = BytesCopied + LENGTH_802_11;
3162 RemainSize = RemainSize - BytesCopied;
3164 if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption1Enabled) && (Header_802_11.Controlhead.Frame.Wep == 1))
3166 // IV + ICV which ASIC added after encryption done
3167 TxSize += 8;
3169 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) && (pWpaKey != NULL))
3171 // IV + EIV + ICV which ASIC added after encryption done
3172 TxSize += 12;
3174 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled) && (pWpaKey != NULL))
3176 // IV + EIV + HW MIC
3177 TxSize += 16;
3180 // Prepare Tx descriptors before kicking tx.
3181 // The BBP register index in Tx descriptor has to be configured too.
3182 #ifdef BIG_ENDIAN
3183 RTMPFrameEndianChange(pAdapter, pOriginDest, DIR_WRITE, FALSE);
3184 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
3185 *pDestTxD = TxD;
3186 pTxD = pDestTxD;
3187 #endif
3188 if (Header_802_11.Controlhead.Addr1.Octet[0] & 0x01)
3190 // Multicast, retry bit is off
3191 RTMPWriteTxDescriptor(pTxD, TRUE, CipherAlg, FALSE, FALSE, FALSE, RetryMode, FrameGap,
3192 pAdapter->PortCfg.TxRate, 4, TxSize, pAdapter->PortCfg.TxPreambleInUsed, AccessCategory);
3194 else
3196 RTMPWriteTxDescriptor(pTxD, TRUE, CipherAlg, TRUE, FALSE, FALSE, RetryMode, FrameGap,
3197 pAdapter->PortCfg.TxRate, 4, TxSize, pAdapter->PortCfg.TxPreambleInUsed, AccessCategory);
3200 // Set frame gap for the rest of fragment burst.
3201 // It won't matter if there is only one fragment (single fragment frame).
3202 StartOfFrame = FALSE;
3203 FrameGap = IFS_SIFS;
3204 NumberRequired--;
3206 // Increase & maintain Tx Ring Index
3207 pAdapter->CurEncryptIndex++;
3208 if (pAdapter->CurEncryptIndex >= TX_RING_SIZE)
3210 pAdapter->CurEncryptIndex = 0;
3213 pAdapter->RalinkCounters.EncryptCount++;
3215 } while (NumberRequired > 0);
3218 // Kick Encrypt Control Register at the end of all ring buffer preparation
3219 RTMP_IO_WRITE32(pAdapter, SECCSR1, 0x1);
3221 // Acknowledge protocol send complete of pending packet.
3222 RTMPFreeSkbBuffer(skb);
3224 // Make sure to release Tx ring resource
3225 NdisReleaseSpinLock(&pAdapter->TxRingLock, IrqFlags);
3227 return (NDIS_STATUS_SUCCESS);
3231 ========================================================================
3233 Routine Description:
3234 Calculates the duration which is required to transmit out frames
3235 with given size and specified rate.
3237 Arguments:
3238 pAdapter Pointer to our adapter
3239 Rate Transmit rate
3240 Size Frame size in units of byte
3242 Return Value:
3243 Duration number in units of usec
3245 Note:
3247 ========================================================================
3249 USHORT RTMPCalcDuration(
3250 IN PRTMP_ADAPTER pAdapter,
3251 IN UCHAR Rate,
3252 IN ULONG Size)
3254 ULONG Duration = 0;
3256 if (Rate < RATE_FIRST_OFDM_RATE) // CCK
3258 if ((Rate > RATE_1) && (pAdapter->PortCfg.TxPreambleInUsed == Rt802_11PreambleShort))
3259 Duration = 96; // 72+24 preamble+plcp
3260 else
3261 Duration = 192; // 144+48 preamble+plcp
3263 Duration += (USHORT)((Size << 4) / RateIdTo500Kbps[Rate]);
3264 if ((Size << 4) % RateIdTo500Kbps[Rate])
3265 Duration ++;
3267 else // OFDM rates
3269 Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension
3270 Duration += 4 * (USHORT)((11 + Size * 4) / RateIdTo500Kbps[Rate]);
3271 if ((11 + Size * 4) % RateIdTo500Kbps[Rate])
3272 Duration += 4;
3275 return (USHORT)Duration;
3280 ========================================================================
3282 Routine Description:
3283 Calculates the duration which is required to transmit out frames
3284 with given size and specified rate.
3286 Arguments:
3287 pTxD Pointer to transmit descriptor
3288 Ack Setting for Ack requirement bit
3289 Fragment Setting for Fragment bit
3290 RetryMode Setting for retry mode
3291 Ifs Setting for IFS gap
3292 Rate Setting for transmit rate
3293 Service Setting for service
3294 Length Frame length
3295 TxPreamble Short or Long preamble when using CCK rates
3296 AccessCategory - 0-3, according to 802.11e/d4.4 June/2003
3298 Return Value:
3299 None
3301 ========================================================================
3303 VOID RTMPWriteTxDescriptor(
3304 IN PTXD_STRUC pSourceTxD,
3305 IN BOOLEAN DoEncrypt,
3306 IN UCHAR CipherAlg,
3307 IN BOOLEAN Ack,
3308 IN BOOLEAN Fragment,
3309 IN BOOLEAN InsTimestamp,
3310 IN UCHAR RetryMode,
3311 IN UCHAR Ifs,
3312 IN UINT Rate,
3313 IN UCHAR Service,
3314 IN ULONG Length,
3315 IN USHORT TxPreamble,
3316 IN UCHAR AccessCategory)
3318 UINT Residual;
3319 PTXD_STRUC pTxD;
3320 #ifndef BIG_ENDIAN
3321 pTxD = pSourceTxD;
3322 #else
3323 TXD_STRUC TxD;
3325 TxD = *pSourceTxD;
3326 pTxD = &TxD;
3327 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
3328 #endif
3330 pTxD->MoreFrag = Fragment;
3331 pTxD->ACK = Ack;
3332 pTxD->Timestamp = InsTimestamp;
3333 pTxD->RetryMd = RetryMode;
3334 pTxD->IFS = Ifs;
3335 pTxD->DataByteCnt = Length;
3336 pTxD->TxRate = Rate;
3337 switch (AccessCategory) // 802.11e/d4.4 June/2003
3339 case 3: // TC3, <AIFSN, CwMin, CwMax> = <1, aCwMin/4, aCwMin/2>
3340 pTxD->CWmin = CW_MIN_IN_BITS - 2;
3341 pTxD->CWmax = CW_MIN_IN_BITS - 1;
3342 pTxD->Aifs = 1;
3343 break;
3344 case 2: // TC2, <AIFSN, CwMin, CwMax> = <1, aCwMin/2, aCwMin>
3345 pTxD->CWmin = CW_MIN_IN_BITS - 1;
3346 pTxD->CWmax = CW_MIN_IN_BITS;
3347 pTxD->Aifs = 1;
3348 break;
3349 case 1: // TC1, <AIFSN, CwMin, CwMax> = <1, aCwMin, aCwMax>
3350 pTxD->CWmin = CW_MIN_IN_BITS;
3351 pTxD->CWmax = CW_MAX_IN_BITS;
3352 pTxD->Aifs = 1;
3353 break;
3354 case 0: // TC0, <AIFSN, CwMin, CwMax> = <2, aCwMin, aCwMax>
3355 default:
3356 pTxD->CWmin = CW_MIN_IN_BITS;
3357 pTxD->CWmax = CW_MAX_IN_BITS;
3358 pTxD->Aifs = 2;
3359 break;
3362 if (Rate < RATE_FIRST_OFDM_RATE)
3363 pTxD->Ofdm = 0;
3364 else
3365 pTxD->Ofdm = 1;
3367 // fill up PLCP SIGNAL field
3368 pTxD->PlcpSignal = PlcpSignal[Rate];
3369 if (((Rate == RATE_2) || (Rate == RATE_5_5) || (Rate == RATE_11)) && (TxPreamble == Rt802_11PreambleShort)) // no short preamble for RATE_1
3371 pTxD->PlcpSignal |= 0x0008;
3374 // fill up PLCP SERVICE field, not used for OFDM rates
3375 pTxD->PlcpService = Service;
3377 // file up PLCP LENGTH_LOW and LENGTH_HIGH fields
3378 Length += 4;
3379 if (Rate < RATE_FIRST_OFDM_RATE) // 11b - RATE_1, RATE_2, RATE_5_5, RATE_11
3381 if ((Rate == RATE_1) || ( Rate == RATE_2))
3383 Length = Length * 8 / (Rate + 1);
3385 else
3387 Residual = ((Length * 16) % (11 * (1 + Rate - RATE_5_5)));
3388 Length = Length * 16 / (11 * (1 + Rate - RATE_5_5));
3389 if (Residual != 0)
3391 Length++;
3393 if ((Residual <= (3 * (1 + Rate - RATE_5_5))) && (Residual != 0))
3395 if (Rate == RATE_11) // Only 11Mbps require length extension bit
3396 pTxD->PlcpService |= 0x80; // 11b's PLCP Length extension bit
3400 pTxD->PlcpLengthHigh = Length / 256;
3401 pTxD->PlcpLengthLow = Length % 256;
3403 else // OFDM - RATE_6, RATE_9, RATE_12, RATE_18, RATE_24, RATE_36, RATE_48, RATE_54
3405 pTxD->PlcpLengthHigh = Length / 64; // high 6-bit of total byte count
3406 pTxD->PlcpLengthLow = Length % 64; // low 6-bit of total byte count
3409 if (DoEncrypt == TRUE) // Do encryption only
3411 pTxD->Owner = DESC_OWN_HOST;
3412 pTxD->Valid = FALSE;
3413 pTxD->CipherAlg = CipherAlg;
3414 pTxD->CipherOwn = DESC_OWN_NIC;
3416 else // Hard transmit
3418 pTxD->Valid = TRUE;
3419 pTxD->CipherAlg = CIPHER_NONE;
3420 pTxD->CipherOwn = DESC_OWN_HOST;
3421 pTxD->Owner = DESC_OWN_NIC;
3423 #ifdef BIG_ENDIAN
3424 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
3425 //*pSourceTxD = *pTxD;
3426 WriteBackToDescriptor((PUCHAR)pSourceTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
3427 #endif
3431 ========================================================================
3433 Routine Description:
3434 Search tuple cache for receive duplicate frame from unicast frames.
3436 Arguments:
3437 pAdapter Pointer to our adapter
3438 pHeader 802.11 header of receiving frame
3440 Return Value:
3441 TRUE found matched tuple cache
3442 FALSE no matched found
3444 Note:
3446 ========================================================================
3448 BOOLEAN RTMPSearchTupleCache(
3449 IN PRTMP_ADAPTER pAdapter,
3450 IN PHEADER_802_11 pHeader)
3452 INT Index;
3454 for (Index = 0; Index < MAX_CLIENT; Index++)
3456 if (pAdapter->TupleCache[Index].Valid == FALSE)
3457 continue;
3459 if (RTMPEqualMemory(&pAdapter->TupleCache[Index].MAC, &pHeader->Controlhead.Addr2, 6) &&
3460 (pAdapter->TupleCache[Index].Sequence == pHeader->Sequence) &&
3461 (pAdapter->TupleCache[Index].Frag == pHeader->Frag))
3463 // DBGPRINT(RT_DEBUG_TRACE,("DUPCHECK - duplicate frame hit entry %d\n", Index));
3464 return (TRUE);
3467 return (FALSE);
3471 ========================================================================
3473 Routine Description:
3474 Update tuple cache for new received unicast frames.
3476 Arguments:
3477 pAdapter Pointer to our adapter
3478 pHeader 802.11 header of receiving frame
3480 Return Value:
3481 None
3483 Note:
3485 ========================================================================
3487 VOID RTMPUpdateTupleCache(
3488 IN PRTMP_ADAPTER pAdapter,
3489 IN PHEADER_802_11 pHeader)
3491 UCHAR Index;
3493 for (Index = 0; Index < MAX_CLIENT; Index++)
3495 if (pAdapter->TupleCache[Index].Valid == FALSE)
3497 // Add new entry
3498 NdisMoveMemory(&pAdapter->TupleCache[Index].MAC, &pHeader->Controlhead.Addr2, 6);
3499 pAdapter->TupleCache[Index].Sequence = pHeader->Sequence;
3500 pAdapter->TupleCache[Index].Frag = pHeader->Frag;
3501 pAdapter->TupleCache[Index].Valid = TRUE;
3502 pAdapter->TupleCacheLastUpdateIndex = Index;
3503 DBGPRINT(RT_DEBUG_INFO,"DUPCHECK - Add Entry %d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n",
3504 Index, pAdapter->TupleCache[Index].MAC.Octet[0], pAdapter->TupleCache[Index].MAC.Octet[1],
3505 pAdapter->TupleCache[Index].MAC.Octet[2], pAdapter->TupleCache[Index].MAC.Octet[3],
3506 pAdapter->TupleCache[Index].MAC.Octet[4], pAdapter->TupleCache[Index].MAC.Octet[5]);
3507 return;
3509 else if (RTMPEqualMemory(&pAdapter->TupleCache[Index].MAC, &pHeader->Controlhead.Addr2, 6))
3511 // Update old entry
3512 pAdapter->TupleCache[Index].Sequence = pHeader->Sequence;
3513 pAdapter->TupleCache[Index].Frag = pHeader->Frag;
3514 return;
3518 // tuple cache full, replace the first inserted one (even though it may not be
3519 // least referenced one)
3520 if (Index == MAX_CLIENT)
3522 pAdapter->TupleCacheLastUpdateIndex ++;
3523 if (pAdapter->TupleCacheLastUpdateIndex >= MAX_CLIENT)
3524 pAdapter->TupleCacheLastUpdateIndex = 0;
3525 Index = pAdapter->TupleCacheLastUpdateIndex;
3527 // replace with new entry
3528 NdisMoveMemory(&pAdapter->TupleCache[Index].MAC, &pHeader->Controlhead.Addr2, 6);
3529 pAdapter->TupleCache[Index].Sequence = pHeader->Sequence;
3530 pAdapter->TupleCache[Index].Frag = pHeader->Frag;
3531 pAdapter->TupleCache[Index].Valid = TRUE;
3532 DBGPRINT(RT_DEBUG_INFO,"DUPCHECK - replace Entry %d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n",
3533 Index, pAdapter->TupleCache[Index].MAC.Octet[0], pAdapter->TupleCache[Index].MAC.Octet[1],
3534 pAdapter->TupleCache[Index].MAC.Octet[2], pAdapter->TupleCache[Index].MAC.Octet[3],
3535 pAdapter->TupleCache[Index].MAC.Octet[4], pAdapter->TupleCache[Index].MAC.Octet[5]);
3540 ========================================================================
3542 Routine Description:
3543 Suspend MSDU transmission
3545 Arguments:
3546 pAdapter Pointer to our adapter
3548 Return Value:
3549 None
3551 Note:
3553 ========================================================================
3555 VOID RTMPSuspendMsduTransmission(
3556 IN PRTMP_ADAPTER pAdapter)
3558 DBGPRINT(RT_DEBUG_TRACE,"SCANNING, suspend MSDU transmission ...\n");
3559 RTMP_SET_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
3563 ========================================================================
3565 Routine Description:
3566 Resume MSDU transmission
3568 Arguments:
3569 pAdapter Pointer to our adapter
3571 Return Value:
3572 None
3574 Note:
3576 ========================================================================
3578 VOID RTMPResumeMsduTransmission(
3579 IN PRTMP_ADAPTER pAdapter)
3581 DBGPRINT(RT_DEBUG_INFO,"SCAN done, resume MSDU transmission ...\n");
3582 RTMP_CLEAR_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
3584 // Dequeue Tx queue if Reset is not in progress
3585 if ((!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
3586 (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF)))
3588 //RTMPDeQueuePacket(pAdapter, &pAdapter->TxSwQueue0);
3589 // Call dequeue without selected queue, let the subroutine select the right priority
3590 // Tx software queue
3591 RTMPDeQueuePacket(pAdapter);
3596 ========================================================================
3598 Routine Description:
3599 Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
3601 Arguments:
3602 pRxD Pointer to the Rx descriptor
3604 Return Value:
3605 NDIS_STATUS_SUCCESS No err
3606 NDIS_STATUS_FAILURE Error
3608 Note:
3610 ========================================================================
3612 inline NDIS_STATUS RTMPCheckRxDescriptor(
3613 IN PRXD_STRUC pRxD)
3615 // Phy errors
3616 if (pRxD->PhyErr)
3617 return(NDIS_STATUS_FAILURE);
3619 // CRC errors
3620 if (pRxD->Crc)
3621 return(NDIS_STATUS_FAILURE);
3623 // Paul 04-03 for OFDM Rx length issue
3624 if (pRxD->DataByteCnt > 1600)
3625 return(NDIS_STATUS_FAILURE);
3627 return(NDIS_STATUS_SUCCESS);
3631 ========================================================================
3633 Routine Description:
3634 Apply packet filter policy, return NDIS_STATUS_FAILURE if this frame
3635 should be dropped.
3637 Arguments:
3638 pAdapter Pointer to our adapter
3639 pRxD Pointer to the Rx descriptor
3640 pHeader Pointer to the 802.11 frame header
3642 Return Value:
3643 NDIS_STATUS_SUCCESS Accept frame
3644 NDIS_STATUS_FAILURE Drop Frame
3646 Note:
3647 Maganement frame should bypass this filtering rule.
3649 ========================================================================
3651 NDIS_STATUS RTMPApplyPacketFilter(
3652 IN PRTMP_ADAPTER pAdapter,
3653 IN PRXD_STRUC pRxD,
3654 IN PHEADER_802_11 pHeader)
3656 UCHAR i;
3658 // 0. Management frame should bypass all these filtering rules.
3659 if (pHeader->Controlhead.Frame.Type == BTYPE_MGMT)
3661 return(NDIS_STATUS_SUCCESS);
3664 // 0.1 Drop all Rx frames if MIC countermeasures kicks in
3665 if (pAdapter->PortCfg.MicErrCnt >= 2)
3667 return(NDIS_STATUS_FAILURE);
3670 // 1. Drop unicast to me packet if NDIS_PACKET_TYPE_DIRECTED is FALSE
3671 if (pRxD->U2M)
3673 if (pAdapter->bAcceptDirect == FALSE)
3675 return(NDIS_STATUS_FAILURE);
3679 // 2. Drop broadcast packet if NDIS_PACKET_TYPE_BROADCAST is FALSE
3680 else if (pRxD->Bcast)
3682 if (pAdapter->bAcceptBroadcast == FALSE)
3684 return(NDIS_STATUS_FAILURE);
3688 // 3. Drop multicast packet if NDIS_PACKET_TYPE_ALL_MULTICAST is false
3689 // and NDIS_PACKET_TYPE_MULTICAST is false.
3690 // If NDIS_PACKET_TYPE_MULTICAST is true, but NDIS_PACKET_TYPE_ALL_MULTICAST is false.
3691 // We have to deal with multicast table lookup & drop not matched packets.
3692 else if (pRxD->Mcast)
3694 if (pAdapter->bAcceptAllMulticast == FALSE)
3696 if (pAdapter->bAcceptMulticast == FALSE)
3698 return(NDIS_STATUS_FAILURE);
3700 else
3702 // Selected accept multicast packet based on multicast table
3703 for (i = 0; i < pAdapter->NumberOfMcAddresses; i++)
3705 if (RTMPEqualMemory(&pHeader->Controlhead.Addr1, pAdapter->McastTable[i], ETH_LENGTH_OF_ADDRESS))
3707 break; // Matched
3711 // Not matched
3712 if (i == pAdapter->NumberOfMcAddresses)
3714 DBGPRINT(RT_DEBUG_INFO,"Drop multicast %02x:%02x:%02x:%02x:%02x:%02x\n",
3715 pHeader->Controlhead.Addr1.Octet[0], pHeader->Controlhead.Addr1.Octet[1],
3716 pHeader->Controlhead.Addr1.Octet[2], pHeader->Controlhead.Addr1.Octet[3],
3717 pHeader->Controlhead.Addr1.Octet[4], pHeader->Controlhead.Addr1.Octet[5]);
3718 return(NDIS_STATUS_FAILURE);
3720 else
3722 DBGPRINT(RT_DEBUG_INFO,"Accept multicast %02x:%02x:%02x:%02x:%02x:%02x\n",
3723 pHeader->Controlhead.Addr1.Octet[0], pHeader->Controlhead.Addr1.Octet[1],
3724 pHeader->Controlhead.Addr1.Octet[2], pHeader->Controlhead.Addr1.Octet[3],
3725 pHeader->Controlhead.Addr1.Octet[4], pHeader->Controlhead.Addr1.Octet[5]);
3731 // 4. Not U2M, not Mcast, not Bcast, must be unicast to other DA.
3732 // Since we did not implement promiscuous mode, just drop this kind of packet for now.
3733 else
3735 return(NDIS_STATUS_FAILURE);
3738 return(NDIS_STATUS_SUCCESS);
3742 ========================================================================
3744 Routine Description:
3745 Check and fine the packet waiting in SW queue with highest priority
3747 Arguments:
3748 pAdapter Pointer to our adapter
3750 Return Value:
3751 pQueue Pointer to Waiting Queue
3753 Note:
3755 ========================================================================
3757 PQUEUE_HEADER RTMPCheckTxSwQueue(
3758 IN PRTMP_ADAPTER pAdapter,
3759 OUT ULONG *Number,
3760 OUT UCHAR *AccessCategory)
3762 // Calculate total number of packets waiting in queues for Nitro mode
3763 *Number = pAdapter->TxSwQueue3.Number + pAdapter->TxSwQueue2.Number + pAdapter->TxSwQueue1.Number +
3764 pAdapter->TxSwQueue0.Number;
3766 if (pAdapter->TxSwQueue3.Head != NULL)
3768 *AccessCategory = 3;
3769 return (&pAdapter->TxSwQueue3);
3771 else if (pAdapter->TxSwQueue2.Head != NULL)
3773 *AccessCategory = 2;
3774 return (&pAdapter->TxSwQueue2);
3776 else if (pAdapter->TxSwQueue1.Head != NULL)
3778 *AccessCategory = 1;
3779 return (&pAdapter->TxSwQueue1);
3781 else if (pAdapter->TxSwQueue0.Head != NULL)
3783 *AccessCategory = 0;
3784 return (&pAdapter->TxSwQueue0);
3787 // No packet pending in Tx Sw queue
3788 *AccessCategory = 0;
3789 return (NULL);
3793 ========================================================================
3795 Routine Description:
3796 Process MIC error indication and record MIC error timer.
3798 Arguments:
3799 pAdapter Pointer to our adapter
3800 pWpaKey Pointer to the WPA key structure
3802 Return Value:
3803 None
3805 Note:
3807 ========================================================================
3809 VOID RTMPReportMicError(
3810 IN PRTMP_ADAPTER pAdapter,
3811 IN PWPA_KEY pWpaKey)
3813 ULONG Now;
3814 struct
3816 NDIS_802_11_STATUS_INDICATION Status;
3817 NDIS_802_11_AUTHENTICATION_REQUEST Request;
3818 } Report;
3820 // 0. Set Status to indicate auth error
3821 Report.Status.StatusType = Ndis802_11StatusType_Authentication;
3823 // 1. Check for Group or Pairwise MIC error
3824 if (pWpaKey->Type == PAIRWISE_KEY)
3825 Report.Request.Flags = NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR;
3826 else
3827 Report.Request.Flags = NDIS_802_11_AUTH_REQUEST_GROUP_ERROR;
3829 // 2. Copy AP MAC address
3830 NdisMoveMemory(Report.Request.Bssid, pWpaKey->BssId, 6);
3832 // 3. Calculate length
3833 Report.Request.Length = sizeof(NDIS_802_11_AUTHENTICATION_REQUEST);
3835 // 4. Record Last MIC error time and count
3836 Now = jiffies;
3837 if (pAdapter->PortCfg.MicErrCnt == 0)
3839 pAdapter->PortCfg.MicErrCnt++;
3840 pAdapter->PortCfg.LastMicErrorTime = Now;
3842 else if (pAdapter->PortCfg.MicErrCnt == 1)
3844 if ((pAdapter->PortCfg.LastMicErrorTime + (60 * HZ)) < Now)
3846 // Update Last MIC error time, this did not violate two MIC errors within 60 seconds
3847 pAdapter->PortCfg.LastMicErrorTime = Now;
3849 else
3851 pAdapter->PortCfg.LastMicErrorTime = Now;
3852 // Violate MIC error counts, MIC countermeasures kicks in
3853 pAdapter->PortCfg.MicErrCnt++;
3854 // We shall block all reception
3855 // We shall clean all Tx ring and disassoicate from AP after next EAPOL frame
3856 RTMPRingCleanUp(pAdapter, TX_RING);
3859 else
3861 // MIC error count >= 2
3862 // This should not happen
3867 #ifdef BIG_ENDIAN
3869 ========================================================================
3871 Routine Description:
3872 Endian conversion of Tx/Rx descriptor .
3874 Arguments:
3875 pAdapter Pointer to our adapter
3876 pData Pointer to Tx/Rx descriptor
3877 DescriptorType Direction of the frame
3879 Return Value:
3880 None
3882 Note:
3883 Call this function when read or update descriptor
3884 ========================================================================
3886 inline VOID RTMPDescriptorEndianChange(
3887 IN PUCHAR pData,
3888 IN ULONG DescriptorType)
3890 *((ULONG *)(pData + 40)) = SWAP32(*((ULONG *)(pData + 40))); // Byte 10
3891 if(DescriptorType == TYPE_TXD)
3892 *((ULONG *)(pData + 8)) = SWAP32(*((ULONG *)(pData + 8))); // Byte 2
3893 *(ULONG *)pData = SWAP32(*(ULONG *)pData); // Byte 0; this must be swapped last
3897 VOID WriteBackToDescriptor(
3898 IN PUCHAR Dest,
3899 IN PUCHAR Src,
3900 IN BOOLEAN DoEncrypt,
3901 IN ULONG DescriptorType)
3903 PULONG p1, p2;
3904 UCHAR i;
3906 p1 = ((PULONG)Dest) + 1;
3907 p2 = ((PULONG)Src) + 1;
3908 for (i = 1; i < RING_DESCRIPTOR_SIZE/4 ; i++)
3909 *p1++ = *p2++;
3910 *(PULONG)Dest = *(PULONG)Src;
3915 ========================================================================
3917 Routine Description:
3918 Endian conversion of all kinds of 802.11 frames .
3920 Arguments:
3921 pAdapter Pointer to our adapter
3922 pData Pointer to the 802.11 frame structure
3923 Dir Direction of the frame
3924 FromRxDoneInt Caller is from RxDone interrupt
3926 Return Value:
3927 None
3929 Note:
3930 Call this function when read or update buffer data
3931 ========================================================================
3933 VOID RTMPFrameEndianChange(
3934 IN PRTMP_ADAPTER pAdapter,
3935 IN PUCHAR pData,
3936 IN ULONG Dir,
3937 IN BOOLEAN FromRxDoneInt)
3939 PMACHDR pFrame;
3940 PUCHAR pMacHdr;
3942 // swab 16 bit fields - Frame Control field
3943 if(Dir == DIR_READ)
3945 *(USHORT *)pData = SWAP16(*(USHORT *)pData);
3948 pFrame = (PMACHDR) pData;
3949 pMacHdr = (PUCHAR) pFrame;
3951 // swab 16 bit fields - Duration/ID field
3952 *(USHORT *)(pMacHdr + 2) = SWAP16(*(USHORT *)(pMacHdr + 2));
3954 // swab 16 bit fields - Sequence Control field
3955 *(USHORT *)(pMacHdr + 22) = SWAP16(*(USHORT *)(pMacHdr + 22));
3957 if(pFrame->Type == BTYPE_MGMT)
3959 switch(pFrame->SubType)
3961 case SUBTYPE_ASSOC_REQ:
3962 case SUBTYPE_REASSOC_REQ:
3963 // swab 16 bit fields - CapabilityInfo field
3964 pMacHdr += MAC_HDR_LEN;
3965 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3967 // swab 16 bit fields - Listen Interval field
3968 pMacHdr += 2;
3969 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3970 break;
3972 case SUBTYPE_ASSOC_RSP:
3973 case SUBTYPE_REASSOC_RSP:
3974 // swab 16 bit fields - CapabilityInfo field
3975 pMacHdr += MAC_HDR_LEN;
3976 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3978 // swab 16 bit fields - Status Code field
3979 pMacHdr += 2;
3980 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3982 // swab 16 bit fields - AID field
3983 pMacHdr += 2;
3984 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3985 break;
3987 case SUBTYPE_AUTH:
3988 // If from RTMPHandleRxDoneInterrupt routine, it is still a encrypt format.
3989 // The convertion is delayed to RTMPHandleDecryptionDoneInterrupt.
3990 if(!FromRxDoneInt && pAdapter->NeedSwapToLittleEndian == TRUE)
3992 // swab 16 bit fields - Auth Alg No. field
3993 pMacHdr += MAC_HDR_LEN;
3994 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3996 // swab 16 bit fields - Auth Seq No. field
3997 pMacHdr += 2;
3998 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
4000 // swab 16 bit fields - Status Code field
4001 pMacHdr += 2;
4002 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
4004 break;
4006 case SUBTYPE_BEACON:
4007 case SUBTYPE_PROBE_RSP:
4008 // swab 16 bit fields - BeaconInterval field
4009 pMacHdr += MAC_HDR_LEN + TIMESTAMP_LEN;
4010 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
4012 // swab 16 bit fields - CapabilityInfo field
4013 pMacHdr += sizeof(USHORT);
4014 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
4015 break;
4017 case SUBTYPE_DEAUTH:
4018 case SUBTYPE_DISASSOC:
4019 // swab 16 bit fields - Reason code field
4020 pMacHdr += MAC_HDR_LEN;
4021 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
4022 break;
4025 else if( pFrame->Type == BTYPE_DATA )
4028 else if(pFrame->Type == BTYPE_CNTL)
4031 else
4033 DBGPRINT(RT_DEBUG_ERROR,"Invalid Frame Type!!!\n");
4036 // swab 16 bit fields - Frame Control
4037 if(Dir == DIR_WRITE)
4039 *(USHORT *)pData = SWAP16(*(USHORT *)pData);
4042 #endif