2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
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. *
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. *
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. *
25 *************************************************************************
31 Handle association related requests either from WSTA or from local MLME
35 --------- ---------- ----------------------------------------------
36 Fonchi Wu 2008 created for 802.11h
39 #include "../rt_config.h"
40 #include "../action.h"
42 VOID MeasureReqTabInit(
45 NdisAllocateSpinLock(&pAd->CommonCfg.MeasureReqTabLock);
47 pAd->CommonCfg.pMeasureReqTab = kmalloc(sizeof(MEASURE_REQ_TAB), GFP_ATOMIC);
48 if (pAd->CommonCfg.pMeasureReqTab)
49 NdisZeroMemory(pAd->CommonCfg.pMeasureReqTab, sizeof(MEASURE_REQ_TAB));
51 DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pMeasureReqTab.\n", __func__));
56 VOID MeasureReqTabExit(
59 NdisFreeSpinLock(pAd->CommonCfg.MeasureReqTabLock);
61 if (pAd->CommonCfg.pMeasureReqTab)
62 kfree(pAd->CommonCfg.pMeasureReqTab);
63 pAd->CommonCfg.pMeasureReqTab = NULL;
68 static PMEASURE_REQ_ENTRY MeasureReqLookUp(
73 PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
74 PMEASURE_REQ_ENTRY pEntry = NULL;
75 PMEASURE_REQ_ENTRY pPrevEntry = NULL;
79 DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __func__));
83 RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
85 HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken);
86 pEntry = pTab->Hash[HashIdx];
90 if (pEntry->DialogToken == DialogToken)
95 pEntry = pEntry->pNext;
99 RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
104 static PMEASURE_REQ_ENTRY MeasureReqInsert(
105 IN PRTMP_ADAPTER pAd,
106 IN UINT8 DialogToken)
110 PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
111 PMEASURE_REQ_ENTRY pEntry = NULL, pCurrEntry;
116 DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __func__));
120 pEntry = MeasureReqLookUp(pAd, DialogToken);
123 RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
124 for (i = 0; i < MAX_MEASURE_REQ_TAB_SIZE; i++)
126 NdisGetSystemUpTime(&Now);
127 pEntry = &pTab->Content[i];
129 if ((pEntry->Valid == TRUE)
130 && RTMP_TIME_AFTER((unsigned long)Now, (unsigned long)(pEntry->lastTime + MQ_REQ_AGE_OUT)))
132 PMEASURE_REQ_ENTRY pPrevEntry = NULL;
133 ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
134 PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
139 if (pProbeEntry == pEntry)
141 if (pPrevEntry == NULL)
143 pTab->Hash[HashIdx] = pEntry->pNext;
147 pPrevEntry->pNext = pEntry->pNext;
152 pPrevEntry = pProbeEntry;
153 pProbeEntry = pProbeEntry->pNext;
154 } while (pProbeEntry);
156 NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY));
162 if (pEntry->Valid == FALSE)
166 if (i < MAX_MEASURE_REQ_TAB_SIZE)
168 NdisGetSystemUpTime(&Now);
169 pEntry->lastTime = Now;
170 pEntry->Valid = TRUE;
171 pEntry->DialogToken = DialogToken;
177 DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab tab full.\n", __func__));
180 // add this Neighbor entry into HASH table
183 HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken);
184 if (pTab->Hash[HashIdx] == NULL)
186 pTab->Hash[HashIdx] = pEntry;
190 pCurrEntry = pTab->Hash[HashIdx];
191 while (pCurrEntry->pNext != NULL)
192 pCurrEntry = pCurrEntry->pNext;
193 pCurrEntry->pNext = pEntry;
197 RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
203 static VOID MeasureReqDelete(
204 IN PRTMP_ADAPTER pAd,
205 IN UINT8 DialogToken)
207 PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
208 PMEASURE_REQ_ENTRY pEntry = NULL;
212 DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __func__));
219 DBGPRINT(RT_DEBUG_ERROR, ("pMeasureReqTab empty.\n"));
223 pEntry = MeasureReqLookUp(pAd, DialogToken);
226 PMEASURE_REQ_ENTRY pPrevEntry = NULL;
227 ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
228 PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
230 RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
234 if (pProbeEntry == pEntry)
236 if (pPrevEntry == NULL)
238 pTab->Hash[HashIdx] = pEntry->pNext;
242 pPrevEntry->pNext = pEntry->pNext;
247 pPrevEntry = pProbeEntry;
248 pProbeEntry = pProbeEntry->pNext;
249 } while (pProbeEntry);
251 NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY));
254 RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
261 IN PRTMP_ADAPTER pAd)
263 NdisAllocateSpinLock(&pAd->CommonCfg.TpcReqTabLock);
265 pAd->CommonCfg.pTpcReqTab = kmalloc(sizeof(TPC_REQ_TAB), GFP_ATOMIC);
266 if (pAd->CommonCfg.pTpcReqTab)
267 NdisZeroMemory(pAd->CommonCfg.pTpcReqTab, sizeof(TPC_REQ_TAB));
269 DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pTpcReqTab.\n", __func__));
275 IN PRTMP_ADAPTER pAd)
277 NdisFreeSpinLock(pAd->CommonCfg.TpcReqTabLock);
279 if (pAd->CommonCfg.pTpcReqTab)
280 kfree(pAd->CommonCfg.pTpcReqTab);
281 pAd->CommonCfg.pTpcReqTab = NULL;
286 static PTPC_REQ_ENTRY TpcReqLookUp(
287 IN PRTMP_ADAPTER pAd,
288 IN UINT8 DialogToken)
291 PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
292 PTPC_REQ_ENTRY pEntry = NULL;
293 PTPC_REQ_ENTRY pPrevEntry = NULL;
297 DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __func__));
301 RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
303 HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken);
304 pEntry = pTab->Hash[HashIdx];
308 if (pEntry->DialogToken == DialogToken)
313 pEntry = pEntry->pNext;
317 RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
323 static PTPC_REQ_ENTRY TpcReqInsert(
324 IN PRTMP_ADAPTER pAd,
325 IN UINT8 DialogToken)
329 PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
330 PTPC_REQ_ENTRY pEntry = NULL, pCurrEntry;
335 DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __func__));
339 pEntry = TpcReqLookUp(pAd, DialogToken);
342 RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
343 for (i = 0; i < MAX_TPC_REQ_TAB_SIZE; i++)
345 NdisGetSystemUpTime(&Now);
346 pEntry = &pTab->Content[i];
348 if ((pEntry->Valid == TRUE)
349 && RTMP_TIME_AFTER((unsigned long)Now, (unsigned long)(pEntry->lastTime + TPC_REQ_AGE_OUT)))
351 PTPC_REQ_ENTRY pPrevEntry = NULL;
352 ULONG HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
353 PTPC_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
358 if (pProbeEntry == pEntry)
360 if (pPrevEntry == NULL)
362 pTab->Hash[HashIdx] = pEntry->pNext;
366 pPrevEntry->pNext = pEntry->pNext;
371 pPrevEntry = pProbeEntry;
372 pProbeEntry = pProbeEntry->pNext;
373 } while (pProbeEntry);
375 NdisZeroMemory(pEntry, sizeof(TPC_REQ_ENTRY));
381 if (pEntry->Valid == FALSE)
385 if (i < MAX_TPC_REQ_TAB_SIZE)
387 NdisGetSystemUpTime(&Now);
388 pEntry->lastTime = Now;
389 pEntry->Valid = TRUE;
390 pEntry->DialogToken = DialogToken;
396 DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab tab full.\n", __func__));
399 // add this Neighbor entry into HASH table
402 HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken);
403 if (pTab->Hash[HashIdx] == NULL)
405 pTab->Hash[HashIdx] = pEntry;
409 pCurrEntry = pTab->Hash[HashIdx];
410 while (pCurrEntry->pNext != NULL)
411 pCurrEntry = pCurrEntry->pNext;
412 pCurrEntry->pNext = pEntry;
416 RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
422 static VOID TpcReqDelete(
423 IN PRTMP_ADAPTER pAd,
424 IN UINT8 DialogToken)
426 PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
427 PTPC_REQ_ENTRY pEntry = NULL;
431 DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __func__));
438 DBGPRINT(RT_DEBUG_ERROR, ("pTpcReqTab empty.\n"));
442 pEntry = TpcReqLookUp(pAd, DialogToken);
445 PTPC_REQ_ENTRY pPrevEntry = NULL;
446 ULONG HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
447 PTPC_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
449 RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
453 if (pProbeEntry == pEntry)
455 if (pPrevEntry == NULL)
457 pTab->Hash[HashIdx] = pEntry->pNext;
461 pPrevEntry->pNext = pEntry->pNext;
466 pPrevEntry = pProbeEntry;
467 pProbeEntry = pProbeEntry->pNext;
468 } while (pProbeEntry);
470 NdisZeroMemory(pEntry, sizeof(TPC_REQ_ENTRY));
473 RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
480 ==========================================================================
482 Get Current TimeS tamp.
486 Return : Current Time Stamp.
487 ==========================================================================
489 static UINT64 GetCurrentTimeStamp(
490 IN PRTMP_ADAPTER pAd)
492 // get current time stamp.
497 ==========================================================================
499 Get Current Transmit Power.
503 Return : Current Time Stamp.
504 ==========================================================================
506 static UINT8 GetCurTxPwr(
507 IN PRTMP_ADAPTER pAd,
510 return 16; /* 16 dBm */
514 ==========================================================================
516 Insert Dialog Token into frame.
519 1. frame buffer pointer.
524 ==========================================================================
526 static VOID InsertDialogToken(
527 IN PRTMP_ADAPTER pAd,
528 OUT PUCHAR pFrameBuf,
529 OUT PULONG pFrameLen,
530 IN UINT8 DialogToken)
533 MakeOutgoingFrame(pFrameBuf, &TempLen,
537 *pFrameLen = *pFrameLen + TempLen;
543 ==========================================================================
545 Insert TPC Request IE into frame.
548 1. frame buffer pointer.
552 ==========================================================================
554 static VOID InsertTpcReqIE(
555 IN PRTMP_ADAPTER pAd,
556 OUT PUCHAR pFrameBuf,
557 OUT PULONG pFrameLen)
561 UINT8 ElementID = IE_TPC_REQUEST;
563 MakeOutgoingFrame(pFrameBuf, &TempLen,
568 *pFrameLen = *pFrameLen + TempLen;
574 ==========================================================================
576 Insert TPC Report IE into frame.
579 1. frame buffer pointer.
585 ==========================================================================
587 static VOID InsertTpcReportIE(
588 IN PRTMP_ADAPTER pAd,
589 OUT PUCHAR pFrameBuf,
590 OUT PULONG pFrameLen,
595 ULONG Len = sizeof(TPC_REPORT_INFO);
596 UINT8 ElementID = IE_TPC_REPORT;
597 TPC_REPORT_INFO TpcReportIE;
599 TpcReportIE.TxPwr = TxPwr;
600 TpcReportIE.LinkMargin = LinkMargin;
602 MakeOutgoingFrame(pFrameBuf, &TempLen,
608 *pFrameLen = *pFrameLen + TempLen;
615 ==========================================================================
617 Insert Channel Switch Announcement IE into frame.
620 1. frame buffer pointer.
622 3. channel switch announcement mode.
623 4. new selected channel.
624 5. channel switch announcement count.
627 ==========================================================================
629 static VOID InsertChSwAnnIE(
630 IN PRTMP_ADAPTER pAd,
631 OUT PUCHAR pFrameBuf,
632 OUT PULONG pFrameLen,
638 ULONG Len = sizeof(CH_SW_ANN_INFO);
639 UINT8 ElementID = IE_CHANNEL_SWITCH_ANNOUNCEMENT;
640 CH_SW_ANN_INFO ChSwAnnIE;
642 ChSwAnnIE.ChSwMode = ChSwMode;
643 ChSwAnnIE.Channel = NewChannel;
644 ChSwAnnIE.ChSwCnt = ChSwCnt;
646 MakeOutgoingFrame(pFrameBuf, &TempLen,
652 *pFrameLen = *pFrameLen + TempLen;
659 ==========================================================================
661 Insert Measure Request IE into frame.
664 1. frame buffer pointer.
667 4. Measure Request Mode.
668 5. Measure Request Type.
670 7. Measure Start time.
675 ==========================================================================
677 static VOID InsertMeasureReqIE(
678 IN PRTMP_ADAPTER pAd,
679 OUT PUCHAR pFrameBuf,
680 OUT PULONG pFrameLen,
681 IN PMEASURE_REQ_INFO pMeasureReqIE)
684 UINT8 Len = sizeof(MEASURE_REQ_INFO);
685 UINT8 ElementID = IE_MEASUREMENT_REQUEST;
687 MakeOutgoingFrame(pFrameBuf, &TempLen,
693 *pFrameLen = *pFrameLen + TempLen;
699 ==========================================================================
701 Insert Measure Report IE into frame.
704 1. frame buffer pointer.
707 4. Measure Request Mode.
708 5. Measure Request Type.
709 6. Length of Report Infomation
710 7. Pointer of Report Infomation Buffer.
713 ==========================================================================
715 static VOID InsertMeasureReportIE(
716 IN PRTMP_ADAPTER pAd,
717 OUT PUCHAR pFrameBuf,
718 OUT PULONG pFrameLen,
719 IN PMEASURE_REPORT_INFO pMeasureReportIE,
720 IN UINT8 ReportLnfoLen,
721 IN PUINT8 pReportInfo)
725 UINT8 ElementID = IE_MEASUREMENT_REPORT;
727 Len = sizeof(MEASURE_REPORT_INFO) + ReportLnfoLen;
729 MakeOutgoingFrame(pFrameBuf, &TempLen,
732 Len, pMeasureReportIE,
735 *pFrameLen = *pFrameLen + TempLen;
737 if ((ReportLnfoLen > 0) && (pReportInfo != NULL))
739 MakeOutgoingFrame(pFrameBuf + *pFrameLen, &TempLen,
740 ReportLnfoLen, pReportInfo,
743 *pFrameLen = *pFrameLen + TempLen;
749 ==========================================================================
751 Prepare Measurement request action frame and enqueue it into
752 management queue waiting for transmition.
755 1. the destination mac address of the frame.
758 ==========================================================================
760 VOID EnqueueMeasurementReq(
761 IN PRTMP_ADAPTER pAd,
763 IN UINT8 MeasureToken,
764 IN UINT8 MeasureReqMode,
765 IN UINT8 MeasureReqType,
767 IN UINT16 MeasureDuration)
769 PUCHAR pOutBuffer = NULL;
772 HEADER_802_11 ActHdr;
773 MEASURE_REQ_INFO MeasureReqIE;
774 UINT8 RmReqDailogToken = RandomByte(pAd);
775 UINT64 MeasureStartTime = GetCurrentTimeStamp(pAd);
777 // build action frame header.
778 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
779 pAd->CurrentAddress);
781 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
782 if(NStatus != NDIS_STATUS_SUCCESS)
784 DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __func__));
787 NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
788 FrameLen = sizeof(HEADER_802_11);
790 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_MRQ);
793 InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, MeasureToken);
795 // prepare Measurement IE.
796 NdisZeroMemory(&MeasureReqIE, sizeof(MEASURE_REQ_INFO));
797 MeasureReqIE.Token = RmReqDailogToken;
798 MeasureReqIE.ReqMode.word = MeasureReqMode;
799 MeasureReqIE.ReqType = MeasureReqType;
800 MeasureReqIE.MeasureReq.ChNum = MeasureCh;
801 MeasureReqIE.MeasureReq.MeasureStartTime = cpu2le64(MeasureStartTime);
802 MeasureReqIE.MeasureReq.MeasureDuration = cpu2le16(MeasureDuration);
803 InsertMeasureReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureReqIE);
805 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
806 MlmeFreeMemory(pAd, pOutBuffer);
812 ==========================================================================
814 Prepare Measurement report action frame and enqueue it into
815 management queue waiting for transmition.
818 1. the destination mac address of the frame.
821 ==========================================================================
823 VOID EnqueueMeasurementRep(
824 IN PRTMP_ADAPTER pAd,
826 IN UINT8 DialogToken,
827 IN UINT8 MeasureToken,
828 IN UINT8 MeasureReqMode,
829 IN UINT8 MeasureReqType,
830 IN UINT8 ReportInfoLen,
831 IN PUINT8 pReportInfo)
833 PUCHAR pOutBuffer = NULL;
836 HEADER_802_11 ActHdr;
837 MEASURE_REPORT_INFO MeasureRepIE;
839 // build action frame header.
840 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
841 pAd->CurrentAddress);
843 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
844 if(NStatus != NDIS_STATUS_SUCCESS)
846 DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __func__));
849 NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
850 FrameLen = sizeof(HEADER_802_11);
852 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_MRP);
855 InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
857 // prepare Measurement IE.
858 NdisZeroMemory(&MeasureRepIE, sizeof(MEASURE_REPORT_INFO));
859 MeasureRepIE.Token = MeasureToken;
860 MeasureRepIE.ReportMode.word = MeasureReqMode;
861 MeasureRepIE.ReportType = MeasureReqType;
862 InsertMeasureReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureRepIE, ReportInfoLen, pReportInfo);
864 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
865 MlmeFreeMemory(pAd, pOutBuffer);
871 ==========================================================================
873 Prepare TPC Request action frame and enqueue it into
874 management queue waiting for transmition.
877 1. the destination mac address of the frame.
880 ==========================================================================
883 IN PRTMP_ADAPTER pAd,
885 IN UCHAR DialogToken)
887 PUCHAR pOutBuffer = NULL;
891 HEADER_802_11 ActHdr;
893 // build action frame header.
894 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
895 pAd->CurrentAddress);
897 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
898 if(NStatus != NDIS_STATUS_SUCCESS)
900 DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __func__));
903 NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
904 FrameLen = sizeof(HEADER_802_11);
906 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_TPCRQ);
909 InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
911 // Insert TPC Request IE.
912 InsertTpcReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen);
914 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
915 MlmeFreeMemory(pAd, pOutBuffer);
921 ==========================================================================
923 Prepare TPC Report action frame and enqueue it into
924 management queue waiting for transmition.
927 1. the destination mac address of the frame.
930 ==========================================================================
933 IN PRTMP_ADAPTER pAd,
935 IN UINT8 DialogToken,
939 PUCHAR pOutBuffer = NULL;
943 HEADER_802_11 ActHdr;
945 // build action frame header.
946 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
947 pAd->CurrentAddress);
949 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
950 if(NStatus != NDIS_STATUS_SUCCESS)
952 DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __func__));
955 NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
956 FrameLen = sizeof(HEADER_802_11);
958 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_TPCRP);
961 InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
963 // Insert TPC Request IE.
964 InsertTpcReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, TxPwr, LinkMargin);
966 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
967 MlmeFreeMemory(pAd, pOutBuffer);
973 ==========================================================================
975 Prepare Channel Switch Announcement action frame and enqueue it into
976 management queue waiting for transmition.
979 1. the destination mac address of the frame.
980 2. Channel switch announcement mode.
981 2. a New selected channel.
984 ==========================================================================
987 IN PRTMP_ADAPTER pAd,
992 PUCHAR pOutBuffer = NULL;
996 HEADER_802_11 ActHdr;
998 // build action frame header.
999 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
1000 pAd->CurrentAddress);
1002 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
1003 if(NStatus != NDIS_STATUS_SUCCESS)
1005 DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __func__));
1008 NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
1009 FrameLen = sizeof(HEADER_802_11);
1011 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_CHANNEL_SWITCH);
1013 InsertChSwAnnIE(pAd, (pOutBuffer + FrameLen), &FrameLen, ChSwMode, NewCh, 0);
1015 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1016 MlmeFreeMemory(pAd, pOutBuffer);
1021 static BOOLEAN DfsRequirementCheck(
1022 IN PRTMP_ADAPTER pAd,
1025 BOOLEAN Result = FALSE;
1030 // check DFS procedure is running.
1031 // make sure DFS procedure won't start twice.
1032 if (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
1038 // check the new channel carried from Channel Switch Announcemnet is valid.
1039 for (i=0; i<pAd->ChannelListNum; i++)
1041 if ((Channel == pAd->ChannelList[i].Channel)
1042 &&(pAd->ChannelList[i].RemainingTimeForUse == 0))
1044 // found radar signal in the channel. the channel can't use at least for 30 minutes.
1045 pAd->ChannelList[i].RemainingTimeForUse = 1800;//30 min = 1800 sec
1055 VOID NotifyChSwAnnToPeerAPs(
1056 IN PRTMP_ADAPTER pAd,
1064 static VOID StartDFSProcedure(
1065 IN PRTMP_ADAPTER pAd,
1069 // start DFS procedure
1070 pAd->CommonCfg.Channel = Channel;
1071 #ifdef DOT11_N_SUPPORT
1072 N_ChannelCheck(pAd);
1073 #endif // DOT11_N_SUPPORT //
1074 pAd->CommonCfg.RadarDetect.RDMode = RD_SWITCHING_MODE;
1075 pAd->CommonCfg.RadarDetect.CSCount = 0;
1079 ==========================================================================
1081 Channel Switch Announcement action frame sanity check.
1084 1. MLME message containing the received frame
1086 3. Channel switch announcement infomation buffer.
1090 ==========================================================================
1094 Channel Switch Announcement IE.
1095 +----+-----+-----------+------------+-----------+
1096 | ID | Len |Ch Sw Mode | New Ch Num | Ch Sw Cnt |
1097 +----+-----+-----------+------------+-----------+
1100 static BOOLEAN PeerChSwAnnSanity(
1101 IN PRTMP_ADAPTER pAd,
1104 OUT PCH_SW_ANN_INFO pChSwAnnInfo)
1106 PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
1107 PUCHAR pFramePtr = Fr->Octet;
1108 BOOLEAN result = FALSE;
1109 PEID_STRUCT eid_ptr;
1111 // skip 802.11 header.
1112 MsgLen -= sizeof(HEADER_802_11);
1114 // skip category and action code.
1118 if (pChSwAnnInfo == NULL)
1121 eid_ptr = (PEID_STRUCT)pFramePtr;
1122 while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
1124 switch(eid_ptr->Eid)
1126 case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
1127 NdisMoveMemory(&pChSwAnnInfo->ChSwMode, eid_ptr->Octet, 1);
1128 NdisMoveMemory(&pChSwAnnInfo->Channel, eid_ptr->Octet + 1, 1);
1129 NdisMoveMemory(&pChSwAnnInfo->ChSwCnt, eid_ptr->Octet + 2, 1);
1137 eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
1144 ==========================================================================
1146 Measurement request action frame sanity check.
1149 1. MLME message containing the received frame
1151 3. Measurement request infomation buffer.
1154 ==========================================================================
1156 static BOOLEAN PeerMeasureReqSanity(
1157 IN PRTMP_ADAPTER pAd,
1160 OUT PUINT8 pDialogToken,
1161 OUT PMEASURE_REQ_INFO pMeasureReqInfo)
1163 PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
1164 PUCHAR pFramePtr = Fr->Octet;
1165 BOOLEAN result = FALSE;
1166 PEID_STRUCT eid_ptr;
1168 UINT64 MeasureStartTime;
1169 UINT16 MeasureDuration;
1171 // skip 802.11 header.
1172 MsgLen -= sizeof(HEADER_802_11);
1174 // skip category and action code.
1178 if (pMeasureReqInfo == NULL)
1181 NdisMoveMemory(pDialogToken, pFramePtr, 1);
1185 eid_ptr = (PEID_STRUCT)pFramePtr;
1186 while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
1188 switch(eid_ptr->Eid)
1190 case IE_MEASUREMENT_REQUEST:
1191 NdisMoveMemory(&pMeasureReqInfo->Token, eid_ptr->Octet, 1);
1192 NdisMoveMemory(&pMeasureReqInfo->ReqMode.word, eid_ptr->Octet + 1, 1);
1193 NdisMoveMemory(&pMeasureReqInfo->ReqType, eid_ptr->Octet + 2, 1);
1194 ptr = eid_ptr->Octet + 3;
1195 NdisMoveMemory(&pMeasureReqInfo->MeasureReq.ChNum, ptr, 1);
1196 NdisMoveMemory(&MeasureStartTime, ptr + 1, 8);
1197 pMeasureReqInfo->MeasureReq.MeasureStartTime = SWAP64(MeasureStartTime);
1198 NdisMoveMemory(&MeasureDuration, ptr + 9, 2);
1199 pMeasureReqInfo->MeasureReq.MeasureDuration = SWAP16(MeasureDuration);
1207 eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
1214 ==========================================================================
1216 Measurement report action frame sanity check.
1219 1. MLME message containing the received frame
1221 3. Measurement report infomation buffer.
1222 4. basic report infomation buffer.
1225 ==========================================================================
1229 Measurement Report IE.
1230 +----+-----+-------+-------------+--------------+----------------+
1231 | ID | Len | Token | Report Mode | Measure Type | Measure Report |
1232 +----+-----+-------+-------------+--------------+----------------+
1236 +--------+------------+----------+-----+
1237 | Ch Num | Start Time | Duration | Map |
1238 +--------+------------+----------+-----+
1241 Map Field Bit Format.
1242 +-----+---------------+---------------------+-------+------------+----------+
1243 | Bss | OFDM Preamble | Unidentified signal | Radar | Unmeasured | Reserved |
1244 +-----+---------------+---------------------+-------+------------+----------+
1247 static BOOLEAN PeerMeasureReportSanity(
1248 IN PRTMP_ADAPTER pAd,
1251 OUT PUINT8 pDialogToken,
1252 OUT PMEASURE_REPORT_INFO pMeasureReportInfo,
1253 OUT PUINT8 pReportBuf)
1255 PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
1256 PUCHAR pFramePtr = Fr->Octet;
1257 BOOLEAN result = FALSE;
1258 PEID_STRUCT eid_ptr;
1261 // skip 802.11 header.
1262 MsgLen -= sizeof(HEADER_802_11);
1264 // skip category and action code.
1268 if (pMeasureReportInfo == NULL)
1271 NdisMoveMemory(pDialogToken, pFramePtr, 1);
1275 eid_ptr = (PEID_STRUCT)pFramePtr;
1276 while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
1278 switch(eid_ptr->Eid)
1280 case IE_MEASUREMENT_REPORT:
1281 NdisMoveMemory(&pMeasureReportInfo->Token, eid_ptr->Octet, 1);
1282 NdisMoveMemory(&pMeasureReportInfo->ReportMode, eid_ptr->Octet + 1, 1);
1283 NdisMoveMemory(&pMeasureReportInfo->ReportType, eid_ptr->Octet + 2, 1);
1284 if (pMeasureReportInfo->ReportType == RM_BASIC)
1286 PMEASURE_BASIC_REPORT pReport = (PMEASURE_BASIC_REPORT)pReportBuf;
1287 ptr = eid_ptr->Octet + 3;
1288 NdisMoveMemory(&pReport->ChNum, ptr, 1);
1289 NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
1290 NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
1291 NdisMoveMemory(&pReport->Map, ptr + 11, 1);
1294 else if (pMeasureReportInfo->ReportType == RM_CCA)
1296 PMEASURE_CCA_REPORT pReport = (PMEASURE_CCA_REPORT)pReportBuf;
1297 ptr = eid_ptr->Octet + 3;
1298 NdisMoveMemory(&pReport->ChNum, ptr, 1);
1299 NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
1300 NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
1301 NdisMoveMemory(&pReport->CCA_Busy_Fraction, ptr + 11, 1);
1304 else if (pMeasureReportInfo->ReportType == RM_RPI_HISTOGRAM)
1306 PMEASURE_RPI_REPORT pReport = (PMEASURE_RPI_REPORT)pReportBuf;
1307 ptr = eid_ptr->Octet + 3;
1308 NdisMoveMemory(&pReport->ChNum, ptr, 1);
1309 NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
1310 NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
1311 NdisMoveMemory(&pReport->RPI_Density, ptr + 11, 8);
1319 eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
1326 ==========================================================================
1328 TPC Request action frame sanity check.
1331 1. MLME message containing the received frame
1336 ==========================================================================
1338 static BOOLEAN PeerTpcReqSanity(
1339 IN PRTMP_ADAPTER pAd,
1342 OUT PUINT8 pDialogToken)
1344 PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
1345 PUCHAR pFramePtr = Fr->Octet;
1346 BOOLEAN result = FALSE;
1347 PEID_STRUCT eid_ptr;
1349 MsgLen -= sizeof(HEADER_802_11);
1351 // skip category and action code.
1355 if (pDialogToken == NULL)
1358 NdisMoveMemory(pDialogToken, pFramePtr, 1);
1362 eid_ptr = (PEID_STRUCT)pFramePtr;
1363 while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
1365 switch(eid_ptr->Eid)
1367 case IE_TPC_REQUEST:
1374 eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
1381 ==========================================================================
1383 TPC Report action frame sanity check.
1386 1. MLME message containing the received frame
1392 ==========================================================================
1394 static BOOLEAN PeerTpcRepSanity(
1395 IN PRTMP_ADAPTER pAd,
1398 OUT PUINT8 pDialogToken,
1399 OUT PTPC_REPORT_INFO pTpcRepInfo)
1401 PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
1402 PUCHAR pFramePtr = Fr->Octet;
1403 BOOLEAN result = FALSE;
1404 PEID_STRUCT eid_ptr;
1406 MsgLen -= sizeof(HEADER_802_11);
1408 // skip category and action code.
1412 if (pDialogToken == NULL)
1415 NdisMoveMemory(pDialogToken, pFramePtr, 1);
1419 eid_ptr = (PEID_STRUCT)pFramePtr;
1420 while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
1422 switch(eid_ptr->Eid)
1425 NdisMoveMemory(&pTpcRepInfo->TxPwr, eid_ptr->Octet, 1);
1426 NdisMoveMemory(&pTpcRepInfo->LinkMargin, eid_ptr->Octet + 1, 1);
1433 eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
1440 ==========================================================================
1442 Channel Switch Announcement action frame handler.
1445 Elme - MLME message containing the received frame
1448 ==========================================================================
1450 static VOID PeerChSwAnnAction(
1451 IN PRTMP_ADAPTER pAd,
1452 IN MLME_QUEUE_ELEM *Elem)
1454 CH_SW_ANN_INFO ChSwAnnInfo;
1455 PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
1456 #ifdef CONFIG_STA_SUPPORT
1457 UCHAR index = 0, Channel = 0, NewChannel = 0;
1459 #endif // CONFIG_STA_SUPPORT //
1461 NdisZeroMemory(&ChSwAnnInfo, sizeof(CH_SW_ANN_INFO));
1462 if (! PeerChSwAnnSanity(pAd, Elem->Msg, Elem->MsgLen, &ChSwAnnInfo))
1464 DBGPRINT(RT_DEBUG_TRACE, ("Invalid Channel Switch Action Frame.\n"));
1469 #ifdef CONFIG_STA_SUPPORT
1470 if (pAd->OpMode == OPMODE_STA)
1472 Bssidx = BssTableSearch(&pAd->ScanTab, pFr->Hdr.Addr3, pAd->CommonCfg.Channel);
1473 if (Bssidx == BSS_NOT_FOUND)
1475 DBGPRINT(RT_DEBUG_TRACE, ("PeerChSwAnnAction - Bssidx is not found\n"));
1479 DBGPRINT(RT_DEBUG_TRACE, ("\n****Bssidx is %d, Channel = %d\n", index, pAd->ScanTab.BssEntry[Bssidx].Channel));
1480 hex_dump("SSID",pAd->ScanTab.BssEntry[Bssidx].Bssid ,6);
1482 Channel = pAd->CommonCfg.Channel;
1483 NewChannel = ChSwAnnInfo.Channel;
1485 if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel))
1487 // Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection).
1488 // In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results.
1489 AsicSwitchChannel(pAd, 1, FALSE);
1490 AsicLockChannel(pAd, 1);
1491 LinkDown(pAd, FALSE);
1492 MlmeQueueInit(&pAd->Mlme.Queue);
1493 BssTableInit(&pAd->ScanTab);
1494 RTMPusecDelay(1000000); // use delay to prevent STA do reassoc
1496 // channel sanity check
1497 for (index = 0 ; index < pAd->ChannelListNum; index++)
1499 if (pAd->ChannelList[index].Channel == NewChannel)
1501 pAd->ScanTab.BssEntry[Bssidx].Channel = NewChannel;
1502 pAd->CommonCfg.Channel = NewChannel;
1503 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1504 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1505 DBGPRINT(RT_DEBUG_TRACE, ("&&&&&&&&&&&&&&&&PeerChSwAnnAction - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel));
1510 if (index >= pAd->ChannelListNum)
1512 DBGPRINT_ERR(("&&&&&&&&&&&&&&&&&&&&&&&&&&PeerChSwAnnAction(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum));
1516 #endif // CONFIG_STA_SUPPORT //
1523 ==========================================================================
1525 Measurement Request action frame handler.
1528 Elme - MLME message containing the received frame
1531 ==========================================================================
1533 static VOID PeerMeasureReqAction(
1534 IN PRTMP_ADAPTER pAd,
1535 IN MLME_QUEUE_ELEM *Elem)
1537 PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
1539 MEASURE_REQ_INFO MeasureReqInfo;
1540 MEASURE_REPORT_MODE ReportMode;
1542 if(PeerMeasureReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReqInfo))
1544 ReportMode.word = 0;
1545 ReportMode.field.Incapable = 1;
1546 EnqueueMeasurementRep(pAd, pFr->Hdr.Addr2, DialogToken, MeasureReqInfo.Token, ReportMode.word, MeasureReqInfo.ReqType, 0, NULL);
1553 ==========================================================================
1555 Measurement Report action frame handler.
1558 Elme - MLME message containing the received frame
1561 ==========================================================================
1563 static VOID PeerMeasureReportAction(
1564 IN PRTMP_ADAPTER pAd,
1565 IN MLME_QUEUE_ELEM *Elem)
1567 MEASURE_REPORT_INFO MeasureReportInfo;
1568 PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
1570 PUINT8 pMeasureReportInfo;
1572 // if (pAd->CommonCfg.bIEEE80211H != TRUE)
1575 if ((pMeasureReportInfo = kmalloc(sizeof(MEASURE_RPI_REPORT), GFP_ATOMIC)) == NULL)
1577 DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%d).\n", __func__, sizeof(MEASURE_RPI_REPORT)));
1581 NdisZeroMemory(&MeasureReportInfo, sizeof(MEASURE_REPORT_INFO));
1582 NdisZeroMemory(pMeasureReportInfo, sizeof(MEASURE_RPI_REPORT));
1583 if (PeerMeasureReportSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReportInfo, pMeasureReportInfo))
1586 PMEASURE_REQ_ENTRY pEntry = NULL;
1588 // Not a autonomous measure report.
1589 // check the dialog token field. drop it if the dialog token doesn't match.
1590 if ((DialogToken != 0)
1591 && ((pEntry = MeasureReqLookUp(pAd, DialogToken)) == NULL))
1595 MeasureReqDelete(pAd, pEntry->DialogToken);
1597 if (MeasureReportInfo.ReportType == RM_BASIC)
1599 PMEASURE_BASIC_REPORT pBasicReport = (PMEASURE_BASIC_REPORT)pMeasureReportInfo;
1600 if ((pBasicReport->Map.field.Radar)
1601 && (DfsRequirementCheck(pAd, pBasicReport->ChNum) == TRUE))
1603 NotifyChSwAnnToPeerAPs(pAd, pFr->Hdr.Addr1, pFr->Hdr.Addr2, 1, pBasicReport->ChNum);
1604 StartDFSProcedure(pAd, pBasicReport->ChNum, 1);
1610 DBGPRINT(RT_DEBUG_TRACE, ("Invalid Measurement Report Frame.\n"));
1612 kfree(pMeasureReportInfo);
1618 ==========================================================================
1620 TPC Request action frame handler.
1623 Elme - MLME message containing the received frame
1626 ==========================================================================
1628 static VOID PeerTpcReqAction(
1629 IN PRTMP_ADAPTER pAd,
1630 IN MLME_QUEUE_ELEM *Elem)
1632 PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
1633 PUCHAR pFramePtr = pFr->Octet;
1635 UINT8 TxPwr = GetCurTxPwr(pAd, Elem->Wcid);
1636 UINT8 LinkMargin = 0;
1639 // link margin: Ratio of the received signal power to the minimum desired by the station (STA). The
1640 // STA may incorporate rate information and channel conditions, including interference, into its computation
1643 RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0),
1644 ConvertToRssi(pAd, Elem->Rssi1, RSSI_1),
1645 ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
1647 // skip Category and action code.
1651 NdisMoveMemory(&DialogToken, pFramePtr, 1);
1653 LinkMargin = (RealRssi / MIN_RCV_PWR);
1654 if (PeerTpcReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken))
1655 EnqueueTPCRep(pAd, pFr->Hdr.Addr2, DialogToken, TxPwr, LinkMargin);
1661 ==========================================================================
1663 TPC Report action frame handler.
1666 Elme - MLME message containing the received frame
1669 ==========================================================================
1671 static VOID PeerTpcRepAction(
1672 IN PRTMP_ADAPTER pAd,
1673 IN MLME_QUEUE_ELEM *Elem)
1676 TPC_REPORT_INFO TpcRepInfo;
1677 PTPC_REQ_ENTRY pEntry = NULL;
1679 NdisZeroMemory(&TpcRepInfo, sizeof(TPC_REPORT_INFO));
1680 if (PeerTpcRepSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &TpcRepInfo))
1682 if ((pEntry = TpcReqLookUp(pAd, DialogToken)) != NULL)
1684 TpcReqDelete(pAd, pEntry->DialogToken);
1685 DBGPRINT(RT_DEBUG_TRACE, ("%s: DialogToken=%x, TxPwr=%d, LinkMargin=%d\n",
1686 __func__, DialogToken, TpcRepInfo.TxPwr, TpcRepInfo.LinkMargin));
1694 ==========================================================================
1696 Spectrun action frames Handler such as channel switch annoucement,
1697 measurement report, measurement request actions frames.
1700 Elme - MLME message containing the received frame
1703 ==========================================================================
1705 VOID PeerSpectrumAction(
1706 IN PRTMP_ADAPTER pAd,
1707 IN MLME_QUEUE_ELEM *Elem)
1710 UCHAR Action = Elem->Msg[LENGTH_802_11+1];
1712 if (pAd->CommonCfg.bIEEE80211H != TRUE)
1718 // current rt2860 unable do such measure specified in Measurement Request.
1719 // reject all measurement request.
1720 PeerMeasureReqAction(pAd, Elem);
1724 PeerMeasureReportAction(pAd, Elem);
1728 PeerTpcReqAction(pAd, Elem);
1732 PeerTpcRepAction(pAd, Elem);
1735 case SPEC_CHANNEL_SWITCH:
1738 PeerChSwAnnAction(pAd, Elem);
1746 ==========================================================================
1752 ==========================================================================
1754 INT Set_MeasureReq_Proc(
1755 IN PRTMP_ADAPTER pAd,
1762 MEASURE_REQ_MODE MeasureReqMode;
1763 UINT8 MeasureReqToken = RandomByte(pAd);
1764 UINT8 MeasureReqType = RM_BASIC;
1765 UINT8 MeasureCh = 1;
1768 while ((thisChar = strsep((char **)&arg, "-")) != NULL)
1773 Aid = simple_strtol(thisChar, 0, 16);
1776 case 2: // Measurement Request Type.
1777 MeasureReqType = simple_strtol(thisChar, 0, 16);
1778 if (MeasureReqType > 3)
1780 DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow MeasureReqType(%d)\n", __func__, MeasureReqType));
1785 case 3: // Measurement channel.
1786 MeasureCh = simple_strtol(thisChar, 0, 16);
1792 DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d, MeasureReqType=%d MeasureCh=%d\n", __func__, Aid, MeasureReqType, MeasureCh));
1793 if (!VALID_WCID(Aid))
1795 DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __func__, Aid));
1799 MeasureReqMode.word = 0;
1800 MeasureReqMode.field.Enable = 1;
1802 MeasureReqInsert(pAd, MeasureReqToken);
1804 EnqueueMeasurementReq(pAd, pAd->MacTab.Content[Aid].Addr,
1805 MeasureReqToken, MeasureReqMode.word, MeasureReqType, MeasureCh, 2000);
1810 INT Set_TpcReq_Proc(
1811 IN PRTMP_ADAPTER pAd,
1816 UINT8 TpcReqToken = RandomByte(pAd);
1818 Aid = simple_strtol(arg, 0, 16);
1820 DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d\n", __func__, Aid));
1821 if (!VALID_WCID(Aid))
1823 DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __func__, Aid));
1827 TpcReqInsert(pAd, TpcReqToken);
1829 EnqueueTPCReq(pAd, pAd->MacTab.Content[Aid].Addr, TpcReqToken);