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 WME_INFO_ELEM
[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
47 UCHAR WME_PARM_ELEM
[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
48 UCHAR Ccx2QosInfo
[] = {0x00, 0x40, 0x96, 0x04};
49 UCHAR RALINK_OUI
[] = {0x00, 0x0c, 0x43};
50 UCHAR BROADCOM_OUI
[] = {0x00, 0x90, 0x4c};
51 UCHAR WPS_OUI
[] = {0x00, 0x50, 0xf2, 0x04};
52 UCHAR PRE_N_HT_OUI
[] = {0x00, 0x90, 0x4c};
54 UCHAR RateSwitchTable
[] = {
55 // 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)
56 0x11, 0x00, 0, 0, 0, // Initial used item after association
57 0x00, 0x00, 0, 40, 101,
58 0x01, 0x00, 1, 40, 50,
59 0x02, 0x00, 2, 35, 45,
60 0x03, 0x00, 3, 20, 45,
61 0x04, 0x21, 0, 30, 50,
62 0x05, 0x21, 1, 20, 50,
63 0x06, 0x21, 2, 20, 50,
64 0x07, 0x21, 3, 15, 50,
65 0x08, 0x21, 4, 15, 30,
66 0x09, 0x21, 5, 10, 25,
69 0x0c, 0x20, 12, 15, 30,
70 0x0d, 0x20, 13, 8, 20,
71 0x0e, 0x20, 14, 8, 20,
72 0x0f, 0x20, 15, 8, 25,
73 0x10, 0x22, 15, 8, 25,
91 UCHAR RateSwitchTable11B
[] = {
92 // 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)
93 0x04, 0x03, 0, 0, 0, // Initial used item after association
94 0x00, 0x00, 0, 40, 101,
95 0x01, 0x00, 1, 40, 50,
96 0x02, 0x00, 2, 35, 45,
97 0x03, 0x00, 3, 20, 45,
100 UCHAR RateSwitchTable11BG
[] = {
101 // 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)
102 0x0a, 0x00, 0, 0, 0, // Initial used item after association
103 0x00, 0x00, 0, 40, 101,
104 0x01, 0x00, 1, 40, 50,
105 0x02, 0x00, 2, 35, 45,
106 0x03, 0x00, 3, 20, 45,
107 0x04, 0x10, 2, 20, 35,
108 0x05, 0x10, 3, 16, 35,
109 0x06, 0x10, 4, 10, 25,
110 0x07, 0x10, 5, 16, 25,
111 0x08, 0x10, 6, 10, 25,
112 0x09, 0x10, 7, 10, 13,
115 UCHAR RateSwitchTable11G
[] = {
116 // 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)
117 0x08, 0x00, 0, 0, 0, // Initial used item after association
118 0x00, 0x10, 0, 20, 101,
119 0x01, 0x10, 1, 20, 35,
120 0x02, 0x10, 2, 20, 35,
121 0x03, 0x10, 3, 16, 35,
122 0x04, 0x10, 4, 10, 25,
123 0x05, 0x10, 5, 16, 25,
124 0x06, 0x10, 6, 10, 25,
125 0x07, 0x10, 7, 10, 13,
128 UCHAR RateSwitchTable11N1S
[] = {
129 // 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)
130 0x09, 0x00, 0, 0, 0, // Initial used item after association
131 0x00, 0x21, 0, 30, 101,
132 0x01, 0x21, 1, 20, 50,
133 0x02, 0x21, 2, 20, 50,
134 0x03, 0x21, 3, 15, 50,
135 0x04, 0x21, 4, 15, 30,
136 0x05, 0x21, 5, 10, 25,
137 0x06, 0x21, 6, 8, 14,
138 0x07, 0x21, 7, 8, 14,
139 0x08, 0x23, 7, 8, 14,
142 UCHAR RateSwitchTable11N2S
[] = {
143 // 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)
144 0x0a, 0x00, 0, 0, 0, // Initial used item after association
145 0x00, 0x21, 0, 30, 101,
146 0x01, 0x21, 1, 20, 50,
147 0x02, 0x21, 2, 20, 50,
148 0x03, 0x21, 3, 15, 50,
149 0x04, 0x21, 4, 15, 30,
150 0x05, 0x20, 12, 15, 30,
151 0x06, 0x20, 13, 8, 20,
152 0x07, 0x20, 14, 8, 20,
153 0x08, 0x20, 15, 8, 25,
154 0x09, 0x22, 15, 8, 25,
157 UCHAR RateSwitchTable11N3S
[] = {
158 // 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)
159 0x0a, 0x00, 0, 0, 0, // Initial used item after association
160 0x00, 0x21, 0, 30, 101,
161 0x01, 0x21, 1, 20, 50,
162 0x02, 0x21, 2, 20, 50,
163 0x03, 0x21, 3, 15, 50,
164 0x04, 0x21, 4, 15, 30,
165 0x05, 0x20, 12, 15, 30,
166 0x06, 0x20, 13, 8, 20,
167 0x07, 0x20, 14, 8, 20,
168 0x08, 0x20, 15, 8, 25,
169 0x09, 0x22, 15, 8, 25,
172 UCHAR RateSwitchTable11N2SForABand
[] = {
173 // 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)
174 0x0b, 0x09, 0, 0, 0, // Initial used item after association
175 0x00, 0x21, 0, 30, 101,
176 0x01, 0x21, 1, 20, 50,
177 0x02, 0x21, 2, 20, 50,
178 0x03, 0x21, 3, 15, 50,
179 0x04, 0x21, 4, 15, 30,
180 0x05, 0x21, 5, 15, 30,
181 0x06, 0x20, 12, 15, 30,
182 0x07, 0x20, 13, 8, 20,
183 0x08, 0x20, 14, 8, 20,
184 0x09, 0x20, 15, 8, 25,
185 0x0a, 0x22, 15, 8, 25,
188 UCHAR RateSwitchTable11N3SForABand
[] = { // 3*3
189 // 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)
190 0x0b, 0x09, 0, 0, 0, // Initial used item after association
191 0x00, 0x21, 0, 30, 101,
192 0x01, 0x21, 1, 20, 50,
193 0x02, 0x21, 2, 20, 50,
194 0x03, 0x21, 3, 15, 50,
195 0x04, 0x21, 4, 15, 30,
196 0x05, 0x21, 5, 15, 30,
197 0x06, 0x20, 12, 15, 30,
198 0x07, 0x20, 13, 8, 20,
199 0x08, 0x20, 14, 8, 20,
200 0x09, 0x20, 15, 8, 25,
201 0x0a, 0x22, 15, 8, 25,
204 UCHAR RateSwitchTable11BGN1S
[] = {
205 // 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)
206 0x0d, 0x00, 0, 0, 0, // Initial used item after association
207 0x00, 0x00, 0, 40, 101,
208 0x01, 0x00, 1, 40, 50,
209 0x02, 0x00, 2, 35, 45,
210 0x03, 0x00, 3, 20, 45,
211 0x04, 0x21, 0, 30,101, //50
212 0x05, 0x21, 1, 20, 50,
213 0x06, 0x21, 2, 20, 50,
214 0x07, 0x21, 3, 15, 50,
215 0x08, 0x21, 4, 15, 30,
216 0x09, 0x21, 5, 10, 25,
217 0x0a, 0x21, 6, 8, 14,
218 0x0b, 0x21, 7, 8, 14,
219 0x0c, 0x23, 7, 8, 14,
222 UCHAR RateSwitchTable11BGN2S
[] = {
223 // 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)
224 0x0a, 0x00, 0, 0, 0, // Initial used item after association
225 0x00, 0x21, 0, 30,101, //50
226 0x01, 0x21, 1, 20, 50,
227 0x02, 0x21, 2, 20, 50,
228 0x03, 0x21, 3, 15, 50,
229 0x04, 0x21, 4, 15, 30,
230 0x05, 0x20, 12, 15, 30,
231 0x06, 0x20, 13, 8, 20,
232 0x07, 0x20, 14, 8, 20,
233 0x08, 0x20, 15, 8, 25,
234 0x09, 0x22, 15, 8, 25,
237 UCHAR RateSwitchTable11BGN3S
[] = { // 3*3
238 // 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)
239 0x0a, 0x00, 0, 0, 0, // Initial used item after association
240 0x00, 0x21, 0, 30,101, //50
241 0x01, 0x21, 1, 20, 50,
242 0x02, 0x21, 2, 20, 50,
243 0x03, 0x21, 3, 20, 50,
244 0x04, 0x21, 4, 15, 50,
245 0x05, 0x20, 20, 15, 30,
246 0x06, 0x20, 21, 8, 20,
247 0x07, 0x20, 22, 8, 20,
248 0x08, 0x20, 23, 8, 25,
249 0x09, 0x22, 23, 8, 25,
252 UCHAR RateSwitchTable11BGN2SForABand
[] = {
253 // 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)
254 0x0b, 0x09, 0, 0, 0, // Initial used item after association
255 0x00, 0x21, 0, 30,101, //50
256 0x01, 0x21, 1, 20, 50,
257 0x02, 0x21, 2, 20, 50,
258 0x03, 0x21, 3, 15, 50,
259 0x04, 0x21, 4, 15, 30,
260 0x05, 0x21, 5, 15, 30,
261 0x06, 0x20, 12, 15, 30,
262 0x07, 0x20, 13, 8, 20,
263 0x08, 0x20, 14, 8, 20,
264 0x09, 0x20, 15, 8, 25,
265 0x0a, 0x22, 15, 8, 25,
268 UCHAR RateSwitchTable11BGN3SForABand
[] = { // 3*3
269 // 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)
270 0x0c, 0x09, 0, 0, 0, // Initial used item after association
271 0x00, 0x21, 0, 30,101, //50
272 0x01, 0x21, 1, 20, 50,
273 0x02, 0x21, 2, 20, 50,
274 0x03, 0x21, 3, 15, 50,
275 0x04, 0x21, 4, 15, 30,
276 0x05, 0x21, 5, 15, 30,
277 0x06, 0x21, 12, 15, 30,
278 0x07, 0x20, 20, 15, 30,
279 0x08, 0x20, 21, 8, 20,
280 0x09, 0x20, 22, 8, 20,
281 0x0a, 0x20, 23, 8, 25,
282 0x0b, 0x22, 23, 8, 25,
285 PUCHAR ReasonString
[] = {
287 /* 1 */ "Unspecified Reason",
288 /* 2 */ "Previous Auth no longer valid",
289 /* 3 */ "STA is leaving / has left",
290 /* 4 */ "DIS-ASSOC due to inactivity",
291 /* 5 */ "AP unable to hanle all associations",
292 /* 6 */ "class 2 error",
293 /* 7 */ "class 3 error",
294 /* 8 */ "STA is leaving / has left",
295 /* 9 */ "require auth before assoc/re-assoc",
299 /* 13 */ "invalid IE",
300 /* 14 */ "MIC error",
301 /* 15 */ "4-way handshake timeout",
302 /* 16 */ "2-way (group key) handshake timeout",
303 /* 17 */ "4-way handshake IE diff among AssosReq/Rsp/Beacon",
307 extern UCHAR OfdmRateToRxwiMCS
[];
308 // since RT61 has better RX sensibility, we have to limit TX ACK rate not to exceed our normal data TX rate.
309 // otherwise the WLAN peer may not be able to receive the ACK thus downgrade its data TX rate
310 ULONG BasicRateMask
[12] = {0xfffff001 /* 1-Mbps */, 0xfffff003 /* 2 Mbps */, 0xfffff007 /* 5.5 */, 0xfffff00f /* 11 */,
311 0xfffff01f /* 6 */ , 0xfffff03f /* 9 */ , 0xfffff07f /* 12 */ , 0xfffff0ff /* 18 */,
312 0xfffff1ff /* 24 */ , 0xfffff3ff /* 36 */ , 0xfffff7ff /* 48 */ , 0xffffffff /* 54 */};
314 UCHAR MULTICAST_ADDR
[MAC_ADDR_LEN
] = {0x1, 0x00, 0x00, 0x00, 0x00, 0x00};
315 UCHAR BROADCAST_ADDR
[MAC_ADDR_LEN
] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
316 UCHAR ZERO_MAC_ADDR
[MAC_ADDR_LEN
] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
318 // e.g. RssiSafeLevelForTxRate[RATE_36]" means if the current RSSI is greater than
319 // this value, then it's quaranteed capable of operating in 36 mbps TX rate in
320 // clean environment.
321 // TxRate: 1 2 5.5 11 6 9 12 18 24 36 48 54 72 100
322 CHAR RssiSafeLevelForTxRate
[] ={ -92, -91, -90, -87, -88, -86, -85, -83, -81, -78, -72, -71, -40, -40 };
324 UCHAR RateIdToMbps
[] = { 1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 72, 100};
325 USHORT RateIdTo500Kbps
[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 144, 200};
327 UCHAR SsidIe
= IE_SSID
;
328 UCHAR SupRateIe
= IE_SUPP_RATES
;
329 UCHAR ExtRateIe
= IE_EXT_SUPP_RATES
;
330 UCHAR HtCapIe
= IE_HT_CAP
;
331 UCHAR AddHtInfoIe
= IE_ADD_HT
;
332 UCHAR NewExtChanIe
= IE_SECONDARY_CH_OFFSET
;
333 UCHAR ErpIe
= IE_ERP
;
334 UCHAR DsIe
= IE_DS_PARM
;
335 UCHAR TimIe
= IE_TIM
;
336 UCHAR WpaIe
= IE_WPA
;
337 UCHAR Wpa2Ie
= IE_WPA2
;
338 UCHAR IbssIe
= IE_IBSS_PARM
;
339 UCHAR Ccx2Ie
= IE_CCX_V2
;
341 extern UCHAR WPA_OUI
[];
343 UCHAR SES_OUI
[] = {0x00, 0x90, 0x4c};
345 UCHAR ZeroSsid
[32] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
346 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
348 // Reset the RFIC setting to new series
349 RTMP_RF_REGS RF2850RegTable
[] = {
350 // ch R1 R2 R3(TX0~4=0) R4
351 {1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b},
352 {2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f},
353 {3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b},
354 {4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f},
355 {5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b},
356 {6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f},
357 {7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b},
358 {8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f},
359 {9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b},
360 {10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f},
361 {11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b},
362 {12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f},
363 {13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b},
364 {14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193},
366 // 802.11 UNI / HyperLan 2
367 {36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3},
368 {38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193},
369 {40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183},
370 {44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3},
371 {46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b},
372 {48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b},
373 {52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193},
374 {54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3},
375 {56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b},
376 {60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183},
377 {62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193},
378 {64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3}, // Plugfest#4, Day4, change RFR3 left4th 9->5.
381 {100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783},
383 // 2008.04.30 modified
384 // The system team has AN to improve the EVM value
385 // for channel 102 to 108 for the RT2850/RT2750 dual band solution.
386 {102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793},
387 {104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3},
388 {108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193},
390 {110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183},
391 {112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b},
392 {116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3},
393 {118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193},
394 {120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183},
395 {124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193},
396 {126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}, // 0x980ed1bb->0x980ed15b required by Rory 20070927
397 {128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3},
398 {132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b},
399 {134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193},
400 {136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b},
401 {140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183},
404 {149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7},
405 {151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187},
406 {153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f},
407 {157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f},
408 {159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7},
409 {161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187},
410 {165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197},
413 {184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b},
414 {188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13},
415 {192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b},
416 {196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23},
417 {208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13},
418 {212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b},
419 {216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23},
421 // still lack of MMAC(Japan) ch 34,38,42,46
423 UCHAR NUM_OF_2850_CHNL
= (sizeof(RF2850RegTable
) / sizeof(RTMP_RF_REGS
));
425 FREQUENCY_ITEM FreqItems3020
[] =
427 /**************************************************/
428 // ISM : 2.4 to 2.483 GHz //
429 /**************************************************/
431 /**************************************************/
432 //-CH---N-------R---K-----------
448 UCHAR NUM_OF_3020_CHNL
=(sizeof(FreqItems3020
) / sizeof(FREQUENCY_ITEM
));
451 ==========================================================================
453 initialize the MLME task and its data structure (queue, spinlock,
454 timer, state machines).
459 always return NDIS_STATUS_SUCCESS
461 ==========================================================================
463 NDIS_STATUS
MlmeInit(
464 IN PRTMP_ADAPTER pAd
)
466 NDIS_STATUS Status
= NDIS_STATUS_SUCCESS
;
468 DBGPRINT(RT_DEBUG_TRACE
, ("--> MLME Initialize\n"));
472 Status
= MlmeQueueInit(&pAd
->Mlme
.Queue
);
473 if(Status
!= NDIS_STATUS_SUCCESS
)
476 pAd
->Mlme
.bRunning
= FALSE
;
477 NdisAllocateSpinLock(&pAd
->Mlme
.TaskLock
);
480 BssTableInit(&pAd
->ScanTab
);
482 // init STA state machines
483 AssocStateMachineInit(pAd
, &pAd
->Mlme
.AssocMachine
, pAd
->Mlme
.AssocFunc
);
484 AuthStateMachineInit(pAd
, &pAd
->Mlme
.AuthMachine
, pAd
->Mlme
.AuthFunc
);
485 AuthRspStateMachineInit(pAd
, &pAd
->Mlme
.AuthRspMachine
, pAd
->Mlme
.AuthRspFunc
);
486 SyncStateMachineInit(pAd
, &pAd
->Mlme
.SyncMachine
, pAd
->Mlme
.SyncFunc
);
487 WpaPskStateMachineInit(pAd
, &pAd
->Mlme
.WpaPskMachine
, pAd
->Mlme
.WpaPskFunc
);
488 AironetStateMachineInit(pAd
, &pAd
->Mlme
.AironetMachine
, pAd
->Mlme
.AironetFunc
);
490 // Since we are using switch/case to implement it, the init is different from the above
491 // state machine init
492 MlmeCntlInit(pAd
, &pAd
->Mlme
.CntlMachine
, NULL
);
495 ActionStateMachineInit(pAd
, &pAd
->Mlme
.ActMachine
, pAd
->Mlme
.ActFunc
);
497 // Init mlme periodic timer
498 RTMPInitTimer(pAd
, &pAd
->Mlme
.PeriodicTimer
, GET_TIMER_FUNCTION(MlmePeriodicExec
), pAd
, TRUE
);
500 // Set mlme periodic timer
501 RTMPSetTimer(&pAd
->Mlme
.PeriodicTimer
, MLME_TASK_EXEC_INTV
);
503 // software-based RX Antenna diversity
504 RTMPInitTimer(pAd
, &pAd
->Mlme
.RxAntEvalTimer
, GET_TIMER_FUNCTION(AsicRxAntEvalTimeout
), pAd
, FALSE
);
508 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE
))
510 // only PCIe cards need these two timers
511 RTMPInitTimer(pAd
, &pAd
->Mlme
.PsPollTimer
, GET_TIMER_FUNCTION(PsPollWakeExec
), pAd
, FALSE
);
512 RTMPInitTimer(pAd
, &pAd
->Mlme
.RadioOnOffTimer
, GET_TIMER_FUNCTION(RadioOnExec
), pAd
, FALSE
);
518 DBGPRINT(RT_DEBUG_TRACE
, ("<-- MLME Initialize\n"));
524 ==========================================================================
526 main loop of the MLME
528 Mlme has to be initialized, and there are something inside the queue
530 This function is invoked from MPSetInformation and MPReceive;
531 This task guarantee only one MlmeHandler will run.
533 IRQL = DISPATCH_LEVEL
535 ==========================================================================
538 IN PRTMP_ADAPTER pAd
)
540 MLME_QUEUE_ELEM
*Elem
= NULL
;
542 // Only accept MLME and Frame from peer side, no other (control/data) frame should
543 // get into this state machine
545 NdisAcquireSpinLock(&pAd
->Mlme
.TaskLock
);
546 if(pAd
->Mlme
.bRunning
)
548 NdisReleaseSpinLock(&pAd
->Mlme
.TaskLock
);
553 pAd
->Mlme
.bRunning
= TRUE
;
555 NdisReleaseSpinLock(&pAd
->Mlme
.TaskLock
);
557 while (!MlmeQueueEmpty(&pAd
->Mlme
.Queue
))
559 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS
) ||
560 RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
) ||
561 RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
))
563 DBGPRINT(RT_DEBUG_TRACE
, ("Device Halted or Removed or MlmeRest, exit MlmeHandler! (queue num = %ld)\n", pAd
->Mlme
.Queue
.Num
));
567 //From message type, determine which state machine I should drive
568 if (MlmeDequeue(&pAd
->Mlme
.Queue
, &Elem
))
571 if (Elem
->MsgType
== MT2_RESET_CONF
)
573 DBGPRINT_RAW(RT_DEBUG_TRACE
, ("!!! reset MLME state machine !!!\n"));
574 MlmeRestartStateMachine(pAd
);
575 Elem
->Occupied
= FALSE
;
581 // if dequeue success
582 switch (Elem
->Machine
)
584 // STA state machines
585 case ASSOC_STATE_MACHINE
:
586 StateMachinePerformAction(pAd
, &pAd
->Mlme
.AssocMachine
, Elem
);
588 case AUTH_STATE_MACHINE
:
589 StateMachinePerformAction(pAd
, &pAd
->Mlme
.AuthMachine
, Elem
);
591 case AUTH_RSP_STATE_MACHINE
:
592 StateMachinePerformAction(pAd
, &pAd
->Mlme
.AuthRspMachine
, Elem
);
594 case SYNC_STATE_MACHINE
:
595 StateMachinePerformAction(pAd
, &pAd
->Mlme
.SyncMachine
, Elem
);
597 case MLME_CNTL_STATE_MACHINE
:
598 MlmeCntlMachinePerformAction(pAd
, &pAd
->Mlme
.CntlMachine
, Elem
);
600 case WPA_PSK_STATE_MACHINE
:
601 StateMachinePerformAction(pAd
, &pAd
->Mlme
.WpaPskMachine
, Elem
);
603 case AIRONET_STATE_MACHINE
:
604 StateMachinePerformAction(pAd
, &pAd
->Mlme
.AironetMachine
, Elem
);
606 case ACTION_STATE_MACHINE
:
607 StateMachinePerformAction(pAd
, &pAd
->Mlme
.ActMachine
, Elem
);
614 DBGPRINT(RT_DEBUG_TRACE
, ("ERROR: Illegal machine %ld in MlmeHandler()\n", Elem
->Machine
));
619 Elem
->Occupied
= FALSE
;
624 DBGPRINT_ERR(("MlmeHandler: MlmeQueue empty\n"));
628 NdisAcquireSpinLock(&pAd
->Mlme
.TaskLock
);
629 pAd
->Mlme
.bRunning
= FALSE
;
630 NdisReleaseSpinLock(&pAd
->Mlme
.TaskLock
);
634 ==========================================================================
636 Destructor of MLME (Destroy queue, state machine, spin lock and timer)
638 Adapter - NIC Adapter pointer
640 The MLME task will no longer work properly
644 ==========================================================================
647 IN PRTMP_ADAPTER pAd
)
651 UINT32 TxPinCfg
= 0x00050F0F;
654 DBGPRINT(RT_DEBUG_TRACE
, ("==> MlmeHalt\n"));
656 if (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
))
658 // disable BEACON generation and other BEACON related hardware timers
659 AsicDisableSync(pAd
);
663 // Cancel pending timers
664 RTMPCancelTimer(&pAd
->MlmeAux
.AssocTimer
, &Cancelled
);
665 RTMPCancelTimer(&pAd
->MlmeAux
.ReassocTimer
, &Cancelled
);
666 RTMPCancelTimer(&pAd
->MlmeAux
.DisassocTimer
, &Cancelled
);
667 RTMPCancelTimer(&pAd
->MlmeAux
.AuthTimer
, &Cancelled
);
668 RTMPCancelTimer(&pAd
->MlmeAux
.BeaconTimer
, &Cancelled
);
669 RTMPCancelTimer(&pAd
->MlmeAux
.ScanTimer
, &Cancelled
);
671 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE
))
673 RTMPCancelTimer(&pAd
->Mlme
.PsPollTimer
, &Cancelled
);
674 RTMPCancelTimer(&pAd
->Mlme
.RadioOnOffTimer
, &Cancelled
);
679 RTMPCancelTimer(&pAd
->Mlme
.PeriodicTimer
, &Cancelled
);
680 RTMPCancelTimer(&pAd
->Mlme
.RxAntEvalTimer
, &Cancelled
);
684 if (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
))
687 RTMPSetLED(pAd
, LED_HALT
);
688 RTMPSetSignalLED(pAd
, -100); // Force signal strength Led to be turned off, firmware is not done it.
691 LED_CFG_STRUC LedCfg
;
692 RTMP_IO_READ32(pAd
, LED_CFG
, &LedCfg
.word
);
693 LedCfg
.field
.LedPolar
= 0;
694 LedCfg
.field
.RLedMode
= 0;
695 LedCfg
.field
.GLedMode
= 0;
696 LedCfg
.field
.YLedMode
= 0;
697 RTMP_IO_WRITE32(pAd
, LED_CFG
, LedCfg
.word
);
704 if (IS_RT3070(pAd
) || IS_RT3071(pAd
))
706 TxPinCfg
&= 0xFFFFF0F0;
707 RTUSBWriteMACRegister(pAd
, TX_PIN_CFG
, TxPinCfg
);
712 RTMPusecDelay(5000); // 5 msec to gurantee Ant Diversity timer canceled
714 MlmeQueueDestroy(&pAd
->Mlme
.Queue
);
715 NdisFreeSpinLock(&pAd
->Mlme
.TaskLock
);
717 DBGPRINT(RT_DEBUG_TRACE
, ("<== MlmeHalt\n"));
720 VOID
MlmeResetRalinkCounters(
721 IN PRTMP_ADAPTER pAd
)
723 pAd
->RalinkCounters
.LastOneSecRxOkDataCnt
= pAd
->RalinkCounters
.OneSecRxOkDataCnt
;
724 // clear all OneSecxxx counters.
725 pAd
->RalinkCounters
.OneSecBeaconSentCnt
= 0;
726 pAd
->RalinkCounters
.OneSecFalseCCACnt
= 0;
727 pAd
->RalinkCounters
.OneSecRxFcsErrCnt
= 0;
728 pAd
->RalinkCounters
.OneSecRxOkCnt
= 0;
729 pAd
->RalinkCounters
.OneSecTxFailCount
= 0;
730 pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
= 0;
731 pAd
->RalinkCounters
.OneSecTxRetryOkCount
= 0;
732 pAd
->RalinkCounters
.OneSecRxOkDataCnt
= 0;
734 // TODO: for debug only. to be removed
735 pAd
->RalinkCounters
.OneSecOsTxCount
[QID_AC_BE
] = 0;
736 pAd
->RalinkCounters
.OneSecOsTxCount
[QID_AC_BK
] = 0;
737 pAd
->RalinkCounters
.OneSecOsTxCount
[QID_AC_VI
] = 0;
738 pAd
->RalinkCounters
.OneSecOsTxCount
[QID_AC_VO
] = 0;
739 pAd
->RalinkCounters
.OneSecDmaDoneCount
[QID_AC_BE
] = 0;
740 pAd
->RalinkCounters
.OneSecDmaDoneCount
[QID_AC_BK
] = 0;
741 pAd
->RalinkCounters
.OneSecDmaDoneCount
[QID_AC_VI
] = 0;
742 pAd
->RalinkCounters
.OneSecDmaDoneCount
[QID_AC_VO
] = 0;
743 pAd
->RalinkCounters
.OneSecTxDoneCount
= 0;
744 pAd
->RalinkCounters
.OneSecRxCount
= 0;
745 pAd
->RalinkCounters
.OneSecTxAggregationCount
= 0;
746 pAd
->RalinkCounters
.OneSecRxAggregationCount
= 0;
751 unsigned long rx_AMSDU
;
752 unsigned long rx_Total
;
755 ==========================================================================
757 This routine is executed periodically to -
758 1. Decide if it's a right time to turn on PwrMgmt bit of all
760 2. Calculate ChannelQuality based on statistics of the last
761 period, so that TX rate won't toggling very frequently between a
762 successful TX and a failed TX.
763 3. If the calculated ChannelQuality indicated current connection not
764 healthy, then a ROAMing attempt is tried here.
766 IRQL = DISPATCH_LEVEL
768 ==========================================================================
770 #define ADHOC_BEACON_LOST_TIME (8*OS_HZ) // 8 sec
771 VOID
MlmePeriodicExec(
772 IN PVOID SystemSpecific1
,
773 IN PVOID FunctionContext
,
774 IN PVOID SystemSpecific2
,
775 IN PVOID SystemSpecific3
)
778 PRTMP_ADAPTER pAd
= (RTMP_ADAPTER
*)FunctionContext
;
782 //printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus));
783 //If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0.
784 //If the STA security setting is WPAPSK or WPA2PSK, pAd->StaCfg.WpaSupplicantUP = 1.
785 if(pAd
->StaCfg
.WepStatus
<2)
787 pAd
->StaCfg
.WpaSupplicantUP
= 0;
791 pAd
->StaCfg
.WpaSupplicantUP
= 1;
795 // If Hardware controlled Radio enabled, we have to check GPIO pin2 every 2 second.
796 // Move code to here, because following code will return when radio is off
797 if ((pAd
->Mlme
.PeriodicRound
% (MLME_TASK_EXEC_MULTIPLE
* 2) == 0) &&
798 (pAd
->StaCfg
.bHardwareRadio
== TRUE
) &&
799 (RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_START_UP
)) &&
800 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
)) &&
801 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
)))
805 // Read GPIO pin2 as Hardware controlled radio state
806 RTMP_IO_FORCE_READ32(pAd
, GPIO_CTRL_CFG
, &data
);
809 pAd
->StaCfg
.bHwRadio
= TRUE
;
813 pAd
->StaCfg
.bHwRadio
= FALSE
;
815 if (pAd
->StaCfg
.bRadio
!= (pAd
->StaCfg
.bHwRadio
&& pAd
->StaCfg
.bSwRadio
))
817 pAd
->StaCfg
.bRadio
= (pAd
->StaCfg
.bHwRadio
&& pAd
->StaCfg
.bSwRadio
);
818 if (pAd
->StaCfg
.bRadio
== TRUE
)
821 // Update extra information
822 pAd
->ExtraInfo
= EXTRA_INFO_CLEAR
;
827 // Update extra information
828 pAd
->ExtraInfo
= HW_RADIO_OFF
;
835 // Do nothing if the driver is starting halt state.
836 // This might happen when timer already been fired before cancel timer with mlmehalt
837 if ((RTMP_TEST_FLAG(pAd
, (fRTMP_ADAPTER_HALT_IN_PROGRESS
|
838 fRTMP_ADAPTER_RADIO_OFF
|
839 fRTMP_ADAPTER_RADIO_MEASUREMENT
|
840 fRTMP_ADAPTER_RESET_IN_PROGRESS
))))
845 if ((pAd
->RalinkCounters
.LastReceivedByteCount
== pAd
->RalinkCounters
.ReceivedByteCount
) && (pAd
->StaCfg
.bRadio
== TRUE
))
847 // If ReceiveByteCount doesn't change, increase SameRxByteCount by 1.
848 pAd
->SameRxByteCount
++;
851 pAd
->SameRxByteCount
= 0;
853 // If after BBP, still not work...need to check to reset PBF&MAC.
854 if (pAd
->SameRxByteCount
== 702)
856 pAd
->SameRxByteCount
= 0;
861 // If SameRxByteCount keeps happens for 2 second in infra mode, or for 60 seconds in idle mode.
862 if (((INFRA_ON(pAd
)) && (pAd
->SameRxByteCount
> 20)) || ((IDLE_ON(pAd
)) && (pAd
->SameRxByteCount
> 600)))
864 if ((pAd
->StaCfg
.bRadio
== TRUE
) && (pAd
->SameRxByteCount
< 700))
866 DBGPRINT(RT_DEBUG_TRACE
, ("---> SameRxByteCount = %lu !!!!!!!!!!!!!!! \n", pAd
->SameRxByteCount
));
867 pAd
->SameRxByteCount
= 700;
872 // Update lastReceiveByteCount.
873 pAd
->RalinkCounters
.LastReceivedByteCount
= pAd
->RalinkCounters
.ReceivedByteCount
;
875 if ((pAd
->CheckDmaBusyCount
> 3) && (IDLE_ON(pAd
)))
877 pAd
->CheckDmaBusyCount
= 0;
878 AsicResetFromDMABusy(pAd
);
882 RT28XX_MLME_PRE_SANITY_CHECK(pAd
);
885 // Do nothing if monitor mode is on
889 if (pAd
->Mlme
.PeriodicRound
& 0x1)
891 // This is the fix for wifi 11n extension channel overlapping test case. for 2860D
892 if (((pAd
->MACVersion
& 0xffff) == 0x0101) &&
893 (STA_TGN_WIFI_ON(pAd
)) &&
894 (pAd
->CommonCfg
.IOTestParm
.bToggle
== FALSE
))
897 RTMP_IO_WRITE32(pAd
, TXOP_CTRL_CFG
, 0x24Bf);
898 pAd
->CommonCfg
.IOTestParm
.bToggle
= TRUE
;
900 else if ((STA_TGN_WIFI_ON(pAd
)) &&
901 ((pAd
->MACVersion
& 0xffff) == 0x0101))
903 RTMP_IO_WRITE32(pAd
, TXOP_CTRL_CFG
, 0x243f);
904 pAd
->CommonCfg
.IOTestParm
.bToggle
= FALSE
;
909 pAd
->bUpdateBcnCntDone
= FALSE
;
911 // RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3);
912 pAd
->Mlme
.PeriodicRound
++;
915 // execute every 100ms, update the Tx FIFO Cnt for update Tx Rate.
916 NICUpdateFifoStaCounters(pAd
);
918 // execute every 500ms
919 if ((pAd
->Mlme
.PeriodicRound
% 5 == 0) && RTMPAutoRateSwitchCheck(pAd
)/*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))*/)
921 // perform dynamic tx rate switching based on past TX history
923 if ((OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
)
925 && (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_DOZE
)))
926 MlmeDynamicTxRateSwitching(pAd
);
930 // Normal 1 second Mlme PeriodicExec.
931 if (pAd
->Mlme
.PeriodicRound
%MLME_TASK_EXEC_MULTIPLE
== 0)
933 pAd
->Mlme
.OneSecPeriodicRound
++;
943 // Media status changed, report to NDIS
944 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_MEDIA_STATE_CHANGE
))
946 RTMP_CLEAR_FLAG(pAd
, fRTMP_ADAPTER_MEDIA_STATE_CHANGE
);
947 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
949 pAd
->IndicateMediaState
= NdisMediaStateConnected
;
950 RTMP_IndicateMediaState(pAd
);
955 pAd
->IndicateMediaState
= NdisMediaStateDisconnected
;
956 RTMP_IndicateMediaState(pAd
);
960 NdisGetSystemUpTime(&pAd
->Mlme
.Now32
);
962 // add the most up-to-date h/w raw counters into software variable, so that
963 // the dynamic tuning mechanism below are based on most up-to-date information
964 NICUpdateRawCounters(pAd
);
967 RT2870_WatchDog(pAd
);
970 // Need statistics after read counter. So put after NICUpdateRawCounters
971 ORIBATimerTimeout(pAd
);
973 // The time period for checking antenna is according to traffic
974 if (pAd
->Mlme
.bEnableAutoAntennaCheck
)
976 TxTotalCnt
= pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
+
977 pAd
->RalinkCounters
.OneSecTxRetryOkCount
+
978 pAd
->RalinkCounters
.OneSecTxFailCount
;
980 // dynamic adjust antenna evaluation period according to the traffic
983 if (pAd
->Mlme
.OneSecPeriodicRound
% 10 == 0)
985 AsicEvaluateRxAnt(pAd
);
990 if (pAd
->Mlme
.OneSecPeriodicRound
% 3 == 0)
992 AsicEvaluateRxAnt(pAd
);
997 STAMlmePeriodicExec(pAd
);
999 MlmeResetRalinkCounters(pAd
);
1003 if (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
) && (pAd
->bPCIclkOff
== FALSE
))
1006 // When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock
1007 // and sending CTS-to-self over and over.
1008 // Software Patch Solution:
1009 // 1. Polling debug state register 0x10F4 every one second.
1010 // 2. If in 0x10F4 the ((bit29==1) && (bit7==1)) OR ((bit29==1) && (bit5==1)), it means the deadlock has occurred.
1011 // 3. If the deadlock occurred, reset MAC/BBP by setting 0x1004 to 0x0001 for a while then setting it back to 0x000C again.
1015 RTMP_IO_READ32(pAd
, 0x10F4, &MacReg
);
1016 if (((MacReg
& 0x20000000) && (MacReg
& 0x80)) || ((MacReg
& 0x20000000) && (MacReg
& 0x20)))
1018 RTMP_IO_WRITE32(pAd
, MAC_SYS_CTRL
, 0x1);
1020 RTMP_IO_WRITE32(pAd
, MAC_SYS_CTRL
, 0xC);
1022 DBGPRINT(RT_DEBUG_WARN
,("Warning, MAC specific condition occurs \n"));
1027 RT28XX_MLME_HANDLER(pAd
);
1030 pAd
->bUpdateBcnCntDone
= FALSE
;
1033 VOID
STAMlmePeriodicExec(
1044 if (pAd
->StaCfg
.WpaSupplicantUP
== WPA_SUPPLICANT_DISABLE
)
1046 // WPA MIC error should block association attempt for 60 seconds
1047 if (pAd
->StaCfg
.bBlockAssoc
&& (pAd
->StaCfg
.LastMicErrorTime
+ (60 * OS_HZ
) < pAd
->Mlme
.Now32
))
1048 pAd
->StaCfg
.bBlockAssoc
= FALSE
;
1053 //printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus));
1054 //If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0.
1055 //If the STA security setting is WPAPSK or WPA2PSK, pAd->StaCfg.WpaSupplicantUP = 1.
1056 if(pAd
->StaCfg
.WepStatus
<2)
1058 pAd
->StaCfg
.WpaSupplicantUP
= 0;
1062 pAd
->StaCfg
.WpaSupplicantUP
= 1;
1066 if ((pAd
->PreMediaState
!= pAd
->IndicateMediaState
) && (pAd
->CommonCfg
.bWirelessEvent
))
1068 if (pAd
->IndicateMediaState
== NdisMediaStateConnected
)
1070 RTMPSendWirelessEvent(pAd
, IW_STA_LINKUP_EVENT_FLAG
, pAd
->MacTab
.Content
[BSSID_WCID
].Addr
, BSS0
, 0);
1072 pAd
->PreMediaState
= pAd
->IndicateMediaState
;
1076 if ((pAd
->OpMode
== OPMODE_STA
) && (IDLE_ON(pAd
)) &&
1077 (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE
)) &&
1078 (pAd
->Mlme
.SyncMachine
.CurrState
== SYNC_IDLE
) &&
1079 (pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_IDLE
) &&
1080 (RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_START_UP
)) &&
1081 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_IDLE_RADIO_OFF
)))
1083 RT28xxPciAsicRadioOff(pAd
, GUI_IDLE_POWER_SAVE
, 0);
1089 AsicStaBbpTuning(pAd
);
1091 TxTotalCnt
= pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
+
1092 pAd
->RalinkCounters
.OneSecTxRetryOkCount
+
1093 pAd
->RalinkCounters
.OneSecTxFailCount
;
1095 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
1097 // update channel quality for Roaming and UI LinkQuality display
1098 MlmeCalculateChannelQuality(pAd
, pAd
->Mlme
.Now32
);
1101 // must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if
1102 // Radio is currently in noisy environment
1103 if (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS
))
1104 AsicAdjustTxPower(pAd
);
1108 // Is PSM bit consistent with user power management policy?
1109 // This is the only place that will set PSM bit ON.
1110 if (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_DOZE
))
1111 MlmeCheckPsmChange(pAd
, pAd
->Mlme
.Now32
);
1113 pAd
->RalinkCounters
.LastOneSecTotalTxCount
= TxTotalCnt
;
1115 if ((pAd
->StaCfg
.LastBeaconRxTime
+ 1*OS_HZ
< pAd
->Mlme
.Now32
) &&
1116 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS
)) &&
1117 ((TxTotalCnt
+ pAd
->RalinkCounters
.OneSecRxOkCnt
< 600)))
1119 RTMPSetAGCInitValue(pAd
, BW_20
);
1120 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n", (0x2E + GET_LNA_GAIN(pAd
))));
1124 if (pAd
->CommonCfg
.bAPSDCapable
&& pAd
->CommonCfg
.APEdcaParm
.bAPSDCapable
)
1126 // When APSD is enabled, the period changes as 20 sec
1127 if ((pAd
->Mlme
.OneSecPeriodicRound
% 20) == 8)
1128 RTMPSendNullFrame(pAd
, pAd
->CommonCfg
.TxRate
, TRUE
);
1132 // Send out a NULL frame every 10 sec to inform AP that STA is still alive (Avoid being age out)
1133 if ((pAd
->Mlme
.OneSecPeriodicRound
% 10) == 8)
1135 if (pAd
->CommonCfg
.bWmmCapable
)
1136 RTMPSendNullFrame(pAd
, pAd
->CommonCfg
.TxRate
, TRUE
);
1138 RTMPSendNullFrame(pAd
, pAd
->CommonCfg
.TxRate
, FALSE
);
1143 if (CQI_IS_DEAD(pAd
->Mlme
.ChannelQuality
))
1145 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n", pAd
->RalinkCounters
.BadCQIAutoRecoveryCount
));
1146 pAd
->StaCfg
.CCXAdjacentAPReportFlag
= TRUE
;
1147 pAd
->StaCfg
.CCXAdjacentAPLinkDownTime
= pAd
->StaCfg
.LastBeaconRxTime
;
1149 // Lost AP, send disconnect & link down event
1150 LinkDown(pAd
, FALSE
);
1153 union iwreq_data wrqu
;
1154 memset(wrqu
.ap_addr
.sa_data
, 0, MAC_ADDR_LEN
);
1155 wireless_send_event(pAd
->net_dev
, SIOCGIWAP
, &wrqu
, NULL
);
1158 MlmeAutoReconnectLastSSID(pAd
);
1160 else if (CQI_IS_BAD(pAd
->Mlme
.ChannelQuality
))
1162 pAd
->RalinkCounters
.BadCQIAutoRecoveryCount
++;
1163 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - Bad CQI. Auto Recovery attempt #%ld\n", pAd
->RalinkCounters
.BadCQIAutoRecoveryCount
));
1164 MlmeAutoReconnectLastSSID(pAd
);
1167 // Add auto seamless roaming
1168 if (pAd
->StaCfg
.bFastRoaming
)
1170 SHORT dBmToRoam
= (SHORT
)pAd
->StaCfg
.dBmToRoam
;
1172 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
));
1174 if (RTMPMaxRssi(pAd
, pAd
->StaCfg
.RssiSample
.LastRssi0
, pAd
->StaCfg
.RssiSample
.LastRssi1
, pAd
->StaCfg
.RssiSample
.LastRssi2
) <= (CHAR
)dBmToRoam
)
1176 MlmeCheckForFastRoaming(pAd
, pAd
->Mlme
.Now32
);
1180 else if (ADHOC_ON(pAd
))
1183 // 2003-04-17 john. this is a patch that driver forces a BEACON out if ASIC fails
1184 // the "TX BEACON competition" for the entire past 1 sec.
1185 // So that even when ASIC's BEACONgen engine been blocked
1186 // by peer's BEACON due to slower system clock, this STA still can send out
1187 // minimum BEACON to tell the peer I'm alive.
1188 // drawback is that this BEACON won't be well aligned at TBTT boundary.
1189 // EnqueueBeaconFrame(pAd); // software send BEACON
1191 // if all 11b peers leave this BSS more than 5 seconds, update Tx rate,
1192 // restore outgoing BEACON to support B/G-mixed mode
1193 if ((pAd
->CommonCfg
.Channel
<= 14) &&
1194 (pAd
->CommonCfg
.MaxTxRate
<= RATE_11
) &&
1195 (pAd
->CommonCfg
.MaxDesiredRate
> RATE_11
) &&
1196 ((pAd
->StaCfg
.Last11bBeaconRxTime
+ 5*OS_HZ
) < pAd
->Mlme
.Now32
))
1198 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - last 11B peer left, update Tx rates\n"));
1199 NdisMoveMemory(pAd
->StaActive
.SupRate
, pAd
->CommonCfg
.SupRate
, MAX_LEN_OF_SUPPORTED_RATES
);
1200 pAd
->StaActive
.SupRateLen
= pAd
->CommonCfg
.SupRateLen
;
1201 MlmeUpdateTxRates(pAd
, FALSE
, 0);
1202 MakeIbssBeacon(pAd
); // re-build BEACON frame
1203 AsicEnableIbssSync(pAd
); // copy to on-chip memory
1204 pAd
->StaCfg
.AdhocBOnlyJoined
= FALSE
;
1207 if (pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
)
1209 if ((pAd
->StaCfg
.AdhocBGJoined
) &&
1210 ((pAd
->StaCfg
.Last11gBeaconRxTime
+ 5 * OS_HZ
) < pAd
->Mlme
.Now32
))
1212 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - last 11G peer left\n"));
1213 pAd
->StaCfg
.AdhocBGJoined
= FALSE
;
1216 if ((pAd
->StaCfg
.Adhoc20NJoined
) &&
1217 ((pAd
->StaCfg
.Last20NBeaconRxTime
+ 5 * OS_HZ
) < pAd
->Mlme
.Now32
))
1219 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - last 20MHz N peer left\n"));
1220 pAd
->StaCfg
.Adhoc20NJoined
= FALSE
;
1226 if ((pAd
->CommonCfg
.Channel
> 14)
1227 && (pAd
->CommonCfg
.bIEEE80211H
== 1)
1228 && RadarChannelCheck(pAd
, pAd
->CommonCfg
.Channel
))
1230 RadarDetectPeriodic(pAd
);
1233 // If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState
1234 // to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can
1236 if ((pAd
->StaCfg
.LastBeaconRxTime
+ ADHOC_BEACON_LOST_TIME
< pAd
->Mlme
.Now32
) &&
1237 OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
1239 MLME_START_REQ_STRUCT StartReq
;
1241 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n"));
1242 LinkDown(pAd
, FALSE
);
1244 StartParmFill(pAd
, &StartReq
, pAd
->MlmeAux
.Ssid
, pAd
->MlmeAux
.SsidLen
);
1245 MlmeEnqueue(pAd
, SYNC_STATE_MACHINE
, MT2_MLME_START_REQ
, sizeof(MLME_START_REQ_STRUCT
), &StartReq
);
1246 pAd
->Mlme
.CntlMachine
.CurrState
= CNTL_WAIT_START
;
1250 for (i
= 1; i
< MAX_LEN_OF_MAC_TABLE
; i
++)
1252 MAC_TABLE_ENTRY
*pEntry
= &pAd
->MacTab
.Content
[i
];
1254 if (pEntry
->ValidAsCLI
== FALSE
)
1257 if (pEntry
->LastBeaconRxTime
+ ADHOC_BEACON_LOST_TIME
< pAd
->Mlme
.Now32
)
1258 MacTableDeleteEntry(pAd
, pEntry
->Aid
, pEntry
->Addr
);
1262 else // no INFRA nor ADHOC connection
1265 if (pAd
->StaCfg
.bScanReqIsFromWebUI
&&
1266 ((pAd
->StaCfg
.LastScanTime
+ 30 * OS_HZ
) > pAd
->Mlme
.Now32
))
1267 goto SKIP_AUTO_SCAN_CONN
;
1269 pAd
->StaCfg
.bScanReqIsFromWebUI
= FALSE
;
1271 if ((pAd
->StaCfg
.bAutoReconnect
== TRUE
)
1272 && RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_START_UP
)
1273 && (MlmeValidateSSID(pAd
->MlmeAux
.AutoReconnectSsid
, pAd
->MlmeAux
.AutoReconnectSsidLen
) == TRUE
))
1275 if ((pAd
->ScanTab
.BssNr
==0) && (pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_IDLE
))
1277 MLME_SCAN_REQ_STRUCT ScanReq
;
1279 if ((pAd
->StaCfg
.LastScanTime
+ 10 * OS_HZ
) < pAd
->Mlme
.Now32
)
1281 DBGPRINT(RT_DEBUG_TRACE
, ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, start a new ACTIVE scan SSID[%s]\n", pAd
->MlmeAux
.AutoReconnectSsid
));
1282 ScanParmFill(pAd
, &ScanReq
, pAd
->MlmeAux
.AutoReconnectSsid
, pAd
->MlmeAux
.AutoReconnectSsidLen
, BSS_ANY
, SCAN_ACTIVE
);
1283 MlmeEnqueue(pAd
, SYNC_STATE_MACHINE
, MT2_MLME_SCAN_REQ
, sizeof(MLME_SCAN_REQ_STRUCT
), &ScanReq
);
1284 pAd
->Mlme
.CntlMachine
.CurrState
= CNTL_WAIT_OID_LIST_SCAN
;
1285 // Reset Missed scan number
1286 pAd
->StaCfg
.LastScanTime
= pAd
->Mlme
.Now32
;
1288 else if (pAd
->StaCfg
.BssType
== BSS_ADHOC
) // Quit the forever scan when in a very clean room
1289 MlmeAutoReconnectLastSSID(pAd
);
1291 else if (pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_IDLE
)
1293 if ((pAd
->Mlme
.OneSecPeriodicRound
% 7) == 0)
1296 pAd
->StaCfg
.LastScanTime
= pAd
->Mlme
.Now32
;
1300 MlmeAutoReconnectLastSSID(pAd
);
1306 SKIP_AUTO_SCAN_CONN
:
1308 if ((pAd
->MacTab
.Content
[BSSID_WCID
].TXBAbitmap
!=0) && (pAd
->MacTab
.fAnyBASession
== FALSE
))
1310 pAd
->MacTab
.fAnyBASession
= TRUE
;
1311 AsicUpdateProtect(pAd
, HT_FORCERTSCTS
, ALLN_SETPROTECT
, FALSE
, FALSE
);
1313 else if ((pAd
->MacTab
.Content
[BSSID_WCID
].TXBAbitmap
==0) && (pAd
->MacTab
.fAnyBASession
== TRUE
))
1315 pAd
->MacTab
.fAnyBASession
= FALSE
;
1316 AsicUpdateProtect(pAd
, pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
, ALLN_SETPROTECT
, FALSE
, FALSE
);
1324 IN PVOID SystemSpecific1
,
1325 IN PVOID FunctionContext
,
1326 IN PVOID SystemSpecific2
,
1327 IN PVOID SystemSpecific3
)
1330 RTMP_ADAPTER
*pAd
= (RTMP_ADAPTER
*)FunctionContext
;
1332 pAd
->IndicateMediaState
= NdisMediaStateDisconnected
;
1333 RTMP_IndicateMediaState(pAd
);
1334 pAd
->ExtraInfo
= GENERAL_LINK_DOWN
;
1337 // IRQL = DISPATCH_LEVEL
1339 IN PRTMP_ADAPTER pAd
)
1341 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1342 if (pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_IDLE
)
1344 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - Driver auto scan\n"));
1346 MLME_CNTL_STATE_MACHINE
,
1347 OID_802_11_BSSID_LIST_SCAN
,
1350 RT28XX_MLME_HANDLER(pAd
);
1354 // IRQL = DISPATCH_LEVEL
1355 VOID
MlmeAutoReconnectLastSSID(
1356 IN PRTMP_ADAPTER pAd
)
1360 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1361 if ((pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_IDLE
) &&
1362 (MlmeValidateSSID(pAd
->MlmeAux
.AutoReconnectSsid
, pAd
->MlmeAux
.AutoReconnectSsidLen
) == TRUE
))
1364 NDIS_802_11_SSID OidSsid
;
1365 OidSsid
.SsidLength
= pAd
->MlmeAux
.AutoReconnectSsidLen
;
1366 NdisMoveMemory(OidSsid
.Ssid
, pAd
->MlmeAux
.AutoReconnectSsid
, pAd
->MlmeAux
.AutoReconnectSsidLen
);
1368 DBGPRINT(RT_DEBUG_TRACE
, ("Driver auto reconnect to last OID_802_11_SSID setting - %s, len - %d\n", pAd
->MlmeAux
.AutoReconnectSsid
, pAd
->MlmeAux
.AutoReconnectSsidLen
));
1370 MLME_CNTL_STATE_MACHINE
,
1372 sizeof(NDIS_802_11_SSID
),
1374 RT28XX_MLME_HANDLER(pAd
);
1379 ==========================================================================
1380 Validate SSID for connection try and rescan purpose
1381 Valid SSID will have visible chars only.
1382 The valid length is from 0 to 32.
1383 IRQL = DISPATCH_LEVEL
1384 ==========================================================================
1386 BOOLEAN
MlmeValidateSSID(
1392 if (SsidLen
> MAX_LEN_OF_SSID
)
1395 // Check each character value
1396 for (index
= 0; index
< SsidLen
; index
++)
1398 if (pSsid
[index
] < 0x20)
1406 VOID
MlmeSelectTxRateTable(
1407 IN PRTMP_ADAPTER pAd
,
1408 IN PMAC_TABLE_ENTRY pEntry
,
1410 IN PUCHAR pTableSize
,
1411 IN PUCHAR pInitTxRateIdx
)
1415 // decide the rate table for tuning
1416 if (pAd
->CommonCfg
.TxRateTableSize
> 0)
1418 *ppTable
= RateSwitchTable
;
1419 *pTableSize
= RateSwitchTable
[0];
1420 *pInitTxRateIdx
= RateSwitchTable
[1];
1425 if ((pAd
->OpMode
== OPMODE_STA
) && ADHOC_ON(pAd
))
1427 if ((pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
) &&
1429 !pAd
->StaCfg
.AdhocBOnlyJoined
&&
1430 !pAd
->StaCfg
.AdhocBGJoined
&&
1431 (pAd
->StaActive
.SupportedPhyInfo
.MCSSet
[0] == 0xff) &&
1432 ((pAd
->StaActive
.SupportedPhyInfo
.MCSSet
[1] == 0x00) || (pAd
->Antenna
.field
.TxPath
== 1)))
1435 (pEntry
->HTCapability
.MCSSet
[0] == 0xff) &&
1436 ((pEntry
->HTCapability
.MCSSet
[1] == 0x00) || (pAd
->Antenna
.field
.TxPath
== 1)))
1439 *ppTable
= RateSwitchTable11N1S
;
1440 *pTableSize
= RateSwitchTable11N1S
[0];
1441 *pInitTxRateIdx
= RateSwitchTable11N1S
[1];
1444 else if ((pAd
->CommonCfg
.PhyMode
>= PHY_11ABGN_MIXED
) &&
1446 !pAd
->StaCfg
.AdhocBOnlyJoined
&&
1447 !pAd
->StaCfg
.AdhocBGJoined
&&
1448 (pAd
->StaActive
.SupportedPhyInfo
.MCSSet
[0] == 0xff) &&
1449 (pAd
->StaActive
.SupportedPhyInfo
.MCSSet
[1] == 0xff) &&
1452 (pEntry
->HTCapability
.MCSSet
[0] == 0xff) &&
1453 (pEntry
->HTCapability
.MCSSet
[1] == 0xff) &&
1455 (pAd
->Antenna
.field
.TxPath
== 2))
1457 if (pAd
->LatchRfRegs
.Channel
<= 14)
1459 *ppTable
= RateSwitchTable11N2S
;
1460 *pTableSize
= RateSwitchTable11N2S
[0];
1461 *pInitTxRateIdx
= RateSwitchTable11N2S
[1];
1465 *ppTable
= RateSwitchTable11N2SForABand
;
1466 *pTableSize
= RateSwitchTable11N2SForABand
[0];
1467 *pInitTxRateIdx
= RateSwitchTable11N2SForABand
[1];
1473 if (pAd
->CommonCfg
.PhyMode
== PHY_11B
)
1475 *ppTable
= RateSwitchTable11B
;
1476 *pTableSize
= RateSwitchTable11B
[0];
1477 *pInitTxRateIdx
= RateSwitchTable11B
[1];
1480 else if((pAd
->LatchRfRegs
.Channel
<= 14) && (pAd
->StaCfg
.AdhocBOnlyJoined
== TRUE
))
1483 if ((pEntry
->RateLen
== 4)
1484 && (pEntry
->HTCapability
.MCSSet
[0] == 0) && (pEntry
->HTCapability
.MCSSet
[1] == 0)
1488 // USe B Table when Only b-only Station in my IBSS .
1489 *ppTable
= RateSwitchTable11B
;
1490 *pTableSize
= RateSwitchTable11B
[0];
1491 *pInitTxRateIdx
= RateSwitchTable11B
[1];
1494 else if (pAd
->LatchRfRegs
.Channel
<= 14)
1496 *ppTable
= RateSwitchTable11BG
;
1497 *pTableSize
= RateSwitchTable11BG
[0];
1498 *pInitTxRateIdx
= RateSwitchTable11BG
[1];
1503 *ppTable
= RateSwitchTable11G
;
1504 *pTableSize
= RateSwitchTable11G
[0];
1505 *pInitTxRateIdx
= RateSwitchTable11G
[1];
1511 if ((pEntry
->RateLen
== 12) && (pEntry
->HTCapability
.MCSSet
[0] == 0xff) &&
1512 ((pEntry
->HTCapability
.MCSSet
[1] == 0x00) || (pAd
->CommonCfg
.TxStream
== 1)))
1514 *ppTable
= RateSwitchTable11BGN1S
;
1515 *pTableSize
= RateSwitchTable11BGN1S
[0];
1516 *pInitTxRateIdx
= RateSwitchTable11BGN1S
[1];
1521 if ((pEntry
->RateLen
== 12) && (pEntry
->HTCapability
.MCSSet
[0] == 0xff) &&
1522 (pEntry
->HTCapability
.MCSSet
[1] == 0xff) && (pAd
->CommonCfg
.TxStream
== 2))
1524 if (pAd
->LatchRfRegs
.Channel
<= 14)
1526 *ppTable
= RateSwitchTable11BGN2S
;
1527 *pTableSize
= RateSwitchTable11BGN2S
[0];
1528 *pInitTxRateIdx
= RateSwitchTable11BGN2S
[1];
1533 *ppTable
= RateSwitchTable11BGN2SForABand
;
1534 *pTableSize
= RateSwitchTable11BGN2SForABand
[0];
1535 *pInitTxRateIdx
= RateSwitchTable11BGN2SForABand
[1];
1541 if ((pEntry
->HTCapability
.MCSSet
[0] == 0xff) && ((pEntry
->HTCapability
.MCSSet
[1] == 0x00) || (pAd
->CommonCfg
.TxStream
== 1)))
1543 *ppTable
= RateSwitchTable11N1S
;
1544 *pTableSize
= RateSwitchTable11N1S
[0];
1545 *pInitTxRateIdx
= RateSwitchTable11N1S
[1];
1550 if ((pEntry
->HTCapability
.MCSSet
[0] == 0xff) && (pEntry
->HTCapability
.MCSSet
[1] == 0xff) && (pAd
->CommonCfg
.TxStream
== 2))
1552 if (pAd
->LatchRfRegs
.Channel
<= 14)
1554 *ppTable
= RateSwitchTable11N2S
;
1555 *pTableSize
= RateSwitchTable11N2S
[0];
1556 *pInitTxRateIdx
= RateSwitchTable11N2S
[1];
1560 *ppTable
= RateSwitchTable11N2SForABand
;
1561 *pTableSize
= RateSwitchTable11N2SForABand
[0];
1562 *pInitTxRateIdx
= RateSwitchTable11N2SForABand
[1];
1568 //else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1569 if (pEntry
->RateLen
== 4)
1571 *ppTable
= RateSwitchTable11B
;
1572 *pTableSize
= RateSwitchTable11B
[0];
1573 *pInitTxRateIdx
= RateSwitchTable11B
[1];
1578 //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1579 if ((pEntry
->RateLen
> 8)
1580 && (pEntry
->HTCapability
.MCSSet
[0] == 0) && (pEntry
->HTCapability
.MCSSet
[1] == 0)
1583 *ppTable
= RateSwitchTable11BG
;
1584 *pTableSize
= RateSwitchTable11BG
[0];
1585 *pInitTxRateIdx
= RateSwitchTable11BG
[1];
1590 //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1591 if ((pEntry
->RateLen
== 8)
1592 && (pEntry
->HTCapability
.MCSSet
[0] == 0) && (pEntry
->HTCapability
.MCSSet
[1] == 0)
1595 *ppTable
= RateSwitchTable11G
;
1596 *pTableSize
= RateSwitchTable11G
[0];
1597 *pInitTxRateIdx
= RateSwitchTable11G
[1];
1603 //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1604 if ((pEntry
->HTCapability
.MCSSet
[0] == 0) && (pEntry
->HTCapability
.MCSSet
[1] == 0))
1606 if (pAd
->CommonCfg
.MaxTxRate
<= RATE_11
)
1608 *ppTable
= RateSwitchTable11B
;
1609 *pTableSize
= RateSwitchTable11B
[0];
1610 *pInitTxRateIdx
= RateSwitchTable11B
[1];
1612 else if ((pAd
->CommonCfg
.MaxTxRate
> RATE_11
) && (pAd
->CommonCfg
.MinTxRate
> RATE_11
))
1614 *ppTable
= RateSwitchTable11G
;
1615 *pTableSize
= RateSwitchTable11G
[0];
1616 *pInitTxRateIdx
= RateSwitchTable11G
[1];
1621 *ppTable
= RateSwitchTable11BG
;
1622 *pTableSize
= RateSwitchTable11BG
[0];
1623 *pInitTxRateIdx
= RateSwitchTable11BG
[1];
1628 if (pAd
->LatchRfRegs
.Channel
<= 14)
1630 if (pAd
->CommonCfg
.TxStream
== 1)
1632 *ppTable
= RateSwitchTable11N1S
;
1633 *pTableSize
= RateSwitchTable11N1S
[0];
1634 *pInitTxRateIdx
= RateSwitchTable11N1S
[1];
1635 DBGPRINT_RAW(RT_DEBUG_ERROR
,("DRS: unkown mode,default use 11N 1S AP \n"));
1639 *ppTable
= RateSwitchTable11N2S
;
1640 *pTableSize
= RateSwitchTable11N2S
[0];
1641 *pInitTxRateIdx
= RateSwitchTable11N2S
[1];
1642 DBGPRINT_RAW(RT_DEBUG_ERROR
,("DRS: unkown mode,default use 11N 2S AP \n"));
1647 if (pAd
->CommonCfg
.TxStream
== 1)
1649 *ppTable
= RateSwitchTable11N1S
;
1650 *pTableSize
= RateSwitchTable11N1S
[0];
1651 *pInitTxRateIdx
= RateSwitchTable11N1S
[1];
1652 DBGPRINT_RAW(RT_DEBUG_ERROR
,("DRS: unkown mode,default use 11N 1S AP \n"));
1656 *ppTable
= RateSwitchTable11N2SForABand
;
1657 *pTableSize
= RateSwitchTable11N2SForABand
[0];
1658 *pInitTxRateIdx
= RateSwitchTable11N2SForABand
[1];
1659 DBGPRINT_RAW(RT_DEBUG_ERROR
,("DRS: unkown mode,default use 11N 2S AP \n"));
1663 DBGPRINT_RAW(RT_DEBUG_ERROR
,("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n",
1664 pAd
->StaActive
.SupRateLen
, pAd
->StaActive
.ExtRateLen
, pAd
->StaActive
.SupportedPhyInfo
.MCSSet
[0], pAd
->StaActive
.SupportedPhyInfo
.MCSSet
[1]));
1670 ==========================================================================
1672 This routine checks if there're other APs out there capable for
1673 roaming. Caller should call this routine only when Link up in INFRA mode
1674 and channel quality is below CQI_GOOD_THRESHOLD.
1676 IRQL = DISPATCH_LEVEL
1679 ==========================================================================
1681 VOID
MlmeCheckForRoaming(
1682 IN PRTMP_ADAPTER pAd
,
1686 BSS_TABLE
*pRoamTab
= &pAd
->MlmeAux
.RoamTab
;
1689 DBGPRINT(RT_DEBUG_TRACE
, ("==> MlmeCheckForRoaming\n"));
1690 // put all roaming candidates into RoamTab, and sort in RSSI order
1691 BssTableInit(pRoamTab
);
1692 for (i
= 0; i
< pAd
->ScanTab
.BssNr
; i
++)
1694 pBss
= &pAd
->ScanTab
.BssEntry
[i
];
1696 if ((pBss
->LastBeaconRxTime
+ BEACON_LOST_TIME
) < Now32
)
1697 continue; // AP disappear
1698 if (pBss
->Rssi
<= RSSI_THRESHOLD_FOR_ROAMING
)
1699 continue; // RSSI too weak. forget it.
1700 if (MAC_ADDR_EQUAL(pBss
->Bssid
, pAd
->CommonCfg
.Bssid
))
1701 continue; // skip current AP
1702 if (pBss
->Rssi
< (pAd
->StaCfg
.RssiSample
.LastRssi0
+ RSSI_DELTA
))
1703 continue; // only AP with stronger RSSI is eligible for roaming
1705 // AP passing all above rules is put into roaming candidate table
1706 NdisMoveMemory(&pRoamTab
->BssEntry
[pRoamTab
->BssNr
], pBss
, sizeof(BSS_ENTRY
));
1707 pRoamTab
->BssNr
+= 1;
1710 if (pRoamTab
->BssNr
> 0)
1712 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1713 if (pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_IDLE
)
1715 pAd
->RalinkCounters
.PoorCQIRoamingCount
++;
1716 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - Roaming attempt #%ld\n", pAd
->RalinkCounters
.PoorCQIRoamingCount
));
1717 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_MLME_ROAMING_REQ
, 0, NULL
);
1718 RT28XX_MLME_HANDLER(pAd
);
1721 DBGPRINT(RT_DEBUG_TRACE
, ("<== MlmeCheckForRoaming(# of candidate= %d)\n",pRoamTab
->BssNr
));
1725 ==========================================================================
1727 This routine checks if there're other APs out there capable for
1728 roaming. Caller should call this routine only when link up in INFRA mode
1729 and channel quality is below CQI_GOOD_THRESHOLD.
1731 IRQL = DISPATCH_LEVEL
1734 ==========================================================================
1736 VOID
MlmeCheckForFastRoaming(
1737 IN PRTMP_ADAPTER pAd
,
1741 BSS_TABLE
*pRoamTab
= &pAd
->MlmeAux
.RoamTab
;
1744 DBGPRINT(RT_DEBUG_TRACE
, ("==> MlmeCheckForFastRoaming\n"));
1745 // put all roaming candidates into RoamTab, and sort in RSSI order
1746 BssTableInit(pRoamTab
);
1747 for (i
= 0; i
< pAd
->ScanTab
.BssNr
; i
++)
1749 pBss
= &pAd
->ScanTab
.BssEntry
[i
];
1751 if ((pBss
->Rssi
<= -50) && (pBss
->Channel
== pAd
->CommonCfg
.Channel
))
1752 continue; // RSSI too weak. forget it.
1753 if (MAC_ADDR_EQUAL(pBss
->Bssid
, pAd
->CommonCfg
.Bssid
))
1754 continue; // skip current AP
1755 if (!SSID_EQUAL(pBss
->Ssid
, pBss
->SsidLen
, pAd
->CommonCfg
.Ssid
, pAd
->CommonCfg
.SsidLen
))
1756 continue; // skip different SSID
1757 if (pBss
->Rssi
< (RTMPMaxRssi(pAd
, pAd
->StaCfg
.RssiSample
.LastRssi0
, pAd
->StaCfg
.RssiSample
.LastRssi1
, pAd
->StaCfg
.RssiSample
.LastRssi2
) + RSSI_DELTA
))
1758 continue; // skip AP without better RSSI
1760 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
));
1761 // AP passing all above rules is put into roaming candidate table
1762 NdisMoveMemory(&pRoamTab
->BssEntry
[pRoamTab
->BssNr
], pBss
, sizeof(BSS_ENTRY
));
1763 pRoamTab
->BssNr
+= 1;
1766 if (pRoamTab
->BssNr
> 0)
1768 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1769 if (pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_IDLE
)
1771 pAd
->RalinkCounters
.PoorCQIRoamingCount
++;
1772 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - Roaming attempt #%ld\n", pAd
->RalinkCounters
.PoorCQIRoamingCount
));
1773 MlmeEnqueue(pAd
, MLME_CNTL_STATE_MACHINE
, MT2_MLME_ROAMING_REQ
, 0, NULL
);
1774 RT28XX_MLME_HANDLER(pAd
);
1777 // Maybe site survey required
1780 if ((pAd
->StaCfg
.LastScanTime
+ 10 * 1000) < Now
)
1782 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1783 DBGPRINT(RT_DEBUG_TRACE
, ("MMCHK - Roaming, No eligable entry, try new scan!\n"));
1784 pAd
->StaCfg
.ScanCnt
= 2;
1785 pAd
->StaCfg
.LastScanTime
= Now
;
1790 DBGPRINT(RT_DEBUG_TRACE
, ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab
->BssNr
));
1794 ==========================================================================
1796 This routine calculates TxPER, RxPER of the past N-sec period. And
1797 according to the calculation result, ChannelQuality is calculated here
1798 to decide if current AP is still doing the job.
1800 If ChannelQuality is not good, a ROAMing attempt may be tried later.
1802 StaCfg.ChannelQuality - 0..100
1804 IRQL = DISPATCH_LEVEL
1806 NOTE: This routine decide channle quality based on RX CRC error ratio.
1807 Caller should make sure a function call to NICUpdateRawCounters(pAd)
1808 is performed right before this routine, so that this routine can decide
1809 channel quality based on the most up-to-date information
1810 ==========================================================================
1812 VOID
MlmeCalculateChannelQuality(
1813 IN PRTMP_ADAPTER pAd
,
1816 ULONG TxOkCnt
, TxCnt
, TxPER
, TxPRR
;
1820 ULONG BeaconLostTime
= BEACON_LOST_TIME
;
1822 MaxRssi
= RTMPMaxRssi(pAd
, pAd
->StaCfg
.RssiSample
.LastRssi0
, pAd
->StaCfg
.RssiSample
.LastRssi1
, pAd
->StaCfg
.RssiSample
.LastRssi2
);
1825 // calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics
1827 TxOkCnt
= pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
+ pAd
->RalinkCounters
.OneSecTxRetryOkCount
;
1828 TxCnt
= TxOkCnt
+ pAd
->RalinkCounters
.OneSecTxFailCount
;
1836 TxPER
= (pAd
->RalinkCounters
.OneSecTxFailCount
* 100) / TxCnt
;
1837 TxPRR
= ((TxCnt
- pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
) * 100) / TxCnt
;
1841 // calculate RX PER - don't take RxPER into consideration if too few sample
1843 RxCnt
= pAd
->RalinkCounters
.OneSecRxOkCnt
+ pAd
->RalinkCounters
.OneSecRxFcsErrCnt
;
1847 RxPER
= (pAd
->RalinkCounters
.OneSecRxFcsErrCnt
* 100) / RxCnt
;
1850 // decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER
1852 if (INFRA_ON(pAd
) &&
1853 (pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
< 2) && // no heavy traffic
1854 (pAd
->StaCfg
.LastBeaconRxTime
+ BeaconLostTime
< Now32
))
1856 DBGPRINT(RT_DEBUG_TRACE
, ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n", BeaconLostTime
, TxOkCnt
));
1857 pAd
->Mlme
.ChannelQuality
= 0;
1864 else if (MaxRssi
< -90)
1867 NorRssi
= (MaxRssi
+ 90) * 2;
1869 // ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER (RSSI 0..100), (TxPER 100..0), (RxPER 100..0)
1870 pAd
->Mlme
.ChannelQuality
= (RSSI_WEIGHTING
* NorRssi
+
1871 TX_WEIGHTING
* (100 - TxPRR
) +
1872 RX_WEIGHTING
* (100 - RxPER
)) / 100;
1873 if (pAd
->Mlme
.ChannelQuality
>= 100)
1874 pAd
->Mlme
.ChannelQuality
= 100;
1880 IN PRTMP_ADAPTER pAd
,
1881 IN PMAC_TABLE_ENTRY pEntry
,
1882 IN PRTMP_TX_RATE_SWITCH pTxRate
)
1884 UCHAR MaxMode
= MODE_OFDM
;
1886 MaxMode
= MODE_HTGREENFIELD
;
1888 if (pTxRate
->STBC
&& (pAd
->StaCfg
.MaxHTPhyMode
.field
.STBC
) && (pAd
->Antenna
.field
.TxPath
== 2))
1889 pAd
->StaCfg
.HTPhyMode
.field
.STBC
= STBC_USE
;
1891 pAd
->StaCfg
.HTPhyMode
.field
.STBC
= STBC_NONE
;
1893 if (pTxRate
->CurrMCS
< MCS_AUTO
)
1894 pAd
->StaCfg
.HTPhyMode
.field
.MCS
= pTxRate
->CurrMCS
;
1896 if (pAd
->StaCfg
.HTPhyMode
.field
.MCS
> 7)
1897 pAd
->StaCfg
.HTPhyMode
.field
.STBC
= STBC_NONE
;
1901 // If peer adhoc is b-only mode, we can't send 11g rate.
1902 pAd
->StaCfg
.HTPhyMode
.field
.ShortGI
= GI_800
;
1903 pEntry
->HTPhyMode
.field
.STBC
= STBC_NONE
;
1906 // For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary
1908 pEntry
->HTPhyMode
.field
.MODE
= pTxRate
->Mode
;
1909 pEntry
->HTPhyMode
.field
.ShortGI
= pAd
->StaCfg
.HTPhyMode
.field
.ShortGI
;
1910 pEntry
->HTPhyMode
.field
.MCS
= pAd
->StaCfg
.HTPhyMode
.field
.MCS
;
1912 // Patch speed error in status page
1913 pAd
->StaCfg
.HTPhyMode
.field
.MODE
= pEntry
->HTPhyMode
.field
.MODE
;
1917 if (pTxRate
->Mode
<= MaxMode
)
1918 pAd
->StaCfg
.HTPhyMode
.field
.MODE
= pTxRate
->Mode
;
1920 if (pTxRate
->ShortGI
&& (pAd
->StaCfg
.MaxHTPhyMode
.field
.ShortGI
))
1921 pAd
->StaCfg
.HTPhyMode
.field
.ShortGI
= GI_400
;
1923 pAd
->StaCfg
.HTPhyMode
.field
.ShortGI
= GI_800
;
1925 // Reexam each bandwidth's SGI support.
1926 if (pAd
->StaCfg
.HTPhyMode
.field
.ShortGI
== GI_400
)
1928 if ((pEntry
->HTPhyMode
.field
.BW
== BW_20
) && (!CLIENT_STATUS_TEST_FLAG(pEntry
, fCLIENT_STATUS_SGI20_CAPABLE
)))
1929 pAd
->StaCfg
.HTPhyMode
.field
.ShortGI
= GI_800
;
1930 if ((pEntry
->HTPhyMode
.field
.BW
== BW_40
) && (!CLIENT_STATUS_TEST_FLAG(pEntry
, fCLIENT_STATUS_SGI40_CAPABLE
)))
1931 pAd
->StaCfg
.HTPhyMode
.field
.ShortGI
= GI_800
;
1934 // Turn RTS/CTS rate to 6Mbps.
1935 if ((pEntry
->HTPhyMode
.field
.MCS
== 0) && (pAd
->StaCfg
.HTPhyMode
.field
.MCS
!= 0))
1937 pEntry
->HTPhyMode
.field
.MCS
= pAd
->StaCfg
.HTPhyMode
.field
.MCS
;
1938 if (pAd
->MacTab
.fAnyBASession
)
1940 AsicUpdateProtect(pAd
, HT_FORCERTSCTS
, ALLN_SETPROTECT
, TRUE
, (BOOLEAN
)pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
);
1944 AsicUpdateProtect(pAd
, pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
, ALLN_SETPROTECT
, TRUE
, (BOOLEAN
)pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
);
1947 else if ((pEntry
->HTPhyMode
.field
.MCS
== 8) && (pAd
->StaCfg
.HTPhyMode
.field
.MCS
!= 8))
1949 pEntry
->HTPhyMode
.field
.MCS
= pAd
->StaCfg
.HTPhyMode
.field
.MCS
;
1950 if (pAd
->MacTab
.fAnyBASession
)
1952 AsicUpdateProtect(pAd
, HT_FORCERTSCTS
, ALLN_SETPROTECT
, TRUE
, (BOOLEAN
)pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
);
1956 AsicUpdateProtect(pAd
, pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.OperaionMode
, ALLN_SETPROTECT
, TRUE
, (BOOLEAN
)pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
);
1959 else if ((pEntry
->HTPhyMode
.field
.MCS
!= 0) && (pAd
->StaCfg
.HTPhyMode
.field
.MCS
== 0))
1961 AsicUpdateProtect(pAd
, HT_RTSCTS_6M
, ALLN_SETPROTECT
, TRUE
, (BOOLEAN
)pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
);
1964 else if ((pEntry
->HTPhyMode
.field
.MCS
!= 8) && (pAd
->StaCfg
.HTPhyMode
.field
.MCS
== 8))
1966 AsicUpdateProtect(pAd
, HT_RTSCTS_6M
, ALLN_SETPROTECT
, TRUE
, (BOOLEAN
)pAd
->MlmeAux
.AddHtInfo
.AddHtInfo2
.NonGfPresent
);
1969 pEntry
->HTPhyMode
.field
.STBC
= pAd
->StaCfg
.HTPhyMode
.field
.STBC
;
1970 pEntry
->HTPhyMode
.field
.ShortGI
= pAd
->StaCfg
.HTPhyMode
.field
.ShortGI
;
1971 pEntry
->HTPhyMode
.field
.MCS
= pAd
->StaCfg
.HTPhyMode
.field
.MCS
;
1972 pEntry
->HTPhyMode
.field
.MODE
= pAd
->StaCfg
.HTPhyMode
.field
.MODE
;
1974 if ((pAd
->StaCfg
.MaxHTPhyMode
.field
.MODE
== MODE_HTGREENFIELD
) &&
1975 pAd
->WIFItestbed
.bGreenField
)
1976 pEntry
->HTPhyMode
.field
.MODE
= MODE_HTGREENFIELD
;
1979 pAd
->LastTxRate
= (USHORT
)(pEntry
->HTPhyMode
.word
);
1983 ==========================================================================
1985 This routine calculates the acumulated TxPER of eaxh TxRate. And
1986 according to the calculation result, change CommonCfg.TxRate which
1987 is the stable TX Rate we expect the Radio situation could sustained.
1989 CommonCfg.TxRate will change dynamically within {RATE_1/RATE_6, MaxTxRate}
1993 IRQL = DISPATCH_LEVEL
1996 call this routine every second
1997 ==========================================================================
1999 VOID
MlmeDynamicTxRateSwitching(
2000 IN PRTMP_ADAPTER pAd
)
2002 UCHAR UpRateIdx
= 0, DownRateIdx
= 0, CurrRateIdx
;
2003 ULONG i
, AccuTxTotalCnt
= 0, TxTotalCnt
;
2004 ULONG TxErrorRatio
= 0;
2005 BOOLEAN bTxRateChanged
, bUpgradeQuality
= FALSE
;
2006 PRTMP_TX_RATE_SWITCH pCurrTxRate
, pNextTxRate
= NULL
;
2008 UCHAR TableSize
= 0;
2009 UCHAR InitTxRateIdx
= 0, TrainUp
, TrainDown
;
2010 CHAR Rssi
, RssiOffset
= 0;
2011 TX_STA_CNT1_STRUC StaTx1
;
2012 TX_STA_CNT0_STRUC TxStaCnt0
;
2013 ULONG TxRetransmit
= 0, TxSuccess
= 0, TxFailCount
= 0;
2014 MAC_TABLE_ENTRY
*pEntry
;
2017 // walk through MAC table, see if need to change AP's TX rate toward each entry
2019 for (i
= 1; i
< MAX_LEN_OF_MAC_TABLE
; i
++)
2021 pEntry
= &pAd
->MacTab
.Content
[i
];
2023 // check if this entry need to switch rate automatically
2024 if (RTMPCheckEntryEnableAutoRateSwitch(pAd
, pEntry
) == FALSE
)
2027 if ((pAd
->MacTab
.Size
== 1) || (pEntry
->ValidAsDls
))
2030 Rssi
= RTMPMaxRssi(pAd
, (CHAR
)pAd
->StaCfg
.RssiSample
.AvgRssi0
, (CHAR
)pAd
->StaCfg
.RssiSample
.AvgRssi1
, (CHAR
)pAd
->StaCfg
.RssiSample
.AvgRssi2
);
2033 Rssi
= RTMPMaxRssi(pAd
,
2034 pAd
->StaCfg
.RssiSample
.AvgRssi0
,
2035 pAd
->StaCfg
.RssiSample
.AvgRssi1
,
2036 pAd
->StaCfg
.RssiSample
.AvgRssi2
);
2039 // Update statistic counter
2040 RTMP_IO_READ32(pAd
, TX_STA_CNT0
, &TxStaCnt0
.word
);
2041 RTMP_IO_READ32(pAd
, TX_STA_CNT1
, &StaTx1
.word
);
2042 pAd
->bUpdateBcnCntDone
= TRUE
;
2043 TxRetransmit
= StaTx1
.field
.TxRetransmit
;
2044 TxSuccess
= StaTx1
.field
.TxSuccess
;
2045 TxFailCount
= TxStaCnt0
.field
.TxFailCount
;
2046 TxTotalCnt
= TxRetransmit
+ TxSuccess
+ TxFailCount
;
2048 pAd
->RalinkCounters
.OneSecTxRetryOkCount
+= StaTx1
.field
.TxRetransmit
;
2049 pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
+= StaTx1
.field
.TxSuccess
;
2050 pAd
->RalinkCounters
.OneSecTxFailCount
+= TxStaCnt0
.field
.TxFailCount
;
2051 pAd
->WlanCounters
.TransmittedFragmentCount
.u
.LowPart
+= StaTx1
.field
.TxSuccess
;
2052 pAd
->WlanCounters
.RetryCount
.u
.LowPart
+= StaTx1
.field
.TxRetransmit
;
2053 pAd
->WlanCounters
.FailedCount
.u
.LowPart
+= TxStaCnt0
.field
.TxFailCount
;
2055 // if no traffic in the past 1-sec period, don't change TX rate,
2056 // but clear all bad history. because the bad history may affect the next
2057 // Chariot throughput test
2058 AccuTxTotalCnt
= pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
+
2059 pAd
->RalinkCounters
.OneSecTxRetryOkCount
+
2060 pAd
->RalinkCounters
.OneSecTxFailCount
;
2063 TxErrorRatio
= ((TxRetransmit
+ TxFailCount
) * 100) / TxTotalCnt
;
2068 Rssi
= RTMPMaxRssi(pAd
, (CHAR
)pEntry
->RssiSample
.AvgRssi0
, (CHAR
)pEntry
->RssiSample
.AvgRssi1
, (CHAR
)pEntry
->RssiSample
.AvgRssi2
);
2071 if (INFRA_ON(pAd
) && (i
== 1))
2072 Rssi
= RTMPMaxRssi(pAd
,
2073 pAd
->StaCfg
.RssiSample
.AvgRssi0
,
2074 pAd
->StaCfg
.RssiSample
.AvgRssi1
,
2075 pAd
->StaCfg
.RssiSample
.AvgRssi2
);
2077 Rssi
= RTMPMaxRssi(pAd
,
2078 pEntry
->RssiSample
.AvgRssi0
,
2079 pEntry
->RssiSample
.AvgRssi1
,
2080 pEntry
->RssiSample
.AvgRssi2
);
2083 TxTotalCnt
= pEntry
->OneSecTxNoRetryOkCount
+
2084 pEntry
->OneSecTxRetryOkCount
+
2085 pEntry
->OneSecTxFailCount
;
2088 TxErrorRatio
= ((pEntry
->OneSecTxRetryOkCount
+ pEntry
->OneSecTxFailCount
) * 100) / TxTotalCnt
;
2091 CurrRateIdx
= pEntry
->CurrTxRateIndex
;
2093 MlmeSelectTxRateTable(pAd
, pEntry
, &pTable
, &TableSize
, &InitTxRateIdx
);
2095 if (CurrRateIdx
>= TableSize
)
2097 CurrRateIdx
= TableSize
- 1;
2100 // When switch from Fixed rate -> auto rate, the REAL TX rate might be different from pAd->CommonCfg.TxRateIndex.
2101 // So need to sync here.
2102 pCurrTxRate
= (PRTMP_TX_RATE_SWITCH
) &pTable
[(CurrRateIdx
+1)*5];
2103 if ((pEntry
->HTPhyMode
.field
.MCS
!= pCurrTxRate
->CurrMCS
)
2104 //&& (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
2108 // Need to sync Real Tx rate and our record.
2109 // Then return for next DRS.
2110 pCurrTxRate
= (PRTMP_TX_RATE_SWITCH
) &pTable
[(InitTxRateIdx
+1)*5];
2111 pEntry
->CurrTxRateIndex
= InitTxRateIdx
;
2112 MlmeSetTxRate(pAd
, pEntry
, pCurrTxRate
);
2114 // reset all OneSecTx counters
2115 RESET_ONE_SEC_TX_CNT(pEntry
);
2119 // decide the next upgrade rate and downgrade rate, if any
2120 if ((CurrRateIdx
> 0) && (CurrRateIdx
< (TableSize
- 1)))
2122 UpRateIdx
= CurrRateIdx
+ 1;
2123 DownRateIdx
= CurrRateIdx
-1;
2125 else if (CurrRateIdx
== 0)
2127 UpRateIdx
= CurrRateIdx
+ 1;
2128 DownRateIdx
= CurrRateIdx
;
2130 else if (CurrRateIdx
== (TableSize
- 1))
2132 UpRateIdx
= CurrRateIdx
;
2133 DownRateIdx
= CurrRateIdx
- 1;
2136 pCurrTxRate
= (PRTMP_TX_RATE_SWITCH
) &pTable
[(CurrRateIdx
+1)*5];
2138 if ((Rssi
> -65) && (pCurrTxRate
->Mode
>= MODE_HTMIX
))
2140 TrainUp
= (pCurrTxRate
->TrainUp
+ (pCurrTxRate
->TrainUp
>> 1));
2141 TrainDown
= (pCurrTxRate
->TrainDown
+ (pCurrTxRate
->TrainDown
>> 1));
2145 TrainUp
= pCurrTxRate
->TrainUp
;
2146 TrainDown
= pCurrTxRate
->TrainDown
;
2149 //pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction;
2152 // Keep the last time TxRateChangeAction status.
2154 pEntry
->LastTimeTxRateChangeAction
= pEntry
->LastSecTxRateChangeAction
;
2159 // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
2160 // (criteria copied from RT2500 for Netopia case)
2162 if (TxTotalCnt
<= 15)
2166 //UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS7 = 0, MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
2167 UCHAR MCS0
= 0, MCS1
= 0, MCS2
= 0, MCS3
= 0, MCS4
= 0, MCS5
=0, MCS6
= 0, MCS7
= 0;
2168 UCHAR MCS12
= 0, MCS13
= 0, MCS14
= 0, MCS15
= 0;
2169 UCHAR MCS20
= 0, MCS21
= 0, MCS22
= 0, MCS23
= 0; // 3*3
2171 // check the existence and index of each needed MCS
2172 while (idx
< pTable
[0])
2174 pCurrTxRate
= (PRTMP_TX_RATE_SWITCH
) &pTable
[(idx
+1)*5];
2176 if (pCurrTxRate
->CurrMCS
== MCS_0
)
2180 else if (pCurrTxRate
->CurrMCS
== MCS_1
)
2184 else if (pCurrTxRate
->CurrMCS
== MCS_2
)
2188 else if (pCurrTxRate
->CurrMCS
== MCS_3
)
2192 else if (pCurrTxRate
->CurrMCS
== MCS_4
)
2196 else if (pCurrTxRate
->CurrMCS
== MCS_5
)
2200 else if (pCurrTxRate
->CurrMCS
== MCS_6
)
2204 //else if (pCurrTxRate->CurrMCS == MCS_7)
2205 else if ((pCurrTxRate
->CurrMCS
== MCS_7
) && (pCurrTxRate
->ShortGI
== GI_800
)) // prevent the highest MCS using short GI when 1T and low throughput
2209 else if (pCurrTxRate
->CurrMCS
== MCS_12
)
2213 else if (pCurrTxRate
->CurrMCS
== MCS_13
)
2217 else if (pCurrTxRate
->CurrMCS
== MCS_14
)
2221 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
2225 else if (pCurrTxRate
->CurrMCS
== MCS_20
) // 3*3
2229 else if (pCurrTxRate
->CurrMCS
== MCS_21
)
2233 else if (pCurrTxRate
->CurrMCS
== MCS_22
)
2237 else if (pCurrTxRate
->CurrMCS
== MCS_23
)
2244 if (pAd
->LatchRfRegs
.Channel
<= 14)
2246 if (pAd
->NicConfig2
.field
.ExternalLNAForG
)
2257 if (pAd
->NicConfig2
.field
.ExternalLNAForA
)
2268 if ((pTable
== RateSwitchTable11BGN3S
) ||
2269 (pTable
== RateSwitchTable11N3S
) ||
2270 (pTable
== RateSwitchTable
))
2271 {// N mode with 3 stream // 3*3
2272 if (MCS23
&& (Rssi
>= -70))
2274 else if (MCS22
&& (Rssi
>= -72))
2276 else if (MCS21
&& (Rssi
>= -76))
2278 else if (MCS20
&& (Rssi
>= -78))
2280 else if (MCS4
&& (Rssi
>= -82))
2282 else if (MCS3
&& (Rssi
>= -84))
2284 else if (MCS2
&& (Rssi
>= -86))
2286 else if (MCS1
&& (Rssi
>= -88))
2291 else if ((pTable
== RateSwitchTable11BGN2S
) || (pTable
== RateSwitchTable11BGN2SForABand
) ||(pTable
== RateSwitchTable11N2S
) ||(pTable
== RateSwitchTable11N2SForABand
)) // 3*3
2292 {// N mode with 2 stream
2293 if (MCS15
&& (Rssi
>= (-70+RssiOffset
)))
2295 else if (MCS14
&& (Rssi
>= (-72+RssiOffset
)))
2297 else if (MCS13
&& (Rssi
>= (-76+RssiOffset
)))
2299 else if (MCS12
&& (Rssi
>= (-78+RssiOffset
)))
2301 else if (MCS4
&& (Rssi
>= (-82+RssiOffset
)))
2303 else if (MCS3
&& (Rssi
>= (-84+RssiOffset
)))
2305 else if (MCS2
&& (Rssi
>= (-86+RssiOffset
)))
2307 else if (MCS1
&& (Rssi
>= (-88+RssiOffset
)))
2312 else if ((pTable
== RateSwitchTable11BGN1S
) || (pTable
== RateSwitchTable11N1S
))
2313 {// N mode with 1 stream
2314 if (MCS7
&& (Rssi
> (-72+RssiOffset
)))
2316 else if (MCS6
&& (Rssi
> (-74+RssiOffset
)))
2318 else if (MCS5
&& (Rssi
> (-77+RssiOffset
)))
2320 else if (MCS4
&& (Rssi
> (-79+RssiOffset
)))
2322 else if (MCS3
&& (Rssi
> (-81+RssiOffset
)))
2324 else if (MCS2
&& (Rssi
> (-83+RssiOffset
)))
2326 else if (MCS1
&& (Rssi
> (-86+RssiOffset
)))
2333 if (MCS7
&& (Rssi
> -70))
2335 else if (MCS6
&& (Rssi
> -74))
2337 else if (MCS5
&& (Rssi
> -78))
2339 else if (MCS4
&& (Rssi
> -82))
2341 else if (MCS4
== 0) // for B-only mode
2343 else if (MCS3
&& (Rssi
> -85))
2345 else if (MCS2
&& (Rssi
> -87))
2347 else if (MCS1
&& (Rssi
> -90))
2354 pEntry
->CurrTxRateIndex
= TxRateIdx
;
2355 pNextTxRate
= (PRTMP_TX_RATE_SWITCH
) &pTable
[(pEntry
->CurrTxRateIndex
+1)*5];
2356 MlmeSetTxRate(pAd
, pEntry
, pNextTxRate
);
2359 NdisZeroMemory(pEntry
->TxQuality
, sizeof(USHORT
) * MAX_STEP_OF_TX_RATE_SWITCH
);
2360 NdisZeroMemory(pEntry
->PER
, sizeof(UCHAR
) * MAX_STEP_OF_TX_RATE_SWITCH
);
2361 pEntry
->fLastSecAccordingRSSI
= TRUE
;
2362 // reset all OneSecTx counters
2363 RESET_ONE_SEC_TX_CNT(pEntry
);
2368 if (pEntry
->fLastSecAccordingRSSI
== TRUE
)
2370 pEntry
->fLastSecAccordingRSSI
= FALSE
;
2371 pEntry
->LastSecTxRateChangeAction
= 0;
2372 // reset all OneSecTx counters
2373 RESET_ONE_SEC_TX_CNT(pEntry
);
2380 BOOLEAN bTrainUpDown
= FALSE
;
2382 pEntry
->CurrTxRateStableTime
++;
2384 // downgrade TX quality if PER >= Rate-Down threshold
2385 if (TxErrorRatio
>= TrainDown
)
2387 bTrainUpDown
= TRUE
;
2388 pEntry
->TxQuality
[CurrRateIdx
] = DRS_TX_QUALITY_WORST_BOUND
;
2390 // upgrade TX quality if PER <= Rate-Up threshold
2391 else if (TxErrorRatio
<= TrainUp
)
2393 bTrainUpDown
= TRUE
;
2394 bUpgradeQuality
= TRUE
;
2395 if (pEntry
->TxQuality
[CurrRateIdx
])
2396 pEntry
->TxQuality
[CurrRateIdx
] --; // quality very good in CurrRate
2398 if (pEntry
->TxRateUpPenalty
)
2399 pEntry
->TxRateUpPenalty
--;
2400 else if (pEntry
->TxQuality
[UpRateIdx
])
2401 pEntry
->TxQuality
[UpRateIdx
] --; // may improve next UP rate's quality
2404 pEntry
->PER
[CurrRateIdx
] = (UCHAR
)TxErrorRatio
;
2408 // perform DRS - consider TxRate Down first, then rate up.
2409 if ((CurrRateIdx
!= DownRateIdx
) && (pEntry
->TxQuality
[CurrRateIdx
] >= DRS_TX_QUALITY_WORST_BOUND
))
2411 pEntry
->CurrTxRateIndex
= DownRateIdx
;
2413 else if ((CurrRateIdx
!= UpRateIdx
) && (pEntry
->TxQuality
[UpRateIdx
] <= 0))
2415 pEntry
->CurrTxRateIndex
= UpRateIdx
;
2420 // if rate-up happen, clear all bad history of all TX rates
2421 if (pEntry
->CurrTxRateIndex
> CurrRateIdx
)
2423 pEntry
->CurrTxRateStableTime
= 0;
2424 pEntry
->TxRateUpPenalty
= 0;
2425 pEntry
->LastSecTxRateChangeAction
= 1; // rate UP
2426 NdisZeroMemory(pEntry
->TxQuality
, sizeof(USHORT
) * MAX_STEP_OF_TX_RATE_SWITCH
);
2427 NdisZeroMemory(pEntry
->PER
, sizeof(UCHAR
) * MAX_STEP_OF_TX_RATE_SWITCH
);
2430 // For TxRate fast train up
2432 if (!pAd
->StaCfg
.StaQuickResponeForRateUpTimerRunning
)
2434 RTMPSetTimer(&pAd
->StaCfg
.StaQuickResponeForRateUpTimer
, 100);
2436 pAd
->StaCfg
.StaQuickResponeForRateUpTimerRunning
= TRUE
;
2438 bTxRateChanged
= TRUE
;
2440 // if rate-down happen, only clear DownRate's bad history
2441 else if (pEntry
->CurrTxRateIndex
< CurrRateIdx
)
2443 pEntry
->CurrTxRateStableTime
= 0;
2444 pEntry
->TxRateUpPenalty
= 0; // no penalty
2445 pEntry
->LastSecTxRateChangeAction
= 2; // rate DOWN
2446 pEntry
->TxQuality
[pEntry
->CurrTxRateIndex
] = 0;
2447 pEntry
->PER
[pEntry
->CurrTxRateIndex
] = 0;
2450 // For TxRate fast train down
2452 if (!pAd
->StaCfg
.StaQuickResponeForRateUpTimerRunning
)
2454 RTMPSetTimer(&pAd
->StaCfg
.StaQuickResponeForRateUpTimer
, 100);
2456 pAd
->StaCfg
.StaQuickResponeForRateUpTimerRunning
= TRUE
;
2458 bTxRateChanged
= TRUE
;
2462 pEntry
->LastSecTxRateChangeAction
= 0; // rate no change
2463 bTxRateChanged
= FALSE
;
2466 pEntry
->LastTxOkCount
= TxSuccess
;
2468 // reset all OneSecTx counters
2469 RESET_ONE_SEC_TX_CNT(pEntry
);
2471 pNextTxRate
= (PRTMP_TX_RATE_SWITCH
) &pTable
[(pEntry
->CurrTxRateIndex
+1)*5];
2472 if (bTxRateChanged
&& pNextTxRate
)
2474 MlmeSetTxRate(pAd
, pEntry
, pNextTxRate
);
2480 ========================================================================
2481 Routine Description:
2482 Station side, Auto TxRate faster train up timer call back function.
2485 SystemSpecific1 - Not used.
2486 FunctionContext - Pointer to our Adapter context.
2487 SystemSpecific2 - Not used.
2488 SystemSpecific3 - Not used.
2493 ========================================================================
2495 VOID
StaQuickResponeForRateUpExec(
2496 IN PVOID SystemSpecific1
,
2497 IN PVOID FunctionContext
,
2498 IN PVOID SystemSpecific2
,
2499 IN PVOID SystemSpecific3
)
2501 PRTMP_ADAPTER pAd
= (PRTMP_ADAPTER
)FunctionContext
;
2502 UCHAR UpRateIdx
= 0, DownRateIdx
= 0, CurrRateIdx
= 0;
2504 ULONG TxErrorRatio
= 0;
2506 BOOLEAN bTxRateChanged
= TRUE
; //, bUpgradeQuality = FALSE;
2509 BOOLEAN bTxRateChanged
; //, bUpgradeQuality = FALSE;
2511 PRTMP_TX_RATE_SWITCH pCurrTxRate
, pNextTxRate
= NULL
;
2513 UCHAR TableSize
= 0;
2514 UCHAR InitTxRateIdx
= 0, TrainUp
, TrainDown
;
2515 TX_STA_CNT1_STRUC StaTx1
;
2516 TX_STA_CNT0_STRUC TxStaCnt0
;
2518 ULONG TxRetransmit
= 0, TxSuccess
= 0, TxFailCount
= 0;
2519 MAC_TABLE_ENTRY
*pEntry
;
2522 pAd
->StaCfg
.StaQuickResponeForRateUpTimerRunning
= FALSE
;
2525 // walk through MAC table, see if need to change AP's TX rate toward each entry
2527 for (i
= 1; i
< MAX_LEN_OF_MAC_TABLE
; i
++)
2529 pEntry
= &pAd
->MacTab
.Content
[i
];
2531 // check if this entry need to switch rate automatically
2532 if (RTMPCheckEntryEnableAutoRateSwitch(pAd
, pEntry
) == FALSE
)
2536 //Rssi = RTMPMaxRssi(pAd, (CHAR)pAd->StaCfg.AvgRssi0, (CHAR)pAd->StaCfg.AvgRssi1, (CHAR)pAd->StaCfg.AvgRssi2);
2537 if (pAd
->Antenna
.field
.TxPath
> 1)
2538 Rssi
= (pAd
->StaCfg
.RssiSample
.AvgRssi0
+ pAd
->StaCfg
.RssiSample
.AvgRssi1
) >> 1;
2540 Rssi
= pAd
->StaCfg
.RssiSample
.AvgRssi0
;
2543 if (INFRA_ON(pAd
) && (i
== 1))
2544 Rssi
= RTMPMaxRssi(pAd
,
2545 pAd
->StaCfg
.RssiSample
.AvgRssi0
,
2546 pAd
->StaCfg
.RssiSample
.AvgRssi1
,
2547 pAd
->StaCfg
.RssiSample
.AvgRssi2
);
2549 Rssi
= RTMPMaxRssi(pAd
,
2550 pEntry
->RssiSample
.AvgRssi0
,
2551 pEntry
->RssiSample
.AvgRssi1
,
2552 pEntry
->RssiSample
.AvgRssi2
);
2555 CurrRateIdx
= pAd
->CommonCfg
.TxRateIndex
;
2557 MlmeSelectTxRateTable(pAd
, pEntry
, &pTable
, &TableSize
, &InitTxRateIdx
);
2559 // decide the next upgrade rate and downgrade rate, if any
2560 if ((CurrRateIdx
> 0) && (CurrRateIdx
< (TableSize
- 1)))
2562 UpRateIdx
= CurrRateIdx
+ 1;
2563 DownRateIdx
= CurrRateIdx
-1;
2565 else if (CurrRateIdx
== 0)
2567 UpRateIdx
= CurrRateIdx
+ 1;
2568 DownRateIdx
= CurrRateIdx
;
2570 else if (CurrRateIdx
== (TableSize
- 1))
2572 UpRateIdx
= CurrRateIdx
;
2573 DownRateIdx
= CurrRateIdx
- 1;
2576 pCurrTxRate
= (PRTMP_TX_RATE_SWITCH
) &pTable
[(CurrRateIdx
+1)*5];
2578 if ((Rssi
> -65) && (pCurrTxRate
->Mode
>= MODE_HTMIX
))
2580 TrainUp
= (pCurrTxRate
->TrainUp
+ (pCurrTxRate
->TrainUp
>> 1));
2581 TrainDown
= (pCurrTxRate
->TrainDown
+ (pCurrTxRate
->TrainDown
>> 1));
2585 TrainUp
= pCurrTxRate
->TrainUp
;
2586 TrainDown
= pCurrTxRate
->TrainDown
;
2589 if (pAd
->MacTab
.Size
== 1)
2591 // Update statistic counter
2592 RTMP_IO_READ32(pAd
, TX_STA_CNT0
, &TxStaCnt0
.word
);
2593 RTMP_IO_READ32(pAd
, TX_STA_CNT1
, &StaTx1
.word
);
2595 TxRetransmit
= StaTx1
.field
.TxRetransmit
;
2596 TxSuccess
= StaTx1
.field
.TxSuccess
;
2597 TxFailCount
= TxStaCnt0
.field
.TxFailCount
;
2598 TxTotalCnt
= TxRetransmit
+ TxSuccess
+ TxFailCount
;
2600 pAd
->RalinkCounters
.OneSecTxRetryOkCount
+= StaTx1
.field
.TxRetransmit
;
2601 pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
+= StaTx1
.field
.TxSuccess
;
2602 pAd
->RalinkCounters
.OneSecTxFailCount
+= TxStaCnt0
.field
.TxFailCount
;
2603 pAd
->WlanCounters
.TransmittedFragmentCount
.u
.LowPart
+= StaTx1
.field
.TxSuccess
;
2604 pAd
->WlanCounters
.RetryCount
.u
.LowPart
+= StaTx1
.field
.TxRetransmit
;
2605 pAd
->WlanCounters
.FailedCount
.u
.LowPart
+= TxStaCnt0
.field
.TxFailCount
;
2608 TxErrorRatio
= ((TxRetransmit
+ TxFailCount
) * 100) / TxTotalCnt
;
2612 TxTotalCnt
= pEntry
->OneSecTxNoRetryOkCount
+
2613 pEntry
->OneSecTxRetryOkCount
+
2614 pEntry
->OneSecTxFailCount
;
2617 TxErrorRatio
= ((pEntry
->OneSecTxRetryOkCount
+ pEntry
->OneSecTxFailCount
) * 100) / TxTotalCnt
;
2622 // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
2623 // (criteria copied from RT2500 for Netopia case)
2625 if (TxTotalCnt
<= 12)
2627 NdisZeroMemory(pAd
->DrsCounters
.TxQuality
, sizeof(USHORT
) * MAX_STEP_OF_TX_RATE_SWITCH
);
2628 NdisZeroMemory(pAd
->DrsCounters
.PER
, sizeof(UCHAR
) * MAX_STEP_OF_TX_RATE_SWITCH
);
2630 if ((pAd
->DrsCounters
.LastSecTxRateChangeAction
== 1) && (CurrRateIdx
!= DownRateIdx
))
2632 pAd
->CommonCfg
.TxRateIndex
= DownRateIdx
;
2633 pAd
->DrsCounters
.TxQuality
[CurrRateIdx
] = DRS_TX_QUALITY_WORST_BOUND
;
2635 else if ((pAd
->DrsCounters
.LastSecTxRateChangeAction
== 2) && (CurrRateIdx
!= UpRateIdx
))
2637 pAd
->CommonCfg
.TxRateIndex
= UpRateIdx
;
2640 DBGPRINT_RAW(RT_DEBUG_TRACE
,("QuickDRS: TxTotalCnt <= 15, train back to original rate \n"));
2646 ULONG OneSecTxNoRetryOKRationCount
;
2648 if (pAd
->DrsCounters
.LastTimeTxRateChangeAction
== 0)
2653 // downgrade TX quality if PER >= Rate-Down threshold
2654 if (TxErrorRatio
>= TrainDown
)
2656 pAd
->DrsCounters
.TxQuality
[CurrRateIdx
] = DRS_TX_QUALITY_WORST_BOUND
;
2659 pAd
->DrsCounters
.PER
[CurrRateIdx
] = (UCHAR
)TxErrorRatio
;
2661 OneSecTxNoRetryOKRationCount
= (TxSuccess
* ratio
);
2663 // perform DRS - consider TxRate Down first, then rate up.
2664 if ((pAd
->DrsCounters
.LastSecTxRateChangeAction
== 1) && (CurrRateIdx
!= DownRateIdx
))
2666 if ((pAd
->DrsCounters
.LastTxOkCount
+ 2) >= OneSecTxNoRetryOKRationCount
)
2668 pAd
->CommonCfg
.TxRateIndex
= DownRateIdx
;
2669 pAd
->DrsCounters
.TxQuality
[CurrRateIdx
] = DRS_TX_QUALITY_WORST_BOUND
;
2674 else if ((pAd
->DrsCounters
.LastSecTxRateChangeAction
== 2) && (CurrRateIdx
!= UpRateIdx
))
2676 if ((TxErrorRatio
>= 50) || (TxErrorRatio
>= TrainDown
))
2680 else if ((pAd
->DrsCounters
.LastTxOkCount
+ 2) >= OneSecTxNoRetryOKRationCount
)
2682 pAd
->CommonCfg
.TxRateIndex
= UpRateIdx
;
2687 // if rate-up happen, clear all bad history of all TX rates
2688 if (pAd
->CommonCfg
.TxRateIndex
> CurrRateIdx
)
2690 pAd
->DrsCounters
.TxRateUpPenalty
= 0;
2691 NdisZeroMemory(pAd
->DrsCounters
.TxQuality
, sizeof(USHORT
) * MAX_STEP_OF_TX_RATE_SWITCH
);
2692 NdisZeroMemory(pAd
->DrsCounters
.PER
, sizeof(UCHAR
) * MAX_STEP_OF_TX_RATE_SWITCH
);
2694 bTxRateChanged
= TRUE
;
2697 // if rate-down happen, only clear DownRate's bad history
2698 else if (pAd
->CommonCfg
.TxRateIndex
< CurrRateIdx
)
2700 DBGPRINT_RAW(RT_DEBUG_TRACE
,("QuickDRS: --TX rate from %d to %d \n", CurrRateIdx
, pAd
->CommonCfg
.TxRateIndex
));
2702 pAd
->DrsCounters
.TxRateUpPenalty
= 0; // no penalty
2703 pAd
->DrsCounters
.TxQuality
[pAd
->CommonCfg
.TxRateIndex
] = 0;
2704 pAd
->DrsCounters
.PER
[pAd
->CommonCfg
.TxRateIndex
] = 0;
2706 bTxRateChanged
= TRUE
;
2711 bTxRateChanged
= FALSE
;
2714 pNextTxRate
= (PRTMP_TX_RATE_SWITCH
) &pTable
[(pAd
->CommonCfg
.TxRateIndex
+1)*5];
2715 if (bTxRateChanged
&& pNextTxRate
)
2717 MlmeSetTxRate(pAd
, pEntry
, pNextTxRate
);
2723 ==========================================================================
2725 This routine is executed periodically inside MlmePeriodicExec() after
2726 association with an AP.
2727 It checks if StaCfg.Psm is consistent with user policy (recorded in
2728 StaCfg.WindowsPowerMode). If not, enforce user policy. However,
2729 there're some conditions to consider:
2730 1. we don't support power-saving in ADHOC mode, so Psm=PWR_ACTIVE all
2731 the time when Mibss==TRUE
2732 2. When link up in INFRA mode, Psm should not be switch to PWR_SAVE
2733 if outgoing traffic available in TxRing or MgmtRing.
2735 1. change pAd->StaCfg.Psm to PWR_SAVE or leave it untouched
2737 IRQL = DISPATCH_LEVEL
2739 ==========================================================================
2741 VOID
MlmeCheckPsmChange(
2742 IN PRTMP_ADAPTER pAd
,
2748 // 1. Psm maybe ON only happen in INFRASTRUCTURE mode
2749 // 2. user wants either MAX_PSP or FAST_PSP
2750 // 3. but current psm is not in PWR_SAVE
2751 // 4. CNTL state machine is not doing SCANning
2752 // 5. no TX SUCCESS event for the past 1-sec period
2753 #ifdef NDIS51_MINIPORT
2754 if (pAd
->StaCfg
.WindowsPowerProfile
== NdisPowerProfileBattery
)
2755 PowerMode
= pAd
->StaCfg
.WindowsBatteryPowerMode
;
2758 PowerMode
= pAd
->StaCfg
.WindowsPowerMode
;
2760 if (INFRA_ON(pAd
) &&
2761 (PowerMode
!= Ndis802_11PowerModeCAM
) &&
2762 (pAd
->StaCfg
.Psm
== PWR_ACTIVE
) &&
2764 RTMP_TEST_PSFLAG(pAd
, fRTMP_PS_CAN_GO_SLEEP
))
2766 (pAd
->Mlme
.CntlMachine
.CurrState
== CNTL_IDLE
))
2769 // add by johnli, use Rx OK data count per second to calculate throughput
2770 // If Ttraffic is too high ( > 400 Rx per second), don't go to sleep mode. If tx rate is low, use low criteria
2771 // Mode=CCK/MCS=3 => 11 Mbps, Mode=OFDM/MCS=3 => 18 Mbps
2772 if (((pAd
->StaCfg
.HTPhyMode
.field
.MCS
<= 3) &&
2773 (pAd
->RalinkCounters
.OneSecRxOkDataCnt
< (ULONG
)100)) ||
2774 ((pAd
->StaCfg
.HTPhyMode
.field
.MCS
> 3) &&
2775 (pAd
->RalinkCounters
.OneSecRxOkDataCnt
< (ULONG
)400)))
2778 NdisGetSystemUpTime(&pAd
->Mlme
.LastSendNULLpsmTime
);
2779 pAd
->RalinkCounters
.RxCountSinceLastNULL
= 0;
2780 MlmeSetPsmBit(pAd
, PWR_SAVE
);
2781 if (!(pAd
->CommonCfg
.bAPSDCapable
&& pAd
->CommonCfg
.APEdcaParm
.bAPSDCapable
))
2783 RTMPSendNullFrame(pAd
, pAd
->CommonCfg
.TxRate
, FALSE
);
2787 RTMPSendNullFrame(pAd
, pAd
->CommonCfg
.TxRate
, TRUE
);
2793 // IRQL = PASSIVE_LEVEL
2794 // IRQL = DISPATCH_LEVEL
2796 IN PRTMP_ADAPTER pAd
,
2799 AUTO_RSP_CFG_STRUC csr4
;
2801 pAd
->StaCfg
.Psm
= psm
;
2802 RTMP_IO_READ32(pAd
, AUTO_RSP_CFG
, &csr4
.word
);
2803 csr4
.field
.AckCtsPsmBit
= (psm
== PWR_SAVE
)? 1:0;
2804 RTMP_IO_WRITE32(pAd
, AUTO_RSP_CFG
, csr4
.word
);
2806 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeSetPsmBit = %d\n", psm
));
2809 // IRQL = DISPATCH_LEVEL
2810 VOID
MlmeSetTxPreamble(
2811 IN PRTMP_ADAPTER pAd
,
2812 IN USHORT TxPreamble
)
2814 AUTO_RSP_CFG_STRUC csr4
;
2817 // Always use Long preamble before verifiation short preamble functionality works well.
2818 // Todo: remove the following line if short preamble functionality works
2820 //TxPreamble = Rt802_11PreambleLong;
2822 RTMP_IO_READ32(pAd
, AUTO_RSP_CFG
, &csr4
.word
);
2823 if (TxPreamble
== Rt802_11PreambleLong
)
2825 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeSetTxPreamble (= LONG PREAMBLE)\n"));
2826 OPSTATUS_CLEAR_FLAG(pAd
, fOP_STATUS_SHORT_PREAMBLE_INUSED
);
2827 csr4
.field
.AutoResponderPreamble
= 0;
2831 // NOTE: 1Mbps should always use long preamble
2832 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeSetTxPreamble (= SHORT PREAMBLE)\n"));
2833 OPSTATUS_SET_FLAG(pAd
, fOP_STATUS_SHORT_PREAMBLE_INUSED
);
2834 csr4
.field
.AutoResponderPreamble
= 1;
2837 RTMP_IO_WRITE32(pAd
, AUTO_RSP_CFG
, csr4
.word
);
2841 ==========================================================================
2843 Update basic rate bitmap
2844 ==========================================================================
2847 VOID
UpdateBasicRateBitmap(
2848 IN PRTMP_ADAPTER pAdapter
)
2851 /* 1 2 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */
2852 UCHAR rate
[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
2853 UCHAR
*sup_p
= pAdapter
->CommonCfg
.SupRate
;
2854 UCHAR
*ext_p
= pAdapter
->CommonCfg
.ExtRate
;
2855 ULONG bitmap
= pAdapter
->CommonCfg
.BasicRateBitmap
;
2858 /* if A mode, always use fix BasicRateBitMap */
2859 //if (pAdapter->CommonCfg.Channel == PHY_11A)
2860 if (pAdapter
->CommonCfg
.Channel
> 14)
2861 pAdapter
->CommonCfg
.BasicRateBitmap
= 0x150; /* 6, 12, 24M */
2864 if (pAdapter
->CommonCfg
.BasicRateBitmap
> 4095)
2866 /* (2 ^ MAX_LEN_OF_SUPPORTED_RATES) -1 */
2870 for(i
=0; i
<MAX_LEN_OF_SUPPORTED_RATES
; i
++)
2876 for(i
=0; i
<MAX_LEN_OF_SUPPORTED_RATES
; i
++)
2878 if (bitmap
& (1 << i
))
2880 for(j
=0; j
<MAX_LEN_OF_SUPPORTED_RATES
; j
++)
2882 if (sup_p
[j
] == rate
[i
])
2887 for(j
=0; j
<MAX_LEN_OF_SUPPORTED_RATES
; j
++)
2889 if (ext_p
[j
] == rate
[i
])
2895 } /* End of UpdateBasicRateBitmap */
2897 // IRQL = PASSIVE_LEVEL
2898 // IRQL = DISPATCH_LEVEL
2899 // bLinkUp is to identify the inital link speed.
2900 // TRUE indicates the rate update at linkup, we should not try to set the rate at 54Mbps.
2901 VOID
MlmeUpdateTxRates(
2902 IN PRTMP_ADAPTER pAd
,
2907 UCHAR Rate
= RATE_6
, MaxDesire
= RATE_1
, MaxSupport
= RATE_1
;
2908 UCHAR MinSupport
= RATE_54
;
2909 ULONG BasicRateBitmap
= 0;
2910 UCHAR CurrBasicRate
= RATE_1
;
2911 UCHAR
*pSupRate
, SupRateLen
, *pExtRate
, ExtRateLen
;
2912 PHTTRANSMIT_SETTING pHtPhy
= NULL
;
2913 PHTTRANSMIT_SETTING pMaxHtPhy
= NULL
;
2914 PHTTRANSMIT_SETTING pMinHtPhy
= NULL
;
2915 BOOLEAN
*auto_rate_cur_p
;
2916 UCHAR HtMcs
= MCS_AUTO
;
2918 // find max desired rate
2919 UpdateBasicRateBitmap(pAd
);
2922 auto_rate_cur_p
= NULL
;
2923 for (i
=0; i
<MAX_LEN_OF_SUPPORTED_RATES
; i
++)
2925 switch (pAd
->CommonCfg
.DesireRate
[i
] & 0x7f)
2927 case 2: Rate
= RATE_1
; num
++; break;
2928 case 4: Rate
= RATE_2
; num
++; break;
2929 case 11: Rate
= RATE_5_5
; num
++; break;
2930 case 22: Rate
= RATE_11
; num
++; break;
2931 case 12: Rate
= RATE_6
; num
++; break;
2932 case 18: Rate
= RATE_9
; num
++; break;
2933 case 24: Rate
= RATE_12
; num
++; break;
2934 case 36: Rate
= RATE_18
; num
++; break;
2935 case 48: Rate
= RATE_24
; num
++; break;
2936 case 72: Rate
= RATE_36
; num
++; break;
2937 case 96: Rate
= RATE_48
; num
++; break;
2938 case 108: Rate
= RATE_54
; num
++; break;
2939 //default: Rate = RATE_1; break;
2941 if (MaxDesire
< Rate
) MaxDesire
= Rate
;
2944 //===========================================================================
2945 //===========================================================================
2947 pHtPhy
= &pAd
->StaCfg
.HTPhyMode
;
2948 pMaxHtPhy
= &pAd
->StaCfg
.MaxHTPhyMode
;
2949 pMinHtPhy
= &pAd
->StaCfg
.MinHTPhyMode
;
2951 auto_rate_cur_p
= &pAd
->StaCfg
.bAutoTxRateSwitch
;
2952 HtMcs
= pAd
->StaCfg
.DesiredTransmitSetting
.field
.MCS
;
2954 if ((pAd
->StaCfg
.BssType
== BSS_ADHOC
) &&
2955 (pAd
->CommonCfg
.PhyMode
== PHY_11B
) &&
2956 (MaxDesire
> RATE_11
))
2958 MaxDesire
= RATE_11
;
2962 pAd
->CommonCfg
.MaxDesiredRate
= MaxDesire
;
2963 pMinHtPhy
->word
= 0;
2964 pMaxHtPhy
->word
= 0;
2967 // Auto rate switching is enabled only if more than one DESIRED RATES are
2968 // specified; otherwise disabled
2971 *auto_rate_cur_p
= FALSE
;
2975 *auto_rate_cur_p
= TRUE
;
2979 if (HtMcs
!= MCS_AUTO
)
2981 *auto_rate_cur_p
= FALSE
;
2985 *auto_rate_cur_p
= TRUE
;
2989 if ((ADHOC_ON(pAd
) || INFRA_ON(pAd
)) && (pAd
->OpMode
== OPMODE_STA
))
2991 pSupRate
= &pAd
->StaActive
.SupRate
[0];
2992 pExtRate
= &pAd
->StaActive
.ExtRate
[0];
2993 SupRateLen
= pAd
->StaActive
.SupRateLen
;
2994 ExtRateLen
= pAd
->StaActive
.ExtRateLen
;
2998 pSupRate
= &pAd
->CommonCfg
.SupRate
[0];
2999 pExtRate
= &pAd
->CommonCfg
.ExtRate
[0];
3000 SupRateLen
= pAd
->CommonCfg
.SupRateLen
;
3001 ExtRateLen
= pAd
->CommonCfg
.ExtRateLen
;
3004 // find max supported rate
3005 for (i
=0; i
<SupRateLen
; i
++)
3007 switch (pSupRate
[i
] & 0x7f)
3009 case 2: Rate
= RATE_1
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0001; break;
3010 case 4: Rate
= RATE_2
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0002; break;
3011 case 11: Rate
= RATE_5_5
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0004; break;
3012 case 22: Rate
= RATE_11
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0008; break;
3013 case 12: Rate
= RATE_6
; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap
|= 0x0010; break;
3014 case 18: Rate
= RATE_9
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0020; break;
3015 case 24: Rate
= RATE_12
; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap
|= 0x0040; break;
3016 case 36: Rate
= RATE_18
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0080; break;
3017 case 48: Rate
= RATE_24
; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap
|= 0x0100; break;
3018 case 72: Rate
= RATE_36
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0200; break;
3019 case 96: Rate
= RATE_48
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0400; break;
3020 case 108: Rate
= RATE_54
; if (pSupRate
[i
] & 0x80) BasicRateBitmap
|= 0x0800; break;
3021 default: Rate
= RATE_1
; break;
3023 if (MaxSupport
< Rate
) MaxSupport
= Rate
;
3025 if (MinSupport
> Rate
) MinSupport
= Rate
;
3028 for (i
=0; i
<ExtRateLen
; i
++)
3030 switch (pExtRate
[i
] & 0x7f)
3032 case 2: Rate
= RATE_1
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0001; break;
3033 case 4: Rate
= RATE_2
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0002; break;
3034 case 11: Rate
= RATE_5_5
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0004; break;
3035 case 22: Rate
= RATE_11
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0008; break;
3036 case 12: Rate
= RATE_6
; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap
|= 0x0010; break;
3037 case 18: Rate
= RATE_9
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0020; break;
3038 case 24: Rate
= RATE_12
; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap
|= 0x0040; break;
3039 case 36: Rate
= RATE_18
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0080; break;
3040 case 48: Rate
= RATE_24
; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap
|= 0x0100; break;
3041 case 72: Rate
= RATE_36
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0200; break;
3042 case 96: Rate
= RATE_48
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0400; break;
3043 case 108: Rate
= RATE_54
; if (pExtRate
[i
] & 0x80) BasicRateBitmap
|= 0x0800; break;
3044 default: Rate
= RATE_1
; break;
3046 if (MaxSupport
< Rate
) MaxSupport
= Rate
;
3048 if (MinSupport
> Rate
) MinSupport
= Rate
;
3051 RTMP_IO_WRITE32(pAd
, LEGACY_BASIC_RATE
, BasicRateBitmap
);
3053 // calculate the exptected ACK rate for each TX rate. This info is used to caculate
3054 // the DURATION field of outgoing uniicast DATA/MGMT frame
3055 for (i
=0; i
<MAX_LEN_OF_SUPPORTED_RATES
; i
++)
3057 if (BasicRateBitmap
& (0x01 << i
))
3058 CurrBasicRate
= (UCHAR
)i
;
3059 pAd
->CommonCfg
.ExpectedACKRate
[i
] = CurrBasicRate
;
3062 DBGPRINT(RT_DEBUG_TRACE
,("MlmeUpdateTxRates[MaxSupport = %d] = MaxDesire %d Mbps\n", RateIdToMbps
[MaxSupport
], RateIdToMbps
[MaxDesire
]));
3063 // max tx rate = min {max desire rate, max supported rate}
3064 if (MaxSupport
< MaxDesire
)
3065 pAd
->CommonCfg
.MaxTxRate
= MaxSupport
;
3067 pAd
->CommonCfg
.MaxTxRate
= MaxDesire
;
3069 pAd
->CommonCfg
.MinTxRate
= MinSupport
;
3070 if (*auto_rate_cur_p
)
3074 dbm
= pAd
->StaCfg
.RssiSample
.AvgRssi0
- pAd
->BbpRssiToDbmDelta
;
3076 if (bLinkUp
== TRUE
)
3077 pAd
->CommonCfg
.TxRate
= RATE_24
;
3079 pAd
->CommonCfg
.TxRate
= pAd
->CommonCfg
.MaxTxRate
;
3082 pAd
->CommonCfg
.TxRate
= RATE_11
;
3084 pAd
->CommonCfg
.TxRate
= RATE_24
;
3086 // should never exceed MaxTxRate (consider 11B-only mode)
3087 if (pAd
->CommonCfg
.TxRate
> pAd
->CommonCfg
.MaxTxRate
)
3088 pAd
->CommonCfg
.TxRate
= pAd
->CommonCfg
.MaxTxRate
;
3090 pAd
->CommonCfg
.TxRateIndex
= 0;
3094 pAd
->CommonCfg
.TxRate
= pAd
->CommonCfg
.MaxTxRate
;
3095 pHtPhy
->field
.MCS
= (pAd
->CommonCfg
.MaxTxRate
> 3) ? (pAd
->CommonCfg
.MaxTxRate
- 4) : pAd
->CommonCfg
.MaxTxRate
;
3096 pHtPhy
->field
.MODE
= (pAd
->CommonCfg
.MaxTxRate
> 3) ? MODE_OFDM
: MODE_CCK
;
3098 pAd
->MacTab
.Content
[BSSID_WCID
].HTPhyMode
.field
.STBC
= pHtPhy
->field
.STBC
;
3099 pAd
->MacTab
.Content
[BSSID_WCID
].HTPhyMode
.field
.ShortGI
= pHtPhy
->field
.ShortGI
;
3100 pAd
->MacTab
.Content
[BSSID_WCID
].HTPhyMode
.field
.MCS
= pHtPhy
->field
.MCS
;
3101 pAd
->MacTab
.Content
[BSSID_WCID
].HTPhyMode
.field
.MODE
= pHtPhy
->field
.MODE
;
3104 if (pAd
->CommonCfg
.TxRate
<= RATE_11
)
3106 pMaxHtPhy
->field
.MODE
= MODE_CCK
;
3107 pMaxHtPhy
->field
.MCS
= pAd
->CommonCfg
.TxRate
;
3108 pMinHtPhy
->field
.MCS
= pAd
->CommonCfg
.MinTxRate
;
3112 pMaxHtPhy
->field
.MODE
= MODE_OFDM
;
3113 pMaxHtPhy
->field
.MCS
= OfdmRateToRxwiMCS
[pAd
->CommonCfg
.TxRate
];
3114 if (pAd
->CommonCfg
.MinTxRate
>= RATE_6
&& (pAd
->CommonCfg
.MinTxRate
<= RATE_54
))
3115 {pMinHtPhy
->field
.MCS
= OfdmRateToRxwiMCS
[pAd
->CommonCfg
.MinTxRate
];}
3117 {pMinHtPhy
->field
.MCS
= pAd
->CommonCfg
.MinTxRate
;}
3120 pHtPhy
->word
= (pMaxHtPhy
->word
);
3121 if (bLinkUp
&& (pAd
->OpMode
== OPMODE_STA
))
3123 pAd
->MacTab
.Content
[BSSID_WCID
].HTPhyMode
.word
= pHtPhy
->word
;
3124 pAd
->MacTab
.Content
[BSSID_WCID
].MaxHTPhyMode
.word
= pMaxHtPhy
->word
;
3125 pAd
->MacTab
.Content
[BSSID_WCID
].MinHTPhyMode
.word
= pMinHtPhy
->word
;
3129 switch (pAd
->CommonCfg
.PhyMode
)
3131 case PHY_11BG_MIXED
:
3133 case PHY_11BGN_MIXED
:
3134 pAd
->CommonCfg
.MlmeRate
= RATE_1
;
3135 pAd
->CommonCfg
.MlmeTransmit
.field
.MODE
= MODE_CCK
;
3136 pAd
->CommonCfg
.MlmeTransmit
.field
.MCS
= RATE_1
;
3137 pAd
->CommonCfg
.RtsRate
= RATE_11
;
3141 case PHY_11AGN_MIXED
:
3142 case PHY_11GN_MIXED
:
3144 case PHY_11AN_MIXED
:
3146 pAd
->CommonCfg
.MlmeRate
= RATE_6
;
3147 pAd
->CommonCfg
.RtsRate
= RATE_6
;
3148 pAd
->CommonCfg
.MlmeTransmit
.field
.MODE
= MODE_OFDM
;
3149 pAd
->CommonCfg
.MlmeTransmit
.field
.MCS
= OfdmRateToRxwiMCS
[pAd
->CommonCfg
.MlmeRate
];
3151 case PHY_11ABG_MIXED
:
3152 case PHY_11ABGN_MIXED
:
3153 if (pAd
->CommonCfg
.Channel
<= 14)
3155 pAd
->CommonCfg
.MlmeRate
= RATE_1
;
3156 pAd
->CommonCfg
.RtsRate
= RATE_1
;
3157 pAd
->CommonCfg
.MlmeTransmit
.field
.MODE
= MODE_CCK
;
3158 pAd
->CommonCfg
.MlmeTransmit
.field
.MCS
= RATE_1
;
3162 pAd
->CommonCfg
.MlmeRate
= RATE_6
;
3163 pAd
->CommonCfg
.RtsRate
= RATE_6
;
3164 pAd
->CommonCfg
.MlmeTransmit
.field
.MODE
= MODE_OFDM
;
3165 pAd
->CommonCfg
.MlmeTransmit
.field
.MCS
= OfdmRateToRxwiMCS
[pAd
->CommonCfg
.MlmeRate
];
3169 pAd
->CommonCfg
.MlmeRate
= RATE_6
;
3170 pAd
->CommonCfg
.MlmeTransmit
.field
.MODE
= MODE_OFDM
;
3171 pAd
->CommonCfg
.MlmeTransmit
.field
.MCS
= OfdmRateToRxwiMCS
[pAd
->CommonCfg
.MlmeRate
];
3172 pAd
->CommonCfg
.RtsRate
= RATE_1
;
3176 // Keep Basic Mlme Rate.
3178 pAd
->MacTab
.Content
[MCAST_WCID
].HTPhyMode
.word
= pAd
->CommonCfg
.MlmeTransmit
.word
;
3179 if (pAd
->CommonCfg
.MlmeTransmit
.field
.MODE
== MODE_OFDM
)
3180 pAd
->MacTab
.Content
[MCAST_WCID
].HTPhyMode
.field
.MCS
= OfdmRateToRxwiMCS
[RATE_24
];
3182 pAd
->MacTab
.Content
[MCAST_WCID
].HTPhyMode
.field
.MCS
= RATE_1
;
3183 pAd
->CommonCfg
.BasicMlmeRate
= pAd
->CommonCfg
.MlmeRate
;
3186 DBGPRINT(RT_DEBUG_TRACE
, (" MlmeUpdateTxRates (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n",
3187 RateIdToMbps
[MaxDesire
], RateIdToMbps
[MaxSupport
], RateIdToMbps
[pAd
->CommonCfg
.MaxTxRate
], RateIdToMbps
[pAd
->CommonCfg
.MinTxRate
],
3188 /*OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)*/*auto_rate_cur_p
));
3189 DBGPRINT(RT_DEBUG_TRACE
, (" MlmeUpdateTxRates (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n",
3190 RateIdToMbps
[pAd
->CommonCfg
.TxRate
], RateIdToMbps
[pAd
->CommonCfg
.RtsRate
], BasicRateBitmap
));
3191 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeUpdateTxRates (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n",
3192 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
));
3196 ==========================================================================
3198 This function update HT Rate setting.
3199 Input Wcid value is valid for 2 case :
3200 1. it's used for Station in infra mode that copy AP rate to Mactable.
3201 2. OR Station in adhoc mode to copy peer's HT rate to Mactable.
3203 IRQL = DISPATCH_LEVEL
3205 ==========================================================================
3207 VOID
MlmeUpdateHtTxRates(
3208 IN PRTMP_ADAPTER pAd
,
3211 UCHAR StbcMcs
; //j, StbcMcs, bitmask;
3213 RT_HT_CAPABILITY
*pRtHtCap
= NULL
;
3214 RT_HT_PHY_INFO
*pActiveHtPhy
= NULL
;
3217 PRT_HT_PHY_INFO pDesireHtPhy
= NULL
;
3218 PHTTRANSMIT_SETTING pHtPhy
= NULL
;
3219 PHTTRANSMIT_SETTING pMaxHtPhy
= NULL
;
3220 PHTTRANSMIT_SETTING pMinHtPhy
= NULL
;
3221 BOOLEAN
*auto_rate_cur_p
;
3223 DBGPRINT(RT_DEBUG_TRACE
,("MlmeUpdateHtTxRates===> \n"));
3225 auto_rate_cur_p
= NULL
;
3228 pDesireHtPhy
= &pAd
->StaCfg
.DesiredHtPhyInfo
;
3229 pActiveHtPhy
= &pAd
->StaCfg
.DesiredHtPhyInfo
;
3230 pHtPhy
= &pAd
->StaCfg
.HTPhyMode
;
3231 pMaxHtPhy
= &pAd
->StaCfg
.MaxHTPhyMode
;
3232 pMinHtPhy
= &pAd
->StaCfg
.MinHTPhyMode
;
3234 auto_rate_cur_p
= &pAd
->StaCfg
.bAutoTxRateSwitch
;
3237 if ((ADHOC_ON(pAd
) || INFRA_ON(pAd
)) && (pAd
->OpMode
== OPMODE_STA
))
3239 if (pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
== FALSE
)
3242 pRtHtCap
= &pAd
->StaActive
.SupportedHtPhy
;
3243 pActiveHtPhy
= &pAd
->StaActive
.SupportedPhyInfo
;
3244 StbcMcs
= (UCHAR
)pAd
->MlmeAux
.AddHtInfo
.AddHtInfo3
.StbcMcs
;
3245 BasicMCS
=pAd
->MlmeAux
.AddHtInfo
.MCSSet
[0]+(pAd
->MlmeAux
.AddHtInfo
.MCSSet
[1]<<8)+(StbcMcs
<<16);
3246 if ((pAd
->CommonCfg
.DesiredHtPhy
.TxSTBC
) && (pRtHtCap
->RxSTBC
) && (pAd
->Antenna
.field
.TxPath
== 2))
3247 pMaxHtPhy
->field
.STBC
= STBC_USE
;
3249 pMaxHtPhy
->field
.STBC
= STBC_NONE
;
3253 if (pDesireHtPhy
->bHtEnable
== FALSE
)
3256 pRtHtCap
= &pAd
->CommonCfg
.DesiredHtPhy
;
3257 StbcMcs
= (UCHAR
)pAd
->CommonCfg
.AddHTInfo
.AddHtInfo3
.StbcMcs
;
3258 BasicMCS
= pAd
->CommonCfg
.AddHTInfo
.MCSSet
[0]+(pAd
->CommonCfg
.AddHTInfo
.MCSSet
[1]<<8)+(StbcMcs
<<16);
3259 if ((pAd
->CommonCfg
.DesiredHtPhy
.TxSTBC
) && (pRtHtCap
->RxSTBC
) && (pAd
->Antenna
.field
.TxPath
== 2))
3260 pMaxHtPhy
->field
.STBC
= STBC_USE
;
3262 pMaxHtPhy
->field
.STBC
= STBC_NONE
;
3265 // Decide MAX ht rate.
3266 if ((pRtHtCap
->GF
) && (pAd
->CommonCfg
.DesiredHtPhy
.GF
))
3267 pMaxHtPhy
->field
.MODE
= MODE_HTGREENFIELD
;
3269 pMaxHtPhy
->field
.MODE
= MODE_HTMIX
;
3271 if ((pAd
->CommonCfg
.DesiredHtPhy
.ChannelWidth
) && (pRtHtCap
->ChannelWidth
))
3272 pMaxHtPhy
->field
.BW
= BW_40
;
3274 pMaxHtPhy
->field
.BW
= BW_20
;
3276 if (pMaxHtPhy
->field
.BW
== BW_20
)
3277 pMaxHtPhy
->field
.ShortGI
= (pAd
->CommonCfg
.DesiredHtPhy
.ShortGIfor20
& pRtHtCap
->ShortGIfor20
);
3279 pMaxHtPhy
->field
.ShortGI
= (pAd
->CommonCfg
.DesiredHtPhy
.ShortGIfor40
& pRtHtCap
->ShortGIfor40
);
3281 for (i
=23; i
>=0; i
--) // 3*3
3284 bitmask
= (1<<(i
-(j
*8)));
3286 if ((pActiveHtPhy
->MCSSet
[j
] & bitmask
) && (pDesireHtPhy
->MCSSet
[j
] & bitmask
))
3288 pMaxHtPhy
->field
.MCS
= i
;
3296 // Copy MIN ht rate. rt2860???
3297 pMinHtPhy
->field
.BW
= BW_20
;
3298 pMinHtPhy
->field
.MCS
= 0;
3299 pMinHtPhy
->field
.STBC
= 0;
3300 pMinHtPhy
->field
.ShortGI
= 0;
3301 //If STA assigns fixed rate. update to fixed here.
3302 if ( (pAd
->OpMode
== OPMODE_STA
) && (pDesireHtPhy
->MCSSet
[0] != 0xff))
3304 if (pDesireHtPhy
->MCSSet
[4] != 0)
3306 pMaxHtPhy
->field
.MCS
= 32;
3307 pMinHtPhy
->field
.MCS
= 32;
3308 DBGPRINT(RT_DEBUG_TRACE
,("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n",pMinHtPhy
->field
.MCS
));
3311 for (i
=23; (CHAR
)i
>= 0; i
--) // 3*3
3314 bitmask
= (1<<(i
-(j
*8)));
3315 if ( (pDesireHtPhy
->MCSSet
[j
] & bitmask
) && (pActiveHtPhy
->MCSSet
[j
] & bitmask
))
3317 pMaxHtPhy
->field
.MCS
= i
;
3318 pMinHtPhy
->field
.MCS
= i
;
3327 pHtPhy
->field
.STBC
= pMaxHtPhy
->field
.STBC
;
3328 pHtPhy
->field
.BW
= pMaxHtPhy
->field
.BW
;
3329 pHtPhy
->field
.MODE
= pMaxHtPhy
->field
.MODE
;
3330 pHtPhy
->field
.MCS
= pMaxHtPhy
->field
.MCS
;
3331 pHtPhy
->field
.ShortGI
= pMaxHtPhy
->field
.ShortGI
;
3333 // use default now. rt2860
3334 if (pDesireHtPhy
->MCSSet
[0] != 0xff)
3335 *auto_rate_cur_p
= FALSE
;
3337 *auto_rate_cur_p
= TRUE
;
3339 DBGPRINT(RT_DEBUG_TRACE
, (" MlmeUpdateHtTxRates<---.AMsduSize = %d \n", pAd
->CommonCfg
.DesiredHtPhy
.AmsduSize
));
3340 DBGPRINT(RT_DEBUG_TRACE
,("TX: MCS[0] = %x (choose %d), BW = %d, ShortGI = %d, MODE = %d, \n", pActiveHtPhy
->MCSSet
[0],pHtPhy
->field
.MCS
,
3341 pHtPhy
->field
.BW
, pHtPhy
->field
.ShortGI
, pHtPhy
->field
.MODE
));
3342 DBGPRINT(RT_DEBUG_TRACE
,("MlmeUpdateHtTxRates<=== \n"));
3345 // IRQL = DISPATCH_LEVEL
3347 IN PRTMP_ADAPTER pAd
)
3349 RT28XX_MLME_RADIO_OFF(pAd
);
3352 // IRQL = DISPATCH_LEVEL
3354 IN PRTMP_ADAPTER pAd
)
3356 RT28XX_MLME_RADIO_ON(pAd
);
3359 // ===========================================================================================
3361 // ===========================================================================================
3364 /*! \brief initialize BSS table
3365 * \param p_tab pointer to the table
3370 IRQL = PASSIVE_LEVEL
3371 IRQL = DISPATCH_LEVEL
3380 Tab
->BssOverlapNr
= 0;
3381 for (i
= 0; i
< MAX_LEN_OF_BSS_TABLE
; i
++)
3383 NdisZeroMemory(&Tab
->BssEntry
[i
], sizeof(BSS_ENTRY
));
3384 Tab
->BssEntry
[i
].Rssi
= -127; // initial the rssi as a minimum value
3389 IN PRTMP_ADAPTER pAd
,
3394 Tab
->numAsOriginator
= 0;
3395 Tab
->numAsRecipient
= 0;
3396 NdisAllocateSpinLock(&pAd
->BATabLock
);
3397 for (i
= 0; i
< MAX_LEN_OF_BA_REC_TABLE
; i
++)
3399 Tab
->BARecEntry
[i
].REC_BA_Status
= Recipient_NONE
;
3400 NdisAllocateSpinLock(&(Tab
->BARecEntry
[i
].RxReRingLock
));
3402 for (i
= 0; i
< MAX_LEN_OF_BA_ORI_TABLE
; i
++)
3404 Tab
->BAOriEntry
[i
].ORI_BA_Status
= Originator_NONE
;
3408 /*! \brief search the BSS table by SSID
3409 * \param p_tab pointer to the bss table
3410 * \param ssid SSID string
3411 * \return index of the table, BSS_NOT_FOUND if not in the table
3414 * \note search by sequential search
3416 IRQL = DISPATCH_LEVEL
3419 ULONG
BssTableSearch(
3426 for (i
= 0; i
< Tab
->BssNr
; i
++)
3429 // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
3430 // We should distinguish this case.
3432 if ((((Tab
->BssEntry
[i
].Channel
<= 14) && (Channel
<= 14)) ||
3433 ((Tab
->BssEntry
[i
].Channel
> 14) && (Channel
> 14))) &&
3434 MAC_ADDR_EQUAL(Tab
->BssEntry
[i
].Bssid
, pBssid
))
3439 return (ULONG
)BSS_NOT_FOUND
;
3442 ULONG
BssSsidTableSearch(
3451 for (i
= 0; i
< Tab
->BssNr
; i
++)
3454 // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
3455 // We should distinguish this case.
3457 if ((((Tab
->BssEntry
[i
].Channel
<= 14) && (Channel
<= 14)) ||
3458 ((Tab
->BssEntry
[i
].Channel
> 14) && (Channel
> 14))) &&
3459 MAC_ADDR_EQUAL(Tab
->BssEntry
[i
].Bssid
, pBssid
) &&
3460 SSID_EQUAL(pSsid
, SsidLen
, Tab
->BssEntry
[i
].Ssid
, Tab
->BssEntry
[i
].SsidLen
))
3465 return (ULONG
)BSS_NOT_FOUND
;
3468 ULONG
BssTableSearchWithSSID(
3477 for (i
= 0; i
< Tab
->BssNr
; i
++)
3479 if ((((Tab
->BssEntry
[i
].Channel
<= 14) && (Channel
<= 14)) ||
3480 ((Tab
->BssEntry
[i
].Channel
> 14) && (Channel
> 14))) &&
3481 MAC_ADDR_EQUAL(&(Tab
->BssEntry
[i
].Bssid
), Bssid
) &&
3482 (SSID_EQUAL(pSsid
, SsidLen
, Tab
->BssEntry
[i
].Ssid
, Tab
->BssEntry
[i
].SsidLen
) ||
3483 (NdisEqualMemory(pSsid
, ZeroSsid
, SsidLen
)) ||
3484 (NdisEqualMemory(Tab
->BssEntry
[i
].Ssid
, ZeroSsid
, Tab
->BssEntry
[i
].SsidLen
))))
3489 return (ULONG
)BSS_NOT_FOUND
;
3492 // IRQL = DISPATCH_LEVEL
3493 VOID
BssTableDeleteEntry(
3494 IN OUT BSS_TABLE
*Tab
,
3500 for (i
= 0; i
< Tab
->BssNr
; i
++)
3502 if ((Tab
->BssEntry
[i
].Channel
== Channel
) &&
3503 (MAC_ADDR_EQUAL(Tab
->BssEntry
[i
].Bssid
, pBssid
)))
3505 for (j
= i
; j
< Tab
->BssNr
- 1; j
++)
3507 NdisMoveMemory(&(Tab
->BssEntry
[j
]), &(Tab
->BssEntry
[j
+ 1]), sizeof(BSS_ENTRY
));
3509 NdisZeroMemory(&(Tab
->BssEntry
[Tab
->BssNr
- 1]), sizeof(BSS_ENTRY
));
3517 ========================================================================
3518 Routine Description:
3519 Delete the Originator Entry in BAtable. Or decrease numAs Originator by 1 if needed.
3522 // IRQL = DISPATCH_LEVEL
3523 ========================================================================
3525 VOID
BATableDeleteORIEntry(
3526 IN OUT PRTMP_ADAPTER pAd
,
3527 IN BA_ORI_ENTRY
*pBAORIEntry
)
3530 if (pBAORIEntry
->ORI_BA_Status
!= Originator_NONE
)
3532 NdisAcquireSpinLock(&pAd
->BATabLock
);
3533 if (pBAORIEntry
->ORI_BA_Status
== Originator_Done
)
3535 pAd
->BATable
.numAsOriginator
-= 1;
3536 DBGPRINT(RT_DEBUG_TRACE
, ("BATableDeleteORIEntry numAsOriginator= %ld\n", pAd
->BATable
.numAsRecipient
));
3537 // Erase Bitmap flag.
3539 pAd
->MacTab
.Content
[pBAORIEntry
->Wcid
].TXBAbitmap
&= (~(1<<(pBAORIEntry
->TID
) )); // If STA mode, erase flag here
3540 pAd
->MacTab
.Content
[pBAORIEntry
->Wcid
].BAOriWcidArray
[pBAORIEntry
->TID
] = 0; // If STA mode, erase flag here
3541 pBAORIEntry
->ORI_BA_Status
= Originator_NONE
;
3542 pBAORIEntry
->Token
= 1;
3543 // Not clear Sequence here.
3544 NdisReleaseSpinLock(&pAd
->BATabLock
);
3554 IRQL = DISPATCH_LEVEL
3558 IN PRTMP_ADAPTER pAd
,
3559 OUT BSS_ENTRY
*pBss
,
3564 IN USHORT BeaconPeriod
,
3565 IN PCF_PARM pCfParm
,
3567 IN USHORT CapabilityInfo
,
3569 IN UCHAR SupRateLen
,
3571 IN UCHAR ExtRateLen
,
3572 IN HT_CAPABILITY_IE
*pHtCapability
,
3573 IN ADD_HT_INFO_IE
*pAddHtInfo
, // AP might use this additional ht info IE
3574 IN UCHAR HtCapabilityLen
,
3575 IN UCHAR AddHtInfoLen
,
3576 IN UCHAR NewExtChanOffset
,
3579 IN LARGE_INTEGER TimeStamp
,
3581 IN PEDCA_PARM pEdcaParm
,
3582 IN PQOS_CAPABILITY_PARM pQosCapability
,
3583 IN PQBSS_LOAD_PARM pQbssLoad
,
3584 IN USHORT LengthVIE
,
3585 IN PNDIS_802_11_VARIABLE_IEs pVIE
)
3587 COPY_MAC_ADDR(pBss
->Bssid
, pBssid
);
3588 // Default Hidden SSID to be TRUE, it will be turned to FALSE after coping SSID
3592 // For hidden SSID AP, it might send beacon with SSID len equal to 0
3593 // Or send beacon /probe response with SSID len matching real SSID length,
3594 // but SSID is all zero. such as "00-00-00-00" with length 4.
3595 // We have to prevent this case overwrite correct table
3596 if (NdisEqualMemory(Ssid
, ZeroSsid
, SsidLen
) == 0)
3598 NdisZeroMemory(pBss
->Ssid
, MAX_LEN_OF_SSID
);
3599 NdisMoveMemory(pBss
->Ssid
, Ssid
, SsidLen
);
3600 pBss
->SsidLen
= SsidLen
;
3606 pBss
->BssType
= BssType
;
3607 pBss
->BeaconPeriod
= BeaconPeriod
;
3608 if (BssType
== BSS_INFRA
)
3610 if (pCfParm
->bValid
)
3612 pBss
->CfpCount
= pCfParm
->CfpCount
;
3613 pBss
->CfpPeriod
= pCfParm
->CfpPeriod
;
3614 pBss
->CfpMaxDuration
= pCfParm
->CfpMaxDuration
;
3615 pBss
->CfpDurRemaining
= pCfParm
->CfpDurRemaining
;
3620 pBss
->AtimWin
= AtimWin
;
3623 pBss
->CapabilityInfo
= CapabilityInfo
;
3624 // The privacy bit indicate security is ON, it maight be WEP, TKIP or AES
3625 // Combine with AuthMode, they will decide the connection methods.
3626 pBss
->Privacy
= CAP_IS_PRIVACY_ON(pBss
->CapabilityInfo
);
3627 ASSERT(SupRateLen
<= MAX_LEN_OF_SUPPORTED_RATES
);
3628 if (SupRateLen
<= MAX_LEN_OF_SUPPORTED_RATES
)
3629 NdisMoveMemory(pBss
->SupRate
, SupRate
, SupRateLen
);
3631 NdisMoveMemory(pBss
->SupRate
, SupRate
, MAX_LEN_OF_SUPPORTED_RATES
);
3632 pBss
->SupRateLen
= SupRateLen
;
3633 ASSERT(ExtRateLen
<= MAX_LEN_OF_SUPPORTED_RATES
);
3634 NdisMoveMemory(pBss
->ExtRate
, ExtRate
, ExtRateLen
);
3635 NdisMoveMemory(&pBss
->HtCapability
, pHtCapability
, HtCapabilityLen
);
3636 NdisMoveMemory(&pBss
->AddHtInfo
, pAddHtInfo
, AddHtInfoLen
);
3637 pBss
->NewExtChanOffset
= NewExtChanOffset
;
3638 pBss
->ExtRateLen
= ExtRateLen
;
3639 pBss
->Channel
= Channel
;
3640 pBss
->CentralChannel
= Channel
;
3642 // Update CkipFlag. if not exists, the value is 0x0
3643 pBss
->CkipFlag
= CkipFlag
;
3645 // New for microsoft Fixed IEs
3646 NdisMoveMemory(pBss
->FixIEs
.Timestamp
, &TimeStamp
, 8);
3647 pBss
->FixIEs
.BeaconInterval
= BeaconPeriod
;
3648 pBss
->FixIEs
.Capabilities
= CapabilityInfo
;
3650 // New for microsoft Variable IEs
3653 pBss
->VarIELen
= LengthVIE
;
3654 NdisMoveMemory(pBss
->VarIEs
, pVIE
, pBss
->VarIELen
);
3661 pBss
->AddHtInfoLen
= 0;
3662 pBss
->HtCapabilityLen
= 0;
3664 if (HtCapabilityLen
> 0)
3666 pBss
->HtCapabilityLen
= HtCapabilityLen
;
3667 NdisMoveMemory(&pBss
->HtCapability
, pHtCapability
, HtCapabilityLen
);
3668 if (AddHtInfoLen
> 0)
3670 pBss
->AddHtInfoLen
= AddHtInfoLen
;
3671 NdisMoveMemory(&pBss
->AddHtInfo
, pAddHtInfo
, AddHtInfoLen
);
3673 if ((pAddHtInfo
->ControlChan
> 2)&& (pAddHtInfo
->AddHtInfo
.ExtChanOffset
== EXTCHA_BELOW
) && (pHtCapability
->HtCapInfo
.ChannelWidth
== BW_40
))
3675 pBss
->CentralChannel
= pAddHtInfo
->ControlChan
- 2;
3677 else if ((pAddHtInfo
->AddHtInfo
.ExtChanOffset
== EXTCHA_ABOVE
) && (pHtCapability
->HtCapInfo
.ChannelWidth
== BW_40
))
3679 pBss
->CentralChannel
= pAddHtInfo
->ControlChan
+ 2;
3684 BssCipherParse(pBss
);
3688 NdisMoveMemory(&pBss
->EdcaParm
, pEdcaParm
, sizeof(EDCA_PARM
));
3690 pBss
->EdcaParm
.bValid
= FALSE
;
3692 NdisMoveMemory(&pBss
->QosCapability
, pQosCapability
, sizeof(QOS_CAPABILITY_PARM
));
3694 pBss
->QosCapability
.bValid
= FALSE
;
3696 NdisMoveMemory(&pBss
->QbssLoad
, pQbssLoad
, sizeof(QBSS_LOAD_PARM
));
3698 pBss
->QbssLoad
.bValid
= FALSE
;
3705 NdisZeroMemory(&pBss
->WpaIE
.IE
[0], MAX_CUSTOM_LEN
);
3706 NdisZeroMemory(&pBss
->RsnIE
.IE
[0], MAX_CUSTOM_LEN
);
3708 pEid
= (PEID_STRUCT
) pVIE
;
3710 while ((Length
+ 2 + (USHORT
)pEid
->Len
) <= LengthVIE
)
3715 if (NdisEqualMemory(pEid
->Octet
, WPA_OUI
, 4))
3717 if ((pEid
->Len
+ 2) > MAX_CUSTOM_LEN
)
3719 pBss
->WpaIE
.IELen
= 0;
3722 pBss
->WpaIE
.IELen
= pEid
->Len
+ 2;
3723 NdisMoveMemory(pBss
->WpaIE
.IE
, pEid
, pBss
->WpaIE
.IELen
);
3727 if (NdisEqualMemory(pEid
->Octet
+ 2, RSN_OUI
, 3))
3729 if ((pEid
->Len
+ 2) > MAX_CUSTOM_LEN
)
3731 pBss
->RsnIE
.IELen
= 0;
3734 pBss
->RsnIE
.IELen
= pEid
->Len
+ 2;
3735 NdisMoveMemory(pBss
->RsnIE
.IE
, pEid
, pBss
->RsnIE
.IELen
);
3739 Length
= Length
+ 2 + (USHORT
)pEid
->Len
; // Eid[1] + Len[1]+ content[Len]
3740 pEid
= (PEID_STRUCT
)((UCHAR
*)pEid
+ 2 + pEid
->Len
);
3746 * \brief insert an entry into the bss table
3747 * \param p_tab The BSS table
3748 * \param Bssid BSSID
3750 * \param ssid_len Length of SSID
3752 * \param beacon_period
3759 * \param channel_idx
3763 * \note If SSID is identical, the old entry will be replaced by the new one
3765 IRQL = DISPATCH_LEVEL
3768 ULONG
BssTableSetEntry(
3769 IN PRTMP_ADAPTER pAd
,
3775 IN USHORT BeaconPeriod
,
3778 IN USHORT CapabilityInfo
,
3780 IN UCHAR SupRateLen
,
3782 IN UCHAR ExtRateLen
,
3783 IN HT_CAPABILITY_IE
*pHtCapability
,
3784 IN ADD_HT_INFO_IE
*pAddHtInfo
, // AP might use this additional ht info IE
3785 IN UCHAR HtCapabilityLen
,
3786 IN UCHAR AddHtInfoLen
,
3787 IN UCHAR NewExtChanOffset
,
3790 IN LARGE_INTEGER TimeStamp
,
3792 IN PEDCA_PARM pEdcaParm
,
3793 IN PQOS_CAPABILITY_PARM pQosCapability
,
3794 IN PQBSS_LOAD_PARM pQbssLoad
,
3795 IN USHORT LengthVIE
,
3796 IN PNDIS_802_11_VARIABLE_IEs pVIE
)
3800 Idx
= BssTableSearchWithSSID(Tab
, pBssid
, Ssid
, SsidLen
, ChannelNo
);
3801 if (Idx
== BSS_NOT_FOUND
)
3803 if (Tab
->BssNr
>= MAX_LEN_OF_BSS_TABLE
)
3806 // It may happen when BSS Table was full.
3807 // The desired AP will not be added into BSS Table
3808 // In this case, if we found the desired AP then overwrite BSS Table.
3810 if(!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
3812 if (MAC_ADDR_EQUAL(pAd
->MlmeAux
.Bssid
, pBssid
) ||
3813 SSID_EQUAL(pAd
->MlmeAux
.Ssid
, pAd
->MlmeAux
.SsidLen
, Ssid
, SsidLen
))
3815 Idx
= Tab
->BssOverlapNr
;
3816 BssEntrySet(pAd
, &Tab
->BssEntry
[Idx
], pBssid
, Ssid
, SsidLen
, BssType
, BeaconPeriod
, CfParm
, AtimWin
,
3817 CapabilityInfo
, SupRate
, SupRateLen
, ExtRate
, ExtRateLen
,pHtCapability
, pAddHtInfo
,HtCapabilityLen
, AddHtInfoLen
,
3818 NewExtChanOffset
, ChannelNo
, Rssi
, TimeStamp
, CkipFlag
, pEdcaParm
, pQosCapability
, pQbssLoad
, LengthVIE
, pVIE
);
3819 Tab
->BssOverlapNr
= (Tab
->BssOverlapNr
++) % MAX_LEN_OF_BSS_TABLE
;
3825 return BSS_NOT_FOUND
;
3829 BssEntrySet(pAd
, &Tab
->BssEntry
[Idx
], pBssid
, Ssid
, SsidLen
, BssType
, BeaconPeriod
, CfParm
, AtimWin
,
3830 CapabilityInfo
, SupRate
, SupRateLen
, ExtRate
, ExtRateLen
,pHtCapability
, pAddHtInfo
,HtCapabilityLen
, AddHtInfoLen
,
3831 NewExtChanOffset
, ChannelNo
, Rssi
, TimeStamp
, CkipFlag
, pEdcaParm
, pQosCapability
, pQbssLoad
, LengthVIE
, pVIE
);
3836 /* avoid Hidden SSID form beacon to overwirite correct SSID from probe response */
3837 if ((SSID_EQUAL(Ssid
, SsidLen
, Tab
->BssEntry
[Idx
].Ssid
, Tab
->BssEntry
[Idx
].SsidLen
)) ||
3838 (NdisEqualMemory(Tab
->BssEntry
[Idx
].Ssid
, ZeroSsid
, Tab
->BssEntry
[Idx
].SsidLen
)))
3840 BssEntrySet(pAd
, &Tab
->BssEntry
[Idx
], pBssid
, Ssid
, SsidLen
, BssType
, BeaconPeriod
,CfParm
, AtimWin
,
3841 CapabilityInfo
, SupRate
, SupRateLen
, ExtRate
, ExtRateLen
,pHtCapability
, pAddHtInfo
,HtCapabilityLen
, AddHtInfoLen
,
3842 NewExtChanOffset
, ChannelNo
, Rssi
, TimeStamp
, CkipFlag
, pEdcaParm
, pQosCapability
, pQbssLoad
, LengthVIE
, pVIE
);
3849 // IRQL = DISPATCH_LEVEL
3850 VOID
BssTableSsidSort(
3851 IN PRTMP_ADAPTER pAd
,
3852 OUT BSS_TABLE
*OutTab
,
3857 BssTableInit(OutTab
);
3859 for (i
= 0; i
< pAd
->ScanTab
.BssNr
; i
++)
3861 BSS_ENTRY
*pInBss
= &pAd
->ScanTab
.BssEntry
[i
];
3862 BOOLEAN bIsHiddenApIncluded
= FALSE
;
3864 if (((pAd
->CommonCfg
.bIEEE80211H
== 1) &&
3865 (pAd
->MlmeAux
.Channel
> 14) &&
3866 RadarChannelCheck(pAd
, pInBss
->Channel
))
3870 bIsHiddenApIncluded
= TRUE
;
3873 if ((pInBss
->BssType
== pAd
->StaCfg
.BssType
) &&
3874 (SSID_EQUAL(Ssid
, SsidLen
, pInBss
->Ssid
, pInBss
->SsidLen
) || bIsHiddenApIncluded
))
3876 BSS_ENTRY
*pOutBss
= &OutTab
->BssEntry
[OutTab
->BssNr
];
3878 // 2.4G/5G N only mode
3879 if ((pInBss
->HtCapabilityLen
== 0) &&
3880 ((pAd
->CommonCfg
.PhyMode
== PHY_11N_2_4G
) || (pAd
->CommonCfg
.PhyMode
== PHY_11N_5G
)))
3882 DBGPRINT(RT_DEBUG_TRACE
,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
3887 // Check the Authmode first
3888 if (pAd
->StaCfg
.AuthMode
>= Ndis802_11AuthModeWPA
)
3890 // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
3891 if ((pAd
->StaCfg
.AuthMode
!= pInBss
->AuthMode
) && (pAd
->StaCfg
.AuthMode
!= pInBss
->AuthModeAux
))
3895 // Check cipher suite, AP must have more secured cipher than station setting
3896 if ((pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA
) || (pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPAPSK
))
3898 // If it's not mixed mode, we should only let BSS pass with the same encryption
3899 if (pInBss
->WPA
.bMixMode
== FALSE
)
3900 if (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA
.GroupCipher
)
3903 // check group cipher
3904 if (pInBss
->WPA
.GroupCipher
!= Ndis802_11GroupWEP40Enabled
&&
3905 pInBss
->WPA
.GroupCipher
!= Ndis802_11GroupWEP104Enabled
&&
3906 pAd
->StaCfg
.WepStatus
< pInBss
->WPA
.GroupCipher
)
3909 // check pairwise cipher, skip if none matched
3910 // If profile set to AES, let it pass without question.
3911 // If profile set to TKIP, we must find one mateched
3912 if ((pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption2Enabled
) &&
3913 (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA
.PairCipher
) &&
3914 (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA
.PairCipherAux
))
3917 else if ((pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA2
) || (pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA2PSK
))
3919 // If it's not mixed mode, we should only let BSS pass with the same encryption
3920 if (pInBss
->WPA2
.bMixMode
== FALSE
)
3921 if (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA2
.GroupCipher
)
3924 // check group cipher
3925 if (pInBss
->WPA2
.GroupCipher
!= Ndis802_11GroupWEP40Enabled
&&
3926 pInBss
->WPA2
.GroupCipher
!= Ndis802_11GroupWEP104Enabled
&&
3927 pAd
->StaCfg
.WepStatus
< pInBss
->WPA2
.GroupCipher
)
3930 // check pairwise cipher, skip if none matched
3931 // If profile set to AES, let it pass without question.
3932 // If profile set to TKIP, we must find one mateched
3933 if ((pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption2Enabled
) &&
3934 (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA2
.PairCipher
) &&
3935 (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA2
.PairCipherAux
))
3939 // Bss Type matched, SSID matched.
3940 // We will check wepstatus for qualification Bss
3941 else if (pAd
->StaCfg
.WepStatus
!= pInBss
->WepStatus
)
3943 DBGPRINT(RT_DEBUG_TRACE
,("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n", pAd
->StaCfg
.WepStatus
, pInBss
->WepStatus
));
3945 // For the SESv2 case, we will not qualify WepStatus.
3951 // Since the AP is using hidden SSID, and we are trying to connect to ANY
3952 // It definitely will fail. So, skip it.
3953 // CCX also require not even try to connect it!!
3957 // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
3958 // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
3959 if ((pInBss
->CentralChannel
!= pInBss
->Channel
) &&
3960 (pAd
->CommonCfg
.RegTransmitSetting
.field
.BW
== BW_40
))
3962 if (RTMPCheckChannel(pAd
, pInBss
->CentralChannel
, pInBss
->Channel
) == FALSE
)
3964 pAd
->CommonCfg
.RegTransmitSetting
.field
.BW
= BW_20
;
3966 pAd
->CommonCfg
.RegTransmitSetting
.field
.BW
= BW_40
;
3970 if (pAd
->CommonCfg
.DesiredHtPhy
.ChannelWidth
== BAND_WIDTH_20
)
3977 // copy matching BSS from InTab to OutTab
3978 NdisMoveMemory(pOutBss
, pInBss
, sizeof(BSS_ENTRY
));
3982 else if ((pInBss
->BssType
== pAd
->StaCfg
.BssType
) && (SsidLen
== 0))
3984 BSS_ENTRY
*pOutBss
= &OutTab
->BssEntry
[OutTab
->BssNr
];
3986 // 2.4G/5G N only mode
3987 if ((pInBss
->HtCapabilityLen
== 0) &&
3988 ((pAd
->CommonCfg
.PhyMode
== PHY_11N_2_4G
) || (pAd
->CommonCfg
.PhyMode
== PHY_11N_5G
)))
3990 DBGPRINT(RT_DEBUG_TRACE
,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
3995 // Check the Authmode first
3996 if (pAd
->StaCfg
.AuthMode
>= Ndis802_11AuthModeWPA
)
3998 // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
3999 if ((pAd
->StaCfg
.AuthMode
!= pInBss
->AuthMode
) && (pAd
->StaCfg
.AuthMode
!= pInBss
->AuthModeAux
))
4003 // Check cipher suite, AP must have more secured cipher than station setting
4004 if ((pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA
) || (pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPAPSK
))
4006 // If it's not mixed mode, we should only let BSS pass with the same encryption
4007 if (pInBss
->WPA
.bMixMode
== FALSE
)
4008 if (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA
.GroupCipher
)
4011 // check group cipher
4012 if (pAd
->StaCfg
.WepStatus
< pInBss
->WPA
.GroupCipher
)
4015 // check pairwise cipher, skip if none matched
4016 // If profile set to AES, let it pass without question.
4017 // If profile set to TKIP, we must find one mateched
4018 if ((pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption2Enabled
) &&
4019 (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA
.PairCipher
) &&
4020 (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA
.PairCipherAux
))
4023 else if ((pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA2
) || (pAd
->StaCfg
.AuthMode
== Ndis802_11AuthModeWPA2PSK
))
4025 // If it's not mixed mode, we should only let BSS pass with the same encryption
4026 if (pInBss
->WPA2
.bMixMode
== FALSE
)
4027 if (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA2
.GroupCipher
)
4030 // check group cipher
4031 if (pAd
->StaCfg
.WepStatus
< pInBss
->WPA2
.GroupCipher
)
4034 // check pairwise cipher, skip if none matched
4035 // If profile set to AES, let it pass without question.
4036 // If profile set to TKIP, we must find one mateched
4037 if ((pAd
->StaCfg
.WepStatus
== Ndis802_11Encryption2Enabled
) &&
4038 (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA2
.PairCipher
) &&
4039 (pAd
->StaCfg
.WepStatus
!= pInBss
->WPA2
.PairCipherAux
))
4043 // Bss Type matched, SSID matched.
4044 // We will check wepstatus for qualification Bss
4045 else if (pAd
->StaCfg
.WepStatus
!= pInBss
->WepStatus
)
4048 // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
4049 // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
4050 if ((pInBss
->CentralChannel
!= pInBss
->Channel
) &&
4051 (pAd
->CommonCfg
.RegTransmitSetting
.field
.BW
== BW_40
))
4053 if (RTMPCheckChannel(pAd
, pInBss
->CentralChannel
, pInBss
->Channel
) == FALSE
)
4055 pAd
->CommonCfg
.RegTransmitSetting
.field
.BW
= BW_20
;
4057 pAd
->CommonCfg
.RegTransmitSetting
.field
.BW
= BW_40
;
4061 // copy matching BSS from InTab to OutTab
4062 NdisMoveMemory(pOutBss
, pInBss
, sizeof(BSS_ENTRY
));
4067 if (OutTab
->BssNr
>= MAX_LEN_OF_BSS_TABLE
)
4071 BssTableSortByRssi(OutTab
);
4075 // IRQL = DISPATCH_LEVEL
4076 VOID
BssTableSortByRssi(
4077 IN OUT BSS_TABLE
*OutTab
)
4082 for (i
= 0; i
< OutTab
->BssNr
- 1; i
++)
4084 for (j
= i
+1; j
< OutTab
->BssNr
; j
++)
4086 if (OutTab
->BssEntry
[j
].Rssi
> OutTab
->BssEntry
[i
].Rssi
)
4088 NdisMoveMemory(&TmpBss
, &OutTab
->BssEntry
[j
], sizeof(BSS_ENTRY
));
4089 NdisMoveMemory(&OutTab
->BssEntry
[j
], &OutTab
->BssEntry
[i
], sizeof(BSS_ENTRY
));
4090 NdisMoveMemory(&OutTab
->BssEntry
[i
], &TmpBss
, sizeof(BSS_ENTRY
));
4096 VOID
BssCipherParse(
4097 IN OUT PBSS_ENTRY pBss
)
4101 PRSN_IE_HEADER_STRUCT pRsnHeader
;
4102 PCIPHER_SUITE_STRUCT pCipher
;
4103 PAKM_SUITE_STRUCT pAKM
;
4106 NDIS_802_11_ENCRYPTION_STATUS TmpCipher
;
4109 // WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame.
4113 pBss
->WepStatus
= Ndis802_11WEPEnabled
;
4117 pBss
->WepStatus
= Ndis802_11WEPDisabled
;
4119 // Set default to disable & open authentication before parsing variable IE
4120 pBss
->AuthMode
= Ndis802_11AuthModeOpen
;
4121 pBss
->AuthModeAux
= Ndis802_11AuthModeOpen
;
4124 pBss
->WPA
.PairCipher
= Ndis802_11WEPDisabled
;
4125 pBss
->WPA
.PairCipherAux
= Ndis802_11WEPDisabled
;
4126 pBss
->WPA
.GroupCipher
= Ndis802_11WEPDisabled
;
4127 pBss
->WPA
.RsnCapability
= 0;
4128 pBss
->WPA
.bMixMode
= FALSE
;
4130 // Init WPA2 setting
4131 pBss
->WPA2
.PairCipher
= Ndis802_11WEPDisabled
;
4132 pBss
->WPA2
.PairCipherAux
= Ndis802_11WEPDisabled
;
4133 pBss
->WPA2
.GroupCipher
= Ndis802_11WEPDisabled
;
4134 pBss
->WPA2
.RsnCapability
= 0;
4135 pBss
->WPA2
.bMixMode
= FALSE
;
4138 Length
= (INT
) pBss
->VarIELen
;
4142 // Parse cipher suite base on WPA1 & WPA2, they should be parsed differently
4143 pTmp
= ((PUCHAR
) pBss
->VarIEs
) + pBss
->VarIELen
- Length
;
4144 pEid
= (PEID_STRUCT
) pTmp
;
4148 //Parse Cisco IE_WPA (LEAP, CCKM, etc.)
4149 if ( NdisEqualMemory((pTmp
+8), CISCO_OUI
, 3))
4155 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4156 pBss
->WepStatus
= Ndis802_11Encryption1Enabled
;
4157 pBss
->WPA
.PairCipher
= Ndis802_11Encryption1Enabled
;
4158 pBss
->WPA
.GroupCipher
= Ndis802_11Encryption1Enabled
;
4161 pBss
->WepStatus
= Ndis802_11Encryption2Enabled
;
4162 pBss
->WPA
.PairCipher
= Ndis802_11Encryption1Enabled
;
4163 pBss
->WPA
.GroupCipher
= Ndis802_11Encryption1Enabled
;
4166 pBss
->WepStatus
= Ndis802_11Encryption3Enabled
;
4167 pBss
->WPA
.PairCipher
= Ndis802_11Encryption1Enabled
;
4168 pBss
->WPA
.GroupCipher
= Ndis802_11Encryption1Enabled
;
4174 // if Cisco IE_WPA, break
4177 else if (NdisEqualMemory(pEid
->Octet
, SES_OUI
, 3) && (pEid
->Len
== 7))
4182 else if (NdisEqualMemory(pEid
->Octet
, WPA_OUI
, 4) != 1)
4184 // if unsupported vendor specific IE
4187 // Skip OUI, version, and multicast suite
4188 // This part should be improved in the future when AP supported multiple cipher suite.
4189 // For now, it's OK since almost all APs have fixed cipher suite supported.
4190 // pTmp = (PUCHAR) pEid->Octet;
4193 // Cipher Suite Selectors from Spec P802.11i/D3.2 P26.
4201 // Parse group cipher
4205 pBss
->WPA
.GroupCipher
= Ndis802_11GroupWEP40Enabled
;
4208 pBss
->WPA
.GroupCipher
= Ndis802_11GroupWEP104Enabled
;
4211 pBss
->WPA
.GroupCipher
= Ndis802_11Encryption2Enabled
;
4214 pBss
->WPA
.GroupCipher
= Ndis802_11Encryption3Enabled
;
4219 // number of unicast suite
4222 // skip all unicast cipher suites
4223 //Count = *(PUSHORT) pTmp;
4224 Count
= (pTmp
[1]<<8) + pTmp
[0];
4225 pTmp
+= sizeof(USHORT
);
4227 // Parsing all unicast cipher suite
4232 TmpCipher
= Ndis802_11WEPDisabled
;
4236 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4237 TmpCipher
= Ndis802_11Encryption1Enabled
;
4240 TmpCipher
= Ndis802_11Encryption2Enabled
;
4243 TmpCipher
= Ndis802_11Encryption3Enabled
;
4248 if (TmpCipher
> pBss
->WPA
.PairCipher
)
4250 // Move the lower cipher suite to PairCipherAux
4251 pBss
->WPA
.PairCipherAux
= pBss
->WPA
.PairCipher
;
4252 pBss
->WPA
.PairCipher
= TmpCipher
;
4256 pBss
->WPA
.PairCipherAux
= TmpCipher
;
4262 // 4. get AKM suite counts
4263 //Count = *(PUSHORT) pTmp;
4264 Count
= (pTmp
[1]<<8) + pTmp
[0];
4265 pTmp
+= sizeof(USHORT
);
4271 // Set AP support WPA mode
4272 if (pBss
->AuthMode
== Ndis802_11AuthModeOpen
)
4273 pBss
->AuthMode
= Ndis802_11AuthModeWPA
;
4275 pBss
->AuthModeAux
= Ndis802_11AuthModeWPA
;
4278 // Set AP support WPA mode
4279 if (pBss
->AuthMode
== Ndis802_11AuthModeOpen
)
4280 pBss
->AuthMode
= Ndis802_11AuthModeWPAPSK
;
4282 pBss
->AuthModeAux
= Ndis802_11AuthModeWPAPSK
;
4289 // Fixed for WPA-None
4290 if (pBss
->BssType
== BSS_ADHOC
)
4292 pBss
->AuthMode
= Ndis802_11AuthModeWPANone
;
4293 pBss
->AuthModeAux
= Ndis802_11AuthModeWPANone
;
4294 pBss
->WepStatus
= pBss
->WPA
.GroupCipher
;
4295 if (pBss
->WPA
.PairCipherAux
== Ndis802_11WEPDisabled
)
4296 pBss
->WPA
.PairCipherAux
= pBss
->WPA
.GroupCipher
;
4299 pBss
->WepStatus
= pBss
->WPA
.PairCipher
;
4301 // Check the Pair & Group, if different, turn on mixed mode flag
4302 if (pBss
->WPA
.GroupCipher
!= pBss
->WPA
.PairCipher
)
4303 pBss
->WPA
.bMixMode
= TRUE
;
4308 pRsnHeader
= (PRSN_IE_HEADER_STRUCT
) pTmp
;
4310 // 0. Version must be 1
4311 if (le2cpu16(pRsnHeader
->Version
) != 1)
4313 pTmp
+= sizeof(RSN_IE_HEADER_STRUCT
);
4315 // 1. Check group cipher
4316 pCipher
= (PCIPHER_SUITE_STRUCT
) pTmp
;
4317 if (!RTMPEqualMemory(pTmp
, RSN_OUI
, 3))
4320 // Parse group cipher
4321 switch (pCipher
->Type
)
4324 pBss
->WPA2
.GroupCipher
= Ndis802_11GroupWEP40Enabled
;
4327 pBss
->WPA2
.GroupCipher
= Ndis802_11GroupWEP104Enabled
;
4330 pBss
->WPA2
.GroupCipher
= Ndis802_11Encryption2Enabled
;
4333 pBss
->WPA2
.GroupCipher
= Ndis802_11Encryption3Enabled
;
4338 // set to correct offset for next parsing
4339 pTmp
+= sizeof(CIPHER_SUITE_STRUCT
);
4341 // 2. Get pairwise cipher counts
4342 //Count = *(PUSHORT) pTmp;
4343 Count
= (pTmp
[1]<<8) + pTmp
[0];
4344 pTmp
+= sizeof(USHORT
);
4346 // 3. Get pairwise cipher
4347 // Parsing all unicast cipher suite
4351 pCipher
= (PCIPHER_SUITE_STRUCT
) pTmp
;
4352 TmpCipher
= Ndis802_11WEPDisabled
;
4353 switch (pCipher
->Type
)
4356 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4357 TmpCipher
= Ndis802_11Encryption1Enabled
;
4360 TmpCipher
= Ndis802_11Encryption2Enabled
;
4363 TmpCipher
= Ndis802_11Encryption3Enabled
;
4368 if (TmpCipher
> pBss
->WPA2
.PairCipher
)
4370 // Move the lower cipher suite to PairCipherAux
4371 pBss
->WPA2
.PairCipherAux
= pBss
->WPA2
.PairCipher
;
4372 pBss
->WPA2
.PairCipher
= TmpCipher
;
4376 pBss
->WPA2
.PairCipherAux
= TmpCipher
;
4378 pTmp
+= sizeof(CIPHER_SUITE_STRUCT
);
4382 // 4. get AKM suite counts
4383 //Count = *(PUSHORT) pTmp;
4384 Count
= (pTmp
[1]<<8) + pTmp
[0];
4385 pTmp
+= sizeof(USHORT
);
4387 // 5. Get AKM ciphers
4388 pAKM
= (PAKM_SUITE_STRUCT
) pTmp
;
4389 if (!RTMPEqualMemory(pTmp
, RSN_OUI
, 3))
4395 // Set AP support WPA mode
4396 if (pBss
->AuthMode
== Ndis802_11AuthModeOpen
)
4397 pBss
->AuthMode
= Ndis802_11AuthModeWPA2
;
4399 pBss
->AuthModeAux
= Ndis802_11AuthModeWPA2
;
4402 // Set AP support WPA mode
4403 if (pBss
->AuthMode
== Ndis802_11AuthModeOpen
)
4404 pBss
->AuthMode
= Ndis802_11AuthModeWPA2PSK
;
4406 pBss
->AuthModeAux
= Ndis802_11AuthModeWPA2PSK
;
4411 pTmp
+= (Count
* sizeof(AKM_SUITE_STRUCT
));
4413 // Fixed for WPA-None
4414 if (pBss
->BssType
== BSS_ADHOC
)
4416 pBss
->AuthMode
= Ndis802_11AuthModeWPANone
;
4417 pBss
->AuthModeAux
= Ndis802_11AuthModeWPANone
;
4418 pBss
->WPA
.PairCipherAux
= pBss
->WPA2
.PairCipherAux
;
4419 pBss
->WPA
.GroupCipher
= pBss
->WPA2
.GroupCipher
;
4420 pBss
->WepStatus
= pBss
->WPA
.GroupCipher
;
4421 if (pBss
->WPA
.PairCipherAux
== Ndis802_11WEPDisabled
)
4422 pBss
->WPA
.PairCipherAux
= pBss
->WPA
.GroupCipher
;
4424 pBss
->WepStatus
= pBss
->WPA2
.PairCipher
;
4426 // 6. Get RSN capability
4427 //pBss->WPA2.RsnCapability = *(PUSHORT) pTmp;
4428 pBss
->WPA2
.RsnCapability
= (pTmp
[1]<<8) + pTmp
[0];
4429 pTmp
+= sizeof(USHORT
);
4431 // Check the Pair & Group, if different, turn on mixed mode flag
4432 if (pBss
->WPA2
.GroupCipher
!= pBss
->WPA2
.PairCipher
)
4433 pBss
->WPA2
.bMixMode
= TRUE
;
4439 Length
-= (pEid
->Len
+ 2);
4443 // ===========================================================================================
4445 // ===========================================================================================
4447 /*! \brief generates a random mac address value for IBSS BSSID
4448 * \param Addr the bssid location
4453 VOID
MacAddrRandomBssid(
4454 IN PRTMP_ADAPTER pAd
,
4459 for (i
= 0; i
< MAC_ADDR_LEN
; i
++)
4461 pAddr
[i
] = RandomByte(pAd
);
4464 pAddr
[0] = (pAddr
[0] & 0xfe) | 0x02; // the first 2 bits must be 01xxxxxxxx
4467 /*! \brief init the management mac frame header
4468 * \param p_hdr mac header
4469 * \param subtype subtype of the frame
4470 * \param p_ds destination address, don't care if it is a broadcast address
4472 * \pre the station has the following information in the pAd->StaCfg
4476 * \note this function initializes the following field
4478 IRQL = PASSIVE_LEVEL
4479 IRQL = DISPATCH_LEVEL
4482 VOID
MgtMacHeaderInit(
4483 IN PRTMP_ADAPTER pAd
,
4484 IN OUT PHEADER_802_11 pHdr80211
,
4490 NdisZeroMemory(pHdr80211
, sizeof(HEADER_802_11
));
4492 pHdr80211
->FC
.Type
= BTYPE_MGMT
;
4493 pHdr80211
->FC
.SubType
= SubType
;
4494 pHdr80211
->FC
.ToDs
= ToDs
;
4495 COPY_MAC_ADDR(pHdr80211
->Addr1
, pDA
);
4497 COPY_MAC_ADDR(pHdr80211
->Addr2
, pAd
->CurrentAddress
);
4499 COPY_MAC_ADDR(pHdr80211
->Addr3
, pBssid
);
4502 // ===========================================================================================
4504 // ===========================================================================================
4506 /*!***************************************************************************
4507 * This routine build an outgoing frame, and fill all information specified
4508 * in argument list to the frame body. The actual frame size is the summation
4511 * Buffer - pointer to a pre-allocated memory segment
4512 * args - a list of <int arg_size, arg> pairs.
4513 * NOTE NOTE NOTE!!!! the last argument must be NULL, otherwise this
4514 * function will FAIL!!!
4516 * Size of the buffer
4518 * MakeOutgoingFrame(Buffer, output_length, 2, &fc, 2, &dur, 6, p_addr1, 6,p_addr2, END_OF_ARGS);
4520 IRQL = PASSIVE_LEVEL
4521 IRQL = DISPATCH_LEVEL
4523 ****************************************************************************/
4524 ULONG
MakeOutgoingFrame(
4526 OUT ULONG
*FrameLen
, ...)
4533 // calculates the total length
4535 va_start(Args
, FrameLen
);
4538 leng
= va_arg(Args
, int);
4539 if (leng
== END_OF_ARGS
)
4543 p
= va_arg(Args
, PVOID
);
4544 NdisMoveMemory(&Buffer
[TotLeng
], p
, leng
);
4545 TotLeng
= TotLeng
+ leng
;
4548 va_end(Args
); /* clean up */
4549 *FrameLen
= TotLeng
;
4553 // ===========================================================================================
4555 // ===========================================================================================
4557 /*! \brief Initialize The MLME Queue, used by MLME Functions
4558 * \param *Queue The MLME Queue
4559 * \return Always Return NDIS_STATE_SUCCESS in this implementation
4562 * \note Because this is done only once (at the init stage), no need to be locked
4564 IRQL = PASSIVE_LEVEL
4567 NDIS_STATUS
MlmeQueueInit(
4568 IN MLME_QUEUE
*Queue
)
4572 NdisAllocateSpinLock(&Queue
->Lock
);
4578 for (i
= 0; i
< MAX_LEN_OF_MLME_QUEUE
; i
++)
4580 Queue
->Entry
[i
].Occupied
= FALSE
;
4581 Queue
->Entry
[i
].MsgLen
= 0;
4582 NdisZeroMemory(Queue
->Entry
[i
].Msg
, MGMT_DMA_BUFFER_SIZE
);
4585 return NDIS_STATUS_SUCCESS
;
4588 /*! \brief Enqueue a message for other threads, if they want to send messages to MLME thread
4589 * \param *Queue The MLME Queue
4590 * \param Machine The State Machine Id
4591 * \param MsgType The Message Type
4592 * \param MsgLen The Message length
4593 * \param *Msg The message pointer
4594 * \return TRUE if enqueue is successful, FALSE if the queue is full
4597 * \note The message has to be initialized
4599 IRQL = PASSIVE_LEVEL
4600 IRQL = DISPATCH_LEVEL
4603 BOOLEAN
MlmeEnqueue(
4604 IN PRTMP_ADAPTER pAd
,
4611 MLME_QUEUE
*Queue
= (MLME_QUEUE
*)&pAd
->Mlme
.Queue
;
4613 // Do nothing if the driver is starting halt state.
4614 // This might happen when timer already been fired before cancel timer with mlmehalt
4615 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
| fRTMP_ADAPTER_NIC_NOT_EXIST
))
4618 // First check the size, it MUST not exceed the mlme queue size
4619 if (MsgLen
> MGMT_DMA_BUFFER_SIZE
)
4621 DBGPRINT_ERR(("MlmeEnqueue: msg too large, size = %ld \n", MsgLen
));
4625 if (MlmeQueueFull(Queue
))
4630 NdisAcquireSpinLock(&(Queue
->Lock
));
4634 if (Queue
->Tail
== MAX_LEN_OF_MLME_QUEUE
)
4639 Queue
->Entry
[Tail
].Wcid
= RESERVED_WCID
;
4640 Queue
->Entry
[Tail
].Occupied
= TRUE
;
4641 Queue
->Entry
[Tail
].Machine
= Machine
;
4642 Queue
->Entry
[Tail
].MsgType
= MsgType
;
4643 Queue
->Entry
[Tail
].MsgLen
= MsgLen
;
4647 NdisMoveMemory(Queue
->Entry
[Tail
].Msg
, Msg
, MsgLen
);
4650 NdisReleaseSpinLock(&(Queue
->Lock
));
4654 /*! \brief This function is used when Recv gets a MLME message
4655 * \param *Queue The MLME Queue
4656 * \param TimeStampHigh The upper 32 bit of timestamp
4657 * \param TimeStampLow The lower 32 bit of timestamp
4658 * \param Rssi The receiving RSSI strength
4659 * \param MsgLen The length of the message
4660 * \param *Msg The message pointer
4661 * \return TRUE if everything ok, FALSE otherwise (like Queue Full)
4665 IRQL = DISPATCH_LEVEL
4668 BOOLEAN
MlmeEnqueueForRecv(
4669 IN PRTMP_ADAPTER pAd
,
4671 IN ULONG TimeStampHigh
,
4672 IN ULONG TimeStampLow
,
4681 PFRAME_802_11 pFrame
= (PFRAME_802_11
)Msg
;
4683 MLME_QUEUE
*Queue
= (MLME_QUEUE
*)&pAd
->Mlme
.Queue
;
4685 // Do nothing if the driver is starting halt state.
4686 // This might happen when timer already been fired before cancel timer with mlmehalt
4687 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
| fRTMP_ADAPTER_NIC_NOT_EXIST
))
4689 DBGPRINT_ERR(("MlmeEnqueueForRecv: fRTMP_ADAPTER_HALT_IN_PROGRESS\n"));
4693 // First check the size, it MUST not exceed the mlme queue size
4694 if (MsgLen
> MGMT_DMA_BUFFER_SIZE
)
4696 DBGPRINT_ERR(("MlmeEnqueueForRecv: frame too large, size = %ld \n", MsgLen
));
4700 if (MlmeQueueFull(Queue
))
4706 if (!MsgTypeSubst(pAd
, pFrame
, &Machine
, &MsgType
))
4708 DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n",pFrame
->Hdr
.FC
.SubType
));
4713 // OK, we got all the informations, it is time to put things into queue
4714 NdisAcquireSpinLock(&(Queue
->Lock
));
4718 if (Queue
->Tail
== MAX_LEN_OF_MLME_QUEUE
)
4722 Queue
->Entry
[Tail
].Occupied
= TRUE
;
4723 Queue
->Entry
[Tail
].Machine
= Machine
;
4724 Queue
->Entry
[Tail
].MsgType
= MsgType
;
4725 Queue
->Entry
[Tail
].MsgLen
= MsgLen
;
4726 Queue
->Entry
[Tail
].TimeStamp
.u
.LowPart
= TimeStampLow
;
4727 Queue
->Entry
[Tail
].TimeStamp
.u
.HighPart
= TimeStampHigh
;
4728 Queue
->Entry
[Tail
].Rssi0
= Rssi0
;
4729 Queue
->Entry
[Tail
].Rssi1
= Rssi1
;
4730 Queue
->Entry
[Tail
].Rssi2
= Rssi2
;
4731 Queue
->Entry
[Tail
].Signal
= Signal
;
4732 Queue
->Entry
[Tail
].Wcid
= (UCHAR
)Wcid
;
4734 Queue
->Entry
[Tail
].Channel
= pAd
->LatchRfRegs
.Channel
;
4738 NdisMoveMemory(Queue
->Entry
[Tail
].Msg
, Msg
, MsgLen
);
4741 NdisReleaseSpinLock(&(Queue
->Lock
));
4743 RT28XX_MLME_HANDLER(pAd
);
4749 /*! \brief Dequeue a message from the MLME Queue
4750 * \param *Queue The MLME Queue
4751 * \param *Elem The message dequeued from MLME Queue
4752 * \return TRUE if the Elem contains something, FALSE otherwise
4756 IRQL = DISPATCH_LEVEL
4759 BOOLEAN
MlmeDequeue(
4760 IN MLME_QUEUE
*Queue
,
4761 OUT MLME_QUEUE_ELEM
**Elem
)
4763 NdisAcquireSpinLock(&(Queue
->Lock
));
4764 *Elem
= &(Queue
->Entry
[Queue
->Head
]);
4767 if (Queue
->Head
== MAX_LEN_OF_MLME_QUEUE
)
4771 NdisReleaseSpinLock(&(Queue
->Lock
));
4775 // IRQL = DISPATCH_LEVEL
4776 VOID
MlmeRestartStateMachine(
4777 IN PRTMP_ADAPTER pAd
)
4780 MLME_QUEUE_ELEM
*Elem
= NULL
;
4784 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeRestartStateMachine \n"));
4787 NdisAcquireSpinLock(&pAd
->Mlme
.TaskLock
);
4788 if(pAd
->Mlme
.bRunning
)
4790 NdisReleaseSpinLock(&pAd
->Mlme
.TaskLock
);
4795 pAd
->Mlme
.bRunning
= TRUE
;
4797 NdisReleaseSpinLock(&pAd
->Mlme
.TaskLock
);
4799 // Remove all Mlme queues elements
4800 while (!MlmeQueueEmpty(&pAd
->Mlme
.Queue
))
4802 //From message type, determine which state machine I should drive
4803 if (MlmeDequeue(&pAd
->Mlme
.Queue
, &Elem
))
4805 // free MLME element
4806 Elem
->Occupied
= FALSE
;
4811 DBGPRINT_ERR(("MlmeRestartStateMachine: MlmeQueue empty\n"));
4817 // Cancel all timer events
4818 // Be careful to cancel new added timer
4819 RTMPCancelTimer(&pAd
->MlmeAux
.AssocTimer
, &Cancelled
);
4820 RTMPCancelTimer(&pAd
->MlmeAux
.ReassocTimer
, &Cancelled
);
4821 RTMPCancelTimer(&pAd
->MlmeAux
.DisassocTimer
, &Cancelled
);
4822 RTMPCancelTimer(&pAd
->MlmeAux
.AuthTimer
, &Cancelled
);
4823 RTMPCancelTimer(&pAd
->MlmeAux
.BeaconTimer
, &Cancelled
);
4824 RTMPCancelTimer(&pAd
->MlmeAux
.ScanTimer
, &Cancelled
);
4827 // Change back to original channel in case of doing scan
4828 AsicSwitchChannel(pAd
, pAd
->CommonCfg
.Channel
, FALSE
);
4829 AsicLockChannel(pAd
, pAd
->CommonCfg
.Channel
);
4831 // Resume MSDU which is turned off durning scan
4832 RTMPResumeMsduTransmission(pAd
);
4835 // Set all state machines back IDLE
4836 pAd
->Mlme
.CntlMachine
.CurrState
= CNTL_IDLE
;
4837 pAd
->Mlme
.AssocMachine
.CurrState
= ASSOC_IDLE
;
4838 pAd
->Mlme
.AuthMachine
.CurrState
= AUTH_REQ_IDLE
;
4839 pAd
->Mlme
.AuthRspMachine
.CurrState
= AUTH_RSP_IDLE
;
4840 pAd
->Mlme
.SyncMachine
.CurrState
= SYNC_IDLE
;
4841 pAd
->Mlme
.ActMachine
.CurrState
= ACT_IDLE
;
4845 // Remove running state
4846 NdisAcquireSpinLock(&pAd
->Mlme
.TaskLock
);
4847 pAd
->Mlme
.bRunning
= FALSE
;
4848 NdisReleaseSpinLock(&pAd
->Mlme
.TaskLock
);
4852 /*! \brief test if the MLME Queue is empty
4853 * \param *Queue The MLME Queue
4854 * \return TRUE if the Queue is empty, FALSE otherwise
4858 IRQL = DISPATCH_LEVEL
4861 BOOLEAN
MlmeQueueEmpty(
4862 IN MLME_QUEUE
*Queue
)
4866 NdisAcquireSpinLock(&(Queue
->Lock
));
4867 Ans
= (Queue
->Num
== 0);
4868 NdisReleaseSpinLock(&(Queue
->Lock
));
4873 /*! \brief test if the MLME Queue is full
4874 * \param *Queue The MLME Queue
4875 * \return TRUE if the Queue is empty, FALSE otherwise
4879 IRQL = PASSIVE_LEVEL
4880 IRQL = DISPATCH_LEVEL
4883 BOOLEAN
MlmeQueueFull(
4884 IN MLME_QUEUE
*Queue
)
4888 NdisAcquireSpinLock(&(Queue
->Lock
));
4889 Ans
= (Queue
->Num
== MAX_LEN_OF_MLME_QUEUE
|| Queue
->Entry
[Queue
->Tail
].Occupied
);
4890 NdisReleaseSpinLock(&(Queue
->Lock
));
4895 /*! \brief The destructor of MLME Queue
4900 * \note Clear Mlme Queue, Set Queue->Num to Zero.
4902 IRQL = PASSIVE_LEVEL
4905 VOID
MlmeQueueDestroy(
4906 IN MLME_QUEUE
*pQueue
)
4908 NdisAcquireSpinLock(&(pQueue
->Lock
));
4912 NdisReleaseSpinLock(&(pQueue
->Lock
));
4913 NdisFreeSpinLock(&(pQueue
->Lock
));
4916 /*! \brief To substitute the message type if the message is coming from external
4917 * \param pFrame The frame received
4918 * \param *Machine The state machine
4919 * \param *MsgType the message type for the state machine
4920 * \return TRUE if the substitution is successful, FALSE otherwise
4924 IRQL = DISPATCH_LEVEL
4927 BOOLEAN
MsgTypeSubst(
4928 IN PRTMP_ADAPTER pAd
,
4929 IN PFRAME_802_11 pFrame
,
4937 // Pointer to start of data frames including SNAP header
4938 pData
= (PUCHAR
) pFrame
+ LENGTH_802_11
;
4940 // The only data type will pass to this function is EAPOL frame
4941 if (pFrame
->Hdr
.FC
.Type
== BTYPE_DATA
)
4943 if (NdisEqualMemory(SNAP_AIRONET
, pData
, LENGTH_802_1_H
))
4945 // Cisco Aironet SNAP header
4946 *Machine
= AIRONET_STATE_MACHINE
;
4947 *MsgType
= MT2_AIRONET_MSG
;
4951 *Machine
= WPA_PSK_STATE_MACHINE
;
4952 EAPType
= *((UCHAR
*)pFrame
+ LENGTH_802_11
+ LENGTH_802_1_H
+ 1);
4953 return(WpaMsgTypeSubst(EAPType
, MsgType
));
4957 switch (pFrame
->Hdr
.FC
.SubType
)
4959 case SUBTYPE_ASSOC_REQ
:
4960 *Machine
= ASSOC_STATE_MACHINE
;
4961 *MsgType
= MT2_PEER_ASSOC_REQ
;
4963 case SUBTYPE_ASSOC_RSP
:
4964 *Machine
= ASSOC_STATE_MACHINE
;
4965 *MsgType
= MT2_PEER_ASSOC_RSP
;
4967 case SUBTYPE_REASSOC_REQ
:
4968 *Machine
= ASSOC_STATE_MACHINE
;
4969 *MsgType
= MT2_PEER_REASSOC_REQ
;
4971 case SUBTYPE_REASSOC_RSP
:
4972 *Machine
= ASSOC_STATE_MACHINE
;
4973 *MsgType
= MT2_PEER_REASSOC_RSP
;
4975 case SUBTYPE_PROBE_REQ
:
4976 *Machine
= SYNC_STATE_MACHINE
;
4977 *MsgType
= MT2_PEER_PROBE_REQ
;
4979 case SUBTYPE_PROBE_RSP
:
4980 *Machine
= SYNC_STATE_MACHINE
;
4981 *MsgType
= MT2_PEER_PROBE_RSP
;
4983 case SUBTYPE_BEACON
:
4984 *Machine
= SYNC_STATE_MACHINE
;
4985 *MsgType
= MT2_PEER_BEACON
;
4988 *Machine
= SYNC_STATE_MACHINE
;
4989 *MsgType
= MT2_PEER_ATIM
;
4991 case SUBTYPE_DISASSOC
:
4992 *Machine
= ASSOC_STATE_MACHINE
;
4993 *MsgType
= MT2_PEER_DISASSOC_REQ
;
4996 // get the sequence number from payload 24 Mac Header + 2 bytes algorithm
4997 NdisMoveMemory(&Seq
, &pFrame
->Octet
[2], sizeof(USHORT
));
4998 if (Seq
== 1 || Seq
== 3)
5000 *Machine
= AUTH_RSP_STATE_MACHINE
;
5001 *MsgType
= MT2_PEER_AUTH_ODD
;
5003 else if (Seq
== 2 || Seq
== 4)
5005 *Machine
= AUTH_STATE_MACHINE
;
5006 *MsgType
= MT2_PEER_AUTH_EVEN
;
5013 case SUBTYPE_DEAUTH
:
5014 *Machine
= AUTH_RSP_STATE_MACHINE
;
5015 *MsgType
= MT2_PEER_DEAUTH
;
5017 case SUBTYPE_ACTION
:
5018 *Machine
= ACTION_STATE_MACHINE
;
5019 // Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support
5020 if ((pFrame
->Octet
[0]&0x7F) > MAX_PEER_CATE_MSG
)
5022 *MsgType
= MT2_ACT_INVALID
;
5026 *MsgType
= (pFrame
->Octet
[0]&0x7F);
5037 // ===========================================================================================
5039 // ===========================================================================================
5041 /*! \brief Initialize the state machine.
5042 * \param *S pointer to the state machine
5043 * \param Trans State machine transition function
5044 * \param StNr number of states
5045 * \param MsgNr number of messages
5046 * \param DefFunc default function, when there is invalid state/message combination
5047 * \param InitState initial state of the state machine
5048 * \param Base StateMachine base, internal use only
5049 * \pre p_sm should be a legal pointer
5052 IRQL = PASSIVE_LEVEL
5055 VOID
StateMachineInit(
5056 IN STATE_MACHINE
*S
,
5057 IN STATE_MACHINE_FUNC Trans
[],
5060 IN STATE_MACHINE_FUNC DefFunc
,
5066 // set number of states and messages
5071 S
->TransFunc
= Trans
;
5073 // init all state transition to default function
5074 for (i
= 0; i
< StNr
; i
++)
5076 for (j
= 0; j
< MsgNr
; j
++)
5078 S
->TransFunc
[i
* MsgNr
+ j
] = DefFunc
;
5082 // set the starting state
5083 S
->CurrState
= InitState
;
5086 /*! \brief This function fills in the function pointer into the cell in the state machine
5087 * \param *S pointer to the state machine
5089 * \param Msg incoming message
5090 * \param f the function to be executed when (state, message) combination occurs at the state machine
5091 * \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
5094 IRQL = PASSIVE_LEVEL
5097 VOID
StateMachineSetAction(
5098 IN STATE_MACHINE
*S
,
5101 IN STATE_MACHINE_FUNC Func
)
5105 MsgIdx
= Msg
- S
->Base
;
5107 if (St
< S
->NrState
&& MsgIdx
< S
->NrMsg
)
5109 // boundary checking before setting the action
5110 S
->TransFunc
[St
* S
->NrMsg
+ MsgIdx
] = Func
;
5114 /*! \brief This function does the state transition
5115 * \param *Adapter the NIC adapter pointer
5116 * \param *S the state machine
5117 * \param *Elem the message to be executed
5120 IRQL = DISPATCH_LEVEL
5123 VOID
StateMachinePerformAction(
5124 IN PRTMP_ADAPTER pAd
,
5125 IN STATE_MACHINE
*S
,
5126 IN MLME_QUEUE_ELEM
*Elem
)
5128 (*(S
->TransFunc
[S
->CurrState
* S
->NrMsg
+ Elem
->MsgType
- S
->Base
]))(pAd
, Elem
);
5132 ==========================================================================
5134 The drop function, when machine executes this, the message is simply
5135 ignored. This function does nothing, the message is freed in
5136 StateMachinePerformAction()
5137 ==========================================================================
5140 IN PRTMP_ADAPTER pAd
,
5141 IN MLME_QUEUE_ELEM
*Elem
)
5145 // ===========================================================================================
5147 // ===========================================================================================
5150 ==========================================================================
5153 IRQL = PASSIVE_LEVEL
5155 ==========================================================================
5158 IN PRTMP_ADAPTER pAd
,
5162 pAd
->Mlme
.ShiftReg
= 1;
5164 pAd
->Mlme
.ShiftReg
= Seed
;
5168 ==========================================================================
5170 ==========================================================================
5173 IN PRTMP_ADAPTER pAd
)
5180 if (pAd
->Mlme
.ShiftReg
== 0)
5181 NdisGetSystemUpTime((ULONG
*)&pAd
->Mlme
.ShiftReg
);
5183 for (i
= 0; i
< 8; i
++)
5185 if (pAd
->Mlme
.ShiftReg
& 0x00000001)
5187 pAd
->Mlme
.ShiftReg
= ((pAd
->Mlme
.ShiftReg
^ LFSR_MASK
) >> 1) | 0x80000000;
5192 pAd
->Mlme
.ShiftReg
= pAd
->Mlme
.ShiftReg
>> 1;
5195 R
= (R
<< 1) | Result
;
5201 VOID
AsicUpdateAutoFallBackTable(
5202 IN PRTMP_ADAPTER pAd
,
5203 IN PUCHAR pRateTable
)
5206 HT_FBK_CFG0_STRUC HtCfg0
;
5207 HT_FBK_CFG1_STRUC HtCfg1
;
5208 LG_FBK_CFG0_STRUC LgCfg0
;
5209 LG_FBK_CFG1_STRUC LgCfg1
;
5210 PRTMP_TX_RATE_SWITCH pCurrTxRate
, pNextTxRate
;
5212 // set to initial value
5213 HtCfg0
.word
= 0x65432100;
5214 HtCfg1
.word
= 0xedcba988;
5215 LgCfg0
.word
= 0xedcba988;
5216 LgCfg1
.word
= 0x00002100;
5218 pNextTxRate
= (PRTMP_TX_RATE_SWITCH
)pRateTable
+1;
5219 for (i
= 1; i
< *((PUCHAR
) pRateTable
); i
++)
5221 pCurrTxRate
= (PRTMP_TX_RATE_SWITCH
)pRateTable
+1+i
;
5222 switch (pCurrTxRate
->Mode
)
5228 switch(pCurrTxRate
->CurrMCS
)
5231 LgCfg0
.field
.OFDMMCS0FBK
= (pNextTxRate
->Mode
== MODE_OFDM
) ? (pNextTxRate
->CurrMCS
+8): pNextTxRate
->CurrMCS
;
5234 LgCfg0
.field
.OFDMMCS1FBK
= (pNextTxRate
->Mode
== MODE_OFDM
) ? (pNextTxRate
->CurrMCS
+8): pNextTxRate
->CurrMCS
;
5237 LgCfg0
.field
.OFDMMCS2FBK
= (pNextTxRate
->Mode
== MODE_OFDM
) ? (pNextTxRate
->CurrMCS
+8): pNextTxRate
->CurrMCS
;
5240 LgCfg0
.field
.OFDMMCS3FBK
= (pNextTxRate
->Mode
== MODE_OFDM
) ? (pNextTxRate
->CurrMCS
+8): pNextTxRate
->CurrMCS
;
5243 LgCfg0
.field
.OFDMMCS4FBK
= (pNextTxRate
->Mode
== MODE_OFDM
) ? (pNextTxRate
->CurrMCS
+8): pNextTxRate
->CurrMCS
;
5246 LgCfg0
.field
.OFDMMCS5FBK
= (pNextTxRate
->Mode
== MODE_OFDM
) ? (pNextTxRate
->CurrMCS
+8): pNextTxRate
->CurrMCS
;
5249 LgCfg0
.field
.OFDMMCS6FBK
= (pNextTxRate
->Mode
== MODE_OFDM
) ? (pNextTxRate
->CurrMCS
+8): pNextTxRate
->CurrMCS
;
5252 LgCfg0
.field
.OFDMMCS7FBK
= (pNextTxRate
->Mode
== MODE_OFDM
) ? (pNextTxRate
->CurrMCS
+8): pNextTxRate
->CurrMCS
;
5260 if ((pNextTxRate
->Mode
>= MODE_HTMIX
) && (pCurrTxRate
->CurrMCS
!= pNextTxRate
->CurrMCS
))
5262 switch(pCurrTxRate
->CurrMCS
)
5265 HtCfg0
.field
.HTMCS0FBK
= pNextTxRate
->CurrMCS
;
5268 HtCfg0
.field
.HTMCS1FBK
= pNextTxRate
->CurrMCS
;
5271 HtCfg0
.field
.HTMCS2FBK
= pNextTxRate
->CurrMCS
;
5274 HtCfg0
.field
.HTMCS3FBK
= pNextTxRate
->CurrMCS
;
5277 HtCfg0
.field
.HTMCS4FBK
= pNextTxRate
->CurrMCS
;
5280 HtCfg0
.field
.HTMCS5FBK
= pNextTxRate
->CurrMCS
;
5283 HtCfg0
.field
.HTMCS6FBK
= pNextTxRate
->CurrMCS
;
5286 HtCfg0
.field
.HTMCS7FBK
= pNextTxRate
->CurrMCS
;
5289 HtCfg1
.field
.HTMCS8FBK
= pNextTxRate
->CurrMCS
;
5292 HtCfg1
.field
.HTMCS9FBK
= pNextTxRate
->CurrMCS
;
5295 HtCfg1
.field
.HTMCS10FBK
= pNextTxRate
->CurrMCS
;
5298 HtCfg1
.field
.HTMCS11FBK
= pNextTxRate
->CurrMCS
;
5301 HtCfg1
.field
.HTMCS12FBK
= pNextTxRate
->CurrMCS
;
5304 HtCfg1
.field
.HTMCS13FBK
= pNextTxRate
->CurrMCS
;
5307 HtCfg1
.field
.HTMCS14FBK
= pNextTxRate
->CurrMCS
;
5310 HtCfg1
.field
.HTMCS15FBK
= pNextTxRate
->CurrMCS
;
5313 DBGPRINT(RT_DEBUG_ERROR
, ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n", pCurrTxRate
->CurrMCS
));
5320 pNextTxRate
= pCurrTxRate
;
5323 RTMP_IO_WRITE32(pAd
, HT_FBK_CFG0
, HtCfg0
.word
);
5324 RTMP_IO_WRITE32(pAd
, HT_FBK_CFG1
, HtCfg1
.word
);
5325 RTMP_IO_WRITE32(pAd
, LG_FBK_CFG0
, LgCfg0
.word
);
5326 RTMP_IO_WRITE32(pAd
, LG_FBK_CFG1
, LgCfg1
.word
);
5330 ========================================================================
5332 Routine Description:
5333 Set MAC register value according operation mode.
5334 OperationMode AND bNonGFExist are for MM and GF Proteciton.
5335 If MM or GF mask is not set, those passing argument doesn't not take effect.
5337 Operation mode meaning:
5338 = 0 : Pure HT, no preotection.
5339 = 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS.
5340 = 0x10: No Transmission in 40M is protected.
5341 = 0x11: Transmission in both 40M and 20M shall be protected
5343 we should choose not to use GF. But still set correct ASIC registers.
5344 ========================================================================
5346 VOID
AsicUpdateProtect(
5347 IN PRTMP_ADAPTER pAd
,
5348 IN USHORT OperationMode
,
5350 IN BOOLEAN bDisableBGProtect
,
5351 IN BOOLEAN bNonGFExist
)
5353 PROT_CFG_STRUC ProtCfg
, ProtCfg4
;
5359 if (!(pAd
->CommonCfg
.bHTProtect
) && (OperationMode
!= 8))
5364 if (pAd
->BATable
.numAsOriginator
)
5367 // enable the RTS/CTS to avoid channel collision
5369 SetMask
= ALLN_SETPROTECT
;
5373 // Config ASIC RTS threshold register
5374 RTMP_IO_READ32(pAd
, TX_RTS_CFG
, &MacReg
);
5375 MacReg
&= 0xFF0000FF;
5377 // If the user want disable RtsThreshold and enable Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096
5379 (pAd
->CommonCfg
.BACapability
.field
.AmsduEnable
) ||
5380 (pAd
->CommonCfg
.bAggregationCapable
== TRUE
))
5381 && pAd
->CommonCfg
.RtsThreshold
== MAX_RTS_THRESHOLD
)
5383 MacReg
|= (0x1000 << 8);
5387 MacReg
|= (pAd
->CommonCfg
.RtsThreshold
<< 8);
5390 RTMP_IO_WRITE32(pAd
, TX_RTS_CFG
, MacReg
);
5392 // Initial common protection settings
5393 RTMPZeroMemory(Protect
, sizeof(Protect
));
5396 ProtCfg
.field
.TxopAllowGF40
= 1;
5397 ProtCfg
.field
.TxopAllowGF20
= 1;
5398 ProtCfg
.field
.TxopAllowMM40
= 1;
5399 ProtCfg
.field
.TxopAllowMM20
= 1;
5400 ProtCfg
.field
.TxopAllowOfdm
= 1;
5401 ProtCfg
.field
.TxopAllowCck
= 1;
5402 ProtCfg
.field
.RTSThEn
= 1;
5403 ProtCfg
.field
.ProtectNav
= ASIC_SHORTNAV
;
5405 // update PHY mode and rate
5406 if (pAd
->CommonCfg
.Channel
> 14)
5407 ProtCfg
.field
.ProtectRate
= 0x4000;
5408 ProtCfg
.field
.ProtectRate
|= pAd
->CommonCfg
.RtsRate
;
5410 // Handle legacy(B/G) protection
5411 if (bDisableBGProtect
)
5413 //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
5414 ProtCfg
.field
.ProtectCtrl
= 0;
5415 Protect
[0] = ProtCfg
.word
;
5416 Protect
[1] = ProtCfg
.word
;
5420 //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
5421 ProtCfg
.field
.ProtectCtrl
= 0; // CCK do not need to be protected
5422 Protect
[0] = ProtCfg
.word
;
5423 ProtCfg
.field
.ProtectCtrl
= ASIC_CTS
; // OFDM needs using CCK to protect
5424 Protect
[1] = ProtCfg
.word
;
5427 // Decide HT frame protection.
5428 if ((SetMask
& ALLN_SETPROTECT
) != 0)
5430 switch(OperationMode
)
5434 // 1.All STAs in the BSS are 20/40 MHz HT
5435 // 2. in ai 20/40MHz BSS
5436 // 3. all STAs are 20MHz in a 20MHz BSS
5437 // Pure HT. no protection.
5441 // PROT_TXOP(25:20) -- 010111
5442 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5443 // PROT_CTRL(17:16) -- 00 (None)
5444 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
5445 Protect
[2] = 0x01744004;
5449 // PROT_TXOP(25:20) -- 111111
5450 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5451 // PROT_CTRL(17:16) -- 00 (None)
5452 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
5453 Protect
[3] = 0x03f44084;
5457 // PROT_TXOP(25:20) -- 010111
5458 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5459 // PROT_CTRL(17:16) -- 00 (None)
5460 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
5461 Protect
[4] = 0x01744004;
5465 // PROT_TXOP(25:20) -- 111111
5466 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5467 // PROT_CTRL(17:16) -- 00 (None)
5468 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
5469 Protect
[5] = 0x03f44084;
5473 // PROT_NAV(19:18) -- 01 (Short NAV protectiion)
5474 // PROT_CTRL(17:16) -- 01 (RTS/CTS)
5475 Protect
[4] = 0x01754004;
5476 Protect
[5] = 0x03f54084;
5478 pAd
->CommonCfg
.IOTestParm
.bRTSLongProtOn
= FALSE
;
5482 // This is "HT non-member protection mode."
5483 // If there may be non-HT STAs my BSS
5484 ProtCfg
.word
= 0x01744004; // PROT_CTRL(17:16) : 0 (None)
5485 ProtCfg4
.word
= 0x03f44084; // duplicaet legacy 24M. BW set 1.
5486 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_BG_PROTECTION_INUSED
))
5488 ProtCfg
.word
= 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
5489 ProtCfg4
.word
= 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083;
5491 //Assign Protection method for 20&40 MHz packets
5492 ProtCfg
.field
.ProtectCtrl
= ASIC_RTS
;
5493 ProtCfg
.field
.ProtectNav
= ASIC_SHORTNAV
;
5494 ProtCfg4
.field
.ProtectCtrl
= ASIC_RTS
;
5495 ProtCfg4
.field
.ProtectNav
= ASIC_SHORTNAV
;
5496 Protect
[2] = ProtCfg
.word
;
5497 Protect
[3] = ProtCfg4
.word
;
5498 Protect
[4] = ProtCfg
.word
;
5499 Protect
[5] = ProtCfg4
.word
;
5500 pAd
->CommonCfg
.IOTestParm
.bRTSLongProtOn
= TRUE
;
5504 // If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets
5505 ProtCfg
.word
= 0x01744004; // PROT_CTRL(17:16) : 0 (None)
5506 ProtCfg4
.word
= 0x03f44084; // duplicaet legacy 24M. BW set 1.
5508 //Assign Protection method for 40MHz packets
5509 ProtCfg4
.field
.ProtectCtrl
= ASIC_RTS
;
5510 ProtCfg4
.field
.ProtectNav
= ASIC_SHORTNAV
;
5511 Protect
[2] = ProtCfg
.word
;
5512 Protect
[3] = ProtCfg4
.word
;
5515 ProtCfg
.field
.ProtectCtrl
= ASIC_RTS
;
5516 ProtCfg
.field
.ProtectNav
= ASIC_SHORTNAV
;
5518 Protect
[4] = ProtCfg
.word
;
5519 Protect
[5] = ProtCfg4
.word
;
5521 pAd
->CommonCfg
.IOTestParm
.bRTSLongProtOn
= FALSE
;
5525 // HT mixed mode. PROTECT ALL!
5527 ProtCfg
.word
= 0x01744004; //duplicaet legacy 24M. BW set 1.
5528 ProtCfg4
.word
= 0x03f44084;
5529 // both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the
5530 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_BG_PROTECTION_INUSED
))
5532 ProtCfg
.word
= 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
5533 ProtCfg4
.word
= 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083
5535 //Assign Protection method for 20&40 MHz packets
5536 ProtCfg
.field
.ProtectCtrl
= ASIC_RTS
;
5537 ProtCfg
.field
.ProtectNav
= ASIC_SHORTNAV
;
5538 ProtCfg4
.field
.ProtectCtrl
= ASIC_RTS
;
5539 ProtCfg4
.field
.ProtectNav
= ASIC_SHORTNAV
;
5540 Protect
[2] = ProtCfg
.word
;
5541 Protect
[3] = ProtCfg4
.word
;
5542 Protect
[4] = ProtCfg
.word
;
5543 Protect
[5] = ProtCfg4
.word
;
5544 pAd
->CommonCfg
.IOTestParm
.bRTSLongProtOn
= TRUE
;
5548 // Special on for Atheros problem n chip.
5549 Protect
[2] = 0x01754004;
5550 Protect
[3] = 0x03f54084;
5551 Protect
[4] = 0x01754004;
5552 Protect
[5] = 0x03f54084;
5553 pAd
->CommonCfg
.IOTestParm
.bRTSLongProtOn
= TRUE
;
5558 offset
= CCK_PROT_CFG
;
5559 for (i
= 0;i
< 6;i
++)
5561 if ((SetMask
& (1<< i
)))
5563 RTMP_IO_WRITE32(pAd
, offset
+ i
*4, Protect
[i
]);
5570 ==========================================================================
5573 Load RF normal operation-mode setup
5575 ==========================================================================
5577 VOID
RT30xxLoadRFNormalModeSetup(
5578 IN PRTMP_ADAPTER pAd
)
5582 // RX0_PD & TX0_PD, RF R1 register Bit 2 & Bit 3 to 0 and RF_BLOCK_en,RX1_PD & TX1_PD, Bit0, Bit 4 & Bit5 to 1
5583 RT30xxReadRFRegister(pAd
, RF_R01
, &RFValue
);
5584 RFValue
= (RFValue
& (~0x0C)) | 0x31;
5585 RT30xxWriteRFRegister(pAd
, RF_R01
, RFValue
);
5587 // TX_LO2_en, RF R15 register Bit 3 to 0
5588 RT30xxReadRFRegister(pAd
, RF_R15
, &RFValue
);
5590 RT30xxWriteRFRegister(pAd
, RF_R15
, RFValue
);
5592 // TX_LO1_en, RF R17 register Bit 3 to 0
5593 RT30xxReadRFRegister(pAd
, RF_R17
, &RFValue
);
5595 // to fix rx long range issue
5596 if (((pAd
->MACVersion
& 0xffff) >= 0x0211) && (pAd
->NicConfig2
.field
.ExternalLNAForG
== 0))
5600 RT30xxWriteRFRegister(pAd
, RF_R17
, RFValue
);
5602 // RX_LO1_en, RF R20 register Bit 3 to 0
5603 RT30xxReadRFRegister(pAd
, RF_R20
, &RFValue
);
5605 RT30xxWriteRFRegister(pAd
, RF_R20
, RFValue
);
5607 // RX_LO2_en, RF R21 register Bit 3 to 0
5608 RT30xxReadRFRegister(pAd
, RF_R21
, &RFValue
);
5610 RT30xxWriteRFRegister(pAd
, RF_R21
, RFValue
);
5612 // LDORF_VC, RF R27 register Bit 2 to 0
5613 RT30xxReadRFRegister(pAd
, RF_R27
, &RFValue
);
5614 if ((pAd
->MACVersion
& 0xffff) < 0x0211)
5615 RFValue
= (RFValue
& (~0x77)) | 0x3;
5617 RFValue
= (RFValue
& (~0x77));
5618 RT30xxWriteRFRegister(pAd
, RF_R27
, RFValue
);
5623 ==========================================================================
5626 Load RF sleep-mode setup
5628 ==========================================================================
5630 VOID
RT30xxLoadRFSleepModeSetup(
5631 IN PRTMP_ADAPTER pAd
)
5636 // RF_BLOCK_en. RF R1 register Bit 0 to 0
5637 RT30xxReadRFRegister(pAd
, RF_R01
, &RFValue
);
5639 RT30xxWriteRFRegister(pAd
, RF_R01
, RFValue
);
5641 // VCO_IC, RF R7 register Bit 4 & Bit 5 to 0
5642 RT30xxReadRFRegister(pAd
, RF_R07
, &RFValue
);
5644 RT30xxWriteRFRegister(pAd
, RF_R07
, RFValue
);
5646 // Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 0
5647 RT30xxReadRFRegister(pAd
, RF_R09
, &RFValue
);
5649 RT30xxWriteRFRegister(pAd
, RF_R09
, RFValue
);
5651 // RX_CTB_en, RF R21 register Bit 7 to 0
5652 RT30xxReadRFRegister(pAd
, RF_R21
, &RFValue
);
5654 RT30xxWriteRFRegister(pAd
, RF_R21
, RFValue
);
5656 // LDORF_VC, RF R27 register Bit 0, Bit 1 & Bit 2 to 1
5657 RT30xxReadRFRegister(pAd
, RF_R27
, &RFValue
);
5659 RT30xxWriteRFRegister(pAd
, RF_R27
, RFValue
);
5661 RTMP_IO_READ32(pAd
, LDO_CFG0
, &MACValue
);
5662 MACValue
|= 0x1D000000;
5663 RTMP_IO_WRITE32(pAd
, LDO_CFG0
, MACValue
);
5667 ==========================================================================
5670 Reverse RF sleep-mode setup
5672 ==========================================================================
5674 VOID
RT30xxReverseRFSleepModeSetup(
5675 IN PRTMP_ADAPTER pAd
)
5680 // RF_BLOCK_en, RF R1 register Bit 0 to 1
5681 RT30xxReadRFRegister(pAd
, RF_R01
, &RFValue
);
5683 RT30xxWriteRFRegister(pAd
, RF_R01
, RFValue
);
5685 // VCO_IC, RF R7 register Bit 4 & Bit 5 to 1
5686 RT30xxReadRFRegister(pAd
, RF_R07
, &RFValue
);
5688 RT30xxWriteRFRegister(pAd
, RF_R07
, RFValue
);
5690 // Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 1
5691 RT30xxReadRFRegister(pAd
, RF_R09
, &RFValue
);
5693 RT30xxWriteRFRegister(pAd
, RF_R09
, RFValue
);
5695 // RX_CTB_en, RF R21 register Bit 7 to 1
5696 RT30xxReadRFRegister(pAd
, RF_R21
, &RFValue
);
5698 RT30xxWriteRFRegister(pAd
, RF_R21
, RFValue
);
5700 // LDORF_VC, RF R27 register Bit 2 to 0
5701 RT30xxReadRFRegister(pAd
, RF_R27
, &RFValue
);
5702 if ((pAd
->MACVersion
& 0xffff) < 0x0211)
5703 RFValue
= (RFValue
& (~0x77)) | 0x3;
5705 RFValue
= (RFValue
& (~0x77));
5706 RT30xxWriteRFRegister(pAd
, RF_R27
, RFValue
);
5708 // RT3071 version E has fixed this issue
5709 if ((pAd
->NicConfig2
.field
.DACTestBit
== 1) && ((pAd
->MACVersion
& 0xffff) < 0x0211))
5711 // patch tx EVM issue temporarily
5712 RTMP_IO_READ32(pAd
, LDO_CFG0
, &MACValue
);
5713 MACValue
= ((MACValue
& 0xE0FFFFFF) | 0x0D000000);
5714 RTMP_IO_WRITE32(pAd
, LDO_CFG0
, MACValue
);
5718 RTMP_IO_READ32(pAd
, LDO_CFG0
, &MACValue
);
5719 MACValue
= ((MACValue
& 0xE0FFFFFF) | 0x01000000);
5720 RTMP_IO_WRITE32(pAd
, LDO_CFG0
, MACValue
);
5726 ==========================================================================
5729 IRQL = PASSIVE_LEVEL
5730 IRQL = DISPATCH_LEVEL
5732 ==========================================================================
5734 VOID
AsicSwitchChannel(
5735 IN PRTMP_ADAPTER pAd
,
5739 ULONG R2
= 0, R3
= DEFAULT_RF_TX_POWER
, R4
= 0;
5740 CHAR TxPwer
= 0, TxPwer2
= DEFAULT_RF_TX_POWER
; //Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER;
5742 UINT32 Value
= 0; //BbpReg, Value;
5743 RTMP_RF_REGS
*RFRegTable
;
5745 // Search Tx power value
5746 // We can't use ChannelList to search channel, since some central channl's txpowr doesn't list
5747 // in ChannelList, so use TxPower array instead.
5749 for (index
= 0; index
< MAX_NUM_OF_CHANNELS
; index
++)
5751 if (Channel
== pAd
->TxPower
[index
].Channel
)
5753 TxPwer
= pAd
->TxPower
[index
].Power
;
5754 TxPwer2
= pAd
->TxPower
[index
].Power2
;
5759 if (index
== MAX_NUM_OF_CHANNELS
)
5760 DBGPRINT(RT_DEBUG_ERROR
, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel
));
5763 // The RF programming sequence is difference between 3xxx and 2xxx
5764 if ((IS_RT3070(pAd
) || IS_RT3090(pAd
)) && (
5765 (pAd
->RfIcType
== RFIC_3022
) || (pAd
->RfIcType
== RFIC_3021
) ||
5766 (pAd
->RfIcType
== RFIC_3020
) || (pAd
->RfIcType
== RFIC_2020
)))
5768 /* modify by WY for Read RF Reg. error */
5771 for (index
= 0; index
< NUM_OF_3020_CHNL
; index
++)
5773 if (Channel
== FreqItems3020
[index
].Channel
)
5775 // Programming channel parameters
5776 RT30xxWriteRFRegister(pAd
, RF_R02
, FreqItems3020
[index
].N
);
5777 RT30xxWriteRFRegister(pAd
, RF_R03
, FreqItems3020
[index
].K
);
5779 RT30xxReadRFRegister(pAd
, RF_R06
, &RFValue
);
5780 RFValue
= (RFValue
& 0xFC) | FreqItems3020
[index
].R
;
5781 RT30xxWriteRFRegister(pAd
, RF_R06
, RFValue
);
5784 RT30xxReadRFRegister(pAd
, RF_R12
, &RFValue
);
5785 RFValue
= (RFValue
& 0xE0) | TxPwer
;
5786 RT30xxWriteRFRegister(pAd
, RF_R12
, RFValue
);
5789 RT30xxReadRFRegister(pAd
, RF_R13
, &RFValue
);
5790 RFValue
= (RFValue
& 0xE0) | TxPwer2
;
5791 RT30xxWriteRFRegister(pAd
, RF_R13
, RFValue
);
5793 // Tx/Rx Stream setting
5794 RT30xxReadRFRegister(pAd
, RF_R01
, &RFValue
);
5795 //if (IS_RT3090(pAd))
5796 // RFValue |= 0x01; // Enable RF block.
5797 RFValue
&= 0x03; //clear bit[7~2]
5798 if (pAd
->Antenna
.field
.TxPath
== 1)
5800 else if (pAd
->Antenna
.field
.TxPath
== 2)
5802 if (pAd
->Antenna
.field
.RxPath
== 1)
5804 else if (pAd
->Antenna
.field
.RxPath
== 2)
5806 RT30xxWriteRFRegister(pAd
, RF_R01
, RFValue
);
5809 RT30xxReadRFRegister(pAd
, RF_R23
, &RFValue
);
5810 RFValue
= (RFValue
& 0x80) | pAd
->RfFreqOffset
;
5811 RT30xxWriteRFRegister(pAd
, RF_R23
, RFValue
);
5814 if (!bScan
&& (pAd
->CommonCfg
.BBPCurrentBW
== BW_40
))
5816 RFValue
= pAd
->Mlme
.CaliBW40RfR24
;
5817 //DISABLE_11N_CHECK(pAd);
5821 RFValue
= pAd
->Mlme
.CaliBW20RfR24
;
5823 RT30xxWriteRFRegister(pAd
, RF_R24
, RFValue
);
5824 RT30xxWriteRFRegister(pAd
, RF_R31
, RFValue
);
5827 RT30xxReadRFRegister(pAd
, RF_R07
, &RFValue
);
5828 RFValue
= RFValue
| 0x1;
5829 RT30xxWriteRFRegister(pAd
, RF_R07
, RFValue
);
5831 // latch channel for future usage.
5832 pAd
->LatchRfRegs
.Channel
= Channel
;
5834 DBGPRINT(RT_DEBUG_TRACE
, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
5839 pAd
->Antenna
.field
.TxPath
,
5840 FreqItems3020
[index
].N
,
5841 FreqItems3020
[index
].K
,
5842 FreqItems3020
[index
].R
));
5847 DBGPRINT(RT_DEBUG_TRACE
, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
5852 pAd
->Antenna
.field
.TxPath
,
5853 FreqItems3020
[index
].N
,
5854 FreqItems3020
[index
].K
,
5855 FreqItems3020
[index
].R
));
5860 RFRegTable
= RF2850RegTable
;
5862 switch (pAd
->RfIcType
)
5869 for (index
= 0; index
< NUM_OF_2850_CHNL
; index
++)
5871 if (Channel
== RFRegTable
[index
].Channel
)
5873 R2
= RFRegTable
[index
].R2
;
5874 if (pAd
->Antenna
.field
.TxPath
== 1)
5876 R2
|= 0x4000; // If TXpath is 1, bit 14 = 1;
5879 if (pAd
->Antenna
.field
.RxPath
== 2)
5881 R2
|= 0x40; // write 1 to off Rxpath.
5883 else if (pAd
->Antenna
.field
.RxPath
== 1)
5885 R2
|= 0x20040; // write 1 to off RxPath
5890 // initialize R3, R4
5891 R3
= (RFRegTable
[index
].R3
& 0xffffc1ff);
5892 R4
= (RFRegTable
[index
].R4
& (~0x001f87c0)) | (pAd
->RfFreqOffset
<< 15);
5894 // 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB
5896 if ((TxPwer
>= -7) && (TxPwer
< 0))
5898 TxPwer
= (7+TxPwer
);
5899 TxPwer
= (TxPwer
> 0xF) ? (0xF) : (TxPwer
);
5900 R3
|= (TxPwer
<< 10);
5901 DBGPRINT(RT_DEBUG_ERROR
, ("AsicSwitchChannel: TxPwer=%d \n", TxPwer
));
5905 TxPwer
= (TxPwer
> 0xF) ? (0xF) : (TxPwer
);
5906 R3
|= (TxPwer
<< 10) | (1 << 9);
5910 if ((TxPwer2
>= -7) && (TxPwer2
< 0))
5912 TxPwer2
= (7+TxPwer2
);
5913 TxPwer2
= (TxPwer2
> 0xF) ? (0xF) : (TxPwer2
);
5914 R4
|= (TxPwer2
<< 7);
5915 DBGPRINT(RT_DEBUG_ERROR
, ("AsicSwitchChannel: TxPwer2=%d \n", TxPwer2
));
5919 TxPwer2
= (TxPwer2
> 0xF) ? (0xF) : (TxPwer2
);
5920 R4
|= (TxPwer2
<< 7) | (1 << 6);
5925 R3
= (RFRegTable
[index
].R3
& 0xffffc1ff) | (TxPwer
<< 9); // set TX power0
5926 R4
= (RFRegTable
[index
].R4
& (~0x001f87c0)) | (pAd
->RfFreqOffset
<< 15) | (TxPwer2
<<6);// Set freq Offset & TxPwr1
5929 // Based on BBP current mode before changing RF channel.
5930 if (!bScan
&& (pAd
->CommonCfg
.BBPCurrentBW
== BW_40
))
5936 pAd
->LatchRfRegs
.Channel
= Channel
;
5937 pAd
->LatchRfRegs
.R1
= RFRegTable
[index
].R1
;
5938 pAd
->LatchRfRegs
.R2
= R2
;
5939 pAd
->LatchRfRegs
.R3
= R3
;
5940 pAd
->LatchRfRegs
.R4
= R4
;
5942 // Set RF value 1's set R3[bit2] = [0]
5943 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R1
);
5944 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R2
);
5945 RTMP_RF_IO_WRITE32(pAd
, (pAd
->LatchRfRegs
.R3
& (~0x04)));
5946 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R4
);
5950 // Set RF value 2's set R3[bit2] = [1]
5951 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R1
);
5952 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R2
);
5953 RTMP_RF_IO_WRITE32(pAd
, (pAd
->LatchRfRegs
.R3
| 0x04));
5954 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R4
);
5958 // Set RF value 3's set R3[bit2] = [0]
5959 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R1
);
5960 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R2
);
5961 RTMP_RF_IO_WRITE32(pAd
, (pAd
->LatchRfRegs
.R3
& (~0x04)));
5962 RTMP_RF_IO_WRITE32(pAd
, pAd
->LatchRfRegs
.R4
);
5974 // Change BBP setting during siwtch from a->g, g->a
5977 ULONG TxPinCfg
= 0x00050F0A;//Gary 2007/08/09 0x050A0A
5979 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R62
, (0x37 - GET_LNA_GAIN(pAd
)));
5980 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R63
, (0x37 - GET_LNA_GAIN(pAd
)));
5981 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R64
, (0x37 - GET_LNA_GAIN(pAd
)));
5982 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.
5983 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
5985 // Rx High power VGA offset for LNA select
5986 if (pAd
->NicConfig2
.field
.ExternalLNAForG
)
5988 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R82
, 0x62);
5989 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R75
, 0x46);
5993 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R82
, 0x84);
5994 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R75
, 0x50);
5997 // 5G band selection PIN, bit1 and bit2 are complement
5998 RTMP_IO_READ32(pAd
, TX_BAND_CFG
, &Value
);
6001 RTMP_IO_WRITE32(pAd
, TX_BAND_CFG
, Value
);
6003 // Turn off unused PA or LNA when only 1T or 1R
6004 if (pAd
->Antenna
.field
.TxPath
== 1)
6006 TxPinCfg
&= 0xFFFFFFF3;
6008 if (pAd
->Antenna
.field
.RxPath
== 1)
6010 TxPinCfg
&= 0xFFFFF3FF;
6013 RTMP_IO_WRITE32(pAd
, TX_PIN_CFG
, TxPinCfg
);
6017 ULONG TxPinCfg
= 0x00050F05;//Gary 2007/8/9 0x050505
6019 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R62
, (0x37 - GET_LNA_GAIN(pAd
)));
6020 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R63
, (0x37 - GET_LNA_GAIN(pAd
)));
6021 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R64
, (0x37 - GET_LNA_GAIN(pAd
)));
6022 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R86
, 0);//(0x44 - GET_LNA_GAIN(pAd))); // According the Rory's suggestion to solve the middle range issue.
6023 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R82
, 0xF2);
6025 // Rx High power VGA offset for LNA select
6026 if (pAd
->NicConfig2
.field
.ExternalLNAForA
)
6028 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R75
, 0x46);
6032 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R75
, 0x50);
6035 // 5G band selection PIN, bit1 and bit2 are complement
6036 RTMP_IO_READ32(pAd
, TX_BAND_CFG
, &Value
);
6039 RTMP_IO_WRITE32(pAd
, TX_BAND_CFG
, Value
);
6041 // Turn off unused PA or LNA when only 1T or 1R
6042 if (pAd
->Antenna
.field
.TxPath
== 1)
6044 TxPinCfg
&= 0xFFFFFFF3;
6046 if (pAd
->Antenna
.field
.RxPath
== 1)
6048 TxPinCfg
&= 0xFFFFF3FF;
6051 RTMP_IO_WRITE32(pAd
, TX_PIN_CFG
, TxPinCfg
);
6054 // R66 should be set according to Channel and use 20MHz when scanning
6055 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd)));
6057 RTMPSetAGCInitValue(pAd
, BW_20
);
6059 RTMPSetAGCInitValue(pAd
, pAd
->CommonCfg
.BBPCurrentBW
);
6062 // On 11A, We should delay and wait RF/BBP to be stable
6063 // and the appropriate time should be 1000 micro seconds
6064 // 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
6066 RTMPusecDelay(1000);
6068 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",
6071 (R3
& 0x00003e00) >> 9,
6072 (R4
& 0x000007c0) >> 6,
6073 pAd
->Antenna
.field
.TxPath
,
6074 pAd
->LatchRfRegs
.R1
,
6075 pAd
->LatchRfRegs
.R2
,
6076 pAd
->LatchRfRegs
.R3
,
6077 pAd
->LatchRfRegs
.R4
));
6081 ==========================================================================
6083 This function is required for 2421 only, and should not be used during
6084 site survey. It's only required after NIC decided to stay at a channel
6085 for a longer period.
6086 When this function is called, it's always after AsicSwitchChannel().
6088 IRQL = PASSIVE_LEVEL
6089 IRQL = DISPATCH_LEVEL
6091 ==========================================================================
6093 VOID
AsicLockChannel(
6094 IN PRTMP_ADAPTER pAd
,
6099 VOID
AsicRfTuningExec(
6100 IN PVOID SystemSpecific1
,
6101 IN PVOID FunctionContext
,
6102 IN PVOID SystemSpecific2
,
6103 IN PVOID SystemSpecific3
)
6108 ==========================================================================
6110 Gives CCK TX rate 2 more dB TX power.
6111 This routine works only in LINK UP in INFRASTRUCTURE mode.
6113 calculate desired Tx power in RF R3.Tx0~5, should consider -
6114 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
6115 1. TxPowerPercentage
6116 2. auto calibration based on TSSI feedback
6117 3. extra 2 db for CCK
6118 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
6120 NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
6121 it should be called AFTER MlmeDynamicTxRatSwitching()
6122 ==========================================================================
6124 VOID
AsicAdjustTxPower(
6125 IN PRTMP_ADAPTER pAd
)
6129 BOOLEAN bAutoTxAgc
= FALSE
;
6130 UCHAR TssiRef
, *pTssiMinusBoundary
, *pTssiPlusBoundary
, TxAgcStep
;
6131 UCHAR BbpR1
= 0, BbpR49
= 0, idx
;
6132 PCHAR pTxAgcCompensate
;
6137 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_DOZE
)
6138 || (pAd
->bPCIclkOff
== TRUE
)
6139 || RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_IDLE_RADIO_OFF
)
6140 || RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS
))
6144 if (pAd
->CommonCfg
.BBPCurrentBW
== BW_40
)
6146 if (pAd
->CommonCfg
.CentralChannel
> 14)
6148 TxPwr
[0] = pAd
->Tx40MPwrCfgABand
[0];
6149 TxPwr
[1] = pAd
->Tx40MPwrCfgABand
[1];
6150 TxPwr
[2] = pAd
->Tx40MPwrCfgABand
[2];
6151 TxPwr
[3] = pAd
->Tx40MPwrCfgABand
[3];
6152 TxPwr
[4] = pAd
->Tx40MPwrCfgABand
[4];
6156 TxPwr
[0] = pAd
->Tx40MPwrCfgGBand
[0];
6157 TxPwr
[1] = pAd
->Tx40MPwrCfgGBand
[1];
6158 TxPwr
[2] = pAd
->Tx40MPwrCfgGBand
[2];
6159 TxPwr
[3] = pAd
->Tx40MPwrCfgGBand
[3];
6160 TxPwr
[4] = pAd
->Tx40MPwrCfgGBand
[4];
6165 if (pAd
->CommonCfg
.Channel
> 14)
6167 TxPwr
[0] = pAd
->Tx20MPwrCfgABand
[0];
6168 TxPwr
[1] = pAd
->Tx20MPwrCfgABand
[1];
6169 TxPwr
[2] = pAd
->Tx20MPwrCfgABand
[2];
6170 TxPwr
[3] = pAd
->Tx20MPwrCfgABand
[3];
6171 TxPwr
[4] = pAd
->Tx20MPwrCfgABand
[4];
6175 TxPwr
[0] = pAd
->Tx20MPwrCfgGBand
[0];
6176 TxPwr
[1] = pAd
->Tx20MPwrCfgGBand
[1];
6177 TxPwr
[2] = pAd
->Tx20MPwrCfgGBand
[2];
6178 TxPwr
[3] = pAd
->Tx20MPwrCfgGBand
[3];
6179 TxPwr
[4] = pAd
->Tx20MPwrCfgGBand
[4];
6183 // TX power compensation for temperature variation based on TSSI. try every 4 second
6184 if (pAd
->Mlme
.OneSecPeriodicRound
% 4 == 0)
6186 if (pAd
->CommonCfg
.Channel
<= 14)
6189 bAutoTxAgc
= pAd
->bAutoTxAgcG
;
6190 TssiRef
= pAd
->TssiRefG
;
6191 pTssiMinusBoundary
= &pAd
->TssiMinusBoundaryG
[0];
6192 pTssiPlusBoundary
= &pAd
->TssiPlusBoundaryG
[0];
6193 TxAgcStep
= pAd
->TxAgcStepG
;
6194 pTxAgcCompensate
= &pAd
->TxAgcCompensateG
;
6199 bAutoTxAgc
= pAd
->bAutoTxAgcA
;
6200 TssiRef
= pAd
->TssiRefA
;
6201 pTssiMinusBoundary
= &pAd
->TssiMinusBoundaryA
[0];
6202 pTssiPlusBoundary
= &pAd
->TssiPlusBoundaryA
[0];
6203 TxAgcStep
= pAd
->TxAgcStepA
;
6204 pTxAgcCompensate
= &pAd
->TxAgcCompensateA
;
6209 /* BbpR1 is unsigned char */
6210 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R49
, &BbpR49
);
6212 /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
6213 /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */
6214 /* step value is defined in pAd->TxAgcStepG for tx power value */
6216 /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */
6217 /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
6218 above value are examined in mass factory production */
6219 /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */
6221 /* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */
6222 /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
6223 /* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */
6225 if (BbpR49
> pTssiMinusBoundary
[1])
6227 // Reading is larger than the reference value
6228 // check for how large we need to decrease the Tx power
6229 for (idx
= 1; idx
< 5; idx
++)
6231 if (BbpR49
<= pTssiMinusBoundary
[idx
]) // Found the range
6234 // The index is the step we should decrease, idx = 0 means there is nothing to compensate
6235 *pTxAgcCompensate
= -(TxAgcStep
* (idx
-1));
6237 DeltaPwr
+= (*pTxAgcCompensate
);
6238 DBGPRINT(RT_DEBUG_TRACE
, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
6239 BbpR49
, TssiRef
, TxAgcStep
, idx
-1));
6241 else if (BbpR49
< pTssiPlusBoundary
[1])
6243 // Reading is smaller than the reference value
6244 // check for how large we need to increase the Tx power
6245 for (idx
= 1; idx
< 5; idx
++)
6247 if (BbpR49
>= pTssiPlusBoundary
[idx
]) // Found the range
6250 // The index is the step we should increase, idx = 0 means there is nothing to compensate
6251 *pTxAgcCompensate
= TxAgcStep
* (idx
-1);
6252 DeltaPwr
+= (*pTxAgcCompensate
);
6253 DBGPRINT(RT_DEBUG_TRACE
, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
6254 BbpR49
, TssiRef
, TxAgcStep
, idx
-1));
6258 *pTxAgcCompensate
= 0;
6259 DBGPRINT(RT_DEBUG_TRACE
, (" Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
6260 BbpR49
, TssiRef
, TxAgcStep
, 0));
6266 if (pAd
->CommonCfg
.Channel
<= 14)
6268 bAutoTxAgc
= pAd
->bAutoTxAgcG
;
6269 pTxAgcCompensate
= &pAd
->TxAgcCompensateG
;
6273 bAutoTxAgc
= pAd
->bAutoTxAgcA
;
6274 pTxAgcCompensate
= &pAd
->TxAgcCompensateA
;
6278 DeltaPwr
+= (*pTxAgcCompensate
);
6281 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R1
, &BbpR1
);
6284 /* calculate delta power based on the percentage specified from UI */
6285 // E2PROM setting is calibrated for maximum TX power (i.e. 100%)
6286 // We lower TX power here according to the percentage specified from UI
6287 if (pAd
->CommonCfg
.TxPowerPercentage
== 0xffffffff) // AUTO TX POWER control
6289 else if (pAd
->CommonCfg
.TxPowerPercentage
> 90) // 91 ~ 100% & AUTO, treat as 100% in terms of mW
6291 else if (pAd
->CommonCfg
.TxPowerPercentage
> 60) // 61 ~ 90%, treat as 75% in terms of mW // DeltaPwr -= 1;
6295 else if (pAd
->CommonCfg
.TxPowerPercentage
> 30) // 31 ~ 60%, treat as 50% in terms of mW // DeltaPwr -= 3;
6299 else if (pAd
->CommonCfg
.TxPowerPercentage
> 15) // 16 ~ 30%, treat as 25% in terms of mW // DeltaPwr -= 6;
6303 else if (pAd
->CommonCfg
.TxPowerPercentage
> 9) // 10 ~ 15%, treat as 12.5% in terms of mW // DeltaPwr -= 9;
6308 else // 0 ~ 9 %, treat as MIN(~3%) in terms of mW // DeltaPwr -= 12;
6313 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R1
, BbpR1
);
6315 /* reset different new tx power for different TX rate */
6318 if (TxPwr
[i
] != 0xffffffff)
6322 Value
= (CHAR
)((TxPwr
[i
] >> j
*4) & 0x0F); /* 0 ~ 15 */
6324 if ((Value
+ DeltaPwr
) < 0)
6326 Value
= 0; /* min */
6328 else if ((Value
+ DeltaPwr
) > 0xF)
6330 Value
= 0xF; /* max */
6334 Value
+= DeltaPwr
; /* temperature compensation */
6337 /* fill new value to CSR offset */
6338 TxPwr
[i
] = (TxPwr
[i
] & ~(0x0000000F << j
*4)) | (Value
<< j
*4);
6341 /* write tx power value to CSR */
6342 /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M
6343 TX power for OFDM 6M/9M
6344 TX power for CCK5.5M/11M
6345 TX power for CCK1M/2M */
6346 /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
6347 RTMP_IO_WRITE32(pAd
, TX_PWR_CFG_0
+ i
*4, TxPwr
[i
]);
6354 ==========================================================================
6356 put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup
6357 automatically. Instead, MCU will issue a TwakeUpInterrupt to host after
6358 the wakeup timer timeout. Driver has to issue a separate command to wake
6361 IRQL = DISPATCH_LEVEL
6363 ==========================================================================
6365 VOID
AsicSleepThenAutoWakeup(
6366 IN PRTMP_ADAPTER pAd
,
6367 IN USHORT TbttNumToNextWakeUp
)
6369 RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd
, TbttNumToNextWakeUp
);
6373 ==========================================================================
6375 AsicForceWakeup() is used whenever manual wakeup is required
6376 AsicForceSleep() should only be used when not in INFRA BSS. When
6377 in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead.
6378 ==========================================================================
6380 VOID
AsicForceSleep(
6381 IN PRTMP_ADAPTER pAd
)
6387 ==========================================================================
6389 AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup)
6392 IRQL = PASSIVE_LEVEL
6393 IRQL = DISPATCH_LEVEL
6394 ==========================================================================
6396 VOID
AsicForceWakeup(
6397 IN PRTMP_ADAPTER pAd
,
6405 DBGPRINT(RT_DEBUG_TRACE
, ("--> AsicForceWakeup \n"));
6407 RT28XX_STA_FORCE_WAKEUP(pAd
, Level
);
6410 RT28XX_STA_FORCE_WAKEUP(pAd
, bFromTx
);
6415 ==========================================================================
6419 IRQL = DISPATCH_LEVEL
6421 ==========================================================================
6424 IN PRTMP_ADAPTER pAd
,
6428 DBGPRINT(RT_DEBUG_TRACE
, ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n",
6429 pBssid
[0],pBssid
[1],pBssid
[2],pBssid
[3], pBssid
[4],pBssid
[5]));
6431 Addr4
= (ULONG
)(pBssid
[0]) |
6432 (ULONG
)(pBssid
[1] << 8) |
6433 (ULONG
)(pBssid
[2] << 16) |
6434 (ULONG
)(pBssid
[3] << 24);
6435 RTMP_IO_WRITE32(pAd
, MAC_BSSID_DW0
, Addr4
);
6438 // always one BSSID in STA mode
6439 Addr4
= (ULONG
)(pBssid
[4]) | (ULONG
)(pBssid
[5] << 8);
6441 RTMP_IO_WRITE32(pAd
, MAC_BSSID_DW1
, Addr4
);
6444 VOID
AsicSetMcastWC(
6445 IN PRTMP_ADAPTER pAd
)
6447 MAC_TABLE_ENTRY
*pEntry
= &pAd
->MacTab
.Content
[MCAST_WCID
];
6450 pEntry
->Sst
= SST_ASSOC
;
6451 pEntry
->Aid
= MCAST_WCID
; // Softap supports 1 BSSID and use WCID=0 as multicast Wcid index
6452 pEntry
->PsMode
= PWR_ACTIVE
;
6453 pEntry
->CurrTxRate
= pAd
->CommonCfg
.MlmeRate
;
6454 offset
= MAC_WCID_BASE
+ BSS0Mcast_WCID
* HW_WCID_ENTRY_SIZE
;
6458 ==========================================================================
6461 IRQL = DISPATCH_LEVEL
6463 ==========================================================================
6465 VOID
AsicDelWcidTab(
6466 IN PRTMP_ADAPTER pAd
,
6469 ULONG Addr0
= 0x0, Addr1
= 0x0;
6472 DBGPRINT(RT_DEBUG_TRACE
, ("AsicDelWcidTab==>Wcid = 0x%x\n",Wcid
));
6473 offset
= MAC_WCID_BASE
+ Wcid
* HW_WCID_ENTRY_SIZE
;
6474 RTMP_IO_WRITE32(pAd
, offset
, Addr0
);
6476 RTMP_IO_WRITE32(pAd
, offset
, Addr1
);
6480 ==========================================================================
6483 IRQL = DISPATCH_LEVEL
6485 ==========================================================================
6488 IN PRTMP_ADAPTER pAd
)
6490 TX_LINK_CFG_STRUC TxLinkCfg
;
6493 RTMP_IO_READ32(pAd
, TX_LINK_CFG
, &TxLinkCfg
.word
);
6494 TxLinkCfg
.field
.TxRDGEn
= 1;
6495 RTMP_IO_WRITE32(pAd
, TX_LINK_CFG
, TxLinkCfg
.word
);
6497 RTMP_IO_READ32(pAd
, EDCA_AC0_CFG
, &Data
);
6500 RTMP_IO_WRITE32(pAd
, EDCA_AC0_CFG
, Data
);
6502 //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
6506 ==========================================================================
6509 IRQL = DISPATCH_LEVEL
6511 ==========================================================================
6513 VOID
AsicDisableRDG(
6514 IN PRTMP_ADAPTER pAd
)
6516 TX_LINK_CFG_STRUC TxLinkCfg
;
6520 RTMP_IO_READ32(pAd
, TX_LINK_CFG
, &TxLinkCfg
.word
);
6521 TxLinkCfg
.field
.TxRDGEn
= 0;
6522 RTMP_IO_WRITE32(pAd
, TX_LINK_CFG
, TxLinkCfg
.word
);
6524 RTMP_IO_READ32(pAd
, EDCA_AC0_CFG
, &Data
);
6527 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE
)
6528 && (pAd
->MacTab
.fAnyStationMIMOPSDynamic
== FALSE
)
6531 // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
6532 if (pAd
->CommonCfg
.bEnableTxBurst
)
6535 RTMP_IO_WRITE32(pAd
, EDCA_AC0_CFG
, Data
);
6539 ==========================================================================
6542 IRQL = PASSIVE_LEVEL
6543 IRQL = DISPATCH_LEVEL
6545 ==========================================================================
6547 VOID
AsicDisableSync(
6548 IN PRTMP_ADAPTER pAd
)
6550 BCN_TIME_CFG_STRUC csr
;
6552 DBGPRINT(RT_DEBUG_TRACE
, ("--->Disable TSF synchronization\n"));
6554 // 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect
6555 // that NIC will never wakes up because TSF stops and no more
6557 pAd
->TbttTickCount
= 0;
6558 RTMP_IO_READ32(pAd
, BCN_TIME_CFG
, &csr
.word
);
6559 csr
.field
.bBeaconGen
= 0;
6560 csr
.field
.bTBTTEnable
= 0;
6561 csr
.field
.TsfSyncMode
= 0;
6562 csr
.field
.bTsfTicking
= 0;
6563 RTMP_IO_WRITE32(pAd
, BCN_TIME_CFG
, csr
.word
);
6568 ==========================================================================
6571 IRQL = DISPATCH_LEVEL
6573 ==========================================================================
6575 VOID
AsicEnableBssSync(
6576 IN PRTMP_ADAPTER pAd
)
6578 BCN_TIME_CFG_STRUC csr
;
6580 DBGPRINT(RT_DEBUG_TRACE
, ("--->AsicEnableBssSync(INFRA mode)\n"));
6582 RTMP_IO_READ32(pAd
, BCN_TIME_CFG
, &csr
.word
);
6585 csr
.field
.BeaconInterval
= pAd
->CommonCfg
.BeaconPeriod
<< 4; // ASIC register in units of 1/16 TU
6586 csr
.field
.bTsfTicking
= 1;
6587 csr
.field
.TsfSyncMode
= 1; // sync TSF in INFRASTRUCTURE mode
6588 csr
.field
.bBeaconGen
= 0; // do NOT generate BEACON
6589 csr
.field
.bTBTTEnable
= 1;
6592 RTMP_IO_WRITE32(pAd
, BCN_TIME_CFG
, csr
.word
);
6596 ==========================================================================
6599 BEACON frame in shared memory should be built ok before this routine
6600 can be called. Otherwise, a garbage frame maybe transmitted out every
6603 IRQL = DISPATCH_LEVEL
6605 ==========================================================================
6607 VOID
AsicEnableIbssSync(
6608 IN PRTMP_ADAPTER pAd
)
6610 BCN_TIME_CFG_STRUC csr9
;
6614 DBGPRINT(RT_DEBUG_TRACE
, ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n", pAd
->BeaconTxWI
.MPDUtotalByteCount
));
6616 RTMP_IO_READ32(pAd
, BCN_TIME_CFG
, &csr9
.word
);
6617 csr9
.field
.bBeaconGen
= 0;
6618 csr9
.field
.bTBTTEnable
= 0;
6619 csr9
.field
.bTsfTicking
= 0;
6620 RTMP_IO_WRITE32(pAd
, BCN_TIME_CFG
, csr9
.word
);
6623 // move BEACON TXD and frame content to on-chip memory
6624 ptr
= (PUCHAR
)&pAd
->BeaconTxWI
;
6625 for (i
=0; i
<TXWI_SIZE
; i
+=4) // 16-byte TXWI field
6627 UINT32 longptr
= *ptr
+ (*(ptr
+1)<<8) + (*(ptr
+2)<<16) + (*(ptr
+3)<<24);
6628 RTMP_IO_WRITE32(pAd
, HW_BEACON_BASE0
+ i
, longptr
);
6632 // start right after the 16-byte TXWI field
6633 ptr
= pAd
->BeaconBuf
;
6634 for (i
=0; i
< pAd
->BeaconTxWI
.MPDUtotalByteCount
; i
+=4)
6636 UINT32 longptr
= *ptr
+ (*(ptr
+1)<<8) + (*(ptr
+2)<<16) + (*(ptr
+3)<<24);
6637 RTMP_IO_WRITE32(pAd
, HW_BEACON_BASE0
+ TXWI_SIZE
+ i
, longptr
);
6642 // move BEACON TXD and frame content to on-chip memory
6643 ptr
= (PUCHAR
)&pAd
->BeaconTxWI
;
6644 for (i
=0; i
<TXWI_SIZE
; i
+=2) // 16-byte TXWI field
6646 RTUSBMultiWrite(pAd
, HW_BEACON_BASE0
+ i
, ptr
, 2);
6650 // start right after the 16-byte TXWI field
6651 ptr
= pAd
->BeaconBuf
;
6652 for (i
=0; i
< pAd
->BeaconTxWI
.MPDUtotalByteCount
; i
+=2)
6654 RTUSBMultiWrite(pAd
, HW_BEACON_BASE0
+ TXWI_SIZE
+ i
, ptr
, 2);
6659 // start sending BEACON
6660 csr9
.field
.BeaconInterval
= pAd
->CommonCfg
.BeaconPeriod
<< 4; // ASIC register in units of 1/16 TU
6661 csr9
.field
.bTsfTicking
= 1;
6662 csr9
.field
.TsfSyncMode
= 2; // sync TSF in IBSS mode
6663 csr9
.field
.bTBTTEnable
= 1;
6664 csr9
.field
.bBeaconGen
= 1;
6665 RTMP_IO_WRITE32(pAd
, BCN_TIME_CFG
, csr9
.word
);
6669 ==========================================================================
6672 IRQL = PASSIVE_LEVEL
6673 IRQL = DISPATCH_LEVEL
6675 ==========================================================================
6677 VOID
AsicSetEdcaParm(
6678 IN PRTMP_ADAPTER pAd
,
6679 IN PEDCA_PARM pEdcaParm
)
6681 EDCA_AC_CFG_STRUC Ac0Cfg
, Ac1Cfg
, Ac2Cfg
, Ac3Cfg
;
6682 AC_TXOP_CSR0_STRUC csr0
;
6683 AC_TXOP_CSR1_STRUC csr1
;
6684 AIFSN_CSR_STRUC AifsnCsr
;
6685 CWMIN_CSR_STRUC CwminCsr
;
6686 CWMAX_CSR_STRUC CwmaxCsr
;
6693 if ((pEdcaParm
== NULL
) || (pEdcaParm
->bValid
== FALSE
))
6695 DBGPRINT(RT_DEBUG_TRACE
,("AsicSetEdcaParm\n"));
6696 OPSTATUS_CLEAR_FLAG(pAd
, fOP_STATUS_WMM_INUSED
);
6697 for (i
=0; i
<MAX_LEN_OF_MAC_TABLE
; i
++)
6699 if (pAd
->MacTab
.Content
[i
].ValidAsCLI
|| pAd
->MacTab
.Content
[i
].ValidAsApCli
)
6700 CLIENT_STATUS_CLEAR_FLAG(&pAd
->MacTab
.Content
[i
], fCLIENT_STATUS_WMM_CAPABLE
);
6703 //========================================================
6704 // MAC Register has a copy .
6705 //========================================================
6706 if( pAd
->CommonCfg
.bEnableTxBurst
)
6708 // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
6709 Ac0Cfg
.field
.AcTxop
= 0x20; // Suggest by John for TxBurst in HT Mode
6712 Ac0Cfg
.field
.AcTxop
= 0; // QID_AC_BE
6713 Ac0Cfg
.field
.Cwmin
= CW_MIN_IN_BITS
;
6714 Ac0Cfg
.field
.Cwmax
= CW_MAX_IN_BITS
;
6715 Ac0Cfg
.field
.Aifsn
= 2;
6716 RTMP_IO_WRITE32(pAd
, EDCA_AC0_CFG
, Ac0Cfg
.word
);
6718 Ac1Cfg
.field
.AcTxop
= 0; // QID_AC_BK
6719 Ac1Cfg
.field
.Cwmin
= CW_MIN_IN_BITS
;
6720 Ac1Cfg
.field
.Cwmax
= CW_MAX_IN_BITS
;
6721 Ac1Cfg
.field
.Aifsn
= 2;
6722 RTMP_IO_WRITE32(pAd
, EDCA_AC1_CFG
, Ac1Cfg
.word
);
6724 if (pAd
->CommonCfg
.PhyMode
== PHY_11B
)
6726 Ac2Cfg
.field
.AcTxop
= 192; // AC_VI: 192*32us ~= 6ms
6727 Ac3Cfg
.field
.AcTxop
= 96; // AC_VO: 96*32us ~= 3ms
6731 Ac2Cfg
.field
.AcTxop
= 96; // AC_VI: 96*32us ~= 3ms
6732 Ac3Cfg
.field
.AcTxop
= 48; // AC_VO: 48*32us ~= 1.5ms
6734 Ac2Cfg
.field
.Cwmin
= CW_MIN_IN_BITS
;
6735 Ac2Cfg
.field
.Cwmax
= CW_MAX_IN_BITS
;
6736 Ac2Cfg
.field
.Aifsn
= 2;
6737 RTMP_IO_WRITE32(pAd
, EDCA_AC2_CFG
, Ac2Cfg
.word
);
6738 Ac3Cfg
.field
.Cwmin
= CW_MIN_IN_BITS
;
6739 Ac3Cfg
.field
.Cwmax
= CW_MAX_IN_BITS
;
6740 Ac3Cfg
.field
.Aifsn
= 2;
6741 RTMP_IO_WRITE32(pAd
, EDCA_AC3_CFG
, Ac3Cfg
.word
);
6743 //========================================================
6744 // DMA Register has a copy too.
6745 //========================================================
6746 csr0
.field
.Ac0Txop
= 0; // QID_AC_BE
6747 csr0
.field
.Ac1Txop
= 0; // QID_AC_BK
6748 RTMP_IO_WRITE32(pAd
, WMM_TXOP0_CFG
, csr0
.word
);
6749 if (pAd
->CommonCfg
.PhyMode
== PHY_11B
)
6751 csr1
.field
.Ac2Txop
= 192; // AC_VI: 192*32us ~= 6ms
6752 csr1
.field
.Ac3Txop
= 96; // AC_VO: 96*32us ~= 3ms
6756 csr1
.field
.Ac2Txop
= 96; // AC_VI: 96*32us ~= 3ms
6757 csr1
.field
.Ac3Txop
= 48; // AC_VO: 48*32us ~= 1.5ms
6759 RTMP_IO_WRITE32(pAd
, WMM_TXOP1_CFG
, csr1
.word
);
6762 CwminCsr
.field
.Cwmin0
= CW_MIN_IN_BITS
;
6763 CwminCsr
.field
.Cwmin1
= CW_MIN_IN_BITS
;
6764 CwminCsr
.field
.Cwmin2
= CW_MIN_IN_BITS
;
6765 CwminCsr
.field
.Cwmin3
= CW_MIN_IN_BITS
;
6766 RTMP_IO_WRITE32(pAd
, WMM_CWMIN_CFG
, CwminCsr
.word
);
6769 CwmaxCsr
.field
.Cwmax0
= CW_MAX_IN_BITS
;
6770 CwmaxCsr
.field
.Cwmax1
= CW_MAX_IN_BITS
;
6771 CwmaxCsr
.field
.Cwmax2
= CW_MAX_IN_BITS
;
6772 CwmaxCsr
.field
.Cwmax3
= CW_MAX_IN_BITS
;
6773 RTMP_IO_WRITE32(pAd
, WMM_CWMAX_CFG
, CwmaxCsr
.word
);
6775 RTMP_IO_WRITE32(pAd
, WMM_AIFSN_CFG
, 0x00002222);
6777 NdisZeroMemory(&pAd
->CommonCfg
.APEdcaParm
, sizeof(EDCA_PARM
));
6781 OPSTATUS_SET_FLAG(pAd
, fOP_STATUS_WMM_INUSED
);
6782 //========================================================
6783 // MAC Register has a copy.
6784 //========================================================
6786 // Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27
6787 // To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue.
6789 //pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this
6791 Ac0Cfg
.field
.AcTxop
= pEdcaParm
->Txop
[QID_AC_BE
];
6792 Ac0Cfg
.field
.Cwmin
= pEdcaParm
->Cwmin
[QID_AC_BE
];
6793 Ac0Cfg
.field
.Cwmax
= pEdcaParm
->Cwmax
[QID_AC_BE
];
6794 Ac0Cfg
.field
.Aifsn
= pEdcaParm
->Aifsn
[QID_AC_BE
]; //+1;
6796 Ac1Cfg
.field
.AcTxop
= pEdcaParm
->Txop
[QID_AC_BK
];
6797 Ac1Cfg
.field
.Cwmin
= pEdcaParm
->Cwmin
[QID_AC_BK
]; //+2;
6798 Ac1Cfg
.field
.Cwmax
= pEdcaParm
->Cwmax
[QID_AC_BK
];
6799 Ac1Cfg
.field
.Aifsn
= pEdcaParm
->Aifsn
[QID_AC_BK
]; //+1;
6801 Ac2Cfg
.field
.AcTxop
= (pEdcaParm
->Txop
[QID_AC_VI
] * 6) / 10;
6802 Ac2Cfg
.field
.Cwmin
= pEdcaParm
->Cwmin
[QID_AC_VI
];
6803 Ac2Cfg
.field
.Cwmax
= pEdcaParm
->Cwmax
[QID_AC_VI
];
6804 Ac2Cfg
.field
.Aifsn
= pEdcaParm
->Aifsn
[QID_AC_VI
];
6807 // Tuning for Wi-Fi WMM S06
6808 if (pAd
->CommonCfg
.bWiFiTest
&&
6809 pEdcaParm
->Aifsn
[QID_AC_VI
] == 10)
6810 Ac2Cfg
.field
.Aifsn
-= 1;
6812 // Tuning for TGn Wi-Fi 5.2.32
6813 // STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta
6814 if (STA_TGN_WIFI_ON(pAd
) &&
6815 pEdcaParm
->Aifsn
[QID_AC_VI
] == 10)
6817 Ac0Cfg
.field
.Aifsn
= 3;
6818 Ac2Cfg
.field
.AcTxop
= 5;
6822 if (pAd
->RfIcType
== RFIC_3020
|| pAd
->RfIcType
== RFIC_2020
)
6824 // Tuning for WiFi WMM S3-T07: connexant legacy sta ==> broadcom 11n sta.
6825 Ac2Cfg
.field
.Aifsn
= 5;
6830 Ac3Cfg
.field
.AcTxop
= pEdcaParm
->Txop
[QID_AC_VO
];
6831 Ac3Cfg
.field
.Cwmin
= pEdcaParm
->Cwmin
[QID_AC_VO
];
6832 Ac3Cfg
.field
.Cwmax
= pEdcaParm
->Cwmax
[QID_AC_VO
];
6833 Ac3Cfg
.field
.Aifsn
= pEdcaParm
->Aifsn
[QID_AC_VO
];
6836 if (pAd
->CommonCfg
.bWiFiTest
)
6838 if (Ac3Cfg
.field
.AcTxop
== 102)
6840 Ac0Cfg
.field
.AcTxop
= pEdcaParm
->Txop
[QID_AC_BE
] ? pEdcaParm
->Txop
[QID_AC_BE
] : 10;
6841 Ac0Cfg
.field
.Aifsn
= pEdcaParm
->Aifsn
[QID_AC_BE
]-1; /* AIFSN must >= 1 */
6842 Ac1Cfg
.field
.AcTxop
= pEdcaParm
->Txop
[QID_AC_BK
];
6843 Ac1Cfg
.field
.Aifsn
= pEdcaParm
->Aifsn
[QID_AC_BK
];
6844 Ac2Cfg
.field
.AcTxop
= pEdcaParm
->Txop
[QID_AC_VI
];
6847 //#endif // WIFI_TEST //
6849 RTMP_IO_WRITE32(pAd
, EDCA_AC0_CFG
, Ac0Cfg
.word
);
6850 RTMP_IO_WRITE32(pAd
, EDCA_AC1_CFG
, Ac1Cfg
.word
);
6851 RTMP_IO_WRITE32(pAd
, EDCA_AC2_CFG
, Ac2Cfg
.word
);
6852 RTMP_IO_WRITE32(pAd
, EDCA_AC3_CFG
, Ac3Cfg
.word
);
6855 //========================================================
6856 // DMA Register has a copy too.
6857 //========================================================
6858 csr0
.field
.Ac0Txop
= Ac0Cfg
.field
.AcTxop
;
6859 csr0
.field
.Ac1Txop
= Ac1Cfg
.field
.AcTxop
;
6860 RTMP_IO_WRITE32(pAd
, WMM_TXOP0_CFG
, csr0
.word
);
6862 csr1
.field
.Ac2Txop
= Ac2Cfg
.field
.AcTxop
;
6863 csr1
.field
.Ac3Txop
= Ac3Cfg
.field
.AcTxop
;
6864 RTMP_IO_WRITE32(pAd
, WMM_TXOP1_CFG
, csr1
.word
);
6867 CwminCsr
.field
.Cwmin0
= pEdcaParm
->Cwmin
[QID_AC_BE
];
6868 CwminCsr
.field
.Cwmin1
= pEdcaParm
->Cwmin
[QID_AC_BK
];
6869 CwminCsr
.field
.Cwmin2
= pEdcaParm
->Cwmin
[QID_AC_VI
];
6871 CwminCsr
.field
.Cwmin3
= pEdcaParm
->Cwmin
[QID_AC_VO
] - 1; //for TGn wifi test
6873 RTMP_IO_WRITE32(pAd
, WMM_CWMIN_CFG
, CwminCsr
.word
);
6876 CwmaxCsr
.field
.Cwmax0
= pEdcaParm
->Cwmax
[QID_AC_BE
];
6877 CwmaxCsr
.field
.Cwmax1
= pEdcaParm
->Cwmax
[QID_AC_BK
];
6878 CwmaxCsr
.field
.Cwmax2
= pEdcaParm
->Cwmax
[QID_AC_VI
];
6879 CwmaxCsr
.field
.Cwmax3
= pEdcaParm
->Cwmax
[QID_AC_VO
];
6880 RTMP_IO_WRITE32(pAd
, WMM_CWMAX_CFG
, CwmaxCsr
.word
);
6883 AifsnCsr
.field
.Aifsn0
= Ac0Cfg
.field
.Aifsn
; //pEdcaParm->Aifsn[QID_AC_BE];
6884 AifsnCsr
.field
.Aifsn1
= Ac1Cfg
.field
.Aifsn
; //pEdcaParm->Aifsn[QID_AC_BK];
6885 AifsnCsr
.field
.Aifsn2
= Ac2Cfg
.field
.Aifsn
; //pEdcaParm->Aifsn[QID_AC_VI];
6888 // Tuning for Wi-Fi WMM S06
6889 if (pAd
->CommonCfg
.bWiFiTest
&&
6890 pEdcaParm
->Aifsn
[QID_AC_VI
] == 10)
6891 AifsnCsr
.field
.Aifsn2
= Ac2Cfg
.field
.Aifsn
- 4;
6893 // Tuning for TGn Wi-Fi 5.2.32
6894 // STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta
6895 if (STA_TGN_WIFI_ON(pAd
) &&
6896 pEdcaParm
->Aifsn
[QID_AC_VI
] == 10)
6898 AifsnCsr
.field
.Aifsn0
= 3;
6899 AifsnCsr
.field
.Aifsn2
= 7;
6903 CLIENT_STATUS_SET_FLAG(&pAd
->MacTab
.Content
[BSSID_WCID
], fCLIENT_STATUS_WMM_CAPABLE
);
6907 AifsnCsr
.field
.Aifsn3
= Ac3Cfg
.field
.Aifsn
- 1; //pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test
6909 if (pAd
->RfIcType
== RFIC_3020
|| pAd
->RfIcType
== RFIC_2020
)
6910 AifsnCsr
.field
.Aifsn2
= 0x2; //pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04.
6912 RTMP_IO_WRITE32(pAd
, WMM_AIFSN_CFG
, AifsnCsr
.word
);
6914 NdisMoveMemory(&pAd
->CommonCfg
.APEdcaParm
, pEdcaParm
, sizeof(EDCA_PARM
));
6917 DBGPRINT(RT_DEBUG_TRACE
,("EDCA [#%d]: AIFSN CWmin CWmax TXOP(us) ACM\n", pEdcaParm
->EdcaUpdateCount
));
6918 DBGPRINT(RT_DEBUG_TRACE
,(" AC_BE %2d %2d %2d %4d %d\n",
6919 pEdcaParm
->Aifsn
[0],
6920 pEdcaParm
->Cwmin
[0],
6921 pEdcaParm
->Cwmax
[0],
6922 pEdcaParm
->Txop
[0]<<5,
6923 pEdcaParm
->bACM
[0]));
6924 DBGPRINT(RT_DEBUG_TRACE
,(" AC_BK %2d %2d %2d %4d %d\n",
6925 pEdcaParm
->Aifsn
[1],
6926 pEdcaParm
->Cwmin
[1],
6927 pEdcaParm
->Cwmax
[1],
6928 pEdcaParm
->Txop
[1]<<5,
6929 pEdcaParm
->bACM
[1]));
6930 DBGPRINT(RT_DEBUG_TRACE
,(" AC_VI %2d %2d %2d %4d %d\n",
6931 pEdcaParm
->Aifsn
[2],
6932 pEdcaParm
->Cwmin
[2],
6933 pEdcaParm
->Cwmax
[2],
6934 pEdcaParm
->Txop
[2]<<5,
6935 pEdcaParm
->bACM
[2]));
6936 DBGPRINT(RT_DEBUG_TRACE
,(" AC_VO %2d %2d %2d %4d %d\n",
6937 pEdcaParm
->Aifsn
[3],
6938 pEdcaParm
->Cwmin
[3],
6939 pEdcaParm
->Cwmax
[3],
6940 pEdcaParm
->Txop
[3]<<5,
6941 pEdcaParm
->bACM
[3]));
6947 ==========================================================================
6950 IRQL = PASSIVE_LEVEL
6951 IRQL = DISPATCH_LEVEL
6953 ==========================================================================
6955 VOID
AsicSetSlotTime(
6956 IN PRTMP_ADAPTER pAd
,
6957 IN BOOLEAN bUseShortSlotTime
)
6960 UINT32 RegValue
= 0;
6962 if (pAd
->CommonCfg
.Channel
> 14)
6963 bUseShortSlotTime
= TRUE
;
6965 if (bUseShortSlotTime
)
6966 OPSTATUS_SET_FLAG(pAd
, fOP_STATUS_SHORT_SLOT_INUSED
);
6968 OPSTATUS_CLEAR_FLAG(pAd
, fOP_STATUS_SHORT_SLOT_INUSED
);
6970 SlotTime
= (bUseShortSlotTime
)? 9 : 20;
6973 // force using short SLOT time for FAE to demo performance when TxBurst is ON
6974 if (((pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
== FALSE
) && (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_WMM_INUSED
)))
6975 || ((pAd
->StaActive
.SupportedPhyInfo
.bHtEnable
== TRUE
) && (pAd
->CommonCfg
.BACapability
.field
.Policy
== BA_NOTUSE
))
6978 // In this case, we will think it is doing Wi-Fi test
6979 // And we will not set to short slot when bEnableTxBurst is TRUE.
6981 else if (pAd
->CommonCfg
.bEnableTxBurst
)
6986 // For some reasons, always set it to short slot time.
6988 // ToDo: Should consider capability with 11B
6990 if (pAd
->StaCfg
.BssType
== BSS_ADHOC
)
6993 RTMP_IO_READ32(pAd
, BKOFF_SLOT_CFG
, &RegValue
);
6994 RegValue
= RegValue
& 0xFFFFFF00;
6996 RegValue
|= SlotTime
;
6998 RTMP_IO_WRITE32(pAd
, BKOFF_SLOT_CFG
, RegValue
);
7002 ========================================================================
7004 Add Shared key information into ASIC.
7005 Update shared key, TxMic and RxMic to Asic Shared key table
7006 Update its cipherAlg to Asic Shared key Mode.
7009 ========================================================================
7011 VOID
AsicAddSharedKeyEntry(
7012 IN PRTMP_ADAPTER pAd
,
7020 ULONG offset
; //, csr0;
7021 SHAREDKEY_MODE_STRUC csr1
;
7026 DBGPRINT(RT_DEBUG_TRACE
, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex
,KeyIdx
));
7027 //============================================================================================
7029 DBGPRINT(RT_DEBUG_TRACE
,("AsicAddSharedKeyEntry: %s key #%d\n", CipherName
[CipherAlg
], BssIndex
*4 + KeyIdx
));
7030 DBGPRINT_RAW(RT_DEBUG_TRACE
, (" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7031 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]));
7034 DBGPRINT_RAW(RT_DEBUG_TRACE
, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7035 pRxMic
[0],pRxMic
[1],pRxMic
[2],pRxMic
[3],pRxMic
[4],pRxMic
[5],pRxMic
[6],pRxMic
[7]));
7039 DBGPRINT_RAW(RT_DEBUG_TRACE
, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7040 pTxMic
[0],pTxMic
[1],pTxMic
[2],pTxMic
[3],pTxMic
[4],pTxMic
[5],pTxMic
[6],pTxMic
[7]));
7042 //============================================================================================
7044 // fill key material - key + TX MIC + RX MIC
7047 offset
= SHARED_KEY_TABLE_BASE
+ (4*BssIndex
+ KeyIdx
)*HW_KEY_ENTRY_SIZE
;
7049 for (i
=0; i
<MAX_LEN_OF_SHARE_KEY
; i
++)
7051 RTMP_IO_WRITE8(pAd
, offset
+ i
, pKey
[i
]);
7055 RTUSBMultiWrite(pAd
, offset
, pKey
, MAX_LEN_OF_SHARE_KEY
);
7057 offset
+= MAX_LEN_OF_SHARE_KEY
;
7063 RTMP_IO_WRITE8(pAd
, offset
+ i
, pTxMic
[i
]);
7067 RTUSBMultiWrite(pAd
, offset
, pTxMic
, 8);
7077 RTMP_IO_WRITE8(pAd
, offset
+ i
, pRxMic
[i
]);
7081 RTUSBMultiWrite(pAd
, offset
, pRxMic
, 8);
7087 // Update cipher algorithm. WSTA always use BSS0
7089 RTMP_IO_READ32(pAd
, SHARED_KEY_MODE_BASE
+4*(BssIndex
/2), &csr1
.word
);
7090 DBGPRINT(RT_DEBUG_TRACE
,("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n", BssIndex
,KeyIdx
, csr1
.word
));
7091 if ((BssIndex
%2) == 0)
7094 csr1
.field
.Bss0Key0CipherAlg
= CipherAlg
;
7095 else if (KeyIdx
== 1)
7096 csr1
.field
.Bss0Key1CipherAlg
= CipherAlg
;
7097 else if (KeyIdx
== 2)
7098 csr1
.field
.Bss0Key2CipherAlg
= CipherAlg
;
7100 csr1
.field
.Bss0Key3CipherAlg
= CipherAlg
;
7105 csr1
.field
.Bss1Key0CipherAlg
= CipherAlg
;
7106 else if (KeyIdx
== 1)
7107 csr1
.field
.Bss1Key1CipherAlg
= CipherAlg
;
7108 else if (KeyIdx
== 2)
7109 csr1
.field
.Bss1Key2CipherAlg
= CipherAlg
;
7111 csr1
.field
.Bss1Key3CipherAlg
= CipherAlg
;
7113 DBGPRINT(RT_DEBUG_TRACE
,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex
, csr1
.word
));
7114 RTMP_IO_WRITE32(pAd
, SHARED_KEY_MODE_BASE
+4*(BssIndex
/2), csr1
.word
);
7118 // IRQL = DISPATCH_LEVEL
7119 VOID
AsicRemoveSharedKeyEntry(
7120 IN PRTMP_ADAPTER pAd
,
7125 SHAREDKEY_MODE_STRUC csr1
;
7127 DBGPRINT(RT_DEBUG_TRACE
,("AsicRemoveSharedKeyEntry: #%d \n", BssIndex
*4 + KeyIdx
));
7129 RTMP_IO_READ32(pAd
, SHARED_KEY_MODE_BASE
+4*(BssIndex
/2), &csr1
.word
);
7130 if ((BssIndex
%2) == 0)
7133 csr1
.field
.Bss0Key0CipherAlg
= 0;
7134 else if (KeyIdx
== 1)
7135 csr1
.field
.Bss0Key1CipherAlg
= 0;
7136 else if (KeyIdx
== 2)
7137 csr1
.field
.Bss0Key2CipherAlg
= 0;
7139 csr1
.field
.Bss0Key3CipherAlg
= 0;
7144 csr1
.field
.Bss1Key0CipherAlg
= 0;
7145 else if (KeyIdx
== 1)
7146 csr1
.field
.Bss1Key1CipherAlg
= 0;
7147 else if (KeyIdx
== 2)
7148 csr1
.field
.Bss1Key2CipherAlg
= 0;
7150 csr1
.field
.Bss1Key3CipherAlg
= 0;
7152 DBGPRINT(RT_DEBUG_TRACE
,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex
, csr1
.word
));
7153 RTMP_IO_WRITE32(pAd
, SHARED_KEY_MODE_BASE
+4*(BssIndex
/2), csr1
.word
);
7154 ASSERT(BssIndex
< 4);
7160 VOID
AsicUpdateWCIDAttribute(
7161 IN PRTMP_ADAPTER pAd
,
7165 IN BOOLEAN bUsePairewiseKeyTable
)
7167 ULONG WCIDAttri
= 0, offset
;
7170 // Update WCID attribute.
7171 // Only TxKey could update WCID attribute.
7173 offset
= MAC_WCID_ATTRIBUTE_BASE
+ (WCID
* HW_WCID_ATTRI_SIZE
);
7174 WCIDAttri
= (BssIndex
<< 4) | (CipherAlg
<< 1) | (bUsePairewiseKeyTable
);
7175 RTMP_IO_WRITE32(pAd
, offset
, WCIDAttri
);
7178 VOID
AsicUpdateWCIDIVEIV(
7179 IN PRTMP_ADAPTER pAd
,
7186 offset
= MAC_IVEIV_TABLE_BASE
+ (WCID
* HW_IVEIV_ENTRY_SIZE
);
7188 RTMP_IO_WRITE32(pAd
, offset
, uIV
);
7189 RTMP_IO_WRITE32(pAd
, offset
+ 4, uEIV
);
7192 VOID
AsicUpdateRxWCIDTable(
7193 IN PRTMP_ADAPTER pAd
,
7200 offset
= MAC_WCID_BASE
+ (WCID
* HW_WCID_ENTRY_SIZE
);
7201 Addr
= pAddr
[0] + (pAddr
[1] << 8) +(pAddr
[2] << 16) +(pAddr
[3] << 24);
7202 RTMP_IO_WRITE32(pAd
, offset
, Addr
);
7203 Addr
= pAddr
[4] + (pAddr
[5] << 8);
7204 RTMP_IO_WRITE32(pAd
, offset
+ 4, Addr
);
7209 ========================================================================
7211 Routine Description:
7212 Set Cipher Key, Cipher algorithm, IV/EIV to Asic
7215 pAd Pointer to our adapter
7216 WCID WCID Entry number.
7217 BssIndex BSSID index, station or none multiple BSSID support
7218 this value should be 0.
7219 KeyIdx This KeyIdx will set to IV's KeyID if bTxKey enabled
7220 pCipherKey Pointer to Cipher Key.
7221 bUsePairewiseKeyTable TRUE means saved the key in SharedKey table,
7222 otherwise PairewiseKey table
7223 bTxKey This is the transmit key if enabled.
7229 This routine will set the relative key stuff to Asic including WCID attribute,
7230 Cipher Key, Cipher algorithm and IV/EIV.
7232 IV/EIV will be update if this CipherKey is the transmission key because
7233 ASIC will base on IV's KeyID value to select Cipher Key.
7235 If bTxKey sets to FALSE, this is not the TX key, but it could be
7238 For AP mode bTxKey must be always set to TRUE.
7239 ========================================================================
7241 VOID
AsicAddKeyEntry(
7242 IN PRTMP_ADAPTER pAd
,
7246 IN PCIPHER_KEY pCipherKey
,
7247 IN BOOLEAN bUsePairewiseKeyTable
,
7252 PUCHAR pKey
= pCipherKey
->Key
;
7253 PUCHAR pTxMic
= pCipherKey
->TxMic
;
7254 PUCHAR pRxMic
= pCipherKey
->RxMic
;
7255 PUCHAR pTxtsc
= pCipherKey
->TxTsc
;
7256 UCHAR CipherAlg
= pCipherKey
->CipherAlg
;
7257 SHAREDKEY_MODE_STRUC csr1
;
7262 DBGPRINT(RT_DEBUG_TRACE
, ("==> AsicAddKeyEntry\n"));
7264 // 1.) decide key table offset
7266 if (bUsePairewiseKeyTable
)
7267 offset
= PAIRWISE_KEY_TABLE_BASE
+ (WCID
* HW_KEY_ENTRY_SIZE
);
7269 offset
= SHARED_KEY_TABLE_BASE
+ (4 * BssIndex
+ KeyIdx
) * HW_KEY_ENTRY_SIZE
;
7272 // 2.) Set Key to Asic
7274 //for (i = 0; i < KeyLen; i++)
7276 for (i
= 0; i
< MAX_LEN_OF_PEER_KEY
; i
++)
7278 RTMP_IO_WRITE8(pAd
, offset
+ i
, pKey
[i
]);
7282 RTUSBMultiWrite(pAd
, offset
, pKey
, MAX_LEN_OF_PEER_KEY
);
7284 offset
+= MAX_LEN_OF_PEER_KEY
;
7287 // 3.) Set MIC key if available
7292 for (i
= 0; i
< 8; i
++)
7294 RTMP_IO_WRITE8(pAd
, offset
+ i
, pTxMic
[i
]);
7298 RTUSBMultiWrite(pAd
, offset
, pTxMic
, 8);
7301 offset
+= LEN_TKIP_TXMICK
;
7306 for (i
= 0; i
< 8; i
++)
7308 RTMP_IO_WRITE8(pAd
, offset
+ i
, pRxMic
[i
]);
7312 RTUSBMultiWrite(pAd
, offset
, pRxMic
, 8);
7318 // 4.) Modify IV/EIV if needs
7319 // This will force Asic to use this key ID by setting IV.
7324 offset
= MAC_IVEIV_TABLE_BASE
+ (WCID
* HW_IVEIV_ENTRY_SIZE
);
7328 RTMP_IO_WRITE8(pAd
, offset
, pTxtsc
[1]);
7329 RTMP_IO_WRITE8(pAd
, offset
+ 1, ((pTxtsc
[1] | 0x20) & 0x7f));
7330 RTMP_IO_WRITE8(pAd
, offset
+ 2, pTxtsc
[0]);
7332 IV4
= (KeyIdx
<< 6);
7333 if ((CipherAlg
== CIPHER_TKIP
) || (CipherAlg
== CIPHER_TKIP_NO_MIC
) ||(CipherAlg
== CIPHER_AES
))
7334 IV4
|= 0x20; // turn on extension bit means EIV existence
7336 RTMP_IO_WRITE8(pAd
, offset
+ 3, IV4
);
7342 for (i
= 0; i
< 4; i
++)
7344 RTMP_IO_WRITE8(pAd
, offset
+ i
, pTxtsc
[i
+ 2]);
7354 IV4
= (KeyIdx
<< 6);
7355 if ((CipherAlg
== CIPHER_TKIP
) || (CipherAlg
== CIPHER_TKIP_NO_MIC
) ||(CipherAlg
== CIPHER_AES
))
7356 IV4
|= 0x20; // turn on extension bit means EIV existence
7358 tmpVal
= pTxtsc
[1] + (((pTxtsc
[1] | 0x20) & 0x7f) << 8) + (pTxtsc
[0] << 16) + (IV4
<< 24);
7359 RTMP_IO_WRITE32(pAd
, offset
, tmpVal
);
7365 RTMP_IO_WRITE32(pAd
, offset
, *(PUINT32
)&pCipherKey
->TxTsc
[2]);
7367 AsicUpdateWCIDAttribute(pAd
, WCID
, BssIndex
, CipherAlg
, bUsePairewiseKeyTable
);
7370 if (!bUsePairewiseKeyTable
)
7373 // Only update the shared key security mode
7375 RTMP_IO_READ32(pAd
, SHARED_KEY_MODE_BASE
+ 4 * (BssIndex
/ 2), &csr1
.word
);
7376 if ((BssIndex
% 2) == 0)
7379 csr1
.field
.Bss0Key0CipherAlg
= CipherAlg
;
7380 else if (KeyIdx
== 1)
7381 csr1
.field
.Bss0Key1CipherAlg
= CipherAlg
;
7382 else if (KeyIdx
== 2)
7383 csr1
.field
.Bss0Key2CipherAlg
= CipherAlg
;
7385 csr1
.field
.Bss0Key3CipherAlg
= CipherAlg
;
7390 csr1
.field
.Bss1Key0CipherAlg
= CipherAlg
;
7391 else if (KeyIdx
== 1)
7392 csr1
.field
.Bss1Key1CipherAlg
= CipherAlg
;
7393 else if (KeyIdx
== 2)
7394 csr1
.field
.Bss1Key2CipherAlg
= CipherAlg
;
7396 csr1
.field
.Bss1Key3CipherAlg
= CipherAlg
;
7398 RTMP_IO_WRITE32(pAd
, SHARED_KEY_MODE_BASE
+ 4 * (BssIndex
/ 2), csr1
.word
);
7401 DBGPRINT(RT_DEBUG_TRACE
, ("<== AsicAddKeyEntry\n"));
7406 ========================================================================
7408 Add Pair-wise key material into ASIC.
7409 Update pairwise key, TxMic and RxMic to Asic Pair-wise key table
7412 ========================================================================
7414 VOID
AsicAddPairwiseKeyEntry(
7415 IN PRTMP_ADAPTER pAd
,
7418 IN CIPHER_KEY
*pCipherKey
)
7422 PUCHAR pKey
= pCipherKey
->Key
;
7423 PUCHAR pTxMic
= pCipherKey
->TxMic
;
7424 PUCHAR pRxMic
= pCipherKey
->RxMic
;
7426 UCHAR CipherAlg
= pCipherKey
->CipherAlg
;
7430 offset
= PAIRWISE_KEY_TABLE_BASE
+ (WCID
* HW_KEY_ENTRY_SIZE
);
7432 for (i
=0; i
<MAX_LEN_OF_PEER_KEY
; i
++)
7434 RTMP_IO_WRITE8(pAd
, offset
+ i
, pKey
[i
]);
7438 RTUSBMultiWrite(pAd
, offset
, &pCipherKey
->Key
[0], MAX_LEN_OF_PEER_KEY
);
7440 for (i
=0; i
<MAX_LEN_OF_PEER_KEY
; i
+=4)
7443 RTMP_IO_READ32(pAd
, offset
+ i
, &Value
);
7446 offset
+= MAX_LEN_OF_PEER_KEY
;
7454 RTMP_IO_WRITE8(pAd
, offset
+i
, pTxMic
[i
]);
7458 RTUSBMultiWrite(pAd
, offset
, &pCipherKey
->TxMic
[0], 8);
7467 RTMP_IO_WRITE8(pAd
, offset
+i
, pRxMic
[i
]);
7471 RTUSBMultiWrite(pAd
, offset
, &pCipherKey
->RxMic
[0], 8);
7475 DBGPRINT(RT_DEBUG_TRACE
,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID
, CipherName
[CipherAlg
]));
7476 DBGPRINT(RT_DEBUG_TRACE
,(" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7477 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]));
7480 DBGPRINT(RT_DEBUG_TRACE
, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7481 pRxMic
[0],pRxMic
[1],pRxMic
[2],pRxMic
[3],pRxMic
[4],pRxMic
[5],pRxMic
[6],pRxMic
[7]));
7485 DBGPRINT(RT_DEBUG_TRACE
, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7486 pTxMic
[0],pTxMic
[1],pTxMic
[2],pTxMic
[3],pTxMic
[4],pTxMic
[5],pTxMic
[6],pTxMic
[7]));
7490 ========================================================================
7492 Remove Pair-wise key material from ASIC.
7495 ========================================================================
7497 VOID
AsicRemovePairwiseKeyEntry(
7498 IN PRTMP_ADAPTER pAd
,
7505 // re-set the entry's WCID attribute as OPEN-NONE.
7506 offset
= MAC_WCID_ATTRIBUTE_BASE
+ (Wcid
* HW_WCID_ATTRI_SIZE
);
7507 WCIDAttri
= (BssIdx
<<4) | PAIRWISEKEYTABLE
;
7508 RTMP_IO_WRITE32(pAd
, offset
, WCIDAttri
);
7511 BOOLEAN
AsicSendCommandToMcu(
7512 IN PRTMP_ADAPTER pAd
,
7518 HOST_CMD_CSR_STRUC H2MCmd
;
7519 H2M_MAILBOX_STRUC H2MMailbox
;
7524 RTMP_IO_READ32(pAd
, H2M_MAILBOX_CSR
, &H2MMailbox
.word
);
7525 if (H2MMailbox
.field
.Owner
== 0)
7538 RTMP_IO_READ32(pAd
, PBF_SYS_CTRL
, &Data
);
7540 RTMP_IO_WRITE32(pAd
, PBF_SYS_CTRL
, Data
);
7542 // After Reset DMA, DMA index will become Zero. So Driver need to reset all ring indexs too.
7543 // Reset DMA/CPU ring index
7544 RTMPRingCleanUp(pAd
, QID_AC_BK
);
7545 RTMPRingCleanUp(pAd
, QID_AC_BE
);
7546 RTMPRingCleanUp(pAd
, QID_AC_VI
);
7547 RTMPRingCleanUp(pAd
, QID_AC_VO
);
7548 RTMPRingCleanUp(pAd
, QID_HCCA
);
7549 RTMPRingCleanUp(pAd
, QID_MGMT
);
7550 RTMPRingCleanUp(pAd
, QID_RX
);
7553 RTMP_IO_READ32(pAd
, PBF_SYS_CTRL
, &Data
);
7555 RTMP_IO_WRITE32(pAd
, PBF_SYS_CTRL
, Data
);
7557 DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
7565 H2MMailbox
.field
.Owner
= 1; // pass ownership to MCU
7566 H2MMailbox
.field
.CmdToken
= Token
;
7567 H2MMailbox
.field
.HighByte
= Arg1
;
7568 H2MMailbox
.field
.LowByte
= Arg0
;
7569 RTMP_IO_WRITE32(pAd
, H2M_MAILBOX_CSR
, H2MMailbox
.word
);
7572 H2MCmd
.field
.HostCommand
= Command
;
7573 RTMP_IO_WRITE32(pAd
, HOST_CMD_CSR
, H2MCmd
.word
);
7575 if (Command
!= 0x80)
7583 BOOLEAN
AsicCheckCommanOk(
7584 IN PRTMP_ADAPTER pAd
,
7587 UINT32 CmdStatus
= 0, CID
= 0, i
;
7588 UINT32 ThisCIDMask
= 0;
7593 RTMP_IO_READ32(pAd
, H2M_MAILBOX_CID
, &CID
);
7594 // Find where the command is. Because this is randomly specified by firmware.
7595 if ((CID
& CID0MASK
) == Command
)
7597 ThisCIDMask
= CID0MASK
;
7600 else if ((((CID
& CID1MASK
)>>8) & 0xff) == Command
)
7602 ThisCIDMask
= CID1MASK
;
7605 else if ((((CID
& CID2MASK
)>>16) & 0xff) == Command
)
7607 ThisCIDMask
= CID2MASK
;
7610 else if ((((CID
& CID3MASK
)>>24) & 0xff) == Command
)
7612 ThisCIDMask
= CID3MASK
;
7620 // Get CommandStatus Value
7621 RTMP_IO_READ32(pAd
, H2M_MAILBOX_STATUS
, &CmdStatus
);
7623 // This command's status is at the same position as command. So AND command position's bitmask to read status.
7626 // If Status is 1, the comamnd is success.
7627 if (((CmdStatus
& ThisCIDMask
) == 0x1) || ((CmdStatus
& ThisCIDMask
) == 0x100)
7628 || ((CmdStatus
& ThisCIDMask
) == 0x10000) || ((CmdStatus
& ThisCIDMask
) == 0x1000000))
7630 DBGPRINT(RT_DEBUG_TRACE
, ("--> AsicCheckCommanOk CID = 0x%x, CmdStatus= 0x%x \n", CID
, CmdStatus
));
7631 RTMP_IO_WRITE32(pAd
, H2M_MAILBOX_STATUS
, 0xffffffff);
7632 RTMP_IO_WRITE32(pAd
, H2M_MAILBOX_CID
, 0xffffffff);
7635 DBGPRINT(RT_DEBUG_TRACE
, ("--> AsicCheckCommanFail1 CID = 0x%x, CmdStatus= 0x%x \n", CID
, CmdStatus
));
7639 DBGPRINT(RT_DEBUG_TRACE
, ("--> AsicCheckCommanFail2 Timeout Command = %d, CmdStatus= 0x%x \n", Command
, CmdStatus
));
7641 // Clear Command and Status.
7642 RTMP_IO_WRITE32(pAd
, H2M_MAILBOX_STATUS
, 0xffffffff);
7643 RTMP_IO_WRITE32(pAd
, H2M_MAILBOX_CID
, 0xffffffff);
7650 ========================================================================
7652 Routine Description:
7653 Verify the support rate for different PHY type
7656 pAd Pointer to our adapter
7661 IRQL = PASSIVE_LEVEL
7663 ========================================================================
7665 VOID
RTMPCheckRates(
7666 IN PRTMP_ADAPTER pAd
,
7667 IN OUT UCHAR SupRate
[],
7668 IN OUT UCHAR
*SupRateLen
)
7670 UCHAR RateIdx
, i
, j
;
7671 UCHAR NewRate
[12], NewRateLen
;
7675 if (pAd
->CommonCfg
.PhyMode
== PHY_11B
)
7680 // Check for support rates exclude basic rate bit
7681 for (i
= 0; i
< *SupRateLen
; i
++)
7682 for (j
= 0; j
< RateIdx
; j
++)
7683 if ((SupRate
[i
] & 0x7f) == RateIdTo500Kbps
[j
])
7684 NewRate
[NewRateLen
++] = SupRate
[i
];
7686 *SupRateLen
= NewRateLen
;
7687 NdisMoveMemory(SupRate
, NewRate
, NewRateLen
);
7690 BOOLEAN
RTMPCheckChannel(
7691 IN PRTMP_ADAPTER pAd
,
7692 IN UCHAR CentralChannel
,
7696 UCHAR UpperChannel
= 0, LowerChannel
= 0;
7697 UCHAR NoEffectChannelinList
= 0;
7699 // Find upper and lower channel according to 40MHz current operation.
7700 if (CentralChannel
< Channel
)
7702 UpperChannel
= Channel
;
7703 if (CentralChannel
> 2)
7704 LowerChannel
= CentralChannel
- 2;
7708 else if (CentralChannel
> Channel
)
7710 UpperChannel
= CentralChannel
+ 2;
7711 LowerChannel
= Channel
;
7714 for (k
= 0;k
< pAd
->ChannelListNum
;k
++)
7716 if (pAd
->ChannelList
[k
].Channel
== UpperChannel
)
7718 NoEffectChannelinList
++;
7720 if (pAd
->ChannelList
[k
].Channel
== LowerChannel
)
7722 NoEffectChannelinList
++;
7726 DBGPRINT(RT_DEBUG_TRACE
,("Total Channel in Channel List = [%d]\n", NoEffectChannelinList
));
7727 if (NoEffectChannelinList
== 2)
7734 ========================================================================
7736 Routine Description:
7737 Verify the support rate for HT phy type
7740 pAd Pointer to our adapter
7743 FALSE if pAd->CommonCfg.SupportedHtPhy doesn't accept the pHtCapability. (AP Mode)
7745 IRQL = PASSIVE_LEVEL
7747 ========================================================================
7749 BOOLEAN
RTMPCheckHt(
7750 IN PRTMP_ADAPTER pAd
,
7752 IN HT_CAPABILITY_IE
*pHtCapability
,
7753 IN ADD_HT_INFO_IE
*pAddHtInfo
)
7755 if (Wcid
>= MAX_LEN_OF_MAC_TABLE
)
7758 // If use AMSDU, set flag.
7759 if (pAd
->CommonCfg
.DesiredHtPhy
.AmsduEnable
)
7760 CLIENT_STATUS_SET_FLAG(&pAd
->MacTab
.Content
[Wcid
], fCLIENT_STATUS_AMSDU_INUSED
);
7761 // Save Peer Capability
7762 if (pHtCapability
->HtCapInfo
.ShortGIfor20
)
7763 CLIENT_STATUS_SET_FLAG(&pAd
->MacTab
.Content
[Wcid
], fCLIENT_STATUS_SGI20_CAPABLE
);
7764 if (pHtCapability
->HtCapInfo
.ShortGIfor40
)
7765 CLIENT_STATUS_SET_FLAG(&pAd
->MacTab
.Content
[Wcid
], fCLIENT_STATUS_SGI40_CAPABLE
);
7766 if (pHtCapability
->HtCapInfo
.TxSTBC
)
7767 CLIENT_STATUS_SET_FLAG(&pAd
->MacTab
.Content
[Wcid
], fCLIENT_STATUS_TxSTBC_CAPABLE
);
7768 if (pHtCapability
->HtCapInfo
.RxSTBC
)
7769 CLIENT_STATUS_SET_FLAG(&pAd
->MacTab
.Content
[Wcid
], fCLIENT_STATUS_RxSTBC_CAPABLE
);
7770 if (pAd
->CommonCfg
.bRdg
&& pHtCapability
->ExtHtCapInfo
.RDGSupport
)
7772 CLIENT_STATUS_SET_FLAG(&pAd
->MacTab
.Content
[Wcid
], fCLIENT_STATUS_RDG_CAPABLE
);
7775 if (Wcid
< MAX_LEN_OF_MAC_TABLE
)
7777 pAd
->MacTab
.Content
[Wcid
].MpduDensity
= pHtCapability
->HtCapParm
.MpduDensity
;
7780 // Will check ChannelWidth for MCSSet[4] below
7781 pAd
->MlmeAux
.HtCapability
.MCSSet
[4] = 0x1;
7782 switch (pAd
->CommonCfg
.RxStream
)
7785 pAd
->MlmeAux
.HtCapability
.MCSSet
[0] = 0xff;
7786 pAd
->MlmeAux
.HtCapability
.MCSSet
[1] = 0x00;
7787 pAd
->MlmeAux
.HtCapability
.MCSSet
[2] = 0x00;
7788 pAd
->MlmeAux
.HtCapability
.MCSSet
[3] = 0x00;
7791 pAd
->MlmeAux
.HtCapability
.MCSSet
[0] = 0xff;
7792 pAd
->MlmeAux
.HtCapability
.MCSSet
[1] = 0xff;
7793 pAd
->MlmeAux
.HtCapability
.MCSSet
[2] = 0x00;
7794 pAd
->MlmeAux
.HtCapability
.MCSSet
[3] = 0x00;
7797 pAd
->MlmeAux
.HtCapability
.MCSSet
[0] = 0xff;
7798 pAd
->MlmeAux
.HtCapability
.MCSSet
[1] = 0xff;
7799 pAd
->MlmeAux
.HtCapability
.MCSSet
[2] = 0xff;
7800 pAd
->MlmeAux
.HtCapability
.MCSSet
[3] = 0x00;
7804 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.ChannelWidth
= pAddHtInfo
->AddHtInfo
.RecomWidth
& pAd
->CommonCfg
.DesiredHtPhy
.ChannelWidth
;
7806 DBGPRINT(RT_DEBUG_TRACE
, ("RTMPCheckHt:: HtCapInfo.ChannelWidth=%d, RecomWidth=%d, DesiredHtPhy.ChannelWidth=%d, BW40MAvailForA/G=%d/%d, PhyMode=%d \n",
7807 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.ChannelWidth
, pAddHtInfo
->AddHtInfo
.RecomWidth
, pAd
->CommonCfg
.DesiredHtPhy
.ChannelWidth
,
7808 pAd
->NicConfig2
.field
.BW40MAvailForA
, pAd
->NicConfig2
.field
.BW40MAvailForG
, pAd
->CommonCfg
.PhyMode
));
7810 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.GF
= pHtCapability
->HtCapInfo
.GF
&pAd
->CommonCfg
.DesiredHtPhy
.GF
;
7812 // Send Assoc Req with my HT capability.
7813 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.AMsduSize
= pAd
->CommonCfg
.DesiredHtPhy
.AmsduSize
;
7814 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.MimoPs
= pAd
->CommonCfg
.DesiredHtPhy
.MimoPs
;
7815 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.ShortGIfor20
= (pAd
->CommonCfg
.DesiredHtPhy
.ShortGIfor20
) & (pHtCapability
->HtCapInfo
.ShortGIfor20
);
7816 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.ShortGIfor40
= (pAd
->CommonCfg
.DesiredHtPhy
.ShortGIfor40
) & (pHtCapability
->HtCapInfo
.ShortGIfor40
);
7817 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.TxSTBC
= (pAd
->CommonCfg
.DesiredHtPhy
.TxSTBC
)&(pHtCapability
->HtCapInfo
.RxSTBC
);
7818 pAd
->MlmeAux
.HtCapability
.HtCapInfo
.RxSTBC
= (pAd
->CommonCfg
.DesiredHtPhy
.RxSTBC
)&(pHtCapability
->HtCapInfo
.TxSTBC
);
7819 pAd
->MlmeAux
.HtCapability
.HtCapParm
.MaxRAmpduFactor
= pAd
->CommonCfg
.DesiredHtPhy
.MaxRAmpduFactor
;
7820 pAd
->MlmeAux
.HtCapability
.HtCapParm
.MpduDensity
= pAd
->CommonCfg
.HtCapability
.HtCapParm
.MpduDensity
;
7821 pAd
->MlmeAux
.HtCapability
.ExtHtCapInfo
.PlusHTC
= pHtCapability
->ExtHtCapInfo
.PlusHTC
;
7822 pAd
->MacTab
.Content
[Wcid
].HTCapability
.ExtHtCapInfo
.PlusHTC
= pHtCapability
->ExtHtCapInfo
.PlusHTC
;
7823 if (pAd
->CommonCfg
.bRdg
)
7825 pAd
->MlmeAux
.HtCapability
.ExtHtCapInfo
.RDGSupport
= pHtCapability
->ExtHtCapInfo
.RDGSupport
;
7826 pAd
->MlmeAux
.HtCapability
.ExtHtCapInfo
.PlusHTC
= 1;
7829 if (pAd
->MlmeAux
.HtCapability
.HtCapInfo
.ChannelWidth
== BW_20
)
7830 pAd
->MlmeAux
.HtCapability
.MCSSet
[4] = 0x0; // BW20 can't transmit MCS32
7832 COPY_AP_HTSETTINGS_FROM_BEACON(pAd
, pHtCapability
);
7837 ========================================================================
7839 Routine Description:
7840 Verify the support rate for different PHY type
7843 pAd Pointer to our adapter
7848 IRQL = PASSIVE_LEVEL
7850 ========================================================================
7852 VOID
RTMPUpdateMlmeRate(
7853 IN PRTMP_ADAPTER pAd
)
7856 UCHAR ProperMlmeRate
; //= RATE_54;
7857 UCHAR i
, j
, RateIdx
= 12; //1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
7858 BOOLEAN bMatch
= FALSE
;
7860 switch (pAd
->CommonCfg
.PhyMode
)
7863 ProperMlmeRate
= RATE_11
;
7864 MinimumRate
= RATE_1
;
7866 case PHY_11BG_MIXED
:
7867 case PHY_11ABGN_MIXED
:
7868 case PHY_11BGN_MIXED
:
7869 if ((pAd
->MlmeAux
.SupRateLen
== 4) &&
7870 (pAd
->MlmeAux
.ExtRateLen
== 0))
7872 ProperMlmeRate
= RATE_11
;
7874 ProperMlmeRate
= RATE_24
;
7876 if (pAd
->MlmeAux
.Channel
<= 14)
7877 MinimumRate
= RATE_1
;
7879 MinimumRate
= RATE_6
;
7882 case PHY_11N_2_4G
: // rt2860 need to check mlmerate for 802.11n
7883 case PHY_11GN_MIXED
:
7884 case PHY_11AGN_MIXED
:
7885 case PHY_11AN_MIXED
:
7887 ProperMlmeRate
= RATE_24
;
7888 MinimumRate
= RATE_6
;
7890 case PHY_11ABG_MIXED
:
7891 ProperMlmeRate
= RATE_24
;
7892 if (pAd
->MlmeAux
.Channel
<= 14)
7893 MinimumRate
= RATE_1
;
7895 MinimumRate
= RATE_6
;
7898 ProperMlmeRate
= RATE_1
;
7899 MinimumRate
= RATE_1
;
7903 for (i
= 0; i
< pAd
->MlmeAux
.SupRateLen
; i
++)
7905 for (j
= 0; j
< RateIdx
; j
++)
7907 if ((pAd
->MlmeAux
.SupRate
[i
] & 0x7f) == RateIdTo500Kbps
[j
])
7909 if (j
== ProperMlmeRate
)
7921 if (bMatch
== FALSE
)
7923 for (i
= 0; i
< pAd
->MlmeAux
.ExtRateLen
; i
++)
7925 for (j
= 0; j
< RateIdx
; j
++)
7927 if ((pAd
->MlmeAux
.ExtRate
[i
] & 0x7f) == RateIdTo500Kbps
[j
])
7929 if (j
== ProperMlmeRate
)
7942 if (bMatch
== FALSE
)
7944 ProperMlmeRate
= MinimumRate
;
7947 pAd
->CommonCfg
.MlmeRate
= MinimumRate
;
7948 pAd
->CommonCfg
.RtsRate
= ProperMlmeRate
;
7949 if (pAd
->CommonCfg
.MlmeRate
>= RATE_6
)
7951 pAd
->CommonCfg
.MlmeTransmit
.field
.MODE
= MODE_OFDM
;
7952 pAd
->CommonCfg
.MlmeTransmit
.field
.MCS
= OfdmRateToRxwiMCS
[pAd
->CommonCfg
.MlmeRate
];
7953 pAd
->MacTab
.Content
[BSS0Mcast_WCID
].HTPhyMode
.field
.MODE
= MODE_OFDM
;
7954 pAd
->MacTab
.Content
[BSS0Mcast_WCID
].HTPhyMode
.field
.MCS
= OfdmRateToRxwiMCS
[pAd
->CommonCfg
.MlmeRate
];
7958 pAd
->CommonCfg
.MlmeTransmit
.field
.MODE
= MODE_CCK
;
7959 pAd
->CommonCfg
.MlmeTransmit
.field
.MCS
= pAd
->CommonCfg
.MlmeRate
;
7960 pAd
->MacTab
.Content
[BSS0Mcast_WCID
].HTPhyMode
.field
.MODE
= MODE_CCK
;
7961 pAd
->MacTab
.Content
[BSS0Mcast_WCID
].HTPhyMode
.field
.MCS
= pAd
->CommonCfg
.MlmeRate
;
7964 DBGPRINT(RT_DEBUG_TRACE
, ("RTMPUpdateMlmeRate ==> MlmeTransmit = 0x%x \n" , pAd
->CommonCfg
.MlmeTransmit
.word
));
7968 IN PRTMP_ADAPTER pAd
,
7975 if ((pAd
->Antenna
.field
.RxPath
== 1) && (Rssi0
!= 0))
7980 if ((pAd
->Antenna
.field
.RxPath
>= 2) && (Rssi1
!= 0))
7982 larger
= max(Rssi0
, Rssi1
);
7985 if ((pAd
->Antenna
.field
.RxPath
== 3) && (Rssi2
!= 0))
7987 larger
= max(larger
, Rssi2
);
7997 // Antenna divesity use GPIO3 and EESK pin for control
7998 // Antenna and EEPROM access are both using EESK pin,
7999 // Therefor we should avoid accessing EESK at the same time
8000 // Then restore antenna after EEPROM access
8002 IN PRTMP_ADAPTER pAd
,
8008 if ((pAd
->EepromAccess
) ||
8009 (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_RESET_IN_PROGRESS
)) ||
8010 (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
)) ||
8011 (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_RADIO_OFF
)) ||
8012 (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
)))
8017 // the antenna selection is through firmware and MAC register(GPIO3)
8021 RTMP_IO_READ32(pAd
, E2PROM_CSR
, &x
);
8023 RTMP_IO_WRITE32(pAd
, E2PROM_CSR
, x
);
8025 RTMP_IO_READ32(pAd
, GPIO_CTRL_CFG
, &Value
);
8027 RTMP_IO_WRITE32(pAd
, GPIO_CTRL_CFG
, Value
);
8028 DBGPRINT_RAW(RT_DEBUG_TRACE
, ("AsicSetRxAnt, switch to main antenna\n"));
8033 RTMP_IO_READ32(pAd
, E2PROM_CSR
, &x
);
8035 RTMP_IO_WRITE32(pAd
, E2PROM_CSR
, x
);
8037 RTMP_IO_READ32(pAd
, GPIO_CTRL_CFG
, &Value
);
8040 RTMP_IO_WRITE32(pAd
, GPIO_CTRL_CFG
, Value
);
8041 DBGPRINT_RAW(RT_DEBUG_TRACE
, ("AsicSetRxAnt, switch to aux antenna\n"));
8047 ========================================================================
8048 Routine Description:
8049 Periodic evaluate antenna link status
8052 pAd - Adapter pointer
8057 ========================================================================
8059 VOID
AsicEvaluateRxAnt(
8060 IN PRTMP_ADAPTER pAd
)
8064 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_RESET_IN_PROGRESS
|
8065 fRTMP_ADAPTER_HALT_IN_PROGRESS
|
8066 fRTMP_ADAPTER_RADIO_OFF
|
8067 fRTMP_ADAPTER_NIC_NOT_EXIST
|
8068 fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS
)
8069 || OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_DOZE
)
8071 || (pAd
->EepromAccess
)
8077 // two antenna selection mechanism- one is antenna diversity, the other is failed antenna remove
8078 // one is antenna diversity:there is only one antenna can rx and tx
8079 // the other is failed antenna remove:two physical antenna can rx and tx
8080 if (pAd
->NicConfig2
.field
.AntDiversity
)
8082 DBGPRINT(RT_DEBUG_TRACE
,("AntDiv - before evaluate Pair1-Ant (%d,%d)\n",
8083 pAd
->RxAnt
.Pair1PrimaryRxAnt
, pAd
->RxAnt
.Pair1SecondaryRxAnt
));
8085 AsicSetRxAnt(pAd
, pAd
->RxAnt
.Pair1SecondaryRxAnt
);
8087 pAd
->RxAnt
.EvaluatePeriod
= 1; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt
8088 pAd
->RxAnt
.FirstPktArrivedWhenEvaluate
= FALSE
;
8089 pAd
->RxAnt
.RcvPktNumWhenEvaluate
= 0;
8091 // a one-shot timer to end the evalution
8092 // dynamic adjust antenna evaluation period according to the traffic
8093 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
8094 RTMPSetTimer(&pAd
->Mlme
.RxAntEvalTimer
, 100);
8096 RTMPSetTimer(&pAd
->Mlme
.RxAntEvalTimer
, 300);
8101 if (pAd
->StaCfg
.Psm
== PWR_SAVE
)
8104 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R3
, &BBPR3
);
8106 if(pAd
->Antenna
.field
.RxPath
== 3)
8110 else if(pAd
->Antenna
.field
.RxPath
== 2)
8114 else if(pAd
->Antenna
.field
.RxPath
== 1)
8118 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R3
, BBPR3
);
8121 pAd
->StaCfg
.BBPR3
= BBPR3
;
8125 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
)
8128 ULONG TxTotalCnt
= pAd
->RalinkCounters
.OneSecTxNoRetryOkCount
+
8129 pAd
->RalinkCounters
.OneSecTxRetryOkCount
+
8130 pAd
->RalinkCounters
.OneSecTxFailCount
;
8132 // dynamic adjust antenna evaluation period according to the traffic
8133 if (TxTotalCnt
> 50)
8135 RTMPSetTimer(&pAd
->Mlme
.RxAntEvalTimer
, 20);
8136 pAd
->Mlme
.bLowThroughput
= FALSE
;
8140 RTMPSetTimer(&pAd
->Mlme
.RxAntEvalTimer
, 300);
8141 pAd
->Mlme
.bLowThroughput
= TRUE
;
8147 ========================================================================
8148 Routine Description:
8149 After evaluation, check antenna link status
8152 pAd - Adapter pointer
8157 ========================================================================
8159 VOID
AsicRxAntEvalTimeout(
8160 IN PVOID SystemSpecific1
,
8161 IN PVOID FunctionContext
,
8162 IN PVOID SystemSpecific2
,
8163 IN PVOID SystemSpecific3
)
8165 RTMP_ADAPTER
*pAd
= (RTMP_ADAPTER
*)FunctionContext
;
8167 CHAR larger
= -127, rssi0
, rssi1
, rssi2
;
8169 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_RESET_IN_PROGRESS
|
8170 fRTMP_ADAPTER_HALT_IN_PROGRESS
|
8171 fRTMP_ADAPTER_RADIO_OFF
|
8172 fRTMP_ADAPTER_NIC_NOT_EXIST
)
8173 || OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_DOZE
)
8175 || (pAd
->EepromAccess
)
8182 if (pAd
->NicConfig2
.field
.AntDiversity
)
8184 if ((pAd
->RxAnt
.RcvPktNumWhenEvaluate
!= 0) && (pAd
->RxAnt
.Pair1AvgRssi
[pAd
->RxAnt
.Pair1SecondaryRxAnt
] >= pAd
->RxAnt
.Pair1AvgRssi
[pAd
->RxAnt
.Pair1PrimaryRxAnt
]))
8189 // select PrimaryRxAntPair
8190 // Role change, Used Pair1SecondaryRxAnt as PrimaryRxAntPair.
8191 // Since Pair1SecondaryRxAnt Quality good than Pair1PrimaryRxAnt
8193 temp
= pAd
->RxAnt
.Pair1PrimaryRxAnt
;
8194 pAd
->RxAnt
.Pair1PrimaryRxAnt
= pAd
->RxAnt
.Pair1SecondaryRxAnt
;
8195 pAd
->RxAnt
.Pair1SecondaryRxAnt
= temp
;
8197 pAd
->RxAnt
.Pair1LastAvgRssi
= (pAd
->RxAnt
.Pair1AvgRssi
[pAd
->RxAnt
.Pair1SecondaryRxAnt
] >> 3);
8198 pAd
->RxAnt
.EvaluateStableCnt
= 0;
8202 // if the evaluated antenna is not better than original, switch back to original antenna
8203 AsicSetRxAnt(pAd
, pAd
->RxAnt
.Pair1PrimaryRxAnt
);
8204 pAd
->RxAnt
.EvaluateStableCnt
++;
8207 pAd
->RxAnt
.EvaluatePeriod
= 0; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt
8209 DBGPRINT(RT_DEBUG_TRACE
,("AsicRxAntEvalAction::After Eval(fix in #%d), <%d, %d>, RcvPktNumWhenEvaluate=%ld\n",
8210 pAd
->RxAnt
.Pair1PrimaryRxAnt
, (pAd
->RxAnt
.Pair1AvgRssi
[0] >> 3), (pAd
->RxAnt
.Pair1AvgRssi
[1] >> 3), pAd
->RxAnt
.RcvPktNumWhenEvaluate
));
8215 if (pAd
->StaCfg
.Psm
== PWR_SAVE
)
8218 // if the traffic is low, use average rssi as the criteria
8219 if (pAd
->Mlme
.bLowThroughput
== TRUE
)
8221 rssi0
= pAd
->StaCfg
.RssiSample
.LastRssi0
;
8222 rssi1
= pAd
->StaCfg
.RssiSample
.LastRssi1
;
8223 rssi2
= pAd
->StaCfg
.RssiSample
.LastRssi2
;
8227 rssi0
= pAd
->StaCfg
.RssiSample
.AvgRssi0
;
8228 rssi1
= pAd
->StaCfg
.RssiSample
.AvgRssi1
;
8229 rssi2
= pAd
->StaCfg
.RssiSample
.AvgRssi2
;
8232 if(pAd
->Antenna
.field
.RxPath
== 3)
8234 larger
= max(rssi0
, rssi1
);
8236 if (larger
> (rssi2
+ 20))
8237 pAd
->Mlme
.RealRxPath
= 2;
8239 pAd
->Mlme
.RealRxPath
= 3;
8241 else if(pAd
->Antenna
.field
.RxPath
== 2)
8243 if (rssi0
> (rssi1
+ 20))
8244 pAd
->Mlme
.RealRxPath
= 1;
8246 pAd
->Mlme
.RealRxPath
= 2;
8249 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R3
, &BBPR3
);
8251 if(pAd
->Mlme
.RealRxPath
== 3)
8255 else if(pAd
->Mlme
.RealRxPath
== 2)
8259 else if(pAd
->Mlme
.RealRxPath
== 1)
8263 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R3
, BBPR3
);
8265 pAd
->StaCfg
.BBPR3
= BBPR3
;
8271 VOID
APSDPeriodicExec(
8272 IN PVOID SystemSpecific1
,
8273 IN PVOID FunctionContext
,
8274 IN PVOID SystemSpecific2
,
8275 IN PVOID SystemSpecific3
)
8277 RTMP_ADAPTER
*pAd
= (RTMP_ADAPTER
*)FunctionContext
;
8279 if (!OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
))
8282 pAd
->CommonCfg
.TriggerTimerCount
++;
8287 ========================================================================
8288 Routine Description:
8289 Set/reset MAC registers according to bPiggyBack parameter
8292 pAd - Adapter pointer
8293 bPiggyBack - Enable / Disable Piggy-Back
8298 ========================================================================
8300 VOID
RTMPSetPiggyBack(
8301 IN PRTMP_ADAPTER pAd
,
8302 IN BOOLEAN bPiggyBack
)
8304 TX_LINK_CFG_STRUC TxLinkCfg
;
8306 RTMP_IO_READ32(pAd
, TX_LINK_CFG
, &TxLinkCfg
.word
);
8308 TxLinkCfg
.field
.TxCFAckEn
= bPiggyBack
;
8309 RTMP_IO_WRITE32(pAd
, TX_LINK_CFG
, TxLinkCfg
.word
);
8313 ========================================================================
8314 Routine Description:
8315 check if this entry need to switch rate automatically
8325 ========================================================================
8327 BOOLEAN
RTMPCheckEntryEnableAutoRateSwitch(
8328 IN PRTMP_ADAPTER pAd
,
8329 IN PMAC_TABLE_ENTRY pEntry
)
8331 BOOLEAN result
= TRUE
;
8334 // only associated STA counts
8335 if (pEntry
&& (pEntry
->ValidAsCLI
) && (pEntry
->Sst
== SST_ASSOC
))
8337 result
= pAd
->StaCfg
.bAutoTxRateSwitch
;
8347 BOOLEAN
RTMPAutoRateSwitchCheck(
8348 IN PRTMP_ADAPTER pAd
)
8350 if (pAd
->StaCfg
.bAutoTxRateSwitch
)
8358 ========================================================================
8359 Routine Description:
8360 check if this entry need to fix tx legacy rate
8370 ========================================================================
8372 UCHAR
RTMPStaFixedTxMode(
8373 IN PRTMP_ADAPTER pAd
,
8374 IN PMAC_TABLE_ENTRY pEntry
)
8376 UCHAR tx_mode
= FIXED_TXMODE_HT
;
8378 tx_mode
= (UCHAR
)pAd
->StaCfg
.DesiredTransmitSetting
.field
.FixedTxMode
;
8384 ========================================================================
8385 Routine Description:
8386 Overwrite HT Tx Mode by Fixed Legency Tx Mode, if specified.
8396 ========================================================================
8398 VOID
RTMPUpdateLegacyTxSetting(
8399 UCHAR fixed_tx_mode
,
8400 PMAC_TABLE_ENTRY pEntry
)
8402 HTTRANSMIT_SETTING TransmitSetting
;
8404 if (fixed_tx_mode
== FIXED_TXMODE_HT
)
8407 TransmitSetting
.word
= 0;
8409 TransmitSetting
.field
.MODE
= pEntry
->HTPhyMode
.field
.MODE
;
8410 TransmitSetting
.field
.MCS
= pEntry
->HTPhyMode
.field
.MCS
;
8412 if (fixed_tx_mode
== FIXED_TXMODE_CCK
)
8414 TransmitSetting
.field
.MODE
= MODE_CCK
;
8415 // CCK mode allow MCS 0~3
8416 if (TransmitSetting
.field
.MCS
> MCS_3
)
8417 TransmitSetting
.field
.MCS
= MCS_3
;
8421 TransmitSetting
.field
.MODE
= MODE_OFDM
;
8422 // OFDM mode allow MCS 0~7
8423 if (TransmitSetting
.field
.MCS
> MCS_7
)
8424 TransmitSetting
.field
.MCS
= MCS_7
;
8427 if (pEntry
->HTPhyMode
.field
.MODE
>= TransmitSetting
.field
.MODE
)
8429 pEntry
->HTPhyMode
.word
= TransmitSetting
.word
;
8430 DBGPRINT(RT_DEBUG_TRACE
, ("RTMPUpdateLegacyTxSetting : wcid-%d, MODE=%s, MCS=%d \n",
8431 pEntry
->Aid
, GetPhyMode(pEntry
->HTPhyMode
.field
.MODE
), pEntry
->HTPhyMode
.field
.MCS
));
8436 ==========================================================================
8438 dynamic tune BBP R66 to find a balance between sensibility and
8441 IRQL = DISPATCH_LEVEL
8443 ==========================================================================
8445 VOID
AsicStaBbpTuning(
8446 IN PRTMP_ADAPTER pAd
)
8448 UCHAR OrigR66Value
= 0, R66
;//, R66UpperBound = 0x30, R66LowerBound = 0x30;
8451 // 2860C did not support Fase CCA, therefore can't tune
8452 if (pAd
->MACVersion
== 0x28600100)
8458 if (pAd
->Mlme
.CntlMachine
.CurrState
!= CNTL_IDLE
) // no R66 tuning when SCANNING
8461 if ((pAd
->OpMode
== OPMODE_STA
)
8462 && (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_MEDIA_STATE_CONNECTED
)
8464 && !(OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_DOZE
))
8466 && (pAd
->bPCIclkOff
== FALSE
))
8472 RTMP_BBP_IO_READ8_BY_REG_ID(pAd
, BBP_R66
, &OrigR66Value
);
8475 if (pAd
->Antenna
.field
.RxPath
> 1)
8476 Rssi
= (pAd
->StaCfg
.RssiSample
.AvgRssi0
+ pAd
->StaCfg
.RssiSample
.AvgRssi1
) >> 1;
8478 Rssi
= pAd
->StaCfg
.RssiSample
.AvgRssi0
;
8480 if (pAd
->LatchRfRegs
.Channel
<= 14)
8483 // RT3070 is a no LNA solution, it should have different control regarding to AGC gain control
8484 // Otherwise, it will have some throughput side effect when low RSSI
8487 if (Rssi
> RSSI_FOR_MID_LOW_SENSIBILITY
)
8489 R66
= 0x1C + 2*GET_LNA_GAIN(pAd
) + 0x20;
8490 if (OrigR66Value
!= R66
)
8491 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8495 R66
= 0x1C + 2*GET_LNA_GAIN(pAd
);
8496 if (OrigR66Value
!= R66
)
8497 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8503 if (Rssi
> RSSI_FOR_MID_LOW_SENSIBILITY
)
8505 R66
= (0x2E + GET_LNA_GAIN(pAd
)) + 0x10;
8506 if (OrigR66Value
!= R66
)
8508 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8513 R66
= 0x2E + GET_LNA_GAIN(pAd
);
8514 if (OrigR66Value
!= R66
)
8516 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8523 if (pAd
->CommonCfg
.BBPCurrentBW
== BW_20
)
8525 if (Rssi
> RSSI_FOR_MID_LOW_SENSIBILITY
)
8527 R66
= 0x32 + (GET_LNA_GAIN(pAd
)*5)/3 + 0x10;
8528 if (OrigR66Value
!= R66
)
8530 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8535 R66
= 0x32 + (GET_LNA_GAIN(pAd
)*5)/3;
8536 if (OrigR66Value
!= R66
)
8538 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8544 if (Rssi
> RSSI_FOR_MID_LOW_SENSIBILITY
)
8546 R66
= 0x3A + (GET_LNA_GAIN(pAd
)*5)/3 + 0x10;
8547 if (OrigR66Value
!= R66
)
8549 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8554 R66
= 0x3A + (GET_LNA_GAIN(pAd
)*5)/3;
8555 if (OrigR66Value
!= R66
)
8557 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8568 VOID
AsicResetFromDMABusy(
8569 IN PRTMP_ADAPTER pAd
)
8572 BOOLEAN bCtrl
= FALSE
;
8574 DBGPRINT(RT_DEBUG_TRACE
, ("---> AsicResetFromDMABusy !!!!!!!!!!!!!!!!!!!!!!! \n"));
8576 // Be sure restore link control value so we can write register.
8577 RTMP_CLEAR_PSFLAG(pAd
, fRTMP_PS_CAN_GO_SLEEP
);
8578 if (RTMP_TEST_PSFLAG(pAd
, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND
))
8580 DBGPRINT(RT_DEBUG_TRACE
,("AsicResetFromDMABusy==>\n"));
8581 RTMPPCIeLinkCtrlValueRestore(pAd
, RESTORE_HALT
);
8582 RTMPusecDelay(6000);
8583 pAd
->bPCIclkOff
= FALSE
;
8587 RTMP_IO_READ32(pAd
, PBF_SYS_CTRL
, &Data
);
8589 RTMP_IO_WRITE32(pAd
, PBF_SYS_CTRL
, Data
);
8591 // After Reset DMA, DMA index will become Zero. So Driver need to reset all ring indexs too.
8592 // Reset DMA/CPU ring index
8593 RTMPRingCleanUp(pAd
, QID_AC_BK
);
8594 RTMPRingCleanUp(pAd
, QID_AC_BE
);
8595 RTMPRingCleanUp(pAd
, QID_AC_VI
);
8596 RTMPRingCleanUp(pAd
, QID_AC_VO
);
8597 RTMPRingCleanUp(pAd
, QID_HCCA
);
8598 RTMPRingCleanUp(pAd
, QID_MGMT
);
8599 RTMPRingCleanUp(pAd
, QID_RX
);
8602 RTMP_IO_READ32(pAd
, PBF_SYS_CTRL
, &Data
);
8604 RTMP_IO_WRITE32(pAd
, PBF_SYS_CTRL
, Data
);
8606 // If in Radio off, should call RTMPPCIePowerLinkCtrl again.
8607 if ((bCtrl
== TRUE
) && (pAd
->StaCfg
.bRadio
== FALSE
))
8608 RTMPPCIeLinkCtrlSetting(pAd
, 3);
8610 RTMP_SET_PSFLAG(pAd
, fRTMP_PS_CAN_GO_SLEEP
);
8611 RTMP_CLEAR_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
| fRTMP_ADAPTER_HALT_IN_PROGRESS
);
8612 DBGPRINT(RT_DEBUG_TRACE
, ("<--- AsicResetFromDMABusy !!!!!!!!!!!!!!!!!!!!!!! \n"));
8616 IN PRTMP_ADAPTER pAd
)
8618 DBGPRINT(RT_DEBUG_TRACE
, ("---> Asic HardReset BBP !!!!!!!!!!!!!!!!!!!!!!! \n"));
8620 RTMP_IO_WRITE32(pAd
, MAC_SYS_CTRL
, 0x0);
8621 RTMP_IO_WRITE32(pAd
, MAC_SYS_CTRL
, 0x2);
8622 RTMP_IO_WRITE32(pAd
, MAC_SYS_CTRL
, 0xc);
8624 // After hard-reset BBP, initialize all BBP values.
8625 NICRestoreBBPValue(pAd
);
8626 DBGPRINT(RT_DEBUG_TRACE
, ("<--- Asic HardReset BBP !!!!!!!!!!!!!!!!!!!!!!! \n"));
8630 IN PRTMP_ADAPTER pAd
)
8634 DBGPRINT(RT_DEBUG_TRACE
, ("---> AsicResetMAC !!!! \n"));
8635 RTMP_IO_READ32(pAd
, PBF_SYS_CTRL
, &Data
);
8637 RTMP_IO_WRITE32(pAd
, PBF_SYS_CTRL
, Data
);
8639 RTMP_IO_WRITE32(pAd
, PBF_SYS_CTRL
, Data
);
8641 DBGPRINT(RT_DEBUG_TRACE
, ("<--- AsicResetMAC !!!! \n"));
8645 IN PRTMP_ADAPTER pAd
)
8647 ULONG Value1
, Value2
;
8650 RTMP_IO_READ32(pAd
, TXRXQ_PCNT
, &Value1
);
8651 RTMP_IO_READ32(pAd
, PBF_DBG
, &Value2
);
8654 // sum should be equals to 0xff, which is the total buffer size.
8655 if ((Value1
+ Value2
) < 0xff)
8657 DBGPRINT(RT_DEBUG_TRACE
, ("---> Asic HardReset PBF !!!! \n"));
8658 RTMP_IO_READ32(pAd
, PBF_SYS_CTRL
, &Data
);
8660 RTMP_IO_WRITE32(pAd
, PBF_SYS_CTRL
, Data
);
8662 RTMP_IO_WRITE32(pAd
, PBF_SYS_CTRL
, Data
);
8664 DBGPRINT(RT_DEBUG_TRACE
, ("<--- Asic HardReset PBF !!!! \n"));
8669 VOID
RTMPSetAGCInitValue(
8670 IN PRTMP_ADAPTER pAd
,
8675 if (pAd
->LatchRfRegs
.Channel
<= 14)
8677 R66
= 0x2E + GET_LNA_GAIN(pAd
);
8678 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8682 if (BandWidth
== BW_20
)
8684 R66
= (UCHAR
)(0x32 + (GET_LNA_GAIN(pAd
)*5)/3);
8685 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8689 R66
= (UCHAR
)(0x3A + (GET_LNA_GAIN(pAd
)*5)/3);
8690 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd
, BBP_R66
, R66
);
8696 VOID
AsicTurnOffRFClk(
8697 IN PRTMP_ADAPTER pAd
,
8702 UINT32 R1
= 0, R2
= 0, R3
= 0;
8704 RTMP_RF_REGS
*RFRegTable
;
8706 // The RF programming sequence is difference between 3xxx and 2xxx
8709 RT30xxLoadRFSleepModeSetup(pAd
); // add by johnli, RF power sequence setup, load RF sleep-mode setup
8713 RFRegTable
= RF2850RegTable
;
8715 switch (pAd
->RfIcType
)
8722 for (index
= 0; index
< NUM_OF_2850_CHNL
; index
++)
8724 if (Channel
== RFRegTable
[index
].Channel
)
8726 R1
= RFRegTable
[index
].R1
& 0xffffdfff;
8727 R2
= RFRegTable
[index
].R2
& 0xfffbffff;
8728 R3
= RFRegTable
[index
].R3
& 0xfff3ffff;
8730 RTMP_RF_IO_WRITE32(pAd
, R1
);
8731 RTMP_RF_IO_WRITE32(pAd
, R2
);
8733 // Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0.
8734 // Set RF R2 bit18=0, R3 bit[18:19]=0
8735 //if (pAd->StaCfg.bRadio == FALSE)
8738 RTMP_RF_IO_WRITE32(pAd
, R3
);
8740 DBGPRINT(RT_DEBUG_TRACE
, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x, R3 = 0x%08x \n",
8741 Channel
, pAd
->RfIcType
, R2
, R3
));
8744 DBGPRINT(RT_DEBUG_TRACE
, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n",
8745 Channel
, pAd
->RfIcType
, R2
));
8757 VOID
AsicTurnOnRFClk(
8758 IN PRTMP_ADAPTER pAd
,
8763 UINT32 R1
= 0, R2
= 0, R3
= 0;
8765 RTMP_RF_REGS
*RFRegTable
;
8767 // The RF programming sequence is difference between 3xxx and 2xxx
8771 RFRegTable
= RF2850RegTable
;
8773 switch (pAd
->RfIcType
)
8780 for (index
= 0; index
< NUM_OF_2850_CHNL
; index
++)
8782 if (Channel
== RFRegTable
[index
].Channel
)
8784 R3
= pAd
->LatchRfRegs
.R3
;
8787 RTMP_RF_IO_WRITE32(pAd
, R3
);
8789 R1
= RFRegTable
[index
].R1
;
8790 RTMP_RF_IO_WRITE32(pAd
, R1
);
8792 R2
= RFRegTable
[index
].R2
;
8793 if (pAd
->Antenna
.field
.TxPath
== 1)
8795 R2
|= 0x4000; // If TXpath is 1, bit 14 = 1;
8798 if (pAd
->Antenna
.field
.RxPath
== 2)
8800 R2
|= 0x40; // write 1 to off Rxpath.
8802 else if (pAd
->Antenna
.field
.RxPath
== 1)
8804 R2
|= 0x20040; // write 1 to off RxPath
8806 RTMP_RF_IO_WRITE32(pAd
, R2
);
8817 DBGPRINT(RT_DEBUG_TRACE
, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n",