rlm_obss.c 14 KB

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