]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - drivers/staging/rt2860/common/spectrum.c
Fix common misspellings
[mirror_ubuntu-zesty-kernel.git] / drivers / staging / rt2860 / common / spectrum.c
CommitLineData
91980990
GKH
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
91980990
GKH
27 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
ca97b838 42/* The regulatory information in the USA (US) */
62eb734b 43struct rt_dot11_regulatory_information USARegulatoryInfo[] = {
ca97b838 44/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */
96b3c83d
BZ
45 {0, {0, 0, {0}
46 }
47 }
ec278fa2 48 , /* Invlid entry */
96b3c83d
BZ
49 {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 }
ca97b838 96};
ca97b838 97
62eb734b 98#define USA_REGULATORY_INFO_SIZE (sizeof(USARegulatoryInfo) / sizeof(struct rt_dot11_regulatory_information))
ca97b838
BZ
99
100/* The regulatory information in Europe */
62eb734b 101struct rt_dot11_regulatory_information EuropeRegulatoryInfo[] = {
ca97b838 102/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */
96b3c83d
BZ
103 {0, {0, 0, {0}
104 }
105 }
ec278fa2 106 , /* Invalid entry */
96b3c83d
BZ
107 {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 }
ca97b838 122};
ca97b838 123
62eb734b 124#define EU_REGULATORY_INFO_SIZE (sizeof(EuropeRegulatoryInfo) / sizeof(struct rt_dot11_regulatory_information))
ca97b838
BZ
125
126/* The regulatory information in Japan */
62eb734b 127struct rt_dot11_regulatory_information JapanRegulatoryInfo[] = {
ca97b838 128/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */
96b3c83d
BZ
129 {0, {0, 0, {0}
130 }
131 }
ec278fa2 132 , /* Invalid entry */
96b3c83d
BZ
133 {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 }
ca97b838 260};
ca97b838 261
62eb734b 262#define JP_REGULATORY_INFO_SIZE (sizeof(JapanRegulatoryInfo) / sizeof(struct rt_dot11_regulatory_information))
ca97b838 263
62eb734b 264char RTMP_GetTxPwr(struct rt_rtmp_adapter *pAd, IN HTTRANSMIT_SETTING HTTxMode)
ca97b838 265{
62eb734b 266 struct tx_pwr_cfg {
51126deb
BZ
267 u8 Mode;
268 u8 MCS;
269 u16 req;
270 u8 shift;
271 u32 BitMask;
62eb734b 272 };
ca97b838 273
51126deb
BZ
274 u32 Value;
275 int Idx;
276 u8 PhyMode;
277 char CurTxPwr;
278 u8 TxPwrRef = 0;
279 char DaltaPwr;
280 unsigned long TxPwr[5];
ca97b838 281
62eb734b 282 struct tx_pwr_cfg TxPwrCfg[] = {
ca97b838
BZ
283 {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}
96b3c83d 296 , {MODE_HTMIX, 0, 1, 20, 0x00f00000},
ca97b838
BZ
297 {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 };
62eb734b 313#define MAX_TXPWR_TAB_SIZE (sizeof(TxPwrCfg) / sizeof(struct tx_pwr_cfg))
ca97b838
BZ
314
315 CurTxPwr = 19;
316
317 /* check Tx Power setting from UI. */
96b3c83d
BZ
318 if (pAd->CommonCfg.TxPowerPercentage > 90) ;
319 else if (pAd->CommonCfg.TxPowerPercentage > 60) /* reduce Pwr for 1 dB. */
ca97b838 320 CurTxPwr -= 1;
96b3c83d 321 else if (pAd->CommonCfg.TxPowerPercentage > 30) /* reduce Pwr for 3 dB. */
ca97b838 322 CurTxPwr -= 3;
96b3c83d 323 else if (pAd->CommonCfg.TxPowerPercentage > 15) /* reduce Pwr for 6 dB. */
ca97b838 324 CurTxPwr -= 6;
96b3c83d 325 else if (pAd->CommonCfg.TxPowerPercentage > 9) /* reduce Pwr for 9 dB. */
ca97b838 326 CurTxPwr -= 9;
96b3c83d 327 else /* reduce Pwr for 12 dB. */
ca97b838
BZ
328 CurTxPwr -= 12;
329
96b3c83d
BZ
330 if (pAd->CommonCfg.BBPCurrentBW == BW_40) {
331 if (pAd->CommonCfg.CentralChannel > 14) {
ca97b838
BZ
332 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];
96b3c83d 337 } else {
ca97b838
BZ
338 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 }
96b3c83d
BZ
344 } else {
345 if (pAd->CommonCfg.Channel > 14) {
ca97b838
BZ
346 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];
96b3c83d 351 } else {
ca97b838
BZ
352 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
96b3c83d
BZ
360 switch (HTTxMode.field.MODE) {
361 case MODE_CCK:
362 case MODE_OFDM:
363 Value = TxPwr[1];
364 TxPwrRef = (Value & 0x00000f00) >> 8;
ca97b838 365
96b3c83d 366 break;
ca97b838 367
96b3c83d
BZ
368 case MODE_HTMIX:
369 case MODE_HTGREENFIELD:
370 if (pAd->CommonCfg.TxStream == 1) {
371 Value = TxPwr[2];
372 TxPwrRef = (Value & 0x00000f00) >> 8;
373 } else if (pAd->CommonCfg.TxStream == 2) {
374 Value = TxPwr[3];
375 TxPwrRef = (Value & 0x00000f00) >> 8;
376 }
377 break;
ca97b838
BZ
378 }
379
96b3c83d
BZ
380 PhyMode = (HTTxMode.field.MODE == MODE_HTGREENFIELD)
381 ? MODE_HTMIX : HTTxMode.field.MODE;
ca97b838 382
96b3c83d 383 for (Idx = 0; Idx < MAX_TXPWR_TAB_SIZE; Idx++) {
ca97b838 384 if ((TxPwrCfg[Idx].Mode == PhyMode)
96b3c83d 385 && (TxPwrCfg[Idx].MCS == HTTxMode.field.MCS)) {
ca97b838 386 Value = TxPwr[TxPwrCfg[Idx].req];
96b3c83d 387 DaltaPwr =
51126deb 388 TxPwrRef - (char)((Value & TxPwrCfg[Idx].BitMask)
96b3c83d 389 >> TxPwrCfg[Idx].shift);
ca97b838
BZ
390 CurTxPwr -= DaltaPwr;
391 break;
392 }
393 }
394
395 return CurTxPwr;
396}
397
62eb734b 398void MeasureReqTabInit(struct rt_rtmp_adapter *pAd)
91980990
GKH
399{
400 NdisAllocateSpinLock(&pAd->CommonCfg.MeasureReqTabLock);
401
96b3c83d 402 pAd->CommonCfg.pMeasureReqTab =
62eb734b 403 kmalloc(sizeof(struct rt_measure_req_tab), GFP_ATOMIC);
91980990 404 if (pAd->CommonCfg.pMeasureReqTab)
96b3c83d 405 NdisZeroMemory(pAd->CommonCfg.pMeasureReqTab,
62eb734b 406 sizeof(struct rt_measure_req_tab));
91980990 407 else
96b3c83d
BZ
408 DBGPRINT(RT_DEBUG_ERROR,
409 ("%s Fail to alloc memory for pAd->CommonCfg.pMeasureReqTab.\n",
410 __func__));
91980990
GKH
411
412 return;
413}
414
62eb734b 415void MeasureReqTabExit(struct rt_rtmp_adapter *pAd)
91980990 416{
ca97b838 417 NdisFreeSpinLock(&pAd->CommonCfg.MeasureReqTabLock);
91980990 418
aea9d72f 419 kfree(pAd->CommonCfg.pMeasureReqTab);
91980990
GKH
420 pAd->CommonCfg.pMeasureReqTab = NULL;
421
422 return;
423}
424
62eb734b 425struct rt_measure_req_entry *MeasureReqLookUp(struct rt_rtmp_adapter *pAd, u8 DialogToken)
91980990 426{
51126deb 427 u32 HashIdx;
62eb734b
BZ
428 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;
91980990 431
96b3c83d
BZ
432 if (pTab == NULL) {
433 DBGPRINT(RT_DEBUG_ERROR,
434 ("%s: pMeasureReqTab doesn't exist.\n", __func__));
91980990
GKH
435 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
96b3c83d 443 while (pEntry) {
91980990
GKH
444 if (pEntry->DialogToken == DialogToken)
445 break;
96b3c83d 446 else {
91980990
GKH
447 pPrevEntry = pEntry;
448 pEntry = pEntry->pNext;
449 }
450 }
451
452 RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
453
454 return pEntry;
455}
456
62eb734b 457struct rt_measure_req_entry *MeasureReqInsert(struct rt_rtmp_adapter *pAd, u8 DialogToken)
91980990 458{
51126deb
BZ
459 int i;
460 unsigned long HashIdx;
62eb734b
BZ
461 struct rt_measure_req_tab *pTab = pAd->CommonCfg.pMeasureReqTab;
462 struct rt_measure_req_entry *pEntry = NULL, *pCurrEntry;
51126deb 463 unsigned long Now;
91980990 464
96b3c83d
BZ
465 if (pTab == NULL) {
466 DBGPRINT(RT_DEBUG_ERROR,
467 ("%s: pMeasureReqTab doesn't exist.\n", __func__));
91980990
GKH
468 return NULL;
469 }
470
471 pEntry = MeasureReqLookUp(pAd, DialogToken);
96b3c83d 472 if (pEntry == NULL) {
91980990 473 RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
96b3c83d 474 for (i = 0; i < MAX_MEASURE_REQ_TAB_SIZE; i++) {
91980990
GKH
475 NdisGetSystemUpTime(&Now);
476 pEntry = &pTab->Content[i];
477
478 if ((pEntry->Valid == TRUE)
96b3c83d
BZ
479 && RTMP_TIME_AFTER((unsigned long)Now,
480 (unsigned long)(pEntry->
481 lastTime +
482 MQ_REQ_AGE_OUT)))
91980990 483 {
62eb734b 484 struct rt_measure_req_entry *pPrevEntry = NULL;
51126deb 485 unsigned long HashIdx =
96b3c83d
BZ
486 MQ_DIALOGTOKEN_HASH_INDEX(pEntry->
487 DialogToken);
62eb734b 488 struct rt_measure_req_entry *pProbeEntry =
96b3c83d 489 pTab->Hash[HashIdx];
91980990 490
ec278fa2 491 /* update Hash list */
96b3c83d
BZ
492 do {
493 if (pProbeEntry == pEntry) {
494 if (pPrevEntry == NULL) {
495 pTab->Hash[HashIdx] =
496 pEntry->pNext;
497 } else {
498 pPrevEntry->pNext =
499 pEntry->pNext;
91980990
GKH
500 }
501 break;
502 }
503
504 pPrevEntry = pProbeEntry;
505 pProbeEntry = pProbeEntry->pNext;
506 } while (pProbeEntry);
507
96b3c83d 508 NdisZeroMemory(pEntry,
62eb734b 509 sizeof(struct rt_measure_req_entry));
91980990
GKH
510 pTab->Size--;
511
512 break;
513 }
514
515 if (pEntry->Valid == FALSE)
516 break;
517 }
518
96b3c83d 519 if (i < MAX_MEASURE_REQ_TAB_SIZE) {
91980990
GKH
520 NdisGetSystemUpTime(&Now);
521 pEntry->lastTime = Now;
522 pEntry->Valid = TRUE;
523 pEntry->DialogToken = DialogToken;
524 pTab->Size++;
96b3c83d 525 } else {
91980990 526 pEntry = NULL;
96b3c83d
BZ
527 DBGPRINT(RT_DEBUG_ERROR,
528 ("%s: pMeasureReqTab tab full.\n", __func__));
91980990
GKH
529 }
530
ec278fa2 531 /* add this Neighbor entry into HASH table */
96b3c83d 532 if (pEntry) {
91980990 533 HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken);
96b3c83d 534 if (pTab->Hash[HashIdx] == NULL) {
91980990 535 pTab->Hash[HashIdx] = pEntry;
96b3c83d 536 } else {
91980990
GKH
537 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
62eb734b 550void MeasureReqDelete(struct rt_rtmp_adapter *pAd, u8 DialogToken)
91980990 551{
62eb734b
BZ
552 struct rt_measure_req_tab *pTab = pAd->CommonCfg.pMeasureReqTab;
553 struct rt_measure_req_entry *pEntry = NULL;
91980990 554
96b3c83d
BZ
555 if (pTab == NULL) {
556 DBGPRINT(RT_DEBUG_ERROR,
557 ("%s: pMeasureReqTab doesn't exist.\n", __func__));
91980990
GKH
558 return;
559 }
ec278fa2 560 /* if empty, return */
96b3c83d 561 if (pTab->Size == 0) {
91980990
GKH
562 DBGPRINT(RT_DEBUG_ERROR, ("pMeasureReqTab empty.\n"));
563 return;
564 }
565
566 pEntry = MeasureReqLookUp(pAd, DialogToken);
96b3c83d 567 if (pEntry != NULL) {
62eb734b 568 struct rt_measure_req_entry *pPrevEntry = NULL;
51126deb 569 unsigned long HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
62eb734b 570 struct rt_measure_req_entry *pProbeEntry = pTab->Hash[HashIdx];
91980990
GKH
571
572 RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
ec278fa2 573 /* update Hash list */
96b3c83d
BZ
574 do {
575 if (pProbeEntry == pEntry) {
576 if (pPrevEntry == NULL) {
91980990 577 pTab->Hash[HashIdx] = pEntry->pNext;
96b3c83d 578 } else {
91980990
GKH
579 pPrevEntry->pNext = pEntry->pNext;
580 }
581 break;
582 }
583
584 pPrevEntry = pProbeEntry;
585 pProbeEntry = pProbeEntry->pNext;
586 } while (pProbeEntry);
587
62eb734b 588 NdisZeroMemory(pEntry, sizeof(struct rt_measure_req_entry));
91980990
GKH
589 pTab->Size--;
590
591 RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
592 }
593
594 return;
595}
596
62eb734b 597void TpcReqTabInit(struct rt_rtmp_adapter *pAd)
91980990
GKH
598{
599 NdisAllocateSpinLock(&pAd->CommonCfg.TpcReqTabLock);
600
62eb734b 601 pAd->CommonCfg.pTpcReqTab = kmalloc(sizeof(struct rt_tpc_req_tab), GFP_ATOMIC);
91980990 602 if (pAd->CommonCfg.pTpcReqTab)
62eb734b 603 NdisZeroMemory(pAd->CommonCfg.pTpcReqTab, sizeof(struct rt_tpc_req_tab));
91980990 604 else
96b3c83d
BZ
605 DBGPRINT(RT_DEBUG_ERROR,
606 ("%s Fail to alloc memory for pAd->CommonCfg.pTpcReqTab.\n",
607 __func__));
91980990
GKH
608
609 return;
610}
611
62eb734b 612void TpcReqTabExit(struct rt_rtmp_adapter *pAd)
91980990 613{
ca97b838 614 NdisFreeSpinLock(&pAd->CommonCfg.TpcReqTabLock);
91980990 615
aea9d72f 616 kfree(pAd->CommonCfg.pTpcReqTab);
91980990
GKH
617 pAd->CommonCfg.pTpcReqTab = NULL;
618
619 return;
620}
621
62eb734b 622static struct rt_tpc_req_entry *TpcReqLookUp(struct rt_rtmp_adapter *pAd, u8 DialogToken)
91980990 623{
51126deb 624 u32 HashIdx;
62eb734b
BZ
625 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;
91980990 628
96b3c83d
BZ
629 if (pTab == NULL) {
630 DBGPRINT(RT_DEBUG_ERROR,
631 ("%s: pTpcReqTab doesn't exist.\n", __func__));
91980990
GKH
632 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
96b3c83d 640 while (pEntry) {
91980990
GKH
641 if (pEntry->DialogToken == DialogToken)
642 break;
96b3c83d 643 else {
91980990
GKH
644 pPrevEntry = pEntry;
645 pEntry = pEntry->pNext;
646 }
647 }
648
649 RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
650
651 return pEntry;
652}
653
62eb734b 654static struct rt_tpc_req_entry *TpcReqInsert(struct rt_rtmp_adapter *pAd, u8 DialogToken)
91980990 655{
51126deb
BZ
656 int i;
657 unsigned long HashIdx;
62eb734b
BZ
658 struct rt_tpc_req_tab *pTab = pAd->CommonCfg.pTpcReqTab;
659 struct rt_tpc_req_entry *pEntry = NULL, *pCurrEntry;
51126deb 660 unsigned long Now;
91980990 661
96b3c83d
BZ
662 if (pTab == NULL) {
663 DBGPRINT(RT_DEBUG_ERROR,
664 ("%s: pTpcReqTab doesn't exist.\n", __func__));
91980990
GKH
665 return NULL;
666 }
667
668 pEntry = TpcReqLookUp(pAd, DialogToken);
96b3c83d 669 if (pEntry == NULL) {
91980990 670 RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
96b3c83d 671 for (i = 0; i < MAX_TPC_REQ_TAB_SIZE; i++) {
91980990
GKH
672 NdisGetSystemUpTime(&Now);
673 pEntry = &pTab->Content[i];
674
675 if ((pEntry->Valid == TRUE)
96b3c83d
BZ
676 && RTMP_TIME_AFTER((unsigned long)Now,
677 (unsigned long)(pEntry->
678 lastTime +
679 TPC_REQ_AGE_OUT)))
91980990 680 {
62eb734b 681 struct rt_tpc_req_entry *pPrevEntry = NULL;
51126deb 682 unsigned long HashIdx =
96b3c83d
BZ
683 TPC_DIALOGTOKEN_HASH_INDEX(pEntry->
684 DialogToken);
62eb734b 685 struct rt_tpc_req_entry *pProbeEntry =
96b3c83d 686 pTab->Hash[HashIdx];
91980990 687
ec278fa2 688 /* update Hash list */
96b3c83d
BZ
689 do {
690 if (pProbeEntry == pEntry) {
691 if (pPrevEntry == NULL) {
692 pTab->Hash[HashIdx] =
693 pEntry->pNext;
694 } else {
695 pPrevEntry->pNext =
696 pEntry->pNext;
91980990
GKH
697 }
698 break;
699 }
700
701 pPrevEntry = pProbeEntry;
702 pProbeEntry = pProbeEntry->pNext;
703 } while (pProbeEntry);
704
62eb734b 705 NdisZeroMemory(pEntry, sizeof(struct rt_tpc_req_entry));
91980990
GKH
706 pTab->Size--;
707
708 break;
709 }
710
711 if (pEntry->Valid == FALSE)
712 break;
713 }
714
96b3c83d 715 if (i < MAX_TPC_REQ_TAB_SIZE) {
91980990
GKH
716 NdisGetSystemUpTime(&Now);
717 pEntry->lastTime = Now;
718 pEntry->Valid = TRUE;
719 pEntry->DialogToken = DialogToken;
720 pTab->Size++;
96b3c83d 721 } else {
91980990 722 pEntry = NULL;
96b3c83d
BZ
723 DBGPRINT(RT_DEBUG_ERROR,
724 ("%s: pTpcReqTab tab full.\n", __func__));
91980990
GKH
725 }
726
ec278fa2 727 /* add this Neighbor entry into HASH table */
96b3c83d 728 if (pEntry) {
91980990 729 HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken);
96b3c83d 730 if (pTab->Hash[HashIdx] == NULL) {
91980990 731 pTab->Hash[HashIdx] = pEntry;
96b3c83d 732 } else {
91980990
GKH
733 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
62eb734b 746static void TpcReqDelete(struct rt_rtmp_adapter *pAd, u8 DialogToken)
91980990 747{
62eb734b
BZ
748 struct rt_tpc_req_tab *pTab = pAd->CommonCfg.pTpcReqTab;
749 struct rt_tpc_req_entry *pEntry = NULL;
91980990 750
96b3c83d
BZ
751 if (pTab == NULL) {
752 DBGPRINT(RT_DEBUG_ERROR,
753 ("%s: pTpcReqTab doesn't exist.\n", __func__));
91980990
GKH
754 return;
755 }
ec278fa2 756 /* if empty, return */
96b3c83d 757 if (pTab->Size == 0) {
91980990
GKH
758 DBGPRINT(RT_DEBUG_ERROR, ("pTpcReqTab empty.\n"));
759 return;
760 }
761
762 pEntry = TpcReqLookUp(pAd, DialogToken);
96b3c83d 763 if (pEntry != NULL) {
62eb734b 764 struct rt_tpc_req_entry *pPrevEntry = NULL;
51126deb 765 unsigned long HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
62eb734b 766 struct rt_tpc_req_entry *pProbeEntry = pTab->Hash[HashIdx];
91980990
GKH
767
768 RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
ec278fa2 769 /* update Hash list */
96b3c83d
BZ
770 do {
771 if (pProbeEntry == pEntry) {
772 if (pPrevEntry == NULL) {
91980990 773 pTab->Hash[HashIdx] = pEntry->pNext;
96b3c83d 774 } else {
91980990
GKH
775 pPrevEntry->pNext = pEntry->pNext;
776 }
777 break;
778 }
779
780 pPrevEntry = pProbeEntry;
781 pProbeEntry = pProbeEntry->pNext;
782 } while (pProbeEntry);
783
62eb734b 784 NdisZeroMemory(pEntry, sizeof(struct rt_tpc_req_entry));
91980990
GKH
785 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 */
62eb734b 803static u64 GetCurrentTimeStamp(struct rt_rtmp_adapter *pAd)
91980990 804{
ec278fa2 805 /* get current time stamp. */
91980990
GKH
806 return 0;
807}
808
809/*
810 ==========================================================================
811 Description:
812 Get Current Transmit Power.
813
814 Parametrs:
815
816 Return : Current Time Stamp.
817 ==========================================================================
818 */
62eb734b 819static u8 GetCurTxPwr(struct rt_rtmp_adapter *pAd, u8 Wcid)
91980990 820{
96b3c83d 821 return 16; /* 16 dBm */
91980990
GKH
822}
823
ca97b838
BZ
824/*
825 ==========================================================================
826 Description:
827 Get Current Transmit Power.
828
829 Parametrs:
830
831 Return : Current Time Stamp.
832 ==========================================================================
833 */
62eb734b 834void InsertChannelRepIE(struct rt_rtmp_adapter *pAd,
51126deb
BZ
835 u8 *pFrameBuf,
836 unsigned long *pFrameLen,
837 char *pCountry, u8 RegulatoryClass)
ca97b838 838{
51126deb
BZ
839 unsigned long TempLen;
840 u8 Len;
841 u8 IEId = IE_AP_CHANNEL_REPORT;
842 u8 *pChListPtr = NULL;
ca97b838
BZ
843
844 Len = 1;
96b3c83d
BZ
845 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));
ca97b838
BZ
850 return;
851 }
852
96b3c83d
BZ
853 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));
ca97b838
BZ
863 return;
864 }
865
96b3c83d
BZ
866 Len +=
867 JapanRegulatoryInfo[RegulatoryClass].ChannelSet.
868 NumberOfChannels;
869 pChListPtr =
870 JapanRegulatoryInfo[RegulatoryClass].ChannelSet.ChannelList;
871 } else {
ca97b838 872 DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknow Country (%s)\n",
96b3c83d 873 __func__, pCountry));
ca97b838
BZ
874 return;
875 }
876
96b3c83d
BZ
877 MakeOutgoingFrame(pFrameBuf, &TempLen,
878 1, &IEId,
879 1, &Len,
880 1, &RegulatoryClass,
881 Len - 1, pChListPtr, END_OF_ARGS);
ca97b838
BZ
882
883 *pFrameLen = *pFrameLen + TempLen;
884
885 return;
886}
887
91980990
GKH
888/*
889 ==========================================================================
890 Description:
891 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 */
62eb734b 901void InsertDialogToken(struct rt_rtmp_adapter *pAd,
51126deb
BZ
902 u8 *pFrameBuf,
903 unsigned long *pFrameLen, u8 DialogToken)
91980990 904{
51126deb 905 unsigned long TempLen;
96b3c83d 906 MakeOutgoingFrame(pFrameBuf, &TempLen, 1, &DialogToken, END_OF_ARGS);
91980990
GKH
907
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 */
62eb734b 925static void InsertTpcReqIE(struct rt_rtmp_adapter *pAd,
51126deb 926 u8 *pFrameBuf, unsigned long *pFrameLen)
91980990 927{
51126deb
BZ
928 unsigned long TempLen;
929 unsigned long Len = 0;
930 u8 ElementID = IE_TPC_REQUEST;
91980990 931
96b3c83d
BZ
932 MakeOutgoingFrame(pFrameBuf, &TempLen,
933 1, &ElementID, 1, &Len, END_OF_ARGS);
91980990
GKH
934
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 */
62eb734b 954void InsertTpcReportIE(struct rt_rtmp_adapter *pAd,
51126deb
BZ
955 u8 *pFrameBuf,
956 unsigned long *pFrameLen,
957 u8 TxPwr, u8 LinkMargin)
91980990 958{
51126deb 959 unsigned long TempLen;
62eb734b 960 unsigned long Len = sizeof(struct rt_tpc_report_info);
51126deb 961 u8 ElementID = IE_TPC_REPORT;
62eb734b 962 struct rt_tpc_report_info TpcReportIE;
91980990
GKH
963
964 TpcReportIE.TxPwr = TxPwr;
965 TpcReportIE.LinkMargin = LinkMargin;
966
96b3c83d
BZ
967 MakeOutgoingFrame(pFrameBuf, &TempLen,
968 1, &ElementID,
969 1, &Len, Len, &TpcReportIE, END_OF_ARGS);
91980990
GKH
970
971 *pFrameLen = *pFrameLen + TempLen;
972
91980990
GKH
973 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 */
62eb734b 991static void InsertChSwAnnIE(struct rt_rtmp_adapter *pAd,
51126deb
BZ
992 u8 *pFrameBuf,
993 unsigned long *pFrameLen,
994 u8 ChSwMode,
995 u8 NewChannel, u8 ChSwCnt)
91980990 996{
51126deb 997 unsigned long TempLen;
62eb734b 998 unsigned long Len = sizeof(struct rt_ch_sw_ann_info);
51126deb 999 u8 ElementID = IE_CHANNEL_SWITCH_ANNOUNCEMENT;
62eb734b 1000 struct rt_ch_sw_ann_info ChSwAnnIE;
91980990
GKH
1001
1002 ChSwAnnIE.ChSwMode = ChSwMode;
1003 ChSwAnnIE.Channel = NewChannel;
1004 ChSwAnnIE.ChSwCnt = ChSwCnt;
1005
96b3c83d
BZ
1006 MakeOutgoingFrame(pFrameBuf, &TempLen,
1007 1, &ElementID, 1, &Len, Len, &ChSwAnnIE, END_OF_ARGS);
91980990
GKH
1008
1009 *pFrameLen = *pFrameLen + TempLen;
1010
91980990
GKH
1011 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
91980990
GKH
1029 Return : None.
1030 ==========================================================================
1031 */
62eb734b 1032static void InsertMeasureReqIE(struct rt_rtmp_adapter *pAd,
51126deb
BZ
1033 u8 *pFrameBuf,
1034 unsigned long *pFrameLen,
62eb734b 1035 u8 Len, struct rt_measure_req_info * pMeasureReqIE)
91980990 1036{
51126deb
BZ
1037 unsigned long TempLen;
1038 u8 ElementID = IE_MEASUREMENT_REQUEST;
91980990 1039
96b3c83d
BZ
1040 MakeOutgoingFrame(pFrameBuf, &TempLen,
1041 1, &ElementID,
1042 1, &Len,
62eb734b 1043 sizeof(struct rt_measure_req_info), pMeasureReqIE, END_OF_ARGS);
91980990
GKH
1044
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.
25985edc
LDM
1061 6. Length of Report Information
1062 7. Pointer of Report Information Buffer.
91980990
GKH
1063
1064 Return : None.
1065 ==========================================================================
1066 */
62eb734b 1067static void InsertMeasureReportIE(struct rt_rtmp_adapter *pAd,
51126deb
BZ
1068 u8 *pFrameBuf,
1069 unsigned long *pFrameLen,
62eb734b 1070 struct rt_measure_report_info * pMeasureReportIE,
51126deb 1071 u8 ReportLnfoLen, u8 *pReportInfo)
91980990 1072{
51126deb
BZ
1073 unsigned long TempLen;
1074 unsigned long Len;
1075 u8 ElementID = IE_MEASUREMENT_REPORT;
91980990 1076
62eb734b 1077 Len = sizeof(struct rt_measure_report_info) + ReportLnfoLen;
91980990 1078
96b3c83d
BZ
1079 MakeOutgoingFrame(pFrameBuf, &TempLen,
1080 1, &ElementID,
1081 1, &Len, Len, pMeasureReportIE, END_OF_ARGS);
91980990
GKH
1082
1083 *pFrameLen = *pFrameLen + TempLen;
1084
96b3c83d
BZ
1085 if ((ReportLnfoLen > 0) && (pReportInfo != NULL)) {
1086 MakeOutgoingFrame(pFrameBuf + *pFrameLen, &TempLen,
1087 ReportLnfoLen, pReportInfo, END_OF_ARGS);
91980990
GKH
1088
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 */
62eb734b 1106void MakeMeasurementReqFrame(struct rt_rtmp_adapter *pAd,
51126deb
BZ
1107 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)
91980990 1115{
51126deb 1116 unsigned long TempLen;
62eb734b 1117 struct rt_measure_req_info MeasureReqIE;
91980990 1118
96b3c83d
BZ
1119 InsertActField(pAd, (pOutBuffer + *pFrameLen), pFrameLen, Category,
1120 Action);
91980990 1121
ec278fa2 1122 /* fill Dialog Token */
96b3c83d
BZ
1123 InsertDialogToken(pAd, (pOutBuffer + *pFrameLen), pFrameLen,
1124 MeasureToken);
91980990 1125
ca97b838 1126 /* fill Number of repetitions. */
96b3c83d
BZ
1127 if (Category == CATEGORY_RM) {
1128 MakeOutgoingFrame((pOutBuffer + *pFrameLen), &TempLen,
1129 2, &NumOfRepetitions, END_OF_ARGS);
91980990 1130
ca97b838
BZ
1131 *pFrameLen += TempLen;
1132 }
ec278fa2 1133 /* prepare Measurement IE. */
62eb734b 1134 NdisZeroMemory(&MeasureReqIE, sizeof(struct rt_measure_req_info));
ca97b838 1135 MeasureReqIE.Token = MeasureToken;
91980990
GKH
1136 MeasureReqIE.ReqMode.word = MeasureReqMode;
1137 MeasureReqIE.ReqType = MeasureReqType;
96b3c83d
BZ
1138 InsertMeasureReqIE(pAd, (pOutBuffer + *pFrameLen), pFrameLen,
1139 TotalLen, &MeasureReqIE);
91980990
GKH
1140
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 */
62eb734b 1156void EnqueueMeasurementRep(struct rt_rtmp_adapter *pAd,
51126deb
BZ
1157 u8 *pDA,
1158 u8 DialogToken,
1159 u8 MeasureToken,
1160 u8 MeasureReqMode,
1161 u8 MeasureReqType,
1162 u8 ReportInfoLen, u8 *pReportInfo)
91980990 1163{
51126deb
BZ
1164 u8 *pOutBuffer = NULL;
1165 int NStatus;
1166 unsigned long FrameLen;
62eb734b
BZ
1167 struct rt_header_802_11 ActHdr;
1168 struct rt_measure_report_info MeasureRepIE;
91980990 1169
ec278fa2 1170 /* build action frame header. */
91980990 1171 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
96b3c83d 1172 pAd->CurrentAddress);
91980990 1173
51126deb 1174 NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer); /*Get an unused nonpaged memory */
96b3c83d
BZ
1175 if (NStatus != NDIS_STATUS_SUCCESS) {
1176 DBGPRINT(RT_DEBUG_TRACE,
1177 ("%s() allocate memory failed \n", __func__));
91980990
GKH
1178 return;
1179 }
62eb734b
BZ
1180 NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11));
1181 FrameLen = sizeof(struct rt_header_802_11);
91980990 1182
96b3c83d
BZ
1183 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen,
1184 CATEGORY_SPECTRUM, SPEC_MRP);
91980990 1185
ec278fa2 1186 /* fill Dialog Token */
91980990
GKH
1187 InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
1188
ec278fa2 1189 /* prepare Measurement IE. */
62eb734b 1190 NdisZeroMemory(&MeasureRepIE, sizeof(struct rt_measure_report_info));
91980990 1191 MeasureRepIE.Token = MeasureToken;
ca97b838 1192 MeasureRepIE.ReportMode = MeasureReqMode;
91980990 1193 MeasureRepIE.ReportType = MeasureReqType;
96b3c83d
BZ
1194 InsertMeasureReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen,
1195 &MeasureRepIE, ReportInfoLen, pReportInfo);
91980990
GKH
1196
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 */
62eb734b 1215void EnqueueTPCReq(struct rt_rtmp_adapter *pAd, u8 *pDA, u8 DialogToken)
91980990 1216{
51126deb
BZ
1217 u8 *pOutBuffer = NULL;
1218 int NStatus;
1219 unsigned long FrameLen;
91980990 1220
62eb734b 1221 struct rt_header_802_11 ActHdr;
91980990 1222
ec278fa2 1223 /* build action frame header. */
91980990 1224 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
96b3c83d 1225 pAd->CurrentAddress);
91980990 1226
51126deb 1227 NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer); /*Get an unused nonpaged memory */
96b3c83d
BZ
1228 if (NStatus != NDIS_STATUS_SUCCESS) {
1229 DBGPRINT(RT_DEBUG_TRACE,
1230 ("%s() allocate memory failed \n", __func__));
91980990
GKH
1231 return;
1232 }
62eb734b
BZ
1233 NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11));
1234 FrameLen = sizeof(struct rt_header_802_11);
91980990 1235
96b3c83d
BZ
1236 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen,
1237 CATEGORY_SPECTRUM, SPEC_TPCRQ);
91980990 1238
ec278fa2 1239 /* fill Dialog Token */
91980990
GKH
1240 InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
1241
ec278fa2 1242 /* Insert TPC Request IE. */
91980990
GKH
1243 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 */
62eb734b 1263void EnqueueTPCRep(struct rt_rtmp_adapter *pAd,
51126deb
BZ
1264 u8 *pDA,
1265 u8 DialogToken, u8 TxPwr, u8 LinkMargin)
91980990 1266{
51126deb
BZ
1267 u8 *pOutBuffer = NULL;
1268 int NStatus;
1269 unsigned long FrameLen;
91980990 1270
62eb734b 1271 struct rt_header_802_11 ActHdr;
91980990 1272
ec278fa2 1273 /* build action frame header. */
91980990 1274 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
96b3c83d 1275 pAd->CurrentAddress);
91980990 1276
51126deb 1277 NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer); /*Get an unused nonpaged memory */
96b3c83d
BZ
1278 if (NStatus != NDIS_STATUS_SUCCESS) {
1279 DBGPRINT(RT_DEBUG_TRACE,
1280 ("%s() allocate memory failed \n", __func__));
91980990
GKH
1281 return;
1282 }
62eb734b
BZ
1283 NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11));
1284 FrameLen = sizeof(struct rt_header_802_11);
91980990 1285
96b3c83d
BZ
1286 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen,
1287 CATEGORY_SPECTRUM, SPEC_TPCRP);
91980990 1288
ec278fa2 1289 /* fill Dialog Token */
91980990
GKH
1290 InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
1291
ec278fa2 1292 /* Insert TPC Request IE. */
96b3c83d
BZ
1293 InsertTpcReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, TxPwr,
1294 LinkMargin);
91980990
GKH
1295
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 */
62eb734b 1316void EnqueueChSwAnn(struct rt_rtmp_adapter *pAd,
51126deb 1317 u8 *pDA, u8 ChSwMode, u8 NewCh)
91980990 1318{
51126deb
BZ
1319 u8 *pOutBuffer = NULL;
1320 int NStatus;
1321 unsigned long FrameLen;
91980990 1322
62eb734b 1323 struct rt_header_802_11 ActHdr;
91980990 1324
ec278fa2 1325 /* build action frame header. */
91980990 1326 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
96b3c83d 1327 pAd->CurrentAddress);
91980990 1328
51126deb 1329 NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer); /*Get an unused nonpaged memory */
96b3c83d
BZ
1330 if (NStatus != NDIS_STATUS_SUCCESS) {
1331 DBGPRINT(RT_DEBUG_TRACE,
1332 ("%s() allocate memory failed \n", __func__));
91980990
GKH
1333 return;
1334 }
62eb734b
BZ
1335 NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11));
1336 FrameLen = sizeof(struct rt_header_802_11);
91980990 1337
96b3c83d
BZ
1338 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen,
1339 CATEGORY_SPECTRUM, SPEC_CHANNEL_SWITCH);
91980990 1340
96b3c83d
BZ
1341 InsertChSwAnnIE(pAd, (pOutBuffer + FrameLen), &FrameLen, ChSwMode,
1342 NewCh, 0);
91980990
GKH
1343
1344 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1345 MlmeFreeMemory(pAd, pOutBuffer);
1346
1347 return;
1348}
1349
62eb734b 1350static BOOLEAN DfsRequirementCheck(struct rt_rtmp_adapter *pAd, u8 Channel)
91980990
GKH
1351{
1352 BOOLEAN Result = FALSE;
51126deb 1353 int i;
91980990 1354
96b3c83d 1355 do {
ec278fa2
BZ
1356 /* check DFS procedure is running. */
1357 /* make sure DFS procedure won't start twice. */
96b3c83d 1358 if (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE) {
91980990
GKH
1359 Result = FALSE;
1360 break;
1361 }
ec278fa2 1362 /* check the new channel carried from Channel Switch Announcemnet is valid. */
96b3c83d 1363 for (i = 0; i < pAd->ChannelListNum; i++) {
91980990 1364 if ((Channel == pAd->ChannelList[i].Channel)
96b3c83d 1365 && (pAd->ChannelList[i].RemainingTimeForUse == 0)) {
ec278fa2
BZ
1366 /* 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 */
91980990
GKH
1368 Result = TRUE;
1369 break;
1370 }
1371 }
96b3c83d 1372 } while (FALSE);
91980990
GKH
1373
1374 return Result;
1375}
1376
62eb734b 1377void NotifyChSwAnnToPeerAPs(struct rt_rtmp_adapter *pAd,
51126deb
BZ
1378 u8 *pRA,
1379 u8 *pTA, u8 ChSwMode, u8 Channel)
91980990 1380{
91980990
GKH
1381}
1382
62eb734b 1383static void StartDFSProcedure(struct rt_rtmp_adapter *pAd,
51126deb 1384 u8 Channel, u8 ChSwMode)
91980990 1385{
ec278fa2 1386 /* start DFS procedure */
91980990 1387 pAd->CommonCfg.Channel = Channel;
1623267a 1388
91980990 1389 N_ChannelCheck(pAd);
1623267a 1390
91980990
GKH
1391 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.
25985edc 1403 3. Channel switch announcement information buffer.
91980990 1404
91980990
GKH
1405 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*/
62eb734b 1416static BOOLEAN PeerChSwAnnSanity(struct rt_rtmp_adapter *pAd,
51126deb
BZ
1417 void * pMsg,
1418 unsigned long MsgLen,
62eb734b 1419 struct rt_ch_sw_ann_info * pChSwAnnInfo)
91980990 1420{
62eb734b 1421 struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg;
51126deb 1422 u8 *pFramePtr = Fr->Octet;
91980990 1423 BOOLEAN result = FALSE;
62eb734b 1424 struct rt_eid * eid_ptr;
91980990 1425
ec278fa2 1426 /* skip 802.11 header. */
62eb734b 1427 MsgLen -= sizeof(struct rt_header_802_11);
91980990 1428
ec278fa2 1429 /* skip category and action code. */
91980990
GKH
1430 pFramePtr += 2;
1431 MsgLen -= 2;
1432
1433 if (pChSwAnnInfo == NULL)
1434 return result;
1435
62eb734b 1436 eid_ptr = (struct rt_eid *) pFramePtr;
51126deb
BZ
1437 while (((u8 *) eid_ptr + eid_ptr->Len + 1) <
1438 ((u8 *)pFramePtr + MsgLen)) {
96b3c83d
BZ
1439 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);
1447
1448 result = TRUE;
1449 break;
91980990 1450
96b3c83d
BZ
1451 default:
1452 break;
91980990 1453 }
62eb734b 1454 eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len);
91980990
GKH
1455 }
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.
25985edc 1468 3. Measurement request information buffer.
91980990
GKH
1469
1470 Return : None.
1471 ==========================================================================
1472 */
62eb734b 1473static BOOLEAN PeerMeasureReqSanity(struct rt_rtmp_adapter *pAd,
51126deb
BZ
1474 void * pMsg,
1475 unsigned long MsgLen,
1476 u8 *pDialogToken,
62eb734b
BZ
1477 struct rt_measure_req_info * pMeasureReqInfo,
1478 struct rt_measure_req * pMeasureReq)
91980990 1479{
62eb734b 1480 struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg;
51126deb 1481 u8 *pFramePtr = Fr->Octet;
91980990 1482 BOOLEAN result = FALSE;
62eb734b 1483 struct rt_eid * eid_ptr;
51126deb
BZ
1484 u8 *ptr;
1485 u64 MeasureStartTime;
1486 u16 MeasureDuration;
91980990 1487
ec278fa2 1488 /* skip 802.11 header. */
62eb734b 1489 MsgLen -= sizeof(struct rt_header_802_11);
91980990 1490
ec278fa2 1491 /* skip category and action code. */
91980990
GKH
1492 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
62eb734b 1502 eid_ptr = (struct rt_eid *) pFramePtr;
51126deb
BZ
1503 while (((u8 *) eid_ptr + eid_ptr->Len + 1) <
1504 ((u8 *)pFramePtr + MsgLen)) {
96b3c83d
BZ
1505 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);
51126deb 1513 ptr = (u8 *)(eid_ptr->Octet + 3);
96b3c83d
BZ
1514 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);
1520
1521 result = TRUE;
1522 break;
91980990 1523
96b3c83d
BZ
1524 default:
1525 break;
91980990 1526 }
62eb734b 1527 eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len);
91980990
GKH
1528 }
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.
25985edc
LDM
1541 3. Measurement report information buffer.
1542 4. basic report information buffer.
91980990
GKH
1543
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*/
62eb734b 1567static BOOLEAN PeerMeasureReportSanity(struct rt_rtmp_adapter *pAd,
51126deb
BZ
1568 void * pMsg,
1569 unsigned long MsgLen,
1570 u8 *pDialogToken,
62eb734b 1571 struct rt_measure_report_info *
96b3c83d 1572 pMeasureReportInfo,
51126deb 1573 u8 *pReportBuf)
91980990 1574{
62eb734b 1575 struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg;
51126deb 1576 u8 *pFramePtr = Fr->Octet;
91980990 1577 BOOLEAN result = FALSE;
62eb734b 1578 struct rt_eid * eid_ptr;
51126deb 1579 u8 *ptr;
91980990 1580
ec278fa2 1581 /* skip 802.11 header. */
62eb734b 1582 MsgLen -= sizeof(struct rt_header_802_11);
91980990 1583
ec278fa2 1584 /* skip category and action code. */
91980990
GKH
1585 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
62eb734b 1595 eid_ptr = (struct rt_eid *) pFramePtr;
51126deb
BZ
1596 while (((u8 *) eid_ptr + eid_ptr->Len + 1) <
1597 ((u8 *)pFramePtr + MsgLen)) {
96b3c83d
BZ
1598 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) {
62eb734b
BZ
1607 struct rt_measure_basic_report * pReport =
1608 (struct rt_measure_basic_report *) pReportBuf;
51126deb 1609 ptr = (u8 *)(eid_ptr->Octet + 3);
96b3c83d
BZ
1610 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);
1616
1617 } else if (pMeasureReportInfo->ReportType == RM_CCA) {
62eb734b
BZ
1618 struct rt_measure_cca_report * pReport =
1619 (struct rt_measure_cca_report *) pReportBuf;
51126deb 1620 ptr = (u8 *)(eid_ptr->Octet + 3);
96b3c83d
BZ
1621 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);
1628
1629 } else if (pMeasureReportInfo->ReportType ==
1630 RM_RPI_HISTOGRAM) {
62eb734b
BZ
1631 struct rt_measure_rpi_report * pReport =
1632 (struct rt_measure_rpi_report *) pReportBuf;
51126deb 1633 ptr = (u8 *)(eid_ptr->Octet + 3);
96b3c83d
BZ
1634 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;
91980990 1644
96b3c83d
BZ
1645 default:
1646 break;
91980990 1647 }
62eb734b 1648 eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len);
91980990
GKH
1649 }
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 */
62eb734b 1667static BOOLEAN PeerTpcReqSanity(struct rt_rtmp_adapter *pAd,
51126deb
BZ
1668 void * pMsg,
1669 unsigned long MsgLen, u8 *pDialogToken)
91980990 1670{
62eb734b 1671 struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg;
51126deb 1672 u8 *pFramePtr = Fr->Octet;
91980990 1673 BOOLEAN result = FALSE;
62eb734b 1674 struct rt_eid * eid_ptr;
91980990 1675
62eb734b 1676 MsgLen -= sizeof(struct rt_header_802_11);
91980990 1677
ec278fa2 1678 /* skip category and action code. */
91980990
GKH
1679 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
62eb734b 1689 eid_ptr = (struct rt_eid *) pFramePtr;
51126deb
BZ
1690 while (((u8 *) eid_ptr + eid_ptr->Len + 1) <
1691 ((u8 *)pFramePtr + MsgLen)) {
96b3c83d
BZ
1692 switch (eid_ptr->Eid) {
1693 case IE_TPC_REQUEST:
1694 result = TRUE;
1695 break;
91980990 1696
96b3c83d
BZ
1697 default:
1698 break;
91980990 1699 }
62eb734b 1700 eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len);
91980990
GKH
1701 }
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 */
62eb734b 1720static BOOLEAN PeerTpcRepSanity(struct rt_rtmp_adapter *pAd,
51126deb
BZ
1721 void * pMsg,
1722 unsigned long MsgLen,
1723 u8 *pDialogToken,
62eb734b 1724 struct rt_tpc_report_info * pTpcRepInfo)
91980990 1725{
62eb734b 1726 struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg;
51126deb 1727 u8 *pFramePtr = Fr->Octet;
91980990 1728 BOOLEAN result = FALSE;
62eb734b 1729 struct rt_eid * eid_ptr;
91980990 1730
62eb734b 1731 MsgLen -= sizeof(struct rt_header_802_11);
91980990 1732
ec278fa2 1733 /* skip category and action code. */
91980990
GKH
1734 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
62eb734b 1744 eid_ptr = (struct rt_eid *) pFramePtr;
51126deb
BZ
1745 while (((u8 *) eid_ptr + eid_ptr->Len + 1) <
1746 ((u8 *)pFramePtr + MsgLen)) {
96b3c83d
BZ
1747 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;
1754
1755 default:
1756 break;
91980990 1757 }
62eb734b 1758 eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len);
91980990
GKH
1759 }
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 */
62eb734b 1775static void PeerChSwAnnAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
91980990 1776{
62eb734b
BZ
1777 struct rt_ch_sw_ann_info ChSwAnnInfo;
1778 struct rt_frame_802_11 * pFr = (struct rt_frame_802_11 *) Elem->Msg;
51126deb
BZ
1779 u8 index = 0, Channel = 0, NewChannel = 0;
1780 unsigned long Bssidx = 0;
91980990 1781
62eb734b 1782 NdisZeroMemory(&ChSwAnnInfo, sizeof(struct rt_ch_sw_ann_info));
96b3c83d
BZ
1783 if (!PeerChSwAnnSanity(pAd, Elem->Msg, Elem->MsgLen, &ChSwAnnInfo)) {
1784 DBGPRINT(RT_DEBUG_TRACE,
1785 ("Invalid Channel Switch Action Frame.\n"));
91980990
GKH
1786 return;
1787 }
1788
96b3c83d
BZ
1789 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"));
91980990
GKH
1796 return;
1797 }
1798
96b3c83d
BZ
1799 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);
91980990
GKH
1803
1804 Channel = pAd->CommonCfg.Channel;
1805 NewChannel = ChSwAnnInfo.Channel;
1806
96b3c83d
BZ
1807 if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0)
1808 && (Channel != NewChannel)) {
ec278fa2
BZ
1809 /* 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. */
91980990
GKH
1811 AsicSwitchChannel(pAd, 1, FALSE);
1812 AsicLockChannel(pAd, 1);
96b3c83d 1813 LinkDown(pAd, FALSE);
91980990
GKH
1814 MlmeQueueInit(&pAd->Mlme.Queue);
1815 BssTableInit(&pAd->ScanTab);
ec278fa2 1816 RTMPusecDelay(1000000); /* use delay to prevent STA do reassoc */
91980990 1817
ec278fa2 1818 /* channel sanity check */
96b3c83d
BZ
1819 for (index = 0; index < pAd->ChannelListNum; index++) {
1820 if (pAd->ChannelList[index].Channel ==
1821 NewChannel) {
1822 pAd->ScanTab.BssEntry[Bssidx].Channel =
1823 NewChannel;
91980990 1824 pAd->CommonCfg.Channel = NewChannel;
96b3c83d
BZ
1825 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));
91980990
GKH
1833 break;
1834 }
1835 }
1836
96b3c83d 1837 if (index >= pAd->ChannelListNum) {
8c3d9092 1838 DBGPRINT_ERR("&&&&&&&&&&&&&&&&&&&&&&&&&&PeerChSwAnnAction(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum);
91980990
GKH
1839 }
1840 }
1841 }
91980990
GKH
1842
1843 return;
1844}
1845
91980990
GKH
1846/*
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 */
62eb734b
BZ
1857static void PeerMeasureReqAction(struct rt_rtmp_adapter *pAd,
1858 struct rt_mlme_queue_elem *Elem)
91980990 1859{
62eb734b 1860 struct rt_frame_802_11 * pFr = (struct rt_frame_802_11 *) Elem->Msg;
51126deb 1861 u8 DialogToken;
62eb734b
BZ
1862 struct rt_measure_req_info MeasureReqInfo;
1863 struct rt_measure_req MeasureReq;
91980990
GKH
1864 MEASURE_REPORT_MODE ReportMode;
1865
96b3c83d
BZ
1866 if (PeerMeasureReqSanity
1867 (pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReqInfo,
1868 &MeasureReq)) {
91980990
GKH
1869 ReportMode.word = 0;
1870 ReportMode.field.Incapable = 1;
96b3c83d
BZ
1871 EnqueueMeasurementRep(pAd, pFr->Hdr.Addr2, DialogToken,
1872 MeasureReqInfo.Token, ReportMode.word,
1873 MeasureReqInfo.ReqType, 0, NULL);
91980990
GKH
1874 }
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 */
62eb734b
BZ
1890static void PeerMeasureReportAction(struct rt_rtmp_adapter *pAd,
1891 struct rt_mlme_queue_elem *Elem)
91980990 1892{
62eb734b
BZ
1893 struct rt_measure_report_info MeasureReportInfo;
1894 struct rt_frame_802_11 * pFr = (struct rt_frame_802_11 *) Elem->Msg;
51126deb
BZ
1895 u8 DialogToken;
1896 u8 *pMeasureReportInfo;
91980990 1897
ec278fa2
BZ
1898/* if (pAd->CommonCfg.bIEEE80211H != TRUE) */
1899/* return; */
91980990 1900
6aed5295
JP
1901 pMeasureReportInfo = kmalloc(sizeof(struct rt_measure_rpi_report), GFP_ATOMIC);
1902 if (pMeasureReportInfo == NULL) {
96b3c83d
BZ
1903 DBGPRINT(RT_DEBUG_ERROR,
1904 ("%s unable to alloc memory for measure report buffer (size=%zu).\n",
62eb734b 1905 __func__, sizeof(struct rt_measure_rpi_report)));
91980990
GKH
1906 return;
1907 }
1908
62eb734b
BZ
1909 NdisZeroMemory(&MeasureReportInfo, sizeof(struct rt_measure_report_info));
1910 NdisZeroMemory(pMeasureReportInfo, sizeof(struct rt_measure_rpi_report));
96b3c83d
BZ
1911 if (PeerMeasureReportSanity
1912 (pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReportInfo,
1913 pMeasureReportInfo)) {
91980990 1914 do {
62eb734b 1915 struct rt_measure_req_entry *pEntry = NULL;
91980990 1916
ec278fa2
BZ
1917 /* Not a autonomous measure report. */
1918 /* check the dialog token field. drop it if the dialog token doesn't match. */
91980990 1919 if ((DialogToken != 0)
96b3c83d
BZ
1920 && ((pEntry = MeasureReqLookUp(pAd, DialogToken)) ==
1921 NULL))
91980990
GKH
1922 break;
1923
1924 if (pEntry != NULL)
1925 MeasureReqDelete(pAd, pEntry->DialogToken);
1926
96b3c83d 1927 if (MeasureReportInfo.ReportType == RM_BASIC) {
62eb734b
BZ
1928 struct rt_measure_basic_report * pBasicReport =
1929 (struct rt_measure_basic_report *) pMeasureReportInfo;
91980990 1930 if ((pBasicReport->Map.field.Radar)
96b3c83d
BZ
1931 &&
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);
91980990
GKH
1943 }
1944 }
1945 } while (FALSE);
96b3c83d
BZ
1946 } else
1947 DBGPRINT(RT_DEBUG_TRACE,
1948 ("Invalid Measurement Report Frame.\n"));
91980990
GKH
1949
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 */
62eb734b 1966static void PeerTpcReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
91980990 1967{
62eb734b 1968 struct rt_frame_802_11 * pFr = (struct rt_frame_802_11 *) Elem->Msg;
51126deb
BZ
1969 u8 *pFramePtr = pFr->Octet;
1970 u8 DialogToken;
1971 u8 TxPwr = GetCurTxPwr(pAd, Elem->Wcid);
1972 u8 LinkMargin = 0;
1973 char RealRssi;
91980990 1974
ec278fa2
BZ
1975 /* 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. */
91980990
GKH
1978
1979 RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0),
96b3c83d
BZ
1980 ConvertToRssi(pAd, Elem->Rssi1, RSSI_1),
1981 ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
91980990 1982
ec278fa2 1983 /* skip Category and action code. */
91980990
GKH
1984 pFramePtr += 2;
1985
ec278fa2 1986 /* Dialog token. */
91980990
GKH
1987 NdisMoveMemory(&DialogToken, pFramePtr, 1);
1988
1989 LinkMargin = (RealRssi / MIN_RCV_PWR);
1990 if (PeerTpcReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken))
96b3c83d
BZ
1991 EnqueueTPCRep(pAd, pFr->Hdr.Addr2, DialogToken, TxPwr,
1992 LinkMargin);
91980990
GKH
1993
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 */
62eb734b 2008static void PeerTpcRepAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
91980990 2009{
51126deb 2010 u8 DialogToken;
62eb734b
BZ
2011 struct rt_tpc_report_info TpcRepInfo;
2012 struct rt_tpc_req_entry *pEntry = NULL;
91980990 2013
62eb734b 2014 NdisZeroMemory(&TpcRepInfo, sizeof(struct rt_tpc_report_info));
96b3c83d
BZ
2015 if (PeerTpcRepSanity
2016 (pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &TpcRepInfo)) {
6aed5295
JP
2017 pEntry = TpcReqLookUp(pAd, DialogToken);
2018 if (pEntry != NULL) {
91980990 2019 TpcReqDelete(pAd, pEntry->DialogToken);
96b3c83d
BZ
2020 DBGPRINT(RT_DEBUG_TRACE,
2021 ("%s: DialogToken=%x, TxPwr=%d, LinkMargin=%d\n",
2022 __func__, DialogToken, TpcRepInfo.TxPwr,
2023 TpcRepInfo.LinkMargin));
91980990
GKH
2024 }
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 */
62eb734b 2042void PeerSpectrumAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
91980990
GKH
2043{
2044
51126deb 2045 u8 Action = Elem->Msg[LENGTH_802_11 + 1];
91980990
GKH
2046
2047 if (pAd->CommonCfg.bIEEE80211H != TRUE)
2048 return;
2049
96b3c83d
BZ
2050 switch (Action) {
2051 case SPEC_MRQ:
ec278fa2
BZ
2052 /* current rt2860 unable do such measure specified in Measurement Request. */
2053 /* reject all measurement request. */
96b3c83d
BZ
2054 PeerMeasureReqAction(pAd, Elem);
2055 break;
91980990 2056
96b3c83d
BZ
2057 case SPEC_MRP:
2058 PeerMeasureReportAction(pAd, Elem);
2059 break;
91980990 2060
96b3c83d
BZ
2061 case SPEC_TPCRQ:
2062 PeerTpcReqAction(pAd, Elem);
2063 break;
91980990 2064
96b3c83d
BZ
2065 case SPEC_TPCRP:
2066 PeerTpcRepAction(pAd, Elem);
2067 break;
91980990 2068
96b3c83d 2069 case SPEC_CHANNEL_SWITCH:
ca97b838 2070
96b3c83d
BZ
2071 PeerChSwAnnAction(pAd, Elem);
2072 break;
91980990
GKH
2073 }
2074
2075 return;
2076}
2077
2078/*
2079 ==========================================================================
2080 Description:
2081
2082 Parametrs:
2083
2084 Return : None.
2085 ==========================================================================
2086 */
62eb734b 2087int Set_MeasureReq_Proc(struct rt_rtmp_adapter *pAd, char *arg)
91980990 2088{
51126deb
BZ
2089 u32 Aid = 1;
2090 u32 ArgIdx;
2091 char *thisChar;
91980990
GKH
2092
2093 MEASURE_REQ_MODE MeasureReqMode;
51126deb
BZ
2094 u8 MeasureReqToken = RandomByte(pAd);
2095 u8 MeasureReqType = RM_BASIC;
2096 u8 MeasureCh = 1;
2097 u64 MeasureStartTime = GetCurrentTimeStamp(pAd);
62eb734b 2098 struct rt_measure_req MeasureReq;
51126deb 2099 u8 TotalLen;
ca97b838 2100
62eb734b 2101 struct rt_header_802_11 ActHdr;
51126deb
BZ
2102 u8 *pOutBuffer = NULL;
2103 int NStatus;
2104 unsigned long FrameLen;
ca97b838 2105
51126deb 2106 NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer); /*Get an unused nonpaged memory */
96b3c83d
BZ
2107 if (NStatus != NDIS_STATUS_SUCCESS) {
2108 DBGPRINT(RT_DEBUG_TRACE,
2109 ("%s() allocate memory failed \n", __func__));
ca97b838
BZ
2110 goto END_OF_MEASURE_REQ;
2111 }
91980990
GKH
2112
2113 ArgIdx = 1;
96b3c83d
BZ
2114 while ((thisChar = strsep((char **)&arg, "-")) != NULL) {
2115 switch (ArgIdx) {
ec278fa2 2116 case 1: /* Aid. */
51126deb 2117 Aid = (u8)simple_strtol(thisChar, 0, 16);
96b3c83d 2118 break;
91980990 2119
ec278fa2 2120 case 2: /* Measurement Request Type. */
96b3c83d
BZ
2121 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;
91980990 2129
ec278fa2 2130 case 3: /* Measurement channel. */
51126deb 2131 MeasureCh = (u8)simple_strtol(thisChar, 0, 16);
96b3c83d 2132 break;
91980990
GKH
2133 }
2134 ArgIdx++;
2135 }
2136
96b3c83d
BZ
2137 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));
ca97b838 2143 goto END_OF_MEASURE_REQ;
91980990
GKH
2144 }
2145
2146 MeasureReqMode.word = 0;
2147 MeasureReqMode.field.Enable = 1;
2148
2149 MeasureReqInsert(pAd, MeasureReqToken);
2150
ec278fa2 2151 /* build action frame header. */
96b3c83d
BZ
2152 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0,
2153 pAd->MacTab.Content[Aid].Addr, pAd->CurrentAddress);
ca97b838 2154
62eb734b
BZ
2155 NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11));
2156 FrameLen = sizeof(struct rt_header_802_11);
ca97b838 2157
62eb734b 2158 TotalLen = sizeof(struct rt_measure_req_info) + sizeof(struct rt_measure_req);
ca97b838
BZ
2159
2160 MakeMeasurementReqFrame(pAd, pOutBuffer, &FrameLen,
62eb734b 2161 sizeof(struct rt_measure_req_info), CATEGORY_RM, RM_BASIC,
96b3c83d
BZ
2162 MeasureReqToken, MeasureReqMode.word,
2163 MeasureReqType, 0);
ca97b838
BZ
2164
2165 MeasureReq.ChNum = MeasureCh;
2166 MeasureReq.MeasureStartTime = cpu2le64(MeasureStartTime);
2167 MeasureReq.MeasureDuration = cpu2le16(2000);
2168
2169 {
51126deb 2170 unsigned long TempLen;
96b3c83d 2171 MakeOutgoingFrame(pOutBuffer + FrameLen, &TempLen,
62eb734b 2172 sizeof(struct rt_measure_req), &MeasureReq,
96b3c83d 2173 END_OF_ARGS);
ca97b838
BZ
2174 FrameLen += TempLen;
2175 }
2176
51126deb 2177 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, (u32)FrameLen);
ca97b838
BZ
2178
2179END_OF_MEASURE_REQ:
2180 MlmeFreeMemory(pAd, pOutBuffer);
91980990
GKH
2181
2182 return TRUE;
2183}
2184
62eb734b 2185int Set_TpcReq_Proc(struct rt_rtmp_adapter *pAd, char *arg)
91980990 2186{
51126deb 2187 u32 Aid;
91980990 2188
51126deb 2189 u8 TpcReqToken = RandomByte(pAd);
91980990 2190
51126deb 2191 Aid = (u32)simple_strtol(arg, 0, 16);
91980990 2192
d599edca 2193 DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d\n", __func__, Aid));
96b3c83d
BZ
2194 if (!VALID_WCID(Aid)) {
2195 DBGPRINT(RT_DEBUG_ERROR,
2196 ("%s: unknow sta of Aid(%d)\n", __func__, Aid));
91980990
GKH
2197 return TRUE;
2198 }
2199
2200 TpcReqInsert(pAd, TpcReqToken);
2201
2202 EnqueueTPCReq(pAd, pAd->MacTab.Content[Aid].Addr, TpcReqToken);
2203
2204 return TRUE;
2205}