MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / net / wireless / rtlink.org / rtmp_data.c
blob15e449e4e22c6975d4969463b242ec03942e22d0
1 /*
2 ***************************************************************************
3 * Ralink Tech Inc.
4 * 4F, No. 2 Technology 5th Rd.
5 * Science-based Industrial Park
6 * Hsin-chu, Taiwan, R.O.C.
8 * (c) Copyright 2002, Ralink Technology, Inc.
10 * All rights reserved. Ralink's source code is an unpublished work and the
11 * use of a copyright notice does not imply otherwise. This source code
12 * contains confidential trade secret material of Ralink Tech. Any attemp
13 * or participation in deciphering, decoding, reverse engineering or in any
14 * way altering the source code is stricitly prohibited, unless the prior
15 * written consent of Ralink Technology, Inc. is obtained.
16 ***************************************************************************
18 Module Name:
19 rtmp_data.c
21 Abstract:
22 Data path subroutines
24 Revision History:
25 Who When What
26 -------- ---------- ----------------------------------------------
27 Name Date Modification logs
28 HK Initial
29 Paul 10/02/02 Merge & modify
30 John 02/25/03 Modified for RT2560
32 #include "rt_config.h"
34 #define ISR_JUST_LOCK 1 // add by Victor Yu. 05-23-2006
36 static UCHAR SNAP_802_1H[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
37 static UCHAR SNAP_BRIDGE_TUNNEL[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8};
38 static UCHAR EAPOL[] = {0x88, 0x8e};
40 static UCHAR IPX[] = {0x81, 0x37};
41 static UCHAR APPLE_TALK[] = {0x80, 0xf3};
42 static UCHAR PlcpSignal[12] = {
43 0, /* RATE_1 */ 1, /* RATE_2 */ 2, /* RATE_5_5 */ 3, /* RATE_11 */ // see BBP spec
44 11, /* RATE_6 */ 15, /* RATE_9 */ 10, /* RATE_12 */ 14, /* RATE_18 */ // see IEEE802.11a-1999 p.14
45 9, /* RATE_24 */ 13, /* RATE_36 */ 8, /* RATE_48 */ 12 /* RATE_54 */ }; // see IEEE802.11a-1999 p.14
47 #define COLLECT_RX_ANTENNA_AVERAGE_RSSI(_RxAnt, _rssi) \
48 { \
49 USHORT AvgRssi; \
50 if (_RxAnt.PrimaryInUsed) \
51 { \
52 AvgRssi = _RxAnt.AvgRssi[_RxAnt.PrimaryRxAnt]; \
53 if (AvgRssi > 0) \
54 AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi; \
55 else \
56 AvgRssi = _rssi << 3; \
57 _RxAnt.AvgRssi[_RxAnt.PrimaryRxAnt] = AvgRssi; \
58 } \
59 else \
60 { \
61 AvgRssi = _RxAnt.AvgRssi[_RxAnt.SecondaryRxAnt]; \
62 if (AvgRssi > 0) \
63 AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi; \
64 else \
65 AvgRssi = _rssi << 3; \
66 _RxAnt.AvgRssi[_RxAnt.SecondaryRxAnt] = AvgRssi; \
67 } \
71 ========================================================================
73 Routine Description:
74 Process RxDone interrupt, running in DPC level
76 Arguments:
77 pAdapter Pointer to our adapter
79 Return Value:
80 None
82 Note:
83 This routine has to maintain Rx ring read pointer.
84 ========================================================================
86 VOID RTMPHandleRxDoneInterrupt(
87 IN PRTMP_ADAPTER pAdapter)
89 PRXD_STRUC pRxD;
90 #ifdef BIG_ENDIAN
91 PRXD_STRUC pDestRxD;
92 RXD_STRUC RxD;
93 #endif
94 PHEADER_802_11 pHeader;
95 PUCHAR pData;
96 PUCHAR pDestMac, pSrcMac;
97 UCHAR Count;
98 UCHAR KeyIdx;
99 PWPA_KEY pWpaKey;
100 NDIS_STATUS Status;
101 BOOLEAN bDropFrame;
102 ULONG RegValue;//, Address;
103 ULONG HwDecryptIndex;
104 #ifndef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
105 unsigned long IrqFlags;
106 #endif
108 #ifdef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
109 spin_lock(&pAdapter->RxRingLock);
110 #else
111 // Make sure Rx ring resource won't be used by other threads
112 NdisAcquireSpinLock(&pAdapter->RxRingLock);
113 #endif
115 // Verify Hardware Decryption pointer with Software Decryption pointer
116 RTMP_IO_READ32(pAdapter, SECCSR0, &RegValue);
117 HwDecryptIndex = (RegValue - pAdapter->RxRing[0].pa_addr) / RING_DESCRIPTOR_SIZE;
118 #if 0
119 Address = pAdapter->RxRing[pAdapter->CurDecryptIndex].pa_addr;
120 if (Address != RegValue)
122 DBGPRINT(RT_DEBUG_ERROR,"Decrypt pointer not matched SW = 0x%x, HW = 0x%x\n", Address, RegValue);
123 DBGPRINT(RT_DEBUG_ERROR,"Sw Decr Ptr = %d, Rx ptr = %d Hw ptr = %d\n",
124 pAdapter->CurDecryptIndex, pAdapter->CurRxIndex, HwDecryptIndex);
126 #endif
127 Count = 0;
130 // Point to Rx indexed rx ring descriptor
131 #ifndef BIG_ENDIAN
132 pRxD = (PRXD_STRUC) pAdapter->RxRing[pAdapter->CurRxIndex].va_addr;
133 #else
134 pDestRxD = (PRXD_STRUC) pAdapter->RxRing[pAdapter->CurRxIndex].va_addr;
135 RxD = *pDestRxD;
136 pRxD = &RxD;
137 RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD); // Scott: to BE
138 #endif
139 // Initialize drop frame flag
140 bDropFrame = FALSE;
142 // In case of false alarm or processed at last instance
143 if (pRxD->Owner != DESC_OWN_HOST)
145 break;
148 // Decrypt engine stuck
149 if (pRxD->CipherOwner != DESC_OWN_HOST)
151 pAdapter->RalinkCounters.RxRingErrCount++;
152 break;
155 #ifdef RALINK_ATE
156 if(pAdapter->ate.Mode == ATE_RXFRAME)
158 bDropFrame = TRUE;
160 #endif //#ifdef RALINK_ATE
162 // Point to Rx ring buffer where stores the real data frame
163 pData = (PUCHAR) (pAdapter->RxRing[pAdapter->CurRxIndex].va_data_addr);
164 // Cast to 802.11 header for flags checking
165 pHeader = (PHEADER_802_11) pData;
167 #ifdef BIG_ENDIAN
168 RTMPFrameEndianChange(pAdapter, (PUCHAR)pHeader, DIR_READ, TRUE);
169 #endif
171 // Increase Total receive byte counter after real data received no mater any error or not
172 pAdapter->RalinkCounters.ReceivedByteCount += pRxD->DataByteCnt;
174 // Check for all RxD errors
175 Status = RTMPCheckRxDescriptor(pRxD);
177 // Apply packet filtering rule based on microsoft requirements.
178 if (Status == NDIS_STATUS_SUCCESS)
179 Status = RTMPApplyPacketFilter(pAdapter, pRxD, pHeader);
181 // Add receive counters
182 if (Status == NDIS_STATUS_SUCCESS)
184 // Increase 802.11 counters & general receive counters
185 INC_COUNTER(pAdapter->WlanCounters.ReceivedFragmentCount);
187 // collect current antenna's average RSSI for software-based RX Antenna diversity
188 if (pRxD->U2M)
190 COLLECT_RX_ANTENNA_AVERAGE_RSSI(pAdapter->PortCfg.RxAnt, pRxD->BBR1);
193 else
195 // Increase general counters
196 pAdapter->Counters.RxErrors++;
199 // Check for retry bit, if this bit is on, search the cache with SA & sequence
200 // as index, if matched, discard this frame, otherwise, update cache
201 // This check only apply to unicast data & management frames
202 if ((Status == NDIS_STATUS_SUCCESS) && (pRxD->U2M) && (pHeader->Controlhead.Frame.Type != BTYPE_CNTL))
204 if (pHeader->Controlhead.Frame.Retry)
206 if (RTMPSearchTupleCache(pAdapter, pHeader) == TRUE)
208 // Found retry frame in tuple cache, Discard this frame / fragment
209 // Increase 802.11 counters
210 INC_COUNTER(pAdapter->WlanCounters.FrameDuplicateCount);
211 Status = NDIS_STATUS_FAILURE;
213 else
214 RTMPUpdateTupleCache(pAdapter, pHeader);
216 else // Update Tuple Cache
217 RTMPUpdateTupleCache(pAdapter, pHeader);
221 // Do RxD release operation for all failure frames
223 pRxD->CipherAlg = CIPHER_NONE;
224 if (Status == NDIS_STATUS_SUCCESS)
226 // pData : Pointer skip the first 24 bytes, 802.11 HEADER
227 pData += LENGTH_802_11;
230 // Start of main loop to parse receiving frames.
231 // The sequence will be Type first, then subtype...
233 switch (pHeader->Controlhead.Frame.Type)
235 // Frame with data type
236 case BTYPE_DATA:
237 // Drop not my BSS frame
238 if (INFRA_ON(pAdapter))
240 // Infrastructure mode, check address 2 for BSSID
241 if (!RTMPEqualMemory(&pHeader->Controlhead.Addr2, &pAdapter->PortCfg.Bssid, 6))
243 // Receive frame not my BSSID
244 bDropFrame = TRUE;
245 break;
248 else // Ad-Hoc mode or Not associated
250 // Ad-Hoc mode, check address 3 for BSSID
251 if (!RTMPEqualMemory(&pHeader->Addr3, &pAdapter->PortCfg.Bssid, 6))
253 // Receive frame not my BSSID
254 bDropFrame = TRUE;
255 break;
258 // Drop frame from AP while we are in Ad-hoc mode or not associated
259 if (pHeader->Controlhead.Frame.FrDs)
261 bDropFrame = TRUE;
262 break;
266 // Drop Null data frame, or CF with NULL data frame
267 if ((pHeader->Controlhead.Frame.Subtype == SUBTYPE_NULL_FUNC) ||
268 (pHeader->Controlhead.Frame.Subtype == SUBTYPE_CFACK) ||
269 (pHeader->Controlhead.Frame.Subtype == SUBTYPE_CFPOLL) ||
270 (pHeader->Controlhead.Frame.Subtype == SUBTYPE_CFACK_CFPOLL))
272 bDropFrame = TRUE;
273 break;
276 // Process Multicast data frame
277 if (pRxD->Mcast)
279 // Multicast 802.11 Counter
280 INC_COUNTER(pAdapter->WlanCounters.MulticastReceivedFrameCount);
281 DBGPRINT(RT_DEBUG_INFO,"Receiving multicast frame\n");
284 // Init WPA Key to NULL
285 pWpaKey = (PWPA_KEY) NULL;
287 // Find the WPA key, either Group or Pairwise Key
288 if ((pAdapter->PortCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pHeader->Controlhead.Frame.Wep))
290 INT idx;
292 // First lookup the DA, if it's a group address, use GROUP key
293 if (pRxD->Bcast || pRxD->Mcast)
296 idx = (*(pData + 3) & 0xc0) >> 6;
297 if ((pAdapter->PortCfg.GroupKey[idx].KeyLen != 0) &&
298 ((INFRA_ON(pAdapter) && (NdisEqualMemory(&pHeader->Controlhead.Addr2, &pAdapter->PortCfg.Bssid, 6))) ||
299 (ADHOC_ON(pAdapter) && (NdisEqualMemory(&pHeader->Addr3, &pAdapter->PortCfg.Bssid, 6)))))
301 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.GroupKey[idx];
302 pWpaKey->Type = GROUP_KEY;
303 DBGPRINT(RT_DEBUG_INFO, "Rx Use Group Key %d\n", idx);
306 // Try to find the Pairwise Key
307 else
309 for (idx = 0; idx < PAIRWISE_KEY_NO; idx++)
311 if ((NdisEqualMemory(&pHeader->Controlhead.Addr2, pAdapter->PortCfg.PairwiseKey[idx].BssId, 6)) &&
312 (pAdapter->PortCfg.PairwiseKey[idx].KeyLen != 0))
314 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.PairwiseKey[idx];
315 pWpaKey->Type = PAIRWISE_KEY;
316 DBGPRINT(RT_DEBUG_INFO, "Rx Use Pairwise Key\n");
317 break;
320 #if 1
321 // Use default Group Key if there is no Pairwise key present
322 if ((pWpaKey == NULL) && (pAdapter->PortCfg.GroupKey[pAdapter->PortCfg.DefaultKeyId].KeyLen != 0))
324 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.GroupKey[pAdapter->PortCfg.DefaultKeyId];
325 pWpaKey->Type = GROUP_KEY;
326 DBGPRINT(RT_DEBUG_INFO, "Rx Use Group Key\n");
328 #endif
332 // Process Broadcast & Multicast data frame
333 if (pRxD->Bcast || pRxD->Mcast)
335 // Drop Mcast / Bcast frame with fragment bit on
336 if (pHeader->Controlhead.Frame.MoreFrag)
338 DBGPRINT(RT_DEBUG_ERROR,"Receiving multicast frame with fragment bit on\n");
339 Status = NDIS_STATUS_FAILURE;
340 bDropFrame = TRUE;
341 break;
344 // Filter out Bcast frame which AP relayed for us
345 if (pHeader->Controlhead.Frame.FrDs && RTMPEqualMemory(&pHeader->Addr3, pAdapter->CurrentAddress, 6))
347 Status = NDIS_STATUS_FAILURE;
348 bDropFrame = TRUE;
349 break;
352 // WEP encrypted frame
353 if (pHeader->Controlhead.Frame.Wep)
355 // Check our WEP setting, if no WEP turning on, just drop this frame
356 if (pAdapter->PortCfg.WepStatus == Ndis802_11Encryption1Enabled) // WEP
358 KeyIdx = (*(pData + 3) & 0xc0) >> 6;
359 NdisMoveMemory((PUCHAR) &pRxD->Iv, pData, 4); //Get WEP IV
360 NdisMoveMemory(pRxD->Key, pAdapter->PortCfg.SharedKey[KeyIdx].Key, pAdapter->PortCfg.SharedKey[KeyIdx].KeyLen);
361 if (pAdapter->PortCfg.SharedKey[KeyIdx].KeyLen == 5)
362 pRxD->CipherAlg = CIPHER_WEP64;
363 else
364 pRxD->CipherAlg = CIPHER_WEP128;
366 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) && (pWpaKey != NULL)) // TKIP
368 UCHAR Eiv_Tmp[4];
370 NdisMoveMemory((PUCHAR) &pRxD->Iv, pData, 4); //Get WEP IV
371 // Swap EIV byte order, due to ASIC's bug.
372 Eiv_Tmp[0] = *(pData + 7);
373 Eiv_Tmp[1] = *(pData + 6);
374 Eiv_Tmp[2] = *(pData + 5);
375 Eiv_Tmp[3] = *(pData + 4);
376 NdisMoveMemory((PUCHAR) &pRxD->Eiv, Eiv_Tmp, 4); //Get WEP EIV
377 // Copy TA into RxD
378 NdisMoveMemory(pRxD->TA, &pHeader->Controlhead.Addr2, 6);
379 KeyIdx = (*(pData + 3) & 0xc0) >> 6;
380 NdisMoveMemory(pRxD->Key, pWpaKey->Key, 16);
381 pRxD->CipherAlg = CIPHER_TKIP;
383 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled) && (pWpaKey != NULL)) // AES
385 NdisMoveMemory((PUCHAR) &pRxD->Iv, pData, 4); //Get WEP IV
386 NdisMoveMemory((PUCHAR) &pRxD->Eiv, (pData + 4), 4); //Get WEP EIV
387 // Copy TA into RxD
388 NdisMoveMemory(pRxD->TA, &pHeader->Controlhead.Addr2, 6);
389 KeyIdx = (*(pData + 3) & 0xc0) >> 6;
390 NdisMoveMemory(pRxD->Key, pWpaKey->Key, 16);
391 pRxD->CipherAlg = CIPHER_AES;
393 else
395 // Add error counter
396 Status = NDIS_STATUS_FAILURE;
397 bDropFrame = TRUE;
398 break;
401 else // Not encrypted frames
403 pRxD->CipherAlg = CIPHER_NONE;
407 // Begin process unicast to me frame
408 else if (pRxD->U2M)
410 // Send PS-Poll for AP to send next data frame
411 if ((pHeader->Controlhead.Frame.MoreData) && INFRA_ON(pAdapter) && (pAdapter->PortCfg.Psm == PWR_SAVE))
413 EnqueuePsPoll(pAdapter);
414 DBGPRINT(RT_DEBUG_TRACE, "Sending PS-POLL\n");
418 // Begin frame processing
420 pDestMac = (PUCHAR) &(pHeader->Controlhead.Addr1); // DA is always address 1
421 if (INFRA_ON(pAdapter)) // For infrastructure, SA is address 3
422 pSrcMac = (PUCHAR) &(pHeader->Addr3);
423 else // For IBSS mode, SA is address 2
424 pSrcMac = (PUCHAR) &(pHeader->Controlhead.Addr2);
426 // WEP encrypted frame
427 if (pAdapter->PortCfg.WepStatus == Ndis802_11Encryption1Enabled) // WEP
429 if (pHeader->Controlhead.Frame.Wep)
431 KeyIdx = (*(pData + 3) & 0xc0) >> 6;
433 NdisMoveMemory((PUCHAR) &pRxD->Iv, pData, 4); //Get WEP IV
434 NdisMoveMemory(pRxD->Key, pAdapter->PortCfg.SharedKey[KeyIdx].Key, pAdapter->PortCfg.SharedKey[KeyIdx].KeyLen);
435 if (pAdapter->PortCfg.SharedKey[KeyIdx].KeyLen == 5)
436 pRxD->CipherAlg = CIPHER_WEP64;
437 else
438 pRxD->CipherAlg = CIPHER_WEP128;
440 else if ((pAdapter->PortCfg.PrivacyFilter == Ndis802_11PrivFilter8021xWEP) &&
441 (pHeader->Frag == 0))
443 // Check 802.1x frame, if not drop it.
444 if (!RTMPEqualMemory(EAPOL, pData + 6, 2))
446 // Not 802.1X frames
447 // Add error counter
448 Status = NDIS_STATUS_FAILURE;
449 bDropFrame = TRUE;
450 break;
454 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) && (pWpaKey != NULL)) // TKIP
456 if (pHeader->Controlhead.Frame.Wep)
458 UCHAR Eiv_Tmp[4];
460 NdisMoveMemory((PUCHAR) &pRxD->Iv, pData, 4); //Get WEP IV
461 // Swap EIV byte order, due to ASIC's bug.
462 Eiv_Tmp[0] = *(pData + 7);
463 Eiv_Tmp[1] = *(pData + 6);
464 Eiv_Tmp[2] = *(pData + 5);
465 Eiv_Tmp[3] = *(pData + 4);
466 NdisMoveMemory((PUCHAR) &pRxD->Eiv, Eiv_Tmp, 4); //Get WEP EIV
467 KeyIdx = (*(pData + 3) & 0xc0) >> 6;
468 // Copy TA into RxD
469 NdisMoveMemory(pRxD->TA, &pHeader->Controlhead.Addr2, 6);
470 NdisMoveMemory(pRxD->Key, pWpaKey->Key, 16);
471 pRxD->CipherAlg = CIPHER_TKIP;
473 else if ((pAdapter->PortCfg.PrivacyFilter == Ndis802_11PrivFilter8021xWEP) &&
474 (pHeader->Frag == 0))
476 // Check 802.1x frame, if not drop it.
477 if (!RTMPEqualMemory(EAPOL, pData + 6, 2))
479 // Not 802.1X frames
480 // Add error counter
481 Status = NDIS_STATUS_FAILURE;
482 bDropFrame = TRUE;
483 break;
487 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled) && (pWpaKey != NULL)) // AES
489 if (pHeader->Controlhead.Frame.Wep)
491 NdisMoveMemory((PUCHAR) &pRxD->Iv, pData, 4); //Get WEP IV
492 NdisMoveMemory((PUCHAR) &pRxD->Eiv, (pData + 4), 4); //Get WEP EIV
493 // Copy TA into RxD
494 NdisMoveMemory(pRxD->TA, &pHeader->Controlhead.Addr2, 6);
495 KeyIdx = (*(pData + 3) & 0xc0) >> 6;
496 NdisMoveMemory(pRxD->Key, pWpaKey->Key, 16);
497 pRxD->CipherAlg = CIPHER_AES;
499 else if ((pAdapter->PortCfg.PrivacyFilter == Ndis802_11PrivFilter8021xWEP) &&
500 (pHeader->Frag == 0))
502 // Check 802.1x frame, if not drop it.
503 if (!RTMPEqualMemory(EAPOL, pData + 6, 2))
505 // Not 802.1X frames
506 // Add error counter
507 Status = NDIS_STATUS_FAILURE;
508 bDropFrame = TRUE;
509 break;
513 else if (pHeader->Controlhead.Frame.Wep)
515 // Drop WEP frame when PrivacyInvoked is FALSE
516 Status = NDIS_STATUS_FAILURE;
517 bDropFrame = TRUE;
518 break;
520 else // Not encryptrd frames
522 pRxD->CipherAlg = CIPHER_NONE;
525 break;
527 case BTYPE_MGMT:
528 // Always None encrypted
529 pRxD->CipherAlg = CIPHER_NONE;
530 break;
532 case BTYPE_CNTL:
533 // Ignore ???
534 bDropFrame = TRUE;
535 break;
537 default :
538 bDropFrame = TRUE;
539 break;
542 else
543 bDropFrame = TRUE;
545 // Packet will still do NULL cipher operation and drop afterward
546 if (bDropFrame == TRUE) {
547 pRxD->Drop = 1;
548 pRxD->CipherAlg = CIPHER_NONE;
549 } else {
550 pRxD->Drop = 0;
551 pRxD->IvOffset = LENGTH_802_11;
553 pRxD->CipherOwner = DESC_OWN_NIC;
555 #ifdef BIG_ENDIAN
556 RTMPFrameEndianChange(pAdapter, (PUCHAR)pHeader, DIR_WRITE, TRUE);
557 RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
558 *pDestRxD = RxD;
559 #endif
561 pAdapter->CurRxIndex++;
562 if (pAdapter->CurRxIndex >= RX_RING_SIZE)
564 pAdapter->CurRxIndex = 0;
566 Count++;
567 pAdapter->RalinkCounters.RxCount ++;
568 } while (Count < MAX_RX_PROCESS);
570 // Kick Decrypt Control Register, based on ASIC's implementation
571 // We have to kick decrypt & encrypt every frame.
572 RTMP_IO_WRITE32(pAdapter, SECCSR0, 0x1);
574 #ifdef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
575 spin_unlock(&pAdapter->RxRingLock);
576 #else
577 // Make sure to release Rx ring resource
578 NdisReleaseSpinLock(&pAdapter->RxRingLock);
579 #endif
583 ========================================================================
585 Routine Description:
586 Process TxRing TxDone interrupt, running in DPC level
588 Arguments:
589 Adapter Pointer to our adapter
591 Return Value:
592 None
594 Note:
596 ========================================================================
598 VOID RTMPHandleTxRingTxDoneInterrupt(
599 IN PRTMP_ADAPTER pAdapter)
601 PTXD_STRUC pTxD;
602 #ifdef BIG_ENDIAN
603 PTXD_STRUC pDestTxD;
604 TXD_STRUC TxD;
605 #endif
606 UCHAR Count;
607 #ifndef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
608 unsigned long IrqFlags;
609 #endif
611 #ifdef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
612 spin_lock(&pAdapter->TxRingLock);
613 #else
614 // Make sure Tx ring resource won't be used by other threads
615 NdisAcquireSpinLock(&pAdapter->TxRingLock);
616 #endif
618 Count = 0;
621 #ifndef BIG_ENDIAN
622 pTxD = (PTXD_STRUC) (pAdapter->TxRing[pAdapter->NextTxDoneIndex].va_addr);
623 #else
624 pDestTxD = (PTXD_STRUC) (pAdapter->TxRing[pAdapter->NextTxDoneIndex].va_addr);
625 TxD = *pDestTxD;
626 pTxD = &TxD;
627 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
628 #endif
630 if ((pTxD->Owner == DESC_OWN_NIC) || (pTxD->CipherOwn == DESC_OWN_NIC) || (pTxD->Valid == FALSE))
632 break;
635 RTMPHardTransmitDone(
636 pAdapter,
637 pTxD,
638 pAdapter->TxRing[pAdapter->NextTxDoneIndex].FrameType);
640 // It might happend with no Ndis packet to indicate back to upper layer
641 // Clear for NdisSendComplete request
642 pTxD->Valid = FALSE;
644 // Increase Total transmit byte counter after real data sent out
645 pAdapter->RalinkCounters.TransmittedByteCount += pTxD->DataByteCnt;
647 #ifdef BIG_ENDIAN
648 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
649 *pDestTxD = TxD;
650 #endif
652 pAdapter->NextTxDoneIndex++;
653 if (pAdapter->NextTxDoneIndex >= TX_RING_SIZE)
655 pAdapter->NextTxDoneIndex = 0;
657 } while (++Count < MAX_TX_PROCESS);
659 #ifdef RALINK_ATE
660 if((pAdapter->ate.Mode == ATE_TXCONT) || (pAdapter->ate.Mode == ATE_TXCARR) || ((pAdapter->ate.Mode == ATE_TXFRAME) && (pAdapter->ate.TxDoneCount < pAdapter->ate.TxCount)))
662 pAdapter->ate.TxDoneCount++;
663 // Scott printk("pAdapter->ate.TxDoneCount = %d, Preamble=%d\n", pAdapter->ate.TxDoneCount, pAdapter->PortCfg.TxPreambleInUsed);
664 pTxD = (PTXD_STRUC)pAdapter->TxRing[pAdapter->CurEncryptIndex].va_addr;
666 RTMPWriteTxDescriptor(pTxD, TRUE, CIPHER_NONE, FALSE, FALSE, FALSE,
667 SHORT_RETRY, IFS_BACKOFF, pAdapter->ate.TxRate, 4,
668 pAdapter->ate.TxLength, Rt802_11PreambleLong, 0);
670 pAdapter->CurEncryptIndex++;
671 if (pAdapter->CurEncryptIndex >= TX_RING_SIZE)
673 pAdapter->CurEncryptIndex = 0;
676 RTMP_IO_WRITE32(pAdapter, SECCSR1, 0x1);
678 #endif //#ifdef RALINK_ATE
680 #ifdef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
681 spin_unlock(&pAdapter->TxRingLock);
682 #else
683 // Make sure to release Tx ring resource
684 NdisReleaseSpinLock(&pAdapter->TxRingLock);
685 #endif
687 if(pAdapter->bNetDeviceStopQueue)
689 if(pAdapter->TxSwQueue0.Number < (MAX_PACKETS_IN_QUEUE >> 2))
691 DBGPRINT(RT_DEBUG_TRACE, "NetDevice start queue!!!\n\n");
692 pAdapter->bNetDeviceStopQueue = FALSE;
693 netif_start_queue(pAdapter->net_dev);
697 // Some Tx ring resource freed, check for pending send frame for hard transmit
698 if ((!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
699 (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF)) &&
700 (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS)))
702 // RTMPDeQueuePacket(pAdapter, &pAdapter->TxSwQueue0);
703 // Call dequeue without selected queue, let the subroutine select the right priority
704 // Tx software queue
705 RTMPDeQueuePacket(pAdapter);
710 ========================================================================
712 Routine Description:
713 Process Priority ring TxDone interrupt, running in DPC level
715 Arguments:
716 Adapter Pointer to our adapter
718 Return Value:
719 None
721 Note:
723 ========================================================================
725 VOID RTMPHandlePrioRingTxDoneInterrupt(
726 IN PRTMP_ADAPTER pAdapter)
728 PTXD_STRUC pTxD;
729 #ifdef BIG_ENDIAN
730 PTXD_STRUC pDestTxD;
731 TXD_STRUC TxD;
732 #endif
733 UCHAR Count=0;
734 #if 0 // mask by Victor Yu. 05-18-2006
735 PMGMT_STRUC pMgmt;
736 #endif
737 #ifndef ISR_JUST_LOCK // add by Victor yu. 05-23-2006
738 unsigned long IrqFlags;
739 #endif
741 #ifdef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
742 spin_lock(&pAdapter->PrioRingLock);
743 #else
744 // Make sure Prio ring resource won't be used by other threads
745 NdisAcquireSpinLock(&pAdapter->PrioRingLock);
746 #endif
748 do {
749 #ifndef BIG_ENDIAN
750 pTxD = (PTXD_STRUC)(pAdapter->PrioRing[pAdapter->NextPrioDoneIndex].va_addr);
751 #else
752 pDestTxD = (PTXD_STRUC)(pAdapter->PrioRing[pAdapter->NextPrioDoneIndex].va_addr);
753 TxD = *pDestTxD;
754 pTxD = &TxD;
755 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
756 #endif
758 // Check for the descriptor ownership
759 if ((pTxD->Owner == DESC_OWN_NIC) || (pTxD->Valid == FALSE)) {
760 #ifdef BIG_ENDIAN
761 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
762 *pDestTxD = TxD;
763 #endif
764 break;
767 // No need to put in reply for MLME
768 RTMPHardTransmitDone(
769 pAdapter,
770 pTxD,
771 pAdapter->PrioRing[pAdapter->NextPrioDoneIndex].FrameType);
773 // It might happend with no Ndis packet to indicate back to upper layer
774 pTxD->Valid = FALSE;
776 // Increase Total transmit byte counter after real data sent out
777 pAdapter->RalinkCounters.TransmittedByteCount += pTxD->DataByteCnt;
779 #ifdef BIG_ENDIAN
780 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
781 *pDestTxD = TxD;
782 #endif
784 pAdapter->NextPrioDoneIndex++;
785 if (pAdapter->NextPrioDoneIndex >= PRIO_RING_SIZE) {
786 pAdapter->NextPrioDoneIndex = 0;
788 } while (++Count < MAX_TX_PROCESS);
790 #ifdef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
791 spin_unlock(&pAdapter->PrioRingLock);
792 #else
793 // Make sure to release Prio ring resource
794 NdisReleaseSpinLock(&pAdapter->PrioRingLock);
795 #endif
797 #if 0 // don't need to do this, mask by Victor Yu. 05-18-2006
798 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF))
799 return;
800 #endif
802 // Scott: 2005-05-04
803 // This IRQ handler might interrupt MiniportMMRequest(), and cause
804 // the MgmtRing[] massed up, since MgmtRing[] is not protected by
805 // any spinlock or semaphore.
806 // Remove below code shouldn't affect the MgmtRing[], since in
807 // MiniportMMRequest(), release of MgmtRing[] will be processed there, too.
808 #if 0
809 // Scott: 2004-12-03
810 if (pAdapter->PushMgmtIndex != pAdapter->PopMgmtIndex)
812 if (RTMPFreeDescriptorRequest(pAdapter, PRIO_RING, 1) == NDIS_STATUS_SUCCESS)
814 pMgmt = (PMGMT_STRUC) &pAdapter->MgmtRing[pAdapter->PopMgmtIndex];
815 if (pMgmt->Valid == TRUE)
817 MlmeHardTransmit(pAdapter, pMgmt->pBuffer, pMgmt->Length);
818 MlmeFreeMemory(pAdapter, pMgmt->pBuffer);
819 pMgmt->Valid = FALSE;
820 pAdapter->PopMgmtIndex++;
821 pAdapter->MgmtQueueSize--;
822 if (pAdapter->PopMgmtIndex >= MGMT_RING_SIZE)
824 pAdapter->PopMgmtIndex = 0;
826 DBGPRINT(RT_DEBUG_TRACE, "Push1=%d, Pop1=%d, Size1=%d\n", pAdapter->PushMgmtIndex, pAdapter->PopMgmtIndex, pAdapter->MgmtQueueSize);
829 else // AlbertY @ 20041202
831 DBGPRINT(RT_DEBUG_TRACE, "In PrioRingTxDoneInt: RTMPFreeDescriptorRequest Fail.\n");
834 #endif
838 ========================================================================
840 Routine Description:
841 Process Atim ring TxDone interrupt, running in DPC level
843 Arguments:
844 Adapter Pointer to our adapter
846 Return Value:
847 None
849 Note:
851 ========================================================================
853 VOID RTMPHandleAtimRingTxDoneInterrupt(
854 IN PRTMP_ADAPTER pAdapter)
856 // PTXD_STRUC pTxD;
857 // UCHAR Count;
858 // unsigned long IrqFlags;
860 // Make sure Atim ring resource won't be used by other threads
861 //NdisAcquireSpinLock(&pAdapter->AtimRingLock);
863 // Did not support ATIM, remove everything.
865 // Make sure to release Atim ring resource
866 //NdisReleaseSpinLock(&pAdapter->AtimRingLock);
870 ========================================================================
872 Routine Description:
873 Process Rx ring DecryptionDone interrupt, running in DPC level
875 Arguments:
876 Adapter Pointer to our adapter
878 Return Value:
879 None
881 Note:
883 ========================================================================
885 VOID RTMPHandleDecryptionDoneInterrupt(
886 IN PRTMP_ADAPTER pAdapter)
888 PRXD_STRUC pRxD;
889 #ifdef BIG_ENDIAN
890 PRXD_STRUC pDestRxD;
891 RXD_STRUC RxD;
892 #endif
893 PHEADER_802_11 pHeader;
894 PUCHAR pData;
895 PVOID pManage;
896 PUCHAR pDestMac, pSrcMac;
897 UCHAR Header802_3[14];
898 UCHAR LLC_Len[2];
899 USHORT PacketSize;
900 ULONG High32TSF, Low32TSF;
901 UCHAR Count;
902 PWPA_KEY pWpaKey;
903 NDIS_STATUS Status;
904 ULONG RegValue;
905 ULONG HwDecryptIndex;
906 ULONG i;
907 struct sk_buff *skb;
908 #ifndef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
909 unsigned long IrqFlags;
910 #endif
912 #ifdef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
913 spin_lock(&pAdapter->RxRingLock);
914 #else
915 // Make sure Rx ring resource won't be used by other threads
916 NdisAcquireSpinLock(&pAdapter->RxRingLock);
917 #endif
919 RTMP_IO_READ32(pAdapter, SECCSR0, &RegValue);
920 HwDecryptIndex = (RegValue - pAdapter->RxRing[0].pa_addr) / RING_DESCRIPTOR_SIZE;
922 Count = 0;
923 #if 0 // mask by Victor Yu. 05-18-2006
924 //do
925 while (pAdapter->CurDecryptIndex != HwDecryptIndex)
927 #else // add by Victor Yu. 05-18-2006
928 do {
929 if ( pAdapter->CurDecryptIndex == HwDecryptIndex )
930 break;
931 #endif
932 // Point to Rx indexed rx ring descriptor
933 #ifndef BIG_ENDIAN
934 pRxD = (PRXD_STRUC) pAdapter->RxRing[pAdapter->CurDecryptIndex].va_addr;
935 #else
936 pDestRxD = (PRXD_STRUC) pAdapter->RxRing[pAdapter->CurDecryptIndex].va_addr;
937 RxD = *pDestRxD;
938 pRxD = &RxD;
939 RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
940 #endif
942 // In case of false alarm or processed at last instance
943 if ((pRxD->Owner != DESC_OWN_HOST) || (pRxD->CipherOwner != DESC_OWN_HOST))
944 break;
946 // Point to Rx ring buffer where stores the real data frame
947 pData = (PUCHAR) (pAdapter->RxRing[pAdapter->CurDecryptIndex].va_data_addr);
948 // Cast to 802.11 header for flags checking
949 pHeader = (PHEADER_802_11) pData;
951 #ifdef BIG_ENDIAN
952 RTMPFrameEndianChange(pAdapter, (PUCHAR)pHeader, DIR_READ, FALSE);
953 #endif
954 // Driver will check the decrypt algorithm and decide whether this ICV is true or not
955 if ((pRxD->IcvError == 1) && (pRxD->CipherAlg == CIPHER_NONE))
956 pRxD->IcvError = 0;
958 // Since we already process header at RxDone interrupt, there is no need to proces
959 // header sanity again, the only thing we have to check is icv_err bit
960 if (pRxD->IcvError == 1) {
961 DBGPRINT(RT_DEBUG_TRACE,"Rx DecryptDone - ICV error (len %d)\n", pRxD->DataByteCnt);
962 pRxD->Drop =1; // Drop frame with icv error
964 // Saved data pointer for management frame which will pass to MLME block
965 pManage = (PVOID) pData;
967 // pData : Pointer skip the first 24 bytes, 802.11 HEADER
968 pData += LENGTH_802_11;
970 // The total available payload should exclude 24-byte 802.11 Header
971 // If Security is enabled, IV, EIV, ICV size is excluded by ASIC
972 PacketSize = (USHORT) pRxD->DataByteCnt - LENGTH_802_11;
974 // Find the WPA key, either Group or Pairwise Key
975 // Although the data has been decrypted by ASIC,
976 // driver has to calculate the RxMIC which required the key.
977 // The failed case should not happen. If it did, drop it.
978 // Init WPA Key
979 pWpaKey = (PWPA_KEY) NULL;
980 if ((pAdapter->PortCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pHeader->Controlhead.Frame.Wep)) {
981 INT idx;
983 // First lookup the DA, if it's a group address, use GROUP key
984 if (pRxD->Bcast || pRxD->Mcast) {
985 // Get the IV index from RxD descriptor
986 idx = (pRxD->Iv & 0xc0000000) >> 30;
987 if ((pAdapter->PortCfg.GroupKey[idx].KeyLen != 0) &&
988 ((INFRA_ON(pAdapter) && (NdisEqualMemory(&pHeader->Controlhead.Addr2, &pAdapter->PortCfg.Bssid, 6))) ||
989 (ADHOC_ON(pAdapter) && (NdisEqualMemory(&pHeader->Addr3, &pAdapter->PortCfg.Bssid, 6)))))
991 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.GroupKey[idx];
992 pWpaKey->Type = GROUP_KEY;
993 DBGPRINT(RT_DEBUG_INFO, "Decrypt Done: Rx Use Group Key %d\n", idx);
996 // Try to find the Pairwise Key
997 else
999 for (idx = 0; idx < PAIRWISE_KEY_NO; idx++)
1001 if ((NdisEqualMemory(&pHeader->Controlhead.Addr2, pAdapter->PortCfg.PairwiseKey[idx].BssId, 6)) &&
1002 (pAdapter->PortCfg.PairwiseKey[idx].KeyLen != 0))
1004 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.PairwiseKey[idx];
1005 pWpaKey->Type = PAIRWISE_KEY;
1006 DBGPRINT(RT_DEBUG_INFO, "Rx Use Pairwise Key\n");
1007 break;
1010 #if 1
1011 // Use default Group Key if there is no Pairwise key present
1012 if ((pWpaKey == NULL) && (pAdapter->PortCfg.GroupKey[pAdapter->PortCfg.DefaultKeyId].KeyLen != 0))
1014 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.GroupKey[pAdapter->PortCfg.DefaultKeyId];
1015 pWpaKey->Type = GROUP_KEY;
1016 DBGPRINT(RT_DEBUG_INFO, "Rx Use Group Key\n");
1018 #endif
1021 // If there is no WPA key matched, this frame should be dropped
1022 if (pWpaKey == NULL)
1023 pRxD->Drop = 1;
1027 // Start of main loop to parse receiving frames.
1028 // The sequence will be Type first, then subtype...
1030 if (pRxD->Drop == 0)
1032 switch (pHeader->Controlhead.Frame.Type)
1034 // Frame with data type
1035 case BTYPE_DATA:
1036 // DA is always address 1
1037 // For infrastructure, SA is address 3. For IBSS mode, SA is address 2
1038 pDestMac = (PUCHAR) &(pHeader->Controlhead.Addr1);
1039 if (INFRA_ON(pAdapter))
1040 pSrcMac = (PUCHAR) &(pHeader->Addr3);
1041 else
1042 pSrcMac = (PUCHAR) &(pHeader->Controlhead.Addr2);
1044 // Process Broadcast & Multicast data frame
1045 if (pRxD->Bcast || pRxD->Mcast)
1047 // For TKIP frame, calculate the MIC value
1048 if (pRxD->CipherAlg == CIPHER_TKIP)
1050 INT i = 0;
1052 if (pWpaKey == NULL)
1054 DBGPRINT(RT_DEBUG_ERROR,"No matched TKIP in decryption done calculate MIC routine!!!\n");
1055 Status = NDIS_STATUS_FAILURE;
1056 break;
1059 // Minus MIC length
1060 PacketSize -= 8;
1061 if (RTMPTkipCompareMICValue(
1062 pAdapter,
1063 pData,
1064 pDestMac,
1065 pSrcMac,
1066 pWpaKey->RxMic,
1067 PacketSize) == FALSE)
1069 DBGPRINT(RT_DEBUG_ERROR,"Rx MIC Value error\n");
1070 RTMPReportMicError(pAdapter, pWpaKey);
1071 Status = NDIS_STATUS_FAILURE;
1072 break;
1075 // Second, increase RxTsc value for next transmission
1076 while (++pWpaKey->RxTsc[i] == 0x0)
1078 i++;
1079 if (i == 6)
1080 break;
1082 // Rx TSC has done one full cycle, since re-key is done by transmitter
1083 // We did not do anything for Rx path
1086 // build 802.3 header and decide if remove the 8-byte LLC/SNAP encapsulation
1087 CONVERT_TO_802_3(Header802_3, pDestMac, pSrcMac, pData, PacketSize);
1089 pAdapter->PortCfg.LedCntl.fRxActivity = TRUE; // for RX ACTIVITY LED
1091 // For miniportTransferData
1092 pAdapter->pRxData = pData;
1094 // Acknolwdge upper layer the received frame
1095 #ifdef RTMP_EMBEDDED
1096 if ((skb = __dev_alloc_skb(PacketSize + LENGTH_802_3 + 2, GFP_DMA|GFP_ATOMIC)) != NULL)
1097 #else
1098 if ((skb = dev_alloc_skb(PacketSize + LENGTH_802_3 + 2)) != NULL)
1099 #endif
1101 skb->dev = pAdapter->net_dev;
1102 skb_reserve(skb, 2); // 16 byte align the IP header
1103 memcpy(skb_put(skb, LENGTH_802_3), Header802_3, LENGTH_802_3);
1104 memcpy(skb_put(skb, PacketSize), pData, PacketSize);
1105 skb->protocol = eth_type_trans(skb, pAdapter->net_dev);
1106 netif_rx(skb);
1107 pAdapter->net_dev->last_rx = jiffies;
1108 pAdapter->stats.rx_packets++;
1111 DBGPRINT(RT_DEBUG_INFO, "!!! Broadcast Ethenet rx Indicated !!!\n");
1114 // Begin process unicast to me frame
1115 else if (pRxD->U2M)
1117 // Update Rx data rate first.
1118 if (pRxD->Ofdm == 1)
1120 for (i = 4; i < 12; i++)
1122 if (pRxD->BBR0 == PlcpSignal[i])
1123 break;
1125 if (i < 12)
1126 pAdapter->LastRxRate = i;
1128 else // receive CCK encoding
1130 if (pRxD->BBR0 == 10)
1131 pAdapter->LastRxRate = 0;
1132 else if (pRxD->BBR0 == 20)
1133 pAdapter->LastRxRate = 1;
1134 else if (pRxD->BBR0 == 55)
1135 pAdapter->LastRxRate = 2;
1136 else if (pRxD->BBR0 == 110)
1137 pAdapter->LastRxRate = 3;
1140 if (pHeader->Frag == 0) // First or Only fragment
1142 // For TKIP frame, calculate the MIC value
1143 if ((pHeader->Controlhead.Frame.MoreFrag == FALSE) &&
1144 (pRxD->CipherAlg == CIPHER_TKIP) &&
1145 (pHeader->Controlhead.Frame.Wep))
1147 if (pWpaKey == NULL)
1149 DBGPRINT(RT_DEBUG_ERROR,"No matched TKIP in decryption done calculate MIC routine!!!\n");
1150 Status = NDIS_STATUS_FAILURE;
1151 break;
1153 // Minus MIC length
1154 PacketSize -= 8;
1155 if (RTMPTkipCompareMICValue(
1156 pAdapter,
1157 pData,
1158 pDestMac,
1159 pSrcMac,
1160 pWpaKey->RxMic,
1161 PacketSize) == FALSE)
1163 DBGPRINT(RT_DEBUG_ERROR,"Rx MIC Value error\n");
1164 RTMPReportMicError(pAdapter, pWpaKey);
1165 Status = NDIS_STATUS_FAILURE;
1166 break;
1170 pAdapter->FragFrame.Flags &= 0xFFFFFFFE;
1172 // Check for encapsulation other than RFC1042 & Bridge tunnel
1173 if ((!RTMPEqualMemory(SNAP_802_1H, pData, 6)) &&
1174 (!RTMPEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6)))
1176 LLC_Len[0] = PacketSize / 256;
1177 LLC_Len[1] = PacketSize % 256;
1178 MAKE_802_3_HEADER(Header802_3, pDestMac, pSrcMac, ((PUCHAR) LLC_Len));
1180 else
1182 char *pProto = pData + 6;
1184 // Remove 802.11 H header & reconstruct 802.3 header
1185 // pData += (LENGTH_802_1_H - LENGTH_802_3_TYPE);
1186 // Check for EAPOL frame when driver supplicant enabled
1187 // TODO: It is not strickly correct. There is no fragment handling. It might damage driver
1188 // TODO: But for WPAPSK, it's not likely fragment on EAPOL frame will happen
1189 if (RTMPEqualMemory(EAPOL, pProto, 2) && ((pAdapter->PortCfg.WpaState != SS_NOTUSE)))
1191 RTMP_IO_READ32(pAdapter, CSR17, &High32TSF); // TSF value
1192 RTMP_IO_READ32(pAdapter, CSR16, &Low32TSF); // TSF vlaue
1193 PacketSize += LENGTH_802_11;
1194 DBGPRINT(RT_DEBUG_TRACE, "PktSz=%d, tm=%ul\n", PacketSize, Low32TSF);
1195 // Enqueue this frame to MLME engine
1196 MlmeEnqueueForRecv(
1197 pAdapter,
1198 &pAdapter->Mlme.Queue,
1199 High32TSF,
1200 Low32TSF,
1201 (UCHAR)pRxD->BBR1,
1202 PacketSize,
1203 pManage);
1204 break;
1207 if ((RTMPEqualMemory(IPX, pProto, 2) || RTMPEqualMemory(APPLE_TALK, pProto, 2)) &&
1208 RTMPEqualMemory(SNAP_802_1H, pData, 6))
1210 // preserved the LLC/SNAP filed
1211 LLC_Len[0] = PacketSize / 256;
1212 LLC_Len[1] = PacketSize % 256;
1213 MAKE_802_3_HEADER(Header802_3, pDestMac, pSrcMac, ((PUCHAR) LLC_Len));
1215 else
1217 // remove the LLC/SNAP field
1218 MAKE_802_3_HEADER(Header802_3, pDestMac, pSrcMac, pProto);
1219 NdisMoveMemory(pAdapter->FragFrame.Header_LLC, pData, 8);
1220 PacketSize -= LENGTH_802_1_H;
1221 pData += LENGTH_802_1_H;
1222 pAdapter->FragFrame.Flags |= 0x01;
1226 // One & The only fragment
1227 if (pHeader->Controlhead.Frame.MoreFrag == FALSE)
1229 // For miniportTransferData
1230 pAdapter->pRxData = pData;
1232 pAdapter->PortCfg.LedCntl.fRxActivity = TRUE; // for RX ACTIVITY LED
1234 // Acknowledge upper layer the received frame
1235 #ifdef RTMP_EMBEDDED
1236 if ((skb = __dev_alloc_skb(PacketSize + LENGTH_802_3 + 2, GFP_DMA|GFP_ATOMIC)) != NULL)
1237 #else
1238 if ((skb = dev_alloc_skb(PacketSize + LENGTH_802_3 + 2)) != NULL)
1239 #endif
1241 skb->dev = pAdapter->net_dev;
1242 skb_reserve(skb, 2); // 16 byte align the IP header
1243 memcpy(skb_put(skb, LENGTH_802_3), Header802_3, LENGTH_802_3);
1244 memcpy(skb_put(skb, PacketSize), pData, PacketSize);
1245 skb->protocol = eth_type_trans(skb, pAdapter->net_dev);
1246 netif_rx(skb);
1247 pAdapter->net_dev->last_rx = jiffies;
1248 pAdapter->stats.rx_packets++;
1251 // NdisZeroMemory(Header802_3, LENGTH_802_3);
1252 DBGPRINT(RT_DEBUG_INFO, "!!! Frame without Fragment Indicated !!!\n");
1254 // Increase general counters
1255 pAdapter->Counters.GoodReceives++;
1258 // First fragment of fragmented frames
1259 else
1261 NdisMoveMemory(pAdapter->FragFrame.Buffer, pData, PacketSize);
1262 NdisMoveMemory(pAdapter->FragFrame.Header802_3, Header802_3, LENGTH_802_3);
1263 //NdisZeroMemory(Header802_3, LENGTH_802_3);
1264 pAdapter->FragFrame.RxSize = PacketSize;
1265 pAdapter->FragFrame.Sequence = pHeader->Sequence;
1266 pAdapter->FragFrame.LastFrag = pHeader->Frag; // Should be 0
1269 // Middle & End of fragment burst fragments
1270 else
1272 // No LLC-SNAP header in except the first fragment frame
1274 if ((pHeader->Sequence != pAdapter->FragFrame.Sequence) ||
1275 (pHeader->Frag != (pAdapter->FragFrame.LastFrag + 1)))
1277 // Fragment is not the same sequence or out of fragment number order
1278 // Clear Fragment frame contents
1279 NdisZeroMemory(&pAdapter->FragFrame, sizeof(FRAGMENT_FRAME));
1280 Status = NDIS_STATUS_FAILURE;
1281 break;
1283 else if ((pAdapter->FragFrame.RxSize + PacketSize) > MAX_FRAME_SIZE)
1285 // Fragment frame is too large, it exeeds the maximum frame size.
1286 // We have to drop it.
1287 // Clear Fragment frame contents
1288 NdisZeroMemory(&pAdapter->FragFrame, sizeof(FRAGMENT_FRAME));
1289 Status = NDIS_STATUS_FAILURE;
1290 break;
1293 // concatenate this fragment into the re-assembly buffer
1294 NdisMoveMemory(&pAdapter->FragFrame.Buffer[pAdapter->FragFrame.RxSize], pData, PacketSize);
1295 pAdapter->FragFrame.RxSize += PacketSize;
1296 pAdapter->FragFrame.LastFrag = pHeader->Frag; // Update fragment number
1298 // Last fragment
1299 if (pHeader->Controlhead.Frame.MoreFrag == FALSE)
1301 // For TKIP frame, calculate the MIC value
1302 if ((pRxD->CipherAlg == CIPHER_TKIP) && (pHeader->Controlhead.Frame.Wep))
1304 if (pWpaKey == NULL)
1306 DBGPRINT(RT_DEBUG_ERROR,"No matched TKIP in decryption done calculate MIC routine!!!\n");
1307 Status = NDIS_STATUS_FAILURE;
1308 break;
1310 // Minus MIC length
1311 pAdapter->FragFrame.RxSize -= 8;
1313 if (pAdapter->FragFrame.Flags & 0x00000001)
1315 // originally there's an LLC/SNAP field in the first fragment
1316 // but been removed in re-assembly buffer. here we have to include
1317 // this LLC/SNAP field upon calculating TKIP MIC
1318 pData = pAdapter->FragFrame.Header_LLC;
1319 PacketSize = (USHORT)pAdapter->FragFrame.RxSize + 8;
1321 else
1323 pData = pAdapter->FragFrame.Buffer;
1324 PacketSize = (USHORT)pAdapter->FragFrame.RxSize;
1327 if (RTMPTkipCompareMICValue(
1328 pAdapter,
1329 pData,
1330 pDestMac,
1331 pSrcMac,
1332 pWpaKey->RxMic,
1333 PacketSize) == FALSE)
1335 DBGPRINT(RT_DEBUG_ERROR,"Rx MIC Value error 2\n");
1336 RTMPReportMicError(pAdapter, pWpaKey);
1337 Status = NDIS_STATUS_FAILURE;
1338 break;
1341 // TODO:
1342 // Getting RxTSC from Rx descriptor
1345 // for RX ACTIVITY LED
1346 pAdapter->PortCfg.LedCntl.fRxActivity = TRUE;
1348 // For miniportTransferData
1349 pAdapter->pRxData = pAdapter->FragFrame.Buffer;
1351 // Acknowledge upper layer the received frame
1352 #ifdef RTMP_EMBEDDED
1353 if ((skb = __dev_alloc_skb(PacketSize + LENGTH_802_3 + 2, GFP_DMA|GFP_ATOMIC)) != NULL)
1354 #else
1355 if ((skb = dev_alloc_skb(PacketSize + LENGTH_802_3 + 2)) != NULL)
1356 #endif
1358 skb->dev = pAdapter->net_dev;
1359 skb_reserve(skb, 2); /* 16 byte align the IP header */
1360 memcpy(skb_put(skb, LENGTH_802_3), Header802_3, LENGTH_802_3);
1361 memcpy(skb_put(skb, PacketSize), pData, PacketSize);
1362 skb->protocol = eth_type_trans(skb, pAdapter->net_dev);
1363 netif_rx(skb);
1364 pAdapter->net_dev->last_rx = jiffies;
1365 pAdapter->stats.rx_packets++;
1368 // Increase general counters
1369 pAdapter->Counters.GoodReceives++;
1371 // Clear Fragment frame contents
1372 NdisZeroMemory(&pAdapter->FragFrame, sizeof(FRAGMENT_FRAME));
1373 DBGPRINT(RT_DEBUG_INFO, "!!! Frame with Fragment Indicated !!!\n");
1377 break;
1379 case BTYPE_MGMT:
1380 // Read required regsiter for MLME engine
1381 RTMP_IO_READ32(pAdapter, CSR17, &High32TSF); // TSF value
1382 RTMP_IO_READ32(pAdapter, CSR16, &Low32TSF); // TSF vlaue
1384 // Enqueue this frame to MLME engine
1385 MlmeEnqueueForRecv(
1386 pAdapter,
1387 &pAdapter->Mlme.Queue,
1388 High32TSF,
1389 Low32TSF,
1390 (UCHAR)pRxD->BBR1,
1391 pRxD->DataByteCnt,
1392 pManage);
1393 break;
1395 case BTYPE_CNTL:
1396 // Ignore ???
1397 break;
1399 default :
1400 break;
1404 pAdapter->CurDecryptIndex++;
1405 if (pAdapter->CurDecryptIndex >= RX_RING_SIZE)
1407 pAdapter->CurDecryptIndex = 0;
1409 Count++;
1411 pAdapter->RalinkCounters.DecryptCount ++;
1413 // Clear Cipherowner bit & Rx Owner bit for all drop & non-drop frames
1414 pRxD->CipherOwner = DESC_OWN_HOST;
1415 pRxD->Owner = DESC_OWN_NIC;
1416 #ifdef BIG_ENDIAN
1417 RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
1418 *pDestRxD = RxD;
1419 #endif
1420 #if 0 // mask by Victor Yu. 05-18-2006
1422 //} while (Count < RX_RING_SIZE);
1423 //} while (pAdapter->CurDecryptIndex != HwDecryptIndex);
1424 #else // add by Victor Yu. 05-18-2006
1425 } while ( Count < (2*RX_RING_SIZE) );
1426 #endif
1428 #ifdef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
1429 spin_unlock(&pAdapter->RxRingLock);
1430 #else
1431 // Make sure to release Rx ring resource
1432 NdisReleaseSpinLock(&pAdapter->RxRingLock);
1433 #endif
1437 ========================================================================
1439 Routine Description:
1440 Process Tx ring EncryptionDone interrupt, running in DPC level
1442 Arguments:
1443 Adapter Pointer to our adapter
1445 Return Value:
1446 None
1448 Note:
1450 ========================================================================
1452 VOID RTMPHandleEncryptionDoneInterrupt(
1453 IN PRTMP_ADAPTER pAdapter)
1455 PTXD_STRUC pTxD;
1456 #ifdef BIG_ENDIAN
1457 PTXD_STRUC pDestTxD;
1458 TXD_STRUC TxD;
1459 #endif
1460 UCHAR Count;
1461 ULONG RegValue;
1462 ULONG HwEncryptIndex;
1463 #ifndef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
1464 unsigned long IrqFlags;
1465 #endif
1467 #ifdef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
1468 spin_lock(&pAdapter->TxRingLock);
1469 #else
1470 // Make sure Prio ring resource won't be used by other threads
1471 NdisAcquireSpinLock(&pAdapter->TxRingLock);
1472 #endif
1474 RTMP_IO_READ32(pAdapter, SECCSR1, &RegValue);
1475 HwEncryptIndex = (RegValue - pAdapter->TxRing[0].pa_addr) / RING_DESCRIPTOR_SIZE;
1477 Count = 0;
1478 #if 0 // mask by Victor Yu. 05-18-2006
1479 //do
1480 while (pAdapter->NextEncryptDoneIndex != HwEncryptIndex)
1482 #else // add by Victor Yu. 05-18-2006
1483 do {
1484 if ( pAdapter->NextEncryptDoneIndex == HwEncryptIndex )
1485 break;
1486 #endif
1487 #ifndef BIG_ENDIAN
1488 pTxD = (PTXD_STRUC) (pAdapter->TxRing[pAdapter->NextEncryptDoneIndex].va_addr);
1489 #else
1490 pDestTxD = (PTXD_STRUC) (pAdapter->TxRing[pAdapter->NextEncryptDoneIndex].va_addr);
1491 TxD = *pDestTxD;
1492 pTxD = &TxD;
1493 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1494 #endif
1496 // Check for the descriptor cipher ownership
1497 if ((pTxD->CipherOwn == DESC_OWN_NIC) || (pTxD->Owner == DESC_OWN_NIC))
1499 pAdapter->RalinkCounters.TxRingErrCount++;
1500 #ifdef BIG_ENDIAN
1501 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1502 *pDestTxD = TxD;
1503 #endif
1504 break;
1507 // Alter EIV due to ASIC's bug
1508 if (pTxD->CipherAlg == CIPHER_TKIP)
1510 UCHAR Eiv_Tmp[4];
1511 PUCHAR pTmp;
1513 NdisMoveMemory(Eiv_Tmp, &pTxD->Eiv, 4);
1514 pTmp = (PUCHAR) &pTxD->Eiv;
1515 *pTmp = Eiv_Tmp[3];
1516 *(pTmp + 1) = Eiv_Tmp[2];
1517 *(pTmp + 2) = Eiv_Tmp[1];
1518 *(pTmp + 3) = Eiv_Tmp[0];
1520 // Sanity Check, CurTxIndex should equal to NextEncryptDoneIndex
1521 // ASSERT(pAdapter->CurTxIndex == pAdapter->NextEncryptDoneIndex);
1523 pTxD->Valid = TRUE;
1524 pTxD->Owner = DESC_OWN_NIC;
1526 #ifdef BIG_ENDIAN
1527 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1528 *pDestTxD = TxD;
1529 #endif
1531 pAdapter->NextEncryptDoneIndex++;
1532 if (pAdapter->NextEncryptDoneIndex >= TX_RING_SIZE)
1534 pAdapter->NextEncryptDoneIndex = 0;
1536 pAdapter->CurTxIndex = pAdapter->NextEncryptDoneIndex;
1537 pAdapter->RalinkCounters.KickTxCount++;
1539 if (pAdapter->CurTxIndex == pAdapter->CurEncryptIndex)
1540 break;
1541 #if 0 // mask by Victor Yu. 05-18-2006
1543 //} while (++Count < MAX_TX_PROCESS);
1544 //} while (pAdapter->NextEncryptDoneIndex != HwEncryptIndex);
1545 #else // add by Victor Yu. 05-18-2006
1546 } while (++Count < (2*MAX_TX_PROCESS) );
1547 #endif
1549 // Kick Tx Control Register at the end of all ring buffer preparation
1550 RTMP_IO_WRITE32(pAdapter, TXCSR0, 0x1);
1552 #ifdef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
1553 spin_unlock(&pAdapter->TxRingLock);
1554 #else
1555 // Make sure to release Tx ring resource
1556 NdisReleaseSpinLock(&pAdapter->TxRingLock);
1557 #endif
1561 ========================================================================
1563 Routine Description:
1564 Arguments:
1565 Adapter Pointer to our adapter
1566 ========================================================================
1568 void RTMPHandleTbcnInterrupt(IN PRTMP_ADAPTER pAdapter)
1570 if (ADHOC_ON(pAdapter))
1572 MACHDR *pBcnHdr = (MACHDR *)pAdapter->BeaconRing.va_data_addr;
1574 // update BEACON frame's sequence number
1575 pAdapter->Sequence = ((pAdapter->Sequence) + 1) & (MAX_SEQ_NUMBER);
1576 pBcnHdr->Seq = pAdapter->Sequence;
1578 #ifdef BIG_ENDIAN
1579 *(USHORT *)((UCHAR *)pBcnHdr + 22) = SWAP16(*(USHORT *)((UCHAR *)pBcnHdr + 22));
1580 #endif
1585 ========================================================================
1587 Routine Description:
1588 Arguments:
1589 Adapter Pointer to our adapter
1590 ========================================================================
1592 void RTMPHandleTwakeupInterrupt(IN PRTMP_ADAPTER pAdapter)
1594 // DBGPRINT(RT_DEBUG_ERROR, ("Twakeup Expired... !!!\n"));
1595 pAdapter->PortCfg.Pss = PWR_ACTIVE;
1599 ========================================================================
1601 Routine Description:
1602 Process all transmit ring Tx Done interrupt, running in DPC level
1604 Arguments:
1605 Adapter Pointer to our adapter
1607 Return Value:
1608 None
1610 Note:
1612 ========================================================================
1614 VOID RTMPHardTransmitDone(
1615 IN PRTMP_ADAPTER pAdapter,
1616 IN PTXD_STRUC pTxD,
1617 IN UCHAR FrameType)
1620 switch (pTxD->TxResult)
1622 case SUCCESS_WITHOUT_RETRY: // Success without any retry
1623 // Return send complete status
1624 // DBGPRINT(RT_DEBUG_INFO, "TX Success without retry<<<\n");
1625 if (pTxD->RTS)
1627 // Increase 802.11 counters
1628 INC_COUNTER(pAdapter->WlanCounters.RTSSuccessCount);
1629 pTxD->RTS = 0;
1632 // Increase general counters
1633 pAdapter->Counters.GoodTransmits++;
1634 INC_COUNTER(pAdapter->WlanCounters.TransmittedFragmentCount);
1636 // update DRS related counters
1637 if (pTxD->ACK && (FrameType == BTYPE_DATA))
1639 pAdapter->DrsCounters.OneSecTxOkCount ++;
1641 break;
1643 case SUCCESS_WITH_RETRY: // Success with some retry
1644 // DBGPRINT(RT_DEBUG_INFO, "TX Success with retry(=%d)<<<\n",pTxD->RetryCount);
1645 // Increase 802.11 counters
1646 INC_COUNTER(pAdapter->WlanCounters.RetryCount);
1647 INC_COUNTER(pAdapter->WlanCounters.ACKFailureCount);
1648 INC_COUNTER(pAdapter->WlanCounters.TransmittedFragmentCount);
1650 // Increase general counters
1651 pAdapter->Counters.GoodTransmits++;
1653 if (pTxD->RetryCount > 1)
1655 // Increase 802.11 counters
1656 INC_COUNTER(pAdapter->WlanCounters.MultipleRetryCount);
1658 // Increase general counters
1659 pAdapter->Counters.MoreCollisions++;
1661 else
1663 // Increase general counters
1664 pAdapter->Counters.OneCollision++;
1667 if (pTxD->RTS)
1669 INC_COUNTER(pAdapter->WlanCounters.RTSSuccessCount);
1670 pTxD->RTS = 0;
1673 // update DRS related counters
1674 if (pTxD->ACK && (FrameType == BTYPE_DATA))
1676 if (pTxD->TxRate > pAdapter->PortCfg.TxRate)
1678 // DRS - must be NULL frame retried @ UpRate; downgrade
1679 // TxQuality[UpRate] so that not upgrade TX rate
1680 pAdapter->DrsCounters.TxQuality[pTxD->TxRate] += 2;
1681 if (pAdapter->DrsCounters.TxQuality[pTxD->TxRate] > DRS_TX_QUALITY_WORST_BOUND)
1682 pAdapter->DrsCounters.TxQuality[pTxD->TxRate] = DRS_TX_QUALITY_WORST_BOUND;
1684 else if (pTxD->TxRate == pAdapter->PortCfg.TxRate)
1685 pAdapter->DrsCounters.OneSecTxRetryOkCount ++;
1687 break;
1689 case FAIL_RETRY_LIMIT: // Fail on hitting retry count limit
1690 // DBGPRINT(RT_DEBUG_WARN, ("TX Failed (RETRY LIMIT)<<<\n"));
1691 // Increase 802.11 counters
1692 INC_COUNTER(pAdapter->WlanCounters.FailedCount);
1693 INC_COUNTER(pAdapter->WlanCounters.ACKFailureCount);
1695 // Increase general counters
1696 pAdapter->Counters.TxErrors++;
1698 if (pTxD->RTS)
1700 INC_COUNTER(pAdapter->WlanCounters.RTSFailureCount);
1701 pTxD->RTS = 0;
1704 // update DRS related counters
1705 if (pTxD->ACK && (FrameType == BTYPE_DATA))
1707 if (pTxD->TxRate > pAdapter->PortCfg.TxRate)
1709 // DRS - must be NULL frame failed @ UpRate; downgrade
1710 // TxQuality[UpRate] so that not upgrade TX rate
1711 pAdapter->DrsCounters.TxQuality[pTxD->TxRate] = DRS_TX_QUALITY_WORST_BOUND;
1713 else if (pTxD->TxRate == pAdapter->PortCfg.TxRate)
1715 pAdapter->DrsCounters.OneSecTxFailCount ++;
1718 break;
1720 case FAIL_INVALID:
1721 // DBGPRINT(RT_DEBUG_WARN, ("TX Failed (INVALID)<<<\n"));
1722 // Increase general counters
1723 pAdapter->Counters.TxErrors++;
1725 if (pTxD->RTS)
1727 INC_COUNTER(pAdapter->WlanCounters.RTSFailureCount);
1728 pTxD->RTS = 0;
1730 break;
1732 case FAIL_OTHER:
1733 default:
1734 // DBGPRINT(RT_DEBUG_ERROR, ("TX Failed (other=%d)<<<\n",pTxD->TxResult));
1735 // Increase 802.11 counters
1736 INC_COUNTER(pAdapter->WlanCounters.FailedCount);
1737 INC_COUNTER(pAdapter->WlanCounters.ACKFailureCount);
1739 // Increase general counters
1740 pAdapter->Counters.TxErrors++;
1742 if (pTxD->RTS)
1744 INC_COUNTER(pAdapter->WlanCounters.RTSFailureCount);
1745 pTxD->RTS = 0;
1747 break;
1752 ========================================================================
1754 Routine Description:
1755 API for MLME to transmit management frame to AP (BSS Mode)
1756 or station (IBSS Mode)
1758 Arguments:
1759 pAdapter Pointer to our adapter
1760 Buffer Pointer to memory of outgoing frame
1761 Length Size of outgoing management frame
1763 Return Value:
1764 NDIS_STATUS_FAILURE
1765 NDIS_STATUS_PENDING
1766 NDIS_STATUS_SUCCESS
1768 Note:
1770 ========================================================================
1772 NDIS_STATUS MiniportMMRequest(
1773 IN PRTMP_ADAPTER pAdapter,
1774 IN PVOID pBuffer,
1775 IN ULONG Length)
1777 #if 0 // mask by Victor Yu. 05-18-2006
1778 PMGMT_STRUC pMgmt, pTest;
1779 #else // add by Victor Yu. 05-18-2006
1780 PMGMT_STRUC pMgmt;
1781 #endif
1782 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
1783 #if 0 // mask by Victor Yu. 05-18-2006
1784 int i;
1785 #endif
1787 DBGPRINT(RT_DEBUG_INFO, "---> MiniportMMRequest\n");
1788 // Check management ring free avaliability
1789 pMgmt = (PMGMT_STRUC) &pAdapter->MgmtRing[pAdapter->PushMgmtIndex];
1791 // This management cell has been occupied
1792 if (pMgmt->Valid == TRUE) {
1793 #if 0 // mask by Victor Yu. 05-18-2006
1794 for (i=0; i<MGMT_RING_SIZE; i++) {
1795 pTest = (PMGMT_STRUC) &pAdapter->MgmtRing[i];
1796 printk("%d: Valid=%d\n", i, pTest->Valid);
1798 printk("Push=%d\n", pAdapter->PushMgmtIndex);
1799 printk("Pop=%d\n", pAdapter->PopMgmtIndex);
1800 printk("Size=%d\n", pAdapter->MgmtQueueSize);
1801 #endif
1803 // No Management ring buffer avaliable
1804 MlmeFreeMemory(pAdapter, pBuffer);
1805 Status = NDIS_STATUS_FAILURE;
1806 DBGPRINT(RT_DEBUG_WARN, "<--- MiniportMMRequest (error:: MgmtRing full)\n");
1807 pAdapter->RalinkCounters.MgmtRingFullCount++;
1808 return (Status);
1811 // Insert this request into software managemnet ring
1812 if (pBuffer)
1814 pMgmt->pBuffer = pBuffer;
1815 pMgmt->Length = Length;
1816 pMgmt->Valid = TRUE;
1817 pAdapter->PushMgmtIndex++;
1818 pAdapter->MgmtQueueSize++;
1819 if (pAdapter->PushMgmtIndex >= MGMT_RING_SIZE)
1821 pAdapter->PushMgmtIndex = 0;
1823 //DBGPRINT(RT_DEBUG_TRACE, "Push2=%d, Pop2=%d, Size2=%d\n", pAdapter->PushMgmtIndex, pAdapter->PopMgmtIndex, pAdapter->MgmtQueueSize);
1825 else
1827 // Null pBuffer, no need to free memory buffer.
1828 // This should not happen
1829 DBGPRINT(RT_DEBUG_WARN, "<--- MiniportMMRequest (error:: NULL msg)\n");
1830 Status = NDIS_STATUS_FAILURE;
1831 return (Status);
1834 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF))
1835 return (Status);
1837 // Check Free priority queue
1838 if (RTMPFreeDescriptorRequest(pAdapter, PRIO_RING, 1) == NDIS_STATUS_SUCCESS)
1840 pMgmt = (PMGMT_STRUC) &pAdapter->MgmtRing[pAdapter->PopMgmtIndex];
1841 if (pMgmt->Valid == TRUE)
1843 MlmeHardTransmit(pAdapter, pMgmt->pBuffer, pMgmt->Length);
1844 MlmeFreeMemory(pAdapter, pMgmt->pBuffer);
1845 pMgmt->Valid = FALSE;
1846 pAdapter->PopMgmtIndex++;
1847 pAdapter->MgmtQueueSize--;
1848 if (pAdapter->PopMgmtIndex >= MGMT_RING_SIZE)
1850 pAdapter->PopMgmtIndex = 0;
1852 //DBGPRINT(RT_DEBUG_TRACE, "Push3=%d, Pop3=%d, Size3=%d\n", pAdapter->PushMgmtIndex, pAdapter->PopMgmtIndex, pAdapter->MgmtQueueSize);
1855 else
1857 DBGPRINT(RT_DEBUG_TRACE, "not enough space in PrioRing\n");
1860 DBGPRINT(RT_DEBUG_INFO, "<--- MiniportMMRequest\n");
1861 return (Status);
1865 ========================================================================
1867 Routine Description:
1868 Copy frame from waiting queue into relative ring buffer and set
1869 appropriate ASIC register to kick hardware transmit function
1871 Arguments:
1872 pAdapter Pointer to our adapter
1873 pBuffer Pointer to memory of outgoing frame
1874 Length Size of outgoing management frame
1876 Return Value:
1877 NDIS_STATUS_FAILURE
1878 NDIS_STATUS_PENDING
1879 NDIS_STATUS_SUCCESS
1881 Note:
1883 ========================================================================
1885 VOID MlmeHardTransmit(
1886 IN PRTMP_ADAPTER pAdapter,
1887 IN PVOID pBuffer,
1888 IN ULONG Length)
1890 PTXD_STRUC pTxD;
1891 #ifdef BIG_ENDIAN
1892 PTXD_STRUC pDestTxD;
1893 TXD_STRUC TxD;
1894 #endif
1895 PUCHAR pDest;
1896 PHEADER_802_11 pHeader_802_11;
1897 BOOLEAN AckRequired, InsertTimestamp;
1898 unsigned long IrqFlags;
1900 DBGPRINT(RT_DEBUG_INFO, "MlmeHardTransmit\n");
1902 // Make sure Prio ring resource won't be used by other threads
1903 NdisAcquireSpinLock(&pAdapter->PrioRingLock);
1905 pDest = (PUCHAR) pAdapter->PrioRing[pAdapter->CurPrioIndex].va_data_addr;
1906 #ifndef BIG_ENDIAN
1907 pTxD = (PTXD_STRUC) pAdapter->PrioRing[pAdapter->CurPrioIndex].va_addr;
1908 #else
1909 pDestTxD = (PTXD_STRUC) pAdapter->PrioRing[pAdapter->CurPrioIndex].va_addr;
1910 TxD = *pDestTxD;
1911 pTxD = &TxD;
1912 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1913 #endif
1915 if (pTxD->Owner == DESC_OWN_NIC)
1917 // Descriptor owned by NIC. No descriptor avaliable
1918 // This should not happen since caller guaranteed.
1919 // Make sure to release Prio ring resource
1920 NdisReleaseSpinLock(&pAdapter->PrioRingLock);
1921 return;
1923 if (pTxD->Valid == TRUE)
1925 // Ndis packet of last round did not cleared.
1926 // This should not happen since caller guaranteed.
1927 // Make sure to release Prio ring resource
1928 NdisReleaseSpinLock(&pAdapter->PrioRingLock);
1929 return;
1931 if (pBuffer == NULL)
1933 // The buffer shouldn't be NULL
1934 NdisReleaseSpinLock(&pAdapter->PrioRingLock);
1935 return;
1938 // outgoing frame always wakeup PHY to prevent frame lost
1939 AsicForceWakeup(pAdapter);
1941 pHeader_802_11 = (PHEADER_802_11) pBuffer;
1942 pHeader_802_11->Controlhead.Frame.PwrMgt = 0; // (pAdapter->PortCfg.Psm == PWR_SAVE);
1943 InsertTimestamp = FALSE;
1944 if (pHeader_802_11->Controlhead.Frame.Type == BTYPE_CNTL) // must be PS-POLL
1946 AckRequired = FALSE;
1947 pAdapter->PrioRing[pAdapter->CurPrioIndex].FrameType = BTYPE_CNTL;
1949 else // BTYPE_MGMT or BMGMT_DATA(must be NULL frame)
1951 pAdapter->PrioRing[pAdapter->CurPrioIndex].FrameType = BTYPE_MGMT;
1952 pAdapter->Sequence = ((pAdapter->Sequence) + 1) & (MAX_SEQ_NUMBER);
1953 pHeader_802_11->Sequence = pAdapter->Sequence;
1955 if (pHeader_802_11->Controlhead.Addr1.Octet[0] & 0x01) // MULTICAST, BROADCAST
1957 AckRequired = FALSE;
1958 pHeader_802_11->Controlhead.Duration = 0;
1960 else
1962 AckRequired = TRUE;
1963 pHeader_802_11->Controlhead.Duration = RTMPCalcDuration(pAdapter, pAdapter->PortCfg.MlmeRate, 14);
1964 if (pHeader_802_11->Controlhead.Frame.Subtype == SUBTYPE_PROBE_RSP)
1966 InsertTimestamp = TRUE;
1970 #ifdef BIG_ENDIAN
1971 RTMPFrameEndianChange(pAdapter, (PUCHAR)pBuffer, DIR_WRITE, FALSE);
1972 #endif
1973 NdisMoveMemory(pDest, pBuffer, Length);
1975 // Initialize Priority Descriptor
1976 // For inter-frame gap, the number is for this frame and next frame
1977 // For MLME rate, we will fix as 2Mb to match other vendor's implement
1978 #ifdef BIG_ENDIAN
1979 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1980 *pDestTxD = TxD;
1981 pTxD = pDestTxD;
1982 #endif
1983 RTMPWriteTxDescriptor(pTxD, FALSE, CIPHER_NONE, AckRequired, FALSE, InsertTimestamp,
1984 SHORT_RETRY, IFS_BACKOFF, pAdapter->PortCfg.MlmeRate, 4, Length, pAdapter->PortCfg.TxPreambleInUsed, 0);
1986 // Increase & maintain Tx Ring Index
1987 pAdapter->CurPrioIndex++;
1988 if (pAdapter->CurPrioIndex >= PRIO_RING_SIZE)
1990 pAdapter->CurPrioIndex = 0;
1993 // Kick priority ring transmit
1994 RTMP_IO_WRITE32(pAdapter,TXCSR0,0x4);
1996 // Make sure to release Prio ring resource
1997 NdisReleaseSpinLock(&pAdapter->PrioRingLock);
2000 ========================================================================
2002 Routine Description:
2003 This routine is used to en-queue outgoing packets when
2004 there is no enough shread memory
2006 Arguments:
2007 pAdapter Pointer to our adapter
2008 pPacket Pointer to send packet
2010 Return Value:
2011 None
2013 Note:
2015 ========================================================================
2017 NDIS_STATUS RTMPSendPacket(
2018 IN PRTMP_ADAPTER pAdapter,
2019 IN struct sk_buff *skb)
2021 PVOID pVirtualAddress;
2022 UINT AllowFragSize;
2023 UCHAR NumberOfFrag;
2024 UCHAR RTSRequired;
2025 NDIS_STATUS Status = NDIS_STATUS_FAILURE;
2026 UCHAR PsMode;
2028 PQUEUE_HEADER pTxQueue = NULL;
2029 ULONG Priority;
2030 UCHAR AccessCategory;
2031 unsigned long IrqFlags;
2033 DBGPRINT(RT_DEBUG_INFO, "<==== RTMPSendPacket\n");
2035 // Init priority value
2036 Priority = 0;
2037 AccessCategory = 0;
2039 if (skb)
2041 Priority = skb->priority;
2042 // 802.11e/d4.4 June, 2003
2043 if (Priority <=2)
2044 AccessCategory = 0;
2045 else if (Priority == 3)
2046 AccessCategory = 1;
2047 else if (Priority <= 5)
2048 AccessCategory = 2;
2049 else
2050 AccessCategory = 3;
2051 DBGPRINT(RT_DEBUG_INFO, "Priority = %d, AC = %d\n", Priority, AccessCategory);
2054 // For TKIP, MIC value is treated as payload, it might be fragmented through
2055 // different MPDUs.
2056 if (pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled)
2058 skb->data_len += 8;
2061 pVirtualAddress = (PVOID)skb->data;
2063 // Check for virtual address allocation, it might fail !!!
2064 if (pVirtualAddress == NULL)
2066 // Resourece is low, system did not allocation virtual address
2067 // return NDIS_STATUS_FAILURE directly to upper layer
2068 return (Status);
2072 // Check for multicast or broadcast (First byte of DA)
2074 if ((*((PUCHAR) pVirtualAddress) & 0x01) != 0)
2076 // For multicast & broadcast, there is no fragment allowed
2077 NumberOfFrag = 1;
2079 else
2081 // Check for payload allowed for each fragment
2082 AllowFragSize = (pAdapter->PortCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;
2084 // Calculate fragments required
2085 NumberOfFrag = ((skb->data_len - LENGTH_802_3 + LENGTH_802_1_H) / AllowFragSize) + 1;
2086 // Minus 1 if the size just match to allowable fragment size
2087 if (((skb->data_len - LENGTH_802_3 + LENGTH_802_1_H) % AllowFragSize) == 0)
2089 NumberOfFrag--;
2093 // Check for requirement of RTS
2094 if (NumberOfFrag > 1)
2096 // If multiple fragment required, RTS is required only for the first fragment
2097 // if the fragment size large than RTS threshold
2098 RTSRequired = (pAdapter->PortCfg.FragmentThreshold > pAdapter->PortCfg.RtsThreshold) ? 1 : 0;
2100 else
2102 RTSRequired = (skb->data_len > pAdapter->PortCfg.RtsThreshold) ? 1 : 0;
2104 DBGPRINT(RT_DEBUG_INFO, "Number of fragments include RTS :%d\n", NumberOfFrag + RTSRequired);
2106 // RTS/CTS may also be required in order to protect OFDM frame
2107 if ((pAdapter->PortCfg.TxRate >= RATE_FIRST_OFDM_RATE) && pAdapter->PortCfg.BGProtectionInUsed)
2108 RTSRequired = 1;
2110 // Save framnet number to Ndis packet reserved field
2111 RTMP_SET_PACKET_FRAGMENTS(skb, NumberOfFrag);
2113 // Save RTS requirement to Ndis packet reserved field
2114 RTMP_SET_PACKET_RTS(skb, RTSRequired);
2116 // Make sure SendTxWait queue resource won't be used by other threads
2117 NdisAcquireSpinLock(&pAdapter->TxSwQueueLock);
2119 // Select the right priority queue
2120 // There should be no else statement since it should always fall within 0-3
2121 if (AccessCategory== 0)
2122 pTxQueue = &pAdapter->TxSwQueue0;
2123 else if (AccessCategory== 1)
2124 pTxQueue = &pAdapter->TxSwQueue1;
2125 else if (AccessCategory== 2)
2126 pTxQueue = &pAdapter->TxSwQueue2;
2127 else if (AccessCategory== 3)
2128 pTxQueue = &pAdapter->TxSwQueue3;
2131 // For infrastructure mode, enqueue this frame immediately to sendwaitqueue
2132 // For Ad-hoc mode, check the DA power state, then decide which queue to enqueue
2134 if (INFRA_ON(pAdapter))
2136 if(pTxQueue->Number > MAX_PACKETS_IN_QUEUE)
2138 DBGPRINT(RT_DEBUG_WARN, "pTxQueue is full!!!\n\n");
2139 pAdapter->bNetDeviceStopQueue = TRUE;
2140 netif_stop_queue(pAdapter->net_dev);
2143 // In infrastructure mode, simply enqueue the packet into Tx waiting queue.
2144 DBGPRINT(RT_DEBUG_INFO, "Infrastructure -> Enqueue one frame\n");
2146 // Enqueue Ndis packet to end of Tx wait queue
2147 InsertTailQueue(pTxQueue, skb);
2148 Status = NDIS_STATUS_SUCCESS;
2150 else
2152 if(pTxQueue->Number > MAX_PACKETS_IN_QUEUE)
2154 DBGPRINT(RT_DEBUG_WARN, "pTxQueue is full!!!\n\n");
2155 pAdapter->bNetDeviceStopQueue = TRUE;
2156 netif_stop_queue(pAdapter->net_dev);
2159 // In IBSS mode, power state of destination should be considered.
2160 PsMode = PWR_ACTIVE; // Faked
2161 if (PsMode == PWR_ACTIVE)
2163 DBGPRINT(RT_DEBUG_INFO,"Ad-Hoc -> Enqueue one frame\n");
2165 // Enqueue Ndis packet to end of Tx wait queue
2166 InsertTailQueue(pTxQueue, skb);
2167 Status = NDIS_STATUS_SUCCESS;
2171 NdisReleaseSpinLock(&pAdapter->TxSwQueueLock);
2172 return (Status);
2176 ========================================================================
2178 Routine Description:
2179 To do the enqueue operation and extract the first item of waiting
2180 list. If a number of available shared memory segments could meet
2181 the request of extracted item, the extracted item will be fragmented
2182 into shared memory segments.
2184 Arguments:
2185 pAdapter Pointer to our adapter
2186 pQueue Pointer to Waiting Queue
2188 Return Value:
2189 None
2191 Note:
2193 ========================================================================
2195 VOID RTMPDeQueuePacket(
2196 IN PRTMP_ADAPTER pAdapter)
2198 UCHAR FragmentRequired;
2199 NDIS_STATUS Status;
2200 UCHAR Count = 0;
2201 PQUEUE_HEADER pQueue;
2202 ULONG Number;
2203 UCHAR AccessCategory;
2204 struct sk_buff *skb;
2205 unsigned long IrqFlags;
2207 // Make sure SendTxWait queue resource won't be used by other threads
2208 NdisAcquireSpinLock(&pAdapter->TxSwQueueLock);
2210 while (((pQueue = RTMPCheckTxSwQueue(pAdapter, &Number, &AccessCategory)) != NULL) && (Count < MAX_TX_PROCESS))
2211 // Check queue before dequeue
2212 // while ((pQueue->Head != NULL) && (Count < MAX_TX_PROCESS))
2214 // Reset is in progress, stop immediately
2215 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS))
2217 break;
2220 // Dequeue the first entry from head of queue list
2221 skb = (struct sk_buff *)RemoveHeadQueue(pQueue);
2223 // RTS or CTS-to-self for B/G protection mode has been set already.
2224 // There is no need to re-do it here.
2225 // Total fragment required = number of fragment + RST if required
2226 FragmentRequired = RTMP_GET_PACKET_FRAGMENTS(skb) + RTMP_GET_PACKET_RTS(skb);
2228 if (RTMPFreeDescriptorRequest(pAdapter, TX_RING, FragmentRequired) == NDIS_STATUS_SUCCESS)
2230 // Avaliable ring descriptors are enough for this frame
2231 // Call hard transmit
2232 // Nitro mode / Normal mode selection
2233 if ((pAdapter->PortCfg.EnableTxBurst == 1) && (Number > 1))
2234 Status = RTMPHardEncrypt(pAdapter, skb, FragmentRequired, TRUE, AccessCategory);
2235 else
2236 Status = RTMPHardEncrypt(pAdapter, skb, FragmentRequired, FALSE, AccessCategory);
2237 if (Status == NDIS_STATUS_FAILURE)
2239 // Packet failed due to various Ndis Packet error
2240 RTMPFreeSkbBuffer(skb);
2241 break;
2243 else if (Status == NDIS_STATUS_RESOURCES)
2245 // Not enough free tx ring, it might happen due to free descriptor inquery might be not correct
2246 // It also might change to NDIS_STATUS_FAILURE to simply drop the frame
2247 // Put the frame back into head of queue
2248 InsertHeadQueue(pQueue, skb);
2249 break;
2251 Count++;
2253 else
2255 InsertHeadQueue(pQueue, skb);
2256 pAdapter->PrivateInfo.TxRingFullCnt++;
2257 DBGPRINT(RT_DEBUG_INFO,"RTMPDequeuePacket --> Not enough free Tx Ring descriptor (CurEncryptIndex=%d,CurTxIndex=%d, NextTxDoneIndex=%d)!!!\n",
2258 pAdapter->CurEncryptIndex, pAdapter->CurTxIndex, pAdapter->NextTxDoneIndex);
2259 break;
2263 // Release TxSwQueue0 resources
2264 NdisReleaseSpinLock(&pAdapter->TxSwQueueLock);
2268 ========================================================================
2270 Routine Description:
2271 This subroutine will scan through releative ring descriptor to find
2272 out avaliable free ring descriptor and compare with request size.
2274 Arguments:
2275 pAdapter Pointer to our adapter
2276 RingType Selected Ring
2278 Return Value:
2279 NDIS_STATUS_FAILURE Not enough free descriptor
2280 NDIS_STATUS_SUCCESS Enough free descriptor
2282 Note:
2284 ========================================================================
2286 NDIS_STATUS RTMPFreeDescriptorRequest(
2287 IN PRTMP_ADAPTER pAdapter,
2288 IN UCHAR RingType,
2289 IN UCHAR NumberRequired)
2291 UCHAR FreeNumber = 0;
2292 UINT Index;
2293 PTXD_STRUC pTxD;
2294 #ifdef BIG_ENDIAN
2295 PTXD_STRUC pDestTxD;
2296 TXD_STRUC TxD;
2297 #endif
2298 NDIS_STATUS Status = NDIS_STATUS_FAILURE;
2299 unsigned long IrqFlags;
2301 switch (RingType)
2303 case TX_RING:
2304 NdisAcquireSpinLock(&pAdapter->TxRingLock);
2305 Index = pAdapter->CurEncryptIndex;
2308 #ifndef BIG_ENDIAN
2309 pTxD = (PTXD_STRUC) pAdapter->TxRing[Index].va_addr;
2310 #else
2311 pDestTxD = (PTXD_STRUC) pAdapter->TxRing[Index].va_addr;
2312 TxD = *pDestTxD;
2313 pTxD = &TxD;
2314 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2315 #endif
2317 // While Owner bit is NIC, obviously ASIC still need it.
2318 // If valid bit is TRUE, indicate that TxDone has not process yet
2319 // We should not use it until TxDone finish cleanup job
2320 if ((pTxD->Owner == DESC_OWN_HOST) && (pTxD->CipherOwn == DESC_OWN_HOST) && (pTxD->Valid == FALSE))
2322 // This one is free
2323 FreeNumber++;
2325 else
2327 DBGPRINT(RT_DEBUG_INFO,"RTMPFreeDescriptorRequest fail - Owner=%d,CipherOwn=%d,Valid=%d\n",pTxD->Owner, pTxD->CipherOwn, pTxD->Valid);
2328 break;
2331 Index++;
2332 if (Index >= TX_RING_SIZE) // Wrap around issue
2334 Index = 0;
2337 } while (FreeNumber < NumberRequired); // Quit here ! Free number is enough !
2339 if (FreeNumber >= NumberRequired)
2341 Status = NDIS_STATUS_SUCCESS;
2344 // Make sure to release Tx ring resource
2345 NdisReleaseSpinLock(&pAdapter->TxRingLock);
2346 break;
2348 case PRIO_RING:
2349 NdisAcquireSpinLock(&pAdapter->PrioRingLock);
2350 Index = pAdapter->CurPrioIndex;
2353 #ifndef BIG_ENDIAN
2354 pTxD = (PTXD_STRUC) pAdapter->PrioRing[Index].va_addr;
2355 #else
2356 pDestTxD = (PTXD_STRUC) pAdapter->PrioRing[Index].va_addr;
2357 TxD = *pDestTxD;
2358 pTxD = &TxD;
2359 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2360 #endif
2362 // While Owner bit is NIC, obviously ASIC still need it.
2363 // If valid bit is TRUE, indicate that TxDone has not process yet
2364 // We should not use it until TxDone finish cleanup job
2365 if ((pTxD->Owner == DESC_OWN_HOST) && (pTxD->Valid == FALSE))
2367 // This one is free
2368 FreeNumber++;
2370 else
2372 break;
2375 Index++;
2376 if (Index >= PRIO_RING_SIZE) // Wrap around issue
2378 Index = 0;
2381 } while (FreeNumber < NumberRequired); // Quit here ! Free number is enough !
2383 if (FreeNumber >= NumberRequired)
2385 Status = NDIS_STATUS_SUCCESS;
2388 // Make sure to release Prio ring resource
2389 NdisReleaseSpinLock(&pAdapter->PrioRingLock);
2390 break;
2392 default:
2393 break;
2396 return (Status);
2399 VOID RTMPSendNullFrame(
2400 IN PRTMP_ADAPTER pAdapter,
2401 IN PVOID pBuffer,
2402 IN ULONG Length,
2403 IN UCHAR TxRate)
2405 PUCHAR pDest;
2406 PTXD_STRUC pTxD;
2407 UCHAR FrameGap;
2408 #ifdef BIG_ENDIAN
2409 PTXD_STRUC pDestTxD;
2410 TXD_STRUC TxD;
2411 #endif
2412 unsigned long IrqFlags;
2414 if (pBuffer == NULL)
2416 return;
2419 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS))
2421 MlmeFreeMemory(pAdapter, pBuffer);
2422 return;
2425 // WPA 802.1x secured port control
2426 if (((pAdapter->PortCfg.AuthMode == Ndis802_11AuthModeWPA) ||
2427 (pAdapter->PortCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) &&
2428 (pAdapter->PortCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
2430 MlmeFreeMemory(pAdapter, pBuffer);
2431 return;
2434 FrameGap = IFS_BACKOFF; // Default frame gap mode
2436 // outgoing frame always wakeup PHY to prevent frame lost and
2437 // turn off PSM bit to improve performance
2438 AsicForceWakeup(pAdapter);
2439 #if 0
2440 if ((pAdapter->TxSwQueue0.Number != 0) || (pAdapter->TxSwQueue1.Number != 0) ||
2441 (pAdapter->TxSwQueue2.Number != 0) || (pAdapter->TxSwQueue3.Number != 0))
2443 DBGPRINT(RT_DEBUG_TRACE,("Drop Null frame due to Tx queue not empty!\n"));
2445 else
2446 #endif
2448 // Make sure Tx ring resource won't be used by other threads
2449 NdisAcquireSpinLock(&pAdapter->TxRingLock);
2451 // Get the Tx Ring descriptor & Dma Buffer address
2452 pDest = (PUCHAR) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_data_addr;
2453 #ifndef BIG_ENDIAN
2454 pTxD = (PTXD_STRUC) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_addr;
2455 #else
2456 pDestTxD = (PTXD_STRUC) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_addr;
2457 TxD = *pDestTxD;
2458 pTxD = &TxD;
2459 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2460 #endif
2462 if ((pTxD->Owner == DESC_OWN_HOST) && (pTxD->CipherOwn == DESC_OWN_HOST) && (pTxD->Valid == FALSE))
2464 HEADER_802_11 *pHeader_802_11;
2466 DBGPRINT(RT_DEBUG_TRACE, "SYNC - send NULL Frame @%d Mbps...\n", RateIdToMbps[TxRate]);
2467 #ifdef BIG_ENDIAN
2468 RTMPFrameEndianChange(pAdapter, (PUCHAR)pBuffer, DIR_WRITE, FALSE);
2469 #endif
2470 NdisMoveMemory(pDest, pBuffer, Length);
2471 pAdapter->TxRing[pAdapter->CurEncryptIndex].FrameType = BTYPE_DATA;
2473 pHeader_802_11 = (PHEADER_802_11) pDest;
2474 pHeader_802_11->Controlhead.Frame.PwrMgt = (pAdapter->PortCfg.Psm == PWR_SAVE);
2476 #ifdef BIG_ENDIAN
2477 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2478 *pDestTxD = TxD;
2479 pTxD = pDestTxD;
2480 #endif
2482 RTMPWriteTxDescriptor(pTxD, TRUE, CIPHER_NONE, TRUE, FALSE, FALSE, LONG_RETRY, IFS_BACKOFF,
2483 TxRate, 4, Length, pAdapter->PortCfg.TxPreambleInUsed, 0);
2485 // Increase & maintain Tx Ring Index
2486 pAdapter->CurEncryptIndex++;
2487 if (pAdapter->CurEncryptIndex >= TX_RING_SIZE)
2489 pAdapter->CurEncryptIndex = 0;
2492 pAdapter->RalinkCounters.EncryptCount++;
2494 // Kick Encrypt Control Register at the end of all ring buffer preparation
2495 RTMP_IO_WRITE32(pAdapter, SECCSR1, 0x1);
2498 NdisReleaseSpinLock(&pAdapter->TxRingLock);
2500 MlmeFreeMemory(pAdapter, pBuffer);
2504 ========================================================================
2506 Routine Description:
2507 Copy frame from waiting queue into relative ring buffer and set
2508 appropriate ASIC register to kick hardware encryption before really
2509 sent out to air.
2511 Arguments:
2512 pAdapter Pointer to our adapter
2513 PNDIS_PACKET Pointer to outgoing Ndis frame
2514 NumberOfFrag Number of fragment required
2516 Return Value:
2517 None
2519 Note:
2521 ========================================================================
2523 NDIS_STATUS RTMPHardEncrypt(
2524 IN PRTMP_ADAPTER pAdapter,
2525 IN struct sk_buff *skb,
2526 IN UCHAR NumberRequired,
2527 IN ULONG EnableTxBurst,
2528 IN UCHAR AccessCategory)
2530 PVOID pVirtualAddress;
2531 UINT NdisBufferLength;
2532 UINT BytesCopied;
2533 UINT TxSize;
2534 UINT FreeFragSize;
2535 UINT RemainSize;
2536 USHORT Protocol;
2537 UCHAR FrameGap;
2538 HEADER_802_11 Header_802_11;
2539 PUCHAR pDest;
2540 PUCHAR pSrc;
2541 PUCHAR pEncap;
2542 UCHAR CipherAlg;
2543 PTXD_STRUC pTxD;
2544 BOOLEAN StartOfFrame;
2545 BOOLEAN EAPOLFrame;
2546 BOOLEAN Encapped;
2547 ULONG Iv16;
2548 ULONG Iv32;
2549 BOOLEAN MICFrag;
2550 PWPA_KEY pWpaKey = NULL;
2551 UCHAR RetryMode = SHORT_RETRY;
2552 UCHAR AckRate = RATE_2;
2553 USHORT AckDuration = 0;
2554 USHORT EncryptionOverhead = 0;
2555 #ifdef BIG_ENDIAN
2556 PTXD_STRUC pDestTxD;
2557 TXD_STRUC TxD;
2558 PUCHAR pOriginDest;
2559 #else
2560 PUCHAR pTxBuffer;
2561 #endif
2562 unsigned long IrqFlags;
2564 // Make sure Tx ring resource won't be used by other threads
2565 NdisAcquireSpinLock(&pAdapter->TxRingLock);
2567 if(skb->data == NULL)
2569 DBGPRINT(RT_DEBUG_ERROR, "Error, Null skb data buffer!!!\n");
2571 NdisReleaseSpinLock(&pAdapter->TxRingLock);
2572 return (NDIS_STATUS_FAILURE);
2575 if (EnableTxBurst == 1)
2576 FrameGap = IFS_SIFS;
2577 else
2578 FrameGap = IFS_BACKOFF; // Default frame gap mode
2580 // outgoing frame always wakeup PHY to prevent frame lost and
2581 // turn off PSM bit to improve performance
2582 if (pAdapter->PortCfg.Psm == PWR_SAVE)
2584 MlmeSetPsmBit(pAdapter, PWR_ACTIVE);
2586 AsicForceWakeup(pAdapter);
2588 // Sequence Number is identical for all fragments belonged to the same frame
2589 // Sequence is 0 - 4095
2590 pAdapter->Sequence = ((pAdapter->Sequence) + 1) & (MAX_SEQ_NUMBER);
2592 AckRate = pAdapter->PortCfg.ExpectedACKRate[pAdapter->PortCfg.TxRate];
2593 AckDuration = RTMPCalcDuration(pAdapter, AckRate, 14);
2595 pVirtualAddress = skb->data;
2596 NdisBufferLength = skb->len;
2598 if ((*((PUCHAR) pVirtualAddress) & 0x01) != 0) // Multicast or Broadcast
2600 INC_COUNTER(pAdapter->WlanCounters.MulticastTransmittedFrameCount);
2603 if (NdisBufferLength < 14)
2605 DBGPRINT(RT_DEBUG_ERROR,"RTMPHardTransmit --> Ndis Packet buffer error !!!\n");
2606 // Make sure to release Tx ring resource
2607 NdisReleaseSpinLock(&pAdapter->TxRingLock);
2608 return (NDIS_STATUS_FAILURE);
2612 // Start making 802.11 frame header
2614 NdisZeroMemory(&Header_802_11, sizeof(HEADER_802_11)); // Initialize 802.11 header for each fragment
2615 if (INFRA_ON(pAdapter))
2617 // Address 1 - AP, Address 2 - this STA, Address 3 - DA
2618 NdisMoveMemory(&Header_802_11.Controlhead.Addr1, &pAdapter->PortCfg.Bssid, ETH_LENGTH_OF_ADDRESS);
2619 NdisMoveMemory(&Header_802_11.Addr3, (PUCHAR) pVirtualAddress, ETH_LENGTH_OF_ADDRESS);
2620 Header_802_11.Controlhead.Frame.ToDs = 1;
2622 else
2624 // Address 1 - DA, Address 2 - this STA, Address 3 - BSSID
2625 NdisMoveMemory(&Header_802_11.Controlhead.Addr1, (PUCHAR) pVirtualAddress, ETH_LENGTH_OF_ADDRESS);
2626 NdisMoveMemory(&Header_802_11.Addr3, &pAdapter->PortCfg.Bssid, ETH_LENGTH_OF_ADDRESS);
2628 NdisMoveMemory(&Header_802_11.Controlhead.Addr2, pAdapter->CurrentAddress, ETH_LENGTH_OF_ADDRESS);
2630 Header_802_11.Sequence = pAdapter->Sequence; // Sequence number
2631 Header_802_11.Controlhead.Frame.Type = BTYPE_DATA; // Frame type
2632 Header_802_11.Controlhead.Frame.PwrMgt = (pAdapter->PortCfg.Psm == PWR_SAVE);
2634 // Add 802.11x protocol check.
2635 // For non-WPA network, 802.1x message should not encrypt even
2636 // the privacy is on.
2637 if (RTMPEqualMemory(EAPOL, ((PUCHAR) pVirtualAddress) + 12, 2))
2639 EAPOLFrame = TRUE;
2640 if (pAdapter->PortCfg.MicErrCnt >= 2)
2641 pAdapter->PortCfg.MicErrCnt++;
2643 else
2644 EAPOLFrame = FALSE;
2646 // WPA 802.1x secured port control
2647 if (((pAdapter->PortCfg.AuthMode == Ndis802_11AuthModeWPA) ||
2648 (pAdapter->PortCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) &&
2649 ((pAdapter->PortCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) || (pAdapter->PortCfg.MicErrCnt >= 2)) &&
2650 (EAPOLFrame == FALSE))
2652 DBGPRINT(RT_DEBUG_TRACE,"RTMPHardEncrypt --> Drop packet before port secured !!!\n");
2653 // Make sure to release Tx ring resource
2654 NdisReleaseSpinLock(&pAdapter->TxRingLock);
2655 return (NDIS_STATUS_FAILURE);
2658 MICFrag = FALSE; // Flag to indicate MIC shall spread into two MPDUs
2659 Encapped = FALSE;
2660 pEncap = NULL;
2662 pSrc = (PUCHAR) pVirtualAddress;
2663 Protocol = *(pSrc + 12) * 256 + *(pSrc + 13);
2664 if (Protocol > 1500) // CHeck for LLC encaped
2666 pEncap = SNAP_802_1H;
2667 Encapped = TRUE;
2668 if (RTMPEqualMemory(IPX, pSrc + 12, 2) ||
2669 RTMPEqualMemory(APPLE_TALK, pSrc + 12, 2))
2671 pEncap = SNAP_BRIDGE_TUNNEL;
2675 if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption1Enabled) &&
2676 (pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].KeyLen != 0))
2677 EncryptionOverhead = 8; // WEP: IV + ICV
2678 else if (pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled)
2679 EncryptionOverhead = 12; // TKIP: IV + EIV + ICV, MIC already added to TotalPacketLength
2680 else if (pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled)
2681 EncryptionOverhead = 16; // AES: IV + EIV + Hardware MIC
2682 else
2683 EncryptionOverhead = 0;
2686 // Make RTS frame if required
2688 if (RTMP_GET_PACKET_RTS(skb))
2690 PCONTROL_HEADER pControlHeader;
2691 ULONG NextFragSize;
2693 // RTS-protected frame should use LONG_RETRY (=4), other frames use SHORT_RETRY (=7)
2694 RetryMode = LONG_RETRY;
2696 pDest = (PUCHAR) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_data_addr;
2697 #ifndef BIG_ENDIAN
2698 pTxD = (PTXD_STRUC) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_addr;
2699 #else
2700 pDestTxD = (PTXD_STRUC) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_addr;
2701 TxD = *pDestTxD;
2702 pTxD = &TxD;
2703 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2704 #endif
2706 if ((pTxD->Owner == DESC_OWN_NIC) || (pTxD->CipherOwn == DESC_OWN_NIC))
2708 // Descriptor owned by NIC. No descriptor avaliable
2709 // This should not happen since caller guaranteed.
2710 // Make sure to release Tx ring resource
2711 NdisReleaseSpinLock(&pAdapter->TxRingLock);
2712 return (NDIS_STATUS_RESOURCES);
2714 if (pTxD->Valid == TRUE)
2716 // This might happen when HardTransmit process faster than TxDone interrupt.
2717 // However, Since we did call free descriptor number check before Tx HardTransmit.
2718 // This case should not happened. We should return to higher caller and requeue this
2719 // acket until next Tx hardtransmit. Hopefully this situation is corrected then.
2720 // Ndis packet of last round did not cleared.
2721 // This should not happen since caller guaranteed.
2722 // Make sure to release Tx ring resource
2723 pTxD->Valid = FALSE;
2724 #ifdef BIG_ENDIAN
2725 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2726 *pDestTxD = TxD;
2727 #endif
2729 NdisReleaseSpinLock(&pAdapter->TxRingLock);
2730 return (NDIS_STATUS_RESOURCES);
2733 pAdapter->TxRing[pAdapter->CurEncryptIndex].FrameType = BTYPE_CNTL;
2734 pControlHeader = (PCONTROL_HEADER) pDest;
2735 NdisZeroMemory(pControlHeader, sizeof(CONTROL_HEADER));
2736 pControlHeader->Frame.Type = BTYPE_CNTL;
2738 // Calculate duration = 2 SIFS + CTS + Data Frame size
2739 if (RTMP_GET_PACKET_FRAGMENTS(skb) > 1)
2741 // If fragment required, size is maximum fragment size
2742 NextFragSize = pAdapter->PortCfg.FragmentThreshold;
2744 else
2746 // Size should be frame with 802.11 header & CRC
2747 NextFragSize = skb->data_len + LENGTH_802_11 + LENGTH_CRC - LENGTH_802_3;
2749 if (Encapped)
2750 NextFragSize += LENGTH_802_1_H;
2752 pControlHeader->Duration = 2 * (pAdapter->PortCfg.Dsifs)
2753 + RTMPCalcDuration(pAdapter, pAdapter->PortCfg.TxRate, NextFragSize + EncryptionOverhead)
2754 + AckDuration;
2756 // Write Tx descriptor
2757 // Don't kick tx start until all frames are prepared
2758 // RTS has to set more fragment bit for fragment burst
2759 // RTS did not encrypt
2760 if (pAdapter->PortCfg.BGProtectionInUsed == 1)
2762 DBGPRINT(RT_DEBUG_TRACE,"Making CTS-to-self Frame\n");
2763 pControlHeader->Frame.Subtype = SUBTYPE_CTS;
2764 NdisMoveMemory(&pControlHeader->Addr1, pAdapter->CurrentAddress, ETH_LENGTH_OF_ADDRESS);
2766 #ifdef BIG_ENDIAN // Add at 08-23-2004, by Yu-Lang Hsu.
2767 RTMPFrameEndianChange(pAdapter, (PUCHAR)pControlHeader, DIR_WRITE, FALSE);
2768 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2769 *pDestTxD = TxD;
2770 pTxD = pDestTxD;
2771 #endif
2772 #ifdef WIFI_TEST
2773 RTMPWriteTxDescriptor(pTxD, TRUE, CIPHER_NONE, FALSE, FALSE, FALSE, SHORT_RETRY,
2774 FrameGap, pAdapter->PortCfg.RtsRate, 4, 10, Rt802_11PreambleShort,
2775 AccessCategory);
2776 #else
2777 RTMPWriteTxDescriptor(pTxD, TRUE, CIPHER_NONE, FALSE, FALSE, FALSE, SHORT_RETRY,
2778 FrameGap, pAdapter->PortCfg.RtsRate, 4, 10, pAdapter->PortCfg.TxPreambleInUsed,
2779 AccessCategory);
2780 #endif
2782 else
2784 DBGPRINT(RT_DEBUG_TRACE,"Making RTS Frame\n");
2785 pControlHeader->Frame.Subtype = SUBTYPE_RTS;
2786 if (INFRA_ON(pAdapter))
2787 NdisMoveMemory(&pControlHeader->Addr1, &pAdapter->PortCfg.Bssid, ETH_LENGTH_OF_ADDRESS);
2788 else
2789 NdisMoveMemory(&pControlHeader->Addr1, (PUCHAR) pVirtualAddress, ETH_LENGTH_OF_ADDRESS);
2790 NdisMoveMemory(&pControlHeader->Addr2, pAdapter->CurrentAddress, ETH_LENGTH_OF_ADDRESS);
2791 #ifdef BIG_ENDIAN
2792 RTMPFrameEndianChange(pAdapter, (PUCHAR)pControlHeader, DIR_WRITE, FALSE);
2793 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2794 *pDestTxD = TxD;
2795 pTxD = pDestTxD;
2796 #endif
2797 RTMPWriteTxDescriptor(pTxD, TRUE, CIPHER_NONE, TRUE, TRUE, FALSE, SHORT_RETRY,
2798 FrameGap, pAdapter->PortCfg.RtsRate, 4, sizeof(CONTROL_HEADER),
2799 pAdapter->PortCfg.TxPreambleInUsed, AccessCategory);
2800 pTxD->RTS = 1;
2803 FrameGap = IFS_SIFS; // Init frame gap for coming data after RTS
2804 NumberRequired--;
2806 // Increase & maintain Tx Ring Index
2807 pAdapter->CurEncryptIndex++;
2808 if (pAdapter->CurEncryptIndex >= TX_RING_SIZE)
2810 pAdapter->CurEncryptIndex = 0;
2812 pAdapter->RalinkCounters.EncryptCount++;
2815 // Find the WPA key, either Group or Pairwise Key
2816 if (pAdapter->PortCfg.AuthMode >= Ndis802_11AuthModeWPA)
2818 INT idx;
2820 pWpaKey = (PWPA_KEY) NULL;
2821 // First lookup the DA, if it's a group address, use GROUP key
2822 if (Header_802_11.Controlhead.Addr1.Octet[0] & 0x01)
2824 if (pAdapter->PortCfg.GroupKey[pAdapter->PortCfg.DefaultKeyId].KeyLen != 0)
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");
2831 // Try to find the Pairwise Key
2832 else
2834 for (idx = 0; idx < PAIRWISE_KEY_NO; idx++)
2836 if ((NdisEqualMemory(&Header_802_11.Controlhead.Addr1, pAdapter->PortCfg.PairwiseKey[idx].BssId, 6)) &&
2837 (pAdapter->PortCfg.PairwiseKey[idx].KeyLen != 0))
2839 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.PairwiseKey[idx];
2840 pWpaKey->Type = PAIRWISE_KEY;
2841 DBGPRINT(RT_DEBUG_INFO, "Tx Use Pairwise Key\n");
2842 break;
2845 // Use default Group Key if there is no Pairwise key present
2846 if ((pAdapter->PortCfg.GroupKey[pAdapter->PortCfg.DefaultKeyId].KeyLen != 0) && (pWpaKey == NULL))
2848 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.GroupKey[pAdapter->PortCfg.DefaultKeyId];
2849 pWpaKey->Type = GROUP_KEY;
2850 DBGPRINT(RT_DEBUG_INFO, "Tx Use Group Key\n");
2855 // For the purpose to calculate duration for the second last fragment
2856 RemainSize = skb->data_len - LENGTH_802_3 + LENGTH_CRC;
2858 StartOfFrame = TRUE;
2859 // Start Copy Ndis Packet into Ring buffer.
2860 // For frame required more than one ring buffer (fragment), all ring buffers
2861 // have to be filled before kicking start tx bit.
2864 // Get the Tx Ring descriptor & Dma Buffer address
2865 #ifndef BIG_ENDIAN
2866 pDest = (PUCHAR) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_data_addr;
2867 pTxD = (PTXD_STRUC) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_addr;
2868 pTxBuffer = pDest;
2869 #else
2870 pDest = (PUCHAR) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_data_addr;
2871 pOriginDest = pDest;
2872 pDestTxD = (PTXD_STRUC) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_addr;
2873 TxD = *pDestTxD;
2874 pTxD = &TxD;
2875 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2876 #endif
2878 if ((pTxD->Owner == DESC_OWN_NIC) || (pTxD->CipherOwn == DESC_OWN_NIC))
2880 // Descriptor owned by NIC. No descriptor avaliable
2881 // This should not happen since caller guaranteed.
2882 // Make sure to release Tx ring resource
2883 pAdapter->RalinkCounters.TxRingErrCount++;
2884 NdisReleaseSpinLock(&pAdapter->TxRingLock);
2885 return (NDIS_STATUS_RESOURCES);
2887 if (pTxD->Valid == TRUE)
2889 // Ndis packet of last round did not cleared.
2890 // This should not happen since caller guaranteed.
2891 // Make sure to release Tx ring resource
2892 pTxD->Valid = FALSE;
2894 #ifdef BIG_ENDIAN
2895 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2896 *pDestTxD = TxD;
2897 #endif
2899 pAdapter->RalinkCounters.TxRingErrCount++;
2900 NdisReleaseSpinLock(&pAdapter->TxRingLock);
2901 return (NDIS_STATUS_RESOURCES);
2903 pAdapter->TxRing[pAdapter->CurEncryptIndex].FrameType = BTYPE_DATA;
2905 // Make fragment number & more fragment bit of 802.11 header
2906 if (StartOfFrame == TRUE)
2907 Header_802_11.Frag = 0; // Start of fragment burst / Single Frame
2908 else
2909 Header_802_11.Frag++; // Rest of fragmented frames.
2911 // Maximum allowable payload with one ring buffer, bound by fragment size
2912 FreeFragSize = pAdapter->PortCfg.FragmentThreshold - LENGTH_CRC;
2915 // calculate "duration" field of this fragment
2917 if (NumberRequired > 1)
2919 ULONG NextFragSize;
2920 Header_802_11.Controlhead.Frame.MoreFrag = 1;
2922 if (NumberRequired == 2)
2923 NextFragSize = RemainSize - pAdapter->PortCfg.FragmentThreshold + LENGTH_802_11 + LENGTH_802_11 + LENGTH_CRC;
2924 else
2925 NextFragSize = pAdapter->PortCfg.FragmentThreshold;
2927 Header_802_11.Controlhead.Duration = 3 * pAdapter->PortCfg.Dsifs
2928 + 2 * AckDuration
2929 + RTMPCalcDuration(pAdapter, pAdapter->PortCfg.TxRate, NextFragSize + EncryptionOverhead);
2931 else // this is the last or only fragment
2933 Header_802_11.Controlhead.Frame.MoreFrag = 0;
2935 if (Header_802_11.Controlhead.Addr1.Octet[0] & 0x01) // multicast/broadcast
2936 Header_802_11.Controlhead.Duration = 0;
2937 else
2938 Header_802_11.Controlhead.Duration = pAdapter->PortCfg.Dsifs + AckDuration;
2941 // Check for WEP enable bit and prepare for software WEP
2942 if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption1Enabled) && (EAPOLFrame == FALSE) &&
2943 (pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].KeyLen != 0))
2944 Header_802_11.Controlhead.Frame.Wep = 1;
2945 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) && (pWpaKey != NULL))
2946 Header_802_11.Controlhead.Frame.Wep = 1;
2947 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled) && (pWpaKey != NULL))
2948 Header_802_11.Controlhead.Frame.Wep = 1;
2951 // Copy 802.11 header to Tx ring buffer
2953 NdisMoveMemory(pDest, &Header_802_11, sizeof(Header_802_11));
2954 pDest += sizeof(Header_802_11);
2955 FreeFragSize -= sizeof(Header_802_11);
2957 if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption1Enabled) && (EAPOLFrame == FALSE) &&
2958 (pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].KeyLen != 0))
2960 // Prepare IV, IV offset, Key for Hardware encryption
2961 RTMPInitWepEngine(
2962 pAdapter,
2963 pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].Key,
2964 pAdapter->PortCfg.DefaultKeyId,
2965 pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].KeyLen,
2966 (PUCHAR) &pTxD->Iv);
2968 if (pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].KeyLen == 5)
2969 CipherAlg = CIPHER_WEP64;
2970 else
2971 CipherAlg = CIPHER_WEP128;
2973 // Set Iv offset in TxD
2974 pTxD->IvOffset = LENGTH_802_11;
2975 // Copy Encrypt Key to TxD
2976 NdisMoveMemory(
2977 pTxD->Key,
2978 pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].Key,
2979 pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].KeyLen);
2981 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) && (pWpaKey != NULL))
2983 INT i = 0;
2985 // Prepare 8 bytes TKIP encapsulation for MPDU
2987 TKIP_IV tkipIv;
2989 tkipIv.IV16.field.rc0 = *(pWpaKey->TxTsc + 1);
2990 tkipIv.IV16.field.rc1 = (tkipIv.IV16.field.rc0 | 0x20) & 0x7f;
2991 tkipIv.IV16.field.rc2 = *pWpaKey->TxTsc;
2992 tkipIv.IV16.field.CONTROL.field.ExtIV = 1; // 0: non-extended IV, 1: an extended IV
2993 tkipIv.IV16.field.CONTROL.field.KeyID = pAdapter->PortCfg.DefaultKeyId;
2994 tkipIv.IV32 = *(PULONG)(pWpaKey->TxTsc + 2);
2996 #ifdef BIG_ENDIAN
2997 pTxD->Iv = (tkipIv.IV16.field.rc0 << 24) | (tkipIv.IV16.field.rc1 << 16) | (tkipIv.IV16.field.rc2 << 8) | (tkipIv.IV16.field.CONTROL.Byte);
2998 #else
2999 #ifdef RTMP_EMBEDDED
3000 pTxD->Iv = (tkipIv.IV16.field.CONTROL.Byte << 24) | (tkipIv.IV16.field.rc2 << 16) | (tkipIv.IV16.field.rc1 << 8) | (tkipIv.IV16.field.rc0);
3001 #else
3002 pTxD->Iv = tkipIv.IV16.word;
3003 #endif
3004 #endif
3006 *((PUCHAR) &pTxD->Eiv) = *((PUCHAR) &tkipIv.IV32 + 3);
3007 *((PUCHAR) &pTxD->Eiv + 1) = *((PUCHAR) &tkipIv.IV32 + 2);
3008 *((PUCHAR) &pTxD->Eiv + 2) = *((PUCHAR) &tkipIv.IV32 + 1);
3009 *((PUCHAR) &pTxD->Eiv + 3) = *((PUCHAR) &tkipIv.IV32);
3012 // Increase TxTsc value for next transmission
3013 while (++pWpaKey->TxTsc[i] == 0x0)
3015 i++;
3016 if (i == 6)
3017 break;
3020 // Set IV offset
3021 pTxD->IvOffset = LENGTH_802_11;
3023 // Copy TKey
3024 NdisMoveMemory(pTxD->Key, pWpaKey->Key, 16);
3026 // Set Cipher suite
3027 CipherAlg = CIPHER_TKIP;
3029 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled) && (pWpaKey != NULL))
3031 INT i;
3032 PUCHAR pTmp;
3034 i = 0;
3035 pTmp = (PUCHAR) &Iv16;
3036 *pTmp = pWpaKey->TxTsc[0];
3037 *(pTmp + 1) = pWpaKey->TxTsc[1];
3038 *(pTmp + 2) = 0;
3039 *(pTmp + 3) = (pAdapter->PortCfg.DefaultKeyId << 6) | 0x20;
3041 Iv32 = *(PULONG)(&pWpaKey->TxTsc[2]);
3043 // Increase TxTsc value for next transmission
3044 while (++pWpaKey->TxTsc[i] == 0x0)
3046 i++;
3047 if (i == 6)
3048 break;
3050 if (i == 6)
3052 // TODO: TSC has done one full cycle, do re-keying stuff follow specs
3053 // Should send a special event microsoft defined to request re-key
3056 NdisMoveMemory(&pTxD->Iv, &Iv16, 4); // Copy IV
3057 NdisMoveMemory(&pTxD->Eiv, &Iv32, 4); // Copy EIV
3058 pTxD->IvOffset = LENGTH_802_11; // Set IV offset
3059 NdisMoveMemory(pTxD->Key, pWpaKey->Key, 16); // Copy TKey
3060 CipherAlg = CIPHER_AES; // Set Cipher suite
3062 else
3063 CipherAlg = CIPHER_NONE;
3066 // Only the first fragment required LLC-SNAP header !!!
3068 if ((StartOfFrame == TRUE) && (Encapped == TRUE))
3070 // For WEP & no encryption required frame, just copy LLC header into buffer,
3071 // Hardware will do the encryption job.
3072 // For TKIP, we have to calculate MIC and store it first
3073 if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) && (pWpaKey != NULL))
3075 // Calculate MSDU MIC Value
3076 RTMPCalculateMICValue(pAdapter, skb, pEncap, 6, pWpaKey);
3079 // Copy LLC header
3080 NdisMoveMemory(pDest, pEncap, 6);
3081 pDest += 6;
3083 // Copy protocol type
3084 pSrc = (PUCHAR) pVirtualAddress;
3085 NdisMoveMemory(pDest, pSrc + 12, 2);
3086 pDest += 2;
3088 // Exclude 802.3 header size, we will recalculate the size at
3089 // the end of fragment preparation.
3090 NdisBufferLength -= LENGTH_802_3;
3091 pSrc += LENGTH_802_3;
3092 FreeFragSize -= LENGTH_802_1_H;
3094 else if ((StartOfFrame == TRUE) && (Encapped == FALSE))
3096 if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) && (pWpaKey != NULL))
3098 // Calculate MSDU MIC Value
3099 RTMPCalculateMICValue(pAdapter, skb, pEncap, 0, pWpaKey);
3102 pSrc = (PUCHAR) pVirtualAddress + LENGTH_802_3;
3103 NdisBufferLength -= LENGTH_802_3;
3106 // Start copying payload
3107 BytesCopied = 0;
3110 if (NdisBufferLength >= FreeFragSize)
3112 // Copy only the free fragment size, and save the pointer
3113 // of current buffer descriptor for next fragment buffer.
3114 NdisMoveMemory(pDest, pSrc, FreeFragSize);
3115 BytesCopied += FreeFragSize;
3116 pSrc += FreeFragSize;
3117 pDest += FreeFragSize;
3118 NdisBufferLength -= FreeFragSize;
3119 break;
3121 else
3123 // Copy the rest of this buffer descriptor pointed data
3124 // into ring buffer.
3125 NdisMoveMemory(pDest, pSrc, NdisBufferLength);
3126 BytesCopied += NdisBufferLength;
3127 pDest += NdisBufferLength;
3128 FreeFragSize -= NdisBufferLength;
3131 // No more buffer descriptor
3132 // Add MIC value if needed
3133 if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
3134 (MICFrag == FALSE) &&
3135 (pWpaKey != NULL))
3137 INT i;
3139 NdisBufferLength = 8; // Set length to MIC length
3140 DBGPRINT(RT_DEBUG_INFO, "Calculated TX MIC value =");
3141 for (i = 0; i < 8; i++)
3143 DBGPRINT(RT_DEBUG_INFO, "%02x:", pAdapter->PrivateInfo.Tx.MIC[i]);
3145 DBGPRINT(RT_DEBUG_INFO, "\n");
3147 if (FreeFragSize >= NdisBufferLength)
3149 NdisMoveMemory(pDest, pAdapter->PrivateInfo.Tx.MIC, NdisBufferLength);
3150 BytesCopied += NdisBufferLength;
3151 pDest += NdisBufferLength;
3152 FreeFragSize -= NdisBufferLength;
3153 NdisBufferLength = 0;
3154 RemainSize += 8; // Need to add MIC as payload
3156 else
3158 NdisMoveMemory(pDest, pAdapter->PrivateInfo.Tx.MIC, FreeFragSize);
3159 BytesCopied += FreeFragSize;
3160 pSrc = pAdapter->PrivateInfo.Tx.MIC + FreeFragSize;
3161 pDest += FreeFragSize;
3162 NdisBufferLength -= FreeFragSize;
3163 MICFrag = TRUE;
3164 RemainSize += (8 - FreeFragSize); // Need to add MIC as payload
3167 } while (FALSE); // End of copying payload
3169 // Real packet size, No 802.1H header for fragments except the first one.
3170 if ((StartOfFrame == TRUE) && (Encapped == TRUE))
3172 TxSize = BytesCopied + LENGTH_802_11 + LENGTH_802_1_H;
3174 else
3176 TxSize = BytesCopied + LENGTH_802_11;
3179 RemainSize = RemainSize - BytesCopied;
3181 if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption1Enabled) && (Header_802_11.Controlhead.Frame.Wep == 1))
3183 // IV + ICV which ASIC added after encryption done
3184 TxSize += 8;
3186 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) && (pWpaKey != NULL))
3188 // IV + EIV + ICV which ASIC added after encryption done
3189 TxSize += 12;
3191 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled) && (pWpaKey != NULL))
3193 // IV + EIV + HW MIC
3194 TxSize += 16;
3197 // Prepare Tx descriptors before kicking tx.
3198 // The BBP register index in Tx descriptor has to be configured too.
3199 #ifdef BIG_ENDIAN
3200 RTMPFrameEndianChange(pAdapter, pOriginDest, DIR_WRITE, FALSE);
3201 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
3202 *pDestTxD = TxD;
3203 pTxD = pDestTxD;
3204 #endif
3205 if (Header_802_11.Controlhead.Addr1.Octet[0] & 0x01)
3207 // Multicast, retry bit is off
3208 RTMPWriteTxDescriptor(pTxD, TRUE, CipherAlg, FALSE, FALSE, FALSE, RetryMode, FrameGap,
3209 pAdapter->PortCfg.TxRate, 4, TxSize, pAdapter->PortCfg.TxPreambleInUsed, AccessCategory);
3211 else
3213 RTMPWriteTxDescriptor(pTxD, TRUE, CipherAlg, TRUE, FALSE, FALSE, RetryMode, FrameGap,
3214 pAdapter->PortCfg.TxRate, 4, TxSize, pAdapter->PortCfg.TxPreambleInUsed, AccessCategory);
3217 // Set frame gap for the rest of fragment burst.
3218 // It won't matter if there is only one fragment (single fragment frame).
3219 StartOfFrame = FALSE;
3220 FrameGap = IFS_SIFS;
3221 NumberRequired--;
3223 // Increase & maintain Tx Ring Index
3224 pAdapter->CurEncryptIndex++;
3225 if (pAdapter->CurEncryptIndex >= TX_RING_SIZE)
3227 pAdapter->CurEncryptIndex = 0;
3230 pAdapter->RalinkCounters.EncryptCount++;
3232 } while (NumberRequired > 0);
3235 // Kick Encrypt Control Register at the end of all ring buffer preparation
3236 RTMP_IO_WRITE32(pAdapter, SECCSR1, 0x1);
3238 // Acknowledge protocol send complete of pending packet.
3239 RTMPFreeSkbBuffer(skb);
3241 // Make sure to release Tx ring resource
3242 NdisReleaseSpinLock(&pAdapter->TxRingLock);
3244 return (NDIS_STATUS_SUCCESS);
3248 ========================================================================
3250 Routine Description:
3251 Calculates the duration which is required to transmit out frames
3252 with given size and specified rate.
3254 Arguments:
3255 pAdapter Pointer to our adapter
3256 Rate Transmit rate
3257 Size Frame size in units of byte
3259 Return Value:
3260 Duration number in units of usec
3262 Note:
3264 ========================================================================
3266 USHORT RTMPCalcDuration(
3267 IN PRTMP_ADAPTER pAdapter,
3268 IN UCHAR Rate,
3269 IN ULONG Size)
3271 ULONG Duration = 0;
3273 if (Rate < RATE_FIRST_OFDM_RATE) // CCK
3275 if ((Rate > RATE_1) && (pAdapter->PortCfg.TxPreambleInUsed == Rt802_11PreambleShort))
3276 Duration = 96; // 72+24 preamble+plcp
3277 else
3278 Duration = 192; // 144+48 preamble+plcp
3280 Duration += (USHORT)((Size << 4) / RateIdTo500Kbps[Rate]);
3281 if ((Size << 4) % RateIdTo500Kbps[Rate])
3282 Duration ++;
3284 else // OFDM rates
3286 Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension
3287 Duration += 4 * (USHORT)((11 + Size * 4) / RateIdTo500Kbps[Rate]);
3288 if ((11 + Size * 4) % RateIdTo500Kbps[Rate])
3289 Duration += 4;
3292 return (USHORT)Duration;
3297 ========================================================================
3299 Routine Description:
3300 Calculates the duration which is required to transmit out frames
3301 with given size and specified rate.
3303 Arguments:
3304 pTxD Pointer to transmit descriptor
3305 Ack Setting for Ack requirement bit
3306 Fragment Setting for Fragment bit
3307 RetryMode Setting for retry mode
3308 Ifs Setting for IFS gap
3309 Rate Setting for transmit rate
3310 Service Setting for service
3311 Length Frame length
3312 TxPreamble Short or Long preamble when using CCK rates
3313 AccessCategory - 0-3, according to 802.11e/d4.4 June/2003
3315 Return Value:
3316 None
3318 ========================================================================
3320 VOID RTMPWriteTxDescriptor(
3321 IN PTXD_STRUC pSourceTxD,
3322 IN BOOLEAN DoEncrypt,
3323 IN UCHAR CipherAlg,
3324 IN BOOLEAN Ack,
3325 IN BOOLEAN Fragment,
3326 IN BOOLEAN InsTimestamp,
3327 IN UCHAR RetryMode,
3328 IN UCHAR Ifs,
3329 IN UINT Rate,
3330 IN UCHAR Service,
3331 IN ULONG Length,
3332 IN USHORT TxPreamble,
3333 IN UCHAR AccessCategory)
3335 UINT Residual;
3336 PTXD_STRUC pTxD;
3337 #ifndef BIG_ENDIAN
3338 pTxD = pSourceTxD;
3339 #else
3340 TXD_STRUC TxD;
3342 TxD = *pSourceTxD;
3343 pTxD = &TxD;
3344 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); // Scott: to BE
3345 #endif
3347 pTxD->MoreFrag = Fragment;
3348 pTxD->ACK = Ack;
3349 pTxD->Timestamp = InsTimestamp;
3350 pTxD->RetryMd = RetryMode;
3351 pTxD->IFS = Ifs;
3352 pTxD->DataByteCnt = Length;
3353 pTxD->TxRate = Rate;
3354 switch (AccessCategory) // 802.11e/d4.4 June/2003
3356 case 3: // TC3, <AIFSN, CwMin, CwMax> = <1, aCwMin/4, aCwMin/2>
3357 pTxD->CWmin = CW_MIN_IN_BITS - 2;
3358 pTxD->CWmax = CW_MIN_IN_BITS - 1;
3359 pTxD->Aifs = 1;
3360 break;
3361 case 2: // TC2, <AIFSN, CwMin, CwMax> = <1, aCwMin/2, aCwMin>
3362 pTxD->CWmin = CW_MIN_IN_BITS - 1;
3363 pTxD->CWmax = CW_MIN_IN_BITS;
3364 pTxD->Aifs = 1;
3365 break;
3366 case 1: // TC1, <AIFSN, CwMin, CwMax> = <1, aCwMin, aCwMax>
3367 pTxD->CWmin = CW_MIN_IN_BITS;
3368 pTxD->CWmax = CW_MAX_IN_BITS;
3369 pTxD->Aifs = 1;
3370 break;
3371 case 0: // TC0, <AIFSN, CwMin, CwMax> = <2, aCwMin, aCwMax>
3372 default:
3373 pTxD->CWmin = CW_MIN_IN_BITS;
3374 pTxD->CWmax = CW_MAX_IN_BITS;
3375 pTxD->Aifs = 2;
3376 break;
3379 if (Rate < RATE_FIRST_OFDM_RATE)
3380 pTxD->Ofdm = 0;
3381 else
3382 pTxD->Ofdm = 1;
3384 // fill up PLCP SIGNAL field
3385 pTxD->PlcpSignal = PlcpSignal[Rate];
3386 if (((Rate == RATE_2) || (Rate == RATE_5_5) || (Rate == RATE_11)) && (TxPreamble == Rt802_11PreambleShort)) // no short preamble for RATE_1
3388 pTxD->PlcpSignal |= 0x0008;
3391 // fill up PLCP SERVICE field, not used for OFDM rates
3392 pTxD->PlcpService = Service;
3394 // file up PLCP LENGTH_LOW and LENGTH_HIGH fields
3395 Length += 4;
3396 if (Rate < RATE_FIRST_OFDM_RATE) // 11b - RATE_1, RATE_2, RATE_5_5, RATE_11
3398 if ((Rate == RATE_1) || ( Rate == RATE_2))
3400 Length = Length * 8 / (Rate + 1);
3402 else
3404 Residual = ((Length * 16) % (11 * (1 + Rate - RATE_5_5)));
3405 Length = Length * 16 / (11 * (1 + Rate - RATE_5_5));
3406 if (Residual != 0)
3408 Length++;
3410 if ((Residual <= (3 * (1 + Rate - RATE_5_5))) && (Residual != 0))
3412 if (Rate == RATE_11) // Only 11Mbps require length extension bit
3413 pTxD->PlcpService |= 0x80; // 11b's PLCP Length extension bit
3417 pTxD->PlcpLengthHigh = Length / 256;
3418 pTxD->PlcpLengthLow = Length % 256;
3420 else // OFDM - RATE_6, RATE_9, RATE_12, RATE_18, RATE_24, RATE_36, RATE_48, RATE_54
3422 pTxD->PlcpLengthHigh = Length / 64; // high 6-bit of total byte count
3423 pTxD->PlcpLengthLow = Length % 64; // low 6-bit of total byte count
3426 if (DoEncrypt == TRUE) // Do encryption only
3428 pTxD->Owner = DESC_OWN_HOST;
3429 pTxD->Valid = FALSE;
3430 pTxD->CipherAlg = CipherAlg;
3431 pTxD->CipherOwn = DESC_OWN_NIC;
3433 else // Hard transmit
3435 pTxD->Valid = TRUE;
3436 pTxD->CipherAlg = CIPHER_NONE;
3437 pTxD->CipherOwn = DESC_OWN_HOST;
3438 pTxD->Owner = DESC_OWN_NIC;
3440 #ifdef BIG_ENDIAN
3441 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); // Scott: to LE
3442 *pSourceTxD = *pTxD;
3443 #endif
3447 ========================================================================
3449 Routine Description:
3450 Search tuple cache for receive duplicate frame from unicast frames.
3452 Arguments:
3453 pAdapter Pointer to our adapter
3454 pHeader 802.11 header of receiving frame
3456 Return Value:
3457 TRUE found matched tuple cache
3458 FALSE no matched found
3460 Note:
3462 ========================================================================
3464 BOOLEAN RTMPSearchTupleCache(
3465 IN PRTMP_ADAPTER pAdapter,
3466 IN PHEADER_802_11 pHeader)
3468 INT Index;
3470 for (Index = 0; Index < MAX_CLIENT; Index++)
3472 if (pAdapter->TupleCache[Index].Valid == FALSE)
3473 continue;
3475 if (RTMPEqualMemory(&pAdapter->TupleCache[Index].MAC, &pHeader->Controlhead.Addr2, 6) &&
3476 (pAdapter->TupleCache[Index].Sequence == pHeader->Sequence) &&
3477 (pAdapter->TupleCache[Index].Frag == pHeader->Frag))
3479 // DBGPRINT(RT_DEBUG_TRACE,("DUPCHECK - duplicate frame hit entry %d\n", Index));
3480 return (TRUE);
3483 return (FALSE);
3487 ========================================================================
3489 Routine Description:
3490 Update tuple cache for new received unicast frames.
3492 Arguments:
3493 pAdapter Pointer to our adapter
3494 pHeader 802.11 header of receiving frame
3496 Return Value:
3497 None
3499 Note:
3501 ========================================================================
3503 VOID RTMPUpdateTupleCache(
3504 IN PRTMP_ADAPTER pAdapter,
3505 IN PHEADER_802_11 pHeader)
3507 UCHAR Index;
3509 for (Index = 0; Index < MAX_CLIENT; Index++)
3511 if (pAdapter->TupleCache[Index].Valid == FALSE)
3513 // Add new entry
3514 NdisMoveMemory(&pAdapter->TupleCache[Index].MAC, &pHeader->Controlhead.Addr2, 6);
3515 pAdapter->TupleCache[Index].Sequence = pHeader->Sequence;
3516 pAdapter->TupleCache[Index].Frag = pHeader->Frag;
3517 pAdapter->TupleCache[Index].Valid = TRUE;
3518 pAdapter->TupleCacheLastUpdateIndex = Index;
3519 DBGPRINT(RT_DEBUG_INFO,"DUPCHECK - Add Entry %d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n",
3520 Index, pAdapter->TupleCache[Index].MAC.Octet[0], pAdapter->TupleCache[Index].MAC.Octet[1],
3521 pAdapter->TupleCache[Index].MAC.Octet[2], pAdapter->TupleCache[Index].MAC.Octet[3],
3522 pAdapter->TupleCache[Index].MAC.Octet[4], pAdapter->TupleCache[Index].MAC.Octet[5]);
3523 return;
3525 else if (RTMPEqualMemory(&pAdapter->TupleCache[Index].MAC, &pHeader->Controlhead.Addr2, 6))
3527 // Update old entry
3528 pAdapter->TupleCache[Index].Sequence = pHeader->Sequence;
3529 pAdapter->TupleCache[Index].Frag = pHeader->Frag;
3530 return;
3534 // tuple cache full, replace the first inserted one (even though it may not be
3535 // least referenced one)
3536 if (Index == MAX_CLIENT)
3538 pAdapter->TupleCacheLastUpdateIndex ++;
3539 if (pAdapter->TupleCacheLastUpdateIndex >= MAX_CLIENT)
3540 pAdapter->TupleCacheLastUpdateIndex = 0;
3541 Index = pAdapter->TupleCacheLastUpdateIndex;
3543 // replace with new entry
3544 NdisMoveMemory(&pAdapter->TupleCache[Index].MAC, &pHeader->Controlhead.Addr2, 6);
3545 pAdapter->TupleCache[Index].Sequence = pHeader->Sequence;
3546 pAdapter->TupleCache[Index].Frag = pHeader->Frag;
3547 pAdapter->TupleCache[Index].Valid = TRUE;
3548 DBGPRINT(RT_DEBUG_INFO,"DUPCHECK - replace Entry %d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n",
3549 Index, pAdapter->TupleCache[Index].MAC.Octet[0], pAdapter->TupleCache[Index].MAC.Octet[1],
3550 pAdapter->TupleCache[Index].MAC.Octet[2], pAdapter->TupleCache[Index].MAC.Octet[3],
3551 pAdapter->TupleCache[Index].MAC.Octet[4], pAdapter->TupleCache[Index].MAC.Octet[5]);
3556 ========================================================================
3558 Routine Description:
3559 Suspend MSDU transmission
3561 Arguments:
3562 pAdapter Pointer to our adapter
3564 Return Value:
3565 None
3567 Note:
3569 ========================================================================
3571 VOID RTMPSuspendMsduTransmission(
3572 IN PRTMP_ADAPTER pAdapter)
3574 //DBGPRINT(RT_DEBUG_TRACE,"SCANNING, suspend MSDU transmission ...\n");
3575 RTMP_SET_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
3579 ========================================================================
3581 Routine Description:
3582 Resume MSDU transmission
3584 Arguments:
3585 pAdapter Pointer to our adapter
3587 Return Value:
3588 None
3590 Note:
3592 ========================================================================
3594 VOID RTMPResumeMsduTransmission(
3595 IN PRTMP_ADAPTER pAdapter)
3597 //DBGPRINT(RT_DEBUG_TRACE,"SCAN done, resume MSDU transmission ...\n");
3598 RTMP_CLEAR_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
3600 // Dequeue Tx queue if Reset is not in progress
3601 if ((!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
3602 (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF)))
3604 //RTMPDeQueuePacket(pAdapter, &pAdapter->TxSwQueue0);
3605 // Call dequeue without selected queue, let the subroutine select the right priority
3606 // Tx software queue
3607 RTMPDeQueuePacket(pAdapter);
3612 ========================================================================
3614 Routine Description:
3615 Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
3617 Arguments:
3618 pRxD Pointer to the Rx descriptor
3620 Return Value:
3621 NDIS_STATUS_SUCCESS No err
3622 NDIS_STATUS_FAILURE Error
3624 Note:
3626 ========================================================================
3628 inline NDIS_STATUS RTMPCheckRxDescriptor(
3629 IN PRXD_STRUC pRxD)
3631 // Phy errors
3632 if (pRxD->PhyErr)
3633 return(NDIS_STATUS_FAILURE);
3635 // CRC errors
3636 if (pRxD->Crc)
3637 return(NDIS_STATUS_FAILURE);
3639 // Paul 04-03 for OFDM Rx length issue
3640 if (pRxD->DataByteCnt > 1600)
3641 return(NDIS_STATUS_FAILURE);
3643 return(NDIS_STATUS_SUCCESS);
3647 ========================================================================
3649 Routine Description:
3650 Apply packet filter policy, return NDIS_STATUS_FAILURE if this frame
3651 should be dropped.
3653 Arguments:
3654 pAdapter Pointer to our adapter
3655 pRxD Pointer to the Rx descriptor
3656 pHeader Pointer to the 802.11 frame header
3658 Return Value:
3659 NDIS_STATUS_SUCCESS Accept frame
3660 NDIS_STATUS_FAILURE Drop Frame
3662 Note:
3663 Maganement frame should bypass this filtering rule.
3665 ========================================================================
3667 NDIS_STATUS RTMPApplyPacketFilter(
3668 IN PRTMP_ADAPTER pAdapter,
3669 IN PRXD_STRUC pRxD,
3670 IN PHEADER_802_11 pHeader)
3672 UCHAR i;
3674 // 0. Management frame should bypass all these filtering rules.
3675 if (pHeader->Controlhead.Frame.Type == BTYPE_MGMT)
3677 return(NDIS_STATUS_SUCCESS);
3680 // 0.1 Drop all Rx frames if MIC countermeasures kicks in
3681 if (pAdapter->PortCfg.MicErrCnt >= 2)
3683 return(NDIS_STATUS_FAILURE);
3686 // 1. Drop unicast to me packet if NDIS_PACKET_TYPE_DIRECTED is FALSE
3687 if (pRxD->U2M)
3689 if (pAdapter->bAcceptDirect == FALSE)
3691 return(NDIS_STATUS_FAILURE);
3695 // 2. Drop broadcast packet if NDIS_PACKET_TYPE_BROADCAST is FALSE
3696 else if (pRxD->Bcast)
3698 if (pAdapter->bAcceptBroadcast == FALSE)
3700 return(NDIS_STATUS_FAILURE);
3704 // 3. Drop multicast packet if NDIS_PACKET_TYPE_ALL_MULTICAST is false
3705 // and NDIS_PACKET_TYPE_MULTICAST is false.
3706 // If NDIS_PACKET_TYPE_MULTICAST is true, but NDIS_PACKET_TYPE_ALL_MULTICAST is false.
3707 // We have to deal with multicast table lookup & drop not matched packets.
3708 else if (pRxD->Mcast)
3710 if (pAdapter->bAcceptAllMulticast == FALSE)
3712 if (pAdapter->bAcceptMulticast == FALSE)
3714 return(NDIS_STATUS_FAILURE);
3716 else
3718 // Selected accept multicast packet based on multicast table
3719 for (i = 0; i < pAdapter->NumberOfMcAddresses; i++)
3721 if (RTMPEqualMemory(&pHeader->Controlhead.Addr1, pAdapter->McastTable[i], ETH_LENGTH_OF_ADDRESS))
3723 break; // Matched
3727 // Not matched
3728 if (i == pAdapter->NumberOfMcAddresses)
3730 DBGPRINT(RT_DEBUG_INFO,"Drop multicast %02x:%02x:%02x:%02x:%02x:%02x\n",
3731 pHeader->Controlhead.Addr1.Octet[0], pHeader->Controlhead.Addr1.Octet[1],
3732 pHeader->Controlhead.Addr1.Octet[2], pHeader->Controlhead.Addr1.Octet[3],
3733 pHeader->Controlhead.Addr1.Octet[4], pHeader->Controlhead.Addr1.Octet[5]);
3734 return(NDIS_STATUS_FAILURE);
3736 else
3738 DBGPRINT(RT_DEBUG_INFO,"Accept multicast %02x:%02x:%02x:%02x:%02x:%02x\n",
3739 pHeader->Controlhead.Addr1.Octet[0], pHeader->Controlhead.Addr1.Octet[1],
3740 pHeader->Controlhead.Addr1.Octet[2], pHeader->Controlhead.Addr1.Octet[3],
3741 pHeader->Controlhead.Addr1.Octet[4], pHeader->Controlhead.Addr1.Octet[5]);
3747 // 4. Not U2M, not Mcast, not Bcast, must be unicast to other DA.
3748 // Since we did not implement promiscuous mode, just drop this kind of packet for now.
3749 else
3751 return(NDIS_STATUS_FAILURE);
3754 return(NDIS_STATUS_SUCCESS);
3758 ========================================================================
3760 Routine Description:
3761 Check and fine the packet waiting in SW queue with highest priority
3763 Arguments:
3764 pAdapter Pointer to our adapter
3766 Return Value:
3767 pQueue Pointer to Waiting Queue
3769 Note:
3771 ========================================================================
3773 PQUEUE_HEADER RTMPCheckTxSwQueue(
3774 IN PRTMP_ADAPTER pAdapter,
3775 OUT ULONG *Number,
3776 OUT UCHAR *AccessCategory)
3778 // Calculate total number of packets waiting in queues for Nitro mode
3779 *Number = pAdapter->TxSwQueue3.Number + pAdapter->TxSwQueue2.Number + pAdapter->TxSwQueue1.Number +
3780 pAdapter->TxSwQueue0.Number;
3782 if (pAdapter->TxSwQueue3.Head != NULL)
3784 *AccessCategory = 3;
3785 return (&pAdapter->TxSwQueue3);
3787 else if (pAdapter->TxSwQueue2.Head != NULL)
3789 *AccessCategory = 2;
3790 return (&pAdapter->TxSwQueue2);
3792 else if (pAdapter->TxSwQueue1.Head != NULL)
3794 *AccessCategory = 1;
3795 return (&pAdapter->TxSwQueue1);
3797 else if (pAdapter->TxSwQueue0.Head != NULL)
3799 *AccessCategory = 0;
3800 return (&pAdapter->TxSwQueue0);
3803 // No packet pending in Tx Sw queue
3804 *AccessCategory = 0;
3805 return (NULL);
3809 ========================================================================
3811 Routine Description:
3812 Process MIC error indication and record MIC error timer.
3814 Arguments:
3815 pAdapter Pointer to our adapter
3816 pWpaKey Pointer to the WPA key structure
3818 Return Value:
3819 None
3821 Note:
3823 ========================================================================
3825 VOID RTMPReportMicError(
3826 IN PRTMP_ADAPTER pAdapter,
3827 IN PWPA_KEY pWpaKey)
3829 ULONG Now;
3830 struct
3832 NDIS_802_11_STATUS_INDICATION Status;
3833 NDIS_802_11_AUTHENTICATION_REQUEST Request;
3834 } Report;
3836 // 0. Set Status to indicate auth error
3837 Report.Status.StatusType = Ndis802_11StatusType_Authentication;
3839 // 1. Check for Group or Pairwise MIC error
3840 if (pWpaKey->Type == PAIRWISE_KEY)
3841 Report.Request.Flags = NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR;
3842 else
3843 Report.Request.Flags = NDIS_802_11_AUTH_REQUEST_GROUP_ERROR;
3845 // 2. Copy AP MAC address
3846 NdisMoveMemory(Report.Request.Bssid, pWpaKey->BssId, 6);
3848 // 3. Calculate length
3849 Report.Request.Length = sizeof(NDIS_802_11_AUTHENTICATION_REQUEST);
3851 // 4. Record Last MIC error time and count
3852 Now = jiffies;
3853 if (pAdapter->PortCfg.MicErrCnt == 0)
3855 pAdapter->PortCfg.MicErrCnt++;
3856 pAdapter->PortCfg.LastMicErrorTime = Now;
3858 else if (pAdapter->PortCfg.MicErrCnt == 1)
3860 if ((pAdapter->PortCfg.LastMicErrorTime + (60 * HZ)) < Now)
3862 // Update Last MIC error time, this did not violate two MIC errors within 60 seconds
3863 pAdapter->PortCfg.LastMicErrorTime = Now;
3865 else
3867 pAdapter->PortCfg.LastMicErrorTime = Now;
3868 // Violate MIC error counts, MIC countermeasures kicks in
3869 pAdapter->PortCfg.MicErrCnt++;
3870 // We shall block all reception
3871 // We shall clean all Tx ring and disassoicate from AP after next EAPOL frame
3872 RTMPRingCleanUp(pAdapter, TX_RING);
3875 else
3877 // MIC error count >= 2
3878 // This should not happen
3883 #ifdef BIG_ENDIAN
3885 ========================================================================
3887 Routine Description:
3888 Endian conversion of Tx/Rx descriptor .
3890 Arguments:
3891 pAdapter Pointer to our adapter
3892 pData Pointer to Tx/Rx descriptor
3893 DescriptorType Direction of the frame
3895 Return Value:
3896 None
3898 Note:
3899 Call this function when read or update descriptor
3900 ========================================================================
3902 inline VOID RTMPDescriptorEndianChange(
3903 IN PUCHAR pData,
3904 IN ULONG DescriptorType)
3906 *((ULONG *)(pData + 40)) = SWAP32(*((ULONG *)(pData + 40))); // Byte 10
3907 if(DescriptorType == TYPE_TXD)
3908 *((ULONG *)(pData + 8)) = SWAP32(*((ULONG *)(pData + 8))); // Byte 2
3909 *(ULONG *)pData = SWAP32(*(ULONG *)pData); // Byte 0; this must be swapped last
3913 ========================================================================
3915 Routine Description:
3916 Endian conversion of all kinds of 802.11 frames .
3918 Arguments:
3919 pAdapter Pointer to our adapter
3920 pData Pointer to the 802.11 frame structure
3921 Dir Direction of the frame
3922 FromRxDoneInt Caller is from RxDone interrupt
3924 Return Value:
3925 None
3927 Note:
3928 Call this function when read or update buffer data
3929 ========================================================================
3931 VOID RTMPFrameEndianChange(
3932 IN PRTMP_ADAPTER pAdapter,
3933 IN PUCHAR pData,
3934 IN ULONG Dir,
3935 IN BOOLEAN FromRxDoneInt)
3937 PMACHDR pFrame;
3938 PUCHAR pMacHdr;
3940 // swab 16 bit fields - Frame Control field
3941 if(Dir == DIR_READ)
3943 *(USHORT *)pData = SWAP16(*(USHORT *)pData);
3946 pFrame = (PMACHDR) pData;
3947 pMacHdr = (PUCHAR) pFrame;
3949 // swab 16 bit fields - Duration/ID field
3950 *(USHORT *)(pMacHdr + 2) = SWAP16(*(USHORT *)(pMacHdr + 2));
3952 // swab 16 bit fields - Sequence Control field
3953 *(USHORT *)(pMacHdr + 22) = SWAP16(*(USHORT *)(pMacHdr + 22));
3955 if(pFrame->Type == BTYPE_MGMT)
3957 switch(pFrame->SubType)
3959 case SUBTYPE_ASSOC_REQ:
3960 case SUBTYPE_REASSOC_REQ:
3961 // swab 16 bit fields - CapabilityInfo field
3962 pMacHdr += MAC_HDR_LEN;
3963 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3965 // swab 16 bit fields - Listen Interval field
3966 pMacHdr += 2;
3967 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3968 break;
3970 case SUBTYPE_ASSOC_RSP:
3971 case SUBTYPE_REASSOC_RSP:
3972 // swab 16 bit fields - CapabilityInfo field
3973 pMacHdr += MAC_HDR_LEN;
3974 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3976 // swab 16 bit fields - Status Code field
3977 pMacHdr += 2;
3978 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3980 // swab 16 bit fields - AID field
3981 pMacHdr += 2;
3982 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3983 break;
3985 case SUBTYPE_AUTH:
3986 // If from RTMPHandleRxDoneInterrupt routine, it is still a encrypt format.
3987 // The convertion is delayed to RTMPHandleDecryptionDoneInterrupt.
3988 if(!FromRxDoneInt && pAdapter->NeedSwapToLittleEndian == TRUE)
3990 // swab 16 bit fields - Auth Alg No. field
3991 pMacHdr += MAC_HDR_LEN;
3992 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3994 // swab 16 bit fields - Auth Seq No. field
3995 pMacHdr += 2;
3996 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3998 // swab 16 bit fields - Status Code field
3999 pMacHdr += 2;
4000 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
4002 break;
4004 case SUBTYPE_BEACON:
4005 case SUBTYPE_PROBE_RSP:
4006 // swab 16 bit fields - BeaconInterval field
4007 pMacHdr += MAC_HDR_LEN + TIMESTAMP_LEN;
4008 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
4010 // swab 16 bit fields - CapabilityInfo field
4011 pMacHdr += sizeof(USHORT);
4012 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
4013 break;
4015 case SUBTYPE_DEAUTH:
4016 case SUBTYPE_DISASSOC:
4017 // swab 16 bit fields - Reason code field
4018 pMacHdr += MAC_HDR_LEN;
4019 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
4020 break;
4023 else if( pFrame->Type == BTYPE_DATA )
4026 else if(pFrame->Type == BTYPE_CNTL)
4029 else
4031 DBGPRINT(RT_DEBUG_ERROR,"Invalid Frame Type!!!\n");
4034 // swab 16 bit fields - Frame Control
4035 if(Dir == DIR_WRITE)
4037 *(USHORT *)pData = SWAP16(*(USHORT *)pData);
4040 #endif