MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / net / wireless / rtlink / rtmp_data.c
blob4fb6417d42b78bdaa1da75bd6c7ed9e589d1532e
1 /*************************************************************************
2 * Ralink Tech Inc. *
3 * 4F, No. 2 Technology 5th Rd. *
4 * Science-based Industrial Park *
5 * Hsin-chu, Taiwan, R.O.C. *
6 * *
7 * (c) Copyright 2002, Ralink Technology, Inc. *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
18 * *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program; if not, write to the *
21 * Free Software Foundation, Inc., *
22 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
23 * *
24 *************************************************************************
26 Module Name:
27 rtmp_data.c
29 Abstract:
30 Data path subroutines
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs
36 HK Initial
37 Paul 10/02/02 Merge & modify
38 John 02/25/03 Modified for RT2560
40 #include "rt_config.h"
42 #define ISR_JUST_LOCK 1 // add by Victor Yu. 05-23-2006
44 static UCHAR SNAP_802_1H[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
45 static UCHAR SNAP_BRIDGE_TUNNEL[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8};
46 static UCHAR EAPOL[] = {0x88, 0x8e};
48 static UCHAR IPX[] = {0x81, 0x37};
49 static UCHAR APPLE_TALK[] = {0x80, 0xf3};
50 static UCHAR PlcpSignal[12] = {
51 0, /* RATE_1 */ 1, /* RATE_2 */ 2, /* RATE_5_5 */ 3, /* RATE_11 */ // see BBP spec
52 11, /* RATE_6 */ 15, /* RATE_9 */ 10, /* RATE_12 */ 14, /* RATE_18 */ // see IEEE802.11a-1999 p.14
53 9, /* RATE_24 */ 13, /* RATE_36 */ 8, /* RATE_48 */ 12 /* RATE_54 */ }; // see IEEE802.11a-1999 p.14
55 #define COLLECT_RX_ANTENNA_AVERAGE_RSSI(_pAd, _RxAnt, _rssi) \
56 { \
57 USHORT AvgRssi; \
58 if (_RxAnt.PrimaryInUsed) \
59 { \
60 AvgRssi = _RxAnt.AvgRssi[_RxAnt.PrimaryRxAnt]; \
61 if (AvgRssi > 0) \
62 AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi; \
63 else \
64 AvgRssi = _rssi << 3; \
65 _RxAnt.AvgRssi[_RxAnt.PrimaryRxAnt] = AvgRssi; \
66 } \
67 else \
68 { \
69 AvgRssi = _RxAnt.AvgRssi[_RxAnt.SecondaryRxAnt]; \
70 _RxAnt.RcvPktNumWhenEvaluate++;\
71 if ((AvgRssi > 0) && (_RxAnt.FirstPktArrivedWhenEvaluate)) \
72 AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi; \
73 else \
74 { \
75 _RxAnt.FirstPktArrivedWhenEvaluate = TRUE; \
76 AvgRssi = _rssi << 3; \
77 DBGPRINT(RT_DEBUG_TRACE,"Reset RSSI(%d) when first packet is rcved \n",_rssi-_pAd->PortCfg.RssiToDbm); \
78 } \
79 _RxAnt.AvgRssi[_RxAnt.SecondaryRxAnt] = AvgRssi; \
80 } \
84 ========================================================================
86 Routine Description:
87 Process RxDone interrupt, running in DPC level
89 Arguments:
90 pAdapter Pointer to our adapter
92 Return Value:
93 None
95 Note:
96 This routine has to maintain Rx ring read pointer.
97 ========================================================================
99 VOID RTMPHandleRxDoneInterrupt(
100 IN PRTMP_ADAPTER pAdapter)
102 PRXD_STRUC pRxD;
103 #ifdef BIG_ENDIAN
104 PRXD_STRUC pDestRxD;
105 RXD_STRUC RxD;
106 #endif
107 PHEADER_802_11 pHeader;
108 PUCHAR pData;
109 PUCHAR pDestMac, pSrcMac;
110 UCHAR Count;
111 UCHAR KeyIdx;
112 PWPA_KEY pWpaKey;
113 NDIS_STATUS Status;
114 BOOLEAN bDropFrame;
115 ULONG RegValue;//, Address;
116 ULONG HwDecryptIndex;
117 #ifndef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
118 ULONG IrqFlags;
119 #endif
120 #ifdef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
121 spin_lock(&pAdapter->RxRingLock);
122 #else
123 // Make sure Rx ring resource won't be used by other threads
124 NdisAcquireSpinLock(&pAdapter->RxRingLock, IrqFlags);
125 #endif
127 // Verify Hardware Decryption pointer with Software Decryption pointer
128 RTMP_IO_READ32(pAdapter, SECCSR0, &RegValue);
129 HwDecryptIndex = (RegValue - pAdapter->RxRing[0].pa_addr) / RING_DESCRIPTOR_SIZE;
130 #if 0
131 Address = pAdapter->RxRing[pAdapter->CurDecryptIndex].pa_addr;
132 if (Address != RegValue)
134 DBGPRINT(RT_DEBUG_ERROR,"Decrypt pointer not matched SW = 0x%x, HW = 0x%x\n", Address, RegValue);
135 DBGPRINT(RT_DEBUG_ERROR,"Sw Decr Ptr = %d, Rx ptr = %d Hw ptr = %d\n",
136 pAdapter->CurDecryptIndex, pAdapter->CurRxIndex, HwDecryptIndex);
138 #endif
139 Count = 0;
142 // Point to Rx indexed rx ring descriptor
143 #ifndef BIG_ENDIAN
144 pRxD = (PRXD_STRUC) pAdapter->RxRing[pAdapter->CurRxIndex].va_addr;
145 #else
146 pDestRxD = (PRXD_STRUC) pAdapter->RxRing[pAdapter->CurRxIndex].va_addr;
147 RxD = *pDestRxD;
148 pRxD = &RxD;
149 RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
150 #endif
151 // Initialize drop frame flag
152 bDropFrame = FALSE;
154 // In case of false alarm or processed at last instance
155 if (pRxD->Owner != DESC_OWN_HOST)
157 break;
160 // Decrypt engine stuck
161 if (pRxD->CipherOwner != DESC_OWN_HOST)
163 pAdapter->RalinkCounters.RxRingErrCount++;
164 break;
167 #ifdef RALINK_ATE
168 if(pAdapter->ate.Mode == ATE_RXFRAME)
170 bDropFrame = TRUE;
172 #endif //#ifdef RALINK_ATE
174 // Point to Rx ring buffer where stores the real data frame
175 pData = (PUCHAR) (pAdapter->RxRing[pAdapter->CurRxIndex].va_data_addr);
176 // Cast to 802.11 header for flags checking
177 pHeader = (PHEADER_802_11) pData;
179 #ifdef BIG_ENDIAN
180 RTMPFrameEndianChange(pAdapter, (PUCHAR)pHeader, DIR_READ, TRUE);
181 #endif
183 // Increase Total receive byte counter after real data received no mater any error or not
184 pAdapter->RalinkCounters.ReceivedByteCount += pRxD->DataByteCnt;
186 // Check for all RxD errors
187 Status = RTMPCheckRxDescriptor(pRxD);
189 // Apply packet filtering rule based on microsoft requirements.
190 if (Status == NDIS_STATUS_SUCCESS)
191 Status = RTMPApplyPacketFilter(pAdapter, pRxD, pHeader);
193 // Add receive counters
194 if (Status == NDIS_STATUS_SUCCESS)
196 // Increase 802.11 counters & general receive counters
197 INC_COUNTER(pAdapter->WlanCounters.ReceivedFragmentCount);
199 // collect current antenna's average RSSI for software-based RX Antenna diversity
200 if ((pRxD->U2M)
201 || ((pHeader->Controlhead.Frame.Subtype == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL(&pAdapter->PortCfg.Bssid, &pHeader->Controlhead.Addr2))))
203 //DBGPRINT(RT_DEBUG_TRACE, "COLLECT_RSSI:(%d)\n", pRxD->BBR1 - pAdapter->PortCfg.RssiToDbm);
204 pAdapter->PortCfg.NumOfAvgRssiSample ++;
205 COLLECT_RX_ANTENNA_AVERAGE_RSSI(pAdapter, pAdapter->PortCfg.RxAnt, pRxD->BBR1);
208 else
210 // Increase general counters
211 pAdapter->Counters.RxErrors++;
214 // Check for retry bit, if this bit is on, search the cache with SA & sequence
215 // as index, if matched, discard this frame, otherwise, update cache
216 // This check only apply to unicast data & management frames
217 if ((Status == NDIS_STATUS_SUCCESS) && (pRxD->U2M) && (pHeader->Controlhead.Frame.Type != BTYPE_CNTL))
219 if (pHeader->Controlhead.Frame.Retry)
221 if (RTMPSearchTupleCache(pAdapter, pHeader) == TRUE)
223 // Found retry frame in tuple cache, Discard this frame / fragment
224 // Increase 802.11 counters
225 INC_COUNTER(pAdapter->WlanCounters.FrameDuplicateCount);
226 Status = NDIS_STATUS_FAILURE;
228 else
229 RTMPUpdateTupleCache(pAdapter, pHeader);
231 else // Update Tuple Cache
232 RTMPUpdateTupleCache(pAdapter, pHeader);
236 // Do RxD release operation for all failure frames
238 pRxD->CipherAlg = CIPHER_NONE;
239 if (Status == NDIS_STATUS_SUCCESS)
241 // pData : Pointer skip the first 24 bytes, 802.11 HEADER
242 pData += LENGTH_802_11;
245 // Start of main loop to parse receiving frames.
246 // The sequence will be Type first, then subtype...
248 switch (pHeader->Controlhead.Frame.Type)
250 // Frame with data type
251 case BTYPE_DATA:
252 // Drop not my BSS frame
253 if (INFRA_ON(pAdapter))
255 // Infrastructure mode, check address 2 for BSSID
256 if (!RTMPEqualMemory(&pHeader->Controlhead.Addr2, &pAdapter->PortCfg.Bssid, 6))
258 // Receive frame not my BSSID
259 bDropFrame = TRUE;
260 break;
263 else // Ad-Hoc mode or Not associated
265 // Ad-Hoc mode, check address 3 for BSSID
266 if (!RTMPEqualMemory(&pHeader->Addr3, &pAdapter->PortCfg.Bssid, 6))
268 // Receive frame not my BSSID
269 bDropFrame = TRUE;
270 break;
273 // Drop frame from AP while we are in Ad-hoc mode or not associated
274 if (pHeader->Controlhead.Frame.FrDs)
276 bDropFrame = TRUE;
277 break;
281 // Drop Null data frame, or CF with NULL data frame
282 if ((pHeader->Controlhead.Frame.Subtype == SUBTYPE_NULL_FUNC) ||
283 (pHeader->Controlhead.Frame.Subtype == SUBTYPE_CFACK) ||
284 (pHeader->Controlhead.Frame.Subtype == SUBTYPE_CFPOLL) ||
285 (pHeader->Controlhead.Frame.Subtype == SUBTYPE_CFACK_CFPOLL))
287 bDropFrame = TRUE;
288 break;
291 // Process Multicast data frame
292 if (pRxD->Mcast)
294 // Multicast 802.11 Counter
295 INC_COUNTER(pAdapter->WlanCounters.MulticastReceivedFrameCount);
296 DBGPRINT(RT_DEBUG_INFO,"Receiving multicast frame\n");
299 // Init WPA Key to NULL
300 pWpaKey = (PWPA_KEY) NULL;
302 // Find the WPA key, either Group or Pairwise Key
303 if ((pAdapter->PortCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pHeader->Controlhead.Frame.Wep))
305 INT idx;
307 // First lookup the DA, if it's a group address, use GROUP key
308 if (pRxD->Bcast || pRxD->Mcast)
311 idx = (*(pData + 3) & 0xc0) >> 6;
312 if ((pAdapter->PortCfg.GroupKey[idx].KeyLen != 0) &&
313 ((INFRA_ON(pAdapter) && (NdisEqualMemory(&pHeader->Controlhead.Addr2, &pAdapter->PortCfg.Bssid, 6))) ||
314 (ADHOC_ON(pAdapter) && (NdisEqualMemory(&pHeader->Addr3, &pAdapter->PortCfg.Bssid, 6)))))
316 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.GroupKey[idx];
317 pWpaKey->Type = GROUP_KEY;
318 DBGPRINT(RT_DEBUG_INFO, "Rx Use Group Key %d\n", idx);
321 // Try to find the Pairwise Key
322 else
324 for (idx = 0; idx < PAIRWISE_KEY_NO; idx++)
326 if ((NdisEqualMemory(&pHeader->Controlhead.Addr2, pAdapter->PortCfg.PairwiseKey[idx].BssId, 6)) &&
327 (pAdapter->PortCfg.PairwiseKey[idx].KeyLen != 0))
329 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.PairwiseKey[idx];
330 pWpaKey->Type = PAIRWISE_KEY;
331 DBGPRINT(RT_DEBUG_INFO, "Rx Use Pairwise Key\n");
332 break;
335 #if 1
336 // Use default Group Key if there is no Pairwise key present
337 if ((pWpaKey == NULL) && (pAdapter->PortCfg.GroupKey[pAdapter->PortCfg.DefaultKeyId].KeyLen != 0))
339 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.GroupKey[pAdapter->PortCfg.DefaultKeyId];
340 pWpaKey->Type = GROUP_KEY;
341 DBGPRINT(RT_DEBUG_INFO, "Rx Use Group Key\n");
343 #endif
347 // Process Broadcast & Multicast data frame
348 if (pRxD->Bcast || pRxD->Mcast)
350 // Drop Mcast / Bcast frame with fragment bit on
351 if (pHeader->Controlhead.Frame.MoreFrag)
353 DBGPRINT(RT_DEBUG_ERROR,"Receiving multicast frame with fragment bit on\n");
354 Status = NDIS_STATUS_FAILURE;
355 bDropFrame = TRUE;
356 break;
359 // Filter out Bcast frame which AP relayed for us
360 if (pHeader->Controlhead.Frame.FrDs && RTMPEqualMemory(&pHeader->Addr3, pAdapter->CurrentAddress, 6))
362 Status = NDIS_STATUS_FAILURE;
363 bDropFrame = TRUE;
364 break;
367 // WEP encrypted frame
368 if (pHeader->Controlhead.Frame.Wep)
370 // Check our WEP setting, if no WEP turning on, just drop this frame
371 if (pAdapter->PortCfg.WepStatus == Ndis802_11Encryption1Enabled) // WEP
373 KeyIdx = (*(pData + 3) & 0xc0) >> 6;
374 NdisMoveMemory((PUCHAR) &pRxD->Iv, pData, 4); //Get WEP IV
375 NdisMoveMemory(pRxD->Key, pAdapter->PortCfg.SharedKey[KeyIdx].Key, pAdapter->PortCfg.SharedKey[KeyIdx].KeyLen);
376 if (pAdapter->PortCfg.SharedKey[KeyIdx].KeyLen == 5)
377 pRxD->CipherAlg = CIPHER_WEP64;
378 else
379 pRxD->CipherAlg = CIPHER_WEP128;
381 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) && (pWpaKey != NULL)) // TKIP
383 UCHAR Eiv_Tmp[4];
385 NdisMoveMemory((PUCHAR) &pRxD->Iv, pData, 4); //Get WEP IV
386 // Swap EIV byte order, due to ASIC's bug.
387 Eiv_Tmp[0] = *(pData + 7);
388 Eiv_Tmp[1] = *(pData + 6);
389 Eiv_Tmp[2] = *(pData + 5);
390 Eiv_Tmp[3] = *(pData + 4);
391 NdisMoveMemory((PUCHAR) &pRxD->Eiv, Eiv_Tmp, 4); //Get WEP EIV
392 // Copy TA into RxD
393 NdisMoveMemory(pRxD->TA, &pHeader->Controlhead.Addr2, 6);
394 KeyIdx = (*(pData + 3) & 0xc0) >> 6;
395 NdisMoveMemory(pRxD->Key, pWpaKey->Key, 16);
396 pRxD->CipherAlg = CIPHER_TKIP;
398 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled) && (pWpaKey != NULL)) // AES
400 NdisMoveMemory((PUCHAR) &pRxD->Iv, pData, 4); //Get WEP IV
401 NdisMoveMemory((PUCHAR) &pRxD->Eiv, (pData + 4), 4); //Get WEP EIV
402 // Copy TA into RxD
403 NdisMoveMemory(pRxD->TA, &pHeader->Controlhead.Addr2, 6);
404 KeyIdx = (*(pData + 3) & 0xc0) >> 6;
405 NdisMoveMemory(pRxD->Key, pWpaKey->Key, 16);
406 pRxD->CipherAlg = CIPHER_AES;
408 else
410 // Add error counter
411 Status = NDIS_STATUS_FAILURE;
412 bDropFrame = TRUE;
413 break;
416 else // Not encrypted frames
418 pRxD->CipherAlg = CIPHER_NONE;
422 // Begin process unicast to me frame
423 else if (pRxD->U2M)
425 // Send PS-Poll for AP to send next data frame
426 if ((pHeader->Controlhead.Frame.MoreData) && INFRA_ON(pAdapter) && (pAdapter->PortCfg.Psm == PWR_SAVE))
428 EnqueuePsPoll(pAdapter);
429 DBGPRINT(RT_DEBUG_TRACE, "Sending PS-POLL\n");
433 // Begin frame processing
435 pDestMac = (PUCHAR) &(pHeader->Controlhead.Addr1); // DA is always address 1
436 if (INFRA_ON(pAdapter)) // For infrastructure, SA is address 3
437 pSrcMac = (PUCHAR) &(pHeader->Addr3);
438 else // For IBSS mode, SA is address 2
439 pSrcMac = (PUCHAR) &(pHeader->Controlhead.Addr2);
441 // WEP encrypted frame
442 if (pAdapter->PortCfg.WepStatus == Ndis802_11Encryption1Enabled) // WEP
444 if (pHeader->Controlhead.Frame.Wep)
446 KeyIdx = (*(pData + 3) & 0xc0) >> 6;
448 NdisMoveMemory((PUCHAR) &pRxD->Iv, pData, 4); //Get WEP IV
449 NdisMoveMemory(pRxD->Key, pAdapter->PortCfg.SharedKey[KeyIdx].Key, pAdapter->PortCfg.SharedKey[KeyIdx].KeyLen);
450 if (pAdapter->PortCfg.SharedKey[KeyIdx].KeyLen == 5)
451 pRxD->CipherAlg = CIPHER_WEP64;
452 else
453 pRxD->CipherAlg = CIPHER_WEP128;
455 else if ((pAdapter->PortCfg.PrivacyFilter == Ndis802_11PrivFilter8021xWEP) &&
456 (pHeader->Frag == 0))
458 // Check 802.1x frame, if not drop it.
459 if (!RTMPEqualMemory(EAPOL, pData + 6, 2))
461 // Not 802.1X frames
462 // Add error counter
463 Status = NDIS_STATUS_FAILURE;
464 bDropFrame = TRUE;
465 break;
469 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) && (pWpaKey != NULL)) // TKIP
471 if (pHeader->Controlhead.Frame.Wep)
473 UCHAR Eiv_Tmp[4];
475 NdisMoveMemory((PUCHAR) &pRxD->Iv, pData, 4); //Get WEP IV
476 // Swap EIV byte order, due to ASIC's bug.
477 Eiv_Tmp[0] = *(pData + 7);
478 Eiv_Tmp[1] = *(pData + 6);
479 Eiv_Tmp[2] = *(pData + 5);
480 Eiv_Tmp[3] = *(pData + 4);
481 NdisMoveMemory((PUCHAR) &pRxD->Eiv, Eiv_Tmp, 4); //Get WEP EIV
482 KeyIdx = (*(pData + 3) & 0xc0) >> 6;
483 // Copy TA into RxD
484 NdisMoveMemory(pRxD->TA, &pHeader->Controlhead.Addr2, 6);
485 NdisMoveMemory(pRxD->Key, pWpaKey->Key, 16);
486 pRxD->CipherAlg = CIPHER_TKIP;
488 else if ((pAdapter->PortCfg.PrivacyFilter == Ndis802_11PrivFilter8021xWEP) &&
489 (pHeader->Frag == 0))
491 // Check 802.1x frame, if not drop it.
492 if (!RTMPEqualMemory(EAPOL, pData + 6, 2))
494 // Not 802.1X frames
495 // Add error counter
496 Status = NDIS_STATUS_FAILURE;
497 bDropFrame = TRUE;
498 break;
502 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled) && (pWpaKey != NULL)) // AES
504 if (pHeader->Controlhead.Frame.Wep)
506 NdisMoveMemory((PUCHAR) &pRxD->Iv, pData, 4); //Get WEP IV
507 NdisMoveMemory((PUCHAR) &pRxD->Eiv, (pData + 4), 4); //Get WEP EIV
508 // Copy TA into RxD
509 NdisMoveMemory(pRxD->TA, &pHeader->Controlhead.Addr2, 6);
510 KeyIdx = (*(pData + 3) & 0xc0) >> 6;
511 NdisMoveMemory(pRxD->Key, pWpaKey->Key, 16);
512 pRxD->CipherAlg = CIPHER_AES;
514 else if ((pAdapter->PortCfg.PrivacyFilter == Ndis802_11PrivFilter8021xWEP) &&
515 (pHeader->Frag == 0))
517 // Check 802.1x frame, if not drop it.
518 if (!RTMPEqualMemory(EAPOL, pData + 6, 2))
520 // Not 802.1X frames
521 // Add error counter
522 Status = NDIS_STATUS_FAILURE;
523 bDropFrame = TRUE;
524 break;
528 else if (pHeader->Controlhead.Frame.Wep)
530 // Drop WEP frame when PrivacyInvoked is FALSE
531 Status = NDIS_STATUS_FAILURE;
532 bDropFrame = TRUE;
533 break;
535 else // Not encryptrd frames
537 pRxD->CipherAlg = CIPHER_NONE;
540 break;
542 case BTYPE_MGMT:
543 // Always None encrypted
544 pRxD->CipherAlg = CIPHER_NONE;
545 break;
547 case BTYPE_CNTL:
548 // Ignore ???
549 bDropFrame = TRUE;
550 break;
552 default :
553 bDropFrame = TRUE;
554 break;
557 else
558 bDropFrame = TRUE;
560 // Packet will still do NULL cipher operation and drop afterward
561 if (bDropFrame == TRUE)
563 pRxD->Drop = 1;
564 pRxD->CipherAlg = CIPHER_NONE;
566 else
568 pRxD->Drop = 0;
569 pRxD->IvOffset = LENGTH_802_11;
572 pRxD->CipherOwner = DESC_OWN_NIC;
574 #ifdef BIG_ENDIAN
575 RTMPFrameEndianChange(pAdapter, (PUCHAR)pHeader, DIR_WRITE, TRUE);
576 RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
577 //*pDestRxD = RxD;
578 WriteBackToDescriptor((PUCHAR)pDestRxD, (PUCHAR)pRxD, TRUE, TYPE_RXD);
579 #endif
581 pAdapter->CurRxIndex++;
582 if (pAdapter->CurRxIndex >= RX_RING_SIZE)
584 pAdapter->CurRxIndex = 0;
586 Count++;
588 pAdapter->RalinkCounters.RxCount ++;
590 } while (Count < MAX_RX_PROCESS);
592 // Kick Decrypt Control Register, based on ASIC's implementation
593 // We have to kick decrypt & encrypt every frame.
594 RTMP_IO_WRITE32(pAdapter, SECCSR0, 0x1);
595 #ifdef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
596 spin_unlock(&pAdapter->RxRingLock);
597 #else
598 // Make sure to release Rx ring resource
599 NdisReleaseSpinLock(&pAdapter->RxRingLock, IrqFlags);
600 #endif
604 ========================================================================
606 Routine Description:
607 Process TxRing TxDone interrupt, running in DPC level
609 Arguments:
610 Adapter Pointer to our adapter
612 Return Value:
613 None
615 Note:
617 ========================================================================
619 VOID RTMPHandleTxRingTxDoneInterrupt(
620 IN PRTMP_ADAPTER pAdapter)
622 PTXD_STRUC pTxD;
623 #ifdef BIG_ENDIAN
624 PTXD_STRUC pDestTxD;
625 TXD_STRUC TxD;
626 #endif
627 UCHAR Count;
628 #ifndef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
629 ULONG IrqFlags;
630 #endif
631 #ifdef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
632 spin_lock(&pAdapter->TxRingLock);
633 #else
634 // Make sure Tx ring resource won't be used by other threads
635 NdisAcquireSpinLock(&pAdapter->TxRingLock, IrqFlags);
636 #endif
637 Count = 0;
640 #ifndef BIG_ENDIAN
641 pTxD = (PTXD_STRUC) (pAdapter->TxRing[pAdapter->NextTxDoneIndex].va_addr);
642 #else
643 pDestTxD = (PTXD_STRUC) (pAdapter->TxRing[pAdapter->NextTxDoneIndex].va_addr);
644 TxD = *pDestTxD;
645 pTxD = &TxD;
646 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
647 #endif
649 if ((pTxD->Owner == DESC_OWN_NIC) || (pTxD->CipherOwn == DESC_OWN_NIC) || (pTxD->Valid == FALSE))
651 break;
654 RTMPHardTransmitDone(
655 pAdapter,
656 pTxD,
657 pAdapter->TxRing[pAdapter->NextTxDoneIndex].FrameType);
659 // It might happend with no Ndis packet to indicate back to upper layer
660 // Clear for NdisSendComplete request
661 pTxD->Valid = FALSE;
663 // Increase Total transmit byte counter after real data sent out
664 pAdapter->RalinkCounters.TransmittedByteCount += pTxD->DataByteCnt;
666 #ifdef BIG_ENDIAN
667 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
668 *pDestTxD = TxD;
669 #endif
671 pAdapter->NextTxDoneIndex++;
672 if (pAdapter->NextTxDoneIndex >= TX_RING_SIZE)
674 pAdapter->NextTxDoneIndex = 0;
676 } while (++Count < MAX_TX_PROCESS);
678 #ifdef RALINK_ATE
679 if((pAdapter->ate.Mode == ATE_TXCONT) || (pAdapter->ate.Mode == ATE_TXCARR) || ((pAdapter->ate.Mode == ATE_TXFRAME)))
681 if (pAdapter->ate.TxDoneCount < pAdapter->ate.TxCount)
683 pAdapter->ate.TxDoneCount++;
684 DBGPRINT(RT_DEBUG_INFO, "pAdapter->ate.TxDoneCount = %d, Preamble=%d\n", pAdapter->ate.TxDoneCount, pAdapter->PortCfg.TxPreambleInUsed);
685 pTxD = (PTXD_STRUC)pAdapter->TxRing[pAdapter->CurEncryptIndex].va_addr;
687 RTMPWriteTxDescriptor(pTxD, TRUE, CIPHER_NONE, FALSE, FALSE, FALSE,
688 SHORT_RETRY, IFS_BACKOFF, pAdapter->ate.TxRate, 4,
689 pAdapter->ate.TxLength, Rt802_11PreambleLong, 0);
691 pAdapter->CurEncryptIndex++;
692 if (pAdapter->CurEncryptIndex >= TX_RING_SIZE)
694 pAdapter->CurEncryptIndex = 0;
697 RTMP_IO_WRITE32(pAdapter, SECCSR1, 0x1);
699 else if (pAdapter->ate.Mode == ATE_TXFRAME)
701 DBGPRINT(RT_DEBUG_TRACE, "ATE TXFRAME completed!\n");
704 #endif //#ifdef RALINK_ATE
705 #ifdef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
706 spin_unlock(&pAdapter->TxRingLock);
707 #else
708 // Make sure to release Tx ring resource
709 NdisReleaseSpinLock(&pAdapter->TxRingLock, IrqFlags);
710 #endif
711 if(pAdapter->bNetDeviceStopQueue)
713 if(pAdapter->TxSwQueue0.Number < (MAX_PACKETS_IN_QUEUE >> 2))
715 DBGPRINT(RT_DEBUG_TRACE, "NetDevice start queue!!!\n\n");
716 pAdapter->bNetDeviceStopQueue = FALSE;
717 netif_start_queue(pAdapter->net_dev);
721 // Some Tx ring resource freed, check for pending send frame for hard transmit
722 if ((!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
723 (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF)) &&
724 (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS)))
726 // RTMPDeQueuePacket(pAdapter, &pAdapter->TxSwQueue0);
727 // Call dequeue without selected queue, let the subroutine select the right priority
728 // Tx software queue
729 RTMPDeQueuePacket(pAdapter);
734 ========================================================================
736 Routine Description:
737 Process Priority ring TxDone interrupt, running in DPC level
739 Arguments:
740 Adapter Pointer to our adapter
742 Return Value:
743 None
745 Note:
747 ========================================================================
749 VOID RTMPHandlePrioRingTxDoneInterrupt(
750 IN PRTMP_ADAPTER pAdapter)
752 PTXD_STRUC pTxD;
753 #ifdef BIG_ENDIAN
754 PTXD_STRUC pDestTxD;
755 TXD_STRUC TxD;
756 #endif
757 UCHAR Count;
758 #if 0 // mask by Victor Yu. 05-18-2006
759 PMGMT_STRUC pMgmt;
760 #endif
761 #ifndef ISR_JUST_LOCK // add by Victor yu. 05-23-2006
762 ULONG IrqFlags;
763 #endif
764 #ifdef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
765 spin_lock(&pAdapter->PrioRingLock);
766 #else
767 // Make sure Prio ring resource won't be used by other threads
768 NdisAcquireSpinLock(&pAdapter->PrioRingLock, IrqFlags);
769 #endif
770 Count = 0;
773 #ifndef BIG_ENDIAN
774 pTxD = (PTXD_STRUC) (pAdapter->PrioRing[pAdapter->NextPrioDoneIndex].va_addr);
775 #else
776 pDestTxD = (PTXD_STRUC) (pAdapter->PrioRing[pAdapter->NextPrioDoneIndex].va_addr);
777 TxD = *pDestTxD;
778 pTxD = &TxD;
779 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
780 #endif
782 // Check for the descriptor ownership
783 if ((pTxD->Owner == DESC_OWN_NIC) || (pTxD->Valid == FALSE))
785 #ifdef BIG_ENDIAN
786 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
787 *pDestTxD = TxD;
788 #endif
789 break;
792 // No need to put in reply for MLME
793 RTMPHardTransmitDone(
794 pAdapter,
795 pTxD,
796 pAdapter->PrioRing[pAdapter->NextPrioDoneIndex].FrameType);
798 // It might happend with no Ndis packet to indicate back to upper layer
799 pTxD->Valid = FALSE;
801 // Increase Total transmit byte counter after real data sent out
802 pAdapter->RalinkCounters.TransmittedByteCount += pTxD->DataByteCnt;
804 #ifdef BIG_ENDIAN
805 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
806 *pDestTxD = TxD;
807 #endif
809 pAdapter->NextPrioDoneIndex++;
810 if (pAdapter->NextPrioDoneIndex >= PRIO_RING_SIZE)
812 pAdapter->NextPrioDoneIndex = 0;
814 } while (++Count < MAX_TX_PROCESS);
815 #ifdef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
816 spin_unlock(&pAdapter->PrioRingLock);
817 #else
818 // Make sure to release Prio ring resource
819 NdisReleaseSpinLock(&pAdapter->PrioRingLock, IrqFlags);
820 #endif
821 #if 0 // don't need to do this, mask by Victor Yu. 05-18-2006
822 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF))
823 return;
824 #endif
825 // Scott: 2005-05-04
826 // This IRQ handler might interrupt MiniportMMRequest(), and cause
827 // the MgmtRing[] massed up, since MgmtRing[] is not protected by
828 // any spinlock or semaphore.
829 // Remove below code shouldn't affect the MgmtRing[], since in
830 // MiniportMMRequest(), release of MgmtRing[] will be processed there, too.
831 #if 0
832 // Scott: 2004-12-03
833 if (pAdapter->PushMgmtIndex != pAdapter->PopMgmtIndex)
835 if (RTMPFreeDescriptorRequest(pAdapter, PRIO_RING, 1) == NDIS_STATUS_SUCCESS)
837 pMgmt = (PMGMT_STRUC) &pAdapter->MgmtRing[pAdapter->PopMgmtIndex];
838 if (pMgmt->Valid == TRUE)
840 MlmeHardTransmit(pAdapter, pMgmt->pBuffer, pMgmt->Length);
841 MlmeFreeMemory(pAdapter, pMgmt->pBuffer);
842 pMgmt->Valid = FALSE;
843 NdisAcquireSpinLock(&pAdapter->PrioRingLock, IrqFlags);
844 pAdapter->PopMgmtIndex++;
845 pAdapter->MgmtQueueSize--;
846 if (pAdapter->PopMgmtIndex >= MGMT_RING_SIZE)
848 pAdapter->PopMgmtIndex = 0;
850 NdisReleaseSpinLock(&pAdapter->PrioRingLock, IrqFlags);
854 #endif
858 ========================================================================
860 Routine Description:
861 Process Atim ring TxDone interrupt, running in DPC level
863 Arguments:
864 Adapter Pointer to our adapter
866 Return Value:
867 None
869 Note:
871 ========================================================================
873 VOID RTMPHandleAtimRingTxDoneInterrupt(
874 IN PRTMP_ADAPTER pAdapter)
876 // PTXD_STRUC pTxD;
877 // UCHAR Count;
879 // Make sure Atim ring resource won't be used by other threads
880 //NdisAcquireSpinLock(&pAdapter->AtimRingLock);
882 // Did not support ATIM, remove everything.
884 // Make sure to release Atim ring resource
885 //NdisReleaseSpinLock(&pAdapter->AtimRingLock);
889 ========================================================================
891 Routine Description:
892 Process Rx ring DecryptionDone interrupt, running in DPC level
894 Arguments:
895 Adapter Pointer to our adapter
897 Return Value:
898 None
900 Note:
902 ========================================================================
904 VOID RTMPHandleDecryptionDoneInterrupt(
905 IN PRTMP_ADAPTER pAdapter)
907 PRXD_STRUC pRxD;
908 #ifdef BIG_ENDIAN
909 PRXD_STRUC pDestRxD;
910 RXD_STRUC RxD;
911 #endif
912 PHEADER_802_11 pHeader;
913 PUCHAR pData;
914 PVOID pManage;
915 PUCHAR pDestMac, pSrcMac;
916 UCHAR Header802_3[14];
917 UCHAR LLC_Len[2];
918 USHORT PacketSize;
919 ULONG High32TSF, Low32TSF;
920 UCHAR Count;
921 PWPA_KEY pWpaKey;
922 NDIS_STATUS Status;
923 ULONG RegValue;
924 ULONG HwDecryptIndex;
925 ULONG i;
926 struct sk_buff *skb;
927 #ifndef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
928 ULONG IrqFlags;
929 #endif
930 #ifdef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
931 spin_lock(&pAdapter->RxRingLock);
932 #else
933 // Make sure Rx ring resource won't be used by other threads
934 NdisAcquireSpinLock(&pAdapter->RxRingLock, IrqFlags);
935 #endif
936 RTMP_IO_READ32(pAdapter, SECCSR0, &RegValue);
937 HwDecryptIndex = (RegValue - pAdapter->RxRing[0].pa_addr) / RING_DESCRIPTOR_SIZE;
939 Count = 0;
940 #if 0 // mask by Victor Yu. 05-18-2006
941 //do
942 while (pAdapter->CurDecryptIndex != HwDecryptIndex)
944 #else // add by Victor Yu. 05-18-2006
945 do {
946 if ( pAdapter->CurDecryptIndex == HwDecryptIndex )
947 break;
948 #endif
950 // Point to Rx indexed rx ring descriptor
951 #ifndef BIG_ENDIAN
952 pRxD = (PRXD_STRUC) pAdapter->RxRing[pAdapter->CurDecryptIndex].va_addr;
953 #else
954 pDestRxD = (PRXD_STRUC) pAdapter->RxRing[pAdapter->CurDecryptIndex].va_addr;
955 RxD = *pDestRxD;
956 pRxD = &RxD;
957 RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
958 #endif
960 // In case of false alarm or processed at last instance
961 if ((pRxD->Owner != DESC_OWN_HOST) || (pRxD->CipherOwner != DESC_OWN_HOST))
962 break;
964 // Point to Rx ring buffer where stores the real data frame
965 pData = (PUCHAR) (pAdapter->RxRing[pAdapter->CurDecryptIndex].va_data_addr);
966 // Cast to 802.11 header for flags checking
967 pHeader = (PHEADER_802_11) pData;
969 #ifdef BIG_ENDIAN
970 RTMPFrameEndianChange(pAdapter, (PUCHAR)pHeader, DIR_READ, FALSE);
971 #endif
972 // Driver will check the decrypt algorithm and decide whether this ICV is true or not
973 if ((pRxD->IcvError == 1) && (pRxD->CipherAlg == CIPHER_NONE))
974 pRxD->IcvError = 0;
976 // Since we already process header at RxDone interrupt, there is no need to proces
977 // header sanity again, the only thing we have to check is icv_err bit
978 //if (pRxD->IcvError == 1)
979 if ((pRxD->IcvError == 1) && (pRxD->CipherAlg != CIPHER_NONE))
981 DBGPRINT(RT_DEBUG_TRACE,"Rx DecryptDone - ICV error (len %d)\n", pRxD->DataByteCnt);
982 pRxD->Drop =1; // Drop frame with icv error
984 // Saved data pointer for management frame which will pass to MLME block
985 pManage = (PVOID) pData;
987 // pData : Pointer skip the first 24 bytes, 802.11 HEADER
988 pData += LENGTH_802_11;
990 // The total available payload should exclude 24-byte 802.11 Header
991 // If Security is enabled, IV, EIV, ICV size is excluded by ASIC
992 PacketSize = (USHORT) pRxD->DataByteCnt - LENGTH_802_11;
994 // Find the WPA key, either Group or Pairwise Key
995 // Although the data has been decrypted by ASIC,
996 // driver has to calculate the RxMIC which required the key.
997 // The failed case should not happen. If it did, drop it.
998 // Init WPA Key
999 pWpaKey = (PWPA_KEY) NULL;
1000 if ((pAdapter->PortCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pHeader->Controlhead.Frame.Wep))
1002 INT idx;
1004 // First lookup the DA, if it's a group address, use GROUP key
1005 if (pRxD->Bcast || pRxD->Mcast)
1007 // Get the IV index from RxD descriptor
1008 #ifdef BIG_ENDIAN
1009 idx = (pRxD->Iv & 0x000000c0) >> 6;
1010 #else
1011 idx = (pRxD->Iv & 0xc0000000) >> 30;
1012 #endif
1013 if ((pAdapter->PortCfg.GroupKey[idx].KeyLen != 0) &&
1014 ((INFRA_ON(pAdapter) && (NdisEqualMemory(&pHeader->Controlhead.Addr2, &pAdapter->PortCfg.Bssid, 6))) ||
1015 (ADHOC_ON(pAdapter) && (NdisEqualMemory(&pHeader->Addr3, &pAdapter->PortCfg.Bssid, 6)))))
1017 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.GroupKey[idx];
1018 pWpaKey->Type = GROUP_KEY;
1019 DBGPRINT(RT_DEBUG_INFO, "Decrypt Done: Rx Use Group Key %d\n", idx);
1022 // Try to find the Pairwise Key
1023 else
1025 for (idx = 0; idx < PAIRWISE_KEY_NO; idx++)
1027 if ((NdisEqualMemory(&pHeader->Controlhead.Addr2, pAdapter->PortCfg.PairwiseKey[idx].BssId, 6)) &&
1028 (pAdapter->PortCfg.PairwiseKey[idx].KeyLen != 0))
1030 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.PairwiseKey[idx];
1031 pWpaKey->Type = PAIRWISE_KEY;
1032 DBGPRINT(RT_DEBUG_INFO, "Rx Use Pairwise Key\n");
1033 break;
1036 #if 1
1037 // Use default Group Key if there is no Pairwise key present
1038 if ((pWpaKey == NULL) && (pAdapter->PortCfg.GroupKey[pAdapter->PortCfg.DefaultKeyId].KeyLen != 0))
1040 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.GroupKey[pAdapter->PortCfg.DefaultKeyId];
1041 pWpaKey->Type = GROUP_KEY;
1042 DBGPRINT(RT_DEBUG_INFO, "Rx Use Group Key\n");
1044 #endif
1047 // If there is no WPA key matched, this frame should be dropped
1048 if (pWpaKey == NULL)
1049 pRxD->Drop = 1;
1053 // Start of main loop to parse receiving frames.
1054 // The sequence will be Type first, then subtype...
1056 if (pRxD->Drop == 0)
1058 switch (pHeader->Controlhead.Frame.Type)
1060 // Frame with data type
1061 case BTYPE_DATA:
1062 // DA is always address 1
1063 // For infrastructure, SA is address 3. For IBSS mode, SA is address 2
1064 pDestMac = (PUCHAR) &(pHeader->Controlhead.Addr1);
1065 if (INFRA_ON(pAdapter))
1066 pSrcMac = (PUCHAR) &(pHeader->Addr3);
1067 else
1068 pSrcMac = (PUCHAR) &(pHeader->Controlhead.Addr2);
1070 // Process Broadcast & Multicast data frame
1071 if (pRxD->Bcast || pRxD->Mcast)
1073 // For TKIP frame, calculate the MIC value
1074 if (pRxD->CipherAlg == CIPHER_TKIP)
1076 INT i = 0;
1078 if (pWpaKey == NULL)
1080 DBGPRINT(RT_DEBUG_ERROR,"No matched TKIP in decryption done calculate MIC routine!!!\n");
1081 Status = NDIS_STATUS_FAILURE;
1082 break;
1085 // Minus MIC length
1086 PacketSize -= 8;
1087 if (RTMPTkipCompareMICValue(
1088 pAdapter,
1089 pData,
1090 pDestMac,
1091 pSrcMac,
1092 pWpaKey->RxMic,
1093 PacketSize) == FALSE)
1095 DBGPRINT(RT_DEBUG_ERROR,"Rx MIC Value error\n");
1096 RTMPReportMicError(pAdapter, pWpaKey);
1097 Status = NDIS_STATUS_FAILURE;
1098 break;
1101 // Second, increase RxTsc value for next transmission
1102 while (++pWpaKey->RxTsc[i] == 0x0)
1104 i++;
1105 if (i == 6)
1106 break;
1108 // Rx TSC has done one full cycle, since re-key is done by transmitter
1109 // We did not do anything for Rx path
1112 // build 802.3 header and decide if remove the 8-byte LLC/SNAP encapsulation
1113 CONVERT_TO_802_3(Header802_3, pDestMac, pSrcMac, pData, PacketSize);
1115 pAdapter->PortCfg.LedCntl.fRxActivity = TRUE; // for RX ACTIVITY LED
1117 // For miniportTransferData
1118 pAdapter->pRxData = pData;
1120 // Acknolwdge upper layer the received frame
1121 if ((skb = __dev_alloc_skb(PacketSize + LENGTH_802_3 + 2, GFP_DMA|GFP_ATOMIC)) != NULL)
1123 skb->dev = pAdapter->net_dev;
1124 skb_reserve(skb, 2); // 16 byte align the IP header
1125 memcpy(skb_put(skb, LENGTH_802_3), Header802_3, LENGTH_802_3);
1126 memcpy(skb_put(skb, PacketSize), pData, PacketSize);
1127 skb->protocol = eth_type_trans(skb, pAdapter->net_dev);
1128 netif_rx(skb);
1129 pAdapter->net_dev->last_rx = jiffies;
1130 pAdapter->stats.rx_packets++;
1133 DBGPRINT(RT_DEBUG_INFO, "!!! Broadcast Ethenet rx Indicated !!!\n");
1136 // Begin process unicast to me frame
1137 else if (pRxD->U2M)
1139 // Update Rx data rate first.
1140 if (pRxD->Ofdm == 1)
1142 for (i = 4; i < 12; i++)
1144 if (pRxD->BBR0 == PlcpSignal[i])
1145 break;
1147 if (i < 12)
1148 pAdapter->LastRxRate = i;
1150 else // receive CCK encoding
1152 if (pRxD->BBR0 == 10)
1153 pAdapter->LastRxRate = 0;
1154 else if (pRxD->BBR0 == 20)
1155 pAdapter->LastRxRate = 1;
1156 else if (pRxD->BBR0 == 55)
1157 pAdapter->LastRxRate = 2;
1158 else if (pRxD->BBR0 == 110)
1159 pAdapter->LastRxRate = 3;
1162 if (pHeader->Frag == 0) // First or Only fragment
1164 // For TKIP frame, calculate the MIC value
1165 if ((pHeader->Controlhead.Frame.MoreFrag == FALSE) &&
1166 (pRxD->CipherAlg == CIPHER_TKIP) &&
1167 (pHeader->Controlhead.Frame.Wep))
1169 if (pWpaKey == NULL)
1171 DBGPRINT(RT_DEBUG_ERROR,"No matched TKIP in decryption done calculate MIC routine!!!\n");
1172 Status = NDIS_STATUS_FAILURE;
1173 break;
1175 // Minus MIC length
1176 PacketSize -= 8;
1177 if (RTMPTkipCompareMICValue(
1178 pAdapter,
1179 pData,
1180 pDestMac,
1181 pSrcMac,
1182 pWpaKey->RxMic,
1183 PacketSize) == FALSE)
1185 DBGPRINT(RT_DEBUG_ERROR,"Rx MIC Value error\n");
1186 RTMPReportMicError(pAdapter, pWpaKey);
1187 Status = NDIS_STATUS_FAILURE;
1188 break;
1192 pAdapter->FragFrame.Flags &= 0xFFFFFFFE;
1194 // Check for encapsulation other than RFC1042 & Bridge tunnel
1195 if ((!RTMPEqualMemory(SNAP_802_1H, pData, 6)) &&
1196 (!RTMPEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6)))
1198 LLC_Len[0] = PacketSize / 256;
1199 LLC_Len[1] = PacketSize % 256;
1200 MAKE_802_3_HEADER(Header802_3, pDestMac, pSrcMac, ((PUCHAR) LLC_Len));
1202 else
1204 char *pProto = pData + 6;
1206 // Remove 802.11 H header & reconstruct 802.3 header
1207 // pData += (LENGTH_802_1_H - LENGTH_802_3_TYPE);
1208 // Check for EAPOL frame when driver supplicant enabled
1209 // TODO: It is not strickly correct. There is no fragment handling. It might damage driver
1210 // TODO: But for WPAPSK, it's not likely fragment on EAPOL frame will happen
1211 if (RTMPEqualMemory(EAPOL, pProto, 2) && ((pAdapter->PortCfg.WpaState != SS_NOTUSE)))
1213 RTMP_IO_READ32(pAdapter, CSR17, &High32TSF); // TSF value
1214 RTMP_IO_READ32(pAdapter, CSR16, &Low32TSF); // TSF vlaue
1215 PacketSize += LENGTH_802_11;
1216 // Enqueue this frame to MLME engine
1217 MlmeEnqueueForRecv(
1218 pAdapter,
1219 &pAdapter->Mlme.Queue,
1220 High32TSF,
1221 Low32TSF,
1222 (UCHAR)pRxD->BBR1,
1223 PacketSize,
1224 pManage);
1225 break;
1228 if ((RTMPEqualMemory(IPX, pProto, 2) || RTMPEqualMemory(APPLE_TALK, pProto, 2)) &&
1229 RTMPEqualMemory(SNAP_802_1H, pData, 6))
1231 // preserved the LLC/SNAP filed
1232 LLC_Len[0] = PacketSize / 256;
1233 LLC_Len[1] = PacketSize % 256;
1234 MAKE_802_3_HEADER(Header802_3, pDestMac, pSrcMac, ((PUCHAR) LLC_Len));
1236 else
1238 // remove the LLC/SNAP field
1239 MAKE_802_3_HEADER(Header802_3, pDestMac, pSrcMac, pProto);
1240 NdisMoveMemory(pAdapter->FragFrame.Header_LLC, pData, 8);
1241 PacketSize -= LENGTH_802_1_H;
1242 pData += LENGTH_802_1_H;
1243 pAdapter->FragFrame.Flags |= 0x01;
1247 // One & The only fragment
1248 if (pHeader->Controlhead.Frame.MoreFrag == FALSE)
1250 // For miniportTransferData
1251 pAdapter->pRxData = pData;
1253 pAdapter->PortCfg.LedCntl.fRxActivity = TRUE; // for RX ACTIVITY LED
1255 // Acknowledge upper layer the received frame
1256 if ((skb = __dev_alloc_skb(PacketSize + LENGTH_802_3 + 2, GFP_DMA|GFP_ATOMIC)) != NULL)
1258 skb->dev = pAdapter->net_dev;
1259 skb_reserve(skb, 2); // 16 byte align the IP header
1260 memcpy(skb_put(skb, LENGTH_802_3), Header802_3, LENGTH_802_3);
1261 memcpy(skb_put(skb, PacketSize), pData, PacketSize);
1262 skb->protocol = eth_type_trans(skb, pAdapter->net_dev);
1263 netif_rx(skb);
1264 pAdapter->net_dev->last_rx = jiffies;
1265 pAdapter->stats.rx_packets++;
1268 // NdisZeroMemory(Header802_3, LENGTH_802_3);
1269 DBGPRINT(RT_DEBUG_INFO, "!!! Frame without Fragment Indicated !!!\n");
1271 // Increase general counters
1272 pAdapter->Counters.GoodReceives++;
1275 // First fragment of fragmented frames
1276 else
1278 NdisMoveMemory(&pAdapter->FragFrame.Buffer[LENGTH_802_3], pData, PacketSize);
1279 NdisMoveMemory(pAdapter->FragFrame.Header802_3, Header802_3, LENGTH_802_3);
1280 //NdisZeroMemory(Header802_3, LENGTH_802_3);
1281 pAdapter->FragFrame.RxSize = PacketSize;
1282 pAdapter->FragFrame.Sequence = pHeader->Sequence;
1283 pAdapter->FragFrame.LastFrag = pHeader->Frag; // Should be 0
1286 // Middle & End of fragment burst fragments
1287 else
1289 // No LLC-SNAP header in except the first fragment frame
1291 if ((pHeader->Sequence != pAdapter->FragFrame.Sequence) ||
1292 (pHeader->Frag != (pAdapter->FragFrame.LastFrag + 1)))
1294 // Fragment is not the same sequence or out of fragment number order
1295 // Clear Fragment frame contents
1296 NdisZeroMemory(&pAdapter->FragFrame, sizeof(FRAGMENT_FRAME));
1297 Status = NDIS_STATUS_FAILURE;
1298 break;
1300 else if ((pAdapter->FragFrame.RxSize + PacketSize) > MAX_FRAME_SIZE)
1302 // Fragment frame is too large, it exeeds the maximum frame size.
1303 // We have to drop it.
1304 // Clear Fragment frame contents
1305 NdisZeroMemory(&pAdapter->FragFrame, sizeof(FRAGMENT_FRAME));
1306 Status = NDIS_STATUS_FAILURE;
1307 break;
1310 // concatenate this fragment into the re-assembly buffer
1311 NdisMoveMemory(&pAdapter->FragFrame.Buffer[LENGTH_802_3 + pAdapter->FragFrame.RxSize], pData, PacketSize);
1312 pAdapter->FragFrame.RxSize += PacketSize;
1313 pAdapter->FragFrame.LastFrag = pHeader->Frag; // Update fragment number
1315 // Last fragment
1316 if (pHeader->Controlhead.Frame.MoreFrag == FALSE)
1318 // For TKIP frame, calculate the MIC value
1319 if ((pRxD->CipherAlg == CIPHER_TKIP) && (pHeader->Controlhead.Frame.Wep))
1321 if (pWpaKey == NULL)
1323 DBGPRINT(RT_DEBUG_ERROR,"No matched TKIP in decryption done calculate MIC routine!!!\n");
1324 Status = NDIS_STATUS_FAILURE;
1325 break;
1327 // Minus MIC length
1328 pAdapter->FragFrame.RxSize -= 8;
1330 if (pAdapter->FragFrame.Flags & 0x00000001)
1332 // originally there's an LLC/SNAP field in the first fragment
1333 // but been removed in re-assembly buffer. here we have to include
1334 // this LLC/SNAP field upon calculating TKIP MIC
1335 // Copy LLC data to the position in front of real data for MIC calculation
1336 NdisMoveMemory(&pAdapter->FragFrame.Buffer[LENGTH_802_3 - LENGTH_802_1_H],
1337 pAdapter->FragFrame.Header_LLC,
1338 LENGTH_802_1_H);
1339 pData = (PUCHAR) &pAdapter->FragFrame.Buffer[LENGTH_802_3 - LENGTH_802_1_H];
1340 PacketSize = (USHORT)pAdapter->FragFrame.RxSize + LENGTH_802_1_H;
1341 //cketSize = (USHORT)pAdapter->FragFrame.RxSize + 8;
1343 else
1345 pData = &pAdapter->FragFrame.Buffer[LENGTH_802_3];
1346 PacketSize = (USHORT)pAdapter->FragFrame.RxSize;
1349 if (RTMPTkipCompareMICValue(
1350 pAdapter,
1351 pData,
1352 pDestMac,
1353 pSrcMac,
1354 pWpaKey->RxMic,
1355 PacketSize) == FALSE)
1357 DBGPRINT(RT_DEBUG_ERROR,"Rx MIC Value error 2\n");
1358 RTMPReportMicError(pAdapter, pWpaKey);
1359 Status = NDIS_STATUS_FAILURE;
1360 break;
1363 // TODO:
1364 // Getting RxTSC from Rx descriptor
1367 // for RX ACTIVITY LED
1368 pAdapter->PortCfg.LedCntl.fRxActivity = TRUE;
1370 // For miniportTransferData
1371 pAdapter->pRxData = &pAdapter->FragFrame.Buffer[LENGTH_802_3];
1373 NdisMoveMemory(pAdapter->FragFrame.Buffer, pAdapter->FragFrame.Header802_3, LENGTH_802_3);
1374 // Acknowledge upper layer the received frame
1375 if ((skb = __dev_alloc_skb(pAdapter->FragFrame.RxSize + LENGTH_802_3 + 2, GFP_DMA|GFP_ATOMIC)) != NULL)
1377 skb->dev = pAdapter->net_dev;
1378 skb_reserve(skb, 2); /* 16 byte align the IP header */
1379 memcpy(skb_put(skb, LENGTH_802_3), (PVOID) &pAdapter->FragFrame.Buffer[0], LENGTH_802_3);
1380 memcpy(skb_put(skb, pAdapter->FragFrame.RxSize), (PVOID) &pAdapter->FragFrame.Buffer[LENGTH_802_3], pAdapter->FragFrame.RxSize);
1381 skb->protocol = eth_type_trans(skb, pAdapter->net_dev);
1382 netif_rx(skb);
1383 pAdapter->net_dev->last_rx = jiffies;
1384 pAdapter->stats.rx_packets++;
1387 // Increase general counters
1388 pAdapter->Counters.GoodReceives++;
1390 // Clear Fragment frame contents
1391 NdisZeroMemory(&pAdapter->FragFrame, sizeof(FRAGMENT_FRAME));
1392 DBGPRINT(RT_DEBUG_INFO, "!!! Frame with Fragment Indicated !!!\n");
1396 break;
1398 case BTYPE_MGMT:
1399 // Read required regsiter for MLME engine
1400 RTMP_IO_READ32(pAdapter, CSR17, &High32TSF); // TSF value
1401 RTMP_IO_READ32(pAdapter, CSR16, &Low32TSF); // TSF vlaue
1403 // Enqueue this frame to MLME engine
1404 MlmeEnqueueForRecv(
1405 pAdapter,
1406 &pAdapter->Mlme.Queue,
1407 High32TSF,
1408 Low32TSF,
1409 (UCHAR)pRxD->BBR1,
1410 pRxD->DataByteCnt,
1411 pManage);
1412 break;
1414 case BTYPE_CNTL:
1415 // Ignore ???
1416 break;
1418 default :
1419 break;
1423 pAdapter->CurDecryptIndex++;
1424 if (pAdapter->CurDecryptIndex >= RX_RING_SIZE)
1426 pAdapter->CurDecryptIndex = 0;
1428 Count++;
1430 pAdapter->RalinkCounters.DecryptCount ++;
1432 // Clear Cipherowner bit & Rx Owner bit for all drop & non-drop frames
1433 pRxD->CipherOwner = DESC_OWN_HOST;
1434 pRxD->Owner = DESC_OWN_NIC;
1435 #ifdef BIG_ENDIAN
1436 RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
1437 //*pDestRxD = RxD;
1438 WriteBackToDescriptor((PUCHAR)pDestRxD, (PUCHAR)pRxD, FALSE, TYPE_RXD);
1439 #endif
1440 #if 0 // mask by Victor Yu. 05-18-2006
1442 //} while (Count < RX_RING_SIZE);
1443 //} while (pAdapter->CurDecryptIndex != HwDecryptIndex);
1444 #else // add by Victor Yu. 05-18-2006
1445 } while ( Count < (2*RX_RING_SIZE) );
1446 #endif
1447 #ifdef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
1448 spin_unlock(&pAdapter->RxRingLock);
1449 #else
1450 // Make sure to release Rx ring resource
1451 NdisReleaseSpinLock(&pAdapter->RxRingLock, IrqFlags);
1452 #endif
1456 ========================================================================
1458 Routine Description:
1459 Process Tx ring EncryptionDone interrupt, running in DPC level
1461 Arguments:
1462 Adapter Pointer to our adapter
1464 Return Value:
1465 None
1467 Note:
1469 ========================================================================
1471 VOID RTMPHandleEncryptionDoneInterrupt(
1472 IN PRTMP_ADAPTER pAdapter)
1474 PTXD_STRUC pTxD;
1475 #ifdef BIG_ENDIAN
1476 PTXD_STRUC pDestTxD;
1477 TXD_STRUC TxD;
1478 #endif
1479 UCHAR Count;
1480 ULONG RegValue;
1481 ULONG HwEncryptIndex;
1482 #ifndef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
1483 ULONG IrqFlags;
1484 #endif
1485 #ifdef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
1486 spin_lock(&pAdapter->TxRingLock);
1487 #else
1488 // Make sure Prio ring resource won't be used by other threads
1489 NdisAcquireSpinLock(&pAdapter->TxRingLock, IrqFlags);
1490 #endif
1491 RTMP_IO_READ32(pAdapter, SECCSR1, &RegValue);
1492 HwEncryptIndex = (RegValue - pAdapter->TxRing[0].pa_addr) / RING_DESCRIPTOR_SIZE;
1494 Count = 0;
1495 #if 0 // mask by Victor Yu. 05-18-2006
1496 //do
1497 while (pAdapter->NextEncryptDoneIndex != HwEncryptIndex)
1499 #else // add by Victor Yu. 05-18-2006
1500 do {
1501 if ( pAdapter->NextEncryptDoneIndex == HwEncryptIndex )
1502 break;
1503 #endif
1505 #ifndef BIG_ENDIAN
1506 pTxD = (PTXD_STRUC) (pAdapter->TxRing[pAdapter->NextEncryptDoneIndex].va_addr);
1507 #else
1508 pDestTxD = (PTXD_STRUC) (pAdapter->TxRing[pAdapter->NextEncryptDoneIndex].va_addr);
1509 TxD = *pDestTxD;
1510 pTxD = &TxD;
1511 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1512 #endif
1514 // Check for the descriptor cipher ownership
1515 if ((pTxD->CipherOwn == DESC_OWN_NIC) || (pTxD->Owner == DESC_OWN_NIC))
1517 pAdapter->RalinkCounters.TxRingErrCount++;
1518 #ifdef BIG_ENDIAN
1519 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1520 *pDestTxD = TxD;
1521 #endif
1522 break;
1525 // Alter EIV due to ASIC's bug
1526 if (pTxD->CipherAlg == CIPHER_TKIP)
1528 UCHAR Eiv_Tmp[4];
1529 PUCHAR pTmp;
1531 NdisMoveMemory(Eiv_Tmp, &pTxD->Eiv, 4);
1532 pTmp = (PUCHAR) &pTxD->Eiv;
1533 *pTmp = Eiv_Tmp[3];
1534 *(pTmp + 1) = Eiv_Tmp[2];
1535 *(pTmp + 2) = Eiv_Tmp[1];
1536 *(pTmp + 3) = Eiv_Tmp[0];
1538 // Sanity Check, CurTxIndex should equal to NextEncryptDoneIndex
1539 // ASSERT(pAdapter->CurTxIndex == pAdapter->NextEncryptDoneIndex);
1541 pTxD->Valid = TRUE;
1542 pTxD->Owner = DESC_OWN_NIC;
1544 #ifdef BIG_ENDIAN
1545 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1546 //*pDestTxD = TxD;
1547 WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
1548 #endif
1550 pAdapter->NextEncryptDoneIndex++;
1551 if (pAdapter->NextEncryptDoneIndex >= TX_RING_SIZE)
1553 pAdapter->NextEncryptDoneIndex = 0;
1555 pAdapter->CurTxIndex = pAdapter->NextEncryptDoneIndex;
1556 pAdapter->RalinkCounters.KickTxCount++;
1558 if (pAdapter->CurTxIndex == pAdapter->CurEncryptIndex)
1559 break;
1560 #if 0 // mask by Victor Yu. 05-18-2006
1562 //} while (++Count < MAX_TX_PROCESS);
1563 //} while (pAdapter->NextEncryptDoneIndex != HwEncryptIndex);
1564 #else // add by Victor Yu. 05-18-2006
1565 } while (++Count < (2*MAX_TX_PROCESS) );
1566 #endif
1568 // Kick Tx Control Register at the end of all ring buffer preparation
1569 RTMP_IO_WRITE32(pAdapter, TXCSR0, 0x1);
1570 #ifdef ISR_JUST_LOCK // add by Victor Yu. 05-23-2006
1571 spin_unlock(&pAdapter->TxRingLock);
1572 #else
1573 // Make sure to release Tx ring resource
1574 NdisReleaseSpinLock(&pAdapter->TxRingLock, IrqFlags);
1575 #endif
1579 ========================================================================
1581 Routine Description:
1582 Arguments:
1583 Adapter Pointer to our adapter
1584 ========================================================================
1586 void RTMPHandleTbcnInterrupt(IN PRTMP_ADAPTER pAdapter)
1588 if (ADHOC_ON(pAdapter))
1590 MACHDR *pBcnHdr = (MACHDR *)pAdapter->BeaconRing.va_data_addr;
1592 // update BEACON frame's sequence number
1593 pAdapter->Sequence = ((pAdapter->Sequence) + 1) & (MAX_SEQ_NUMBER);
1594 pBcnHdr->Seq = pAdapter->Sequence;
1596 #ifdef BIG_ENDIAN
1597 *(USHORT *)((UCHAR *)pBcnHdr + 22) = SWAP16(*(USHORT *)((UCHAR *)pBcnHdr + 22));
1598 #endif
1603 ========================================================================
1605 Routine Description:
1606 Arguments:
1607 Adapter Pointer to our adapter
1608 ========================================================================
1610 void RTMPHandleTwakeupInterrupt(IN PRTMP_ADAPTER pAdapter)
1612 // DBGPRINT(RT_DEBUG_ERROR, ("Twakeup Expired... !!!\n"));
1613 pAdapter->PortCfg.Pss = PWR_ACTIVE;
1617 ========================================================================
1619 Routine Description:
1620 Process all transmit ring Tx Done interrupt, running in DPC level
1622 Arguments:
1623 Adapter Pointer to our adapter
1625 Return Value:
1626 None
1628 Note:
1630 ========================================================================
1632 VOID RTMPHardTransmitDone(
1633 IN PRTMP_ADAPTER pAdapter,
1634 IN PTXD_STRUC pTxD,
1635 IN UCHAR FrameType)
1638 switch (pTxD->TxResult)
1640 case SUCCESS_WITHOUT_RETRY: // Success without any retry
1641 // Return send complete status
1642 // DBGPRINT(RT_DEBUG_INFO, "TX Success without retry<<<\n");
1643 if (pTxD->RTS)
1645 // Increase 802.11 counters
1646 INC_COUNTER(pAdapter->WlanCounters.RTSSuccessCount);
1647 pTxD->RTS = 0;
1650 // Increase general counters
1651 pAdapter->Counters.GoodTransmits++;
1652 INC_COUNTER(pAdapter->WlanCounters.TransmittedFragmentCount);
1654 // update DRS related counters
1655 if (pTxD->ACK && (FrameType == BTYPE_DATA))
1657 pAdapter->DrsCounters.OneSecTxOkCount ++;
1659 break;
1661 case SUCCESS_WITH_RETRY: // Success with some retry
1662 // DBGPRINT(RT_DEBUG_INFO, "TX Success with retry(=%d)<<<\n",pTxD->RetryCount);
1663 // Increase 802.11 counters
1664 INC_COUNTER(pAdapter->WlanCounters.RetryCount);
1665 INC_COUNTER(pAdapter->WlanCounters.ACKFailureCount);
1666 INC_COUNTER(pAdapter->WlanCounters.TransmittedFragmentCount);
1668 // Increase general counters
1669 pAdapter->Counters.GoodTransmits++;
1671 if (pTxD->RetryCount > 1)
1673 // Increase 802.11 counters
1674 INC_COUNTER(pAdapter->WlanCounters.MultipleRetryCount);
1676 // Increase general counters
1677 pAdapter->Counters.MoreCollisions++;
1679 else
1681 // Increase general counters
1682 pAdapter->Counters.OneCollision++;
1685 if (pTxD->RTS)
1687 INC_COUNTER(pAdapter->WlanCounters.RTSSuccessCount);
1688 pTxD->RTS = 0;
1691 // update DRS related counters
1692 if (pTxD->ACK && (FrameType == BTYPE_DATA))
1694 if (pTxD->TxRate > pAdapter->PortCfg.TxRate)
1696 // DRS - must be NULL frame retried @ UpRate; downgrade
1697 // TxQuality[UpRate] so that not upgrade TX rate
1698 pAdapter->DrsCounters.TxQuality[pTxD->TxRate] += 2;
1699 if (pAdapter->DrsCounters.TxQuality[pTxD->TxRate] > DRS_TX_QUALITY_WORST_BOUND)
1700 pAdapter->DrsCounters.TxQuality[pTxD->TxRate] = DRS_TX_QUALITY_WORST_BOUND;
1702 else if (pTxD->TxRate == pAdapter->PortCfg.TxRate)
1703 pAdapter->DrsCounters.OneSecTxRetryOkCount ++;
1705 break;
1707 case FAIL_RETRY_LIMIT: // Fail on hitting retry count limit
1708 // DBGPRINT(RT_DEBUG_WARN, ("TX Failed (RETRY LIMIT)<<<\n"));
1709 // Increase 802.11 counters
1710 INC_COUNTER(pAdapter->WlanCounters.FailedCount);
1711 INC_COUNTER(pAdapter->WlanCounters.ACKFailureCount);
1713 // Increase general counters
1714 pAdapter->Counters.TxErrors++;
1716 if (pTxD->RTS)
1718 INC_COUNTER(pAdapter->WlanCounters.RTSFailureCount);
1719 pTxD->RTS = 0;
1722 // update DRS related counters
1723 if (pTxD->ACK && (FrameType == BTYPE_DATA))
1725 if (pTxD->TxRate > pAdapter->PortCfg.TxRate)
1727 // DRS - must be NULL frame failed @ UpRate; downgrade
1728 // TxQuality[UpRate] so that not upgrade TX rate
1729 pAdapter->DrsCounters.TxQuality[pTxD->TxRate] = DRS_TX_QUALITY_WORST_BOUND;
1731 else if (pTxD->TxRate == pAdapter->PortCfg.TxRate)
1733 pAdapter->DrsCounters.OneSecTxFailCount ++;
1736 break;
1738 case FAIL_INVALID:
1739 // DBGPRINT(RT_DEBUG_WARN, ("TX Failed (INVALID)<<<\n"));
1740 // Increase general counters
1741 pAdapter->Counters.TxErrors++;
1743 if (pTxD->RTS)
1745 INC_COUNTER(pAdapter->WlanCounters.RTSFailureCount);
1746 pTxD->RTS = 0;
1748 break;
1750 case FAIL_OTHER:
1751 default:
1752 // DBGPRINT(RT_DEBUG_ERROR, ("TX Failed (other=%d)<<<\n",pTxD->TxResult));
1753 // Increase 802.11 counters
1754 INC_COUNTER(pAdapter->WlanCounters.FailedCount);
1755 INC_COUNTER(pAdapter->WlanCounters.ACKFailureCount);
1757 // Increase general counters
1758 pAdapter->Counters.TxErrors++;
1760 if (pTxD->RTS)
1762 INC_COUNTER(pAdapter->WlanCounters.RTSFailureCount);
1763 pTxD->RTS = 0;
1765 break;
1770 ========================================================================
1772 Routine Description:
1773 API for MLME to transmit management frame to AP (BSS Mode)
1774 or station (IBSS Mode)
1776 Arguments:
1777 pAdapter Pointer to our adapter
1778 Buffer Pointer to memory of outgoing frame
1779 Length Size of outgoing management frame
1781 Return Value:
1782 NDIS_STATUS_FAILURE
1783 NDIS_STATUS_PENDING
1784 NDIS_STATUS_SUCCESS
1786 Note:
1788 ========================================================================
1790 NDIS_STATUS MiniportMMRequest(
1791 IN PRTMP_ADAPTER pAdapter,
1792 IN PVOID pBuffer,
1793 IN ULONG Length)
1795 PMGMT_STRUC pMgmt;
1796 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
1797 ULONG IrqFlags;
1799 DBGPRINT(RT_DEBUG_INFO, "---> MiniportMMRequest\n");
1800 // Check management ring free avaliability
1801 pMgmt = (PMGMT_STRUC) &pAdapter->MgmtRing[pAdapter->PushMgmtIndex];
1803 // This management cell has been occupied
1804 if (pMgmt->Valid == TRUE)
1806 // No Management ring buffer avaliable
1807 MlmeFreeMemory(pAdapter, pBuffer);
1808 Status = NDIS_STATUS_FAILURE;
1809 DBGPRINT(RT_DEBUG_WARN, "<--- MiniportMMRequest (error:: MgmtRing full)\n");
1810 pAdapter->RalinkCounters.MgmtRingFullCount++;
1811 return (Status);
1814 // Insert this request into software managemnet ring
1815 if (pBuffer)
1817 pMgmt->pBuffer = pBuffer;
1818 pMgmt->Length = Length;
1819 pMgmt->Valid = TRUE;
1820 pAdapter->PushMgmtIndex++;
1821 pAdapter->MgmtQueueSize++;
1822 if (pAdapter->PushMgmtIndex >= MGMT_RING_SIZE)
1824 pAdapter->PushMgmtIndex = 0;
1827 else
1829 // Null pBuffer, no need to free memory buffer.
1830 // This should not happen
1831 DBGPRINT(RT_DEBUG_WARN, "<--- MiniportMMRequest (error:: NULL msg)\n");
1832 Status = NDIS_STATUS_FAILURE;
1833 return (Status);
1836 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF))
1837 return (Status);
1839 // Check Free priority queue
1840 if (RTMPFreeDescriptorRequest(pAdapter, PRIO_RING, 1) == NDIS_STATUS_SUCCESS)
1842 pMgmt = (PMGMT_STRUC) &pAdapter->MgmtRing[pAdapter->PopMgmtIndex];
1843 if (pMgmt->Valid == TRUE)
1845 MlmeHardTransmit(pAdapter, pMgmt->pBuffer, pMgmt->Length);
1846 MlmeFreeMemory(pAdapter, pMgmt->pBuffer);
1847 pMgmt->Valid = FALSE;
1848 NdisAcquireSpinLock(&pAdapter->PrioRingLock, IrqFlags);
1849 pAdapter->PopMgmtIndex++;
1850 pAdapter->MgmtQueueSize--;
1851 if (pAdapter->PopMgmtIndex >= MGMT_RING_SIZE)
1853 pAdapter->PopMgmtIndex = 0;
1855 NdisReleaseSpinLock(&pAdapter->PrioRingLock, IrqFlags);
1858 else
1860 DBGPRINT(RT_DEBUG_TRACE, "not enough space in PrioRing\n");
1863 DBGPRINT(RT_DEBUG_INFO, "<--- MiniportMMRequest\n");
1864 return (Status);
1868 ========================================================================
1870 Routine Description:
1871 Copy frame from waiting queue into relative ring buffer and set
1872 appropriate ASIC register to kick hardware transmit function
1874 Arguments:
1875 pAdapter Pointer to our adapter
1876 pBuffer Pointer to memory of outgoing frame
1877 Length Size of outgoing management frame
1879 Return Value:
1880 NDIS_STATUS_FAILURE
1881 NDIS_STATUS_PENDING
1882 NDIS_STATUS_SUCCESS
1884 Note:
1886 ========================================================================
1888 VOID MlmeHardTransmit(
1889 IN PRTMP_ADAPTER pAdapter,
1890 IN PVOID pBuffer,
1891 IN ULONG Length)
1893 PTXD_STRUC pTxD;
1894 #ifdef BIG_ENDIAN
1895 PTXD_STRUC pDestTxD;
1896 TXD_STRUC TxD;
1897 #endif
1898 PUCHAR pDest;
1899 PHEADER_802_11 pHeader_802_11;
1900 BOOLEAN AckRequired, InsertTimestamp;
1901 ULONG IrqFlags;
1903 DBGPRINT(RT_DEBUG_INFO, "MlmeHardTransmit\n");
1905 // Make sure Prio ring resource won't be used by other threads
1906 NdisAcquireSpinLock(&pAdapter->PrioRingLock, IrqFlags);
1908 pDest = (PUCHAR) pAdapter->PrioRing[pAdapter->CurPrioIndex].va_data_addr;
1909 #ifndef BIG_ENDIAN
1910 pTxD = (PTXD_STRUC) pAdapter->PrioRing[pAdapter->CurPrioIndex].va_addr;
1911 #else
1912 pDestTxD = (PTXD_STRUC) pAdapter->PrioRing[pAdapter->CurPrioIndex].va_addr;
1913 TxD = *pDestTxD;
1914 pTxD = &TxD;
1915 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1916 #endif
1918 if (pTxD->Owner == DESC_OWN_NIC)
1920 // Descriptor owned by NIC. No descriptor avaliable
1921 // This should not happen since caller guaranteed.
1922 // Make sure to release Prio ring resource
1923 NdisReleaseSpinLock(&pAdapter->PrioRingLock, IrqFlags);
1924 return;
1926 if (pTxD->Valid == TRUE)
1928 // Ndis packet of last round did not cleared.
1929 // This should not happen since caller guaranteed.
1930 // Make sure to release Prio ring resource
1931 NdisReleaseSpinLock(&pAdapter->PrioRingLock, IrqFlags);
1932 return;
1934 if (pBuffer == NULL)
1936 // The buffer shouldn't be NULL
1937 NdisReleaseSpinLock(&pAdapter->PrioRingLock, IrqFlags);
1938 return;
1941 // outgoing frame always wakeup PHY to prevent frame lost
1942 AsicForceWakeup(pAdapter);
1944 pHeader_802_11 = (PHEADER_802_11) pBuffer;
1945 pHeader_802_11->Controlhead.Frame.PwrMgt = 0; // (pAdapter->PortCfg.Psm == PWR_SAVE);
1946 InsertTimestamp = FALSE;
1947 if (pHeader_802_11->Controlhead.Frame.Type == BTYPE_CNTL) // must be PS-POLL
1949 AckRequired = FALSE;
1950 pAdapter->PrioRing[pAdapter->CurPrioIndex].FrameType = BTYPE_CNTL;
1952 else // BTYPE_MGMT or BMGMT_DATA(must be NULL frame)
1954 pAdapter->PrioRing[pAdapter->CurPrioIndex].FrameType = BTYPE_MGMT;
1955 pAdapter->Sequence = ((pAdapter->Sequence) + 1) & (MAX_SEQ_NUMBER);
1956 pHeader_802_11->Sequence = pAdapter->Sequence;
1958 if (pHeader_802_11->Controlhead.Addr1.Octet[0] & 0x01) // MULTICAST, BROADCAST
1960 AckRequired = FALSE;
1961 pHeader_802_11->Controlhead.Duration = 0;
1963 else
1965 AckRequired = TRUE;
1966 pHeader_802_11->Controlhead.Duration = RTMPCalcDuration(pAdapter, pAdapter->PortCfg.MlmeRate, 14);
1967 if (pHeader_802_11->Controlhead.Frame.Subtype == SUBTYPE_PROBE_RSP)
1969 InsertTimestamp = TRUE;
1973 #ifdef BIG_ENDIAN
1974 RTMPFrameEndianChange(pAdapter, (PUCHAR)pBuffer, DIR_WRITE, FALSE);
1975 #endif
1976 NdisMoveMemory(pDest, pBuffer, Length);
1978 // Initialize Priority Descriptor
1979 // For inter-frame gap, the number is for this frame and next frame
1980 // For MLME rate, we will fix as 2Mb to match other vendor's implement
1981 #ifdef BIG_ENDIAN
1982 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1983 *pDestTxD = TxD;
1984 pTxD = pDestTxD;
1985 #endif
1986 RTMPWriteTxDescriptor(pTxD, FALSE, CIPHER_NONE, AckRequired, FALSE, InsertTimestamp,
1987 SHORT_RETRY, IFS_BACKOFF, pAdapter->PortCfg.MlmeRate, 4, Length, pAdapter->PortCfg.TxPreambleInUsed, 0);
1989 // Increase & maintain Tx Ring Index
1990 pAdapter->CurPrioIndex++;
1991 if (pAdapter->CurPrioIndex >= PRIO_RING_SIZE)
1993 pAdapter->CurPrioIndex = 0;
1996 // Kick priority ring transmit
1997 RTMP_IO_WRITE32(pAdapter,TXCSR0,0x4);
1999 // Make sure to release Prio ring resource
2000 NdisReleaseSpinLock(&pAdapter->PrioRingLock, IrqFlags);
2003 ========================================================================
2005 Routine Description:
2006 This routine is used to en-queue outgoing packets when
2007 there is no enough shread memory
2009 Arguments:
2010 pAdapter Pointer to our adapter
2011 pPacket Pointer to send packet
2013 Return Value:
2014 None
2016 Note:
2018 ========================================================================
2020 NDIS_STATUS RTMPSendPacket(
2021 IN PRTMP_ADAPTER pAdapter,
2022 IN struct sk_buff *skb)
2024 PVOID pVirtualAddress;
2025 UINT AllowFragSize;
2026 UCHAR NumberOfFrag;
2027 UCHAR RTSRequired;
2028 NDIS_STATUS Status = NDIS_STATUS_FAILURE;
2029 UCHAR PsMode;
2031 PQUEUE_HEADER pTxQueue = NULL;
2032 ULONG Priority;
2033 UCHAR AccessCategory;
2034 ULONG IrqFlags;
2036 DBGPRINT(RT_DEBUG_INFO, "<==== RTMPSendPacket\n");
2038 // Init priority value
2039 Priority = 0;
2040 AccessCategory = 0;
2042 if (skb)
2044 Priority = skb->priority;
2045 // 802.11e/d4.4 June, 2003
2046 if (Priority <=2)
2047 AccessCategory = 0;
2048 else if (Priority == 3)
2049 AccessCategory = 1;
2050 else if (Priority <= 5)
2051 AccessCategory = 2;
2052 else
2053 AccessCategory = 3;
2054 DBGPRINT(RT_DEBUG_INFO, "Priority = %d, AC = %d\n", Priority, AccessCategory);
2057 // For TKIP, MIC value is treated as payload, it might be fragmented through
2058 // different MPDUs.
2059 if (pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled)
2061 skb->data_len += 8;
2064 pVirtualAddress = (PVOID)skb->data;
2066 // Check for virtual address allocation, it might fail !!!
2067 if (pVirtualAddress == NULL)
2069 // Resourece is low, system did not allocation virtual address
2070 // return NDIS_STATUS_FAILURE directly to upper layer
2071 return (Status);
2074 // Store Ethernet MAC address when APClinet mode on
2075 if ((pAdapter->PortCfg.StaWithEtherBridge.Enable)
2076 && ((*((PUCHAR) pVirtualAddress) & 0x01) == 0)
2077 && !MAC_ADDR_EQUAL(&pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr, ((PUCHAR) pVirtualAddress) + 6)
2078 /*&& !MAC_ADDR_EQUAL(&pAdapter->PermanentAddress, ((PUCHAR) pVirtualAddress) + 6)*/)
2080 CSR3_STRUC StaMacReg0;
2081 CSR4_STRUC StaMacReg1;
2083 COPY_MAC_ADDR(&pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr, ((PUCHAR) pVirtualAddress) + 6);
2085 StaMacReg0.field.Byte0 = pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr.Octet[0];
2086 StaMacReg0.field.Byte1 = pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr.Octet[1];
2087 StaMacReg0.field.Byte2 = pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr.Octet[2];
2088 StaMacReg0.field.Byte3 = pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr.Octet[3];
2090 StaMacReg1.field.Byte4 = pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr.Octet[4];
2091 StaMacReg1.field.Byte5 = pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr.Octet[5];
2093 pAdapter->CurrentAddress[0] = StaMacReg0.field.Byte0;
2094 pAdapter->CurrentAddress[1] = StaMacReg0.field.Byte1;
2095 pAdapter->CurrentAddress[2] = StaMacReg0.field.Byte2;
2096 pAdapter->CurrentAddress[3] = StaMacReg0.field.Byte3;
2097 pAdapter->CurrentAddress[4] = StaMacReg1.field.Byte4;
2098 pAdapter->CurrentAddress[5] = StaMacReg1.field.Byte5;
2100 RTMP_IO_WRITE32(pAdapter, CSR3, StaMacReg0.word);
2101 RTMP_IO_WRITE32(pAdapter, CSR4, StaMacReg1.word);
2103 DBGPRINT(RT_DEBUG_TRACE, "StaWithEtherBridge - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
2104 pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr.Octet[0],pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr.Octet[1],pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr.Octet[2],
2105 pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr.Octet[3],pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr.Octet[4],pAdapter->PortCfg.StaWithEtherBridge.EtherMacAddr.Octet[5]);
2109 // Check for multicast or broadcast (First byte of DA)
2111 if ((*((PUCHAR) pVirtualAddress) & 0x01) != 0)
2113 // For multicast & broadcast, there is no fragment allowed
2114 NumberOfFrag = 1;
2116 else
2118 // Check for payload allowed for each fragment
2119 AllowFragSize = (pAdapter->PortCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;
2121 // Calculate fragments required
2122 NumberOfFrag = ((skb->data_len - LENGTH_802_3 + LENGTH_802_1_H) / AllowFragSize) + 1;
2123 // Minus 1 if the size just match to allowable fragment size
2124 if (((skb->data_len - LENGTH_802_3 + LENGTH_802_1_H) % AllowFragSize) == 0)
2126 NumberOfFrag--;
2130 // Check for requirement of RTS
2131 if (NumberOfFrag > 1)
2133 // If multiple fragment required, RTS is required only for the first fragment
2134 // if the fragment size large than RTS threshold
2135 RTSRequired = (pAdapter->PortCfg.FragmentThreshold > pAdapter->PortCfg.RtsThreshold) ? 1 : 0;
2137 else
2139 RTSRequired = (skb->data_len > pAdapter->PortCfg.RtsThreshold) ? 1 : 0;
2141 DBGPRINT(RT_DEBUG_INFO, "Number of fragments include RTS :%d\n", NumberOfFrag + RTSRequired);
2143 // RTS/CTS may also be required in order to protect OFDM frame
2144 if ((pAdapter->PortCfg.TxRate >= RATE_FIRST_OFDM_RATE) && pAdapter->PortCfg.BGProtectionInUsed)
2145 RTSRequired = 1;
2147 // Save framnet number to Ndis packet reserved field
2148 RTMP_SET_PACKET_FRAGMENTS(skb, NumberOfFrag);
2150 // Save RTS requirement to Ndis packet reserved field
2151 RTMP_SET_PACKET_RTS(skb, RTSRequired);
2153 // Make sure SendTxWait queue resource won't be used by other threads
2154 NdisAcquireSpinLock(&pAdapter->TxSwQueueLock, IrqFlags);
2156 // Select the right priority queue
2157 // There should be no else statement since it should always fall within 0-3
2158 if (AccessCategory== 0)
2159 pTxQueue = &pAdapter->TxSwQueue0;
2160 else if (AccessCategory== 1)
2161 pTxQueue = &pAdapter->TxSwQueue1;
2162 else if (AccessCategory== 2)
2163 pTxQueue = &pAdapter->TxSwQueue2;
2164 else if (AccessCategory== 3)
2165 pTxQueue = &pAdapter->TxSwQueue3;
2168 // For infrastructure mode, enqueue this frame immediately to sendwaitqueue
2169 // For Ad-hoc mode, check the DA power state, then decide which queue to enqueue
2171 if (INFRA_ON(pAdapter))
2173 if(pTxQueue->Number > MAX_PACKETS_IN_QUEUE)
2175 DBGPRINT(RT_DEBUG_WARN, "pTxQueue is full!!!\n\n");
2176 pAdapter->bNetDeviceStopQueue = TRUE;
2177 netif_stop_queue(pAdapter->net_dev);
2180 // In infrastructure mode, simply enqueue the packet into Tx waiting queue.
2181 DBGPRINT(RT_DEBUG_INFO, "Infrastructure -> Enqueue one frame\n");
2183 // Enqueue Ndis packet to end of Tx wait queue
2184 InsertTailQueue(pTxQueue, skb);
2185 Status = NDIS_STATUS_SUCCESS;
2187 else
2189 if(pTxQueue->Number > MAX_PACKETS_IN_QUEUE)
2191 DBGPRINT(RT_DEBUG_WARN, "pTxQueue is full!!!\n\n");
2192 pAdapter->bNetDeviceStopQueue = TRUE;
2193 netif_stop_queue(pAdapter->net_dev);
2196 // In IBSS mode, power state of destination should be considered.
2197 PsMode = PWR_ACTIVE; // Faked
2198 if (PsMode == PWR_ACTIVE)
2200 DBGPRINT(RT_DEBUG_INFO,"Ad-Hoc -> Enqueue one frame\n");
2202 // Enqueue Ndis packet to end of Tx wait queue
2203 InsertTailQueue(pTxQueue, skb);
2204 Status = NDIS_STATUS_SUCCESS;
2208 NdisReleaseSpinLock(&pAdapter->TxSwQueueLock, IrqFlags);
2209 return (Status);
2213 ========================================================================
2215 Routine Description:
2216 To do the enqueue operation and extract the first item of waiting
2217 list. If a number of available shared memory segments could meet
2218 the request of extracted item, the extracted item will be fragmented
2219 into shared memory segments.
2221 Arguments:
2222 pAdapter Pointer to our adapter
2223 pQueue Pointer to Waiting Queue
2225 Return Value:
2226 None
2228 Note:
2230 ========================================================================
2232 VOID RTMPDeQueuePacket(
2233 IN PRTMP_ADAPTER pAdapter)
2235 UCHAR FragmentRequired;
2236 NDIS_STATUS Status;
2237 UCHAR Count = 0;
2238 PQUEUE_HEADER pQueue;
2239 ULONG Number;
2240 UCHAR AccessCategory;
2241 struct sk_buff *skb;
2242 ULONG IrqFlags;
2244 // Make sure SendTxWait queue resource won't be used by other threads
2245 NdisAcquireSpinLock(&pAdapter->TxSwQueueLock, IrqFlags);
2247 while (((pQueue = RTMPCheckTxSwQueue(pAdapter, &Number, &AccessCategory)) != NULL) && (Count < MAX_TX_PROCESS))
2248 // Check queue before dequeue
2249 // while ((pQueue->Head != NULL) && (Count < MAX_TX_PROCESS))
2251 // Reset is in progress, stop immediately
2252 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS))
2254 break;
2257 // Dequeue the first entry from head of queue list
2258 skb = (struct sk_buff *)RemoveHeadQueue(pQueue);
2260 // RTS or CTS-to-self for B/G protection mode has been set already.
2261 // There is no need to re-do it here.
2262 // Total fragment required = number of fragment + RST if required
2263 FragmentRequired = RTMP_GET_PACKET_FRAGMENTS(skb) + RTMP_GET_PACKET_RTS(skb);
2265 if (RTMPFreeDescriptorRequest(pAdapter, TX_RING, FragmentRequired) == NDIS_STATUS_SUCCESS)
2267 // Avaliable ring descriptors are enough for this frame
2268 // Call hard transmit
2269 // Nitro mode / Normal mode selection
2270 if ((pAdapter->PortCfg.EnableTxBurst == 1) && (Number > 1))
2271 Status = RTMPHardEncrypt(pAdapter, skb, FragmentRequired, TRUE, AccessCategory);
2272 else
2273 Status = RTMPHardEncrypt(pAdapter, skb, FragmentRequired, FALSE, AccessCategory);
2274 if (Status == NDIS_STATUS_FAILURE)
2276 // Packet failed due to various Ndis Packet error
2277 RTMPFreeSkbBuffer(skb);
2278 break;
2280 else if (Status == NDIS_STATUS_RESOURCES)
2282 // Not enough free tx ring, it might happen due to free descriptor inquery might be not correct
2283 // It also might change to NDIS_STATUS_FAILURE to simply drop the frame
2284 // Put the frame back into head of queue
2285 InsertHeadQueue(pQueue, skb);
2286 break;
2288 Count++;
2290 else
2292 InsertHeadQueue(pQueue, skb);
2293 pAdapter->PrivateInfo.TxRingFullCnt++;
2294 DBGPRINT(RT_DEBUG_INFO,"RTMPDequeuePacket --> Not enough free Tx Ring descriptor (CurEncryptIndex=%d,CurTxIndex=%d, NextTxDoneIndex=%d)!!!\n",
2295 pAdapter->CurEncryptIndex, pAdapter->CurTxIndex, pAdapter->NextTxDoneIndex);
2296 break;
2300 // Release TxSwQueue0 resources
2301 NdisReleaseSpinLock(&pAdapter->TxSwQueueLock, IrqFlags);
2305 ========================================================================
2307 Routine Description:
2308 This subroutine will scan through releative ring descriptor to find
2309 out avaliable free ring descriptor and compare with request size.
2311 Arguments:
2312 pAdapter Pointer to our adapter
2313 RingType Selected Ring
2315 Return Value:
2316 NDIS_STATUS_FAILURE Not enough free descriptor
2317 NDIS_STATUS_SUCCESS Enough free descriptor
2319 Note:
2321 ========================================================================
2323 NDIS_STATUS RTMPFreeDescriptorRequest(
2324 IN PRTMP_ADAPTER pAdapter,
2325 IN UCHAR RingType,
2326 IN UCHAR NumberRequired)
2328 UCHAR FreeNumber = 0;
2329 UINT Index;
2330 PTXD_STRUC pTxD;
2331 #ifdef BIG_ENDIAN
2332 PTXD_STRUC pDestTxD;
2333 TXD_STRUC TxD;
2334 #endif
2335 NDIS_STATUS Status = NDIS_STATUS_FAILURE;
2336 ULONG IrqFlags;
2338 switch (RingType)
2340 case TX_RING:
2341 NdisAcquireSpinLock(&pAdapter->TxRingLock, IrqFlags);
2342 Index = pAdapter->CurEncryptIndex;
2345 #ifndef BIG_ENDIAN
2346 pTxD = (PTXD_STRUC) pAdapter->TxRing[Index].va_addr;
2347 #else
2348 pDestTxD = (PTXD_STRUC) pAdapter->TxRing[Index].va_addr;
2349 TxD = *pDestTxD;
2350 pTxD = &TxD;
2351 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2352 #endif
2354 // While Owner bit is NIC, obviously ASIC still need it.
2355 // If valid bit is TRUE, indicate that TxDone has not process yet
2356 // We should not use it until TxDone finish cleanup job
2357 if ((pTxD->Owner == DESC_OWN_HOST) && (pTxD->CipherOwn == DESC_OWN_HOST) && (pTxD->Valid == FALSE))
2359 // This one is free
2360 FreeNumber++;
2362 else
2364 DBGPRINT(RT_DEBUG_INFO,"RTMPFreeDescriptorRequest fail - Owner=%d,CipherOwn=%d,Valid=%d\n",pTxD->Owner, pTxD->CipherOwn, pTxD->Valid);
2365 break;
2368 Index++;
2369 if (Index >= TX_RING_SIZE) // Wrap around issue
2371 Index = 0;
2374 } while (FreeNumber < NumberRequired); // Quit here ! Free number is enough !
2376 if (FreeNumber >= NumberRequired)
2378 Status = NDIS_STATUS_SUCCESS;
2381 // Make sure to release Tx ring resource
2382 NdisReleaseSpinLock(&pAdapter->TxRingLock, IrqFlags);
2383 break;
2385 case PRIO_RING:
2386 NdisAcquireSpinLock(&pAdapter->PrioRingLock, IrqFlags);
2387 Index = pAdapter->CurPrioIndex;
2390 #ifndef BIG_ENDIAN
2391 pTxD = (PTXD_STRUC) pAdapter->PrioRing[Index].va_addr;
2392 #else
2393 pDestTxD = (PTXD_STRUC) pAdapter->PrioRing[Index].va_addr;
2394 TxD = *pDestTxD;
2395 pTxD = &TxD;
2396 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2397 #endif
2399 // While Owner bit is NIC, obviously ASIC still need it.
2400 // If valid bit is TRUE, indicate that TxDone has not process yet
2401 // We should not use it until TxDone finish cleanup job
2402 if ((pTxD->Owner == DESC_OWN_HOST) && (pTxD->Valid == FALSE))
2404 // This one is free
2405 FreeNumber++;
2407 else
2409 break;
2412 Index++;
2413 if (Index >= PRIO_RING_SIZE) // Wrap around issue
2415 Index = 0;
2418 } while (FreeNumber < NumberRequired); // Quit here ! Free number is enough !
2420 if (FreeNumber >= NumberRequired)
2422 Status = NDIS_STATUS_SUCCESS;
2425 // Make sure to release Prio ring resource
2426 NdisReleaseSpinLock(&pAdapter->PrioRingLock, IrqFlags);
2427 break;
2429 default:
2430 break;
2433 return (Status);
2436 VOID RTMPSendNullFrame(
2437 IN PRTMP_ADAPTER pAdapter,
2438 IN PVOID pBuffer,
2439 IN ULONG Length,
2440 IN UCHAR TxRate)
2442 PUCHAR pDest;
2443 PTXD_STRUC pTxD;
2444 UCHAR FrameGap;
2445 #ifdef BIG_ENDIAN
2446 PTXD_STRUC pDestTxD;
2447 TXD_STRUC TxD;
2448 #endif
2449 ULONG IrqFlags;
2451 if (pBuffer == NULL)
2453 return;
2456 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS))
2458 MlmeFreeMemory(pAdapter, pBuffer);
2459 return;
2462 // WPA 802.1x secured port control
2463 if (((pAdapter->PortCfg.AuthMode == Ndis802_11AuthModeWPA) ||
2464 (pAdapter->PortCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) &&
2465 (pAdapter->PortCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
2467 MlmeFreeMemory(pAdapter, pBuffer);
2468 return;
2471 FrameGap = IFS_BACKOFF; // Default frame gap mode
2473 // outgoing frame always wakeup PHY to prevent frame lost and
2474 // turn off PSM bit to improve performance
2475 AsicForceWakeup(pAdapter);
2476 #if 0
2477 if ((pAdapter->TxSwQueue0.Number != 0) || (pAdapter->TxSwQueue1.Number != 0) ||
2478 (pAdapter->TxSwQueue2.Number != 0) || (pAdapter->TxSwQueue3.Number != 0))
2480 DBGPRINT(RT_DEBUG_TRACE,("Drop Null frame due to Tx queue not empty!\n"));
2482 else
2483 #endif
2485 // Make sure Tx ring resource won't be used by other threads
2486 NdisAcquireSpinLock(&pAdapter->TxRingLock, IrqFlags);
2488 // Get the Tx Ring descriptor & Dma Buffer address
2489 pDest = (PUCHAR) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_data_addr;
2490 #ifndef BIG_ENDIAN
2491 pTxD = (PTXD_STRUC) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_addr;
2492 #else
2493 pDestTxD = (PTXD_STRUC) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_addr;
2494 TxD = *pDestTxD;
2495 pTxD = &TxD;
2496 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2497 #endif
2499 if ((pTxD->Owner == DESC_OWN_HOST) && (pTxD->CipherOwn == DESC_OWN_HOST) && (pTxD->Valid == FALSE))
2501 HEADER_802_11 *pHeader_802_11;
2503 DBGPRINT(RT_DEBUG_TRACE, "SYNC - send NULL Frame @%d Mbps...\n", RateIdToMbps[TxRate]);
2504 #ifdef BIG_ENDIAN
2505 RTMPFrameEndianChange(pAdapter, (PUCHAR)pBuffer, DIR_WRITE, FALSE);
2506 #endif
2507 NdisMoveMemory(pDest, pBuffer, Length);
2508 pAdapter->TxRing[pAdapter->CurEncryptIndex].FrameType = BTYPE_DATA;
2510 pHeader_802_11 = (PHEADER_802_11) pDest;
2511 pHeader_802_11->Controlhead.Frame.PwrMgt = (pAdapter->PortCfg.Psm == PWR_SAVE);
2513 #ifdef BIG_ENDIAN
2514 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2515 *pDestTxD = TxD;
2516 pTxD = pDestTxD;
2517 #endif
2519 RTMPWriteTxDescriptor(pTxD, TRUE, CIPHER_NONE, TRUE, FALSE, FALSE, LONG_RETRY, IFS_BACKOFF,
2520 TxRate, 4, Length, pAdapter->PortCfg.TxPreambleInUsed, 0);
2522 // Increase & maintain Tx Ring Index
2523 pAdapter->CurEncryptIndex++;
2524 if (pAdapter->CurEncryptIndex >= TX_RING_SIZE)
2526 pAdapter->CurEncryptIndex = 0;
2529 pAdapter->RalinkCounters.EncryptCount++;
2531 // Kick Encrypt Control Register at the end of all ring buffer preparation
2532 RTMP_IO_WRITE32(pAdapter, SECCSR1, 0x1);
2535 NdisReleaseSpinLock(&pAdapter->TxRingLock, IrqFlags);
2537 MlmeFreeMemory(pAdapter, pBuffer);
2541 ========================================================================
2543 Routine Description:
2544 Copy frame from waiting queue into relative ring buffer and set
2545 appropriate ASIC register to kick hardware encryption before really
2546 sent out to air.
2548 Arguments:
2549 pAdapter Pointer to our adapter
2550 PNDIS_PACKET Pointer to outgoing Ndis frame
2551 NumberOfFrag Number of fragment required
2553 Return Value:
2554 None
2556 Note:
2558 ========================================================================
2560 NDIS_STATUS RTMPHardEncrypt(
2561 IN PRTMP_ADAPTER pAdapter,
2562 IN struct sk_buff *skb,
2563 IN UCHAR NumberRequired,
2564 IN ULONG EnableTxBurst,
2565 IN UCHAR AccessCategory)
2567 PVOID pVirtualAddress;
2568 UINT NdisBufferLength;
2569 UINT BytesCopied;
2570 UINT TxSize;
2571 UINT FreeFragSize;
2572 UINT RemainSize;
2573 USHORT Protocol;
2574 UCHAR FrameGap;
2575 HEADER_802_11 Header_802_11;
2576 PUCHAR pDest;
2577 PUCHAR pSrc;
2578 PUCHAR pEncap;
2579 UCHAR CipherAlg;
2580 PTXD_STRUC pTxD;
2581 BOOLEAN StartOfFrame;
2582 BOOLEAN EAPOLFrame;
2583 BOOLEAN Encapped;
2584 ULONG Iv16;
2585 ULONG Iv32;
2586 BOOLEAN MICFrag;
2587 PWPA_KEY pWpaKey = NULL;
2588 UCHAR RetryMode = SHORT_RETRY;
2589 UCHAR AckRate = RATE_2;
2590 USHORT AckDuration = 0;
2591 USHORT EncryptionOverhead = 0;
2592 #ifdef BIG_ENDIAN
2593 PTXD_STRUC pDestTxD;
2594 TXD_STRUC TxD;
2595 PUCHAR pOriginDest;
2596 #endif
2597 ULONG IrqFlags;
2599 // Make sure Tx ring resource won't be used by other threads
2600 NdisAcquireSpinLock(&pAdapter->TxRingLock, IrqFlags);
2602 if(skb->data == NULL)
2604 DBGPRINT(RT_DEBUG_ERROR, "Error, Null skb data buffer!!!\n");
2606 NdisReleaseSpinLock(&pAdapter->TxRingLock, IrqFlags);
2607 return (NDIS_STATUS_FAILURE);
2610 if (EnableTxBurst == 1)
2611 FrameGap = IFS_SIFS;
2612 else
2613 FrameGap = IFS_BACKOFF; // Default frame gap mode
2615 // outgoing frame always wakeup PHY to prevent frame lost and
2616 // turn off PSM bit to improve performance
2617 if (pAdapter->PortCfg.Psm == PWR_SAVE)
2619 MlmeSetPsmBit(pAdapter, PWR_ACTIVE);
2621 AsicForceWakeup(pAdapter);
2623 // Sequence Number is identical for all fragments belonged to the same frame
2624 // Sequence is 0 - 4095
2625 pAdapter->Sequence = ((pAdapter->Sequence) + 1) & (MAX_SEQ_NUMBER);
2627 AckRate = pAdapter->PortCfg.ExpectedACKRate[pAdapter->PortCfg.TxRate];
2628 AckDuration = RTMPCalcDuration(pAdapter, AckRate, 14);
2630 pVirtualAddress = skb->data;
2631 NdisBufferLength = skb->len;
2633 if ((*((PUCHAR) pVirtualAddress) & 0x01) != 0) // Multicast or Broadcast
2635 INC_COUNTER(pAdapter->WlanCounters.MulticastTransmittedFrameCount);
2638 if (NdisBufferLength < 14)
2640 DBGPRINT(RT_DEBUG_ERROR,"RTMPHardTransmit --> Ndis Packet buffer error !!!\n");
2641 // Make sure to release Tx ring resource
2642 NdisReleaseSpinLock(&pAdapter->TxRingLock, IrqFlags);
2643 return (NDIS_STATUS_FAILURE);
2647 // Start making 802.11 frame header
2649 NdisZeroMemory(&Header_802_11, sizeof(HEADER_802_11)); // Initialize 802.11 header for each fragment
2650 if (INFRA_ON(pAdapter))
2652 // Address 1 - AP, Address 2 - this STA, Address 3 - DA
2653 NdisMoveMemory(&Header_802_11.Controlhead.Addr1, &pAdapter->PortCfg.Bssid, ETH_LENGTH_OF_ADDRESS);
2654 NdisMoveMemory(&Header_802_11.Addr3, (PUCHAR) pVirtualAddress, ETH_LENGTH_OF_ADDRESS);
2655 Header_802_11.Controlhead.Frame.ToDs = 1;
2657 else
2659 // Address 1 - DA, Address 2 - this STA, Address 3 - BSSID
2660 NdisMoveMemory(&Header_802_11.Controlhead.Addr1, (PUCHAR) pVirtualAddress, ETH_LENGTH_OF_ADDRESS);
2661 NdisMoveMemory(&Header_802_11.Addr3, &pAdapter->PortCfg.Bssid, ETH_LENGTH_OF_ADDRESS);
2663 NdisMoveMemory(&Header_802_11.Controlhead.Addr2, pAdapter->CurrentAddress, ETH_LENGTH_OF_ADDRESS);
2665 Header_802_11.Sequence = pAdapter->Sequence; // Sequence number
2666 Header_802_11.Controlhead.Frame.Type = BTYPE_DATA; // Frame type
2667 Header_802_11.Controlhead.Frame.PwrMgt = (pAdapter->PortCfg.Psm == PWR_SAVE);
2669 // Add 802.11x protocol check.
2670 // For non-WPA network, 802.1x message should not encrypt even
2671 // the privacy is on.
2672 if (RTMPEqualMemory(EAPOL, ((PUCHAR) pVirtualAddress) + 12, 2))
2674 EAPOLFrame = TRUE;
2675 if (pAdapter->PortCfg.MicErrCnt >= 2)
2676 pAdapter->PortCfg.MicErrCnt++;
2678 else
2679 EAPOLFrame = FALSE;
2681 // WPA 802.1x secured port control
2682 if (((pAdapter->PortCfg.AuthMode == Ndis802_11AuthModeWPA) ||
2683 (pAdapter->PortCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) &&
2684 ((pAdapter->PortCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) || (pAdapter->PortCfg.MicErrCnt >= 2)) &&
2685 (EAPOLFrame == FALSE))
2687 DBGPRINT(RT_DEBUG_TRACE,"RTMPHardEncrypt --> Drop packet before port secured !!!\n");
2688 // Make sure to release Tx ring resource
2689 NdisReleaseSpinLock(&pAdapter->TxRingLock, IrqFlags);
2690 return (NDIS_STATUS_FAILURE);
2693 MICFrag = FALSE; // Flag to indicate MIC shall spread into two MPDUs
2694 Encapped = FALSE;
2695 pEncap = NULL;
2697 pSrc = (PUCHAR) pVirtualAddress;
2698 Protocol = *(pSrc + 12) * 256 + *(pSrc + 13);
2699 if (Protocol > 1500) // CHeck for LLC encaped
2701 pEncap = SNAP_802_1H;
2702 Encapped = TRUE;
2703 if (RTMPEqualMemory(IPX, pSrc + 12, 2) ||
2704 RTMPEqualMemory(APPLE_TALK, pSrc + 12, 2))
2706 pEncap = SNAP_BRIDGE_TUNNEL;
2710 if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption1Enabled) &&
2711 (pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].KeyLen != 0))
2712 EncryptionOverhead = 8; // WEP: IV + ICV
2713 else if (pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled)
2714 EncryptionOverhead = 12; // TKIP: IV + EIV + ICV, MIC already added to TotalPacketLength
2715 else if (pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled)
2716 EncryptionOverhead = 16; // AES: IV + EIV + Hardware MIC
2717 else
2718 EncryptionOverhead = 0;
2721 // Make RTS frame if required
2723 if (RTMP_GET_PACKET_RTS(skb))
2725 PCONTROL_HEADER pControlHeader;
2726 ULONG NextFragSize;
2728 // RTS-protected frame should use LONG_RETRY (=4), other frames use SHORT_RETRY (=7)
2729 RetryMode = LONG_RETRY;
2731 pDest = (PUCHAR) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_data_addr;
2732 #ifndef BIG_ENDIAN
2733 pTxD = (PTXD_STRUC) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_addr;
2734 #else
2735 pDestTxD = (PTXD_STRUC) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_addr;
2736 TxD = *pDestTxD;
2737 pTxD = &TxD;
2738 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2739 #endif
2741 if ((pTxD->Owner == DESC_OWN_NIC) || (pTxD->CipherOwn == DESC_OWN_NIC))
2743 // Descriptor owned by NIC. No descriptor avaliable
2744 // This should not happen since caller guaranteed.
2745 // Make sure to release Tx ring resource
2746 NdisReleaseSpinLock(&pAdapter->TxRingLock, IrqFlags);
2747 return (NDIS_STATUS_RESOURCES);
2749 if (pTxD->Valid == TRUE)
2751 // This might happen when HardTransmit process faster than TxDone interrupt.
2752 // However, Since we did call free descriptor number check before Tx HardTransmit.
2753 // This case should not happened. We should return to higher caller and requeue this
2754 // acket until next Tx hardtransmit. Hopefully this situation is corrected then.
2755 // Ndis packet of last round did not cleared.
2756 // This should not happen since caller guaranteed.
2757 // Make sure to release Tx ring resource
2758 pTxD->Valid = FALSE;
2759 #ifdef BIG_ENDIAN
2760 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2761 *pDestTxD = TxD;
2762 #endif
2764 NdisReleaseSpinLock(&pAdapter->TxRingLock, IrqFlags);
2765 return (NDIS_STATUS_RESOURCES);
2768 pAdapter->TxRing[pAdapter->CurEncryptIndex].FrameType = BTYPE_CNTL;
2769 pControlHeader = (PCONTROL_HEADER) pDest;
2770 NdisZeroMemory(pControlHeader, sizeof(CONTROL_HEADER));
2771 pControlHeader->Frame.Type = BTYPE_CNTL;
2773 // Calculate duration = 2 SIFS + CTS + Data Frame size
2774 if (RTMP_GET_PACKET_FRAGMENTS(skb) > 1)
2776 // If fragment required, size is maximum fragment size
2777 NextFragSize = pAdapter->PortCfg.FragmentThreshold;
2779 else
2781 // Size should be frame with 802.11 header & CRC
2782 NextFragSize = skb->data_len + LENGTH_802_11 + LENGTH_CRC - LENGTH_802_3;
2784 if (Encapped)
2785 NextFragSize += LENGTH_802_1_H;
2787 pControlHeader->Duration = 2 * (pAdapter->PortCfg.Dsifs)
2788 + RTMPCalcDuration(pAdapter, pAdapter->PortCfg.TxRate, NextFragSize + EncryptionOverhead)
2789 + AckDuration;
2791 // Write Tx descriptor
2792 // Don't kick tx start until all frames are prepared
2793 // RTS has to set more fragment bit for fragment burst
2794 // RTS did not encrypt
2795 if (pAdapter->PortCfg.BGProtectionInUsed == 1)
2797 DBGPRINT(RT_DEBUG_TRACE,"Making CTS-to-self Frame\n");
2798 pControlHeader->Frame.Subtype = SUBTYPE_CTS;
2799 NdisMoveMemory(&pControlHeader->Addr1, pAdapter->CurrentAddress, ETH_LENGTH_OF_ADDRESS);
2801 // Write Tx descriptor
2802 // Don't kick tx start until all frames are prepared
2803 // CTS has to set more fragment bit for fragment burst
2804 // CTS did not encrypt
2805 // CTS-to-self will never receive ACK
2806 #ifdef BIG_ENDIAN
2807 RTMPFrameEndianChange(pAdapter, (PUCHAR)pControlHeader, DIR_WRITE, FALSE);
2808 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2809 *pDestTxD = TxD;
2810 pTxD = pDestTxD;
2811 #endif
2813 #ifdef WIFI_TEST
2814 RTMPWriteTxDescriptor(pTxD, TRUE, CIPHER_NONE, FALSE, FALSE, FALSE, SHORT_RETRY,
2815 FrameGap, pAdapter->PortCfg.RtsRate, 4, 10, Rt802_11PreambleShort,
2816 AccessCategory);
2817 #else
2818 RTMPWriteTxDescriptor(pTxD, TRUE, CIPHER_NONE, FALSE, FALSE, FALSE, SHORT_RETRY,
2819 FrameGap, pAdapter->PortCfg.RtsRate, 4, 10, pAdapter->PortCfg.TxPreambleInUsed,
2820 AccessCategory);
2821 #endif
2823 else
2825 DBGPRINT(RT_DEBUG_TRACE,"Making RTS Frame\n");
2826 pControlHeader->Frame.Subtype = SUBTYPE_RTS;
2827 if (INFRA_ON(pAdapter))
2828 NdisMoveMemory(&pControlHeader->Addr1, &pAdapter->PortCfg.Bssid, ETH_LENGTH_OF_ADDRESS);
2829 else
2830 NdisMoveMemory(&pControlHeader->Addr1, (PUCHAR) pVirtualAddress, ETH_LENGTH_OF_ADDRESS);
2831 NdisMoveMemory(&pControlHeader->Addr2, pAdapter->CurrentAddress, ETH_LENGTH_OF_ADDRESS);
2833 // Write Tx descriptor
2834 // Don't kick tx start until all frames are prepared
2835 // RTS has to set more fragment bit for fragment burst
2836 // RTS did not encrypt
2837 pTxD->RTS = 1;
2838 #ifdef BIG_ENDIAN
2839 RTMPFrameEndianChange(pAdapter, (PUCHAR)pControlHeader, DIR_WRITE, FALSE);
2840 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2841 *pDestTxD = TxD;
2842 pTxD = pDestTxD;
2843 #endif
2844 RTMPWriteTxDescriptor(pTxD, TRUE, CIPHER_NONE, TRUE, TRUE, FALSE, SHORT_RETRY,
2845 FrameGap, pAdapter->PortCfg.RtsRate, 4, sizeof(CONTROL_HEADER),
2846 pAdapter->PortCfg.TxPreambleInUsed, AccessCategory);
2851 FrameGap = IFS_SIFS; // Init frame gap for coming data after RTS
2852 NumberRequired--;
2854 // Increase & maintain Tx Ring Index
2855 pAdapter->CurEncryptIndex++;
2856 if (pAdapter->CurEncryptIndex >= TX_RING_SIZE)
2858 pAdapter->CurEncryptIndex = 0;
2860 pAdapter->RalinkCounters.EncryptCount++;
2863 // Find the WPA key, either Group or Pairwise Key
2864 if (pAdapter->PortCfg.AuthMode >= Ndis802_11AuthModeWPA)
2866 INT idx;
2868 pWpaKey = (PWPA_KEY) NULL;
2869 // First lookup the DA, if it's a group address, use GROUP key
2870 if (Header_802_11.Controlhead.Addr1.Octet[0] & 0x01)
2872 if (pAdapter->PortCfg.GroupKey[pAdapter->PortCfg.DefaultKeyId].KeyLen != 0)
2874 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.GroupKey[pAdapter->PortCfg.DefaultKeyId];
2875 pWpaKey->Type = GROUP_KEY;
2876 DBGPRINT(RT_DEBUG_INFO, "Tx Use Group Key\n");
2879 // Try to find the Pairwise Key
2880 else
2882 for (idx = 0; idx < PAIRWISE_KEY_NO; idx++)
2884 if ((NdisEqualMemory(&Header_802_11.Controlhead.Addr1, pAdapter->PortCfg.PairwiseKey[idx].BssId, 6)) &&
2885 (pAdapter->PortCfg.PairwiseKey[idx].KeyLen != 0))
2887 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.PairwiseKey[idx];
2888 pWpaKey->Type = PAIRWISE_KEY;
2889 DBGPRINT(RT_DEBUG_INFO, "Tx Use Pairwise Key\n");
2890 break;
2893 // Use default Group Key if there is no Pairwise key present
2894 if ((pAdapter->PortCfg.GroupKey[pAdapter->PortCfg.DefaultKeyId].KeyLen != 0) && (pWpaKey == NULL))
2896 pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.GroupKey[pAdapter->PortCfg.DefaultKeyId];
2897 pWpaKey->Type = GROUP_KEY;
2898 DBGPRINT(RT_DEBUG_INFO, "Tx Use Group Key\n");
2903 // For the purpose to calculate duration for the second last fragment
2904 RemainSize = skb->data_len - LENGTH_802_3 + LENGTH_CRC;
2906 StartOfFrame = TRUE;
2907 // Start Copy Ndis Packet into Ring buffer.
2908 // For frame required more than one ring buffer (fragment), all ring buffers
2909 // have to be filled before kicking start tx bit.
2912 // Get the Tx Ring descriptor & Dma Buffer address
2913 #ifndef BIG_ENDIAN
2914 pDest = (PUCHAR) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_data_addr;
2915 pTxD = (PTXD_STRUC) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_addr;
2916 #else
2917 pDest = (PUCHAR) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_data_addr;
2918 pOriginDest = pDest;
2919 pDestTxD = (PTXD_STRUC) pAdapter->TxRing[pAdapter->CurEncryptIndex].va_addr;
2920 TxD = *pDestTxD;
2921 pTxD = &TxD;
2922 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2923 #endif
2925 if ((pTxD->Owner == DESC_OWN_NIC) || (pTxD->CipherOwn == DESC_OWN_NIC))
2927 // Descriptor owned by NIC. No descriptor avaliable
2928 // This should not happen since caller guaranteed.
2929 // Make sure to release Tx ring resource
2930 pAdapter->RalinkCounters.TxRingErrCount++;
2931 NdisReleaseSpinLock(&pAdapter->TxRingLock, IrqFlags);
2932 return (NDIS_STATUS_RESOURCES);
2934 if (pTxD->Valid == TRUE)
2936 // Ndis packet of last round did not cleared.
2937 // This should not happen since caller guaranteed.
2938 // Make sure to release Tx ring resource
2939 pTxD->Valid = FALSE;
2941 #ifdef BIG_ENDIAN
2942 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2943 *pDestTxD = TxD;
2944 #endif
2946 pAdapter->RalinkCounters.TxRingErrCount++;
2947 NdisReleaseSpinLock(&pAdapter->TxRingLock, IrqFlags);
2948 return (NDIS_STATUS_RESOURCES);
2950 pAdapter->TxRing[pAdapter->CurEncryptIndex].FrameType = BTYPE_DATA;
2952 // Make fragment number & more fragment bit of 802.11 header
2953 if (StartOfFrame == TRUE)
2954 Header_802_11.Frag = 0; // Start of fragment burst / Single Frame
2955 else
2956 Header_802_11.Frag++; // Rest of fragmented frames.
2958 // Maximum allowable payload with one ring buffer, bound by fragment size
2959 FreeFragSize = pAdapter->PortCfg.FragmentThreshold - LENGTH_CRC;
2962 // calculate "duration" field of this fragment
2964 if (NumberRequired > 1)
2966 ULONG NextFragSize;
2967 Header_802_11.Controlhead.Frame.MoreFrag = 1;
2969 if (NumberRequired == 2)
2970 NextFragSize = RemainSize - pAdapter->PortCfg.FragmentThreshold + LENGTH_802_11 + LENGTH_802_11 + LENGTH_CRC;
2971 else
2972 NextFragSize = pAdapter->PortCfg.FragmentThreshold;
2974 Header_802_11.Controlhead.Duration = 3 * pAdapter->PortCfg.Dsifs
2975 + 2 * AckDuration
2976 + RTMPCalcDuration(pAdapter, pAdapter->PortCfg.TxRate, NextFragSize + EncryptionOverhead);
2978 else // this is the last or only fragment
2980 Header_802_11.Controlhead.Frame.MoreFrag = 0;
2982 if (Header_802_11.Controlhead.Addr1.Octet[0] & 0x01) // multicast/broadcast
2983 Header_802_11.Controlhead.Duration = 0;
2984 else
2985 Header_802_11.Controlhead.Duration = pAdapter->PortCfg.Dsifs + AckDuration;
2988 // Check for WEP enable bit and prepare for software WEP
2989 if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption1Enabled) && (EAPOLFrame == FALSE) &&
2990 (pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].KeyLen != 0))
2991 Header_802_11.Controlhead.Frame.Wep = 1;
2992 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) && (pWpaKey != NULL))
2993 Header_802_11.Controlhead.Frame.Wep = 1;
2994 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled) && (pWpaKey != NULL))
2995 Header_802_11.Controlhead.Frame.Wep = 1;
2998 // Copy 802.11 header to Tx ring buffer
3000 NdisMoveMemory(pDest, &Header_802_11, sizeof(Header_802_11));
3001 pDest += sizeof(Header_802_11);
3002 FreeFragSize -= sizeof(Header_802_11);
3004 DBGPRINT(RT_DEBUG_INFO,"pWpaKey = %s\n", pWpaKey == NULL ? "NULL" : "not NULL");
3006 if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption1Enabled) && (EAPOLFrame == FALSE) &&
3007 (pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].KeyLen != 0))
3009 DBGPRINT(RT_DEBUG_INFO,"Ndis802_11Encryption1Enabled::DefaultKeyId = %d\n", pAdapter->PortCfg.DefaultKeyId);
3011 // Prepare IV, IV offset, Key for Hardware encryption
3012 RTMPInitWepEngine(
3013 pAdapter,
3014 pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].Key,
3015 pAdapter->PortCfg.DefaultKeyId,
3016 pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].KeyLen,
3017 (PUCHAR) &pTxD->Iv);
3019 if (pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].KeyLen == 5)
3020 CipherAlg = CIPHER_WEP64;
3021 else
3022 CipherAlg = CIPHER_WEP128;
3024 // Set Iv offset in TxD
3025 pTxD->IvOffset = LENGTH_802_11;
3026 // Copy Encrypt Key to TxD
3027 NdisMoveMemory(
3028 pTxD->Key,
3029 pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].Key,
3030 pAdapter->PortCfg.SharedKey[pAdapter->PortCfg.DefaultKeyId].KeyLen);
3032 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) && (pWpaKey != NULL))
3034 INT i = 0;
3036 DBGPRINT(RT_DEBUG_INFO,"Ndis802_11Encryption2Enabled::DefaultKeyId = %d\n", pAdapter->PortCfg.DefaultKeyId);
3038 // Prepare 8 bytes TKIP encapsulation for MPDU
3040 TKIP_IV tkipIv;
3042 tkipIv.IV16.field.rc0 = *(pWpaKey->TxTsc + 1);
3043 tkipIv.IV16.field.rc1 = (tkipIv.IV16.field.rc0 | 0x20) & 0x7f;
3044 tkipIv.IV16.field.rc2 = *pWpaKey->TxTsc;
3045 tkipIv.IV16.field.ExtIV = 1; // 0: non-extended IV, 1: an extended IV
3046 tkipIv.IV16.field.KeyID = pAdapter->PortCfg.DefaultKeyId;
3047 //tkipIv.IV32 = *(PULONG)(pWpaKey->TxTsc + 2);
3048 NdisMoveMemory(&tkipIv.IV32, &pWpaKey->TxTsc[2], 4);
3050 #ifdef BIG_ENDIAN
3051 pTxD->Iv = SWAP32(tkipIv.IV16.word);
3052 #else
3053 pTxD->Iv = tkipIv.IV16.word;
3054 #endif
3056 *((PUCHAR) &pTxD->Eiv) = *((PUCHAR) &tkipIv.IV32 + 3);
3057 *((PUCHAR) &pTxD->Eiv + 1) = *((PUCHAR) &tkipIv.IV32 + 2);
3058 *((PUCHAR) &pTxD->Eiv + 2) = *((PUCHAR) &tkipIv.IV32 + 1);
3059 *((PUCHAR) &pTxD->Eiv + 3) = *((PUCHAR) &tkipIv.IV32);
3062 // Increase TxTsc value for next transmission
3063 while (++pWpaKey->TxTsc[i] == 0x0)
3065 i++;
3066 if (i == 6)
3067 break;
3070 // Set IV offset
3071 pTxD->IvOffset = LENGTH_802_11;
3073 // Copy TKey
3074 NdisMoveMemory(pTxD->Key, pWpaKey->Key, 16);
3076 // Set Cipher suite
3077 CipherAlg = CIPHER_TKIP;
3079 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled) && (pWpaKey != NULL))
3081 INT i;
3082 PUCHAR pTmp;
3084 DBGPRINT(RT_DEBUG_INFO,"Ndis802_11Encryption3Enabled::DefaultKeyId = %d\n", pAdapter->PortCfg.DefaultKeyId);
3086 i = 0;
3087 pTmp = (PUCHAR) &Iv16;
3088 *pTmp = pWpaKey->TxTsc[0];
3089 *(pTmp + 1) = pWpaKey->TxTsc[1];
3090 *(pTmp + 2) = 0;
3091 *(pTmp + 3) = (pAdapter->PortCfg.DefaultKeyId << 6) | 0x20;
3093 //Iv32 = *(PULONG)(&pWpaKey->TxTsc[2]);
3094 NdisMoveMemory(&Iv32, &pWpaKey->TxTsc[2], 4);
3096 // Increase TxTsc value for next transmission
3097 while (++pWpaKey->TxTsc[i] == 0x0)
3099 i++;
3100 if (i == 6)
3101 break;
3103 if (i == 6)
3105 // TODO: TSC has done one full cycle, do re-keying stuff follow specs
3106 // Should send a special event microsoft defined to request re-key
3109 NdisMoveMemory(&pTxD->Iv, &Iv16, 4); // Copy IV
3110 NdisMoveMemory(&pTxD->Eiv, &Iv32, 4); // Copy EIV
3111 pTxD->IvOffset = LENGTH_802_11; // Set IV offset
3112 NdisMoveMemory(pTxD->Key, pWpaKey->Key, 16); // Copy TKey
3113 CipherAlg = CIPHER_AES; // Set Cipher suite
3115 else
3116 CipherAlg = CIPHER_NONE;
3119 // Only the first fragment required LLC-SNAP header !!!
3121 if ((StartOfFrame == TRUE) && (Encapped == TRUE))
3123 // For WEP & no encryption required frame, just copy LLC header into buffer,
3124 // Hardware will do the encryption job.
3125 // For TKIP, we have to calculate MIC and store it first
3126 if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) && (pWpaKey != NULL))
3128 // Calculate MSDU MIC Value
3129 RTMPCalculateMICValue(pAdapter, skb, pEncap, 6, pWpaKey);
3132 // Copy LLC header
3133 NdisMoveMemory(pDest, pEncap, 6);
3134 pDest += 6;
3136 // Copy protocol type
3137 pSrc = (PUCHAR) pVirtualAddress;
3138 NdisMoveMemory(pDest, pSrc + 12, 2);
3139 pDest += 2;
3141 // Exclude 802.3 header size, we will recalculate the size at
3142 // the end of fragment preparation.
3143 NdisBufferLength -= LENGTH_802_3;
3144 pSrc += LENGTH_802_3;
3145 FreeFragSize -= LENGTH_802_1_H;
3147 else if ((StartOfFrame == TRUE) && (Encapped == FALSE))
3149 if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) && (pWpaKey != NULL))
3151 // Calculate MSDU MIC Value
3152 RTMPCalculateMICValue(pAdapter, skb, pEncap, 0, pWpaKey);
3155 pSrc = (PUCHAR) pVirtualAddress + LENGTH_802_3;
3156 NdisBufferLength -= LENGTH_802_3;
3159 // Start copying payload
3160 BytesCopied = 0;
3163 if (NdisBufferLength >= FreeFragSize)
3165 // Copy only the free fragment size, and save the pointer
3166 // of current buffer descriptor for next fragment buffer.
3167 NdisMoveMemory(pDest, pSrc, FreeFragSize);
3168 BytesCopied += FreeFragSize;
3169 pSrc += FreeFragSize;
3170 pDest += FreeFragSize;
3171 NdisBufferLength -= FreeFragSize;
3172 break;
3174 else
3176 // Copy the rest of this buffer descriptor pointed data
3177 // into ring buffer.
3178 NdisMoveMemory(pDest, pSrc, NdisBufferLength);
3179 BytesCopied += NdisBufferLength;
3180 pDest += NdisBufferLength;
3181 FreeFragSize -= NdisBufferLength;
3184 // No more buffer descriptor
3185 // Add MIC value if needed
3186 if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
3187 (MICFrag == FALSE) &&
3188 (pWpaKey != NULL))
3190 INT i;
3192 NdisBufferLength = 8; // Set length to MIC length
3193 DBGPRINT(RT_DEBUG_INFO, "Calculated TX MIC value =");
3194 for (i = 0; i < 8; i++)
3196 DBGPRINT(RT_DEBUG_INFO, "%02x:", pAdapter->PrivateInfo.Tx.MIC[i]);
3198 DBGPRINT(RT_DEBUG_INFO, "\n");
3200 if (FreeFragSize >= NdisBufferLength)
3202 NdisMoveMemory(pDest, pAdapter->PrivateInfo.Tx.MIC, NdisBufferLength);
3203 BytesCopied += NdisBufferLength;
3204 pDest += NdisBufferLength;
3205 FreeFragSize -= NdisBufferLength;
3206 NdisBufferLength = 0;
3207 RemainSize += 8; // Need to add MIC as payload
3209 else
3211 NdisMoveMemory(pDest, pAdapter->PrivateInfo.Tx.MIC, FreeFragSize);
3212 BytesCopied += FreeFragSize;
3213 pSrc = pAdapter->PrivateInfo.Tx.MIC + FreeFragSize;
3214 pDest += FreeFragSize;
3215 NdisBufferLength -= FreeFragSize;
3216 MICFrag = TRUE;
3217 RemainSize += (8 - FreeFragSize); // Need to add MIC as payload
3220 } while (FALSE); // End of copying payload
3222 // Real packet size, No 802.1H header for fragments except the first one.
3223 if ((StartOfFrame == TRUE) && (Encapped == TRUE))
3225 TxSize = BytesCopied + LENGTH_802_11 + LENGTH_802_1_H;
3227 else
3229 TxSize = BytesCopied + LENGTH_802_11;
3232 RemainSize = RemainSize - BytesCopied;
3234 if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption1Enabled) && (Header_802_11.Controlhead.Frame.Wep == 1))
3236 // IV + ICV which ASIC added after encryption done
3237 TxSize += 8;
3239 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) && (pWpaKey != NULL))
3241 // IV + EIV + ICV which ASIC added after encryption done
3242 TxSize += 12;
3244 else if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled) && (pWpaKey != NULL))
3246 // IV + EIV + HW MIC
3247 TxSize += 16;
3250 // Prepare Tx descriptors before kicking tx.
3251 // The BBP register index in Tx descriptor has to be configured too.
3252 #ifdef BIG_ENDIAN
3253 RTMPFrameEndianChange(pAdapter, pOriginDest, DIR_WRITE, FALSE);
3254 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
3255 *pDestTxD = TxD;
3256 pTxD = pDestTxD;
3257 #endif
3258 if (Header_802_11.Controlhead.Addr1.Octet[0] & 0x01)
3260 // Multicast, retry bit is off
3261 RTMPWriteTxDescriptor(pTxD, TRUE, CipherAlg, FALSE, FALSE, FALSE, RetryMode, FrameGap,
3262 pAdapter->PortCfg.TxRate, 4, TxSize, pAdapter->PortCfg.TxPreambleInUsed, AccessCategory);
3264 else
3266 RTMPWriteTxDescriptor(pTxD, TRUE, CipherAlg, TRUE, FALSE, FALSE, RetryMode, FrameGap,
3267 pAdapter->PortCfg.TxRate, 4, TxSize, pAdapter->PortCfg.TxPreambleInUsed, AccessCategory);
3270 // Set frame gap for the rest of fragment burst.
3271 // It won't matter if there is only one fragment (single fragment frame).
3272 StartOfFrame = FALSE;
3273 FrameGap = IFS_SIFS;
3274 NumberRequired--;
3276 // Increase & maintain Tx Ring Index
3277 pAdapter->CurEncryptIndex++;
3278 if (pAdapter->CurEncryptIndex >= TX_RING_SIZE)
3280 pAdapter->CurEncryptIndex = 0;
3283 pAdapter->RalinkCounters.EncryptCount++;
3285 } while (NumberRequired > 0);
3288 // Kick Encrypt Control Register at the end of all ring buffer preparation
3289 RTMP_IO_WRITE32(pAdapter, SECCSR1, 0x1);
3291 // Acknowledge protocol send complete of pending packet.
3292 RTMPFreeSkbBuffer(skb);
3294 // Make sure to release Tx ring resource
3295 NdisReleaseSpinLock(&pAdapter->TxRingLock, IrqFlags);
3297 return (NDIS_STATUS_SUCCESS);
3301 ========================================================================
3303 Routine Description:
3304 Calculates the duration which is required to transmit out frames
3305 with given size and specified rate.
3307 Arguments:
3308 pAdapter Pointer to our adapter
3309 Rate Transmit rate
3310 Size Frame size in units of byte
3312 Return Value:
3313 Duration number in units of usec
3315 Note:
3317 ========================================================================
3319 USHORT RTMPCalcDuration(
3320 IN PRTMP_ADAPTER pAdapter,
3321 IN UCHAR Rate,
3322 IN ULONG Size)
3324 ULONG Duration = 0;
3326 if (Rate < RATE_FIRST_OFDM_RATE) // CCK
3328 if ((Rate > RATE_1) && (pAdapter->PortCfg.TxPreambleInUsed == Rt802_11PreambleShort))
3329 Duration = 96; // 72+24 preamble+plcp
3330 else
3331 Duration = 192; // 144+48 preamble+plcp
3333 Duration += (USHORT)((Size << 4) / RateIdTo500Kbps[Rate]);
3334 if ((Size << 4) % RateIdTo500Kbps[Rate])
3335 Duration ++;
3337 else // OFDM rates
3339 Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension
3340 Duration += 4 * (USHORT)((11 + Size * 4) / RateIdTo500Kbps[Rate]);
3341 if ((11 + Size * 4) % RateIdTo500Kbps[Rate])
3342 Duration += 4;
3345 return (USHORT)Duration;
3350 ========================================================================
3352 Routine Description:
3353 Calculates the duration which is required to transmit out frames
3354 with given size and specified rate.
3356 Arguments:
3357 pTxD Pointer to transmit descriptor
3358 Ack Setting for Ack requirement bit
3359 Fragment Setting for Fragment bit
3360 RetryMode Setting for retry mode
3361 Ifs Setting for IFS gap
3362 Rate Setting for transmit rate
3363 Service Setting for service
3364 Length Frame length
3365 TxPreamble Short or Long preamble when using CCK rates
3366 AccessCategory - 0-3, according to 802.11e/d4.4 June/2003
3368 Return Value:
3369 None
3371 ========================================================================
3373 VOID RTMPWriteTxDescriptor(
3374 IN PTXD_STRUC pSourceTxD,
3375 IN BOOLEAN DoEncrypt,
3376 IN UCHAR CipherAlg,
3377 IN BOOLEAN Ack,
3378 IN BOOLEAN Fragment,
3379 IN BOOLEAN InsTimestamp,
3380 IN UCHAR RetryMode,
3381 IN UCHAR Ifs,
3382 IN UINT Rate,
3383 IN UCHAR Service,
3384 IN ULONG Length,
3385 IN USHORT TxPreamble,
3386 IN UCHAR AccessCategory)
3388 UINT Residual;
3389 PTXD_STRUC pTxD;
3390 #ifndef BIG_ENDIAN
3391 pTxD = pSourceTxD;
3392 #else
3393 TXD_STRUC TxD;
3395 TxD = *pSourceTxD;
3396 pTxD = &TxD;
3397 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
3398 #endif
3400 pTxD->MoreFrag = Fragment;
3401 pTxD->ACK = Ack;
3402 pTxD->Timestamp = InsTimestamp;
3403 pTxD->RetryMd = RetryMode;
3404 pTxD->IFS = Ifs;
3405 pTxD->DataByteCnt = Length;
3406 pTxD->TxRate = Rate;
3407 switch (AccessCategory) // 802.11e/d4.4 June/2003
3409 case 3: // TC3, <AIFSN, CwMin, CwMax> = <1, aCwMin/4, aCwMin/2>
3410 pTxD->CWmin = CW_MIN_IN_BITS - 2;
3411 pTxD->CWmax = CW_MIN_IN_BITS - 1;
3412 pTxD->Aifs = 1;
3413 break;
3414 case 2: // TC2, <AIFSN, CwMin, CwMax> = <1, aCwMin/2, aCwMin>
3415 pTxD->CWmin = CW_MIN_IN_BITS - 1;
3416 pTxD->CWmax = CW_MIN_IN_BITS;
3417 pTxD->Aifs = 1;
3418 break;
3419 case 1: // TC1, <AIFSN, CwMin, CwMax> = <1, aCwMin, aCwMax>
3420 pTxD->CWmin = CW_MIN_IN_BITS;
3421 pTxD->CWmax = CW_MAX_IN_BITS;
3422 pTxD->Aifs = 1;
3423 break;
3424 case 0: // TC0, <AIFSN, CwMin, CwMax> = <2, aCwMin, aCwMax>
3425 default:
3426 pTxD->CWmin = CW_MIN_IN_BITS;
3427 pTxD->CWmax = CW_MAX_IN_BITS;
3428 pTxD->Aifs = 2;
3429 break;
3432 if (Rate < RATE_FIRST_OFDM_RATE)
3433 pTxD->Ofdm = 0;
3434 else
3435 pTxD->Ofdm = 1;
3437 // fill up PLCP SIGNAL field
3438 pTxD->PlcpSignal = PlcpSignal[Rate];
3439 if (((Rate == RATE_2) || (Rate == RATE_5_5) || (Rate == RATE_11)) && (TxPreamble == Rt802_11PreambleShort)) // no short preamble for RATE_1
3441 pTxD->PlcpSignal |= 0x0008;
3444 // fill up PLCP SERVICE field, not used for OFDM rates
3445 pTxD->PlcpService = Service;
3447 // file up PLCP LENGTH_LOW and LENGTH_HIGH fields
3448 Length += 4;
3449 if (Rate < RATE_FIRST_OFDM_RATE) // 11b - RATE_1, RATE_2, RATE_5_5, RATE_11
3451 if ((Rate == RATE_1) || ( Rate == RATE_2))
3453 Length = Length * 8 / (Rate + 1);
3455 else
3457 Residual = ((Length * 16) % (11 * (1 + Rate - RATE_5_5)));
3458 Length = Length * 16 / (11 * (1 + Rate - RATE_5_5));
3459 if (Residual != 0)
3461 Length++;
3463 if ((Residual <= (3 * (1 + Rate - RATE_5_5))) && (Residual != 0))
3465 if (Rate == RATE_11) // Only 11Mbps require length extension bit
3466 pTxD->PlcpService |= 0x80; // 11b's PLCP Length extension bit
3470 pTxD->PlcpLengthHigh = Length / 256;
3471 pTxD->PlcpLengthLow = Length % 256;
3473 else // OFDM - RATE_6, RATE_9, RATE_12, RATE_18, RATE_24, RATE_36, RATE_48, RATE_54
3475 pTxD->PlcpLengthHigh = Length / 64; // high 6-bit of total byte count
3476 pTxD->PlcpLengthLow = Length % 64; // low 6-bit of total byte count
3479 if (DoEncrypt == TRUE) // Do encryption only
3481 pTxD->Owner = DESC_OWN_HOST;
3482 pTxD->Valid = FALSE;
3483 pTxD->CipherAlg = CipherAlg;
3484 pTxD->CipherOwn = DESC_OWN_NIC;
3486 else // Hard transmit
3488 pTxD->Valid = TRUE;
3489 pTxD->CipherAlg = CIPHER_NONE;
3490 pTxD->CipherOwn = DESC_OWN_HOST;
3491 pTxD->Owner = DESC_OWN_NIC;
3493 #ifdef BIG_ENDIAN
3494 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
3495 //*pSourceTxD = *pTxD;
3496 WriteBackToDescriptor((PUCHAR)pSourceTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
3497 #endif
3501 ========================================================================
3503 Routine Description:
3504 Search tuple cache for receive duplicate frame from unicast frames.
3506 Arguments:
3507 pAdapter Pointer to our adapter
3508 pHeader 802.11 header of receiving frame
3510 Return Value:
3511 TRUE found matched tuple cache
3512 FALSE no matched found
3514 Note:
3516 ========================================================================
3518 BOOLEAN RTMPSearchTupleCache(
3519 IN PRTMP_ADAPTER pAdapter,
3520 IN PHEADER_802_11 pHeader)
3522 INT Index;
3524 for (Index = 0; Index < MAX_CLIENT; Index++)
3526 if (pAdapter->TupleCache[Index].Valid == FALSE)
3527 continue;
3529 if (RTMPEqualMemory(&pAdapter->TupleCache[Index].MAC, &pHeader->Controlhead.Addr2, 6) &&
3530 (pAdapter->TupleCache[Index].Sequence == pHeader->Sequence) &&
3531 (pAdapter->TupleCache[Index].Frag == pHeader->Frag))
3533 // DBGPRINT(RT_DEBUG_TRACE,("DUPCHECK - duplicate frame hit entry %d\n", Index));
3534 return (TRUE);
3537 return (FALSE);
3541 ========================================================================
3543 Routine Description:
3544 Update tuple cache for new received unicast frames.
3546 Arguments:
3547 pAdapter Pointer to our adapter
3548 pHeader 802.11 header of receiving frame
3550 Return Value:
3551 None
3553 Note:
3555 ========================================================================
3557 VOID RTMPUpdateTupleCache(
3558 IN PRTMP_ADAPTER pAdapter,
3559 IN PHEADER_802_11 pHeader)
3561 UCHAR Index;
3563 for (Index = 0; Index < MAX_CLIENT; Index++)
3565 if (pAdapter->TupleCache[Index].Valid == FALSE)
3567 // Add new entry
3568 NdisMoveMemory(&pAdapter->TupleCache[Index].MAC, &pHeader->Controlhead.Addr2, 6);
3569 pAdapter->TupleCache[Index].Sequence = pHeader->Sequence;
3570 pAdapter->TupleCache[Index].Frag = pHeader->Frag;
3571 pAdapter->TupleCache[Index].Valid = TRUE;
3572 pAdapter->TupleCacheLastUpdateIndex = Index;
3573 DBGPRINT(RT_DEBUG_INFO,"DUPCHECK - Add Entry %d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n",
3574 Index, pAdapter->TupleCache[Index].MAC.Octet[0], pAdapter->TupleCache[Index].MAC.Octet[1],
3575 pAdapter->TupleCache[Index].MAC.Octet[2], pAdapter->TupleCache[Index].MAC.Octet[3],
3576 pAdapter->TupleCache[Index].MAC.Octet[4], pAdapter->TupleCache[Index].MAC.Octet[5]);
3577 return;
3579 else if (RTMPEqualMemory(&pAdapter->TupleCache[Index].MAC, &pHeader->Controlhead.Addr2, 6))
3581 // Update old entry
3582 pAdapter->TupleCache[Index].Sequence = pHeader->Sequence;
3583 pAdapter->TupleCache[Index].Frag = pHeader->Frag;
3584 return;
3588 // tuple cache full, replace the first inserted one (even though it may not be
3589 // least referenced one)
3590 if (Index == MAX_CLIENT)
3592 pAdapter->TupleCacheLastUpdateIndex ++;
3593 if (pAdapter->TupleCacheLastUpdateIndex >= MAX_CLIENT)
3594 pAdapter->TupleCacheLastUpdateIndex = 0;
3595 Index = pAdapter->TupleCacheLastUpdateIndex;
3597 // replace with new entry
3598 NdisMoveMemory(&pAdapter->TupleCache[Index].MAC, &pHeader->Controlhead.Addr2, 6);
3599 pAdapter->TupleCache[Index].Sequence = pHeader->Sequence;
3600 pAdapter->TupleCache[Index].Frag = pHeader->Frag;
3601 pAdapter->TupleCache[Index].Valid = TRUE;
3602 DBGPRINT(RT_DEBUG_INFO,"DUPCHECK - replace Entry %d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n",
3603 Index, pAdapter->TupleCache[Index].MAC.Octet[0], pAdapter->TupleCache[Index].MAC.Octet[1],
3604 pAdapter->TupleCache[Index].MAC.Octet[2], pAdapter->TupleCache[Index].MAC.Octet[3],
3605 pAdapter->TupleCache[Index].MAC.Octet[4], pAdapter->TupleCache[Index].MAC.Octet[5]);
3610 ========================================================================
3612 Routine Description:
3613 Suspend MSDU transmission
3615 Arguments:
3616 pAdapter Pointer to our adapter
3618 Return Value:
3619 None
3621 Note:
3623 ========================================================================
3625 VOID RTMPSuspendMsduTransmission(
3626 IN PRTMP_ADAPTER pAdapter)
3628 DBGPRINT(RT_DEBUG_TRACE,"SCANNING, suspend MSDU transmission ...\n");
3629 RTMP_SET_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
3633 ========================================================================
3635 Routine Description:
3636 Resume MSDU transmission
3638 Arguments:
3639 pAdapter Pointer to our adapter
3641 Return Value:
3642 None
3644 Note:
3646 ========================================================================
3648 VOID RTMPResumeMsduTransmission(
3649 IN PRTMP_ADAPTER pAdapter)
3651 DBGPRINT(RT_DEBUG_INFO,"SCAN done, resume MSDU transmission ...\n");
3652 RTMP_CLEAR_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
3654 // Dequeue Tx queue if Reset is not in progress
3655 if ((!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
3656 (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF)))
3658 //RTMPDeQueuePacket(pAdapter, &pAdapter->TxSwQueue0);
3659 // Call dequeue without selected queue, let the subroutine select the right priority
3660 // Tx software queue
3661 RTMPDeQueuePacket(pAdapter);
3666 ========================================================================
3668 Routine Description:
3669 Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
3671 Arguments:
3672 pRxD Pointer to the Rx descriptor
3674 Return Value:
3675 NDIS_STATUS_SUCCESS No err
3676 NDIS_STATUS_FAILURE Error
3678 Note:
3680 ========================================================================
3682 inline NDIS_STATUS RTMPCheckRxDescriptor(
3683 IN PRXD_STRUC pRxD)
3685 // Phy errors
3686 if (pRxD->PhyErr)
3687 return(NDIS_STATUS_FAILURE);
3689 // CRC errors
3690 if (pRxD->Crc)
3691 return(NDIS_STATUS_FAILURE);
3693 // Paul 04-03 for OFDM Rx length issue
3694 if (pRxD->DataByteCnt > 1600)
3695 return(NDIS_STATUS_FAILURE);
3697 return(NDIS_STATUS_SUCCESS);
3701 ========================================================================
3703 Routine Description:
3704 Apply packet filter policy, return NDIS_STATUS_FAILURE if this frame
3705 should be dropped.
3707 Arguments:
3708 pAdapter Pointer to our adapter
3709 pRxD Pointer to the Rx descriptor
3710 pHeader Pointer to the 802.11 frame header
3712 Return Value:
3713 NDIS_STATUS_SUCCESS Accept frame
3714 NDIS_STATUS_FAILURE Drop Frame
3716 Note:
3717 Maganement frame should bypass this filtering rule.
3719 ========================================================================
3721 NDIS_STATUS RTMPApplyPacketFilter(
3722 IN PRTMP_ADAPTER pAdapter,
3723 IN PRXD_STRUC pRxD,
3724 IN PHEADER_802_11 pHeader)
3726 UCHAR i;
3728 // 0. Management frame should bypass all these filtering rules.
3729 if (pHeader->Controlhead.Frame.Type == BTYPE_MGMT)
3731 return(NDIS_STATUS_SUCCESS);
3734 // 0.1 Drop all Rx frames if MIC countermeasures kicks in
3735 if (pAdapter->PortCfg.MicErrCnt >= 2)
3737 return(NDIS_STATUS_FAILURE);
3740 // 1. Drop unicast to me packet if NDIS_PACKET_TYPE_DIRECTED is FALSE
3741 if (pRxD->U2M)
3743 if (pAdapter->bAcceptDirect == FALSE)
3745 return(NDIS_STATUS_FAILURE);
3749 // 2. Drop broadcast packet if NDIS_PACKET_TYPE_BROADCAST is FALSE
3750 else if (pRxD->Bcast)
3752 if (pAdapter->bAcceptBroadcast == FALSE)
3754 return(NDIS_STATUS_FAILURE);
3758 // 3. Drop multicast packet if NDIS_PACKET_TYPE_ALL_MULTICAST is false
3759 // and NDIS_PACKET_TYPE_MULTICAST is false.
3760 // If NDIS_PACKET_TYPE_MULTICAST is true, but NDIS_PACKET_TYPE_ALL_MULTICAST is false.
3761 // We have to deal with multicast table lookup & drop not matched packets.
3762 else if (pRxD->Mcast)
3764 if (pAdapter->bAcceptAllMulticast == FALSE)
3766 if (pAdapter->bAcceptMulticast == FALSE)
3768 return(NDIS_STATUS_FAILURE);
3770 else
3772 // Selected accept multicast packet based on multicast table
3773 for (i = 0; i < pAdapter->NumberOfMcAddresses; i++)
3775 if (RTMPEqualMemory(&pHeader->Controlhead.Addr1, pAdapter->McastTable[i], ETH_LENGTH_OF_ADDRESS))
3777 break; // Matched
3781 // Not matched
3782 if (i == pAdapter->NumberOfMcAddresses)
3784 DBGPRINT(RT_DEBUG_INFO,"Drop multicast %02x:%02x:%02x:%02x:%02x:%02x\n",
3785 pHeader->Controlhead.Addr1.Octet[0], pHeader->Controlhead.Addr1.Octet[1],
3786 pHeader->Controlhead.Addr1.Octet[2], pHeader->Controlhead.Addr1.Octet[3],
3787 pHeader->Controlhead.Addr1.Octet[4], pHeader->Controlhead.Addr1.Octet[5]);
3788 return(NDIS_STATUS_FAILURE);
3790 else
3792 DBGPRINT(RT_DEBUG_INFO,"Accept multicast %02x:%02x:%02x:%02x:%02x:%02x\n",
3793 pHeader->Controlhead.Addr1.Octet[0], pHeader->Controlhead.Addr1.Octet[1],
3794 pHeader->Controlhead.Addr1.Octet[2], pHeader->Controlhead.Addr1.Octet[3],
3795 pHeader->Controlhead.Addr1.Octet[4], pHeader->Controlhead.Addr1.Octet[5]);
3801 // 4. Not U2M, not Mcast, not Bcast, must be unicast to other DA.
3802 // Since we did not implement promiscuous mode, just drop this kind of packet for now.
3803 else
3805 return(NDIS_STATUS_FAILURE);
3808 return(NDIS_STATUS_SUCCESS);
3812 ========================================================================
3814 Routine Description:
3815 Check and fine the packet waiting in SW queue with highest priority
3817 Arguments:
3818 pAdapter Pointer to our adapter
3820 Return Value:
3821 pQueue Pointer to Waiting Queue
3823 Note:
3825 ========================================================================
3827 PQUEUE_HEADER RTMPCheckTxSwQueue(
3828 IN PRTMP_ADAPTER pAdapter,
3829 OUT ULONG *Number,
3830 OUT UCHAR *AccessCategory)
3832 // Calculate total number of packets waiting in queues for Nitro mode
3833 *Number = pAdapter->TxSwQueue3.Number + pAdapter->TxSwQueue2.Number + pAdapter->TxSwQueue1.Number +
3834 pAdapter->TxSwQueue0.Number;
3836 if (pAdapter->TxSwQueue3.Head != NULL)
3838 *AccessCategory = 3;
3839 return (&pAdapter->TxSwQueue3);
3841 else if (pAdapter->TxSwQueue2.Head != NULL)
3843 *AccessCategory = 2;
3844 return (&pAdapter->TxSwQueue2);
3846 else if (pAdapter->TxSwQueue1.Head != NULL)
3848 *AccessCategory = 1;
3849 return (&pAdapter->TxSwQueue1);
3851 else if (pAdapter->TxSwQueue0.Head != NULL)
3853 *AccessCategory = 0;
3854 return (&pAdapter->TxSwQueue0);
3857 // No packet pending in Tx Sw queue
3858 *AccessCategory = 0;
3859 return (NULL);
3863 ========================================================================
3865 Routine Description:
3866 Process MIC error indication and record MIC error timer.
3868 Arguments:
3869 pAdapter Pointer to our adapter
3870 pWpaKey Pointer to the WPA key structure
3872 Return Value:
3873 None
3875 Note:
3877 ========================================================================
3879 VOID RTMPReportMicError(
3880 IN PRTMP_ADAPTER pAdapter,
3881 IN PWPA_KEY pWpaKey)
3883 ULONG Now;
3884 struct
3886 NDIS_802_11_STATUS_INDICATION Status;
3887 NDIS_802_11_AUTHENTICATION_REQUEST Request;
3888 } Report;
3890 // 0. Set Status to indicate auth error
3891 Report.Status.StatusType = Ndis802_11StatusType_Authentication;
3893 // 1. Check for Group or Pairwise MIC error
3894 if (pWpaKey->Type == PAIRWISE_KEY)
3895 Report.Request.Flags = NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR;
3896 else
3897 Report.Request.Flags = NDIS_802_11_AUTH_REQUEST_GROUP_ERROR;
3899 // 2. Copy AP MAC address
3900 NdisMoveMemory(Report.Request.Bssid, pWpaKey->BssId, 6);
3902 // 3. Calculate length
3903 Report.Request.Length = sizeof(NDIS_802_11_AUTHENTICATION_REQUEST);
3905 // 4. Record Last MIC error time and count
3906 Now = jiffies;
3907 if (pAdapter->PortCfg.MicErrCnt == 0)
3909 pAdapter->PortCfg.MicErrCnt++;
3910 pAdapter->PortCfg.LastMicErrorTime = Now;
3912 else if (pAdapter->PortCfg.MicErrCnt == 1)
3914 if ((pAdapter->PortCfg.LastMicErrorTime + (60 * HZ)) < Now)
3916 // Update Last MIC error time, this did not violate two MIC errors within 60 seconds
3917 pAdapter->PortCfg.LastMicErrorTime = Now;
3919 else
3921 pAdapter->PortCfg.LastMicErrorTime = Now;
3922 // Violate MIC error counts, MIC countermeasures kicks in
3923 pAdapter->PortCfg.MicErrCnt++;
3924 // We shall block all reception
3925 // We shall clean all Tx ring and disassoicate from AP after next EAPOL frame
3926 RTMPRingCleanUp(pAdapter, TX_RING);
3929 else
3931 // MIC error count >= 2
3932 // This should not happen
3937 #ifdef BIG_ENDIAN
3939 ========================================================================
3941 Routine Description:
3942 Endian conversion of Tx/Rx descriptor .
3944 Arguments:
3945 pAdapter Pointer to our adapter
3946 pData Pointer to Tx/Rx descriptor
3947 DescriptorType Direction of the frame
3949 Return Value:
3950 None
3952 Note:
3953 Call this function when read or update descriptor
3954 ========================================================================
3956 inline VOID RTMPDescriptorEndianChange(
3957 IN PUCHAR pData,
3958 IN ULONG DescriptorType)
3960 *((ULONG *)(pData + 40)) = SWAP32(*((ULONG *)(pData + 40))); // Byte 10
3961 if(DescriptorType == TYPE_TXD)
3962 *((ULONG *)(pData + 8)) = SWAP32(*((ULONG *)(pData + 8))); // Byte 2
3963 *(ULONG *)pData = SWAP32(*(ULONG *)pData); // Byte 0; this must be swapped last
3967 VOID WriteBackToDescriptor(
3968 IN PUCHAR Dest,
3969 IN PUCHAR Src,
3970 IN BOOLEAN DoEncrypt,
3971 IN ULONG DescriptorType)
3973 PULONG p1, p2;
3974 UCHAR i;
3976 p1 = ((PULONG)Dest) + 1;
3977 p2 = ((PULONG)Src) + 1;
3978 for (i = 1; i < RING_DESCRIPTOR_SIZE/4 ; i++)
3979 *p1++ = *p2++;
3980 *(PULONG)Dest = *(PULONG)Src;
3985 ========================================================================
3987 Routine Description:
3988 Endian conversion of all kinds of 802.11 frames .
3990 Arguments:
3991 pAdapter Pointer to our adapter
3992 pData Pointer to the 802.11 frame structure
3993 Dir Direction of the frame
3994 FromRxDoneInt Caller is from RxDone interrupt
3996 Return Value:
3997 None
3999 Note:
4000 Call this function when read or update buffer data
4001 ========================================================================
4003 VOID RTMPFrameEndianChange(
4004 IN PRTMP_ADAPTER pAdapter,
4005 IN PUCHAR pData,
4006 IN ULONG Dir,
4007 IN BOOLEAN FromRxDoneInt)
4009 PMACHDR pFrame;
4010 PUCHAR pMacHdr;
4012 // swab 16 bit fields - Frame Control field
4013 if(Dir == DIR_READ)
4015 *(USHORT *)pData = SWAP16(*(USHORT *)pData);
4018 pFrame = (PMACHDR) pData;
4019 pMacHdr = (PUCHAR) pFrame;
4021 // swab 16 bit fields - Duration/ID field
4022 *(USHORT *)(pMacHdr + 2) = SWAP16(*(USHORT *)(pMacHdr + 2));
4024 // swab 16 bit fields - Sequence Control field
4025 *(USHORT *)(pMacHdr + 22) = SWAP16(*(USHORT *)(pMacHdr + 22));
4027 if(pFrame->Type == BTYPE_MGMT)
4029 switch(pFrame->SubType)
4031 case SUBTYPE_ASSOC_REQ:
4032 case SUBTYPE_REASSOC_REQ:
4033 // swab 16 bit fields - CapabilityInfo field
4034 pMacHdr += MAC_HDR_LEN;
4035 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
4037 // swab 16 bit fields - Listen Interval field
4038 pMacHdr += 2;
4039 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
4040 break;
4042 case SUBTYPE_ASSOC_RSP:
4043 case SUBTYPE_REASSOC_RSP:
4044 // swab 16 bit fields - CapabilityInfo field
4045 pMacHdr += MAC_HDR_LEN;
4046 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
4048 // swab 16 bit fields - Status Code field
4049 pMacHdr += 2;
4050 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
4052 // swab 16 bit fields - AID field
4053 pMacHdr += 2;
4054 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
4055 break;
4057 case SUBTYPE_AUTH:
4058 // If from RTMPHandleRxDoneInterrupt routine, it is still a encrypt format.
4059 // The convertion is delayed to RTMPHandleDecryptionDoneInterrupt.
4060 if(!FromRxDoneInt && pAdapter->NeedSwapToLittleEndian == TRUE)
4062 // swab 16 bit fields - Auth Alg No. field
4063 pMacHdr += MAC_HDR_LEN;
4064 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
4066 // swab 16 bit fields - Auth Seq No. field
4067 pMacHdr += 2;
4068 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
4070 // swab 16 bit fields - Status Code field
4071 pMacHdr += 2;
4072 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
4074 break;
4076 case SUBTYPE_BEACON:
4077 case SUBTYPE_PROBE_RSP:
4078 // swab 16 bit fields - BeaconInterval field
4079 pMacHdr += MAC_HDR_LEN + TIMESTAMP_LEN;
4080 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
4082 // swab 16 bit fields - CapabilityInfo field
4083 pMacHdr += sizeof(USHORT);
4084 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
4085 break;
4087 case SUBTYPE_DEAUTH:
4088 case SUBTYPE_DISASSOC:
4089 // swab 16 bit fields - Reason code field
4090 pMacHdr += MAC_HDR_LEN;
4091 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
4092 break;
4095 else if( pFrame->Type == BTYPE_DATA )
4098 else if(pFrame->Type == BTYPE_CNTL)
4101 else
4103 DBGPRINT(RT_DEBUG_ERROR,"Invalid Frame Type!!!\n");
4106 // swab 16 bit fields - Frame Control
4107 if(Dir == DIR_WRITE)
4109 *(USHORT *)pData = SWAP16(*(USHORT *)pData);
4112 #endif