import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / connectivity / combo / drv_wlan / mt6628 / wlan / mgmt / rlm_obss.c
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 }