]>
Commit | Line | Data |
---|---|---|
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 | ||
27 | ||
28 | Module Name: | |
29 | action.c | |
30 | ||
31 | Abstract: | |
32 | Handle association related requests either from WSTA or from local MLME | |
33 | ||
34 | Revision History: | |
35 | Who When What | |
36 | --------- ---------- ---------------------------------------------- | |
37 | Fonchi Wu 2008 created for 802.11h | |
38 | */ | |
39 | ||
40 | #include "../rt_config.h" | |
41 | #include "action.h" | |
42 | ||
ca97b838 BZ |
43 | |
44 | /* The regulatory information in the USA (US) */ | |
45 | DOT11_REGULATORY_INFORMATION USARegulatoryInfo[] = | |
46 | { | |
47 | /* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */ | |
48 | {0, {0, 0, {0}}}, // Invlid entry | |
49 | {1, {4, 16, {36, 40, 44, 48}}}, | |
50 | {2, {4, 23, {52, 56, 60, 64}}}, | |
51 | {3, {4, 29, {149, 153, 157, 161}}}, | |
52 | {4, {11, 23, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}}, | |
53 | {5, {5, 30, {149, 153, 157, 161, 165}}}, | |
54 | {6, {10, 14, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}}, | |
55 | {7, {10, 27, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}}, | |
56 | {8, {5, 17, {11, 13, 15, 17, 19}}}, | |
57 | {9, {5, 30, {11, 13, 15, 17, 19}}}, | |
58 | {10, {2, 20, {21, 25}}}, | |
59 | {11, {2, 33, {21, 25}}}, | |
60 | {12, {11, 30, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}} | |
61 | }; | |
62 | #define USA_REGULATORY_INFO_SIZE (sizeof(USARegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION)) | |
63 | ||
64 | ||
65 | /* The regulatory information in Europe */ | |
66 | DOT11_REGULATORY_INFORMATION EuropeRegulatoryInfo[] = | |
67 | { | |
68 | /* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */ | |
69 | {0, {0, 0, {0}}}, // Invalid entry | |
70 | {1, {4, 20, {36, 40, 44, 48}}}, | |
71 | {2, {4, 20, {52, 56, 60, 64}}}, | |
72 | {3, {11, 30, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}}, | |
73 | {4, {13, 20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}} | |
74 | }; | |
75 | #define EU_REGULATORY_INFO_SIZE (sizeof(EuropeRegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION)) | |
76 | ||
77 | ||
78 | /* The regulatory information in Japan */ | |
79 | DOT11_REGULATORY_INFORMATION JapanRegulatoryInfo[] = | |
80 | { | |
81 | /* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */ | |
82 | {0, {0, 0, {0}}}, // Invalid entry | |
83 | {1, {4, 22, {34, 38, 42, 46}}}, | |
84 | {2, {3, 24, {8, 12, 16}}}, | |
85 | {3, {3, 24, {8, 12, 16}}}, | |
86 | {4, {3, 24, {8, 12, 16}}}, | |
87 | {5, {3, 24, {8, 12, 16}}}, | |
88 | {6, {3, 22, {8, 12, 16}}}, | |
89 | {7, {4, 24, {184, 188, 192, 196}}}, | |
90 | {8, {4, 24, {184, 188, 192, 196}}}, | |
91 | {9, {4, 24, {184, 188, 192, 196}}}, | |
92 | {10, {4, 24, {184, 188, 192, 196}}}, | |
93 | {11, {4, 22, {184, 188, 192, 196}}}, | |
94 | {12, {4, 24, {7, 8, 9, 11}}}, | |
95 | {13, {4, 24, {7, 8, 9, 11}}}, | |
96 | {14, {4, 24, {7, 8, 9, 11}}}, | |
97 | {15, {4, 24, {7, 8, 9, 11}}}, | |
98 | {16, {6, 24, {183, 184, 185, 187, 188, 189}}}, | |
99 | {17, {6, 24, {183, 184, 185, 187, 188, 189}}}, | |
100 | {18, {6, 24, {183, 184, 185, 187, 188, 189}}}, | |
101 | {19, {6, 24, {183, 184, 185, 187, 188, 189}}}, | |
102 | {20, {6, 17, {183, 184, 185, 187, 188, 189}}}, | |
103 | {21, {6, 24, {6, 7, 8, 9, 10, 11}}}, | |
104 | {22, {6, 24, {6, 7, 8, 9, 10, 11}}}, | |
105 | {23, {6, 24, {6, 7, 8, 9, 10, 11}}}, | |
106 | {24, {6, 24, {6, 7, 8, 9, 10, 11}}}, | |
107 | {25, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}}, | |
108 | {26, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}}, | |
109 | {27, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}}, | |
110 | {28, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}}, | |
111 | {29, {8, 17, {182, 183, 184, 185, 186, 187, 188, 189}}}, | |
112 | {30, {13, 23, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}}, | |
113 | {31, {1, 23, {14}}}, | |
114 | {32, {4, 22, {52, 56, 60, 64}}} | |
115 | }; | |
116 | #define JP_REGULATORY_INFO_SIZE (sizeof(JapanRegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION)) | |
117 | ||
118 | ||
119 | CHAR RTMP_GetTxPwr( | |
120 | IN PRTMP_ADAPTER pAd, | |
121 | IN HTTRANSMIT_SETTING HTTxMode) | |
122 | { | |
123 | typedef struct __TX_PWR_CFG | |
124 | { | |
125 | UINT8 Mode; | |
126 | UINT8 MCS; | |
127 | UINT16 req; | |
128 | UINT8 shift; | |
129 | UINT32 BitMask; | |
130 | } TX_PWR_CFG; | |
131 | ||
132 | UINT32 Value; | |
133 | INT Idx; | |
134 | UINT8 PhyMode; | |
135 | CHAR CurTxPwr; | |
136 | UINT8 TxPwrRef = 0; | |
137 | CHAR DaltaPwr; | |
138 | ULONG TxPwr[5]; | |
139 | ||
140 | ||
141 | TX_PWR_CFG TxPwrCfg[] = { | |
142 | {MODE_CCK, 0, 0, 4, 0x000000f0}, | |
143 | {MODE_CCK, 1, 0, 0, 0x0000000f}, | |
144 | {MODE_CCK, 2, 0, 12, 0x0000f000}, | |
145 | {MODE_CCK, 3, 0, 8, 0x00000f00}, | |
146 | ||
147 | {MODE_OFDM, 0, 0, 20, 0x00f00000}, | |
148 | {MODE_OFDM, 1, 0, 16, 0x000f0000}, | |
149 | {MODE_OFDM, 2, 0, 28, 0xf0000000}, | |
150 | {MODE_OFDM, 3, 0, 24, 0x0f000000}, | |
151 | {MODE_OFDM, 4, 1, 4, 0x000000f0}, | |
152 | {MODE_OFDM, 5, 1, 0, 0x0000000f}, | |
153 | {MODE_OFDM, 6, 1, 12, 0x0000f000}, | |
154 | {MODE_OFDM, 7, 1, 8, 0x00000f00} | |
155 | ,{MODE_HTMIX, 0, 1, 20, 0x00f00000}, | |
156 | {MODE_HTMIX, 1, 1, 16, 0x000f0000}, | |
157 | {MODE_HTMIX, 2, 1, 28, 0xf0000000}, | |
158 | {MODE_HTMIX, 3, 1, 24, 0x0f000000}, | |
159 | {MODE_HTMIX, 4, 2, 4, 0x000000f0}, | |
160 | {MODE_HTMIX, 5, 2, 0, 0x0000000f}, | |
161 | {MODE_HTMIX, 6, 2, 12, 0x0000f000}, | |
162 | {MODE_HTMIX, 7, 2, 8, 0x00000f00}, | |
163 | {MODE_HTMIX, 8, 2, 20, 0x00f00000}, | |
164 | {MODE_HTMIX, 9, 2, 16, 0x000f0000}, | |
165 | {MODE_HTMIX, 10, 2, 28, 0xf0000000}, | |
166 | {MODE_HTMIX, 11, 2, 24, 0x0f000000}, | |
167 | {MODE_HTMIX, 12, 3, 4, 0x000000f0}, | |
168 | {MODE_HTMIX, 13, 3, 0, 0x0000000f}, | |
169 | {MODE_HTMIX, 14, 3, 12, 0x0000f000}, | |
170 | {MODE_HTMIX, 15, 3, 8, 0x00000f00} | |
171 | }; | |
172 | #define MAX_TXPWR_TAB_SIZE (sizeof(TxPwrCfg) / sizeof(TX_PWR_CFG)) | |
173 | ||
174 | CurTxPwr = 19; | |
175 | ||
176 | /* check Tx Power setting from UI. */ | |
177 | if (pAd->CommonCfg.TxPowerPercentage > 90) | |
178 | ; | |
179 | else if (pAd->CommonCfg.TxPowerPercentage > 60) /* reduce Pwr for 1 dB. */ | |
180 | CurTxPwr -= 1; | |
181 | else if (pAd->CommonCfg.TxPowerPercentage > 30) /* reduce Pwr for 3 dB. */ | |
182 | CurTxPwr -= 3; | |
183 | else if (pAd->CommonCfg.TxPowerPercentage > 15) /* reduce Pwr for 6 dB. */ | |
184 | CurTxPwr -= 6; | |
185 | else if (pAd->CommonCfg.TxPowerPercentage > 9) /* reduce Pwr for 9 dB. */ | |
186 | CurTxPwr -= 9; | |
187 | else /* reduce Pwr for 12 dB. */ | |
188 | CurTxPwr -= 12; | |
189 | ||
190 | if (pAd->CommonCfg.BBPCurrentBW == BW_40) | |
191 | { | |
192 | if (pAd->CommonCfg.CentralChannel > 14) | |
193 | { | |
194 | TxPwr[0] = pAd->Tx40MPwrCfgABand[0]; | |
195 | TxPwr[1] = pAd->Tx40MPwrCfgABand[1]; | |
196 | TxPwr[2] = pAd->Tx40MPwrCfgABand[2]; | |
197 | TxPwr[3] = pAd->Tx40MPwrCfgABand[3]; | |
198 | TxPwr[4] = pAd->Tx40MPwrCfgABand[4]; | |
199 | } | |
200 | else | |
201 | { | |
202 | TxPwr[0] = pAd->Tx40MPwrCfgGBand[0]; | |
203 | TxPwr[1] = pAd->Tx40MPwrCfgGBand[1]; | |
204 | TxPwr[2] = pAd->Tx40MPwrCfgGBand[2]; | |
205 | TxPwr[3] = pAd->Tx40MPwrCfgGBand[3]; | |
206 | TxPwr[4] = pAd->Tx40MPwrCfgGBand[4]; | |
207 | } | |
208 | } | |
209 | else | |
210 | { | |
211 | if (pAd->CommonCfg.Channel > 14) | |
212 | { | |
213 | TxPwr[0] = pAd->Tx20MPwrCfgABand[0]; | |
214 | TxPwr[1] = pAd->Tx20MPwrCfgABand[1]; | |
215 | TxPwr[2] = pAd->Tx20MPwrCfgABand[2]; | |
216 | TxPwr[3] = pAd->Tx20MPwrCfgABand[3]; | |
217 | TxPwr[4] = pAd->Tx20MPwrCfgABand[4]; | |
218 | } | |
219 | else | |
220 | { | |
221 | TxPwr[0] = pAd->Tx20MPwrCfgGBand[0]; | |
222 | TxPwr[1] = pAd->Tx20MPwrCfgGBand[1]; | |
223 | TxPwr[2] = pAd->Tx20MPwrCfgGBand[2]; | |
224 | TxPwr[3] = pAd->Tx20MPwrCfgGBand[3]; | |
225 | TxPwr[4] = pAd->Tx20MPwrCfgGBand[4]; | |
226 | } | |
227 | } | |
228 | ||
229 | ||
230 | switch(HTTxMode.field.MODE) | |
231 | { | |
232 | case MODE_CCK: | |
233 | case MODE_OFDM: | |
234 | Value = TxPwr[1]; | |
235 | TxPwrRef = (Value & 0x00000f00) >> 8; | |
236 | ||
237 | break; | |
238 | ||
239 | case MODE_HTMIX: | |
240 | case MODE_HTGREENFIELD: | |
241 | if (pAd->CommonCfg.TxStream == 1) | |
242 | { | |
243 | Value = TxPwr[2]; | |
244 | TxPwrRef = (Value & 0x00000f00) >> 8; | |
245 | } | |
246 | else if (pAd->CommonCfg.TxStream == 2) | |
247 | { | |
248 | Value = TxPwr[3]; | |
249 | TxPwrRef = (Value & 0x00000f00) >> 8; | |
250 | } | |
251 | break; | |
252 | } | |
253 | ||
254 | PhyMode = | |
255 | (HTTxMode.field.MODE == MODE_HTGREENFIELD) | |
256 | ? MODE_HTMIX : | |
257 | HTTxMode.field.MODE; | |
258 | ||
259 | for (Idx = 0; Idx < MAX_TXPWR_TAB_SIZE; Idx++) | |
260 | { | |
261 | if ((TxPwrCfg[Idx].Mode == PhyMode) | |
262 | && (TxPwrCfg[Idx].MCS == HTTxMode.field.MCS)) | |
263 | { | |
264 | Value = TxPwr[TxPwrCfg[Idx].req]; | |
265 | DaltaPwr = TxPwrRef - (CHAR)((Value & TxPwrCfg[Idx].BitMask) | |
266 | >> TxPwrCfg[Idx].shift); | |
267 | CurTxPwr -= DaltaPwr; | |
268 | break; | |
269 | } | |
270 | } | |
271 | ||
272 | return CurTxPwr; | |
273 | } | |
274 | ||
275 | ||
91980990 GKH |
276 | VOID MeasureReqTabInit( |
277 | IN PRTMP_ADAPTER pAd) | |
278 | { | |
279 | NdisAllocateSpinLock(&pAd->CommonCfg.MeasureReqTabLock); | |
280 | ||
281 | pAd->CommonCfg.pMeasureReqTab = kmalloc(sizeof(MEASURE_REQ_TAB), GFP_ATOMIC); | |
282 | if (pAd->CommonCfg.pMeasureReqTab) | |
283 | NdisZeroMemory(pAd->CommonCfg.pMeasureReqTab, sizeof(MEASURE_REQ_TAB)); | |
284 | else | |
d599edca | 285 | DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pMeasureReqTab.\n", __func__)); |
91980990 GKH |
286 | |
287 | return; | |
288 | } | |
289 | ||
290 | VOID MeasureReqTabExit( | |
291 | IN PRTMP_ADAPTER pAd) | |
292 | { | |
ca97b838 | 293 | NdisFreeSpinLock(&pAd->CommonCfg.MeasureReqTabLock); |
91980990 GKH |
294 | |
295 | if (pAd->CommonCfg.pMeasureReqTab) | |
296 | kfree(pAd->CommonCfg.pMeasureReqTab); | |
297 | pAd->CommonCfg.pMeasureReqTab = NULL; | |
298 | ||
299 | return; | |
300 | } | |
301 | ||
ca97b838 | 302 | PMEASURE_REQ_ENTRY MeasureReqLookUp( |
91980990 GKH |
303 | IN PRTMP_ADAPTER pAd, |
304 | IN UINT8 DialogToken) | |
305 | { | |
306 | UINT HashIdx; | |
307 | PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab; | |
308 | PMEASURE_REQ_ENTRY pEntry = NULL; | |
309 | PMEASURE_REQ_ENTRY pPrevEntry = NULL; | |
310 | ||
311 | if (pTab == NULL) | |
312 | { | |
d599edca | 313 | DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __func__)); |
91980990 GKH |
314 | return NULL; |
315 | } | |
316 | ||
317 | RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock); | |
318 | ||
319 | HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken); | |
320 | pEntry = pTab->Hash[HashIdx]; | |
321 | ||
322 | while (pEntry) | |
323 | { | |
324 | if (pEntry->DialogToken == DialogToken) | |
325 | break; | |
326 | else | |
327 | { | |
328 | pPrevEntry = pEntry; | |
329 | pEntry = pEntry->pNext; | |
330 | } | |
331 | } | |
332 | ||
333 | RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock); | |
334 | ||
335 | return pEntry; | |
336 | } | |
337 | ||
ca97b838 | 338 | PMEASURE_REQ_ENTRY MeasureReqInsert( |
91980990 GKH |
339 | IN PRTMP_ADAPTER pAd, |
340 | IN UINT8 DialogToken) | |
341 | { | |
342 | INT i; | |
343 | ULONG HashIdx; | |
344 | PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab; | |
345 | PMEASURE_REQ_ENTRY pEntry = NULL, pCurrEntry; | |
346 | ULONG Now; | |
347 | ||
348 | if(pTab == NULL) | |
349 | { | |
d599edca | 350 | DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __func__)); |
91980990 GKH |
351 | return NULL; |
352 | } | |
353 | ||
354 | pEntry = MeasureReqLookUp(pAd, DialogToken); | |
355 | if (pEntry == NULL) | |
356 | { | |
357 | RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock); | |
358 | for (i = 0; i < MAX_MEASURE_REQ_TAB_SIZE; i++) | |
359 | { | |
360 | NdisGetSystemUpTime(&Now); | |
361 | pEntry = &pTab->Content[i]; | |
362 | ||
363 | if ((pEntry->Valid == TRUE) | |
364 | && RTMP_TIME_AFTER((unsigned long)Now, (unsigned long)(pEntry->lastTime + MQ_REQ_AGE_OUT))) | |
365 | { | |
366 | PMEASURE_REQ_ENTRY pPrevEntry = NULL; | |
367 | ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken); | |
368 | PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx]; | |
369 | ||
370 | // update Hash list | |
371 | do | |
372 | { | |
373 | if (pProbeEntry == pEntry) | |
374 | { | |
375 | if (pPrevEntry == NULL) | |
376 | { | |
377 | pTab->Hash[HashIdx] = pEntry->pNext; | |
378 | } | |
379 | else | |
380 | { | |
381 | pPrevEntry->pNext = pEntry->pNext; | |
382 | } | |
383 | break; | |
384 | } | |
385 | ||
386 | pPrevEntry = pProbeEntry; | |
387 | pProbeEntry = pProbeEntry->pNext; | |
388 | } while (pProbeEntry); | |
389 | ||
390 | NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY)); | |
391 | pTab->Size--; | |
392 | ||
393 | break; | |
394 | } | |
395 | ||
396 | if (pEntry->Valid == FALSE) | |
397 | break; | |
398 | } | |
399 | ||
400 | if (i < MAX_MEASURE_REQ_TAB_SIZE) | |
401 | { | |
402 | NdisGetSystemUpTime(&Now); | |
403 | pEntry->lastTime = Now; | |
404 | pEntry->Valid = TRUE; | |
405 | pEntry->DialogToken = DialogToken; | |
406 | pTab->Size++; | |
407 | } | |
408 | else | |
409 | { | |
410 | pEntry = NULL; | |
d599edca | 411 | DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab tab full.\n", __func__)); |
91980990 GKH |
412 | } |
413 | ||
414 | // add this Neighbor entry into HASH table | |
415 | if (pEntry) | |
416 | { | |
417 | HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken); | |
418 | if (pTab->Hash[HashIdx] == NULL) | |
419 | { | |
420 | pTab->Hash[HashIdx] = pEntry; | |
421 | } | |
422 | else | |
423 | { | |
424 | pCurrEntry = pTab->Hash[HashIdx]; | |
425 | while (pCurrEntry->pNext != NULL) | |
426 | pCurrEntry = pCurrEntry->pNext; | |
427 | pCurrEntry->pNext = pEntry; | |
428 | } | |
429 | } | |
430 | ||
431 | RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock); | |
432 | } | |
433 | ||
434 | return pEntry; | |
435 | } | |
436 | ||
ca97b838 | 437 | VOID MeasureReqDelete( |
91980990 GKH |
438 | IN PRTMP_ADAPTER pAd, |
439 | IN UINT8 DialogToken) | |
440 | { | |
441 | PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab; | |
442 | PMEASURE_REQ_ENTRY pEntry = NULL; | |
443 | ||
444 | if(pTab == NULL) | |
445 | { | |
d599edca | 446 | DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __func__)); |
91980990 GKH |
447 | return; |
448 | } | |
449 | ||
450 | // if empty, return | |
451 | if (pTab->Size == 0) | |
452 | { | |
453 | DBGPRINT(RT_DEBUG_ERROR, ("pMeasureReqTab empty.\n")); | |
454 | return; | |
455 | } | |
456 | ||
457 | pEntry = MeasureReqLookUp(pAd, DialogToken); | |
458 | if (pEntry != NULL) | |
459 | { | |
460 | PMEASURE_REQ_ENTRY pPrevEntry = NULL; | |
461 | ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken); | |
462 | PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx]; | |
463 | ||
464 | RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock); | |
465 | // update Hash list | |
466 | do | |
467 | { | |
468 | if (pProbeEntry == pEntry) | |
469 | { | |
470 | if (pPrevEntry == NULL) | |
471 | { | |
472 | pTab->Hash[HashIdx] = pEntry->pNext; | |
473 | } | |
474 | else | |
475 | { | |
476 | pPrevEntry->pNext = pEntry->pNext; | |
477 | } | |
478 | break; | |
479 | } | |
480 | ||
481 | pPrevEntry = pProbeEntry; | |
482 | pProbeEntry = pProbeEntry->pNext; | |
483 | } while (pProbeEntry); | |
484 | ||
485 | NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY)); | |
486 | pTab->Size--; | |
487 | ||
488 | RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock); | |
489 | } | |
490 | ||
491 | return; | |
492 | } | |
493 | ||
494 | VOID TpcReqTabInit( | |
495 | IN PRTMP_ADAPTER pAd) | |
496 | { | |
497 | NdisAllocateSpinLock(&pAd->CommonCfg.TpcReqTabLock); | |
498 | ||
499 | pAd->CommonCfg.pTpcReqTab = kmalloc(sizeof(TPC_REQ_TAB), GFP_ATOMIC); | |
500 | if (pAd->CommonCfg.pTpcReqTab) | |
501 | NdisZeroMemory(pAd->CommonCfg.pTpcReqTab, sizeof(TPC_REQ_TAB)); | |
502 | else | |
d599edca | 503 | DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pTpcReqTab.\n", __func__)); |
91980990 GKH |
504 | |
505 | return; | |
506 | } | |
507 | ||
508 | VOID TpcReqTabExit( | |
509 | IN PRTMP_ADAPTER pAd) | |
510 | { | |
ca97b838 | 511 | NdisFreeSpinLock(&pAd->CommonCfg.TpcReqTabLock); |
91980990 GKH |
512 | |
513 | if (pAd->CommonCfg.pTpcReqTab) | |
514 | kfree(pAd->CommonCfg.pTpcReqTab); | |
515 | pAd->CommonCfg.pTpcReqTab = NULL; | |
516 | ||
517 | return; | |
518 | } | |
519 | ||
520 | static PTPC_REQ_ENTRY TpcReqLookUp( | |
521 | IN PRTMP_ADAPTER pAd, | |
522 | IN UINT8 DialogToken) | |
523 | { | |
524 | UINT HashIdx; | |
525 | PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab; | |
526 | PTPC_REQ_ENTRY pEntry = NULL; | |
527 | PTPC_REQ_ENTRY pPrevEntry = NULL; | |
528 | ||
529 | if (pTab == NULL) | |
530 | { | |
d599edca | 531 | DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __func__)); |
91980990 GKH |
532 | return NULL; |
533 | } | |
534 | ||
535 | RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock); | |
536 | ||
537 | HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken); | |
538 | pEntry = pTab->Hash[HashIdx]; | |
539 | ||
540 | while (pEntry) | |
541 | { | |
542 | if (pEntry->DialogToken == DialogToken) | |
543 | break; | |
544 | else | |
545 | { | |
546 | pPrevEntry = pEntry; | |
547 | pEntry = pEntry->pNext; | |
548 | } | |
549 | } | |
550 | ||
551 | RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock); | |
552 | ||
553 | return pEntry; | |
554 | } | |
555 | ||
556 | ||
557 | static PTPC_REQ_ENTRY TpcReqInsert( | |
558 | IN PRTMP_ADAPTER pAd, | |
559 | IN UINT8 DialogToken) | |
560 | { | |
561 | INT i; | |
562 | ULONG HashIdx; | |
563 | PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab; | |
564 | PTPC_REQ_ENTRY pEntry = NULL, pCurrEntry; | |
565 | ULONG Now; | |
566 | ||
567 | if(pTab == NULL) | |
568 | { | |
d599edca | 569 | DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __func__)); |
91980990 GKH |
570 | return NULL; |
571 | } | |
572 | ||
573 | pEntry = TpcReqLookUp(pAd, DialogToken); | |
574 | if (pEntry == NULL) | |
575 | { | |
576 | RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock); | |
577 | for (i = 0; i < MAX_TPC_REQ_TAB_SIZE; i++) | |
578 | { | |
579 | NdisGetSystemUpTime(&Now); | |
580 | pEntry = &pTab->Content[i]; | |
581 | ||
582 | if ((pEntry->Valid == TRUE) | |
583 | && RTMP_TIME_AFTER((unsigned long)Now, (unsigned long)(pEntry->lastTime + TPC_REQ_AGE_OUT))) | |
584 | { | |
585 | PTPC_REQ_ENTRY pPrevEntry = NULL; | |
586 | ULONG HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken); | |
587 | PTPC_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx]; | |
588 | ||
589 | // update Hash list | |
590 | do | |
591 | { | |
592 | if (pProbeEntry == pEntry) | |
593 | { | |
594 | if (pPrevEntry == NULL) | |
595 | { | |
596 | pTab->Hash[HashIdx] = pEntry->pNext; | |
597 | } | |
598 | else | |
599 | { | |
600 | pPrevEntry->pNext = pEntry->pNext; | |
601 | } | |
602 | break; | |
603 | } | |
604 | ||
605 | pPrevEntry = pProbeEntry; | |
606 | pProbeEntry = pProbeEntry->pNext; | |
607 | } while (pProbeEntry); | |
608 | ||
609 | NdisZeroMemory(pEntry, sizeof(TPC_REQ_ENTRY)); | |
610 | pTab->Size--; | |
611 | ||
612 | break; | |
613 | } | |
614 | ||
615 | if (pEntry->Valid == FALSE) | |
616 | break; | |
617 | } | |
618 | ||
619 | if (i < MAX_TPC_REQ_TAB_SIZE) | |
620 | { | |
621 | NdisGetSystemUpTime(&Now); | |
622 | pEntry->lastTime = Now; | |
623 | pEntry->Valid = TRUE; | |
624 | pEntry->DialogToken = DialogToken; | |
625 | pTab->Size++; | |
626 | } | |
627 | else | |
628 | { | |
629 | pEntry = NULL; | |
d599edca | 630 | DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab tab full.\n", __func__)); |
91980990 GKH |
631 | } |
632 | ||
633 | // add this Neighbor entry into HASH table | |
634 | if (pEntry) | |
635 | { | |
636 | HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken); | |
637 | if (pTab->Hash[HashIdx] == NULL) | |
638 | { | |
639 | pTab->Hash[HashIdx] = pEntry; | |
640 | } | |
641 | else | |
642 | { | |
643 | pCurrEntry = pTab->Hash[HashIdx]; | |
644 | while (pCurrEntry->pNext != NULL) | |
645 | pCurrEntry = pCurrEntry->pNext; | |
646 | pCurrEntry->pNext = pEntry; | |
647 | } | |
648 | } | |
649 | ||
650 | RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock); | |
651 | } | |
652 | ||
653 | return pEntry; | |
654 | } | |
655 | ||
656 | static VOID TpcReqDelete( | |
657 | IN PRTMP_ADAPTER pAd, | |
658 | IN UINT8 DialogToken) | |
659 | { | |
660 | PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab; | |
661 | PTPC_REQ_ENTRY pEntry = NULL; | |
662 | ||
663 | if(pTab == NULL) | |
664 | { | |
d599edca | 665 | DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __func__)); |
91980990 GKH |
666 | return; |
667 | } | |
668 | ||
669 | // if empty, return | |
670 | if (pTab->Size == 0) | |
671 | { | |
672 | DBGPRINT(RT_DEBUG_ERROR, ("pTpcReqTab empty.\n")); | |
673 | return; | |
674 | } | |
675 | ||
676 | pEntry = TpcReqLookUp(pAd, DialogToken); | |
677 | if (pEntry != NULL) | |
678 | { | |
679 | PTPC_REQ_ENTRY pPrevEntry = NULL; | |
680 | ULONG HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken); | |
681 | PTPC_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx]; | |
682 | ||
683 | RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock); | |
684 | // update Hash list | |
685 | do | |
686 | { | |
687 | if (pProbeEntry == pEntry) | |
688 | { | |
689 | if (pPrevEntry == NULL) | |
690 | { | |
691 | pTab->Hash[HashIdx] = pEntry->pNext; | |
692 | } | |
693 | else | |
694 | { | |
695 | pPrevEntry->pNext = pEntry->pNext; | |
696 | } | |
697 | break; | |
698 | } | |
699 | ||
700 | pPrevEntry = pProbeEntry; | |
701 | pProbeEntry = pProbeEntry->pNext; | |
702 | } while (pProbeEntry); | |
703 | ||
704 | NdisZeroMemory(pEntry, sizeof(TPC_REQ_ENTRY)); | |
705 | pTab->Size--; | |
706 | ||
707 | RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock); | |
708 | } | |
709 | ||
710 | return; | |
711 | } | |
712 | ||
713 | /* | |
714 | ========================================================================== | |
715 | Description: | |
716 | Get Current TimeS tamp. | |
717 | ||
718 | Parametrs: | |
719 | ||
720 | Return : Current Time Stamp. | |
721 | ========================================================================== | |
722 | */ | |
723 | static UINT64 GetCurrentTimeStamp( | |
724 | IN PRTMP_ADAPTER pAd) | |
725 | { | |
726 | // get current time stamp. | |
727 | return 0; | |
728 | } | |
729 | ||
730 | /* | |
731 | ========================================================================== | |
732 | Description: | |
733 | Get Current Transmit Power. | |
734 | ||
735 | Parametrs: | |
736 | ||
737 | Return : Current Time Stamp. | |
738 | ========================================================================== | |
739 | */ | |
740 | static UINT8 GetCurTxPwr( | |
741 | IN PRTMP_ADAPTER pAd, | |
742 | IN UINT8 Wcid) | |
743 | { | |
744 | return 16; /* 16 dBm */ | |
745 | } | |
746 | ||
ca97b838 BZ |
747 | /* |
748 | ========================================================================== | |
749 | Description: | |
750 | Get Current Transmit Power. | |
751 | ||
752 | Parametrs: | |
753 | ||
754 | Return : Current Time Stamp. | |
755 | ========================================================================== | |
756 | */ | |
757 | VOID InsertChannelRepIE( | |
758 | IN PRTMP_ADAPTER pAd, | |
759 | OUT PUCHAR pFrameBuf, | |
760 | OUT PULONG pFrameLen, | |
761 | IN PSTRING pCountry, | |
762 | IN UINT8 RegulatoryClass) | |
763 | { | |
764 | ULONG TempLen; | |
765 | UINT8 Len; | |
766 | UINT8 IEId = IE_AP_CHANNEL_REPORT; | |
767 | PUCHAR pChListPtr = NULL; | |
768 | ||
769 | Len = 1; | |
770 | if (strncmp(pCountry, "US", 2) == 0) | |
771 | { | |
772 | if (RegulatoryClass >= USA_REGULATORY_INFO_SIZE) | |
773 | { | |
774 | DBGPRINT(RT_DEBUG_ERROR, ("%s: USA Unknow Requlatory class (%d)\n", | |
775 | __func__, RegulatoryClass)); | |
776 | return; | |
777 | } | |
778 | ||
779 | Len += USARegulatoryInfo[RegulatoryClass].ChannelSet.NumberOfChannels; | |
780 | pChListPtr = USARegulatoryInfo[RegulatoryClass].ChannelSet.ChannelList; | |
781 | } | |
782 | else if (strncmp(pCountry, "JP", 2) == 0) | |
783 | { | |
784 | if (RegulatoryClass >= JP_REGULATORY_INFO_SIZE) | |
785 | { | |
786 | DBGPRINT(RT_DEBUG_ERROR, ("%s: JP Unknow Requlatory class (%d)\n", | |
787 | __func__, RegulatoryClass)); | |
788 | return; | |
789 | } | |
790 | ||
791 | Len += JapanRegulatoryInfo[RegulatoryClass].ChannelSet.NumberOfChannels; | |
792 | pChListPtr = JapanRegulatoryInfo[RegulatoryClass].ChannelSet.ChannelList; | |
793 | } | |
794 | else | |
795 | { | |
796 | DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknow Country (%s)\n", | |
797 | __func__, pCountry)); | |
798 | return; | |
799 | } | |
800 | ||
801 | MakeOutgoingFrame(pFrameBuf, &TempLen, | |
802 | 1, &IEId, | |
803 | 1, &Len, | |
804 | 1, &RegulatoryClass, | |
805 | Len -1, pChListPtr, | |
806 | END_OF_ARGS); | |
807 | ||
808 | *pFrameLen = *pFrameLen + TempLen; | |
809 | ||
810 | return; | |
811 | } | |
812 | ||
91980990 GKH |
813 | /* |
814 | ========================================================================== | |
815 | Description: | |
816 | Insert Dialog Token into frame. | |
817 | ||
818 | Parametrs: | |
819 | 1. frame buffer pointer. | |
820 | 2. frame length. | |
821 | 3. Dialog token. | |
822 | ||
823 | Return : None. | |
824 | ========================================================================== | |
825 | */ | |
ca97b838 | 826 | VOID InsertDialogToken( |
91980990 GKH |
827 | IN PRTMP_ADAPTER pAd, |
828 | OUT PUCHAR pFrameBuf, | |
829 | OUT PULONG pFrameLen, | |
830 | IN UINT8 DialogToken) | |
831 | { | |
832 | ULONG TempLen; | |
833 | MakeOutgoingFrame(pFrameBuf, &TempLen, | |
834 | 1, &DialogToken, | |
835 | END_OF_ARGS); | |
836 | ||
837 | *pFrameLen = *pFrameLen + TempLen; | |
838 | ||
839 | return; | |
840 | } | |
841 | ||
842 | /* | |
843 | ========================================================================== | |
844 | Description: | |
845 | Insert TPC Request IE into frame. | |
846 | ||
847 | Parametrs: | |
848 | 1. frame buffer pointer. | |
849 | 2. frame length. | |
850 | ||
851 | Return : None. | |
852 | ========================================================================== | |
853 | */ | |
854 | static VOID InsertTpcReqIE( | |
855 | IN PRTMP_ADAPTER pAd, | |
856 | OUT PUCHAR pFrameBuf, | |
857 | OUT PULONG pFrameLen) | |
858 | { | |
859 | ULONG TempLen; | |
860 | ULONG Len = 0; | |
861 | UINT8 ElementID = IE_TPC_REQUEST; | |
862 | ||
863 | MakeOutgoingFrame(pFrameBuf, &TempLen, | |
864 | 1, &ElementID, | |
865 | 1, &Len, | |
866 | END_OF_ARGS); | |
867 | ||
868 | *pFrameLen = *pFrameLen + TempLen; | |
869 | ||
870 | return; | |
871 | } | |
872 | ||
873 | /* | |
874 | ========================================================================== | |
875 | Description: | |
876 | Insert TPC Report IE into frame. | |
877 | ||
878 | Parametrs: | |
879 | 1. frame buffer pointer. | |
880 | 2. frame length. | |
881 | 3. Transmit Power. | |
882 | 4. Link Margin. | |
883 | ||
884 | Return : None. | |
885 | ========================================================================== | |
886 | */ | |
ca97b838 | 887 | VOID InsertTpcReportIE( |
91980990 GKH |
888 | IN PRTMP_ADAPTER pAd, |
889 | OUT PUCHAR pFrameBuf, | |
890 | OUT PULONG pFrameLen, | |
891 | IN UINT8 TxPwr, | |
892 | IN UINT8 LinkMargin) | |
893 | { | |
894 | ULONG TempLen; | |
895 | ULONG Len = sizeof(TPC_REPORT_INFO); | |
896 | UINT8 ElementID = IE_TPC_REPORT; | |
897 | TPC_REPORT_INFO TpcReportIE; | |
898 | ||
899 | TpcReportIE.TxPwr = TxPwr; | |
900 | TpcReportIE.LinkMargin = LinkMargin; | |
901 | ||
902 | MakeOutgoingFrame(pFrameBuf, &TempLen, | |
903 | 1, &ElementID, | |
904 | 1, &Len, | |
905 | Len, &TpcReportIE, | |
906 | END_OF_ARGS); | |
907 | ||
908 | *pFrameLen = *pFrameLen + TempLen; | |
909 | ||
910 | ||
911 | return; | |
912 | } | |
913 | ||
914 | /* | |
915 | ========================================================================== | |
916 | Description: | |
917 | Insert Channel Switch Announcement IE into frame. | |
918 | ||
919 | Parametrs: | |
920 | 1. frame buffer pointer. | |
921 | 2. frame length. | |
922 | 3. channel switch announcement mode. | |
923 | 4. new selected channel. | |
924 | 5. channel switch announcement count. | |
925 | ||
926 | Return : None. | |
927 | ========================================================================== | |
928 | */ | |
929 | static VOID InsertChSwAnnIE( | |
930 | IN PRTMP_ADAPTER pAd, | |
931 | OUT PUCHAR pFrameBuf, | |
932 | OUT PULONG pFrameLen, | |
933 | IN UINT8 ChSwMode, | |
934 | IN UINT8 NewChannel, | |
935 | IN UINT8 ChSwCnt) | |
936 | { | |
937 | ULONG TempLen; | |
938 | ULONG Len = sizeof(CH_SW_ANN_INFO); | |
939 | UINT8 ElementID = IE_CHANNEL_SWITCH_ANNOUNCEMENT; | |
940 | CH_SW_ANN_INFO ChSwAnnIE; | |
941 | ||
942 | ChSwAnnIE.ChSwMode = ChSwMode; | |
943 | ChSwAnnIE.Channel = NewChannel; | |
944 | ChSwAnnIE.ChSwCnt = ChSwCnt; | |
945 | ||
946 | MakeOutgoingFrame(pFrameBuf, &TempLen, | |
947 | 1, &ElementID, | |
948 | 1, &Len, | |
949 | Len, &ChSwAnnIE, | |
950 | END_OF_ARGS); | |
951 | ||
952 | *pFrameLen = *pFrameLen + TempLen; | |
953 | ||
954 | ||
955 | return; | |
956 | } | |
957 | ||
958 | /* | |
959 | ========================================================================== | |
960 | Description: | |
961 | Insert Measure Request IE into frame. | |
962 | ||
963 | Parametrs: | |
964 | 1. frame buffer pointer. | |
965 | 2. frame length. | |
966 | 3. Measure Token. | |
967 | 4. Measure Request Mode. | |
968 | 5. Measure Request Type. | |
969 | 6. Measure Channel. | |
970 | 7. Measure Start time. | |
971 | 8. Measure Duration. | |
972 | ||
973 | ||
974 | Return : None. | |
975 | ========================================================================== | |
976 | */ | |
977 | static VOID InsertMeasureReqIE( | |
978 | IN PRTMP_ADAPTER pAd, | |
979 | OUT PUCHAR pFrameBuf, | |
980 | OUT PULONG pFrameLen, | |
ca97b838 | 981 | IN UINT8 Len, |
91980990 GKH |
982 | IN PMEASURE_REQ_INFO pMeasureReqIE) |
983 | { | |
984 | ULONG TempLen; | |
91980990 GKH |
985 | UINT8 ElementID = IE_MEASUREMENT_REQUEST; |
986 | ||
987 | MakeOutgoingFrame(pFrameBuf, &TempLen, | |
988 | 1, &ElementID, | |
989 | 1, &Len, | |
ca97b838 | 990 | sizeof(MEASURE_REQ_INFO), pMeasureReqIE, |
91980990 GKH |
991 | END_OF_ARGS); |
992 | ||
993 | *pFrameLen = *pFrameLen + TempLen; | |
994 | ||
995 | return; | |
996 | } | |
997 | ||
998 | /* | |
999 | ========================================================================== | |
1000 | Description: | |
1001 | Insert Measure Report IE into frame. | |
1002 | ||
1003 | Parametrs: | |
1004 | 1. frame buffer pointer. | |
1005 | 2. frame length. | |
1006 | 3. Measure Token. | |
1007 | 4. Measure Request Mode. | |
1008 | 5. Measure Request Type. | |
1009 | 6. Length of Report Infomation | |
1010 | 7. Pointer of Report Infomation Buffer. | |
1011 | ||
1012 | Return : None. | |
1013 | ========================================================================== | |
1014 | */ | |
1015 | static VOID InsertMeasureReportIE( | |
1016 | IN PRTMP_ADAPTER pAd, | |
1017 | OUT PUCHAR pFrameBuf, | |
1018 | OUT PULONG pFrameLen, | |
1019 | IN PMEASURE_REPORT_INFO pMeasureReportIE, | |
1020 | IN UINT8 ReportLnfoLen, | |
1021 | IN PUINT8 pReportInfo) | |
1022 | { | |
1023 | ULONG TempLen; | |
1024 | ULONG Len; | |
1025 | UINT8 ElementID = IE_MEASUREMENT_REPORT; | |
1026 | ||
1027 | Len = sizeof(MEASURE_REPORT_INFO) + ReportLnfoLen; | |
1028 | ||
1029 | MakeOutgoingFrame(pFrameBuf, &TempLen, | |
1030 | 1, &ElementID, | |
1031 | 1, &Len, | |
1032 | Len, pMeasureReportIE, | |
1033 | END_OF_ARGS); | |
1034 | ||
1035 | *pFrameLen = *pFrameLen + TempLen; | |
1036 | ||
1037 | if ((ReportLnfoLen > 0) && (pReportInfo != NULL)) | |
1038 | { | |
1039 | MakeOutgoingFrame(pFrameBuf + *pFrameLen, &TempLen, | |
1040 | ReportLnfoLen, pReportInfo, | |
1041 | END_OF_ARGS); | |
1042 | ||
1043 | *pFrameLen = *pFrameLen + TempLen; | |
1044 | } | |
1045 | return; | |
1046 | } | |
1047 | ||
1048 | /* | |
1049 | ========================================================================== | |
1050 | Description: | |
1051 | Prepare Measurement request action frame and enqueue it into | |
1052 | management queue waiting for transmition. | |
1053 | ||
1054 | Parametrs: | |
1055 | 1. the destination mac address of the frame. | |
1056 | ||
1057 | Return : None. | |
1058 | ========================================================================== | |
1059 | */ | |
ca97b838 | 1060 | VOID MakeMeasurementReqFrame( |
91980990 | 1061 | IN PRTMP_ADAPTER pAd, |
ca97b838 BZ |
1062 | OUT PUCHAR pOutBuffer, |
1063 | OUT PULONG pFrameLen, | |
1064 | IN UINT8 TotalLen, | |
1065 | IN UINT8 Category, | |
1066 | IN UINT8 Action, | |
91980990 GKH |
1067 | IN UINT8 MeasureToken, |
1068 | IN UINT8 MeasureReqMode, | |
1069 | IN UINT8 MeasureReqType, | |
ca97b838 | 1070 | IN UINT8 NumOfRepetitions) |
91980990 | 1071 | { |
ca97b838 | 1072 | ULONG TempLen; |
91980990 | 1073 | MEASURE_REQ_INFO MeasureReqIE; |
91980990 | 1074 | |
ca97b838 | 1075 | InsertActField(pAd, (pOutBuffer + *pFrameLen), pFrameLen, Category, Action); |
91980990 | 1076 | |
ca97b838 BZ |
1077 | // fill Dialog Token |
1078 | InsertDialogToken(pAd, (pOutBuffer + *pFrameLen), pFrameLen, MeasureToken); | |
91980990 | 1079 | |
ca97b838 BZ |
1080 | /* fill Number of repetitions. */ |
1081 | if (Category == CATEGORY_RM) | |
1082 | { | |
1083 | MakeOutgoingFrame((pOutBuffer+*pFrameLen), &TempLen, | |
1084 | 2, &NumOfRepetitions, | |
1085 | END_OF_ARGS); | |
91980990 | 1086 | |
ca97b838 BZ |
1087 | *pFrameLen += TempLen; |
1088 | } | |
91980990 GKH |
1089 | |
1090 | // prepare Measurement IE. | |
1091 | NdisZeroMemory(&MeasureReqIE, sizeof(MEASURE_REQ_INFO)); | |
ca97b838 | 1092 | MeasureReqIE.Token = MeasureToken; |
91980990 GKH |
1093 | MeasureReqIE.ReqMode.word = MeasureReqMode; |
1094 | MeasureReqIE.ReqType = MeasureReqType; | |
ca97b838 BZ |
1095 | InsertMeasureReqIE(pAd, (pOutBuffer+*pFrameLen), pFrameLen, |
1096 | TotalLen, &MeasureReqIE); | |
91980990 GKH |
1097 | |
1098 | return; | |
1099 | } | |
1100 | ||
1101 | /* | |
1102 | ========================================================================== | |
1103 | Description: | |
1104 | Prepare Measurement report action frame and enqueue it into | |
1105 | management queue waiting for transmition. | |
1106 | ||
1107 | Parametrs: | |
1108 | 1. the destination mac address of the frame. | |
1109 | ||
1110 | Return : None. | |
1111 | ========================================================================== | |
1112 | */ | |
1113 | VOID EnqueueMeasurementRep( | |
1114 | IN PRTMP_ADAPTER pAd, | |
1115 | IN PUCHAR pDA, | |
1116 | IN UINT8 DialogToken, | |
1117 | IN UINT8 MeasureToken, | |
1118 | IN UINT8 MeasureReqMode, | |
1119 | IN UINT8 MeasureReqType, | |
1120 | IN UINT8 ReportInfoLen, | |
1121 | IN PUINT8 pReportInfo) | |
1122 | { | |
1123 | PUCHAR pOutBuffer = NULL; | |
1124 | NDIS_STATUS NStatus; | |
1125 | ULONG FrameLen; | |
1126 | HEADER_802_11 ActHdr; | |
1127 | MEASURE_REPORT_INFO MeasureRepIE; | |
1128 | ||
1129 | // build action frame header. | |
1130 | MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA, | |
1131 | pAd->CurrentAddress); | |
1132 | ||
1133 | NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory | |
1134 | if(NStatus != NDIS_STATUS_SUCCESS) | |
1135 | { | |
d599edca | 1136 | DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __func__)); |
91980990 GKH |
1137 | return; |
1138 | } | |
1139 | NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11)); | |
1140 | FrameLen = sizeof(HEADER_802_11); | |
1141 | ||
1142 | InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_MRP); | |
1143 | ||
1144 | // fill Dialog Token | |
1145 | InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken); | |
1146 | ||
1147 | // prepare Measurement IE. | |
1148 | NdisZeroMemory(&MeasureRepIE, sizeof(MEASURE_REPORT_INFO)); | |
1149 | MeasureRepIE.Token = MeasureToken; | |
ca97b838 | 1150 | MeasureRepIE.ReportMode = MeasureReqMode; |
91980990 GKH |
1151 | MeasureRepIE.ReportType = MeasureReqType; |
1152 | InsertMeasureReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureRepIE, ReportInfoLen, pReportInfo); | |
1153 | ||
1154 | MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); | |
1155 | MlmeFreeMemory(pAd, pOutBuffer); | |
1156 | ||
1157 | return; | |
1158 | } | |
1159 | ||
1160 | /* | |
1161 | ========================================================================== | |
1162 | Description: | |
1163 | Prepare TPC Request action frame and enqueue it into | |
1164 | management queue waiting for transmition. | |
1165 | ||
1166 | Parametrs: | |
1167 | 1. the destination mac address of the frame. | |
1168 | ||
1169 | Return : None. | |
1170 | ========================================================================== | |
1171 | */ | |
1172 | VOID EnqueueTPCReq( | |
1173 | IN PRTMP_ADAPTER pAd, | |
1174 | IN PUCHAR pDA, | |
1175 | IN UCHAR DialogToken) | |
1176 | { | |
1177 | PUCHAR pOutBuffer = NULL; | |
1178 | NDIS_STATUS NStatus; | |
1179 | ULONG FrameLen; | |
1180 | ||
1181 | HEADER_802_11 ActHdr; | |
1182 | ||
1183 | // build action frame header. | |
1184 | MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA, | |
1185 | pAd->CurrentAddress); | |
1186 | ||
1187 | NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory | |
1188 | if(NStatus != NDIS_STATUS_SUCCESS) | |
1189 | { | |
d599edca | 1190 | DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __func__)); |
91980990 GKH |
1191 | return; |
1192 | } | |
1193 | NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11)); | |
1194 | FrameLen = sizeof(HEADER_802_11); | |
1195 | ||
1196 | InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_TPCRQ); | |
1197 | ||
1198 | // fill Dialog Token | |
1199 | InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken); | |
1200 | ||
1201 | // Insert TPC Request IE. | |
1202 | InsertTpcReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen); | |
1203 | ||
1204 | MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); | |
1205 | MlmeFreeMemory(pAd, pOutBuffer); | |
1206 | ||
1207 | return; | |
1208 | } | |
1209 | ||
1210 | /* | |
1211 | ========================================================================== | |
1212 | Description: | |
1213 | Prepare TPC Report action frame and enqueue it into | |
1214 | management queue waiting for transmition. | |
1215 | ||
1216 | Parametrs: | |
1217 | 1. the destination mac address of the frame. | |
1218 | ||
1219 | Return : None. | |
1220 | ========================================================================== | |
1221 | */ | |
1222 | VOID EnqueueTPCRep( | |
1223 | IN PRTMP_ADAPTER pAd, | |
1224 | IN PUCHAR pDA, | |
1225 | IN UINT8 DialogToken, | |
1226 | IN UINT8 TxPwr, | |
1227 | IN UINT8 LinkMargin) | |
1228 | { | |
1229 | PUCHAR pOutBuffer = NULL; | |
1230 | NDIS_STATUS NStatus; | |
1231 | ULONG FrameLen; | |
1232 | ||
1233 | HEADER_802_11 ActHdr; | |
1234 | ||
1235 | // build action frame header. | |
1236 | MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA, | |
1237 | pAd->CurrentAddress); | |
1238 | ||
1239 | NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory | |
1240 | if(NStatus != NDIS_STATUS_SUCCESS) | |
1241 | { | |
d599edca | 1242 | DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __func__)); |
91980990 GKH |
1243 | return; |
1244 | } | |
1245 | NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11)); | |
1246 | FrameLen = sizeof(HEADER_802_11); | |
1247 | ||
1248 | InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_TPCRP); | |
1249 | ||
1250 | // fill Dialog Token | |
1251 | InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken); | |
1252 | ||
1253 | // Insert TPC Request IE. | |
1254 | InsertTpcReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, TxPwr, LinkMargin); | |
1255 | ||
1256 | MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); | |
1257 | MlmeFreeMemory(pAd, pOutBuffer); | |
1258 | ||
1259 | return; | |
1260 | } | |
1261 | ||
1262 | /* | |
1263 | ========================================================================== | |
1264 | Description: | |
1265 | Prepare Channel Switch Announcement action frame and enqueue it into | |
1266 | management queue waiting for transmition. | |
1267 | ||
1268 | Parametrs: | |
1269 | 1. the destination mac address of the frame. | |
1270 | 2. Channel switch announcement mode. | |
1271 | 2. a New selected channel. | |
1272 | ||
1273 | Return : None. | |
1274 | ========================================================================== | |
1275 | */ | |
1276 | VOID EnqueueChSwAnn( | |
1277 | IN PRTMP_ADAPTER pAd, | |
1278 | IN PUCHAR pDA, | |
1279 | IN UINT8 ChSwMode, | |
1280 | IN UINT8 NewCh) | |
1281 | { | |
1282 | PUCHAR pOutBuffer = NULL; | |
1283 | NDIS_STATUS NStatus; | |
1284 | ULONG FrameLen; | |
1285 | ||
1286 | HEADER_802_11 ActHdr; | |
1287 | ||
1288 | // build action frame header. | |
1289 | MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA, | |
1290 | pAd->CurrentAddress); | |
1291 | ||
1292 | NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory | |
1293 | if(NStatus != NDIS_STATUS_SUCCESS) | |
1294 | { | |
d599edca | 1295 | DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __func__)); |
91980990 GKH |
1296 | return; |
1297 | } | |
1298 | NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11)); | |
1299 | FrameLen = sizeof(HEADER_802_11); | |
1300 | ||
1301 | InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_CHANNEL_SWITCH); | |
1302 | ||
1303 | InsertChSwAnnIE(pAd, (pOutBuffer + FrameLen), &FrameLen, ChSwMode, NewCh, 0); | |
1304 | ||
1305 | MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); | |
1306 | MlmeFreeMemory(pAd, pOutBuffer); | |
1307 | ||
1308 | return; | |
1309 | } | |
1310 | ||
1311 | static BOOLEAN DfsRequirementCheck( | |
1312 | IN PRTMP_ADAPTER pAd, | |
1313 | IN UINT8 Channel) | |
1314 | { | |
1315 | BOOLEAN Result = FALSE; | |
1316 | INT i; | |
1317 | ||
1318 | do | |
1319 | { | |
1320 | // check DFS procedure is running. | |
1321 | // make sure DFS procedure won't start twice. | |
1322 | if (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE) | |
1323 | { | |
1324 | Result = FALSE; | |
1325 | break; | |
1326 | } | |
1327 | ||
1328 | // check the new channel carried from Channel Switch Announcemnet is valid. | |
1329 | for (i=0; i<pAd->ChannelListNum; i++) | |
1330 | { | |
1331 | if ((Channel == pAd->ChannelList[i].Channel) | |
1332 | &&(pAd->ChannelList[i].RemainingTimeForUse == 0)) | |
1333 | { | |
1334 | // found radar signal in the channel. the channel can't use at least for 30 minutes. | |
1335 | pAd->ChannelList[i].RemainingTimeForUse = 1800;//30 min = 1800 sec | |
1336 | Result = TRUE; | |
1337 | break; | |
1338 | } | |
1339 | } | |
1340 | } while(FALSE); | |
1341 | ||
1342 | return Result; | |
1343 | } | |
1344 | ||
1345 | VOID NotifyChSwAnnToPeerAPs( | |
1346 | IN PRTMP_ADAPTER pAd, | |
1347 | IN PUCHAR pRA, | |
1348 | IN PUCHAR pTA, | |
1349 | IN UINT8 ChSwMode, | |
1350 | IN UINT8 Channel) | |
1351 | { | |
91980990 GKH |
1352 | } |
1353 | ||
1354 | static VOID StartDFSProcedure( | |
1355 | IN PRTMP_ADAPTER pAd, | |
1356 | IN UCHAR Channel, | |
1357 | IN UINT8 ChSwMode) | |
1358 | { | |
1359 | // start DFS procedure | |
1360 | pAd->CommonCfg.Channel = Channel; | |
1623267a | 1361 | |
91980990 | 1362 | N_ChannelCheck(pAd); |
1623267a | 1363 | |
91980990 GKH |
1364 | pAd->CommonCfg.RadarDetect.RDMode = RD_SWITCHING_MODE; |
1365 | pAd->CommonCfg.RadarDetect.CSCount = 0; | |
1366 | } | |
1367 | ||
1368 | /* | |
1369 | ========================================================================== | |
1370 | Description: | |
1371 | Channel Switch Announcement action frame sanity check. | |
1372 | ||
1373 | Parametrs: | |
1374 | 1. MLME message containing the received frame | |
1375 | 2. message length. | |
1376 | 3. Channel switch announcement infomation buffer. | |
1377 | ||
1378 | ||
1379 | Return : None. | |
1380 | ========================================================================== | |
1381 | */ | |
1382 | ||
1383 | /* | |
1384 | Channel Switch Announcement IE. | |
1385 | +----+-----+-----------+------------+-----------+ | |
1386 | | ID | Len |Ch Sw Mode | New Ch Num | Ch Sw Cnt | | |
1387 | +----+-----+-----------+------------+-----------+ | |
1388 | 1 1 1 1 1 | |
1389 | */ | |
1390 | static BOOLEAN PeerChSwAnnSanity( | |
1391 | IN PRTMP_ADAPTER pAd, | |
1392 | IN VOID *pMsg, | |
1393 | IN ULONG MsgLen, | |
1394 | OUT PCH_SW_ANN_INFO pChSwAnnInfo) | |
1395 | { | |
1396 | PFRAME_802_11 Fr = (PFRAME_802_11)pMsg; | |
1397 | PUCHAR pFramePtr = Fr->Octet; | |
1398 | BOOLEAN result = FALSE; | |
1399 | PEID_STRUCT eid_ptr; | |
1400 | ||
1401 | // skip 802.11 header. | |
1402 | MsgLen -= sizeof(HEADER_802_11); | |
1403 | ||
1404 | // skip category and action code. | |
1405 | pFramePtr += 2; | |
1406 | MsgLen -= 2; | |
1407 | ||
1408 | if (pChSwAnnInfo == NULL) | |
1409 | return result; | |
1410 | ||
1411 | eid_ptr = (PEID_STRUCT)pFramePtr; | |
1412 | while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen)) | |
1413 | { | |
1414 | switch(eid_ptr->Eid) | |
1415 | { | |
1416 | case IE_CHANNEL_SWITCH_ANNOUNCEMENT: | |
1417 | NdisMoveMemory(&pChSwAnnInfo->ChSwMode, eid_ptr->Octet, 1); | |
1418 | NdisMoveMemory(&pChSwAnnInfo->Channel, eid_ptr->Octet + 1, 1); | |
1419 | NdisMoveMemory(&pChSwAnnInfo->ChSwCnt, eid_ptr->Octet + 2, 1); | |
1420 | ||
1421 | result = TRUE; | |
1422 | break; | |
1423 | ||
1424 | default: | |
1425 | break; | |
1426 | } | |
1427 | eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len); | |
1428 | } | |
1429 | ||
1430 | return result; | |
1431 | } | |
1432 | ||
1433 | /* | |
1434 | ========================================================================== | |
1435 | Description: | |
1436 | Measurement request action frame sanity check. | |
1437 | ||
1438 | Parametrs: | |
1439 | 1. MLME message containing the received frame | |
1440 | 2. message length. | |
1441 | 3. Measurement request infomation buffer. | |
1442 | ||
1443 | Return : None. | |
1444 | ========================================================================== | |
1445 | */ | |
1446 | static BOOLEAN PeerMeasureReqSanity( | |
1447 | IN PRTMP_ADAPTER pAd, | |
1448 | IN VOID *pMsg, | |
1449 | IN ULONG MsgLen, | |
1450 | OUT PUINT8 pDialogToken, | |
ca97b838 BZ |
1451 | OUT PMEASURE_REQ_INFO pMeasureReqInfo, |
1452 | OUT PMEASURE_REQ pMeasureReq) | |
91980990 GKH |
1453 | { |
1454 | PFRAME_802_11 Fr = (PFRAME_802_11)pMsg; | |
1455 | PUCHAR pFramePtr = Fr->Octet; | |
1456 | BOOLEAN result = FALSE; | |
1457 | PEID_STRUCT eid_ptr; | |
1458 | PUCHAR ptr; | |
1459 | UINT64 MeasureStartTime; | |
1460 | UINT16 MeasureDuration; | |
1461 | ||
1462 | // skip 802.11 header. | |
1463 | MsgLen -= sizeof(HEADER_802_11); | |
1464 | ||
1465 | // skip category and action code. | |
1466 | pFramePtr += 2; | |
1467 | MsgLen -= 2; | |
1468 | ||
1469 | if (pMeasureReqInfo == NULL) | |
1470 | return result; | |
1471 | ||
1472 | NdisMoveMemory(pDialogToken, pFramePtr, 1); | |
1473 | pFramePtr += 1; | |
1474 | MsgLen -= 1; | |
1475 | ||
1476 | eid_ptr = (PEID_STRUCT)pFramePtr; | |
1477 | while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen)) | |
1478 | { | |
1479 | switch(eid_ptr->Eid) | |
1480 | { | |
1481 | case IE_MEASUREMENT_REQUEST: | |
1482 | NdisMoveMemory(&pMeasureReqInfo->Token, eid_ptr->Octet, 1); | |
1483 | NdisMoveMemory(&pMeasureReqInfo->ReqMode.word, eid_ptr->Octet + 1, 1); | |
1484 | NdisMoveMemory(&pMeasureReqInfo->ReqType, eid_ptr->Octet + 2, 1); | |
ca97b838 BZ |
1485 | ptr = (PUCHAR)(eid_ptr->Octet + 3); |
1486 | NdisMoveMemory(&pMeasureReq->ChNum, ptr, 1); | |
91980990 | 1487 | NdisMoveMemory(&MeasureStartTime, ptr + 1, 8); |
ca97b838 | 1488 | pMeasureReq->MeasureStartTime = SWAP64(MeasureStartTime); |
91980990 | 1489 | NdisMoveMemory(&MeasureDuration, ptr + 9, 2); |
ca97b838 | 1490 | pMeasureReq->MeasureDuration = SWAP16(MeasureDuration); |
91980990 GKH |
1491 | |
1492 | result = TRUE; | |
1493 | break; | |
1494 | ||
1495 | default: | |
1496 | break; | |
1497 | } | |
1498 | eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len); | |
1499 | } | |
1500 | ||
1501 | return result; | |
1502 | } | |
1503 | ||
1504 | /* | |
1505 | ========================================================================== | |
1506 | Description: | |
1507 | Measurement report action frame sanity check. | |
1508 | ||
1509 | Parametrs: | |
1510 | 1. MLME message containing the received frame | |
1511 | 2. message length. | |
1512 | 3. Measurement report infomation buffer. | |
1513 | 4. basic report infomation buffer. | |
1514 | ||
1515 | Return : None. | |
1516 | ========================================================================== | |
1517 | */ | |
1518 | ||
1519 | /* | |
1520 | Measurement Report IE. | |
1521 | +----+-----+-------+-------------+--------------+----------------+ | |
1522 | | ID | Len | Token | Report Mode | Measure Type | Measure Report | | |
1523 | +----+-----+-------+-------------+--------------+----------------+ | |
1524 | 1 1 1 1 1 variable | |
1525 | ||
1526 | Basic Report. | |
1527 | +--------+------------+----------+-----+ | |
1528 | | Ch Num | Start Time | Duration | Map | | |
1529 | +--------+------------+----------+-----+ | |
1530 | 1 8 2 1 | |
1531 | ||
1532 | Map Field Bit Format. | |
1533 | +-----+---------------+---------------------+-------+------------+----------+ | |
1534 | | Bss | OFDM Preamble | Unidentified signal | Radar | Unmeasured | Reserved | | |
1535 | +-----+---------------+---------------------+-------+------------+----------+ | |
1536 | 0 1 2 3 4 5-7 | |
1537 | */ | |
1538 | static BOOLEAN PeerMeasureReportSanity( | |
1539 | IN PRTMP_ADAPTER pAd, | |
1540 | IN VOID *pMsg, | |
1541 | IN ULONG MsgLen, | |
1542 | OUT PUINT8 pDialogToken, | |
1543 | OUT PMEASURE_REPORT_INFO pMeasureReportInfo, | |
1544 | OUT PUINT8 pReportBuf) | |
1545 | { | |
1546 | PFRAME_802_11 Fr = (PFRAME_802_11)pMsg; | |
1547 | PUCHAR pFramePtr = Fr->Octet; | |
1548 | BOOLEAN result = FALSE; | |
1549 | PEID_STRUCT eid_ptr; | |
1550 | PUCHAR ptr; | |
1551 | ||
1552 | // skip 802.11 header. | |
1553 | MsgLen -= sizeof(HEADER_802_11); | |
1554 | ||
1555 | // skip category and action code. | |
1556 | pFramePtr += 2; | |
1557 | MsgLen -= 2; | |
1558 | ||
1559 | if (pMeasureReportInfo == NULL) | |
1560 | return result; | |
1561 | ||
1562 | NdisMoveMemory(pDialogToken, pFramePtr, 1); | |
1563 | pFramePtr += 1; | |
1564 | MsgLen -= 1; | |
1565 | ||
1566 | eid_ptr = (PEID_STRUCT)pFramePtr; | |
1567 | while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen)) | |
1568 | { | |
1569 | switch(eid_ptr->Eid) | |
1570 | { | |
1571 | case IE_MEASUREMENT_REPORT: | |
1572 | NdisMoveMemory(&pMeasureReportInfo->Token, eid_ptr->Octet, 1); | |
1573 | NdisMoveMemory(&pMeasureReportInfo->ReportMode, eid_ptr->Octet + 1, 1); | |
1574 | NdisMoveMemory(&pMeasureReportInfo->ReportType, eid_ptr->Octet + 2, 1); | |
1575 | if (pMeasureReportInfo->ReportType == RM_BASIC) | |
1576 | { | |
1577 | PMEASURE_BASIC_REPORT pReport = (PMEASURE_BASIC_REPORT)pReportBuf; | |
ca97b838 | 1578 | ptr = (PUCHAR)(eid_ptr->Octet + 3); |
91980990 GKH |
1579 | NdisMoveMemory(&pReport->ChNum, ptr, 1); |
1580 | NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8); | |
1581 | NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2); | |
1582 | NdisMoveMemory(&pReport->Map, ptr + 11, 1); | |
1583 | ||
1584 | } | |
1585 | else if (pMeasureReportInfo->ReportType == RM_CCA) | |
1586 | { | |
1587 | PMEASURE_CCA_REPORT pReport = (PMEASURE_CCA_REPORT)pReportBuf; | |
ca97b838 | 1588 | ptr = (PUCHAR)(eid_ptr->Octet + 3); |
91980990 GKH |
1589 | NdisMoveMemory(&pReport->ChNum, ptr, 1); |
1590 | NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8); | |
1591 | NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2); | |
1592 | NdisMoveMemory(&pReport->CCA_Busy_Fraction, ptr + 11, 1); | |
1593 | ||
1594 | } | |
1595 | else if (pMeasureReportInfo->ReportType == RM_RPI_HISTOGRAM) | |
1596 | { | |
1597 | PMEASURE_RPI_REPORT pReport = (PMEASURE_RPI_REPORT)pReportBuf; | |
ca97b838 | 1598 | ptr = (PUCHAR)(eid_ptr->Octet + 3); |
91980990 GKH |
1599 | NdisMoveMemory(&pReport->ChNum, ptr, 1); |
1600 | NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8); | |
1601 | NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2); | |
1602 | NdisMoveMemory(&pReport->RPI_Density, ptr + 11, 8); | |
1603 | } | |
1604 | result = TRUE; | |
1605 | break; | |
1606 | ||
1607 | default: | |
1608 | break; | |
1609 | } | |
1610 | eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len); | |
1611 | } | |
1612 | ||
1613 | return result; | |
1614 | } | |
1615 | ||
1616 | /* | |
1617 | ========================================================================== | |
1618 | Description: | |
1619 | TPC Request action frame sanity check. | |
1620 | ||
1621 | Parametrs: | |
1622 | 1. MLME message containing the received frame | |
1623 | 2. message length. | |
1624 | 3. Dialog Token. | |
1625 | ||
1626 | Return : None. | |
1627 | ========================================================================== | |
1628 | */ | |
1629 | static BOOLEAN PeerTpcReqSanity( | |
1630 | IN PRTMP_ADAPTER pAd, | |
1631 | IN VOID *pMsg, | |
1632 | IN ULONG MsgLen, | |
1633 | OUT PUINT8 pDialogToken) | |
1634 | { | |
1635 | PFRAME_802_11 Fr = (PFRAME_802_11)pMsg; | |
1636 | PUCHAR pFramePtr = Fr->Octet; | |
1637 | BOOLEAN result = FALSE; | |
1638 | PEID_STRUCT eid_ptr; | |
1639 | ||
1640 | MsgLen -= sizeof(HEADER_802_11); | |
1641 | ||
1642 | // skip category and action code. | |
1643 | pFramePtr += 2; | |
1644 | MsgLen -= 2; | |
1645 | ||
1646 | if (pDialogToken == NULL) | |
1647 | return result; | |
1648 | ||
1649 | NdisMoveMemory(pDialogToken, pFramePtr, 1); | |
1650 | pFramePtr += 1; | |
1651 | MsgLen -= 1; | |
1652 | ||
1653 | eid_ptr = (PEID_STRUCT)pFramePtr; | |
1654 | while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen)) | |
1655 | { | |
1656 | switch(eid_ptr->Eid) | |
1657 | { | |
1658 | case IE_TPC_REQUEST: | |
1659 | result = TRUE; | |
1660 | break; | |
1661 | ||
1662 | default: | |
1663 | break; | |
1664 | } | |
1665 | eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len); | |
1666 | } | |
1667 | ||
1668 | return result; | |
1669 | } | |
1670 | ||
1671 | /* | |
1672 | ========================================================================== | |
1673 | Description: | |
1674 | TPC Report action frame sanity check. | |
1675 | ||
1676 | Parametrs: | |
1677 | 1. MLME message containing the received frame | |
1678 | 2. message length. | |
1679 | 3. Dialog Token. | |
1680 | 4. TPC Report IE. | |
1681 | ||
1682 | Return : None. | |
1683 | ========================================================================== | |
1684 | */ | |
1685 | static BOOLEAN PeerTpcRepSanity( | |
1686 | IN PRTMP_ADAPTER pAd, | |
1687 | IN VOID *pMsg, | |
1688 | IN ULONG MsgLen, | |
1689 | OUT PUINT8 pDialogToken, | |
1690 | OUT PTPC_REPORT_INFO pTpcRepInfo) | |
1691 | { | |
1692 | PFRAME_802_11 Fr = (PFRAME_802_11)pMsg; | |
1693 | PUCHAR pFramePtr = Fr->Octet; | |
1694 | BOOLEAN result = FALSE; | |
1695 | PEID_STRUCT eid_ptr; | |
1696 | ||
1697 | MsgLen -= sizeof(HEADER_802_11); | |
1698 | ||
1699 | // skip category and action code. | |
1700 | pFramePtr += 2; | |
1701 | MsgLen -= 2; | |
1702 | ||
1703 | if (pDialogToken == NULL) | |
1704 | return result; | |
1705 | ||
1706 | NdisMoveMemory(pDialogToken, pFramePtr, 1); | |
1707 | pFramePtr += 1; | |
1708 | MsgLen -= 1; | |
1709 | ||
1710 | eid_ptr = (PEID_STRUCT)pFramePtr; | |
1711 | while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen)) | |
1712 | { | |
1713 | switch(eid_ptr->Eid) | |
1714 | { | |
1715 | case IE_TPC_REPORT: | |
1716 | NdisMoveMemory(&pTpcRepInfo->TxPwr, eid_ptr->Octet, 1); | |
1717 | NdisMoveMemory(&pTpcRepInfo->LinkMargin, eid_ptr->Octet + 1, 1); | |
1718 | result = TRUE; | |
1719 | break; | |
1720 | ||
1721 | default: | |
1722 | break; | |
1723 | } | |
1724 | eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len); | |
1725 | } | |
1726 | ||
1727 | return result; | |
1728 | } | |
1729 | ||
1730 | /* | |
1731 | ========================================================================== | |
1732 | Description: | |
1733 | Channel Switch Announcement action frame handler. | |
1734 | ||
1735 | Parametrs: | |
1736 | Elme - MLME message containing the received frame | |
1737 | ||
1738 | Return : None. | |
1739 | ========================================================================== | |
1740 | */ | |
1741 | static VOID PeerChSwAnnAction( | |
1742 | IN PRTMP_ADAPTER pAd, | |
1743 | IN MLME_QUEUE_ELEM *Elem) | |
1744 | { | |
1745 | CH_SW_ANN_INFO ChSwAnnInfo; | |
1746 | PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg; | |
91980990 GKH |
1747 | UCHAR index = 0, Channel = 0, NewChannel = 0; |
1748 | ULONG Bssidx = 0; | |
91980990 GKH |
1749 | |
1750 | NdisZeroMemory(&ChSwAnnInfo, sizeof(CH_SW_ANN_INFO)); | |
1751 | if (! PeerChSwAnnSanity(pAd, Elem->Msg, Elem->MsgLen, &ChSwAnnInfo)) | |
1752 | { | |
1753 | DBGPRINT(RT_DEBUG_TRACE, ("Invalid Channel Switch Action Frame.\n")); | |
1754 | return; | |
1755 | } | |
1756 | ||
91980990 GKH |
1757 | if (pAd->OpMode == OPMODE_STA) |
1758 | { | |
1759 | Bssidx = BssTableSearch(&pAd->ScanTab, pFr->Hdr.Addr3, pAd->CommonCfg.Channel); | |
1760 | if (Bssidx == BSS_NOT_FOUND) | |
1761 | { | |
1762 | DBGPRINT(RT_DEBUG_TRACE, ("PeerChSwAnnAction - Bssidx is not found\n")); | |
1763 | return; | |
1764 | } | |
1765 | ||
1766 | DBGPRINT(RT_DEBUG_TRACE, ("\n****Bssidx is %d, Channel = %d\n", index, pAd->ScanTab.BssEntry[Bssidx].Channel)); | |
1767 | hex_dump("SSID",pAd->ScanTab.BssEntry[Bssidx].Bssid ,6); | |
1768 | ||
1769 | Channel = pAd->CommonCfg.Channel; | |
1770 | NewChannel = ChSwAnnInfo.Channel; | |
1771 | ||
1772 | if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel)) | |
1773 | { | |
1774 | // Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection). | |
1775 | // In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results. | |
1776 | AsicSwitchChannel(pAd, 1, FALSE); | |
1777 | AsicLockChannel(pAd, 1); | |
1778 | LinkDown(pAd, FALSE); | |
1779 | MlmeQueueInit(&pAd->Mlme.Queue); | |
1780 | BssTableInit(&pAd->ScanTab); | |
1781 | RTMPusecDelay(1000000); // use delay to prevent STA do reassoc | |
1782 | ||
1783 | // channel sanity check | |
1784 | for (index = 0 ; index < pAd->ChannelListNum; index++) | |
1785 | { | |
1786 | if (pAd->ChannelList[index].Channel == NewChannel) | |
1787 | { | |
1788 | pAd->ScanTab.BssEntry[Bssidx].Channel = NewChannel; | |
1789 | pAd->CommonCfg.Channel = NewChannel; | |
1790 | AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); | |
1791 | AsicLockChannel(pAd, pAd->CommonCfg.Channel); | |
1792 | DBGPRINT(RT_DEBUG_TRACE, ("&&&&&&&&&&&&&&&&PeerChSwAnnAction - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel)); | |
1793 | break; | |
1794 | } | |
1795 | } | |
1796 | ||
1797 | if (index >= pAd->ChannelListNum) | |
1798 | { | |
1799 | DBGPRINT_ERR(("&&&&&&&&&&&&&&&&&&&&&&&&&&PeerChSwAnnAction(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum)); | |
1800 | } | |
1801 | } | |
1802 | } | |
91980990 GKH |
1803 | |
1804 | return; | |
1805 | } | |
1806 | ||
1807 | ||
1808 | /* | |
1809 | ========================================================================== | |
1810 | Description: | |
1811 | Measurement Request action frame handler. | |
1812 | ||
1813 | Parametrs: | |
1814 | Elme - MLME message containing the received frame | |
1815 | ||
1816 | Return : None. | |
1817 | ========================================================================== | |
1818 | */ | |
1819 | static VOID PeerMeasureReqAction( | |
1820 | IN PRTMP_ADAPTER pAd, | |
1821 | IN MLME_QUEUE_ELEM *Elem) | |
1822 | { | |
1823 | PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg; | |
1824 | UINT8 DialogToken; | |
1825 | MEASURE_REQ_INFO MeasureReqInfo; | |
ca97b838 | 1826 | MEASURE_REQ MeasureReq; |
91980990 GKH |
1827 | MEASURE_REPORT_MODE ReportMode; |
1828 | ||
ca97b838 | 1829 | if(PeerMeasureReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReqInfo, &MeasureReq)) |
91980990 GKH |
1830 | { |
1831 | ReportMode.word = 0; | |
1832 | ReportMode.field.Incapable = 1; | |
1833 | EnqueueMeasurementRep(pAd, pFr->Hdr.Addr2, DialogToken, MeasureReqInfo.Token, ReportMode.word, MeasureReqInfo.ReqType, 0, NULL); | |
1834 | } | |
1835 | ||
1836 | return; | |
1837 | } | |
1838 | ||
1839 | /* | |
1840 | ========================================================================== | |
1841 | Description: | |
1842 | Measurement Report action frame handler. | |
1843 | ||
1844 | Parametrs: | |
1845 | Elme - MLME message containing the received frame | |
1846 | ||
1847 | Return : None. | |
1848 | ========================================================================== | |
1849 | */ | |
1850 | static VOID PeerMeasureReportAction( | |
1851 | IN PRTMP_ADAPTER pAd, | |
1852 | IN MLME_QUEUE_ELEM *Elem) | |
1853 | { | |
1854 | MEASURE_REPORT_INFO MeasureReportInfo; | |
1855 | PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg; | |
1856 | UINT8 DialogToken; | |
1857 | PUINT8 pMeasureReportInfo; | |
1858 | ||
1859 | // if (pAd->CommonCfg.bIEEE80211H != TRUE) | |
1860 | // return; | |
1861 | ||
1862 | if ((pMeasureReportInfo = kmalloc(sizeof(MEASURE_RPI_REPORT), GFP_ATOMIC)) == NULL) | |
1863 | { | |
f4b44e76 | 1864 | DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%zu).\n", __func__, sizeof(MEASURE_RPI_REPORT))); |
91980990 GKH |
1865 | return; |
1866 | } | |
1867 | ||
1868 | NdisZeroMemory(&MeasureReportInfo, sizeof(MEASURE_REPORT_INFO)); | |
1869 | NdisZeroMemory(pMeasureReportInfo, sizeof(MEASURE_RPI_REPORT)); | |
1870 | if (PeerMeasureReportSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReportInfo, pMeasureReportInfo)) | |
1871 | { | |
1872 | do { | |
1873 | PMEASURE_REQ_ENTRY pEntry = NULL; | |
1874 | ||
1875 | // Not a autonomous measure report. | |
1876 | // check the dialog token field. drop it if the dialog token doesn't match. | |
1877 | if ((DialogToken != 0) | |
1878 | && ((pEntry = MeasureReqLookUp(pAd, DialogToken)) == NULL)) | |
1879 | break; | |
1880 | ||
1881 | if (pEntry != NULL) | |
1882 | MeasureReqDelete(pAd, pEntry->DialogToken); | |
1883 | ||
1884 | if (MeasureReportInfo.ReportType == RM_BASIC) | |
1885 | { | |
1886 | PMEASURE_BASIC_REPORT pBasicReport = (PMEASURE_BASIC_REPORT)pMeasureReportInfo; | |
1887 | if ((pBasicReport->Map.field.Radar) | |
1888 | && (DfsRequirementCheck(pAd, pBasicReport->ChNum) == TRUE)) | |
1889 | { | |
1890 | NotifyChSwAnnToPeerAPs(pAd, pFr->Hdr.Addr1, pFr->Hdr.Addr2, 1, pBasicReport->ChNum); | |
1891 | StartDFSProcedure(pAd, pBasicReport->ChNum, 1); | |
1892 | } | |
1893 | } | |
1894 | } while (FALSE); | |
1895 | } | |
1896 | else | |
1897 | DBGPRINT(RT_DEBUG_TRACE, ("Invalid Measurement Report Frame.\n")); | |
1898 | ||
1899 | kfree(pMeasureReportInfo); | |
1900 | ||
1901 | return; | |
1902 | } | |
1903 | ||
1904 | /* | |
1905 | ========================================================================== | |
1906 | Description: | |
1907 | TPC Request action frame handler. | |
1908 | ||
1909 | Parametrs: | |
1910 | Elme - MLME message containing the received frame | |
1911 | ||
1912 | Return : None. | |
1913 | ========================================================================== | |
1914 | */ | |
1915 | static VOID PeerTpcReqAction( | |
1916 | IN PRTMP_ADAPTER pAd, | |
1917 | IN MLME_QUEUE_ELEM *Elem) | |
1918 | { | |
1919 | PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg; | |
1920 | PUCHAR pFramePtr = pFr->Octet; | |
1921 | UINT8 DialogToken; | |
1922 | UINT8 TxPwr = GetCurTxPwr(pAd, Elem->Wcid); | |
1923 | UINT8 LinkMargin = 0; | |
1924 | CHAR RealRssi; | |
1925 | ||
1926 | // link margin: Ratio of the received signal power to the minimum desired by the station (STA). The | |
1927 | // STA may incorporate rate information and channel conditions, including interference, into its computation | |
1928 | // of link margin. | |
1929 | ||
1930 | RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), | |
1931 | ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), | |
1932 | ConvertToRssi(pAd, Elem->Rssi2, RSSI_2)); | |
1933 | ||
1934 | // skip Category and action code. | |
1935 | pFramePtr += 2; | |
1936 | ||
1937 | // Dialog token. | |
1938 | NdisMoveMemory(&DialogToken, pFramePtr, 1); | |
1939 | ||
1940 | LinkMargin = (RealRssi / MIN_RCV_PWR); | |
1941 | if (PeerTpcReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken)) | |
1942 | EnqueueTPCRep(pAd, pFr->Hdr.Addr2, DialogToken, TxPwr, LinkMargin); | |
1943 | ||
1944 | return; | |
1945 | } | |
1946 | ||
1947 | /* | |
1948 | ========================================================================== | |
1949 | Description: | |
1950 | TPC Report action frame handler. | |
1951 | ||
1952 | Parametrs: | |
1953 | Elme - MLME message containing the received frame | |
1954 | ||
1955 | Return : None. | |
1956 | ========================================================================== | |
1957 | */ | |
1958 | static VOID PeerTpcRepAction( | |
1959 | IN PRTMP_ADAPTER pAd, | |
1960 | IN MLME_QUEUE_ELEM *Elem) | |
1961 | { | |
1962 | UINT8 DialogToken; | |
1963 | TPC_REPORT_INFO TpcRepInfo; | |
1964 | PTPC_REQ_ENTRY pEntry = NULL; | |
1965 | ||
1966 | NdisZeroMemory(&TpcRepInfo, sizeof(TPC_REPORT_INFO)); | |
1967 | if (PeerTpcRepSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &TpcRepInfo)) | |
1968 | { | |
1969 | if ((pEntry = TpcReqLookUp(pAd, DialogToken)) != NULL) | |
1970 | { | |
1971 | TpcReqDelete(pAd, pEntry->DialogToken); | |
1972 | DBGPRINT(RT_DEBUG_TRACE, ("%s: DialogToken=%x, TxPwr=%d, LinkMargin=%d\n", | |
d599edca | 1973 | __func__, DialogToken, TpcRepInfo.TxPwr, TpcRepInfo.LinkMargin)); |
91980990 GKH |
1974 | } |
1975 | } | |
1976 | ||
1977 | return; | |
1978 | } | |
1979 | ||
1980 | /* | |
1981 | ========================================================================== | |
1982 | Description: | |
1983 | Spectrun action frames Handler such as channel switch annoucement, | |
1984 | measurement report, measurement request actions frames. | |
1985 | ||
1986 | Parametrs: | |
1987 | Elme - MLME message containing the received frame | |
1988 | ||
1989 | Return : None. | |
1990 | ========================================================================== | |
1991 | */ | |
1992 | VOID PeerSpectrumAction( | |
1993 | IN PRTMP_ADAPTER pAd, | |
1994 | IN MLME_QUEUE_ELEM *Elem) | |
1995 | { | |
1996 | ||
1997 | UCHAR Action = Elem->Msg[LENGTH_802_11+1]; | |
1998 | ||
1999 | if (pAd->CommonCfg.bIEEE80211H != TRUE) | |
2000 | return; | |
2001 | ||
2002 | switch(Action) | |
2003 | { | |
2004 | case SPEC_MRQ: | |
2005 | // current rt2860 unable do such measure specified in Measurement Request. | |
2006 | // reject all measurement request. | |
2007 | PeerMeasureReqAction(pAd, Elem); | |
2008 | break; | |
2009 | ||
2010 | case SPEC_MRP: | |
2011 | PeerMeasureReportAction(pAd, Elem); | |
2012 | break; | |
2013 | ||
2014 | case SPEC_TPCRQ: | |
2015 | PeerTpcReqAction(pAd, Elem); | |
2016 | break; | |
2017 | ||
2018 | case SPEC_TPCRP: | |
2019 | PeerTpcRepAction(pAd, Elem); | |
2020 | break; | |
2021 | ||
2022 | case SPEC_CHANNEL_SWITCH: | |
ca97b838 BZ |
2023 | |
2024 | ||
91980990 GKH |
2025 | PeerChSwAnnAction(pAd, Elem); |
2026 | break; | |
2027 | } | |
2028 | ||
2029 | return; | |
2030 | } | |
2031 | ||
2032 | /* | |
2033 | ========================================================================== | |
2034 | Description: | |
2035 | ||
2036 | Parametrs: | |
2037 | ||
2038 | Return : None. | |
2039 | ========================================================================== | |
2040 | */ | |
2041 | INT Set_MeasureReq_Proc( | |
2042 | IN PRTMP_ADAPTER pAd, | |
ca97b838 | 2043 | IN PSTRING arg) |
91980990 GKH |
2044 | { |
2045 | UINT Aid = 1; | |
2046 | UINT ArgIdx; | |
ca97b838 | 2047 | PSTRING thisChar; |
91980990 GKH |
2048 | |
2049 | MEASURE_REQ_MODE MeasureReqMode; | |
2050 | UINT8 MeasureReqToken = RandomByte(pAd); | |
2051 | UINT8 MeasureReqType = RM_BASIC; | |
2052 | UINT8 MeasureCh = 1; | |
ca97b838 BZ |
2053 | UINT64 MeasureStartTime = GetCurrentTimeStamp(pAd); |
2054 | MEASURE_REQ MeasureReq; | |
2055 | UINT8 TotalLen; | |
2056 | ||
2057 | HEADER_802_11 ActHdr; | |
2058 | PUCHAR pOutBuffer = NULL; | |
2059 | NDIS_STATUS NStatus; | |
2060 | ULONG FrameLen; | |
2061 | ||
2062 | NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory | |
2063 | if(NStatus != NDIS_STATUS_SUCCESS) | |
2064 | { | |
2065 | DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __func__)); | |
2066 | goto END_OF_MEASURE_REQ; | |
2067 | } | |
91980990 GKH |
2068 | |
2069 | ArgIdx = 1; | |
2070 | while ((thisChar = strsep((char **)&arg, "-")) != NULL) | |
2071 | { | |
2072 | switch(ArgIdx) | |
2073 | { | |
2074 | case 1: // Aid. | |
ca97b838 | 2075 | Aid = (UINT8) simple_strtol(thisChar, 0, 16); |
91980990 GKH |
2076 | break; |
2077 | ||
2078 | case 2: // Measurement Request Type. | |
2079 | MeasureReqType = simple_strtol(thisChar, 0, 16); | |
2080 | if (MeasureReqType > 3) | |
2081 | { | |
d599edca | 2082 | DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow MeasureReqType(%d)\n", __func__, MeasureReqType)); |
ca97b838 | 2083 | goto END_OF_MEASURE_REQ; |
91980990 GKH |
2084 | } |
2085 | break; | |
2086 | ||
2087 | case 3: // Measurement channel. | |
ca97b838 | 2088 | MeasureCh = (UINT8) simple_strtol(thisChar, 0, 16); |
91980990 GKH |
2089 | break; |
2090 | } | |
2091 | ArgIdx++; | |
2092 | } | |
2093 | ||
d599edca | 2094 | DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d, MeasureReqType=%d MeasureCh=%d\n", __func__, Aid, MeasureReqType, MeasureCh)); |
91980990 GKH |
2095 | if (!VALID_WCID(Aid)) |
2096 | { | |
d599edca | 2097 | DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __func__, Aid)); |
ca97b838 | 2098 | goto END_OF_MEASURE_REQ; |
91980990 GKH |
2099 | } |
2100 | ||
2101 | MeasureReqMode.word = 0; | |
2102 | MeasureReqMode.field.Enable = 1; | |
2103 | ||
2104 | MeasureReqInsert(pAd, MeasureReqToken); | |
2105 | ||
ca97b838 BZ |
2106 | // build action frame header. |
2107 | MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pAd->MacTab.Content[Aid].Addr, | |
2108 | pAd->CurrentAddress); | |
2109 | ||
2110 | NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11)); | |
2111 | FrameLen = sizeof(HEADER_802_11); | |
2112 | ||
2113 | TotalLen = sizeof(MEASURE_REQ_INFO) + sizeof(MEASURE_REQ); | |
2114 | ||
2115 | MakeMeasurementReqFrame(pAd, pOutBuffer, &FrameLen, | |
2116 | sizeof(MEASURE_REQ_INFO), CATEGORY_RM, RM_BASIC, | |
2117 | MeasureReqToken, MeasureReqMode.word, | |
2118 | MeasureReqType, 0); | |
2119 | ||
2120 | MeasureReq.ChNum = MeasureCh; | |
2121 | MeasureReq.MeasureStartTime = cpu2le64(MeasureStartTime); | |
2122 | MeasureReq.MeasureDuration = cpu2le16(2000); | |
2123 | ||
2124 | { | |
2125 | ULONG TempLen; | |
2126 | MakeOutgoingFrame( pOutBuffer+FrameLen, &TempLen, | |
2127 | sizeof(MEASURE_REQ), &MeasureReq, | |
2128 | END_OF_ARGS); | |
2129 | FrameLen += TempLen; | |
2130 | } | |
2131 | ||
2132 | MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, (UINT)FrameLen); | |
2133 | ||
2134 | END_OF_MEASURE_REQ: | |
2135 | MlmeFreeMemory(pAd, pOutBuffer); | |
91980990 GKH |
2136 | |
2137 | return TRUE; | |
2138 | } | |
2139 | ||
2140 | INT Set_TpcReq_Proc( | |
2141 | IN PRTMP_ADAPTER pAd, | |
ca97b838 | 2142 | IN PSTRING arg) |
91980990 GKH |
2143 | { |
2144 | UINT Aid; | |
2145 | ||
2146 | UINT8 TpcReqToken = RandomByte(pAd); | |
2147 | ||
ca97b838 | 2148 | Aid = (UINT) simple_strtol(arg, 0, 16); |
91980990 | 2149 | |
d599edca | 2150 | DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d\n", __func__, Aid)); |
91980990 GKH |
2151 | if (!VALID_WCID(Aid)) |
2152 | { | |
d599edca | 2153 | DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __func__, Aid)); |
91980990 GKH |
2154 | return TRUE; |
2155 | } | |
2156 | ||
2157 | TpcReqInsert(pAd, TpcReqToken); | |
2158 | ||
2159 | EnqueueTPCReq(pAd, pAd->MacTab.Content[Aid].Addr, TpcReqToken); | |
2160 | ||
2161 | return TRUE; | |
2162 | } | |
2163 |