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"
43 /* The regulatory information in the USA (US) */
44 DOT11_REGULATORY_INFORMATION USARegulatoryInfo
[] =
46 /* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */
47 {0, {0, 0, {0}}}, // Invlid entry
48 {1, {4, 16, {36, 40, 44, 48}}},
49 {2, {4, 23, {52, 56, 60, 64}}},
50 {3, {4, 29, {149, 153, 157, 161}}},
51 {4, {11, 23, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}},
52 {5, {5, 30, {149, 153, 157, 161, 165}}},
53 {6, {10, 14, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}},
54 {7, {10, 27, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}},
55 {8, {5, 17, {11, 13, 15, 17, 19}}},
56 {9, {5, 30, {11, 13, 15, 17, 19}}},
57 {10, {2, 20, {21, 25}}},
58 {11, {2, 33, {21, 25}}},
59 {12, {11, 30, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}}
61 #define USA_REGULATORY_INFO_SIZE (sizeof(USARegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION))
64 /* The regulatory information in Europe */
65 DOT11_REGULATORY_INFORMATION EuropeRegulatoryInfo
[] =
67 /* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */
68 {0, {0, 0, {0}}}, // Invalid entry
69 {1, {4, 20, {36, 40, 44, 48}}},
70 {2, {4, 20, {52, 56, 60, 64}}},
71 {3, {11, 30, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}},
72 {4, {13, 20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}}
74 #define EU_REGULATORY_INFO_SIZE (sizeof(EuropeRegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION))
77 /* The regulatory information in Japan */
78 DOT11_REGULATORY_INFORMATION JapanRegulatoryInfo
[] =
80 /* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */
81 {0, {0, 0, {0}}}, // Invalid entry
82 {1, {4, 22, {34, 38, 42, 46}}},
83 {2, {3, 24, {8, 12, 16}}},
84 {3, {3, 24, {8, 12, 16}}},
85 {4, {3, 24, {8, 12, 16}}},
86 {5, {3, 24, {8, 12, 16}}},
87 {6, {3, 22, {8, 12, 16}}},
88 {7, {4, 24, {184, 188, 192, 196}}},
89 {8, {4, 24, {184, 188, 192, 196}}},
90 {9, {4, 24, {184, 188, 192, 196}}},
91 {10, {4, 24, {184, 188, 192, 196}}},
92 {11, {4, 22, {184, 188, 192, 196}}},
93 {12, {4, 24, {7, 8, 9, 11}}},
94 {13, {4, 24, {7, 8, 9, 11}}},
95 {14, {4, 24, {7, 8, 9, 11}}},
96 {15, {4, 24, {7, 8, 9, 11}}},
97 {16, {6, 24, {183, 184, 185, 187, 188, 189}}},
98 {17, {6, 24, {183, 184, 185, 187, 188, 189}}},
99 {18, {6, 24, {183, 184, 185, 187, 188, 189}}},
100 {19, {6, 24, {183, 184, 185, 187, 188, 189}}},
101 {20, {6, 17, {183, 184, 185, 187, 188, 189}}},
102 {21, {6, 24, {6, 7, 8, 9, 10, 11}}},
103 {22, {6, 24, {6, 7, 8, 9, 10, 11}}},
104 {23, {6, 24, {6, 7, 8, 9, 10, 11}}},
105 {24, {6, 24, {6, 7, 8, 9, 10, 11}}},
106 {25, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}},
107 {26, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}},
108 {27, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}},
109 {28, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}},
110 {29, {8, 17, {182, 183, 184, 185, 186, 187, 188, 189}}},
111 {30, {13, 23, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}},
113 {32, {4, 22, {52, 56, 60, 64}}}
115 #define JP_REGULATORY_INFO_SIZE (sizeof(JapanRegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION))
119 IN PRTMP_ADAPTER pAd
,
120 IN HTTRANSMIT_SETTING HTTxMode
)
122 typedef struct __TX_PWR_CFG
140 TX_PWR_CFG TxPwrCfg
[] = {
141 {MODE_CCK
, 0, 0, 4, 0x000000f0},
142 {MODE_CCK
, 1, 0, 0, 0x0000000f},
143 {MODE_CCK
, 2, 0, 12, 0x0000f000},
144 {MODE_CCK
, 3, 0, 8, 0x00000f00},
146 {MODE_OFDM
, 0, 0, 20, 0x00f00000},
147 {MODE_OFDM
, 1, 0, 16, 0x000f0000},
148 {MODE_OFDM
, 2, 0, 28, 0xf0000000},
149 {MODE_OFDM
, 3, 0, 24, 0x0f000000},
150 {MODE_OFDM
, 4, 1, 4, 0x000000f0},
151 {MODE_OFDM
, 5, 1, 0, 0x0000000f},
152 {MODE_OFDM
, 6, 1, 12, 0x0000f000},
153 {MODE_OFDM
, 7, 1, 8, 0x00000f00}
154 #ifdef DOT11_N_SUPPORT
155 ,{MODE_HTMIX
, 0, 1, 20, 0x00f00000},
156 {MODE_HTMIX
, 1, 1, 16, 0x000f0000},
157 {MODE_HTMIX
, 2, 1, 28, 0xf0000000},
158 {MODE_HTMIX
, 3, 1, 24, 0x0f000000},
159 {MODE_HTMIX
, 4, 2, 4, 0x000000f0},
160 {MODE_HTMIX
, 5, 2, 0, 0x0000000f},
161 {MODE_HTMIX
, 6, 2, 12, 0x0000f000},
162 {MODE_HTMIX
, 7, 2, 8, 0x00000f00},
163 {MODE_HTMIX
, 8, 2, 20, 0x00f00000},
164 {MODE_HTMIX
, 9, 2, 16, 0x000f0000},
165 {MODE_HTMIX
, 10, 2, 28, 0xf0000000},
166 {MODE_HTMIX
, 11, 2, 24, 0x0f000000},
167 {MODE_HTMIX
, 12, 3, 4, 0x000000f0},
168 {MODE_HTMIX
, 13, 3, 0, 0x0000000f},
169 {MODE_HTMIX
, 14, 3, 12, 0x0000f000},
170 {MODE_HTMIX
, 15, 3, 8, 0x00000f00}
171 #endif // DOT11_N_SUPPORT //
173 #define MAX_TXPWR_TAB_SIZE (sizeof(TxPwrCfg) / sizeof(TX_PWR_CFG))
176 CurTxPwr
= pAd
->CommonCfg
.DefineMaxTxPwr
;
181 /* check Tx Power setting from UI. */
182 if (pAd
->CommonCfg
.TxPowerPercentage
> 90)
184 else if (pAd
->CommonCfg
.TxPowerPercentage
> 60) /* reduce Pwr for 1 dB. */
186 else if (pAd
->CommonCfg
.TxPowerPercentage
> 30) /* reduce Pwr for 3 dB. */
188 else if (pAd
->CommonCfg
.TxPowerPercentage
> 15) /* reduce Pwr for 6 dB. */
190 else if (pAd
->CommonCfg
.TxPowerPercentage
> 9) /* reduce Pwr for 9 dB. */
192 else /* reduce Pwr for 12 dB. */
195 if (pAd
->CommonCfg
.BBPCurrentBW
== BW_40
)
197 if (pAd
->CommonCfg
.CentralChannel
> 14)
199 TxPwr
[0] = pAd
->Tx40MPwrCfgABand
[0];
200 TxPwr
[1] = pAd
->Tx40MPwrCfgABand
[1];
201 TxPwr
[2] = pAd
->Tx40MPwrCfgABand
[2];
202 TxPwr
[3] = pAd
->Tx40MPwrCfgABand
[3];
203 TxPwr
[4] = pAd
->Tx40MPwrCfgABand
[4];
207 TxPwr
[0] = pAd
->Tx40MPwrCfgGBand
[0];
208 TxPwr
[1] = pAd
->Tx40MPwrCfgGBand
[1];
209 TxPwr
[2] = pAd
->Tx40MPwrCfgGBand
[2];
210 TxPwr
[3] = pAd
->Tx40MPwrCfgGBand
[3];
211 TxPwr
[4] = pAd
->Tx40MPwrCfgGBand
[4];
216 if (pAd
->CommonCfg
.Channel
> 14)
218 TxPwr
[0] = pAd
->Tx20MPwrCfgABand
[0];
219 TxPwr
[1] = pAd
->Tx20MPwrCfgABand
[1];
220 TxPwr
[2] = pAd
->Tx20MPwrCfgABand
[2];
221 TxPwr
[3] = pAd
->Tx20MPwrCfgABand
[3];
222 TxPwr
[4] = pAd
->Tx20MPwrCfgABand
[4];
226 TxPwr
[0] = pAd
->Tx20MPwrCfgGBand
[0];
227 TxPwr
[1] = pAd
->Tx20MPwrCfgGBand
[1];
228 TxPwr
[2] = pAd
->Tx20MPwrCfgGBand
[2];
229 TxPwr
[3] = pAd
->Tx20MPwrCfgGBand
[3];
230 TxPwr
[4] = pAd
->Tx20MPwrCfgGBand
[4];
235 switch(HTTxMode
.field
.MODE
)
240 TxPwrRef
= (Value
& 0x00000f00) >> 8;
244 #ifdef DOT11_N_SUPPORT
246 case MODE_HTGREENFIELD
:
247 if (pAd
->CommonCfg
.TxStream
== 1)
250 TxPwrRef
= (Value
& 0x00000f00) >> 8;
252 else if (pAd
->CommonCfg
.TxStream
== 2)
255 TxPwrRef
= (Value
& 0x00000f00) >> 8;
258 #endif // DOT11_N_SUPPORT //
262 #ifdef DOT11_N_SUPPORT
263 (HTTxMode
.field
.MODE
== MODE_HTGREENFIELD
)
265 #endif // DOT11_N_SUPPORT //
268 for (Idx
= 0; Idx
< MAX_TXPWR_TAB_SIZE
; Idx
++)
270 if ((TxPwrCfg
[Idx
].Mode
== PhyMode
)
271 && (TxPwrCfg
[Idx
].MCS
== HTTxMode
.field
.MCS
))
273 Value
= TxPwr
[TxPwrCfg
[Idx
].req
];
274 DaltaPwr
= TxPwrRef
- (CHAR
)((Value
& TxPwrCfg
[Idx
].BitMask
)
275 >> TxPwrCfg
[Idx
].shift
);
276 CurTxPwr
-= DaltaPwr
;
285 VOID
MeasureReqTabInit(
286 IN PRTMP_ADAPTER pAd
)
288 NdisAllocateSpinLock(&pAd
->CommonCfg
.MeasureReqTabLock
);
290 pAd
->CommonCfg
.pMeasureReqTab
= kmalloc(sizeof(MEASURE_REQ_TAB
), GFP_ATOMIC
);
291 if (pAd
->CommonCfg
.pMeasureReqTab
)
292 NdisZeroMemory(pAd
->CommonCfg
.pMeasureReqTab
, sizeof(MEASURE_REQ_TAB
));
294 DBGPRINT(RT_DEBUG_ERROR
, ("%s Fail to alloc memory for pAd->CommonCfg.pMeasureReqTab.\n", __FUNCTION__
));
299 VOID
MeasureReqTabExit(
300 IN PRTMP_ADAPTER pAd
)
302 NdisFreeSpinLock(&pAd
->CommonCfg
.MeasureReqTabLock
);
304 if (pAd
->CommonCfg
.pMeasureReqTab
)
305 kfree(pAd
->CommonCfg
.pMeasureReqTab
);
306 pAd
->CommonCfg
.pMeasureReqTab
= NULL
;
311 PMEASURE_REQ_ENTRY
MeasureReqLookUp(
312 IN PRTMP_ADAPTER pAd
,
313 IN UINT8 DialogToken
)
316 PMEASURE_REQ_TAB pTab
= pAd
->CommonCfg
.pMeasureReqTab
;
317 PMEASURE_REQ_ENTRY pEntry
= NULL
;
318 PMEASURE_REQ_ENTRY pPrevEntry
= NULL
;
322 DBGPRINT(RT_DEBUG_ERROR
, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__
));
326 RTMP_SEM_LOCK(&pAd
->CommonCfg
.MeasureReqTabLock
);
328 HashIdx
= MQ_DIALOGTOKEN_HASH_INDEX(DialogToken
);
329 pEntry
= pTab
->Hash
[HashIdx
];
333 if (pEntry
->DialogToken
== DialogToken
)
338 pEntry
= pEntry
->pNext
;
342 RTMP_SEM_UNLOCK(&pAd
->CommonCfg
.MeasureReqTabLock
);
347 PMEASURE_REQ_ENTRY
MeasureReqInsert(
348 IN PRTMP_ADAPTER pAd
,
349 IN UINT8 DialogToken
)
353 PMEASURE_REQ_TAB pTab
= pAd
->CommonCfg
.pMeasureReqTab
;
354 PMEASURE_REQ_ENTRY pEntry
= NULL
, pCurrEntry
;
359 DBGPRINT(RT_DEBUG_ERROR
, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__
));
363 pEntry
= MeasureReqLookUp(pAd
, DialogToken
);
366 RTMP_SEM_LOCK(&pAd
->CommonCfg
.MeasureReqTabLock
);
367 for (i
= 0; i
< MAX_MEASURE_REQ_TAB_SIZE
; i
++)
369 NdisGetSystemUpTime(&Now
);
370 pEntry
= &pTab
->Content
[i
];
372 if ((pEntry
->Valid
== TRUE
)
373 && RTMP_TIME_AFTER((unsigned long)Now
, (unsigned long)(pEntry
->lastTime
+ MQ_REQ_AGE_OUT
)))
375 PMEASURE_REQ_ENTRY pPrevEntry
= NULL
;
376 ULONG HashIdx
= MQ_DIALOGTOKEN_HASH_INDEX(pEntry
->DialogToken
);
377 PMEASURE_REQ_ENTRY pProbeEntry
= pTab
->Hash
[HashIdx
];
382 if (pProbeEntry
== pEntry
)
384 if (pPrevEntry
== NULL
)
386 pTab
->Hash
[HashIdx
] = pEntry
->pNext
;
390 pPrevEntry
->pNext
= pEntry
->pNext
;
395 pPrevEntry
= pProbeEntry
;
396 pProbeEntry
= pProbeEntry
->pNext
;
397 } while (pProbeEntry
);
399 NdisZeroMemory(pEntry
, sizeof(MEASURE_REQ_ENTRY
));
405 if (pEntry
->Valid
== FALSE
)
409 if (i
< MAX_MEASURE_REQ_TAB_SIZE
)
411 NdisGetSystemUpTime(&Now
);
412 pEntry
->lastTime
= Now
;
413 pEntry
->Valid
= TRUE
;
414 pEntry
->DialogToken
= DialogToken
;
420 DBGPRINT(RT_DEBUG_ERROR
, ("%s: pMeasureReqTab tab full.\n", __FUNCTION__
));
423 // add this Neighbor entry into HASH table
426 HashIdx
= MQ_DIALOGTOKEN_HASH_INDEX(DialogToken
);
427 if (pTab
->Hash
[HashIdx
] == NULL
)
429 pTab
->Hash
[HashIdx
] = pEntry
;
433 pCurrEntry
= pTab
->Hash
[HashIdx
];
434 while (pCurrEntry
->pNext
!= NULL
)
435 pCurrEntry
= pCurrEntry
->pNext
;
436 pCurrEntry
->pNext
= pEntry
;
440 RTMP_SEM_UNLOCK(&pAd
->CommonCfg
.MeasureReqTabLock
);
446 VOID
MeasureReqDelete(
447 IN PRTMP_ADAPTER pAd
,
448 IN UINT8 DialogToken
)
450 PMEASURE_REQ_TAB pTab
= pAd
->CommonCfg
.pMeasureReqTab
;
451 PMEASURE_REQ_ENTRY pEntry
= NULL
;
455 DBGPRINT(RT_DEBUG_ERROR
, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__
));
462 DBGPRINT(RT_DEBUG_ERROR
, ("pMeasureReqTab empty.\n"));
466 pEntry
= MeasureReqLookUp(pAd
, DialogToken
);
469 PMEASURE_REQ_ENTRY pPrevEntry
= NULL
;
470 ULONG HashIdx
= MQ_DIALOGTOKEN_HASH_INDEX(pEntry
->DialogToken
);
471 PMEASURE_REQ_ENTRY pProbeEntry
= pTab
->Hash
[HashIdx
];
473 RTMP_SEM_LOCK(&pAd
->CommonCfg
.MeasureReqTabLock
);
477 if (pProbeEntry
== pEntry
)
479 if (pPrevEntry
== NULL
)
481 pTab
->Hash
[HashIdx
] = pEntry
->pNext
;
485 pPrevEntry
->pNext
= pEntry
->pNext
;
490 pPrevEntry
= pProbeEntry
;
491 pProbeEntry
= pProbeEntry
->pNext
;
492 } while (pProbeEntry
);
494 NdisZeroMemory(pEntry
, sizeof(MEASURE_REQ_ENTRY
));
497 RTMP_SEM_UNLOCK(&pAd
->CommonCfg
.MeasureReqTabLock
);
504 IN PRTMP_ADAPTER pAd
)
506 NdisAllocateSpinLock(&pAd
->CommonCfg
.TpcReqTabLock
);
508 pAd
->CommonCfg
.pTpcReqTab
= kmalloc(sizeof(TPC_REQ_TAB
), GFP_ATOMIC
);
509 if (pAd
->CommonCfg
.pTpcReqTab
)
510 NdisZeroMemory(pAd
->CommonCfg
.pTpcReqTab
, sizeof(TPC_REQ_TAB
));
512 DBGPRINT(RT_DEBUG_ERROR
, ("%s Fail to alloc memory for pAd->CommonCfg.pTpcReqTab.\n", __FUNCTION__
));
518 IN PRTMP_ADAPTER pAd
)
520 NdisFreeSpinLock(&pAd
->CommonCfg
.TpcReqTabLock
);
522 if (pAd
->CommonCfg
.pTpcReqTab
)
523 kfree(pAd
->CommonCfg
.pTpcReqTab
);
524 pAd
->CommonCfg
.pTpcReqTab
= NULL
;
529 static PTPC_REQ_ENTRY
TpcReqLookUp(
530 IN PRTMP_ADAPTER pAd
,
531 IN UINT8 DialogToken
)
534 PTPC_REQ_TAB pTab
= pAd
->CommonCfg
.pTpcReqTab
;
535 PTPC_REQ_ENTRY pEntry
= NULL
;
536 PTPC_REQ_ENTRY pPrevEntry
= NULL
;
540 DBGPRINT(RT_DEBUG_ERROR
, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__
));
544 RTMP_SEM_LOCK(&pAd
->CommonCfg
.TpcReqTabLock
);
546 HashIdx
= TPC_DIALOGTOKEN_HASH_INDEX(DialogToken
);
547 pEntry
= pTab
->Hash
[HashIdx
];
551 if (pEntry
->DialogToken
== DialogToken
)
556 pEntry
= pEntry
->pNext
;
560 RTMP_SEM_UNLOCK(&pAd
->CommonCfg
.TpcReqTabLock
);
566 static PTPC_REQ_ENTRY
TpcReqInsert(
567 IN PRTMP_ADAPTER pAd
,
568 IN UINT8 DialogToken
)
572 PTPC_REQ_TAB pTab
= pAd
->CommonCfg
.pTpcReqTab
;
573 PTPC_REQ_ENTRY pEntry
= NULL
, pCurrEntry
;
578 DBGPRINT(RT_DEBUG_ERROR
, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__
));
582 pEntry
= TpcReqLookUp(pAd
, DialogToken
);
585 RTMP_SEM_LOCK(&pAd
->CommonCfg
.TpcReqTabLock
);
586 for (i
= 0; i
< MAX_TPC_REQ_TAB_SIZE
; i
++)
588 NdisGetSystemUpTime(&Now
);
589 pEntry
= &pTab
->Content
[i
];
591 if ((pEntry
->Valid
== TRUE
)
592 && RTMP_TIME_AFTER((unsigned long)Now
, (unsigned long)(pEntry
->lastTime
+ TPC_REQ_AGE_OUT
)))
594 PTPC_REQ_ENTRY pPrevEntry
= NULL
;
595 ULONG HashIdx
= TPC_DIALOGTOKEN_HASH_INDEX(pEntry
->DialogToken
);
596 PTPC_REQ_ENTRY pProbeEntry
= pTab
->Hash
[HashIdx
];
601 if (pProbeEntry
== pEntry
)
603 if (pPrevEntry
== NULL
)
605 pTab
->Hash
[HashIdx
] = pEntry
->pNext
;
609 pPrevEntry
->pNext
= pEntry
->pNext
;
614 pPrevEntry
= pProbeEntry
;
615 pProbeEntry
= pProbeEntry
->pNext
;
616 } while (pProbeEntry
);
618 NdisZeroMemory(pEntry
, sizeof(TPC_REQ_ENTRY
));
624 if (pEntry
->Valid
== FALSE
)
628 if (i
< MAX_TPC_REQ_TAB_SIZE
)
630 NdisGetSystemUpTime(&Now
);
631 pEntry
->lastTime
= Now
;
632 pEntry
->Valid
= TRUE
;
633 pEntry
->DialogToken
= DialogToken
;
639 DBGPRINT(RT_DEBUG_ERROR
, ("%s: pTpcReqTab tab full.\n", __FUNCTION__
));
642 // add this Neighbor entry into HASH table
645 HashIdx
= TPC_DIALOGTOKEN_HASH_INDEX(DialogToken
);
646 if (pTab
->Hash
[HashIdx
] == NULL
)
648 pTab
->Hash
[HashIdx
] = pEntry
;
652 pCurrEntry
= pTab
->Hash
[HashIdx
];
653 while (pCurrEntry
->pNext
!= NULL
)
654 pCurrEntry
= pCurrEntry
->pNext
;
655 pCurrEntry
->pNext
= pEntry
;
659 RTMP_SEM_UNLOCK(&pAd
->CommonCfg
.TpcReqTabLock
);
665 static VOID
TpcReqDelete(
666 IN PRTMP_ADAPTER pAd
,
667 IN UINT8 DialogToken
)
669 PTPC_REQ_TAB pTab
= pAd
->CommonCfg
.pTpcReqTab
;
670 PTPC_REQ_ENTRY pEntry
= NULL
;
674 DBGPRINT(RT_DEBUG_ERROR
, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__
));
681 DBGPRINT(RT_DEBUG_ERROR
, ("pTpcReqTab empty.\n"));
685 pEntry
= TpcReqLookUp(pAd
, DialogToken
);
688 PTPC_REQ_ENTRY pPrevEntry
= NULL
;
689 ULONG HashIdx
= TPC_DIALOGTOKEN_HASH_INDEX(pEntry
->DialogToken
);
690 PTPC_REQ_ENTRY pProbeEntry
= pTab
->Hash
[HashIdx
];
692 RTMP_SEM_LOCK(&pAd
->CommonCfg
.TpcReqTabLock
);
696 if (pProbeEntry
== pEntry
)
698 if (pPrevEntry
== NULL
)
700 pTab
->Hash
[HashIdx
] = pEntry
->pNext
;
704 pPrevEntry
->pNext
= pEntry
->pNext
;
709 pPrevEntry
= pProbeEntry
;
710 pProbeEntry
= pProbeEntry
->pNext
;
711 } while (pProbeEntry
);
713 NdisZeroMemory(pEntry
, sizeof(TPC_REQ_ENTRY
));
716 RTMP_SEM_UNLOCK(&pAd
->CommonCfg
.TpcReqTabLock
);
723 ==========================================================================
725 Get Current TimeS tamp.
729 Return : Current Time Stamp.
730 ==========================================================================
732 static UINT64
GetCurrentTimeStamp(
733 IN PRTMP_ADAPTER pAd
)
735 // get current time stamp.
740 ==========================================================================
742 Get Current Transmit Power.
746 Return : Current Time Stamp.
747 ==========================================================================
749 static UINT8
GetCurTxPwr(
750 IN PRTMP_ADAPTER pAd
,
753 return 16; /* 16 dBm */
757 ==========================================================================
759 Get Current Transmit Power.
763 Return : Current Time Stamp.
764 ==========================================================================
766 VOID
InsertChannelRepIE(
767 IN PRTMP_ADAPTER pAd
,
768 OUT PUCHAR pFrameBuf
,
769 OUT PULONG pFrameLen
,
771 IN UINT8 RegulatoryClass
)
775 UINT8 IEId
= IE_AP_CHANNEL_REPORT
;
776 PUCHAR pChListPtr
= NULL
;
779 if (strncmp(pCountry
, "US", 2) == 0)
781 if (RegulatoryClass
>= USA_REGULATORY_INFO_SIZE
)
783 DBGPRINT(RT_DEBUG_ERROR
, ("%s: USA Unknow Requlatory class (%d)\n",
784 __FUNCTION__
, RegulatoryClass
));
788 Len
+= USARegulatoryInfo
[RegulatoryClass
].ChannelSet
.NumberOfChannels
;
789 pChListPtr
= USARegulatoryInfo
[RegulatoryClass
].ChannelSet
.ChannelList
;
791 else if (strncmp(pCountry
, "JP", 2) == 0)
793 if (RegulatoryClass
>= JP_REGULATORY_INFO_SIZE
)
795 DBGPRINT(RT_DEBUG_ERROR
, ("%s: JP Unknow Requlatory class (%d)\n",
796 __FUNCTION__
, RegulatoryClass
));
800 Len
+= JapanRegulatoryInfo
[RegulatoryClass
].ChannelSet
.NumberOfChannels
;
801 pChListPtr
= JapanRegulatoryInfo
[RegulatoryClass
].ChannelSet
.ChannelList
;
805 DBGPRINT(RT_DEBUG_ERROR
, ("%s: Unknow Country (%s)\n",
806 __FUNCTION__
, pCountry
));
810 MakeOutgoingFrame(pFrameBuf
, &TempLen
,
817 *pFrameLen
= *pFrameLen
+ TempLen
;
823 ==========================================================================
825 Insert Dialog Token into frame.
828 1. frame buffer pointer.
833 ==========================================================================
835 VOID
InsertDialogToken(
836 IN PRTMP_ADAPTER pAd
,
837 OUT PUCHAR pFrameBuf
,
838 OUT PULONG pFrameLen
,
839 IN UINT8 DialogToken
)
842 MakeOutgoingFrame(pFrameBuf
, &TempLen
,
846 *pFrameLen
= *pFrameLen
+ TempLen
;
852 ==========================================================================
854 Insert TPC Request IE into frame.
857 1. frame buffer pointer.
861 ==========================================================================
863 static VOID
InsertTpcReqIE(
864 IN PRTMP_ADAPTER pAd
,
865 OUT PUCHAR pFrameBuf
,
866 OUT PULONG pFrameLen
)
870 UINT8 ElementID
= IE_TPC_REQUEST
;
872 MakeOutgoingFrame(pFrameBuf
, &TempLen
,
877 *pFrameLen
= *pFrameLen
+ TempLen
;
883 ==========================================================================
885 Insert TPC Report IE into frame.
888 1. frame buffer pointer.
894 ==========================================================================
896 VOID
InsertTpcReportIE(
897 IN PRTMP_ADAPTER pAd
,
898 OUT PUCHAR pFrameBuf
,
899 OUT PULONG pFrameLen
,
904 ULONG Len
= sizeof(TPC_REPORT_INFO
);
905 UINT8 ElementID
= IE_TPC_REPORT
;
906 TPC_REPORT_INFO TpcReportIE
;
908 TpcReportIE
.TxPwr
= TxPwr
;
909 TpcReportIE
.LinkMargin
= LinkMargin
;
911 MakeOutgoingFrame(pFrameBuf
, &TempLen
,
917 *pFrameLen
= *pFrameLen
+ TempLen
;
924 ==========================================================================
926 Insert Channel Switch Announcement IE into frame.
929 1. frame buffer pointer.
931 3. channel switch announcement mode.
932 4. new selected channel.
933 5. channel switch announcement count.
936 ==========================================================================
938 static VOID
InsertChSwAnnIE(
939 IN PRTMP_ADAPTER pAd
,
940 OUT PUCHAR pFrameBuf
,
941 OUT PULONG pFrameLen
,
947 ULONG Len
= sizeof(CH_SW_ANN_INFO
);
948 UINT8 ElementID
= IE_CHANNEL_SWITCH_ANNOUNCEMENT
;
949 CH_SW_ANN_INFO ChSwAnnIE
;
951 ChSwAnnIE
.ChSwMode
= ChSwMode
;
952 ChSwAnnIE
.Channel
= NewChannel
;
953 ChSwAnnIE
.ChSwCnt
= ChSwCnt
;
955 MakeOutgoingFrame(pFrameBuf
, &TempLen
,
961 *pFrameLen
= *pFrameLen
+ TempLen
;
968 ==========================================================================
970 Insert Measure Request IE into frame.
973 1. frame buffer pointer.
976 4. Measure Request Mode.
977 5. Measure Request Type.
979 7. Measure Start time.
984 ==========================================================================
986 static VOID
InsertMeasureReqIE(
987 IN PRTMP_ADAPTER pAd
,
988 OUT PUCHAR pFrameBuf
,
989 OUT PULONG pFrameLen
,
991 IN PMEASURE_REQ_INFO pMeasureReqIE
)
994 UINT8 ElementID
= IE_MEASUREMENT_REQUEST
;
996 MakeOutgoingFrame(pFrameBuf
, &TempLen
,
999 sizeof(MEASURE_REQ_INFO
), pMeasureReqIE
,
1002 *pFrameLen
= *pFrameLen
+ TempLen
;
1008 ==========================================================================
1010 Insert Measure Report IE into frame.
1013 1. frame buffer pointer.
1016 4. Measure Request Mode.
1017 5. Measure Request Type.
1018 6. Length of Report Infomation
1019 7. Pointer of Report Infomation Buffer.
1022 ==========================================================================
1024 static VOID
InsertMeasureReportIE(
1025 IN PRTMP_ADAPTER pAd
,
1026 OUT PUCHAR pFrameBuf
,
1027 OUT PULONG pFrameLen
,
1028 IN PMEASURE_REPORT_INFO pMeasureReportIE
,
1029 IN UINT8 ReportLnfoLen
,
1030 IN PUINT8 pReportInfo
)
1034 UINT8 ElementID
= IE_MEASUREMENT_REPORT
;
1036 Len
= sizeof(MEASURE_REPORT_INFO
) + ReportLnfoLen
;
1038 MakeOutgoingFrame(pFrameBuf
, &TempLen
,
1041 Len
, pMeasureReportIE
,
1044 *pFrameLen
= *pFrameLen
+ TempLen
;
1046 if ((ReportLnfoLen
> 0) && (pReportInfo
!= NULL
))
1048 MakeOutgoingFrame(pFrameBuf
+ *pFrameLen
, &TempLen
,
1049 ReportLnfoLen
, pReportInfo
,
1052 *pFrameLen
= *pFrameLen
+ TempLen
;
1058 ==========================================================================
1060 Prepare Measurement request action frame and enqueue it into
1061 management queue waiting for transmition.
1064 1. the destination mac address of the frame.
1067 ==========================================================================
1069 VOID
MakeMeasurementReqFrame(
1070 IN PRTMP_ADAPTER pAd
,
1071 OUT PUCHAR pOutBuffer
,
1072 OUT PULONG pFrameLen
,
1076 IN UINT8 MeasureToken
,
1077 IN UINT8 MeasureReqMode
,
1078 IN UINT8 MeasureReqType
,
1079 IN UINT8 NumOfRepetitions
)
1082 MEASURE_REQ_INFO MeasureReqIE
;
1084 InsertActField(pAd
, (pOutBuffer
+ *pFrameLen
), pFrameLen
, Category
, Action
);
1086 // fill Dialog Token
1087 InsertDialogToken(pAd
, (pOutBuffer
+ *pFrameLen
), pFrameLen
, MeasureToken
);
1089 /* fill Number of repetitions. */
1090 if (Category
== CATEGORY_RM
)
1092 MakeOutgoingFrame((pOutBuffer
+*pFrameLen
), &TempLen
,
1093 2, &NumOfRepetitions
,
1096 *pFrameLen
+= TempLen
;
1099 // prepare Measurement IE.
1100 NdisZeroMemory(&MeasureReqIE
, sizeof(MEASURE_REQ_INFO
));
1101 MeasureReqIE
.Token
= MeasureToken
;
1102 MeasureReqIE
.ReqMode
.word
= MeasureReqMode
;
1103 MeasureReqIE
.ReqType
= MeasureReqType
;
1104 InsertMeasureReqIE(pAd
, (pOutBuffer
+*pFrameLen
), pFrameLen
,
1105 TotalLen
, &MeasureReqIE
);
1111 ==========================================================================
1113 Prepare Measurement report action frame and enqueue it into
1114 management queue waiting for transmition.
1117 1. the destination mac address of the frame.
1120 ==========================================================================
1122 VOID
EnqueueMeasurementRep(
1123 IN PRTMP_ADAPTER pAd
,
1125 IN UINT8 DialogToken
,
1126 IN UINT8 MeasureToken
,
1127 IN UINT8 MeasureReqMode
,
1128 IN UINT8 MeasureReqType
,
1129 IN UINT8 ReportInfoLen
,
1130 IN PUINT8 pReportInfo
)
1132 PUCHAR pOutBuffer
= NULL
;
1133 NDIS_STATUS NStatus
;
1135 HEADER_802_11 ActHdr
;
1136 MEASURE_REPORT_INFO MeasureRepIE
;
1138 // build action frame header.
1139 MgtMacHeaderInit(pAd
, &ActHdr
, SUBTYPE_ACTION
, 0, pDA
,
1140 pAd
->CurrentAddress
);
1142 NStatus
= MlmeAllocateMemory(pAd
, (PVOID
)&pOutBuffer
); //Get an unused nonpaged memory
1143 if(NStatus
!= NDIS_STATUS_SUCCESS
)
1145 DBGPRINT(RT_DEBUG_TRACE
, ("%s() allocate memory failed \n", __FUNCTION__
));
1148 NdisMoveMemory(pOutBuffer
, (PCHAR
)&ActHdr
, sizeof(HEADER_802_11
));
1149 FrameLen
= sizeof(HEADER_802_11
);
1151 InsertActField(pAd
, (pOutBuffer
+ FrameLen
), &FrameLen
, CATEGORY_SPECTRUM
, SPEC_MRP
);
1153 // fill Dialog Token
1154 InsertDialogToken(pAd
, (pOutBuffer
+ FrameLen
), &FrameLen
, DialogToken
);
1156 // prepare Measurement IE.
1157 NdisZeroMemory(&MeasureRepIE
, sizeof(MEASURE_REPORT_INFO
));
1158 MeasureRepIE
.Token
= MeasureToken
;
1159 MeasureRepIE
.ReportMode
= MeasureReqMode
;
1160 MeasureRepIE
.ReportType
= MeasureReqType
;
1161 InsertMeasureReportIE(pAd
, (pOutBuffer
+ FrameLen
), &FrameLen
, &MeasureRepIE
, ReportInfoLen
, pReportInfo
);
1163 MiniportMMRequest(pAd
, QID_AC_BE
, pOutBuffer
, FrameLen
);
1164 MlmeFreeMemory(pAd
, pOutBuffer
);
1170 ==========================================================================
1172 Prepare TPC Request action frame and enqueue it into
1173 management queue waiting for transmition.
1176 1. the destination mac address of the frame.
1179 ==========================================================================
1182 IN PRTMP_ADAPTER pAd
,
1184 IN UCHAR DialogToken
)
1186 PUCHAR pOutBuffer
= NULL
;
1187 NDIS_STATUS NStatus
;
1190 HEADER_802_11 ActHdr
;
1192 // build action frame header.
1193 MgtMacHeaderInit(pAd
, &ActHdr
, SUBTYPE_ACTION
, 0, pDA
,
1194 pAd
->CurrentAddress
);
1196 NStatus
= MlmeAllocateMemory(pAd
, (PVOID
)&pOutBuffer
); //Get an unused nonpaged memory
1197 if(NStatus
!= NDIS_STATUS_SUCCESS
)
1199 DBGPRINT(RT_DEBUG_TRACE
, ("%s() allocate memory failed \n", __FUNCTION__
));
1202 NdisMoveMemory(pOutBuffer
, (PCHAR
)&ActHdr
, sizeof(HEADER_802_11
));
1203 FrameLen
= sizeof(HEADER_802_11
);
1205 InsertActField(pAd
, (pOutBuffer
+ FrameLen
), &FrameLen
, CATEGORY_SPECTRUM
, SPEC_TPCRQ
);
1207 // fill Dialog Token
1208 InsertDialogToken(pAd
, (pOutBuffer
+ FrameLen
), &FrameLen
, DialogToken
);
1210 // Insert TPC Request IE.
1211 InsertTpcReqIE(pAd
, (pOutBuffer
+ FrameLen
), &FrameLen
);
1213 MiniportMMRequest(pAd
, QID_AC_BE
, pOutBuffer
, FrameLen
);
1214 MlmeFreeMemory(pAd
, pOutBuffer
);
1220 ==========================================================================
1222 Prepare TPC Report action frame and enqueue it into
1223 management queue waiting for transmition.
1226 1. the destination mac address of the frame.
1229 ==========================================================================
1232 IN PRTMP_ADAPTER pAd
,
1234 IN UINT8 DialogToken
,
1236 IN UINT8 LinkMargin
)
1238 PUCHAR pOutBuffer
= NULL
;
1239 NDIS_STATUS NStatus
;
1242 HEADER_802_11 ActHdr
;
1244 // build action frame header.
1245 MgtMacHeaderInit(pAd
, &ActHdr
, SUBTYPE_ACTION
, 0, pDA
,
1246 pAd
->CurrentAddress
);
1248 NStatus
= MlmeAllocateMemory(pAd
, (PVOID
)&pOutBuffer
); //Get an unused nonpaged memory
1249 if(NStatus
!= NDIS_STATUS_SUCCESS
)
1251 DBGPRINT(RT_DEBUG_TRACE
, ("%s() allocate memory failed \n", __FUNCTION__
));
1254 NdisMoveMemory(pOutBuffer
, (PCHAR
)&ActHdr
, sizeof(HEADER_802_11
));
1255 FrameLen
= sizeof(HEADER_802_11
);
1257 InsertActField(pAd
, (pOutBuffer
+ FrameLen
), &FrameLen
, CATEGORY_SPECTRUM
, SPEC_TPCRP
);
1259 // fill Dialog Token
1260 InsertDialogToken(pAd
, (pOutBuffer
+ FrameLen
), &FrameLen
, DialogToken
);
1262 // Insert TPC Request IE.
1263 InsertTpcReportIE(pAd
, (pOutBuffer
+ FrameLen
), &FrameLen
, TxPwr
, LinkMargin
);
1265 MiniportMMRequest(pAd
, QID_AC_BE
, pOutBuffer
, FrameLen
);
1266 MlmeFreeMemory(pAd
, pOutBuffer
);
1272 ==========================================================================
1274 Prepare Channel Switch Announcement action frame and enqueue it into
1275 management queue waiting for transmition.
1278 1. the destination mac address of the frame.
1279 2. Channel switch announcement mode.
1280 2. a New selected channel.
1283 ==========================================================================
1285 VOID
EnqueueChSwAnn(
1286 IN PRTMP_ADAPTER pAd
,
1291 PUCHAR pOutBuffer
= NULL
;
1292 NDIS_STATUS NStatus
;
1295 HEADER_802_11 ActHdr
;
1297 // build action frame header.
1298 MgtMacHeaderInit(pAd
, &ActHdr
, SUBTYPE_ACTION
, 0, pDA
,
1299 pAd
->CurrentAddress
);
1301 NStatus
= MlmeAllocateMemory(pAd
, (PVOID
)&pOutBuffer
); //Get an unused nonpaged memory
1302 if(NStatus
!= NDIS_STATUS_SUCCESS
)
1304 DBGPRINT(RT_DEBUG_TRACE
, ("%s() allocate memory failed \n", __FUNCTION__
));
1307 NdisMoveMemory(pOutBuffer
, (PCHAR
)&ActHdr
, sizeof(HEADER_802_11
));
1308 FrameLen
= sizeof(HEADER_802_11
);
1310 InsertActField(pAd
, (pOutBuffer
+ FrameLen
), &FrameLen
, CATEGORY_SPECTRUM
, SPEC_CHANNEL_SWITCH
);
1312 InsertChSwAnnIE(pAd
, (pOutBuffer
+ FrameLen
), &FrameLen
, ChSwMode
, NewCh
, 0);
1314 MiniportMMRequest(pAd
, QID_AC_BE
, pOutBuffer
, FrameLen
);
1315 MlmeFreeMemory(pAd
, pOutBuffer
);
1320 static BOOLEAN
DfsRequirementCheck(
1321 IN PRTMP_ADAPTER pAd
,
1324 BOOLEAN Result
= FALSE
;
1329 // check DFS procedure is running.
1330 // make sure DFS procedure won't start twice.
1331 if (pAd
->CommonCfg
.RadarDetect
.RDMode
!= RD_NORMAL_MODE
)
1337 // check the new channel carried from Channel Switch Announcemnet is valid.
1338 for (i
=0; i
<pAd
->ChannelListNum
; i
++)
1340 if ((Channel
== pAd
->ChannelList
[i
].Channel
)
1341 &&(pAd
->ChannelList
[i
].RemainingTimeForUse
== 0))
1343 // found radar signal in the channel. the channel can't use at least for 30 minutes.
1344 pAd
->ChannelList
[i
].RemainingTimeForUse
= 1800;//30 min = 1800 sec
1354 VOID
NotifyChSwAnnToPeerAPs(
1355 IN PRTMP_ADAPTER pAd
,
1362 if (!((pRA
[0] & 0xff) == 0xff)) // is pRA a broadcase address.
1365 // info neighbor APs that Radar signal found throgh WDS link.
1366 for (i
= 0; i
< MAX_WDS_ENTRY
; i
++)
1368 if (ValidWdsEntry(pAd
, i
))
1370 PUCHAR pDA
= pAd
->WdsTab
.WdsEntry
[i
].PeerWdsAddr
;
1372 // DA equal to SA. have no necessary orignal AP which found Radar signal.
1373 if (MAC_ADDR_EQUAL(pTA
, pDA
))
1376 // send Channel Switch Action frame to info Neighbro APs.
1377 EnqueueChSwAnn(pAd
, pDA
, ChSwMode
, Channel
);
1381 #endif // WDS_SUPPORT //
1384 static VOID
StartDFSProcedure(
1385 IN PRTMP_ADAPTER pAd
,
1389 // start DFS procedure
1390 pAd
->CommonCfg
.Channel
= Channel
;
1391 #ifdef DOT11_N_SUPPORT
1392 N_ChannelCheck(pAd
);
1393 #endif // DOT11_N_SUPPORT //
1394 pAd
->CommonCfg
.RadarDetect
.RDMode
= RD_SWITCHING_MODE
;
1395 pAd
->CommonCfg
.RadarDetect
.CSCount
= 0;
1399 ==========================================================================
1401 Channel Switch Announcement action frame sanity check.
1404 1. MLME message containing the received frame
1406 3. Channel switch announcement infomation buffer.
1410 ==========================================================================
1414 Channel Switch Announcement IE.
1415 +----+-----+-----------+------------+-----------+
1416 | ID | Len |Ch Sw Mode | New Ch Num | Ch Sw Cnt |
1417 +----+-----+-----------+------------+-----------+
1420 static BOOLEAN
PeerChSwAnnSanity(
1421 IN PRTMP_ADAPTER pAd
,
1424 OUT PCH_SW_ANN_INFO pChSwAnnInfo
)
1426 PFRAME_802_11 Fr
= (PFRAME_802_11
)pMsg
;
1427 PUCHAR pFramePtr
= Fr
->Octet
;
1428 BOOLEAN result
= FALSE
;
1429 PEID_STRUCT eid_ptr
;
1431 // skip 802.11 header.
1432 MsgLen
-= sizeof(HEADER_802_11
);
1434 // skip category and action code.
1438 if (pChSwAnnInfo
== NULL
)
1441 eid_ptr
= (PEID_STRUCT
)pFramePtr
;
1442 while (((UCHAR
*)eid_ptr
+ eid_ptr
->Len
+ 1) < ((PUCHAR
)pFramePtr
+ MsgLen
))
1444 switch(eid_ptr
->Eid
)
1446 case IE_CHANNEL_SWITCH_ANNOUNCEMENT
:
1447 NdisMoveMemory(&pChSwAnnInfo
->ChSwMode
, eid_ptr
->Octet
, 1);
1448 NdisMoveMemory(&pChSwAnnInfo
->Channel
, eid_ptr
->Octet
+ 1, 1);
1449 NdisMoveMemory(&pChSwAnnInfo
->ChSwCnt
, eid_ptr
->Octet
+ 2, 1);
1457 eid_ptr
= (PEID_STRUCT
)((UCHAR
*)eid_ptr
+ 2 + eid_ptr
->Len
);
1464 ==========================================================================
1466 Measurement request action frame sanity check.
1469 1. MLME message containing the received frame
1471 3. Measurement request infomation buffer.
1474 ==========================================================================
1476 static BOOLEAN
PeerMeasureReqSanity(
1477 IN PRTMP_ADAPTER pAd
,
1480 OUT PUINT8 pDialogToken
,
1481 OUT PMEASURE_REQ_INFO pMeasureReqInfo
,
1482 OUT PMEASURE_REQ pMeasureReq
)
1484 PFRAME_802_11 Fr
= (PFRAME_802_11
)pMsg
;
1485 PUCHAR pFramePtr
= Fr
->Octet
;
1486 BOOLEAN result
= FALSE
;
1487 PEID_STRUCT eid_ptr
;
1489 UINT64 MeasureStartTime
;
1490 UINT16 MeasureDuration
;
1492 // skip 802.11 header.
1493 MsgLen
-= sizeof(HEADER_802_11
);
1495 // skip category and action code.
1499 if (pMeasureReqInfo
== NULL
)
1502 NdisMoveMemory(pDialogToken
, pFramePtr
, 1);
1506 eid_ptr
= (PEID_STRUCT
)pFramePtr
;
1507 while (((UCHAR
*)eid_ptr
+ eid_ptr
->Len
+ 1) < ((PUCHAR
)pFramePtr
+ MsgLen
))
1509 switch(eid_ptr
->Eid
)
1511 case IE_MEASUREMENT_REQUEST
:
1512 NdisMoveMemory(&pMeasureReqInfo
->Token
, eid_ptr
->Octet
, 1);
1513 NdisMoveMemory(&pMeasureReqInfo
->ReqMode
.word
, eid_ptr
->Octet
+ 1, 1);
1514 NdisMoveMemory(&pMeasureReqInfo
->ReqType
, eid_ptr
->Octet
+ 2, 1);
1515 ptr
= (PUCHAR
)(eid_ptr
->Octet
+ 3);
1516 NdisMoveMemory(&pMeasureReq
->ChNum
, ptr
, 1);
1517 NdisMoveMemory(&MeasureStartTime
, ptr
+ 1, 8);
1518 pMeasureReq
->MeasureStartTime
= SWAP64(MeasureStartTime
);
1519 NdisMoveMemory(&MeasureDuration
, ptr
+ 9, 2);
1520 pMeasureReq
->MeasureDuration
= SWAP16(MeasureDuration
);
1528 eid_ptr
= (PEID_STRUCT
)((UCHAR
*)eid_ptr
+ 2 + eid_ptr
->Len
);
1535 ==========================================================================
1537 Measurement report action frame sanity check.
1540 1. MLME message containing the received frame
1542 3. Measurement report infomation buffer.
1543 4. basic report infomation buffer.
1546 ==========================================================================
1550 Measurement Report IE.
1551 +----+-----+-------+-------------+--------------+----------------+
1552 | ID | Len | Token | Report Mode | Measure Type | Measure Report |
1553 +----+-----+-------+-------------+--------------+----------------+
1557 +--------+------------+----------+-----+
1558 | Ch Num | Start Time | Duration | Map |
1559 +--------+------------+----------+-----+
1562 Map Field Bit Format.
1563 +-----+---------------+---------------------+-------+------------+----------+
1564 | Bss | OFDM Preamble | Unidentified signal | Radar | Unmeasured | Reserved |
1565 +-----+---------------+---------------------+-------+------------+----------+
1568 static BOOLEAN
PeerMeasureReportSanity(
1569 IN PRTMP_ADAPTER pAd
,
1572 OUT PUINT8 pDialogToken
,
1573 OUT PMEASURE_REPORT_INFO pMeasureReportInfo
,
1574 OUT PUINT8 pReportBuf
)
1576 PFRAME_802_11 Fr
= (PFRAME_802_11
)pMsg
;
1577 PUCHAR pFramePtr
= Fr
->Octet
;
1578 BOOLEAN result
= FALSE
;
1579 PEID_STRUCT eid_ptr
;
1582 // skip 802.11 header.
1583 MsgLen
-= sizeof(HEADER_802_11
);
1585 // skip category and action code.
1589 if (pMeasureReportInfo
== NULL
)
1592 NdisMoveMemory(pDialogToken
, pFramePtr
, 1);
1596 eid_ptr
= (PEID_STRUCT
)pFramePtr
;
1597 while (((UCHAR
*)eid_ptr
+ eid_ptr
->Len
+ 1) < ((PUCHAR
)pFramePtr
+ MsgLen
))
1599 switch(eid_ptr
->Eid
)
1601 case IE_MEASUREMENT_REPORT
:
1602 NdisMoveMemory(&pMeasureReportInfo
->Token
, eid_ptr
->Octet
, 1);
1603 NdisMoveMemory(&pMeasureReportInfo
->ReportMode
, eid_ptr
->Octet
+ 1, 1);
1604 NdisMoveMemory(&pMeasureReportInfo
->ReportType
, eid_ptr
->Octet
+ 2, 1);
1605 if (pMeasureReportInfo
->ReportType
== RM_BASIC
)
1607 PMEASURE_BASIC_REPORT pReport
= (PMEASURE_BASIC_REPORT
)pReportBuf
;
1608 ptr
= (PUCHAR
)(eid_ptr
->Octet
+ 3);
1609 NdisMoveMemory(&pReport
->ChNum
, ptr
, 1);
1610 NdisMoveMemory(&pReport
->MeasureStartTime
, ptr
+ 1, 8);
1611 NdisMoveMemory(&pReport
->MeasureDuration
, ptr
+ 9, 2);
1612 NdisMoveMemory(&pReport
->Map
, ptr
+ 11, 1);
1615 else if (pMeasureReportInfo
->ReportType
== RM_CCA
)
1617 PMEASURE_CCA_REPORT pReport
= (PMEASURE_CCA_REPORT
)pReportBuf
;
1618 ptr
= (PUCHAR
)(eid_ptr
->Octet
+ 3);
1619 NdisMoveMemory(&pReport
->ChNum
, ptr
, 1);
1620 NdisMoveMemory(&pReport
->MeasureStartTime
, ptr
+ 1, 8);
1621 NdisMoveMemory(&pReport
->MeasureDuration
, ptr
+ 9, 2);
1622 NdisMoveMemory(&pReport
->CCA_Busy_Fraction
, ptr
+ 11, 1);
1625 else if (pMeasureReportInfo
->ReportType
== RM_RPI_HISTOGRAM
)
1627 PMEASURE_RPI_REPORT pReport
= (PMEASURE_RPI_REPORT
)pReportBuf
;
1628 ptr
= (PUCHAR
)(eid_ptr
->Octet
+ 3);
1629 NdisMoveMemory(&pReport
->ChNum
, ptr
, 1);
1630 NdisMoveMemory(&pReport
->MeasureStartTime
, ptr
+ 1, 8);
1631 NdisMoveMemory(&pReport
->MeasureDuration
, ptr
+ 9, 2);
1632 NdisMoveMemory(&pReport
->RPI_Density
, ptr
+ 11, 8);
1640 eid_ptr
= (PEID_STRUCT
)((UCHAR
*)eid_ptr
+ 2 + eid_ptr
->Len
);
1647 ==========================================================================
1649 TPC Request action frame sanity check.
1652 1. MLME message containing the received frame
1657 ==========================================================================
1659 static BOOLEAN
PeerTpcReqSanity(
1660 IN PRTMP_ADAPTER pAd
,
1663 OUT PUINT8 pDialogToken
)
1665 PFRAME_802_11 Fr
= (PFRAME_802_11
)pMsg
;
1666 PUCHAR pFramePtr
= Fr
->Octet
;
1667 BOOLEAN result
= FALSE
;
1668 PEID_STRUCT eid_ptr
;
1670 MsgLen
-= sizeof(HEADER_802_11
);
1672 // skip category and action code.
1676 if (pDialogToken
== NULL
)
1679 NdisMoveMemory(pDialogToken
, pFramePtr
, 1);
1683 eid_ptr
= (PEID_STRUCT
)pFramePtr
;
1684 while (((UCHAR
*)eid_ptr
+ eid_ptr
->Len
+ 1) < ((PUCHAR
)pFramePtr
+ MsgLen
))
1686 switch(eid_ptr
->Eid
)
1688 case IE_TPC_REQUEST
:
1695 eid_ptr
= (PEID_STRUCT
)((UCHAR
*)eid_ptr
+ 2 + eid_ptr
->Len
);
1702 ==========================================================================
1704 TPC Report action frame sanity check.
1707 1. MLME message containing the received frame
1713 ==========================================================================
1715 static BOOLEAN
PeerTpcRepSanity(
1716 IN PRTMP_ADAPTER pAd
,
1719 OUT PUINT8 pDialogToken
,
1720 OUT PTPC_REPORT_INFO pTpcRepInfo
)
1722 PFRAME_802_11 Fr
= (PFRAME_802_11
)pMsg
;
1723 PUCHAR pFramePtr
= Fr
->Octet
;
1724 BOOLEAN result
= FALSE
;
1725 PEID_STRUCT eid_ptr
;
1727 MsgLen
-= sizeof(HEADER_802_11
);
1729 // skip category and action code.
1733 if (pDialogToken
== NULL
)
1736 NdisMoveMemory(pDialogToken
, pFramePtr
, 1);
1740 eid_ptr
= (PEID_STRUCT
)pFramePtr
;
1741 while (((UCHAR
*)eid_ptr
+ eid_ptr
->Len
+ 1) < ((PUCHAR
)pFramePtr
+ MsgLen
))
1743 switch(eid_ptr
->Eid
)
1746 NdisMoveMemory(&pTpcRepInfo
->TxPwr
, eid_ptr
->Octet
, 1);
1747 NdisMoveMemory(&pTpcRepInfo
->LinkMargin
, eid_ptr
->Octet
+ 1, 1);
1754 eid_ptr
= (PEID_STRUCT
)((UCHAR
*)eid_ptr
+ 2 + eid_ptr
->Len
);
1761 ==========================================================================
1763 Channel Switch Announcement action frame handler.
1766 Elme - MLME message containing the received frame
1769 ==========================================================================
1771 static VOID
PeerChSwAnnAction(
1772 IN PRTMP_ADAPTER pAd
,
1773 IN MLME_QUEUE_ELEM
*Elem
)
1775 CH_SW_ANN_INFO ChSwAnnInfo
;
1776 PFRAME_802_11 pFr
= (PFRAME_802_11
)Elem
->Msg
;
1777 #ifdef CONFIG_STA_SUPPORT
1778 UCHAR index
= 0, Channel
= 0, NewChannel
= 0;
1780 #endif // CONFIG_STA_SUPPORT //
1782 NdisZeroMemory(&ChSwAnnInfo
, sizeof(CH_SW_ANN_INFO
));
1783 if (! PeerChSwAnnSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, &ChSwAnnInfo
))
1785 DBGPRINT(RT_DEBUG_TRACE
, ("Invalid Channel Switch Action Frame.\n"));
1790 #ifdef CONFIG_STA_SUPPORT
1791 if (pAd
->OpMode
== OPMODE_STA
)
1793 Bssidx
= BssTableSearch(&pAd
->ScanTab
, pFr
->Hdr
.Addr3
, pAd
->CommonCfg
.Channel
);
1794 if (Bssidx
== BSS_NOT_FOUND
)
1796 DBGPRINT(RT_DEBUG_TRACE
, ("PeerChSwAnnAction - Bssidx is not found\n"));
1800 DBGPRINT(RT_DEBUG_TRACE
, ("\n****Bssidx is %d, Channel = %d\n", index
, pAd
->ScanTab
.BssEntry
[Bssidx
].Channel
));
1801 hex_dump("SSID",pAd
->ScanTab
.BssEntry
[Bssidx
].Bssid
,6);
1803 Channel
= pAd
->CommonCfg
.Channel
;
1804 NewChannel
= ChSwAnnInfo
.Channel
;
1806 if ((pAd
->CommonCfg
.bIEEE80211H
== 1) && (NewChannel
!= 0) && (Channel
!= NewChannel
))
1808 // Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection).
1809 // In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results.
1810 AsicSwitchChannel(pAd
, 1, FALSE
);
1811 AsicLockChannel(pAd
, 1);
1812 LinkDown(pAd
, FALSE
);
1813 MlmeQueueInit(&pAd
->Mlme
.Queue
);
1814 BssTableInit(&pAd
->ScanTab
);
1815 RTMPusecDelay(1000000); // use delay to prevent STA do reassoc
1817 // channel sanity check
1818 for (index
= 0 ; index
< pAd
->ChannelListNum
; index
++)
1820 if (pAd
->ChannelList
[index
].Channel
== NewChannel
)
1822 pAd
->ScanTab
.BssEntry
[Bssidx
].Channel
= NewChannel
;
1823 pAd
->CommonCfg
.Channel
= NewChannel
;
1824 AsicSwitchChannel(pAd
, pAd
->CommonCfg
.Channel
, FALSE
);
1825 AsicLockChannel(pAd
, pAd
->CommonCfg
.Channel
);
1826 DBGPRINT(RT_DEBUG_TRACE
, ("&&&&&&&&&&&&&&&&PeerChSwAnnAction - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel
));
1831 if (index
>= pAd
->ChannelListNum
)
1833 DBGPRINT_ERR(("&&&&&&&&&&&&&&&&&&&&&&&&&&PeerChSwAnnAction(can not find New Channel=%d in ChannelList[%d]\n", pAd
->CommonCfg
.Channel
, pAd
->ChannelListNum
));
1837 #endif // CONFIG_STA_SUPPORT //
1844 ==========================================================================
1846 Measurement Request action frame handler.
1849 Elme - MLME message containing the received frame
1852 ==========================================================================
1854 static VOID
PeerMeasureReqAction(
1855 IN PRTMP_ADAPTER pAd
,
1856 IN MLME_QUEUE_ELEM
*Elem
)
1858 PFRAME_802_11 pFr
= (PFRAME_802_11
)Elem
->Msg
;
1860 MEASURE_REQ_INFO MeasureReqInfo
;
1861 MEASURE_REQ MeasureReq
;
1862 MEASURE_REPORT_MODE ReportMode
;
1864 if(PeerMeasureReqSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, &DialogToken
, &MeasureReqInfo
, &MeasureReq
))
1866 ReportMode
.word
= 0;
1867 ReportMode
.field
.Incapable
= 1;
1868 EnqueueMeasurementRep(pAd
, pFr
->Hdr
.Addr2
, DialogToken
, MeasureReqInfo
.Token
, ReportMode
.word
, MeasureReqInfo
.ReqType
, 0, NULL
);
1875 ==========================================================================
1877 Measurement Report action frame handler.
1880 Elme - MLME message containing the received frame
1883 ==========================================================================
1885 static VOID
PeerMeasureReportAction(
1886 IN PRTMP_ADAPTER pAd
,
1887 IN MLME_QUEUE_ELEM
*Elem
)
1889 MEASURE_REPORT_INFO MeasureReportInfo
;
1890 PFRAME_802_11 pFr
= (PFRAME_802_11
)Elem
->Msg
;
1892 PUINT8 pMeasureReportInfo
;
1894 // if (pAd->CommonCfg.bIEEE80211H != TRUE)
1897 if ((pMeasureReportInfo
= kmalloc(sizeof(MEASURE_RPI_REPORT
), GFP_ATOMIC
)) == NULL
)
1899 DBGPRINT(RT_DEBUG_ERROR
, ("%s unable to alloc memory for measure report buffer (size=%d).\n", __FUNCTION__
, sizeof(MEASURE_RPI_REPORT
)));
1903 NdisZeroMemory(&MeasureReportInfo
, sizeof(MEASURE_REPORT_INFO
));
1904 NdisZeroMemory(pMeasureReportInfo
, sizeof(MEASURE_RPI_REPORT
));
1905 if (PeerMeasureReportSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, &DialogToken
, &MeasureReportInfo
, pMeasureReportInfo
))
1908 PMEASURE_REQ_ENTRY pEntry
= NULL
;
1910 // Not a autonomous measure report.
1911 // check the dialog token field. drop it if the dialog token doesn't match.
1912 if ((DialogToken
!= 0)
1913 && ((pEntry
= MeasureReqLookUp(pAd
, DialogToken
)) == NULL
))
1917 MeasureReqDelete(pAd
, pEntry
->DialogToken
);
1919 if (MeasureReportInfo
.ReportType
== RM_BASIC
)
1921 PMEASURE_BASIC_REPORT pBasicReport
= (PMEASURE_BASIC_REPORT
)pMeasureReportInfo
;
1922 if ((pBasicReport
->Map
.field
.Radar
)
1923 && (DfsRequirementCheck(pAd
, pBasicReport
->ChNum
) == TRUE
))
1925 NotifyChSwAnnToPeerAPs(pAd
, pFr
->Hdr
.Addr1
, pFr
->Hdr
.Addr2
, 1, pBasicReport
->ChNum
);
1926 StartDFSProcedure(pAd
, pBasicReport
->ChNum
, 1);
1932 DBGPRINT(RT_DEBUG_TRACE
, ("Invalid Measurement Report Frame.\n"));
1934 kfree(pMeasureReportInfo
);
1940 ==========================================================================
1942 TPC Request action frame handler.
1945 Elme - MLME message containing the received frame
1948 ==========================================================================
1950 static VOID
PeerTpcReqAction(
1951 IN PRTMP_ADAPTER pAd
,
1952 IN MLME_QUEUE_ELEM
*Elem
)
1954 PFRAME_802_11 pFr
= (PFRAME_802_11
)Elem
->Msg
;
1955 PUCHAR pFramePtr
= pFr
->Octet
;
1957 UINT8 TxPwr
= GetCurTxPwr(pAd
, Elem
->Wcid
);
1958 UINT8 LinkMargin
= 0;
1961 // link margin: Ratio of the received signal power to the minimum desired by the station (STA). The
1962 // STA may incorporate rate information and channel conditions, including interference, into its computation
1965 RealRssi
= RTMPMaxRssi(pAd
, ConvertToRssi(pAd
, Elem
->Rssi0
, RSSI_0
),
1966 ConvertToRssi(pAd
, Elem
->Rssi1
, RSSI_1
),
1967 ConvertToRssi(pAd
, Elem
->Rssi2
, RSSI_2
));
1969 // skip Category and action code.
1973 NdisMoveMemory(&DialogToken
, pFramePtr
, 1);
1975 LinkMargin
= (RealRssi
/ MIN_RCV_PWR
);
1976 if (PeerTpcReqSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, &DialogToken
))
1977 EnqueueTPCRep(pAd
, pFr
->Hdr
.Addr2
, DialogToken
, TxPwr
, LinkMargin
);
1983 ==========================================================================
1985 TPC Report action frame handler.
1988 Elme - MLME message containing the received frame
1991 ==========================================================================
1993 static VOID
PeerTpcRepAction(
1994 IN PRTMP_ADAPTER pAd
,
1995 IN MLME_QUEUE_ELEM
*Elem
)
1998 TPC_REPORT_INFO TpcRepInfo
;
1999 PTPC_REQ_ENTRY pEntry
= NULL
;
2001 NdisZeroMemory(&TpcRepInfo
, sizeof(TPC_REPORT_INFO
));
2002 if (PeerTpcRepSanity(pAd
, Elem
->Msg
, Elem
->MsgLen
, &DialogToken
, &TpcRepInfo
))
2004 if ((pEntry
= TpcReqLookUp(pAd
, DialogToken
)) != NULL
)
2006 TpcReqDelete(pAd
, pEntry
->DialogToken
);
2007 DBGPRINT(RT_DEBUG_TRACE
, ("%s: DialogToken=%x, TxPwr=%d, LinkMargin=%d\n",
2008 __FUNCTION__
, DialogToken
, TpcRepInfo
.TxPwr
, TpcRepInfo
.LinkMargin
));
2016 ==========================================================================
2018 Spectrun action frames Handler such as channel switch annoucement,
2019 measurement report, measurement request actions frames.
2022 Elme - MLME message containing the received frame
2025 ==========================================================================
2027 VOID
PeerSpectrumAction(
2028 IN PRTMP_ADAPTER pAd
,
2029 IN MLME_QUEUE_ELEM
*Elem
)
2032 UCHAR Action
= Elem
->Msg
[LENGTH_802_11
+1];
2034 if (pAd
->CommonCfg
.bIEEE80211H
!= TRUE
)
2040 // current rt2860 unable do such measure specified in Measurement Request.
2041 // reject all measurement request.
2042 PeerMeasureReqAction(pAd
, Elem
);
2046 PeerMeasureReportAction(pAd
, Elem
);
2050 PeerTpcReqAction(pAd
, Elem
);
2054 PeerTpcRepAction(pAd
, Elem
);
2057 case SPEC_CHANNEL_SWITCH
:
2059 #ifdef DOT11N_DRAFT3
2061 SEC_CHA_OFFSET_IE Secondary
;
2062 CHA_SWITCH_ANNOUNCE_IE ChannelSwitch
;
2064 // 802.11h only has Channel Switch Announcement IE.
2065 RTMPMoveMemory(&ChannelSwitch
, &Elem
->Msg
[LENGTH_802_11
+4], sizeof (CHA_SWITCH_ANNOUNCE_IE
));
2067 // 802.11n D3.03 adds secondary channel offset element in the end.
2068 if (Elem
->MsgLen
== (LENGTH_802_11
+ 2 + sizeof (CHA_SWITCH_ANNOUNCE_IE
) + sizeof (SEC_CHA_OFFSET_IE
)))
2070 RTMPMoveMemory(&Secondary
, &Elem
->Msg
[LENGTH_802_11
+9], sizeof (SEC_CHA_OFFSET_IE
));
2074 Secondary
.SecondaryChannelOffset
= 0;
2077 if ((Elem
->Msg
[LENGTH_802_11
+2] == IE_CHANNEL_SWITCH_ANNOUNCEMENT
) && (Elem
->Msg
[LENGTH_802_11
+3] == 3))
2079 ChannelSwitchAction(pAd
, Elem
->Wcid
, ChannelSwitch
.NewChannel
, Secondary
.SecondaryChannelOffset
);
2082 #endif // DOT11N_DRAFT3 //
2084 PeerChSwAnnAction(pAd
, Elem
);
2092 ==========================================================================
2098 ==========================================================================
2100 INT
Set_MeasureReq_Proc(
2101 IN PRTMP_ADAPTER pAd
,
2108 MEASURE_REQ_MODE MeasureReqMode
;
2109 UINT8 MeasureReqToken
= RandomByte(pAd
);
2110 UINT8 MeasureReqType
= RM_BASIC
;
2111 UINT8 MeasureCh
= 1;
2112 UINT64 MeasureStartTime
= GetCurrentTimeStamp(pAd
);
2113 MEASURE_REQ MeasureReq
;
2116 HEADER_802_11 ActHdr
;
2117 PUCHAR pOutBuffer
= NULL
;
2118 NDIS_STATUS NStatus
;
2121 NStatus
= MlmeAllocateMemory(pAd
, (PVOID
)&pOutBuffer
); //Get an unused nonpaged memory
2122 if(NStatus
!= NDIS_STATUS_SUCCESS
)
2124 DBGPRINT(RT_DEBUG_TRACE
, ("%s() allocate memory failed \n", __FUNCTION__
));
2125 goto END_OF_MEASURE_REQ
;
2129 while ((thisChar
= strsep((char **)&arg
, "-")) != NULL
)
2134 Aid
= (UINT8
) simple_strtol(thisChar
, 0, 16);
2137 case 2: // Measurement Request Type.
2138 MeasureReqType
= simple_strtol(thisChar
, 0, 16);
2139 if (MeasureReqType
> 3)
2141 DBGPRINT(RT_DEBUG_ERROR
, ("%s: unknow MeasureReqType(%d)\n", __FUNCTION__
, MeasureReqType
));
2142 goto END_OF_MEASURE_REQ
;
2146 case 3: // Measurement channel.
2147 MeasureCh
= (UINT8
) simple_strtol(thisChar
, 0, 16);
2153 DBGPRINT(RT_DEBUG_TRACE
, ("%s::Aid = %d, MeasureReqType=%d MeasureCh=%d\n", __FUNCTION__
, Aid
, MeasureReqType
, MeasureCh
));
2154 if (!VALID_WCID(Aid
))
2156 DBGPRINT(RT_DEBUG_ERROR
, ("%s: unknow sta of Aid(%d)\n", __FUNCTION__
, Aid
));
2157 goto END_OF_MEASURE_REQ
;
2160 MeasureReqMode
.word
= 0;
2161 MeasureReqMode
.field
.Enable
= 1;
2163 MeasureReqInsert(pAd
, MeasureReqToken
);
2165 // build action frame header.
2166 MgtMacHeaderInit(pAd
, &ActHdr
, SUBTYPE_ACTION
, 0, pAd
->MacTab
.Content
[Aid
].Addr
,
2167 pAd
->CurrentAddress
);
2169 NdisMoveMemory(pOutBuffer
, (PCHAR
)&ActHdr
, sizeof(HEADER_802_11
));
2170 FrameLen
= sizeof(HEADER_802_11
);
2172 TotalLen
= sizeof(MEASURE_REQ_INFO
) + sizeof(MEASURE_REQ
);
2174 MakeMeasurementReqFrame(pAd
, pOutBuffer
, &FrameLen
,
2175 sizeof(MEASURE_REQ_INFO
), CATEGORY_RM
, RM_BASIC
,
2176 MeasureReqToken
, MeasureReqMode
.word
,
2179 MeasureReq
.ChNum
= MeasureCh
;
2180 MeasureReq
.MeasureStartTime
= cpu2le64(MeasureStartTime
);
2181 MeasureReq
.MeasureDuration
= cpu2le16(2000);
2185 MakeOutgoingFrame( pOutBuffer
+FrameLen
, &TempLen
,
2186 sizeof(MEASURE_REQ
), &MeasureReq
,
2188 FrameLen
+= TempLen
;
2191 MiniportMMRequest(pAd
, QID_AC_BE
, pOutBuffer
, (UINT
)FrameLen
);
2194 MlmeFreeMemory(pAd
, pOutBuffer
);
2199 INT
Set_TpcReq_Proc(
2200 IN PRTMP_ADAPTER pAd
,
2205 UINT8 TpcReqToken
= RandomByte(pAd
);
2207 Aid
= (UINT
) simple_strtol(arg
, 0, 16);
2209 DBGPRINT(RT_DEBUG_TRACE
, ("%s::Aid = %d\n", __FUNCTION__
, Aid
));
2210 if (!VALID_WCID(Aid
))
2212 DBGPRINT(RT_DEBUG_ERROR
, ("%s: unknow sta of Aid(%d)\n", __FUNCTION__
, Aid
));
2216 TpcReqInsert(pAd
, TpcReqToken
);
2218 EnqueueTPCReq(pAd
, pAd
->MacTab
.Content
[Aid
].Addr
, TpcReqToken
);