2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 *************************************************************************
34 -------- ---------- ----------------------------------------------
35 John Chang 2004-08-25 Modify from RT2500 code base
36 John Chang 2004-09-06 modified for RT2600
39 #include "../rt_config.h"
42 UCHAR CISCO_OUI[] = {0x00, 0x40, 0x96};
44 UCHAR WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
45 UCHAR RSN_OUI[] = {0x00, 0x0f, 0xac};
46 UCHAR WAPI_OUI[] = {0x00, 0x14, 0x72};
47 UCHAR WME_INFO_ELEM[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
48 UCHAR WME_PARM_ELEM[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
49 UCHAR Ccx2QosInfo[] = {0x00, 0x40, 0x96, 0x04};
50 UCHAR RALINK_OUI[] = {0x00, 0x0c, 0x43};
51 UCHAR BROADCOM_OUI[] = {0x00, 0x90, 0x4c};
52 UCHAR WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
53 #ifdef CONFIG_STA_SUPPORT
54 #ifdef DOT11_N_SUPPORT
55 UCHAR PRE_N_HT_OUI[] = {0x00, 0x90, 0x4c};
56 #endif // DOT11_N_SUPPORT //
57 #endif // CONFIG_STA_SUPPORT //
59 UCHAR RateSwitchTable[] = {
60 // 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)
61 0x11, 0x00, 0, 0, 0, // Initial used item after association
62 0x00, 0x00, 0, 40, 101,
63 0x01, 0x00, 1, 40, 50,
64 0x02, 0x00, 2, 35, 45,
65 0x03, 0x00, 3, 20, 45,
66 0x04, 0x21, 0, 30, 50,
67 0x05, 0x21, 1, 20, 50,
68 0x06, 0x21, 2, 20, 50,
69 0x07, 0x21, 3, 15, 50,
70 0x08, 0x21, 4, 15, 30,
71 0x09, 0x21, 5, 10, 25,
74 0x0c, 0x20, 12, 15, 30,
75 0x0d, 0x20, 13, 8, 20,
76 0x0e, 0x20, 14, 8, 20,
77 0x0f, 0x20, 15, 8, 25,
78 0x10, 0x22, 15, 8, 25,
96 UCHAR RateSwitchTable11B[] = {
97 // 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)
98 0x04, 0x03, 0, 0, 0, // Initial used item after association
99 0x00, 0x00, 0, 40, 101,
100 0x01, 0x00, 1, 40, 50,
101 0x02, 0x00, 2, 35, 45,
102 0x03, 0x00, 3, 20, 45,
105 UCHAR RateSwitchTable11BG[] = {
106 // 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)
107 0x0a, 0x00, 0, 0, 0, // Initial used item after association
108 0x00, 0x00, 0, 40, 101,
109 0x01, 0x00, 1, 40, 50,
110 0x02, 0x00, 2, 35, 45,
111 0x03, 0x00, 3, 20, 45,
112 0x04, 0x10, 2, 20, 35,
113 0x05, 0x10, 3, 16, 35,
114 0x06, 0x10, 4, 10, 25,
115 0x07, 0x10, 5, 16, 25,
116 0x08, 0x10, 6, 10, 25,
117 0x09, 0x10, 7, 10, 13,
120 UCHAR RateSwitchTable11G[] = {
121 // 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)
122 0x08, 0x00, 0, 0, 0, // Initial used item after association
123 0x00, 0x10, 0, 20, 101,
124 0x01, 0x10, 1, 20, 35,
125 0x02, 0x10, 2, 20, 35,
126 0x03, 0x10, 3, 16, 35,
127 0x04, 0x10, 4, 10, 25,
128 0x05, 0x10, 5, 16, 25,
129 0x06, 0x10, 6, 10, 25,
130 0x07, 0x10, 7, 10, 13,
133 #ifdef DOT11_N_SUPPORT
134 UCHAR RateSwitchTable11N1S[] = {
135 // 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)
136 0x09, 0x00, 0, 0, 0, // Initial used item after association
137 0x00, 0x21, 0, 30, 101,
138 0x01, 0x21, 1, 20, 50,
139 0x02, 0x21, 2, 20, 50,
140 0x03, 0x21, 3, 15, 50,
141 0x04, 0x21, 4, 15, 30,
142 0x05, 0x21, 5, 10, 25,
143 0x06, 0x21, 6, 8, 14,
144 0x07, 0x21, 7, 8, 14,
145 0x08, 0x23, 7, 8, 14,
148 UCHAR RateSwitchTable11N2S[] = {
149 // 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)
150 0x0a, 0x00, 0, 0, 0, // Initial used item after association
151 0x00, 0x21, 0, 30, 101,
152 0x01, 0x21, 1, 20, 50,
153 0x02, 0x21, 2, 20, 50,
154 0x03, 0x21, 3, 15, 50,
155 0x04, 0x21, 4, 15, 30,
156 0x05, 0x20, 12, 15, 30,
157 0x06, 0x20, 13, 8, 20,
158 0x07, 0x20, 14, 8, 20,
159 0x08, 0x20, 15, 8, 25,
160 0x09, 0x22, 15, 8, 25,
163 UCHAR RateSwitchTable11N3S[] = {
164 // 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)
165 0x0a, 0x00, 0, 0, 0, // Initial used item after association
166 0x00, 0x21, 0, 30, 101,
167 0x01, 0x21, 1, 20, 50,
168 0x02, 0x21, 2, 20, 50,
169 0x03, 0x21, 3, 15, 50,
170 0x04, 0x21, 4, 15, 30,
171 0x05, 0x20, 12, 15, 30,
172 0x06, 0x20, 13, 8, 20,
173 0x07, 0x20, 14, 8, 20,
174 0x08, 0x20, 15, 8, 25,
175 0x09, 0x22, 15, 8, 25,
178 UCHAR RateSwitchTable11N2SForABand[] = {
179 // 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)
180 0x0b, 0x09, 0, 0, 0, // Initial used item after association
181 0x00, 0x21, 0, 30, 101,
182 0x01, 0x21, 1, 20, 50,
183 0x02, 0x21, 2, 20, 50,
184 0x03, 0x21, 3, 15, 50,
185 0x04, 0x21, 4, 15, 30,
186 0x05, 0x21, 5, 15, 30,
187 0x06, 0x20, 12, 15, 30,
188 0x07, 0x20, 13, 8, 20,
189 0x08, 0x20, 14, 8, 20,
190 0x09, 0x20, 15, 8, 25,
191 0x0a, 0x22, 15, 8, 25,
194 UCHAR RateSwitchTable11N3SForABand[] = { // 3*3
195 // 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)
196 0x0b, 0x09, 0, 0, 0, // Initial used item after association
197 0x00, 0x21, 0, 30, 101,
198 0x01, 0x21, 1, 20, 50,
199 0x02, 0x21, 2, 20, 50,
200 0x03, 0x21, 3, 15, 50,
201 0x04, 0x21, 4, 15, 30,
202 0x05, 0x21, 5, 15, 30,
203 0x06, 0x20, 12, 15, 30,
204 0x07, 0x20, 13, 8, 20,
205 0x08, 0x20, 14, 8, 20,
206 0x09, 0x20, 15, 8, 25,
207 0x0a, 0x22, 15, 8, 25,
210 UCHAR RateSwitchTable11BGN1S[] = {
211 // 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)
212 0x0d, 0x00, 0, 0, 0, // Initial used item after association
213 0x00, 0x00, 0, 40, 101,
214 0x01, 0x00, 1, 40, 50,
215 0x02, 0x00, 2, 35, 45,
216 0x03, 0x00, 3, 20, 45,
217 0x04, 0x21, 0, 30,101, //50
218 0x05, 0x21, 1, 20, 50,
219 0x06, 0x21, 2, 20, 50,
220 0x07, 0x21, 3, 15, 50,
221 0x08, 0x21, 4, 15, 30,
222 0x09, 0x21, 5, 10, 25,
223 0x0a, 0x21, 6, 8, 14,
224 0x0b, 0x21, 7, 8, 14,
225 0x0c, 0x23, 7, 8, 14,
228 UCHAR RateSwitchTable11BGN2S[] = {
229 // 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)
230 0x0a, 0x00, 0, 0, 0, // Initial used item after association
231 0x00, 0x21, 0, 30,101, //50
232 0x01, 0x21, 1, 20, 50,
233 0x02, 0x21, 2, 20, 50,
234 0x03, 0x21, 3, 15, 50,
235 0x04, 0x21, 4, 15, 30,
236 0x05, 0x20, 12, 15, 30,
237 0x06, 0x20, 13, 8, 20,
238 0x07, 0x20, 14, 8, 20,
239 0x08, 0x20, 15, 8, 25,
240 0x09, 0x22, 15, 8, 25,
243 UCHAR RateSwitchTable11BGN3S[] = { // 3*3
244 // 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)
245 0x0a, 0x00, 0, 0, 0, // Initial used item after association
246 0x00, 0x21, 0, 30,101, //50
247 0x01, 0x21, 1, 20, 50,
248 0x02, 0x21, 2, 20, 50,
249 0x03, 0x21, 3, 20, 50,
250 0x04, 0x21, 4, 15, 50,
251 0x05, 0x20, 20, 15, 30,
252 0x06, 0x20, 21, 8, 20,
253 0x07, 0x20, 22, 8, 20,
254 0x08, 0x20, 23, 8, 25,
255 0x09, 0x22, 23, 8, 25,
258 UCHAR RateSwitchTable11BGN2SForABand[] = {
259 // 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)
260 0x0b, 0x09, 0, 0, 0, // Initial used item after association
261 0x00, 0x21, 0, 30,101, //50
262 0x01, 0x21, 1, 20, 50,
263 0x02, 0x21, 2, 20, 50,
264 0x03, 0x21, 3, 15, 50,
265 0x04, 0x21, 4, 15, 30,
266 0x05, 0x21, 5, 15, 30,
267 0x06, 0x20, 12, 15, 30,
268 0x07, 0x20, 13, 8, 20,
269 0x08, 0x20, 14, 8, 20,
270 0x09, 0x20, 15, 8, 25,
271 0x0a, 0x22, 15, 8, 25,
274 UCHAR RateSwitchTable11BGN3SForABand[] = { // 3*3
275 // 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)
276 0x0c, 0x09, 0, 0, 0, // Initial used item after association
277 0x00, 0x21, 0, 30,101, //50
278 0x01, 0x21, 1, 20, 50,
279 0x02, 0x21, 2, 20, 50,
280 0x03, 0x21, 3, 15, 50,
281 0x04, 0x21, 4, 15, 30,
282 0x05, 0x21, 5, 15, 30,
283 0x06, 0x21, 12, 15, 30,
284 0x07, 0x20, 20, 15, 30,
285 0x08, 0x20, 21, 8, 20,
286 0x09, 0x20, 22, 8, 20,
287 0x0a, 0x20, 23, 8, 25,
288 0x0b, 0x22, 23, 8, 25,
290 #endif // DOT11_N_SUPPORT //
292 PUCHAR ReasonString[] = {
294 /* 1 */ "Unspecified Reason",
295 /* 2 */ "Previous Auth no longer valid",
296 /* 3 */ "STA is leaving / has left",
297 /* 4 */ "DIS-ASSOC due to inactivity",
298 /* 5 */ "AP unable to hanle all associations",
299 /* 6 */ "class 2 error",
300 /* 7 */ "class 3 error",
301 /* 8 */ "STA is leaving / has left",
302 /* 9 */ "require auth before assoc/re-assoc",
306 /* 13 */ "invalid IE",
307 /* 14 */ "MIC error",
308 /* 15 */ "4-way handshake timeout",
309 /* 16 */ "2-way (group key) handshake timeout",
310 /* 17 */ "4-way handshake IE diff among AssosReq/Rsp/Beacon",
314 extern UCHAR OfdmRateToRxwiMCS[];
315 // since RT61 has better RX sensibility, we have to limit TX ACK rate not to exceed our normal data TX rate.
316 // otherwise the WLAN peer may not be able to receive the ACK thus downgrade its data TX rate
317 ULONG BasicRateMask[12] = {0xfffff001 /* 1-Mbps */, 0xfffff003 /* 2 Mbps */, 0xfffff007 /* 5.5 */, 0xfffff00f /* 11 */,
318 0xfffff01f /* 6 */ , 0xfffff03f /* 9 */ , 0xfffff07f /* 12 */ , 0xfffff0ff /* 18 */,
319 0xfffff1ff /* 24 */ , 0xfffff3ff /* 36 */ , 0xfffff7ff /* 48 */ , 0xffffffff /* 54 */};
321 UCHAR MULTICAST_ADDR[MAC_ADDR_LEN] = {0x1, 0x00, 0x00, 0x00, 0x00, 0x00};
322 UCHAR BROADCAST_ADDR[MAC_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
323 UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
325 // e.g. RssiSafeLevelForTxRate[RATE_36]" means if the current RSSI is greater than
326 // this value, then it's quaranteed capable of operating in 36 mbps TX rate in
327 // clean environment.
328 // TxRate: 1 2 5.5 11 6 9 12 18 24 36 48 54 72 100
329 CHAR RssiSafeLevelForTxRate[] ={ -92, -91, -90, -87, -88, -86, -85, -83, -81, -78, -72, -71, -40, -40 };
331 UCHAR RateIdToMbps[] = { 1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 72, 100};
332 USHORT RateIdTo500Kbps[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 144, 200};
334 UCHAR SsidIe = IE_SSID;
335 UCHAR SupRateIe = IE_SUPP_RATES;
336 UCHAR ExtRateIe = IE_EXT_SUPP_RATES;
337 #ifdef DOT11_N_SUPPORT
338 UCHAR HtCapIe = IE_HT_CAP;
339 UCHAR AddHtInfoIe = IE_ADD_HT;
340 UCHAR NewExtChanIe = IE_SECONDARY_CH_OFFSET;
342 UCHAR ExtHtCapIe = IE_EXT_CAPABILITY;
343 #endif // DOT11N_DRAFT3 //
344 #endif // DOT11_N_SUPPORT //
345 UCHAR ErpIe = IE_ERP;
346 UCHAR DsIe = IE_DS_PARM;
347 UCHAR TimIe = IE_TIM;
348 UCHAR WpaIe = IE_WPA;
349 UCHAR Wpa2Ie = IE_WPA2;
350 UCHAR IbssIe = IE_IBSS_PARM;
351 UCHAR Ccx2Ie = IE_CCX_V2;
353 extern UCHAR WPA_OUI[];
355 UCHAR SES_OUI[] = {0x00, 0x90, 0x4c};
357 UCHAR ZeroSsid[32] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
358 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
360 // Reset the RFIC setting to new series
361 RTMP_RF_REGS RF2850RegTable[] = {
362 // ch R1 R2 R3(TX0~4=0) R4
363 {1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b},
364 {2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f},
365 {3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b},
366 {4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f},
367 {5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b},
368 {6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f},
369 {7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b},
370 {8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f},
371 {9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b},
372 {10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f},
373 {11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b},
374 {12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f},
375 {13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b},
376 {14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193},
378 // 802.11 UNI / HyperLan 2
379 {36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3},
380 {38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193},
381 {40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183},
382 {44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3},
383 {46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b},
384 {48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b},
385 {52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193},
386 {54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3},
387 {56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b},
388 {60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183},
389 {62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193},
390 {64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3}, // Plugfest#4, Day4, change RFR3 left4th 9->5.
393 {100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783},
395 // 2008.04.30 modified
396 // The system team has AN to improve the EVM value
397 // for channel 102 to 108 for the RT2850/RT2750 dual band solution.
398 {102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793},
399 {104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3},
400 {108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193},
402 {110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183},
403 {112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b},
404 {116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3},
405 {118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193},
406 {120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183},
407 {124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193},
408 {126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}, // 0x980ed1bb->0x980ed15b required by Rory 20070927
409 {128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3},
410 {132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b},
411 {134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193},
412 {136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b},
413 {140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183},
416 {149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7},
417 {151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187},
418 {153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f},
419 {157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f},
420 {159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7},
421 {161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187},
422 {165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197},
425 {184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b},
426 {188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13},
427 {192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b},
428 {196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23},
429 {208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13},
430 {212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b},
431 {216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23},
433 // still lack of MMAC(Japan) ch 34,38,42,46
435 UCHAR NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(RTMP_RF_REGS));
437 FREQUENCY_ITEM FreqItems3020[] =
439 /**************************************************/
440 // ISM : 2.4 to 2.483 GHz //
441 /**************************************************/
443 /**************************************************/
444 //-CH---N-------R---K-----------
460 #define NUM_OF_3020_CHNL (sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM))
463 ==========================================================================
465 initialize the MLME task and its data structure (queue, spinlock,
466 timer, state machines).
471 always return NDIS_STATUS_SUCCESS
473 ==========================================================================
475 NDIS_STATUS MlmeInit(
476 IN PRTMP_ADAPTER pAd)
478 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
480 DBGPRINT(RT_DEBUG_TRACE, ("--> MLME Initialize\n"));
484 Status = MlmeQueueInit(&pAd->Mlme.Queue);
485 if(Status != NDIS_STATUS_SUCCESS)
488 pAd->Mlme.bRunning = FALSE;
489 NdisAllocateSpinLock(&pAd->Mlme.TaskLock);
491 #ifdef CONFIG_STA_SUPPORT
492 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
494 BssTableInit(&pAd->ScanTab);
496 // init STA state machines
497 AssocStateMachineInit(pAd, &pAd->Mlme.AssocMachine, pAd->Mlme.AssocFunc);
498 AuthStateMachineInit(pAd, &pAd->Mlme.AuthMachine, pAd->Mlme.AuthFunc);
499 AuthRspStateMachineInit(pAd, &pAd->Mlme.AuthRspMachine, pAd->Mlme.AuthRspFunc);
500 SyncStateMachineInit(pAd, &pAd->Mlme.SyncMachine, pAd->Mlme.SyncFunc);
501 WpaPskStateMachineInit(pAd, &pAd->Mlme.WpaPskMachine, pAd->Mlme.WpaPskFunc);
502 AironetStateMachineInit(pAd, &pAd->Mlme.AironetMachine, pAd->Mlme.AironetFunc);
504 #ifdef QOS_DLS_SUPPORT
505 DlsStateMachineInit(pAd, &pAd->Mlme.DlsMachine, pAd->Mlme.DlsFunc);
506 #endif // QOS_DLS_SUPPORT //
509 // Since we are using switch/case to implement it, the init is different from the above
510 // state machine init
511 MlmeCntlInit(pAd, &pAd->Mlme.CntlMachine, NULL);
513 #endif // CONFIG_STA_SUPPORT //
517 ActionStateMachineInit(pAd, &pAd->Mlme.ActMachine, pAd->Mlme.ActFunc);
519 // Init mlme periodic timer
520 RTMPInitTimer(pAd, &pAd->Mlme.PeriodicTimer, GET_TIMER_FUNCTION(MlmePeriodicExec), pAd, TRUE);
522 // Set mlme periodic timer
523 RTMPSetTimer(&pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
525 // software-based RX Antenna diversity
526 RTMPInitTimer(pAd, &pAd->Mlme.RxAntEvalTimer, GET_TIMER_FUNCTION(AsicRxAntEvalTimeout), pAd, FALSE);
529 #ifdef CONFIG_STA_SUPPORT
530 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
532 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
534 // only PCIe cards need these two timers
535 RTMPInitTimer(pAd, &pAd->Mlme.PsPollTimer, GET_TIMER_FUNCTION(PsPollWakeExec), pAd, FALSE);
536 RTMPInitTimer(pAd, &pAd->Mlme.RadioOnOffTimer, GET_TIMER_FUNCTION(RadioOnExec), pAd, FALSE);
539 #endif // CONFIG_STA_SUPPORT //
543 DBGPRINT(RT_DEBUG_TRACE, ("<-- MLME Initialize\n"));
549 ==========================================================================
551 main loop of the MLME
553 Mlme has to be initialized, and there are something inside the queue
555 This function is invoked from MPSetInformation and MPReceive;
556 This task guarantee only one MlmeHandler will run.
558 IRQL = DISPATCH_LEVEL
560 ==========================================================================
563 IN PRTMP_ADAPTER pAd)
565 MLME_QUEUE_ELEM *Elem = NULL;
570 // Only accept MLME and Frame from peer side, no other (control/data) frame should
571 // get into this state machine
573 NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
574 if(pAd->Mlme.bRunning)
576 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
581 pAd->Mlme.bRunning = TRUE;
583 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
585 while (!MlmeQueueEmpty(&pAd->Mlme.Queue))
587 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS) ||
588 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
589 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
591 DBGPRINT(RT_DEBUG_TRACE, ("Device Halted or Removed or MlmeRest, exit MlmeHandler! (queue num = %ld)\n", pAd->Mlme.Queue.Num));
598 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now in MlmeHandler\n"));
601 #endif // RALINK_ATE //
603 //From message type, determine which state machine I should drive
604 if (MlmeDequeue(&pAd->Mlme.Queue, &Elem))
607 // if dequeue success
608 switch (Elem->Machine)
610 // STA state machines
611 #ifdef CONFIG_STA_SUPPORT
612 case ASSOC_STATE_MACHINE:
613 StateMachinePerformAction(pAd, &pAd->Mlme.AssocMachine, Elem);
615 case AUTH_STATE_MACHINE:
616 StateMachinePerformAction(pAd, &pAd->Mlme.AuthMachine, Elem);
618 case AUTH_RSP_STATE_MACHINE:
619 StateMachinePerformAction(pAd, &pAd->Mlme.AuthRspMachine, Elem);
621 case SYNC_STATE_MACHINE:
622 StateMachinePerformAction(pAd, &pAd->Mlme.SyncMachine, Elem);
624 case MLME_CNTL_STATE_MACHINE:
625 MlmeCntlMachinePerformAction(pAd, &pAd->Mlme.CntlMachine, Elem);
627 case WPA_PSK_STATE_MACHINE:
628 StateMachinePerformAction(pAd, &pAd->Mlme.WpaPskMachine, Elem);
631 case LEAP_STATE_MACHINE:
632 LeapMachinePerformAction(pAd, &pAd->Mlme.LeapMachine, Elem);
635 case AIRONET_STATE_MACHINE:
636 StateMachinePerformAction(pAd, &pAd->Mlme.AironetMachine, Elem);
639 #ifdef QOS_DLS_SUPPORT
640 case DLS_STATE_MACHINE:
641 StateMachinePerformAction(pAd, &pAd->Mlme.DlsMachine, Elem);
643 #endif // QOS_DLS_SUPPORT //
644 #endif // CONFIG_STA_SUPPORT //
646 case ACTION_STATE_MACHINE:
647 StateMachinePerformAction(pAd, &pAd->Mlme.ActMachine, Elem);
654 DBGPRINT(RT_DEBUG_TRACE, ("ERROR: Illegal machine %ld in MlmeHandler()\n", Elem->Machine));
659 Elem->Occupied = FALSE;
664 DBGPRINT_ERR(("MlmeHandler: MlmeQueue empty\n"));
668 NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
669 pAd->Mlme.bRunning = FALSE;
670 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
674 ==========================================================================
676 Destructor of MLME (Destroy queue, state machine, spin lock and timer)
678 Adapter - NIC Adapter pointer
680 The MLME task will no longer work properly
684 ==========================================================================
687 IN PRTMP_ADAPTER pAd)
691 DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeHalt\n"));
693 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
695 // disable BEACON generation and other BEACON related hardware timers
696 AsicDisableSync(pAd);
699 #ifdef CONFIG_STA_SUPPORT
700 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
702 #ifdef QOS_DLS_SUPPORT
704 #endif // QOS_DLS_SUPPORT //
705 // Cancel pending timers
706 RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
707 RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
708 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
709 RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
710 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
711 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
712 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
714 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
715 RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled);
718 #ifdef QOS_DLS_SUPPORT
719 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
721 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &Cancelled);
723 #endif // QOS_DLS_SUPPORT //
725 #endif // CONFIG_STA_SUPPORT //
727 RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);
728 RTMPCancelTimer(&pAd->Mlme.RxAntEvalTimer, &Cancelled);
732 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
735 RTMPSetLED(pAd, LED_HALT);
736 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
739 RTMPusecDelay(5000); // 5 msec to gurantee Ant Diversity timer canceled
741 MlmeQueueDestroy(&pAd->Mlme.Queue);
742 NdisFreeSpinLock(&pAd->Mlme.TaskLock);
744 DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeHalt\n"));
747 VOID MlmeResetRalinkCounters(
748 IN PRTMP_ADAPTER pAd)
750 pAd->RalinkCounters.LastOneSecRxOkDataCnt = pAd->RalinkCounters.OneSecRxOkDataCnt;
751 // clear all OneSecxxx counters.
752 pAd->RalinkCounters.OneSecBeaconSentCnt = 0;
753 pAd->RalinkCounters.OneSecFalseCCACnt = 0;
754 pAd->RalinkCounters.OneSecRxFcsErrCnt = 0;
755 pAd->RalinkCounters.OneSecRxOkCnt = 0;
756 pAd->RalinkCounters.OneSecTxFailCount = 0;
757 pAd->RalinkCounters.OneSecTxNoRetryOkCount = 0;
758 pAd->RalinkCounters.OneSecTxRetryOkCount = 0;
759 pAd->RalinkCounters.OneSecRxOkDataCnt = 0;
761 // TODO: for debug only. to be removed
762 pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BE] = 0;
763 pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BK] = 0;
764 pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VI] = 0;
765 pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VO] = 0;
766 pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BE] = 0;
767 pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BK] = 0;
768 pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VI] = 0;
769 pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VO] = 0;
770 pAd->RalinkCounters.OneSecTxDoneCount = 0;
771 pAd->RalinkCounters.OneSecRxCount = 0;
772 pAd->RalinkCounters.OneSecTxAggregationCount = 0;
773 pAd->RalinkCounters.OneSecRxAggregationCount = 0;
778 unsigned long rx_AMSDU;
779 unsigned long rx_Total;
782 ==========================================================================
784 This routine is executed periodically to -
785 1. Decide if it's a right time to turn on PwrMgmt bit of all
787 2. Calculate ChannelQuality based on statistics of the last
788 period, so that TX rate won't toggling very frequently between a
789 successful TX and a failed TX.
790 3. If the calculated ChannelQuality indicated current connection not
791 healthy, then a ROAMing attempt is tried here.
793 IRQL = DISPATCH_LEVEL
795 ==========================================================================
797 #define ADHOC_BEACON_LOST_TIME (8*OS_HZ) // 8 sec
798 VOID MlmePeriodicExec(
799 IN PVOID SystemSpecific1,
800 IN PVOID FunctionContext,
801 IN PVOID SystemSpecific2,
802 IN PVOID SystemSpecific3)
805 PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
808 //printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus));
809 //If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0.
810 //If the STA security setting is WPAPSK or WPA2PSK, pAd->StaCfg.WpaSupplicantUP = 1.
811 if(pAd->StaCfg.WepStatus<2)
813 pAd->StaCfg.WpaSupplicantUP = 0;
817 pAd->StaCfg.WpaSupplicantUP = 1;
820 #ifdef CONFIG_STA_SUPPORT
821 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
823 // If Hardware controlled Radio enabled, we have to check GPIO pin2 every 2 second.
824 // Move code to here, because following code will return when radio is off
825 if ((pAd->Mlme.PeriodicRound % (MLME_TASK_EXEC_MULTIPLE * 2) == 0) &&
826 (pAd->StaCfg.bHardwareRadio == TRUE) &&
827 (RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP)) &&
828 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
829 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
833 // Read GPIO pin2 as Hardware controlled radio state
834 RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data);
837 pAd->StaCfg.bHwRadio = TRUE;
841 pAd->StaCfg.bHwRadio = FALSE;
843 if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
845 pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
846 if (pAd->StaCfg.bRadio == TRUE)
849 // Update extra information
850 pAd->ExtraInfo = EXTRA_INFO_CLEAR;
855 // Update extra information
856 pAd->ExtraInfo = HW_RADIO_OFF;
861 #endif // CONFIG_STA_SUPPORT //
863 // Do nothing if the driver is starting halt state.
864 // This might happen when timer already been fired before cancel timer with mlmehalt
865 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_HALT_IN_PROGRESS |
866 fRTMP_ADAPTER_RADIO_OFF |
867 fRTMP_ADAPTER_RADIO_MEASUREMENT |
868 fRTMP_ADAPTER_RESET_IN_PROGRESS))))
871 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
873 if ((pAd->RalinkCounters.LastReceivedByteCount == pAd->RalinkCounters.ReceivedByteCount) && (pAd->StaCfg.bRadio == TRUE))
875 // If ReceiveByteCount doesn't change, increase SameRxByteCount by 1.
876 pAd->SameRxByteCount++;
879 pAd->SameRxByteCount = 0;
881 // If after BBP, still not work...need to check to reset PBF&MAC.
882 if (pAd->SameRxByteCount == 702)
884 pAd->SameRxByteCount = 0;
889 // If SameRxByteCount keeps happens for 2 second in infra mode, or for 60 seconds in idle mode.
890 if (((INFRA_ON(pAd)) && (pAd->SameRxByteCount > 20)) || ((IDLE_ON(pAd)) && (pAd->SameRxByteCount > 600)))
892 if ((pAd->StaCfg.bRadio == TRUE) && (pAd->SameRxByteCount < 700))
894 DBGPRINT(RT_DEBUG_TRACE, ("---> SameRxByteCount = %lu !!!!!!!!!!!!!!! \n", pAd->SameRxByteCount));
895 pAd->SameRxByteCount = 700;
900 // Update lastReceiveByteCount.
901 pAd->RalinkCounters.LastReceivedByteCount = pAd->RalinkCounters.ReceivedByteCount;
903 if ((pAd->CheckDmaBusyCount > 3) && (IDLE_ON(pAd)))
905 pAd->CheckDmaBusyCount = 0;
906 AsicResetFromDMABusy(pAd);
910 RT28XX_MLME_PRE_SANITY_CHECK(pAd);
913 /* Do not show RSSI until "Normal 1 second Mlme PeriodicExec". */
916 if (pAd->Mlme.PeriodicRound % MLME_TASK_EXEC_MULTIPLE != (MLME_TASK_EXEC_MULTIPLE - 1))
918 pAd->Mlme.PeriodicRound ++;
922 #endif // RALINK_ATE //
924 #ifdef CONFIG_STA_SUPPORT
925 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
927 // Do nothing if monitor mode is on
931 if (pAd->Mlme.PeriodicRound & 0x1)
933 // This is the fix for wifi 11n extension channel overlapping test case. for 2860D
934 if (((pAd->MACVersion & 0xffff) == 0x0101) &&
935 (STA_TGN_WIFI_ON(pAd)) &&
936 (pAd->CommonCfg.IOTestParm.bToggle == FALSE))
939 RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x24Bf);
940 pAd->CommonCfg.IOTestParm.bToggle = TRUE;
942 else if ((STA_TGN_WIFI_ON(pAd)) &&
943 ((pAd->MACVersion & 0xffff) == 0x0101))
945 RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x243f);
946 pAd->CommonCfg.IOTestParm.bToggle = FALSE;
950 #endif // CONFIG_STA_SUPPORT //
952 pAd->bUpdateBcnCntDone = FALSE;
954 // RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3);
955 pAd->Mlme.PeriodicRound ++;
957 // execute every 500ms
958 if ((pAd->Mlme.PeriodicRound % 5 == 0) && RTMPAutoRateSwitchCheck(pAd)/*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))*/)
960 #ifdef CONFIG_STA_SUPPORT
961 // perform dynamic tx rate switching based on past TX history
962 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
964 if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
966 && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)))
967 MlmeDynamicTxRateSwitching(pAd);
969 #endif // CONFIG_STA_SUPPORT //
972 // Normal 1 second Mlme PeriodicExec.
973 if (pAd->Mlme.PeriodicRound %MLME_TASK_EXEC_MULTIPLE == 0)
975 pAd->Mlme.OneSecPeriodicRound ++;
980 /* request from Baron : move this routine from later to here */
981 /* for showing Rx error count in ATE RXFRAME */
982 NICUpdateRawCounters(pAd);
983 if (pAd->ate.bRxFer == 1)
985 pAd->ate.RxTotalCnt += pAd->ate.RxCntPerSec;
986 ate_print(KERN_EMERG "MlmePeriodicExec: Rx packet cnt = %d/%d\n", pAd->ate.RxCntPerSec, pAd->ate.RxTotalCnt);
987 pAd->ate.RxCntPerSec = 0;
989 if (pAd->ate.RxAntennaSel == 0)
990 ate_print(KERN_EMERG "MlmePeriodicExec: Rx AvgRssi0=%d, AvgRssi1=%d, AvgRssi2=%d\n\n",
991 pAd->ate.AvgRssi0, pAd->ate.AvgRssi1, pAd->ate.AvgRssi2);
993 ate_print(KERN_EMERG "MlmePeriodicExec: Rx AvgRssi=%d\n\n", pAd->ate.AvgRssi0);
995 MlmeResetRalinkCounters(pAd);
998 #endif // RALINK_ATE //
1009 // Media status changed, report to NDIS
1010 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE))
1012 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
1013 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1015 pAd->IndicateMediaState = NdisMediaStateConnected;
1016 RTMP_IndicateMediaState(pAd);
1021 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1022 RTMP_IndicateMediaState(pAd);
1026 NdisGetSystemUpTime(&pAd->Mlme.Now32);
1028 // add the most up-to-date h/w raw counters into software variable, so that
1029 // the dynamic tuning mechanism below are based on most up-to-date information
1030 NICUpdateRawCounters(pAd);
1033 #ifdef DOT11_N_SUPPORT
1034 // Need statistics after read counter. So put after NICUpdateRawCounters
1035 ORIBATimerTimeout(pAd);
1036 #endif // DOT11_N_SUPPORT //
1039 // The time period for checking antenna is according to traffic
1040 if (pAd->Mlme.bEnableAutoAntennaCheck)
1042 TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
1043 pAd->RalinkCounters.OneSecTxRetryOkCount +
1044 pAd->RalinkCounters.OneSecTxFailCount;
1046 if (TxTotalCnt > 50)
1048 if (pAd->Mlme.OneSecPeriodicRound % 10 == 0)
1050 AsicEvaluateRxAnt(pAd);
1055 if (pAd->Mlme.OneSecPeriodicRound % 3 == 0)
1057 AsicEvaluateRxAnt(pAd);
1062 #ifdef CONFIG_STA_SUPPORT
1063 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1064 STAMlmePeriodicExec(pAd);
1065 #endif // CONFIG_STA_SUPPORT //
1067 MlmeResetRalinkCounters(pAd);
1069 #ifdef CONFIG_STA_SUPPORT
1070 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1072 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->bPCIclkOff == FALSE))
1074 // When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock
1075 // and sending CTS-to-self over and over.
1076 // Software Patch Solution:
1077 // 1. Polling debug state register 0x10F4 every one second.
1078 // 2. If in 0x10F4 the ((bit29==1) && (bit7==1)) OR ((bit29==1) && (bit5==1)), it means the deadlock has occurred.
1079 // 3. If the deadlock occurred, reset MAC/BBP by setting 0x1004 to 0x0001 for a while then setting it back to 0x000C again.
1083 RTMP_IO_READ32(pAd, 0x10F4, &MacReg);
1084 if (((MacReg & 0x20000000) && (MacReg & 0x80)) || ((MacReg & 0x20000000) && (MacReg & 0x20)))
1086 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
1088 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xC);
1090 DBGPRINT(RT_DEBUG_WARN,("Warning, MAC specific condition occurs \n"));
1094 #endif // CONFIG_STA_SUPPORT //
1096 RT28XX_MLME_HANDLER(pAd);
1100 pAd->bUpdateBcnCntDone = FALSE;
1103 #ifdef CONFIG_STA_SUPPORT
1104 VOID STAMlmePeriodicExec(
1110 // We return here in ATE mode, because the statistics
1111 // that ATE needs are not collected via this routine.
1114 // It is supposed that we will never reach here in ATE mode.
1115 ASSERT(!(ATE_ON(pAd)));
1118 #endif // RALINK_ATE //
1120 #ifdef WPA_SUPPLICANT_SUPPORT
1121 if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)
1122 #endif // WPA_SUPPLICANT_SUPPORT //
1124 // WPA MIC error should block association attempt for 60 seconds
1125 if (pAd->StaCfg.bBlockAssoc && (pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ) < pAd->Mlme.Now32))
1126 pAd->StaCfg.bBlockAssoc = FALSE;
1130 //printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus));
1131 //If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0.
1132 //If the STA security setting is WPAPSK or WPA2PSK, pAd->StaCfg.WpaSupplicantUP = 1.
1133 if(pAd->StaCfg.WepStatus<2)
1135 pAd->StaCfg.WpaSupplicantUP = 0;
1139 pAd->StaCfg.WpaSupplicantUP = 1;
1142 if ((pAd->PreMediaState != pAd->IndicateMediaState) && (pAd->CommonCfg.bWirelessEvent))
1144 if (pAd->IndicateMediaState == NdisMediaStateConnected)
1146 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1148 pAd->PreMediaState = pAd->IndicateMediaState;
1151 if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd)) &&
1152 (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
1153 (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE) &&
1154 (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
1155 (RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP)) &&
1156 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
1158 RT28xxPciAsicRadioOff(pAd, GUI_IDLE_POWER_SAVE, 0);
1163 AsicStaBbpTuning(pAd);
1165 TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
1166 pAd->RalinkCounters.OneSecTxRetryOkCount +
1167 pAd->RalinkCounters.OneSecTxFailCount;
1169 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1171 // update channel quality for Roaming and UI LinkQuality display
1172 MlmeCalculateChannelQuality(pAd, pAd->Mlme.Now32);
1175 // must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if
1176 // Radio is currently in noisy environment
1177 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1178 AsicAdjustTxPower(pAd);
1182 #ifdef QOS_DLS_SUPPORT
1183 // Check DLS time out, then tear down those session
1184 RTMPCheckDLSTimeOut(pAd);
1185 #endif // QOS_DLS_SUPPORT //
1187 // Is PSM bit consistent with user power management policy?
1188 // This is the only place that will set PSM bit ON.
1189 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
1190 MlmeCheckPsmChange(pAd, pAd->Mlme.Now32);
1192 pAd->RalinkCounters.LastOneSecTotalTxCount = TxTotalCnt;
1194 if ((pAd->StaCfg.LastBeaconRxTime + 1*OS_HZ < pAd->Mlme.Now32) &&
1195 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
1196 ((TxTotalCnt + pAd->RalinkCounters.OneSecRxOkCnt < 600)))
1198 RTMPSetAGCInitValue(pAd, BW_20);
1199 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n", (0x2E + GET_LNA_GAIN(pAd))));
1203 if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable)
1205 // When APSD is enabled, the period changes as 20 sec
1206 if ((pAd->Mlme.OneSecPeriodicRound % 20) == 8)
1207 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
1211 // Send out a NULL frame every 10 sec to inform AP that STA is still alive (Avoid being age out)
1212 if ((pAd->Mlme.OneSecPeriodicRound % 10) == 8)
1214 if (pAd->CommonCfg.bWmmCapable)
1215 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
1217 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
1222 if (CQI_IS_DEAD(pAd->Mlme.ChannelQuality))
1224 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
1225 pAd->StaCfg.CCXAdjacentAPReportFlag = TRUE;
1226 pAd->StaCfg.CCXAdjacentAPLinkDownTime = pAd->StaCfg.LastBeaconRxTime;
1228 // Lost AP, send disconnect & link down event
1229 LinkDown(pAd, FALSE);
1231 #ifdef WPA_SUPPLICANT_SUPPORT
1232 #ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1233 if (pAd->StaCfg.WpaSupplicantUP)
1235 union iwreq_data wrqu;
1236 //send disassociate event to wpa_supplicant
1237 memset(&wrqu, 0, sizeof(wrqu));
1238 wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
1239 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
1241 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1242 #endif // WPA_SUPPLICANT_SUPPORT //
1244 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1246 union iwreq_data wrqu;
1247 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
1248 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
1250 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1252 MlmeAutoReconnectLastSSID(pAd);
1254 else if (CQI_IS_BAD(pAd->Mlme.ChannelQuality))
1256 pAd->RalinkCounters.BadCQIAutoRecoveryCount ++;
1257 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Bad CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
1258 MlmeAutoReconnectLastSSID(pAd);
1261 // Add auto seamless roaming
1262 if (pAd->StaCfg.bFastRoaming)
1264 SHORT dBmToRoam = (SHORT)pAd->StaCfg.dBmToRoam;
1266 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));
1268 if (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) <= (CHAR)dBmToRoam)
1270 MlmeCheckForFastRoaming(pAd, pAd->Mlme.Now32);
1274 else if (ADHOC_ON(pAd))
1276 // 2003-04-17 john. this is a patch that driver forces a BEACON out if ASIC fails
1277 // the "TX BEACON competition" for the entire past 1 sec.
1278 // So that even when ASIC's BEACONgen engine been blocked
1279 // by peer's BEACON due to slower system clock, this STA still can send out
1280 // minimum BEACON to tell the peer I'm alive.
1281 // drawback is that this BEACON won't be well aligned at TBTT boundary.
1282 // EnqueueBeaconFrame(pAd); // software send BEACON
1284 // if all 11b peers leave this BSS more than 5 seconds, update Tx rate,
1285 // restore outgoing BEACON to support B/G-mixed mode
1286 if ((pAd->CommonCfg.Channel <= 14) &&
1287 (pAd->CommonCfg.MaxTxRate <= RATE_11) &&
1288 (pAd->CommonCfg.MaxDesiredRate > RATE_11) &&
1289 ((pAd->StaCfg.Last11bBeaconRxTime + 5*OS_HZ) < pAd->Mlme.Now32))
1291 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - last 11B peer left, update Tx rates\n"));
1292 NdisMoveMemory(pAd->StaActive.SupRate, pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
1293 pAd->StaActive.SupRateLen = pAd->CommonCfg.SupRateLen;
1294 MlmeUpdateTxRates(pAd, FALSE, 0);
1295 MakeIbssBeacon(pAd); // re-build BEACON frame
1296 AsicEnableIbssSync(pAd); // copy to on-chip memory
1297 pAd->StaCfg.AdhocBOnlyJoined = FALSE;
1300 #ifdef DOT11_N_SUPPORT
1301 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
1303 if ((pAd->StaCfg.AdhocBGJoined) &&
1304 ((pAd->StaCfg.Last11gBeaconRxTime + 5 * OS_HZ) < pAd->Mlme.Now32))
1306 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - last 11G peer left\n"));
1307 pAd->StaCfg.AdhocBGJoined = FALSE;
1310 if ((pAd->StaCfg.Adhoc20NJoined) &&
1311 ((pAd->StaCfg.Last20NBeaconRxTime + 5 * OS_HZ) < pAd->Mlme.Now32))
1313 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - last 20MHz N peer left\n"));
1314 pAd->StaCfg.Adhoc20NJoined = FALSE;
1317 #endif // DOT11_N_SUPPORT //
1320 if ((pAd->CommonCfg.Channel > 14)
1321 && (pAd->CommonCfg.bIEEE80211H == 1)
1322 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1324 RadarDetectPeriodic(pAd);
1327 // If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState
1328 // to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can
1330 if ((pAd->StaCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32) &&
1331 OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1333 MLME_START_REQ_STRUCT StartReq;
1335 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n"));
1336 LinkDown(pAd, FALSE);
1338 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
1339 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
1340 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
1343 else // no INFRA nor ADHOC connection
1346 if (pAd->StaCfg.bScanReqIsFromWebUI &&
1347 ((pAd->StaCfg.LastScanTime + 30 * OS_HZ) > pAd->Mlme.Now32))
1348 goto SKIP_AUTO_SCAN_CONN;
1350 pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
1352 if ((pAd->StaCfg.bAutoReconnect == TRUE)
1353 && RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)
1354 && (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
1356 if ((pAd->ScanTab.BssNr==0) && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE))
1358 MLME_SCAN_REQ_STRUCT ScanReq;
1360 if ((pAd->StaCfg.LastScanTime + 10 * OS_HZ) < pAd->Mlme.Now32)
1362 DBGPRINT(RT_DEBUG_TRACE, ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, start a new ACTIVE scan SSID[%s]\n", pAd->MlmeAux.AutoReconnectSsid));
1363 ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen, BSS_ANY, SCAN_ACTIVE);
1364 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
1365 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
1366 // Reset Missed scan number
1367 pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
1369 else if (pAd->StaCfg.BssType == BSS_ADHOC) // Quit the forever scan when in a very clean room
1370 MlmeAutoReconnectLastSSID(pAd);
1372 else if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1374 if ((pAd->Mlme.OneSecPeriodicRound % 7) == 0)
1377 pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
1381 #ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
1382 if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
1384 if ((pAd->Mlme.OneSecPeriodicRound % 5) == 1)
1385 MlmeAutoReconnectLastSSID(pAd);
1388 #endif // CARRIER_DETECTION_SUPPORT //
1389 MlmeAutoReconnectLastSSID(pAd);
1395 SKIP_AUTO_SCAN_CONN:
1397 #ifdef DOT11_N_SUPPORT
1398 if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap !=0) && (pAd->MacTab.fAnyBASession == FALSE))
1400 pAd->MacTab.fAnyBASession = TRUE;
1401 AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, FALSE, FALSE);
1403 else if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap ==0) && (pAd->MacTab.fAnyBASession == TRUE))
1405 pAd->MacTab.fAnyBASession = FALSE;
1406 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1408 #endif // DOT11_N_SUPPORT //
1411 #ifdef DOT11_N_SUPPORT
1412 #ifdef DOT11N_DRAFT3
1413 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SCAN_2040))
1414 TriEventCounterMaintenance(pAd);
1415 #endif // DOT11N_DRAFT3 //
1416 #endif // DOT11_N_SUPPORT //
1423 IN PVOID SystemSpecific1,
1424 IN PVOID FunctionContext,
1425 IN PVOID SystemSpecific2,
1426 IN PVOID SystemSpecific3)
1429 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
1431 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1432 RTMP_IndicateMediaState(pAd);
1433 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1436 // IRQL = DISPATCH_LEVEL
1438 IN PRTMP_ADAPTER pAd)
1440 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1441 if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1443 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Driver auto scan\n"));
1445 MLME_CNTL_STATE_MACHINE,
1446 OID_802_11_BSSID_LIST_SCAN,
1449 RT28XX_MLME_HANDLER(pAd);
1453 // IRQL = DISPATCH_LEVEL
1454 VOID MlmeAutoReconnectLastSSID(
1455 IN PRTMP_ADAPTER pAd)
1459 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1460 if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
1461 (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
1463 NDIS_802_11_SSID OidSsid;
1464 OidSsid.SsidLength = pAd->MlmeAux.AutoReconnectSsidLen;
1465 NdisMoveMemory(OidSsid.Ssid, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
1467 DBGPRINT(RT_DEBUG_TRACE, ("Driver auto reconnect to last OID_802_11_SSID setting - %s, len - %d\n", pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen));
1469 MLME_CNTL_STATE_MACHINE,
1471 sizeof(NDIS_802_11_SSID),
1473 RT28XX_MLME_HANDLER(pAd);
1476 #endif // CONFIG_STA_SUPPORT //
1479 ==========================================================================
1480 Validate SSID for connection try and rescan purpose
1481 Valid SSID will have visible chars only.
1482 The valid length is from 0 to 32.
1483 IRQL = DISPATCH_LEVEL
1484 ==========================================================================
1486 BOOLEAN MlmeValidateSSID(
1492 if (SsidLen > MAX_LEN_OF_SSID)
1495 // Check each character value
1496 for (index = 0; index < SsidLen; index++)
1498 if (pSsid[index] < 0x20)
1506 VOID MlmeSelectTxRateTable(
1507 IN PRTMP_ADAPTER pAd,
1508 IN PMAC_TABLE_ENTRY pEntry,
1510 IN PUCHAR pTableSize,
1511 IN PUCHAR pInitTxRateIdx)
1515 // decide the rate table for tuning
1516 if (pAd->CommonCfg.TxRateTableSize > 0)
1518 *ppTable = RateSwitchTable;
1519 *pTableSize = RateSwitchTable[0];
1520 *pInitTxRateIdx = RateSwitchTable[1];
1525 #ifdef CONFIG_STA_SUPPORT
1526 if ((pAd->OpMode == OPMODE_STA) && ADHOC_ON(pAd))
1528 #ifdef DOT11_N_SUPPORT
1529 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
1530 !pAd->StaCfg.AdhocBOnlyJoined &&
1531 !pAd->StaCfg.AdhocBGJoined &&
1532 (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
1533 ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
1535 *ppTable = RateSwitchTable11N1S;
1536 *pTableSize = RateSwitchTable11N1S[0];
1537 *pInitTxRateIdx = RateSwitchTable11N1S[1];
1540 else if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
1541 !pAd->StaCfg.AdhocBOnlyJoined &&
1542 !pAd->StaCfg.AdhocBGJoined &&
1543 (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
1544 (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) &&
1545 (pAd->Antenna.field.TxPath == 2))
1547 if (pAd->LatchRfRegs.Channel <= 14)
1549 *ppTable = RateSwitchTable11N2S;
1550 *pTableSize = RateSwitchTable11N2S[0];
1551 *pInitTxRateIdx = RateSwitchTable11N2S[1];
1555 *ppTable = RateSwitchTable11N2SForABand;
1556 *pTableSize = RateSwitchTable11N2SForABand[0];
1557 *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
1562 #endif // DOT11_N_SUPPORT //
1563 if (pAd->CommonCfg.PhyMode == PHY_11B)
1565 *ppTable = RateSwitchTable11B;
1566 *pTableSize = RateSwitchTable11B[0];
1567 *pInitTxRateIdx = RateSwitchTable11B[1];
1570 else if((pAd->LatchRfRegs.Channel <= 14) && (pAd->StaCfg.AdhocBOnlyJoined == TRUE))
1572 // USe B Table when Only b-only Station in my IBSS .
1573 *ppTable = RateSwitchTable11B;
1574 *pTableSize = RateSwitchTable11B[0];
1575 *pInitTxRateIdx = RateSwitchTable11B[1];
1578 else if (pAd->LatchRfRegs.Channel <= 14)
1580 *ppTable = RateSwitchTable11BG;
1581 *pTableSize = RateSwitchTable11BG[0];
1582 *pInitTxRateIdx = RateSwitchTable11BG[1];
1587 *ppTable = RateSwitchTable11G;
1588 *pTableSize = RateSwitchTable11G[0];
1589 *pInitTxRateIdx = RateSwitchTable11G[1];
1594 #endif // CONFIG_STA_SUPPORT //
1596 #ifdef DOT11_N_SUPPORT
1597 if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
1598 ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
1600 *ppTable = RateSwitchTable11BGN1S;
1601 *pTableSize = RateSwitchTable11BGN1S[0];
1602 *pInitTxRateIdx = RateSwitchTable11BGN1S[1];
1607 if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
1608 (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
1610 if (pAd->LatchRfRegs.Channel <= 14)
1612 *ppTable = RateSwitchTable11BGN2S;
1613 *pTableSize = RateSwitchTable11BGN2S[0];
1614 *pInitTxRateIdx = RateSwitchTable11BGN2S[1];
1619 *ppTable = RateSwitchTable11BGN2SForABand;
1620 *pTableSize = RateSwitchTable11BGN2SForABand[0];
1621 *pInitTxRateIdx = RateSwitchTable11BGN2SForABand[1];
1627 if ((pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
1629 *ppTable = RateSwitchTable11N1S;
1630 *pTableSize = RateSwitchTable11N1S[0];
1631 *pInitTxRateIdx = RateSwitchTable11N1S[1];
1636 if ((pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
1638 if (pAd->LatchRfRegs.Channel <= 14)
1640 *ppTable = RateSwitchTable11N2S;
1641 *pTableSize = RateSwitchTable11N2S[0];
1642 *pInitTxRateIdx = RateSwitchTable11N2S[1];
1646 *ppTable = RateSwitchTable11N2SForABand;
1647 *pTableSize = RateSwitchTable11N2SForABand[0];
1648 *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
1653 #endif // DOT11_N_SUPPORT //
1654 //else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1655 if ((pEntry->RateLen == 4)
1656 #ifdef DOT11_N_SUPPORT
1657 && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
1658 #endif // DOT11_N_SUPPORT //
1661 *ppTable = RateSwitchTable11B;
1662 *pTableSize = RateSwitchTable11B[0];
1663 *pInitTxRateIdx = RateSwitchTable11B[1];
1668 //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1669 if ((pEntry->RateLen > 8)
1670 #ifdef DOT11_N_SUPPORT
1671 && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
1672 #endif // DOT11_N_SUPPORT //
1675 *ppTable = RateSwitchTable11BG;
1676 *pTableSize = RateSwitchTable11BG[0];
1677 *pInitTxRateIdx = RateSwitchTable11BG[1];
1682 //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1683 if ((pEntry->RateLen == 8)
1684 #ifdef DOT11_N_SUPPORT
1685 && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
1686 #endif // DOT11_N_SUPPORT //
1689 *ppTable = RateSwitchTable11G;
1690 *pTableSize = RateSwitchTable11G[0];
1691 *pInitTxRateIdx = RateSwitchTable11G[1];
1695 #ifdef DOT11_N_SUPPORT
1696 #endif // DOT11_N_SUPPORT //
1698 #ifdef CONFIG_STA_SUPPORT
1699 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1701 #ifdef DOT11_N_SUPPORT
1702 //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1703 if ((pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0))
1704 #endif // DOT11_N_SUPPORT //
1706 if (pAd->CommonCfg.MaxTxRate <= RATE_11)
1708 *ppTable = RateSwitchTable11B;
1709 *pTableSize = RateSwitchTable11B[0];
1710 *pInitTxRateIdx = RateSwitchTable11B[1];
1712 else if ((pAd->CommonCfg.MaxTxRate > RATE_11) && (pAd->CommonCfg.MinTxRate > RATE_11))
1714 *ppTable = RateSwitchTable11G;
1715 *pTableSize = RateSwitchTable11G[0];
1716 *pInitTxRateIdx = RateSwitchTable11G[1];
1721 *ppTable = RateSwitchTable11BG;
1722 *pTableSize = RateSwitchTable11BG[0];
1723 *pInitTxRateIdx = RateSwitchTable11BG[1];
1727 #ifdef DOT11_N_SUPPORT
1728 if (pAd->LatchRfRegs.Channel <= 14)
1730 if (pAd->CommonCfg.TxStream == 1)
1732 *ppTable = RateSwitchTable11N1S;
1733 *pTableSize = RateSwitchTable11N1S[0];
1734 *pInitTxRateIdx = RateSwitchTable11N1S[1];
1735 DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
1739 *ppTable = RateSwitchTable11N2S;
1740 *pTableSize = RateSwitchTable11N2S[0];
1741 *pInitTxRateIdx = RateSwitchTable11N2S[1];
1742 DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
1747 if (pAd->CommonCfg.TxStream == 1)
1749 *ppTable = RateSwitchTable11N1S;
1750 *pTableSize = RateSwitchTable11N1S[0];
1751 *pInitTxRateIdx = RateSwitchTable11N1S[1];
1752 DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
1756 *ppTable = RateSwitchTable11N2SForABand;
1757 *pTableSize = RateSwitchTable11N2SForABand[0];
1758 *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
1759 DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
1762 #endif // DOT11_N_SUPPORT //
1763 DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n",
1764 pAd->StaActive.SupRateLen, pAd->StaActive.ExtRateLen, pAd->StaActive.SupportedPhyInfo.MCSSet[0], pAd->StaActive.SupportedPhyInfo.MCSSet[1]));
1766 #endif // CONFIG_STA_SUPPORT //
1770 #ifdef CONFIG_STA_SUPPORT
1772 ==========================================================================
1774 This routine checks if there're other APs out there capable for
1775 roaming. Caller should call this routine only when Link up in INFRA mode
1776 and channel quality is below CQI_GOOD_THRESHOLD.
1778 IRQL = DISPATCH_LEVEL
1781 ==========================================================================
1783 VOID MlmeCheckForRoaming(
1784 IN PRTMP_ADAPTER pAd,
1788 BSS_TABLE *pRoamTab = &pAd->MlmeAux.RoamTab;
1791 DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForRoaming\n"));
1792 // put all roaming candidates into RoamTab, and sort in RSSI order
1793 BssTableInit(pRoamTab);
1794 for (i = 0; i < pAd->ScanTab.BssNr; i++)
1796 pBss = &pAd->ScanTab.BssEntry[i];
1798 if ((pBss->LastBeaconRxTime + BEACON_LOST_TIME) < Now32)
1799 continue; // AP disappear
1800 if (pBss->Rssi <= RSSI_THRESHOLD_FOR_ROAMING)
1801 continue; // RSSI too weak. forget it.
1802 if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
1803 continue; // skip current AP
1804 if (pBss->Rssi < (pAd->StaCfg.RssiSample.LastRssi0 + RSSI_DELTA))
1805 continue; // only AP with stronger RSSI is eligible for roaming
1807 // AP passing all above rules is put into roaming candidate table
1808 NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
1809 pRoamTab->BssNr += 1;
1812 if (pRoamTab->BssNr > 0)
1814 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1815 if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1817 pAd->RalinkCounters.PoorCQIRoamingCount ++;
1818 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
1819 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
1820 RT28XX_MLME_HANDLER(pAd);
1823 DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForRoaming(# of candidate= %d)\n",pRoamTab->BssNr));
1827 ==========================================================================
1829 This routine checks if there're other APs out there capable for
1830 roaming. Caller should call this routine only when link up in INFRA mode
1831 and channel quality is below CQI_GOOD_THRESHOLD.
1833 IRQL = DISPATCH_LEVEL
1836 ==========================================================================
1838 VOID MlmeCheckForFastRoaming(
1839 IN PRTMP_ADAPTER pAd,
1843 BSS_TABLE *pRoamTab = &pAd->MlmeAux.RoamTab;
1846 DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForFastRoaming\n"));
1847 // put all roaming candidates into RoamTab, and sort in RSSI order
1848 BssTableInit(pRoamTab);
1849 for (i = 0; i < pAd->ScanTab.BssNr; i++)
1851 pBss = &pAd->ScanTab.BssEntry[i];
1853 if ((pBss->Rssi <= -50) && (pBss->Channel == pAd->CommonCfg.Channel))
1854 continue; // RSSI too weak. forget it.
1855 if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
1856 continue; // skip current AP
1857 if (!SSID_EQUAL(pBss->Ssid, pBss->SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen))
1858 continue; // skip different SSID
1859 if (pBss->Rssi < (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) + RSSI_DELTA))
1860 continue; // skip AP without better RSSI
1862 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));
1863 // AP passing all above rules is put into roaming candidate table
1864 NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
1865 pRoamTab->BssNr += 1;
1868 if (pRoamTab->BssNr > 0)
1870 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1871 if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1873 pAd->RalinkCounters.PoorCQIRoamingCount ++;
1874 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
1875 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
1876 RT28XX_MLME_HANDLER(pAd);
1879 // Maybe site survey required
1882 if ((pAd->StaCfg.LastScanTime + 10 * 1000) < Now)
1884 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1885 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming, No eligable entry, try new scan!\n"));
1886 pAd->StaCfg.ScanCnt = 2;
1887 pAd->StaCfg.LastScanTime = Now;
1892 DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr));
1896 ==========================================================================
1898 This routine calculates TxPER, RxPER of the past N-sec period. And
1899 according to the calculation result, ChannelQuality is calculated here
1900 to decide if current AP is still doing the job.
1902 If ChannelQuality is not good, a ROAMing attempt may be tried later.
1904 StaCfg.ChannelQuality - 0..100
1906 IRQL = DISPATCH_LEVEL
1908 NOTE: This routine decide channle quality based on RX CRC error ratio.
1909 Caller should make sure a function call to NICUpdateRawCounters(pAd)
1910 is performed right before this routine, so that this routine can decide
1911 channel quality based on the most up-to-date information
1912 ==========================================================================
1914 VOID MlmeCalculateChannelQuality(
1915 IN PRTMP_ADAPTER pAd,
1918 ULONG TxOkCnt, TxCnt, TxPER, TxPRR;
1922 ULONG BeaconLostTime = BEACON_LOST_TIME;
1924 #ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
1925 // longer beacon lost time when carrier detection enabled
1926 if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
1928 BeaconLostTime = BEACON_LOST_TIME + BEACON_LOST_TIME/2;
1930 #endif // CARRIER_DETECTION_SUPPORT //
1932 MaxRssi = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2);
1935 // calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics
1937 TxOkCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + pAd->RalinkCounters.OneSecTxRetryOkCount;
1938 TxCnt = TxOkCnt + pAd->RalinkCounters.OneSecTxFailCount;
1946 TxPER = (pAd->RalinkCounters.OneSecTxFailCount * 100) / TxCnt;
1947 TxPRR = ((TxCnt - pAd->RalinkCounters.OneSecTxNoRetryOkCount) * 100) / TxCnt;
1951 // calculate RX PER - don't take RxPER into consideration if too few sample
1953 RxCnt = pAd->RalinkCounters.OneSecRxOkCnt + pAd->RalinkCounters.OneSecRxFcsErrCnt;
1957 RxPER = (pAd->RalinkCounters.OneSecRxFcsErrCnt * 100) / RxCnt;
1960 // decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER
1962 if (INFRA_ON(pAd) &&
1963 (pAd->RalinkCounters.OneSecTxNoRetryOkCount < 2) && // no heavy traffic
1964 (pAd->StaCfg.LastBeaconRxTime + BeaconLostTime < Now32))
1966 DBGPRINT(RT_DEBUG_TRACE, ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n", BeaconLostTime, TxOkCnt));
1967 pAd->Mlme.ChannelQuality = 0;
1974 else if (MaxRssi < -90)
1977 NorRssi = (MaxRssi + 90) * 2;
1979 // ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER (RSSI 0..100), (TxPER 100..0), (RxPER 100..0)
1980 pAd->Mlme.ChannelQuality = (RSSI_WEIGHTING * NorRssi +
1981 TX_WEIGHTING * (100 - TxPRR) +
1982 RX_WEIGHTING* (100 - RxPER)) / 100;
1983 if (pAd->Mlme.ChannelQuality >= 100)
1984 pAd->Mlme.ChannelQuality = 100;
1990 IN PRTMP_ADAPTER pAd,
1991 IN PMAC_TABLE_ENTRY pEntry,
1992 IN PRTMP_TX_RATE_SWITCH pTxRate)
1994 UCHAR MaxMode = MODE_OFDM;
1996 #ifdef DOT11_N_SUPPORT
1997 MaxMode = MODE_HTGREENFIELD;
1999 if (pTxRate->STBC && (pAd->StaCfg.MaxHTPhyMode.field.STBC) && (pAd->Antenna.field.TxPath == 2))
2000 pAd->StaCfg.HTPhyMode.field.STBC = STBC_USE;
2002 #endif // DOT11_N_SUPPORT //
2003 pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
2005 if (pTxRate->CurrMCS < MCS_AUTO)
2006 pAd->StaCfg.HTPhyMode.field.MCS = pTxRate->CurrMCS;
2008 if (pAd->StaCfg.HTPhyMode.field.MCS > 7)
2009 pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
2013 // If peer adhoc is b-only mode, we can't send 11g rate.
2014 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
2015 pEntry->HTPhyMode.field.STBC = STBC_NONE;
2018 // For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary
2020 pEntry->HTPhyMode.field.MODE = pTxRate->Mode;
2021 pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI;
2022 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
2024 // Patch speed error in status page
2025 pAd->StaCfg.HTPhyMode.field.MODE = pEntry->HTPhyMode.field.MODE;
2029 if (pTxRate->Mode <= MaxMode)
2030 pAd->StaCfg.HTPhyMode.field.MODE = pTxRate->Mode;
2032 #ifdef DOT11_N_SUPPORT
2033 if (pTxRate->ShortGI && (pAd->StaCfg.MaxHTPhyMode.field.ShortGI))
2034 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_400;
2036 #endif // DOT11_N_SUPPORT //
2037 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
2039 #ifdef DOT11_N_SUPPORT
2040 // Reexam each bandwidth's SGI support.
2041 if (pAd->StaCfg.HTPhyMode.field.ShortGI == GI_400)
2043 if ((pEntry->HTPhyMode.field.BW == BW_20) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE)))
2044 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
2045 if ((pEntry->HTPhyMode.field.BW == BW_40) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE)))
2046 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
2049 // Turn RTS/CTS rate to 6Mbps.
2050 if ((pEntry->HTPhyMode.field.MCS == 0) && (pAd->StaCfg.HTPhyMode.field.MCS != 0))
2052 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
2053 if (pAd->MacTab.fAnyBASession)
2055 AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
2059 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
2062 else if ((pEntry->HTPhyMode.field.MCS == 8) && (pAd->StaCfg.HTPhyMode.field.MCS != 8))
2064 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
2065 if (pAd->MacTab.fAnyBASession)
2067 AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
2071 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
2074 else if ((pEntry->HTPhyMode.field.MCS != 0) && (pAd->StaCfg.HTPhyMode.field.MCS == 0))
2076 AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
2079 else if ((pEntry->HTPhyMode.field.MCS != 8) && (pAd->StaCfg.HTPhyMode.field.MCS == 8))
2081 AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
2083 #endif // DOT11_N_SUPPORT //
2085 pEntry->HTPhyMode.field.STBC = pAd->StaCfg.HTPhyMode.field.STBC;
2086 pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI;
2087 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
2088 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
2089 #ifdef DOT11_N_SUPPORT
2090 if ((pAd->StaCfg.MaxHTPhyMode.field.MODE == MODE_HTGREENFIELD) &&
2091 pAd->WIFItestbed.bGreenField)
2092 pEntry->HTPhyMode.field.MODE = MODE_HTGREENFIELD;
2093 #endif // DOT11_N_SUPPORT //
2096 pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
2100 ==========================================================================
2102 This routine calculates the acumulated TxPER of eaxh TxRate. And
2103 according to the calculation result, change CommonCfg.TxRate which
2104 is the stable TX Rate we expect the Radio situation could sustained.
2106 CommonCfg.TxRate will change dynamically within {RATE_1/RATE_6, MaxTxRate}
2110 IRQL = DISPATCH_LEVEL
2113 call this routine every second
2114 ==========================================================================
2116 VOID MlmeDynamicTxRateSwitching(
2117 IN PRTMP_ADAPTER pAd)
2119 UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx;
2120 ULONG i, AccuTxTotalCnt = 0, TxTotalCnt;
2121 ULONG TxErrorRatio = 0;
2122 BOOLEAN bTxRateChanged, bUpgradeQuality = FALSE;
2123 PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL;
2125 UCHAR TableSize = 0;
2126 UCHAR InitTxRateIdx = 0, TrainUp, TrainDown;
2127 CHAR Rssi, RssiOffset = 0;
2128 TX_STA_CNT1_STRUC StaTx1;
2129 TX_STA_CNT0_STRUC TxStaCnt0;
2130 ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
2131 MAC_TABLE_ENTRY *pEntry;
2138 #endif // RALINK_ATE //
2140 /*if (pAd->Antenna.field.RxPath > 1)
2141 Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
2143 Rssi = pAd->StaCfg.RssiSample.AvgRssi0;*/
2146 // walk through MAC table, see if need to change AP's TX rate toward each entry
2148 for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
2150 pEntry = &pAd->MacTab.Content[i];
2152 // check if this entry need to switch rate automatically
2153 if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
2156 if ((pAd->MacTab.Size == 1) || (pEntry->ValidAsDls))
2158 Rssi = RTMPMaxRssi(pAd, (CHAR)pAd->StaCfg.RssiSample.AvgRssi0, (CHAR)pAd->StaCfg.RssiSample.AvgRssi1, (CHAR)pAd->StaCfg.RssiSample.AvgRssi2);
2160 // Update statistic counter
2161 RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
2162 RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
2163 pAd->bUpdateBcnCntDone = TRUE;
2164 TxRetransmit = StaTx1.field.TxRetransmit;
2165 TxSuccess = StaTx1.field.TxSuccess;
2166 TxFailCount = TxStaCnt0.field.TxFailCount;
2167 TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
2169 pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
2170 pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
2171 pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
2172 pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
2173 pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
2174 pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
2176 // if no traffic in the past 1-sec period, don't change TX rate,
2177 // but clear all bad history. because the bad history may affect the next
2178 // Chariot throughput test
2179 AccuTxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
2180 pAd->RalinkCounters.OneSecTxRetryOkCount +
2181 pAd->RalinkCounters.OneSecTxFailCount;
2184 TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
2188 Rssi = RTMPMaxRssi(pAd, (CHAR)pEntry->RssiSample.AvgRssi0, (CHAR)pEntry->RssiSample.AvgRssi1, (CHAR)pEntry->RssiSample.AvgRssi2);
2190 TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
2191 pEntry->OneSecTxRetryOkCount +
2192 pEntry->OneSecTxFailCount;
2195 TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
2198 CurrRateIdx = pEntry->CurrTxRateIndex;
2200 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
2202 if (CurrRateIdx >= TableSize)
2204 CurrRateIdx = TableSize - 1;
2207 // When switch from Fixed rate -> auto rate, the REAL TX rate might be different from pAd->CommonCfg.TxRateIndex.
2208 // So need to sync here.
2209 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
2210 if ((pEntry->HTPhyMode.field.MCS != pCurrTxRate->CurrMCS)
2211 //&& (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
2215 // Need to sync Real Tx rate and our record.
2216 // Then return for next DRS.
2217 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(InitTxRateIdx+1)*5];
2218 pEntry->CurrTxRateIndex = InitTxRateIdx;
2219 MlmeSetTxRate(pAd, pEntry, pCurrTxRate);
2221 // reset all OneSecTx counters
2222 RESET_ONE_SEC_TX_CNT(pEntry);
2226 // decide the next upgrade rate and downgrade rate, if any
2227 if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
2229 UpRateIdx = CurrRateIdx + 1;
2230 DownRateIdx = CurrRateIdx -1;
2232 else if (CurrRateIdx == 0)
2234 UpRateIdx = CurrRateIdx + 1;
2235 DownRateIdx = CurrRateIdx;
2237 else if (CurrRateIdx == (TableSize - 1))
2239 UpRateIdx = CurrRateIdx;
2240 DownRateIdx = CurrRateIdx - 1;
2243 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
2245 #ifdef DOT11_N_SUPPORT
2246 if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
2248 TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
2249 TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
2252 #endif // DOT11_N_SUPPORT //
2254 TrainUp = pCurrTxRate->TrainUp;
2255 TrainDown = pCurrTxRate->TrainDown;
2258 //pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction;
2261 // Keep the last time TxRateChangeAction status.
2263 pEntry->LastTimeTxRateChangeAction = pEntry->LastSecTxRateChangeAction;
2268 // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
2269 // (criteria copied from RT2500 for Netopia case)
2271 if (TxTotalCnt <= 15)
2275 //UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS7 = 0, MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
2276 UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS5 =0, MCS6 = 0, MCS7 = 0;
2277 UCHAR MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
2278 UCHAR MCS20 = 0, MCS21 = 0, MCS22 = 0, MCS23 = 0; // 3*3
2280 // check the existence and index of each needed MCS
2281 while (idx < pTable[0])
2283 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(idx+1)*5];
2285 if (pCurrTxRate->CurrMCS == MCS_0)
2289 else if (pCurrTxRate->CurrMCS == MCS_1)
2293 else if (pCurrTxRate->CurrMCS == MCS_2)
2297 else if (pCurrTxRate->CurrMCS == MCS_3)
2301 else if (pCurrTxRate->CurrMCS == MCS_4)
2305 else if (pCurrTxRate->CurrMCS == MCS_5)
2309 else if (pCurrTxRate->CurrMCS == MCS_6)
2313 //else if (pCurrTxRate->CurrMCS == MCS_7)
2314 else if ((pCurrTxRate->CurrMCS == MCS_7) && (pCurrTxRate->ShortGI == GI_800)) // prevent the highest MCS using short GI when 1T and low throughput
2318 else if (pCurrTxRate->CurrMCS == MCS_12)
2322 else if (pCurrTxRate->CurrMCS == MCS_13)
2326 else if (pCurrTxRate->CurrMCS == MCS_14)
2330 //else if ((pCurrTxRate->CurrMCS == MCS_15)/* && (pCurrTxRate->ShortGI == GI_800)*/) //we hope to use ShortGI as initial rate
2331 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
2335 else if (pCurrTxRate->CurrMCS == MCS_20) // 3*3
2339 else if (pCurrTxRate->CurrMCS == MCS_21)
2343 else if (pCurrTxRate->CurrMCS == MCS_22)
2347 else if (pCurrTxRate->CurrMCS == MCS_23)
2354 if (pAd->LatchRfRegs.Channel <= 14)
2356 if (pAd->NicConfig2.field.ExternalLNAForG)
2367 if (pAd->NicConfig2.field.ExternalLNAForA)
2376 #ifdef DOT11_N_SUPPORT
2378 if ((pTable == RateSwitchTable11BGN3S) ||
2379 (pTable == RateSwitchTable11N3S) ||
2380 (pTable == RateSwitchTable))
2381 {// N mode with 3 stream // 3*3
2382 if (MCS23 && (Rssi >= -70))
2384 else if (MCS22 && (Rssi >= -72))
2386 else if (MCS21 && (Rssi >= -76))
2388 else if (MCS20 && (Rssi >= -78))
2390 else if (MCS4 && (Rssi >= -82))
2392 else if (MCS3 && (Rssi >= -84))
2394 else if (MCS2 && (Rssi >= -86))
2396 else if (MCS1 && (Rssi >= -88))
2401 else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand)) // 3*3
2402 {// N mode with 2 stream
2403 if (MCS15 && (Rssi >= (-70+RssiOffset)))
2405 else if (MCS14 && (Rssi >= (-72+RssiOffset)))
2407 else if (MCS13 && (Rssi >= (-76+RssiOffset)))
2409 else if (MCS12 && (Rssi >= (-78+RssiOffset)))
2411 else if (MCS4 && (Rssi >= (-82+RssiOffset)))
2413 else if (MCS3 && (Rssi >= (-84+RssiOffset)))
2415 else if (MCS2 && (Rssi >= (-86+RssiOffset)))
2417 else if (MCS1 && (Rssi >= (-88+RssiOffset)))
2422 else if ((pTable == RateSwitchTable11BGN1S) || (pTable == RateSwitchTable11N1S))
2423 {// N mode with 1 stream
2424 if (MCS7 && (Rssi > (-72+RssiOffset)))
2426 else if (MCS6 && (Rssi > (-74+RssiOffset)))
2428 else if (MCS5 && (Rssi > (-77+RssiOffset)))
2430 else if (MCS4 && (Rssi > (-79+RssiOffset)))
2432 else if (MCS3 && (Rssi > (-81+RssiOffset)))
2434 else if (MCS2 && (Rssi > (-83+RssiOffset)))
2436 else if (MCS1 && (Rssi > (-86+RssiOffset)))
2442 #endif // DOT11_N_SUPPORT //
2444 if (MCS7 && (Rssi > -70))
2446 else if (MCS6 && (Rssi > -74))
2448 else if (MCS5 && (Rssi > -78))
2450 else if (MCS4 && (Rssi > -82))
2452 else if (MCS4 == 0) // for B-only mode
2454 else if (MCS3 && (Rssi > -85))
2456 else if (MCS2 && (Rssi > -87))
2458 else if (MCS1 && (Rssi > -90))
2465 pEntry->CurrTxRateIndex = TxRateIdx;
2466 pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
2467 MlmeSetTxRate(pAd, pEntry, pNextTxRate);
2470 NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
2471 NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
2472 pEntry->fLastSecAccordingRSSI = TRUE;
2473 // reset all OneSecTx counters
2474 RESET_ONE_SEC_TX_CNT(pEntry);
2479 if (pEntry->fLastSecAccordingRSSI == TRUE)
2481 pEntry->fLastSecAccordingRSSI = FALSE;
2482 pEntry->LastSecTxRateChangeAction = 0;
2483 // reset all OneSecTx counters
2484 RESET_ONE_SEC_TX_CNT(pEntry);
2491 BOOLEAN bTrainUpDown = FALSE;
2493 pEntry->CurrTxRateStableTime ++;
2495 // downgrade TX quality if PER >= Rate-Down threshold
2496 if (TxErrorRatio >= TrainDown)
2498 bTrainUpDown = TRUE;
2499 pEntry->TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
2501 // upgrade TX quality if PER <= Rate-Up threshold
2502 else if (TxErrorRatio <= TrainUp)
2504 bTrainUpDown = TRUE;
2505 bUpgradeQuality = TRUE;
2506 if (pEntry->TxQuality[CurrRateIdx])
2507 pEntry->TxQuality[CurrRateIdx] --; // quality very good in CurrRate
2509 if (pEntry->TxRateUpPenalty)
2510 pEntry->TxRateUpPenalty --;
2511 else if (pEntry->TxQuality[UpRateIdx])
2512 pEntry->TxQuality[UpRateIdx] --; // may improve next UP rate's quality
2515 pEntry->PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
2519 // perform DRS - consider TxRate Down first, then rate up.
2520 if ((CurrRateIdx != DownRateIdx) && (pEntry->TxQuality[CurrRateIdx] >= DRS_TX_QUALITY_WORST_BOUND))
2522 pEntry->CurrTxRateIndex = DownRateIdx;
2524 else if ((CurrRateIdx != UpRateIdx) && (pEntry->TxQuality[UpRateIdx] <= 0))
2526 pEntry->CurrTxRateIndex = UpRateIdx;
2531 // if rate-up happen, clear all bad history of all TX rates
2532 if (pEntry->CurrTxRateIndex > CurrRateIdx)
2534 pEntry->CurrTxRateStableTime = 0;
2535 pEntry->TxRateUpPenalty = 0;
2536 pEntry->LastSecTxRateChangeAction = 1; // rate UP
2537 NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
2538 NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
2541 // For TxRate fast train up
2543 if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
2545 RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
2547 pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
2549 bTxRateChanged = TRUE;
2551 // if rate-down happen, only clear DownRate's bad history
2552 else if (pEntry->CurrTxRateIndex < CurrRateIdx)
2554 pEntry->CurrTxRateStableTime = 0;
2555 pEntry->TxRateUpPenalty = 0; // no penalty
2556 pEntry->LastSecTxRateChangeAction = 2; // rate DOWN
2557 pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0;
2558 pEntry->PER[pEntry->CurrTxRateIndex] = 0;
2561 // For TxRate fast train down
2563 if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
2565 RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
2567 pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
2569 bTxRateChanged = TRUE;
2573 pEntry->LastSecTxRateChangeAction = 0; // rate no change
2574 bTxRateChanged = FALSE;
2577 pEntry->LastTxOkCount = TxSuccess;
2579 // reset all OneSecTx counters
2580 RESET_ONE_SEC_TX_CNT(pEntry);
2582 pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
2583 if (bTxRateChanged && pNextTxRate)
2585 MlmeSetTxRate(pAd, pEntry, pNextTxRate);
2591 ========================================================================
2592 Routine Description:
2593 Station side, Auto TxRate faster train up timer call back function.
2596 SystemSpecific1 - Not used.
2597 FunctionContext - Pointer to our Adapter context.
2598 SystemSpecific2 - Not used.
2599 SystemSpecific3 - Not used.
2604 ========================================================================
2606 VOID StaQuickResponeForRateUpExec(
2607 IN PVOID SystemSpecific1,
2608 IN PVOID FunctionContext,
2609 IN PVOID SystemSpecific2,
2610 IN PVOID SystemSpecific3)
2612 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext;
2613 UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0;
2615 ULONG TxErrorRatio = 0;
2616 BOOLEAN bTxRateChanged = TRUE; //, bUpgradeQuality = FALSE;
2617 PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL;
2619 UCHAR TableSize = 0;
2620 UCHAR InitTxRateIdx = 0, TrainUp, TrainDown;
2621 TX_STA_CNT1_STRUC StaTx1;
2622 TX_STA_CNT0_STRUC TxStaCnt0;
2624 ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
2625 MAC_TABLE_ENTRY *pEntry;
2628 pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
2631 // walk through MAC table, see if need to change AP's TX rate toward each entry
2633 for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
2635 pEntry = &pAd->MacTab.Content[i];
2637 // check if this entry need to switch rate automatically
2638 if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
2641 //Rssi = RTMPMaxRssi(pAd, (CHAR)pAd->StaCfg.AvgRssi0, (CHAR)pAd->StaCfg.AvgRssi1, (CHAR)pAd->StaCfg.AvgRssi2);
2642 if (pAd->Antenna.field.TxPath > 1)
2643 Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
2645 Rssi = pAd->StaCfg.RssiSample.AvgRssi0;
2647 CurrRateIdx = pAd->CommonCfg.TxRateIndex;
2649 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
2651 // decide the next upgrade rate and downgrade rate, if any
2652 if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
2654 UpRateIdx = CurrRateIdx + 1;
2655 DownRateIdx = CurrRateIdx -1;
2657 else if (CurrRateIdx == 0)
2659 UpRateIdx = CurrRateIdx + 1;
2660 DownRateIdx = CurrRateIdx;
2662 else if (CurrRateIdx == (TableSize - 1))
2664 UpRateIdx = CurrRateIdx;
2665 DownRateIdx = CurrRateIdx - 1;
2668 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
2670 #ifdef DOT11_N_SUPPORT
2671 if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
2673 TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
2674 TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
2677 #endif // DOT11_N_SUPPORT //
2679 TrainUp = pCurrTxRate->TrainUp;
2680 TrainDown = pCurrTxRate->TrainDown;
2683 if (pAd->MacTab.Size == 1)
2685 // Update statistic counter
2686 RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
2687 RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
2689 TxRetransmit = StaTx1.field.TxRetransmit;
2690 TxSuccess = StaTx1.field.TxSuccess;
2691 TxFailCount = TxStaCnt0.field.TxFailCount;
2692 TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
2694 pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
2695 pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
2696 pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
2697 pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
2698 pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
2699 pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
2702 TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
2706 TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
2707 pEntry->OneSecTxRetryOkCount +
2708 pEntry->OneSecTxFailCount;
2711 TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
2716 // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
2717 // (criteria copied from RT2500 for Netopia case)
2719 if (TxTotalCnt <= 12)
2721 NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
2722 NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
2724 if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
2726 pAd->CommonCfg.TxRateIndex = DownRateIdx;
2727 pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
2729 else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
2731 pAd->CommonCfg.TxRateIndex = UpRateIdx;
2734 DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: TxTotalCnt <= 15, train back to original rate \n"));
2740 ULONG OneSecTxNoRetryOKRationCount;
2742 if (pAd->DrsCounters.LastTimeTxRateChangeAction == 0)
2747 // downgrade TX quality if PER >= Rate-Down threshold
2748 if (TxErrorRatio >= TrainDown)
2750 pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
2753 pAd->DrsCounters.PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
2755 OneSecTxNoRetryOKRationCount = (TxSuccess * ratio);
2757 // perform DRS - consider TxRate Down first, then rate up.
2758 if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
2760 if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
2762 pAd->CommonCfg.TxRateIndex = DownRateIdx;
2763 pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
2768 else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
2770 if ((TxErrorRatio >= 50) || (TxErrorRatio >= TrainDown))
2774 else if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
2776 pAd->CommonCfg.TxRateIndex = UpRateIdx;
2781 // if rate-up happen, clear all bad history of all TX rates
2782 if (pAd->CommonCfg.TxRateIndex > CurrRateIdx)
2784 pAd->DrsCounters.TxRateUpPenalty = 0;
2785 NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
2786 NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
2788 // if rate-down happen, only clear DownRate's bad history
2789 else if (pAd->CommonCfg.TxRateIndex < CurrRateIdx)
2791 DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: --TX rate from %d to %d \n", CurrRateIdx, pAd->CommonCfg.TxRateIndex));
2793 pAd->DrsCounters.TxRateUpPenalty = 0; // no penalty
2794 pAd->DrsCounters.TxQuality[pAd->CommonCfg.TxRateIndex] = 0;
2795 pAd->DrsCounters.PER[pAd->CommonCfg.TxRateIndex] = 0;
2799 bTxRateChanged = FALSE;
2802 pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pAd->CommonCfg.TxRateIndex+1)*5];
2803 if (bTxRateChanged && pNextTxRate)
2805 MlmeSetTxRate(pAd, pEntry, pNextTxRate);
2811 ==========================================================================
2813 This routine is executed periodically inside MlmePeriodicExec() after
2814 association with an AP.
2815 It checks if StaCfg.Psm is consistent with user policy (recorded in
2816 StaCfg.WindowsPowerMode). If not, enforce user policy. However,
2817 there're some conditions to consider:
2818 1. we don't support power-saving in ADHOC mode, so Psm=PWR_ACTIVE all
2819 the time when Mibss==TRUE
2820 2. When link up in INFRA mode, Psm should not be switch to PWR_SAVE
2821 if outgoing traffic available in TxRing or MgmtRing.
2823 1. change pAd->StaCfg.Psm to PWR_SAVE or leave it untouched
2825 IRQL = DISPATCH_LEVEL
2827 ==========================================================================
2829 VOID MlmeCheckPsmChange(
2830 IN PRTMP_ADAPTER pAd,
2836 // 1. Psm maybe ON only happen in INFRASTRUCTURE mode
2837 // 2. user wants either MAX_PSP or FAST_PSP
2838 // 3. but current psm is not in PWR_SAVE
2839 // 4. CNTL state machine is not doing SCANning
2840 // 5. no TX SUCCESS event for the past 1-sec period
2841 #ifdef NDIS51_MINIPORT
2842 if (pAd->StaCfg.WindowsPowerProfile == NdisPowerProfileBattery)
2843 PowerMode = pAd->StaCfg.WindowsBatteryPowerMode;
2846 PowerMode = pAd->StaCfg.WindowsPowerMode;
2848 if (INFRA_ON(pAd) &&
2849 (PowerMode != Ndis802_11PowerModeCAM) &&
2850 (pAd->StaCfg.Psm == PWR_ACTIVE) &&
2851 RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP))
2853 NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime);
2854 pAd->RalinkCounters.RxCountSinceLastNULL = 0;
2855 MlmeSetPsmBit(pAd, PWR_SAVE);
2856 if (!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
2858 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
2862 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
2867 // IRQL = PASSIVE_LEVEL
2868 // IRQL = DISPATCH_LEVEL
2870 IN PRTMP_ADAPTER pAd,
2873 AUTO_RSP_CFG_STRUC csr4;
2875 pAd->StaCfg.Psm = psm;
2876 RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
2877 csr4.field.AckCtsPsmBit = (psm == PWR_SAVE)? 1:0;
2878 RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
2879 DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetPsmBit = %d\n", psm));
2881 #endif // CONFIG_STA_SUPPORT //
2884 // IRQL = DISPATCH_LEVEL
2885 VOID MlmeSetTxPreamble(
2886 IN PRTMP_ADAPTER pAd,
2887 IN USHORT TxPreamble)
2889 AUTO_RSP_CFG_STRUC csr4;
2892 // Always use Long preamble before verifiation short preamble functionality works well.
2893 // Todo: remove the following line if short preamble functionality works
2895 //TxPreamble = Rt802_11PreambleLong;
2897 RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
2898 if (TxPreamble == Rt802_11PreambleLong)
2900 DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= LONG PREAMBLE)\n"));
2901 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
2902 csr4.field.AutoResponderPreamble = 0;
2906 // NOTE: 1Mbps should always use long preamble
2907 DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= SHORT PREAMBLE)\n"));
2908 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
2909 csr4.field.AutoResponderPreamble = 1;
2912 RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
2916 ==========================================================================
2918 Update basic rate bitmap
2919 ==========================================================================
2922 VOID UpdateBasicRateBitmap(
2923 IN PRTMP_ADAPTER pAdapter)
2926 /* 1 2 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */
2927 UCHAR rate[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
2928 UCHAR *sup_p = pAdapter->CommonCfg.SupRate;
2929 UCHAR *ext_p = pAdapter->CommonCfg.ExtRate;
2930 ULONG bitmap = pAdapter->CommonCfg.BasicRateBitmap;
2933 /* if A mode, always use fix BasicRateBitMap */
2934 //if (pAdapter->CommonCfg.Channel == PHY_11A)
2935 if (pAdapter->CommonCfg.Channel > 14)
2936 pAdapter->CommonCfg.BasicRateBitmap = 0x150; /* 6, 12, 24M */
2939 if (pAdapter->CommonCfg.BasicRateBitmap > 4095)
2941 /* (2 ^ MAX_LEN_OF_SUPPORTED_RATES) -1 */
2945 for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
2951 for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
2953 if (bitmap & (1 << i))
2955 for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
2957 if (sup_p[j] == rate[i])
2962 for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
2964 if (ext_p[j] == rate[i])
2970 } /* End of UpdateBasicRateBitmap */
2972 // IRQL = PASSIVE_LEVEL
2973 // IRQL = DISPATCH_LEVEL
2974 // bLinkUp is to identify the inital link speed.
2975 // TRUE indicates the rate update at linkup, we should not try to set the rate at 54Mbps.
2976 VOID MlmeUpdateTxRates(
2977 IN PRTMP_ADAPTER pAd,
2982 UCHAR Rate = RATE_6, MaxDesire = RATE_1, MaxSupport = RATE_1;
2983 UCHAR MinSupport = RATE_54;
2984 ULONG BasicRateBitmap = 0;
2985 UCHAR CurrBasicRate = RATE_1;
2986 UCHAR *pSupRate, SupRateLen, *pExtRate, ExtRateLen;
2987 PHTTRANSMIT_SETTING pHtPhy = NULL;
2988 PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
2989 PHTTRANSMIT_SETTING pMinHtPhy = NULL;
2990 BOOLEAN *auto_rate_cur_p;
2991 UCHAR HtMcs = MCS_AUTO;
2993 // find max desired rate
2994 UpdateBasicRateBitmap(pAd);
2997 auto_rate_cur_p = NULL;
2998 for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
3000 switch (pAd->CommonCfg.DesireRate[i] & 0x7f)
3002 case 2: Rate = RATE_1; num++; break;
3003 case 4: Rate = RATE_2; num++; break;
3004 case 11: Rate = RATE_5_5; num++; break;
3005 case 22: Rate = RATE_11; num++; break;
3006 case 12: Rate = RATE_6; num++; break;
3007 case 18: Rate = RATE_9; num++; break;
3008 case 24: Rate = RATE_12; num++; break;
3009 case 36: Rate = RATE_18; num++; break;
3010 case 48: Rate = RATE_24; num++; break;
3011 case 72: Rate = RATE_36; num++; break;
3012 case 96: Rate = RATE_48; num++; break;
3013 case 108: Rate = RATE_54; num++; break;
3014 //default: Rate = RATE_1; break;
3016 if (MaxDesire < Rate) MaxDesire = Rate;
3019 //===========================================================================
3020 //===========================================================================
3022 #ifdef CONFIG_STA_SUPPORT
3023 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3025 pHtPhy = &pAd->StaCfg.HTPhyMode;
3026 pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
3027 pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
3029 auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
3030 HtMcs = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
3032 if ((pAd->StaCfg.BssType == BSS_ADHOC) &&
3033 (pAd->CommonCfg.PhyMode == PHY_11B) &&
3034 (MaxDesire > RATE_11))
3036 MaxDesire = RATE_11;
3039 #endif // CONFIG_STA_SUPPORT //
3041 pAd->CommonCfg.MaxDesiredRate = MaxDesire;
3042 pMinHtPhy->word = 0;
3043 pMaxHtPhy->word = 0;
3046 // Auto rate switching is enabled only if more than one DESIRED RATES are
3047 // specified; otherwise disabled
3050 *auto_rate_cur_p = FALSE;
3054 *auto_rate_cur_p = TRUE;
3058 if (HtMcs != MCS_AUTO)
3060 *auto_rate_cur_p = FALSE;
3064 *auto_rate_cur_p = TRUE;
3068 #ifdef CONFIG_STA_SUPPORT
3069 if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
3071 pSupRate = &pAd->StaActive.SupRate[0];
3072 pExtRate = &pAd->StaActive.ExtRate[0];
3073 SupRateLen = pAd->StaActive.SupRateLen;
3074 ExtRateLen = pAd->StaActive.ExtRateLen;
3077 #endif // CONFIG_STA_SUPPORT //
3079 pSupRate = &pAd->CommonCfg.SupRate[0];
3080 pExtRate = &pAd->CommonCfg.ExtRate[0];
3081 SupRateLen = pAd->CommonCfg.SupRateLen;
3082 ExtRateLen = pAd->CommonCfg.ExtRateLen;
3085 // find max supported rate
3086 for (i=0; i<SupRateLen; i++)
3088 switch (pSupRate[i] & 0x7f)
3090 case 2: Rate = RATE_1; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0001; break;
3091 case 4: Rate = RATE_2; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0002; break;
3092 case 11: Rate = RATE_5_5; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0004; break;
3093 case 22: Rate = RATE_11; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0008; break;
3094 case 12: Rate = RATE_6; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 0x0010; break;
3095 case 18: Rate = RATE_9; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0020; break;
3096 case 24: Rate = RATE_12; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 0x0040; break;
3097 case 36: Rate = RATE_18; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0080; break;
3098 case 48: Rate = RATE_24; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 0x0100; break;
3099 case 72: Rate = RATE_36; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0200; break;
3100 case 96: Rate = RATE_48; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0400; break;
3101 case 108: Rate = RATE_54; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0800; break;
3102 default: Rate = RATE_1; break;
3104 if (MaxSupport < Rate) MaxSupport = Rate;
3106 if (MinSupport > Rate) MinSupport = Rate;
3109 for (i=0; i<ExtRateLen; i++)
3111 switch (pExtRate[i] & 0x7f)
3113 case 2: Rate = RATE_1; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0001; break;
3114 case 4: Rate = RATE_2; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0002; break;
3115 case 11: Rate = RATE_5_5; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0004; break;
3116 case 22: Rate = RATE_11; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0008; break;
3117 case 12: Rate = RATE_6; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 0x0010; break;
3118 case 18: Rate = RATE_9; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0020; break;
3119 case 24: Rate = RATE_12; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 0x0040; break;
3120 case 36: Rate = RATE_18; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0080; break;
3121 case 48: Rate = RATE_24; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 0x0100; break;
3122 case 72: Rate = RATE_36; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0200; break;
3123 case 96: Rate = RATE_48; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0400; break;
3124 case 108: Rate = RATE_54; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0800; break;
3125 default: Rate = RATE_1; break;
3127 if (MaxSupport < Rate) MaxSupport = Rate;
3129 if (MinSupport > Rate) MinSupport = Rate;
3132 RTMP_IO_WRITE32(pAd, LEGACY_BASIC_RATE, BasicRateBitmap);
3134 // calculate the exptected ACK rate for each TX rate. This info is used to caculate
3135 // the DURATION field of outgoing uniicast DATA/MGMT frame
3136 for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
3138 if (BasicRateBitmap & (0x01 << i))
3139 CurrBasicRate = (UCHAR)i;
3140 pAd->CommonCfg.ExpectedACKRate[i] = CurrBasicRate;
3143 DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateTxRates[MaxSupport = %d] = MaxDesire %d Mbps\n", RateIdToMbps[MaxSupport], RateIdToMbps[MaxDesire]));
3144 // max tx rate = min {max desire rate, max supported rate}
3145 if (MaxSupport < MaxDesire)
3146 pAd->CommonCfg.MaxTxRate = MaxSupport;
3148 pAd->CommonCfg.MaxTxRate = MaxDesire;
3150 pAd->CommonCfg.MinTxRate = MinSupport;
3151 if (*auto_rate_cur_p)
3154 #ifdef CONFIG_STA_SUPPORT
3155 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3156 dbm = pAd->StaCfg.RssiSample.AvgRssi0 - pAd->BbpRssiToDbmDelta;
3157 #endif // CONFIG_STA_SUPPORT //
3158 if (bLinkUp == TRUE)
3159 pAd->CommonCfg.TxRate = RATE_24;
3161 pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
3164 pAd->CommonCfg.TxRate = RATE_11;
3166 pAd->CommonCfg.TxRate = RATE_24;
3168 // should never exceed MaxTxRate (consider 11B-only mode)
3169 if (pAd->CommonCfg.TxRate > pAd->CommonCfg.MaxTxRate)
3170 pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
3172 pAd->CommonCfg.TxRateIndex = 0;
3176 pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
3177 pHtPhy->field.MCS = (pAd->CommonCfg.MaxTxRate > 3) ? (pAd->CommonCfg.MaxTxRate - 4) : pAd->CommonCfg.MaxTxRate;
3178 pHtPhy->field.MODE = (pAd->CommonCfg.MaxTxRate > 3) ? MODE_OFDM : MODE_CCK;
3180 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC = pHtPhy->field.STBC;
3181 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI = pHtPhy->field.ShortGI;
3182 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS = pHtPhy->field.MCS;
3183 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE = pHtPhy->field.MODE;
3186 if (pAd->CommonCfg.TxRate <= RATE_11)
3188 pMaxHtPhy->field.MODE = MODE_CCK;
3189 pMaxHtPhy->field.MCS = pAd->CommonCfg.TxRate;
3190 pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;
3194 pMaxHtPhy->field.MODE = MODE_OFDM;
3195 pMaxHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.TxRate];
3196 if (pAd->CommonCfg.MinTxRate >= RATE_6 && (pAd->CommonCfg.MinTxRate <= RATE_54))
3197 {pMinHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MinTxRate];}
3199 {pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;}
3202 pHtPhy->word = (pMaxHtPhy->word);
3203 if (bLinkUp && (pAd->OpMode == OPMODE_STA))
3205 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word = pHtPhy->word;
3206 pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word = pMaxHtPhy->word;
3207 pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word = pMinHtPhy->word;
3211 switch (pAd->CommonCfg.PhyMode)
3213 case PHY_11BG_MIXED:
3215 #ifdef DOT11_N_SUPPORT
3216 case PHY_11BGN_MIXED:
3217 #endif // DOT11_N_SUPPORT //
3218 pAd->CommonCfg.MlmeRate = RATE_1;
3219 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
3220 pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
3221 pAd->CommonCfg.RtsRate = RATE_11;
3225 #ifdef DOT11_N_SUPPORT
3226 case PHY_11AGN_MIXED:
3227 case PHY_11GN_MIXED:
3229 case PHY_11AN_MIXED:
3231 #endif // DOT11_N_SUPPORT //
3232 pAd->CommonCfg.MlmeRate = RATE_6;
3233 pAd->CommonCfg.RtsRate = RATE_6;
3234 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
3235 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
3237 case PHY_11ABG_MIXED:
3238 #ifdef DOT11_N_SUPPORT
3239 case PHY_11ABGN_MIXED:
3240 #endif // DOT11_N_SUPPORT //
3241 if (pAd->CommonCfg.Channel <= 14)
3243 pAd->CommonCfg.MlmeRate = RATE_1;
3244 pAd->CommonCfg.RtsRate = RATE_1;
3245 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
3246 pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
3250 pAd->CommonCfg.MlmeRate = RATE_6;
3251 pAd->CommonCfg.RtsRate = RATE_6;
3252 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
3253 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
3257 pAd->CommonCfg.MlmeRate = RATE_6;
3258 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
3259 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
3260 pAd->CommonCfg.RtsRate = RATE_1;
3264 // Keep Basic Mlme Rate.
3266 pAd->MacTab.Content[MCAST_WCID].HTPhyMode.word = pAd->CommonCfg.MlmeTransmit.word;
3267 if (pAd->CommonCfg.MlmeTransmit.field.MODE == MODE_OFDM)
3268 pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[RATE_24];
3270 pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = RATE_1;
3271 pAd->CommonCfg.BasicMlmeRate = pAd->CommonCfg.MlmeRate;
3274 DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n",
3275 RateIdToMbps[MaxDesire], RateIdToMbps[MaxSupport], RateIdToMbps[pAd->CommonCfg.MaxTxRate], RateIdToMbps[pAd->CommonCfg.MinTxRate],
3276 /*OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)*/*auto_rate_cur_p));
3277 DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n",
3278 RateIdToMbps[pAd->CommonCfg.TxRate], RateIdToMbps[pAd->CommonCfg.RtsRate], BasicRateBitmap));
3279 DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateTxRates (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n",
3280 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 ));
3283 #ifdef DOT11_N_SUPPORT
3285 ==========================================================================
3287 This function update HT Rate setting.
3288 Input Wcid value is valid for 2 case :
3289 1. it's used for Station in infra mode that copy AP rate to Mactable.
3290 2. OR Station in adhoc mode to copy peer's HT rate to Mactable.
3292 IRQL = DISPATCH_LEVEL
3294 ==========================================================================
3296 VOID MlmeUpdateHtTxRates(
3297 IN PRTMP_ADAPTER pAd,
3300 UCHAR StbcMcs; //j, StbcMcs, bitmask;
3302 RT_HT_CAPABILITY *pRtHtCap = NULL;
3303 RT_HT_PHY_INFO *pActiveHtPhy = NULL;
3306 PRT_HT_PHY_INFO pDesireHtPhy = NULL;
3307 PHTTRANSMIT_SETTING pHtPhy = NULL;
3308 PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
3309 PHTTRANSMIT_SETTING pMinHtPhy = NULL;
3310 BOOLEAN *auto_rate_cur_p;
3312 DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates===> \n"));
3314 auto_rate_cur_p = NULL;
3316 #ifdef CONFIG_STA_SUPPORT
3317 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3319 pDesireHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
3320 pActiveHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
3321 pHtPhy = &pAd->StaCfg.HTPhyMode;
3322 pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
3323 pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
3325 auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
3327 #endif // CONFIG_STA_SUPPORT //
3329 #ifdef CONFIG_STA_SUPPORT
3330 if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
3332 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
3335 pRtHtCap = &pAd->StaActive.SupportedHtPhy;
3336 pActiveHtPhy = &pAd->StaActive.SupportedPhyInfo;
3337 StbcMcs = (UCHAR)pAd->MlmeAux.AddHtInfo.AddHtInfo3.StbcMcs;
3338 BasicMCS =pAd->MlmeAux.AddHtInfo.MCSSet[0]+(pAd->MlmeAux.AddHtInfo.MCSSet[1]<<8)+(StbcMcs<<16);
3339 if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
3340 pMaxHtPhy->field.STBC = STBC_USE;
3342 pMaxHtPhy->field.STBC = STBC_NONE;
3345 #endif // CONFIG_STA_SUPPORT //
3347 if (pDesireHtPhy->bHtEnable == FALSE)
3350 pRtHtCap = &pAd->CommonCfg.DesiredHtPhy;
3351 StbcMcs = (UCHAR)pAd->CommonCfg.AddHTInfo.AddHtInfo3.StbcMcs;
3352 BasicMCS = pAd->CommonCfg.AddHTInfo.MCSSet[0]+(pAd->CommonCfg.AddHTInfo.MCSSet[1]<<8)+(StbcMcs<<16);
3353 if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
3354 pMaxHtPhy->field.STBC = STBC_USE;
3356 pMaxHtPhy->field.STBC = STBC_NONE;
3359 // Decide MAX ht rate.
3360 if ((pRtHtCap->GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
3361 pMaxHtPhy->field.MODE = MODE_HTGREENFIELD;
3363 pMaxHtPhy->field.MODE = MODE_HTMIX;
3365 if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth) && (pRtHtCap->ChannelWidth))
3366 pMaxHtPhy->field.BW = BW_40;
3368 pMaxHtPhy->field.BW = BW_20;
3370 if (pMaxHtPhy->field.BW == BW_20)
3371 pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 & pRtHtCap->ShortGIfor20);
3373 pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 & pRtHtCap->ShortGIfor40);
3375 for (i=23; i>=0; i--) // 3*3
3378 bitmask = (1<<(i-(j*8)));
3380 if ((pActiveHtPhy->MCSSet[j] & bitmask) && (pDesireHtPhy->MCSSet[j] & bitmask))
3382 pMaxHtPhy->field.MCS = i;
3390 // Copy MIN ht rate. rt2860???
3391 pMinHtPhy->field.BW = BW_20;
3392 pMinHtPhy->field.MCS = 0;
3393 pMinHtPhy->field.STBC = 0;
3394 pMinHtPhy->field.ShortGI = 0;
3395 //If STA assigns fixed rate. update to fixed here.
3396 #ifdef CONFIG_STA_SUPPORT
3397 if ( (pAd->OpMode == OPMODE_STA) && (pDesireHtPhy->MCSSet[0] != 0xff))
3399 if (pDesireHtPhy->MCSSet[4] != 0)
3401 pMaxHtPhy->field.MCS = 32;
3402 pMinHtPhy->field.MCS = 32;
3403 DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n",pMinHtPhy->field.MCS));
3406 for (i=23; (CHAR)i >= 0; i--) // 3*3
3409 bitmask = (1<<(i-(j*8)));
3410 if ( (pDesireHtPhy->MCSSet[j] & bitmask) && (pActiveHtPhy->MCSSet[j] & bitmask))
3412 pMaxHtPhy->field.MCS = i;
3413 pMinHtPhy->field.MCS = i;
3420 #endif // CONFIG_STA_SUPPORT //
3424 pHtPhy->field.STBC = pMaxHtPhy->field.STBC;
3425 pHtPhy->field.BW = pMaxHtPhy->field.BW;
3426 pHtPhy->field.MODE = pMaxHtPhy->field.MODE;
3427 pHtPhy->field.MCS = pMaxHtPhy->field.MCS;
3428 pHtPhy->field.ShortGI = pMaxHtPhy->field.ShortGI;
3430 // use default now. rt2860
3431 if (pDesireHtPhy->MCSSet[0] != 0xff)
3432 *auto_rate_cur_p = FALSE;
3434 *auto_rate_cur_p = TRUE;
3436 DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateHtTxRates<---.AMsduSize = %d \n", pAd->CommonCfg.DesiredHtPhy.AmsduSize ));
3437 DBGPRINT(RT_DEBUG_TRACE,("TX: MCS[0] = %x (choose %d), BW = %d, ShortGI = %d, MODE = %d, \n", pActiveHtPhy->MCSSet[0],pHtPhy->field.MCS,
3438 pHtPhy->field.BW, pHtPhy->field.ShortGI, pHtPhy->field.MODE));
3439 DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== \n"));
3441 #endif // DOT11_N_SUPPORT //
3443 // IRQL = DISPATCH_LEVEL
3445 IN PRTMP_ADAPTER pAd)
3447 RT28XX_MLME_RADIO_OFF(pAd);
3450 // IRQL = DISPATCH_LEVEL
3452 IN PRTMP_ADAPTER pAd)
3454 RT28XX_MLME_RADIO_ON(pAd);
3457 // ===========================================================================================
3459 // ===========================================================================================
3462 /*! \brief initialize BSS table
3463 * \param p_tab pointer to the table
3468 IRQL = PASSIVE_LEVEL
3469 IRQL = DISPATCH_LEVEL
3478 Tab->BssOverlapNr = 0;
3479 for (i = 0; i < MAX_LEN_OF_BSS_TABLE; i++)
3481 NdisZeroMemory(&Tab->BssEntry[i], sizeof(BSS_ENTRY));
3482 Tab->BssEntry[i].Rssi = -127; // initial the rssi as a minimum value
3486 #ifdef DOT11_N_SUPPORT
3488 IN PRTMP_ADAPTER pAd,
3493 Tab->numAsOriginator = 0;
3494 Tab->numAsRecipient = 0;
3495 NdisAllocateSpinLock(&pAd->BATabLock);
3496 for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++)
3498 Tab->BARecEntry[i].REC_BA_Status = Recipient_NONE;
3499 NdisAllocateSpinLock(&(Tab->BARecEntry[i].RxReRingLock));
3501 for (i = 0; i < MAX_LEN_OF_BA_ORI_TABLE; i++)
3503 Tab->BAOriEntry[i].ORI_BA_Status = Originator_NONE;
3506 #endif // DOT11_N_SUPPORT //
3508 /*! \brief search the BSS table by SSID
3509 * \param p_tab pointer to the bss table
3510 * \param ssid SSID string
3511 * \return index of the table, BSS_NOT_FOUND if not in the table
3514 * \note search by sequential search
3516 IRQL = DISPATCH_LEVEL
3519 ULONG BssTableSearch(
3526 for (i = 0; i < Tab->BssNr; i++)
3529 // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
3530 // We should distinguish this case.
3532 if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
3533 ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
3534 MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid))
3539 return (ULONG)BSS_NOT_FOUND;
3542 ULONG BssSsidTableSearch(
3551 for (i = 0; i < Tab->BssNr; i++)
3554 // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
3555 // We should distinguish this case.
3557 if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
3558 ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
3559 MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid) &&
3560 SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen))
3565 return (ULONG)BSS_NOT_FOUND;
3568 ULONG BssTableSearchWithSSID(
3577 for (i = 0; i < Tab->BssNr; i++)
3579 if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
3580 ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
3581 MAC_ADDR_EQUAL(&(Tab->BssEntry[i].Bssid), Bssid) &&
3582 (SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen) ||
3583 (NdisEqualMemory(pSsid, ZeroSsid, SsidLen)) ||
3584 (NdisEqualMemory(Tab->BssEntry[i].Ssid, ZeroSsid, Tab->BssEntry[i].SsidLen))))
3589 return (ULONG)BSS_NOT_FOUND;
3592 // IRQL = DISPATCH_LEVEL
3593 VOID BssTableDeleteEntry(
3594 IN OUT BSS_TABLE *Tab,
3600 for (i = 0; i < Tab->BssNr; i++)
3602 if ((Tab->BssEntry[i].Channel == Channel) &&
3603 (MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid)))
3605 for (j = i; j < Tab->BssNr - 1; j++)
3607 NdisMoveMemory(&(Tab->BssEntry[j]), &(Tab->BssEntry[j + 1]), sizeof(BSS_ENTRY));
3609 NdisZeroMemory(&(Tab->BssEntry[Tab->BssNr - 1]), sizeof(BSS_ENTRY));
3616 #ifdef DOT11_N_SUPPORT
3618 ========================================================================
3619 Routine Description:
3620 Delete the Originator Entry in BAtable. Or decrease numAs Originator by 1 if needed.
3623 // IRQL = DISPATCH_LEVEL
3624 ========================================================================
3626 VOID BATableDeleteORIEntry(
3627 IN OUT PRTMP_ADAPTER pAd,
3628 IN BA_ORI_ENTRY *pBAORIEntry)
3631 if (pBAORIEntry->ORI_BA_Status != Originator_NONE)
3633 NdisAcquireSpinLock(&pAd->BATabLock);
3634 if (pBAORIEntry->ORI_BA_Status == Originator_Done)
3636 pAd->BATable.numAsOriginator -= 1;
3637 DBGPRINT(RT_DEBUG_TRACE, ("BATableDeleteORIEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient));
3638 // Erase Bitmap flag.
3640 pAd->MacTab.Content[pBAORIEntry->Wcid].TXBAbitmap &= (~(1<<(pBAORIEntry->TID) )); // If STA mode, erase flag here
3641 pAd->MacTab.Content[pBAORIEntry->Wcid].BAOriWcidArray[pBAORIEntry->TID] = 0; // If STA mode, erase flag here
3642 pBAORIEntry->ORI_BA_Status = Originator_NONE;
3643 pBAORIEntry->Token = 1;
3644 // Not clear Sequence here.
3645 NdisReleaseSpinLock(&pAd->BATabLock);
3648 #endif // DOT11_N_SUPPORT //
3656 IRQL = DISPATCH_LEVEL
3660 IN PRTMP_ADAPTER pAd,
3661 OUT BSS_ENTRY *pBss,
3666 IN USHORT BeaconPeriod,
3667 IN PCF_PARM pCfParm,
3669 IN USHORT CapabilityInfo,
3671 IN UCHAR SupRateLen,
3673 IN UCHAR ExtRateLen,
3674 IN HT_CAPABILITY_IE *pHtCapability,
3675 IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
3676 IN UCHAR HtCapabilityLen,
3677 IN UCHAR AddHtInfoLen,
3678 IN UCHAR NewExtChanOffset,
3681 IN LARGE_INTEGER TimeStamp,
3683 IN PEDCA_PARM pEdcaParm,
3684 IN PQOS_CAPABILITY_PARM pQosCapability,
3685 IN PQBSS_LOAD_PARM pQbssLoad,
3686 IN USHORT LengthVIE,
3687 IN PNDIS_802_11_VARIABLE_IEs pVIE)
3689 COPY_MAC_ADDR(pBss->Bssid, pBssid);
3690 // Default Hidden SSID to be TRUE, it will be turned to FALSE after coping SSID
3694 // For hidden SSID AP, it might send beacon with SSID len equal to 0
3695 // Or send beacon /probe response with SSID len matching real SSID length,
3696 // but SSID is all zero. such as "00-00-00-00" with length 4.
3697 // We have to prevent this case overwrite correct table
3698 if (NdisEqualMemory(Ssid, ZeroSsid, SsidLen) == 0)
3700 NdisZeroMemory(pBss->Ssid, MAX_LEN_OF_SSID);
3701 NdisMoveMemory(pBss->Ssid, Ssid, SsidLen);
3702 pBss->SsidLen = SsidLen;
3708 pBss->BssType = BssType;
3709 pBss->BeaconPeriod = BeaconPeriod;
3710 if (BssType == BSS_INFRA)
3712 if (pCfParm->bValid)
3714 pBss->CfpCount = pCfParm->CfpCount;
3715 pBss->CfpPeriod = pCfParm->CfpPeriod;
3716 pBss->CfpMaxDuration = pCfParm->CfpMaxDuration;
3717 pBss->CfpDurRemaining = pCfParm->CfpDurRemaining;
3722 pBss->AtimWin = AtimWin;
3725 pBss->CapabilityInfo = CapabilityInfo;
3726 // The privacy bit indicate security is ON, it maight be WEP, TKIP or AES
3727 // Combine with AuthMode, they will decide the connection methods.
3728 pBss->Privacy = CAP_IS_PRIVACY_ON(pBss->CapabilityInfo);
3729 ASSERT(SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
3730 if (SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES)
3731 NdisMoveMemory(pBss->SupRate, SupRate, SupRateLen);
3733 NdisMoveMemory(pBss->SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES);
3734 pBss->SupRateLen = SupRateLen;
3735 ASSERT(ExtRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
3736 NdisMoveMemory(pBss->ExtRate, ExtRate, ExtRateLen);
3737 NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen);
3738 NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
3739 pBss->NewExtChanOffset = NewExtChanOffset;
3740 pBss->ExtRateLen = ExtRateLen;
3741 pBss->Channel = Channel;
3742 pBss->CentralChannel = Channel;
3744 // Update CkipFlag. if not exists, the value is 0x0
3745 pBss->CkipFlag = CkipFlag;
3747 // New for microsoft Fixed IEs
3748 NdisMoveMemory(pBss->FixIEs.Timestamp, &TimeStamp, 8);
3749 pBss->FixIEs.BeaconInterval = BeaconPeriod;
3750 pBss->FixIEs.Capabilities = CapabilityInfo;
3752 // New for microsoft Variable IEs
3755 pBss->VarIELen = LengthVIE;
3756 NdisMoveMemory(pBss->VarIEs, pVIE, pBss->VarIELen);
3763 pBss->AddHtInfoLen = 0;
3764 pBss->HtCapabilityLen = 0;
3765 #ifdef DOT11_N_SUPPORT
3766 if (HtCapabilityLen> 0)
3768 pBss->HtCapabilityLen = HtCapabilityLen;
3769 NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen);
3770 if (AddHtInfoLen > 0)
3772 pBss->AddHtInfoLen = AddHtInfoLen;
3773 NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
3775 if ((pAddHtInfo->ControlChan > 2)&& (pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
3777 pBss->CentralChannel = pAddHtInfo->ControlChan - 2;
3779 else if ((pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
3781 pBss->CentralChannel = pAddHtInfo->ControlChan + 2;
3785 #endif // DOT11_N_SUPPORT //
3787 BssCipherParse(pBss);
3791 NdisMoveMemory(&pBss->EdcaParm, pEdcaParm, sizeof(EDCA_PARM));
3793 pBss->EdcaParm.bValid = FALSE;
3795 NdisMoveMemory(&pBss->QosCapability, pQosCapability, sizeof(QOS_CAPABILITY_PARM));
3797 pBss->QosCapability.bValid = FALSE;
3799 NdisMoveMemory(&pBss->QbssLoad, pQbssLoad, sizeof(QBSS_LOAD_PARM));
3801 pBss->QbssLoad.bValid = FALSE;
3803 #ifdef CONFIG_STA_SUPPORT
3804 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3810 NdisZeroMemory(&pBss->WpaIE.IE[0], MAX_CUSTOM_LEN);
3811 NdisZeroMemory(&pBss->RsnIE.IE[0], MAX_CUSTOM_LEN);
3812 #ifdef EXT_BUILD_CHANNEL_LIST
3813 NdisZeroMemory(&pBss->CountryString[0], 3);
3814 pBss->bHasCountryIE = FALSE;
3815 #endif // EXT_BUILD_CHANNEL_LIST //
3816 pEid = (PEID_STRUCT) pVIE;
3817 while ((Length + 2 + (USHORT)pEid->Len) <= LengthVIE)
3822 if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
3824 if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
3826 pBss->WpaIE.IELen = 0;
3829 pBss->WpaIE.IELen = pEid->Len + 2;
3830 NdisMoveMemory(pBss->WpaIE.IE, pEid, pBss->WpaIE.IELen);
3834 if (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
3836 if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
3838 pBss->RsnIE.IELen = 0;
3841 pBss->RsnIE.IELen = pEid->Len + 2;
3842 NdisMoveMemory(pBss->RsnIE.IE, pEid, pBss->RsnIE.IELen);
3845 #ifdef EXT_BUILD_CHANNEL_LIST
3847 NdisMoveMemory(&pBss->CountryString[0], pEid->Octet, 3);
3848 pBss->bHasCountryIE = TRUE;
3850 #endif // EXT_BUILD_CHANNEL_LIST //
3852 Length = Length + 2 + (USHORT)pEid->Len; // Eid[1] + Len[1]+ content[Len]
3853 pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
3856 #endif // CONFIG_STA_SUPPORT //
3860 * \brief insert an entry into the bss table
3861 * \param p_tab The BSS table
3862 * \param Bssid BSSID
3864 * \param ssid_len Length of SSID
3866 * \param beacon_period
3873 * \param channel_idx
3877 * \note If SSID is identical, the old entry will be replaced by the new one
3879 IRQL = DISPATCH_LEVEL
3882 ULONG BssTableSetEntry(
3883 IN PRTMP_ADAPTER pAd,
3889 IN USHORT BeaconPeriod,
3892 IN USHORT CapabilityInfo,
3894 IN UCHAR SupRateLen,
3896 IN UCHAR ExtRateLen,
3897 IN HT_CAPABILITY_IE *pHtCapability,
3898 IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
3899 IN UCHAR HtCapabilityLen,
3900 IN UCHAR AddHtInfoLen,
3901 IN UCHAR NewExtChanOffset,
3904 IN LARGE_INTEGER TimeStamp,
3906 IN PEDCA_PARM pEdcaParm,
3907 IN PQOS_CAPABILITY_PARM pQosCapability,
3908 IN PQBSS_LOAD_PARM pQbssLoad,
3909 IN USHORT LengthVIE,
3910 IN PNDIS_802_11_VARIABLE_IEs pVIE)
3914 Idx = BssTableSearchWithSSID(Tab, pBssid, Ssid, SsidLen, ChannelNo);
3915 if (Idx == BSS_NOT_FOUND)
3917 if (Tab->BssNr >= MAX_LEN_OF_BSS_TABLE)
3920 // It may happen when BSS Table was full.
3921 // The desired AP will not be added into BSS Table
3922 // In this case, if we found the desired AP then overwrite BSS Table.
3924 if(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
3926 if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, pBssid) ||
3927 SSID_EQUAL(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Ssid, SsidLen))
3929 Idx = Tab->BssOverlapNr;
3930 BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
3931 CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
3932 NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
3933 Tab->BssOverlapNr = (Tab->BssOverlapNr++) % MAX_LEN_OF_BSS_TABLE;
3939 return BSS_NOT_FOUND;
3943 BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
3944 CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
3945 NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
3950 BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod,CfParm, AtimWin,
3951 CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
3952 NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
3958 #ifdef CONFIG_STA_SUPPORT
3959 #ifdef DOT11_N_SUPPORT
3960 #ifdef DOT11N_DRAFT3
3962 IN PRTMP_ADAPTER pAd)
3966 for (i = 0;i < MAX_TRIGGER_EVENT;i++)
3967 pAd->CommonCfg.TriggerEventTab.EventA[i].bValid = FALSE;
3969 pAd->CommonCfg.TriggerEventTab.EventANo = 0;
3970 pAd->CommonCfg.TriggerEventTab.EventBCountDown = 0;
3973 ULONG TriEventTableSetEntry(
3974 IN PRTMP_ADAPTER pAd,
3975 OUT TRIGGER_EVENT_TAB *Tab,
3977 IN HT_CAPABILITY_IE *pHtCapability,
3978 IN UCHAR HtCapabilityLen,
3983 if (HtCapabilityLen == 0)
3985 if (Tab->EventANo < MAX_TRIGGER_EVENT)
3987 RTMPMoveMemory(Tab->EventA[Tab->EventANo].BSSID, pBssid, 6);
3988 Tab->EventA[Tab->EventANo].bValid = TRUE;
3989 Tab->EventA[Tab->EventANo].Channel = ChannelNo;
3990 Tab->EventA[Tab->EventANo].CDCounter = pAd->CommonCfg.Dot11BssWidthChanTranDelay;
3993 // Beacon has Regulatory class IE. So use beacon's
3994 Tab->EventA[Tab->EventANo].RegClass = RegClass;
3998 // Use Station's Regulatory class instead.
3999 if (pAd->StaActive.SupportedHtPhy.bHtEnable == TRUE)
4001 if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
4003 Tab->EventA[Tab->EventANo].RegClass = 32;
4005 else if (pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
4006 Tab->EventA[Tab->EventANo].RegClass = 33;
4009 Tab->EventA[Tab->EventANo].RegClass = ??;
4016 else if (pHtCapability->HtCapInfo.Intolerant40)
4018 Tab->EventBCountDown = pAd->CommonCfg.Dot11BssWidthChanTranDelay;
4024 ========================================================================
4025 Routine Description:
4026 Trigger Event table Maintainence called once every second.
4029 // IRQL = DISPATCH_LEVEL
4030 ========================================================================
4032 VOID TriEventCounterMaintenance(
4033 IN PRTMP_ADAPTER pAd)
4036 BOOLEAN bNotify = FALSE;
4037 for (i = 0;i < MAX_TRIGGER_EVENT;i++)
4039 if (pAd->CommonCfg.TriggerEventTab.EventA[i].bValid && (pAd->CommonCfg.TriggerEventTab.EventA[i].CDCounter > 0))
4041 pAd->CommonCfg.TriggerEventTab.EventA[i].CDCounter--;
4042 if (pAd->CommonCfg.TriggerEventTab.EventA[i].CDCounter == 0)
4044 pAd->CommonCfg.TriggerEventTab.EventA[i].bValid = FALSE;
4045 pAd->CommonCfg.TriggerEventTab.EventANo --;
4046 // Need to send 20/40 Coexistence Notify frame if has status change.
4051 if (pAd->CommonCfg.TriggerEventTab.EventBCountDown > 0)
4053 pAd->CommonCfg.TriggerEventTab.EventBCountDown--;
4054 if (pAd->CommonCfg.TriggerEventTab.EventBCountDown == 0)
4058 if (bNotify == TRUE)
4059 Update2040CoexistFrameAndNotify(pAd, BSSID_WCID, TRUE);
4061 #endif // DOT11N_DRAFT3 //
4062 #endif // DOT11_N_SUPPORT //
4064 // IRQL = DISPATCH_LEVEL
4065 VOID BssTableSsidSort(
4066 IN PRTMP_ADAPTER pAd,
4067 OUT BSS_TABLE *OutTab,
4072 BssTableInit(OutTab);
4074 for (i = 0; i < pAd->ScanTab.BssNr; i++)
4076 BSS_ENTRY *pInBss = &pAd->ScanTab.BssEntry[i];
4077 BOOLEAN bIsHiddenApIncluded = FALSE;
4079 if (((pAd->CommonCfg.bIEEE80211H == 1) &&
4080 (pAd->MlmeAux.Channel > 14) &&
4081 RadarChannelCheck(pAd, pInBss->Channel))
4082 #ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
4083 || (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
4084 #endif // CARRIER_DETECTION_SUPPORT //
4088 bIsHiddenApIncluded = TRUE;
4091 if ((pInBss->BssType == pAd->StaCfg.BssType) &&
4092 (SSID_EQUAL(Ssid, SsidLen, pInBss->Ssid, pInBss->SsidLen) || bIsHiddenApIncluded))
4094 BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
4097 #ifdef EXT_BUILD_CHANNEL_LIST
4098 // If no Country IE exists no Connection will be established when IEEE80211dClientMode is strict.
4099 if ((pAd->StaCfg.IEEE80211dClientMode == Rt802_11_D_Strict) &&
4100 (pInBss->bHasCountryIE == FALSE))
4102 DBGPRINT(RT_DEBUG_TRACE,("StaCfg.IEEE80211dClientMode == Rt802_11_D_Strict, but this AP doesn't have country IE.\n"));
4105 #endif // EXT_BUILD_CHANNEL_LIST //
4107 #ifdef DOT11_N_SUPPORT
4108 // 2.4G/5G N only mode
4109 if ((pInBss->HtCapabilityLen == 0) &&
4110 ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
4112 DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
4115 #endif // DOT11_N_SUPPORT //
4118 // Check the Authmode first
4119 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
4121 // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
4122 if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
4126 // Check cipher suite, AP must have more secured cipher than station setting
4127 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
4129 // If it's not mixed mode, we should only let BSS pass with the same encryption
4130 if (pInBss->WPA.bMixMode == FALSE)
4131 if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
4134 // check group cipher
4135 if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) &&
4136 (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP40Enabled) &&
4137 (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP104Enabled))
4140 // check pairwise cipher, skip if none matched
4141 // If profile set to AES, let it pass without question.
4142 // If profile set to TKIP, we must find one mateched
4143 if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
4144 (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
4145 (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
4148 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
4150 // If it's not mixed mode, we should only let BSS pass with the same encryption
4151 if (pInBss->WPA2.bMixMode == FALSE)
4152 if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
4155 // check group cipher
4156 if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) &&
4157 (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP40Enabled) &&
4158 (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP104Enabled))
4161 // check pairwise cipher, skip if none matched
4162 // If profile set to AES, let it pass without question.
4163 // If profile set to TKIP, we must find one mateched
4164 if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
4165 (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
4166 (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
4170 // Bss Type matched, SSID matched.
4171 // We will check wepstatus for qualification Bss
4172 else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
4174 DBGPRINT(RT_DEBUG_TRACE,("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n", pAd->StaCfg.WepStatus, pInBss->WepStatus));
4176 // For the SESv2 case, we will not qualify WepStatus.
4182 // Since the AP is using hidden SSID, and we are trying to connect to ANY
4183 // It definitely will fail. So, skip it.
4184 // CCX also require not even try to connect it!!
4188 #ifdef DOT11_N_SUPPORT
4189 // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
4190 // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
4191 if ((pInBss->CentralChannel != pInBss->Channel) &&
4192 (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
4194 if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
4196 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
4198 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
4202 if (pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BAND_WIDTH_20)
4208 #endif // DOT11_N_SUPPORT //
4210 // copy matching BSS from InTab to OutTab
4211 NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
4215 else if ((pInBss->BssType == pAd->StaCfg.BssType) && (SsidLen == 0))
4217 BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
4220 #ifdef DOT11_N_SUPPORT
4221 // 2.4G/5G N only mode
4222 if ((pInBss->HtCapabilityLen == 0) &&
4223 ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
4225 DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
4228 #endif // DOT11_N_SUPPORT //
4231 // Check the Authmode first
4232 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
4234 // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
4235 if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
4239 // Check cipher suite, AP must have more secured cipher than station setting
4240 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
4242 // If it's not mixed mode, we should only let BSS pass with the same encryption
4243 if (pInBss->WPA.bMixMode == FALSE)
4244 if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
4247 // check group cipher
4248 if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
4251 // check pairwise cipher, skip if none matched
4252 // If profile set to AES, let it pass without question.
4253 // If profile set to TKIP, we must find one mateched
4254 if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
4255 (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
4256 (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
4259 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
4261 // If it's not mixed mode, we should only let BSS pass with the same encryption
4262 if (pInBss->WPA2.bMixMode == FALSE)
4263 if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
4266 // check group cipher
4267 if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
4270 // check pairwise cipher, skip if none matched
4271 // If profile set to AES, let it pass without question.
4272 // If profile set to TKIP, we must find one mateched
4273 if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
4274 (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
4275 (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
4279 // Bss Type matched, SSID matched.
4280 // We will check wepstatus for qualification Bss
4281 else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
4284 #ifdef DOT11_N_SUPPORT
4285 // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
4286 // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
4287 if ((pInBss->CentralChannel != pInBss->Channel) &&
4288 (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
4290 if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
4292 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
4294 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
4297 #endif // DOT11_N_SUPPORT //
4299 // copy matching BSS from InTab to OutTab
4300 NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
4305 if (OutTab->BssNr >= MAX_LEN_OF_BSS_TABLE)
4309 BssTableSortByRssi(OutTab);
4313 // IRQL = DISPATCH_LEVEL
4314 VOID BssTableSortByRssi(
4315 IN OUT BSS_TABLE *OutTab)
4320 for (i = 0; i < OutTab->BssNr - 1; i++)
4322 for (j = i+1; j < OutTab->BssNr; j++)
4324 if (OutTab->BssEntry[j].Rssi > OutTab->BssEntry[i].Rssi)
4326 NdisMoveMemory(&TmpBss, &OutTab->BssEntry[j], sizeof(BSS_ENTRY));
4327 NdisMoveMemory(&OutTab->BssEntry[j], &OutTab->BssEntry[i], sizeof(BSS_ENTRY));
4328 NdisMoveMemory(&OutTab->BssEntry[i], &TmpBss, sizeof(BSS_ENTRY));
4333 #endif // CONFIG_STA_SUPPORT //
4336 VOID BssCipherParse(
4337 IN OUT PBSS_ENTRY pBss)
4341 PRSN_IE_HEADER_STRUCT pRsnHeader;
4342 PCIPHER_SUITE_STRUCT pCipher;
4343 PAKM_SUITE_STRUCT pAKM;
4346 NDIS_802_11_ENCRYPTION_STATUS TmpCipher;
4349 // WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame.
4353 pBss->WepStatus = Ndis802_11WEPEnabled;
4357 pBss->WepStatus = Ndis802_11WEPDisabled;
4359 // Set default to disable & open authentication before parsing variable IE
4360 pBss->AuthMode = Ndis802_11AuthModeOpen;
4361 pBss->AuthModeAux = Ndis802_11AuthModeOpen;
4364 pBss->WPA.PairCipher = Ndis802_11WEPDisabled;
4365 pBss->WPA.PairCipherAux = Ndis802_11WEPDisabled;
4366 pBss->WPA.GroupCipher = Ndis802_11WEPDisabled;
4367 pBss->WPA.RsnCapability = 0;
4368 pBss->WPA.bMixMode = FALSE;
4370 // Init WPA2 setting
4371 pBss->WPA2.PairCipher = Ndis802_11WEPDisabled;
4372 pBss->WPA2.PairCipherAux = Ndis802_11WEPDisabled;
4373 pBss->WPA2.GroupCipher = Ndis802_11WEPDisabled;
4374 pBss->WPA2.RsnCapability = 0;
4375 pBss->WPA2.bMixMode = FALSE;
4378 Length = (INT) pBss->VarIELen;
4382 // Parse cipher suite base on WPA1 & WPA2, they should be parsed differently
4383 pTmp = ((PUCHAR) pBss->VarIEs) + pBss->VarIELen - Length;
4384 pEid = (PEID_STRUCT) pTmp;
4388 //Parse Cisco IE_WPA (LEAP, CCKM, etc.)
4389 if ( NdisEqualMemory((pTmp+8), CISCO_OUI, 3))
4395 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4396 pBss->WepStatus = Ndis802_11Encryption1Enabled;
4397 pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
4398 pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
4401 pBss->WepStatus = Ndis802_11Encryption2Enabled;
4402 pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
4403 pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
4406 pBss->WepStatus = Ndis802_11Encryption3Enabled;
4407 pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
4408 pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
4414 // if Cisco IE_WPA, break
4417 else if (NdisEqualMemory(pEid->Octet, SES_OUI, 3) && (pEid->Len == 7))
4422 else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4) != 1)
4424 // if unsupported vendor specific IE
4427 // Skip OUI, version, and multicast suite
4428 // This part should be improved in the future when AP supported multiple cipher suite.
4429 // For now, it's OK since almost all APs have fixed cipher suite supported.
4430 // pTmp = (PUCHAR) pEid->Octet;
4433 // Cipher Suite Selectors from Spec P802.11i/D3.2 P26.
4441 // Parse group cipher
4445 pBss->WPA.GroupCipher = Ndis802_11GroupWEP40Enabled;
4448 pBss->WPA.GroupCipher = Ndis802_11GroupWEP104Enabled;
4451 pBss->WPA.GroupCipher = Ndis802_11Encryption2Enabled;
4454 pBss->WPA.GroupCipher = Ndis802_11Encryption3Enabled;
4459 // number of unicast suite
4462 // skip all unicast cipher suites
4463 //Count = *(PUSHORT) pTmp;
4464 Count = (pTmp[1]<<8) + pTmp[0];
4465 pTmp += sizeof(USHORT);
4467 // Parsing all unicast cipher suite
4472 TmpCipher = Ndis802_11WEPDisabled;
4476 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4477 TmpCipher = Ndis802_11Encryption1Enabled;
4480 TmpCipher = Ndis802_11Encryption2Enabled;
4483 TmpCipher = Ndis802_11Encryption3Enabled;
4488 if (TmpCipher > pBss->WPA.PairCipher)
4490 // Move the lower cipher suite to PairCipherAux
4491 pBss->WPA.PairCipherAux = pBss->WPA.PairCipher;
4492 pBss->WPA.PairCipher = TmpCipher;
4496 pBss->WPA.PairCipherAux = TmpCipher;
4502 // 4. get AKM suite counts
4503 //Count = *(PUSHORT) pTmp;
4504 Count = (pTmp[1]<<8) + pTmp[0];
4505 pTmp += sizeof(USHORT);
4511 // Set AP support WPA mode
4512 if (pBss->AuthMode == Ndis802_11AuthModeOpen)
4513 pBss->AuthMode = Ndis802_11AuthModeWPA;
4515 pBss->AuthModeAux = Ndis802_11AuthModeWPA;
4518 // Set AP support WPA mode
4519 if (pBss->AuthMode == Ndis802_11AuthModeOpen)
4520 pBss->AuthMode = Ndis802_11AuthModeWPAPSK;
4522 pBss->AuthModeAux = Ndis802_11AuthModeWPAPSK;
4529 // Fixed for WPA-None
4530 if (pBss->BssType == BSS_ADHOC)
4532 pBss->AuthMode = Ndis802_11AuthModeWPANone;
4533 pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
4534 pBss->WepStatus = pBss->WPA.GroupCipher;
4535 // Patched bugs for old driver
4536 if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
4537 pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
4540 pBss->WepStatus = pBss->WPA.PairCipher;
4542 // Check the Pair & Group, if different, turn on mixed mode flag
4543 if (pBss->WPA.GroupCipher != pBss->WPA.PairCipher)
4544 pBss->WPA.bMixMode = TRUE;
4549 pRsnHeader = (PRSN_IE_HEADER_STRUCT) pTmp;
4551 // 0. Version must be 1
4552 if (le2cpu16(pRsnHeader->Version) != 1)
4554 pTmp += sizeof(RSN_IE_HEADER_STRUCT);
4556 // 1. Check group cipher
4557 pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
4558 if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
4561 // Parse group cipher
4562 switch (pCipher->Type)
4565 pBss->WPA2.GroupCipher = Ndis802_11GroupWEP40Enabled;
4568 pBss->WPA2.GroupCipher = Ndis802_11GroupWEP104Enabled;
4571 pBss->WPA2.GroupCipher = Ndis802_11Encryption2Enabled;
4574 pBss->WPA2.GroupCipher = Ndis802_11Encryption3Enabled;
4579 // set to correct offset for next parsing
4580 pTmp += sizeof(CIPHER_SUITE_STRUCT);
4582 // 2. Get pairwise cipher counts
4583 //Count = *(PUSHORT) pTmp;
4584 Count = (pTmp[1]<<8) + pTmp[0];
4585 pTmp += sizeof(USHORT);
4587 // 3. Get pairwise cipher
4588 // Parsing all unicast cipher suite
4592 pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
4593 TmpCipher = Ndis802_11WEPDisabled;
4594 switch (pCipher->Type)
4597 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4598 TmpCipher = Ndis802_11Encryption1Enabled;
4601 TmpCipher = Ndis802_11Encryption2Enabled;
4604 TmpCipher = Ndis802_11Encryption3Enabled;
4609 if (TmpCipher > pBss->WPA2.PairCipher)
4611 // Move the lower cipher suite to PairCipherAux
4612 pBss->WPA2.PairCipherAux = pBss->WPA2.PairCipher;
4613 pBss->WPA2.PairCipher = TmpCipher;
4617 pBss->WPA2.PairCipherAux = TmpCipher;
4619 pTmp += sizeof(CIPHER_SUITE_STRUCT);
4623 // 4. get AKM suite counts
4624 //Count = *(PUSHORT) pTmp;
4625 Count = (pTmp[1]<<8) + pTmp[0];
4626 pTmp += sizeof(USHORT);
4628 // 5. Get AKM ciphers
4629 pAKM = (PAKM_SUITE_STRUCT) pTmp;
4630 if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
4636 // Set AP support WPA mode
4637 if (pBss->AuthMode == Ndis802_11AuthModeOpen)
4638 pBss->AuthMode = Ndis802_11AuthModeWPA2;
4640 pBss->AuthModeAux = Ndis802_11AuthModeWPA2;
4643 // Set AP support WPA mode
4644 if (pBss->AuthMode == Ndis802_11AuthModeOpen)
4645 pBss->AuthMode = Ndis802_11AuthModeWPA2PSK;
4647 pBss->AuthModeAux = Ndis802_11AuthModeWPA2PSK;
4652 pTmp += (Count * sizeof(AKM_SUITE_STRUCT));
4654 // Fixed for WPA-None
4655 if (pBss->BssType == BSS_ADHOC)
4657 pBss->AuthMode = Ndis802_11AuthModeWPANone;
4658 pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
4659 pBss->WPA.PairCipherAux = pBss->WPA2.PairCipherAux;
4660 pBss->WPA.GroupCipher = pBss->WPA2.GroupCipher;
4661 pBss->WepStatus = pBss->WPA.GroupCipher;
4662 // Patched bugs for old driver
4663 if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
4664 pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
4666 pBss->WepStatus = pBss->WPA2.PairCipher;
4668 // 6. Get RSN capability
4669 //pBss->WPA2.RsnCapability = *(PUSHORT) pTmp;
4670 pBss->WPA2.RsnCapability = (pTmp[1]<<8) + pTmp[0];
4671 pTmp += sizeof(USHORT);
4673 // Check the Pair & Group, if different, turn on mixed mode flag
4674 if (pBss->WPA2.GroupCipher != pBss->WPA2.PairCipher)
4675 pBss->WPA2.bMixMode = TRUE;
4681 Length -= (pEid->Len + 2);
4685 // ===========================================================================================
4687 // ===========================================================================================
4689 /*! \brief generates a random mac address value for IBSS BSSID
4690 * \param Addr the bssid location
4695 VOID MacAddrRandomBssid(
4696 IN PRTMP_ADAPTER pAd,
4701 for (i = 0; i < MAC_ADDR_LEN; i++)
4703 pAddr[i] = RandomByte(pAd);
4706 pAddr[0] = (pAddr[0] & 0xfe) | 0x02; // the first 2 bits must be 01xxxxxxxx
4709 /*! \brief init the management mac frame header
4710 * \param p_hdr mac header
4711 * \param subtype subtype of the frame
4712 * \param p_ds destination address, don't care if it is a broadcast address
4714 * \pre the station has the following information in the pAd->StaCfg
4718 * \note this function initializes the following field
4720 IRQL = PASSIVE_LEVEL
4721 IRQL = DISPATCH_LEVEL
4724 VOID MgtMacHeaderInit(
4725 IN PRTMP_ADAPTER pAd,
4726 IN OUT PHEADER_802_11 pHdr80211,
4732 NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
4734 pHdr80211->FC.Type = BTYPE_MGMT;
4735 pHdr80211->FC.SubType = SubType;
4736 pHdr80211->FC.ToDs = ToDs;
4737 COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
4738 #ifdef CONFIG_STA_SUPPORT
4739 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
4740 COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
4741 #endif // CONFIG_STA_SUPPORT //
4742 COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
4745 // ===========================================================================================
4747 // ===========================================================================================
4749 /*!***************************************************************************
4750 * This routine build an outgoing frame, and fill all information specified
4751 * in argument list to the frame body. The actual frame size is the summation
4754 * Buffer - pointer to a pre-allocated memory segment
4755 * args - a list of <int arg_size, arg> pairs.
4756 * NOTE NOTE NOTE!!!! the last argument must be NULL, otherwise this
4757 * function will FAIL!!!
4759 * Size of the buffer
4761 * MakeOutgoingFrame(Buffer, output_length, 2, &fc, 2, &dur, 6, p_addr1, 6,p_addr2, END_OF_ARGS);
4763 IRQL = PASSIVE_LEVEL
4764 IRQL = DISPATCH_LEVEL
4766 ****************************************************************************/
4767 ULONG MakeOutgoingFrame(
4769 OUT ULONG *FrameLen, ...)
4776 // calculates the total length
4778 va_start(Args, FrameLen);
4781 leng = va_arg(Args, int);
4782 if (leng == END_OF_ARGS)
4786 p = va_arg(Args, PVOID);
4787 NdisMoveMemory(&Buffer[TotLeng], p, leng);
4788 TotLeng = TotLeng + leng;
4791 va_end(Args); /* clean up */
4792 *FrameLen = TotLeng;
4796 // ===========================================================================================
4798 // ===========================================================================================
4800 /*! \brief Initialize The MLME Queue, used by MLME Functions
4801 * \param *Queue The MLME Queue
4802 * \return Always Return NDIS_STATE_SUCCESS in this implementation
4805 * \note Because this is done only once (at the init stage), no need to be locked
4807 IRQL = PASSIVE_LEVEL
4810 NDIS_STATUS MlmeQueueInit(
4811 IN MLME_QUEUE *Queue)
4815 NdisAllocateSpinLock(&Queue->Lock);
4821 for (i = 0; i < MAX_LEN_OF_MLME_QUEUE; i++)
4823 Queue->Entry[i].Occupied = FALSE;
4824 Queue->Entry[i].MsgLen = 0;
4825 NdisZeroMemory(Queue->Entry[i].Msg, MGMT_DMA_BUFFER_SIZE);
4828 return NDIS_STATUS_SUCCESS;
4831 /*! \brief Enqueue a message for other threads, if they want to send messages to MLME thread
4832 * \param *Queue The MLME Queue
4833 * \param Machine The State Machine Id
4834 * \param MsgType The Message Type
4835 * \param MsgLen The Message length
4836 * \param *Msg The message pointer
4837 * \return TRUE if enqueue is successful, FALSE if the queue is full
4840 * \note The message has to be initialized
4842 IRQL = PASSIVE_LEVEL
4843 IRQL = DISPATCH_LEVEL
4846 BOOLEAN MlmeEnqueue(
4847 IN PRTMP_ADAPTER pAd,
4854 MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
4856 // Do nothing if the driver is starting halt state.
4857 // This might happen when timer already been fired before cancel timer with mlmehalt
4858 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
4861 // First check the size, it MUST not exceed the mlme queue size
4862 if (MsgLen > MGMT_DMA_BUFFER_SIZE)
4864 DBGPRINT_ERR(("MlmeEnqueue: msg too large, size = %ld \n", MsgLen));
4868 if (MlmeQueueFull(Queue))
4873 NdisAcquireSpinLock(&(Queue->Lock));
4877 if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
4882 Queue->Entry[Tail].Wcid = RESERVED_WCID;
4883 Queue->Entry[Tail].Occupied = TRUE;
4884 Queue->Entry[Tail].Machine = Machine;
4885 Queue->Entry[Tail].MsgType = MsgType;
4886 Queue->Entry[Tail].MsgLen = MsgLen;
4890 NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
4893 NdisReleaseSpinLock(&(Queue->Lock));
4897 /*! \brief This function is used when Recv gets a MLME message
4898 * \param *Queue The MLME Queue
4899 * \param TimeStampHigh The upper 32 bit of timestamp
4900 * \param TimeStampLow The lower 32 bit of timestamp
4901 * \param Rssi The receiving RSSI strength
4902 * \param MsgLen The length of the message
4903 * \param *Msg The message pointer
4904 * \return TRUE if everything ok, FALSE otherwise (like Queue Full)
4908 IRQL = DISPATCH_LEVEL
4911 BOOLEAN MlmeEnqueueForRecv(
4912 IN PRTMP_ADAPTER pAd,
4914 IN ULONG TimeStampHigh,
4915 IN ULONG TimeStampLow,
4924 PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
4926 MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
4929 /* Nothing to do in ATE mode */
4932 #endif // RALINK_ATE //
4934 // Do nothing if the driver is starting halt state.
4935 // This might happen when timer already been fired before cancel timer with mlmehalt
4936 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
4938 DBGPRINT_ERR(("MlmeEnqueueForRecv: fRTMP_ADAPTER_HALT_IN_PROGRESS\n"));
4942 // First check the size, it MUST not exceed the mlme queue size
4943 if (MsgLen > MGMT_DMA_BUFFER_SIZE)
4945 DBGPRINT_ERR(("MlmeEnqueueForRecv: frame too large, size = %ld \n", MsgLen));
4949 if (MlmeQueueFull(Queue))
4954 #ifdef CONFIG_STA_SUPPORT
4955 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
4957 if (!MsgTypeSubst(pAd, pFrame, &Machine, &MsgType))
4959 DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n",pFrame->Hdr.FC.SubType));
4963 #endif // CONFIG_STA_SUPPORT //
4965 // OK, we got all the informations, it is time to put things into queue
4966 NdisAcquireSpinLock(&(Queue->Lock));
4970 if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
4974 Queue->Entry[Tail].Occupied = TRUE;
4975 Queue->Entry[Tail].Machine = Machine;
4976 Queue->Entry[Tail].MsgType = MsgType;
4977 Queue->Entry[Tail].MsgLen = MsgLen;
4978 Queue->Entry[Tail].TimeStamp.u.LowPart = TimeStampLow;
4979 Queue->Entry[Tail].TimeStamp.u.HighPart = TimeStampHigh;
4980 Queue->Entry[Tail].Rssi0 = Rssi0;
4981 Queue->Entry[Tail].Rssi1 = Rssi1;
4982 Queue->Entry[Tail].Rssi2 = Rssi2;
4983 Queue->Entry[Tail].Signal = Signal;
4984 Queue->Entry[Tail].Wcid = (UCHAR)Wcid;
4986 Queue->Entry[Tail].Channel = pAd->LatchRfRegs.Channel;
4990 NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
4993 NdisReleaseSpinLock(&(Queue->Lock));
4995 RT28XX_MLME_HANDLER(pAd);
5001 /*! \brief Dequeue a message from the MLME Queue
5002 * \param *Queue The MLME Queue
5003 * \param *Elem The message dequeued from MLME Queue
5004 * \return TRUE if the Elem contains something, FALSE otherwise
5008 IRQL = DISPATCH_LEVEL
5011 BOOLEAN MlmeDequeue(
5012 IN MLME_QUEUE *Queue,
5013 OUT MLME_QUEUE_ELEM **Elem)
5015 NdisAcquireSpinLock(&(Queue->Lock));
5016 *Elem = &(Queue->Entry[Queue->Head]);
5019 if (Queue->Head == MAX_LEN_OF_MLME_QUEUE)
5023 NdisReleaseSpinLock(&(Queue->Lock));
5027 // IRQL = DISPATCH_LEVEL
5028 VOID MlmeRestartStateMachine(
5029 IN PRTMP_ADAPTER pAd)
5031 MLME_QUEUE_ELEM *Elem = NULL;
5032 #ifdef CONFIG_STA_SUPPORT
5034 #endif // CONFIG_STA_SUPPORT //
5036 DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n"));
5038 NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
5039 if(pAd->Mlme.bRunning)
5041 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
5046 pAd->Mlme.bRunning = TRUE;
5048 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
5050 // Remove all Mlme queues elements
5051 while (!MlmeQueueEmpty(&pAd->Mlme.Queue))
5053 //From message type, determine which state machine I should drive
5054 if (MlmeDequeue(&pAd->Mlme.Queue, &Elem))
5056 // free MLME element
5057 Elem->Occupied = FALSE;
5062 DBGPRINT_ERR(("MlmeRestartStateMachine: MlmeQueue empty\n"));
5066 #ifdef CONFIG_STA_SUPPORT
5067 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
5069 #ifdef QOS_DLS_SUPPORT
5071 #endif // QOS_DLS_SUPPORT //
5072 // Cancel all timer events
5073 // Be careful to cancel new added timer
5074 RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
5075 RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
5076 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
5077 RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
5078 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
5079 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
5081 #ifdef QOS_DLS_SUPPORT
5082 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
5084 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &Cancelled);
5086 #endif // QOS_DLS_SUPPORT //
5088 #endif // CONFIG_STA_SUPPORT //
5090 // Change back to original channel in case of doing scan
5091 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
5092 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
5094 // Resume MSDU which is turned off durning scan
5095 RTMPResumeMsduTransmission(pAd);
5097 #ifdef CONFIG_STA_SUPPORT
5098 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
5100 // Set all state machines back IDLE
5101 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
5102 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
5103 pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
5104 pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE;
5105 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
5106 pAd->Mlme.ActMachine.CurrState = ACT_IDLE;
5107 #ifdef QOS_DLS_SUPPORT
5108 pAd->Mlme.DlsMachine.CurrState = DLS_IDLE;
5109 #endif // QOS_DLS_SUPPORT //
5111 #endif // CONFIG_STA_SUPPORT //
5113 // Remove running state
5114 NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
5115 pAd->Mlme.bRunning = FALSE;
5116 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
5119 /*! \brief test if the MLME Queue is empty
5120 * \param *Queue The MLME Queue
5121 * \return TRUE if the Queue is empty, FALSE otherwise
5125 IRQL = DISPATCH_LEVEL
5128 BOOLEAN MlmeQueueEmpty(
5129 IN MLME_QUEUE *Queue)
5133 NdisAcquireSpinLock(&(Queue->Lock));
5134 Ans = (Queue->Num == 0);
5135 NdisReleaseSpinLock(&(Queue->Lock));
5140 /*! \brief test if the MLME Queue is full
5141 * \param *Queue The MLME Queue
5142 * \return TRUE if the Queue is empty, FALSE otherwise
5146 IRQL = PASSIVE_LEVEL
5147 IRQL = DISPATCH_LEVEL
5150 BOOLEAN MlmeQueueFull(
5151 IN MLME_QUEUE *Queue)
5155 NdisAcquireSpinLock(&(Queue->Lock));
5156 Ans = (Queue->Num == MAX_LEN_OF_MLME_QUEUE || Queue->Entry[Queue->Tail].Occupied);
5157 NdisReleaseSpinLock(&(Queue->Lock));
5162 /*! \brief The destructor of MLME Queue
5167 * \note Clear Mlme Queue, Set Queue->Num to Zero.
5169 IRQL = PASSIVE_LEVEL
5172 VOID MlmeQueueDestroy(
5173 IN MLME_QUEUE *pQueue)
5175 NdisAcquireSpinLock(&(pQueue->Lock));
5179 NdisReleaseSpinLock(&(pQueue->Lock));
5180 NdisFreeSpinLock(&(pQueue->Lock));
5183 /*! \brief To substitute the message type if the message is coming from external
5184 * \param pFrame The frame received
5185 * \param *Machine The state machine
5186 * \param *MsgType the message type for the state machine
5187 * \return TRUE if the substitution is successful, FALSE otherwise
5191 IRQL = DISPATCH_LEVEL
5194 #ifdef CONFIG_STA_SUPPORT
5195 BOOLEAN MsgTypeSubst(
5196 IN PRTMP_ADAPTER pAd,
5197 IN PFRAME_802_11 pFrame,
5205 // Pointer to start of data frames including SNAP header
5206 pData = (PUCHAR) pFrame + LENGTH_802_11;
5208 // The only data type will pass to this function is EAPOL frame
5209 if (pFrame->Hdr.FC.Type == BTYPE_DATA)
5211 if (NdisEqualMemory(SNAP_AIRONET, pData, LENGTH_802_1_H))
5213 // Cisco Aironet SNAP header
5214 *Machine = AIRONET_STATE_MACHINE;
5215 *MsgType = MT2_AIRONET_MSG;
5219 if ( pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP ) //LEAP
5222 *Machine = LEAP_STATE_MACHINE;
5223 EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
5224 return (LeapMsgTypeSubst(EAPType, MsgType));
5227 #endif // LEAP_SUPPORT //
5229 *Machine = WPA_PSK_STATE_MACHINE;
5230 EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
5231 return(WpaMsgTypeSubst(EAPType, MsgType));
5235 switch (pFrame->Hdr.FC.SubType)
5237 case SUBTYPE_ASSOC_REQ:
5238 *Machine = ASSOC_STATE_MACHINE;
5239 *MsgType = MT2_PEER_ASSOC_REQ;
5241 case SUBTYPE_ASSOC_RSP:
5242 *Machine = ASSOC_STATE_MACHINE;
5243 *MsgType = MT2_PEER_ASSOC_RSP;
5245 case SUBTYPE_REASSOC_REQ:
5246 *Machine = ASSOC_STATE_MACHINE;
5247 *MsgType = MT2_PEER_REASSOC_REQ;
5249 case SUBTYPE_REASSOC_RSP:
5250 *Machine = ASSOC_STATE_MACHINE;
5251 *MsgType = MT2_PEER_REASSOC_RSP;
5253 case SUBTYPE_PROBE_REQ:
5254 *Machine = SYNC_STATE_MACHINE;
5255 *MsgType = MT2_PEER_PROBE_REQ;
5257 case SUBTYPE_PROBE_RSP:
5258 *Machine = SYNC_STATE_MACHINE;
5259 *MsgType = MT2_PEER_PROBE_RSP;
5261 case SUBTYPE_BEACON:
5262 *Machine = SYNC_STATE_MACHINE;
5263 *MsgType = MT2_PEER_BEACON;
5266 *Machine = SYNC_STATE_MACHINE;
5267 *MsgType = MT2_PEER_ATIM;
5269 case SUBTYPE_DISASSOC:
5270 *Machine = ASSOC_STATE_MACHINE;
5271 *MsgType = MT2_PEER_DISASSOC_REQ;
5274 // get the sequence number from payload 24 Mac Header + 2 bytes algorithm
5275 NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(USHORT));
5276 if (Seq == 1 || Seq == 3)
5278 *Machine = AUTH_RSP_STATE_MACHINE;
5279 *MsgType = MT2_PEER_AUTH_ODD;
5281 else if (Seq == 2 || Seq == 4)
5283 *Machine = AUTH_STATE_MACHINE;
5284 *MsgType = MT2_PEER_AUTH_EVEN;
5291 case SUBTYPE_DEAUTH:
5292 *Machine = AUTH_RSP_STATE_MACHINE;
5293 *MsgType = MT2_PEER_DEAUTH;
5295 case SUBTYPE_ACTION:
5296 *Machine = ACTION_STATE_MACHINE;
5297 // Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support
5298 if ((pFrame->Octet[0]&0x7F) > MAX_PEER_CATE_MSG)
5300 *MsgType = MT2_ACT_INVALID;
5304 *MsgType = (pFrame->Octet[0]&0x7F);
5314 #endif // CONFIG_STA_SUPPORT //
5316 // ===========================================================================================
5318 // ===========================================================================================
5320 /*! \brief Initialize the state machine.
5321 * \param *S pointer to the state machine
5322 * \param Trans State machine transition function
5323 * \param StNr number of states
5324 * \param MsgNr number of messages
5325 * \param DefFunc default function, when there is invalid state/message combination
5326 * \param InitState initial state of the state machine
5327 * \param Base StateMachine base, internal use only
5328 * \pre p_sm should be a legal pointer
5331 IRQL = PASSIVE_LEVEL
5334 VOID StateMachineInit(
5335 IN STATE_MACHINE *S,
5336 IN STATE_MACHINE_FUNC Trans[],
5339 IN STATE_MACHINE_FUNC DefFunc,
5345 // set number of states and messages
5350 S->TransFunc = Trans;
5352 // init all state transition to default function
5353 for (i = 0; i < StNr; i++)
5355 for (j = 0; j < MsgNr; j++)
5357 S->TransFunc[i * MsgNr + j] = DefFunc;
5361 // set the starting state
5362 S->CurrState = InitState;
5365 /*! \brief This function fills in the function pointer into the cell in the state machine
5366 * \param *S pointer to the state machine
5368 * \param Msg incoming message
5369 * \param f the function to be executed when (state, message) combination occurs at the state machine
5370 * \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
5373 IRQL = PASSIVE_LEVEL
5376 VOID StateMachineSetAction(
5377 IN STATE_MACHINE *S,
5380 IN STATE_MACHINE_FUNC Func)
5384 MsgIdx = Msg - S->Base;
5386 if (St < S->NrState && MsgIdx < S->NrMsg)
5388 // boundary checking before setting the action
5389 S->TransFunc[St * S->NrMsg + MsgIdx] = Func;
5393 /*! \brief This function does the state transition
5394 * \param *Adapter the NIC adapter pointer
5395 * \param *S the state machine
5396 * \param *Elem the message to be executed
5399 IRQL = DISPATCH_LEVEL
5402 VOID StateMachinePerformAction(
5403 IN PRTMP_ADAPTER pAd,
5404 IN STATE_MACHINE *S,
5405 IN MLME_QUEUE_ELEM *Elem)
5407 (*(S->TransFunc[S->CurrState * S->NrMsg + Elem->MsgType - S->Base]))(pAd, Elem);
5411 ==========================================================================
5413 The drop function, when machine executes this, the message is simply
5414 ignored. This function does nothing, the message is freed in
5415 StateMachinePerformAction()
5416 ==========================================================================
5419 IN PRTMP_ADAPTER pAd,
5420 IN MLME_QUEUE_ELEM *Elem)
5424 // ===========================================================================================
5426 // ===========================================================================================
5429 ==========================================================================
5432 IRQL = PASSIVE_LEVEL
5434 ==========================================================================
5437 IN PRTMP_ADAPTER pAd,
5441 pAd->Mlme.ShiftReg = 1;
5443 pAd->Mlme.ShiftReg = Seed;
5447 ==========================================================================
5449 ==========================================================================
5452 IN PRTMP_ADAPTER pAd)
5459 if (pAd->Mlme.ShiftReg == 0)
5460 NdisGetSystemUpTime((ULONG *)&pAd->Mlme.ShiftReg);
5462 for (i = 0; i < 8; i++)
5464 if (pAd->Mlme.ShiftReg & 0x00000001)
5466 pAd->Mlme.ShiftReg = ((pAd->Mlme.ShiftReg ^ LFSR_MASK) >> 1) | 0x80000000;
5471 pAd->Mlme.ShiftReg = pAd->Mlme.ShiftReg >> 1;
5474 R = (R << 1) | Result;
5480 VOID AsicUpdateAutoFallBackTable(
5481 IN PRTMP_ADAPTER pAd,
5482 IN PUCHAR pRateTable)
5485 HT_FBK_CFG0_STRUC HtCfg0;
5486 HT_FBK_CFG1_STRUC HtCfg1;
5487 LG_FBK_CFG0_STRUC LgCfg0;
5488 LG_FBK_CFG1_STRUC LgCfg1;
5489 PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate;
5491 // set to initial value
5492 HtCfg0.word = 0x65432100;
5493 HtCfg1.word = 0xedcba988;
5494 LgCfg0.word = 0xedcba988;
5495 LgCfg1.word = 0x00002100;
5497 pNextTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1;
5498 for (i = 1; i < *((PUCHAR) pRateTable); i++)
5500 pCurrTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1+i;
5501 switch (pCurrTxRate->Mode)
5507 switch(pCurrTxRate->CurrMCS)
5510 LgCfg0.field.OFDMMCS0FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5513 LgCfg0.field.OFDMMCS1FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5516 LgCfg0.field.OFDMMCS2FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5519 LgCfg0.field.OFDMMCS3FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5522 LgCfg0.field.OFDMMCS4FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5525 LgCfg0.field.OFDMMCS5FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5528 LgCfg0.field.OFDMMCS6FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5531 LgCfg0.field.OFDMMCS7FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5536 #ifdef DOT11_N_SUPPORT
5540 if ((pNextTxRate->Mode >= MODE_HTMIX) && (pCurrTxRate->CurrMCS != pNextTxRate->CurrMCS))
5542 switch(pCurrTxRate->CurrMCS)
5545 HtCfg0.field.HTMCS0FBK = pNextTxRate->CurrMCS;
5548 HtCfg0.field.HTMCS1FBK = pNextTxRate->CurrMCS;
5551 HtCfg0.field.HTMCS2FBK = pNextTxRate->CurrMCS;
5554 HtCfg0.field.HTMCS3FBK = pNextTxRate->CurrMCS;
5557 HtCfg0.field.HTMCS4FBK = pNextTxRate->CurrMCS;
5560 HtCfg0.field.HTMCS5FBK = pNextTxRate->CurrMCS;
5563 HtCfg0.field.HTMCS6FBK = pNextTxRate->CurrMCS;
5566 HtCfg0.field.HTMCS7FBK = pNextTxRate->CurrMCS;
5569 HtCfg1.field.HTMCS8FBK = pNextTxRate->CurrMCS;
5572 HtCfg1.field.HTMCS9FBK = pNextTxRate->CurrMCS;
5575 HtCfg1.field.HTMCS10FBK = pNextTxRate->CurrMCS;
5578 HtCfg1.field.HTMCS11FBK = pNextTxRate->CurrMCS;
5581 HtCfg1.field.HTMCS12FBK = pNextTxRate->CurrMCS;
5584 HtCfg1.field.HTMCS13FBK = pNextTxRate->CurrMCS;
5587 HtCfg1.field.HTMCS14FBK = pNextTxRate->CurrMCS;
5590 HtCfg1.field.HTMCS15FBK = pNextTxRate->CurrMCS;
5593 DBGPRINT(RT_DEBUG_ERROR, ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n", pCurrTxRate->CurrMCS));
5598 #endif // DOT11_N_SUPPORT //
5601 pNextTxRate = pCurrTxRate;
5604 RTMP_IO_WRITE32(pAd, HT_FBK_CFG0, HtCfg0.word);
5605 RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, HtCfg1.word);
5606 RTMP_IO_WRITE32(pAd, LG_FBK_CFG0, LgCfg0.word);
5607 RTMP_IO_WRITE32(pAd, LG_FBK_CFG1, LgCfg1.word);
5611 ========================================================================
5613 Routine Description:
5614 Set MAC register value according operation mode.
5615 OperationMode AND bNonGFExist are for MM and GF Proteciton.
5616 If MM or GF mask is not set, those passing argument doesn't not take effect.
5618 Operation mode meaning:
5619 = 0 : Pure HT, no preotection.
5620 = 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS.
5621 = 0x10: No Transmission in 40M is protected.
5622 = 0x11: Transmission in both 40M and 20M shall be protected
5624 we should choose not to use GF. But still set correct ASIC registers.
5625 ========================================================================
5627 VOID AsicUpdateProtect(
5628 IN PRTMP_ADAPTER pAd,
5629 IN USHORT OperationMode,
5631 IN BOOLEAN bDisableBGProtect,
5632 IN BOOLEAN bNonGFExist)
5634 PROT_CFG_STRUC ProtCfg, ProtCfg4;
5643 #endif // RALINK_ATE //
5645 #ifdef DOT11_N_SUPPORT
5646 if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8))
5651 if (pAd->BATable.numAsOriginator)
5654 // enable the RTS/CTS to avoid channel collision
5656 SetMask = ALLN_SETPROTECT;
5659 #endif // DOT11_N_SUPPORT //
5661 // Config ASIC RTS threshold register
5662 RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
5663 MacReg &= 0xFF0000FF;
5665 MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
5667 // If the user want disable RtsThreshold and enable Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096
5669 #ifdef DOT11_N_SUPPORT
5670 (pAd->CommonCfg.BACapability.field.AmsduEnable) ||
5671 #endif // DOT11_N_SUPPORT //
5672 (pAd->CommonCfg.bAggregationCapable == TRUE))
5673 && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD)
5675 MacReg |= (0x1000 << 8);
5679 MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
5683 RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
5685 // Initial common protection settings
5686 RTMPZeroMemory(Protect, sizeof(Protect));
5689 ProtCfg.field.TxopAllowGF40 = 1;
5690 ProtCfg.field.TxopAllowGF20 = 1;
5691 ProtCfg.field.TxopAllowMM40 = 1;
5692 ProtCfg.field.TxopAllowMM20 = 1;
5693 ProtCfg.field.TxopAllowOfdm = 1;
5694 ProtCfg.field.TxopAllowCck = 1;
5695 ProtCfg.field.RTSThEn = 1;
5696 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
5698 // update PHY mode and rate
5699 if (pAd->CommonCfg.Channel > 14)
5700 ProtCfg.field.ProtectRate = 0x4000;
5701 ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate;
5703 // Handle legacy(B/G) protection
5704 if (bDisableBGProtect)
5706 //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
5707 ProtCfg.field.ProtectCtrl = 0;
5708 Protect[0] = ProtCfg.word;
5709 Protect[1] = ProtCfg.word;
5713 //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
5714 ProtCfg.field.ProtectCtrl = 0; // CCK do not need to be protected
5715 Protect[0] = ProtCfg.word;
5716 ProtCfg.field.ProtectCtrl = ASIC_CTS; // OFDM needs using CCK to protect
5717 Protect[1] = ProtCfg.word;
5720 #ifdef DOT11_N_SUPPORT
5721 // Decide HT frame protection.
5722 if ((SetMask & ALLN_SETPROTECT) != 0)
5724 switch(OperationMode)
5728 // 1.All STAs in the BSS are 20/40 MHz HT
5729 // 2. in ai 20/40MHz BSS
5730 // 3. all STAs are 20MHz in a 20MHz BSS
5731 // Pure HT. no protection.
5735 // PROT_TXOP(25:20) -- 010111
5736 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5737 // PROT_CTRL(17:16) -- 00 (None)
5738 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
5739 Protect[2] = 0x01744004;
5743 // PROT_TXOP(25:20) -- 111111
5744 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5745 // PROT_CTRL(17:16) -- 00 (None)
5746 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
5747 Protect[3] = 0x03f44084;
5751 // PROT_TXOP(25:20) -- 010111
5752 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5753 // PROT_CTRL(17:16) -- 00 (None)
5754 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
5755 Protect[4] = 0x01744004;
5759 // PROT_TXOP(25:20) -- 111111
5760 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5761 // PROT_CTRL(17:16) -- 00 (None)
5762 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
5763 Protect[5] = 0x03f44084;
5767 // PROT_NAV(19:18) -- 01 (Short NAV protectiion)
5768 // PROT_CTRL(17:16) -- 01 (RTS/CTS)
5769 Protect[4] = 0x01754004;
5770 Protect[5] = 0x03f54084;
5772 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
5776 // This is "HT non-member protection mode."
5777 // If there may be non-HT STAs my BSS
5778 ProtCfg.word = 0x01744004; // PROT_CTRL(17:16) : 0 (None)
5779 ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
5780 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
5782 ProtCfg.word = 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
5783 ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083;
5785 //Assign Protection method for 20&40 MHz packets
5786 ProtCfg.field.ProtectCtrl = ASIC_RTS;
5787 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
5788 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
5789 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
5790 Protect[2] = ProtCfg.word;
5791 Protect[3] = ProtCfg4.word;
5792 Protect[4] = ProtCfg.word;
5793 Protect[5] = ProtCfg4.word;
5794 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
5798 // If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets
5799 ProtCfg.word = 0x01744004; // PROT_CTRL(17:16) : 0 (None)
5800 ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
5802 //Assign Protection method for 40MHz packets
5803 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
5804 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
5805 Protect[2] = ProtCfg.word;
5806 Protect[3] = ProtCfg4.word;
5809 ProtCfg.field.ProtectCtrl = ASIC_RTS;
5810 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
5812 Protect[4] = ProtCfg.word;
5813 Protect[5] = ProtCfg4.word;
5815 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
5819 // HT mixed mode. PROTECT ALL!
5821 ProtCfg.word = 0x01744004; //duplicaet legacy 24M. BW set 1.
5822 ProtCfg4.word = 0x03f44084;
5823 // both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the
5824 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
5826 ProtCfg.word = 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
5827 ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083
5829 //Assign Protection method for 20&40 MHz packets
5830 ProtCfg.field.ProtectCtrl = ASIC_RTS;
5831 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
5832 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
5833 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
5834 Protect[2] = ProtCfg.word;
5835 Protect[3] = ProtCfg4.word;
5836 Protect[4] = ProtCfg.word;
5837 Protect[5] = ProtCfg4.word;
5838 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
5842 // Special on for Atheros problem n chip.
5843 Protect[2] = 0x01754004;
5844 Protect[3] = 0x03f54084;
5845 Protect[4] = 0x01754004;
5846 Protect[5] = 0x03f54084;
5847 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
5851 #endif // DOT11_N_SUPPORT //
5853 offset = CCK_PROT_CFG;
5854 for (i = 0;i < 6;i++)
5856 if ((SetMask & (1<< i)))
5858 RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]);
5864 ==========================================================================
5867 IRQL = PASSIVE_LEVEL
5868 IRQL = DISPATCH_LEVEL
5870 ==========================================================================
5872 VOID AsicSwitchChannel(
5873 IN PRTMP_ADAPTER pAd,
5877 ULONG R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0;
5878 CHAR TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; //Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER;
5880 UINT32 Value = 0; //BbpReg, Value;
5881 RTMP_RF_REGS *RFRegTable;
5883 // Search Tx power value
5884 for (index = 0; index < pAd->ChannelListNum; index++)
5886 if (Channel == pAd->ChannelList[index].Channel)
5888 TxPwer = pAd->ChannelList[index].Power;
5889 TxPwer2 = pAd->ChannelList[index].Power2;
5894 if (index == MAX_NUM_OF_CHANNELS)
5896 DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Cant find the Channel#%d \n", Channel));
5900 RFRegTable = RF2850RegTable;
5902 switch (pAd->RfIcType)
5909 for (index = 0; index < NUM_OF_2850_CHNL; index++)
5911 if (Channel == RFRegTable[index].Channel)
5913 R2 = RFRegTable[index].R2;
5914 if (pAd->Antenna.field.TxPath == 1)
5916 R2 |= 0x4000; // If TXpath is 1, bit 14 = 1;
5919 if (pAd->Antenna.field.RxPath == 2)
5921 R2 |= 0x40; // write 1 to off Rxpath.
5923 else if (pAd->Antenna.field.RxPath == 1)
5925 R2 |= 0x20040; // write 1 to off RxPath
5930 // initialize R3, R4
5931 R3 = (RFRegTable[index].R3 & 0xffffc1ff);
5932 R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15);
5934 // 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB
5936 if ((TxPwer >= -7) && (TxPwer < 0))
5938 TxPwer = (7+TxPwer);
5939 TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
5940 R3 |= (TxPwer << 10);
5941 DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer=%d \n", TxPwer));
5945 TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
5946 R3 |= (TxPwer << 10) | (1 << 9);
5950 if ((TxPwer2 >= -7) && (TxPwer2 < 0))
5952 TxPwer2 = (7+TxPwer2);
5953 TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
5954 R4 |= (TxPwer2 << 7);
5955 DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer2=%d \n", TxPwer2));
5959 TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
5960 R4 |= (TxPwer2 << 7) | (1 << 6);
5965 R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); // set TX power0
5966 R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 <<6);// Set freq Offset & TxPwr1
5969 // Based on BBP current mode before changing RF channel.
5970 if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
5976 pAd->LatchRfRegs.Channel = Channel;
5977 pAd->LatchRfRegs.R1 = RFRegTable[index].R1;
5978 pAd->LatchRfRegs.R2 = R2;
5979 pAd->LatchRfRegs.R3 = R3;
5980 pAd->LatchRfRegs.R4 = R4;
5982 // Set RF value 1's set R3[bit2] = [0]
5983 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
5984 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
5985 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
5986 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
5990 // Set RF value 2's set R3[bit2] = [1]
5991 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
5992 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
5993 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04));
5994 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
5998 // Set RF value 3's set R3[bit2] = [0]
5999 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
6000 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
6001 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
6002 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
6014 // Change BBP setting during siwtch from a->g, g->a
6017 ULONG TxPinCfg = 0x00050F0A;//Gary 2007/08/09 0x050A0A
6019 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
6020 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
6021 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
6022 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.
6023 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
6025 // Rx High power VGA offset for LNA select
6026 if (pAd->NicConfig2.field.ExternalLNAForG)
6028 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
6029 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
6033 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
6034 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
6037 // 5G band selection PIN, bit1 and bit2 are complement
6038 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
6041 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
6043 // Turn off unused PA or LNA when only 1T or 1R
6044 if (pAd->Antenna.field.TxPath == 1)
6046 TxPinCfg &= 0xFFFFFFF3;
6048 if (pAd->Antenna.field.RxPath == 1)
6050 TxPinCfg &= 0xFFFFF3FF;
6053 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
6057 ULONG TxPinCfg = 0x00050F05;//Gary 2007/8/9 0x050505
6059 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
6060 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
6061 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
6062 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.
6063 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
6065 // Rx High power VGA offset for LNA select
6066 if (pAd->NicConfig2.field.ExternalLNAForA)
6068 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
6072 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
6075 // 5G band selection PIN, bit1 and bit2 are complement
6076 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
6079 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
6081 // Turn off unused PA or LNA when only 1T or 1R
6082 if (pAd->Antenna.field.TxPath == 1)
6084 TxPinCfg &= 0xFFFFFFF3;
6086 if (pAd->Antenna.field.RxPath == 1)
6088 TxPinCfg &= 0xFFFFF3FF;
6091 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
6094 // R66 should be set according to Channel and use 20MHz when scanning
6095 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd)));
6097 RTMPSetAGCInitValue(pAd, BW_20);
6099 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
6102 // On 11A, We should delay and wait RF/BBP to be stable
6103 // and the appropriate time should be 1000 micro seconds
6104 // 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
6106 RTMPusecDelay(1000);
6108 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",
6111 (R3 & 0x00003e00) >> 9,
6112 (R4 & 0x000007c0) >> 6,
6113 pAd->Antenna.field.TxPath,
6114 pAd->LatchRfRegs.R1,
6115 pAd->LatchRfRegs.R2,
6116 pAd->LatchRfRegs.R3,
6117 pAd->LatchRfRegs.R4));
6121 ==========================================================================
6123 This function is required for 2421 only, and should not be used during
6124 site survey. It's only required after NIC decided to stay at a channel
6125 for a longer period.
6126 When this function is called, it's always after AsicSwitchChannel().
6128 IRQL = PASSIVE_LEVEL
6129 IRQL = DISPATCH_LEVEL
6131 ==========================================================================
6133 VOID AsicLockChannel(
6134 IN PRTMP_ADAPTER pAd,
6140 ==========================================================================
6143 IRQL = PASSIVE_LEVEL
6144 IRQL = DISPATCH_LEVEL
6146 ==========================================================================
6148 VOID AsicAntennaSelect(
6149 IN PRTMP_ADAPTER pAd,
6155 ========================================================================
6157 Routine Description:
6158 Antenna miscellaneous setting.
6161 pAd Pointer to our adapter
6162 BandState Indicate current Band State.
6167 IRQL <= DISPATCH_LEVEL
6170 1.) Frame End type control
6171 only valid for G only (RF_2527 & RF_2529)
6172 0: means DPDT, set BBP R4 bit 5 to 1
6173 1: means SPDT, set BBP R4 bit 5 to 0
6176 ========================================================================
6178 VOID AsicAntennaSetting(
6179 IN PRTMP_ADAPTER pAd,
6180 IN ABGBAND_STATE BandState)
6184 VOID AsicRfTuningExec(
6185 IN PVOID SystemSpecific1,
6186 IN PVOID FunctionContext,
6187 IN PVOID SystemSpecific2,
6188 IN PVOID SystemSpecific3)
6193 ==========================================================================
6195 Gives CCK TX rate 2 more dB TX power.
6196 This routine works only in LINK UP in INFRASTRUCTURE mode.
6198 calculate desired Tx power in RF R3.Tx0~5, should consider -
6199 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
6200 1. TxPowerPercentage
6201 2. auto calibration based on TSSI feedback
6202 3. extra 2 db for CCK
6203 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
6205 NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
6206 it should be called AFTER MlmeDynamicTxRatSwitching()
6207 ==========================================================================
6209 VOID AsicAdjustTxPower(
6210 IN PRTMP_ADAPTER pAd)
6214 BOOLEAN bAutoTxAgc = FALSE;
6215 UCHAR TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
6216 UCHAR BbpR1 = 0, BbpR49 = 0, idx;
6217 PCHAR pTxAgcCompensate;
6221 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
6222 || (pAd->bPCIclkOff == TRUE)
6223 || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)
6224 || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
6227 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
6229 if (pAd->CommonCfg.CentralChannel > 14)
6231 TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
6232 TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
6233 TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
6234 TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
6235 TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
6239 TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
6240 TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
6241 TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
6242 TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
6243 TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
6248 if (pAd->CommonCfg.Channel > 14)
6250 TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
6251 TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
6252 TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
6253 TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
6254 TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
6258 TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
6259 TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
6260 TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
6261 TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
6262 TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
6266 // TX power compensation for temperature variation based on TSSI. try every 4 second
6267 if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
6269 if (pAd->CommonCfg.Channel <= 14)
6272 bAutoTxAgc = pAd->bAutoTxAgcG;
6273 TssiRef = pAd->TssiRefG;
6274 pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
6275 pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0];
6276 TxAgcStep = pAd->TxAgcStepG;
6277 pTxAgcCompensate = &pAd->TxAgcCompensateG;
6282 bAutoTxAgc = pAd->bAutoTxAgcA;
6283 TssiRef = pAd->TssiRefA;
6284 pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
6285 pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0];
6286 TxAgcStep = pAd->TxAgcStepA;
6287 pTxAgcCompensate = &pAd->TxAgcCompensateA;
6292 /* BbpR1 is unsigned char */
6293 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
6295 /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
6296 /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */
6297 /* step value is defined in pAd->TxAgcStepG for tx power value */
6299 /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */
6300 /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
6301 above value are examined in mass factory production */
6302 /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */
6304 /* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */
6305 /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
6306 /* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */
6308 if (BbpR49 > pTssiMinusBoundary[1])
6310 // Reading is larger than the reference value
6311 // check for how large we need to decrease the Tx power
6312 for (idx = 1; idx < 5; idx++)
6314 if (BbpR49 <= pTssiMinusBoundary[idx]) // Found the range
6317 // The index is the step we should decrease, idx = 0 means there is nothing to compensate
6318 *pTxAgcCompensate = -(TxAgcStep * (idx-1));
6320 DeltaPwr += (*pTxAgcCompensate);
6321 DBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
6322 BbpR49, TssiRef, TxAgcStep, idx-1));
6324 else if (BbpR49 < pTssiPlusBoundary[1])
6326 // Reading is smaller than the reference value
6327 // check for how large we need to increase the Tx power
6328 for (idx = 1; idx < 5; idx++)
6330 if (BbpR49 >= pTssiPlusBoundary[idx]) // Found the range
6333 // The index is the step we should increase, idx = 0 means there is nothing to compensate
6334 *pTxAgcCompensate = TxAgcStep * (idx-1);
6335 DeltaPwr += (*pTxAgcCompensate);
6336 DBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
6337 BbpR49, TssiRef, TxAgcStep, idx-1));
6341 *pTxAgcCompensate = 0;
6342 DBGPRINT(RT_DEBUG_TRACE, (" Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
6343 BbpR49, TssiRef, TxAgcStep, 0));
6349 if (pAd->CommonCfg.Channel <= 14)
6351 bAutoTxAgc = pAd->bAutoTxAgcG;
6352 pTxAgcCompensate = &pAd->TxAgcCompensateG;
6356 bAutoTxAgc = pAd->bAutoTxAgcA;
6357 pTxAgcCompensate = &pAd->TxAgcCompensateA;
6361 DeltaPwr += (*pTxAgcCompensate);
6364 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1);
6368 // Handle regulatory max tx power constrain
6371 UCHAR TxPwrInEEPROM = 0xFF, CountryTxPwr = 0xFF, criterion;
6372 UCHAR AdjustMaxTxPwr[40];
6374 if (pAd->CommonCfg.Channel > 14) // 5G band
6375 TxPwrInEEPROM = ((pAd->CommonCfg.DefineMaxTxPwr & 0xFF00) >> 8);
6377 TxPwrInEEPROM = (pAd->CommonCfg.DefineMaxTxPwr & 0x00FF);
6378 CountryTxPwr = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel);
6380 // error handling, range check
6381 if ((TxPwrInEEPROM > 0x50) || (CountryTxPwr > 0x50))
6383 DBGPRINT(RT_DEBUG_ERROR,("AsicAdjustTxPower - Invalid max tx power (=0x%02x), CountryTxPwr=%d\n", TxPwrInEEPROM, CountryTxPwr));
6387 criterion = *((PUCHAR)TxPwr + 2) & 0xF; // FAE use OFDM 6M as criterion
6389 DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (criterion=%d, TxPwrInEEPROM=%d, CountryTxPwr=%d)\n", criterion, TxPwrInEEPROM, CountryTxPwr));
6391 // Adjust max tx power according to the relationship of tx power in E2PROM
6394 // CCK will have 4dBm larger than OFDM
6395 // Therefore, we should separate to parse the tx power field
6400 Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F);
6404 // CCK will have 4dBm larger than OFDM
6405 AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion) + 4;
6409 AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion);
6411 DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
6418 Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F);
6420 AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion);
6421 DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
6426 // Adjust tx power according to the relationship
6429 if (TxPwr[i] != 0xffffffff)
6433 Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F);
6435 // The system tx power is larger than the regulatory, the power should be restrain
6436 if (AdjustMaxTxPwr[i*8+j] > CountryTxPwr)
6438 // decrease to zero and don't need to take care BBPR1
6439 if ((Value - (AdjustMaxTxPwr[i*8+j] - CountryTxPwr)) > 0)
6440 Value -= (AdjustMaxTxPwr[i*8+j] - CountryTxPwr);
6444 DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
6447 DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d, no change)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
6449 TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
6454 #endif // SINGLE_SKU //
6456 /* calculate delta power based on the percentage specified from UI */
6457 // E2PROM setting is calibrated for maximum TX power (i.e. 100%)
6458 // We lower TX power here according to the percentage specified from UI
6459 if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff) // AUTO TX POWER control
6461 else if (pAd->CommonCfg.TxPowerPercentage > 90) // 91 ~ 100% & AUTO, treat as 100% in terms of mW
6463 else if (pAd->CommonCfg.TxPowerPercentage > 60) // 61 ~ 90%, treat as 75% in terms of mW // DeltaPwr -= 1;
6467 else if (pAd->CommonCfg.TxPowerPercentage > 30) // 31 ~ 60%, treat as 50% in terms of mW // DeltaPwr -= 3;
6471 else if (pAd->CommonCfg.TxPowerPercentage > 15) // 16 ~ 30%, treat as 25% in terms of mW // DeltaPwr -= 6;
6475 else if (pAd->CommonCfg.TxPowerPercentage > 9) // 10 ~ 15%, treat as 12.5% in terms of mW // DeltaPwr -= 9;
6480 else // 0 ~ 9 %, treat as MIN(~3%) in terms of mW // DeltaPwr -= 12;
6485 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
6487 /* reset different new tx power for different TX rate */
6490 if (TxPwr[i] != 0xffffffff)
6494 Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */
6496 if ((Value + DeltaPwr) < 0)
6498 Value = 0; /* min */
6500 else if ((Value + DeltaPwr) > 0xF)
6502 Value = 0xF; /* max */
6506 Value += DeltaPwr; /* temperature compensation */
6509 /* fill new value to CSR offset */
6510 TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
6513 /* write tx power value to CSR */
6514 /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M
6515 TX power for OFDM 6M/9M
6516 TX power for CCK5.5M/11M
6517 TX power for CCK1M/2M */
6518 /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
6519 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]);
6525 #ifdef CONFIG_STA_SUPPORT
6527 ==========================================================================
6529 put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup
6530 automatically. Instead, MCU will issue a TwakeUpInterrupt to host after
6531 the wakeup timer timeout. Driver has to issue a separate command to wake
6534 IRQL = DISPATCH_LEVEL
6536 ==========================================================================
6538 VOID AsicSleepThenAutoWakeup(
6539 IN PRTMP_ADAPTER pAd,
6540 IN USHORT TbttNumToNextWakeUp)
6542 RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp);
6546 ==========================================================================
6548 AsicForceWakeup() is used whenever manual wakeup is required
6549 AsicForceSleep() should only be used when not in INFRA BSS. When
6550 in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead.
6551 ==========================================================================
6553 VOID AsicForceSleep(
6554 IN PRTMP_ADAPTER pAd)
6560 ==========================================================================
6562 AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup)
6565 IRQL = PASSIVE_LEVEL
6566 IRQL = DISPATCH_LEVEL
6567 ==========================================================================
6569 VOID AsicForceWakeup(
6570 IN PRTMP_ADAPTER pAd,
6573 DBGPRINT(RT_DEBUG_TRACE, ("--> AsicForceWakeup \n"));
6574 RT28XX_STA_FORCE_WAKEUP(pAd, Level);
6576 #endif // CONFIG_STA_SUPPORT //
6578 ==========================================================================
6582 IRQL = DISPATCH_LEVEL
6584 ==========================================================================
6587 IN PRTMP_ADAPTER pAd,
6591 DBGPRINT(RT_DEBUG_TRACE, ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n",
6592 pBssid[0],pBssid[1],pBssid[2],pBssid[3], pBssid[4],pBssid[5]));
6594 Addr4 = (ULONG)(pBssid[0]) |
6595 (ULONG)(pBssid[1] << 8) |
6596 (ULONG)(pBssid[2] << 16) |
6597 (ULONG)(pBssid[3] << 24);
6598 RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
6601 // always one BSSID in STA mode
6602 Addr4 = (ULONG)(pBssid[4]) | (ULONG)(pBssid[5] << 8);
6604 RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
6607 VOID AsicSetMcastWC(
6608 IN PRTMP_ADAPTER pAd)
6610 MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[MCAST_WCID];
6613 pEntry->Sst = SST_ASSOC;
6614 pEntry->Aid = MCAST_WCID; // Softap supports 1 BSSID and use WCID=0 as multicast Wcid index
6615 pEntry->PsMode = PWR_ACTIVE;
6616 pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate;
6617 offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE;
6621 ==========================================================================
6624 IRQL = DISPATCH_LEVEL
6626 ==========================================================================
6628 VOID AsicDelWcidTab(
6629 IN PRTMP_ADAPTER pAd,
6632 ULONG Addr0 = 0x0, Addr1 = 0x0;
6635 DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n",Wcid));
6636 offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE;
6637 RTMP_IO_WRITE32(pAd, offset, Addr0);
6639 RTMP_IO_WRITE32(pAd, offset, Addr1);
6643 ==========================================================================
6646 IRQL = DISPATCH_LEVEL
6648 ==========================================================================
6651 IN PRTMP_ADAPTER pAd)
6653 TX_LINK_CFG_STRUC TxLinkCfg;
6656 RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
6657 TxLinkCfg.field.TxRDGEn = 1;
6658 RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
6660 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
6663 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
6665 //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
6669 ==========================================================================
6672 IRQL = DISPATCH_LEVEL
6674 ==========================================================================
6676 VOID AsicDisableRDG(
6677 IN PRTMP_ADAPTER pAd)
6679 TX_LINK_CFG_STRUC TxLinkCfg;
6683 RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
6684 TxLinkCfg.field.TxRDGEn = 0;
6685 RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
6687 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
6690 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE)
6691 #ifdef DOT11_N_SUPPORT
6692 && (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE)
6693 #endif // DOT11_N_SUPPORT //
6696 // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
6697 if (pAd->CommonCfg.bEnableTxBurst)
6700 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
6704 ==========================================================================
6707 IRQL = PASSIVE_LEVEL
6708 IRQL = DISPATCH_LEVEL
6710 ==========================================================================
6712 VOID AsicDisableSync(
6713 IN PRTMP_ADAPTER pAd)
6715 BCN_TIME_CFG_STRUC csr;
6717 DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n"));
6719 // 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect
6720 // that NIC will never wakes up because TSF stops and no more
6722 pAd->TbttTickCount = 0;
6723 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
6724 csr.field.bBeaconGen = 0;
6725 csr.field.bTBTTEnable = 0;
6726 csr.field.TsfSyncMode = 0;
6727 csr.field.bTsfTicking = 0;
6728 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
6733 ==========================================================================
6736 IRQL = DISPATCH_LEVEL
6738 ==========================================================================
6740 VOID AsicEnableBssSync(
6741 IN PRTMP_ADAPTER pAd)
6743 BCN_TIME_CFG_STRUC csr;
6745 DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n"));
6747 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
6748 #ifdef CONFIG_STA_SUPPORT
6749 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
6751 csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
6752 csr.field.bTsfTicking = 1;
6753 csr.field.TsfSyncMode = 1; // sync TSF in INFRASTRUCTURE mode
6754 csr.field.bBeaconGen = 0; // do NOT generate BEACON
6755 csr.field.bTBTTEnable = 1;
6757 #endif // CONFIG_STA_SUPPORT //
6758 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
6762 ==========================================================================
6765 BEACON frame in shared memory should be built ok before this routine
6766 can be called. Otherwise, a garbage frame maybe transmitted out every
6769 IRQL = DISPATCH_LEVEL
6771 ==========================================================================
6773 VOID AsicEnableIbssSync(
6774 IN PRTMP_ADAPTER pAd)
6776 BCN_TIME_CFG_STRUC csr9;
6780 DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n", pAd->BeaconTxWI.MPDUtotalByteCount));
6782 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word);
6783 csr9.field.bBeaconGen = 0;
6784 csr9.field.bTBTTEnable = 0;
6785 csr9.field.bTsfTicking = 0;
6786 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
6788 // move BEACON TXD and frame content to on-chip memory
6789 ptr = (PUCHAR)&pAd->BeaconTxWI;
6790 for (i=0; i<TXWI_SIZE; i+=4) // 16-byte TXWI field
6792 UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
6793 RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr);
6797 // start right after the 16-byte TXWI field
6798 ptr = pAd->BeaconBuf;
6799 for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=4)
6801 UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
6802 RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
6806 // start sending BEACON
6807 csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
6808 csr9.field.bTsfTicking = 1;
6809 csr9.field.TsfSyncMode = 2; // sync TSF in IBSS mode
6810 csr9.field.bTBTTEnable = 1;
6811 csr9.field.bBeaconGen = 1;
6812 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
6816 ==========================================================================
6819 IRQL = PASSIVE_LEVEL
6820 IRQL = DISPATCH_LEVEL
6822 ==========================================================================
6824 VOID AsicSetEdcaParm(
6825 IN PRTMP_ADAPTER pAd,
6826 IN PEDCA_PARM pEdcaParm)
6828 EDCA_AC_CFG_STRUC Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg;
6829 AC_TXOP_CSR0_STRUC csr0;
6830 AC_TXOP_CSR1_STRUC csr1;
6831 AIFSN_CSR_STRUC AifsnCsr;
6832 CWMIN_CSR_STRUC CwminCsr;
6833 CWMAX_CSR_STRUC CwmaxCsr;
6840 if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE))
6842 DBGPRINT(RT_DEBUG_TRACE,("AsicSetEdcaParm\n"));
6843 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED);
6844 for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
6846 if (pAd->MacTab.Content[i].ValidAsCLI || pAd->MacTab.Content[i].ValidAsApCli)
6847 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[i], fCLIENT_STATUS_WMM_CAPABLE);
6850 //========================================================
6851 // MAC Register has a copy .
6852 //========================================================
6853 if( pAd->CommonCfg.bEnableTxBurst )
6855 // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
6856 Ac0Cfg.field.AcTxop = 0x20; // Suggest by John for TxBurst in HT Mode
6859 Ac0Cfg.field.AcTxop = 0; // QID_AC_BE
6860 Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS;
6861 Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS;
6862 Ac0Cfg.field.Aifsn = 2;
6863 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
6865 Ac1Cfg.field.AcTxop = 0; // QID_AC_BK
6866 Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS;
6867 Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS;
6868 Ac1Cfg.field.Aifsn = 2;
6869 RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
6871 if (pAd->CommonCfg.PhyMode == PHY_11B)
6873 Ac2Cfg.field.AcTxop = 192; // AC_VI: 192*32us ~= 6ms
6874 Ac3Cfg.field.AcTxop = 96; // AC_VO: 96*32us ~= 3ms
6878 Ac2Cfg.field.AcTxop = 96; // AC_VI: 96*32us ~= 3ms
6879 Ac3Cfg.field.AcTxop = 48; // AC_VO: 48*32us ~= 1.5ms
6881 Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS;
6882 Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS;
6883 Ac2Cfg.field.Aifsn = 2;
6884 RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
6885 Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS;
6886 Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS;
6887 Ac3Cfg.field.Aifsn = 2;
6888 RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
6890 //========================================================
6891 // DMA Register has a copy too.
6892 //========================================================
6893 csr0.field.Ac0Txop = 0; // QID_AC_BE
6894 csr0.field.Ac1Txop = 0; // QID_AC_BK
6895 RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
6896 if (pAd->CommonCfg.PhyMode == PHY_11B)
6898 csr1.field.Ac2Txop = 192; // AC_VI: 192*32us ~= 6ms
6899 csr1.field.Ac3Txop = 96; // AC_VO: 96*32us ~= 3ms
6903 csr1.field.Ac2Txop = 96; // AC_VI: 96*32us ~= 3ms
6904 csr1.field.Ac3Txop = 48; // AC_VO: 48*32us ~= 1.5ms
6906 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
6909 CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS;
6910 CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS;
6911 CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS;
6912 CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS;
6913 RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
6916 CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS;
6917 CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS;
6918 CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS;
6919 CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS;
6920 RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
6922 RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222);
6924 NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(EDCA_PARM));
6928 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED);
6929 //========================================================
6930 // MAC Register has a copy.
6931 //========================================================
6933 // Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27
6934 // To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue.
6936 //pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this
6938 Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE];
6939 Ac0Cfg.field.Cwmin= pEdcaParm->Cwmin[QID_AC_BE];
6940 Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE];
6941 Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]; //+1;
6943 Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
6944 Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK]; //+2;
6945 Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK];
6946 Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK]; //+1;
6948 Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10;
6949 Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI];
6950 Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI];
6951 Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI];
6952 #ifdef CONFIG_STA_SUPPORT
6953 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
6955 // Tuning for Wi-Fi WMM S06
6956 if (pAd->CommonCfg.bWiFiTest &&
6957 pEdcaParm->Aifsn[QID_AC_VI] == 10)
6958 Ac2Cfg.field.Aifsn -= 1;
6960 // Tuning for TGn Wi-Fi 5.2.32
6961 // STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta
6962 if (STA_TGN_WIFI_ON(pAd) &&
6963 pEdcaParm->Aifsn[QID_AC_VI] == 10)
6965 Ac0Cfg.field.Aifsn = 3;
6966 Ac2Cfg.field.AcTxop = 5;
6969 #endif // CONFIG_STA_SUPPORT //
6971 Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO];
6972 Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO];
6973 Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO];
6974 Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO];
6977 if (pAd->CommonCfg.bWiFiTest)
6979 if (Ac3Cfg.field.AcTxop == 102)
6981 Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm->Txop[QID_AC_BE] : 10;
6982 Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]-1; /* AIFSN must >= 1 */
6983 Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
6984 Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK];
6985 Ac2Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VI];
6988 //#endif // WIFI_TEST //
6990 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
6991 RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
6992 RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
6993 RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
6996 //========================================================
6997 // DMA Register has a copy too.
6998 //========================================================
6999 csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop;
7000 csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop;
7001 RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
7003 csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop;
7004 csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop;
7005 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
7008 CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE];
7009 CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK];
7010 CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI];
7011 #ifdef CONFIG_STA_SUPPORT
7012 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
7013 CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO] - 1; //for TGn wifi test
7014 #endif // CONFIG_STA_SUPPORT //
7015 RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
7018 CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE];
7019 CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK];
7020 CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI];
7021 CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO];
7022 RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
7025 AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BE];
7026 AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BK];
7027 AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_VI];
7028 #ifdef CONFIG_STA_SUPPORT
7029 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
7031 // Tuning for Wi-Fi WMM S06
7032 if (pAd->CommonCfg.bWiFiTest &&
7033 pEdcaParm->Aifsn[QID_AC_VI] == 10)
7034 AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4;
7036 // Tuning for TGn Wi-Fi 5.2.32
7037 // STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta
7038 if (STA_TGN_WIFI_ON(pAd) &&
7039 pEdcaParm->Aifsn[QID_AC_VI] == 10)
7041 AifsnCsr.field.Aifsn0 = 3;
7042 AifsnCsr.field.Aifsn2 = 7;
7045 #endif // CONFIG_STA_SUPPORT //
7047 #ifdef CONFIG_STA_SUPPORT
7048 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
7049 AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; //pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test
7050 #endif // CONFIG_STA_SUPPORT //
7051 RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word);
7053 NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
7056 DBGPRINT(RT_DEBUG_TRACE,("EDCA [#%d]: AIFSN CWmin CWmax TXOP(us) ACM\n", pEdcaParm->EdcaUpdateCount));
7057 DBGPRINT(RT_DEBUG_TRACE,(" AC_BE %2d %2d %2d %4d %d\n",
7058 pEdcaParm->Aifsn[0],
7059 pEdcaParm->Cwmin[0],
7060 pEdcaParm->Cwmax[0],
7061 pEdcaParm->Txop[0]<<5,
7062 pEdcaParm->bACM[0]));
7063 DBGPRINT(RT_DEBUG_TRACE,(" AC_BK %2d %2d %2d %4d %d\n",
7064 pEdcaParm->Aifsn[1],
7065 pEdcaParm->Cwmin[1],
7066 pEdcaParm->Cwmax[1],
7067 pEdcaParm->Txop[1]<<5,
7068 pEdcaParm->bACM[1]));
7069 DBGPRINT(RT_DEBUG_TRACE,(" AC_VI %2d %2d %2d %4d %d\n",
7070 pEdcaParm->Aifsn[2],
7071 pEdcaParm->Cwmin[2],
7072 pEdcaParm->Cwmax[2],
7073 pEdcaParm->Txop[2]<<5,
7074 pEdcaParm->bACM[2]));
7075 DBGPRINT(RT_DEBUG_TRACE,(" AC_VO %2d %2d %2d %4d %d\n",
7076 pEdcaParm->Aifsn[3],
7077 pEdcaParm->Cwmin[3],
7078 pEdcaParm->Cwmax[3],
7079 pEdcaParm->Txop[3]<<5,
7080 pEdcaParm->bACM[3]));
7086 ==========================================================================
7089 IRQL = PASSIVE_LEVEL
7090 IRQL = DISPATCH_LEVEL
7092 ==========================================================================
7094 VOID AsicSetSlotTime(
7095 IN PRTMP_ADAPTER pAd,
7096 IN BOOLEAN bUseShortSlotTime)
7099 UINT32 RegValue = 0;
7101 #ifdef CONFIG_STA_SUPPORT
7102 if (pAd->CommonCfg.Channel > 14)
7103 bUseShortSlotTime = TRUE;
7104 #endif // CONFIG_STA_SUPPORT //
7106 if (bUseShortSlotTime)
7107 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
7109 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
7111 SlotTime = (bUseShortSlotTime)? 9 : 20;
7113 #ifdef CONFIG_STA_SUPPORT
7114 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
7116 // force using short SLOT time for FAE to demo performance when TxBurst is ON
7117 if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
7118 #ifdef DOT11_N_SUPPORT
7119 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE))
7120 #endif // DOT11_N_SUPPORT //
7123 // In this case, we will think it is doing Wi-Fi test
7124 // And we will not set to short slot when bEnableTxBurst is TRUE.
7126 else if (pAd->CommonCfg.bEnableTxBurst)
7129 #endif // CONFIG_STA_SUPPORT //
7132 // For some reasons, always set it to short slot time.
7134 // ToDo: Should consider capability with 11B
7136 #ifdef CONFIG_STA_SUPPORT
7137 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
7139 if (pAd->StaCfg.BssType == BSS_ADHOC)
7142 #endif // CONFIG_STA_SUPPORT //
7144 RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue);
7145 RegValue = RegValue & 0xFFFFFF00;
7147 RegValue |= SlotTime;
7149 RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue);
7153 ========================================================================
7155 Add Shared key information into ASIC.
7156 Update shared key, TxMic and RxMic to Asic Shared key table
7157 Update its cipherAlg to Asic Shared key Mode.
7160 ========================================================================
7162 VOID AsicAddSharedKeyEntry(
7163 IN PRTMP_ADAPTER pAd,
7171 ULONG offset; //, csr0;
7172 SHAREDKEY_MODE_STRUC csr1;
7175 DBGPRINT(RT_DEBUG_TRACE, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,KeyIdx));
7176 //============================================================================================
7178 DBGPRINT(RT_DEBUG_TRACE,("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg], BssIndex*4 + KeyIdx));
7179 DBGPRINT_RAW(RT_DEBUG_TRACE, (" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7180 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]));
7183 DBGPRINT_RAW(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7184 pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
7188 DBGPRINT_RAW(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7189 pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
7191 //============================================================================================
7193 // fill key material - key + TX MIC + RX MIC
7195 offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE;
7196 for (i=0; i<MAX_LEN_OF_SHARE_KEY; i++)
7198 RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
7201 offset += MAX_LEN_OF_SHARE_KEY;
7206 RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
7215 RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
7221 // Update cipher algorithm. WSTA always use BSS0
7223 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
7224 DBGPRINT(RT_DEBUG_TRACE,("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n", BssIndex,KeyIdx, csr1.word));
7225 if ((BssIndex%2) == 0)
7228 csr1.field.Bss0Key0CipherAlg = CipherAlg;
7229 else if (KeyIdx == 1)
7230 csr1.field.Bss0Key1CipherAlg = CipherAlg;
7231 else if (KeyIdx == 2)
7232 csr1.field.Bss0Key2CipherAlg = CipherAlg;
7234 csr1.field.Bss0Key3CipherAlg = CipherAlg;
7239 csr1.field.Bss1Key0CipherAlg = CipherAlg;
7240 else if (KeyIdx == 1)
7241 csr1.field.Bss1Key1CipherAlg = CipherAlg;
7242 else if (KeyIdx == 2)
7243 csr1.field.Bss1Key2CipherAlg = CipherAlg;
7245 csr1.field.Bss1Key3CipherAlg = CipherAlg;
7247 DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
7248 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
7252 // IRQL = DISPATCH_LEVEL
7253 VOID AsicRemoveSharedKeyEntry(
7254 IN PRTMP_ADAPTER pAd,
7259 SHAREDKEY_MODE_STRUC csr1;
7261 DBGPRINT(RT_DEBUG_TRACE,("AsicRemoveSharedKeyEntry: #%d \n", BssIndex*4 + KeyIdx));
7263 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
7264 if ((BssIndex%2) == 0)
7267 csr1.field.Bss0Key0CipherAlg = 0;
7268 else if (KeyIdx == 1)
7269 csr1.field.Bss0Key1CipherAlg = 0;
7270 else if (KeyIdx == 2)
7271 csr1.field.Bss0Key2CipherAlg = 0;
7273 csr1.field.Bss0Key3CipherAlg = 0;
7278 csr1.field.Bss1Key0CipherAlg = 0;
7279 else if (KeyIdx == 1)
7280 csr1.field.Bss1Key1CipherAlg = 0;
7281 else if (KeyIdx == 2)
7282 csr1.field.Bss1Key2CipherAlg = 0;
7284 csr1.field.Bss1Key3CipherAlg = 0;
7286 DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
7287 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
7288 ASSERT(BssIndex < 4);
7294 VOID AsicUpdateWCIDAttribute(
7295 IN PRTMP_ADAPTER pAd,
7299 IN BOOLEAN bUsePairewiseKeyTable)
7301 ULONG WCIDAttri = 0, offset;
7304 // Update WCID attribute.
7305 // Only TxKey could update WCID attribute.
7307 offset = MAC_WCID_ATTRIBUTE_BASE + (WCID * HW_WCID_ATTRI_SIZE);
7308 WCIDAttri = (BssIndex << 4) | (CipherAlg << 1) | (bUsePairewiseKeyTable);
7309 RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
7312 VOID AsicUpdateWCIDIVEIV(
7313 IN PRTMP_ADAPTER pAd,
7320 offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
7322 RTMP_IO_WRITE32(pAd, offset, uIV);
7323 RTMP_IO_WRITE32(pAd, offset + 4, uEIV);
7326 VOID AsicUpdateRxWCIDTable(
7327 IN PRTMP_ADAPTER pAd,
7334 offset = MAC_WCID_BASE + (WCID * HW_WCID_ENTRY_SIZE);
7335 Addr = pAddr[0] + (pAddr[1] << 8) +(pAddr[2] << 16) +(pAddr[3] << 24);
7336 RTMP_IO_WRITE32(pAd, offset, Addr);
7337 Addr = pAddr[4] + (pAddr[5] << 8);
7338 RTMP_IO_WRITE32(pAd, offset + 4, Addr);
7343 ========================================================================
7345 Routine Description:
7346 Set Cipher Key, Cipher algorithm, IV/EIV to Asic
7349 pAd Pointer to our adapter
7350 WCID WCID Entry number.
7351 BssIndex BSSID index, station or none multiple BSSID support
7352 this value should be 0.
7353 KeyIdx This KeyIdx will set to IV's KeyID if bTxKey enabled
7354 pCipherKey Pointer to Cipher Key.
7355 bUsePairewiseKeyTable TRUE means saved the key in SharedKey table,
7356 otherwise PairewiseKey table
7357 bTxKey This is the transmit key if enabled.
7363 This routine will set the relative key stuff to Asic including WCID attribute,
7364 Cipher Key, Cipher algorithm and IV/EIV.
7366 IV/EIV will be update if this CipherKey is the transmission key because
7367 ASIC will base on IV's KeyID value to select Cipher Key.
7369 If bTxKey sets to FALSE, this is not the TX key, but it could be
7372 For AP mode bTxKey must be always set to TRUE.
7373 ========================================================================
7375 VOID AsicAddKeyEntry(
7376 IN PRTMP_ADAPTER pAd,
7380 IN PCIPHER_KEY pCipherKey,
7381 IN BOOLEAN bUsePairewiseKeyTable,
7386 PUCHAR pKey = pCipherKey->Key;
7387 PUCHAR pTxMic = pCipherKey->TxMic;
7388 PUCHAR pRxMic = pCipherKey->RxMic;
7389 PUCHAR pTxtsc = pCipherKey->TxTsc;
7390 UCHAR CipherAlg = pCipherKey->CipherAlg;
7391 SHAREDKEY_MODE_STRUC csr1;
7394 DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n"));
7396 // 1.) decide key table offset
7398 if (bUsePairewiseKeyTable)
7399 offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
7401 offset = SHARED_KEY_TABLE_BASE + (4 * BssIndex + KeyIdx) * HW_KEY_ENTRY_SIZE;
7404 // 2.) Set Key to Asic
7406 //for (i = 0; i < KeyLen; i++)
7407 for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++)
7409 RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
7411 offset += MAX_LEN_OF_PEER_KEY;
7414 // 3.) Set MIC key if available
7418 for (i = 0; i < 8; i++)
7420 RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
7423 offset += LEN_TKIP_TXMICK;
7427 for (i = 0; i < 8; i++)
7429 RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
7435 // 4.) Modify IV/EIV if needs
7436 // This will force Asic to use this key ID by setting IV.
7440 offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
7444 RTMP_IO_WRITE8(pAd, offset, pTxtsc[1]);
7445 RTMP_IO_WRITE8(pAd, offset + 1, ((pTxtsc[1] | 0x20) & 0x7f));
7446 RTMP_IO_WRITE8(pAd, offset + 2, pTxtsc[0]);
7448 IV4 = (KeyIdx << 6);
7449 if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES))
7450 IV4 |= 0x20; // turn on extension bit means EIV existence
7452 RTMP_IO_WRITE8(pAd, offset + 3, IV4);
7458 for (i = 0; i < 4; i++)
7460 RTMP_IO_WRITE8(pAd, offset + i, pTxtsc[i + 2]);
7463 AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg, bUsePairewiseKeyTable);
7466 if (!bUsePairewiseKeyTable)
7469 // Only update the shared key security mode
7471 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), &csr1.word);
7472 if ((BssIndex % 2) == 0)
7475 csr1.field.Bss0Key0CipherAlg = CipherAlg;
7476 else if (KeyIdx == 1)
7477 csr1.field.Bss0Key1CipherAlg = CipherAlg;
7478 else if (KeyIdx == 2)
7479 csr1.field.Bss0Key2CipherAlg = CipherAlg;
7481 csr1.field.Bss0Key3CipherAlg = CipherAlg;
7486 csr1.field.Bss1Key0CipherAlg = CipherAlg;
7487 else if (KeyIdx == 1)
7488 csr1.field.Bss1Key1CipherAlg = CipherAlg;
7489 else if (KeyIdx == 2)
7490 csr1.field.Bss1Key2CipherAlg = CipherAlg;
7492 csr1.field.Bss1Key3CipherAlg = CipherAlg;
7494 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), csr1.word);
7497 DBGPRINT(RT_DEBUG_TRACE, ("<== AsicAddKeyEntry\n"));
7502 ========================================================================
7504 Add Pair-wise key material into ASIC.
7505 Update pairwise key, TxMic and RxMic to Asic Pair-wise key table
7508 ========================================================================
7510 VOID AsicAddPairwiseKeyEntry(
7511 IN PRTMP_ADAPTER pAd,
7514 IN CIPHER_KEY *pCipherKey)
7518 PUCHAR pKey = pCipherKey->Key;
7519 PUCHAR pTxMic = pCipherKey->TxMic;
7520 PUCHAR pRxMic = pCipherKey->RxMic;
7522 UCHAR CipherAlg = pCipherKey->CipherAlg;
7526 offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
7527 for (i=0; i<MAX_LEN_OF_PEER_KEY; i++)
7529 RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
7531 for (i=0; i<MAX_LEN_OF_PEER_KEY; i+=4)
7534 RTMP_IO_READ32(pAd, offset + i, &Value);
7537 offset += MAX_LEN_OF_PEER_KEY;
7544 RTMP_IO_WRITE8(pAd, offset+i, pTxMic[i]);
7552 RTMP_IO_WRITE8(pAd, offset+i, pRxMic[i]);
7556 DBGPRINT(RT_DEBUG_TRACE,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID, CipherName[CipherAlg]));
7557 DBGPRINT(RT_DEBUG_TRACE,(" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7558 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]));
7561 DBGPRINT(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7562 pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
7566 DBGPRINT(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7567 pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
7571 ========================================================================
7573 Remove Pair-wise key material from ASIC.
7576 ========================================================================
7578 VOID AsicRemovePairwiseKeyEntry(
7579 IN PRTMP_ADAPTER pAd,
7586 // re-set the entry's WCID attribute as OPEN-NONE.
7587 offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
7588 WCIDAttri = (BssIdx<<4) | PAIRWISEKEYTABLE;
7589 RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
7592 BOOLEAN AsicSendCommandToMcu(
7593 IN PRTMP_ADAPTER pAd,
7599 HOST_CMD_CSR_STRUC H2MCmd;
7600 H2M_MAILBOX_STRUC H2MMailbox;
7603 static UINT32 j = 0;
7604 #endif // RALINK_ATE //
7607 RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
7608 if (H2MMailbox.field.Owner == 0)
7617 if (pAd->ate.bFWLoading == TRUE)
7619 /* reloading firmware when received iwpriv cmd "ATE=ATESTOP" */
7624 DBGPRINT(RT_DEBUG_ERROR, ("#"));
7628 DBGPRINT(RT_DEBUG_ERROR, ("\n"));
7634 DBGPRINT(RT_DEBUG_ERROR, ("Loading firmware. Please wait for a moment...\n"));
7639 #endif // RALINK_ATE //
7644 RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
7646 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
7648 // After Reset DMA, DMA index will become Zero. So Driver need to reset all ring indexs too.
7649 // Reset DMA/CPU ring index
7650 RTMPRingCleanUp(pAd, QID_AC_BK);
7651 RTMPRingCleanUp(pAd, QID_AC_BE);
7652 RTMPRingCleanUp(pAd, QID_AC_VI);
7653 RTMPRingCleanUp(pAd, QID_AC_VO);
7654 RTMPRingCleanUp(pAd, QID_HCCA);
7655 RTMPRingCleanUp(pAd, QID_MGMT);
7656 RTMPRingCleanUp(pAd, QID_RX);
7659 RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
7661 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
7662 DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
7668 else if (pAd->ate.bFWLoading == TRUE)
7670 /* reloading of firmware is completed */
7671 pAd->ate.bFWLoading = FALSE;
7672 DBGPRINT(RT_DEBUG_ERROR, ("\n"));
7675 #endif // RALINK_ATE //
7677 H2MMailbox.field.Owner = 1; // pass ownership to MCU
7678 H2MMailbox.field.CmdToken = Token;
7679 H2MMailbox.field.HighByte = Arg1;
7680 H2MMailbox.field.LowByte = Arg0;
7681 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
7684 H2MCmd.field.HostCommand = Command;
7685 RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
7687 if (Command != 0x80)
7694 BOOLEAN AsicCheckCommanOk(
7695 IN PRTMP_ADAPTER pAd,
7698 UINT32 CmdStatus = 0, CID = 0, i;
7699 UINT32 ThisCIDMask = 0;
7704 RTMP_IO_READ32(pAd, H2M_MAILBOX_CID, &CID);
7705 // Find where the command is. Because this is randomly specified by firmware.
7706 if ((CID & CID0MASK) == Command)
7708 ThisCIDMask = CID0MASK;
7711 else if ((((CID & CID1MASK)>>8) & 0xff) == Command)
7713 ThisCIDMask = CID1MASK;
7716 else if ((((CID & CID2MASK)>>16) & 0xff) == Command)
7718 ThisCIDMask = CID2MASK;
7721 else if ((((CID & CID3MASK)>>24) & 0xff) == Command)
7723 ThisCIDMask = CID3MASK;
7731 // Get CommandStatus Value
7732 RTMP_IO_READ32(pAd, H2M_MAILBOX_STATUS, &CmdStatus);
7734 // This command's status is at the same position as command. So AND command position's bitmask to read status.
7737 // If Status is 1, the comamnd is success.
7738 if (((CmdStatus & ThisCIDMask) == 0x1) || ((CmdStatus & ThisCIDMask) == 0x100)
7739 || ((CmdStatus & ThisCIDMask) == 0x10000) || ((CmdStatus & ThisCIDMask) == 0x1000000))
7741 DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanOk CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus));
7742 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
7743 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
7746 DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail1 CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus));
7750 DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail2 Timeout Command = %d, CmdStatus= 0x%x \n", Command, CmdStatus));
7752 // Clear Command and Status.
7753 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
7754 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
7760 ========================================================================
7762 Routine Description:
7763 Verify the support rate for different PHY type
7766 pAd Pointer to our adapter
7771 IRQL = PASSIVE_LEVEL
7773 ========================================================================
7775 VOID RTMPCheckRates(
7776 IN PRTMP_ADAPTER pAd,
7777 IN OUT UCHAR SupRate[],
7778 IN OUT UCHAR *SupRateLen)
7780 UCHAR RateIdx, i, j;
7781 UCHAR NewRate[12], NewRateLen;
7785 if (pAd->CommonCfg.PhyMode == PHY_11B)
7790 // Check for support rates exclude basic rate bit
7791 for (i = 0; i < *SupRateLen; i++)
7792 for (j = 0; j < RateIdx; j++)
7793 if ((SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
7794 NewRate[NewRateLen++] = SupRate[i];
7796 *SupRateLen = NewRateLen;
7797 NdisMoveMemory(SupRate, NewRate, NewRateLen);
7800 #ifdef CONFIG_STA_SUPPORT
7801 #ifdef DOT11_N_SUPPORT
7802 BOOLEAN RTMPCheckChannel(
7803 IN PRTMP_ADAPTER pAd,
7804 IN UCHAR CentralChannel,
7808 UCHAR UpperChannel = 0, LowerChannel = 0;
7809 UCHAR NoEffectChannelinList = 0;
7811 // Find upper and lower channel according to 40MHz current operation.
7812 if (CentralChannel < Channel)
7814 UpperChannel = Channel;
7815 if (CentralChannel > 2)
7816 LowerChannel = CentralChannel - 2;
7820 else if (CentralChannel > Channel)
7822 UpperChannel = CentralChannel + 2;
7823 LowerChannel = Channel;
7826 for (k = 0;k < pAd->ChannelListNum;k++)
7828 if (pAd->ChannelList[k].Channel == UpperChannel)
7830 NoEffectChannelinList ++;
7832 if (pAd->ChannelList[k].Channel == LowerChannel)
7834 NoEffectChannelinList ++;
7838 DBGPRINT(RT_DEBUG_TRACE,("Total Channel in Channel List = [%d]\n", NoEffectChannelinList));
7839 if (NoEffectChannelinList == 2)
7846 ========================================================================
7848 Routine Description:
7849 Verify the support rate for HT phy type
7852 pAd Pointer to our adapter
7855 FALSE if pAd->CommonCfg.SupportedHtPhy doesn't accept the pHtCapability. (AP Mode)
7857 IRQL = PASSIVE_LEVEL
7859 ========================================================================
7861 BOOLEAN RTMPCheckHt(
7862 IN PRTMP_ADAPTER pAd,
7864 IN HT_CAPABILITY_IE *pHtCapability,
7865 IN ADD_HT_INFO_IE *pAddHtInfo)
7867 if (Wcid >= MAX_LEN_OF_MAC_TABLE)
7870 // If use AMSDU, set flag.
7871 if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable)
7872 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_AMSDU_INUSED);
7873 // Save Peer Capability
7874 if (pHtCapability->HtCapInfo.ShortGIfor20)
7875 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_SGI20_CAPABLE);
7876 if (pHtCapability->HtCapInfo.ShortGIfor40)
7877 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_SGI40_CAPABLE);
7878 if (pHtCapability->HtCapInfo.TxSTBC)
7879 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_TxSTBC_CAPABLE);
7880 if (pHtCapability->HtCapInfo.RxSTBC)
7881 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_RxSTBC_CAPABLE);
7882 if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport)
7884 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_RDG_CAPABLE);
7887 if (Wcid < MAX_LEN_OF_MAC_TABLE)
7889 pAd->MacTab.Content[Wcid].MpduDensity = pHtCapability->HtCapParm.MpduDensity;
7892 // Will check ChannelWidth for MCSSet[4] below
7893 pAd->MlmeAux.HtCapability.MCSSet[4] = 0x1;
7894 switch (pAd->CommonCfg.RxStream)
7897 pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
7898 pAd->MlmeAux.HtCapability.MCSSet[1] = 0x00;
7899 pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
7900 pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
7903 pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
7904 pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
7905 pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
7906 pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
7909 pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
7910 pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
7911 pAd->MlmeAux.HtCapability.MCSSet[2] = 0xff;
7912 pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
7916 pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth = pAddHtInfo->AddHtInfo.RecomWidth & pAd->CommonCfg.DesiredHtPhy.ChannelWidth;
7918 DBGPRINT(RT_DEBUG_TRACE, ("RTMPCheckHt:: HtCapInfo.ChannelWidth=%d, RecomWidth=%d, DesiredHtPhy.ChannelWidth=%d, BW40MAvailForA/G=%d/%d, PhyMode=%d \n",
7919 pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth, pAddHtInfo->AddHtInfo.RecomWidth, pAd->CommonCfg.DesiredHtPhy.ChannelWidth,
7920 pAd->NicConfig2.field.BW40MAvailForA, pAd->NicConfig2.field.BW40MAvailForG, pAd->CommonCfg.PhyMode));
7922 pAd->MlmeAux.HtCapability.HtCapInfo.GF = pHtCapability->HtCapInfo.GF &pAd->CommonCfg.DesiredHtPhy.GF;
7924 // Send Assoc Req with my HT capability.
7925 pAd->MlmeAux.HtCapability.HtCapInfo.AMsduSize = pAd->CommonCfg.DesiredHtPhy.AmsduSize;
7926 pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs = pAd->CommonCfg.DesiredHtPhy.MimoPs;
7927 pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20 = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20) & (pHtCapability->HtCapInfo.ShortGIfor20);
7928 pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40 = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40) & (pHtCapability->HtCapInfo.ShortGIfor40);
7929 pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC = (pAd->CommonCfg.DesiredHtPhy.TxSTBC)&(pHtCapability->HtCapInfo.RxSTBC);
7930 pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC = (pAd->CommonCfg.DesiredHtPhy.RxSTBC)&(pHtCapability->HtCapInfo.TxSTBC);
7931 pAd->MlmeAux.HtCapability.HtCapParm.MaxRAmpduFactor = pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor;
7932 pAd->MlmeAux.HtCapability.HtCapParm.MpduDensity = pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity;
7933 pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = pHtCapability->ExtHtCapInfo.PlusHTC;
7934 pAd->MacTab.Content[Wcid].HTCapability.ExtHtCapInfo.PlusHTC = pHtCapability->ExtHtCapInfo.PlusHTC;
7935 if (pAd->CommonCfg.bRdg)
7937 pAd->MlmeAux.HtCapability.ExtHtCapInfo.RDGSupport = pHtCapability->ExtHtCapInfo.RDGSupport;
7938 pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = 1;
7941 if (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_20)
7942 pAd->MlmeAux.HtCapability.MCSSet[4] = 0x0; // BW20 can't transmit MCS32
7944 COPY_AP_HTSETTINGS_FROM_BEACON(pAd, pHtCapability);
7947 #endif // DOT11_N_SUPPORT //
7948 #endif // CONFIG_STA_SUPPORT //
7951 ========================================================================
7953 Routine Description:
7954 Verify the support rate for different PHY type
7957 pAd Pointer to our adapter
7962 IRQL = PASSIVE_LEVEL
7964 ========================================================================
7966 VOID RTMPUpdateMlmeRate(
7967 IN PRTMP_ADAPTER pAd)
7970 UCHAR ProperMlmeRate; //= RATE_54;
7971 UCHAR i, j, RateIdx = 12; //1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
7972 BOOLEAN bMatch = FALSE;
7974 switch (pAd->CommonCfg.PhyMode)
7977 ProperMlmeRate = RATE_11;
7978 MinimumRate = RATE_1;
7980 case PHY_11BG_MIXED:
7981 #ifdef DOT11_N_SUPPORT
7982 case PHY_11ABGN_MIXED:
7983 case PHY_11BGN_MIXED:
7984 #endif // DOT11_N_SUPPORT //
7985 if ((pAd->MlmeAux.SupRateLen == 4) &&
7986 (pAd->MlmeAux.ExtRateLen == 0))
7988 ProperMlmeRate = RATE_11;
7990 ProperMlmeRate = RATE_24;
7992 if (pAd->MlmeAux.Channel <= 14)
7993 MinimumRate = RATE_1;
7995 MinimumRate = RATE_6;
7998 #ifdef DOT11_N_SUPPORT
7999 case PHY_11N_2_4G: // rt2860 need to check mlmerate for 802.11n
8000 case PHY_11GN_MIXED:
8001 case PHY_11AGN_MIXED:
8002 case PHY_11AN_MIXED:
8004 #endif // DOT11_N_SUPPORT //
8005 ProperMlmeRate = RATE_24;
8006 MinimumRate = RATE_6;
8008 case PHY_11ABG_MIXED:
8009 ProperMlmeRate = RATE_24;
8010 if (pAd->MlmeAux.Channel <= 14)
8011 MinimumRate = RATE_1;
8013 MinimumRate = RATE_6;
8016 ProperMlmeRate = RATE_1;
8017 MinimumRate = RATE_1;
8021 for (i = 0; i < pAd->MlmeAux.SupRateLen; i++)
8023 for (j = 0; j < RateIdx; j++)
8025 if ((pAd->MlmeAux.SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
8027 if (j == ProperMlmeRate)
8039 if (bMatch == FALSE)
8041 for (i = 0; i < pAd->MlmeAux.ExtRateLen; i++)
8043 for (j = 0; j < RateIdx; j++)
8045 if ((pAd->MlmeAux.ExtRate[i] & 0x7f) == RateIdTo500Kbps[j])
8047 if (j == ProperMlmeRate)
8060 if (bMatch == FALSE)
8062 ProperMlmeRate = MinimumRate;
8065 pAd->CommonCfg.MlmeRate = MinimumRate;
8066 pAd->CommonCfg.RtsRate = ProperMlmeRate;
8067 if (pAd->CommonCfg.MlmeRate >= RATE_6)
8069 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
8070 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
8071 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
8072 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
8076 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
8077 pAd->CommonCfg.MlmeTransmit.field.MCS = pAd->CommonCfg.MlmeRate;
8078 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_CCK;
8079 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = pAd->CommonCfg.MlmeRate;
8082 DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateMlmeRate ==> MlmeTransmit = 0x%x \n" , pAd->CommonCfg.MlmeTransmit.word));
8086 IN PRTMP_ADAPTER pAd,
8093 if ((pAd->Antenna.field.RxPath == 1) && (Rssi0 != 0))
8098 if ((pAd->Antenna.field.RxPath >= 2) && (Rssi1 != 0))
8100 larger = max(Rssi0, Rssi1);
8103 if ((pAd->Antenna.field.RxPath == 3) && (Rssi2 != 0))
8105 larger = max(larger, Rssi2);
8115 ========================================================================
8116 Routine Description:
8117 Periodic evaluate antenna link status
8120 pAd - Adapter pointer
8125 ========================================================================
8127 VOID AsicEvaluateRxAnt(
8128 IN PRTMP_ADAPTER pAd)
8135 #endif // RALINK_ATE //
8138 #ifdef CONFIG_STA_SUPPORT
8139 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
8141 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
8142 fRTMP_ADAPTER_HALT_IN_PROGRESS |
8143 fRTMP_ADAPTER_RADIO_OFF |
8144 fRTMP_ADAPTER_NIC_NOT_EXIST |
8145 fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
8148 if (pAd->StaCfg.Psm == PWR_SAVE)
8151 #endif // CONFIG_STA_SUPPORT //
8153 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
8155 if(pAd->Antenna.field.RxPath == 3)
8159 else if(pAd->Antenna.field.RxPath == 2)
8163 else if(pAd->Antenna.field.RxPath == 1)
8167 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
8168 #ifdef CONFIG_STA_SUPPORT
8169 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
8170 pAd->StaCfg.BBPR3 = BBPR3;
8171 #endif // CONFIG_STA_SUPPORT //
8172 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
8175 ULONG TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
8176 pAd->RalinkCounters.OneSecTxRetryOkCount +
8177 pAd->RalinkCounters.OneSecTxFailCount;
8179 if (TxTotalCnt > 50)
8181 RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 20);
8182 pAd->Mlme.bLowThroughput = FALSE;
8186 RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
8187 pAd->Mlme.bLowThroughput = TRUE;
8193 ========================================================================
8194 Routine Description:
8195 After evaluation, check antenna link status
8198 pAd - Adapter pointer
8203 ========================================================================
8205 VOID AsicRxAntEvalTimeout(
8206 IN PVOID SystemSpecific1,
8207 IN PVOID FunctionContext,
8208 IN PVOID SystemSpecific2,
8209 IN PVOID SystemSpecific3)
8211 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
8212 #ifdef CONFIG_STA_SUPPORT
8214 CHAR larger = -127, rssi0, rssi1, rssi2;
8215 #endif // CONFIG_STA_SUPPORT //
8220 #endif // RALINK_ATE //
8223 #ifdef CONFIG_STA_SUPPORT
8224 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
8226 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
8227 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
8228 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF) ||
8229 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
8232 if (pAd->StaCfg.Psm == PWR_SAVE)
8236 // if the traffic is low, use average rssi as the criteria
8237 if (pAd->Mlme.bLowThroughput == TRUE)
8239 rssi0 = pAd->StaCfg.RssiSample.LastRssi0;
8240 rssi1 = pAd->StaCfg.RssiSample.LastRssi1;
8241 rssi2 = pAd->StaCfg.RssiSample.LastRssi2;
8245 rssi0 = pAd->StaCfg.RssiSample.AvgRssi0;
8246 rssi1 = pAd->StaCfg.RssiSample.AvgRssi1;
8247 rssi2 = pAd->StaCfg.RssiSample.AvgRssi2;
8250 if(pAd->Antenna.field.RxPath == 3)
8252 larger = max(rssi0, rssi1);
8254 if (larger > (rssi2 + 20))
8255 pAd->Mlme.RealRxPath = 2;
8257 pAd->Mlme.RealRxPath = 3;
8259 else if(pAd->Antenna.field.RxPath == 2)
8261 if (rssi0 > (rssi1 + 20))
8262 pAd->Mlme.RealRxPath = 1;
8264 pAd->Mlme.RealRxPath = 2;
8267 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
8269 if(pAd->Mlme.RealRxPath == 3)
8273 else if(pAd->Mlme.RealRxPath == 2)
8277 else if(pAd->Mlme.RealRxPath == 1)
8281 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
8282 pAd->StaCfg.BBPR3 = BBPR3;
8285 #endif // CONFIG_STA_SUPPORT //
8291 VOID APSDPeriodicExec(
8292 IN PVOID SystemSpecific1,
8293 IN PVOID FunctionContext,
8294 IN PVOID SystemSpecific2,
8295 IN PVOID SystemSpecific3)
8297 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
8299 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
8302 pAd->CommonCfg.TriggerTimerCount++;
8307 ========================================================================
8308 Routine Description:
8309 Set/reset MAC registers according to bPiggyBack parameter
8312 pAd - Adapter pointer
8313 bPiggyBack - Enable / Disable Piggy-Back
8318 ========================================================================
8320 VOID RTMPSetPiggyBack(
8321 IN PRTMP_ADAPTER pAd,
8322 IN BOOLEAN bPiggyBack)
8324 TX_LINK_CFG_STRUC TxLinkCfg;
8326 RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
8328 TxLinkCfg.field.TxCFAckEn = bPiggyBack;
8329 RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
8333 ========================================================================
8334 Routine Description:
8335 check if this entry need to switch rate automatically
8345 ========================================================================
8347 BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(
8348 IN PRTMP_ADAPTER pAd,
8349 IN PMAC_TABLE_ENTRY pEntry)
8351 BOOLEAN result = TRUE;
8354 #ifdef CONFIG_STA_SUPPORT
8355 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
8357 // only associated STA counts
8358 if (pEntry && (pEntry->ValidAsCLI) && (pEntry->Sst == SST_ASSOC))
8360 result = pAd->StaCfg.bAutoTxRateSwitch;
8365 #ifdef QOS_DLS_SUPPORT
8366 if (pEntry && (pEntry->ValidAsDls))
8367 result = pAd->StaCfg.bAutoTxRateSwitch;
8368 #endif // QOS_DLS_SUPPORT //
8370 #endif // CONFIG_STA_SUPPORT //
8378 BOOLEAN RTMPAutoRateSwitchCheck(
8379 IN PRTMP_ADAPTER pAd)
8382 #ifdef CONFIG_STA_SUPPORT
8383 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
8385 if (pAd->StaCfg.bAutoTxRateSwitch)
8388 #endif // CONFIG_STA_SUPPORT //
8394 ========================================================================
8395 Routine Description:
8396 check if this entry need to fix tx legacy rate
8406 ========================================================================
8408 UCHAR RTMPStaFixedTxMode(
8409 IN PRTMP_ADAPTER pAd,
8410 IN PMAC_TABLE_ENTRY pEntry)
8412 UCHAR tx_mode = FIXED_TXMODE_HT;
8415 #ifdef CONFIG_STA_SUPPORT
8416 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
8418 tx_mode = (UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode;
8420 #endif // CONFIG_STA_SUPPORT //
8426 ========================================================================
8427 Routine Description:
8428 Overwrite HT Tx Mode by Fixed Legency Tx Mode, if specified.
8438 ========================================================================
8440 VOID RTMPUpdateLegacyTxSetting(
8441 UCHAR fixed_tx_mode,
8442 PMAC_TABLE_ENTRY pEntry)
8444 HTTRANSMIT_SETTING TransmitSetting;
8446 if (fixed_tx_mode == FIXED_TXMODE_HT)
8449 TransmitSetting.word = 0;
8451 TransmitSetting.field.MODE = pEntry->HTPhyMode.field.MODE;
8452 TransmitSetting.field.MCS = pEntry->HTPhyMode.field.MCS;
8454 if (fixed_tx_mode == FIXED_TXMODE_CCK)
8456 TransmitSetting.field.MODE = MODE_CCK;
8457 // CCK mode allow MCS 0~3
8458 if (TransmitSetting.field.MCS > MCS_3)
8459 TransmitSetting.field.MCS = MCS_3;
8463 TransmitSetting.field.MODE = MODE_OFDM;
8464 // OFDM mode allow MCS 0~7
8465 if (TransmitSetting.field.MCS > MCS_7)
8466 TransmitSetting.field.MCS = MCS_7;
8469 if (pEntry->HTPhyMode.field.MODE >= TransmitSetting.field.MODE)
8471 pEntry->HTPhyMode.word = TransmitSetting.word;
8472 DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateLegacyTxSetting : wcid-%d, MODE=%s, MCS=%d \n",
8473 pEntry->Aid, GetPhyMode(pEntry->HTPhyMode.field.MODE), pEntry->HTPhyMode.field.MCS));
8477 #ifdef CONFIG_STA_SUPPORT
8479 ==========================================================================
8481 dynamic tune BBP R66 to find a balance between sensibility and
8484 IRQL = DISPATCH_LEVEL
8486 ==========================================================================
8488 VOID AsicStaBbpTuning(
8489 IN PRTMP_ADAPTER pAd)
8491 UCHAR OrigR66Value = 0, R66;//, R66UpperBound = 0x30, R66LowerBound = 0x30;
8494 // 2860C did not support Fase CCA, therefore can't tune
8495 if (pAd->MACVersion == 0x28600100)
8501 if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) // no R66 tuning when SCANNING
8504 if ((pAd->OpMode == OPMODE_STA)
8505 && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
8507 && !(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
8508 && (pAd->bPCIclkOff == FALSE))
8510 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &OrigR66Value);
8513 if (pAd->Antenna.field.RxPath > 1)
8514 Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
8516 Rssi = pAd->StaCfg.RssiSample.AvgRssi0;
8518 if (pAd->LatchRfRegs.Channel <= 14)
8521 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
8523 R66 = (0x2E + GET_LNA_GAIN(pAd)) + 0x10;
8524 if (OrigR66Value != R66)
8526 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8531 R66 = 0x2E + GET_LNA_GAIN(pAd);
8532 if (OrigR66Value != R66)
8534 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8541 if (pAd->CommonCfg.BBPCurrentBW == BW_20)
8543 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
8545 R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3 + 0x10;
8546 if (OrigR66Value != R66)
8548 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8553 R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3;
8554 if (OrigR66Value != R66)
8556 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8562 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
8564 R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3 + 0x10;
8565 if (OrigR66Value != R66)
8567 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8572 R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3;
8573 if (OrigR66Value != R66)
8575 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8585 VOID AsicResetFromDMABusy(
8586 IN PRTMP_ADAPTER pAd)
8589 BOOLEAN bCtrl = FALSE;
8591 DBGPRINT(RT_DEBUG_TRACE, ("---> AsicResetFromDMABusy !!!!!!!!!!!!!!!!!!!!!!! \n"));
8593 // Be sure restore link control value so we can write register.
8594 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
8595 if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
8597 DBGPRINT(RT_DEBUG_TRACE,("AsicResetFromDMABusy==>\n"));
8598 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
8599 RTMPusecDelay(6000);
8600 pAd->bPCIclkOff = FALSE;
8604 RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
8606 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
8608 // After Reset DMA, DMA index will become Zero. So Driver need to reset all ring indexs too.
8609 // Reset DMA/CPU ring index
8610 RTMPRingCleanUp(pAd, QID_AC_BK);
8611 RTMPRingCleanUp(pAd, QID_AC_BE);
8612 RTMPRingCleanUp(pAd, QID_AC_VI);
8613 RTMPRingCleanUp(pAd, QID_AC_VO);
8614 RTMPRingCleanUp(pAd, QID_HCCA);
8615 RTMPRingCleanUp(pAd, QID_MGMT);
8616 RTMPRingCleanUp(pAd, QID_RX);
8619 RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
8621 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
8623 // If in Radio off, should call RTMPPCIePowerLinkCtrl again.
8624 if ((bCtrl == TRUE) && (pAd->StaCfg.bRadio == FALSE))
8625 RTMPPCIeLinkCtrlSetting(pAd, 3);
8627 RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
8628 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS);
8629 DBGPRINT(RT_DEBUG_TRACE, ("<--- AsicResetFromDMABusy !!!!!!!!!!!!!!!!!!!!!!! \n"));
8633 IN PRTMP_ADAPTER pAd)
8635 DBGPRINT(RT_DEBUG_TRACE, ("---> Asic HardReset BBP !!!!!!!!!!!!!!!!!!!!!!! \n"));
8637 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
8638 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x2);
8639 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc);
8641 // After hard-reset BBP, initialize all BBP values.
8642 NICRestoreBBPValue(pAd);
8643 DBGPRINT(RT_DEBUG_TRACE, ("<--- Asic HardReset BBP !!!!!!!!!!!!!!!!!!!!!!! \n"));
8647 IN PRTMP_ADAPTER pAd)
8651 DBGPRINT(RT_DEBUG_TRACE, ("---> AsicResetMAC !!!! \n"));
8652 RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
8654 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
8656 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
8658 DBGPRINT(RT_DEBUG_TRACE, ("<--- AsicResetMAC !!!! \n"));
8662 IN PRTMP_ADAPTER pAd)
8664 ULONG Value1, Value2;
8667 RTMP_IO_READ32(pAd, TXRXQ_PCNT, &Value1);
8668 RTMP_IO_READ32(pAd, PBF_DBG, &Value2);
8671 // sum should be equals to 0xff, which is the total buffer size.
8672 if ((Value1 + Value2) < 0xff)
8674 DBGPRINT(RT_DEBUG_TRACE, ("---> Asic HardReset PBF !!!! \n"));
8675 RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
8677 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
8679 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
8681 DBGPRINT(RT_DEBUG_TRACE, ("<--- Asic HardReset PBF !!!! \n"));
8684 #endif // CONFIG_STA_SUPPORT //
8686 VOID RTMPSetAGCInitValue(
8687 IN PRTMP_ADAPTER pAd,
8692 if (pAd->LatchRfRegs.Channel <= 14)
8694 R66 = 0x2E + GET_LNA_GAIN(pAd);
8695 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8699 if (BandWidth == BW_20)
8701 R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3);
8702 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8704 #ifdef DOT11_N_SUPPORT
8707 R66 = (UCHAR)(0x3A + (GET_LNA_GAIN(pAd)*5)/3);
8708 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8710 #endif // DOT11_N_SUPPORT //
8715 VOID AsicTurnOffRFClk(
8716 IN PRTMP_ADAPTER pAd,
8721 UINT32 R1 = 0, R2 = 0, R3 = 0;
8723 RTMP_RF_REGS *RFRegTable;
8725 RFRegTable = RF2850RegTable;
8727 switch (pAd->RfIcType)
8734 for (index = 0; index < NUM_OF_2850_CHNL; index++)
8736 if (Channel == RFRegTable[index].Channel)
8738 R1 = RFRegTable[index].R1 & 0xffffdfff;
8739 R2 = RFRegTable[index].R2 & 0xfffbffff;
8740 R3 = RFRegTable[index].R3 & 0xfff3ffff;
8742 RTMP_RF_IO_WRITE32(pAd, R1);
8743 RTMP_RF_IO_WRITE32(pAd, R2);
8745 // Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0.
8746 // Set RF R2 bit18=0, R3 bit[18:19]=0
8747 //if (pAd->StaCfg.bRadio == FALSE)
8750 RTMP_RF_IO_WRITE32(pAd, R3);
8752 DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x, R3 = 0x%08x \n",
8753 Channel, pAd->RfIcType, R2, R3));
8756 DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n",
8757 Channel, pAd->RfIcType, R2));
8769 VOID AsicTurnOnRFClk(
8770 IN PRTMP_ADAPTER pAd,
8775 UINT32 R1 = 0, R2 = 0, R3 = 0;
8777 RTMP_RF_REGS *RFRegTable;
8779 RFRegTable = RF2850RegTable;
8781 switch (pAd->RfIcType)
8788 for (index = 0; index < NUM_OF_2850_CHNL; index++)
8790 if (Channel == RFRegTable[index].Channel)
8792 R3 = pAd->LatchRfRegs.R3;
8795 RTMP_RF_IO_WRITE32(pAd, R3);
8797 R1 = RFRegTable[index].R1;
8798 RTMP_RF_IO_WRITE32(pAd, R1);
8800 R2 = RFRegTable[index].R2;
8801 if (pAd->Antenna.field.TxPath == 1)
8803 R2 |= 0x4000; // If TXpath is 1, bit 14 = 1;
8806 if (pAd->Antenna.field.RxPath == 2)
8808 R2 |= 0x40; // write 1 to off Rxpath.
8810 else if (pAd->Antenna.field.RxPath == 1)
8812 R2 |= 0x20040; // write 1 to off RxPath
8814 RTMP_RF_IO_WRITE32(pAd, R2);
8825 DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n",