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)
320 #ifdef CARRIER_DETECTION_SUPPORT
321 #endif // CARRIER_DETECTION_SUPPORT //
324 return NDIS_STATUS_FAILURE;
327 return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
331 NDIS_STATUS MlmeDataHardTransmit(
332 IN PRTMP_ADAPTER pAd,
334 IN PNDIS_PACKET pPacket)
336 if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
337 #ifdef CARRIER_DETECTION_SUPPORT
338 #endif // CARRIER_DETECTION_SUPPORT //
341 return NDIS_STATUS_FAILURE;
345 return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
353 NDIS_STATUS MlmeHardTransmitMgmtRing(
354 IN PRTMP_ADAPTER pAd,
356 IN PNDIS_PACKET pPacket)
358 PACKET_INFO PacketInfo;
361 PHEADER_802_11 pHeader_802_11;
362 BOOLEAN bAckRequired, bInsertTimestamp;
364 PTXWI_STRUC pFirstTxWI;
365 MAC_TABLE_ENTRY *pMacEntry = NULL;
367 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
369 // Make sure MGMT ring resource won't be used by other threads
370 // sample, for IRQ LOCK -> SEM LOCK
371 // IrqState = pAd->irq_disabled;
373 RTMP_SEM_LOCK(&pAd->MgmtRingLock);
376 if (pSrcBufVA == NULL)
378 // The buffer shouldn't be NULL
380 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
381 return NDIS_STATUS_FAILURE;
384 #ifdef CONFIG_STA_SUPPORT
385 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
387 // outgoing frame always wakeup PHY to prevent frame lost
388 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
389 AsicForceWakeup(pAd, TRUE);
391 #endif // CONFIG_STA_SUPPORT //
393 pFirstTxWI = (PTXWI_STRUC)(pSrcBufVA + TXINFO_SIZE);
394 pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); //TXWI_SIZE);
396 if (pHeader_802_11->Addr1[0] & 0x01)
398 MlmeRate = pAd->CommonCfg.BasicMlmeRate;
402 MlmeRate = pAd->CommonCfg.MlmeRate;
405 // Verify Mlme rate for a / g bands.
406 if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band
409 if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
410 (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))
412 pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
415 #ifdef CONFIG_STA_SUPPORT
416 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
418 // Fixed W52 with Activity scan issue in ABG_MIXED and ABGN_MIXED mode.
419 if (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED
420 #ifdef DOT11_N_SUPPORT
421 || pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED
422 #endif // DOT11_N_SUPPORT //
425 if (pAd->LatchRfRegs.Channel > 14)
426 pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
428 pAd->CommonCfg.MlmeTransmit.field.MODE = 0;
431 #endif // CONFIG_STA_SUPPORT //
434 // Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)
435 // Snice it's been set to 0 while on MgtMacHeaderInit
436 // By the way this will cause frame to be send on PWR_SAVE failed.
438 // pHeader_802_11->FC.PwrMgmt = 0; // (pAd->StaCfg.Psm == PWR_SAVE);
440 // In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
441 #ifdef CONFIG_STA_SUPPORT
442 // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
443 if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL))
445 if ((pAd->StaCfg.Psm == PWR_SAVE) &&
446 (pHeader_802_11->FC.SubType == SUBTYPE_ACTION))
447 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
449 pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
451 #endif // CONFIG_STA_SUPPORT //
453 bInsertTimestamp = FALSE;
454 if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
456 #ifdef CONFIG_STA_SUPPORT
457 //Set PM bit in ps-poll, to fix WLK 1.2 PowerSaveMode_ext failure issue.
458 if ((pAd->OpMode == OPMODE_STA) && (pHeader_802_11->FC.SubType == SUBTYPE_PS_POLL))
460 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
462 #endif // CONFIG_STA_SUPPORT //
463 bAckRequired = FALSE;
465 else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
468 //pHeader_802_11->Sequence = pAd->Sequence;
470 if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
472 bAckRequired = FALSE;
473 pHeader_802_11->Duration = 0;
478 pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
479 if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
481 bInsertTimestamp = TRUE;
486 pHeader_802_11->Sequence = pAd->Sequence++;
487 if (pAd->Sequence >0xfff)
490 // Before radar detection done, mgmt frame can not be sent but probe req
491 // Because we need to use probe req to trigger driver to send probe req in passive scan
492 if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
493 && (pAd->CommonCfg.bIEEE80211H == 1)
494 && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
496 DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
498 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
499 return (NDIS_STATUS_FAILURE);
503 RTMPFrameEndianChange(pAd, (PUCHAR)pHeader_802_11, DIR_WRITE, FALSE);
507 // fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
508 // should always has only one ohysical buffer, and the whole frame size equals
509 // to the first scatter buffer size
512 // Initialize TX Descriptor
513 // For inter-frame gap, the number is for this frame and next frame
514 // For MLME rate, we will fix as 2Mb to match other vendor's implement
515 // pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
517 // management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
518 if (pMacEntry == NULL)
520 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
521 0, RESERVED_WCID, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID_MGMT, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
525 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
526 bInsertTimestamp, FALSE, bAckRequired, FALSE,
527 0, pMacEntry->Aid, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE),
528 pMacEntry->MaxHTPhyMode.field.MCS, 0,
529 (UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
530 IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
534 RTMPWIEndianChange((PUCHAR)pFirstTxWI, TYPE_TXWI);
537 // Now do hardware-depened kick out.
538 HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen);
540 // Make sure to release MGMT ring resource
542 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
543 return NDIS_STATUS_SUCCESS;
547 /********************************************************************************
549 New DeQueue Procedures.
551 ********************************************************************************/
553 #define DEQUEUE_LOCK(lock, bIntContext, IrqFlags) \
555 if (bIntContext == FALSE) \
556 RTMP_IRQ_LOCK((lock), IrqFlags); \
559 #define DEQUEUE_UNLOCK(lock, bIntContext, IrqFlags) \
561 if (bIntContext == FALSE) \
562 RTMP_IRQ_UNLOCK((lock), IrqFlags); \
567 ========================================================================
568 Tx Path design algorithm:
569 Basically, we divide the packets into four types, Broadcast/Multicast, 11N Rate(AMPDU, AMSDU, Normal), B/G Rate(ARALINK, Normal),
570 Specific Packet Type. Following show the classification rule and policy for each kinds of packets.
571 Classification Rule=>
572 Multicast: (*addr1 & 0x01) == 0x01
573 Specific : bDHCPFrame, bARPFrame, bEAPOLFrame, etc.
574 11N Rate : If peer support HT
575 (1).AMPDU -- If TXBA is negotiated.
576 (2).AMSDU -- If AMSDU is capable for both peer and ourself.
577 *). AMSDU can embedded in a AMPDU, but now we didn't support it.
578 (3).Normal -- Other packets which send as 11n rate.
580 B/G Rate : If peer is b/g only.
581 (1).ARALINK-- If both of peer/us supprot Ralink proprietary Aggregation and the TxRate is large than RATE_6
582 (2).Normal -- Other packets which send as b/g rate.
584 The packet must be unicast, NOT A-RALINK, NOT A-MSDU, NOT 11n, then can consider about fragment.
586 Classified Packet Handle Rule=>
588 No ACK, //pTxBlk->bAckRequired = FALSE;
589 No WMM, //pTxBlk->bWMM = FALSE;
590 No piggyback, //pTxBlk->bPiggyBack = FALSE;
591 Force LowRate, //pTxBlk->bForceLowRate = TRUE;
592 Specific : Basically, for specific packet, we should handle it specifically, but now all specific packets are use
593 the same policy to handle it.
594 Force LowRate, //pTxBlk->bForceLowRate = TRUE;
597 No piggyback, //pTxBlk->bPiggyBack = FALSE;
609 ========================================================================
611 static UCHAR TxPktClassification(
612 IN RTMP_ADAPTER *pAd,
613 IN PNDIS_PACKET pPacket)
615 UCHAR TxFrameType = TX_UNKOWN_FRAME;
617 MAC_TABLE_ENTRY *pMacEntry = NULL;
618 #ifdef DOT11_N_SUPPORT
619 BOOLEAN bHTRate = FALSE;
620 #endif // DOT11_N_SUPPORT //
622 Wcid = RTMP_GET_PACKET_WCID(pPacket);
623 if (Wcid == MCAST_WCID)
624 { // Handle for RA is Broadcast/Multicast Address.
625 return TX_MCAST_FRAME;
628 // Handle for unicast packets
629 pMacEntry = &pAd->MacTab.Content[Wcid];
630 if (RTMP_GET_PACKET_LOWRATE(pPacket))
631 { // It's a specific packet need to force low rate, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame
632 TxFrameType = TX_LEGACY_FRAME;
634 #ifdef DOT11_N_SUPPORT
635 else if (IS_HT_RATE(pMacEntry))
636 { // it's a 11n capable packet
638 // Depends on HTPhyMode to check if the peer support the HTRate transmission.
639 // Currently didn't support A-MSDU embedded in A-MPDU
641 if (RTMP_GET_PACKET_MOREDATA(pPacket) || (pMacEntry->PsMode == PWR_SAVE))
642 TxFrameType = TX_LEGACY_FRAME;
643 #ifdef UAPSD_AP_SUPPORT
644 else if (RTMP_GET_PACKET_EOSP(pPacket))
645 TxFrameType = TX_LEGACY_FRAME;
646 #endif // UAPSD_AP_SUPPORT //
647 else if((pMacEntry->TXBAbitmap & (1<<(RTMP_GET_PACKET_UP(pPacket)))) != 0)
648 return TX_AMPDU_FRAME;
649 else if(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AMSDU_INUSED))
650 return TX_AMSDU_FRAME;
652 TxFrameType = TX_LEGACY_FRAME;
654 #endif // DOT11_N_SUPPORT //
656 { // it's a legacy b/g packet.
657 if ((CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE) && pAd->CommonCfg.bAggregationCapable) &&
658 (RTMP_GET_PACKET_TXRATE(pPacket) >= RATE_6) &&
659 (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
660 { // if peer support Ralink Aggregation, we use it.
661 TxFrameType = TX_RALINK_FRAME;
665 TxFrameType = TX_LEGACY_FRAME;
669 // Currently, our fragment only support when a unicast packet send as NOT-ARALINK, NOT-AMSDU and NOT-AMPDU.
670 if ((RTMP_GET_PACKET_FRAGMENTS(pPacket) > 1) && (TxFrameType == TX_LEGACY_FRAME))
671 TxFrameType = TX_FRAG_FRAME;
677 BOOLEAN RTMP_FillTxBlkInfo(
678 IN RTMP_ADAPTER *pAd,
681 PACKET_INFO PacketInfo;
682 PNDIS_PACKET pPacket;
683 PMAC_TABLE_ENTRY pMacEntry = NULL;
685 pPacket = pTxBlk->pPacket;
686 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen);
688 pTxBlk->Wcid = RTMP_GET_PACKET_WCID(pPacket);
689 pTxBlk->apidx = RTMP_GET_PACKET_IF(pPacket);
690 pTxBlk->UserPriority = RTMP_GET_PACKET_UP(pPacket);
691 pTxBlk->FrameGap = IFS_HTTXOP; // ASIC determine Frame Gap
693 if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pTxBlk->pPacket))
694 TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame);
696 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bClearEAPFrame);
698 // Default to clear this flag
699 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bForceNonQoS);
702 if (pTxBlk->Wcid == MCAST_WCID)
704 pTxBlk->pMacEntry = NULL;
706 #ifdef MCAST_RATE_SPECIFIC
707 PUCHAR pDA = GET_OS_PKT_DATAPTR(pPacket);
708 if (((*pDA & 0x01) == 0x01) && (*pDA != 0xff))
709 pTxBlk->pTransmit = &pAd->CommonCfg.MCastPhyMode;
711 #endif // MCAST_RATE_SPECIFIC //
712 pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
715 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); // AckRequired = FALSE, when broadcast packet in Adhoc mode.
716 //TX_BLK_SET_FLAG(pTxBlk, fTX_bForceLowRate);
717 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAllowFrag);
718 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
719 if (RTMP_GET_PACKET_MOREDATA(pPacket))
721 TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
727 pTxBlk->pMacEntry = &pAd->MacTab.Content[pTxBlk->Wcid];
728 pTxBlk->pTransmit = &pTxBlk->pMacEntry->HTPhyMode;
730 pMacEntry = pTxBlk->pMacEntry;
733 // For all unicast packets, need Ack unless the Ack Policy is not set as NORMAL_ACK.
734 if (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx] != NORMAL_ACK)
735 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);
737 TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired);
741 #ifdef CONFIG_STA_SUPPORT
742 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
745 // If support WMM, enable it.
746 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
747 CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))
748 TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM);
750 // if (pAd->StaCfg.bAutoTxRateSwitch)
751 // TX_BLK_SET_FLAG(pTxBlk, fTX_AutoRateSwitch);
753 #endif // CONFIG_STA_SUPPORT //
756 if (pTxBlk->TxFrameType == TX_LEGACY_FRAME)
758 if ( (RTMP_GET_PACKET_LOWRATE(pPacket)) ||
759 ((pAd->OpMode == OPMODE_AP) && (pMacEntry->MaxHTPhyMode.field.MODE == MODE_CCK) && (pMacEntry->MaxHTPhyMode.field.MCS == RATE_1)))
760 { // Specific packet, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame, need force low rate.
761 pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
762 #ifdef DOT11_N_SUPPORT
763 // Modify the WMM bit for ICV issue. If we have a packet with EOSP field need to set as 1, how to handle it???
764 if (IS_HT_STA(pTxBlk->pMacEntry) &&
765 (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RALINK_CHIPSET)) &&
766 ((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RDG_CAPABLE)))
768 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
769 TX_BLK_SET_FLAG(pTxBlk, fTX_bForceNonQoS);
771 #endif // DOT11_N_SUPPORT //
774 #ifdef DOT11_N_SUPPORT
775 if ( (IS_HT_RATE(pMacEntry) == FALSE) &&
776 (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE)))
777 { // Currently piggy-back only support when peer is operate in b/g mode.
778 TX_BLK_SET_FLAG(pTxBlk, fTX_bPiggyBack);
780 #endif // DOT11_N_SUPPORT //
782 if (RTMP_GET_PACKET_MOREDATA(pPacket))
784 TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
786 #ifdef UAPSD_AP_SUPPORT
787 if (RTMP_GET_PACKET_EOSP(pPacket))
789 TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP);
791 #endif // UAPSD_AP_SUPPORT //
793 else if (pTxBlk->TxFrameType == TX_FRAG_FRAME)
795 TX_BLK_SET_FLAG(pTxBlk, fTX_bAllowFrag);
798 pMacEntry->DebugTxCount++;
808 BOOLEAN CanDoAggregateTransmit(
809 IN RTMP_ADAPTER *pAd,
810 IN NDIS_PACKET *pPacket,
814 //printk("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType);
816 if (RTMP_GET_PACKET_WCID(pPacket) == MCAST_WCID)
819 if (RTMP_GET_PACKET_DHCP(pPacket) ||
820 RTMP_GET_PACKET_EAPOL(pPacket) ||
821 RTMP_GET_PACKET_WAI(pPacket))
824 if ((pTxBlk->TxFrameType == TX_AMSDU_FRAME) &&
825 ((pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))> (RX_BUFFER_AGGRESIZE - 100)))
826 { // For AMSDU, allow the packets with total length < max-amsdu size
830 if ((pTxBlk->TxFrameType == TX_RALINK_FRAME) &&
831 (pTxBlk->TxPacketList.Number == 2))
832 { // For RALINK-Aggregation, allow two frames in one batch.
836 #ifdef CONFIG_STA_SUPPORT
837 if ((INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) // must be unicast to AP
840 #endif // CONFIG_STA_SUPPORT //
847 ========================================================================
850 To do the enqueue operation and extract the first item of waiting
851 list. If a number of available shared memory segments could meet
852 the request of extracted item, the extracted item will be fragmented
853 into shared memory segments.
856 pAd Pointer to our adapter
857 pQueue Pointer to Waiting Queue
862 IRQL = DISPATCH_LEVEL
866 ========================================================================
868 VOID RTMPDeQueuePacket(
869 IN PRTMP_ADAPTER pAd,
870 IN BOOLEAN bIntContext,
871 IN UCHAR QIdx, /* BulkOutPipeId */
872 IN UCHAR Max_Tx_Packets)
874 PQUEUE_ENTRY pEntry = NULL;
875 PNDIS_PACKET pPacket;
876 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
878 PQUEUE_HEADER pQueue;
879 ULONG FreeNumber[NUM_OF_TX_RING];
880 UCHAR QueIdx, sQIdx, eQIdx;
881 unsigned long IrqFlags = 0;
882 BOOLEAN hasTxDesc = FALSE;
888 RtmpDiagStruct *pDiagStruct = &pAd->DiagStruct;
892 if (QIdx == NUM_OF_TX_RING)
895 //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
896 #ifdef CONFIG_STA_SUPPORT
897 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
898 eQIdx = 3; // 4 ACs, start from 0.
899 #endif // CONFIG_STA_SUPPORT //
903 sQIdx = eQIdx = QIdx;
906 for (QueIdx=sQIdx; QueIdx <= eQIdx; QueIdx++)
910 RT28XX_START_DEQUEUE(pAd, QueIdx, IrqFlags);
913 firstRound = ((QueIdx == 0) ? TRUE : FALSE);
914 #endif // DBG_DIAGNOSE //
918 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS |
919 fRTMP_ADAPTER_RADIO_OFF |
920 fRTMP_ADAPTER_RESET_IN_PROGRESS |
921 fRTMP_ADAPTER_HALT_IN_PROGRESS |
922 fRTMP_ADAPTER_NIC_NOT_EXIST))))
924 RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
928 if (Count >= Max_Tx_Packets)
931 DEQUEUE_LOCK(&pAd->irq_lock, bIntContext, IrqFlags);
932 if (&pAd->TxSwQueue[QueIdx] == NULL)
935 if (firstRound == TRUE)
936 pDiagStruct->TxSWQueCnt[pDiagStruct->ArrayCurIdx][0]++;
937 #endif // DBG_DIAGNOSE //
938 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
943 // probe the Queue Head
944 pQueue = &pAd->TxSwQueue[QueIdx];
945 if ((pEntry = pQueue->Head) == NULL)
947 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
952 NdisZeroMemory((PUCHAR)pTxBlk, sizeof(TX_BLK));
953 //InitializeQueueHeader(&pTxBlk->TxPacketList); // Didn't need it because we already memzero it.
954 pTxBlk->QueIdx = QueIdx;
956 pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
958 // Early check to make sure we have enoguh Tx Resource.
959 hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
962 pAd->PrivateInfo.TxRingFullCnt++;
964 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
969 pTxBlk->TxFrameType = TxPktClassification(pAd, pPacket);
970 pEntry = RemoveHeadQueue(pQueue);
971 pTxBlk->TotalFrameNum++;
972 pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); // The real fragment number maybe vary
973 pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
974 pTxBlk->pPacket = pPacket;
975 InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
977 if (pTxBlk->TxFrameType == TX_RALINK_FRAME || pTxBlk->TxFrameType == TX_AMSDU_FRAME)
979 // Enhance SW Aggregation Mechanism
980 if (NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, FreeNumber[QueIdx], pTxBlk->TxFrameType))
982 InsertHeadQueue(pQueue, PACKET_TO_QUEUE_ENTRY(pPacket));
983 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
988 if((pEntry = pQueue->Head) == NULL)
991 // For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation.
992 pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
993 FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
994 hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
995 if ((hasTxDesc == FALSE) || (CanDoAggregateTransmit(pAd, pPacket, pTxBlk) == FALSE))
998 //Remove the packet from the TxSwQueue and insert into pTxBlk
999 pEntry = RemoveHeadQueue(pQueue);
1001 pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
1002 pTxBlk->TotalFrameNum++;
1003 pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); // The real fragment number maybe vary
1004 pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
1005 InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
1008 if (pTxBlk->TxPacketList.Number == 1)
1009 pTxBlk->TxFrameType = TX_LEGACY_FRAME;
1013 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
1016 Count += pTxBlk->TxPacketList.Number;
1018 // Do HardTransmit now.
1019 #ifdef CONFIG_STA_SUPPORT
1020 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1021 Status = STAHardTransmit(pAd, pTxBlk, QueIdx);
1022 #endif // CONFIG_STA_SUPPORT //
1025 RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
1029 RTUSBKickBulkOut(pAd);
1033 if ((pAd->blockQueueTab[QueIdx].SwTxQueueBlockFlag == TRUE)
1034 && (pAd->TxSwQueue[QueIdx].Number < 1))
1036 releaseNetIf(&pAd->blockQueueTab[QueIdx]);
1038 #endif // BLOCK_NET_IF //
1046 ========================================================================
1048 Routine Description:
1049 Calculates the duration which is required to transmit out frames
1050 with given size and specified rate.
1053 pAd Pointer to our adapter
1055 Size Frame size in units of byte
1058 Duration number in units of usec
1060 IRQL = PASSIVE_LEVEL
1061 IRQL = DISPATCH_LEVEL
1065 ========================================================================
1067 USHORT RTMPCalcDuration(
1068 IN PRTMP_ADAPTER pAd,
1074 if (Rate < RATE_FIRST_OFDM_RATE) // CCK
1076 if ((Rate > RATE_1) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED))
1077 Duration = 96; // 72+24 preamble+plcp
1079 Duration = 192; // 144+48 preamble+plcp
1081 Duration += (USHORT)((Size << 4) / RateIdTo500Kbps[Rate]);
1082 if ((Size << 4) % RateIdTo500Kbps[Rate])
1085 else if (Rate <= RATE_LAST_OFDM_RATE)// OFDM rates
1087 Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension
1088 Duration += 4 * (USHORT)((11 + Size * 4) / RateIdTo500Kbps[Rate]);
1089 if ((11 + Size * 4) % RateIdTo500Kbps[Rate])
1094 Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension
1097 return (USHORT)Duration;
1102 ========================================================================
1104 Routine Description:
1105 Calculates the duration which is required to transmit out frames
1106 with given size and specified rate.
1109 pTxWI Pointer to head of each MPDU to HW.
1110 Ack Setting for Ack requirement bit
1111 Fragment Setting for Fragment bit
1112 RetryMode Setting for retry mode
1113 Ifs Setting for IFS gap
1114 Rate Setting for transmit rate
1115 Service Setting for service
1117 TxPreamble Short or Long preamble when using CCK rates
1118 QueIdx - 0-3, according to 802.11e/d4.4 June/2003
1123 IRQL = PASSIVE_LEVEL
1124 IRQL = DISPATCH_LEVEL
1126 See also : BASmartHardTransmit() !!!
1128 ========================================================================
1131 IN PRTMP_ADAPTER pAd,
1132 IN PTXWI_STRUC pOutTxWI,
1135 IN BOOLEAN InsTimestamp,
1138 IN BOOLEAN NSeq, // HW new a sequence.
1147 IN HTTRANSMIT_SETTING *pTransmit)
1149 PMAC_TABLE_ENTRY pMac = NULL;
1153 if (WCID < MAX_LEN_OF_MAC_TABLE)
1154 pMac = &pAd->MacTab.Content[WCID];
1157 // Always use Long preamble before verifiation short preamble functionality works well.
1158 // Todo: remove the following line if short preamble functionality works
1160 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1161 NdisZeroMemory(&TxWI, TXWI_SIZE);
1166 pTxWI->CFACK = CFACK;
1167 pTxWI->TS= InsTimestamp;
1168 pTxWI->AMPDU = AMPDU;
1170 pTxWI->txop= Txopmode;
1173 // John tune the performace with Intel Client in 20 MHz performance
1174 #ifdef DOT11_N_SUPPORT
1175 BASize = pAd->CommonCfg.TxBASize;
1179 pTxWI->BAWinSize = BASize;
1180 pTxWI->ShortGI = pTransmit->field.ShortGI;
1181 pTxWI->STBC = pTransmit->field.STBC;
1182 #endif // DOT11_N_SUPPORT //
1184 pTxWI->WirelessCliID = WCID;
1185 pTxWI->MPDUtotalByteCount = Length;
1186 pTxWI->PacketId = PID;
1188 // If CCK or OFDM, BW must be 20
1189 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1190 #ifdef DOT11N_DRAFT3
1192 pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
1193 #endif // DOT11N_DRAFT3 //
1195 pTxWI->MCS = pTransmit->field.MCS;
1196 pTxWI->PHYMODE = pTransmit->field.MODE;
1197 pTxWI->CFACK = CfAck;
1199 #ifdef DOT11_N_SUPPORT
1202 if (pAd->CommonCfg.bMIMOPSEnable)
1204 if ((pMac->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1206 // Dynamic MIMO Power Save Mode
1209 else if (pMac->MmpsMode == MMPS_STATIC)
1211 // Static MIMO Power Save Mode
1212 if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
1219 //pTxWI->MIMOps = (pMac->PsMode == PWR_MMPS)? 1:0;
1220 if (pMac->bIAmBadAtheros && (pMac->WepStatus != Ndis802_11WEPDisabled))
1222 pTxWI->MpduDensity = 7;
1226 pTxWI->MpduDensity = pMac->MpduDensity;
1229 #endif // DOT11_N_SUPPORT //
1231 pTxWI->PacketId = pTxWI->MCS;
1232 NdisMoveMemory(pOutTxWI, &TxWI, sizeof(TXWI_STRUC));
1236 VOID RTMPWriteTxWI_Data(
1237 IN PRTMP_ADAPTER pAd,
1238 IN OUT PTXWI_STRUC pTxWI,
1241 HTTRANSMIT_SETTING *pTransmit;
1242 PMAC_TABLE_ENTRY pMacEntry;
1243 #ifdef DOT11_N_SUPPORT
1245 #endif // DOT11_N_SUPPORT //
1250 pTransmit = pTxBlk->pTransmit;
1251 pMacEntry = pTxBlk->pMacEntry;
1255 // Always use Long preamble before verifiation short preamble functionality works well.
1256 // Todo: remove the following line if short preamble functionality works
1258 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1259 NdisZeroMemory(pTxWI, TXWI_SIZE);
1261 pTxWI->FRAG = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag);
1262 pTxWI->ACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAckRequired);
1263 pTxWI->txop = pTxBlk->FrameGap;
1265 #ifdef CONFIG_STA_SUPPORT
1266 #ifdef QOS_DLS_SUPPORT
1268 (pAd->StaCfg.BssType == BSS_INFRA) &&
1269 (pMacEntry->ValidAsDls == TRUE))
1270 pTxWI->WirelessCliID = BSSID_WCID;
1272 #endif // QOS_DLS_SUPPORT //
1273 #endif // CONFIG_STA_SUPPORT //
1274 pTxWI->WirelessCliID = pTxBlk->Wcid;
1276 pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
1277 pTxWI->CFACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bPiggyBack);
1279 // If CCK or OFDM, BW must be 20
1280 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1281 #ifdef DOT11_N_SUPPORT
1282 #ifdef DOT11N_DRAFT3
1284 pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
1285 #endif // DOT11N_DRAFT3 //
1286 pTxWI->AMPDU = ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) ? TRUE : FALSE);
1288 // John tune the performace with Intel Client in 20 MHz performance
1289 BASize = pAd->CommonCfg.TxBASize;
1290 if((pTxBlk->TxFrameType == TX_AMPDU_FRAME) && (pMacEntry))
1292 UCHAR RABAOriIdx = 0; //The RA's BA Originator table index.
1294 RABAOriIdx = pTxBlk->pMacEntry->BAOriWcidArray[pTxBlk->UserPriority];
1295 BASize = pAd->BATable.BAOriEntry[RABAOriIdx].BAWinSize;
1298 pTxWI->TxBF = pTransmit->field.TxBF;
1299 pTxWI->BAWinSize = BASize;
1300 pTxWI->ShortGI = pTransmit->field.ShortGI;
1301 pTxWI->STBC = pTransmit->field.STBC;
1302 #endif // DOT11_N_SUPPORT //
1304 pTxWI->MCS = pTransmit->field.MCS;
1305 pTxWI->PHYMODE = pTransmit->field.MODE;
1307 #ifdef DOT11_N_SUPPORT
1310 if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1312 // Dynamic MIMO Power Save Mode
1315 else if (pMacEntry->MmpsMode == MMPS_STATIC)
1317 // Static MIMO Power Save Mode
1318 if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
1325 if (pMacEntry->bIAmBadAtheros && (pMacEntry->WepStatus != Ndis802_11WEPDisabled))
1327 pTxWI->MpduDensity = 7;
1331 pTxWI->MpduDensity = pMacEntry->MpduDensity;
1334 #endif // DOT11_N_SUPPORT //
1337 if (pTxBlk->QueIdx== 0)
1339 pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
1340 pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
1342 #endif // DBG_DIAGNOSE //
1344 // for rate adapation
1345 pTxWI->PacketId = pTxWI->MCS;
1346 #ifdef INF_AMAZON_SE
1347 /*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate */
1348 if( RTMP_GET_PACKET_NOBULKOUT(pTxBlk->pPacket))
1350 if(pTxWI->PHYMODE == MODE_CCK)
1352 pTxWI->PacketId = 6;
1355 #endif // INF_AMAZON_SE //
1359 VOID RTMPWriteTxWI_Cache(
1360 IN PRTMP_ADAPTER pAd,
1361 IN OUT PTXWI_STRUC pTxWI,
1364 PHTTRANSMIT_SETTING /*pTxHTPhyMode,*/ pTransmit;
1365 PMAC_TABLE_ENTRY pMacEntry;
1370 pMacEntry = pTxBlk->pMacEntry;
1371 pTransmit = pTxBlk->pTransmit;
1373 //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
1374 //if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pMacEntry))
1375 //if (TX_BLK_TEST_FLAG(pTxBlk, fTX_AutoRateSwitch))
1376 if (pMacEntry->bAutoTxRateSwitch)
1378 pTxWI->txop = IFS_HTTXOP;
1380 // If CCK or OFDM, BW must be 20
1381 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1382 pTxWI->ShortGI = pTransmit->field.ShortGI;
1383 pTxWI->STBC = pTransmit->field.STBC;
1385 pTxWI->MCS = pTransmit->field.MCS;
1386 pTxWI->PHYMODE = pTransmit->field.MODE;
1388 // set PID for TxRateSwitching
1389 pTxWI->PacketId = pTransmit->field.MCS;
1392 #ifdef DOT11_N_SUPPORT
1393 pTxWI->AMPDU = ((pMacEntry->NoBADataCountDown == 0) ? TRUE: FALSE);
1396 #ifdef DOT11N_DRAFT3
1398 pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
1399 #endif // DOT11N_DRAFT3 //
1401 if (pAd->CommonCfg.bMIMOPSEnable)
1403 // MIMO Power Save Mode
1404 if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1406 // Dynamic MIMO Power Save Mode
1409 else if (pMacEntry->MmpsMode == MMPS_STATIC)
1411 // Static MIMO Power Save Mode
1412 if ((pTransmit->field.MODE >= MODE_HTMIX) && (pTransmit->field.MCS > 7))
1419 #endif // DOT11_N_SUPPORT //
1422 if (pTxBlk->QueIdx== 0)
1424 pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
1425 pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
1427 #endif // DBG_DIAGNOSE //
1429 pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
1435 ========================================================================
1437 Routine Description:
1438 Calculates the duration which is required to transmit out frames
1439 with given size and specified rate.
1442 pTxD Pointer to transmit descriptor
1443 Ack Setting for Ack requirement bit
1444 Fragment Setting for Fragment bit
1445 RetryMode Setting for retry mode
1446 Ifs Setting for IFS gap
1447 Rate Setting for transmit rate
1448 Service Setting for service
1450 TxPreamble Short or Long preamble when using CCK rates
1451 QueIdx - 0-3, according to 802.11e/d4.4 June/2003
1456 IRQL = PASSIVE_LEVEL
1457 IRQL = DISPATCH_LEVEL
1459 ========================================================================
1461 VOID RTMPWriteTxDescriptor(
1462 IN PRTMP_ADAPTER pAd,
1468 // Always use Long preamble before verifiation short preamble functionality works well.
1469 // Todo: remove the following line if short preamble functionality works
1471 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1473 pTxD->WIV = (bWIV) ? 1: 0;
1474 pTxD->QSEL= (QueueSEL);
1475 if (pAd->bGenOneHCCA == TRUE)
1476 pTxD->QSEL= FIFO_HCCA;
1481 // should be called only when -
1482 // 1. MEADIA_CONNECTED
1483 // 2. AGGREGATION_IN_USED
1484 // 3. Fragmentation not in used
1485 // 4. either no previous frame (pPrevAddr1=NULL) .OR. previoud frame is aggregatible
1486 BOOLEAN TxFrameIsAggregatible(
1487 IN PRTMP_ADAPTER pAd,
1488 IN PUCHAR pPrevAddr1,
1492 // can't aggregate EAPOL (802.1x) frame
1493 if ((p8023hdr[12] == 0x88) && (p8023hdr[13] == 0x8e))
1496 // can't aggregate multicast/broadcast frame
1497 if (p8023hdr[0] & 0x01)
1500 if (INFRA_ON(pAd)) // must be unicast to AP
1502 else if ((pPrevAddr1 == NULL) || MAC_ADDR_EQUAL(pPrevAddr1, p8023hdr)) // unicast to same STA
1510 ========================================================================
1512 Routine Description:
1513 Check the MSDU Aggregation policy
1514 1.HT aggregation is A-MSDU
1515 2.legaacy rate aggregation is software aggregation by Ralink.
1523 ========================================================================
1525 BOOLEAN PeerIsAggreOn(
1526 IN PRTMP_ADAPTER pAd,
1528 IN PMAC_TABLE_ENTRY pMacEntry)
1530 ULONG AFlags = (fCLIENT_STATUS_AMSDU_INUSED | fCLIENT_STATUS_AGGREGATION_CAPABLE);
1532 if (pMacEntry != NULL && CLIENT_STATUS_TEST_FLAG(pMacEntry, AFlags))
1534 #ifdef DOT11_N_SUPPORT
1535 if (pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
1539 #endif // DOT11_N_SUPPORT //
1541 #ifdef AGGREGATION_SUPPORT
1542 if (TxRate >= RATE_6 && pAd->CommonCfg.bAggregationCapable && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
1543 { // legacy Ralink Aggregation support
1546 #endif // AGGREGATION_SUPPORT //
1555 ========================================================================
1557 Routine Description:
1558 Check and fine the packet waiting in SW queue with highest priority
1561 pAd Pointer to our adapter
1564 pQueue Pointer to Waiting Queue
1566 IRQL = DISPATCH_LEVEL
1570 ========================================================================
1572 PQUEUE_HEADER RTMPCheckTxSwQueue(
1573 IN PRTMP_ADAPTER pAd,
1578 // 2004-11-15 to be removed. test aggregation only
1579 // if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)) && (*pNumber < 2))
1582 Number = pAd->TxSwQueue[QID_AC_BK].Number
1583 + pAd->TxSwQueue[QID_AC_BE].Number
1584 + pAd->TxSwQueue[QID_AC_VI].Number
1585 + pAd->TxSwQueue[QID_AC_VO].Number
1586 + pAd->TxSwQueue[QID_HCCA].Number;
1588 if (pAd->TxSwQueue[QID_AC_VO].Head != NULL)
1590 *pQueIdx = QID_AC_VO;
1591 return (&pAd->TxSwQueue[QID_AC_VO]);
1593 else if (pAd->TxSwQueue[QID_AC_VI].Head != NULL)
1595 *pQueIdx = QID_AC_VI;
1596 return (&pAd->TxSwQueue[QID_AC_VI]);
1598 else if (pAd->TxSwQueue[QID_AC_BE].Head != NULL)
1600 *pQueIdx = QID_AC_BE;
1601 return (&pAd->TxSwQueue[QID_AC_BE]);
1603 else if (pAd->TxSwQueue[QID_AC_BK].Head != NULL)
1605 *pQueIdx = QID_AC_BK;
1606 return (&pAd->TxSwQueue[QID_AC_BK]);
1608 else if (pAd->TxSwQueue[QID_HCCA].Head != NULL)
1610 *pQueIdx = QID_HCCA;
1611 return (&pAd->TxSwQueue[QID_HCCA]);
1614 // No packet pending in Tx Sw queue
1615 *pQueIdx = QID_AC_BK;
1623 ========================================================================
1625 Routine Description:
1626 Suspend MSDU transmission
1629 pAd Pointer to our adapter
1636 ========================================================================
1638 VOID RTMPSuspendMsduTransmission(
1639 IN PRTMP_ADAPTER pAd)
1641 DBGPRINT(RT_DEBUG_TRACE,("SCANNING, suspend MSDU transmission ...\n"));
1645 // Before BSS_SCAN_IN_PROGRESS, we need to keep Current R66 value and
1646 // use Lowbound as R66 value on ScanNextChannel(...)
1648 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1650 // set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning)
1651 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x26 + GET_LNA_GAIN(pAd)));
1652 RTMPSetAGCInitValue(pAd, BW_20);
1654 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1655 //RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x000f0000); // abort all TX rings
1660 ========================================================================
1662 Routine Description:
1663 Resume MSDU transmission
1666 pAd Pointer to our adapter
1671 IRQL = DISPATCH_LEVEL
1675 ========================================================================
1677 VOID RTMPResumeMsduTransmission(
1678 IN PRTMP_ADAPTER pAd)
1682 DBGPRINT(RT_DEBUG_TRACE,("SCAN done, resume MSDU transmission ...\n"));
1685 // After finish BSS_SCAN_IN_PROGRESS, we need to restore Current R66 value
1686 // R66 should not be 0
1687 if (pAd->BbpTuning.R66CurrentValue == 0)
1689 pAd->BbpTuning.R66CurrentValue = 0x38;
1690 DBGPRINT_ERR(("RTMPResumeMsduTransmission, R66CurrentValue=0...\n"));
1692 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, pAd->BbpTuning.R66CurrentValue);
1694 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1695 // sample, for IRQ LOCK to SEM LOCK
1696 // IrqState = pAd->irq_disabled;
1698 // RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1700 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1704 UINT deaggregate_AMSDU_announce(
1705 IN PRTMP_ADAPTER pAd,
1706 PNDIS_PACKET pPacket,
1711 USHORT SubFrameSize;
1712 PHEADER_802_3 pAMSDUsubheader;
1714 UCHAR Header802_3[14];
1716 PUCHAR pPayload, pDA, pSA, pRemovedLLCSNAP;
1717 PNDIS_PACKET pClonePacket;
1723 while (DataSize > LENGTH_802_3)
1728 //hex_dump("subheader", pData, 64);
1729 pAMSDUsubheader = (PHEADER_802_3)pData;
1730 //pData += LENGTH_802_3;
1731 PayloadSize = pAMSDUsubheader->Octet[1] + (pAMSDUsubheader->Octet[0]<<8);
1732 SubFrameSize = PayloadSize + LENGTH_802_3;
1735 if ((DataSize < SubFrameSize) || (PayloadSize > 1518 ))
1740 //printk("%d subframe: Size = %d\n", nMSDU, PayloadSize);
1742 pPayload = pData + LENGTH_802_3;
1744 pSA = pData + MAC_ADDR_LEN;
1746 // convert to 802.3 header
1747 CONVERT_TO_802_3(Header802_3, pDA, pSA, pPayload, PayloadSize, pRemovedLLCSNAP);
1749 #ifdef CONFIG_STA_SUPPORT
1750 if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E) )
1752 // avoid local heap overflow, use dyanamic allocation
1753 MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
1754 memmove(Elem->Msg+(LENGTH_802_11 + LENGTH_802_1_H), pPayload, PayloadSize);
1755 Elem->MsgLen = LENGTH_802_11 + LENGTH_802_1_H + PayloadSize;
1756 WpaEAPOLKeyAction(pAd, Elem);
1759 #endif // CONFIG_STA_SUPPORT //
1761 #ifdef CONFIG_STA_SUPPORT
1762 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1764 if (pRemovedLLCSNAP)
1766 pPayload -= LENGTH_802_3;
1767 PayloadSize += LENGTH_802_3;
1768 NdisMoveMemory(pPayload, &Header802_3[0], LENGTH_802_3);
1771 #endif // CONFIG_STA_SUPPORT //
1773 pClonePacket = ClonePacket(pAd, pPacket, pPayload, PayloadSize);
1776 #ifdef CONFIG_STA_SUPPORT
1777 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1778 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pClonePacket, RTMP_GET_PACKET_IF(pPacket));
1779 #endif // CONFIG_STA_SUPPORT //
1783 // A-MSDU has padding to multiple of 4 including subframe header.
1784 // align SubFrameSize up to multiple of 4
1785 SubFrameSize = (SubFrameSize+3)&(~0x3);
1788 if (SubFrameSize > 1528 || SubFrameSize < 32)
1793 if (DataSize > SubFrameSize)
1795 pData += SubFrameSize;
1796 DataSize -= SubFrameSize;
1805 // finally release original rx packet
1806 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1812 UINT BA_Reorder_AMSDU_Annnounce(
1813 IN PRTMP_ADAPTER pAd,
1814 IN PNDIS_PACKET pPacket)
1820 pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
1821 DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
1823 nMSDU = deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
1830 ==========================================================================
1832 Look up the MAC address in the MAC table. Return NULL if not found.
1834 pEntry - pointer to the MAC entry; NULL is not found
1835 ==========================================================================
1837 MAC_TABLE_ENTRY *MacTableLookup(
1838 IN PRTMP_ADAPTER pAd,
1842 MAC_TABLE_ENTRY *pEntry = NULL;
1844 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
1845 pEntry = pAd->MacTab.Hash[HashIdx];
1847 while (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsWDS || pEntry->ValidAsApCli || pEntry->ValidAsMesh))
1849 if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
1854 pEntry = pEntry->pNext;
1860 MAC_TABLE_ENTRY *MacTableInsertEntry(
1861 IN PRTMP_ADAPTER pAd,
1864 IN BOOLEAN CleanAll)
1868 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1873 if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
1877 #ifdef CONFIG_STA_SUPPORT
1878 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1879 if (pAd->StaCfg.BssType == BSS_INFRA)
1881 #endif // CONFIG_STA_SUPPORT //
1883 // allocate one MAC entry
1884 NdisAcquireSpinLock(&pAd->MacTabLock);
1885 for (i = FirstWcid; i< MAX_LEN_OF_MAC_TABLE; i++) // skip entry#0 so that "entry index == AID" for fast lookup
1887 // pick up the first available vacancy
1888 if ((pAd->MacTab.Content[i].ValidAsCLI == FALSE) &&
1889 (pAd->MacTab.Content[i].ValidAsWDS == FALSE) &&
1890 (pAd->MacTab.Content[i].ValidAsApCli== FALSE) &&
1891 (pAd->MacTab.Content[i].ValidAsMesh == FALSE)
1892 #ifdef CONFIG_STA_SUPPORT
1893 #ifdef QOS_DLS_SUPPORT
1894 && (pAd->MacTab.Content[i].ValidAsDls == FALSE)
1895 #endif // QOS_DLS_SUPPORT //
1896 #endif // CONFIG_STA_SUPPORT //
1899 pEntry = &pAd->MacTab.Content[i];
1900 if (CleanAll == TRUE)
1902 pEntry->MaxSupportedRate = RATE_11;
1903 pEntry->CurrTxRate = RATE_11;
1904 NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
1905 pEntry->PairwiseKey.KeyLen = 0;
1906 pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
1908 #ifdef CONFIG_STA_SUPPORT
1909 #ifdef QOS_DLS_SUPPORT
1910 if (apidx >= MIN_NET_DEVICE_FOR_DLS)
1912 pEntry->ValidAsCLI = FALSE;
1913 pEntry->ValidAsWDS = FALSE;
1914 pEntry->ValidAsApCli = FALSE;
1915 pEntry->ValidAsMesh = FALSE;
1916 pEntry->ValidAsDls = TRUE;
1917 pEntry->isCached = FALSE;
1920 #endif // QOS_DLS_SUPPORT //
1921 #endif // CONFIG_STA_SUPPORT //
1924 #ifdef CONFIG_STA_SUPPORT
1925 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1927 pEntry->ValidAsCLI = TRUE;
1928 pEntry->ValidAsWDS = FALSE;
1929 pEntry->ValidAsApCli = FALSE;
1930 pEntry->ValidAsMesh = FALSE;
1931 pEntry->ValidAsDls = FALSE;
1933 #endif // CONFIG_STA_SUPPORT //
1936 pEntry->bIAmBadAtheros = FALSE;
1938 pEntry->CMTimerRunning = FALSE;
1939 pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
1940 pEntry->RSNIE_Len = 0;
1941 NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter));
1942 pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
1944 if (pEntry->ValidAsMesh)
1945 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_MESH);
1946 else if (pEntry->ValidAsApCli)
1947 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_APCLI);
1948 else if (pEntry->ValidAsWDS)
1949 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_WDS);
1950 #ifdef CONFIG_STA_SUPPORT
1951 #ifdef QOS_DLS_SUPPORT
1952 else if (pEntry->ValidAsDls)
1953 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_DLS);
1954 #endif // QOS_DLS_SUPPORT //
1955 #endif // CONFIG_STA_SUPPORT //
1957 pEntry->apidx = apidx;
1961 #ifdef CONFIG_STA_SUPPORT
1962 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1964 pEntry->AuthMode = pAd->StaCfg.AuthMode;
1965 pEntry->WepStatus = pAd->StaCfg.WepStatus;
1966 pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1968 #endif // CONFIG_STA_SUPPORT //
1971 pEntry->GTKState = REKEY_NEGOTIATING;
1972 pEntry->PairwiseKey.KeyLen = 0;
1973 pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
1974 #ifdef CONFIG_STA_SUPPORT
1975 #ifdef QOS_DLS_SUPPORT
1976 if (pEntry->ValidAsDls == TRUE)
1977 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
1979 #endif //QOS_DLS_SUPPORT
1980 #endif // CONFIG_STA_SUPPORT //
1981 pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1982 pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
1983 COPY_MAC_ADDR(pEntry->Addr, pAddr);
1984 pEntry->Sst = SST_NOT_AUTH;
1985 pEntry->AuthState = AS_NOT_AUTH;
1986 pEntry->Aid = (USHORT)i; //0;
1987 pEntry->CapabilityInfo = 0;
1988 pEntry->PsMode = PWR_ACTIVE;
1989 pEntry->PsQIdleCount = 0;
1990 pEntry->NoDataIdleCount = 0;
1991 pEntry->ContinueTxFailCnt = 0;
1992 InitializeQueueHeader(&pEntry->PsQueue);
1995 pAd->MacTab.Size ++;
1997 // Add this entry into ASIC RX WCID search table
1998 RT28XX_STA_ENTRY_ADD(pAd, pEntry);
2002 DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertEntry - allocate entry #%d, Total= %d\n",i, pAd->MacTab.Size));
2007 // add this MAC entry into HASH table
2010 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
2011 if (pAd->MacTab.Hash[HashIdx] == NULL)
2013 pAd->MacTab.Hash[HashIdx] = pEntry;
2017 pCurrEntry = pAd->MacTab.Hash[HashIdx];
2018 while (pCurrEntry->pNext != NULL)
2019 pCurrEntry = pCurrEntry->pNext;
2020 pCurrEntry->pNext = pEntry;
2024 NdisReleaseSpinLock(&pAd->MacTabLock);
2029 ==========================================================================
2031 Delete a specified client from MAC table
2032 ==========================================================================
2034 BOOLEAN MacTableDeleteEntry(
2035 IN PRTMP_ADAPTER pAd,
2040 MAC_TABLE_ENTRY *pEntry, *pPrevEntry, *pProbeEntry;
2042 //USHORT offset; // unused variable
2043 //UCHAR j; // unused variable
2045 if (wcid >= MAX_LEN_OF_MAC_TABLE)
2048 NdisAcquireSpinLock(&pAd->MacTabLock);
2050 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
2051 //pEntry = pAd->MacTab.Hash[HashIdx];
2052 pEntry = &pAd->MacTab.Content[wcid];
2054 if (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsApCli || pEntry->ValidAsWDS || pEntry->ValidAsMesh
2055 #ifdef CONFIG_STA_SUPPORT
2056 #ifdef QOS_DLS_SUPPORT
2057 || pEntry->ValidAsDls
2058 #endif // QOS_DLS_SUPPORT //
2059 #endif // CONFIG_STA_SUPPORT //
2062 if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
2065 // Delete this entry from ASIC on-chip WCID Table
2066 RT28XX_STA_ENTRY_MAC_RESET(pAd, wcid);
2068 #ifdef DOT11_N_SUPPORT
2069 // free resources of BA
2070 BASessionTearDownALL(pAd, pEntry->Aid);
2071 #endif // DOT11_N_SUPPORT //
2075 pProbeEntry = pAd->MacTab.Hash[HashIdx];
2076 ASSERT(pProbeEntry);
2081 if (pProbeEntry == pEntry)
2083 if (pPrevEntry == NULL)
2085 pAd->MacTab.Hash[HashIdx] = pEntry->pNext;
2089 pPrevEntry->pNext = pEntry->pNext;
2094 pPrevEntry = pProbeEntry;
2095 pProbeEntry = pProbeEntry->pNext;
2096 } while (pProbeEntry);
2099 ASSERT(pProbeEntry != NULL);
2101 RT28XX_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid);
2104 if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
2106 RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
2107 pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
2111 NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
2112 pAd->MacTab.Size --;
2113 DBGPRINT(RT_DEBUG_TRACE, ("MacTableDeleteEntry1 - Total= %d\n", pAd->MacTab.Size));
2117 printk("\n%s: Impossible Wcid = %d !!!!!\n", __func__, wcid);
2121 NdisReleaseSpinLock(&pAd->MacTabLock);
2123 //Reset operating mode when no Sta.
2124 if (pAd->MacTab.Size == 0)
2126 #ifdef DOT11_N_SUPPORT
2127 pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0;
2128 #endif // DOT11_N_SUPPORT //
2129 //AsicUpdateProtect(pAd, 0 /*pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode*/, (ALLN_SETPROTECT), TRUE, 0 /*pAd->MacTab.fAnyStationNonGF*/);
2130 RT28XX_UPDATE_PROTECT(pAd); // edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
2138 ==========================================================================
2140 This routine reset the entire MAC table. All packets pending in
2141 the power-saving queues are freed here.
2142 ==========================================================================
2145 IN PRTMP_ADAPTER pAd)
2149 DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n"));
2150 //NdisAcquireSpinLock(&pAd->MacTabLock);
2152 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
2154 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
2157 #ifdef DOT11_N_SUPPORT
2158 // free resources of BA
2159 BASessionTearDownALL(pAd, i);
2160 #endif // DOT11_N_SUPPORT //
2162 pAd->MacTab.Content[i].ValidAsCLI = FALSE;
2167 NdisZeroMemory(pAd->MacTab.Content[i].Addr, 6);
2168 RT28XX_STA_ENTRY_MAC_RESET(pAd, i);
2171 //AsicDelWcidTab(pAd, i);
2179 ==========================================================================
2182 IRQL = DISPATCH_LEVEL
2184 ==========================================================================
2187 IN PRTMP_ADAPTER pAd,
2188 IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq,
2190 IN USHORT CapabilityInfo,
2192 IN USHORT ListenIntv)
2194 COPY_MAC_ADDR(AssocReq->Addr, pAddr);
2195 // Add mask to support 802.11b mode only
2196 AssocReq->CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; // not cf-pollable, not cf-poll-request
2197 AssocReq->Timeout = Timeout;
2198 AssocReq->ListenIntv = ListenIntv;
2203 ==========================================================================
2206 IRQL = DISPATCH_LEVEL
2208 ==========================================================================
2210 VOID DisassocParmFill(
2211 IN PRTMP_ADAPTER pAd,
2212 IN OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq,
2216 COPY_MAC_ADDR(DisassocReq->Addr, pAddr);
2217 DisassocReq->Reason = Reason;
2222 ========================================================================
2224 Routine Description:
2225 Check the out going frame, if this is an DHCP or ARP datagram
2226 will be duplicate another frame at low data rate transmit.
2229 pAd Pointer to our adapter
2230 pPacket Pointer to outgoing Ndis frame
2233 TRUE To be duplicate at Low data rate transmit. (1mb)
2236 IRQL = DISPATCH_LEVEL
2240 MAC header + IP Header + UDP Header
2244 00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|
2246 16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|
2249 port 0x43 means Bootstrap Protocol, server.
2250 Port 0x44 means Bootstrap Protocol, client.
2252 ========================================================================
2255 BOOLEAN RTMPCheckDHCPFrame(
2256 IN PRTMP_ADAPTER pAd,
2257 IN PNDIS_PACKET pPacket)
2259 PACKET_INFO PacketInfo;
2260 ULONG NumberOfBytesRead = 0;
2261 ULONG CurrentOffset = 0;
2262 PVOID pVirtualAddress = NULL;
2263 UINT NdisBufferLength;
2266 UCHAR ByteOffset36 = 0;
2267 UCHAR ByteOffset38 = 0;
2268 BOOLEAN ReadFirstParm = TRUE;
2270 RTMP_QueryPacketInfo(pPacket, &PacketInfo, (PUCHAR *)&pVirtualAddress, &NdisBufferLength);
2272 NumberOfBytesRead += NdisBufferLength;
2273 pSrc = (PUCHAR) pVirtualAddress;
2274 Protocol = *(pSrc + 12) * 256 + *(pSrc + 13);
2277 // Check DHCP & BOOTP protocol
2279 while (NumberOfBytesRead <= PacketInfo.TotalPacketLength)
2281 if ((NumberOfBytesRead >= 35) && (ReadFirstParm == TRUE))
2283 CurrentOffset = 35 - (NumberOfBytesRead - NdisBufferLength);
2284 ByteOffset36 = *(pSrc + CurrentOffset);
2285 ReadFirstParm = FALSE;
2288 if (NumberOfBytesRead >= 37)
2290 CurrentOffset = 37 - (NumberOfBytesRead - NdisBufferLength);
2291 ByteOffset38 = *(pSrc + CurrentOffset);
2298 // Check for DHCP & BOOTP protocol
2299 if ((ByteOffset36 != 0x44) || (ByteOffset38 != 0x43))
2302 // 2054 (hex 0806) for ARP datagrams
2303 // if this packet is not ARP datagrams, then do nothing
2304 // ARP datagrams will also be duplicate at 1mb broadcast frames
2306 if (Protocol != 0x0806 )
2314 BOOLEAN RTMPCheckEtherType(
2315 IN PRTMP_ADAPTER pAd,
2316 IN PNDIS_PACKET pPacket)
2322 UINT16 srcPort, dstPort;
2323 BOOLEAN status = TRUE;
2326 pSrcBuf = GET_OS_PKT_DATAPTR(pPacket);
2327 pktLen = GET_OS_PKT_LEN(pPacket);
2331 RTMP_SET_PACKET_SPECIFIC(pPacket, 0);
2333 // get Ethernet protocol field
2334 TypeLen = (pSrcBuf[12] << 8) + pSrcBuf[13];
2336 pSrcBuf += LENGTH_802_3; // Skip the Ethernet Header.
2338 if (TypeLen <= 1500)
2339 { // 802.3, 802.3 LLC
2341 DestMAC(6) + SrcMAC(6) + Lenght(2) +
2342 DSAP(1) + SSAP(1) + Control(1) +
2343 if the DSAP = 0xAA, SSAP=0xAA, Contorl = 0x03, it has a 5-bytes SNAP header.
2344 => + SNAP (5, OriginationID(3) + etherType(2))
2346 if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA && pSrcBuf[2] == 0x03)
2348 Sniff2BytesFromNdisBuffer(pSrcBuf, 6, &Byte0, &Byte1);
2349 RTMP_SET_PACKET_LLCSNAP(pPacket, 1);
2350 TypeLen = (USHORT)((Byte0 << 8) + Byte1);
2351 pSrcBuf += 8; // Skip this LLC/SNAP header
2355 //It just has 3-byte LLC header, maybe a legacy ether type frame. we didn't handle it.
2359 // If it's a VLAN packet, get the real Type/Length field.
2360 if (TypeLen == 0x8100)
2362 /* 0x8100 means VLAN packets */
2364 /* Dest. MAC Address (6-bytes) +
2365 Source MAC Address (6-bytes) +
2366 Length/Type = 802.1Q Tag Type (2-byte) +
2367 Tag Control Information (2-bytes) +
2368 Length / Type (2-bytes) +
2369 data payload (0-n bytes) +
2371 Frame Check Sequence (4-bytes) */
2373 RTMP_SET_PACKET_VLAN(pPacket, 1);
2374 Sniff2BytesFromNdisBuffer(pSrcBuf, 2, &Byte0, &Byte1);
2375 TypeLen = (USHORT)((Byte0 << 8) + Byte1);
2377 pSrcBuf += 4; // Skip the VLAN Header.
2384 ASSERT((pktLen > 34));
2385 if (*(pSrcBuf + 9) == 0x11)
2387 ASSERT((pktLen > 34)); // 14 for ethernet header, 20 for IP header
2389 pSrcBuf += 20; // Skip the IP header
2390 srcPort = OS_NTOHS(*((UINT16 *)pSrcBuf));
2391 dstPort = OS_NTOHS(*((UINT16 *)(pSrcBuf +2)));
2393 if ((srcPort==0x44 && dstPort==0x43) || (srcPort==0x43 && dstPort==0x44))
2394 { //It's a BOOTP/DHCP packet
2395 RTMP_SET_PACKET_DHCP(pPacket, 1);
2403 RTMP_SET_PACKET_DHCP(pPacket, 1);
2409 RTMP_SET_PACKET_EAPOL(pPacket, 1);
2423 VOID Update_Rssi_Sample(
2424 IN PRTMP_ADAPTER pAd,
2425 IN RSSI_SAMPLE *pRssi,
2426 IN PRXWI_STRUC pRxWI)
2428 CHAR rssi0 = pRxWI->RSSI0;
2429 CHAR rssi1 = pRxWI->RSSI1;
2430 CHAR rssi2 = pRxWI->RSSI2;
2434 pRssi->LastRssi0 = ConvertToRssi(pAd, (CHAR)rssi0, RSSI_0);
2435 pRssi->AvgRssi0X8 = (pRssi->AvgRssi0X8 - pRssi->AvgRssi0) + pRssi->LastRssi0;
2436 pRssi->AvgRssi0 = pRssi->AvgRssi0X8 >> 3;
2441 pRssi->LastRssi1 = ConvertToRssi(pAd, (CHAR)rssi1, RSSI_1);
2442 pRssi->AvgRssi1X8 = (pRssi->AvgRssi1X8 - pRssi->AvgRssi1) + pRssi->LastRssi1;
2443 pRssi->AvgRssi1 = pRssi->AvgRssi1X8 >> 3;
2448 pRssi->LastRssi2 = ConvertToRssi(pAd, (CHAR)rssi2, RSSI_2);
2449 pRssi->AvgRssi2X8 = (pRssi->AvgRssi2X8 - pRssi->AvgRssi2) + pRssi->LastRssi2;
2450 pRssi->AvgRssi2 = pRssi->AvgRssi2X8 >> 3;
2456 // Normal legacy Rx packet indication
2457 VOID Indicate_Legacy_Packet(
2458 IN PRTMP_ADAPTER pAd,
2460 IN UCHAR FromWhichBSSID)
2462 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
2463 UCHAR Header802_3[LENGTH_802_3];
2465 // 1. get 802.3 Header
2467 // a. pointer pRxBlk->pData to payload
2468 // b. modify pRxBlk->DataSize
2469 #ifdef CONFIG_STA_SUPPORT
2470 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2471 RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
2472 #endif // CONFIG_STA_SUPPORT //
2474 if (pRxBlk->DataSize > MAX_RX_PKT_LEN)
2477 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
2482 STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
2485 #ifdef DOT11_N_SUPPORT
2486 if (pAd->CommonCfg.bDisableReordering == 0)
2488 PBA_REC_ENTRY pBAEntry;
2490 UCHAR Wcid = pRxBlk->pRxWI->WirelessCliID;
2491 UCHAR TID = pRxBlk->pRxWI->TID;
2494 #define REORDERING_PACKET_TIMEOUT ((100 * HZ)/1000) // system ticks -- 100 ms
2496 if (Wcid < MAX_LEN_OF_MAC_TABLE)
2498 Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
2501 pBAEntry = &pAd->BATable.BARecEntry[Idx];
2502 // update last rx time
2503 NdisGetSystemUpTime(&Now32);
2504 if ((pBAEntry->list.qlen > 0) &&
2505 RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT)))
2508 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);
2509 hex_dump("Dump the legacy Packet:", GET_OS_PKT_DATAPTR(pRxBlk->pRxPacket), 64);
2510 ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
2515 #endif // DOT11_N_SUPPORT //
2518 wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
2521 // pass this 802.3 packet to upper layer or forward this packet to WM directly
2523 #ifdef CONFIG_STA_SUPPORT
2524 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2525 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxPacket, FromWhichBSSID);
2526 #endif // CONFIG_STA_SUPPORT //
2531 // Normal, AMPDU or AMSDU
2532 VOID CmmRxnonRalinkFrameIndicate(
2533 IN PRTMP_ADAPTER pAd,
2535 IN UCHAR FromWhichBSSID)
2537 #ifdef DOT11_N_SUPPORT
2538 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
2540 Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
2543 #endif // DOT11_N_SUPPORT //
2545 #ifdef DOT11_N_SUPPORT
2546 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
2549 Indicate_AMSDU_Packet(pAd, pRxBlk, FromWhichBSSID);
2552 #endif // DOT11_N_SUPPORT //
2554 Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
2560 VOID CmmRxRalinkFrameIndicate(
2561 IN PRTMP_ADAPTER pAd,
2562 IN MAC_TABLE_ENTRY *pEntry,
2564 IN UCHAR FromWhichBSSID)
2566 UCHAR Header802_3[LENGTH_802_3];
2568 UINT16 Payload1Size, Payload2Size;
2570 PNDIS_PACKET pPacket2 = NULL;
2574 Msdu2Size = *(pRxBlk->pData) + (*(pRxBlk->pData+1) << 8);
2576 if ((Msdu2Size <= 1536) && (Msdu2Size < pRxBlk->DataSize))
2578 /* skip two byte MSDU2 len */
2580 pRxBlk->DataSize -= 2;
2585 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
2589 // get 802.3 Header and remove LLC
2590 #ifdef CONFIG_STA_SUPPORT
2591 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2592 RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
2593 #endif // CONFIG_STA_SUPPORT //
2596 ASSERT(pRxBlk->pRxPacket);
2598 // Ralink Aggregation frame
2599 pAd->RalinkCounters.OneSecRxAggregationCount ++;
2600 Payload1Size = pRxBlk->DataSize - Msdu2Size;
2601 Payload2Size = Msdu2Size - LENGTH_802_3;
2603 pData2 = pRxBlk->pData + Payload1Size + LENGTH_802_3;
2604 #ifdef CONFIG_STA_SUPPORT
2605 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2606 pPacket2 = duplicate_pkt(pAd, (pData2-LENGTH_802_3), LENGTH_802_3, pData2, Payload2Size, FromWhichBSSID);
2607 #endif // CONFIG_STA_SUPPORT //
2612 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
2616 // update payload size of 1st packet
2617 pRxBlk->DataSize = Payload1Size;
2618 wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
2620 #ifdef CONFIG_STA_SUPPORT
2621 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2622 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxBlk->pRxPacket, FromWhichBSSID);
2623 #endif // CONFIG_STA_SUPPORT //
2627 #ifdef CONFIG_STA_SUPPORT
2628 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2629 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket2, FromWhichBSSID);
2630 #endif // CONFIG_STA_SUPPORT //
2635 #define RESET_FRAGFRAME(_fragFrame) \
2637 _fragFrame.RxSize = 0; \
2638 _fragFrame.Sequence = 0; \
2639 _fragFrame.LastFrag = 0; \
2640 _fragFrame.Flags = 0; \
2644 PNDIS_PACKET RTMPDeFragmentDataFrame(
2645 IN PRTMP_ADAPTER pAd,
2648 PHEADER_802_11 pHeader = pRxBlk->pHeader;
2649 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
2650 UCHAR *pData = pRxBlk->pData;
2651 USHORT DataSize = pRxBlk->DataSize;
2652 PNDIS_PACKET pRetPacket = NULL;
2653 UCHAR *pFragBuffer = NULL;
2654 BOOLEAN bReassDone = FALSE;
2655 UCHAR HeaderRoom = 0;
2660 HeaderRoom = pData - (UCHAR *)pHeader;
2662 // Re-assemble the fragmented packets
2663 if (pHeader->Frag == 0) // Frag. Number is 0 : First frag or only one pkt
2665 // the first pkt of fragment, record it.
2666 if (pHeader->FC.MoreFrag)
2668 ASSERT(pAd->FragFrame.pFragPacket);
2669 pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
2670 pAd->FragFrame.RxSize = DataSize + HeaderRoom;
2671 NdisMoveMemory(pFragBuffer, pHeader, pAd->FragFrame.RxSize);
2672 pAd->FragFrame.Sequence = pHeader->Sequence;
2673 pAd->FragFrame.LastFrag = pHeader->Frag; // Should be 0
2674 ASSERT(pAd->FragFrame.LastFrag == 0);
2675 goto done; // end of processing this frame
2678 else //Middle & End of fragment
2680 if ((pHeader->Sequence != pAd->FragFrame.Sequence) ||
2681 (pHeader->Frag != (pAd->FragFrame.LastFrag + 1)))
2683 // Fragment is not the same sequence or out of fragment number order
2684 // Reset Fragment control blk
2685 RESET_FRAGFRAME(pAd->FragFrame);
2686 DBGPRINT(RT_DEBUG_ERROR, ("Fragment is not the same sequence or out of fragment number order.\n"));
2687 goto done; // give up this frame
2689 else if ((pAd->FragFrame.RxSize + DataSize) > MAX_FRAME_SIZE)
2691 // Fragment frame is too large, it exeeds the maximum frame size.
2692 // Reset Fragment control blk
2693 RESET_FRAGFRAME(pAd->FragFrame);
2694 DBGPRINT(RT_DEBUG_ERROR, ("Fragment frame is too large, it exeeds the maximum frame size.\n"));
2695 goto done; // give up this frame
2699 // Broadcom AP(BCM94704AGR) will send out LLC in fragment's packet, LLC only can accpet at first fragment.
2700 // In this case, we will dropt it.
2702 if (NdisEqualMemory(pData, SNAP_802_1H, sizeof(SNAP_802_1H)))
2704 DBGPRINT(RT_DEBUG_ERROR, ("Find another LLC at Middle or End fragment(SN=%d, Frag=%d)\n", pHeader->Sequence, pHeader->Frag));
2705 goto done; // give up this frame
2708 pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
2710 // concatenate this fragment into the re-assembly buffer
2711 NdisMoveMemory((pFragBuffer + pAd->FragFrame.RxSize), pData, DataSize);
2712 pAd->FragFrame.RxSize += DataSize;
2713 pAd->FragFrame.LastFrag = pHeader->Frag; // Update fragment number
2716 if (pHeader->FC.MoreFrag == FALSE)
2723 // always release rx fragmented packet
2724 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
2726 // return defragmented packet if packet is reassembled completely
2727 // otherwise return NULL
2730 PNDIS_PACKET pNewFragPacket;
2732 // allocate a new packet buffer for fragment
2733 pNewFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
2737 pRetPacket = pAd->FragFrame.pFragPacket;
2738 pAd->FragFrame.pFragPacket = pNewFragPacket;
2739 pRxBlk->pHeader = (PHEADER_802_11) GET_OS_PKT_DATAPTR(pRetPacket);
2740 pRxBlk->pData = (UCHAR *)pRxBlk->pHeader + HeaderRoom;
2741 pRxBlk->DataSize = pAd->FragFrame.RxSize - HeaderRoom;
2742 pRxBlk->pRxPacket = pRetPacket;
2746 RESET_FRAGFRAME(pAd->FragFrame);
2754 VOID Indicate_AMSDU_Packet(
2755 IN PRTMP_ADAPTER pAd,
2757 IN UCHAR FromWhichBSSID)
2761 update_os_packet_info(pAd, pRxBlk, FromWhichBSSID);
2762 RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
2763 nMSDU = deaggregate_AMSDU_announce(pAd, pRxBlk->pRxPacket, pRxBlk->pData, pRxBlk->DataSize);
2766 VOID Indicate_EAPOL_Packet(
2767 IN PRTMP_ADAPTER pAd,
2769 IN UCHAR FromWhichBSSID)
2771 MAC_TABLE_ENTRY *pEntry = NULL;
2774 #ifdef CONFIG_STA_SUPPORT
2775 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2777 pEntry = &pAd->MacTab.Content[BSSID_WCID];
2778 STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
2781 #endif // CONFIG_STA_SUPPORT //
2785 DBGPRINT(RT_DEBUG_WARN, ("Indicate_EAPOL_Packet: drop and release the invalid packet.\n"));
2787 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
2792 #define BCN_TBTT_OFFSET 64 //defer 64 us
2793 VOID ReSyncBeaconTime(
2794 IN PRTMP_ADAPTER pAd)
2800 Offset = (pAd->TbttTickCount) % (BCN_TBTT_OFFSET);
2802 pAd->TbttTickCount++;
2805 // The updated BeaconInterval Value will affect Beacon Interval after two TBTT
2806 // beacasue the original BeaconInterval had been loaded into next TBTT_TIMER
2808 if (Offset == (BCN_TBTT_OFFSET-2))
2810 BCN_TIME_CFG_STRUC csr;
2811 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
2812 csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod << 4) - 1 ; // ASIC register in units of 1/16 TU = 64us
2813 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
2817 if (Offset == (BCN_TBTT_OFFSET-1))
2819 BCN_TIME_CFG_STRUC csr;
2821 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
2822 csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod) << 4; // ASIC register in units of 1/16 TU
2823 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);