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_cwmax[]={CW_MAX_IN_BITS, CW_MAX_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1};
71 UCHAR default_sta_aifsn[]={3,7,2,2};
73 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};
77 ========================================================================
80 API for MLME to transmit management frame to AP (BSS Mode)
81 or station (IBSS Mode)
84 pAd Pointer to our adapter
85 pData Pointer to the outgoing 802.11 frame
86 Length Size of outgoing management frame
98 ========================================================================
100 NDIS_STATUS MiniportMMRequest(
101 IN PRTMP_ADAPTER pAd,
106 PNDIS_PACKET pPacket;
107 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
110 UCHAR rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
112 ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
118 IrqState = pAd->irq_disabled;
122 // Reset is in progress, stop immediately
123 if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
124 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
125 !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
127 Status = NDIS_STATUS_FAILURE;
131 // Check Free priority queue
132 // Since we use PBF Queue2 for management frame. Its corresponding DMA ring should be using TxRing.
135 if (pAd->MACVersion == 0x28600100)
137 FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
141 FreeNum = GET_MGMTRING_FREENO(pAd);
146 // We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870
147 NdisZeroMemory(&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE));
148 Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE), pData, Length);
149 if (Status != NDIS_STATUS_SUCCESS)
151 DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
155 //pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
156 //pAd->CommonCfg.MlmeRate = RATE_2;
159 Status = MlmeHardTransmit(pAd, QueIdx, pPacket);
160 if (Status != NDIS_STATUS_SUCCESS)
161 RTMPFreeNdisPacket(pAd, pPacket);
165 pAd->RalinkCounters.MgmtRingFullCount++;
166 DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing, MgmtRingFullCount=%ld!\n",
167 QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
178 NDIS_STATUS MlmeDataHardTransmit(
179 IN PRTMP_ADAPTER pAd,
181 IN PNDIS_PACKET pPacket);
183 #define MAX_DATAMM_RETRY 3
185 ========================================================================
188 API for MLME to transmit management frame to AP (BSS Mode)
189 or station (IBSS Mode)
192 pAd Pointer to our adapter
193 pData Pointer to the outgoing 802.11 frame
194 Length Size of outgoing management frame
202 IRQL = DISPATCH_LEVEL
206 ========================================================================
208 NDIS_STATUS MiniportDataMMRequest(
209 IN PRTMP_ADAPTER pAd,
214 PNDIS_PACKET pPacket;
215 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
219 UCHAR rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
221 ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
224 IrqState = pAd->irq_disabled;
228 // Reset is in progress, stop immediately
229 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
230 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
231 !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
233 Status = NDIS_STATUS_FAILURE;
237 // Check Free priority queue
238 // Since we use PBF Queue2 for management frame. Its corresponding DMA ring should be using TxRing.
242 // free Tx(QueIdx) resources
243 FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
247 // We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870
248 NdisZeroMemory(&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE));
249 Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE), pData, Length);
250 if (Status != NDIS_STATUS_SUCCESS)
252 DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
256 //pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
257 //pAd->CommonCfg.MlmeRate = RATE_2;
260 Status = MlmeDataHardTransmit(pAd, QueIdx, pPacket);
261 if (Status != NDIS_STATUS_SUCCESS)
262 RTMPFreeNdisPacket(pAd, pPacket);
263 retry = MAX_DATAMM_RETRY;
269 printk("retry %d\n", retry);
270 pAd->RalinkCounters.MgmtRingFullCount++;
272 if (retry >= MAX_DATAMM_RETRY)
274 DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in DataRing, MgmtRingFullCount=%ld!\n",
275 QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
279 } while (retry < MAX_DATAMM_RETRY);
291 ========================================================================
294 Copy frame from waiting queue into relative ring buffer and set
295 appropriate ASIC register to kick hardware transmit function
298 pAd Pointer to our adapter
299 pBuffer Pointer to memory of outgoing frame
300 Length Size of outgoing management frame
308 IRQL = DISPATCH_LEVEL
312 ========================================================================
314 NDIS_STATUS MlmeHardTransmit(
315 IN PRTMP_ADAPTER pAd,
317 IN PNDIS_PACKET pPacket)
319 if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
322 return NDIS_STATUS_FAILURE;
325 return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
329 NDIS_STATUS MlmeDataHardTransmit(
330 IN PRTMP_ADAPTER pAd,
332 IN PNDIS_PACKET pPacket)
334 if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
337 return NDIS_STATUS_FAILURE;
341 return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
349 NDIS_STATUS MlmeHardTransmitMgmtRing(
350 IN PRTMP_ADAPTER pAd,
352 IN PNDIS_PACKET pPacket)
354 PACKET_INFO PacketInfo;
357 PHEADER_802_11 pHeader_802_11;
358 BOOLEAN bAckRequired, bInsertTimestamp;
360 PTXWI_STRUC pFirstTxWI;
361 MAC_TABLE_ENTRY *pMacEntry = NULL;
363 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
365 // Make sure MGMT ring resource won't be used by other threads
366 // sample, for IRQ LOCK -> SEM LOCK
367 // IrqState = pAd->irq_disabled;
369 RTMP_SEM_LOCK(&pAd->MgmtRingLock);
372 if (pSrcBufVA == NULL)
374 // The buffer shouldn't be NULL
376 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
377 return NDIS_STATUS_FAILURE;
380 #ifdef CONFIG_STA_SUPPORT
381 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
383 // outgoing frame always wakeup PHY to prevent frame lost
384 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
385 AsicForceWakeup(pAd, TRUE);
387 #endif // CONFIG_STA_SUPPORT //
389 pFirstTxWI = (PTXWI_STRUC)(pSrcBufVA + TXINFO_SIZE);
390 pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); //TXWI_SIZE);
392 if (pHeader_802_11->Addr1[0] & 0x01)
394 MlmeRate = pAd->CommonCfg.BasicMlmeRate;
398 MlmeRate = pAd->CommonCfg.MlmeRate;
401 // Verify Mlme rate for a / g bands.
402 if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band
405 if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
406 (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))
408 pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
411 #ifdef CONFIG_STA_SUPPORT
412 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
414 // Fixed W52 with Activity scan issue in ABG_MIXED and ABGN_MIXED mode.
415 if (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED
416 #ifdef DOT11_N_SUPPORT
417 || pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED
418 #endif // DOT11_N_SUPPORT //
421 if (pAd->LatchRfRegs.Channel > 14)
422 pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
424 pAd->CommonCfg.MlmeTransmit.field.MODE = 0;
427 #endif // CONFIG_STA_SUPPORT //
430 // Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)
431 // Snice it's been set to 0 while on MgtMacHeaderInit
432 // By the way this will cause frame to be send on PWR_SAVE failed.
434 // pHeader_802_11->FC.PwrMgmt = 0; // (pAd->StaCfg.Psm == PWR_SAVE);
436 // In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
437 #ifdef CONFIG_STA_SUPPORT
438 // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
439 if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL))
441 if ((pAd->StaCfg.Psm == PWR_SAVE) &&
442 (pHeader_802_11->FC.SubType == SUBTYPE_ACTION))
443 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
445 pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
447 #endif // CONFIG_STA_SUPPORT //
449 bInsertTimestamp = FALSE;
450 if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
452 #ifdef CONFIG_STA_SUPPORT
453 //Set PM bit in ps-poll, to fix WLK 1.2 PowerSaveMode_ext failure issue.
454 if ((pAd->OpMode == OPMODE_STA) && (pHeader_802_11->FC.SubType == SUBTYPE_PS_POLL))
456 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
458 #endif // CONFIG_STA_SUPPORT //
459 bAckRequired = FALSE;
461 else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
464 //pHeader_802_11->Sequence = pAd->Sequence;
466 if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
468 bAckRequired = FALSE;
469 pHeader_802_11->Duration = 0;
474 pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
475 if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
477 bInsertTimestamp = TRUE;
482 pHeader_802_11->Sequence = pAd->Sequence++;
483 if (pAd->Sequence >0xfff)
486 // Before radar detection done, mgmt frame can not be sent but probe req
487 // Because we need to use probe req to trigger driver to send probe req in passive scan
488 if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
489 && (pAd->CommonCfg.bIEEE80211H == 1)
490 && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
492 DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
494 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
495 return (NDIS_STATUS_FAILURE);
499 RTMPFrameEndianChange(pAd, (PUCHAR)pHeader_802_11, DIR_WRITE, FALSE);
503 // fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
504 // should always has only one ohysical buffer, and the whole frame size equals
505 // to the first scatter buffer size
508 // Initialize TX Descriptor
509 // For inter-frame gap, the number is for this frame and next frame
510 // For MLME rate, we will fix as 2Mb to match other vendor's implement
511 // pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
513 // management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
514 if (pMacEntry == NULL)
516 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
517 0, RESERVED_WCID, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID_MGMT, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
521 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
522 bInsertTimestamp, FALSE, bAckRequired, FALSE,
523 0, pMacEntry->Aid, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE),
524 pMacEntry->MaxHTPhyMode.field.MCS, 0,
525 (UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
526 IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
530 RTMPWIEndianChange((PUCHAR)pFirstTxWI, TYPE_TXWI);
533 // Now do hardware-depened kick out.
534 HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen);
536 // Make sure to release MGMT ring resource
538 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
539 return NDIS_STATUS_SUCCESS;
543 /********************************************************************************
545 New DeQueue Procedures.
547 ********************************************************************************/
549 #define DEQUEUE_LOCK(lock, bIntContext, IrqFlags) \
551 if (bIntContext == FALSE) \
552 RTMP_IRQ_LOCK((lock), IrqFlags); \
555 #define DEQUEUE_UNLOCK(lock, bIntContext, IrqFlags) \
557 if (bIntContext == FALSE) \
558 RTMP_IRQ_UNLOCK((lock), IrqFlags); \
563 ========================================================================
564 Tx Path design algorithm:
565 Basically, we divide the packets into four types, Broadcast/Multicast, 11N Rate(AMPDU, AMSDU, Normal), B/G Rate(ARALINK, Normal),
566 Specific Packet Type. Following show the classification rule and policy for each kinds of packets.
567 Classification Rule=>
568 Multicast: (*addr1 & 0x01) == 0x01
569 Specific : bDHCPFrame, bARPFrame, bEAPOLFrame, etc.
570 11N Rate : If peer support HT
571 (1).AMPDU -- If TXBA is negotiated.
572 (2).AMSDU -- If AMSDU is capable for both peer and ourself.
573 *). AMSDU can embedded in a AMPDU, but now we didn't support it.
574 (3).Normal -- Other packets which send as 11n rate.
576 B/G Rate : If peer is b/g only.
577 (1).ARALINK-- If both of peer/us supprot Ralink proprietary Aggregation and the TxRate is large than RATE_6
578 (2).Normal -- Other packets which send as b/g rate.
580 The packet must be unicast, NOT A-RALINK, NOT A-MSDU, NOT 11n, then can consider about fragment.
582 Classified Packet Handle Rule=>
584 No ACK, //pTxBlk->bAckRequired = FALSE;
585 No WMM, //pTxBlk->bWMM = FALSE;
586 No piggyback, //pTxBlk->bPiggyBack = FALSE;
587 Force LowRate, //pTxBlk->bForceLowRate = TRUE;
588 Specific : Basically, for specific packet, we should handle it specifically, but now all specific packets are use
589 the same policy to handle it.
590 Force LowRate, //pTxBlk->bForceLowRate = TRUE;
593 No piggyback, //pTxBlk->bPiggyBack = FALSE;
605 ========================================================================
607 static UCHAR TxPktClassification(
608 IN RTMP_ADAPTER *pAd,
609 IN PNDIS_PACKET pPacket)
611 UCHAR TxFrameType = TX_UNKOWN_FRAME;
613 MAC_TABLE_ENTRY *pMacEntry = NULL;
614 #ifdef DOT11_N_SUPPORT
615 BOOLEAN bHTRate = FALSE;
616 #endif // DOT11_N_SUPPORT //
618 Wcid = RTMP_GET_PACKET_WCID(pPacket);
619 if (Wcid == MCAST_WCID)
620 { // Handle for RA is Broadcast/Multicast Address.
621 return TX_MCAST_FRAME;
624 // Handle for unicast packets
625 pMacEntry = &pAd->MacTab.Content[Wcid];
626 if (RTMP_GET_PACKET_LOWRATE(pPacket))
627 { // It's a specific packet need to force low rate, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame
628 TxFrameType = TX_LEGACY_FRAME;
630 #ifdef DOT11_N_SUPPORT
631 else if (IS_HT_RATE(pMacEntry))
632 { // it's a 11n capable packet
634 // Depends on HTPhyMode to check if the peer support the HTRate transmission.
635 // Currently didn't support A-MSDU embedded in A-MPDU
637 if (RTMP_GET_PACKET_MOREDATA(pPacket) || (pMacEntry->PsMode == PWR_SAVE))
638 TxFrameType = TX_LEGACY_FRAME;
639 #ifdef UAPSD_AP_SUPPORT
640 else if (RTMP_GET_PACKET_EOSP(pPacket))
641 TxFrameType = TX_LEGACY_FRAME;
642 #endif // UAPSD_AP_SUPPORT //
643 else if((pMacEntry->TXBAbitmap & (1<<(RTMP_GET_PACKET_UP(pPacket)))) != 0)
644 return TX_AMPDU_FRAME;
645 else if(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AMSDU_INUSED))
646 return TX_AMSDU_FRAME;
648 TxFrameType = TX_LEGACY_FRAME;
650 #endif // DOT11_N_SUPPORT //
652 { // it's a legacy b/g packet.
653 if ((CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE) && pAd->CommonCfg.bAggregationCapable) &&
654 (RTMP_GET_PACKET_TXRATE(pPacket) >= RATE_6) &&
655 (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
656 { // if peer support Ralink Aggregation, we use it.
657 TxFrameType = TX_RALINK_FRAME;
661 TxFrameType = TX_LEGACY_FRAME;
665 // Currently, our fragment only support when a unicast packet send as NOT-ARALINK, NOT-AMSDU and NOT-AMPDU.
666 if ((RTMP_GET_PACKET_FRAGMENTS(pPacket) > 1) && (TxFrameType == TX_LEGACY_FRAME))
667 TxFrameType = TX_FRAG_FRAME;
673 BOOLEAN RTMP_FillTxBlkInfo(
674 IN RTMP_ADAPTER *pAd,
677 PACKET_INFO PacketInfo;
678 PNDIS_PACKET pPacket;
679 PMAC_TABLE_ENTRY pMacEntry = NULL;
681 pPacket = pTxBlk->pPacket;
682 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen);
684 pTxBlk->Wcid = RTMP_GET_PACKET_WCID(pPacket);
685 pTxBlk->apidx = RTMP_GET_PACKET_IF(pPacket);
686 pTxBlk->UserPriority = RTMP_GET_PACKET_UP(pPacket);
687 pTxBlk->FrameGap = IFS_HTTXOP; // ASIC determine Frame Gap
689 if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pTxBlk->pPacket))
690 TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame);
692 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bClearEAPFrame);
694 // Default to clear this flag
695 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bForceNonQoS);
698 if (pTxBlk->Wcid == MCAST_WCID)
700 pTxBlk->pMacEntry = NULL;
702 #ifdef MCAST_RATE_SPECIFIC
703 PUCHAR pDA = GET_OS_PKT_DATAPTR(pPacket);
704 if (((*pDA & 0x01) == 0x01) && (*pDA != 0xff))
705 pTxBlk->pTransmit = &pAd->CommonCfg.MCastPhyMode;
707 #endif // MCAST_RATE_SPECIFIC //
708 pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
711 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); // AckRequired = FALSE, when broadcast packet in Adhoc mode.
712 //TX_BLK_SET_FLAG(pTxBlk, fTX_bForceLowRate);
713 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAllowFrag);
714 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
715 if (RTMP_GET_PACKET_MOREDATA(pPacket))
717 TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
723 pTxBlk->pMacEntry = &pAd->MacTab.Content[pTxBlk->Wcid];
724 pTxBlk->pTransmit = &pTxBlk->pMacEntry->HTPhyMode;
726 pMacEntry = pTxBlk->pMacEntry;
729 // For all unicast packets, need Ack unless the Ack Policy is not set as NORMAL_ACK.
730 if (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx] != NORMAL_ACK)
731 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);
733 TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired);
737 #ifdef CONFIG_STA_SUPPORT
738 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
741 // If support WMM, enable it.
742 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
743 CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))
744 TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM);
746 // if (pAd->StaCfg.bAutoTxRateSwitch)
747 // TX_BLK_SET_FLAG(pTxBlk, fTX_AutoRateSwitch);
749 #endif // CONFIG_STA_SUPPORT //
752 if (pTxBlk->TxFrameType == TX_LEGACY_FRAME)
754 if ( (RTMP_GET_PACKET_LOWRATE(pPacket)) ||
755 ((pAd->OpMode == OPMODE_AP) && (pMacEntry->MaxHTPhyMode.field.MODE == MODE_CCK) && (pMacEntry->MaxHTPhyMode.field.MCS == RATE_1)))
756 { // Specific packet, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame, need force low rate.
757 pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
758 #ifdef DOT11_N_SUPPORT
759 // Modify the WMM bit for ICV issue. If we have a packet with EOSP field need to set as 1, how to handle it???
760 if (IS_HT_STA(pTxBlk->pMacEntry) &&
761 (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RALINK_CHIPSET)) &&
762 ((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RDG_CAPABLE)))
764 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
765 TX_BLK_SET_FLAG(pTxBlk, fTX_bForceNonQoS);
767 #endif // DOT11_N_SUPPORT //
770 #ifdef DOT11_N_SUPPORT
771 if ( (IS_HT_RATE(pMacEntry) == FALSE) &&
772 (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE)))
773 { // Currently piggy-back only support when peer is operate in b/g mode.
774 TX_BLK_SET_FLAG(pTxBlk, fTX_bPiggyBack);
776 #endif // DOT11_N_SUPPORT //
778 if (RTMP_GET_PACKET_MOREDATA(pPacket))
780 TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
782 #ifdef UAPSD_AP_SUPPORT
783 if (RTMP_GET_PACKET_EOSP(pPacket))
785 TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP);
787 #endif // UAPSD_AP_SUPPORT //
789 else if (pTxBlk->TxFrameType == TX_FRAG_FRAME)
791 TX_BLK_SET_FLAG(pTxBlk, fTX_bAllowFrag);
794 pMacEntry->DebugTxCount++;
804 BOOLEAN CanDoAggregateTransmit(
805 IN RTMP_ADAPTER *pAd,
806 IN NDIS_PACKET *pPacket,
810 //printk("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType);
812 if (RTMP_GET_PACKET_WCID(pPacket) == MCAST_WCID)
815 if (RTMP_GET_PACKET_DHCP(pPacket) ||
816 RTMP_GET_PACKET_EAPOL(pPacket) ||
817 RTMP_GET_PACKET_WAI(pPacket))
820 if ((pTxBlk->TxFrameType == TX_AMSDU_FRAME) &&
821 ((pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))> (RX_BUFFER_AGGRESIZE - 100)))
822 { // For AMSDU, allow the packets with total length < max-amsdu size
826 if ((pTxBlk->TxFrameType == TX_RALINK_FRAME) &&
827 (pTxBlk->TxPacketList.Number == 2))
828 { // For RALINK-Aggregation, allow two frames in one batch.
832 #ifdef CONFIG_STA_SUPPORT
833 if ((INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) // must be unicast to AP
836 #endif // CONFIG_STA_SUPPORT //
843 ========================================================================
846 To do the enqueue operation and extract the first item of waiting
847 list. If a number of available shared memory segments could meet
848 the request of extracted item, the extracted item will be fragmented
849 into shared memory segments.
852 pAd Pointer to our adapter
853 pQueue Pointer to Waiting Queue
858 IRQL = DISPATCH_LEVEL
862 ========================================================================
864 VOID RTMPDeQueuePacket(
865 IN PRTMP_ADAPTER pAd,
866 IN BOOLEAN bIntContext,
867 IN UCHAR QIdx, /* BulkOutPipeId */
868 IN UCHAR Max_Tx_Packets)
870 PQUEUE_ENTRY pEntry = NULL;
871 PNDIS_PACKET pPacket;
872 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
874 PQUEUE_HEADER pQueue;
875 ULONG FreeNumber[NUM_OF_TX_RING];
876 UCHAR QueIdx, sQIdx, eQIdx;
877 unsigned long IrqFlags = 0;
878 BOOLEAN hasTxDesc = FALSE;
884 RtmpDiagStruct *pDiagStruct = &pAd->DiagStruct;
888 if (QIdx == NUM_OF_TX_RING)
891 //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
892 #ifdef CONFIG_STA_SUPPORT
893 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
894 eQIdx = 3; // 4 ACs, start from 0.
895 #endif // CONFIG_STA_SUPPORT //
899 sQIdx = eQIdx = QIdx;
902 for (QueIdx=sQIdx; QueIdx <= eQIdx; QueIdx++)
906 RT28XX_START_DEQUEUE(pAd, QueIdx, IrqFlags);
909 firstRound = ((QueIdx == 0) ? TRUE : FALSE);
910 #endif // DBG_DIAGNOSE //
914 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS |
915 fRTMP_ADAPTER_RADIO_OFF |
916 fRTMP_ADAPTER_RESET_IN_PROGRESS |
917 fRTMP_ADAPTER_HALT_IN_PROGRESS |
918 fRTMP_ADAPTER_NIC_NOT_EXIST))))
920 RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
924 if (Count >= Max_Tx_Packets)
927 DEQUEUE_LOCK(&pAd->irq_lock, bIntContext, IrqFlags);
928 if (&pAd->TxSwQueue[QueIdx] == NULL)
931 if (firstRound == TRUE)
932 pDiagStruct->TxSWQueCnt[pDiagStruct->ArrayCurIdx][0]++;
933 #endif // DBG_DIAGNOSE //
934 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
939 // probe the Queue Head
940 pQueue = &pAd->TxSwQueue[QueIdx];
941 if ((pEntry = pQueue->Head) == NULL)
943 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
948 NdisZeroMemory((PUCHAR)pTxBlk, sizeof(TX_BLK));
949 //InitializeQueueHeader(&pTxBlk->TxPacketList); // Didn't need it because we already memzero it.
950 pTxBlk->QueIdx = QueIdx;
952 pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
954 // Early check to make sure we have enoguh Tx Resource.
955 hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
958 pAd->PrivateInfo.TxRingFullCnt++;
960 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
965 pTxBlk->TxFrameType = TxPktClassification(pAd, pPacket);
966 pEntry = RemoveHeadQueue(pQueue);
967 pTxBlk->TotalFrameNum++;
968 pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); // The real fragment number maybe vary
969 pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
970 pTxBlk->pPacket = pPacket;
971 InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
973 if (pTxBlk->TxFrameType == TX_RALINK_FRAME || pTxBlk->TxFrameType == TX_AMSDU_FRAME)
975 // Enhance SW Aggregation Mechanism
976 if (NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, FreeNumber[QueIdx], pTxBlk->TxFrameType))
978 InsertHeadQueue(pQueue, PACKET_TO_QUEUE_ENTRY(pPacket));
979 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
984 if((pEntry = pQueue->Head) == NULL)
987 // For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation.
988 pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
989 FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
990 hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
991 if ((hasTxDesc == FALSE) || (CanDoAggregateTransmit(pAd, pPacket, pTxBlk) == FALSE))
994 //Remove the packet from the TxSwQueue and insert into pTxBlk
995 pEntry = RemoveHeadQueue(pQueue);
997 pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
998 pTxBlk->TotalFrameNum++;
999 pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); // The real fragment number maybe vary
1000 pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
1001 InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
1004 if (pTxBlk->TxPacketList.Number == 1)
1005 pTxBlk->TxFrameType = TX_LEGACY_FRAME;
1009 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
1012 Count += pTxBlk->TxPacketList.Number;
1014 // Do HardTransmit now.
1015 #ifdef CONFIG_STA_SUPPORT
1016 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1017 Status = STAHardTransmit(pAd, pTxBlk, QueIdx);
1018 #endif // CONFIG_STA_SUPPORT //
1021 RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
1025 RTUSBKickBulkOut(pAd);
1033 ========================================================================
1035 Routine Description:
1036 Calculates the duration which is required to transmit out frames
1037 with given size and specified rate.
1040 pAd Pointer to our adapter
1042 Size Frame size in units of byte
1045 Duration number in units of usec
1047 IRQL = PASSIVE_LEVEL
1048 IRQL = DISPATCH_LEVEL
1052 ========================================================================
1054 USHORT RTMPCalcDuration(
1055 IN PRTMP_ADAPTER pAd,
1061 if (Rate < RATE_FIRST_OFDM_RATE) // CCK
1063 if ((Rate > RATE_1) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED))
1064 Duration = 96; // 72+24 preamble+plcp
1066 Duration = 192; // 144+48 preamble+plcp
1068 Duration += (USHORT)((Size << 4) / RateIdTo500Kbps[Rate]);
1069 if ((Size << 4) % RateIdTo500Kbps[Rate])
1072 else if (Rate <= RATE_LAST_OFDM_RATE)// OFDM rates
1074 Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension
1075 Duration += 4 * (USHORT)((11 + Size * 4) / RateIdTo500Kbps[Rate]);
1076 if ((11 + Size * 4) % RateIdTo500Kbps[Rate])
1081 Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension
1084 return (USHORT)Duration;
1089 ========================================================================
1091 Routine Description:
1092 Calculates the duration which is required to transmit out frames
1093 with given size and specified rate.
1096 pTxWI Pointer to head of each MPDU to HW.
1097 Ack Setting for Ack requirement bit
1098 Fragment Setting for Fragment bit
1099 RetryMode Setting for retry mode
1100 Ifs Setting for IFS gap
1101 Rate Setting for transmit rate
1102 Service Setting for service
1104 TxPreamble Short or Long preamble when using CCK rates
1105 QueIdx - 0-3, according to 802.11e/d4.4 June/2003
1110 IRQL = PASSIVE_LEVEL
1111 IRQL = DISPATCH_LEVEL
1113 See also : BASmartHardTransmit() !!!
1115 ========================================================================
1118 IN PRTMP_ADAPTER pAd,
1119 IN PTXWI_STRUC pOutTxWI,
1122 IN BOOLEAN InsTimestamp,
1125 IN BOOLEAN NSeq, // HW new a sequence.
1134 IN HTTRANSMIT_SETTING *pTransmit)
1136 PMAC_TABLE_ENTRY pMac = NULL;
1140 if (WCID < MAX_LEN_OF_MAC_TABLE)
1141 pMac = &pAd->MacTab.Content[WCID];
1144 // Always use Long preamble before verifiation short preamble functionality works well.
1145 // Todo: remove the following line if short preamble functionality works
1147 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1148 NdisZeroMemory(&TxWI, TXWI_SIZE);
1153 pTxWI->CFACK = CFACK;
1154 pTxWI->TS= InsTimestamp;
1155 pTxWI->AMPDU = AMPDU;
1157 pTxWI->txop= Txopmode;
1160 // John tune the performace with Intel Client in 20 MHz performance
1161 #ifdef DOT11_N_SUPPORT
1162 BASize = pAd->CommonCfg.TxBASize;
1166 pTxWI->BAWinSize = BASize;
1167 pTxWI->ShortGI = pTransmit->field.ShortGI;
1168 pTxWI->STBC = pTransmit->field.STBC;
1169 #endif // DOT11_N_SUPPORT //
1171 pTxWI->WirelessCliID = WCID;
1172 pTxWI->MPDUtotalByteCount = Length;
1173 pTxWI->PacketId = PID;
1175 // If CCK or OFDM, BW must be 20
1176 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1177 #ifdef DOT11N_DRAFT3
1179 pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
1180 #endif // DOT11N_DRAFT3 //
1182 pTxWI->MCS = pTransmit->field.MCS;
1183 pTxWI->PHYMODE = pTransmit->field.MODE;
1184 pTxWI->CFACK = CfAck;
1186 #ifdef DOT11_N_SUPPORT
1189 if (pAd->CommonCfg.bMIMOPSEnable)
1191 if ((pMac->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1193 // Dynamic MIMO Power Save Mode
1196 else if (pMac->MmpsMode == MMPS_STATIC)
1198 // Static MIMO Power Save Mode
1199 if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
1206 //pTxWI->MIMOps = (pMac->PsMode == PWR_MMPS)? 1:0;
1207 if (pMac->bIAmBadAtheros && (pMac->WepStatus != Ndis802_11WEPDisabled))
1209 pTxWI->MpduDensity = 7;
1213 pTxWI->MpduDensity = pMac->MpduDensity;
1216 #endif // DOT11_N_SUPPORT //
1218 pTxWI->PacketId = pTxWI->MCS;
1219 NdisMoveMemory(pOutTxWI, &TxWI, sizeof(TXWI_STRUC));
1223 VOID RTMPWriteTxWI_Data(
1224 IN PRTMP_ADAPTER pAd,
1225 IN OUT PTXWI_STRUC pTxWI,
1228 HTTRANSMIT_SETTING *pTransmit;
1229 PMAC_TABLE_ENTRY pMacEntry;
1230 #ifdef DOT11_N_SUPPORT
1232 #endif // DOT11_N_SUPPORT //
1237 pTransmit = pTxBlk->pTransmit;
1238 pMacEntry = pTxBlk->pMacEntry;
1242 // Always use Long preamble before verifiation short preamble functionality works well.
1243 // Todo: remove the following line if short preamble functionality works
1245 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1246 NdisZeroMemory(pTxWI, TXWI_SIZE);
1248 pTxWI->FRAG = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag);
1249 pTxWI->ACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAckRequired);
1250 pTxWI->txop = pTxBlk->FrameGap;
1252 pTxWI->WirelessCliID = pTxBlk->Wcid;
1254 pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
1255 pTxWI->CFACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bPiggyBack);
1257 // If CCK or OFDM, BW must be 20
1258 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1259 #ifdef DOT11_N_SUPPORT
1260 #ifdef DOT11N_DRAFT3
1262 pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
1263 #endif // DOT11N_DRAFT3 //
1264 pTxWI->AMPDU = ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) ? TRUE : FALSE);
1266 // John tune the performace with Intel Client in 20 MHz performance
1267 BASize = pAd->CommonCfg.TxBASize;
1268 if((pTxBlk->TxFrameType == TX_AMPDU_FRAME) && (pMacEntry))
1270 UCHAR RABAOriIdx = 0; //The RA's BA Originator table index.
1272 RABAOriIdx = pTxBlk->pMacEntry->BAOriWcidArray[pTxBlk->UserPriority];
1273 BASize = pAd->BATable.BAOriEntry[RABAOriIdx].BAWinSize;
1276 pTxWI->TxBF = pTransmit->field.TxBF;
1277 pTxWI->BAWinSize = BASize;
1278 pTxWI->ShortGI = pTransmit->field.ShortGI;
1279 pTxWI->STBC = pTransmit->field.STBC;
1280 #endif // DOT11_N_SUPPORT //
1282 pTxWI->MCS = pTransmit->field.MCS;
1283 pTxWI->PHYMODE = pTransmit->field.MODE;
1285 #ifdef DOT11_N_SUPPORT
1288 if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1290 // Dynamic MIMO Power Save Mode
1293 else if (pMacEntry->MmpsMode == MMPS_STATIC)
1295 // Static MIMO Power Save Mode
1296 if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
1303 if (pMacEntry->bIAmBadAtheros && (pMacEntry->WepStatus != Ndis802_11WEPDisabled))
1305 pTxWI->MpduDensity = 7;
1309 pTxWI->MpduDensity = pMacEntry->MpduDensity;
1312 #endif // DOT11_N_SUPPORT //
1315 if (pTxBlk->QueIdx== 0)
1317 pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
1318 pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
1320 #endif // DBG_DIAGNOSE //
1322 // for rate adapation
1323 pTxWI->PacketId = pTxWI->MCS;
1324 #ifdef INF_AMAZON_SE
1325 /*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate */
1326 if( RTMP_GET_PACKET_NOBULKOUT(pTxBlk->pPacket))
1328 if(pTxWI->PHYMODE == MODE_CCK)
1330 pTxWI->PacketId = 6;
1333 #endif // INF_AMAZON_SE //
1337 VOID RTMPWriteTxWI_Cache(
1338 IN PRTMP_ADAPTER pAd,
1339 IN OUT PTXWI_STRUC pTxWI,
1342 PHTTRANSMIT_SETTING /*pTxHTPhyMode,*/ pTransmit;
1343 PMAC_TABLE_ENTRY pMacEntry;
1348 pMacEntry = pTxBlk->pMacEntry;
1349 pTransmit = pTxBlk->pTransmit;
1351 //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
1352 //if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pMacEntry))
1353 //if (TX_BLK_TEST_FLAG(pTxBlk, fTX_AutoRateSwitch))
1354 if (pMacEntry->bAutoTxRateSwitch)
1356 pTxWI->txop = IFS_HTTXOP;
1358 // If CCK or OFDM, BW must be 20
1359 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1360 pTxWI->ShortGI = pTransmit->field.ShortGI;
1361 pTxWI->STBC = pTransmit->field.STBC;
1363 pTxWI->MCS = pTransmit->field.MCS;
1364 pTxWI->PHYMODE = pTransmit->field.MODE;
1366 // set PID for TxRateSwitching
1367 pTxWI->PacketId = pTransmit->field.MCS;
1370 #ifdef DOT11_N_SUPPORT
1371 pTxWI->AMPDU = ((pMacEntry->NoBADataCountDown == 0) ? TRUE: FALSE);
1374 #ifdef DOT11N_DRAFT3
1376 pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
1377 #endif // DOT11N_DRAFT3 //
1379 if (pAd->CommonCfg.bMIMOPSEnable)
1381 // MIMO Power Save Mode
1382 if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1384 // Dynamic MIMO Power Save Mode
1387 else if (pMacEntry->MmpsMode == MMPS_STATIC)
1389 // Static MIMO Power Save Mode
1390 if ((pTransmit->field.MODE >= MODE_HTMIX) && (pTransmit->field.MCS > 7))
1397 #endif // DOT11_N_SUPPORT //
1400 if (pTxBlk->QueIdx== 0)
1402 pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
1403 pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
1405 #endif // DBG_DIAGNOSE //
1407 pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
1413 ========================================================================
1415 Routine Description:
1416 Calculates the duration which is required to transmit out frames
1417 with given size and specified rate.
1420 pTxD Pointer to transmit descriptor
1421 Ack Setting for Ack requirement bit
1422 Fragment Setting for Fragment bit
1423 RetryMode Setting for retry mode
1424 Ifs Setting for IFS gap
1425 Rate Setting for transmit rate
1426 Service Setting for service
1428 TxPreamble Short or Long preamble when using CCK rates
1429 QueIdx - 0-3, according to 802.11e/d4.4 June/2003
1434 IRQL = PASSIVE_LEVEL
1435 IRQL = DISPATCH_LEVEL
1437 ========================================================================
1439 VOID RTMPWriteTxDescriptor(
1440 IN PRTMP_ADAPTER pAd,
1446 // Always use Long preamble before verifiation short preamble functionality works well.
1447 // Todo: remove the following line if short preamble functionality works
1449 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1451 pTxD->WIV = (bWIV) ? 1: 0;
1452 pTxD->QSEL= (QueueSEL);
1453 if (pAd->bGenOneHCCA == TRUE)
1454 pTxD->QSEL= FIFO_HCCA;
1459 // should be called only when -
1460 // 1. MEADIA_CONNECTED
1461 // 2. AGGREGATION_IN_USED
1462 // 3. Fragmentation not in used
1463 // 4. either no previous frame (pPrevAddr1=NULL) .OR. previoud frame is aggregatible
1464 BOOLEAN TxFrameIsAggregatible(
1465 IN PRTMP_ADAPTER pAd,
1466 IN PUCHAR pPrevAddr1,
1470 // can't aggregate EAPOL (802.1x) frame
1471 if ((p8023hdr[12] == 0x88) && (p8023hdr[13] == 0x8e))
1474 // can't aggregate multicast/broadcast frame
1475 if (p8023hdr[0] & 0x01)
1478 if (INFRA_ON(pAd)) // must be unicast to AP
1480 else if ((pPrevAddr1 == NULL) || MAC_ADDR_EQUAL(pPrevAddr1, p8023hdr)) // unicast to same STA
1488 ========================================================================
1490 Routine Description:
1491 Check the MSDU Aggregation policy
1492 1.HT aggregation is A-MSDU
1493 2.legaacy rate aggregation is software aggregation by Ralink.
1501 ========================================================================
1503 BOOLEAN PeerIsAggreOn(
1504 IN PRTMP_ADAPTER pAd,
1506 IN PMAC_TABLE_ENTRY pMacEntry)
1508 ULONG AFlags = (fCLIENT_STATUS_AMSDU_INUSED | fCLIENT_STATUS_AGGREGATION_CAPABLE);
1510 if (pMacEntry != NULL && CLIENT_STATUS_TEST_FLAG(pMacEntry, AFlags))
1512 #ifdef DOT11_N_SUPPORT
1513 if (pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
1517 #endif // DOT11_N_SUPPORT //
1519 #ifdef AGGREGATION_SUPPORT
1520 if (TxRate >= RATE_6 && pAd->CommonCfg.bAggregationCapable && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
1521 { // legacy Ralink Aggregation support
1524 #endif // AGGREGATION_SUPPORT //
1533 ========================================================================
1535 Routine Description:
1536 Check and fine the packet waiting in SW queue with highest priority
1539 pAd Pointer to our adapter
1542 pQueue Pointer to Waiting Queue
1544 IRQL = DISPATCH_LEVEL
1548 ========================================================================
1550 PQUEUE_HEADER RTMPCheckTxSwQueue(
1551 IN PRTMP_ADAPTER pAd,
1556 // 2004-11-15 to be removed. test aggregation only
1557 // if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)) && (*pNumber < 2))
1560 Number = pAd->TxSwQueue[QID_AC_BK].Number
1561 + pAd->TxSwQueue[QID_AC_BE].Number
1562 + pAd->TxSwQueue[QID_AC_VI].Number
1563 + pAd->TxSwQueue[QID_AC_VO].Number
1564 + pAd->TxSwQueue[QID_HCCA].Number;
1566 if (pAd->TxSwQueue[QID_AC_VO].Head != NULL)
1568 *pQueIdx = QID_AC_VO;
1569 return (&pAd->TxSwQueue[QID_AC_VO]);
1571 else if (pAd->TxSwQueue[QID_AC_VI].Head != NULL)
1573 *pQueIdx = QID_AC_VI;
1574 return (&pAd->TxSwQueue[QID_AC_VI]);
1576 else if (pAd->TxSwQueue[QID_AC_BE].Head != NULL)
1578 *pQueIdx = QID_AC_BE;
1579 return (&pAd->TxSwQueue[QID_AC_BE]);
1581 else if (pAd->TxSwQueue[QID_AC_BK].Head != NULL)
1583 *pQueIdx = QID_AC_BK;
1584 return (&pAd->TxSwQueue[QID_AC_BK]);
1586 else if (pAd->TxSwQueue[QID_HCCA].Head != NULL)
1588 *pQueIdx = QID_HCCA;
1589 return (&pAd->TxSwQueue[QID_HCCA]);
1592 // No packet pending in Tx Sw queue
1593 *pQueIdx = QID_AC_BK;
1601 ========================================================================
1603 Routine Description:
1604 Suspend MSDU transmission
1607 pAd Pointer to our adapter
1614 ========================================================================
1616 VOID RTMPSuspendMsduTransmission(
1617 IN PRTMP_ADAPTER pAd)
1619 DBGPRINT(RT_DEBUG_TRACE,("SCANNING, suspend MSDU transmission ...\n"));
1623 // Before BSS_SCAN_IN_PROGRESS, we need to keep Current R66 value and
1624 // use Lowbound as R66 value on ScanNextChannel(...)
1626 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1628 // set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning)
1629 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x26 + GET_LNA_GAIN(pAd)));
1630 RTMPSetAGCInitValue(pAd, BW_20);
1632 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1633 //RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x000f0000); // abort all TX rings
1638 ========================================================================
1640 Routine Description:
1641 Resume MSDU transmission
1644 pAd Pointer to our adapter
1649 IRQL = DISPATCH_LEVEL
1653 ========================================================================
1655 VOID RTMPResumeMsduTransmission(
1656 IN PRTMP_ADAPTER pAd)
1660 DBGPRINT(RT_DEBUG_TRACE,("SCAN done, resume MSDU transmission ...\n"));
1663 // After finish BSS_SCAN_IN_PROGRESS, we need to restore Current R66 value
1664 // R66 should not be 0
1665 if (pAd->BbpTuning.R66CurrentValue == 0)
1667 pAd->BbpTuning.R66CurrentValue = 0x38;
1668 DBGPRINT_ERR(("RTMPResumeMsduTransmission, R66CurrentValue=0...\n"));
1670 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, pAd->BbpTuning.R66CurrentValue);
1672 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1673 // sample, for IRQ LOCK to SEM LOCK
1674 // IrqState = pAd->irq_disabled;
1676 // RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1678 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1682 UINT deaggregate_AMSDU_announce(
1683 IN PRTMP_ADAPTER pAd,
1684 PNDIS_PACKET pPacket,
1689 USHORT SubFrameSize;
1690 PHEADER_802_3 pAMSDUsubheader;
1692 UCHAR Header802_3[14];
1694 PUCHAR pPayload, pDA, pSA, pRemovedLLCSNAP;
1695 PNDIS_PACKET pClonePacket;
1701 while (DataSize > LENGTH_802_3)
1706 //hex_dump("subheader", pData, 64);
1707 pAMSDUsubheader = (PHEADER_802_3)pData;
1708 //pData += LENGTH_802_3;
1709 PayloadSize = pAMSDUsubheader->Octet[1] + (pAMSDUsubheader->Octet[0]<<8);
1710 SubFrameSize = PayloadSize + LENGTH_802_3;
1713 if ((DataSize < SubFrameSize) || (PayloadSize > 1518 ))
1718 //printk("%d subframe: Size = %d\n", nMSDU, PayloadSize);
1720 pPayload = pData + LENGTH_802_3;
1722 pSA = pData + MAC_ADDR_LEN;
1724 // convert to 802.3 header
1725 CONVERT_TO_802_3(Header802_3, pDA, pSA, pPayload, PayloadSize, pRemovedLLCSNAP);
1727 #ifdef CONFIG_STA_SUPPORT
1728 if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E) )
1730 // avoid local heap overflow, use dyanamic allocation
1731 MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
1732 memmove(Elem->Msg+(LENGTH_802_11 + LENGTH_802_1_H), pPayload, PayloadSize);
1733 Elem->MsgLen = LENGTH_802_11 + LENGTH_802_1_H + PayloadSize;
1734 WpaEAPOLKeyAction(pAd, Elem);
1737 #endif // CONFIG_STA_SUPPORT //
1739 #ifdef CONFIG_STA_SUPPORT
1740 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1742 if (pRemovedLLCSNAP)
1744 pPayload -= LENGTH_802_3;
1745 PayloadSize += LENGTH_802_3;
1746 NdisMoveMemory(pPayload, &Header802_3[0], LENGTH_802_3);
1749 #endif // CONFIG_STA_SUPPORT //
1751 pClonePacket = ClonePacket(pAd, pPacket, pPayload, PayloadSize);
1754 #ifdef CONFIG_STA_SUPPORT
1755 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1756 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pClonePacket, RTMP_GET_PACKET_IF(pPacket));
1757 #endif // CONFIG_STA_SUPPORT //
1761 // A-MSDU has padding to multiple of 4 including subframe header.
1762 // align SubFrameSize up to multiple of 4
1763 SubFrameSize = (SubFrameSize+3)&(~0x3);
1766 if (SubFrameSize > 1528 || SubFrameSize < 32)
1771 if (DataSize > SubFrameSize)
1773 pData += SubFrameSize;
1774 DataSize -= SubFrameSize;
1783 // finally release original rx packet
1784 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1790 UINT BA_Reorder_AMSDU_Annnounce(
1791 IN PRTMP_ADAPTER pAd,
1792 IN PNDIS_PACKET pPacket)
1798 pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
1799 DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
1801 nMSDU = deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
1808 ==========================================================================
1810 Look up the MAC address in the MAC table. Return NULL if not found.
1812 pEntry - pointer to the MAC entry; NULL is not found
1813 ==========================================================================
1815 MAC_TABLE_ENTRY *MacTableLookup(
1816 IN PRTMP_ADAPTER pAd,
1820 MAC_TABLE_ENTRY *pEntry = NULL;
1822 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
1823 pEntry = pAd->MacTab.Hash[HashIdx];
1825 while (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsWDS || pEntry->ValidAsApCli || pEntry->ValidAsMesh))
1827 if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
1832 pEntry = pEntry->pNext;
1838 MAC_TABLE_ENTRY *MacTableInsertEntry(
1839 IN PRTMP_ADAPTER pAd,
1842 IN BOOLEAN CleanAll)
1846 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1851 if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
1855 #ifdef CONFIG_STA_SUPPORT
1856 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1857 if (pAd->StaCfg.BssType == BSS_INFRA)
1859 #endif // CONFIG_STA_SUPPORT //
1861 // allocate one MAC entry
1862 NdisAcquireSpinLock(&pAd->MacTabLock);
1863 for (i = FirstWcid; i< MAX_LEN_OF_MAC_TABLE; i++) // skip entry#0 so that "entry index == AID" for fast lookup
1865 // pick up the first available vacancy
1866 if ((pAd->MacTab.Content[i].ValidAsCLI == FALSE) &&
1867 (pAd->MacTab.Content[i].ValidAsWDS == FALSE) &&
1868 (pAd->MacTab.Content[i].ValidAsApCli== FALSE) &&
1869 (pAd->MacTab.Content[i].ValidAsMesh == FALSE)
1872 pEntry = &pAd->MacTab.Content[i];
1873 if (CleanAll == TRUE)
1875 pEntry->MaxSupportedRate = RATE_11;
1876 pEntry->CurrTxRate = RATE_11;
1877 NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
1878 pEntry->PairwiseKey.KeyLen = 0;
1879 pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
1883 #ifdef CONFIG_STA_SUPPORT
1884 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1886 pEntry->ValidAsCLI = TRUE;
1887 pEntry->ValidAsWDS = FALSE;
1888 pEntry->ValidAsApCli = FALSE;
1889 pEntry->ValidAsMesh = FALSE;
1890 pEntry->ValidAsDls = FALSE;
1892 #endif // CONFIG_STA_SUPPORT //
1895 pEntry->bIAmBadAtheros = FALSE;
1897 pEntry->CMTimerRunning = FALSE;
1898 pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
1899 pEntry->RSNIE_Len = 0;
1900 NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter));
1901 pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
1903 if (pEntry->ValidAsMesh)
1904 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_MESH);
1905 else if (pEntry->ValidAsApCli)
1906 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_APCLI);
1907 else if (pEntry->ValidAsWDS)
1908 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_WDS);
1910 pEntry->apidx = apidx;
1914 #ifdef CONFIG_STA_SUPPORT
1915 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1917 pEntry->AuthMode = pAd->StaCfg.AuthMode;
1918 pEntry->WepStatus = pAd->StaCfg.WepStatus;
1919 pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1921 #endif // CONFIG_STA_SUPPORT //
1924 pEntry->GTKState = REKEY_NEGOTIATING;
1925 pEntry->PairwiseKey.KeyLen = 0;
1926 pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
1927 pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1928 pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
1929 COPY_MAC_ADDR(pEntry->Addr, pAddr);
1930 pEntry->Sst = SST_NOT_AUTH;
1931 pEntry->AuthState = AS_NOT_AUTH;
1932 pEntry->Aid = (USHORT)i; //0;
1933 pEntry->CapabilityInfo = 0;
1934 pEntry->PsMode = PWR_ACTIVE;
1935 pEntry->PsQIdleCount = 0;
1936 pEntry->NoDataIdleCount = 0;
1937 pEntry->ContinueTxFailCnt = 0;
1938 InitializeQueueHeader(&pEntry->PsQueue);
1941 pAd->MacTab.Size ++;
1943 // Add this entry into ASIC RX WCID search table
1944 RT28XX_STA_ENTRY_ADD(pAd, pEntry);
1948 DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertEntry - allocate entry #%d, Total= %d\n",i, pAd->MacTab.Size));
1953 // add this MAC entry into HASH table
1956 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
1957 if (pAd->MacTab.Hash[HashIdx] == NULL)
1959 pAd->MacTab.Hash[HashIdx] = pEntry;
1963 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1964 while (pCurrEntry->pNext != NULL)
1965 pCurrEntry = pCurrEntry->pNext;
1966 pCurrEntry->pNext = pEntry;
1970 NdisReleaseSpinLock(&pAd->MacTabLock);
1975 ==========================================================================
1977 Delete a specified client from MAC table
1978 ==========================================================================
1980 BOOLEAN MacTableDeleteEntry(
1981 IN PRTMP_ADAPTER pAd,
1986 MAC_TABLE_ENTRY *pEntry, *pPrevEntry, *pProbeEntry;
1988 //USHORT offset; // unused variable
1989 //UCHAR j; // unused variable
1991 if (wcid >= MAX_LEN_OF_MAC_TABLE)
1994 NdisAcquireSpinLock(&pAd->MacTabLock);
1996 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
1997 //pEntry = pAd->MacTab.Hash[HashIdx];
1998 pEntry = &pAd->MacTab.Content[wcid];
2000 if (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsApCli || pEntry->ValidAsWDS || pEntry->ValidAsMesh
2003 if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
2006 // Delete this entry from ASIC on-chip WCID Table
2007 RT28XX_STA_ENTRY_MAC_RESET(pAd, wcid);
2009 #ifdef DOT11_N_SUPPORT
2010 // free resources of BA
2011 BASessionTearDownALL(pAd, pEntry->Aid);
2012 #endif // DOT11_N_SUPPORT //
2016 pProbeEntry = pAd->MacTab.Hash[HashIdx];
2017 ASSERT(pProbeEntry);
2022 if (pProbeEntry == pEntry)
2024 if (pPrevEntry == NULL)
2026 pAd->MacTab.Hash[HashIdx] = pEntry->pNext;
2030 pPrevEntry->pNext = pEntry->pNext;
2035 pPrevEntry = pProbeEntry;
2036 pProbeEntry = pProbeEntry->pNext;
2037 } while (pProbeEntry);
2040 ASSERT(pProbeEntry != NULL);
2042 RT28XX_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid);
2045 if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
2047 RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
2048 pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
2052 NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
2053 pAd->MacTab.Size --;
2054 DBGPRINT(RT_DEBUG_TRACE, ("MacTableDeleteEntry1 - Total= %d\n", pAd->MacTab.Size));
2058 printk("\n%s: Impossible Wcid = %d !!!!!\n", __func__, wcid);
2062 NdisReleaseSpinLock(&pAd->MacTabLock);
2064 //Reset operating mode when no Sta.
2065 if (pAd->MacTab.Size == 0)
2067 #ifdef DOT11_N_SUPPORT
2068 pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0;
2069 #endif // DOT11_N_SUPPORT //
2070 //AsicUpdateProtect(pAd, 0 /*pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode*/, (ALLN_SETPROTECT), TRUE, 0 /*pAd->MacTab.fAnyStationNonGF*/);
2071 RT28XX_UPDATE_PROTECT(pAd); // edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
2079 ==========================================================================
2081 This routine reset the entire MAC table. All packets pending in
2082 the power-saving queues are freed here.
2083 ==========================================================================
2086 IN PRTMP_ADAPTER pAd)
2090 DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n"));
2091 //NdisAcquireSpinLock(&pAd->MacTabLock);
2093 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
2095 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
2098 #ifdef DOT11_N_SUPPORT
2099 // free resources of BA
2100 BASessionTearDownALL(pAd, i);
2101 #endif // DOT11_N_SUPPORT //
2103 pAd->MacTab.Content[i].ValidAsCLI = FALSE;
2108 NdisZeroMemory(pAd->MacTab.Content[i].Addr, 6);
2109 RT28XX_STA_ENTRY_MAC_RESET(pAd, i);
2112 //AsicDelWcidTab(pAd, i);
2120 ==========================================================================
2123 IRQL = DISPATCH_LEVEL
2125 ==========================================================================
2128 IN PRTMP_ADAPTER pAd,
2129 IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq,
2131 IN USHORT CapabilityInfo,
2133 IN USHORT ListenIntv)
2135 COPY_MAC_ADDR(AssocReq->Addr, pAddr);
2136 // Add mask to support 802.11b mode only
2137 AssocReq->CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; // not cf-pollable, not cf-poll-request
2138 AssocReq->Timeout = Timeout;
2139 AssocReq->ListenIntv = ListenIntv;
2144 ==========================================================================
2147 IRQL = DISPATCH_LEVEL
2149 ==========================================================================
2151 VOID DisassocParmFill(
2152 IN PRTMP_ADAPTER pAd,
2153 IN OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq,
2157 COPY_MAC_ADDR(DisassocReq->Addr, pAddr);
2158 DisassocReq->Reason = Reason;
2163 ========================================================================
2165 Routine Description:
2166 Check the out going frame, if this is an DHCP or ARP datagram
2167 will be duplicate another frame at low data rate transmit.
2170 pAd Pointer to our adapter
2171 pPacket Pointer to outgoing Ndis frame
2174 TRUE To be duplicate at Low data rate transmit. (1mb)
2177 IRQL = DISPATCH_LEVEL
2181 MAC header + IP Header + UDP Header
2185 00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|
2187 16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|
2190 port 0x43 means Bootstrap Protocol, server.
2191 Port 0x44 means Bootstrap Protocol, client.
2193 ========================================================================
2196 BOOLEAN RTMPCheckDHCPFrame(
2197 IN PRTMP_ADAPTER pAd,
2198 IN PNDIS_PACKET pPacket)
2200 PACKET_INFO PacketInfo;
2201 ULONG NumberOfBytesRead = 0;
2202 ULONG CurrentOffset = 0;
2203 PVOID pVirtualAddress = NULL;
2204 UINT NdisBufferLength;
2207 UCHAR ByteOffset36 = 0;
2208 UCHAR ByteOffset38 = 0;
2209 BOOLEAN ReadFirstParm = TRUE;
2211 RTMP_QueryPacketInfo(pPacket, &PacketInfo, (PUCHAR *)&pVirtualAddress, &NdisBufferLength);
2213 NumberOfBytesRead += NdisBufferLength;
2214 pSrc = (PUCHAR) pVirtualAddress;
2215 Protocol = *(pSrc + 12) * 256 + *(pSrc + 13);
2218 // Check DHCP & BOOTP protocol
2220 while (NumberOfBytesRead <= PacketInfo.TotalPacketLength)
2222 if ((NumberOfBytesRead >= 35) && (ReadFirstParm == TRUE))
2224 CurrentOffset = 35 - (NumberOfBytesRead - NdisBufferLength);
2225 ByteOffset36 = *(pSrc + CurrentOffset);
2226 ReadFirstParm = FALSE;
2229 if (NumberOfBytesRead >= 37)
2231 CurrentOffset = 37 - (NumberOfBytesRead - NdisBufferLength);
2232 ByteOffset38 = *(pSrc + CurrentOffset);
2239 // Check for DHCP & BOOTP protocol
2240 if ((ByteOffset36 != 0x44) || (ByteOffset38 != 0x43))
2243 // 2054 (hex 0806) for ARP datagrams
2244 // if this packet is not ARP datagrams, then do nothing
2245 // ARP datagrams will also be duplicate at 1mb broadcast frames
2247 if (Protocol != 0x0806 )
2255 BOOLEAN RTMPCheckEtherType(
2256 IN PRTMP_ADAPTER pAd,
2257 IN PNDIS_PACKET pPacket)
2263 UINT16 srcPort, dstPort;
2264 BOOLEAN status = TRUE;
2267 pSrcBuf = GET_OS_PKT_DATAPTR(pPacket);
2268 pktLen = GET_OS_PKT_LEN(pPacket);
2272 RTMP_SET_PACKET_SPECIFIC(pPacket, 0);
2274 // get Ethernet protocol field
2275 TypeLen = (pSrcBuf[12] << 8) + pSrcBuf[13];
2277 pSrcBuf += LENGTH_802_3; // Skip the Ethernet Header.
2279 if (TypeLen <= 1500)
2280 { // 802.3, 802.3 LLC
2282 DestMAC(6) + SrcMAC(6) + Lenght(2) +
2283 DSAP(1) + SSAP(1) + Control(1) +
2284 if the DSAP = 0xAA, SSAP=0xAA, Contorl = 0x03, it has a 5-bytes SNAP header.
2285 => + SNAP (5, OriginationID(3) + etherType(2))
2287 if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA && pSrcBuf[2] == 0x03)
2289 Sniff2BytesFromNdisBuffer(pSrcBuf, 6, &Byte0, &Byte1);
2290 RTMP_SET_PACKET_LLCSNAP(pPacket, 1);
2291 TypeLen = (USHORT)((Byte0 << 8) + Byte1);
2292 pSrcBuf += 8; // Skip this LLC/SNAP header
2296 //It just has 3-byte LLC header, maybe a legacy ether type frame. we didn't handle it.
2300 // If it's a VLAN packet, get the real Type/Length field.
2301 if (TypeLen == 0x8100)
2303 /* 0x8100 means VLAN packets */
2305 /* Dest. MAC Address (6-bytes) +
2306 Source MAC Address (6-bytes) +
2307 Length/Type = 802.1Q Tag Type (2-byte) +
2308 Tag Control Information (2-bytes) +
2309 Length / Type (2-bytes) +
2310 data payload (0-n bytes) +
2312 Frame Check Sequence (4-bytes) */
2314 RTMP_SET_PACKET_VLAN(pPacket, 1);
2315 Sniff2BytesFromNdisBuffer(pSrcBuf, 2, &Byte0, &Byte1);
2316 TypeLen = (USHORT)((Byte0 << 8) + Byte1);
2318 pSrcBuf += 4; // Skip the VLAN Header.
2325 ASSERT((pktLen > 34));
2326 if (*(pSrcBuf + 9) == 0x11)
2328 ASSERT((pktLen > 34)); // 14 for ethernet header, 20 for IP header
2330 pSrcBuf += 20; // Skip the IP header
2331 srcPort = OS_NTOHS(*((UINT16 *)pSrcBuf));
2332 dstPort = OS_NTOHS(*((UINT16 *)(pSrcBuf +2)));
2334 if ((srcPort==0x44 && dstPort==0x43) || (srcPort==0x43 && dstPort==0x44))
2335 { //It's a BOOTP/DHCP packet
2336 RTMP_SET_PACKET_DHCP(pPacket, 1);
2344 RTMP_SET_PACKET_DHCP(pPacket, 1);
2350 RTMP_SET_PACKET_EAPOL(pPacket, 1);
2364 VOID Update_Rssi_Sample(
2365 IN PRTMP_ADAPTER pAd,
2366 IN RSSI_SAMPLE *pRssi,
2367 IN PRXWI_STRUC pRxWI)
2369 CHAR rssi0 = pRxWI->RSSI0;
2370 CHAR rssi1 = pRxWI->RSSI1;
2371 CHAR rssi2 = pRxWI->RSSI2;
2375 pRssi->LastRssi0 = ConvertToRssi(pAd, (CHAR)rssi0, RSSI_0);
2376 pRssi->AvgRssi0X8 = (pRssi->AvgRssi0X8 - pRssi->AvgRssi0) + pRssi->LastRssi0;
2377 pRssi->AvgRssi0 = pRssi->AvgRssi0X8 >> 3;
2382 pRssi->LastRssi1 = ConvertToRssi(pAd, (CHAR)rssi1, RSSI_1);
2383 pRssi->AvgRssi1X8 = (pRssi->AvgRssi1X8 - pRssi->AvgRssi1) + pRssi->LastRssi1;
2384 pRssi->AvgRssi1 = pRssi->AvgRssi1X8 >> 3;
2389 pRssi->LastRssi2 = ConvertToRssi(pAd, (CHAR)rssi2, RSSI_2);
2390 pRssi->AvgRssi2X8 = (pRssi->AvgRssi2X8 - pRssi->AvgRssi2) + pRssi->LastRssi2;
2391 pRssi->AvgRssi2 = pRssi->AvgRssi2X8 >> 3;
2397 // Normal legacy Rx packet indication
2398 VOID Indicate_Legacy_Packet(
2399 IN PRTMP_ADAPTER pAd,
2401 IN UCHAR FromWhichBSSID)
2403 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
2404 UCHAR Header802_3[LENGTH_802_3];
2406 // 1. get 802.3 Header
2408 // a. pointer pRxBlk->pData to payload
2409 // b. modify pRxBlk->DataSize
2410 #ifdef CONFIG_STA_SUPPORT
2411 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2412 RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
2413 #endif // CONFIG_STA_SUPPORT //
2415 if (pRxBlk->DataSize > MAX_RX_PKT_LEN)
2418 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
2423 STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
2426 #ifdef DOT11_N_SUPPORT
2427 if (pAd->CommonCfg.bDisableReordering == 0)
2429 PBA_REC_ENTRY pBAEntry;
2431 UCHAR Wcid = pRxBlk->pRxWI->WirelessCliID;
2432 UCHAR TID = pRxBlk->pRxWI->TID;
2435 #define REORDERING_PACKET_TIMEOUT ((100 * HZ)/1000) // system ticks -- 100 ms
2437 if (Wcid < MAX_LEN_OF_MAC_TABLE)
2439 Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
2442 pBAEntry = &pAd->BATable.BARecEntry[Idx];
2443 // update last rx time
2444 NdisGetSystemUpTime(&Now32);
2445 if ((pBAEntry->list.qlen > 0) &&
2446 RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT)))
2449 printk("Indicate_Legacy_Packet():flush reordering_timeout_mpdus! RxWI->Flags=%d, pRxWI.TID=%d, RxD->AMPDU=%d!\n", pRxBlk->Flags, pRxBlk->pRxWI->TID, pRxBlk->RxD.AMPDU);
2450 hex_dump("Dump the legacy Packet:", GET_OS_PKT_DATAPTR(pRxBlk->pRxPacket), 64);
2451 ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
2456 #endif // DOT11_N_SUPPORT //
2459 wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
2462 // pass this 802.3 packet to upper layer or forward this packet to WM directly
2464 #ifdef CONFIG_STA_SUPPORT
2465 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2466 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxPacket, FromWhichBSSID);
2467 #endif // CONFIG_STA_SUPPORT //
2472 // Normal, AMPDU or AMSDU
2473 VOID CmmRxnonRalinkFrameIndicate(
2474 IN PRTMP_ADAPTER pAd,
2476 IN UCHAR FromWhichBSSID)
2478 #ifdef DOT11_N_SUPPORT
2479 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
2481 Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
2484 #endif // DOT11_N_SUPPORT //
2486 #ifdef DOT11_N_SUPPORT
2487 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
2490 Indicate_AMSDU_Packet(pAd, pRxBlk, FromWhichBSSID);
2493 #endif // DOT11_N_SUPPORT //
2495 Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
2501 VOID CmmRxRalinkFrameIndicate(
2502 IN PRTMP_ADAPTER pAd,
2503 IN MAC_TABLE_ENTRY *pEntry,
2505 IN UCHAR FromWhichBSSID)
2507 UCHAR Header802_3[LENGTH_802_3];
2509 UINT16 Payload1Size, Payload2Size;
2511 PNDIS_PACKET pPacket2 = NULL;
2515 Msdu2Size = *(pRxBlk->pData) + (*(pRxBlk->pData+1) << 8);
2517 if ((Msdu2Size <= 1536) && (Msdu2Size < pRxBlk->DataSize))
2519 /* skip two byte MSDU2 len */
2521 pRxBlk->DataSize -= 2;
2526 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
2530 // get 802.3 Header and remove LLC
2531 #ifdef CONFIG_STA_SUPPORT
2532 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2533 RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
2534 #endif // CONFIG_STA_SUPPORT //
2537 ASSERT(pRxBlk->pRxPacket);
2539 // Ralink Aggregation frame
2540 pAd->RalinkCounters.OneSecRxAggregationCount ++;
2541 Payload1Size = pRxBlk->DataSize - Msdu2Size;
2542 Payload2Size = Msdu2Size - LENGTH_802_3;
2544 pData2 = pRxBlk->pData + Payload1Size + LENGTH_802_3;
2545 #ifdef CONFIG_STA_SUPPORT
2546 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2547 pPacket2 = duplicate_pkt(pAd, (pData2-LENGTH_802_3), LENGTH_802_3, pData2, Payload2Size, FromWhichBSSID);
2548 #endif // CONFIG_STA_SUPPORT //
2553 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
2557 // update payload size of 1st packet
2558 pRxBlk->DataSize = Payload1Size;
2559 wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
2561 #ifdef CONFIG_STA_SUPPORT
2562 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2563 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxBlk->pRxPacket, FromWhichBSSID);
2564 #endif // CONFIG_STA_SUPPORT //
2568 #ifdef CONFIG_STA_SUPPORT
2569 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2570 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket2, FromWhichBSSID);
2571 #endif // CONFIG_STA_SUPPORT //
2576 #define RESET_FRAGFRAME(_fragFrame) \
2578 _fragFrame.RxSize = 0; \
2579 _fragFrame.Sequence = 0; \
2580 _fragFrame.LastFrag = 0; \
2581 _fragFrame.Flags = 0; \
2585 PNDIS_PACKET RTMPDeFragmentDataFrame(
2586 IN PRTMP_ADAPTER pAd,
2589 PHEADER_802_11 pHeader = pRxBlk->pHeader;
2590 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
2591 UCHAR *pData = pRxBlk->pData;
2592 USHORT DataSize = pRxBlk->DataSize;
2593 PNDIS_PACKET pRetPacket = NULL;
2594 UCHAR *pFragBuffer = NULL;
2595 BOOLEAN bReassDone = FALSE;
2596 UCHAR HeaderRoom = 0;
2601 HeaderRoom = pData - (UCHAR *)pHeader;
2603 // Re-assemble the fragmented packets
2604 if (pHeader->Frag == 0) // Frag. Number is 0 : First frag or only one pkt
2606 // the first pkt of fragment, record it.
2607 if (pHeader->FC.MoreFrag)
2609 ASSERT(pAd->FragFrame.pFragPacket);
2610 pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
2611 pAd->FragFrame.RxSize = DataSize + HeaderRoom;
2612 NdisMoveMemory(pFragBuffer, pHeader, pAd->FragFrame.RxSize);
2613 pAd->FragFrame.Sequence = pHeader->Sequence;
2614 pAd->FragFrame.LastFrag = pHeader->Frag; // Should be 0
2615 ASSERT(pAd->FragFrame.LastFrag == 0);
2616 goto done; // end of processing this frame
2619 else //Middle & End of fragment
2621 if ((pHeader->Sequence != pAd->FragFrame.Sequence) ||
2622 (pHeader->Frag != (pAd->FragFrame.LastFrag + 1)))
2624 // Fragment is not the same sequence or out of fragment number order
2625 // Reset Fragment control blk
2626 RESET_FRAGFRAME(pAd->FragFrame);
2627 DBGPRINT(RT_DEBUG_ERROR, ("Fragment is not the same sequence or out of fragment number order.\n"));
2628 goto done; // give up this frame
2630 else if ((pAd->FragFrame.RxSize + DataSize) > MAX_FRAME_SIZE)
2632 // Fragment frame is too large, it exeeds the maximum frame size.
2633 // Reset Fragment control blk
2634 RESET_FRAGFRAME(pAd->FragFrame);
2635 DBGPRINT(RT_DEBUG_ERROR, ("Fragment frame is too large, it exeeds the maximum frame size.\n"));
2636 goto done; // give up this frame
2640 // Broadcom AP(BCM94704AGR) will send out LLC in fragment's packet, LLC only can accpet at first fragment.
2641 // In this case, we will dropt it.
2643 if (NdisEqualMemory(pData, SNAP_802_1H, sizeof(SNAP_802_1H)))
2645 DBGPRINT(RT_DEBUG_ERROR, ("Find another LLC at Middle or End fragment(SN=%d, Frag=%d)\n", pHeader->Sequence, pHeader->Frag));
2646 goto done; // give up this frame
2649 pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
2651 // concatenate this fragment into the re-assembly buffer
2652 NdisMoveMemory((pFragBuffer + pAd->FragFrame.RxSize), pData, DataSize);
2653 pAd->FragFrame.RxSize += DataSize;
2654 pAd->FragFrame.LastFrag = pHeader->Frag; // Update fragment number
2657 if (pHeader->FC.MoreFrag == FALSE)
2664 // always release rx fragmented packet
2665 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
2667 // return defragmented packet if packet is reassembled completely
2668 // otherwise return NULL
2671 PNDIS_PACKET pNewFragPacket;
2673 // allocate a new packet buffer for fragment
2674 pNewFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
2678 pRetPacket = pAd->FragFrame.pFragPacket;
2679 pAd->FragFrame.pFragPacket = pNewFragPacket;
2680 pRxBlk->pHeader = (PHEADER_802_11) GET_OS_PKT_DATAPTR(pRetPacket);
2681 pRxBlk->pData = (UCHAR *)pRxBlk->pHeader + HeaderRoom;
2682 pRxBlk->DataSize = pAd->FragFrame.RxSize - HeaderRoom;
2683 pRxBlk->pRxPacket = pRetPacket;
2687 RESET_FRAGFRAME(pAd->FragFrame);
2695 VOID Indicate_AMSDU_Packet(
2696 IN PRTMP_ADAPTER pAd,
2698 IN UCHAR FromWhichBSSID)
2702 update_os_packet_info(pAd, pRxBlk, FromWhichBSSID);
2703 RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
2704 nMSDU = deaggregate_AMSDU_announce(pAd, pRxBlk->pRxPacket, pRxBlk->pData, pRxBlk->DataSize);
2707 VOID Indicate_EAPOL_Packet(
2708 IN PRTMP_ADAPTER pAd,
2710 IN UCHAR FromWhichBSSID)
2712 MAC_TABLE_ENTRY *pEntry = NULL;
2715 #ifdef CONFIG_STA_SUPPORT
2716 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2718 pEntry = &pAd->MacTab.Content[BSSID_WCID];
2719 STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
2722 #endif // CONFIG_STA_SUPPORT //
2726 DBGPRINT(RT_DEBUG_WARN, ("Indicate_EAPOL_Packet: drop and release the invalid packet.\n"));
2728 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
2733 #define BCN_TBTT_OFFSET 64 //defer 64 us
2734 VOID ReSyncBeaconTime(
2735 IN PRTMP_ADAPTER pAd)
2741 Offset = (pAd->TbttTickCount) % (BCN_TBTT_OFFSET);
2743 pAd->TbttTickCount++;
2746 // The updated BeaconInterval Value will affect Beacon Interval after two TBTT
2747 // beacasue the original BeaconInterval had been loaded into next TBTT_TIMER
2749 if (Offset == (BCN_TBTT_OFFSET-2))
2751 BCN_TIME_CFG_STRUC csr;
2752 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
2753 csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod << 4) - 1 ; // ASIC register in units of 1/16 TU = 64us
2754 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
2758 if (Offset == (BCN_TBTT_OFFSET-1))
2760 BCN_TIME_CFG_STRUC csr;
2762 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
2763 csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod) << 4; // ASIC register in units of 1/16 TU
2764 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);