blob: ceb622df12d7a1faf4fb4157fbbd8d4773a8d0d9 [file] [log] [blame]
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001/*
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
Greg Kroah-Hartman91980992008-10-28 14:48:09 -070027 Module Name:
28 action.c
29
30 Abstract:
31 Handle association related requests either from WSTA or from local MLME
32
33 Revision History:
34 Who When What
35 --------- ---------- ----------------------------------------------
36 Fonchi Wu 2008 created for 802.11h
37 */
38
39#include "../rt_config.h"
40#include "action.h"
41
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +020042/* The regulatory information in the USA (US) */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -080043struct rt_dot11_regulatory_information USARegulatoryInfo[] = {
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +020044/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -080045 {0, {0, 0, {0}
46 }
47 }
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -080048 , /* Invlid entry */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -080049 {1, {4, 16, {36, 40, 44, 48}
50 }
51 }
52 ,
53 {2, {4, 23, {52, 56, 60, 64}
54 }
55 }
56 ,
57 {3, {4, 29, {149, 153, 157, 161}
58 }
59 }
60 ,
61 {4, {11, 23, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}
62 }
63 }
64 ,
65 {5, {5, 30, {149, 153, 157, 161, 165}
66 }
67 }
68 ,
69 {6, {10, 14, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
70 }
71 }
72 ,
73 {7, {10, 27, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
74 }
75 }
76 ,
77 {8, {5, 17, {11, 13, 15, 17, 19}
78 }
79 }
80 ,
81 {9, {5, 30, {11, 13, 15, 17, 19}
82 }
83 }
84 ,
85 {10, {2, 20, {21, 25}
86 }
87 }
88 ,
89 {11, {2, 33, {21, 25}
90 }
91 }
92 ,
93 {12, {11, 30, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
94 }
95 }
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +020096};
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -080097
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -080098#define USA_REGULATORY_INFO_SIZE (sizeof(USARegulatoryInfo) / sizeof(struct rt_dot11_regulatory_information))
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +020099
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200100/* The regulatory information in Europe */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800101struct rt_dot11_regulatory_information EuropeRegulatoryInfo[] = {
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200102/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800103 {0, {0, 0, {0}
104 }
105 }
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -0800106 , /* Invalid entry */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800107 {1, {4, 20, {36, 40, 44, 48}
108 }
109 }
110 ,
111 {2, {4, 20, {52, 56, 60, 64}
112 }
113 }
114 ,
115 {3, {11, 30, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}
116 }
117 }
118 ,
119 {4, {13, 20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}
120 }
121 }
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200122};
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800123
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800124#define EU_REGULATORY_INFO_SIZE (sizeof(EuropeRegulatoryInfo) / sizeof(struct rt_dot11_regulatory_information))
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200125
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200126/* The regulatory information in Japan */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800127struct rt_dot11_regulatory_information JapanRegulatoryInfo[] = {
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200128/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800129 {0, {0, 0, {0}
130 }
131 }
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -0800132 , /* Invalid entry */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800133 {1, {4, 22, {34, 38, 42, 46}
134 }
135 }
136 ,
137 {2, {3, 24, {8, 12, 16}
138 }
139 }
140 ,
141 {3, {3, 24, {8, 12, 16}
142 }
143 }
144 ,
145 {4, {3, 24, {8, 12, 16}
146 }
147 }
148 ,
149 {5, {3, 24, {8, 12, 16}
150 }
151 }
152 ,
153 {6, {3, 22, {8, 12, 16}
154 }
155 }
156 ,
157 {7, {4, 24, {184, 188, 192, 196}
158 }
159 }
160 ,
161 {8, {4, 24, {184, 188, 192, 196}
162 }
163 }
164 ,
165 {9, {4, 24, {184, 188, 192, 196}
166 }
167 }
168 ,
169 {10, {4, 24, {184, 188, 192, 196}
170 }
171 }
172 ,
173 {11, {4, 22, {184, 188, 192, 196}
174 }
175 }
176 ,
177 {12, {4, 24, {7, 8, 9, 11}
178 }
179 }
180 ,
181 {13, {4, 24, {7, 8, 9, 11}
182 }
183 }
184 ,
185 {14, {4, 24, {7, 8, 9, 11}
186 }
187 }
188 ,
189 {15, {4, 24, {7, 8, 9, 11}
190 }
191 }
192 ,
193 {16, {6, 24, {183, 184, 185, 187, 188, 189}
194 }
195 }
196 ,
197 {17, {6, 24, {183, 184, 185, 187, 188, 189}
198 }
199 }
200 ,
201 {18, {6, 24, {183, 184, 185, 187, 188, 189}
202 }
203 }
204 ,
205 {19, {6, 24, {183, 184, 185, 187, 188, 189}
206 }
207 }
208 ,
209 {20, {6, 17, {183, 184, 185, 187, 188, 189}
210 }
211 }
212 ,
213 {21, {6, 24, {6, 7, 8, 9, 10, 11}
214 }
215 }
216 ,
217 {22, {6, 24, {6, 7, 8, 9, 10, 11}
218 }
219 }
220 ,
221 {23, {6, 24, {6, 7, 8, 9, 10, 11}
222 }
223 }
224 ,
225 {24, {6, 24, {6, 7, 8, 9, 10, 11}
226 }
227 }
228 ,
229 {25, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}
230 }
231 }
232 ,
233 {26, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}
234 }
235 }
236 ,
237 {27, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}
238 }
239 }
240 ,
241 {28, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}
242 }
243 }
244 ,
245 {29, {8, 17, {182, 183, 184, 185, 186, 187, 188, 189}
246 }
247 }
248 ,
249 {30, {13, 23, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}
250 }
251 }
252 ,
253 {31, {1, 23, {14}
254 }
255 }
256 ,
257 {32, {4, 22, {52, 56, 60, 64}
258 }
259 }
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200260};
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800261
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800262#define JP_REGULATORY_INFO_SIZE (sizeof(JapanRegulatoryInfo) / sizeof(struct rt_dot11_regulatory_information))
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200263
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800264char RTMP_GetTxPwr(struct rt_rtmp_adapter *pAd, IN HTTRANSMIT_SETTING HTTxMode)
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200265{
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800266 struct tx_pwr_cfg {
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -0800267 u8 Mode;
268 u8 MCS;
269 u16 req;
270 u8 shift;
271 u32 BitMask;
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800272 };
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200273
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -0800274 u32 Value;
275 int Idx;
276 u8 PhyMode;
277 char CurTxPwr;
278 u8 TxPwrRef = 0;
279 char DaltaPwr;
280 unsigned long TxPwr[5];
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200281
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800282 struct tx_pwr_cfg TxPwrCfg[] = {
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200283 {MODE_CCK, 0, 0, 4, 0x000000f0},
284 {MODE_CCK, 1, 0, 0, 0x0000000f},
285 {MODE_CCK, 2, 0, 12, 0x0000f000},
286 {MODE_CCK, 3, 0, 8, 0x00000f00},
287
288 {MODE_OFDM, 0, 0, 20, 0x00f00000},
289 {MODE_OFDM, 1, 0, 16, 0x000f0000},
290 {MODE_OFDM, 2, 0, 28, 0xf0000000},
291 {MODE_OFDM, 3, 0, 24, 0x0f000000},
292 {MODE_OFDM, 4, 1, 4, 0x000000f0},
293 {MODE_OFDM, 5, 1, 0, 0x0000000f},
294 {MODE_OFDM, 6, 1, 12, 0x0000f000},
295 {MODE_OFDM, 7, 1, 8, 0x00000f00}
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800296 , {MODE_HTMIX, 0, 1, 20, 0x00f00000},
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200297 {MODE_HTMIX, 1, 1, 16, 0x000f0000},
298 {MODE_HTMIX, 2, 1, 28, 0xf0000000},
299 {MODE_HTMIX, 3, 1, 24, 0x0f000000},
300 {MODE_HTMIX, 4, 2, 4, 0x000000f0},
301 {MODE_HTMIX, 5, 2, 0, 0x0000000f},
302 {MODE_HTMIX, 6, 2, 12, 0x0000f000},
303 {MODE_HTMIX, 7, 2, 8, 0x00000f00},
304 {MODE_HTMIX, 8, 2, 20, 0x00f00000},
305 {MODE_HTMIX, 9, 2, 16, 0x000f0000},
306 {MODE_HTMIX, 10, 2, 28, 0xf0000000},
307 {MODE_HTMIX, 11, 2, 24, 0x0f000000},
308 {MODE_HTMIX, 12, 3, 4, 0x000000f0},
309 {MODE_HTMIX, 13, 3, 0, 0x0000000f},
310 {MODE_HTMIX, 14, 3, 12, 0x0000f000},
311 {MODE_HTMIX, 15, 3, 8, 0x00000f00}
312 };
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800313#define MAX_TXPWR_TAB_SIZE (sizeof(TxPwrCfg) / sizeof(struct tx_pwr_cfg))
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200314
315 CurTxPwr = 19;
316
317 /* check Tx Power setting from UI. */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800318 if (pAd->CommonCfg.TxPowerPercentage > 90) ;
319 else if (pAd->CommonCfg.TxPowerPercentage > 60) /* reduce Pwr for 1 dB. */
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200320 CurTxPwr -= 1;
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800321 else if (pAd->CommonCfg.TxPowerPercentage > 30) /* reduce Pwr for 3 dB. */
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200322 CurTxPwr -= 3;
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800323 else if (pAd->CommonCfg.TxPowerPercentage > 15) /* reduce Pwr for 6 dB. */
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200324 CurTxPwr -= 6;
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800325 else if (pAd->CommonCfg.TxPowerPercentage > 9) /* reduce Pwr for 9 dB. */
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200326 CurTxPwr -= 9;
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800327 else /* reduce Pwr for 12 dB. */
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200328 CurTxPwr -= 12;
329
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800330 if (pAd->CommonCfg.BBPCurrentBW == BW_40) {
331 if (pAd->CommonCfg.CentralChannel > 14) {
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200332 TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
333 TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
334 TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
335 TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
336 TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800337 } else {
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200338 TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
339 TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
340 TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
341 TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
342 TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
343 }
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800344 } else {
345 if (pAd->CommonCfg.Channel > 14) {
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200346 TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
347 TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
348 TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
349 TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
350 TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800351 } else {
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200352 TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
353 TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
354 TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
355 TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
356 TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
357 }
358 }
359
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800360 switch (HTTxMode.field.MODE) {
361 case MODE_CCK:
362 case MODE_OFDM:
363 Value = TxPwr[1];
364 TxPwrRef = (Value & 0x00000f00) >> 8;
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200365
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800366 break;
367
368 case MODE_HTMIX:
369 case MODE_HTGREENFIELD:
370 if (pAd->CommonCfg.TxStream == 1) {
371 Value = TxPwr[2];
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200372 TxPwrRef = (Value & 0x00000f00) >> 8;
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800373 } else if (pAd->CommonCfg.TxStream == 2) {
374 Value = TxPwr[3];
375 TxPwrRef = (Value & 0x00000f00) >> 8;
376 }
377 break;
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200378 }
379
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800380 PhyMode = (HTTxMode.field.MODE == MODE_HTGREENFIELD)
381 ? MODE_HTMIX : HTTxMode.field.MODE;
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200382
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800383 for (Idx = 0; Idx < MAX_TXPWR_TAB_SIZE; Idx++) {
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200384 if ((TxPwrCfg[Idx].Mode == PhyMode)
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800385 && (TxPwrCfg[Idx].MCS == HTTxMode.field.MCS)) {
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200386 Value = TxPwr[TxPwrCfg[Idx].req];
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800387 DaltaPwr =
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -0800388 TxPwrRef - (char)((Value & TxPwrCfg[Idx].BitMask)
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800389 >> TxPwrCfg[Idx].shift);
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200390 CurTxPwr -= DaltaPwr;
391 break;
392 }
393 }
394
395 return CurTxPwr;
396}
397
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800398void MeasureReqTabInit(struct rt_rtmp_adapter *pAd)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700399{
400 NdisAllocateSpinLock(&pAd->CommonCfg.MeasureReqTabLock);
401
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800402 pAd->CommonCfg.pMeasureReqTab =
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800403 kmalloc(sizeof(struct rt_measure_req_tab), GFP_ATOMIC);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700404 if (pAd->CommonCfg.pMeasureReqTab)
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800405 NdisZeroMemory(pAd->CommonCfg.pMeasureReqTab,
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800406 sizeof(struct rt_measure_req_tab));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700407 else
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800408 DBGPRINT(RT_DEBUG_ERROR,
409 ("%s Fail to alloc memory for pAd->CommonCfg.pMeasureReqTab.\n",
410 __func__));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700411
412 return;
413}
414
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800415void MeasureReqTabExit(struct rt_rtmp_adapter *pAd)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700416{
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200417 NdisFreeSpinLock(&pAd->CommonCfg.MeasureReqTabLock);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700418
Ilia Mirkinaea9d722011-03-13 00:29:04 -0500419 kfree(pAd->CommonCfg.pMeasureReqTab);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700420 pAd->CommonCfg.pMeasureReqTab = NULL;
421
422 return;
423}
424
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800425struct rt_measure_req_entry *MeasureReqLookUp(struct rt_rtmp_adapter *pAd, u8 DialogToken)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700426{
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -0800427 u32 HashIdx;
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800428 struct rt_measure_req_tab *pTab = pAd->CommonCfg.pMeasureReqTab;
429 struct rt_measure_req_entry *pEntry = NULL;
430 struct rt_measure_req_entry *pPrevEntry = NULL;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700431
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800432 if (pTab == NULL) {
433 DBGPRINT(RT_DEBUG_ERROR,
434 ("%s: pMeasureReqTab doesn't exist.\n", __func__));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700435 return NULL;
436 }
437
438 RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
439
440 HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken);
441 pEntry = pTab->Hash[HashIdx];
442
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800443 while (pEntry) {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700444 if (pEntry->DialogToken == DialogToken)
445 break;
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800446 else {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700447 pPrevEntry = pEntry;
448 pEntry = pEntry->pNext;
449 }
450 }
451
452 RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
453
454 return pEntry;
455}
456
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800457struct rt_measure_req_entry *MeasureReqInsert(struct rt_rtmp_adapter *pAd, u8 DialogToken)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700458{
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -0800459 int i;
460 unsigned long HashIdx;
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800461 struct rt_measure_req_tab *pTab = pAd->CommonCfg.pMeasureReqTab;
462 struct rt_measure_req_entry *pEntry = NULL, *pCurrEntry;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -0800463 unsigned long Now;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700464
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800465 if (pTab == NULL) {
466 DBGPRINT(RT_DEBUG_ERROR,
467 ("%s: pMeasureReqTab doesn't exist.\n", __func__));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700468 return NULL;
469 }
470
471 pEntry = MeasureReqLookUp(pAd, DialogToken);
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800472 if (pEntry == NULL) {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700473 RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800474 for (i = 0; i < MAX_MEASURE_REQ_TAB_SIZE; i++) {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700475 NdisGetSystemUpTime(&Now);
476 pEntry = &pTab->Content[i];
477
478 if ((pEntry->Valid == TRUE)
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800479 && RTMP_TIME_AFTER((unsigned long)Now,
480 (unsigned long)(pEntry->
481 lastTime +
482 MQ_REQ_AGE_OUT)))
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700483 {
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800484 struct rt_measure_req_entry *pPrevEntry = NULL;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -0800485 unsigned long HashIdx =
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800486 MQ_DIALOGTOKEN_HASH_INDEX(pEntry->
487 DialogToken);
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800488 struct rt_measure_req_entry *pProbeEntry =
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800489 pTab->Hash[HashIdx];
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700490
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -0800491 /* update Hash list */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800492 do {
493 if (pProbeEntry == pEntry) {
494 if (pPrevEntry == NULL) {
495 pTab->Hash[HashIdx] =
496 pEntry->pNext;
497 } else {
498 pPrevEntry->pNext =
499 pEntry->pNext;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700500 }
501 break;
502 }
503
504 pPrevEntry = pProbeEntry;
505 pProbeEntry = pProbeEntry->pNext;
506 } while (pProbeEntry);
507
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800508 NdisZeroMemory(pEntry,
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800509 sizeof(struct rt_measure_req_entry));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700510 pTab->Size--;
511
512 break;
513 }
514
515 if (pEntry->Valid == FALSE)
516 break;
517 }
518
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800519 if (i < MAX_MEASURE_REQ_TAB_SIZE) {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700520 NdisGetSystemUpTime(&Now);
521 pEntry->lastTime = Now;
522 pEntry->Valid = TRUE;
523 pEntry->DialogToken = DialogToken;
524 pTab->Size++;
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800525 } else {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700526 pEntry = NULL;
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800527 DBGPRINT(RT_DEBUG_ERROR,
528 ("%s: pMeasureReqTab tab full.\n", __func__));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700529 }
530
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -0800531 /* add this Neighbor entry into HASH table */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800532 if (pEntry) {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700533 HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken);
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800534 if (pTab->Hash[HashIdx] == NULL) {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700535 pTab->Hash[HashIdx] = pEntry;
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800536 } else {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700537 pCurrEntry = pTab->Hash[HashIdx];
538 while (pCurrEntry->pNext != NULL)
539 pCurrEntry = pCurrEntry->pNext;
540 pCurrEntry->pNext = pEntry;
541 }
542 }
543
544 RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
545 }
546
547 return pEntry;
548}
549
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800550void MeasureReqDelete(struct rt_rtmp_adapter *pAd, u8 DialogToken)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700551{
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800552 struct rt_measure_req_tab *pTab = pAd->CommonCfg.pMeasureReqTab;
553 struct rt_measure_req_entry *pEntry = NULL;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700554
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800555 if (pTab == NULL) {
556 DBGPRINT(RT_DEBUG_ERROR,
557 ("%s: pMeasureReqTab doesn't exist.\n", __func__));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700558 return;
559 }
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -0800560 /* if empty, return */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800561 if (pTab->Size == 0) {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700562 DBGPRINT(RT_DEBUG_ERROR, ("pMeasureReqTab empty.\n"));
563 return;
564 }
565
566 pEntry = MeasureReqLookUp(pAd, DialogToken);
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800567 if (pEntry != NULL) {
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800568 struct rt_measure_req_entry *pPrevEntry = NULL;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -0800569 unsigned long HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800570 struct rt_measure_req_entry *pProbeEntry = pTab->Hash[HashIdx];
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700571
572 RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -0800573 /* update Hash list */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800574 do {
575 if (pProbeEntry == pEntry) {
576 if (pPrevEntry == NULL) {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700577 pTab->Hash[HashIdx] = pEntry->pNext;
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800578 } else {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700579 pPrevEntry->pNext = pEntry->pNext;
580 }
581 break;
582 }
583
584 pPrevEntry = pProbeEntry;
585 pProbeEntry = pProbeEntry->pNext;
586 } while (pProbeEntry);
587
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800588 NdisZeroMemory(pEntry, sizeof(struct rt_measure_req_entry));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700589 pTab->Size--;
590
591 RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
592 }
593
594 return;
595}
596
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800597void TpcReqTabInit(struct rt_rtmp_adapter *pAd)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700598{
599 NdisAllocateSpinLock(&pAd->CommonCfg.TpcReqTabLock);
600
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800601 pAd->CommonCfg.pTpcReqTab = kmalloc(sizeof(struct rt_tpc_req_tab), GFP_ATOMIC);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700602 if (pAd->CommonCfg.pTpcReqTab)
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800603 NdisZeroMemory(pAd->CommonCfg.pTpcReqTab, sizeof(struct rt_tpc_req_tab));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700604 else
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800605 DBGPRINT(RT_DEBUG_ERROR,
606 ("%s Fail to alloc memory for pAd->CommonCfg.pTpcReqTab.\n",
607 __func__));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700608
609 return;
610}
611
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800612void TpcReqTabExit(struct rt_rtmp_adapter *pAd)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700613{
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200614 NdisFreeSpinLock(&pAd->CommonCfg.TpcReqTabLock);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700615
Ilia Mirkinaea9d722011-03-13 00:29:04 -0500616 kfree(pAd->CommonCfg.pTpcReqTab);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700617 pAd->CommonCfg.pTpcReqTab = NULL;
618
619 return;
620}
621
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800622static struct rt_tpc_req_entry *TpcReqLookUp(struct rt_rtmp_adapter *pAd, u8 DialogToken)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700623{
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -0800624 u32 HashIdx;
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800625 struct rt_tpc_req_tab *pTab = pAd->CommonCfg.pTpcReqTab;
626 struct rt_tpc_req_entry *pEntry = NULL;
627 struct rt_tpc_req_entry *pPrevEntry = NULL;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700628
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800629 if (pTab == NULL) {
630 DBGPRINT(RT_DEBUG_ERROR,
631 ("%s: pTpcReqTab doesn't exist.\n", __func__));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700632 return NULL;
633 }
634
635 RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
636
637 HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken);
638 pEntry = pTab->Hash[HashIdx];
639
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800640 while (pEntry) {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700641 if (pEntry->DialogToken == DialogToken)
642 break;
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800643 else {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700644 pPrevEntry = pEntry;
645 pEntry = pEntry->pNext;
646 }
647 }
648
649 RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
650
651 return pEntry;
652}
653
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800654static struct rt_tpc_req_entry *TpcReqInsert(struct rt_rtmp_adapter *pAd, u8 DialogToken)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700655{
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -0800656 int i;
657 unsigned long HashIdx;
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800658 struct rt_tpc_req_tab *pTab = pAd->CommonCfg.pTpcReqTab;
659 struct rt_tpc_req_entry *pEntry = NULL, *pCurrEntry;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -0800660 unsigned long Now;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700661
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800662 if (pTab == NULL) {
663 DBGPRINT(RT_DEBUG_ERROR,
664 ("%s: pTpcReqTab doesn't exist.\n", __func__));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700665 return NULL;
666 }
667
668 pEntry = TpcReqLookUp(pAd, DialogToken);
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800669 if (pEntry == NULL) {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700670 RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800671 for (i = 0; i < MAX_TPC_REQ_TAB_SIZE; i++) {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700672 NdisGetSystemUpTime(&Now);
673 pEntry = &pTab->Content[i];
674
675 if ((pEntry->Valid == TRUE)
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800676 && RTMP_TIME_AFTER((unsigned long)Now,
677 (unsigned long)(pEntry->
678 lastTime +
679 TPC_REQ_AGE_OUT)))
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700680 {
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800681 struct rt_tpc_req_entry *pPrevEntry = NULL;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -0800682 unsigned long HashIdx =
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800683 TPC_DIALOGTOKEN_HASH_INDEX(pEntry->
684 DialogToken);
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800685 struct rt_tpc_req_entry *pProbeEntry =
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800686 pTab->Hash[HashIdx];
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700687
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -0800688 /* update Hash list */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800689 do {
690 if (pProbeEntry == pEntry) {
691 if (pPrevEntry == NULL) {
692 pTab->Hash[HashIdx] =
693 pEntry->pNext;
694 } else {
695 pPrevEntry->pNext =
696 pEntry->pNext;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700697 }
698 break;
699 }
700
701 pPrevEntry = pProbeEntry;
702 pProbeEntry = pProbeEntry->pNext;
703 } while (pProbeEntry);
704
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800705 NdisZeroMemory(pEntry, sizeof(struct rt_tpc_req_entry));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700706 pTab->Size--;
707
708 break;
709 }
710
711 if (pEntry->Valid == FALSE)
712 break;
713 }
714
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800715 if (i < MAX_TPC_REQ_TAB_SIZE) {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700716 NdisGetSystemUpTime(&Now);
717 pEntry->lastTime = Now;
718 pEntry->Valid = TRUE;
719 pEntry->DialogToken = DialogToken;
720 pTab->Size++;
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800721 } else {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700722 pEntry = NULL;
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800723 DBGPRINT(RT_DEBUG_ERROR,
724 ("%s: pTpcReqTab tab full.\n", __func__));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700725 }
726
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -0800727 /* add this Neighbor entry into HASH table */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800728 if (pEntry) {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700729 HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken);
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800730 if (pTab->Hash[HashIdx] == NULL) {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700731 pTab->Hash[HashIdx] = pEntry;
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800732 } else {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700733 pCurrEntry = pTab->Hash[HashIdx];
734 while (pCurrEntry->pNext != NULL)
735 pCurrEntry = pCurrEntry->pNext;
736 pCurrEntry->pNext = pEntry;
737 }
738 }
739
740 RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
741 }
742
743 return pEntry;
744}
745
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800746static void TpcReqDelete(struct rt_rtmp_adapter *pAd, u8 DialogToken)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700747{
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800748 struct rt_tpc_req_tab *pTab = pAd->CommonCfg.pTpcReqTab;
749 struct rt_tpc_req_entry *pEntry = NULL;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700750
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800751 if (pTab == NULL) {
752 DBGPRINT(RT_DEBUG_ERROR,
753 ("%s: pTpcReqTab doesn't exist.\n", __func__));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700754 return;
755 }
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -0800756 /* if empty, return */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800757 if (pTab->Size == 0) {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700758 DBGPRINT(RT_DEBUG_ERROR, ("pTpcReqTab empty.\n"));
759 return;
760 }
761
762 pEntry = TpcReqLookUp(pAd, DialogToken);
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800763 if (pEntry != NULL) {
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800764 struct rt_tpc_req_entry *pPrevEntry = NULL;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -0800765 unsigned long HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800766 struct rt_tpc_req_entry *pProbeEntry = pTab->Hash[HashIdx];
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700767
768 RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -0800769 /* update Hash list */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800770 do {
771 if (pProbeEntry == pEntry) {
772 if (pPrevEntry == NULL) {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700773 pTab->Hash[HashIdx] = pEntry->pNext;
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800774 } else {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700775 pPrevEntry->pNext = pEntry->pNext;
776 }
777 break;
778 }
779
780 pPrevEntry = pProbeEntry;
781 pProbeEntry = pProbeEntry->pNext;
782 } while (pProbeEntry);
783
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800784 NdisZeroMemory(pEntry, sizeof(struct rt_tpc_req_entry));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700785 pTab->Size--;
786
787 RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
788 }
789
790 return;
791}
792
793/*
794 ==========================================================================
795 Description:
796 Get Current TimeS tamp.
797
798 Parametrs:
799
800 Return : Current Time Stamp.
801 ==========================================================================
802 */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800803static u64 GetCurrentTimeStamp(struct rt_rtmp_adapter *pAd)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700804{
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -0800805 /* get current time stamp. */
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700806 return 0;
807}
808
809/*
810 ==========================================================================
811 Description:
812 Get Current Transmit Power.
813
814 Parametrs:
815
816 Return : Current Time Stamp.
817 ==========================================================================
818 */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800819static u8 GetCurTxPwr(struct rt_rtmp_adapter *pAd, u8 Wcid)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700820{
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800821 return 16; /* 16 dBm */
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700822}
823
824/*
825 ==========================================================================
826 Description:
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200827 Get Current Transmit Power.
828
829 Parametrs:
830
831 Return : Current Time Stamp.
832 ==========================================================================
833 */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800834void InsertChannelRepIE(struct rt_rtmp_adapter *pAd,
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -0800835 u8 *pFrameBuf,
836 unsigned long *pFrameLen,
837 char *pCountry, u8 RegulatoryClass)
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200838{
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -0800839 unsigned long TempLen;
840 u8 Len;
841 u8 IEId = IE_AP_CHANNEL_REPORT;
842 u8 *pChListPtr = NULL;
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200843
844 Len = 1;
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800845 if (strncmp(pCountry, "US", 2) == 0) {
846 if (RegulatoryClass >= USA_REGULATORY_INFO_SIZE) {
847 DBGPRINT(RT_DEBUG_ERROR,
848 ("%s: USA Unknow Requlatory class (%d)\n",
849 __func__, RegulatoryClass));
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200850 return;
851 }
852
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800853 Len +=
854 USARegulatoryInfo[RegulatoryClass].ChannelSet.
855 NumberOfChannels;
856 pChListPtr =
857 USARegulatoryInfo[RegulatoryClass].ChannelSet.ChannelList;
858 } else if (strncmp(pCountry, "JP", 2) == 0) {
859 if (RegulatoryClass >= JP_REGULATORY_INFO_SIZE) {
860 DBGPRINT(RT_DEBUG_ERROR,
861 ("%s: JP Unknow Requlatory class (%d)\n",
862 __func__, RegulatoryClass));
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200863 return;
864 }
865
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800866 Len +=
867 JapanRegulatoryInfo[RegulatoryClass].ChannelSet.
868 NumberOfChannels;
869 pChListPtr =
870 JapanRegulatoryInfo[RegulatoryClass].ChannelSet.ChannelList;
871 } else {
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200872 DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknow Country (%s)\n",
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800873 __func__, pCountry));
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200874 return;
875 }
876
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800877 MakeOutgoingFrame(pFrameBuf, &TempLen,
878 1, &IEId,
879 1, &Len,
880 1, &RegulatoryClass,
881 Len - 1, pChListPtr, END_OF_ARGS);
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +0200882
883 *pFrameLen = *pFrameLen + TempLen;
884
885 return;
886}
887
888/*
889 ==========================================================================
890 Description:
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700891 Insert Dialog Token into frame.
892
893 Parametrs:
894 1. frame buffer pointer.
895 2. frame length.
896 3. Dialog token.
897
898 Return : None.
899 ==========================================================================
900 */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800901void InsertDialogToken(struct rt_rtmp_adapter *pAd,
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -0800902 u8 *pFrameBuf,
903 unsigned long *pFrameLen, u8 DialogToken)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700904{
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -0800905 unsigned long TempLen;
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800906 MakeOutgoingFrame(pFrameBuf, &TempLen, 1, &DialogToken, END_OF_ARGS);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700907
908 *pFrameLen = *pFrameLen + TempLen;
909
910 return;
911}
912
913/*
914 ==========================================================================
915 Description:
916 Insert TPC Request IE into frame.
917
918 Parametrs:
919 1. frame buffer pointer.
920 2. frame length.
921
922 Return : None.
923 ==========================================================================
924 */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800925static void InsertTpcReqIE(struct rt_rtmp_adapter *pAd,
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -0800926 u8 *pFrameBuf, unsigned long *pFrameLen)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700927{
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -0800928 unsigned long TempLen;
929 unsigned long Len = 0;
930 u8 ElementID = IE_TPC_REQUEST;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700931
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800932 MakeOutgoingFrame(pFrameBuf, &TempLen,
933 1, &ElementID, 1, &Len, END_OF_ARGS);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700934
935 *pFrameLen = *pFrameLen + TempLen;
936
937 return;
938}
939
940/*
941 ==========================================================================
942 Description:
943 Insert TPC Report IE into frame.
944
945 Parametrs:
946 1. frame buffer pointer.
947 2. frame length.
948 3. Transmit Power.
949 4. Link Margin.
950
951 Return : None.
952 ==========================================================================
953 */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800954void InsertTpcReportIE(struct rt_rtmp_adapter *pAd,
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -0800955 u8 *pFrameBuf,
956 unsigned long *pFrameLen,
957 u8 TxPwr, u8 LinkMargin)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700958{
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -0800959 unsigned long TempLen;
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800960 unsigned long Len = sizeof(struct rt_tpc_report_info);
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -0800961 u8 ElementID = IE_TPC_REPORT;
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800962 struct rt_tpc_report_info TpcReportIE;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700963
964 TpcReportIE.TxPwr = TxPwr;
965 TpcReportIE.LinkMargin = LinkMargin;
966
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -0800967 MakeOutgoingFrame(pFrameBuf, &TempLen,
968 1, &ElementID,
969 1, &Len, Len, &TpcReportIE, END_OF_ARGS);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700970
971 *pFrameLen = *pFrameLen + TempLen;
972
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700973 return;
974}
975
976/*
977 ==========================================================================
978 Description:
979 Insert Channel Switch Announcement IE into frame.
980
981 Parametrs:
982 1. frame buffer pointer.
983 2. frame length.
984 3. channel switch announcement mode.
985 4. new selected channel.
986 5. channel switch announcement count.
987
988 Return : None.
989 ==========================================================================
990 */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800991static void InsertChSwAnnIE(struct rt_rtmp_adapter *pAd,
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -0800992 u8 *pFrameBuf,
993 unsigned long *pFrameLen,
994 u8 ChSwMode,
995 u8 NewChannel, u8 ChSwCnt)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700996{
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -0800997 unsigned long TempLen;
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -0800998 unsigned long Len = sizeof(struct rt_ch_sw_ann_info);
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -0800999 u8 ElementID = IE_CHANNEL_SWITCH_ANNOUNCEMENT;
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001000 struct rt_ch_sw_ann_info ChSwAnnIE;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001001
1002 ChSwAnnIE.ChSwMode = ChSwMode;
1003 ChSwAnnIE.Channel = NewChannel;
1004 ChSwAnnIE.ChSwCnt = ChSwCnt;
1005
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001006 MakeOutgoingFrame(pFrameBuf, &TempLen,
1007 1, &ElementID, 1, &Len, Len, &ChSwAnnIE, END_OF_ARGS);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001008
1009 *pFrameLen = *pFrameLen + TempLen;
1010
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001011 return;
1012}
1013
1014/*
1015 ==========================================================================
1016 Description:
1017 Insert Measure Request IE into frame.
1018
1019 Parametrs:
1020 1. frame buffer pointer.
1021 2. frame length.
1022 3. Measure Token.
1023 4. Measure Request Mode.
1024 5. Measure Request Type.
1025 6. Measure Channel.
1026 7. Measure Start time.
1027 8. Measure Duration.
1028
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001029 Return : None.
1030 ==========================================================================
1031 */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001032static void InsertMeasureReqIE(struct rt_rtmp_adapter *pAd,
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001033 u8 *pFrameBuf,
1034 unsigned long *pFrameLen,
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001035 u8 Len, struct rt_measure_req_info * pMeasureReqIE)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001036{
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001037 unsigned long TempLen;
1038 u8 ElementID = IE_MEASUREMENT_REQUEST;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001039
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001040 MakeOutgoingFrame(pFrameBuf, &TempLen,
1041 1, &ElementID,
1042 1, &Len,
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001043 sizeof(struct rt_measure_req_info), pMeasureReqIE, END_OF_ARGS);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001044
1045 *pFrameLen = *pFrameLen + TempLen;
1046
1047 return;
1048}
1049
1050/*
1051 ==========================================================================
1052 Description:
1053 Insert Measure Report IE into frame.
1054
1055 Parametrs:
1056 1. frame buffer pointer.
1057 2. frame length.
1058 3. Measure Token.
1059 4. Measure Request Mode.
1060 5. Measure Request Type.
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001061 6. Length of Report Information
1062 7. Pointer of Report Information Buffer.
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001063
1064 Return : None.
1065 ==========================================================================
1066 */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001067static void InsertMeasureReportIE(struct rt_rtmp_adapter *pAd,
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001068 u8 *pFrameBuf,
1069 unsigned long *pFrameLen,
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001070 struct rt_measure_report_info * pMeasureReportIE,
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001071 u8 ReportLnfoLen, u8 *pReportInfo)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001072{
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001073 unsigned long TempLen;
1074 unsigned long Len;
1075 u8 ElementID = IE_MEASUREMENT_REPORT;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001076
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001077 Len = sizeof(struct rt_measure_report_info) + ReportLnfoLen;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001078
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001079 MakeOutgoingFrame(pFrameBuf, &TempLen,
1080 1, &ElementID,
1081 1, &Len, Len, pMeasureReportIE, END_OF_ARGS);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001082
1083 *pFrameLen = *pFrameLen + TempLen;
1084
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001085 if ((ReportLnfoLen > 0) && (pReportInfo != NULL)) {
1086 MakeOutgoingFrame(pFrameBuf + *pFrameLen, &TempLen,
1087 ReportLnfoLen, pReportInfo, END_OF_ARGS);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001088
1089 *pFrameLen = *pFrameLen + TempLen;
1090 }
1091 return;
1092}
1093
1094/*
1095 ==========================================================================
1096 Description:
1097 Prepare Measurement request action frame and enqueue it into
1098 management queue waiting for transmition.
1099
1100 Parametrs:
1101 1. the destination mac address of the frame.
1102
1103 Return : None.
1104 ==========================================================================
1105 */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001106void MakeMeasurementReqFrame(struct rt_rtmp_adapter *pAd,
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001107 u8 *pOutBuffer,
1108 unsigned long *pFrameLen,
1109 u8 TotalLen,
1110 u8 Category,
1111 u8 Action,
1112 u8 MeasureToken,
1113 u8 MeasureReqMode,
1114 u8 MeasureReqType, u8 NumOfRepetitions)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001115{
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001116 unsigned long TempLen;
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001117 struct rt_measure_req_info MeasureReqIE;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001118
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001119 InsertActField(pAd, (pOutBuffer + *pFrameLen), pFrameLen, Category,
1120 Action);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001121
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001122 /* fill Dialog Token */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001123 InsertDialogToken(pAd, (pOutBuffer + *pFrameLen), pFrameLen,
1124 MeasureToken);
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +02001125
1126 /* fill Number of repetitions. */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001127 if (Category == CATEGORY_RM) {
1128 MakeOutgoingFrame((pOutBuffer + *pFrameLen), &TempLen,
1129 2, &NumOfRepetitions, END_OF_ARGS);
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +02001130
1131 *pFrameLen += TempLen;
1132 }
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001133 /* prepare Measurement IE. */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001134 NdisZeroMemory(&MeasureReqIE, sizeof(struct rt_measure_req_info));
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +02001135 MeasureReqIE.Token = MeasureToken;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001136 MeasureReqIE.ReqMode.word = MeasureReqMode;
1137 MeasureReqIE.ReqType = MeasureReqType;
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001138 InsertMeasureReqIE(pAd, (pOutBuffer + *pFrameLen), pFrameLen,
1139 TotalLen, &MeasureReqIE);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001140
1141 return;
1142}
1143
1144/*
1145 ==========================================================================
1146 Description:
1147 Prepare Measurement report action frame and enqueue it into
1148 management queue waiting for transmition.
1149
1150 Parametrs:
1151 1. the destination mac address of the frame.
1152
1153 Return : None.
1154 ==========================================================================
1155 */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001156void EnqueueMeasurementRep(struct rt_rtmp_adapter *pAd,
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001157 u8 *pDA,
1158 u8 DialogToken,
1159 u8 MeasureToken,
1160 u8 MeasureReqMode,
1161 u8 MeasureReqType,
1162 u8 ReportInfoLen, u8 *pReportInfo)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001163{
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001164 u8 *pOutBuffer = NULL;
1165 int NStatus;
1166 unsigned long FrameLen;
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001167 struct rt_header_802_11 ActHdr;
1168 struct rt_measure_report_info MeasureRepIE;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001169
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001170 /* build action frame header. */
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001171 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001172 pAd->CurrentAddress);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001173
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001174 NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer); /*Get an unused nonpaged memory */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001175 if (NStatus != NDIS_STATUS_SUCCESS) {
1176 DBGPRINT(RT_DEBUG_TRACE,
1177 ("%s() allocate memory failed \n", __func__));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001178 return;
1179 }
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001180 NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11));
1181 FrameLen = sizeof(struct rt_header_802_11);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001182
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001183 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen,
1184 CATEGORY_SPECTRUM, SPEC_MRP);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001185
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001186 /* fill Dialog Token */
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001187 InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
1188
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001189 /* prepare Measurement IE. */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001190 NdisZeroMemory(&MeasureRepIE, sizeof(struct rt_measure_report_info));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001191 MeasureRepIE.Token = MeasureToken;
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +02001192 MeasureRepIE.ReportMode = MeasureReqMode;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001193 MeasureRepIE.ReportType = MeasureReqType;
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001194 InsertMeasureReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen,
1195 &MeasureRepIE, ReportInfoLen, pReportInfo);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001196
1197 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1198 MlmeFreeMemory(pAd, pOutBuffer);
1199
1200 return;
1201}
1202
1203/*
1204 ==========================================================================
1205 Description:
1206 Prepare TPC Request action frame and enqueue it into
1207 management queue waiting for transmition.
1208
1209 Parametrs:
1210 1. the destination mac address of the frame.
1211
1212 Return : None.
1213 ==========================================================================
1214 */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001215void EnqueueTPCReq(struct rt_rtmp_adapter *pAd, u8 *pDA, u8 DialogToken)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001216{
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001217 u8 *pOutBuffer = NULL;
1218 int NStatus;
1219 unsigned long FrameLen;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001220
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001221 struct rt_header_802_11 ActHdr;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001222
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001223 /* build action frame header. */
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001224 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001225 pAd->CurrentAddress);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001226
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001227 NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer); /*Get an unused nonpaged memory */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001228 if (NStatus != NDIS_STATUS_SUCCESS) {
1229 DBGPRINT(RT_DEBUG_TRACE,
1230 ("%s() allocate memory failed \n", __func__));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001231 return;
1232 }
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001233 NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11));
1234 FrameLen = sizeof(struct rt_header_802_11);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001235
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001236 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen,
1237 CATEGORY_SPECTRUM, SPEC_TPCRQ);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001238
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001239 /* fill Dialog Token */
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001240 InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
1241
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001242 /* Insert TPC Request IE. */
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001243 InsertTpcReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen);
1244
1245 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1246 MlmeFreeMemory(pAd, pOutBuffer);
1247
1248 return;
1249}
1250
1251/*
1252 ==========================================================================
1253 Description:
1254 Prepare TPC Report action frame and enqueue it into
1255 management queue waiting for transmition.
1256
1257 Parametrs:
1258 1. the destination mac address of the frame.
1259
1260 Return : None.
1261 ==========================================================================
1262 */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001263void EnqueueTPCRep(struct rt_rtmp_adapter *pAd,
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001264 u8 *pDA,
1265 u8 DialogToken, u8 TxPwr, u8 LinkMargin)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001266{
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001267 u8 *pOutBuffer = NULL;
1268 int NStatus;
1269 unsigned long FrameLen;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001270
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001271 struct rt_header_802_11 ActHdr;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001272
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001273 /* build action frame header. */
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001274 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001275 pAd->CurrentAddress);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001276
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001277 NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer); /*Get an unused nonpaged memory */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001278 if (NStatus != NDIS_STATUS_SUCCESS) {
1279 DBGPRINT(RT_DEBUG_TRACE,
1280 ("%s() allocate memory failed \n", __func__));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001281 return;
1282 }
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001283 NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11));
1284 FrameLen = sizeof(struct rt_header_802_11);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001285
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001286 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen,
1287 CATEGORY_SPECTRUM, SPEC_TPCRP);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001288
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001289 /* fill Dialog Token */
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001290 InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
1291
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001292 /* Insert TPC Request IE. */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001293 InsertTpcReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, TxPwr,
1294 LinkMargin);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001295
1296 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1297 MlmeFreeMemory(pAd, pOutBuffer);
1298
1299 return;
1300}
1301
1302/*
1303 ==========================================================================
1304 Description:
1305 Prepare Channel Switch Announcement action frame and enqueue it into
1306 management queue waiting for transmition.
1307
1308 Parametrs:
1309 1. the destination mac address of the frame.
1310 2. Channel switch announcement mode.
1311 2. a New selected channel.
1312
1313 Return : None.
1314 ==========================================================================
1315 */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001316void EnqueueChSwAnn(struct rt_rtmp_adapter *pAd,
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001317 u8 *pDA, u8 ChSwMode, u8 NewCh)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001318{
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001319 u8 *pOutBuffer = NULL;
1320 int NStatus;
1321 unsigned long FrameLen;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001322
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001323 struct rt_header_802_11 ActHdr;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001324
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001325 /* build action frame header. */
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001326 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001327 pAd->CurrentAddress);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001328
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001329 NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer); /*Get an unused nonpaged memory */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001330 if (NStatus != NDIS_STATUS_SUCCESS) {
1331 DBGPRINT(RT_DEBUG_TRACE,
1332 ("%s() allocate memory failed \n", __func__));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001333 return;
1334 }
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001335 NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11));
1336 FrameLen = sizeof(struct rt_header_802_11);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001337
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001338 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen,
1339 CATEGORY_SPECTRUM, SPEC_CHANNEL_SWITCH);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001340
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001341 InsertChSwAnnIE(pAd, (pOutBuffer + FrameLen), &FrameLen, ChSwMode,
1342 NewCh, 0);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001343
1344 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1345 MlmeFreeMemory(pAd, pOutBuffer);
1346
1347 return;
1348}
1349
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001350static BOOLEAN DfsRequirementCheck(struct rt_rtmp_adapter *pAd, u8 Channel)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001351{
1352 BOOLEAN Result = FALSE;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001353 int i;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001354
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001355 do {
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001356 /* check DFS procedure is running. */
1357 /* make sure DFS procedure won't start twice. */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001358 if (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE) {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001359 Result = FALSE;
1360 break;
1361 }
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001362 /* check the new channel carried from Channel Switch Announcemnet is valid. */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001363 for (i = 0; i < pAd->ChannelListNum; i++) {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001364 if ((Channel == pAd->ChannelList[i].Channel)
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001365 && (pAd->ChannelList[i].RemainingTimeForUse == 0)) {
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001366 /* found radar signal in the channel. the channel can't use at least for 30 minutes. */
1367 pAd->ChannelList[i].RemainingTimeForUse = 1800; /*30 min = 1800 sec */
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001368 Result = TRUE;
1369 break;
1370 }
1371 }
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001372 } while (FALSE);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001373
1374 return Result;
1375}
1376
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001377void NotifyChSwAnnToPeerAPs(struct rt_rtmp_adapter *pAd,
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001378 u8 *pRA,
1379 u8 *pTA, u8 ChSwMode, u8 Channel)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001380{
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001381}
1382
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001383static void StartDFSProcedure(struct rt_rtmp_adapter *pAd,
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001384 u8 Channel, u8 ChSwMode)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001385{
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001386 /* start DFS procedure */
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001387 pAd->CommonCfg.Channel = Channel;
Bartlomiej Zolnierkiewicz16232672009-04-26 16:06:00 +02001388
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001389 N_ChannelCheck(pAd);
Bartlomiej Zolnierkiewicz16232672009-04-26 16:06:00 +02001390
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001391 pAd->CommonCfg.RadarDetect.RDMode = RD_SWITCHING_MODE;
1392 pAd->CommonCfg.RadarDetect.CSCount = 0;
1393}
1394
1395/*
1396 ==========================================================================
1397 Description:
1398 Channel Switch Announcement action frame sanity check.
1399
1400 Parametrs:
1401 1. MLME message containing the received frame
1402 2. message length.
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001403 3. Channel switch announcement information buffer.
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001404
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001405 Return : None.
1406 ==========================================================================
1407 */
1408
1409/*
1410 Channel Switch Announcement IE.
1411 +----+-----+-----------+------------+-----------+
1412 | ID | Len |Ch Sw Mode | New Ch Num | Ch Sw Cnt |
1413 +----+-----+-----------+------------+-----------+
1414 1 1 1 1 1
1415*/
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001416static BOOLEAN PeerChSwAnnSanity(struct rt_rtmp_adapter *pAd,
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001417 void * pMsg,
1418 unsigned long MsgLen,
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001419 struct rt_ch_sw_ann_info * pChSwAnnInfo)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001420{
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001421 struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001422 u8 *pFramePtr = Fr->Octet;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001423 BOOLEAN result = FALSE;
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001424 struct rt_eid * eid_ptr;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001425
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001426 /* skip 802.11 header. */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001427 MsgLen -= sizeof(struct rt_header_802_11);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001428
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001429 /* skip category and action code. */
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001430 pFramePtr += 2;
1431 MsgLen -= 2;
1432
1433 if (pChSwAnnInfo == NULL)
1434 return result;
1435
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001436 eid_ptr = (struct rt_eid *) pFramePtr;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001437 while (((u8 *) eid_ptr + eid_ptr->Len + 1) <
1438 ((u8 *)pFramePtr + MsgLen)) {
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001439 switch (eid_ptr->Eid) {
1440 case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
1441 NdisMoveMemory(&pChSwAnnInfo->ChSwMode, eid_ptr->Octet,
1442 1);
1443 NdisMoveMemory(&pChSwAnnInfo->Channel,
1444 eid_ptr->Octet + 1, 1);
1445 NdisMoveMemory(&pChSwAnnInfo->ChSwCnt,
1446 eid_ptr->Octet + 2, 1);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001447
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001448 result = TRUE;
1449 break;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001450
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001451 default:
1452 break;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001453 }
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001454 eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001455 }
1456
1457 return result;
1458}
1459
1460/*
1461 ==========================================================================
1462 Description:
1463 Measurement request action frame sanity check.
1464
1465 Parametrs:
1466 1. MLME message containing the received frame
1467 2. message length.
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001468 3. Measurement request information buffer.
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001469
1470 Return : None.
1471 ==========================================================================
1472 */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001473static BOOLEAN PeerMeasureReqSanity(struct rt_rtmp_adapter *pAd,
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001474 void * pMsg,
1475 unsigned long MsgLen,
1476 u8 *pDialogToken,
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001477 struct rt_measure_req_info * pMeasureReqInfo,
1478 struct rt_measure_req * pMeasureReq)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001479{
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001480 struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001481 u8 *pFramePtr = Fr->Octet;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001482 BOOLEAN result = FALSE;
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001483 struct rt_eid * eid_ptr;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001484 u8 *ptr;
1485 u64 MeasureStartTime;
1486 u16 MeasureDuration;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001487
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001488 /* skip 802.11 header. */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001489 MsgLen -= sizeof(struct rt_header_802_11);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001490
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001491 /* skip category and action code. */
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001492 pFramePtr += 2;
1493 MsgLen -= 2;
1494
1495 if (pMeasureReqInfo == NULL)
1496 return result;
1497
1498 NdisMoveMemory(pDialogToken, pFramePtr, 1);
1499 pFramePtr += 1;
1500 MsgLen -= 1;
1501
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001502 eid_ptr = (struct rt_eid *) pFramePtr;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001503 while (((u8 *) eid_ptr + eid_ptr->Len + 1) <
1504 ((u8 *)pFramePtr + MsgLen)) {
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001505 switch (eid_ptr->Eid) {
1506 case IE_MEASUREMENT_REQUEST:
1507 NdisMoveMemory(&pMeasureReqInfo->Token, eid_ptr->Octet,
1508 1);
1509 NdisMoveMemory(&pMeasureReqInfo->ReqMode.word,
1510 eid_ptr->Octet + 1, 1);
1511 NdisMoveMemory(&pMeasureReqInfo->ReqType,
1512 eid_ptr->Octet + 2, 1);
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001513 ptr = (u8 *)(eid_ptr->Octet + 3);
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001514 NdisMoveMemory(&pMeasureReq->ChNum, ptr, 1);
1515 NdisMoveMemory(&MeasureStartTime, ptr + 1, 8);
1516 pMeasureReq->MeasureStartTime =
1517 SWAP64(MeasureStartTime);
1518 NdisMoveMemory(&MeasureDuration, ptr + 9, 2);
1519 pMeasureReq->MeasureDuration = SWAP16(MeasureDuration);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001520
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001521 result = TRUE;
1522 break;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001523
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001524 default:
1525 break;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001526 }
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001527 eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001528 }
1529
1530 return result;
1531}
1532
1533/*
1534 ==========================================================================
1535 Description:
1536 Measurement report action frame sanity check.
1537
1538 Parametrs:
1539 1. MLME message containing the received frame
1540 2. message length.
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001541 3. Measurement report information buffer.
1542 4. basic report information buffer.
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001543
1544 Return : None.
1545 ==========================================================================
1546 */
1547
1548/*
1549 Measurement Report IE.
1550 +----+-----+-------+-------------+--------------+----------------+
1551 | ID | Len | Token | Report Mode | Measure Type | Measure Report |
1552 +----+-----+-------+-------------+--------------+----------------+
1553 1 1 1 1 1 variable
1554
1555 Basic Report.
1556 +--------+------------+----------+-----+
1557 | Ch Num | Start Time | Duration | Map |
1558 +--------+------------+----------+-----+
1559 1 8 2 1
1560
1561 Map Field Bit Format.
1562 +-----+---------------+---------------------+-------+------------+----------+
1563 | Bss | OFDM Preamble | Unidentified signal | Radar | Unmeasured | Reserved |
1564 +-----+---------------+---------------------+-------+------------+----------+
1565 0 1 2 3 4 5-7
1566*/
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001567static BOOLEAN PeerMeasureReportSanity(struct rt_rtmp_adapter *pAd,
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001568 void * pMsg,
1569 unsigned long MsgLen,
1570 u8 *pDialogToken,
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001571 struct rt_measure_report_info *
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001572 pMeasureReportInfo,
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001573 u8 *pReportBuf)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001574{
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001575 struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001576 u8 *pFramePtr = Fr->Octet;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001577 BOOLEAN result = FALSE;
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001578 struct rt_eid * eid_ptr;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001579 u8 *ptr;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001580
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001581 /* skip 802.11 header. */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001582 MsgLen -= sizeof(struct rt_header_802_11);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001583
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001584 /* skip category and action code. */
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001585 pFramePtr += 2;
1586 MsgLen -= 2;
1587
1588 if (pMeasureReportInfo == NULL)
1589 return result;
1590
1591 NdisMoveMemory(pDialogToken, pFramePtr, 1);
1592 pFramePtr += 1;
1593 MsgLen -= 1;
1594
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001595 eid_ptr = (struct rt_eid *) pFramePtr;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001596 while (((u8 *) eid_ptr + eid_ptr->Len + 1) <
1597 ((u8 *)pFramePtr + MsgLen)) {
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001598 switch (eid_ptr->Eid) {
1599 case IE_MEASUREMENT_REPORT:
1600 NdisMoveMemory(&pMeasureReportInfo->Token,
1601 eid_ptr->Octet, 1);
1602 NdisMoveMemory(&pMeasureReportInfo->ReportMode,
1603 eid_ptr->Octet + 1, 1);
1604 NdisMoveMemory(&pMeasureReportInfo->ReportType,
1605 eid_ptr->Octet + 2, 1);
1606 if (pMeasureReportInfo->ReportType == RM_BASIC) {
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001607 struct rt_measure_basic_report * pReport =
1608 (struct rt_measure_basic_report *) pReportBuf;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001609 ptr = (u8 *)(eid_ptr->Octet + 3);
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001610 NdisMoveMemory(&pReport->ChNum, ptr, 1);
1611 NdisMoveMemory(&pReport->MeasureStartTime,
1612 ptr + 1, 8);
1613 NdisMoveMemory(&pReport->MeasureDuration,
1614 ptr + 9, 2);
1615 NdisMoveMemory(&pReport->Map, ptr + 11, 1);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001616
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001617 } else if (pMeasureReportInfo->ReportType == RM_CCA) {
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001618 struct rt_measure_cca_report * pReport =
1619 (struct rt_measure_cca_report *) pReportBuf;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001620 ptr = (u8 *)(eid_ptr->Octet + 3);
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001621 NdisMoveMemory(&pReport->ChNum, ptr, 1);
1622 NdisMoveMemory(&pReport->MeasureStartTime,
1623 ptr + 1, 8);
1624 NdisMoveMemory(&pReport->MeasureDuration,
1625 ptr + 9, 2);
1626 NdisMoveMemory(&pReport->CCA_Busy_Fraction,
1627 ptr + 11, 1);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001628
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001629 } else if (pMeasureReportInfo->ReportType ==
1630 RM_RPI_HISTOGRAM) {
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001631 struct rt_measure_rpi_report * pReport =
1632 (struct rt_measure_rpi_report *) pReportBuf;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001633 ptr = (u8 *)(eid_ptr->Octet + 3);
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001634 NdisMoveMemory(&pReport->ChNum, ptr, 1);
1635 NdisMoveMemory(&pReport->MeasureStartTime,
1636 ptr + 1, 8);
1637 NdisMoveMemory(&pReport->MeasureDuration,
1638 ptr + 9, 2);
1639 NdisMoveMemory(&pReport->RPI_Density, ptr + 11,
1640 8);
1641 }
1642 result = TRUE;
1643 break;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001644
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001645 default:
1646 break;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001647 }
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001648 eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001649 }
1650
1651 return result;
1652}
1653
1654/*
1655 ==========================================================================
1656 Description:
1657 TPC Request action frame sanity check.
1658
1659 Parametrs:
1660 1. MLME message containing the received frame
1661 2. message length.
1662 3. Dialog Token.
1663
1664 Return : None.
1665 ==========================================================================
1666 */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001667static BOOLEAN PeerTpcReqSanity(struct rt_rtmp_adapter *pAd,
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001668 void * pMsg,
1669 unsigned long MsgLen, u8 *pDialogToken)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001670{
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001671 struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001672 u8 *pFramePtr = Fr->Octet;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001673 BOOLEAN result = FALSE;
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001674 struct rt_eid * eid_ptr;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001675
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001676 MsgLen -= sizeof(struct rt_header_802_11);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001677
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001678 /* skip category and action code. */
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001679 pFramePtr += 2;
1680 MsgLen -= 2;
1681
1682 if (pDialogToken == NULL)
1683 return result;
1684
1685 NdisMoveMemory(pDialogToken, pFramePtr, 1);
1686 pFramePtr += 1;
1687 MsgLen -= 1;
1688
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001689 eid_ptr = (struct rt_eid *) pFramePtr;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001690 while (((u8 *) eid_ptr + eid_ptr->Len + 1) <
1691 ((u8 *)pFramePtr + MsgLen)) {
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001692 switch (eid_ptr->Eid) {
1693 case IE_TPC_REQUEST:
1694 result = TRUE;
1695 break;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001696
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001697 default:
1698 break;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001699 }
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001700 eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001701 }
1702
1703 return result;
1704}
1705
1706/*
1707 ==========================================================================
1708 Description:
1709 TPC Report action frame sanity check.
1710
1711 Parametrs:
1712 1. MLME message containing the received frame
1713 2. message length.
1714 3. Dialog Token.
1715 4. TPC Report IE.
1716
1717 Return : None.
1718 ==========================================================================
1719 */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001720static BOOLEAN PeerTpcRepSanity(struct rt_rtmp_adapter *pAd,
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001721 void * pMsg,
1722 unsigned long MsgLen,
1723 u8 *pDialogToken,
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001724 struct rt_tpc_report_info * pTpcRepInfo)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001725{
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001726 struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001727 u8 *pFramePtr = Fr->Octet;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001728 BOOLEAN result = FALSE;
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001729 struct rt_eid * eid_ptr;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001730
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001731 MsgLen -= sizeof(struct rt_header_802_11);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001732
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001733 /* skip category and action code. */
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001734 pFramePtr += 2;
1735 MsgLen -= 2;
1736
1737 if (pDialogToken == NULL)
1738 return result;
1739
1740 NdisMoveMemory(pDialogToken, pFramePtr, 1);
1741 pFramePtr += 1;
1742 MsgLen -= 1;
1743
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001744 eid_ptr = (struct rt_eid *) pFramePtr;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001745 while (((u8 *) eid_ptr + eid_ptr->Len + 1) <
1746 ((u8 *)pFramePtr + MsgLen)) {
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001747 switch (eid_ptr->Eid) {
1748 case IE_TPC_REPORT:
1749 NdisMoveMemory(&pTpcRepInfo->TxPwr, eid_ptr->Octet, 1);
1750 NdisMoveMemory(&pTpcRepInfo->LinkMargin,
1751 eid_ptr->Octet + 1, 1);
1752 result = TRUE;
1753 break;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001754
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001755 default:
1756 break;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001757 }
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001758 eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001759 }
1760
1761 return result;
1762}
1763
1764/*
1765 ==========================================================================
1766 Description:
1767 Channel Switch Announcement action frame handler.
1768
1769 Parametrs:
1770 Elme - MLME message containing the received frame
1771
1772 Return : None.
1773 ==========================================================================
1774 */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001775static void PeerChSwAnnAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001776{
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001777 struct rt_ch_sw_ann_info ChSwAnnInfo;
1778 struct rt_frame_802_11 * pFr = (struct rt_frame_802_11 *) Elem->Msg;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001779 u8 index = 0, Channel = 0, NewChannel = 0;
1780 unsigned long Bssidx = 0;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001781
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001782 NdisZeroMemory(&ChSwAnnInfo, sizeof(struct rt_ch_sw_ann_info));
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001783 if (!PeerChSwAnnSanity(pAd, Elem->Msg, Elem->MsgLen, &ChSwAnnInfo)) {
1784 DBGPRINT(RT_DEBUG_TRACE,
1785 ("Invalid Channel Switch Action Frame.\n"));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001786 return;
1787 }
1788
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001789 if (pAd->OpMode == OPMODE_STA) {
1790 Bssidx =
1791 BssTableSearch(&pAd->ScanTab, pFr->Hdr.Addr3,
1792 pAd->CommonCfg.Channel);
1793 if (Bssidx == BSS_NOT_FOUND) {
1794 DBGPRINT(RT_DEBUG_TRACE,
1795 ("PeerChSwAnnAction - Bssidx is not found\n"));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001796 return;
1797 }
1798
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001799 DBGPRINT(RT_DEBUG_TRACE,
1800 ("\n****Bssidx is %d, Channel = %d\n", index,
1801 pAd->ScanTab.BssEntry[Bssidx].Channel));
1802 hex_dump("SSID", pAd->ScanTab.BssEntry[Bssidx].Bssid, 6);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001803
1804 Channel = pAd->CommonCfg.Channel;
1805 NewChannel = ChSwAnnInfo.Channel;
1806
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001807 if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0)
1808 && (Channel != NewChannel)) {
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001809 /* Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection). */
1810 /* In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results. */
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001811 AsicSwitchChannel(pAd, 1, FALSE);
1812 AsicLockChannel(pAd, 1);
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001813 LinkDown(pAd, FALSE);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001814 MlmeQueueInit(&pAd->Mlme.Queue);
1815 BssTableInit(&pAd->ScanTab);
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001816 RTMPusecDelay(1000000); /* use delay to prevent STA do reassoc */
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001817
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001818 /* channel sanity check */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001819 for (index = 0; index < pAd->ChannelListNum; index++) {
1820 if (pAd->ChannelList[index].Channel ==
1821 NewChannel) {
1822 pAd->ScanTab.BssEntry[Bssidx].Channel =
1823 NewChannel;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001824 pAd->CommonCfg.Channel = NewChannel;
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001825 AsicSwitchChannel(pAd,
1826 pAd->CommonCfg.
1827 Channel, FALSE);
1828 AsicLockChannel(pAd,
1829 pAd->CommonCfg.Channel);
1830 DBGPRINT(RT_DEBUG_TRACE,
1831 ("&&&&&&&&&&&&&&&&PeerChSwAnnAction - STA receive channel switch announcement IE (New Channel =%d)\n",
1832 NewChannel));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001833 break;
1834 }
1835 }
1836
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001837 if (index >= pAd->ChannelListNum) {
L. Alberto Giménez8c3d9092010-12-14 02:01:55 +01001838 DBGPRINT_ERR("&&&&&&&&&&&&&&&&&&&&&&&&&&PeerChSwAnnAction(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001839 }
1840 }
1841 }
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001842
1843 return;
1844}
1845
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001846/*
1847 ==========================================================================
1848 Description:
1849 Measurement Request action frame handler.
1850
1851 Parametrs:
1852 Elme - MLME message containing the received frame
1853
1854 Return : None.
1855 ==========================================================================
1856 */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001857static void PeerMeasureReqAction(struct rt_rtmp_adapter *pAd,
1858 struct rt_mlme_queue_elem *Elem)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001859{
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001860 struct rt_frame_802_11 * pFr = (struct rt_frame_802_11 *) Elem->Msg;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001861 u8 DialogToken;
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001862 struct rt_measure_req_info MeasureReqInfo;
1863 struct rt_measure_req MeasureReq;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001864 MEASURE_REPORT_MODE ReportMode;
1865
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001866 if (PeerMeasureReqSanity
1867 (pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReqInfo,
1868 &MeasureReq)) {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001869 ReportMode.word = 0;
1870 ReportMode.field.Incapable = 1;
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001871 EnqueueMeasurementRep(pAd, pFr->Hdr.Addr2, DialogToken,
1872 MeasureReqInfo.Token, ReportMode.word,
1873 MeasureReqInfo.ReqType, 0, NULL);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001874 }
1875
1876 return;
1877}
1878
1879/*
1880 ==========================================================================
1881 Description:
1882 Measurement Report action frame handler.
1883
1884 Parametrs:
1885 Elme - MLME message containing the received frame
1886
1887 Return : None.
1888 ==========================================================================
1889 */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001890static void PeerMeasureReportAction(struct rt_rtmp_adapter *pAd,
1891 struct rt_mlme_queue_elem *Elem)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001892{
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001893 struct rt_measure_report_info MeasureReportInfo;
1894 struct rt_frame_802_11 * pFr = (struct rt_frame_802_11 *) Elem->Msg;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001895 u8 DialogToken;
1896 u8 *pMeasureReportInfo;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001897
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001898/* if (pAd->CommonCfg.bIEEE80211H != TRUE) */
1899/* return; */
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001900
Joe Perches6aed5292010-03-24 22:16:59 -07001901 pMeasureReportInfo = kmalloc(sizeof(struct rt_measure_rpi_report), GFP_ATOMIC);
1902 if (pMeasureReportInfo == NULL) {
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001903 DBGPRINT(RT_DEBUG_ERROR,
1904 ("%s unable to alloc memory for measure report buffer (size=%zu).\n",
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001905 __func__, sizeof(struct rt_measure_rpi_report)));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001906 return;
1907 }
1908
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001909 NdisZeroMemory(&MeasureReportInfo, sizeof(struct rt_measure_report_info));
1910 NdisZeroMemory(pMeasureReportInfo, sizeof(struct rt_measure_rpi_report));
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001911 if (PeerMeasureReportSanity
1912 (pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReportInfo,
1913 pMeasureReportInfo)) {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001914 do {
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001915 struct rt_measure_req_entry *pEntry = NULL;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001916
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001917 /* Not a autonomous measure report. */
1918 /* check the dialog token field. drop it if the dialog token doesn't match. */
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001919 if ((DialogToken != 0)
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001920 && ((pEntry = MeasureReqLookUp(pAd, DialogToken)) ==
1921 NULL))
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001922 break;
1923
1924 if (pEntry != NULL)
1925 MeasureReqDelete(pAd, pEntry->DialogToken);
1926
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001927 if (MeasureReportInfo.ReportType == RM_BASIC) {
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001928 struct rt_measure_basic_report * pBasicReport =
1929 (struct rt_measure_basic_report *) pMeasureReportInfo;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001930 if ((pBasicReport->Map.field.Radar)
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001931 &&
1932 (DfsRequirementCheck
1933 (pAd, pBasicReport->ChNum) == TRUE)) {
1934 NotifyChSwAnnToPeerAPs(pAd,
1935 pFr->Hdr.Addr1,
1936 pFr->Hdr.Addr2,
1937 1,
1938 pBasicReport->
1939 ChNum);
1940 StartDFSProcedure(pAd,
1941 pBasicReport->ChNum,
1942 1);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001943 }
1944 }
1945 } while (FALSE);
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001946 } else
1947 DBGPRINT(RT_DEBUG_TRACE,
1948 ("Invalid Measurement Report Frame.\n"));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001949
1950 kfree(pMeasureReportInfo);
1951
1952 return;
1953}
1954
1955/*
1956 ==========================================================================
1957 Description:
1958 TPC Request action frame handler.
1959
1960 Parametrs:
1961 Elme - MLME message containing the received frame
1962
1963 Return : None.
1964 ==========================================================================
1965 */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001966static void PeerTpcReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001967{
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08001968 struct rt_frame_802_11 * pFr = (struct rt_frame_802_11 *) Elem->Msg;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08001969 u8 *pFramePtr = pFr->Octet;
1970 u8 DialogToken;
1971 u8 TxPwr = GetCurTxPwr(pAd, Elem->Wcid);
1972 u8 LinkMargin = 0;
1973 char RealRssi;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001974
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001975 /* link margin: Ratio of the received signal power to the minimum desired by the station (STA). The */
1976 /* STA may incorporate rate information and channel conditions, including interference, into its computation */
1977 /* of link margin. */
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001978
1979 RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0),
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001980 ConvertToRssi(pAd, Elem->Rssi1, RSSI_1),
1981 ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001982
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001983 /* skip Category and action code. */
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001984 pFramePtr += 2;
1985
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08001986 /* Dialog token. */
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001987 NdisMoveMemory(&DialogToken, pFramePtr, 1);
1988
1989 LinkMargin = (RealRssi / MIN_RCV_PWR);
1990 if (PeerTpcReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken))
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08001991 EnqueueTPCRep(pAd, pFr->Hdr.Addr2, DialogToken, TxPwr,
1992 LinkMargin);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001993
1994 return;
1995}
1996
1997/*
1998 ==========================================================================
1999 Description:
2000 TPC Report action frame handler.
2001
2002 Parametrs:
2003 Elme - MLME message containing the received frame
2004
2005 Return : None.
2006 ==========================================================================
2007 */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08002008static void PeerTpcRepAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07002009{
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08002010 u8 DialogToken;
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08002011 struct rt_tpc_report_info TpcRepInfo;
2012 struct rt_tpc_req_entry *pEntry = NULL;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07002013
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08002014 NdisZeroMemory(&TpcRepInfo, sizeof(struct rt_tpc_report_info));
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08002015 if (PeerTpcRepSanity
2016 (pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &TpcRepInfo)) {
Joe Perches6aed5292010-03-24 22:16:59 -07002017 pEntry = TpcReqLookUp(pAd, DialogToken);
2018 if (pEntry != NULL) {
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07002019 TpcReqDelete(pAd, pEntry->DialogToken);
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08002020 DBGPRINT(RT_DEBUG_TRACE,
2021 ("%s: DialogToken=%x, TxPwr=%d, LinkMargin=%d\n",
2022 __func__, DialogToken, TpcRepInfo.TxPwr,
2023 TpcRepInfo.LinkMargin));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07002024 }
2025 }
2026
2027 return;
2028}
2029
2030/*
2031 ==========================================================================
2032 Description:
2033 Spectrun action frames Handler such as channel switch annoucement,
2034 measurement report, measurement request actions frames.
2035
2036 Parametrs:
2037 Elme - MLME message containing the received frame
2038
2039 Return : None.
2040 ==========================================================================
2041 */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08002042void PeerSpectrumAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07002043{
2044
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08002045 u8 Action = Elem->Msg[LENGTH_802_11 + 1];
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07002046
2047 if (pAd->CommonCfg.bIEEE80211H != TRUE)
2048 return;
2049
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08002050 switch (Action) {
2051 case SPEC_MRQ:
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08002052 /* current rt2860 unable do such measure specified in Measurement Request. */
2053 /* reject all measurement request. */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08002054 PeerMeasureReqAction(pAd, Elem);
2055 break;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07002056
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08002057 case SPEC_MRP:
2058 PeerMeasureReportAction(pAd, Elem);
2059 break;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07002060
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08002061 case SPEC_TPCRQ:
2062 PeerTpcReqAction(pAd, Elem);
2063 break;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07002064
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08002065 case SPEC_TPCRP:
2066 PeerTpcRepAction(pAd, Elem);
2067 break;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07002068
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08002069 case SPEC_CHANNEL_SWITCH:
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +02002070
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08002071 PeerChSwAnnAction(pAd, Elem);
2072 break;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07002073 }
2074
2075 return;
2076}
2077
2078/*
2079 ==========================================================================
2080 Description:
2081
2082 Parametrs:
2083
2084 Return : None.
2085 ==========================================================================
2086 */
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08002087int Set_MeasureReq_Proc(struct rt_rtmp_adapter *pAd, char *arg)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07002088{
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08002089 u32 Aid = 1;
2090 u32 ArgIdx;
2091 char *thisChar;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07002092
2093 MEASURE_REQ_MODE MeasureReqMode;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08002094 u8 MeasureReqToken = RandomByte(pAd);
2095 u8 MeasureReqType = RM_BASIC;
2096 u8 MeasureCh = 1;
2097 u64 MeasureStartTime = GetCurrentTimeStamp(pAd);
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08002098 struct rt_measure_req MeasureReq;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08002099 u8 TotalLen;
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +02002100
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08002101 struct rt_header_802_11 ActHdr;
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08002102 u8 *pOutBuffer = NULL;
2103 int NStatus;
2104 unsigned long FrameLen;
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +02002105
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08002106 NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer); /*Get an unused nonpaged memory */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08002107 if (NStatus != NDIS_STATUS_SUCCESS) {
2108 DBGPRINT(RT_DEBUG_TRACE,
2109 ("%s() allocate memory failed \n", __func__));
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +02002110 goto END_OF_MEASURE_REQ;
2111 }
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07002112
2113 ArgIdx = 1;
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08002114 while ((thisChar = strsep((char **)&arg, "-")) != NULL) {
2115 switch (ArgIdx) {
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08002116 case 1: /* Aid. */
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08002117 Aid = (u8)simple_strtol(thisChar, 0, 16);
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08002118 break;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07002119
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08002120 case 2: /* Measurement Request Type. */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08002121 MeasureReqType = simple_strtol(thisChar, 0, 16);
2122 if (MeasureReqType > 3) {
2123 DBGPRINT(RT_DEBUG_ERROR,
2124 ("%s: unknow MeasureReqType(%d)\n",
2125 __func__, MeasureReqType));
2126 goto END_OF_MEASURE_REQ;
2127 }
2128 break;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07002129
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08002130 case 3: /* Measurement channel. */
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08002131 MeasureCh = (u8)simple_strtol(thisChar, 0, 16);
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08002132 break;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07002133 }
2134 ArgIdx++;
2135 }
2136
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08002137 DBGPRINT(RT_DEBUG_TRACE,
2138 ("%s::Aid = %d, MeasureReqType=%d MeasureCh=%d\n", __func__,
2139 Aid, MeasureReqType, MeasureCh));
2140 if (!VALID_WCID(Aid)) {
2141 DBGPRINT(RT_DEBUG_ERROR,
2142 ("%s: unknow sta of Aid(%d)\n", __func__, Aid));
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +02002143 goto END_OF_MEASURE_REQ;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07002144 }
2145
2146 MeasureReqMode.word = 0;
2147 MeasureReqMode.field.Enable = 1;
2148
2149 MeasureReqInsert(pAd, MeasureReqToken);
2150
Bartlomiej Zolnierkiewiczec278fa2009-12-11 12:23:15 -08002151 /* build action frame header. */
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08002152 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0,
2153 pAd->MacTab.Content[Aid].Addr, pAd->CurrentAddress);
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +02002154
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08002155 NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11));
2156 FrameLen = sizeof(struct rt_header_802_11);
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +02002157
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08002158 TotalLen = sizeof(struct rt_measure_req_info) + sizeof(struct rt_measure_req);
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +02002159
2160 MakeMeasurementReqFrame(pAd, pOutBuffer, &FrameLen,
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08002161 sizeof(struct rt_measure_req_info), CATEGORY_RM, RM_BASIC,
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08002162 MeasureReqToken, MeasureReqMode.word,
2163 MeasureReqType, 0);
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +02002164
2165 MeasureReq.ChNum = MeasureCh;
2166 MeasureReq.MeasureStartTime = cpu2le64(MeasureStartTime);
2167 MeasureReq.MeasureDuration = cpu2le16(2000);
2168
2169 {
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08002170 unsigned long TempLen;
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08002171 MakeOutgoingFrame(pOutBuffer + FrameLen, &TempLen,
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08002172 sizeof(struct rt_measure_req), &MeasureReq,
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08002173 END_OF_ARGS);
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +02002174 FrameLen += TempLen;
2175 }
2176
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08002177 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, (u32)FrameLen);
Bartlomiej Zolnierkiewiczca97b832009-09-22 20:44:07 +02002178
2179END_OF_MEASURE_REQ:
2180 MlmeFreeMemory(pAd, pOutBuffer);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07002181
2182 return TRUE;
2183}
2184
Bartlomiej Zolnierkiewicz62eb7342009-12-11 12:23:16 -08002185int Set_TpcReq_Proc(struct rt_rtmp_adapter *pAd, char *arg)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07002186{
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08002187 u32 Aid;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07002188
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08002189 u8 TpcReqToken = RandomByte(pAd);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07002190
Bartlomiej Zolnierkiewicz51126de2009-12-11 12:23:15 -08002191 Aid = (u32)simple_strtol(arg, 0, 16);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07002192
Harvey Harrisond599edc2009-01-07 14:31:57 -08002193 DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d\n", __func__, Aid));
Bartlomiej Zolnierkiewicz96b3c83d2009-12-11 12:23:13 -08002194 if (!VALID_WCID(Aid)) {
2195 DBGPRINT(RT_DEBUG_ERROR,
2196 ("%s: unknow sta of Aid(%d)\n", __func__, Aid));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07002197 return TRUE;
2198 }
2199
2200 TpcReqInsert(pAd, TpcReqToken);
2201
2202 EnqueueTPCReq(pAd, pAd->MacTab.Content[Aid].Addr, TpcReqToken);
2203
2204 return TRUE;
2205}