143d72104a24752677c8ce474d0c865720477a48
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / mt5931 / 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
177 rlmObssScanTimeout (
178     P_ADAPTER_T prAdapter,
179     UINT_32     u4Data
180     );
181
182 /*******************************************************************************
183 *                              F U N C T I O N S
184 ********************************************************************************
185 */
186
187 /*----------------------------------------------------------------------------*/
188 /*!
189 * \brief
190 *
191 * \param[in]
192 *
193 * \return none
194 */
195 /*----------------------------------------------------------------------------*/
196 VOID
197 rlmObssInit (
198     P_ADAPTER_T     prAdapter
199     )
200 {
201     P_BSS_INFO_T    prBssInfo;
202     UINT_8          ucNetIdx;
203
204     RLM_NET_FOR_EACH(ucNetIdx) {
205         prBssInfo = &prAdapter->rWifiVar.arBssInfo[ucNetIdx];
206         ASSERT(prBssInfo);
207
208         cnmTimerInitTimer(prAdapter, &prBssInfo->rObssScanTimer,
209             rlmObssScanTimeout, (UINT_32) prBssInfo);
210     } /* end of RLM_NET_FOR_EACH */
211 }
212
213 /*----------------------------------------------------------------------------*/
214 /*!
215 * \brief
216 *
217 * \param[in]
218 *
219 * \return none
220 */
221 /*----------------------------------------------------------------------------*/
222 BOOLEAN
223 rlmObssUpdateChnlLists (
224     P_ADAPTER_T prAdapter,
225     P_SW_RFB_T  prSwRfb
226     )
227 {
228     return TRUE;
229 }
230
231 /*----------------------------------------------------------------------------*/
232 /*!
233 * \brief
234 *
235 * \param[in]
236 *
237 * \return none
238 */
239 /*----------------------------------------------------------------------------*/
240 VOID
241 rlmObssScanDone (
242     P_ADAPTER_T prAdapter,
243     P_MSG_HDR_T prMsgHdr
244     )
245 {
246     P_MSG_SCN_SCAN_DONE             prScanDoneMsg;
247     P_BSS_INFO_T                    prBssInfo;
248     P_MSDU_INFO_T                   prMsduInfo;
249     P_ACTION_20_40_COEXIST_FRAME    prTxFrame;
250     UINT_16                         i, u2PayloadLen;
251
252     ASSERT(prMsgHdr);
253
254     prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr;
255     prBssInfo = &prAdapter->rWifiVar.arBssInfo[prScanDoneMsg->ucNetTypeIndex];
256     ASSERT(prBssInfo);
257
258     DBGLOG(RLM, INFO, ("OBSS Scan Done (NetIdx=%d, Mode=%d)\n",
259         prScanDoneMsg->ucNetTypeIndex, prBssInfo->eCurrentOPMode));
260
261     cnmMemFree(prAdapter, prMsgHdr);
262
263 #if CFG_ENABLE_WIFI_DIRECT
264     /* AP mode */
265     if ((prAdapter->fgIsP2PRegistered) &&
266         (IS_NET_ACTIVE(prAdapter, prBssInfo->ucNetTypeIndex)) &&
267         (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) {
268         return;
269     }
270 #endif
271
272     /* STA mode */
273     if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE ||
274         !RLM_NET_PARAM_VALID(prBssInfo) || prBssInfo->u2ObssScanInterval == 0) {
275         DBGLOG(RLM, WARN, ("OBSS Scan Done (NetIdx=%d) -- Aborted!!\n",
276             prBssInfo->ucNetTypeIndex));
277         return;
278     }
279
280     /* To do: check 2.4G channel list to decide if obss mgmt should be
281      *        sent to associated AP. Note: how to handle concurrent network?
282      * To do: invoke rlmObssChnlLevel() to decide if 20/40 BSS coexistence
283      *        management frame is needed.
284      */
285     if ((prBssInfo->auc2G_20mReqChnlList[0] > 0 ||
286          prBssInfo->auc2G_NonHtChnlList[0] > 0) &&
287         (prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter,
288                       MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN)) != NULL) {
289
290         DBGLOG(RLM, INFO, ("Send 20/40 coexistence mgmt(20mReq=%d, NonHt=%d)\n",
291             prBssInfo->auc2G_20mReqChnlList[0],
292             prBssInfo->auc2G_NonHtChnlList[0]));
293
294         prTxFrame = (P_ACTION_20_40_COEXIST_FRAME)
295             ((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
296
297         prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION;
298         COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID);
299         COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr);
300         COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID);
301
302         prTxFrame->ucCategory = CATEGORY_PUBLIC_ACTION;
303         prTxFrame->ucAction = ACTION_PUBLIC_20_40_COEXIST;
304
305         /* To do: find correct algorithm */
306         prTxFrame->rBssCoexist.ucId = ELEM_ID_20_40_BSS_COEXISTENCE;
307         prTxFrame->rBssCoexist.ucLength = 1;
308         prTxFrame->rBssCoexist.ucData =
309             (prBssInfo->auc2G_20mReqChnlList[0] > 0) ? BSS_COEXIST_20M_REQ : 0;
310
311         u2PayloadLen = 2 + 3;
312
313         if (prBssInfo->auc2G_NonHtChnlList[0] > 0) {
314             ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G);
315
316             prTxFrame->rChnlReport.ucId = ELEM_ID_20_40_INTOLERANT_CHNL_REPORT;
317             prTxFrame->rChnlReport.ucLength =
318                 prBssInfo->auc2G_NonHtChnlList[0] + 1;
319             prTxFrame->rChnlReport.ucRegulatoryClass = 81; /* 2.4GHz, ch1~13 */
320             for (i = 0; i < prBssInfo->auc2G_NonHtChnlList[0] &&
321                  i < CHNL_LIST_SZ_2G; i++) {
322                 prTxFrame->rChnlReport.aucChannelList[i] =
323                     prBssInfo->auc2G_NonHtChnlList[i+1];
324             }
325
326             u2PayloadLen += IE_SIZE(&prTxFrame->rChnlReport);
327         }
328         ASSERT((WLAN_MAC_HEADER_LEN + u2PayloadLen) <= PUBLIC_ACTION_MAX_LEN);
329
330         /* Clear up channel lists in 2.4G band */
331         prBssInfo->auc2G_20mReqChnlList[0] = 0;
332         prBssInfo->auc2G_NonHtChnlList[0] = 0;
333
334
335         //4 Update information of MSDU_INFO_T
336         prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;   /* Management frame */
337         prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex;
338         prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex;
339         prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
340         prMsduInfo->fgIs802_1x = FALSE;
341         prMsduInfo->fgIs802_11 = TRUE;
342         prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
343         prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
344         prMsduInfo->pfTxDoneHandler = NULL;
345         prMsduInfo->fgIsBasicRate = FALSE;
346
347         //4 Enqueue the frame to send this action frame.
348         nicTxEnqueueMsdu(prAdapter, prMsduInfo);
349     } /* end of prMsduInfo != NULL */
350
351     if (prBssInfo->u2ObssScanInterval > 0) {
352         DBGLOG(RLM, INFO, ("Set OBSS timer (NetIdx=%d, %d sec)\n",
353             prBssInfo->ucNetTypeIndex, prBssInfo->u2ObssScanInterval));
354
355         cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer,
356             prBssInfo->u2ObssScanInterval * MSEC_PER_SEC);
357     }
358 }
359
360 /*----------------------------------------------------------------------------*/
361 /*!
362 * \brief
363 *
364 * \param[in]
365 *
366 * \return none
367 */
368 /*----------------------------------------------------------------------------*/
369 static VOID
370 rlmObssScanTimeout (
371     P_ADAPTER_T prAdapter,
372     UINT_32     u4Data
373     )
374 {
375     P_BSS_INFO_T        prBssInfo;
376
377     prBssInfo = (P_BSS_INFO_T) u4Data;
378     ASSERT(prBssInfo);
379
380 #if CFG_ENABLE_WIFI_DIRECT
381     /* AP mode */
382     if (prAdapter->fgIsP2PRegistered &&
383         (IS_NET_ACTIVE(prAdapter, prBssInfo->ucNetTypeIndex)) &&
384         (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) {
385
386         prBssInfo->fgObssActionForcedTo20M = FALSE;
387
388         /* Check if Beacon content need to be updated */
389         rlmUpdateParamsForAP(prAdapter, prBssInfo, FALSE);
390         
391         return;
392     }
393 #endif /* end of CFG_ENABLE_WIFI_DIRECT */
394
395
396     /* STA mode */
397     if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE ||
398         !RLM_NET_PARAM_VALID(prBssInfo) || prBssInfo->u2ObssScanInterval == 0) {
399         DBGLOG(RLM, WARN, ("OBSS Scan timeout (NetIdx=%d) -- Aborted!!\n",
400             prBssInfo->ucNetTypeIndex));
401         return;
402     }
403
404     rlmObssTriggerScan(prAdapter, prBssInfo);
405 }
406
407 /*----------------------------------------------------------------------------*/
408 /*!
409 * \brief
410 *
411 * \param[in]
412 *
413 * \return none
414 */
415 /*----------------------------------------------------------------------------*/
416 VOID
417 rlmObssTriggerScan (
418     P_ADAPTER_T         prAdapter,
419     P_BSS_INFO_T        prBssInfo
420     )
421 {
422     P_MSG_SCN_SCAN_REQ  prScanReqMsg;
423
424     ASSERT(prBssInfo);
425
426     prScanReqMsg = (P_MSG_SCN_SCAN_REQ)
427             cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_REQ));
428     ASSERT(prScanReqMsg);
429
430     if (!prScanReqMsg) {
431         DBGLOG(RLM, WARN, ("No buf for OBSS scan (NetIdx=%d)!!\n",
432             prBssInfo->ucNetTypeIndex));
433
434         cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer,
435             prBssInfo->u2ObssScanInterval * MSEC_PER_SEC);
436         return;
437     }
438
439     /* It is ok that ucSeqNum is set to fixed value because the same network
440      * OBSS scan interval is limited to OBSS_SCAN_MIN_INTERVAL (min 10 sec)
441      * and scan module don't care seqNum of OBSS scanning
442      */
443     prScanReqMsg->rMsgHdr.eMsgId = MID_RLM_SCN_SCAN_REQ;
444     prScanReqMsg->ucSeqNum = 0x33;
445     prScanReqMsg->ucNetTypeIndex = prBssInfo->ucNetTypeIndex;
446     prScanReqMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN;
447     prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_WILDCARD;
448     prScanReqMsg->ucSSIDLength = 0;
449     prScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4;
450     prScanReqMsg->u2IELen = 0;
451
452     mboxSendMsg(prAdapter,
453                 MBOX_ID_0,
454                 (P_MSG_HDR_T) prScanReqMsg,
455                 MSG_SEND_METHOD_BUF);
456
457     DBGLOG(RLM, INFO, ("Timeout to trigger OBSS scan (NetIdx=%d)!!\n",
458         prBssInfo->ucNetTypeIndex));
459 }
460
461