2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 *************************************************************************
28 #include "../rt_config.h"
30 #define MAX_TX_IN_TBTT (16)
33 UCHAR SNAP_802_1H[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
34 UCHAR SNAP_BRIDGE_TUNNEL[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8};
35 // Add Cisco Aironet SNAP heade for CCX2 support
36 UCHAR SNAP_AIRONET[] = {0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x00};
37 UCHAR CKIP_LLC_SNAP[] = {0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02};
38 UCHAR EAPOL_LLC_SNAP[]= {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e};
39 UCHAR EAPOL[] = {0x88, 0x8e};
40 UCHAR TPID[] = {0x81, 0x00}; /* VLAN related */
42 UCHAR IPX[] = {0x81, 0x37};
43 UCHAR APPLE_TALK[] = {0x80, 0xf3};
44 UCHAR RateIdToPlcpSignal[12] = {
45 0, /* RATE_1 */ 1, /* RATE_2 */ 2, /* RATE_5_5 */ 3, /* RATE_11 */ // see BBP spec
46 11, /* RATE_6 */ 15, /* RATE_9 */ 10, /* RATE_12 */ 14, /* RATE_18 */ // see IEEE802.11a-1999 p.14
47 9, /* RATE_24 */ 13, /* RATE_36 */ 8, /* RATE_48 */ 12 /* RATE_54 */ }; // see IEEE802.11a-1999 p.14
49 UCHAR OfdmSignalToRateId[16] = {
50 RATE_54, RATE_54, RATE_54, RATE_54, // OFDM PLCP Signal = 0, 1, 2, 3 respectively
51 RATE_54, RATE_54, RATE_54, RATE_54, // OFDM PLCP Signal = 4, 5, 6, 7 respectively
52 RATE_48, RATE_24, RATE_12, RATE_6, // OFDM PLCP Signal = 8, 9, 10, 11 respectively
53 RATE_54, RATE_36, RATE_18, RATE_9, // OFDM PLCP Signal = 12, 13, 14, 15 respectively
56 UCHAR OfdmRateToRxwiMCS[12] = {
58 0, 1, 2, 3, // OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3
59 4, 5, 6, 7, // OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7
61 UCHAR RxwiMCSToOfdmRate[12] = {
62 RATE_6, RATE_9, RATE_12, RATE_18,
63 RATE_24, RATE_36, RATE_48, RATE_54, // OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3
64 4, 5, 6, 7, // OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7
67 char* MCSToMbps[] = {"1Mbps","2Mbps","5.5Mbps","11Mbps","06Mbps","09Mbps","12Mbps","18Mbps","24Mbps","36Mbps","48Mbps","54Mbps","MM-0","MM-1","MM-2","MM-3","MM-4","MM-5","MM-6","MM-7","MM-8","MM-9","MM-10","MM-11","MM-12","MM-13","MM-14","MM-15","MM-32","ee1","ee2","ee3"};
69 UCHAR default_cwmin[]={CW_MIN_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1, CW_MIN_IN_BITS-2};
70 UCHAR default_sta_aifsn[]={3,7,2,2};
72 UCHAR MapUserPriorityToAccessCategory[8] = {QID_AC_BE, QID_AC_BK, QID_AC_BK, QID_AC_BE, QID_AC_VI, QID_AC_VI, QID_AC_VO, QID_AC_VO};
76 ========================================================================
79 API for MLME to transmit management frame to AP (BSS Mode)
80 or station (IBSS Mode)
83 pAd Pointer to our adapter
84 pData Pointer to the outgoing 802.11 frame
85 Length Size of outgoing management frame
97 ========================================================================
99 NDIS_STATUS MiniportMMRequest(
100 IN PRTMP_ADAPTER pAd,
105 PNDIS_PACKET pPacket;
106 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
108 unsigned long IrqFlags = 0;
110 UCHAR rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
112 ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
118 IrqState = pAd->irq_disabled;
120 if ((pAd->MACVersion == 0x28600100) && (!IrqState))
121 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
125 // Reset is in progress, stop immediately
126 if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
127 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
128 !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
130 Status = NDIS_STATUS_FAILURE;
134 // Check Free priority queue
135 // Since we use PBF Queue2 for management frame. Its corresponding DMA ring should be using TxRing.
138 if (pAd->MACVersion == 0x28600100)
140 FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
144 FreeNum = GET_MGMTRING_FREENO(pAd);
149 // We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870
150 NdisZeroMemory(&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE));
151 Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE), pData, Length);
152 if (Status != NDIS_STATUS_SUCCESS)
154 DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
158 //pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
159 //pAd->CommonCfg.MlmeRate = RATE_2;
162 Status = MlmeHardTransmit(pAd, QueIdx, pPacket);
163 if (Status != NDIS_STATUS_SUCCESS)
164 RTMPFreeNdisPacket(pAd, pPacket);
168 pAd->RalinkCounters.MgmtRingFullCount++;
169 DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing, MgmtRingFullCount=%ld!\n",
170 QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
176 if ((pAd->MACVersion == 0x28600100) && (!IrqState))
177 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
183 NDIS_STATUS MiniportMMRequestUnlock(
184 IN PRTMP_ADAPTER pAd,
189 PNDIS_PACKET pPacket;
190 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
197 ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
201 // Reset is in progress, stop immediately
202 if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
203 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
204 !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
206 Status = NDIS_STATUS_FAILURE;
210 // Check Free priority queue
211 // Since we use PBF Queue2 for management frame. Its corresponding DMA ring should be using TxRing.
213 if (pAd->MACVersion == 0x28600100)
215 FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
216 SW_TX_IDX = pAd->TxRing[QueIdx].TxCpuIdx;
217 pTxD = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SW_TX_IDX].AllocVa;
221 FreeNum = GET_MGMTRING_FREENO(pAd);
222 SW_TX_IDX = pAd->MgmtRing.TxCpuIdx;
223 pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[SW_TX_IDX].AllocVa;
227 NdisZeroMemory(&TXWI, TXWI_SIZE);
228 Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&TXWI, TXWI_SIZE, pData, Length);
229 if (Status != NDIS_STATUS_SUCCESS)
231 DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
235 Status = MlmeHardTransmit(pAd, QueIdx, pPacket);
236 if (Status != NDIS_STATUS_SUCCESS)
237 RTMPFreeNdisPacket(pAd, pPacket);
241 pAd->RalinkCounters.MgmtRingFullCount++;
242 DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing\n", QueIdx));
253 ========================================================================
256 Copy frame from waiting queue into relative ring buffer and set
257 appropriate ASIC register to kick hardware transmit function
260 pAd Pointer to our adapter
261 pBuffer Pointer to memory of outgoing frame
262 Length Size of outgoing management frame
270 IRQL = DISPATCH_LEVEL
274 ========================================================================
276 NDIS_STATUS MlmeHardTransmit(
277 IN PRTMP_ADAPTER pAd,
279 IN PNDIS_PACKET pPacket)
281 if (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
283 return NDIS_STATUS_FAILURE;
286 if ( pAd->MACVersion == 0x28600100 )
287 return MlmeHardTransmitTxRing(pAd,QueIdx,pPacket);
289 return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
294 NDIS_STATUS MlmeHardTransmitTxRing(
295 IN PRTMP_ADAPTER pAd,
297 IN PNDIS_PACKET pPacket)
299 PACKET_INFO PacketInfo;
307 PHEADER_802_11 pHeader_802_11;
308 BOOLEAN bAckRequired, bInsertTimestamp;
311 ULONG SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
312 PTXWI_STRUC pFirstTxWI;
314 MAC_TABLE_ENTRY *pMacEntry = NULL;
317 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
319 if (pSrcBufVA == NULL)
321 // The buffer shouldn't be NULL
322 return NDIS_STATUS_FAILURE;
325 // Make sure MGMT ring resource won't be used by other threads
326 //NdisAcquireSpinLock(&pAd->TxRingLock);
328 FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
332 //NdisReleaseSpinLock(&pAd->TxRingLock);
333 return NDIS_STATUS_FAILURE;
336 SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
338 #ifndef RT_BIG_ENDIAN
339 pTxD = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa;
341 pDestTxD = (PTXD_STRUC)pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa;
344 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
347 if (pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket)
349 printk("MlmeHardTransmit Error\n");
350 return NDIS_STATUS_FAILURE;
354 #ifdef CONFIG_STA_SUPPORT
355 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
357 // outgoing frame always wakeup PHY to prevent frame lost
358 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
359 AsicForceWakeup(pAd, FROM_TX);
361 #endif // CONFIG_STA_SUPPORT //
362 pFirstTxWI =(PTXWI_STRUC)pSrcBufVA;
364 pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXWI_SIZE);
365 if (pHeader_802_11->Addr1[0] & 0x01)
367 MlmeRate = pAd->CommonCfg.BasicMlmeRate;
371 MlmeRate = pAd->CommonCfg.MlmeRate;
374 if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
375 (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))
377 pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
380 // Verify Mlme rate for a / g bands.
381 if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band
385 // Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)
386 // Snice it's been set to 0 while on MgtMacHeaderInit
387 // By the way this will cause frame to be send on PWR_SAVE failed.
390 // In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
391 #ifdef CONFIG_STA_SUPPORT
392 // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
393 if (pHeader_802_11->FC.Type != BTYPE_DATA)
395 if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) || !(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
397 pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
401 pHeader_802_11->FC.PwrMgmt = pAd->CommonCfg.bAPSDForcePowerSave;
404 #endif // CONFIG_STA_SUPPORT //
406 bInsertTimestamp = FALSE;
407 if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
409 bAckRequired = FALSE;
411 else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
413 if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
415 bAckRequired = FALSE;
416 pHeader_802_11->Duration = 0;
421 pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
422 if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
424 bInsertTimestamp = TRUE;
428 pHeader_802_11->Sequence = pAd->Sequence++;
429 if (pAd->Sequence > 0xfff)
431 // Before radar detection done, mgmt frame can not be sent but probe req
432 // Because we need to use probe req to trigger driver to send probe req in passive scan
433 if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
434 && (pAd->CommonCfg.bIEEE80211H == 1)
435 && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
437 DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
438 return (NDIS_STATUS_FAILURE);
442 RTMPFrameEndianChange(pAd, (PUCHAR)pHeader_802_11, DIR_WRITE, FALSE);
445 // fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
446 // should always has only one ohysical buffer, and the whole frame size equals
447 // to the first scatter buffer size
450 // Initialize TX Descriptor
451 // For inter-frame gap, the number is for this frame and next frame
452 // For MLME rate, we will fix as 2Mb to match other vendor's implement
454 // management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
455 // Only beacon use Nseq=TRUE. So here we use Nseq=FALSE.
456 if (pMacEntry == NULL)
458 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
459 0, RESERVED_WCID, (SrcBufLen - TXWI_SIZE), PID_MGMT, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
463 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
464 bInsertTimestamp, FALSE, bAckRequired, FALSE,
465 0, pMacEntry->Aid, (SrcBufLen - TXWI_SIZE),
466 pMacEntry->MaxHTPhyMode.field.MCS, 0,
467 (UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
468 IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
471 pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket = pPacket;
472 pAd->TxRing[QueIdx].Cell[SwIdx].pNextNdisPacket = NULL;
474 RTMPWIEndianChange((PUCHAR)pFirstTxWI, TYPE_TXWI);
476 SrcBufPA = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
479 RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_EDCA);
482 pTxD->SDLen0 = SrcBufLen;
484 pTxD->SDPtr0 = SrcBufPA;
488 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
489 WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
492 pAd->RalinkCounters.KickTxCount++;
493 pAd->RalinkCounters.OneSecTxDoneCount++;
495 // Increase TX_CTX_IDX, but write to register later.
496 INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE);
498 RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx*0x10, pAd->TxRing[QueIdx].TxCpuIdx);
500 return NDIS_STATUS_SUCCESS;
504 NDIS_STATUS MlmeHardTransmitMgmtRing(
505 IN PRTMP_ADAPTER pAd,
507 IN PNDIS_PACKET pPacket)
509 PACKET_INFO PacketInfo;
512 PHEADER_802_11 pHeader_802_11;
513 BOOLEAN bAckRequired, bInsertTimestamp;
515 PTXWI_STRUC pFirstTxWI;
516 MAC_TABLE_ENTRY *pMacEntry = NULL;
518 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
519 RTMP_SEM_LOCK(&pAd->MgmtRingLock);
522 if (pSrcBufVA == NULL)
524 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
525 return NDIS_STATUS_FAILURE;
528 #ifdef CONFIG_STA_SUPPORT
529 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
531 // outgoing frame always wakeup PHY to prevent frame lost
532 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
533 AsicForceWakeup(pAd, FROM_TX);
535 #endif // CONFIG_STA_SUPPORT //
537 pFirstTxWI = (PTXWI_STRUC)(pSrcBufVA + TXINFO_SIZE);
538 pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); //TXWI_SIZE);
540 if (pHeader_802_11->Addr1[0] & 0x01)
542 MlmeRate = pAd->CommonCfg.BasicMlmeRate;
546 MlmeRate = pAd->CommonCfg.MlmeRate;
549 // Verify Mlme rate for a / g bands.
550 if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band
553 if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
554 (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))
556 pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
559 #ifdef CONFIG_STA_SUPPORT
560 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
562 // Fixed W52 with Activity scan issue in ABG_MIXED and ABGN_MIXED mode.
563 if (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED
564 #ifdef DOT11_N_SUPPORT
565 || pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED
566 #endif // DOT11_N_SUPPORT //
569 if (pAd->LatchRfRegs.Channel > 14)
570 pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
572 pAd->CommonCfg.MlmeTransmit.field.MODE = 0;
575 #endif // CONFIG_STA_SUPPORT //
578 // Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)
579 // Snice it's been set to 0 while on MgtMacHeaderInit
580 // By the way this will cause frame to be send on PWR_SAVE failed.
582 // pHeader_802_11->FC.PwrMgmt = 0; // (pAd->StaCfg.Psm == PWR_SAVE);
584 // In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
585 #ifdef CONFIG_STA_SUPPORT
586 // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
587 if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL))
589 if ((pAd->StaCfg.Psm == PWR_SAVE) &&
590 (pHeader_802_11->FC.SubType == SUBTYPE_ACTION))
591 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
593 pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
595 #endif // CONFIG_STA_SUPPORT //
597 bInsertTimestamp = FALSE;
598 if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
600 #ifdef CONFIG_STA_SUPPORT
601 //Set PM bit in ps-poll, to fix WLK 1.2 PowerSaveMode_ext failure issue.
602 if ((pAd->OpMode == OPMODE_STA) && (pHeader_802_11->FC.SubType == SUBTYPE_PS_POLL))
604 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
606 #endif // CONFIG_STA_SUPPORT //
607 bAckRequired = FALSE;
609 else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
611 if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
613 bAckRequired = FALSE;
614 pHeader_802_11->Duration = 0;
619 pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
620 if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
622 bInsertTimestamp = TRUE;
627 pHeader_802_11->Sequence = pAd->Sequence++;
628 if (pAd->Sequence >0xfff)
631 // Before radar detection done, mgmt frame can not be sent but probe req
632 // Because we need to use probe req to trigger driver to send probe req in passive scan
633 if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
634 && (pAd->CommonCfg.bIEEE80211H == 1)
635 && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
637 DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
638 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
639 return (NDIS_STATUS_FAILURE);
643 RTMPFrameEndianChange(pAd, (PUCHAR)pHeader_802_11, DIR_WRITE, FALSE);
647 // fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
648 // should always has only one ohysical buffer, and the whole frame size equals
649 // to the first scatter buffer size
652 // Initialize TX Descriptor
653 // For inter-frame gap, the number is for this frame and next frame
654 // For MLME rate, we will fix as 2Mb to match other vendor's implement
656 // management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
657 if (pMacEntry == NULL)
659 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
660 0, RESERVED_WCID, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID_MGMT, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
664 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
665 bInsertTimestamp, FALSE, bAckRequired, FALSE,
666 0, pMacEntry->Aid, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE),
667 pMacEntry->MaxHTPhyMode.field.MCS, 0,
668 (UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
669 IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
673 RTMPWIEndianChange((PUCHAR)pFirstTxWI, TYPE_TXWI);
676 // Now do hardware-depened kick out.
677 HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen);
679 // Make sure to release MGMT ring resource
680 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
681 return NDIS_STATUS_SUCCESS;
685 /********************************************************************************
687 New DeQueue Procedures.
689 ********************************************************************************/
691 #define DEQUEUE_LOCK(lock, bIntContext, IrqFlags) \
693 if (bIntContext == FALSE) \
694 RTMP_IRQ_LOCK((lock), IrqFlags); \
697 #define DEQUEUE_UNLOCK(lock, bIntContext, IrqFlags) \
699 if (bIntContext == FALSE) \
700 RTMP_IRQ_UNLOCK((lock), IrqFlags); \
704 ========================================================================
705 Tx Path design algorithm:
706 Basically, we divide the packets into four types, Broadcast/Multicast, 11N Rate(AMPDU, AMSDU, Normal), B/G Rate(ARALINK, Normal),
707 Specific Packet Type. Following show the classification rule and policy for each kinds of packets.
708 Classification Rule=>
709 Multicast: (*addr1 & 0x01) == 0x01
710 Specific : bDHCPFrame, bARPFrame, bEAPOLFrame, etc.
711 11N Rate : If peer support HT
712 (1).AMPDU -- If TXBA is negotiated.
713 (2).AMSDU -- If AMSDU is capable for both peer and ourself.
714 *). AMSDU can embedded in a AMPDU, but now we didn't support it.
715 (3).Normal -- Other packets which send as 11n rate.
717 B/G Rate : If peer is b/g only.
718 (1).ARALINK-- If both of peer/us supprot Ralink proprietary Aggregation and the TxRate is large than RATE_6
719 (2).Normal -- Other packets which send as b/g rate.
721 The packet must be unicast, NOT A-RALINK, NOT A-MSDU, NOT 11n, then can consider about fragment.
723 Classified Packet Handle Rule=>
725 No ACK, //pTxBlk->bAckRequired = FALSE;
726 No WMM, //pTxBlk->bWMM = FALSE;
727 No piggyback, //pTxBlk->bPiggyBack = FALSE;
728 Force LowRate, //pTxBlk->bForceLowRate = TRUE;
729 Specific : Basically, for specific packet, we should handle it specifically, but now all specific packets are use
730 the same policy to handle it.
731 Force LowRate, //pTxBlk->bForceLowRate = TRUE;
734 No piggyback, //pTxBlk->bPiggyBack = FALSE;
746 ========================================================================
748 static UCHAR TxPktClassification(
749 IN RTMP_ADAPTER *pAd,
750 IN PNDIS_PACKET pPacket)
752 UCHAR TxFrameType = TX_UNKOWN_FRAME;
754 MAC_TABLE_ENTRY *pMacEntry = NULL;
755 #ifdef DOT11_N_SUPPORT
756 BOOLEAN bHTRate = FALSE;
757 #endif // DOT11_N_SUPPORT //
759 Wcid = RTMP_GET_PACKET_WCID(pPacket);
760 if (Wcid == MCAST_WCID)
761 { // Handle for RA is Broadcast/Multicast Address.
762 return TX_MCAST_FRAME;
765 // Handle for unicast packets
766 pMacEntry = &pAd->MacTab.Content[Wcid];
767 if (RTMP_GET_PACKET_LOWRATE(pPacket))
768 { // It's a specific packet need to force low rate, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame
769 TxFrameType = TX_LEGACY_FRAME;
771 #ifdef DOT11_N_SUPPORT
772 else if (IS_HT_RATE(pMacEntry))
773 { // it's a 11n capable packet
775 // Depends on HTPhyMode to check if the peer support the HTRate transmission.
776 // Currently didn't support A-MSDU embedded in A-MPDU
778 if (RTMP_GET_PACKET_MOREDATA(pPacket) || (pMacEntry->PsMode == PWR_SAVE))
779 TxFrameType = TX_LEGACY_FRAME;
780 #ifdef UAPSD_AP_SUPPORT
781 else if (RTMP_GET_PACKET_EOSP(pPacket))
782 TxFrameType = TX_LEGACY_FRAME;
783 #endif // UAPSD_AP_SUPPORT //
784 else if((pMacEntry->TXBAbitmap & (1<<(RTMP_GET_PACKET_UP(pPacket)))) != 0)
785 return TX_AMPDU_FRAME;
786 else if(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AMSDU_INUSED))
787 return TX_AMSDU_FRAME;
789 TxFrameType = TX_LEGACY_FRAME;
791 #endif // DOT11_N_SUPPORT //
793 { // it's a legacy b/g packet.
794 if ((CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE) && pAd->CommonCfg.bAggregationCapable) &&
795 (RTMP_GET_PACKET_TXRATE(pPacket) >= RATE_6) &&
796 (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
797 { // if peer support Ralink Aggregation, we use it.
798 TxFrameType = TX_RALINK_FRAME;
802 TxFrameType = TX_LEGACY_FRAME;
806 // Currently, our fragment only support when a unicast packet send as NOT-ARALINK, NOT-AMSDU and NOT-AMPDU.
807 if ((RTMP_GET_PACKET_FRAGMENTS(pPacket) > 1) && (TxFrameType == TX_LEGACY_FRAME))
808 TxFrameType = TX_FRAG_FRAME;
814 BOOLEAN RTMP_FillTxBlkInfo(
815 IN RTMP_ADAPTER *pAd,
818 PACKET_INFO PacketInfo;
819 PNDIS_PACKET pPacket;
820 PMAC_TABLE_ENTRY pMacEntry = NULL;
822 pPacket = pTxBlk->pPacket;
823 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen);
825 pTxBlk->Wcid = RTMP_GET_PACKET_WCID(pPacket);
826 pTxBlk->apidx = RTMP_GET_PACKET_IF(pPacket);
827 pTxBlk->UserPriority = RTMP_GET_PACKET_UP(pPacket);
828 pTxBlk->FrameGap = IFS_HTTXOP; // ASIC determine Frame Gap
830 if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pTxBlk->pPacket))
831 TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame);
833 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bClearEAPFrame);
835 // Default to clear this flag
836 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bForceNonQoS);
839 if (pTxBlk->Wcid == MCAST_WCID)
841 pTxBlk->pMacEntry = NULL;
843 #ifdef MCAST_RATE_SPECIFIC
844 PUCHAR pDA = GET_OS_PKT_DATAPTR(pPacket);
845 if (((*pDA & 0x01) == 0x01) && (*pDA != 0xff))
846 pTxBlk->pTransmit = &pAd->CommonCfg.MCastPhyMode;
848 #endif // MCAST_RATE_SPECIFIC //
849 pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
852 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); // AckRequired = FALSE, when broadcast packet in Adhoc mode.
853 //TX_BLK_SET_FLAG(pTxBlk, fTX_bForceLowRate);
854 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAllowFrag);
855 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
856 if (RTMP_GET_PACKET_MOREDATA(pPacket))
858 TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
864 pTxBlk->pMacEntry = &pAd->MacTab.Content[pTxBlk->Wcid];
865 pTxBlk->pTransmit = &pTxBlk->pMacEntry->HTPhyMode;
867 pMacEntry = pTxBlk->pMacEntry;
870 // For all unicast packets, need Ack unless the Ack Policy is not set as NORMAL_ACK.
871 if (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx] != NORMAL_ACK)
872 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);
874 TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired);
878 #ifdef CONFIG_STA_SUPPORT
879 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
882 // If support WMM, enable it.
883 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
884 TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM);
886 #endif // CONFIG_STA_SUPPORT //
889 if (pTxBlk->TxFrameType == TX_LEGACY_FRAME)
891 if ( (RTMP_GET_PACKET_LOWRATE(pPacket)) ||
892 ((pAd->OpMode == OPMODE_AP) && (pMacEntry->MaxHTPhyMode.field.MODE == MODE_CCK) && (pMacEntry->MaxHTPhyMode.field.MCS == RATE_1)))
893 { // Specific packet, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame, need force low rate.
894 pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
895 #ifdef DOT11_N_SUPPORT
896 // Modify the WMM bit for ICV issue. If we have a packet with EOSP field need to set as 1, how to handle it???
897 if (IS_HT_STA(pTxBlk->pMacEntry) &&
898 (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RALINK_CHIPSET)) &&
899 ((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RDG_CAPABLE)))
901 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
902 TX_BLK_SET_FLAG(pTxBlk, fTX_bForceNonQoS);
904 #endif // DOT11_N_SUPPORT //
907 #ifdef DOT11_N_SUPPORT
908 if ( (IS_HT_RATE(pMacEntry) == FALSE) &&
909 (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE)))
910 { // Currently piggy-back only support when peer is operate in b/g mode.
911 TX_BLK_SET_FLAG(pTxBlk, fTX_bPiggyBack);
913 #endif // DOT11_N_SUPPORT //
915 if (RTMP_GET_PACKET_MOREDATA(pPacket))
917 TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
919 #ifdef UAPSD_AP_SUPPORT
920 if (RTMP_GET_PACKET_EOSP(pPacket))
922 TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP);
924 #endif // UAPSD_AP_SUPPORT //
926 else if (pTxBlk->TxFrameType == TX_FRAG_FRAME)
928 TX_BLK_SET_FLAG(pTxBlk, fTX_bAllowFrag);
931 pMacEntry->DebugTxCount++;
938 BOOLEAN CanDoAggregateTransmit(
939 IN RTMP_ADAPTER *pAd,
940 IN NDIS_PACKET *pPacket,
944 //printk("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType);
946 if (RTMP_GET_PACKET_WCID(pPacket) == MCAST_WCID)
949 if (RTMP_GET_PACKET_DHCP(pPacket) ||
950 RTMP_GET_PACKET_EAPOL(pPacket) ||
951 RTMP_GET_PACKET_WAI(pPacket))
954 if ((pTxBlk->TxFrameType == TX_AMSDU_FRAME) &&
955 ((pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))> (RX_BUFFER_AGGRESIZE - 100)))
956 { // For AMSDU, allow the packets with total length < max-amsdu size
960 if ((pTxBlk->TxFrameType == TX_RALINK_FRAME) &&
961 (pTxBlk->TxPacketList.Number == 2))
962 { // For RALINK-Aggregation, allow two frames in one batch.
966 #ifdef CONFIG_STA_SUPPORT
967 if ((INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) // must be unicast to AP
970 #endif // CONFIG_STA_SUPPORT //
977 ========================================================================
980 To do the enqueue operation and extract the first item of waiting
981 list. If a number of available shared memory segments could meet
982 the request of extracted item, the extracted item will be fragmented
983 into shared memory segments.
986 pAd Pointer to our adapter
987 pQueue Pointer to Waiting Queue
992 IRQL = DISPATCH_LEVEL
996 ========================================================================
998 VOID RTMPDeQueuePacket(
999 IN PRTMP_ADAPTER pAd,
1000 IN BOOLEAN bIntContext,
1001 IN UCHAR QIdx, /* BulkOutPipeId */
1002 IN UCHAR Max_Tx_Packets)
1004 PQUEUE_ENTRY pEntry = NULL;
1005 PNDIS_PACKET pPacket;
1006 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
1008 PQUEUE_HEADER pQueue;
1009 ULONG FreeNumber[NUM_OF_TX_RING];
1010 UCHAR QueIdx, sQIdx, eQIdx;
1011 unsigned long IrqFlags = 0;
1012 BOOLEAN hasTxDesc = FALSE;
1018 RtmpDiagStruct *pDiagStruct = &pAd->DiagStruct;
1022 if (QIdx == NUM_OF_TX_RING)
1025 eQIdx = 3; // 4 ACs, start from 0.
1029 sQIdx = eQIdx = QIdx;
1032 for (QueIdx=sQIdx; QueIdx <= eQIdx; QueIdx++)
1036 RT28XX_START_DEQUEUE(pAd, QueIdx, IrqFlags);
1039 firstRound = ((QueIdx == 0) ? TRUE : FALSE);
1040 #endif // DBG_DIAGNOSE //
1044 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS |
1045 fRTMP_ADAPTER_RADIO_OFF |
1046 fRTMP_ADAPTER_RESET_IN_PROGRESS |
1047 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1048 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1050 RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
1054 if (Count >= Max_Tx_Packets)
1057 DEQUEUE_LOCK(&pAd->irq_lock, bIntContext, IrqFlags);
1058 if (&pAd->TxSwQueue[QueIdx] == NULL)
1061 if (firstRound == TRUE)
1062 pDiagStruct->TxSWQueCnt[pDiagStruct->ArrayCurIdx][0]++;
1063 #endif // DBG_DIAGNOSE //
1064 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
1068 FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
1071 if (firstRound == TRUE)
1073 UCHAR txDescNumLevel, txSwQNumLevel;
1075 txDescNumLevel = (TX_RING_SIZE - FreeNumber[QueIdx]); // Number of occupied hw desc.
1076 txDescNumLevel = ((txDescNumLevel <=15) ? txDescNumLevel : 15);
1077 pDiagStruct->TxDescCnt[pDiagStruct->ArrayCurIdx][txDescNumLevel]++;
1079 txSwQNumLevel = ((pAd->TxSwQueue[QueIdx].Number <=7) ? pAd->TxSwQueue[QueIdx].Number : 8);
1080 pDiagStruct->TxSWQueCnt[pDiagStruct->ArrayCurIdx][txSwQNumLevel]++;
1084 #endif // DBG_DIAGNOSE //
1086 if (FreeNumber[QueIdx] <= 5)
1088 // free Tx(QueIdx) resources
1089 RTMPFreeTXDUponTxDmaDone(pAd, QueIdx);
1090 FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
1093 // probe the Queue Head
1094 pQueue = &pAd->TxSwQueue[QueIdx];
1095 if ((pEntry = pQueue->Head) == NULL)
1097 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
1102 NdisZeroMemory((PUCHAR)pTxBlk, sizeof(TX_BLK));
1103 pTxBlk->QueIdx = QueIdx;
1105 pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
1107 // Early check to make sure we have enoguh Tx Resource.
1108 hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
1111 pAd->PrivateInfo.TxRingFullCnt++;
1113 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
1118 pTxBlk->TxFrameType = TxPktClassification(pAd, pPacket);
1119 pEntry = RemoveHeadQueue(pQueue);
1120 pTxBlk->TotalFrameNum++;
1121 pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); // The real fragment number maybe vary
1122 pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
1123 pTxBlk->pPacket = pPacket;
1124 InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
1126 if (pTxBlk->TxFrameType == TX_RALINK_FRAME || pTxBlk->TxFrameType == TX_AMSDU_FRAME)
1128 // Enhance SW Aggregation Mechanism
1129 if (NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, FreeNumber[QueIdx], pTxBlk->TxFrameType))
1131 InsertHeadQueue(pQueue, PACKET_TO_QUEUE_ENTRY(pPacket));
1132 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
1137 if((pEntry = pQueue->Head) == NULL)
1140 // For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation.
1141 pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
1142 FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
1143 hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
1144 if ((hasTxDesc == FALSE) || (CanDoAggregateTransmit(pAd, pPacket, pTxBlk) == FALSE))
1147 //Remove the packet from the TxSwQueue and insert into pTxBlk
1148 pEntry = RemoveHeadQueue(pQueue);
1150 pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
1151 pTxBlk->TotalFrameNum++;
1152 pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); // The real fragment number maybe vary
1153 pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
1154 InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
1157 if (pTxBlk->TxPacketList.Number == 1)
1158 pTxBlk->TxFrameType = TX_LEGACY_FRAME;
1162 Count += pTxBlk->TxPacketList.Number;
1164 // Do HardTransmit now.
1165 #ifdef CONFIG_STA_SUPPORT
1166 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1167 Status = STAHardTransmit(pAd, pTxBlk, QueIdx);
1168 #endif // CONFIG_STA_SUPPORT //
1170 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
1171 // static rate also need NICUpdateFifoStaCounters() function.
1172 //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
1173 NICUpdateFifoStaCounters(pAd);
1176 RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
1180 if ((pAd->blockQueueTab[QueIdx].SwTxQueueBlockFlag == TRUE)
1181 && (pAd->TxSwQueue[QueIdx].Number < 1))
1183 releaseNetIf(&pAd->blockQueueTab[QueIdx]);
1185 #endif // BLOCK_NET_IF //
1193 ========================================================================
1195 Routine Description:
1196 Calculates the duration which is required to transmit out frames
1197 with given size and specified rate.
1200 pAd Pointer to our adapter
1202 Size Frame size in units of byte
1205 Duration number in units of usec
1207 IRQL = PASSIVE_LEVEL
1208 IRQL = DISPATCH_LEVEL
1212 ========================================================================
1214 USHORT RTMPCalcDuration(
1215 IN PRTMP_ADAPTER pAd,
1221 if (Rate < RATE_FIRST_OFDM_RATE) // CCK
1223 if ((Rate > RATE_1) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED))
1224 Duration = 96; // 72+24 preamble+plcp
1226 Duration = 192; // 144+48 preamble+plcp
1228 Duration += (USHORT)((Size << 4) / RateIdTo500Kbps[Rate]);
1229 if ((Size << 4) % RateIdTo500Kbps[Rate])
1232 else if (Rate <= RATE_LAST_OFDM_RATE)// OFDM rates
1234 Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension
1235 Duration += 4 * (USHORT)((11 + Size * 4) / RateIdTo500Kbps[Rate]);
1236 if ((11 + Size * 4) % RateIdTo500Kbps[Rate])
1241 Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension
1244 return (USHORT)Duration;
1249 ========================================================================
1251 Routine Description:
1252 Calculates the duration which is required to transmit out frames
1253 with given size and specified rate.
1256 pTxWI Pointer to head of each MPDU to HW.
1257 Ack Setting for Ack requirement bit
1258 Fragment Setting for Fragment bit
1259 RetryMode Setting for retry mode
1260 Ifs Setting for IFS gap
1261 Rate Setting for transmit rate
1262 Service Setting for service
1264 TxPreamble Short or Long preamble when using CCK rates
1265 QueIdx - 0-3, according to 802.11e/d4.4 June/2003
1270 IRQL = PASSIVE_LEVEL
1271 IRQL = DISPATCH_LEVEL
1273 See also : BASmartHardTransmit() !!!
1275 ========================================================================
1278 IN PRTMP_ADAPTER pAd,
1279 IN PTXWI_STRUC pOutTxWI,
1282 IN BOOLEAN InsTimestamp,
1285 IN BOOLEAN NSeq, // HW new a sequence.
1294 IN HTTRANSMIT_SETTING *pTransmit)
1296 PMAC_TABLE_ENTRY pMac = NULL;
1300 if (WCID < MAX_LEN_OF_MAC_TABLE)
1301 pMac = &pAd->MacTab.Content[WCID];
1304 // Always use Long preamble before verifiation short preamble functionality works well.
1305 // Todo: remove the following line if short preamble functionality works
1307 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1308 NdisZeroMemory(&TxWI, TXWI_SIZE);
1313 pTxWI->CFACK = CFACK;
1314 pTxWI->TS= InsTimestamp;
1315 pTxWI->AMPDU = AMPDU;
1317 pTxWI->txop= Txopmode;
1320 // John tune the performace with Intel Client in 20 MHz performance
1321 #ifdef DOT11_N_SUPPORT
1322 BASize = pAd->CommonCfg.TxBASize;
1326 pTxWI->BAWinSize = BASize;
1327 pTxWI->ShortGI = pTransmit->field.ShortGI;
1328 pTxWI->STBC = pTransmit->field.STBC;
1329 #endif // DOT11_N_SUPPORT //
1331 pTxWI->WirelessCliID = WCID;
1332 pTxWI->MPDUtotalByteCount = Length;
1333 pTxWI->PacketId = PID;
1335 // If CCK or OFDM, BW must be 20
1336 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1337 #ifdef DOT11N_DRAFT3
1339 pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
1340 #endif // DOT11N_DRAFT3 //
1342 pTxWI->MCS = pTransmit->field.MCS;
1343 pTxWI->PHYMODE = pTransmit->field.MODE;
1344 pTxWI->CFACK = CfAck;
1346 #ifdef DOT11_N_SUPPORT
1349 if (pAd->CommonCfg.bMIMOPSEnable)
1351 if ((pMac->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1353 // Dynamic MIMO Power Save Mode
1356 else if (pMac->MmpsMode == MMPS_STATIC)
1358 // Static MIMO Power Save Mode
1359 if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
1366 //pTxWI->MIMOps = (pMac->PsMode == PWR_MMPS)? 1:0;
1367 if (pMac->bIAmBadAtheros && (pMac->WepStatus != Ndis802_11WEPDisabled))
1369 pTxWI->MpduDensity = 7;
1373 pTxWI->MpduDensity = pMac->MpduDensity;
1376 #endif // DOT11_N_SUPPORT //
1378 pTxWI->PacketId = pTxWI->MCS;
1379 NdisMoveMemory(pOutTxWI, &TxWI, sizeof(TXWI_STRUC));
1383 VOID RTMPWriteTxWI_Data(
1384 IN PRTMP_ADAPTER pAd,
1385 IN OUT PTXWI_STRUC pTxWI,
1388 HTTRANSMIT_SETTING *pTransmit;
1389 PMAC_TABLE_ENTRY pMacEntry;
1390 #ifdef DOT11_N_SUPPORT
1392 #endif // DOT11_N_SUPPORT //
1397 pTransmit = pTxBlk->pTransmit;
1398 pMacEntry = pTxBlk->pMacEntry;
1402 // Always use Long preamble before verifiation short preamble functionality works well.
1403 // Todo: remove the following line if short preamble functionality works
1405 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1406 NdisZeroMemory(pTxWI, TXWI_SIZE);
1408 pTxWI->FRAG = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag);
1409 pTxWI->ACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAckRequired);
1410 pTxWI->txop = pTxBlk->FrameGap;
1412 #ifdef CONFIG_STA_SUPPORT
1413 #ifdef QOS_DLS_SUPPORT
1415 (pAd->StaCfg.BssType == BSS_INFRA) &&
1416 (pMacEntry->ValidAsDls == TRUE))
1417 pTxWI->WirelessCliID = BSSID_WCID;
1419 #endif // QOS_DLS_SUPPORT //
1420 #endif // CONFIG_STA_SUPPORT //
1421 pTxWI->WirelessCliID = pTxBlk->Wcid;
1423 pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
1424 pTxWI->CFACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bPiggyBack);
1426 // If CCK or OFDM, BW must be 20
1427 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1428 #ifdef DOT11_N_SUPPORT
1429 #ifdef DOT11N_DRAFT3
1431 pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
1432 #endif // DOT11N_DRAFT3 //
1433 pTxWI->AMPDU = ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) ? TRUE : FALSE);
1435 // John tune the performace with Intel Client in 20 MHz performance
1436 BASize = pAd->CommonCfg.TxBASize;
1437 if((pTxBlk->TxFrameType == TX_AMPDU_FRAME) && (pMacEntry))
1439 UCHAR RABAOriIdx = 0; //The RA's BA Originator table index.
1441 RABAOriIdx = pTxBlk->pMacEntry->BAOriWcidArray[pTxBlk->UserPriority];
1442 BASize = pAd->BATable.BAOriEntry[RABAOriIdx].BAWinSize;
1445 pTxWI->TxBF = pTransmit->field.TxBF;
1446 pTxWI->BAWinSize = BASize;
1447 pTxWI->ShortGI = pTransmit->field.ShortGI;
1448 pTxWI->STBC = pTransmit->field.STBC;
1449 #endif // DOT11_N_SUPPORT //
1451 pTxWI->MCS = pTransmit->field.MCS;
1452 pTxWI->PHYMODE = pTransmit->field.MODE;
1454 #ifdef DOT11_N_SUPPORT
1457 if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1459 // Dynamic MIMO Power Save Mode
1462 else if (pMacEntry->MmpsMode == MMPS_STATIC)
1464 // Static MIMO Power Save Mode
1465 if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
1472 if (pMacEntry->bIAmBadAtheros && (pMacEntry->WepStatus != Ndis802_11WEPDisabled))
1474 pTxWI->MpduDensity = 7;
1478 pTxWI->MpduDensity = pMacEntry->MpduDensity;
1481 #endif // DOT11_N_SUPPORT //
1484 if (pTxBlk->QueIdx== 0)
1486 pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
1487 pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
1489 #endif // DBG_DIAGNOSE //
1491 // for rate adapation
1492 pTxWI->PacketId = pTxWI->MCS;
1496 VOID RTMPWriteTxWI_Cache(
1497 IN PRTMP_ADAPTER pAd,
1498 IN OUT PTXWI_STRUC pTxWI,
1501 PHTTRANSMIT_SETTING pTransmit;
1502 PMAC_TABLE_ENTRY pMacEntry;
1507 pMacEntry = pTxBlk->pMacEntry;
1508 pTransmit = pTxBlk->pTransmit;
1510 if (pMacEntry->bAutoTxRateSwitch)
1512 pTxWI->txop = IFS_HTTXOP;
1514 // If CCK or OFDM, BW must be 20
1515 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1516 pTxWI->ShortGI = pTransmit->field.ShortGI;
1517 pTxWI->STBC = pTransmit->field.STBC;
1519 pTxWI->MCS = pTransmit->field.MCS;
1520 pTxWI->PHYMODE = pTransmit->field.MODE;
1522 // set PID for TxRateSwitching
1523 pTxWI->PacketId = pTransmit->field.MCS;
1526 #ifdef DOT11_N_SUPPORT
1527 pTxWI->AMPDU = ((pMacEntry->NoBADataCountDown == 0) ? TRUE: FALSE);
1530 #ifdef DOT11N_DRAFT3
1532 pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
1533 #endif // DOT11N_DRAFT3 //
1535 if (pAd->CommonCfg.bMIMOPSEnable)
1537 // MIMO Power Save Mode
1538 if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1540 // Dynamic MIMO Power Save Mode
1543 else if (pMacEntry->MmpsMode == MMPS_STATIC)
1545 // Static MIMO Power Save Mode
1546 if ((pTransmit->field.MODE >= MODE_HTMIX) && (pTransmit->field.MCS > 7))
1553 #endif // DOT11_N_SUPPORT //
1556 if (pTxBlk->QueIdx== 0)
1558 pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
1559 pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
1561 #endif // DBG_DIAGNOSE //
1563 pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
1569 ========================================================================
1571 Routine Description:
1572 Calculates the duration which is required to transmit out frames
1573 with given size and specified rate.
1576 pTxD Pointer to transmit descriptor
1577 Ack Setting for Ack requirement bit
1578 Fragment Setting for Fragment bit
1579 RetryMode Setting for retry mode
1580 Ifs Setting for IFS gap
1581 Rate Setting for transmit rate
1582 Service Setting for service
1584 TxPreamble Short or Long preamble when using CCK rates
1585 QueIdx - 0-3, according to 802.11e/d4.4 June/2003
1590 IRQL = PASSIVE_LEVEL
1591 IRQL = DISPATCH_LEVEL
1593 ========================================================================
1595 VOID RTMPWriteTxDescriptor(
1596 IN PRTMP_ADAPTER pAd,
1602 // Always use Long preamble before verifiation short preamble functionality works well.
1603 // Todo: remove the following line if short preamble functionality works
1605 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1607 pTxD->WIV = (bWIV) ? 1: 0;
1608 pTxD->QSEL= (QueueSEL);
1609 if (pAd->bGenOneHCCA == TRUE)
1610 pTxD->QSEL= FIFO_HCCA;
1615 // should be called only when -
1616 // 1. MEADIA_CONNECTED
1617 // 2. AGGREGATION_IN_USED
1618 // 3. Fragmentation not in used
1619 // 4. either no previous frame (pPrevAddr1=NULL) .OR. previoud frame is aggregatible
1620 BOOLEAN TxFrameIsAggregatible(
1621 IN PRTMP_ADAPTER pAd,
1622 IN PUCHAR pPrevAddr1,
1626 // can't aggregate EAPOL (802.1x) frame
1627 if ((p8023hdr[12] == 0x88) && (p8023hdr[13] == 0x8e))
1630 // can't aggregate multicast/broadcast frame
1631 if (p8023hdr[0] & 0x01)
1634 if (INFRA_ON(pAd)) // must be unicast to AP
1636 else if ((pPrevAddr1 == NULL) || MAC_ADDR_EQUAL(pPrevAddr1, p8023hdr)) // unicast to same STA
1644 ========================================================================
1646 Routine Description:
1647 Check the MSDU Aggregation policy
1648 1.HT aggregation is A-MSDU
1649 2.legaacy rate aggregation is software aggregation by Ralink.
1657 ========================================================================
1659 BOOLEAN PeerIsAggreOn(
1660 IN PRTMP_ADAPTER pAd,
1662 IN PMAC_TABLE_ENTRY pMacEntry)
1664 ULONG AFlags = (fCLIENT_STATUS_AMSDU_INUSED | fCLIENT_STATUS_AGGREGATION_CAPABLE);
1666 if (pMacEntry != NULL && CLIENT_STATUS_TEST_FLAG(pMacEntry, AFlags))
1668 #ifdef DOT11_N_SUPPORT
1669 if (pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
1673 #endif // DOT11_N_SUPPORT //
1675 #ifdef AGGREGATION_SUPPORT
1676 if (TxRate >= RATE_6 && pAd->CommonCfg.bAggregationCapable && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
1677 { // legacy Ralink Aggregation support
1680 #endif // AGGREGATION_SUPPORT //
1689 ========================================================================
1691 Routine Description:
1692 Check and fine the packet waiting in SW queue with highest priority
1695 pAd Pointer to our adapter
1698 pQueue Pointer to Waiting Queue
1700 IRQL = DISPATCH_LEVEL
1704 ========================================================================
1706 PQUEUE_HEADER RTMPCheckTxSwQueue(
1707 IN PRTMP_ADAPTER pAd,
1713 Number = pAd->TxSwQueue[QID_AC_BK].Number
1714 + pAd->TxSwQueue[QID_AC_BE].Number
1715 + pAd->TxSwQueue[QID_AC_VI].Number
1716 + pAd->TxSwQueue[QID_AC_VO].Number
1717 + pAd->TxSwQueue[QID_HCCA].Number;
1719 if (pAd->TxSwQueue[QID_AC_VO].Head != NULL)
1721 *pQueIdx = QID_AC_VO;
1722 return (&pAd->TxSwQueue[QID_AC_VO]);
1724 else if (pAd->TxSwQueue[QID_AC_VI].Head != NULL)
1726 *pQueIdx = QID_AC_VI;
1727 return (&pAd->TxSwQueue[QID_AC_VI]);
1729 else if (pAd->TxSwQueue[QID_AC_BE].Head != NULL)
1731 *pQueIdx = QID_AC_BE;
1732 return (&pAd->TxSwQueue[QID_AC_BE]);
1734 else if (pAd->TxSwQueue[QID_AC_BK].Head != NULL)
1736 *pQueIdx = QID_AC_BK;
1737 return (&pAd->TxSwQueue[QID_AC_BK]);
1739 else if (pAd->TxSwQueue[QID_HCCA].Head != NULL)
1741 *pQueIdx = QID_HCCA;
1742 return (&pAd->TxSwQueue[QID_HCCA]);
1745 // No packet pending in Tx Sw queue
1746 *pQueIdx = QID_AC_BK;
1752 BOOLEAN RTMPFreeTXDUponTxDmaDone(
1753 IN PRTMP_ADAPTER pAd,
1756 PRTMP_TX_RING pTxRing;
1758 #ifdef RT_BIG_ENDIAN
1759 PTXD_STRUC pDestTxD;
1761 PNDIS_PACKET pPacket;
1763 TXD_STRUC TxD, *pOriTxD;
1765 BOOLEAN bReschedule = FALSE;
1768 ASSERT(QueIdx < NUM_OF_TX_RING);
1769 pTxRing = &pAd->TxRing[QueIdx];
1771 RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF, &pTxRing->TxDmaIdx);
1772 while (pTxRing->TxSwFreeIdx != pTxRing->TxDmaIdx)
1774 // static rate also need NICUpdateFifoStaCounters() function.
1775 //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
1776 NICUpdateFifoStaCounters(pAd);
1778 /* Note : If (pAd->ate.bQATxStart == TRUE), we will never reach here. */
1780 #ifndef RT_BIG_ENDIAN
1781 pTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
1783 NdisMoveMemory(&TxD, pTxD, sizeof(TXD_STRUC));
1786 pDestTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
1787 pOriTxD = pDestTxD ;
1790 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1795 /*====================================================================*/
1797 pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket;
1800 #ifdef CONFIG_5VT_ENHANCE
1801 if (RTMP_GET_PACKET_5VT(pPacket))
1802 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, 16, PCI_DMA_TODEVICE);
1804 #endif // CONFIG_5VT_ENHANCE //
1805 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
1806 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1808 //Always assign pNdisPacket as NULL after clear
1809 pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket = NULL;
1811 pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket;
1813 ASSERT(pPacket == NULL);
1816 #ifdef CONFIG_5VT_ENHANCE
1817 if (RTMP_GET_PACKET_5VT(pPacket))
1818 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, 16, PCI_DMA_TODEVICE);
1820 #endif // CONFIG_5VT_ENHANCE //
1821 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
1822 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1824 //Always assign pNextNdisPacket as NULL after clear
1825 pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL;
1827 /*====================================================================*/
1829 pAd->RalinkCounters.TransmittedByteCount += (pTxD->SDLen1 + pTxD->SDLen0);
1830 pAd->RalinkCounters.OneSecDmaDoneCount[QueIdx] ++;
1831 INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE);
1832 /* get tx_tdx_idx again */
1833 RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF , &pTxRing->TxDmaIdx);
1834 #ifdef RT_BIG_ENDIAN
1835 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1838 NdisMoveMemory(pOriTxD, pTxD, sizeof(TXD_STRUC));
1849 ========================================================================
1851 Routine Description:
1852 Process TX Rings DMA Done interrupt, running in DPC level
1855 Adapter Pointer to our adapter
1860 IRQL = DISPATCH_LEVEL
1862 ========================================================================
1864 BOOLEAN RTMPHandleTxRingDmaDoneInterrupt(
1865 IN PRTMP_ADAPTER pAd,
1866 IN INT_SOURCE_CSR_STRUC TxRingBitmap)
1868 unsigned long IrqFlags;
1869 BOOLEAN bReschedule = FALSE;
1871 // Make sure Tx ring resource won't be used by other threads
1873 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
1875 if (TxRingBitmap.field.Ac0DmaDone)
1876 bReschedule = RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BE);
1878 if (TxRingBitmap.field.HccaDmaDone)
1879 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_HCCA);
1881 if (TxRingBitmap.field.Ac3DmaDone)
1882 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VO);
1884 if (TxRingBitmap.field.Ac2DmaDone)
1885 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VI);
1887 if (TxRingBitmap.field.Ac1DmaDone)
1888 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BK);
1890 // Make sure to release Tx ring resource
1891 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
1893 // Dequeue outgoing frames from TxSwQueue[] and process it
1894 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1901 ========================================================================
1903 Routine Description:
1904 Process MGMT ring DMA done interrupt, running in DPC level
1907 pAd Pointer to our adapter
1912 IRQL = DISPATCH_LEVEL
1916 ========================================================================
1918 VOID RTMPHandleMgmtRingDmaDoneInterrupt(
1919 IN PRTMP_ADAPTER pAd)
1922 #ifdef RT_BIG_ENDIAN
1923 PTXD_STRUC pDestTxD;
1926 PNDIS_PACKET pPacket;
1928 PRTMP_MGMT_RING pMgmtRing = &pAd->MgmtRing;
1930 NdisAcquireSpinLock(&pAd->MgmtRingLock);
1932 RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pMgmtRing->TxDmaIdx);
1933 while (pMgmtRing->TxSwFreeIdx!= pMgmtRing->TxDmaIdx)
1936 #ifdef RT_BIG_ENDIAN
1937 pDestTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa);
1940 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1942 pTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa);
1945 pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket;
1950 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
1951 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1953 pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket = NULL;
1955 pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket;
1958 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
1959 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1961 pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket = NULL;
1962 INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE);
1964 #ifdef RT_BIG_ENDIAN
1965 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1966 WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, TRUE, TYPE_TXD);
1969 NdisReleaseSpinLock(&pAd->MgmtRingLock);
1975 ========================================================================
1977 Routine Description:
1979 Adapter Pointer to our adapter. Dequeue all power safe delayed braodcast frames after beacon.
1981 IRQL = DISPATCH_LEVEL
1983 ========================================================================
1985 VOID RTMPHandleTBTTInterrupt(
1986 IN PRTMP_ADAPTER pAd)
1989 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
1997 ========================================================================
1999 Routine Description:
2001 Adapter Pointer to our adapter. Rewrite beacon content before next send-out.
2003 IRQL = DISPATCH_LEVEL
2005 ========================================================================
2007 VOID RTMPHandlePreTBTTInterrupt(
2008 IN PRTMP_ADAPTER pAd)
2011 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
2013 DBGPRINT(RT_DEBUG_TRACE, ("RTMPHandlePreTBTTInterrupt...\n"));
2020 VOID RTMPHandleRxCoherentInterrupt(
2021 IN PRTMP_ADAPTER pAd)
2023 WPDMA_GLO_CFG_STRUC GloCfg;
2027 DBGPRINT(RT_DEBUG_TRACE, ("====> pAd is NULL, return.\n"));
2031 DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPHandleRxCoherentInterrupt \n"));
2033 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG , &GloCfg.word);
2035 GloCfg.field.EnTXWriteBackDDONE = 0;
2036 GloCfg.field.EnableRxDMA = 0;
2037 GloCfg.field.EnableTxDMA = 0;
2038 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
2040 RTMPRingCleanUp(pAd, QID_AC_BE);
2041 RTMPRingCleanUp(pAd, QID_AC_BK);
2042 RTMPRingCleanUp(pAd, QID_AC_VI);
2043 RTMPRingCleanUp(pAd, QID_AC_VO);
2044 RTMPRingCleanUp(pAd, QID_HCCA);
2045 RTMPRingCleanUp(pAd, QID_MGMT);
2046 RTMPRingCleanUp(pAd, QID_RX);
2048 RTMPEnableRxTx(pAd);
2050 DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPHandleRxCoherentInterrupt \n"));
2054 VOID DBGPRINT_TX_RING(
2055 IN PRTMP_ADAPTER pAd,
2059 UINT32 Ac0HwIdx = 0, Ac0SwIdx = 0, AC0freeIdx;
2063 DBGPRINT_RAW(RT_DEBUG_TRACE, ("=====================================================\n " ));
2067 RTMP_IO_READ32(pAd, TX_BASE_PTR0, &Ac0Base);
2068 RTMP_IO_READ32(pAd, TX_CTX_IDX0, &Ac0SwIdx);
2069 RTMP_IO_READ32(pAd, TX_DTX_IDX0, &Ac0HwIdx);
2070 DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_BE DESCRIPTOR \n " ));
2071 for (i=0;i<TX_RING_SIZE;i++)
2073 ptemp= (PULONG)pAd->TxRing[QID_AC_BE].Cell[i].AllocVa;
2074 DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d] %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
2076 DBGPRINT_RAW(RT_DEBUG_TRACE, (" \n " ));
2079 RTMP_IO_READ32(pAd, TX_BASE_PTR1, &Ac0Base);
2080 RTMP_IO_READ32(pAd, TX_CTX_IDX1, &Ac0SwIdx);
2081 RTMP_IO_READ32(pAd, TX_DTX_IDX1, &Ac0HwIdx);
2082 DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_BK DESCRIPTOR \n " ));
2083 for (i=0;i<TX_RING_SIZE;i++)
2085 ptemp= (PULONG)pAd->TxRing[QID_AC_BK].Cell[i].AllocVa;
2086 DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d] %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
2088 DBGPRINT_RAW(RT_DEBUG_TRACE, (" \n " ));
2091 RTMP_IO_READ32(pAd, TX_BASE_PTR2, &Ac0Base);
2092 RTMP_IO_READ32(pAd, TX_CTX_IDX2, &Ac0SwIdx);
2093 RTMP_IO_READ32(pAd, TX_DTX_IDX2, &Ac0HwIdx);
2094 DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_VI DESCRIPTOR \n " ));
2095 for (i=0;i<TX_RING_SIZE;i++)
2097 ptemp= (PULONG)pAd->TxRing[QID_AC_VI].Cell[i].AllocVa;
2098 DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d] %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
2100 DBGPRINT_RAW(RT_DEBUG_TRACE, (" \n " ));
2103 RTMP_IO_READ32(pAd, TX_BASE_PTR3, &Ac0Base);
2104 RTMP_IO_READ32(pAd, TX_CTX_IDX3, &Ac0SwIdx);
2105 RTMP_IO_READ32(pAd, TX_DTX_IDX3, &Ac0HwIdx);
2106 DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_VO DESCRIPTOR \n " ));
2107 for (i=0;i<TX_RING_SIZE;i++)
2109 ptemp= (PULONG)pAd->TxRing[QID_AC_VO].Cell[i].AllocVa;
2110 DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d] %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
2112 DBGPRINT_RAW(RT_DEBUG_TRACE, (" \n " ));
2115 RTMP_IO_READ32(pAd, TX_BASE_PTR5, &Ac0Base);
2116 RTMP_IO_READ32(pAd, TX_CTX_IDX5, &Ac0SwIdx);
2117 RTMP_IO_READ32(pAd, TX_DTX_IDX5, &Ac0HwIdx);
2118 DBGPRINT_RAW(RT_DEBUG_TRACE, (" All QID_MGMT DESCRIPTOR \n " ));
2119 for (i=0;i<MGMT_RING_SIZE;i++)
2121 ptemp= (PULONG)pAd->MgmtRing.Cell[i].AllocVa;
2122 DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d] %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
2124 DBGPRINT_RAW(RT_DEBUG_TRACE, (" \n " ));
2128 DBGPRINT_ERR(("DBGPRINT_TX_RING(Ring %d) not supported\n", QueIdx));
2131 AC0freeIdx = pAd->TxRing[QueIdx].TxSwFreeIdx;
2133 DBGPRINT(RT_DEBUG_TRACE,("TxRing%d, TX_DTX_IDX=%d, TX_CTX_IDX=%d\n", QueIdx, Ac0HwIdx, Ac0SwIdx));
2134 DBGPRINT_RAW(RT_DEBUG_TRACE,(" TxSwFreeIdx[%d]", AC0freeIdx));
2135 DBGPRINT_RAW(RT_DEBUG_TRACE,(" pending-NDIS=%ld\n", pAd->RalinkCounters.PendingNdisPacketCount));
2141 VOID DBGPRINT_RX_RING(
2142 IN PRTMP_ADAPTER pAd)
2145 UINT32 Ac0HwIdx = 0, Ac0SwIdx = 0, AC0freeIdx;
2149 DBGPRINT_RAW(RT_DEBUG_TRACE, ("=====================================================\n " ));
2150 RTMP_IO_READ32(pAd, RX_BASE_PTR, &Ac0Base);
2151 RTMP_IO_READ32(pAd, RX_CRX_IDX, &Ac0SwIdx);
2152 RTMP_IO_READ32(pAd, RX_DRX_IDX, &Ac0HwIdx);
2153 AC0freeIdx = pAd->RxRing.RxSwReadIdx;
2155 DBGPRINT_RAW(RT_DEBUG_TRACE, ("All RX DSP \n " ));
2156 for (i=0;i<RX_RING_SIZE;i++)
2158 ptemp = (UINT32 *)pAd->RxRing.Cell[i].AllocVa;
2159 DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d] %08x: %08x: %08x: %08x\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
2161 DBGPRINT(RT_DEBUG_TRACE,("RxRing, RX_DRX_IDX=%d, RX_CRX_IDX=%d \n", Ac0HwIdx, Ac0SwIdx));
2162 DBGPRINT_RAW(RT_DEBUG_TRACE,(" RxSwReadIdx [%d]=", AC0freeIdx));
2163 DBGPRINT_RAW(RT_DEBUG_TRACE,(" pending-NDIS=%ld\n", pAd->RalinkCounters.PendingNdisPacketCount));
2167 ========================================================================
2169 Routine Description:
2170 Suspend MSDU transmission
2173 pAd Pointer to our adapter
2180 ========================================================================
2182 VOID RTMPSuspendMsduTransmission(
2183 IN PRTMP_ADAPTER pAd)
2185 DBGPRINT(RT_DEBUG_TRACE,("SCANNING, suspend MSDU transmission ...\n"));
2189 // Before BSS_SCAN_IN_PROGRESS, we need to keep Current R66 value and
2190 // use Lowbound as R66 value on ScanNextChannel(...)
2192 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
2194 // set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning)
2195 RTMPSetAGCInitValue(pAd, BW_20);
2197 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2202 ========================================================================
2204 Routine Description:
2205 Resume MSDU transmission
2208 pAd Pointer to our adapter
2213 IRQL = DISPATCH_LEVEL
2217 ========================================================================
2219 VOID RTMPResumeMsduTransmission(
2220 IN PRTMP_ADAPTER pAd)
2222 DBGPRINT(RT_DEBUG_TRACE,("SCAN done, resume MSDU transmission ...\n"));
2225 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, pAd->BbpTuning.R66CurrentValue);
2227 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2228 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
2232 UINT deaggregate_AMSDU_announce(
2233 IN PRTMP_ADAPTER pAd,
2234 PNDIS_PACKET pPacket,
2239 USHORT SubFrameSize;
2240 PHEADER_802_3 pAMSDUsubheader;
2242 UCHAR Header802_3[14];
2244 PUCHAR pPayload, pDA, pSA, pRemovedLLCSNAP;
2245 PNDIS_PACKET pClonePacket;
2251 while (DataSize > LENGTH_802_3)
2256 pAMSDUsubheader = (PHEADER_802_3)pData;
2257 PayloadSize = pAMSDUsubheader->Octet[1] + (pAMSDUsubheader->Octet[0]<<8);
2258 SubFrameSize = PayloadSize + LENGTH_802_3;
2261 if ((DataSize < SubFrameSize) || (PayloadSize > 1518 ))
2266 pPayload = pData + LENGTH_802_3;
2268 pSA = pData + MAC_ADDR_LEN;
2270 // convert to 802.3 header
2271 CONVERT_TO_802_3(Header802_3, pDA, pSA, pPayload, PayloadSize, pRemovedLLCSNAP);
2273 #ifdef CONFIG_STA_SUPPORT
2274 if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E) )
2276 // avoid local heap overflow, use dyanamic allocation
2277 MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
2278 memmove(Elem->Msg+(LENGTH_802_11 + LENGTH_802_1_H), pPayload, PayloadSize);
2279 Elem->MsgLen = LENGTH_802_11 + LENGTH_802_1_H + PayloadSize;
2280 WpaEAPOLKeyAction(pAd, Elem);
2283 #endif // CONFIG_STA_SUPPORT //
2285 #ifdef CONFIG_STA_SUPPORT
2286 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2288 if (pRemovedLLCSNAP)
2290 pPayload -= LENGTH_802_3;
2291 PayloadSize += LENGTH_802_3;
2292 NdisMoveMemory(pPayload, &Header802_3[0], LENGTH_802_3);
2295 #endif // CONFIG_STA_SUPPORT //
2297 pClonePacket = ClonePacket(pAd, pPacket, pPayload, PayloadSize);
2300 #ifdef CONFIG_STA_SUPPORT
2301 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2302 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pClonePacket, RTMP_GET_PACKET_IF(pPacket));
2303 #endif // CONFIG_STA_SUPPORT //
2307 // A-MSDU has padding to multiple of 4 including subframe header.
2308 // align SubFrameSize up to multiple of 4
2309 SubFrameSize = (SubFrameSize+3)&(~0x3);
2312 if (SubFrameSize > 1528 || SubFrameSize < 32)
2317 if (DataSize > SubFrameSize)
2319 pData += SubFrameSize;
2320 DataSize -= SubFrameSize;
2329 // finally release original rx packet
2330 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
2336 UINT BA_Reorder_AMSDU_Annnounce(
2337 IN PRTMP_ADAPTER pAd,
2338 IN PNDIS_PACKET pPacket)
2344 pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
2345 DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
2347 nMSDU = deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
2354 ==========================================================================
2356 Look up the MAC address in the MAC table. Return NULL if not found.
2358 pEntry - pointer to the MAC entry; NULL is not found
2359 ==========================================================================
2361 MAC_TABLE_ENTRY *MacTableLookup(
2362 IN PRTMP_ADAPTER pAd,
2366 MAC_TABLE_ENTRY *pEntry = NULL;
2368 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
2369 pEntry = pAd->MacTab.Hash[HashIdx];
2371 while (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsWDS || pEntry->ValidAsApCli || pEntry->ValidAsMesh))
2373 if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
2378 pEntry = pEntry->pNext;
2384 MAC_TABLE_ENTRY *MacTableInsertEntry(
2385 IN PRTMP_ADAPTER pAd,
2388 IN BOOLEAN CleanAll)
2392 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
2395 if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
2399 #ifdef CONFIG_STA_SUPPORT
2400 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2401 if (pAd->StaCfg.BssType == BSS_INFRA)
2403 #endif // CONFIG_STA_SUPPORT //
2405 // allocate one MAC entry
2406 NdisAcquireSpinLock(&pAd->MacTabLock);
2407 for (i = FirstWcid; i< MAX_LEN_OF_MAC_TABLE; i++) // skip entry#0 so that "entry index == AID" for fast lookup
2409 // pick up the first available vacancy
2410 if ((pAd->MacTab.Content[i].ValidAsCLI == FALSE) &&
2411 (pAd->MacTab.Content[i].ValidAsWDS == FALSE) &&
2412 (pAd->MacTab.Content[i].ValidAsApCli== FALSE) &&
2413 (pAd->MacTab.Content[i].ValidAsMesh == FALSE)
2414 #ifdef CONFIG_STA_SUPPORT
2415 #ifdef QOS_DLS_SUPPORT
2416 && (pAd->MacTab.Content[i].ValidAsDls == FALSE)
2417 #endif // QOS_DLS_SUPPORT //
2418 #endif // CONFIG_STA_SUPPORT //
2421 pEntry = &pAd->MacTab.Content[i];
2422 if (CleanAll == TRUE)
2424 pEntry->MaxSupportedRate = RATE_11;
2425 pEntry->CurrTxRate = RATE_11;
2426 NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
2427 pEntry->PairwiseKey.KeyLen = 0;
2428 pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
2430 #ifdef CONFIG_STA_SUPPORT
2431 #ifdef QOS_DLS_SUPPORT
2432 if (apidx >= MIN_NET_DEVICE_FOR_DLS)
2434 pEntry->ValidAsCLI = FALSE;
2435 pEntry->ValidAsWDS = FALSE;
2436 pEntry->ValidAsApCli = FALSE;
2437 pEntry->ValidAsMesh = FALSE;
2438 pEntry->ValidAsDls = TRUE;
2439 pEntry->isCached = FALSE;
2442 #endif // QOS_DLS_SUPPORT //
2443 #endif // CONFIG_STA_SUPPORT //
2446 #ifdef CONFIG_STA_SUPPORT
2447 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2449 pEntry->ValidAsCLI = TRUE;
2450 pEntry->ValidAsWDS = FALSE;
2451 pEntry->ValidAsApCli = FALSE;
2452 pEntry->ValidAsMesh = FALSE;
2453 pEntry->ValidAsDls = FALSE;
2455 #endif // CONFIG_STA_SUPPORT //
2458 pEntry->bIAmBadAtheros = FALSE;
2460 pEntry->CMTimerRunning = FALSE;
2461 pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
2462 pEntry->RSNIE_Len = 0;
2463 NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter));
2464 pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
2466 if (pEntry->ValidAsMesh)
2467 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_MESH);
2468 else if (pEntry->ValidAsApCli)
2469 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_APCLI);
2470 else if (pEntry->ValidAsWDS)
2471 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_WDS);
2472 #ifdef CONFIG_STA_SUPPORT
2473 #ifdef QOS_DLS_SUPPORT
2474 else if (pEntry->ValidAsDls)
2475 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_DLS);
2476 #endif // QOS_DLS_SUPPORT //
2477 #endif // CONFIG_STA_SUPPORT //
2479 pEntry->apidx = apidx;
2483 #ifdef CONFIG_STA_SUPPORT
2484 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2486 pEntry->AuthMode = pAd->StaCfg.AuthMode;
2487 pEntry->WepStatus = pAd->StaCfg.WepStatus;
2488 pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
2489 AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)i);
2491 #endif // CONFIG_STA_SUPPORT //
2494 pEntry->GTKState = REKEY_NEGOTIATING;
2495 pEntry->PairwiseKey.KeyLen = 0;
2496 pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
2497 #ifdef CONFIG_STA_SUPPORT
2498 if ((pAd->OpMode == OPMODE_STA) &&
2499 (pAd->StaCfg.BssType == BSS_ADHOC))
2500 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
2502 #ifdef QOS_DLS_SUPPORT
2503 if (pEntry->ValidAsDls == TRUE)
2504 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
2506 #endif //QOS_DLS_SUPPORT
2507 #endif // CONFIG_STA_SUPPORT //
2508 pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2509 pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
2510 COPY_MAC_ADDR(pEntry->Addr, pAddr);
2511 pEntry->Sst = SST_NOT_AUTH;
2512 pEntry->AuthState = AS_NOT_AUTH;
2513 pEntry->Aid = (USHORT)i; //0;
2514 pEntry->CapabilityInfo = 0;
2515 pEntry->PsMode = PWR_ACTIVE;
2516 pEntry->PsQIdleCount = 0;
2517 pEntry->NoDataIdleCount = 0;
2518 pEntry->ContinueTxFailCnt = 0;
2519 InitializeQueueHeader(&pEntry->PsQueue);
2522 pAd->MacTab.Size ++;
2523 // Add this entry into ASIC RX WCID search table
2524 RT28XX_STA_ENTRY_ADD(pAd, pEntry);
2528 DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertEntry - allocate entry #%d, Total= %d\n",i, pAd->MacTab.Size));
2533 // add this MAC entry into HASH table
2536 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
2537 if (pAd->MacTab.Hash[HashIdx] == NULL)
2539 pAd->MacTab.Hash[HashIdx] = pEntry;
2543 pCurrEntry = pAd->MacTab.Hash[HashIdx];
2544 while (pCurrEntry->pNext != NULL)
2545 pCurrEntry = pCurrEntry->pNext;
2546 pCurrEntry->pNext = pEntry;
2550 NdisReleaseSpinLock(&pAd->MacTabLock);
2555 ==========================================================================
2557 Delete a specified client from MAC table
2558 ==========================================================================
2560 BOOLEAN MacTableDeleteEntry(
2561 IN PRTMP_ADAPTER pAd,
2566 MAC_TABLE_ENTRY *pEntry, *pPrevEntry, *pProbeEntry;
2569 if (wcid >= MAX_LEN_OF_MAC_TABLE)
2572 NdisAcquireSpinLock(&pAd->MacTabLock);
2574 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
2575 pEntry = &pAd->MacTab.Content[wcid];
2577 if (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsApCli || pEntry->ValidAsWDS || pEntry->ValidAsMesh
2578 #ifdef CONFIG_STA_SUPPORT
2579 #ifdef QOS_DLS_SUPPORT
2580 || pEntry->ValidAsDls
2581 #endif // QOS_DLS_SUPPORT //
2582 #endif // CONFIG_STA_SUPPORT //
2585 if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
2588 // Delete this entry from ASIC on-chip WCID Table
2589 RT28XX_STA_ENTRY_MAC_RESET(pAd, wcid);
2591 #ifdef DOT11_N_SUPPORT
2592 // free resources of BA
2593 BASessionTearDownALL(pAd, pEntry->Aid);
2594 #endif // DOT11_N_SUPPORT //
2598 pProbeEntry = pAd->MacTab.Hash[HashIdx];
2599 ASSERT(pProbeEntry);
2604 if (pProbeEntry == pEntry)
2606 if (pPrevEntry == NULL)
2608 pAd->MacTab.Hash[HashIdx] = pEntry->pNext;
2612 pPrevEntry->pNext = pEntry->pNext;
2617 pPrevEntry = pProbeEntry;
2618 pProbeEntry = pProbeEntry->pNext;
2619 } while (pProbeEntry);
2622 ASSERT(pProbeEntry != NULL);
2624 RT28XX_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid);
2627 if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
2629 RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
2630 pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
2634 NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
2635 pAd->MacTab.Size --;
2636 DBGPRINT(RT_DEBUG_TRACE, ("MacTableDeleteEntry1 - Total= %d\n", pAd->MacTab.Size));
2640 printk("\n%s: Impossible Wcid = %d !!!!!\n", __func__, wcid);
2644 NdisReleaseSpinLock(&pAd->MacTabLock);
2646 //Reset operating mode when no Sta.
2647 if (pAd->MacTab.Size == 0)
2649 #ifdef DOT11_N_SUPPORT
2650 pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0;
2651 #endif // DOT11_N_SUPPORT //
2652 AsicUpdateProtect(pAd, 0 /*pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode*/, (ALLN_SETPROTECT), TRUE, 0 /*pAd->MacTab.fAnyStationNonGF*/);
2660 ==========================================================================
2662 This routine reset the entire MAC table. All packets pending in
2663 the power-saving queues are freed here.
2664 ==========================================================================
2667 IN PRTMP_ADAPTER pAd)
2671 DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n"));
2672 //NdisAcquireSpinLock(&pAd->MacTabLock);
2674 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
2676 RT28XX_STA_ENTRY_MAC_RESET(pAd, i);
2677 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
2680 #ifdef DOT11_N_SUPPORT
2681 // free resources of BA
2682 BASessionTearDownALL(pAd, i);
2683 #endif // DOT11_N_SUPPORT //
2685 pAd->MacTab.Content[i].ValidAsCLI = FALSE;
2690 //AsicDelWcidTab(pAd, i);
2698 ==========================================================================
2701 IRQL = DISPATCH_LEVEL
2703 ==========================================================================
2706 IN PRTMP_ADAPTER pAd,
2707 IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq,
2709 IN USHORT CapabilityInfo,
2711 IN USHORT ListenIntv)
2713 COPY_MAC_ADDR(AssocReq->Addr, pAddr);
2714 // Add mask to support 802.11b mode only
2715 AssocReq->CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; // not cf-pollable, not cf-poll-request
2716 AssocReq->Timeout = Timeout;
2717 AssocReq->ListenIntv = ListenIntv;
2722 ==========================================================================
2725 IRQL = DISPATCH_LEVEL
2727 ==========================================================================
2729 VOID DisassocParmFill(
2730 IN PRTMP_ADAPTER pAd,
2731 IN OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq,
2735 COPY_MAC_ADDR(DisassocReq->Addr, pAddr);
2736 DisassocReq->Reason = Reason;
2741 ========================================================================
2743 Routine Description:
2744 Check the out going frame, if this is an DHCP or ARP datagram
2745 will be duplicate another frame at low data rate transmit.
2748 pAd Pointer to our adapter
2749 pPacket Pointer to outgoing Ndis frame
2752 TRUE To be duplicate at Low data rate transmit. (1mb)
2755 IRQL = DISPATCH_LEVEL
2759 MAC header + IP Header + UDP Header
2763 00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|
2765 16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|
2768 port 0x43 means Bootstrap Protocol, server.
2769 Port 0x44 means Bootstrap Protocol, client.
2771 ========================================================================
2774 BOOLEAN RTMPCheckDHCPFrame(
2775 IN PRTMP_ADAPTER pAd,
2776 IN PNDIS_PACKET pPacket)
2778 PACKET_INFO PacketInfo;
2779 ULONG NumberOfBytesRead = 0;
2780 ULONG CurrentOffset = 0;
2781 PVOID pVirtualAddress = NULL;
2782 UINT NdisBufferLength;
2785 UCHAR ByteOffset36 = 0;
2786 UCHAR ByteOffset38 = 0;
2787 BOOLEAN ReadFirstParm = TRUE;
2789 RTMP_QueryPacketInfo(pPacket, &PacketInfo, (PUCHAR *)&pVirtualAddress, &NdisBufferLength);
2791 NumberOfBytesRead += NdisBufferLength;
2792 pSrc = (PUCHAR) pVirtualAddress;
2793 Protocol = *(pSrc + 12) * 256 + *(pSrc + 13);
2796 // Check DHCP & BOOTP protocol
2798 while (NumberOfBytesRead <= PacketInfo.TotalPacketLength)
2800 if ((NumberOfBytesRead >= 35) && (ReadFirstParm == TRUE))
2802 CurrentOffset = 35 - (NumberOfBytesRead - NdisBufferLength);
2803 ByteOffset36 = *(pSrc + CurrentOffset);
2804 ReadFirstParm = FALSE;
2807 if (NumberOfBytesRead >= 37)
2809 CurrentOffset = 37 - (NumberOfBytesRead - NdisBufferLength);
2810 ByteOffset38 = *(pSrc + CurrentOffset);
2817 // Check for DHCP & BOOTP protocol
2818 if ((ByteOffset36 != 0x44) || (ByteOffset38 != 0x43))
2821 // 2054 (hex 0806) for ARP datagrams
2822 // if this packet is not ARP datagrams, then do nothing
2823 // ARP datagrams will also be duplicate at 1mb broadcast frames
2825 if (Protocol != 0x0806 )
2833 BOOLEAN RTMPCheckEtherType(
2834 IN PRTMP_ADAPTER pAd,
2835 IN PNDIS_PACKET pPacket)
2841 UINT16 srcPort, dstPort;
2842 BOOLEAN status = TRUE;
2845 pSrcBuf = GET_OS_PKT_DATAPTR(pPacket);
2846 pktLen = GET_OS_PKT_LEN(pPacket);
2850 RTMP_SET_PACKET_SPECIFIC(pPacket, 0);
2852 // get Ethernet protocol field
2853 TypeLen = (pSrcBuf[12] << 8) + pSrcBuf[13];
2855 pSrcBuf += LENGTH_802_3; // Skip the Ethernet Header.
2857 if (TypeLen <= 1500)
2858 { // 802.3, 802.3 LLC
2860 DestMAC(6) + SrcMAC(6) + Lenght(2) +
2861 DSAP(1) + SSAP(1) + Control(1) +
2862 if the DSAP = 0xAA, SSAP=0xAA, Contorl = 0x03, it has a 5-bytes SNAP header.
2863 => + SNAP (5, OriginationID(3) + etherType(2))
2865 if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA && pSrcBuf[2] == 0x03)
2867 Sniff2BytesFromNdisBuffer(pSrcBuf, 6, &Byte0, &Byte1);
2868 RTMP_SET_PACKET_LLCSNAP(pPacket, 1);
2869 TypeLen = (USHORT)((Byte0 << 8) + Byte1);
2870 pSrcBuf += 8; // Skip this LLC/SNAP header
2874 //It just has 3-byte LLC header, maybe a legacy ether type frame. we didn't handle it.
2878 // If it's a VLAN packet, get the real Type/Length field.
2879 if (TypeLen == 0x8100)
2881 /* 0x8100 means VLAN packets */
2883 /* Dest. MAC Address (6-bytes) +
2884 Source MAC Address (6-bytes) +
2885 Length/Type = 802.1Q Tag Type (2-byte) +
2886 Tag Control Information (2-bytes) +
2887 Length / Type (2-bytes) +
2888 data payload (0-n bytes) +
2890 Frame Check Sequence (4-bytes) */
2892 RTMP_SET_PACKET_VLAN(pPacket, 1);
2893 Sniff2BytesFromNdisBuffer(pSrcBuf, 2, &Byte0, &Byte1);
2894 TypeLen = (USHORT)((Byte0 << 8) + Byte1);
2896 pSrcBuf += 4; // Skip the VLAN Header.
2903 ASSERT((pktLen > 34));
2904 if (*(pSrcBuf + 9) == 0x11)
2906 ASSERT((pktLen > 34)); // 14 for ethernet header, 20 for IP header
2908 pSrcBuf += 20; // Skip the IP header
2909 srcPort = OS_NTOHS(*((UINT16 *)pSrcBuf));
2910 dstPort = OS_NTOHS(*((UINT16 *)(pSrcBuf +2)));
2912 if ((srcPort==0x44 && dstPort==0x43) || (srcPort==0x43 && dstPort==0x44))
2913 { //It's a BOOTP/DHCP packet
2914 RTMP_SET_PACKET_DHCP(pPacket, 1);
2922 RTMP_SET_PACKET_DHCP(pPacket, 1);
2928 RTMP_SET_PACKET_EAPOL(pPacket, 1);
2942 VOID Update_Rssi_Sample(
2943 IN PRTMP_ADAPTER pAd,
2944 IN RSSI_SAMPLE *pRssi,
2945 IN PRXWI_STRUC pRxWI)
2947 CHAR rssi0 = pRxWI->RSSI0;
2948 CHAR rssi1 = pRxWI->RSSI1;
2949 CHAR rssi2 = pRxWI->RSSI2;
2953 pRssi->LastRssi0 = ConvertToRssi(pAd, (CHAR)rssi0, RSSI_0);
2954 pRssi->AvgRssi0X8 = (pRssi->AvgRssi0X8 - pRssi->AvgRssi0) + pRssi->LastRssi0;
2955 pRssi->AvgRssi0 = pRssi->AvgRssi0X8 >> 3;
2960 pRssi->LastRssi1 = ConvertToRssi(pAd, (CHAR)rssi1, RSSI_1);
2961 pRssi->AvgRssi1X8 = (pRssi->AvgRssi1X8 - pRssi->AvgRssi1) + pRssi->LastRssi1;
2962 pRssi->AvgRssi1 = pRssi->AvgRssi1X8 >> 3;
2967 pRssi->LastRssi2 = ConvertToRssi(pAd, (CHAR)rssi2, RSSI_2);
2968 pRssi->AvgRssi2X8 = (pRssi->AvgRssi2X8 - pRssi->AvgRssi2) + pRssi->LastRssi2;
2969 pRssi->AvgRssi2 = pRssi->AvgRssi2X8 >> 3;
2975 // Normal legacy Rx packet indication
2976 VOID Indicate_Legacy_Packet(
2977 IN PRTMP_ADAPTER pAd,
2979 IN UCHAR FromWhichBSSID)
2981 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
2982 UCHAR Header802_3[LENGTH_802_3];
2984 // 1. get 802.3 Header
2986 // a. pointer pRxBlk->pData to payload
2987 // b. modify pRxBlk->DataSize
2988 #ifdef CONFIG_STA_SUPPORT
2989 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2990 RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
2991 #endif // CONFIG_STA_SUPPORT //
2993 if (pRxBlk->DataSize > MAX_RX_PKT_LEN)
2997 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
3002 STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
3005 wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
3008 // pass this 802.3 packet to upper layer or forward this packet to WM directly
3010 #ifdef CONFIG_STA_SUPPORT
3011 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3012 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxPacket, FromWhichBSSID);
3013 #endif // CONFIG_STA_SUPPORT //
3018 // Normal, AMPDU or AMSDU
3019 VOID CmmRxnonRalinkFrameIndicate(
3020 IN PRTMP_ADAPTER pAd,
3022 IN UCHAR FromWhichBSSID)
3024 #ifdef DOT11_N_SUPPORT
3025 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
3027 Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
3030 #endif // DOT11_N_SUPPORT //
3032 #ifdef DOT11_N_SUPPORT
3033 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
3036 Indicate_AMSDU_Packet(pAd, pRxBlk, FromWhichBSSID);
3039 #endif // DOT11_N_SUPPORT //
3041 Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
3047 VOID CmmRxRalinkFrameIndicate(
3048 IN PRTMP_ADAPTER pAd,
3049 IN MAC_TABLE_ENTRY *pEntry,
3051 IN UCHAR FromWhichBSSID)
3053 UCHAR Header802_3[LENGTH_802_3];
3055 UINT16 Payload1Size, Payload2Size;
3057 PNDIS_PACKET pPacket2 = NULL;
3061 Msdu2Size = *(pRxBlk->pData) + (*(pRxBlk->pData+1) << 8);
3063 if ((Msdu2Size <= 1536) && (Msdu2Size < pRxBlk->DataSize))
3065 /* skip two byte MSDU2 len */
3067 pRxBlk->DataSize -= 2;
3072 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
3076 // get 802.3 Header and remove LLC
3077 #ifdef CONFIG_STA_SUPPORT
3078 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3079 RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
3080 #endif // CONFIG_STA_SUPPORT //
3083 ASSERT(pRxBlk->pRxPacket);
3085 // Ralink Aggregation frame
3086 pAd->RalinkCounters.OneSecRxAggregationCount ++;
3087 Payload1Size = pRxBlk->DataSize - Msdu2Size;
3088 Payload2Size = Msdu2Size - LENGTH_802_3;
3090 pData2 = pRxBlk->pData + Payload1Size + LENGTH_802_3;
3091 #ifdef CONFIG_STA_SUPPORT
3092 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3093 pPacket2 = duplicate_pkt(pAd, (pData2-LENGTH_802_3), LENGTH_802_3, pData2, Payload2Size, FromWhichBSSID);
3094 #endif // CONFIG_STA_SUPPORT //
3099 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
3103 // update payload size of 1st packet
3104 pRxBlk->DataSize = Payload1Size;
3105 wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
3107 #ifdef CONFIG_STA_SUPPORT
3108 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3109 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxBlk->pRxPacket, FromWhichBSSID);
3110 #endif // CONFIG_STA_SUPPORT //
3114 #ifdef CONFIG_STA_SUPPORT
3115 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3116 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket2, FromWhichBSSID);
3117 #endif // CONFIG_STA_SUPPORT //
3122 #define RESET_FRAGFRAME(_fragFrame) \
3124 _fragFrame.RxSize = 0; \
3125 _fragFrame.Sequence = 0; \
3126 _fragFrame.LastFrag = 0; \
3127 _fragFrame.Flags = 0; \
3131 PNDIS_PACKET RTMPDeFragmentDataFrame(
3132 IN PRTMP_ADAPTER pAd,
3135 PHEADER_802_11 pHeader = pRxBlk->pHeader;
3136 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
3137 UCHAR *pData = pRxBlk->pData;
3138 USHORT DataSize = pRxBlk->DataSize;
3139 PNDIS_PACKET pRetPacket = NULL;
3140 UCHAR *pFragBuffer = NULL;
3141 BOOLEAN bReassDone = FALSE;
3142 UCHAR HeaderRoom = 0;
3147 HeaderRoom = pData - (UCHAR *)pHeader;
3149 // Re-assemble the fragmented packets
3150 if (pHeader->Frag == 0) // Frag. Number is 0 : First frag or only one pkt
3152 // the first pkt of fragment, record it.
3153 if (pHeader->FC.MoreFrag)
3155 ASSERT(pAd->FragFrame.pFragPacket);
3156 pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
3157 pAd->FragFrame.RxSize = DataSize + HeaderRoom;
3158 NdisMoveMemory(pFragBuffer, pHeader, pAd->FragFrame.RxSize);
3159 pAd->FragFrame.Sequence = pHeader->Sequence;
3160 pAd->FragFrame.LastFrag = pHeader->Frag; // Should be 0
3161 ASSERT(pAd->FragFrame.LastFrag == 0);
3162 goto done; // end of processing this frame
3165 else //Middle & End of fragment
3167 if ((pHeader->Sequence != pAd->FragFrame.Sequence) ||
3168 (pHeader->Frag != (pAd->FragFrame.LastFrag + 1)))
3170 // Fragment is not the same sequence or out of fragment number order
3171 // Reset Fragment control blk
3172 RESET_FRAGFRAME(pAd->FragFrame);
3173 DBGPRINT(RT_DEBUG_ERROR, ("Fragment is not the same sequence or out of fragment number order.\n"));
3174 goto done; // give up this frame
3176 else if ((pAd->FragFrame.RxSize + DataSize) > MAX_FRAME_SIZE)
3178 // Fragment frame is too large, it exeeds the maximum frame size.
3179 // Reset Fragment control blk
3180 RESET_FRAGFRAME(pAd->FragFrame);
3181 DBGPRINT(RT_DEBUG_ERROR, ("Fragment frame is too large, it exeeds the maximum frame size.\n"));
3182 goto done; // give up this frame
3186 // Broadcom AP(BCM94704AGR) will send out LLC in fragment's packet, LLC only can accpet at first fragment.
3187 // In this case, we will dropt it.
3189 if (NdisEqualMemory(pData, SNAP_802_1H, sizeof(SNAP_802_1H)))
3191 DBGPRINT(RT_DEBUG_ERROR, ("Find another LLC at Middle or End fragment(SN=%d, Frag=%d)\n", pHeader->Sequence, pHeader->Frag));
3192 goto done; // give up this frame
3195 pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
3197 // concatenate this fragment into the re-assembly buffer
3198 NdisMoveMemory((pFragBuffer + pAd->FragFrame.RxSize), pData, DataSize);
3199 pAd->FragFrame.RxSize += DataSize;
3200 pAd->FragFrame.LastFrag = pHeader->Frag; // Update fragment number
3203 if (pHeader->FC.MoreFrag == FALSE)
3210 // always release rx fragmented packet
3211 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
3213 // return defragmented packet if packet is reassembled completely
3214 // otherwise return NULL
3217 PNDIS_PACKET pNewFragPacket;
3219 // allocate a new packet buffer for fragment
3220 pNewFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
3224 pRetPacket = pAd->FragFrame.pFragPacket;
3225 pAd->FragFrame.pFragPacket = pNewFragPacket;
3226 pRxBlk->pHeader = (PHEADER_802_11) GET_OS_PKT_DATAPTR(pRetPacket);
3227 pRxBlk->pData = (UCHAR *)pRxBlk->pHeader + HeaderRoom;
3228 pRxBlk->DataSize = pAd->FragFrame.RxSize - HeaderRoom;
3229 pRxBlk->pRxPacket = pRetPacket;
3233 RESET_FRAGFRAME(pAd->FragFrame);
3241 VOID Indicate_AMSDU_Packet(
3242 IN PRTMP_ADAPTER pAd,
3244 IN UCHAR FromWhichBSSID)
3248 update_os_packet_info(pAd, pRxBlk, FromWhichBSSID);
3249 RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
3250 nMSDU = deaggregate_AMSDU_announce(pAd, pRxBlk->pRxPacket, pRxBlk->pData, pRxBlk->DataSize);
3253 VOID Indicate_EAPOL_Packet(
3254 IN PRTMP_ADAPTER pAd,
3256 IN UCHAR FromWhichBSSID)
3258 MAC_TABLE_ENTRY *pEntry = NULL;
3261 #ifdef CONFIG_STA_SUPPORT
3262 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3264 pEntry = &pAd->MacTab.Content[BSSID_WCID];
3265 STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
3268 #endif // CONFIG_STA_SUPPORT //
3272 DBGPRINT(RT_DEBUG_WARN, ("Indicate_EAPOL_Packet: drop and release the invalid packet.\n"));
3274 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
3279 #define BCN_TBTT_OFFSET 64 //defer 64 us
3280 VOID ReSyncBeaconTime(
3281 IN PRTMP_ADAPTER pAd)
3287 Offset = (pAd->TbttTickCount) % (BCN_TBTT_OFFSET);
3289 pAd->TbttTickCount++;
3292 // The updated BeaconInterval Value will affect Beacon Interval after two TBTT
3293 // beacasue the original BeaconInterval had been loaded into next TBTT_TIMER
3295 if (Offset == (BCN_TBTT_OFFSET-2))
3297 BCN_TIME_CFG_STRUC csr;
3298 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
3299 csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod << 4) - 1 ; // ASIC register in units of 1/16 TU = 64us
3300 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
3304 if (Offset == (BCN_TBTT_OFFSET-1))
3306 BCN_TIME_CFG_STRUC csr;
3308 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
3309 csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod) << 4; // ASIC register in units of 1/16 TU
3310 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);