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 DOT11_N_SUPPORT
54 UCHAR PRE_N_HT_OUI
[] = {0x00, 0x90, 0x4c};
55 #endif // DOT11_N_SUPPORT //
57 UCHAR RateSwitchTable
[] = {
58 // 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)
59 0x11, 0x00, 0, 0, 0, // Initial used item after association
60 0x00, 0x00, 0, 40, 101,
61 0x01, 0x00, 1, 40, 50,
62 0x02, 0x00, 2, 35, 45,
63 0x03, 0x00, 3, 20, 45,
64 0x04, 0x21, 0, 30, 50,
65 0x05, 0x21, 1, 20, 50,
66 0x06, 0x21, 2, 20, 50,
67 0x07, 0x21, 3, 15, 50,
68 0x08, 0x21, 4, 15, 30,
69 0x09, 0x21, 5, 10, 25,
72 0x0c, 0x20, 12, 15, 30,
73 0x0d, 0x20, 13, 8, 20,
74 0x0e, 0x20, 14, 8, 20,
75 0x0f, 0x20, 15, 8, 25,
76 0x10, 0x22, 15, 8, 25,
94 UCHAR RateSwitchTable11B
[] = {
95 // 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)
96 0x04, 0x03, 0, 0, 0, // Initial used item after association
97 0x00, 0x00, 0, 40, 101,
98 0x01, 0x00, 1, 40, 50,
99 0x02, 0x00, 2, 35, 45,
100 0x03, 0x00, 3, 20, 45,
103 UCHAR RateSwitchTable11BG
[] = {
104 // 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)
105 0x0a, 0x00, 0, 0, 0, // Initial used item after association
106 0x00, 0x00, 0, 40, 101,
107 0x01, 0x00, 1, 40, 50,
108 0x02, 0x00, 2, 35, 45,
109 0x03, 0x00, 3, 20, 45,
110 0x04, 0x10, 2, 20, 35,
111 0x05, 0x10, 3, 16, 35,
112 0x06, 0x10, 4, 10, 25,
113 0x07, 0x10, 5, 16, 25,
114 0x08, 0x10, 6, 10, 25,
115 0x09, 0x10, 7, 10, 13,
118 UCHAR RateSwitchTable11G
[] = {
119 // 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)
120 0x08, 0x00, 0, 0, 0, // Initial used item after association
121 0x00, 0x10, 0, 20, 101,
122 0x01, 0x10, 1, 20, 35,
123 0x02, 0x10, 2, 20, 35,
124 0x03, 0x10, 3, 16, 35,
125 0x04, 0x10, 4, 10, 25,
126 0x05, 0x10, 5, 16, 25,
127 0x06, 0x10, 6, 10, 25,
128 0x07, 0x10, 7, 10, 13,
131 #ifdef DOT11_N_SUPPORT
132 UCHAR RateSwitchTable11N1S
[] = {
133 // 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)
134 0x09, 0x00, 0, 0, 0, // Initial used item after association
135 0x00, 0x21, 0, 30, 101,
136 0x01, 0x21, 1, 20, 50,
137 0x02, 0x21, 2, 20, 50,
138 0x03, 0x21, 3, 15, 50,
139 0x04, 0x21, 4, 15, 30,
140 0x05, 0x21, 5, 10, 25,
141 0x06, 0x21, 6, 8, 14,
142 0x07, 0x21, 7, 8, 14,
143 0x08, 0x23, 7, 8, 14,
146 UCHAR RateSwitchTable11N2S
[] = {
147 // 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)
148 0x0a, 0x00, 0, 0, 0, // Initial used item after association
149 0x00, 0x21, 0, 30, 101,
150 0x01, 0x21, 1, 20, 50,
151 0x02, 0x21, 2, 20, 50,
152 0x03, 0x21, 3, 15, 50,
153 0x04, 0x21, 4, 15, 30,
154 0x05, 0x20, 12, 15, 30,
155 0x06, 0x20, 13, 8, 20,
156 0x07, 0x20, 14, 8, 20,
157 0x08, 0x20, 15, 8, 25,
158 0x09, 0x22, 15, 8, 25,
161 UCHAR RateSwitchTable11N3S
[] = {
162 // 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)
163 0x0a, 0x00, 0, 0, 0, // Initial used item after association
164 0x00, 0x21, 0, 30, 101,
165 0x01, 0x21, 1, 20, 50,
166 0x02, 0x21, 2, 20, 50,
167 0x03, 0x21, 3, 15, 50,
168 0x04, 0x21, 4, 15, 30,
169 0x05, 0x20, 12, 15, 30,
170 0x06, 0x20, 13, 8, 20,
171 0x07, 0x20, 14, 8, 20,
172 0x08, 0x20, 15, 8, 25,
173 0x09, 0x22, 15, 8, 25,
176 UCHAR RateSwitchTable11N2SForABand
[] = {
177 // 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)
178 0x0b, 0x09, 0, 0, 0, // Initial used item after association
179 0x00, 0x21, 0, 30, 101,
180 0x01, 0x21, 1, 20, 50,
181 0x02, 0x21, 2, 20, 50,
182 0x03, 0x21, 3, 15, 50,
183 0x04, 0x21, 4, 15, 30,
184 0x05, 0x21, 5, 15, 30,
185 0x06, 0x20, 12, 15, 30,
186 0x07, 0x20, 13, 8, 20,
187 0x08, 0x20, 14, 8, 20,
188 0x09, 0x20, 15, 8, 25,
189 0x0a, 0x22, 15, 8, 25,
192 UCHAR RateSwitchTable11N3SForABand
[] = { // 3*3
193 // 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)
194 0x0b, 0x09, 0, 0, 0, // Initial used item after association
195 0x00, 0x21, 0, 30, 101,
196 0x01, 0x21, 1, 20, 50,
197 0x02, 0x21, 2, 20, 50,
198 0x03, 0x21, 3, 15, 50,
199 0x04, 0x21, 4, 15, 30,
200 0x05, 0x21, 5, 15, 30,
201 0x06, 0x20, 12, 15, 30,
202 0x07, 0x20, 13, 8, 20,
203 0x08, 0x20, 14, 8, 20,
204 0x09, 0x20, 15, 8, 25,
205 0x0a, 0x22, 15, 8, 25,
208 UCHAR RateSwitchTable11BGN1S
[] = {
209 // 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)
210 0x0d, 0x00, 0, 0, 0, // Initial used item after association
211 0x00, 0x00, 0, 40, 101,
212 0x01, 0x00, 1, 40, 50,
213 0x02, 0x00, 2, 35, 45,
214 0x03, 0x00, 3, 20, 45,
215 0x04, 0x21, 0, 30,101, //50
216 0x05, 0x21, 1, 20, 50,
217 0x06, 0x21, 2, 20, 50,
218 0x07, 0x21, 3, 15, 50,
219 0x08, 0x21, 4, 15, 30,
220 0x09, 0x21, 5, 10, 25,
221 0x0a, 0x21, 6, 8, 14,
222 0x0b, 0x21, 7, 8, 14,
223 0x0c, 0x23, 7, 8, 14,
226 UCHAR RateSwitchTable11BGN2S
[] = {
227 // 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)
228 0x0a, 0x00, 0, 0, 0, // Initial used item after association
229 0x00, 0x21, 0, 30,101, //50
230 0x01, 0x21, 1, 20, 50,
231 0x02, 0x21, 2, 20, 50,
232 0x03, 0x21, 3, 15, 50,
233 0x04, 0x21, 4, 15, 30,
234 0x05, 0x20, 12, 15, 30,
235 0x06, 0x20, 13, 8, 20,
236 0x07, 0x20, 14, 8, 20,
237 0x08, 0x20, 15, 8, 25,
238 0x09, 0x22, 15, 8, 25,
241 UCHAR RateSwitchTable11BGN3S
[] = { // 3*3
242 // 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)
243 0x0a, 0x00, 0, 0, 0, // Initial used item after association
244 0x00, 0x21, 0, 30,101, //50
245 0x01, 0x21, 1, 20, 50,
246 0x02, 0x21, 2, 20, 50,
247 0x03, 0x21, 3, 20, 50,
248 0x04, 0x21, 4, 15, 50,
249 0x05, 0x20, 20, 15, 30,
250 0x06, 0x20, 21, 8, 20,
251 0x07, 0x20, 22, 8, 20,
252 0x08, 0x20, 23, 8, 25,
253 0x09, 0x22, 23, 8, 25,
256 UCHAR RateSwitchTable11BGN2SForABand
[] = {
257 // 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)
258 0x0b, 0x09, 0, 0, 0, // Initial used item after association
259 0x00, 0x21, 0, 30,101, //50
260 0x01, 0x21, 1, 20, 50,
261 0x02, 0x21, 2, 20, 50,
262 0x03, 0x21, 3, 15, 50,
263 0x04, 0x21, 4, 15, 30,
264 0x05, 0x21, 5, 15, 30,
265 0x06, 0x20, 12, 15, 30,
266 0x07, 0x20, 13, 8, 20,
267 0x08, 0x20, 14, 8, 20,
268 0x09, 0x20, 15, 8, 25,
269 0x0a, 0x22, 15, 8, 25,
272 UCHAR RateSwitchTable11BGN3SForABand
[] = { // 3*3
273 // 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)
274 0x0c, 0x09, 0, 0, 0, // Initial used item after association
275 0x00, 0x21, 0, 30,101, //50
276 0x01, 0x21, 1, 20, 50,
277 0x02, 0x21, 2, 20, 50,
278 0x03, 0x21, 3, 15, 50,
279 0x04, 0x21, 4, 15, 30,
280 0x05, 0x21, 5, 15, 30,
281 0x06, 0x21, 12, 15, 30,
282 0x07, 0x20, 20, 15, 30,
283 0x08, 0x20, 21, 8, 20,
284 0x09, 0x20, 22, 8, 20,
285 0x0a, 0x20, 23, 8, 25,
286 0x0b, 0x22, 23, 8, 25,
288 #endif // DOT11_N_SUPPORT //
290 PUCHAR ReasonString
[] = {
292 /* 1 */ "Unspecified Reason",
293 /* 2 */ "Previous Auth no longer valid",
294 /* 3 */ "STA is leaving / has left",
295 /* 4 */ "DIS-ASSOC due to inactivity",
296 /* 5 */ "AP unable to hanle all associations",
297 /* 6 */ "class 2 error",
298 /* 7 */ "class 3 error",
299 /* 8 */ "STA is leaving / has left",
300 /* 9 */ "require auth before assoc/re-assoc",
304 /* 13 */ "invalid IE",
305 /* 14 */ "MIC error",
306 /* 15 */ "4-way handshake timeout",
307 /* 16 */ "2-way (group key) handshake timeout",
308 /* 17 */ "4-way handshake IE diff among AssosReq/Rsp/Beacon",
312 extern UCHAR OfdmRateToRxwiMCS
[];
313 // since RT61 has better RX sensibility, we have to limit TX ACK rate not to exceed our normal data TX rate.
314 // otherwise the WLAN peer may not be able to receive the ACK thus downgrade its data TX rate
315 ULONG BasicRateMask
[12] = {0xfffff001 /* 1-Mbps */, 0xfffff003 /* 2 Mbps */, 0xfffff007 /* 5.5 */, 0xfffff00f /* 11 */,
316 0xfffff01f /* 6 */ , 0xfffff03f /* 9 */ , 0xfffff07f /* 12 */ , 0xfffff0ff /* 18 */,
317 0xfffff1ff /* 24 */ , 0xfffff3ff /* 36 */ , 0xfffff7ff /* 48 */ , 0xffffffff /* 54 */};
319 UCHAR MULTICAST_ADDR
[MAC_ADDR_LEN
] = {0x1, 0x00, 0x00, 0x00, 0x00, 0x00};
320 UCHAR BROADCAST_ADDR
[MAC_ADDR_LEN
] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
321 UCHAR ZERO_MAC_ADDR
[MAC_ADDR_LEN
] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
323 // e.g. RssiSafeLevelForTxRate[RATE_36]" means if the current RSSI is greater than
324 // this value, then it's quaranteed capable of operating in 36 mbps TX rate in
325 // clean environment.
326 // TxRate: 1 2 5.5 11 6 9 12 18 24 36 48 54 72 100
327 CHAR RssiSafeLevelForTxRate
[] ={ -92, -91, -90, -87, -88, -86, -85, -83, -81, -78, -72, -71, -40, -40 };
329 UCHAR RateIdToMbps
[] = { 1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 72, 100};
330 USHORT RateIdTo500Kbps
[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 144, 200};
332 UCHAR SsidIe
= IE_SSID
;
333 UCHAR SupRateIe
= IE_SUPP_RATES
;
334 UCHAR ExtRateIe
= IE_EXT_SUPP_RATES
;
335 #ifdef DOT11_N_SUPPORT
336 UCHAR HtCapIe
= IE_HT_CAP
;
337 UCHAR AddHtInfoIe
= IE_ADD_HT
;
338 UCHAR NewExtChanIe
= IE_SECONDARY_CH_OFFSET
;
339 #endif // DOT11_N_SUPPORT //
340 UCHAR ErpIe
= IE_ERP
;
341 UCHAR DsIe
= IE_DS_PARM
;
342 UCHAR TimIe
= IE_TIM
;
343 UCHAR WpaIe
= IE_WPA
;
344 UCHAR Wpa2Ie
= IE_WPA2
;
345 UCHAR IbssIe
= IE_IBSS_PARM
;
346 UCHAR Ccx2Ie
= IE_CCX_V2
;
348 extern UCHAR WPA_OUI
[];
350 UCHAR SES_OUI
[] = {0x00, 0x90, 0x4c};
352 UCHAR ZeroSsid
[32] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
353 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
355 // Reset the RFIC setting to new series
356 RTMP_RF_REGS RF2850RegTable
[] = {
357 // ch R1 R2 R3(TX0~4=0) R4
358 {1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b},
359 {2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f},
360 {3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b},
361 {4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f},
362 {5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b},
363 {6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f},
364 {7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b},
365 {8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f},
366 {9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b},
367 {10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f},
368 {11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b},
369 {12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f},
370 {13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b},
371 {14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193},
373 // 802.11 UNI / HyperLan 2
374 {36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3},
375 {38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193},
376 {40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183},
377 {44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3},
378 {46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b},
379 {48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b},
380 {52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193},
381 {54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3},
382 {56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b},
383 {60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183},
384 {62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193},
385 {64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3}, // Plugfest#4, Day4, change RFR3 left4th 9->5.
388 {100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783},
390 // 2008.04.30 modified
391 // The system team has AN to improve the EVM value
392 // for channel 102 to 108 for the RT2850/RT2750 dual band solution.
393 {102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793},
394 {104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3},
395 {108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193},
397 {110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183},
398 {112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b},
399 {116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3},
400 {118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193},
401 {120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183},
402 {124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193},
403 {126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}, // 0x980ed1bb->0x980ed15b required by Rory 20070927
404 {128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3},
405 {132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b},
406 {134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193},
407 {136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b},
408 {140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183},
411 {149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7},
412 {151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187},
413 {153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f},
414 {157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f},
415 {159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7},
416 {161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187},
417 {165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197},
420 {184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b},
421 {188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13},
422 {192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b},
423 {196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23},
424 {208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13},
425 {212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b},
426 {216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23},
428 // still lack of MMAC(Japan) ch 34,38,42,46
430 UCHAR NUM_OF_2850_CHNL
= (sizeof(RF2850RegTable
) / sizeof(RTMP_RF_REGS
));
432 FREQUENCY_ITEM FreqItems3020
[] =
434 /**************************************************/
435 // ISM : 2.4 to 2.483 GHz //
436 /**************************************************/
438 /**************************************************/
439 //-CH---N-------R---K-----------
455 #define NUM_OF_3020_CHNL (sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM))
458 ==========================================================================
460 initialize the MLME task and its data structure (queue, spinlock,
461 timer, state machines).
466 always return NDIS_STATUS_SUCCESS
468 ==========================================================================
470 NDIS_STATUS
MlmeInit(
471 IN PRTMP_ADAPTER pAd
)
473 NDIS_STATUS Status
= NDIS_STATUS_SUCCESS
;
475 DBGPRINT(RT_DEBUG_TRACE
, ("--> MLME Initialize\n"));
479 Status
= MlmeQueueInit(&pAd
->Mlme
.Queue
);
480 if(Status
!= NDIS_STATUS_SUCCESS
)
483 pAd
->Mlme
.bRunning
= FALSE
;
484 NdisAllocateSpinLock(&pAd
->Mlme
.TaskLock
);
486 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
488 BssTableInit(&pAd
->ScanTab
);
490 // init STA state machines
491 AssocStateMachineInit(pAd
, &pAd
->Mlme
.AssocMachine
, pAd
->Mlme
.AssocFunc
);
492 AuthStateMachineInit(pAd
, &pAd
->Mlme
.AuthMachine
, pAd
->Mlme
.AuthFunc
);
493 AuthRspStateMachineInit(pAd
, &pAd
->Mlme
.AuthRspMachine
, pAd
->Mlme
.AuthRspFunc
);
494 SyncStateMachineInit(pAd
, &pAd
->Mlme
.SyncMachine
, pAd
->Mlme
.SyncFunc
);
495 WpaPskStateMachineInit(pAd
, &pAd
->Mlme
.WpaPskMachine
, pAd
->Mlme
.WpaPskFunc
);
496 AironetStateMachineInit(pAd
, &pAd
->Mlme
.AironetMachine
, pAd
->Mlme
.AironetFunc
);
498 // Since we are using switch/case to implement it, the init is different from the above
499 // state machine init
500 MlmeCntlInit(pAd
, &pAd
->Mlme
.CntlMachine
, NULL
);
503 ActionStateMachineInit(pAd
, &pAd
->Mlme
.ActMachine
, pAd
->Mlme
.ActFunc
);
505 // Init mlme periodic timer
506 RTMPInitTimer(pAd
, &pAd
->Mlme
.PeriodicTimer
, GET_TIMER_FUNCTION(MlmePeriodicExec
), pAd
, TRUE
);
508 // Set mlme periodic timer
509 RTMPSetTimer(&pAd
->Mlme
.PeriodicTimer
, MLME_TASK_EXEC_INTV
);
511 // software-based RX Antenna diversity
512 RTMPInitTimer(pAd
, &pAd
->Mlme
.RxAntEvalTimer
, GET_TIMER_FUNCTION(AsicRxAntEvalTimeout
), pAd
, FALSE
);
514 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
516 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE
))
518 // only PCIe cards need these two timers
519 RTMPInitTimer(pAd
, &pAd
->Mlme
.PsPollTimer
, GET_TIMER_FUNCTION(PsPollWakeExec
), pAd
, FALSE
);
520 RTMPInitTimer(pAd
, &pAd
->Mlme
.RadioOnOffTimer
, GET_TIMER_FUNCTION(RadioOnExec
), pAd
, FALSE
);
525 DBGPRINT(RT_DEBUG_TRACE
, ("<-- MLME Initialize\n"));
531 ==========================================================================
533 main loop of the MLME
535 Mlme has to be initialized, and there are something inside the queue
537 This function is invoked from MPSetInformation and MPReceive;
538 This task guarantee only one MlmeHandler will run.
540 IRQL = DISPATCH_LEVEL
542 ==========================================================================
545 IN PRTMP_ADAPTER pAd
)
547 MLME_QUEUE_ELEM
*Elem
= NULL
;
549 // Only accept MLME and Frame from peer side, no other (control/data) frame should
550 // get into this state machine
552 NdisAcquireSpinLock(&pAd
->Mlme
.TaskLock
);
553 if(pAd
->Mlme
.bRunning
)
555 NdisReleaseSpinLock(&pAd
->Mlme
.TaskLock
);
560 pAd
->Mlme
.bRunning
= TRUE
;
562 NdisReleaseSpinLock(&pAd
->Mlme
.TaskLock
);
564 while (!MlmeQueueEmpty(&pAd
->Mlme
.Queue
))
566 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS
) ||
567 RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
) ||
568 RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
))
570 DBGPRINT(RT_DEBUG_TRACE
, ("Device Halted or Removed or MlmeRest, exit MlmeHandler! (queue num = %ld)\n", pAd
->Mlme
.Queue
.Num
));
574 //From message type, determine which state machine I should drive
575 if (MlmeDequeue(&pAd
->Mlme
.Queue
, &Elem
))
578 // if dequeue success
579 switch (Elem
->Machine
)
581 // STA state machines
582 case ASSOC_STATE_MACHINE
:
583 StateMachinePerformAction(pAd
, &pAd
->Mlme
.AssocMachine
, Elem
);
585 case AUTH_STATE_MACHINE
:
586 StateMachinePerformAction(pAd
, &pAd
->Mlme
.AuthMachine
, Elem
);
588 case AUTH_RSP_STATE_MACHINE
:
589 StateMachinePerformAction(pAd
, &pAd
->Mlme
.AuthRspMachine
, Elem
);
591 case SYNC_STATE_MACHINE
:
592 StateMachinePerformAction(pAd
, &pAd
->Mlme
.SyncMachine
, Elem
);
594 case MLME_CNTL_STATE_MACHINE
:
595 MlmeCntlMachinePerformAction(pAd
, &pAd
->Mlme
.CntlMachine
, Elem
);
597 case WPA_PSK_STATE_MACHINE
:
598 StateMachinePerformAction(pAd
, &pAd
->Mlme
.WpaPskMachine
, Elem
);
600 case AIRONET_STATE_MACHINE
:
601 StateMachinePerformAction(pAd
, &pAd
->Mlme
.AironetMachine
, Elem
);
603 case ACTION_STATE_MACHINE
:
604 StateMachinePerformAction(pAd
, &pAd
->Mlme
.ActMachine
, Elem
);
611 DBGPRINT(RT_DEBUG_TRACE
, ("ERROR: Illegal machine %ld in MlmeHandler()\n", Elem
->Machine
));
616 Elem
->Occupied
= FALSE
;
621 DBGPRINT_ERR(("MlmeHandler: MlmeQueue empty\n"));
625 NdisAcquireSpinLock(&pAd
->Mlme
.TaskLock
);
626 pAd
->Mlme
.bRunning
= FALSE
;
627 NdisReleaseSpinLock(&pAd
->Mlme
.TaskLock
);
631 ==========================================================================
633 Destructor of MLME (Destroy queue, state machine, spin lock and timer)
635 Adapter - NIC Adapter pointer
637 The MLME task will no longer work properly
641 ==========================================================================
644 IN PRTMP_ADAPTER pAd
)
648 DBGPRINT(RT_DEBUG_TRACE
, ("==> MlmeHalt\n"));
650 if (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
))
652 // disable BEACON generation and other BEACON related hardware timers
653 AsicDisableSync(pAd
);
656 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
658 // Cancel pending timers
659 RTMPCancelTimer(&pAd
->MlmeAux
.AssocTimer
, &Cancelled
);
660 RTMPCancelTimer(&pAd
->MlmeAux
.ReassocTimer
, &Cancelled
);
661 RTMPCancelTimer(&pAd
->MlmeAux
.DisassocTimer
, &Cancelled
);
662 RTMPCancelTimer(&pAd
->MlmeAux
.AuthTimer
, &Cancelled
);
663 RTMPCancelTimer(&pAd
->MlmeAux
.BeaconTimer
, &Cancelled
);
664 RTMPCancelTimer(&pAd
->MlmeAux
.ScanTimer
, &Cancelled
);
665 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE
))
667 RTMPCancelTimer(&pAd
->Mlme
.PsPollTimer
, &Cancelled
);
668 RTMPCancelTimer(&pAd
->Mlme
.RadioOnOffTimer
, &Cancelled
);
672 RTMPCancelTimer(&pAd
->Mlme
.PeriodicTimer
, &Cancelled
);
673 RTMPCancelTimer(&pAd
->Mlme
.RxAntEvalTimer
, &Cancelled
);
677 if (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
))
680 RTMPSetLED(pAd
, LED_HALT
);
681 RTMPSetSignalLED(pAd
, -100); // Force signal strength Led to be turned off, firmware is not done it.
684 RTMPusecDelay(5000); // 5 msec to gurantee Ant Diversity timer canceled
686 MlmeQueueDestroy(&pAd
->Mlme
.Queue
);
687 NdisFreeSpinLock(&pAd
->Mlme
.TaskLock
);
689 DBGPRINT(RT_DEBUG_TRACE
, ("<== MlmeHalt\n"));
692 VOID
MlmeResetRalinkCounters(
693 IN PRTMP_ADAPTER pAd
)
695 pAd
->RalinkCounters
.LastOneSecRxOkDataCnt
= pAd
->RalinkCounters
.OneSecRxOkDataCnt
;
696 // clear all OneSecxxx counters.
697 pAd
->RalinkCounters
.OneSecBeaconSentCnt
= 0;
698 pAd
->RalinkCounters
.OneSecFalseCCACnt
= 0;
699 pAd
->RalinkCounters
.OneSecRxFcsErrCnt
= 0;
700 pAd
->RalinkCounters
.OneSecRxOkCnt
= 0;
701 pAd
->RalinkCounters
.OneSecTxFailCount
= 0;
702 pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
= 0;
703 pAd
->RalinkCounters
.OneSecTxRetryOkCount
= 0;
704 pAd
->RalinkCounters
.OneSecRxOkDataCnt
= 0;
706 // TODO: for debug only. to be removed
707 pAd
->RalinkCounters
.OneSecOsTxCount
[QID_AC_BE
] = 0;
708 pAd
->RalinkCounters
.OneSecOsTxCount
[QID_AC_BK
] = 0;
709 pAd
->RalinkCounters
.OneSecOsTxCount
[QID_AC_VI
] = 0;
710 pAd
->RalinkCounters
.OneSecOsTxCount
[QID_AC_VO
] = 0;
711 pAd
->RalinkCounters
.OneSecDmaDoneCount
[QID_AC_BE
] = 0;
712 pAd
->RalinkCounters
.OneSecDmaDoneCount
[QID_AC_BK
] = 0;
713 pAd
->RalinkCounters
.OneSecDmaDoneCount
[QID_AC_VI
] = 0;
714 pAd
->RalinkCounters
.OneSecDmaDoneCount
[QID_AC_VO
] = 0;
715 pAd
->RalinkCounters
.OneSecTxDoneCount
= 0;
716 pAd
->RalinkCounters
.OneSecRxCount
= 0;
717 pAd
->RalinkCounters
.OneSecTxAggregationCount
= 0;
718 pAd
->RalinkCounters
.OneSecRxAggregationCount
= 0;
723 unsigned long rx_AMSDU
;
724 unsigned long rx_Total
;
727 ==========================================================================
729 This routine is executed periodically to -
730 1. Decide if it's a right time to turn on PwrMgmt bit of all
732 2. Calculate ChannelQuality based on statistics of the last
733 period, so that TX rate won't toggling very frequently between a
734 successful TX and a failed TX.
735 3. If the calculated ChannelQuality indicated current connection not
736 healthy, then a ROAMing attempt is tried here.
738 IRQL = DISPATCH_LEVEL
740 ==========================================================================
742 #define ADHOC_BEACON_LOST_TIME (8*OS_HZ) // 8 sec
743 VOID
MlmePeriodicExec(
744 IN PVOID SystemSpecific1
,
745 IN PVOID FunctionContext
,
746 IN PVOID SystemSpecific2
,
747 IN PVOID SystemSpecific3
)
750 PRTMP_ADAPTER pAd
= (RTMP_ADAPTER
*)FunctionContext
;
753 //printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus));
754 //If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0.
755 //If the STA security setting is WPAPSK or WPA2PSK, pAd->StaCfg.WpaSupplicantUP = 1.
756 if(pAd
->StaCfg
.WepStatus
<2)
758 pAd
->StaCfg
.WpaSupplicantUP
= 0;
762 pAd
->StaCfg
.WpaSupplicantUP
= 1;
765 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
767 // If Hardware controlled Radio enabled, we have to check GPIO pin2 every 2 second.
768 // Move code to here, because following code will return when radio is off
769 if ((pAd
->Mlme
.PeriodicRound
% (MLME_TASK_EXEC_MULTIPLE
* 2) == 0) &&
770 (pAd
->StaCfg
.bHardwareRadio
== TRUE
) &&
771 (RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_START_UP
)) &&
772 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
)) &&
773 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
)))
777 // Read GPIO pin2 as Hardware controlled radio state
778 RTMP_IO_FORCE_READ32(pAd
, GPIO_CTRL_CFG
, &data
);
781 pAd
->StaCfg
.bHwRadio
= TRUE
;
785 pAd
->StaCfg
.bHwRadio
= FALSE
;
787 if (pAd
->StaCfg
.bRadio
!= (pAd
->StaCfg
.bHwRadio
&& pAd
->StaCfg
.bSwRadio
))
789 pAd
->StaCfg
.bRadio
= (pAd
->StaCfg
.bHwRadio
&& pAd
->StaCfg
.bSwRadio
);
790 if (pAd
->StaCfg
.bRadio
== TRUE
)
793 // Update extra information
794 pAd
->ExtraInfo
= EXTRA_INFO_CLEAR
;
799 // Update extra information
800 pAd
->ExtraInfo
= HW_RADIO_OFF
;
806 // Do nothing if the driver is starting halt state.
807 // This might happen when timer already been fired before cancel timer with mlmehalt
808 if ((RTMP_TEST_FLAG(pAd
, (fRTMP_ADAPTER_HALT_IN_PROGRESS
|
809 fRTMP_ADAPTER_RADIO_OFF
|
810 fRTMP_ADAPTER_RADIO_MEASUREMENT
|
811 fRTMP_ADAPTER_RESET_IN_PROGRESS
))))
814 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
816 if ((pAd
->RalinkCounters
.LastReceivedByteCount
== pAd
->RalinkCounters
.ReceivedByteCount
) && (pAd
->StaCfg
.bRadio
== TRUE
))
818 // If ReceiveByteCount doesn't change, increase SameRxByteCount by 1.
819 pAd
->SameRxByteCount
++;
822 pAd
->SameRxByteCount
= 0;
824 // If after BBP, still not work...need to check to reset PBF&MAC.
825 if (pAd
->SameRxByteCount
== 702)
827 pAd
->SameRxByteCount
= 0;
832 // If SameRxByteCount keeps happens for 2 second in infra mode, or for 60 seconds in idle mode.
833 if (((INFRA_ON(pAd
)) && (pAd
->SameRxByteCount
> 20)) || ((IDLE_ON(pAd
)) && (pAd
->SameRxByteCount
> 600)))
835 if ((pAd
->StaCfg
.bRadio
== TRUE
) && (pAd
->SameRxByteCount
< 700))
837 DBGPRINT(RT_DEBUG_TRACE
, ("---> SameRxByteCount = %lu !!!!!!!!!!!!!!! \n", pAd
->SameRxByteCount
));
838 pAd
->SameRxByteCount
= 700;
843 // Update lastReceiveByteCount.
844 pAd
->RalinkCounters
.LastReceivedByteCount
= pAd
->RalinkCounters
.ReceivedByteCount
;
846 if ((pAd
->CheckDmaBusyCount
> 3) && (IDLE_ON(pAd
)))
848 pAd
->CheckDmaBusyCount
= 0;
849 AsicResetFromDMABusy(pAd
);
853 RT28XX_MLME_PRE_SANITY_CHECK(pAd
);
855 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
857 // Do nothing if monitor mode is on
861 if (pAd
->Mlme
.PeriodicRound
& 0x1)
863 // This is the fix for wifi 11n extension channel overlapping test case. for 2860D
864 if (((pAd
->MACVersion
& 0xffff) == 0x0101) &&
865 (STA_TGN_WIFI_ON(pAd
)) &&
866 (pAd
->CommonCfg
.IOTestParm
.bToggle
== FALSE
))
869 RTMP_IO_WRITE32(pAd
, TXOP_CTRL_CFG
, 0x24Bf);
870 pAd
->CommonCfg
.IOTestParm
.bToggle
= TRUE
;
872 else if ((STA_TGN_WIFI_ON(pAd
)) &&
873 ((pAd
->MACVersion
& 0xffff) == 0x0101))
875 RTMP_IO_WRITE32(pAd
, TXOP_CTRL_CFG
, 0x243f);
876 pAd
->CommonCfg
.IOTestParm
.bToggle
= FALSE
;
881 pAd
->bUpdateBcnCntDone
= FALSE
;
883 // RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3);
884 pAd
->Mlme
.PeriodicRound
++;
886 // execute every 500ms
887 if ((pAd
->Mlme
.PeriodicRound
% 5 == 0) && RTMPAutoRateSwitchCheck(pAd
)/*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))*/)
889 // perform dynamic tx rate switching based on past TX history
890 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
892 if ((OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
)
894 && (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_DOZE
)))
895 MlmeDynamicTxRateSwitching(pAd
);
899 // Normal 1 second Mlme PeriodicExec.
900 if (pAd
->Mlme
.PeriodicRound
%MLME_TASK_EXEC_MULTIPLE
== 0)
902 pAd
->Mlme
.OneSecPeriodicRound
++;
912 // Media status changed, report to NDIS
913 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_MEDIA_STATE_CHANGE
))
915 RTMP_CLEAR_FLAG(pAd
, fRTMP_ADAPTER_MEDIA_STATE_CHANGE
);
916 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
918 pAd
->IndicateMediaState
= NdisMediaStateConnected
;
919 RTMP_IndicateMediaState(pAd
);
924 pAd
->IndicateMediaState
= NdisMediaStateDisconnected
;
925 RTMP_IndicateMediaState(pAd
);
929 NdisGetSystemUpTime(&pAd
->Mlme
.Now32
);
931 // add the most up-to-date h/w raw counters into software variable, so that
932 // the dynamic tuning mechanism below are based on most up-to-date information
933 NICUpdateRawCounters(pAd
);
936 #ifdef DOT11_N_SUPPORT
937 // Need statistics after read counter. So put after NICUpdateRawCounters
938 ORIBATimerTimeout(pAd
);
939 #endif // DOT11_N_SUPPORT //
942 // The time period for checking antenna is according to traffic
943 if (pAd
->Mlme
.bEnableAutoAntennaCheck
)
945 TxTotalCnt
= pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
+
946 pAd
->RalinkCounters
.OneSecTxRetryOkCount
+
947 pAd
->RalinkCounters
.OneSecTxFailCount
;
951 if (pAd
->Mlme
.OneSecPeriodicRound
% 10 == 0)
953 AsicEvaluateRxAnt(pAd
);
958 if (pAd
->Mlme
.OneSecPeriodicRound
% 3 == 0)
960 AsicEvaluateRxAnt(pAd
);
965 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
966 STAMlmePeriodicExec(pAd
);
968 MlmeResetRalinkCounters(pAd
);
970 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
972 if (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
) && (pAd
->bPCIclkOff
== FALSE
))
974 // When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock
975 // and sending CTS-to-self over and over.
976 // Software Patch Solution:
977 // 1. Polling debug state register 0x10F4 every one second.
978 // 2. If in 0x10F4 the ((bit29==1) && (bit7==1)) OR ((bit29==1) && (bit5==1)), it means the deadlock has occurred.
979 // 3. If the deadlock occurred, reset MAC/BBP by setting 0x1004 to 0x0001 for a while then setting it back to 0x000C again.
983 RTMP_IO_READ32(pAd
, 0x10F4, &MacReg
);
984 if (((MacReg
& 0x20000000) && (MacReg
& 0x80)) || ((MacReg
& 0x20000000) && (MacReg
& 0x20)))
986 RTMP_IO_WRITE32(pAd
, MAC_SYS_CTRL
, 0x1);
988 RTMP_IO_WRITE32(pAd
, MAC_SYS_CTRL
, 0xC);
990 DBGPRINT(RT_DEBUG_WARN
,("Warning, MAC specific condition occurs \n"));
995 RT28XX_MLME_HANDLER(pAd
);
999 pAd
->bUpdateBcnCntDone
= FALSE
;
1002 VOID
STAMlmePeriodicExec(
1007 #ifdef WPA_SUPPLICANT_SUPPORT
1008 if (pAd
->StaCfg
.WpaSupplicantUP
== WPA_SUPPLICANT_DISABLE
)
1009 #endif // WPA_SUPPLICANT_SUPPORT //
1011 // WPA MIC error should block association attempt for 60 seconds
1012 if (pAd
->StaCfg
.bBlockAssoc
&& (pAd
->StaCfg
.LastMicErrorTime
+ (60 * OS_HZ
) < pAd
->Mlme
.Now32
))
1013 pAd
->StaCfg
.bBlockAssoc
= FALSE
;
1017 //printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus));
1018 //If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0.
1019 //If the STA security setting is WPAPSK or WPA2PSK, pAd->StaCfg.WpaSupplicantUP = 1.
1020 if(pAd
->StaCfg
.WepStatus
<2)
1022 pAd
->StaCfg
.WpaSupplicantUP
= 0;
1026 pAd
->StaCfg
.WpaSupplicantUP
= 1;
1029 if ((pAd
->PreMediaState
!= pAd
->IndicateMediaState
) && (pAd
->CommonCfg
.bWirelessEvent
))
1031 if (pAd
->IndicateMediaState
== NdisMediaStateConnected
)
1033 RTMPSendWirelessEvent(pAd
, IW_STA_LINKUP_EVENT_FLAG
, pAd
->MacTab
.Content
[BSSID_WCID
].Addr
, BSS0
, 0);
1035 pAd
->PreMediaState
= pAd
->IndicateMediaState
;
1038 if ((pAd
->OpMode
== OPMODE_STA
) && (IDLE_ON(pAd
)) &&
1039 (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE
)) &&
1040 (pAd
->Mlme
.SyncMachine
.CurrState
== SYNC_IDLE
) &&
1041 (pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_IDLE
) &&
1042 (RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_START_UP
)) &&
1043 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_IDLE_RADIO_OFF
)))
1045 RT28xxPciAsicRadioOff(pAd
, GUI_IDLE_POWER_SAVE
, 0);
1050 AsicStaBbpTuning(pAd
);
1052 TxTotalCnt
= pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
+
1053 pAd
->RalinkCounters
.OneSecTxRetryOkCount
+
1054 pAd
->RalinkCounters
.OneSecTxFailCount
;
1056 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
1058 // update channel quality for Roaming and UI LinkQuality display
1059 MlmeCalculateChannelQuality(pAd
, pAd
->Mlme
.Now32
);
1062 // must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if
1063 // Radio is currently in noisy environment
1064 if (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS
))
1065 AsicAdjustTxPower(pAd
);
1069 // Is PSM bit consistent with user power management policy?
1070 // This is the only place that will set PSM bit ON.
1071 if (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_DOZE
))
1072 MlmeCheckPsmChange(pAd
, pAd
->Mlme
.Now32
);
1074 pAd
->RalinkCounters
.LastOneSecTotalTxCount
= TxTotalCnt
;
1076 if ((pAd
->StaCfg
.LastBeaconRxTime
+ 1*OS_HZ
< pAd
->Mlme
.Now32
) &&
1077 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS
)) &&
1078 ((TxTotalCnt
+ pAd
->RalinkCounters
.OneSecRxOkCnt
< 600)))
1080 RTMPSetAGCInitValue(pAd
, BW_20
);
1081 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n", (0x2E + GET_LNA_GAIN(pAd
))));
1085 if (pAd
->CommonCfg
.bAPSDCapable
&& pAd
->CommonCfg
.APEdcaParm
.bAPSDCapable
)
1087 // When APSD is enabled, the period changes as 20 sec
1088 if ((pAd
->Mlme
.OneSecPeriodicRound
% 20) == 8)
1089 RTMPSendNullFrame(pAd
, pAd
->CommonCfg
.TxRate
, TRUE
);
1093 // Send out a NULL frame every 10 sec to inform AP that STA is still alive (Avoid being age out)
1094 if ((pAd
->Mlme
.OneSecPeriodicRound
% 10) == 8)
1096 if (pAd
->CommonCfg
.bWmmCapable
)
1097 RTMPSendNullFrame(pAd
, pAd
->CommonCfg
.TxRate
, TRUE
);
1099 RTMPSendNullFrame(pAd
, pAd
->CommonCfg
.TxRate
, FALSE
);
1104 if (CQI_IS_DEAD(pAd
->Mlme
.ChannelQuality
))
1106 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n", pAd
->RalinkCounters
.BadCQIAutoRecoveryCount
));
1107 pAd
->StaCfg
.CCXAdjacentAPReportFlag
= TRUE
;
1108 pAd
->StaCfg
.CCXAdjacentAPLinkDownTime
= pAd
->StaCfg
.LastBeaconRxTime
;
1110 // Lost AP, send disconnect & link down event
1111 LinkDown(pAd
, FALSE
);
1114 union iwreq_data wrqu
;
1115 memset(wrqu
.ap_addr
.sa_data
, 0, MAC_ADDR_LEN
);
1116 wireless_send_event(pAd
->net_dev
, SIOCGIWAP
, &wrqu
, NULL
);
1119 MlmeAutoReconnectLastSSID(pAd
);
1121 else if (CQI_IS_BAD(pAd
->Mlme
.ChannelQuality
))
1123 pAd
->RalinkCounters
.BadCQIAutoRecoveryCount
++;
1124 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - Bad CQI. Auto Recovery attempt #%ld\n", pAd
->RalinkCounters
.BadCQIAutoRecoveryCount
));
1125 MlmeAutoReconnectLastSSID(pAd
);
1128 // Add auto seamless roaming
1129 if (pAd
->StaCfg
.bFastRoaming
)
1131 SHORT dBmToRoam
= (SHORT
)pAd
->StaCfg
.dBmToRoam
;
1133 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
));
1135 if (RTMPMaxRssi(pAd
, pAd
->StaCfg
.RssiSample
.LastRssi0
, pAd
->StaCfg
.RssiSample
.LastRssi1
, pAd
->StaCfg
.RssiSample
.LastRssi2
) <= (CHAR
)dBmToRoam
)
1137 MlmeCheckForFastRoaming(pAd
, pAd
->Mlme
.Now32
);
1141 else if (ADHOC_ON(pAd
))
1143 // 2003-04-17 john. this is a patch that driver forces a BEACON out if ASIC fails
1144 // the "TX BEACON competition" for the entire past 1 sec.
1145 // So that even when ASIC's BEACONgen engine been blocked
1146 // by peer's BEACON due to slower system clock, this STA still can send out
1147 // minimum BEACON to tell the peer I'm alive.
1148 // drawback is that this BEACON won't be well aligned at TBTT boundary.
1149 // EnqueueBeaconFrame(pAd); // software send BEACON
1151 // if all 11b peers leave this BSS more than 5 seconds, update Tx rate,
1152 // restore outgoing BEACON to support B/G-mixed mode
1153 if ((pAd
->CommonCfg
.Channel
<= 14) &&
1154 (pAd
->CommonCfg
.MaxTxRate
<= RATE_11
) &&
1155 (pAd
->CommonCfg
.MaxDesiredRate
> RATE_11
) &&
1156 ((pAd
->StaCfg
.Last11bBeaconRxTime
+ 5*OS_HZ
) < pAd
->Mlme
.Now32
))
1158 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - last 11B peer left, update Tx rates\n"));
1159 NdisMoveMemory(pAd
->StaActive
.SupRate
, pAd
->CommonCfg
.SupRate
, MAX_LEN_OF_SUPPORTED_RATES
);
1160 pAd
->StaActive
.SupRateLen
= pAd
->CommonCfg
.SupRateLen
;
1161 MlmeUpdateTxRates(pAd
, FALSE
, 0);
1162 MakeIbssBeacon(pAd
); // re-build BEACON frame
1163 AsicEnableIbssSync(pAd
); // copy to on-chip memory
1164 pAd
->StaCfg
.AdhocBOnlyJoined
= FALSE
;
1167 #ifdef DOT11_N_SUPPORT
1168 if (pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
)
1170 if ((pAd
->StaCfg
.AdhocBGJoined
) &&
1171 ((pAd
->StaCfg
.Last11gBeaconRxTime
+ 5 * OS_HZ
) < pAd
->Mlme
.Now32
))
1173 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - last 11G peer left\n"));
1174 pAd
->StaCfg
.AdhocBGJoined
= FALSE
;
1177 if ((pAd
->StaCfg
.Adhoc20NJoined
) &&
1178 ((pAd
->StaCfg
.Last20NBeaconRxTime
+ 5 * OS_HZ
) < pAd
->Mlme
.Now32
))
1180 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - last 20MHz N peer left\n"));
1181 pAd
->StaCfg
.Adhoc20NJoined
= FALSE
;
1184 #endif // DOT11_N_SUPPORT //
1187 if ((pAd
->CommonCfg
.Channel
> 14)
1188 && (pAd
->CommonCfg
.bIEEE80211H
== 1)
1189 && RadarChannelCheck(pAd
, pAd
->CommonCfg
.Channel
))
1191 RadarDetectPeriodic(pAd
);
1194 // If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState
1195 // to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can
1197 if ((pAd
->StaCfg
.LastBeaconRxTime
+ ADHOC_BEACON_LOST_TIME
< pAd
->Mlme
.Now32
) &&
1198 OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
1200 MLME_START_REQ_STRUCT StartReq
;
1202 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n"));
1203 LinkDown(pAd
, FALSE
);
1205 StartParmFill(pAd
, &StartReq
, pAd
->MlmeAux
.Ssid
, pAd
->MlmeAux
.SsidLen
);
1206 MlmeEnqueue(pAd
, SYNC_STATE_MACHINE
, MT2_MLME_START_REQ
, sizeof(MLME_START_REQ_STRUCT
), &StartReq
);
1207 pAd
->Mlme
.CntlMachine
.CurrState
= CNTL_WAIT_START
;
1210 else // no INFRA nor ADHOC connection
1213 if (pAd
->StaCfg
.bScanReqIsFromWebUI
&&
1214 ((pAd
->StaCfg
.LastScanTime
+ 30 * OS_HZ
) > pAd
->Mlme
.Now32
))
1215 goto SKIP_AUTO_SCAN_CONN
;
1217 pAd
->StaCfg
.bScanReqIsFromWebUI
= FALSE
;
1219 if ((pAd
->StaCfg
.bAutoReconnect
== TRUE
)
1220 && RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_START_UP
)
1221 && (MlmeValidateSSID(pAd
->MlmeAux
.AutoReconnectSsid
, pAd
->MlmeAux
.AutoReconnectSsidLen
) == TRUE
))
1223 if ((pAd
->ScanTab
.BssNr
==0) && (pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_IDLE
))
1225 MLME_SCAN_REQ_STRUCT ScanReq
;
1227 if ((pAd
->StaCfg
.LastScanTime
+ 10 * OS_HZ
) < pAd
->Mlme
.Now32
)
1229 DBGPRINT(RT_DEBUG_TRACE
, ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, start a new ACTIVE scan SSID[%s]\n", pAd
->MlmeAux
.AutoReconnectSsid
));
1230 ScanParmFill(pAd
, &ScanReq
, pAd
->MlmeAux
.AutoReconnectSsid
, pAd
->MlmeAux
.AutoReconnectSsidLen
, BSS_ANY
, SCAN_ACTIVE
);
1231 MlmeEnqueue(pAd
, SYNC_STATE_MACHINE
, MT2_MLME_SCAN_REQ
, sizeof(MLME_SCAN_REQ_STRUCT
), &ScanReq
);
1232 pAd
->Mlme
.CntlMachine
.CurrState
= CNTL_WAIT_OID_LIST_SCAN
;
1233 // Reset Missed scan number
1234 pAd
->StaCfg
.LastScanTime
= pAd
->Mlme
.Now32
;
1236 else if (pAd
->StaCfg
.BssType
== BSS_ADHOC
) // Quit the forever scan when in a very clean room
1237 MlmeAutoReconnectLastSSID(pAd
);
1239 else if (pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_IDLE
)
1241 if ((pAd
->Mlme
.OneSecPeriodicRound
% 7) == 0)
1244 pAd
->StaCfg
.LastScanTime
= pAd
->Mlme
.Now32
;
1248 MlmeAutoReconnectLastSSID(pAd
);
1254 SKIP_AUTO_SCAN_CONN
:
1256 #ifdef DOT11_N_SUPPORT
1257 if ((pAd
->MacTab
.Content
[BSSID_WCID
].TXBAbitmap
!=0) && (pAd
->MacTab
.fAnyBASession
== FALSE
))
1259 pAd
->MacTab
.fAnyBASession
= TRUE
;
1260 AsicUpdateProtect(pAd
, HT_FORCERTSCTS
, ALLN_SETPROTECT
, FALSE
, FALSE
);
1262 else if ((pAd
->MacTab
.Content
[BSSID_WCID
].TXBAbitmap
==0) && (pAd
->MacTab
.fAnyBASession
== TRUE
))
1264 pAd
->MacTab
.fAnyBASession
= FALSE
;
1265 AsicUpdateProtect(pAd
, pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
, ALLN_SETPROTECT
, FALSE
, FALSE
);
1267 #endif // DOT11_N_SUPPORT //
1274 IN PVOID SystemSpecific1
,
1275 IN PVOID FunctionContext
,
1276 IN PVOID SystemSpecific2
,
1277 IN PVOID SystemSpecific3
)
1280 RTMP_ADAPTER
*pAd
= (RTMP_ADAPTER
*)FunctionContext
;
1282 pAd
->IndicateMediaState
= NdisMediaStateDisconnected
;
1283 RTMP_IndicateMediaState(pAd
);
1284 pAd
->ExtraInfo
= GENERAL_LINK_DOWN
;
1287 // IRQL = DISPATCH_LEVEL
1289 IN PRTMP_ADAPTER pAd
)
1291 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1292 if (pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_IDLE
)
1294 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - Driver auto scan\n"));
1296 MLME_CNTL_STATE_MACHINE
,
1297 OID_802_11_BSSID_LIST_SCAN
,
1300 RT28XX_MLME_HANDLER(pAd
);
1304 // IRQL = DISPATCH_LEVEL
1305 VOID
MlmeAutoReconnectLastSSID(
1306 IN PRTMP_ADAPTER pAd
)
1310 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1311 if ((pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_IDLE
) &&
1312 (MlmeValidateSSID(pAd
->MlmeAux
.AutoReconnectSsid
, pAd
->MlmeAux
.AutoReconnectSsidLen
) == TRUE
))
1314 NDIS_802_11_SSID OidSsid
;
1315 OidSsid
.SsidLength
= pAd
->MlmeAux
.AutoReconnectSsidLen
;
1316 NdisMoveMemory(OidSsid
.Ssid
, pAd
->MlmeAux
.AutoReconnectSsid
, pAd
->MlmeAux
.AutoReconnectSsidLen
);
1318 DBGPRINT(RT_DEBUG_TRACE
, ("Driver auto reconnect to last OID_802_11_SSID setting - %s, len - %d\n", pAd
->MlmeAux
.AutoReconnectSsid
, pAd
->MlmeAux
.AutoReconnectSsidLen
));
1320 MLME_CNTL_STATE_MACHINE
,
1322 sizeof(NDIS_802_11_SSID
),
1324 RT28XX_MLME_HANDLER(pAd
);
1329 ==========================================================================
1330 Validate SSID for connection try and rescan purpose
1331 Valid SSID will have visible chars only.
1332 The valid length is from 0 to 32.
1333 IRQL = DISPATCH_LEVEL
1334 ==========================================================================
1336 BOOLEAN
MlmeValidateSSID(
1342 if (SsidLen
> MAX_LEN_OF_SSID
)
1345 // Check each character value
1346 for (index
= 0; index
< SsidLen
; index
++)
1348 if (pSsid
[index
] < 0x20)
1356 VOID
MlmeSelectTxRateTable(
1357 IN PRTMP_ADAPTER pAd
,
1358 IN PMAC_TABLE_ENTRY pEntry
,
1360 IN PUCHAR pTableSize
,
1361 IN PUCHAR pInitTxRateIdx
)
1365 // decide the rate table for tuning
1366 if (pAd
->CommonCfg
.TxRateTableSize
> 0)
1368 *ppTable
= RateSwitchTable
;
1369 *pTableSize
= RateSwitchTable
[0];
1370 *pInitTxRateIdx
= RateSwitchTable
[1];
1375 if ((pAd
->OpMode
== OPMODE_STA
) && ADHOC_ON(pAd
))
1377 #ifdef DOT11_N_SUPPORT
1378 if ((pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
) &&
1379 !pAd
->StaCfg
.AdhocBOnlyJoined
&&
1380 !pAd
->StaCfg
.AdhocBGJoined
&&
1381 (pAd
->StaActive
.SupportedPhyInfo
.MCSSet
[0] == 0xff) &&
1382 ((pAd
->StaActive
.SupportedPhyInfo
.MCSSet
[1] == 0x00) || (pAd
->Antenna
.field
.TxPath
== 1)))
1384 *ppTable
= RateSwitchTable11N1S
;
1385 *pTableSize
= RateSwitchTable11N1S
[0];
1386 *pInitTxRateIdx
= RateSwitchTable11N1S
[1];
1389 else if ((pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
) &&
1390 !pAd
->StaCfg
.AdhocBOnlyJoined
&&
1391 !pAd
->StaCfg
.AdhocBGJoined
&&
1392 (pAd
->StaActive
.SupportedPhyInfo
.MCSSet
[0] == 0xff) &&
1393 (pAd
->StaActive
.SupportedPhyInfo
.MCSSet
[1] == 0xff) &&
1394 (pAd
->Antenna
.field
.TxPath
== 2))
1396 if (pAd
->LatchRfRegs
.Channel
<= 14)
1398 *ppTable
= RateSwitchTable11N2S
;
1399 *pTableSize
= RateSwitchTable11N2S
[0];
1400 *pInitTxRateIdx
= RateSwitchTable11N2S
[1];
1404 *ppTable
= RateSwitchTable11N2SForABand
;
1405 *pTableSize
= RateSwitchTable11N2SForABand
[0];
1406 *pInitTxRateIdx
= RateSwitchTable11N2SForABand
[1];
1411 #endif // DOT11_N_SUPPORT //
1412 if (pAd
->CommonCfg
.PhyMode
== PHY_11B
)
1414 *ppTable
= RateSwitchTable11B
;
1415 *pTableSize
= RateSwitchTable11B
[0];
1416 *pInitTxRateIdx
= RateSwitchTable11B
[1];
1419 else if((pAd
->LatchRfRegs
.Channel
<= 14) && (pAd
->StaCfg
.AdhocBOnlyJoined
== TRUE
))
1421 // USe B Table when Only b-only Station in my IBSS .
1422 *ppTable
= RateSwitchTable11B
;
1423 *pTableSize
= RateSwitchTable11B
[0];
1424 *pInitTxRateIdx
= RateSwitchTable11B
[1];
1427 else if (pAd
->LatchRfRegs
.Channel
<= 14)
1429 *ppTable
= RateSwitchTable11BG
;
1430 *pTableSize
= RateSwitchTable11BG
[0];
1431 *pInitTxRateIdx
= RateSwitchTable11BG
[1];
1436 *ppTable
= RateSwitchTable11G
;
1437 *pTableSize
= RateSwitchTable11G
[0];
1438 *pInitTxRateIdx
= RateSwitchTable11G
[1];
1444 #ifdef DOT11_N_SUPPORT
1445 if ((pEntry
->RateLen
== 12) && (pEntry
->HTCapability
.MCSSet
[0] == 0xff) &&
1446 ((pEntry
->HTCapability
.MCSSet
[1] == 0x00) || (pAd
->CommonCfg
.TxStream
== 1)))
1448 *ppTable
= RateSwitchTable11BGN1S
;
1449 *pTableSize
= RateSwitchTable11BGN1S
[0];
1450 *pInitTxRateIdx
= RateSwitchTable11BGN1S
[1];
1455 if ((pEntry
->RateLen
== 12) && (pEntry
->HTCapability
.MCSSet
[0] == 0xff) &&
1456 (pEntry
->HTCapability
.MCSSet
[1] == 0xff) && (pAd
->CommonCfg
.TxStream
== 2))
1458 if (pAd
->LatchRfRegs
.Channel
<= 14)
1460 *ppTable
= RateSwitchTable11BGN2S
;
1461 *pTableSize
= RateSwitchTable11BGN2S
[0];
1462 *pInitTxRateIdx
= RateSwitchTable11BGN2S
[1];
1467 *ppTable
= RateSwitchTable11BGN2SForABand
;
1468 *pTableSize
= RateSwitchTable11BGN2SForABand
[0];
1469 *pInitTxRateIdx
= RateSwitchTable11BGN2SForABand
[1];
1475 if ((pEntry
->HTCapability
.MCSSet
[0] == 0xff) && ((pEntry
->HTCapability
.MCSSet
[1] == 0x00) || (pAd
->CommonCfg
.TxStream
== 1)))
1477 *ppTable
= RateSwitchTable11N1S
;
1478 *pTableSize
= RateSwitchTable11N1S
[0];
1479 *pInitTxRateIdx
= RateSwitchTable11N1S
[1];
1484 if ((pEntry
->HTCapability
.MCSSet
[0] == 0xff) && (pEntry
->HTCapability
.MCSSet
[1] == 0xff) && (pAd
->CommonCfg
.TxStream
== 2))
1486 if (pAd
->LatchRfRegs
.Channel
<= 14)
1488 *ppTable
= RateSwitchTable11N2S
;
1489 *pTableSize
= RateSwitchTable11N2S
[0];
1490 *pInitTxRateIdx
= RateSwitchTable11N2S
[1];
1494 *ppTable
= RateSwitchTable11N2SForABand
;
1495 *pTableSize
= RateSwitchTable11N2SForABand
[0];
1496 *pInitTxRateIdx
= RateSwitchTable11N2SForABand
[1];
1501 #endif // DOT11_N_SUPPORT //
1502 //else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1503 if ((pEntry
->RateLen
== 4)
1504 #ifdef DOT11_N_SUPPORT
1505 && (pEntry
->HTCapability
.MCSSet
[0] == 0) && (pEntry
->HTCapability
.MCSSet
[1] == 0)
1506 #endif // DOT11_N_SUPPORT //
1509 *ppTable
= RateSwitchTable11B
;
1510 *pTableSize
= RateSwitchTable11B
[0];
1511 *pInitTxRateIdx
= RateSwitchTable11B
[1];
1516 //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1517 if ((pEntry
->RateLen
> 8)
1518 #ifdef DOT11_N_SUPPORT
1519 && (pEntry
->HTCapability
.MCSSet
[0] == 0) && (pEntry
->HTCapability
.MCSSet
[1] == 0)
1520 #endif // DOT11_N_SUPPORT //
1523 *ppTable
= RateSwitchTable11BG
;
1524 *pTableSize
= RateSwitchTable11BG
[0];
1525 *pInitTxRateIdx
= RateSwitchTable11BG
[1];
1530 //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1531 if ((pEntry
->RateLen
== 8)
1532 #ifdef DOT11_N_SUPPORT
1533 && (pEntry
->HTCapability
.MCSSet
[0] == 0) && (pEntry
->HTCapability
.MCSSet
[1] == 0)
1534 #endif // DOT11_N_SUPPORT //
1537 *ppTable
= RateSwitchTable11G
;
1538 *pTableSize
= RateSwitchTable11G
[0];
1539 *pInitTxRateIdx
= RateSwitchTable11G
[1];
1543 #ifdef DOT11_N_SUPPORT
1544 #endif // DOT11_N_SUPPORT //
1546 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
1548 #ifdef DOT11_N_SUPPORT
1549 //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1550 if ((pEntry
->HTCapability
.MCSSet
[0] == 0) && (pEntry
->HTCapability
.MCSSet
[1] == 0))
1551 #endif // DOT11_N_SUPPORT //
1553 if (pAd
->CommonCfg
.MaxTxRate
<= RATE_11
)
1555 *ppTable
= RateSwitchTable11B
;
1556 *pTableSize
= RateSwitchTable11B
[0];
1557 *pInitTxRateIdx
= RateSwitchTable11B
[1];
1559 else if ((pAd
->CommonCfg
.MaxTxRate
> RATE_11
) && (pAd
->CommonCfg
.MinTxRate
> RATE_11
))
1561 *ppTable
= RateSwitchTable11G
;
1562 *pTableSize
= RateSwitchTable11G
[0];
1563 *pInitTxRateIdx
= RateSwitchTable11G
[1];
1568 *ppTable
= RateSwitchTable11BG
;
1569 *pTableSize
= RateSwitchTable11BG
[0];
1570 *pInitTxRateIdx
= RateSwitchTable11BG
[1];
1574 #ifdef DOT11_N_SUPPORT
1575 if (pAd
->LatchRfRegs
.Channel
<= 14)
1577 if (pAd
->CommonCfg
.TxStream
== 1)
1579 *ppTable
= RateSwitchTable11N1S
;
1580 *pTableSize
= RateSwitchTable11N1S
[0];
1581 *pInitTxRateIdx
= RateSwitchTable11N1S
[1];
1582 DBGPRINT_RAW(RT_DEBUG_ERROR
,("DRS: unkown mode,default use 11N 1S AP \n"));
1586 *ppTable
= RateSwitchTable11N2S
;
1587 *pTableSize
= RateSwitchTable11N2S
[0];
1588 *pInitTxRateIdx
= RateSwitchTable11N2S
[1];
1589 DBGPRINT_RAW(RT_DEBUG_ERROR
,("DRS: unkown mode,default use 11N 2S AP \n"));
1594 if (pAd
->CommonCfg
.TxStream
== 1)
1596 *ppTable
= RateSwitchTable11N1S
;
1597 *pTableSize
= RateSwitchTable11N1S
[0];
1598 *pInitTxRateIdx
= RateSwitchTable11N1S
[1];
1599 DBGPRINT_RAW(RT_DEBUG_ERROR
,("DRS: unkown mode,default use 11N 1S AP \n"));
1603 *ppTable
= RateSwitchTable11N2SForABand
;
1604 *pTableSize
= RateSwitchTable11N2SForABand
[0];
1605 *pInitTxRateIdx
= RateSwitchTable11N2SForABand
[1];
1606 DBGPRINT_RAW(RT_DEBUG_ERROR
,("DRS: unkown mode,default use 11N 2S AP \n"));
1609 #endif // DOT11_N_SUPPORT //
1610 DBGPRINT_RAW(RT_DEBUG_ERROR
,("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n",
1611 pAd
->StaActive
.SupRateLen
, pAd
->StaActive
.ExtRateLen
, pAd
->StaActive
.SupportedPhyInfo
.MCSSet
[0], pAd
->StaActive
.SupportedPhyInfo
.MCSSet
[1]));
1617 ==========================================================================
1619 This routine checks if there're other APs out there capable for
1620 roaming. Caller should call this routine only when Link up in INFRA mode
1621 and channel quality is below CQI_GOOD_THRESHOLD.
1623 IRQL = DISPATCH_LEVEL
1626 ==========================================================================
1628 VOID
MlmeCheckForRoaming(
1629 IN PRTMP_ADAPTER pAd
,
1633 BSS_TABLE
*pRoamTab
= &pAd
->MlmeAux
.RoamTab
;
1636 DBGPRINT(RT_DEBUG_TRACE
, ("==> MlmeCheckForRoaming\n"));
1637 // put all roaming candidates into RoamTab, and sort in RSSI order
1638 BssTableInit(pRoamTab
);
1639 for (i
= 0; i
< pAd
->ScanTab
.BssNr
; i
++)
1641 pBss
= &pAd
->ScanTab
.BssEntry
[i
];
1643 if ((pBss
->LastBeaconRxTime
+ BEACON_LOST_TIME
) < Now32
)
1644 continue; // AP disappear
1645 if (pBss
->Rssi
<= RSSI_THRESHOLD_FOR_ROAMING
)
1646 continue; // RSSI too weak. forget it.
1647 if (MAC_ADDR_EQUAL(pBss
->Bssid
, pAd
->CommonCfg
.Bssid
))
1648 continue; // skip current AP
1649 if (pBss
->Rssi
< (pAd
->StaCfg
.RssiSample
.LastRssi0
+ RSSI_DELTA
))
1650 continue; // only AP with stronger RSSI is eligible for roaming
1652 // AP passing all above rules is put into roaming candidate table
1653 NdisMoveMemory(&pRoamTab
->BssEntry
[pRoamTab
->BssNr
], pBss
, sizeof(BSS_ENTRY
));
1654 pRoamTab
->BssNr
+= 1;
1657 if (pRoamTab
->BssNr
> 0)
1659 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1660 if (pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_IDLE
)
1662 pAd
->RalinkCounters
.PoorCQIRoamingCount
++;
1663 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - Roaming attempt #%ld\n", pAd
->RalinkCounters
.PoorCQIRoamingCount
));
1664 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_MLME_ROAMING_REQ
, 0, NULL
);
1665 RT28XX_MLME_HANDLER(pAd
);
1668 DBGPRINT(RT_DEBUG_TRACE
, ("<== MlmeCheckForRoaming(# of candidate= %d)\n",pRoamTab
->BssNr
));
1672 ==========================================================================
1674 This routine checks if there're other APs out there capable for
1675 roaming. Caller should call this routine only when link up in INFRA mode
1676 and channel quality is below CQI_GOOD_THRESHOLD.
1678 IRQL = DISPATCH_LEVEL
1681 ==========================================================================
1683 VOID
MlmeCheckForFastRoaming(
1684 IN PRTMP_ADAPTER pAd
,
1688 BSS_TABLE
*pRoamTab
= &pAd
->MlmeAux
.RoamTab
;
1691 DBGPRINT(RT_DEBUG_TRACE
, ("==> MlmeCheckForFastRoaming\n"));
1692 // put all roaming candidates into RoamTab, and sort in RSSI order
1693 BssTableInit(pRoamTab
);
1694 for (i
= 0; i
< pAd
->ScanTab
.BssNr
; i
++)
1696 pBss
= &pAd
->ScanTab
.BssEntry
[i
];
1698 if ((pBss
->Rssi
<= -50) && (pBss
->Channel
== pAd
->CommonCfg
.Channel
))
1699 continue; // RSSI too weak. forget it.
1700 if (MAC_ADDR_EQUAL(pBss
->Bssid
, pAd
->CommonCfg
.Bssid
))
1701 continue; // skip current AP
1702 if (!SSID_EQUAL(pBss
->Ssid
, pBss
->SsidLen
, pAd
->CommonCfg
.Ssid
, pAd
->CommonCfg
.SsidLen
))
1703 continue; // skip different SSID
1704 if (pBss
->Rssi
< (RTMPMaxRssi(pAd
, pAd
->StaCfg
.RssiSample
.LastRssi0
, pAd
->StaCfg
.RssiSample
.LastRssi1
, pAd
->StaCfg
.RssiSample
.LastRssi2
) + RSSI_DELTA
))
1705 continue; // skip AP without better RSSI
1707 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
));
1708 // AP passing all above rules is put into roaming candidate table
1709 NdisMoveMemory(&pRoamTab
->BssEntry
[pRoamTab
->BssNr
], pBss
, sizeof(BSS_ENTRY
));
1710 pRoamTab
->BssNr
+= 1;
1713 if (pRoamTab
->BssNr
> 0)
1715 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1716 if (pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_IDLE
)
1718 pAd
->RalinkCounters
.PoorCQIRoamingCount
++;
1719 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - Roaming attempt #%ld\n", pAd
->RalinkCounters
.PoorCQIRoamingCount
));
1720 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_MLME_ROAMING_REQ
, 0, NULL
);
1721 RT28XX_MLME_HANDLER(pAd
);
1724 // Maybe site survey required
1727 if ((pAd
->StaCfg
.LastScanTime
+ 10 * 1000) < Now
)
1729 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1730 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - Roaming, No eligable entry, try new scan!\n"));
1731 pAd
->StaCfg
.ScanCnt
= 2;
1732 pAd
->StaCfg
.LastScanTime
= Now
;
1737 DBGPRINT(RT_DEBUG_TRACE
, ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab
->BssNr
));
1741 ==========================================================================
1743 This routine calculates TxPER, RxPER of the past N-sec period. And
1744 according to the calculation result, ChannelQuality is calculated here
1745 to decide if current AP is still doing the job.
1747 If ChannelQuality is not good, a ROAMing attempt may be tried later.
1749 StaCfg.ChannelQuality - 0..100
1751 IRQL = DISPATCH_LEVEL
1753 NOTE: This routine decide channle quality based on RX CRC error ratio.
1754 Caller should make sure a function call to NICUpdateRawCounters(pAd)
1755 is performed right before this routine, so that this routine can decide
1756 channel quality based on the most up-to-date information
1757 ==========================================================================
1759 VOID
MlmeCalculateChannelQuality(
1760 IN PRTMP_ADAPTER pAd
,
1763 ULONG TxOkCnt
, TxCnt
, TxPER
, TxPRR
;
1767 ULONG BeaconLostTime
= BEACON_LOST_TIME
;
1769 MaxRssi
= RTMPMaxRssi(pAd
, pAd
->StaCfg
.RssiSample
.LastRssi0
, pAd
->StaCfg
.RssiSample
.LastRssi1
, pAd
->StaCfg
.RssiSample
.LastRssi2
);
1772 // calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics
1774 TxOkCnt
= pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
+ pAd
->RalinkCounters
.OneSecTxRetryOkCount
;
1775 TxCnt
= TxOkCnt
+ pAd
->RalinkCounters
.OneSecTxFailCount
;
1783 TxPER
= (pAd
->RalinkCounters
.OneSecTxFailCount
* 100) / TxCnt
;
1784 TxPRR
= ((TxCnt
- pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
) * 100) / TxCnt
;
1788 // calculate RX PER - don't take RxPER into consideration if too few sample
1790 RxCnt
= pAd
->RalinkCounters
.OneSecRxOkCnt
+ pAd
->RalinkCounters
.OneSecRxFcsErrCnt
;
1794 RxPER
= (pAd
->RalinkCounters
.OneSecRxFcsErrCnt
* 100) / RxCnt
;
1797 // decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER
1799 if (INFRA_ON(pAd
) &&
1800 (pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
< 2) && // no heavy traffic
1801 (pAd
->StaCfg
.LastBeaconRxTime
+ BeaconLostTime
< Now32
))
1803 DBGPRINT(RT_DEBUG_TRACE
, ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n", BeaconLostTime
, TxOkCnt
));
1804 pAd
->Mlme
.ChannelQuality
= 0;
1811 else if (MaxRssi
< -90)
1814 NorRssi
= (MaxRssi
+ 90) * 2;
1816 // ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER (RSSI 0..100), (TxPER 100..0), (RxPER 100..0)
1817 pAd
->Mlme
.ChannelQuality
= (RSSI_WEIGHTING
* NorRssi
+
1818 TX_WEIGHTING
* (100 - TxPRR
) +
1819 RX_WEIGHTING
* (100 - RxPER
)) / 100;
1820 if (pAd
->Mlme
.ChannelQuality
>= 100)
1821 pAd
->Mlme
.ChannelQuality
= 100;
1827 IN PRTMP_ADAPTER pAd
,
1828 IN PMAC_TABLE_ENTRY pEntry
,
1829 IN PRTMP_TX_RATE_SWITCH pTxRate
)
1831 UCHAR MaxMode
= MODE_OFDM
;
1833 #ifdef DOT11_N_SUPPORT
1834 MaxMode
= MODE_HTGREENFIELD
;
1836 if (pTxRate
->STBC
&& (pAd
->StaCfg
.MaxHTPhyMode
.field
.STBC
) && (pAd
->Antenna
.field
.TxPath
== 2))
1837 pAd
->StaCfg
.HTPhyMode
.field
.STBC
= STBC_USE
;
1839 #endif // DOT11_N_SUPPORT //
1840 pAd
->StaCfg
.HTPhyMode
.field
.STBC
= STBC_NONE
;
1842 if (pTxRate
->CurrMCS
< MCS_AUTO
)
1843 pAd
->StaCfg
.HTPhyMode
.field
.MCS
= pTxRate
->CurrMCS
;
1845 if (pAd
->StaCfg
.HTPhyMode
.field
.MCS
> 7)
1846 pAd
->StaCfg
.HTPhyMode
.field
.STBC
= STBC_NONE
;
1850 // If peer adhoc is b-only mode, we can't send 11g rate.
1851 pAd
->StaCfg
.HTPhyMode
.field
.ShortGI
= GI_800
;
1852 pEntry
->HTPhyMode
.field
.STBC
= STBC_NONE
;
1855 // For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary
1857 pEntry
->HTPhyMode
.field
.MODE
= pTxRate
->Mode
;
1858 pEntry
->HTPhyMode
.field
.ShortGI
= pAd
->StaCfg
.HTPhyMode
.field
.ShortGI
;
1859 pEntry
->HTPhyMode
.field
.MCS
= pAd
->StaCfg
.HTPhyMode
.field
.MCS
;
1861 // Patch speed error in status page
1862 pAd
->StaCfg
.HTPhyMode
.field
.MODE
= pEntry
->HTPhyMode
.field
.MODE
;
1866 if (pTxRate
->Mode
<= MaxMode
)
1867 pAd
->StaCfg
.HTPhyMode
.field
.MODE
= pTxRate
->Mode
;
1869 #ifdef DOT11_N_SUPPORT
1870 if (pTxRate
->ShortGI
&& (pAd
->StaCfg
.MaxHTPhyMode
.field
.ShortGI
))
1871 pAd
->StaCfg
.HTPhyMode
.field
.ShortGI
= GI_400
;
1873 #endif // DOT11_N_SUPPORT //
1874 pAd
->StaCfg
.HTPhyMode
.field
.ShortGI
= GI_800
;
1876 #ifdef DOT11_N_SUPPORT
1877 // Reexam each bandwidth's SGI support.
1878 if (pAd
->StaCfg
.HTPhyMode
.field
.ShortGI
== GI_400
)
1880 if ((pEntry
->HTPhyMode
.field
.BW
== BW_20
) && (!CLIENT_STATUS_TEST_FLAG(pEntry
, fCLIENT_STATUS_SGI20_CAPABLE
)))
1881 pAd
->StaCfg
.HTPhyMode
.field
.ShortGI
= GI_800
;
1882 if ((pEntry
->HTPhyMode
.field
.BW
== BW_40
) && (!CLIENT_STATUS_TEST_FLAG(pEntry
, fCLIENT_STATUS_SGI40_CAPABLE
)))
1883 pAd
->StaCfg
.HTPhyMode
.field
.ShortGI
= GI_800
;
1886 // Turn RTS/CTS rate to 6Mbps.
1887 if ((pEntry
->HTPhyMode
.field
.MCS
== 0) && (pAd
->StaCfg
.HTPhyMode
.field
.MCS
!= 0))
1889 pEntry
->HTPhyMode
.field
.MCS
= pAd
->StaCfg
.HTPhyMode
.field
.MCS
;
1890 if (pAd
->MacTab
.fAnyBASession
)
1892 AsicUpdateProtect(pAd
, HT_FORCERTSCTS
, ALLN_SETPROTECT
, TRUE
, (BOOLEAN
)pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
);
1896 AsicUpdateProtect(pAd
, pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
, ALLN_SETPROTECT
, TRUE
, (BOOLEAN
)pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
);
1899 else if ((pEntry
->HTPhyMode
.field
.MCS
== 8) && (pAd
->StaCfg
.HTPhyMode
.field
.MCS
!= 8))
1901 pEntry
->HTPhyMode
.field
.MCS
= pAd
->StaCfg
.HTPhyMode
.field
.MCS
;
1902 if (pAd
->MacTab
.fAnyBASession
)
1904 AsicUpdateProtect(pAd
, HT_FORCERTSCTS
, ALLN_SETPROTECT
, TRUE
, (BOOLEAN
)pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
);
1908 AsicUpdateProtect(pAd
, pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
, ALLN_SETPROTECT
, TRUE
, (BOOLEAN
)pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
);
1911 else if ((pEntry
->HTPhyMode
.field
.MCS
!= 0) && (pAd
->StaCfg
.HTPhyMode
.field
.MCS
== 0))
1913 AsicUpdateProtect(pAd
, HT_RTSCTS_6M
, ALLN_SETPROTECT
, TRUE
, (BOOLEAN
)pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
);
1916 else if ((pEntry
->HTPhyMode
.field
.MCS
!= 8) && (pAd
->StaCfg
.HTPhyMode
.field
.MCS
== 8))
1918 AsicUpdateProtect(pAd
, HT_RTSCTS_6M
, ALLN_SETPROTECT
, TRUE
, (BOOLEAN
)pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
);
1920 #endif // DOT11_N_SUPPORT //
1922 pEntry
->HTPhyMode
.field
.STBC
= pAd
->StaCfg
.HTPhyMode
.field
.STBC
;
1923 pEntry
->HTPhyMode
.field
.ShortGI
= pAd
->StaCfg
.HTPhyMode
.field
.ShortGI
;
1924 pEntry
->HTPhyMode
.field
.MCS
= pAd
->StaCfg
.HTPhyMode
.field
.MCS
;
1925 pEntry
->HTPhyMode
.field
.MODE
= pAd
->StaCfg
.HTPhyMode
.field
.MODE
;
1926 #ifdef DOT11_N_SUPPORT
1927 if ((pAd
->StaCfg
.MaxHTPhyMode
.field
.MODE
== MODE_HTGREENFIELD
) &&
1928 pAd
->WIFItestbed
.bGreenField
)
1929 pEntry
->HTPhyMode
.field
.MODE
= MODE_HTGREENFIELD
;
1930 #endif // DOT11_N_SUPPORT //
1933 pAd
->LastTxRate
= (USHORT
)(pEntry
->HTPhyMode
.word
);
1937 ==========================================================================
1939 This routine calculates the acumulated TxPER of eaxh TxRate. And
1940 according to the calculation result, change CommonCfg.TxRate which
1941 is the stable TX Rate we expect the Radio situation could sustained.
1943 CommonCfg.TxRate will change dynamically within {RATE_1/RATE_6, MaxTxRate}
1947 IRQL = DISPATCH_LEVEL
1950 call this routine every second
1951 ==========================================================================
1953 VOID
MlmeDynamicTxRateSwitching(
1954 IN PRTMP_ADAPTER pAd
)
1956 UCHAR UpRateIdx
= 0, DownRateIdx
= 0, CurrRateIdx
;
1957 ULONG i
, AccuTxTotalCnt
= 0, TxTotalCnt
;
1958 ULONG TxErrorRatio
= 0;
1959 BOOLEAN bTxRateChanged
, bUpgradeQuality
= FALSE
;
1960 PRTMP_TX_RATE_SWITCH pCurrTxRate
, pNextTxRate
= NULL
;
1962 UCHAR TableSize
= 0;
1963 UCHAR InitTxRateIdx
= 0, TrainUp
, TrainDown
;
1964 CHAR Rssi
, RssiOffset
= 0;
1965 TX_STA_CNT1_STRUC StaTx1
;
1966 TX_STA_CNT0_STRUC TxStaCnt0
;
1967 ULONG TxRetransmit
= 0, TxSuccess
= 0, TxFailCount
= 0;
1968 MAC_TABLE_ENTRY
*pEntry
;
1970 /*if (pAd->Antenna.field.RxPath > 1)
1971 Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
1973 Rssi = pAd->StaCfg.RssiSample.AvgRssi0;*/
1976 // walk through MAC table, see if need to change AP's TX rate toward each entry
1978 for (i
= 1; i
< MAX_LEN_OF_MAC_TABLE
; i
++)
1980 pEntry
= &pAd
->MacTab
.Content
[i
];
1982 // check if this entry need to switch rate automatically
1983 if (RTMPCheckEntryEnableAutoRateSwitch(pAd
, pEntry
) == FALSE
)
1986 if ((pAd
->MacTab
.Size
== 1) || (pEntry
->ValidAsDls
))
1988 Rssi
= RTMPMaxRssi(pAd
, (CHAR
)pAd
->StaCfg
.RssiSample
.AvgRssi0
, (CHAR
)pAd
->StaCfg
.RssiSample
.AvgRssi1
, (CHAR
)pAd
->StaCfg
.RssiSample
.AvgRssi2
);
1990 // Update statistic counter
1991 RTMP_IO_READ32(pAd
, TX_STA_CNT0
, &TxStaCnt0
.word
);
1992 RTMP_IO_READ32(pAd
, TX_STA_CNT1
, &StaTx1
.word
);
1993 pAd
->bUpdateBcnCntDone
= TRUE
;
1994 TxRetransmit
= StaTx1
.field
.TxRetransmit
;
1995 TxSuccess
= StaTx1
.field
.TxSuccess
;
1996 TxFailCount
= TxStaCnt0
.field
.TxFailCount
;
1997 TxTotalCnt
= TxRetransmit
+ TxSuccess
+ TxFailCount
;
1999 pAd
->RalinkCounters
.OneSecTxRetryOkCount
+= StaTx1
.field
.TxRetransmit
;
2000 pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
+= StaTx1
.field
.TxSuccess
;
2001 pAd
->RalinkCounters
.OneSecTxFailCount
+= TxStaCnt0
.field
.TxFailCount
;
2002 pAd
->WlanCounters
.TransmittedFragmentCount
.u
.LowPart
+= StaTx1
.field
.TxSuccess
;
2003 pAd
->WlanCounters
.RetryCount
.u
.LowPart
+= StaTx1
.field
.TxRetransmit
;
2004 pAd
->WlanCounters
.FailedCount
.u
.LowPart
+= TxStaCnt0
.field
.TxFailCount
;
2006 // if no traffic in the past 1-sec period, don't change TX rate,
2007 // but clear all bad history. because the bad history may affect the next
2008 // Chariot throughput test
2009 AccuTxTotalCnt
= pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
+
2010 pAd
->RalinkCounters
.OneSecTxRetryOkCount
+
2011 pAd
->RalinkCounters
.OneSecTxFailCount
;
2014 TxErrorRatio
= ((TxRetransmit
+ TxFailCount
) * 100) / TxTotalCnt
;
2018 Rssi
= RTMPMaxRssi(pAd
, (CHAR
)pEntry
->RssiSample
.AvgRssi0
, (CHAR
)pEntry
->RssiSample
.AvgRssi1
, (CHAR
)pEntry
->RssiSample
.AvgRssi2
);
2020 TxTotalCnt
= pEntry
->OneSecTxNoRetryOkCount
+
2021 pEntry
->OneSecTxRetryOkCount
+
2022 pEntry
->OneSecTxFailCount
;
2025 TxErrorRatio
= ((pEntry
->OneSecTxRetryOkCount
+ pEntry
->OneSecTxFailCount
) * 100) / TxTotalCnt
;
2028 CurrRateIdx
= pEntry
->CurrTxRateIndex
;
2030 MlmeSelectTxRateTable(pAd
, pEntry
, &pTable
, &TableSize
, &InitTxRateIdx
);
2032 if (CurrRateIdx
>= TableSize
)
2034 CurrRateIdx
= TableSize
- 1;
2037 // When switch from Fixed rate -> auto rate, the REAL TX rate might be different from pAd->CommonCfg.TxRateIndex.
2038 // So need to sync here.
2039 pCurrTxRate
= (PRTMP_TX_RATE_SWITCH
) &pTable
[(CurrRateIdx
+1)*5];
2040 if ((pEntry
->HTPhyMode
.field
.MCS
!= pCurrTxRate
->CurrMCS
)
2041 //&& (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
2045 // Need to sync Real Tx rate and our record.
2046 // Then return for next DRS.
2047 pCurrTxRate
= (PRTMP_TX_RATE_SWITCH
) &pTable
[(InitTxRateIdx
+1)*5];
2048 pEntry
->CurrTxRateIndex
= InitTxRateIdx
;
2049 MlmeSetTxRate(pAd
, pEntry
, pCurrTxRate
);
2051 // reset all OneSecTx counters
2052 RESET_ONE_SEC_TX_CNT(pEntry
);
2056 // decide the next upgrade rate and downgrade rate, if any
2057 if ((CurrRateIdx
> 0) && (CurrRateIdx
< (TableSize
- 1)))
2059 UpRateIdx
= CurrRateIdx
+ 1;
2060 DownRateIdx
= CurrRateIdx
-1;
2062 else if (CurrRateIdx
== 0)
2064 UpRateIdx
= CurrRateIdx
+ 1;
2065 DownRateIdx
= CurrRateIdx
;
2067 else if (CurrRateIdx
== (TableSize
- 1))
2069 UpRateIdx
= CurrRateIdx
;
2070 DownRateIdx
= CurrRateIdx
- 1;
2073 pCurrTxRate
= (PRTMP_TX_RATE_SWITCH
) &pTable
[(CurrRateIdx
+1)*5];
2075 #ifdef DOT11_N_SUPPORT
2076 if ((Rssi
> -65) && (pCurrTxRate
->Mode
>= MODE_HTMIX
))
2078 TrainUp
= (pCurrTxRate
->TrainUp
+ (pCurrTxRate
->TrainUp
>> 1));
2079 TrainDown
= (pCurrTxRate
->TrainDown
+ (pCurrTxRate
->TrainDown
>> 1));
2082 #endif // DOT11_N_SUPPORT //
2084 TrainUp
= pCurrTxRate
->TrainUp
;
2085 TrainDown
= pCurrTxRate
->TrainDown
;
2088 //pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction;
2091 // Keep the last time TxRateChangeAction status.
2093 pEntry
->LastTimeTxRateChangeAction
= pEntry
->LastSecTxRateChangeAction
;
2098 // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
2099 // (criteria copied from RT2500 for Netopia case)
2101 if (TxTotalCnt
<= 15)
2105 //UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS7 = 0, MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
2106 UCHAR MCS0
= 0, MCS1
= 0, MCS2
= 0, MCS3
= 0, MCS4
= 0, MCS5
=0, MCS6
= 0, MCS7
= 0;
2107 UCHAR MCS12
= 0, MCS13
= 0, MCS14
= 0, MCS15
= 0;
2108 UCHAR MCS20
= 0, MCS21
= 0, MCS22
= 0, MCS23
= 0; // 3*3
2110 // check the existence and index of each needed MCS
2111 while (idx
< pTable
[0])
2113 pCurrTxRate
= (PRTMP_TX_RATE_SWITCH
) &pTable
[(idx
+1)*5];
2115 if (pCurrTxRate
->CurrMCS
== MCS_0
)
2119 else if (pCurrTxRate
->CurrMCS
== MCS_1
)
2123 else if (pCurrTxRate
->CurrMCS
== MCS_2
)
2127 else if (pCurrTxRate
->CurrMCS
== MCS_3
)
2131 else if (pCurrTxRate
->CurrMCS
== MCS_4
)
2135 else if (pCurrTxRate
->CurrMCS
== MCS_5
)
2139 else if (pCurrTxRate
->CurrMCS
== MCS_6
)
2143 //else if (pCurrTxRate->CurrMCS == MCS_7)
2144 else if ((pCurrTxRate
->CurrMCS
== MCS_7
) && (pCurrTxRate
->ShortGI
== GI_800
)) // prevent the highest MCS using short GI when 1T and low throughput
2148 else if (pCurrTxRate
->CurrMCS
== MCS_12
)
2152 else if (pCurrTxRate
->CurrMCS
== MCS_13
)
2156 else if (pCurrTxRate
->CurrMCS
== MCS_14
)
2160 //else if ((pCurrTxRate->CurrMCS == MCS_15)/* && (pCurrTxRate->ShortGI == GI_800)*/) //we hope to use ShortGI as initial rate
2161 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
2165 else if (pCurrTxRate
->CurrMCS
== MCS_20
) // 3*3
2169 else if (pCurrTxRate
->CurrMCS
== MCS_21
)
2173 else if (pCurrTxRate
->CurrMCS
== MCS_22
)
2177 else if (pCurrTxRate
->CurrMCS
== MCS_23
)
2184 if (pAd
->LatchRfRegs
.Channel
<= 14)
2186 if (pAd
->NicConfig2
.field
.ExternalLNAForG
)
2197 if (pAd
->NicConfig2
.field
.ExternalLNAForA
)
2206 #ifdef DOT11_N_SUPPORT
2208 if ((pTable
== RateSwitchTable11BGN3S
) ||
2209 (pTable
== RateSwitchTable11N3S
) ||
2210 (pTable
== RateSwitchTable
))
2211 {// N mode with 3 stream // 3*3
2212 if (MCS23
&& (Rssi
>= -70))
2214 else if (MCS22
&& (Rssi
>= -72))
2216 else if (MCS21
&& (Rssi
>= -76))
2218 else if (MCS20
&& (Rssi
>= -78))
2220 else if (MCS4
&& (Rssi
>= -82))
2222 else if (MCS3
&& (Rssi
>= -84))
2224 else if (MCS2
&& (Rssi
>= -86))
2226 else if (MCS1
&& (Rssi
>= -88))
2231 else if ((pTable
== RateSwitchTable11BGN2S
) || (pTable
== RateSwitchTable11BGN2SForABand
) ||(pTable
== RateSwitchTable11N2S
) ||(pTable
== RateSwitchTable11N2SForABand
)) // 3*3
2232 {// N mode with 2 stream
2233 if (MCS15
&& (Rssi
>= (-70+RssiOffset
)))
2235 else if (MCS14
&& (Rssi
>= (-72+RssiOffset
)))
2237 else if (MCS13
&& (Rssi
>= (-76+RssiOffset
)))
2239 else if (MCS12
&& (Rssi
>= (-78+RssiOffset
)))
2241 else if (MCS4
&& (Rssi
>= (-82+RssiOffset
)))
2243 else if (MCS3
&& (Rssi
>= (-84+RssiOffset
)))
2245 else if (MCS2
&& (Rssi
>= (-86+RssiOffset
)))
2247 else if (MCS1
&& (Rssi
>= (-88+RssiOffset
)))
2252 else if ((pTable
== RateSwitchTable11BGN1S
) || (pTable
== RateSwitchTable11N1S
))
2253 {// N mode with 1 stream
2254 if (MCS7
&& (Rssi
> (-72+RssiOffset
)))
2256 else if (MCS6
&& (Rssi
> (-74+RssiOffset
)))
2258 else if (MCS5
&& (Rssi
> (-77+RssiOffset
)))
2260 else if (MCS4
&& (Rssi
> (-79+RssiOffset
)))
2262 else if (MCS3
&& (Rssi
> (-81+RssiOffset
)))
2264 else if (MCS2
&& (Rssi
> (-83+RssiOffset
)))
2266 else if (MCS1
&& (Rssi
> (-86+RssiOffset
)))
2272 #endif // DOT11_N_SUPPORT //
2274 if (MCS7
&& (Rssi
> -70))
2276 else if (MCS6
&& (Rssi
> -74))
2278 else if (MCS5
&& (Rssi
> -78))
2280 else if (MCS4
&& (Rssi
> -82))
2282 else if (MCS4
== 0) // for B-only mode
2284 else if (MCS3
&& (Rssi
> -85))
2286 else if (MCS2
&& (Rssi
> -87))
2288 else if (MCS1
&& (Rssi
> -90))
2295 pEntry
->CurrTxRateIndex
= TxRateIdx
;
2296 pNextTxRate
= (PRTMP_TX_RATE_SWITCH
) &pTable
[(pEntry
->CurrTxRateIndex
+1)*5];
2297 MlmeSetTxRate(pAd
, pEntry
, pNextTxRate
);
2300 NdisZeroMemory(pEntry
->TxQuality
, sizeof(USHORT
) * MAX_STEP_OF_TX_RATE_SWITCH
);
2301 NdisZeroMemory(pEntry
->PER
, sizeof(UCHAR
) * MAX_STEP_OF_TX_RATE_SWITCH
);
2302 pEntry
->fLastSecAccordingRSSI
= TRUE
;
2303 // reset all OneSecTx counters
2304 RESET_ONE_SEC_TX_CNT(pEntry
);
2309 if (pEntry
->fLastSecAccordingRSSI
== TRUE
)
2311 pEntry
->fLastSecAccordingRSSI
= FALSE
;
2312 pEntry
->LastSecTxRateChangeAction
= 0;
2313 // reset all OneSecTx counters
2314 RESET_ONE_SEC_TX_CNT(pEntry
);
2321 BOOLEAN bTrainUpDown
= FALSE
;
2323 pEntry
->CurrTxRateStableTime
++;
2325 // downgrade TX quality if PER >= Rate-Down threshold
2326 if (TxErrorRatio
>= TrainDown
)
2328 bTrainUpDown
= TRUE
;
2329 pEntry
->TxQuality
[CurrRateIdx
] = DRS_TX_QUALITY_WORST_BOUND
;
2331 // upgrade TX quality if PER <= Rate-Up threshold
2332 else if (TxErrorRatio
<= TrainUp
)
2334 bTrainUpDown
= TRUE
;
2335 bUpgradeQuality
= TRUE
;
2336 if (pEntry
->TxQuality
[CurrRateIdx
])
2337 pEntry
->TxQuality
[CurrRateIdx
] --; // quality very good in CurrRate
2339 if (pEntry
->TxRateUpPenalty
)
2340 pEntry
->TxRateUpPenalty
--;
2341 else if (pEntry
->TxQuality
[UpRateIdx
])
2342 pEntry
->TxQuality
[UpRateIdx
] --; // may improve next UP rate's quality
2345 pEntry
->PER
[CurrRateIdx
] = (UCHAR
)TxErrorRatio
;
2349 // perform DRS - consider TxRate Down first, then rate up.
2350 if ((CurrRateIdx
!= DownRateIdx
) && (pEntry
->TxQuality
[CurrRateIdx
] >= DRS_TX_QUALITY_WORST_BOUND
))
2352 pEntry
->CurrTxRateIndex
= DownRateIdx
;
2354 else if ((CurrRateIdx
!= UpRateIdx
) && (pEntry
->TxQuality
[UpRateIdx
] <= 0))
2356 pEntry
->CurrTxRateIndex
= UpRateIdx
;
2361 // if rate-up happen, clear all bad history of all TX rates
2362 if (pEntry
->CurrTxRateIndex
> CurrRateIdx
)
2364 pEntry
->CurrTxRateStableTime
= 0;
2365 pEntry
->TxRateUpPenalty
= 0;
2366 pEntry
->LastSecTxRateChangeAction
= 1; // rate UP
2367 NdisZeroMemory(pEntry
->TxQuality
, sizeof(USHORT
) * MAX_STEP_OF_TX_RATE_SWITCH
);
2368 NdisZeroMemory(pEntry
->PER
, sizeof(UCHAR
) * MAX_STEP_OF_TX_RATE_SWITCH
);
2371 // For TxRate fast train up
2373 if (!pAd
->StaCfg
.StaQuickResponeForRateUpTimerRunning
)
2375 RTMPSetTimer(&pAd
->StaCfg
.StaQuickResponeForRateUpTimer
, 100);
2377 pAd
->StaCfg
.StaQuickResponeForRateUpTimerRunning
= TRUE
;
2379 bTxRateChanged
= TRUE
;
2381 // if rate-down happen, only clear DownRate's bad history
2382 else if (pEntry
->CurrTxRateIndex
< CurrRateIdx
)
2384 pEntry
->CurrTxRateStableTime
= 0;
2385 pEntry
->TxRateUpPenalty
= 0; // no penalty
2386 pEntry
->LastSecTxRateChangeAction
= 2; // rate DOWN
2387 pEntry
->TxQuality
[pEntry
->CurrTxRateIndex
] = 0;
2388 pEntry
->PER
[pEntry
->CurrTxRateIndex
] = 0;
2391 // For TxRate fast train down
2393 if (!pAd
->StaCfg
.StaQuickResponeForRateUpTimerRunning
)
2395 RTMPSetTimer(&pAd
->StaCfg
.StaQuickResponeForRateUpTimer
, 100);
2397 pAd
->StaCfg
.StaQuickResponeForRateUpTimerRunning
= TRUE
;
2399 bTxRateChanged
= TRUE
;
2403 pEntry
->LastSecTxRateChangeAction
= 0; // rate no change
2404 bTxRateChanged
= FALSE
;
2407 pEntry
->LastTxOkCount
= TxSuccess
;
2409 // reset all OneSecTx counters
2410 RESET_ONE_SEC_TX_CNT(pEntry
);
2412 pNextTxRate
= (PRTMP_TX_RATE_SWITCH
) &pTable
[(pEntry
->CurrTxRateIndex
+1)*5];
2413 if (bTxRateChanged
&& pNextTxRate
)
2415 MlmeSetTxRate(pAd
, pEntry
, pNextTxRate
);
2421 ========================================================================
2422 Routine Description:
2423 Station side, Auto TxRate faster train up timer call back function.
2426 SystemSpecific1 - Not used.
2427 FunctionContext - Pointer to our Adapter context.
2428 SystemSpecific2 - Not used.
2429 SystemSpecific3 - Not used.
2434 ========================================================================
2436 VOID
StaQuickResponeForRateUpExec(
2437 IN PVOID SystemSpecific1
,
2438 IN PVOID FunctionContext
,
2439 IN PVOID SystemSpecific2
,
2440 IN PVOID SystemSpecific3
)
2442 PRTMP_ADAPTER pAd
= (PRTMP_ADAPTER
)FunctionContext
;
2443 UCHAR UpRateIdx
= 0, DownRateIdx
= 0, CurrRateIdx
= 0;
2445 ULONG TxErrorRatio
= 0;
2446 BOOLEAN bTxRateChanged
= TRUE
; //, bUpgradeQuality = FALSE;
2447 PRTMP_TX_RATE_SWITCH pCurrTxRate
, pNextTxRate
= NULL
;
2449 UCHAR TableSize
= 0;
2450 UCHAR InitTxRateIdx
= 0, TrainUp
, TrainDown
;
2451 TX_STA_CNT1_STRUC StaTx1
;
2452 TX_STA_CNT0_STRUC TxStaCnt0
;
2454 ULONG TxRetransmit
= 0, TxSuccess
= 0, TxFailCount
= 0;
2455 MAC_TABLE_ENTRY
*pEntry
;
2458 pAd
->StaCfg
.StaQuickResponeForRateUpTimerRunning
= FALSE
;
2461 // walk through MAC table, see if need to change AP's TX rate toward each entry
2463 for (i
= 1; i
< MAX_LEN_OF_MAC_TABLE
; i
++)
2465 pEntry
= &pAd
->MacTab
.Content
[i
];
2467 // check if this entry need to switch rate automatically
2468 if (RTMPCheckEntryEnableAutoRateSwitch(pAd
, pEntry
) == FALSE
)
2471 //Rssi = RTMPMaxRssi(pAd, (CHAR)pAd->StaCfg.AvgRssi0, (CHAR)pAd->StaCfg.AvgRssi1, (CHAR)pAd->StaCfg.AvgRssi2);
2472 if (pAd
->Antenna
.field
.TxPath
> 1)
2473 Rssi
= (pAd
->StaCfg
.RssiSample
.AvgRssi0
+ pAd
->StaCfg
.RssiSample
.AvgRssi1
) >> 1;
2475 Rssi
= pAd
->StaCfg
.RssiSample
.AvgRssi0
;
2477 CurrRateIdx
= pAd
->CommonCfg
.TxRateIndex
;
2479 MlmeSelectTxRateTable(pAd
, pEntry
, &pTable
, &TableSize
, &InitTxRateIdx
);
2481 // decide the next upgrade rate and downgrade rate, if any
2482 if ((CurrRateIdx
> 0) && (CurrRateIdx
< (TableSize
- 1)))
2484 UpRateIdx
= CurrRateIdx
+ 1;
2485 DownRateIdx
= CurrRateIdx
-1;
2487 else if (CurrRateIdx
== 0)
2489 UpRateIdx
= CurrRateIdx
+ 1;
2490 DownRateIdx
= CurrRateIdx
;
2492 else if (CurrRateIdx
== (TableSize
- 1))
2494 UpRateIdx
= CurrRateIdx
;
2495 DownRateIdx
= CurrRateIdx
- 1;
2498 pCurrTxRate
= (PRTMP_TX_RATE_SWITCH
) &pTable
[(CurrRateIdx
+1)*5];
2500 #ifdef DOT11_N_SUPPORT
2501 if ((Rssi
> -65) && (pCurrTxRate
->Mode
>= MODE_HTMIX
))
2503 TrainUp
= (pCurrTxRate
->TrainUp
+ (pCurrTxRate
->TrainUp
>> 1));
2504 TrainDown
= (pCurrTxRate
->TrainDown
+ (pCurrTxRate
->TrainDown
>> 1));
2507 #endif // DOT11_N_SUPPORT //
2509 TrainUp
= pCurrTxRate
->TrainUp
;
2510 TrainDown
= pCurrTxRate
->TrainDown
;
2513 if (pAd
->MacTab
.Size
== 1)
2515 // Update statistic counter
2516 RTMP_IO_READ32(pAd
, TX_STA_CNT0
, &TxStaCnt0
.word
);
2517 RTMP_IO_READ32(pAd
, TX_STA_CNT1
, &StaTx1
.word
);
2519 TxRetransmit
= StaTx1
.field
.TxRetransmit
;
2520 TxSuccess
= StaTx1
.field
.TxSuccess
;
2521 TxFailCount
= TxStaCnt0
.field
.TxFailCount
;
2522 TxTotalCnt
= TxRetransmit
+ TxSuccess
+ TxFailCount
;
2524 pAd
->RalinkCounters
.OneSecTxRetryOkCount
+= StaTx1
.field
.TxRetransmit
;
2525 pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
+= StaTx1
.field
.TxSuccess
;
2526 pAd
->RalinkCounters
.OneSecTxFailCount
+= TxStaCnt0
.field
.TxFailCount
;
2527 pAd
->WlanCounters
.TransmittedFragmentCount
.u
.LowPart
+= StaTx1
.field
.TxSuccess
;
2528 pAd
->WlanCounters
.RetryCount
.u
.LowPart
+= StaTx1
.field
.TxRetransmit
;
2529 pAd
->WlanCounters
.FailedCount
.u
.LowPart
+= TxStaCnt0
.field
.TxFailCount
;
2532 TxErrorRatio
= ((TxRetransmit
+ TxFailCount
) * 100) / TxTotalCnt
;
2536 TxTotalCnt
= pEntry
->OneSecTxNoRetryOkCount
+
2537 pEntry
->OneSecTxRetryOkCount
+
2538 pEntry
->OneSecTxFailCount
;
2541 TxErrorRatio
= ((pEntry
->OneSecTxRetryOkCount
+ pEntry
->OneSecTxFailCount
) * 100) / TxTotalCnt
;
2546 // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
2547 // (criteria copied from RT2500 for Netopia case)
2549 if (TxTotalCnt
<= 12)
2551 NdisZeroMemory(pAd
->DrsCounters
.TxQuality
, sizeof(USHORT
) * MAX_STEP_OF_TX_RATE_SWITCH
);
2552 NdisZeroMemory(pAd
->DrsCounters
.PER
, sizeof(UCHAR
) * MAX_STEP_OF_TX_RATE_SWITCH
);
2554 if ((pAd
->DrsCounters
.LastSecTxRateChangeAction
== 1) && (CurrRateIdx
!= DownRateIdx
))
2556 pAd
->CommonCfg
.TxRateIndex
= DownRateIdx
;
2557 pAd
->DrsCounters
.TxQuality
[CurrRateIdx
] = DRS_TX_QUALITY_WORST_BOUND
;
2559 else if ((pAd
->DrsCounters
.LastSecTxRateChangeAction
== 2) && (CurrRateIdx
!= UpRateIdx
))
2561 pAd
->CommonCfg
.TxRateIndex
= UpRateIdx
;
2564 DBGPRINT_RAW(RT_DEBUG_TRACE
,("QuickDRS: TxTotalCnt <= 15, train back to original rate \n"));
2570 ULONG OneSecTxNoRetryOKRationCount
;
2572 if (pAd
->DrsCounters
.LastTimeTxRateChangeAction
== 0)
2577 // downgrade TX quality if PER >= Rate-Down threshold
2578 if (TxErrorRatio
>= TrainDown
)
2580 pAd
->DrsCounters
.TxQuality
[CurrRateIdx
] = DRS_TX_QUALITY_WORST_BOUND
;
2583 pAd
->DrsCounters
.PER
[CurrRateIdx
] = (UCHAR
)TxErrorRatio
;
2585 OneSecTxNoRetryOKRationCount
= (TxSuccess
* ratio
);
2587 // perform DRS - consider TxRate Down first, then rate up.
2588 if ((pAd
->DrsCounters
.LastSecTxRateChangeAction
== 1) && (CurrRateIdx
!= DownRateIdx
))
2590 if ((pAd
->DrsCounters
.LastTxOkCount
+ 2) >= OneSecTxNoRetryOKRationCount
)
2592 pAd
->CommonCfg
.TxRateIndex
= DownRateIdx
;
2593 pAd
->DrsCounters
.TxQuality
[CurrRateIdx
] = DRS_TX_QUALITY_WORST_BOUND
;
2598 else if ((pAd
->DrsCounters
.LastSecTxRateChangeAction
== 2) && (CurrRateIdx
!= UpRateIdx
))
2600 if ((TxErrorRatio
>= 50) || (TxErrorRatio
>= TrainDown
))
2604 else if ((pAd
->DrsCounters
.LastTxOkCount
+ 2) >= OneSecTxNoRetryOKRationCount
)
2606 pAd
->CommonCfg
.TxRateIndex
= UpRateIdx
;
2611 // if rate-up happen, clear all bad history of all TX rates
2612 if (pAd
->CommonCfg
.TxRateIndex
> CurrRateIdx
)
2614 pAd
->DrsCounters
.TxRateUpPenalty
= 0;
2615 NdisZeroMemory(pAd
->DrsCounters
.TxQuality
, sizeof(USHORT
) * MAX_STEP_OF_TX_RATE_SWITCH
);
2616 NdisZeroMemory(pAd
->DrsCounters
.PER
, sizeof(UCHAR
) * MAX_STEP_OF_TX_RATE_SWITCH
);
2618 // if rate-down happen, only clear DownRate's bad history
2619 else if (pAd
->CommonCfg
.TxRateIndex
< CurrRateIdx
)
2621 DBGPRINT_RAW(RT_DEBUG_TRACE
,("QuickDRS: --TX rate from %d to %d \n", CurrRateIdx
, pAd
->CommonCfg
.TxRateIndex
));
2623 pAd
->DrsCounters
.TxRateUpPenalty
= 0; // no penalty
2624 pAd
->DrsCounters
.TxQuality
[pAd
->CommonCfg
.TxRateIndex
] = 0;
2625 pAd
->DrsCounters
.PER
[pAd
->CommonCfg
.TxRateIndex
] = 0;
2629 bTxRateChanged
= FALSE
;
2632 pNextTxRate
= (PRTMP_TX_RATE_SWITCH
) &pTable
[(pAd
->CommonCfg
.TxRateIndex
+1)*5];
2633 if (bTxRateChanged
&& pNextTxRate
)
2635 MlmeSetTxRate(pAd
, pEntry
, pNextTxRate
);
2641 ==========================================================================
2643 This routine is executed periodically inside MlmePeriodicExec() after
2644 association with an AP.
2645 It checks if StaCfg.Psm is consistent with user policy (recorded in
2646 StaCfg.WindowsPowerMode). If not, enforce user policy. However,
2647 there're some conditions to consider:
2648 1. we don't support power-saving in ADHOC mode, so Psm=PWR_ACTIVE all
2649 the time when Mibss==TRUE
2650 2. When link up in INFRA mode, Psm should not be switch to PWR_SAVE
2651 if outgoing traffic available in TxRing or MgmtRing.
2653 1. change pAd->StaCfg.Psm to PWR_SAVE or leave it untouched
2655 IRQL = DISPATCH_LEVEL
2657 ==========================================================================
2659 VOID
MlmeCheckPsmChange(
2660 IN PRTMP_ADAPTER pAd
,
2666 // 1. Psm maybe ON only happen in INFRASTRUCTURE mode
2667 // 2. user wants either MAX_PSP or FAST_PSP
2668 // 3. but current psm is not in PWR_SAVE
2669 // 4. CNTL state machine is not doing SCANning
2670 // 5. no TX SUCCESS event for the past 1-sec period
2671 #ifdef NDIS51_MINIPORT
2672 if (pAd
->StaCfg
.WindowsPowerProfile
== NdisPowerProfileBattery
)
2673 PowerMode
= pAd
->StaCfg
.WindowsBatteryPowerMode
;
2676 PowerMode
= pAd
->StaCfg
.WindowsPowerMode
;
2678 if (INFRA_ON(pAd
) &&
2679 (PowerMode
!= Ndis802_11PowerModeCAM
) &&
2680 (pAd
->StaCfg
.Psm
== PWR_ACTIVE
) &&
2681 RTMP_TEST_PSFLAG(pAd
, fRTMP_PS_CAN_GO_SLEEP
))
2683 NdisGetSystemUpTime(&pAd
->Mlme
.LastSendNULLpsmTime
);
2684 pAd
->RalinkCounters
.RxCountSinceLastNULL
= 0;
2685 MlmeSetPsmBit(pAd
, PWR_SAVE
);
2686 if (!(pAd
->CommonCfg
.bAPSDCapable
&& pAd
->CommonCfg
.APEdcaParm
.bAPSDCapable
))
2688 RTMPSendNullFrame(pAd
, pAd
->CommonCfg
.TxRate
, FALSE
);
2692 RTMPSendNullFrame(pAd
, pAd
->CommonCfg
.TxRate
, TRUE
);
2697 // IRQL = PASSIVE_LEVEL
2698 // IRQL = DISPATCH_LEVEL
2700 IN PRTMP_ADAPTER pAd
,
2703 AUTO_RSP_CFG_STRUC csr4
;
2705 pAd
->StaCfg
.Psm
= psm
;
2706 RTMP_IO_READ32(pAd
, AUTO_RSP_CFG
, &csr4
.word
);
2707 csr4
.field
.AckCtsPsmBit
= (psm
== PWR_SAVE
)? 1:0;
2708 RTMP_IO_WRITE32(pAd
, AUTO_RSP_CFG
, csr4
.word
);
2709 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeSetPsmBit = %d\n", psm
));
2712 // IRQL = DISPATCH_LEVEL
2713 VOID
MlmeSetTxPreamble(
2714 IN PRTMP_ADAPTER pAd
,
2715 IN USHORT TxPreamble
)
2717 AUTO_RSP_CFG_STRUC csr4
;
2720 // Always use Long preamble before verifiation short preamble functionality works well.
2721 // Todo: remove the following line if short preamble functionality works
2723 //TxPreamble = Rt802_11PreambleLong;
2725 RTMP_IO_READ32(pAd
, AUTO_RSP_CFG
, &csr4
.word
);
2726 if (TxPreamble
== Rt802_11PreambleLong
)
2728 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeSetTxPreamble (= LONG PREAMBLE)\n"));
2729 OPSTATUS_CLEAR_FLAG(pAd
, fOP_STATUS_SHORT_PREAMBLE_INUSED
);
2730 csr4
.field
.AutoResponderPreamble
= 0;
2734 // NOTE: 1Mbps should always use long preamble
2735 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeSetTxPreamble (= SHORT PREAMBLE)\n"));
2736 OPSTATUS_SET_FLAG(pAd
, fOP_STATUS_SHORT_PREAMBLE_INUSED
);
2737 csr4
.field
.AutoResponderPreamble
= 1;
2740 RTMP_IO_WRITE32(pAd
, AUTO_RSP_CFG
, csr4
.word
);
2744 ==========================================================================
2746 Update basic rate bitmap
2747 ==========================================================================
2750 VOID
UpdateBasicRateBitmap(
2751 IN PRTMP_ADAPTER pAdapter
)
2754 /* 1 2 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */
2755 UCHAR rate
[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
2756 UCHAR
*sup_p
= pAdapter
->CommonCfg
.SupRate
;
2757 UCHAR
*ext_p
= pAdapter
->CommonCfg
.ExtRate
;
2758 ULONG bitmap
= pAdapter
->CommonCfg
.BasicRateBitmap
;
2761 /* if A mode, always use fix BasicRateBitMap */
2762 //if (pAdapter->CommonCfg.Channel == PHY_11A)
2763 if (pAdapter
->CommonCfg
.Channel
> 14)
2764 pAdapter
->CommonCfg
.BasicRateBitmap
= 0x150; /* 6, 12, 24M */
2767 if (pAdapter
->CommonCfg
.BasicRateBitmap
> 4095)
2769 /* (2 ^ MAX_LEN_OF_SUPPORTED_RATES) -1 */
2773 for(i
=0; i
<MAX_LEN_OF_SUPPORTED_RATES
; i
++)
2779 for(i
=0; i
<MAX_LEN_OF_SUPPORTED_RATES
; i
++)
2781 if (bitmap
& (1 << i
))
2783 for(j
=0; j
<MAX_LEN_OF_SUPPORTED_RATES
; j
++)
2785 if (sup_p
[j
] == rate
[i
])
2790 for(j
=0; j
<MAX_LEN_OF_SUPPORTED_RATES
; j
++)
2792 if (ext_p
[j
] == rate
[i
])
2798 } /* End of UpdateBasicRateBitmap */
2800 // IRQL = PASSIVE_LEVEL
2801 // IRQL = DISPATCH_LEVEL
2802 // bLinkUp is to identify the inital link speed.
2803 // TRUE indicates the rate update at linkup, we should not try to set the rate at 54Mbps.
2804 VOID
MlmeUpdateTxRates(
2805 IN PRTMP_ADAPTER pAd
,
2810 UCHAR Rate
= RATE_6
, MaxDesire
= RATE_1
, MaxSupport
= RATE_1
;
2811 UCHAR MinSupport
= RATE_54
;
2812 ULONG BasicRateBitmap
= 0;
2813 UCHAR CurrBasicRate
= RATE_1
;
2814 UCHAR
*pSupRate
, SupRateLen
, *pExtRate
, ExtRateLen
;
2815 PHTTRANSMIT_SETTING pHtPhy
= NULL
;
2816 PHTTRANSMIT_SETTING pMaxHtPhy
= NULL
;
2817 PHTTRANSMIT_SETTING pMinHtPhy
= NULL
;
2818 BOOLEAN
*auto_rate_cur_p
;
2819 UCHAR HtMcs
= MCS_AUTO
;
2821 // find max desired rate
2822 UpdateBasicRateBitmap(pAd
);
2825 auto_rate_cur_p
= NULL
;
2826 for (i
=0; i
<MAX_LEN_OF_SUPPORTED_RATES
; i
++)
2828 switch (pAd
->CommonCfg
.DesireRate
[i
] & 0x7f)
2830 case 2: Rate
= RATE_1
; num
++; break;
2831 case 4: Rate
= RATE_2
; num
++; break;
2832 case 11: Rate
= RATE_5_5
; num
++; break;
2833 case 22: Rate
= RATE_11
; num
++; break;
2834 case 12: Rate
= RATE_6
; num
++; break;
2835 case 18: Rate
= RATE_9
; num
++; break;
2836 case 24: Rate
= RATE_12
; num
++; break;
2837 case 36: Rate
= RATE_18
; num
++; break;
2838 case 48: Rate
= RATE_24
; num
++; break;
2839 case 72: Rate
= RATE_36
; num
++; break;
2840 case 96: Rate
= RATE_48
; num
++; break;
2841 case 108: Rate
= RATE_54
; num
++; break;
2842 //default: Rate = RATE_1; break;
2844 if (MaxDesire
< Rate
) MaxDesire
= Rate
;
2847 //===========================================================================
2848 //===========================================================================
2849 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
2851 pHtPhy
= &pAd
->StaCfg
.HTPhyMode
;
2852 pMaxHtPhy
= &pAd
->StaCfg
.MaxHTPhyMode
;
2853 pMinHtPhy
= &pAd
->StaCfg
.MinHTPhyMode
;
2855 auto_rate_cur_p
= &pAd
->StaCfg
.bAutoTxRateSwitch
;
2856 HtMcs
= pAd
->StaCfg
.DesiredTransmitSetting
.field
.MCS
;
2858 if ((pAd
->StaCfg
.BssType
== BSS_ADHOC
) &&
2859 (pAd
->CommonCfg
.PhyMode
== PHY_11B
) &&
2860 (MaxDesire
> RATE_11
))
2862 MaxDesire
= RATE_11
;
2866 pAd
->CommonCfg
.MaxDesiredRate
= MaxDesire
;
2867 pMinHtPhy
->word
= 0;
2868 pMaxHtPhy
->word
= 0;
2871 // Auto rate switching is enabled only if more than one DESIRED RATES are
2872 // specified; otherwise disabled
2875 *auto_rate_cur_p
= FALSE
;
2879 *auto_rate_cur_p
= TRUE
;
2883 if (HtMcs
!= MCS_AUTO
)
2885 *auto_rate_cur_p
= FALSE
;
2889 *auto_rate_cur_p
= TRUE
;
2893 if ((ADHOC_ON(pAd
) || INFRA_ON(pAd
)) && (pAd
->OpMode
== OPMODE_STA
))
2895 pSupRate
= &pAd
->StaActive
.SupRate
[0];
2896 pExtRate
= &pAd
->StaActive
.ExtRate
[0];
2897 SupRateLen
= pAd
->StaActive
.SupRateLen
;
2898 ExtRateLen
= pAd
->StaActive
.ExtRateLen
;
2902 pSupRate
= &pAd
->CommonCfg
.SupRate
[0];
2903 pExtRate
= &pAd
->CommonCfg
.ExtRate
[0];
2904 SupRateLen
= pAd
->CommonCfg
.SupRateLen
;
2905 ExtRateLen
= pAd
->CommonCfg
.ExtRateLen
;
2908 // find max supported rate
2909 for (i
=0; i
<SupRateLen
; i
++)
2911 switch (pSupRate
[i
] & 0x7f)
2913 case 2: Rate
= RATE_1
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0001; break;
2914 case 4: Rate
= RATE_2
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0002; break;
2915 case 11: Rate
= RATE_5_5
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0004; break;
2916 case 22: Rate
= RATE_11
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0008; break;
2917 case 12: Rate
= RATE_6
; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap
|= 0x0010; break;
2918 case 18: Rate
= RATE_9
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0020; break;
2919 case 24: Rate
= RATE_12
; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap
|= 0x0040; break;
2920 case 36: Rate
= RATE_18
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0080; break;
2921 case 48: Rate
= RATE_24
; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap
|= 0x0100; break;
2922 case 72: Rate
= RATE_36
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0200; break;
2923 case 96: Rate
= RATE_48
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0400; break;
2924 case 108: Rate
= RATE_54
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0800; break;
2925 default: Rate
= RATE_1
; break;
2927 if (MaxSupport
< Rate
) MaxSupport
= Rate
;
2929 if (MinSupport
> Rate
) MinSupport
= Rate
;
2932 for (i
=0; i
<ExtRateLen
; i
++)
2934 switch (pExtRate
[i
] & 0x7f)
2936 case 2: Rate
= RATE_1
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0001; break;
2937 case 4: Rate
= RATE_2
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0002; break;
2938 case 11: Rate
= RATE_5_5
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0004; break;
2939 case 22: Rate
= RATE_11
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0008; break;
2940 case 12: Rate
= RATE_6
; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap
|= 0x0010; break;
2941 case 18: Rate
= RATE_9
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0020; break;
2942 case 24: Rate
= RATE_12
; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap
|= 0x0040; break;
2943 case 36: Rate
= RATE_18
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0080; break;
2944 case 48: Rate
= RATE_24
; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap
|= 0x0100; break;
2945 case 72: Rate
= RATE_36
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0200; break;
2946 case 96: Rate
= RATE_48
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0400; break;
2947 case 108: Rate
= RATE_54
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0800; break;
2948 default: Rate
= RATE_1
; break;
2950 if (MaxSupport
< Rate
) MaxSupport
= Rate
;
2952 if (MinSupport
> Rate
) MinSupport
= Rate
;
2955 RTMP_IO_WRITE32(pAd
, LEGACY_BASIC_RATE
, BasicRateBitmap
);
2957 // calculate the exptected ACK rate for each TX rate. This info is used to caculate
2958 // the DURATION field of outgoing uniicast DATA/MGMT frame
2959 for (i
=0; i
<MAX_LEN_OF_SUPPORTED_RATES
; i
++)
2961 if (BasicRateBitmap
& (0x01 << i
))
2962 CurrBasicRate
= (UCHAR
)i
;
2963 pAd
->CommonCfg
.ExpectedACKRate
[i
] = CurrBasicRate
;
2966 DBGPRINT(RT_DEBUG_TRACE
,("MlmeUpdateTxRates[MaxSupport = %d] = MaxDesire %d Mbps\n", RateIdToMbps
[MaxSupport
], RateIdToMbps
[MaxDesire
]));
2967 // max tx rate = min {max desire rate, max supported rate}
2968 if (MaxSupport
< MaxDesire
)
2969 pAd
->CommonCfg
.MaxTxRate
= MaxSupport
;
2971 pAd
->CommonCfg
.MaxTxRate
= MaxDesire
;
2973 pAd
->CommonCfg
.MinTxRate
= MinSupport
;
2974 if (*auto_rate_cur_p
)
2978 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
2979 dbm
= pAd
->StaCfg
.RssiSample
.AvgRssi0
- pAd
->BbpRssiToDbmDelta
;
2981 if (bLinkUp
== TRUE
)
2982 pAd
->CommonCfg
.TxRate
= RATE_24
;
2984 pAd
->CommonCfg
.TxRate
= pAd
->CommonCfg
.MaxTxRate
;
2987 pAd
->CommonCfg
.TxRate
= RATE_11
;
2989 pAd
->CommonCfg
.TxRate
= RATE_24
;
2991 // should never exceed MaxTxRate (consider 11B-only mode)
2992 if (pAd
->CommonCfg
.TxRate
> pAd
->CommonCfg
.MaxTxRate
)
2993 pAd
->CommonCfg
.TxRate
= pAd
->CommonCfg
.MaxTxRate
;
2995 pAd
->CommonCfg
.TxRateIndex
= 0;
2999 pAd
->CommonCfg
.TxRate
= pAd
->CommonCfg
.MaxTxRate
;
3000 pHtPhy
->field
.MCS
= (pAd
->CommonCfg
.MaxTxRate
> 3) ? (pAd
->CommonCfg
.MaxTxRate
- 4) : pAd
->CommonCfg
.MaxTxRate
;
3001 pHtPhy
->field
.MODE
= (pAd
->CommonCfg
.MaxTxRate
> 3) ? MODE_OFDM
: MODE_CCK
;
3003 pAd
->MacTab
.Content
[BSSID_WCID
].HTPhyMode
.field
.STBC
= pHtPhy
->field
.STBC
;
3004 pAd
->MacTab
.Content
[BSSID_WCID
].HTPhyMode
.field
.ShortGI
= pHtPhy
->field
.ShortGI
;
3005 pAd
->MacTab
.Content
[BSSID_WCID
].HTPhyMode
.field
.MCS
= pHtPhy
->field
.MCS
;
3006 pAd
->MacTab
.Content
[BSSID_WCID
].HTPhyMode
.field
.MODE
= pHtPhy
->field
.MODE
;
3009 if (pAd
->CommonCfg
.TxRate
<= RATE_11
)
3011 pMaxHtPhy
->field
.MODE
= MODE_CCK
;
3012 pMaxHtPhy
->field
.MCS
= pAd
->CommonCfg
.TxRate
;
3013 pMinHtPhy
->field
.MCS
= pAd
->CommonCfg
.MinTxRate
;
3017 pMaxHtPhy
->field
.MODE
= MODE_OFDM
;
3018 pMaxHtPhy
->field
.MCS
= OfdmRateToRxwiMCS
[pAd
->CommonCfg
.TxRate
];
3019 if (pAd
->CommonCfg
.MinTxRate
>= RATE_6
&& (pAd
->CommonCfg
.MinTxRate
<= RATE_54
))
3020 {pMinHtPhy
->field
.MCS
= OfdmRateToRxwiMCS
[pAd
->CommonCfg
.MinTxRate
];}
3022 {pMinHtPhy
->field
.MCS
= pAd
->CommonCfg
.MinTxRate
;}
3025 pHtPhy
->word
= (pMaxHtPhy
->word
);
3026 if (bLinkUp
&& (pAd
->OpMode
== OPMODE_STA
))
3028 pAd
->MacTab
.Content
[BSSID_WCID
].HTPhyMode
.word
= pHtPhy
->word
;
3029 pAd
->MacTab
.Content
[BSSID_WCID
].MaxHTPhyMode
.word
= pMaxHtPhy
->word
;
3030 pAd
->MacTab
.Content
[BSSID_WCID
].MinHTPhyMode
.word
= pMinHtPhy
->word
;
3034 switch (pAd
->CommonCfg
.PhyMode
)
3036 case PHY_11BG_MIXED
:
3038 #ifdef DOT11_N_SUPPORT
3039 case PHY_11BGN_MIXED
:
3040 #endif // DOT11_N_SUPPORT //
3041 pAd
->CommonCfg
.MlmeRate
= RATE_1
;
3042 pAd
->CommonCfg
.MlmeTransmit
.field
.MODE
= MODE_CCK
;
3043 pAd
->CommonCfg
.MlmeTransmit
.field
.MCS
= RATE_1
;
3044 pAd
->CommonCfg
.RtsRate
= RATE_11
;
3048 #ifdef DOT11_N_SUPPORT
3049 case PHY_11AGN_MIXED
:
3050 case PHY_11GN_MIXED
:
3052 case PHY_11AN_MIXED
:
3054 #endif // DOT11_N_SUPPORT //
3055 pAd
->CommonCfg
.MlmeRate
= RATE_6
;
3056 pAd
->CommonCfg
.RtsRate
= RATE_6
;
3057 pAd
->CommonCfg
.MlmeTransmit
.field
.MODE
= MODE_OFDM
;
3058 pAd
->CommonCfg
.MlmeTransmit
.field
.MCS
= OfdmRateToRxwiMCS
[pAd
->CommonCfg
.MlmeRate
];
3060 case PHY_11ABG_MIXED
:
3061 #ifdef DOT11_N_SUPPORT
3062 case PHY_11ABGN_MIXED
:
3063 #endif // DOT11_N_SUPPORT //
3064 if (pAd
->CommonCfg
.Channel
<= 14)
3066 pAd
->CommonCfg
.MlmeRate
= RATE_1
;
3067 pAd
->CommonCfg
.RtsRate
= RATE_1
;
3068 pAd
->CommonCfg
.MlmeTransmit
.field
.MODE
= MODE_CCK
;
3069 pAd
->CommonCfg
.MlmeTransmit
.field
.MCS
= RATE_1
;
3073 pAd
->CommonCfg
.MlmeRate
= RATE_6
;
3074 pAd
->CommonCfg
.RtsRate
= RATE_6
;
3075 pAd
->CommonCfg
.MlmeTransmit
.field
.MODE
= MODE_OFDM
;
3076 pAd
->CommonCfg
.MlmeTransmit
.field
.MCS
= OfdmRateToRxwiMCS
[pAd
->CommonCfg
.MlmeRate
];
3080 pAd
->CommonCfg
.MlmeRate
= RATE_6
;
3081 pAd
->CommonCfg
.MlmeTransmit
.field
.MODE
= MODE_OFDM
;
3082 pAd
->CommonCfg
.MlmeTransmit
.field
.MCS
= OfdmRateToRxwiMCS
[pAd
->CommonCfg
.MlmeRate
];
3083 pAd
->CommonCfg
.RtsRate
= RATE_1
;
3087 // Keep Basic Mlme Rate.
3089 pAd
->MacTab
.Content
[MCAST_WCID
].HTPhyMode
.word
= pAd
->CommonCfg
.MlmeTransmit
.word
;
3090 if (pAd
->CommonCfg
.MlmeTransmit
.field
.MODE
== MODE_OFDM
)
3091 pAd
->MacTab
.Content
[MCAST_WCID
].HTPhyMode
.field
.MCS
= OfdmRateToRxwiMCS
[RATE_24
];
3093 pAd
->MacTab
.Content
[MCAST_WCID
].HTPhyMode
.field
.MCS
= RATE_1
;
3094 pAd
->CommonCfg
.BasicMlmeRate
= pAd
->CommonCfg
.MlmeRate
;
3097 DBGPRINT(RT_DEBUG_TRACE
, (" MlmeUpdateTxRates (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n",
3098 RateIdToMbps
[MaxDesire
], RateIdToMbps
[MaxSupport
], RateIdToMbps
[pAd
->CommonCfg
.MaxTxRate
], RateIdToMbps
[pAd
->CommonCfg
.MinTxRate
],
3099 /*OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)*/*auto_rate_cur_p
));
3100 DBGPRINT(RT_DEBUG_TRACE
, (" MlmeUpdateTxRates (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n",
3101 RateIdToMbps
[pAd
->CommonCfg
.TxRate
], RateIdToMbps
[pAd
->CommonCfg
.RtsRate
], BasicRateBitmap
));
3102 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeUpdateTxRates (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n",
3103 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
));
3106 #ifdef DOT11_N_SUPPORT
3108 ==========================================================================
3110 This function update HT Rate setting.
3111 Input Wcid value is valid for 2 case :
3112 1. it's used for Station in infra mode that copy AP rate to Mactable.
3113 2. OR Station in adhoc mode to copy peer's HT rate to Mactable.
3115 IRQL = DISPATCH_LEVEL
3117 ==========================================================================
3119 VOID
MlmeUpdateHtTxRates(
3120 IN PRTMP_ADAPTER pAd
,
3123 UCHAR StbcMcs
; //j, StbcMcs, bitmask;
3125 RT_HT_CAPABILITY
*pRtHtCap
= NULL
;
3126 RT_HT_PHY_INFO
*pActiveHtPhy
= NULL
;
3129 PRT_HT_PHY_INFO pDesireHtPhy
= NULL
;
3130 PHTTRANSMIT_SETTING pHtPhy
= NULL
;
3131 PHTTRANSMIT_SETTING pMaxHtPhy
= NULL
;
3132 PHTTRANSMIT_SETTING pMinHtPhy
= NULL
;
3133 BOOLEAN
*auto_rate_cur_p
;
3135 DBGPRINT(RT_DEBUG_TRACE
,("MlmeUpdateHtTxRates===> \n"));
3137 auto_rate_cur_p
= NULL
;
3139 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
3141 pDesireHtPhy
= &pAd
->StaCfg
.DesiredHtPhyInfo
;
3142 pActiveHtPhy
= &pAd
->StaCfg
.DesiredHtPhyInfo
;
3143 pHtPhy
= &pAd
->StaCfg
.HTPhyMode
;
3144 pMaxHtPhy
= &pAd
->StaCfg
.MaxHTPhyMode
;
3145 pMinHtPhy
= &pAd
->StaCfg
.MinHTPhyMode
;
3147 auto_rate_cur_p
= &pAd
->StaCfg
.bAutoTxRateSwitch
;
3150 if ((ADHOC_ON(pAd
) || INFRA_ON(pAd
)) && (pAd
->OpMode
== OPMODE_STA
))
3152 if (pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
== FALSE
)
3155 pRtHtCap
= &pAd
->StaActive
.SupportedHtPhy
;
3156 pActiveHtPhy
= &pAd
->StaActive
.SupportedPhyInfo
;
3157 StbcMcs
= (UCHAR
)pAd
->MlmeAux
.AddHtInfo
.AddHtInfo3
.StbcMcs
;
3158 BasicMCS
=pAd
->MlmeAux
.AddHtInfo
.MCSSet
[0]+(pAd
->MlmeAux
.AddHtInfo
.MCSSet
[1]<<8)+(StbcMcs
<<16);
3159 if ((pAd
->CommonCfg
.DesiredHtPhy
.TxSTBC
) && (pRtHtCap
->RxSTBC
) && (pAd
->Antenna
.field
.TxPath
== 2))
3160 pMaxHtPhy
->field
.STBC
= STBC_USE
;
3162 pMaxHtPhy
->field
.STBC
= STBC_NONE
;
3166 if (pDesireHtPhy
->bHtEnable
== FALSE
)
3169 pRtHtCap
= &pAd
->CommonCfg
.DesiredHtPhy
;
3170 StbcMcs
= (UCHAR
)pAd
->CommonCfg
.AddHTInfo
.AddHtInfo3
.StbcMcs
;
3171 BasicMCS
= pAd
->CommonCfg
.AddHTInfo
.MCSSet
[0]+(pAd
->CommonCfg
.AddHTInfo
.MCSSet
[1]<<8)+(StbcMcs
<<16);
3172 if ((pAd
->CommonCfg
.DesiredHtPhy
.TxSTBC
) && (pRtHtCap
->RxSTBC
) && (pAd
->Antenna
.field
.TxPath
== 2))
3173 pMaxHtPhy
->field
.STBC
= STBC_USE
;
3175 pMaxHtPhy
->field
.STBC
= STBC_NONE
;
3178 // Decide MAX ht rate.
3179 if ((pRtHtCap
->GF
) && (pAd
->CommonCfg
.DesiredHtPhy
.GF
))
3180 pMaxHtPhy
->field
.MODE
= MODE_HTGREENFIELD
;
3182 pMaxHtPhy
->field
.MODE
= MODE_HTMIX
;
3184 if ((pAd
->CommonCfg
.DesiredHtPhy
.ChannelWidth
) && (pRtHtCap
->ChannelWidth
))
3185 pMaxHtPhy
->field
.BW
= BW_40
;
3187 pMaxHtPhy
->field
.BW
= BW_20
;
3189 if (pMaxHtPhy
->field
.BW
== BW_20
)
3190 pMaxHtPhy
->field
.ShortGI
= (pAd
->CommonCfg
.DesiredHtPhy
.ShortGIfor20
& pRtHtCap
->ShortGIfor20
);
3192 pMaxHtPhy
->field
.ShortGI
= (pAd
->CommonCfg
.DesiredHtPhy
.ShortGIfor40
& pRtHtCap
->ShortGIfor40
);
3194 for (i
=23; i
>=0; i
--) // 3*3
3197 bitmask
= (1<<(i
-(j
*8)));
3199 if ((pActiveHtPhy
->MCSSet
[j
] & bitmask
) && (pDesireHtPhy
->MCSSet
[j
] & bitmask
))
3201 pMaxHtPhy
->field
.MCS
= i
;
3209 // Copy MIN ht rate. rt2860???
3210 pMinHtPhy
->field
.BW
= BW_20
;
3211 pMinHtPhy
->field
.MCS
= 0;
3212 pMinHtPhy
->field
.STBC
= 0;
3213 pMinHtPhy
->field
.ShortGI
= 0;
3214 //If STA assigns fixed rate. update to fixed here.
3215 if ( (pAd
->OpMode
== OPMODE_STA
) && (pDesireHtPhy
->MCSSet
[0] != 0xff))
3217 if (pDesireHtPhy
->MCSSet
[4] != 0)
3219 pMaxHtPhy
->field
.MCS
= 32;
3220 pMinHtPhy
->field
.MCS
= 32;
3221 DBGPRINT(RT_DEBUG_TRACE
,("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n",pMinHtPhy
->field
.MCS
));
3224 for (i
=23; (CHAR
)i
>= 0; i
--) // 3*3
3227 bitmask
= (1<<(i
-(j
*8)));
3228 if ( (pDesireHtPhy
->MCSSet
[j
] & bitmask
) && (pActiveHtPhy
->MCSSet
[j
] & bitmask
))
3230 pMaxHtPhy
->field
.MCS
= i
;
3231 pMinHtPhy
->field
.MCS
= i
;
3240 pHtPhy
->field
.STBC
= pMaxHtPhy
->field
.STBC
;
3241 pHtPhy
->field
.BW
= pMaxHtPhy
->field
.BW
;
3242 pHtPhy
->field
.MODE
= pMaxHtPhy
->field
.MODE
;
3243 pHtPhy
->field
.MCS
= pMaxHtPhy
->field
.MCS
;
3244 pHtPhy
->field
.ShortGI
= pMaxHtPhy
->field
.ShortGI
;
3246 // use default now. rt2860
3247 if (pDesireHtPhy
->MCSSet
[0] != 0xff)
3248 *auto_rate_cur_p
= FALSE
;
3250 *auto_rate_cur_p
= TRUE
;
3252 DBGPRINT(RT_DEBUG_TRACE
, (" MlmeUpdateHtTxRates<---.AMsduSize = %d \n", pAd
->CommonCfg
.DesiredHtPhy
.AmsduSize
));
3253 DBGPRINT(RT_DEBUG_TRACE
,("TX: MCS[0] = %x (choose %d), BW = %d, ShortGI = %d, MODE = %d, \n", pActiveHtPhy
->MCSSet
[0],pHtPhy
->field
.MCS
,
3254 pHtPhy
->field
.BW
, pHtPhy
->field
.ShortGI
, pHtPhy
->field
.MODE
));
3255 DBGPRINT(RT_DEBUG_TRACE
,("MlmeUpdateHtTxRates<=== \n"));
3257 #endif // DOT11_N_SUPPORT //
3259 // IRQL = DISPATCH_LEVEL
3261 IN PRTMP_ADAPTER pAd
)
3263 RT28XX_MLME_RADIO_OFF(pAd
);
3266 // IRQL = DISPATCH_LEVEL
3268 IN PRTMP_ADAPTER pAd
)
3270 RT28XX_MLME_RADIO_ON(pAd
);
3273 // ===========================================================================================
3275 // ===========================================================================================
3278 /*! \brief initialize BSS table
3279 * \param p_tab pointer to the table
3284 IRQL = PASSIVE_LEVEL
3285 IRQL = DISPATCH_LEVEL
3294 Tab
->BssOverlapNr
= 0;
3295 for (i
= 0; i
< MAX_LEN_OF_BSS_TABLE
; i
++)
3297 NdisZeroMemory(&Tab
->BssEntry
[i
], sizeof(BSS_ENTRY
));
3298 Tab
->BssEntry
[i
].Rssi
= -127; // initial the rssi as a minimum value
3302 #ifdef DOT11_N_SUPPORT
3304 IN PRTMP_ADAPTER pAd
,
3309 Tab
->numAsOriginator
= 0;
3310 Tab
->numAsRecipient
= 0;
3311 NdisAllocateSpinLock(&pAd
->BATabLock
);
3312 for (i
= 0; i
< MAX_LEN_OF_BA_REC_TABLE
; i
++)
3314 Tab
->BARecEntry
[i
].REC_BA_Status
= Recipient_NONE
;
3315 NdisAllocateSpinLock(&(Tab
->BARecEntry
[i
].RxReRingLock
));
3317 for (i
= 0; i
< MAX_LEN_OF_BA_ORI_TABLE
; i
++)
3319 Tab
->BAOriEntry
[i
].ORI_BA_Status
= Originator_NONE
;
3322 #endif // DOT11_N_SUPPORT //
3324 /*! \brief search the BSS table by SSID
3325 * \param p_tab pointer to the bss table
3326 * \param ssid SSID string
3327 * \return index of the table, BSS_NOT_FOUND if not in the table
3330 * \note search by sequential search
3332 IRQL = DISPATCH_LEVEL
3335 ULONG
BssTableSearch(
3342 for (i
= 0; i
< Tab
->BssNr
; i
++)
3345 // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
3346 // We should distinguish this case.
3348 if ((((Tab
->BssEntry
[i
].Channel
<= 14) && (Channel
<= 14)) ||
3349 ((Tab
->BssEntry
[i
].Channel
> 14) && (Channel
> 14))) &&
3350 MAC_ADDR_EQUAL(Tab
->BssEntry
[i
].Bssid
, pBssid
))
3355 return (ULONG
)BSS_NOT_FOUND
;
3358 ULONG
BssSsidTableSearch(
3367 for (i
= 0; i
< Tab
->BssNr
; i
++)
3370 // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
3371 // We should distinguish this case.
3373 if ((((Tab
->BssEntry
[i
].Channel
<= 14) && (Channel
<= 14)) ||
3374 ((Tab
->BssEntry
[i
].Channel
> 14) && (Channel
> 14))) &&
3375 MAC_ADDR_EQUAL(Tab
->BssEntry
[i
].Bssid
, pBssid
) &&
3376 SSID_EQUAL(pSsid
, SsidLen
, Tab
->BssEntry
[i
].Ssid
, Tab
->BssEntry
[i
].SsidLen
))
3381 return (ULONG
)BSS_NOT_FOUND
;
3384 ULONG
BssTableSearchWithSSID(
3393 for (i
= 0; i
< Tab
->BssNr
; i
++)
3395 if ((((Tab
->BssEntry
[i
].Channel
<= 14) && (Channel
<= 14)) ||
3396 ((Tab
->BssEntry
[i
].Channel
> 14) && (Channel
> 14))) &&
3397 MAC_ADDR_EQUAL(&(Tab
->BssEntry
[i
].Bssid
), Bssid
) &&
3398 (SSID_EQUAL(pSsid
, SsidLen
, Tab
->BssEntry
[i
].Ssid
, Tab
->BssEntry
[i
].SsidLen
) ||
3399 (NdisEqualMemory(pSsid
, ZeroSsid
, SsidLen
)) ||
3400 (NdisEqualMemory(Tab
->BssEntry
[i
].Ssid
, ZeroSsid
, Tab
->BssEntry
[i
].SsidLen
))))
3405 return (ULONG
)BSS_NOT_FOUND
;
3408 // IRQL = DISPATCH_LEVEL
3409 VOID
BssTableDeleteEntry(
3410 IN OUT BSS_TABLE
*Tab
,
3416 for (i
= 0; i
< Tab
->BssNr
; i
++)
3418 if ((Tab
->BssEntry
[i
].Channel
== Channel
) &&
3419 (MAC_ADDR_EQUAL(Tab
->BssEntry
[i
].Bssid
, pBssid
)))
3421 for (j
= i
; j
< Tab
->BssNr
- 1; j
++)
3423 NdisMoveMemory(&(Tab
->BssEntry
[j
]), &(Tab
->BssEntry
[j
+ 1]), sizeof(BSS_ENTRY
));
3425 NdisZeroMemory(&(Tab
->BssEntry
[Tab
->BssNr
- 1]), sizeof(BSS_ENTRY
));
3432 #ifdef DOT11_N_SUPPORT
3434 ========================================================================
3435 Routine Description:
3436 Delete the Originator Entry in BAtable. Or decrease numAs Originator by 1 if needed.
3439 // IRQL = DISPATCH_LEVEL
3440 ========================================================================
3442 VOID
BATableDeleteORIEntry(
3443 IN OUT PRTMP_ADAPTER pAd
,
3444 IN BA_ORI_ENTRY
*pBAORIEntry
)
3447 if (pBAORIEntry
->ORI_BA_Status
!= Originator_NONE
)
3449 NdisAcquireSpinLock(&pAd
->BATabLock
);
3450 if (pBAORIEntry
->ORI_BA_Status
== Originator_Done
)
3452 pAd
->BATable
.numAsOriginator
-= 1;
3453 DBGPRINT(RT_DEBUG_TRACE
, ("BATableDeleteORIEntry numAsOriginator= %ld\n", pAd
->BATable
.numAsRecipient
));
3454 // Erase Bitmap flag.
3456 pAd
->MacTab
.Content
[pBAORIEntry
->Wcid
].TXBAbitmap
&= (~(1<<(pBAORIEntry
->TID
) )); // If STA mode, erase flag here
3457 pAd
->MacTab
.Content
[pBAORIEntry
->Wcid
].BAOriWcidArray
[pBAORIEntry
->TID
] = 0; // If STA mode, erase flag here
3458 pBAORIEntry
->ORI_BA_Status
= Originator_NONE
;
3459 pBAORIEntry
->Token
= 1;
3460 // Not clear Sequence here.
3461 NdisReleaseSpinLock(&pAd
->BATabLock
);
3464 #endif // DOT11_N_SUPPORT //
3472 IRQL = DISPATCH_LEVEL
3476 IN PRTMP_ADAPTER pAd
,
3477 OUT BSS_ENTRY
*pBss
,
3482 IN USHORT BeaconPeriod
,
3483 IN PCF_PARM pCfParm
,
3485 IN USHORT CapabilityInfo
,
3487 IN UCHAR SupRateLen
,
3489 IN UCHAR ExtRateLen
,
3490 IN HT_CAPABILITY_IE
*pHtCapability
,
3491 IN ADD_HT_INFO_IE
*pAddHtInfo
, // AP might use this additional ht info IE
3492 IN UCHAR HtCapabilityLen
,
3493 IN UCHAR AddHtInfoLen
,
3494 IN UCHAR NewExtChanOffset
,
3497 IN LARGE_INTEGER TimeStamp
,
3499 IN PEDCA_PARM pEdcaParm
,
3500 IN PQOS_CAPABILITY_PARM pQosCapability
,
3501 IN PQBSS_LOAD_PARM pQbssLoad
,
3502 IN USHORT LengthVIE
,
3503 IN PNDIS_802_11_VARIABLE_IEs pVIE
)
3505 COPY_MAC_ADDR(pBss
->Bssid
, pBssid
);
3506 // Default Hidden SSID to be TRUE, it will be turned to FALSE after coping SSID
3510 // For hidden SSID AP, it might send beacon with SSID len equal to 0
3511 // Or send beacon /probe response with SSID len matching real SSID length,
3512 // but SSID is all zero. such as "00-00-00-00" with length 4.
3513 // We have to prevent this case overwrite correct table
3514 if (NdisEqualMemory(Ssid
, ZeroSsid
, SsidLen
) == 0)
3516 NdisZeroMemory(pBss
->Ssid
, MAX_LEN_OF_SSID
);
3517 NdisMoveMemory(pBss
->Ssid
, Ssid
, SsidLen
);
3518 pBss
->SsidLen
= SsidLen
;
3524 pBss
->BssType
= BssType
;
3525 pBss
->BeaconPeriod
= BeaconPeriod
;
3526 if (BssType
== BSS_INFRA
)
3528 if (pCfParm
->bValid
)
3530 pBss
->CfpCount
= pCfParm
->CfpCount
;
3531 pBss
->CfpPeriod
= pCfParm
->CfpPeriod
;
3532 pBss
->CfpMaxDuration
= pCfParm
->CfpMaxDuration
;
3533 pBss
->CfpDurRemaining
= pCfParm
->CfpDurRemaining
;
3538 pBss
->AtimWin
= AtimWin
;
3541 pBss
->CapabilityInfo
= CapabilityInfo
;
3542 // The privacy bit indicate security is ON, it maight be WEP, TKIP or AES
3543 // Combine with AuthMode, they will decide the connection methods.
3544 pBss
->Privacy
= CAP_IS_PRIVACY_ON(pBss
->CapabilityInfo
);
3545 ASSERT(SupRateLen
<= MAX_LEN_OF_SUPPORTED_RATES
);
3546 if (SupRateLen
<= MAX_LEN_OF_SUPPORTED_RATES
)
3547 NdisMoveMemory(pBss
->SupRate
, SupRate
, SupRateLen
);
3549 NdisMoveMemory(pBss
->SupRate
, SupRate
, MAX_LEN_OF_SUPPORTED_RATES
);
3550 pBss
->SupRateLen
= SupRateLen
;
3551 ASSERT(ExtRateLen
<= MAX_LEN_OF_SUPPORTED_RATES
);
3552 NdisMoveMemory(pBss
->ExtRate
, ExtRate
, ExtRateLen
);
3553 NdisMoveMemory(&pBss
->HtCapability
, pHtCapability
, HtCapabilityLen
);
3554 NdisMoveMemory(&pBss
->AddHtInfo
, pAddHtInfo
, AddHtInfoLen
);
3555 pBss
->NewExtChanOffset
= NewExtChanOffset
;
3556 pBss
->ExtRateLen
= ExtRateLen
;
3557 pBss
->Channel
= Channel
;
3558 pBss
->CentralChannel
= Channel
;
3560 // Update CkipFlag. if not exists, the value is 0x0
3561 pBss
->CkipFlag
= CkipFlag
;
3563 // New for microsoft Fixed IEs
3564 NdisMoveMemory(pBss
->FixIEs
.Timestamp
, &TimeStamp
, 8);
3565 pBss
->FixIEs
.BeaconInterval
= BeaconPeriod
;
3566 pBss
->FixIEs
.Capabilities
= CapabilityInfo
;
3568 // New for microsoft Variable IEs
3571 pBss
->VarIELen
= LengthVIE
;
3572 NdisMoveMemory(pBss
->VarIEs
, pVIE
, pBss
->VarIELen
);
3579 pBss
->AddHtInfoLen
= 0;
3580 pBss
->HtCapabilityLen
= 0;
3581 #ifdef DOT11_N_SUPPORT
3582 if (HtCapabilityLen
> 0)
3584 pBss
->HtCapabilityLen
= HtCapabilityLen
;
3585 NdisMoveMemory(&pBss
->HtCapability
, pHtCapability
, HtCapabilityLen
);
3586 if (AddHtInfoLen
> 0)
3588 pBss
->AddHtInfoLen
= AddHtInfoLen
;
3589 NdisMoveMemory(&pBss
->AddHtInfo
, pAddHtInfo
, AddHtInfoLen
);
3591 if ((pAddHtInfo
->ControlChan
> 2)&& (pAddHtInfo
->AddHtInfo
.ExtChanOffset
== EXTCHA_BELOW
) && (pHtCapability
->HtCapInfo
.ChannelWidth
== BW_40
))
3593 pBss
->CentralChannel
= pAddHtInfo
->ControlChan
- 2;
3595 else if ((pAddHtInfo
->AddHtInfo
.ExtChanOffset
== EXTCHA_ABOVE
) && (pHtCapability
->HtCapInfo
.ChannelWidth
== BW_40
))
3597 pBss
->CentralChannel
= pAddHtInfo
->ControlChan
+ 2;
3601 #endif // DOT11_N_SUPPORT //
3603 BssCipherParse(pBss
);
3607 NdisMoveMemory(&pBss
->EdcaParm
, pEdcaParm
, sizeof(EDCA_PARM
));
3609 pBss
->EdcaParm
.bValid
= FALSE
;
3611 NdisMoveMemory(&pBss
->QosCapability
, pQosCapability
, sizeof(QOS_CAPABILITY_PARM
));
3613 pBss
->QosCapability
.bValid
= FALSE
;
3615 NdisMoveMemory(&pBss
->QbssLoad
, pQbssLoad
, sizeof(QBSS_LOAD_PARM
));
3617 pBss
->QbssLoad
.bValid
= FALSE
;
3619 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
3625 NdisZeroMemory(&pBss
->WpaIE
.IE
[0], MAX_CUSTOM_LEN
);
3626 NdisZeroMemory(&pBss
->RsnIE
.IE
[0], MAX_CUSTOM_LEN
);
3628 pEid
= (PEID_STRUCT
) pVIE
;
3630 while ((Length
+ 2 + (USHORT
)pEid
->Len
) <= LengthVIE
)
3635 if (NdisEqualMemory(pEid
->Octet
, WPA_OUI
, 4))
3637 if ((pEid
->Len
+ 2) > MAX_CUSTOM_LEN
)
3639 pBss
->WpaIE
.IELen
= 0;
3642 pBss
->WpaIE
.IELen
= pEid
->Len
+ 2;
3643 NdisMoveMemory(pBss
->WpaIE
.IE
, pEid
, pBss
->WpaIE
.IELen
);
3647 if (NdisEqualMemory(pEid
->Octet
+ 2, RSN_OUI
, 3))
3649 if ((pEid
->Len
+ 2) > MAX_CUSTOM_LEN
)
3651 pBss
->RsnIE
.IELen
= 0;
3654 pBss
->RsnIE
.IELen
= pEid
->Len
+ 2;
3655 NdisMoveMemory(pBss
->RsnIE
.IE
, pEid
, pBss
->RsnIE
.IELen
);
3659 Length
= Length
+ 2 + (USHORT
)pEid
->Len
; // Eid[1] + Len[1]+ content[Len]
3660 pEid
= (PEID_STRUCT
)((UCHAR
*)pEid
+ 2 + pEid
->Len
);
3666 * \brief insert an entry into the bss table
3667 * \param p_tab The BSS table
3668 * \param Bssid BSSID
3670 * \param ssid_len Length of SSID
3672 * \param beacon_period
3679 * \param channel_idx
3683 * \note If SSID is identical, the old entry will be replaced by the new one
3685 IRQL = DISPATCH_LEVEL
3688 ULONG
BssTableSetEntry(
3689 IN PRTMP_ADAPTER pAd
,
3695 IN USHORT BeaconPeriod
,
3698 IN USHORT CapabilityInfo
,
3700 IN UCHAR SupRateLen
,
3702 IN UCHAR ExtRateLen
,
3703 IN HT_CAPABILITY_IE
*pHtCapability
,
3704 IN ADD_HT_INFO_IE
*pAddHtInfo
, // AP might use this additional ht info IE
3705 IN UCHAR HtCapabilityLen
,
3706 IN UCHAR AddHtInfoLen
,
3707 IN UCHAR NewExtChanOffset
,
3710 IN LARGE_INTEGER TimeStamp
,
3712 IN PEDCA_PARM pEdcaParm
,
3713 IN PQOS_CAPABILITY_PARM pQosCapability
,
3714 IN PQBSS_LOAD_PARM pQbssLoad
,
3715 IN USHORT LengthVIE
,
3716 IN PNDIS_802_11_VARIABLE_IEs pVIE
)
3720 Idx
= BssTableSearchWithSSID(Tab
, pBssid
, Ssid
, SsidLen
, ChannelNo
);
3721 if (Idx
== BSS_NOT_FOUND
)
3723 if (Tab
->BssNr
>= MAX_LEN_OF_BSS_TABLE
)
3726 // It may happen when BSS Table was full.
3727 // The desired AP will not be added into BSS Table
3728 // In this case, if we found the desired AP then overwrite BSS Table.
3730 if(!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
3732 if (MAC_ADDR_EQUAL(pAd
->MlmeAux
.Bssid
, pBssid
) ||
3733 SSID_EQUAL(pAd
->MlmeAux
.Ssid
, pAd
->MlmeAux
.SsidLen
, Ssid
, SsidLen
))
3735 Idx
= Tab
->BssOverlapNr
;
3736 BssEntrySet(pAd
, &Tab
->BssEntry
[Idx
], pBssid
, Ssid
, SsidLen
, BssType
, BeaconPeriod
, CfParm
, AtimWin
,
3737 CapabilityInfo
, SupRate
, SupRateLen
, ExtRate
, ExtRateLen
,pHtCapability
, pAddHtInfo
,HtCapabilityLen
, AddHtInfoLen
,
3738 NewExtChanOffset
, ChannelNo
, Rssi
, TimeStamp
, CkipFlag
, pEdcaParm
, pQosCapability
, pQbssLoad
, LengthVIE
, pVIE
);
3739 Tab
->BssOverlapNr
= (Tab
->BssOverlapNr
++) % MAX_LEN_OF_BSS_TABLE
;
3745 return BSS_NOT_FOUND
;
3749 BssEntrySet(pAd
, &Tab
->BssEntry
[Idx
], pBssid
, Ssid
, SsidLen
, BssType
, BeaconPeriod
, CfParm
, AtimWin
,
3750 CapabilityInfo
, SupRate
, SupRateLen
, ExtRate
, ExtRateLen
,pHtCapability
, pAddHtInfo
,HtCapabilityLen
, AddHtInfoLen
,
3751 NewExtChanOffset
, ChannelNo
, Rssi
, TimeStamp
, CkipFlag
, pEdcaParm
, pQosCapability
, pQbssLoad
, LengthVIE
, pVIE
);
3756 BssEntrySet(pAd
, &Tab
->BssEntry
[Idx
], pBssid
, Ssid
, SsidLen
, BssType
, BeaconPeriod
,CfParm
, AtimWin
,
3757 CapabilityInfo
, SupRate
, SupRateLen
, ExtRate
, ExtRateLen
,pHtCapability
, pAddHtInfo
,HtCapabilityLen
, AddHtInfoLen
,
3758 NewExtChanOffset
, ChannelNo
, Rssi
, TimeStamp
, CkipFlag
, pEdcaParm
, pQosCapability
, pQbssLoad
, LengthVIE
, pVIE
);
3764 // IRQL = DISPATCH_LEVEL
3765 VOID
BssTableSsidSort(
3766 IN PRTMP_ADAPTER pAd
,
3767 OUT BSS_TABLE
*OutTab
,
3772 BssTableInit(OutTab
);
3774 for (i
= 0; i
< pAd
->ScanTab
.BssNr
; i
++)
3776 BSS_ENTRY
*pInBss
= &pAd
->ScanTab
.BssEntry
[i
];
3777 BOOLEAN bIsHiddenApIncluded
= FALSE
;
3779 if (((pAd
->CommonCfg
.bIEEE80211H
== 1) &&
3780 (pAd
->MlmeAux
.Channel
> 14) &&
3781 RadarChannelCheck(pAd
, pInBss
->Channel
))
3785 bIsHiddenApIncluded
= TRUE
;
3788 if ((pInBss
->BssType
== pAd
->StaCfg
.BssType
) &&
3789 (SSID_EQUAL(Ssid
, SsidLen
, pInBss
->Ssid
, pInBss
->SsidLen
) || bIsHiddenApIncluded
))
3791 BSS_ENTRY
*pOutBss
= &OutTab
->BssEntry
[OutTab
->BssNr
];
3792 #ifdef DOT11_N_SUPPORT
3793 // 2.4G/5G N only mode
3794 if ((pInBss
->HtCapabilityLen
== 0) &&
3795 ((pAd
->CommonCfg
.PhyMode
== PHY_11N_2_4G
) || (pAd
->CommonCfg
.PhyMode
== PHY_11N_5G
)))
3797 DBGPRINT(RT_DEBUG_TRACE
,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
3800 #endif // DOT11_N_SUPPORT //
3803 // Check the Authmode first
3804 if (pAd
->StaCfg
.AuthMode
>= Ndis802_11AuthModeWPA
)
3806 // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
3807 if ((pAd
->StaCfg
.AuthMode
!= pInBss
->AuthMode
) && (pAd
->StaCfg
.AuthMode
!= pInBss
->AuthModeAux
))
3811 // Check cipher suite, AP must have more secured cipher than station setting
3812 if ((pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA
) || (pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPAPSK
))
3814 // If it's not mixed mode, we should only let BSS pass with the same encryption
3815 if (pInBss
->WPA
.bMixMode
== FALSE
)
3816 if (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA
.GroupCipher
)
3819 // check group cipher
3820 if ((pAd
->StaCfg
.WepStatus
< pInBss
->WPA
.GroupCipher
) &&
3821 (pInBss
->WPA
.GroupCipher
!= Ndis802_11GroupWEP40Enabled
) &&
3822 (pInBss
->WPA
.GroupCipher
!= Ndis802_11GroupWEP104Enabled
))
3825 // check pairwise cipher, skip if none matched
3826 // If profile set to AES, let it pass without question.
3827 // If profile set to TKIP, we must find one mateched
3828 if ((pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption2Enabled
) &&
3829 (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA
.PairCipher
) &&
3830 (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA
.PairCipherAux
))
3833 else if ((pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA2
) || (pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA2PSK
))
3835 // If it's not mixed mode, we should only let BSS pass with the same encryption
3836 if (pInBss
->WPA2
.bMixMode
== FALSE
)
3837 if (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA2
.GroupCipher
)
3840 // check group cipher
3841 if ((pAd
->StaCfg
.WepStatus
< pInBss
->WPA
.GroupCipher
) &&
3842 (pInBss
->WPA2
.GroupCipher
!= Ndis802_11GroupWEP40Enabled
) &&
3843 (pInBss
->WPA2
.GroupCipher
!= Ndis802_11GroupWEP104Enabled
))
3846 // check pairwise cipher, skip if none matched
3847 // If profile set to AES, let it pass without question.
3848 // If profile set to TKIP, we must find one mateched
3849 if ((pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption2Enabled
) &&
3850 (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA2
.PairCipher
) &&
3851 (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA2
.PairCipherAux
))
3855 // Bss Type matched, SSID matched.
3856 // We will check wepstatus for qualification Bss
3857 else if (pAd
->StaCfg
.WepStatus
!= pInBss
->WepStatus
)
3859 DBGPRINT(RT_DEBUG_TRACE
,("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n", pAd
->StaCfg
.WepStatus
, pInBss
->WepStatus
));
3861 // For the SESv2 case, we will not qualify WepStatus.
3867 // Since the AP is using hidden SSID, and we are trying to connect to ANY
3868 // It definitely will fail. So, skip it.
3869 // CCX also require not even try to connect it!!
3873 #ifdef DOT11_N_SUPPORT
3874 // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
3875 // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
3876 if ((pInBss
->CentralChannel
!= pInBss
->Channel
) &&
3877 (pAd
->CommonCfg
.RegTransmitSetting
.field
.BW
== BW_40
))
3879 if (RTMPCheckChannel(pAd
, pInBss
->CentralChannel
, pInBss
->Channel
) == FALSE
)
3881 pAd
->CommonCfg
.RegTransmitSetting
.field
.BW
= BW_20
;
3883 pAd
->CommonCfg
.RegTransmitSetting
.field
.BW
= BW_40
;
3887 if (pAd
->CommonCfg
.DesiredHtPhy
.ChannelWidth
== BAND_WIDTH_20
)
3893 #endif // DOT11_N_SUPPORT //
3895 // copy matching BSS from InTab to OutTab
3896 NdisMoveMemory(pOutBss
, pInBss
, sizeof(BSS_ENTRY
));
3900 else if ((pInBss
->BssType
== pAd
->StaCfg
.BssType
) && (SsidLen
== 0))
3902 BSS_ENTRY
*pOutBss
= &OutTab
->BssEntry
[OutTab
->BssNr
];
3905 #ifdef DOT11_N_SUPPORT
3906 // 2.4G/5G N only mode
3907 if ((pInBss
->HtCapabilityLen
== 0) &&
3908 ((pAd
->CommonCfg
.PhyMode
== PHY_11N_2_4G
) || (pAd
->CommonCfg
.PhyMode
== PHY_11N_5G
)))
3910 DBGPRINT(RT_DEBUG_TRACE
,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
3913 #endif // DOT11_N_SUPPORT //
3916 // Check the Authmode first
3917 if (pAd
->StaCfg
.AuthMode
>= Ndis802_11AuthModeWPA
)
3919 // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
3920 if ((pAd
->StaCfg
.AuthMode
!= pInBss
->AuthMode
) && (pAd
->StaCfg
.AuthMode
!= pInBss
->AuthModeAux
))
3924 // Check cipher suite, AP must have more secured cipher than station setting
3925 if ((pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA
) || (pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPAPSK
))
3927 // If it's not mixed mode, we should only let BSS pass with the same encryption
3928 if (pInBss
->WPA
.bMixMode
== FALSE
)
3929 if (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA
.GroupCipher
)
3932 // check group cipher
3933 if (pAd
->StaCfg
.WepStatus
< pInBss
->WPA
.GroupCipher
)
3936 // check pairwise cipher, skip if none matched
3937 // If profile set to AES, let it pass without question.
3938 // If profile set to TKIP, we must find one mateched
3939 if ((pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption2Enabled
) &&
3940 (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA
.PairCipher
) &&
3941 (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA
.PairCipherAux
))
3944 else if ((pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA2
) || (pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA2PSK
))
3946 // If it's not mixed mode, we should only let BSS pass with the same encryption
3947 if (pInBss
->WPA2
.bMixMode
== FALSE
)
3948 if (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA2
.GroupCipher
)
3951 // check group cipher
3952 if (pAd
->StaCfg
.WepStatus
< pInBss
->WPA2
.GroupCipher
)
3955 // check pairwise cipher, skip if none matched
3956 // If profile set to AES, let it pass without question.
3957 // If profile set to TKIP, we must find one mateched
3958 if ((pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption2Enabled
) &&
3959 (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA2
.PairCipher
) &&
3960 (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA2
.PairCipherAux
))
3964 // Bss Type matched, SSID matched.
3965 // We will check wepstatus for qualification Bss
3966 else if (pAd
->StaCfg
.WepStatus
!= pInBss
->WepStatus
)
3969 #ifdef DOT11_N_SUPPORT
3970 // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
3971 // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
3972 if ((pInBss
->CentralChannel
!= pInBss
->Channel
) &&
3973 (pAd
->CommonCfg
.RegTransmitSetting
.field
.BW
== BW_40
))
3975 if (RTMPCheckChannel(pAd
, pInBss
->CentralChannel
, pInBss
->Channel
) == FALSE
)
3977 pAd
->CommonCfg
.RegTransmitSetting
.field
.BW
= BW_20
;
3979 pAd
->CommonCfg
.RegTransmitSetting
.field
.BW
= BW_40
;
3982 #endif // DOT11_N_SUPPORT //
3984 // copy matching BSS from InTab to OutTab
3985 NdisMoveMemory(pOutBss
, pInBss
, sizeof(BSS_ENTRY
));
3990 if (OutTab
->BssNr
>= MAX_LEN_OF_BSS_TABLE
)
3994 BssTableSortByRssi(OutTab
);
3998 // IRQL = DISPATCH_LEVEL
3999 VOID
BssTableSortByRssi(
4000 IN OUT BSS_TABLE
*OutTab
)
4005 for (i
= 0; i
< OutTab
->BssNr
- 1; i
++)
4007 for (j
= i
+1; j
< OutTab
->BssNr
; j
++)
4009 if (OutTab
->BssEntry
[j
].Rssi
> OutTab
->BssEntry
[i
].Rssi
)
4011 NdisMoveMemory(&TmpBss
, &OutTab
->BssEntry
[j
], sizeof(BSS_ENTRY
));
4012 NdisMoveMemory(&OutTab
->BssEntry
[j
], &OutTab
->BssEntry
[i
], sizeof(BSS_ENTRY
));
4013 NdisMoveMemory(&OutTab
->BssEntry
[i
], &TmpBss
, sizeof(BSS_ENTRY
));
4019 VOID
BssCipherParse(
4020 IN OUT PBSS_ENTRY pBss
)
4024 PRSN_IE_HEADER_STRUCT pRsnHeader
;
4025 PCIPHER_SUITE_STRUCT pCipher
;
4026 PAKM_SUITE_STRUCT pAKM
;
4029 NDIS_802_11_ENCRYPTION_STATUS TmpCipher
;
4032 // WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame.
4036 pBss
->WepStatus
= Ndis802_11WEPEnabled
;
4040 pBss
->WepStatus
= Ndis802_11WEPDisabled
;
4042 // Set default to disable & open authentication before parsing variable IE
4043 pBss
->AuthMode
= Ndis802_11AuthModeOpen
;
4044 pBss
->AuthModeAux
= Ndis802_11AuthModeOpen
;
4047 pBss
->WPA
.PairCipher
= Ndis802_11WEPDisabled
;
4048 pBss
->WPA
.PairCipherAux
= Ndis802_11WEPDisabled
;
4049 pBss
->WPA
.GroupCipher
= Ndis802_11WEPDisabled
;
4050 pBss
->WPA
.RsnCapability
= 0;
4051 pBss
->WPA
.bMixMode
= FALSE
;
4053 // Init WPA2 setting
4054 pBss
->WPA2
.PairCipher
= Ndis802_11WEPDisabled
;
4055 pBss
->WPA2
.PairCipherAux
= Ndis802_11WEPDisabled
;
4056 pBss
->WPA2
.GroupCipher
= Ndis802_11WEPDisabled
;
4057 pBss
->WPA2
.RsnCapability
= 0;
4058 pBss
->WPA2
.bMixMode
= FALSE
;
4061 Length
= (INT
) pBss
->VarIELen
;
4065 // Parse cipher suite base on WPA1 & WPA2, they should be parsed differently
4066 pTmp
= ((PUCHAR
) pBss
->VarIEs
) + pBss
->VarIELen
- Length
;
4067 pEid
= (PEID_STRUCT
) pTmp
;
4071 //Parse Cisco IE_WPA (LEAP, CCKM, etc.)
4072 if ( NdisEqualMemory((pTmp
+8), CISCO_OUI
, 3))
4078 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4079 pBss
->WepStatus
= Ndis802_11Encryption1Enabled
;
4080 pBss
->WPA
.PairCipher
= Ndis802_11Encryption1Enabled
;
4081 pBss
->WPA
.GroupCipher
= Ndis802_11Encryption1Enabled
;
4084 pBss
->WepStatus
= Ndis802_11Encryption2Enabled
;
4085 pBss
->WPA
.PairCipher
= Ndis802_11Encryption1Enabled
;
4086 pBss
->WPA
.GroupCipher
= Ndis802_11Encryption1Enabled
;
4089 pBss
->WepStatus
= Ndis802_11Encryption3Enabled
;
4090 pBss
->WPA
.PairCipher
= Ndis802_11Encryption1Enabled
;
4091 pBss
->WPA
.GroupCipher
= Ndis802_11Encryption1Enabled
;
4097 // if Cisco IE_WPA, break
4100 else if (NdisEqualMemory(pEid
->Octet
, SES_OUI
, 3) && (pEid
->Len
== 7))
4105 else if (NdisEqualMemory(pEid
->Octet
, WPA_OUI
, 4) != 1)
4107 // if unsupported vendor specific IE
4110 // Skip OUI, version, and multicast suite
4111 // This part should be improved in the future when AP supported multiple cipher suite.
4112 // For now, it's OK since almost all APs have fixed cipher suite supported.
4113 // pTmp = (PUCHAR) pEid->Octet;
4116 // Cipher Suite Selectors from Spec P802.11i/D3.2 P26.
4124 // Parse group cipher
4128 pBss
->WPA
.GroupCipher
= Ndis802_11GroupWEP40Enabled
;
4131 pBss
->WPA
.GroupCipher
= Ndis802_11GroupWEP104Enabled
;
4134 pBss
->WPA
.GroupCipher
= Ndis802_11Encryption2Enabled
;
4137 pBss
->WPA
.GroupCipher
= Ndis802_11Encryption3Enabled
;
4142 // number of unicast suite
4145 // skip all unicast cipher suites
4146 //Count = *(PUSHORT) pTmp;
4147 Count
= (pTmp
[1]<<8) + pTmp
[0];
4148 pTmp
+= sizeof(USHORT
);
4150 // Parsing all unicast cipher suite
4155 TmpCipher
= Ndis802_11WEPDisabled
;
4159 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4160 TmpCipher
= Ndis802_11Encryption1Enabled
;
4163 TmpCipher
= Ndis802_11Encryption2Enabled
;
4166 TmpCipher
= Ndis802_11Encryption3Enabled
;
4171 if (TmpCipher
> pBss
->WPA
.PairCipher
)
4173 // Move the lower cipher suite to PairCipherAux
4174 pBss
->WPA
.PairCipherAux
= pBss
->WPA
.PairCipher
;
4175 pBss
->WPA
.PairCipher
= TmpCipher
;
4179 pBss
->WPA
.PairCipherAux
= TmpCipher
;
4185 // 4. get AKM suite counts
4186 //Count = *(PUSHORT) pTmp;
4187 Count
= (pTmp
[1]<<8) + pTmp
[0];
4188 pTmp
+= sizeof(USHORT
);
4194 // Set AP support WPA mode
4195 if (pBss
->AuthMode
== Ndis802_11AuthModeOpen
)
4196 pBss
->AuthMode
= Ndis802_11AuthModeWPA
;
4198 pBss
->AuthModeAux
= Ndis802_11AuthModeWPA
;
4201 // Set AP support WPA mode
4202 if (pBss
->AuthMode
== Ndis802_11AuthModeOpen
)
4203 pBss
->AuthMode
= Ndis802_11AuthModeWPAPSK
;
4205 pBss
->AuthModeAux
= Ndis802_11AuthModeWPAPSK
;
4212 // Fixed for WPA-None
4213 if (pBss
->BssType
== BSS_ADHOC
)
4215 pBss
->AuthMode
= Ndis802_11AuthModeWPANone
;
4216 pBss
->AuthModeAux
= Ndis802_11AuthModeWPANone
;
4217 pBss
->WepStatus
= pBss
->WPA
.GroupCipher
;
4218 // Patched bugs for old driver
4219 if (pBss
->WPA
.PairCipherAux
== Ndis802_11WEPDisabled
)
4220 pBss
->WPA
.PairCipherAux
= pBss
->WPA
.GroupCipher
;
4223 pBss
->WepStatus
= pBss
->WPA
.PairCipher
;
4225 // Check the Pair & Group, if different, turn on mixed mode flag
4226 if (pBss
->WPA
.GroupCipher
!= pBss
->WPA
.PairCipher
)
4227 pBss
->WPA
.bMixMode
= TRUE
;
4232 pRsnHeader
= (PRSN_IE_HEADER_STRUCT
) pTmp
;
4234 // 0. Version must be 1
4235 if (le2cpu16(pRsnHeader
->Version
) != 1)
4237 pTmp
+= sizeof(RSN_IE_HEADER_STRUCT
);
4239 // 1. Check group cipher
4240 pCipher
= (PCIPHER_SUITE_STRUCT
) pTmp
;
4241 if (!RTMPEqualMemory(pTmp
, RSN_OUI
, 3))
4244 // Parse group cipher
4245 switch (pCipher
->Type
)
4248 pBss
->WPA2
.GroupCipher
= Ndis802_11GroupWEP40Enabled
;
4251 pBss
->WPA2
.GroupCipher
= Ndis802_11GroupWEP104Enabled
;
4254 pBss
->WPA2
.GroupCipher
= Ndis802_11Encryption2Enabled
;
4257 pBss
->WPA2
.GroupCipher
= Ndis802_11Encryption3Enabled
;
4262 // set to correct offset for next parsing
4263 pTmp
+= sizeof(CIPHER_SUITE_STRUCT
);
4265 // 2. Get pairwise cipher counts
4266 //Count = *(PUSHORT) pTmp;
4267 Count
= (pTmp
[1]<<8) + pTmp
[0];
4268 pTmp
+= sizeof(USHORT
);
4270 // 3. Get pairwise cipher
4271 // Parsing all unicast cipher suite
4275 pCipher
= (PCIPHER_SUITE_STRUCT
) pTmp
;
4276 TmpCipher
= Ndis802_11WEPDisabled
;
4277 switch (pCipher
->Type
)
4280 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4281 TmpCipher
= Ndis802_11Encryption1Enabled
;
4284 TmpCipher
= Ndis802_11Encryption2Enabled
;
4287 TmpCipher
= Ndis802_11Encryption3Enabled
;
4292 if (TmpCipher
> pBss
->WPA2
.PairCipher
)
4294 // Move the lower cipher suite to PairCipherAux
4295 pBss
->WPA2
.PairCipherAux
= pBss
->WPA2
.PairCipher
;
4296 pBss
->WPA2
.PairCipher
= TmpCipher
;
4300 pBss
->WPA2
.PairCipherAux
= TmpCipher
;
4302 pTmp
+= sizeof(CIPHER_SUITE_STRUCT
);
4306 // 4. get AKM suite counts
4307 //Count = *(PUSHORT) pTmp;
4308 Count
= (pTmp
[1]<<8) + pTmp
[0];
4309 pTmp
+= sizeof(USHORT
);
4311 // 5. Get AKM ciphers
4312 pAKM
= (PAKM_SUITE_STRUCT
) pTmp
;
4313 if (!RTMPEqualMemory(pTmp
, RSN_OUI
, 3))
4319 // Set AP support WPA mode
4320 if (pBss
->AuthMode
== Ndis802_11AuthModeOpen
)
4321 pBss
->AuthMode
= Ndis802_11AuthModeWPA2
;
4323 pBss
->AuthModeAux
= Ndis802_11AuthModeWPA2
;
4326 // Set AP support WPA mode
4327 if (pBss
->AuthMode
== Ndis802_11AuthModeOpen
)
4328 pBss
->AuthMode
= Ndis802_11AuthModeWPA2PSK
;
4330 pBss
->AuthModeAux
= Ndis802_11AuthModeWPA2PSK
;
4335 pTmp
+= (Count
* sizeof(AKM_SUITE_STRUCT
));
4337 // Fixed for WPA-None
4338 if (pBss
->BssType
== BSS_ADHOC
)
4340 pBss
->AuthMode
= Ndis802_11AuthModeWPANone
;
4341 pBss
->AuthModeAux
= Ndis802_11AuthModeWPANone
;
4342 pBss
->WPA
.PairCipherAux
= pBss
->WPA2
.PairCipherAux
;
4343 pBss
->WPA
.GroupCipher
= pBss
->WPA2
.GroupCipher
;
4344 pBss
->WepStatus
= pBss
->WPA
.GroupCipher
;
4345 // Patched bugs for old driver
4346 if (pBss
->WPA
.PairCipherAux
== Ndis802_11WEPDisabled
)
4347 pBss
->WPA
.PairCipherAux
= pBss
->WPA
.GroupCipher
;
4349 pBss
->WepStatus
= pBss
->WPA2
.PairCipher
;
4351 // 6. Get RSN capability
4352 //pBss->WPA2.RsnCapability = *(PUSHORT) pTmp;
4353 pBss
->WPA2
.RsnCapability
= (pTmp
[1]<<8) + pTmp
[0];
4354 pTmp
+= sizeof(USHORT
);
4356 // Check the Pair & Group, if different, turn on mixed mode flag
4357 if (pBss
->WPA2
.GroupCipher
!= pBss
->WPA2
.PairCipher
)
4358 pBss
->WPA2
.bMixMode
= TRUE
;
4364 Length
-= (pEid
->Len
+ 2);
4368 // ===========================================================================================
4370 // ===========================================================================================
4372 /*! \brief generates a random mac address value for IBSS BSSID
4373 * \param Addr the bssid location
4378 VOID
MacAddrRandomBssid(
4379 IN PRTMP_ADAPTER pAd
,
4384 for (i
= 0; i
< MAC_ADDR_LEN
; i
++)
4386 pAddr
[i
] = RandomByte(pAd
);
4389 pAddr
[0] = (pAddr
[0] & 0xfe) | 0x02; // the first 2 bits must be 01xxxxxxxx
4392 /*! \brief init the management mac frame header
4393 * \param p_hdr mac header
4394 * \param subtype subtype of the frame
4395 * \param p_ds destination address, don't care if it is a broadcast address
4397 * \pre the station has the following information in the pAd->StaCfg
4401 * \note this function initializes the following field
4403 IRQL = PASSIVE_LEVEL
4404 IRQL = DISPATCH_LEVEL
4407 VOID
MgtMacHeaderInit(
4408 IN PRTMP_ADAPTER pAd
,
4409 IN OUT PHEADER_802_11 pHdr80211
,
4415 NdisZeroMemory(pHdr80211
, sizeof(HEADER_802_11
));
4417 pHdr80211
->FC
.Type
= BTYPE_MGMT
;
4418 pHdr80211
->FC
.SubType
= SubType
;
4419 pHdr80211
->FC
.ToDs
= ToDs
;
4420 COPY_MAC_ADDR(pHdr80211
->Addr1
, pDA
);
4422 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
4423 COPY_MAC_ADDR(pHdr80211
->Addr2
, pAd
->CurrentAddress
);
4425 COPY_MAC_ADDR(pHdr80211
->Addr3
, pBssid
);
4428 // ===========================================================================================
4430 // ===========================================================================================
4432 /*!***************************************************************************
4433 * This routine build an outgoing frame, and fill all information specified
4434 * in argument list to the frame body. The actual frame size is the summation
4437 * Buffer - pointer to a pre-allocated memory segment
4438 * args - a list of <int arg_size, arg> pairs.
4439 * NOTE NOTE NOTE!!!! the last argument must be NULL, otherwise this
4440 * function will FAIL!!!
4442 * Size of the buffer
4444 * MakeOutgoingFrame(Buffer, output_length, 2, &fc, 2, &dur, 6, p_addr1, 6,p_addr2, END_OF_ARGS);
4446 IRQL = PASSIVE_LEVEL
4447 IRQL = DISPATCH_LEVEL
4449 ****************************************************************************/
4450 ULONG
MakeOutgoingFrame(
4452 OUT ULONG
*FrameLen
, ...)
4459 // calculates the total length
4461 va_start(Args
, FrameLen
);
4464 leng
= va_arg(Args
, int);
4465 if (leng
== END_OF_ARGS
)
4469 p
= va_arg(Args
, PVOID
);
4470 NdisMoveMemory(&Buffer
[TotLeng
], p
, leng
);
4471 TotLeng
= TotLeng
+ leng
;
4474 va_end(Args
); /* clean up */
4475 *FrameLen
= TotLeng
;
4479 // ===========================================================================================
4481 // ===========================================================================================
4483 /*! \brief Initialize The MLME Queue, used by MLME Functions
4484 * \param *Queue The MLME Queue
4485 * \return Always Return NDIS_STATE_SUCCESS in this implementation
4488 * \note Because this is done only once (at the init stage), no need to be locked
4490 IRQL = PASSIVE_LEVEL
4493 NDIS_STATUS
MlmeQueueInit(
4494 IN MLME_QUEUE
*Queue
)
4498 NdisAllocateSpinLock(&Queue
->Lock
);
4504 for (i
= 0; i
< MAX_LEN_OF_MLME_QUEUE
; i
++)
4506 Queue
->Entry
[i
].Occupied
= FALSE
;
4507 Queue
->Entry
[i
].MsgLen
= 0;
4508 NdisZeroMemory(Queue
->Entry
[i
].Msg
, MGMT_DMA_BUFFER_SIZE
);
4511 return NDIS_STATUS_SUCCESS
;
4514 /*! \brief Enqueue a message for other threads, if they want to send messages to MLME thread
4515 * \param *Queue The MLME Queue
4516 * \param Machine The State Machine Id
4517 * \param MsgType The Message Type
4518 * \param MsgLen The Message length
4519 * \param *Msg The message pointer
4520 * \return TRUE if enqueue is successful, FALSE if the queue is full
4523 * \note The message has to be initialized
4525 IRQL = PASSIVE_LEVEL
4526 IRQL = DISPATCH_LEVEL
4529 BOOLEAN
MlmeEnqueue(
4530 IN PRTMP_ADAPTER pAd
,
4537 MLME_QUEUE
*Queue
= (MLME_QUEUE
*)&pAd
->Mlme
.Queue
;
4539 // Do nothing if the driver is starting halt state.
4540 // This might happen when timer already been fired before cancel timer with mlmehalt
4541 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
| fRTMP_ADAPTER_NIC_NOT_EXIST
))
4544 // First check the size, it MUST not exceed the mlme queue size
4545 if (MsgLen
> MGMT_DMA_BUFFER_SIZE
)
4547 DBGPRINT_ERR(("MlmeEnqueue: msg too large, size = %ld \n", MsgLen
));
4551 if (MlmeQueueFull(Queue
))
4556 NdisAcquireSpinLock(&(Queue
->Lock
));
4560 if (Queue
->Tail
== MAX_LEN_OF_MLME_QUEUE
)
4565 Queue
->Entry
[Tail
].Wcid
= RESERVED_WCID
;
4566 Queue
->Entry
[Tail
].Occupied
= TRUE
;
4567 Queue
->Entry
[Tail
].Machine
= Machine
;
4568 Queue
->Entry
[Tail
].MsgType
= MsgType
;
4569 Queue
->Entry
[Tail
].MsgLen
= MsgLen
;
4573 NdisMoveMemory(Queue
->Entry
[Tail
].Msg
, Msg
, MsgLen
);
4576 NdisReleaseSpinLock(&(Queue
->Lock
));
4580 /*! \brief This function is used when Recv gets a MLME message
4581 * \param *Queue The MLME Queue
4582 * \param TimeStampHigh The upper 32 bit of timestamp
4583 * \param TimeStampLow The lower 32 bit of timestamp
4584 * \param Rssi The receiving RSSI strength
4585 * \param MsgLen The length of the message
4586 * \param *Msg The message pointer
4587 * \return TRUE if everything ok, FALSE otherwise (like Queue Full)
4591 IRQL = DISPATCH_LEVEL
4594 BOOLEAN
MlmeEnqueueForRecv(
4595 IN PRTMP_ADAPTER pAd
,
4597 IN ULONG TimeStampHigh
,
4598 IN ULONG TimeStampLow
,
4607 PFRAME_802_11 pFrame
= (PFRAME_802_11
)Msg
;
4609 MLME_QUEUE
*Queue
= (MLME_QUEUE
*)&pAd
->Mlme
.Queue
;
4611 // Do nothing if the driver is starting halt state.
4612 // This might happen when timer already been fired before cancel timer with mlmehalt
4613 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
| fRTMP_ADAPTER_NIC_NOT_EXIST
))
4615 DBGPRINT_ERR(("MlmeEnqueueForRecv: fRTMP_ADAPTER_HALT_IN_PROGRESS\n"));
4619 // First check the size, it MUST not exceed the mlme queue size
4620 if (MsgLen
> MGMT_DMA_BUFFER_SIZE
)
4622 DBGPRINT_ERR(("MlmeEnqueueForRecv: frame too large, size = %ld \n", MsgLen
));
4626 if (MlmeQueueFull(Queue
))
4631 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
4633 if (!MsgTypeSubst(pAd
, pFrame
, &Machine
, &MsgType
))
4635 DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n",pFrame
->Hdr
.FC
.SubType
));
4640 // OK, we got all the informations, it is time to put things into queue
4641 NdisAcquireSpinLock(&(Queue
->Lock
));
4645 if (Queue
->Tail
== MAX_LEN_OF_MLME_QUEUE
)
4649 Queue
->Entry
[Tail
].Occupied
= TRUE
;
4650 Queue
->Entry
[Tail
].Machine
= Machine
;
4651 Queue
->Entry
[Tail
].MsgType
= MsgType
;
4652 Queue
->Entry
[Tail
].MsgLen
= MsgLen
;
4653 Queue
->Entry
[Tail
].TimeStamp
.u
.LowPart
= TimeStampLow
;
4654 Queue
->Entry
[Tail
].TimeStamp
.u
.HighPart
= TimeStampHigh
;
4655 Queue
->Entry
[Tail
].Rssi0
= Rssi0
;
4656 Queue
->Entry
[Tail
].Rssi1
= Rssi1
;
4657 Queue
->Entry
[Tail
].Rssi2
= Rssi2
;
4658 Queue
->Entry
[Tail
].Signal
= Signal
;
4659 Queue
->Entry
[Tail
].Wcid
= (UCHAR
)Wcid
;
4661 Queue
->Entry
[Tail
].Channel
= pAd
->LatchRfRegs
.Channel
;
4665 NdisMoveMemory(Queue
->Entry
[Tail
].Msg
, Msg
, MsgLen
);
4668 NdisReleaseSpinLock(&(Queue
->Lock
));
4670 RT28XX_MLME_HANDLER(pAd
);
4676 /*! \brief Dequeue a message from the MLME Queue
4677 * \param *Queue The MLME Queue
4678 * \param *Elem The message dequeued from MLME Queue
4679 * \return TRUE if the Elem contains something, FALSE otherwise
4683 IRQL = DISPATCH_LEVEL
4686 BOOLEAN
MlmeDequeue(
4687 IN MLME_QUEUE
*Queue
,
4688 OUT MLME_QUEUE_ELEM
**Elem
)
4690 NdisAcquireSpinLock(&(Queue
->Lock
));
4691 *Elem
= &(Queue
->Entry
[Queue
->Head
]);
4694 if (Queue
->Head
== MAX_LEN_OF_MLME_QUEUE
)
4698 NdisReleaseSpinLock(&(Queue
->Lock
));
4702 // IRQL = DISPATCH_LEVEL
4703 VOID
MlmeRestartStateMachine(
4704 IN PRTMP_ADAPTER pAd
)
4706 MLME_QUEUE_ELEM
*Elem
= NULL
;
4709 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeRestartStateMachine \n"));
4711 NdisAcquireSpinLock(&pAd
->Mlme
.TaskLock
);
4712 if(pAd
->Mlme
.bRunning
)
4714 NdisReleaseSpinLock(&pAd
->Mlme
.TaskLock
);
4719 pAd
->Mlme
.bRunning
= TRUE
;
4721 NdisReleaseSpinLock(&pAd
->Mlme
.TaskLock
);
4723 // Remove all Mlme queues elements
4724 while (!MlmeQueueEmpty(&pAd
->Mlme
.Queue
))
4726 //From message type, determine which state machine I should drive
4727 if (MlmeDequeue(&pAd
->Mlme
.Queue
, &Elem
))
4729 // free MLME element
4730 Elem
->Occupied
= FALSE
;
4735 DBGPRINT_ERR(("MlmeRestartStateMachine: MlmeQueue empty\n"));
4739 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
4741 // Cancel all timer events
4742 // Be careful to cancel new added timer
4743 RTMPCancelTimer(&pAd
->MlmeAux
.AssocTimer
, &Cancelled
);
4744 RTMPCancelTimer(&pAd
->MlmeAux
.ReassocTimer
, &Cancelled
);
4745 RTMPCancelTimer(&pAd
->MlmeAux
.DisassocTimer
, &Cancelled
);
4746 RTMPCancelTimer(&pAd
->MlmeAux
.AuthTimer
, &Cancelled
);
4747 RTMPCancelTimer(&pAd
->MlmeAux
.BeaconTimer
, &Cancelled
);
4748 RTMPCancelTimer(&pAd
->MlmeAux
.ScanTimer
, &Cancelled
);
4751 // Change back to original channel in case of doing scan
4752 AsicSwitchChannel(pAd
, pAd
->CommonCfg
.Channel
, FALSE
);
4753 AsicLockChannel(pAd
, pAd
->CommonCfg
.Channel
);
4755 // Resume MSDU which is turned off durning scan
4756 RTMPResumeMsduTransmission(pAd
);
4758 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
4760 // Set all state machines back IDLE
4761 pAd
->Mlme
.CntlMachine
.CurrState
= CNTL_IDLE
;
4762 pAd
->Mlme
.AssocMachine
.CurrState
= ASSOC_IDLE
;
4763 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
4764 pAd
->Mlme
.AuthRspMachine
.CurrState
= AUTH_RSP_IDLE
;
4765 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
4766 pAd
->Mlme
.ActMachine
.CurrState
= ACT_IDLE
;
4769 // Remove running state
4770 NdisAcquireSpinLock(&pAd
->Mlme
.TaskLock
);
4771 pAd
->Mlme
.bRunning
= FALSE
;
4772 NdisReleaseSpinLock(&pAd
->Mlme
.TaskLock
);
4775 /*! \brief test if the MLME Queue is empty
4776 * \param *Queue The MLME Queue
4777 * \return TRUE if the Queue is empty, FALSE otherwise
4781 IRQL = DISPATCH_LEVEL
4784 BOOLEAN
MlmeQueueEmpty(
4785 IN MLME_QUEUE
*Queue
)
4789 NdisAcquireSpinLock(&(Queue
->Lock
));
4790 Ans
= (Queue
->Num
== 0);
4791 NdisReleaseSpinLock(&(Queue
->Lock
));
4796 /*! \brief test if the MLME Queue is full
4797 * \param *Queue The MLME Queue
4798 * \return TRUE if the Queue is empty, FALSE otherwise
4802 IRQL = PASSIVE_LEVEL
4803 IRQL = DISPATCH_LEVEL
4806 BOOLEAN
MlmeQueueFull(
4807 IN MLME_QUEUE
*Queue
)
4811 NdisAcquireSpinLock(&(Queue
->Lock
));
4812 Ans
= (Queue
->Num
== MAX_LEN_OF_MLME_QUEUE
|| Queue
->Entry
[Queue
->Tail
].Occupied
);
4813 NdisReleaseSpinLock(&(Queue
->Lock
));
4818 /*! \brief The destructor of MLME Queue
4823 * \note Clear Mlme Queue, Set Queue->Num to Zero.
4825 IRQL = PASSIVE_LEVEL
4828 VOID
MlmeQueueDestroy(
4829 IN MLME_QUEUE
*pQueue
)
4831 NdisAcquireSpinLock(&(pQueue
->Lock
));
4835 NdisReleaseSpinLock(&(pQueue
->Lock
));
4836 NdisFreeSpinLock(&(pQueue
->Lock
));
4839 /*! \brief To substitute the message type if the message is coming from external
4840 * \param pFrame The frame received
4841 * \param *Machine The state machine
4842 * \param *MsgType the message type for the state machine
4843 * \return TRUE if the substitution is successful, FALSE otherwise
4847 IRQL = DISPATCH_LEVEL
4850 BOOLEAN
MsgTypeSubst(
4851 IN PRTMP_ADAPTER pAd
,
4852 IN PFRAME_802_11 pFrame
,
4860 // Pointer to start of data frames including SNAP header
4861 pData
= (PUCHAR
) pFrame
+ LENGTH_802_11
;
4863 // The only data type will pass to this function is EAPOL frame
4864 if (pFrame
->Hdr
.FC
.Type
== BTYPE_DATA
)
4866 if (NdisEqualMemory(SNAP_AIRONET
, pData
, LENGTH_802_1_H
))
4868 // Cisco Aironet SNAP header
4869 *Machine
= AIRONET_STATE_MACHINE
;
4870 *MsgType
= MT2_AIRONET_MSG
;
4874 *Machine
= WPA_PSK_STATE_MACHINE
;
4875 EAPType
= *((UCHAR
*)pFrame
+ LENGTH_802_11
+ LENGTH_802_1_H
+ 1);
4876 return(WpaMsgTypeSubst(EAPType
, MsgType
));
4880 switch (pFrame
->Hdr
.FC
.SubType
)
4882 case SUBTYPE_ASSOC_REQ
:
4883 *Machine
= ASSOC_STATE_MACHINE
;
4884 *MsgType
= MT2_PEER_ASSOC_REQ
;
4886 case SUBTYPE_ASSOC_RSP
:
4887 *Machine
= ASSOC_STATE_MACHINE
;
4888 *MsgType
= MT2_PEER_ASSOC_RSP
;
4890 case SUBTYPE_REASSOC_REQ
:
4891 *Machine
= ASSOC_STATE_MACHINE
;
4892 *MsgType
= MT2_PEER_REASSOC_REQ
;
4894 case SUBTYPE_REASSOC_RSP
:
4895 *Machine
= ASSOC_STATE_MACHINE
;
4896 *MsgType
= MT2_PEER_REASSOC_RSP
;
4898 case SUBTYPE_PROBE_REQ
:
4899 *Machine
= SYNC_STATE_MACHINE
;
4900 *MsgType
= MT2_PEER_PROBE_REQ
;
4902 case SUBTYPE_PROBE_RSP
:
4903 *Machine
= SYNC_STATE_MACHINE
;
4904 *MsgType
= MT2_PEER_PROBE_RSP
;
4906 case SUBTYPE_BEACON
:
4907 *Machine
= SYNC_STATE_MACHINE
;
4908 *MsgType
= MT2_PEER_BEACON
;
4911 *Machine
= SYNC_STATE_MACHINE
;
4912 *MsgType
= MT2_PEER_ATIM
;
4914 case SUBTYPE_DISASSOC
:
4915 *Machine
= ASSOC_STATE_MACHINE
;
4916 *MsgType
= MT2_PEER_DISASSOC_REQ
;
4919 // get the sequence number from payload 24 Mac Header + 2 bytes algorithm
4920 NdisMoveMemory(&Seq
, &pFrame
->Octet
[2], sizeof(USHORT
));
4921 if (Seq
== 1 || Seq
== 3)
4923 *Machine
= AUTH_RSP_STATE_MACHINE
;
4924 *MsgType
= MT2_PEER_AUTH_ODD
;
4926 else if (Seq
== 2 || Seq
== 4)
4928 *Machine
= AUTH_STATE_MACHINE
;
4929 *MsgType
= MT2_PEER_AUTH_EVEN
;
4936 case SUBTYPE_DEAUTH
:
4937 *Machine
= AUTH_RSP_STATE_MACHINE
;
4938 *MsgType
= MT2_PEER_DEAUTH
;
4940 case SUBTYPE_ACTION
:
4941 *Machine
= ACTION_STATE_MACHINE
;
4942 // Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support
4943 if ((pFrame
->Octet
[0]&0x7F) > MAX_PEER_CATE_MSG
)
4945 *MsgType
= MT2_ACT_INVALID
;
4949 *MsgType
= (pFrame
->Octet
[0]&0x7F);
4960 // ===========================================================================================
4962 // ===========================================================================================
4964 /*! \brief Initialize the state machine.
4965 * \param *S pointer to the state machine
4966 * \param Trans State machine transition function
4967 * \param StNr number of states
4968 * \param MsgNr number of messages
4969 * \param DefFunc default function, when there is invalid state/message combination
4970 * \param InitState initial state of the state machine
4971 * \param Base StateMachine base, internal use only
4972 * \pre p_sm should be a legal pointer
4975 IRQL = PASSIVE_LEVEL
4978 VOID
StateMachineInit(
4979 IN STATE_MACHINE
*S
,
4980 IN STATE_MACHINE_FUNC Trans
[],
4983 IN STATE_MACHINE_FUNC DefFunc
,
4989 // set number of states and messages
4994 S
->TransFunc
= Trans
;
4996 // init all state transition to default function
4997 for (i
= 0; i
< StNr
; i
++)
4999 for (j
= 0; j
< MsgNr
; j
++)
5001 S
->TransFunc
[i
* MsgNr
+ j
] = DefFunc
;
5005 // set the starting state
5006 S
->CurrState
= InitState
;
5009 /*! \brief This function fills in the function pointer into the cell in the state machine
5010 * \param *S pointer to the state machine
5012 * \param Msg incoming message
5013 * \param f the function to be executed when (state, message) combination occurs at the state machine
5014 * \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
5017 IRQL = PASSIVE_LEVEL
5020 VOID
StateMachineSetAction(
5021 IN STATE_MACHINE
*S
,
5024 IN STATE_MACHINE_FUNC Func
)
5028 MsgIdx
= Msg
- S
->Base
;
5030 if (St
< S
->NrState
&& MsgIdx
< S
->NrMsg
)
5032 // boundary checking before setting the action
5033 S
->TransFunc
[St
* S
->NrMsg
+ MsgIdx
] = Func
;
5037 /*! \brief This function does the state transition
5038 * \param *Adapter the NIC adapter pointer
5039 * \param *S the state machine
5040 * \param *Elem the message to be executed
5043 IRQL = DISPATCH_LEVEL
5046 VOID
StateMachinePerformAction(
5047 IN PRTMP_ADAPTER pAd
,
5048 IN STATE_MACHINE
*S
,
5049 IN MLME_QUEUE_ELEM
*Elem
)
5051 (*(S
->TransFunc
[S
->CurrState
* S
->NrMsg
+ Elem
->MsgType
- S
->Base
]))(pAd
, Elem
);
5055 ==========================================================================
5057 The drop function, when machine executes this, the message is simply
5058 ignored. This function does nothing, the message is freed in
5059 StateMachinePerformAction()
5060 ==========================================================================
5063 IN PRTMP_ADAPTER pAd
,
5064 IN MLME_QUEUE_ELEM
*Elem
)
5068 // ===========================================================================================
5070 // ===========================================================================================
5073 ==========================================================================
5076 IRQL = PASSIVE_LEVEL
5078 ==========================================================================
5081 IN PRTMP_ADAPTER pAd
,
5085 pAd
->Mlme
.ShiftReg
= 1;
5087 pAd
->Mlme
.ShiftReg
= Seed
;
5091 ==========================================================================
5093 ==========================================================================
5096 IN PRTMP_ADAPTER pAd
)
5103 if (pAd
->Mlme
.ShiftReg
== 0)
5104 NdisGetSystemUpTime((ULONG
*)&pAd
->Mlme
.ShiftReg
);
5106 for (i
= 0; i
< 8; i
++)
5108 if (pAd
->Mlme
.ShiftReg
& 0x00000001)
5110 pAd
->Mlme
.ShiftReg
= ((pAd
->Mlme
.ShiftReg
^ LFSR_MASK
) >> 1) | 0x80000000;
5115 pAd
->Mlme
.ShiftReg
= pAd
->Mlme
.ShiftReg
>> 1;
5118 R
= (R
<< 1) | Result
;
5124 VOID
AsicUpdateAutoFallBackTable(
5125 IN PRTMP_ADAPTER pAd
,
5126 IN PUCHAR pRateTable
)
5129 HT_FBK_CFG0_STRUC HtCfg0
;
5130 HT_FBK_CFG1_STRUC HtCfg1
;
5131 LG_FBK_CFG0_STRUC LgCfg0
;
5132 LG_FBK_CFG1_STRUC LgCfg1
;
5133 PRTMP_TX_RATE_SWITCH pCurrTxRate
, pNextTxRate
;
5135 // set to initial value
5136 HtCfg0
.word
= 0x65432100;
5137 HtCfg1
.word
= 0xedcba988;
5138 LgCfg0
.word
= 0xedcba988;
5139 LgCfg1
.word
= 0x00002100;
5141 pNextTxRate
= (PRTMP_TX_RATE_SWITCH
)pRateTable
+1;
5142 for (i
= 1; i
< *((PUCHAR
) pRateTable
); i
++)
5144 pCurrTxRate
= (PRTMP_TX_RATE_SWITCH
)pRateTable
+1+i
;
5145 switch (pCurrTxRate
->Mode
)
5151 switch(pCurrTxRate
->CurrMCS
)
5154 LgCfg0
.field
.OFDMMCS0FBK
= (pNextTxRate
->Mode
== MODE_OFDM
) ? (pNextTxRate
->CurrMCS
+8): pNextTxRate
->CurrMCS
;
5157 LgCfg0
.field
.OFDMMCS1FBK
= (pNextTxRate
->Mode
== MODE_OFDM
) ? (pNextTxRate
->CurrMCS
+8): pNextTxRate
->CurrMCS
;
5160 LgCfg0
.field
.OFDMMCS2FBK
= (pNextTxRate
->Mode
== MODE_OFDM
) ? (pNextTxRate
->CurrMCS
+8): pNextTxRate
->CurrMCS
;
5163 LgCfg0
.field
.OFDMMCS3FBK
= (pNextTxRate
->Mode
== MODE_OFDM
) ? (pNextTxRate
->CurrMCS
+8): pNextTxRate
->CurrMCS
;
5166 LgCfg0
.field
.OFDMMCS4FBK
= (pNextTxRate
->Mode
== MODE_OFDM
) ? (pNextTxRate
->CurrMCS
+8): pNextTxRate
->CurrMCS
;
5169 LgCfg0
.field
.OFDMMCS5FBK
= (pNextTxRate
->Mode
== MODE_OFDM
) ? (pNextTxRate
->CurrMCS
+8): pNextTxRate
->CurrMCS
;
5172 LgCfg0
.field
.OFDMMCS6FBK
= (pNextTxRate
->Mode
== MODE_OFDM
) ? (pNextTxRate
->CurrMCS
+8): pNextTxRate
->CurrMCS
;
5175 LgCfg0
.field
.OFDMMCS7FBK
= (pNextTxRate
->Mode
== MODE_OFDM
) ? (pNextTxRate
->CurrMCS
+8): pNextTxRate
->CurrMCS
;
5180 #ifdef DOT11_N_SUPPORT
5184 if ((pNextTxRate
->Mode
>= MODE_HTMIX
) && (pCurrTxRate
->CurrMCS
!= pNextTxRate
->CurrMCS
))
5186 switch(pCurrTxRate
->CurrMCS
)
5189 HtCfg0
.field
.HTMCS0FBK
= pNextTxRate
->CurrMCS
;
5192 HtCfg0
.field
.HTMCS1FBK
= pNextTxRate
->CurrMCS
;
5195 HtCfg0
.field
.HTMCS2FBK
= pNextTxRate
->CurrMCS
;
5198 HtCfg0
.field
.HTMCS3FBK
= pNextTxRate
->CurrMCS
;
5201 HtCfg0
.field
.HTMCS4FBK
= pNextTxRate
->CurrMCS
;
5204 HtCfg0
.field
.HTMCS5FBK
= pNextTxRate
->CurrMCS
;
5207 HtCfg0
.field
.HTMCS6FBK
= pNextTxRate
->CurrMCS
;
5210 HtCfg0
.field
.HTMCS7FBK
= pNextTxRate
->CurrMCS
;
5213 HtCfg1
.field
.HTMCS8FBK
= pNextTxRate
->CurrMCS
;
5216 HtCfg1
.field
.HTMCS9FBK
= pNextTxRate
->CurrMCS
;
5219 HtCfg1
.field
.HTMCS10FBK
= pNextTxRate
->CurrMCS
;
5222 HtCfg1
.field
.HTMCS11FBK
= pNextTxRate
->CurrMCS
;
5225 HtCfg1
.field
.HTMCS12FBK
= pNextTxRate
->CurrMCS
;
5228 HtCfg1
.field
.HTMCS13FBK
= pNextTxRate
->CurrMCS
;
5231 HtCfg1
.field
.HTMCS14FBK
= pNextTxRate
->CurrMCS
;
5234 HtCfg1
.field
.HTMCS15FBK
= pNextTxRate
->CurrMCS
;
5237 DBGPRINT(RT_DEBUG_ERROR
, ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n", pCurrTxRate
->CurrMCS
));
5242 #endif // DOT11_N_SUPPORT //
5245 pNextTxRate
= pCurrTxRate
;
5248 RTMP_IO_WRITE32(pAd
, HT_FBK_CFG0
, HtCfg0
.word
);
5249 RTMP_IO_WRITE32(pAd
, HT_FBK_CFG1
, HtCfg1
.word
);
5250 RTMP_IO_WRITE32(pAd
, LG_FBK_CFG0
, LgCfg0
.word
);
5251 RTMP_IO_WRITE32(pAd
, LG_FBK_CFG1
, LgCfg1
.word
);
5255 ========================================================================
5257 Routine Description:
5258 Set MAC register value according operation mode.
5259 OperationMode AND bNonGFExist are for MM and GF Proteciton.
5260 If MM or GF mask is not set, those passing argument doesn't not take effect.
5262 Operation mode meaning:
5263 = 0 : Pure HT, no preotection.
5264 = 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS.
5265 = 0x10: No Transmission in 40M is protected.
5266 = 0x11: Transmission in both 40M and 20M shall be protected
5268 we should choose not to use GF. But still set correct ASIC registers.
5269 ========================================================================
5271 VOID
AsicUpdateProtect(
5272 IN PRTMP_ADAPTER pAd
,
5273 IN USHORT OperationMode
,
5275 IN BOOLEAN bDisableBGProtect
,
5276 IN BOOLEAN bNonGFExist
)
5278 PROT_CFG_STRUC ProtCfg
, ProtCfg4
;
5284 #ifdef DOT11_N_SUPPORT
5285 if (!(pAd
->CommonCfg
.bHTProtect
) && (OperationMode
!= 8))
5290 if (pAd
->BATable
.numAsOriginator
)
5293 // enable the RTS/CTS to avoid channel collision
5295 SetMask
= ALLN_SETPROTECT
;
5298 #endif // DOT11_N_SUPPORT //
5300 // Config ASIC RTS threshold register
5301 RTMP_IO_READ32(pAd
, TX_RTS_CFG
, &MacReg
);
5302 MacReg
&= 0xFF0000FF;
5304 MacReg
|= (pAd
->CommonCfg
.RtsThreshold
<< 8);
5306 // If the user want disable RtsThreshold and enable Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096
5308 #ifdef DOT11_N_SUPPORT
5309 (pAd
->CommonCfg
.BACapability
.field
.AmsduEnable
) ||
5310 #endif // DOT11_N_SUPPORT //
5311 (pAd
->CommonCfg
.bAggregationCapable
== TRUE
))
5312 && pAd
->CommonCfg
.RtsThreshold
== MAX_RTS_THRESHOLD
)
5314 MacReg
|= (0x1000 << 8);
5318 MacReg
|= (pAd
->CommonCfg
.RtsThreshold
<< 8);
5322 RTMP_IO_WRITE32(pAd
, TX_RTS_CFG
, MacReg
);
5324 // Initial common protection settings
5325 RTMPZeroMemory(Protect
, sizeof(Protect
));
5328 ProtCfg
.field
.TxopAllowGF40
= 1;
5329 ProtCfg
.field
.TxopAllowGF20
= 1;
5330 ProtCfg
.field
.TxopAllowMM40
= 1;
5331 ProtCfg
.field
.TxopAllowMM20
= 1;
5332 ProtCfg
.field
.TxopAllowOfdm
= 1;
5333 ProtCfg
.field
.TxopAllowCck
= 1;
5334 ProtCfg
.field
.RTSThEn
= 1;
5335 ProtCfg
.field
.ProtectNav
= ASIC_SHORTNAV
;
5337 // update PHY mode and rate
5338 if (pAd
->CommonCfg
.Channel
> 14)
5339 ProtCfg
.field
.ProtectRate
= 0x4000;
5340 ProtCfg
.field
.ProtectRate
|= pAd
->CommonCfg
.RtsRate
;
5342 // Handle legacy(B/G) protection
5343 if (bDisableBGProtect
)
5345 //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
5346 ProtCfg
.field
.ProtectCtrl
= 0;
5347 Protect
[0] = ProtCfg
.word
;
5348 Protect
[1] = ProtCfg
.word
;
5352 //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
5353 ProtCfg
.field
.ProtectCtrl
= 0; // CCK do not need to be protected
5354 Protect
[0] = ProtCfg
.word
;
5355 ProtCfg
.field
.ProtectCtrl
= ASIC_CTS
; // OFDM needs using CCK to protect
5356 Protect
[1] = ProtCfg
.word
;
5359 #ifdef DOT11_N_SUPPORT
5360 // Decide HT frame protection.
5361 if ((SetMask
& ALLN_SETPROTECT
) != 0)
5363 switch(OperationMode
)
5367 // 1.All STAs in the BSS are 20/40 MHz HT
5368 // 2. in ai 20/40MHz BSS
5369 // 3. all STAs are 20MHz in a 20MHz BSS
5370 // Pure HT. no protection.
5374 // PROT_TXOP(25:20) -- 010111
5375 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5376 // PROT_CTRL(17:16) -- 00 (None)
5377 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
5378 Protect
[2] = 0x01744004;
5382 // PROT_TXOP(25:20) -- 111111
5383 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5384 // PROT_CTRL(17:16) -- 00 (None)
5385 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
5386 Protect
[3] = 0x03f44084;
5390 // PROT_TXOP(25:20) -- 010111
5391 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5392 // PROT_CTRL(17:16) -- 00 (None)
5393 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
5394 Protect
[4] = 0x01744004;
5398 // PROT_TXOP(25:20) -- 111111
5399 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5400 // PROT_CTRL(17:16) -- 00 (None)
5401 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
5402 Protect
[5] = 0x03f44084;
5406 // PROT_NAV(19:18) -- 01 (Short NAV protectiion)
5407 // PROT_CTRL(17:16) -- 01 (RTS/CTS)
5408 Protect
[4] = 0x01754004;
5409 Protect
[5] = 0x03f54084;
5411 pAd
->CommonCfg
.IOTestParm
.bRTSLongProtOn
= FALSE
;
5415 // This is "HT non-member protection mode."
5416 // If there may be non-HT STAs my BSS
5417 ProtCfg
.word
= 0x01744004; // PROT_CTRL(17:16) : 0 (None)
5418 ProtCfg4
.word
= 0x03f44084; // duplicaet legacy 24M. BW set 1.
5419 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_BG_PROTECTION_INUSED
))
5421 ProtCfg
.word
= 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
5422 ProtCfg4
.word
= 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083;
5424 //Assign Protection method for 20&40 MHz packets
5425 ProtCfg
.field
.ProtectCtrl
= ASIC_RTS
;
5426 ProtCfg
.field
.ProtectNav
= ASIC_SHORTNAV
;
5427 ProtCfg4
.field
.ProtectCtrl
= ASIC_RTS
;
5428 ProtCfg4
.field
.ProtectNav
= ASIC_SHORTNAV
;
5429 Protect
[2] = ProtCfg
.word
;
5430 Protect
[3] = ProtCfg4
.word
;
5431 Protect
[4] = ProtCfg
.word
;
5432 Protect
[5] = ProtCfg4
.word
;
5433 pAd
->CommonCfg
.IOTestParm
.bRTSLongProtOn
= TRUE
;
5437 // If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets
5438 ProtCfg
.word
= 0x01744004; // PROT_CTRL(17:16) : 0 (None)
5439 ProtCfg4
.word
= 0x03f44084; // duplicaet legacy 24M. BW set 1.
5441 //Assign Protection method for 40MHz packets
5442 ProtCfg4
.field
.ProtectCtrl
= ASIC_RTS
;
5443 ProtCfg4
.field
.ProtectNav
= ASIC_SHORTNAV
;
5444 Protect
[2] = ProtCfg
.word
;
5445 Protect
[3] = ProtCfg4
.word
;
5448 ProtCfg
.field
.ProtectCtrl
= ASIC_RTS
;
5449 ProtCfg
.field
.ProtectNav
= ASIC_SHORTNAV
;
5451 Protect
[4] = ProtCfg
.word
;
5452 Protect
[5] = ProtCfg4
.word
;
5454 pAd
->CommonCfg
.IOTestParm
.bRTSLongProtOn
= FALSE
;
5458 // HT mixed mode. PROTECT ALL!
5460 ProtCfg
.word
= 0x01744004; //duplicaet legacy 24M. BW set 1.
5461 ProtCfg4
.word
= 0x03f44084;
5462 // both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the
5463 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_BG_PROTECTION_INUSED
))
5465 ProtCfg
.word
= 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
5466 ProtCfg4
.word
= 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083
5468 //Assign Protection method for 20&40 MHz packets
5469 ProtCfg
.field
.ProtectCtrl
= ASIC_RTS
;
5470 ProtCfg
.field
.ProtectNav
= ASIC_SHORTNAV
;
5471 ProtCfg4
.field
.ProtectCtrl
= ASIC_RTS
;
5472 ProtCfg4
.field
.ProtectNav
= ASIC_SHORTNAV
;
5473 Protect
[2] = ProtCfg
.word
;
5474 Protect
[3] = ProtCfg4
.word
;
5475 Protect
[4] = ProtCfg
.word
;
5476 Protect
[5] = ProtCfg4
.word
;
5477 pAd
->CommonCfg
.IOTestParm
.bRTSLongProtOn
= TRUE
;
5481 // Special on for Atheros problem n chip.
5482 Protect
[2] = 0x01754004;
5483 Protect
[3] = 0x03f54084;
5484 Protect
[4] = 0x01754004;
5485 Protect
[5] = 0x03f54084;
5486 pAd
->CommonCfg
.IOTestParm
.bRTSLongProtOn
= TRUE
;
5490 #endif // DOT11_N_SUPPORT //
5492 offset
= CCK_PROT_CFG
;
5493 for (i
= 0;i
< 6;i
++)
5495 if ((SetMask
& (1<< i
)))
5497 RTMP_IO_WRITE32(pAd
, offset
+ i
*4, Protect
[i
]);
5503 ==========================================================================
5506 IRQL = PASSIVE_LEVEL
5507 IRQL = DISPATCH_LEVEL
5509 ==========================================================================
5511 VOID
AsicSwitchChannel(
5512 IN PRTMP_ADAPTER pAd
,
5516 ULONG R2
= 0, R3
= DEFAULT_RF_TX_POWER
, R4
= 0;
5517 CHAR TxPwer
= 0, TxPwer2
= DEFAULT_RF_TX_POWER
; //Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER;
5519 UINT32 Value
= 0; //BbpReg, Value;
5520 RTMP_RF_REGS
*RFRegTable
;
5522 // Search Tx power value
5523 for (index
= 0; index
< pAd
->ChannelListNum
; index
++)
5525 if (Channel
== pAd
->ChannelList
[index
].Channel
)
5527 TxPwer
= pAd
->ChannelList
[index
].Power
;
5528 TxPwer2
= pAd
->ChannelList
[index
].Power2
;
5533 if (index
== MAX_NUM_OF_CHANNELS
)
5535 DBGPRINT(RT_DEBUG_ERROR
, ("AsicSwitchChannel: Cant find the Channel#%d \n", Channel
));
5539 RFRegTable
= RF2850RegTable
;
5541 switch (pAd
->RfIcType
)
5548 for (index
= 0; index
< NUM_OF_2850_CHNL
; index
++)
5550 if (Channel
== RFRegTable
[index
].Channel
)
5552 R2
= RFRegTable
[index
].R2
;
5553 if (pAd
->Antenna
.field
.TxPath
== 1)
5555 R2
|= 0x4000; // If TXpath is 1, bit 14 = 1;
5558 if (pAd
->Antenna
.field
.RxPath
== 2)
5560 R2
|= 0x40; // write 1 to off Rxpath.
5562 else if (pAd
->Antenna
.field
.RxPath
== 1)
5564 R2
|= 0x20040; // write 1 to off RxPath
5569 // initialize R3, R4
5570 R3
= (RFRegTable
[index
].R3
& 0xffffc1ff);
5571 R4
= (RFRegTable
[index
].R4
& (~0x001f87c0)) | (pAd
->RfFreqOffset
<< 15);
5573 // 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB
5575 if ((TxPwer
>= -7) && (TxPwer
< 0))
5577 TxPwer
= (7+TxPwer
);
5578 TxPwer
= (TxPwer
> 0xF) ? (0xF) : (TxPwer
);
5579 R3
|= (TxPwer
<< 10);
5580 DBGPRINT(RT_DEBUG_ERROR
, ("AsicSwitchChannel: TxPwer=%d \n", TxPwer
));
5584 TxPwer
= (TxPwer
> 0xF) ? (0xF) : (TxPwer
);
5585 R3
|= (TxPwer
<< 10) | (1 << 9);
5589 if ((TxPwer2
>= -7) && (TxPwer2
< 0))
5591 TxPwer2
= (7+TxPwer2
);
5592 TxPwer2
= (TxPwer2
> 0xF) ? (0xF) : (TxPwer2
);
5593 R4
|= (TxPwer2
<< 7);
5594 DBGPRINT(RT_DEBUG_ERROR
, ("AsicSwitchChannel: TxPwer2=%d \n", TxPwer2
));
5598 TxPwer2
= (TxPwer2
> 0xF) ? (0xF) : (TxPwer2
);
5599 R4
|= (TxPwer2
<< 7) | (1 << 6);
5604 R3
= (RFRegTable
[index
].R3
& 0xffffc1ff) | (TxPwer
<< 9); // set TX power0
5605 R4
= (RFRegTable
[index
].R4
& (~0x001f87c0)) | (pAd
->RfFreqOffset
<< 15) | (TxPwer2
<<6);// Set freq Offset & TxPwr1
5608 // Based on BBP current mode before changing RF channel.
5609 if (!bScan
&& (pAd
->CommonCfg
.BBPCurrentBW
== BW_40
))
5615 pAd
->LatchRfRegs
.Channel
= Channel
;
5616 pAd
->LatchRfRegs
.R1
= RFRegTable
[index
].R1
;
5617 pAd
->LatchRfRegs
.R2
= R2
;
5618 pAd
->LatchRfRegs
.R3
= R3
;
5619 pAd
->LatchRfRegs
.R4
= R4
;
5621 // Set RF value 1's set R3[bit2] = [0]
5622 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R1
);
5623 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R2
);
5624 RTMP_RF_IO_WRITE32(pAd
, (pAd
->LatchRfRegs
.R3
& (~0x04)));
5625 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R4
);
5629 // Set RF value 2's set R3[bit2] = [1]
5630 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R1
);
5631 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R2
);
5632 RTMP_RF_IO_WRITE32(pAd
, (pAd
->LatchRfRegs
.R3
| 0x04));
5633 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R4
);
5637 // Set RF value 3's set R3[bit2] = [0]
5638 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R1
);
5639 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R2
);
5640 RTMP_RF_IO_WRITE32(pAd
, (pAd
->LatchRfRegs
.R3
& (~0x04)));
5641 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R4
);
5653 // Change BBP setting during siwtch from a->g, g->a
5656 ULONG TxPinCfg
= 0x00050F0A;//Gary 2007/08/09 0x050A0A
5658 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R62
, (0x37 - GET_LNA_GAIN(pAd
)));
5659 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R63
, (0x37 - GET_LNA_GAIN(pAd
)));
5660 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R64
, (0x37 - GET_LNA_GAIN(pAd
)));
5661 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.
5662 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
5664 // Rx High power VGA offset for LNA select
5665 if (pAd
->NicConfig2
.field
.ExternalLNAForG
)
5667 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R82
, 0x62);
5668 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R75
, 0x46);
5672 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R82
, 0x84);
5673 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R75
, 0x50);
5676 // 5G band selection PIN, bit1 and bit2 are complement
5677 RTMP_IO_READ32(pAd
, TX_BAND_CFG
, &Value
);
5680 RTMP_IO_WRITE32(pAd
, TX_BAND_CFG
, Value
);
5682 // Turn off unused PA or LNA when only 1T or 1R
5683 if (pAd
->Antenna
.field
.TxPath
== 1)
5685 TxPinCfg
&= 0xFFFFFFF3;
5687 if (pAd
->Antenna
.field
.RxPath
== 1)
5689 TxPinCfg
&= 0xFFFFF3FF;
5692 RTMP_IO_WRITE32(pAd
, TX_PIN_CFG
, TxPinCfg
);
5696 ULONG TxPinCfg
= 0x00050F05;//Gary 2007/8/9 0x050505
5698 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R62
, (0x37 - GET_LNA_GAIN(pAd
)));
5699 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R63
, (0x37 - GET_LNA_GAIN(pAd
)));
5700 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R64
, (0x37 - GET_LNA_GAIN(pAd
)));
5701 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.
5702 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R82
, 0xF2);
5704 // Rx High power VGA offset for LNA select
5705 if (pAd
->NicConfig2
.field
.ExternalLNAForA
)
5707 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R75
, 0x46);
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
);
5733 // R66 should be set according to Channel and use 20MHz when scanning
5734 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd)));
5736 RTMPSetAGCInitValue(pAd
, BW_20
);
5738 RTMPSetAGCInitValue(pAd
, pAd
->CommonCfg
.BBPCurrentBW
);
5741 // On 11A, We should delay and wait RF/BBP to be stable
5742 // and the appropriate time should be 1000 micro seconds
5743 // 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
5745 RTMPusecDelay(1000);
5747 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",
5750 (R3
& 0x00003e00) >> 9,
5751 (R4
& 0x000007c0) >> 6,
5752 pAd
->Antenna
.field
.TxPath
,
5753 pAd
->LatchRfRegs
.R1
,
5754 pAd
->LatchRfRegs
.R2
,
5755 pAd
->LatchRfRegs
.R3
,
5756 pAd
->LatchRfRegs
.R4
));
5760 ==========================================================================
5762 This function is required for 2421 only, and should not be used during
5763 site survey. It's only required after NIC decided to stay at a channel
5764 for a longer period.
5765 When this function is called, it's always after AsicSwitchChannel().
5767 IRQL = PASSIVE_LEVEL
5768 IRQL = DISPATCH_LEVEL
5770 ==========================================================================
5772 VOID
AsicLockChannel(
5773 IN PRTMP_ADAPTER pAd
,
5779 ==========================================================================
5782 IRQL = PASSIVE_LEVEL
5783 IRQL = DISPATCH_LEVEL
5785 ==========================================================================
5787 VOID
AsicAntennaSelect(
5788 IN PRTMP_ADAPTER pAd
,
5794 ========================================================================
5796 Routine Description:
5797 Antenna miscellaneous setting.
5800 pAd Pointer to our adapter
5801 BandState Indicate current Band State.
5806 IRQL <= DISPATCH_LEVEL
5809 1.) Frame End type control
5810 only valid for G only (RF_2527 & RF_2529)
5811 0: means DPDT, set BBP R4 bit 5 to 1
5812 1: means SPDT, set BBP R4 bit 5 to 0
5815 ========================================================================
5817 VOID
AsicAntennaSetting(
5818 IN PRTMP_ADAPTER pAd
,
5819 IN ABGBAND_STATE BandState
)
5823 VOID
AsicRfTuningExec(
5824 IN PVOID SystemSpecific1
,
5825 IN PVOID FunctionContext
,
5826 IN PVOID SystemSpecific2
,
5827 IN PVOID SystemSpecific3
)
5832 ==========================================================================
5834 Gives CCK TX rate 2 more dB TX power.
5835 This routine works only in LINK UP in INFRASTRUCTURE mode.
5837 calculate desired Tx power in RF R3.Tx0~5, should consider -
5838 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
5839 1. TxPowerPercentage
5840 2. auto calibration based on TSSI feedback
5841 3. extra 2 db for CCK
5842 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
5844 NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
5845 it should be called AFTER MlmeDynamicTxRatSwitching()
5846 ==========================================================================
5848 VOID
AsicAdjustTxPower(
5849 IN PRTMP_ADAPTER pAd
)
5853 BOOLEAN bAutoTxAgc
= FALSE
;
5854 UCHAR TssiRef
, *pTssiMinusBoundary
, *pTssiPlusBoundary
, TxAgcStep
;
5855 UCHAR BbpR1
= 0, BbpR49
= 0, idx
;
5856 PCHAR pTxAgcCompensate
;
5860 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_DOZE
)
5861 || (pAd
->bPCIclkOff
== TRUE
)
5862 || RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_IDLE_RADIO_OFF
)
5863 || RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS
))
5866 if (pAd
->CommonCfg
.BBPCurrentBW
== BW_40
)
5868 if (pAd
->CommonCfg
.CentralChannel
> 14)
5870 TxPwr
[0] = pAd
->Tx40MPwrCfgABand
[0];
5871 TxPwr
[1] = pAd
->Tx40MPwrCfgABand
[1];
5872 TxPwr
[2] = pAd
->Tx40MPwrCfgABand
[2];
5873 TxPwr
[3] = pAd
->Tx40MPwrCfgABand
[3];
5874 TxPwr
[4] = pAd
->Tx40MPwrCfgABand
[4];
5878 TxPwr
[0] = pAd
->Tx40MPwrCfgGBand
[0];
5879 TxPwr
[1] = pAd
->Tx40MPwrCfgGBand
[1];
5880 TxPwr
[2] = pAd
->Tx40MPwrCfgGBand
[2];
5881 TxPwr
[3] = pAd
->Tx40MPwrCfgGBand
[3];
5882 TxPwr
[4] = pAd
->Tx40MPwrCfgGBand
[4];
5887 if (pAd
->CommonCfg
.Channel
> 14)
5889 TxPwr
[0] = pAd
->Tx20MPwrCfgABand
[0];
5890 TxPwr
[1] = pAd
->Tx20MPwrCfgABand
[1];
5891 TxPwr
[2] = pAd
->Tx20MPwrCfgABand
[2];
5892 TxPwr
[3] = pAd
->Tx20MPwrCfgABand
[3];
5893 TxPwr
[4] = pAd
->Tx20MPwrCfgABand
[4];
5897 TxPwr
[0] = pAd
->Tx20MPwrCfgGBand
[0];
5898 TxPwr
[1] = pAd
->Tx20MPwrCfgGBand
[1];
5899 TxPwr
[2] = pAd
->Tx20MPwrCfgGBand
[2];
5900 TxPwr
[3] = pAd
->Tx20MPwrCfgGBand
[3];
5901 TxPwr
[4] = pAd
->Tx20MPwrCfgGBand
[4];
5905 // TX power compensation for temperature variation based on TSSI. try every 4 second
5906 if (pAd
->Mlme
.OneSecPeriodicRound
% 4 == 0)
5908 if (pAd
->CommonCfg
.Channel
<= 14)
5911 bAutoTxAgc
= pAd
->bAutoTxAgcG
;
5912 TssiRef
= pAd
->TssiRefG
;
5913 pTssiMinusBoundary
= &pAd
->TssiMinusBoundaryG
[0];
5914 pTssiPlusBoundary
= &pAd
->TssiPlusBoundaryG
[0];
5915 TxAgcStep
= pAd
->TxAgcStepG
;
5916 pTxAgcCompensate
= &pAd
->TxAgcCompensateG
;
5921 bAutoTxAgc
= pAd
->bAutoTxAgcA
;
5922 TssiRef
= pAd
->TssiRefA
;
5923 pTssiMinusBoundary
= &pAd
->TssiMinusBoundaryA
[0];
5924 pTssiPlusBoundary
= &pAd
->TssiPlusBoundaryA
[0];
5925 TxAgcStep
= pAd
->TxAgcStepA
;
5926 pTxAgcCompensate
= &pAd
->TxAgcCompensateA
;
5931 /* BbpR1 is unsigned char */
5932 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R49
, &BbpR49
);
5934 /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
5935 /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */
5936 /* step value is defined in pAd->TxAgcStepG for tx power value */
5938 /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */
5939 /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
5940 above value are examined in mass factory production */
5941 /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */
5943 /* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */
5944 /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
5945 /* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */
5947 if (BbpR49
> pTssiMinusBoundary
[1])
5949 // Reading is larger than the reference value
5950 // check for how large we need to decrease the Tx power
5951 for (idx
= 1; idx
< 5; idx
++)
5953 if (BbpR49
<= pTssiMinusBoundary
[idx
]) // Found the range
5956 // The index is the step we should decrease, idx = 0 means there is nothing to compensate
5957 *pTxAgcCompensate
= -(TxAgcStep
* (idx
-1));
5959 DeltaPwr
+= (*pTxAgcCompensate
);
5960 DBGPRINT(RT_DEBUG_TRACE
, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
5961 BbpR49
, TssiRef
, TxAgcStep
, idx
-1));
5963 else if (BbpR49
< pTssiPlusBoundary
[1])
5965 // Reading is smaller than the reference value
5966 // check for how large we need to increase the Tx power
5967 for (idx
= 1; idx
< 5; idx
++)
5969 if (BbpR49
>= pTssiPlusBoundary
[idx
]) // Found the range
5972 // The index is the step we should increase, idx = 0 means there is nothing to compensate
5973 *pTxAgcCompensate
= TxAgcStep
* (idx
-1);
5974 DeltaPwr
+= (*pTxAgcCompensate
);
5975 DBGPRINT(RT_DEBUG_TRACE
, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
5976 BbpR49
, TssiRef
, TxAgcStep
, idx
-1));
5980 *pTxAgcCompensate
= 0;
5981 DBGPRINT(RT_DEBUG_TRACE
, (" Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
5982 BbpR49
, TssiRef
, TxAgcStep
, 0));
5988 if (pAd
->CommonCfg
.Channel
<= 14)
5990 bAutoTxAgc
= pAd
->bAutoTxAgcG
;
5991 pTxAgcCompensate
= &pAd
->TxAgcCompensateG
;
5995 bAutoTxAgc
= pAd
->bAutoTxAgcA
;
5996 pTxAgcCompensate
= &pAd
->TxAgcCompensateA
;
6000 DeltaPwr
+= (*pTxAgcCompensate
);
6003 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R1
, &BbpR1
);
6006 /* calculate delta power based on the percentage specified from UI */
6007 // E2PROM setting is calibrated for maximum TX power (i.e. 100%)
6008 // We lower TX power here according to the percentage specified from UI
6009 if (pAd
->CommonCfg
.TxPowerPercentage
== 0xffffffff) // AUTO TX POWER control
6011 else if (pAd
->CommonCfg
.TxPowerPercentage
> 90) // 91 ~ 100% & AUTO, treat as 100% in terms of mW
6013 else if (pAd
->CommonCfg
.TxPowerPercentage
> 60) // 61 ~ 90%, treat as 75% in terms of mW // DeltaPwr -= 1;
6017 else if (pAd
->CommonCfg
.TxPowerPercentage
> 30) // 31 ~ 60%, treat as 50% in terms of mW // DeltaPwr -= 3;
6021 else if (pAd
->CommonCfg
.TxPowerPercentage
> 15) // 16 ~ 30%, treat as 25% in terms of mW // DeltaPwr -= 6;
6025 else if (pAd
->CommonCfg
.TxPowerPercentage
> 9) // 10 ~ 15%, treat as 12.5% in terms of mW // DeltaPwr -= 9;
6030 else // 0 ~ 9 %, treat as MIN(~3%) in terms of mW // DeltaPwr -= 12;
6035 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R1
, BbpR1
);
6037 /* reset different new tx power for different TX rate */
6040 if (TxPwr
[i
] != 0xffffffff)
6044 Value
= (CHAR
)((TxPwr
[i
] >> j
*4) & 0x0F); /* 0 ~ 15 */
6046 if ((Value
+ DeltaPwr
) < 0)
6048 Value
= 0; /* min */
6050 else if ((Value
+ DeltaPwr
) > 0xF)
6052 Value
= 0xF; /* max */
6056 Value
+= DeltaPwr
; /* temperature compensation */
6059 /* fill new value to CSR offset */
6060 TxPwr
[i
] = (TxPwr
[i
] & ~(0x0000000F << j
*4)) | (Value
<< j
*4);
6063 /* write tx power value to CSR */
6064 /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M
6065 TX power for OFDM 6M/9M
6066 TX power for CCK5.5M/11M
6067 TX power for CCK1M/2M */
6068 /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
6069 RTMP_IO_WRITE32(pAd
, TX_PWR_CFG_0
+ i
*4, TxPwr
[i
]);
6076 ==========================================================================
6078 put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup
6079 automatically. Instead, MCU will issue a TwakeUpInterrupt to host after
6080 the wakeup timer timeout. Driver has to issue a separate command to wake
6083 IRQL = DISPATCH_LEVEL
6085 ==========================================================================
6087 VOID
AsicSleepThenAutoWakeup(
6088 IN PRTMP_ADAPTER pAd
,
6089 IN USHORT TbttNumToNextWakeUp
)
6091 RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd
, TbttNumToNextWakeUp
);
6095 ==========================================================================
6097 AsicForceWakeup() is used whenever manual wakeup is required
6098 AsicForceSleep() should only be used when not in INFRA BSS. When
6099 in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead.
6100 ==========================================================================
6102 VOID
AsicForceSleep(
6103 IN PRTMP_ADAPTER pAd
)
6109 ==========================================================================
6111 AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup)
6114 IRQL = PASSIVE_LEVEL
6115 IRQL = DISPATCH_LEVEL
6116 ==========================================================================
6118 VOID
AsicForceWakeup(
6119 IN PRTMP_ADAPTER pAd
,
6122 DBGPRINT(RT_DEBUG_TRACE
, ("--> AsicForceWakeup \n"));
6123 RT28XX_STA_FORCE_WAKEUP(pAd
, Level
);
6127 ==========================================================================
6131 IRQL = DISPATCH_LEVEL
6133 ==========================================================================
6136 IN PRTMP_ADAPTER pAd
,
6140 DBGPRINT(RT_DEBUG_TRACE
, ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n",
6141 pBssid
[0],pBssid
[1],pBssid
[2],pBssid
[3], pBssid
[4],pBssid
[5]));
6143 Addr4
= (ULONG
)(pBssid
[0]) |
6144 (ULONG
)(pBssid
[1] << 8) |
6145 (ULONG
)(pBssid
[2] << 16) |
6146 (ULONG
)(pBssid
[3] << 24);
6147 RTMP_IO_WRITE32(pAd
, MAC_BSSID_DW0
, Addr4
);
6150 // always one BSSID in STA mode
6151 Addr4
= (ULONG
)(pBssid
[4]) | (ULONG
)(pBssid
[5] << 8);
6153 RTMP_IO_WRITE32(pAd
, MAC_BSSID_DW1
, Addr4
);
6156 VOID
AsicSetMcastWC(
6157 IN PRTMP_ADAPTER pAd
)
6159 MAC_TABLE_ENTRY
*pEntry
= &pAd
->MacTab
.Content
[MCAST_WCID
];
6162 pEntry
->Sst
= SST_ASSOC
;
6163 pEntry
->Aid
= MCAST_WCID
; // Softap supports 1 BSSID and use WCID=0 as multicast Wcid index
6164 pEntry
->PsMode
= PWR_ACTIVE
;
6165 pEntry
->CurrTxRate
= pAd
->CommonCfg
.MlmeRate
;
6166 offset
= MAC_WCID_BASE
+ BSS0Mcast_WCID
* HW_WCID_ENTRY_SIZE
;
6170 ==========================================================================
6173 IRQL = DISPATCH_LEVEL
6175 ==========================================================================
6177 VOID
AsicDelWcidTab(
6178 IN PRTMP_ADAPTER pAd
,
6181 ULONG Addr0
= 0x0, Addr1
= 0x0;
6184 DBGPRINT(RT_DEBUG_TRACE
, ("AsicDelWcidTab==>Wcid = 0x%x\n",Wcid
));
6185 offset
= MAC_WCID_BASE
+ Wcid
* HW_WCID_ENTRY_SIZE
;
6186 RTMP_IO_WRITE32(pAd
, offset
, Addr0
);
6188 RTMP_IO_WRITE32(pAd
, offset
, Addr1
);
6192 ==========================================================================
6195 IRQL = DISPATCH_LEVEL
6197 ==========================================================================
6200 IN PRTMP_ADAPTER pAd
)
6202 TX_LINK_CFG_STRUC TxLinkCfg
;
6205 RTMP_IO_READ32(pAd
, TX_LINK_CFG
, &TxLinkCfg
.word
);
6206 TxLinkCfg
.field
.TxRDGEn
= 1;
6207 RTMP_IO_WRITE32(pAd
, TX_LINK_CFG
, TxLinkCfg
.word
);
6209 RTMP_IO_READ32(pAd
, EDCA_AC0_CFG
, &Data
);
6212 RTMP_IO_WRITE32(pAd
, EDCA_AC0_CFG
, Data
);
6214 //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
6218 ==========================================================================
6221 IRQL = DISPATCH_LEVEL
6223 ==========================================================================
6225 VOID
AsicDisableRDG(
6226 IN PRTMP_ADAPTER pAd
)
6228 TX_LINK_CFG_STRUC TxLinkCfg
;
6232 RTMP_IO_READ32(pAd
, TX_LINK_CFG
, &TxLinkCfg
.word
);
6233 TxLinkCfg
.field
.TxRDGEn
= 0;
6234 RTMP_IO_WRITE32(pAd
, TX_LINK_CFG
, TxLinkCfg
.word
);
6236 RTMP_IO_READ32(pAd
, EDCA_AC0_CFG
, &Data
);
6239 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE
)
6240 #ifdef DOT11_N_SUPPORT
6241 && (pAd
->MacTab
.fAnyStationMIMOPSDynamic
== FALSE
)
6242 #endif // DOT11_N_SUPPORT //
6245 // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
6246 if (pAd
->CommonCfg
.bEnableTxBurst
)
6249 RTMP_IO_WRITE32(pAd
, EDCA_AC0_CFG
, Data
);
6253 ==========================================================================
6256 IRQL = PASSIVE_LEVEL
6257 IRQL = DISPATCH_LEVEL
6259 ==========================================================================
6261 VOID
AsicDisableSync(
6262 IN PRTMP_ADAPTER pAd
)
6264 BCN_TIME_CFG_STRUC csr
;
6266 DBGPRINT(RT_DEBUG_TRACE
, ("--->Disable TSF synchronization\n"));
6268 // 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect
6269 // that NIC will never wakes up because TSF stops and no more
6271 pAd
->TbttTickCount
= 0;
6272 RTMP_IO_READ32(pAd
, BCN_TIME_CFG
, &csr
.word
);
6273 csr
.field
.bBeaconGen
= 0;
6274 csr
.field
.bTBTTEnable
= 0;
6275 csr
.field
.TsfSyncMode
= 0;
6276 csr
.field
.bTsfTicking
= 0;
6277 RTMP_IO_WRITE32(pAd
, BCN_TIME_CFG
, csr
.word
);
6282 ==========================================================================
6285 IRQL = DISPATCH_LEVEL
6287 ==========================================================================
6289 VOID
AsicEnableBssSync(
6290 IN PRTMP_ADAPTER pAd
)
6292 BCN_TIME_CFG_STRUC csr
;
6294 DBGPRINT(RT_DEBUG_TRACE
, ("--->AsicEnableBssSync(INFRA mode)\n"));
6296 RTMP_IO_READ32(pAd
, BCN_TIME_CFG
, &csr
.word
);
6298 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
6300 csr
.field
.BeaconInterval
= pAd
->CommonCfg
.BeaconPeriod
<< 4; // ASIC register in units of 1/16 TU
6301 csr
.field
.bTsfTicking
= 1;
6302 csr
.field
.TsfSyncMode
= 1; // sync TSF in INFRASTRUCTURE mode
6303 csr
.field
.bBeaconGen
= 0; // do NOT generate BEACON
6304 csr
.field
.bTBTTEnable
= 1;
6307 RTMP_IO_WRITE32(pAd
, BCN_TIME_CFG
, csr
.word
);
6311 ==========================================================================
6314 BEACON frame in shared memory should be built ok before this routine
6315 can be called. Otherwise, a garbage frame maybe transmitted out every
6318 IRQL = DISPATCH_LEVEL
6320 ==========================================================================
6322 VOID
AsicEnableIbssSync(
6323 IN PRTMP_ADAPTER pAd
)
6325 BCN_TIME_CFG_STRUC csr9
;
6329 DBGPRINT(RT_DEBUG_TRACE
, ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n", pAd
->BeaconTxWI
.MPDUtotalByteCount
));
6331 RTMP_IO_READ32(pAd
, BCN_TIME_CFG
, &csr9
.word
);
6332 csr9
.field
.bBeaconGen
= 0;
6333 csr9
.field
.bTBTTEnable
= 0;
6334 csr9
.field
.bTsfTicking
= 0;
6335 RTMP_IO_WRITE32(pAd
, BCN_TIME_CFG
, csr9
.word
);
6337 // move BEACON TXD and frame content to on-chip memory
6338 ptr
= (PUCHAR
)&pAd
->BeaconTxWI
;
6339 for (i
=0; i
<TXWI_SIZE
; i
+=4) // 16-byte TXWI field
6341 UINT32 longptr
= *ptr
+ (*(ptr
+1)<<8) + (*(ptr
+2)<<16) + (*(ptr
+3)<<24);
6342 RTMP_IO_WRITE32(pAd
, HW_BEACON_BASE0
+ i
, longptr
);
6346 // start right after the 16-byte TXWI field
6347 ptr
= pAd
->BeaconBuf
;
6348 for (i
=0; i
< pAd
->BeaconTxWI
.MPDUtotalByteCount
; i
+=4)
6350 UINT32 longptr
= *ptr
+ (*(ptr
+1)<<8) + (*(ptr
+2)<<16) + (*(ptr
+3)<<24);
6351 RTMP_IO_WRITE32(pAd
, HW_BEACON_BASE0
+ TXWI_SIZE
+ i
, longptr
);
6355 // start sending BEACON
6356 csr9
.field
.BeaconInterval
= pAd
->CommonCfg
.BeaconPeriod
<< 4; // ASIC register in units of 1/16 TU
6357 csr9
.field
.bTsfTicking
= 1;
6358 csr9
.field
.TsfSyncMode
= 2; // sync TSF in IBSS mode
6359 csr9
.field
.bTBTTEnable
= 1;
6360 csr9
.field
.bBeaconGen
= 1;
6361 RTMP_IO_WRITE32(pAd
, BCN_TIME_CFG
, csr9
.word
);
6365 ==========================================================================
6368 IRQL = PASSIVE_LEVEL
6369 IRQL = DISPATCH_LEVEL
6371 ==========================================================================
6373 VOID
AsicSetEdcaParm(
6374 IN PRTMP_ADAPTER pAd
,
6375 IN PEDCA_PARM pEdcaParm
)
6377 EDCA_AC_CFG_STRUC Ac0Cfg
, Ac1Cfg
, Ac2Cfg
, Ac3Cfg
;
6378 AC_TXOP_CSR0_STRUC csr0
;
6379 AC_TXOP_CSR1_STRUC csr1
;
6380 AIFSN_CSR_STRUC AifsnCsr
;
6381 CWMIN_CSR_STRUC CwminCsr
;
6382 CWMAX_CSR_STRUC CwmaxCsr
;
6389 if ((pEdcaParm
== NULL
) || (pEdcaParm
->bValid
== FALSE
))
6391 DBGPRINT(RT_DEBUG_TRACE
,("AsicSetEdcaParm\n"));
6392 OPSTATUS_CLEAR_FLAG(pAd
, fOP_STATUS_WMM_INUSED
);
6393 for (i
=0; i
<MAX_LEN_OF_MAC_TABLE
; i
++)
6395 if (pAd
->MacTab
.Content
[i
].ValidAsCLI
|| pAd
->MacTab
.Content
[i
].ValidAsApCli
)
6396 CLIENT_STATUS_CLEAR_FLAG(&pAd
->MacTab
.Content
[i
], fCLIENT_STATUS_WMM_CAPABLE
);
6399 //========================================================
6400 // MAC Register has a copy .
6401 //========================================================
6402 if( pAd
->CommonCfg
.bEnableTxBurst
)
6404 // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
6405 Ac0Cfg
.field
.AcTxop
= 0x20; // Suggest by John for TxBurst in HT Mode
6408 Ac0Cfg
.field
.AcTxop
= 0; // QID_AC_BE
6409 Ac0Cfg
.field
.Cwmin
= CW_MIN_IN_BITS
;
6410 Ac0Cfg
.field
.Cwmax
= CW_MAX_IN_BITS
;
6411 Ac0Cfg
.field
.Aifsn
= 2;
6412 RTMP_IO_WRITE32(pAd
, EDCA_AC0_CFG
, Ac0Cfg
.word
);
6414 Ac1Cfg
.field
.AcTxop
= 0; // QID_AC_BK
6415 Ac1Cfg
.field
.Cwmin
= CW_MIN_IN_BITS
;
6416 Ac1Cfg
.field
.Cwmax
= CW_MAX_IN_BITS
;
6417 Ac1Cfg
.field
.Aifsn
= 2;
6418 RTMP_IO_WRITE32(pAd
, EDCA_AC1_CFG
, Ac1Cfg
.word
);
6420 if (pAd
->CommonCfg
.PhyMode
== PHY_11B
)
6422 Ac2Cfg
.field
.AcTxop
= 192; // AC_VI: 192*32us ~= 6ms
6423 Ac3Cfg
.field
.AcTxop
= 96; // AC_VO: 96*32us ~= 3ms
6427 Ac2Cfg
.field
.AcTxop
= 96; // AC_VI: 96*32us ~= 3ms
6428 Ac3Cfg
.field
.AcTxop
= 48; // AC_VO: 48*32us ~= 1.5ms
6430 Ac2Cfg
.field
.Cwmin
= CW_MIN_IN_BITS
;
6431 Ac2Cfg
.field
.Cwmax
= CW_MAX_IN_BITS
;
6432 Ac2Cfg
.field
.Aifsn
= 2;
6433 RTMP_IO_WRITE32(pAd
, EDCA_AC2_CFG
, Ac2Cfg
.word
);
6434 Ac3Cfg
.field
.Cwmin
= CW_MIN_IN_BITS
;
6435 Ac3Cfg
.field
.Cwmax
= CW_MAX_IN_BITS
;
6436 Ac3Cfg
.field
.Aifsn
= 2;
6437 RTMP_IO_WRITE32(pAd
, EDCA_AC3_CFG
, Ac3Cfg
.word
);
6439 //========================================================
6440 // DMA Register has a copy too.
6441 //========================================================
6442 csr0
.field
.Ac0Txop
= 0; // QID_AC_BE
6443 csr0
.field
.Ac1Txop
= 0; // QID_AC_BK
6444 RTMP_IO_WRITE32(pAd
, WMM_TXOP0_CFG
, csr0
.word
);
6445 if (pAd
->CommonCfg
.PhyMode
== PHY_11B
)
6447 csr1
.field
.Ac2Txop
= 192; // AC_VI: 192*32us ~= 6ms
6448 csr1
.field
.Ac3Txop
= 96; // AC_VO: 96*32us ~= 3ms
6452 csr1
.field
.Ac2Txop
= 96; // AC_VI: 96*32us ~= 3ms
6453 csr1
.field
.Ac3Txop
= 48; // AC_VO: 48*32us ~= 1.5ms
6455 RTMP_IO_WRITE32(pAd
, WMM_TXOP1_CFG
, csr1
.word
);
6458 CwminCsr
.field
.Cwmin0
= CW_MIN_IN_BITS
;
6459 CwminCsr
.field
.Cwmin1
= CW_MIN_IN_BITS
;
6460 CwminCsr
.field
.Cwmin2
= CW_MIN_IN_BITS
;
6461 CwminCsr
.field
.Cwmin3
= CW_MIN_IN_BITS
;
6462 RTMP_IO_WRITE32(pAd
, WMM_CWMIN_CFG
, CwminCsr
.word
);
6465 CwmaxCsr
.field
.Cwmax0
= CW_MAX_IN_BITS
;
6466 CwmaxCsr
.field
.Cwmax1
= CW_MAX_IN_BITS
;
6467 CwmaxCsr
.field
.Cwmax2
= CW_MAX_IN_BITS
;
6468 CwmaxCsr
.field
.Cwmax3
= CW_MAX_IN_BITS
;
6469 RTMP_IO_WRITE32(pAd
, WMM_CWMAX_CFG
, CwmaxCsr
.word
);
6471 RTMP_IO_WRITE32(pAd
, WMM_AIFSN_CFG
, 0x00002222);
6473 NdisZeroMemory(&pAd
->CommonCfg
.APEdcaParm
, sizeof(EDCA_PARM
));
6477 OPSTATUS_SET_FLAG(pAd
, fOP_STATUS_WMM_INUSED
);
6478 //========================================================
6479 // MAC Register has a copy.
6480 //========================================================
6482 // Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27
6483 // To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue.
6485 //pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this
6487 Ac0Cfg
.field
.AcTxop
= pEdcaParm
->Txop
[QID_AC_BE
];
6488 Ac0Cfg
.field
.Cwmin
= pEdcaParm
->Cwmin
[QID_AC_BE
];
6489 Ac0Cfg
.field
.Cwmax
= pEdcaParm
->Cwmax
[QID_AC_BE
];
6490 Ac0Cfg
.field
.Aifsn
= pEdcaParm
->Aifsn
[QID_AC_BE
]; //+1;
6492 Ac1Cfg
.field
.AcTxop
= pEdcaParm
->Txop
[QID_AC_BK
];
6493 Ac1Cfg
.field
.Cwmin
= pEdcaParm
->Cwmin
[QID_AC_BK
]; //+2;
6494 Ac1Cfg
.field
.Cwmax
= pEdcaParm
->Cwmax
[QID_AC_BK
];
6495 Ac1Cfg
.field
.Aifsn
= pEdcaParm
->Aifsn
[QID_AC_BK
]; //+1;
6497 Ac2Cfg
.field
.AcTxop
= (pEdcaParm
->Txop
[QID_AC_VI
] * 6) / 10;
6498 Ac2Cfg
.field
.Cwmin
= pEdcaParm
->Cwmin
[QID_AC_VI
];
6499 Ac2Cfg
.field
.Cwmax
= pEdcaParm
->Cwmax
[QID_AC_VI
];
6500 Ac2Cfg
.field
.Aifsn
= pEdcaParm
->Aifsn
[QID_AC_VI
];
6502 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
6504 // Tuning for Wi-Fi WMM S06
6505 if (pAd
->CommonCfg
.bWiFiTest
&&
6506 pEdcaParm
->Aifsn
[QID_AC_VI
] == 10)
6507 Ac2Cfg
.field
.Aifsn
-= 1;
6509 // Tuning for TGn Wi-Fi 5.2.32
6510 // STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta
6511 if (STA_TGN_WIFI_ON(pAd
) &&
6512 pEdcaParm
->Aifsn
[QID_AC_VI
] == 10)
6514 Ac0Cfg
.field
.Aifsn
= 3;
6515 Ac2Cfg
.field
.AcTxop
= 5;
6519 Ac3Cfg
.field
.AcTxop
= pEdcaParm
->Txop
[QID_AC_VO
];
6520 Ac3Cfg
.field
.Cwmin
= pEdcaParm
->Cwmin
[QID_AC_VO
];
6521 Ac3Cfg
.field
.Cwmax
= pEdcaParm
->Cwmax
[QID_AC_VO
];
6522 Ac3Cfg
.field
.Aifsn
= pEdcaParm
->Aifsn
[QID_AC_VO
];
6525 if (pAd
->CommonCfg
.bWiFiTest
)
6527 if (Ac3Cfg
.field
.AcTxop
== 102)
6529 Ac0Cfg
.field
.AcTxop
= pEdcaParm
->Txop
[QID_AC_BE
] ? pEdcaParm
->Txop
[QID_AC_BE
] : 10;
6530 Ac0Cfg
.field
.Aifsn
= pEdcaParm
->Aifsn
[QID_AC_BE
]-1; /* AIFSN must >= 1 */
6531 Ac1Cfg
.field
.AcTxop
= pEdcaParm
->Txop
[QID_AC_BK
];
6532 Ac1Cfg
.field
.Aifsn
= pEdcaParm
->Aifsn
[QID_AC_BK
];
6533 Ac2Cfg
.field
.AcTxop
= pEdcaParm
->Txop
[QID_AC_VI
];
6536 //#endif // WIFI_TEST //
6538 RTMP_IO_WRITE32(pAd
, EDCA_AC0_CFG
, Ac0Cfg
.word
);
6539 RTMP_IO_WRITE32(pAd
, EDCA_AC1_CFG
, Ac1Cfg
.word
);
6540 RTMP_IO_WRITE32(pAd
, EDCA_AC2_CFG
, Ac2Cfg
.word
);
6541 RTMP_IO_WRITE32(pAd
, EDCA_AC3_CFG
, Ac3Cfg
.word
);
6544 //========================================================
6545 // DMA Register has a copy too.
6546 //========================================================
6547 csr0
.field
.Ac0Txop
= Ac0Cfg
.field
.AcTxop
;
6548 csr0
.field
.Ac1Txop
= Ac1Cfg
.field
.AcTxop
;
6549 RTMP_IO_WRITE32(pAd
, WMM_TXOP0_CFG
, csr0
.word
);
6551 csr1
.field
.Ac2Txop
= Ac2Cfg
.field
.AcTxop
;
6552 csr1
.field
.Ac3Txop
= Ac3Cfg
.field
.AcTxop
;
6553 RTMP_IO_WRITE32(pAd
, WMM_TXOP1_CFG
, csr1
.word
);
6556 CwminCsr
.field
.Cwmin0
= pEdcaParm
->Cwmin
[QID_AC_BE
];
6557 CwminCsr
.field
.Cwmin1
= pEdcaParm
->Cwmin
[QID_AC_BK
];
6558 CwminCsr
.field
.Cwmin2
= pEdcaParm
->Cwmin
[QID_AC_VI
];
6560 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
6561 CwminCsr
.field
.Cwmin3
= pEdcaParm
->Cwmin
[QID_AC_VO
] - 1; //for TGn wifi test
6563 RTMP_IO_WRITE32(pAd
, WMM_CWMIN_CFG
, CwminCsr
.word
);
6566 CwmaxCsr
.field
.Cwmax0
= pEdcaParm
->Cwmax
[QID_AC_BE
];
6567 CwmaxCsr
.field
.Cwmax1
= pEdcaParm
->Cwmax
[QID_AC_BK
];
6568 CwmaxCsr
.field
.Cwmax2
= pEdcaParm
->Cwmax
[QID_AC_VI
];
6569 CwmaxCsr
.field
.Cwmax3
= pEdcaParm
->Cwmax
[QID_AC_VO
];
6570 RTMP_IO_WRITE32(pAd
, WMM_CWMAX_CFG
, CwmaxCsr
.word
);
6573 AifsnCsr
.field
.Aifsn0
= Ac0Cfg
.field
.Aifsn
; //pEdcaParm->Aifsn[QID_AC_BE];
6574 AifsnCsr
.field
.Aifsn1
= Ac1Cfg
.field
.Aifsn
; //pEdcaParm->Aifsn[QID_AC_BK];
6575 AifsnCsr
.field
.Aifsn2
= Ac2Cfg
.field
.Aifsn
; //pEdcaParm->Aifsn[QID_AC_VI];
6577 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
6579 // Tuning for Wi-Fi WMM S06
6580 if (pAd
->CommonCfg
.bWiFiTest
&&
6581 pEdcaParm
->Aifsn
[QID_AC_VI
] == 10)
6582 AifsnCsr
.field
.Aifsn2
= Ac2Cfg
.field
.Aifsn
- 4;
6584 // Tuning for TGn Wi-Fi 5.2.32
6585 // STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta
6586 if (STA_TGN_WIFI_ON(pAd
) &&
6587 pEdcaParm
->Aifsn
[QID_AC_VI
] == 10)
6589 AifsnCsr
.field
.Aifsn0
= 3;
6590 AifsnCsr
.field
.Aifsn2
= 7;
6594 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
6595 AifsnCsr
.field
.Aifsn3
= Ac3Cfg
.field
.Aifsn
- 1; //pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test
6597 RTMP_IO_WRITE32(pAd
, WMM_AIFSN_CFG
, AifsnCsr
.word
);
6599 NdisMoveMemory(&pAd
->CommonCfg
.APEdcaParm
, pEdcaParm
, sizeof(EDCA_PARM
));
6602 DBGPRINT(RT_DEBUG_TRACE
,("EDCA [#%d]: AIFSN CWmin CWmax TXOP(us) ACM\n", pEdcaParm
->EdcaUpdateCount
));
6603 DBGPRINT(RT_DEBUG_TRACE
,(" AC_BE %2d %2d %2d %4d %d\n",
6604 pEdcaParm
->Aifsn
[0],
6605 pEdcaParm
->Cwmin
[0],
6606 pEdcaParm
->Cwmax
[0],
6607 pEdcaParm
->Txop
[0]<<5,
6608 pEdcaParm
->bACM
[0]));
6609 DBGPRINT(RT_DEBUG_TRACE
,(" AC_BK %2d %2d %2d %4d %d\n",
6610 pEdcaParm
->Aifsn
[1],
6611 pEdcaParm
->Cwmin
[1],
6612 pEdcaParm
->Cwmax
[1],
6613 pEdcaParm
->Txop
[1]<<5,
6614 pEdcaParm
->bACM
[1]));
6615 DBGPRINT(RT_DEBUG_TRACE
,(" AC_VI %2d %2d %2d %4d %d\n",
6616 pEdcaParm
->Aifsn
[2],
6617 pEdcaParm
->Cwmin
[2],
6618 pEdcaParm
->Cwmax
[2],
6619 pEdcaParm
->Txop
[2]<<5,
6620 pEdcaParm
->bACM
[2]));
6621 DBGPRINT(RT_DEBUG_TRACE
,(" AC_VO %2d %2d %2d %4d %d\n",
6622 pEdcaParm
->Aifsn
[3],
6623 pEdcaParm
->Cwmin
[3],
6624 pEdcaParm
->Cwmax
[3],
6625 pEdcaParm
->Txop
[3]<<5,
6626 pEdcaParm
->bACM
[3]));
6632 ==========================================================================
6635 IRQL = PASSIVE_LEVEL
6636 IRQL = DISPATCH_LEVEL
6638 ==========================================================================
6640 VOID
AsicSetSlotTime(
6641 IN PRTMP_ADAPTER pAd
,
6642 IN BOOLEAN bUseShortSlotTime
)
6645 UINT32 RegValue
= 0;
6647 if (pAd
->CommonCfg
.Channel
> 14)
6648 bUseShortSlotTime
= TRUE
;
6650 if (bUseShortSlotTime
)
6651 OPSTATUS_SET_FLAG(pAd
, fOP_STATUS_SHORT_SLOT_INUSED
);
6653 OPSTATUS_CLEAR_FLAG(pAd
, fOP_STATUS_SHORT_SLOT_INUSED
);
6655 SlotTime
= (bUseShortSlotTime
)? 9 : 20;
6657 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
6659 // force using short SLOT time for FAE to demo performance when TxBurst is ON
6660 if (((pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
== FALSE
) && (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_WMM_INUSED
)))
6661 #ifdef DOT11_N_SUPPORT
6662 || ((pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
== TRUE
) && (pAd
->CommonCfg
.BACapability
.field
.Policy
== BA_NOTUSE
))
6663 #endif // DOT11_N_SUPPORT //
6666 // In this case, we will think it is doing Wi-Fi test
6667 // And we will not set to short slot when bEnableTxBurst is TRUE.
6669 else if (pAd
->CommonCfg
.bEnableTxBurst
)
6674 // For some reasons, always set it to short slot time.
6676 // ToDo: Should consider capability with 11B
6678 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
6680 if (pAd
->StaCfg
.BssType
== BSS_ADHOC
)
6684 RTMP_IO_READ32(pAd
, BKOFF_SLOT_CFG
, &RegValue
);
6685 RegValue
= RegValue
& 0xFFFFFF00;
6687 RegValue
|= SlotTime
;
6689 RTMP_IO_WRITE32(pAd
, BKOFF_SLOT_CFG
, RegValue
);
6693 ========================================================================
6695 Add Shared key information into ASIC.
6696 Update shared key, TxMic and RxMic to Asic Shared key table
6697 Update its cipherAlg to Asic Shared key Mode.
6700 ========================================================================
6702 VOID
AsicAddSharedKeyEntry(
6703 IN PRTMP_ADAPTER pAd
,
6711 ULONG offset
; //, csr0;
6712 SHAREDKEY_MODE_STRUC csr1
;
6715 DBGPRINT(RT_DEBUG_TRACE
, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex
,KeyIdx
));
6716 //============================================================================================
6718 DBGPRINT(RT_DEBUG_TRACE
,("AsicAddSharedKeyEntry: %s key #%d\n", CipherName
[CipherAlg
], BssIndex
*4 + KeyIdx
));
6719 DBGPRINT_RAW(RT_DEBUG_TRACE
, (" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
6720 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]));
6723 DBGPRINT_RAW(RT_DEBUG_TRACE
, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
6724 pRxMic
[0],pRxMic
[1],pRxMic
[2],pRxMic
[3],pRxMic
[4],pRxMic
[5],pRxMic
[6],pRxMic
[7]));
6728 DBGPRINT_RAW(RT_DEBUG_TRACE
, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
6729 pTxMic
[0],pTxMic
[1],pTxMic
[2],pTxMic
[3],pTxMic
[4],pTxMic
[5],pTxMic
[6],pTxMic
[7]));
6731 //============================================================================================
6733 // fill key material - key + TX MIC + RX MIC
6735 offset
= SHARED_KEY_TABLE_BASE
+ (4*BssIndex
+ KeyIdx
)*HW_KEY_ENTRY_SIZE
;
6736 for (i
=0; i
<MAX_LEN_OF_SHARE_KEY
; i
++)
6738 RTMP_IO_WRITE8(pAd
, offset
+ i
, pKey
[i
]);
6741 offset
+= MAX_LEN_OF_SHARE_KEY
;
6746 RTMP_IO_WRITE8(pAd
, offset
+ i
, pTxMic
[i
]);
6755 RTMP_IO_WRITE8(pAd
, offset
+ i
, pRxMic
[i
]);
6761 // Update cipher algorithm. WSTA always use BSS0
6763 RTMP_IO_READ32(pAd
, SHARED_KEY_MODE_BASE
+4*(BssIndex
/2), &csr1
.word
);
6764 DBGPRINT(RT_DEBUG_TRACE
,("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n", BssIndex
,KeyIdx
, csr1
.word
));
6765 if ((BssIndex
%2) == 0)
6768 csr1
.field
.Bss0Key0CipherAlg
= CipherAlg
;
6769 else if (KeyIdx
== 1)
6770 csr1
.field
.Bss0Key1CipherAlg
= CipherAlg
;
6771 else if (KeyIdx
== 2)
6772 csr1
.field
.Bss0Key2CipherAlg
= CipherAlg
;
6774 csr1
.field
.Bss0Key3CipherAlg
= CipherAlg
;
6779 csr1
.field
.Bss1Key0CipherAlg
= CipherAlg
;
6780 else if (KeyIdx
== 1)
6781 csr1
.field
.Bss1Key1CipherAlg
= CipherAlg
;
6782 else if (KeyIdx
== 2)
6783 csr1
.field
.Bss1Key2CipherAlg
= CipherAlg
;
6785 csr1
.field
.Bss1Key3CipherAlg
= CipherAlg
;
6787 DBGPRINT(RT_DEBUG_TRACE
,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex
, csr1
.word
));
6788 RTMP_IO_WRITE32(pAd
, SHARED_KEY_MODE_BASE
+4*(BssIndex
/2), csr1
.word
);
6792 // IRQL = DISPATCH_LEVEL
6793 VOID
AsicRemoveSharedKeyEntry(
6794 IN PRTMP_ADAPTER pAd
,
6799 SHAREDKEY_MODE_STRUC csr1
;
6801 DBGPRINT(RT_DEBUG_TRACE
,("AsicRemoveSharedKeyEntry: #%d \n", BssIndex
*4 + KeyIdx
));
6803 RTMP_IO_READ32(pAd
, SHARED_KEY_MODE_BASE
+4*(BssIndex
/2), &csr1
.word
);
6804 if ((BssIndex
%2) == 0)
6807 csr1
.field
.Bss0Key0CipherAlg
= 0;
6808 else if (KeyIdx
== 1)
6809 csr1
.field
.Bss0Key1CipherAlg
= 0;
6810 else if (KeyIdx
== 2)
6811 csr1
.field
.Bss0Key2CipherAlg
= 0;
6813 csr1
.field
.Bss0Key3CipherAlg
= 0;
6818 csr1
.field
.Bss1Key0CipherAlg
= 0;
6819 else if (KeyIdx
== 1)
6820 csr1
.field
.Bss1Key1CipherAlg
= 0;
6821 else if (KeyIdx
== 2)
6822 csr1
.field
.Bss1Key2CipherAlg
= 0;
6824 csr1
.field
.Bss1Key3CipherAlg
= 0;
6826 DBGPRINT(RT_DEBUG_TRACE
,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex
, csr1
.word
));
6827 RTMP_IO_WRITE32(pAd
, SHARED_KEY_MODE_BASE
+4*(BssIndex
/2), csr1
.word
);
6828 ASSERT(BssIndex
< 4);
6834 VOID
AsicUpdateWCIDAttribute(
6835 IN PRTMP_ADAPTER pAd
,
6839 IN BOOLEAN bUsePairewiseKeyTable
)
6841 ULONG WCIDAttri
= 0, offset
;
6844 // Update WCID attribute.
6845 // Only TxKey could update WCID attribute.
6847 offset
= MAC_WCID_ATTRIBUTE_BASE
+ (WCID
* HW_WCID_ATTRI_SIZE
);
6848 WCIDAttri
= (BssIndex
<< 4) | (CipherAlg
<< 1) | (bUsePairewiseKeyTable
);
6849 RTMP_IO_WRITE32(pAd
, offset
, WCIDAttri
);
6852 VOID
AsicUpdateWCIDIVEIV(
6853 IN PRTMP_ADAPTER pAd
,
6860 offset
= MAC_IVEIV_TABLE_BASE
+ (WCID
* HW_IVEIV_ENTRY_SIZE
);
6862 RTMP_IO_WRITE32(pAd
, offset
, uIV
);
6863 RTMP_IO_WRITE32(pAd
, offset
+ 4, uEIV
);
6866 VOID
AsicUpdateRxWCIDTable(
6867 IN PRTMP_ADAPTER pAd
,
6874 offset
= MAC_WCID_BASE
+ (WCID
* HW_WCID_ENTRY_SIZE
);
6875 Addr
= pAddr
[0] + (pAddr
[1] << 8) +(pAddr
[2] << 16) +(pAddr
[3] << 24);
6876 RTMP_IO_WRITE32(pAd
, offset
, Addr
);
6877 Addr
= pAddr
[4] + (pAddr
[5] << 8);
6878 RTMP_IO_WRITE32(pAd
, offset
+ 4, Addr
);
6883 ========================================================================
6885 Routine Description:
6886 Set Cipher Key, Cipher algorithm, IV/EIV to Asic
6889 pAd Pointer to our adapter
6890 WCID WCID Entry number.
6891 BssIndex BSSID index, station or none multiple BSSID support
6892 this value should be 0.
6893 KeyIdx This KeyIdx will set to IV's KeyID if bTxKey enabled
6894 pCipherKey Pointer to Cipher Key.
6895 bUsePairewiseKeyTable TRUE means saved the key in SharedKey table,
6896 otherwise PairewiseKey table
6897 bTxKey This is the transmit key if enabled.
6903 This routine will set the relative key stuff to Asic including WCID attribute,
6904 Cipher Key, Cipher algorithm and IV/EIV.
6906 IV/EIV will be update if this CipherKey is the transmission key because
6907 ASIC will base on IV's KeyID value to select Cipher Key.
6909 If bTxKey sets to FALSE, this is not the TX key, but it could be
6912 For AP mode bTxKey must be always set to TRUE.
6913 ========================================================================
6915 VOID
AsicAddKeyEntry(
6916 IN PRTMP_ADAPTER pAd
,
6920 IN PCIPHER_KEY pCipherKey
,
6921 IN BOOLEAN bUsePairewiseKeyTable
,
6926 PUCHAR pKey
= pCipherKey
->Key
;
6927 PUCHAR pTxMic
= pCipherKey
->TxMic
;
6928 PUCHAR pRxMic
= pCipherKey
->RxMic
;
6929 PUCHAR pTxtsc
= pCipherKey
->TxTsc
;
6930 UCHAR CipherAlg
= pCipherKey
->CipherAlg
;
6931 SHAREDKEY_MODE_STRUC csr1
;
6934 DBGPRINT(RT_DEBUG_TRACE
, ("==> AsicAddKeyEntry\n"));
6936 // 1.) decide key table offset
6938 if (bUsePairewiseKeyTable
)
6939 offset
= PAIRWISE_KEY_TABLE_BASE
+ (WCID
* HW_KEY_ENTRY_SIZE
);
6941 offset
= SHARED_KEY_TABLE_BASE
+ (4 * BssIndex
+ KeyIdx
) * HW_KEY_ENTRY_SIZE
;
6944 // 2.) Set Key to Asic
6946 //for (i = 0; i < KeyLen; i++)
6947 for (i
= 0; i
< MAX_LEN_OF_PEER_KEY
; i
++)
6949 RTMP_IO_WRITE8(pAd
, offset
+ i
, pKey
[i
]);
6951 offset
+= MAX_LEN_OF_PEER_KEY
;
6954 // 3.) Set MIC key if available
6958 for (i
= 0; i
< 8; i
++)
6960 RTMP_IO_WRITE8(pAd
, offset
+ i
, pTxMic
[i
]);
6963 offset
+= LEN_TKIP_TXMICK
;
6967 for (i
= 0; i
< 8; i
++)
6969 RTMP_IO_WRITE8(pAd
, offset
+ i
, pRxMic
[i
]);
6975 // 4.) Modify IV/EIV if needs
6976 // This will force Asic to use this key ID by setting IV.
6980 offset
= MAC_IVEIV_TABLE_BASE
+ (WCID
* HW_IVEIV_ENTRY_SIZE
);
6984 RTMP_IO_WRITE8(pAd
, offset
, pTxtsc
[1]);
6985 RTMP_IO_WRITE8(pAd
, offset
+ 1, ((pTxtsc
[1] | 0x20) & 0x7f));
6986 RTMP_IO_WRITE8(pAd
, offset
+ 2, pTxtsc
[0]);
6988 IV4
= (KeyIdx
<< 6);
6989 if ((CipherAlg
== CIPHER_TKIP
) || (CipherAlg
== CIPHER_TKIP_NO_MIC
) ||(CipherAlg
== CIPHER_AES
))
6990 IV4
|= 0x20; // turn on extension bit means EIV existence
6992 RTMP_IO_WRITE8(pAd
, offset
+ 3, IV4
);
6998 for (i
= 0; i
< 4; i
++)
7000 RTMP_IO_WRITE8(pAd
, offset
+ i
, pTxtsc
[i
+ 2]);
7003 AsicUpdateWCIDAttribute(pAd
, WCID
, BssIndex
, CipherAlg
, bUsePairewiseKeyTable
);
7006 if (!bUsePairewiseKeyTable
)
7009 // Only update the shared key security mode
7011 RTMP_IO_READ32(pAd
, SHARED_KEY_MODE_BASE
+ 4 * (BssIndex
/ 2), &csr1
.word
);
7012 if ((BssIndex
% 2) == 0)
7015 csr1
.field
.Bss0Key0CipherAlg
= CipherAlg
;
7016 else if (KeyIdx
== 1)
7017 csr1
.field
.Bss0Key1CipherAlg
= CipherAlg
;
7018 else if (KeyIdx
== 2)
7019 csr1
.field
.Bss0Key2CipherAlg
= CipherAlg
;
7021 csr1
.field
.Bss0Key3CipherAlg
= CipherAlg
;
7026 csr1
.field
.Bss1Key0CipherAlg
= CipherAlg
;
7027 else if (KeyIdx
== 1)
7028 csr1
.field
.Bss1Key1CipherAlg
= CipherAlg
;
7029 else if (KeyIdx
== 2)
7030 csr1
.field
.Bss1Key2CipherAlg
= CipherAlg
;
7032 csr1
.field
.Bss1Key3CipherAlg
= CipherAlg
;
7034 RTMP_IO_WRITE32(pAd
, SHARED_KEY_MODE_BASE
+ 4 * (BssIndex
/ 2), csr1
.word
);
7037 DBGPRINT(RT_DEBUG_TRACE
, ("<== AsicAddKeyEntry\n"));
7042 ========================================================================
7044 Add Pair-wise key material into ASIC.
7045 Update pairwise key, TxMic and RxMic to Asic Pair-wise key table
7048 ========================================================================
7050 VOID
AsicAddPairwiseKeyEntry(
7051 IN PRTMP_ADAPTER pAd
,
7054 IN CIPHER_KEY
*pCipherKey
)
7058 PUCHAR pKey
= pCipherKey
->Key
;
7059 PUCHAR pTxMic
= pCipherKey
->TxMic
;
7060 PUCHAR pRxMic
= pCipherKey
->RxMic
;
7062 UCHAR CipherAlg
= pCipherKey
->CipherAlg
;
7066 offset
= PAIRWISE_KEY_TABLE_BASE
+ (WCID
* HW_KEY_ENTRY_SIZE
);
7067 for (i
=0; i
<MAX_LEN_OF_PEER_KEY
; i
++)
7069 RTMP_IO_WRITE8(pAd
, offset
+ i
, pKey
[i
]);
7071 for (i
=0; i
<MAX_LEN_OF_PEER_KEY
; i
+=4)
7074 RTMP_IO_READ32(pAd
, offset
+ i
, &Value
);
7077 offset
+= MAX_LEN_OF_PEER_KEY
;
7084 RTMP_IO_WRITE8(pAd
, offset
+i
, pTxMic
[i
]);
7092 RTMP_IO_WRITE8(pAd
, offset
+i
, pRxMic
[i
]);
7096 DBGPRINT(RT_DEBUG_TRACE
,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID
, CipherName
[CipherAlg
]));
7097 DBGPRINT(RT_DEBUG_TRACE
,(" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7098 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]));
7101 DBGPRINT(RT_DEBUG_TRACE
, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7102 pRxMic
[0],pRxMic
[1],pRxMic
[2],pRxMic
[3],pRxMic
[4],pRxMic
[5],pRxMic
[6],pRxMic
[7]));
7106 DBGPRINT(RT_DEBUG_TRACE
, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7107 pTxMic
[0],pTxMic
[1],pTxMic
[2],pTxMic
[3],pTxMic
[4],pTxMic
[5],pTxMic
[6],pTxMic
[7]));
7111 ========================================================================
7113 Remove Pair-wise key material from ASIC.
7116 ========================================================================
7118 VOID
AsicRemovePairwiseKeyEntry(
7119 IN PRTMP_ADAPTER pAd
,
7126 // re-set the entry's WCID attribute as OPEN-NONE.
7127 offset
= MAC_WCID_ATTRIBUTE_BASE
+ (Wcid
* HW_WCID_ATTRI_SIZE
);
7128 WCIDAttri
= (BssIdx
<<4) | PAIRWISEKEYTABLE
;
7129 RTMP_IO_WRITE32(pAd
, offset
, WCIDAttri
);
7132 BOOLEAN
AsicSendCommandToMcu(
7133 IN PRTMP_ADAPTER pAd
,
7139 HOST_CMD_CSR_STRUC H2MCmd
;
7140 H2M_MAILBOX_STRUC H2MMailbox
;
7145 RTMP_IO_READ32(pAd
, H2M_MAILBOX_CSR
, &H2MMailbox
.word
);
7146 if (H2MMailbox
.field
.Owner
== 0)
7158 RTMP_IO_READ32(pAd
, PBF_SYS_CTRL
, &Data
);
7160 RTMP_IO_WRITE32(pAd
, PBF_SYS_CTRL
, Data
);
7162 // After Reset DMA, DMA index will become Zero. So Driver need to reset all ring indexs too.
7163 // Reset DMA/CPU ring index
7164 RTMPRingCleanUp(pAd
, QID_AC_BK
);
7165 RTMPRingCleanUp(pAd
, QID_AC_BE
);
7166 RTMPRingCleanUp(pAd
, QID_AC_VI
);
7167 RTMPRingCleanUp(pAd
, QID_AC_VO
);
7168 RTMPRingCleanUp(pAd
, QID_HCCA
);
7169 RTMPRingCleanUp(pAd
, QID_MGMT
);
7170 RTMPRingCleanUp(pAd
, QID_RX
);
7173 RTMP_IO_READ32(pAd
, PBF_SYS_CTRL
, &Data
);
7175 RTMP_IO_WRITE32(pAd
, PBF_SYS_CTRL
, Data
);
7176 DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
7181 H2MMailbox
.field
.Owner
= 1; // pass ownership to MCU
7182 H2MMailbox
.field
.CmdToken
= Token
;
7183 H2MMailbox
.field
.HighByte
= Arg1
;
7184 H2MMailbox
.field
.LowByte
= Arg0
;
7185 RTMP_IO_WRITE32(pAd
, H2M_MAILBOX_CSR
, H2MMailbox
.word
);
7188 H2MCmd
.field
.HostCommand
= Command
;
7189 RTMP_IO_WRITE32(pAd
, HOST_CMD_CSR
, H2MCmd
.word
);
7191 if (Command
!= 0x80)
7198 BOOLEAN
AsicCheckCommanOk(
7199 IN PRTMP_ADAPTER pAd
,
7202 UINT32 CmdStatus
= 0, CID
= 0, i
;
7203 UINT32 ThisCIDMask
= 0;
7208 RTMP_IO_READ32(pAd
, H2M_MAILBOX_CID
, &CID
);
7209 // Find where the command is. Because this is randomly specified by firmware.
7210 if ((CID
& CID0MASK
) == Command
)
7212 ThisCIDMask
= CID0MASK
;
7215 else if ((((CID
& CID1MASK
)>>8) & 0xff) == Command
)
7217 ThisCIDMask
= CID1MASK
;
7220 else if ((((CID
& CID2MASK
)>>16) & 0xff) == Command
)
7222 ThisCIDMask
= CID2MASK
;
7225 else if ((((CID
& CID3MASK
)>>24) & 0xff) == Command
)
7227 ThisCIDMask
= CID3MASK
;
7235 // Get CommandStatus Value
7236 RTMP_IO_READ32(pAd
, H2M_MAILBOX_STATUS
, &CmdStatus
);
7238 // This command's status is at the same position as command. So AND command position's bitmask to read status.
7241 // If Status is 1, the comamnd is success.
7242 if (((CmdStatus
& ThisCIDMask
) == 0x1) || ((CmdStatus
& ThisCIDMask
) == 0x100)
7243 || ((CmdStatus
& ThisCIDMask
) == 0x10000) || ((CmdStatus
& ThisCIDMask
) == 0x1000000))
7245 DBGPRINT(RT_DEBUG_TRACE
, ("--> AsicCheckCommanOk CID = 0x%x, CmdStatus= 0x%x \n", CID
, CmdStatus
));
7246 RTMP_IO_WRITE32(pAd
, H2M_MAILBOX_STATUS
, 0xffffffff);
7247 RTMP_IO_WRITE32(pAd
, H2M_MAILBOX_CID
, 0xffffffff);
7250 DBGPRINT(RT_DEBUG_TRACE
, ("--> AsicCheckCommanFail1 CID = 0x%x, CmdStatus= 0x%x \n", CID
, CmdStatus
));
7254 DBGPRINT(RT_DEBUG_TRACE
, ("--> AsicCheckCommanFail2 Timeout Command = %d, CmdStatus= 0x%x \n", Command
, CmdStatus
));
7256 // Clear Command and Status.
7257 RTMP_IO_WRITE32(pAd
, H2M_MAILBOX_STATUS
, 0xffffffff);
7258 RTMP_IO_WRITE32(pAd
, H2M_MAILBOX_CID
, 0xffffffff);
7264 ========================================================================
7266 Routine Description:
7267 Verify the support rate for different PHY type
7270 pAd Pointer to our adapter
7275 IRQL = PASSIVE_LEVEL
7277 ========================================================================
7279 VOID
RTMPCheckRates(
7280 IN PRTMP_ADAPTER pAd
,
7281 IN OUT UCHAR SupRate
[],
7282 IN OUT UCHAR
*SupRateLen
)
7284 UCHAR RateIdx
, i
, j
;
7285 UCHAR NewRate
[12], NewRateLen
;
7289 if (pAd
->CommonCfg
.PhyMode
== PHY_11B
)
7294 // Check for support rates exclude basic rate bit
7295 for (i
= 0; i
< *SupRateLen
; i
++)
7296 for (j
= 0; j
< RateIdx
; j
++)
7297 if ((SupRate
[i
] & 0x7f) == RateIdTo500Kbps
[j
])
7298 NewRate
[NewRateLen
++] = SupRate
[i
];
7300 *SupRateLen
= NewRateLen
;
7301 NdisMoveMemory(SupRate
, NewRate
, NewRateLen
);
7304 #ifdef DOT11_N_SUPPORT
7305 BOOLEAN
RTMPCheckChannel(
7306 IN PRTMP_ADAPTER pAd
,
7307 IN UCHAR CentralChannel
,
7311 UCHAR UpperChannel
= 0, LowerChannel
= 0;
7312 UCHAR NoEffectChannelinList
= 0;
7314 // Find upper and lower channel according to 40MHz current operation.
7315 if (CentralChannel
< Channel
)
7317 UpperChannel
= Channel
;
7318 if (CentralChannel
> 2)
7319 LowerChannel
= CentralChannel
- 2;
7323 else if (CentralChannel
> Channel
)
7325 UpperChannel
= CentralChannel
+ 2;
7326 LowerChannel
= Channel
;
7329 for (k
= 0;k
< pAd
->ChannelListNum
;k
++)
7331 if (pAd
->ChannelList
[k
].Channel
== UpperChannel
)
7333 NoEffectChannelinList
++;
7335 if (pAd
->ChannelList
[k
].Channel
== LowerChannel
)
7337 NoEffectChannelinList
++;
7341 DBGPRINT(RT_DEBUG_TRACE
,("Total Channel in Channel List = [%d]\n", NoEffectChannelinList
));
7342 if (NoEffectChannelinList
== 2)
7349 ========================================================================
7351 Routine Description:
7352 Verify the support rate for HT phy type
7355 pAd Pointer to our adapter
7358 FALSE if pAd->CommonCfg.SupportedHtPhy doesn't accept the pHtCapability. (AP Mode)
7360 IRQL = PASSIVE_LEVEL
7362 ========================================================================
7364 BOOLEAN
RTMPCheckHt(
7365 IN PRTMP_ADAPTER pAd
,
7367 IN HT_CAPABILITY_IE
*pHtCapability
,
7368 IN ADD_HT_INFO_IE
*pAddHtInfo
)
7370 if (Wcid
>= MAX_LEN_OF_MAC_TABLE
)
7373 // If use AMSDU, set flag.
7374 if (pAd
->CommonCfg
.DesiredHtPhy
.AmsduEnable
)
7375 CLIENT_STATUS_SET_FLAG(&pAd
->MacTab
.Content
[Wcid
], fCLIENT_STATUS_AMSDU_INUSED
);
7376 // Save Peer Capability
7377 if (pHtCapability
->HtCapInfo
.ShortGIfor20
)
7378 CLIENT_STATUS_SET_FLAG(&pAd
->MacTab
.Content
[Wcid
], fCLIENT_STATUS_SGI20_CAPABLE
);
7379 if (pHtCapability
->HtCapInfo
.ShortGIfor40
)
7380 CLIENT_STATUS_SET_FLAG(&pAd
->MacTab
.Content
[Wcid
], fCLIENT_STATUS_SGI40_CAPABLE
);
7381 if (pHtCapability
->HtCapInfo
.TxSTBC
)
7382 CLIENT_STATUS_SET_FLAG(&pAd
->MacTab
.Content
[Wcid
], fCLIENT_STATUS_TxSTBC_CAPABLE
);
7383 if (pHtCapability
->HtCapInfo
.RxSTBC
)
7384 CLIENT_STATUS_SET_FLAG(&pAd
->MacTab
.Content
[Wcid
], fCLIENT_STATUS_RxSTBC_CAPABLE
);
7385 if (pAd
->CommonCfg
.bRdg
&& pHtCapability
->ExtHtCapInfo
.RDGSupport
)
7387 CLIENT_STATUS_SET_FLAG(&pAd
->MacTab
.Content
[Wcid
], fCLIENT_STATUS_RDG_CAPABLE
);
7390 if (Wcid
< MAX_LEN_OF_MAC_TABLE
)
7392 pAd
->MacTab
.Content
[Wcid
].MpduDensity
= pHtCapability
->HtCapParm
.MpduDensity
;
7395 // Will check ChannelWidth for MCSSet[4] below
7396 pAd
->MlmeAux
.HtCapability
.MCSSet
[4] = 0x1;
7397 switch (pAd
->CommonCfg
.RxStream
)
7400 pAd
->MlmeAux
.HtCapability
.MCSSet
[0] = 0xff;
7401 pAd
->MlmeAux
.HtCapability
.MCSSet
[1] = 0x00;
7402 pAd
->MlmeAux
.HtCapability
.MCSSet
[2] = 0x00;
7403 pAd
->MlmeAux
.HtCapability
.MCSSet
[3] = 0x00;
7406 pAd
->MlmeAux
.HtCapability
.MCSSet
[0] = 0xff;
7407 pAd
->MlmeAux
.HtCapability
.MCSSet
[1] = 0xff;
7408 pAd
->MlmeAux
.HtCapability
.MCSSet
[2] = 0x00;
7409 pAd
->MlmeAux
.HtCapability
.MCSSet
[3] = 0x00;
7412 pAd
->MlmeAux
.HtCapability
.MCSSet
[0] = 0xff;
7413 pAd
->MlmeAux
.HtCapability
.MCSSet
[1] = 0xff;
7414 pAd
->MlmeAux
.HtCapability
.MCSSet
[2] = 0xff;
7415 pAd
->MlmeAux
.HtCapability
.MCSSet
[3] = 0x00;
7419 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.ChannelWidth
= pAddHtInfo
->AddHtInfo
.RecomWidth
& pAd
->CommonCfg
.DesiredHtPhy
.ChannelWidth
;
7421 DBGPRINT(RT_DEBUG_TRACE
, ("RTMPCheckHt:: HtCapInfo.ChannelWidth=%d, RecomWidth=%d, DesiredHtPhy.ChannelWidth=%d, BW40MAvailForA/G=%d/%d, PhyMode=%d \n",
7422 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.ChannelWidth
, pAddHtInfo
->AddHtInfo
.RecomWidth
, pAd
->CommonCfg
.DesiredHtPhy
.ChannelWidth
,
7423 pAd
->NicConfig2
.field
.BW40MAvailForA
, pAd
->NicConfig2
.field
.BW40MAvailForG
, pAd
->CommonCfg
.PhyMode
));
7425 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.GF
= pHtCapability
->HtCapInfo
.GF
&pAd
->CommonCfg
.DesiredHtPhy
.GF
;
7427 // Send Assoc Req with my HT capability.
7428 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.AMsduSize
= pAd
->CommonCfg
.DesiredHtPhy
.AmsduSize
;
7429 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.MimoPs
= pAd
->CommonCfg
.DesiredHtPhy
.MimoPs
;
7430 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.ShortGIfor20
= (pAd
->CommonCfg
.DesiredHtPhy
.ShortGIfor20
) & (pHtCapability
->HtCapInfo
.ShortGIfor20
);
7431 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.ShortGIfor40
= (pAd
->CommonCfg
.DesiredHtPhy
.ShortGIfor40
) & (pHtCapability
->HtCapInfo
.ShortGIfor40
);
7432 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.TxSTBC
= (pAd
->CommonCfg
.DesiredHtPhy
.TxSTBC
)&(pHtCapability
->HtCapInfo
.RxSTBC
);
7433 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.RxSTBC
= (pAd
->CommonCfg
.DesiredHtPhy
.RxSTBC
)&(pHtCapability
->HtCapInfo
.TxSTBC
);
7434 pAd
->MlmeAux
.HtCapability
.HtCapParm
.MaxRAmpduFactor
= pAd
->CommonCfg
.DesiredHtPhy
.MaxRAmpduFactor
;
7435 pAd
->MlmeAux
.HtCapability
.HtCapParm
.MpduDensity
= pAd
->CommonCfg
.HtCapability
.HtCapParm
.MpduDensity
;
7436 pAd
->MlmeAux
.HtCapability
.ExtHtCapInfo
.PlusHTC
= pHtCapability
->ExtHtCapInfo
.PlusHTC
;
7437 pAd
->MacTab
.Content
[Wcid
].HTCapability
.ExtHtCapInfo
.PlusHTC
= pHtCapability
->ExtHtCapInfo
.PlusHTC
;
7438 if (pAd
->CommonCfg
.bRdg
)
7440 pAd
->MlmeAux
.HtCapability
.ExtHtCapInfo
.RDGSupport
= pHtCapability
->ExtHtCapInfo
.RDGSupport
;
7441 pAd
->MlmeAux
.HtCapability
.ExtHtCapInfo
.PlusHTC
= 1;
7444 if (pAd
->MlmeAux
.HtCapability
.HtCapInfo
.ChannelWidth
== BW_20
)
7445 pAd
->MlmeAux
.HtCapability
.MCSSet
[4] = 0x0; // BW20 can't transmit MCS32
7447 COPY_AP_HTSETTINGS_FROM_BEACON(pAd
, pHtCapability
);
7450 #endif // DOT11_N_SUPPORT //
7453 ========================================================================
7455 Routine Description:
7456 Verify the support rate for different PHY type
7459 pAd Pointer to our adapter
7464 IRQL = PASSIVE_LEVEL
7466 ========================================================================
7468 VOID
RTMPUpdateMlmeRate(
7469 IN PRTMP_ADAPTER pAd
)
7472 UCHAR ProperMlmeRate
; //= RATE_54;
7473 UCHAR i
, j
, RateIdx
= 12; //1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
7474 BOOLEAN bMatch
= FALSE
;
7476 switch (pAd
->CommonCfg
.PhyMode
)
7479 ProperMlmeRate
= RATE_11
;
7480 MinimumRate
= RATE_1
;
7482 case PHY_11BG_MIXED
:
7483 #ifdef DOT11_N_SUPPORT
7484 case PHY_11ABGN_MIXED
:
7485 case PHY_11BGN_MIXED
:
7486 #endif // DOT11_N_SUPPORT //
7487 if ((pAd
->MlmeAux
.SupRateLen
== 4) &&
7488 (pAd
->MlmeAux
.ExtRateLen
== 0))
7490 ProperMlmeRate
= RATE_11
;
7492 ProperMlmeRate
= RATE_24
;
7494 if (pAd
->MlmeAux
.Channel
<= 14)
7495 MinimumRate
= RATE_1
;
7497 MinimumRate
= RATE_6
;
7500 #ifdef DOT11_N_SUPPORT
7501 case PHY_11N_2_4G
: // rt2860 need to check mlmerate for 802.11n
7502 case PHY_11GN_MIXED
:
7503 case PHY_11AGN_MIXED
:
7504 case PHY_11AN_MIXED
:
7506 #endif // DOT11_N_SUPPORT //
7507 ProperMlmeRate
= RATE_24
;
7508 MinimumRate
= RATE_6
;
7510 case PHY_11ABG_MIXED
:
7511 ProperMlmeRate
= RATE_24
;
7512 if (pAd
->MlmeAux
.Channel
<= 14)
7513 MinimumRate
= RATE_1
;
7515 MinimumRate
= RATE_6
;
7518 ProperMlmeRate
= RATE_1
;
7519 MinimumRate
= RATE_1
;
7523 for (i
= 0; i
< pAd
->MlmeAux
.SupRateLen
; i
++)
7525 for (j
= 0; j
< RateIdx
; j
++)
7527 if ((pAd
->MlmeAux
.SupRate
[i
] & 0x7f) == RateIdTo500Kbps
[j
])
7529 if (j
== ProperMlmeRate
)
7541 if (bMatch
== FALSE
)
7543 for (i
= 0; i
< pAd
->MlmeAux
.ExtRateLen
; i
++)
7545 for (j
= 0; j
< RateIdx
; j
++)
7547 if ((pAd
->MlmeAux
.ExtRate
[i
] & 0x7f) == RateIdTo500Kbps
[j
])
7549 if (j
== ProperMlmeRate
)
7562 if (bMatch
== FALSE
)
7564 ProperMlmeRate
= MinimumRate
;
7567 pAd
->CommonCfg
.MlmeRate
= MinimumRate
;
7568 pAd
->CommonCfg
.RtsRate
= ProperMlmeRate
;
7569 if (pAd
->CommonCfg
.MlmeRate
>= RATE_6
)
7571 pAd
->CommonCfg
.MlmeTransmit
.field
.MODE
= MODE_OFDM
;
7572 pAd
->CommonCfg
.MlmeTransmit
.field
.MCS
= OfdmRateToRxwiMCS
[pAd
->CommonCfg
.MlmeRate
];
7573 pAd
->MacTab
.Content
[BSS0Mcast_WCID
].HTPhyMode
.field
.MODE
= MODE_OFDM
;
7574 pAd
->MacTab
.Content
[BSS0Mcast_WCID
].HTPhyMode
.field
.MCS
= OfdmRateToRxwiMCS
[pAd
->CommonCfg
.MlmeRate
];
7578 pAd
->CommonCfg
.MlmeTransmit
.field
.MODE
= MODE_CCK
;
7579 pAd
->CommonCfg
.MlmeTransmit
.field
.MCS
= pAd
->CommonCfg
.MlmeRate
;
7580 pAd
->MacTab
.Content
[BSS0Mcast_WCID
].HTPhyMode
.field
.MODE
= MODE_CCK
;
7581 pAd
->MacTab
.Content
[BSS0Mcast_WCID
].HTPhyMode
.field
.MCS
= pAd
->CommonCfg
.MlmeRate
;
7584 DBGPRINT(RT_DEBUG_TRACE
, ("RTMPUpdateMlmeRate ==> MlmeTransmit = 0x%x \n" , pAd
->CommonCfg
.MlmeTransmit
.word
));
7588 IN PRTMP_ADAPTER pAd
,
7595 if ((pAd
->Antenna
.field
.RxPath
== 1) && (Rssi0
!= 0))
7600 if ((pAd
->Antenna
.field
.RxPath
>= 2) && (Rssi1
!= 0))
7602 larger
= max(Rssi0
, Rssi1
);
7605 if ((pAd
->Antenna
.field
.RxPath
== 3) && (Rssi2
!= 0))
7607 larger
= max(larger
, Rssi2
);
7617 ========================================================================
7618 Routine Description:
7619 Periodic evaluate antenna link status
7622 pAd - Adapter pointer
7627 ========================================================================
7629 VOID
AsicEvaluateRxAnt(
7630 IN PRTMP_ADAPTER pAd
)
7634 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
7636 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_RESET_IN_PROGRESS
|
7637 fRTMP_ADAPTER_HALT_IN_PROGRESS
|
7638 fRTMP_ADAPTER_RADIO_OFF
|
7639 fRTMP_ADAPTER_NIC_NOT_EXIST
|
7640 fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS
))
7643 if (pAd
->StaCfg
.Psm
== PWR_SAVE
)
7647 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R3
, &BBPR3
);
7649 if(pAd
->Antenna
.field
.RxPath
== 3)
7653 else if(pAd
->Antenna
.field
.RxPath
== 2)
7657 else if(pAd
->Antenna
.field
.RxPath
== 1)
7661 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R3
, BBPR3
);
7663 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
7664 pAd
->StaCfg
.BBPR3
= BBPR3
;
7666 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
)
7669 ULONG TxTotalCnt
= pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
+
7670 pAd
->RalinkCounters
.OneSecTxRetryOkCount
+
7671 pAd
->RalinkCounters
.OneSecTxFailCount
;
7673 if (TxTotalCnt
> 50)
7675 RTMPSetTimer(&pAd
->Mlme
.RxAntEvalTimer
, 20);
7676 pAd
->Mlme
.bLowThroughput
= FALSE
;
7680 RTMPSetTimer(&pAd
->Mlme
.RxAntEvalTimer
, 300);
7681 pAd
->Mlme
.bLowThroughput
= TRUE
;
7687 ========================================================================
7688 Routine Description:
7689 After evaluation, check antenna link status
7692 pAd - Adapter pointer
7697 ========================================================================
7699 VOID
AsicRxAntEvalTimeout(
7700 IN PVOID SystemSpecific1
,
7701 IN PVOID FunctionContext
,
7702 IN PVOID SystemSpecific2
,
7703 IN PVOID SystemSpecific3
)
7705 RTMP_ADAPTER
*pAd
= (RTMP_ADAPTER
*)FunctionContext
;
7707 CHAR larger
= -127, rssi0
, rssi1
, rssi2
;
7709 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
7711 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_RESET_IN_PROGRESS
) ||
7712 RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
) ||
7713 RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_RADIO_OFF
) ||
7714 RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
))
7717 if (pAd
->StaCfg
.Psm
== PWR_SAVE
)
7721 // if the traffic is low, use average rssi as the criteria
7722 if (pAd
->Mlme
.bLowThroughput
== TRUE
)
7724 rssi0
= pAd
->StaCfg
.RssiSample
.LastRssi0
;
7725 rssi1
= pAd
->StaCfg
.RssiSample
.LastRssi1
;
7726 rssi2
= pAd
->StaCfg
.RssiSample
.LastRssi2
;
7730 rssi0
= pAd
->StaCfg
.RssiSample
.AvgRssi0
;
7731 rssi1
= pAd
->StaCfg
.RssiSample
.AvgRssi1
;
7732 rssi2
= pAd
->StaCfg
.RssiSample
.AvgRssi2
;
7735 if(pAd
->Antenna
.field
.RxPath
== 3)
7737 larger
= max(rssi0
, rssi1
);
7739 if (larger
> (rssi2
+ 20))
7740 pAd
->Mlme
.RealRxPath
= 2;
7742 pAd
->Mlme
.RealRxPath
= 3;
7744 else if(pAd
->Antenna
.field
.RxPath
== 2)
7746 if (rssi0
> (rssi1
+ 20))
7747 pAd
->Mlme
.RealRxPath
= 1;
7749 pAd
->Mlme
.RealRxPath
= 2;
7752 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R3
, &BBPR3
);
7754 if(pAd
->Mlme
.RealRxPath
== 3)
7758 else if(pAd
->Mlme
.RealRxPath
== 2)
7762 else if(pAd
->Mlme
.RealRxPath
== 1)
7766 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R3
, BBPR3
);
7767 pAd
->StaCfg
.BBPR3
= BBPR3
;
7773 VOID
APSDPeriodicExec(
7774 IN PVOID SystemSpecific1
,
7775 IN PVOID FunctionContext
,
7776 IN PVOID SystemSpecific2
,
7777 IN PVOID SystemSpecific3
)
7779 RTMP_ADAPTER
*pAd
= (RTMP_ADAPTER
*)FunctionContext
;
7781 if (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
7784 pAd
->CommonCfg
.TriggerTimerCount
++;
7789 ========================================================================
7790 Routine Description:
7791 Set/reset MAC registers according to bPiggyBack parameter
7794 pAd - Adapter pointer
7795 bPiggyBack - Enable / Disable Piggy-Back
7800 ========================================================================
7802 VOID
RTMPSetPiggyBack(
7803 IN PRTMP_ADAPTER pAd
,
7804 IN BOOLEAN bPiggyBack
)
7806 TX_LINK_CFG_STRUC TxLinkCfg
;
7808 RTMP_IO_READ32(pAd
, TX_LINK_CFG
, &TxLinkCfg
.word
);
7810 TxLinkCfg
.field
.TxCFAckEn
= bPiggyBack
;
7811 RTMP_IO_WRITE32(pAd
, TX_LINK_CFG
, TxLinkCfg
.word
);
7815 ========================================================================
7816 Routine Description:
7817 check if this entry need to switch rate automatically
7827 ========================================================================
7829 BOOLEAN
RTMPCheckEntryEnableAutoRateSwitch(
7830 IN PRTMP_ADAPTER pAd
,
7831 IN PMAC_TABLE_ENTRY pEntry
)
7833 BOOLEAN result
= TRUE
;
7835 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
7837 // only associated STA counts
7838 if (pEntry
&& (pEntry
->ValidAsCLI
) && (pEntry
->Sst
== SST_ASSOC
))
7840 result
= pAd
->StaCfg
.bAutoTxRateSwitch
;
7850 BOOLEAN
RTMPAutoRateSwitchCheck(
7851 IN PRTMP_ADAPTER pAd
)
7853 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
7855 if (pAd
->StaCfg
.bAutoTxRateSwitch
)
7864 ========================================================================
7865 Routine Description:
7866 check if this entry need to fix tx legacy rate
7876 ========================================================================
7878 UCHAR
RTMPStaFixedTxMode(
7879 IN PRTMP_ADAPTER pAd
,
7880 IN PMAC_TABLE_ENTRY pEntry
)
7882 UCHAR tx_mode
= FIXED_TXMODE_HT
;
7884 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
7886 tx_mode
= (UCHAR
)pAd
->StaCfg
.DesiredTransmitSetting
.field
.FixedTxMode
;
7893 ========================================================================
7894 Routine Description:
7895 Overwrite HT Tx Mode by Fixed Legency Tx Mode, if specified.
7905 ========================================================================
7907 VOID
RTMPUpdateLegacyTxSetting(
7908 UCHAR fixed_tx_mode
,
7909 PMAC_TABLE_ENTRY pEntry
)
7911 HTTRANSMIT_SETTING TransmitSetting
;
7913 if (fixed_tx_mode
== FIXED_TXMODE_HT
)
7916 TransmitSetting
.word
= 0;
7918 TransmitSetting
.field
.MODE
= pEntry
->HTPhyMode
.field
.MODE
;
7919 TransmitSetting
.field
.MCS
= pEntry
->HTPhyMode
.field
.MCS
;
7921 if (fixed_tx_mode
== FIXED_TXMODE_CCK
)
7923 TransmitSetting
.field
.MODE
= MODE_CCK
;
7924 // CCK mode allow MCS 0~3
7925 if (TransmitSetting
.field
.MCS
> MCS_3
)
7926 TransmitSetting
.field
.MCS
= MCS_3
;
7930 TransmitSetting
.field
.MODE
= MODE_OFDM
;
7931 // OFDM mode allow MCS 0~7
7932 if (TransmitSetting
.field
.MCS
> MCS_7
)
7933 TransmitSetting
.field
.MCS
= MCS_7
;
7936 if (pEntry
->HTPhyMode
.field
.MODE
>= TransmitSetting
.field
.MODE
)
7938 pEntry
->HTPhyMode
.word
= TransmitSetting
.word
;
7939 DBGPRINT(RT_DEBUG_TRACE
, ("RTMPUpdateLegacyTxSetting : wcid-%d, MODE=%s, MCS=%d \n",
7940 pEntry
->Aid
, GetPhyMode(pEntry
->HTPhyMode
.field
.MODE
), pEntry
->HTPhyMode
.field
.MCS
));
7945 ==========================================================================
7947 dynamic tune BBP R66 to find a balance between sensibility and
7950 IRQL = DISPATCH_LEVEL
7952 ==========================================================================
7954 VOID
AsicStaBbpTuning(
7955 IN PRTMP_ADAPTER pAd
)
7957 UCHAR OrigR66Value
= 0, R66
;//, R66UpperBound = 0x30, R66LowerBound = 0x30;
7960 // 2860C did not support Fase CCA, therefore can't tune
7961 if (pAd
->MACVersion
== 0x28600100)
7967 if (pAd
->Mlme
.CntlMachine
.CurrState
!= CNTL_IDLE
) // no R66 tuning when SCANNING
7970 if ((pAd
->OpMode
== OPMODE_STA
)
7971 && (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
)
7973 && !(OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_DOZE
))
7974 && (pAd
->bPCIclkOff
== FALSE
))
7976 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R66
, &OrigR66Value
);
7979 if (pAd
->Antenna
.field
.RxPath
> 1)
7980 Rssi
= (pAd
->StaCfg
.RssiSample
.AvgRssi0
+ pAd
->StaCfg
.RssiSample
.AvgRssi1
) >> 1;
7982 Rssi
= pAd
->StaCfg
.RssiSample
.AvgRssi0
;
7984 if (pAd
->LatchRfRegs
.Channel
<= 14)
7987 if (Rssi
> RSSI_FOR_MID_LOW_SENSIBILITY
)
7989 R66
= (0x2E + GET_LNA_GAIN(pAd
)) + 0x10;
7990 if (OrigR66Value
!= R66
)
7992 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
7997 R66
= 0x2E + GET_LNA_GAIN(pAd
);
7998 if (OrigR66Value
!= R66
)
8000 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8007 if (pAd
->CommonCfg
.BBPCurrentBW
== BW_20
)
8009 if (Rssi
> RSSI_FOR_MID_LOW_SENSIBILITY
)
8011 R66
= 0x32 + (GET_LNA_GAIN(pAd
)*5)/3 + 0x10;
8012 if (OrigR66Value
!= R66
)
8014 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8019 R66
= 0x32 + (GET_LNA_GAIN(pAd
)*5)/3;
8020 if (OrigR66Value
!= R66
)
8022 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8028 if (Rssi
> RSSI_FOR_MID_LOW_SENSIBILITY
)
8030 R66
= 0x3A + (GET_LNA_GAIN(pAd
)*5)/3 + 0x10;
8031 if (OrigR66Value
!= R66
)
8033 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8038 R66
= 0x3A + (GET_LNA_GAIN(pAd
)*5)/3;
8039 if (OrigR66Value
!= R66
)
8041 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8051 VOID
AsicResetFromDMABusy(
8052 IN PRTMP_ADAPTER pAd
)
8055 BOOLEAN bCtrl
= FALSE
;
8057 DBGPRINT(RT_DEBUG_TRACE
, ("---> AsicResetFromDMABusy !!!!!!!!!!!!!!!!!!!!!!! \n"));
8059 // Be sure restore link control value so we can write register.
8060 RTMP_CLEAR_PSFLAG(pAd
, fRTMP_PS_CAN_GO_SLEEP
);
8061 if (RTMP_TEST_PSFLAG(pAd
, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND
))
8063 DBGPRINT(RT_DEBUG_TRACE
,("AsicResetFromDMABusy==>\n"));
8064 RTMPPCIeLinkCtrlValueRestore(pAd
, RESTORE_HALT
);
8065 RTMPusecDelay(6000);
8066 pAd
->bPCIclkOff
= FALSE
;
8070 RTMP_IO_READ32(pAd
, PBF_SYS_CTRL
, &Data
);
8072 RTMP_IO_WRITE32(pAd
, PBF_SYS_CTRL
, Data
);
8074 // After Reset DMA, DMA index will become Zero. So Driver need to reset all ring indexs too.
8075 // Reset DMA/CPU ring index
8076 RTMPRingCleanUp(pAd
, QID_AC_BK
);
8077 RTMPRingCleanUp(pAd
, QID_AC_BE
);
8078 RTMPRingCleanUp(pAd
, QID_AC_VI
);
8079 RTMPRingCleanUp(pAd
, QID_AC_VO
);
8080 RTMPRingCleanUp(pAd
, QID_HCCA
);
8081 RTMPRingCleanUp(pAd
, QID_MGMT
);
8082 RTMPRingCleanUp(pAd
, QID_RX
);
8085 RTMP_IO_READ32(pAd
, PBF_SYS_CTRL
, &Data
);
8087 RTMP_IO_WRITE32(pAd
, PBF_SYS_CTRL
, Data
);
8089 // If in Radio off, should call RTMPPCIePowerLinkCtrl again.
8090 if ((bCtrl
== TRUE
) && (pAd
->StaCfg
.bRadio
== FALSE
))
8091 RTMPPCIeLinkCtrlSetting(pAd
, 3);
8093 RTMP_SET_PSFLAG(pAd
, fRTMP_PS_CAN_GO_SLEEP
);
8094 RTMP_CLEAR_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
| fRTMP_ADAPTER_HALT_IN_PROGRESS
);
8095 DBGPRINT(RT_DEBUG_TRACE
, ("<--- AsicResetFromDMABusy !!!!!!!!!!!!!!!!!!!!!!! \n"));
8099 IN PRTMP_ADAPTER pAd
)
8101 DBGPRINT(RT_DEBUG_TRACE
, ("---> Asic HardReset BBP !!!!!!!!!!!!!!!!!!!!!!! \n"));
8103 RTMP_IO_WRITE32(pAd
, MAC_SYS_CTRL
, 0x0);
8104 RTMP_IO_WRITE32(pAd
, MAC_SYS_CTRL
, 0x2);
8105 RTMP_IO_WRITE32(pAd
, MAC_SYS_CTRL
, 0xc);
8107 // After hard-reset BBP, initialize all BBP values.
8108 NICRestoreBBPValue(pAd
);
8109 DBGPRINT(RT_DEBUG_TRACE
, ("<--- Asic HardReset BBP !!!!!!!!!!!!!!!!!!!!!!! \n"));
8113 IN PRTMP_ADAPTER pAd
)
8117 DBGPRINT(RT_DEBUG_TRACE
, ("---> AsicResetMAC !!!! \n"));
8118 RTMP_IO_READ32(pAd
, PBF_SYS_CTRL
, &Data
);
8120 RTMP_IO_WRITE32(pAd
, PBF_SYS_CTRL
, Data
);
8122 RTMP_IO_WRITE32(pAd
, PBF_SYS_CTRL
, Data
);
8124 DBGPRINT(RT_DEBUG_TRACE
, ("<--- AsicResetMAC !!!! \n"));
8128 IN PRTMP_ADAPTER pAd
)
8130 ULONG Value1
, Value2
;
8133 RTMP_IO_READ32(pAd
, TXRXQ_PCNT
, &Value1
);
8134 RTMP_IO_READ32(pAd
, PBF_DBG
, &Value2
);
8137 // sum should be equals to 0xff, which is the total buffer size.
8138 if ((Value1
+ Value2
) < 0xff)
8140 DBGPRINT(RT_DEBUG_TRACE
, ("---> Asic HardReset PBF !!!! \n"));
8141 RTMP_IO_READ32(pAd
, PBF_SYS_CTRL
, &Data
);
8143 RTMP_IO_WRITE32(pAd
, PBF_SYS_CTRL
, Data
);
8145 RTMP_IO_WRITE32(pAd
, PBF_SYS_CTRL
, Data
);
8147 DBGPRINT(RT_DEBUG_TRACE
, ("<--- Asic HardReset PBF !!!! \n"));
8151 VOID
RTMPSetAGCInitValue(
8152 IN PRTMP_ADAPTER pAd
,
8157 if (pAd
->LatchRfRegs
.Channel
<= 14)
8159 R66
= 0x2E + GET_LNA_GAIN(pAd
);
8160 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8164 if (BandWidth
== BW_20
)
8166 R66
= (UCHAR
)(0x32 + (GET_LNA_GAIN(pAd
)*5)/3);
8167 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8169 #ifdef DOT11_N_SUPPORT
8172 R66
= (UCHAR
)(0x3A + (GET_LNA_GAIN(pAd
)*5)/3);
8173 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8175 #endif // DOT11_N_SUPPORT //
8180 VOID
AsicTurnOffRFClk(
8181 IN PRTMP_ADAPTER pAd
,
8186 UINT32 R1
= 0, R2
= 0, R3
= 0;
8188 RTMP_RF_REGS
*RFRegTable
;
8190 RFRegTable
= RF2850RegTable
;
8192 switch (pAd
->RfIcType
)
8199 for (index
= 0; index
< NUM_OF_2850_CHNL
; index
++)
8201 if (Channel
== RFRegTable
[index
].Channel
)
8203 R1
= RFRegTable
[index
].R1
& 0xffffdfff;
8204 R2
= RFRegTable
[index
].R2
& 0xfffbffff;
8205 R3
= RFRegTable
[index
].R3
& 0xfff3ffff;
8207 RTMP_RF_IO_WRITE32(pAd
, R1
);
8208 RTMP_RF_IO_WRITE32(pAd
, R2
);
8210 // Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0.
8211 // Set RF R2 bit18=0, R3 bit[18:19]=0
8212 //if (pAd->StaCfg.bRadio == FALSE)
8215 RTMP_RF_IO_WRITE32(pAd
, R3
);
8217 DBGPRINT(RT_DEBUG_TRACE
, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x, R3 = 0x%08x \n",
8218 Channel
, pAd
->RfIcType
, R2
, R3
));
8221 DBGPRINT(RT_DEBUG_TRACE
, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n",
8222 Channel
, pAd
->RfIcType
, R2
));
8234 VOID
AsicTurnOnRFClk(
8235 IN PRTMP_ADAPTER pAd
,
8240 UINT32 R1
= 0, R2
= 0, R3
= 0;
8242 RTMP_RF_REGS
*RFRegTable
;
8244 RFRegTable
= RF2850RegTable
;
8246 switch (pAd
->RfIcType
)
8253 for (index
= 0; index
< NUM_OF_2850_CHNL
; index
++)
8255 if (Channel
== RFRegTable
[index
].Channel
)
8257 R3
= pAd
->LatchRfRegs
.R3
;
8260 RTMP_RF_IO_WRITE32(pAd
, R3
);
8262 R1
= RFRegTable
[index
].R1
;
8263 RTMP_RF_IO_WRITE32(pAd
, R1
);
8265 R2
= RFRegTable
[index
].R2
;
8266 if (pAd
->Antenna
.field
.TxPath
== 1)
8268 R2
|= 0x4000; // If TXpath is 1, bit 14 = 1;
8271 if (pAd
->Antenna
.field
.RxPath
== 2)
8273 R2
|= 0x40; // write 1 to off Rxpath.
8275 else if (pAd
->Antenna
.field
.RxPath
== 1)
8277 R2
|= 0x20040; // write 1 to off RxPath
8279 RTMP_RF_IO_WRITE32(pAd
, R2
);
8290 DBGPRINT(RT_DEBUG_TRACE
, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n",