c9be8898020b9e62941b3923af2c01fadf9a1d0f
[safe/jmp/linux-2.6] / drivers / staging / rt2860 / common / mlme.c
1 /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
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.                                   *
14  *                                                                       *
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.                          *
19  *                                                                       *
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.             *
24  *                                                                       *
25  *************************************************************************
26
27         Module Name:
28         mlme.c
29
30         Abstract:
31
32         Revision History:
33         Who                     When                    What
34         --------        ----------              ----------------------------------------------
35         John Chang      2004-08-25              Modify from RT2500 code base
36         John Chang      2004-09-06              modified for RT2600
37 */
38
39 #include "../rt_config.h"
40 #include <stdarg.h>
41
42 UCHAR   CISCO_OUI[] = {0x00, 0x40, 0x96};
43
44 UCHAR   WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
45 UCHAR   RSN_OUI[] = {0x00, 0x0f, 0xac};
46 UCHAR   WAPI_OUI[] = {0x00, 0x14, 0x72};
47 UCHAR   WME_INFO_ELEM[]  = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
48 UCHAR   WME_PARM_ELEM[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
49 UCHAR   Ccx2QosInfo[] = {0x00, 0x40, 0x96, 0x04};
50 UCHAR   RALINK_OUI[]  = {0x00, 0x0c, 0x43};
51 UCHAR   BROADCOM_OUI[]  = {0x00, 0x90, 0x4c};
52 UCHAR   WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
53 UCHAR   PRE_N_HT_OUI[]  = {0x00, 0x90, 0x4c};
54
55 UCHAR RateSwitchTable[] = {
56 // 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)
57     0x11, 0x00,  0,  0,  0,                                             // Initial used item after association
58     0x00, 0x00,  0, 40, 101,
59     0x01, 0x00,  1, 40, 50,
60     0x02, 0x00,  2, 35, 45,
61     0x03, 0x00,  3, 20, 45,
62     0x04, 0x21,  0, 30, 50,
63     0x05, 0x21,  1, 20, 50,
64     0x06, 0x21,  2, 20, 50,
65     0x07, 0x21,  3, 15, 50,
66     0x08, 0x21,  4, 15, 30,
67     0x09, 0x21,  5, 10, 25,
68     0x0a, 0x21,  6,  8, 25,
69     0x0b, 0x21,  7,  8, 25,
70     0x0c, 0x20, 12,  15, 30,
71     0x0d, 0x20, 13,  8, 20,
72     0x0e, 0x20, 14,  8, 20,
73     0x0f, 0x20, 15,  8, 25,
74     0x10, 0x22, 15,  8, 25,
75     0x11, 0x00,  0,  0,  0,
76     0x12, 0x00,  0,  0,  0,
77     0x13, 0x00,  0,  0,  0,
78     0x14, 0x00,  0,  0,  0,
79     0x15, 0x00,  0,  0,  0,
80     0x16, 0x00,  0,  0,  0,
81     0x17, 0x00,  0,  0,  0,
82     0x18, 0x00,  0,  0,  0,
83     0x19, 0x00,  0,  0,  0,
84     0x1a, 0x00,  0,  0,  0,
85     0x1b, 0x00,  0,  0,  0,
86     0x1c, 0x00,  0,  0,  0,
87     0x1d, 0x00,  0,  0,  0,
88     0x1e, 0x00,  0,  0,  0,
89     0x1f, 0x00,  0,  0,  0,
90 };
91
92 UCHAR RateSwitchTable11B[] = {
93 // 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)
94     0x04, 0x03,  0,  0,  0,                                             // Initial used item after association
95     0x00, 0x00,  0, 40, 101,
96     0x01, 0x00,  1, 40, 50,
97     0x02, 0x00,  2, 35, 45,
98     0x03, 0x00,  3, 20, 45,
99 };
100
101 UCHAR RateSwitchTable11BG[] = {
102 // 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)
103     0x0a, 0x00,  0,  0,  0,                                             // Initial used item after association
104     0x00, 0x00,  0, 40, 101,
105     0x01, 0x00,  1, 40, 50,
106     0x02, 0x00,  2, 35, 45,
107     0x03, 0x00,  3, 20, 45,
108     0x04, 0x10,  2, 20, 35,
109     0x05, 0x10,  3, 16, 35,
110     0x06, 0x10,  4, 10, 25,
111     0x07, 0x10,  5, 16, 25,
112     0x08, 0x10,  6, 10, 25,
113     0x09, 0x10,  7, 10, 13,
114 };
115
116 UCHAR RateSwitchTable11G[] = {
117 // 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)
118     0x08, 0x00,  0,  0,  0,                                             // Initial used item after association
119     0x00, 0x10,  0, 20, 101,
120     0x01, 0x10,  1, 20, 35,
121     0x02, 0x10,  2, 20, 35,
122     0x03, 0x10,  3, 16, 35,
123     0x04, 0x10,  4, 10, 25,
124     0x05, 0x10,  5, 16, 25,
125     0x06, 0x10,  6, 10, 25,
126     0x07, 0x10,  7, 10, 13,
127 };
128
129 UCHAR RateSwitchTable11N1S[] = {
130 // 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)
131     0x09, 0x00,  0,  0,  0,                                             // Initial used item after association
132     0x00, 0x21,  0, 30, 101,
133     0x01, 0x21,  1, 20, 50,
134     0x02, 0x21,  2, 20, 50,
135     0x03, 0x21,  3, 15, 50,
136     0x04, 0x21,  4, 15, 30,
137     0x05, 0x21,  5, 10, 25,
138     0x06, 0x21,  6,  8, 14,
139     0x07, 0x21,  7,  8, 14,
140     0x08, 0x23,  7,  8, 14,
141 };
142
143 UCHAR RateSwitchTable11N2S[] = {
144 // 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)
145     0x0a, 0x00,  0,  0,  0,      // Initial used item after association
146     0x00, 0x21,  0, 30, 101,
147     0x01, 0x21,  1, 20, 50,
148     0x02, 0x21,  2, 20, 50,
149     0x03, 0x21,  3, 15, 50,
150     0x04, 0x21,  4, 15, 30,
151     0x05, 0x20, 12,  15, 30,
152     0x06, 0x20, 13,  8, 20,
153     0x07, 0x20, 14,  8, 20,
154     0x08, 0x20, 15,  8, 25,
155     0x09, 0x22, 15,  8, 25,
156 };
157
158 UCHAR RateSwitchTable11N3S[] = {
159 // 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)
160     0x0a, 0x00,  0,  0,  0,      // Initial used item after association
161     0x00, 0x21,  0, 30, 101,
162     0x01, 0x21,  1, 20, 50,
163     0x02, 0x21,  2, 20, 50,
164     0x03, 0x21,  3, 15, 50,
165     0x04, 0x21,  4, 15, 30,
166     0x05, 0x20, 12,  15, 30,
167     0x06, 0x20, 13,  8, 20,
168     0x07, 0x20, 14,  8, 20,
169     0x08, 0x20, 15,  8, 25,
170     0x09, 0x22, 15,  8, 25,
171 };
172
173 UCHAR RateSwitchTable11N2SForABand[] = {
174 // 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)
175     0x0b, 0x09,  0,  0,  0,                                             // Initial used item after association
176     0x00, 0x21,  0, 30, 101,
177     0x01, 0x21,  1, 20, 50,
178     0x02, 0x21,  2, 20, 50,
179     0x03, 0x21,  3, 15, 50,
180     0x04, 0x21,  4, 15, 30,
181     0x05, 0x21,  5, 15, 30,
182     0x06, 0x20, 12,  15, 30,
183     0x07, 0x20, 13,  8, 20,
184     0x08, 0x20, 14,  8, 20,
185     0x09, 0x20, 15,  8, 25,
186     0x0a, 0x22, 15,  8, 25,
187 };
188
189 UCHAR RateSwitchTable11N3SForABand[] = { // 3*3
190 // 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)
191     0x0b, 0x09,  0,  0,  0,                                             // Initial used item after association
192     0x00, 0x21,  0, 30, 101,
193     0x01, 0x21,  1, 20, 50,
194     0x02, 0x21,  2, 20, 50,
195     0x03, 0x21,  3, 15, 50,
196     0x04, 0x21,  4, 15, 30,
197     0x05, 0x21,  5, 15, 30,
198     0x06, 0x20, 12,  15, 30,
199     0x07, 0x20, 13,  8, 20,
200     0x08, 0x20, 14,  8, 20,
201     0x09, 0x20, 15,  8, 25,
202     0x0a, 0x22, 15,  8, 25,
203 };
204
205 UCHAR RateSwitchTable11BGN1S[] = {
206 // 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)
207     0x0d, 0x00,  0,  0,  0,                                             // Initial used item after association
208     0x00, 0x00,  0, 40, 101,
209     0x01, 0x00,  1, 40, 50,
210     0x02, 0x00,  2, 35, 45,
211     0x03, 0x00,  3, 20, 45,
212     0x04, 0x21,  0, 30,101,     //50
213     0x05, 0x21,  1, 20, 50,
214     0x06, 0x21,  2, 20, 50,
215     0x07, 0x21,  3, 15, 50,
216     0x08, 0x21,  4, 15, 30,
217     0x09, 0x21,  5, 10, 25,
218     0x0a, 0x21,  6,  8, 14,
219     0x0b, 0x21,  7,  8, 14,
220         0x0c, 0x23,  7,  8, 14,
221 };
222
223 UCHAR RateSwitchTable11BGN2S[] = {
224 // 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)
225     0x0a, 0x00,  0,  0,  0,                                             // Initial used item after association
226     0x00, 0x21,  0, 30,101,     //50
227     0x01, 0x21,  1, 20, 50,
228     0x02, 0x21,  2, 20, 50,
229     0x03, 0x21,  3, 15, 50,
230     0x04, 0x21,  4, 15, 30,
231     0x05, 0x20, 12, 15, 30,
232     0x06, 0x20, 13,  8, 20,
233     0x07, 0x20, 14,  8, 20,
234     0x08, 0x20, 15,  8, 25,
235     0x09, 0x22, 15,  8, 25,
236 };
237
238 UCHAR RateSwitchTable11BGN3S[] = { // 3*3
239 // 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)
240     0x0a, 0x00,  0,  0,  0,                                             // Initial used item after association
241     0x00, 0x21,  0, 30,101,     //50
242     0x01, 0x21,  1, 20, 50,
243     0x02, 0x21,  2, 20, 50,
244     0x03, 0x21,  3, 20, 50,
245     0x04, 0x21,  4, 15, 50,
246     0x05, 0x20, 20, 15, 30,
247     0x06, 0x20, 21,  8, 20,
248     0x07, 0x20, 22,  8, 20,
249     0x08, 0x20, 23,  8, 25,
250     0x09, 0x22, 23,  8, 25,
251 };
252
253 UCHAR RateSwitchTable11BGN2SForABand[] = {
254 // 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)
255     0x0b, 0x09,  0,  0,  0,                                             // Initial used item after association
256     0x00, 0x21,  0, 30,101,     //50
257     0x01, 0x21,  1, 20, 50,
258     0x02, 0x21,  2, 20, 50,
259     0x03, 0x21,  3, 15, 50,
260     0x04, 0x21,  4, 15, 30,
261     0x05, 0x21,  5, 15, 30,
262     0x06, 0x20, 12, 15, 30,
263     0x07, 0x20, 13,  8, 20,
264     0x08, 0x20, 14,  8, 20,
265     0x09, 0x20, 15,  8, 25,
266     0x0a, 0x22, 15,  8, 25,
267 };
268
269 UCHAR RateSwitchTable11BGN3SForABand[] = { // 3*3
270 // 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)
271     0x0c, 0x09,  0,  0,  0,                                             // Initial used item after association
272     0x00, 0x21,  0, 30,101,     //50
273     0x01, 0x21,  1, 20, 50,
274     0x02, 0x21,  2, 20, 50,
275     0x03, 0x21,  3, 15, 50,
276     0x04, 0x21,  4, 15, 30,
277     0x05, 0x21,  5, 15, 30,
278     0x06, 0x21, 12, 15, 30,
279     0x07, 0x20, 20, 15, 30,
280     0x08, 0x20, 21,  8, 20,
281     0x09, 0x20, 22,  8, 20,
282     0x0a, 0x20, 23,  8, 25,
283     0x0b, 0x22, 23,  8, 25,
284 };
285
286 PUCHAR ReasonString[] = {
287         /* 0  */         "Reserved",
288         /* 1  */         "Unspecified Reason",
289         /* 2  */         "Previous Auth no longer valid",
290         /* 3  */         "STA is leaving / has left",
291         /* 4  */         "DIS-ASSOC due to inactivity",
292         /* 5  */         "AP unable to hanle all associations",
293         /* 6  */         "class 2 error",
294         /* 7  */         "class 3 error",
295         /* 8  */         "STA is leaving / has left",
296         /* 9  */         "require auth before assoc/re-assoc",
297         /* 10 */         "Reserved",
298         /* 11 */         "Reserved",
299         /* 12 */         "Reserved",
300         /* 13 */         "invalid IE",
301         /* 14 */         "MIC error",
302         /* 15 */         "4-way handshake timeout",
303         /* 16 */         "2-way (group key) handshake timeout",
304         /* 17 */         "4-way handshake IE diff among AssosReq/Rsp/Beacon",
305         /* 18 */
306 };
307
308 extern UCHAR     OfdmRateToRxwiMCS[];
309 // since RT61 has better RX sensibility, we have to limit TX ACK rate not to exceed our normal data TX rate.
310 // otherwise the WLAN peer may not be able to receive the ACK thus downgrade its data TX rate
311 ULONG BasicRateMask[12]                         = {0xfffff001 /* 1-Mbps */, 0xfffff003 /* 2 Mbps */, 0xfffff007 /* 5.5 */, 0xfffff00f /* 11 */,
312                                                                           0xfffff01f /* 6 */     , 0xfffff03f /* 9 */     , 0xfffff07f /* 12 */ , 0xfffff0ff /* 18 */,
313                                                                           0xfffff1ff /* 24 */    , 0xfffff3ff /* 36 */    , 0xfffff7ff /* 48 */ , 0xffffffff /* 54 */};
314
315 UCHAR MULTICAST_ADDR[MAC_ADDR_LEN] = {0x1,  0x00, 0x00, 0x00, 0x00, 0x00};
316 UCHAR BROADCAST_ADDR[MAC_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
317 UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN]  = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
318
319 // e.g. RssiSafeLevelForTxRate[RATE_36]" means if the current RSSI is greater than
320 //              this value, then it's quaranteed capable of operating in 36 mbps TX rate in
321 //              clean environment.
322 //                                                                TxRate: 1   2   5.5   11       6        9    12       18       24   36   48   54       72  100
323 CHAR RssiSafeLevelForTxRate[] ={  -92, -91, -90, -87, -88, -86, -85, -83, -81, -78, -72, -71, -40, -40 };
324
325 UCHAR  RateIdToMbps[]    = { 1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 72, 100};
326 USHORT RateIdTo500Kbps[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 144, 200};
327
328 UCHAR  SsidIe    = IE_SSID;
329 UCHAR  SupRateIe = IE_SUPP_RATES;
330 UCHAR  ExtRateIe = IE_EXT_SUPP_RATES;
331 UCHAR  HtCapIe = IE_HT_CAP;
332 UCHAR  AddHtInfoIe = IE_ADD_HT;
333 UCHAR  NewExtChanIe = IE_SECONDARY_CH_OFFSET;
334 UCHAR  ErpIe     = IE_ERP;
335 UCHAR  DsIe      = IE_DS_PARM;
336 UCHAR  TimIe     = IE_TIM;
337 UCHAR  WpaIe     = IE_WPA;
338 UCHAR  Wpa2Ie    = IE_WPA2;
339 UCHAR  IbssIe    = IE_IBSS_PARM;
340 UCHAR  Ccx2Ie    = IE_CCX_V2;
341 #ifdef RT2870
342 UCHAR  WapiIe    = IE_WAPI;
343 #endif
344
345 extern UCHAR    WPA_OUI[];
346
347 UCHAR   SES_OUI[] = {0x00, 0x90, 0x4c};
348
349 UCHAR   ZeroSsid[32] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
350         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
351
352 // Reset the RFIC setting to new series
353 RTMP_RF_REGS RF2850RegTable[] = {
354 //              ch       R1              R2              R3(TX0~4=0) R4
355                 {1,  0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b},
356                 {2,  0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f},
357                 {3,  0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b},
358                 {4,  0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f},
359                 {5,  0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b},
360                 {6,  0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f},
361                 {7,  0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b},
362                 {8,  0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f},
363                 {9,  0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b},
364                 {10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f},
365                 {11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b},
366                 {12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f},
367                 {13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b},
368                 {14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193},
369
370                 // 802.11 UNI / HyperLan 2
371                 {36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3},
372                 {38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193},
373                 {40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183},
374                 {44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3},
375                 {46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b},
376                 {48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b},
377                 {52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193},
378                 {54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3},
379                 {56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b},
380                 {60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183},
381                 {62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193},
382                 {64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3}, // Plugfest#4, Day4, change RFR3 left4th 9->5.
383
384                 // 802.11 HyperLan 2
385                 {100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783},
386
387                 // 2008.04.30 modified
388                 // The system team has AN to improve the EVM value
389                 // for channel 102 to 108 for the RT2850/RT2750 dual band solution.
390                 {102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793},
391                 {104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3},
392                 {108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193},
393
394                 {110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183},
395                 {112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b},
396                 {116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3},
397                 {118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193},
398                 {120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183},
399                 {124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193},
400                 {126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}, // 0x980ed1bb->0x980ed15b required by Rory 20070927
401                 {128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3},
402                 {132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b},
403                 {134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193},
404                 {136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b},
405                 {140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183},
406
407                 // 802.11 UNII
408                 {149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7},
409                 {151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187},
410                 {153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f},
411                 {157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f},
412                 {159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7},
413                 {161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187},
414                 {165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197},
415
416                 // Japan
417                 {184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b},
418                 {188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13},
419                 {192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b},
420                 {196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23},
421                 {208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13},
422                 {212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b},
423                 {216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23},
424
425                 // still lack of MMAC(Japan) ch 34,38,42,46
426 };
427 UCHAR   NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(RTMP_RF_REGS));
428
429 FREQUENCY_ITEM FreqItems3020[] =
430 {
431         /**************************************************/
432         // ISM : 2.4 to 2.483 GHz                         //
433         /**************************************************/
434         // 11g
435         /**************************************************/
436         //-CH---N-------R---K-----------
437         {1,    241,  2,  2},
438         {2,    241,      2,  7},
439         {3,    242,      2,  2},
440         {4,    242,      2,  7},
441         {5,    243,      2,  2},
442         {6,    243,      2,  7},
443         {7,    244,      2,  2},
444         {8,    244,      2,  7},
445         {9,    245,      2,  2},
446         {10,   245,      2,  7},
447         {11,   246,      2,  2},
448         {12,   246,      2,  7},
449         {13,   247,      2,  2},
450         {14,   248,      2,  4},
451 };
452 #ifndef RT30xx
453 #define NUM_OF_3020_CHNL        (sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM))
454 #endif
455 #ifdef RT30xx
456 //2008/07/10:KH Modified to share this variable
457 UCHAR   NUM_OF_3020_CHNL=(sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM));
458 #endif
459
460 /*
461         ==========================================================================
462         Description:
463                 initialize the MLME task and its data structure (queue, spinlock,
464                 timer, state machines).
465
466         IRQL = PASSIVE_LEVEL
467
468         Return:
469                 always return NDIS_STATUS_SUCCESS
470
471         ==========================================================================
472 */
473 NDIS_STATUS MlmeInit(
474         IN PRTMP_ADAPTER pAd)
475 {
476         NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
477
478         DBGPRINT(RT_DEBUG_TRACE, ("--> MLME Initialize\n"));
479
480         do
481         {
482                 Status = MlmeQueueInit(&pAd->Mlme.Queue);
483                 if(Status != NDIS_STATUS_SUCCESS)
484                         break;
485
486                 pAd->Mlme.bRunning = FALSE;
487                 NdisAllocateSpinLock(&pAd->Mlme.TaskLock);
488
489                 {
490                         BssTableInit(&pAd->ScanTab);
491
492                         // init STA state machines
493                         AssocStateMachineInit(pAd, &pAd->Mlme.AssocMachine, pAd->Mlme.AssocFunc);
494                         AuthStateMachineInit(pAd, &pAd->Mlme.AuthMachine, pAd->Mlme.AuthFunc);
495                         AuthRspStateMachineInit(pAd, &pAd->Mlme.AuthRspMachine, pAd->Mlme.AuthRspFunc);
496                         SyncStateMachineInit(pAd, &pAd->Mlme.SyncMachine, pAd->Mlme.SyncFunc);
497                         WpaPskStateMachineInit(pAd, &pAd->Mlme.WpaPskMachine, pAd->Mlme.WpaPskFunc);
498                         AironetStateMachineInit(pAd, &pAd->Mlme.AironetMachine, pAd->Mlme.AironetFunc);
499
500                         // Since we are using switch/case to implement it, the init is different from the above
501                         // state machine init
502                         MlmeCntlInit(pAd, &pAd->Mlme.CntlMachine, NULL);
503                 }
504
505                 ActionStateMachineInit(pAd, &pAd->Mlme.ActMachine, pAd->Mlme.ActFunc);
506
507                 // Init mlme periodic timer
508                 RTMPInitTimer(pAd, &pAd->Mlme.PeriodicTimer, GET_TIMER_FUNCTION(MlmePeriodicExec), pAd, TRUE);
509
510                 // Set mlme periodic timer
511                 RTMPSetTimer(&pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
512
513                 // software-based RX Antenna diversity
514                 RTMPInitTimer(pAd, &pAd->Mlme.RxAntEvalTimer, GET_TIMER_FUNCTION(AsicRxAntEvalTimeout), pAd, FALSE);
515
516 #ifdef RT2860
517                 {
518                 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
519                 {
520                     // only PCIe cards need these two timers
521                         RTMPInitTimer(pAd, &pAd->Mlme.PsPollTimer, GET_TIMER_FUNCTION(PsPollWakeExec), pAd, FALSE);
522                         RTMPInitTimer(pAd, &pAd->Mlme.RadioOnOffTimer, GET_TIMER_FUNCTION(RadioOnExec), pAd, FALSE);
523                 }
524                 }
525 #endif
526         } while (FALSE);
527
528         DBGPRINT(RT_DEBUG_TRACE, ("<-- MLME Initialize\n"));
529
530         return Status;
531 }
532
533 /*
534         ==========================================================================
535         Description:
536                 main loop of the MLME
537         Pre:
538                 Mlme has to be initialized, and there are something inside the queue
539         Note:
540                 This function is invoked from MPSetInformation and MPReceive;
541                 This task guarantee only one MlmeHandler will run.
542
543         IRQL = DISPATCH_LEVEL
544
545         ==========================================================================
546  */
547 VOID MlmeHandler(
548         IN PRTMP_ADAPTER pAd)
549 {
550         MLME_QUEUE_ELEM            *Elem = NULL;
551
552         // Only accept MLME and Frame from peer side, no other (control/data) frame should
553         // get into this state machine
554
555         NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
556         if(pAd->Mlme.bRunning)
557         {
558                 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
559                 return;
560         }
561         else
562         {
563                 pAd->Mlme.bRunning = TRUE;
564         }
565         NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
566
567         while (!MlmeQueueEmpty(&pAd->Mlme.Queue))
568         {
569                 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS) ||
570                         RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
571                         RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
572                 {
573                         DBGPRINT(RT_DEBUG_TRACE, ("Device Halted or Removed or MlmeRest, exit MlmeHandler! (queue num = %ld)\n", pAd->Mlme.Queue.Num));
574                         break;
575                 }
576
577                 //From message type, determine which state machine I should drive
578                 if (MlmeDequeue(&pAd->Mlme.Queue, &Elem))
579                 {
580 #ifdef RT2870
581                         if (Elem->MsgType == MT2_RESET_CONF)
582                         {
583                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("!!! reset MLME state machine !!!\n"));
584                                 MlmeRestartStateMachine(pAd);
585                                 Elem->Occupied = FALSE;
586                                 Elem->MsgLen = 0;
587                                 continue;
588                         }
589 #endif // RT2870 //
590
591                         // if dequeue success
592                         switch (Elem->Machine)
593                         {
594                                 // STA state machines
595                                 case ASSOC_STATE_MACHINE:
596                                         StateMachinePerformAction(pAd, &pAd->Mlme.AssocMachine, Elem);
597                                         break;
598                                 case AUTH_STATE_MACHINE:
599                                         StateMachinePerformAction(pAd, &pAd->Mlme.AuthMachine, Elem);
600                                         break;
601                                 case AUTH_RSP_STATE_MACHINE:
602                                         StateMachinePerformAction(pAd, &pAd->Mlme.AuthRspMachine, Elem);
603                                         break;
604                                 case SYNC_STATE_MACHINE:
605                                         StateMachinePerformAction(pAd, &pAd->Mlme.SyncMachine, Elem);
606                                         break;
607                                 case MLME_CNTL_STATE_MACHINE:
608                                         MlmeCntlMachinePerformAction(pAd, &pAd->Mlme.CntlMachine, Elem);
609                                         break;
610                                 case WPA_PSK_STATE_MACHINE:
611                                         StateMachinePerformAction(pAd, &pAd->Mlme.WpaPskMachine, Elem);
612                                         break;
613                                 case AIRONET_STATE_MACHINE:
614                                         StateMachinePerformAction(pAd, &pAd->Mlme.AironetMachine, Elem);
615                                         break;
616                                 case ACTION_STATE_MACHINE:
617                                         StateMachinePerformAction(pAd, &pAd->Mlme.ActMachine, Elem);
618                                         break;
619
620
621
622
623                                 default:
624                                         DBGPRINT(RT_DEBUG_TRACE, ("ERROR: Illegal machine %ld in MlmeHandler()\n", Elem->Machine));
625                                         break;
626                         } // end of switch
627
628                         // free MLME element
629                         Elem->Occupied = FALSE;
630                         Elem->MsgLen = 0;
631
632                 }
633                 else {
634                         DBGPRINT_ERR(("MlmeHandler: MlmeQueue empty\n"));
635                 }
636         }
637
638         NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
639         pAd->Mlme.bRunning = FALSE;
640         NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
641 }
642
643 /*
644         ==========================================================================
645         Description:
646                 Destructor of MLME (Destroy queue, state machine, spin lock and timer)
647         Parameters:
648                 Adapter - NIC Adapter pointer
649         Post:
650                 The MLME task will no longer work properly
651
652         IRQL = PASSIVE_LEVEL
653
654         ==========================================================================
655  */
656 VOID MlmeHalt(
657         IN PRTMP_ADAPTER pAd)
658 {
659         BOOLEAN           Cancelled;
660 #ifdef RT3070
661         UINT32          TxPinCfg = 0x00050F0F;
662 #endif // RT3070 //
663
664         DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeHalt\n"));
665
666         if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
667         {
668                 // disable BEACON generation and other BEACON related hardware timers
669                 AsicDisableSync(pAd);
670         }
671
672         {
673                 // Cancel pending timers
674                 RTMPCancelTimer(&pAd->MlmeAux.AssocTimer,               &Cancelled);
675                 RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer,             &Cancelled);
676                 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer,    &Cancelled);
677                 RTMPCancelTimer(&pAd->MlmeAux.AuthTimer,                &Cancelled);
678                 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer,              &Cancelled);
679                 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer,                &Cancelled);
680 #ifdef RT2860
681             if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
682             {
683                     RTMPCancelTimer(&pAd->Mlme.PsPollTimer,             &Cancelled);
684                     RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer,         &Cancelled);
685                 }
686 #endif
687         }
688
689         RTMPCancelTimer(&pAd->Mlme.PeriodicTimer,               &Cancelled);
690         RTMPCancelTimer(&pAd->Mlme.RxAntEvalTimer,              &Cancelled);
691
692
693
694         if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
695         {
696                 // Set LED
697                 RTMPSetLED(pAd, LED_HALT);
698         RTMPSetSignalLED(pAd, -100);    // Force signal strength Led to be turned off, firmware is not done it.
699 #ifdef RT2870
700         {
701             LED_CFG_STRUC LedCfg;
702             RTMP_IO_READ32(pAd, LED_CFG, &LedCfg.word);
703             LedCfg.field.LedPolar = 0;
704             LedCfg.field.RLedMode = 0;
705             LedCfg.field.GLedMode = 0;
706             LedCfg.field.YLedMode = 0;
707             RTMP_IO_WRITE32(pAd, LED_CFG, LedCfg.word);
708         }
709 #endif // RT2870 //
710 #ifdef RT3070
711                 //
712                 // Turn off LNA_PE
713                 //
714                 if (IS_RT3070(pAd) || IS_RT3071(pAd))
715                 {
716                         TxPinCfg &= 0xFFFFF0F0;
717                         RTUSBWriteMACRegister(pAd, TX_PIN_CFG, TxPinCfg);
718                 }
719 #endif // RT3070 //
720         }
721
722         RTMPusecDelay(5000);    //  5 msec to gurantee Ant Diversity timer canceled
723
724         MlmeQueueDestroy(&pAd->Mlme.Queue);
725         NdisFreeSpinLock(&pAd->Mlme.TaskLock);
726
727         DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeHalt\n"));
728 }
729
730 VOID MlmeResetRalinkCounters(
731         IN  PRTMP_ADAPTER   pAd)
732 {
733         pAd->RalinkCounters.LastOneSecRxOkDataCnt = pAd->RalinkCounters.OneSecRxOkDataCnt;
734         // clear all OneSecxxx counters.
735         pAd->RalinkCounters.OneSecBeaconSentCnt = 0;
736         pAd->RalinkCounters.OneSecFalseCCACnt = 0;
737         pAd->RalinkCounters.OneSecRxFcsErrCnt = 0;
738         pAd->RalinkCounters.OneSecRxOkCnt = 0;
739         pAd->RalinkCounters.OneSecTxFailCount = 0;
740         pAd->RalinkCounters.OneSecTxNoRetryOkCount = 0;
741         pAd->RalinkCounters.OneSecTxRetryOkCount = 0;
742         pAd->RalinkCounters.OneSecRxOkDataCnt = 0;
743
744         // TODO: for debug only. to be removed
745         pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BE] = 0;
746         pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BK] = 0;
747         pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VI] = 0;
748         pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VO] = 0;
749         pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BE] = 0;
750         pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BK] = 0;
751         pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VI] = 0;
752         pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VO] = 0;
753         pAd->RalinkCounters.OneSecTxDoneCount = 0;
754         pAd->RalinkCounters.OneSecRxCount = 0;
755         pAd->RalinkCounters.OneSecTxAggregationCount = 0;
756         pAd->RalinkCounters.OneSecRxAggregationCount = 0;
757
758         return;
759 }
760
761 unsigned long rx_AMSDU;
762 unsigned long rx_Total;
763
764 /*
765         ==========================================================================
766         Description:
767                 This routine is executed periodically to -
768                 1. Decide if it's a right time to turn on PwrMgmt bit of all
769                    outgoiing frames
770                 2. Calculate ChannelQuality based on statistics of the last
771                    period, so that TX rate won't toggling very frequently between a
772                    successful TX and a failed TX.
773                 3. If the calculated ChannelQuality indicated current connection not
774                    healthy, then a ROAMing attempt is tried here.
775
776         IRQL = DISPATCH_LEVEL
777
778         ==========================================================================
779  */
780 #define ADHOC_BEACON_LOST_TIME          (8*OS_HZ)  // 8 sec
781 VOID MlmePeriodicExec(
782         IN PVOID SystemSpecific1,
783         IN PVOID FunctionContext,
784         IN PVOID SystemSpecific2,
785         IN PVOID SystemSpecific3)
786 {
787         ULONG                   TxTotalCnt;
788         PRTMP_ADAPTER   pAd = (RTMP_ADAPTER *)FunctionContext;
789
790 #ifdef RT2860
791         //Baron 2008/07/10
792         //printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus));
793         //If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0.
794         //If the STA security setting is WPAPSK or WPA2PSK, pAd->StaCfg.WpaSupplicantUP = 1.
795         if(pAd->StaCfg.WepStatus<2)
796         {
797                 pAd->StaCfg.WpaSupplicantUP = 0;
798         }
799         else
800         {
801                 pAd->StaCfg.WpaSupplicantUP = 1;
802         }
803
804         {
805             // If Hardware controlled Radio enabled, we have to check GPIO pin2 every 2 second.
806                 // Move code to here, because following code will return when radio is off
807                 if ((pAd->Mlme.PeriodicRound % (MLME_TASK_EXEC_MULTIPLE * 2) == 0) &&
808                         (pAd->StaCfg.bHardwareRadio == TRUE) &&
809                         (RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP)) &&
810                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
811                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
812                 {
813                         UINT32                          data = 0;
814
815                         // Read GPIO pin2 as Hardware controlled radio state
816                         RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data);
817                         if (data & 0x04)
818                         {
819                                 pAd->StaCfg.bHwRadio = TRUE;
820                         }
821                         else
822                         {
823                                 pAd->StaCfg.bHwRadio = FALSE;
824                         }
825                         if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
826                         {
827                                 pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
828                                 if (pAd->StaCfg.bRadio == TRUE)
829                                 {
830                                         MlmeRadioOn(pAd);
831                                         // Update extra information
832                                         pAd->ExtraInfo = EXTRA_INFO_CLEAR;
833                                 }
834                                 else
835                                 {
836                                         MlmeRadioOff(pAd);
837                                         // Update extra information
838                                         pAd->ExtraInfo = HW_RADIO_OFF;
839                                 }
840                         }
841                 }
842         }
843 #endif /* RT2860 */
844
845         // Do nothing if the driver is starting halt state.
846         // This might happen when timer already been fired before cancel timer with mlmehalt
847         if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_HALT_IN_PROGRESS |
848                                                                 fRTMP_ADAPTER_RADIO_OFF |
849                                                                 fRTMP_ADAPTER_RADIO_MEASUREMENT |
850                                                                 fRTMP_ADAPTER_RESET_IN_PROGRESS))))
851                 return;
852
853 #ifdef RT2860
854         {
855                 if ((pAd->RalinkCounters.LastReceivedByteCount == pAd->RalinkCounters.ReceivedByteCount) && (pAd->StaCfg.bRadio == TRUE))
856                 {
857                         // If ReceiveByteCount doesn't change,  increase SameRxByteCount by 1.
858                         pAd->SameRxByteCount++;
859                 }
860                 else
861                         pAd->SameRxByteCount = 0;
862
863                 // If after BBP, still not work...need to check to reset PBF&MAC.
864                 if (pAd->SameRxByteCount == 702)
865                 {
866                         pAd->SameRxByteCount = 0;
867                         AsicResetPBF(pAd);
868                         AsicResetMAC(pAd);
869                 }
870
871                 // If SameRxByteCount keeps happens for 2 second in infra mode, or for 60 seconds in idle mode.
872                 if (((INFRA_ON(pAd)) && (pAd->SameRxByteCount > 20)) || ((IDLE_ON(pAd)) && (pAd->SameRxByteCount > 600)))
873                 {
874                         if ((pAd->StaCfg.bRadio == TRUE) && (pAd->SameRxByteCount < 700))
875                         {
876                                 DBGPRINT(RT_DEBUG_TRACE, ("--->  SameRxByteCount = %lu !!!!!!!!!!!!!!! \n", pAd->SameRxByteCount));
877                                 pAd->SameRxByteCount = 700;
878                                 AsicResetBBP(pAd);
879                         }
880                 }
881
882                 // Update lastReceiveByteCount.
883                 pAd->RalinkCounters.LastReceivedByteCount = pAd->RalinkCounters.ReceivedByteCount;
884
885                 if ((pAd->CheckDmaBusyCount > 3) && (IDLE_ON(pAd)))
886                 {
887                         pAd->CheckDmaBusyCount = 0;
888                         AsicResetFromDMABusy(pAd);
889                 }
890         }
891 #endif /* RT2860 */
892         RT28XX_MLME_PRE_SANITY_CHECK(pAd);
893
894         {
895                 // Do nothing if monitor mode is on
896                 if (MONITOR_ON(pAd))
897                         return;
898
899                 if (pAd->Mlme.PeriodicRound & 0x1)
900                 {
901                         // This is the fix for wifi 11n extension channel overlapping test case.  for 2860D
902                         if (((pAd->MACVersion & 0xffff) == 0x0101) &&
903                                 (STA_TGN_WIFI_ON(pAd)) &&
904                                 (pAd->CommonCfg.IOTestParm.bToggle == FALSE))
905
906                                 {
907                                         RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x24Bf);
908                                         pAd->CommonCfg.IOTestParm.bToggle = TRUE;
909                                 }
910                                 else if ((STA_TGN_WIFI_ON(pAd)) &&
911                                                 ((pAd->MACVersion & 0xffff) == 0x0101))
912                                 {
913                                         RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x243f);
914                                         pAd->CommonCfg.IOTestParm.bToggle = FALSE;
915                                 }
916                 }
917         }
918
919         pAd->bUpdateBcnCntDone = FALSE;
920
921 //      RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3);
922         pAd->Mlme.PeriodicRound ++;
923
924 #ifdef RT3070
925         // execute every 100ms, update the Tx FIFO Cnt for update Tx Rate.
926         NICUpdateFifoStaCounters(pAd);
927 #endif // RT3070 //
928         // execute every 500ms
929         if ((pAd->Mlme.PeriodicRound % 5 == 0) && RTMPAutoRateSwitchCheck(pAd)/*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))*/)
930         {
931                 // perform dynamic tx rate switching based on past TX history
932                 {
933                         if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
934                                         )
935                                 && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)))
936                                 MlmeDynamicTxRateSwitching(pAd);
937                 }
938         }
939
940         // Normal 1 second Mlme PeriodicExec.
941         if (pAd->Mlme.PeriodicRound %MLME_TASK_EXEC_MULTIPLE == 0)
942         {
943                 pAd->Mlme.OneSecPeriodicRound ++;
944
945                 if (rx_Total)
946                 {
947
948                         // reset counters
949                         rx_AMSDU = 0;
950                         rx_Total = 0;
951                 }
952
953                 // Media status changed, report to NDIS
954                 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE))
955                 {
956                         RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
957                         if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
958                         {
959                                 pAd->IndicateMediaState = NdisMediaStateConnected;
960                                 RTMP_IndicateMediaState(pAd);
961
962                         }
963                         else
964                         {
965                                 pAd->IndicateMediaState = NdisMediaStateDisconnected;
966                                 RTMP_IndicateMediaState(pAd);
967                         }
968                 }
969
970                 NdisGetSystemUpTime(&pAd->Mlme.Now32);
971
972                 // add the most up-to-date h/w raw counters into software variable, so that
973                 // the dynamic tuning mechanism below are based on most up-to-date information
974                 NICUpdateRawCounters(pAd);
975
976 #ifdef RT2870
977                 RT2870_WatchDog(pAd);
978 #endif // RT2870 //
979
980                 // Need statistics after read counter. So put after NICUpdateRawCounters
981                 ORIBATimerTimeout(pAd);
982
983                 // The time period for checking antenna is according to traffic
984                 if (pAd->Mlme.bEnableAutoAntennaCheck)
985                 {
986                         TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
987                                                          pAd->RalinkCounters.OneSecTxRetryOkCount +
988                                                          pAd->RalinkCounters.OneSecTxFailCount;
989
990                         // dynamic adjust antenna evaluation period according to the traffic
991                         if (TxTotalCnt > 50)
992                         {
993                                 if (pAd->Mlme.OneSecPeriodicRound % 10 == 0)
994                                 {
995                                         AsicEvaluateRxAnt(pAd);
996                                 }
997                         }
998                         else
999                         {
1000                                 if (pAd->Mlme.OneSecPeriodicRound % 3 == 0)
1001                                 {
1002                                         AsicEvaluateRxAnt(pAd);
1003                                 }
1004                         }
1005                 }
1006
1007                 STAMlmePeriodicExec(pAd);
1008
1009                 MlmeResetRalinkCounters(pAd);
1010
1011                 {
1012 #ifdef RT2860
1013                         if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->bPCIclkOff == FALSE))
1014 #endif
1015                         {
1016                                 // When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock
1017                                 // and sending CTS-to-self over and over.
1018                                 // Software Patch Solution:
1019                                 // 1. Polling debug state register 0x10F4 every one second.
1020                                 // 2. If in 0x10F4 the ((bit29==1) && (bit7==1)) OR ((bit29==1) && (bit5==1)), it means the deadlock has occurred.
1021                                 // 3. If the deadlock occurred, reset MAC/BBP by setting 0x1004 to 0x0001 for a while then setting it back to 0x000C again.
1022
1023                                 UINT32  MacReg = 0;
1024
1025                                 RTMP_IO_READ32(pAd, 0x10F4, &MacReg);
1026                                 if (((MacReg & 0x20000000) && (MacReg & 0x80)) || ((MacReg & 0x20000000) && (MacReg & 0x20)))
1027                                 {
1028                                         RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
1029                                         RTMPusecDelay(1);
1030                                         RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xC);
1031
1032                                         DBGPRINT(RT_DEBUG_WARN,("Warning, MAC specific condition occurs \n"));
1033                                 }
1034                         }
1035                 }
1036
1037                 RT28XX_MLME_HANDLER(pAd);
1038         }
1039
1040         pAd->bUpdateBcnCntDone = FALSE;
1041 }
1042
1043 VOID STAMlmePeriodicExec(
1044         PRTMP_ADAPTER pAd)
1045 {
1046 #ifdef RT2860
1047         ULONG                       TxTotalCnt;
1048 #endif
1049 #ifdef RT2870
1050         ULONG   TxTotalCnt;
1051         int     i;
1052 #endif
1053
1054     if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)
1055     {
1056         // WPA MIC error should block association attempt for 60 seconds
1057         if (pAd->StaCfg.bBlockAssoc && (pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ) < pAd->Mlme.Now32))
1058                 pAd->StaCfg.bBlockAssoc = FALSE;
1059     }
1060
1061 #ifdef RT2860
1062         //Baron 2008/07/10
1063         //printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus));
1064         //If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0.
1065         //If the STA security setting is WPAPSK or WPA2PSK, pAd->StaCfg.WpaSupplicantUP = 1.
1066         if(pAd->StaCfg.WepStatus<2)
1067         {
1068                 pAd->StaCfg.WpaSupplicantUP = 0;
1069         }
1070         else
1071         {
1072                 pAd->StaCfg.WpaSupplicantUP = 1;
1073         }
1074 #endif
1075
1076     if ((pAd->PreMediaState != pAd->IndicateMediaState) && (pAd->CommonCfg.bWirelessEvent))
1077         {
1078                 if (pAd->IndicateMediaState == NdisMediaStateConnected)
1079                 {
1080                         RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1081                 }
1082                 pAd->PreMediaState = pAd->IndicateMediaState;
1083         }
1084
1085 #ifdef RT2860
1086         if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd)) &&
1087         (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
1088                 (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE) &&
1089                 (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
1090                 (RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP)) &&
1091                 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
1092         {
1093                 RT28xxPciAsicRadioOff(pAd, GUI_IDLE_POWER_SAVE, 0);
1094         }
1095 #endif
1096
1097
1098
1099         AsicStaBbpTuning(pAd);
1100
1101         TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
1102                                          pAd->RalinkCounters.OneSecTxRetryOkCount +
1103                                          pAd->RalinkCounters.OneSecTxFailCount;
1104
1105         if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1106         {
1107                 // update channel quality for Roaming and UI LinkQuality display
1108                 MlmeCalculateChannelQuality(pAd, pAd->Mlme.Now32);
1109         }
1110
1111         // must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if
1112         // Radio is currently in noisy environment
1113         if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1114                 AsicAdjustTxPower(pAd);
1115
1116         if (INFRA_ON(pAd))
1117         {
1118                 // Is PSM bit consistent with user power management policy?
1119                 // This is the only place that will set PSM bit ON.
1120                 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
1121                 MlmeCheckPsmChange(pAd, pAd->Mlme.Now32);
1122
1123                 pAd->RalinkCounters.LastOneSecTotalTxCount = TxTotalCnt;
1124
1125                 if ((pAd->StaCfg.LastBeaconRxTime + 1*OS_HZ < pAd->Mlme.Now32) &&
1126                         (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
1127                         ((TxTotalCnt + pAd->RalinkCounters.OneSecRxOkCnt < 600)))
1128                 {
1129                         RTMPSetAGCInitValue(pAd, BW_20);
1130                         DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n", (0x2E + GET_LNA_GAIN(pAd))));
1131                 }
1132
1133         {
1134                 if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable)
1135                 {
1136                     // When APSD is enabled, the period changes as 20 sec
1137                         if ((pAd->Mlme.OneSecPeriodicRound % 20) == 8)
1138                                 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
1139                 }
1140                 else
1141                 {
1142                     // Send out a NULL frame every 10 sec to inform AP that STA is still alive (Avoid being age out)
1143                         if ((pAd->Mlme.OneSecPeriodicRound % 10) == 8)
1144                 {
1145                     if (pAd->CommonCfg.bWmmCapable)
1146                                         RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
1147                     else
1148                                                 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
1149                 }
1150                 }
1151         }
1152
1153                 if (CQI_IS_DEAD(pAd->Mlme.ChannelQuality))
1154                         {
1155                         DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
1156                         pAd->StaCfg.CCXAdjacentAPReportFlag = TRUE;
1157                         pAd->StaCfg.CCXAdjacentAPLinkDownTime = pAd->StaCfg.LastBeaconRxTime;
1158
1159                         // Lost AP, send disconnect & link down event
1160                         LinkDown(pAd, FALSE);
1161
1162             {
1163                 union iwreq_data    wrqu;
1164                 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
1165                 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
1166             }
1167
1168                         MlmeAutoReconnectLastSSID(pAd);
1169                 }
1170                 else if (CQI_IS_BAD(pAd->Mlme.ChannelQuality))
1171                 {
1172                         pAd->RalinkCounters.BadCQIAutoRecoveryCount ++;
1173                         DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Bad CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
1174                         MlmeAutoReconnectLastSSID(pAd);
1175                 }
1176
1177                 // Add auto seamless roaming
1178                 if (pAd->StaCfg.bFastRoaming)
1179                 {
1180                         SHORT   dBmToRoam = (SHORT)pAd->StaCfg.dBmToRoam;
1181
1182                         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));
1183
1184                         if (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) <= (CHAR)dBmToRoam)
1185                         {
1186                                 MlmeCheckForFastRoaming(pAd, pAd->Mlme.Now32);
1187                         }
1188                 }
1189         }
1190         else if (ADHOC_ON(pAd))
1191         {
1192 #ifdef RT2860
1193                 // 2003-04-17 john. this is a patch that driver forces a BEACON out if ASIC fails
1194                 // the "TX BEACON competition" for the entire past 1 sec.
1195                 // So that even when ASIC's BEACONgen engine been blocked
1196                 // by peer's BEACON due to slower system clock, this STA still can send out
1197                 // minimum BEACON to tell the peer I'm alive.
1198                 // drawback is that this BEACON won't be well aligned at TBTT boundary.
1199                 // EnqueueBeaconFrame(pAd);                       // software send BEACON
1200
1201                 // if all 11b peers leave this BSS more than 5 seconds, update Tx rate,
1202                 // restore outgoing BEACON to support B/G-mixed mode
1203                 if ((pAd->CommonCfg.Channel <= 14)                         &&
1204                         (pAd->CommonCfg.MaxTxRate <= RATE_11)      &&
1205                         (pAd->CommonCfg.MaxDesiredRate > RATE_11)  &&
1206                         ((pAd->StaCfg.Last11bBeaconRxTime + 5*OS_HZ) < pAd->Mlme.Now32))
1207                 {
1208                         DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - last 11B peer left, update Tx rates\n"));
1209                         NdisMoveMemory(pAd->StaActive.SupRate, pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
1210                         pAd->StaActive.SupRateLen = pAd->CommonCfg.SupRateLen;
1211                         MlmeUpdateTxRates(pAd, FALSE, 0);
1212                         MakeIbssBeacon(pAd);            // re-build BEACON frame
1213                         AsicEnableIbssSync(pAd);        // copy to on-chip memory
1214                         pAd->StaCfg.AdhocBOnlyJoined = FALSE;
1215                 }
1216
1217                 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
1218                 {
1219                         if ((pAd->StaCfg.AdhocBGJoined) &&
1220                                 ((pAd->StaCfg.Last11gBeaconRxTime + 5 * OS_HZ) < pAd->Mlme.Now32))
1221                         {
1222                                 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - last 11G peer left\n"));
1223                                 pAd->StaCfg.AdhocBGJoined = FALSE;
1224                         }
1225
1226                         if ((pAd->StaCfg.Adhoc20NJoined) &&
1227                                 ((pAd->StaCfg.Last20NBeaconRxTime + 5 * OS_HZ) < pAd->Mlme.Now32))
1228                         {
1229                                 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - last 20MHz N peer left\n"));
1230                                 pAd->StaCfg.Adhoc20NJoined = FALSE;
1231                         }
1232                 }
1233 #endif /* RT2860 */
1234
1235                 //radar detect
1236                 if ((pAd->CommonCfg.Channel > 14)
1237                         && (pAd->CommonCfg.bIEEE80211H == 1)
1238                         && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1239                 {
1240                         RadarDetectPeriodic(pAd);
1241                 }
1242
1243                 // If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState
1244                 // to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can
1245                 // join later.
1246                 if ((pAd->StaCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32) &&
1247                         OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1248                 {
1249                         MLME_START_REQ_STRUCT     StartReq;
1250
1251                         DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n"));
1252                         LinkDown(pAd, FALSE);
1253
1254                         StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
1255                         MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
1256                         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
1257                 }
1258
1259 #ifdef RT2870
1260                 for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
1261                 {
1262                         MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[i];
1263
1264                         if (pEntry->ValidAsCLI == FALSE)
1265                                 continue;
1266
1267                         if (pEntry->LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32)
1268                                 MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
1269                 }
1270 #endif
1271         }
1272         else // no INFRA nor ADHOC connection
1273         {
1274
1275                 if (pAd->StaCfg.bScanReqIsFromWebUI &&
1276             ((pAd->StaCfg.LastScanTime + 30 * OS_HZ) > pAd->Mlme.Now32))
1277                         goto SKIP_AUTO_SCAN_CONN;
1278         else
1279             pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
1280
1281                 if ((pAd->StaCfg.bAutoReconnect == TRUE)
1282                         && RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)
1283                         && (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
1284                 {
1285                         if ((pAd->ScanTab.BssNr==0) && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE))
1286                         {
1287                                 MLME_SCAN_REQ_STRUCT       ScanReq;
1288
1289                                 if ((pAd->StaCfg.LastScanTime + 10 * OS_HZ) < pAd->Mlme.Now32)
1290                                 {
1291                                         DBGPRINT(RT_DEBUG_TRACE, ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, start a new ACTIVE scan SSID[%s]\n", pAd->MlmeAux.AutoReconnectSsid));
1292                                         ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen, BSS_ANY, SCAN_ACTIVE);
1293                                         MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
1294                                         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
1295                                         // Reset Missed scan number
1296                                         pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
1297                                 }
1298                                 else if (pAd->StaCfg.BssType == BSS_ADHOC)      // Quit the forever scan when in a very clean room
1299                                         MlmeAutoReconnectLastSSID(pAd);
1300                         }
1301                         else if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1302                         {
1303                                 if ((pAd->Mlme.OneSecPeriodicRound % 7) == 0)
1304                                 {
1305                                         MlmeAutoScan(pAd);
1306                                         pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
1307                                 }
1308                                 else
1309                                 {
1310                                                 MlmeAutoReconnectLastSSID(pAd);
1311                                 }
1312                         }
1313                 }
1314         }
1315
1316 SKIP_AUTO_SCAN_CONN:
1317
1318     if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap !=0) && (pAd->MacTab.fAnyBASession == FALSE))
1319         {
1320                 pAd->MacTab.fAnyBASession = TRUE;
1321                 AsicUpdateProtect(pAd, HT_FORCERTSCTS,  ALLN_SETPROTECT, FALSE, FALSE);
1322         }
1323         else if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap ==0) && (pAd->MacTab.fAnyBASession == TRUE))
1324         {
1325                 pAd->MacTab.fAnyBASession = FALSE;
1326                 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode,  ALLN_SETPROTECT, FALSE, FALSE);
1327         }
1328
1329         return;
1330 }
1331
1332 // Link down report
1333 VOID LinkDownExec(
1334         IN PVOID SystemSpecific1,
1335         IN PVOID FunctionContext,
1336         IN PVOID SystemSpecific2,
1337         IN PVOID SystemSpecific3)
1338 {
1339
1340         RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
1341
1342         pAd->IndicateMediaState = NdisMediaStateDisconnected;
1343         RTMP_IndicateMediaState(pAd);
1344     pAd->ExtraInfo = GENERAL_LINK_DOWN;
1345 }
1346
1347 // IRQL = DISPATCH_LEVEL
1348 VOID MlmeAutoScan(
1349         IN PRTMP_ADAPTER pAd)
1350 {
1351         // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1352         if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1353         {
1354                 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Driver auto scan\n"));
1355                 MlmeEnqueue(pAd,
1356                                         MLME_CNTL_STATE_MACHINE,
1357                                         OID_802_11_BSSID_LIST_SCAN,
1358                                         0,
1359                                         NULL);
1360                 RT28XX_MLME_HANDLER(pAd);
1361         }
1362 }
1363
1364 // IRQL = DISPATCH_LEVEL
1365 VOID MlmeAutoReconnectLastSSID(
1366         IN PRTMP_ADAPTER pAd)
1367 {
1368
1369
1370         // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1371         if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
1372                 (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
1373         {
1374                 NDIS_802_11_SSID OidSsid;
1375                 OidSsid.SsidLength = pAd->MlmeAux.AutoReconnectSsidLen;
1376                 NdisMoveMemory(OidSsid.Ssid, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
1377
1378                 DBGPRINT(RT_DEBUG_TRACE, ("Driver auto reconnect to last OID_802_11_SSID setting - %s, len - %d\n", pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen));
1379                 MlmeEnqueue(pAd,
1380                                         MLME_CNTL_STATE_MACHINE,
1381                                         OID_802_11_SSID,
1382                                         sizeof(NDIS_802_11_SSID),
1383                                         &OidSsid);
1384                 RT28XX_MLME_HANDLER(pAd);
1385         }
1386 }
1387
1388 /*
1389         ==========================================================================
1390         Validate SSID for connection try and rescan purpose
1391         Valid SSID will have visible chars only.
1392         The valid length is from 0 to 32.
1393         IRQL = DISPATCH_LEVEL
1394         ==========================================================================
1395  */
1396 BOOLEAN MlmeValidateSSID(
1397         IN PUCHAR       pSsid,
1398         IN UCHAR        SsidLen)
1399 {
1400         int     index;
1401
1402         if (SsidLen > MAX_LEN_OF_SSID)
1403                 return (FALSE);
1404
1405         // Check each character value
1406         for (index = 0; index < SsidLen; index++)
1407         {
1408                 if (pSsid[index] < 0x20)
1409                         return (FALSE);
1410         }
1411
1412         // All checked
1413         return (TRUE);
1414 }
1415
1416 VOID MlmeSelectTxRateTable(
1417         IN PRTMP_ADAPTER                pAd,
1418         IN PMAC_TABLE_ENTRY             pEntry,
1419         IN PUCHAR                               *ppTable,
1420         IN PUCHAR                               pTableSize,
1421         IN PUCHAR                               pInitTxRateIdx)
1422 {
1423         do
1424         {
1425                 // decide the rate table for tuning
1426                 if (pAd->CommonCfg.TxRateTableSize > 0)
1427                 {
1428                         *ppTable = RateSwitchTable;
1429                         *pTableSize = RateSwitchTable[0];
1430                         *pInitTxRateIdx = RateSwitchTable[1];
1431
1432                         break;
1433                 }
1434
1435                 if ((pAd->OpMode == OPMODE_STA) && ADHOC_ON(pAd))
1436                 {
1437                         if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
1438 #ifdef RT2860
1439                                 !pAd->StaCfg.AdhocBOnlyJoined &&
1440                                 !pAd->StaCfg.AdhocBGJoined &&
1441                                 (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
1442                                 ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
1443 #endif
1444 #ifdef RT2870
1445                                 (pEntry->HTCapability.MCSSet[0] == 0xff) &&
1446                                 ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
1447 #endif
1448                         {// 11N 1S Adhoc
1449                                 *ppTable = RateSwitchTable11N1S;
1450                                 *pTableSize = RateSwitchTable11N1S[0];
1451                                 *pInitTxRateIdx = RateSwitchTable11N1S[1];
1452
1453                         }
1454                         else if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
1455 #ifdef RT2860
1456                                         !pAd->StaCfg.AdhocBOnlyJoined &&
1457                                         !pAd->StaCfg.AdhocBGJoined &&
1458                                         (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
1459                                         (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) &&
1460 #endif
1461 #ifdef RT2870
1462                                         (pEntry->HTCapability.MCSSet[0] == 0xff) &&
1463                                         (pEntry->HTCapability.MCSSet[1] == 0xff) &&
1464 #endif
1465                                         (pAd->Antenna.field.TxPath == 2))
1466                         {// 11N 2S Adhoc
1467                                 if (pAd->LatchRfRegs.Channel <= 14)
1468                                 {
1469                                         *ppTable = RateSwitchTable11N2S;
1470                                         *pTableSize = RateSwitchTable11N2S[0];
1471                                         *pInitTxRateIdx = RateSwitchTable11N2S[1];
1472                                 }
1473                                 else
1474                                 {
1475                                         *ppTable = RateSwitchTable11N2SForABand;
1476                                         *pTableSize = RateSwitchTable11N2SForABand[0];
1477                                         *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
1478                                 }
1479
1480                         }
1481                         else
1482 #ifdef RT2860
1483                                 if (pAd->CommonCfg.PhyMode == PHY_11B)
1484                         {
1485                                 *ppTable = RateSwitchTable11B;
1486                                 *pTableSize = RateSwitchTable11B[0];
1487                                 *pInitTxRateIdx = RateSwitchTable11B[1];
1488
1489                         }
1490                 else if((pAd->LatchRfRegs.Channel <= 14) && (pAd->StaCfg.AdhocBOnlyJoined == TRUE))
1491 #endif
1492 #ifdef RT2870
1493                                 if ((pEntry->RateLen == 4)
1494                                         && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
1495                                         )
1496 #endif
1497                         {
1498                                 // USe B Table when Only b-only Station in my IBSS .
1499                                 *ppTable = RateSwitchTable11B;
1500                                 *pTableSize = RateSwitchTable11B[0];
1501                                 *pInitTxRateIdx = RateSwitchTable11B[1];
1502
1503                         }
1504                         else if (pAd->LatchRfRegs.Channel <= 14)
1505                         {
1506                                 *ppTable = RateSwitchTable11BG;
1507                                 *pTableSize = RateSwitchTable11BG[0];
1508                                 *pInitTxRateIdx = RateSwitchTable11BG[1];
1509
1510                         }
1511                         else
1512                         {
1513                                 *ppTable = RateSwitchTable11G;
1514                                 *pTableSize = RateSwitchTable11G[0];
1515                                 *pInitTxRateIdx = RateSwitchTable11G[1];
1516
1517                         }
1518                         break;
1519                 }
1520
1521                 if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
1522                         ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
1523                 {// 11BGN 1S AP
1524                         *ppTable = RateSwitchTable11BGN1S;
1525                         *pTableSize = RateSwitchTable11BGN1S[0];
1526                         *pInitTxRateIdx = RateSwitchTable11BGN1S[1];
1527
1528                         break;
1529                 }
1530
1531                 if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
1532                         (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
1533                 {// 11BGN 2S AP
1534                         if (pAd->LatchRfRegs.Channel <= 14)
1535                         {
1536                                 *ppTable = RateSwitchTable11BGN2S;
1537                                 *pTableSize = RateSwitchTable11BGN2S[0];
1538                                 *pInitTxRateIdx = RateSwitchTable11BGN2S[1];
1539
1540                         }
1541                         else
1542                         {
1543                                 *ppTable = RateSwitchTable11BGN2SForABand;
1544                                 *pTableSize = RateSwitchTable11BGN2SForABand[0];
1545                                 *pInitTxRateIdx = RateSwitchTable11BGN2SForABand[1];
1546
1547                         }
1548                         break;
1549                 }
1550
1551                 if ((pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
1552                 {// 11N 1S AP
1553                         *ppTable = RateSwitchTable11N1S;
1554                         *pTableSize = RateSwitchTable11N1S[0];
1555                         *pInitTxRateIdx = RateSwitchTable11N1S[1];
1556
1557                         break;
1558                 }
1559
1560                 if ((pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
1561                 {// 11N 2S AP
1562                         if (pAd->LatchRfRegs.Channel <= 14)
1563                         {
1564                         *ppTable = RateSwitchTable11N2S;
1565                         *pTableSize = RateSwitchTable11N2S[0];
1566                         *pInitTxRateIdx = RateSwitchTable11N2S[1];
1567             }
1568                         else
1569                         {
1570                                 *ppTable = RateSwitchTable11N2SForABand;
1571                                 *pTableSize = RateSwitchTable11N2SForABand[0];
1572                                 *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
1573                         }
1574
1575                         break;
1576                 }
1577
1578                 //else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1579                 if ((pEntry->RateLen == 4)
1580 #ifndef RT30xx
1581 //Iverson mark for Adhoc b mode,sta will use rate 54  Mbps when connect with sta b/g/n mode
1582                         && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
1583 #endif
1584                         )
1585                 {// B only AP
1586                         *ppTable = RateSwitchTable11B;
1587                         *pTableSize = RateSwitchTable11B[0];
1588                         *pInitTxRateIdx = RateSwitchTable11B[1];
1589
1590                         break;
1591                 }
1592
1593                 //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1594                 if ((pEntry->RateLen > 8)
1595                         && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
1596                         )
1597                 {// B/G  mixed AP
1598                         *ppTable = RateSwitchTable11BG;
1599                         *pTableSize = RateSwitchTable11BG[0];
1600                         *pInitTxRateIdx = RateSwitchTable11BG[1];
1601
1602                         break;
1603                 }
1604
1605                 //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1606                 if ((pEntry->RateLen == 8)
1607                         && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
1608                         )
1609                 {// G only AP
1610                         *ppTable = RateSwitchTable11G;
1611                         *pTableSize = RateSwitchTable11G[0];
1612                         *pInitTxRateIdx = RateSwitchTable11G[1];
1613
1614                         break;
1615                 }
1616
1617                 {
1618                         //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1619                         if ((pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0))
1620                         {       // Legacy mode
1621                                 if (pAd->CommonCfg.MaxTxRate <= RATE_11)
1622                                 {
1623                                         *ppTable = RateSwitchTable11B;
1624                                         *pTableSize = RateSwitchTable11B[0];
1625                                         *pInitTxRateIdx = RateSwitchTable11B[1];
1626                                 }
1627                                 else if ((pAd->CommonCfg.MaxTxRate > RATE_11) && (pAd->CommonCfg.MinTxRate > RATE_11))
1628                                 {
1629                                         *ppTable = RateSwitchTable11G;
1630                                         *pTableSize = RateSwitchTable11G[0];
1631                                         *pInitTxRateIdx = RateSwitchTable11G[1];
1632
1633                                 }
1634                                 else
1635                                 {
1636                                         *ppTable = RateSwitchTable11BG;
1637                                         *pTableSize = RateSwitchTable11BG[0];
1638                                         *pInitTxRateIdx = RateSwitchTable11BG[1];
1639                                 }
1640                                 break;
1641                         }
1642
1643                         if (pAd->LatchRfRegs.Channel <= 14)
1644                         {
1645                                 if (pAd->CommonCfg.TxStream == 1)
1646                                 {
1647                                         *ppTable = RateSwitchTable11N1S;
1648                                         *pTableSize = RateSwitchTable11N1S[0];
1649                                         *pInitTxRateIdx = RateSwitchTable11N1S[1];
1650                                         DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
1651                                 }
1652                                 else
1653                                 {
1654                                         *ppTable = RateSwitchTable11N2S;
1655                                         *pTableSize = RateSwitchTable11N2S[0];
1656                                         *pInitTxRateIdx = RateSwitchTable11N2S[1];
1657                                         DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
1658                                 }
1659                         }
1660                         else
1661                         {
1662                                 if (pAd->CommonCfg.TxStream == 1)
1663                                 {
1664                                         *ppTable = RateSwitchTable11N1S;
1665                                         *pTableSize = RateSwitchTable11N1S[0];
1666                                         *pInitTxRateIdx = RateSwitchTable11N1S[1];
1667                                         DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
1668                                 }
1669                                 else
1670                                 {
1671                                         *ppTable = RateSwitchTable11N2SForABand;
1672                                         *pTableSize = RateSwitchTable11N2SForABand[0];
1673                                         *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
1674                                         DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
1675                                 }
1676                         }
1677
1678                         DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n",
1679                                 pAd->StaActive.SupRateLen, pAd->StaActive.ExtRateLen, pAd->StaActive.SupportedPhyInfo.MCSSet[0], pAd->StaActive.SupportedPhyInfo.MCSSet[1]));
1680                 }
1681         } while(FALSE);
1682 }
1683
1684 /*
1685         ==========================================================================
1686         Description:
1687                 This routine checks if there're other APs out there capable for
1688                 roaming. Caller should call this routine only when Link up in INFRA mode
1689                 and channel quality is below CQI_GOOD_THRESHOLD.
1690
1691         IRQL = DISPATCH_LEVEL
1692
1693         Output:
1694         ==========================================================================
1695  */
1696 VOID MlmeCheckForRoaming(
1697         IN PRTMP_ADAPTER pAd,
1698         IN ULONG        Now32)
1699 {
1700         USHORT     i;
1701         BSS_TABLE  *pRoamTab = &pAd->MlmeAux.RoamTab;
1702         BSS_ENTRY  *pBss;
1703
1704         DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForRoaming\n"));
1705         // put all roaming candidates into RoamTab, and sort in RSSI order
1706         BssTableInit(pRoamTab);
1707         for (i = 0; i < pAd->ScanTab.BssNr; i++)
1708         {
1709                 pBss = &pAd->ScanTab.BssEntry[i];
1710
1711                 if ((pBss->LastBeaconRxTime + BEACON_LOST_TIME) < Now32)
1712                         continue;        // AP disappear
1713                 if (pBss->Rssi <= RSSI_THRESHOLD_FOR_ROAMING)
1714                         continue;        // RSSI too weak. forget it.
1715                 if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
1716                         continue;        // skip current AP
1717                 if (pBss->Rssi < (pAd->StaCfg.RssiSample.LastRssi0 + RSSI_DELTA))
1718                         continue;        // only AP with stronger RSSI is eligible for roaming
1719
1720                 // AP passing all above rules is put into roaming candidate table
1721                 NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
1722                 pRoamTab->BssNr += 1;
1723         }
1724
1725         if (pRoamTab->BssNr > 0)
1726         {
1727                 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1728                 if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1729                 {
1730                         pAd->RalinkCounters.PoorCQIRoamingCount ++;
1731                         DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
1732                         MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
1733                         RT28XX_MLME_HANDLER(pAd);
1734                 }
1735         }
1736         DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForRoaming(# of candidate= %d)\n",pRoamTab->BssNr));
1737 }
1738
1739 /*
1740         ==========================================================================
1741         Description:
1742                 This routine checks if there're other APs out there capable for
1743                 roaming. Caller should call this routine only when link up in INFRA mode
1744                 and channel quality is below CQI_GOOD_THRESHOLD.
1745
1746         IRQL = DISPATCH_LEVEL
1747
1748         Output:
1749         ==========================================================================
1750  */
1751 VOID MlmeCheckForFastRoaming(
1752         IN      PRTMP_ADAPTER   pAd,
1753         IN      ULONG                   Now)
1754 {
1755         USHORT          i;
1756         BSS_TABLE       *pRoamTab = &pAd->MlmeAux.RoamTab;
1757         BSS_ENTRY       *pBss;
1758
1759         DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForFastRoaming\n"));
1760         // put all roaming candidates into RoamTab, and sort in RSSI order
1761         BssTableInit(pRoamTab);
1762         for (i = 0; i < pAd->ScanTab.BssNr; i++)
1763         {
1764                 pBss = &pAd->ScanTab.BssEntry[i];
1765
1766         if ((pBss->Rssi <= -50) && (pBss->Channel == pAd->CommonCfg.Channel))
1767                         continue;        // RSSI too weak. forget it.
1768                 if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
1769                         continue;        // skip current AP
1770                 if (!SSID_EQUAL(pBss->Ssid, pBss->SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen))
1771                         continue;        // skip different SSID
1772         if (pBss->Rssi < (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) + RSSI_DELTA))
1773                         continue;        // skip AP without better RSSI
1774
1775         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));
1776                 // AP passing all above rules is put into roaming candidate table
1777                 NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
1778                 pRoamTab->BssNr += 1;
1779         }
1780
1781         if (pRoamTab->BssNr > 0)
1782         {
1783                 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1784                 if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1785                 {
1786                         pAd->RalinkCounters.PoorCQIRoamingCount ++;
1787                         DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
1788                         MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
1789                         RT28XX_MLME_HANDLER(pAd);
1790                 }
1791         }
1792         // Maybe site survey required
1793         else
1794         {
1795                 if ((pAd->StaCfg.LastScanTime + 10 * 1000) < Now)
1796                 {
1797                         // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1798                         DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming, No eligable entry, try new scan!\n"));
1799                         pAd->StaCfg.ScanCnt = 2;
1800                         pAd->StaCfg.LastScanTime = Now;
1801                         MlmeAutoScan(pAd);
1802                 }
1803         }
1804
1805     DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr));
1806 }
1807
1808 /*
1809         ==========================================================================
1810         Description:
1811                 This routine calculates TxPER, RxPER of the past N-sec period. And
1812                 according to the calculation result, ChannelQuality is calculated here
1813                 to decide if current AP is still doing the job.
1814
1815                 If ChannelQuality is not good, a ROAMing attempt may be tried later.
1816         Output:
1817                 StaCfg.ChannelQuality - 0..100
1818
1819         IRQL = DISPATCH_LEVEL
1820
1821         NOTE: This routine decide channle quality based on RX CRC error ratio.
1822                 Caller should make sure a function call to NICUpdateRawCounters(pAd)
1823                 is performed right before this routine, so that this routine can decide
1824                 channel quality based on the most up-to-date information
1825         ==========================================================================
1826  */
1827 VOID MlmeCalculateChannelQuality(
1828         IN PRTMP_ADAPTER pAd,
1829         IN ULONG Now32)
1830 {
1831         ULONG TxOkCnt, TxCnt, TxPER, TxPRR;
1832         ULONG RxCnt, RxPER;
1833         UCHAR NorRssi;
1834         CHAR  MaxRssi;
1835         ULONG BeaconLostTime = BEACON_LOST_TIME;
1836
1837         MaxRssi = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2);
1838
1839         //
1840         // calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics
1841         //
1842         TxOkCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + pAd->RalinkCounters.OneSecTxRetryOkCount;
1843         TxCnt = TxOkCnt + pAd->RalinkCounters.OneSecTxFailCount;
1844         if (TxCnt < 5)
1845         {
1846                 TxPER = 0;
1847                 TxPRR = 0;
1848         }
1849         else
1850         {
1851                 TxPER = (pAd->RalinkCounters.OneSecTxFailCount * 100) / TxCnt;
1852                 TxPRR = ((TxCnt - pAd->RalinkCounters.OneSecTxNoRetryOkCount) * 100) / TxCnt;
1853         }
1854
1855         //
1856         // calculate RX PER - don't take RxPER into consideration if too few sample
1857         //
1858         RxCnt = pAd->RalinkCounters.OneSecRxOkCnt + pAd->RalinkCounters.OneSecRxFcsErrCnt;
1859         if (RxCnt < 5)
1860                 RxPER = 0;
1861         else
1862                 RxPER = (pAd->RalinkCounters.OneSecRxFcsErrCnt * 100) / RxCnt;
1863
1864         //
1865         // decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER
1866         //
1867         if (INFRA_ON(pAd) &&
1868                 (pAd->RalinkCounters.OneSecTxNoRetryOkCount < 2) && // no heavy traffic
1869                 (pAd->StaCfg.LastBeaconRxTime + BeaconLostTime < Now32))
1870         {
1871                 DBGPRINT(RT_DEBUG_TRACE, ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n", BeaconLostTime, TxOkCnt));
1872                 pAd->Mlme.ChannelQuality = 0;
1873         }
1874         else
1875         {
1876                 // Normalize Rssi
1877                 if (MaxRssi > -40)
1878                         NorRssi = 100;
1879                 else if (MaxRssi < -90)
1880                         NorRssi = 0;
1881                 else
1882                         NorRssi = (MaxRssi + 90) * 2;
1883
1884                 // ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER        (RSSI 0..100), (TxPER 100..0), (RxPER 100..0)
1885                 pAd->Mlme.ChannelQuality = (RSSI_WEIGHTING * NorRssi +
1886                                                                    TX_WEIGHTING * (100 - TxPRR) +
1887                                                                    RX_WEIGHTING* (100 - RxPER)) / 100;
1888                 if (pAd->Mlme.ChannelQuality >= 100)
1889                         pAd->Mlme.ChannelQuality = 100;
1890         }
1891
1892 }
1893
1894 VOID MlmeSetTxRate(
1895         IN PRTMP_ADAPTER                pAd,
1896         IN PMAC_TABLE_ENTRY             pEntry,
1897         IN PRTMP_TX_RATE_SWITCH pTxRate)
1898 {
1899         UCHAR   MaxMode = MODE_OFDM;
1900
1901         MaxMode = MODE_HTGREENFIELD;
1902
1903         if (pTxRate->STBC && (pAd->StaCfg.MaxHTPhyMode.field.STBC) && (pAd->Antenna.field.TxPath == 2))
1904                 pAd->StaCfg.HTPhyMode.field.STBC = STBC_USE;
1905         else
1906                 pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
1907
1908         if (pTxRate->CurrMCS < MCS_AUTO)
1909                 pAd->StaCfg.HTPhyMode.field.MCS = pTxRate->CurrMCS;
1910
1911         if (pAd->StaCfg.HTPhyMode.field.MCS > 7)
1912                 pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
1913
1914         if (ADHOC_ON(pAd))
1915         {
1916                 // If peer adhoc is b-only mode, we can't send 11g rate.
1917                 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
1918                 pEntry->HTPhyMode.field.STBC    = STBC_NONE;
1919
1920                 //
1921                 // For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary
1922                 //
1923                 pEntry->HTPhyMode.field.MODE    = pTxRate->Mode;
1924                 pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI;
1925                 pEntry->HTPhyMode.field.MCS             = pAd->StaCfg.HTPhyMode.field.MCS;
1926
1927                 // Patch speed error in status page
1928                 pAd->StaCfg.HTPhyMode.field.MODE = pEntry->HTPhyMode.field.MODE;
1929         }
1930         else
1931         {
1932                 if (pTxRate->Mode <= MaxMode)
1933                         pAd->StaCfg.HTPhyMode.field.MODE = pTxRate->Mode;
1934
1935                 if (pTxRate->ShortGI && (pAd->StaCfg.MaxHTPhyMode.field.ShortGI))
1936                         pAd->StaCfg.HTPhyMode.field.ShortGI = GI_400;
1937                 else
1938                         pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
1939
1940                 // Reexam each bandwidth's SGI support.
1941                 if (pAd->StaCfg.HTPhyMode.field.ShortGI == GI_400)
1942                 {
1943                         if ((pEntry->HTPhyMode.field.BW == BW_20) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE)))
1944                                 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
1945                         if ((pEntry->HTPhyMode.field.BW == BW_40) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE)))
1946                                 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
1947                 }
1948
1949                 // Turn RTS/CTS rate to 6Mbps.
1950                 if ((pEntry->HTPhyMode.field.MCS == 0) && (pAd->StaCfg.HTPhyMode.field.MCS != 0))
1951                 {
1952                         pEntry->HTPhyMode.field.MCS             = pAd->StaCfg.HTPhyMode.field.MCS;
1953                         if (pAd->MacTab.fAnyBASession)
1954                         {
1955                                 AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1956                         }
1957                         else
1958                         {
1959                                 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1960                         }
1961                 }
1962                 else if ((pEntry->HTPhyMode.field.MCS == 8) && (pAd->StaCfg.HTPhyMode.field.MCS != 8))
1963                 {
1964                         pEntry->HTPhyMode.field.MCS             = pAd->StaCfg.HTPhyMode.field.MCS;
1965                         if (pAd->MacTab.fAnyBASession)
1966                         {
1967                                 AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1968                         }
1969                         else
1970                         {
1971                                 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1972                         }
1973                 }
1974                 else if ((pEntry->HTPhyMode.field.MCS != 0) && (pAd->StaCfg.HTPhyMode.field.MCS == 0))
1975                 {
1976                         AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1977
1978                 }
1979                 else if ((pEntry->HTPhyMode.field.MCS != 8) && (pAd->StaCfg.HTPhyMode.field.MCS == 8))
1980                 {
1981                         AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1982                 }
1983
1984                 pEntry->HTPhyMode.field.STBC    = pAd->StaCfg.HTPhyMode.field.STBC;
1985                 pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI;
1986                 pEntry->HTPhyMode.field.MCS             = pAd->StaCfg.HTPhyMode.field.MCS;
1987                 pEntry->HTPhyMode.field.MODE    = pAd->StaCfg.HTPhyMode.field.MODE;
1988
1989                 if ((pAd->StaCfg.MaxHTPhyMode.field.MODE == MODE_HTGREENFIELD) &&
1990                     pAd->WIFItestbed.bGreenField)
1991                     pEntry->HTPhyMode.field.MODE = MODE_HTGREENFIELD;
1992         }
1993
1994         pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1995 }
1996
1997 /*
1998         ==========================================================================
1999         Description:
2000                 This routine calculates the acumulated TxPER of eaxh TxRate. And
2001                 according to the calculation result, change CommonCfg.TxRate which
2002                 is the stable TX Rate we expect the Radio situation could sustained.
2003
2004                 CommonCfg.TxRate will change dynamically within {RATE_1/RATE_6, MaxTxRate}
2005         Output:
2006                 CommonCfg.TxRate -
2007
2008         IRQL = DISPATCH_LEVEL
2009
2010         NOTE:
2011                 call this routine every second
2012         ==========================================================================
2013  */
2014 VOID MlmeDynamicTxRateSwitching(
2015         IN PRTMP_ADAPTER pAd)
2016 {
2017         UCHAR                                   UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx;
2018         ULONG                                   i, AccuTxTotalCnt = 0, TxTotalCnt;
2019         ULONG                                   TxErrorRatio = 0;
2020         BOOLEAN                                 bTxRateChanged, bUpgradeQuality = FALSE;
2021         PRTMP_TX_RATE_SWITCH    pCurrTxRate, pNextTxRate = NULL;
2022         PUCHAR                                  pTable;
2023         UCHAR                                   TableSize = 0;
2024         UCHAR                                   InitTxRateIdx = 0, TrainUp, TrainDown;
2025         CHAR                                    Rssi, RssiOffset = 0;
2026         TX_STA_CNT1_STRUC               StaTx1;
2027         TX_STA_CNT0_STRUC               TxStaCnt0;
2028         ULONG                                   TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
2029         MAC_TABLE_ENTRY                 *pEntry;
2030
2031         //
2032         // walk through MAC table, see if need to change AP's TX rate toward each entry
2033         //
2034         for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
2035         {
2036                 pEntry = &pAd->MacTab.Content[i];
2037
2038                 // check if this entry need to switch rate automatically
2039                 if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
2040                         continue;
2041
2042                 if ((pAd->MacTab.Size == 1) || (pEntry->ValidAsDls))
2043                 {
2044 #ifdef RT2860
2045                         Rssi = RTMPMaxRssi(pAd, (CHAR)pAd->StaCfg.RssiSample.AvgRssi0, (CHAR)pAd->StaCfg.RssiSample.AvgRssi1, (CHAR)pAd->StaCfg.RssiSample.AvgRssi2);
2046 #endif
2047 #ifdef RT2870
2048                         Rssi = RTMPMaxRssi(pAd,
2049                                                            pAd->StaCfg.RssiSample.AvgRssi0,
2050                                                            pAd->StaCfg.RssiSample.AvgRssi1,
2051                                                            pAd->StaCfg.RssiSample.AvgRssi2);
2052 #endif
2053
2054                         // Update statistic counter
2055                         RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
2056                         RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
2057                         pAd->bUpdateBcnCntDone = TRUE;
2058                         TxRetransmit = StaTx1.field.TxRetransmit;
2059                         TxSuccess = StaTx1.field.TxSuccess;
2060                         TxFailCount = TxStaCnt0.field.TxFailCount;
2061                         TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
2062
2063                         pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
2064                         pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
2065                         pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
2066                         pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
2067                         pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
2068                         pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
2069
2070                         // if no traffic in the past 1-sec period, don't change TX rate,
2071                         // but clear all bad history. because the bad history may affect the next
2072                         // Chariot throughput test
2073                         AccuTxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
2074                                                  pAd->RalinkCounters.OneSecTxRetryOkCount +
2075                                                  pAd->RalinkCounters.OneSecTxFailCount;
2076
2077                         if (TxTotalCnt)
2078                                 TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
2079                 }
2080                 else
2081                 {
2082 #ifdef RT2860
2083                         Rssi = RTMPMaxRssi(pAd, (CHAR)pEntry->RssiSample.AvgRssi0, (CHAR)pEntry->RssiSample.AvgRssi1, (CHAR)pEntry->RssiSample.AvgRssi2);
2084 #endif
2085 #ifdef RT2870
2086                         if (INFRA_ON(pAd) && (i == 1))
2087                                 Rssi = RTMPMaxRssi(pAd,
2088                                                                    pAd->StaCfg.RssiSample.AvgRssi0,
2089                                                                    pAd->StaCfg.RssiSample.AvgRssi1,
2090                                                                    pAd->StaCfg.RssiSample.AvgRssi2);
2091                         else
2092                                 Rssi = RTMPMaxRssi(pAd,
2093                                                                    pEntry->RssiSample.AvgRssi0,
2094                                                                    pEntry->RssiSample.AvgRssi1,
2095                                                                    pEntry->RssiSample.AvgRssi2);
2096 #endif
2097
2098                         TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
2099                                  pEntry->OneSecTxRetryOkCount +
2100                                  pEntry->OneSecTxFailCount;
2101
2102                         if (TxTotalCnt)
2103                                 TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
2104                 }
2105
2106                 CurrRateIdx = pEntry->CurrTxRateIndex;
2107
2108                 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
2109
2110                 if (CurrRateIdx >= TableSize)
2111                 {
2112                         CurrRateIdx = TableSize - 1;
2113                 }
2114
2115                 // When switch from Fixed rate -> auto rate, the REAL TX rate might be different from pAd->CommonCfg.TxRateIndex.
2116                 // So need to sync here.
2117                 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
2118                 if ((pEntry->HTPhyMode.field.MCS != pCurrTxRate->CurrMCS)
2119                         //&& (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
2120                         )
2121                 {
2122
2123                         // Need to sync Real Tx rate and our record.
2124                         // Then return for next DRS.
2125                         pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(InitTxRateIdx+1)*5];
2126                         pEntry->CurrTxRateIndex = InitTxRateIdx;
2127                         MlmeSetTxRate(pAd, pEntry, pCurrTxRate);
2128
2129                         // reset all OneSecTx counters
2130                         RESET_ONE_SEC_TX_CNT(pEntry);
2131                         continue;
2132                 }
2133
2134                 // decide the next upgrade rate and downgrade rate, if any
2135                 if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
2136                 {
2137                         UpRateIdx = CurrRateIdx + 1;
2138                         DownRateIdx = CurrRateIdx -1;
2139                 }
2140                 else if (CurrRateIdx == 0)
2141                 {
2142                         UpRateIdx = CurrRateIdx + 1;
2143                         DownRateIdx = CurrRateIdx;
2144                 }
2145                 else if (CurrRateIdx == (TableSize - 1))
2146                 {
2147                         UpRateIdx = CurrRateIdx;
2148                         DownRateIdx = CurrRateIdx - 1;
2149                 }
2150
2151                 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
2152
2153                 if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
2154                 {
2155                         TrainUp         = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
2156                         TrainDown       = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
2157                 }
2158                 else
2159                 {
2160                         TrainUp         = pCurrTxRate->TrainUp;
2161                         TrainDown       = pCurrTxRate->TrainDown;
2162                 }
2163
2164                 //pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction;
2165
2166                 //
2167                 // Keep the last time TxRateChangeAction status.
2168                 //
2169                 pEntry->LastTimeTxRateChangeAction = pEntry->LastSecTxRateChangeAction;
2170
2171
2172
2173                 //
2174                 // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
2175                 //         (criteria copied from RT2500 for Netopia case)
2176                 //
2177                 if (TxTotalCnt <= 15)
2178                 {
2179                         CHAR    idx = 0;
2180                         UCHAR   TxRateIdx;
2181                         //UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS7 = 0, MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
2182                         UCHAR   MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0,  MCS5 =0, MCS6 = 0, MCS7 = 0;
2183                 UCHAR   MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
2184                         UCHAR   MCS20 = 0, MCS21 = 0, MCS22 = 0, MCS23 = 0; // 3*3
2185
2186                         // check the existence and index of each needed MCS
2187                         while (idx < pTable[0])
2188                         {
2189                                 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(idx+1)*5];
2190
2191                                 if (pCurrTxRate->CurrMCS == MCS_0)
2192                                 {
2193                                         MCS0 = idx;
2194                                 }
2195                                 else if (pCurrTxRate->CurrMCS == MCS_1)
2196                                 {
2197                                         MCS1 = idx;
2198                                 }
2199                                 else if (pCurrTxRate->CurrMCS == MCS_2)
2200                                 {
2201                                         MCS2 = idx;
2202                                 }
2203                                 else if (pCurrTxRate->CurrMCS == MCS_3)
2204                                 {
2205                                         MCS3 = idx;
2206                                 }
2207                                 else if (pCurrTxRate->CurrMCS == MCS_4)
2208                                 {
2209                                         MCS4 = idx;
2210                                 }
2211                     else if (pCurrTxRate->CurrMCS == MCS_5)
2212                     {
2213                         MCS5 = idx;
2214                     }
2215                     else if (pCurrTxRate->CurrMCS == MCS_6)
2216                     {
2217                         MCS6 = idx;
2218                     }
2219                                 //else if (pCurrTxRate->CurrMCS == MCS_7)
2220                                 else if ((pCurrTxRate->CurrMCS == MCS_7) && (pCurrTxRate->ShortGI == GI_800))   // prevent the highest MCS using short GI when 1T and low throughput
2221                                 {
2222                                         MCS7 = idx;
2223                                 }
2224                                 else if (pCurrTxRate->CurrMCS == MCS_12)
2225                                 {
2226                                         MCS12 = idx;
2227                                 }
2228                                 else if (pCurrTxRate->CurrMCS == MCS_13)
2229                                 {
2230                                         MCS13 = idx;
2231                                 }
2232                                 else if (pCurrTxRate->CurrMCS == MCS_14)
2233                                 {
2234                                         MCS14 = idx;
2235                                 }
2236                                 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
2237                                 {
2238                                         MCS15 = idx;
2239                                 }
2240                                 else if (pCurrTxRate->CurrMCS == MCS_20) // 3*3
2241                                 {
2242                                         MCS20 = idx;
2243                                 }
2244                                 else if (pCurrTxRate->CurrMCS == MCS_21)
2245                                 {
2246                                         MCS21 = idx;
2247                                 }
2248                                 else if (pCurrTxRate->CurrMCS == MCS_22)
2249                                 {
2250                                         MCS22 = idx;
2251                                 }
2252                                 else if (pCurrTxRate->CurrMCS == MCS_23)
2253                                 {
2254                                         MCS23 = idx;
2255                                 }
2256                                 idx ++;
2257                         }
2258
2259                         if (pAd->LatchRfRegs.Channel <= 14)
2260                         {
2261                                 if (pAd->NicConfig2.field.ExternalLNAForG)
2262                                 {
2263                                         RssiOffset = 2;
2264                                 }
2265                                 else
2266                                 {
2267                                         RssiOffset = 5;
2268                                 }
2269                         }
2270                         else
2271                         {
2272                                 if (pAd->NicConfig2.field.ExternalLNAForA)
2273                                 {
2274                                         RssiOffset = 5;
2275                                 }
2276                                 else
2277                                 {
2278                                         RssiOffset = 8;
2279                                 }
2280                         }
2281
2282                         /*if (MCS15)*/
2283                         if ((pTable == RateSwitchTable11BGN3S) ||
2284                                 (pTable == RateSwitchTable11N3S) ||
2285                                 (pTable == RateSwitchTable))
2286                         {// N mode with 3 stream // 3*3
2287                                 if (MCS23 && (Rssi >= -70))
2288                                         TxRateIdx = MCS15;
2289                                 else if (MCS22 && (Rssi >= -72))
2290                                         TxRateIdx = MCS14;
2291                     else if (MCS21 && (Rssi >= -76))
2292                                         TxRateIdx = MCS13;
2293                                 else if (MCS20 && (Rssi >= -78))
2294                                         TxRateIdx = MCS12;
2295                         else if (MCS4 && (Rssi >= -82))
2296                                 TxRateIdx = MCS4;
2297                         else if (MCS3 && (Rssi >= -84))
2298                                 TxRateIdx = MCS3;
2299                         else if (MCS2 && (Rssi >= -86))
2300                                 TxRateIdx = MCS2;
2301                         else if (MCS1 && (Rssi >= -88))
2302                                 TxRateIdx = MCS1;
2303                         else
2304                                 TxRateIdx = MCS0;
2305                 }
2306                 else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand)) // 3*3
2307                         {// N mode with 2 stream
2308                                 if (MCS15 && (Rssi >= (-70+RssiOffset)))
2309                                         TxRateIdx = MCS15;
2310                                 else if (MCS14 && (Rssi >= (-72+RssiOffset)))
2311                                         TxRateIdx = MCS14;
2312                                 else if (MCS13 && (Rssi >= (-76+RssiOffset)))
2313                                         TxRateIdx = MCS13;
2314                                 else if (MCS12 && (Rssi >= (-78+RssiOffset)))
2315                                         TxRateIdx = MCS12;
2316                                 else if (MCS4 && (Rssi >= (-82+RssiOffset)))
2317                                         TxRateIdx = MCS4;
2318                                 else if (MCS3 && (Rssi >= (-84+RssiOffset)))
2319                                         TxRateIdx = MCS3;
2320                                 else if (MCS2 && (Rssi >= (-86+RssiOffset)))
2321                                         TxRateIdx = MCS2;
2322                                 else if (MCS1 && (Rssi >= (-88+RssiOffset)))
2323                                         TxRateIdx = MCS1;
2324                                 else
2325                                         TxRateIdx = MCS0;
2326                         }
2327                         else if ((pTable == RateSwitchTable11BGN1S) || (pTable == RateSwitchTable11N1S))
2328                         {// N mode with 1 stream
2329                                 if (MCS7 && (Rssi > (-72+RssiOffset)))
2330                                         TxRateIdx = MCS7;
2331                                 else if (MCS6 && (Rssi > (-74+RssiOffset)))
2332                                         TxRateIdx = MCS6;
2333                                 else if (MCS5 && (Rssi > (-77+RssiOffset)))
2334                                         TxRateIdx = MCS5;
2335                                 else if (MCS4 && (Rssi > (-79+RssiOffset)))
2336                                         TxRateIdx = MCS4;
2337                                 else if (MCS3 && (Rssi > (-81+RssiOffset)))
2338                                         TxRateIdx = MCS3;
2339                                 else if (MCS2 && (Rssi > (-83+RssiOffset)))
2340                                         TxRateIdx = MCS2;
2341                                 else if (MCS1 && (Rssi > (-86+RssiOffset)))
2342                                         TxRateIdx = MCS1;
2343                                 else
2344                                         TxRateIdx = MCS0;
2345                         }
2346                         else
2347                         {// Legacy mode
2348                                 if (MCS7 && (Rssi > -70))
2349                                         TxRateIdx = MCS7;
2350                                 else if (MCS6 && (Rssi > -74))
2351                                         TxRateIdx = MCS6;
2352                                 else if (MCS5 && (Rssi > -78))
2353                                         TxRateIdx = MCS5;
2354                                 else if (MCS4 && (Rssi > -82))
2355                                         TxRateIdx = MCS4;
2356                                 else if (MCS4 == 0)     // for B-only mode
2357                                         TxRateIdx = MCS3;
2358                                 else if (MCS3 && (Rssi > -85))
2359                                         TxRateIdx = MCS3;
2360                                 else if (MCS2 && (Rssi > -87))
2361                                         TxRateIdx = MCS2;
2362                                 else if (MCS1 && (Rssi > -90))
2363                                         TxRateIdx = MCS1;
2364                                 else
2365                                         TxRateIdx = MCS0;
2366                         }
2367
2368                         {
2369                                 pEntry->CurrTxRateIndex = TxRateIdx;
2370                                 pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
2371                                 MlmeSetTxRate(pAd, pEntry, pNextTxRate);
2372                         }
2373
2374                         NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
2375                         NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
2376                         pEntry->fLastSecAccordingRSSI = TRUE;
2377                         // reset all OneSecTx counters
2378                         RESET_ONE_SEC_TX_CNT(pEntry);
2379
2380                         continue;
2381                 }
2382
2383                 if (pEntry->fLastSecAccordingRSSI == TRUE)
2384                 {
2385                         pEntry->fLastSecAccordingRSSI = FALSE;
2386                         pEntry->LastSecTxRateChangeAction = 0;
2387                         // reset all OneSecTx counters
2388                         RESET_ONE_SEC_TX_CNT(pEntry);
2389
2390                         continue;
2391                 }
2392
2393                 do
2394                 {
2395                         BOOLEAN bTrainUpDown = FALSE;
2396
2397                         pEntry->CurrTxRateStableTime ++;
2398
2399                         // downgrade TX quality if PER >= Rate-Down threshold
2400                         if (TxErrorRatio >= TrainDown)
2401                         {
2402                                 bTrainUpDown = TRUE;
2403                                 pEntry->TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
2404                         }
2405                         // upgrade TX quality if PER <= Rate-Up threshold
2406                         else if (TxErrorRatio <= TrainUp)
2407                         {
2408                                 bTrainUpDown = TRUE;
2409                                 bUpgradeQuality = TRUE;
2410                                 if (pEntry->TxQuality[CurrRateIdx])
2411                                         pEntry->TxQuality[CurrRateIdx] --;  // quality very good in CurrRate
2412
2413                                 if (pEntry->TxRateUpPenalty)
2414                                         pEntry->TxRateUpPenalty --;
2415                                 else if (pEntry->TxQuality[UpRateIdx])
2416                                         pEntry->TxQuality[UpRateIdx] --;    // may improve next UP rate's quality
2417                         }
2418
2419                         pEntry->PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
2420
2421                         if (bTrainUpDown)
2422                         {
2423                                 // perform DRS - consider TxRate Down first, then rate up.
2424                                 if ((CurrRateIdx != DownRateIdx) && (pEntry->TxQuality[CurrRateIdx] >= DRS_TX_QUALITY_WORST_BOUND))
2425                                 {
2426                                         pEntry->CurrTxRateIndex = DownRateIdx;
2427                                 }
2428                                 else if ((CurrRateIdx != UpRateIdx) && (pEntry->TxQuality[UpRateIdx] <= 0))
2429                                 {
2430                                         pEntry->CurrTxRateIndex = UpRateIdx;
2431                                 }
2432                         }
2433                 } while (FALSE);
2434
2435                 // if rate-up happen, clear all bad history of all TX rates
2436                 if (pEntry->CurrTxRateIndex > CurrRateIdx)
2437                 {
2438                         pEntry->CurrTxRateStableTime = 0;
2439                         pEntry->TxRateUpPenalty = 0;
2440                         pEntry->LastSecTxRateChangeAction = 1; // rate UP
2441                         NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
2442                         NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
2443
2444                         //
2445                         // For TxRate fast train up
2446                         //
2447                         if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
2448                         {
2449                                 RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
2450
2451                                 pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
2452                         }
2453                         bTxRateChanged = TRUE;
2454                 }
2455                 // if rate-down happen, only clear DownRate's bad history
2456                 else if (pEntry->CurrTxRateIndex < CurrRateIdx)
2457                 {
2458                         pEntry->CurrTxRateStableTime = 0;
2459                         pEntry->TxRateUpPenalty = 0;           // no penalty
2460                         pEntry->LastSecTxRateChangeAction = 2; // rate DOWN
2461                         pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0;
2462                         pEntry->PER[pEntry->CurrTxRateIndex] = 0;
2463
2464                         //
2465                         // For TxRate fast train down
2466                         //
2467                         if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
2468                         {
2469                                 RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
2470
2471                                 pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
2472                         }
2473                         bTxRateChanged = TRUE;
2474                 }
2475                 else
2476                 {
2477                         pEntry->LastSecTxRateChangeAction = 0; // rate no change
2478                         bTxRateChanged = FALSE;
2479                 }
2480
2481                 pEntry->LastTxOkCount = TxSuccess;
2482
2483                 // reset all OneSecTx counters
2484                 RESET_ONE_SEC_TX_CNT(pEntry);
2485
2486                 pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
2487                 if (bTxRateChanged && pNextTxRate)
2488                 {
2489                         MlmeSetTxRate(pAd, pEntry, pNextTxRate);
2490                 }
2491         }
2492 }
2493
2494 /*
2495         ========================================================================
2496         Routine Description:
2497                 Station side, Auto TxRate faster train up timer call back function.
2498
2499         Arguments:
2500                 SystemSpecific1                 - Not used.
2501                 FunctionContext                 - Pointer to our Adapter context.
2502                 SystemSpecific2                 - Not used.
2503                 SystemSpecific3                 - Not used.
2504
2505         Return Value:
2506                 None
2507
2508         ========================================================================
2509 */
2510 VOID StaQuickResponeForRateUpExec(
2511         IN PVOID SystemSpecific1,
2512         IN PVOID FunctionContext,
2513         IN PVOID SystemSpecific2,
2514         IN PVOID SystemSpecific3)
2515 {
2516         PRTMP_ADAPTER                   pAd = (PRTMP_ADAPTER)FunctionContext;
2517         UCHAR                                   UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0;
2518         ULONG                                   TxTotalCnt;
2519         ULONG                                   TxErrorRatio = 0;
2520 #ifdef RT2860
2521         BOOLEAN                                 bTxRateChanged = TRUE; //, bUpgradeQuality = FALSE;
2522 #endif
2523 #ifdef RT2870
2524         BOOLEAN                                 bTxRateChanged; //, bUpgradeQuality = FALSE;
2525 #endif
2526         PRTMP_TX_RATE_SWITCH    pCurrTxRate, pNextTxRate = NULL;
2527         PUCHAR                                  pTable;
2528         UCHAR                                   TableSize = 0;
2529         UCHAR                                   InitTxRateIdx = 0, TrainUp, TrainDown;
2530         TX_STA_CNT1_STRUC               StaTx1;
2531         TX_STA_CNT0_STRUC               TxStaCnt0;
2532         CHAR                                    Rssi, ratio;
2533         ULONG                                   TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
2534         MAC_TABLE_ENTRY                 *pEntry;
2535         ULONG                                   i;
2536
2537         pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
2538
2539     //
2540     // walk through MAC table, see if need to change AP's TX rate toward each entry
2541     //
2542         for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
2543         {
2544                 pEntry = &pAd->MacTab.Content[i];
2545
2546                 // check if this entry need to switch rate automatically
2547                 if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
2548                         continue;
2549
2550 #ifdef RT2860
2551                 //Rssi = RTMPMaxRssi(pAd, (CHAR)pAd->StaCfg.AvgRssi0, (CHAR)pAd->StaCfg.AvgRssi1, (CHAR)pAd->StaCfg.AvgRssi2);
2552             if (pAd->Antenna.field.TxPath > 1)
2553                         Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
2554                 else
2555                         Rssi = pAd->StaCfg.RssiSample.AvgRssi0;
2556 #endif
2557 #ifdef RT2870
2558                 if (INFRA_ON(pAd) && (i == 1))
2559                         Rssi = RTMPMaxRssi(pAd,
2560                                                            pAd->StaCfg.RssiSample.AvgRssi0,
2561                                                            pAd->StaCfg.RssiSample.AvgRssi1,
2562                                                            pAd->StaCfg.RssiSample.AvgRssi2);
2563                 else
2564                         Rssi = RTMPMaxRssi(pAd,
2565                                                            pEntry->RssiSample.AvgRssi0,
2566                                                            pEntry->RssiSample.AvgRssi1,
2567                                                            pEntry->RssiSample.AvgRssi2);
2568 #endif
2569
2570                 CurrRateIdx = pAd->CommonCfg.TxRateIndex;
2571
2572                         MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
2573
2574                 // decide the next upgrade rate and downgrade rate, if any
2575                 if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
2576                 {
2577                         UpRateIdx = CurrRateIdx + 1;
2578                         DownRateIdx = CurrRateIdx -1;
2579                 }
2580                 else if (CurrRateIdx == 0)
2581                 {
2582                         UpRateIdx = CurrRateIdx + 1;
2583                         DownRateIdx = CurrRateIdx;
2584                 }
2585                 else if (CurrRateIdx == (TableSize - 1))
2586                 {
2587                         UpRateIdx = CurrRateIdx;
2588                         DownRateIdx = CurrRateIdx - 1;
2589                 }
2590
2591                 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
2592
2593                 if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
2594                 {
2595                         TrainUp         = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
2596                         TrainDown       = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
2597                 }
2598                 else
2599                 {
2600                         TrainUp         = pCurrTxRate->TrainUp;
2601                         TrainDown       = pCurrTxRate->TrainDown;
2602                 }
2603
2604                 if (pAd->MacTab.Size == 1)
2605                 {
2606                         // Update statistic counter
2607                         RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
2608                         RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
2609
2610                         TxRetransmit = StaTx1.field.TxRetransmit;
2611                         TxSuccess = StaTx1.field.TxSuccess;
2612                         TxFailCount = TxStaCnt0.field.TxFailCount;
2613                         TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
2614
2615                         pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
2616                         pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
2617                         pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
2618                         pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
2619                         pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
2620                         pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
2621
2622                         if (TxTotalCnt)
2623                                 TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
2624                 }
2625                 else
2626                 {
2627                         TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
2628                                  pEntry->OneSecTxRetryOkCount +
2629                                  pEntry->OneSecTxFailCount;
2630
2631                         if (TxTotalCnt)
2632                                 TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
2633                 }
2634
2635
2636                 //
2637                 // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
2638                 //         (criteria copied from RT2500 for Netopia case)
2639                 //
2640                 if (TxTotalCnt <= 12)
2641                 {
2642                         NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
2643                         NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
2644
2645                         if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
2646                         {
2647                                 pAd->CommonCfg.TxRateIndex = DownRateIdx;
2648                                 pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
2649                         }
2650                         else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
2651                         {
2652                                 pAd->CommonCfg.TxRateIndex = UpRateIdx;
2653                         }
2654
2655                         DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: TxTotalCnt <= 15, train back to original rate \n"));
2656                         return;
2657                 }
2658
2659                 do
2660                 {
2661                         ULONG OneSecTxNoRetryOKRationCount;
2662
2663                         if (pAd->DrsCounters.LastTimeTxRateChangeAction == 0)
2664                                 ratio = 5;
2665                         else
2666                                 ratio = 4;
2667
2668                         // downgrade TX quality if PER >= Rate-Down threshold
2669                         if (TxErrorRatio >= TrainDown)
2670                         {
2671                                 pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
2672                         }
2673
2674                         pAd->DrsCounters.PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
2675
2676                         OneSecTxNoRetryOKRationCount = (TxSuccess * ratio);
2677
2678                         // perform DRS - consider TxRate Down first, then rate up.
2679                         if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
2680                         {
2681                                 if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
2682                                 {
2683                                         pAd->CommonCfg.TxRateIndex = DownRateIdx;
2684                                         pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
2685
2686                                 }
2687
2688                         }
2689                         else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
2690                         {
2691                                 if ((TxErrorRatio >= 50) || (TxErrorRatio >= TrainDown))
2692                                 {
2693
2694                                 }
2695                                 else if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
2696                                 {
2697                                         pAd->CommonCfg.TxRateIndex = UpRateIdx;
2698                                 }
2699                         }
2700                 }while (FALSE);
2701
2702                 // if rate-up happen, clear all bad history of all TX rates
2703                 if (pAd->CommonCfg.TxRateIndex > CurrRateIdx)
2704                 {
2705                         pAd->DrsCounters.TxRateUpPenalty = 0;
2706                         NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
2707                         NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
2708 #ifdef RT2870
2709                         bTxRateChanged = TRUE;
2710 #endif
2711                 }
2712                 // if rate-down happen, only clear DownRate's bad history
2713                 else if (pAd->CommonCfg.TxRateIndex < CurrRateIdx)
2714                 {
2715                         DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: --TX rate from %d to %d \n", CurrRateIdx, pAd->CommonCfg.TxRateIndex));
2716
2717                         pAd->DrsCounters.TxRateUpPenalty = 0;           // no penalty
2718                         pAd->DrsCounters.TxQuality[pAd->CommonCfg.TxRateIndex] = 0;
2719                         pAd->DrsCounters.PER[pAd->CommonCfg.TxRateIndex] = 0;
2720 #ifdef RT2870
2721                         bTxRateChanged = TRUE;
2722 #endif
2723                 }
2724                 else
2725                 {
2726                         bTxRateChanged = FALSE;
2727                 }
2728
2729                 pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pAd->CommonCfg.TxRateIndex+1)*5];
2730                 if (bTxRateChanged && pNextTxRate)
2731                 {
2732                         MlmeSetTxRate(pAd, pEntry, pNextTxRate);
2733                 }
2734         }
2735 }
2736
2737 /*
2738         ==========================================================================
2739         Description:
2740                 This routine is executed periodically inside MlmePeriodicExec() after
2741                 association with an AP.
2742                 It checks if StaCfg.Psm is consistent with user policy (recorded in
2743                 StaCfg.WindowsPowerMode). If not, enforce user policy. However,
2744                 there're some conditions to consider:
2745                 1. we don't support power-saving in ADHOC mode, so Psm=PWR_ACTIVE all
2746                    the time when Mibss==TRUE
2747                 2. When link up in INFRA mode, Psm should not be switch to PWR_SAVE
2748                    if outgoing traffic available in TxRing or MgmtRing.
2749         Output:
2750                 1. change pAd->StaCfg.Psm to PWR_SAVE or leave it untouched
2751
2752         IRQL = DISPATCH_LEVEL
2753
2754         ==========================================================================
2755  */
2756 VOID MlmeCheckPsmChange(
2757         IN PRTMP_ADAPTER pAd,
2758         IN ULONG        Now32)
2759 {
2760         ULONG   PowerMode;
2761
2762         // condition -
2763         // 1. Psm maybe ON only happen in INFRASTRUCTURE mode
2764         // 2. user wants either MAX_PSP or FAST_PSP
2765         // 3. but current psm is not in PWR_SAVE
2766         // 4. CNTL state machine is not doing SCANning
2767         // 5. no TX SUCCESS event for the past 1-sec period
2768 #ifdef NDIS51_MINIPORT
2769         if (pAd->StaCfg.WindowsPowerProfile == NdisPowerProfileBattery)
2770                 PowerMode = pAd->StaCfg.WindowsBatteryPowerMode;
2771         else
2772 #endif
2773                 PowerMode = pAd->StaCfg.WindowsPowerMode;
2774
2775         if (INFRA_ON(pAd) &&
2776                 (PowerMode != Ndis802_11PowerModeCAM) &&
2777                 (pAd->StaCfg.Psm == PWR_ACTIVE) &&
2778 #ifdef RT2860
2779                 RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP))
2780 #endif
2781 #if !defined(RT2860) && !defined(RT30xx)
2782                 (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE))
2783 #endif
2784 #ifndef RT30xx
2785         {
2786                 NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime);
2787                 pAd->RalinkCounters.RxCountSinceLastNULL = 0;
2788                 MlmeSetPsmBit(pAd, PWR_SAVE);
2789                 if (!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
2790                 {
2791                         RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
2792                 }
2793                 else
2794                 {
2795                         RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
2796                 }
2797         }
2798 #endif
2799 #ifdef RT30xx
2800 //              (! RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
2801                 (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) /*&&
2802                 (pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
2803                 (pAd->RalinkCounters.OneSecTxRetryOkCount == 0)*/)
2804         {
2805                 // add by johnli, use Rx OK data count per second to calculate throughput
2806                 // If Ttraffic is too high ( > 400 Rx per second), don't go to sleep mode. If tx rate is low, use low criteria
2807                 // Mode=CCK/MCS=3 => 11 Mbps, Mode=OFDM/MCS=3 => 18 Mbps
2808                 if (((pAd->StaCfg.HTPhyMode.field.MCS <= 3) &&
2809 /* Iverson mark
2810                                 (pAd->StaCfg.HTPhyMode.field.MODE <= MODE_OFDM) &&
2811 */
2812                                 (pAd->RalinkCounters.OneSecRxOkDataCnt < (ULONG)100)) ||
2813                         ((pAd->StaCfg.HTPhyMode.field.MCS > 3) &&
2814 /* Iverson mark
2815                         (pAd->StaCfg.HTPhyMode.field.MODE > MODE_OFDM) &&
2816 */
2817                         (pAd->RalinkCounters.OneSecRxOkDataCnt < (ULONG)400)))
2818                 {
2819                                 // Get this time
2820                         NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime);
2821                         pAd->RalinkCounters.RxCountSinceLastNULL = 0;
2822                         MlmeSetPsmBit(pAd, PWR_SAVE);
2823                         if (!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
2824                         {
2825                                 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
2826                         }
2827                         else
2828                         {
2829                                 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
2830                         }
2831                 }
2832         }
2833 #endif
2834 }
2835
2836 // IRQL = PASSIVE_LEVEL
2837 // IRQL = DISPATCH_LEVEL
2838 VOID MlmeSetPsmBit(
2839         IN PRTMP_ADAPTER pAd,
2840         IN USHORT psm)
2841 {
2842         AUTO_RSP_CFG_STRUC csr4;
2843
2844         pAd->StaCfg.Psm = psm;
2845         RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
2846         csr4.field.AckCtsPsmBit = (psm == PWR_SAVE)? 1:0;
2847         RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
2848 #ifndef RT30xx
2849         DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetPsmBit = %d\n", psm));
2850 #endif
2851 }
2852
2853 // IRQL = DISPATCH_LEVEL
2854 VOID MlmeSetTxPreamble(
2855         IN PRTMP_ADAPTER pAd,
2856         IN USHORT TxPreamble)
2857 {
2858         AUTO_RSP_CFG_STRUC csr4;
2859
2860         //
2861         // Always use Long preamble before verifiation short preamble functionality works well.
2862         // Todo: remove the following line if short preamble functionality works
2863         //
2864         //TxPreamble = Rt802_11PreambleLong;
2865
2866         RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
2867         if (TxPreamble == Rt802_11PreambleLong)
2868         {
2869                 DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= LONG PREAMBLE)\n"));
2870                 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
2871                 csr4.field.AutoResponderPreamble = 0;
2872         }
2873         else
2874         {
2875                 // NOTE: 1Mbps should always use long preamble
2876                 DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= SHORT PREAMBLE)\n"));
2877                 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
2878                 csr4.field.AutoResponderPreamble = 1;
2879         }
2880
2881         RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
2882 }
2883
2884 /*
2885     ==========================================================================
2886     Description:
2887         Update basic rate bitmap
2888     ==========================================================================
2889  */
2890
2891 VOID UpdateBasicRateBitmap(
2892     IN  PRTMP_ADAPTER   pAdapter)
2893 {
2894     INT  i, j;
2895                   /* 1  2  5.5, 11,  6,  9, 12, 18, 24, 36, 48,  54 */
2896     UCHAR rate[] = { 2, 4,  11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
2897     UCHAR *sup_p = pAdapter->CommonCfg.SupRate;
2898     UCHAR *ext_p = pAdapter->CommonCfg.ExtRate;
2899     ULONG bitmap = pAdapter->CommonCfg.BasicRateBitmap;
2900
2901
2902     /* if A mode, always use fix BasicRateBitMap */
2903     //if (pAdapter->CommonCfg.Channel == PHY_11A)
2904         if (pAdapter->CommonCfg.Channel > 14)
2905         pAdapter->CommonCfg.BasicRateBitmap = 0x150; /* 6, 12, 24M */
2906     /* End of if */
2907
2908     if (pAdapter->CommonCfg.BasicRateBitmap > 4095)
2909     {
2910         /* (2 ^ MAX_LEN_OF_SUPPORTED_RATES) -1 */
2911         return;
2912     } /* End of if */
2913
2914     for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
2915     {
2916         sup_p[i] &= 0x7f;
2917         ext_p[i] &= 0x7f;
2918     } /* End of for */
2919
2920     for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
2921     {
2922         if (bitmap & (1 << i))
2923         {
2924             for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
2925             {
2926                 if (sup_p[j] == rate[i])
2927                     sup_p[j] |= 0x80;
2928                 /* End of if */
2929             } /* End of for */
2930
2931             for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
2932             {
2933                 if (ext_p[j] == rate[i])
2934                     ext_p[j] |= 0x80;
2935                 /* End of if */
2936             } /* End of for */
2937         } /* End of if */
2938     } /* End of for */
2939 } /* End of UpdateBasicRateBitmap */
2940
2941 // IRQL = PASSIVE_LEVEL
2942 // IRQL = DISPATCH_LEVEL
2943 // bLinkUp is to identify the inital link speed.
2944 // TRUE indicates the rate update at linkup, we should not try to set the rate at 54Mbps.
2945 VOID MlmeUpdateTxRates(
2946         IN PRTMP_ADAPTER                pAd,
2947         IN      BOOLEAN                         bLinkUp,
2948         IN      UCHAR                           apidx)
2949 {
2950         int i, num;
2951         UCHAR Rate = RATE_6, MaxDesire = RATE_1, MaxSupport = RATE_1;
2952         UCHAR MinSupport = RATE_54;
2953         ULONG BasicRateBitmap = 0;
2954         UCHAR CurrBasicRate = RATE_1;
2955         UCHAR *pSupRate, SupRateLen, *pExtRate, ExtRateLen;
2956         PHTTRANSMIT_SETTING             pHtPhy = NULL;
2957         PHTTRANSMIT_SETTING             pMaxHtPhy = NULL;
2958         PHTTRANSMIT_SETTING             pMinHtPhy = NULL;
2959         BOOLEAN                                 *auto_rate_cur_p;
2960         UCHAR                                   HtMcs = MCS_AUTO;
2961
2962         // find max desired rate
2963         UpdateBasicRateBitmap(pAd);
2964
2965         num = 0;
2966         auto_rate_cur_p = NULL;
2967         for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
2968         {
2969                 switch (pAd->CommonCfg.DesireRate[i] & 0x7f)
2970                 {
2971                         case 2:  Rate = RATE_1;   num++;   break;
2972                         case 4:  Rate = RATE_2;   num++;   break;
2973                         case 11: Rate = RATE_5_5; num++;   break;
2974                         case 22: Rate = RATE_11;  num++;   break;
2975                         case 12: Rate = RATE_6;   num++;   break;
2976                         case 18: Rate = RATE_9;   num++;   break;
2977                         case 24: Rate = RATE_12;  num++;   break;
2978                         case 36: Rate = RATE_18;  num++;   break;
2979                         case 48: Rate = RATE_24;  num++;   break;
2980                         case 72: Rate = RATE_36;  num++;   break;
2981                         case 96: Rate = RATE_48;  num++;   break;
2982                         case 108: Rate = RATE_54; num++;   break;
2983                         //default: Rate = RATE_1;   break;
2984                 }
2985                 if (MaxDesire < Rate)  MaxDesire = Rate;
2986         }
2987
2988 //===========================================================================
2989 //===========================================================================
2990         {
2991                 pHtPhy          = &pAd->StaCfg.HTPhyMode;
2992                 pMaxHtPhy       = &pAd->StaCfg.MaxHTPhyMode;
2993                 pMinHtPhy       = &pAd->StaCfg.MinHTPhyMode;
2994
2995                 auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
2996                 HtMcs           = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
2997
2998                 if ((pAd->StaCfg.BssType == BSS_ADHOC) &&
2999                         (pAd->CommonCfg.PhyMode == PHY_11B) &&
3000                         (MaxDesire > RATE_11))
3001                 {
3002                         MaxDesire = RATE_11;
3003                 }
3004         }
3005
3006         pAd->CommonCfg.MaxDesiredRate = MaxDesire;
3007         pMinHtPhy->word = 0;
3008         pMaxHtPhy->word = 0;
3009         pHtPhy->word = 0;
3010
3011         // Auto rate switching is enabled only if more than one DESIRED RATES are
3012         // specified; otherwise disabled
3013         if (num <= 1)
3014         {
3015                 *auto_rate_cur_p = FALSE;
3016         }
3017         else
3018         {
3019                 *auto_rate_cur_p = TRUE;
3020         }
3021
3022 #if 1
3023         if (HtMcs != MCS_AUTO)
3024         {
3025                 *auto_rate_cur_p = FALSE;
3026         }
3027         else
3028         {
3029                 *auto_rate_cur_p = TRUE;
3030         }
3031 #endif
3032
3033         if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
3034         {
3035                 pSupRate = &pAd->StaActive.SupRate[0];
3036                 pExtRate = &pAd->StaActive.ExtRate[0];
3037                 SupRateLen = pAd->StaActive.SupRateLen;
3038                 ExtRateLen = pAd->StaActive.ExtRateLen;
3039         }
3040         else
3041         {
3042                 pSupRate = &pAd->CommonCfg.SupRate[0];
3043                 pExtRate = &pAd->CommonCfg.ExtRate[0];
3044                 SupRateLen = pAd->CommonCfg.SupRateLen;
3045                 ExtRateLen = pAd->CommonCfg.ExtRateLen;
3046         }
3047
3048         // find max supported rate
3049         for (i=0; i<SupRateLen; i++)
3050         {
3051                 switch (pSupRate[i] & 0x7f)
3052                 {
3053                         case 2:   Rate = RATE_1;        if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0001;       break;
3054                         case 4:   Rate = RATE_2;        if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0002;       break;
3055                         case 11:  Rate = RATE_5_5;      if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0004;       break;
3056                         case 22:  Rate = RATE_11;       if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0008;       break;
3057                         case 12:  Rate = RATE_6;        /*if (pSupRate[i] & 0x80)*/  BasicRateBitmap |= 0x0010;  break;
3058                         case 18:  Rate = RATE_9;        if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0020;       break;
3059                         case 24:  Rate = RATE_12;       /*if (pSupRate[i] & 0x80)*/  BasicRateBitmap |= 0x0040;  break;
3060                         case 36:  Rate = RATE_18;       if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0080;       break;
3061                         case 48:  Rate = RATE_24;       /*if (pSupRate[i] & 0x80)*/  BasicRateBitmap |= 0x0100;  break;
3062                         case 72:  Rate = RATE_36;       if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0200;       break;
3063                         case 96:  Rate = RATE_48;       if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0400;       break;
3064                         case 108: Rate = RATE_54;       if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0800;       break;
3065                         default:  Rate = RATE_1;        break;
3066                 }
3067                 if (MaxSupport < Rate)  MaxSupport = Rate;
3068
3069                 if (MinSupport > Rate) MinSupport = Rate;
3070         }
3071
3072         for (i=0; i<ExtRateLen; i++)
3073         {
3074                 switch (pExtRate[i] & 0x7f)
3075                 {
3076                         case 2:   Rate = RATE_1;        if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0001;       break;
3077                         case 4:   Rate = RATE_2;        if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0002;       break;
3078                         case 11:  Rate = RATE_5_5;      if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0004;       break;
3079                         case 22:  Rate = RATE_11;       if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0008;       break;
3080                         case 12:  Rate = RATE_6;        /*if (pExtRate[i] & 0x80)*/  BasicRateBitmap |= 0x0010;  break;
3081                         case 18:  Rate = RATE_9;        if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0020;       break;
3082                         case 24:  Rate = RATE_12;       /*if (pExtRate[i] & 0x80)*/  BasicRateBitmap |= 0x0040;  break;
3083                         case 36:  Rate = RATE_18;       if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0080;       break;
3084                         case 48:  Rate = RATE_24;       /*if (pExtRate[i] & 0x80)*/  BasicRateBitmap |= 0x0100;  break;
3085                         case 72:  Rate = RATE_36;       if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0200;       break;
3086                         case 96:  Rate = RATE_48;       if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0400;       break;
3087                         case 108: Rate = RATE_54;       if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0800;       break;
3088                         default:  Rate = RATE_1;        break;
3089                 }
3090                 if (MaxSupport < Rate)  MaxSupport = Rate;
3091
3092                 if (MinSupport > Rate) MinSupport = Rate;
3093         }
3094
3095         RTMP_IO_WRITE32(pAd, LEGACY_BASIC_RATE, BasicRateBitmap);
3096
3097         // calculate the exptected ACK rate for each TX rate. This info is used to caculate
3098         // the DURATION field of outgoing uniicast DATA/MGMT frame
3099         for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
3100         {
3101                 if (BasicRateBitmap & (0x01 << i))
3102                         CurrBasicRate = (UCHAR)i;
3103                 pAd->CommonCfg.ExpectedACKRate[i] = CurrBasicRate;
3104         }
3105
3106         DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateTxRates[MaxSupport = %d] = MaxDesire %d Mbps\n", RateIdToMbps[MaxSupport], RateIdToMbps[MaxDesire]));
3107         // max tx rate = min {max desire rate, max supported rate}
3108         if (MaxSupport < MaxDesire)
3109                 pAd->CommonCfg.MaxTxRate = MaxSupport;
3110         else
3111                 pAd->CommonCfg.MaxTxRate = MaxDesire;
3112
3113         pAd->CommonCfg.MinTxRate = MinSupport;
3114         if (*auto_rate_cur_p)
3115         {
3116                 short dbm = 0;
3117
3118                 dbm = pAd->StaCfg.RssiSample.AvgRssi0 - pAd->BbpRssiToDbmDelta;
3119
3120                 if (bLinkUp == TRUE)
3121                         pAd->CommonCfg.TxRate = RATE_24;
3122                 else
3123                         pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
3124
3125                 if (dbm < -75)
3126                         pAd->CommonCfg.TxRate = RATE_11;
3127                 else if (dbm < -70)
3128                         pAd->CommonCfg.TxRate = RATE_24;
3129
3130                 // should never exceed MaxTxRate (consider 11B-only mode)
3131                 if (pAd->CommonCfg.TxRate > pAd->CommonCfg.MaxTxRate)
3132                         pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
3133
3134                 pAd->CommonCfg.TxRateIndex = 0;
3135         }
3136         else
3137         {
3138                 pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
3139                 pHtPhy->field.MCS       = (pAd->CommonCfg.MaxTxRate > 3) ? (pAd->CommonCfg.MaxTxRate - 4) : pAd->CommonCfg.MaxTxRate;
3140                 pHtPhy->field.MODE      = (pAd->CommonCfg.MaxTxRate > 3) ? MODE_OFDM : MODE_CCK;
3141
3142                 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC    = pHtPhy->field.STBC;
3143                 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI = pHtPhy->field.ShortGI;
3144                 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS             = pHtPhy->field.MCS;
3145                 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE    = pHtPhy->field.MODE;
3146         }
3147
3148         if (pAd->CommonCfg.TxRate <= RATE_11)
3149         {
3150                 pMaxHtPhy->field.MODE = MODE_CCK;
3151                 pMaxHtPhy->field.MCS = pAd->CommonCfg.TxRate;
3152                 pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;
3153         }
3154         else
3155         {
3156                 pMaxHtPhy->field.MODE = MODE_OFDM;
3157                 pMaxHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.TxRate];
3158                 if (pAd->CommonCfg.MinTxRate >= RATE_6 && (pAd->CommonCfg.MinTxRate <= RATE_54))
3159                         {pMinHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MinTxRate];}
3160                 else
3161                         {pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;}
3162         }
3163
3164         pHtPhy->word = (pMaxHtPhy->word);
3165         if (bLinkUp && (pAd->OpMode == OPMODE_STA))
3166         {
3167                         pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word = pHtPhy->word;
3168                         pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word = pMaxHtPhy->word;
3169                         pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word = pMinHtPhy->word;
3170         }
3171         else
3172         {
3173                 switch (pAd->CommonCfg.PhyMode)
3174                 {
3175                         case PHY_11BG_MIXED:
3176                         case PHY_11B:
3177                         case PHY_11BGN_MIXED:
3178                                 pAd->CommonCfg.MlmeRate = RATE_1;
3179                                 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
3180                                 pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
3181                                 pAd->CommonCfg.RtsRate = RATE_11;
3182                                 break;
3183                         case PHY_11G:
3184                         case PHY_11A:
3185                         case PHY_11AGN_MIXED:
3186                         case PHY_11GN_MIXED:
3187                         case PHY_11N_2_4G:
3188                         case PHY_11AN_MIXED:
3189                         case PHY_11N_5G:
3190                                 pAd->CommonCfg.MlmeRate = RATE_6;
3191                                 pAd->CommonCfg.RtsRate = RATE_6;
3192                                 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
3193                                 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
3194                                 break;
3195                         case PHY_11ABG_MIXED:
3196                         case PHY_11ABGN_MIXED:
3197                                 if (pAd->CommonCfg.Channel <= 14)
3198                                 {
3199                                         pAd->CommonCfg.MlmeRate = RATE_1;
3200                                         pAd->CommonCfg.RtsRate = RATE_1;
3201                                         pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
3202                                         pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
3203                                 }
3204                                 else
3205                                 {
3206                                         pAd->CommonCfg.MlmeRate = RATE_6;
3207                                         pAd->CommonCfg.RtsRate = RATE_6;
3208                                         pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
3209                                         pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
3210                                 }
3211                                 break;
3212                         default: // error
3213                                 pAd->CommonCfg.MlmeRate = RATE_6;
3214                                 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
3215                                 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
3216                                 pAd->CommonCfg.RtsRate = RATE_1;
3217                                 break;
3218                 }
3219                 //
3220                 // Keep Basic Mlme Rate.
3221                 //
3222                 pAd->MacTab.Content[MCAST_WCID].HTPhyMode.word = pAd->CommonCfg.MlmeTransmit.word;
3223                 if (pAd->CommonCfg.MlmeTransmit.field.MODE == MODE_OFDM)
3224                         pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[RATE_24];
3225                 else
3226                         pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = RATE_1;
3227                 pAd->CommonCfg.BasicMlmeRate = pAd->CommonCfg.MlmeRate;
3228         }
3229
3230         DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n",
3231                          RateIdToMbps[MaxDesire], RateIdToMbps[MaxSupport], RateIdToMbps[pAd->CommonCfg.MaxTxRate], RateIdToMbps[pAd->CommonCfg.MinTxRate],
3232                          /*OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)*/*auto_rate_cur_p));
3233         DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n",
3234                          RateIdToMbps[pAd->CommonCfg.TxRate], RateIdToMbps[pAd->CommonCfg.RtsRate], BasicRateBitmap));
3235         DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateTxRates (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n",
3236                          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 ));
3237 }
3238
3239 /*
3240         ==========================================================================
3241         Description:
3242                 This function update HT Rate setting.
3243                 Input Wcid value is valid for 2 case :
3244                 1. it's used for Station in infra mode that copy AP rate to Mactable.
3245                 2. OR Station   in adhoc mode to copy peer's HT rate to Mactable.
3246
3247         IRQL = DISPATCH_LEVEL
3248
3249         ==========================================================================
3250  */
3251 VOID MlmeUpdateHtTxRates(
3252         IN PRTMP_ADAPTER                pAd,
3253         IN      UCHAR                           apidx)
3254 {
3255         UCHAR   StbcMcs; //j, StbcMcs, bitmask;
3256         CHAR    i; // 3*3
3257         RT_HT_CAPABILITY        *pRtHtCap = NULL;
3258         RT_HT_PHY_INFO          *pActiveHtPhy = NULL;
3259         ULONG           BasicMCS;
3260         UCHAR j, bitmask;
3261         PRT_HT_PHY_INFO                 pDesireHtPhy = NULL;
3262         PHTTRANSMIT_SETTING             pHtPhy = NULL;
3263         PHTTRANSMIT_SETTING             pMaxHtPhy = NULL;
3264         PHTTRANSMIT_SETTING             pMinHtPhy = NULL;
3265         BOOLEAN                                 *auto_rate_cur_p;
3266
3267         DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates===> \n"));
3268
3269         auto_rate_cur_p = NULL;
3270
3271         {
3272                 pDesireHtPhy    = &pAd->StaCfg.DesiredHtPhyInfo;
3273                 pActiveHtPhy    = &pAd->StaCfg.DesiredHtPhyInfo;
3274                 pHtPhy          = &pAd->StaCfg.HTPhyMode;
3275                 pMaxHtPhy       = &pAd->StaCfg.MaxHTPhyMode;
3276                 pMinHtPhy       = &pAd->StaCfg.MinHTPhyMode;
3277
3278                 auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
3279         }
3280
3281         if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
3282         {
3283                 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
3284                         return;
3285
3286                 pRtHtCap = &pAd->StaActive.SupportedHtPhy;
3287                 pActiveHtPhy = &pAd->StaActive.SupportedPhyInfo;
3288                 StbcMcs = (UCHAR)pAd->MlmeAux.AddHtInfo.AddHtInfo3.StbcMcs;
3289                 BasicMCS =pAd->MlmeAux.AddHtInfo.MCSSet[0]+(pAd->MlmeAux.AddHtInfo.MCSSet[1]<<8)+(StbcMcs<<16);
3290                 if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
3291                         pMaxHtPhy->field.STBC = STBC_USE;
3292                 else
3293                         pMaxHtPhy->field.STBC = STBC_NONE;
3294         }
3295         else
3296         {
3297                 if (pDesireHtPhy->bHtEnable == FALSE)
3298                         return;
3299
3300                 pRtHtCap = &pAd->CommonCfg.DesiredHtPhy;
3301                 StbcMcs = (UCHAR)pAd->CommonCfg.AddHTInfo.AddHtInfo3.StbcMcs;
3302                 BasicMCS = pAd->CommonCfg.AddHTInfo.MCSSet[0]+(pAd->CommonCfg.AddHTInfo.MCSSet[1]<<8)+(StbcMcs<<16);
3303                 if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
3304                         pMaxHtPhy->field.STBC = STBC_USE;
3305                 else
3306                         pMaxHtPhy->field.STBC = STBC_NONE;
3307         }
3308
3309         // Decide MAX ht rate.
3310         if ((pRtHtCap->GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
3311                 pMaxHtPhy->field.MODE = MODE_HTGREENFIELD;
3312         else
3313                 pMaxHtPhy->field.MODE = MODE_HTMIX;
3314
3315     if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth) && (pRtHtCap->ChannelWidth))
3316                 pMaxHtPhy->field.BW = BW_40;
3317         else
3318                 pMaxHtPhy->field.BW = BW_20;
3319
3320     if (pMaxHtPhy->field.BW == BW_20)
3321                 pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 & pRtHtCap->ShortGIfor20);
3322         else
3323                 pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 & pRtHtCap->ShortGIfor40);
3324
3325         for (i=23; i>=0; i--) // 3*3
3326         {
3327                 j = i/8;
3328                 bitmask = (1<<(i-(j*8)));
3329
3330                 if ((pActiveHtPhy->MCSSet[j] & bitmask) && (pDesireHtPhy->MCSSet[j] & bitmask))
3331                 {
3332                         pMaxHtPhy->field.MCS = i;
3333                         break;
3334                 }
3335
3336                 if (i==0)
3337                         break;
3338         }
3339
3340         // Copy MIN ht rate.  rt2860???
3341         pMinHtPhy->field.BW = BW_20;
3342         pMinHtPhy->field.MCS = 0;
3343         pMinHtPhy->field.STBC = 0;
3344         pMinHtPhy->field.ShortGI = 0;
3345         //If STA assigns fixed rate. update to fixed here.
3346         if ( (pAd->OpMode == OPMODE_STA) && (pDesireHtPhy->MCSSet[0] != 0xff))
3347         {
3348                 if (pDesireHtPhy->MCSSet[4] != 0)
3349                 {
3350                         pMaxHtPhy->field.MCS = 32;
3351                         pMinHtPhy->field.MCS = 32;
3352                         DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n",pMinHtPhy->field.MCS));
3353                 }
3354
3355                 for (i=23; (CHAR)i >= 0; i--) // 3*3
3356                 {
3357                         j = i/8;
3358                         bitmask = (1<<(i-(j*8)));
3359                         if ( (pDesireHtPhy->MCSSet[j] & bitmask) && (pActiveHtPhy->MCSSet[j] & bitmask))
3360                         {
3361                                 pMaxHtPhy->field.MCS = i;
3362                                 pMinHtPhy->field.MCS = i;
3363                                 break;
3364                         }
3365                         if (i==0)
3366                                 break;
3367                 }
3368         }
3369
3370         // Decide ht rate
3371         pHtPhy->field.STBC = pMaxHtPhy->field.STBC;
3372         pHtPhy->field.BW = pMaxHtPhy->field.BW;
3373         pHtPhy->field.MODE = pMaxHtPhy->field.MODE;
3374         pHtPhy->field.MCS = pMaxHtPhy->field.MCS;
3375         pHtPhy->field.ShortGI = pMaxHtPhy->field.ShortGI;
3376
3377         // use default now. rt2860
3378         if (pDesireHtPhy->MCSSet[0] != 0xff)
3379                 *auto_rate_cur_p = FALSE;
3380         else
3381                 *auto_rate_cur_p = TRUE;
3382
3383         DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateHtTxRates<---.AMsduSize = %d  \n", pAd->CommonCfg.DesiredHtPhy.AmsduSize ));
3384         DBGPRINT(RT_DEBUG_TRACE,("TX: MCS[0] = %x (choose %d), BW = %d, ShortGI = %d, MODE = %d,  \n", pActiveHtPhy->MCSSet[0],pHtPhy->field.MCS,
3385                 pHtPhy->field.BW, pHtPhy->field.ShortGI, pHtPhy->field.MODE));
3386         DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== \n"));
3387 }
3388
3389 // IRQL = DISPATCH_LEVEL
3390 VOID MlmeRadioOff(
3391         IN PRTMP_ADAPTER pAd)
3392 {
3393         RT28XX_MLME_RADIO_OFF(pAd);
3394 }
3395
3396 // IRQL = DISPATCH_LEVEL
3397 VOID MlmeRadioOn(
3398         IN PRTMP_ADAPTER pAd)
3399 {
3400         RT28XX_MLME_RADIO_ON(pAd);
3401 }
3402
3403 // ===========================================================================================
3404 // bss_table.c
3405 // ===========================================================================================
3406
3407
3408 /*! \brief initialize BSS table
3409  *      \param p_tab pointer to the table
3410  *      \return none
3411  *      \pre
3412  *      \post
3413
3414  IRQL = PASSIVE_LEVEL
3415  IRQL = DISPATCH_LEVEL
3416
3417  */
3418 VOID BssTableInit(
3419         IN BSS_TABLE *Tab)
3420 {
3421         int i;
3422
3423         Tab->BssNr = 0;
3424     Tab->BssOverlapNr = 0;
3425         for (i = 0; i < MAX_LEN_OF_BSS_TABLE; i++)
3426         {
3427                 NdisZeroMemory(&Tab->BssEntry[i], sizeof(BSS_ENTRY));
3428                 Tab->BssEntry[i].Rssi = -127;   // initial the rssi as a minimum value
3429         }
3430 }
3431
3432 VOID BATableInit(
3433         IN PRTMP_ADAPTER pAd,
3434     IN BA_TABLE *Tab)
3435 {
3436         int i;
3437
3438         Tab->numAsOriginator = 0;
3439         Tab->numAsRecipient = 0;
3440         NdisAllocateSpinLock(&pAd->BATabLock);
3441         for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++)
3442         {
3443                 Tab->BARecEntry[i].REC_BA_Status = Recipient_NONE;
3444                 NdisAllocateSpinLock(&(Tab->BARecEntry[i].RxReRingLock));
3445         }
3446         for (i = 0; i < MAX_LEN_OF_BA_ORI_TABLE; i++)
3447         {
3448                 Tab->BAOriEntry[i].ORI_BA_Status = Originator_NONE;
3449         }
3450 }
3451
3452 /*! \brief search the BSS table by SSID
3453  *      \param p_tab pointer to the bss table
3454  *      \param ssid SSID string
3455  *      \return index of the table, BSS_NOT_FOUND if not in the table
3456  *      \pre
3457  *      \post
3458  *      \note search by sequential search
3459
3460  IRQL = DISPATCH_LEVEL
3461
3462  */
3463 ULONG BssTableSearch(
3464         IN BSS_TABLE *Tab,
3465         IN PUCHAR        pBssid,
3466         IN UCHAR         Channel)
3467 {
3468         UCHAR i;
3469
3470         for (i = 0; i < Tab->BssNr; i++)
3471         {
3472                 //
3473                 // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
3474                 // We should distinguish this case.
3475                 //
3476                 if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
3477                          ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
3478                         MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid))
3479                 {
3480                         return i;
3481                 }
3482         }
3483         return (ULONG)BSS_NOT_FOUND;
3484 }
3485
3486 ULONG BssSsidTableSearch(
3487         IN BSS_TABLE *Tab,
3488         IN PUCHAR        pBssid,
3489         IN PUCHAR        pSsid,
3490         IN UCHAR         SsidLen,
3491         IN UCHAR         Channel)
3492 {
3493         UCHAR i;
3494
3495         for (i = 0; i < Tab->BssNr; i++)
3496         {
3497                 //
3498                 // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
3499                 // We should distinguish this case.
3500                 //
3501                 if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
3502                          ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
3503                         MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid) &&
3504                         SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen))
3505                 {
3506                         return i;
3507                 }
3508         }
3509         return (ULONG)BSS_NOT_FOUND;
3510 }
3511
3512 ULONG BssTableSearchWithSSID(
3513         IN BSS_TABLE *Tab,
3514         IN PUCHAR        Bssid,
3515         IN PUCHAR        pSsid,
3516         IN UCHAR         SsidLen,
3517         IN UCHAR         Channel)
3518 {
3519         UCHAR i;
3520
3521         for (i = 0; i < Tab->BssNr; i++)
3522         {
3523                 if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
3524                         ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
3525                         MAC_ADDR_EQUAL(&(Tab->BssEntry[i].Bssid), Bssid) &&
3526                         (SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen) ||
3527                         (NdisEqualMemory(pSsid, ZeroSsid, SsidLen)) ||
3528                         (NdisEqualMemory(Tab->BssEntry[i].Ssid, ZeroSsid, Tab->BssEntry[i].SsidLen))))
3529                 {
3530                         return i;
3531                 }
3532         }
3533         return (ULONG)BSS_NOT_FOUND;
3534 }
3535
3536 // IRQL = DISPATCH_LEVEL
3537 VOID BssTableDeleteEntry(
3538         IN OUT  BSS_TABLE *Tab,
3539         IN              PUCHAR    pBssid,
3540         IN              UCHAR     Channel)
3541 {
3542         UCHAR i, j;
3543
3544         for (i = 0; i < Tab->BssNr; i++)
3545         {
3546                 if ((Tab->BssEntry[i].Channel == Channel) &&
3547                         (MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid)))
3548                 {
3549                         for (j = i; j < Tab->BssNr - 1; j++)
3550                         {
3551                                 NdisMoveMemory(&(Tab->BssEntry[j]), &(Tab->BssEntry[j + 1]), sizeof(BSS_ENTRY));
3552                         }
3553                         NdisZeroMemory(&(Tab->BssEntry[Tab->BssNr - 1]), sizeof(BSS_ENTRY));
3554                         Tab->BssNr -= 1;
3555                         return;
3556                 }
3557         }
3558 }
3559
3560 /*
3561         ========================================================================
3562         Routine Description:
3563                 Delete the Originator Entry in BAtable. Or decrease numAs Originator by 1 if needed.
3564
3565         Arguments:
3566         // IRQL = DISPATCH_LEVEL
3567         ========================================================================
3568 */
3569 VOID BATableDeleteORIEntry(
3570         IN OUT  PRTMP_ADAPTER pAd,
3571         IN              BA_ORI_ENTRY    *pBAORIEntry)
3572 {
3573
3574         if (pBAORIEntry->ORI_BA_Status != Originator_NONE)
3575         {
3576                 NdisAcquireSpinLock(&pAd->BATabLock);
3577                 if (pBAORIEntry->ORI_BA_Status == Originator_Done)
3578                 {
3579                         pAd->BATable.numAsOriginator -= 1;
3580                         DBGPRINT(RT_DEBUG_TRACE, ("BATableDeleteORIEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient));
3581                         // Erase Bitmap flag.
3582                 }
3583                 pAd->MacTab.Content[pBAORIEntry->Wcid].TXBAbitmap &= (~(1<<(pBAORIEntry->TID) ));       // If STA mode,  erase flag here
3584                 pAd->MacTab.Content[pBAORIEntry->Wcid].BAOriWcidArray[pBAORIEntry->TID] = 0;    // If STA mode,  erase flag here
3585                 pBAORIEntry->ORI_BA_Status = Originator_NONE;
3586                 pBAORIEntry->Token = 1;
3587                 // Not clear Sequence here.
3588                 NdisReleaseSpinLock(&pAd->BATabLock);
3589         }
3590 }
3591
3592 /*! \brief
3593  *      \param
3594  *      \return
3595  *      \pre
3596  *      \post
3597
3598  IRQL = DISPATCH_LEVEL
3599
3600  */
3601 VOID BssEntrySet(
3602         IN PRTMP_ADAPTER        pAd,
3603         OUT BSS_ENTRY *pBss,
3604         IN PUCHAR pBssid,
3605         IN CHAR Ssid[],
3606         IN UCHAR SsidLen,
3607         IN UCHAR BssType,
3608         IN USHORT BeaconPeriod,
3609         IN PCF_PARM pCfParm,
3610         IN USHORT AtimWin,
3611         IN USHORT CapabilityInfo,
3612         IN UCHAR SupRate[],
3613         IN UCHAR SupRateLen,
3614         IN UCHAR ExtRate[],
3615         IN UCHAR ExtRateLen,
3616         IN HT_CAPABILITY_IE *pHtCapability,
3617         IN ADD_HT_INFO_IE *pAddHtInfo,  // AP might use this additional ht info IE
3618         IN UCHAR                        HtCapabilityLen,
3619         IN UCHAR                        AddHtInfoLen,
3620         IN UCHAR                        NewExtChanOffset,
3621         IN UCHAR Channel,
3622         IN CHAR Rssi,
3623         IN LARGE_INTEGER TimeStamp,
3624         IN UCHAR CkipFlag,
3625         IN PEDCA_PARM pEdcaParm,
3626         IN PQOS_CAPABILITY_PARM pQosCapability,
3627         IN PQBSS_LOAD_PARM pQbssLoad,
3628         IN USHORT LengthVIE,
3629         IN PNDIS_802_11_VARIABLE_IEs pVIE)
3630 {
3631         COPY_MAC_ADDR(pBss->Bssid, pBssid);
3632         // Default Hidden SSID to be TRUE, it will be turned to FALSE after coping SSID
3633         pBss->Hidden = 1;
3634         if (SsidLen > 0)
3635         {
3636                 // For hidden SSID AP, it might send beacon with SSID len equal to 0
3637                 // Or send beacon /probe response with SSID len matching real SSID length,
3638                 // but SSID is all zero. such as "00-00-00-00" with length 4.
3639                 // We have to prevent this case overwrite correct table
3640                 if (NdisEqualMemory(Ssid, ZeroSsid, SsidLen) == 0)
3641                 {
3642                     NdisZeroMemory(pBss->Ssid, MAX_LEN_OF_SSID);
3643                         NdisMoveMemory(pBss->Ssid, Ssid, SsidLen);
3644                         pBss->SsidLen = SsidLen;
3645                         pBss->Hidden = 0;
3646                 }
3647         }
3648         else
3649                 pBss->SsidLen = 0;
3650         pBss->BssType = BssType;
3651         pBss->BeaconPeriod = BeaconPeriod;
3652         if (BssType == BSS_INFRA)
3653         {
3654                 if (pCfParm->bValid)
3655                 {
3656                         pBss->CfpCount = pCfParm->CfpCount;
3657                         pBss->CfpPeriod = pCfParm->CfpPeriod;
3658                         pBss->CfpMaxDuration = pCfParm->CfpMaxDuration;
3659                         pBss->CfpDurRemaining = pCfParm->CfpDurRemaining;
3660                 }
3661         }
3662         else
3663         {
3664                 pBss->AtimWin = AtimWin;
3665         }
3666
3667         pBss->CapabilityInfo = CapabilityInfo;
3668         // The privacy bit indicate security is ON, it maight be WEP, TKIP or AES
3669         // Combine with AuthMode, they will decide the connection methods.
3670         pBss->Privacy = CAP_IS_PRIVACY_ON(pBss->CapabilityInfo);
3671         ASSERT(SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
3672         if (SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES)
3673                 NdisMoveMemory(pBss->SupRate, SupRate, SupRateLen);
3674         else
3675                 NdisMoveMemory(pBss->SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES);
3676         pBss->SupRateLen = SupRateLen;
3677         ASSERT(ExtRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
3678         NdisMoveMemory(pBss->ExtRate, ExtRate, ExtRateLen);
3679         NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen);
3680         NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
3681         pBss->NewExtChanOffset = NewExtChanOffset;
3682         pBss->ExtRateLen = ExtRateLen;
3683         pBss->Channel = Channel;
3684         pBss->CentralChannel = Channel;
3685         pBss->Rssi = Rssi;
3686         // Update CkipFlag. if not exists, the value is 0x0
3687         pBss->CkipFlag = CkipFlag;
3688
3689         // New for microsoft Fixed IEs
3690         NdisMoveMemory(pBss->FixIEs.Timestamp, &TimeStamp, 8);
3691         pBss->FixIEs.BeaconInterval = BeaconPeriod;
3692         pBss->FixIEs.Capabilities = CapabilityInfo;
3693
3694         // New for microsoft Variable IEs
3695         if (LengthVIE != 0)
3696         {
3697                 pBss->VarIELen = LengthVIE;
3698                 NdisMoveMemory(pBss->VarIEs, pVIE, pBss->VarIELen);
3699         }
3700         else
3701         {
3702                 pBss->VarIELen = 0;
3703         }
3704
3705         pBss->AddHtInfoLen = 0;
3706         pBss->HtCapabilityLen = 0;
3707
3708         if (HtCapabilityLen> 0)
3709         {
3710                 pBss->HtCapabilityLen = HtCapabilityLen;
3711                 NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen);
3712                 if (AddHtInfoLen > 0)
3713                 {
3714                         pBss->AddHtInfoLen = AddHtInfoLen;
3715                         NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
3716
3717                                 if ((pAddHtInfo->ControlChan > 2)&& (pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
3718                                 {
3719                                         pBss->CentralChannel = pAddHtInfo->ControlChan - 2;
3720                                 }
3721                                 else if ((pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
3722                                 {
3723                                                 pBss->CentralChannel = pAddHtInfo->ControlChan + 2;
3724                                 }
3725                 }
3726         }
3727
3728         BssCipherParse(pBss);
3729
3730         // new for QOS
3731         if (pEdcaParm)
3732                 NdisMoveMemory(&pBss->EdcaParm, pEdcaParm, sizeof(EDCA_PARM));
3733         else
3734                 pBss->EdcaParm.bValid = FALSE;
3735         if (pQosCapability)
3736                 NdisMoveMemory(&pBss->QosCapability, pQosCapability, sizeof(QOS_CAPABILITY_PARM));
3737         else
3738                 pBss->QosCapability.bValid = FALSE;
3739         if (pQbssLoad)
3740                 NdisMoveMemory(&pBss->QbssLoad, pQbssLoad, sizeof(QBSS_LOAD_PARM));
3741         else
3742                 pBss->QbssLoad.bValid = FALSE;
3743
3744         {
3745                 PEID_STRUCT     pEid;
3746                 USHORT          Length = 0;
3747
3748
3749                 NdisZeroMemory(&pBss->WpaIE.IE[0], MAX_CUSTOM_LEN);
3750                 NdisZeroMemory(&pBss->RsnIE.IE[0], MAX_CUSTOM_LEN);
3751
3752                 pEid = (PEID_STRUCT) pVIE;
3753
3754                 while ((Length + 2 + (USHORT)pEid->Len) <= LengthVIE)
3755                 {
3756                         switch(pEid->Eid)
3757                         {
3758                                 case IE_WPA:
3759                                         if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
3760                                         {
3761                                                 if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
3762                                                 {
3763                                                         pBss->WpaIE.IELen = 0;
3764                                                         break;
3765                                                 }
3766                                                 pBss->WpaIE.IELen = pEid->Len + 2;
3767                                                 NdisMoveMemory(pBss->WpaIE.IE, pEid, pBss->WpaIE.IELen);
3768                                         }
3769                                         break;
3770                 case IE_RSN:
3771                     if (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
3772                                         {
3773                                                 if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
3774                                                 {
3775                                                         pBss->RsnIE.IELen = 0;
3776                                                         break;
3777                                                 }
3778                                                 pBss->RsnIE.IELen = pEid->Len + 2;
3779                                                 NdisMoveMemory(pBss->RsnIE.IE, pEid, pBss->RsnIE.IELen);
3780                         }
3781                                 break;
3782             }
3783                         Length = Length + 2 + (USHORT)pEid->Len;  // Eid[1] + Len[1]+ content[Len]
3784                         pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
3785                 }
3786         }
3787 }
3788
3789 /*!
3790  *      \brief insert an entry into the bss table
3791  *      \param p_tab The BSS table
3792  *      \param Bssid BSSID
3793  *      \param ssid SSID
3794  *      \param ssid_len Length of SSID
3795  *      \param bss_type
3796  *      \param beacon_period
3797  *      \param timestamp
3798  *      \param p_cf
3799  *      \param atim_win
3800  *      \param cap
3801  *      \param rates
3802  *      \param rates_len
3803  *      \param channel_idx
3804  *      \return none
3805  *      \pre
3806  *      \post
3807  *      \note If SSID is identical, the old entry will be replaced by the new one
3808
3809  IRQL = DISPATCH_LEVEL
3810
3811  */
3812 ULONG BssTableSetEntry(
3813         IN      PRTMP_ADAPTER   pAd,
3814         OUT BSS_TABLE *Tab,
3815         IN PUCHAR pBssid,
3816         IN CHAR Ssid[],
3817         IN UCHAR SsidLen,
3818         IN UCHAR BssType,
3819         IN USHORT BeaconPeriod,
3820         IN CF_PARM *CfParm,
3821         IN USHORT AtimWin,
3822         IN USHORT CapabilityInfo,
3823         IN UCHAR SupRate[],
3824         IN UCHAR SupRateLen,
3825         IN UCHAR ExtRate[],
3826         IN UCHAR ExtRateLen,
3827         IN HT_CAPABILITY_IE *pHtCapability,
3828         IN ADD_HT_INFO_IE *pAddHtInfo,  // AP might use this additional ht info IE
3829         IN UCHAR                        HtCapabilityLen,
3830         IN UCHAR                        AddHtInfoLen,
3831         IN UCHAR                        NewExtChanOffset,
3832         IN UCHAR ChannelNo,
3833         IN CHAR Rssi,
3834         IN LARGE_INTEGER TimeStamp,
3835         IN UCHAR CkipFlag,
3836         IN PEDCA_PARM pEdcaParm,
3837         IN PQOS_CAPABILITY_PARM pQosCapability,
3838         IN PQBSS_LOAD_PARM pQbssLoad,
3839         IN USHORT LengthVIE,
3840         IN PNDIS_802_11_VARIABLE_IEs pVIE)
3841 {
3842         ULONG   Idx;
3843
3844         Idx = BssTableSearchWithSSID(Tab, pBssid,  Ssid, SsidLen, ChannelNo);
3845         if (Idx == BSS_NOT_FOUND)
3846         {
3847                 if (Tab->BssNr >= MAX_LEN_OF_BSS_TABLE)
3848             {
3849                         //
3850                         // It may happen when BSS Table was full.
3851                         // The desired AP will not be added into BSS Table
3852                         // In this case, if we found the desired AP then overwrite BSS Table.
3853                         //
3854                         if(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
3855                         {
3856                                 if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, pBssid) ||
3857                                         SSID_EQUAL(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Ssid, SsidLen))
3858                                 {
3859                                         Idx = Tab->BssOverlapNr;
3860                                         BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
3861                                                 CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
3862                                                 NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
3863                     Tab->BssOverlapNr = (Tab->BssOverlapNr++) % MAX_LEN_OF_BSS_TABLE;
3864                                 }
3865                                 return Idx;
3866                         }
3867                         else
3868                         {
3869                         return BSS_NOT_FOUND;
3870                         }
3871                 }
3872                 Idx = Tab->BssNr;
3873                 BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
3874                                         CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
3875                                         NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
3876                 Tab->BssNr++;
3877         }
3878         else
3879         {
3880 #ifdef RT30xx
3881                 /* avoid  Hidden SSID form beacon to overwirite correct SSID from probe response */
3882                 if ((SSID_EQUAL(Ssid, SsidLen, Tab->BssEntry[Idx].Ssid, Tab->BssEntry[Idx].SsidLen)) ||
3883                         (NdisEqualMemory(Tab->BssEntry[Idx].Ssid, ZeroSsid, Tab->BssEntry[Idx].SsidLen)))
3884                 {
3885 #endif
3886                 BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod,CfParm, AtimWin,
3887                                         CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
3888                                         NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
3889 #ifdef RT30xx
3890                 }
3891 #endif
3892         }
3893
3894         return Idx;
3895 }
3896
3897 // IRQL = DISPATCH_LEVEL
3898 VOID BssTableSsidSort(
3899         IN      PRTMP_ADAPTER   pAd,
3900         OUT BSS_TABLE *OutTab,
3901         IN      CHAR Ssid[],
3902         IN      UCHAR SsidLen)
3903 {
3904         INT i;
3905         BssTableInit(OutTab);
3906
3907         for (i = 0; i < pAd->ScanTab.BssNr; i++)
3908         {
3909                 BSS_ENTRY *pInBss = &pAd->ScanTab.BssEntry[i];
3910                 BOOLEAN bIsHiddenApIncluded = FALSE;
3911
3912                 if (((pAd->CommonCfg.bIEEE80211H == 1) &&
3913             (pAd->MlmeAux.Channel > 14) &&
3914              RadarChannelCheck(pAd, pInBss->Channel))
3915             )
3916                 {
3917                         if (pInBss->Hidden)
3918                                 bIsHiddenApIncluded = TRUE;
3919                 }
3920
3921                 if ((pInBss->BssType == pAd->StaCfg.BssType) &&
3922                         (SSID_EQUAL(Ssid, SsidLen, pInBss->Ssid, pInBss->SsidLen) || bIsHiddenApIncluded))
3923                 {
3924                         BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
3925
3926                         // 2.4G/5G N only mode
3927                         if ((pInBss->HtCapabilityLen == 0) &&
3928                                 ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
3929                         {
3930                                 DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
3931                                 continue;
3932                         }
3933
3934                         // New for WPA2
3935                         // Check the Authmode first
3936                         if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3937                         {
3938                                 // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
3939                                 if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
3940                                         // None matched
3941                                         continue;
3942
3943                                 // Check cipher suite, AP must have more secured cipher than station setting
3944                                 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
3945                                 {
3946                                         // If it's not mixed mode, we should only let BSS pass with the same encryption
3947                                         if (pInBss->WPA.bMixMode == FALSE)
3948                                                 if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
3949                                                         continue;
3950
3951                                         // check group cipher
3952 #ifndef RT30xx
3953                                         if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) &&
3954                                                 (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP40Enabled) &&
3955                                                 (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP104Enabled))
3956 #endif
3957 #ifdef RT30xx
3958                                         if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
3959 #endif
3960                                                 continue;
3961
3962                                         // check pairwise cipher, skip if none matched
3963                                         // If profile set to AES, let it pass without question.
3964                                         // If profile set to TKIP, we must find one mateched
3965                                         if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
3966                                                 (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
3967                                                 (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
3968                                                 continue;
3969                                 }
3970                                 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
3971                                 {
3972                                         // If it's not mixed mode, we should only let BSS pass with the same encryption
3973                                         if (pInBss->WPA2.bMixMode == FALSE)
3974                                                 if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
3975                                                         continue;
3976
3977                                         // check group cipher
3978 #ifndef RT30xx
3979                                         if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) &&
3980                                                 (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP40Enabled) &&
3981                                                 (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP104Enabled))
3982 #endif
3983 #ifdef RT30xx
3984                                         if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
3985 #endif
3986                                                 continue;
3987
3988                                         // check pairwise cipher, skip if none matched
3989                                         // If profile set to AES, let it pass without question.
3990                                         // If profile set to TKIP, we must find one mateched
3991                                         if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
3992                                                 (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
3993                                                 (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
3994                                                 continue;
3995                                 }
3996                         }
3997                         // Bss Type matched, SSID matched.
3998                         // We will check wepstatus for qualification Bss
3999                         else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
4000                         {
4001                                 DBGPRINT(RT_DEBUG_TRACE,("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n", pAd->StaCfg.WepStatus, pInBss->WepStatus));
4002                                 //
4003                                 // For the SESv2 case, we will not qualify WepStatus.
4004                                 //
4005                                 if (!pInBss->bSES)
4006                                         continue;
4007                         }
4008
4009                         // Since the AP is using hidden SSID, and we are trying to connect to ANY
4010                         // It definitely will fail. So, skip it.
4011                         // CCX also require not even try to connect it!!
4012                         if (SsidLen == 0)
4013                                 continue;
4014
4015                         // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
4016                         // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
4017                         if ((pInBss->CentralChannel != pInBss->Channel) &&
4018                                 (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
4019                         {
4020                                 if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
4021                                 {
4022                                         pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
4023                                         SetCommonHT(pAd);
4024                                         pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
4025                                 }
4026                                 else
4027                                 {
4028                                         if (pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BAND_WIDTH_20)
4029                                         {
4030                                                 SetCommonHT(pAd);
4031                                         }
4032                                 }
4033                         }
4034
4035                         // copy matching BSS from InTab to OutTab
4036                         NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
4037
4038                         OutTab->BssNr++;
4039                 }
4040                 else if ((pInBss->BssType == pAd->StaCfg.BssType) && (SsidLen == 0))
4041                 {
4042                         BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
4043
4044                         // 2.4G/5G N only mode
4045                         if ((pInBss->HtCapabilityLen == 0) &&
4046                                 ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
4047                         {
4048                                 DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
4049                                 continue;
4050                         }
4051
4052                         // New for WPA2
4053                         // Check the Authmode first
4054                         if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
4055                         {
4056                                 // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
4057                                 if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
4058                                         // None matched
4059                                         continue;
4060
4061                                 // Check cipher suite, AP must have more secured cipher than station setting
4062                                 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
4063                                 {
4064                                         // If it's not mixed mode, we should only let BSS pass with the same encryption
4065                                         if (pInBss->WPA.bMixMode == FALSE)
4066                                                 if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
4067                                                         continue;
4068
4069                                         // check group cipher
4070                                         if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
4071                                                 continue;
4072
4073                                         // check pairwise cipher, skip if none matched
4074                                         // If profile set to AES, let it pass without question.
4075                                         // If profile set to TKIP, we must find one mateched
4076                                         if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
4077                                                 (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
4078                                                 (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
4079                                                 continue;
4080                                 }
4081                                 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
4082                                 {
4083                                         // If it's not mixed mode, we should only let BSS pass with the same encryption
4084                                         if (pInBss->WPA2.bMixMode == FALSE)
4085                                                 if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
4086                                                         continue;
4087
4088                                         // check group cipher
4089                                         if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
4090                                                 continue;
4091
4092                                         // check pairwise cipher, skip if none matched
4093                                         // If profile set to AES, let it pass without question.
4094                                         // If profile set to TKIP, we must find one mateched
4095                                         if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
4096                                                 (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
4097                                                 (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
4098                                                 continue;
4099                                 }
4100                         }
4101                         // Bss Type matched, SSID matched.
4102                         // We will check wepstatus for qualification Bss
4103                         else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
4104                                         continue;
4105
4106                         // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
4107                         // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
4108                         if ((pInBss->CentralChannel != pInBss->Channel) &&
4109                                 (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
4110                         {
4111                                 if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
4112                                 {
4113                                         pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
4114                                         SetCommonHT(pAd);
4115                                         pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
4116                                 }
4117                         }
4118
4119                         // copy matching BSS from InTab to OutTab
4120                         NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
4121
4122                         OutTab->BssNr++;
4123                 }
4124
4125                 if (OutTab->BssNr >= MAX_LEN_OF_BSS_TABLE)
4126                         break;
4127         }
4128
4129         BssTableSortByRssi(OutTab);
4130 }
4131
4132
4133 // IRQL = DISPATCH_LEVEL
4134 VOID BssTableSortByRssi(
4135         IN OUT BSS_TABLE *OutTab)
4136 {
4137         INT       i, j;
4138         BSS_ENTRY TmpBss;
4139
4140         for (i = 0; i < OutTab->BssNr - 1; i++)
4141         {
4142                 for (j = i+1; j < OutTab->BssNr; j++)
4143                 {
4144                         if (OutTab->BssEntry[j].Rssi > OutTab->BssEntry[i].Rssi)
4145                         {
4146                                 NdisMoveMemory(&TmpBss, &OutTab->BssEntry[j], sizeof(BSS_ENTRY));
4147                                 NdisMoveMemory(&OutTab->BssEntry[j], &OutTab->BssEntry[i], sizeof(BSS_ENTRY));
4148                                 NdisMoveMemory(&OutTab->BssEntry[i], &TmpBss, sizeof(BSS_ENTRY));
4149                         }
4150                 }
4151         }
4152 }
4153
4154 VOID BssCipherParse(
4155         IN OUT  PBSS_ENTRY      pBss)
4156 {
4157         PEID_STRUCT              pEid;
4158         PUCHAR                          pTmp;
4159         PRSN_IE_HEADER_STRUCT                   pRsnHeader;
4160         PCIPHER_SUITE_STRUCT                    pCipher;
4161         PAKM_SUITE_STRUCT                               pAKM;
4162         USHORT                                                  Count;
4163         INT                                                             Length;
4164         NDIS_802_11_ENCRYPTION_STATUS   TmpCipher;
4165
4166         //
4167         // WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame.
4168         //
4169         if (pBss->Privacy)
4170         {
4171                 pBss->WepStatus         = Ndis802_11WEPEnabled;
4172         }
4173         else
4174         {
4175                 pBss->WepStatus         = Ndis802_11WEPDisabled;
4176         }
4177         // Set default to disable & open authentication before parsing variable IE
4178         pBss->AuthMode          = Ndis802_11AuthModeOpen;
4179         pBss->AuthModeAux       = Ndis802_11AuthModeOpen;
4180
4181         // Init WPA setting
4182         pBss->WPA.PairCipher    = Ndis802_11WEPDisabled;
4183         pBss->WPA.PairCipherAux = Ndis802_11WEPDisabled;
4184         pBss->WPA.GroupCipher   = Ndis802_11WEPDisabled;
4185         pBss->WPA.RsnCapability = 0;
4186         pBss->WPA.bMixMode              = FALSE;
4187
4188         // Init WPA2 setting
4189         pBss->WPA2.PairCipher    = Ndis802_11WEPDisabled;
4190         pBss->WPA2.PairCipherAux = Ndis802_11WEPDisabled;
4191         pBss->WPA2.GroupCipher   = Ndis802_11WEPDisabled;
4192         pBss->WPA2.RsnCapability = 0;
4193         pBss->WPA2.bMixMode      = FALSE;
4194
4195
4196         Length = (INT) pBss->VarIELen;
4197
4198         while (Length > 0)
4199         {
4200                 // Parse cipher suite base on WPA1 & WPA2, they should be parsed differently
4201                 pTmp = ((PUCHAR) pBss->VarIEs) + pBss->VarIELen - Length;
4202                 pEid = (PEID_STRUCT) pTmp;
4203                 switch (pEid->Eid)
4204                 {
4205                         case IE_WPA:
4206                                 //Parse Cisco IE_WPA (LEAP, CCKM, etc.)
4207                                 if ( NdisEqualMemory((pTmp+8), CISCO_OUI, 3))
4208                                 {
4209                                         pTmp   += 11;
4210                                         switch (*pTmp)
4211                                         {
4212                                                 case 1:
4213                                                 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4214                                                         pBss->WepStatus = Ndis802_11Encryption1Enabled;
4215                                                         pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
4216                                                         pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
4217                                                         break;
4218                                                 case 2:
4219                                                         pBss->WepStatus = Ndis802_11Encryption2Enabled;
4220                                                         pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
4221                                                         pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
4222                                                         break;
4223                                                 case 4:
4224                                                         pBss->WepStatus = Ndis802_11Encryption3Enabled;
4225                                                         pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
4226                                                         pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
4227                                                         break;
4228                                                 default:
4229                                                         break;
4230                                         }
4231
4232                                         // if Cisco IE_WPA, break
4233                                         break;
4234                                 }
4235                                 else if (NdisEqualMemory(pEid->Octet, SES_OUI, 3) && (pEid->Len == 7))
4236                                 {
4237                                         pBss->bSES = TRUE;
4238                                         break;
4239                                 }
4240                                 else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4) != 1)
4241                                 {
4242                                         // if unsupported vendor specific IE
4243                                         break;
4244                                 }
4245                                 // Skip OUI, version, and multicast suite
4246                                 // This part should be improved in the future when AP supported multiple cipher suite.
4247                                 // For now, it's OK since almost all APs have fixed cipher suite supported.
4248                                 // pTmp = (PUCHAR) pEid->Octet;
4249                                 pTmp   += 11;
4250
4251                                 // Cipher Suite Selectors from Spec P802.11i/D3.2 P26.
4252                                 //      Value      Meaning
4253                                 //      0                       None
4254                                 //      1                       WEP-40
4255                                 //      2                       Tkip
4256                                 //      3                       WRAP
4257                                 //      4                       AES
4258                                 //      5                       WEP-104
4259                                 // Parse group cipher
4260                                 switch (*pTmp)
4261                                 {
4262                                         case 1:
4263 #ifndef RT30xx
4264                                                 pBss->WPA.GroupCipher = Ndis802_11GroupWEP40Enabled;
4265                                                 break;
4266                                         case 5:
4267                                                 pBss->WPA.GroupCipher = Ndis802_11GroupWEP104Enabled;
4268 #endif
4269 #ifdef RT30xx
4270                                         case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4271                                                 pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
4272 #endif
4273                                                 break;
4274                                         case 2:
4275                                                 pBss->WPA.GroupCipher = Ndis802_11Encryption2Enabled;
4276                                                 break;
4277                                         case 4:
4278                                                 pBss->WPA.GroupCipher = Ndis802_11Encryption3Enabled;
4279                                                 break;
4280                                         default:
4281                                                 break;
4282                                 }
4283                                 // number of unicast suite
4284                                 pTmp   += 1;
4285
4286                                 // skip all unicast cipher suites
4287                                 //Count = *(PUSHORT) pTmp;
4288                                 Count = (pTmp[1]<<8) + pTmp[0];
4289                                 pTmp   += sizeof(USHORT);
4290
4291                                 // Parsing all unicast cipher suite
4292                                 while (Count > 0)
4293                                 {
4294                                         // Skip OUI
4295                                         pTmp += 3;
4296                                         TmpCipher = Ndis802_11WEPDisabled;
4297                                         switch (*pTmp)
4298                                         {
4299                                                 case 1:
4300                                                 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4301                                                         TmpCipher = Ndis802_11Encryption1Enabled;
4302                                                         break;
4303                                                 case 2:
4304                                                         TmpCipher = Ndis802_11Encryption2Enabled;
4305                                                         break;
4306                                                 case 4:
4307                                                         TmpCipher = Ndis802_11Encryption3Enabled;
4308                                                         break;
4309                                                 default:
4310                                                         break;
4311                                         }
4312                                         if (TmpCipher > pBss->WPA.PairCipher)
4313                                         {
4314                                                 // Move the lower cipher suite to PairCipherAux
4315                                                 pBss->WPA.PairCipherAux = pBss->WPA.PairCipher;
4316                                                 pBss->WPA.PairCipher    = TmpCipher;
4317                                         }
4318                                         else
4319                                         {
4320                                                 pBss->WPA.PairCipherAux = TmpCipher;
4321                                         }
4322                                         pTmp++;
4323                                         Count--;
4324                                 }
4325
4326                                 // 4. get AKM suite counts
4327                                 //Count = *(PUSHORT) pTmp;
4328                                 Count = (pTmp[1]<<8) + pTmp[0];
4329                                 pTmp   += sizeof(USHORT);
4330                                 pTmp   += 3;
4331
4332                                 switch (*pTmp)
4333                                 {
4334                                         case 1:
4335                                                 // Set AP support WPA mode
4336                                                 if (pBss->AuthMode == Ndis802_11AuthModeOpen)
4337                                                         pBss->AuthMode = Ndis802_11AuthModeWPA;
4338                                                 else
4339                                                         pBss->AuthModeAux = Ndis802_11AuthModeWPA;
4340                                                 break;
4341                                         case 2:
4342                                                 // Set AP support WPA mode
4343                                                 if (pBss->AuthMode == Ndis802_11AuthModeOpen)
4344                                                         pBss->AuthMode = Ndis802_11AuthModeWPAPSK;
4345                                                 else
4346                                                         pBss->AuthModeAux = Ndis802_11AuthModeWPAPSK;
4347                                                 break;
4348                                         default:
4349                                                 break;
4350                                 }
4351                                 pTmp   += 1;
4352
4353                                 // Fixed for WPA-None
4354                                 if (pBss->BssType == BSS_ADHOC)
4355                                 {
4356                                         pBss->AuthMode    = Ndis802_11AuthModeWPANone;
4357                                         pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
4358                                         pBss->WepStatus   = pBss->WPA.GroupCipher;
4359                                         if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
4360                                                 pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
4361                                 }
4362                                 else
4363                                         pBss->WepStatus   = pBss->WPA.PairCipher;
4364
4365                                 // Check the Pair & Group, if different, turn on mixed mode flag
4366                                 if (pBss->WPA.GroupCipher != pBss->WPA.PairCipher)
4367                                         pBss->WPA.bMixMode = TRUE;
4368
4369                                 break;
4370
4371                         case IE_RSN:
4372                                 pRsnHeader = (PRSN_IE_HEADER_STRUCT) pTmp;
4373
4374                                 // 0. Version must be 1
4375                                 if (le2cpu16(pRsnHeader->Version) != 1)
4376                                         break;
4377                                 pTmp   += sizeof(RSN_IE_HEADER_STRUCT);
4378
4379                                 // 1. Check group cipher
4380                                 pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
4381                                 if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
4382                                         break;
4383
4384                                 // Parse group cipher
4385                                 switch (pCipher->Type)
4386                                 {
4387                                         case 1:
4388 #ifndef RT30xx
4389                                                 pBss->WPA2.GroupCipher = Ndis802_11GroupWEP40Enabled;
4390                                                 break;
4391                                         case 5:
4392                                                 pBss->WPA2.GroupCipher = Ndis802_11GroupWEP104Enabled;
4393 #endif
4394 #ifdef RT30xx
4395                                         case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4396                                                 pBss->WPA2.GroupCipher = Ndis802_11Encryption1Enabled;
4397 #endif
4398                                                 break;
4399                                         case 2:
4400                                                 pBss->WPA2.GroupCipher = Ndis802_11Encryption2Enabled;
4401                                                 break;
4402                                         case 4:
4403                                                 pBss->WPA2.GroupCipher = Ndis802_11Encryption3Enabled;
4404                                                 break;
4405                                         default:
4406                                                 break;
4407                                 }
4408                                 // set to correct offset for next parsing
4409                                 pTmp   += sizeof(CIPHER_SUITE_STRUCT);
4410
4411                                 // 2. Get pairwise cipher counts
4412                                 //Count = *(PUSHORT) pTmp;
4413                                 Count = (pTmp[1]<<8) + pTmp[0];
4414                                 pTmp   += sizeof(USHORT);
4415
4416                                 // 3. Get pairwise cipher
4417                                 // Parsing all unicast cipher suite
4418                                 while (Count > 0)
4419                                 {
4420                                         // Skip OUI
4421                                         pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
4422                                         TmpCipher = Ndis802_11WEPDisabled;
4423                                         switch (pCipher->Type)
4424                                         {
4425                                                 case 1:
4426                                                 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4427                                                         TmpCipher = Ndis802_11Encryption1Enabled;
4428                                                         break;
4429                                                 case 2:
4430                                                         TmpCipher = Ndis802_11Encryption2Enabled;
4431                                                         break;
4432                                                 case 4:
4433                                                         TmpCipher = Ndis802_11Encryption3Enabled;
4434                                                         break;
4435                                                 default:
4436                                                         break;
4437                                         }
4438                                         if (TmpCipher > pBss->WPA2.PairCipher)
4439                                         {
4440                                                 // Move the lower cipher suite to PairCipherAux
4441                                                 pBss->WPA2.PairCipherAux = pBss->WPA2.PairCipher;
4442                                                 pBss->WPA2.PairCipher    = TmpCipher;
4443                                         }
4444                                         else
4445                                         {
4446                                                 pBss->WPA2.PairCipherAux = TmpCipher;
4447                                         }
4448                                         pTmp += sizeof(CIPHER_SUITE_STRUCT);
4449                                         Count--;
4450                                 }
4451
4452                                 // 4. get AKM suite counts
4453                                 //Count = *(PUSHORT) pTmp;
4454                                 Count = (pTmp[1]<<8) + pTmp[0];
4455                                 pTmp   += sizeof(USHORT);
4456
4457                                 // 5. Get AKM ciphers
4458                                 pAKM = (PAKM_SUITE_STRUCT) pTmp;
4459                                 if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
4460                                         break;
4461
4462                                 switch (pAKM->Type)
4463                                 {
4464                                         case 1:
4465                                                 // Set AP support WPA mode
4466                                                 if (pBss->AuthMode == Ndis802_11AuthModeOpen)
4467                                                         pBss->AuthMode = Ndis802_11AuthModeWPA2;
4468                                                 else
4469                                                         pBss->AuthModeAux = Ndis802_11AuthModeWPA2;
4470                                                 break;
4471                                         case 2:
4472                                                 // Set AP support WPA mode
4473                                                 if (pBss->AuthMode == Ndis802_11AuthModeOpen)
4474                                                         pBss->AuthMode = Ndis802_11AuthModeWPA2PSK;
4475                                                 else
4476                                                         pBss->AuthModeAux = Ndis802_11AuthModeWPA2PSK;
4477                                                 break;
4478                                         default:
4479                                                 break;
4480                                 }
4481                                 pTmp   += (Count * sizeof(AKM_SUITE_STRUCT));
4482
4483                                 // Fixed for WPA-None
4484                                 if (pBss->BssType == BSS_ADHOC)
4485                                 {
4486                                         pBss->AuthMode = Ndis802_11AuthModeWPANone;
4487                                         pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
4488                                         pBss->WPA.PairCipherAux = pBss->WPA2.PairCipherAux;
4489                                         pBss->WPA.GroupCipher   = pBss->WPA2.GroupCipher;
4490                                         pBss->WepStatus                 = pBss->WPA.GroupCipher;
4491                                         if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
4492                                                 pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
4493                                 }
4494                                 pBss->WepStatus   = pBss->WPA2.PairCipher;
4495
4496                                 // 6. Get RSN capability
4497                                 //pBss->WPA2.RsnCapability = *(PUSHORT) pTmp;
4498                                 pBss->WPA2.RsnCapability = (pTmp[1]<<8) + pTmp[0];
4499                                 pTmp += sizeof(USHORT);
4500
4501                                 // Check the Pair & Group, if different, turn on mixed mode flag
4502                                 if (pBss->WPA2.GroupCipher != pBss->WPA2.PairCipher)
4503                                         pBss->WPA2.bMixMode = TRUE;
4504
4505                                 break;
4506                         default:
4507                                 break;
4508                 }
4509                 Length -= (pEid->Len + 2);
4510         }
4511 }
4512
4513 // ===========================================================================================
4514 // mac_table.c
4515 // ===========================================================================================
4516
4517 /*! \brief generates a random mac address value for IBSS BSSID
4518  *      \param Addr the bssid location
4519  *      \return none
4520  *      \pre
4521  *      \post
4522  */
4523 VOID MacAddrRandomBssid(
4524         IN PRTMP_ADAPTER pAd,
4525         OUT PUCHAR pAddr)
4526 {
4527         INT i;
4528
4529         for (i = 0; i < MAC_ADDR_LEN; i++)
4530         {
4531                 pAddr[i] = RandomByte(pAd);
4532         }
4533
4534         pAddr[0] = (pAddr[0] & 0xfe) | 0x02;  // the first 2 bits must be 01xxxxxxxx
4535 }
4536
4537 /*! \brief init the management mac frame header
4538  *      \param p_hdr mac header
4539  *      \param subtype subtype of the frame
4540  *      \param p_ds destination address, don't care if it is a broadcast address
4541  *      \return none
4542  *      \pre the station has the following information in the pAd->StaCfg
4543  *       - bssid
4544  *       - station address
4545  *      \post
4546  *      \note this function initializes the following field
4547
4548  IRQL = PASSIVE_LEVEL
4549  IRQL = DISPATCH_LEVEL
4550
4551  */
4552 VOID MgtMacHeaderInit(
4553         IN      PRTMP_ADAPTER   pAd,
4554         IN OUT PHEADER_802_11 pHdr80211,
4555         IN UCHAR SubType,
4556         IN UCHAR ToDs,
4557         IN PUCHAR pDA,
4558         IN PUCHAR pBssid)
4559 {
4560         NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
4561
4562         pHdr80211->FC.Type = BTYPE_MGMT;
4563         pHdr80211->FC.SubType = SubType;
4564         pHdr80211->FC.ToDs = ToDs;
4565         COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
4566
4567         COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
4568
4569         COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
4570 }
4571
4572 // ===========================================================================================
4573 // mem_mgmt.c
4574 // ===========================================================================================
4575
4576 /*!***************************************************************************
4577  * This routine build an outgoing frame, and fill all information specified
4578  * in argument list to the frame body. The actual frame size is the summation
4579  * of all arguments.
4580  * input params:
4581  *              Buffer - pointer to a pre-allocated memory segment
4582  *              args - a list of <int arg_size, arg> pairs.
4583  *              NOTE NOTE NOTE!!!! the last argument must be NULL, otherwise this
4584  *                                                 function will FAIL!!!
4585  * return:
4586  *              Size of the buffer
4587  * usage:
4588  *              MakeOutgoingFrame(Buffer, output_length, 2, &fc, 2, &dur, 6, p_addr1, 6,p_addr2, END_OF_ARGS);
4589
4590  IRQL = PASSIVE_LEVEL
4591  IRQL = DISPATCH_LEVEL
4592
4593  ****************************************************************************/
4594 ULONG MakeOutgoingFrame(
4595         OUT CHAR *Buffer,
4596         OUT ULONG *FrameLen, ...)
4597 {
4598         CHAR   *p;
4599         int     leng;
4600         ULONG   TotLeng;
4601         va_list Args;
4602
4603         // calculates the total length
4604         TotLeng = 0;
4605         va_start(Args, FrameLen);
4606         do
4607         {
4608                 leng = va_arg(Args, int);
4609                 if (leng == END_OF_ARGS)
4610                 {
4611                         break;
4612                 }
4613                 p = va_arg(Args, PVOID);
4614                 NdisMoveMemory(&Buffer[TotLeng], p, leng);
4615                 TotLeng = TotLeng + leng;
4616         } while(TRUE);
4617
4618         va_end(Args); /* clean up */
4619         *FrameLen = TotLeng;
4620         return TotLeng;
4621 }
4622
4623 // ===========================================================================================
4624 // mlme_queue.c
4625 // ===========================================================================================
4626
4627 /*! \brief      Initialize The MLME Queue, used by MLME Functions
4628  *      \param  *Queue     The MLME Queue
4629  *      \return Always     Return NDIS_STATE_SUCCESS in this implementation
4630  *      \pre
4631  *      \post
4632  *      \note   Because this is done only once (at the init stage), no need to be locked
4633
4634  IRQL = PASSIVE_LEVEL
4635
4636  */
4637 NDIS_STATUS MlmeQueueInit(
4638         IN MLME_QUEUE *Queue)
4639 {
4640         INT i;
4641
4642         NdisAllocateSpinLock(&Queue->Lock);
4643
4644         Queue->Num      = 0;
4645         Queue->Head = 0;
4646         Queue->Tail = 0;
4647
4648         for (i = 0; i < MAX_LEN_OF_MLME_QUEUE; i++)
4649         {
4650                 Queue->Entry[i].Occupied = FALSE;
4651                 Queue->Entry[i].MsgLen = 0;
4652                 NdisZeroMemory(Queue->Entry[i].Msg, MGMT_DMA_BUFFER_SIZE);
4653         }
4654
4655         return NDIS_STATUS_SUCCESS;
4656 }
4657
4658 /*! \brief       Enqueue a message for other threads, if they want to send messages to MLME thread
4659  *      \param  *Queue    The MLME Queue
4660  *      \param   Machine  The State Machine Id
4661  *      \param   MsgType  The Message Type
4662  *      \param   MsgLen   The Message length
4663  *      \param  *Msg      The message pointer
4664  *      \return  TRUE if enqueue is successful, FALSE if the queue is full
4665  *      \pre
4666  *      \post
4667  *      \note    The message has to be initialized
4668
4669  IRQL = PASSIVE_LEVEL
4670  IRQL = DISPATCH_LEVEL
4671
4672  */
4673 BOOLEAN MlmeEnqueue(
4674         IN      PRTMP_ADAPTER   pAd,
4675         IN ULONG Machine,
4676         IN ULONG MsgType,
4677         IN ULONG MsgLen,
4678         IN VOID *Msg)
4679 {
4680         INT Tail;
4681         MLME_QUEUE      *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
4682
4683         // Do nothing if the driver is starting halt state.
4684         // This might happen when timer already been fired before cancel timer with mlmehalt
4685         if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
4686                 return FALSE;
4687
4688         // First check the size, it MUST not exceed the mlme queue size
4689         if (MsgLen > MGMT_DMA_BUFFER_SIZE)
4690         {
4691                 DBGPRINT_ERR(("MlmeEnqueue: msg too large, size = %ld \n", MsgLen));
4692                 return FALSE;
4693         }
4694
4695         if (MlmeQueueFull(Queue))
4696         {
4697                 return FALSE;
4698         }
4699
4700         NdisAcquireSpinLock(&(Queue->Lock));
4701         Tail = Queue->Tail;
4702         Queue->Tail++;
4703         Queue->Num++;
4704         if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
4705         {
4706                 Queue->Tail = 0;
4707         }
4708
4709         Queue->Entry[Tail].Wcid = RESERVED_WCID;
4710         Queue->Entry[Tail].Occupied = TRUE;
4711         Queue->Entry[Tail].Machine = Machine;
4712         Queue->Entry[Tail].MsgType = MsgType;
4713         Queue->Entry[Tail].MsgLen  = MsgLen;
4714
4715         if (Msg != NULL)
4716         {
4717                 NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
4718         }
4719
4720         NdisReleaseSpinLock(&(Queue->Lock));
4721         return TRUE;
4722 }
4723
4724 /*! \brief       This function is used when Recv gets a MLME message
4725  *      \param  *Queue                   The MLME Queue
4726  *      \param   TimeStampHigh   The upper 32 bit of timestamp
4727  *      \param   TimeStampLow    The lower 32 bit of timestamp
4728  *      \param   Rssi                    The receiving RSSI strength
4729  *      \param   MsgLen                  The length of the message
4730  *      \param  *Msg                     The message pointer
4731  *      \return  TRUE if everything ok, FALSE otherwise (like Queue Full)
4732  *      \pre
4733  *      \post
4734
4735  IRQL = DISPATCH_LEVEL
4736
4737  */
4738 BOOLEAN MlmeEnqueueForRecv(
4739         IN      PRTMP_ADAPTER   pAd,
4740         IN ULONG Wcid,
4741         IN ULONG TimeStampHigh,
4742         IN ULONG TimeStampLow,
4743         IN UCHAR Rssi0,
4744         IN UCHAR Rssi1,
4745         IN UCHAR Rssi2,
4746         IN ULONG MsgLen,
4747         IN VOID *Msg,
4748         IN UCHAR Signal)
4749 {
4750         INT              Tail, Machine;
4751         PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
4752         INT              MsgType;
4753         MLME_QUEUE      *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
4754
4755         // Do nothing if the driver is starting halt state.
4756         // This might happen when timer already been fired before cancel timer with mlmehalt
4757         if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
4758         {
4759                 DBGPRINT_ERR(("MlmeEnqueueForRecv: fRTMP_ADAPTER_HALT_IN_PROGRESS\n"));
4760                 return FALSE;
4761         }
4762
4763         // First check the size, it MUST not exceed the mlme queue size
4764         if (MsgLen > MGMT_DMA_BUFFER_SIZE)
4765         {
4766                 DBGPRINT_ERR(("MlmeEnqueueForRecv: frame too large, size = %ld \n", MsgLen));
4767                 return FALSE;
4768         }
4769
4770         if (MlmeQueueFull(Queue))
4771         {
4772                 return FALSE;
4773         }
4774
4775         {
4776                 if (!MsgTypeSubst(pAd, pFrame, &Machine, &MsgType))
4777                 {
4778                         DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n",pFrame->Hdr.FC.SubType));
4779                         return FALSE;
4780                 }
4781         }
4782
4783         // OK, we got all the informations, it is time to put things into queue
4784         NdisAcquireSpinLock(&(Queue->Lock));
4785         Tail = Queue->Tail;
4786         Queue->Tail++;
4787         Queue->Num++;
4788         if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
4789         {
4790                 Queue->Tail = 0;
4791         }
4792         Queue->Entry[Tail].Occupied = TRUE;
4793         Queue->Entry[Tail].Machine = Machine;
4794         Queue->Entry[Tail].MsgType = MsgType;
4795         Queue->Entry[Tail].MsgLen  = MsgLen;
4796         Queue->Entry[Tail].TimeStamp.u.LowPart = TimeStampLow;
4797         Queue->Entry[Tail].TimeStamp.u.HighPart = TimeStampHigh;
4798         Queue->Entry[Tail].Rssi0 = Rssi0;
4799         Queue->Entry[Tail].Rssi1 = Rssi1;
4800         Queue->Entry[Tail].Rssi2 = Rssi2;
4801         Queue->Entry[Tail].Signal = Signal;
4802         Queue->Entry[Tail].Wcid = (UCHAR)Wcid;
4803
4804         Queue->Entry[Tail].Channel = pAd->LatchRfRegs.Channel;
4805
4806         if (Msg != NULL)
4807         {
4808                 NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
4809         }
4810
4811         NdisReleaseSpinLock(&(Queue->Lock));
4812
4813         RT28XX_MLME_HANDLER(pAd);
4814
4815         return TRUE;
4816 }
4817
4818
4819 /*! \brief       Dequeue a message from the MLME Queue
4820  *      \param  *Queue    The MLME Queue
4821  *      \param  *Elem     The message dequeued from MLME Queue
4822  *      \return  TRUE if the Elem contains something, FALSE otherwise
4823  *      \pre
4824  *      \post
4825
4826  IRQL = DISPATCH_LEVEL
4827
4828  */
4829 BOOLEAN MlmeDequeue(
4830         IN MLME_QUEUE *Queue,
4831         OUT MLME_QUEUE_ELEM **Elem)
4832 {
4833         NdisAcquireSpinLock(&(Queue->Lock));
4834         *Elem = &(Queue->Entry[Queue->Head]);
4835         Queue->Num--;
4836         Queue->Head++;
4837         if (Queue->Head == MAX_LEN_OF_MLME_QUEUE)
4838         {
4839                 Queue->Head = 0;
4840         }
4841         NdisReleaseSpinLock(&(Queue->Lock));
4842         return TRUE;
4843 }
4844
4845 // IRQL = DISPATCH_LEVEL
4846 VOID    MlmeRestartStateMachine(
4847         IN      PRTMP_ADAPTER   pAd)
4848 {
4849 #ifdef RT2860
4850         MLME_QUEUE_ELEM         *Elem = NULL;
4851 #endif
4852         BOOLEAN                         Cancelled;
4853
4854         DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n"));
4855
4856 #ifdef RT2860
4857         NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
4858         if(pAd->Mlme.bRunning)
4859         {
4860                 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
4861                 return;
4862         }
4863         else
4864         {
4865                 pAd->Mlme.bRunning = TRUE;
4866         }
4867         NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
4868
4869         // Remove all Mlme queues elements
4870         while (!MlmeQueueEmpty(&pAd->Mlme.Queue))
4871         {
4872                 //From message type, determine which state machine I should drive
4873                 if (MlmeDequeue(&pAd->Mlme.Queue, &Elem))
4874                 {
4875                         // free MLME element
4876                         Elem->Occupied = FALSE;
4877                         Elem->MsgLen = 0;
4878
4879                 }
4880                 else {
4881                         DBGPRINT_ERR(("MlmeRestartStateMachine: MlmeQueue empty\n"));
4882                 }
4883         }
4884 #endif /* RT2860 */
4885
4886         {
4887                 // Cancel all timer events
4888                 // Be careful to cancel new added timer
4889                 RTMPCancelTimer(&pAd->MlmeAux.AssocTimer,         &Cancelled);
4890                 RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer,   &Cancelled);
4891                 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer,  &Cancelled);
4892                 RTMPCancelTimer(&pAd->MlmeAux.AuthTimer,           &Cancelled);
4893                 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer,         &Cancelled);
4894                 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer,           &Cancelled);
4895         }
4896
4897         // Change back to original channel in case of doing scan
4898         AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
4899         AsicLockChannel(pAd, pAd->CommonCfg.Channel);
4900
4901         // Resume MSDU which is turned off durning scan
4902         RTMPResumeMsduTransmission(pAd);
4903
4904         {
4905                 // Set all state machines back IDLE
4906                 pAd->Mlme.CntlMachine.CurrState    = CNTL_IDLE;
4907                 pAd->Mlme.AssocMachine.CurrState   = ASSOC_IDLE;
4908                 pAd->Mlme.AuthMachine.CurrState    = AUTH_REQ_IDLE;
4909                 pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE;
4910                 pAd->Mlme.SyncMachine.CurrState    = SYNC_IDLE;
4911                 pAd->Mlme.ActMachine.CurrState    = ACT_IDLE;
4912         }
4913
4914 #ifdef RT2860
4915         // Remove running state
4916         NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
4917         pAd->Mlme.bRunning = FALSE;
4918         NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
4919 #endif
4920 }
4921
4922 /*! \brief      test if the MLME Queue is empty
4923  *      \param  *Queue    The MLME Queue
4924  *      \return TRUE if the Queue is empty, FALSE otherwise
4925  *      \pre
4926  *      \post
4927
4928  IRQL = DISPATCH_LEVEL
4929
4930  */
4931 BOOLEAN MlmeQueueEmpty(
4932         IN MLME_QUEUE *Queue)
4933 {
4934         BOOLEAN Ans;
4935
4936         NdisAcquireSpinLock(&(Queue->Lock));
4937         Ans = (Queue->Num == 0);
4938         NdisReleaseSpinLock(&(Queue->Lock));
4939
4940         return Ans;
4941 }
4942
4943 /*! \brief       test if the MLME Queue is full
4944  *      \param   *Queue          The MLME Queue
4945  *      \return  TRUE if the Queue is empty, FALSE otherwise
4946  *      \pre
4947  *      \post
4948
4949  IRQL = PASSIVE_LEVEL
4950  IRQL = DISPATCH_LEVEL
4951
4952  */
4953 BOOLEAN MlmeQueueFull(
4954         IN MLME_QUEUE *Queue)
4955 {
4956         BOOLEAN Ans;
4957
4958         NdisAcquireSpinLock(&(Queue->Lock));
4959         Ans = (Queue->Num == MAX_LEN_OF_MLME_QUEUE || Queue->Entry[Queue->Tail].Occupied);
4960         NdisReleaseSpinLock(&(Queue->Lock));
4961
4962         return Ans;
4963 }
4964
4965 /*! \brief       The destructor of MLME Queue
4966  *      \param
4967  *      \return
4968  *      \pre
4969  *      \post
4970  *      \note   Clear Mlme Queue, Set Queue->Num to Zero.
4971
4972  IRQL = PASSIVE_LEVEL
4973
4974  */
4975 VOID MlmeQueueDestroy(
4976         IN MLME_QUEUE *pQueue)
4977 {
4978         NdisAcquireSpinLock(&(pQueue->Lock));
4979         pQueue->Num  = 0;
4980         pQueue->Head = 0;
4981         pQueue->Tail = 0;
4982         NdisReleaseSpinLock(&(pQueue->Lock));
4983         NdisFreeSpinLock(&(pQueue->Lock));
4984 }
4985
4986 /*! \brief       To substitute the message type if the message is coming from external
4987  *      \param  pFrame             The frame received
4988  *      \param  *Machine           The state machine
4989  *      \param  *MsgType           the message type for the state machine
4990  *      \return TRUE if the substitution is successful, FALSE otherwise
4991  *      \pre
4992  *      \post
4993
4994  IRQL = DISPATCH_LEVEL
4995
4996  */
4997 BOOLEAN MsgTypeSubst(
4998         IN PRTMP_ADAPTER  pAd,
4999         IN PFRAME_802_11 pFrame,
5000         OUT INT *Machine,
5001         OUT INT *MsgType)
5002 {
5003         USHORT  Seq;
5004         UCHAR   EAPType;
5005         PUCHAR  pData;
5006
5007         // Pointer to start of data frames including SNAP header
5008         pData = (PUCHAR) pFrame + LENGTH_802_11;
5009
5010         // The only data type will pass to this function is EAPOL frame
5011         if (pFrame->Hdr.FC.Type == BTYPE_DATA)
5012         {
5013                 if (NdisEqualMemory(SNAP_AIRONET, pData, LENGTH_802_1_H))
5014                 {
5015                         // Cisco Aironet SNAP header
5016                         *Machine = AIRONET_STATE_MACHINE;
5017                         *MsgType = MT2_AIRONET_MSG;
5018                         return (TRUE);
5019                 }
5020                 {
5021                         *Machine = WPA_PSK_STATE_MACHINE;
5022                         EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
5023                         return(WpaMsgTypeSubst(EAPType, MsgType));
5024                 }
5025         }
5026
5027         switch (pFrame->Hdr.FC.SubType)
5028         {
5029                 case SUBTYPE_ASSOC_REQ:
5030                         *Machine = ASSOC_STATE_MACHINE;
5031                         *MsgType = MT2_PEER_ASSOC_REQ;
5032                         break;
5033                 case SUBTYPE_ASSOC_RSP:
5034                         *Machine = ASSOC_STATE_MACHINE;
5035                         *MsgType = MT2_PEER_ASSOC_RSP;
5036                         break;
5037                 case SUBTYPE_REASSOC_REQ:
5038                         *Machine = ASSOC_STATE_MACHINE;
5039                         *MsgType = MT2_PEER_REASSOC_REQ;
5040                         break;
5041                 case SUBTYPE_REASSOC_RSP:
5042                         *Machine = ASSOC_STATE_MACHINE;
5043                         *MsgType = MT2_PEER_REASSOC_RSP;
5044                         break;
5045                 case SUBTYPE_PROBE_REQ:
5046                         *Machine = SYNC_STATE_MACHINE;
5047                         *MsgType = MT2_PEER_PROBE_REQ;
5048                         break;
5049                 case SUBTYPE_PROBE_RSP:
5050                         *Machine = SYNC_STATE_MACHINE;
5051                         *MsgType = MT2_PEER_PROBE_RSP;
5052                         break;
5053                 case SUBTYPE_BEACON:
5054                         *Machine = SYNC_STATE_MACHINE;
5055                         *MsgType = MT2_PEER_BEACON;
5056                         break;
5057                 case SUBTYPE_ATIM:
5058                         *Machine = SYNC_STATE_MACHINE;
5059                         *MsgType = MT2_PEER_ATIM;
5060                         break;
5061                 case SUBTYPE_DISASSOC:
5062                         *Machine = ASSOC_STATE_MACHINE;
5063                         *MsgType = MT2_PEER_DISASSOC_REQ;
5064                         break;
5065                 case SUBTYPE_AUTH:
5066                         // get the sequence number from payload 24 Mac Header + 2 bytes algorithm
5067                         NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(USHORT));
5068                         if (Seq == 1 || Seq == 3)
5069                         {
5070                                 *Machine = AUTH_RSP_STATE_MACHINE;
5071                                 *MsgType = MT2_PEER_AUTH_ODD;
5072                         }
5073                         else if (Seq == 2 || Seq == 4)
5074                         {
5075                                 *Machine = AUTH_STATE_MACHINE;
5076                                 *MsgType = MT2_PEER_AUTH_EVEN;
5077                         }
5078                         else
5079                         {
5080                                 return FALSE;
5081                         }
5082                         break;
5083                 case SUBTYPE_DEAUTH:
5084                         *Machine = AUTH_RSP_STATE_MACHINE;
5085                         *MsgType = MT2_PEER_DEAUTH;
5086                         break;
5087                 case SUBTYPE_ACTION:
5088                         *Machine = ACTION_STATE_MACHINE;
5089                         //  Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support
5090                         if ((pFrame->Octet[0]&0x7F) > MAX_PEER_CATE_MSG)
5091                         {
5092                                 *MsgType = MT2_ACT_INVALID;
5093                         }
5094                         else
5095                         {
5096                                 *MsgType = (pFrame->Octet[0]&0x7F);
5097                         }
5098                         break;
5099                 default:
5100                         return FALSE;
5101                         break;
5102         }
5103
5104         return TRUE;
5105 }
5106
5107 // ===========================================================================================
5108 // state_machine.c
5109 // ===========================================================================================
5110
5111 /*! \brief Initialize the state machine.
5112  *      \param *S                       pointer to the state machine
5113  *      \param  Trans           State machine transition function
5114  *      \param  StNr            number of states
5115  *      \param  MsgNr           number of messages
5116  *      \param  DefFunc         default function, when there is invalid state/message combination
5117  *      \param  InitState       initial state of the state machine
5118  *      \param  Base            StateMachine base, internal use only
5119  *      \pre p_sm should be a legal pointer
5120  *      \post
5121
5122  IRQL = PASSIVE_LEVEL
5123
5124  */
5125 VOID StateMachineInit(
5126         IN STATE_MACHINE *S,
5127         IN STATE_MACHINE_FUNC Trans[],
5128         IN ULONG StNr,
5129         IN ULONG MsgNr,
5130         IN STATE_MACHINE_FUNC DefFunc,
5131         IN ULONG InitState,
5132         IN ULONG Base)
5133 {
5134         ULONG i, j;
5135
5136         // set number of states and messages
5137         S->NrState = StNr;
5138         S->NrMsg   = MsgNr;
5139         S->Base    = Base;
5140
5141         S->TransFunc  = Trans;
5142
5143         // init all state transition to default function
5144         for (i = 0; i < StNr; i++)
5145         {
5146                 for (j = 0; j < MsgNr; j++)
5147                 {
5148                         S->TransFunc[i * MsgNr + j] = DefFunc;
5149                 }
5150         }
5151
5152         // set the starting state
5153         S->CurrState = InitState;
5154 }
5155
5156 /*! \brief This function fills in the function pointer into the cell in the state machine
5157  *      \param *S       pointer to the state machine
5158  *      \param St       state
5159  *      \param Msg      incoming message
5160  *      \param f        the function to be executed when (state, message) combination occurs at the state machine
5161  *      \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
5162  *      \post
5163
5164  IRQL = PASSIVE_LEVEL
5165
5166  */
5167 VOID StateMachineSetAction(
5168         IN STATE_MACHINE *S,
5169         IN ULONG St,
5170         IN ULONG Msg,
5171         IN STATE_MACHINE_FUNC Func)
5172 {
5173         ULONG MsgIdx;
5174
5175         MsgIdx = Msg - S->Base;
5176
5177         if (St < S->NrState && MsgIdx < S->NrMsg)
5178         {
5179                 // boundary checking before setting the action
5180                 S->TransFunc[St * S->NrMsg + MsgIdx] = Func;
5181         }
5182 }
5183
5184 /*! \brief       This function does the state transition
5185  *      \param   *Adapter the NIC adapter pointer
5186  *      \param   *S       the state machine
5187  *      \param   *Elem    the message to be executed
5188  *      \return   None
5189
5190  IRQL = DISPATCH_LEVEL
5191
5192  */
5193 VOID StateMachinePerformAction(
5194         IN      PRTMP_ADAPTER   pAd,
5195         IN STATE_MACHINE *S,
5196         IN MLME_QUEUE_ELEM *Elem)
5197 {
5198         (*(S->TransFunc[S->CurrState * S->NrMsg + Elem->MsgType - S->Base]))(pAd, Elem);
5199 }
5200
5201 /*
5202         ==========================================================================
5203         Description:
5204                 The drop function, when machine executes this, the message is simply
5205                 ignored. This function does nothing, the message is freed in
5206                 StateMachinePerformAction()
5207         ==========================================================================
5208  */
5209 VOID Drop(
5210         IN PRTMP_ADAPTER pAd,
5211         IN MLME_QUEUE_ELEM *Elem)
5212 {
5213 }
5214
5215 // ===========================================================================================
5216 // lfsr.c
5217 // ===========================================================================================
5218
5219 /*
5220         ==========================================================================
5221         Description:
5222
5223         IRQL = PASSIVE_LEVEL
5224
5225         ==========================================================================
5226  */
5227 VOID LfsrInit(
5228         IN PRTMP_ADAPTER pAd,
5229         IN ULONG Seed)
5230 {
5231         if (Seed == 0)
5232                 pAd->Mlme.ShiftReg = 1;
5233         else
5234                 pAd->Mlme.ShiftReg = Seed;
5235 }
5236
5237 /*
5238         ==========================================================================
5239         Description:
5240         ==========================================================================
5241  */
5242 UCHAR RandomByte(
5243         IN PRTMP_ADAPTER pAd)
5244 {
5245         ULONG i;
5246         UCHAR R, Result;
5247
5248         R = 0;
5249
5250         if (pAd->Mlme.ShiftReg == 0)
5251         NdisGetSystemUpTime((ULONG *)&pAd->Mlme.ShiftReg);
5252
5253         for (i = 0; i < 8; i++)
5254         {
5255                 if (pAd->Mlme.ShiftReg & 0x00000001)
5256                 {
5257                         pAd->Mlme.ShiftReg = ((pAd->Mlme.ShiftReg ^ LFSR_MASK) >> 1) | 0x80000000;
5258                         Result = 1;
5259                 }
5260                 else
5261                 {
5262                         pAd->Mlme.ShiftReg = pAd->Mlme.ShiftReg >> 1;
5263                         Result = 0;
5264                 }
5265                 R = (R << 1) | Result;
5266         }
5267
5268         return R;
5269 }
5270
5271 VOID AsicUpdateAutoFallBackTable(
5272         IN      PRTMP_ADAPTER   pAd,
5273         IN      PUCHAR                  pRateTable)
5274 {
5275         UCHAR                                   i;
5276         HT_FBK_CFG0_STRUC               HtCfg0;
5277         HT_FBK_CFG1_STRUC               HtCfg1;
5278         LG_FBK_CFG0_STRUC               LgCfg0;
5279         LG_FBK_CFG1_STRUC               LgCfg1;
5280         PRTMP_TX_RATE_SWITCH    pCurrTxRate, pNextTxRate;
5281
5282         // set to initial value
5283         HtCfg0.word = 0x65432100;
5284         HtCfg1.word = 0xedcba988;
5285         LgCfg0.word = 0xedcba988;
5286         LgCfg1.word = 0x00002100;
5287
5288         pNextTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1;
5289         for (i = 1; i < *((PUCHAR) pRateTable); i++)
5290         {
5291                 pCurrTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1+i;
5292                 switch (pCurrTxRate->Mode)
5293                 {
5294                         case 0:         //CCK
5295                                 break;
5296                         case 1:         //OFDM
5297                                 {
5298                                         switch(pCurrTxRate->CurrMCS)
5299                                         {
5300                                                 case 0:
5301                                                         LgCfg0.field.OFDMMCS0FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5302                                                         break;
5303                                                 case 1:
5304                                                         LgCfg0.field.OFDMMCS1FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5305                                                         break;
5306                                                 case 2:
5307                                                         LgCfg0.field.OFDMMCS2FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5308                                                         break;
5309                                                 case 3:
5310                                                         LgCfg0.field.OFDMMCS3FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5311                                                         break;
5312                                                 case 4:
5313                                                         LgCfg0.field.OFDMMCS4FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5314                                                         break;
5315                                                 case 5:
5316                                                         LgCfg0.field.OFDMMCS5FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5317                                                         break;
5318                                                 case 6:
5319                                                         LgCfg0.field.OFDMMCS6FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5320                                                         break;
5321                                                 case 7:
5322                                                         LgCfg0.field.OFDMMCS7FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5323                                                         break;
5324                                         }
5325                                 }
5326                                 break;
5327                         case 2:         //HT-MIX
5328                         case 3:         //HT-GF
5329                                 {
5330                                         if ((pNextTxRate->Mode >= MODE_HTMIX) && (pCurrTxRate->CurrMCS != pNextTxRate->CurrMCS))
5331                                         {
5332                                                 switch(pCurrTxRate->CurrMCS)
5333                                                 {
5334                                                         case 0:
5335                                                                 HtCfg0.field.HTMCS0FBK = pNextTxRate->CurrMCS;
5336                                                                 break;
5337                                                         case 1:
5338                                                                 HtCfg0.field.HTMCS1FBK = pNextTxRate->CurrMCS;
5339                                                                 break;
5340                                                         case 2:
5341                                                                 HtCfg0.field.HTMCS2FBK = pNextTxRate->CurrMCS;
5342                                                                 break;
5343                                                         case 3:
5344                                                                 HtCfg0.field.HTMCS3FBK = pNextTxRate->CurrMCS;
5345                                                                 break;
5346                                                         case 4:
5347                                                                 HtCfg0.field.HTMCS4FBK = pNextTxRate->CurrMCS;
5348                                                                 break;
5349                                                         case 5:
5350                                                                 HtCfg0.field.HTMCS5FBK = pNextTxRate->CurrMCS;
5351                                                                 break;
5352                                                         case 6:
5353                                                                 HtCfg0.field.HTMCS6FBK = pNextTxRate->CurrMCS;
5354                                                                 break;
5355                                                         case 7:
5356                                                                 HtCfg0.field.HTMCS7FBK = pNextTxRate->CurrMCS;
5357                                                                 break;
5358                                                         case 8:
5359                                                                 HtCfg1.field.HTMCS8FBK = pNextTxRate->CurrMCS;
5360                                                                 break;
5361                                                         case 9:
5362                                                                 HtCfg1.field.HTMCS9FBK = pNextTxRate->CurrMCS;
5363                                                                 break;
5364                                                         case 10:
5365                                                                 HtCfg1.field.HTMCS10FBK = pNextTxRate->CurrMCS;
5366                                                                 break;
5367                                                         case 11:
5368                                                                 HtCfg1.field.HTMCS11FBK = pNextTxRate->CurrMCS;
5369                                                                 break;
5370                                                         case 12:
5371                                                                 HtCfg1.field.HTMCS12FBK = pNextTxRate->CurrMCS;
5372                                                                 break;
5373                                                         case 13:
5374                                                                 HtCfg1.field.HTMCS13FBK = pNextTxRate->CurrMCS;
5375                                                                 break;
5376                                                         case 14:
5377                                                                 HtCfg1.field.HTMCS14FBK = pNextTxRate->CurrMCS;
5378                                                                 break;
5379                                                         case 15:
5380                                                                 HtCfg1.field.HTMCS15FBK = pNextTxRate->CurrMCS;
5381                                                                 break;
5382                                                         default:
5383                                                                 DBGPRINT(RT_DEBUG_ERROR, ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n", pCurrTxRate->CurrMCS));
5384                                                 }
5385                                         }
5386                                 }
5387                                 break;
5388                 }
5389
5390                 pNextTxRate = pCurrTxRate;
5391         }
5392
5393         RTMP_IO_WRITE32(pAd, HT_FBK_CFG0, HtCfg0.word);
5394         RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, HtCfg1.word);
5395         RTMP_IO_WRITE32(pAd, LG_FBK_CFG0, LgCfg0.word);
5396         RTMP_IO_WRITE32(pAd, LG_FBK_CFG1, LgCfg1.word);
5397 }
5398
5399 /*
5400         ========================================================================
5401
5402         Routine Description:
5403                 Set MAC register value according operation mode.
5404                 OperationMode AND bNonGFExist are for MM and GF Proteciton.
5405                 If MM or GF mask is not set, those passing argument doesn't not take effect.
5406
5407                 Operation mode meaning:
5408                 = 0 : Pure HT, no preotection.
5409                 = 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS.
5410                 = 0x10: No Transmission in 40M is protected.
5411                 = 0x11: Transmission in both 40M and 20M shall be protected
5412                 if (bNonGFExist)
5413                         we should choose not to use GF. But still set correct ASIC registers.
5414         ========================================================================
5415 */
5416 VOID    AsicUpdateProtect(
5417         IN              PRTMP_ADAPTER   pAd,
5418         IN              USHORT                  OperationMode,
5419         IN              UCHAR                   SetMask,
5420         IN              BOOLEAN                 bDisableBGProtect,
5421         IN              BOOLEAN                 bNonGFExist)
5422 {
5423         PROT_CFG_STRUC  ProtCfg, ProtCfg4;
5424         UINT32 Protect[6];
5425         USHORT                  offset;
5426         UCHAR                   i;
5427         UINT32 MacReg = 0;
5428
5429         if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8))
5430         {
5431                 return;
5432         }
5433
5434         if (pAd->BATable.numAsOriginator)
5435         {
5436                 //
5437                 // enable the RTS/CTS to avoid channel collision
5438                 //
5439                 SetMask = ALLN_SETPROTECT;
5440                 OperationMode = 8;
5441         }
5442
5443         // Config ASIC RTS threshold register
5444         RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
5445         MacReg &= 0xFF0000FF;
5446
5447         // If the user want disable RtsThreshold and enable Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096
5448         if ((
5449                         (pAd->CommonCfg.BACapability.field.AmsduEnable) ||
5450                         (pAd->CommonCfg.bAggregationCapable == TRUE))
5451             && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD)
5452         {
5453                         MacReg |= (0x1000 << 8);
5454         }
5455         else
5456         {
5457                         MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
5458         }
5459
5460         RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
5461
5462         // Initial common protection settings
5463         RTMPZeroMemory(Protect, sizeof(Protect));
5464         ProtCfg4.word = 0;
5465         ProtCfg.word = 0;
5466         ProtCfg.field.TxopAllowGF40 = 1;
5467         ProtCfg.field.TxopAllowGF20 = 1;
5468         ProtCfg.field.TxopAllowMM40 = 1;
5469         ProtCfg.field.TxopAllowMM20 = 1;
5470         ProtCfg.field.TxopAllowOfdm = 1;
5471         ProtCfg.field.TxopAllowCck = 1;
5472         ProtCfg.field.RTSThEn = 1;
5473         ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
5474
5475         // update PHY mode and rate
5476         if (pAd->CommonCfg.Channel > 14)
5477                 ProtCfg.field.ProtectRate = 0x4000;
5478         ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate;
5479
5480         // Handle legacy(B/G) protection
5481         if (bDisableBGProtect)
5482         {
5483                 //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
5484                 ProtCfg.field.ProtectCtrl = 0;
5485                 Protect[0] = ProtCfg.word;
5486                 Protect[1] = ProtCfg.word;
5487         }
5488         else
5489         {
5490                 //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
5491                 ProtCfg.field.ProtectCtrl = 0;                  // CCK do not need to be protected
5492                 Protect[0] = ProtCfg.word;
5493                 ProtCfg.field.ProtectCtrl = ASIC_CTS;   // OFDM needs using CCK to protect
5494                 Protect[1] = ProtCfg.word;
5495         }
5496
5497         // Decide HT frame protection.
5498         if ((SetMask & ALLN_SETPROTECT) != 0)
5499         {
5500                 switch(OperationMode)
5501                 {
5502                         case 0x0:
5503                                 // NO PROTECT
5504                                 // 1.All STAs in the BSS are 20/40 MHz HT
5505                                 // 2. in ai 20/40MHz BSS
5506                                 // 3. all STAs are 20MHz in a 20MHz BSS
5507                                 // Pure HT. no protection.
5508
5509                                 // MM20_PROT_CFG
5510                                 //      Reserved (31:27)
5511                                 //      PROT_TXOP(25:20) -- 010111
5512                                 //      PROT_NAV(19:18)  -- 01 (Short NAV protection)
5513                                 //  PROT_CTRL(17:16) -- 00 (None)
5514                                 //      PROT_RATE(15:0)  -- 0x4004 (OFDM 24M)
5515                                 Protect[2] = 0x01744004;
5516
5517                                 // MM40_PROT_CFG
5518                                 //      Reserved (31:27)
5519                                 //      PROT_TXOP(25:20) -- 111111
5520                                 //      PROT_NAV(19:18)  -- 01 (Short NAV protection)
5521                                 //  PROT_CTRL(17:16) -- 00 (None)
5522                                 //      PROT_RATE(15:0)  -- 0x4084 (duplicate OFDM 24M)
5523                                 Protect[3] = 0x03f44084;
5524
5525                                 // CF20_PROT_CFG
5526                                 //      Reserved (31:27)
5527                                 //      PROT_TXOP(25:20) -- 010111
5528                                 //      PROT_NAV(19:18)  -- 01 (Short NAV protection)
5529                                 //  PROT_CTRL(17:16) -- 00 (None)
5530                                 //      PROT_RATE(15:0)  -- 0x4004 (OFDM 24M)
5531                                 Protect[4] = 0x01744004;
5532
5533                                 // CF40_PROT_CFG
5534                                 //      Reserved (31:27)
5535                                 //      PROT_TXOP(25:20) -- 111111
5536                                 //      PROT_NAV(19:18)  -- 01 (Short NAV protection)
5537                                 //  PROT_CTRL(17:16) -- 00 (None)
5538                                 //      PROT_RATE(15:0)  -- 0x4084 (duplicate OFDM 24M)
5539                                 Protect[5] = 0x03f44084;
5540
5541                                 if (bNonGFExist)
5542                                 {
5543                                         // PROT_NAV(19:18)  -- 01 (Short NAV protectiion)
5544                                         // PROT_CTRL(17:16) -- 01 (RTS/CTS)
5545                                         Protect[4] = 0x01754004;
5546                                         Protect[5] = 0x03f54084;
5547                                 }
5548                                 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
5549                                 break;
5550
5551                         case 1:
5552                                 // This is "HT non-member protection mode."
5553                                 // If there may be non-HT STAs my BSS
5554                                 ProtCfg.word = 0x01744004;      // PROT_CTRL(17:16) : 0 (None)
5555                                 ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
5556                                 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
5557                                 {
5558                                         ProtCfg.word = 0x01740003;      //ERP use Protection bit is set, use protection rate at Clause 18..
5559                                         ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083;
5560                                 }
5561                                 //Assign Protection method for 20&40 MHz packets
5562                                 ProtCfg.field.ProtectCtrl = ASIC_RTS;
5563                                 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
5564                                 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
5565                                 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
5566                                 Protect[2] = ProtCfg.word;
5567                                 Protect[3] = ProtCfg4.word;
5568                                 Protect[4] = ProtCfg.word;
5569                                 Protect[5] = ProtCfg4.word;
5570                                 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
5571                                 break;
5572
5573                         case 2:
5574                                 // If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets
5575                                 ProtCfg.word = 0x01744004;  // PROT_CTRL(17:16) : 0 (None)
5576                                 ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
5577
5578                                 //Assign Protection method for 40MHz packets
5579                                 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
5580                                 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
5581                                 Protect[2] = ProtCfg.word;
5582                                 Protect[3] = ProtCfg4.word;
5583                                 if (bNonGFExist)
5584                                 {
5585                                         ProtCfg.field.ProtectCtrl = ASIC_RTS;
5586                                         ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
5587                                 }
5588                                 Protect[4] = ProtCfg.word;
5589                                 Protect[5] = ProtCfg4.word;
5590
5591                                 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
5592                                 break;
5593
5594                         case 3:
5595                                 // HT mixed mode.        PROTECT ALL!
5596                                 // Assign Rate
5597                                 ProtCfg.word = 0x01744004;      //duplicaet legacy 24M. BW set 1.
5598                                 ProtCfg4.word = 0x03f44084;
5599                                 // both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the
5600                                 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
5601                                 {
5602                                         ProtCfg.word = 0x01740003;      //ERP use Protection bit is set, use protection rate at Clause 18..
5603                                         ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083
5604                                 }
5605                                 //Assign Protection method for 20&40 MHz packets
5606                                 ProtCfg.field.ProtectCtrl = ASIC_RTS;
5607                                 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
5608                                 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
5609                                 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
5610                                 Protect[2] = ProtCfg.word;
5611                                 Protect[3] = ProtCfg4.word;
5612                                 Protect[4] = ProtCfg.word;
5613                                 Protect[5] = ProtCfg4.word;
5614                                 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
5615                                 break;
5616
5617                         case 8:
5618                                 // Special on for Atheros problem n chip.
5619                                 Protect[2] = 0x01754004;
5620                                 Protect[3] = 0x03f54084;
5621                                 Protect[4] = 0x01754004;
5622                                 Protect[5] = 0x03f54084;
5623                                 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
5624                                 break;
5625                 }
5626         }
5627
5628         offset = CCK_PROT_CFG;
5629         for (i = 0;i < 6;i++)
5630         {
5631                 if ((SetMask & (1<< i)))
5632                 {
5633                         RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]);
5634                 }
5635         }
5636 }
5637
5638 #ifdef RT30xx
5639 // add by johnli, RF power sequence setup
5640 /*
5641         ==========================================================================
5642         Description:
5643
5644         Load RF normal operation-mode setup
5645
5646         ==========================================================================
5647  */
5648 VOID RT30xxLoadRFNormalModeSetup(
5649         IN PRTMP_ADAPTER        pAd)
5650 {
5651         UCHAR RFValue;
5652
5653         // 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
5654         RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
5655         RFValue = (RFValue & (~0x0C)) | 0x31;
5656         RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
5657
5658         // TX_LO2_en, RF R15 register Bit 3 to 0
5659         RT30xxReadRFRegister(pAd, RF_R15, &RFValue);
5660         RFValue &= (~0x08);
5661         RT30xxWriteRFRegister(pAd, RF_R15, RFValue);
5662
5663         // TX_LO1_en, RF R17 register Bit 3 to 0
5664         RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
5665         RFValue &= (~0x08);
5666         // to fix rx long range issue
5667         if (((pAd->MACVersion & 0xffff) >= 0x0211) && (pAd->NicConfig2.field.ExternalLNAForG == 0))
5668         {
5669                 RFValue |= 0x20;
5670         }
5671         RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
5672
5673         // RX_LO1_en, RF R20 register Bit 3 to 0
5674         RT30xxReadRFRegister(pAd, RF_R20, &RFValue);
5675         RFValue &= (~0x08);
5676         RT30xxWriteRFRegister(pAd, RF_R20, RFValue);
5677
5678         // RX_LO2_en, RF R21 register Bit 3 to 0
5679         RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
5680         RFValue &= (~0x08);
5681         RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
5682
5683         // LDORF_VC, RF R27 register Bit 2 to 0
5684         RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
5685         if ((pAd->MACVersion & 0xffff) < 0x0211)
5686                 RFValue = (RFValue & (~0x77)) | 0x3;
5687         else
5688                 RFValue = (RFValue & (~0x77));
5689         RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
5690         /* end johnli */
5691 }
5692
5693 /*
5694         ==========================================================================
5695         Description:
5696
5697         Load RF sleep-mode setup
5698
5699         ==========================================================================
5700  */
5701 VOID RT30xxLoadRFSleepModeSetup(
5702         IN PRTMP_ADAPTER        pAd)
5703 {
5704         UCHAR RFValue;
5705         UINT32 MACValue;
5706
5707         // RF_BLOCK_en. RF R1 register Bit 0 to 0
5708         RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
5709         RFValue &= (~0x01);
5710         RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
5711
5712         // VCO_IC, RF R7 register Bit 4 & Bit 5 to 0
5713         RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
5714         RFValue &= (~0x30);
5715         RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
5716
5717         // Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 0
5718         RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
5719         RFValue &= (~0x0E);
5720         RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
5721
5722         // RX_CTB_en, RF R21 register Bit 7 to 0
5723         RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
5724         RFValue &= (~0x80);
5725         RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
5726
5727         // LDORF_VC, RF R27 register Bit 0, Bit 1 & Bit 2 to 1
5728         RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
5729         RFValue |= 0x77;
5730         RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
5731
5732         RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
5733         MACValue |= 0x1D000000;
5734         RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
5735 }
5736
5737 /*
5738         ==========================================================================
5739         Description:
5740
5741         Reverse RF sleep-mode setup
5742
5743         ==========================================================================
5744  */
5745 VOID RT30xxReverseRFSleepModeSetup(
5746         IN PRTMP_ADAPTER        pAd)
5747 {
5748         UCHAR RFValue;
5749         UINT32 MACValue;
5750
5751         // RF_BLOCK_en, RF R1 register Bit 0 to 1
5752         RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
5753         RFValue |= 0x01;
5754         RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
5755
5756         // VCO_IC, RF R7 register Bit 4 & Bit 5 to 1
5757         RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
5758         RFValue |= 0x30;
5759         RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
5760
5761         // Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 1
5762         RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
5763         RFValue |= 0x0E;
5764         RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
5765
5766         // RX_CTB_en, RF R21 register Bit 7 to 1
5767         RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
5768         RFValue |= 0x80;
5769         RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
5770
5771         // LDORF_VC, RF R27 register Bit 2 to 0
5772         RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
5773         if ((pAd->MACVersion & 0xffff) < 0x0211)
5774                 RFValue = (RFValue & (~0x77)) | 0x3;
5775         else
5776                 RFValue = (RFValue & (~0x77));
5777         RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
5778
5779         // RT3071 version E has fixed this issue
5780         if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211))
5781         {
5782                 // patch tx EVM issue temporarily
5783                 RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
5784                 MACValue = ((MACValue & 0xE0FFFFFF) | 0x0D000000);
5785                 RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
5786         }
5787         else
5788         {
5789                 RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
5790                 MACValue = ((MACValue & 0xE0FFFFFF) | 0x01000000);
5791                 RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
5792         }
5793 }
5794 // end johnli
5795 #endif // RT30xx //
5796
5797 /*
5798         ==========================================================================
5799         Description:
5800
5801         IRQL = PASSIVE_LEVEL
5802         IRQL = DISPATCH_LEVEL
5803
5804         ==========================================================================
5805  */
5806 VOID AsicSwitchChannel(
5807                                           IN PRTMP_ADAPTER pAd,
5808         IN      UCHAR                   Channel,
5809         IN      BOOLEAN                 bScan)
5810 {
5811         ULONG                   R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0;
5812         CHAR    TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; //Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER;
5813         UCHAR   index;
5814         UINT32  Value = 0; //BbpReg, Value;
5815         RTMP_RF_REGS *RFRegTable;
5816
5817         // Search Tx power value
5818 #ifdef RT30xx
5819         // We can't use ChannelList to search channel, since some central channl's txpowr doesn't list
5820         // in ChannelList, so use TxPower array instead.
5821         //
5822         for (index = 0; index < MAX_NUM_OF_CHANNELS; index++)
5823         {
5824                 if (Channel == pAd->TxPower[index].Channel)
5825         {
5826                         TxPwer = pAd->TxPower[index].Power;
5827                         TxPwer2 = pAd->TxPower[index].Power2;
5828                         break;
5829                 }
5830         }
5831 #endif
5832 #ifndef RT30xx
5833         for (index = 0; index < pAd->ChannelListNum; index++)
5834         {
5835                 if (Channel == pAd->ChannelList[index].Channel)
5836                 {
5837                         TxPwer = pAd->ChannelList[index].Power;
5838                         TxPwer2 = pAd->ChannelList[index].Power2;
5839                         break;
5840                 }
5841         }
5842 #endif
5843
5844         if (index == MAX_NUM_OF_CHANNELS)
5845         {
5846 #ifndef RT30xx
5847                 DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Cant find the Channel#%d \n", Channel));
5848 #endif
5849 #ifdef RT30xx
5850                 DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel));
5851 #endif
5852         }
5853
5854 #ifdef RT2870
5855         // The RF programming sequence is difference between 3xxx and 2xxx
5856 #ifdef RT30xx
5857         if ((IS_RT3070(pAd) || IS_RT3090(pAd)) && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020) ||
5858                 (pAd->RfIcType == RFIC_3021) || (pAd->RfIcType == RFIC_3022)))
5859 #endif
5860 #ifndef RT30xx
5861         if (IS_RT3070(pAd) && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020)))
5862 #endif
5863         {
5864                 /* modify by WY for Read RF Reg. error */
5865                 UCHAR RFValue;
5866
5867                 for (index = 0; index < NUM_OF_3020_CHNL; index++)
5868                 {
5869                         if (Channel == FreqItems3020[index].Channel)
5870                         {
5871                                 // Programming channel parameters
5872                                 RT30xxWriteRFRegister(pAd, RF_R02, FreqItems3020[index].N);
5873                                 RT30xxWriteRFRegister(pAd, RF_R03, FreqItems3020[index].K);
5874
5875 #ifndef RT30xx
5876                                 RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RFValue);
5877                                 RFValue = (RFValue & 0xFC) | FreqItems3020[index].R;
5878                                 RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RFValue);
5879
5880                                 // Set Tx Power
5881                                 RT30xxReadRFRegister(pAd, RF_R12, (PUCHAR)&RFValue);
5882                                 RFValue = (RFValue & 0xE0) | TxPwer;
5883                                 RT30xxWriteRFRegister(pAd, RF_R12, (UCHAR)RFValue);
5884
5885                                 // Set RF offset
5886                                 RT30xxReadRFRegister(pAd, RF_R23, (PUCHAR)&RFValue);
5887                                 RFValue = (RFValue & 0x80) | pAd->RfFreqOffset;
5888                                 RT30xxWriteRFRegister(pAd, RF_R23, (UCHAR)RFValue);
5889 #endif
5890 #ifdef RT30xx
5891                                 RT30xxReadRFRegister(pAd, RF_R06, &RFValue);
5892                                 RFValue = (RFValue & 0xFC) | FreqItems3020[index].R;
5893                                 RT30xxWriteRFRegister(pAd, RF_R06, RFValue);
5894
5895                                 // Set Tx0 Power
5896                                 RT30xxReadRFRegister(pAd, RF_R12, &RFValue);
5897                                 RFValue = (RFValue & 0xE0) | TxPwer;
5898                                 RT30xxWriteRFRegister(pAd, RF_R12, RFValue);
5899
5900                                 // Set Tx1 Power
5901                                 RT30xxReadRFRegister(pAd, RF_R13, &RFValue);
5902                                 RFValue = (RFValue & 0xE0) | TxPwer2;
5903                                 RT30xxWriteRFRegister(pAd, RF_R13, RFValue);
5904
5905                                 // Tx/Rx Stream setting
5906                                 RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
5907                                 //if (IS_RT3090(pAd))
5908                                 //      RFValue |= 0x01; // Enable RF block.
5909                                 RFValue &= 0x03;        //clear bit[7~2]
5910                                 if (pAd->Antenna.field.TxPath == 1)
5911                                         RFValue |= 0xA0;
5912                                 else if (pAd->Antenna.field.TxPath == 2)
5913                                         RFValue |= 0x80;
5914                                 if (pAd->Antenna.field.RxPath == 1)
5915                                         RFValue |= 0x50;
5916                                 else if (pAd->Antenna.field.RxPath == 2)
5917                                         RFValue |= 0x40;
5918                                 RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
5919
5920                                 // Set RF offset
5921                                 RT30xxReadRFRegister(pAd, RF_R23, &RFValue);
5922                                 RFValue = (RFValue & 0x80) | pAd->RfFreqOffset;
5923                                 RT30xxWriteRFRegister(pAd, RF_R23, RFValue);
5924 #endif
5925
5926                                 // Set BW
5927                                 if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
5928                                 {
5929                                         RFValue = pAd->Mlme.CaliBW40RfR24;
5930                                         //DISABLE_11N_CHECK(pAd);
5931                                 }
5932                                 else
5933                                 {
5934                                         RFValue = pAd->Mlme.CaliBW20RfR24;
5935                                 }
5936 #ifndef RT30xx
5937                                 RT30xxWriteRFRegister(pAd, RF_R24, (UCHAR)RFValue);
5938
5939                                 // Enable RF tuning
5940                                 RT30xxReadRFRegister(pAd, RF_R07, (PUCHAR)&RFValue);
5941                                 RFValue = RFValue | 0x1;
5942                                 RT30xxWriteRFRegister(pAd, RF_R07, (UCHAR)RFValue);
5943
5944                                 // latch channel for future usage.
5945                                 pAd->LatchRfRegs.Channel = Channel;
5946 #endif
5947 #ifdef RT30xx
5948                                 RT30xxWriteRFRegister(pAd, RF_R24, RFValue);
5949                                 RT30xxWriteRFRegister(pAd, RF_R31, RFValue);
5950
5951                                 // Enable RF tuning
5952                                 RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
5953                                 RFValue = RFValue | 0x1;
5954                                 RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
5955
5956                                 // latch channel for future usage.
5957                                 pAd->LatchRfRegs.Channel = Channel;
5958
5959                                 DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
5960                                         Channel,
5961                                         pAd->RfIcType,
5962                                         TxPwer,
5963                                         TxPwer2,
5964                                         pAd->Antenna.field.TxPath,
5965                                         FreqItems3020[index].N,
5966                                         FreqItems3020[index].K,
5967                                         FreqItems3020[index].R));
5968 #endif
5969
5970                                 break;
5971                         }
5972                 }
5973
5974 #ifndef RT30xx
5975                 DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
5976                         Channel,
5977                         pAd->RfIcType,
5978                         TxPwer,
5979                         TxPwer2,
5980                         pAd->Antenna.field.TxPath,
5981                         FreqItems3020[index].N,
5982                         FreqItems3020[index].K,
5983                         FreqItems3020[index].R));
5984 #endif
5985         }
5986         else
5987 #endif // RT2870 //
5988         {
5989                 RFRegTable = RF2850RegTable;
5990
5991                 switch (pAd->RfIcType)
5992                 {
5993                         case RFIC_2820:
5994                         case RFIC_2850:
5995                         case RFIC_2720:
5996                         case RFIC_2750:
5997
5998                         for (index = 0; index < NUM_OF_2850_CHNL; index++)
5999                         {
6000                                 if (Channel == RFRegTable[index].Channel)
6001                                 {
6002                                         R2 = RFRegTable[index].R2;
6003                                         if (pAd->Antenna.field.TxPath == 1)
6004                                         {
6005                                                 R2 |= 0x4000;   // If TXpath is 1, bit 14 = 1;
6006                                         }
6007
6008                                         if (pAd->Antenna.field.RxPath == 2)
6009                                         {
6010                                                 R2 |= 0x40;     // write 1 to off Rxpath.
6011                                         }
6012                                         else if (pAd->Antenna.field.RxPath == 1)
6013                                         {
6014                                                 R2 |= 0x20040;  // write 1 to off RxPath
6015                                         }
6016
6017                                         if (Channel > 14)
6018                                         {
6019                                                 // initialize R3, R4
6020                                                 R3 = (RFRegTable[index].R3 & 0xffffc1ff);
6021                                                 R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15);
6022
6023                                                 // 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB
6024                                                 // R3
6025                                                 if ((TxPwer >= -7) && (TxPwer < 0))
6026                                                 {
6027                                                         TxPwer = (7+TxPwer);
6028                                                         TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
6029                                                         R3 |= (TxPwer << 10);
6030                                                         DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer=%d \n", TxPwer));
6031                                                 }
6032                                                 else
6033                                                 {
6034                                                         TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
6035                                                         R3 |= (TxPwer << 10) | (1 << 9);
6036                                                 }
6037
6038                                                 // R4
6039                                                 if ((TxPwer2 >= -7) && (TxPwer2 < 0))
6040                                                 {
6041                                                         TxPwer2 = (7+TxPwer2);
6042                                                         TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
6043                                                         R4 |= (TxPwer2 << 7);
6044                                                         DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer2=%d \n", TxPwer2));
6045                                                 }
6046                                                 else
6047                                                 {
6048                                                         TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
6049                                                         R4 |= (TxPwer2 << 7) | (1 << 6);
6050                                                 }
6051                                         }
6052                                         else
6053                                         {
6054                                                 R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); // set TX power0
6055                                         R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 <<6);// Set freq Offset & TxPwr1
6056                                         }
6057
6058                                         // Based on BBP current mode before changing RF channel.
6059                                         if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
6060                                         {
6061                                                 R4 |=0x200000;
6062                                         }
6063
6064                                         // Update variables
6065                                         pAd->LatchRfRegs.Channel = Channel;
6066                                         pAd->LatchRfRegs.R1 = RFRegTable[index].R1;
6067                                         pAd->LatchRfRegs.R2 = R2;
6068                                         pAd->LatchRfRegs.R3 = R3;
6069                                         pAd->LatchRfRegs.R4 = R4;
6070
6071                                         // Set RF value 1's set R3[bit2] = [0]
6072                                         RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
6073                                         RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
6074                                         RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
6075                                         RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
6076
6077                                         RTMPusecDelay(200);
6078
6079                                         // Set RF value 2's set R3[bit2] = [1]
6080                                         RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
6081                                         RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
6082                                         RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04));
6083                                         RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
6084
6085                                         RTMPusecDelay(200);
6086
6087                                         // Set RF value 3's set R3[bit2] = [0]
6088                                         RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
6089                                         RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
6090                                         RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
6091                                         RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
6092
6093                                         break;
6094                                 }
6095                         }
6096                         break;
6097
6098                         default:
6099                         break;
6100                 }
6101         }
6102
6103         // Change BBP setting during siwtch from a->g, g->a
6104         if (Channel <= 14)
6105         {
6106             ULONG       TxPinCfg = 0x00050F0A;//Gary 2007/08/09 0x050A0A
6107
6108                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
6109                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
6110                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
6111                 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.
6112                 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
6113
6114                 // Rx High power VGA offset for LNA select
6115             if (pAd->NicConfig2.field.ExternalLNAForG)
6116             {
6117                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
6118                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
6119             }
6120             else
6121             {
6122                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
6123                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
6124             }
6125
6126                 // 5G band selection PIN, bit1 and bit2 are complement
6127                 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
6128                 Value &= (~0x6);
6129                 Value |= (0x04);
6130                 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
6131
6132         // Turn off unused PA or LNA when only 1T or 1R
6133                 if (pAd->Antenna.field.TxPath == 1)
6134                 {
6135                         TxPinCfg &= 0xFFFFFFF3;
6136                 }
6137                 if (pAd->Antenna.field.RxPath == 1)
6138                 {
6139                         TxPinCfg &= 0xFFFFF3FF;
6140                 }
6141
6142                 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
6143         }
6144         else
6145         {
6146             ULONG       TxPinCfg = 0x00050F05;//Gary 2007/8/9 0x050505
6147
6148                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
6149                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
6150                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
6151                 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.
6152                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
6153
6154                 // Rx High power VGA offset for LNA select
6155                 if (pAd->NicConfig2.field.ExternalLNAForA)
6156                 {
6157                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
6158                 }
6159                 else
6160                 {
6161                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
6162                 }
6163
6164                 // 5G band selection PIN, bit1 and bit2 are complement
6165                 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
6166                 Value &= (~0x6);
6167                 Value |= (0x02);
6168                 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
6169
6170         // Turn off unused PA or LNA when only 1T or 1R
6171                 if (pAd->Antenna.field.TxPath == 1)
6172                 {
6173                         TxPinCfg &= 0xFFFFFFF3;
6174         }
6175                 if (pAd->Antenna.field.RxPath == 1)
6176                 {
6177                         TxPinCfg &= 0xFFFFF3FF;
6178         }
6179
6180                 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
6181         }
6182
6183     // R66 should be set according to Channel and use 20MHz when scanning
6184         //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd)));
6185         if (bScan)
6186                 RTMPSetAGCInitValue(pAd, BW_20);
6187         else
6188                 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
6189
6190         //
6191         // On 11A, We should delay and wait RF/BBP to be stable
6192         // and the appropriate time should be 1000 micro seconds
6193         // 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
6194         //
6195         RTMPusecDelay(1000);
6196
6197         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",
6198                                                           Channel,
6199                                                           pAd->RfIcType,
6200                                                           (R3 & 0x00003e00) >> 9,
6201                                                           (R4 & 0x000007c0) >> 6,
6202                                                           pAd->Antenna.field.TxPath,
6203                                                           pAd->LatchRfRegs.R1,
6204                                                           pAd->LatchRfRegs.R2,
6205                                                           pAd->LatchRfRegs.R3,
6206                                                           pAd->LatchRfRegs.R4));
6207 }
6208
6209 /*
6210         ==========================================================================
6211         Description:
6212                 This function is required for 2421 only, and should not be used during
6213                 site survey. It's only required after NIC decided to stay at a channel
6214                 for a longer period.
6215                 When this function is called, it's always after AsicSwitchChannel().
6216
6217         IRQL = PASSIVE_LEVEL
6218         IRQL = DISPATCH_LEVEL
6219
6220         ==========================================================================
6221  */
6222 VOID AsicLockChannel(
6223         IN PRTMP_ADAPTER pAd,
6224         IN UCHAR Channel)
6225 {
6226 }
6227
6228 /*
6229         ==========================================================================
6230         Description:
6231
6232         IRQL = PASSIVE_LEVEL
6233         IRQL = DISPATCH_LEVEL
6234
6235         ==========================================================================
6236  */
6237 VOID    AsicAntennaSelect(
6238         IN      PRTMP_ADAPTER   pAd,
6239         IN      UCHAR                   Channel)
6240 {
6241 #ifdef RT30xx
6242                         if (pAd->Mlme.OneSecPeriodicRound % 2 == 1)
6243                         {
6244                                 // patch for AsicSetRxAnt failed
6245                                 pAd->RxAnt.EvaluatePeriod = 0;
6246
6247                                 // check every 2 second. If rcv-beacon less than 5 in the past 2 second, then AvgRSSI is no longer a
6248                                 // valid indication of the distance between this AP and its clients.
6249                                 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
6250                                 {
6251                                         SHORT   realavgrssi1;
6252
6253                                         // if no traffic then reset average rssi to trigger evaluation
6254                                         if (pAd->StaCfg.NumOfAvgRssiSample < 5)
6255                                         {
6256                                                 pAd->RxAnt.Pair1LastAvgRssi = (-99);
6257                                                 pAd->RxAnt.Pair2LastAvgRssi = (-99);
6258                                                 DBGPRINT(RT_DEBUG_TRACE, ("MlmePeriodicExec: no traffic/beacon, reset RSSI\n"));
6259                                         }
6260
6261                                         pAd->StaCfg.NumOfAvgRssiSample = 0;
6262                                         realavgrssi1 = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt] >> 3);
6263
6264                                         DBGPRINT(RT_DEBUG_TRACE,("Ant-realrssi0(%d), Lastrssi0(%d), EvaluateStableCnt=%d\n", realavgrssi1, pAd->RxAnt.Pair1LastAvgRssi, pAd->RxAnt.EvaluateStableCnt));
6265
6266                                         // if the difference between two rssi is larger or less than 5, then evaluate the other antenna
6267                                         if ((pAd->RxAnt.EvaluateStableCnt < 2) || (realavgrssi1 > (pAd->RxAnt.Pair1LastAvgRssi + 5)) || (realavgrssi1 < (pAd->RxAnt.Pair1LastAvgRssi - 5)))
6268                                         {
6269                                                 pAd->RxAnt.Pair1LastAvgRssi = realavgrssi1;
6270                                                 AsicEvaluateRxAnt(pAd);
6271                                         }
6272                                 }
6273                                 else
6274                                 {
6275                                         // if not connected, always switch antenna to try to connect
6276                                         UCHAR   temp;
6277
6278                                         temp = pAd->RxAnt.Pair1PrimaryRxAnt;
6279                                         pAd->RxAnt.Pair1PrimaryRxAnt = pAd->RxAnt.Pair1SecondaryRxAnt;
6280                                         pAd->RxAnt.Pair1SecondaryRxAnt = temp;
6281
6282                                         DBGPRINT(RT_DEBUG_TRACE, ("MlmePeriodicExec: no connect, switch to another one to try connection\n"));
6283
6284                                         AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
6285                                 }
6286                         }
6287 #endif /* RT30xx */
6288 }
6289
6290 /*
6291         ========================================================================
6292
6293         Routine Description:
6294                 Antenna miscellaneous setting.
6295
6296         Arguments:
6297                 pAd                                             Pointer to our adapter
6298                 BandState                               Indicate current Band State.
6299
6300         Return Value:
6301                 None
6302
6303         IRQL <= DISPATCH_LEVEL
6304
6305         Note:
6306                 1.) Frame End type control
6307                         only valid for G only (RF_2527 & RF_2529)
6308                         0: means DPDT, set BBP R4 bit 5 to 1
6309                         1: means SPDT, set BBP R4 bit 5 to 0
6310
6311
6312         ========================================================================
6313 */
6314 VOID    AsicAntennaSetting(
6315         IN      PRTMP_ADAPTER   pAd,
6316         IN      ABGBAND_STATE   BandState)
6317 {
6318 }
6319
6320 VOID AsicRfTuningExec(
6321         IN PVOID SystemSpecific1,
6322         IN PVOID FunctionContext,
6323         IN PVOID SystemSpecific2,
6324         IN PVOID SystemSpecific3)
6325 {
6326 }
6327
6328 /*
6329         ==========================================================================
6330         Description:
6331                 Gives CCK TX rate 2 more dB TX power.
6332                 This routine works only in LINK UP in INFRASTRUCTURE mode.
6333
6334                 calculate desired Tx power in RF R3.Tx0~5,      should consider -
6335                 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
6336                 1. TxPowerPercentage
6337                 2. auto calibration based on TSSI feedback
6338                 3. extra 2 db for CCK
6339                 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
6340
6341         NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
6342                 it should be called AFTER MlmeDynamicTxRatSwitching()
6343         ==========================================================================
6344  */
6345 VOID AsicAdjustTxPower(
6346         IN PRTMP_ADAPTER pAd)
6347 {
6348         INT                     i, j;
6349         CHAR            DeltaPwr = 0;
6350         BOOLEAN         bAutoTxAgc = FALSE;
6351         UCHAR           TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
6352         UCHAR           BbpR1 = 0, BbpR49 = 0, idx;
6353         PCHAR           pTxAgcCompensate;
6354         ULONG           TxPwr[5];
6355         CHAR            Value;
6356
6357 #ifdef RT2860
6358         if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
6359                 || (pAd->bPCIclkOff == TRUE)
6360                 || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)
6361                 || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
6362                 return;
6363 #endif
6364
6365         if (pAd->CommonCfg.BBPCurrentBW == BW_40)
6366         {
6367                 if (pAd->CommonCfg.CentralChannel > 14)
6368                 {
6369                         TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
6370                         TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
6371                         TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
6372                         TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
6373                         TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
6374                 }
6375                 else
6376                 {
6377                         TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
6378                         TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
6379                         TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
6380                         TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
6381                         TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
6382                 }
6383         }
6384         else
6385         {
6386                 if (pAd->CommonCfg.Channel > 14)
6387                 {
6388                         TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
6389                         TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
6390                         TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
6391                         TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
6392                         TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
6393                 }
6394                 else
6395                 {
6396                         TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
6397                         TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
6398                         TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
6399                         TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
6400                         TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
6401                 }
6402         }
6403
6404         // TX power compensation for temperature variation based on TSSI. try every 4 second
6405         if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
6406         {
6407                 if (pAd->CommonCfg.Channel <= 14)
6408                 {
6409                         /* bg channel */
6410                         bAutoTxAgc         = pAd->bAutoTxAgcG;
6411                         TssiRef            = pAd->TssiRefG;
6412                         pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
6413                         pTssiPlusBoundary  = &pAd->TssiPlusBoundaryG[0];
6414                         TxAgcStep          = pAd->TxAgcStepG;
6415                         pTxAgcCompensate   = &pAd->TxAgcCompensateG;
6416                 }
6417                 else
6418                 {
6419                         /* a channel */
6420                         bAutoTxAgc         = pAd->bAutoTxAgcA;
6421                         TssiRef            = pAd->TssiRefA;
6422                         pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
6423                         pTssiPlusBoundary  = &pAd->TssiPlusBoundaryA[0];
6424                         TxAgcStep          = pAd->TxAgcStepA;
6425                         pTxAgcCompensate   = &pAd->TxAgcCompensateA;
6426                 }
6427
6428                 if (bAutoTxAgc)
6429                 {
6430                         /* BbpR1 is unsigned char */
6431                         RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
6432
6433                         /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
6434                         /* compensate: +4     +3   +2   +1    0   -1   -2   -3   -4 * steps */
6435                         /* step value is defined in pAd->TxAgcStepG for tx power value */
6436
6437                         /* [4]+1+[4]   p4     p3   p2   p1   o1   m1   m2   m3   m4 */
6438                         /* ex:         0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
6439                            above value are examined in mass factory production */
6440                         /*             [4]    [3]  [2]  [1]  [0]  [1]  [2]  [3]  [4] */
6441
6442                         /* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */
6443                         /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
6444                         /* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */
6445
6446                         if (BbpR49 > pTssiMinusBoundary[1])
6447                         {
6448                                 // Reading is larger than the reference value
6449                                 // check for how large we need to decrease the Tx power
6450                                 for (idx = 1; idx < 5; idx++)
6451                                 {
6452                                         if (BbpR49 <= pTssiMinusBoundary[idx])  // Found the range
6453                                                 break;
6454                                 }
6455                                 // The index is the step we should decrease, idx = 0 means there is nothing to compensate
6456                                 *pTxAgcCompensate = -(TxAgcStep * (idx-1));
6457
6458                                 DeltaPwr += (*pTxAgcCompensate);
6459                                 DBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
6460                                         BbpR49, TssiRef, TxAgcStep, idx-1));
6461                         }
6462                         else if (BbpR49 < pTssiPlusBoundary[1])
6463                         {
6464                                 // Reading is smaller than the reference value
6465                                 // check for how large we need to increase the Tx power
6466                                 for (idx = 1; idx < 5; idx++)
6467                                 {
6468                                         if (BbpR49 >= pTssiPlusBoundary[idx])   // Found the range
6469                                                 break;
6470                                 }
6471                                 // The index is the step we should increase, idx = 0 means there is nothing to compensate
6472                                 *pTxAgcCompensate = TxAgcStep * (idx-1);
6473                                 DeltaPwr += (*pTxAgcCompensate);
6474                                 DBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
6475                                         BbpR49, TssiRef, TxAgcStep, idx-1));
6476                         }
6477                         else
6478                         {
6479                                 *pTxAgcCompensate = 0;
6480                                 DBGPRINT(RT_DEBUG_TRACE, ("   Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
6481                                         BbpR49, TssiRef, TxAgcStep, 0));
6482                         }
6483                 }
6484         }
6485         else
6486         {
6487                 if (pAd->CommonCfg.Channel <= 14)
6488                 {
6489                         bAutoTxAgc         = pAd->bAutoTxAgcG;
6490                         pTxAgcCompensate   = &pAd->TxAgcCompensateG;
6491                 }
6492                 else
6493                 {
6494                         bAutoTxAgc         = pAd->bAutoTxAgcA;
6495                         pTxAgcCompensate   = &pAd->TxAgcCompensateA;
6496                 }
6497
6498                 if (bAutoTxAgc)
6499                         DeltaPwr += (*pTxAgcCompensate);
6500         }
6501
6502         RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1);
6503         BbpR1 &= 0xFC;
6504
6505         /* calculate delta power based on the percentage specified from UI */
6506         // E2PROM setting is calibrated for maximum TX power (i.e. 100%)
6507         // We lower TX power here according to the percentage specified from UI
6508         if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff)       // AUTO TX POWER control
6509                 ;
6510         else if (pAd->CommonCfg.TxPowerPercentage > 90)  // 91 ~ 100% & AUTO, treat as 100% in terms of mW
6511                 ;
6512         else if (pAd->CommonCfg.TxPowerPercentage > 60)  // 61 ~ 90%, treat as 75% in terms of mW               // DeltaPwr -= 1;
6513         {
6514                 DeltaPwr -= 1;
6515         }
6516         else if (pAd->CommonCfg.TxPowerPercentage > 30)  // 31 ~ 60%, treat as 50% in terms of mW               // DeltaPwr -= 3;
6517         {
6518                 DeltaPwr -= 3;
6519         }
6520         else if (pAd->CommonCfg.TxPowerPercentage > 15)  // 16 ~ 30%, treat as 25% in terms of mW               // DeltaPwr -= 6;
6521         {
6522                 BbpR1 |= 0x01;
6523         }
6524         else if (pAd->CommonCfg.TxPowerPercentage > 9)   // 10 ~ 15%, treat as 12.5% in terms of mW             // DeltaPwr -= 9;
6525         {
6526                 BbpR1 |= 0x01;
6527                 DeltaPwr -= 3;
6528         }
6529         else                                           // 0 ~ 9 %, treat as MIN(~3%) in terms of mW             // DeltaPwr -= 12;
6530         {
6531                 BbpR1 |= 0x02;
6532         }
6533
6534         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
6535
6536         /* reset different new tx power for different TX rate */
6537         for(i=0; i<5; i++)
6538         {
6539                 if (TxPwr[i] != 0xffffffff)
6540                 {
6541                         for (j=0; j<8; j++)
6542                         {
6543                                 Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */
6544
6545                                 if ((Value + DeltaPwr) < 0)
6546                                 {
6547                                         Value = 0; /* min */
6548                                 }
6549                                 else if ((Value + DeltaPwr) > 0xF)
6550                                 {
6551                                         Value = 0xF; /* max */
6552                                 }
6553                                 else
6554                                 {
6555                                         Value += DeltaPwr; /* temperature compensation */
6556                                 }
6557
6558                                 /* fill new value to CSR offset */
6559                                 TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
6560                         }
6561
6562                         /* write tx power value to CSR */
6563                         /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M
6564                                                                                         TX power for OFDM 6M/9M
6565                                                                                         TX power for CCK5.5M/11M
6566                                                                                         TX power for CCK1M/2M */
6567                         /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
6568                         RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]);
6569                 }
6570         }
6571
6572 }
6573
6574 /*
6575         ==========================================================================
6576         Description:
6577                 put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup
6578                 automatically. Instead, MCU will issue a TwakeUpInterrupt to host after
6579                 the wakeup timer timeout. Driver has to issue a separate command to wake
6580                 PHY up.
6581
6582         IRQL = DISPATCH_LEVEL
6583
6584         ==========================================================================
6585  */
6586 VOID AsicSleepThenAutoWakeup(
6587         IN PRTMP_ADAPTER pAd,
6588         IN USHORT TbttNumToNextWakeUp)
6589 {
6590     RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp);
6591 }
6592
6593 /*
6594         ==========================================================================
6595         Description:
6596                 AsicForceWakeup() is used whenever manual wakeup is required
6597                 AsicForceSleep() should only be used when not in INFRA BSS. When
6598                 in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead.
6599         ==========================================================================
6600  */
6601 VOID AsicForceSleep(
6602         IN PRTMP_ADAPTER pAd)
6603 {
6604
6605 }
6606
6607 /*
6608         ==========================================================================
6609         Description:
6610                 AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup)
6611                 expired.
6612
6613         IRQL = PASSIVE_LEVEL
6614         IRQL = DISPATCH_LEVEL
6615         ==========================================================================
6616  */
6617 VOID AsicForceWakeup(
6618         IN PRTMP_ADAPTER pAd,
6619 #ifdef RT2860
6620         IN UCHAR         Level)
6621 #endif
6622 #ifdef RT2870
6623         IN BOOLEAN    bFromTx)
6624 #endif
6625 {
6626     DBGPRINT(RT_DEBUG_TRACE, ("--> AsicForceWakeup \n"));
6627 #ifdef RT2860
6628     RT28XX_STA_FORCE_WAKEUP(pAd, Level);
6629 #endif
6630 #ifdef RT2870
6631     RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx);
6632 #endif
6633 }
6634
6635 /*
6636         ==========================================================================
6637         Description:
6638                 Set My BSSID
6639
6640         IRQL = DISPATCH_LEVEL
6641
6642         ==========================================================================
6643  */
6644 VOID AsicSetBssid(
6645         IN PRTMP_ADAPTER pAd,
6646         IN PUCHAR pBssid)
6647 {
6648         ULONG             Addr4;
6649         DBGPRINT(RT_DEBUG_TRACE, ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n",
6650                 pBssid[0],pBssid[1],pBssid[2],pBssid[3], pBssid[4],pBssid[5]));
6651
6652         Addr4 = (ULONG)(pBssid[0])               |
6653                         (ULONG)(pBssid[1] << 8)  |
6654                         (ULONG)(pBssid[2] << 16) |
6655                         (ULONG)(pBssid[3] << 24);
6656         RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
6657
6658         Addr4 = 0;
6659         // always one BSSID in STA mode
6660         Addr4 = (ULONG)(pBssid[4]) | (ULONG)(pBssid[5] << 8);
6661
6662         RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
6663 }
6664
6665 VOID AsicSetMcastWC(
6666         IN PRTMP_ADAPTER pAd)
6667 {
6668         MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[MCAST_WCID];
6669         USHORT          offset;
6670
6671         pEntry->Sst        = SST_ASSOC;
6672         pEntry->Aid        = MCAST_WCID;        // Softap supports 1 BSSID and use WCID=0 as multicast Wcid index
6673         pEntry->PsMode     = PWR_ACTIVE;
6674         pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate;
6675         offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE;
6676 }
6677
6678 /*
6679         ==========================================================================
6680         Description:
6681
6682         IRQL = DISPATCH_LEVEL
6683
6684         ==========================================================================
6685  */
6686 VOID AsicDelWcidTab(
6687         IN PRTMP_ADAPTER pAd,
6688         IN UCHAR        Wcid)
6689 {
6690         ULONG             Addr0 = 0x0, Addr1 = 0x0;
6691         ULONG           offset;
6692
6693         DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n",Wcid));
6694         offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE;
6695         RTMP_IO_WRITE32(pAd, offset, Addr0);
6696         offset += 4;
6697         RTMP_IO_WRITE32(pAd, offset, Addr1);
6698 }
6699
6700 /*
6701         ==========================================================================
6702         Description:
6703
6704         IRQL = DISPATCH_LEVEL
6705
6706         ==========================================================================
6707  */
6708 VOID AsicEnableRDG(
6709         IN PRTMP_ADAPTER pAd)
6710 {
6711         TX_LINK_CFG_STRUC       TxLinkCfg;
6712         UINT32                          Data = 0;
6713
6714         RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
6715         TxLinkCfg.field.TxRDGEn = 1;
6716         RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
6717
6718         RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
6719         Data  &= 0xFFFFFF00;
6720         Data  |= 0x80;
6721         RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
6722
6723         //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
6724 }
6725
6726 /*
6727         ==========================================================================
6728         Description:
6729
6730         IRQL = DISPATCH_LEVEL
6731
6732         ==========================================================================
6733  */
6734 VOID AsicDisableRDG(
6735         IN PRTMP_ADAPTER pAd)
6736 {
6737         TX_LINK_CFG_STRUC       TxLinkCfg;
6738         UINT32                          Data = 0;
6739
6740
6741         RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
6742         TxLinkCfg.field.TxRDGEn = 0;
6743         RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
6744
6745         RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
6746
6747         Data  &= 0xFFFFFF00;
6748         if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE)
6749                 && (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE)
6750         )
6751         {
6752                 // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
6753                 if (pAd->CommonCfg.bEnableTxBurst)
6754                         Data |= 0x20;
6755         }
6756         RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
6757 }
6758
6759 /*
6760         ==========================================================================
6761         Description:
6762
6763         IRQL = PASSIVE_LEVEL
6764         IRQL = DISPATCH_LEVEL
6765
6766         ==========================================================================
6767  */
6768 VOID AsicDisableSync(
6769         IN PRTMP_ADAPTER pAd)
6770 {
6771         BCN_TIME_CFG_STRUC csr;
6772
6773         DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n"));
6774
6775         // 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect
6776         //                        that NIC will never wakes up because TSF stops and no more
6777         //                        TBTT interrupts
6778         pAd->TbttTickCount = 0;
6779         RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
6780         csr.field.bBeaconGen = 0;
6781         csr.field.bTBTTEnable = 0;
6782         csr.field.TsfSyncMode = 0;
6783         csr.field.bTsfTicking = 0;
6784         RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
6785
6786 }
6787
6788 /*
6789         ==========================================================================
6790         Description:
6791
6792         IRQL = DISPATCH_LEVEL
6793
6794         ==========================================================================
6795  */
6796 VOID AsicEnableBssSync(
6797         IN PRTMP_ADAPTER pAd)
6798 {
6799         BCN_TIME_CFG_STRUC csr;
6800
6801         DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n"));
6802
6803         RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
6804
6805         {
6806                 csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
6807                 csr.field.bTsfTicking = 1;
6808                 csr.field.TsfSyncMode = 1; // sync TSF in INFRASTRUCTURE mode
6809                 csr.field.bBeaconGen  = 0; // do NOT generate BEACON
6810                 csr.field.bTBTTEnable = 1;
6811         }
6812
6813         RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
6814 }
6815
6816 /*
6817         ==========================================================================
6818         Description:
6819         Note:
6820                 BEACON frame in shared memory should be built ok before this routine
6821                 can be called. Otherwise, a garbage frame maybe transmitted out every
6822                 Beacon period.
6823
6824         IRQL = DISPATCH_LEVEL
6825
6826         ==========================================================================
6827  */
6828 VOID AsicEnableIbssSync(
6829         IN PRTMP_ADAPTER pAd)
6830 {
6831         BCN_TIME_CFG_STRUC csr9;
6832         PUCHAR                  ptr;
6833         UINT i;
6834
6835         DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n", pAd->BeaconTxWI.MPDUtotalByteCount));
6836
6837         RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word);
6838         csr9.field.bBeaconGen = 0;
6839         csr9.field.bTBTTEnable = 0;
6840         csr9.field.bTsfTicking = 0;
6841         RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
6842
6843 #ifdef RT2860
6844         // move BEACON TXD and frame content to on-chip memory
6845         ptr = (PUCHAR)&pAd->BeaconTxWI;
6846         for (i=0; i<TXWI_SIZE; i+=4)  // 16-byte TXWI field
6847         {
6848                 UINT32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
6849                 RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr);
6850                 ptr += 4;
6851         }
6852
6853         // start right after the 16-byte TXWI field
6854         ptr = pAd->BeaconBuf;
6855         for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=4)
6856         {
6857                 UINT32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
6858                 RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
6859                 ptr +=4;
6860         }
6861 #endif
6862 #ifdef RT2870
6863         // move BEACON TXD and frame content to on-chip memory
6864         ptr = (PUCHAR)&pAd->BeaconTxWI;
6865         for (i=0; i<TXWI_SIZE; i+=2)  // 16-byte TXWI field
6866         {
6867                 RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + i, ptr, 2);
6868                 ptr += 2;
6869         }
6870
6871         // start right after the 16-byte TXWI field
6872         ptr = pAd->BeaconBuf;
6873         for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=2)
6874         {
6875                 RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, ptr, 2);
6876                 ptr +=2;
6877         }
6878 #endif // RT2870 //
6879
6880         // start sending BEACON
6881         csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
6882         csr9.field.bTsfTicking = 1;
6883         csr9.field.TsfSyncMode = 2; // sync TSF in IBSS mode
6884         csr9.field.bTBTTEnable = 1;
6885         csr9.field.bBeaconGen = 1;
6886         RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
6887 }
6888
6889 /*
6890         ==========================================================================
6891         Description:
6892
6893         IRQL = PASSIVE_LEVEL
6894         IRQL = DISPATCH_LEVEL
6895
6896         ==========================================================================
6897  */
6898 VOID AsicSetEdcaParm(
6899         IN PRTMP_ADAPTER pAd,
6900         IN PEDCA_PARM    pEdcaParm)
6901 {
6902         EDCA_AC_CFG_STRUC   Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg;
6903         AC_TXOP_CSR0_STRUC csr0;
6904         AC_TXOP_CSR1_STRUC csr1;
6905         AIFSN_CSR_STRUC    AifsnCsr;
6906         CWMIN_CSR_STRUC    CwminCsr;
6907         CWMAX_CSR_STRUC    CwmaxCsr;
6908         int i;
6909
6910         Ac0Cfg.word = 0;
6911         Ac1Cfg.word = 0;
6912         Ac2Cfg.word = 0;
6913         Ac3Cfg.word = 0;
6914         if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE))
6915         {
6916                 DBGPRINT(RT_DEBUG_TRACE,("AsicSetEdcaParm\n"));
6917                 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED);
6918                 for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
6919                 {
6920                         if (pAd->MacTab.Content[i].ValidAsCLI || pAd->MacTab.Content[i].ValidAsApCli)
6921                                 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[i], fCLIENT_STATUS_WMM_CAPABLE);
6922                 }
6923
6924                 //========================================================
6925                 //      MAC Register has a copy .
6926                 //========================================================
6927                 if( pAd->CommonCfg.bEnableTxBurst )
6928                 {
6929                         // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
6930                         Ac0Cfg.field.AcTxop = 0x20; // Suggest by John for TxBurst in HT Mode
6931                 }
6932                 else
6933                         Ac0Cfg.field.AcTxop = 0;        // QID_AC_BE
6934                 Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS;
6935                 Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS;
6936                 Ac0Cfg.field.Aifsn = 2;
6937                 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
6938
6939                 Ac1Cfg.field.AcTxop = 0;        // QID_AC_BK
6940                 Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS;
6941                 Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS;
6942                 Ac1Cfg.field.Aifsn = 2;
6943                 RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
6944
6945                 if (pAd->CommonCfg.PhyMode == PHY_11B)
6946                 {
6947                         Ac2Cfg.field.AcTxop = 192;      // AC_VI: 192*32us ~= 6ms
6948                         Ac3Cfg.field.AcTxop = 96;       // AC_VO: 96*32us  ~= 3ms
6949                 }
6950                 else
6951                 {
6952                         Ac2Cfg.field.AcTxop = 96;       // AC_VI: 96*32us ~= 3ms
6953                         Ac3Cfg.field.AcTxop = 48;       // AC_VO: 48*32us ~= 1.5ms
6954                 }
6955                 Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS;
6956                 Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS;
6957                 Ac2Cfg.field.Aifsn = 2;
6958                 RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
6959                 Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS;
6960                 Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS;
6961                 Ac3Cfg.field.Aifsn = 2;
6962                 RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
6963
6964                 //========================================================
6965                 //      DMA Register has a copy too.
6966                 //========================================================
6967                 csr0.field.Ac0Txop = 0;         // QID_AC_BE
6968                 csr0.field.Ac1Txop = 0;         // QID_AC_BK
6969                 RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
6970                 if (pAd->CommonCfg.PhyMode == PHY_11B)
6971                 {
6972                         csr1.field.Ac2Txop = 192;               // AC_VI: 192*32us ~= 6ms
6973                         csr1.field.Ac3Txop = 96;                // AC_VO: 96*32us  ~= 3ms
6974                 }
6975                 else
6976                 {
6977                         csr1.field.Ac2Txop = 96;                // AC_VI: 96*32us ~= 3ms
6978                         csr1.field.Ac3Txop = 48;                // AC_VO: 48*32us ~= 1.5ms
6979                 }
6980                 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
6981
6982                 CwminCsr.word = 0;
6983                 CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS;
6984                 CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS;
6985                 CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS;
6986                 CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS;
6987                 RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
6988
6989                 CwmaxCsr.word = 0;
6990                 CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS;
6991                 CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS;
6992                 CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS;
6993                 CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS;
6994                 RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
6995
6996                 RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222);
6997
6998                 NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(EDCA_PARM));
6999         }
7000         else
7001         {
7002                 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED);
7003                 //========================================================
7004                 //      MAC Register has a copy.
7005                 //========================================================
7006                 //
7007                 // Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27
7008                 // To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue.
7009                 //
7010                 //pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this
7011
7012                 Ac0Cfg.field.AcTxop =  pEdcaParm->Txop[QID_AC_BE];
7013                 Ac0Cfg.field.Cwmin= pEdcaParm->Cwmin[QID_AC_BE];
7014                 Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE];
7015                 Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]; //+1;
7016
7017                 Ac1Cfg.field.AcTxop =  pEdcaParm->Txop[QID_AC_BK];
7018                 Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK]; //+2;
7019                 Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK];
7020                 Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK]; //+1;
7021
7022                 Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10;
7023                 Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI];
7024                 Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI];
7025                 Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI];
7026
7027                 {
7028                         // Tuning for Wi-Fi WMM S06
7029                         if (pAd->CommonCfg.bWiFiTest &&
7030                                 pEdcaParm->Aifsn[QID_AC_VI] == 10)
7031                                 Ac2Cfg.field.Aifsn -= 1;
7032
7033                         // Tuning for TGn Wi-Fi 5.2.32
7034                         // STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta
7035                         if (STA_TGN_WIFI_ON(pAd) &&
7036                                 pEdcaParm->Aifsn[QID_AC_VI] == 10)
7037                         {
7038                                 Ac0Cfg.field.Aifsn = 3;
7039                                 Ac2Cfg.field.AcTxop = 5;
7040                         }
7041
7042 #ifdef RT30xx
7043                         if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
7044                         {
7045                                 // Tuning for WiFi WMM S3-T07: connexant legacy sta ==> broadcom 11n sta.
7046                                 Ac2Cfg.field.Aifsn = 5;
7047                         }
7048 #endif // RT30xx //
7049                 }
7050
7051                 Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO];
7052                 Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO];
7053                 Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO];
7054                 Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO];
7055
7056 //#ifdef WIFI_TEST
7057                 if (pAd->CommonCfg.bWiFiTest)
7058                 {
7059                         if (Ac3Cfg.field.AcTxop == 102)
7060                         {
7061                         Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm->Txop[QID_AC_BE] : 10;
7062                                 Ac0Cfg.field.Aifsn  = pEdcaParm->Aifsn[QID_AC_BE]-1; /* AIFSN must >= 1 */
7063                         Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
7064                                 Ac1Cfg.field.Aifsn  = pEdcaParm->Aifsn[QID_AC_BK];
7065                         Ac2Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VI];
7066                         } /* End of if */
7067                 }
7068 //#endif // WIFI_TEST //
7069
7070                 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
7071                 RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
7072                 RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
7073                 RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
7074
7075
7076                 //========================================================
7077                 //      DMA Register has a copy too.
7078                 //========================================================
7079                 csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop;
7080                 csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop;
7081                 RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
7082
7083                 csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop;
7084                 csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop;
7085                 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
7086
7087                 CwminCsr.word = 0;
7088                 CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE];
7089                 CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK];
7090                 CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI];
7091
7092                 CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO] - 1; //for TGn wifi test
7093
7094                 RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
7095
7096                 CwmaxCsr.word = 0;
7097                 CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE];
7098                 CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK];
7099                 CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI];
7100                 CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO];
7101                 RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
7102
7103                 AifsnCsr.word = 0;
7104                 AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BE];
7105                 AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BK];
7106                 AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_VI];
7107
7108                 {
7109                         // Tuning for Wi-Fi WMM S06
7110                         if (pAd->CommonCfg.bWiFiTest &&
7111                                 pEdcaParm->Aifsn[QID_AC_VI] == 10)
7112                                 AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4;
7113
7114                         // Tuning for TGn Wi-Fi 5.2.32
7115                         // STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta
7116                         if (STA_TGN_WIFI_ON(pAd) &&
7117                                 pEdcaParm->Aifsn[QID_AC_VI] == 10)
7118                         {
7119                                 AifsnCsr.field.Aifsn0 = 3;
7120                                 AifsnCsr.field.Aifsn2 = 7;
7121                         }
7122 #ifdef RT2870
7123                         if (INFRA_ON(pAd))
7124                                 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_WMM_CAPABLE);
7125 #endif
7126                 }
7127
7128                 AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; //pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test
7129 #ifdef RT30xx
7130                 if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
7131                         AifsnCsr.field.Aifsn2 = 0x2; //pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04.
7132 #endif // RT30xx //
7133
7134                 RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word);
7135
7136                 NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
7137                 if (!ADHOC_ON(pAd))
7138                 {
7139                         DBGPRINT(RT_DEBUG_TRACE,("EDCA [#%d]: AIFSN CWmin CWmax  TXOP(us)  ACM\n", pEdcaParm->EdcaUpdateCount));
7140                         DBGPRINT(RT_DEBUG_TRACE,("     AC_BE      %2d     %2d     %2d      %4d     %d\n",
7141                                                                          pEdcaParm->Aifsn[0],
7142                                                                          pEdcaParm->Cwmin[0],
7143                                                                          pEdcaParm->Cwmax[0],
7144                                                                          pEdcaParm->Txop[0]<<5,
7145                                                                          pEdcaParm->bACM[0]));
7146                         DBGPRINT(RT_DEBUG_TRACE,("     AC_BK      %2d     %2d     %2d      %4d     %d\n",
7147                                                                          pEdcaParm->Aifsn[1],
7148                                                                          pEdcaParm->Cwmin[1],
7149                                                                          pEdcaParm->Cwmax[1],
7150                                                                          pEdcaParm->Txop[1]<<5,
7151                                                                          pEdcaParm->bACM[1]));
7152                         DBGPRINT(RT_DEBUG_TRACE,("     AC_VI      %2d     %2d     %2d      %4d     %d\n",
7153                                                                          pEdcaParm->Aifsn[2],
7154                                                                          pEdcaParm->Cwmin[2],
7155                                                                          pEdcaParm->Cwmax[2],
7156                                                                          pEdcaParm->Txop[2]<<5,
7157                                                                          pEdcaParm->bACM[2]));
7158                         DBGPRINT(RT_DEBUG_TRACE,("     AC_VO      %2d     %2d     %2d      %4d     %d\n",
7159                                                                          pEdcaParm->Aifsn[3],
7160                                                                          pEdcaParm->Cwmin[3],
7161                                                                          pEdcaParm->Cwmax[3],
7162                                                                          pEdcaParm->Txop[3]<<5,
7163                                                                          pEdcaParm->bACM[3]));
7164                 }
7165         }
7166 }
7167
7168 /*
7169         ==========================================================================
7170         Description:
7171
7172         IRQL = PASSIVE_LEVEL
7173         IRQL = DISPATCH_LEVEL
7174
7175         ==========================================================================
7176  */
7177 VOID    AsicSetSlotTime(
7178         IN PRTMP_ADAPTER pAd,
7179         IN BOOLEAN bUseShortSlotTime)
7180 {
7181         ULONG   SlotTime;
7182         UINT32  RegValue = 0;
7183
7184         if (pAd->CommonCfg.Channel > 14)
7185                 bUseShortSlotTime = TRUE;
7186
7187         if (bUseShortSlotTime)
7188                 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
7189         else
7190                 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
7191
7192         SlotTime = (bUseShortSlotTime)? 9 : 20;
7193
7194         {
7195 #ifndef RT30xx
7196                 // force using short SLOT time for FAE to demo performance when TxBurst is ON
7197                 if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
7198                         || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE))
7199                         )
7200                 {
7201                         // In this case, we will think it is doing Wi-Fi test
7202                         // And we will not set to short slot when bEnableTxBurst is TRUE.
7203                 }
7204                 else if (pAd->CommonCfg.bEnableTxBurst)
7205 #endif
7206 #ifdef RT30xx
7207                 if (pAd->CommonCfg.bEnableTxBurst)
7208 #endif
7209                         SlotTime = 9;
7210         }
7211
7212         //
7213         // For some reasons, always set it to short slot time.
7214         //
7215         // ToDo: Should consider capability with 11B
7216         //
7217         if (pAd->StaCfg.BssType == BSS_ADHOC)
7218                 SlotTime = 20;
7219
7220         RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue);
7221         RegValue = RegValue & 0xFFFFFF00;
7222
7223         RegValue |= SlotTime;
7224
7225         RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue);
7226 }
7227
7228 /*
7229         ========================================================================
7230         Description:
7231                 Add Shared key information into ASIC.
7232                 Update shared key, TxMic and RxMic to Asic Shared key table
7233                 Update its cipherAlg to Asic Shared key Mode.
7234
7235     Return:
7236         ========================================================================
7237 */
7238 VOID AsicAddSharedKeyEntry(
7239         IN PRTMP_ADAPTER pAd,
7240         IN UCHAR                 BssIndex,
7241         IN UCHAR                 KeyIdx,
7242         IN UCHAR                 CipherAlg,
7243         IN PUCHAR                pKey,
7244         IN PUCHAR                pTxMic,
7245         IN PUCHAR                pRxMic)
7246 {
7247         ULONG offset; //, csr0;
7248         SHAREDKEY_MODE_STRUC csr1;
7249 #ifdef RT2860
7250         INT   i;
7251 #endif
7252
7253         DBGPRINT(RT_DEBUG_TRACE, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,KeyIdx));
7254 //============================================================================================
7255
7256         DBGPRINT(RT_DEBUG_TRACE,("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg], BssIndex*4 + KeyIdx));
7257         DBGPRINT_RAW(RT_DEBUG_TRACE, ("         Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7258                 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]));
7259         if (pRxMic)
7260         {
7261                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("         Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7262                         pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
7263         }
7264         if (pTxMic)
7265         {
7266                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("         Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7267                         pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
7268         }
7269 //============================================================================================
7270         //
7271         // fill key material - key + TX MIC + RX MIC
7272         //
7273
7274         offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE;
7275 #ifdef RT2860
7276         for (i=0; i<MAX_LEN_OF_SHARE_KEY; i++)
7277         {
7278                 RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
7279         }
7280 #endif
7281 #ifdef RT2870
7282         RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_SHARE_KEY);
7283 #endif
7284         offset += MAX_LEN_OF_SHARE_KEY;
7285         if (pTxMic)
7286         {
7287 #ifdef RT2860
7288                 for (i=0; i<8; i++)
7289                 {
7290                         RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
7291                 }
7292 #endif
7293 #ifdef RT2870
7294                 RTUSBMultiWrite(pAd, offset, pTxMic, 8);
7295 #endif
7296         }
7297
7298         offset += 8;
7299         if (pRxMic)
7300         {
7301 #ifdef RT2860
7302                 for (i=0; i<8; i++)
7303                 {
7304                         RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
7305                 }
7306 #endif
7307 #ifdef RT2870
7308                 RTUSBMultiWrite(pAd, offset, pRxMic, 8);
7309 #endif
7310         }
7311
7312
7313         //
7314         // Update cipher algorithm. WSTA always use BSS0
7315         //
7316         RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
7317         DBGPRINT(RT_DEBUG_TRACE,("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n", BssIndex,KeyIdx, csr1.word));
7318         if ((BssIndex%2) == 0)
7319         {
7320                 if (KeyIdx == 0)
7321                         csr1.field.Bss0Key0CipherAlg = CipherAlg;
7322                 else if (KeyIdx == 1)
7323                         csr1.field.Bss0Key1CipherAlg = CipherAlg;
7324                 else if (KeyIdx == 2)
7325                         csr1.field.Bss0Key2CipherAlg = CipherAlg;
7326                 else
7327                         csr1.field.Bss0Key3CipherAlg = CipherAlg;
7328         }
7329         else
7330         {
7331                 if (KeyIdx == 0)
7332                         csr1.field.Bss1Key0CipherAlg = CipherAlg;
7333                 else if (KeyIdx == 1)
7334                         csr1.field.Bss1Key1CipherAlg = CipherAlg;
7335                 else if (KeyIdx == 2)
7336                         csr1.field.Bss1Key2CipherAlg = CipherAlg;
7337                 else
7338                         csr1.field.Bss1Key3CipherAlg = CipherAlg;
7339         }
7340         DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
7341         RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
7342
7343 }
7344
7345 //      IRQL = DISPATCH_LEVEL
7346 VOID AsicRemoveSharedKeyEntry(
7347         IN PRTMP_ADAPTER pAd,
7348         IN UCHAR                 BssIndex,
7349         IN UCHAR                 KeyIdx)
7350 {
7351         //ULONG SecCsr0;
7352         SHAREDKEY_MODE_STRUC csr1;
7353
7354         DBGPRINT(RT_DEBUG_TRACE,("AsicRemoveSharedKeyEntry: #%d \n", BssIndex*4 + KeyIdx));
7355
7356         RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
7357         if ((BssIndex%2) == 0)
7358         {
7359                 if (KeyIdx == 0)
7360                         csr1.field.Bss0Key0CipherAlg = 0;
7361                 else if (KeyIdx == 1)
7362                         csr1.field.Bss0Key1CipherAlg = 0;
7363                 else if (KeyIdx == 2)
7364                         csr1.field.Bss0Key2CipherAlg = 0;
7365                 else
7366                         csr1.field.Bss0Key3CipherAlg = 0;
7367         }
7368         else
7369         {
7370                 if (KeyIdx == 0)
7371                         csr1.field.Bss1Key0CipherAlg = 0;
7372                 else if (KeyIdx == 1)
7373                         csr1.field.Bss1Key1CipherAlg = 0;
7374                 else if (KeyIdx == 2)
7375                         csr1.field.Bss1Key2CipherAlg = 0;
7376                 else
7377                         csr1.field.Bss1Key3CipherAlg = 0;
7378         }
7379         DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
7380         RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
7381         ASSERT(BssIndex < 4);
7382         ASSERT(KeyIdx < 4);
7383
7384 }
7385
7386
7387 VOID AsicUpdateWCIDAttribute(
7388         IN PRTMP_ADAPTER pAd,
7389         IN USHORT               WCID,
7390         IN UCHAR                BssIndex,
7391         IN UCHAR        CipherAlg,
7392         IN BOOLEAN              bUsePairewiseKeyTable)
7393 {
7394         ULONG   WCIDAttri = 0, offset;
7395
7396         //
7397         // Update WCID attribute.
7398         // Only TxKey could update WCID attribute.
7399         //
7400         offset = MAC_WCID_ATTRIBUTE_BASE + (WCID * HW_WCID_ATTRI_SIZE);
7401         WCIDAttri = (BssIndex << 4) | (CipherAlg << 1) | (bUsePairewiseKeyTable);
7402         RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
7403 }
7404
7405 VOID AsicUpdateWCIDIVEIV(
7406         IN PRTMP_ADAPTER pAd,
7407         IN USHORT               WCID,
7408         IN ULONG        uIV,
7409         IN ULONG        uEIV)
7410 {
7411         ULONG   offset;
7412
7413         offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
7414
7415         RTMP_IO_WRITE32(pAd, offset, uIV);
7416         RTMP_IO_WRITE32(pAd, offset + 4, uEIV);
7417 }
7418
7419 VOID AsicUpdateRxWCIDTable(
7420         IN PRTMP_ADAPTER pAd,
7421         IN USHORT               WCID,
7422         IN PUCHAR        pAddr)
7423 {
7424         ULONG offset;
7425         ULONG Addr;
7426
7427         offset = MAC_WCID_BASE + (WCID * HW_WCID_ENTRY_SIZE);
7428         Addr = pAddr[0] + (pAddr[1] << 8) +(pAddr[2] << 16) +(pAddr[3] << 24);
7429         RTMP_IO_WRITE32(pAd, offset, Addr);
7430         Addr = pAddr[4] + (pAddr[5] << 8);
7431         RTMP_IO_WRITE32(pAd, offset + 4, Addr);
7432 }
7433
7434
7435 /*
7436     ========================================================================
7437
7438     Routine Description:
7439         Set Cipher Key, Cipher algorithm, IV/EIV to Asic
7440
7441     Arguments:
7442         pAd                     Pointer to our adapter
7443         WCID                    WCID Entry number.
7444         BssIndex                BSSID index, station or none multiple BSSID support
7445                                 this value should be 0.
7446         KeyIdx                  This KeyIdx will set to IV's KeyID if bTxKey enabled
7447         pCipherKey              Pointer to Cipher Key.
7448         bUsePairewiseKeyTable   TRUE means saved the key in SharedKey table,
7449                                 otherwise PairewiseKey table
7450         bTxKey                  This is the transmit key if enabled.
7451
7452     Return Value:
7453         None
7454
7455     Note:
7456         This routine will set the relative key stuff to Asic including WCID attribute,
7457         Cipher Key, Cipher algorithm and IV/EIV.
7458
7459         IV/EIV will be update if this CipherKey is the transmission key because
7460         ASIC will base on IV's KeyID value to select Cipher Key.
7461
7462         If bTxKey sets to FALSE, this is not the TX key, but it could be
7463         RX key
7464
7465         For AP mode bTxKey must be always set to TRUE.
7466     ========================================================================
7467 */
7468 VOID AsicAddKeyEntry(
7469         IN PRTMP_ADAPTER pAd,
7470         IN USHORT               WCID,
7471         IN UCHAR                BssIndex,
7472         IN UCHAR                KeyIdx,
7473         IN PCIPHER_KEY  pCipherKey,
7474         IN BOOLEAN              bUsePairewiseKeyTable,
7475         IN BOOLEAN              bTxKey)
7476 {
7477         ULONG   offset;
7478         UCHAR   IV4 = 0;
7479         PUCHAR          pKey = pCipherKey->Key;
7480         PUCHAR          pTxMic = pCipherKey->TxMic;
7481         PUCHAR          pRxMic = pCipherKey->RxMic;
7482         PUCHAR          pTxtsc = pCipherKey->TxTsc;
7483         UCHAR           CipherAlg = pCipherKey->CipherAlg;
7484         SHAREDKEY_MODE_STRUC csr1;
7485 #ifdef RT2860
7486         UCHAR           i;
7487 #endif
7488
7489         DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n"));
7490         //
7491         // 1.) decide key table offset
7492         //
7493         if (bUsePairewiseKeyTable)
7494                 offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
7495         else
7496                 offset = SHARED_KEY_TABLE_BASE + (4 * BssIndex + KeyIdx) * HW_KEY_ENTRY_SIZE;
7497
7498         //
7499         // 2.) Set Key to Asic
7500         //
7501         //for (i = 0; i < KeyLen; i++)
7502 #ifdef RT2860
7503         for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++)
7504         {
7505                 RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
7506         }
7507 #endif
7508 #ifdef RT2870
7509         RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_PEER_KEY);
7510 #endif
7511         offset += MAX_LEN_OF_PEER_KEY;
7512
7513         //
7514         // 3.) Set MIC key if available
7515         //
7516         if (pTxMic)
7517         {
7518 #ifdef RT2860
7519                 for (i = 0; i < 8; i++)
7520                 {
7521                         RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
7522                 }
7523 #endif
7524 #ifdef RT2870
7525                 RTUSBMultiWrite(pAd, offset, pTxMic, 8);
7526 #endif
7527         }
7528         offset += LEN_TKIP_TXMICK;
7529
7530         if (pRxMic)
7531         {
7532 #ifdef RT2860
7533                 for (i = 0; i < 8; i++)
7534                 {
7535                         RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
7536                 }
7537 #endif
7538 #ifdef RT2870
7539                 RTUSBMultiWrite(pAd, offset, pRxMic, 8);
7540 #endif
7541         }
7542
7543
7544         //
7545         // 4.) Modify IV/EIV if needs
7546         //     This will force Asic to use this key ID by setting IV.
7547         //
7548         if (bTxKey)
7549         {
7550 #ifdef RT2860
7551                 offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
7552                 //
7553                 // Write IV
7554                 //
7555                 RTMP_IO_WRITE8(pAd, offset, pTxtsc[1]);
7556                 RTMP_IO_WRITE8(pAd, offset + 1, ((pTxtsc[1] | 0x20) & 0x7f));
7557                 RTMP_IO_WRITE8(pAd, offset + 2, pTxtsc[0]);
7558
7559                 IV4 = (KeyIdx << 6);
7560                 if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES))
7561                         IV4 |= 0x20;  // turn on extension bit means EIV existence
7562
7563                 RTMP_IO_WRITE8(pAd, offset + 3, IV4);
7564
7565                 //
7566                 // Write EIV
7567                 //
7568                 offset += 4;
7569                 for (i = 0; i < 4; i++)
7570                 {
7571                         RTMP_IO_WRITE8(pAd, offset + i, pTxtsc[i + 2]);
7572                 }
7573
7574 #endif
7575 #ifdef RT2870
7576                 UINT32 tmpVal;
7577
7578                 //
7579                 // Write IV
7580                 //
7581                 IV4 = (KeyIdx << 6);
7582                 if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES))
7583                         IV4 |= 0x20;  // turn on extension bit means EIV existence
7584
7585                 tmpVal = pTxtsc[1] + (((pTxtsc[1] | 0x20) & 0x7f) << 8) + (pTxtsc[0] << 16) + (IV4 << 24);
7586                 RTMP_IO_WRITE32(pAd, offset, tmpVal);
7587
7588                 //
7589                 // Write EIV
7590                 //
7591                 offset += 4;
7592                 RTMP_IO_WRITE32(pAd, offset, *(PUINT32)&pCipherKey->TxTsc[2]);
7593 #endif // RT2870 //
7594                 AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg, bUsePairewiseKeyTable);
7595         }
7596
7597         if (!bUsePairewiseKeyTable)
7598         {
7599                 //
7600                 // Only update the shared key security mode
7601                 //
7602                 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), &csr1.word);
7603                 if ((BssIndex % 2) == 0)
7604                 {
7605                         if (KeyIdx == 0)
7606                                 csr1.field.Bss0Key0CipherAlg = CipherAlg;
7607                         else if (KeyIdx == 1)
7608                                 csr1.field.Bss0Key1CipherAlg = CipherAlg;
7609                         else if (KeyIdx == 2)
7610                                 csr1.field.Bss0Key2CipherAlg = CipherAlg;
7611                         else
7612                                 csr1.field.Bss0Key3CipherAlg = CipherAlg;
7613                 }
7614                 else
7615                 {
7616                         if (KeyIdx == 0)
7617                                 csr1.field.Bss1Key0CipherAlg = CipherAlg;
7618                         else if (KeyIdx == 1)
7619                                 csr1.field.Bss1Key1CipherAlg = CipherAlg;
7620                         else if (KeyIdx == 2)
7621                                 csr1.field.Bss1Key2CipherAlg = CipherAlg;
7622                         else
7623                                 csr1.field.Bss1Key3CipherAlg = CipherAlg;
7624                 }
7625                 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), csr1.word);
7626         }
7627
7628         DBGPRINT(RT_DEBUG_TRACE, ("<== AsicAddKeyEntry\n"));
7629 }
7630
7631
7632 /*
7633         ========================================================================
7634         Description:
7635                 Add Pair-wise key material into ASIC.
7636                 Update pairwise key, TxMic and RxMic to Asic Pair-wise key table
7637
7638     Return:
7639         ========================================================================
7640 */
7641 VOID AsicAddPairwiseKeyEntry(
7642         IN PRTMP_ADAPTER pAd,
7643         IN PUCHAR        pAddr,
7644         IN UCHAR                WCID,
7645         IN CIPHER_KEY            *pCipherKey)
7646 {
7647         INT i;
7648         ULONG           offset;
7649         PUCHAR           pKey = pCipherKey->Key;
7650         PUCHAR           pTxMic = pCipherKey->TxMic;
7651         PUCHAR           pRxMic = pCipherKey->RxMic;
7652 #ifdef DBG
7653         UCHAR           CipherAlg = pCipherKey->CipherAlg;
7654 #endif // DBG //
7655
7656         // EKEY
7657         offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
7658 #ifdef RT2860
7659         for (i=0; i<MAX_LEN_OF_PEER_KEY; i++)
7660         {
7661                 RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
7662         }
7663 #endif
7664 #ifdef RT2870
7665         RTUSBMultiWrite(pAd, offset, &pCipherKey->Key[0], MAX_LEN_OF_PEER_KEY);
7666 #endif // RT2870 //
7667         for (i=0; i<MAX_LEN_OF_PEER_KEY; i+=4)
7668         {
7669                 UINT32 Value;
7670                 RTMP_IO_READ32(pAd, offset + i, &Value);
7671         }
7672
7673         offset += MAX_LEN_OF_PEER_KEY;
7674
7675         //  MIC KEY
7676         if (pTxMic)
7677         {
7678 #ifdef RT2860
7679                 for (i=0; i<8; i++)
7680                 {
7681                         RTMP_IO_WRITE8(pAd, offset+i, pTxMic[i]);
7682                 }
7683 #endif
7684 #ifdef RT2870
7685                 RTUSBMultiWrite(pAd, offset, &pCipherKey->TxMic[0], 8);
7686 #endif // RT2870 //
7687         }
7688         offset += 8;
7689         if (pRxMic)
7690         {
7691 #ifdef RT2860
7692                 for (i=0; i<8; i++)
7693                 {
7694                         RTMP_IO_WRITE8(pAd, offset+i, pRxMic[i]);
7695                 }
7696 #endif
7697 #ifdef RT2870
7698                 RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8);
7699 #endif // RT2870 //
7700         }
7701
7702         DBGPRINT(RT_DEBUG_TRACE,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID, CipherName[CipherAlg]));
7703         DBGPRINT(RT_DEBUG_TRACE,("      Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7704                 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]));
7705         if (pRxMic)
7706         {
7707                 DBGPRINT(RT_DEBUG_TRACE, ("     Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7708                         pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
7709         }
7710         if (pTxMic)
7711         {
7712                 DBGPRINT(RT_DEBUG_TRACE, ("     Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7713                         pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
7714         }
7715 }
7716 /*
7717         ========================================================================
7718         Description:
7719                 Remove Pair-wise key material from ASIC.
7720
7721     Return:
7722         ========================================================================
7723 */
7724 VOID AsicRemovePairwiseKeyEntry(
7725         IN PRTMP_ADAPTER pAd,
7726         IN UCHAR                 BssIdx,
7727         IN UCHAR                 Wcid)
7728 {
7729         ULONG           WCIDAttri;
7730         USHORT          offset;
7731
7732         // re-set the entry's WCID attribute as OPEN-NONE.
7733         offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
7734         WCIDAttri = (BssIdx<<4) | PAIRWISEKEYTABLE;
7735         RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
7736 }
7737
7738 BOOLEAN AsicSendCommandToMcu(
7739         IN PRTMP_ADAPTER pAd,
7740         IN UCHAR                 Command,
7741         IN UCHAR                 Token,
7742         IN UCHAR                 Arg0,
7743         IN UCHAR                 Arg1)
7744 {
7745         HOST_CMD_CSR_STRUC      H2MCmd;
7746         H2M_MAILBOX_STRUC       H2MMailbox;
7747         ULONG                           i = 0;
7748
7749         do
7750         {
7751                 RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
7752                 if (H2MMailbox.field.Owner == 0)
7753                         break;
7754
7755                 RTMPusecDelay(2);
7756         } while(i++ < 100);
7757
7758         if (i > 100)
7759         {
7760                 {
7761 #ifdef RT2860
7762                         UINT32 Data;
7763
7764                         // Reset DMA
7765                         RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
7766                         Data |= 0x2;
7767                         RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
7768
7769                         // After Reset DMA, DMA index will become Zero. So Driver need to reset all ring indexs too.
7770                         // Reset DMA/CPU ring index
7771                         RTMPRingCleanUp(pAd, QID_AC_BK);
7772                         RTMPRingCleanUp(pAd, QID_AC_BE);
7773                         RTMPRingCleanUp(pAd, QID_AC_VI);
7774                         RTMPRingCleanUp(pAd, QID_AC_VO);
7775                         RTMPRingCleanUp(pAd, QID_HCCA);
7776                         RTMPRingCleanUp(pAd, QID_MGMT);
7777                         RTMPRingCleanUp(pAd, QID_RX);
7778
7779                         // Clear Reset
7780                         RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
7781                         Data &= 0xfffffffd;
7782                         RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
7783 #endif /* RT2860 */
7784                 DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
7785                 }
7786                 //return FALSE;
7787 #ifdef RT2870
7788                 return FALSE;
7789 #endif
7790         }
7791
7792         H2MMailbox.field.Owner    = 1;     // pass ownership to MCU
7793         H2MMailbox.field.CmdToken = Token;
7794         H2MMailbox.field.HighByte = Arg1;
7795         H2MMailbox.field.LowByte  = Arg0;
7796         RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
7797
7798         H2MCmd.word                       = 0;
7799         H2MCmd.field.HostCommand  = Command;
7800         RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
7801
7802         if (Command != 0x80)
7803         {
7804         }
7805
7806         return TRUE;
7807 }
7808
7809 #ifdef RT2860
7810 BOOLEAN AsicCheckCommanOk(
7811         IN PRTMP_ADAPTER pAd,
7812         IN UCHAR                 Command)
7813 {
7814         UINT32  CmdStatus = 0, CID = 0, i;
7815         UINT32  ThisCIDMask = 0;
7816
7817         i = 0;
7818         do
7819         {
7820                 RTMP_IO_READ32(pAd, H2M_MAILBOX_CID, &CID);
7821                 // Find where the command is. Because this is randomly specified by firmware.
7822                 if ((CID & CID0MASK) == Command)
7823                 {
7824                         ThisCIDMask = CID0MASK;
7825                         break;
7826                 }
7827                 else if ((((CID & CID1MASK)>>8) & 0xff) == Command)
7828                 {
7829                         ThisCIDMask = CID1MASK;
7830                         break;
7831                 }
7832                 else if ((((CID & CID2MASK)>>16) & 0xff) == Command)
7833                 {
7834                         ThisCIDMask = CID2MASK;
7835                         break;
7836                 }
7837                 else if ((((CID & CID3MASK)>>24) & 0xff) == Command)
7838                 {
7839                         ThisCIDMask = CID3MASK;
7840                         break;
7841                 }
7842
7843                 RTMPusecDelay(100);
7844                 i++;
7845         }while (i < 200);
7846
7847         // Get CommandStatus Value
7848         RTMP_IO_READ32(pAd, H2M_MAILBOX_STATUS, &CmdStatus);
7849
7850         // This command's status is at the same position as command. So AND command position's bitmask to read status.
7851         if (i < 200)
7852         {
7853                 // If Status is 1, the comamnd is success.
7854                 if (((CmdStatus & ThisCIDMask) == 0x1) || ((CmdStatus & ThisCIDMask) == 0x100)
7855                         || ((CmdStatus & ThisCIDMask) == 0x10000) || ((CmdStatus & ThisCIDMask) == 0x1000000))
7856                 {
7857                         DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanOk CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus));
7858                         RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
7859                         RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
7860                         return TRUE;
7861                 }
7862                 DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail1 CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus));
7863         }
7864         else
7865         {
7866                 DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail2 Timeout Command = %d, CmdStatus= 0x%x \n", Command, CmdStatus));
7867         }
7868         // Clear Command and Status.
7869         RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
7870         RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
7871
7872         return FALSE;
7873 }
7874 #endif /* RT8260 */
7875
7876 /*
7877         ========================================================================
7878
7879         Routine Description:
7880                 Verify the support rate for different PHY type
7881
7882         Arguments:
7883                 pAd                             Pointer to our adapter
7884
7885         Return Value:
7886                 None
7887
7888         IRQL = PASSIVE_LEVEL
7889
7890         ========================================================================
7891 */
7892 VOID    RTMPCheckRates(
7893         IN              PRTMP_ADAPTER   pAd,
7894         IN OUT  UCHAR                   SupRate[],
7895         IN OUT  UCHAR                   *SupRateLen)
7896 {
7897         UCHAR   RateIdx, i, j;
7898         UCHAR   NewRate[12], NewRateLen;
7899
7900         NewRateLen = 0;
7901
7902         if (pAd->CommonCfg.PhyMode == PHY_11B)
7903                 RateIdx = 4;
7904         else
7905                 RateIdx = 12;
7906
7907         // Check for support rates exclude basic rate bit
7908         for (i = 0; i < *SupRateLen; i++)
7909                 for (j = 0; j < RateIdx; j++)
7910                         if ((SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
7911                                 NewRate[NewRateLen++] = SupRate[i];
7912
7913         *SupRateLen = NewRateLen;
7914         NdisMoveMemory(SupRate, NewRate, NewRateLen);
7915 }
7916
7917 BOOLEAN RTMPCheckChannel(
7918         IN PRTMP_ADAPTER pAd,
7919         IN UCHAR                CentralChannel,
7920         IN UCHAR                Channel)
7921 {
7922         UCHAR           k;
7923         UCHAR           UpperChannel = 0, LowerChannel = 0;
7924         UCHAR           NoEffectChannelinList = 0;
7925
7926         // Find upper and lower channel according to 40MHz current operation.
7927         if (CentralChannel < Channel)
7928         {
7929                 UpperChannel = Channel;
7930                 if (CentralChannel > 2)
7931                         LowerChannel = CentralChannel - 2;
7932                 else
7933                         return FALSE;
7934         }
7935         else if (CentralChannel > Channel)
7936         {
7937                 UpperChannel = CentralChannel + 2;
7938                 LowerChannel = Channel;
7939         }
7940
7941         for (k = 0;k < pAd->ChannelListNum;k++)
7942         {
7943                 if (pAd->ChannelList[k].Channel == UpperChannel)
7944                 {
7945                         NoEffectChannelinList ++;
7946                 }
7947                 if (pAd->ChannelList[k].Channel == LowerChannel)
7948                 {
7949                         NoEffectChannelinList ++;
7950                 }
7951         }
7952
7953         DBGPRINT(RT_DEBUG_TRACE,("Total Channel in Channel List = [%d]\n", NoEffectChannelinList));
7954         if (NoEffectChannelinList == 2)
7955                 return TRUE;
7956         else
7957                 return FALSE;
7958 }
7959
7960 /*
7961         ========================================================================
7962
7963         Routine Description:
7964                 Verify the support rate for HT phy type
7965
7966         Arguments:
7967                 pAd                             Pointer to our adapter
7968
7969         Return Value:
7970                 FALSE if pAd->CommonCfg.SupportedHtPhy doesn't accept the pHtCapability.  (AP Mode)
7971
7972         IRQL = PASSIVE_LEVEL
7973
7974         ========================================================================
7975 */
7976 BOOLEAN         RTMPCheckHt(
7977         IN      PRTMP_ADAPTER                   pAd,
7978         IN      UCHAR                                   Wcid,
7979         IN      HT_CAPABILITY_IE                *pHtCapability,
7980         IN      ADD_HT_INFO_IE                  *pAddHtInfo)
7981 {
7982         if (Wcid >= MAX_LEN_OF_MAC_TABLE)
7983                 return FALSE;
7984
7985         // If use AMSDU, set flag.
7986         if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable)
7987                 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_AMSDU_INUSED);
7988         // Save Peer Capability
7989         if (pHtCapability->HtCapInfo.ShortGIfor20)
7990                 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_SGI20_CAPABLE);
7991         if (pHtCapability->HtCapInfo.ShortGIfor40)
7992                 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_SGI40_CAPABLE);
7993         if (pHtCapability->HtCapInfo.TxSTBC)
7994                 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_TxSTBC_CAPABLE);
7995         if (pHtCapability->HtCapInfo.RxSTBC)
7996                 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_RxSTBC_CAPABLE);
7997         if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport)
7998         {
7999                 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_RDG_CAPABLE);
8000         }
8001
8002         if (Wcid < MAX_LEN_OF_MAC_TABLE)
8003         {
8004                 pAd->MacTab.Content[Wcid].MpduDensity = pHtCapability->HtCapParm.MpduDensity;
8005         }
8006
8007         // Will check ChannelWidth for MCSSet[4] below
8008         pAd->MlmeAux.HtCapability.MCSSet[4] = 0x1;
8009     switch (pAd->CommonCfg.RxStream)
8010         {
8011                 case 1:
8012                         pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
8013                         pAd->MlmeAux.HtCapability.MCSSet[1] = 0x00;
8014             pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
8015             pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
8016                         break;
8017                 case 2:
8018                         pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
8019                         pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
8020             pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
8021             pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
8022                         break;
8023                 case 3:
8024                         pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
8025                         pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
8026             pAd->MlmeAux.HtCapability.MCSSet[2] = 0xff;
8027             pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
8028                         break;
8029         }
8030
8031         pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth = pAddHtInfo->AddHtInfo.RecomWidth & pAd->CommonCfg.DesiredHtPhy.ChannelWidth;
8032
8033     DBGPRINT(RT_DEBUG_TRACE, ("RTMPCheckHt:: HtCapInfo.ChannelWidth=%d, RecomWidth=%d, DesiredHtPhy.ChannelWidth=%d, BW40MAvailForA/G=%d/%d, PhyMode=%d \n",
8034                 pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth, pAddHtInfo->AddHtInfo.RecomWidth, pAd->CommonCfg.DesiredHtPhy.ChannelWidth,
8035                 pAd->NicConfig2.field.BW40MAvailForA, pAd->NicConfig2.field.BW40MAvailForG, pAd->CommonCfg.PhyMode));
8036
8037         pAd->MlmeAux.HtCapability.HtCapInfo.GF =  pHtCapability->HtCapInfo.GF &pAd->CommonCfg.DesiredHtPhy.GF;
8038
8039         // Send Assoc Req with my HT capability.
8040         pAd->MlmeAux.HtCapability.HtCapInfo.AMsduSize =  pAd->CommonCfg.DesiredHtPhy.AmsduSize;
8041         pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs =  pAd->CommonCfg.DesiredHtPhy.MimoPs;
8042         pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20 =  (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20) & (pHtCapability->HtCapInfo.ShortGIfor20);
8043         pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40 =  (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40) & (pHtCapability->HtCapInfo.ShortGIfor40);
8044         pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC =  (pAd->CommonCfg.DesiredHtPhy.TxSTBC)&(pHtCapability->HtCapInfo.RxSTBC);
8045         pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC =  (pAd->CommonCfg.DesiredHtPhy.RxSTBC)&(pHtCapability->HtCapInfo.TxSTBC);
8046         pAd->MlmeAux.HtCapability.HtCapParm.MaxRAmpduFactor = pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor;
8047     pAd->MlmeAux.HtCapability.HtCapParm.MpduDensity = pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity;
8048         pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = pHtCapability->ExtHtCapInfo.PlusHTC;
8049         pAd->MacTab.Content[Wcid].HTCapability.ExtHtCapInfo.PlusHTC = pHtCapability->ExtHtCapInfo.PlusHTC;
8050         if (pAd->CommonCfg.bRdg)
8051         {
8052                 pAd->MlmeAux.HtCapability.ExtHtCapInfo.RDGSupport = pHtCapability->ExtHtCapInfo.RDGSupport;
8053         pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = 1;
8054         }
8055
8056     if (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_20)
8057         pAd->MlmeAux.HtCapability.MCSSet[4] = 0x0;  // BW20 can't transmit MCS32
8058
8059         COPY_AP_HTSETTINGS_FROM_BEACON(pAd, pHtCapability);
8060         return TRUE;
8061 }
8062
8063 /*
8064         ========================================================================
8065
8066         Routine Description:
8067                 Verify the support rate for different PHY type
8068
8069         Arguments:
8070                 pAd                             Pointer to our adapter
8071
8072         Return Value:
8073                 None
8074
8075         IRQL = PASSIVE_LEVEL
8076
8077         ========================================================================
8078 */
8079 VOID RTMPUpdateMlmeRate(
8080         IN PRTMP_ADAPTER        pAd)
8081 {
8082         UCHAR   MinimumRate;
8083         UCHAR   ProperMlmeRate; //= RATE_54;
8084         UCHAR   i, j, RateIdx = 12; //1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
8085         BOOLEAN bMatch = FALSE;
8086
8087         switch (pAd->CommonCfg.PhyMode)
8088         {
8089                 case PHY_11B:
8090                         ProperMlmeRate = RATE_11;
8091                         MinimumRate = RATE_1;
8092                         break;
8093                 case PHY_11BG_MIXED:
8094                 case PHY_11ABGN_MIXED:
8095                 case PHY_11BGN_MIXED:
8096                         if ((pAd->MlmeAux.SupRateLen == 4) &&
8097                                 (pAd->MlmeAux.ExtRateLen == 0))
8098                                 // B only AP
8099                                 ProperMlmeRate = RATE_11;
8100                         else
8101                                 ProperMlmeRate = RATE_24;
8102
8103                         if (pAd->MlmeAux.Channel <= 14)
8104                                 MinimumRate = RATE_1;
8105                         else
8106                                 MinimumRate = RATE_6;
8107                         break;
8108                 case PHY_11A:
8109                 case PHY_11N_2_4G:      // rt2860 need to check mlmerate for 802.11n
8110                 case PHY_11GN_MIXED:
8111                 case PHY_11AGN_MIXED:
8112                 case PHY_11AN_MIXED:
8113                 case PHY_11N_5G:
8114                         ProperMlmeRate = RATE_24;
8115                         MinimumRate = RATE_6;
8116                         break;
8117                 case PHY_11ABG_MIXED:
8118                         ProperMlmeRate = RATE_24;
8119                         if (pAd->MlmeAux.Channel <= 14)
8120                            MinimumRate = RATE_1;
8121                         else
8122                                 MinimumRate = RATE_6;
8123                         break;
8124                 default: // error
8125                         ProperMlmeRate = RATE_1;
8126                         MinimumRate = RATE_1;
8127                         break;
8128         }
8129
8130         for (i = 0; i < pAd->MlmeAux.SupRateLen; i++)
8131         {
8132                 for (j = 0; j < RateIdx; j++)
8133                 {
8134                         if ((pAd->MlmeAux.SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
8135                         {
8136                                 if (j == ProperMlmeRate)
8137                                 {
8138                                         bMatch = TRUE;
8139                                         break;
8140                                 }
8141                         }
8142                 }
8143
8144                 if (bMatch)
8145                         break;
8146         }
8147
8148         if (bMatch == FALSE)
8149         {
8150                 for (i = 0; i < pAd->MlmeAux.ExtRateLen; i++)
8151                 {
8152                         for (j = 0; j < RateIdx; j++)
8153                         {
8154                                 if ((pAd->MlmeAux.ExtRate[i] & 0x7f) == RateIdTo500Kbps[j])
8155                                 {
8156                                         if (j == ProperMlmeRate)
8157                                         {
8158                                                 bMatch = TRUE;
8159                                                 break;
8160                                         }
8161                                 }
8162                         }
8163
8164                         if (bMatch)
8165                                 break;
8166                 }
8167         }
8168
8169         if (bMatch == FALSE)
8170         {
8171                 ProperMlmeRate = MinimumRate;
8172         }
8173
8174         pAd->CommonCfg.MlmeRate = MinimumRate;
8175         pAd->CommonCfg.RtsRate = ProperMlmeRate;
8176         if (pAd->CommonCfg.MlmeRate >= RATE_6)
8177         {
8178                 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
8179                 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
8180                 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
8181                 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
8182         }
8183         else
8184         {
8185                 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
8186                 pAd->CommonCfg.MlmeTransmit.field.MCS = pAd->CommonCfg.MlmeRate;
8187                 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_CCK;
8188                 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = pAd->CommonCfg.MlmeRate;
8189         }
8190
8191         DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateMlmeRate ==>   MlmeTransmit = 0x%x  \n" , pAd->CommonCfg.MlmeTransmit.word));
8192 }
8193
8194 CHAR RTMPMaxRssi(
8195         IN PRTMP_ADAPTER        pAd,
8196         IN CHAR                         Rssi0,
8197         IN CHAR                         Rssi1,
8198         IN CHAR                         Rssi2)
8199 {
8200         CHAR    larger = -127;
8201
8202         if ((pAd->Antenna.field.RxPath == 1) && (Rssi0 != 0))
8203         {
8204                 larger = Rssi0;
8205         }
8206
8207         if ((pAd->Antenna.field.RxPath >= 2) && (Rssi1 != 0))
8208         {
8209                 larger = max(Rssi0, Rssi1);
8210         }
8211
8212         if ((pAd->Antenna.field.RxPath == 3) && (Rssi2 != 0))
8213         {
8214                 larger = max(larger, Rssi2);
8215         }
8216
8217         if (larger == -127)
8218                 larger = 0;
8219
8220         return larger;
8221 }
8222
8223 #ifdef RT30xx
8224 // Antenna divesity use GPIO3 and EESK pin for control
8225 // Antenna and EEPROM access are both using EESK pin,
8226 // Therefor we should avoid accessing EESK at the same time
8227 // Then restore antenna after EEPROM access
8228 VOID AsicSetRxAnt(
8229         IN PRTMP_ADAPTER        pAd,
8230         IN UCHAR                        Ant)
8231 {
8232 #ifdef RT30xx
8233         UINT32  Value;
8234         UINT32  x;
8235
8236         if ((pAd->EepromAccess)                                                                         ||
8237                 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS))  ||
8238                 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))   ||
8239                 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))                  ||
8240                 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
8241         {
8242                 return;
8243         }
8244
8245         // the antenna selection is through firmware and MAC register(GPIO3)
8246         if (Ant == 0)
8247         {
8248                 // Main antenna
8249                 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
8250                 x |= (EESK);
8251                 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
8252
8253                 RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
8254                 Value &= ~(0x0808);
8255                 RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
8256                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to main antenna\n"));
8257         }
8258         else
8259         {
8260                 // Aux antenna
8261                 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
8262                 x &= ~(EESK);
8263                 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
8264
8265                 RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
8266                 Value &= ~(0x0808);
8267                 Value |= 0x08;
8268                 RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
8269                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to aux antenna\n"));
8270         }
8271 #endif // RT30xx //
8272 }
8273 #endif /* RT30xx */
8274
8275 /*
8276     ========================================================================
8277     Routine Description:
8278         Periodic evaluate antenna link status
8279
8280     Arguments:
8281         pAd         - Adapter pointer
8282
8283     Return Value:
8284         None
8285
8286     ========================================================================
8287 */
8288 VOID AsicEvaluateRxAnt(
8289         IN PRTMP_ADAPTER        pAd)
8290 {
8291         UCHAR   BBPR3 = 0;
8292
8293 #ifndef RT30xx
8294         {
8295                 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
8296                                                                 fRTMP_ADAPTER_HALT_IN_PROGRESS  |
8297                                                                 fRTMP_ADAPTER_RADIO_OFF                 |
8298                                                                 fRTMP_ADAPTER_NIC_NOT_EXIST             |
8299                                                                 fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
8300                         return;
8301
8302                 if (pAd->StaCfg.Psm == PWR_SAVE)
8303                         return;
8304         }
8305
8306         RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
8307         BBPR3 &= (~0x18);
8308         if(pAd->Antenna.field.RxPath == 3)
8309         {
8310                 BBPR3 |= (0x10);
8311         }
8312         else if(pAd->Antenna.field.RxPath == 2)
8313         {
8314                 BBPR3 |= (0x8);
8315         }
8316         else if(pAd->Antenna.field.RxPath == 1)
8317         {
8318                 BBPR3 |= (0x0);
8319         }
8320         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
8321
8322 #ifdef RT2860
8323         pAd->StaCfg.BBPR3 = BBPR3;
8324 #endif
8325 #endif /* RT30xx */
8326 #ifdef RT30xx
8327         if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
8328                                                         fRTMP_ADAPTER_HALT_IN_PROGRESS  |
8329                                                         fRTMP_ADAPTER_RADIO_OFF                 |
8330                                                         fRTMP_ADAPTER_NIC_NOT_EXIST             |
8331                                                         fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) ||
8332                                                         OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
8333 #ifdef RT30xx
8334                                                         || (pAd->EepromAccess)
8335 #endif // RT30xx //
8336                                                         )
8337                 return;
8338
8339
8340         {
8341                 //if (pAd->StaCfg.Psm == PWR_SAVE)
8342                 //      return;
8343         }
8344
8345         // two antenna selection mechanism- one is antenna diversity, the other is failed antenna remove
8346         // one is antenna diversity:there is only one antenna can rx and tx
8347         // the other is failed antenna remove:two physical antenna can rx and tx
8348         if (pAd->NicConfig2.field.AntDiversity)
8349         {
8350                 DBGPRINT(RT_DEBUG_TRACE,("AntDiv - before evaluate Pair1-Ant (%d,%d)\n",
8351                         pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt));
8352
8353                 AsicSetRxAnt(pAd, pAd->RxAnt.Pair1SecondaryRxAnt);
8354
8355                 pAd->RxAnt.EvaluatePeriod = 1; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt
8356                 pAd->RxAnt.FirstPktArrivedWhenEvaluate = FALSE;
8357                 pAd->RxAnt.RcvPktNumWhenEvaluate = 0;
8358
8359                 // a one-shot timer to end the evalution
8360                 // dynamic adjust antenna evaluation period according to the traffic
8361                 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
8362                         RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 100);
8363                 else
8364                         RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
8365         }
8366         else
8367         {
8368                 if (pAd->StaCfg.Psm == PWR_SAVE)
8369                         return;
8370
8371                 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
8372                 BBPR3 &= (~0x18);
8373                 if(pAd->Antenna.field.RxPath == 3)
8374                 {
8375                         BBPR3 |= (0x10);
8376                 }
8377                 else if(pAd->Antenna.field.RxPath == 2)
8378                 {
8379                         BBPR3 |= (0x8);
8380                 }
8381                 else if(pAd->Antenna.field.RxPath == 1)
8382                 {
8383                         BBPR3 |= (0x0);
8384                 }
8385                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
8386         }
8387 #endif /* RT30xx */
8388
8389         if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
8390                 )
8391         {
8392                 ULONG   TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
8393                                                                 pAd->RalinkCounters.OneSecTxRetryOkCount +
8394                                                                 pAd->RalinkCounters.OneSecTxFailCount;
8395
8396                         // dynamic adjust antenna evaluation period according to the traffic
8397                 if (TxTotalCnt > 50)
8398                 {
8399                         RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 20);
8400                         pAd->Mlme.bLowThroughput = FALSE;
8401                 }
8402                 else
8403                 {
8404                         RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
8405                         pAd->Mlme.bLowThroughput = TRUE;
8406                 }
8407         }
8408 }
8409
8410 /*
8411     ========================================================================
8412     Routine Description:
8413         After evaluation, check antenna link status
8414
8415     Arguments:
8416         pAd         - Adapter pointer
8417
8418     Return Value:
8419         None
8420
8421     ========================================================================
8422 */
8423 VOID AsicRxAntEvalTimeout(
8424         IN PVOID SystemSpecific1,
8425         IN PVOID FunctionContext,
8426         IN PVOID SystemSpecific2,
8427         IN PVOID SystemSpecific3)
8428 {
8429         RTMP_ADAPTER    *pAd = (RTMP_ADAPTER *)FunctionContext;
8430         UCHAR                   BBPR3 = 0;
8431         CHAR                    larger = -127, rssi0, rssi1, rssi2;
8432
8433 #ifndef RT30xx
8434         {
8435                 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)        ||
8436                         RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)             ||
8437                         RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)                    ||
8438                         RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
8439                         return;
8440
8441                 if (pAd->StaCfg.Psm == PWR_SAVE)
8442                         return;
8443
8444
8445                 // if the traffic is low, use average rssi as the criteria
8446                 if (pAd->Mlme.bLowThroughput == TRUE)
8447                 {
8448                         rssi0 = pAd->StaCfg.RssiSample.LastRssi0;
8449                         rssi1 = pAd->StaCfg.RssiSample.LastRssi1;
8450                         rssi2 = pAd->StaCfg.RssiSample.LastRssi2;
8451                 }
8452                 else
8453                 {
8454                         rssi0 = pAd->StaCfg.RssiSample.AvgRssi0;
8455                         rssi1 = pAd->StaCfg.RssiSample.AvgRssi1;
8456                         rssi2 = pAd->StaCfg.RssiSample.AvgRssi2;
8457                 }
8458
8459                 if(pAd->Antenna.field.RxPath == 3)
8460                 {
8461                         larger = max(rssi0, rssi1);
8462
8463                         if (larger > (rssi2 + 20))
8464                                 pAd->Mlme.RealRxPath = 2;
8465                         else
8466                                 pAd->Mlme.RealRxPath = 3;
8467                 }
8468                 else if(pAd->Antenna.field.RxPath == 2)
8469                 {
8470                         if (rssi0 > (rssi1 + 20))
8471                                 pAd->Mlme.RealRxPath = 1;
8472                         else
8473                                 pAd->Mlme.RealRxPath = 2;
8474                 }
8475
8476                 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
8477                 BBPR3 &= (~0x18);
8478                 if(pAd->Mlme.RealRxPath == 3)
8479                 {
8480                         BBPR3 |= (0x10);
8481                 }
8482                 else if(pAd->Mlme.RealRxPath == 2)
8483                 {
8484                         BBPR3 |= (0x8);
8485                 }
8486                 else if(pAd->Mlme.RealRxPath == 1)
8487                 {
8488                         BBPR3 |= (0x0);
8489                 }
8490                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
8491 #ifdef RT2860
8492                 pAd->StaCfg.BBPR3 = BBPR3;
8493 #endif
8494         }
8495 #endif /* RT30xx */
8496 #ifdef RT30xx
8497         if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
8498                                                         fRTMP_ADAPTER_HALT_IN_PROGRESS  |
8499                                                         fRTMP_ADAPTER_RADIO_OFF                 |
8500                                                         fRTMP_ADAPTER_NIC_NOT_EXIST) ||
8501                                                         OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
8502 #ifdef RT30xx
8503                                                         || (pAd->EepromAccess)
8504 #endif // RT30xx //
8505                                                         )
8506                 return;
8507
8508         {
8509                 //if (pAd->StaCfg.Psm == PWR_SAVE)
8510                 //      return;
8511
8512                 if (pAd->NicConfig2.field.AntDiversity)
8513                 {
8514                         if ((pAd->RxAnt.RcvPktNumWhenEvaluate != 0) && (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >= pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt]))
8515                         {
8516                                 UCHAR                   temp;
8517
8518                                 //
8519                                 // select PrimaryRxAntPair
8520                                 //    Role change, Used Pair1SecondaryRxAnt as PrimaryRxAntPair.
8521                                 //    Since Pair1SecondaryRxAnt Quality good than Pair1PrimaryRxAnt
8522                                 //
8523                                 temp = pAd->RxAnt.Pair1PrimaryRxAnt;
8524                                 pAd->RxAnt.Pair1PrimaryRxAnt = pAd->RxAnt.Pair1SecondaryRxAnt;
8525                                 pAd->RxAnt.Pair1SecondaryRxAnt = temp;
8526
8527                                 pAd->RxAnt.Pair1LastAvgRssi = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >> 3);
8528                                 pAd->RxAnt.EvaluateStableCnt = 0;
8529                         }
8530                         else
8531                         {
8532                                 // if the evaluated antenna is not better than original, switch back to original antenna
8533                                 AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
8534                                 pAd->RxAnt.EvaluateStableCnt ++;
8535                         }
8536
8537                         pAd->RxAnt.EvaluatePeriod = 0; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt
8538
8539                         DBGPRINT(RT_DEBUG_TRACE,("AsicRxAntEvalAction::After Eval(fix in #%d), <%d, %d>, RcvPktNumWhenEvaluate=%ld\n",
8540                                         pAd->RxAnt.Pair1PrimaryRxAnt, (pAd->RxAnt.Pair1AvgRssi[0] >> 3), (pAd->RxAnt.Pair1AvgRssi[1] >> 3), pAd->RxAnt.RcvPktNumWhenEvaluate));
8541                 }
8542                 else
8543                 {
8544                         if (pAd->StaCfg.Psm == PWR_SAVE)
8545                                 return;
8546
8547                         // if the traffic is low, use average rssi as the criteria
8548                         if (pAd->Mlme.bLowThroughput == TRUE)
8549                         {
8550                                 rssi0 = pAd->StaCfg.RssiSample.LastRssi0;
8551                                 rssi1 = pAd->StaCfg.RssiSample.LastRssi1;
8552                                 rssi2 = pAd->StaCfg.RssiSample.LastRssi2;
8553                         }
8554                         else
8555                         {
8556                                 rssi0 = pAd->StaCfg.RssiSample.AvgRssi0;
8557                                 rssi1 = pAd->StaCfg.RssiSample.AvgRssi1;
8558                                 rssi2 = pAd->StaCfg.RssiSample.AvgRssi2;
8559                         }
8560
8561                         if(pAd->Antenna.field.RxPath == 3)
8562                         {
8563                                 larger = max(rssi0, rssi1);
8564
8565                                 if (larger > (rssi2 + 20))
8566                                         pAd->Mlme.RealRxPath = 2;
8567                                 else
8568                                         pAd->Mlme.RealRxPath = 3;
8569                         }
8570                         else if(pAd->Antenna.field.RxPath == 2)
8571                         {
8572                                 if (rssi0 > (rssi1 + 20))
8573                                         pAd->Mlme.RealRxPath = 1;
8574                                 else
8575                                         pAd->Mlme.RealRxPath = 2;
8576                         }
8577
8578                         RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
8579                         BBPR3 &= (~0x18);
8580                         if(pAd->Mlme.RealRxPath == 3)
8581                         {
8582                                 BBPR3 |= (0x10);
8583                         }
8584                         else if(pAd->Mlme.RealRxPath == 2)
8585                         {
8586                                 BBPR3 |= (0x8);
8587                         }
8588                         else if(pAd->Mlme.RealRxPath == 1)
8589                         {
8590                                 BBPR3 |= (0x0);
8591                         }
8592                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
8593                 }
8594         }
8595 #endif /* RT30xx */
8596 }
8597
8598
8599
8600 VOID APSDPeriodicExec(
8601         IN PVOID SystemSpecific1,
8602         IN PVOID FunctionContext,
8603         IN PVOID SystemSpecific2,
8604         IN PVOID SystemSpecific3)
8605 {
8606         RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
8607
8608         if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
8609                 return;
8610
8611         pAd->CommonCfg.TriggerTimerCount++;
8612
8613 }
8614
8615 /*
8616     ========================================================================
8617     Routine Description:
8618         Set/reset MAC registers according to bPiggyBack parameter
8619
8620     Arguments:
8621         pAd         - Adapter pointer
8622         bPiggyBack  - Enable / Disable Piggy-Back
8623
8624     Return Value:
8625         None
8626
8627     ========================================================================
8628 */
8629 VOID RTMPSetPiggyBack(
8630     IN PRTMP_ADAPTER    pAd,
8631     IN BOOLEAN          bPiggyBack)
8632 {
8633         TX_LINK_CFG_STRUC  TxLinkCfg;
8634
8635         RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
8636
8637         TxLinkCfg.field.TxCFAckEn = bPiggyBack;
8638         RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
8639 }
8640
8641 /*
8642     ========================================================================
8643     Routine Description:
8644         check if this entry need to switch rate automatically
8645
8646     Arguments:
8647         pAd
8648         pEntry
8649
8650     Return Value:
8651         TURE
8652         FALSE
8653
8654     ========================================================================
8655 */
8656 BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(
8657         IN PRTMP_ADAPTER    pAd,
8658         IN PMAC_TABLE_ENTRY     pEntry)
8659 {
8660         BOOLEAN         result = TRUE;
8661
8662         {
8663                 // only associated STA counts
8664                 if (pEntry && (pEntry->ValidAsCLI) && (pEntry->Sst == SST_ASSOC))
8665                 {
8666                         result = pAd->StaCfg.bAutoTxRateSwitch;
8667                 }
8668                 else
8669                         result = FALSE;
8670         }
8671
8672         return result;
8673 }
8674
8675
8676 BOOLEAN RTMPAutoRateSwitchCheck(
8677         IN PRTMP_ADAPTER    pAd)
8678 {
8679         if (pAd->StaCfg.bAutoTxRateSwitch)
8680                 return TRUE;
8681
8682         return FALSE;
8683 }
8684
8685
8686 /*
8687     ========================================================================
8688     Routine Description:
8689         check if this entry need to fix tx legacy rate
8690
8691     Arguments:
8692         pAd
8693         pEntry
8694
8695     Return Value:
8696         TURE
8697         FALSE
8698
8699     ========================================================================
8700 */
8701 UCHAR RTMPStaFixedTxMode(
8702         IN PRTMP_ADAPTER    pAd,
8703         IN PMAC_TABLE_ENTRY     pEntry)
8704 {
8705         UCHAR   tx_mode = FIXED_TXMODE_HT;
8706
8707         tx_mode = (UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode;
8708
8709         return tx_mode;
8710 }
8711
8712 /*
8713     ========================================================================
8714     Routine Description:
8715         Overwrite HT Tx Mode by Fixed Legency Tx Mode, if specified.
8716
8717     Arguments:
8718         pAd
8719         pEntry
8720
8721     Return Value:
8722         TURE
8723         FALSE
8724
8725     ========================================================================
8726 */
8727 VOID RTMPUpdateLegacyTxSetting(
8728                 UCHAR                           fixed_tx_mode,
8729                 PMAC_TABLE_ENTRY        pEntry)
8730 {
8731         HTTRANSMIT_SETTING TransmitSetting;
8732
8733         if (fixed_tx_mode == FIXED_TXMODE_HT)
8734                 return;
8735
8736         TransmitSetting.word = 0;
8737
8738         TransmitSetting.field.MODE = pEntry->HTPhyMode.field.MODE;
8739         TransmitSetting.field.MCS = pEntry->HTPhyMode.field.MCS;
8740
8741         if (fixed_tx_mode == FIXED_TXMODE_CCK)
8742         {
8743                 TransmitSetting.field.MODE = MODE_CCK;
8744                 // CCK mode allow MCS 0~3
8745                 if (TransmitSetting.field.MCS > MCS_3)
8746                         TransmitSetting.field.MCS = MCS_3;
8747         }
8748         else
8749         {
8750                 TransmitSetting.field.MODE = MODE_OFDM;
8751                 // OFDM mode allow MCS 0~7
8752                 if (TransmitSetting.field.MCS > MCS_7)
8753                         TransmitSetting.field.MCS = MCS_7;
8754         }
8755
8756         if (pEntry->HTPhyMode.field.MODE >= TransmitSetting.field.MODE)
8757         {
8758                 pEntry->HTPhyMode.word = TransmitSetting.word;
8759                 DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateLegacyTxSetting : wcid-%d, MODE=%s, MCS=%d \n",
8760                                 pEntry->Aid, GetPhyMode(pEntry->HTPhyMode.field.MODE), pEntry->HTPhyMode.field.MCS));
8761         }
8762 }
8763
8764 /*
8765         ==========================================================================
8766         Description:
8767                 dynamic tune BBP R66 to find a balance between sensibility and
8768                 noise isolation
8769
8770         IRQL = DISPATCH_LEVEL
8771
8772         ==========================================================================
8773  */
8774 VOID AsicStaBbpTuning(
8775         IN PRTMP_ADAPTER pAd)
8776 {
8777         UCHAR   OrigR66Value = 0, R66;//, R66UpperBound = 0x30, R66LowerBound = 0x30;
8778         CHAR    Rssi;
8779
8780         // 2860C did not support Fase CCA, therefore can't tune
8781         if (pAd->MACVersion == 0x28600100)
8782                 return;
8783
8784         //
8785         // work as a STA
8786         //
8787         if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)  // no R66 tuning when SCANNING
8788                 return;
8789
8790         if ((pAd->OpMode == OPMODE_STA)
8791                 && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
8792                         )
8793                 && !(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
8794 #ifdef RT2860
8795                 && (pAd->bPCIclkOff == FALSE))
8796 #endif
8797 #ifdef RT2870
8798                 )
8799 #endif
8800         {
8801                 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &OrigR66Value);
8802                 R66 = OrigR66Value;
8803
8804                 if (pAd->Antenna.field.RxPath > 1)
8805                         Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
8806                 else
8807                         Rssi = pAd->StaCfg.RssiSample.AvgRssi0;
8808
8809                 if (pAd->LatchRfRegs.Channel <= 14)
8810                 {       //BG band
8811 #ifdef RT2870
8812                         // RT3070 is a no LNA solution, it should have different control regarding to AGC gain control
8813                         // Otherwise, it will have some throughput side effect when low RSSI
8814 #ifndef RT30xx
8815                         if (IS_RT3070(pAd))
8816 #endif
8817 #ifdef RT30xx
8818                         if (IS_RT30xx(pAd))
8819 #endif
8820                         {
8821                                 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
8822                                 {
8823                                         R66 = 0x1C + 2*GET_LNA_GAIN(pAd) + 0x20;
8824                                         if (OrigR66Value != R66)
8825                                         {
8826 #ifndef RT30xx
8827                                                 RTUSBWriteBBPRegister(pAd, BBP_R66, R66);
8828 #endif
8829 #ifdef RT30xx
8830                                                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8831 #endif
8832                                         }
8833                                 }
8834                                 else
8835                                 {
8836                                         R66 = 0x1C + 2*GET_LNA_GAIN(pAd);
8837                                         if (OrigR66Value != R66)
8838                                         {
8839 #ifndef RT30xx
8840                                                 RTUSBWriteBBPRegister(pAd, BBP_R66, R66);
8841 #endif
8842 #ifdef RT30xx
8843                                                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8844 #endif
8845                                         }
8846                                 }
8847                         }
8848                         else
8849 #endif // RT2870 //
8850                         {
8851                                 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
8852                                 {
8853                                         R66 = (0x2E + GET_LNA_GAIN(pAd)) + 0x10;
8854                                         if (OrigR66Value != R66)
8855                                         {
8856                                                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8857                                         }
8858                                 }
8859                                 else
8860                                 {
8861                                         R66 = 0x2E + GET_LNA_GAIN(pAd);
8862                                         if (OrigR66Value != R66)
8863                                         {
8864                                                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8865                                         }
8866                                 }
8867                         }
8868                 }
8869                 else
8870                 {       //A band
8871                         if (pAd->CommonCfg.BBPCurrentBW == BW_20)
8872                         {
8873                                 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
8874                                 {
8875                                         R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3 + 0x10;
8876                                         if (OrigR66Value != R66)
8877                                         {
8878                                                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8879                                         }
8880                                 }
8881                                 else
8882                                 {
8883                                         R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3;
8884                                         if (OrigR66Value != R66)
8885                                         {
8886                                                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8887                                         }
8888                                 }
8889                         }
8890                         else
8891                         {
8892                                 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
8893                                 {
8894                                         R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3 + 0x10;
8895                                         if (OrigR66Value != R66)
8896                                         {
8897                                                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8898                                         }
8899                                 }
8900                                 else
8901                                 {
8902                                         R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3;
8903                                         if (OrigR66Value != R66)
8904                                         {
8905                                                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8906                                         }
8907                                 }
8908                         }
8909                 }
8910
8911
8912         }
8913 }
8914
8915 #ifdef RT2860
8916 VOID AsicResetFromDMABusy(
8917         IN PRTMP_ADAPTER pAd)
8918 {
8919         UINT32          Data;
8920         BOOLEAN         bCtrl = FALSE;
8921
8922         DBGPRINT(RT_DEBUG_TRACE, ("--->  AsicResetFromDMABusy  !!!!!!!!!!!!!!!!!!!!!!! \n"));
8923
8924         // Be sure restore link control value so we can write register.
8925         RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
8926         if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
8927         {
8928                 DBGPRINT(RT_DEBUG_TRACE,("AsicResetFromDMABusy==>\n"));
8929                 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
8930                 RTMPusecDelay(6000);
8931                 pAd->bPCIclkOff = FALSE;
8932                 bCtrl = TRUE;
8933         }
8934         // Reset DMA
8935         RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
8936         Data |= 0x2;
8937         RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
8938
8939         // After Reset DMA, DMA index will become Zero. So Driver need to reset all ring indexs too.
8940         // Reset DMA/CPU ring index
8941         RTMPRingCleanUp(pAd, QID_AC_BK);
8942         RTMPRingCleanUp(pAd, QID_AC_BE);
8943         RTMPRingCleanUp(pAd, QID_AC_VI);
8944         RTMPRingCleanUp(pAd, QID_AC_VO);
8945         RTMPRingCleanUp(pAd, QID_HCCA);
8946         RTMPRingCleanUp(pAd, QID_MGMT);
8947         RTMPRingCleanUp(pAd, QID_RX);
8948
8949         // Clear Reset
8950         RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
8951         Data &= 0xfffffffd;
8952         RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
8953
8954         // If in Radio off, should call RTMPPCIePowerLinkCtrl again.
8955         if ((bCtrl == TRUE) && (pAd->StaCfg.bRadio == FALSE))
8956                 RTMPPCIeLinkCtrlSetting(pAd, 3);
8957
8958         RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
8959         RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS);
8960         DBGPRINT(RT_DEBUG_TRACE, ("<---  AsicResetFromDMABusy !!!!!!!!!!!!!!!!!!!!!!!  \n"));
8961 }
8962
8963 VOID AsicResetBBP(
8964         IN PRTMP_ADAPTER pAd)
8965 {
8966         DBGPRINT(RT_DEBUG_TRACE, ("--->  Asic HardReset BBP  !!!!!!!!!!!!!!!!!!!!!!! \n"));
8967
8968         RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
8969         RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x2);
8970         RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc);
8971
8972         // After hard-reset BBP, initialize all BBP values.
8973         NICRestoreBBPValue(pAd);
8974         DBGPRINT(RT_DEBUG_TRACE, ("<---  Asic HardReset BBP !!!!!!!!!!!!!!!!!!!!!!!  \n"));
8975 }
8976
8977 VOID AsicResetMAC(
8978         IN PRTMP_ADAPTER pAd)
8979 {
8980         ULONG           Data;
8981
8982         DBGPRINT(RT_DEBUG_TRACE, ("--->  AsicResetMAC   !!!! \n"));
8983         RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
8984         Data |= 0x4;
8985         RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
8986         Data &= 0xfffffffb;
8987         RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
8988
8989         DBGPRINT(RT_DEBUG_TRACE, ("<---  AsicResetMAC   !!!! \n"));
8990 }
8991
8992 VOID AsicResetPBF(
8993         IN PRTMP_ADAPTER pAd)
8994 {
8995         ULONG           Value1, Value2;
8996         ULONG           Data;
8997
8998         RTMP_IO_READ32(pAd, TXRXQ_PCNT, &Value1);
8999         RTMP_IO_READ32(pAd, PBF_DBG, &Value2);
9000
9001         Value2 &= 0xff;
9002         // sum should be equals to 0xff, which is the total buffer size.
9003         if ((Value1 + Value2) < 0xff)
9004         {
9005                 DBGPRINT(RT_DEBUG_TRACE, ("--->  Asic HardReset PBF !!!! \n"));
9006                 RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
9007                 Data |= 0x8;
9008                 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
9009                 Data &= 0xfffffff7;
9010                 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
9011
9012                 DBGPRINT(RT_DEBUG_TRACE, ("<---  Asic HardReset PBF !!!! \n"));
9013         }
9014 }
9015 #endif /* RT2860 */
9016
9017 VOID RTMPSetAGCInitValue(
9018         IN PRTMP_ADAPTER        pAd,
9019         IN UCHAR                        BandWidth)
9020 {
9021         UCHAR   R66 = 0x30;
9022
9023         if (pAd->LatchRfRegs.Channel <= 14)
9024         {       // BG band
9025                 R66 = 0x2E + GET_LNA_GAIN(pAd);
9026                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
9027         }
9028         else
9029         {       //A band
9030                 if (BandWidth == BW_20)
9031                 {
9032                         R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3);
9033                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
9034                 }
9035                 else
9036                 {
9037                         R66 = (UCHAR)(0x3A + (GET_LNA_GAIN(pAd)*5)/3);
9038                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
9039                 }
9040         }
9041
9042 }
9043
9044 VOID AsicTurnOffRFClk(
9045         IN PRTMP_ADAPTER pAd,
9046         IN      UCHAR           Channel)
9047 {
9048
9049         // RF R2 bit 18 = 0
9050         UINT32                  R1 = 0, R2 = 0, R3 = 0;
9051         UCHAR                   index;
9052         RTMP_RF_REGS    *RFRegTable;
9053
9054 #ifdef RT30xx
9055         // The RF programming sequence is difference between 3xxx and 2xxx
9056         if (IS_RT3090(pAd))
9057         {
9058                 RT30xxLoadRFSleepModeSetup(pAd);  // add by johnli,  RF power sequence setup, load RF sleep-mode setup
9059         }
9060         else
9061         {
9062 #endif // RT30xx //
9063         RFRegTable = RF2850RegTable;
9064
9065         switch (pAd->RfIcType)
9066         {
9067                 case RFIC_2820:
9068                 case RFIC_2850:
9069                 case RFIC_2720:
9070                 case RFIC_2750:
9071
9072                         for (index = 0; index < NUM_OF_2850_CHNL; index++)
9073                         {
9074                                 if (Channel == RFRegTable[index].Channel)
9075                                 {
9076                                         R1 = RFRegTable[index].R1 & 0xffffdfff;
9077                                         R2 = RFRegTable[index].R2 & 0xfffbffff;
9078                                         R3 = RFRegTable[index].R3 & 0xfff3ffff;
9079
9080                                         RTMP_RF_IO_WRITE32(pAd, R1);
9081                                         RTMP_RF_IO_WRITE32(pAd, R2);
9082
9083                                         // Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0.
9084                                         // Set RF R2 bit18=0, R3 bit[18:19]=0
9085                                         //if (pAd->StaCfg.bRadio == FALSE)
9086                                         if (1)
9087                                         {
9088                                                 RTMP_RF_IO_WRITE32(pAd, R3);
9089
9090                                                 DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x,  R3 = 0x%08x \n",
9091                                                         Channel, pAd->RfIcType, R2, R3));
9092                                         }
9093                                         else
9094                                                 DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n",
9095                                                         Channel, pAd->RfIcType, R2));
9096                                         break;
9097                                 }
9098                         }
9099                         break;
9100
9101                 default:
9102                         break;
9103         }
9104 #ifdef RT30xx
9105         }
9106 #endif // RT30xx //
9107
9108 }
9109
9110
9111 VOID AsicTurnOnRFClk(
9112         IN PRTMP_ADAPTER pAd,
9113         IN      UCHAR                   Channel)
9114 {
9115
9116         // RF R2 bit 18 = 0
9117         UINT32                  R1 = 0, R2 = 0, R3 = 0;
9118         UCHAR                   index;
9119         RTMP_RF_REGS    *RFRegTable;
9120
9121 #ifdef RT30xx
9122         // The RF programming sequence is difference between 3xxx and 2xxx
9123         if (IS_RT3090(pAd))
9124         {
9125         }
9126         else
9127         {
9128 #endif // RT30xx //
9129         RFRegTable = RF2850RegTable;
9130
9131         switch (pAd->RfIcType)
9132         {
9133                 case RFIC_2820:
9134                 case RFIC_2850:
9135                 case RFIC_2720:
9136                 case RFIC_2750:
9137
9138                         for (index = 0; index < NUM_OF_2850_CHNL; index++)
9139                         {
9140                                 if (Channel == RFRegTable[index].Channel)
9141                                 {
9142                                         R3 = pAd->LatchRfRegs.R3;
9143                                         R3 &= 0xfff3ffff;
9144                                         R3 |= 0x00080000;
9145                                         RTMP_RF_IO_WRITE32(pAd, R3);
9146
9147                                         R1 = RFRegTable[index].R1;
9148                                         RTMP_RF_IO_WRITE32(pAd, R1);
9149
9150                                         R2 = RFRegTable[index].R2;
9151                                         if (pAd->Antenna.field.TxPath == 1)
9152                                         {
9153                                                 R2 |= 0x4000;   // If TXpath is 1, bit 14 = 1;
9154                                         }
9155
9156                                         if (pAd->Antenna.field.RxPath == 2)
9157                                         {
9158                                                 R2 |= 0x40;     // write 1 to off Rxpath.
9159                                         }
9160                                         else if (pAd->Antenna.field.RxPath == 1)
9161                                         {
9162                                                 R2 |= 0x20040;  // write 1 to off RxPath
9163                                         }
9164                                         RTMP_RF_IO_WRITE32(pAd, R2);
9165
9166                                         break;
9167                                 }
9168                         }
9169                         break;
9170
9171                 default:
9172                         break;
9173         }
9174
9175 #ifndef RT30xx
9176         DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n",
9177                 Channel,
9178                 pAd->RfIcType,
9179                 R2));
9180 #endif
9181 #ifdef RT30xx
9182         }
9183 #endif // RT30xx //
9184 }
9185