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,
252 0x05, 0x20, 20, 15, 30,
253 0x06, 0x20, 21, 8, 20,
254 0x07, 0x20, 22, 8, 20,
255 0x08, 0x20, 23, 8, 25,
256 0x09, 0x22, 23, 8, 25,
257 #else // for RT2860 2*3 test
258 0x05, 0x20, 12, 15, 30,
259 0x06, 0x20, 13, 8, 20,
260 0x07, 0x20, 14, 8, 20,
261 0x08, 0x20, 15, 8, 25,
262 0x09, 0x22, 15, 8, 25,
266 UCHAR RateSwitchTable11BGN2SForABand
[] = {
267 // 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)
268 0x0b, 0x09, 0, 0, 0, // Initial used item after association
269 0x00, 0x21, 0, 30,101, //50
270 0x01, 0x21, 1, 20, 50,
271 0x02, 0x21, 2, 20, 50,
272 0x03, 0x21, 3, 15, 50,
273 0x04, 0x21, 4, 15, 30,
274 0x05, 0x21, 5, 15, 30,
275 0x06, 0x20, 12, 15, 30,
276 0x07, 0x20, 13, 8, 20,
277 0x08, 0x20, 14, 8, 20,
278 0x09, 0x20, 15, 8, 25,
279 0x0a, 0x22, 15, 8, 25,
282 UCHAR RateSwitchTable11BGN3SForABand
[] = { // 3*3
283 // 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)
284 0x0c, 0x09, 0, 0, 0, // Initial used item after association
285 0x00, 0x21, 0, 30,101, //50
286 0x01, 0x21, 1, 20, 50,
287 0x02, 0x21, 2, 20, 50,
288 0x03, 0x21, 3, 15, 50,
289 0x04, 0x21, 4, 15, 30,
290 0x05, 0x21, 5, 15, 30,
291 0x06, 0x21, 12, 15, 30,
292 0x07, 0x20, 20, 15, 30,
293 0x08, 0x20, 21, 8, 20,
294 0x09, 0x20, 22, 8, 20,
295 0x0a, 0x20, 23, 8, 25,
296 0x0b, 0x22, 23, 8, 25,
298 #endif // DOT11_N_SUPPORT //
300 PUCHAR ReasonString
[] = {
302 /* 1 */ "Unspecified Reason",
303 /* 2 */ "Previous Auth no longer valid",
304 /* 3 */ "STA is leaving / has left",
305 /* 4 */ "DIS-ASSOC due to inactivity",
306 /* 5 */ "AP unable to hanle all associations",
307 /* 6 */ "class 2 error",
308 /* 7 */ "class 3 error",
309 /* 8 */ "STA is leaving / has left",
310 /* 9 */ "require auth before assoc/re-assoc",
314 /* 13 */ "invalid IE",
315 /* 14 */ "MIC error",
316 /* 15 */ "4-way handshake timeout",
317 /* 16 */ "2-way (group key) handshake timeout",
318 /* 17 */ "4-way handshake IE diff among AssosReq/Rsp/Beacon",
322 extern UCHAR OfdmRateToRxwiMCS
[];
323 // since RT61 has better RX sensibility, we have to limit TX ACK rate not to exceed our normal data TX rate.
324 // otherwise the WLAN peer may not be able to receive the ACK thus downgrade its data TX rate
325 ULONG BasicRateMask
[12] = {0xfffff001 /* 1-Mbps */, 0xfffff003 /* 2 Mbps */, 0xfffff007 /* 5.5 */, 0xfffff00f /* 11 */,
326 0xfffff01f /* 6 */ , 0xfffff03f /* 9 */ , 0xfffff07f /* 12 */ , 0xfffff0ff /* 18 */,
327 0xfffff1ff /* 24 */ , 0xfffff3ff /* 36 */ , 0xfffff7ff /* 48 */ , 0xffffffff /* 54 */};
329 UCHAR MULTICAST_ADDR
[MAC_ADDR_LEN
] = {0x1, 0x00, 0x00, 0x00, 0x00, 0x00};
330 UCHAR BROADCAST_ADDR
[MAC_ADDR_LEN
] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
331 UCHAR ZERO_MAC_ADDR
[MAC_ADDR_LEN
] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
333 // e.g. RssiSafeLevelForTxRate[RATE_36]" means if the current RSSI is greater than
334 // this value, then it's quaranteed capable of operating in 36 mbps TX rate in
335 // clean environment.
336 // TxRate: 1 2 5.5 11 6 9 12 18 24 36 48 54 72 100
337 CHAR RssiSafeLevelForTxRate
[] ={ -92, -91, -90, -87, -88, -86, -85, -83, -81, -78, -72, -71, -40, -40 };
339 UCHAR RateIdToMbps
[] = { 1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 72, 100};
340 USHORT RateIdTo500Kbps
[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 144, 200};
342 UCHAR SsidIe
= IE_SSID
;
343 UCHAR SupRateIe
= IE_SUPP_RATES
;
344 UCHAR ExtRateIe
= IE_EXT_SUPP_RATES
;
345 #ifdef DOT11_N_SUPPORT
346 UCHAR HtCapIe
= IE_HT_CAP
;
347 UCHAR AddHtInfoIe
= IE_ADD_HT
;
348 UCHAR NewExtChanIe
= IE_SECONDARY_CH_OFFSET
;
349 #endif // DOT11_N_SUPPORT //
350 UCHAR ErpIe
= IE_ERP
;
351 UCHAR DsIe
= IE_DS_PARM
;
352 UCHAR TimIe
= IE_TIM
;
353 UCHAR WpaIe
= IE_WPA
;
354 UCHAR Wpa2Ie
= IE_WPA2
;
355 UCHAR IbssIe
= IE_IBSS_PARM
;
356 UCHAR Ccx2Ie
= IE_CCX_V2
;
357 UCHAR WapiIe
= IE_WAPI
;
359 extern UCHAR WPA_OUI
[];
361 UCHAR SES_OUI
[] = {0x00, 0x90, 0x4c};
363 UCHAR ZeroSsid
[32] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
364 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
366 // Reset the RFIC setting to new series
367 RTMP_RF_REGS RF2850RegTable
[] = {
368 // ch R1 R2 R3(TX0~4=0) R4
369 {1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b},
370 {2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f},
371 {3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b},
372 {4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f},
373 {5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b},
374 {6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f},
375 {7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b},
376 {8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f},
377 {9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b},
378 {10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f},
379 {11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b},
380 {12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f},
381 {13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b},
382 {14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193},
384 // 802.11 UNI / HyperLan 2
385 {36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3},
386 {38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193},
387 {40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183},
388 {44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3},
389 {46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b},
390 {48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b},
391 {52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193},
392 {54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3},
393 {56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b},
394 {60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183},
395 {62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193},
396 {64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3}, // Plugfest#4, Day4, change RFR3 left4th 9->5.
399 {100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783},
401 // 2008.04.30 modified
402 // The system team has AN to improve the EVM value
403 // for channel 102 to 108 for the RT2850/RT2750 dual band solution.
404 {102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793},
405 {104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3},
406 {108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193},
408 {110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183},
409 {112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b},
410 {116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3},
411 {118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193},
412 {120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183},
413 {124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193},
414 {126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}, // 0x980ed1bb->0x980ed15b required by Rory 20070927
415 {128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3},
416 {132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b},
417 {134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193},
418 {136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b},
419 {140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183},
422 {149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7},
423 {151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187},
424 {153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f},
425 {157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f},
426 {159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7},
427 {161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187},
428 {165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197},
431 {184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b},
432 {188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13},
433 {192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b},
434 {196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23},
435 {208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13},
436 {212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b},
437 {216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23},
439 // still lack of MMAC(Japan) ch 34,38,42,46
441 UCHAR NUM_OF_2850_CHNL
= (sizeof(RF2850RegTable
) / sizeof(RTMP_RF_REGS
));
443 FREQUENCY_ITEM FreqItems3020
[] =
445 /**************************************************/
446 // ISM : 2.4 to 2.483 GHz //
447 /**************************************************/
449 /**************************************************/
450 //-CH---N-------R---K-----------
466 #define NUM_OF_3020_CHNL (sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM))
469 ==========================================================================
471 initialize the MLME task and its data structure (queue, spinlock,
472 timer, state machines).
477 always return NDIS_STATUS_SUCCESS
479 ==========================================================================
481 NDIS_STATUS
MlmeInit(
482 IN PRTMP_ADAPTER pAd
)
484 NDIS_STATUS Status
= NDIS_STATUS_SUCCESS
;
486 DBGPRINT(RT_DEBUG_TRACE
, ("--> MLME Initialize\n"));
490 Status
= MlmeQueueInit(&pAd
->Mlme
.Queue
);
491 if(Status
!= NDIS_STATUS_SUCCESS
)
494 pAd
->Mlme
.bRunning
= FALSE
;
495 NdisAllocateSpinLock(&pAd
->Mlme
.TaskLock
);
497 #ifdef CONFIG_STA_SUPPORT
498 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
500 BssTableInit(&pAd
->ScanTab
);
502 // init STA state machines
503 AssocStateMachineInit(pAd
, &pAd
->Mlme
.AssocMachine
, pAd
->Mlme
.AssocFunc
);
504 AuthStateMachineInit(pAd
, &pAd
->Mlme
.AuthMachine
, pAd
->Mlme
.AuthFunc
);
505 AuthRspStateMachineInit(pAd
, &pAd
->Mlme
.AuthRspMachine
, pAd
->Mlme
.AuthRspFunc
);
506 SyncStateMachineInit(pAd
, &pAd
->Mlme
.SyncMachine
, pAd
->Mlme
.SyncFunc
);
507 WpaPskStateMachineInit(pAd
, &pAd
->Mlme
.WpaPskMachine
, pAd
->Mlme
.WpaPskFunc
);
508 AironetStateMachineInit(pAd
, &pAd
->Mlme
.AironetMachine
, pAd
->Mlme
.AironetFunc
);
510 // Since we are using switch/case to implement it, the init is different from the above
511 // state machine init
512 MlmeCntlInit(pAd
, &pAd
->Mlme
.CntlMachine
, NULL
);
514 #endif // CONFIG_STA_SUPPORT //
518 ActionStateMachineInit(pAd
, &pAd
->Mlme
.ActMachine
, pAd
->Mlme
.ActFunc
);
520 // Init mlme periodic timer
521 RTMPInitTimer(pAd
, &pAd
->Mlme
.PeriodicTimer
, GET_TIMER_FUNCTION(MlmePeriodicExec
), pAd
, TRUE
);
523 // Set mlme periodic timer
524 RTMPSetTimer(&pAd
->Mlme
.PeriodicTimer
, MLME_TASK_EXEC_INTV
);
526 // software-based RX Antenna diversity
527 RTMPInitTimer(pAd
, &pAd
->Mlme
.RxAntEvalTimer
, GET_TIMER_FUNCTION(AsicRxAntEvalTimeout
), pAd
, FALSE
);
531 DBGPRINT(RT_DEBUG_TRACE
, ("<-- MLME Initialize\n"));
537 ==========================================================================
539 main loop of the MLME
541 Mlme has to be initialized, and there are something inside the queue
543 This function is invoked from MPSetInformation and MPReceive;
544 This task guarantee only one MlmeHandler will run.
546 IRQL = DISPATCH_LEVEL
548 ==========================================================================
551 IN PRTMP_ADAPTER pAd
)
553 MLME_QUEUE_ELEM
*Elem
= NULL
;
555 // Only accept MLME and Frame from peer side, no other (control/data) frame should
556 // get into this state machine
558 NdisAcquireSpinLock(&pAd
->Mlme
.TaskLock
);
559 if(pAd
->Mlme
.bRunning
)
561 NdisReleaseSpinLock(&pAd
->Mlme
.TaskLock
);
566 pAd
->Mlme
.bRunning
= TRUE
;
568 NdisReleaseSpinLock(&pAd
->Mlme
.TaskLock
);
570 while (!MlmeQueueEmpty(&pAd
->Mlme
.Queue
))
572 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS
) ||
573 RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
) ||
574 RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
))
576 DBGPRINT(RT_DEBUG_TRACE
, ("Device Halted or Removed or MlmeRest, exit MlmeHandler! (queue num = %ld)\n", pAd
->Mlme
.Queue
.Num
));
580 //From message type, determine which state machine I should drive
581 if (MlmeDequeue(&pAd
->Mlme
.Queue
, &Elem
))
584 if (Elem
->MsgType
== MT2_RESET_CONF
)
586 DBGPRINT_RAW(RT_DEBUG_TRACE
, ("!!! reset MLME state machine !!!\n"));
587 MlmeRestartStateMachine(pAd
);
588 Elem
->Occupied
= FALSE
;
594 // if dequeue success
595 switch (Elem
->Machine
)
597 // STA state machines
598 #ifdef CONFIG_STA_SUPPORT
599 case ASSOC_STATE_MACHINE
:
600 StateMachinePerformAction(pAd
, &pAd
->Mlme
.AssocMachine
, Elem
);
602 case AUTH_STATE_MACHINE
:
603 StateMachinePerformAction(pAd
, &pAd
->Mlme
.AuthMachine
, Elem
);
605 case AUTH_RSP_STATE_MACHINE
:
606 StateMachinePerformAction(pAd
, &pAd
->Mlme
.AuthRspMachine
, Elem
);
608 case SYNC_STATE_MACHINE
:
609 StateMachinePerformAction(pAd
, &pAd
->Mlme
.SyncMachine
, Elem
);
611 case MLME_CNTL_STATE_MACHINE
:
612 MlmeCntlMachinePerformAction(pAd
, &pAd
->Mlme
.CntlMachine
, Elem
);
614 case WPA_PSK_STATE_MACHINE
:
615 StateMachinePerformAction(pAd
, &pAd
->Mlme
.WpaPskMachine
, Elem
);
617 case AIRONET_STATE_MACHINE
:
618 StateMachinePerformAction(pAd
, &pAd
->Mlme
.AironetMachine
, Elem
);
620 #endif // CONFIG_STA_SUPPORT //
622 case ACTION_STATE_MACHINE
:
623 StateMachinePerformAction(pAd
, &pAd
->Mlme
.ActMachine
, Elem
);
630 DBGPRINT(RT_DEBUG_TRACE
, ("ERROR: Illegal machine %ld in MlmeHandler()\n", Elem
->Machine
));
635 Elem
->Occupied
= FALSE
;
640 DBGPRINT_ERR(("MlmeHandler: MlmeQueue empty\n"));
644 NdisAcquireSpinLock(&pAd
->Mlme
.TaskLock
);
645 pAd
->Mlme
.bRunning
= FALSE
;
646 NdisReleaseSpinLock(&pAd
->Mlme
.TaskLock
);
650 ==========================================================================
652 Destructor of MLME (Destroy queue, state machine, spin lock and timer)
654 Adapter - NIC Adapter pointer
656 The MLME task will no longer work properly
660 ==========================================================================
663 IN PRTMP_ADAPTER pAd
)
667 DBGPRINT(RT_DEBUG_TRACE
, ("==> MlmeHalt\n"));
669 if (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
))
671 // disable BEACON generation and other BEACON related hardware timers
672 AsicDisableSync(pAd
);
675 #ifdef CONFIG_STA_SUPPORT
676 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
678 // Cancel pending timers
679 RTMPCancelTimer(&pAd
->MlmeAux
.AssocTimer
, &Cancelled
);
680 RTMPCancelTimer(&pAd
->MlmeAux
.ReassocTimer
, &Cancelled
);
681 RTMPCancelTimer(&pAd
->MlmeAux
.DisassocTimer
, &Cancelled
);
682 RTMPCancelTimer(&pAd
->MlmeAux
.AuthTimer
, &Cancelled
);
683 RTMPCancelTimer(&pAd
->MlmeAux
.BeaconTimer
, &Cancelled
);
684 RTMPCancelTimer(&pAd
->MlmeAux
.ScanTimer
, &Cancelled
);
686 #endif // CONFIG_STA_SUPPORT //
688 RTMPCancelTimer(&pAd
->Mlme
.PeriodicTimer
, &Cancelled
);
689 RTMPCancelTimer(&pAd
->Mlme
.RxAntEvalTimer
, &Cancelled
);
693 if (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
))
696 RTMPSetLED(pAd
, LED_HALT
);
697 RTMPSetSignalLED(pAd
, -100); // Force signal strength Led to be turned off, firmware is not done it.
700 LED_CFG_STRUC LedCfg
;
701 RTMP_IO_READ32(pAd
, LED_CFG
, &LedCfg
.word
);
702 LedCfg
.field
.LedPolar
= 0;
703 LedCfg
.field
.RLedMode
= 0;
704 LedCfg
.field
.GLedMode
= 0;
705 LedCfg
.field
.YLedMode
= 0;
706 RTMP_IO_WRITE32(pAd
, LED_CFG
, LedCfg
.word
);
711 RTMPusecDelay(5000); // 5 msec to gurantee Ant Diversity timer canceled
713 MlmeQueueDestroy(&pAd
->Mlme
.Queue
);
714 NdisFreeSpinLock(&pAd
->Mlme
.TaskLock
);
716 DBGPRINT(RT_DEBUG_TRACE
, ("<== MlmeHalt\n"));
719 VOID
MlmeResetRalinkCounters(
720 IN PRTMP_ADAPTER pAd
)
722 pAd
->RalinkCounters
.LastOneSecRxOkDataCnt
= pAd
->RalinkCounters
.OneSecRxOkDataCnt
;
723 // clear all OneSecxxx counters.
724 pAd
->RalinkCounters
.OneSecBeaconSentCnt
= 0;
725 pAd
->RalinkCounters
.OneSecFalseCCACnt
= 0;
726 pAd
->RalinkCounters
.OneSecRxFcsErrCnt
= 0;
727 pAd
->RalinkCounters
.OneSecRxOkCnt
= 0;
728 pAd
->RalinkCounters
.OneSecTxFailCount
= 0;
729 pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
= 0;
730 pAd
->RalinkCounters
.OneSecTxRetryOkCount
= 0;
731 pAd
->RalinkCounters
.OneSecRxOkDataCnt
= 0;
733 // TODO: for debug only. to be removed
734 pAd
->RalinkCounters
.OneSecOsTxCount
[QID_AC_BE
] = 0;
735 pAd
->RalinkCounters
.OneSecOsTxCount
[QID_AC_BK
] = 0;
736 pAd
->RalinkCounters
.OneSecOsTxCount
[QID_AC_VI
] = 0;
737 pAd
->RalinkCounters
.OneSecOsTxCount
[QID_AC_VO
] = 0;
738 pAd
->RalinkCounters
.OneSecDmaDoneCount
[QID_AC_BE
] = 0;
739 pAd
->RalinkCounters
.OneSecDmaDoneCount
[QID_AC_BK
] = 0;
740 pAd
->RalinkCounters
.OneSecDmaDoneCount
[QID_AC_VI
] = 0;
741 pAd
->RalinkCounters
.OneSecDmaDoneCount
[QID_AC_VO
] = 0;
742 pAd
->RalinkCounters
.OneSecTxDoneCount
= 0;
743 pAd
->RalinkCounters
.OneSecRxCount
= 0;
744 pAd
->RalinkCounters
.OneSecTxAggregationCount
= 0;
745 pAd
->RalinkCounters
.OneSecRxAggregationCount
= 0;
750 unsigned long rx_AMSDU
;
751 unsigned long rx_Total
;
754 ==========================================================================
756 This routine is executed periodically to -
757 1. Decide if it's a right time to turn on PwrMgmt bit of all
759 2. Calculate ChannelQuality based on statistics of the last
760 period, so that TX rate won't toggling very frequently between a
761 successful TX and a failed TX.
762 3. If the calculated ChannelQuality indicated current connection not
763 healthy, then a ROAMing attempt is tried here.
765 IRQL = DISPATCH_LEVEL
767 ==========================================================================
769 #define ADHOC_BEACON_LOST_TIME (8*OS_HZ) // 8 sec
770 VOID
MlmePeriodicExec(
771 IN PVOID SystemSpecific1
,
772 IN PVOID FunctionContext
,
773 IN PVOID SystemSpecific2
,
774 IN PVOID SystemSpecific3
)
777 PRTMP_ADAPTER pAd
= (RTMP_ADAPTER
*)FunctionContext
;
779 // Do nothing if the driver is starting halt state.
780 // This might happen when timer already been fired before cancel timer with mlmehalt
781 if ((RTMP_TEST_FLAG(pAd
, (fRTMP_ADAPTER_HALT_IN_PROGRESS
|
782 fRTMP_ADAPTER_RADIO_OFF
|
783 fRTMP_ADAPTER_RADIO_MEASUREMENT
|
784 fRTMP_ADAPTER_RESET_IN_PROGRESS
))))
787 RT28XX_MLME_PRE_SANITY_CHECK(pAd
);
789 #ifdef CONFIG_STA_SUPPORT
790 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
792 // Do nothing if monitor mode is on
796 if (pAd
->Mlme
.PeriodicRound
& 0x1)
798 // This is the fix for wifi 11n extension channel overlapping test case. for 2860D
799 if (((pAd
->MACVersion
& 0xffff) == 0x0101) &&
800 (STA_TGN_WIFI_ON(pAd
)) &&
801 (pAd
->CommonCfg
.IOTestParm
.bToggle
== FALSE
))
804 RTMP_IO_WRITE32(pAd
, TXOP_CTRL_CFG
, 0x24Bf);
805 pAd
->CommonCfg
.IOTestParm
.bToggle
= TRUE
;
807 else if ((STA_TGN_WIFI_ON(pAd
)) &&
808 ((pAd
->MACVersion
& 0xffff) == 0x0101))
810 RTMP_IO_WRITE32(pAd
, TXOP_CTRL_CFG
, 0x243f);
811 pAd
->CommonCfg
.IOTestParm
.bToggle
= FALSE
;
815 #endif // CONFIG_STA_SUPPORT //
817 pAd
->bUpdateBcnCntDone
= FALSE
;
819 // RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3);
820 pAd
->Mlme
.PeriodicRound
++;
822 // execute every 500ms
823 if ((pAd
->Mlme
.PeriodicRound
% 5 == 0) && RTMPAutoRateSwitchCheck(pAd
)/*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))*/)
825 #ifdef CONFIG_STA_SUPPORT
826 // perform dynamic tx rate switching based on past TX history
827 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
829 if ((OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
)
831 && (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_DOZE
)))
832 MlmeDynamicTxRateSwitching(pAd
);
834 #endif // CONFIG_STA_SUPPORT //
837 // Normal 1 second Mlme PeriodicExec.
838 if (pAd
->Mlme
.PeriodicRound
%MLME_TASK_EXEC_MULTIPLE
== 0)
840 pAd
->Mlme
.OneSecPeriodicRound
++;
850 //ORIBATimerTimeout(pAd);
852 // Media status changed, report to NDIS
853 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_MEDIA_STATE_CHANGE
))
855 RTMP_CLEAR_FLAG(pAd
, fRTMP_ADAPTER_MEDIA_STATE_CHANGE
);
856 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
858 pAd
->IndicateMediaState
= NdisMediaStateConnected
;
859 RTMP_IndicateMediaState(pAd
);
864 pAd
->IndicateMediaState
= NdisMediaStateDisconnected
;
865 RTMP_IndicateMediaState(pAd
);
869 NdisGetSystemUpTime(&pAd
->Mlme
.Now32
);
871 // add the most up-to-date h/w raw counters into software variable, so that
872 // the dynamic tuning mechanism below are based on most up-to-date information
873 NICUpdateRawCounters(pAd
);
876 RT2870_WatchDog(pAd
);
879 #ifdef DOT11_N_SUPPORT
880 // Need statistics after read counter. So put after NICUpdateRawCounters
881 ORIBATimerTimeout(pAd
);
882 #endif // DOT11_N_SUPPORT //
884 // if MGMT RING is full more than twice within 1 second, we consider there's
885 // a hardware problem stucking the TX path. In this case, try a hardware reset
886 // to recover the system
887 // if (pAd->RalinkCounters.MgmtRingFullCount >= 2)
888 // RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HARDWARE_ERROR);
890 // pAd->RalinkCounters.MgmtRingFullCount = 0;
892 // The time period for checking antenna is according to traffic
893 if (pAd
->Mlme
.bEnableAutoAntennaCheck
)
895 TxTotalCnt
= pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
+
896 pAd
->RalinkCounters
.OneSecTxRetryOkCount
+
897 pAd
->RalinkCounters
.OneSecTxFailCount
;
901 if (pAd
->Mlme
.OneSecPeriodicRound
% 10 == 0)
903 AsicEvaluateRxAnt(pAd
);
908 if (pAd
->Mlme
.OneSecPeriodicRound
% 3 == 0)
910 AsicEvaluateRxAnt(pAd
);
915 #ifdef CONFIG_STA_SUPPORT
916 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
917 STAMlmePeriodicExec(pAd
);
918 #endif // CONFIG_STA_SUPPORT //
920 MlmeResetRalinkCounters(pAd
);
922 #ifdef CONFIG_STA_SUPPORT
923 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
926 // When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock
927 // and sending CTS-to-self over and over.
928 // Software Patch Solution:
929 // 1. Polling debug state register 0x10F4 every one second.
930 // 2. If in 0x10F4 the ((bit29==1) && (bit7==1)) OR ((bit29==1) && (bit5==1)), it means the deadlock has occurred.
931 // 3. If the deadlock occurred, reset MAC/BBP by setting 0x1004 to 0x0001 for a while then setting it back to 0x000C again.
935 RTMP_IO_READ32(pAd
, 0x10F4, &MacReg
);
936 if (((MacReg
& 0x20000000) && (MacReg
& 0x80)) || ((MacReg
& 0x20000000) && (MacReg
& 0x20)))
938 RTMP_IO_WRITE32(pAd
, MAC_SYS_CTRL
, 0x1);
940 RTMP_IO_WRITE32(pAd
, MAC_SYS_CTRL
, 0xC);
942 DBGPRINT(RT_DEBUG_WARN
,("Warning, MAC specific condition occurs \n"));
946 #endif // CONFIG_STA_SUPPORT //
948 RT28XX_MLME_HANDLER(pAd
);
952 pAd
->bUpdateBcnCntDone
= FALSE
;
955 #ifdef CONFIG_STA_SUPPORT
956 VOID
STAMlmePeriodicExec(
962 #ifdef WPA_SUPPLICANT_SUPPORT
963 if (pAd
->StaCfg
.WpaSupplicantUP
== WPA_SUPPLICANT_DISABLE
)
964 #endif // WPA_SUPPLICANT_SUPPORT //
966 // WPA MIC error should block association attempt for 60 seconds
967 if (pAd
->StaCfg
.bBlockAssoc
&& (pAd
->StaCfg
.LastMicErrorTime
+ (60 * OS_HZ
) < pAd
->Mlme
.Now32
))
968 pAd
->StaCfg
.bBlockAssoc
= FALSE
;
971 if ((pAd
->PreMediaState
!= pAd
->IndicateMediaState
) && (pAd
->CommonCfg
.bWirelessEvent
))
973 if (pAd
->IndicateMediaState
== NdisMediaStateConnected
)
975 RTMPSendWirelessEvent(pAd
, IW_STA_LINKUP_EVENT_FLAG
, pAd
->MacTab
.Content
[BSSID_WCID
].Addr
, BSS0
, 0);
977 pAd
->PreMediaState
= pAd
->IndicateMediaState
;
983 AsicStaBbpTuning(pAd
);
985 TxTotalCnt
= pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
+
986 pAd
->RalinkCounters
.OneSecTxRetryOkCount
+
987 pAd
->RalinkCounters
.OneSecTxFailCount
;
989 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
991 // update channel quality for Roaming and UI LinkQuality display
992 MlmeCalculateChannelQuality(pAd
, pAd
->Mlme
.Now32
);
995 // must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if
996 // Radio is currently in noisy environment
997 if (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS
))
998 AsicAdjustTxPower(pAd
);
1002 // Is PSM bit consistent with user power management policy?
1003 // This is the only place that will set PSM bit ON.
1004 if (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_DOZE
))
1005 MlmeCheckPsmChange(pAd
, pAd
->Mlme
.Now32
);
1007 pAd
->RalinkCounters
.LastOneSecTotalTxCount
= TxTotalCnt
;
1009 if ((pAd
->StaCfg
.LastBeaconRxTime
+ 1*OS_HZ
< pAd
->Mlme
.Now32
) &&
1010 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS
)) &&
1011 ((TxTotalCnt
+ pAd
->RalinkCounters
.OneSecRxOkCnt
< 600)))
1013 RTMPSetAGCInitValue(pAd
, BW_20
);
1014 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n", (0x2E + GET_LNA_GAIN(pAd
))));
1017 //if ((pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
1018 // (pAd->RalinkCounters.OneSecTxRetryOkCount == 0))
1020 if (pAd
->CommonCfg
.bAPSDCapable
&& pAd
->CommonCfg
.APEdcaParm
.bAPSDCapable
)
1022 // When APSD is enabled, the period changes as 20 sec
1023 if ((pAd
->Mlme
.OneSecPeriodicRound
% 20) == 8)
1024 RTMPSendNullFrame(pAd
, pAd
->CommonCfg
.TxRate
, TRUE
);
1028 // Send out a NULL frame every 10 sec to inform AP that STA is still alive (Avoid being age out)
1029 if ((pAd
->Mlme
.OneSecPeriodicRound
% 10) == 8)
1031 if (pAd
->CommonCfg
.bWmmCapable
)
1032 RTMPSendNullFrame(pAd
, pAd
->CommonCfg
.TxRate
, TRUE
);
1034 RTMPSendNullFrame(pAd
, pAd
->CommonCfg
.TxRate
, FALSE
);
1039 if (CQI_IS_DEAD(pAd
->Mlme
.ChannelQuality
))
1041 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n", pAd
->RalinkCounters
.BadCQIAutoRecoveryCount
));
1042 pAd
->StaCfg
.CCXAdjacentAPReportFlag
= TRUE
;
1043 pAd
->StaCfg
.CCXAdjacentAPLinkDownTime
= pAd
->StaCfg
.LastBeaconRxTime
;
1045 // Lost AP, send disconnect & link down event
1046 LinkDown(pAd
, FALSE
);
1048 #ifdef WPA_SUPPLICANT_SUPPORT
1049 #ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1050 if (pAd
->StaCfg
.WpaSupplicantUP
)
1052 union iwreq_data wrqu
;
1053 //send disassociate event to wpa_supplicant
1054 memset(&wrqu
, 0, sizeof(wrqu
));
1055 wrqu
.data
.flags
= RT_DISASSOC_EVENT_FLAG
;
1056 wireless_send_event(pAd
->net_dev
, IWEVCUSTOM
, &wrqu
, NULL
);
1058 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1059 #endif // WPA_SUPPLICANT_SUPPORT //
1061 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1063 union iwreq_data wrqu
;
1064 memset(wrqu
.ap_addr
.sa_data
, 0, MAC_ADDR_LEN
);
1065 wireless_send_event(pAd
->net_dev
, SIOCGIWAP
, &wrqu
, NULL
);
1067 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1069 // RTMPPatchMacBbpBug(pAd);
1070 MlmeAutoReconnectLastSSID(pAd
);
1072 else if (CQI_IS_BAD(pAd
->Mlme
.ChannelQuality
))
1074 pAd
->RalinkCounters
.BadCQIAutoRecoveryCount
++;
1075 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - Bad CQI. Auto Recovery attempt #%ld\n", pAd
->RalinkCounters
.BadCQIAutoRecoveryCount
));
1076 MlmeAutoReconnectLastSSID(pAd
);
1079 // Add auto seamless roaming
1080 if (pAd
->StaCfg
.bFastRoaming
)
1082 SHORT dBmToRoam
= (SHORT
)pAd
->StaCfg
.dBmToRoam
;
1084 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
));
1086 if (RTMPMaxRssi(pAd
, pAd
->StaCfg
.RssiSample
.LastRssi0
, pAd
->StaCfg
.RssiSample
.LastRssi1
, pAd
->StaCfg
.RssiSample
.LastRssi2
) <= (CHAR
)dBmToRoam
)
1088 MlmeCheckForFastRoaming(pAd
, pAd
->Mlme
.Now32
);
1092 else if (ADHOC_ON(pAd
))
1095 if ((pAd
->CommonCfg
.Channel
> 14)
1096 && (pAd
->CommonCfg
.bIEEE80211H
== 1)
1097 && RadarChannelCheck(pAd
, pAd
->CommonCfg
.Channel
))
1099 RadarDetectPeriodic(pAd
);
1102 // If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState
1103 // to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can
1105 if ((pAd
->StaCfg
.LastBeaconRxTime
+ ADHOC_BEACON_LOST_TIME
< pAd
->Mlme
.Now32
) &&
1106 OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
1108 MLME_START_REQ_STRUCT StartReq
;
1110 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n"));
1111 LinkDown(pAd
, FALSE
);
1113 StartParmFill(pAd
, &StartReq
, pAd
->MlmeAux
.Ssid
, pAd
->MlmeAux
.SsidLen
);
1114 MlmeEnqueue(pAd
, SYNC_STATE_MACHINE
, MT2_MLME_START_REQ
, sizeof(MLME_START_REQ_STRUCT
), &StartReq
);
1115 pAd
->Mlme
.CntlMachine
.CurrState
= CNTL_WAIT_START
;
1118 for (i
= 1; i
< MAX_LEN_OF_MAC_TABLE
; i
++)
1120 MAC_TABLE_ENTRY
*pEntry
= &pAd
->MacTab
.Content
[i
];
1122 if (pEntry
->ValidAsCLI
== FALSE
)
1125 if (pEntry
->LastBeaconRxTime
+ ADHOC_BEACON_LOST_TIME
< pAd
->Mlme
.Now32
)
1126 MacTableDeleteEntry(pAd
, pEntry
->Aid
, pEntry
->Addr
);
1129 else // no INFRA nor ADHOC connection
1132 if (pAd
->StaCfg
.bScanReqIsFromWebUI
&&
1133 ((pAd
->StaCfg
.LastScanTime
+ 30 * OS_HZ
) > pAd
->Mlme
.Now32
))
1134 goto SKIP_AUTO_SCAN_CONN
;
1136 pAd
->StaCfg
.bScanReqIsFromWebUI
= FALSE
;
1138 if ((pAd
->StaCfg
.bAutoReconnect
== TRUE
)
1139 && RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_START_UP
)
1140 && (MlmeValidateSSID(pAd
->MlmeAux
.AutoReconnectSsid
, pAd
->MlmeAux
.AutoReconnectSsidLen
) == TRUE
))
1142 if ((pAd
->ScanTab
.BssNr
==0) && (pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_IDLE
))
1144 MLME_SCAN_REQ_STRUCT ScanReq
;
1146 if ((pAd
->StaCfg
.LastScanTime
+ 10 * OS_HZ
) < pAd
->Mlme
.Now32
)
1148 DBGPRINT(RT_DEBUG_TRACE
, ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, start a new ACTIVE scan SSID[%s]\n", pAd
->MlmeAux
.AutoReconnectSsid
));
1149 ScanParmFill(pAd
, &ScanReq
, pAd
->MlmeAux
.AutoReconnectSsid
, pAd
->MlmeAux
.AutoReconnectSsidLen
, BSS_ANY
, SCAN_ACTIVE
);
1150 MlmeEnqueue(pAd
, SYNC_STATE_MACHINE
, MT2_MLME_SCAN_REQ
, sizeof(MLME_SCAN_REQ_STRUCT
), &ScanReq
);
1151 pAd
->Mlme
.CntlMachine
.CurrState
= CNTL_WAIT_OID_LIST_SCAN
;
1152 // Reset Missed scan number
1153 pAd
->StaCfg
.LastScanTime
= pAd
->Mlme
.Now32
;
1155 else if (pAd
->StaCfg
.BssType
== BSS_ADHOC
) // Quit the forever scan when in a very clean room
1156 MlmeAutoReconnectLastSSID(pAd
);
1158 else if (pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_IDLE
)
1160 if ((pAd
->Mlme
.OneSecPeriodicRound
% 7) == 0)
1163 pAd
->StaCfg
.LastScanTime
= pAd
->Mlme
.Now32
;
1167 MlmeAutoReconnectLastSSID(pAd
);
1173 SKIP_AUTO_SCAN_CONN
:
1175 #ifdef DOT11_N_SUPPORT
1176 if ((pAd
->MacTab
.Content
[BSSID_WCID
].TXBAbitmap
!=0) && (pAd
->MacTab
.fAnyBASession
== FALSE
))
1178 pAd
->MacTab
.fAnyBASession
= TRUE
;
1179 AsicUpdateProtect(pAd
, HT_FORCERTSCTS
, ALLN_SETPROTECT
, FALSE
, FALSE
);
1181 else if ((pAd
->MacTab
.Content
[BSSID_WCID
].TXBAbitmap
==0) && (pAd
->MacTab
.fAnyBASession
== TRUE
))
1183 pAd
->MacTab
.fAnyBASession
= FALSE
;
1184 AsicUpdateProtect(pAd
, pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
, ALLN_SETPROTECT
, FALSE
, FALSE
);
1186 #endif // DOT11_N_SUPPORT //
1193 IN PVOID SystemSpecific1
,
1194 IN PVOID FunctionContext
,
1195 IN PVOID SystemSpecific2
,
1196 IN PVOID SystemSpecific3
)
1199 RTMP_ADAPTER
*pAd
= (RTMP_ADAPTER
*)FunctionContext
;
1201 pAd
->IndicateMediaState
= NdisMediaStateDisconnected
;
1202 RTMP_IndicateMediaState(pAd
);
1203 pAd
->ExtraInfo
= GENERAL_LINK_DOWN
;
1206 // IRQL = DISPATCH_LEVEL
1208 IN PRTMP_ADAPTER pAd
)
1210 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1211 if (pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_IDLE
)
1213 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - Driver auto scan\n"));
1215 MLME_CNTL_STATE_MACHINE
,
1216 OID_802_11_BSSID_LIST_SCAN
,
1219 RT28XX_MLME_HANDLER(pAd
);
1223 // IRQL = DISPATCH_LEVEL
1224 VOID
MlmeAutoReconnectLastSSID(
1225 IN PRTMP_ADAPTER pAd
)
1229 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1230 if ((pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_IDLE
) &&
1231 (MlmeValidateSSID(pAd
->MlmeAux
.AutoReconnectSsid
, pAd
->MlmeAux
.AutoReconnectSsidLen
) == TRUE
))
1233 NDIS_802_11_SSID OidSsid
;
1234 OidSsid
.SsidLength
= pAd
->MlmeAux
.AutoReconnectSsidLen
;
1235 NdisMoveMemory(OidSsid
.Ssid
, pAd
->MlmeAux
.AutoReconnectSsid
, pAd
->MlmeAux
.AutoReconnectSsidLen
);
1237 DBGPRINT(RT_DEBUG_TRACE
, ("Driver auto reconnect to last OID_802_11_SSID setting - %s, len - %d\n", pAd
->MlmeAux
.AutoReconnectSsid
, pAd
->MlmeAux
.AutoReconnectSsidLen
));
1239 MLME_CNTL_STATE_MACHINE
,
1241 sizeof(NDIS_802_11_SSID
),
1243 RT28XX_MLME_HANDLER(pAd
);
1246 #endif // CONFIG_STA_SUPPORT //
1249 ==========================================================================
1250 Validate SSID for connection try and rescan purpose
1251 Valid SSID will have visible chars only.
1252 The valid length is from 0 to 32.
1253 IRQL = DISPATCH_LEVEL
1254 ==========================================================================
1256 BOOLEAN
MlmeValidateSSID(
1262 if (SsidLen
> MAX_LEN_OF_SSID
)
1265 // Check each character value
1266 for (index
= 0; index
< SsidLen
; index
++)
1268 if (pSsid
[index
] < 0x20)
1276 VOID
MlmeSelectTxRateTable(
1277 IN PRTMP_ADAPTER pAd
,
1278 IN PMAC_TABLE_ENTRY pEntry
,
1280 IN PUCHAR pTableSize
,
1281 IN PUCHAR pInitTxRateIdx
)
1285 // decide the rate table for tuning
1286 if (pAd
->CommonCfg
.TxRateTableSize
> 0)
1288 *ppTable
= RateSwitchTable
;
1289 *pTableSize
= RateSwitchTable
[0];
1290 *pInitTxRateIdx
= RateSwitchTable
[1];
1295 #ifdef CONFIG_STA_SUPPORT
1296 if ((pAd
->OpMode
== OPMODE_STA
) && ADHOC_ON(pAd
))
1298 #ifdef DOT11_N_SUPPORT
1299 if ((pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
) &&
1300 (pEntry
->HTCapability
.MCSSet
[0] == 0xff) &&
1301 ((pEntry
->HTCapability
.MCSSet
[1] == 0x00) || (pAd
->Antenna
.field
.TxPath
== 1)))
1303 *ppTable
= RateSwitchTable11N1S
;
1304 *pTableSize
= RateSwitchTable11N1S
[0];
1305 *pInitTxRateIdx
= RateSwitchTable11N1S
[1];
1308 else if ((pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
) &&
1309 (pEntry
->HTCapability
.MCSSet
[0] == 0xff) &&
1310 (pEntry
->HTCapability
.MCSSet
[1] == 0xff) &&
1311 (pAd
->Antenna
.field
.TxPath
== 2))
1313 if (pAd
->LatchRfRegs
.Channel
<= 14)
1315 *ppTable
= RateSwitchTable11N2S
;
1316 *pTableSize
= RateSwitchTable11N2S
[0];
1317 *pInitTxRateIdx
= RateSwitchTable11N2S
[1];
1321 *ppTable
= RateSwitchTable11N2SForABand
;
1322 *pTableSize
= RateSwitchTable11N2SForABand
[0];
1323 *pInitTxRateIdx
= RateSwitchTable11N2SForABand
[1];
1328 #endif // DOT11_N_SUPPORT //
1329 if ((pEntry
->RateLen
== 4)
1330 #ifdef DOT11_N_SUPPORT
1331 && (pEntry
->HTCapability
.MCSSet
[0] == 0) && (pEntry
->HTCapability
.MCSSet
[1] == 0)
1332 #endif // DOT11_N_SUPPORT //
1335 *ppTable
= RateSwitchTable11B
;
1336 *pTableSize
= RateSwitchTable11B
[0];
1337 *pInitTxRateIdx
= RateSwitchTable11B
[1];
1340 else if (pAd
->LatchRfRegs
.Channel
<= 14)
1342 *ppTable
= RateSwitchTable11BG
;
1343 *pTableSize
= RateSwitchTable11BG
[0];
1344 *pInitTxRateIdx
= RateSwitchTable11BG
[1];
1349 *ppTable
= RateSwitchTable11G
;
1350 *pTableSize
= RateSwitchTable11G
[0];
1351 *pInitTxRateIdx
= RateSwitchTable11G
[1];
1356 #endif // CONFIG_STA_SUPPORT //
1358 #ifdef DOT11_N_SUPPORT
1359 //if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
1360 // ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
1361 if ((pEntry
->RateLen
== 12) && (pEntry
->HTCapability
.MCSSet
[0] == 0xff) &&
1362 ((pEntry
->HTCapability
.MCSSet
[1] == 0x00) || (pAd
->CommonCfg
.TxStream
== 1)))
1364 *ppTable
= RateSwitchTable11BGN1S
;
1365 *pTableSize
= RateSwitchTable11BGN1S
[0];
1366 *pInitTxRateIdx
= RateSwitchTable11BGN1S
[1];
1371 //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
1372 // (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2))
1373 if ((pEntry
->RateLen
== 12) && (pEntry
->HTCapability
.MCSSet
[0] == 0xff) &&
1374 (pEntry
->HTCapability
.MCSSet
[1] == 0xff) && (pAd
->CommonCfg
.TxStream
== 2))
1376 if (pAd
->LatchRfRegs
.Channel
<= 14)
1378 *ppTable
= RateSwitchTable11BGN2S
;
1379 *pTableSize
= RateSwitchTable11BGN2S
[0];
1380 *pInitTxRateIdx
= RateSwitchTable11BGN2S
[1];
1385 *ppTable
= RateSwitchTable11BGN2SForABand
;
1386 *pTableSize
= RateSwitchTable11BGN2SForABand
[0];
1387 *pInitTxRateIdx
= RateSwitchTable11BGN2SForABand
[1];
1393 //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
1394 if ((pEntry
->HTCapability
.MCSSet
[0] == 0xff) && ((pEntry
->HTCapability
.MCSSet
[1] == 0x00) || (pAd
->CommonCfg
.TxStream
== 1)))
1396 *ppTable
= RateSwitchTable11N1S
;
1397 *pTableSize
= RateSwitchTable11N1S
[0];
1398 *pInitTxRateIdx
= RateSwitchTable11N1S
[1];
1403 //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2))
1404 if ((pEntry
->HTCapability
.MCSSet
[0] == 0xff) && (pEntry
->HTCapability
.MCSSet
[1] == 0xff) && (pAd
->CommonCfg
.TxStream
== 2))
1406 if (pAd
->LatchRfRegs
.Channel
<= 14)
1408 *ppTable
= RateSwitchTable11N2S
;
1409 *pTableSize
= RateSwitchTable11N2S
[0];
1410 *pInitTxRateIdx
= RateSwitchTable11N2S
[1];
1414 *ppTable
= RateSwitchTable11N2SForABand
;
1415 *pTableSize
= RateSwitchTable11N2SForABand
[0];
1416 *pInitTxRateIdx
= RateSwitchTable11N2SForABand
[1];
1421 #endif // DOT11_N_SUPPORT //
1422 //else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1423 if ((pEntry
->RateLen
== 4)
1424 #ifdef DOT11_N_SUPPORT
1425 && (pEntry
->HTCapability
.MCSSet
[0] == 0) && (pEntry
->HTCapability
.MCSSet
[1] == 0)
1426 #endif // DOT11_N_SUPPORT //
1429 *ppTable
= RateSwitchTable11B
;
1430 *pTableSize
= RateSwitchTable11B
[0];
1431 *pInitTxRateIdx
= RateSwitchTable11B
[1];
1436 //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1437 if ((pEntry
->RateLen
> 8)
1438 #ifdef DOT11_N_SUPPORT
1439 && (pEntry
->HTCapability
.MCSSet
[0] == 0) && (pEntry
->HTCapability
.MCSSet
[1] == 0)
1440 #endif // DOT11_N_SUPPORT //
1443 *ppTable
= RateSwitchTable11BG
;
1444 *pTableSize
= RateSwitchTable11BG
[0];
1445 *pInitTxRateIdx
= RateSwitchTable11BG
[1];
1450 //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1451 if ((pEntry
->RateLen
== 8)
1452 #ifdef DOT11_N_SUPPORT
1453 && (pEntry
->HTCapability
.MCSSet
[0] == 0) && (pEntry
->HTCapability
.MCSSet
[1] == 0)
1454 #endif // DOT11_N_SUPPORT //
1457 *ppTable
= RateSwitchTable11G
;
1458 *pTableSize
= RateSwitchTable11G
[0];
1459 *pInitTxRateIdx
= RateSwitchTable11G
[1];
1463 #ifdef DOT11_N_SUPPORT
1464 #endif // DOT11_N_SUPPORT //
1466 #ifdef CONFIG_STA_SUPPORT
1467 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
1469 #ifdef DOT11_N_SUPPORT
1470 //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1471 if ((pEntry
->HTCapability
.MCSSet
[0] == 0) && (pEntry
->HTCapability
.MCSSet
[1] == 0))
1472 #endif // DOT11_N_SUPPORT //
1474 if (pAd
->CommonCfg
.MaxTxRate
<= RATE_11
)
1476 *ppTable
= RateSwitchTable11B
;
1477 *pTableSize
= RateSwitchTable11B
[0];
1478 *pInitTxRateIdx
= RateSwitchTable11B
[1];
1480 else if ((pAd
->CommonCfg
.MaxTxRate
> RATE_11
) && (pAd
->CommonCfg
.MinTxRate
> RATE_11
))
1482 *ppTable
= RateSwitchTable11G
;
1483 *pTableSize
= RateSwitchTable11G
[0];
1484 *pInitTxRateIdx
= RateSwitchTable11G
[1];
1489 *ppTable
= RateSwitchTable11BG
;
1490 *pTableSize
= RateSwitchTable11BG
[0];
1491 *pInitTxRateIdx
= RateSwitchTable11BG
[1];
1495 #ifdef DOT11_N_SUPPORT
1496 if (pAd
->LatchRfRegs
.Channel
<= 14)
1498 if (pAd
->CommonCfg
.TxStream
== 1)
1500 *ppTable
= RateSwitchTable11N1S
;
1501 *pTableSize
= RateSwitchTable11N1S
[0];
1502 *pInitTxRateIdx
= RateSwitchTable11N1S
[1];
1503 DBGPRINT_RAW(RT_DEBUG_ERROR
,("DRS: unkown mode,default use 11N 1S AP \n"));
1507 *ppTable
= RateSwitchTable11N2S
;
1508 *pTableSize
= RateSwitchTable11N2S
[0];
1509 *pInitTxRateIdx
= RateSwitchTable11N2S
[1];
1510 DBGPRINT_RAW(RT_DEBUG_ERROR
,("DRS: unkown mode,default use 11N 2S AP \n"));
1515 if (pAd
->CommonCfg
.TxStream
== 1)
1517 *ppTable
= RateSwitchTable11N1S
;
1518 *pTableSize
= RateSwitchTable11N1S
[0];
1519 *pInitTxRateIdx
= RateSwitchTable11N1S
[1];
1520 DBGPRINT_RAW(RT_DEBUG_ERROR
,("DRS: unkown mode,default use 11N 1S AP \n"));
1524 *ppTable
= RateSwitchTable11N2SForABand
;
1525 *pTableSize
= RateSwitchTable11N2SForABand
[0];
1526 *pInitTxRateIdx
= RateSwitchTable11N2SForABand
[1];
1527 DBGPRINT_RAW(RT_DEBUG_ERROR
,("DRS: unkown mode,default use 11N 2S AP \n"));
1530 #endif // DOT11_N_SUPPORT //
1531 DBGPRINT_RAW(RT_DEBUG_ERROR
,("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n",
1532 pAd
->StaActive
.SupRateLen
, pAd
->StaActive
.ExtRateLen
, pAd
->StaActive
.SupportedPhyInfo
.MCSSet
[0], pAd
->StaActive
.SupportedPhyInfo
.MCSSet
[1]));
1534 #endif // CONFIG_STA_SUPPORT //
1538 #ifdef CONFIG_STA_SUPPORT
1540 ==========================================================================
1542 This routine checks if there're other APs out there capable for
1543 roaming. Caller should call this routine only when Link up in INFRA mode
1544 and channel quality is below CQI_GOOD_THRESHOLD.
1546 IRQL = DISPATCH_LEVEL
1549 ==========================================================================
1551 VOID
MlmeCheckForRoaming(
1552 IN PRTMP_ADAPTER pAd
,
1556 BSS_TABLE
*pRoamTab
= &pAd
->MlmeAux
.RoamTab
;
1559 DBGPRINT(RT_DEBUG_TRACE
, ("==> MlmeCheckForRoaming\n"));
1560 // put all roaming candidates into RoamTab, and sort in RSSI order
1561 BssTableInit(pRoamTab
);
1562 for (i
= 0; i
< pAd
->ScanTab
.BssNr
; i
++)
1564 pBss
= &pAd
->ScanTab
.BssEntry
[i
];
1566 if ((pBss
->LastBeaconRxTime
+ BEACON_LOST_TIME
) < Now32
)
1567 continue; // AP disappear
1568 if (pBss
->Rssi
<= RSSI_THRESHOLD_FOR_ROAMING
)
1569 continue; // RSSI too weak. forget it.
1570 if (MAC_ADDR_EQUAL(pBss
->Bssid
, pAd
->CommonCfg
.Bssid
))
1571 continue; // skip current AP
1572 if (pBss
->Rssi
< (pAd
->StaCfg
.RssiSample
.LastRssi0
+ RSSI_DELTA
))
1573 continue; // only AP with stronger RSSI is eligible for roaming
1575 // AP passing all above rules is put into roaming candidate table
1576 NdisMoveMemory(&pRoamTab
->BssEntry
[pRoamTab
->BssNr
], pBss
, sizeof(BSS_ENTRY
));
1577 pRoamTab
->BssNr
+= 1;
1580 if (pRoamTab
->BssNr
> 0)
1582 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1583 if (pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_IDLE
)
1585 pAd
->RalinkCounters
.PoorCQIRoamingCount
++;
1586 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - Roaming attempt #%ld\n", pAd
->RalinkCounters
.PoorCQIRoamingCount
));
1587 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_MLME_ROAMING_REQ
, 0, NULL
);
1588 RT28XX_MLME_HANDLER(pAd
);
1591 DBGPRINT(RT_DEBUG_TRACE
, ("<== MlmeCheckForRoaming(# of candidate= %d)\n",pRoamTab
->BssNr
));
1595 ==========================================================================
1597 This routine checks if there're other APs out there capable for
1598 roaming. Caller should call this routine only when link up in INFRA mode
1599 and channel quality is below CQI_GOOD_THRESHOLD.
1601 IRQL = DISPATCH_LEVEL
1604 ==========================================================================
1606 VOID
MlmeCheckForFastRoaming(
1607 IN PRTMP_ADAPTER pAd
,
1611 BSS_TABLE
*pRoamTab
= &pAd
->MlmeAux
.RoamTab
;
1614 DBGPRINT(RT_DEBUG_TRACE
, ("==> MlmeCheckForFastRoaming\n"));
1615 // put all roaming candidates into RoamTab, and sort in RSSI order
1616 BssTableInit(pRoamTab
);
1617 for (i
= 0; i
< pAd
->ScanTab
.BssNr
; i
++)
1619 pBss
= &pAd
->ScanTab
.BssEntry
[i
];
1621 if ((pBss
->Rssi
<= -50) && (pBss
->Channel
== pAd
->CommonCfg
.Channel
))
1622 continue; // RSSI too weak. forget it.
1623 if (MAC_ADDR_EQUAL(pBss
->Bssid
, pAd
->CommonCfg
.Bssid
))
1624 continue; // skip current AP
1625 if (!SSID_EQUAL(pBss
->Ssid
, pBss
->SsidLen
, pAd
->CommonCfg
.Ssid
, pAd
->CommonCfg
.SsidLen
))
1626 continue; // skip different SSID
1627 if (pBss
->Rssi
< (RTMPMaxRssi(pAd
, pAd
->StaCfg
.RssiSample
.LastRssi0
, pAd
->StaCfg
.RssiSample
.LastRssi1
, pAd
->StaCfg
.RssiSample
.LastRssi2
) + RSSI_DELTA
))
1628 continue; // skip AP without better RSSI
1630 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
));
1631 // AP passing all above rules is put into roaming candidate table
1632 NdisMoveMemory(&pRoamTab
->BssEntry
[pRoamTab
->BssNr
], pBss
, sizeof(BSS_ENTRY
));
1633 pRoamTab
->BssNr
+= 1;
1636 if (pRoamTab
->BssNr
> 0)
1638 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1639 if (pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_IDLE
)
1641 pAd
->RalinkCounters
.PoorCQIRoamingCount
++;
1642 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - Roaming attempt #%ld\n", pAd
->RalinkCounters
.PoorCQIRoamingCount
));
1643 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_MLME_ROAMING_REQ
, 0, NULL
);
1644 RT28XX_MLME_HANDLER(pAd
);
1647 // Maybe site survey required
1650 if ((pAd
->StaCfg
.LastScanTime
+ 10 * 1000) < Now
)
1652 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1653 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - Roaming, No eligable entry, try new scan!\n"));
1654 pAd
->StaCfg
.ScanCnt
= 2;
1655 pAd
->StaCfg
.LastScanTime
= Now
;
1660 DBGPRINT(RT_DEBUG_TRACE
, ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab
->BssNr
));
1664 ==========================================================================
1666 This routine calculates TxPER, RxPER of the past N-sec period. And
1667 according to the calculation result, ChannelQuality is calculated here
1668 to decide if current AP is still doing the job.
1670 If ChannelQuality is not good, a ROAMing attempt may be tried later.
1672 StaCfg.ChannelQuality - 0..100
1674 IRQL = DISPATCH_LEVEL
1676 NOTE: This routine decide channle quality based on RX CRC error ratio.
1677 Caller should make sure a function call to NICUpdateRawCounters(pAd)
1678 is performed right before this routine, so that this routine can decide
1679 channel quality based on the most up-to-date information
1680 ==========================================================================
1682 VOID
MlmeCalculateChannelQuality(
1683 IN PRTMP_ADAPTER pAd
,
1686 ULONG TxOkCnt
, TxCnt
, TxPER
, TxPRR
;
1690 ULONG BeaconLostTime
= BEACON_LOST_TIME
;
1692 MaxRssi
= RTMPMaxRssi(pAd
, pAd
->StaCfg
.RssiSample
.LastRssi0
, pAd
->StaCfg
.RssiSample
.LastRssi1
, pAd
->StaCfg
.RssiSample
.LastRssi2
);
1695 // calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics
1697 TxOkCnt
= pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
+ pAd
->RalinkCounters
.OneSecTxRetryOkCount
;
1698 TxCnt
= TxOkCnt
+ pAd
->RalinkCounters
.OneSecTxFailCount
;
1706 TxPER
= (pAd
->RalinkCounters
.OneSecTxFailCount
* 100) / TxCnt
;
1707 TxPRR
= ((TxCnt
- pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
) * 100) / TxCnt
;
1711 // calculate RX PER - don't take RxPER into consideration if too few sample
1713 RxCnt
= pAd
->RalinkCounters
.OneSecRxOkCnt
+ pAd
->RalinkCounters
.OneSecRxFcsErrCnt
;
1717 RxPER
= (pAd
->RalinkCounters
.OneSecRxFcsErrCnt
* 100) / RxCnt
;
1720 // decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER
1722 if (INFRA_ON(pAd
) &&
1723 (pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
< 2) && // no heavy traffic
1724 (pAd
->StaCfg
.LastBeaconRxTime
+ BeaconLostTime
< Now32
))
1726 DBGPRINT(RT_DEBUG_TRACE
, ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n", BeaconLostTime
, TxOkCnt
));
1727 pAd
->Mlme
.ChannelQuality
= 0;
1734 else if (MaxRssi
< -90)
1737 NorRssi
= (MaxRssi
+ 90) * 2;
1739 // ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER (RSSI 0..100), (TxPER 100..0), (RxPER 100..0)
1740 pAd
->Mlme
.ChannelQuality
= (RSSI_WEIGHTING
* NorRssi
+
1741 TX_WEIGHTING
* (100 - TxPRR
) +
1742 RX_WEIGHTING
* (100 - RxPER
)) / 100;
1743 if (pAd
->Mlme
.ChannelQuality
>= 100)
1744 pAd
->Mlme
.ChannelQuality
= 100;
1750 IN PRTMP_ADAPTER pAd
,
1751 IN PMAC_TABLE_ENTRY pEntry
,
1752 IN PRTMP_TX_RATE_SWITCH pTxRate
)
1754 UCHAR MaxMode
= MODE_OFDM
;
1756 #ifdef DOT11_N_SUPPORT
1757 MaxMode
= MODE_HTGREENFIELD
;
1759 if (pTxRate
->STBC
&& (pAd
->StaCfg
.MaxHTPhyMode
.field
.STBC
) && (pAd
->Antenna
.field
.TxPath
== 2))
1760 pAd
->StaCfg
.HTPhyMode
.field
.STBC
= STBC_USE
;
1762 #endif // DOT11_N_SUPPORT //
1763 pAd
->StaCfg
.HTPhyMode
.field
.STBC
= STBC_NONE
;
1765 if (pTxRate
->CurrMCS
< MCS_AUTO
)
1766 pAd
->StaCfg
.HTPhyMode
.field
.MCS
= pTxRate
->CurrMCS
;
1768 if (pAd
->StaCfg
.HTPhyMode
.field
.MCS
> 7)
1769 pAd
->StaCfg
.HTPhyMode
.field
.STBC
= STBC_NONE
;
1773 // If peer adhoc is b-only mode, we can't send 11g rate.
1774 pAd
->StaCfg
.HTPhyMode
.field
.ShortGI
= GI_800
;
1775 pEntry
->HTPhyMode
.field
.STBC
= STBC_NONE
;
1778 // For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary
1780 pEntry
->HTPhyMode
.field
.MODE
= pTxRate
->Mode
;
1781 pEntry
->HTPhyMode
.field
.ShortGI
= pAd
->StaCfg
.HTPhyMode
.field
.ShortGI
;
1782 pEntry
->HTPhyMode
.field
.MCS
= pAd
->StaCfg
.HTPhyMode
.field
.MCS
;
1784 // Patch speed error in status page
1785 pAd
->StaCfg
.HTPhyMode
.field
.MODE
= pEntry
->HTPhyMode
.field
.MODE
;
1789 if (pTxRate
->Mode
<= MaxMode
)
1790 pAd
->StaCfg
.HTPhyMode
.field
.MODE
= pTxRate
->Mode
;
1792 #ifdef DOT11_N_SUPPORT
1793 if (pTxRate
->ShortGI
&& (pAd
->StaCfg
.MaxHTPhyMode
.field
.ShortGI
))
1794 pAd
->StaCfg
.HTPhyMode
.field
.ShortGI
= GI_400
;
1796 #endif // DOT11_N_SUPPORT //
1797 pAd
->StaCfg
.HTPhyMode
.field
.ShortGI
= GI_800
;
1799 #ifdef DOT11_N_SUPPORT
1800 // Reexam each bandwidth's SGI support.
1801 if (pAd
->StaCfg
.HTPhyMode
.field
.ShortGI
== GI_400
)
1803 if ((pEntry
->HTPhyMode
.field
.BW
== BW_20
) && (!CLIENT_STATUS_TEST_FLAG(pEntry
, fCLIENT_STATUS_SGI20_CAPABLE
)))
1804 pAd
->StaCfg
.HTPhyMode
.field
.ShortGI
= GI_800
;
1805 if ((pEntry
->HTPhyMode
.field
.BW
== BW_40
) && (!CLIENT_STATUS_TEST_FLAG(pEntry
, fCLIENT_STATUS_SGI40_CAPABLE
)))
1806 pAd
->StaCfg
.HTPhyMode
.field
.ShortGI
= GI_800
;
1809 // Turn RTS/CTS rate to 6Mbps.
1810 if ((pEntry
->HTPhyMode
.field
.MCS
== 0) && (pAd
->StaCfg
.HTPhyMode
.field
.MCS
!= 0))
1812 pEntry
->HTPhyMode
.field
.MCS
= pAd
->StaCfg
.HTPhyMode
.field
.MCS
;
1813 if (pAd
->MacTab
.fAnyBASession
)
1815 AsicUpdateProtect(pAd
, HT_FORCERTSCTS
, ALLN_SETPROTECT
, TRUE
, (BOOLEAN
)pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
);
1819 AsicUpdateProtect(pAd
, pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
, ALLN_SETPROTECT
, TRUE
, (BOOLEAN
)pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
);
1822 else if ((pEntry
->HTPhyMode
.field
.MCS
== 8) && (pAd
->StaCfg
.HTPhyMode
.field
.MCS
!= 8))
1824 pEntry
->HTPhyMode
.field
.MCS
= pAd
->StaCfg
.HTPhyMode
.field
.MCS
;
1825 if (pAd
->MacTab
.fAnyBASession
)
1827 AsicUpdateProtect(pAd
, HT_FORCERTSCTS
, ALLN_SETPROTECT
, TRUE
, (BOOLEAN
)pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
);
1831 AsicUpdateProtect(pAd
, pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
, ALLN_SETPROTECT
, TRUE
, (BOOLEAN
)pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
);
1834 else if ((pEntry
->HTPhyMode
.field
.MCS
!= 0) && (pAd
->StaCfg
.HTPhyMode
.field
.MCS
== 0))
1836 AsicUpdateProtect(pAd
, HT_RTSCTS_6M
, ALLN_SETPROTECT
, TRUE
, (BOOLEAN
)pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
);
1839 else if ((pEntry
->HTPhyMode
.field
.MCS
!= 8) && (pAd
->StaCfg
.HTPhyMode
.field
.MCS
== 8))
1841 AsicUpdateProtect(pAd
, HT_RTSCTS_6M
, ALLN_SETPROTECT
, TRUE
, (BOOLEAN
)pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
);
1843 #endif // DOT11_N_SUPPORT //
1845 pEntry
->HTPhyMode
.field
.STBC
= pAd
->StaCfg
.HTPhyMode
.field
.STBC
;
1846 pEntry
->HTPhyMode
.field
.ShortGI
= pAd
->StaCfg
.HTPhyMode
.field
.ShortGI
;
1847 pEntry
->HTPhyMode
.field
.MCS
= pAd
->StaCfg
.HTPhyMode
.field
.MCS
;
1848 pEntry
->HTPhyMode
.field
.MODE
= pAd
->StaCfg
.HTPhyMode
.field
.MODE
;
1849 #ifdef DOT11_N_SUPPORT
1850 if ((pAd
->StaCfg
.MaxHTPhyMode
.field
.MODE
== MODE_HTGREENFIELD
) &&
1851 pAd
->WIFItestbed
.bGreenField
)
1852 pEntry
->HTPhyMode
.field
.MODE
= MODE_HTGREENFIELD
;
1853 #endif // DOT11_N_SUPPORT //
1856 pAd
->LastTxRate
= (USHORT
)(pEntry
->HTPhyMode
.word
);
1860 ==========================================================================
1862 This routine calculates the acumulated TxPER of eaxh TxRate. And
1863 according to the calculation result, change CommonCfg.TxRate which
1864 is the stable TX Rate we expect the Radio situation could sustained.
1866 CommonCfg.TxRate will change dynamically within {RATE_1/RATE_6, MaxTxRate}
1870 IRQL = DISPATCH_LEVEL
1873 call this routine every second
1874 ==========================================================================
1876 VOID
MlmeDynamicTxRateSwitching(
1877 IN PRTMP_ADAPTER pAd
)
1879 UCHAR UpRateIdx
= 0, DownRateIdx
= 0, CurrRateIdx
;
1880 ULONG i
, AccuTxTotalCnt
= 0, TxTotalCnt
;
1881 ULONG TxErrorRatio
= 0;
1882 BOOLEAN bTxRateChanged
, bUpgradeQuality
= FALSE
;
1883 PRTMP_TX_RATE_SWITCH pCurrTxRate
, pNextTxRate
= NULL
;
1885 UCHAR TableSize
= 0;
1886 UCHAR InitTxRateIdx
= 0, TrainUp
, TrainDown
;
1887 CHAR Rssi
, RssiOffset
= 0;
1888 TX_STA_CNT1_STRUC StaTx1
;
1889 TX_STA_CNT0_STRUC TxStaCnt0
;
1890 ULONG TxRetransmit
= 0, TxSuccess
= 0, TxFailCount
= 0;
1891 MAC_TABLE_ENTRY
*pEntry
;
1894 // walk through MAC table, see if need to change AP's TX rate toward each entry
1896 for (i
= 1; i
< MAX_LEN_OF_MAC_TABLE
; i
++)
1898 pEntry
= &pAd
->MacTab
.Content
[i
];
1900 // check if this entry need to switch rate automatically
1901 if (RTMPCheckEntryEnableAutoRateSwitch(pAd
, pEntry
) == FALSE
)
1904 if ((pAd
->MacTab
.Size
== 1) || (pEntry
->ValidAsDls
))
1906 Rssi
= RTMPMaxRssi(pAd
,
1907 pAd
->StaCfg
.RssiSample
.AvgRssi0
,
1908 pAd
->StaCfg
.RssiSample
.AvgRssi1
,
1909 pAd
->StaCfg
.RssiSample
.AvgRssi2
);
1911 // Update statistic counter
1912 RTMP_IO_READ32(pAd
, TX_STA_CNT0
, &TxStaCnt0
.word
);
1913 RTMP_IO_READ32(pAd
, TX_STA_CNT1
, &StaTx1
.word
);
1914 pAd
->bUpdateBcnCntDone
= TRUE
;
1915 TxRetransmit
= StaTx1
.field
.TxRetransmit
;
1916 TxSuccess
= StaTx1
.field
.TxSuccess
;
1917 TxFailCount
= TxStaCnt0
.field
.TxFailCount
;
1918 TxTotalCnt
= TxRetransmit
+ TxSuccess
+ TxFailCount
;
1920 pAd
->RalinkCounters
.OneSecTxRetryOkCount
+= StaTx1
.field
.TxRetransmit
;
1921 pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
+= StaTx1
.field
.TxSuccess
;
1922 pAd
->RalinkCounters
.OneSecTxFailCount
+= TxStaCnt0
.field
.TxFailCount
;
1923 pAd
->WlanCounters
.TransmittedFragmentCount
.u
.LowPart
+= StaTx1
.field
.TxSuccess
;
1924 pAd
->WlanCounters
.RetryCount
.u
.LowPart
+= StaTx1
.field
.TxRetransmit
;
1925 pAd
->WlanCounters
.FailedCount
.u
.LowPart
+= TxStaCnt0
.field
.TxFailCount
;
1927 // if no traffic in the past 1-sec period, don't change TX rate,
1928 // but clear all bad history. because the bad history may affect the next
1929 // Chariot throughput test
1930 AccuTxTotalCnt
= pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
+
1931 pAd
->RalinkCounters
.OneSecTxRetryOkCount
+
1932 pAd
->RalinkCounters
.OneSecTxFailCount
;
1935 TxErrorRatio
= ((TxRetransmit
+ TxFailCount
) * 100) / TxTotalCnt
;
1939 if (INFRA_ON(pAd
) && (i
== 1))
1940 Rssi
= RTMPMaxRssi(pAd
,
1941 pAd
->StaCfg
.RssiSample
.AvgRssi0
,
1942 pAd
->StaCfg
.RssiSample
.AvgRssi1
,
1943 pAd
->StaCfg
.RssiSample
.AvgRssi2
);
1945 Rssi
= RTMPMaxRssi(pAd
,
1946 pEntry
->RssiSample
.AvgRssi0
,
1947 pEntry
->RssiSample
.AvgRssi1
,
1948 pEntry
->RssiSample
.AvgRssi2
);
1950 TxTotalCnt
= pEntry
->OneSecTxNoRetryOkCount
+
1951 pEntry
->OneSecTxRetryOkCount
+
1952 pEntry
->OneSecTxFailCount
;
1955 TxErrorRatio
= ((pEntry
->OneSecTxRetryOkCount
+ pEntry
->OneSecTxFailCount
) * 100) / TxTotalCnt
;
1958 CurrRateIdx
= pEntry
->CurrTxRateIndex
;
1960 MlmeSelectTxRateTable(pAd
, pEntry
, &pTable
, &TableSize
, &InitTxRateIdx
);
1962 if (CurrRateIdx
>= TableSize
)
1964 CurrRateIdx
= TableSize
- 1;
1967 // When switch from Fixed rate -> auto rate, the REAL TX rate might be different from pAd->CommonCfg.TxRateIndex.
1968 // So need to sync here.
1969 pCurrTxRate
= (PRTMP_TX_RATE_SWITCH
) &pTable
[(CurrRateIdx
+1)*5];
1970 if ((pEntry
->HTPhyMode
.field
.MCS
!= pCurrTxRate
->CurrMCS
)
1971 //&& (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
1975 // Need to sync Real Tx rate and our record.
1976 // Then return for next DRS.
1977 pCurrTxRate
= (PRTMP_TX_RATE_SWITCH
) &pTable
[(InitTxRateIdx
+1)*5];
1978 pEntry
->CurrTxRateIndex
= InitTxRateIdx
;
1979 MlmeSetTxRate(pAd
, pEntry
, pCurrTxRate
);
1981 // reset all OneSecTx counters
1982 RESET_ONE_SEC_TX_CNT(pEntry
);
1986 // decide the next upgrade rate and downgrade rate, if any
1987 if ((CurrRateIdx
> 0) && (CurrRateIdx
< (TableSize
- 1)))
1989 UpRateIdx
= CurrRateIdx
+ 1;
1990 DownRateIdx
= CurrRateIdx
-1;
1992 else if (CurrRateIdx
== 0)
1994 UpRateIdx
= CurrRateIdx
+ 1;
1995 DownRateIdx
= CurrRateIdx
;
1997 else if (CurrRateIdx
== (TableSize
- 1))
1999 UpRateIdx
= CurrRateIdx
;
2000 DownRateIdx
= CurrRateIdx
- 1;
2003 pCurrTxRate
= (PRTMP_TX_RATE_SWITCH
) &pTable
[(CurrRateIdx
+1)*5];
2005 #ifdef DOT11_N_SUPPORT
2006 if ((Rssi
> -65) && (pCurrTxRate
->Mode
>= MODE_HTMIX
))
2008 TrainUp
= (pCurrTxRate
->TrainUp
+ (pCurrTxRate
->TrainUp
>> 1));
2009 TrainDown
= (pCurrTxRate
->TrainDown
+ (pCurrTxRate
->TrainDown
>> 1));
2012 #endif // DOT11_N_SUPPORT //
2014 TrainUp
= pCurrTxRate
->TrainUp
;
2015 TrainDown
= pCurrTxRate
->TrainDown
;
2018 //pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction;
2021 // Keep the last time TxRateChangeAction status.
2023 pEntry
->LastTimeTxRateChangeAction
= pEntry
->LastSecTxRateChangeAction
;
2028 // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
2029 // (criteria copied from RT2500 for Netopia case)
2031 if (TxTotalCnt
<= 15)
2035 //UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS7 = 0, MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
2036 UCHAR MCS0
= 0, MCS1
= 0, MCS2
= 0, MCS3
= 0, MCS4
= 0, MCS5
=0, MCS6
= 0, MCS7
= 0;
2037 UCHAR MCS12
= 0, MCS13
= 0, MCS14
= 0, MCS15
= 0;
2038 UCHAR MCS20
= 0, MCS21
= 0, MCS22
= 0, MCS23
= 0; // 3*3
2040 // check the existence and index of each needed MCS
2041 while (idx
< pTable
[0])
2043 pCurrTxRate
= (PRTMP_TX_RATE_SWITCH
) &pTable
[(idx
+1)*5];
2045 if (pCurrTxRate
->CurrMCS
== MCS_0
)
2049 else if (pCurrTxRate
->CurrMCS
== MCS_1
)
2053 else if (pCurrTxRate
->CurrMCS
== MCS_2
)
2057 else if (pCurrTxRate
->CurrMCS
== MCS_3
)
2061 else if (pCurrTxRate
->CurrMCS
== MCS_4
)
2065 else if (pCurrTxRate
->CurrMCS
== MCS_5
)
2069 else if (pCurrTxRate
->CurrMCS
== MCS_6
)
2073 //else if (pCurrTxRate->CurrMCS == MCS_7)
2074 else if ((pCurrTxRate
->CurrMCS
== MCS_7
) && (pCurrTxRate
->ShortGI
== GI_800
)) // prevent the highest MCS using short GI when 1T and low throughput
2078 else if (pCurrTxRate
->CurrMCS
== MCS_12
)
2082 else if (pCurrTxRate
->CurrMCS
== MCS_13
)
2086 else if (pCurrTxRate
->CurrMCS
== MCS_14
)
2090 //else if ((pCurrTxRate->CurrMCS == MCS_15)/* && (pCurrTxRate->ShortGI == GI_800)*/) //we hope to use ShortGI as initial rate
2091 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
2095 else if (pCurrTxRate
->CurrMCS
== MCS_20
) // 3*3
2099 else if (pCurrTxRate
->CurrMCS
== MCS_21
)
2103 else if (pCurrTxRate
->CurrMCS
== MCS_22
)
2107 else if (pCurrTxRate
->CurrMCS
== MCS_23
)
2114 if (pAd
->LatchRfRegs
.Channel
<= 14)
2116 if (pAd
->NicConfig2
.field
.ExternalLNAForG
)
2127 if (pAd
->NicConfig2
.field
.ExternalLNAForA
)
2136 #ifdef DOT11_N_SUPPORT
2138 if ((pTable
== RateSwitchTable11BGN3S
) ||
2139 (pTable
== RateSwitchTable11N3S
) ||
2140 (pTable
== RateSwitchTable
))
2141 {// N mode with 3 stream // 3*3
2142 if (MCS23
&& (Rssi
>= -70))
2144 else if (MCS22
&& (Rssi
>= -72))
2146 else if (MCS21
&& (Rssi
>= -76))
2148 else if (MCS20
&& (Rssi
>= -78))
2150 else if (MCS4
&& (Rssi
>= -82))
2152 else if (MCS3
&& (Rssi
>= -84))
2154 else if (MCS2
&& (Rssi
>= -86))
2156 else if (MCS1
&& (Rssi
>= -88))
2161 // else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand) || (pTable == RateSwitchTable))
2162 else if ((pTable
== RateSwitchTable11BGN2S
) || (pTable
== RateSwitchTable11BGN2SForABand
) ||(pTable
== RateSwitchTable11N2S
) ||(pTable
== RateSwitchTable11N2SForABand
)) // 3*3
2163 {// N mode with 2 stream
2164 if (MCS15
&& (Rssi
>= (-70+RssiOffset
)))
2166 else if (MCS14
&& (Rssi
>= (-72+RssiOffset
)))
2168 else if (MCS13
&& (Rssi
>= (-76+RssiOffset
)))
2170 else if (MCS12
&& (Rssi
>= (-78+RssiOffset
)))
2172 else if (MCS4
&& (Rssi
>= (-82+RssiOffset
)))
2174 else if (MCS3
&& (Rssi
>= (-84+RssiOffset
)))
2176 else if (MCS2
&& (Rssi
>= (-86+RssiOffset
)))
2178 else if (MCS1
&& (Rssi
>= (-88+RssiOffset
)))
2183 else if ((pTable
== RateSwitchTable11BGN1S
) || (pTable
== RateSwitchTable11N1S
))
2184 {// N mode with 1 stream
2185 if (MCS7
&& (Rssi
> (-72+RssiOffset
)))
2187 else if (MCS6
&& (Rssi
> (-74+RssiOffset
)))
2189 else if (MCS5
&& (Rssi
> (-77+RssiOffset
)))
2191 else if (MCS4
&& (Rssi
> (-79+RssiOffset
)))
2193 else if (MCS3
&& (Rssi
> (-81+RssiOffset
)))
2195 else if (MCS2
&& (Rssi
> (-83+RssiOffset
)))
2197 else if (MCS1
&& (Rssi
> (-86+RssiOffset
)))
2203 #endif // DOT11_N_SUPPORT //
2205 if (MCS7
&& (Rssi
> -70))
2207 else if (MCS6
&& (Rssi
> -74))
2209 else if (MCS5
&& (Rssi
> -78))
2211 else if (MCS4
&& (Rssi
> -82))
2213 else if (MCS4
== 0) // for B-only mode
2215 else if (MCS3
&& (Rssi
> -85))
2217 else if (MCS2
&& (Rssi
> -87))
2219 else if (MCS1
&& (Rssi
> -90))
2225 // if (TxRateIdx != pAd->CommonCfg.TxRateIndex)
2227 pEntry
->CurrTxRateIndex
= TxRateIdx
;
2228 pNextTxRate
= (PRTMP_TX_RATE_SWITCH
) &pTable
[(pEntry
->CurrTxRateIndex
+1)*5];
2229 MlmeSetTxRate(pAd
, pEntry
, pNextTxRate
);
2232 NdisZeroMemory(pEntry
->TxQuality
, sizeof(USHORT
) * MAX_STEP_OF_TX_RATE_SWITCH
);
2233 NdisZeroMemory(pEntry
->PER
, sizeof(UCHAR
) * MAX_STEP_OF_TX_RATE_SWITCH
);
2234 pEntry
->fLastSecAccordingRSSI
= TRUE
;
2235 // reset all OneSecTx counters
2236 RESET_ONE_SEC_TX_CNT(pEntry
);
2241 if (pEntry
->fLastSecAccordingRSSI
== TRUE
)
2243 pEntry
->fLastSecAccordingRSSI
= FALSE
;
2244 pEntry
->LastSecTxRateChangeAction
= 0;
2245 // reset all OneSecTx counters
2246 RESET_ONE_SEC_TX_CNT(pEntry
);
2253 BOOLEAN bTrainUpDown
= FALSE
;
2255 pEntry
->CurrTxRateStableTime
++;
2257 // downgrade TX quality if PER >= Rate-Down threshold
2258 if (TxErrorRatio
>= TrainDown
)
2260 bTrainUpDown
= TRUE
;
2261 pEntry
->TxQuality
[CurrRateIdx
] = DRS_TX_QUALITY_WORST_BOUND
;
2263 // upgrade TX quality if PER <= Rate-Up threshold
2264 else if (TxErrorRatio
<= TrainUp
)
2266 bTrainUpDown
= TRUE
;
2267 bUpgradeQuality
= TRUE
;
2268 if (pEntry
->TxQuality
[CurrRateIdx
])
2269 pEntry
->TxQuality
[CurrRateIdx
] --; // quality very good in CurrRate
2271 if (pEntry
->TxRateUpPenalty
)
2272 pEntry
->TxRateUpPenalty
--;
2273 else if (pEntry
->TxQuality
[UpRateIdx
])
2274 pEntry
->TxQuality
[UpRateIdx
] --; // may improve next UP rate's quality
2277 pEntry
->PER
[CurrRateIdx
] = (UCHAR
)TxErrorRatio
;
2281 // perform DRS - consider TxRate Down first, then rate up.
2282 if ((CurrRateIdx
!= DownRateIdx
) && (pEntry
->TxQuality
[CurrRateIdx
] >= DRS_TX_QUALITY_WORST_BOUND
))
2284 pEntry
->CurrTxRateIndex
= DownRateIdx
;
2286 else if ((CurrRateIdx
!= UpRateIdx
) && (pEntry
->TxQuality
[UpRateIdx
] <= 0))
2288 pEntry
->CurrTxRateIndex
= UpRateIdx
;
2293 // if rate-up happen, clear all bad history of all TX rates
2294 if (pEntry
->CurrTxRateIndex
> CurrRateIdx
)
2296 pEntry
->CurrTxRateStableTime
= 0;
2297 pEntry
->TxRateUpPenalty
= 0;
2298 pEntry
->LastSecTxRateChangeAction
= 1; // rate UP
2299 NdisZeroMemory(pEntry
->TxQuality
, sizeof(USHORT
) * MAX_STEP_OF_TX_RATE_SWITCH
);
2300 NdisZeroMemory(pEntry
->PER
, sizeof(UCHAR
) * MAX_STEP_OF_TX_RATE_SWITCH
);
2303 // For TxRate fast train up
2305 if (!pAd
->StaCfg
.StaQuickResponeForRateUpTimerRunning
)
2307 RTMPSetTimer(&pAd
->StaCfg
.StaQuickResponeForRateUpTimer
, 100);
2309 pAd
->StaCfg
.StaQuickResponeForRateUpTimerRunning
= TRUE
;
2311 bTxRateChanged
= TRUE
;
2313 // if rate-down happen, only clear DownRate's bad history
2314 else if (pEntry
->CurrTxRateIndex
< CurrRateIdx
)
2316 pEntry
->CurrTxRateStableTime
= 0;
2317 pEntry
->TxRateUpPenalty
= 0; // no penalty
2318 pEntry
->LastSecTxRateChangeAction
= 2; // rate DOWN
2319 pEntry
->TxQuality
[pEntry
->CurrTxRateIndex
] = 0;
2320 pEntry
->PER
[pEntry
->CurrTxRateIndex
] = 0;
2323 // For TxRate fast train down
2325 if (!pAd
->StaCfg
.StaQuickResponeForRateUpTimerRunning
)
2327 RTMPSetTimer(&pAd
->StaCfg
.StaQuickResponeForRateUpTimer
, 100);
2329 pAd
->StaCfg
.StaQuickResponeForRateUpTimerRunning
= TRUE
;
2331 bTxRateChanged
= TRUE
;
2335 pEntry
->LastSecTxRateChangeAction
= 0; // rate no change
2336 bTxRateChanged
= FALSE
;
2339 pEntry
->LastTxOkCount
= TxSuccess
;
2341 // reset all OneSecTx counters
2342 RESET_ONE_SEC_TX_CNT(pEntry
);
2344 pNextTxRate
= (PRTMP_TX_RATE_SWITCH
) &pTable
[(pEntry
->CurrTxRateIndex
+1)*5];
2345 if (bTxRateChanged
&& pNextTxRate
)
2347 MlmeSetTxRate(pAd
, pEntry
, pNextTxRate
);
2353 ========================================================================
2354 Routine Description:
2355 Station side, Auto TxRate faster train up timer call back function.
2358 SystemSpecific1 - Not used.
2359 FunctionContext - Pointer to our Adapter context.
2360 SystemSpecific2 - Not used.
2361 SystemSpecific3 - Not used.
2366 ========================================================================
2368 VOID
StaQuickResponeForRateUpExec(
2369 IN PVOID SystemSpecific1
,
2370 IN PVOID FunctionContext
,
2371 IN PVOID SystemSpecific2
,
2372 IN PVOID SystemSpecific3
)
2374 PRTMP_ADAPTER pAd
= (PRTMP_ADAPTER
)FunctionContext
;
2375 UCHAR UpRateIdx
= 0, DownRateIdx
= 0, CurrRateIdx
= 0;
2377 ULONG TxErrorRatio
= 0;
2378 BOOLEAN bTxRateChanged
; //, bUpgradeQuality = FALSE;
2379 PRTMP_TX_RATE_SWITCH pCurrTxRate
, pNextTxRate
= NULL
;
2381 UCHAR TableSize
= 0;
2382 UCHAR InitTxRateIdx
= 0, TrainUp
, TrainDown
;
2383 TX_STA_CNT1_STRUC StaTx1
;
2384 TX_STA_CNT0_STRUC TxStaCnt0
;
2386 ULONG TxRetransmit
= 0, TxSuccess
= 0, TxFailCount
= 0;
2387 MAC_TABLE_ENTRY
*pEntry
;
2390 pAd
->StaCfg
.StaQuickResponeForRateUpTimerRunning
= FALSE
;
2393 // walk through MAC table, see if need to change AP's TX rate toward each entry
2395 for (i
= 1; i
< MAX_LEN_OF_MAC_TABLE
; i
++)
2397 pEntry
= &pAd
->MacTab
.Content
[i
];
2399 // check if this entry need to switch rate automatically
2400 if (RTMPCheckEntryEnableAutoRateSwitch(pAd
, pEntry
) == FALSE
)
2403 if (INFRA_ON(pAd
) && (i
== 1))
2404 Rssi
= RTMPMaxRssi(pAd
,
2405 pAd
->StaCfg
.RssiSample
.AvgRssi0
,
2406 pAd
->StaCfg
.RssiSample
.AvgRssi1
,
2407 pAd
->StaCfg
.RssiSample
.AvgRssi2
);
2409 Rssi
= RTMPMaxRssi(pAd
,
2410 pEntry
->RssiSample
.AvgRssi0
,
2411 pEntry
->RssiSample
.AvgRssi1
,
2412 pEntry
->RssiSample
.AvgRssi2
);
2414 CurrRateIdx
= pAd
->CommonCfg
.TxRateIndex
;
2416 MlmeSelectTxRateTable(pAd
, pEntry
, &pTable
, &TableSize
, &InitTxRateIdx
);
2418 // decide the next upgrade rate and downgrade rate, if any
2419 if ((CurrRateIdx
> 0) && (CurrRateIdx
< (TableSize
- 1)))
2421 UpRateIdx
= CurrRateIdx
+ 1;
2422 DownRateIdx
= CurrRateIdx
-1;
2424 else if (CurrRateIdx
== 0)
2426 UpRateIdx
= CurrRateIdx
+ 1;
2427 DownRateIdx
= CurrRateIdx
;
2429 else if (CurrRateIdx
== (TableSize
- 1))
2431 UpRateIdx
= CurrRateIdx
;
2432 DownRateIdx
= CurrRateIdx
- 1;
2435 pCurrTxRate
= (PRTMP_TX_RATE_SWITCH
) &pTable
[(CurrRateIdx
+1)*5];
2437 #ifdef DOT11_N_SUPPORT
2438 if ((Rssi
> -65) && (pCurrTxRate
->Mode
>= MODE_HTMIX
))
2440 TrainUp
= (pCurrTxRate
->TrainUp
+ (pCurrTxRate
->TrainUp
>> 1));
2441 TrainDown
= (pCurrTxRate
->TrainDown
+ (pCurrTxRate
->TrainDown
>> 1));
2444 #endif // DOT11_N_SUPPORT //
2446 TrainUp
= pCurrTxRate
->TrainUp
;
2447 TrainDown
= pCurrTxRate
->TrainDown
;
2450 if (pAd
->MacTab
.Size
== 1)
2452 // Update statistic counter
2453 RTMP_IO_READ32(pAd
, TX_STA_CNT0
, &TxStaCnt0
.word
);
2454 RTMP_IO_READ32(pAd
, TX_STA_CNT1
, &StaTx1
.word
);
2456 TxRetransmit
= StaTx1
.field
.TxRetransmit
;
2457 TxSuccess
= StaTx1
.field
.TxSuccess
;
2458 TxFailCount
= TxStaCnt0
.field
.TxFailCount
;
2459 TxTotalCnt
= TxRetransmit
+ TxSuccess
+ TxFailCount
;
2461 pAd
->RalinkCounters
.OneSecTxRetryOkCount
+= StaTx1
.field
.TxRetransmit
;
2462 pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
+= StaTx1
.field
.TxSuccess
;
2463 pAd
->RalinkCounters
.OneSecTxFailCount
+= TxStaCnt0
.field
.TxFailCount
;
2464 pAd
->WlanCounters
.TransmittedFragmentCount
.u
.LowPart
+= StaTx1
.field
.TxSuccess
;
2465 pAd
->WlanCounters
.RetryCount
.u
.LowPart
+= StaTx1
.field
.TxRetransmit
;
2466 pAd
->WlanCounters
.FailedCount
.u
.LowPart
+= TxStaCnt0
.field
.TxFailCount
;
2468 #if 0 // test by Gary.
2469 // if no traffic in the past 1-sec period, don't change TX rate,
2470 // but clear all bad history. because the bad history may affect the next
2471 // Chariot throughput test
2472 TxTotalCnt
= pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
+
2473 pAd
->RalinkCounters
.OneSecTxRetryOkCount
+
2474 pAd
->RalinkCounters
.OneSecTxFailCount
;
2477 TxErrorRatio
= ((TxRetransmit
+ TxFailCount
) * 100) / TxTotalCnt
;
2481 TxTotalCnt
= pEntry
->OneSecTxNoRetryOkCount
+
2482 pEntry
->OneSecTxRetryOkCount
+
2483 pEntry
->OneSecTxFailCount
;
2486 TxErrorRatio
= ((pEntry
->OneSecTxRetryOkCount
+ pEntry
->OneSecTxFailCount
) * 100) / TxTotalCnt
;
2491 // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
2492 // (criteria copied from RT2500 for Netopia case)
2494 if (TxTotalCnt
<= 12)
2496 NdisZeroMemory(pAd
->DrsCounters
.TxQuality
, sizeof(USHORT
) * MAX_STEP_OF_TX_RATE_SWITCH
);
2497 NdisZeroMemory(pAd
->DrsCounters
.PER
, sizeof(UCHAR
) * MAX_STEP_OF_TX_RATE_SWITCH
);
2499 if ((pAd
->DrsCounters
.LastSecTxRateChangeAction
== 1) && (CurrRateIdx
!= DownRateIdx
))
2501 pAd
->CommonCfg
.TxRateIndex
= DownRateIdx
;
2502 pAd
->DrsCounters
.TxQuality
[CurrRateIdx
] = DRS_TX_QUALITY_WORST_BOUND
;
2504 else if ((pAd
->DrsCounters
.LastSecTxRateChangeAction
== 2) && (CurrRateIdx
!= UpRateIdx
))
2506 pAd
->CommonCfg
.TxRateIndex
= UpRateIdx
;
2509 DBGPRINT_RAW(RT_DEBUG_TRACE
,("QuickDRS: TxTotalCnt <= 15, train back to original rate \n"));
2515 ULONG OneSecTxNoRetryOKRationCount
;
2517 if (pAd
->DrsCounters
.LastTimeTxRateChangeAction
== 0)
2522 // downgrade TX quality if PER >= Rate-Down threshold
2523 if (TxErrorRatio
>= TrainDown
)
2525 pAd
->DrsCounters
.TxQuality
[CurrRateIdx
] = DRS_TX_QUALITY_WORST_BOUND
;
2528 pAd
->DrsCounters
.PER
[CurrRateIdx
] = (UCHAR
)TxErrorRatio
;
2530 OneSecTxNoRetryOKRationCount
= (TxSuccess
* ratio
);
2532 // perform DRS - consider TxRate Down first, then rate up.
2533 if ((pAd
->DrsCounters
.LastSecTxRateChangeAction
== 1) && (CurrRateIdx
!= DownRateIdx
))
2535 if ((pAd
->DrsCounters
.LastTxOkCount
+ 2) >= OneSecTxNoRetryOKRationCount
)
2537 pAd
->CommonCfg
.TxRateIndex
= DownRateIdx
;
2538 pAd
->DrsCounters
.TxQuality
[CurrRateIdx
] = DRS_TX_QUALITY_WORST_BOUND
;
2543 else if ((pAd
->DrsCounters
.LastSecTxRateChangeAction
== 2) && (CurrRateIdx
!= UpRateIdx
))
2545 if ((TxErrorRatio
>= 50) || (TxErrorRatio
>= TrainDown
))
2549 else if ((pAd
->DrsCounters
.LastTxOkCount
+ 2) >= OneSecTxNoRetryOKRationCount
)
2551 pAd
->CommonCfg
.TxRateIndex
= UpRateIdx
;
2556 // if rate-up happen, clear all bad history of all TX rates
2557 if (pAd
->CommonCfg
.TxRateIndex
> CurrRateIdx
)
2559 pAd
->DrsCounters
.TxRateUpPenalty
= 0;
2560 NdisZeroMemory(pAd
->DrsCounters
.TxQuality
, sizeof(USHORT
) * MAX_STEP_OF_TX_RATE_SWITCH
);
2561 NdisZeroMemory(pAd
->DrsCounters
.PER
, sizeof(UCHAR
) * MAX_STEP_OF_TX_RATE_SWITCH
);
2562 bTxRateChanged
= TRUE
;
2564 // if rate-down happen, only clear DownRate's bad history
2565 else if (pAd
->CommonCfg
.TxRateIndex
< CurrRateIdx
)
2567 DBGPRINT_RAW(RT_DEBUG_TRACE
,("QuickDRS: --TX rate from %d to %d \n", CurrRateIdx
, pAd
->CommonCfg
.TxRateIndex
));
2569 pAd
->DrsCounters
.TxRateUpPenalty
= 0; // no penalty
2570 pAd
->DrsCounters
.TxQuality
[pAd
->CommonCfg
.TxRateIndex
] = 0;
2571 pAd
->DrsCounters
.PER
[pAd
->CommonCfg
.TxRateIndex
] = 0;
2572 bTxRateChanged
= TRUE
;
2576 bTxRateChanged
= FALSE
;
2579 pNextTxRate
= (PRTMP_TX_RATE_SWITCH
) &pTable
[(pAd
->CommonCfg
.TxRateIndex
+1)*5];
2580 if (bTxRateChanged
&& pNextTxRate
)
2582 MlmeSetTxRate(pAd
, pEntry
, pNextTxRate
);
2588 ==========================================================================
2590 This routine is executed periodically inside MlmePeriodicExec() after
2591 association with an AP.
2592 It checks if StaCfg.Psm is consistent with user policy (recorded in
2593 StaCfg.WindowsPowerMode). If not, enforce user policy. However,
2594 there're some conditions to consider:
2595 1. we don't support power-saving in ADHOC mode, so Psm=PWR_ACTIVE all
2596 the time when Mibss==TRUE
2597 2. When link up in INFRA mode, Psm should not be switch to PWR_SAVE
2598 if outgoing traffic available in TxRing or MgmtRing.
2600 1. change pAd->StaCfg.Psm to PWR_SAVE or leave it untouched
2602 IRQL = DISPATCH_LEVEL
2604 ==========================================================================
2606 VOID
MlmeCheckPsmChange(
2607 IN PRTMP_ADAPTER pAd
,
2613 // 1. Psm maybe ON only happen in INFRASTRUCTURE mode
2614 // 2. user wants either MAX_PSP or FAST_PSP
2615 // 3. but current psm is not in PWR_SAVE
2616 // 4. CNTL state machine is not doing SCANning
2617 // 5. no TX SUCCESS event for the past 1-sec period
2618 #ifdef NDIS51_MINIPORT
2619 if (pAd
->StaCfg
.WindowsPowerProfile
== NdisPowerProfileBattery
)
2620 PowerMode
= pAd
->StaCfg
.WindowsBatteryPowerMode
;
2623 PowerMode
= pAd
->StaCfg
.WindowsPowerMode
;
2625 if (INFRA_ON(pAd
) &&
2626 (PowerMode
!= Ndis802_11PowerModeCAM
) &&
2627 (pAd
->StaCfg
.Psm
== PWR_ACTIVE
) &&
2628 // (! RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
2629 (pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_IDLE
) /*&&
2630 (pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
2631 (pAd->RalinkCounters.OneSecTxRetryOkCount == 0)*/)
2633 NdisGetSystemUpTime(&pAd
->Mlme
.LastSendNULLpsmTime
);
2634 pAd
->RalinkCounters
.RxCountSinceLastNULL
= 0;
2635 MlmeSetPsmBit(pAd
, PWR_SAVE
);
2636 if (!(pAd
->CommonCfg
.bAPSDCapable
&& pAd
->CommonCfg
.APEdcaParm
.bAPSDCapable
))
2638 RTMPSendNullFrame(pAd
, pAd
->CommonCfg
.TxRate
, FALSE
);
2642 RTMPSendNullFrame(pAd
, pAd
->CommonCfg
.TxRate
, TRUE
);
2647 // IRQL = PASSIVE_LEVEL
2648 // IRQL = DISPATCH_LEVEL
2650 IN PRTMP_ADAPTER pAd
,
2653 AUTO_RSP_CFG_STRUC csr4
;
2655 pAd
->StaCfg
.Psm
= psm
;
2656 RTMP_IO_READ32(pAd
, AUTO_RSP_CFG
, &csr4
.word
);
2657 csr4
.field
.AckCtsPsmBit
= (psm
== PWR_SAVE
)? 1:0;
2658 RTMP_IO_WRITE32(pAd
, AUTO_RSP_CFG
, csr4
.word
);
2659 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeSetPsmBit = %d\n", psm
));
2661 #endif // CONFIG_STA_SUPPORT //
2664 // IRQL = DISPATCH_LEVEL
2665 VOID
MlmeSetTxPreamble(
2666 IN PRTMP_ADAPTER pAd
,
2667 IN USHORT TxPreamble
)
2669 AUTO_RSP_CFG_STRUC csr4
;
2672 // Always use Long preamble before verifiation short preamble functionality works well.
2673 // Todo: remove the following line if short preamble functionality works
2675 //TxPreamble = Rt802_11PreambleLong;
2677 RTMP_IO_READ32(pAd
, AUTO_RSP_CFG
, &csr4
.word
);
2678 if (TxPreamble
== Rt802_11PreambleLong
)
2680 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeSetTxPreamble (= LONG PREAMBLE)\n"));
2681 OPSTATUS_CLEAR_FLAG(pAd
, fOP_STATUS_SHORT_PREAMBLE_INUSED
);
2682 csr4
.field
.AutoResponderPreamble
= 0;
2686 // NOTE: 1Mbps should always use long preamble
2687 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeSetTxPreamble (= SHORT PREAMBLE)\n"));
2688 OPSTATUS_SET_FLAG(pAd
, fOP_STATUS_SHORT_PREAMBLE_INUSED
);
2689 csr4
.field
.AutoResponderPreamble
= 1;
2692 RTMP_IO_WRITE32(pAd
, AUTO_RSP_CFG
, csr4
.word
);
2696 ==========================================================================
2698 Update basic rate bitmap
2699 ==========================================================================
2702 VOID
UpdateBasicRateBitmap(
2703 IN PRTMP_ADAPTER pAdapter
)
2706 /* 1 2 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */
2707 UCHAR rate
[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
2708 UCHAR
*sup_p
= pAdapter
->CommonCfg
.SupRate
;
2709 UCHAR
*ext_p
= pAdapter
->CommonCfg
.ExtRate
;
2710 ULONG bitmap
= pAdapter
->CommonCfg
.BasicRateBitmap
;
2713 /* if A mode, always use fix BasicRateBitMap */
2714 //if (pAdapter->CommonCfg.Channel == PHY_11A)
2715 if (pAdapter
->CommonCfg
.Channel
> 14)
2716 pAdapter
->CommonCfg
.BasicRateBitmap
= 0x150; /* 6, 12, 24M */
2719 if (pAdapter
->CommonCfg
.BasicRateBitmap
> 4095)
2721 /* (2 ^ MAX_LEN_OF_SUPPORTED_RATES) -1 */
2725 for(i
=0; i
<MAX_LEN_OF_SUPPORTED_RATES
; i
++)
2731 for(i
=0; i
<MAX_LEN_OF_SUPPORTED_RATES
; i
++)
2733 if (bitmap
& (1 << i
))
2735 for(j
=0; j
<MAX_LEN_OF_SUPPORTED_RATES
; j
++)
2737 if (sup_p
[j
] == rate
[i
])
2742 for(j
=0; j
<MAX_LEN_OF_SUPPORTED_RATES
; j
++)
2744 if (ext_p
[j
] == rate
[i
])
2750 } /* End of UpdateBasicRateBitmap */
2752 // IRQL = PASSIVE_LEVEL
2753 // IRQL = DISPATCH_LEVEL
2754 // bLinkUp is to identify the inital link speed.
2755 // TRUE indicates the rate update at linkup, we should not try to set the rate at 54Mbps.
2756 VOID
MlmeUpdateTxRates(
2757 IN PRTMP_ADAPTER pAd
,
2762 UCHAR Rate
= RATE_6
, MaxDesire
= RATE_1
, MaxSupport
= RATE_1
;
2763 UCHAR MinSupport
= RATE_54
;
2764 ULONG BasicRateBitmap
= 0;
2765 UCHAR CurrBasicRate
= RATE_1
;
2766 UCHAR
*pSupRate
, SupRateLen
, *pExtRate
, ExtRateLen
;
2767 PHTTRANSMIT_SETTING pHtPhy
= NULL
;
2768 PHTTRANSMIT_SETTING pMaxHtPhy
= NULL
;
2769 PHTTRANSMIT_SETTING pMinHtPhy
= NULL
;
2770 BOOLEAN
*auto_rate_cur_p
;
2771 UCHAR HtMcs
= MCS_AUTO
;
2773 // find max desired rate
2774 UpdateBasicRateBitmap(pAd
);
2777 auto_rate_cur_p
= NULL
;
2778 for (i
=0; i
<MAX_LEN_OF_SUPPORTED_RATES
; i
++)
2780 switch (pAd
->CommonCfg
.DesireRate
[i
] & 0x7f)
2782 case 2: Rate
= RATE_1
; num
++; break;
2783 case 4: Rate
= RATE_2
; num
++; break;
2784 case 11: Rate
= RATE_5_5
; num
++; break;
2785 case 22: Rate
= RATE_11
; num
++; break;
2786 case 12: Rate
= RATE_6
; num
++; break;
2787 case 18: Rate
= RATE_9
; num
++; break;
2788 case 24: Rate
= RATE_12
; num
++; break;
2789 case 36: Rate
= RATE_18
; num
++; break;
2790 case 48: Rate
= RATE_24
; num
++; break;
2791 case 72: Rate
= RATE_36
; num
++; break;
2792 case 96: Rate
= RATE_48
; num
++; break;
2793 case 108: Rate
= RATE_54
; num
++; break;
2794 //default: Rate = RATE_1; break;
2796 if (MaxDesire
< Rate
) MaxDesire
= Rate
;
2799 //===========================================================================
2800 //===========================================================================
2802 #ifdef CONFIG_STA_SUPPORT
2803 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
2805 pHtPhy
= &pAd
->StaCfg
.HTPhyMode
;
2806 pMaxHtPhy
= &pAd
->StaCfg
.MaxHTPhyMode
;
2807 pMinHtPhy
= &pAd
->StaCfg
.MinHTPhyMode
;
2809 auto_rate_cur_p
= &pAd
->StaCfg
.bAutoTxRateSwitch
;
2810 HtMcs
= pAd
->StaCfg
.DesiredTransmitSetting
.field
.MCS
;
2812 if ((pAd
->StaCfg
.BssType
== BSS_ADHOC
) &&
2813 (pAd
->CommonCfg
.PhyMode
== PHY_11B
) &&
2814 (MaxDesire
> RATE_11
))
2816 MaxDesire
= RATE_11
;
2819 #endif // CONFIG_STA_SUPPORT //
2821 pAd
->CommonCfg
.MaxDesiredRate
= MaxDesire
;
2822 pMinHtPhy
->word
= 0;
2823 pMaxHtPhy
->word
= 0;
2826 // Auto rate switching is enabled only if more than one DESIRED RATES are
2827 // specified; otherwise disabled
2830 //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
2831 //pAd->CommonCfg.bAutoTxRateSwitch = FALSE;
2832 *auto_rate_cur_p
= FALSE
;
2836 //OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
2837 //pAd->CommonCfg.bAutoTxRateSwitch = TRUE;
2838 *auto_rate_cur_p
= TRUE
;
2842 if (HtMcs
!= MCS_AUTO
)
2844 //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
2845 //pAd->CommonCfg.bAutoTxRateSwitch = FALSE;
2846 *auto_rate_cur_p
= FALSE
;
2850 //OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
2851 //pAd->CommonCfg.bAutoTxRateSwitch = TRUE;
2852 *auto_rate_cur_p
= TRUE
;
2856 #ifdef CONFIG_STA_SUPPORT
2857 if ((ADHOC_ON(pAd
) || INFRA_ON(pAd
)) && (pAd
->OpMode
== OPMODE_STA
))
2859 pSupRate
= &pAd
->StaActive
.SupRate
[0];
2860 pExtRate
= &pAd
->StaActive
.ExtRate
[0];
2861 SupRateLen
= pAd
->StaActive
.SupRateLen
;
2862 ExtRateLen
= pAd
->StaActive
.ExtRateLen
;
2865 #endif // CONFIG_STA_SUPPORT //
2867 pSupRate
= &pAd
->CommonCfg
.SupRate
[0];
2868 pExtRate
= &pAd
->CommonCfg
.ExtRate
[0];
2869 SupRateLen
= pAd
->CommonCfg
.SupRateLen
;
2870 ExtRateLen
= pAd
->CommonCfg
.ExtRateLen
;
2873 // find max supported rate
2874 for (i
=0; i
<SupRateLen
; i
++)
2876 switch (pSupRate
[i
] & 0x7f)
2878 case 2: Rate
= RATE_1
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0001; break;
2879 case 4: Rate
= RATE_2
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0002; break;
2880 case 11: Rate
= RATE_5_5
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0004; break;
2881 case 22: Rate
= RATE_11
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0008; break;
2882 case 12: Rate
= RATE_6
; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap
|= 0x0010; break;
2883 case 18: Rate
= RATE_9
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0020; break;
2884 case 24: Rate
= RATE_12
; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap
|= 0x0040; break;
2885 case 36: Rate
= RATE_18
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0080; break;
2886 case 48: Rate
= RATE_24
; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap
|= 0x0100; break;
2887 case 72: Rate
= RATE_36
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0200; break;
2888 case 96: Rate
= RATE_48
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0400; break;
2889 case 108: Rate
= RATE_54
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0800; break;
2890 default: Rate
= RATE_1
; break;
2892 if (MaxSupport
< Rate
) MaxSupport
= Rate
;
2894 if (MinSupport
> Rate
) MinSupport
= Rate
;
2897 for (i
=0; i
<ExtRateLen
; i
++)
2899 switch (pExtRate
[i
] & 0x7f)
2901 case 2: Rate
= RATE_1
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0001; break;
2902 case 4: Rate
= RATE_2
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0002; break;
2903 case 11: Rate
= RATE_5_5
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0004; break;
2904 case 22: Rate
= RATE_11
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0008; break;
2905 case 12: Rate
= RATE_6
; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap
|= 0x0010; break;
2906 case 18: Rate
= RATE_9
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0020; break;
2907 case 24: Rate
= RATE_12
; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap
|= 0x0040; break;
2908 case 36: Rate
= RATE_18
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0080; break;
2909 case 48: Rate
= RATE_24
; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap
|= 0x0100; break;
2910 case 72: Rate
= RATE_36
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0200; break;
2911 case 96: Rate
= RATE_48
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0400; break;
2912 case 108: Rate
= RATE_54
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0800; break;
2913 default: Rate
= RATE_1
; break;
2915 if (MaxSupport
< Rate
) MaxSupport
= Rate
;
2917 if (MinSupport
> Rate
) MinSupport
= Rate
;
2920 RTMP_IO_WRITE32(pAd
, LEGACY_BASIC_RATE
, BasicRateBitmap
);
2923 // pAd->CommonCfg.BasicRateBitmap = BasicRateBitmap;
2925 // calculate the exptected ACK rate for each TX rate. This info is used to caculate
2926 // the DURATION field of outgoing uniicast DATA/MGMT frame
2927 for (i
=0; i
<MAX_LEN_OF_SUPPORTED_RATES
; i
++)
2929 if (BasicRateBitmap
& (0x01 << i
))
2930 CurrBasicRate
= (UCHAR
)i
;
2931 pAd
->CommonCfg
.ExpectedACKRate
[i
] = CurrBasicRate
;
2934 DBGPRINT(RT_DEBUG_TRACE
,("MlmeUpdateTxRates[MaxSupport = %d] = MaxDesire %d Mbps\n", RateIdToMbps
[MaxSupport
], RateIdToMbps
[MaxDesire
]));
2935 // max tx rate = min {max desire rate, max supported rate}
2936 if (MaxSupport
< MaxDesire
)
2937 pAd
->CommonCfg
.MaxTxRate
= MaxSupport
;
2939 pAd
->CommonCfg
.MaxTxRate
= MaxDesire
;
2941 pAd
->CommonCfg
.MinTxRate
= MinSupport
;
2942 // 2003-07-31 john - 2500 doesn't have good sensitivity at high OFDM rates. to increase the success
2943 // ratio of initial DHCP packet exchange, TX rate starts from a lower rate depending
2945 // 1. RSSI >= -70db, start at 54 Mbps (short distance)
2946 // 2. -70 > RSSI >= -75, start at 24 Mbps (mid distance)
2947 // 3. -75 > RSSI, start at 11 Mbps (long distance)
2948 //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)/* &&
2949 // OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)*/)
2950 if (*auto_rate_cur_p
)
2953 #ifdef CONFIG_STA_SUPPORT
2954 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
2955 dbm
= pAd
->StaCfg
.RssiSample
.AvgRssi0
- pAd
->BbpRssiToDbmDelta
;
2956 #endif // CONFIG_STA_SUPPORT //
2957 if (bLinkUp
== TRUE
)
2958 pAd
->CommonCfg
.TxRate
= RATE_24
;
2960 pAd
->CommonCfg
.TxRate
= pAd
->CommonCfg
.MaxTxRate
;
2963 pAd
->CommonCfg
.TxRate
= RATE_11
;
2965 pAd
->CommonCfg
.TxRate
= RATE_24
;
2967 // should never exceed MaxTxRate (consider 11B-only mode)
2968 if (pAd
->CommonCfg
.TxRate
> pAd
->CommonCfg
.MaxTxRate
)
2969 pAd
->CommonCfg
.TxRate
= pAd
->CommonCfg
.MaxTxRate
;
2971 pAd
->CommonCfg
.TxRateIndex
= 0;
2975 pAd
->CommonCfg
.TxRate
= pAd
->CommonCfg
.MaxTxRate
;
2976 pHtPhy
->field
.MCS
= (pAd
->CommonCfg
.MaxTxRate
> 3) ? (pAd
->CommonCfg
.MaxTxRate
- 4) : pAd
->CommonCfg
.MaxTxRate
;
2977 pHtPhy
->field
.MODE
= (pAd
->CommonCfg
.MaxTxRate
> 3) ? MODE_OFDM
: MODE_CCK
;
2979 pAd
->MacTab
.Content
[BSSID_WCID
].HTPhyMode
.field
.STBC
= pHtPhy
->field
.STBC
;
2980 pAd
->MacTab
.Content
[BSSID_WCID
].HTPhyMode
.field
.ShortGI
= pHtPhy
->field
.ShortGI
;
2981 pAd
->MacTab
.Content
[BSSID_WCID
].HTPhyMode
.field
.MCS
= pHtPhy
->field
.MCS
;
2982 pAd
->MacTab
.Content
[BSSID_WCID
].HTPhyMode
.field
.MODE
= pHtPhy
->field
.MODE
;
2985 if (pAd
->CommonCfg
.TxRate
<= RATE_11
)
2987 pMaxHtPhy
->field
.MODE
= MODE_CCK
;
2988 pMaxHtPhy
->field
.MCS
= pAd
->CommonCfg
.TxRate
;
2989 pMinHtPhy
->field
.MCS
= pAd
->CommonCfg
.MinTxRate
;
2993 pMaxHtPhy
->field
.MODE
= MODE_OFDM
;
2994 pMaxHtPhy
->field
.MCS
= OfdmRateToRxwiMCS
[pAd
->CommonCfg
.TxRate
];
2995 if (pAd
->CommonCfg
.MinTxRate
>= RATE_6
&& (pAd
->CommonCfg
.MinTxRate
<= RATE_54
))
2996 {pMinHtPhy
->field
.MCS
= OfdmRateToRxwiMCS
[pAd
->CommonCfg
.MinTxRate
];}
2998 {pMinHtPhy
->field
.MCS
= pAd
->CommonCfg
.MinTxRate
;}
3001 pHtPhy
->word
= (pMaxHtPhy
->word
);
3002 if (bLinkUp
&& (pAd
->OpMode
== OPMODE_STA
))
3004 pAd
->MacTab
.Content
[BSSID_WCID
].HTPhyMode
.word
= pHtPhy
->word
;
3005 pAd
->MacTab
.Content
[BSSID_WCID
].MaxHTPhyMode
.word
= pMaxHtPhy
->word
;
3006 pAd
->MacTab
.Content
[BSSID_WCID
].MinHTPhyMode
.word
= pMinHtPhy
->word
;
3010 switch (pAd
->CommonCfg
.PhyMode
)
3012 case PHY_11BG_MIXED
:
3014 #ifdef DOT11_N_SUPPORT
3015 case PHY_11BGN_MIXED
:
3016 #endif // DOT11_N_SUPPORT //
3017 pAd
->CommonCfg
.MlmeRate
= RATE_1
;
3018 pAd
->CommonCfg
.MlmeTransmit
.field
.MODE
= MODE_CCK
;
3019 pAd
->CommonCfg
.MlmeTransmit
.field
.MCS
= RATE_1
;
3022 pAd
->CommonCfg
.RtsRate
= RATE_11
;
3024 // pAd->CommonCfg.RtsRate = RATE_1;
3029 #ifdef DOT11_N_SUPPORT
3030 case PHY_11AGN_MIXED
:
3031 case PHY_11GN_MIXED
:
3033 case PHY_11AN_MIXED
:
3035 #endif // DOT11_N_SUPPORT //
3036 pAd
->CommonCfg
.MlmeRate
= RATE_6
;
3037 pAd
->CommonCfg
.RtsRate
= RATE_6
;
3038 pAd
->CommonCfg
.MlmeTransmit
.field
.MODE
= MODE_OFDM
;
3039 pAd
->CommonCfg
.MlmeTransmit
.field
.MCS
= OfdmRateToRxwiMCS
[pAd
->CommonCfg
.MlmeRate
];
3041 case PHY_11ABG_MIXED
:
3042 #ifdef DOT11_N_SUPPORT
3043 case PHY_11ABGN_MIXED
:
3044 #endif // DOT11_N_SUPPORT //
3045 if (pAd
->CommonCfg
.Channel
<= 14)
3047 pAd
->CommonCfg
.MlmeRate
= RATE_1
;
3048 pAd
->CommonCfg
.RtsRate
= RATE_1
;
3049 pAd
->CommonCfg
.MlmeTransmit
.field
.MODE
= MODE_CCK
;
3050 pAd
->CommonCfg
.MlmeTransmit
.field
.MCS
= RATE_1
;
3054 pAd
->CommonCfg
.MlmeRate
= RATE_6
;
3055 pAd
->CommonCfg
.RtsRate
= RATE_6
;
3056 pAd
->CommonCfg
.MlmeTransmit
.field
.MODE
= MODE_OFDM
;
3057 pAd
->CommonCfg
.MlmeTransmit
.field
.MCS
= OfdmRateToRxwiMCS
[pAd
->CommonCfg
.MlmeRate
];
3061 pAd
->CommonCfg
.MlmeRate
= RATE_6
;
3062 pAd
->CommonCfg
.MlmeTransmit
.field
.MODE
= MODE_OFDM
;
3063 pAd
->CommonCfg
.MlmeTransmit
.field
.MCS
= OfdmRateToRxwiMCS
[pAd
->CommonCfg
.MlmeRate
];
3064 pAd
->CommonCfg
.RtsRate
= RATE_1
;
3068 // Keep Basic Mlme Rate.
3070 pAd
->MacTab
.Content
[MCAST_WCID
].HTPhyMode
.word
= pAd
->CommonCfg
.MlmeTransmit
.word
;
3071 if (pAd
->CommonCfg
.MlmeTransmit
.field
.MODE
== MODE_OFDM
)
3072 pAd
->MacTab
.Content
[MCAST_WCID
].HTPhyMode
.field
.MCS
= OfdmRateToRxwiMCS
[RATE_24
];
3074 pAd
->MacTab
.Content
[MCAST_WCID
].HTPhyMode
.field
.MCS
= RATE_1
;
3075 pAd
->CommonCfg
.BasicMlmeRate
= pAd
->CommonCfg
.MlmeRate
;
3078 DBGPRINT(RT_DEBUG_TRACE
, (" MlmeUpdateTxRates (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n",
3079 RateIdToMbps
[MaxDesire
], RateIdToMbps
[MaxSupport
], RateIdToMbps
[pAd
->CommonCfg
.MaxTxRate
], RateIdToMbps
[pAd
->CommonCfg
.MinTxRate
],
3080 /*OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)*/*auto_rate_cur_p
));
3081 DBGPRINT(RT_DEBUG_TRACE
, (" MlmeUpdateTxRates (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n",
3082 RateIdToMbps
[pAd
->CommonCfg
.TxRate
], RateIdToMbps
[pAd
->CommonCfg
.RtsRate
], BasicRateBitmap
));
3083 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeUpdateTxRates (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n",
3084 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
));
3087 #ifdef DOT11_N_SUPPORT
3089 ==========================================================================
3091 This function update HT Rate setting.
3092 Input Wcid value is valid for 2 case :
3093 1. it's used for Station in infra mode that copy AP rate to Mactable.
3094 2. OR Station in adhoc mode to copy peer's HT rate to Mactable.
3096 IRQL = DISPATCH_LEVEL
3098 ==========================================================================
3100 VOID
MlmeUpdateHtTxRates(
3101 IN PRTMP_ADAPTER pAd
,
3104 UCHAR StbcMcs
; //j, StbcMcs, bitmask;
3106 RT_HT_CAPABILITY
*pRtHtCap
= NULL
;
3107 RT_HT_PHY_INFO
*pActiveHtPhy
= NULL
;
3110 PRT_HT_PHY_INFO pDesireHtPhy
= NULL
;
3111 PHTTRANSMIT_SETTING pHtPhy
= NULL
;
3112 PHTTRANSMIT_SETTING pMaxHtPhy
= NULL
;
3113 PHTTRANSMIT_SETTING pMinHtPhy
= NULL
;
3114 BOOLEAN
*auto_rate_cur_p
;
3116 DBGPRINT(RT_DEBUG_TRACE
,("MlmeUpdateHtTxRates===> \n"));
3118 auto_rate_cur_p
= NULL
;
3120 #ifdef CONFIG_STA_SUPPORT
3121 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
3123 pDesireHtPhy
= &pAd
->StaCfg
.DesiredHtPhyInfo
;
3124 pActiveHtPhy
= &pAd
->StaCfg
.DesiredHtPhyInfo
;
3125 pHtPhy
= &pAd
->StaCfg
.HTPhyMode
;
3126 pMaxHtPhy
= &pAd
->StaCfg
.MaxHTPhyMode
;
3127 pMinHtPhy
= &pAd
->StaCfg
.MinHTPhyMode
;
3129 auto_rate_cur_p
= &pAd
->StaCfg
.bAutoTxRateSwitch
;
3131 #endif // CONFIG_STA_SUPPORT //
3133 #ifdef CONFIG_STA_SUPPORT
3134 if ((ADHOC_ON(pAd
) || INFRA_ON(pAd
)) && (pAd
->OpMode
== OPMODE_STA
))
3136 if (pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
== FALSE
)
3139 pRtHtCap
= &pAd
->StaActive
.SupportedHtPhy
;
3140 pActiveHtPhy
= &pAd
->StaActive
.SupportedPhyInfo
;
3141 StbcMcs
= (UCHAR
)pAd
->MlmeAux
.AddHtInfo
.AddHtInfo3
.StbcMcs
;
3142 BasicMCS
=pAd
->MlmeAux
.AddHtInfo
.MCSSet
[0]+(pAd
->MlmeAux
.AddHtInfo
.MCSSet
[1]<<8)+(StbcMcs
<<16);
3143 if ((pAd
->CommonCfg
.DesiredHtPhy
.TxSTBC
) && (pRtHtCap
->RxSTBC
) && (pAd
->Antenna
.field
.TxPath
== 2))
3144 pMaxHtPhy
->field
.STBC
= STBC_USE
;
3146 pMaxHtPhy
->field
.STBC
= STBC_NONE
;
3149 #endif // CONFIG_STA_SUPPORT //
3151 if (pDesireHtPhy
->bHtEnable
== FALSE
)
3154 pRtHtCap
= &pAd
->CommonCfg
.DesiredHtPhy
;
3155 StbcMcs
= (UCHAR
)pAd
->CommonCfg
.AddHTInfo
.AddHtInfo3
.StbcMcs
;
3156 BasicMCS
= pAd
->CommonCfg
.AddHTInfo
.MCSSet
[0]+(pAd
->CommonCfg
.AddHTInfo
.MCSSet
[1]<<8)+(StbcMcs
<<16);
3157 if ((pAd
->CommonCfg
.DesiredHtPhy
.TxSTBC
) && (pRtHtCap
->RxSTBC
) && (pAd
->Antenna
.field
.TxPath
== 2))
3158 pMaxHtPhy
->field
.STBC
= STBC_USE
;
3160 pMaxHtPhy
->field
.STBC
= STBC_NONE
;
3163 // Decide MAX ht rate.
3164 if ((pRtHtCap
->GF
) && (pAd
->CommonCfg
.DesiredHtPhy
.GF
))
3165 pMaxHtPhy
->field
.MODE
= MODE_HTGREENFIELD
;
3167 pMaxHtPhy
->field
.MODE
= MODE_HTMIX
;
3169 if ((pAd
->CommonCfg
.DesiredHtPhy
.ChannelWidth
) && (pRtHtCap
->ChannelWidth
))
3170 pMaxHtPhy
->field
.BW
= BW_40
;
3172 pMaxHtPhy
->field
.BW
= BW_20
;
3174 if (pMaxHtPhy
->field
.BW
== BW_20
)
3175 pMaxHtPhy
->field
.ShortGI
= (pAd
->CommonCfg
.DesiredHtPhy
.ShortGIfor20
& pRtHtCap
->ShortGIfor20
);
3177 pMaxHtPhy
->field
.ShortGI
= (pAd
->CommonCfg
.DesiredHtPhy
.ShortGIfor40
& pRtHtCap
->ShortGIfor40
);
3179 for (i
=23; i
>=0; i
--) // 3*3
3182 bitmask
= (1<<(i
-(j
*8)));
3184 if ((pActiveHtPhy
->MCSSet
[j
] & bitmask
) && (pDesireHtPhy
->MCSSet
[j
] & bitmask
))
3186 pMaxHtPhy
->field
.MCS
= i
;
3194 // Copy MIN ht rate. rt2860???
3195 pMinHtPhy
->field
.BW
= BW_20
;
3196 pMinHtPhy
->field
.MCS
= 0;
3197 pMinHtPhy
->field
.STBC
= 0;
3198 pMinHtPhy
->field
.ShortGI
= 0;
3199 //If STA assigns fixed rate. update to fixed here.
3200 #ifdef CONFIG_STA_SUPPORT
3201 if ( (pAd
->OpMode
== OPMODE_STA
) && (pDesireHtPhy
->MCSSet
[0] != 0xff))
3203 if (pDesireHtPhy
->MCSSet
[4] != 0)
3205 pMaxHtPhy
->field
.MCS
= 32;
3206 pMinHtPhy
->field
.MCS
= 32;
3207 DBGPRINT(RT_DEBUG_TRACE
,("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n",pMinHtPhy
->field
.MCS
));
3210 for (i
=23; (CHAR
)i
>= 0; i
--) // 3*3
3213 bitmask
= (1<<(i
-(j
*8)));
3214 if ( (pDesireHtPhy
->MCSSet
[j
] & bitmask
) && (pActiveHtPhy
->MCSSet
[j
] & bitmask
))
3216 pMaxHtPhy
->field
.MCS
= i
;
3217 pMinHtPhy
->field
.MCS
= i
;
3224 #endif // CONFIG_STA_SUPPORT //
3228 pHtPhy
->field
.STBC
= pMaxHtPhy
->field
.STBC
;
3229 pHtPhy
->field
.BW
= pMaxHtPhy
->field
.BW
;
3230 pHtPhy
->field
.MODE
= pMaxHtPhy
->field
.MODE
;
3231 pHtPhy
->field
.MCS
= pMaxHtPhy
->field
.MCS
;
3232 pHtPhy
->field
.ShortGI
= pMaxHtPhy
->field
.ShortGI
;
3234 // use default now. rt2860
3235 if (pDesireHtPhy
->MCSSet
[0] != 0xff)
3236 *auto_rate_cur_p
= FALSE
;
3238 *auto_rate_cur_p
= TRUE
;
3240 DBGPRINT(RT_DEBUG_TRACE
, (" MlmeUpdateHtTxRates<---.AMsduSize = %d \n", pAd
->CommonCfg
.DesiredHtPhy
.AmsduSize
));
3241 DBGPRINT(RT_DEBUG_TRACE
,("TX: MCS[0] = %x (choose %d), BW = %d, ShortGI = %d, MODE = %d, \n", pActiveHtPhy
->MCSSet
[0],pHtPhy
->field
.MCS
,
3242 pHtPhy
->field
.BW
, pHtPhy
->field
.ShortGI
, pHtPhy
->field
.MODE
));
3243 DBGPRINT(RT_DEBUG_TRACE
,("MlmeUpdateHtTxRates<=== \n"));
3245 #endif // DOT11_N_SUPPORT //
3247 // IRQL = DISPATCH_LEVEL
3249 IN PRTMP_ADAPTER pAd
)
3251 RT28XX_MLME_RADIO_OFF(pAd
);
3254 // IRQL = DISPATCH_LEVEL
3256 IN PRTMP_ADAPTER pAd
)
3258 RT28XX_MLME_RADIO_ON(pAd
);
3261 // ===========================================================================================
3263 // ===========================================================================================
3266 /*! \brief initialize BSS table
3267 * \param p_tab pointer to the table
3272 IRQL = PASSIVE_LEVEL
3273 IRQL = DISPATCH_LEVEL
3282 Tab
->BssOverlapNr
= 0;
3283 for (i
= 0; i
< MAX_LEN_OF_BSS_TABLE
; i
++)
3285 NdisZeroMemory(&Tab
->BssEntry
[i
], sizeof(BSS_ENTRY
));
3286 Tab
->BssEntry
[i
].Rssi
= -127; // initial the rssi as a minimum value
3290 #ifdef DOT11_N_SUPPORT
3292 IN PRTMP_ADAPTER pAd
,
3297 Tab
->numAsOriginator
= 0;
3298 Tab
->numAsRecipient
= 0;
3299 NdisAllocateSpinLock(&pAd
->BATabLock
);
3300 for (i
= 0; i
< MAX_LEN_OF_BA_REC_TABLE
; i
++)
3302 Tab
->BARecEntry
[i
].REC_BA_Status
= Recipient_NONE
;
3303 NdisAllocateSpinLock(&(Tab
->BARecEntry
[i
].RxReRingLock
));
3305 for (i
= 0; i
< MAX_LEN_OF_BA_ORI_TABLE
; i
++)
3307 Tab
->BAOriEntry
[i
].ORI_BA_Status
= Originator_NONE
;
3310 #endif // DOT11_N_SUPPORT //
3312 /*! \brief search the BSS table by SSID
3313 * \param p_tab pointer to the bss table
3314 * \param ssid SSID string
3315 * \return index of the table, BSS_NOT_FOUND if not in the table
3318 * \note search by sequential search
3320 IRQL = DISPATCH_LEVEL
3323 ULONG
BssTableSearch(
3330 for (i
= 0; i
< Tab
->BssNr
; i
++)
3333 // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
3334 // We should distinguish this case.
3336 if ((((Tab
->BssEntry
[i
].Channel
<= 14) && (Channel
<= 14)) ||
3337 ((Tab
->BssEntry
[i
].Channel
> 14) && (Channel
> 14))) &&
3338 MAC_ADDR_EQUAL(Tab
->BssEntry
[i
].Bssid
, pBssid
))
3343 return (ULONG
)BSS_NOT_FOUND
;
3346 ULONG
BssSsidTableSearch(
3355 for (i
= 0; i
< Tab
->BssNr
; i
++)
3358 // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
3359 // We should distinguish this case.
3361 if ((((Tab
->BssEntry
[i
].Channel
<= 14) && (Channel
<= 14)) ||
3362 ((Tab
->BssEntry
[i
].Channel
> 14) && (Channel
> 14))) &&
3363 MAC_ADDR_EQUAL(Tab
->BssEntry
[i
].Bssid
, pBssid
) &&
3364 SSID_EQUAL(pSsid
, SsidLen
, Tab
->BssEntry
[i
].Ssid
, Tab
->BssEntry
[i
].SsidLen
))
3369 return (ULONG
)BSS_NOT_FOUND
;
3372 ULONG
BssTableSearchWithSSID(
3381 for (i
= 0; i
< Tab
->BssNr
; i
++)
3383 if ((((Tab
->BssEntry
[i
].Channel
<= 14) && (Channel
<= 14)) ||
3384 ((Tab
->BssEntry
[i
].Channel
> 14) && (Channel
> 14))) &&
3385 MAC_ADDR_EQUAL(&(Tab
->BssEntry
[i
].Bssid
), Bssid
) &&
3386 (SSID_EQUAL(pSsid
, SsidLen
, Tab
->BssEntry
[i
].Ssid
, Tab
->BssEntry
[i
].SsidLen
) ||
3387 (NdisEqualMemory(pSsid
, ZeroSsid
, SsidLen
)) ||
3388 (NdisEqualMemory(Tab
->BssEntry
[i
].Ssid
, ZeroSsid
, Tab
->BssEntry
[i
].SsidLen
))))
3393 return (ULONG
)BSS_NOT_FOUND
;
3396 // IRQL = DISPATCH_LEVEL
3397 VOID
BssTableDeleteEntry(
3398 IN OUT BSS_TABLE
*Tab
,
3404 for (i
= 0; i
< Tab
->BssNr
; i
++)
3406 if ((Tab
->BssEntry
[i
].Channel
== Channel
) &&
3407 (MAC_ADDR_EQUAL(Tab
->BssEntry
[i
].Bssid
, pBssid
)))
3409 for (j
= i
; j
< Tab
->BssNr
- 1; j
++)
3411 NdisMoveMemory(&(Tab
->BssEntry
[j
]), &(Tab
->BssEntry
[j
+ 1]), sizeof(BSS_ENTRY
));
3413 NdisZeroMemory(&(Tab
->BssEntry
[Tab
->BssNr
- 1]), sizeof(BSS_ENTRY
));
3420 #ifdef DOT11_N_SUPPORT
3422 ========================================================================
3423 Routine Description:
3424 Delete the Originator Entry in BAtable. Or decrease numAs Originator by 1 if needed.
3427 // IRQL = DISPATCH_LEVEL
3428 ========================================================================
3430 VOID
BATableDeleteORIEntry(
3431 IN OUT PRTMP_ADAPTER pAd
,
3432 IN BA_ORI_ENTRY
*pBAORIEntry
)
3435 if (pBAORIEntry
->ORI_BA_Status
!= Originator_NONE
)
3437 NdisAcquireSpinLock(&pAd
->BATabLock
);
3438 if (pBAORIEntry
->ORI_BA_Status
== Originator_Done
)
3440 pAd
->BATable
.numAsOriginator
-= 1;
3441 DBGPRINT(RT_DEBUG_TRACE
, ("BATableDeleteORIEntry numAsOriginator= %ld\n", pAd
->BATable
.numAsRecipient
));
3442 // Erase Bitmap flag.
3444 pAd
->MacTab
.Content
[pBAORIEntry
->Wcid
].TXBAbitmap
&= (~(1<<(pBAORIEntry
->TID
) )); // If STA mode, erase flag here
3445 pAd
->MacTab
.Content
[pBAORIEntry
->Wcid
].BAOriWcidArray
[pBAORIEntry
->TID
] = 0; // If STA mode, erase flag here
3446 pBAORIEntry
->ORI_BA_Status
= Originator_NONE
;
3447 pBAORIEntry
->Token
= 1;
3448 // Not clear Sequence here.
3449 NdisReleaseSpinLock(&pAd
->BATabLock
);
3452 #endif // DOT11_N_SUPPORT //
3460 IRQL = DISPATCH_LEVEL
3464 IN PRTMP_ADAPTER pAd
,
3465 OUT BSS_ENTRY
*pBss
,
3470 IN USHORT BeaconPeriod
,
3471 IN PCF_PARM pCfParm
,
3473 IN USHORT CapabilityInfo
,
3475 IN UCHAR SupRateLen
,
3477 IN UCHAR ExtRateLen
,
3478 IN HT_CAPABILITY_IE
*pHtCapability
,
3479 IN ADD_HT_INFO_IE
*pAddHtInfo
, // AP might use this additional ht info IE
3480 IN UCHAR HtCapabilityLen
,
3481 IN UCHAR AddHtInfoLen
,
3482 IN UCHAR NewExtChanOffset
,
3485 IN LARGE_INTEGER TimeStamp
,
3487 IN PEDCA_PARM pEdcaParm
,
3488 IN PQOS_CAPABILITY_PARM pQosCapability
,
3489 IN PQBSS_LOAD_PARM pQbssLoad
,
3490 IN USHORT LengthVIE
,
3491 IN PNDIS_802_11_VARIABLE_IEs pVIE
)
3493 COPY_MAC_ADDR(pBss
->Bssid
, pBssid
);
3494 // Default Hidden SSID to be TRUE, it will be turned to FALSE after coping SSID
3498 // For hidden SSID AP, it might send beacon with SSID len equal to 0
3499 // Or send beacon /probe response with SSID len matching real SSID length,
3500 // but SSID is all zero. such as "00-00-00-00" with length 4.
3501 // We have to prevent this case overwrite correct table
3502 if (NdisEqualMemory(Ssid
, ZeroSsid
, SsidLen
) == 0)
3504 NdisZeroMemory(pBss
->Ssid
, MAX_LEN_OF_SSID
);
3505 NdisMoveMemory(pBss
->Ssid
, Ssid
, SsidLen
);
3506 pBss
->SsidLen
= SsidLen
;
3512 pBss
->BssType
= BssType
;
3513 pBss
->BeaconPeriod
= BeaconPeriod
;
3514 if (BssType
== BSS_INFRA
)
3516 if (pCfParm
->bValid
)
3518 pBss
->CfpCount
= pCfParm
->CfpCount
;
3519 pBss
->CfpPeriod
= pCfParm
->CfpPeriod
;
3520 pBss
->CfpMaxDuration
= pCfParm
->CfpMaxDuration
;
3521 pBss
->CfpDurRemaining
= pCfParm
->CfpDurRemaining
;
3526 pBss
->AtimWin
= AtimWin
;
3529 pBss
->CapabilityInfo
= CapabilityInfo
;
3530 // The privacy bit indicate security is ON, it maight be WEP, TKIP or AES
3531 // Combine with AuthMode, they will decide the connection methods.
3532 pBss
->Privacy
= CAP_IS_PRIVACY_ON(pBss
->CapabilityInfo
);
3533 ASSERT(SupRateLen
<= MAX_LEN_OF_SUPPORTED_RATES
);
3534 if (SupRateLen
<= MAX_LEN_OF_SUPPORTED_RATES
)
3535 NdisMoveMemory(pBss
->SupRate
, SupRate
, SupRateLen
);
3537 NdisMoveMemory(pBss
->SupRate
, SupRate
, MAX_LEN_OF_SUPPORTED_RATES
);
3538 pBss
->SupRateLen
= SupRateLen
;
3539 ASSERT(ExtRateLen
<= MAX_LEN_OF_SUPPORTED_RATES
);
3540 NdisMoveMemory(pBss
->ExtRate
, ExtRate
, ExtRateLen
);
3541 NdisMoveMemory(&pBss
->HtCapability
, pHtCapability
, HtCapabilityLen
);
3542 NdisMoveMemory(&pBss
->AddHtInfo
, pAddHtInfo
, AddHtInfoLen
);
3543 pBss
->NewExtChanOffset
= NewExtChanOffset
;
3544 pBss
->ExtRateLen
= ExtRateLen
;
3545 pBss
->Channel
= Channel
;
3546 pBss
->CentralChannel
= Channel
;
3548 // Update CkipFlag. if not exists, the value is 0x0
3549 pBss
->CkipFlag
= CkipFlag
;
3551 // New for microsoft Fixed IEs
3552 NdisMoveMemory(pBss
->FixIEs
.Timestamp
, &TimeStamp
, 8);
3553 pBss
->FixIEs
.BeaconInterval
= BeaconPeriod
;
3554 pBss
->FixIEs
.Capabilities
= CapabilityInfo
;
3556 // New for microsoft Variable IEs
3559 pBss
->VarIELen
= LengthVIE
;
3560 NdisMoveMemory(pBss
->VarIEs
, pVIE
, pBss
->VarIELen
);
3567 pBss
->AddHtInfoLen
= 0;
3568 pBss
->HtCapabilityLen
= 0;
3569 #ifdef DOT11_N_SUPPORT
3570 if (HtCapabilityLen
> 0)
3572 pBss
->HtCapabilityLen
= HtCapabilityLen
;
3573 NdisMoveMemory(&pBss
->HtCapability
, pHtCapability
, HtCapabilityLen
);
3574 if (AddHtInfoLen
> 0)
3576 pBss
->AddHtInfoLen
= AddHtInfoLen
;
3577 NdisMoveMemory(&pBss
->AddHtInfo
, pAddHtInfo
, AddHtInfoLen
);
3579 if ((pAddHtInfo
->ControlChan
> 2)&& (pAddHtInfo
->AddHtInfo
.ExtChanOffset
== EXTCHA_BELOW
) && (pHtCapability
->HtCapInfo
.ChannelWidth
== BW_40
))
3581 pBss
->CentralChannel
= pAddHtInfo
->ControlChan
- 2;
3583 else if ((pAddHtInfo
->AddHtInfo
.ExtChanOffset
== EXTCHA_ABOVE
) && (pHtCapability
->HtCapInfo
.ChannelWidth
== BW_40
))
3585 pBss
->CentralChannel
= pAddHtInfo
->ControlChan
+ 2;
3589 #endif // DOT11_N_SUPPORT //
3591 BssCipherParse(pBss
);
3595 NdisMoveMemory(&pBss
->EdcaParm
, pEdcaParm
, sizeof(EDCA_PARM
));
3597 pBss
->EdcaParm
.bValid
= FALSE
;
3599 NdisMoveMemory(&pBss
->QosCapability
, pQosCapability
, sizeof(QOS_CAPABILITY_PARM
));
3601 pBss
->QosCapability
.bValid
= FALSE
;
3603 NdisMoveMemory(&pBss
->QbssLoad
, pQbssLoad
, sizeof(QBSS_LOAD_PARM
));
3605 pBss
->QbssLoad
.bValid
= FALSE
;
3607 #ifdef CONFIG_STA_SUPPORT
3608 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
3614 NdisZeroMemory(&pBss
->WpaIE
.IE
[0], MAX_CUSTOM_LEN
);
3615 NdisZeroMemory(&pBss
->RsnIE
.IE
[0], MAX_CUSTOM_LEN
);
3617 pEid
= (PEID_STRUCT
) pVIE
;
3619 while ((Length
+ 2 + (USHORT
)pEid
->Len
) <= LengthVIE
)
3624 if (NdisEqualMemory(pEid
->Octet
, WPA_OUI
, 4))
3626 if ((pEid
->Len
+ 2) > MAX_CUSTOM_LEN
)
3628 pBss
->WpaIE
.IELen
= 0;
3631 pBss
->WpaIE
.IELen
= pEid
->Len
+ 2;
3632 NdisMoveMemory(pBss
->WpaIE
.IE
, pEid
, pBss
->WpaIE
.IELen
);
3636 if (NdisEqualMemory(pEid
->Octet
+ 2, RSN_OUI
, 3))
3638 if ((pEid
->Len
+ 2) > MAX_CUSTOM_LEN
)
3640 pBss
->RsnIE
.IELen
= 0;
3643 pBss
->RsnIE
.IELen
= pEid
->Len
+ 2;
3644 NdisMoveMemory(pBss
->RsnIE
.IE
, pEid
, pBss
->RsnIE
.IELen
);
3648 Length
= Length
+ 2 + (USHORT
)pEid
->Len
; // Eid[1] + Len[1]+ content[Len]
3649 pEid
= (PEID_STRUCT
)((UCHAR
*)pEid
+ 2 + pEid
->Len
);
3652 #endif // CONFIG_STA_SUPPORT //
3656 * \brief insert an entry into the bss table
3657 * \param p_tab The BSS table
3658 * \param Bssid BSSID
3660 * \param ssid_len Length of SSID
3662 * \param beacon_period
3669 * \param channel_idx
3673 * \note If SSID is identical, the old entry will be replaced by the new one
3675 IRQL = DISPATCH_LEVEL
3678 ULONG
BssTableSetEntry(
3679 IN PRTMP_ADAPTER pAd
,
3685 IN USHORT BeaconPeriod
,
3688 IN USHORT CapabilityInfo
,
3690 IN UCHAR SupRateLen
,
3692 IN UCHAR ExtRateLen
,
3693 IN HT_CAPABILITY_IE
*pHtCapability
,
3694 IN ADD_HT_INFO_IE
*pAddHtInfo
, // AP might use this additional ht info IE
3695 IN UCHAR HtCapabilityLen
,
3696 IN UCHAR AddHtInfoLen
,
3697 IN UCHAR NewExtChanOffset
,
3700 IN LARGE_INTEGER TimeStamp
,
3702 IN PEDCA_PARM pEdcaParm
,
3703 IN PQOS_CAPABILITY_PARM pQosCapability
,
3704 IN PQBSS_LOAD_PARM pQbssLoad
,
3705 IN USHORT LengthVIE
,
3706 IN PNDIS_802_11_VARIABLE_IEs pVIE
)
3710 Idx
= BssTableSearchWithSSID(Tab
, pBssid
, Ssid
, SsidLen
, ChannelNo
);
3711 if (Idx
== BSS_NOT_FOUND
)
3713 if (Tab
->BssNr
>= MAX_LEN_OF_BSS_TABLE
)
3716 // It may happen when BSS Table was full.
3717 // The desired AP will not be added into BSS Table
3718 // In this case, if we found the desired AP then overwrite BSS Table.
3720 if(!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
3722 if (MAC_ADDR_EQUAL(pAd
->MlmeAux
.Bssid
, pBssid
) ||
3723 SSID_EQUAL(pAd
->MlmeAux
.Ssid
, pAd
->MlmeAux
.SsidLen
, Ssid
, SsidLen
))
3725 Idx
= Tab
->BssOverlapNr
;
3726 BssEntrySet(pAd
, &Tab
->BssEntry
[Idx
], pBssid
, Ssid
, SsidLen
, BssType
, BeaconPeriod
, CfParm
, AtimWin
,
3727 CapabilityInfo
, SupRate
, SupRateLen
, ExtRate
, ExtRateLen
,pHtCapability
, pAddHtInfo
,HtCapabilityLen
, AddHtInfoLen
,
3728 NewExtChanOffset
, ChannelNo
, Rssi
, TimeStamp
, CkipFlag
, pEdcaParm
, pQosCapability
, pQbssLoad
, LengthVIE
, pVIE
);
3729 Tab
->BssOverlapNr
= (Tab
->BssOverlapNr
++) % MAX_LEN_OF_BSS_TABLE
;
3735 return BSS_NOT_FOUND
;
3739 BssEntrySet(pAd
, &Tab
->BssEntry
[Idx
], pBssid
, Ssid
, SsidLen
, BssType
, BeaconPeriod
, CfParm
, AtimWin
,
3740 CapabilityInfo
, SupRate
, SupRateLen
, ExtRate
, ExtRateLen
,pHtCapability
, pAddHtInfo
,HtCapabilityLen
, AddHtInfoLen
,
3741 NewExtChanOffset
, ChannelNo
, Rssi
, TimeStamp
, CkipFlag
, pEdcaParm
, pQosCapability
, pQbssLoad
, LengthVIE
, pVIE
);
3746 BssEntrySet(pAd
, &Tab
->BssEntry
[Idx
], pBssid
, Ssid
, SsidLen
, BssType
, BeaconPeriod
,CfParm
, AtimWin
,
3747 CapabilityInfo
, SupRate
, SupRateLen
, ExtRate
, ExtRateLen
,pHtCapability
, pAddHtInfo
,HtCapabilityLen
, AddHtInfoLen
,
3748 NewExtChanOffset
, ChannelNo
, Rssi
, TimeStamp
, CkipFlag
, pEdcaParm
, pQosCapability
, pQbssLoad
, LengthVIE
, pVIE
);
3754 #ifdef CONFIG_STA_SUPPORT
3755 // IRQL = DISPATCH_LEVEL
3756 VOID
BssTableSsidSort(
3757 IN PRTMP_ADAPTER pAd
,
3758 OUT BSS_TABLE
*OutTab
,
3763 BssTableInit(OutTab
);
3765 for (i
= 0; i
< pAd
->ScanTab
.BssNr
; i
++)
3767 BSS_ENTRY
*pInBss
= &pAd
->ScanTab
.BssEntry
[i
];
3768 BOOLEAN bIsHiddenApIncluded
= FALSE
;
3770 if (((pAd
->CommonCfg
.bIEEE80211H
== 1) &&
3771 (pAd
->MlmeAux
.Channel
> 14) &&
3772 RadarChannelCheck(pAd
, pInBss
->Channel
))
3776 bIsHiddenApIncluded
= TRUE
;
3779 if ((pInBss
->BssType
== pAd
->StaCfg
.BssType
) &&
3780 (SSID_EQUAL(Ssid
, SsidLen
, pInBss
->Ssid
, pInBss
->SsidLen
) || bIsHiddenApIncluded
))
3782 BSS_ENTRY
*pOutBss
= &OutTab
->BssEntry
[OutTab
->BssNr
];
3783 #ifdef DOT11_N_SUPPORT
3784 // 2.4G/5G N only mode
3785 if ((pInBss
->HtCapabilityLen
== 0) &&
3786 ((pAd
->CommonCfg
.PhyMode
== PHY_11N_2_4G
) || (pAd
->CommonCfg
.PhyMode
== PHY_11N_5G
)))
3788 DBGPRINT(RT_DEBUG_TRACE
,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
3791 #endif // DOT11_N_SUPPORT //
3794 // Check the Authmode first
3795 if (pAd
->StaCfg
.AuthMode
>= Ndis802_11AuthModeWPA
)
3797 // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
3798 if ((pAd
->StaCfg
.AuthMode
!= pInBss
->AuthMode
) && (pAd
->StaCfg
.AuthMode
!= pInBss
->AuthModeAux
))
3802 // Check cipher suite, AP must have more secured cipher than station setting
3803 if ((pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA
) || (pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPAPSK
))
3805 // If it's not mixed mode, we should only let BSS pass with the same encryption
3806 if (pInBss
->WPA
.bMixMode
== FALSE
)
3807 if (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA
.GroupCipher
)
3810 // check group cipher
3811 if ((pAd
->StaCfg
.WepStatus
< pInBss
->WPA
.GroupCipher
) &&
3812 (pInBss
->WPA
.GroupCipher
!= Ndis802_11GroupWEP40Enabled
) &&
3813 (pInBss
->WPA
.GroupCipher
!= Ndis802_11GroupWEP104Enabled
))
3816 // check pairwise cipher, skip if none matched
3817 // If profile set to AES, let it pass without question.
3818 // If profile set to TKIP, we must find one mateched
3819 if ((pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption2Enabled
) &&
3820 (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA
.PairCipher
) &&
3821 (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA
.PairCipherAux
))
3824 else if ((pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA2
) || (pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA2PSK
))
3826 // If it's not mixed mode, we should only let BSS pass with the same encryption
3827 if (pInBss
->WPA2
.bMixMode
== FALSE
)
3828 if (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA2
.GroupCipher
)
3831 // check group cipher
3832 if ((pAd
->StaCfg
.WepStatus
< pInBss
->WPA
.GroupCipher
) &&
3833 (pInBss
->WPA2
.GroupCipher
!= Ndis802_11GroupWEP40Enabled
) &&
3834 (pInBss
->WPA2
.GroupCipher
!= Ndis802_11GroupWEP104Enabled
))
3837 // check pairwise cipher, skip if none matched
3838 // If profile set to AES, let it pass without question.
3839 // If profile set to TKIP, we must find one mateched
3840 if ((pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption2Enabled
) &&
3841 (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA2
.PairCipher
) &&
3842 (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA2
.PairCipherAux
))
3846 // Bss Type matched, SSID matched.
3847 // We will check wepstatus for qualification Bss
3848 else if (pAd
->StaCfg
.WepStatus
!= pInBss
->WepStatus
)
3850 DBGPRINT(RT_DEBUG_TRACE
,("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n", pAd
->StaCfg
.WepStatus
, pInBss
->WepStatus
));
3852 // For the SESv2 case, we will not qualify WepStatus.
3858 // Since the AP is using hidden SSID, and we are trying to connect to ANY
3859 // It definitely will fail. So, skip it.
3860 // CCX also require not even try to connect it!!
3864 #ifdef DOT11_N_SUPPORT
3865 // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
3866 // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
3867 if ((pInBss
->CentralChannel
!= pInBss
->Channel
) &&
3868 (pAd
->CommonCfg
.RegTransmitSetting
.field
.BW
== BW_40
))
3870 if (RTMPCheckChannel(pAd
, pInBss
->CentralChannel
, pInBss
->Channel
) == FALSE
)
3872 pAd
->CommonCfg
.RegTransmitSetting
.field
.BW
= BW_20
;
3874 pAd
->CommonCfg
.RegTransmitSetting
.field
.BW
= BW_40
;
3878 if (pAd
->CommonCfg
.DesiredHtPhy
.ChannelWidth
== BAND_WIDTH_20
)
3884 #endif // DOT11_N_SUPPORT //
3886 // copy matching BSS from InTab to OutTab
3887 NdisMoveMemory(pOutBss
, pInBss
, sizeof(BSS_ENTRY
));
3891 else if ((pInBss
->BssType
== pAd
->StaCfg
.BssType
) && (SsidLen
== 0))
3893 BSS_ENTRY
*pOutBss
= &OutTab
->BssEntry
[OutTab
->BssNr
];
3896 #ifdef DOT11_N_SUPPORT
3897 // 2.4G/5G N only mode
3898 if ((pInBss
->HtCapabilityLen
== 0) &&
3899 ((pAd
->CommonCfg
.PhyMode
== PHY_11N_2_4G
) || (pAd
->CommonCfg
.PhyMode
== PHY_11N_5G
)))
3901 DBGPRINT(RT_DEBUG_TRACE
,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
3904 #endif // DOT11_N_SUPPORT //
3907 // Check the Authmode first
3908 if (pAd
->StaCfg
.AuthMode
>= Ndis802_11AuthModeWPA
)
3910 // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
3911 if ((pAd
->StaCfg
.AuthMode
!= pInBss
->AuthMode
) && (pAd
->StaCfg
.AuthMode
!= pInBss
->AuthModeAux
))
3915 // Check cipher suite, AP must have more secured cipher than station setting
3916 if ((pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA
) || (pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPAPSK
))
3918 // If it's not mixed mode, we should only let BSS pass with the same encryption
3919 if (pInBss
->WPA
.bMixMode
== FALSE
)
3920 if (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA
.GroupCipher
)
3923 // check group cipher
3924 if (pAd
->StaCfg
.WepStatus
< pInBss
->WPA
.GroupCipher
)
3927 // check pairwise cipher, skip if none matched
3928 // If profile set to AES, let it pass without question.
3929 // If profile set to TKIP, we must find one mateched
3930 if ((pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption2Enabled
) &&
3931 (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA
.PairCipher
) &&
3932 (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA
.PairCipherAux
))
3935 else if ((pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA2
) || (pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA2PSK
))
3937 // If it's not mixed mode, we should only let BSS pass with the same encryption
3938 if (pInBss
->WPA2
.bMixMode
== FALSE
)
3939 if (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA2
.GroupCipher
)
3942 // check group cipher
3943 if (pAd
->StaCfg
.WepStatus
< pInBss
->WPA2
.GroupCipher
)
3946 // check pairwise cipher, skip if none matched
3947 // If profile set to AES, let it pass without question.
3948 // If profile set to TKIP, we must find one mateched
3949 if ((pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption2Enabled
) &&
3950 (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA2
.PairCipher
) &&
3951 (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA2
.PairCipherAux
))
3955 // Bss Type matched, SSID matched.
3956 // We will check wepstatus for qualification Bss
3957 else if (pAd
->StaCfg
.WepStatus
!= pInBss
->WepStatus
)
3960 #ifdef DOT11_N_SUPPORT
3961 // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
3962 // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
3963 if ((pInBss
->CentralChannel
!= pInBss
->Channel
) &&
3964 (pAd
->CommonCfg
.RegTransmitSetting
.field
.BW
== BW_40
))
3966 if (RTMPCheckChannel(pAd
, pInBss
->CentralChannel
, pInBss
->Channel
) == FALSE
)
3968 pAd
->CommonCfg
.RegTransmitSetting
.field
.BW
= BW_20
;
3970 pAd
->CommonCfg
.RegTransmitSetting
.field
.BW
= BW_40
;
3973 #endif // DOT11_N_SUPPORT //
3975 // copy matching BSS from InTab to OutTab
3976 NdisMoveMemory(pOutBss
, pInBss
, sizeof(BSS_ENTRY
));
3981 if (OutTab
->BssNr
>= MAX_LEN_OF_BSS_TABLE
)
3985 BssTableSortByRssi(OutTab
);
3989 // IRQL = DISPATCH_LEVEL
3990 VOID
BssTableSortByRssi(
3991 IN OUT BSS_TABLE
*OutTab
)
3996 for (i
= 0; i
< OutTab
->BssNr
- 1; i
++)
3998 for (j
= i
+1; j
< OutTab
->BssNr
; j
++)
4000 if (OutTab
->BssEntry
[j
].Rssi
> OutTab
->BssEntry
[i
].Rssi
)
4002 NdisMoveMemory(&TmpBss
, &OutTab
->BssEntry
[j
], sizeof(BSS_ENTRY
));
4003 NdisMoveMemory(&OutTab
->BssEntry
[j
], &OutTab
->BssEntry
[i
], sizeof(BSS_ENTRY
));
4004 NdisMoveMemory(&OutTab
->BssEntry
[i
], &TmpBss
, sizeof(BSS_ENTRY
));
4009 #endif // CONFIG_STA_SUPPORT //
4012 VOID
BssCipherParse(
4013 IN OUT PBSS_ENTRY pBss
)
4017 PRSN_IE_HEADER_STRUCT pRsnHeader
;
4018 PCIPHER_SUITE_STRUCT pCipher
;
4019 PAKM_SUITE_STRUCT pAKM
;
4022 NDIS_802_11_ENCRYPTION_STATUS TmpCipher
;
4025 // WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame.
4029 pBss
->WepStatus
= Ndis802_11WEPEnabled
;
4033 pBss
->WepStatus
= Ndis802_11WEPDisabled
;
4035 // Set default to disable & open authentication before parsing variable IE
4036 pBss
->AuthMode
= Ndis802_11AuthModeOpen
;
4037 pBss
->AuthModeAux
= Ndis802_11AuthModeOpen
;
4040 pBss
->WPA
.PairCipher
= Ndis802_11WEPDisabled
;
4041 pBss
->WPA
.PairCipherAux
= Ndis802_11WEPDisabled
;
4042 pBss
->WPA
.GroupCipher
= Ndis802_11WEPDisabled
;
4043 pBss
->WPA
.RsnCapability
= 0;
4044 pBss
->WPA
.bMixMode
= FALSE
;
4046 // Init WPA2 setting
4047 pBss
->WPA2
.PairCipher
= Ndis802_11WEPDisabled
;
4048 pBss
->WPA2
.PairCipherAux
= Ndis802_11WEPDisabled
;
4049 pBss
->WPA2
.GroupCipher
= Ndis802_11WEPDisabled
;
4050 pBss
->WPA2
.RsnCapability
= 0;
4051 pBss
->WPA2
.bMixMode
= FALSE
;
4054 Length
= (INT
) pBss
->VarIELen
;
4058 // Parse cipher suite base on WPA1 & WPA2, they should be parsed differently
4059 pTmp
= ((PUCHAR
) pBss
->VarIEs
) + pBss
->VarIELen
- Length
;
4060 pEid
= (PEID_STRUCT
) pTmp
;
4064 //Parse Cisco IE_WPA (LEAP, CCKM, etc.)
4065 if ( NdisEqualMemory((pTmp
+8), CISCO_OUI
, 3))
4071 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4072 pBss
->WepStatus
= Ndis802_11Encryption1Enabled
;
4073 pBss
->WPA
.PairCipher
= Ndis802_11Encryption1Enabled
;
4074 pBss
->WPA
.GroupCipher
= Ndis802_11Encryption1Enabled
;
4077 pBss
->WepStatus
= Ndis802_11Encryption2Enabled
;
4078 pBss
->WPA
.PairCipher
= Ndis802_11Encryption1Enabled
;
4079 pBss
->WPA
.GroupCipher
= Ndis802_11Encryption1Enabled
;
4082 pBss
->WepStatus
= Ndis802_11Encryption3Enabled
;
4083 pBss
->WPA
.PairCipher
= Ndis802_11Encryption1Enabled
;
4084 pBss
->WPA
.GroupCipher
= Ndis802_11Encryption1Enabled
;
4090 // if Cisco IE_WPA, break
4093 else if (NdisEqualMemory(pEid
->Octet
, SES_OUI
, 3) && (pEid
->Len
== 7))
4098 else if (NdisEqualMemory(pEid
->Octet
, WPA_OUI
, 4) != 1)
4100 // if unsupported vendor specific IE
4103 // Skip OUI, version, and multicast suite
4104 // This part should be improved in the future when AP supported multiple cipher suite.
4105 // For now, it's OK since almost all APs have fixed cipher suite supported.
4106 // pTmp = (PUCHAR) pEid->Octet;
4109 // Cipher Suite Selectors from Spec P802.11i/D3.2 P26.
4117 // Parse group cipher
4121 pBss
->WPA
.GroupCipher
= Ndis802_11GroupWEP40Enabled
;
4124 pBss
->WPA
.GroupCipher
= Ndis802_11GroupWEP104Enabled
;
4127 pBss
->WPA
.GroupCipher
= Ndis802_11Encryption2Enabled
;
4130 pBss
->WPA
.GroupCipher
= Ndis802_11Encryption3Enabled
;
4135 // number of unicast suite
4138 // skip all unicast cipher suites
4139 //Count = *(PUSHORT) pTmp;
4140 Count
= (pTmp
[1]<<8) + pTmp
[0];
4141 pTmp
+= sizeof(USHORT
);
4143 // Parsing all unicast cipher suite
4148 TmpCipher
= Ndis802_11WEPDisabled
;
4152 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4153 TmpCipher
= Ndis802_11Encryption1Enabled
;
4156 TmpCipher
= Ndis802_11Encryption2Enabled
;
4159 TmpCipher
= Ndis802_11Encryption3Enabled
;
4164 if (TmpCipher
> pBss
->WPA
.PairCipher
)
4166 // Move the lower cipher suite to PairCipherAux
4167 pBss
->WPA
.PairCipherAux
= pBss
->WPA
.PairCipher
;
4168 pBss
->WPA
.PairCipher
= TmpCipher
;
4172 pBss
->WPA
.PairCipherAux
= TmpCipher
;
4178 // 4. get AKM suite counts
4179 //Count = *(PUSHORT) pTmp;
4180 Count
= (pTmp
[1]<<8) + pTmp
[0];
4181 pTmp
+= sizeof(USHORT
);
4187 // Set AP support WPA mode
4188 if (pBss
->AuthMode
== Ndis802_11AuthModeOpen
)
4189 pBss
->AuthMode
= Ndis802_11AuthModeWPA
;
4191 pBss
->AuthModeAux
= Ndis802_11AuthModeWPA
;
4194 // Set AP support WPA mode
4195 if (pBss
->AuthMode
== Ndis802_11AuthModeOpen
)
4196 pBss
->AuthMode
= Ndis802_11AuthModeWPAPSK
;
4198 pBss
->AuthModeAux
= Ndis802_11AuthModeWPAPSK
;
4205 // Fixed for WPA-None
4206 if (pBss
->BssType
== BSS_ADHOC
)
4208 pBss
->AuthMode
= Ndis802_11AuthModeWPANone
;
4209 pBss
->AuthModeAux
= Ndis802_11AuthModeWPANone
;
4210 pBss
->WepStatus
= pBss
->WPA
.GroupCipher
;
4211 // Patched bugs for old driver
4212 if (pBss
->WPA
.PairCipherAux
== Ndis802_11WEPDisabled
)
4213 pBss
->WPA
.PairCipherAux
= pBss
->WPA
.GroupCipher
;
4216 pBss
->WepStatus
= pBss
->WPA
.PairCipher
;
4218 // Check the Pair & Group, if different, turn on mixed mode flag
4219 if (pBss
->WPA
.GroupCipher
!= pBss
->WPA
.PairCipher
)
4220 pBss
->WPA
.bMixMode
= TRUE
;
4225 pRsnHeader
= (PRSN_IE_HEADER_STRUCT
) pTmp
;
4227 // 0. Version must be 1
4228 if (le2cpu16(pRsnHeader
->Version
) != 1)
4230 pTmp
+= sizeof(RSN_IE_HEADER_STRUCT
);
4232 // 1. Check group cipher
4233 pCipher
= (PCIPHER_SUITE_STRUCT
) pTmp
;
4234 if (!RTMPEqualMemory(pTmp
, RSN_OUI
, 3))
4237 // Parse group cipher
4238 switch (pCipher
->Type
)
4241 pBss
->WPA2
.GroupCipher
= Ndis802_11GroupWEP40Enabled
;
4244 pBss
->WPA2
.GroupCipher
= Ndis802_11GroupWEP104Enabled
;
4247 pBss
->WPA2
.GroupCipher
= Ndis802_11Encryption2Enabled
;
4250 pBss
->WPA2
.GroupCipher
= Ndis802_11Encryption3Enabled
;
4255 // set to correct offset for next parsing
4256 pTmp
+= sizeof(CIPHER_SUITE_STRUCT
);
4258 // 2. Get pairwise cipher counts
4259 //Count = *(PUSHORT) pTmp;
4260 Count
= (pTmp
[1]<<8) + pTmp
[0];
4261 pTmp
+= sizeof(USHORT
);
4263 // 3. Get pairwise cipher
4264 // Parsing all unicast cipher suite
4268 pCipher
= (PCIPHER_SUITE_STRUCT
) pTmp
;
4269 TmpCipher
= Ndis802_11WEPDisabled
;
4270 switch (pCipher
->Type
)
4273 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4274 TmpCipher
= Ndis802_11Encryption1Enabled
;
4277 TmpCipher
= Ndis802_11Encryption2Enabled
;
4280 TmpCipher
= Ndis802_11Encryption3Enabled
;
4285 if (TmpCipher
> pBss
->WPA2
.PairCipher
)
4287 // Move the lower cipher suite to PairCipherAux
4288 pBss
->WPA2
.PairCipherAux
= pBss
->WPA2
.PairCipher
;
4289 pBss
->WPA2
.PairCipher
= TmpCipher
;
4293 pBss
->WPA2
.PairCipherAux
= TmpCipher
;
4295 pTmp
+= sizeof(CIPHER_SUITE_STRUCT
);
4299 // 4. get AKM suite counts
4300 //Count = *(PUSHORT) pTmp;
4301 Count
= (pTmp
[1]<<8) + pTmp
[0];
4302 pTmp
+= sizeof(USHORT
);
4304 // 5. Get AKM ciphers
4305 pAKM
= (PAKM_SUITE_STRUCT
) pTmp
;
4306 if (!RTMPEqualMemory(pTmp
, RSN_OUI
, 3))
4312 // Set AP support WPA mode
4313 if (pBss
->AuthMode
== Ndis802_11AuthModeOpen
)
4314 pBss
->AuthMode
= Ndis802_11AuthModeWPA2
;
4316 pBss
->AuthModeAux
= Ndis802_11AuthModeWPA2
;
4319 // Set AP support WPA mode
4320 if (pBss
->AuthMode
== Ndis802_11AuthModeOpen
)
4321 pBss
->AuthMode
= Ndis802_11AuthModeWPA2PSK
;
4323 pBss
->AuthModeAux
= Ndis802_11AuthModeWPA2PSK
;
4328 pTmp
+= (Count
* sizeof(AKM_SUITE_STRUCT
));
4330 // Fixed for WPA-None
4331 if (pBss
->BssType
== BSS_ADHOC
)
4333 pBss
->AuthMode
= Ndis802_11AuthModeWPANone
;
4334 pBss
->AuthModeAux
= Ndis802_11AuthModeWPANone
;
4335 pBss
->WPA
.PairCipherAux
= pBss
->WPA2
.PairCipherAux
;
4336 pBss
->WPA
.GroupCipher
= pBss
->WPA2
.GroupCipher
;
4337 pBss
->WepStatus
= pBss
->WPA
.GroupCipher
;
4338 // Patched bugs for old driver
4339 if (pBss
->WPA
.PairCipherAux
== Ndis802_11WEPDisabled
)
4340 pBss
->WPA
.PairCipherAux
= pBss
->WPA
.GroupCipher
;
4342 pBss
->WepStatus
= pBss
->WPA2
.PairCipher
;
4344 // 6. Get RSN capability
4345 //pBss->WPA2.RsnCapability = *(PUSHORT) pTmp;
4346 pBss
->WPA2
.RsnCapability
= (pTmp
[1]<<8) + pTmp
[0];
4347 pTmp
+= sizeof(USHORT
);
4349 // Check the Pair & Group, if different, turn on mixed mode flag
4350 if (pBss
->WPA2
.GroupCipher
!= pBss
->WPA2
.PairCipher
)
4351 pBss
->WPA2
.bMixMode
= TRUE
;
4357 Length
-= (pEid
->Len
+ 2);
4361 // ===========================================================================================
4363 // ===========================================================================================
4365 /*! \brief generates a random mac address value for IBSS BSSID
4366 * \param Addr the bssid location
4371 VOID
MacAddrRandomBssid(
4372 IN PRTMP_ADAPTER pAd
,
4377 for (i
= 0; i
< MAC_ADDR_LEN
; i
++)
4379 pAddr
[i
] = RandomByte(pAd
);
4382 pAddr
[0] = (pAddr
[0] & 0xfe) | 0x02; // the first 2 bits must be 01xxxxxxxx
4385 /*! \brief init the management mac frame header
4386 * \param p_hdr mac header
4387 * \param subtype subtype of the frame
4388 * \param p_ds destination address, don't care if it is a broadcast address
4390 * \pre the station has the following information in the pAd->StaCfg
4394 * \note this function initializes the following field
4396 IRQL = PASSIVE_LEVEL
4397 IRQL = DISPATCH_LEVEL
4400 VOID
MgtMacHeaderInit(
4401 IN PRTMP_ADAPTER pAd
,
4402 IN OUT PHEADER_802_11 pHdr80211
,
4408 NdisZeroMemory(pHdr80211
, sizeof(HEADER_802_11
));
4410 pHdr80211
->FC
.Type
= BTYPE_MGMT
;
4411 pHdr80211
->FC
.SubType
= SubType
;
4412 // if (SubType == SUBTYPE_ACK) // sample, no use, it will conflict with ACTION frame sub type
4413 // pHdr80211->FC.Type = BTYPE_CNTL;
4414 pHdr80211
->FC
.ToDs
= ToDs
;
4415 COPY_MAC_ADDR(pHdr80211
->Addr1
, pDA
);
4416 #ifdef CONFIG_STA_SUPPORT
4417 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
4418 COPY_MAC_ADDR(pHdr80211
->Addr2
, pAd
->CurrentAddress
);
4419 #endif // CONFIG_STA_SUPPORT //
4420 COPY_MAC_ADDR(pHdr80211
->Addr3
, pBssid
);
4423 // ===========================================================================================
4425 // ===========================================================================================
4427 /*!***************************************************************************
4428 * This routine build an outgoing frame, and fill all information specified
4429 * in argument list to the frame body. The actual frame size is the summation
4432 * Buffer - pointer to a pre-allocated memory segment
4433 * args - a list of <int arg_size, arg> pairs.
4434 * NOTE NOTE NOTE!!!! the last argument must be NULL, otherwise this
4435 * function will FAIL!!!
4437 * Size of the buffer
4439 * MakeOutgoingFrame(Buffer, output_length, 2, &fc, 2, &dur, 6, p_addr1, 6,p_addr2, END_OF_ARGS);
4441 IRQL = PASSIVE_LEVEL
4442 IRQL = DISPATCH_LEVEL
4444 ****************************************************************************/
4445 ULONG
MakeOutgoingFrame(
4447 OUT ULONG
*FrameLen
, ...)
4454 // calculates the total length
4456 va_start(Args
, FrameLen
);
4459 leng
= va_arg(Args
, int);
4460 if (leng
== END_OF_ARGS
)
4464 p
= va_arg(Args
, PVOID
);
4465 NdisMoveMemory(&Buffer
[TotLeng
], p
, leng
);
4466 TotLeng
= TotLeng
+ leng
;
4469 va_end(Args
); /* clean up */
4470 *FrameLen
= TotLeng
;
4474 // ===========================================================================================
4476 // ===========================================================================================
4478 /*! \brief Initialize The MLME Queue, used by MLME Functions
4479 * \param *Queue The MLME Queue
4480 * \return Always Return NDIS_STATE_SUCCESS in this implementation
4483 * \note Because this is done only once (at the init stage), no need to be locked
4485 IRQL = PASSIVE_LEVEL
4488 NDIS_STATUS
MlmeQueueInit(
4489 IN MLME_QUEUE
*Queue
)
4493 NdisAllocateSpinLock(&Queue
->Lock
);
4499 for (i
= 0; i
< MAX_LEN_OF_MLME_QUEUE
; i
++)
4501 Queue
->Entry
[i
].Occupied
= FALSE
;
4502 Queue
->Entry
[i
].MsgLen
= 0;
4503 NdisZeroMemory(Queue
->Entry
[i
].Msg
, MGMT_DMA_BUFFER_SIZE
);
4506 return NDIS_STATUS_SUCCESS
;
4509 /*! \brief Enqueue a message for other threads, if they want to send messages to MLME thread
4510 * \param *Queue The MLME Queue
4511 * \param Machine The State Machine Id
4512 * \param MsgType The Message Type
4513 * \param MsgLen The Message length
4514 * \param *Msg The message pointer
4515 * \return TRUE if enqueue is successful, FALSE if the queue is full
4518 * \note The message has to be initialized
4520 IRQL = PASSIVE_LEVEL
4521 IRQL = DISPATCH_LEVEL
4524 BOOLEAN
MlmeEnqueue(
4525 IN PRTMP_ADAPTER pAd
,
4532 MLME_QUEUE
*Queue
= (MLME_QUEUE
*)&pAd
->Mlme
.Queue
;
4534 // Do nothing if the driver is starting halt state.
4535 // This might happen when timer already been fired before cancel timer with mlmehalt
4536 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
| fRTMP_ADAPTER_NIC_NOT_EXIST
))
4539 // First check the size, it MUST not exceed the mlme queue size
4540 if (MsgLen
> MGMT_DMA_BUFFER_SIZE
)
4542 DBGPRINT_ERR(("MlmeEnqueue: msg too large, size = %ld \n", MsgLen
));
4546 if (MlmeQueueFull(Queue
))
4551 NdisAcquireSpinLock(&(Queue
->Lock
));
4555 if (Queue
->Tail
== MAX_LEN_OF_MLME_QUEUE
)
4560 Queue
->Entry
[Tail
].Wcid
= RESERVED_WCID
;
4561 Queue
->Entry
[Tail
].Occupied
= TRUE
;
4562 Queue
->Entry
[Tail
].Machine
= Machine
;
4563 Queue
->Entry
[Tail
].MsgType
= MsgType
;
4564 Queue
->Entry
[Tail
].MsgLen
= MsgLen
;
4568 NdisMoveMemory(Queue
->Entry
[Tail
].Msg
, Msg
, MsgLen
);
4571 NdisReleaseSpinLock(&(Queue
->Lock
));
4575 /*! \brief This function is used when Recv gets a MLME message
4576 * \param *Queue The MLME Queue
4577 * \param TimeStampHigh The upper 32 bit of timestamp
4578 * \param TimeStampLow The lower 32 bit of timestamp
4579 * \param Rssi The receiving RSSI strength
4580 * \param MsgLen The length of the message
4581 * \param *Msg The message pointer
4582 * \return TRUE if everything ok, FALSE otherwise (like Queue Full)
4586 IRQL = DISPATCH_LEVEL
4589 BOOLEAN
MlmeEnqueueForRecv(
4590 IN PRTMP_ADAPTER pAd
,
4592 IN ULONG TimeStampHigh
,
4593 IN ULONG TimeStampLow
,
4602 PFRAME_802_11 pFrame
= (PFRAME_802_11
)Msg
;
4604 MLME_QUEUE
*Queue
= (MLME_QUEUE
*)&pAd
->Mlme
.Queue
;
4606 // Do nothing if the driver is starting halt state.
4607 // This might happen when timer already been fired before cancel timer with mlmehalt
4608 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
| fRTMP_ADAPTER_NIC_NOT_EXIST
))
4610 DBGPRINT_ERR(("MlmeEnqueueForRecv: fRTMP_ADAPTER_HALT_IN_PROGRESS\n"));
4614 // First check the size, it MUST not exceed the mlme queue size
4615 if (MsgLen
> MGMT_DMA_BUFFER_SIZE
)
4617 DBGPRINT_ERR(("MlmeEnqueueForRecv: frame too large, size = %ld \n", MsgLen
));
4621 if (MlmeQueueFull(Queue
))
4626 #ifdef CONFIG_STA_SUPPORT
4627 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
4629 if (!MsgTypeSubst(pAd
, pFrame
, &Machine
, &MsgType
))
4631 DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n",pFrame
->Hdr
.FC
.SubType
));
4635 #endif // CONFIG_STA_SUPPORT //
4637 // OK, we got all the informations, it is time to put things into queue
4638 NdisAcquireSpinLock(&(Queue
->Lock
));
4642 if (Queue
->Tail
== MAX_LEN_OF_MLME_QUEUE
)
4646 Queue
->Entry
[Tail
].Occupied
= TRUE
;
4647 Queue
->Entry
[Tail
].Machine
= Machine
;
4648 Queue
->Entry
[Tail
].MsgType
= MsgType
;
4649 Queue
->Entry
[Tail
].MsgLen
= MsgLen
;
4650 Queue
->Entry
[Tail
].TimeStamp
.u
.LowPart
= TimeStampLow
;
4651 Queue
->Entry
[Tail
].TimeStamp
.u
.HighPart
= TimeStampHigh
;
4652 Queue
->Entry
[Tail
].Rssi0
= Rssi0
;
4653 Queue
->Entry
[Tail
].Rssi1
= Rssi1
;
4654 Queue
->Entry
[Tail
].Rssi2
= Rssi2
;
4655 Queue
->Entry
[Tail
].Signal
= Signal
;
4656 Queue
->Entry
[Tail
].Wcid
= (UCHAR
)Wcid
;
4658 Queue
->Entry
[Tail
].Channel
= pAd
->LatchRfRegs
.Channel
;
4662 NdisMoveMemory(Queue
->Entry
[Tail
].Msg
, Msg
, MsgLen
);
4665 NdisReleaseSpinLock(&(Queue
->Lock
));
4667 RT28XX_MLME_HANDLER(pAd
);
4673 /*! \brief Dequeue a message from the MLME Queue
4674 * \param *Queue The MLME Queue
4675 * \param *Elem The message dequeued from MLME Queue
4676 * \return TRUE if the Elem contains something, FALSE otherwise
4680 IRQL = DISPATCH_LEVEL
4683 BOOLEAN
MlmeDequeue(
4684 IN MLME_QUEUE
*Queue
,
4685 OUT MLME_QUEUE_ELEM
**Elem
)
4687 NdisAcquireSpinLock(&(Queue
->Lock
));
4688 *Elem
= &(Queue
->Entry
[Queue
->Head
]);
4691 if (Queue
->Head
== MAX_LEN_OF_MLME_QUEUE
)
4695 NdisReleaseSpinLock(&(Queue
->Lock
));
4699 // IRQL = DISPATCH_LEVEL
4700 VOID
MlmeRestartStateMachine(
4701 IN PRTMP_ADAPTER pAd
)
4703 #ifdef CONFIG_STA_SUPPORT
4705 #endif // CONFIG_STA_SUPPORT //
4707 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeRestartStateMachine \n"));
4710 #ifdef CONFIG_STA_SUPPORT
4711 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
4713 // Cancel all timer events
4714 // Be careful to cancel new added timer
4715 RTMPCancelTimer(&pAd
->MlmeAux
.AssocTimer
, &Cancelled
);
4716 RTMPCancelTimer(&pAd
->MlmeAux
.ReassocTimer
, &Cancelled
);
4717 RTMPCancelTimer(&pAd
->MlmeAux
.DisassocTimer
, &Cancelled
);
4718 RTMPCancelTimer(&pAd
->MlmeAux
.AuthTimer
, &Cancelled
);
4719 RTMPCancelTimer(&pAd
->MlmeAux
.BeaconTimer
, &Cancelled
);
4720 RTMPCancelTimer(&pAd
->MlmeAux
.ScanTimer
, &Cancelled
);
4722 #endif // CONFIG_STA_SUPPORT //
4724 // Change back to original channel in case of doing scan
4725 AsicSwitchChannel(pAd
, pAd
->CommonCfg
.Channel
, FALSE
);
4726 AsicLockChannel(pAd
, pAd
->CommonCfg
.Channel
);
4728 // Resume MSDU which is turned off durning scan
4729 RTMPResumeMsduTransmission(pAd
);
4731 #ifdef CONFIG_STA_SUPPORT
4732 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
4734 // Set all state machines back IDLE
4735 pAd
->Mlme
.CntlMachine
.CurrState
= CNTL_IDLE
;
4736 pAd
->Mlme
.AssocMachine
.CurrState
= ASSOC_IDLE
;
4737 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
4738 pAd
->Mlme
.AuthRspMachine
.CurrState
= AUTH_RSP_IDLE
;
4739 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
4740 pAd
->Mlme
.ActMachine
.CurrState
= ACT_IDLE
;
4742 #endif // CONFIG_STA_SUPPORT //
4746 /*! \brief test if the MLME Queue is empty
4747 * \param *Queue The MLME Queue
4748 * \return TRUE if the Queue is empty, FALSE otherwise
4752 IRQL = DISPATCH_LEVEL
4755 BOOLEAN
MlmeQueueEmpty(
4756 IN MLME_QUEUE
*Queue
)
4760 NdisAcquireSpinLock(&(Queue
->Lock
));
4761 Ans
= (Queue
->Num
== 0);
4762 NdisReleaseSpinLock(&(Queue
->Lock
));
4767 /*! \brief test if the MLME Queue is full
4768 * \param *Queue The MLME Queue
4769 * \return TRUE if the Queue is empty, FALSE otherwise
4773 IRQL = PASSIVE_LEVEL
4774 IRQL = DISPATCH_LEVEL
4777 BOOLEAN
MlmeQueueFull(
4778 IN MLME_QUEUE
*Queue
)
4782 NdisAcquireSpinLock(&(Queue
->Lock
));
4783 Ans
= (Queue
->Num
== MAX_LEN_OF_MLME_QUEUE
|| Queue
->Entry
[Queue
->Tail
].Occupied
);
4784 NdisReleaseSpinLock(&(Queue
->Lock
));
4789 /*! \brief The destructor of MLME Queue
4794 * \note Clear Mlme Queue, Set Queue->Num to Zero.
4796 IRQL = PASSIVE_LEVEL
4799 VOID
MlmeQueueDestroy(
4800 IN MLME_QUEUE
*pQueue
)
4802 NdisAcquireSpinLock(&(pQueue
->Lock
));
4806 NdisReleaseSpinLock(&(pQueue
->Lock
));
4807 NdisFreeSpinLock(&(pQueue
->Lock
));
4810 /*! \brief To substitute the message type if the message is coming from external
4811 * \param pFrame The frame received
4812 * \param *Machine The state machine
4813 * \param *MsgType the message type for the state machine
4814 * \return TRUE if the substitution is successful, FALSE otherwise
4818 IRQL = DISPATCH_LEVEL
4821 #ifdef CONFIG_STA_SUPPORT
4822 BOOLEAN
MsgTypeSubst(
4823 IN PRTMP_ADAPTER pAd
,
4824 IN PFRAME_802_11 pFrame
,
4832 // Pointer to start of data frames including SNAP header
4833 pData
= (PUCHAR
) pFrame
+ LENGTH_802_11
;
4835 // The only data type will pass to this function is EAPOL frame
4836 if (pFrame
->Hdr
.FC
.Type
== BTYPE_DATA
)
4838 if (NdisEqualMemory(SNAP_AIRONET
, pData
, LENGTH_802_1_H
))
4840 // Cisco Aironet SNAP header
4841 *Machine
= AIRONET_STATE_MACHINE
;
4842 *MsgType
= MT2_AIRONET_MSG
;
4846 *Machine
= WPA_PSK_STATE_MACHINE
;
4847 EAPType
= *((UCHAR
*)pFrame
+ LENGTH_802_11
+ LENGTH_802_1_H
+ 1);
4848 return(WpaMsgTypeSubst(EAPType
, MsgType
));
4852 switch (pFrame
->Hdr
.FC
.SubType
)
4854 case SUBTYPE_ASSOC_REQ
:
4855 *Machine
= ASSOC_STATE_MACHINE
;
4856 *MsgType
= MT2_PEER_ASSOC_REQ
;
4858 case SUBTYPE_ASSOC_RSP
:
4859 *Machine
= ASSOC_STATE_MACHINE
;
4860 *MsgType
= MT2_PEER_ASSOC_RSP
;
4862 case SUBTYPE_REASSOC_REQ
:
4863 *Machine
= ASSOC_STATE_MACHINE
;
4864 *MsgType
= MT2_PEER_REASSOC_REQ
;
4866 case SUBTYPE_REASSOC_RSP
:
4867 *Machine
= ASSOC_STATE_MACHINE
;
4868 *MsgType
= MT2_PEER_REASSOC_RSP
;
4870 case SUBTYPE_PROBE_REQ
:
4871 *Machine
= SYNC_STATE_MACHINE
;
4872 *MsgType
= MT2_PEER_PROBE_REQ
;
4874 case SUBTYPE_PROBE_RSP
:
4875 *Machine
= SYNC_STATE_MACHINE
;
4876 *MsgType
= MT2_PEER_PROBE_RSP
;
4878 case SUBTYPE_BEACON
:
4879 *Machine
= SYNC_STATE_MACHINE
;
4880 *MsgType
= MT2_PEER_BEACON
;
4883 *Machine
= SYNC_STATE_MACHINE
;
4884 *MsgType
= MT2_PEER_ATIM
;
4886 case SUBTYPE_DISASSOC
:
4887 *Machine
= ASSOC_STATE_MACHINE
;
4888 *MsgType
= MT2_PEER_DISASSOC_REQ
;
4891 // get the sequence number from payload 24 Mac Header + 2 bytes algorithm
4892 NdisMoveMemory(&Seq
, &pFrame
->Octet
[2], sizeof(USHORT
));
4893 if (Seq
== 1 || Seq
== 3)
4895 *Machine
= AUTH_RSP_STATE_MACHINE
;
4896 *MsgType
= MT2_PEER_AUTH_ODD
;
4898 else if (Seq
== 2 || Seq
== 4)
4900 *Machine
= AUTH_STATE_MACHINE
;
4901 *MsgType
= MT2_PEER_AUTH_EVEN
;
4908 case SUBTYPE_DEAUTH
:
4909 *Machine
= AUTH_RSP_STATE_MACHINE
;
4910 *MsgType
= MT2_PEER_DEAUTH
;
4912 case SUBTYPE_ACTION
:
4913 *Machine
= ACTION_STATE_MACHINE
;
4914 // Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support
4915 if ((pFrame
->Octet
[0]&0x7F) > MAX_PEER_CATE_MSG
)
4917 *MsgType
= MT2_ACT_INVALID
;
4921 *MsgType
= (pFrame
->Octet
[0]&0x7F);
4931 #endif // CONFIG_STA_SUPPORT //
4933 // ===========================================================================================
4935 // ===========================================================================================
4937 /*! \brief Initialize the state machine.
4938 * \param *S pointer to the state machine
4939 * \param Trans State machine transition function
4940 * \param StNr number of states
4941 * \param MsgNr number of messages
4942 * \param DefFunc default function, when there is invalid state/message combination
4943 * \param InitState initial state of the state machine
4944 * \param Base StateMachine base, internal use only
4945 * \pre p_sm should be a legal pointer
4948 IRQL = PASSIVE_LEVEL
4951 VOID
StateMachineInit(
4952 IN STATE_MACHINE
*S
,
4953 IN STATE_MACHINE_FUNC Trans
[],
4956 IN STATE_MACHINE_FUNC DefFunc
,
4962 // set number of states and messages
4967 S
->TransFunc
= Trans
;
4969 // init all state transition to default function
4970 for (i
= 0; i
< StNr
; i
++)
4972 for (j
= 0; j
< MsgNr
; j
++)
4974 S
->TransFunc
[i
* MsgNr
+ j
] = DefFunc
;
4978 // set the starting state
4979 S
->CurrState
= InitState
;
4982 /*! \brief This function fills in the function pointer into the cell in the state machine
4983 * \param *S pointer to the state machine
4985 * \param Msg incoming message
4986 * \param f the function to be executed when (state, message) combination occurs at the state machine
4987 * \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
4990 IRQL = PASSIVE_LEVEL
4993 VOID
StateMachineSetAction(
4994 IN STATE_MACHINE
*S
,
4997 IN STATE_MACHINE_FUNC Func
)
5001 MsgIdx
= Msg
- S
->Base
;
5003 if (St
< S
->NrState
&& MsgIdx
< S
->NrMsg
)
5005 // boundary checking before setting the action
5006 S
->TransFunc
[St
* S
->NrMsg
+ MsgIdx
] = Func
;
5010 /*! \brief This function does the state transition
5011 * \param *Adapter the NIC adapter pointer
5012 * \param *S the state machine
5013 * \param *Elem the message to be executed
5016 IRQL = DISPATCH_LEVEL
5019 VOID
StateMachinePerformAction(
5020 IN PRTMP_ADAPTER pAd
,
5021 IN STATE_MACHINE
*S
,
5022 IN MLME_QUEUE_ELEM
*Elem
)
5024 (*(S
->TransFunc
[S
->CurrState
* S
->NrMsg
+ Elem
->MsgType
- S
->Base
]))(pAd
, Elem
);
5028 ==========================================================================
5030 The drop function, when machine executes this, the message is simply
5031 ignored. This function does nothing, the message is freed in
5032 StateMachinePerformAction()
5033 ==========================================================================
5036 IN PRTMP_ADAPTER pAd
,
5037 IN MLME_QUEUE_ELEM
*Elem
)
5041 // ===========================================================================================
5043 // ===========================================================================================
5046 ==========================================================================
5049 IRQL = PASSIVE_LEVEL
5051 ==========================================================================
5054 IN PRTMP_ADAPTER pAd
,
5058 pAd
->Mlme
.ShiftReg
= 1;
5060 pAd
->Mlme
.ShiftReg
= Seed
;
5064 ==========================================================================
5066 ==========================================================================
5069 IN PRTMP_ADAPTER pAd
)
5076 if (pAd
->Mlme
.ShiftReg
== 0)
5077 NdisGetSystemUpTime((ULONG
*)&pAd
->Mlme
.ShiftReg
);
5079 for (i
= 0; i
< 8; i
++)
5081 if (pAd
->Mlme
.ShiftReg
& 0x00000001)
5083 pAd
->Mlme
.ShiftReg
= ((pAd
->Mlme
.ShiftReg
^ LFSR_MASK
) >> 1) | 0x80000000;
5088 pAd
->Mlme
.ShiftReg
= pAd
->Mlme
.ShiftReg
>> 1;
5091 R
= (R
<< 1) | Result
;
5097 VOID
AsicUpdateAutoFallBackTable(
5098 IN PRTMP_ADAPTER pAd
,
5099 IN PUCHAR pRateTable
)
5102 HT_FBK_CFG0_STRUC HtCfg0
;
5103 HT_FBK_CFG1_STRUC HtCfg1
;
5104 LG_FBK_CFG0_STRUC LgCfg0
;
5105 LG_FBK_CFG1_STRUC LgCfg1
;
5106 PRTMP_TX_RATE_SWITCH pCurrTxRate
, pNextTxRate
;
5108 // set to initial value
5109 HtCfg0
.word
= 0x65432100;
5110 HtCfg1
.word
= 0xedcba988;
5111 LgCfg0
.word
= 0xedcba988;
5112 LgCfg1
.word
= 0x00002100;
5114 pNextTxRate
= (PRTMP_TX_RATE_SWITCH
)pRateTable
+1;
5115 for (i
= 1; i
< *((PUCHAR
) pRateTable
); i
++)
5117 pCurrTxRate
= (PRTMP_TX_RATE_SWITCH
)pRateTable
+1+i
;
5118 switch (pCurrTxRate
->Mode
)
5124 switch(pCurrTxRate
->CurrMCS
)
5127 LgCfg0
.field
.OFDMMCS0FBK
= (pNextTxRate
->Mode
== MODE_OFDM
) ? (pNextTxRate
->CurrMCS
+8): pNextTxRate
->CurrMCS
;
5130 LgCfg0
.field
.OFDMMCS1FBK
= (pNextTxRate
->Mode
== MODE_OFDM
) ? (pNextTxRate
->CurrMCS
+8): pNextTxRate
->CurrMCS
;
5133 LgCfg0
.field
.OFDMMCS2FBK
= (pNextTxRate
->Mode
== MODE_OFDM
) ? (pNextTxRate
->CurrMCS
+8): pNextTxRate
->CurrMCS
;
5136 LgCfg0
.field
.OFDMMCS3FBK
= (pNextTxRate
->Mode
== MODE_OFDM
) ? (pNextTxRate
->CurrMCS
+8): pNextTxRate
->CurrMCS
;
5139 LgCfg0
.field
.OFDMMCS4FBK
= (pNextTxRate
->Mode
== MODE_OFDM
) ? (pNextTxRate
->CurrMCS
+8): pNextTxRate
->CurrMCS
;
5142 LgCfg0
.field
.OFDMMCS5FBK
= (pNextTxRate
->Mode
== MODE_OFDM
) ? (pNextTxRate
->CurrMCS
+8): pNextTxRate
->CurrMCS
;
5145 LgCfg0
.field
.OFDMMCS6FBK
= (pNextTxRate
->Mode
== MODE_OFDM
) ? (pNextTxRate
->CurrMCS
+8): pNextTxRate
->CurrMCS
;
5148 LgCfg0
.field
.OFDMMCS7FBK
= (pNextTxRate
->Mode
== MODE_OFDM
) ? (pNextTxRate
->CurrMCS
+8): pNextTxRate
->CurrMCS
;
5153 #ifdef DOT11_N_SUPPORT
5157 if ((pNextTxRate
->Mode
>= MODE_HTMIX
) && (pCurrTxRate
->CurrMCS
!= pNextTxRate
->CurrMCS
))
5159 switch(pCurrTxRate
->CurrMCS
)
5162 HtCfg0
.field
.HTMCS0FBK
= pNextTxRate
->CurrMCS
;
5165 HtCfg0
.field
.HTMCS1FBK
= pNextTxRate
->CurrMCS
;
5168 HtCfg0
.field
.HTMCS2FBK
= pNextTxRate
->CurrMCS
;
5171 HtCfg0
.field
.HTMCS3FBK
= pNextTxRate
->CurrMCS
;
5174 HtCfg0
.field
.HTMCS4FBK
= pNextTxRate
->CurrMCS
;
5177 HtCfg0
.field
.HTMCS5FBK
= pNextTxRate
->CurrMCS
;
5180 HtCfg0
.field
.HTMCS6FBK
= pNextTxRate
->CurrMCS
;
5183 HtCfg0
.field
.HTMCS7FBK
= pNextTxRate
->CurrMCS
;
5186 HtCfg1
.field
.HTMCS8FBK
= pNextTxRate
->CurrMCS
;
5189 HtCfg1
.field
.HTMCS9FBK
= pNextTxRate
->CurrMCS
;
5192 HtCfg1
.field
.HTMCS10FBK
= pNextTxRate
->CurrMCS
;
5195 HtCfg1
.field
.HTMCS11FBK
= pNextTxRate
->CurrMCS
;
5198 HtCfg1
.field
.HTMCS12FBK
= pNextTxRate
->CurrMCS
;
5201 HtCfg1
.field
.HTMCS13FBK
= pNextTxRate
->CurrMCS
;
5204 HtCfg1
.field
.HTMCS14FBK
= pNextTxRate
->CurrMCS
;
5207 HtCfg1
.field
.HTMCS15FBK
= pNextTxRate
->CurrMCS
;
5210 DBGPRINT(RT_DEBUG_ERROR
, ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n", pCurrTxRate
->CurrMCS
));
5215 #endif // DOT11_N_SUPPORT //
5218 pNextTxRate
= pCurrTxRate
;
5221 RTMP_IO_WRITE32(pAd
, HT_FBK_CFG0
, HtCfg0
.word
);
5222 RTMP_IO_WRITE32(pAd
, HT_FBK_CFG1
, HtCfg1
.word
);
5223 RTMP_IO_WRITE32(pAd
, LG_FBK_CFG0
, LgCfg0
.word
);
5224 RTMP_IO_WRITE32(pAd
, LG_FBK_CFG1
, LgCfg1
.word
);
5228 ========================================================================
5230 Routine Description:
5231 Set MAC register value according operation mode.
5232 OperationMode AND bNonGFExist are for MM and GF Proteciton.
5233 If MM or GF mask is not set, those passing argument doesn't not take effect.
5235 Operation mode meaning:
5236 = 0 : Pure HT, no preotection.
5237 = 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS.
5238 = 0x10: No Transmission in 40M is protected.
5239 = 0x11: Transmission in both 40M and 20M shall be protected
5241 we should choose not to use GF. But still set correct ASIC registers.
5242 ========================================================================
5244 VOID
AsicUpdateProtect(
5245 IN PRTMP_ADAPTER pAd
,
5246 IN USHORT OperationMode
,
5248 IN BOOLEAN bDisableBGProtect
,
5249 IN BOOLEAN bNonGFExist
)
5251 PROT_CFG_STRUC ProtCfg
, ProtCfg4
;
5257 #ifdef DOT11_N_SUPPORT
5258 if (!(pAd
->CommonCfg
.bHTProtect
) && (OperationMode
!= 8))
5263 if (pAd
->BATable
.numAsOriginator
)
5266 // enable the RTS/CTS to avoid channel collision
5268 SetMask
= ALLN_SETPROTECT
;
5271 #endif // DOT11_N_SUPPORT //
5273 // Config ASIC RTS threshold register
5274 RTMP_IO_READ32(pAd
, TX_RTS_CFG
, &MacReg
);
5275 MacReg
&= 0xFF0000FF;
5277 MacReg
|= (pAd
->CommonCfg
.RtsThreshold
<< 8);
5279 // If the user want disable RtsThreshold and enable Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096
5281 #ifdef DOT11_N_SUPPORT
5282 (pAd
->CommonCfg
.BACapability
.field
.AmsduEnable
) ||
5283 #endif // DOT11_N_SUPPORT //
5284 (pAd
->CommonCfg
.bAggregationCapable
== TRUE
))
5285 && pAd
->CommonCfg
.RtsThreshold
== MAX_RTS_THRESHOLD
)
5287 MacReg
|= (0x1000 << 8);
5291 MacReg
|= (pAd
->CommonCfg
.RtsThreshold
<< 8);
5295 RTMP_IO_WRITE32(pAd
, TX_RTS_CFG
, MacReg
);
5297 // Initial common protection settings
5298 RTMPZeroMemory(Protect
, sizeof(Protect
));
5301 ProtCfg
.field
.TxopAllowGF40
= 1;
5302 ProtCfg
.field
.TxopAllowGF20
= 1;
5303 ProtCfg
.field
.TxopAllowMM40
= 1;
5304 ProtCfg
.field
.TxopAllowMM20
= 1;
5305 ProtCfg
.field
.TxopAllowOfdm
= 1;
5306 ProtCfg
.field
.TxopAllowCck
= 1;
5307 ProtCfg
.field
.RTSThEn
= 1;
5308 ProtCfg
.field
.ProtectNav
= ASIC_SHORTNAV
;
5310 // update PHY mode and rate
5311 if (pAd
->CommonCfg
.Channel
> 14)
5312 ProtCfg
.field
.ProtectRate
= 0x4000;
5313 ProtCfg
.field
.ProtectRate
|= pAd
->CommonCfg
.RtsRate
;
5315 // Handle legacy(B/G) protection
5316 if (bDisableBGProtect
)
5318 //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
5319 ProtCfg
.field
.ProtectCtrl
= 0;
5320 Protect
[0] = ProtCfg
.word
;
5321 Protect
[1] = ProtCfg
.word
;
5325 //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
5326 ProtCfg
.field
.ProtectCtrl
= 0; // CCK do not need to be protected
5327 Protect
[0] = ProtCfg
.word
;
5328 ProtCfg
.field
.ProtectCtrl
= ASIC_CTS
; // OFDM needs using CCK to protect
5329 Protect
[1] = ProtCfg
.word
;
5332 #ifdef DOT11_N_SUPPORT
5333 // Decide HT frame protection.
5334 if ((SetMask
& ALLN_SETPROTECT
) != 0)
5336 switch(OperationMode
)
5340 // 1.All STAs in the BSS are 20/40 MHz HT
5341 // 2. in ai 20/40MHz BSS
5342 // 3. all STAs are 20MHz in a 20MHz BSS
5343 // Pure HT. no protection.
5347 // PROT_TXOP(25:20) -- 010111
5348 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5349 // PROT_CTRL(17:16) -- 00 (None)
5350 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
5351 Protect
[2] = 0x01744004;
5355 // PROT_TXOP(25:20) -- 111111
5356 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5357 // PROT_CTRL(17:16) -- 00 (None)
5358 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
5359 Protect
[3] = 0x03f44084;
5363 // PROT_TXOP(25:20) -- 010111
5364 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5365 // PROT_CTRL(17:16) -- 00 (None)
5366 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
5367 Protect
[4] = 0x01744004;
5371 // PROT_TXOP(25:20) -- 111111
5372 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5373 // PROT_CTRL(17:16) -- 00 (None)
5374 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
5375 Protect
[5] = 0x03f44084;
5379 // PROT_NAV(19:18) -- 01 (Short NAV protectiion)
5380 // PROT_CTRL(17:16) -- 01 (RTS/CTS)
5381 Protect
[4] = 0x01754004;
5382 Protect
[5] = 0x03f54084;
5384 pAd
->CommonCfg
.IOTestParm
.bRTSLongProtOn
= FALSE
;
5388 // This is "HT non-member protection mode."
5389 // If there may be non-HT STAs my BSS
5390 ProtCfg
.word
= 0x01744004; // PROT_CTRL(17:16) : 0 (None)
5391 ProtCfg4
.word
= 0x03f44084; // duplicaet legacy 24M. BW set 1.
5392 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_BG_PROTECTION_INUSED
))
5394 ProtCfg
.word
= 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
5395 ProtCfg4
.word
= 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083;
5397 //Assign Protection method for 20&40 MHz packets
5398 ProtCfg
.field
.ProtectCtrl
= ASIC_RTS
;
5399 ProtCfg
.field
.ProtectNav
= ASIC_SHORTNAV
;
5400 ProtCfg4
.field
.ProtectCtrl
= ASIC_RTS
;
5401 ProtCfg4
.field
.ProtectNav
= ASIC_SHORTNAV
;
5402 Protect
[2] = ProtCfg
.word
;
5403 Protect
[3] = ProtCfg4
.word
;
5404 Protect
[4] = ProtCfg
.word
;
5405 Protect
[5] = ProtCfg4
.word
;
5406 pAd
->CommonCfg
.IOTestParm
.bRTSLongProtOn
= TRUE
;
5410 // If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets
5411 ProtCfg
.word
= 0x01744004; // PROT_CTRL(17:16) : 0 (None)
5412 ProtCfg4
.word
= 0x03f44084; // duplicaet legacy 24M. BW set 1.
5414 //Assign Protection method for 40MHz packets
5415 ProtCfg4
.field
.ProtectCtrl
= ASIC_RTS
;
5416 ProtCfg4
.field
.ProtectNav
= ASIC_SHORTNAV
;
5417 Protect
[2] = ProtCfg
.word
;
5418 Protect
[3] = ProtCfg4
.word
;
5421 ProtCfg
.field
.ProtectCtrl
= ASIC_RTS
;
5422 ProtCfg
.field
.ProtectNav
= ASIC_SHORTNAV
;
5424 Protect
[4] = ProtCfg
.word
;
5425 Protect
[5] = ProtCfg4
.word
;
5427 pAd
->CommonCfg
.IOTestParm
.bRTSLongProtOn
= FALSE
;
5431 // HT mixed mode. PROTECT ALL!
5433 ProtCfg
.word
= 0x01744004; //duplicaet legacy 24M. BW set 1.
5434 ProtCfg4
.word
= 0x03f44084;
5435 // both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the
5436 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_BG_PROTECTION_INUSED
))
5438 ProtCfg
.word
= 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
5439 ProtCfg4
.word
= 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083
5441 //Assign Protection method for 20&40 MHz packets
5442 ProtCfg
.field
.ProtectCtrl
= ASIC_RTS
;
5443 ProtCfg
.field
.ProtectNav
= ASIC_SHORTNAV
;
5444 ProtCfg4
.field
.ProtectCtrl
= ASIC_RTS
;
5445 ProtCfg4
.field
.ProtectNav
= ASIC_SHORTNAV
;
5446 Protect
[2] = ProtCfg
.word
;
5447 Protect
[3] = ProtCfg4
.word
;
5448 Protect
[4] = ProtCfg
.word
;
5449 Protect
[5] = ProtCfg4
.word
;
5450 pAd
->CommonCfg
.IOTestParm
.bRTSLongProtOn
= TRUE
;
5454 // Special on for Atheros problem n chip.
5455 Protect
[2] = 0x01754004;
5456 Protect
[3] = 0x03f54084;
5457 Protect
[4] = 0x01754004;
5458 Protect
[5] = 0x03f54084;
5459 pAd
->CommonCfg
.IOTestParm
.bRTSLongProtOn
= TRUE
;
5463 #endif // DOT11_N_SUPPORT //
5465 offset
= CCK_PROT_CFG
;
5466 for (i
= 0;i
< 6;i
++)
5468 if ((SetMask
& (1<< i
)))
5470 RTMP_IO_WRITE32(pAd
, offset
+ i
*4, Protect
[i
]);
5476 ==========================================================================
5479 IRQL = PASSIVE_LEVEL
5480 IRQL = DISPATCH_LEVEL
5482 ==========================================================================
5484 VOID
AsicSwitchChannel(
5485 IN PRTMP_ADAPTER pAd
,
5489 ULONG R2
= 0, R3
= DEFAULT_RF_TX_POWER
, R4
= 0;
5490 CHAR TxPwer
= 0, TxPwer2
= DEFAULT_RF_TX_POWER
; //Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER;
5492 UINT32 Value
= 0; //BbpReg, Value;
5493 RTMP_RF_REGS
*RFRegTable
;
5495 // Search Tx power value
5496 for (index
= 0; index
< pAd
->ChannelListNum
; index
++)
5498 if (Channel
== pAd
->ChannelList
[index
].Channel
)
5500 TxPwer
= pAd
->ChannelList
[index
].Power
;
5501 TxPwer2
= pAd
->ChannelList
[index
].Power2
;
5506 if (index
== MAX_NUM_OF_CHANNELS
)
5508 DBGPRINT(RT_DEBUG_ERROR
, ("AsicSwitchChannel: Cant find the Channel#%d \n", Channel
));
5512 // The RF programming sequence is difference between 3xxx and 2xxx
5513 if (IS_RT3070(pAd
) && ((pAd
->RfIcType
== RFIC_3020
) || (pAd
->RfIcType
== RFIC_2020
)))
5515 /* modify by WY for Read RF Reg. error */
5518 for (index
= 0; index
< NUM_OF_3020_CHNL
; index
++)
5520 if (Channel
== FreqItems3020
[index
].Channel
)
5522 // Programming channel parameters
5523 RT30xxWriteRFRegister(pAd
, RF_R02
, FreqItems3020
[index
].N
);
5524 RT30xxWriteRFRegister(pAd
, RF_R03
, FreqItems3020
[index
].K
);
5526 RT30xxReadRFRegister(pAd
, RF_R06
, (PUCHAR
)&RFValue
);
5527 RFValue
= (RFValue
& 0xFC) | FreqItems3020
[index
].R
;
5528 RT30xxWriteRFRegister(pAd
, RF_R06
, (UCHAR
)RFValue
);
5531 RT30xxReadRFRegister(pAd
, RF_R12
, (PUCHAR
)&RFValue
);
5532 RFValue
= (RFValue
& 0xE0) | TxPwer
;
5533 RT30xxWriteRFRegister(pAd
, RF_R12
, (UCHAR
)RFValue
);
5536 RT30xxReadRFRegister(pAd
, RF_R23
, (PUCHAR
)&RFValue
);
5537 RFValue
= (RFValue
& 0x80) | pAd
->RfFreqOffset
;
5538 RT30xxWriteRFRegister(pAd
, RF_R23
, (UCHAR
)RFValue
);
5541 if (!bScan
&& (pAd
->CommonCfg
.BBPCurrentBW
== BW_40
))
5543 RFValue
= pAd
->Mlme
.CaliBW40RfR24
;
5544 //DISABLE_11N_CHECK(pAd);
5548 RFValue
= pAd
->Mlme
.CaliBW20RfR24
;
5550 RT30xxWriteRFRegister(pAd
, RF_R24
, (UCHAR
)RFValue
);
5553 RT30xxReadRFRegister(pAd
, RF_R07
, (PUCHAR
)&RFValue
);
5554 RFValue
= RFValue
| 0x1;
5555 RT30xxWriteRFRegister(pAd
, RF_R07
, (UCHAR
)RFValue
);
5557 // latch channel for future usage.
5558 pAd
->LatchRfRegs
.Channel
= Channel
;
5564 DBGPRINT(RT_DEBUG_TRACE
, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
5569 pAd
->Antenna
.field
.TxPath
,
5570 FreqItems3020
[index
].N
,
5571 FreqItems3020
[index
].K
,
5572 FreqItems3020
[index
].R
));
5577 RFRegTable
= RF2850RegTable
;
5579 switch (pAd
->RfIcType
)
5586 for (index
= 0; index
< NUM_OF_2850_CHNL
; index
++)
5588 if (Channel
== RFRegTable
[index
].Channel
)
5590 R2
= RFRegTable
[index
].R2
;
5591 if (pAd
->Antenna
.field
.TxPath
== 1)
5593 R2
|= 0x4000; // If TXpath is 1, bit 14 = 1;
5596 if (pAd
->Antenna
.field
.RxPath
== 2)
5598 R2
|= 0x40; // write 1 to off Rxpath.
5600 else if (pAd
->Antenna
.field
.RxPath
== 1)
5602 R2
|= 0x20040; // write 1 to off RxPath
5607 // initialize R3, R4
5608 R3
= (RFRegTable
[index
].R3
& 0xffffc1ff);
5609 R4
= (RFRegTable
[index
].R4
& (~0x001f87c0)) | (pAd
->RfFreqOffset
<< 15);
5611 // 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB
5613 if ((TxPwer
>= -7) && (TxPwer
< 0))
5615 TxPwer
= (7+TxPwer
);
5616 TxPwer
= (TxPwer
> 0xF) ? (0xF) : (TxPwer
);
5617 R3
|= (TxPwer
<< 10);
5618 DBGPRINT(RT_DEBUG_ERROR
, ("AsicSwitchChannel: TxPwer=%d \n", TxPwer
));
5622 TxPwer
= (TxPwer
> 0xF) ? (0xF) : (TxPwer
);
5623 R3
|= (TxPwer
<< 10) | (1 << 9);
5627 if ((TxPwer2
>= -7) && (TxPwer2
< 0))
5629 TxPwer2
= (7+TxPwer2
);
5630 TxPwer2
= (TxPwer2
> 0xF) ? (0xF) : (TxPwer2
);
5631 R4
|= (TxPwer2
<< 7);
5632 DBGPRINT(RT_DEBUG_ERROR
, ("AsicSwitchChannel: TxPwer2=%d \n", TxPwer2
));
5636 TxPwer2
= (TxPwer2
> 0xF) ? (0xF) : (TxPwer2
);
5637 R4
|= (TxPwer2
<< 7) | (1 << 6);
5642 R3
= (RFRegTable
[index
].R3
& 0xffffc1ff) | (TxPwer
<< 9); // set TX power0
5643 R4
= (RFRegTable
[index
].R4
& (~0x001f87c0)) | (pAd
->RfFreqOffset
<< 15) | (TxPwer2
<<6);// Set freq Offset & TxPwr1
5646 // Based on BBP current mode before changing RF channel.
5647 if (!bScan
&& (pAd
->CommonCfg
.BBPCurrentBW
== BW_40
))
5653 pAd
->LatchRfRegs
.Channel
= Channel
;
5654 pAd
->LatchRfRegs
.R1
= RFRegTable
[index
].R1
;
5655 pAd
->LatchRfRegs
.R2
= R2
;
5656 pAd
->LatchRfRegs
.R3
= R3
;
5657 pAd
->LatchRfRegs
.R4
= R4
;
5659 // Set RF value 1's set R3[bit2] = [0]
5660 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R1
);
5661 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R2
);
5662 RTMP_RF_IO_WRITE32(pAd
, (pAd
->LatchRfRegs
.R3
& (~0x04)));
5663 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R4
);
5667 // Set RF value 2's set R3[bit2] = [1]
5668 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R1
);
5669 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R2
);
5670 RTMP_RF_IO_WRITE32(pAd
, (pAd
->LatchRfRegs
.R3
| 0x04));
5671 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R4
);
5675 // Set RF value 3's set R3[bit2] = [0]
5676 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R1
);
5677 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R2
);
5678 RTMP_RF_IO_WRITE32(pAd
, (pAd
->LatchRfRegs
.R3
& (~0x04)));
5679 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R4
);
5691 // Change BBP setting during siwtch from a->g, g->a
5694 ULONG TxPinCfg
= 0x00050F0A;//Gary 2007/08/09 0x050A0A
5696 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R62
, (0x37 - GET_LNA_GAIN(pAd
)));
5697 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R63
, (0x37 - GET_LNA_GAIN(pAd
)));
5698 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R64
, (0x37 - GET_LNA_GAIN(pAd
)));
5699 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.
5700 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
5702 // Rx High power VGA offset for LNA select
5703 if (pAd
->NicConfig2
.field
.ExternalLNAForG
)
5705 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R82
, 0x62);
5706 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R75
, 0x46);
5710 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R82
, 0x84);
5711 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R75
, 0x50);
5714 // 5G band selection PIN, bit1 and bit2 are complement
5715 RTMP_IO_READ32(pAd
, TX_BAND_CFG
, &Value
);
5718 RTMP_IO_WRITE32(pAd
, TX_BAND_CFG
, Value
);
5720 // Turn off unused PA or LNA when only 1T or 1R
5721 if (pAd
->Antenna
.field
.TxPath
== 1)
5723 TxPinCfg
&= 0xFFFFFFF3;
5725 if (pAd
->Antenna
.field
.RxPath
== 1)
5727 TxPinCfg
&= 0xFFFFF3FF;
5730 RTMP_IO_WRITE32(pAd
, TX_PIN_CFG
, TxPinCfg
);
5734 ULONG TxPinCfg
= 0x00050F05;//Gary 2007/8/9 0x050505
5736 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R62
, (0x37 - GET_LNA_GAIN(pAd
)));
5737 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R63
, (0x37 - GET_LNA_GAIN(pAd
)));
5738 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R64
, (0x37 - GET_LNA_GAIN(pAd
)));
5739 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.
5740 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R82
, 0xF2);
5742 // Rx High power VGA offset for LNA select
5743 if (pAd
->NicConfig2
.field
.ExternalLNAForA
)
5745 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R75
, 0x46);
5749 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R75
, 0x50);
5752 // 5G band selection PIN, bit1 and bit2 are complement
5753 RTMP_IO_READ32(pAd
, TX_BAND_CFG
, &Value
);
5756 RTMP_IO_WRITE32(pAd
, TX_BAND_CFG
, Value
);
5758 // Turn off unused PA or LNA when only 1T or 1R
5759 if (pAd
->Antenna
.field
.TxPath
== 1)
5761 TxPinCfg
&= 0xFFFFFFF3;
5763 if (pAd
->Antenna
.field
.RxPath
== 1)
5765 TxPinCfg
&= 0xFFFFF3FF;
5768 RTMP_IO_WRITE32(pAd
, TX_PIN_CFG
, TxPinCfg
);
5771 // R66 should be set according to Channel and use 20MHz when scanning
5772 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd)));
5774 RTMPSetAGCInitValue(pAd
, BW_20
);
5776 RTMPSetAGCInitValue(pAd
, pAd
->CommonCfg
.BBPCurrentBW
);
5779 // On 11A, We should delay and wait RF/BBP to be stable
5780 // and the appropriate time should be 1000 micro seconds
5781 // 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
5783 RTMPusecDelay(1000);
5785 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",
5788 (R3
& 0x00003e00) >> 9,
5789 (R4
& 0x000007c0) >> 6,
5790 pAd
->Antenna
.field
.TxPath
,
5791 pAd
->LatchRfRegs
.R1
,
5792 pAd
->LatchRfRegs
.R2
,
5793 pAd
->LatchRfRegs
.R3
,
5794 pAd
->LatchRfRegs
.R4
));
5798 ==========================================================================
5800 This function is required for 2421 only, and should not be used during
5801 site survey. It's only required after NIC decided to stay at a channel
5802 for a longer period.
5803 When this function is called, it's always after AsicSwitchChannel().
5805 IRQL = PASSIVE_LEVEL
5806 IRQL = DISPATCH_LEVEL
5808 ==========================================================================
5810 VOID
AsicLockChannel(
5811 IN PRTMP_ADAPTER pAd
,
5817 ==========================================================================
5820 IRQL = PASSIVE_LEVEL
5821 IRQL = DISPATCH_LEVEL
5823 ==========================================================================
5825 VOID
AsicAntennaSelect(
5826 IN PRTMP_ADAPTER pAd
,
5832 ========================================================================
5834 Routine Description:
5835 Antenna miscellaneous setting.
5838 pAd Pointer to our adapter
5839 BandState Indicate current Band State.
5844 IRQL <= DISPATCH_LEVEL
5847 1.) Frame End type control
5848 only valid for G only (RF_2527 & RF_2529)
5849 0: means DPDT, set BBP R4 bit 5 to 1
5850 1: means SPDT, set BBP R4 bit 5 to 0
5853 ========================================================================
5855 VOID
AsicAntennaSetting(
5856 IN PRTMP_ADAPTER pAd
,
5857 IN ABGBAND_STATE BandState
)
5861 VOID
AsicRfTuningExec(
5862 IN PVOID SystemSpecific1
,
5863 IN PVOID FunctionContext
,
5864 IN PVOID SystemSpecific2
,
5865 IN PVOID SystemSpecific3
)
5870 ==========================================================================
5872 Gives CCK TX rate 2 more dB TX power.
5873 This routine works only in LINK UP in INFRASTRUCTURE mode.
5875 calculate desired Tx power in RF R3.Tx0~5, should consider -
5876 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
5877 1. TxPowerPercentage
5878 2. auto calibration based on TSSI feedback
5879 3. extra 2 db for CCK
5880 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
5882 NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
5883 it should be called AFTER MlmeDynamicTxRatSwitching()
5884 ==========================================================================
5886 VOID
AsicAdjustTxPower(
5887 IN PRTMP_ADAPTER pAd
)
5891 BOOLEAN bAutoTxAgc
= FALSE
;
5892 UCHAR TssiRef
, *pTssiMinusBoundary
, *pTssiPlusBoundary
, TxAgcStep
;
5893 UCHAR BbpR1
= 0, BbpR49
= 0, idx
;
5894 PCHAR pTxAgcCompensate
;
5898 if (pAd
->CommonCfg
.BBPCurrentBW
== BW_40
)
5900 if (pAd
->CommonCfg
.CentralChannel
> 14)
5902 TxPwr
[0] = pAd
->Tx40MPwrCfgABand
[0];
5903 TxPwr
[1] = pAd
->Tx40MPwrCfgABand
[1];
5904 TxPwr
[2] = pAd
->Tx40MPwrCfgABand
[2];
5905 TxPwr
[3] = pAd
->Tx40MPwrCfgABand
[3];
5906 TxPwr
[4] = pAd
->Tx40MPwrCfgABand
[4];
5910 TxPwr
[0] = pAd
->Tx40MPwrCfgGBand
[0];
5911 TxPwr
[1] = pAd
->Tx40MPwrCfgGBand
[1];
5912 TxPwr
[2] = pAd
->Tx40MPwrCfgGBand
[2];
5913 TxPwr
[3] = pAd
->Tx40MPwrCfgGBand
[3];
5914 TxPwr
[4] = pAd
->Tx40MPwrCfgGBand
[4];
5919 if (pAd
->CommonCfg
.Channel
> 14)
5921 TxPwr
[0] = pAd
->Tx20MPwrCfgABand
[0];
5922 TxPwr
[1] = pAd
->Tx20MPwrCfgABand
[1];
5923 TxPwr
[2] = pAd
->Tx20MPwrCfgABand
[2];
5924 TxPwr
[3] = pAd
->Tx20MPwrCfgABand
[3];
5925 TxPwr
[4] = pAd
->Tx20MPwrCfgABand
[4];
5929 TxPwr
[0] = pAd
->Tx20MPwrCfgGBand
[0];
5930 TxPwr
[1] = pAd
->Tx20MPwrCfgGBand
[1];
5931 TxPwr
[2] = pAd
->Tx20MPwrCfgGBand
[2];
5932 TxPwr
[3] = pAd
->Tx20MPwrCfgGBand
[3];
5933 TxPwr
[4] = pAd
->Tx20MPwrCfgGBand
[4];
5937 // TX power compensation for temperature variation based on TSSI. try every 4 second
5938 if (pAd
->Mlme
.OneSecPeriodicRound
% 4 == 0)
5940 if (pAd
->CommonCfg
.Channel
<= 14)
5943 bAutoTxAgc
= pAd
->bAutoTxAgcG
;
5944 TssiRef
= pAd
->TssiRefG
;
5945 pTssiMinusBoundary
= &pAd
->TssiMinusBoundaryG
[0];
5946 pTssiPlusBoundary
= &pAd
->TssiPlusBoundaryG
[0];
5947 TxAgcStep
= pAd
->TxAgcStepG
;
5948 pTxAgcCompensate
= &pAd
->TxAgcCompensateG
;
5953 bAutoTxAgc
= pAd
->bAutoTxAgcA
;
5954 TssiRef
= pAd
->TssiRefA
;
5955 pTssiMinusBoundary
= &pAd
->TssiMinusBoundaryA
[0];
5956 pTssiPlusBoundary
= &pAd
->TssiPlusBoundaryA
[0];
5957 TxAgcStep
= pAd
->TxAgcStepA
;
5958 pTxAgcCompensate
= &pAd
->TxAgcCompensateA
;
5963 /* BbpR1 is unsigned char */
5964 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R49
, &BbpR49
);
5966 /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
5967 /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */
5968 /* step value is defined in pAd->TxAgcStepG for tx power value */
5970 /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */
5971 /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
5972 above value are examined in mass factory production */
5973 /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */
5975 /* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */
5976 /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
5977 /* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */
5979 if (BbpR49
> pTssiMinusBoundary
[1])
5981 // Reading is larger than the reference value
5982 // check for how large we need to decrease the Tx power
5983 for (idx
= 1; idx
< 5; idx
++)
5985 if (BbpR49
<= pTssiMinusBoundary
[idx
]) // Found the range
5988 // The index is the step we should decrease, idx = 0 means there is nothing to compensate
5989 // if (R3 > (ULONG) (TxAgcStep * (idx-1)))
5990 *pTxAgcCompensate
= -(TxAgcStep
* (idx
-1));
5992 // *pTxAgcCompensate = -((UCHAR)R3);
5994 DeltaPwr
+= (*pTxAgcCompensate
);
5995 DBGPRINT(RT_DEBUG_TRACE
, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
5996 BbpR49
, TssiRef
, TxAgcStep
, idx
-1));
5998 else if (BbpR49
< pTssiPlusBoundary
[1])
6000 // Reading is smaller than the reference value
6001 // check for how large we need to increase the Tx power
6002 for (idx
= 1; idx
< 5; idx
++)
6004 if (BbpR49
>= pTssiPlusBoundary
[idx
]) // Found the range
6007 // The index is the step we should increase, idx = 0 means there is nothing to compensate
6008 *pTxAgcCompensate
= TxAgcStep
* (idx
-1);
6009 DeltaPwr
+= (*pTxAgcCompensate
);
6010 DBGPRINT(RT_DEBUG_TRACE
, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
6011 BbpR49
, TssiRef
, TxAgcStep
, idx
-1));
6015 *pTxAgcCompensate
= 0;
6016 DBGPRINT(RT_DEBUG_TRACE
, (" Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
6017 BbpR49
, TssiRef
, TxAgcStep
, 0));
6023 if (pAd
->CommonCfg
.Channel
<= 14)
6025 bAutoTxAgc
= pAd
->bAutoTxAgcG
;
6026 pTxAgcCompensate
= &pAd
->TxAgcCompensateG
;
6030 bAutoTxAgc
= pAd
->bAutoTxAgcA
;
6031 pTxAgcCompensate
= &pAd
->TxAgcCompensateA
;
6035 DeltaPwr
+= (*pTxAgcCompensate
);
6038 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R1
, &BbpR1
);
6041 /* calculate delta power based on the percentage specified from UI */
6042 // E2PROM setting is calibrated for maximum TX power (i.e. 100%)
6043 // We lower TX power here according to the percentage specified from UI
6044 if (pAd
->CommonCfg
.TxPowerPercentage
== 0xffffffff) // AUTO TX POWER control
6046 else if (pAd
->CommonCfg
.TxPowerPercentage
> 90) // 91 ~ 100% & AUTO, treat as 100% in terms of mW
6048 else if (pAd
->CommonCfg
.TxPowerPercentage
> 60) // 61 ~ 90%, treat as 75% in terms of mW // DeltaPwr -= 1;
6052 else if (pAd
->CommonCfg
.TxPowerPercentage
> 30) // 31 ~ 60%, treat as 50% in terms of mW // DeltaPwr -= 3;
6056 else if (pAd
->CommonCfg
.TxPowerPercentage
> 15) // 16 ~ 30%, treat as 25% in terms of mW // DeltaPwr -= 6;
6060 else if (pAd
->CommonCfg
.TxPowerPercentage
> 9) // 10 ~ 15%, treat as 12.5% in terms of mW // DeltaPwr -= 9;
6065 else // 0 ~ 9 %, treat as MIN(~3%) in terms of mW // DeltaPwr -= 12;
6070 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R1
, BbpR1
);
6072 /* reset different new tx power for different TX rate */
6075 if (TxPwr
[i
] != 0xffffffff)
6079 Value
= (CHAR
)((TxPwr
[i
] >> j
*4) & 0x0F); /* 0 ~ 15 */
6081 if ((Value
+ DeltaPwr
) < 0)
6083 Value
= 0; /* min */
6085 else if ((Value
+ DeltaPwr
) > 0xF)
6087 Value
= 0xF; /* max */
6091 Value
+= DeltaPwr
; /* temperature compensation */
6094 /* fill new value to CSR offset */
6095 TxPwr
[i
] = (TxPwr
[i
] & ~(0x0000000F << j
*4)) | (Value
<< j
*4);
6098 /* write tx power value to CSR */
6099 /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M
6100 TX power for OFDM 6M/9M
6101 TX power for CCK5.5M/11M
6102 TX power for CCK1M/2M */
6103 /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
6104 RTMP_IO_WRITE32(pAd
, TX_PWR_CFG_0
+ i
*4, TxPwr
[i
]);
6110 #ifdef CONFIG_STA_SUPPORT
6112 ==========================================================================
6114 put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup
6115 automatically. Instead, MCU will issue a TwakeUpInterrupt to host after
6116 the wakeup timer timeout. Driver has to issue a separate command to wake
6119 IRQL = DISPATCH_LEVEL
6121 ==========================================================================
6123 VOID
AsicSleepThenAutoWakeup(
6124 IN PRTMP_ADAPTER pAd
,
6125 IN USHORT TbttNumToNextWakeUp
)
6127 RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd
, TbttNumToNextWakeUp
);
6131 ==========================================================================
6133 AsicForceWakeup() is used whenever manual wakeup is required
6134 AsicForceSleep() should only be used when not in INFRA BSS. When
6135 in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead.
6136 ==========================================================================
6138 VOID
AsicForceSleep(
6139 IN PRTMP_ADAPTER pAd
)
6145 ==========================================================================
6147 AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup)
6150 IRQL = PASSIVE_LEVEL
6151 IRQL = DISPATCH_LEVEL
6152 ==========================================================================
6154 VOID
AsicForceWakeup(
6155 IN PRTMP_ADAPTER pAd
,
6158 DBGPRINT(RT_DEBUG_TRACE
, ("--> AsicForceWakeup \n"));
6159 RT28XX_STA_FORCE_WAKEUP(pAd
, bFromTx
);
6161 #endif // CONFIG_STA_SUPPORT //
6163 ==========================================================================
6167 IRQL = DISPATCH_LEVEL
6169 ==========================================================================
6172 IN PRTMP_ADAPTER pAd
,
6176 DBGPRINT(RT_DEBUG_TRACE
, ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n",
6177 pBssid
[0],pBssid
[1],pBssid
[2],pBssid
[3], pBssid
[4],pBssid
[5]));
6179 Addr4
= (ULONG
)(pBssid
[0]) |
6180 (ULONG
)(pBssid
[1] << 8) |
6181 (ULONG
)(pBssid
[2] << 16) |
6182 (ULONG
)(pBssid
[3] << 24);
6183 RTMP_IO_WRITE32(pAd
, MAC_BSSID_DW0
, Addr4
);
6186 // always one BSSID in STA mode
6187 Addr4
= (ULONG
)(pBssid
[4]) | (ULONG
)(pBssid
[5] << 8);
6189 RTMP_IO_WRITE32(pAd
, MAC_BSSID_DW1
, Addr4
);
6192 VOID
AsicSetMcastWC(
6193 IN PRTMP_ADAPTER pAd
)
6195 MAC_TABLE_ENTRY
*pEntry
= &pAd
->MacTab
.Content
[MCAST_WCID
];
6198 pEntry
->Sst
= SST_ASSOC
;
6199 pEntry
->Aid
= MCAST_WCID
; // Softap supports 1 BSSID and use WCID=0 as multicast Wcid index
6200 pEntry
->PsMode
= PWR_ACTIVE
;
6201 pEntry
->CurrTxRate
= pAd
->CommonCfg
.MlmeRate
;
6202 offset
= MAC_WCID_BASE
+ BSS0Mcast_WCID
* HW_WCID_ENTRY_SIZE
;
6206 ==========================================================================
6209 IRQL = DISPATCH_LEVEL
6211 ==========================================================================
6213 VOID
AsicDelWcidTab(
6214 IN PRTMP_ADAPTER pAd
,
6217 ULONG Addr0
= 0x0, Addr1
= 0x0;
6220 DBGPRINT(RT_DEBUG_TRACE
, ("AsicDelWcidTab==>Wcid = 0x%x\n",Wcid
));
6221 offset
= MAC_WCID_BASE
+ Wcid
* HW_WCID_ENTRY_SIZE
;
6222 RTMP_IO_WRITE32(pAd
, offset
, Addr0
);
6224 RTMP_IO_WRITE32(pAd
, offset
, Addr1
);
6228 ==========================================================================
6231 IRQL = DISPATCH_LEVEL
6233 ==========================================================================
6236 IN PRTMP_ADAPTER pAd
)
6238 TX_LINK_CFG_STRUC TxLinkCfg
;
6241 RTMP_IO_READ32(pAd
, TX_LINK_CFG
, &TxLinkCfg
.word
);
6242 TxLinkCfg
.field
.TxRDGEn
= 1;
6243 RTMP_IO_WRITE32(pAd
, TX_LINK_CFG
, TxLinkCfg
.word
);
6245 RTMP_IO_READ32(pAd
, EDCA_AC0_CFG
, &Data
);
6248 RTMP_IO_WRITE32(pAd
, EDCA_AC0_CFG
, Data
);
6250 //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
6254 ==========================================================================
6257 IRQL = DISPATCH_LEVEL
6259 ==========================================================================
6261 VOID
AsicDisableRDG(
6262 IN PRTMP_ADAPTER pAd
)
6264 TX_LINK_CFG_STRUC TxLinkCfg
;
6268 RTMP_IO_READ32(pAd
, TX_LINK_CFG
, &TxLinkCfg
.word
);
6269 TxLinkCfg
.field
.TxRDGEn
= 0;
6270 RTMP_IO_WRITE32(pAd
, TX_LINK_CFG
, TxLinkCfg
.word
);
6272 RTMP_IO_READ32(pAd
, EDCA_AC0_CFG
, &Data
);
6277 //if ( pAd->CommonCfg.bEnableTxBurst )
6278 // Data |= 0x60; // for performance issue not set the TXOP to 0
6280 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE
)
6281 #ifdef DOT11_N_SUPPORT
6282 && (pAd
->MacTab
.fAnyStationMIMOPSDynamic
== FALSE
)
6283 #endif // DOT11_N_SUPPORT //
6286 // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
6287 if (pAd
->CommonCfg
.bEnableTxBurst
)
6290 RTMP_IO_WRITE32(pAd
, EDCA_AC0_CFG
, Data
);
6294 ==========================================================================
6297 IRQL = PASSIVE_LEVEL
6298 IRQL = DISPATCH_LEVEL
6300 ==========================================================================
6302 VOID
AsicDisableSync(
6303 IN PRTMP_ADAPTER pAd
)
6305 BCN_TIME_CFG_STRUC csr
;
6307 DBGPRINT(RT_DEBUG_TRACE
, ("--->Disable TSF synchronization\n"));
6309 // 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect
6310 // that NIC will never wakes up because TSF stops and no more
6312 pAd
->TbttTickCount
= 0;
6313 RTMP_IO_READ32(pAd
, BCN_TIME_CFG
, &csr
.word
);
6314 csr
.field
.bBeaconGen
= 0;
6315 csr
.field
.bTBTTEnable
= 0;
6316 csr
.field
.TsfSyncMode
= 0;
6317 csr
.field
.bTsfTicking
= 0;
6318 RTMP_IO_WRITE32(pAd
, BCN_TIME_CFG
, csr
.word
);
6323 ==========================================================================
6326 IRQL = DISPATCH_LEVEL
6328 ==========================================================================
6330 VOID
AsicEnableBssSync(
6331 IN PRTMP_ADAPTER pAd
)
6333 BCN_TIME_CFG_STRUC csr
;
6335 DBGPRINT(RT_DEBUG_TRACE
, ("--->AsicEnableBssSync(INFRA mode)\n"));
6337 RTMP_IO_READ32(pAd
, BCN_TIME_CFG
, &csr
.word
);
6338 // RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, 0x00000000);
6339 #ifdef CONFIG_STA_SUPPORT
6340 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
6342 csr
.field
.BeaconInterval
= pAd
->CommonCfg
.BeaconPeriod
<< 4; // ASIC register in units of 1/16 TU
6343 csr
.field
.bTsfTicking
= 1;
6344 csr
.field
.TsfSyncMode
= 1; // sync TSF in INFRASTRUCTURE mode
6345 csr
.field
.bBeaconGen
= 0; // do NOT generate BEACON
6346 csr
.field
.bTBTTEnable
= 1;
6348 #endif // CONFIG_STA_SUPPORT //
6349 RTMP_IO_WRITE32(pAd
, BCN_TIME_CFG
, csr
.word
);
6353 ==========================================================================
6356 BEACON frame in shared memory should be built ok before this routine
6357 can be called. Otherwise, a garbage frame maybe transmitted out every
6360 IRQL = DISPATCH_LEVEL
6362 ==========================================================================
6364 VOID
AsicEnableIbssSync(
6365 IN PRTMP_ADAPTER pAd
)
6367 BCN_TIME_CFG_STRUC csr9
;
6371 DBGPRINT(RT_DEBUG_TRACE
, ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n", pAd
->BeaconTxWI
.MPDUtotalByteCount
));
6373 RTMP_IO_READ32(pAd
, BCN_TIME_CFG
, &csr9
.word
);
6374 csr9
.field
.bBeaconGen
= 0;
6375 csr9
.field
.bTBTTEnable
= 0;
6376 csr9
.field
.bTsfTicking
= 0;
6377 RTMP_IO_WRITE32(pAd
, BCN_TIME_CFG
, csr9
.word
);
6381 // move BEACON TXD and frame content to on-chip memory
6382 ptr
= (PUCHAR
)&pAd
->BeaconTxWI
;
6383 for (i
=0; i
<TXWI_SIZE
; i
+=2) // 16-byte TXWI field
6385 //UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
6386 //RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr);
6387 RTUSBMultiWrite(pAd
, HW_BEACON_BASE0
+ i
, ptr
, 2);
6391 // start right after the 16-byte TXWI field
6392 ptr
= pAd
->BeaconBuf
;
6393 for (i
=0; i
< pAd
->BeaconTxWI
.MPDUtotalByteCount
; i
+=2)
6395 //UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
6396 //RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
6397 RTUSBMultiWrite(pAd
, HW_BEACON_BASE0
+ TXWI_SIZE
+ i
, ptr
, 2);
6403 // For Wi-Fi faily generated beacons between participating stations.
6404 // Set TBTT phase adaptive adjustment step to 8us (default 16us)
6405 // don't change settings 2006-5- by Jerry
6406 //RTMP_IO_WRITE32(pAd, TBTT_SYNC_CFG, 0x00001010);
6408 // start sending BEACON
6409 csr9
.field
.BeaconInterval
= pAd
->CommonCfg
.BeaconPeriod
<< 4; // ASIC register in units of 1/16 TU
6410 csr9
.field
.bTsfTicking
= 1;
6411 csr9
.field
.TsfSyncMode
= 2; // sync TSF in IBSS mode
6412 csr9
.field
.bTBTTEnable
= 1;
6413 csr9
.field
.bBeaconGen
= 1;
6414 RTMP_IO_WRITE32(pAd
, BCN_TIME_CFG
, csr9
.word
);
6418 ==========================================================================
6421 IRQL = PASSIVE_LEVEL
6422 IRQL = DISPATCH_LEVEL
6424 ==========================================================================
6426 VOID
AsicSetEdcaParm(
6427 IN PRTMP_ADAPTER pAd
,
6428 IN PEDCA_PARM pEdcaParm
)
6430 EDCA_AC_CFG_STRUC Ac0Cfg
, Ac1Cfg
, Ac2Cfg
, Ac3Cfg
;
6431 AC_TXOP_CSR0_STRUC csr0
;
6432 AC_TXOP_CSR1_STRUC csr1
;
6433 AIFSN_CSR_STRUC AifsnCsr
;
6434 CWMIN_CSR_STRUC CwminCsr
;
6435 CWMAX_CSR_STRUC CwmaxCsr
;
6442 if ((pEdcaParm
== NULL
) || (pEdcaParm
->bValid
== FALSE
))
6444 DBGPRINT(RT_DEBUG_TRACE
,("AsicSetEdcaParm\n"));
6445 OPSTATUS_CLEAR_FLAG(pAd
, fOP_STATUS_WMM_INUSED
);
6446 for (i
=0; i
<MAX_LEN_OF_MAC_TABLE
; i
++)
6448 if (pAd
->MacTab
.Content
[i
].ValidAsCLI
|| pAd
->MacTab
.Content
[i
].ValidAsApCli
)
6449 CLIENT_STATUS_CLEAR_FLAG(&pAd
->MacTab
.Content
[i
], fCLIENT_STATUS_WMM_CAPABLE
);
6452 //========================================================
6453 // MAC Register has a copy .
6454 //========================================================
6456 if( pAd
->CommonCfg
.bEnableTxBurst
)
6458 // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
6459 Ac0Cfg
.field
.AcTxop
= 0x20; // Suggest by John for TxBurst in HT Mode
6462 Ac0Cfg
.field
.AcTxop
= 0; // QID_AC_BE
6464 // Ac0Cfg.field.AcTxop = 0; // QID_AC_BE
6466 Ac0Cfg
.field
.Cwmin
= CW_MIN_IN_BITS
;
6467 Ac0Cfg
.field
.Cwmax
= CW_MAX_IN_BITS
;
6468 Ac0Cfg
.field
.Aifsn
= 2;
6469 RTMP_IO_WRITE32(pAd
, EDCA_AC0_CFG
, Ac0Cfg
.word
);
6471 Ac1Cfg
.field
.AcTxop
= 0; // QID_AC_BK
6472 Ac1Cfg
.field
.Cwmin
= CW_MIN_IN_BITS
;
6473 Ac1Cfg
.field
.Cwmax
= CW_MAX_IN_BITS
;
6474 Ac1Cfg
.field
.Aifsn
= 2;
6475 RTMP_IO_WRITE32(pAd
, EDCA_AC1_CFG
, Ac1Cfg
.word
);
6477 if (pAd
->CommonCfg
.PhyMode
== PHY_11B
)
6479 Ac2Cfg
.field
.AcTxop
= 192; // AC_VI: 192*32us ~= 6ms
6480 Ac3Cfg
.field
.AcTxop
= 96; // AC_VO: 96*32us ~= 3ms
6484 Ac2Cfg
.field
.AcTxop
= 96; // AC_VI: 96*32us ~= 3ms
6485 Ac3Cfg
.field
.AcTxop
= 48; // AC_VO: 48*32us ~= 1.5ms
6487 Ac2Cfg
.field
.Cwmin
= CW_MIN_IN_BITS
;
6488 Ac2Cfg
.field
.Cwmax
= CW_MAX_IN_BITS
;
6489 Ac2Cfg
.field
.Aifsn
= 2;
6490 RTMP_IO_WRITE32(pAd
, EDCA_AC2_CFG
, Ac2Cfg
.word
);
6491 Ac3Cfg
.field
.Cwmin
= CW_MIN_IN_BITS
;
6492 Ac3Cfg
.field
.Cwmax
= CW_MAX_IN_BITS
;
6493 Ac3Cfg
.field
.Aifsn
= 2;
6494 RTMP_IO_WRITE32(pAd
, EDCA_AC3_CFG
, Ac3Cfg
.word
);
6496 //========================================================
6497 // DMA Register has a copy too.
6498 //========================================================
6499 csr0
.field
.Ac0Txop
= 0; // QID_AC_BE
6500 csr0
.field
.Ac1Txop
= 0; // QID_AC_BK
6501 RTMP_IO_WRITE32(pAd
, WMM_TXOP0_CFG
, csr0
.word
);
6502 if (pAd
->CommonCfg
.PhyMode
== PHY_11B
)
6504 csr1
.field
.Ac2Txop
= 192; // AC_VI: 192*32us ~= 6ms
6505 csr1
.field
.Ac3Txop
= 96; // AC_VO: 96*32us ~= 3ms
6509 csr1
.field
.Ac2Txop
= 96; // AC_VI: 96*32us ~= 3ms
6510 csr1
.field
.Ac3Txop
= 48; // AC_VO: 48*32us ~= 1.5ms
6512 RTMP_IO_WRITE32(pAd
, WMM_TXOP1_CFG
, csr1
.word
);
6515 CwminCsr
.field
.Cwmin0
= CW_MIN_IN_BITS
;
6516 CwminCsr
.field
.Cwmin1
= CW_MIN_IN_BITS
;
6517 CwminCsr
.field
.Cwmin2
= CW_MIN_IN_BITS
;
6518 CwminCsr
.field
.Cwmin3
= CW_MIN_IN_BITS
;
6519 RTMP_IO_WRITE32(pAd
, WMM_CWMIN_CFG
, CwminCsr
.word
);
6522 CwmaxCsr
.field
.Cwmax0
= CW_MAX_IN_BITS
;
6523 CwmaxCsr
.field
.Cwmax1
= CW_MAX_IN_BITS
;
6524 CwmaxCsr
.field
.Cwmax2
= CW_MAX_IN_BITS
;
6525 CwmaxCsr
.field
.Cwmax3
= CW_MAX_IN_BITS
;
6526 RTMP_IO_WRITE32(pAd
, WMM_CWMAX_CFG
, CwmaxCsr
.word
);
6528 RTMP_IO_WRITE32(pAd
, WMM_AIFSN_CFG
, 0x00002222);
6530 NdisZeroMemory(&pAd
->CommonCfg
.APEdcaParm
, sizeof(EDCA_PARM
));
6534 OPSTATUS_SET_FLAG(pAd
, fOP_STATUS_WMM_INUSED
);
6535 //========================================================
6536 // MAC Register has a copy.
6537 //========================================================
6539 // Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27
6540 // To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue.
6542 //pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this
6544 Ac0Cfg
.field
.AcTxop
= pEdcaParm
->Txop
[QID_AC_BE
];
6545 Ac0Cfg
.field
.Cwmin
= pEdcaParm
->Cwmin
[QID_AC_BE
];
6546 Ac0Cfg
.field
.Cwmax
= pEdcaParm
->Cwmax
[QID_AC_BE
];
6547 Ac0Cfg
.field
.Aifsn
= pEdcaParm
->Aifsn
[QID_AC_BE
]; //+1;
6549 Ac1Cfg
.field
.AcTxop
= pEdcaParm
->Txop
[QID_AC_BK
];
6550 Ac1Cfg
.field
.Cwmin
= pEdcaParm
->Cwmin
[QID_AC_BK
]; //+2;
6551 Ac1Cfg
.field
.Cwmax
= pEdcaParm
->Cwmax
[QID_AC_BK
];
6552 Ac1Cfg
.field
.Aifsn
= pEdcaParm
->Aifsn
[QID_AC_BK
]; //+1;
6554 Ac2Cfg
.field
.AcTxop
= (pEdcaParm
->Txop
[QID_AC_VI
] * 6) / 10;
6555 Ac2Cfg
.field
.Cwmin
= pEdcaParm
->Cwmin
[QID_AC_VI
];
6556 Ac2Cfg
.field
.Cwmax
= pEdcaParm
->Cwmax
[QID_AC_VI
];
6557 Ac2Cfg
.field
.Aifsn
= pEdcaParm
->Aifsn
[QID_AC_VI
];
6558 #ifdef CONFIG_STA_SUPPORT
6559 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
6561 // Tuning for Wi-Fi WMM S06
6562 if (pAd
->CommonCfg
.bWiFiTest
&&
6563 pEdcaParm
->Aifsn
[QID_AC_VI
] == 10)
6564 Ac2Cfg
.field
.Aifsn
-= 1;
6566 // Tuning for TGn Wi-Fi 5.2.32
6567 // STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta
6568 if (STA_TGN_WIFI_ON(pAd
) &&
6569 pEdcaParm
->Aifsn
[QID_AC_VI
] == 10)
6571 Ac0Cfg
.field
.Aifsn
= 3;
6572 Ac2Cfg
.field
.AcTxop
= 5;
6575 #endif // CONFIG_STA_SUPPORT //
6577 Ac3Cfg
.field
.AcTxop
= pEdcaParm
->Txop
[QID_AC_VO
];
6578 Ac3Cfg
.field
.Cwmin
= pEdcaParm
->Cwmin
[QID_AC_VO
];
6579 Ac3Cfg
.field
.Cwmax
= pEdcaParm
->Cwmax
[QID_AC_VO
];
6580 Ac3Cfg
.field
.Aifsn
= pEdcaParm
->Aifsn
[QID_AC_VO
];
6583 if (pAd
->CommonCfg
.bWiFiTest
)
6585 if (Ac3Cfg
.field
.AcTxop
== 102)
6587 Ac0Cfg
.field
.AcTxop
= pEdcaParm
->Txop
[QID_AC_BE
] ? pEdcaParm
->Txop
[QID_AC_BE
] : 10;
6588 Ac0Cfg
.field
.Aifsn
= pEdcaParm
->Aifsn
[QID_AC_BE
]-1; /* AIFSN must >= 1 */
6589 Ac1Cfg
.field
.AcTxop
= pEdcaParm
->Txop
[QID_AC_BK
];
6590 Ac1Cfg
.field
.Aifsn
= pEdcaParm
->Aifsn
[QID_AC_BK
];
6591 Ac2Cfg
.field
.AcTxop
= pEdcaParm
->Txop
[QID_AC_VI
];
6594 //#endif // WIFI_TEST //
6596 RTMP_IO_WRITE32(pAd
, EDCA_AC0_CFG
, Ac0Cfg
.word
);
6597 RTMP_IO_WRITE32(pAd
, EDCA_AC1_CFG
, Ac1Cfg
.word
);
6598 RTMP_IO_WRITE32(pAd
, EDCA_AC2_CFG
, Ac2Cfg
.word
);
6599 RTMP_IO_WRITE32(pAd
, EDCA_AC3_CFG
, Ac3Cfg
.word
);
6602 //========================================================
6603 // DMA Register has a copy too.
6604 //========================================================
6605 csr0
.field
.Ac0Txop
= Ac0Cfg
.field
.AcTxop
;
6606 csr0
.field
.Ac1Txop
= Ac1Cfg
.field
.AcTxop
;
6607 RTMP_IO_WRITE32(pAd
, WMM_TXOP0_CFG
, csr0
.word
);
6609 csr1
.field
.Ac2Txop
= Ac2Cfg
.field
.AcTxop
;
6610 csr1
.field
.Ac3Txop
= Ac3Cfg
.field
.AcTxop
;
6611 RTMP_IO_WRITE32(pAd
, WMM_TXOP1_CFG
, csr1
.word
);
6614 CwminCsr
.field
.Cwmin0
= pEdcaParm
->Cwmin
[QID_AC_BE
];
6615 CwminCsr
.field
.Cwmin1
= pEdcaParm
->Cwmin
[QID_AC_BK
];
6616 CwminCsr
.field
.Cwmin2
= pEdcaParm
->Cwmin
[QID_AC_VI
];
6617 #ifdef CONFIG_STA_SUPPORT
6618 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
6619 CwminCsr
.field
.Cwmin3
= pEdcaParm
->Cwmin
[QID_AC_VO
] - 1; //for TGn wifi test
6620 #endif // CONFIG_STA_SUPPORT //
6621 RTMP_IO_WRITE32(pAd
, WMM_CWMIN_CFG
, CwminCsr
.word
);
6624 CwmaxCsr
.field
.Cwmax0
= pEdcaParm
->Cwmax
[QID_AC_BE
];
6625 CwmaxCsr
.field
.Cwmax1
= pEdcaParm
->Cwmax
[QID_AC_BK
];
6626 CwmaxCsr
.field
.Cwmax2
= pEdcaParm
->Cwmax
[QID_AC_VI
];
6627 CwmaxCsr
.field
.Cwmax3
= pEdcaParm
->Cwmax
[QID_AC_VO
];
6628 RTMP_IO_WRITE32(pAd
, WMM_CWMAX_CFG
, CwmaxCsr
.word
);
6631 AifsnCsr
.field
.Aifsn0
= Ac0Cfg
.field
.Aifsn
; //pEdcaParm->Aifsn[QID_AC_BE];
6632 AifsnCsr
.field
.Aifsn1
= Ac1Cfg
.field
.Aifsn
; //pEdcaParm->Aifsn[QID_AC_BK];
6633 AifsnCsr
.field
.Aifsn2
= Ac2Cfg
.field
.Aifsn
; //pEdcaParm->Aifsn[QID_AC_VI];
6634 #ifdef CONFIG_STA_SUPPORT
6635 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
6637 // Tuning for Wi-Fi WMM S06
6638 if (pAd
->CommonCfg
.bWiFiTest
&&
6639 pEdcaParm
->Aifsn
[QID_AC_VI
] == 10)
6640 AifsnCsr
.field
.Aifsn2
= Ac2Cfg
.field
.Aifsn
- 4;
6642 // Tuning for TGn Wi-Fi 5.2.32
6643 // STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta
6644 if (STA_TGN_WIFI_ON(pAd
) &&
6645 pEdcaParm
->Aifsn
[QID_AC_VI
] == 10)
6647 AifsnCsr
.field
.Aifsn0
= 3;
6648 AifsnCsr
.field
.Aifsn2
= 7;
6652 CLIENT_STATUS_SET_FLAG(&pAd
->MacTab
.Content
[BSSID_WCID
], fCLIENT_STATUS_WMM_CAPABLE
);
6654 #endif // CONFIG_STA_SUPPORT //
6656 #ifdef CONFIG_STA_SUPPORT
6657 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
6658 AifsnCsr
.field
.Aifsn3
= Ac3Cfg
.field
.Aifsn
- 1; //pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test
6659 #endif // CONFIG_STA_SUPPORT //
6660 RTMP_IO_WRITE32(pAd
, WMM_AIFSN_CFG
, AifsnCsr
.word
);
6662 NdisMoveMemory(&pAd
->CommonCfg
.APEdcaParm
, pEdcaParm
, sizeof(EDCA_PARM
));
6665 DBGPRINT(RT_DEBUG_TRACE
,("EDCA [#%d]: AIFSN CWmin CWmax TXOP(us) ACM\n", pEdcaParm
->EdcaUpdateCount
));
6666 DBGPRINT(RT_DEBUG_TRACE
,(" AC_BE %2d %2d %2d %4d %d\n",
6667 pEdcaParm
->Aifsn
[0],
6668 pEdcaParm
->Cwmin
[0],
6669 pEdcaParm
->Cwmax
[0],
6670 pEdcaParm
->Txop
[0]<<5,
6671 pEdcaParm
->bACM
[0]));
6672 DBGPRINT(RT_DEBUG_TRACE
,(" AC_BK %2d %2d %2d %4d %d\n",
6673 pEdcaParm
->Aifsn
[1],
6674 pEdcaParm
->Cwmin
[1],
6675 pEdcaParm
->Cwmax
[1],
6676 pEdcaParm
->Txop
[1]<<5,
6677 pEdcaParm
->bACM
[1]));
6678 DBGPRINT(RT_DEBUG_TRACE
,(" AC_VI %2d %2d %2d %4d %d\n",
6679 pEdcaParm
->Aifsn
[2],
6680 pEdcaParm
->Cwmin
[2],
6681 pEdcaParm
->Cwmax
[2],
6682 pEdcaParm
->Txop
[2]<<5,
6683 pEdcaParm
->bACM
[2]));
6684 DBGPRINT(RT_DEBUG_TRACE
,(" AC_VO %2d %2d %2d %4d %d\n",
6685 pEdcaParm
->Aifsn
[3],
6686 pEdcaParm
->Cwmin
[3],
6687 pEdcaParm
->Cwmax
[3],
6688 pEdcaParm
->Txop
[3]<<5,
6689 pEdcaParm
->bACM
[3]));
6695 ==========================================================================
6698 IRQL = PASSIVE_LEVEL
6699 IRQL = DISPATCH_LEVEL
6701 ==========================================================================
6703 VOID
AsicSetSlotTime(
6704 IN PRTMP_ADAPTER pAd
,
6705 IN BOOLEAN bUseShortSlotTime
)
6708 UINT32 RegValue
= 0;
6710 #ifdef CONFIG_STA_SUPPORT
6711 if (pAd
->CommonCfg
.Channel
> 14)
6712 bUseShortSlotTime
= TRUE
;
6713 #endif // CONFIG_STA_SUPPORT //
6715 if (bUseShortSlotTime
)
6716 OPSTATUS_SET_FLAG(pAd
, fOP_STATUS_SHORT_SLOT_INUSED
);
6718 OPSTATUS_CLEAR_FLAG(pAd
, fOP_STATUS_SHORT_SLOT_INUSED
);
6720 SlotTime
= (bUseShortSlotTime
)? 9 : 20;
6722 #ifdef CONFIG_STA_SUPPORT
6723 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
6725 // force using short SLOT time for FAE to demo performance when TxBurst is ON
6726 if (((pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
== FALSE
) && (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_WMM_INUSED
)))
6727 #ifdef DOT11_N_SUPPORT
6728 || ((pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
== TRUE
) && (pAd
->CommonCfg
.BACapability
.field
.Policy
== BA_NOTUSE
))
6729 #endif // DOT11_N_SUPPORT //
6732 // In this case, we will think it is doing Wi-Fi test
6733 // And we will not set to short slot when bEnableTxBurst is TRUE.
6735 else if (pAd
->CommonCfg
.bEnableTxBurst
)
6738 #endif // CONFIG_STA_SUPPORT //
6741 // For some reasons, always set it to short slot time.
6743 // ToDo: Should consider capability with 11B
6745 #ifdef CONFIG_STA_SUPPORT
6746 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
6748 if (pAd
->StaCfg
.BssType
== BSS_ADHOC
)
6751 #endif // CONFIG_STA_SUPPORT //
6753 RTMP_IO_READ32(pAd
, BKOFF_SLOT_CFG
, &RegValue
);
6754 RegValue
= RegValue
& 0xFFFFFF00;
6756 RegValue
|= SlotTime
;
6758 RTMP_IO_WRITE32(pAd
, BKOFF_SLOT_CFG
, RegValue
);
6762 ========================================================================
6764 Add Shared key information into ASIC.
6765 Update shared key, TxMic and RxMic to Asic Shared key table
6766 Update its cipherAlg to Asic Shared key Mode.
6769 ========================================================================
6771 VOID
AsicAddSharedKeyEntry(
6772 IN PRTMP_ADAPTER pAd
,
6780 ULONG offset
; //, csr0;
6781 SHAREDKEY_MODE_STRUC csr1
;
6783 DBGPRINT(RT_DEBUG_TRACE
, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex
,KeyIdx
));
6784 //============================================================================================
6786 DBGPRINT(RT_DEBUG_TRACE
,("AsicAddSharedKeyEntry: %s key #%d\n", CipherName
[CipherAlg
], BssIndex
*4 + KeyIdx
));
6787 DBGPRINT_RAW(RT_DEBUG_TRACE
, (" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
6788 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]));
6791 DBGPRINT_RAW(RT_DEBUG_TRACE
, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
6792 pRxMic
[0],pRxMic
[1],pRxMic
[2],pRxMic
[3],pRxMic
[4],pRxMic
[5],pRxMic
[6],pRxMic
[7]));
6796 DBGPRINT_RAW(RT_DEBUG_TRACE
, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
6797 pTxMic
[0],pTxMic
[1],pTxMic
[2],pTxMic
[3],pTxMic
[4],pTxMic
[5],pTxMic
[6],pTxMic
[7]));
6799 //============================================================================================
6801 // fill key material - key + TX MIC + RX MIC
6806 offset
= SHARED_KEY_TABLE_BASE
+ (4*BssIndex
+ KeyIdx
)*HW_KEY_ENTRY_SIZE
;
6807 RTUSBMultiWrite(pAd
, offset
, pKey
, MAX_LEN_OF_SHARE_KEY
);
6809 offset
+= MAX_LEN_OF_SHARE_KEY
;
6812 RTUSBMultiWrite(pAd
, offset
, pTxMic
, 8);
6818 RTUSBMultiWrite(pAd
, offset
, pRxMic
, 8);
6824 // Update cipher algorithm. WSTA always use BSS0
6826 RTMP_IO_READ32(pAd
, SHARED_KEY_MODE_BASE
+4*(BssIndex
/2), &csr1
.word
);
6827 DBGPRINT(RT_DEBUG_TRACE
,("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n", BssIndex
,KeyIdx
, csr1
.word
));
6828 if ((BssIndex
%2) == 0)
6831 csr1
.field
.Bss0Key0CipherAlg
= CipherAlg
;
6832 else if (KeyIdx
== 1)
6833 csr1
.field
.Bss0Key1CipherAlg
= CipherAlg
;
6834 else if (KeyIdx
== 2)
6835 csr1
.field
.Bss0Key2CipherAlg
= CipherAlg
;
6837 csr1
.field
.Bss0Key3CipherAlg
= CipherAlg
;
6842 csr1
.field
.Bss1Key0CipherAlg
= CipherAlg
;
6843 else if (KeyIdx
== 1)
6844 csr1
.field
.Bss1Key1CipherAlg
= CipherAlg
;
6845 else if (KeyIdx
== 2)
6846 csr1
.field
.Bss1Key2CipherAlg
= CipherAlg
;
6848 csr1
.field
.Bss1Key3CipherAlg
= CipherAlg
;
6850 DBGPRINT(RT_DEBUG_TRACE
,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex
, csr1
.word
));
6851 RTMP_IO_WRITE32(pAd
, SHARED_KEY_MODE_BASE
+4*(BssIndex
/2), csr1
.word
);
6855 // IRQL = DISPATCH_LEVEL
6856 VOID
AsicRemoveSharedKeyEntry(
6857 IN PRTMP_ADAPTER pAd
,
6862 SHAREDKEY_MODE_STRUC csr1
;
6864 DBGPRINT(RT_DEBUG_TRACE
,("AsicRemoveSharedKeyEntry: #%d \n", BssIndex
*4 + KeyIdx
));
6866 RTMP_IO_READ32(pAd
, SHARED_KEY_MODE_BASE
+4*(BssIndex
/2), &csr1
.word
);
6867 if ((BssIndex
%2) == 0)
6870 csr1
.field
.Bss0Key0CipherAlg
= 0;
6871 else if (KeyIdx
== 1)
6872 csr1
.field
.Bss0Key1CipherAlg
= 0;
6873 else if (KeyIdx
== 2)
6874 csr1
.field
.Bss0Key2CipherAlg
= 0;
6876 csr1
.field
.Bss0Key3CipherAlg
= 0;
6881 csr1
.field
.Bss1Key0CipherAlg
= 0;
6882 else if (KeyIdx
== 1)
6883 csr1
.field
.Bss1Key1CipherAlg
= 0;
6884 else if (KeyIdx
== 2)
6885 csr1
.field
.Bss1Key2CipherAlg
= 0;
6887 csr1
.field
.Bss1Key3CipherAlg
= 0;
6889 DBGPRINT(RT_DEBUG_TRACE
,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex
, csr1
.word
));
6890 RTMP_IO_WRITE32(pAd
, SHARED_KEY_MODE_BASE
+4*(BssIndex
/2), csr1
.word
);
6891 ASSERT(BssIndex
< 4);
6897 VOID
AsicUpdateWCIDAttribute(
6898 IN PRTMP_ADAPTER pAd
,
6902 IN BOOLEAN bUsePairewiseKeyTable
)
6904 ULONG WCIDAttri
= 0, offset
;
6907 // Update WCID attribute.
6908 // Only TxKey could update WCID attribute.
6910 offset
= MAC_WCID_ATTRIBUTE_BASE
+ (WCID
* HW_WCID_ATTRI_SIZE
);
6911 WCIDAttri
= (BssIndex
<< 4) | (CipherAlg
<< 1) | (bUsePairewiseKeyTable
);
6912 RTMP_IO_WRITE32(pAd
, offset
, WCIDAttri
);
6915 VOID
AsicUpdateWCIDIVEIV(
6916 IN PRTMP_ADAPTER pAd
,
6923 offset
= MAC_IVEIV_TABLE_BASE
+ (WCID
* HW_IVEIV_ENTRY_SIZE
);
6925 RTMP_IO_WRITE32(pAd
, offset
, uIV
);
6926 RTMP_IO_WRITE32(pAd
, offset
+ 4, uEIV
);
6929 VOID
AsicUpdateRxWCIDTable(
6930 IN PRTMP_ADAPTER pAd
,
6937 offset
= MAC_WCID_BASE
+ (WCID
* HW_WCID_ENTRY_SIZE
);
6938 Addr
= pAddr
[0] + (pAddr
[1] << 8) +(pAddr
[2] << 16) +(pAddr
[3] << 24);
6939 RTMP_IO_WRITE32(pAd
, offset
, Addr
);
6940 Addr
= pAddr
[4] + (pAddr
[5] << 8);
6941 RTMP_IO_WRITE32(pAd
, offset
+ 4, Addr
);
6946 ========================================================================
6948 Routine Description:
6949 Set Cipher Key, Cipher algorithm, IV/EIV to Asic
6952 pAd Pointer to our adapter
6953 WCID WCID Entry number.
6954 BssIndex BSSID index, station or none multiple BSSID support
6955 this value should be 0.
6956 KeyIdx This KeyIdx will set to IV's KeyID if bTxKey enabled
6957 pCipherKey Pointer to Cipher Key.
6958 bUsePairewiseKeyTable TRUE means saved the key in SharedKey table,
6959 otherwise PairewiseKey table
6960 bTxKey This is the transmit key if enabled.
6966 This routine will set the relative key stuff to Asic including WCID attribute,
6967 Cipher Key, Cipher algorithm and IV/EIV.
6969 IV/EIV will be update if this CipherKey is the transmission key because
6970 ASIC will base on IV's KeyID value to select Cipher Key.
6972 If bTxKey sets to FALSE, this is not the TX key, but it could be
6975 For AP mode bTxKey must be always set to TRUE.
6976 ========================================================================
6978 VOID
AsicAddKeyEntry(
6979 IN PRTMP_ADAPTER pAd
,
6983 IN PCIPHER_KEY pCipherKey
,
6984 IN BOOLEAN bUsePairewiseKeyTable
,
6988 // ULONG WCIDAttri = 0;
6990 PUCHAR pKey
= pCipherKey
->Key
;
6991 // ULONG KeyLen = pCipherKey->KeyLen;
6992 PUCHAR pTxMic
= pCipherKey
->TxMic
;
6993 PUCHAR pRxMic
= pCipherKey
->RxMic
;
6994 PUCHAR pTxtsc
= pCipherKey
->TxTsc
;
6995 UCHAR CipherAlg
= pCipherKey
->CipherAlg
;
6996 SHAREDKEY_MODE_STRUC csr1
;
6998 // ASSERT(KeyLen <= MAX_LEN_OF_PEER_KEY);
7000 DBGPRINT(RT_DEBUG_TRACE
, ("==> AsicAddKeyEntry\n"));
7002 // 1.) decide key table offset
7004 if (bUsePairewiseKeyTable
)
7005 offset
= PAIRWISE_KEY_TABLE_BASE
+ (WCID
* HW_KEY_ENTRY_SIZE
);
7007 offset
= SHARED_KEY_TABLE_BASE
+ (4 * BssIndex
+ KeyIdx
) * HW_KEY_ENTRY_SIZE
;
7010 // 2.) Set Key to Asic
7012 //for (i = 0; i < KeyLen; i++)
7015 RTUSBMultiWrite(pAd
, offset
, pKey
, MAX_LEN_OF_PEER_KEY
);
7016 offset
+= MAX_LEN_OF_PEER_KEY
;
7019 // 3.) Set MIC key if available
7023 RTUSBMultiWrite(pAd
, offset
, pTxMic
, 8);
7025 offset
+= LEN_TKIP_TXMICK
;
7029 RTUSBMultiWrite(pAd
, offset
, pRxMic
, 8);
7034 // 4.) Modify IV/EIV if needs
7035 // This will force Asic to use this key ID by setting IV.
7046 IV4
= (KeyIdx
<< 6);
7047 if ((CipherAlg
== CIPHER_TKIP
) || (CipherAlg
== CIPHER_TKIP_NO_MIC
) ||(CipherAlg
== CIPHER_AES
))
7048 IV4
|= 0x20; // turn on extension bit means EIV existence
7050 tmpVal
= pTxtsc
[1] + (((pTxtsc
[1] | 0x20) & 0x7f) << 8) + (pTxtsc
[0] << 16) + (IV4
<< 24);
7051 RTMP_IO_WRITE32(pAd
, offset
, tmpVal
);
7057 RTMP_IO_WRITE32(pAd
, offset
, *(PUINT32
)&pCipherKey
->TxTsc
[2]);
7059 AsicUpdateWCIDAttribute(pAd
, WCID
, BssIndex
, CipherAlg
, bUsePairewiseKeyTable
);
7062 if (!bUsePairewiseKeyTable
)
7065 // Only update the shared key security mode
7067 RTMP_IO_READ32(pAd
, SHARED_KEY_MODE_BASE
+ 4 * (BssIndex
/ 2), &csr1
.word
);
7068 if ((BssIndex
% 2) == 0)
7071 csr1
.field
.Bss0Key0CipherAlg
= CipherAlg
;
7072 else if (KeyIdx
== 1)
7073 csr1
.field
.Bss0Key1CipherAlg
= CipherAlg
;
7074 else if (KeyIdx
== 2)
7075 csr1
.field
.Bss0Key2CipherAlg
= CipherAlg
;
7077 csr1
.field
.Bss0Key3CipherAlg
= CipherAlg
;
7082 csr1
.field
.Bss1Key0CipherAlg
= CipherAlg
;
7083 else if (KeyIdx
== 1)
7084 csr1
.field
.Bss1Key1CipherAlg
= CipherAlg
;
7085 else if (KeyIdx
== 2)
7086 csr1
.field
.Bss1Key2CipherAlg
= CipherAlg
;
7088 csr1
.field
.Bss1Key3CipherAlg
= CipherAlg
;
7090 RTMP_IO_WRITE32(pAd
, SHARED_KEY_MODE_BASE
+ 4 * (BssIndex
/ 2), csr1
.word
);
7093 DBGPRINT(RT_DEBUG_TRACE
, ("<== AsicAddKeyEntry\n"));
7098 ========================================================================
7100 Add Pair-wise key material into ASIC.
7101 Update pairwise key, TxMic and RxMic to Asic Pair-wise key table
7104 ========================================================================
7106 VOID
AsicAddPairwiseKeyEntry(
7107 IN PRTMP_ADAPTER pAd
,
7110 IN CIPHER_KEY
*pCipherKey
)
7114 PUCHAR pKey
= pCipherKey
->Key
;
7115 PUCHAR pTxMic
= pCipherKey
->TxMic
;
7116 PUCHAR pRxMic
= pCipherKey
->RxMic
;
7118 UCHAR CipherAlg
= pCipherKey
->CipherAlg
;
7122 offset
= PAIRWISE_KEY_TABLE_BASE
+ (WCID
* HW_KEY_ENTRY_SIZE
);
7124 RTUSBMultiWrite(pAd
, offset
, &pCipherKey
->Key
[0], MAX_LEN_OF_PEER_KEY
);
7126 for (i
=0; i
<MAX_LEN_OF_PEER_KEY
; i
+=4)
7129 RTMP_IO_READ32(pAd
, offset
+ i
, &Value
);
7132 offset
+= MAX_LEN_OF_PEER_KEY
;
7138 RTUSBMultiWrite(pAd
, offset
, &pCipherKey
->TxMic
[0], 8);
7145 RTUSBMultiWrite(pAd
, offset
, &pCipherKey
->RxMic
[0], 8);
7149 DBGPRINT(RT_DEBUG_TRACE
,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID
, CipherName
[CipherAlg
]));
7150 DBGPRINT(RT_DEBUG_TRACE
,(" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7151 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]));
7154 DBGPRINT(RT_DEBUG_TRACE
, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7155 pRxMic
[0],pRxMic
[1],pRxMic
[2],pRxMic
[3],pRxMic
[4],pRxMic
[5],pRxMic
[6],pRxMic
[7]));
7159 DBGPRINT(RT_DEBUG_TRACE
, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7160 pTxMic
[0],pTxMic
[1],pTxMic
[2],pTxMic
[3],pTxMic
[4],pTxMic
[5],pTxMic
[6],pTxMic
[7]));
7164 ========================================================================
7166 Remove Pair-wise key material from ASIC.
7169 ========================================================================
7171 VOID
AsicRemovePairwiseKeyEntry(
7172 IN PRTMP_ADAPTER pAd
,
7179 // re-set the entry's WCID attribute as OPEN-NONE.
7180 offset
= MAC_WCID_ATTRIBUTE_BASE
+ (Wcid
* HW_WCID_ATTRI_SIZE
);
7181 WCIDAttri
= (BssIdx
<<4) | PAIRWISEKEYTABLE
;
7182 RTMP_IO_WRITE32(pAd
, offset
, WCIDAttri
);
7185 BOOLEAN
AsicSendCommandToMcu(
7186 IN PRTMP_ADAPTER pAd
,
7192 HOST_CMD_CSR_STRUC H2MCmd
;
7193 H2M_MAILBOX_STRUC H2MMailbox
;
7197 RTMP_IO_READ32(pAd
, H2M_MAILBOX_CSR
, &H2MMailbox
.word
);
7198 if (H2MMailbox
.field
.Owner
== 0)
7207 DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
7213 H2MMailbox
.field
.Owner
= 1; // pass ownership to MCU
7214 H2MMailbox
.field
.CmdToken
= Token
;
7215 H2MMailbox
.field
.HighByte
= Arg1
;
7216 H2MMailbox
.field
.LowByte
= Arg0
;
7217 RTMP_IO_WRITE32(pAd
, H2M_MAILBOX_CSR
, H2MMailbox
.word
);
7220 H2MCmd
.field
.HostCommand
= Command
;
7221 RTMP_IO_WRITE32(pAd
, HOST_CMD_CSR
, H2MCmd
.word
);
7223 if (Command
!= 0x80)
7232 ========================================================================
7234 Routine Description:
7235 Verify the support rate for different PHY type
7238 pAd Pointer to our adapter
7243 IRQL = PASSIVE_LEVEL
7245 ========================================================================
7247 VOID
RTMPCheckRates(
7248 IN PRTMP_ADAPTER pAd
,
7249 IN OUT UCHAR SupRate
[],
7250 IN OUT UCHAR
*SupRateLen
)
7252 UCHAR RateIdx
, i
, j
;
7253 UCHAR NewRate
[12], NewRateLen
;
7257 if (pAd
->CommonCfg
.PhyMode
== PHY_11B
)
7262 // Check for support rates exclude basic rate bit
7263 for (i
= 0; i
< *SupRateLen
; i
++)
7264 for (j
= 0; j
< RateIdx
; j
++)
7265 if ((SupRate
[i
] & 0x7f) == RateIdTo500Kbps
[j
])
7266 NewRate
[NewRateLen
++] = SupRate
[i
];
7268 *SupRateLen
= NewRateLen
;
7269 NdisMoveMemory(SupRate
, NewRate
, NewRateLen
);
7272 #ifdef CONFIG_STA_SUPPORT
7273 #ifdef DOT11_N_SUPPORT
7274 BOOLEAN
RTMPCheckChannel(
7275 IN PRTMP_ADAPTER pAd
,
7276 IN UCHAR CentralChannel
,
7280 UCHAR UpperChannel
= 0, LowerChannel
= 0;
7281 UCHAR NoEffectChannelinList
= 0;
7283 // Find upper and lower channel according to 40MHz current operation.
7284 if (CentralChannel
< Channel
)
7286 UpperChannel
= Channel
;
7287 if (CentralChannel
> 2)
7288 LowerChannel
= CentralChannel
- 2;
7292 else if (CentralChannel
> Channel
)
7294 UpperChannel
= CentralChannel
+ 2;
7295 LowerChannel
= Channel
;
7298 for (k
= 0;k
< pAd
->ChannelListNum
;k
++)
7300 if (pAd
->ChannelList
[k
].Channel
== UpperChannel
)
7302 NoEffectChannelinList
++;
7304 if (pAd
->ChannelList
[k
].Channel
== LowerChannel
)
7306 NoEffectChannelinList
++;
7310 DBGPRINT(RT_DEBUG_TRACE
,("Total Channel in Channel List = [%d]\n", NoEffectChannelinList
));
7311 if (NoEffectChannelinList
== 2)
7318 ========================================================================
7320 Routine Description:
7321 Verify the support rate for HT phy type
7324 pAd Pointer to our adapter
7327 FALSE if pAd->CommonCfg.SupportedHtPhy doesn't accept the pHtCapability. (AP Mode)
7329 IRQL = PASSIVE_LEVEL
7331 ========================================================================
7333 BOOLEAN
RTMPCheckHt(
7334 IN PRTMP_ADAPTER pAd
,
7336 IN HT_CAPABILITY_IE
*pHtCapability
,
7337 IN ADD_HT_INFO_IE
*pAddHtInfo
)
7339 if (Wcid
>= MAX_LEN_OF_MAC_TABLE
)
7342 // If use AMSDU, set flag.
7343 if (pAd
->CommonCfg
.DesiredHtPhy
.AmsduEnable
)
7344 CLIENT_STATUS_SET_FLAG(&pAd
->MacTab
.Content
[Wcid
], fCLIENT_STATUS_AMSDU_INUSED
);
7345 // Save Peer Capability
7346 if (pHtCapability
->HtCapInfo
.ShortGIfor20
)
7347 CLIENT_STATUS_SET_FLAG(&pAd
->MacTab
.Content
[Wcid
], fCLIENT_STATUS_SGI20_CAPABLE
);
7348 if (pHtCapability
->HtCapInfo
.ShortGIfor40
)
7349 CLIENT_STATUS_SET_FLAG(&pAd
->MacTab
.Content
[Wcid
], fCLIENT_STATUS_SGI40_CAPABLE
);
7350 if (pHtCapability
->HtCapInfo
.TxSTBC
)
7351 CLIENT_STATUS_SET_FLAG(&pAd
->MacTab
.Content
[Wcid
], fCLIENT_STATUS_TxSTBC_CAPABLE
);
7352 if (pHtCapability
->HtCapInfo
.RxSTBC
)
7353 CLIENT_STATUS_SET_FLAG(&pAd
->MacTab
.Content
[Wcid
], fCLIENT_STATUS_RxSTBC_CAPABLE
);
7354 if (pAd
->CommonCfg
.bRdg
&& pHtCapability
->ExtHtCapInfo
.RDGSupport
)
7356 CLIENT_STATUS_SET_FLAG(&pAd
->MacTab
.Content
[Wcid
], fCLIENT_STATUS_RDG_CAPABLE
);
7359 if (Wcid
< MAX_LEN_OF_MAC_TABLE
)
7361 pAd
->MacTab
.Content
[Wcid
].MpduDensity
= pHtCapability
->HtCapParm
.MpduDensity
;
7364 // Will check ChannelWidth for MCSSet[4] below
7365 pAd
->MlmeAux
.HtCapability
.MCSSet
[4] = 0x1;
7366 switch (pAd
->CommonCfg
.RxStream
)
7369 pAd
->MlmeAux
.HtCapability
.MCSSet
[0] = 0xff;
7370 pAd
->MlmeAux
.HtCapability
.MCSSet
[1] = 0x00;
7371 pAd
->MlmeAux
.HtCapability
.MCSSet
[2] = 0x00;
7372 pAd
->MlmeAux
.HtCapability
.MCSSet
[3] = 0x00;
7375 pAd
->MlmeAux
.HtCapability
.MCSSet
[0] = 0xff;
7376 pAd
->MlmeAux
.HtCapability
.MCSSet
[1] = 0xff;
7377 pAd
->MlmeAux
.HtCapability
.MCSSet
[2] = 0x00;
7378 pAd
->MlmeAux
.HtCapability
.MCSSet
[3] = 0x00;
7381 pAd
->MlmeAux
.HtCapability
.MCSSet
[0] = 0xff;
7382 pAd
->MlmeAux
.HtCapability
.MCSSet
[1] = 0xff;
7383 pAd
->MlmeAux
.HtCapability
.MCSSet
[2] = 0xff;
7384 pAd
->MlmeAux
.HtCapability
.MCSSet
[3] = 0x00;
7388 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.ChannelWidth
= pAddHtInfo
->AddHtInfo
.RecomWidth
& pAd
->CommonCfg
.DesiredHtPhy
.ChannelWidth
;
7390 DBGPRINT(RT_DEBUG_TRACE
, ("RTMPCheckHt:: HtCapInfo.ChannelWidth=%d, RecomWidth=%d, DesiredHtPhy.ChannelWidth=%d, BW40MAvailForA/G=%d/%d, PhyMode=%d \n",
7391 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.ChannelWidth
, pAddHtInfo
->AddHtInfo
.RecomWidth
, pAd
->CommonCfg
.DesiredHtPhy
.ChannelWidth
,
7392 pAd
->NicConfig2
.field
.BW40MAvailForA
, pAd
->NicConfig2
.field
.BW40MAvailForG
, pAd
->CommonCfg
.PhyMode
));
7394 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.GF
= pHtCapability
->HtCapInfo
.GF
&pAd
->CommonCfg
.DesiredHtPhy
.GF
;
7396 // Send Assoc Req with my HT capability.
7397 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.AMsduSize
= pAd
->CommonCfg
.DesiredHtPhy
.AmsduSize
;
7398 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.MimoPs
= pAd
->CommonCfg
.DesiredHtPhy
.MimoPs
;
7399 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.ShortGIfor20
= (pAd
->CommonCfg
.DesiredHtPhy
.ShortGIfor20
) & (pHtCapability
->HtCapInfo
.ShortGIfor20
);
7400 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.ShortGIfor40
= (pAd
->CommonCfg
.DesiredHtPhy
.ShortGIfor40
) & (pHtCapability
->HtCapInfo
.ShortGIfor40
);
7401 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.TxSTBC
= (pAd
->CommonCfg
.DesiredHtPhy
.TxSTBC
)&(pHtCapability
->HtCapInfo
.RxSTBC
);
7402 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.RxSTBC
= (pAd
->CommonCfg
.DesiredHtPhy
.RxSTBC
)&(pHtCapability
->HtCapInfo
.TxSTBC
);
7403 pAd
->MlmeAux
.HtCapability
.HtCapParm
.MaxRAmpduFactor
= pAd
->CommonCfg
.DesiredHtPhy
.MaxRAmpduFactor
;
7404 pAd
->MlmeAux
.HtCapability
.HtCapParm
.MpduDensity
= pAd
->CommonCfg
.HtCapability
.HtCapParm
.MpduDensity
;
7405 pAd
->MlmeAux
.HtCapability
.ExtHtCapInfo
.PlusHTC
= pHtCapability
->ExtHtCapInfo
.PlusHTC
;
7406 pAd
->MacTab
.Content
[Wcid
].HTCapability
.ExtHtCapInfo
.PlusHTC
= pHtCapability
->ExtHtCapInfo
.PlusHTC
;
7407 if (pAd
->CommonCfg
.bRdg
)
7409 pAd
->MlmeAux
.HtCapability
.ExtHtCapInfo
.RDGSupport
= pHtCapability
->ExtHtCapInfo
.RDGSupport
;
7410 pAd
->MlmeAux
.HtCapability
.ExtHtCapInfo
.PlusHTC
= 1;
7413 if (pAd
->MlmeAux
.HtCapability
.HtCapInfo
.ChannelWidth
== BW_20
)
7414 pAd
->MlmeAux
.HtCapability
.MCSSet
[4] = 0x0; // BW20 can't transmit MCS32
7416 COPY_AP_HTSETTINGS_FROM_BEACON(pAd
, pHtCapability
);
7419 #endif // DOT11_N_SUPPORT //
7420 #endif // CONFIG_STA_SUPPORT //
7423 ========================================================================
7425 Routine Description:
7426 Verify the support rate for different PHY type
7429 pAd Pointer to our adapter
7434 IRQL = PASSIVE_LEVEL
7436 ========================================================================
7438 VOID
RTMPUpdateMlmeRate(
7439 IN PRTMP_ADAPTER pAd
)
7442 UCHAR ProperMlmeRate
; //= RATE_54;
7443 UCHAR i
, j
, RateIdx
= 12; //1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
7444 BOOLEAN bMatch
= FALSE
;
7446 switch (pAd
->CommonCfg
.PhyMode
)
7449 ProperMlmeRate
= RATE_11
;
7450 MinimumRate
= RATE_1
;
7452 case PHY_11BG_MIXED
:
7453 #ifdef DOT11_N_SUPPORT
7454 case PHY_11ABGN_MIXED
:
7455 case PHY_11BGN_MIXED
:
7456 #endif // DOT11_N_SUPPORT //
7457 if ((pAd
->MlmeAux
.SupRateLen
== 4) &&
7458 (pAd
->MlmeAux
.ExtRateLen
== 0))
7460 ProperMlmeRate
= RATE_11
;
7462 ProperMlmeRate
= RATE_24
;
7464 if (pAd
->MlmeAux
.Channel
<= 14)
7465 MinimumRate
= RATE_1
;
7467 MinimumRate
= RATE_6
;
7470 #ifdef DOT11_N_SUPPORT
7471 case PHY_11N_2_4G
: // rt2860 need to check mlmerate for 802.11n
7472 case PHY_11GN_MIXED
:
7473 case PHY_11AGN_MIXED
:
7474 case PHY_11AN_MIXED
:
7476 #endif // DOT11_N_SUPPORT //
7477 ProperMlmeRate
= RATE_24
;
7478 MinimumRate
= RATE_6
;
7480 case PHY_11ABG_MIXED
:
7481 ProperMlmeRate
= RATE_24
;
7482 if (pAd
->MlmeAux
.Channel
<= 14)
7483 MinimumRate
= RATE_1
;
7485 MinimumRate
= RATE_6
;
7488 ProperMlmeRate
= RATE_1
;
7489 MinimumRate
= RATE_1
;
7493 for (i
= 0; i
< pAd
->MlmeAux
.SupRateLen
; i
++)
7495 for (j
= 0; j
< RateIdx
; j
++)
7497 if ((pAd
->MlmeAux
.SupRate
[i
] & 0x7f) == RateIdTo500Kbps
[j
])
7499 if (j
== ProperMlmeRate
)
7511 if (bMatch
== FALSE
)
7513 for (i
= 0; i
< pAd
->MlmeAux
.ExtRateLen
; i
++)
7515 for (j
= 0; j
< RateIdx
; j
++)
7517 if ((pAd
->MlmeAux
.ExtRate
[i
] & 0x7f) == RateIdTo500Kbps
[j
])
7519 if (j
== ProperMlmeRate
)
7532 if (bMatch
== FALSE
)
7534 ProperMlmeRate
= MinimumRate
;
7537 pAd
->CommonCfg
.MlmeRate
= MinimumRate
;
7538 pAd
->CommonCfg
.RtsRate
= ProperMlmeRate
;
7539 if (pAd
->CommonCfg
.MlmeRate
>= RATE_6
)
7541 pAd
->CommonCfg
.MlmeTransmit
.field
.MODE
= MODE_OFDM
;
7542 pAd
->CommonCfg
.MlmeTransmit
.field
.MCS
= OfdmRateToRxwiMCS
[pAd
->CommonCfg
.MlmeRate
];
7543 pAd
->MacTab
.Content
[BSS0Mcast_WCID
].HTPhyMode
.field
.MODE
= MODE_OFDM
;
7544 pAd
->MacTab
.Content
[BSS0Mcast_WCID
].HTPhyMode
.field
.MCS
= OfdmRateToRxwiMCS
[pAd
->CommonCfg
.MlmeRate
];
7548 pAd
->CommonCfg
.MlmeTransmit
.field
.MODE
= MODE_CCK
;
7549 pAd
->CommonCfg
.MlmeTransmit
.field
.MCS
= pAd
->CommonCfg
.MlmeRate
;
7550 pAd
->MacTab
.Content
[BSS0Mcast_WCID
].HTPhyMode
.field
.MODE
= MODE_CCK
;
7551 pAd
->MacTab
.Content
[BSS0Mcast_WCID
].HTPhyMode
.field
.MCS
= pAd
->CommonCfg
.MlmeRate
;
7554 DBGPRINT(RT_DEBUG_TRACE
, ("RTMPUpdateMlmeRate ==> MlmeTransmit = 0x%x \n" , pAd
->CommonCfg
.MlmeTransmit
.word
));
7558 IN PRTMP_ADAPTER pAd
,
7565 if ((pAd
->Antenna
.field
.RxPath
== 1) && (Rssi0
!= 0))
7570 if ((pAd
->Antenna
.field
.RxPath
>= 2) && (Rssi1
!= 0))
7572 larger
= max(Rssi0
, Rssi1
);
7575 if ((pAd
->Antenna
.field
.RxPath
== 3) && (Rssi2
!= 0))
7577 larger
= max(larger
, Rssi2
);
7587 ========================================================================
7588 Routine Description:
7589 Periodic evaluate antenna link status
7592 pAd - Adapter pointer
7597 ========================================================================
7599 VOID
AsicEvaluateRxAnt(
7600 IN PRTMP_ADAPTER pAd
)
7604 #ifdef CONFIG_STA_SUPPORT
7605 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
7607 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_RESET_IN_PROGRESS
|
7608 fRTMP_ADAPTER_HALT_IN_PROGRESS
|
7609 fRTMP_ADAPTER_RADIO_OFF
|
7610 fRTMP_ADAPTER_NIC_NOT_EXIST
|
7611 fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS
))
7614 if (pAd
->StaCfg
.Psm
== PWR_SAVE
)
7617 #endif // CONFIG_STA_SUPPORT //
7619 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R3
, &BBPR3
);
7621 if(pAd
->Antenna
.field
.RxPath
== 3)
7625 else if(pAd
->Antenna
.field
.RxPath
== 2)
7629 else if(pAd
->Antenna
.field
.RxPath
== 1)
7633 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R3
, BBPR3
);
7634 #ifdef CONFIG_STA_SUPPORT
7635 #endif // CONFIG_STA_SUPPORT //
7636 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
)
7639 ULONG TxTotalCnt
= pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
+
7640 pAd
->RalinkCounters
.OneSecTxRetryOkCount
+
7641 pAd
->RalinkCounters
.OneSecTxFailCount
;
7643 if (TxTotalCnt
> 50)
7645 RTMPSetTimer(&pAd
->Mlme
.RxAntEvalTimer
, 20);
7646 pAd
->Mlme
.bLowThroughput
= FALSE
;
7650 RTMPSetTimer(&pAd
->Mlme
.RxAntEvalTimer
, 300);
7651 pAd
->Mlme
.bLowThroughput
= TRUE
;
7657 ========================================================================
7658 Routine Description:
7659 After evaluation, check antenna link status
7662 pAd - Adapter pointer
7667 ========================================================================
7669 VOID
AsicRxAntEvalTimeout(
7670 IN PVOID SystemSpecific1
,
7671 IN PVOID FunctionContext
,
7672 IN PVOID SystemSpecific2
,
7673 IN PVOID SystemSpecific3
)
7675 RTMP_ADAPTER
*pAd
= (RTMP_ADAPTER
*)FunctionContext
;
7676 #ifdef CONFIG_STA_SUPPORT
7678 CHAR larger
= -127, rssi0
, rssi1
, rssi2
;
7679 #endif // CONFIG_STA_SUPPORT //
7681 #ifdef CONFIG_STA_SUPPORT
7682 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
7684 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_RESET_IN_PROGRESS
) ||
7685 RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
) ||
7686 RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_RADIO_OFF
) ||
7687 RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
))
7690 if (pAd
->StaCfg
.Psm
== PWR_SAVE
)
7694 // if the traffic is low, use average rssi as the criteria
7695 if (pAd
->Mlme
.bLowThroughput
== TRUE
)
7697 rssi0
= pAd
->StaCfg
.RssiSample
.LastRssi0
;
7698 rssi1
= pAd
->StaCfg
.RssiSample
.LastRssi1
;
7699 rssi2
= pAd
->StaCfg
.RssiSample
.LastRssi2
;
7703 rssi0
= pAd
->StaCfg
.RssiSample
.AvgRssi0
;
7704 rssi1
= pAd
->StaCfg
.RssiSample
.AvgRssi1
;
7705 rssi2
= pAd
->StaCfg
.RssiSample
.AvgRssi2
;
7708 if(pAd
->Antenna
.field
.RxPath
== 3)
7710 larger
= max(rssi0
, rssi1
);
7712 if (larger
> (rssi2
+ 20))
7713 pAd
->Mlme
.RealRxPath
= 2;
7715 pAd
->Mlme
.RealRxPath
= 3;
7717 else if(pAd
->Antenna
.field
.RxPath
== 2)
7719 if (rssi0
> (rssi1
+ 20))
7720 pAd
->Mlme
.RealRxPath
= 1;
7722 pAd
->Mlme
.RealRxPath
= 2;
7725 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R3
, &BBPR3
);
7727 if(pAd
->Mlme
.RealRxPath
== 3)
7731 else if(pAd
->Mlme
.RealRxPath
== 2)
7735 else if(pAd
->Mlme
.RealRxPath
== 1)
7739 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R3
, BBPR3
);
7742 #endif // CONFIG_STA_SUPPORT //
7748 VOID
APSDPeriodicExec(
7749 IN PVOID SystemSpecific1
,
7750 IN PVOID FunctionContext
,
7751 IN PVOID SystemSpecific2
,
7752 IN PVOID SystemSpecific3
)
7754 RTMP_ADAPTER
*pAd
= (RTMP_ADAPTER
*)FunctionContext
;
7756 if (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
7759 pAd
->CommonCfg
.TriggerTimerCount
++;
7761 // Driver should not send trigger frame, it should be send by application layer
7763 if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable
7764 && (pAd->CommonCfg.bNeedSendTriggerFrame ||
7765 (((pAd->CommonCfg.TriggerTimerCount%20) == 19) && (!pAd->CommonCfg.bAPSDAC_BE || !pAd->CommonCfg.bAPSDAC_BK || !pAd->CommonCfg.bAPSDAC_VI || !pAd->CommonCfg.bAPSDAC_VO))))
7767 DBGPRINT(RT_DEBUG_TRACE,("Sending trigger frame and enter service period when support APSD\n"));
7768 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
7769 pAd->CommonCfg.bNeedSendTriggerFrame = FALSE;
7770 pAd->CommonCfg.TriggerTimerCount = 0;
7771 pAd->CommonCfg.bInServicePeriod = TRUE;
7776 ========================================================================
7777 Routine Description:
7778 Set/reset MAC registers according to bPiggyBack parameter
7781 pAd - Adapter pointer
7782 bPiggyBack - Enable / Disable Piggy-Back
7787 ========================================================================
7789 VOID
RTMPSetPiggyBack(
7790 IN PRTMP_ADAPTER pAd
,
7791 IN BOOLEAN bPiggyBack
)
7793 TX_LINK_CFG_STRUC TxLinkCfg
;
7795 RTMP_IO_READ32(pAd
, TX_LINK_CFG
, &TxLinkCfg
.word
);
7797 TxLinkCfg
.field
.TxCFAckEn
= bPiggyBack
;
7798 RTMP_IO_WRITE32(pAd
, TX_LINK_CFG
, TxLinkCfg
.word
);
7802 ========================================================================
7803 Routine Description:
7804 check if this entry need to switch rate automatically
7814 ========================================================================
7816 BOOLEAN
RTMPCheckEntryEnableAutoRateSwitch(
7817 IN PRTMP_ADAPTER pAd
,
7818 IN PMAC_TABLE_ENTRY pEntry
)
7820 BOOLEAN result
= TRUE
;
7823 #ifdef CONFIG_STA_SUPPORT
7824 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
7826 // only associated STA counts
7827 if (pEntry
&& (pEntry
->ValidAsCLI
) && (pEntry
->Sst
== SST_ASSOC
))
7829 result
= pAd
->StaCfg
.bAutoTxRateSwitch
;
7834 #endif // CONFIG_STA_SUPPORT //
7842 BOOLEAN
RTMPAutoRateSwitchCheck(
7843 IN PRTMP_ADAPTER pAd
)
7846 #ifdef CONFIG_STA_SUPPORT
7847 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
7849 if (pAd
->StaCfg
.bAutoTxRateSwitch
)
7852 #endif // CONFIG_STA_SUPPORT //
7858 ========================================================================
7859 Routine Description:
7860 check if this entry need to fix tx legacy rate
7870 ========================================================================
7872 UCHAR
RTMPStaFixedTxMode(
7873 IN PRTMP_ADAPTER pAd
,
7874 IN PMAC_TABLE_ENTRY pEntry
)
7876 UCHAR tx_mode
= FIXED_TXMODE_HT
;
7879 #ifdef CONFIG_STA_SUPPORT
7880 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
7882 tx_mode
= (UCHAR
)pAd
->StaCfg
.DesiredTransmitSetting
.field
.FixedTxMode
;
7884 #endif // CONFIG_STA_SUPPORT //
7890 ========================================================================
7891 Routine Description:
7892 Overwrite HT Tx Mode by Fixed Legency Tx Mode, if specified.
7902 ========================================================================
7904 VOID
RTMPUpdateLegacyTxSetting(
7905 UCHAR fixed_tx_mode
,
7906 PMAC_TABLE_ENTRY pEntry
)
7908 HTTRANSMIT_SETTING TransmitSetting
;
7910 if (fixed_tx_mode
== FIXED_TXMODE_HT
)
7913 TransmitSetting
.word
= 0;
7915 TransmitSetting
.field
.MODE
= pEntry
->HTPhyMode
.field
.MODE
;
7916 TransmitSetting
.field
.MCS
= pEntry
->HTPhyMode
.field
.MCS
;
7918 if (fixed_tx_mode
== FIXED_TXMODE_CCK
)
7920 TransmitSetting
.field
.MODE
= MODE_CCK
;
7921 // CCK mode allow MCS 0~3
7922 if (TransmitSetting
.field
.MCS
> MCS_3
)
7923 TransmitSetting
.field
.MCS
= MCS_3
;
7927 TransmitSetting
.field
.MODE
= MODE_OFDM
;
7928 // OFDM mode allow MCS 0~7
7929 if (TransmitSetting
.field
.MCS
> MCS_7
)
7930 TransmitSetting
.field
.MCS
= MCS_7
;
7933 if (pEntry
->HTPhyMode
.field
.MODE
>= TransmitSetting
.field
.MODE
)
7935 pEntry
->HTPhyMode
.word
= TransmitSetting
.word
;
7936 DBGPRINT(RT_DEBUG_TRACE
, ("RTMPUpdateLegacyTxSetting : wcid-%d, MODE=%s, MCS=%d \n",
7937 pEntry
->Aid
, GetPhyMode(pEntry
->HTPhyMode
.field
.MODE
), pEntry
->HTPhyMode
.field
.MCS
));
7941 #ifdef CONFIG_STA_SUPPORT
7943 ==========================================================================
7945 dynamic tune BBP R66 to find a balance between sensibility and
7948 IRQL = DISPATCH_LEVEL
7950 ==========================================================================
7952 VOID
AsicStaBbpTuning(
7953 IN PRTMP_ADAPTER pAd
)
7955 UCHAR OrigR66Value
= 0, R66
;//, R66UpperBound = 0x30, R66LowerBound = 0x30;
7958 // 2860C did not support Fase CCA, therefore can't tune
7959 if (pAd
->MACVersion
== 0x28600100)
7965 if (pAd
->Mlme
.CntlMachine
.CurrState
!= CNTL_IDLE
) // no R66 tuning when SCANNING
7968 if ((pAd
->OpMode
== OPMODE_STA
)
7969 && (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
)
7971 && !(OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_DOZE
))
7974 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R66
, &OrigR66Value
);
7977 if (pAd
->Antenna
.field
.RxPath
> 1)
7978 Rssi
= (pAd
->StaCfg
.RssiSample
.AvgRssi0
+ pAd
->StaCfg
.RssiSample
.AvgRssi1
) >> 1;
7980 Rssi
= pAd
->StaCfg
.RssiSample
.AvgRssi0
;
7982 if (pAd
->LatchRfRegs
.Channel
<= 14)
7985 // RT3070 is a no LNA solution, it should have different control regarding to AGC gain control
7986 // Otherwise, it will have some throughput side effect when low RSSI
7989 if (Rssi
> RSSI_FOR_MID_LOW_SENSIBILITY
)
7991 R66
= 0x1C + 2*GET_LNA_GAIN(pAd
) + 0x20;
7992 if (OrigR66Value
!= R66
)
7994 RTUSBWriteBBPRegister(pAd
, BBP_R66
, R66
);
7999 R66
= 0x1C + 2*GET_LNA_GAIN(pAd
);
8000 if (OrigR66Value
!= R66
)
8002 RTUSBWriteBBPRegister(pAd
, BBP_R66
, R66
);
8009 if (Rssi
> RSSI_FOR_MID_LOW_SENSIBILITY
)
8011 R66
= (0x2E + GET_LNA_GAIN(pAd
)) + 0x10;
8012 if (OrigR66Value
!= R66
)
8014 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8019 R66
= 0x2E + GET_LNA_GAIN(pAd
);
8020 if (OrigR66Value
!= R66
)
8022 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8029 if (pAd
->CommonCfg
.BBPCurrentBW
== BW_20
)
8031 if (Rssi
> RSSI_FOR_MID_LOW_SENSIBILITY
)
8033 R66
= 0x32 + (GET_LNA_GAIN(pAd
)*5)/3 + 0x10;
8034 if (OrigR66Value
!= R66
)
8036 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8041 R66
= 0x32 + (GET_LNA_GAIN(pAd
)*5)/3;
8042 if (OrigR66Value
!= R66
)
8044 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8050 if (Rssi
> RSSI_FOR_MID_LOW_SENSIBILITY
)
8052 R66
= 0x3A + (GET_LNA_GAIN(pAd
)*5)/3 + 0x10;
8053 if (OrigR66Value
!= R66
)
8055 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8060 R66
= 0x3A + (GET_LNA_GAIN(pAd
)*5)/3;
8061 if (OrigR66Value
!= R66
)
8063 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8072 #endif // CONFIG_STA_SUPPORT //
8074 VOID
RTMPSetAGCInitValue(
8075 IN PRTMP_ADAPTER pAd
,
8080 if (pAd
->LatchRfRegs
.Channel
<= 14)
8082 R66
= 0x2E + GET_LNA_GAIN(pAd
);
8083 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8087 if (BandWidth
== BW_20
)
8089 R66
= (UCHAR
)(0x32 + (GET_LNA_GAIN(pAd
)*5)/3);
8090 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8092 #ifdef DOT11_N_SUPPORT
8095 R66
= (UCHAR
)(0x3A + (GET_LNA_GAIN(pAd
)*5)/3);
8096 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8098 #endif // DOT11_N_SUPPORT //
8103 VOID
AsicTurnOffRFClk(
8104 IN PRTMP_ADAPTER pAd
,
8109 UINT32 R1
= 0, R2
= 0, R3
= 0;
8111 RTMP_RF_REGS
*RFRegTable
;
8113 RFRegTable
= RF2850RegTable
;
8115 switch (pAd
->RfIcType
)
8122 for (index
= 0; index
< NUM_OF_2850_CHNL
; index
++)
8124 if (Channel
== RFRegTable
[index
].Channel
)
8126 R1
= RFRegTable
[index
].R1
& 0xffffdfff;
8127 R2
= RFRegTable
[index
].R2
& 0xfffbffff;
8128 R3
= RFRegTable
[index
].R3
& 0xfff3ffff;
8130 RTMP_RF_IO_WRITE32(pAd
, R1
);
8131 RTMP_RF_IO_WRITE32(pAd
, R2
);
8133 // Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0.
8134 // Set RF R2 bit18=0, R3 bit[18:19]=0
8135 //if (pAd->StaCfg.bRadio == FALSE)
8138 RTMP_RF_IO_WRITE32(pAd
, R3
);
8140 DBGPRINT(RT_DEBUG_TRACE
, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x, R3 = 0x%08x \n",
8141 Channel
, pAd
->RfIcType
, R2
, R3
));
8144 DBGPRINT(RT_DEBUG_TRACE
, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n",
8145 Channel
, pAd
->RfIcType
, R2
));
8157 VOID
AsicTurnOnRFClk(
8158 IN PRTMP_ADAPTER pAd
,
8163 UINT32 R1
= 0, R2
= 0, R3
= 0;
8165 RTMP_RF_REGS
*RFRegTable
;
8167 RFRegTable
= RF2850RegTable
;
8169 switch (pAd
->RfIcType
)
8176 for (index
= 0; index
< NUM_OF_2850_CHNL
; index
++)
8178 if (Channel
== RFRegTable
[index
].Channel
)
8180 R3
= pAd
->LatchRfRegs
.R3
;
8183 RTMP_RF_IO_WRITE32(pAd
, R3
);
8185 R1
= RFRegTable
[index
].R1
;
8186 RTMP_RF_IO_WRITE32(pAd
, R1
);
8188 R2
= RFRegTable
[index
].R2
;
8189 if (pAd
->Antenna
.field
.TxPath
== 1)
8191 R2
|= 0x4000; // If TXpath is 1, bit 14 = 1;
8194 if (pAd
->Antenna
.field
.RxPath
== 2)
8196 R2
|= 0x40; // write 1 to off Rxpath.
8198 else if (pAd
->Antenna
.field
.RxPath
== 1)
8200 R2
|= 0x20040; // write 1 to off RxPath
8202 RTMP_RF_IO_WRITE32(pAd
, R2
);
8213 DBGPRINT(RT_DEBUG_TRACE
, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n",