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