UCHAR RateSwitchTable11N1S[] = {
// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
- 0x09, 0x00, 0, 0, 0, // Initial used item after association
- 0x00, 0x21, 0, 30, 101,
- 0x01, 0x21, 1, 20, 50,
- 0x02, 0x21, 2, 20, 50,
- 0x03, 0x21, 3, 15, 50,
- 0x04, 0x21, 4, 15, 30,
- 0x05, 0x21, 5, 10, 25,
- 0x06, 0x21, 6, 8, 14,
- 0x07, 0x21, 7, 8, 14,
- 0x08, 0x23, 7, 8, 14,
+ 0x0c, 0x0a, 0, 0, 0, // Initial used item after association
+ 0x00, 0x00, 0, 40, 101,
+ 0x01, 0x00, 1, 40, 50,
+ 0x02, 0x00, 2, 25, 45,
+ 0x03, 0x21, 0, 20, 35,
+ 0x04, 0x21, 1, 20, 35,
+ 0x05, 0x21, 2, 20, 35,
+ 0x06, 0x21, 3, 15, 35,
+ 0x07, 0x21, 4, 15, 30,
+ 0x08, 0x21, 5, 10, 25,
+ 0x09, 0x21, 6, 8, 14,
+ 0x0a, 0x21, 7, 8, 14,
+ 0x0b, 0x23, 7, 8, 14,
};
UCHAR RateSwitchTable11N2S[] = {
// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
- 0x0a, 0x00, 0, 0, 0, // Initial used item after association
- 0x00, 0x21, 0, 30, 101,
- 0x01, 0x21, 1, 20, 50,
- 0x02, 0x21, 2, 20, 50,
- 0x03, 0x21, 3, 15, 50,
- 0x04, 0x21, 4, 15, 30,
- 0x05, 0x20, 12, 15, 30,
- 0x06, 0x20, 13, 8, 20,
- 0x07, 0x20, 14, 8, 20,
- 0x08, 0x20, 15, 8, 25,
- 0x09, 0x22, 15, 8, 25,
+ 0x0e, 0x0c, 0, 0, 0, // Initial used item after association
+ 0x00, 0x00, 0, 40, 101,
+ 0x01, 0x00, 1, 40, 50,
+ 0x02, 0x00, 2, 25, 45,
+ 0x03, 0x21, 0, 20, 35,
+ 0x04, 0x21, 1, 20, 35,
+ 0x05, 0x21, 2, 20, 35,
+ 0x06, 0x21, 3, 15, 35,
+ 0x07, 0x21, 4, 15, 30,
+ 0x08, 0x20, 11, 15, 30,
+ 0x09, 0x20, 12, 15, 30,
+ 0x0a, 0x20, 13, 8, 20,
+ 0x0b, 0x20, 14, 8, 20,
+ 0x0c, 0x20, 15, 8, 25,
+ 0x0d, 0x22, 15, 8, 15,
};
UCHAR RateSwitchTable11N3S[] = {
// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
- 0x0a, 0x00, 0, 0, 0, // Initial used item after association
+ 0x0b, 0x00, 0, 0, 0, // 0x0a, 0x00, 0, 0, 0, // Initial used item after association
0x00, 0x21, 0, 30, 101,
0x01, 0x21, 1, 20, 50,
0x02, 0x21, 2, 20, 50,
0x03, 0x21, 3, 15, 50,
0x04, 0x21, 4, 15, 30,
- 0x05, 0x20, 12, 15, 30,
- 0x06, 0x20, 13, 8, 20,
- 0x07, 0x20, 14, 8, 20,
- 0x08, 0x20, 15, 8, 25,
- 0x09, 0x22, 15, 8, 25,
+ 0x05, 0x20, 11, 15, 30, // Required by System-Alan @ 20080812
+ 0x06, 0x20, 12, 15, 30, // 0x05, 0x20, 12, 15, 30,
+ 0x07, 0x20, 13, 8, 20, // 0x06, 0x20, 13, 8, 20,
+ 0x08, 0x20, 14, 8, 20, // 0x07, 0x20, 14, 8, 20,
+ 0x09, 0x20, 15, 8, 25, // 0x08, 0x20, 15, 8, 25,
+ 0x0a, 0x22, 15, 8, 25, // 0x09, 0x22, 15, 8, 25,
};
UCHAR RateSwitchTable11N2SForABand[] = {
UCHAR RateSwitchTable11BGN1S[] = {
// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
- 0x0d, 0x00, 0, 0, 0, // Initial used item after association
+ 0x0c, 0x0a, 0, 0, 0, // Initial used item after association
0x00, 0x00, 0, 40, 101,
0x01, 0x00, 1, 40, 50,
- 0x02, 0x00, 2, 35, 45,
- 0x03, 0x00, 3, 20, 45,
- 0x04, 0x21, 0, 30,101, //50
- 0x05, 0x21, 1, 20, 50,
- 0x06, 0x21, 2, 20, 50,
- 0x07, 0x21, 3, 15, 50,
- 0x08, 0x21, 4, 15, 30,
- 0x09, 0x21, 5, 10, 25,
- 0x0a, 0x21, 6, 8, 14,
- 0x0b, 0x21, 7, 8, 14,
- 0x0c, 0x23, 7, 8, 14,
+ 0x02, 0x00, 2, 25, 45,
+ 0x03, 0x21, 0, 20, 35,
+ 0x04, 0x21, 1, 20, 35,
+ 0x05, 0x21, 2, 20, 35,
+ 0x06, 0x21, 3, 15, 35,
+ 0x07, 0x21, 4, 15, 30,
+ 0x08, 0x21, 5, 10, 25,
+ 0x09, 0x21, 6, 8, 14,
+ 0x0a, 0x21, 7, 8, 14,
+ 0x0b, 0x23, 7, 8, 14,
};
UCHAR RateSwitchTable11BGN2S[] = {
// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
- 0x0a, 0x00, 0, 0, 0, // Initial used item after association
- 0x00, 0x21, 0, 30,101, //50
- 0x01, 0x21, 1, 20, 50,
- 0x02, 0x21, 2, 20, 50,
- 0x03, 0x21, 3, 15, 50,
- 0x04, 0x21, 4, 15, 30,
- 0x05, 0x20, 12, 15, 30,
- 0x06, 0x20, 13, 8, 20,
- 0x07, 0x20, 14, 8, 20,
- 0x08, 0x20, 15, 8, 25,
- 0x09, 0x22, 15, 8, 25,
+ 0x0e, 0x0c, 0, 0, 0, // Initial used item after association
+ 0x00, 0x00, 0, 40, 101,
+ 0x01, 0x00, 1, 40, 50,
+ 0x02, 0x00, 2, 25, 45,
+ 0x03, 0x21, 0, 20, 35,
+ 0x04, 0x21, 1, 20, 35,
+ 0x05, 0x21, 2, 20, 35,
+ 0x06, 0x21, 3, 15, 35,
+ 0x07, 0x21, 4, 15, 30,
+ 0x08, 0x20, 11, 15, 30,
+ 0x09, 0x20, 12, 15, 30,
+ 0x0a, 0x20, 13, 8, 20,
+ 0x0b, 0x20, 14, 8, 20,
+ 0x0c, 0x20, 15, 8, 25,
+ 0x0d, 0x22, 15, 8, 15,
};
UCHAR RateSwitchTable11BGN3S[] = { // 3*3
0x0b, 0x22, 23, 8, 25,
};
-PUCHAR ReasonString[] = {
- /* 0 */ "Reserved",
- /* 1 */ "Unspecified Reason",
- /* 2 */ "Previous Auth no longer valid",
- /* 3 */ "STA is leaving / has left",
- /* 4 */ "DIS-ASSOC due to inactivity",
- /* 5 */ "AP unable to hanle all associations",
- /* 6 */ "class 2 error",
- /* 7 */ "class 3 error",
- /* 8 */ "STA is leaving / has left",
- /* 9 */ "require auth before assoc/re-assoc",
- /* 10 */ "Reserved",
- /* 11 */ "Reserved",
- /* 12 */ "Reserved",
- /* 13 */ "invalid IE",
- /* 14 */ "MIC error",
- /* 15 */ "4-way handshake timeout",
- /* 16 */ "2-way (group key) handshake timeout",
- /* 17 */ "4-way handshake IE diff among AssosReq/Rsp/Beacon",
- /* 18 */
-};
extern UCHAR OfdmRateToRxwiMCS[];
// since RT61 has better RX sensibility, we have to limit TX ACK rate not to exceed our normal data TX rate.
0xfffff01f /* 6 */ , 0xfffff03f /* 9 */ , 0xfffff07f /* 12 */ , 0xfffff0ff /* 18 */,
0xfffff1ff /* 24 */ , 0xfffff3ff /* 36 */ , 0xfffff7ff /* 48 */ , 0xffffffff /* 54 */};
-UCHAR MULTICAST_ADDR[MAC_ADDR_LEN] = {0x1, 0x00, 0x00, 0x00, 0x00, 0x00};
UCHAR BROADCAST_ADDR[MAC_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
UCHAR WpaIe = IE_WPA;
UCHAR Wpa2Ie = IE_WPA2;
UCHAR IbssIe = IE_IBSS_PARM;
-UCHAR Ccx2Ie = IE_CCX_V2;
extern UCHAR WPA_OUI[];
UCHAR ZeroSsid[32] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
-// Reset the RFIC setting to new series
-RTMP_RF_REGS RF2850RegTable[] = {
-// ch R1 R2 R3(TX0~4=0) R4
- {1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b},
- {2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f},
- {3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b},
- {4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f},
- {5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b},
- {6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f},
- {7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b},
- {8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f},
- {9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b},
- {10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f},
- {11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b},
- {12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f},
- {13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b},
- {14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193},
-
- // 802.11 UNI / HyperLan 2
- {36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3},
- {38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193},
- {40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183},
- {44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3},
- {46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b},
- {48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b},
- {52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193},
- {54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3},
- {56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b},
- {60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183},
- {62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193},
- {64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3}, // Plugfest#4, Day4, change RFR3 left4th 9->5.
-
- // 802.11 HyperLan 2
- {100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783},
-
- // 2008.04.30 modified
- // The system team has AN to improve the EVM value
- // for channel 102 to 108 for the RT2850/RT2750 dual band solution.
- {102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793},
- {104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3},
- {108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193},
-
- {110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183},
- {112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b},
- {116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3},
- {118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193},
- {120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183},
- {124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193},
- {126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}, // 0x980ed1bb->0x980ed15b required by Rory 20070927
- {128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3},
- {132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b},
- {134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193},
- {136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b},
- {140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183},
-
- // 802.11 UNII
- {149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7},
- {151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187},
- {153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f},
- {157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f},
- {159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7},
- {161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187},
- {165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197},
-
- // Japan
- {184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b},
- {188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13},
- {192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b},
- {196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23},
- {208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13},
- {212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b},
- {216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23},
-
- // still lack of MMAC(Japan) ch 34,38,42,46
-};
-UCHAR NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(RTMP_RF_REGS));
-
-FREQUENCY_ITEM FreqItems3020[] =
-{
- /**************************************************/
- // ISM : 2.4 to 2.483 GHz //
- /**************************************************/
- // 11g
- /**************************************************/
- //-CH---N-------R---K-----------
- {1, 241, 2, 2},
- {2, 241, 2, 7},
- {3, 242, 2, 2},
- {4, 242, 2, 7},
- {5, 243, 2, 2},
- {6, 243, 2, 7},
- {7, 244, 2, 2},
- {8, 244, 2, 7},
- {9, 245, 2, 2},
- {10, 245, 2, 7},
- {11, 246, 2, 2},
- {12, 246, 2, 7},
- {13, 247, 2, 2},
- {14, 248, 2, 4},
-};
-UCHAR NUM_OF_3020_CHNL=(sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM));
/*
==========================================================================
AuthStateMachineInit(pAd, &pAd->Mlme.AuthMachine, pAd->Mlme.AuthFunc);
AuthRspStateMachineInit(pAd, &pAd->Mlme.AuthRspMachine, pAd->Mlme.AuthRspFunc);
SyncStateMachineInit(pAd, &pAd->Mlme.SyncMachine, pAd->Mlme.SyncFunc);
- WpaPskStateMachineInit(pAd, &pAd->Mlme.WpaPskMachine, pAd->Mlme.WpaPskFunc);
- AironetStateMachineInit(pAd, &pAd->Mlme.AironetMachine, pAd->Mlme.AironetFunc);
+
+
+
// Since we are using switch/case to implement it, the init is different from the above
// state machine init
MlmeCntlInit(pAd, &pAd->Mlme.CntlMachine, NULL);
}
+
+ WpaStateMachineInit(pAd, &pAd->Mlme.WpaMachine, pAd->Mlme.WpaFunc);
+
+
ActionStateMachineInit(pAd, &pAd->Mlme.ActMachine, pAd->Mlme.ActFunc);
// Init mlme periodic timer
// software-based RX Antenna diversity
RTMPInitTimer(pAd, &pAd->Mlme.RxAntEvalTimer, GET_TIMER_FUNCTION(AsicRxAntEvalTimeout), pAd, FALSE);
-#ifdef RT2860
{
+#ifdef RTMP_PCI_SUPPORT
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
{
// only PCIe cards need these two timers
RTMPInitTimer(pAd, &pAd->Mlme.PsPollTimer, GET_TIMER_FUNCTION(PsPollWakeExec), pAd, FALSE);
RTMPInitTimer(pAd, &pAd->Mlme.RadioOnOffTimer, GET_TIMER_FUNCTION(RadioOnExec), pAd, FALSE);
}
+#endif // RTMP_PCI_SUPPORT //
+
+ RTMPInitTimer(pAd, &pAd->Mlme.LinkDownTimer, GET_TIMER_FUNCTION(LinkDownExec), pAd, FALSE);
+
+#ifdef RTMP_MAC_USB
+ RTMPInitTimer(pAd, &pAd->Mlme.AutoWakeupTimer, GET_TIMER_FUNCTION(RtmpUsbStaAsicForceWakeupTimeout), pAd, FALSE);
+ pAd->Mlme.AutoWakeupTimerRunning = FALSE;
+#endif // RTMP_MAC_USB //
}
-#endif
+
} while (FALSE);
DBGPRINT(RT_DEBUG_TRACE, ("<-- MLME Initialize\n"));
//From message type, determine which state machine I should drive
if (MlmeDequeue(&pAd->Mlme.Queue, &Elem))
{
-#ifdef RT2870
+#ifdef RTMP_MAC_USB
if (Elem->MsgType == MT2_RESET_CONF)
{
DBGPRINT_RAW(RT_DEBUG_TRACE, ("!!! reset MLME state machine !!!\n"));
Elem->MsgLen = 0;
continue;
}
-#endif // RT2870 //
+#endif // RTMP_MAC_USB //
// if dequeue success
switch (Elem->Machine)
case WPA_PSK_STATE_MACHINE:
StateMachinePerformAction(pAd, &pAd->Mlme.WpaPskMachine, Elem);
break;
- case AIRONET_STATE_MACHINE:
- StateMachinePerformAction(pAd, &pAd->Mlme.AironetMachine, Elem);
- break;
+
+
+
case ACTION_STATE_MACHINE:
StateMachinePerformAction(pAd, &pAd->Mlme.ActMachine, Elem);
break;
-
+ case WPA_STATE_MACHINE:
+ StateMachinePerformAction(pAd, &pAd->Mlme.WpaMachine, Elem);
+ break;
default:
IN PRTMP_ADAPTER pAd)
{
BOOLEAN Cancelled;
-#ifdef RT3070
- UINT32 TxPinCfg = 0x00050F0F;
-#endif // RT3070 //
DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeHalt\n"));
RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
-#ifdef RT2860
+
+
+#ifdef RTMP_MAC_PCI
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
{
RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled);
}
-#endif
+#endif // RTMP_MAC_PCI //
+
+ RTMPCancelTimer(&pAd->Mlme.LinkDownTimer, &Cancelled);
+
+#ifdef RTMP_MAC_USB
+ RTMPCancelTimer(&pAd->Mlme.AutoWakeupTimer, &Cancelled);
+#endif // RTMP_MAC_USB //
}
RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);
if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
{
+ RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
+
// Set LED
RTMPSetLED(pAd, LED_HALT);
RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
-#ifdef RT2870
+#ifdef RTMP_MAC_USB
{
LED_CFG_STRUC LedCfg;
RTMP_IO_READ32(pAd, LED_CFG, &LedCfg.word);
LedCfg.field.YLedMode = 0;
RTMP_IO_WRITE32(pAd, LED_CFG, LedCfg.word);
}
-#endif // RT2870 //
-#ifdef RT3070
- //
- // Turn off LNA_PE
- //
- if (IS_RT3070(pAd) || IS_RT3071(pAd))
- {
- TxPinCfg &= 0xFFFFF0F0;
- RTUSBWriteMACRegister(pAd, TX_PIN_CFG, TxPinCfg);
- }
-#endif // RT3070 //
+#endif // RTMP_MAC_USB //
+
+ if (pChipOps->AsicHaltAction)
+ pChipOps->AsicHaltAction(pAd);
}
RTMPusecDelay(5000); // 5 msec to gurantee Ant Diversity timer canceled
pAd->RalinkCounters.OneSecTxNoRetryOkCount = 0;
pAd->RalinkCounters.OneSecTxRetryOkCount = 0;
pAd->RalinkCounters.OneSecRxOkDataCnt = 0;
+ pAd->RalinkCounters.OneSecReceivedByteCount = 0;
+ pAd->RalinkCounters.OneSecTransmittedByteCount = 0;
// TODO: for debug only. to be removed
pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BE] = 0;
return;
}
-unsigned long rx_AMSDU;
-unsigned long rx_Total;
/*
==========================================================================
ULONG TxTotalCnt;
PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
-#ifdef RT2860
- //Baron 2008/07/10
- //printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus));
- //If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0.
- //If the STA security setting is WPAPSK or WPA2PSK, pAd->StaCfg.WpaSupplicantUP = 1.
- if(pAd->StaCfg.WepStatus<2)
- {
- pAd->StaCfg.WpaSupplicantUP = 0;
- }
- else
- {
- pAd->StaCfg.WpaSupplicantUP = 1;
- }
-
+#ifdef RTMP_MAC_PCI
{
// If Hardware controlled Radio enabled, we have to check GPIO pin2 every 2 second.
// Move code to here, because following code will return when radio is off
- if ((pAd->Mlme.PeriodicRound % (MLME_TASK_EXEC_MULTIPLE * 2) == 0) &&
- (pAd->StaCfg.bHardwareRadio == TRUE) &&
- (RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP)) &&
+ if ((pAd->Mlme.PeriodicRound % (MLME_TASK_EXEC_MULTIPLE * 2) == 0) && (pAd->StaCfg.bHardwareRadio == TRUE) &&
(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
- (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
+ /*&&(pAd->bPCIclkOff == FALSE)*/)
{
UINT32 data = 0;
// Read GPIO pin2 as Hardware controlled radio state
- RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data);
+ RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data);
if (data & 0x04)
{
pAd->StaCfg.bHwRadio = TRUE;
}
}
}
-#endif /* RT2860 */
+#endif // RTMP_MAC_PCI //
// Do nothing if the driver is starting halt state.
// This might happen when timer already been fired before cancel timer with mlmehalt
fRTMP_ADAPTER_RESET_IN_PROGRESS))))
return;
-#ifdef RT2860
- {
- if ((pAd->RalinkCounters.LastReceivedByteCount == pAd->RalinkCounters.ReceivedByteCount) && (pAd->StaCfg.bRadio == TRUE))
- {
- // If ReceiveByteCount doesn't change, increase SameRxByteCount by 1.
- pAd->SameRxByteCount++;
- }
- else
- pAd->SameRxByteCount = 0;
-
- // If after BBP, still not work...need to check to reset PBF&MAC.
- if (pAd->SameRxByteCount == 702)
- {
- pAd->SameRxByteCount = 0;
- AsicResetPBF(pAd);
- AsicResetMAC(pAd);
- }
-
- // If SameRxByteCount keeps happens for 2 second in infra mode, or for 60 seconds in idle mode.
- if (((INFRA_ON(pAd)) && (pAd->SameRxByteCount > 20)) || ((IDLE_ON(pAd)) && (pAd->SameRxByteCount > 600)))
- {
- if ((pAd->StaCfg.bRadio == TRUE) && (pAd->SameRxByteCount < 700))
- {
- DBGPRINT(RT_DEBUG_TRACE, ("---> SameRxByteCount = %lu !!!!!!!!!!!!!!! \n", pAd->SameRxByteCount));
- pAd->SameRxByteCount = 700;
- AsicResetBBP(pAd);
- }
- }
-
- // Update lastReceiveByteCount.
- pAd->RalinkCounters.LastReceivedByteCount = pAd->RalinkCounters.ReceivedByteCount;
-
- if ((pAd->CheckDmaBusyCount > 3) && (IDLE_ON(pAd)))
- {
- pAd->CheckDmaBusyCount = 0;
- AsicResetFromDMABusy(pAd);
- }
- }
-#endif /* RT2860 */
- RT28XX_MLME_PRE_SANITY_CHECK(pAd);
+ RTMP_MLME_PRE_SANITY_CHECK(pAd);
{
// Do nothing if monitor mode is on
// RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3);
pAd->Mlme.PeriodicRound ++;
-#ifdef RT3070
+#ifdef RTMP_MAC_USB
// execute every 100ms, update the Tx FIFO Cnt for update Tx Rate.
NICUpdateFifoStaCounters(pAd);
-#endif // RT3070 //
+#endif // RTMP_MAC_USB //
+
// execute every 500ms
if ((pAd->Mlme.PeriodicRound % 5 == 0) && RTMPAutoRateSwitchCheck(pAd)/*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))*/)
{
{
pAd->Mlme.OneSecPeriodicRound ++;
- if (rx_Total)
- {
- // reset counters
- rx_AMSDU = 0;
- rx_Total = 0;
- }
+
+
+ //ORIBATimerTimeout(pAd);
// Media status changed, report to NDIS
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE))
// the dynamic tuning mechanism below are based on most up-to-date information
NICUpdateRawCounters(pAd);
-#ifdef RT2870
- RT2870_WatchDog(pAd);
-#endif // RT2870 //
+#ifdef RTMP_MAC_USB
+ RTUSBWatchDog(pAd);
+#endif // RTMP_MAC_USB //
// Need statistics after read counter. So put after NICUpdateRawCounters
ORIBATimerTimeout(pAd);
+ // if MGMT RING is full more than twice within 1 second, we consider there's
+ // a hardware problem stucking the TX path. In this case, try a hardware reset
+ // to recover the system
+ // if (pAd->RalinkCounters.MgmtRingFullCount >= 2)
+ // RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HARDWARE_ERROR);
+ // else
+ // pAd->RalinkCounters.MgmtRingFullCount = 0;
+
// The time period for checking antenna is according to traffic
+ {
if (pAd->Mlme.bEnableAutoAntennaCheck)
{
TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
}
}
}
+ }
STAMlmePeriodicExec(pAd);
MlmeResetRalinkCounters(pAd);
{
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->bPCIclkOff == FALSE))
-#endif
+#endif // RTMP_MAC_PCI //
{
// When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock
// and sending CTS-to-self over and over.
}
}
- RT28XX_MLME_HANDLER(pAd);
+ RTMP_MLME_HANDLER(pAd);
}
+
pAd->bUpdateBcnCntDone = FALSE;
}
-VOID STAMlmePeriodicExec(
- PRTMP_ADAPTER pAd)
+
+/*
+ ==========================================================================
+ Validate SSID for connection try and rescan purpose
+ Valid SSID will have visible chars only.
+ The valid length is from 0 to 32.
+ IRQL = DISPATCH_LEVEL
+ ==========================================================================
+ */
+BOOLEAN MlmeValidateSSID(
+ IN PUCHAR pSsid,
+ IN UCHAR SsidLen)
{
-#ifdef RT2860
- ULONG TxTotalCnt;
-#endif
-#ifdef RT2870
- ULONG TxTotalCnt;
- int i;
-#endif
+ int index;
- if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)
+ if (SsidLen > MAX_LEN_OF_SSID)
+ return (FALSE);
+
+ // Check each character value
+ for (index = 0; index < SsidLen; index++)
{
- // WPA MIC error should block association attempt for 60 seconds
- if (pAd->StaCfg.bBlockAssoc && (pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ) < pAd->Mlme.Now32))
- pAd->StaCfg.bBlockAssoc = FALSE;
+ if (pSsid[index] < 0x20)
+ return (FALSE);
}
-#ifdef RT2860
- //Baron 2008/07/10
- //printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus));
- //If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0.
- //If the STA security setting is WPAPSK or WPA2PSK, pAd->StaCfg.WpaSupplicantUP = 1.
- if(pAd->StaCfg.WepStatus<2)
+ // All checked
+ return (TRUE);
+}
+
+VOID MlmeSelectTxRateTable(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN PUCHAR *ppTable,
+ IN PUCHAR pTableSize,
+ IN PUCHAR pInitTxRateIdx)
+{
+ do
{
- pAd->StaCfg.WpaSupplicantUP = 0;
- }
- else
+ // decide the rate table for tuning
+ if (pAd->CommonCfg.TxRateTableSize > 0)
{
- pAd->StaCfg.WpaSupplicantUP = 1;
+ *ppTable = RateSwitchTable;
+ *pTableSize = RateSwitchTable[0];
+ *pInitTxRateIdx = RateSwitchTable[1];
+
+ break;
}
-#endif
- if ((pAd->PreMediaState != pAd->IndicateMediaState) && (pAd->CommonCfg.bWirelessEvent))
+ if ((pAd->OpMode == OPMODE_STA) && ADHOC_ON(pAd))
{
- if (pAd->IndicateMediaState == NdisMediaStateConnected)
+ if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
+ (pEntry->HTCapability.MCSSet[0] == 0xff) &&
+ ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
+ {// 11N 1S Adhoc
+ *ppTable = RateSwitchTable11N1S;
+ *pTableSize = RateSwitchTable11N1S[0];
+ *pInitTxRateIdx = RateSwitchTable11N1S[1];
+
+ }
+ else if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
+ (pEntry->HTCapability.MCSSet[0] == 0xff) &&
+ (pEntry->HTCapability.MCSSet[1] == 0xff) &&
+ (pAd->Antenna.field.TxPath == 2))
+ {// 11N 2S Adhoc
+ if (pAd->LatchRfRegs.Channel <= 14)
{
- RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+ *ppTable = RateSwitchTable11N2S;
+ *pTableSize = RateSwitchTable11N2S[0];
+ *pInitTxRateIdx = RateSwitchTable11N2S[1];
}
- pAd->PreMediaState = pAd->IndicateMediaState;
+ else
+ {
+ *ppTable = RateSwitchTable11N2SForABand;
+ *pTableSize = RateSwitchTable11N2SForABand[0];
+ *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
}
-#ifdef RT2860
- if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd)) &&
- (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
- (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE) &&
- (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
- (RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP)) &&
- (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
- {
- RT28xxPciAsicRadioOff(pAd, GUI_IDLE_POWER_SAVE, 0);
}
-#endif
+ else
+ if ((pEntry->RateLen == 4)
+ && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
+ )
+ {
+ *ppTable = RateSwitchTable11B;
+ *pTableSize = RateSwitchTable11B[0];
+ *pInitTxRateIdx = RateSwitchTable11B[1];
+ }
+ else if (pAd->LatchRfRegs.Channel <= 14)
+ {
+ *ppTable = RateSwitchTable11BG;
+ *pTableSize = RateSwitchTable11BG[0];
+ *pInitTxRateIdx = RateSwitchTable11BG[1];
+ }
+ else
+ {
+ *ppTable = RateSwitchTable11G;
+ *pTableSize = RateSwitchTable11G[0];
+ *pInitTxRateIdx = RateSwitchTable11G[1];
- AsicStaBbpTuning(pAd);
+ }
+ break;
+ }
- TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
- pAd->RalinkCounters.OneSecTxRetryOkCount +
- pAd->RalinkCounters.OneSecTxFailCount;
+ //if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
+ // ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
+ if (((pEntry->RateLen == 12) || (pAd->OpMode == OPMODE_STA)) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
+ ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
+ {// 11BGN 1S AP
+ *ppTable = RateSwitchTable11BGN1S;
+ *pTableSize = RateSwitchTable11BGN1S[0];
+ *pInitTxRateIdx = RateSwitchTable11BGN1S[1];
- if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
- {
- // update channel quality for Roaming and UI LinkQuality display
- MlmeCalculateChannelQuality(pAd, pAd->Mlme.Now32);
+ break;
}
- // must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if
- // Radio is currently in noisy environment
- if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
- AsicAdjustTxPower(pAd);
-
- if (INFRA_ON(pAd))
+ //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
+ // (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2))
+ if (((pEntry->RateLen == 12) || (pAd->OpMode == OPMODE_STA)) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
+ (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
+ {// 11BGN 2S AP
+ if (pAd->LatchRfRegs.Channel <= 14)
{
- // Is PSM bit consistent with user power management policy?
- // This is the only place that will set PSM bit ON.
- if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
- MlmeCheckPsmChange(pAd, pAd->Mlme.Now32);
+ *ppTable = RateSwitchTable11BGN2S;
+ *pTableSize = RateSwitchTable11BGN2S[0];
+ *pInitTxRateIdx = RateSwitchTable11BGN2S[1];
- pAd->RalinkCounters.LastOneSecTotalTxCount = TxTotalCnt;
+ }
+ else
+ {
+ *ppTable = RateSwitchTable11BGN2SForABand;
+ *pTableSize = RateSwitchTable11BGN2SForABand[0];
+ *pInitTxRateIdx = RateSwitchTable11BGN2SForABand[1];
- if ((pAd->StaCfg.LastBeaconRxTime + 1*OS_HZ < pAd->Mlme.Now32) &&
- (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
- ((TxTotalCnt + pAd->RalinkCounters.OneSecRxOkCnt < 600)))
- {
- RTMPSetAGCInitValue(pAd, BW_20);
- DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n", (0x2E + GET_LNA_GAIN(pAd))));
+ }
+ break;
}
- {
- if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable)
- {
- // When APSD is enabled, the period changes as 20 sec
+ //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
+ if ((pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
+ {// 11N 1S AP
+ *ppTable = RateSwitchTable11N1S;
+ *pTableSize = RateSwitchTable11N1S[0];
+ *pInitTxRateIdx = RateSwitchTable11N1S[1];
+
+ break;
+ }
+
+ //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2))
+ if ((pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
+ {// 11N 2S AP
+ if (pAd->LatchRfRegs.Channel <= 14)
+ {
+ *ppTable = RateSwitchTable11N2S;
+ *pTableSize = RateSwitchTable11N2S[0];
+ *pInitTxRateIdx = RateSwitchTable11N2S[1];
+ }
+ else
+ {
+ *ppTable = RateSwitchTable11N2SForABand;
+ *pTableSize = RateSwitchTable11N2SForABand[0];
+ *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
+ }
+
+ break;
+ }
+ //else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
+ if ((pEntry->RateLen == 4 || pAd->CommonCfg.PhyMode==PHY_11B)
+ //Iverson mark for Adhoc b mode,sta will use rate 54 Mbps when connect with sta b/g/n mode
+ /* && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)*/
+ )
+ {// B only AP
+ *ppTable = RateSwitchTable11B;
+ *pTableSize = RateSwitchTable11B[0];
+ *pInitTxRateIdx = RateSwitchTable11B[1];
+
+ break;
+ }
+
+ //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
+ if ((pEntry->RateLen > 8)
+ && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
+ )
+ {// B/G mixed AP
+ *ppTable = RateSwitchTable11BG;
+ *pTableSize = RateSwitchTable11BG[0];
+ *pInitTxRateIdx = RateSwitchTable11BG[1];
+
+ break;
+ }
+
+ //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
+ if ((pEntry->RateLen == 8)
+ && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
+ )
+ {// G only AP
+ *ppTable = RateSwitchTable11G;
+ *pTableSize = RateSwitchTable11G[0];
+ *pInitTxRateIdx = RateSwitchTable11G[1];
+
+ break;
+ }
+
+ {
+ //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
+ if ((pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0))
+ { // Legacy mode
+ if (pAd->CommonCfg.MaxTxRate <= RATE_11)
+ {
+ *ppTable = RateSwitchTable11B;
+ *pTableSize = RateSwitchTable11B[0];
+ *pInitTxRateIdx = RateSwitchTable11B[1];
+ }
+ else if ((pAd->CommonCfg.MaxTxRate > RATE_11) && (pAd->CommonCfg.MinTxRate > RATE_11))
+ {
+ *ppTable = RateSwitchTable11G;
+ *pTableSize = RateSwitchTable11G[0];
+ *pInitTxRateIdx = RateSwitchTable11G[1];
+
+ }
+ else
+ {
+ *ppTable = RateSwitchTable11BG;
+ *pTableSize = RateSwitchTable11BG[0];
+ *pInitTxRateIdx = RateSwitchTable11BG[1];
+ }
+ break;
+ }
+ if (pAd->LatchRfRegs.Channel <= 14)
+ {
+ if (pAd->CommonCfg.TxStream == 1)
+ {
+ *ppTable = RateSwitchTable11N1S;
+ *pTableSize = RateSwitchTable11N1S[0];
+ *pInitTxRateIdx = RateSwitchTable11N1S[1];
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
+ }
+ else
+ {
+ *ppTable = RateSwitchTable11N2S;
+ *pTableSize = RateSwitchTable11N2S[0];
+ *pInitTxRateIdx = RateSwitchTable11N2S[1];
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
+ }
+ }
+ else
+ {
+ if (pAd->CommonCfg.TxStream == 1)
+ {
+ *ppTable = RateSwitchTable11N1S;
+ *pTableSize = RateSwitchTable11N1S[0];
+ *pInitTxRateIdx = RateSwitchTable11N1S[1];
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
+ }
+ else
+ {
+ *ppTable = RateSwitchTable11N2SForABand;
+ *pTableSize = RateSwitchTable11N2SForABand[0];
+ *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
+ }
+ }
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n",
+ pAd->StaActive.SupRateLen, pAd->StaActive.ExtRateLen, pAd->StaActive.SupportedPhyInfo.MCSSet[0], pAd->StaActive.SupportedPhyInfo.MCSSet[1]));
+ }
+ } while(FALSE);
+}
+
+
+VOID STAMlmePeriodicExec(
+ PRTMP_ADAPTER pAd)
+{
+ ULONG TxTotalCnt;
+ int i;
+
+ /*
+ We return here in ATE mode, because the statistics
+ that ATE need are not collected via this routine.
+ */
+#if defined(RT305x)||defined(RT3070)
+ // request by Gary, if Rssi0 > -42, BBP 82 need to be changed from 0x62 to 0x42, , bbp 67 need to be changed from 0x20 to 0x18
+ if (!pAd->CommonCfg.HighPowerPatchDisabled)
+ {
+#ifdef RT3070
+ if ( (IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201)))
+#endif // RT3070 //
+ {
+ if ((pAd->StaCfg.RssiSample.AvgRssi0 != 0) && (pAd->StaCfg.RssiSample.AvgRssi0 > (pAd->BbpRssiToDbmDelta - 35)))
+ {
+ RT30xxWriteRFRegister(pAd, RF_R27, 0x20);
+ }
+ else
+ {
+ RT30xxWriteRFRegister(pAd, RF_R27, 0x23);
+ }
+ }
+ }
+#endif
+
+ if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)
+ {
+ // WPA MIC error should block association attempt for 60 seconds
+ if (pAd->StaCfg.bBlockAssoc &&
+ RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->StaCfg.LastMicErrorTime + (60*OS_HZ)))
+ pAd->StaCfg.bBlockAssoc = FALSE;
+ }
+
+ if ((pAd->PreMediaState != pAd->IndicateMediaState) && (pAd->CommonCfg.bWirelessEvent))
+ {
+ if (pAd->IndicateMediaState == NdisMediaStateConnected)
+ {
+ RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+ }
+ pAd->PreMediaState = pAd->IndicateMediaState;
+ }
+
+
+
+
+ if (pAd->CommonCfg.PSPXlink && ADHOC_ON(pAd))
+ {
+ }
+ else
+ {
+ AsicStaBbpTuning(pAd);
+ }
+
+ TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+ pAd->RalinkCounters.OneSecTxRetryOkCount +
+ pAd->RalinkCounters.OneSecTxFailCount;
+
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ {
+ // update channel quality for Roaming and UI LinkQuality display
+ MlmeCalculateChannelQuality(pAd, NULL, pAd->Mlme.Now32);
+ }
+
+ // must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if
+ // Radio is currently in noisy environment
+ if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+ AsicAdjustTxPower(pAd);
+
+ if (INFRA_ON(pAd))
+ {
+
+ // Is PSM bit consistent with user power management policy?
+ // This is the only place that will set PSM bit ON.
+ if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+ MlmeCheckPsmChange(pAd, pAd->Mlme.Now32);
+
+ pAd->RalinkCounters.LastOneSecTotalTxCount = TxTotalCnt;
+
+ if ((RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->StaCfg.LastBeaconRxTime + (1*OS_HZ))) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
+ (((TxTotalCnt + pAd->RalinkCounters.OneSecRxOkCnt) < 600)))
+ {
+ RTMPSetAGCInitValue(pAd, BW_20);
+ DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n", (0x2E + GET_LNA_GAIN(pAd))));
+ }
+
+ //if ((pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
+ // (pAd->RalinkCounters.OneSecTxRetryOkCount == 0))
+ {
+ if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable)
+ {
+ // When APSD is enabled, the period changes as 20 sec
if ((pAd->Mlme.OneSecPeriodicRound % 20) == 8)
RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
}
if (CQI_IS_DEAD(pAd->Mlme.ChannelQuality))
{
DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
- pAd->StaCfg.CCXAdjacentAPReportFlag = TRUE;
- pAd->StaCfg.CCXAdjacentAPLinkDownTime = pAd->StaCfg.LastBeaconRxTime;
+
+ if ((pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) &&
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
+ pAd->StaCfg.bLostAp = TRUE;
// Lost AP, send disconnect & link down event
LinkDown(pAd, FALSE);
- {
- union iwreq_data wrqu;
- memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
- wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
- }
+ RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0);
+
+ // RTMPPatchMacBbpBug(pAd);
MlmeAutoReconnectLastSSID(pAd);
}
else if (CQI_IS_BAD(pAd->Mlme.ChannelQuality))
MlmeAutoReconnectLastSSID(pAd);
}
- // Add auto seamless roaming
- if (pAd->StaCfg.bFastRoaming)
+ if (pAd->StaCfg.bAutoRoaming)
{
- SHORT dBmToRoam = (SHORT)pAd->StaCfg.dBmToRoam;
-
- DBGPRINT(RT_DEBUG_TRACE, ("Rssi=%d, dBmToRoam=%d\n", RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2), (CHAR)dBmToRoam));
+ BOOLEAN rv = FALSE;
+ CHAR dBmToRoam = pAd->StaCfg.dBmToRoam;
+ CHAR MaxRssi = RTMPMaxRssi(pAd,
+ pAd->StaCfg.RssiSample.LastRssi0,
+ pAd->StaCfg.RssiSample.LastRssi1,
+ pAd->StaCfg.RssiSample.LastRssi2);
- if (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) <= (CHAR)dBmToRoam)
- {
- MlmeCheckForFastRoaming(pAd, pAd->Mlme.Now32);
- }
- }
- }
- else if (ADHOC_ON(pAd))
+ // Scanning, ignore Roaming
+ if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) &&
+ (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE) &&
+ (MaxRssi <= dBmToRoam))
{
-#ifdef RT2860
- // 2003-04-17 john. this is a patch that driver forces a BEACON out if ASIC fails
- // the "TX BEACON competition" for the entire past 1 sec.
- // So that even when ASIC's BEACONgen engine been blocked
- // by peer's BEACON due to slower system clock, this STA still can send out
- // minimum BEACON to tell the peer I'm alive.
- // drawback is that this BEACON won't be well aligned at TBTT boundary.
- // EnqueueBeaconFrame(pAd); // software send BEACON
-
- // if all 11b peers leave this BSS more than 5 seconds, update Tx rate,
- // restore outgoing BEACON to support B/G-mixed mode
- if ((pAd->CommonCfg.Channel <= 14) &&
- (pAd->CommonCfg.MaxTxRate <= RATE_11) &&
- (pAd->CommonCfg.MaxDesiredRate > RATE_11) &&
- ((pAd->StaCfg.Last11bBeaconRxTime + 5*OS_HZ) < pAd->Mlme.Now32))
- {
- DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - last 11B peer left, update Tx rates\n"));
- NdisMoveMemory(pAd->StaActive.SupRate, pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
- pAd->StaActive.SupRateLen = pAd->CommonCfg.SupRateLen;
- MlmeUpdateTxRates(pAd, FALSE, 0);
- MakeIbssBeacon(pAd); // re-build BEACON frame
- AsicEnableIbssSync(pAd); // copy to on-chip memory
- pAd->StaCfg.AdhocBOnlyJoined = FALSE;
- }
+ DBGPRINT(RT_DEBUG_TRACE, ("Rssi=%d, dBmToRoam=%d\n", MaxRssi, (CHAR)dBmToRoam));
+
+
+ // Add auto seamless roaming
+ if (rv == FALSE)
+ rv = MlmeCheckForFastRoaming(pAd);
- if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+ if (rv == FALSE)
{
- if ((pAd->StaCfg.AdhocBGJoined) &&
- ((pAd->StaCfg.Last11gBeaconRxTime + 5 * OS_HZ) < pAd->Mlme.Now32))
+ if ((pAd->StaCfg.LastScanTime + 10 * OS_HZ) < pAd->Mlme.Now32)
{
- DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - last 11G peer left\n"));
- pAd->StaCfg.AdhocBGJoined = FALSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming, No eligable entry, try new scan!\n"));
+ pAd->StaCfg.ScanCnt = 2;
+ pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
+ MlmeAutoScan(pAd);
}
-
- if ((pAd->StaCfg.Adhoc20NJoined) &&
- ((pAd->StaCfg.Last20NBeaconRxTime + 5 * OS_HZ) < pAd->Mlme.Now32))
- {
- DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - last 20MHz N peer left\n"));
- pAd->StaCfg.Adhoc20NJoined = FALSE;
}
}
-#endif /* RT2860 */
-
- //radar detect
- if ((pAd->CommonCfg.Channel > 14)
- && (pAd->CommonCfg.bIEEE80211H == 1)
- && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
- {
- RadarDetectPeriodic(pAd);
}
-
+ }
+ else if (ADHOC_ON(pAd))
+ {
// If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState
// to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can
// join later.
- if ((pAd->StaCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32) &&
+ if (RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->StaCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME) &&
OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
{
MLME_START_REQ_STRUCT StartReq;
DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n"));
LinkDown(pAd, FALSE);
- StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+ StartParmFill(pAd, &StartReq, (CHAR *)pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
}
-#ifdef RT2870
for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
{
MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[i];
if (pEntry->ValidAsCLI == FALSE)
continue;
- if (pEntry->LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32)
+ if (RTMP_TIME_AFTER(pAd->Mlme.Now32, pEntry->LastBeaconRxTime + ADHOC_BEACON_LOST_TIME))
MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
}
-#endif
}
else // no INFRA nor ADHOC connection
{
if (pAd->StaCfg.bScanReqIsFromWebUI &&
- ((pAd->StaCfg.LastScanTime + 30 * OS_HZ) > pAd->Mlme.Now32))
+ RTMP_TIME_BEFORE(pAd->Mlme.Now32, pAd->StaCfg.LastScanTime + (30 * OS_HZ)))
goto SKIP_AUTO_SCAN_CONN;
else
pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
{
MLME_SCAN_REQ_STRUCT ScanReq;
- if ((pAd->StaCfg.LastScanTime + 10 * OS_HZ) < pAd->Mlme.Now32)
+ if (RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->StaCfg.LastScanTime + (10 * OS_HZ)))
{
DBGPRINT(RT_DEBUG_TRACE, ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, start a new ACTIVE scan SSID[%s]\n", pAd->MlmeAux.AutoReconnectSsid));
- ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen, BSS_ANY, SCAN_ACTIVE);
+ ScanParmFill(pAd, &ScanReq, (PSTRING) pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen, BSS_ANY, SCAN_ACTIVE);
MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
// Reset Missed scan number
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3)
{
-
RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+ if (pAd != NULL)
+ {
+ MLME_DISASSOC_REQ_STRUCT DisassocReq;
+
+ if ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) &&
+ (INFRA_ON(pAd)))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("LinkDownExec(): disassociate with current AP...\n"));
+ DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
+ sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
+
pAd->IndicateMediaState = NdisMediaStateDisconnected;
RTMP_IndicateMediaState(pAd);
pAd->ExtraInfo = GENERAL_LINK_DOWN;
+ }
+ }
}
// IRQL = DISPATCH_LEVEL
MlmeEnqueue(pAd,
MLME_CNTL_STATE_MACHINE,
OID_802_11_BSSID_LIST_SCAN,
- 0,
- NULL);
- RT28XX_MLME_HANDLER(pAd);
+ pAd->MlmeAux.AutoReconnectSsidLen,
+ pAd->MlmeAux.AutoReconnectSsid);
+ RTMP_MLME_HANDLER(pAd);
}
}
VOID MlmeAutoReconnectLastSSID(
IN PRTMP_ADAPTER pAd)
{
+ if (pAd->StaCfg.bAutoConnectByBssid)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Driver auto reconnect to last OID_802_11_BSSID setting - %02X:%02X:%02X:%02X:%02X:%02X\n",
+ pAd->MlmeAux.Bssid[0],
+ pAd->MlmeAux.Bssid[1],
+ pAd->MlmeAux.Bssid[2],
+ pAd->MlmeAux.Bssid[3],
+ pAd->MlmeAux.Bssid[4],
+ pAd->MlmeAux.Bssid[5]));
+
+ pAd->MlmeAux.Channel = pAd->CommonCfg.Channel;
+ MlmeEnqueue(pAd,
+ MLME_CNTL_STATE_MACHINE,
+ OID_802_11_BSSID,
+ MAC_ADDR_LEN,
+ pAd->MlmeAux.Bssid);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ RTMP_MLME_HANDLER(pAd);
+ }
// check CntlMachine.CurrState to avoid collision with NDIS SetOID request
- if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
+ else if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
(MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
{
NDIS_802_11_SSID OidSsid;
OID_802_11_SSID,
sizeof(NDIS_802_11_SSID),
&OidSsid);
- RT28XX_MLME_HANDLER(pAd);
+ RTMP_MLME_HANDLER(pAd);
}
}
+
/*
==========================================================================
- Validate SSID for connection try and rescan purpose
- Valid SSID will have visible chars only.
- The valid length is from 0 to 32.
+ Description:
+ This routine checks if there're other APs out there capable for
+ roaming. Caller should call this routine only when Link up in INFRA mode
+ and channel quality is below CQI_GOOD_THRESHOLD.
+
IRQL = DISPATCH_LEVEL
+
+ Output:
==========================================================================
*/
-BOOLEAN MlmeValidateSSID(
- IN PUCHAR pSsid,
- IN UCHAR SsidLen)
+VOID MlmeCheckForRoaming(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Now32)
{
- int index;
-
- if (SsidLen > MAX_LEN_OF_SSID)
- return (FALSE);
+ USHORT i;
+ BSS_TABLE *pRoamTab = &pAd->MlmeAux.RoamTab;
+ BSS_ENTRY *pBss;
- // Check each character value
- for (index = 0; index < SsidLen; index++)
+ DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForRoaming\n"));
+ // put all roaming candidates into RoamTab, and sort in RSSI order
+ BssTableInit(pRoamTab);
+ for (i = 0; i < pAd->ScanTab.BssNr; i++)
{
- if (pSsid[index] < 0x20)
- return (FALSE);
+ pBss = &pAd->ScanTab.BssEntry[i];
+
+ if ((pBss->LastBeaconRxTime + pAd->StaCfg.BeaconLostTime) < Now32)
+ continue; // AP disappear
+ if (pBss->Rssi <= RSSI_THRESHOLD_FOR_ROAMING)
+ continue; // RSSI too weak. forget it.
+ if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
+ continue; // skip current AP
+ if (pBss->Rssi < (pAd->StaCfg.RssiSample.LastRssi0 + RSSI_DELTA))
+ continue; // only AP with stronger RSSI is eligible for roaming
+
+ // AP passing all above rules is put into roaming candidate table
+ NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
+ pRoamTab->BssNr += 1;
}
- // All checked
- return (TRUE);
+ if (pRoamTab->BssNr > 0)
+ {
+ // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
+ if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
+ {
+ pAd->RalinkCounters.PoorCQIRoamingCount ++;
+ DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
+ RTMP_MLME_HANDLER(pAd);
+ }
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForRoaming(# of candidate= %d)\n",pRoamTab->BssNr));
}
-VOID MlmeSelectTxRateTable(
- IN PRTMP_ADAPTER pAd,
- IN PMAC_TABLE_ENTRY pEntry,
- IN PUCHAR *ppTable,
- IN PUCHAR pTableSize,
- IN PUCHAR pInitTxRateIdx)
+/*
+ ==========================================================================
+ Description:
+ This routine checks if there're other APs out there capable for
+ roaming. Caller should call this routine only when link up in INFRA mode
+ and channel quality is below CQI_GOOD_THRESHOLD.
+
+ IRQL = DISPATCH_LEVEL
+
+ Output:
+ ==========================================================================
+ */
+BOOLEAN MlmeCheckForFastRoaming(
+ IN PRTMP_ADAPTER pAd)
{
- do
- {
- // decide the rate table for tuning
- if (pAd->CommonCfg.TxRateTableSize > 0)
+ USHORT i;
+ BSS_TABLE *pRoamTab = &pAd->MlmeAux.RoamTab;
+ BSS_ENTRY *pBss;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForFastRoaming\n"));
+ // put all roaming candidates into RoamTab, and sort in RSSI order
+ BssTableInit(pRoamTab);
+ for (i = 0; i < pAd->ScanTab.BssNr; i++)
{
- *ppTable = RateSwitchTable;
- *pTableSize = RateSwitchTable[0];
- *pInitTxRateIdx = RateSwitchTable[1];
+ pBss = &pAd->ScanTab.BssEntry[i];
- break;
+ if ((pBss->Rssi <= -50) && (pBss->Channel == pAd->CommonCfg.Channel))
+ continue; // RSSI too weak. forget it.
+ if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
+ continue; // skip current AP
+ if (!SSID_EQUAL(pBss->Ssid, pBss->SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen))
+ continue; // skip different SSID
+ if (pBss->Rssi < (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) + RSSI_DELTA))
+ continue; // skip AP without better RSSI
+
+ DBGPRINT(RT_DEBUG_TRACE, ("LastRssi0 = %d, pBss->Rssi = %d\n", RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2), pBss->Rssi));
+ // AP passing all above rules is put into roaming candidate table
+ NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
+ pRoamTab->BssNr += 1;
}
- if ((pAd->OpMode == OPMODE_STA) && ADHOC_ON(pAd))
+ DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr));
+ if (pRoamTab->BssNr > 0)
{
- if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
-#ifdef RT2860
- !pAd->StaCfg.AdhocBOnlyJoined &&
- !pAd->StaCfg.AdhocBGJoined &&
- (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
- ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
-#endif
-#ifdef RT2870
- (pEntry->HTCapability.MCSSet[0] == 0xff) &&
- ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
-#endif
- {// 11N 1S Adhoc
- *ppTable = RateSwitchTable11N1S;
- *pTableSize = RateSwitchTable11N1S[0];
- *pInitTxRateIdx = RateSwitchTable11N1S[1];
-
- }
- else if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
-#ifdef RT2860
- !pAd->StaCfg.AdhocBOnlyJoined &&
- !pAd->StaCfg.AdhocBGJoined &&
- (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
- (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) &&
-#endif
-#ifdef RT2870
- (pEntry->HTCapability.MCSSet[0] == 0xff) &&
- (pEntry->HTCapability.MCSSet[1] == 0xff) &&
-#endif
- (pAd->Antenna.field.TxPath == 2))
- {// 11N 2S Adhoc
- if (pAd->LatchRfRegs.Channel <= 14)
+ // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
+ if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
{
- *ppTable = RateSwitchTable11N2S;
- *pTableSize = RateSwitchTable11N2S[0];
- *pInitTxRateIdx = RateSwitchTable11N2S[1];
+ pAd->RalinkCounters.PoorCQIRoamingCount ++;
+ DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
+ RTMP_MLME_HANDLER(pAd);
+ return TRUE;
}
- else
- {
- *ppTable = RateSwitchTable11N2SForABand;
- *pTableSize = RateSwitchTable11N2SForABand[0];
- *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
}
- }
- else
-#ifdef RT2860
- if (pAd->CommonCfg.PhyMode == PHY_11B)
- {
- *ppTable = RateSwitchTable11B;
- *pTableSize = RateSwitchTable11B[0];
- *pInitTxRateIdx = RateSwitchTable11B[1];
+ return FALSE;
+}
- }
- else if((pAd->LatchRfRegs.Channel <= 14) && (pAd->StaCfg.AdhocBOnlyJoined == TRUE))
-#endif
-#ifdef RT2870
- if ((pEntry->RateLen == 4)
- && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
- )
-#endif
- {
- // USe B Table when Only b-only Station in my IBSS .
- *ppTable = RateSwitchTable11B;
- *pTableSize = RateSwitchTable11B[0];
- *pInitTxRateIdx = RateSwitchTable11B[1];
+VOID MlmeSetTxRate(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN PRTMP_TX_RATE_SWITCH pTxRate)
+{
+ UCHAR MaxMode = MODE_OFDM;
- }
- else if (pAd->LatchRfRegs.Channel <= 14)
- {
- *ppTable = RateSwitchTable11BG;
- *pTableSize = RateSwitchTable11BG[0];
- *pInitTxRateIdx = RateSwitchTable11BG[1];
+ MaxMode = MODE_HTGREENFIELD;
- }
+ if (pTxRate->STBC && (pAd->StaCfg.MaxHTPhyMode.field.STBC) && (pAd->Antenna.field.TxPath == 2))
+ pAd->StaCfg.HTPhyMode.field.STBC = STBC_USE;
else
- {
- *ppTable = RateSwitchTable11G;
- *pTableSize = RateSwitchTable11G[0];
- *pInitTxRateIdx = RateSwitchTable11G[1];
-
- }
- break;
- }
+ pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
- if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
- ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
- {// 11BGN 1S AP
- *ppTable = RateSwitchTable11BGN1S;
- *pTableSize = RateSwitchTable11BGN1S[0];
- *pInitTxRateIdx = RateSwitchTable11BGN1S[1];
+ if (pTxRate->CurrMCS < MCS_AUTO)
+ pAd->StaCfg.HTPhyMode.field.MCS = pTxRate->CurrMCS;
- break;
- }
+ if (pAd->StaCfg.HTPhyMode.field.MCS > 7)
+ pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
- if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
- (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
- {// 11BGN 2S AP
- if (pAd->LatchRfRegs.Channel <= 14)
+ if (ADHOC_ON(pAd))
{
- *ppTable = RateSwitchTable11BGN2S;
- *pTableSize = RateSwitchTable11BGN2S[0];
- *pInitTxRateIdx = RateSwitchTable11BGN2S[1];
+ // If peer adhoc is b-only mode, we can't send 11g rate.
+ pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
+ pEntry->HTPhyMode.field.STBC = STBC_NONE;
+ //
+ // For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary
+ //
+ pEntry->HTPhyMode.field.MODE = pTxRate->Mode;
+ pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI;
+ pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+
+ // Patch speed error in status page
+ pAd->StaCfg.HTPhyMode.field.MODE = pEntry->HTPhyMode.field.MODE;
}
else
{
- *ppTable = RateSwitchTable11BGN2SForABand;
- *pTableSize = RateSwitchTable11BGN2SForABand[0];
- *pInitTxRateIdx = RateSwitchTable11BGN2SForABand[1];
-
- }
- break;
- }
+ if (pTxRate->Mode <= MaxMode)
+ pAd->StaCfg.HTPhyMode.field.MODE = pTxRate->Mode;
- if ((pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
- {// 11N 1S AP
- *ppTable = RateSwitchTable11N1S;
- *pTableSize = RateSwitchTable11N1S[0];
- *pInitTxRateIdx = RateSwitchTable11N1S[1];
+ if (pTxRate->ShortGI && (pAd->StaCfg.MaxHTPhyMode.field.ShortGI))
+ pAd->StaCfg.HTPhyMode.field.ShortGI = GI_400;
+ else
+ pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
- break;
+ // Reexam each bandwidth's SGI support.
+ if (pAd->StaCfg.HTPhyMode.field.ShortGI == GI_400)
+ {
+ if ((pEntry->HTPhyMode.field.BW == BW_20) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE)))
+ pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
+ if ((pEntry->HTPhyMode.field.BW == BW_40) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE)))
+ pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
}
- if ((pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
- {// 11N 2S AP
- if (pAd->LatchRfRegs.Channel <= 14)
+ // Turn RTS/CTS rate to 6Mbps.
+ if ((pEntry->HTPhyMode.field.MCS == 0) && (pAd->StaCfg.HTPhyMode.field.MCS != 0))
{
- *ppTable = RateSwitchTable11N2S;
- *pTableSize = RateSwitchTable11N2S[0];
- *pInitTxRateIdx = RateSwitchTable11N2S[1];
+ pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+ if (pAd->MacTab.fAnyBASession)
+ {
+ AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
}
else
{
- *ppTable = RateSwitchTable11N2SForABand;
- *pTableSize = RateSwitchTable11N2SForABand[0];
- *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
+ AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+ }
+ }
+ else if ((pEntry->HTPhyMode.field.MCS == 8) && (pAd->StaCfg.HTPhyMode.field.MCS != 8))
+ {
+ pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+ if (pAd->MacTab.fAnyBASession)
+ {
+ AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+ }
+ else
+ {
+ AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+ }
}
+ else if ((pEntry->HTPhyMode.field.MCS != 0) && (pAd->StaCfg.HTPhyMode.field.MCS == 0))
+ {
+ AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
- break;
- }
+ }
+ else if ((pEntry->HTPhyMode.field.MCS != 8) && (pAd->StaCfg.HTPhyMode.field.MCS == 8))
+ {
+ AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+ }
- //else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
- if (pEntry->RateLen == 4)
- {// B only AP
- *ppTable = RateSwitchTable11B;
- *pTableSize = RateSwitchTable11B[0];
- *pInitTxRateIdx = RateSwitchTable11B[1];
-
- break;
- }
-
- //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
- if ((pEntry->RateLen > 8)
- && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
- )
- {// B/G mixed AP
- *ppTable = RateSwitchTable11BG;
- *pTableSize = RateSwitchTable11BG[0];
- *pInitTxRateIdx = RateSwitchTable11BG[1];
-
- break;
- }
-
- //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
- if ((pEntry->RateLen == 8)
- && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
- )
- {// G only AP
- *ppTable = RateSwitchTable11G;
- *pTableSize = RateSwitchTable11G[0];
- *pInitTxRateIdx = RateSwitchTable11G[1];
-
- break;
+ pEntry->HTPhyMode.field.STBC = pAd->StaCfg.HTPhyMode.field.STBC;
+ pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI;
+ pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+ pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
+ if ((pAd->StaCfg.MaxHTPhyMode.field.MODE == MODE_HTGREENFIELD) &&
+ pAd->WIFItestbed.bGreenField)
+ pEntry->HTPhyMode.field.MODE = MODE_HTGREENFIELD;
}
- {
- //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
- if ((pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0))
- { // Legacy mode
- if (pAd->CommonCfg.MaxTxRate <= RATE_11)
- {
- *ppTable = RateSwitchTable11B;
- *pTableSize = RateSwitchTable11B[0];
- *pInitTxRateIdx = RateSwitchTable11B[1];
- }
- else if ((pAd->CommonCfg.MaxTxRate > RATE_11) && (pAd->CommonCfg.MinTxRate > RATE_11))
- {
- *ppTable = RateSwitchTable11G;
- *pTableSize = RateSwitchTable11G[0];
- *pInitTxRateIdx = RateSwitchTable11G[1];
-
- }
- else
- {
- *ppTable = RateSwitchTable11BG;
- *pTableSize = RateSwitchTable11BG[0];
- *pInitTxRateIdx = RateSwitchTable11BG[1];
- }
- break;
- }
-
- if (pAd->LatchRfRegs.Channel <= 14)
- {
- if (pAd->CommonCfg.TxStream == 1)
- {
- *ppTable = RateSwitchTable11N1S;
- *pTableSize = RateSwitchTable11N1S[0];
- *pInitTxRateIdx = RateSwitchTable11N1S[1];
- DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
- }
- else
- {
- *ppTable = RateSwitchTable11N2S;
- *pTableSize = RateSwitchTable11N2S[0];
- *pInitTxRateIdx = RateSwitchTable11N2S[1];
- DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
- }
- }
- else
- {
- if (pAd->CommonCfg.TxStream == 1)
- {
- *ppTable = RateSwitchTable11N1S;
- *pTableSize = RateSwitchTable11N1S[0];
- *pInitTxRateIdx = RateSwitchTable11N1S[1];
- DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
- }
- else
- {
- *ppTable = RateSwitchTable11N2SForABand;
- *pTableSize = RateSwitchTable11N2SForABand[0];
- *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
- DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
- }
- }
-
- DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n",
- pAd->StaActive.SupRateLen, pAd->StaActive.ExtRateLen, pAd->StaActive.SupportedPhyInfo.MCSSet[0], pAd->StaActive.SupportedPhyInfo.MCSSet[1]));
- }
- } while(FALSE);
+ pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
}
/*
==========================================================================
Description:
- This routine checks if there're other APs out there capable for
- roaming. Caller should call this routine only when Link up in INFRA mode
- and channel quality is below CQI_GOOD_THRESHOLD.
+ This routine calculates the acumulated TxPER of eaxh TxRate. And
+ according to the calculation result, change CommonCfg.TxRate which
+ is the stable TX Rate we expect the Radio situation could sustained.
+
+ CommonCfg.TxRate will change dynamically within {RATE_1/RATE_6, MaxTxRate}
+ Output:
+ CommonCfg.TxRate -
IRQL = DISPATCH_LEVEL
- Output:
+ NOTE:
+ call this routine every second
==========================================================================
*/
-VOID MlmeCheckForRoaming(
- IN PRTMP_ADAPTER pAd,
- IN ULONG Now32)
+VOID MlmeDynamicTxRateSwitching(
+ IN PRTMP_ADAPTER pAd)
{
- USHORT i;
- BSS_TABLE *pRoamTab = &pAd->MlmeAux.RoamTab;
- BSS_ENTRY *pBss;
+ UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx;
+ ULONG i, AccuTxTotalCnt = 0, TxTotalCnt;
+ ULONG TxErrorRatio = 0;
+ BOOLEAN bTxRateChanged = FALSE, bUpgradeQuality = FALSE;
+ PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL;
+ PUCHAR pTable;
+ UCHAR TableSize = 0;
+ UCHAR InitTxRateIdx = 0, TrainUp, TrainDown;
+ CHAR Rssi, RssiOffset = 0;
+ TX_STA_CNT1_STRUC StaTx1;
+ TX_STA_CNT0_STRUC TxStaCnt0;
+ ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
+ MAC_TABLE_ENTRY *pEntry;
+ RSSI_SAMPLE *pRssi = &pAd->StaCfg.RssiSample;
- DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForRoaming\n"));
- // put all roaming candidates into RoamTab, and sort in RSSI order
- BssTableInit(pRoamTab);
- for (i = 0; i < pAd->ScanTab.BssNr; i++)
- {
- pBss = &pAd->ScanTab.BssEntry[i];
- if ((pBss->LastBeaconRxTime + BEACON_LOST_TIME) < Now32)
- continue; // AP disappear
- if (pBss->Rssi <= RSSI_THRESHOLD_FOR_ROAMING)
- continue; // RSSI too weak. forget it.
- if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
- continue; // skip current AP
- if (pBss->Rssi < (pAd->StaCfg.RssiSample.LastRssi0 + RSSI_DELTA))
- continue; // only AP with stronger RSSI is eligible for roaming
+ //
+ // walk through MAC table, see if need to change AP's TX rate toward each entry
+ //
+ for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ pEntry = &pAd->MacTab.Content[i];
- // AP passing all above rules is put into roaming candidate table
- NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
- pRoamTab->BssNr += 1;
- }
+ // check if this entry need to switch rate automatically
+ if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
+ continue;
- if (pRoamTab->BssNr > 0)
- {
- // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
- if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
+ if ((pAd->MacTab.Size == 1) || (pEntry->ValidAsDls))
{
- pAd->RalinkCounters.PoorCQIRoamingCount ++;
- DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
- MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
- RT28XX_MLME_HANDLER(pAd);
- }
- }
- DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForRoaming(# of candidate= %d)\n",pRoamTab->BssNr));
-}
+ Rssi = RTMPMaxRssi(pAd,
+ pRssi->AvgRssi0,
+ pRssi->AvgRssi1,
+ pRssi->AvgRssi2);
-/*
- ==========================================================================
- Description:
- This routine checks if there're other APs out there capable for
- roaming. Caller should call this routine only when link up in INFRA mode
- and channel quality is below CQI_GOOD_THRESHOLD.
+ // Update statistic counter
+ RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
+ RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
+ pAd->bUpdateBcnCntDone = TRUE;
+ TxRetransmit = StaTx1.field.TxRetransmit;
+ TxSuccess = StaTx1.field.TxSuccess;
+ TxFailCount = TxStaCnt0.field.TxFailCount;
+ TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
- IRQL = DISPATCH_LEVEL
+ pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
+ pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
+ pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
+ pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
+ pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
+ pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
- Output:
- ==========================================================================
- */
-VOID MlmeCheckForFastRoaming(
- IN PRTMP_ADAPTER pAd,
- IN ULONG Now)
-{
- USHORT i;
- BSS_TABLE *pRoamTab = &pAd->MlmeAux.RoamTab;
- BSS_ENTRY *pBss;
+ // if no traffic in the past 1-sec period, don't change TX rate,
+ // but clear all bad history. because the bad history may affect the next
+ // Chariot throughput test
+ AccuTxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+ pAd->RalinkCounters.OneSecTxRetryOkCount +
+ pAd->RalinkCounters.OneSecTxFailCount;
- DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForFastRoaming\n"));
- // put all roaming candidates into RoamTab, and sort in RSSI order
- BssTableInit(pRoamTab);
- for (i = 0; i < pAd->ScanTab.BssNr; i++)
+ if (TxTotalCnt)
+ TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
+ }
+ else
{
- pBss = &pAd->ScanTab.BssEntry[i];
+ if (INFRA_ON(pAd) && (i == 1))
+ Rssi = RTMPMaxRssi(pAd,
+ pRssi->AvgRssi0,
+ pRssi->AvgRssi1,
+ pRssi->AvgRssi2);
+ else
+ Rssi = RTMPMaxRssi(pAd,
+ pEntry->RssiSample.AvgRssi0,
+ pEntry->RssiSample.AvgRssi1,
+ pEntry->RssiSample.AvgRssi2);
- if ((pBss->Rssi <= -50) && (pBss->Channel == pAd->CommonCfg.Channel))
- continue; // RSSI too weak. forget it.
- if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
- continue; // skip current AP
- if (!SSID_EQUAL(pBss->Ssid, pBss->SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen))
- continue; // skip different SSID
- if (pBss->Rssi < (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) + RSSI_DELTA))
- continue; // skip AP without better RSSI
+ TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
+ pEntry->OneSecTxRetryOkCount +
+ pEntry->OneSecTxFailCount;
- DBGPRINT(RT_DEBUG_TRACE, ("LastRssi0 = %d, pBss->Rssi = %d\n", RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2), pBss->Rssi));
- // AP passing all above rules is put into roaming candidate table
- NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
- pRoamTab->BssNr += 1;
+ if (TxTotalCnt)
+ TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
}
- if (pRoamTab->BssNr > 0)
- {
- // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
- if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
+ if (TxTotalCnt)
{
- pAd->RalinkCounters.PoorCQIRoamingCount ++;
- DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
- MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
- RT28XX_MLME_HANDLER(pAd);
- }
- }
- // Maybe site survey required
- else
- {
- if ((pAd->StaCfg.LastScanTime + 10 * 1000) < Now)
+ /*
+ Three AdHoc connections can not work normally if one AdHoc connection is disappeared from a heavy traffic environment generated by ping tool
+ We force to set LongRtyLimit and ShortRtyLimit to 0 to stop retransmitting packet, after a while, resoring original settings
+ */
+ if (TxErrorRatio == 100)
+ {
+ TX_RTY_CFG_STRUC TxRtyCfg,TxRtyCfgtmp;
+ ULONG Index;
+ ULONG MACValue;
+
+ RTMP_IO_READ32(pAd, TX_RTY_CFG, &TxRtyCfg.word);
+ TxRtyCfgtmp.word = TxRtyCfg.word;
+ TxRtyCfg.field.LongRtyLimit = 0x0;
+ TxRtyCfg.field.ShortRtyLimit = 0x0;
+ RTMP_IO_WRITE32(pAd, TX_RTY_CFG, TxRtyCfg.word);
+
+ RTMPusecDelay(1);
+
+ Index = 0;
+ MACValue = 0;
+ do
{
- // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
- DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming, No eligable entry, try new scan!\n"));
- pAd->StaCfg.ScanCnt = 2;
- pAd->StaCfg.LastScanTime = Now;
- MlmeAutoScan(pAd);
+ RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
+ if ((MACValue & 0xffffff) == 0)
+ break;
+ Index++;
+ RTMPusecDelay(1000);
+ }while((Index < 330)&&(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)));
+
+ RTMP_IO_READ32(pAd, TX_RTY_CFG, &TxRtyCfg.word);
+ TxRtyCfg.field.LongRtyLimit = TxRtyCfgtmp.field.LongRtyLimit;
+ TxRtyCfg.field.ShortRtyLimit = TxRtyCfgtmp.field.ShortRtyLimit;
+ RTMP_IO_WRITE32(pAd, TX_RTY_CFG, TxRtyCfg.word);
}
}
- DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr));
-}
+ CurrRateIdx = pEntry->CurrTxRateIndex;
-/*
- ==========================================================================
- Description:
- This routine calculates TxPER, RxPER of the past N-sec period. And
- according to the calculation result, ChannelQuality is calculated here
- to decide if current AP is still doing the job.
+ MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
- If ChannelQuality is not good, a ROAMing attempt may be tried later.
- Output:
- StaCfg.ChannelQuality - 0..100
+ if (CurrRateIdx >= TableSize)
+ {
+ CurrRateIdx = TableSize - 1;
+ }
- IRQL = DISPATCH_LEVEL
+ // When switch from Fixed rate -> auto rate, the REAL TX rate might be different from pAd->CommonCfg.TxRateIndex.
+ // So need to sync here.
+ pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
+ if ((pEntry->HTPhyMode.field.MCS != pCurrTxRate->CurrMCS)
+ //&& (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
+ )
+ {
- NOTE: This routine decide channle quality based on RX CRC error ratio.
- Caller should make sure a function call to NICUpdateRawCounters(pAd)
- is performed right before this routine, so that this routine can decide
- channel quality based on the most up-to-date information
- ==========================================================================
- */
-VOID MlmeCalculateChannelQuality(
- IN PRTMP_ADAPTER pAd,
- IN ULONG Now32)
-{
- ULONG TxOkCnt, TxCnt, TxPER, TxPRR;
- ULONG RxCnt, RxPER;
- UCHAR NorRssi;
- CHAR MaxRssi;
- ULONG BeaconLostTime = BEACON_LOST_TIME;
+ // Need to sync Real Tx rate and our record.
+ // Then return for next DRS.
+ pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(InitTxRateIdx+1)*5];
+ pEntry->CurrTxRateIndex = InitTxRateIdx;
+ MlmeSetTxRate(pAd, pEntry, pCurrTxRate);
- MaxRssi = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2);
+ // reset all OneSecTx counters
+ RESET_ONE_SEC_TX_CNT(pEntry);
+ continue;
+ }
- //
- // calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics
- //
- TxOkCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + pAd->RalinkCounters.OneSecTxRetryOkCount;
- TxCnt = TxOkCnt + pAd->RalinkCounters.OneSecTxFailCount;
- if (TxCnt < 5)
+ // decide the next upgrade rate and downgrade rate, if any
+ if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
{
- TxPER = 0;
- TxPRR = 0;
+ UpRateIdx = CurrRateIdx + 1;
+ DownRateIdx = CurrRateIdx -1;
}
- else
+ else if (CurrRateIdx == 0)
+ {
+ UpRateIdx = CurrRateIdx + 1;
+ DownRateIdx = CurrRateIdx;
+ }
+ else if (CurrRateIdx == (TableSize - 1))
{
- TxPER = (pAd->RalinkCounters.OneSecTxFailCount * 100) / TxCnt;
- TxPRR = ((TxCnt - pAd->RalinkCounters.OneSecTxNoRetryOkCount) * 100) / TxCnt;
+ UpRateIdx = CurrRateIdx;
+ DownRateIdx = CurrRateIdx - 1;
}
- //
- // calculate RX PER - don't take RxPER into consideration if too few sample
- //
- RxCnt = pAd->RalinkCounters.OneSecRxOkCnt + pAd->RalinkCounters.OneSecRxFcsErrCnt;
- if (RxCnt < 5)
- RxPER = 0;
- else
- RxPER = (pAd->RalinkCounters.OneSecRxFcsErrCnt * 100) / RxCnt;
+ pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
- //
- // decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER
- //
- if (INFRA_ON(pAd) &&
- (pAd->RalinkCounters.OneSecTxNoRetryOkCount < 2) && // no heavy traffic
- (pAd->StaCfg.LastBeaconRxTime + BeaconLostTime < Now32))
+ if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
{
- DBGPRINT(RT_DEBUG_TRACE, ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n", BeaconLostTime, TxOkCnt));
- pAd->Mlme.ChannelQuality = 0;
+ TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
+ TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
}
else
{
- // Normalize Rssi
- if (MaxRssi > -40)
- NorRssi = 100;
- else if (MaxRssi < -90)
- NorRssi = 0;
- else
- NorRssi = (MaxRssi + 90) * 2;
-
- // ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER (RSSI 0..100), (TxPER 100..0), (RxPER 100..0)
- pAd->Mlme.ChannelQuality = (RSSI_WEIGHTING * NorRssi +
- TX_WEIGHTING * (100 - TxPRR) +
- RX_WEIGHTING* (100 - RxPER)) / 100;
- if (pAd->Mlme.ChannelQuality >= 100)
- pAd->Mlme.ChannelQuality = 100;
+ TrainUp = pCurrTxRate->TrainUp;
+ TrainDown = pCurrTxRate->TrainDown;
}
-}
-
-VOID MlmeSetTxRate(
- IN PRTMP_ADAPTER pAd,
- IN PMAC_TABLE_ENTRY pEntry,
- IN PRTMP_TX_RATE_SWITCH pTxRate)
-{
- UCHAR MaxMode = MODE_OFDM;
-
- MaxMode = MODE_HTGREENFIELD;
-
- if (pTxRate->STBC && (pAd->StaCfg.MaxHTPhyMode.field.STBC) && (pAd->Antenna.field.TxPath == 2))
- pAd->StaCfg.HTPhyMode.field.STBC = STBC_USE;
- else
- pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
+ //pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction;
- if (pTxRate->CurrMCS < MCS_AUTO)
- pAd->StaCfg.HTPhyMode.field.MCS = pTxRate->CurrMCS;
+ //
+ // Keep the last time TxRateChangeAction status.
+ //
+ pEntry->LastTimeTxRateChangeAction = pEntry->LastSecTxRateChangeAction;
- if (pAd->StaCfg.HTPhyMode.field.MCS > 7)
- pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
- if (ADHOC_ON(pAd))
- {
- // If peer adhoc is b-only mode, we can't send 11g rate.
- pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
- pEntry->HTPhyMode.field.STBC = STBC_NONE;
//
- // For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary
+ // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
+ // (criteria copied from RT2500 for Netopia case)
//
- pEntry->HTPhyMode.field.MODE = pTxRate->Mode;
- pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI;
- pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
-
- // Patch speed error in status page
- pAd->StaCfg.HTPhyMode.field.MODE = pEntry->HTPhyMode.field.MODE;
- }
- else
+ if (TxTotalCnt <= 15)
{
- if (pTxRate->Mode <= MaxMode)
- pAd->StaCfg.HTPhyMode.field.MODE = pTxRate->Mode;
+ CHAR idx = 0;
+ UCHAR TxRateIdx;
+ UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS5 =0, MCS6 = 0, MCS7 = 0;
+ UCHAR MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
+ UCHAR MCS20 = 0, MCS21 = 0, MCS22 = 0, MCS23 = 0; // 3*3
- if (pTxRate->ShortGI && (pAd->StaCfg.MaxHTPhyMode.field.ShortGI))
- pAd->StaCfg.HTPhyMode.field.ShortGI = GI_400;
- else
- pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
+ // check the existence and index of each needed MCS
+ while (idx < pTable[0])
+ {
+ pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(idx+1)*5];
- // Reexam each bandwidth's SGI support.
- if (pAd->StaCfg.HTPhyMode.field.ShortGI == GI_400)
+ if (pCurrTxRate->CurrMCS == MCS_0)
{
- if ((pEntry->HTPhyMode.field.BW == BW_20) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE)))
- pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
- if ((pEntry->HTPhyMode.field.BW == BW_40) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE)))
- pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
+ MCS0 = idx;
}
-
- // Turn RTS/CTS rate to 6Mbps.
- if ((pEntry->HTPhyMode.field.MCS == 0) && (pAd->StaCfg.HTPhyMode.field.MCS != 0))
+ else if (pCurrTxRate->CurrMCS == MCS_1)
{
- pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
- if (pAd->MacTab.fAnyBASession)
+ MCS1 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_2)
{
- AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+ MCS2 = idx;
}
- else
+ else if (pCurrTxRate->CurrMCS == MCS_3)
{
- AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+ MCS3 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_4)
+ {
+ MCS4 = idx;
}
+ else if (pCurrTxRate->CurrMCS == MCS_5)
+ {
+ MCS5 = idx;
}
- else if ((pEntry->HTPhyMode.field.MCS == 8) && (pAd->StaCfg.HTPhyMode.field.MCS != 8))
+ else if (pCurrTxRate->CurrMCS == MCS_6)
{
- pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
- if (pAd->MacTab.fAnyBASession)
+ MCS6 = idx;
+ }
+ //else if (pCurrTxRate->CurrMCS == MCS_7)
+ else if ((pCurrTxRate->CurrMCS == MCS_7) && (pCurrTxRate->ShortGI == GI_800)) // prevent the highest MCS using short GI when 1T and low throughput
{
- AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+ MCS7 = idx;
}
- else
+ else if (pCurrTxRate->CurrMCS == MCS_12)
{
- AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+ MCS12 = idx;
}
+ else if (pCurrTxRate->CurrMCS == MCS_13)
+ {
+ MCS13 = idx;
}
- else if ((pEntry->HTPhyMode.field.MCS != 0) && (pAd->StaCfg.HTPhyMode.field.MCS == 0))
+ else if (pCurrTxRate->CurrMCS == MCS_14)
{
- AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
-
+ MCS14 = idx;
}
- else if ((pEntry->HTPhyMode.field.MCS != 8) && (pAd->StaCfg.HTPhyMode.field.MCS == 8))
+ //else if ((pCurrTxRate->CurrMCS == MCS_15)/* && (pCurrTxRate->ShortGI == GI_800)*/) //we hope to use ShortGI as initial rate
+ else if ((pCurrTxRate->CurrMCS == MCS_15) && (pCurrTxRate->ShortGI == GI_800)) //we hope to use ShortGI as initial rate, however Atheros's chip has bugs when short GI
{
- AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+ MCS15 = idx;
}
+ else if (pCurrTxRate->CurrMCS == MCS_20) // 3*3
+ {
+ MCS20 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_21)
+ {
+ MCS21 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_22)
+ {
+ MCS22 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_23)
+ {
+ MCS23 = idx;
+ }
+ idx ++;
+ }
- pEntry->HTPhyMode.field.STBC = pAd->StaCfg.HTPhyMode.field.STBC;
- pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI;
- pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
- pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
-
- if ((pAd->StaCfg.MaxHTPhyMode.field.MODE == MODE_HTGREENFIELD) &&
- pAd->WIFItestbed.bGreenField)
- pEntry->HTPhyMode.field.MODE = MODE_HTGREENFIELD;
- }
-
- pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
-}
-
-/*
- ==========================================================================
- Description:
- This routine calculates the acumulated TxPER of eaxh TxRate. And
- according to the calculation result, change CommonCfg.TxRate which
- is the stable TX Rate we expect the Radio situation could sustained.
+ if (pAd->LatchRfRegs.Channel <= 14)
+ {
+ if (pAd->NicConfig2.field.ExternalLNAForG)
+ {
+ RssiOffset = 2;
+ }
+ else
+ {
+ RssiOffset = 5;
+ }
+ }
+ else
+ {
+ if (pAd->NicConfig2.field.ExternalLNAForA)
+ {
+ RssiOffset = 5;
+ }
+ else
+ {
+ RssiOffset = 8;
+ }
+ }
- CommonCfg.TxRate will change dynamically within {RATE_1/RATE_6, MaxTxRate}
- Output:
- CommonCfg.TxRate -
-
- IRQL = DISPATCH_LEVEL
-
- NOTE:
- call this routine every second
- ==========================================================================
- */
-VOID MlmeDynamicTxRateSwitching(
- IN PRTMP_ADAPTER pAd)
-{
- UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx;
- ULONG i, AccuTxTotalCnt = 0, TxTotalCnt;
- ULONG TxErrorRatio = 0;
- BOOLEAN bTxRateChanged, bUpgradeQuality = FALSE;
- PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL;
- PUCHAR pTable;
- UCHAR TableSize = 0;
- UCHAR InitTxRateIdx = 0, TrainUp, TrainDown;
- CHAR Rssi, RssiOffset = 0;
- TX_STA_CNT1_STRUC StaTx1;
- TX_STA_CNT0_STRUC TxStaCnt0;
- ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
- MAC_TABLE_ENTRY *pEntry;
-
- //
- // walk through MAC table, see if need to change AP's TX rate toward each entry
- //
- for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
- {
- pEntry = &pAd->MacTab.Content[i];
-
- // check if this entry need to switch rate automatically
- if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
- continue;
-
- if ((pAd->MacTab.Size == 1) || (pEntry->ValidAsDls))
- {
-#ifdef RT2860
- Rssi = RTMPMaxRssi(pAd, (CHAR)pAd->StaCfg.RssiSample.AvgRssi0, (CHAR)pAd->StaCfg.RssiSample.AvgRssi1, (CHAR)pAd->StaCfg.RssiSample.AvgRssi2);
-#endif
-#ifdef RT2870
- Rssi = RTMPMaxRssi(pAd,
- pAd->StaCfg.RssiSample.AvgRssi0,
- pAd->StaCfg.RssiSample.AvgRssi1,
- pAd->StaCfg.RssiSample.AvgRssi2);
-#endif
-
- // Update statistic counter
- RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
- RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
- pAd->bUpdateBcnCntDone = TRUE;
- TxRetransmit = StaTx1.field.TxRetransmit;
- TxSuccess = StaTx1.field.TxSuccess;
- TxFailCount = TxStaCnt0.field.TxFailCount;
- TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
-
- pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
- pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
- pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
- pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
- pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
- pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
-
- // if no traffic in the past 1-sec period, don't change TX rate,
- // but clear all bad history. because the bad history may affect the next
- // Chariot throughput test
- AccuTxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
- pAd->RalinkCounters.OneSecTxRetryOkCount +
- pAd->RalinkCounters.OneSecTxFailCount;
-
- if (TxTotalCnt)
- TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
- }
- else
- {
-#ifdef RT2860
- Rssi = RTMPMaxRssi(pAd, (CHAR)pEntry->RssiSample.AvgRssi0, (CHAR)pEntry->RssiSample.AvgRssi1, (CHAR)pEntry->RssiSample.AvgRssi2);
-#endif
-#ifdef RT2870
- if (INFRA_ON(pAd) && (i == 1))
- Rssi = RTMPMaxRssi(pAd,
- pAd->StaCfg.RssiSample.AvgRssi0,
- pAd->StaCfg.RssiSample.AvgRssi1,
- pAd->StaCfg.RssiSample.AvgRssi2);
- else
- Rssi = RTMPMaxRssi(pAd,
- pEntry->RssiSample.AvgRssi0,
- pEntry->RssiSample.AvgRssi1,
- pEntry->RssiSample.AvgRssi2);
-#endif
-
- TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
- pEntry->OneSecTxRetryOkCount +
- pEntry->OneSecTxFailCount;
-
- if (TxTotalCnt)
- TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
- }
-
- CurrRateIdx = pEntry->CurrTxRateIndex;
-
- MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
-
- if (CurrRateIdx >= TableSize)
- {
- CurrRateIdx = TableSize - 1;
- }
-
- // When switch from Fixed rate -> auto rate, the REAL TX rate might be different from pAd->CommonCfg.TxRateIndex.
- // So need to sync here.
- pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
- if ((pEntry->HTPhyMode.field.MCS != pCurrTxRate->CurrMCS)
- //&& (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
- )
- {
-
- // Need to sync Real Tx rate and our record.
- // Then return for next DRS.
- pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(InitTxRateIdx+1)*5];
- pEntry->CurrTxRateIndex = InitTxRateIdx;
- MlmeSetTxRate(pAd, pEntry, pCurrTxRate);
-
- // reset all OneSecTx counters
- RESET_ONE_SEC_TX_CNT(pEntry);
- continue;
- }
-
- // decide the next upgrade rate and downgrade rate, if any
- if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
- {
- UpRateIdx = CurrRateIdx + 1;
- DownRateIdx = CurrRateIdx -1;
- }
- else if (CurrRateIdx == 0)
- {
- UpRateIdx = CurrRateIdx + 1;
- DownRateIdx = CurrRateIdx;
- }
- else if (CurrRateIdx == (TableSize - 1))
- {
- UpRateIdx = CurrRateIdx;
- DownRateIdx = CurrRateIdx - 1;
- }
-
- pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
-
- if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
- {
- TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
- TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
- }
- else
- {
- TrainUp = pCurrTxRate->TrainUp;
- TrainDown = pCurrTxRate->TrainDown;
- }
-
- //pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction;
-
- //
- // Keep the last time TxRateChangeAction status.
- //
- pEntry->LastTimeTxRateChangeAction = pEntry->LastSecTxRateChangeAction;
-
-
-
- //
- // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
- // (criteria copied from RT2500 for Netopia case)
- //
- if (TxTotalCnt <= 15)
- {
- CHAR idx = 0;
- UCHAR TxRateIdx;
- //UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS7 = 0, MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
- UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS5 =0, MCS6 = 0, MCS7 = 0;
- UCHAR MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
- UCHAR MCS20 = 0, MCS21 = 0, MCS22 = 0, MCS23 = 0; // 3*3
-
- // check the existence and index of each needed MCS
- while (idx < pTable[0])
- {
- pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(idx+1)*5];
-
- if (pCurrTxRate->CurrMCS == MCS_0)
- {
- MCS0 = idx;
- }
- else if (pCurrTxRate->CurrMCS == MCS_1)
- {
- MCS1 = idx;
- }
- else if (pCurrTxRate->CurrMCS == MCS_2)
- {
- MCS2 = idx;
- }
- else if (pCurrTxRate->CurrMCS == MCS_3)
- {
- MCS3 = idx;
- }
- else if (pCurrTxRate->CurrMCS == MCS_4)
- {
- MCS4 = idx;
- }
- else if (pCurrTxRate->CurrMCS == MCS_5)
- {
- MCS5 = idx;
- }
- else if (pCurrTxRate->CurrMCS == MCS_6)
- {
- MCS6 = idx;
- }
- //else if (pCurrTxRate->CurrMCS == MCS_7)
- else if ((pCurrTxRate->CurrMCS == MCS_7) && (pCurrTxRate->ShortGI == GI_800)) // prevent the highest MCS using short GI when 1T and low throughput
- {
- MCS7 = idx;
- }
- else if (pCurrTxRate->CurrMCS == MCS_12)
- {
- MCS12 = idx;
- }
- else if (pCurrTxRate->CurrMCS == MCS_13)
- {
- MCS13 = idx;
- }
- else if (pCurrTxRate->CurrMCS == MCS_14)
- {
- MCS14 = idx;
- }
- else if ((pCurrTxRate->CurrMCS == MCS_15) && (pCurrTxRate->ShortGI == GI_800)) //we hope to use ShortGI as initial rate, however Atheros's chip has bugs when short GI
- {
- MCS15 = idx;
- }
- else if (pCurrTxRate->CurrMCS == MCS_20) // 3*3
- {
- MCS20 = idx;
- }
- else if (pCurrTxRate->CurrMCS == MCS_21)
- {
- MCS21 = idx;
- }
- else if (pCurrTxRate->CurrMCS == MCS_22)
- {
- MCS22 = idx;
- }
- else if (pCurrTxRate->CurrMCS == MCS_23)
- {
- MCS23 = idx;
- }
- idx ++;
- }
-
- if (pAd->LatchRfRegs.Channel <= 14)
- {
- if (pAd->NicConfig2.field.ExternalLNAForG)
- {
- RssiOffset = 2;
- }
- else
- {
- RssiOffset = 5;
- }
- }
- else
- {
- if (pAd->NicConfig2.field.ExternalLNAForA)
- {
- RssiOffset = 5;
- }
- else
- {
- RssiOffset = 8;
- }
- }
-
- /*if (MCS15)*/
- if ((pTable == RateSwitchTable11BGN3S) ||
- (pTable == RateSwitchTable11N3S) ||
- (pTable == RateSwitchTable))
- {// N mode with 3 stream // 3*3
- if (MCS23 && (Rssi >= -70))
- TxRateIdx = MCS15;
- else if (MCS22 && (Rssi >= -72))
- TxRateIdx = MCS14;
- else if (MCS21 && (Rssi >= -76))
- TxRateIdx = MCS13;
- else if (MCS20 && (Rssi >= -78))
- TxRateIdx = MCS12;
- else if (MCS4 && (Rssi >= -82))
- TxRateIdx = MCS4;
- else if (MCS3 && (Rssi >= -84))
- TxRateIdx = MCS3;
- else if (MCS2 && (Rssi >= -86))
- TxRateIdx = MCS2;
- else if (MCS1 && (Rssi >= -88))
- TxRateIdx = MCS1;
- else
- TxRateIdx = MCS0;
- }
- else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand)) // 3*3
- {// N mode with 2 stream
- if (MCS15 && (Rssi >= (-70+RssiOffset)))
- TxRateIdx = MCS15;
- else if (MCS14 && (Rssi >= (-72+RssiOffset)))
- TxRateIdx = MCS14;
- else if (MCS13 && (Rssi >= (-76+RssiOffset)))
- TxRateIdx = MCS13;
- else if (MCS12 && (Rssi >= (-78+RssiOffset)))
- TxRateIdx = MCS12;
- else if (MCS4 && (Rssi >= (-82+RssiOffset)))
- TxRateIdx = MCS4;
- else if (MCS3 && (Rssi >= (-84+RssiOffset)))
- TxRateIdx = MCS3;
- else if (MCS2 && (Rssi >= (-86+RssiOffset)))
- TxRateIdx = MCS2;
- else if (MCS1 && (Rssi >= (-88+RssiOffset)))
- TxRateIdx = MCS1;
- else
- TxRateIdx = MCS0;
- }
- else if ((pTable == RateSwitchTable11BGN1S) || (pTable == RateSwitchTable11N1S))
- {// N mode with 1 stream
- if (MCS7 && (Rssi > (-72+RssiOffset)))
- TxRateIdx = MCS7;
- else if (MCS6 && (Rssi > (-74+RssiOffset)))
- TxRateIdx = MCS6;
- else if (MCS5 && (Rssi > (-77+RssiOffset)))
- TxRateIdx = MCS5;
- else if (MCS4 && (Rssi > (-79+RssiOffset)))
- TxRateIdx = MCS4;
- else if (MCS3 && (Rssi > (-81+RssiOffset)))
- TxRateIdx = MCS3;
- else if (MCS2 && (Rssi > (-83+RssiOffset)))
- TxRateIdx = MCS2;
- else if (MCS1 && (Rssi > (-86+RssiOffset)))
- TxRateIdx = MCS1;
- else
- TxRateIdx = MCS0;
- }
- else
- {// Legacy mode
- if (MCS7 && (Rssi > -70))
- TxRateIdx = MCS7;
- else if (MCS6 && (Rssi > -74))
- TxRateIdx = MCS6;
- else if (MCS5 && (Rssi > -78))
- TxRateIdx = MCS5;
- else if (MCS4 && (Rssi > -82))
- TxRateIdx = MCS4;
- else if (MCS4 == 0) // for B-only mode
- TxRateIdx = MCS3;
- else if (MCS3 && (Rssi > -85))
- TxRateIdx = MCS3;
- else if (MCS2 && (Rssi > -87))
- TxRateIdx = MCS2;
- else if (MCS1 && (Rssi > -90))
- TxRateIdx = MCS1;
- else
- TxRateIdx = MCS0;
- }
-
- {
- pEntry->CurrTxRateIndex = TxRateIdx;
- pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
- MlmeSetTxRate(pAd, pEntry, pNextTxRate);
- }
-
- NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
- NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
- pEntry->fLastSecAccordingRSSI = TRUE;
- // reset all OneSecTx counters
- RESET_ONE_SEC_TX_CNT(pEntry);
-
- continue;
- }
-
- if (pEntry->fLastSecAccordingRSSI == TRUE)
- {
- pEntry->fLastSecAccordingRSSI = FALSE;
- pEntry->LastSecTxRateChangeAction = 0;
- // reset all OneSecTx counters
- RESET_ONE_SEC_TX_CNT(pEntry);
-
- continue;
- }
-
- do
- {
- BOOLEAN bTrainUpDown = FALSE;
-
- pEntry->CurrTxRateStableTime ++;
-
- // downgrade TX quality if PER >= Rate-Down threshold
- if (TxErrorRatio >= TrainDown)
- {
- bTrainUpDown = TRUE;
- pEntry->TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
- }
- // upgrade TX quality if PER <= Rate-Up threshold
- else if (TxErrorRatio <= TrainUp)
- {
- bTrainUpDown = TRUE;
- bUpgradeQuality = TRUE;
- if (pEntry->TxQuality[CurrRateIdx])
- pEntry->TxQuality[CurrRateIdx] --; // quality very good in CurrRate
-
- if (pEntry->TxRateUpPenalty)
- pEntry->TxRateUpPenalty --;
- else if (pEntry->TxQuality[UpRateIdx])
- pEntry->TxQuality[UpRateIdx] --; // may improve next UP rate's quality
- }
-
- pEntry->PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
-
- if (bTrainUpDown)
- {
- // perform DRS - consider TxRate Down first, then rate up.
- if ((CurrRateIdx != DownRateIdx) && (pEntry->TxQuality[CurrRateIdx] >= DRS_TX_QUALITY_WORST_BOUND))
- {
- pEntry->CurrTxRateIndex = DownRateIdx;
- }
- else if ((CurrRateIdx != UpRateIdx) && (pEntry->TxQuality[UpRateIdx] <= 0))
- {
- pEntry->CurrTxRateIndex = UpRateIdx;
- }
- }
- } while (FALSE);
-
- // if rate-up happen, clear all bad history of all TX rates
- if (pEntry->CurrTxRateIndex > CurrRateIdx)
- {
- pEntry->CurrTxRateStableTime = 0;
- pEntry->TxRateUpPenalty = 0;
- pEntry->LastSecTxRateChangeAction = 1; // rate UP
- NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
- NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
-
- //
- // For TxRate fast train up
- //
- if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
- {
- RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
-
- pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
- }
- bTxRateChanged = TRUE;
- }
- // if rate-down happen, only clear DownRate's bad history
- else if (pEntry->CurrTxRateIndex < CurrRateIdx)
- {
- pEntry->CurrTxRateStableTime = 0;
- pEntry->TxRateUpPenalty = 0; // no penalty
- pEntry->LastSecTxRateChangeAction = 2; // rate DOWN
- pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0;
- pEntry->PER[pEntry->CurrTxRateIndex] = 0;
-
- //
- // For TxRate fast train down
- //
- if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
- {
- RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
-
- pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
- }
- bTxRateChanged = TRUE;
- }
- else
- {
- pEntry->LastSecTxRateChangeAction = 0; // rate no change
- bTxRateChanged = FALSE;
- }
-
- pEntry->LastTxOkCount = TxSuccess;
-
- // reset all OneSecTx counters
- RESET_ONE_SEC_TX_CNT(pEntry);
-
- pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
- if (bTxRateChanged && pNextTxRate)
- {
- MlmeSetTxRate(pAd, pEntry, pNextTxRate);
- }
- }
-}
-
-/*
- ========================================================================
- Routine Description:
- Station side, Auto TxRate faster train up timer call back function.
-
- Arguments:
- SystemSpecific1 - Not used.
- FunctionContext - Pointer to our Adapter context.
- SystemSpecific2 - Not used.
- SystemSpecific3 - Not used.
-
- Return Value:
- None
-
- ========================================================================
-*/
-VOID StaQuickResponeForRateUpExec(
- IN PVOID SystemSpecific1,
- IN PVOID FunctionContext,
- IN PVOID SystemSpecific2,
- IN PVOID SystemSpecific3)
-{
- PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext;
- UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0;
- ULONG TxTotalCnt;
- ULONG TxErrorRatio = 0;
-#ifdef RT2860
- BOOLEAN bTxRateChanged = TRUE; //, bUpgradeQuality = FALSE;
-#endif
-#ifdef RT2870
- BOOLEAN bTxRateChanged; //, bUpgradeQuality = FALSE;
-#endif
- PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL;
- PUCHAR pTable;
- UCHAR TableSize = 0;
- UCHAR InitTxRateIdx = 0, TrainUp, TrainDown;
- TX_STA_CNT1_STRUC StaTx1;
- TX_STA_CNT0_STRUC TxStaCnt0;
- CHAR Rssi, ratio;
- ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
- MAC_TABLE_ENTRY *pEntry;
- ULONG i;
-
- pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
-
- //
- // walk through MAC table, see if need to change AP's TX rate toward each entry
- //
- for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
- {
- pEntry = &pAd->MacTab.Content[i];
-
- // check if this entry need to switch rate automatically
- if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
- continue;
-
-#ifdef RT2860
- //Rssi = RTMPMaxRssi(pAd, (CHAR)pAd->StaCfg.AvgRssi0, (CHAR)pAd->StaCfg.AvgRssi1, (CHAR)pAd->StaCfg.AvgRssi2);
- if (pAd->Antenna.field.TxPath > 1)
- Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
- else
- Rssi = pAd->StaCfg.RssiSample.AvgRssi0;
-#endif
-#ifdef RT2870
- if (INFRA_ON(pAd) && (i == 1))
- Rssi = RTMPMaxRssi(pAd,
- pAd->StaCfg.RssiSample.AvgRssi0,
- pAd->StaCfg.RssiSample.AvgRssi1,
- pAd->StaCfg.RssiSample.AvgRssi2);
- else
- Rssi = RTMPMaxRssi(pAd,
- pEntry->RssiSample.AvgRssi0,
- pEntry->RssiSample.AvgRssi1,
- pEntry->RssiSample.AvgRssi2);
-#endif
-
- CurrRateIdx = pAd->CommonCfg.TxRateIndex;
-
- MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
-
- // decide the next upgrade rate and downgrade rate, if any
- if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
- {
- UpRateIdx = CurrRateIdx + 1;
- DownRateIdx = CurrRateIdx -1;
- }
- else if (CurrRateIdx == 0)
- {
- UpRateIdx = CurrRateIdx + 1;
- DownRateIdx = CurrRateIdx;
- }
- else if (CurrRateIdx == (TableSize - 1))
- {
- UpRateIdx = CurrRateIdx;
- DownRateIdx = CurrRateIdx - 1;
- }
-
- pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
-
- if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
- {
- TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
- TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
- }
- else
- {
- TrainUp = pCurrTxRate->TrainUp;
- TrainDown = pCurrTxRate->TrainDown;
- }
-
- if (pAd->MacTab.Size == 1)
- {
- // Update statistic counter
- RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
- RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
-
- TxRetransmit = StaTx1.field.TxRetransmit;
- TxSuccess = StaTx1.field.TxSuccess;
- TxFailCount = TxStaCnt0.field.TxFailCount;
- TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
-
- pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
- pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
- pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
- pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
- pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
- pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
-
- if (TxTotalCnt)
- TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
- }
- else
- {
- TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
- pEntry->OneSecTxRetryOkCount +
- pEntry->OneSecTxFailCount;
-
- if (TxTotalCnt)
- TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
- }
-
-
- //
- // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
- // (criteria copied from RT2500 for Netopia case)
- //
- if (TxTotalCnt <= 12)
- {
- NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
- NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
-
- if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
- {
- pAd->CommonCfg.TxRateIndex = DownRateIdx;
- pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
- }
- else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
- {
- pAd->CommonCfg.TxRateIndex = UpRateIdx;
- }
-
- DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: TxTotalCnt <= 15, train back to original rate \n"));
- return;
- }
-
- do
- {
- ULONG OneSecTxNoRetryOKRationCount;
-
- if (pAd->DrsCounters.LastTimeTxRateChangeAction == 0)
- ratio = 5;
- else
- ratio = 4;
-
- // downgrade TX quality if PER >= Rate-Down threshold
- if (TxErrorRatio >= TrainDown)
- {
- pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
- }
-
- pAd->DrsCounters.PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
-
- OneSecTxNoRetryOKRationCount = (TxSuccess * ratio);
-
- // perform DRS - consider TxRate Down first, then rate up.
- if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
- {
- if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
- {
- pAd->CommonCfg.TxRateIndex = DownRateIdx;
- pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
-
- }
-
- }
- else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
- {
- if ((TxErrorRatio >= 50) || (TxErrorRatio >= TrainDown))
- {
-
- }
- else if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
- {
- pAd->CommonCfg.TxRateIndex = UpRateIdx;
- }
- }
- }while (FALSE);
-
- // if rate-up happen, clear all bad history of all TX rates
- if (pAd->CommonCfg.TxRateIndex > CurrRateIdx)
- {
- pAd->DrsCounters.TxRateUpPenalty = 0;
- NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
- NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
-#ifdef RT2870
- bTxRateChanged = TRUE;
-#endif
- }
- // if rate-down happen, only clear DownRate's bad history
- else if (pAd->CommonCfg.TxRateIndex < CurrRateIdx)
- {
- DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: --TX rate from %d to %d \n", CurrRateIdx, pAd->CommonCfg.TxRateIndex));
-
- pAd->DrsCounters.TxRateUpPenalty = 0; // no penalty
- pAd->DrsCounters.TxQuality[pAd->CommonCfg.TxRateIndex] = 0;
- pAd->DrsCounters.PER[pAd->CommonCfg.TxRateIndex] = 0;
-#ifdef RT2870
- bTxRateChanged = TRUE;
-#endif
- }
- else
- {
- bTxRateChanged = FALSE;
- }
-
- pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pAd->CommonCfg.TxRateIndex+1)*5];
- if (bTxRateChanged && pNextTxRate)
- {
- MlmeSetTxRate(pAd, pEntry, pNextTxRate);
- }
- }
-}
-
-/*
- ==========================================================================
- Description:
- This routine is executed periodically inside MlmePeriodicExec() after
- association with an AP.
- It checks if StaCfg.Psm is consistent with user policy (recorded in
- StaCfg.WindowsPowerMode). If not, enforce user policy. However,
- there're some conditions to consider:
- 1. we don't support power-saving in ADHOC mode, so Psm=PWR_ACTIVE all
- the time when Mibss==TRUE
- 2. When link up in INFRA mode, Psm should not be switch to PWR_SAVE
- if outgoing traffic available in TxRing or MgmtRing.
- Output:
- 1. change pAd->StaCfg.Psm to PWR_SAVE or leave it untouched
-
- IRQL = DISPATCH_LEVEL
-
- ==========================================================================
- */
-VOID MlmeCheckPsmChange(
- IN PRTMP_ADAPTER pAd,
- IN ULONG Now32)
-{
- ULONG PowerMode;
-
- // condition -
- // 1. Psm maybe ON only happen in INFRASTRUCTURE mode
- // 2. user wants either MAX_PSP or FAST_PSP
- // 3. but current psm is not in PWR_SAVE
- // 4. CNTL state machine is not doing SCANning
- // 5. no TX SUCCESS event for the past 1-sec period
-#ifdef NDIS51_MINIPORT
- if (pAd->StaCfg.WindowsPowerProfile == NdisPowerProfileBattery)
- PowerMode = pAd->StaCfg.WindowsBatteryPowerMode;
- else
-#endif
- PowerMode = pAd->StaCfg.WindowsPowerMode;
-
- if (INFRA_ON(pAd) &&
- (PowerMode != Ndis802_11PowerModeCAM) &&
- (pAd->StaCfg.Psm == PWR_ACTIVE) &&
-#ifdef RT2860
- RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP))
-#else
- (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE))
-#endif
- {
- // add by johnli, use Rx OK data count per second to calculate throughput
- // If Ttraffic is too high ( > 400 Rx per second), don't go to sleep mode. If tx rate is low, use low criteria
- // Mode=CCK/MCS=3 => 11 Mbps, Mode=OFDM/MCS=3 => 18 Mbps
- if (((pAd->StaCfg.HTPhyMode.field.MCS <= 3) &&
- (pAd->RalinkCounters.OneSecRxOkDataCnt < (ULONG)100)) ||
- ((pAd->StaCfg.HTPhyMode.field.MCS > 3) &&
- (pAd->RalinkCounters.OneSecRxOkDataCnt < (ULONG)400)))
- {
- // Get this time
- NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime);
- pAd->RalinkCounters.RxCountSinceLastNULL = 0;
- MlmeSetPsmBit(pAd, PWR_SAVE);
- if (!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
- {
- RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
- }
- else
- {
- RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
- }
- }
- }
-}
-
-// IRQL = PASSIVE_LEVEL
-// IRQL = DISPATCH_LEVEL
-VOID MlmeSetPsmBit(
- IN PRTMP_ADAPTER pAd,
- IN USHORT psm)
-{
- AUTO_RSP_CFG_STRUC csr4;
-
- pAd->StaCfg.Psm = psm;
- RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
- csr4.field.AckCtsPsmBit = (psm == PWR_SAVE)? 1:0;
- RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
-
- DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetPsmBit = %d\n", psm));
-}
-
-// IRQL = DISPATCH_LEVEL
-VOID MlmeSetTxPreamble(
- IN PRTMP_ADAPTER pAd,
- IN USHORT TxPreamble)
-{
- AUTO_RSP_CFG_STRUC csr4;
-
- //
- // Always use Long preamble before verifiation short preamble functionality works well.
- // Todo: remove the following line if short preamble functionality works
- //
- //TxPreamble = Rt802_11PreambleLong;
-
- RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
- if (TxPreamble == Rt802_11PreambleLong)
- {
- DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= LONG PREAMBLE)\n"));
- OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
- csr4.field.AutoResponderPreamble = 0;
- }
- else
- {
- // NOTE: 1Mbps should always use long preamble
- DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= SHORT PREAMBLE)\n"));
- OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
- csr4.field.AutoResponderPreamble = 1;
- }
-
- RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
-}
-
-/*
- ==========================================================================
- Description:
- Update basic rate bitmap
- ==========================================================================
- */
-
-VOID UpdateBasicRateBitmap(
- IN PRTMP_ADAPTER pAdapter)
-{
- INT i, j;
- /* 1 2 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */
- UCHAR rate[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
- UCHAR *sup_p = pAdapter->CommonCfg.SupRate;
- UCHAR *ext_p = pAdapter->CommonCfg.ExtRate;
- ULONG bitmap = pAdapter->CommonCfg.BasicRateBitmap;
-
-
- /* if A mode, always use fix BasicRateBitMap */
- //if (pAdapter->CommonCfg.Channel == PHY_11A)
- if (pAdapter->CommonCfg.Channel > 14)
- pAdapter->CommonCfg.BasicRateBitmap = 0x150; /* 6, 12, 24M */
- /* End of if */
-
- if (pAdapter->CommonCfg.BasicRateBitmap > 4095)
- {
- /* (2 ^ MAX_LEN_OF_SUPPORTED_RATES) -1 */
- return;
- } /* End of if */
-
- for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
- {
- sup_p[i] &= 0x7f;
- ext_p[i] &= 0x7f;
- } /* End of for */
-
- for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
- {
- if (bitmap & (1 << i))
- {
- for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
- {
- if (sup_p[j] == rate[i])
- sup_p[j] |= 0x80;
- /* End of if */
- } /* End of for */
-
- for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
- {
- if (ext_p[j] == rate[i])
- ext_p[j] |= 0x80;
- /* End of if */
- } /* End of for */
- } /* End of if */
- } /* End of for */
-} /* End of UpdateBasicRateBitmap */
-
-// IRQL = PASSIVE_LEVEL
-// IRQL = DISPATCH_LEVEL
-// bLinkUp is to identify the inital link speed.
-// TRUE indicates the rate update at linkup, we should not try to set the rate at 54Mbps.
-VOID MlmeUpdateTxRates(
- IN PRTMP_ADAPTER pAd,
- IN BOOLEAN bLinkUp,
- IN UCHAR apidx)
-{
- int i, num;
- UCHAR Rate = RATE_6, MaxDesire = RATE_1, MaxSupport = RATE_1;
- UCHAR MinSupport = RATE_54;
- ULONG BasicRateBitmap = 0;
- UCHAR CurrBasicRate = RATE_1;
- UCHAR *pSupRate, SupRateLen, *pExtRate, ExtRateLen;
- PHTTRANSMIT_SETTING pHtPhy = NULL;
- PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
- PHTTRANSMIT_SETTING pMinHtPhy = NULL;
- BOOLEAN *auto_rate_cur_p;
- UCHAR HtMcs = MCS_AUTO;
-
- // find max desired rate
- UpdateBasicRateBitmap(pAd);
-
- num = 0;
- auto_rate_cur_p = NULL;
- for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
- {
- switch (pAd->CommonCfg.DesireRate[i] & 0x7f)
- {
- case 2: Rate = RATE_1; num++; break;
- case 4: Rate = RATE_2; num++; break;
- case 11: Rate = RATE_5_5; num++; break;
- case 22: Rate = RATE_11; num++; break;
- case 12: Rate = RATE_6; num++; break;
- case 18: Rate = RATE_9; num++; break;
- case 24: Rate = RATE_12; num++; break;
- case 36: Rate = RATE_18; num++; break;
- case 48: Rate = RATE_24; num++; break;
- case 72: Rate = RATE_36; num++; break;
- case 96: Rate = RATE_48; num++; break;
- case 108: Rate = RATE_54; num++; break;
- //default: Rate = RATE_1; break;
- }
- if (MaxDesire < Rate) MaxDesire = Rate;
- }
-
-//===========================================================================
-//===========================================================================
- {
- pHtPhy = &pAd->StaCfg.HTPhyMode;
- pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
- pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
-
- auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
- HtMcs = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
-
- if ((pAd->StaCfg.BssType == BSS_ADHOC) &&
- (pAd->CommonCfg.PhyMode == PHY_11B) &&
- (MaxDesire > RATE_11))
- {
- MaxDesire = RATE_11;
- }
- }
-
- pAd->CommonCfg.MaxDesiredRate = MaxDesire;
- pMinHtPhy->word = 0;
- pMaxHtPhy->word = 0;
- pHtPhy->word = 0;
-
- // Auto rate switching is enabled only if more than one DESIRED RATES are
- // specified; otherwise disabled
- if (num <= 1)
- {
- *auto_rate_cur_p = FALSE;
- }
- else
- {
- *auto_rate_cur_p = TRUE;
- }
-
-#if 1
- if (HtMcs != MCS_AUTO)
- {
- *auto_rate_cur_p = FALSE;
- }
- else
- {
- *auto_rate_cur_p = TRUE;
- }
-#endif
-
- if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
- {
- pSupRate = &pAd->StaActive.SupRate[0];
- pExtRate = &pAd->StaActive.ExtRate[0];
- SupRateLen = pAd->StaActive.SupRateLen;
- ExtRateLen = pAd->StaActive.ExtRateLen;
- }
- else
- {
- pSupRate = &pAd->CommonCfg.SupRate[0];
- pExtRate = &pAd->CommonCfg.ExtRate[0];
- SupRateLen = pAd->CommonCfg.SupRateLen;
- ExtRateLen = pAd->CommonCfg.ExtRateLen;
- }
-
- // find max supported rate
- for (i=0; i<SupRateLen; i++)
- {
- switch (pSupRate[i] & 0x7f)
- {
- case 2: Rate = RATE_1; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0001; break;
- case 4: Rate = RATE_2; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0002; break;
- case 11: Rate = RATE_5_5; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0004; break;
- case 22: Rate = RATE_11; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0008; break;
- case 12: Rate = RATE_6; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 0x0010; break;
- case 18: Rate = RATE_9; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0020; break;
- case 24: Rate = RATE_12; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 0x0040; break;
- case 36: Rate = RATE_18; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0080; break;
- case 48: Rate = RATE_24; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 0x0100; break;
- case 72: Rate = RATE_36; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0200; break;
- case 96: Rate = RATE_48; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0400; break;
- case 108: Rate = RATE_54; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0800; break;
- default: Rate = RATE_1; break;
- }
- if (MaxSupport < Rate) MaxSupport = Rate;
-
- if (MinSupport > Rate) MinSupport = Rate;
- }
-
- for (i=0; i<ExtRateLen; i++)
- {
- switch (pExtRate[i] & 0x7f)
- {
- case 2: Rate = RATE_1; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0001; break;
- case 4: Rate = RATE_2; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0002; break;
- case 11: Rate = RATE_5_5; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0004; break;
- case 22: Rate = RATE_11; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0008; break;
- case 12: Rate = RATE_6; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 0x0010; break;
- case 18: Rate = RATE_9; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0020; break;
- case 24: Rate = RATE_12; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 0x0040; break;
- case 36: Rate = RATE_18; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0080; break;
- case 48: Rate = RATE_24; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 0x0100; break;
- case 72: Rate = RATE_36; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0200; break;
- case 96: Rate = RATE_48; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0400; break;
- case 108: Rate = RATE_54; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0800; break;
- default: Rate = RATE_1; break;
- }
- if (MaxSupport < Rate) MaxSupport = Rate;
-
- if (MinSupport > Rate) MinSupport = Rate;
- }
-
- RTMP_IO_WRITE32(pAd, LEGACY_BASIC_RATE, BasicRateBitmap);
-
- // calculate the exptected ACK rate for each TX rate. This info is used to caculate
- // the DURATION field of outgoing uniicast DATA/MGMT frame
- for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
- {
- if (BasicRateBitmap & (0x01 << i))
- CurrBasicRate = (UCHAR)i;
- pAd->CommonCfg.ExpectedACKRate[i] = CurrBasicRate;
- }
-
- DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateTxRates[MaxSupport = %d] = MaxDesire %d Mbps\n", RateIdToMbps[MaxSupport], RateIdToMbps[MaxDesire]));
- // max tx rate = min {max desire rate, max supported rate}
- if (MaxSupport < MaxDesire)
- pAd->CommonCfg.MaxTxRate = MaxSupport;
- else
- pAd->CommonCfg.MaxTxRate = MaxDesire;
-
- pAd->CommonCfg.MinTxRate = MinSupport;
- if (*auto_rate_cur_p)
- {
- short dbm = 0;
-
- dbm = pAd->StaCfg.RssiSample.AvgRssi0 - pAd->BbpRssiToDbmDelta;
-
- if (bLinkUp == TRUE)
- pAd->CommonCfg.TxRate = RATE_24;
- else
- pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
-
- if (dbm < -75)
- pAd->CommonCfg.TxRate = RATE_11;
- else if (dbm < -70)
- pAd->CommonCfg.TxRate = RATE_24;
-
- // should never exceed MaxTxRate (consider 11B-only mode)
- if (pAd->CommonCfg.TxRate > pAd->CommonCfg.MaxTxRate)
- pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
-
- pAd->CommonCfg.TxRateIndex = 0;
- }
- else
- {
- pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
- pHtPhy->field.MCS = (pAd->CommonCfg.MaxTxRate > 3) ? (pAd->CommonCfg.MaxTxRate - 4) : pAd->CommonCfg.MaxTxRate;
- pHtPhy->field.MODE = (pAd->CommonCfg.MaxTxRate > 3) ? MODE_OFDM : MODE_CCK;
-
- pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC = pHtPhy->field.STBC;
- pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI = pHtPhy->field.ShortGI;
- pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS = pHtPhy->field.MCS;
- pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE = pHtPhy->field.MODE;
- }
-
- if (pAd->CommonCfg.TxRate <= RATE_11)
- {
- pMaxHtPhy->field.MODE = MODE_CCK;
- pMaxHtPhy->field.MCS = pAd->CommonCfg.TxRate;
- pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;
- }
- else
- {
- pMaxHtPhy->field.MODE = MODE_OFDM;
- pMaxHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.TxRate];
- if (pAd->CommonCfg.MinTxRate >= RATE_6 && (pAd->CommonCfg.MinTxRate <= RATE_54))
- {pMinHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MinTxRate];}
- else
- {pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;}
- }
-
- pHtPhy->word = (pMaxHtPhy->word);
- if (bLinkUp && (pAd->OpMode == OPMODE_STA))
- {
- pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word = pHtPhy->word;
- pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word = pMaxHtPhy->word;
- pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word = pMinHtPhy->word;
- }
- else
- {
- switch (pAd->CommonCfg.PhyMode)
- {
- case PHY_11BG_MIXED:
- case PHY_11B:
- case PHY_11BGN_MIXED:
- pAd->CommonCfg.MlmeRate = RATE_1;
- pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
- pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
- pAd->CommonCfg.RtsRate = RATE_11;
- break;
- case PHY_11G:
- case PHY_11A:
- case PHY_11AGN_MIXED:
- case PHY_11GN_MIXED:
- case PHY_11N_2_4G:
- case PHY_11AN_MIXED:
- case PHY_11N_5G:
- pAd->CommonCfg.MlmeRate = RATE_6;
- pAd->CommonCfg.RtsRate = RATE_6;
- pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
- pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
- break;
- case PHY_11ABG_MIXED:
- case PHY_11ABGN_MIXED:
- if (pAd->CommonCfg.Channel <= 14)
- {
- pAd->CommonCfg.MlmeRate = RATE_1;
- pAd->CommonCfg.RtsRate = RATE_1;
- pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
- pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
- }
- else
- {
- pAd->CommonCfg.MlmeRate = RATE_6;
- pAd->CommonCfg.RtsRate = RATE_6;
- pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
- pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
- }
- break;
- default: // error
- pAd->CommonCfg.MlmeRate = RATE_6;
- pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
- pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
- pAd->CommonCfg.RtsRate = RATE_1;
- break;
- }
- //
- // Keep Basic Mlme Rate.
- //
- pAd->MacTab.Content[MCAST_WCID].HTPhyMode.word = pAd->CommonCfg.MlmeTransmit.word;
- if (pAd->CommonCfg.MlmeTransmit.field.MODE == MODE_OFDM)
- pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[RATE_24];
- else
- pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = RATE_1;
- pAd->CommonCfg.BasicMlmeRate = pAd->CommonCfg.MlmeRate;
- }
-
- DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n",
- RateIdToMbps[MaxDesire], RateIdToMbps[MaxSupport], RateIdToMbps[pAd->CommonCfg.MaxTxRate], RateIdToMbps[pAd->CommonCfg.MinTxRate],
- /*OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)*/*auto_rate_cur_p));
- DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n",
- RateIdToMbps[pAd->CommonCfg.TxRate], RateIdToMbps[pAd->CommonCfg.RtsRate], BasicRateBitmap));
- DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateTxRates (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n",
- pAd->CommonCfg.MlmeTransmit.word, pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word ,pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word ,pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word ));
-}
-
-/*
- ==========================================================================
- Description:
- This function update HT Rate setting.
- Input Wcid value is valid for 2 case :
- 1. it's used for Station in infra mode that copy AP rate to Mactable.
- 2. OR Station in adhoc mode to copy peer's HT rate to Mactable.
-
- IRQL = DISPATCH_LEVEL
-
- ==========================================================================
- */
-VOID MlmeUpdateHtTxRates(
- IN PRTMP_ADAPTER pAd,
- IN UCHAR apidx)
-{
- UCHAR StbcMcs; //j, StbcMcs, bitmask;
- CHAR i; // 3*3
- RT_HT_CAPABILITY *pRtHtCap = NULL;
- RT_HT_PHY_INFO *pActiveHtPhy = NULL;
- ULONG BasicMCS;
- UCHAR j, bitmask;
- PRT_HT_PHY_INFO pDesireHtPhy = NULL;
- PHTTRANSMIT_SETTING pHtPhy = NULL;
- PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
- PHTTRANSMIT_SETTING pMinHtPhy = NULL;
- BOOLEAN *auto_rate_cur_p;
-
- DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates===> \n"));
-
- auto_rate_cur_p = NULL;
-
- {
- pDesireHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
- pActiveHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
- pHtPhy = &pAd->StaCfg.HTPhyMode;
- pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
- pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
-
- auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
- }
-
- if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
- {
- if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
- return;
-
- pRtHtCap = &pAd->StaActive.SupportedHtPhy;
- pActiveHtPhy = &pAd->StaActive.SupportedPhyInfo;
- StbcMcs = (UCHAR)pAd->MlmeAux.AddHtInfo.AddHtInfo3.StbcMcs;
- BasicMCS =pAd->MlmeAux.AddHtInfo.MCSSet[0]+(pAd->MlmeAux.AddHtInfo.MCSSet[1]<<8)+(StbcMcs<<16);
- if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
- pMaxHtPhy->field.STBC = STBC_USE;
- else
- pMaxHtPhy->field.STBC = STBC_NONE;
- }
- else
- {
- if (pDesireHtPhy->bHtEnable == FALSE)
- return;
-
- pRtHtCap = &pAd->CommonCfg.DesiredHtPhy;
- StbcMcs = (UCHAR)pAd->CommonCfg.AddHTInfo.AddHtInfo3.StbcMcs;
- BasicMCS = pAd->CommonCfg.AddHTInfo.MCSSet[0]+(pAd->CommonCfg.AddHTInfo.MCSSet[1]<<8)+(StbcMcs<<16);
- if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
- pMaxHtPhy->field.STBC = STBC_USE;
- else
- pMaxHtPhy->field.STBC = STBC_NONE;
- }
-
- // Decide MAX ht rate.
- if ((pRtHtCap->GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
- pMaxHtPhy->field.MODE = MODE_HTGREENFIELD;
- else
- pMaxHtPhy->field.MODE = MODE_HTMIX;
-
- if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth) && (pRtHtCap->ChannelWidth))
- pMaxHtPhy->field.BW = BW_40;
- else
- pMaxHtPhy->field.BW = BW_20;
-
- if (pMaxHtPhy->field.BW == BW_20)
- pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 & pRtHtCap->ShortGIfor20);
- else
- pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 & pRtHtCap->ShortGIfor40);
-
- for (i=23; i>=0; i--) // 3*3
- {
- j = i/8;
- bitmask = (1<<(i-(j*8)));
-
- if ((pActiveHtPhy->MCSSet[j] & bitmask) && (pDesireHtPhy->MCSSet[j] & bitmask))
- {
- pMaxHtPhy->field.MCS = i;
- break;
- }
-
- if (i==0)
- break;
- }
-
- // Copy MIN ht rate. rt2860???
- pMinHtPhy->field.BW = BW_20;
- pMinHtPhy->field.MCS = 0;
- pMinHtPhy->field.STBC = 0;
- pMinHtPhy->field.ShortGI = 0;
- //If STA assigns fixed rate. update to fixed here.
- if ( (pAd->OpMode == OPMODE_STA) && (pDesireHtPhy->MCSSet[0] != 0xff))
- {
- if (pDesireHtPhy->MCSSet[4] != 0)
- {
- pMaxHtPhy->field.MCS = 32;
- pMinHtPhy->field.MCS = 32;
- DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n",pMinHtPhy->field.MCS));
- }
-
- for (i=23; (CHAR)i >= 0; i--) // 3*3
- {
- j = i/8;
- bitmask = (1<<(i-(j*8)));
- if ( (pDesireHtPhy->MCSSet[j] & bitmask) && (pActiveHtPhy->MCSSet[j] & bitmask))
- {
- pMaxHtPhy->field.MCS = i;
- pMinHtPhy->field.MCS = i;
- break;
- }
- if (i==0)
- break;
- }
- }
-
- // Decide ht rate
- pHtPhy->field.STBC = pMaxHtPhy->field.STBC;
- pHtPhy->field.BW = pMaxHtPhy->field.BW;
- pHtPhy->field.MODE = pMaxHtPhy->field.MODE;
- pHtPhy->field.MCS = pMaxHtPhy->field.MCS;
- pHtPhy->field.ShortGI = pMaxHtPhy->field.ShortGI;
-
- // use default now. rt2860
- if (pDesireHtPhy->MCSSet[0] != 0xff)
- *auto_rate_cur_p = FALSE;
- else
- *auto_rate_cur_p = TRUE;
-
- DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateHtTxRates<---.AMsduSize = %d \n", pAd->CommonCfg.DesiredHtPhy.AmsduSize ));
- DBGPRINT(RT_DEBUG_TRACE,("TX: MCS[0] = %x (choose %d), BW = %d, ShortGI = %d, MODE = %d, \n", pActiveHtPhy->MCSSet[0],pHtPhy->field.MCS,
- pHtPhy->field.BW, pHtPhy->field.ShortGI, pHtPhy->field.MODE));
- DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== \n"));
-}
-
-// IRQL = DISPATCH_LEVEL
-VOID MlmeRadioOff(
- IN PRTMP_ADAPTER pAd)
-{
- RT28XX_MLME_RADIO_OFF(pAd);
-}
-
-// IRQL = DISPATCH_LEVEL
-VOID MlmeRadioOn(
- IN PRTMP_ADAPTER pAd)
-{
- RT28XX_MLME_RADIO_ON(pAd);
-}
-
-// ===========================================================================================
-// bss_table.c
-// ===========================================================================================
-
-
-/*! \brief initialize BSS table
- * \param p_tab pointer to the table
- * \return none
- * \pre
- * \post
-
- IRQL = PASSIVE_LEVEL
- IRQL = DISPATCH_LEVEL
-
- */
-VOID BssTableInit(
- IN BSS_TABLE *Tab)
-{
- int i;
-
- Tab->BssNr = 0;
- Tab->BssOverlapNr = 0;
- for (i = 0; i < MAX_LEN_OF_BSS_TABLE; i++)
- {
- NdisZeroMemory(&Tab->BssEntry[i], sizeof(BSS_ENTRY));
- Tab->BssEntry[i].Rssi = -127; // initial the rssi as a minimum value
- }
-}
-
-VOID BATableInit(
- IN PRTMP_ADAPTER pAd,
- IN BA_TABLE *Tab)
-{
- int i;
-
- Tab->numAsOriginator = 0;
- Tab->numAsRecipient = 0;
- NdisAllocateSpinLock(&pAd->BATabLock);
- for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++)
- {
- Tab->BARecEntry[i].REC_BA_Status = Recipient_NONE;
- NdisAllocateSpinLock(&(Tab->BARecEntry[i].RxReRingLock));
- }
- for (i = 0; i < MAX_LEN_OF_BA_ORI_TABLE; i++)
- {
- Tab->BAOriEntry[i].ORI_BA_Status = Originator_NONE;
- }
-}
-
-/*! \brief search the BSS table by SSID
- * \param p_tab pointer to the bss table
- * \param ssid SSID string
- * \return index of the table, BSS_NOT_FOUND if not in the table
- * \pre
- * \post
- * \note search by sequential search
-
- IRQL = DISPATCH_LEVEL
-
- */
-ULONG BssTableSearch(
- IN BSS_TABLE *Tab,
- IN PUCHAR pBssid,
- IN UCHAR Channel)
-{
- UCHAR i;
-
- for (i = 0; i < Tab->BssNr; i++)
- {
- //
- // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
- // We should distinguish this case.
- //
- if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
- ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
- MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid))
- {
- return i;
- }
- }
- return (ULONG)BSS_NOT_FOUND;
-}
-
-ULONG BssSsidTableSearch(
- IN BSS_TABLE *Tab,
- IN PUCHAR pBssid,
- IN PUCHAR pSsid,
- IN UCHAR SsidLen,
- IN UCHAR Channel)
-{
- UCHAR i;
-
- for (i = 0; i < Tab->BssNr; i++)
- {
- //
- // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
- // We should distinguish this case.
- //
- if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
- ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
- MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid) &&
- SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen))
- {
- return i;
- }
- }
- return (ULONG)BSS_NOT_FOUND;
-}
-
-ULONG BssTableSearchWithSSID(
- IN BSS_TABLE *Tab,
- IN PUCHAR Bssid,
- IN PUCHAR pSsid,
- IN UCHAR SsidLen,
- IN UCHAR Channel)
-{
- UCHAR i;
-
- for (i = 0; i < Tab->BssNr; i++)
- {
- if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
- ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
- MAC_ADDR_EQUAL(&(Tab->BssEntry[i].Bssid), Bssid) &&
- (SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen) ||
- (NdisEqualMemory(pSsid, ZeroSsid, SsidLen)) ||
- (NdisEqualMemory(Tab->BssEntry[i].Ssid, ZeroSsid, Tab->BssEntry[i].SsidLen))))
- {
- return i;
- }
- }
- return (ULONG)BSS_NOT_FOUND;
-}
-
-// IRQL = DISPATCH_LEVEL
-VOID BssTableDeleteEntry(
- IN OUT BSS_TABLE *Tab,
- IN PUCHAR pBssid,
- IN UCHAR Channel)
-{
- UCHAR i, j;
-
- for (i = 0; i < Tab->BssNr; i++)
- {
- if ((Tab->BssEntry[i].Channel == Channel) &&
- (MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid)))
- {
- for (j = i; j < Tab->BssNr - 1; j++)
- {
- NdisMoveMemory(&(Tab->BssEntry[j]), &(Tab->BssEntry[j + 1]), sizeof(BSS_ENTRY));
- }
- NdisZeroMemory(&(Tab->BssEntry[Tab->BssNr - 1]), sizeof(BSS_ENTRY));
- Tab->BssNr -= 1;
- return;
- }
- }
-}
-
-/*
- ========================================================================
- Routine Description:
- Delete the Originator Entry in BAtable. Or decrease numAs Originator by 1 if needed.
-
- Arguments:
- // IRQL = DISPATCH_LEVEL
- ========================================================================
-*/
-VOID BATableDeleteORIEntry(
- IN OUT PRTMP_ADAPTER pAd,
- IN BA_ORI_ENTRY *pBAORIEntry)
-{
-
- if (pBAORIEntry->ORI_BA_Status != Originator_NONE)
- {
- NdisAcquireSpinLock(&pAd->BATabLock);
- if (pBAORIEntry->ORI_BA_Status == Originator_Done)
- {
- pAd->BATable.numAsOriginator -= 1;
- DBGPRINT(RT_DEBUG_TRACE, ("BATableDeleteORIEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient));
- // Erase Bitmap flag.
- }
- pAd->MacTab.Content[pBAORIEntry->Wcid].TXBAbitmap &= (~(1<<(pBAORIEntry->TID) )); // If STA mode, erase flag here
- pAd->MacTab.Content[pBAORIEntry->Wcid].BAOriWcidArray[pBAORIEntry->TID] = 0; // If STA mode, erase flag here
- pBAORIEntry->ORI_BA_Status = Originator_NONE;
- pBAORIEntry->Token = 1;
- // Not clear Sequence here.
- NdisReleaseSpinLock(&pAd->BATabLock);
- }
-}
-
-/*! \brief
- * \param
- * \return
- * \pre
- * \post
-
- IRQL = DISPATCH_LEVEL
-
- */
-VOID BssEntrySet(
- IN PRTMP_ADAPTER pAd,
- OUT BSS_ENTRY *pBss,
- IN PUCHAR pBssid,
- IN CHAR Ssid[],
- IN UCHAR SsidLen,
- IN UCHAR BssType,
- IN USHORT BeaconPeriod,
- IN PCF_PARM pCfParm,
- IN USHORT AtimWin,
- IN USHORT CapabilityInfo,
- IN UCHAR SupRate[],
- IN UCHAR SupRateLen,
- IN UCHAR ExtRate[],
- IN UCHAR ExtRateLen,
- IN HT_CAPABILITY_IE *pHtCapability,
- IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
- IN UCHAR HtCapabilityLen,
- IN UCHAR AddHtInfoLen,
- IN UCHAR NewExtChanOffset,
- IN UCHAR Channel,
- IN CHAR Rssi,
- IN LARGE_INTEGER TimeStamp,
- IN UCHAR CkipFlag,
- IN PEDCA_PARM pEdcaParm,
- IN PQOS_CAPABILITY_PARM pQosCapability,
- IN PQBSS_LOAD_PARM pQbssLoad,
- IN USHORT LengthVIE,
- IN PNDIS_802_11_VARIABLE_IEs pVIE)
-{
- COPY_MAC_ADDR(pBss->Bssid, pBssid);
- // Default Hidden SSID to be TRUE, it will be turned to FALSE after coping SSID
- pBss->Hidden = 1;
- if (SsidLen > 0)
- {
- // For hidden SSID AP, it might send beacon with SSID len equal to 0
- // Or send beacon /probe response with SSID len matching real SSID length,
- // but SSID is all zero. such as "00-00-00-00" with length 4.
- // We have to prevent this case overwrite correct table
- if (NdisEqualMemory(Ssid, ZeroSsid, SsidLen) == 0)
- {
- NdisZeroMemory(pBss->Ssid, MAX_LEN_OF_SSID);
- NdisMoveMemory(pBss->Ssid, Ssid, SsidLen);
- pBss->SsidLen = SsidLen;
- pBss->Hidden = 0;
- }
- }
- else
- pBss->SsidLen = 0;
- pBss->BssType = BssType;
- pBss->BeaconPeriod = BeaconPeriod;
- if (BssType == BSS_INFRA)
- {
- if (pCfParm->bValid)
- {
- pBss->CfpCount = pCfParm->CfpCount;
- pBss->CfpPeriod = pCfParm->CfpPeriod;
- pBss->CfpMaxDuration = pCfParm->CfpMaxDuration;
- pBss->CfpDurRemaining = pCfParm->CfpDurRemaining;
- }
- }
- else
- {
- pBss->AtimWin = AtimWin;
- }
-
- pBss->CapabilityInfo = CapabilityInfo;
- // The privacy bit indicate security is ON, it maight be WEP, TKIP or AES
- // Combine with AuthMode, they will decide the connection methods.
- pBss->Privacy = CAP_IS_PRIVACY_ON(pBss->CapabilityInfo);
- ASSERT(SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
- if (SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES)
- NdisMoveMemory(pBss->SupRate, SupRate, SupRateLen);
- else
- NdisMoveMemory(pBss->SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES);
- pBss->SupRateLen = SupRateLen;
- ASSERT(ExtRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
- NdisMoveMemory(pBss->ExtRate, ExtRate, ExtRateLen);
- NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen);
- NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
- pBss->NewExtChanOffset = NewExtChanOffset;
- pBss->ExtRateLen = ExtRateLen;
- pBss->Channel = Channel;
- pBss->CentralChannel = Channel;
- pBss->Rssi = Rssi;
- // Update CkipFlag. if not exists, the value is 0x0
- pBss->CkipFlag = CkipFlag;
-
- // New for microsoft Fixed IEs
- NdisMoveMemory(pBss->FixIEs.Timestamp, &TimeStamp, 8);
- pBss->FixIEs.BeaconInterval = BeaconPeriod;
- pBss->FixIEs.Capabilities = CapabilityInfo;
-
- // New for microsoft Variable IEs
- if (LengthVIE != 0)
- {
- pBss->VarIELen = LengthVIE;
- NdisMoveMemory(pBss->VarIEs, pVIE, pBss->VarIELen);
- }
- else
- {
- pBss->VarIELen = 0;
- }
-
- pBss->AddHtInfoLen = 0;
- pBss->HtCapabilityLen = 0;
-
- if (HtCapabilityLen> 0)
- {
- pBss->HtCapabilityLen = HtCapabilityLen;
- NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen);
- if (AddHtInfoLen > 0)
- {
- pBss->AddHtInfoLen = AddHtInfoLen;
- NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
-
- if ((pAddHtInfo->ControlChan > 2)&& (pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
- {
- pBss->CentralChannel = pAddHtInfo->ControlChan - 2;
- }
- else if ((pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
- {
- pBss->CentralChannel = pAddHtInfo->ControlChan + 2;
- }
+ /*if (MCS15)*/
+ if ((pTable == RateSwitchTable11BGN3S) ||
+ (pTable == RateSwitchTable11N3S) ||
+ (pTable == RateSwitchTable))
+ {// N mode with 3 stream // 3*3
+ if (MCS23 && (Rssi >= -70))
+ TxRateIdx = MCS23;
+ else if (MCS22 && (Rssi >= -72))
+ TxRateIdx = MCS22;
+ else if (MCS21 && (Rssi >= -76))
+ TxRateIdx = MCS21;
+ else if (MCS20 && (Rssi >= -78))
+ TxRateIdx = MCS20;
+ else if (MCS4 && (Rssi >= -82))
+ TxRateIdx = MCS4;
+ else if (MCS3 && (Rssi >= -84))
+ TxRateIdx = MCS3;
+ else if (MCS2 && (Rssi >= -86))
+ TxRateIdx = MCS2;
+ else if (MCS1 && (Rssi >= -88))
+ TxRateIdx = MCS1;
+ else
+ TxRateIdx = MCS0;
}
- }
-
- BssCipherParse(pBss);
-
- // new for QOS
- if (pEdcaParm)
- NdisMoveMemory(&pBss->EdcaParm, pEdcaParm, sizeof(EDCA_PARM));
- else
- pBss->EdcaParm.bValid = FALSE;
- if (pQosCapability)
- NdisMoveMemory(&pBss->QosCapability, pQosCapability, sizeof(QOS_CAPABILITY_PARM));
- else
- pBss->QosCapability.bValid = FALSE;
- if (pQbssLoad)
- NdisMoveMemory(&pBss->QbssLoad, pQbssLoad, sizeof(QBSS_LOAD_PARM));
- else
- pBss->QbssLoad.bValid = FALSE;
-
- {
- PEID_STRUCT pEid;
- USHORT Length = 0;
-
-
- NdisZeroMemory(&pBss->WpaIE.IE[0], MAX_CUSTOM_LEN);
- NdisZeroMemory(&pBss->RsnIE.IE[0], MAX_CUSTOM_LEN);
-
- pEid = (PEID_STRUCT) pVIE;
-
- while ((Length + 2 + (USHORT)pEid->Len) <= LengthVIE)
- {
- switch(pEid->Eid)
- {
- case IE_WPA:
- if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
- {
- if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
- {
- pBss->WpaIE.IELen = 0;
- break;
- }
- pBss->WpaIE.IELen = pEid->Len + 2;
- NdisMoveMemory(pBss->WpaIE.IE, pEid, pBss->WpaIE.IELen);
- }
- break;
- case IE_RSN:
- if (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
- {
- if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
- {
- pBss->RsnIE.IELen = 0;
- break;
- }
- pBss->RsnIE.IELen = pEid->Len + 2;
- NdisMoveMemory(pBss->RsnIE.IE, pEid, pBss->RsnIE.IELen);
+// else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand) || (pTable == RateSwitchTable))
+ else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand)) // 3*3
+ {// N mode with 2 stream
+ if (MCS15 && (Rssi >= (-70+RssiOffset)))
+ TxRateIdx = MCS15;
+ else if (MCS14 && (Rssi >= (-72+RssiOffset)))
+ TxRateIdx = MCS14;
+ else if (MCS13 && (Rssi >= (-76+RssiOffset)))
+ TxRateIdx = MCS13;
+ else if (MCS12 && (Rssi >= (-78+RssiOffset)))
+ TxRateIdx = MCS12;
+ else if (MCS4 && (Rssi >= (-82+RssiOffset)))
+ TxRateIdx = MCS4;
+ else if (MCS3 && (Rssi >= (-84+RssiOffset)))
+ TxRateIdx = MCS3;
+ else if (MCS2 && (Rssi >= (-86+RssiOffset)))
+ TxRateIdx = MCS2;
+ else if (MCS1 && (Rssi >= (-88+RssiOffset)))
+ TxRateIdx = MCS1;
+ else
+ TxRateIdx = MCS0;
}
- break;
- }
- Length = Length + 2 + (USHORT)pEid->Len; // Eid[1] + Len[1]+ content[Len]
- pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
- }
- }
-}
-
-/*!
- * \brief insert an entry into the bss table
- * \param p_tab The BSS table
- * \param Bssid BSSID
- * \param ssid SSID
- * \param ssid_len Length of SSID
- * \param bss_type
- * \param beacon_period
- * \param timestamp
- * \param p_cf
- * \param atim_win
- * \param cap
- * \param rates
- * \param rates_len
- * \param channel_idx
- * \return none
- * \pre
- * \post
- * \note If SSID is identical, the old entry will be replaced by the new one
-
- IRQL = DISPATCH_LEVEL
-
- */
-ULONG BssTableSetEntry(
- IN PRTMP_ADAPTER pAd,
- OUT BSS_TABLE *Tab,
- IN PUCHAR pBssid,
- IN CHAR Ssid[],
- IN UCHAR SsidLen,
- IN UCHAR BssType,
- IN USHORT BeaconPeriod,
- IN CF_PARM *CfParm,
- IN USHORT AtimWin,
- IN USHORT CapabilityInfo,
- IN UCHAR SupRate[],
- IN UCHAR SupRateLen,
- IN UCHAR ExtRate[],
- IN UCHAR ExtRateLen,
- IN HT_CAPABILITY_IE *pHtCapability,
- IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
- IN UCHAR HtCapabilityLen,
- IN UCHAR AddHtInfoLen,
- IN UCHAR NewExtChanOffset,
- IN UCHAR ChannelNo,
- IN CHAR Rssi,
- IN LARGE_INTEGER TimeStamp,
- IN UCHAR CkipFlag,
- IN PEDCA_PARM pEdcaParm,
- IN PQOS_CAPABILITY_PARM pQosCapability,
- IN PQBSS_LOAD_PARM pQbssLoad,
- IN USHORT LengthVIE,
- IN PNDIS_802_11_VARIABLE_IEs pVIE)
-{
- ULONG Idx;
-
- Idx = BssTableSearchWithSSID(Tab, pBssid, Ssid, SsidLen, ChannelNo);
- if (Idx == BSS_NOT_FOUND)
- {
- if (Tab->BssNr >= MAX_LEN_OF_BSS_TABLE)
- {
- //
- // It may happen when BSS Table was full.
- // The desired AP will not be added into BSS Table
- // In this case, if we found the desired AP then overwrite BSS Table.
- //
- if(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
- {
- if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, pBssid) ||
- SSID_EQUAL(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Ssid, SsidLen))
- {
- Idx = Tab->BssOverlapNr;
- BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
- CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
- NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
- Tab->BssOverlapNr = (Tab->BssOverlapNr++) % MAX_LEN_OF_BSS_TABLE;
- }
- return Idx;
+ else if ((pTable == RateSwitchTable11BGN1S) || (pTable == RateSwitchTable11N1S))
+ {// N mode with 1 stream
+ if (MCS7 && (Rssi > (-72+RssiOffset)))
+ TxRateIdx = MCS7;
+ else if (MCS6 && (Rssi > (-74+RssiOffset)))
+ TxRateIdx = MCS6;
+ else if (MCS5 && (Rssi > (-77+RssiOffset)))
+ TxRateIdx = MCS5;
+ else if (MCS4 && (Rssi > (-79+RssiOffset)))
+ TxRateIdx = MCS4;
+ else if (MCS3 && (Rssi > (-81+RssiOffset)))
+ TxRateIdx = MCS3;
+ else if (MCS2 && (Rssi > (-83+RssiOffset)))
+ TxRateIdx = MCS2;
+ else if (MCS1 && (Rssi > (-86+RssiOffset)))
+ TxRateIdx = MCS1;
+ else
+ TxRateIdx = MCS0;
}
else
- {
- return BSS_NOT_FOUND;
- }
- }
- Idx = Tab->BssNr;
- BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
- CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
- NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
- Tab->BssNr++;
- }
- else
- {
- /* avoid Hidden SSID form beacon to overwirite correct SSID from probe response */
- if ((SSID_EQUAL(Ssid, SsidLen, Tab->BssEntry[Idx].Ssid, Tab->BssEntry[Idx].SsidLen)) ||
- (NdisEqualMemory(Tab->BssEntry[Idx].Ssid, ZeroSsid, Tab->BssEntry[Idx].SsidLen)))
- {
- BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod,CfParm, AtimWin,
- CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
- NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
- }
- }
+ {// Legacy mode
+ if (MCS7 && (Rssi > -70))
+ TxRateIdx = MCS7;
+ else if (MCS6 && (Rssi > -74))
+ TxRateIdx = MCS6;
+ else if (MCS5 && (Rssi > -78))
+ TxRateIdx = MCS5;
+ else if (MCS4 && (Rssi > -82))
+ TxRateIdx = MCS4;
+ else if (MCS4 == 0) // for B-only mode
+ TxRateIdx = MCS3;
+ else if (MCS3 && (Rssi > -85))
+ TxRateIdx = MCS3;
+ else if (MCS2 && (Rssi > -87))
+ TxRateIdx = MCS2;
+ else if (MCS1 && (Rssi > -90))
+ TxRateIdx = MCS1;
+ else
+ TxRateIdx = MCS0;
+ }
- return Idx;
-}
+ // if (TxRateIdx != pAd->CommonCfg.TxRateIndex)
+ {
+ pEntry->CurrTxRateIndex = TxRateIdx;
+ pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
+ MlmeSetTxRate(pAd, pEntry, pNextTxRate);
+ }
-// IRQL = DISPATCH_LEVEL
-VOID BssTableSsidSort(
- IN PRTMP_ADAPTER pAd,
- OUT BSS_TABLE *OutTab,
- IN CHAR Ssid[],
- IN UCHAR SsidLen)
-{
- INT i;
- BssTableInit(OutTab);
+ NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
+ NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
+ pEntry->fLastSecAccordingRSSI = TRUE;
+ // reset all OneSecTx counters
+ RESET_ONE_SEC_TX_CNT(pEntry);
- for (i = 0; i < pAd->ScanTab.BssNr; i++)
- {
- BSS_ENTRY *pInBss = &pAd->ScanTab.BssEntry[i];
- BOOLEAN bIsHiddenApIncluded = FALSE;
+ continue;
+ }
- if (((pAd->CommonCfg.bIEEE80211H == 1) &&
- (pAd->MlmeAux.Channel > 14) &&
- RadarChannelCheck(pAd, pInBss->Channel))
- )
+ if (pEntry->fLastSecAccordingRSSI == TRUE)
{
- if (pInBss->Hidden)
- bIsHiddenApIncluded = TRUE;
+ pEntry->fLastSecAccordingRSSI = FALSE;
+ pEntry->LastSecTxRateChangeAction = 0;
+ // reset all OneSecTx counters
+ RESET_ONE_SEC_TX_CNT(pEntry);
+
+ continue;
}
- if ((pInBss->BssType == pAd->StaCfg.BssType) &&
- (SSID_EQUAL(Ssid, SsidLen, pInBss->Ssid, pInBss->SsidLen) || bIsHiddenApIncluded))
+ do
{
- BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
+ BOOLEAN bTrainUpDown = FALSE;
- // 2.4G/5G N only mode
- if ((pInBss->HtCapabilityLen == 0) &&
- ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
- {
- DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
- continue;
- }
+ pEntry->CurrTxRateStableTime ++;
- // New for WPA2
- // Check the Authmode first
- if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ // downgrade TX quality if PER >= Rate-Down threshold
+ if (TxErrorRatio >= TrainDown)
{
- // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
- if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
- // None matched
- continue;
-
- // Check cipher suite, AP must have more secured cipher than station setting
- if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
- {
- // If it's not mixed mode, we should only let BSS pass with the same encryption
- if (pInBss->WPA.bMixMode == FALSE)
- if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
- continue;
-
- // check group cipher
- if (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP40Enabled &&
- pInBss->WPA.GroupCipher != Ndis802_11GroupWEP104Enabled &&
- pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
- continue;
-
- // check pairwise cipher, skip if none matched
- // If profile set to AES, let it pass without question.
- // If profile set to TKIP, we must find one mateched
- if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
- (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
- (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
- continue;
- }
- else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
- {
- // If it's not mixed mode, we should only let BSS pass with the same encryption
- if (pInBss->WPA2.bMixMode == FALSE)
- if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
- continue;
-
- // check group cipher
- if (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP40Enabled &&
- pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP104Enabled &&
- pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
- continue;
-
- // check pairwise cipher, skip if none matched
- // If profile set to AES, let it pass without question.
- // If profile set to TKIP, we must find one mateched
- if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
- (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
- (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
- continue;
- }
+ bTrainUpDown = TRUE;
+ pEntry->TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
}
- // Bss Type matched, SSID matched.
- // We will check wepstatus for qualification Bss
- else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
+ // upgrade TX quality if PER <= Rate-Up threshold
+ else if (TxErrorRatio <= TrainUp)
{
- DBGPRINT(RT_DEBUG_TRACE,("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n", pAd->StaCfg.WepStatus, pInBss->WepStatus));
- //
- // For the SESv2 case, we will not qualify WepStatus.
- //
- if (!pInBss->bSES)
- continue;
+ bTrainUpDown = TRUE;
+ bUpgradeQuality = TRUE;
+ if (pEntry->TxQuality[CurrRateIdx])
+ pEntry->TxQuality[CurrRateIdx] --; // quality very good in CurrRate
+
+ if (pEntry->TxRateUpPenalty)
+ pEntry->TxRateUpPenalty --;
+ else if (pEntry->TxQuality[UpRateIdx])
+ pEntry->TxQuality[UpRateIdx] --; // may improve next UP rate's quality
}
- // Since the AP is using hidden SSID, and we are trying to connect to ANY
- // It definitely will fail. So, skip it.
- // CCX also require not even try to connect it!!
- if (SsidLen == 0)
- continue;
+ pEntry->PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
- // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
- // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
- if ((pInBss->CentralChannel != pInBss->Channel) &&
- (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
+ if (bTrainUpDown)
{
- if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
+ // perform DRS - consider TxRate Down first, then rate up.
+ if ((CurrRateIdx != DownRateIdx) && (pEntry->TxQuality[CurrRateIdx] >= DRS_TX_QUALITY_WORST_BOUND))
{
- pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
- SetCommonHT(pAd);
- pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
+ pEntry->CurrTxRateIndex = DownRateIdx;
}
- else
+ else if ((CurrRateIdx != UpRateIdx) && (pEntry->TxQuality[UpRateIdx] <= 0))
{
- if (pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BAND_WIDTH_20)
- {
- SetCommonHT(pAd);
- }
+ pEntry->CurrTxRateIndex = UpRateIdx;
}
}
+ } while (FALSE);
- // copy matching BSS from InTab to OutTab
- NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
-
- OutTab->BssNr++;
- }
- else if ((pInBss->BssType == pAd->StaCfg.BssType) && (SsidLen == 0))
+ // if rate-up happen, clear all bad history of all TX rates
+ if (pEntry->CurrTxRateIndex > CurrRateIdx)
{
- BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
-
- // 2.4G/5G N only mode
- if ((pInBss->HtCapabilityLen == 0) &&
- ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
- {
- DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
- continue;
- }
+ pEntry->CurrTxRateStableTime = 0;
+ pEntry->TxRateUpPenalty = 0;
+ pEntry->LastSecTxRateChangeAction = 1; // rate UP
+ NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
+ NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
- // New for WPA2
- // Check the Authmode first
- if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ //
+ // For TxRate fast train up
+ //
+ if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
{
- // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
- if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
- // None matched
- continue;
-
- // Check cipher suite, AP must have more secured cipher than station setting
- if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
- {
- // If it's not mixed mode, we should only let BSS pass with the same encryption
- if (pInBss->WPA.bMixMode == FALSE)
- if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
- continue;
-
- // check group cipher
- if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
- continue;
-
- // check pairwise cipher, skip if none matched
- // If profile set to AES, let it pass without question.
- // If profile set to TKIP, we must find one mateched
- if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
- (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
- (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
- continue;
- }
- else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
- {
- // If it's not mixed mode, we should only let BSS pass with the same encryption
- if (pInBss->WPA2.bMixMode == FALSE)
- if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
- continue;
-
- // check group cipher
- if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
- continue;
-
- // check pairwise cipher, skip if none matched
- // If profile set to AES, let it pass without question.
- // If profile set to TKIP, we must find one mateched
- if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
- (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
- (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
- continue;
- }
- }
- // Bss Type matched, SSID matched.
- // We will check wepstatus for qualification Bss
- else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
- continue;
+ RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
- // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
- // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
- if ((pInBss->CentralChannel != pInBss->Channel) &&
- (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
- {
- if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
- {
- pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
- SetCommonHT(pAd);
- pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
- }
+ pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
}
+ bTxRateChanged = TRUE;
+ }
+ // if rate-down happen, only clear DownRate's bad history
+ else if (pEntry->CurrTxRateIndex < CurrRateIdx)
+ {
+ pEntry->CurrTxRateStableTime = 0;
+ pEntry->TxRateUpPenalty = 0; // no penalty
+ pEntry->LastSecTxRateChangeAction = 2; // rate DOWN
+ pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0;
+ pEntry->PER[pEntry->CurrTxRateIndex] = 0;
- // copy matching BSS from InTab to OutTab
- NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
+ //
+ // For TxRate fast train down
+ //
+ if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
+ {
+ RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
- OutTab->BssNr++;
+ pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
+ }
+ bTxRateChanged = TRUE;
+ }
+ else
+ {
+ pEntry->LastSecTxRateChangeAction = 0; // rate no change
+ bTxRateChanged = FALSE;
}
- if (OutTab->BssNr >= MAX_LEN_OF_BSS_TABLE)
- break;
- }
-
- BssTableSortByRssi(OutTab);
-}
-
-
-// IRQL = DISPATCH_LEVEL
-VOID BssTableSortByRssi(
- IN OUT BSS_TABLE *OutTab)
-{
- INT i, j;
- BSS_ENTRY TmpBss;
-
- for (i = 0; i < OutTab->BssNr - 1; i++)
- {
- for (j = i+1; j < OutTab->BssNr; j++)
+ pEntry->LastTxOkCount = TxSuccess;
+#ifdef RT2860
+ pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
+#endif // RT2860 //
+#if defined(RT2870) || defined(RT3070)
{
- if (OutTab->BssEntry[j].Rssi > OutTab->BssEntry[i].Rssi)
+ UCHAR tmpTxRate;
+
+ // to fix tcp ack issue
+ if (!bTxRateChanged && (pAd->RalinkCounters.OneSecReceivedByteCount > (pAd->RalinkCounters.OneSecTransmittedByteCount * 5)))
{
- NdisMoveMemory(&TmpBss, &OutTab->BssEntry[j], sizeof(BSS_ENTRY));
- NdisMoveMemory(&OutTab->BssEntry[j], &OutTab->BssEntry[i], sizeof(BSS_ENTRY));
- NdisMoveMemory(&OutTab->BssEntry[i], &TmpBss, sizeof(BSS_ENTRY));
+ tmpTxRate = DownRateIdx;
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("DRS: Rx(%d) is 5 times larger than Tx(%d), use low rate (curr=%d, tmp=%d)\n",
+ pAd->RalinkCounters.OneSecReceivedByteCount, pAd->RalinkCounters.OneSecTransmittedByteCount, pEntry->CurrTxRateIndex, tmpTxRate));
+ }
+ else
+ {
+ tmpTxRate = pEntry->CurrTxRateIndex;
}
+
+ pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(tmpTxRate+1)*5];
+ }
+#endif // RT2870 //
+ if (bTxRateChanged && pNextTxRate)
+ {
+ MlmeSetTxRate(pAd, pEntry, pNextTxRate);
}
+ // reset all OneSecTx counters
+ RESET_ONE_SEC_TX_CNT(pEntry);
}
}
-VOID BssCipherParse(
- IN OUT PBSS_ENTRY pBss)
+/*
+ ========================================================================
+ Routine Description:
+ Station side, Auto TxRate faster train up timer call back function.
+
+ Arguments:
+ SystemSpecific1 - Not used.
+ FunctionContext - Pointer to our Adapter context.
+ SystemSpecific2 - Not used.
+ SystemSpecific3 - Not used.
+
+ Return Value:
+ None
+
+ ========================================================================
+*/
+VOID StaQuickResponeForRateUpExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
{
- PEID_STRUCT pEid;
- PUCHAR pTmp;
- PRSN_IE_HEADER_STRUCT pRsnHeader;
- PCIPHER_SUITE_STRUCT pCipher;
- PAKM_SUITE_STRUCT pAKM;
- USHORT Count;
- INT Length;
- NDIS_802_11_ENCRYPTION_STATUS TmpCipher;
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext;
+ UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0;
+ ULONG TxTotalCnt;
+ ULONG TxErrorRatio = 0;
+ BOOLEAN bTxRateChanged; //, bUpgradeQuality = FALSE;
+ PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL;
+ PUCHAR pTable;
+ UCHAR TableSize = 0;
+ UCHAR InitTxRateIdx = 0, TrainUp, TrainDown;
+ TX_STA_CNT1_STRUC StaTx1;
+ TX_STA_CNT0_STRUC TxStaCnt0;
+ CHAR Rssi, ratio;
+ ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
+ MAC_TABLE_ENTRY *pEntry;
+ ULONG i;
- //
- // WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame.
- //
- if (pBss->Privacy)
- {
- pBss->WepStatus = Ndis802_11WEPEnabled;
- }
- else
+ pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
+
+ //
+ // walk through MAC table, see if need to change AP's TX rate toward each entry
+ //
+ for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
{
- pBss->WepStatus = Ndis802_11WEPDisabled;
- }
- // Set default to disable & open authentication before parsing variable IE
- pBss->AuthMode = Ndis802_11AuthModeOpen;
- pBss->AuthModeAux = Ndis802_11AuthModeOpen;
+ pEntry = &pAd->MacTab.Content[i];
- // Init WPA setting
- pBss->WPA.PairCipher = Ndis802_11WEPDisabled;
- pBss->WPA.PairCipherAux = Ndis802_11WEPDisabled;
- pBss->WPA.GroupCipher = Ndis802_11WEPDisabled;
- pBss->WPA.RsnCapability = 0;
- pBss->WPA.bMixMode = FALSE;
+ // check if this entry need to switch rate automatically
+ if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
+ continue;
- // Init WPA2 setting
- pBss->WPA2.PairCipher = Ndis802_11WEPDisabled;
- pBss->WPA2.PairCipherAux = Ndis802_11WEPDisabled;
- pBss->WPA2.GroupCipher = Ndis802_11WEPDisabled;
- pBss->WPA2.RsnCapability = 0;
- pBss->WPA2.bMixMode = FALSE;
+ if (INFRA_ON(pAd) && (i == 1))
+ Rssi = RTMPMaxRssi(pAd,
+ pAd->StaCfg.RssiSample.AvgRssi0,
+ pAd->StaCfg.RssiSample.AvgRssi1,
+ pAd->StaCfg.RssiSample.AvgRssi2);
+ else
+ Rssi = RTMPMaxRssi(pAd,
+ pEntry->RssiSample.AvgRssi0,
+ pEntry->RssiSample.AvgRssi1,
+ pEntry->RssiSample.AvgRssi2);
+ CurrRateIdx = pAd->CommonCfg.TxRateIndex;
- Length = (INT) pBss->VarIELen;
+ MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
- while (Length > 0)
- {
- // Parse cipher suite base on WPA1 & WPA2, they should be parsed differently
- pTmp = ((PUCHAR) pBss->VarIEs) + pBss->VarIELen - Length;
- pEid = (PEID_STRUCT) pTmp;
- switch (pEid->Eid)
+ // decide the next upgrade rate and downgrade rate, if any
+ if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
{
- case IE_WPA:
- //Parse Cisco IE_WPA (LEAP, CCKM, etc.)
- if ( NdisEqualMemory((pTmp+8), CISCO_OUI, 3))
- {
- pTmp += 11;
- switch (*pTmp)
- {
- case 1:
- case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
- pBss->WepStatus = Ndis802_11Encryption1Enabled;
- pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
- pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
- break;
- case 2:
- pBss->WepStatus = Ndis802_11Encryption2Enabled;
- pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
- pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
- break;
- case 4:
- pBss->WepStatus = Ndis802_11Encryption3Enabled;
- pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
- pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
- break;
- default:
- break;
- }
+ UpRateIdx = CurrRateIdx + 1;
+ DownRateIdx = CurrRateIdx -1;
+ }
+ else if (CurrRateIdx == 0)
+ {
+ UpRateIdx = CurrRateIdx + 1;
+ DownRateIdx = CurrRateIdx;
+ }
+ else if (CurrRateIdx == (TableSize - 1))
+ {
+ UpRateIdx = CurrRateIdx;
+ DownRateIdx = CurrRateIdx - 1;
+ }
- // if Cisco IE_WPA, break
- break;
- }
- else if (NdisEqualMemory(pEid->Octet, SES_OUI, 3) && (pEid->Len == 7))
- {
- pBss->bSES = TRUE;
- break;
- }
- else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4) != 1)
- {
- // if unsupported vendor specific IE
- break;
- }
- // Skip OUI, version, and multicast suite
- // This part should be improved in the future when AP supported multiple cipher suite.
- // For now, it's OK since almost all APs have fixed cipher suite supported.
- // pTmp = (PUCHAR) pEid->Octet;
- pTmp += 11;
+ pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
- // Cipher Suite Selectors from Spec P802.11i/D3.2 P26.
- // Value Meaning
- // 0 None
- // 1 WEP-40
- // 2 Tkip
- // 3 WRAP
- // 4 AES
- // 5 WEP-104
- // Parse group cipher
- switch (*pTmp)
- {
- case 1:
- pBss->WPA.GroupCipher = Ndis802_11GroupWEP40Enabled;
- break;
- case 5:
- pBss->WPA.GroupCipher = Ndis802_11GroupWEP104Enabled;
- break;
- case 2:
- pBss->WPA.GroupCipher = Ndis802_11Encryption2Enabled;
- break;
- case 4:
- pBss->WPA.GroupCipher = Ndis802_11Encryption3Enabled;
- break;
- default:
- break;
- }
- // number of unicast suite
- pTmp += 1;
+ if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
+ {
+ TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
+ TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
+ }
+ else
+ {
+ TrainUp = pCurrTxRate->TrainUp;
+ TrainDown = pCurrTxRate->TrainDown;
+ }
+
+ if (pAd->MacTab.Size == 1)
+ {
+ // Update statistic counter
+ RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
+ RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
+
+ TxRetransmit = StaTx1.field.TxRetransmit;
+ TxSuccess = StaTx1.field.TxSuccess;
+ TxFailCount = TxStaCnt0.field.TxFailCount;
+ TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
+
+ pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
+ pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
+ pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
+ pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
+ pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
+ pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
+
+ if (TxTotalCnt)
+ TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
+ }
+ else
+ {
+ TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
+ pEntry->OneSecTxRetryOkCount +
+ pEntry->OneSecTxFailCount;
- // skip all unicast cipher suites
- //Count = *(PUSHORT) pTmp;
- Count = (pTmp[1]<<8) + pTmp[0];
- pTmp += sizeof(USHORT);
+ if (TxTotalCnt)
+ TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
+ }
- // Parsing all unicast cipher suite
- while (Count > 0)
- {
- // Skip OUI
- pTmp += 3;
- TmpCipher = Ndis802_11WEPDisabled;
- switch (*pTmp)
- {
- case 1:
- case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
- TmpCipher = Ndis802_11Encryption1Enabled;
- break;
- case 2:
- TmpCipher = Ndis802_11Encryption2Enabled;
- break;
- case 4:
- TmpCipher = Ndis802_11Encryption3Enabled;
- break;
- default:
- break;
- }
- if (TmpCipher > pBss->WPA.PairCipher)
- {
- // Move the lower cipher suite to PairCipherAux
- pBss->WPA.PairCipherAux = pBss->WPA.PairCipher;
- pBss->WPA.PairCipher = TmpCipher;
- }
- else
- {
- pBss->WPA.PairCipherAux = TmpCipher;
- }
- pTmp++;
- Count--;
- }
- // 4. get AKM suite counts
- //Count = *(PUSHORT) pTmp;
- Count = (pTmp[1]<<8) + pTmp[0];
- pTmp += sizeof(USHORT);
- pTmp += 3;
+ //
+ // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
+ // (criteria copied from RT2500 for Netopia case)
+ //
+ if (TxTotalCnt <= 12)
+ {
+ NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
+ NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
- switch (*pTmp)
- {
- case 1:
- // Set AP support WPA mode
- if (pBss->AuthMode == Ndis802_11AuthModeOpen)
- pBss->AuthMode = Ndis802_11AuthModeWPA;
- else
- pBss->AuthModeAux = Ndis802_11AuthModeWPA;
- break;
- case 2:
- // Set AP support WPA mode
- if (pBss->AuthMode == Ndis802_11AuthModeOpen)
- pBss->AuthMode = Ndis802_11AuthModeWPAPSK;
- else
- pBss->AuthModeAux = Ndis802_11AuthModeWPAPSK;
- break;
- default:
- break;
- }
- pTmp += 1;
+ if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
+ {
+ pAd->CommonCfg.TxRateIndex = DownRateIdx;
+ pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
+ }
+ else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
+ {
+ pAd->CommonCfg.TxRateIndex = UpRateIdx;
+ }
- // Fixed for WPA-None
- if (pBss->BssType == BSS_ADHOC)
- {
- pBss->AuthMode = Ndis802_11AuthModeWPANone;
- pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
- pBss->WepStatus = pBss->WPA.GroupCipher;
- if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
- pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
- }
- else
- pBss->WepStatus = pBss->WPA.PairCipher;
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: TxTotalCnt <= 15, train back to original rate \n"));
+ return;
+ }
- // Check the Pair & Group, if different, turn on mixed mode flag
- if (pBss->WPA.GroupCipher != pBss->WPA.PairCipher)
- pBss->WPA.bMixMode = TRUE;
+ do
+ {
+ ULONG OneSecTxNoRetryOKRationCount;
- break;
+ if (pAd->DrsCounters.LastTimeTxRateChangeAction == 0)
+ ratio = 5;
+ else
+ ratio = 4;
- case IE_RSN:
- pRsnHeader = (PRSN_IE_HEADER_STRUCT) pTmp;
+ // downgrade TX quality if PER >= Rate-Down threshold
+ if (TxErrorRatio >= TrainDown)
+ {
+ pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
+ }
- // 0. Version must be 1
- if (le2cpu16(pRsnHeader->Version) != 1)
- break;
- pTmp += sizeof(RSN_IE_HEADER_STRUCT);
+ pAd->DrsCounters.PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
- // 1. Check group cipher
- pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
- if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
- break;
+ OneSecTxNoRetryOKRationCount = (TxSuccess * ratio);
- // Parse group cipher
- switch (pCipher->Type)
+ // perform DRS - consider TxRate Down first, then rate up.
+ if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
+ {
+ if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
{
- case 1:
- pBss->WPA2.GroupCipher = Ndis802_11GroupWEP40Enabled;
- break;
- case 5:
- pBss->WPA2.GroupCipher = Ndis802_11GroupWEP104Enabled;
- break;
- case 2:
- pBss->WPA2.GroupCipher = Ndis802_11Encryption2Enabled;
- break;
- case 4:
- pBss->WPA2.GroupCipher = Ndis802_11Encryption3Enabled;
- break;
- default:
- break;
+ pAd->CommonCfg.TxRateIndex = DownRateIdx;
+ pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
+
}
- // set to correct offset for next parsing
- pTmp += sizeof(CIPHER_SUITE_STRUCT);
- // 2. Get pairwise cipher counts
- //Count = *(PUSHORT) pTmp;
- Count = (pTmp[1]<<8) + pTmp[0];
- pTmp += sizeof(USHORT);
+ }
+ else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
+ {
+ if ((TxErrorRatio >= 50) || (TxErrorRatio >= TrainDown))
+ {
- // 3. Get pairwise cipher
- // Parsing all unicast cipher suite
- while (Count > 0)
+ }
+ else if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
{
- // Skip OUI
- pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
- TmpCipher = Ndis802_11WEPDisabled;
- switch (pCipher->Type)
- {
- case 1:
- case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
- TmpCipher = Ndis802_11Encryption1Enabled;
- break;
- case 2:
- TmpCipher = Ndis802_11Encryption2Enabled;
- break;
- case 4:
- TmpCipher = Ndis802_11Encryption3Enabled;
- break;
- default:
- break;
- }
- if (TmpCipher > pBss->WPA2.PairCipher)
- {
- // Move the lower cipher suite to PairCipherAux
- pBss->WPA2.PairCipherAux = pBss->WPA2.PairCipher;
- pBss->WPA2.PairCipher = TmpCipher;
- }
- else
- {
- pBss->WPA2.PairCipherAux = TmpCipher;
- }
- pTmp += sizeof(CIPHER_SUITE_STRUCT);
- Count--;
+ pAd->CommonCfg.TxRateIndex = UpRateIdx;
}
+ }
+ }while (FALSE);
- // 4. get AKM suite counts
- //Count = *(PUSHORT) pTmp;
- Count = (pTmp[1]<<8) + pTmp[0];
- pTmp += sizeof(USHORT);
+ // if rate-up happen, clear all bad history of all TX rates
+ if (pAd->CommonCfg.TxRateIndex > CurrRateIdx)
+ {
+ pAd->DrsCounters.TxRateUpPenalty = 0;
+ NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
+ NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
+ bTxRateChanged = TRUE;
+ }
+ // if rate-down happen, only clear DownRate's bad history
+ else if (pAd->CommonCfg.TxRateIndex < CurrRateIdx)
+ {
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: --TX rate from %d to %d \n", CurrRateIdx, pAd->CommonCfg.TxRateIndex));
- // 5. Get AKM ciphers
- pAKM = (PAKM_SUITE_STRUCT) pTmp;
- if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
- break;
+ pAd->DrsCounters.TxRateUpPenalty = 0; // no penalty
+ pAd->DrsCounters.TxQuality[pAd->CommonCfg.TxRateIndex] = 0;
+ pAd->DrsCounters.PER[pAd->CommonCfg.TxRateIndex] = 0;
+ bTxRateChanged = TRUE;
+ }
+ else
+ {
+ bTxRateChanged = FALSE;
+ }
- switch (pAKM->Type)
- {
- case 1:
- // Set AP support WPA mode
- if (pBss->AuthMode == Ndis802_11AuthModeOpen)
- pBss->AuthMode = Ndis802_11AuthModeWPA2;
- else
- pBss->AuthModeAux = Ndis802_11AuthModeWPA2;
- break;
- case 2:
- // Set AP support WPA mode
- if (pBss->AuthMode == Ndis802_11AuthModeOpen)
- pBss->AuthMode = Ndis802_11AuthModeWPA2PSK;
- else
- pBss->AuthModeAux = Ndis802_11AuthModeWPA2PSK;
- break;
- default:
- break;
- }
- pTmp += (Count * sizeof(AKM_SUITE_STRUCT));
+ pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pAd->CommonCfg.TxRateIndex+1)*5];
+ if (bTxRateChanged && pNextTxRate)
+ {
+ MlmeSetTxRate(pAd, pEntry, pNextTxRate);
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ This routine is executed periodically inside MlmePeriodicExec() after
+ association with an AP.
+ It checks if StaCfg.Psm is consistent with user policy (recorded in
+ StaCfg.WindowsPowerMode). If not, enforce user policy. However,
+ there're some conditions to consider:
+ 1. we don't support power-saving in ADHOC mode, so Psm=PWR_ACTIVE all
+ the time when Mibss==TRUE
+ 2. When link up in INFRA mode, Psm should not be switch to PWR_SAVE
+ if outgoing traffic available in TxRing or MgmtRing.
+ Output:
+ 1. change pAd->StaCfg.Psm to PWR_SAVE or leave it untouched
- // Fixed for WPA-None
- if (pBss->BssType == BSS_ADHOC)
- {
- pBss->AuthMode = Ndis802_11AuthModeWPANone;
- pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
- pBss->WPA.PairCipherAux = pBss->WPA2.PairCipherAux;
- pBss->WPA.GroupCipher = pBss->WPA2.GroupCipher;
- pBss->WepStatus = pBss->WPA.GroupCipher;
- if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
- pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
- }
- pBss->WepStatus = pBss->WPA2.PairCipher;
+ IRQL = DISPATCH_LEVEL
- // 6. Get RSN capability
- //pBss->WPA2.RsnCapability = *(PUSHORT) pTmp;
- pBss->WPA2.RsnCapability = (pTmp[1]<<8) + pTmp[0];
- pTmp += sizeof(USHORT);
+ ==========================================================================
+ */
+VOID MlmeCheckPsmChange(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Now32)
+{
+ ULONG PowerMode;
- // Check the Pair & Group, if different, turn on mixed mode flag
- if (pBss->WPA2.GroupCipher != pBss->WPA2.PairCipher)
- pBss->WPA2.bMixMode = TRUE;
+ // condition -
+ // 1. Psm maybe ON only happen in INFRASTRUCTURE mode
+ // 2. user wants either MAX_PSP or FAST_PSP
+ // 3. but current psm is not in PWR_SAVE
+ // 4. CNTL state machine is not doing SCANning
+ // 5. no TX SUCCESS event for the past 1-sec period
+ PowerMode = pAd->StaCfg.WindowsPowerMode;
- break;
- default:
- break;
+ if (INFRA_ON(pAd) &&
+ (PowerMode != Ndis802_11PowerModeCAM) &&
+ (pAd->StaCfg.Psm == PWR_ACTIVE) &&
+// (! RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+ (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)&&
+ RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP)
+ /*&&
+ (pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
+ (pAd->RalinkCounters.OneSecTxRetryOkCount == 0)*/)
+ {
+ NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime);
+ pAd->RalinkCounters.RxCountSinceLastNULL = 0;
+ RTMP_SET_PSM_BIT(pAd, PWR_SAVE);
+ if (!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
+ {
+ RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
+ }
+ else
+ {
+ RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
+ }
}
- Length -= (pEid->Len + 2);
- }
}
-// ===========================================================================================
-// mac_table.c
-// ===========================================================================================
+// IRQL = PASSIVE_LEVEL
+// IRQL = DISPATCH_LEVEL
+VOID MlmeSetPsmBit(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT psm)
+{
+ AUTO_RSP_CFG_STRUC csr4;
-/*! \brief generates a random mac address value for IBSS BSSID
- * \param Addr the bssid location
- * \return none
- * \pre
- * \post
+ pAd->StaCfg.Psm = psm;
+ RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
+ csr4.field.AckCtsPsmBit = (psm == PWR_SAVE)? 1:0;
+ RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetPsmBit = %d\n", psm));
+}
+
+/*
+ ==========================================================================
+ Description:
+ This routine calculates TxPER, RxPER of the past N-sec period. And
+ according to the calculation result, ChannelQuality is calculated here
+ to decide if current AP is still doing the job.
+
+ If ChannelQuality is not good, a ROAMing attempt may be tried later.
+ Output:
+ StaCfg.ChannelQuality - 0..100
+
+ IRQL = DISPATCH_LEVEL
+
+ NOTE: This routine decide channle quality based on RX CRC error ratio.
+ Caller should make sure a function call to NICUpdateRawCounters(pAd)
+ is performed right before this routine, so that this routine can decide
+ channel quality based on the most up-to-date information
+ ==========================================================================
*/
-VOID MacAddrRandomBssid(
+VOID MlmeCalculateChannelQuality(
IN PRTMP_ADAPTER pAd,
- OUT PUCHAR pAddr)
+ IN PMAC_TABLE_ENTRY pMacEntry,
+ IN ULONG Now32)
{
- INT i;
+ ULONG TxOkCnt, TxCnt, TxPER, TxPRR;
+ ULONG RxCnt, RxPER;
+ UCHAR NorRssi;
+ CHAR MaxRssi;
+ RSSI_SAMPLE *pRssiSample = NULL;
+ UINT32 OneSecTxNoRetryOkCount = 0;
+ UINT32 OneSecTxRetryOkCount = 0;
+ UINT32 OneSecTxFailCount = 0;
+ UINT32 OneSecRxOkCnt = 0;
+ UINT32 OneSecRxFcsErrCnt = 0;
+ ULONG ChannelQuality = 0; // 0..100, Channel Quality Indication for Roaming
+ ULONG BeaconLostTime = pAd->StaCfg.BeaconLostTime;
- for (i = 0; i < MAC_ADDR_LEN; i++)
+
+ if (pAd->OpMode == OPMODE_STA)
{
- pAddr[i] = RandomByte(pAd);
+ pRssiSample = &pAd->StaCfg.RssiSample;
+ OneSecTxNoRetryOkCount = pAd->RalinkCounters.OneSecTxNoRetryOkCount;
+ OneSecTxRetryOkCount = pAd->RalinkCounters.OneSecTxRetryOkCount;
+ OneSecTxFailCount = pAd->RalinkCounters.OneSecTxFailCount;
+ OneSecRxOkCnt = pAd->RalinkCounters.OneSecRxOkCnt;
+ OneSecRxFcsErrCnt = pAd->RalinkCounters.OneSecRxFcsErrCnt;
}
- pAddr[0] = (pAddr[0] & 0xfe) | 0x02; // the first 2 bits must be 01xxxxxxxx
-}
+ MaxRssi = RTMPMaxRssi(pAd, pRssiSample->LastRssi0,
+ pRssiSample->LastRssi1,
+ pRssiSample->LastRssi2);
-/*! \brief init the management mac frame header
- * \param p_hdr mac header
- * \param subtype subtype of the frame
- * \param p_ds destination address, don't care if it is a broadcast address
- * \return none
- * \pre the station has the following information in the pAd->StaCfg
- * - bssid
- * - station address
- * \post
- * \note this function initializes the following field
+ //
+ // calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics
+ //
+ TxOkCnt = OneSecTxNoRetryOkCount + OneSecTxRetryOkCount;
+ TxCnt = TxOkCnt + OneSecTxFailCount;
+ if (TxCnt < 5)
+ {
+ TxPER = 0;
+ TxPRR = 0;
+ }
+ else
+ {
+ TxPER = (OneSecTxFailCount * 100) / TxCnt;
+ TxPRR = ((TxCnt - OneSecTxNoRetryOkCount) * 100) / TxCnt;
+ }
- IRQL = PASSIVE_LEVEL
- IRQL = DISPATCH_LEVEL
+ //
+ // calculate RX PER - don't take RxPER into consideration if too few sample
+ //
+ RxCnt = OneSecRxOkCnt + OneSecRxFcsErrCnt;
+ if (RxCnt < 5)
+ RxPER = 0;
+ else
+ RxPER = (OneSecRxFcsErrCnt * 100) / RxCnt;
- */
-VOID MgtMacHeaderInit(
- IN PRTMP_ADAPTER pAd,
- IN OUT PHEADER_802_11 pHdr80211,
- IN UCHAR SubType,
- IN UCHAR ToDs,
- IN PUCHAR pDA,
- IN PUCHAR pBssid)
-{
- NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
+ //
+ // decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER
+ //
+ if ((pAd->OpMode == OPMODE_STA) &&
+ INFRA_ON(pAd) &&
+ (OneSecTxNoRetryOkCount < 2) && // no heavy traffic
+ ((pAd->StaCfg.LastBeaconRxTime + BeaconLostTime) < Now32))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n", BeaconLostTime, TxOkCnt));
+ ChannelQuality = 0;
+ }
+ else
+ {
+ // Normalize Rssi
+ if (MaxRssi > -40)
+ NorRssi = 100;
+ else if (MaxRssi < -90)
+ NorRssi = 0;
+ else
+ NorRssi = (MaxRssi + 90) * 2;
- pHdr80211->FC.Type = BTYPE_MGMT;
- pHdr80211->FC.SubType = SubType;
- pHdr80211->FC.ToDs = ToDs;
- COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
+ // ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER (RSSI 0..100), (TxPER 100..0), (RxPER 100..0)
+ ChannelQuality = (RSSI_WEIGHTING * NorRssi +
+ TX_WEIGHTING * (100 - TxPRR) +
+ RX_WEIGHTING* (100 - RxPER)) / 100;
+ }
- COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
- COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
-}
+ if (pAd->OpMode == OPMODE_STA)
+ pAd->Mlme.ChannelQuality = (ChannelQuality > 100) ? 100 : ChannelQuality;
-// ===========================================================================================
-// mem_mgmt.c
-// ===========================================================================================
-/*!***************************************************************************
- * This routine build an outgoing frame, and fill all information specified
- * in argument list to the frame body. The actual frame size is the summation
- * of all arguments.
- * input params:
- * Buffer - pointer to a pre-allocated memory segment
- * args - a list of <int arg_size, arg> pairs.
- * NOTE NOTE NOTE!!!! the last argument must be NULL, otherwise this
- * function will FAIL!!!
- * return:
- * Size of the buffer
- * usage:
- * MakeOutgoingFrame(Buffer, output_length, 2, &fc, 2, &dur, 6, p_addr1, 6,p_addr2, END_OF_ARGS);
+}
- IRQL = PASSIVE_LEVEL
- IRQL = DISPATCH_LEVEL
- ****************************************************************************/
-ULONG MakeOutgoingFrame(
- OUT CHAR *Buffer,
- OUT ULONG *FrameLen, ...)
+// IRQL = DISPATCH_LEVEL
+VOID MlmeSetTxPreamble(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT TxPreamble)
{
- CHAR *p;
- int leng;
- ULONG TotLeng;
- va_list Args;
+ AUTO_RSP_CFG_STRUC csr4;
- // calculates the total length
- TotLeng = 0;
- va_start(Args, FrameLen);
- do
+ //
+ // Always use Long preamble before verifiation short preamble functionality works well.
+ // Todo: remove the following line if short preamble functionality works
+ //
+ //TxPreamble = Rt802_11PreambleLong;
+
+ RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
+ if (TxPreamble == Rt802_11PreambleLong)
{
- leng = va_arg(Args, int);
- if (leng == END_OF_ARGS)
- {
- break;
- }
- p = va_arg(Args, PVOID);
- NdisMoveMemory(&Buffer[TotLeng], p, leng);
- TotLeng = TotLeng + leng;
- } while(TRUE);
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= LONG PREAMBLE)\n"));
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+ csr4.field.AutoResponderPreamble = 0;
+ }
+ else
+ {
+ // NOTE: 1Mbps should always use long preamble
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= SHORT PREAMBLE)\n"));
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+ csr4.field.AutoResponderPreamble = 1;
+ }
+
+ RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Update basic rate bitmap
+ ==========================================================================
+ */
+
+VOID UpdateBasicRateBitmap(
+ IN PRTMP_ADAPTER pAdapter)
+{
+ INT i, j;
+ /* 1 2 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */
+ UCHAR rate[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
+ UCHAR *sup_p = pAdapter->CommonCfg.SupRate;
+ UCHAR *ext_p = pAdapter->CommonCfg.ExtRate;
+ ULONG bitmap = pAdapter->CommonCfg.BasicRateBitmap;
+
+
+ /* if A mode, always use fix BasicRateBitMap */
+ //if (pAdapter->CommonCfg.Channel == PHY_11A)
+ if (pAdapter->CommonCfg.Channel > 14)
+ pAdapter->CommonCfg.BasicRateBitmap = 0x150; /* 6, 12, 24M */
+ /* End of if */
- va_end(Args); /* clean up */
- *FrameLen = TotLeng;
- return TotLeng;
-}
+ if (pAdapter->CommonCfg.BasicRateBitmap > 4095)
+ {
+ /* (2 ^ MAX_LEN_OF_SUPPORTED_RATES) -1 */
+ return;
+ } /* End of if */
-// ===========================================================================================
-// mlme_queue.c
-// ===========================================================================================
+ for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
+ {
+ sup_p[i] &= 0x7f;
+ ext_p[i] &= 0x7f;
+ } /* End of for */
-/*! \brief Initialize The MLME Queue, used by MLME Functions
- * \param *Queue The MLME Queue
- * \return Always Return NDIS_STATE_SUCCESS in this implementation
- * \pre
- * \post
- * \note Because this is done only once (at the init stage), no need to be locked
+ for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
+ {
+ if (bitmap & (1 << i))
+ {
+ for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
+ {
+ if (sup_p[j] == rate[i])
+ sup_p[j] |= 0x80;
+ /* End of if */
+ } /* End of for */
- IRQL = PASSIVE_LEVEL
+ for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
+ {
+ if (ext_p[j] == rate[i])
+ ext_p[j] |= 0x80;
+ /* End of if */
+ } /* End of for */
+ } /* End of if */
+ } /* End of for */
+} /* End of UpdateBasicRateBitmap */
- */
-NDIS_STATUS MlmeQueueInit(
- IN MLME_QUEUE *Queue)
+// IRQL = PASSIVE_LEVEL
+// IRQL = DISPATCH_LEVEL
+// bLinkUp is to identify the inital link speed.
+// TRUE indicates the rate update at linkup, we should not try to set the rate at 54Mbps.
+VOID MlmeUpdateTxRates(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bLinkUp,
+ IN UCHAR apidx)
{
- INT i;
-
- NdisAllocateSpinLock(&Queue->Lock);
+ int i, num;
+ UCHAR Rate = RATE_6, MaxDesire = RATE_1, MaxSupport = RATE_1;
+ UCHAR MinSupport = RATE_54;
+ ULONG BasicRateBitmap = 0;
+ UCHAR CurrBasicRate = RATE_1;
+ UCHAR *pSupRate, SupRateLen, *pExtRate, ExtRateLen;
+ PHTTRANSMIT_SETTING pHtPhy = NULL;
+ PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
+ PHTTRANSMIT_SETTING pMinHtPhy = NULL;
+ BOOLEAN *auto_rate_cur_p;
+ UCHAR HtMcs = MCS_AUTO;
- Queue->Num = 0;
- Queue->Head = 0;
- Queue->Tail = 0;
+ // find max desired rate
+ UpdateBasicRateBitmap(pAd);
- for (i = 0; i < MAX_LEN_OF_MLME_QUEUE; i++)
+ num = 0;
+ auto_rate_cur_p = NULL;
+ for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
{
- Queue->Entry[i].Occupied = FALSE;
- Queue->Entry[i].MsgLen = 0;
- NdisZeroMemory(Queue->Entry[i].Msg, MGMT_DMA_BUFFER_SIZE);
+ switch (pAd->CommonCfg.DesireRate[i] & 0x7f)
+ {
+ case 2: Rate = RATE_1; num++; break;
+ case 4: Rate = RATE_2; num++; break;
+ case 11: Rate = RATE_5_5; num++; break;
+ case 22: Rate = RATE_11; num++; break;
+ case 12: Rate = RATE_6; num++; break;
+ case 18: Rate = RATE_9; num++; break;
+ case 24: Rate = RATE_12; num++; break;
+ case 36: Rate = RATE_18; num++; break;
+ case 48: Rate = RATE_24; num++; break;
+ case 72: Rate = RATE_36; num++; break;
+ case 96: Rate = RATE_48; num++; break;
+ case 108: Rate = RATE_54; num++; break;
+ //default: Rate = RATE_1; break;
+ }
+ if (MaxDesire < Rate) MaxDesire = Rate;
}
- return NDIS_STATUS_SUCCESS;
-}
-
-/*! \brief Enqueue a message for other threads, if they want to send messages to MLME thread
- * \param *Queue The MLME Queue
- * \param Machine The State Machine Id
- * \param MsgType The Message Type
- * \param MsgLen The Message length
- * \param *Msg The message pointer
- * \return TRUE if enqueue is successful, FALSE if the queue is full
- * \pre
- * \post
- * \note The message has to be initialized
+//===========================================================================
+//===========================================================================
+ {
+ pHtPhy = &pAd->StaCfg.HTPhyMode;
+ pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
+ pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
- IRQL = PASSIVE_LEVEL
- IRQL = DISPATCH_LEVEL
+ auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
+ HtMcs = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
- */
-BOOLEAN MlmeEnqueue(
- IN PRTMP_ADAPTER pAd,
- IN ULONG Machine,
- IN ULONG MsgType,
- IN ULONG MsgLen,
- IN VOID *Msg)
-{
- INT Tail;
- MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
+ if ((pAd->StaCfg.BssType == BSS_ADHOC) &&
+ (pAd->CommonCfg.PhyMode == PHY_11B) &&
+ (MaxDesire > RATE_11))
+ {
+ MaxDesire = RATE_11;
+ }
+ }
- // Do nothing if the driver is starting halt state.
- // This might happen when timer already been fired before cancel timer with mlmehalt
- if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
- return FALSE;
+ pAd->CommonCfg.MaxDesiredRate = MaxDesire;
+ pMinHtPhy->word = 0;
+ pMaxHtPhy->word = 0;
+ pHtPhy->word = 0;
- // First check the size, it MUST not exceed the mlme queue size
- if (MsgLen > MGMT_DMA_BUFFER_SIZE)
+ // Auto rate switching is enabled only if more than one DESIRED RATES are
+ // specified; otherwise disabled
+ if (num <= 1)
{
- DBGPRINT_ERR(("MlmeEnqueue: msg too large, size = %ld \n", MsgLen));
- return FALSE;
+ //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
+ //pAd->CommonCfg.bAutoTxRateSwitch = FALSE;
+ *auto_rate_cur_p = FALSE;
}
-
- if (MlmeQueueFull(Queue))
+ else
{
- return FALSE;
+ //OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
+ //pAd->CommonCfg.bAutoTxRateSwitch = TRUE;
+ *auto_rate_cur_p = TRUE;
}
- NdisAcquireSpinLock(&(Queue->Lock));
- Tail = Queue->Tail;
- Queue->Tail++;
- Queue->Num++;
- if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
+ if (HtMcs != MCS_AUTO)
{
- Queue->Tail = 0;
+ //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
+ //pAd->CommonCfg.bAutoTxRateSwitch = FALSE;
+ *auto_rate_cur_p = FALSE;
}
-
- Queue->Entry[Tail].Wcid = RESERVED_WCID;
- Queue->Entry[Tail].Occupied = TRUE;
- Queue->Entry[Tail].Machine = Machine;
- Queue->Entry[Tail].MsgType = MsgType;
- Queue->Entry[Tail].MsgLen = MsgLen;
-
- if (Msg != NULL)
+ else
{
- NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
+ //OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
+ //pAd->CommonCfg.bAutoTxRateSwitch = TRUE;
+ *auto_rate_cur_p = TRUE;
}
- NdisReleaseSpinLock(&(Queue->Lock));
- return TRUE;
-}
-
-/*! \brief This function is used when Recv gets a MLME message
- * \param *Queue The MLME Queue
- * \param TimeStampHigh The upper 32 bit of timestamp
- * \param TimeStampLow The lower 32 bit of timestamp
- * \param Rssi The receiving RSSI strength
- * \param MsgLen The length of the message
- * \param *Msg The message pointer
- * \return TRUE if everything ok, FALSE otherwise (like Queue Full)
- * \pre
- * \post
-
- IRQL = DISPATCH_LEVEL
-
- */
-BOOLEAN MlmeEnqueueForRecv(
- IN PRTMP_ADAPTER pAd,
- IN ULONG Wcid,
- IN ULONG TimeStampHigh,
- IN ULONG TimeStampLow,
- IN UCHAR Rssi0,
- IN UCHAR Rssi1,
- IN UCHAR Rssi2,
- IN ULONG MsgLen,
- IN VOID *Msg,
- IN UCHAR Signal)
-{
- INT Tail, Machine;
- PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
- INT MsgType;
- MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
-
- // Do nothing if the driver is starting halt state.
- // This might happen when timer already been fired before cancel timer with mlmehalt
- if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+ if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
{
- DBGPRINT_ERR(("MlmeEnqueueForRecv: fRTMP_ADAPTER_HALT_IN_PROGRESS\n"));
- return FALSE;
+ pSupRate = &pAd->StaActive.SupRate[0];
+ pExtRate = &pAd->StaActive.ExtRate[0];
+ SupRateLen = pAd->StaActive.SupRateLen;
+ ExtRateLen = pAd->StaActive.ExtRateLen;
}
-
- // First check the size, it MUST not exceed the mlme queue size
- if (MsgLen > MGMT_DMA_BUFFER_SIZE)
+ else
{
- DBGPRINT_ERR(("MlmeEnqueueForRecv: frame too large, size = %ld \n", MsgLen));
- return FALSE;
+ pSupRate = &pAd->CommonCfg.SupRate[0];
+ pExtRate = &pAd->CommonCfg.ExtRate[0];
+ SupRateLen = pAd->CommonCfg.SupRateLen;
+ ExtRateLen = pAd->CommonCfg.ExtRateLen;
}
- if (MlmeQueueFull(Queue))
+ // find max supported rate
+ for (i=0; i<SupRateLen; i++)
{
- return FALSE;
+ switch (pSupRate[i] & 0x7f)
+ {
+ case 2: Rate = RATE_1; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0001; break;
+ case 4: Rate = RATE_2; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0002; break;
+ case 11: Rate = RATE_5_5; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0004; break;
+ case 22: Rate = RATE_11; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0008; break;
+ case 12: Rate = RATE_6; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 0x0010; break;
+ case 18: Rate = RATE_9; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0020; break;
+ case 24: Rate = RATE_12; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 0x0040; break;
+ case 36: Rate = RATE_18; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0080; break;
+ case 48: Rate = RATE_24; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 0x0100; break;
+ case 72: Rate = RATE_36; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0200; break;
+ case 96: Rate = RATE_48; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0400; break;
+ case 108: Rate = RATE_54; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0800; break;
+ default: Rate = RATE_1; break;
+ }
+ if (MaxSupport < Rate) MaxSupport = Rate;
+
+ if (MinSupport > Rate) MinSupport = Rate;
}
+ for (i=0; i<ExtRateLen; i++)
{
- if (!MsgTypeSubst(pAd, pFrame, &Machine, &MsgType))
+ switch (pExtRate[i] & 0x7f)
{
- DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n",pFrame->Hdr.FC.SubType));
- return FALSE;
+ case 2: Rate = RATE_1; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0001; break;
+ case 4: Rate = RATE_2; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0002; break;
+ case 11: Rate = RATE_5_5; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0004; break;
+ case 22: Rate = RATE_11; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0008; break;
+ case 12: Rate = RATE_6; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 0x0010; break;
+ case 18: Rate = RATE_9; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0020; break;
+ case 24: Rate = RATE_12; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 0x0040; break;
+ case 36: Rate = RATE_18; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0080; break;
+ case 48: Rate = RATE_24; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 0x0100; break;
+ case 72: Rate = RATE_36; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0200; break;
+ case 96: Rate = RATE_48; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0400; break;
+ case 108: Rate = RATE_54; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0800; break;
+ default: Rate = RATE_1; break;
}
- }
+ if (MaxSupport < Rate) MaxSupport = Rate;
- // OK, we got all the informations, it is time to put things into queue
- NdisAcquireSpinLock(&(Queue->Lock));
- Tail = Queue->Tail;
- Queue->Tail++;
- Queue->Num++;
- if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
- {
- Queue->Tail = 0;
+ if (MinSupport > Rate) MinSupport = Rate;
}
- Queue->Entry[Tail].Occupied = TRUE;
- Queue->Entry[Tail].Machine = Machine;
- Queue->Entry[Tail].MsgType = MsgType;
- Queue->Entry[Tail].MsgLen = MsgLen;
- Queue->Entry[Tail].TimeStamp.u.LowPart = TimeStampLow;
- Queue->Entry[Tail].TimeStamp.u.HighPart = TimeStampHigh;
- Queue->Entry[Tail].Rssi0 = Rssi0;
- Queue->Entry[Tail].Rssi1 = Rssi1;
- Queue->Entry[Tail].Rssi2 = Rssi2;
- Queue->Entry[Tail].Signal = Signal;
- Queue->Entry[Tail].Wcid = (UCHAR)Wcid;
- Queue->Entry[Tail].Channel = pAd->LatchRfRegs.Channel;
+ RTMP_IO_WRITE32(pAd, LEGACY_BASIC_RATE, BasicRateBitmap);
- if (Msg != NULL)
+ // bug fix
+ // pAd->CommonCfg.BasicRateBitmap = BasicRateBitmap;
+
+ // calculate the exptected ACK rate for each TX rate. This info is used to caculate
+ // the DURATION field of outgoing uniicast DATA/MGMT frame
+ for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
{
- NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
+ if (BasicRateBitmap & (0x01 << i))
+ CurrBasicRate = (UCHAR)i;
+ pAd->CommonCfg.ExpectedACKRate[i] = CurrBasicRate;
}
- NdisReleaseSpinLock(&(Queue->Lock));
+ DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateTxRates[MaxSupport = %d] = MaxDesire %d Mbps\n", RateIdToMbps[MaxSupport], RateIdToMbps[MaxDesire]));
+ // max tx rate = min {max desire rate, max supported rate}
+ if (MaxSupport < MaxDesire)
+ pAd->CommonCfg.MaxTxRate = MaxSupport;
+ else
+ pAd->CommonCfg.MaxTxRate = MaxDesire;
- RT28XX_MLME_HANDLER(pAd);
+ pAd->CommonCfg.MinTxRate = MinSupport;
+ // 2003-07-31 john - 2500 doesn't have good sensitivity at high OFDM rates. to increase the success
+ // ratio of initial DHCP packet exchange, TX rate starts from a lower rate depending
+ // on average RSSI
+ // 1. RSSI >= -70db, start at 54 Mbps (short distance)
+ // 2. -70 > RSSI >= -75, start at 24 Mbps (mid distance)
+ // 3. -75 > RSSI, start at 11 Mbps (long distance)
+ //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)/* &&
+ // OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)*/)
+ if (*auto_rate_cur_p)
+ {
+ short dbm = 0;
- return TRUE;
-}
+ dbm = pAd->StaCfg.RssiSample.AvgRssi0 - pAd->BbpRssiToDbmDelta;
+ if (bLinkUp == TRUE)
+ pAd->CommonCfg.TxRate = RATE_24;
+ else
+ pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
-/*! \brief Dequeue a message from the MLME Queue
- * \param *Queue The MLME Queue
- * \param *Elem The message dequeued from MLME Queue
- * \return TRUE if the Elem contains something, FALSE otherwise
- * \pre
- * \post
+ if (dbm < -75)
+ pAd->CommonCfg.TxRate = RATE_11;
+ else if (dbm < -70)
+ pAd->CommonCfg.TxRate = RATE_24;
- IRQL = DISPATCH_LEVEL
+ // should never exceed MaxTxRate (consider 11B-only mode)
+ if (pAd->CommonCfg.TxRate > pAd->CommonCfg.MaxTxRate)
+ pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
- */
-BOOLEAN MlmeDequeue(
- IN MLME_QUEUE *Queue,
- OUT MLME_QUEUE_ELEM **Elem)
-{
- NdisAcquireSpinLock(&(Queue->Lock));
- *Elem = &(Queue->Entry[Queue->Head]);
- Queue->Num--;
- Queue->Head++;
- if (Queue->Head == MAX_LEN_OF_MLME_QUEUE)
- {
- Queue->Head = 0;
+ pAd->CommonCfg.TxRateIndex = 0;
}
- NdisReleaseSpinLock(&(Queue->Lock));
- return TRUE;
-}
-
-// IRQL = DISPATCH_LEVEL
-VOID MlmeRestartStateMachine(
- IN PRTMP_ADAPTER pAd)
-{
-#ifdef RT2860
- MLME_QUEUE_ELEM *Elem = NULL;
-#endif
- BOOLEAN Cancelled;
+ else
+ {
+ pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
+ pHtPhy->field.MCS = (pAd->CommonCfg.MaxTxRate > 3) ? (pAd->CommonCfg.MaxTxRate - 4) : pAd->CommonCfg.MaxTxRate;
+ pHtPhy->field.MODE = (pAd->CommonCfg.MaxTxRate > 3) ? MODE_OFDM : MODE_CCK;
- DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n"));
+ pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC = pHtPhy->field.STBC;
+ pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI = pHtPhy->field.ShortGI;
+ pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS = pHtPhy->field.MCS;
+ pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE = pHtPhy->field.MODE;
+ }
-#ifdef RT2860
- NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
- if(pAd->Mlme.bRunning)
+ if (pAd->CommonCfg.TxRate <= RATE_11)
{
- NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
- return;
+ pMaxHtPhy->field.MODE = MODE_CCK;
+ pMaxHtPhy->field.MCS = pAd->CommonCfg.TxRate;
+ pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;
}
else
{
- pAd->Mlme.bRunning = TRUE;
+ pMaxHtPhy->field.MODE = MODE_OFDM;
+ pMaxHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.TxRate];
+ if (pAd->CommonCfg.MinTxRate >= RATE_6 && (pAd->CommonCfg.MinTxRate <= RATE_54))
+ {pMinHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MinTxRate];}
+ else
+ {pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;}
}
- NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
- // Remove all Mlme queues elements
- while (!MlmeQueueEmpty(&pAd->Mlme.Queue))
+ pHtPhy->word = (pMaxHtPhy->word);
+ if (bLinkUp && (pAd->OpMode == OPMODE_STA))
{
- //From message type, determine which state machine I should drive
- if (MlmeDequeue(&pAd->Mlme.Queue, &Elem))
- {
- // free MLME element
- Elem->Occupied = FALSE;
- Elem->MsgLen = 0;
-
- }
- else {
- DBGPRINT_ERR(("MlmeRestartStateMachine: MlmeQueue empty\n"));
- }
+ pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word = pHtPhy->word;
+ pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word = pMaxHtPhy->word;
+ pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word = pMinHtPhy->word;
}
-#endif /* RT2860 */
+ else
+ {
+ switch (pAd->CommonCfg.PhyMode)
+ {
+ case PHY_11BG_MIXED:
+ case PHY_11B:
+ case PHY_11BGN_MIXED:
+ pAd->CommonCfg.MlmeRate = RATE_1;
+ pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
+ pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
+//#ifdef WIFI_TEST
+ pAd->CommonCfg.RtsRate = RATE_11;
+//#else
+// pAd->CommonCfg.RtsRate = RATE_1;
+//#endif
+ break;
+ case PHY_11G:
+ case PHY_11A:
+ case PHY_11AGN_MIXED:
+ case PHY_11GN_MIXED:
+ case PHY_11N_2_4G:
+ case PHY_11AN_MIXED:
+ case PHY_11N_5G:
+ pAd->CommonCfg.MlmeRate = RATE_6;
+ pAd->CommonCfg.RtsRate = RATE_6;
+ pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
+ pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+ break;
+ case PHY_11ABG_MIXED:
+ case PHY_11ABGN_MIXED:
+ if (pAd->CommonCfg.Channel <= 14)
{
- // Cancel all timer events
- // Be careful to cancel new added timer
- RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
- RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
- RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
- RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
- RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
- RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
+ pAd->CommonCfg.MlmeRate = RATE_1;
+ pAd->CommonCfg.RtsRate = RATE_1;
+ pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
+ pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
}
-
- // Change back to original channel in case of doing scan
- AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
- AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-
- // Resume MSDU which is turned off durning scan
- RTMPResumeMsduTransmission(pAd);
-
+ else
{
- // Set all state machines back IDLE
- pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
- pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
- pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
- pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE;
- pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
- pAd->Mlme.ActMachine.CurrState = ACT_IDLE;
+ pAd->CommonCfg.MlmeRate = RATE_6;
+ pAd->CommonCfg.RtsRate = RATE_6;
+ pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
+ pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+ }
+ break;
+ default: // error
+ pAd->CommonCfg.MlmeRate = RATE_6;
+ pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
+ pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+ pAd->CommonCfg.RtsRate = RATE_1;
+ break;
+ }
+ //
+ // Keep Basic Mlme Rate.
+ //
+ pAd->MacTab.Content[MCAST_WCID].HTPhyMode.word = pAd->CommonCfg.MlmeTransmit.word;
+ if (pAd->CommonCfg.MlmeTransmit.field.MODE == MODE_OFDM)
+ pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[RATE_24];
+ else
+ pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = RATE_1;
+ pAd->CommonCfg.BasicMlmeRate = pAd->CommonCfg.MlmeRate;
}
-#ifdef RT2860
- // Remove running state
- NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
- pAd->Mlme.bRunning = FALSE;
- NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
-#endif
+ DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n",
+ RateIdToMbps[MaxDesire], RateIdToMbps[MaxSupport], RateIdToMbps[pAd->CommonCfg.MaxTxRate], RateIdToMbps[pAd->CommonCfg.MinTxRate],
+ /*OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)*/*auto_rate_cur_p));
+ DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n",
+ RateIdToMbps[pAd->CommonCfg.TxRate], RateIdToMbps[pAd->CommonCfg.RtsRate], BasicRateBitmap));
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateTxRates (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n",
+ pAd->CommonCfg.MlmeTransmit.word, pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word ,pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word ,pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word ));
}
-/*! \brief test if the MLME Queue is empty
- * \param *Queue The MLME Queue
- * \return TRUE if the Queue is empty, FALSE otherwise
- * \pre
- * \post
+/*
+ ==========================================================================
+ Description:
+ This function update HT Rate setting.
+ Input Wcid value is valid for 2 case :
+ 1. it's used for Station in infra mode that copy AP rate to Mactable.
+ 2. OR Station in adhoc mode to copy peer's HT rate to Mactable.
IRQL = DISPATCH_LEVEL
+ ==========================================================================
*/
-BOOLEAN MlmeQueueEmpty(
- IN MLME_QUEUE *Queue)
+VOID MlmeUpdateHtTxRates(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR apidx)
{
- BOOLEAN Ans;
+ UCHAR StbcMcs; //j, StbcMcs, bitmask;
+ CHAR i; // 3*3
+ RT_HT_CAPABILITY *pRtHtCap = NULL;
+ RT_HT_PHY_INFO *pActiveHtPhy = NULL;
+ ULONG BasicMCS;
+ UCHAR j, bitmask;
+ PRT_HT_PHY_INFO pDesireHtPhy = NULL;
+ PHTTRANSMIT_SETTING pHtPhy = NULL;
+ PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
+ PHTTRANSMIT_SETTING pMinHtPhy = NULL;
+ BOOLEAN *auto_rate_cur_p;
- NdisAcquireSpinLock(&(Queue->Lock));
- Ans = (Queue->Num == 0);
- NdisReleaseSpinLock(&(Queue->Lock));
+ DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates===> \n"));
- return Ans;
-}
+ auto_rate_cur_p = NULL;
-/*! \brief test if the MLME Queue is full
- * \param *Queue The MLME Queue
- * \return TRUE if the Queue is empty, FALSE otherwise
- * \pre
- * \post
+ {
+ pDesireHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
+ pActiveHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
+ pHtPhy = &pAd->StaCfg.HTPhyMode;
+ pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
+ pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
- IRQL = PASSIVE_LEVEL
- IRQL = DISPATCH_LEVEL
+ auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
+ }
- */
-BOOLEAN MlmeQueueFull(
- IN MLME_QUEUE *Queue)
-{
- BOOLEAN Ans;
+ if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
+ {
+ if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
+ return;
- NdisAcquireSpinLock(&(Queue->Lock));
- Ans = (Queue->Num == MAX_LEN_OF_MLME_QUEUE || Queue->Entry[Queue->Tail].Occupied);
- NdisReleaseSpinLock(&(Queue->Lock));
+ pRtHtCap = &pAd->StaActive.SupportedHtPhy;
+ pActiveHtPhy = &pAd->StaActive.SupportedPhyInfo;
+ StbcMcs = (UCHAR)pAd->MlmeAux.AddHtInfo.AddHtInfo3.StbcMcs;
+ BasicMCS =pAd->MlmeAux.AddHtInfo.MCSSet[0]+(pAd->MlmeAux.AddHtInfo.MCSSet[1]<<8)+(StbcMcs<<16);
+ if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
+ pMaxHtPhy->field.STBC = STBC_USE;
+ else
+ pMaxHtPhy->field.STBC = STBC_NONE;
+ }
+ else
+ {
+ if (pDesireHtPhy->bHtEnable == FALSE)
+ return;
- return Ans;
-}
+ pRtHtCap = &pAd->CommonCfg.DesiredHtPhy;
+ StbcMcs = (UCHAR)pAd->CommonCfg.AddHTInfo.AddHtInfo3.StbcMcs;
+ BasicMCS = pAd->CommonCfg.AddHTInfo.MCSSet[0]+(pAd->CommonCfg.AddHTInfo.MCSSet[1]<<8)+(StbcMcs<<16);
+ if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
+ pMaxHtPhy->field.STBC = STBC_USE;
+ else
+ pMaxHtPhy->field.STBC = STBC_NONE;
+ }
-/*! \brief The destructor of MLME Queue
- * \param
- * \return
- * \pre
- * \post
- * \note Clear Mlme Queue, Set Queue->Num to Zero.
+ // Decide MAX ht rate.
+ if ((pRtHtCap->GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
+ pMaxHtPhy->field.MODE = MODE_HTGREENFIELD;
+ else
+ pMaxHtPhy->field.MODE = MODE_HTMIX;
- IRQL = PASSIVE_LEVEL
+ if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth) && (pRtHtCap->ChannelWidth))
+ pMaxHtPhy->field.BW = BW_40;
+ else
+ pMaxHtPhy->field.BW = BW_20;
- */
-VOID MlmeQueueDestroy(
- IN MLME_QUEUE *pQueue)
-{
- NdisAcquireSpinLock(&(pQueue->Lock));
- pQueue->Num = 0;
- pQueue->Head = 0;
- pQueue->Tail = 0;
- NdisReleaseSpinLock(&(pQueue->Lock));
- NdisFreeSpinLock(&(pQueue->Lock));
-}
+ if (pMaxHtPhy->field.BW == BW_20)
+ pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 & pRtHtCap->ShortGIfor20);
+ else
+ pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 & pRtHtCap->ShortGIfor40);
-/*! \brief To substitute the message type if the message is coming from external
- * \param pFrame The frame received
- * \param *Machine The state machine
- * \param *MsgType the message type for the state machine
- * \return TRUE if the substitution is successful, FALSE otherwise
- * \pre
- * \post
+ if (pDesireHtPhy->MCSSet[4] != 0)
+ {
+ pMaxHtPhy->field.MCS = 32;
+ }
- IRQL = DISPATCH_LEVEL
+ for (i=23; i>=0; i--) // 3*3
+ {
+ j = i/8;
+ bitmask = (1<<(i-(j*8)));
- */
-BOOLEAN MsgTypeSubst(
- IN PRTMP_ADAPTER pAd,
- IN PFRAME_802_11 pFrame,
- OUT INT *Machine,
- OUT INT *MsgType)
-{
- USHORT Seq;
- UCHAR EAPType;
- PUCHAR pData;
+ if ((pActiveHtPhy->MCSSet[j] & bitmask) && (pDesireHtPhy->MCSSet[j] & bitmask))
+ {
+ pMaxHtPhy->field.MCS = i;
+ break;
+ }
- // Pointer to start of data frames including SNAP header
- pData = (PUCHAR) pFrame + LENGTH_802_11;
+ if (i==0)
+ break;
+ }
- // The only data type will pass to this function is EAPOL frame
- if (pFrame->Hdr.FC.Type == BTYPE_DATA)
+ // Copy MIN ht rate. rt2860???
+ pMinHtPhy->field.BW = BW_20;
+ pMinHtPhy->field.MCS = 0;
+ pMinHtPhy->field.STBC = 0;
+ pMinHtPhy->field.ShortGI = 0;
+ //If STA assigns fixed rate. update to fixed here.
+ if ( (pAd->OpMode == OPMODE_STA) && (pDesireHtPhy->MCSSet[0] != 0xff))
{
- if (NdisEqualMemory(SNAP_AIRONET, pData, LENGTH_802_1_H))
- {
- // Cisco Aironet SNAP header
- *Machine = AIRONET_STATE_MACHINE;
- *MsgType = MT2_AIRONET_MSG;
- return (TRUE);
- }
+ if (pDesireHtPhy->MCSSet[4] != 0)
+ {
+ pMaxHtPhy->field.MCS = 32;
+ pMinHtPhy->field.MCS = 32;
+ DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n",pMinHtPhy->field.MCS));
+ }
+
+ for (i=23; (CHAR)i >= 0; i--) // 3*3
+ {
+ j = i/8;
+ bitmask = (1<<(i-(j*8)));
+ if ( (pDesireHtPhy->MCSSet[j] & bitmask) && (pActiveHtPhy->MCSSet[j] & bitmask))
{
- *Machine = WPA_PSK_STATE_MACHINE;
- EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
- return(WpaMsgTypeSubst(EAPType, MsgType));
+ pMaxHtPhy->field.MCS = i;
+ pMinHtPhy->field.MCS = i;
+ break;
}
+ if (i==0)
+ break;
+ }
}
- switch (pFrame->Hdr.FC.SubType)
- {
- case SUBTYPE_ASSOC_REQ:
- *Machine = ASSOC_STATE_MACHINE;
- *MsgType = MT2_PEER_ASSOC_REQ;
- break;
- case SUBTYPE_ASSOC_RSP:
- *Machine = ASSOC_STATE_MACHINE;
- *MsgType = MT2_PEER_ASSOC_RSP;
- break;
- case SUBTYPE_REASSOC_REQ:
- *Machine = ASSOC_STATE_MACHINE;
- *MsgType = MT2_PEER_REASSOC_REQ;
- break;
- case SUBTYPE_REASSOC_RSP:
- *Machine = ASSOC_STATE_MACHINE;
- *MsgType = MT2_PEER_REASSOC_RSP;
- break;
- case SUBTYPE_PROBE_REQ:
- *Machine = SYNC_STATE_MACHINE;
- *MsgType = MT2_PEER_PROBE_REQ;
- break;
- case SUBTYPE_PROBE_RSP:
- *Machine = SYNC_STATE_MACHINE;
- *MsgType = MT2_PEER_PROBE_RSP;
- break;
- case SUBTYPE_BEACON:
- *Machine = SYNC_STATE_MACHINE;
- *MsgType = MT2_PEER_BEACON;
- break;
- case SUBTYPE_ATIM:
- *Machine = SYNC_STATE_MACHINE;
- *MsgType = MT2_PEER_ATIM;
- break;
- case SUBTYPE_DISASSOC:
- *Machine = ASSOC_STATE_MACHINE;
- *MsgType = MT2_PEER_DISASSOC_REQ;
- break;
- case SUBTYPE_AUTH:
- // get the sequence number from payload 24 Mac Header + 2 bytes algorithm
- NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(USHORT));
- if (Seq == 1 || Seq == 3)
- {
- *Machine = AUTH_RSP_STATE_MACHINE;
- *MsgType = MT2_PEER_AUTH_ODD;
- }
- else if (Seq == 2 || Seq == 4)
- {
- *Machine = AUTH_STATE_MACHINE;
- *MsgType = MT2_PEER_AUTH_EVEN;
- }
- else
- {
- return FALSE;
- }
- break;
- case SUBTYPE_DEAUTH:
- *Machine = AUTH_RSP_STATE_MACHINE;
- *MsgType = MT2_PEER_DEAUTH;
- break;
- case SUBTYPE_ACTION:
- *Machine = ACTION_STATE_MACHINE;
- // Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support
- if ((pFrame->Octet[0]&0x7F) > MAX_PEER_CATE_MSG)
- {
- *MsgType = MT2_ACT_INVALID;
- }
- else
- {
- *MsgType = (pFrame->Octet[0]&0x7F);
- }
- break;
- default:
- return FALSE;
- break;
+
+ // Decide ht rate
+ pHtPhy->field.STBC = pMaxHtPhy->field.STBC;
+ pHtPhy->field.BW = pMaxHtPhy->field.BW;
+ pHtPhy->field.MODE = pMaxHtPhy->field.MODE;
+ pHtPhy->field.MCS = pMaxHtPhy->field.MCS;
+ pHtPhy->field.ShortGI = pMaxHtPhy->field.ShortGI;
+
+ // use default now. rt2860
+ if (pDesireHtPhy->MCSSet[0] != 0xff)
+ *auto_rate_cur_p = FALSE;
+ else
+ *auto_rate_cur_p = TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateHtTxRates<---.AMsduSize = %d \n", pAd->CommonCfg.DesiredHtPhy.AmsduSize ));
+ DBGPRINT(RT_DEBUG_TRACE,("TX: MCS[0] = %x (choose %d), BW = %d, ShortGI = %d, MODE = %d, \n", pActiveHtPhy->MCSSet[0],pHtPhy->field.MCS,
+ pHtPhy->field.BW, pHtPhy->field.ShortGI, pHtPhy->field.MODE));
+ DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== \n"));
+}
+
+
+VOID BATableInit(
+ IN PRTMP_ADAPTER pAd,
+ IN BA_TABLE *Tab)
+{
+ int i;
+
+ Tab->numAsOriginator = 0;
+ Tab->numAsRecipient = 0;
+ Tab->numDoneOriginator = 0;
+ NdisAllocateSpinLock(&pAd->BATabLock);
+ for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++)
+ {
+ Tab->BARecEntry[i].REC_BA_Status = Recipient_NONE;
+ NdisAllocateSpinLock(&(Tab->BARecEntry[i].RxReRingLock));
+ }
+ for (i = 0; i < MAX_LEN_OF_BA_ORI_TABLE; i++)
+ {
+ Tab->BAOriEntry[i].ORI_BA_Status = Originator_NONE;
}
+}
- return TRUE;
+// IRQL = DISPATCH_LEVEL
+VOID MlmeRadioOff(
+ IN PRTMP_ADAPTER pAd)
+{
+ RTMP_MLME_RADIO_OFF(pAd);
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID MlmeRadioOn(
+ IN PRTMP_ADAPTER pAd)
+{
+ RTMP_MLME_RADIO_ON(pAd);
}
// ===========================================================================================
-// state_machine.c
+// bss_table.c
// ===========================================================================================
-/*! \brief Initialize the state machine.
- * \param *S pointer to the state machine
- * \param Trans State machine transition function
- * \param StNr number of states
- * \param MsgNr number of messages
- * \param DefFunc default function, when there is invalid state/message combination
- * \param InitState initial state of the state machine
- * \param Base StateMachine base, internal use only
- * \pre p_sm should be a legal pointer
+
+/*! \brief initialize BSS table
+ * \param p_tab pointer to the table
+ * \return none
+ * \pre
* \post
IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
*/
-VOID StateMachineInit(
- IN STATE_MACHINE *S,
- IN STATE_MACHINE_FUNC Trans[],
- IN ULONG StNr,
- IN ULONG MsgNr,
- IN STATE_MACHINE_FUNC DefFunc,
- IN ULONG InitState,
- IN ULONG Base)
+VOID BssTableInit(
+ IN BSS_TABLE *Tab)
{
- ULONG i, j;
+ int i;
- // set number of states and messages
- S->NrState = StNr;
- S->NrMsg = MsgNr;
- S->Base = Base;
+ Tab->BssNr = 0;
+ Tab->BssOverlapNr = 0;
+ for (i = 0; i < MAX_LEN_OF_BSS_TABLE; i++)
+ {
+ NdisZeroMemory(&Tab->BssEntry[i], sizeof(BSS_ENTRY));
+ Tab->BssEntry[i].Rssi = -127; // initial the rssi as a minimum value
+ }
+}
- S->TransFunc = Trans;
- // init all state transition to default function
- for (i = 0; i < StNr; i++)
+/*! \brief search the BSS table by SSID
+ * \param p_tab pointer to the bss table
+ * \param ssid SSID string
+ * \return index of the table, BSS_NOT_FOUND if not in the table
+ * \pre
+ * \post
+ * \note search by sequential search
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+ULONG BssTableSearch(
+ IN BSS_TABLE *Tab,
+ IN PUCHAR pBssid,
+ IN UCHAR Channel)
+{
+ UCHAR i;
+
+ for (i = 0; i < Tab->BssNr; i++)
{
- for (j = 0; j < MsgNr; j++)
+ //
+ // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
+ // We should distinguish this case.
+ //
+ if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
+ ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
+ MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid))
{
- S->TransFunc[i * MsgNr + j] = DefFunc;
+ return i;
}
}
-
- // set the starting state
- S->CurrState = InitState;
+ return (ULONG)BSS_NOT_FOUND;
}
-/*! \brief This function fills in the function pointer into the cell in the state machine
- * \param *S pointer to the state machine
- * \param St state
- * \param Msg incoming message
- * \param f the function to be executed when (state, message) combination occurs at the state machine
- * \pre *S should be a legal pointer to the state machine, st, msg, should be all within the range, Base should be set in the initial state
- * \post
+ULONG BssSsidTableSearch(
+ IN BSS_TABLE *Tab,
+ IN PUCHAR pBssid,
+ IN PUCHAR pSsid,
+ IN UCHAR SsidLen,
+ IN UCHAR Channel)
+{
+ UCHAR i;
- IRQL = PASSIVE_LEVEL
+ for (i = 0; i < Tab->BssNr; i++)
+ {
+ //
+ // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
+ // We should distinguish this case.
+ //
+ if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
+ ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
+ MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid) &&
+ SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen))
+ {
+ return i;
+ }
+ }
+ return (ULONG)BSS_NOT_FOUND;
+}
- */
-VOID StateMachineSetAction(
- IN STATE_MACHINE *S,
- IN ULONG St,
- IN ULONG Msg,
- IN STATE_MACHINE_FUNC Func)
+ULONG BssTableSearchWithSSID(
+ IN BSS_TABLE *Tab,
+ IN PUCHAR Bssid,
+ IN PUCHAR pSsid,
+ IN UCHAR SsidLen,
+ IN UCHAR Channel)
{
- ULONG MsgIdx;
-
- MsgIdx = Msg - S->Base;
+ UCHAR i;
- if (St < S->NrState && MsgIdx < S->NrMsg)
+ for (i = 0; i < Tab->BssNr; i++)
{
- // boundary checking before setting the action
- S->TransFunc[St * S->NrMsg + MsgIdx] = Func;
+ if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
+ ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
+ MAC_ADDR_EQUAL(&(Tab->BssEntry[i].Bssid), Bssid) &&
+ (SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen) ||
+ (NdisEqualMemory(pSsid, ZeroSsid, SsidLen)) ||
+ (NdisEqualMemory(Tab->BssEntry[i].Ssid, ZeroSsid, Tab->BssEntry[i].SsidLen))))
+ {
+ return i;
+ }
}
+ return (ULONG)BSS_NOT_FOUND;
}
-/*! \brief This function does the state transition
- * \param *Adapter the NIC adapter pointer
- * \param *S the state machine
- * \param *Elem the message to be executed
- * \return None
- IRQL = DISPATCH_LEVEL
+ULONG BssSsidTableSearchBySSID(
+ IN BSS_TABLE *Tab,
+ IN PUCHAR pSsid,
+ IN UCHAR SsidLen)
+{
+ UCHAR i;
- */
-VOID StateMachinePerformAction(
- IN PRTMP_ADAPTER pAd,
- IN STATE_MACHINE *S,
- IN MLME_QUEUE_ELEM *Elem)
+ for (i = 0; i < Tab->BssNr; i++)
+ {
+ if (SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen))
+ {
+ return i;
+ }
+ }
+ return (ULONG)BSS_NOT_FOUND;
+}
+
+
+// IRQL = DISPATCH_LEVEL
+VOID BssTableDeleteEntry(
+ IN OUT BSS_TABLE *Tab,
+ IN PUCHAR pBssid,
+ IN UCHAR Channel)
{
- (*(S->TransFunc[S->CurrState * S->NrMsg + Elem->MsgType - S->Base]))(pAd, Elem);
+ UCHAR i, j;
+
+ for (i = 0; i < Tab->BssNr; i++)
+ {
+ if ((Tab->BssEntry[i].Channel == Channel) &&
+ (MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid)))
+ {
+ for (j = i; j < Tab->BssNr - 1; j++)
+ {
+ NdisMoveMemory(&(Tab->BssEntry[j]), &(Tab->BssEntry[j + 1]), sizeof(BSS_ENTRY));
+ }
+ NdisZeroMemory(&(Tab->BssEntry[Tab->BssNr - 1]), sizeof(BSS_ENTRY));
+ Tab->BssNr -= 1;
+ return;
+ }
+ }
}
/*
- ==========================================================================
- Description:
- The drop function, when machine executes this, the message is simply
- ignored. This function does nothing, the message is freed in
- StateMachinePerformAction()
- ==========================================================================
- */
-VOID Drop(
- IN PRTMP_ADAPTER pAd,
- IN MLME_QUEUE_ELEM *Elem)
+ ========================================================================
+ Routine Description:
+ Delete the Originator Entry in BAtable. Or decrease numAs Originator by 1 if needed.
+
+ Arguments:
+ // IRQL = DISPATCH_LEVEL
+ ========================================================================
+*/
+VOID BATableDeleteORIEntry(
+ IN OUT PRTMP_ADAPTER pAd,
+ IN BA_ORI_ENTRY *pBAORIEntry)
{
-}
-// ===========================================================================================
-// lfsr.c
-// ===========================================================================================
+ if (pBAORIEntry->ORI_BA_Status != Originator_NONE)
+ {
+ NdisAcquireSpinLock(&pAd->BATabLock);
+ if (pBAORIEntry->ORI_BA_Status == Originator_Done)
+ {
+ pAd->BATable.numAsOriginator -= 1;
+ DBGPRINT(RT_DEBUG_TRACE, ("BATableDeleteORIEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient));
+ // Erase Bitmap flag.
+ }
+ pAd->MacTab.Content[pBAORIEntry->Wcid].TXBAbitmap &= (~(1<<(pBAORIEntry->TID) )); // If STA mode, erase flag here
+ pAd->MacTab.Content[pBAORIEntry->Wcid].BAOriWcidArray[pBAORIEntry->TID] = 0; // If STA mode, erase flag here
+ pBAORIEntry->ORI_BA_Status = Originator_NONE;
+ pBAORIEntry->Token = 1;
+ // Not clear Sequence here.
+ NdisReleaseSpinLock(&pAd->BATabLock);
+ }
+}
-/*
- ==========================================================================
- Description:
+/*! \brief
+ * \param
+ * \return
+ * \pre
+ * \post
- IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
- ==========================================================================
*/
-VOID LfsrInit(
+VOID BssEntrySet(
IN PRTMP_ADAPTER pAd,
- IN ULONG Seed)
+ OUT BSS_ENTRY *pBss,
+ IN PUCHAR pBssid,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen,
+ IN UCHAR BssType,
+ IN USHORT BeaconPeriod,
+ IN PCF_PARM pCfParm,
+ IN USHORT AtimWin,
+ IN USHORT CapabilityInfo,
+ IN UCHAR SupRate[],
+ IN UCHAR SupRateLen,
+ IN UCHAR ExtRate[],
+ IN UCHAR ExtRateLen,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
+ IN UCHAR HtCapabilityLen,
+ IN UCHAR AddHtInfoLen,
+ IN UCHAR NewExtChanOffset,
+ IN UCHAR Channel,
+ IN CHAR Rssi,
+ IN LARGE_INTEGER TimeStamp,
+ IN UCHAR CkipFlag,
+ IN PEDCA_PARM pEdcaParm,
+ IN PQOS_CAPABILITY_PARM pQosCapability,
+ IN PQBSS_LOAD_PARM pQbssLoad,
+ IN USHORT LengthVIE,
+ IN PNDIS_802_11_VARIABLE_IEs pVIE)
{
- if (Seed == 0)
- pAd->Mlme.ShiftReg = 1;
+ COPY_MAC_ADDR(pBss->Bssid, pBssid);
+ // Default Hidden SSID to be TRUE, it will be turned to FALSE after coping SSID
+ pBss->Hidden = 1;
+ if (SsidLen > 0)
+ {
+ // For hidden SSID AP, it might send beacon with SSID len equal to 0
+ // Or send beacon /probe response with SSID len matching real SSID length,
+ // but SSID is all zero. such as "00-00-00-00" with length 4.
+ // We have to prevent this case overwrite correct table
+ if (NdisEqualMemory(Ssid, ZeroSsid, SsidLen) == 0)
+ {
+ NdisZeroMemory(pBss->Ssid, MAX_LEN_OF_SSID);
+ NdisMoveMemory(pBss->Ssid, Ssid, SsidLen);
+ pBss->SsidLen = SsidLen;
+ pBss->Hidden = 0;
+ }
+ }
else
- pAd->Mlme.ShiftReg = Seed;
-}
+ pBss->SsidLen = 0;
+ pBss->BssType = BssType;
+ pBss->BeaconPeriod = BeaconPeriod;
+ if (BssType == BSS_INFRA)
+ {
+ if (pCfParm->bValid)
+ {
+ pBss->CfpCount = pCfParm->CfpCount;
+ pBss->CfpPeriod = pCfParm->CfpPeriod;
+ pBss->CfpMaxDuration = pCfParm->CfpMaxDuration;
+ pBss->CfpDurRemaining = pCfParm->CfpDurRemaining;
+ }
+ }
+ else
+ {
+ pBss->AtimWin = AtimWin;
+ }
-/*
- ==========================================================================
- Description:
- ==========================================================================
- */
-UCHAR RandomByte(
- IN PRTMP_ADAPTER pAd)
-{
- ULONG i;
- UCHAR R, Result;
+ pBss->CapabilityInfo = CapabilityInfo;
+ // The privacy bit indicate security is ON, it maight be WEP, TKIP or AES
+ // Combine with AuthMode, they will decide the connection methods.
+ pBss->Privacy = CAP_IS_PRIVACY_ON(pBss->CapabilityInfo);
+ ASSERT(SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
+ if (SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES)
+ NdisMoveMemory(pBss->SupRate, SupRate, SupRateLen);
+ else
+ NdisMoveMemory(pBss->SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES);
+ pBss->SupRateLen = SupRateLen;
+ ASSERT(ExtRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
+ NdisMoveMemory(pBss->ExtRate, ExtRate, ExtRateLen);
+ pBss->NewExtChanOffset = NewExtChanOffset;
+ pBss->ExtRateLen = ExtRateLen;
+ pBss->Channel = Channel;
+ pBss->CentralChannel = Channel;
+ pBss->Rssi = Rssi;
+ // Update CkipFlag. if not exists, the value is 0x0
+ pBss->CkipFlag = CkipFlag;
- R = 0;
+ // New for microsoft Fixed IEs
+ NdisMoveMemory(pBss->FixIEs.Timestamp, &TimeStamp, 8);
+ pBss->FixIEs.BeaconInterval = BeaconPeriod;
+ pBss->FixIEs.Capabilities = CapabilityInfo;
- if (pAd->Mlme.ShiftReg == 0)
- NdisGetSystemUpTime((ULONG *)&pAd->Mlme.ShiftReg);
+ // New for microsoft Variable IEs
+ if (LengthVIE != 0)
+ {
+ pBss->VarIELen = LengthVIE;
+ NdisMoveMemory(pBss->VarIEs, pVIE, pBss->VarIELen);
+ }
+ else
+ {
+ pBss->VarIELen = 0;
+ }
- for (i = 0; i < 8; i++)
+ pBss->AddHtInfoLen = 0;
+ pBss->HtCapabilityLen = 0;
+ if (HtCapabilityLen> 0)
{
- if (pAd->Mlme.ShiftReg & 0x00000001)
+ pBss->HtCapabilityLen = HtCapabilityLen;
+ NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen);
+ if (AddHtInfoLen > 0)
{
- pAd->Mlme.ShiftReg = ((pAd->Mlme.ShiftReg ^ LFSR_MASK) >> 1) | 0x80000000;
- Result = 1;
+ pBss->AddHtInfoLen = AddHtInfoLen;
+ NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
+
+ if ((pAddHtInfo->ControlChan > 2)&& (pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
+ {
+ pBss->CentralChannel = pAddHtInfo->ControlChan - 2;
}
- else
+ else if ((pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
{
- pAd->Mlme.ShiftReg = pAd->Mlme.ShiftReg >> 1;
- Result = 0;
+ pBss->CentralChannel = pAddHtInfo->ControlChan + 2;
+ }
}
- R = (R << 1) | Result;
}
- return R;
-}
+ BssCipherParse(pBss);
-VOID AsicUpdateAutoFallBackTable(
- IN PRTMP_ADAPTER pAd,
- IN PUCHAR pRateTable)
-{
- UCHAR i;
- HT_FBK_CFG0_STRUC HtCfg0;
- HT_FBK_CFG1_STRUC HtCfg1;
- LG_FBK_CFG0_STRUC LgCfg0;
- LG_FBK_CFG1_STRUC LgCfg1;
- PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate;
-
- // set to initial value
- HtCfg0.word = 0x65432100;
- HtCfg1.word = 0xedcba988;
- LgCfg0.word = 0xedcba988;
- LgCfg1.word = 0x00002100;
-
- pNextTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1;
- for (i = 1; i < *((PUCHAR) pRateTable); i++)
- {
- pCurrTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1+i;
- switch (pCurrTxRate->Mode)
+ // new for QOS
+ if (pEdcaParm)
+ NdisMoveMemory(&pBss->EdcaParm, pEdcaParm, sizeof(EDCA_PARM));
+ else
+ pBss->EdcaParm.bValid = FALSE;
+ if (pQosCapability)
+ NdisMoveMemory(&pBss->QosCapability, pQosCapability, sizeof(QOS_CAPABILITY_PARM));
+ else
+ pBss->QosCapability.bValid = FALSE;
+ if (pQbssLoad)
+ NdisMoveMemory(&pBss->QbssLoad, pQbssLoad, sizeof(QBSS_LOAD_PARM));
+ else
+ pBss->QbssLoad.bValid = FALSE;
+
+ {
+ PEID_STRUCT pEid;
+ USHORT Length = 0;
+
+
+ NdisZeroMemory(&pBss->WpaIE.IE[0], MAX_CUSTOM_LEN);
+ NdisZeroMemory(&pBss->RsnIE.IE[0], MAX_CUSTOM_LEN);
+ pEid = (PEID_STRUCT) pVIE;
+ while ((Length + 2 + (USHORT)pEid->Len) <= LengthVIE)
+ {
+ switch(pEid->Eid)
{
- case 0: //CCK
- break;
- case 1: //OFDM
+ case IE_WPA:
+ if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
{
- switch(pCurrTxRate->CurrMCS)
+ if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
{
- case 0:
- LgCfg0.field.OFDMMCS0FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
- break;
- case 1:
- LgCfg0.field.OFDMMCS1FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
- break;
- case 2:
- LgCfg0.field.OFDMMCS2FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
- break;
- case 3:
- LgCfg0.field.OFDMMCS3FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
- break;
- case 4:
- LgCfg0.field.OFDMMCS4FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
- break;
- case 5:
- LgCfg0.field.OFDMMCS5FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
- break;
- case 6:
- LgCfg0.field.OFDMMCS6FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
- break;
- case 7:
- LgCfg0.field.OFDMMCS7FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+ pBss->WpaIE.IELen = 0;
break;
}
+ pBss->WpaIE.IELen = pEid->Len + 2;
+ NdisMoveMemory(pBss->WpaIE.IE, pEid, pBss->WpaIE.IELen);
}
break;
- case 2: //HT-MIX
- case 3: //HT-GF
- {
- if ((pNextTxRate->Mode >= MODE_HTMIX) && (pCurrTxRate->CurrMCS != pNextTxRate->CurrMCS))
+ case IE_RSN:
+ if (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
{
- switch(pCurrTxRate->CurrMCS)
+ if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
{
- case 0:
- HtCfg0.field.HTMCS0FBK = pNextTxRate->CurrMCS;
- break;
- case 1:
- HtCfg0.field.HTMCS1FBK = pNextTxRate->CurrMCS;
- break;
- case 2:
- HtCfg0.field.HTMCS2FBK = pNextTxRate->CurrMCS;
- break;
- case 3:
- HtCfg0.field.HTMCS3FBK = pNextTxRate->CurrMCS;
- break;
- case 4:
- HtCfg0.field.HTMCS4FBK = pNextTxRate->CurrMCS;
- break;
- case 5:
- HtCfg0.field.HTMCS5FBK = pNextTxRate->CurrMCS;
- break;
- case 6:
- HtCfg0.field.HTMCS6FBK = pNextTxRate->CurrMCS;
- break;
- case 7:
- HtCfg0.field.HTMCS7FBK = pNextTxRate->CurrMCS;
- break;
- case 8:
- HtCfg1.field.HTMCS8FBK = pNextTxRate->CurrMCS;
- break;
- case 9:
- HtCfg1.field.HTMCS9FBK = pNextTxRate->CurrMCS;
- break;
- case 10:
- HtCfg1.field.HTMCS10FBK = pNextTxRate->CurrMCS;
- break;
- case 11:
- HtCfg1.field.HTMCS11FBK = pNextTxRate->CurrMCS;
- break;
- case 12:
- HtCfg1.field.HTMCS12FBK = pNextTxRate->CurrMCS;
- break;
- case 13:
- HtCfg1.field.HTMCS13FBK = pNextTxRate->CurrMCS;
- break;
- case 14:
- HtCfg1.field.HTMCS14FBK = pNextTxRate->CurrMCS;
- break;
- case 15:
- HtCfg1.field.HTMCS15FBK = pNextTxRate->CurrMCS;
+ pBss->RsnIE.IELen = 0;
break;
- default:
- DBGPRINT(RT_DEBUG_ERROR, ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n", pCurrTxRate->CurrMCS));
- }
}
+ pBss->RsnIE.IELen = pEid->Len + 2;
+ NdisMoveMemory(pBss->RsnIE.IE, pEid, pBss->RsnIE.IELen);
}
break;
}
-
- pNextTxRate = pCurrTxRate;
+ Length = Length + 2 + (USHORT)pEid->Len; // Eid[1] + Len[1]+ content[Len]
+ pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
+ }
}
-
- RTMP_IO_WRITE32(pAd, HT_FBK_CFG0, HtCfg0.word);
- RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, HtCfg1.word);
- RTMP_IO_WRITE32(pAd, LG_FBK_CFG0, LgCfg0.word);
- RTMP_IO_WRITE32(pAd, LG_FBK_CFG1, LgCfg1.word);
}
-/*
- ========================================================================
+/*!
+ * \brief insert an entry into the bss table
+ * \param p_tab The BSS table
+ * \param Bssid BSSID
+ * \param ssid SSID
+ * \param ssid_len Length of SSID
+ * \param bss_type
+ * \param beacon_period
+ * \param timestamp
+ * \param p_cf
+ * \param atim_win
+ * \param cap
+ * \param rates
+ * \param rates_len
+ * \param channel_idx
+ * \return none
+ * \pre
+ * \post
+ * \note If SSID is identical, the old entry will be replaced by the new one
- Routine Description:
- Set MAC register value according operation mode.
- OperationMode AND bNonGFExist are for MM and GF Proteciton.
- If MM or GF mask is not set, those passing argument doesn't not take effect.
-
- Operation mode meaning:
- = 0 : Pure HT, no preotection.
- = 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS.
- = 0x10: No Transmission in 40M is protected.
- = 0x11: Transmission in both 40M and 20M shall be protected
- if (bNonGFExist)
- we should choose not to use GF. But still set correct ASIC registers.
- ========================================================================
-*/
-VOID AsicUpdateProtect(
+ IRQL = DISPATCH_LEVEL
+
+ */
+ULONG BssTableSetEntry(
IN PRTMP_ADAPTER pAd,
- IN USHORT OperationMode,
- IN UCHAR SetMask,
- IN BOOLEAN bDisableBGProtect,
- IN BOOLEAN bNonGFExist)
+ OUT BSS_TABLE *Tab,
+ IN PUCHAR pBssid,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen,
+ IN UCHAR BssType,
+ IN USHORT BeaconPeriod,
+ IN CF_PARM *CfParm,
+ IN USHORT AtimWin,
+ IN USHORT CapabilityInfo,
+ IN UCHAR SupRate[],
+ IN UCHAR SupRateLen,
+ IN UCHAR ExtRate[],
+ IN UCHAR ExtRateLen,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
+ IN UCHAR HtCapabilityLen,
+ IN UCHAR AddHtInfoLen,
+ IN UCHAR NewExtChanOffset,
+ IN UCHAR ChannelNo,
+ IN CHAR Rssi,
+ IN LARGE_INTEGER TimeStamp,
+ IN UCHAR CkipFlag,
+ IN PEDCA_PARM pEdcaParm,
+ IN PQOS_CAPABILITY_PARM pQosCapability,
+ IN PQBSS_LOAD_PARM pQbssLoad,
+ IN USHORT LengthVIE,
+ IN PNDIS_802_11_VARIABLE_IEs pVIE)
{
- PROT_CFG_STRUC ProtCfg, ProtCfg4;
- UINT32 Protect[6];
- USHORT offset;
- UCHAR i;
- UINT32 MacReg = 0;
-
- if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8))
- {
- return;
- }
+ ULONG Idx;
- if (pAd->BATable.numAsOriginator)
+ Idx = BssTableSearchWithSSID(Tab, pBssid, (UCHAR *)Ssid, SsidLen, ChannelNo);
+ if (Idx == BSS_NOT_FOUND)
{
- //
- // enable the RTS/CTS to avoid channel collision
- //
- SetMask = ALLN_SETPROTECT;
- OperationMode = 8;
- }
-
- // Config ASIC RTS threshold register
- RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
- MacReg &= 0xFF0000FF;
-
- // If the user want disable RtsThreshold and enable Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096
- if ((
- (pAd->CommonCfg.BACapability.field.AmsduEnable) ||
- (pAd->CommonCfg.bAggregationCapable == TRUE))
- && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD)
- {
- MacReg |= (0x1000 << 8);
- }
- else
- {
- MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
- }
-
- RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
-
- // Initial common protection settings
- RTMPZeroMemory(Protect, sizeof(Protect));
- ProtCfg4.word = 0;
- ProtCfg.word = 0;
- ProtCfg.field.TxopAllowGF40 = 1;
- ProtCfg.field.TxopAllowGF20 = 1;
- ProtCfg.field.TxopAllowMM40 = 1;
- ProtCfg.field.TxopAllowMM20 = 1;
- ProtCfg.field.TxopAllowOfdm = 1;
- ProtCfg.field.TxopAllowCck = 1;
- ProtCfg.field.RTSThEn = 1;
- ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
-
- // update PHY mode and rate
- if (pAd->CommonCfg.Channel > 14)
- ProtCfg.field.ProtectRate = 0x4000;
- ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate;
-
- // Handle legacy(B/G) protection
- if (bDisableBGProtect)
- {
- //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
- ProtCfg.field.ProtectCtrl = 0;
- Protect[0] = ProtCfg.word;
- Protect[1] = ProtCfg.word;
- }
- else
+ if (Tab->BssNr >= MAX_LEN_OF_BSS_TABLE)
+ {
+ //
+ // It may happen when BSS Table was full.
+ // The desired AP will not be added into BSS Table
+ // In this case, if we found the desired AP then overwrite BSS Table.
+ //
+ if(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
{
- //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
- ProtCfg.field.ProtectCtrl = 0; // CCK do not need to be protected
- Protect[0] = ProtCfg.word;
- ProtCfg.field.ProtectCtrl = ASIC_CTS; // OFDM needs using CCK to protect
- Protect[1] = ProtCfg.word;
- }
-
- // Decide HT frame protection.
- if ((SetMask & ALLN_SETPROTECT) != 0)
+ if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, pBssid) ||
+ SSID_EQUAL(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Ssid, SsidLen))
{
- switch(OperationMode)
- {
- case 0x0:
- // NO PROTECT
- // 1.All STAs in the BSS are 20/40 MHz HT
- // 2. in ai 20/40MHz BSS
- // 3. all STAs are 20MHz in a 20MHz BSS
- // Pure HT. no protection.
-
- // MM20_PROT_CFG
- // Reserved (31:27)
- // PROT_TXOP(25:20) -- 010111
- // PROT_NAV(19:18) -- 01 (Short NAV protection)
- // PROT_CTRL(17:16) -- 00 (None)
- // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
- Protect[2] = 0x01744004;
-
- // MM40_PROT_CFG
- // Reserved (31:27)
- // PROT_TXOP(25:20) -- 111111
- // PROT_NAV(19:18) -- 01 (Short NAV protection)
- // PROT_CTRL(17:16) -- 00 (None)
- // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
- Protect[3] = 0x03f44084;
-
- // CF20_PROT_CFG
- // Reserved (31:27)
- // PROT_TXOP(25:20) -- 010111
- // PROT_NAV(19:18) -- 01 (Short NAV protection)
- // PROT_CTRL(17:16) -- 00 (None)
- // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
- Protect[4] = 0x01744004;
-
- // CF40_PROT_CFG
- // Reserved (31:27)
- // PROT_TXOP(25:20) -- 111111
- // PROT_NAV(19:18) -- 01 (Short NAV protection)
- // PROT_CTRL(17:16) -- 00 (None)
- // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
- Protect[5] = 0x03f44084;
-
- if (bNonGFExist)
- {
- // PROT_NAV(19:18) -- 01 (Short NAV protectiion)
- // PROT_CTRL(17:16) -- 01 (RTS/CTS)
- Protect[4] = 0x01754004;
- Protect[5] = 0x03f54084;
- }
- pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
- break;
-
- case 1:
- // This is "HT non-member protection mode."
- // If there may be non-HT STAs my BSS
- ProtCfg.word = 0x01744004; // PROT_CTRL(17:16) : 0 (None)
- ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
- if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
- {
- ProtCfg.word = 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
- ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083;
+ Idx = Tab->BssOverlapNr;
+ BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
+ CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
+ NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
+ Tab->BssOverlapNr = (Tab->BssOverlapNr++) % MAX_LEN_OF_BSS_TABLE;
}
- //Assign Protection method for 20&40 MHz packets
- ProtCfg.field.ProtectCtrl = ASIC_RTS;
- ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
- ProtCfg4.field.ProtectCtrl = ASIC_RTS;
- ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
- Protect[2] = ProtCfg.word;
- Protect[3] = ProtCfg4.word;
- Protect[4] = ProtCfg.word;
- Protect[5] = ProtCfg4.word;
- pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
- break;
-
- case 2:
- // If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets
- ProtCfg.word = 0x01744004; // PROT_CTRL(17:16) : 0 (None)
- ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
-
- //Assign Protection method for 40MHz packets
- ProtCfg4.field.ProtectCtrl = ASIC_RTS;
- ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
- Protect[2] = ProtCfg.word;
- Protect[3] = ProtCfg4.word;
- if (bNonGFExist)
- {
- ProtCfg.field.ProtectCtrl = ASIC_RTS;
- ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+ return Idx;
}
- Protect[4] = ProtCfg.word;
- Protect[5] = ProtCfg4.word;
-
- pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
- break;
-
- case 3:
- // HT mixed mode. PROTECT ALL!
- // Assign Rate
- ProtCfg.word = 0x01744004; //duplicaet legacy 24M. BW set 1.
- ProtCfg4.word = 0x03f44084;
- // both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the
- if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
+ else
{
- ProtCfg.word = 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
- ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083
+ return BSS_NOT_FOUND;
}
- //Assign Protection method for 20&40 MHz packets
- ProtCfg.field.ProtectCtrl = ASIC_RTS;
- ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
- ProtCfg4.field.ProtectCtrl = ASIC_RTS;
- ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
- Protect[2] = ProtCfg.word;
- Protect[3] = ProtCfg4.word;
- Protect[4] = ProtCfg.word;
- Protect[5] = ProtCfg4.word;
- pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
- break;
-
- case 8:
- // Special on for Atheros problem n chip.
- Protect[2] = 0x01754004;
- Protect[3] = 0x03f54084;
- Protect[4] = 0x01754004;
- Protect[5] = 0x03f54084;
- pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
- break;
}
+ Idx = Tab->BssNr;
+ BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
+ CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
+ NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
+ Tab->BssNr++;
}
-
- offset = CCK_PROT_CFG;
- for (i = 0;i < 6;i++)
+ else
{
- if ((SetMask & (1<< i)))
+ /* avoid Hidden SSID form beacon to overwirite correct SSID from probe response */
+ if ((SSID_EQUAL(Ssid, SsidLen, Tab->BssEntry[Idx].Ssid, Tab->BssEntry[Idx].SsidLen)) ||
+ (NdisEqualMemory(Tab->BssEntry[Idx].Ssid, ZeroSsid, Tab->BssEntry[Idx].SsidLen)))
{
- RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]);
+ BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod,CfParm, AtimWin,
+ CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
+ NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
}
}
-}
-#ifdef RT2870
-/*
- ==========================================================================
- Description:
+ return Idx;
+}
- Load RF normal operation-mode setup
- ==========================================================================
- */
-VOID RT30xxLoadRFNormalModeSetup(
- IN PRTMP_ADAPTER pAd)
+// IRQL = DISPATCH_LEVEL
+VOID BssTableSsidSort(
+ IN PRTMP_ADAPTER pAd,
+ OUT BSS_TABLE *OutTab,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen)
{
- UCHAR RFValue;
-
- // RX0_PD & TX0_PD, RF R1 register Bit 2 & Bit 3 to 0 and RF_BLOCK_en,RX1_PD & TX1_PD, Bit0, Bit 4 & Bit5 to 1
- RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
- RFValue = (RFValue & (~0x0C)) | 0x31;
- RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
-
- // TX_LO2_en, RF R15 register Bit 3 to 0
- RT30xxReadRFRegister(pAd, RF_R15, &RFValue);
- RFValue &= (~0x08);
- RT30xxWriteRFRegister(pAd, RF_R15, RFValue);
-
- // TX_LO1_en, RF R17 register Bit 3 to 0
- RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
- RFValue &= (~0x08);
- // to fix rx long range issue
- if (((pAd->MACVersion & 0xffff) >= 0x0211) && (pAd->NicConfig2.field.ExternalLNAForG == 0))
- {
- RFValue |= 0x20;
- }
- RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
-
- // RX_LO1_en, RF R20 register Bit 3 to 0
- RT30xxReadRFRegister(pAd, RF_R20, &RFValue);
- RFValue &= (~0x08);
- RT30xxWriteRFRegister(pAd, RF_R20, RFValue);
-
- // RX_LO2_en, RF R21 register Bit 3 to 0
- RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
- RFValue &= (~0x08);
- RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
-
- // LDORF_VC, RF R27 register Bit 2 to 0
- RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
- if ((pAd->MACVersion & 0xffff) < 0x0211)
- RFValue = (RFValue & (~0x77)) | 0x3;
- else
- RFValue = (RFValue & (~0x77));
- RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
- /* end johnli */
-}
-
-/*
- ==========================================================================
- Description:
+ INT i;
+ BssTableInit(OutTab);
- Load RF sleep-mode setup
+ for (i = 0; i < pAd->ScanTab.BssNr; i++)
+ {
+ BSS_ENTRY *pInBss = &pAd->ScanTab.BssEntry[i];
+ BOOLEAN bIsHiddenApIncluded = FALSE;
- ==========================================================================
- */
-VOID RT30xxLoadRFSleepModeSetup(
- IN PRTMP_ADAPTER pAd)
+ if (((pAd->CommonCfg.bIEEE80211H == 1) &&
+ (pAd->MlmeAux.Channel > 14) &&
+ RadarChannelCheck(pAd, pInBss->Channel))
+ )
{
- UCHAR RFValue;
- UINT32 MACValue;
-
- // RF_BLOCK_en. RF R1 register Bit 0 to 0
- RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
- RFValue &= (~0x01);
- RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
-
- // VCO_IC, RF R7 register Bit 4 & Bit 5 to 0
- RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
- RFValue &= (~0x30);
- RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
-
- // Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 0
- RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
- RFValue &= (~0x0E);
- RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
-
- // RX_CTB_en, RF R21 register Bit 7 to 0
- RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
- RFValue &= (~0x80);
- RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
-
- // LDORF_VC, RF R27 register Bit 0, Bit 1 & Bit 2 to 1
- RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
- RFValue |= 0x77;
- RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
-
- RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
- MACValue |= 0x1D000000;
- RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
+ if (pInBss->Hidden)
+ bIsHiddenApIncluded = TRUE;
}
-/*
- ==========================================================================
- Description:
+ if ((pInBss->BssType == pAd->StaCfg.BssType) &&
+ (SSID_EQUAL(Ssid, SsidLen, pInBss->Ssid, pInBss->SsidLen) || bIsHiddenApIncluded))
+ {
+ BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
- Reverse RF sleep-mode setup
- ==========================================================================
- */
-VOID RT30xxReverseRFSleepModeSetup(
- IN PRTMP_ADAPTER pAd)
-{
- UCHAR RFValue;
- UINT32 MACValue;
-
- // RF_BLOCK_en, RF R1 register Bit 0 to 1
- RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
- RFValue |= 0x01;
- RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
-
- // VCO_IC, RF R7 register Bit 4 & Bit 5 to 1
- RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
- RFValue |= 0x30;
- RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
-
- // Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 1
- RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
- RFValue |= 0x0E;
- RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
-
- // RX_CTB_en, RF R21 register Bit 7 to 1
- RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
- RFValue |= 0x80;
- RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
-
- // LDORF_VC, RF R27 register Bit 2 to 0
- RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
- if ((pAd->MACVersion & 0xffff) < 0x0211)
- RFValue = (RFValue & (~0x77)) | 0x3;
- else
- RFValue = (RFValue & (~0x77));
- RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
- // RT3071 version E has fixed this issue
- if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211))
- {
- // patch tx EVM issue temporarily
- RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
- MACValue = ((MACValue & 0xE0FFFFFF) | 0x0D000000);
- RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
+ // 2.4G/5G N only mode
+ if ((pInBss->HtCapabilityLen == 0) &&
+ ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
+ continue;
}
- else
+#ifdef RT2860
+ if ((pAd->CommonCfg.PhyMode == PHY_11GN_MIXED) &&
+ ((pInBss->SupRateLen + pInBss->ExtRateLen) < 12))
{
- RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
- MACValue = ((MACValue & 0xE0FFFFFF) | 0x01000000);
- RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
+ DBGPRINT(RT_DEBUG_TRACE,("STA is in GN-only Mode, this AP is in B mode.\n"));
+ continue;
}
-}
-#endif
+#endif // RT2860 //
+ // New for WPA2
+ // Check the Authmode first
+ if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ {
+ // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
+ if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
+ // None matched
+ continue;
-/*
- ==========================================================================
- Description:
+ // Check cipher suite, AP must have more secured cipher than station setting
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
+ {
+ // If it's not mixed mode, we should only let BSS pass with the same encryption
+ if (pInBss->WPA.bMixMode == FALSE)
+ if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
+ continue;
- IRQL = PASSIVE_LEVEL
- IRQL = DISPATCH_LEVEL
+ // check group cipher
+ if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) &&
+ (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP40Enabled) &&
+ (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP104Enabled))
+ continue;
- ==========================================================================
- */
-VOID AsicSwitchChannel(
- IN PRTMP_ADAPTER pAd,
- IN UCHAR Channel,
- IN BOOLEAN bScan)
-{
- ULONG R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0;
- CHAR TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; //Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER;
- UCHAR index;
- UINT32 Value = 0; //BbpReg, Value;
- RTMP_RF_REGS *RFRegTable;
-
- // Search Tx power value
- // We can't use ChannelList to search channel, since some central channl's txpowr doesn't list
- // in ChannelList, so use TxPower array instead.
+ // check pairwise cipher, skip if none matched
+ // If profile set to AES, let it pass without question.
+ // If profile set to TKIP, we must find one mateched
+ if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
+ (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
+ (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
+ continue;
+ }
+ else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+ {
+ // If it's not mixed mode, we should only let BSS pass with the same encryption
+ if (pInBss->WPA2.bMixMode == FALSE)
+ if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
+ continue;
+
+ // check group cipher
+ if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) &&
+ (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP40Enabled) &&
+ (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP104Enabled))
+ continue;
+
+ // check pairwise cipher, skip if none matched
+ // If profile set to AES, let it pass without question.
+ // If profile set to TKIP, we must find one mateched
+ if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
+ (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
+ (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
+ continue;
+ }
+ }
+ // Bss Type matched, SSID matched.
+ // We will check wepstatus for qualification Bss
+ else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n", pAd->StaCfg.WepStatus, pInBss->WepStatus));
+ //
+ // For the SESv2 case, we will not qualify WepStatus.
//
- for (index = 0; index < MAX_NUM_OF_CHANNELS; index++)
+ if (!pInBss->bSES)
+ continue;
+ }
+
+ // Since the AP is using hidden SSID, and we are trying to connect to ANY
+ // It definitely will fail. So, skip it.
+ // CCX also require not even try to connect it!!
+ if (SsidLen == 0)
+ continue;
+
+ // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
+ // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
+ if ((pInBss->CentralChannel != pInBss->Channel) &&
+ (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
{
- if (Channel == pAd->TxPower[index].Channel)
+ if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
{
- TxPwer = pAd->TxPower[index].Power;
- TxPwer2 = pAd->TxPower[index].Power2;
- break;
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
+ SetCommonHT(pAd);
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
+ }
+ else
+ {
+ if (pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BAND_WIDTH_20)
+ {
+ SetCommonHT(pAd);
+ }
}
}
- if (index == MAX_NUM_OF_CHANNELS)
- DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel));
+ // copy matching BSS from InTab to OutTab
+ NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
+
+ OutTab->BssNr++;
+ }
+ else if ((pInBss->BssType == pAd->StaCfg.BssType) && (SsidLen == 0))
+ {
+ BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
+
+
+ // 2.4G/5G N only mode
+ if ((pInBss->HtCapabilityLen == 0) &&
+ ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
+ continue;
+ }
+#ifdef RT2860
+ if ((pAd->CommonCfg.PhyMode == PHY_11GN_MIXED) &&
+ ((pInBss->SupRateLen + pInBss->ExtRateLen) < 12))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("STA is in GN-only Mode, this AP is in B mode.\n"));
+ continue;
+ }
+#endif // RT2860 //
+ // New for WPA2
+ // Check the Authmode first
+ if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ {
+ // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
+ if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
+ // None matched
+ continue;
+
+ // Check cipher suite, AP must have more secured cipher than station setting
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
+ {
+ // If it's not mixed mode, we should only let BSS pass with the same encryption
+ if (pInBss->WPA.bMixMode == FALSE)
+ if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
+ continue;
-#ifdef RT2870
- // The RF programming sequence is difference between 3xxx and 2xxx
- if ((IS_RT3070(pAd) || IS_RT3090(pAd)) && (
- (pAd->RfIcType == RFIC_3022) || (pAd->RfIcType == RFIC_3021) ||
- (pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020)))
- {
- /* modify by WY for Read RF Reg. error */
- UCHAR RFValue;
+ // check group cipher
+ if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
+ continue;
- for (index = 0; index < NUM_OF_3020_CHNL; index++)
- {
- if (Channel == FreqItems3020[index].Channel)
- {
- // Programming channel parameters
- RT30xxWriteRFRegister(pAd, RF_R02, FreqItems3020[index].N);
- RT30xxWriteRFRegister(pAd, RF_R03, FreqItems3020[index].K);
-
- RT30xxReadRFRegister(pAd, RF_R06, &RFValue);
- RFValue = (RFValue & 0xFC) | FreqItems3020[index].R;
- RT30xxWriteRFRegister(pAd, RF_R06, RFValue);
-
- // Set Tx0 Power
- RT30xxReadRFRegister(pAd, RF_R12, &RFValue);
- RFValue = (RFValue & 0xE0) | TxPwer;
- RT30xxWriteRFRegister(pAd, RF_R12, RFValue);
-
- // Set Tx1 Power
- RT30xxReadRFRegister(pAd, RF_R13, &RFValue);
- RFValue = (RFValue & 0xE0) | TxPwer2;
- RT30xxWriteRFRegister(pAd, RF_R13, RFValue);
-
- // Tx/Rx Stream setting
- RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
- //if (IS_RT3090(pAd))
- // RFValue |= 0x01; // Enable RF block.
- RFValue &= 0x03; //clear bit[7~2]
- if (pAd->Antenna.field.TxPath == 1)
- RFValue |= 0xA0;
- else if (pAd->Antenna.field.TxPath == 2)
- RFValue |= 0x80;
- if (pAd->Antenna.field.RxPath == 1)
- RFValue |= 0x50;
- else if (pAd->Antenna.field.RxPath == 2)
- RFValue |= 0x40;
- RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
-
- // Set RF offset
- RT30xxReadRFRegister(pAd, RF_R23, &RFValue);
- RFValue = (RFValue & 0x80) | pAd->RfFreqOffset;
- RT30xxWriteRFRegister(pAd, RF_R23, RFValue);
-
- // Set BW
- if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
+ // check pairwise cipher, skip if none matched
+ // If profile set to AES, let it pass without question.
+ // If profile set to TKIP, we must find one mateched
+ if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
+ (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
+ (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
+ continue;
+ }
+ else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
{
- RFValue = pAd->Mlme.CaliBW40RfR24;
- //DISABLE_11N_CHECK(pAd);
+ // If it's not mixed mode, we should only let BSS pass with the same encryption
+ if (pInBss->WPA2.bMixMode == FALSE)
+ if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
+ continue;
+
+ // check group cipher
+ if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
+ continue;
+
+ // check pairwise cipher, skip if none matched
+ // If profile set to AES, let it pass without question.
+ // If profile set to TKIP, we must find one mateched
+ if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
+ (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
+ (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
+ continue;
}
- else
+ }
+ // Bss Type matched, SSID matched.
+ // We will check wepstatus for qualification Bss
+ else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
+ continue;
+
+ // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
+ // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
+ if ((pInBss->CentralChannel != pInBss->Channel) &&
+ (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
+ {
+ if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
{
- RFValue = pAd->Mlme.CaliBW20RfR24;
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
+ SetCommonHT(pAd);
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
}
- RT30xxWriteRFRegister(pAd, RF_R24, RFValue);
- RT30xxWriteRFRegister(pAd, RF_R31, RFValue);
-
- // Enable RF tuning
- RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
- RFValue = RFValue | 0x1;
- RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
-
- // latch channel for future usage.
- pAd->LatchRfRegs.Channel = Channel;
-
- DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
- Channel,
- pAd->RfIcType,
- TxPwer,
- TxPwer2,
- pAd->Antenna.field.TxPath,
- FreqItems3020[index].N,
- FreqItems3020[index].K,
- FreqItems3020[index].R));
+ }
+
+ // copy matching BSS from InTab to OutTab
+ NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
+
+ OutTab->BssNr++;
+ }
+
+ if (OutTab->BssNr >= MAX_LEN_OF_BSS_TABLE)
break;
}
- }
- DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
- Channel,
- pAd->RfIcType,
- TxPwer,
- TxPwer2,
- pAd->Antenna.field.TxPath,
- FreqItems3020[index].N,
- FreqItems3020[index].K,
- FreqItems3020[index].R));
- }
- else
-#endif // RT2870 //
- {
- RFRegTable = RF2850RegTable;
+ BssTableSortByRssi(OutTab);
+}
- switch (pAd->RfIcType)
- {
- case RFIC_2820:
- case RFIC_2850:
- case RFIC_2720:
- case RFIC_2750:
- for (index = 0; index < NUM_OF_2850_CHNL; index++)
+// IRQL = DISPATCH_LEVEL
+VOID BssTableSortByRssi(
+ IN OUT BSS_TABLE *OutTab)
+{
+ INT i, j;
+ BSS_ENTRY TmpBss;
+
+ for (i = 0; i < OutTab->BssNr - 1; i++)
{
- if (Channel == RFRegTable[index].Channel)
+ for (j = i+1; j < OutTab->BssNr; j++)
{
- R2 = RFRegTable[index].R2;
- if (pAd->Antenna.field.TxPath == 1)
+ if (OutTab->BssEntry[j].Rssi > OutTab->BssEntry[i].Rssi)
{
- R2 |= 0x4000; // If TXpath is 1, bit 14 = 1;
+ NdisMoveMemory(&TmpBss, &OutTab->BssEntry[j], sizeof(BSS_ENTRY));
+ NdisMoveMemory(&OutTab->BssEntry[j], &OutTab->BssEntry[i], sizeof(BSS_ENTRY));
+ NdisMoveMemory(&OutTab->BssEntry[i], &TmpBss, sizeof(BSS_ENTRY));
}
-
- if (pAd->Antenna.field.RxPath == 2)
- {
- R2 |= 0x40; // write 1 to off Rxpath.
}
- else if (pAd->Antenna.field.RxPath == 1)
- {
- R2 |= 0x20040; // write 1 to off RxPath
}
+}
- if (Channel > 14)
- {
- // initialize R3, R4
- R3 = (RFRegTable[index].R3 & 0xffffc1ff);
- R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15);
- // 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB
- // R3
- if ((TxPwer >= -7) && (TxPwer < 0))
- {
- TxPwer = (7+TxPwer);
- TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
- R3 |= (TxPwer << 10);
- DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer=%d \n", TxPwer));
- }
- else
- {
- TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
- R3 |= (TxPwer << 10) | (1 << 9);
- }
+VOID BssCipherParse(
+ IN OUT PBSS_ENTRY pBss)
+{
+ PEID_STRUCT pEid;
+ PUCHAR pTmp;
+ PRSN_IE_HEADER_STRUCT pRsnHeader;
+ PCIPHER_SUITE_STRUCT pCipher;
+ PAKM_SUITE_STRUCT pAKM;
+ USHORT Count;
+ INT Length;
+ NDIS_802_11_ENCRYPTION_STATUS TmpCipher;
- // R4
- if ((TxPwer2 >= -7) && (TxPwer2 < 0))
- {
- TxPwer2 = (7+TxPwer2);
- TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
- R4 |= (TxPwer2 << 7);
- DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer2=%d \n", TxPwer2));
- }
- else
+ //
+ // WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame.
+ //
+ if (pBss->Privacy)
{
- TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
- R4 |= (TxPwer2 << 7) | (1 << 6);
- }
+ pBss->WepStatus = Ndis802_11WEPEnabled;
}
else
{
- R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); // set TX power0
- R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 <<6);// Set freq Offset & TxPwr1
- }
-
- // Based on BBP current mode before changing RF channel.
- if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
- {
- R4 |=0x200000;
+ pBss->WepStatus = Ndis802_11WEPDisabled;
}
+ // Set default to disable & open authentication before parsing variable IE
+ pBss->AuthMode = Ndis802_11AuthModeOpen;
+ pBss->AuthModeAux = Ndis802_11AuthModeOpen;
- // Update variables
- pAd->LatchRfRegs.Channel = Channel;
- pAd->LatchRfRegs.R1 = RFRegTable[index].R1;
- pAd->LatchRfRegs.R2 = R2;
- pAd->LatchRfRegs.R3 = R3;
- pAd->LatchRfRegs.R4 = R4;
-
- // Set RF value 1's set R3[bit2] = [0]
- RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
- RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
- RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
- RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
-
- RTMPusecDelay(200);
-
- // Set RF value 2's set R3[bit2] = [1]
- RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
- RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
- RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04));
- RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
-
- RTMPusecDelay(200);
-
- // Set RF value 3's set R3[bit2] = [0]
- RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
- RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
- RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
- RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
-
- break;
- }
- }
- break;
+ // Init WPA setting
+ pBss->WPA.PairCipher = Ndis802_11WEPDisabled;
+ pBss->WPA.PairCipherAux = Ndis802_11WEPDisabled;
+ pBss->WPA.GroupCipher = Ndis802_11WEPDisabled;
+ pBss->WPA.RsnCapability = 0;
+ pBss->WPA.bMixMode = FALSE;
- default:
- break;
- }
- }
+ // Init WPA2 setting
+ pBss->WPA2.PairCipher = Ndis802_11WEPDisabled;
+ pBss->WPA2.PairCipherAux = Ndis802_11WEPDisabled;
+ pBss->WPA2.GroupCipher = Ndis802_11WEPDisabled;
+ pBss->WPA2.RsnCapability = 0;
+ pBss->WPA2.bMixMode = FALSE;
- // Change BBP setting during siwtch from a->g, g->a
- if (Channel <= 14)
- {
- ULONG TxPinCfg = 0x00050F0A;//Gary 2007/08/09 0x050A0A
- RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
- RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
- RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
- RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);//(0x44 - GET_LNA_GAIN(pAd))); // According the Rory's suggestion to solve the middle range issue.
- //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
+ Length = (INT) pBss->VarIELen;
- // Rx High power VGA offset for LNA select
- if (pAd->NicConfig2.field.ExternalLNAForG)
+ while (Length > 0)
{
- RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
- RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
- }
- else
+ // Parse cipher suite base on WPA1 & WPA2, they should be parsed differently
+ pTmp = ((PUCHAR) pBss->VarIEs) + pBss->VarIELen - Length;
+ pEid = (PEID_STRUCT) pTmp;
+ switch (pEid->Eid)
{
- RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
- RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
- }
-
- // 5G band selection PIN, bit1 and bit2 are complement
- RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
- Value &= (~0x6);
- Value |= (0x04);
- RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
-
- // Turn off unused PA or LNA when only 1T or 1R
- if (pAd->Antenna.field.TxPath == 1)
+ case IE_WPA:
+ if (NdisEqualMemory(pEid->Octet, SES_OUI, 3) && (pEid->Len == 7))
{
- TxPinCfg &= 0xFFFFFFF3;
+ pBss->bSES = TRUE;
+ break;
}
- if (pAd->Antenna.field.RxPath == 1)
+ else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4) != 1)
{
- TxPinCfg &= 0xFFFFF3FF;
+ // if unsupported vendor specific IE
+ break;
}
+ // Skip OUI, version, and multicast suite
+ // This part should be improved in the future when AP supported multiple cipher suite.
+ // For now, it's OK since almost all APs have fixed cipher suite supported.
+ // pTmp = (PUCHAR) pEid->Octet;
+ pTmp += 11;
- RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
- }
- else
+ // Cipher Suite Selectors from Spec P802.11i/D3.2 P26.
+ // Value Meaning
+ // 0 None
+ // 1 WEP-40
+ // 2 Tkip
+ // 3 WRAP
+ // 4 AES
+ // 5 WEP-104
+ // Parse group cipher
+ switch (*pTmp)
{
- ULONG TxPinCfg = 0x00050F05;//Gary 2007/8/9 0x050505
-
- RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
- RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
- RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
- RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);//(0x44 - GET_LNA_GAIN(pAd))); // According the Rory's suggestion to solve the middle range issue.
- RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
-
- // Rx High power VGA offset for LNA select
- if (pAd->NicConfig2.field.ExternalLNAForA)
- {
- RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
- }
- else
- {
- RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
- }
+ case 1:
+ pBss->WPA.GroupCipher = Ndis802_11GroupWEP40Enabled;
+ break;
+ case 5:
+ pBss->WPA.GroupCipher = Ndis802_11GroupWEP104Enabled;
+ break;
+ case 2:
+ pBss->WPA.GroupCipher = Ndis802_11Encryption2Enabled;
+ break;
+ case 4:
+ pBss->WPA.GroupCipher = Ndis802_11Encryption3Enabled;
+ break;
+ default:
+ break;
+ }
+ // number of unicast suite
+ pTmp += 1;
- // 5G band selection PIN, bit1 and bit2 are complement
- RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
- Value &= (~0x6);
- Value |= (0x02);
- RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
+ // skip all unicast cipher suites
+ //Count = *(PUSHORT) pTmp;
+ Count = (pTmp[1]<<8) + pTmp[0];
+ pTmp += sizeof(USHORT);
- // Turn off unused PA or LNA when only 1T or 1R
- if (pAd->Antenna.field.TxPath == 1)
- {
- TxPinCfg &= 0xFFFFFFF3;
- }
- if (pAd->Antenna.field.RxPath == 1)
+ // Parsing all unicast cipher suite
+ while (Count > 0)
{
- TxPinCfg &= 0xFFFFF3FF;
- }
-
- RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
- }
-
- // R66 should be set according to Channel and use 20MHz when scanning
- //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd)));
- if (bScan)
- RTMPSetAGCInitValue(pAd, BW_20);
- else
- RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
-
- //
- // On 11A, We should delay and wait RF/BBP to be stable
- // and the appropriate time should be 1000 micro seconds
- // 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
- //
- RTMPusecDelay(1000);
-
- DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%lu, Pwr1=%lu, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
- Channel,
- pAd->RfIcType,
- (R3 & 0x00003e00) >> 9,
- (R4 & 0x000007c0) >> 6,
- pAd->Antenna.field.TxPath,
- pAd->LatchRfRegs.R1,
- pAd->LatchRfRegs.R2,
- pAd->LatchRfRegs.R3,
- pAd->LatchRfRegs.R4));
-}
-
-/*
- ==========================================================================
- Description:
- This function is required for 2421 only, and should not be used during
- site survey. It's only required after NIC decided to stay at a channel
- for a longer period.
- When this function is called, it's always after AsicSwitchChannel().
-
- IRQL = PASSIVE_LEVEL
- IRQL = DISPATCH_LEVEL
-
- ==========================================================================
- */
-VOID AsicLockChannel(
- IN PRTMP_ADAPTER pAd,
- IN UCHAR Channel)
-{
-}
-
-VOID AsicRfTuningExec(
- IN PVOID SystemSpecific1,
- IN PVOID FunctionContext,
- IN PVOID SystemSpecific2,
- IN PVOID SystemSpecific3)
-{
-}
-
-/*
- ==========================================================================
- Description:
- Gives CCK TX rate 2 more dB TX power.
- This routine works only in LINK UP in INFRASTRUCTURE mode.
-
- calculate desired Tx power in RF R3.Tx0~5, should consider -
- 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
- 1. TxPowerPercentage
- 2. auto calibration based on TSSI feedback
- 3. extra 2 db for CCK
- 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
-
- NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
- it should be called AFTER MlmeDynamicTxRatSwitching()
- ==========================================================================
- */
-VOID AsicAdjustTxPower(
- IN PRTMP_ADAPTER pAd)
-{
- INT i, j;
- CHAR DeltaPwr = 0;
- BOOLEAN bAutoTxAgc = FALSE;
- UCHAR TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
- UCHAR BbpR1 = 0, BbpR49 = 0, idx;
- PCHAR pTxAgcCompensate;
- ULONG TxPwr[5];
- CHAR Value;
-
-#ifdef RT2860
- if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
- || (pAd->bPCIclkOff == TRUE)
- || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)
- || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
- return;
-#endif
-
- if (pAd->CommonCfg.BBPCurrentBW == BW_40)
- {
- if (pAd->CommonCfg.CentralChannel > 14)
+ // Skip OUI
+ pTmp += 3;
+ TmpCipher = Ndis802_11WEPDisabled;
+ switch (*pTmp)
{
- TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
- TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
- TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
- TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
- TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
+ case 1:
+ case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
+ TmpCipher = Ndis802_11Encryption1Enabled;
+ break;
+ case 2:
+ TmpCipher = Ndis802_11Encryption2Enabled;
+ break;
+ case 4:
+ TmpCipher = Ndis802_11Encryption3Enabled;
+ break;
+ default:
+ break;
}
- else
+ if (TmpCipher > pBss->WPA.PairCipher)
{
- TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
- TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
- TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
- TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
- TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
- }
+ // Move the lower cipher suite to PairCipherAux
+ pBss->WPA.PairCipherAux = pBss->WPA.PairCipher;
+ pBss->WPA.PairCipher = TmpCipher;
}
- else
- {
- if (pAd->CommonCfg.Channel > 14)
- {
- TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
- TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
- TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
- TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
- TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
- }
- else
+ else
{
- TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
- TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
- TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
- TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
- TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
- }
+ pBss->WPA.PairCipherAux = TmpCipher;
+ }
+ pTmp++;
+ Count--;
}
- // TX power compensation for temperature variation based on TSSI. try every 4 second
- if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
- {
- if (pAd->CommonCfg.Channel <= 14)
+ // 4. get AKM suite counts
+ //Count = *(PUSHORT) pTmp;
+ Count = (pTmp[1]<<8) + pTmp[0];
+ pTmp += sizeof(USHORT);
+ pTmp += 3;
+
+ switch (*pTmp)
{
- /* bg channel */
- bAutoTxAgc = pAd->bAutoTxAgcG;
- TssiRef = pAd->TssiRefG;
- pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
- pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0];
- TxAgcStep = pAd->TxAgcStepG;
- pTxAgcCompensate = &pAd->TxAgcCompensateG;
- }
+ case 1:
+ // Set AP support WPA-enterprise mode
+ if (pBss->AuthMode == Ndis802_11AuthModeOpen)
+ pBss->AuthMode = Ndis802_11AuthModeWPA;
+ else
+ pBss->AuthModeAux = Ndis802_11AuthModeWPA;
+ break;
+ case 2:
+ // Set AP support WPA-PSK mode
+ if (pBss->AuthMode == Ndis802_11AuthModeOpen)
+ pBss->AuthMode = Ndis802_11AuthModeWPAPSK;
else
+ pBss->AuthModeAux = Ndis802_11AuthModeWPAPSK;
+ break;
+ default:
+ break;
+ }
+ pTmp += 1;
+
+ // Fixed for WPA-None
+ if (pBss->BssType == BSS_ADHOC)
{
- /* a channel */
- bAutoTxAgc = pAd->bAutoTxAgcA;
- TssiRef = pAd->TssiRefA;
- pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
- pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0];
- TxAgcStep = pAd->TxAgcStepA;
- pTxAgcCompensate = &pAd->TxAgcCompensateA;
+ pBss->AuthMode = Ndis802_11AuthModeWPANone;
+ pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
+ pBss->WepStatus = pBss->WPA.GroupCipher;
+ // Patched bugs for old driver
+ if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
+ pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
}
+ else
+ pBss->WepStatus = pBss->WPA.PairCipher;
- if (bAutoTxAgc)
- {
- /* BbpR1 is unsigned char */
- RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
+ // Check the Pair & Group, if different, turn on mixed mode flag
+ if (pBss->WPA.GroupCipher != pBss->WPA.PairCipher)
+ pBss->WPA.bMixMode = TRUE;
- /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
- /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */
- /* step value is defined in pAd->TxAgcStepG for tx power value */
+ break;
- /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */
- /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
- above value are examined in mass factory production */
- /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */
+ case IE_RSN:
+ pRsnHeader = (PRSN_IE_HEADER_STRUCT) pTmp;
- /* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */
- /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
- /* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */
+ // 0. Version must be 1
+ if (le2cpu16(pRsnHeader->Version) != 1)
+ break;
+ pTmp += sizeof(RSN_IE_HEADER_STRUCT);
- if (BbpR49 > pTssiMinusBoundary[1])
- {
- // Reading is larger than the reference value
- // check for how large we need to decrease the Tx power
- for (idx = 1; idx < 5; idx++)
- {
- if (BbpR49 <= pTssiMinusBoundary[idx]) // Found the range
+ // 1. Check group cipher
+ pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
+ if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
break;
- }
- // The index is the step we should decrease, idx = 0 means there is nothing to compensate
- *pTxAgcCompensate = -(TxAgcStep * (idx-1));
- DeltaPwr += (*pTxAgcCompensate);
- DBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
- BbpR49, TssiRef, TxAgcStep, idx-1));
- }
- else if (BbpR49 < pTssiPlusBoundary[1])
- {
- // Reading is smaller than the reference value
- // check for how large we need to increase the Tx power
- for (idx = 1; idx < 5; idx++)
+ // Parse group cipher
+ switch (pCipher->Type)
{
- if (BbpR49 >= pTssiPlusBoundary[idx]) // Found the range
+ case 1:
+ pBss->WPA2.GroupCipher = Ndis802_11GroupWEP40Enabled;
+ break;
+ case 5:
+ pBss->WPA2.GroupCipher = Ndis802_11GroupWEP104Enabled;
+ break;
+ case 2:
+ pBss->WPA2.GroupCipher = Ndis802_11Encryption2Enabled;
+ break;
+ case 4:
+ pBss->WPA2.GroupCipher = Ndis802_11Encryption3Enabled;
+ break;
+ default:
break;
}
- // The index is the step we should increase, idx = 0 means there is nothing to compensate
- *pTxAgcCompensate = TxAgcStep * (idx-1);
- DeltaPwr += (*pTxAgcCompensate);
- DBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
- BbpR49, TssiRef, TxAgcStep, idx-1));
- }
- else
- {
- *pTxAgcCompensate = 0;
- DBGPRINT(RT_DEBUG_TRACE, (" Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
- BbpR49, TssiRef, TxAgcStep, 0));
- }
- }
- }
- else
- {
- if (pAd->CommonCfg.Channel <= 14)
- {
- bAutoTxAgc = pAd->bAutoTxAgcG;
- pTxAgcCompensate = &pAd->TxAgcCompensateG;
- }
- else
- {
- bAutoTxAgc = pAd->bAutoTxAgcA;
- pTxAgcCompensate = &pAd->TxAgcCompensateA;
- }
-
- if (bAutoTxAgc)
- DeltaPwr += (*pTxAgcCompensate);
- }
+ // set to correct offset for next parsing
+ pTmp += sizeof(CIPHER_SUITE_STRUCT);
- RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1);
- BbpR1 &= 0xFC;
+ // 2. Get pairwise cipher counts
+ //Count = *(PUSHORT) pTmp;
+ Count = (pTmp[1]<<8) + pTmp[0];
+ pTmp += sizeof(USHORT);
- /* calculate delta power based on the percentage specified from UI */
- // E2PROM setting is calibrated for maximum TX power (i.e. 100%)
- // We lower TX power here according to the percentage specified from UI
- if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff) // AUTO TX POWER control
- ;
- else if (pAd->CommonCfg.TxPowerPercentage > 90) // 91 ~ 100% & AUTO, treat as 100% in terms of mW
- ;
- else if (pAd->CommonCfg.TxPowerPercentage > 60) // 61 ~ 90%, treat as 75% in terms of mW // DeltaPwr -= 1;
+ // 3. Get pairwise cipher
+ // Parsing all unicast cipher suite
+ while (Count > 0)
{
- DeltaPwr -= 1;
- }
- else if (pAd->CommonCfg.TxPowerPercentage > 30) // 31 ~ 60%, treat as 50% in terms of mW // DeltaPwr -= 3;
+ // Skip OUI
+ pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
+ TmpCipher = Ndis802_11WEPDisabled;
+ switch (pCipher->Type)
{
- DeltaPwr -= 3;
+ case 1:
+ case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
+ TmpCipher = Ndis802_11Encryption1Enabled;
+ break;
+ case 2:
+ TmpCipher = Ndis802_11Encryption2Enabled;
+ break;
+ case 4:
+ TmpCipher = Ndis802_11Encryption3Enabled;
+ break;
+ default:
+ break;
}
- else if (pAd->CommonCfg.TxPowerPercentage > 15) // 16 ~ 30%, treat as 25% in terms of mW // DeltaPwr -= 6;
+ if (TmpCipher > pBss->WPA2.PairCipher)
{
- BbpR1 |= 0x01;
+ // Move the lower cipher suite to PairCipherAux
+ pBss->WPA2.PairCipherAux = pBss->WPA2.PairCipher;
+ pBss->WPA2.PairCipher = TmpCipher;
}
- else if (pAd->CommonCfg.TxPowerPercentage > 9) // 10 ~ 15%, treat as 12.5% in terms of mW // DeltaPwr -= 9;
+ else
{
- BbpR1 |= 0x01;
- DeltaPwr -= 3;
+ pBss->WPA2.PairCipherAux = TmpCipher;
}
- else // 0 ~ 9 %, treat as MIN(~3%) in terms of mW // DeltaPwr -= 12;
- {
- BbpR1 |= 0x02;
+ pTmp += sizeof(CIPHER_SUITE_STRUCT);
+ Count--;
}
- RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
+ // 4. get AKM suite counts
+ //Count = *(PUSHORT) pTmp;
+ Count = (pTmp[1]<<8) + pTmp[0];
+ pTmp += sizeof(USHORT);
- /* reset different new tx power for different TX rate */
- for(i=0; i<5; i++)
- {
- if (TxPwr[i] != 0xffffffff)
- {
- for (j=0; j<8; j++)
+ // 5. Get AKM ciphers
+ // Parsing all AKM ciphers
+ while (Count > 0)
{
- Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */
+ pAKM = (PAKM_SUITE_STRUCT) pTmp;
+ if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
+ break;
- if ((Value + DeltaPwr) < 0)
- {
- Value = 0; /* min */
- }
- else if ((Value + DeltaPwr) > 0xF)
+ switch (pAKM->Type)
{
- Value = 0xF; /* max */
- }
+ case 1:
+ // Set AP support WPA-enterprise mode
+ if (pBss->AuthMode == Ndis802_11AuthModeOpen)
+ pBss->AuthMode = Ndis802_11AuthModeWPA2;
else
- {
- Value += DeltaPwr; /* temperature compensation */
+ pBss->AuthModeAux = Ndis802_11AuthModeWPA2;
+ break;
+ case 2:
+ // Set AP support WPA-PSK mode
+ if (pBss->AuthMode == Ndis802_11AuthModeOpen)
+ pBss->AuthMode = Ndis802_11AuthModeWPA2PSK;
+ else
+ pBss->AuthModeAux = Ndis802_11AuthModeWPA2PSK;
+ break;
+ default:
+ if (pBss->AuthMode == Ndis802_11AuthModeOpen)
+ pBss->AuthMode = Ndis802_11AuthModeMax;
+ else
+ pBss->AuthModeAux = Ndis802_11AuthModeMax;
+ break;
}
-
- /* fill new value to CSR offset */
- TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
+ pTmp += (Count * sizeof(AKM_SUITE_STRUCT));
+ Count--;
}
- /* write tx power value to CSR */
- /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M
- TX power for OFDM 6M/9M
- TX power for CCK5.5M/11M
- TX power for CCK1M/2M */
- /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
- RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]);
- }
+ // Fixed for WPA-None
+ if (pBss->BssType == BSS_ADHOC)
+ {
+ pBss->AuthMode = Ndis802_11AuthModeWPANone;
+ pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
+ pBss->WPA.PairCipherAux = pBss->WPA2.PairCipherAux;
+ pBss->WPA.GroupCipher = pBss->WPA2.GroupCipher;
+ pBss->WepStatus = pBss->WPA.GroupCipher;
+ // Patched bugs for old driver
+ if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
+ pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
}
+ pBss->WepStatus = pBss->WPA2.PairCipher;
-}
-
-/*
- ==========================================================================
- Description:
- put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup
- automatically. Instead, MCU will issue a TwakeUpInterrupt to host after
- the wakeup timer timeout. Driver has to issue a separate command to wake
- PHY up.
-
- IRQL = DISPATCH_LEVEL
-
- ==========================================================================
- */
-VOID AsicSleepThenAutoWakeup(
- IN PRTMP_ADAPTER pAd,
- IN USHORT TbttNumToNextWakeUp)
-{
- RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp);
-}
-
-/*
- ==========================================================================
- Description:
- AsicForceWakeup() is used whenever manual wakeup is required
- AsicForceSleep() should only be used when not in INFRA BSS. When
- in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead.
- ==========================================================================
- */
-VOID AsicForceSleep(
- IN PRTMP_ADAPTER pAd)
-{
-
-}
-
-/*
- ==========================================================================
- Description:
- AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup)
- expired.
-
- IRQL = PASSIVE_LEVEL
- IRQL = DISPATCH_LEVEL
- ==========================================================================
- */
-VOID AsicForceWakeup(
- IN PRTMP_ADAPTER pAd,
-#ifdef RT2860
- IN UCHAR Level)
-#endif
-#ifdef RT2870
- IN BOOLEAN bFromTx)
-#endif
-{
- DBGPRINT(RT_DEBUG_TRACE, ("--> AsicForceWakeup \n"));
-#ifdef RT2860
- RT28XX_STA_FORCE_WAKEUP(pAd, Level);
-#endif
-#ifdef RT2870
- RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx);
-#endif
-}
-
-/*
- ==========================================================================
- Description:
- Set My BSSID
-
- IRQL = DISPATCH_LEVEL
-
- ==========================================================================
- */
-VOID AsicSetBssid(
- IN PRTMP_ADAPTER pAd,
- IN PUCHAR pBssid)
-{
- ULONG Addr4;
- DBGPRINT(RT_DEBUG_TRACE, ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n",
- pBssid[0],pBssid[1],pBssid[2],pBssid[3], pBssid[4],pBssid[5]));
-
- Addr4 = (ULONG)(pBssid[0]) |
- (ULONG)(pBssid[1] << 8) |
- (ULONG)(pBssid[2] << 16) |
- (ULONG)(pBssid[3] << 24);
- RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
-
- Addr4 = 0;
- // always one BSSID in STA mode
- Addr4 = (ULONG)(pBssid[4]) | (ULONG)(pBssid[5] << 8);
-
- RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
-}
-
-VOID AsicSetMcastWC(
- IN PRTMP_ADAPTER pAd)
-{
- MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[MCAST_WCID];
- USHORT offset;
-
- pEntry->Sst = SST_ASSOC;
- pEntry->Aid = MCAST_WCID; // Softap supports 1 BSSID and use WCID=0 as multicast Wcid index
- pEntry->PsMode = PWR_ACTIVE;
- pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate;
- offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE;
-}
-
-/*
- ==========================================================================
- Description:
-
- IRQL = DISPATCH_LEVEL
-
- ==========================================================================
- */
-VOID AsicDelWcidTab(
- IN PRTMP_ADAPTER pAd,
- IN UCHAR Wcid)
-{
- ULONG Addr0 = 0x0, Addr1 = 0x0;
- ULONG offset;
-
- DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n",Wcid));
- offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE;
- RTMP_IO_WRITE32(pAd, offset, Addr0);
- offset += 4;
- RTMP_IO_WRITE32(pAd, offset, Addr1);
-}
-
-/*
- ==========================================================================
- Description:
-
- IRQL = DISPATCH_LEVEL
-
- ==========================================================================
- */
-VOID AsicEnableRDG(
- IN PRTMP_ADAPTER pAd)
-{
- TX_LINK_CFG_STRUC TxLinkCfg;
- UINT32 Data = 0;
-
- RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
- TxLinkCfg.field.TxRDGEn = 1;
- RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
-
- RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
- Data &= 0xFFFFFF00;
- Data |= 0x80;
- RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+ // 6. Get RSN capability
+ //pBss->WPA2.RsnCapability = *(PUSHORT) pTmp;
+ pBss->WPA2.RsnCapability = (pTmp[1]<<8) + pTmp[0];
+ pTmp += sizeof(USHORT);
- //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
-}
+ // Check the Pair & Group, if different, turn on mixed mode flag
+ if (pBss->WPA2.GroupCipher != pBss->WPA2.PairCipher)
+ pBss->WPA2.bMixMode = TRUE;
-/*
- ==========================================================================
- Description:
+ break;
+ default:
+ break;
+ }
+ Length -= (pEid->Len + 2);
+ }
+}
- IRQL = DISPATCH_LEVEL
+// ===========================================================================================
+// mac_table.c
+// ===========================================================================================
- ==========================================================================
+/*! \brief generates a random mac address value for IBSS BSSID
+ * \param Addr the bssid location
+ * \return none
+ * \pre
+ * \post
*/
-VOID AsicDisableRDG(
- IN PRTMP_ADAPTER pAd)
+VOID MacAddrRandomBssid(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pAddr)
{
- TX_LINK_CFG_STRUC TxLinkCfg;
- UINT32 Data = 0;
-
-
- RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
- TxLinkCfg.field.TxRDGEn = 0;
- RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
-
- RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+ INT i;
- Data &= 0xFFFFFF00;
- if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE)
- && (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE)
- )
+ for (i = 0; i < MAC_ADDR_LEN; i++)
{
- // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
- if (pAd->CommonCfg.bEnableTxBurst)
- Data |= 0x20;
+ pAddr[i] = RandomByte(pAd);
}
- RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+
+ pAddr[0] = (pAddr[0] & 0xfe) | 0x02; // the first 2 bits must be 01xxxxxxxx
}
-/*
- ==========================================================================
- Description:
+/*! \brief init the management mac frame header
+ * \param p_hdr mac header
+ * \param subtype subtype of the frame
+ * \param p_ds destination address, don't care if it is a broadcast address
+ * \return none
+ * \pre the station has the following information in the pAd->StaCfg
+ * - bssid
+ * - station address
+ * \post
+ * \note this function initializes the following field
IRQL = PASSIVE_LEVEL
IRQL = DISPATCH_LEVEL
- ==========================================================================
*/
-VOID AsicDisableSync(
- IN PRTMP_ADAPTER pAd)
+VOID MgtMacHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PHEADER_802_11 pHdr80211,
+ IN UCHAR SubType,
+ IN UCHAR ToDs,
+ IN PUCHAR pDA,
+ IN PUCHAR pBssid)
{
- BCN_TIME_CFG_STRUC csr;
-
- DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n"));
-
- // 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect
- // that NIC will never wakes up because TSF stops and no more
- // TBTT interrupts
- pAd->TbttTickCount = 0;
- RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
- csr.field.bBeaconGen = 0;
- csr.field.bTBTTEnable = 0;
- csr.field.TsfSyncMode = 0;
- csr.field.bTsfTicking = 0;
- RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
+ NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
+ pHdr80211->FC.Type = BTYPE_MGMT;
+ pHdr80211->FC.SubType = SubType;
+// if (SubType == SUBTYPE_ACK) // sample, no use, it will conflict with ACTION frame sub type
+// pHdr80211->FC.Type = BTYPE_CNTL;
+ pHdr80211->FC.ToDs = ToDs;
+ COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
+ COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
+ COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
}
-/*
- ==========================================================================
- Description:
+// ===========================================================================================
+// mem_mgmt.c
+// ===========================================================================================
+
+/*!***************************************************************************
+ * This routine build an outgoing frame, and fill all information specified
+ * in argument list to the frame body. The actual frame size is the summation
+ * of all arguments.
+ * input params:
+ * Buffer - pointer to a pre-allocated memory segment
+ * args - a list of <int arg_size, arg> pairs.
+ * NOTE NOTE NOTE!!!! the last argument must be NULL, otherwise this
+ * function will FAIL!!!
+ * return:
+ * Size of the buffer
+ * usage:
+ * MakeOutgoingFrame(Buffer, output_length, 2, &fc, 2, &dur, 6, p_addr1, 6,p_addr2, END_OF_ARGS);
+ IRQL = PASSIVE_LEVEL
IRQL = DISPATCH_LEVEL
- ==========================================================================
- */
-VOID AsicEnableBssSync(
- IN PRTMP_ADAPTER pAd)
+ ****************************************************************************/
+ULONG MakeOutgoingFrame(
+ OUT UCHAR *Buffer,
+ OUT ULONG *FrameLen, ...)
{
- BCN_TIME_CFG_STRUC csr;
-
- DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n"));
-
- RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
+ UCHAR *p;
+ int leng;
+ ULONG TotLeng;
+ va_list Args;
+ // calculates the total length
+ TotLeng = 0;
+ va_start(Args, FrameLen);
+ do
{
- csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
- csr.field.bTsfTicking = 1;
- csr.field.TsfSyncMode = 1; // sync TSF in INFRASTRUCTURE mode
- csr.field.bBeaconGen = 0; // do NOT generate BEACON
- csr.field.bTBTTEnable = 1;
+ leng = va_arg(Args, int);
+ if (leng == END_OF_ARGS)
+ {
+ break;
}
+ p = va_arg(Args, PVOID);
+ NdisMoveMemory(&Buffer[TotLeng], p, leng);
+ TotLeng = TotLeng + leng;
+ } while(TRUE);
- RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
+ va_end(Args); /* clean up */
+ *FrameLen = TotLeng;
+ return TotLeng;
}
-/*
- ==========================================================================
- Description:
- Note:
- BEACON frame in shared memory should be built ok before this routine
- can be called. Otherwise, a garbage frame maybe transmitted out every
- Beacon period.
+// ===========================================================================================
+// mlme_queue.c
+// ===========================================================================================
- IRQL = DISPATCH_LEVEL
+/*! \brief Initialize The MLME Queue, used by MLME Functions
+ * \param *Queue The MLME Queue
+ * \return Always Return NDIS_STATE_SUCCESS in this implementation
+ * \pre
+ * \post
+ * \note Because this is done only once (at the init stage), no need to be locked
+
+ IRQL = PASSIVE_LEVEL
- ==========================================================================
*/
-VOID AsicEnableIbssSync(
- IN PRTMP_ADAPTER pAd)
+NDIS_STATUS MlmeQueueInit(
+ IN MLME_QUEUE *Queue)
{
- BCN_TIME_CFG_STRUC csr9;
- PUCHAR ptr;
- UINT i;
-
- DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n", pAd->BeaconTxWI.MPDUtotalByteCount));
-
- RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word);
- csr9.field.bBeaconGen = 0;
- csr9.field.bTBTTEnable = 0;
- csr9.field.bTsfTicking = 0;
- RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
+ INT i;
-#ifdef RT2860
- // move BEACON TXD and frame content to on-chip memory
- ptr = (PUCHAR)&pAd->BeaconTxWI;
- for (i=0; i<TXWI_SIZE; i+=4) // 16-byte TXWI field
- {
- UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
- RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr);
- ptr += 4;
- }
+ NdisAllocateSpinLock(&Queue->Lock);
- // start right after the 16-byte TXWI field
- ptr = pAd->BeaconBuf;
- for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=4)
- {
- UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
- RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
- ptr +=4;
- }
-#endif
-#ifdef RT2870
- // move BEACON TXD and frame content to on-chip memory
- ptr = (PUCHAR)&pAd->BeaconTxWI;
- for (i=0; i<TXWI_SIZE; i+=2) // 16-byte TXWI field
- {
- RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + i, ptr, 2);
- ptr += 2;
- }
+ Queue->Num = 0;
+ Queue->Head = 0;
+ Queue->Tail = 0;
- // start right after the 16-byte TXWI field
- ptr = pAd->BeaconBuf;
- for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=2)
+ for (i = 0; i < MAX_LEN_OF_MLME_QUEUE; i++)
{
- RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, ptr, 2);
- ptr +=2;
+ Queue->Entry[i].Occupied = FALSE;
+ Queue->Entry[i].MsgLen = 0;
+ NdisZeroMemory(Queue->Entry[i].Msg, MGMT_DMA_BUFFER_SIZE);
}
-#endif // RT2870 //
- // start sending BEACON
- csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
- csr9.field.bTsfTicking = 1;
- csr9.field.TsfSyncMode = 2; // sync TSF in IBSS mode
- csr9.field.bTBTTEnable = 1;
- csr9.field.bBeaconGen = 1;
- RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
+ return NDIS_STATUS_SUCCESS;
}
-/*
- ==========================================================================
- Description:
+/*! \brief Enqueue a message for other threads, if they want to send messages to MLME thread
+ * \param *Queue The MLME Queue
+ * \param Machine The State Machine Id
+ * \param MsgType The Message Type
+ * \param MsgLen The Message length
+ * \param *Msg The message pointer
+ * \return TRUE if enqueue is successful, FALSE if the queue is full
+ * \pre
+ * \post
+ * \note The message has to be initialized
IRQL = PASSIVE_LEVEL
IRQL = DISPATCH_LEVEL
- ==========================================================================
*/
-VOID AsicSetEdcaParm(
+BOOLEAN MlmeEnqueue(
IN PRTMP_ADAPTER pAd,
- IN PEDCA_PARM pEdcaParm)
+ IN ULONG Machine,
+ IN ULONG MsgType,
+ IN ULONG MsgLen,
+ IN VOID *Msg)
{
- EDCA_AC_CFG_STRUC Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg;
- AC_TXOP_CSR0_STRUC csr0;
- AC_TXOP_CSR1_STRUC csr1;
- AIFSN_CSR_STRUC AifsnCsr;
- CWMIN_CSR_STRUC CwminCsr;
- CWMAX_CSR_STRUC CwmaxCsr;
- int i;
+ INT Tail;
+ MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
- Ac0Cfg.word = 0;
- Ac1Cfg.word = 0;
- Ac2Cfg.word = 0;
- Ac3Cfg.word = 0;
- if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE))
- {
- DBGPRINT(RT_DEBUG_TRACE,("AsicSetEdcaParm\n"));
- OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED);
- for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
- {
- if (pAd->MacTab.Content[i].ValidAsCLI || pAd->MacTab.Content[i].ValidAsApCli)
- CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[i], fCLIENT_STATUS_WMM_CAPABLE);
- }
+ // Do nothing if the driver is starting halt state.
+ // This might happen when timer already been fired before cancel timer with mlmehalt
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+ return FALSE;
- //========================================================
- // MAC Register has a copy .
- //========================================================
- if( pAd->CommonCfg.bEnableTxBurst )
- {
- // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
- Ac0Cfg.field.AcTxop = 0x20; // Suggest by John for TxBurst in HT Mode
- }
- else
- Ac0Cfg.field.AcTxop = 0; // QID_AC_BE
- Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS;
- Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS;
- Ac0Cfg.field.Aifsn = 2;
- RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
-
- Ac1Cfg.field.AcTxop = 0; // QID_AC_BK
- Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS;
- Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS;
- Ac1Cfg.field.Aifsn = 2;
- RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
-
- if (pAd->CommonCfg.PhyMode == PHY_11B)
- {
- Ac2Cfg.field.AcTxop = 192; // AC_VI: 192*32us ~= 6ms
- Ac3Cfg.field.AcTxop = 96; // AC_VO: 96*32us ~= 3ms
- }
- else
+ // First check the size, it MUST not exceed the mlme queue size
+ if (MsgLen > MGMT_DMA_BUFFER_SIZE)
{
- Ac2Cfg.field.AcTxop = 96; // AC_VI: 96*32us ~= 3ms
- Ac3Cfg.field.AcTxop = 48; // AC_VO: 48*32us ~= 1.5ms
- }
- Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS;
- Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS;
- Ac2Cfg.field.Aifsn = 2;
- RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
- Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS;
- Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS;
- Ac3Cfg.field.Aifsn = 2;
- RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
-
- //========================================================
- // DMA Register has a copy too.
- //========================================================
- csr0.field.Ac0Txop = 0; // QID_AC_BE
- csr0.field.Ac1Txop = 0; // QID_AC_BK
- RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
- if (pAd->CommonCfg.PhyMode == PHY_11B)
+ DBGPRINT_ERR(("MlmeEnqueue: msg too large, size = %ld \n", MsgLen));
+ return FALSE;
+ }
+
+ if (MlmeQueueFull(Queue))
{
- csr1.field.Ac2Txop = 192; // AC_VI: 192*32us ~= 6ms
- csr1.field.Ac3Txop = 96; // AC_VO: 96*32us ~= 3ms
+ return FALSE;
+ }
+
+ NdisAcquireSpinLock(&(Queue->Lock));
+ Tail = Queue->Tail;
+ Queue->Tail++;
+ Queue->Num++;
+ if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
+ {
+ Queue->Tail = 0;
}
- else
- {
- csr1.field.Ac2Txop = 96; // AC_VI: 96*32us ~= 3ms
- csr1.field.Ac3Txop = 48; // AC_VO: 48*32us ~= 1.5ms
+
+ Queue->Entry[Tail].Wcid = RESERVED_WCID;
+ Queue->Entry[Tail].Occupied = TRUE;
+ Queue->Entry[Tail].Machine = Machine;
+ Queue->Entry[Tail].MsgType = MsgType;
+ Queue->Entry[Tail].MsgLen = MsgLen;
+
+ if (Msg != NULL)
+ {
+ NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
}
- RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
- CwminCsr.word = 0;
- CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS;
- CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS;
- CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS;
- CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS;
- RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
+ NdisReleaseSpinLock(&(Queue->Lock));
+ return TRUE;
+}
- CwmaxCsr.word = 0;
- CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS;
- CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS;
- CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS;
- CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS;
- RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
+/*! \brief This function is used when Recv gets a MLME message
+ * \param *Queue The MLME Queue
+ * \param TimeStampHigh The upper 32 bit of timestamp
+ * \param TimeStampLow The lower 32 bit of timestamp
+ * \param Rssi The receiving RSSI strength
+ * \param MsgLen The length of the message
+ * \param *Msg The message pointer
+ * \return TRUE if everything ok, FALSE otherwise (like Queue Full)
+ * \pre
+ * \post
- RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222);
+ IRQL = DISPATCH_LEVEL
- NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(EDCA_PARM));
- }
- else
- {
- OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED);
- //========================================================
- // MAC Register has a copy.
- //========================================================
- //
- // Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27
- // To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue.
- //
- //pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this
+ */
+BOOLEAN MlmeEnqueueForRecv(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Wcid,
+ IN ULONG TimeStampHigh,
+ IN ULONG TimeStampLow,
+ IN UCHAR Rssi0,
+ IN UCHAR Rssi1,
+ IN UCHAR Rssi2,
+ IN ULONG MsgLen,
+ IN VOID *Msg,
+ IN UCHAR Signal)
+{
+ INT Tail, Machine;
+ PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
+ INT MsgType;
+ MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
- Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE];
- Ac0Cfg.field.Cwmin= pEdcaParm->Cwmin[QID_AC_BE];
- Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE];
- Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]; //+1;
- Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
- Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK]; //+2;
- Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK];
- Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK]; //+1;
+ // Do nothing if the driver is starting halt state.
+ // This might happen when timer already been fired before cancel timer with mlmehalt
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+ {
+ DBGPRINT_ERR(("MlmeEnqueueForRecv: fRTMP_ADAPTER_HALT_IN_PROGRESS\n"));
+ return FALSE;
+ }
- Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10;
- Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI];
- Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI];
- Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI];
+ // First check the size, it MUST not exceed the mlme queue size
+ if (MsgLen > MGMT_DMA_BUFFER_SIZE)
+ {
+ DBGPRINT_ERR(("MlmeEnqueueForRecv: frame too large, size = %ld \n", MsgLen));
+ return FALSE;
+ }
+ if (MlmeQueueFull(Queue))
{
- // Tuning for Wi-Fi WMM S06
- if (pAd->CommonCfg.bWiFiTest &&
- pEdcaParm->Aifsn[QID_AC_VI] == 10)
- Ac2Cfg.field.Aifsn -= 1;
-
- // Tuning for TGn Wi-Fi 5.2.32
- // STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta
- if (STA_TGN_WIFI_ON(pAd) &&
- pEdcaParm->Aifsn[QID_AC_VI] == 10)
- {
- Ac0Cfg.field.Aifsn = 3;
- Ac2Cfg.field.AcTxop = 5;
- }
+ return FALSE;
+ }
-#ifdef RT2870
- if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
{
- // Tuning for WiFi WMM S3-T07: connexant legacy sta ==> broadcom 11n sta.
- Ac2Cfg.field.Aifsn = 5;
+ if (!MsgTypeSubst(pAd, pFrame, &Machine, &MsgType))
+ {
+ DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n",pFrame->Hdr.FC.SubType));
+ return FALSE;
}
-#endif
}
- Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO];
- Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO];
- Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO];
- Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO];
-
-//#ifdef WIFI_TEST
- if (pAd->CommonCfg.bWiFiTest)
+ // OK, we got all the informations, it is time to put things into queue
+ NdisAcquireSpinLock(&(Queue->Lock));
+ Tail = Queue->Tail;
+ Queue->Tail++;
+ Queue->Num++;
+ if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
{
- if (Ac3Cfg.field.AcTxop == 102)
- {
- Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm->Txop[QID_AC_BE] : 10;
- Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]-1; /* AIFSN must >= 1 */
- Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
- Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK];
- Ac2Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VI];
- } /* End of if */
+ Queue->Tail = 0;
}
-//#endif // WIFI_TEST //
-
- RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
- RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
- RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
- RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
-
-
- //========================================================
- // DMA Register has a copy too.
- //========================================================
- csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop;
- csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop;
- RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
-
- csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop;
- csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop;
- RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
-
- CwminCsr.word = 0;
- CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE];
- CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK];
- CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI];
-
- CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO] - 1; //for TGn wifi test
-
- RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
+ Queue->Entry[Tail].Occupied = TRUE;
+ Queue->Entry[Tail].Machine = Machine;
+ Queue->Entry[Tail].MsgType = MsgType;
+ Queue->Entry[Tail].MsgLen = MsgLen;
+ Queue->Entry[Tail].TimeStamp.u.LowPart = TimeStampLow;
+ Queue->Entry[Tail].TimeStamp.u.HighPart = TimeStampHigh;
+ Queue->Entry[Tail].Rssi0 = Rssi0;
+ Queue->Entry[Tail].Rssi1 = Rssi1;
+ Queue->Entry[Tail].Rssi2 = Rssi2;
+ Queue->Entry[Tail].Signal = Signal;
+ Queue->Entry[Tail].Wcid = (UCHAR)Wcid;
- CwmaxCsr.word = 0;
- CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE];
- CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK];
- CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI];
- CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO];
- RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
+ Queue->Entry[Tail].Channel = pAd->LatchRfRegs.Channel;
- AifsnCsr.word = 0;
- AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BE];
- AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BK];
- AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_VI];
+ if (Msg != NULL)
+ {
+ NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
+ }
- {
- // Tuning for Wi-Fi WMM S06
- if (pAd->CommonCfg.bWiFiTest &&
- pEdcaParm->Aifsn[QID_AC_VI] == 10)
- AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4;
-
- // Tuning for TGn Wi-Fi 5.2.32
- // STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta
- if (STA_TGN_WIFI_ON(pAd) &&
- pEdcaParm->Aifsn[QID_AC_VI] == 10)
- {
- AifsnCsr.field.Aifsn0 = 3;
- AifsnCsr.field.Aifsn2 = 7;
- }
-#ifdef RT2870
- if (INFRA_ON(pAd))
- CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_WMM_CAPABLE);
-#endif
- }
+ NdisReleaseSpinLock(&(Queue->Lock));
- AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; //pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test
-#ifdef RT2870
- if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
- AifsnCsr.field.Aifsn2 = 0x2; //pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04.
-#endif
- RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word);
+ RTMP_MLME_HANDLER(pAd);
- NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
- if (!ADHOC_ON(pAd))
- {
- DBGPRINT(RT_DEBUG_TRACE,("EDCA [#%d]: AIFSN CWmin CWmax TXOP(us) ACM\n", pEdcaParm->EdcaUpdateCount));
- DBGPRINT(RT_DEBUG_TRACE,(" AC_BE %2d %2d %2d %4d %d\n",
- pEdcaParm->Aifsn[0],
- pEdcaParm->Cwmin[0],
- pEdcaParm->Cwmax[0],
- pEdcaParm->Txop[0]<<5,
- pEdcaParm->bACM[0]));
- DBGPRINT(RT_DEBUG_TRACE,(" AC_BK %2d %2d %2d %4d %d\n",
- pEdcaParm->Aifsn[1],
- pEdcaParm->Cwmin[1],
- pEdcaParm->Cwmax[1],
- pEdcaParm->Txop[1]<<5,
- pEdcaParm->bACM[1]));
- DBGPRINT(RT_DEBUG_TRACE,(" AC_VI %2d %2d %2d %4d %d\n",
- pEdcaParm->Aifsn[2],
- pEdcaParm->Cwmin[2],
- pEdcaParm->Cwmax[2],
- pEdcaParm->Txop[2]<<5,
- pEdcaParm->bACM[2]));
- DBGPRINT(RT_DEBUG_TRACE,(" AC_VO %2d %2d %2d %4d %d\n",
- pEdcaParm->Aifsn[3],
- pEdcaParm->Cwmin[3],
- pEdcaParm->Cwmax[3],
- pEdcaParm->Txop[3]<<5,
- pEdcaParm->bACM[3]));
- }
- }
+ return TRUE;
}
-/*
- ==========================================================================
- Description:
- IRQL = PASSIVE_LEVEL
- IRQL = DISPATCH_LEVEL
+/*! \brief Dequeue a message from the MLME Queue
+ * \param *Queue The MLME Queue
+ * \param *Elem The message dequeued from MLME Queue
+ * \return TRUE if the Elem contains something, FALSE otherwise
+ * \pre
+ * \post
+
+ IRQL = DISPATCH_LEVEL
- ==========================================================================
*/
-VOID AsicSetSlotTime(
- IN PRTMP_ADAPTER pAd,
- IN BOOLEAN bUseShortSlotTime)
+BOOLEAN MlmeDequeue(
+ IN MLME_QUEUE *Queue,
+ OUT MLME_QUEUE_ELEM **Elem)
{
- ULONG SlotTime;
- UINT32 RegValue = 0;
-
- if (pAd->CommonCfg.Channel > 14)
- bUseShortSlotTime = TRUE;
-
- if (bUseShortSlotTime)
- OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
- else
- OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
-
- SlotTime = (bUseShortSlotTime)? 9 : 20;
-
+ NdisAcquireSpinLock(&(Queue->Lock));
+ *Elem = &(Queue->Entry[Queue->Head]);
+ Queue->Num--;
+ Queue->Head++;
+ if (Queue->Head == MAX_LEN_OF_MLME_QUEUE)
{
- // force using short SLOT time for FAE to demo performance when TxBurst is ON
- if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
- || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE))
- )
- {
- // In this case, we will think it is doing Wi-Fi test
- // And we will not set to short slot when bEnableTxBurst is TRUE.
- }
- else if (pAd->CommonCfg.bEnableTxBurst)
- SlotTime = 9;
+ Queue->Head = 0;
}
-
- //
- // For some reasons, always set it to short slot time.
- //
- // ToDo: Should consider capability with 11B
- //
- if (pAd->StaCfg.BssType == BSS_ADHOC)
- SlotTime = 20;
-
- RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue);
- RegValue = RegValue & 0xFFFFFF00;
-
- RegValue |= SlotTime;
-
- RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue);
+ NdisReleaseSpinLock(&(Queue->Lock));
+ return TRUE;
}
-/*
- ========================================================================
- Description:
- Add Shared key information into ASIC.
- Update shared key, TxMic and RxMic to Asic Shared key table
- Update its cipherAlg to Asic Shared key Mode.
-
- Return:
- ========================================================================
-*/
-VOID AsicAddSharedKeyEntry(
- IN PRTMP_ADAPTER pAd,
- IN UCHAR BssIndex,
- IN UCHAR KeyIdx,
- IN UCHAR CipherAlg,
- IN PUCHAR pKey,
- IN PUCHAR pTxMic,
- IN PUCHAR pRxMic)
+// IRQL = DISPATCH_LEVEL
+VOID MlmeRestartStateMachine(
+ IN PRTMP_ADAPTER pAd)
{
- ULONG offset; //, csr0;
- SHAREDKEY_MODE_STRUC csr1;
-#ifdef RT2860
- INT i;
-#endif
+#ifdef RTMP_MAC_PCI
+ MLME_QUEUE_ELEM *Elem = NULL;
+#endif // RTMP_MAC_PCI //
+ BOOLEAN Cancelled;
- DBGPRINT(RT_DEBUG_TRACE, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,KeyIdx));
-//============================================================================================
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n"));
- DBGPRINT(RT_DEBUG_TRACE,("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg], BssIndex*4 + KeyIdx));
- DBGPRINT_RAW(RT_DEBUG_TRACE, (" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
- pKey[0],pKey[1],pKey[2],pKey[3],pKey[4],pKey[5],pKey[6],pKey[7],pKey[8],pKey[9],pKey[10],pKey[11],pKey[12],pKey[13],pKey[14],pKey[15]));
- if (pRxMic)
+#ifdef RTMP_MAC_PCI
+ NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
+ if(pAd->Mlme.bRunning)
{
- DBGPRINT_RAW(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
- pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
+ NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
+ return;
}
- if (pTxMic)
+ else
{
- DBGPRINT_RAW(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
- pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
+ pAd->Mlme.bRunning = TRUE;
}
-//============================================================================================
- //
- // fill key material - key + TX MIC + RX MIC
- //
+ NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
- offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE;
-#ifdef RT2860
- for (i=0; i<MAX_LEN_OF_SHARE_KEY; i++)
- {
- RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
- }
-#endif
-#ifdef RT2870
- RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_SHARE_KEY);
-#endif
- offset += MAX_LEN_OF_SHARE_KEY;
- if (pTxMic)
+ // Remove all Mlme queues elements
+ while (!MlmeQueueEmpty(&pAd->Mlme.Queue))
{
-#ifdef RT2860
- for (i=0; i<8; i++)
+ //From message type, determine which state machine I should drive
+ if (MlmeDequeue(&pAd->Mlme.Queue, &Elem))
{
- RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
- }
-#endif
-#ifdef RT2870
- RTUSBMultiWrite(pAd, offset, pTxMic, 8);
-#endif
- }
+ // free MLME element
+ Elem->Occupied = FALSE;
+ Elem->MsgLen = 0;
- offset += 8;
- if (pRxMic)
- {
-#ifdef RT2860
- for (i=0; i<8; i++)
- {
- RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
}
-#endif
-#ifdef RT2870
- RTUSBMultiWrite(pAd, offset, pRxMic, 8);
-#endif
+ else {
+ DBGPRINT_ERR(("MlmeRestartStateMachine: MlmeQueue empty\n"));
}
-
-
- //
- // Update cipher algorithm. WSTA always use BSS0
- //
- RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
- DBGPRINT(RT_DEBUG_TRACE,("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n", BssIndex,KeyIdx, csr1.word));
- if ((BssIndex%2) == 0)
- {
- if (KeyIdx == 0)
- csr1.field.Bss0Key0CipherAlg = CipherAlg;
- else if (KeyIdx == 1)
- csr1.field.Bss0Key1CipherAlg = CipherAlg;
- else if (KeyIdx == 2)
- csr1.field.Bss0Key2CipherAlg = CipherAlg;
- else
- csr1.field.Bss0Key3CipherAlg = CipherAlg;
}
- else
+#endif // RTMP_MAC_PCI //
+
{
- if (KeyIdx == 0)
- csr1.field.Bss1Key0CipherAlg = CipherAlg;
- else if (KeyIdx == 1)
- csr1.field.Bss1Key1CipherAlg = CipherAlg;
- else if (KeyIdx == 2)
- csr1.field.Bss1Key2CipherAlg = CipherAlg;
- else
- csr1.field.Bss1Key3CipherAlg = CipherAlg;
- }
- DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
- RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
+ // Cancel all timer events
+ // Be careful to cancel new added timer
+ RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
-}
+ }
-// IRQL = DISPATCH_LEVEL
-VOID AsicRemoveSharedKeyEntry(
- IN PRTMP_ADAPTER pAd,
- IN UCHAR BssIndex,
- IN UCHAR KeyIdx)
-{
- //ULONG SecCsr0;
- SHAREDKEY_MODE_STRUC csr1;
+ // Change back to original channel in case of doing scan
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
- DBGPRINT(RT_DEBUG_TRACE,("AsicRemoveSharedKeyEntry: #%d \n", BssIndex*4 + KeyIdx));
+ // Resume MSDU which is turned off durning scan
+ RTMPResumeMsduTransmission(pAd);
- RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
- if ((BssIndex%2) == 0)
- {
- if (KeyIdx == 0)
- csr1.field.Bss0Key0CipherAlg = 0;
- else if (KeyIdx == 1)
- csr1.field.Bss0Key1CipherAlg = 0;
- else if (KeyIdx == 2)
- csr1.field.Bss0Key2CipherAlg = 0;
- else
- csr1.field.Bss0Key3CipherAlg = 0;
- }
- else
{
- if (KeyIdx == 0)
- csr1.field.Bss1Key0CipherAlg = 0;
- else if (KeyIdx == 1)
- csr1.field.Bss1Key1CipherAlg = 0;
- else if (KeyIdx == 2)
- csr1.field.Bss1Key2CipherAlg = 0;
- else
- csr1.field.Bss1Key3CipherAlg = 0;
+ // Set all state machines back IDLE
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+ pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE;
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ pAd->Mlme.ActMachine.CurrState = ACT_IDLE;
}
- DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
- RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
- ASSERT(BssIndex < 4);
- ASSERT(KeyIdx < 4);
+#ifdef RTMP_MAC_PCI
+ // Remove running state
+ NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
+ pAd->Mlme.bRunning = FALSE;
+ NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
+#endif // RTMP_MAC_PCI //
}
+/*! \brief test if the MLME Queue is empty
+ * \param *Queue The MLME Queue
+ * \return TRUE if the Queue is empty, FALSE otherwise
+ * \pre
+ * \post
-VOID AsicUpdateWCIDAttribute(
- IN PRTMP_ADAPTER pAd,
- IN USHORT WCID,
- IN UCHAR BssIndex,
- IN UCHAR CipherAlg,
- IN BOOLEAN bUsePairewiseKeyTable)
-{
- ULONG WCIDAttri = 0, offset;
-
- //
- // Update WCID attribute.
- // Only TxKey could update WCID attribute.
- //
- offset = MAC_WCID_ATTRIBUTE_BASE + (WCID * HW_WCID_ATTRI_SIZE);
- WCIDAttri = (BssIndex << 4) | (CipherAlg << 1) | (bUsePairewiseKeyTable);
- RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
-}
+ IRQL = DISPATCH_LEVEL
-VOID AsicUpdateWCIDIVEIV(
- IN PRTMP_ADAPTER pAd,
- IN USHORT WCID,
- IN ULONG uIV,
- IN ULONG uEIV)
+ */
+BOOLEAN MlmeQueueEmpty(
+ IN MLME_QUEUE *Queue)
{
- ULONG offset;
+ BOOLEAN Ans;
- offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
+ NdisAcquireSpinLock(&(Queue->Lock));
+ Ans = (Queue->Num == 0);
+ NdisReleaseSpinLock(&(Queue->Lock));
- RTMP_IO_WRITE32(pAd, offset, uIV);
- RTMP_IO_WRITE32(pAd, offset + 4, uEIV);
+ return Ans;
}
-VOID AsicUpdateRxWCIDTable(
- IN PRTMP_ADAPTER pAd,
- IN USHORT WCID,
- IN PUCHAR pAddr)
+/*! \brief test if the MLME Queue is full
+ * \param *Queue The MLME Queue
+ * \return TRUE if the Queue is empty, FALSE otherwise
+ * \pre
+ * \post
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ */
+BOOLEAN MlmeQueueFull(
+ IN MLME_QUEUE *Queue)
{
- ULONG offset;
- ULONG Addr;
-
- offset = MAC_WCID_BASE + (WCID * HW_WCID_ENTRY_SIZE);
- Addr = pAddr[0] + (pAddr[1] << 8) +(pAddr[2] << 16) +(pAddr[3] << 24);
- RTMP_IO_WRITE32(pAd, offset, Addr);
- Addr = pAddr[4] + (pAddr[5] << 8);
- RTMP_IO_WRITE32(pAd, offset + 4, Addr);
-}
+ BOOLEAN Ans;
+ NdisAcquireSpinLock(&(Queue->Lock));
+ Ans = (Queue->Num == MAX_LEN_OF_MLME_QUEUE || Queue->Entry[Queue->Tail].Occupied);
+ NdisReleaseSpinLock(&(Queue->Lock));
-/*
- ========================================================================
+ return Ans;
+}
- Routine Description:
- Set Cipher Key, Cipher algorithm, IV/EIV to Asic
+/*! \brief The destructor of MLME Queue
+ * \param
+ * \return
+ * \pre
+ * \post
+ * \note Clear Mlme Queue, Set Queue->Num to Zero.
- Arguments:
- pAd Pointer to our adapter
- WCID WCID Entry number.
- BssIndex BSSID index, station or none multiple BSSID support
- this value should be 0.
- KeyIdx This KeyIdx will set to IV's KeyID if bTxKey enabled
- pCipherKey Pointer to Cipher Key.
- bUsePairewiseKeyTable TRUE means saved the key in SharedKey table,
- otherwise PairewiseKey table
- bTxKey This is the transmit key if enabled.
+ IRQL = PASSIVE_LEVEL
- Return Value:
- None
+ */
+VOID MlmeQueueDestroy(
+ IN MLME_QUEUE *pQueue)
+{
+ NdisAcquireSpinLock(&(pQueue->Lock));
+ pQueue->Num = 0;
+ pQueue->Head = 0;
+ pQueue->Tail = 0;
+ NdisReleaseSpinLock(&(pQueue->Lock));
+ NdisFreeSpinLock(&(pQueue->Lock));
+}
- Note:
- This routine will set the relative key stuff to Asic including WCID attribute,
- Cipher Key, Cipher algorithm and IV/EIV.
- IV/EIV will be update if this CipherKey is the transmission key because
- ASIC will base on IV's KeyID value to select Cipher Key.
+/*! \brief To substitute the message type if the message is coming from external
+ * \param pFrame The frame received
+ * \param *Machine The state machine
+ * \param *MsgType the message type for the state machine
+ * \return TRUE if the substitution is successful, FALSE otherwise
+ * \pre
+ * \post
- If bTxKey sets to FALSE, this is not the TX key, but it could be
- RX key
+ IRQL = DISPATCH_LEVEL
- For AP mode bTxKey must be always set to TRUE.
- ========================================================================
-*/
-VOID AsicAddKeyEntry(
- IN PRTMP_ADAPTER pAd,
- IN USHORT WCID,
- IN UCHAR BssIndex,
- IN UCHAR KeyIdx,
- IN PCIPHER_KEY pCipherKey,
- IN BOOLEAN bUsePairewiseKeyTable,
- IN BOOLEAN bTxKey)
+ */
+BOOLEAN MsgTypeSubst(
+ IN PRTMP_ADAPTER pAd,
+ IN PFRAME_802_11 pFrame,
+ OUT INT *Machine,
+ OUT INT *MsgType)
{
- ULONG offset;
- UCHAR IV4 = 0;
- PUCHAR pKey = pCipherKey->Key;
- PUCHAR pTxMic = pCipherKey->TxMic;
- PUCHAR pRxMic = pCipherKey->RxMic;
- PUCHAR pTxtsc = pCipherKey->TxTsc;
- UCHAR CipherAlg = pCipherKey->CipherAlg;
- SHAREDKEY_MODE_STRUC csr1;
-#ifdef RT2860
- UCHAR i;
-#endif
-
- DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n"));
- //
- // 1.) decide key table offset
- //
- if (bUsePairewiseKeyTable)
- offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
- else
- offset = SHARED_KEY_TABLE_BASE + (4 * BssIndex + KeyIdx) * HW_KEY_ENTRY_SIZE;
+ USHORT Seq, Alg;
+ UCHAR EAPType;
+ PUCHAR pData;
- //
- // 2.) Set Key to Asic
- //
- //for (i = 0; i < KeyLen; i++)
-#ifdef RT2860
- for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++)
- {
- RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
- }
-#endif
-#ifdef RT2870
- RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_PEER_KEY);
-#endif
- offset += MAX_LEN_OF_PEER_KEY;
+ // Pointer to start of data frames including SNAP header
+ pData = (PUCHAR) pFrame + LENGTH_802_11;
- //
- // 3.) Set MIC key if available
- //
- if (pTxMic)
+ // The only data type will pass to this function is EAPOL frame
+ if (pFrame->Hdr.FC.Type == BTYPE_DATA)
{
-#ifdef RT2860
- for (i = 0; i < 8; i++)
{
- RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
+ *Machine = WPA_STATE_MACHINE;
+ EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
+ return (WpaMsgTypeSubst(EAPType, (INT *) MsgType));
}
-#endif
-#ifdef RT2870
- RTUSBMultiWrite(pAd, offset, pTxMic, 8);
-#endif
}
- offset += LEN_TKIP_TXMICK;
- if (pRxMic)
+ switch (pFrame->Hdr.FC.SubType)
{
-#ifdef RT2860
- for (i = 0; i < 8; i++)
+ case SUBTYPE_ASSOC_REQ:
+ *Machine = ASSOC_STATE_MACHINE;
+ *MsgType = MT2_PEER_ASSOC_REQ;
+ break;
+ case SUBTYPE_ASSOC_RSP:
+ *Machine = ASSOC_STATE_MACHINE;
+ *MsgType = MT2_PEER_ASSOC_RSP;
+ break;
+ case SUBTYPE_REASSOC_REQ:
+ *Machine = ASSOC_STATE_MACHINE;
+ *MsgType = MT2_PEER_REASSOC_REQ;
+ break;
+ case SUBTYPE_REASSOC_RSP:
+ *Machine = ASSOC_STATE_MACHINE;
+ *MsgType = MT2_PEER_REASSOC_RSP;
+ break;
+ case SUBTYPE_PROBE_REQ:
+ *Machine = SYNC_STATE_MACHINE;
+ *MsgType = MT2_PEER_PROBE_REQ;
+ break;
+ case SUBTYPE_PROBE_RSP:
+ *Machine = SYNC_STATE_MACHINE;
+ *MsgType = MT2_PEER_PROBE_RSP;
+ break;
+ case SUBTYPE_BEACON:
+ *Machine = SYNC_STATE_MACHINE;
+ *MsgType = MT2_PEER_BEACON;
+ break;
+ case SUBTYPE_ATIM:
+ *Machine = SYNC_STATE_MACHINE;
+ *MsgType = MT2_PEER_ATIM;
+ break;
+ case SUBTYPE_DISASSOC:
+ *Machine = ASSOC_STATE_MACHINE;
+ *MsgType = MT2_PEER_DISASSOC_REQ;
+ break;
+ case SUBTYPE_AUTH:
+ // get the sequence number from payload 24 Mac Header + 2 bytes algorithm
+ NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(USHORT));
+ NdisMoveMemory(&Alg, &pFrame->Octet[0], sizeof(USHORT));
+ if (Seq == 1 || Seq == 3)
{
- RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
- }
-#endif
-#ifdef RT2870
- RTUSBMultiWrite(pAd, offset, pRxMic, 8);
-#endif
+ *Machine = AUTH_RSP_STATE_MACHINE;
+ *MsgType = MT2_PEER_AUTH_ODD;
}
-
-
- //
- // 4.) Modify IV/EIV if needs
- // This will force Asic to use this key ID by setting IV.
- //
- if (bTxKey)
+ else if (Seq == 2 || Seq == 4)
{
-#ifdef RT2860
- offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
- //
- // Write IV
- //
- RTMP_IO_WRITE8(pAd, offset, pTxtsc[1]);
- RTMP_IO_WRITE8(pAd, offset + 1, ((pTxtsc[1] | 0x20) & 0x7f));
- RTMP_IO_WRITE8(pAd, offset + 2, pTxtsc[0]);
-
- IV4 = (KeyIdx << 6);
- if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES))
- IV4 |= 0x20; // turn on extension bit means EIV existence
-
- RTMP_IO_WRITE8(pAd, offset + 3, IV4);
-
- //
- // Write EIV
- //
- offset += 4;
- for (i = 0; i < 4; i++)
+ if (Alg == AUTH_MODE_OPEN || Alg == AUTH_MODE_KEY)
{
- RTMP_IO_WRITE8(pAd, offset + i, pTxtsc[i + 2]);
+ *Machine = AUTH_STATE_MACHINE;
+ *MsgType = MT2_PEER_AUTH_EVEN;
}
-
-#endif
-#ifdef RT2870
- UINT32 tmpVal;
-
- //
- // Write IV
- //
- IV4 = (KeyIdx << 6);
- if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES))
- IV4 |= 0x20; // turn on extension bit means EIV existence
-
- tmpVal = pTxtsc[1] + (((pTxtsc[1] | 0x20) & 0x7f) << 8) + (pTxtsc[0] << 16) + (IV4 << 24);
- RTMP_IO_WRITE32(pAd, offset, tmpVal);
-
- //
- // Write EIV
- //
- offset += 4;
- RTMP_IO_WRITE32(pAd, offset, *(PUINT32)&pCipherKey->TxTsc[2]);
-#endif // RT2870 //
- AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg, bUsePairewiseKeyTable);
}
-
- if (!bUsePairewiseKeyTable)
+ else
{
- //
- // Only update the shared key security mode
- //
- RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), &csr1.word);
- if ((BssIndex % 2) == 0)
+ return FALSE;
+ }
+ break;
+ case SUBTYPE_DEAUTH:
+ *Machine = AUTH_RSP_STATE_MACHINE;
+ *MsgType = MT2_PEER_DEAUTH;
+ break;
+ case SUBTYPE_ACTION:
+ *Machine = ACTION_STATE_MACHINE;
+ // Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support
+ if ((pFrame->Octet[0]&0x7F) > MAX_PEER_CATE_MSG)
{
- if (KeyIdx == 0)
- csr1.field.Bss0Key0CipherAlg = CipherAlg;
- else if (KeyIdx == 1)
- csr1.field.Bss0Key1CipherAlg = CipherAlg;
- else if (KeyIdx == 2)
- csr1.field.Bss0Key2CipherAlg = CipherAlg;
- else
- csr1.field.Bss0Key3CipherAlg = CipherAlg;
+ *MsgType = MT2_ACT_INVALID;
}
else
{
- if (KeyIdx == 0)
- csr1.field.Bss1Key0CipherAlg = CipherAlg;
- else if (KeyIdx == 1)
- csr1.field.Bss1Key1CipherAlg = CipherAlg;
- else if (KeyIdx == 2)
- csr1.field.Bss1Key2CipherAlg = CipherAlg;
- else
- csr1.field.Bss1Key3CipherAlg = CipherAlg;
+ *MsgType = (pFrame->Octet[0]&0x7F);
}
- RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), csr1.word);
+ break;
+ default:
+ return FALSE;
+ break;
}
- DBGPRINT(RT_DEBUG_TRACE, ("<== AsicAddKeyEntry\n"));
+ return TRUE;
}
+// ===========================================================================================
+// state_machine.c
+// ===========================================================================================
-/*
- ========================================================================
- Description:
- Add Pair-wise key material into ASIC.
- Update pairwise key, TxMic and RxMic to Asic Pair-wise key table
+/*! \brief Initialize the state machine.
+ * \param *S pointer to the state machine
+ * \param Trans State machine transition function
+ * \param StNr number of states
+ * \param MsgNr number of messages
+ * \param DefFunc default function, when there is invalid state/message combination
+ * \param InitState initial state of the state machine
+ * \param Base StateMachine base, internal use only
+ * \pre p_sm should be a legal pointer
+ * \post
- Return:
- ========================================================================
-*/
-VOID AsicAddPairwiseKeyEntry(
- IN PRTMP_ADAPTER pAd,
- IN PUCHAR pAddr,
- IN UCHAR WCID,
- IN CIPHER_KEY *pCipherKey)
+ IRQL = PASSIVE_LEVEL
+
+ */
+VOID StateMachineInit(
+ IN STATE_MACHINE *S,
+ IN STATE_MACHINE_FUNC Trans[],
+ IN ULONG StNr,
+ IN ULONG MsgNr,
+ IN STATE_MACHINE_FUNC DefFunc,
+ IN ULONG InitState,
+ IN ULONG Base)
{
- INT i;
- ULONG offset;
- PUCHAR pKey = pCipherKey->Key;
- PUCHAR pTxMic = pCipherKey->TxMic;
- PUCHAR pRxMic = pCipherKey->RxMic;
-#ifdef DBG
- UCHAR CipherAlg = pCipherKey->CipherAlg;
-#endif // DBG //
-
- // EKEY
- offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
-#ifdef RT2860
- for (i=0; i<MAX_LEN_OF_PEER_KEY; i++)
- {
- RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
- }
-#endif
-#ifdef RT2870
- RTUSBMultiWrite(pAd, offset, &pCipherKey->Key[0], MAX_LEN_OF_PEER_KEY);
-#endif // RT2870 //
- for (i=0; i<MAX_LEN_OF_PEER_KEY; i+=4)
- {
- UINT32 Value;
- RTMP_IO_READ32(pAd, offset + i, &Value);
- }
+ ULONG i, j;
- offset += MAX_LEN_OF_PEER_KEY;
+ // set number of states and messages
+ S->NrState = StNr;
+ S->NrMsg = MsgNr;
+ S->Base = Base;
- // MIC KEY
- if (pTxMic)
- {
-#ifdef RT2860
- for (i=0; i<8; i++)
- {
- RTMP_IO_WRITE8(pAd, offset+i, pTxMic[i]);
- }
-#endif
-#ifdef RT2870
- RTUSBMultiWrite(pAd, offset, &pCipherKey->TxMic[0], 8);
-#endif // RT2870 //
- }
- offset += 8;
- if (pRxMic)
+ S->TransFunc = Trans;
+
+ // init all state transition to default function
+ for (i = 0; i < StNr; i++)
{
-#ifdef RT2860
- for (i=0; i<8; i++)
+ for (j = 0; j < MsgNr; j++)
{
- RTMP_IO_WRITE8(pAd, offset+i, pRxMic[i]);
+ S->TransFunc[i * MsgNr + j] = DefFunc;
}
-#endif
-#ifdef RT2870
- RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8);
-#endif // RT2870 //
}
- DBGPRINT(RT_DEBUG_TRACE,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID, CipherName[CipherAlg]));
- DBGPRINT(RT_DEBUG_TRACE,(" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
- pKey[0],pKey[1],pKey[2],pKey[3],pKey[4],pKey[5],pKey[6],pKey[7],pKey[8],pKey[9],pKey[10],pKey[11],pKey[12],pKey[13],pKey[14],pKey[15]));
- if (pRxMic)
- {
- DBGPRINT(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
- pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
- }
- if (pTxMic)
+ // set the starting state
+ S->CurrState = InitState;
+}
+
+/*! \brief This function fills in the function pointer into the cell in the state machine
+ * \param *S pointer to the state machine
+ * \param St state
+ * \param Msg incoming message
+ * \param f the function to be executed when (state, message) combination occurs at the state machine
+ * \pre *S should be a legal pointer to the state machine, st, msg, should be all within the range, Base should be set in the initial state
+ * \post
+
+ IRQL = PASSIVE_LEVEL
+
+ */
+VOID StateMachineSetAction(
+ IN STATE_MACHINE *S,
+ IN ULONG St,
+ IN ULONG Msg,
+ IN STATE_MACHINE_FUNC Func)
+{
+ ULONG MsgIdx;
+
+ MsgIdx = Msg - S->Base;
+
+ if (St < S->NrState && MsgIdx < S->NrMsg)
{
- DBGPRINT(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
- pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
+ // boundary checking before setting the action
+ S->TransFunc[St * S->NrMsg + MsgIdx] = Func;
}
}
+
+/*! \brief This function does the state transition
+ * \param *Adapter the NIC adapter pointer
+ * \param *S the state machine
+ * \param *Elem the message to be executed
+ * \return None
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+VOID StateMachinePerformAction(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ (*(S->TransFunc[S->CurrState * S->NrMsg + Elem->MsgType - S->Base]))(pAd, Elem);
+}
+
/*
- ========================================================================
+ ==========================================================================
Description:
- Remove Pair-wise key material from ASIC.
-
- Return:
- ========================================================================
-*/
-VOID AsicRemovePairwiseKeyEntry(
+ The drop function, when machine executes this, the message is simply
+ ignored. This function does nothing, the message is freed in
+ StateMachinePerformAction()
+ ==========================================================================
+ */
+VOID Drop(
IN PRTMP_ADAPTER pAd,
- IN UCHAR BssIdx,
- IN UCHAR Wcid)
+ IN MLME_QUEUE_ELEM *Elem)
{
- ULONG WCIDAttri;
- USHORT offset;
-
- // re-set the entry's WCID attribute as OPEN-NONE.
- offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
- WCIDAttri = (BssIdx<<4) | PAIRWISEKEYTABLE;
- RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
}
-BOOLEAN AsicSendCommandToMcu(
- IN PRTMP_ADAPTER pAd,
- IN UCHAR Command,
- IN UCHAR Token,
- IN UCHAR Arg0,
- IN UCHAR Arg1)
-{
- HOST_CMD_CSR_STRUC H2MCmd;
- H2M_MAILBOX_STRUC H2MMailbox;
- ULONG i = 0;
-
- do
- {
- RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
- if (H2MMailbox.field.Owner == 0)
- break;
-
- RTMPusecDelay(2);
- } while(i++ < 100);
-
- if (i > 100)
- {
- {
-#ifdef RT2860
- UINT32 Data;
-
- // Reset DMA
- RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
- Data |= 0x2;
- RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
-
- // After Reset DMA, DMA index will become Zero. So Driver need to reset all ring indexs too.
- // Reset DMA/CPU ring index
- RTMPRingCleanUp(pAd, QID_AC_BK);
- RTMPRingCleanUp(pAd, QID_AC_BE);
- RTMPRingCleanUp(pAd, QID_AC_VI);
- RTMPRingCleanUp(pAd, QID_AC_VO);
- RTMPRingCleanUp(pAd, QID_HCCA);
- RTMPRingCleanUp(pAd, QID_MGMT);
- RTMPRingCleanUp(pAd, QID_RX);
-
- // Clear Reset
- RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
- Data &= 0xfffffffd;
- RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
-#endif /* RT2860 */
- DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
- }
- //return FALSE;
-#ifdef RT2870
- return FALSE;
-#endif
- }
-
- H2MMailbox.field.Owner = 1; // pass ownership to MCU
- H2MMailbox.field.CmdToken = Token;
- H2MMailbox.field.HighByte = Arg1;
- H2MMailbox.field.LowByte = Arg0;
- RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
-
- H2MCmd.word = 0;
- H2MCmd.field.HostCommand = Command;
- RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
+// ===========================================================================================
+// lfsr.c
+// ===========================================================================================
- if (Command != 0x80)
- {
- }
+/*
+ ==========================================================================
+ Description:
- return TRUE;
-}
+ IRQL = PASSIVE_LEVEL
-#ifdef RT2860
-BOOLEAN AsicCheckCommanOk(
+ ==========================================================================
+ */
+VOID LfsrInit(
IN PRTMP_ADAPTER pAd,
- IN UCHAR Command)
+ IN ULONG Seed)
{
- UINT32 CmdStatus = 0, CID = 0, i;
- UINT32 ThisCIDMask = 0;
+ if (Seed == 0)
+ pAd->Mlme.ShiftReg = 1;
+ else
+ pAd->Mlme.ShiftReg = Seed;
+}
- i = 0;
- do
- {
- RTMP_IO_READ32(pAd, H2M_MAILBOX_CID, &CID);
- // Find where the command is. Because this is randomly specified by firmware.
- if ((CID & CID0MASK) == Command)
- {
- ThisCIDMask = CID0MASK;
- break;
- }
- else if ((((CID & CID1MASK)>>8) & 0xff) == Command)
- {
- ThisCIDMask = CID1MASK;
- break;
- }
- else if ((((CID & CID2MASK)>>16) & 0xff) == Command)
- {
- ThisCIDMask = CID2MASK;
- break;
- }
- else if ((((CID & CID3MASK)>>24) & 0xff) == Command)
- {
- ThisCIDMask = CID3MASK;
- break;
- }
+/*
+ ==========================================================================
+ Description:
+ ==========================================================================
+ */
+UCHAR RandomByte(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG i;
+ UCHAR R, Result;
- RTMPusecDelay(100);
- i++;
- }while (i < 200);
+ R = 0;
- // Get CommandStatus Value
- RTMP_IO_READ32(pAd, H2M_MAILBOX_STATUS, &CmdStatus);
+ if (pAd->Mlme.ShiftReg == 0)
+ NdisGetSystemUpTime((ULONG *)&pAd->Mlme.ShiftReg);
- // This command's status is at the same position as command. So AND command position's bitmask to read status.
- if (i < 200)
+ for (i = 0; i < 8; i++)
{
- // If Status is 1, the comamnd is success.
- if (((CmdStatus & ThisCIDMask) == 0x1) || ((CmdStatus & ThisCIDMask) == 0x100)
- || ((CmdStatus & ThisCIDMask) == 0x10000) || ((CmdStatus & ThisCIDMask) == 0x1000000))
+ if (pAd->Mlme.ShiftReg & 0x00000001)
{
- DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanOk CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus));
- RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
- RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
- return TRUE;
- }
- DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail1 CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus));
+ pAd->Mlme.ShiftReg = ((pAd->Mlme.ShiftReg ^ LFSR_MASK) >> 1) | 0x80000000;
+ Result = 1;
}
else
{
- DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail2 Timeout Command = %d, CmdStatus= 0x%x \n", Command, CmdStatus));
+ pAd->Mlme.ShiftReg = pAd->Mlme.ShiftReg >> 1;
+ Result = 0;
+ }
+ R = (R << 1) | Result;
}
- // Clear Command and Status.
- RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
- RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
- return FALSE;
+ return R;
}
-#endif /* RT8260 */
+
/*
========================================================================
return larger;
}
-#ifdef RT2870
-// Antenna divesity use GPIO3 and EESK pin for control
-// Antenna and EEPROM access are both using EESK pin,
-// Therefor we should avoid accessing EESK at the same time
-// Then restore antenna after EEPROM access
-VOID AsicSetRxAnt(
- IN PRTMP_ADAPTER pAd,
- IN UCHAR Ant)
-{
- UINT32 Value;
- UINT32 x;
-
- if ((pAd->EepromAccess) ||
- (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) ||
- (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) ||
- (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) ||
- (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
- {
- return;
- }
-
- // the antenna selection is through firmware and MAC register(GPIO3)
- if (Ant == 0)
- {
- // Main antenna
- RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
- x |= (EESK);
- RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
- RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
- Value &= ~(0x0808);
- RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
- DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to main antenna\n"));
- }
- else
- {
- // Aux antenna
- RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
- x &= ~(EESK);
- RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
- RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
- Value &= ~(0x0808);
- Value |= 0x08;
- RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
- DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to aux antenna\n"));
- }
-}
-#endif
/*
========================================================================
fRTMP_ADAPTER_HALT_IN_PROGRESS |
fRTMP_ADAPTER_RADIO_OFF |
fRTMP_ADAPTER_NIC_NOT_EXIST |
- fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)
- || OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
-#ifdef RT2870
+ fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) ||
+ OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
+#ifdef RT30xx
|| (pAd->EepromAccess)
-#endif
+#endif // RT30xx //
)
return;
-#ifdef RT30xx
- // two antenna selection mechanism- one is antenna diversity, the other is failed antenna remove
- // one is antenna diversity:there is only one antenna can rx and tx
- // the other is failed antenna remove:two physical antenna can rx and tx
- if (pAd->NicConfig2.field.AntDiversity)
- {
- DBGPRINT(RT_DEBUG_TRACE,("AntDiv - before evaluate Pair1-Ant (%d,%d)\n",
- pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt));
-
- AsicSetRxAnt(pAd, pAd->RxAnt.Pair1SecondaryRxAnt);
- pAd->RxAnt.EvaluatePeriod = 1; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt
- pAd->RxAnt.FirstPktArrivedWhenEvaluate = FALSE;
- pAd->RxAnt.RcvPktNumWhenEvaluate = 0;
+ {
+ //if (pAd->StaCfg.Psm == PWR_SAVE)
+ // return;
- // a one-shot timer to end the evalution
- // dynamic adjust antenna evaluation period according to the traffic
- if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
- RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 100);
- else
- RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
- }
- else
-#endif
{
+
if (pAd->StaCfg.Psm == PWR_SAVE)
return;
BBPR3 |= (0x0);
}
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
-
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
pAd->StaCfg.BBPR3 = BBPR3;
-#endif
- }
-
+#endif // RTMP_MAC_PCI //
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
)
{
pAd->Mlme.bLowThroughput = TRUE;
}
}
+ }
+
+ }
+
+
}
/*
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
fRTMP_ADAPTER_HALT_IN_PROGRESS |
fRTMP_ADAPTER_RADIO_OFF |
- fRTMP_ADAPTER_NIC_NOT_EXIST)
- || OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
-#ifdef RT2870
+ fRTMP_ADAPTER_NIC_NOT_EXIST) ||
+ OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
+#ifdef RT30xx
|| (pAd->EepromAccess)
-#endif
+#endif // RT30xx //
)
return;
{
-#ifdef RT30xx
- if (pAd->NicConfig2.field.AntDiversity)
- {
- if ((pAd->RxAnt.RcvPktNumWhenEvaluate != 0) && (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >= pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt]))
- {
- UCHAR temp;
-
- //
- // select PrimaryRxAntPair
- // Role change, Used Pair1SecondaryRxAnt as PrimaryRxAntPair.
- // Since Pair1SecondaryRxAnt Quality good than Pair1PrimaryRxAnt
- //
- temp = pAd->RxAnt.Pair1PrimaryRxAnt;
- pAd->RxAnt.Pair1PrimaryRxAnt = pAd->RxAnt.Pair1SecondaryRxAnt;
- pAd->RxAnt.Pair1SecondaryRxAnt = temp;
-
- pAd->RxAnt.Pair1LastAvgRssi = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >> 3);
- pAd->RxAnt.EvaluateStableCnt = 0;
- }
- else
- {
- // if the evaluated antenna is not better than original, switch back to original antenna
- AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
- pAd->RxAnt.EvaluateStableCnt ++;
- }
-
- pAd->RxAnt.EvaluatePeriod = 0; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt
-
- DBGPRINT(RT_DEBUG_TRACE,("AsicRxAntEvalAction::After Eval(fix in #%d), <%d, %d>, RcvPktNumWhenEvaluate=%ld\n",
- pAd->RxAnt.Pair1PrimaryRxAnt, (pAd->RxAnt.Pair1AvgRssi[0] >> 3), (pAd->RxAnt.Pair1AvgRssi[1] >> 3), pAd->RxAnt.RcvPktNumWhenEvaluate));
- }
- else
-#endif
+ //if (pAd->StaCfg.Psm == PWR_SAVE)
+ // return;
{
if (pAd->StaCfg.Psm == PWR_SAVE)
return;
BBPR3 |= (0x0);
}
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
pAd->StaCfg.BBPR3 = BBPR3;
-#endif
+#endif // RTMP_MAC_PCI //
}
}
+
+
}
+
VOID APSDPeriodicExec(
IN PVOID SystemSpecific1,
IN PVOID FunctionContext,
pAd->CommonCfg.TriggerTimerCount++;
+// Driver should not send trigger frame, it should be send by application layer
+/*
+ if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable
+ && (pAd->CommonCfg.bNeedSendTriggerFrame ||
+ (((pAd->CommonCfg.TriggerTimerCount%20) == 19) && (!pAd->CommonCfg.bAPSDAC_BE || !pAd->CommonCfg.bAPSDAC_BK || !pAd->CommonCfg.bAPSDAC_VI || !pAd->CommonCfg.bAPSDAC_VO))))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("Sending trigger frame and enter service period when support APSD\n"));
+ RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
+ pAd->CommonCfg.bNeedSendTriggerFrame = FALSE;
+ pAd->CommonCfg.TriggerTimerCount = 0;
+ pAd->CommonCfg.bInServicePeriod = TRUE;
+ }*/
}
/*
BOOLEAN RTMPAutoRateSwitchCheck(
IN PRTMP_ADAPTER pAd)
{
+ {
if (pAd->StaCfg.bAutoTxRateSwitch)
return TRUE;
-
+ }
return FALSE;
}
{
UCHAR tx_mode = FIXED_TXMODE_HT;
+ {
tx_mode = (UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode;
+ }
return tx_mode;
}
&& (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
)
&& !(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-#ifdef RT2860
- && (pAd->bPCIclkOff == FALSE))
-#endif
-#ifdef RT2870
+#ifdef RTMP_MAC_PCI
+ && (pAd->bPCIclkOff == FALSE)
+#endif // RTMP_MAC_PCI //
)
-#endif
{
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &OrigR66Value);
R66 = OrigR66Value;
if (pAd->LatchRfRegs.Channel <= 14)
{ //BG band
-#ifdef RT2870
+#ifdef RT30xx
// RT3070 is a no LNA solution, it should have different control regarding to AGC gain control
// Otherwise, it will have some throughput side effect when low RSSI
- if (IS_RT30xx(pAd))
+
+ if (IS_RT3070(pAd)||IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
{
if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
{
R66 = 0x1C + 2*GET_LNA_GAIN(pAd) + 0x20;
if (OrigR66Value != R66)
+ {
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
}
+ }
else
{
R66 = 0x1C + 2*GET_LNA_GAIN(pAd);
if (OrigR66Value != R66)
+ {
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
}
}
+ }
else
-#endif // RT2870 //
+#endif // RT30xx //
{
if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
{
}
}
-#ifdef RT2860
-VOID AsicResetFromDMABusy(
- IN PRTMP_ADAPTER pAd)
-{
- UINT32 Data;
- BOOLEAN bCtrl = FALSE;
-
- DBGPRINT(RT_DEBUG_TRACE, ("---> AsicResetFromDMABusy !!!!!!!!!!!!!!!!!!!!!!! \n"));
-
- // Be sure restore link control value so we can write register.
- RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
- if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
- {
- DBGPRINT(RT_DEBUG_TRACE,("AsicResetFromDMABusy==>\n"));
- RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
- RTMPusecDelay(6000);
- pAd->bPCIclkOff = FALSE;
- bCtrl = TRUE;
- }
- // Reset DMA
- RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
- Data |= 0x2;
- RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
-
- // After Reset DMA, DMA index will become Zero. So Driver need to reset all ring indexs too.
- // Reset DMA/CPU ring index
- RTMPRingCleanUp(pAd, QID_AC_BK);
- RTMPRingCleanUp(pAd, QID_AC_BE);
- RTMPRingCleanUp(pAd, QID_AC_VI);
- RTMPRingCleanUp(pAd, QID_AC_VO);
- RTMPRingCleanUp(pAd, QID_HCCA);
- RTMPRingCleanUp(pAd, QID_MGMT);
- RTMPRingCleanUp(pAd, QID_RX);
-
- // Clear Reset
- RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
- Data &= 0xfffffffd;
- RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
-
- // If in Radio off, should call RTMPPCIePowerLinkCtrl again.
- if ((bCtrl == TRUE) && (pAd->StaCfg.bRadio == FALSE))
- RTMPPCIeLinkCtrlSetting(pAd, 3);
-
- RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
- RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS);
- DBGPRINT(RT_DEBUG_TRACE, ("<--- AsicResetFromDMABusy !!!!!!!!!!!!!!!!!!!!!!! \n"));
-}
-
-VOID AsicResetBBP(
- IN PRTMP_ADAPTER pAd)
-{
- DBGPRINT(RT_DEBUG_TRACE, ("---> Asic HardReset BBP !!!!!!!!!!!!!!!!!!!!!!! \n"));
-
- RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
- RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x2);
- RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc);
-
- // After hard-reset BBP, initialize all BBP values.
- NICRestoreBBPValue(pAd);
- DBGPRINT(RT_DEBUG_TRACE, ("<--- Asic HardReset BBP !!!!!!!!!!!!!!!!!!!!!!! \n"));
-}
-
-VOID AsicResetMAC(
- IN PRTMP_ADAPTER pAd)
-{
- ULONG Data;
-
- DBGPRINT(RT_DEBUG_TRACE, ("---> AsicResetMAC !!!! \n"));
- RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
- Data |= 0x4;
- RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
- Data &= 0xfffffffb;
- RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
-
- DBGPRINT(RT_DEBUG_TRACE, ("<--- AsicResetMAC !!!! \n"));
-}
-
-VOID AsicResetPBF(
- IN PRTMP_ADAPTER pAd)
-{
- ULONG Value1, Value2;
- ULONG Data;
-
- RTMP_IO_READ32(pAd, TXRXQ_PCNT, &Value1);
- RTMP_IO_READ32(pAd, PBF_DBG, &Value2);
-
- Value2 &= 0xff;
- // sum should be equals to 0xff, which is the total buffer size.
- if ((Value1 + Value2) < 0xff)
- {
- DBGPRINT(RT_DEBUG_TRACE, ("---> Asic HardReset PBF !!!! \n"));
- RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
- Data |= 0x8;
- RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
- Data &= 0xfffffff7;
- RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
-
- DBGPRINT(RT_DEBUG_TRACE, ("<--- Asic HardReset PBF !!!! \n"));
- }
-}
-#endif /* RT2860 */
-
VOID RTMPSetAGCInitValue(
IN PRTMP_ADAPTER pAd,
IN UCHAR BandWidth)
if (pAd->LatchRfRegs.Channel <= 14)
{ // BG band
+#ifdef RT30xx
+ /* Gary was verified Amazon AP and find that RT307x has BBP_R66 invalid default value */
+
+ if (IS_RT3070(pAd)||IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
+ {
+ R66 = 0x1C + 2*GET_LNA_GAIN(pAd);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ else
+#endif // RT30xx //
+ {
R66 = 0x2E + GET_LNA_GAIN(pAd);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
}
+ }
else
{ //A band
+ {
if (BandWidth == BW_20)
{
R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
}
}
-
-}
-
-VOID AsicTurnOffRFClk(
- IN PRTMP_ADAPTER pAd,
- IN UCHAR Channel)
-{
-
- // RF R2 bit 18 = 0
- UINT32 R1 = 0, R2 = 0, R3 = 0;
- UCHAR index;
- RTMP_RF_REGS *RFRegTable;
-
- // The RF programming sequence is difference between 3xxx and 2xxx
- if (IS_RT3090(pAd))
- {
- RT30xxLoadRFSleepModeSetup(pAd); // add by johnli, RF power sequence setup, load RF sleep-mode setup
- return;
- }
-
- RFRegTable = RF2850RegTable;
-
- switch (pAd->RfIcType)
- {
- case RFIC_2820:
- case RFIC_2850:
- case RFIC_2720:
- case RFIC_2750:
-
- for (index = 0; index < NUM_OF_2850_CHNL; index++)
- {
- if (Channel == RFRegTable[index].Channel)
- {
- R1 = RFRegTable[index].R1 & 0xffffdfff;
- R2 = RFRegTable[index].R2 & 0xfffbffff;
- R3 = RFRegTable[index].R3 & 0xfff3ffff;
-
- RTMP_RF_IO_WRITE32(pAd, R1);
- RTMP_RF_IO_WRITE32(pAd, R2);
-
- // Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0.
- // Set RF R2 bit18=0, R3 bit[18:19]=0
- //if (pAd->StaCfg.bRadio == FALSE)
- if (1)
- {
- RTMP_RF_IO_WRITE32(pAd, R3);
-
- DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x, R3 = 0x%08x \n",
- Channel, pAd->RfIcType, R2, R3));
- }
- else
- DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n",
- Channel, pAd->RfIcType, R2));
- break;
- }
- }
- break;
-
- default:
- break;
- }
-}
-
-
-VOID AsicTurnOnRFClk(
- IN PRTMP_ADAPTER pAd,
- IN UCHAR Channel)
-{
-
- // RF R2 bit 18 = 0
- UINT32 R1 = 0, R2 = 0, R3 = 0;
- UCHAR index;
- RTMP_RF_REGS *RFRegTable;
-
- // The RF programming sequence is difference between 3xxx and 2xxx
- if (IS_RT3090(pAd))
- return;
-
- RFRegTable = RF2850RegTable;
-
- switch (pAd->RfIcType)
- {
- case RFIC_2820:
- case RFIC_2850:
- case RFIC_2720:
- case RFIC_2750:
-
- for (index = 0; index < NUM_OF_2850_CHNL; index++)
- {
- if (Channel == RFRegTable[index].Channel)
- {
- R3 = pAd->LatchRfRegs.R3;
- R3 &= 0xfff3ffff;
- R3 |= 0x00080000;
- RTMP_RF_IO_WRITE32(pAd, R3);
-
- R1 = RFRegTable[index].R1;
- RTMP_RF_IO_WRITE32(pAd, R1);
-
- R2 = RFRegTable[index].R2;
- if (pAd->Antenna.field.TxPath == 1)
- {
- R2 |= 0x4000; // If TXpath is 1, bit 14 = 1;
- }
-
- if (pAd->Antenna.field.RxPath == 2)
- {
- R2 |= 0x40; // write 1 to off Rxpath.
- }
- else if (pAd->Antenna.field.RxPath == 1)
- {
- R2 |= 0x20040; // write 1 to off RxPath
- }
- RTMP_RF_IO_WRITE32(pAd, R2);
-
- break;
- }
- }
- break;
-
- default:
- break;
}
- DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n",
- Channel,
- pAd->RfIcType,
- R2));
}