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 #ifdef CONFIG_STA_SUPPORT
1253 #ifdef QOS_DLS_SUPPORT
1255 (pAd->StaCfg.BssType == BSS_INFRA) &&
1256 (pMacEntry->ValidAsDls == TRUE))
1257 pTxWI->WirelessCliID = BSSID_WCID;
1259 #endif // QOS_DLS_SUPPORT //
1260 #endif // CONFIG_STA_SUPPORT //
1261 pTxWI->WirelessCliID = pTxBlk->Wcid;
1263 pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
1264 pTxWI->CFACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bPiggyBack);
1266 // If CCK or OFDM, BW must be 20
1267 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1268 #ifdef DOT11_N_SUPPORT
1269 #ifdef DOT11N_DRAFT3
1271 pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
1272 #endif // DOT11N_DRAFT3 //
1273 pTxWI->AMPDU = ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) ? TRUE : FALSE);
1275 // John tune the performace with Intel Client in 20 MHz performance
1276 BASize = pAd->CommonCfg.TxBASize;
1277 if((pTxBlk->TxFrameType == TX_AMPDU_FRAME) && (pMacEntry))
1279 UCHAR RABAOriIdx = 0; //The RA's BA Originator table index.
1281 RABAOriIdx = pTxBlk->pMacEntry->BAOriWcidArray[pTxBlk->UserPriority];
1282 BASize = pAd->BATable.BAOriEntry[RABAOriIdx].BAWinSize;
1285 pTxWI->TxBF = pTransmit->field.TxBF;
1286 pTxWI->BAWinSize = BASize;
1287 pTxWI->ShortGI = pTransmit->field.ShortGI;
1288 pTxWI->STBC = pTransmit->field.STBC;
1289 #endif // DOT11_N_SUPPORT //
1291 pTxWI->MCS = pTransmit->field.MCS;
1292 pTxWI->PHYMODE = pTransmit->field.MODE;
1294 #ifdef DOT11_N_SUPPORT
1297 if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1299 // Dynamic MIMO Power Save Mode
1302 else if (pMacEntry->MmpsMode == MMPS_STATIC)
1304 // Static MIMO Power Save Mode
1305 if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
1312 if (pMacEntry->bIAmBadAtheros && (pMacEntry->WepStatus != Ndis802_11WEPDisabled))
1314 pTxWI->MpduDensity = 7;
1318 pTxWI->MpduDensity = pMacEntry->MpduDensity;
1321 #endif // DOT11_N_SUPPORT //
1324 if (pTxBlk->QueIdx== 0)
1326 pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
1327 pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
1329 #endif // DBG_DIAGNOSE //
1331 // for rate adapation
1332 pTxWI->PacketId = pTxWI->MCS;
1333 #ifdef INF_AMAZON_SE
1334 /*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate */
1335 if( RTMP_GET_PACKET_NOBULKOUT(pTxBlk->pPacket))
1337 if(pTxWI->PHYMODE == MODE_CCK)
1339 pTxWI->PacketId = 6;
1342 #endif // INF_AMAZON_SE //
1346 VOID RTMPWriteTxWI_Cache(
1347 IN PRTMP_ADAPTER pAd,
1348 IN OUT PTXWI_STRUC pTxWI,
1351 PHTTRANSMIT_SETTING /*pTxHTPhyMode,*/ pTransmit;
1352 PMAC_TABLE_ENTRY pMacEntry;
1357 pMacEntry = pTxBlk->pMacEntry;
1358 pTransmit = pTxBlk->pTransmit;
1360 //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
1361 //if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pMacEntry))
1362 //if (TX_BLK_TEST_FLAG(pTxBlk, fTX_AutoRateSwitch))
1363 if (pMacEntry->bAutoTxRateSwitch)
1365 pTxWI->txop = IFS_HTTXOP;
1367 // If CCK or OFDM, BW must be 20
1368 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1369 pTxWI->ShortGI = pTransmit->field.ShortGI;
1370 pTxWI->STBC = pTransmit->field.STBC;
1372 pTxWI->MCS = pTransmit->field.MCS;
1373 pTxWI->PHYMODE = pTransmit->field.MODE;
1375 // set PID for TxRateSwitching
1376 pTxWI->PacketId = pTransmit->field.MCS;
1379 #ifdef DOT11_N_SUPPORT
1380 pTxWI->AMPDU = ((pMacEntry->NoBADataCountDown == 0) ? TRUE: FALSE);
1383 #ifdef DOT11N_DRAFT3
1385 pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
1386 #endif // DOT11N_DRAFT3 //
1388 if (pAd->CommonCfg.bMIMOPSEnable)
1390 // MIMO Power Save Mode
1391 if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1393 // Dynamic MIMO Power Save Mode
1396 else if (pMacEntry->MmpsMode == MMPS_STATIC)
1398 // Static MIMO Power Save Mode
1399 if ((pTransmit->field.MODE >= MODE_HTMIX) && (pTransmit->field.MCS > 7))
1406 #endif // DOT11_N_SUPPORT //
1409 if (pTxBlk->QueIdx== 0)
1411 pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
1412 pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
1414 #endif // DBG_DIAGNOSE //
1416 pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
1422 ========================================================================
1424 Routine Description:
1425 Calculates the duration which is required to transmit out frames
1426 with given size and specified rate.
1429 pTxD Pointer to transmit descriptor
1430 Ack Setting for Ack requirement bit
1431 Fragment Setting for Fragment bit
1432 RetryMode Setting for retry mode
1433 Ifs Setting for IFS gap
1434 Rate Setting for transmit rate
1435 Service Setting for service
1437 TxPreamble Short or Long preamble when using CCK rates
1438 QueIdx - 0-3, according to 802.11e/d4.4 June/2003
1443 IRQL = PASSIVE_LEVEL
1444 IRQL = DISPATCH_LEVEL
1446 ========================================================================
1448 VOID RTMPWriteTxDescriptor(
1449 IN PRTMP_ADAPTER pAd,
1455 // Always use Long preamble before verifiation short preamble functionality works well.
1456 // Todo: remove the following line if short preamble functionality works
1458 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1460 pTxD->WIV = (bWIV) ? 1: 0;
1461 pTxD->QSEL= (QueueSEL);
1462 if (pAd->bGenOneHCCA == TRUE)
1463 pTxD->QSEL= FIFO_HCCA;
1468 // should be called only when -
1469 // 1. MEADIA_CONNECTED
1470 // 2. AGGREGATION_IN_USED
1471 // 3. Fragmentation not in used
1472 // 4. either no previous frame (pPrevAddr1=NULL) .OR. previoud frame is aggregatible
1473 BOOLEAN TxFrameIsAggregatible(
1474 IN PRTMP_ADAPTER pAd,
1475 IN PUCHAR pPrevAddr1,
1479 // can't aggregate EAPOL (802.1x) frame
1480 if ((p8023hdr[12] == 0x88) && (p8023hdr[13] == 0x8e))
1483 // can't aggregate multicast/broadcast frame
1484 if (p8023hdr[0] & 0x01)
1487 if (INFRA_ON(pAd)) // must be unicast to AP
1489 else if ((pPrevAddr1 == NULL) || MAC_ADDR_EQUAL(pPrevAddr1, p8023hdr)) // unicast to same STA
1497 ========================================================================
1499 Routine Description:
1500 Check the MSDU Aggregation policy
1501 1.HT aggregation is A-MSDU
1502 2.legaacy rate aggregation is software aggregation by Ralink.
1510 ========================================================================
1512 BOOLEAN PeerIsAggreOn(
1513 IN PRTMP_ADAPTER pAd,
1515 IN PMAC_TABLE_ENTRY pMacEntry)
1517 ULONG AFlags = (fCLIENT_STATUS_AMSDU_INUSED | fCLIENT_STATUS_AGGREGATION_CAPABLE);
1519 if (pMacEntry != NULL && CLIENT_STATUS_TEST_FLAG(pMacEntry, AFlags))
1521 #ifdef DOT11_N_SUPPORT
1522 if (pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
1526 #endif // DOT11_N_SUPPORT //
1528 #ifdef AGGREGATION_SUPPORT
1529 if (TxRate >= RATE_6 && pAd->CommonCfg.bAggregationCapable && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
1530 { // legacy Ralink Aggregation support
1533 #endif // AGGREGATION_SUPPORT //
1542 ========================================================================
1544 Routine Description:
1545 Check and fine the packet waiting in SW queue with highest priority
1548 pAd Pointer to our adapter
1551 pQueue Pointer to Waiting Queue
1553 IRQL = DISPATCH_LEVEL
1557 ========================================================================
1559 PQUEUE_HEADER RTMPCheckTxSwQueue(
1560 IN PRTMP_ADAPTER pAd,
1565 // 2004-11-15 to be removed. test aggregation only
1566 // if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)) && (*pNumber < 2))
1569 Number = pAd->TxSwQueue[QID_AC_BK].Number
1570 + pAd->TxSwQueue[QID_AC_BE].Number
1571 + pAd->TxSwQueue[QID_AC_VI].Number
1572 + pAd->TxSwQueue[QID_AC_VO].Number
1573 + pAd->TxSwQueue[QID_HCCA].Number;
1575 if (pAd->TxSwQueue[QID_AC_VO].Head != NULL)
1577 *pQueIdx = QID_AC_VO;
1578 return (&pAd->TxSwQueue[QID_AC_VO]);
1580 else if (pAd->TxSwQueue[QID_AC_VI].Head != NULL)
1582 *pQueIdx = QID_AC_VI;
1583 return (&pAd->TxSwQueue[QID_AC_VI]);
1585 else if (pAd->TxSwQueue[QID_AC_BE].Head != NULL)
1587 *pQueIdx = QID_AC_BE;
1588 return (&pAd->TxSwQueue[QID_AC_BE]);
1590 else if (pAd->TxSwQueue[QID_AC_BK].Head != NULL)
1592 *pQueIdx = QID_AC_BK;
1593 return (&pAd->TxSwQueue[QID_AC_BK]);
1595 else if (pAd->TxSwQueue[QID_HCCA].Head != NULL)
1597 *pQueIdx = QID_HCCA;
1598 return (&pAd->TxSwQueue[QID_HCCA]);
1601 // No packet pending in Tx Sw queue
1602 *pQueIdx = QID_AC_BK;
1610 ========================================================================
1612 Routine Description:
1613 Suspend MSDU transmission
1616 pAd Pointer to our adapter
1623 ========================================================================
1625 VOID RTMPSuspendMsduTransmission(
1626 IN PRTMP_ADAPTER pAd)
1628 DBGPRINT(RT_DEBUG_TRACE,("SCANNING, suspend MSDU transmission ...\n"));
1632 // Before BSS_SCAN_IN_PROGRESS, we need to keep Current R66 value and
1633 // use Lowbound as R66 value on ScanNextChannel(...)
1635 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1637 // set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning)
1638 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x26 + GET_LNA_GAIN(pAd)));
1639 RTMPSetAGCInitValue(pAd, BW_20);
1641 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1642 //RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x000f0000); // abort all TX rings
1647 ========================================================================
1649 Routine Description:
1650 Resume MSDU transmission
1653 pAd Pointer to our adapter
1658 IRQL = DISPATCH_LEVEL
1662 ========================================================================
1664 VOID RTMPResumeMsduTransmission(
1665 IN PRTMP_ADAPTER pAd)
1669 DBGPRINT(RT_DEBUG_TRACE,("SCAN done, resume MSDU transmission ...\n"));
1672 // After finish BSS_SCAN_IN_PROGRESS, we need to restore Current R66 value
1673 // R66 should not be 0
1674 if (pAd->BbpTuning.R66CurrentValue == 0)
1676 pAd->BbpTuning.R66CurrentValue = 0x38;
1677 DBGPRINT_ERR(("RTMPResumeMsduTransmission, R66CurrentValue=0...\n"));
1679 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, pAd->BbpTuning.R66CurrentValue);
1681 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1682 // sample, for IRQ LOCK to SEM LOCK
1683 // IrqState = pAd->irq_disabled;
1685 // RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1687 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1691 UINT deaggregate_AMSDU_announce(
1692 IN PRTMP_ADAPTER pAd,
1693 PNDIS_PACKET pPacket,
1698 USHORT SubFrameSize;
1699 PHEADER_802_3 pAMSDUsubheader;
1701 UCHAR Header802_3[14];
1703 PUCHAR pPayload, pDA, pSA, pRemovedLLCSNAP;
1704 PNDIS_PACKET pClonePacket;
1710 while (DataSize > LENGTH_802_3)
1715 //hex_dump("subheader", pData, 64);
1716 pAMSDUsubheader = (PHEADER_802_3)pData;
1717 //pData += LENGTH_802_3;
1718 PayloadSize = pAMSDUsubheader->Octet[1] + (pAMSDUsubheader->Octet[0]<<8);
1719 SubFrameSize = PayloadSize + LENGTH_802_3;
1722 if ((DataSize < SubFrameSize) || (PayloadSize > 1518 ))
1727 //printk("%d subframe: Size = %d\n", nMSDU, PayloadSize);
1729 pPayload = pData + LENGTH_802_3;
1731 pSA = pData + MAC_ADDR_LEN;
1733 // convert to 802.3 header
1734 CONVERT_TO_802_3(Header802_3, pDA, pSA, pPayload, PayloadSize, pRemovedLLCSNAP);
1736 #ifdef CONFIG_STA_SUPPORT
1737 if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E) )
1739 // avoid local heap overflow, use dyanamic allocation
1740 MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
1741 memmove(Elem->Msg+(LENGTH_802_11 + LENGTH_802_1_H), pPayload, PayloadSize);
1742 Elem->MsgLen = LENGTH_802_11 + LENGTH_802_1_H + PayloadSize;
1743 WpaEAPOLKeyAction(pAd, Elem);
1746 #endif // CONFIG_STA_SUPPORT //
1748 #ifdef CONFIG_STA_SUPPORT
1749 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1751 if (pRemovedLLCSNAP)
1753 pPayload -= LENGTH_802_3;
1754 PayloadSize += LENGTH_802_3;
1755 NdisMoveMemory(pPayload, &Header802_3[0], LENGTH_802_3);
1758 #endif // CONFIG_STA_SUPPORT //
1760 pClonePacket = ClonePacket(pAd, pPacket, pPayload, PayloadSize);
1763 #ifdef CONFIG_STA_SUPPORT
1764 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1765 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pClonePacket, RTMP_GET_PACKET_IF(pPacket));
1766 #endif // CONFIG_STA_SUPPORT //
1770 // A-MSDU has padding to multiple of 4 including subframe header.
1771 // align SubFrameSize up to multiple of 4
1772 SubFrameSize = (SubFrameSize+3)&(~0x3);
1775 if (SubFrameSize > 1528 || SubFrameSize < 32)
1780 if (DataSize > SubFrameSize)
1782 pData += SubFrameSize;
1783 DataSize -= SubFrameSize;
1792 // finally release original rx packet
1793 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1799 UINT BA_Reorder_AMSDU_Annnounce(
1800 IN PRTMP_ADAPTER pAd,
1801 IN PNDIS_PACKET pPacket)
1807 pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
1808 DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
1810 nMSDU = deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
1817 ==========================================================================
1819 Look up the MAC address in the MAC table. Return NULL if not found.
1821 pEntry - pointer to the MAC entry; NULL is not found
1822 ==========================================================================
1824 MAC_TABLE_ENTRY *MacTableLookup(
1825 IN PRTMP_ADAPTER pAd,
1829 MAC_TABLE_ENTRY *pEntry = NULL;
1831 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
1832 pEntry = pAd->MacTab.Hash[HashIdx];
1834 while (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsWDS || pEntry->ValidAsApCli || pEntry->ValidAsMesh))
1836 if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
1841 pEntry = pEntry->pNext;
1847 MAC_TABLE_ENTRY *MacTableInsertEntry(
1848 IN PRTMP_ADAPTER pAd,
1851 IN BOOLEAN CleanAll)
1855 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1860 if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
1864 #ifdef CONFIG_STA_SUPPORT
1865 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1866 if (pAd->StaCfg.BssType == BSS_INFRA)
1868 #endif // CONFIG_STA_SUPPORT //
1870 // allocate one MAC entry
1871 NdisAcquireSpinLock(&pAd->MacTabLock);
1872 for (i = FirstWcid; i< MAX_LEN_OF_MAC_TABLE; i++) // skip entry#0 so that "entry index == AID" for fast lookup
1874 // pick up the first available vacancy
1875 if ((pAd->MacTab.Content[i].ValidAsCLI == FALSE) &&
1876 (pAd->MacTab.Content[i].ValidAsWDS == FALSE) &&
1877 (pAd->MacTab.Content[i].ValidAsApCli== FALSE) &&
1878 (pAd->MacTab.Content[i].ValidAsMesh == FALSE)
1879 #ifdef CONFIG_STA_SUPPORT
1880 #ifdef QOS_DLS_SUPPORT
1881 && (pAd->MacTab.Content[i].ValidAsDls == FALSE)
1882 #endif // QOS_DLS_SUPPORT //
1883 #endif // CONFIG_STA_SUPPORT //
1886 pEntry = &pAd->MacTab.Content[i];
1887 if (CleanAll == TRUE)
1889 pEntry->MaxSupportedRate = RATE_11;
1890 pEntry->CurrTxRate = RATE_11;
1891 NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
1892 pEntry->PairwiseKey.KeyLen = 0;
1893 pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
1895 #ifdef CONFIG_STA_SUPPORT
1896 #ifdef QOS_DLS_SUPPORT
1897 if (apidx >= MIN_NET_DEVICE_FOR_DLS)
1899 pEntry->ValidAsCLI = FALSE;
1900 pEntry->ValidAsWDS = FALSE;
1901 pEntry->ValidAsApCli = FALSE;
1902 pEntry->ValidAsMesh = FALSE;
1903 pEntry->ValidAsDls = TRUE;
1904 pEntry->isCached = FALSE;
1907 #endif // QOS_DLS_SUPPORT //
1908 #endif // CONFIG_STA_SUPPORT //
1911 #ifdef CONFIG_STA_SUPPORT
1912 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1914 pEntry->ValidAsCLI = TRUE;
1915 pEntry->ValidAsWDS = FALSE;
1916 pEntry->ValidAsApCli = FALSE;
1917 pEntry->ValidAsMesh = FALSE;
1918 pEntry->ValidAsDls = FALSE;
1920 #endif // CONFIG_STA_SUPPORT //
1923 pEntry->bIAmBadAtheros = FALSE;
1925 pEntry->CMTimerRunning = FALSE;
1926 pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
1927 pEntry->RSNIE_Len = 0;
1928 NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter));
1929 pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
1931 if (pEntry->ValidAsMesh)
1932 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_MESH);
1933 else if (pEntry->ValidAsApCli)
1934 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_APCLI);
1935 else if (pEntry->ValidAsWDS)
1936 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_WDS);
1937 #ifdef CONFIG_STA_SUPPORT
1938 #ifdef QOS_DLS_SUPPORT
1939 else if (pEntry->ValidAsDls)
1940 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_DLS);
1941 #endif // QOS_DLS_SUPPORT //
1942 #endif // CONFIG_STA_SUPPORT //
1944 pEntry->apidx = apidx;
1948 #ifdef CONFIG_STA_SUPPORT
1949 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1951 pEntry->AuthMode = pAd->StaCfg.AuthMode;
1952 pEntry->WepStatus = pAd->StaCfg.WepStatus;
1953 pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1955 #endif // CONFIG_STA_SUPPORT //
1958 pEntry->GTKState = REKEY_NEGOTIATING;
1959 pEntry->PairwiseKey.KeyLen = 0;
1960 pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
1961 #ifdef CONFIG_STA_SUPPORT
1962 #ifdef QOS_DLS_SUPPORT
1963 if (pEntry->ValidAsDls == TRUE)
1964 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
1966 #endif //QOS_DLS_SUPPORT
1967 #endif // CONFIG_STA_SUPPORT //
1968 pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1969 pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
1970 COPY_MAC_ADDR(pEntry->Addr, pAddr);
1971 pEntry->Sst = SST_NOT_AUTH;
1972 pEntry->AuthState = AS_NOT_AUTH;
1973 pEntry->Aid = (USHORT)i; //0;
1974 pEntry->CapabilityInfo = 0;
1975 pEntry->PsMode = PWR_ACTIVE;
1976 pEntry->PsQIdleCount = 0;
1977 pEntry->NoDataIdleCount = 0;
1978 pEntry->ContinueTxFailCnt = 0;
1979 InitializeQueueHeader(&pEntry->PsQueue);
1982 pAd->MacTab.Size ++;
1984 // Add this entry into ASIC RX WCID search table
1985 RT28XX_STA_ENTRY_ADD(pAd, pEntry);
1989 DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertEntry - allocate entry #%d, Total= %d\n",i, pAd->MacTab.Size));
1994 // add this MAC entry into HASH table
1997 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
1998 if (pAd->MacTab.Hash[HashIdx] == NULL)
2000 pAd->MacTab.Hash[HashIdx] = pEntry;
2004 pCurrEntry = pAd->MacTab.Hash[HashIdx];
2005 while (pCurrEntry->pNext != NULL)
2006 pCurrEntry = pCurrEntry->pNext;
2007 pCurrEntry->pNext = pEntry;
2011 NdisReleaseSpinLock(&pAd->MacTabLock);
2016 ==========================================================================
2018 Delete a specified client from MAC table
2019 ==========================================================================
2021 BOOLEAN MacTableDeleteEntry(
2022 IN PRTMP_ADAPTER pAd,
2027 MAC_TABLE_ENTRY *pEntry, *pPrevEntry, *pProbeEntry;
2029 //USHORT offset; // unused variable
2030 //UCHAR j; // unused variable
2032 if (wcid >= MAX_LEN_OF_MAC_TABLE)
2035 NdisAcquireSpinLock(&pAd->MacTabLock);
2037 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
2038 //pEntry = pAd->MacTab.Hash[HashIdx];
2039 pEntry = &pAd->MacTab.Content[wcid];
2041 if (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsApCli || pEntry->ValidAsWDS || pEntry->ValidAsMesh
2042 #ifdef CONFIG_STA_SUPPORT
2043 #ifdef QOS_DLS_SUPPORT
2044 || pEntry->ValidAsDls
2045 #endif // QOS_DLS_SUPPORT //
2046 #endif // CONFIG_STA_SUPPORT //
2049 if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
2052 // Delete this entry from ASIC on-chip WCID Table
2053 RT28XX_STA_ENTRY_MAC_RESET(pAd, wcid);
2055 #ifdef DOT11_N_SUPPORT
2056 // free resources of BA
2057 BASessionTearDownALL(pAd, pEntry->Aid);
2058 #endif // DOT11_N_SUPPORT //
2062 pProbeEntry = pAd->MacTab.Hash[HashIdx];
2063 ASSERT(pProbeEntry);
2068 if (pProbeEntry == pEntry)
2070 if (pPrevEntry == NULL)
2072 pAd->MacTab.Hash[HashIdx] = pEntry->pNext;
2076 pPrevEntry->pNext = pEntry->pNext;
2081 pPrevEntry = pProbeEntry;
2082 pProbeEntry = pProbeEntry->pNext;
2083 } while (pProbeEntry);
2086 ASSERT(pProbeEntry != NULL);
2088 RT28XX_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid);
2091 if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
2093 RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
2094 pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
2098 NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
2099 pAd->MacTab.Size --;
2100 DBGPRINT(RT_DEBUG_TRACE, ("MacTableDeleteEntry1 - Total= %d\n", pAd->MacTab.Size));
2104 printk("\n%s: Impossible Wcid = %d !!!!!\n", __func__, wcid);
2108 NdisReleaseSpinLock(&pAd->MacTabLock);
2110 //Reset operating mode when no Sta.
2111 if (pAd->MacTab.Size == 0)
2113 #ifdef DOT11_N_SUPPORT
2114 pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0;
2115 #endif // DOT11_N_SUPPORT //
2116 //AsicUpdateProtect(pAd, 0 /*pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode*/, (ALLN_SETPROTECT), TRUE, 0 /*pAd->MacTab.fAnyStationNonGF*/);
2117 RT28XX_UPDATE_PROTECT(pAd); // edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
2125 ==========================================================================
2127 This routine reset the entire MAC table. All packets pending in
2128 the power-saving queues are freed here.
2129 ==========================================================================
2132 IN PRTMP_ADAPTER pAd)
2136 DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n"));
2137 //NdisAcquireSpinLock(&pAd->MacTabLock);
2139 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
2141 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
2144 #ifdef DOT11_N_SUPPORT
2145 // free resources of BA
2146 BASessionTearDownALL(pAd, i);
2147 #endif // DOT11_N_SUPPORT //
2149 pAd->MacTab.Content[i].ValidAsCLI = FALSE;
2154 NdisZeroMemory(pAd->MacTab.Content[i].Addr, 6);
2155 RT28XX_STA_ENTRY_MAC_RESET(pAd, i);
2158 //AsicDelWcidTab(pAd, i);
2166 ==========================================================================
2169 IRQL = DISPATCH_LEVEL
2171 ==========================================================================
2174 IN PRTMP_ADAPTER pAd,
2175 IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq,
2177 IN USHORT CapabilityInfo,
2179 IN USHORT ListenIntv)
2181 COPY_MAC_ADDR(AssocReq->Addr, pAddr);
2182 // Add mask to support 802.11b mode only
2183 AssocReq->CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; // not cf-pollable, not cf-poll-request
2184 AssocReq->Timeout = Timeout;
2185 AssocReq->ListenIntv = ListenIntv;
2190 ==========================================================================
2193 IRQL = DISPATCH_LEVEL
2195 ==========================================================================
2197 VOID DisassocParmFill(
2198 IN PRTMP_ADAPTER pAd,
2199 IN OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq,
2203 COPY_MAC_ADDR(DisassocReq->Addr, pAddr);
2204 DisassocReq->Reason = Reason;
2209 ========================================================================
2211 Routine Description:
2212 Check the out going frame, if this is an DHCP or ARP datagram
2213 will be duplicate another frame at low data rate transmit.
2216 pAd Pointer to our adapter
2217 pPacket Pointer to outgoing Ndis frame
2220 TRUE To be duplicate at Low data rate transmit. (1mb)
2223 IRQL = DISPATCH_LEVEL
2227 MAC header + IP Header + UDP Header
2231 00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|
2233 16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|
2236 port 0x43 means Bootstrap Protocol, server.
2237 Port 0x44 means Bootstrap Protocol, client.
2239 ========================================================================
2242 BOOLEAN RTMPCheckDHCPFrame(
2243 IN PRTMP_ADAPTER pAd,
2244 IN PNDIS_PACKET pPacket)
2246 PACKET_INFO PacketInfo;
2247 ULONG NumberOfBytesRead = 0;
2248 ULONG CurrentOffset = 0;
2249 PVOID pVirtualAddress = NULL;
2250 UINT NdisBufferLength;
2253 UCHAR ByteOffset36 = 0;
2254 UCHAR ByteOffset38 = 0;
2255 BOOLEAN ReadFirstParm = TRUE;
2257 RTMP_QueryPacketInfo(pPacket, &PacketInfo, (PUCHAR *)&pVirtualAddress, &NdisBufferLength);
2259 NumberOfBytesRead += NdisBufferLength;
2260 pSrc = (PUCHAR) pVirtualAddress;
2261 Protocol = *(pSrc + 12) * 256 + *(pSrc + 13);
2264 // Check DHCP & BOOTP protocol
2266 while (NumberOfBytesRead <= PacketInfo.TotalPacketLength)
2268 if ((NumberOfBytesRead >= 35) && (ReadFirstParm == TRUE))
2270 CurrentOffset = 35 - (NumberOfBytesRead - NdisBufferLength);
2271 ByteOffset36 = *(pSrc + CurrentOffset);
2272 ReadFirstParm = FALSE;
2275 if (NumberOfBytesRead >= 37)
2277 CurrentOffset = 37 - (NumberOfBytesRead - NdisBufferLength);
2278 ByteOffset38 = *(pSrc + CurrentOffset);
2285 // Check for DHCP & BOOTP protocol
2286 if ((ByteOffset36 != 0x44) || (ByteOffset38 != 0x43))
2289 // 2054 (hex 0806) for ARP datagrams
2290 // if this packet is not ARP datagrams, then do nothing
2291 // ARP datagrams will also be duplicate at 1mb broadcast frames
2293 if (Protocol != 0x0806 )
2301 BOOLEAN RTMPCheckEtherType(
2302 IN PRTMP_ADAPTER pAd,
2303 IN PNDIS_PACKET pPacket)
2309 UINT16 srcPort, dstPort;
2310 BOOLEAN status = TRUE;
2313 pSrcBuf = GET_OS_PKT_DATAPTR(pPacket);
2314 pktLen = GET_OS_PKT_LEN(pPacket);
2318 RTMP_SET_PACKET_SPECIFIC(pPacket, 0);
2320 // get Ethernet protocol field
2321 TypeLen = (pSrcBuf[12] << 8) + pSrcBuf[13];
2323 pSrcBuf += LENGTH_802_3; // Skip the Ethernet Header.
2325 if (TypeLen <= 1500)
2326 { // 802.3, 802.3 LLC
2328 DestMAC(6) + SrcMAC(6) + Lenght(2) +
2329 DSAP(1) + SSAP(1) + Control(1) +
2330 if the DSAP = 0xAA, SSAP=0xAA, Contorl = 0x03, it has a 5-bytes SNAP header.
2331 => + SNAP (5, OriginationID(3) + etherType(2))
2333 if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA && pSrcBuf[2] == 0x03)
2335 Sniff2BytesFromNdisBuffer(pSrcBuf, 6, &Byte0, &Byte1);
2336 RTMP_SET_PACKET_LLCSNAP(pPacket, 1);
2337 TypeLen = (USHORT)((Byte0 << 8) + Byte1);
2338 pSrcBuf += 8; // Skip this LLC/SNAP header
2342 //It just has 3-byte LLC header, maybe a legacy ether type frame. we didn't handle it.
2346 // If it's a VLAN packet, get the real Type/Length field.
2347 if (TypeLen == 0x8100)
2349 /* 0x8100 means VLAN packets */
2351 /* Dest. MAC Address (6-bytes) +
2352 Source MAC Address (6-bytes) +
2353 Length/Type = 802.1Q Tag Type (2-byte) +
2354 Tag Control Information (2-bytes) +
2355 Length / Type (2-bytes) +
2356 data payload (0-n bytes) +
2358 Frame Check Sequence (4-bytes) */
2360 RTMP_SET_PACKET_VLAN(pPacket, 1);
2361 Sniff2BytesFromNdisBuffer(pSrcBuf, 2, &Byte0, &Byte1);
2362 TypeLen = (USHORT)((Byte0 << 8) + Byte1);
2364 pSrcBuf += 4; // Skip the VLAN Header.
2371 ASSERT((pktLen > 34));
2372 if (*(pSrcBuf + 9) == 0x11)
2374 ASSERT((pktLen > 34)); // 14 for ethernet header, 20 for IP header
2376 pSrcBuf += 20; // Skip the IP header
2377 srcPort = OS_NTOHS(*((UINT16 *)pSrcBuf));
2378 dstPort = OS_NTOHS(*((UINT16 *)(pSrcBuf +2)));
2380 if ((srcPort==0x44 && dstPort==0x43) || (srcPort==0x43 && dstPort==0x44))
2381 { //It's a BOOTP/DHCP packet
2382 RTMP_SET_PACKET_DHCP(pPacket, 1);
2390 RTMP_SET_PACKET_DHCP(pPacket, 1);
2396 RTMP_SET_PACKET_EAPOL(pPacket, 1);
2410 VOID Update_Rssi_Sample(
2411 IN PRTMP_ADAPTER pAd,
2412 IN RSSI_SAMPLE *pRssi,
2413 IN PRXWI_STRUC pRxWI)
2415 CHAR rssi0 = pRxWI->RSSI0;
2416 CHAR rssi1 = pRxWI->RSSI1;
2417 CHAR rssi2 = pRxWI->RSSI2;
2421 pRssi->LastRssi0 = ConvertToRssi(pAd, (CHAR)rssi0, RSSI_0);
2422 pRssi->AvgRssi0X8 = (pRssi->AvgRssi0X8 - pRssi->AvgRssi0) + pRssi->LastRssi0;
2423 pRssi->AvgRssi0 = pRssi->AvgRssi0X8 >> 3;
2428 pRssi->LastRssi1 = ConvertToRssi(pAd, (CHAR)rssi1, RSSI_1);
2429 pRssi->AvgRssi1X8 = (pRssi->AvgRssi1X8 - pRssi->AvgRssi1) + pRssi->LastRssi1;
2430 pRssi->AvgRssi1 = pRssi->AvgRssi1X8 >> 3;
2435 pRssi->LastRssi2 = ConvertToRssi(pAd, (CHAR)rssi2, RSSI_2);
2436 pRssi->AvgRssi2X8 = (pRssi->AvgRssi2X8 - pRssi->AvgRssi2) + pRssi->LastRssi2;
2437 pRssi->AvgRssi2 = pRssi->AvgRssi2X8 >> 3;
2443 // Normal legacy Rx packet indication
2444 VOID Indicate_Legacy_Packet(
2445 IN PRTMP_ADAPTER pAd,
2447 IN UCHAR FromWhichBSSID)
2449 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
2450 UCHAR Header802_3[LENGTH_802_3];
2452 // 1. get 802.3 Header
2454 // a. pointer pRxBlk->pData to payload
2455 // b. modify pRxBlk->DataSize
2456 #ifdef CONFIG_STA_SUPPORT
2457 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2458 RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
2459 #endif // CONFIG_STA_SUPPORT //
2461 if (pRxBlk->DataSize > MAX_RX_PKT_LEN)
2464 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
2469 STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
2472 #ifdef DOT11_N_SUPPORT
2473 if (pAd->CommonCfg.bDisableReordering == 0)
2475 PBA_REC_ENTRY pBAEntry;
2477 UCHAR Wcid = pRxBlk->pRxWI->WirelessCliID;
2478 UCHAR TID = pRxBlk->pRxWI->TID;
2481 #define REORDERING_PACKET_TIMEOUT ((100 * HZ)/1000) // system ticks -- 100 ms
2483 if (Wcid < MAX_LEN_OF_MAC_TABLE)
2485 Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
2488 pBAEntry = &pAd->BATable.BARecEntry[Idx];
2489 // update last rx time
2490 NdisGetSystemUpTime(&Now32);
2491 if ((pBAEntry->list.qlen > 0) &&
2492 RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT)))
2495 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);
2496 hex_dump("Dump the legacy Packet:", GET_OS_PKT_DATAPTR(pRxBlk->pRxPacket), 64);
2497 ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
2502 #endif // DOT11_N_SUPPORT //
2505 wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
2508 // pass this 802.3 packet to upper layer or forward this packet to WM directly
2510 #ifdef CONFIG_STA_SUPPORT
2511 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2512 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxPacket, FromWhichBSSID);
2513 #endif // CONFIG_STA_SUPPORT //
2518 // Normal, AMPDU or AMSDU
2519 VOID CmmRxnonRalinkFrameIndicate(
2520 IN PRTMP_ADAPTER pAd,
2522 IN UCHAR FromWhichBSSID)
2524 #ifdef DOT11_N_SUPPORT
2525 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
2527 Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
2530 #endif // DOT11_N_SUPPORT //
2532 #ifdef DOT11_N_SUPPORT
2533 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
2536 Indicate_AMSDU_Packet(pAd, pRxBlk, FromWhichBSSID);
2539 #endif // DOT11_N_SUPPORT //
2541 Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
2547 VOID CmmRxRalinkFrameIndicate(
2548 IN PRTMP_ADAPTER pAd,
2549 IN MAC_TABLE_ENTRY *pEntry,
2551 IN UCHAR FromWhichBSSID)
2553 UCHAR Header802_3[LENGTH_802_3];
2555 UINT16 Payload1Size, Payload2Size;
2557 PNDIS_PACKET pPacket2 = NULL;
2561 Msdu2Size = *(pRxBlk->pData) + (*(pRxBlk->pData+1) << 8);
2563 if ((Msdu2Size <= 1536) && (Msdu2Size < pRxBlk->DataSize))
2565 /* skip two byte MSDU2 len */
2567 pRxBlk->DataSize -= 2;
2572 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
2576 // get 802.3 Header and remove LLC
2577 #ifdef CONFIG_STA_SUPPORT
2578 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2579 RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
2580 #endif // CONFIG_STA_SUPPORT //
2583 ASSERT(pRxBlk->pRxPacket);
2585 // Ralink Aggregation frame
2586 pAd->RalinkCounters.OneSecRxAggregationCount ++;
2587 Payload1Size = pRxBlk->DataSize - Msdu2Size;
2588 Payload2Size = Msdu2Size - LENGTH_802_3;
2590 pData2 = pRxBlk->pData + Payload1Size + LENGTH_802_3;
2591 #ifdef CONFIG_STA_SUPPORT
2592 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2593 pPacket2 = duplicate_pkt(pAd, (pData2-LENGTH_802_3), LENGTH_802_3, pData2, Payload2Size, FromWhichBSSID);
2594 #endif // CONFIG_STA_SUPPORT //
2599 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
2603 // update payload size of 1st packet
2604 pRxBlk->DataSize = Payload1Size;
2605 wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
2607 #ifdef CONFIG_STA_SUPPORT
2608 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2609 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxBlk->pRxPacket, FromWhichBSSID);
2610 #endif // CONFIG_STA_SUPPORT //
2614 #ifdef CONFIG_STA_SUPPORT
2615 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2616 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket2, FromWhichBSSID);
2617 #endif // CONFIG_STA_SUPPORT //
2622 #define RESET_FRAGFRAME(_fragFrame) \
2624 _fragFrame.RxSize = 0; \
2625 _fragFrame.Sequence = 0; \
2626 _fragFrame.LastFrag = 0; \
2627 _fragFrame.Flags = 0; \
2631 PNDIS_PACKET RTMPDeFragmentDataFrame(
2632 IN PRTMP_ADAPTER pAd,
2635 PHEADER_802_11 pHeader = pRxBlk->pHeader;
2636 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
2637 UCHAR *pData = pRxBlk->pData;
2638 USHORT DataSize = pRxBlk->DataSize;
2639 PNDIS_PACKET pRetPacket = NULL;
2640 UCHAR *pFragBuffer = NULL;
2641 BOOLEAN bReassDone = FALSE;
2642 UCHAR HeaderRoom = 0;
2647 HeaderRoom = pData - (UCHAR *)pHeader;
2649 // Re-assemble the fragmented packets
2650 if (pHeader->Frag == 0) // Frag. Number is 0 : First frag or only one pkt
2652 // the first pkt of fragment, record it.
2653 if (pHeader->FC.MoreFrag)
2655 ASSERT(pAd->FragFrame.pFragPacket);
2656 pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
2657 pAd->FragFrame.RxSize = DataSize + HeaderRoom;
2658 NdisMoveMemory(pFragBuffer, pHeader, pAd->FragFrame.RxSize);
2659 pAd->FragFrame.Sequence = pHeader->Sequence;
2660 pAd->FragFrame.LastFrag = pHeader->Frag; // Should be 0
2661 ASSERT(pAd->FragFrame.LastFrag == 0);
2662 goto done; // end of processing this frame
2665 else //Middle & End of fragment
2667 if ((pHeader->Sequence != pAd->FragFrame.Sequence) ||
2668 (pHeader->Frag != (pAd->FragFrame.LastFrag + 1)))
2670 // Fragment is not the same sequence or out of fragment number order
2671 // Reset Fragment control blk
2672 RESET_FRAGFRAME(pAd->FragFrame);
2673 DBGPRINT(RT_DEBUG_ERROR, ("Fragment is not the same sequence or out of fragment number order.\n"));
2674 goto done; // give up this frame
2676 else if ((pAd->FragFrame.RxSize + DataSize) > MAX_FRAME_SIZE)
2678 // Fragment frame is too large, it exeeds the maximum frame size.
2679 // Reset Fragment control blk
2680 RESET_FRAGFRAME(pAd->FragFrame);
2681 DBGPRINT(RT_DEBUG_ERROR, ("Fragment frame is too large, it exeeds the maximum frame size.\n"));
2682 goto done; // give up this frame
2686 // Broadcom AP(BCM94704AGR) will send out LLC in fragment's packet, LLC only can accpet at first fragment.
2687 // In this case, we will dropt it.
2689 if (NdisEqualMemory(pData, SNAP_802_1H, sizeof(SNAP_802_1H)))
2691 DBGPRINT(RT_DEBUG_ERROR, ("Find another LLC at Middle or End fragment(SN=%d, Frag=%d)\n", pHeader->Sequence, pHeader->Frag));
2692 goto done; // give up this frame
2695 pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
2697 // concatenate this fragment into the re-assembly buffer
2698 NdisMoveMemory((pFragBuffer + pAd->FragFrame.RxSize), pData, DataSize);
2699 pAd->FragFrame.RxSize += DataSize;
2700 pAd->FragFrame.LastFrag = pHeader->Frag; // Update fragment number
2703 if (pHeader->FC.MoreFrag == FALSE)
2710 // always release rx fragmented packet
2711 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
2713 // return defragmented packet if packet is reassembled completely
2714 // otherwise return NULL
2717 PNDIS_PACKET pNewFragPacket;
2719 // allocate a new packet buffer for fragment
2720 pNewFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
2724 pRetPacket = pAd->FragFrame.pFragPacket;
2725 pAd->FragFrame.pFragPacket = pNewFragPacket;
2726 pRxBlk->pHeader = (PHEADER_802_11) GET_OS_PKT_DATAPTR(pRetPacket);
2727 pRxBlk->pData = (UCHAR *)pRxBlk->pHeader + HeaderRoom;
2728 pRxBlk->DataSize = pAd->FragFrame.RxSize - HeaderRoom;
2729 pRxBlk->pRxPacket = pRetPacket;
2733 RESET_FRAGFRAME(pAd->FragFrame);
2741 VOID Indicate_AMSDU_Packet(
2742 IN PRTMP_ADAPTER pAd,
2744 IN UCHAR FromWhichBSSID)
2748 update_os_packet_info(pAd, pRxBlk, FromWhichBSSID);
2749 RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
2750 nMSDU = deaggregate_AMSDU_announce(pAd, pRxBlk->pRxPacket, pRxBlk->pData, pRxBlk->DataSize);
2753 VOID Indicate_EAPOL_Packet(
2754 IN PRTMP_ADAPTER pAd,
2756 IN UCHAR FromWhichBSSID)
2758 MAC_TABLE_ENTRY *pEntry = NULL;
2761 #ifdef CONFIG_STA_SUPPORT
2762 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2764 pEntry = &pAd->MacTab.Content[BSSID_WCID];
2765 STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
2768 #endif // CONFIG_STA_SUPPORT //
2772 DBGPRINT(RT_DEBUG_WARN, ("Indicate_EAPOL_Packet: drop and release the invalid packet.\n"));
2774 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
2779 #define BCN_TBTT_OFFSET 64 //defer 64 us
2780 VOID ReSyncBeaconTime(
2781 IN PRTMP_ADAPTER pAd)
2787 Offset = (pAd->TbttTickCount) % (BCN_TBTT_OFFSET);
2789 pAd->TbttTickCount++;
2792 // The updated BeaconInterval Value will affect Beacon Interval after two TBTT
2793 // beacasue the original BeaconInterval had been loaded into next TBTT_TIMER
2795 if (Offset == (BCN_TBTT_OFFSET-2))
2797 BCN_TIME_CFG_STRUC csr;
2798 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
2799 csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod << 4) - 1 ; // ASIC register in units of 1/16 TU = 64us
2800 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
2804 if (Offset == (BCN_TBTT_OFFSET-1))
2806 BCN_TIME_CFG_STRUC csr;
2808 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
2809 csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod) << 4; // ASIC register in units of 1/16 TU
2810 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);