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));
180 ========================================================================
183 Copy frame from waiting queue into relative ring buffer and set
184 appropriate ASIC register to kick hardware transmit function
187 pAd Pointer to our adapter
188 pBuffer Pointer to memory of outgoing frame
189 Length Size of outgoing management frame
197 IRQL = DISPATCH_LEVEL
201 ========================================================================
203 NDIS_STATUS MlmeHardTransmit(
204 IN PRTMP_ADAPTER pAd,
206 IN PNDIS_PACKET pPacket)
208 if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
209 #ifdef CARRIER_DETECTION_SUPPORT
210 #endif // CARRIER_DETECTION_SUPPORT //
213 return NDIS_STATUS_FAILURE;
216 return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
222 NDIS_STATUS MlmeHardTransmitMgmtRing(
223 IN PRTMP_ADAPTER pAd,
225 IN PNDIS_PACKET pPacket)
227 PACKET_INFO PacketInfo;
230 PHEADER_802_11 pHeader_802_11;
231 BOOLEAN bAckRequired, bInsertTimestamp;
233 PTXWI_STRUC pFirstTxWI;
234 MAC_TABLE_ENTRY *pMacEntry = NULL;
236 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
238 // Make sure MGMT ring resource won't be used by other threads
239 // sample, for IRQ LOCK -> SEM LOCK
240 // IrqState = pAd->irq_disabled;
242 RTMP_SEM_LOCK(&pAd->MgmtRingLock);
245 if (pSrcBufVA == NULL)
247 // The buffer shouldn't be NULL
249 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
250 return NDIS_STATUS_FAILURE;
253 #ifdef CONFIG_STA_SUPPORT
254 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
256 // outgoing frame always wakeup PHY to prevent frame lost
257 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
258 AsicForceWakeup(pAd, TRUE);
260 #endif // CONFIG_STA_SUPPORT //
262 pFirstTxWI = (PTXWI_STRUC)(pSrcBufVA + TXINFO_SIZE);
263 pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); //TXWI_SIZE);
265 if (pHeader_802_11->Addr1[0] & 0x01)
267 MlmeRate = pAd->CommonCfg.BasicMlmeRate;
271 MlmeRate = pAd->CommonCfg.MlmeRate;
274 // Verify Mlme rate for a / g bands.
275 if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band
278 if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
279 (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))
281 pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
284 #ifdef CONFIG_STA_SUPPORT
285 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
287 // Fixed W52 with Activity scan issue in ABG_MIXED and ABGN_MIXED mode.
288 if (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED
289 #ifdef DOT11_N_SUPPORT
290 || pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED
291 #endif // DOT11_N_SUPPORT //
294 if (pAd->LatchRfRegs.Channel > 14)
295 pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
297 pAd->CommonCfg.MlmeTransmit.field.MODE = 0;
300 #endif // CONFIG_STA_SUPPORT //
303 // Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)
304 // Snice it's been set to 0 while on MgtMacHeaderInit
305 // By the way this will cause frame to be send on PWR_SAVE failed.
307 // pHeader_802_11->FC.PwrMgmt = 0; // (pAd->StaCfg.Psm == PWR_SAVE);
309 // In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
310 #ifdef CONFIG_STA_SUPPORT
311 // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
312 if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL))
314 if ((pAd->StaCfg.Psm == PWR_SAVE) &&
315 (pHeader_802_11->FC.SubType == SUBTYPE_ACTION))
316 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
318 pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
320 #endif // CONFIG_STA_SUPPORT //
322 bInsertTimestamp = FALSE;
323 if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
325 #ifdef CONFIG_STA_SUPPORT
326 //Set PM bit in ps-poll, to fix WLK 1.2 PowerSaveMode_ext failure issue.
327 if ((pAd->OpMode == OPMODE_STA) && (pHeader_802_11->FC.SubType == SUBTYPE_PS_POLL))
329 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
331 #endif // CONFIG_STA_SUPPORT //
332 bAckRequired = FALSE;
334 else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
337 //pHeader_802_11->Sequence = pAd->Sequence;
339 if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
341 bAckRequired = FALSE;
342 pHeader_802_11->Duration = 0;
347 pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
348 if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
350 bInsertTimestamp = TRUE;
355 pHeader_802_11->Sequence = pAd->Sequence++;
356 if (pAd->Sequence >0xfff)
359 // Before radar detection done, mgmt frame can not be sent but probe req
360 // Because we need to use probe req to trigger driver to send probe req in passive scan
361 if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
362 && (pAd->CommonCfg.bIEEE80211H == 1)
363 && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
365 DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
367 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
368 return (NDIS_STATUS_FAILURE);
372 RTMPFrameEndianChange(pAd, (PUCHAR)pHeader_802_11, DIR_WRITE, FALSE);
376 // fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
377 // should always has only one ohysical buffer, and the whole frame size equals
378 // to the first scatter buffer size
381 // Initialize TX Descriptor
382 // For inter-frame gap, the number is for this frame and next frame
383 // For MLME rate, we will fix as 2Mb to match other vendor's implement
384 // pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
386 // management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
387 if (pMacEntry == NULL)
389 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
390 0, RESERVED_WCID, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID_MGMT, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
394 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
395 bInsertTimestamp, FALSE, bAckRequired, FALSE,
396 0, pMacEntry->Aid, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE),
397 pMacEntry->MaxHTPhyMode.field.MCS, 0,
398 (UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
399 IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
403 RTMPWIEndianChange((PUCHAR)pFirstTxWI, TYPE_TXWI);
406 // Now do hardware-depened kick out.
407 HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen);
409 // Make sure to release MGMT ring resource
411 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
412 return NDIS_STATUS_SUCCESS;
416 /********************************************************************************
418 New DeQueue Procedures.
420 ********************************************************************************/
422 #define DEQUEUE_LOCK(lock, bIntContext, IrqFlags) \
424 if (bIntContext == FALSE) \
425 RTMP_IRQ_LOCK((lock), IrqFlags); \
428 #define DEQUEUE_UNLOCK(lock, bIntContext, IrqFlags) \
430 if (bIntContext == FALSE) \
431 RTMP_IRQ_UNLOCK((lock), IrqFlags); \
436 static VOID dumpTxBlk(TX_BLK *pTxBlk)
438 NDIS_PACKET *pPacket;
440 PQUEUE_ENTRY pQEntry;
442 printk("Dump TX_BLK Structure:\n");
443 printk("\tTxFrameType=%d!\n", pTxBlk->TxFrameType);
444 printk("\tTotalFrameLen=%d\n", pTxBlk->TotalFrameLen);
445 printk("\tTotalFrameNum=%ld!\n", pTxBlk->TxPacketList.Number);
446 printk("\tTotalFragNum=%d!\n", pTxBlk->TotalFragNum);
447 printk("\tpPacketList=\n");
449 frameNum = pTxBlk->TxPacketList.Number;
451 for(i=0; i < frameNum; i++)
455 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
456 pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
459 pBuf = GET_OS_PKT_DATAPTR(pPacket);
460 printk("\t\t[%d]:ptr=0x%x, Len=%d!\n", i, (UINT32)(GET_OS_PKT_DATAPTR(pPacket)), GET_OS_PKT_LEN(pPacket));
462 for (j =0 ; j < GET_OS_PKT_LEN(pPacket); j++)
464 printk("%02x ", (pBuf[j] & 0xff));
468 InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
471 printk("\tWcid=%d!\n", pTxBlk->Wcid);
472 printk("\tapidx=%d!\n", pTxBlk->apidx);
473 printk("----EndOfDump\n");
480 ========================================================================
481 Tx Path design algorithm:
482 Basically, we divide the packets into four types, Broadcast/Multicast, 11N Rate(AMPDU, AMSDU, Normal), B/G Rate(ARALINK, Normal),
483 Specific Packet Type. Following show the classification rule and policy for each kinds of packets.
484 Classification Rule=>
485 Multicast: (*addr1 & 0x01) == 0x01
486 Specific : bDHCPFrame, bARPFrame, bEAPOLFrame, etc.
487 11N Rate : If peer support HT
488 (1).AMPDU -- If TXBA is negotiated.
489 (2).AMSDU -- If AMSDU is capable for both peer and ourself.
490 *). AMSDU can embedded in a AMPDU, but now we didn't support it.
491 (3).Normal -- Other packets which send as 11n rate.
493 B/G Rate : If peer is b/g only.
494 (1).ARALINK-- If both of peer/us supprot Ralink proprietary Aggregation and the TxRate is large than RATE_6
495 (2).Normal -- Other packets which send as b/g rate.
497 The packet must be unicast, NOT A-RALINK, NOT A-MSDU, NOT 11n, then can consider about fragment.
499 Classified Packet Handle Rule=>
501 No ACK, //pTxBlk->bAckRequired = FALSE;
502 No WMM, //pTxBlk->bWMM = FALSE;
503 No piggyback, //pTxBlk->bPiggyBack = FALSE;
504 Force LowRate, //pTxBlk->bForceLowRate = TRUE;
505 Specific : Basically, for specific packet, we should handle it specifically, but now all specific packets are use
506 the same policy to handle it.
507 Force LowRate, //pTxBlk->bForceLowRate = TRUE;
510 No piggyback, //pTxBlk->bPiggyBack = FALSE;
522 ========================================================================
524 static UCHAR TxPktClassification(
525 IN RTMP_ADAPTER *pAd,
526 IN PNDIS_PACKET pPacket)
528 UCHAR TxFrameType = TX_UNKOWN_FRAME;
530 MAC_TABLE_ENTRY *pMacEntry = NULL;
531 #ifdef DOT11_N_SUPPORT
532 BOOLEAN bHTRate = FALSE;
533 #endif // DOT11_N_SUPPORT //
535 Wcid = RTMP_GET_PACKET_WCID(pPacket);
536 if (Wcid == MCAST_WCID)
537 { // Handle for RA is Broadcast/Multicast Address.
538 return TX_MCAST_FRAME;
541 // Handle for unicast packets
542 pMacEntry = &pAd->MacTab.Content[Wcid];
543 if (RTMP_GET_PACKET_LOWRATE(pPacket))
544 { // It's a specific packet need to force low rate, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame
545 TxFrameType = TX_LEGACY_FRAME;
547 #ifdef DOT11_N_SUPPORT
548 else if (IS_HT_RATE(pMacEntry))
549 { // it's a 11n capable packet
551 // Depends on HTPhyMode to check if the peer support the HTRate transmission.
552 // Currently didn't support A-MSDU embedded in A-MPDU
554 if (RTMP_GET_PACKET_MOREDATA(pPacket) || (pMacEntry->PsMode == PWR_SAVE))
555 TxFrameType = TX_LEGACY_FRAME;
556 #ifdef UAPSD_AP_SUPPORT
557 else if (RTMP_GET_PACKET_EOSP(pPacket))
558 TxFrameType = TX_LEGACY_FRAME;
559 #endif // UAPSD_AP_SUPPORT //
560 else if((pMacEntry->TXBAbitmap & (1<<(RTMP_GET_PACKET_UP(pPacket)))) != 0)
561 return TX_AMPDU_FRAME;
562 else if(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AMSDU_INUSED))
563 return TX_AMSDU_FRAME;
565 TxFrameType = TX_LEGACY_FRAME;
567 #endif // DOT11_N_SUPPORT //
569 { // it's a legacy b/g packet.
570 if ((CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE) && pAd->CommonCfg.bAggregationCapable) &&
571 (RTMP_GET_PACKET_TXRATE(pPacket) >= RATE_6) &&
572 (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
573 { // if peer support Ralink Aggregation, we use it.
574 TxFrameType = TX_RALINK_FRAME;
578 TxFrameType = TX_LEGACY_FRAME;
582 // Currently, our fragment only support when a unicast packet send as NOT-ARALINK, NOT-AMSDU and NOT-AMPDU.
583 if ((RTMP_GET_PACKET_FRAGMENTS(pPacket) > 1) && (TxFrameType == TX_LEGACY_FRAME))
584 TxFrameType = TX_FRAG_FRAME;
590 BOOLEAN RTMP_FillTxBlkInfo(
591 IN RTMP_ADAPTER *pAd,
594 PACKET_INFO PacketInfo;
595 PNDIS_PACKET pPacket;
596 PMAC_TABLE_ENTRY pMacEntry = NULL;
598 pPacket = pTxBlk->pPacket;
599 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen);
601 pTxBlk->Wcid = RTMP_GET_PACKET_WCID(pPacket);
602 pTxBlk->apidx = RTMP_GET_PACKET_IF(pPacket);
603 pTxBlk->UserPriority = RTMP_GET_PACKET_UP(pPacket);
604 pTxBlk->FrameGap = IFS_HTTXOP; // ASIC determine Frame Gap
606 if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pTxBlk->pPacket))
607 TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame);
609 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bClearEAPFrame);
611 // Default to clear this flag
612 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bForceNonQoS);
615 if (pTxBlk->Wcid == MCAST_WCID)
617 pTxBlk->pMacEntry = NULL;
619 #ifdef MCAST_RATE_SPECIFIC
620 PUCHAR pDA = GET_OS_PKT_DATAPTR(pPacket);
621 if (((*pDA & 0x01) == 0x01) && (*pDA != 0xff))
622 pTxBlk->pTransmit = &pAd->CommonCfg.MCastPhyMode;
624 #endif // MCAST_RATE_SPECIFIC //
625 pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
628 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); // AckRequired = FALSE, when broadcast packet in Adhoc mode.
629 //TX_BLK_SET_FLAG(pTxBlk, fTX_bForceLowRate);
630 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAllowFrag);
631 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
632 if (RTMP_GET_PACKET_MOREDATA(pPacket))
634 TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
640 pTxBlk->pMacEntry = &pAd->MacTab.Content[pTxBlk->Wcid];
641 pTxBlk->pTransmit = &pTxBlk->pMacEntry->HTPhyMode;
643 pMacEntry = pTxBlk->pMacEntry;
646 // For all unicast packets, need Ack unless the Ack Policy is not set as NORMAL_ACK.
647 if (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx] != NORMAL_ACK)
648 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);
650 TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired);
654 #ifdef CONFIG_STA_SUPPORT
655 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
658 // If support WMM, enable it.
659 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
660 CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))
661 TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM);
663 #endif // CONFIG_STA_SUPPORT //
666 if (pTxBlk->TxFrameType == TX_LEGACY_FRAME)
668 if ( (RTMP_GET_PACKET_LOWRATE(pPacket)) ||
669 ((pAd->OpMode == OPMODE_AP) && (pMacEntry->MaxHTPhyMode.field.MODE == MODE_CCK) && (pMacEntry->MaxHTPhyMode.field.MCS == RATE_1)))
670 { // Specific packet, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame, need force low rate.
671 pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
672 #ifdef DOT11_N_SUPPORT
673 // Modify the WMM bit for ICV issue. If we have a packet with EOSP field need to set as 1, how to handle it???
674 if (IS_HT_STA(pTxBlk->pMacEntry) &&
675 (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RALINK_CHIPSET)) &&
676 ((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RDG_CAPABLE)))
678 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
679 TX_BLK_SET_FLAG(pTxBlk, fTX_bForceNonQoS);
681 #endif // DOT11_N_SUPPORT //
684 #ifdef DOT11_N_SUPPORT
685 if ( (IS_HT_RATE(pMacEntry) == FALSE) &&
686 (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE)))
687 { // Currently piggy-back only support when peer is operate in b/g mode.
688 TX_BLK_SET_FLAG(pTxBlk, fTX_bPiggyBack);
690 #endif // DOT11_N_SUPPORT //
692 if (RTMP_GET_PACKET_MOREDATA(pPacket))
694 TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
696 #ifdef UAPSD_AP_SUPPORT
697 if (RTMP_GET_PACKET_EOSP(pPacket))
699 TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP);
701 #endif // UAPSD_AP_SUPPORT //
703 else if (pTxBlk->TxFrameType == TX_FRAG_FRAME)
705 TX_BLK_SET_FLAG(pTxBlk, fTX_bAllowFrag);
708 pMacEntry->DebugTxCount++;
715 BOOLEAN CanDoAggregateTransmit(
716 IN RTMP_ADAPTER *pAd,
717 IN NDIS_PACKET *pPacket,
721 //printk("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType);
723 if (RTMP_GET_PACKET_WCID(pPacket) == MCAST_WCID)
726 if (RTMP_GET_PACKET_DHCP(pPacket) ||
727 RTMP_GET_PACKET_EAPOL(pPacket) ||
728 RTMP_GET_PACKET_WAI(pPacket))
731 if ((pTxBlk->TxFrameType == TX_AMSDU_FRAME) &&
732 ((pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))> (RX_BUFFER_AGGRESIZE - 100)))
733 { // For AMSDU, allow the packets with total length < max-amsdu size
737 if ((pTxBlk->TxFrameType == TX_RALINK_FRAME) &&
738 (pTxBlk->TxPacketList.Number == 2))
739 { // For RALINK-Aggregation, allow two frames in one batch.
743 #ifdef CONFIG_STA_SUPPORT
744 if ((INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) // must be unicast to AP
747 #endif // CONFIG_STA_SUPPORT //
754 ========================================================================
757 To do the enqueue operation and extract the first item of waiting
758 list. If a number of available shared memory segments could meet
759 the request of extracted item, the extracted item will be fragmented
760 into shared memory segments.
763 pAd Pointer to our adapter
764 pQueue Pointer to Waiting Queue
769 IRQL = DISPATCH_LEVEL
773 ========================================================================
775 VOID RTMPDeQueuePacket(
776 IN PRTMP_ADAPTER pAd,
777 IN BOOLEAN bIntContext,
778 IN UCHAR QIdx, /* BulkOutPipeId */
779 IN UCHAR Max_Tx_Packets)
781 PQUEUE_ENTRY pEntry = NULL;
782 PNDIS_PACKET pPacket;
783 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
785 PQUEUE_HEADER pQueue;
786 ULONG FreeNumber[NUM_OF_TX_RING];
787 UCHAR QueIdx, sQIdx, eQIdx;
788 unsigned long IrqFlags = 0;
789 BOOLEAN hasTxDesc = FALSE;
795 RtmpDiagStruct *pDiagStruct = &pAd->DiagStruct;
799 if (QIdx == NUM_OF_TX_RING)
802 eQIdx = 3; // 4 ACs, start from 0.
806 sQIdx = eQIdx = QIdx;
809 for (QueIdx=sQIdx; QueIdx <= eQIdx; QueIdx++)
813 RT28XX_START_DEQUEUE(pAd, QueIdx, IrqFlags);
816 firstRound = ((QueIdx == 0) ? TRUE : FALSE);
817 #endif // DBG_DIAGNOSE //
821 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS |
822 fRTMP_ADAPTER_RADIO_OFF |
823 fRTMP_ADAPTER_RESET_IN_PROGRESS |
824 fRTMP_ADAPTER_HALT_IN_PROGRESS |
825 fRTMP_ADAPTER_NIC_NOT_EXIST))))
827 RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
831 if (Count >= Max_Tx_Packets)
834 DEQUEUE_LOCK(&pAd->irq_lock, bIntContext, IrqFlags);
835 if (&pAd->TxSwQueue[QueIdx] == NULL)
838 if (firstRound == TRUE)
839 pDiagStruct->TxSWQueCnt[pDiagStruct->ArrayCurIdx][0]++;
840 #endif // DBG_DIAGNOSE //
841 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
846 // probe the Queue Head
847 pQueue = &pAd->TxSwQueue[QueIdx];
848 if ((pEntry = pQueue->Head) == NULL)
850 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
855 NdisZeroMemory((PUCHAR)pTxBlk, sizeof(TX_BLK));
856 //InitializeQueueHeader(&pTxBlk->TxPacketList); // Didn't need it because we already memzero it.
857 pTxBlk->QueIdx = QueIdx;
859 pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
861 // Early check to make sure we have enoguh Tx Resource.
862 hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
865 pAd->PrivateInfo.TxRingFullCnt++;
867 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
872 pTxBlk->TxFrameType = TxPktClassification(pAd, pPacket);
873 pEntry = RemoveHeadQueue(pQueue);
874 pTxBlk->TotalFrameNum++;
875 pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); // The real fragment number maybe vary
876 pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
877 pTxBlk->pPacket = pPacket;
878 InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
880 if (pTxBlk->TxFrameType == TX_RALINK_FRAME || pTxBlk->TxFrameType == TX_AMSDU_FRAME)
882 // Enhance SW Aggregation Mechanism
883 if (NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, FreeNumber[QueIdx], pTxBlk->TxFrameType))
885 InsertHeadQueue(pQueue, PACKET_TO_QUEUE_ENTRY(pPacket));
886 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
891 if((pEntry = pQueue->Head) == NULL)
894 // For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation.
895 pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
896 FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
897 hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
898 if ((hasTxDesc == FALSE) || (CanDoAggregateTransmit(pAd, pPacket, pTxBlk) == FALSE))
901 //Remove the packet from the TxSwQueue and insert into pTxBlk
902 pEntry = RemoveHeadQueue(pQueue);
904 pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
905 pTxBlk->TotalFrameNum++;
906 pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); // The real fragment number maybe vary
907 pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
908 InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
911 if (pTxBlk->TxPacketList.Number == 1)
912 pTxBlk->TxFrameType = TX_LEGACY_FRAME;
916 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
919 Count += pTxBlk->TxPacketList.Number;
921 // Do HardTransmit now.
922 #ifdef CONFIG_STA_SUPPORT
923 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
924 Status = STAHardTransmit(pAd, pTxBlk, QueIdx);
925 #endif // CONFIG_STA_SUPPORT //
928 #if 0 // We should not break if HardTransmit failed. Well, at least now we should not!
929 if (Status != NDIS_STATUS_SUCCESS)
931 DBGPRINT(RT_DEBUG_TRACE /*RT_DEBUG_INFO*/,("RTMPHardTransmit return failed!!!\n"));
937 RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
941 RTUSBKickBulkOut(pAd);
949 ========================================================================
952 Calculates the duration which is required to transmit out frames
953 with given size and specified rate.
956 pAd Pointer to our adapter
958 Size Frame size in units of byte
961 Duration number in units of usec
964 IRQL = DISPATCH_LEVEL
968 ========================================================================
970 USHORT RTMPCalcDuration(
971 IN PRTMP_ADAPTER pAd,
977 if (Rate < RATE_FIRST_OFDM_RATE) // CCK
979 if ((Rate > RATE_1) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED))
980 Duration = 96; // 72+24 preamble+plcp
982 Duration = 192; // 144+48 preamble+plcp
984 Duration += (USHORT)((Size << 4) / RateIdTo500Kbps[Rate]);
985 if ((Size << 4) % RateIdTo500Kbps[Rate])
988 else if (Rate <= RATE_LAST_OFDM_RATE)// OFDM rates
990 Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension
991 Duration += 4 * (USHORT)((11 + Size * 4) / RateIdTo500Kbps[Rate]);
992 if ((11 + Size * 4) % RateIdTo500Kbps[Rate])
997 Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension
1000 return (USHORT)Duration;
1005 ========================================================================
1007 Routine Description:
1008 Calculates the duration which is required to transmit out frames
1009 with given size and specified rate.
1012 pTxWI Pointer to head of each MPDU to HW.
1013 Ack Setting for Ack requirement bit
1014 Fragment Setting for Fragment bit
1015 RetryMode Setting for retry mode
1016 Ifs Setting for IFS gap
1017 Rate Setting for transmit rate
1018 Service Setting for service
1020 TxPreamble Short or Long preamble when using CCK rates
1021 QueIdx - 0-3, according to 802.11e/d4.4 June/2003
1026 IRQL = PASSIVE_LEVEL
1027 IRQL = DISPATCH_LEVEL
1029 See also : BASmartHardTransmit() !!!
1031 ========================================================================
1034 IN PRTMP_ADAPTER pAd,
1035 IN PTXWI_STRUC pOutTxWI,
1038 IN BOOLEAN InsTimestamp,
1041 IN BOOLEAN NSeq, // HW new a sequence.
1050 IN HTTRANSMIT_SETTING *pTransmit)
1052 PMAC_TABLE_ENTRY pMac = NULL;
1056 if (WCID < MAX_LEN_OF_MAC_TABLE)
1057 pMac = &pAd->MacTab.Content[WCID];
1060 // Always use Long preamble before verifiation short preamble functionality works well.
1061 // Todo: remove the following line if short preamble functionality works
1063 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1064 NdisZeroMemory(&TxWI, TXWI_SIZE);
1069 pTxWI->CFACK = CFACK;
1070 pTxWI->TS= InsTimestamp;
1071 pTxWI->AMPDU = AMPDU;
1073 pTxWI->txop= Txopmode;
1076 // John tune the performace with Intel Client in 20 MHz performance
1077 #ifdef DOT11_N_SUPPORT
1078 BASize = pAd->CommonCfg.TxBASize;
1082 pTxWI->BAWinSize = BASize;
1083 pTxWI->ShortGI = pTransmit->field.ShortGI;
1084 pTxWI->STBC = pTransmit->field.STBC;
1085 #endif // DOT11_N_SUPPORT //
1087 pTxWI->WirelessCliID = WCID;
1088 pTxWI->MPDUtotalByteCount = Length;
1089 pTxWI->PacketId = PID;
1091 // If CCK or OFDM, BW must be 20
1092 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1093 #ifdef DOT11N_DRAFT3
1095 pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
1096 #endif // DOT11N_DRAFT3 //
1098 pTxWI->MCS = pTransmit->field.MCS;
1099 pTxWI->PHYMODE = pTransmit->field.MODE;
1100 pTxWI->CFACK = CfAck;
1102 #ifdef DOT11_N_SUPPORT
1105 if (pAd->CommonCfg.bMIMOPSEnable)
1107 if ((pMac->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1109 // Dynamic MIMO Power Save Mode
1112 else if (pMac->MmpsMode == MMPS_STATIC)
1114 // Static MIMO Power Save Mode
1115 if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
1122 //pTxWI->MIMOps = (pMac->PsMode == PWR_MMPS)? 1:0;
1123 if (pMac->bIAmBadAtheros && (pMac->WepStatus != Ndis802_11WEPDisabled))
1125 pTxWI->MpduDensity = 7;
1129 pTxWI->MpduDensity = pMac->MpduDensity;
1132 #endif // DOT11_N_SUPPORT //
1134 pTxWI->PacketId = pTxWI->MCS;
1135 NdisMoveMemory(pOutTxWI, &TxWI, sizeof(TXWI_STRUC));
1139 VOID RTMPWriteTxWI_Data(
1140 IN PRTMP_ADAPTER pAd,
1141 IN OUT PTXWI_STRUC pTxWI,
1144 HTTRANSMIT_SETTING *pTransmit;
1145 PMAC_TABLE_ENTRY pMacEntry;
1146 #ifdef DOT11_N_SUPPORT
1148 #endif // DOT11_N_SUPPORT //
1153 pTransmit = pTxBlk->pTransmit;
1154 pMacEntry = pTxBlk->pMacEntry;
1158 // Always use Long preamble before verifiation short preamble functionality works well.
1159 // Todo: remove the following line if short preamble functionality works
1161 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1162 NdisZeroMemory(pTxWI, TXWI_SIZE);
1164 pTxWI->FRAG = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag);
1165 pTxWI->ACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAckRequired);
1166 pTxWI->txop = pTxBlk->FrameGap;
1168 #ifdef CONFIG_STA_SUPPORT
1169 #ifdef QOS_DLS_SUPPORT
1171 (pAd->StaCfg.BssType == BSS_INFRA) &&
1172 (pMacEntry->ValidAsDls == TRUE))
1173 pTxWI->WirelessCliID = BSSID_WCID;
1175 #endif // QOS_DLS_SUPPORT //
1176 #endif // CONFIG_STA_SUPPORT //
1177 pTxWI->WirelessCliID = pTxBlk->Wcid;
1179 pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
1180 pTxWI->CFACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bPiggyBack);
1182 // If CCK or OFDM, BW must be 20
1183 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1184 #ifdef DOT11_N_SUPPORT
1185 #ifdef DOT11N_DRAFT3
1187 pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
1188 #endif // DOT11N_DRAFT3 //
1189 pTxWI->AMPDU = ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) ? TRUE : FALSE);
1191 // John tune the performace with Intel Client in 20 MHz performance
1192 BASize = pAd->CommonCfg.TxBASize;
1193 if((pTxBlk->TxFrameType == TX_AMPDU_FRAME) && (pMacEntry))
1195 UCHAR RABAOriIdx = 0; //The RA's BA Originator table index.
1197 RABAOriIdx = pTxBlk->pMacEntry->BAOriWcidArray[pTxBlk->UserPriority];
1198 BASize = pAd->BATable.BAOriEntry[RABAOriIdx].BAWinSize;
1206 pTxWI->TxBF = pTransmit->field.TxBF;
1207 pTxWI->BAWinSize = BASize;
1208 pTxWI->ShortGI = pTransmit->field.ShortGI;
1209 pTxWI->STBC = pTransmit->field.STBC;
1210 #endif // DOT11_N_SUPPORT //
1212 pTxWI->MCS = pTransmit->field.MCS;
1213 pTxWI->PHYMODE = pTransmit->field.MODE;
1215 #ifdef DOT11_N_SUPPORT
1218 if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1220 // Dynamic MIMO Power Save Mode
1223 else if (pMacEntry->MmpsMode == MMPS_STATIC)
1225 // Static MIMO Power Save Mode
1226 if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
1233 if (pMacEntry->bIAmBadAtheros && (pMacEntry->WepStatus != Ndis802_11WEPDisabled))
1235 pTxWI->MpduDensity = 7;
1239 pTxWI->MpduDensity = pMacEntry->MpduDensity;
1242 #endif // DOT11_N_SUPPORT //
1245 if (pTxBlk->QueIdx== 0)
1247 pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
1248 pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
1250 #endif // DBG_DIAGNOSE //
1252 // for rate adapation
1253 pTxWI->PacketId = pTxWI->MCS;
1257 VOID RTMPWriteTxWI_Cache(
1258 IN PRTMP_ADAPTER pAd,
1259 IN OUT PTXWI_STRUC pTxWI,
1262 PHTTRANSMIT_SETTING /*pTxHTPhyMode,*/ pTransmit;
1263 PMAC_TABLE_ENTRY pMacEntry;
1268 pMacEntry = pTxBlk->pMacEntry;
1269 pTransmit = pTxBlk->pTransmit;
1271 if (pMacEntry->bAutoTxRateSwitch)
1273 pTxWI->txop = IFS_HTTXOP;
1275 // If CCK or OFDM, BW must be 20
1276 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1277 pTxWI->ShortGI = pTransmit->field.ShortGI;
1278 pTxWI->STBC = pTransmit->field.STBC;
1280 pTxWI->MCS = pTransmit->field.MCS;
1281 pTxWI->PHYMODE = pTransmit->field.MODE;
1283 // set PID for TxRateSwitching
1284 pTxWI->PacketId = pTransmit->field.MCS;
1287 #ifdef DOT11_N_SUPPORT
1288 pTxWI->AMPDU = ((pMacEntry->NoBADataCountDown == 0) ? TRUE: FALSE);
1291 #ifdef DOT11N_DRAFT3
1293 pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
1294 #endif // DOT11N_DRAFT3 //
1296 if (pAd->CommonCfg.bMIMOPSEnable)
1298 // MIMO Power Save Mode
1299 if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1301 // Dynamic MIMO Power Save Mode
1304 else if (pMacEntry->MmpsMode == MMPS_STATIC)
1306 // Static MIMO Power Save Mode
1307 if ((pTransmit->field.MODE >= MODE_HTMIX) && (pTransmit->field.MCS > 7))
1314 #endif // DOT11_N_SUPPORT //
1317 if (pTxBlk->QueIdx== 0)
1319 pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
1320 pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
1322 #endif // DBG_DIAGNOSE //
1324 pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
1330 ========================================================================
1332 Routine Description:
1333 Calculates the duration which is required to transmit out frames
1334 with given size and specified rate.
1337 pTxD Pointer to transmit descriptor
1338 Ack Setting for Ack requirement bit
1339 Fragment Setting for Fragment bit
1340 RetryMode Setting for retry mode
1341 Ifs Setting for IFS gap
1342 Rate Setting for transmit rate
1343 Service Setting for service
1345 TxPreamble Short or Long preamble when using CCK rates
1346 QueIdx - 0-3, according to 802.11e/d4.4 June/2003
1351 IRQL = PASSIVE_LEVEL
1352 IRQL = DISPATCH_LEVEL
1354 ========================================================================
1356 VOID RTMPWriteTxDescriptor(
1357 IN PRTMP_ADAPTER pAd,
1363 // Always use Long preamble before verifiation short preamble functionality works well.
1364 // Todo: remove the following line if short preamble functionality works
1366 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1368 pTxD->WIV = (bWIV) ? 1: 0;
1369 pTxD->QSEL= (QueueSEL);
1370 //RT2860c?? fixed using EDCA queue for test... We doubt Queue1 has problem. 2006-09-26 Jan
1371 //pTxD->QSEL= FIFO_EDCA;
1372 if (pAd->bGenOneHCCA == TRUE)
1373 pTxD->QSEL= FIFO_HCCA;
1378 // should be called only when -
1379 // 1. MEADIA_CONNECTED
1380 // 2. AGGREGATION_IN_USED
1381 // 3. Fragmentation not in used
1382 // 4. either no previous frame (pPrevAddr1=NULL) .OR. previoud frame is aggregatible
1383 BOOLEAN TxFrameIsAggregatible(
1384 IN PRTMP_ADAPTER pAd,
1385 IN PUCHAR pPrevAddr1,
1389 // can't aggregate EAPOL (802.1x) frame
1390 if ((p8023hdr[12] == 0x88) && (p8023hdr[13] == 0x8e))
1393 // can't aggregate multicast/broadcast frame
1394 if (p8023hdr[0] & 0x01)
1397 if (INFRA_ON(pAd)) // must be unicast to AP
1399 else if ((pPrevAddr1 == NULL) || MAC_ADDR_EQUAL(pPrevAddr1, p8023hdr)) // unicast to same STA
1407 ========================================================================
1409 Routine Description:
1410 Check the MSDU Aggregation policy
1411 1.HT aggregation is A-MSDU
1412 2.legaacy rate aggregation is software aggregation by Ralink.
1420 ========================================================================
1422 BOOLEAN PeerIsAggreOn(
1423 IN PRTMP_ADAPTER pAd,
1425 IN PMAC_TABLE_ENTRY pMacEntry)
1427 ULONG AFlags = (fCLIENT_STATUS_AMSDU_INUSED | fCLIENT_STATUS_AGGREGATION_CAPABLE);
1429 if (pMacEntry != NULL && CLIENT_STATUS_TEST_FLAG(pMacEntry, AFlags))
1431 #ifdef DOT11_N_SUPPORT
1432 if (pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
1436 #endif // DOT11_N_SUPPORT //
1438 #ifdef AGGREGATION_SUPPORT
1439 if (TxRate >= RATE_6 && pAd->CommonCfg.bAggregationCapable && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
1440 { // legacy Ralink Aggregation support
1443 #endif // AGGREGATION_SUPPORT //
1451 ========================================================================
1453 Routine Description:
1454 Check and fine the packet waiting in SW queue with highest priority
1457 pAd Pointer to our adapter
1460 pQueue Pointer to Waiting Queue
1462 IRQL = DISPATCH_LEVEL
1466 ========================================================================
1468 PQUEUE_HEADER RTMPCheckTxSwQueue(
1469 IN PRTMP_ADAPTER pAd,
1474 // 2004-11-15 to be removed. test aggregation only
1475 // if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)) && (*pNumber < 2))
1478 Number = pAd->TxSwQueue[QID_AC_BK].Number
1479 + pAd->TxSwQueue[QID_AC_BE].Number
1480 + pAd->TxSwQueue[QID_AC_VI].Number
1481 + pAd->TxSwQueue[QID_AC_VO].Number
1482 + pAd->TxSwQueue[QID_HCCA].Number;
1484 if (pAd->TxSwQueue[QID_AC_VO].Head != NULL)
1486 *pQueIdx = QID_AC_VO;
1487 return (&pAd->TxSwQueue[QID_AC_VO]);
1489 else if (pAd->TxSwQueue[QID_AC_VI].Head != NULL)
1491 *pQueIdx = QID_AC_VI;
1492 return (&pAd->TxSwQueue[QID_AC_VI]);
1494 else if (pAd->TxSwQueue[QID_AC_BE].Head != NULL)
1496 *pQueIdx = QID_AC_BE;
1497 return (&pAd->TxSwQueue[QID_AC_BE]);
1499 else if (pAd->TxSwQueue[QID_AC_BK].Head != NULL)
1501 *pQueIdx = QID_AC_BK;
1502 return (&pAd->TxSwQueue[QID_AC_BK]);
1504 else if (pAd->TxSwQueue[QID_HCCA].Head != NULL)
1506 *pQueIdx = QID_HCCA;
1507 return (&pAd->TxSwQueue[QID_HCCA]);
1510 // No packet pending in Tx Sw queue
1511 *pQueIdx = QID_AC_BK;
1519 ========================================================================
1521 Routine Description:
1522 Suspend MSDU transmission
1525 pAd Pointer to our adapter
1532 ========================================================================
1534 VOID RTMPSuspendMsduTransmission(
1535 IN PRTMP_ADAPTER pAd)
1537 DBGPRINT(RT_DEBUG_TRACE,("SCANNING, suspend MSDU transmission ...\n"));
1541 // Before BSS_SCAN_IN_PROGRESS, we need to keep Current R66 value and
1542 // use Lowbound as R66 value on ScanNextChannel(...)
1544 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1546 // set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning)
1547 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x26 + GET_LNA_GAIN(pAd)));
1548 RTMPSetAGCInitValue(pAd, BW_20);
1550 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1551 //RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x000f0000); // abort all TX rings
1556 ========================================================================
1558 Routine Description:
1559 Resume MSDU transmission
1562 pAd Pointer to our adapter
1567 IRQL = DISPATCH_LEVEL
1571 ========================================================================
1573 VOID RTMPResumeMsduTransmission(
1574 IN PRTMP_ADAPTER pAd)
1578 DBGPRINT(RT_DEBUG_TRACE,("SCAN done, resume MSDU transmission ...\n"));
1581 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, pAd->BbpTuning.R66CurrentValue);
1583 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1584 // sample, for IRQ LOCK to SEM LOCK
1585 // IrqState = pAd->irq_disabled;
1587 // RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1589 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1593 UINT deaggregate_AMSDU_announce(
1594 IN PRTMP_ADAPTER pAd,
1595 PNDIS_PACKET pPacket,
1600 USHORT SubFrameSize;
1601 PHEADER_802_3 pAMSDUsubheader;
1603 UCHAR Header802_3[14];
1605 PUCHAR pPayload, pDA, pSA, pRemovedLLCSNAP;
1606 PNDIS_PACKET pClonePacket;
1612 while (DataSize > LENGTH_802_3)
1617 //hex_dump("subheader", pData, 64);
1618 pAMSDUsubheader = (PHEADER_802_3)pData;
1619 //pData += LENGTH_802_3;
1620 PayloadSize = pAMSDUsubheader->Octet[1] + (pAMSDUsubheader->Octet[0]<<8);
1621 SubFrameSize = PayloadSize + LENGTH_802_3;
1624 if ((DataSize < SubFrameSize) || (PayloadSize > 1518 ))
1629 //printk("%d subframe: Size = %d\n", nMSDU, PayloadSize);
1631 pPayload = pData + LENGTH_802_3;
1633 pSA = pData + MAC_ADDR_LEN;
1635 // convert to 802.3 header
1636 CONVERT_TO_802_3(Header802_3, pDA, pSA, pPayload, PayloadSize, pRemovedLLCSNAP);
1638 #ifdef CONFIG_STA_SUPPORT
1639 if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E) )
1641 // avoid local heap overflow, use dyanamic allocation
1642 MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
1643 memmove(Elem->Msg+(LENGTH_802_11 + LENGTH_802_1_H), pPayload, PayloadSize);
1644 Elem->MsgLen = LENGTH_802_11 + LENGTH_802_1_H + PayloadSize;
1645 WpaEAPOLKeyAction(pAd, Elem);
1648 #endif // CONFIG_STA_SUPPORT //
1650 #ifdef CONFIG_STA_SUPPORT
1651 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1653 if (pRemovedLLCSNAP)
1655 pPayload -= LENGTH_802_3;
1656 PayloadSize += LENGTH_802_3;
1657 NdisMoveMemory(pPayload, &Header802_3[0], LENGTH_802_3);
1660 #endif // CONFIG_STA_SUPPORT //
1662 pClonePacket = ClonePacket(pAd, pPacket, pPayload, PayloadSize);
1665 #ifdef CONFIG_STA_SUPPORT
1666 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1667 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pClonePacket, RTMP_GET_PACKET_IF(pPacket));
1668 #endif // CONFIG_STA_SUPPORT //
1672 // A-MSDU has padding to multiple of 4 including subframe header.
1673 // align SubFrameSize up to multiple of 4
1674 SubFrameSize = (SubFrameSize+3)&(~0x3);
1677 if (SubFrameSize > 1528 || SubFrameSize < 32)
1682 if (DataSize > SubFrameSize)
1684 pData += SubFrameSize;
1685 DataSize -= SubFrameSize;
1694 // finally release original rx packet
1695 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1701 UINT BA_Reorder_AMSDU_Annnounce(
1702 IN PRTMP_ADAPTER pAd,
1703 IN PNDIS_PACKET pPacket)
1709 pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
1710 DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
1712 nMSDU = deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
1719 ==========================================================================
1721 Look up the MAC address in the MAC table. Return NULL if not found.
1723 pEntry - pointer to the MAC entry; NULL is not found
1724 ==========================================================================
1726 MAC_TABLE_ENTRY *MacTableLookup(
1727 IN PRTMP_ADAPTER pAd,
1731 MAC_TABLE_ENTRY *pEntry = NULL;
1733 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
1734 pEntry = pAd->MacTab.Hash[HashIdx];
1736 while (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsWDS || pEntry->ValidAsApCli || pEntry->ValidAsMesh))
1738 if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
1743 pEntry = pEntry->pNext;
1749 MAC_TABLE_ENTRY *MacTableInsertEntry(
1750 IN PRTMP_ADAPTER pAd,
1753 IN BOOLEAN CleanAll)
1757 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1760 if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
1764 #ifdef CONFIG_STA_SUPPORT
1765 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1766 if (pAd->StaCfg.BssType == BSS_INFRA)
1768 #endif // CONFIG_STA_SUPPORT //
1770 // allocate one MAC entry
1771 NdisAcquireSpinLock(&pAd->MacTabLock);
1772 for (i = FirstWcid; i< MAX_LEN_OF_MAC_TABLE; i++) // skip entry#0 so that "entry index == AID" for fast lookup
1774 // pick up the first available vacancy
1775 if ((pAd->MacTab.Content[i].ValidAsCLI == FALSE) &&
1776 (pAd->MacTab.Content[i].ValidAsWDS == FALSE) &&
1777 (pAd->MacTab.Content[i].ValidAsApCli== FALSE) &&
1778 (pAd->MacTab.Content[i].ValidAsMesh == FALSE)
1779 #ifdef CONFIG_STA_SUPPORT
1780 #ifdef QOS_DLS_SUPPORT
1781 && (pAd->MacTab.Content[i].ValidAsDls == FALSE)
1782 #endif // QOS_DLS_SUPPORT //
1783 #endif // CONFIG_STA_SUPPORT //
1786 pEntry = &pAd->MacTab.Content[i];
1787 if (CleanAll == TRUE)
1789 pEntry->MaxSupportedRate = RATE_11;
1790 pEntry->CurrTxRate = RATE_11;
1791 NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
1792 pEntry->PairwiseKey.KeyLen = 0;
1793 pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
1795 #ifdef CONFIG_STA_SUPPORT
1796 #ifdef QOS_DLS_SUPPORT
1797 if (apidx >= MIN_NET_DEVICE_FOR_DLS)
1799 pEntry->ValidAsCLI = FALSE;
1800 pEntry->ValidAsWDS = FALSE;
1801 pEntry->ValidAsApCli = FALSE;
1802 pEntry->ValidAsMesh = FALSE;
1803 pEntry->ValidAsDls = TRUE;
1804 pEntry->isCached = FALSE;
1807 #endif // QOS_DLS_SUPPORT //
1808 #endif // CONFIG_STA_SUPPORT //
1811 #ifdef CONFIG_STA_SUPPORT
1812 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1814 pEntry->ValidAsCLI = TRUE;
1815 pEntry->ValidAsWDS = FALSE;
1816 pEntry->ValidAsApCli = FALSE;
1817 pEntry->ValidAsMesh = FALSE;
1818 pEntry->ValidAsDls = FALSE;
1820 #endif // CONFIG_STA_SUPPORT //
1823 pEntry->bIAmBadAtheros = FALSE;
1825 pEntry->CMTimerRunning = FALSE;
1826 pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
1827 pEntry->RSNIE_Len = 0;
1828 NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter));
1829 pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
1831 if (pEntry->ValidAsMesh)
1832 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_MESH);
1833 else if (pEntry->ValidAsApCli)
1834 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_APCLI);
1835 else if (pEntry->ValidAsWDS)
1836 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_WDS);
1837 #ifdef CONFIG_STA_SUPPORT
1838 #ifdef QOS_DLS_SUPPORT
1839 else if (pEntry->ValidAsDls)
1840 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_DLS);
1841 #endif // QOS_DLS_SUPPORT //
1842 #endif // CONFIG_STA_SUPPORT //
1844 pEntry->apidx = apidx;
1848 #ifdef CONFIG_STA_SUPPORT
1849 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1851 pEntry->AuthMode = pAd->StaCfg.AuthMode;
1852 pEntry->WepStatus = pAd->StaCfg.WepStatus;
1853 pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1855 #endif // CONFIG_STA_SUPPORT //
1858 pEntry->GTKState = REKEY_NEGOTIATING;
1859 pEntry->PairwiseKey.KeyLen = 0;
1860 pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
1861 #ifdef CONFIG_STA_SUPPORT
1862 #ifdef QOS_DLS_SUPPORT
1863 if (pEntry->ValidAsDls == TRUE)
1864 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
1865 #endif //QOS_DLS_SUPPORT
1866 #endif // CONFIG_STA_SUPPORT //
1867 pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1868 pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
1869 COPY_MAC_ADDR(pEntry->Addr, pAddr);
1870 pEntry->Sst = SST_NOT_AUTH;
1871 pEntry->AuthState = AS_NOT_AUTH;
1872 pEntry->Aid = (USHORT)i; //0;
1873 pEntry->CapabilityInfo = 0;
1874 pEntry->PsMode = PWR_ACTIVE;
1875 pEntry->PsQIdleCount = 0;
1876 pEntry->NoDataIdleCount = 0;
1877 pEntry->ContinueTxFailCnt = 0;
1878 InitializeQueueHeader(&pEntry->PsQueue);
1881 pAd->MacTab.Size ++;
1882 // Add this entry into ASIC RX WCID search table
1883 RT28XX_STA_ENTRY_ADD(pAd, pEntry);
1885 DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertEntry - allocate entry #%d, Total= %d\n",i, pAd->MacTab.Size));
1890 // add this MAC entry into HASH table
1893 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
1894 if (pAd->MacTab.Hash[HashIdx] == NULL)
1896 pAd->MacTab.Hash[HashIdx] = pEntry;
1900 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1901 while (pCurrEntry->pNext != NULL)
1902 pCurrEntry = pCurrEntry->pNext;
1903 pCurrEntry->pNext = pEntry;
1907 NdisReleaseSpinLock(&pAd->MacTabLock);
1912 ==========================================================================
1914 Delete a specified client from MAC table
1915 ==========================================================================
1917 BOOLEAN MacTableDeleteEntry(
1918 IN PRTMP_ADAPTER pAd,
1923 MAC_TABLE_ENTRY *pEntry, *pPrevEntry, *pProbeEntry;
1925 //USHORT offset; // unused variable
1926 //UCHAR j; // unused variable
1928 if (wcid >= MAX_LEN_OF_MAC_TABLE)
1931 NdisAcquireSpinLock(&pAd->MacTabLock);
1933 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
1934 //pEntry = pAd->MacTab.Hash[HashIdx];
1935 pEntry = &pAd->MacTab.Content[wcid];
1937 if (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsApCli || pEntry->ValidAsWDS || pEntry->ValidAsMesh
1938 #ifdef CONFIG_STA_SUPPORT
1939 #ifdef QOS_DLS_SUPPORT
1940 || pEntry->ValidAsDls
1941 #endif // QOS_DLS_SUPPORT //
1942 #endif // CONFIG_STA_SUPPORT //
1945 if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
1948 // Delete this entry from ASIC on-chip WCID Table
1949 RT28XX_STA_ENTRY_MAC_RESET(pAd, wcid);
1951 #ifdef DOT11_N_SUPPORT
1952 // free resources of BA
1953 BASessionTearDownALL(pAd, pEntry->Aid);
1954 #endif // DOT11_N_SUPPORT //
1958 pProbeEntry = pAd->MacTab.Hash[HashIdx];
1959 ASSERT(pProbeEntry);
1964 if (pProbeEntry == pEntry)
1966 if (pPrevEntry == NULL)
1968 pAd->MacTab.Hash[HashIdx] = pEntry->pNext;
1972 pPrevEntry->pNext = pEntry->pNext;
1977 pPrevEntry = pProbeEntry;
1978 pProbeEntry = pProbeEntry->pNext;
1979 } while (pProbeEntry);
1982 ASSERT(pProbeEntry != NULL);
1984 RT28XX_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid);
1987 if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
1989 RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
1990 pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
1994 NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
1995 pAd->MacTab.Size --;
1996 DBGPRINT(RT_DEBUG_TRACE, ("MacTableDeleteEntry1 - Total= %d\n", pAd->MacTab.Size));
2000 printk("\n%s: Impossible Wcid = %d !!!!!\n", __func__, wcid);
2004 NdisReleaseSpinLock(&pAd->MacTabLock);
2006 //Reset operating mode when no Sta.
2007 if (pAd->MacTab.Size == 0)
2009 #ifdef DOT11_N_SUPPORT
2010 pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0;
2011 #endif // DOT11_N_SUPPORT //
2012 AsicUpdateProtect(pAd, 0 /*pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode*/, (ALLN_SETPROTECT), TRUE, 0 /*pAd->MacTab.fAnyStationNonGF*/);
2020 ==========================================================================
2022 This routine reset the entire MAC table. All packets pending in
2023 the power-saving queues are freed here.
2024 ==========================================================================
2027 IN PRTMP_ADAPTER pAd)
2031 DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n"));
2032 //NdisAcquireSpinLock(&pAd->MacTabLock);
2034 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
2036 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
2039 #ifdef DOT11_N_SUPPORT
2040 // free resources of BA
2041 BASessionTearDownALL(pAd, i);
2042 #endif // DOT11_N_SUPPORT //
2044 pAd->MacTab.Content[i].ValidAsCLI = FALSE;
2049 NdisZeroMemory(pAd->MacTab.Content[i].Addr, 6);
2050 RT28XX_STA_ENTRY_MAC_RESET(pAd, i);
2053 //AsicDelWcidTab(pAd, i);
2061 ==========================================================================
2064 IRQL = DISPATCH_LEVEL
2066 ==========================================================================
2069 IN PRTMP_ADAPTER pAd,
2070 IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq,
2072 IN USHORT CapabilityInfo,
2074 IN USHORT ListenIntv)
2076 COPY_MAC_ADDR(AssocReq->Addr, pAddr);
2077 // Add mask to support 802.11b mode only
2078 AssocReq->CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; // not cf-pollable, not cf-poll-request
2079 AssocReq->Timeout = Timeout;
2080 AssocReq->ListenIntv = ListenIntv;
2085 ==========================================================================
2088 IRQL = DISPATCH_LEVEL
2090 ==========================================================================
2092 VOID DisassocParmFill(
2093 IN PRTMP_ADAPTER pAd,
2094 IN OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq,
2098 COPY_MAC_ADDR(DisassocReq->Addr, pAddr);
2099 DisassocReq->Reason = Reason;
2104 ========================================================================
2106 Routine Description:
2107 Check the out going frame, if this is an DHCP or ARP datagram
2108 will be duplicate another frame at low data rate transmit.
2111 pAd Pointer to our adapter
2112 pPacket Pointer to outgoing Ndis frame
2115 TRUE To be duplicate at Low data rate transmit. (1mb)
2118 IRQL = DISPATCH_LEVEL
2122 MAC header + IP Header + UDP Header
2126 00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|
2128 16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|
2131 port 0x43 means Bootstrap Protocol, server.
2132 Port 0x44 means Bootstrap Protocol, client.
2134 ========================================================================
2137 BOOLEAN RTMPCheckDHCPFrame(
2138 IN PRTMP_ADAPTER pAd,
2139 IN PNDIS_PACKET pPacket)
2141 PACKET_INFO PacketInfo;
2142 ULONG NumberOfBytesRead = 0;
2143 ULONG CurrentOffset = 0;
2144 PVOID pVirtualAddress = NULL;
2145 UINT NdisBufferLength;
2148 UCHAR ByteOffset36 = 0;
2149 UCHAR ByteOffset38 = 0;
2150 BOOLEAN ReadFirstParm = TRUE;
2152 RTMP_QueryPacketInfo(pPacket, &PacketInfo, (PUCHAR *)&pVirtualAddress, &NdisBufferLength);
2154 NumberOfBytesRead += NdisBufferLength;
2155 pSrc = (PUCHAR) pVirtualAddress;
2156 Protocol = *(pSrc + 12) * 256 + *(pSrc + 13);
2159 // Check DHCP & BOOTP protocol
2161 while (NumberOfBytesRead <= PacketInfo.TotalPacketLength)
2163 if ((NumberOfBytesRead >= 35) && (ReadFirstParm == TRUE))
2165 CurrentOffset = 35 - (NumberOfBytesRead - NdisBufferLength);
2166 ByteOffset36 = *(pSrc + CurrentOffset);
2167 ReadFirstParm = FALSE;
2170 if (NumberOfBytesRead >= 37)
2172 CurrentOffset = 37 - (NumberOfBytesRead - NdisBufferLength);
2173 ByteOffset38 = *(pSrc + CurrentOffset);
2180 // Check for DHCP & BOOTP protocol
2181 if ((ByteOffset36 != 0x44) || (ByteOffset38 != 0x43))
2184 // 2054 (hex 0806) for ARP datagrams
2185 // if this packet is not ARP datagrams, then do nothing
2186 // ARP datagrams will also be duplicate at 1mb broadcast frames
2188 if (Protocol != 0x0806 )
2196 BOOLEAN RTMPCheckEtherType(
2197 IN PRTMP_ADAPTER pAd,
2198 IN PNDIS_PACKET pPacket)
2204 UINT16 srcPort, dstPort;
2205 BOOLEAN status = TRUE;
2208 pSrcBuf = GET_OS_PKT_DATAPTR(pPacket);
2209 pktLen = GET_OS_PKT_LEN(pPacket);
2213 RTMP_SET_PACKET_SPECIFIC(pPacket, 0);
2215 // get Ethernet protocol field
2216 TypeLen = (pSrcBuf[12] << 8) + pSrcBuf[13];
2218 pSrcBuf += LENGTH_802_3; // Skip the Ethernet Header.
2220 if (TypeLen <= 1500)
2221 { // 802.3, 802.3 LLC
2223 DestMAC(6) + SrcMAC(6) + Lenght(2) +
2224 DSAP(1) + SSAP(1) + Control(1) +
2225 if the DSAP = 0xAA, SSAP=0xAA, Contorl = 0x03, it has a 5-bytes SNAP header.
2226 => + SNAP (5, OriginationID(3) + etherType(2))
2228 if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA && pSrcBuf[2] == 0x03)
2230 Sniff2BytesFromNdisBuffer(pSrcBuf, 6, &Byte0, &Byte1);
2231 RTMP_SET_PACKET_LLCSNAP(pPacket, 1);
2232 TypeLen = (USHORT)((Byte0 << 8) + Byte1);
2233 pSrcBuf += 8; // Skip this LLC/SNAP header
2237 //It just has 3-byte LLC header, maybe a legacy ether type frame. we didn't handle it.
2241 // If it's a VLAN packet, get the real Type/Length field.
2242 if (TypeLen == 0x8100)
2244 /* 0x8100 means VLAN packets */
2246 /* Dest. MAC Address (6-bytes) +
2247 Source MAC Address (6-bytes) +
2248 Length/Type = 802.1Q Tag Type (2-byte) +
2249 Tag Control Information (2-bytes) +
2250 Length / Type (2-bytes) +
2251 data payload (0-n bytes) +
2253 Frame Check Sequence (4-bytes) */
2255 RTMP_SET_PACKET_VLAN(pPacket, 1);
2256 Sniff2BytesFromNdisBuffer(pSrcBuf, 2, &Byte0, &Byte1);
2257 TypeLen = (USHORT)((Byte0 << 8) + Byte1);
2259 pSrcBuf += 4; // Skip the VLAN Header.
2266 ASSERT((pktLen > 34));
2267 if (*(pSrcBuf + 9) == 0x11)
2269 ASSERT((pktLen > 34)); // 14 for ethernet header, 20 for IP header
2271 pSrcBuf += 20; // Skip the IP header
2272 srcPort = OS_NTOHS(*((UINT16 *)pSrcBuf));
2273 dstPort = OS_NTOHS(*((UINT16 *)(pSrcBuf +2)));
2275 if ((srcPort==0x44 && dstPort==0x43) || (srcPort==0x43 && dstPort==0x44))
2276 { //It's a BOOTP/DHCP packet
2277 RTMP_SET_PACKET_DHCP(pPacket, 1);
2285 RTMP_SET_PACKET_DHCP(pPacket, 1);
2291 RTMP_SET_PACKET_EAPOL(pPacket, 1);
2305 VOID Update_Rssi_Sample(
2306 IN PRTMP_ADAPTER pAd,
2307 IN RSSI_SAMPLE *pRssi,
2308 IN PRXWI_STRUC pRxWI)
2310 CHAR rssi0 = pRxWI->RSSI0;
2311 CHAR rssi1 = pRxWI->RSSI1;
2312 CHAR rssi2 = pRxWI->RSSI2;
2316 pRssi->LastRssi0 = ConvertToRssi(pAd, (CHAR)rssi0, RSSI_0);
2317 pRssi->AvgRssi0X8 = (pRssi->AvgRssi0X8 - pRssi->AvgRssi0) + pRssi->LastRssi0;
2318 pRssi->AvgRssi0 = pRssi->AvgRssi0X8 >> 3;
2323 pRssi->LastRssi1 = ConvertToRssi(pAd, (CHAR)rssi1, RSSI_1);
2324 pRssi->AvgRssi1X8 = (pRssi->AvgRssi1X8 - pRssi->AvgRssi1) + pRssi->LastRssi1;
2325 pRssi->AvgRssi1 = pRssi->AvgRssi1X8 >> 3;
2330 pRssi->LastRssi2 = ConvertToRssi(pAd, (CHAR)rssi2, RSSI_2);
2331 pRssi->AvgRssi2X8 = (pRssi->AvgRssi2X8 - pRssi->AvgRssi2) + pRssi->LastRssi2;
2332 pRssi->AvgRssi2 = pRssi->AvgRssi2X8 >> 3;
2338 // Normal legacy Rx packet indication
2339 VOID Indicate_Legacy_Packet(
2340 IN PRTMP_ADAPTER pAd,
2342 IN UCHAR FromWhichBSSID)
2344 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
2345 UCHAR Header802_3[LENGTH_802_3];
2347 // 1. get 802.3 Header
2349 // a. pointer pRxBlk->pData to payload
2350 // b. modify pRxBlk->DataSize
2351 #ifdef CONFIG_STA_SUPPORT
2352 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2353 RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
2354 #endif // CONFIG_STA_SUPPORT //
2356 if (pRxBlk->DataSize > MAX_RX_PKT_LEN)
2358 #if 0 // sample take off, for multiple card design
2359 static int err_size;
2364 printk("Legacy DataSize = %d\n", pRxBlk->DataSize);
2365 hex_dump("802.3 Header", Header802_3, LENGTH_802_3);
2366 hex_dump("Payload", pRxBlk->pData, 64);
2372 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
2377 STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
2380 #ifdef DOT11_N_SUPPORT
2381 if (pAd->CommonCfg.bDisableReordering == 0)
2383 PBA_REC_ENTRY pBAEntry;
2385 UCHAR Wcid = pRxBlk->pRxWI->WirelessCliID;
2386 UCHAR TID = pRxBlk->pRxWI->TID;
2389 #define REORDERING_PACKET_TIMEOUT ((100 * HZ)/1000) // system ticks -- 100 ms
2391 if (Wcid < MAX_LEN_OF_MAC_TABLE)
2393 Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
2396 pBAEntry = &pAd->BATable.BARecEntry[Idx];
2397 // update last rx time
2398 NdisGetSystemUpTime(&Now32);
2399 if ((pBAEntry->list.qlen > 0) &&
2400 RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT)))
2403 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);
2404 hex_dump("Dump the legacy Packet:", GET_OS_PKT_DATAPTR(pRxBlk->pRxPacket), 64);
2405 ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
2410 #endif // DOT11_N_SUPPORT //
2413 wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
2416 // pass this 802.3 packet to upper layer or forward this packet to WM directly
2418 #ifdef CONFIG_STA_SUPPORT
2419 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2420 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxPacket, FromWhichBSSID);
2421 #endif // CONFIG_STA_SUPPORT //
2426 // Normal, AMPDU or AMSDU
2427 VOID CmmRxnonRalinkFrameIndicate(
2428 IN PRTMP_ADAPTER pAd,
2430 IN UCHAR FromWhichBSSID)
2432 #ifdef DOT11_N_SUPPORT
2433 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
2435 Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
2438 #endif // DOT11_N_SUPPORT //
2440 #ifdef DOT11_N_SUPPORT
2441 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
2444 Indicate_AMSDU_Packet(pAd, pRxBlk, FromWhichBSSID);
2447 #endif // DOT11_N_SUPPORT //
2449 Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
2455 VOID CmmRxRalinkFrameIndicate(
2456 IN PRTMP_ADAPTER pAd,
2457 IN MAC_TABLE_ENTRY *pEntry,
2459 IN UCHAR FromWhichBSSID)
2461 UCHAR Header802_3[LENGTH_802_3];
2463 UINT16 Payload1Size, Payload2Size;
2465 PNDIS_PACKET pPacket2 = NULL;
2469 Msdu2Size = *(pRxBlk->pData) + (*(pRxBlk->pData+1) << 8);
2471 if ((Msdu2Size <= 1536) && (Msdu2Size < pRxBlk->DataSize))
2473 /* skip two byte MSDU2 len */
2475 pRxBlk->DataSize -= 2;
2480 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
2484 // get 802.3 Header and remove LLC
2485 #ifdef CONFIG_STA_SUPPORT
2486 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2487 RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
2488 #endif // CONFIG_STA_SUPPORT //
2491 ASSERT(pRxBlk->pRxPacket);
2493 // Ralink Aggregation frame
2494 pAd->RalinkCounters.OneSecRxAggregationCount ++;
2495 Payload1Size = pRxBlk->DataSize - Msdu2Size;
2496 Payload2Size = Msdu2Size - LENGTH_802_3;
2498 pData2 = pRxBlk->pData + Payload1Size + LENGTH_802_3;
2499 #ifdef CONFIG_STA_SUPPORT
2500 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2501 pPacket2 = duplicate_pkt(pAd, (pData2-LENGTH_802_3), LENGTH_802_3, pData2, Payload2Size, FromWhichBSSID);
2502 #endif // CONFIG_STA_SUPPORT //
2507 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
2511 // update payload size of 1st packet
2512 pRxBlk->DataSize = Payload1Size;
2513 wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
2515 #ifdef CONFIG_STA_SUPPORT
2516 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2517 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxBlk->pRxPacket, FromWhichBSSID);
2518 #endif // CONFIG_STA_SUPPORT //
2522 #ifdef CONFIG_STA_SUPPORT
2523 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2524 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket2, FromWhichBSSID);
2525 #endif // CONFIG_STA_SUPPORT //
2530 #define RESET_FRAGFRAME(_fragFrame) \
2532 _fragFrame.RxSize = 0; \
2533 _fragFrame.Sequence = 0; \
2534 _fragFrame.LastFrag = 0; \
2535 _fragFrame.Flags = 0; \
2539 PNDIS_PACKET RTMPDeFragmentDataFrame(
2540 IN PRTMP_ADAPTER pAd,
2543 PHEADER_802_11 pHeader = pRxBlk->pHeader;
2544 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
2545 UCHAR *pData = pRxBlk->pData;
2546 USHORT DataSize = pRxBlk->DataSize;
2547 PNDIS_PACKET pRetPacket = NULL;
2548 UCHAR *pFragBuffer = NULL;
2549 BOOLEAN bReassDone = FALSE;
2550 UCHAR HeaderRoom = 0;
2555 HeaderRoom = pData - (UCHAR *)pHeader;
2557 // Re-assemble the fragmented packets
2558 if (pHeader->Frag == 0) // Frag. Number is 0 : First frag or only one pkt
2560 // the first pkt of fragment, record it.
2561 if (pHeader->FC.MoreFrag)
2563 ASSERT(pAd->FragFrame.pFragPacket);
2564 pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
2565 pAd->FragFrame.RxSize = DataSize + HeaderRoom;
2566 NdisMoveMemory(pFragBuffer, pHeader, pAd->FragFrame.RxSize);
2567 pAd->FragFrame.Sequence = pHeader->Sequence;
2568 pAd->FragFrame.LastFrag = pHeader->Frag; // Should be 0
2569 ASSERT(pAd->FragFrame.LastFrag == 0);
2570 goto done; // end of processing this frame
2573 else //Middle & End of fragment
2575 if ((pHeader->Sequence != pAd->FragFrame.Sequence) ||
2576 (pHeader->Frag != (pAd->FragFrame.LastFrag + 1)))
2578 // Fragment is not the same sequence or out of fragment number order
2579 // Reset Fragment control blk
2580 RESET_FRAGFRAME(pAd->FragFrame);
2581 DBGPRINT(RT_DEBUG_ERROR, ("Fragment is not the same sequence or out of fragment number order.\n"));
2582 goto done; // give up this frame
2584 else if ((pAd->FragFrame.RxSize + DataSize) > MAX_FRAME_SIZE)
2586 // Fragment frame is too large, it exeeds the maximum frame size.
2587 // Reset Fragment control blk
2588 RESET_FRAGFRAME(pAd->FragFrame);
2589 DBGPRINT(RT_DEBUG_ERROR, ("Fragment frame is too large, it exeeds the maximum frame size.\n"));
2590 goto done; // give up this frame
2594 // Broadcom AP(BCM94704AGR) will send out LLC in fragment's packet, LLC only can accpet at first fragment.
2595 // In this case, we will dropt it.
2597 if (NdisEqualMemory(pData, SNAP_802_1H, sizeof(SNAP_802_1H)))
2599 DBGPRINT(RT_DEBUG_ERROR, ("Find another LLC at Middle or End fragment(SN=%d, Frag=%d)\n", pHeader->Sequence, pHeader->Frag));
2600 goto done; // give up this frame
2603 pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
2605 // concatenate this fragment into the re-assembly buffer
2606 NdisMoveMemory((pFragBuffer + pAd->FragFrame.RxSize), pData, DataSize);
2607 pAd->FragFrame.RxSize += DataSize;
2608 pAd->FragFrame.LastFrag = pHeader->Frag; // Update fragment number
2611 if (pHeader->FC.MoreFrag == FALSE)
2618 // always release rx fragmented packet
2619 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
2621 // return defragmented packet if packet is reassembled completely
2622 // otherwise return NULL
2625 PNDIS_PACKET pNewFragPacket;
2627 // allocate a new packet buffer for fragment
2628 pNewFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
2632 pRetPacket = pAd->FragFrame.pFragPacket;
2633 pAd->FragFrame.pFragPacket = pNewFragPacket;
2634 pRxBlk->pHeader = (PHEADER_802_11) GET_OS_PKT_DATAPTR(pRetPacket);
2635 pRxBlk->pData = (UCHAR *)pRxBlk->pHeader + HeaderRoom;
2636 pRxBlk->DataSize = pAd->FragFrame.RxSize - HeaderRoom;
2637 pRxBlk->pRxPacket = pRetPacket;
2641 RESET_FRAGFRAME(pAd->FragFrame);
2649 VOID Indicate_AMSDU_Packet(
2650 IN PRTMP_ADAPTER pAd,
2652 IN UCHAR FromWhichBSSID)
2656 update_os_packet_info(pAd, pRxBlk, FromWhichBSSID);
2657 RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
2658 nMSDU = deaggregate_AMSDU_announce(pAd, pRxBlk->pRxPacket, pRxBlk->pData, pRxBlk->DataSize);
2661 VOID Indicate_EAPOL_Packet(
2662 IN PRTMP_ADAPTER pAd,
2664 IN UCHAR FromWhichBSSID)
2666 MAC_TABLE_ENTRY *pEntry = NULL;
2669 #ifdef CONFIG_STA_SUPPORT
2670 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2672 pEntry = &pAd->MacTab.Content[BSSID_WCID];
2673 STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
2676 #endif // CONFIG_STA_SUPPORT //
2680 DBGPRINT(RT_DEBUG_WARN, ("Indicate_EAPOL_Packet: drop and release the invalid packet.\n"));
2682 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
2687 #define BCN_TBTT_OFFSET 64 //defer 64 us
2688 VOID ReSyncBeaconTime(
2689 IN PRTMP_ADAPTER pAd)
2695 Offset = (pAd->TbttTickCount) % (BCN_TBTT_OFFSET);
2697 pAd->TbttTickCount++;
2700 // The updated BeaconInterval Value will affect Beacon Interval after two TBTT
2701 // beacasue the original BeaconInterval had been loaded into next TBTT_TIMER
2703 if (Offset == (BCN_TBTT_OFFSET-2))
2705 BCN_TIME_CFG_STRUC csr;
2706 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
2707 csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod << 4) - 1 ; // ASIC register in units of 1/16 TU = 64us
2708 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
2712 if (Offset == (BCN_TBTT_OFFSET-1))
2714 BCN_TIME_CFG_STRUC csr;
2716 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
2717 csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod) << 4; // ASIC register in units of 1/16 TU
2718 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);