Commit | Line | Data |
---|---|---|
6fa3eb70 S |
1 | /* |
2 | ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm_obss.c#2 $ | |
3 | */ | |
4 | ||
5 | /*! \file "rlm_obss.c" | |
6 | \brief | |
7 | ||
8 | */ | |
9 | ||
10 | ||
11 | ||
12 | /* | |
13 | ** $Log: rlm_obss.c $ | |
14 | * | |
15 | * 07 17 2012 yuche.tsai | |
16 | * NULL | |
17 | * Compile no error before trial run. | |
18 | * | |
19 | * 11 15 2011 cm.chang | |
20 | * NULL | |
21 | * Avoid possible OBSS scan when BSS is switched | |
22 | * | |
23 | * 11 08 2011 cm.chang | |
24 | * NULL | |
25 | * Add RLM and CNM debug message for XLOG | |
26 | * | |
27 | * 10 25 2011 cm.chang | |
28 | * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode | |
29 | * Regulation class is changed to 81 in 20_40_coexistence action frame | |
30 | * | |
31 | * 04 12 2011 cm.chang | |
32 | * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency | |
33 | * . | |
34 | * | |
35 | * 03 29 2011 cm.chang | |
36 | * [WCXRP00000606] [MT6620 Wi-Fi][Driver][FW] Fix klocwork warning | |
37 | * As CR title | |
38 | * | |
39 | * 01 24 2011 cm.chang | |
40 | * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode and stop ampdu timer when sta_rec is freed | |
41 | * Process received 20/40 coexistence action frame for AP mode | |
42 | * | |
43 | * 01 13 2011 cm.chang | |
44 | * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module | |
45 | * Refine function when rcv a 20/40M public action frame | |
46 | * | |
47 | * 01 13 2011 cm.chang | |
48 | * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting | |
49 | * Use SCO of BSS_INFO to replace user-defined setting variables | |
50 | * | |
51 | * 01 12 2011 cm.chang | |
52 | * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting | |
53 | * User-defined bandwidth is for 2.4G and 5G individually | |
54 | * | |
55 | * 10 18 2010 cp.wu | |
56 | * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning | |
57 | * use definition macro to replace hard-coded constant | |
58 | * | |
59 | * 09 16 2010 cm.chang | |
60 | * NULL | |
61 | * Change conditional compiling options for BOW | |
62 | * | |
63 | * 09 10 2010 cm.chang | |
64 | * NULL | |
65 | * Always update Beacon content if FW sync OBSS info | |
66 | * | |
67 | * 08 24 2010 cm.chang | |
68 | * NULL | |
69 | * Support RLM initail channel of Ad-hoc, P2P and BOW | |
70 | * | |
71 | * 08 20 2010 cm.chang | |
72 | * NULL | |
73 | * Migrate RLM code to host from FW | |
74 | * | |
75 | * 07 26 2010 yuche.tsai | |
76 | * | |
77 | * Fix compile error while enabling WiFi Direct function. | |
78 | * | |
79 | * 07 21 2010 yuche.tsai | |
80 | * | |
81 | * Add P2P Scan & Scan Result Parsing & Saving. | |
82 | * | |
83 | * 07 08 2010 cp.wu | |
84 | * | |
85 | * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. | |
86 | * | |
87 | * 07 08 2010 cm.chang | |
88 | * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver | |
89 | * Check draft RLM code for HT cap | |
90 | * | |
91 | * 05 07 2010 cm.chang | |
92 | * [BORA00000018]Integrate WIFI part into BORA for the 1st time | |
93 | * Process 20/40 coexistence public action frame in AP mode | |
94 | * | |
95 | * 05 05 2010 cm.chang | |
96 | * [BORA00000018]Integrate WIFI part into BORA for the 1st time | |
97 | * First draft support for 20/40M bandwidth for AP mode | |
98 | * | |
99 | * 04 24 2010 cm.chang | |
100 | * [BORA00000018]Integrate WIFI part into BORA for the 1st time | |
101 | * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW | |
102 | * | |
103 | * 04 13 2010 cm.chang | |
104 | * [BORA00000018]Integrate WIFI part into BORA for the 1st time | |
105 | * Add more ASSERT to check exception | |
106 | * | |
107 | * 04 07 2010 cm.chang | |
108 | * [BORA00000018]Integrate WIFI part into BORA for the 1st time | |
109 | * Add virtual test for OBSS scan | |
110 | * | |
111 | * 03 30 2010 cm.chang | |
112 | * [BORA00000018]Integrate WIFI part into BORA for the 1st time | |
113 | * Support 2.4G OBSS scan | |
114 | * | |
115 | * 03 03 2010 cm.chang | |
116 | * [BORA00000018]Integrate WIFI part into BORA for the 1st time | |
117 | * To support CFG_SUPPORT_BCM_STP | |
118 | * | |
119 | * 02 13 2010 cm.chang | |
120 | * [BORA00000018]Integrate WIFI part into BORA for the 1st time | |
121 | * Support PCO in STA mode | |
122 | * | |
123 | * 02 12 2010 cm.chang | |
124 | * [BORA00000018]Integrate WIFI part into BORA for the 1st time | |
125 | * Use bss info array for concurrent handle | |
126 | * | |
127 | * 02 05 2010 kevin.huang | |
128 | * [BORA00000603][WIFISYS] [New Feature] AAA Module Support | |
129 | * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup | |
130 | * | |
131 | * 01 25 2010 cm.chang | |
132 | * [BORA00000018]Integrate WIFI part into BORA for the 1st time | |
133 | * Support protection and bandwidth switch | |
134 | */ | |
135 | ||
136 | /******************************************************************************* | |
137 | * C O M P I L E R F L A G S | |
138 | ******************************************************************************** | |
139 | */ | |
140 | ||
141 | /******************************************************************************* | |
142 | * E X T E R N A L R E F E R E N C E S | |
143 | ******************************************************************************** | |
144 | */ | |
145 | #include "precomp.h" | |
146 | ||
147 | /******************************************************************************* | |
148 | * C O N S T A N T S | |
149 | ******************************************************************************** | |
150 | */ | |
151 | ||
152 | /******************************************************************************* | |
153 | * D A T A T Y P E S | |
154 | ******************************************************************************** | |
155 | */ | |
156 | ||
157 | /******************************************************************************* | |
158 | * P U B L I C D A T A | |
159 | ******************************************************************************** | |
160 | */ | |
161 | ||
162 | /******************************************************************************* | |
163 | * P R I V A T E D A T A | |
164 | ******************************************************************************** | |
165 | */ | |
166 | ||
167 | /******************************************************************************* | |
168 | * M A C R O S | |
169 | ******************************************************************************** | |
170 | */ | |
171 | ||
172 | /******************************************************************************* | |
173 | * F U N C T I O N D E C L A R A T I O N S | |
174 | ******************************************************************************** | |
175 | */ | |
176 | static VOID rlmObssScanTimeout(P_ADAPTER_T prAdapter, UINT_32 u4Data); | |
177 | ||
178 | /******************************************************************************* | |
179 | * F U N C T I O N S | |
180 | ******************************************************************************** | |
181 | */ | |
182 | ||
183 | /*----------------------------------------------------------------------------*/ | |
184 | /*! | |
185 | * \brief | |
186 | * | |
187 | * \param[in] | |
188 | * | |
189 | * \return none | |
190 | */ | |
191 | /*----------------------------------------------------------------------------*/ | |
192 | VOID rlmObssInit(P_ADAPTER_T prAdapter) | |
193 | { | |
194 | P_BSS_INFO_T prBssInfo; | |
195 | UINT_8 ucNetIdx; | |
196 | ||
197 | RLM_NET_FOR_EACH(ucNetIdx) { | |
198 | prBssInfo = &prAdapter->rWifiVar.arBssInfo[ucNetIdx]; | |
199 | ASSERT(prBssInfo); | |
200 | ||
201 | cnmTimerInitTimer(prAdapter, &prBssInfo->rObssScanTimer, | |
202 | rlmObssScanTimeout, (UINT_32) prBssInfo); | |
203 | } /* end of RLM_NET_FOR_EACH */ | |
204 | } | |
205 | ||
206 | /*----------------------------------------------------------------------------*/ | |
207 | /*! | |
208 | * \brief | |
209 | * | |
210 | * \param[in] | |
211 | * | |
212 | * \return none | |
213 | */ | |
214 | /*----------------------------------------------------------------------------*/ | |
215 | BOOLEAN rlmObssUpdateChnlLists(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) | |
216 | { | |
217 | return TRUE; | |
218 | } | |
219 | ||
220 | /*----------------------------------------------------------------------------*/ | |
221 | /*! | |
222 | * \brief | |
223 | * | |
224 | * \param[in] | |
225 | * | |
226 | * \return none | |
227 | */ | |
228 | /*----------------------------------------------------------------------------*/ | |
229 | VOID rlmObssScanDone(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr) | |
230 | { | |
231 | P_MSG_SCN_SCAN_DONE prScanDoneMsg; | |
232 | P_BSS_INFO_T prBssInfo; | |
233 | P_MSDU_INFO_T prMsduInfo; | |
234 | P_ACTION_20_40_COEXIST_FRAME prTxFrame; | |
235 | UINT_16 i, u2PayloadLen; | |
236 | ||
237 | ASSERT(prMsgHdr); | |
238 | ||
239 | prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr; | |
240 | prBssInfo = &prAdapter->rWifiVar.arBssInfo[prScanDoneMsg->ucNetTypeIndex]; | |
241 | ASSERT(prBssInfo); | |
242 | ||
243 | DBGLOG(RLM, INFO, ("OBSS Scan Done (NetIdx=%d, Mode=%d)\n", | |
244 | prScanDoneMsg->ucNetTypeIndex, prBssInfo->eCurrentOPMode)); | |
245 | ||
246 | cnmMemFree(prAdapter, prMsgHdr); | |
247 | ||
248 | #if CFG_ENABLE_WIFI_DIRECT | |
249 | /* AP mode */ | |
250 | if ((prAdapter->fgIsP2PRegistered) && | |
251 | (IS_NET_ACTIVE(prAdapter, prBssInfo->ucNetTypeIndex)) && | |
252 | (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { | |
253 | return; | |
254 | } | |
255 | #endif | |
256 | ||
257 | /* STA mode */ | |
258 | if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE || | |
259 | !RLM_NET_PARAM_VALID(prBssInfo) || prBssInfo->u2ObssScanInterval == 0) { | |
260 | DBGLOG(RLM, WARN, ("OBSS Scan Done (NetIdx=%d) -- Aborted!!\n", | |
261 | prBssInfo->ucNetTypeIndex)); | |
262 | return; | |
263 | } | |
264 | ||
265 | /* To do: check 2.4G channel list to decide if obss mgmt should be | |
266 | * sent to associated AP. Note: how to handle concurrent network? | |
267 | * To do: invoke rlmObssChnlLevel() to decide if 20/40 BSS coexistence | |
268 | * management frame is needed. | |
269 | */ | |
270 | if ((prBssInfo->auc2G_20mReqChnlList[0] > 0 || | |
271 | prBssInfo->auc2G_NonHtChnlList[0] > 0) && | |
272 | (prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, | |
273 | MAC_TX_RESERVED_FIELD + | |
274 | PUBLIC_ACTION_MAX_LEN)) != NULL) { | |
275 | ||
276 | DBGLOG(RLM, INFO, ("Send 20/40 coexistence mgmt(20mReq=%d, NonHt=%d)\n", | |
277 | prBssInfo->auc2G_20mReqChnlList[0], | |
278 | prBssInfo->auc2G_NonHtChnlList[0])); | |
279 | ||
280 | prTxFrame = (P_ACTION_20_40_COEXIST_FRAME) | |
281 | ((UINT_32) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); | |
282 | ||
283 | prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; | |
284 | COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID); | |
285 | COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); | |
286 | COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); | |
287 | ||
288 | prTxFrame->ucCategory = CATEGORY_PUBLIC_ACTION; | |
289 | prTxFrame->ucAction = ACTION_PUBLIC_20_40_COEXIST; | |
290 | ||
291 | /* To do: find correct algorithm */ | |
292 | prTxFrame->rBssCoexist.ucId = ELEM_ID_20_40_BSS_COEXISTENCE; | |
293 | prTxFrame->rBssCoexist.ucLength = 1; | |
294 | prTxFrame->rBssCoexist.ucData = | |
295 | (prBssInfo->auc2G_20mReqChnlList[0] > 0) ? BSS_COEXIST_20M_REQ : 0; | |
296 | ||
297 | u2PayloadLen = 2 + 3; | |
298 | ||
299 | if (prBssInfo->auc2G_NonHtChnlList[0] > 0) { | |
300 | ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); | |
301 | ||
302 | prTxFrame->rChnlReport.ucId = ELEM_ID_20_40_INTOLERANT_CHNL_REPORT; | |
303 | prTxFrame->rChnlReport.ucLength = prBssInfo->auc2G_NonHtChnlList[0] + 1; | |
304 | prTxFrame->rChnlReport.ucRegulatoryClass = 81; /* 2.4GHz, ch1~13 */ | |
305 | for (i = 0; i < prBssInfo->auc2G_NonHtChnlList[0] && | |
306 | i < CHNL_LIST_SZ_2G; i++) { | |
307 | prTxFrame->rChnlReport.aucChannelList[i] = | |
308 | prBssInfo->auc2G_NonHtChnlList[i + 1]; | |
309 | } | |
310 | ||
311 | u2PayloadLen += IE_SIZE(&prTxFrame->rChnlReport); | |
312 | } | |
313 | ASSERT((WLAN_MAC_HEADER_LEN + u2PayloadLen) <= PUBLIC_ACTION_MAX_LEN); | |
314 | ||
315 | /* Clear up channel lists in 2.4G band */ | |
316 | prBssInfo->auc2G_20mReqChnlList[0] = 0; | |
317 | prBssInfo->auc2G_NonHtChnlList[0] = 0; | |
318 | ||
319 | ||
320 | /* 4 Update information of MSDU_INFO_T */ | |
321 | prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */ | |
322 | prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex; | |
323 | prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex; | |
324 | prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; | |
325 | prMsduInfo->fgIs802_1x = FALSE; | |
326 | prMsduInfo->fgIs802_11 = TRUE; | |
327 | prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; | |
328 | prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); | |
329 | prMsduInfo->pfTxDoneHandler = NULL; | |
330 | prMsduInfo->fgIsBasicRate = FALSE; | |
331 | ||
332 | /* 4 Enqueue the frame to send this action frame. */ | |
333 | nicTxEnqueueMsdu(prAdapter, prMsduInfo); | |
334 | } | |
335 | /* end of prMsduInfo != NULL */ | |
336 | if (prBssInfo->u2ObssScanInterval > 0) { | |
337 | DBGLOG(RLM, INFO, ("Set OBSS timer (NetIdx=%d, %d sec)\n", | |
338 | prBssInfo->ucNetTypeIndex, prBssInfo->u2ObssScanInterval)); | |
339 | ||
340 | cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, | |
341 | prBssInfo->u2ObssScanInterval * MSEC_PER_SEC); | |
342 | } | |
343 | } | |
344 | ||
345 | /*----------------------------------------------------------------------------*/ | |
346 | /*! | |
347 | * \brief | |
348 | * | |
349 | * \param[in] | |
350 | * | |
351 | * \return none | |
352 | */ | |
353 | /*----------------------------------------------------------------------------*/ | |
354 | static VOID rlmObssScanTimeout(P_ADAPTER_T prAdapter, UINT_32 u4Data) | |
355 | { | |
356 | P_BSS_INFO_T prBssInfo; | |
357 | ||
358 | prBssInfo = (P_BSS_INFO_T) u4Data; | |
359 | ASSERT(prBssInfo); | |
360 | ||
361 | #if CFG_ENABLE_WIFI_DIRECT | |
362 | /* AP mode */ | |
363 | if (prAdapter->fgIsP2PRegistered && | |
364 | (IS_NET_ACTIVE(prAdapter, prBssInfo->ucNetTypeIndex)) && | |
365 | (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { | |
366 | ||
367 | prBssInfo->fgObssActionForcedTo20M = FALSE; | |
368 | ||
369 | /* Check if Beacon content need to be updated */ | |
370 | rlmUpdateParamsForAP(prAdapter, prBssInfo, FALSE); | |
371 | ||
372 | return; | |
373 | } | |
374 | #endif /* end of CFG_ENABLE_WIFI_DIRECT */ | |
375 | ||
376 | ||
377 | /* STA mode */ | |
378 | if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE || | |
379 | !RLM_NET_PARAM_VALID(prBssInfo) || prBssInfo->u2ObssScanInterval == 0) { | |
380 | DBGLOG(RLM, WARN, ("OBSS Scan timeout (NetIdx=%d) -- Aborted!!\n", | |
381 | prBssInfo->ucNetTypeIndex)); | |
382 | return; | |
383 | } | |
384 | ||
385 | rlmObssTriggerScan(prAdapter, prBssInfo); | |
386 | } | |
387 | ||
388 | /*----------------------------------------------------------------------------*/ | |
389 | /*! | |
390 | * \brief | |
391 | * | |
392 | * \param[in] | |
393 | * | |
394 | * \return none | |
395 | */ | |
396 | /*----------------------------------------------------------------------------*/ | |
397 | VOID rlmObssTriggerScan(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) | |
398 | { | |
399 | P_MSG_SCN_SCAN_REQ prScanReqMsg; | |
400 | ||
401 | ASSERT(prBssInfo); | |
402 | ||
403 | prScanReqMsg = (P_MSG_SCN_SCAN_REQ) | |
404 | cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_REQ)); | |
405 | ASSERT(prScanReqMsg); | |
406 | ||
407 | if (!prScanReqMsg) { | |
408 | DBGLOG(RLM, WARN, ("No buf for OBSS scan (NetIdx=%d)!!\n", | |
409 | prBssInfo->ucNetTypeIndex)); | |
410 | ||
411 | cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, | |
412 | prBssInfo->u2ObssScanInterval * MSEC_PER_SEC); | |
413 | return; | |
414 | } | |
415 | ||
416 | /* It is ok that ucSeqNum is set to fixed value because the same network | |
417 | * OBSS scan interval is limited to OBSS_SCAN_MIN_INTERVAL (min 10 sec) | |
418 | * and scan module don't care seqNum of OBSS scanning | |
419 | */ | |
420 | prScanReqMsg->rMsgHdr.eMsgId = MID_RLM_SCN_SCAN_REQ; | |
421 | prScanReqMsg->ucSeqNum = 0x33; | |
422 | prScanReqMsg->ucNetTypeIndex = prBssInfo->ucNetTypeIndex; | |
423 | prScanReqMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN; | |
424 | prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_WILDCARD; | |
425 | prScanReqMsg->ucSSIDLength = 0; | |
426 | prScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; | |
427 | prScanReqMsg->u2IELen = 0; | |
428 | ||
429 | mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReqMsg, MSG_SEND_METHOD_BUF); | |
430 | ||
431 | DBGLOG(RLM, INFO, ("Timeout to trigger OBSS scan (NetIdx=%d)!!\n", | |
432 | prBssInfo->ucNetTypeIndex)); | |
433 | } |