p2p_rlm.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905
  1. /*
  2. ** Id: @(#) p2p_rlm.c@@
  3. */
  4. /*! \file "p2p_rlm.c"
  5. \brief
  6. */
  7. /*******************************************************************************
  8. * C O M P I L E R F L A G S
  9. ********************************************************************************
  10. */
  11. /*******************************************************************************
  12. * E X T E R N A L R E F E R E N C E S
  13. ********************************************************************************
  14. */
  15. #include "precomp.h"
  16. /*******************************************************************************
  17. * C O N S T A N T S
  18. ********************************************************************************
  19. */
  20. /*******************************************************************************
  21. * D A T A T Y P E S
  22. ********************************************************************************
  23. */
  24. /*******************************************************************************
  25. * P U B L I C D A T A
  26. ********************************************************************************
  27. */
  28. /*******************************************************************************
  29. * P R I V A T E D A T A
  30. ********************************************************************************
  31. */
  32. /*******************************************************************************
  33. * M A C R O S
  34. ********************************************************************************
  35. */
  36. /*******************************************************************************
  37. * F U N C T I O N D E C L A R A T I O N S
  38. ********************************************************************************
  39. */
  40. /*******************************************************************************
  41. * F U N C T I O N S
  42. ********************************************************************************
  43. */
  44. /*----------------------------------------------------------------------------*/
  45. /*!
  46. * \brief Init AP Bss
  47. *
  48. * \param[in]
  49. *
  50. * \return none
  51. */
  52. /*----------------------------------------------------------------------------*/
  53. VOID rlmBssInitForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo)
  54. {
  55. ENUM_BAND_T eBand;
  56. UINT_8 ucChannel;
  57. ENUM_CHNL_EXT_T eSCO;
  58. ASSERT(prAdapter);
  59. ASSERT(prBssInfo);
  60. if (prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT)
  61. return;
  62. /* Operation band, channel shall be ready before invoking this function.
  63. * Bandwidth may be ready if other network is connected
  64. */
  65. prBssInfo->fg40mBwAllowed = FALSE;
  66. prBssInfo->fgAssoc40mBwAllowed = FALSE;
  67. prBssInfo->eBssSCO = CHNL_EXT_SCN;
  68. if (RLM_AP_IS_BW_40_ALLOWED(prAdapter, prBssInfo)) {
  69. /* In this case, the first BSS's SCO is 40MHz and known, so AP can
  70. * apply 40MHz bandwidth, but the first BSS's SCO may be changed
  71. * later if its Beacon lost timeout occurs
  72. */
  73. if (cnmPreferredChannel(prAdapter, &eBand, &ucChannel, &eSCO) &&
  74. eSCO != CHNL_EXT_SCN && ucChannel == prBssInfo->ucPrimaryChannel && eBand == prBssInfo->eBand) {
  75. prBssInfo->eBssSCO = eSCO;
  76. } else if (cnmBss40mBwPermitted(prAdapter, prBssInfo->ucNetTypeIndex)) {
  77. prBssInfo->eBssSCO = rlmDecideScoForAP(prAdapter, prBssInfo);
  78. }
  79. if (prBssInfo->eBssSCO != CHNL_EXT_SCN) {
  80. prBssInfo->fg40mBwAllowed = TRUE;
  81. prBssInfo->fgAssoc40mBwAllowed = TRUE;
  82. prBssInfo->ucHtOpInfo1 = (UINT_8)
  83. (((UINT_32) prBssInfo->eBssSCO) | HT_OP_INFO1_STA_CHNL_WIDTH);
  84. rlmUpdateBwByChListForAP(prAdapter, prBssInfo);
  85. }
  86. }
  87. DBGLOG(RLM, INFO, "WLAN AP SCO=%d\n", prBssInfo->eBssSCO);
  88. }
  89. /*----------------------------------------------------------------------------*/
  90. /*!
  91. * \brief For probe response (GO, IBSS) and association response
  92. *
  93. * \param[in]
  94. *
  95. * \return none
  96. */
  97. /*----------------------------------------------------------------------------*/
  98. VOID rlmRspGenerateObssScanIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo)
  99. {
  100. P_BSS_INFO_T prBssInfo;
  101. P_IE_OBSS_SCAN_PARAM_T prObssScanIe;
  102. P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL;
  103. ASSERT(prAdapter);
  104. ASSERT(prMsduInfo);
  105. ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType));
  106. prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
  107. prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType];
  108. ASSERT(prBssInfo);
  109. if (RLM_NET_IS_11N(prBssInfo) && !RLM_NET_IS_BOW(prBssInfo) &&
  110. prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT &&
  111. (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) &&
  112. prBssInfo->eBand == BAND_2G4 && prBssInfo->eBssSCO != CHNL_EXT_SCN) {
  113. prObssScanIe = (P_IE_OBSS_SCAN_PARAM_T)
  114. (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength);
  115. /* Add 20/40 BSS coexistence IE */
  116. prObssScanIe->ucId = ELEM_ID_OBSS_SCAN_PARAMS;
  117. prObssScanIe->ucLength = sizeof(IE_OBSS_SCAN_PARAM_T) - ELEM_HDR_LEN;
  118. prObssScanIe->u2ScanPassiveDwell = dot11OBSSScanPassiveDwell;
  119. prObssScanIe->u2ScanActiveDwell = dot11OBSSScanActiveDwell;
  120. prObssScanIe->u2TriggerScanInterval = dot11BSSWidthTriggerScanInterval;
  121. prObssScanIe->u2ScanPassiveTotalPerChnl = dot11OBSSScanPassiveTotalPerChannel;
  122. prObssScanIe->u2ScanActiveTotalPerChnl = dot11OBSSScanActiveTotalPerChannel;
  123. prObssScanIe->u2WidthTransDelayFactor = dot11BSSWidthChannelTransitionDelayFactor;
  124. prObssScanIe->u2ScanActivityThres = dot11OBSSScanActivityThreshold;
  125. ASSERT(IE_SIZE(prObssScanIe) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN));
  126. prMsduInfo->u2FrameLength += IE_SIZE(prObssScanIe);
  127. }
  128. }
  129. /*----------------------------------------------------------------------------*/
  130. /*!
  131. * \brief P2P GO.
  132. *
  133. * \param[in]
  134. *
  135. * \return none
  136. */
  137. /*----------------------------------------------------------------------------*/
  138. BOOLEAN rlmUpdateBwByChListForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo)
  139. {
  140. UINT_8 ucLevel;
  141. BOOLEAN fgBwChange;
  142. ASSERT(prAdapter);
  143. ASSERT(prBssInfo);
  144. fgBwChange = FALSE;
  145. if (prBssInfo->eBssSCO == CHNL_EXT_SCN)
  146. return fgBwChange;
  147. ucLevel = rlmObssChnlLevel(prBssInfo, prBssInfo->eBand, prBssInfo->ucPrimaryChannel, prBssInfo->eBssSCO);
  148. if (ucLevel == CHNL_LEVEL0) {
  149. /* Forced to 20MHz, so extended channel is SCN and STA width is zero */
  150. prBssInfo->fgObssActionForcedTo20M = TRUE;
  151. if (prBssInfo->ucHtOpInfo1 != (UINT_8) CHNL_EXT_SCN) {
  152. prBssInfo->ucHtOpInfo1 = (UINT_8) CHNL_EXT_SCN;
  153. fgBwChange = TRUE;
  154. }
  155. cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, OBSS_20_40M_TIMEOUT * MSEC_PER_SEC);
  156. }
  157. /* Clear up all channel lists */
  158. prBssInfo->auc2G_20mReqChnlList[0] = 0;
  159. prBssInfo->auc2G_NonHtChnlList[0] = 0;
  160. prBssInfo->auc2G_PriChnlList[0] = 0;
  161. prBssInfo->auc2G_SecChnlList[0] = 0;
  162. prBssInfo->auc5G_20mReqChnlList[0] = 0;
  163. prBssInfo->auc5G_NonHtChnlList[0] = 0;
  164. prBssInfo->auc5G_PriChnlList[0] = 0;
  165. prBssInfo->auc5G_SecChnlList[0] = 0;
  166. return fgBwChange;
  167. }
  168. /*----------------------------------------------------------------------------*/
  169. /*!
  170. * \brief
  171. *
  172. * \param[in]
  173. *
  174. * \return none
  175. */
  176. /*----------------------------------------------------------------------------*/
  177. VOID rlmProcessPublicAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb)
  178. {
  179. P_ACTION_20_40_COEXIST_FRAME prRxFrame;
  180. P_IE_20_40_COEXIST_T prCoexist;
  181. P_IE_INTOLERANT_CHNL_REPORT_T prChnlReport;
  182. P_BSS_INFO_T prBssInfo;
  183. P_STA_RECORD_T prStaRec;
  184. PUINT_8 pucIE;
  185. UINT_16 u2IELength, u2Offset;
  186. UINT_8 i, j;
  187. ASSERT(prAdapter);
  188. ASSERT(prSwRfb);
  189. prRxFrame = (P_ACTION_20_40_COEXIST_FRAME) prSwRfb->pvHeader;
  190. prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
  191. if (prRxFrame->ucAction != ACTION_PUBLIC_20_40_COEXIST ||
  192. !prStaRec || prStaRec->ucStaState != STA_STATE_3 ||
  193. prSwRfb->u2PacketLen < (WLAN_MAC_MGMT_HEADER_LEN + 5) ||
  194. HIF_RX_HDR_GET_NETWORK_IDX(prSwRfb->prHifRxHdr) != NETWORK_TYPE_P2P_INDEX) {
  195. return;
  196. }
  197. prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX];
  198. ASSERT(prBssInfo);
  199. if (!IS_BSS_ACTIVE(prBssInfo) ||
  200. prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT || prBssInfo->eBssSCO == CHNL_EXT_SCN) {
  201. return;
  202. }
  203. prCoexist = &prRxFrame->rBssCoexist;
  204. if (prCoexist->ucData & (BSS_COEXIST_40M_INTOLERANT | BSS_COEXIST_20M_REQ)) {
  205. ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G);
  206. for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) {
  207. if (prBssInfo->auc2G_20mReqChnlList[i] == prBssInfo->ucPrimaryChannel)
  208. break;
  209. }
  210. if ((i > prBssInfo->auc2G_20mReqChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) {
  211. prBssInfo->auc2G_20mReqChnlList[i] = prBssInfo->ucPrimaryChannel;
  212. prBssInfo->auc2G_20mReqChnlList[0]++;
  213. }
  214. }
  215. /* Process intolerant channel report IE */
  216. pucIE = (PUINT_8) &prRxFrame->rChnlReport;
  217. u2IELength = prSwRfb->u2PacketLen - (WLAN_MAC_MGMT_HEADER_LEN + 5);
  218. IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
  219. switch (IE_ID(pucIE)) {
  220. case ELEM_ID_20_40_INTOLERANT_CHNL_REPORT:
  221. prChnlReport = (P_IE_INTOLERANT_CHNL_REPORT_T) pucIE;
  222. if (prChnlReport->ucLength <= 1)
  223. break;
  224. /* To do: process regulatory class. Now we assume 2.4G band */
  225. for (j = 0; j < prChnlReport->ucLength - 1; j++) {
  226. /* Update non-HT channel list */
  227. ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G);
  228. for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) {
  229. if (prBssInfo->auc2G_NonHtChnlList[i] == prChnlReport->aucChannelList[j])
  230. break;
  231. }
  232. if ((i > prBssInfo->auc2G_NonHtChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) {
  233. prBssInfo->auc2G_NonHtChnlList[i] = prChnlReport->aucChannelList[j];
  234. prBssInfo->auc2G_NonHtChnlList[0]++;
  235. }
  236. }
  237. break;
  238. default:
  239. break;
  240. }
  241. } /* end of IE_FOR_EACH */
  242. if (rlmUpdateBwByChListForAP(prAdapter, prBssInfo)) {
  243. bssUpdateBeaconContent(prAdapter, prBssInfo->ucNetTypeIndex);
  244. rlmSyncOperationParams(prAdapter, prBssInfo);
  245. }
  246. /* Check if OBSS scan exemption response should be sent */
  247. if (prCoexist->ucData & BSS_COEXIST_OBSS_SCAN_EXEMPTION_REQ)
  248. rlmObssScanExemptionRsp(prAdapter, prBssInfo, prSwRfb);
  249. }
  250. /*----------------------------------------------------------------------------*/
  251. /*!
  252. * \brief
  253. *
  254. * \param[in]
  255. *
  256. * \return none
  257. */
  258. /*----------------------------------------------------------------------------*/
  259. VOID rlmProcessHtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb)
  260. {
  261. P_ACTION_NOTIFY_CHNL_WIDTH_FRAME prRxFrame;
  262. P_STA_RECORD_T prStaRec;
  263. ASSERT(prAdapter);
  264. ASSERT(prSwRfb);
  265. prRxFrame = (P_ACTION_NOTIFY_CHNL_WIDTH_FRAME) prSwRfb->pvHeader;
  266. prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
  267. if (prRxFrame->ucAction != ACTION_HT_NOTIFY_CHANNEL_WIDTH ||
  268. !prStaRec || prStaRec->ucStaState != STA_STATE_3 ||
  269. prSwRfb->u2PacketLen < sizeof(ACTION_NOTIFY_CHNL_WIDTH_FRAME)) {
  270. return;
  271. }
  272. /* To do: depending regulation class 13 and 14 based on spec
  273. * Note: (ucChannelWidth==1) shall restored back to original capability,
  274. * not current setting to 40MHz BW here
  275. */
  276. if (prRxFrame->ucChannelWidth == 0)
  277. prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH;
  278. else if (prRxFrame->ucChannelWidth == 1)
  279. prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH;
  280. cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3);
  281. }
  282. /*----------------------------------------------------------------------------*/
  283. /*!
  284. * \brief
  285. *
  286. * \param[in]
  287. *
  288. * \return none
  289. */
  290. /*----------------------------------------------------------------------------*/
  291. VOID rlmHandleObssStatusEventPkt(P_ADAPTER_T prAdapter, P_EVENT_AP_OBSS_STATUS_T prObssStatus)
  292. {
  293. P_BSS_INFO_T prBssInfo;
  294. ASSERT(prAdapter);
  295. ASSERT(prObssStatus);
  296. ASSERT(prObssStatus->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX);
  297. prBssInfo = &prAdapter->rWifiVar.arBssInfo[prObssStatus->ucNetTypeIndex];
  298. ASSERT(prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT);
  299. prBssInfo->fgObssErpProtectMode = (BOOLEAN) prObssStatus->ucObssErpProtectMode;
  300. prBssInfo->eObssHtProtectMode = (ENUM_HT_PROTECT_MODE_T) prObssStatus->ucObssHtProtectMode;
  301. prBssInfo->eObssGfOperationMode = (ENUM_GF_MODE_T) prObssStatus->ucObssGfOperationMode;
  302. prBssInfo->fgObssRifsOperationMode = (BOOLEAN) prObssStatus->ucObssRifsOperationMode;
  303. prBssInfo->fgObssBeaconForcedTo20M = (BOOLEAN) prObssStatus->ucObssBeaconForcedTo20M;
  304. /* Check if Beacon content need to be updated */
  305. rlmUpdateParamsForAP(prAdapter, prBssInfo, TRUE);
  306. }
  307. /*----------------------------------------------------------------------------*/
  308. /*!
  309. * \brief It is only for AP mode in NETWORK_TYPE_P2P_INDEX.
  310. *
  311. * \param[in]
  312. *
  313. * \return none
  314. */
  315. /*----------------------------------------------------------------------------*/
  316. VOID rlmUpdateParamsForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, BOOLEAN fgUpdateBeacon)
  317. {
  318. P_LINK_T prStaList;
  319. P_STA_RECORD_T prStaRec;
  320. BOOLEAN fgErpProtectMode, fgSta40mIntolerant;
  321. BOOLEAN fgUseShortPreamble, fgUseShortSlotTime;
  322. ENUM_HT_PROTECT_MODE_T eHtProtectMode;
  323. ENUM_GF_MODE_T eGfOperationMode;
  324. UINT_8 ucHtOpInfo1;
  325. #if CFG_SUPPORT_HOTSPOT_OPTIMIZATION
  326. P_GLUE_INFO_T prGlueInfo;
  327. #endif
  328. ASSERT(prAdapter);
  329. ASSERT(prBssInfo);
  330. if (!IS_BSS_ACTIVE(prBssInfo) || prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT)
  331. return;
  332. fgErpProtectMode = FALSE;
  333. eHtProtectMode = HT_PROTECT_MODE_NONE;
  334. eGfOperationMode = GF_MODE_NORMAL;
  335. fgSta40mIntolerant = FALSE;
  336. fgUseShortPreamble = prBssInfo->fgIsShortPreambleAllowed;
  337. fgUseShortSlotTime = TRUE;
  338. ucHtOpInfo1 = (UINT_8) CHNL_EXT_SCN;
  339. prStaList = &prBssInfo->rStaRecOfClientList;
  340. LINK_FOR_EACH_ENTRY(prStaRec, prStaList, rLinkEntry, STA_RECORD_T) {
  341. /* ASSERT(prStaRec); */
  342. if (!prStaRec) {
  343. DBGLOG(P2P, TRACE, "prStaRec is NULL in rlmUpdateParamsForAP()\n");
  344. break;
  345. }
  346. if (prStaRec->fgIsInUse && prStaRec->ucStaState == STA_STATE_3 &&
  347. prStaRec->ucNetTypeIndex == prBssInfo->ucNetTypeIndex) {
  348. if (!(prStaRec->ucPhyTypeSet & (PHY_TYPE_SET_802_11GN | PHY_TYPE_SET_802_11A))) {
  349. /* B-only mode, so mode 1 (ERP protection) */
  350. fgErpProtectMode = TRUE;
  351. }
  352. if (!(prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) {
  353. /* BG-only or A-only */
  354. eHtProtectMode = HT_PROTECT_MODE_NON_HT;
  355. } else if (!(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH)) {
  356. /* 20MHz-only */
  357. /*
  358. The HT Protection field may be set to 20 MHz protection
  359. mode only if the following are true:
  360. \A1X All STAs detected (by any means) in the primary channel
  361. and all STAs detected (by any means) in the secondary
  362. channel are HT STAs and all STAs that are members of
  363. this BSS are HT STAs, and
  364. \A1X This BSS is a 20/40 MHz BSS, and
  365. \A1X There is at least one 20 MHz HT STA associated with this BSS.
  366. */
  367. if (eHtProtectMode == HT_PROTECT_MODE_NONE && prBssInfo->fgAssoc40mBwAllowed)
  368. eHtProtectMode = HT_PROTECT_MODE_20M;
  369. }
  370. if (!(prStaRec->u2HtCapInfo & HT_CAP_INFO_HT_GF))
  371. eGfOperationMode = GF_MODE_PROTECT;
  372. if (!(prStaRec->u2CapInfo & CAP_INFO_SHORT_PREAMBLE))
  373. fgUseShortPreamble = FALSE;
  374. if (!(prStaRec->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME))
  375. fgUseShortSlotTime = FALSE;
  376. if (prStaRec->u2HtCapInfo & HT_CAP_INFO_40M_INTOLERANT)
  377. fgSta40mIntolerant = TRUE;
  378. }
  379. } /* end of LINK_FOR_EACH_ENTRY */
  380. /* Check if HT operation IE about 20/40M bandwidth shall be updated */
  381. if (prBssInfo->eBssSCO != CHNL_EXT_SCN) {
  382. if (/*!LINK_IS_EMPTY(prStaList) && */ !fgSta40mIntolerant &&
  383. !prBssInfo->fgObssActionForcedTo20M && !prBssInfo->fgObssBeaconForcedTo20M) {
  384. ucHtOpInfo1 = (UINT_8)
  385. (((UINT_32) prBssInfo->eBssSCO) | HT_OP_INFO1_STA_CHNL_WIDTH);
  386. }
  387. }
  388. #if CFG_SUPPORT_HOTSPOT_OPTIMIZATION
  389. prGlueInfo = prAdapter->prGlueInfo;
  390. if (prGlueInfo->prP2PInfo->u4PsLevel & BITS(8, 15))
  391. fgErpProtectMode = TRUE;
  392. #endif
  393. /* Check if any new parameter may be updated */
  394. if (prBssInfo->fgErpProtectMode != fgErpProtectMode ||
  395. prBssInfo->eHtProtectMode != eHtProtectMode ||
  396. prBssInfo->eGfOperationMode != eGfOperationMode ||
  397. prBssInfo->ucHtOpInfo1 != ucHtOpInfo1 ||
  398. prBssInfo->fgUseShortPreamble != fgUseShortPreamble ||
  399. prBssInfo->fgUseShortSlotTime != fgUseShortSlotTime) {
  400. prBssInfo->fgErpProtectMode = fgErpProtectMode;
  401. prBssInfo->eHtProtectMode = eHtProtectMode;
  402. prBssInfo->eGfOperationMode = eGfOperationMode;
  403. prBssInfo->ucHtOpInfo1 = ucHtOpInfo1;
  404. prBssInfo->fgUseShortPreamble = fgUseShortPreamble;
  405. prBssInfo->fgUseShortSlotTime = fgUseShortSlotTime;
  406. if (fgUseShortSlotTime)
  407. prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME;
  408. else
  409. prBssInfo->u2CapInfo &= ~CAP_INFO_SHORT_SLOT_TIME;
  410. rlmSyncOperationParams(prAdapter, prBssInfo);
  411. fgUpdateBeacon = TRUE;
  412. }
  413. /* Update Beacon content if related IE content is changed */
  414. if (fgUpdateBeacon)
  415. bssUpdateBeaconContent(prAdapter, prBssInfo->ucNetTypeIndex);
  416. }
  417. /*----------------------------------------------------------------------------*/
  418. /*!
  419. * \brief Initial the channel list from the domain information.
  420. * This function is called after P2P initial and Domain information changed.
  421. * Make sure the device is disconnected while changing domain information.
  422. *
  423. * \param[in] prAdapter Pointer of ADAPTER_T
  424. *
  425. * \return boolean value if probe response frame is
  426. */
  427. /*----------------------------------------------------------------------------*/
  428. VOID rlmFuncInitialChannelList(IN P_ADAPTER_T prAdapter)
  429. {
  430. P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL;
  431. P_DOMAIN_INFO_ENTRY prDomainInfoEntry = (P_DOMAIN_INFO_ENTRY) NULL;
  432. P_DOMAIN_SUBBAND_INFO prDomainSubBand = (P_DOMAIN_SUBBAND_INFO) NULL;
  433. P_CHANNEL_ENTRY_FIELD_T prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) NULL;
  434. UINT_32 u4Idx = 0, u4IdxII = 0;
  435. UINT_8 ucBufferSize = P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE;
  436. #if 0
  437. UINT_8 ucSocialChnlSupport = 0, ucAutoChnl = 0;
  438. #endif
  439. do {
  440. ASSERT_BREAK(prAdapter != NULL);
  441. prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings;
  442. #if 0
  443. ucAutoChnl = prP2pConnSetting->ucOperatingChnl;
  444. #endif
  445. prDomainInfoEntry = rlmDomainGetDomainInfo(prAdapter);
  446. ASSERT_BREAK((prDomainInfoEntry != NULL) && (prP2pConnSetting != NULL));
  447. prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField;
  448. for (u4Idx = 0; u4Idx < MAX_SUBBAND_NUM; u4Idx++) {
  449. prDomainSubBand = &prDomainInfoEntry->rSubBand[u4Idx];
  450. if (((prDomainSubBand->ucBand == BAND_5G) && (!prAdapter->fgEnable5GBand)) ||
  451. (prDomainSubBand->ucBand == BAND_NULL)) {
  452. continue;
  453. }
  454. if (ucBufferSize < (P2P_ATTRI_LEN_CHANNEL_ENTRY + prDomainSubBand->ucNumChannels)) {
  455. /* Buffer is not enough to include all supported channels. */
  456. break; /* for */
  457. }
  458. prChannelEntryField->ucRegulatoryClass = prDomainSubBand->ucRegClass;
  459. prChannelEntryField->ucNumberOfChannels = prDomainSubBand->ucNumChannels;
  460. for (u4IdxII = 0; u4IdxII < prDomainSubBand->ucNumChannels; u4IdxII++) {
  461. prChannelEntryField->aucChannelList[u4IdxII] = prDomainSubBand->ucFirstChannelNum +
  462. (u4IdxII * prDomainSubBand->ucChannelSpan);
  463. #if 0
  464. switch (prChannelEntryField->aucChannelList[u4IdxII]) {
  465. case 1:
  466. ucSocialChnlSupport = 1;
  467. break;
  468. case 6:
  469. ucSocialChnlSupport = 6;
  470. break;
  471. case 11:
  472. ucSocialChnlSupport = 11;
  473. break;
  474. default:
  475. break;
  476. }
  477. #endif
  478. }
  479. if (ucBufferSize >= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels))
  480. ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels);
  481. else
  482. break;
  483. prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryField +
  484. P2P_ATTRI_LEN_CHANNEL_ENTRY +
  485. (ULONG)
  486. prChannelEntryField->ucNumberOfChannels);
  487. }
  488. #if 0
  489. if (prP2pConnSetting->ucListenChnl == 0) {
  490. prP2pConnSetting->ucListenChnl = P2P_DEFAULT_LISTEN_CHANNEL;
  491. if (ucSocialChnlSupport != 0) {
  492. /* 1. User Not Set LISTEN channel.
  493. * 2. Social channel is not empty.
  494. */
  495. prP2pConnSetting->ucListenChnl = ucSocialChnlSupport;
  496. }
  497. }
  498. #endif
  499. /* TODO: 20110921 frog - */
  500. /* If LISTEN channel is not set,
  501. * a random supported channel would be set.
  502. * If no social channel is supported, DEFAULT channel would be set.
  503. */
  504. prP2pConnSetting->ucRfChannelListSize = P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE - ucBufferSize;
  505. #if 0
  506. if (prP2pConnSetting->ucOperatingChnl == 0) { /* User not set OPERATE channel. */
  507. if (scnQuerySparseChannel(prAdapter, NULL, &ucAutoChnl))
  508. break; /* while */
  509. ucBufferSize = prP2pConnSetting->ucRfChannelListSize;
  510. prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField;
  511. while (ucBufferSize != 0) {
  512. if (prChannelEntryField->ucNumberOfChannels != 0) {
  513. ucAutoChnl = prChannelEntryField->aucChannelList[0];
  514. break; /* while */
  515. }
  516. else {
  517. prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) ((UINT_32) prChannelEntryField +
  518. P2P_ATTRI_LEN_CHANNEL_ENTRY +
  519. (UINT_32)prChannelEntryField->ucNumberOfChannels);
  520. ucBufferSize -=
  521. (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels);
  522. }
  523. }
  524. }
  525. #endif
  526. /* We assume user would not set a channel not in the channel list.
  527. * If so, the operating channel still depends on target device supporting capability.
  528. */
  529. /* TODO: 20110921 frog - */
  530. /* If the Operating channel is not set, a channel from supported channel list is set automatically.
  531. * If there is no supported channel in channel list, a DEFAULT channel is set.
  532. */
  533. } while (FALSE);
  534. #if 0
  535. prP2pConnSetting->ucOperatingChnl = ucAutoChnl;
  536. #endif
  537. } /* rlmFuncInitialChannelList */
  538. /*----------------------------------------------------------------------------*/
  539. /*!
  540. * \brief Find a common channel list from the local channel list info & target channel list info.
  541. *
  542. * \param[in] prAdapter Pointer of ADAPTER_T
  543. *
  544. * \return boolean value if probe response frame is
  545. */
  546. /*----------------------------------------------------------------------------*/
  547. VOID
  548. rlmFuncCommonChannelList(IN P_ADAPTER_T prAdapter,
  549. IN P_CHANNEL_ENTRY_FIELD_T prChannelEntryII, IN UINT_8 ucChannelListSize)
  550. {
  551. P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL;
  552. P_CHANNEL_ENTRY_FIELD_T prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T) NULL, prChannelEntryIII =
  553. (P_CHANNEL_ENTRY_FIELD_T) NULL;
  554. UINT_8 aucCommonChannelList[P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE] = {0};
  555. UINT_8 ucOriChnlSize = 0, ucNewChnlSize = 0;
  556. do {
  557. ASSERT_BREAK(prAdapter != NULL);
  558. prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings;
  559. prChannelEntryIII = (P_CHANNEL_ENTRY_FIELD_T) aucCommonChannelList;
  560. while (ucChannelListSize > 0) {
  561. prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField;
  562. ucOriChnlSize = prP2pConnSetting->ucRfChannelListSize;
  563. while (ucOriChnlSize > 0) {
  564. if (prChannelEntryI->ucRegulatoryClass == prChannelEntryII->ucRegulatoryClass) {
  565. prChannelEntryIII->ucRegulatoryClass = prChannelEntryI->ucRegulatoryClass;
  566. /* TODO: Currently we assume that the regulatory class the same,
  567. * the channels are the same. */
  568. kalMemCopy(prChannelEntryIII->aucChannelList, prChannelEntryII->aucChannelList,
  569. prChannelEntryII->ucNumberOfChannels);
  570. prChannelEntryIII->ucNumberOfChannels = prChannelEntryII->ucNumberOfChannels;
  571. ucNewChnlSize +=
  572. P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryIII->ucNumberOfChannels;
  573. prChannelEntryIII = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryIII +
  574. P2P_ATTRI_LEN_CHANNEL_ENTRY +
  575. (ULONG)prChannelEntryIII->ucNumberOfChannels);
  576. }
  577. ucOriChnlSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryI->ucNumberOfChannels);
  578. prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryI +
  579. P2P_ATTRI_LEN_CHANNEL_ENTRY +
  580. (ULONG)
  581. prChannelEntryI->ucNumberOfChannels);
  582. }
  583. ucChannelListSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryII->ucNumberOfChannels);
  584. prChannelEntryII = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryII +
  585. P2P_ATTRI_LEN_CHANNEL_ENTRY +
  586. (ULONG) prChannelEntryII->ucNumberOfChannels);
  587. }
  588. kalMemCopy(prP2pConnSetting->aucChannelEntriesField, aucCommonChannelList, ucNewChnlSize);
  589. prP2pConnSetting->ucRfChannelListSize = ucNewChnlSize;
  590. } while (FALSE);
  591. } /* rlmFuncCommonChannelList */
  592. /*----------------------------------------------------------------------------*/
  593. /*!
  594. * \brief
  595. *
  596. * \param[in]
  597. *
  598. * \return none
  599. */
  600. /*----------------------------------------------------------------------------*/
  601. UINT_8 rlmFuncFindOperatingClass(IN P_ADAPTER_T prAdapter, IN UINT_8 ucChannelNum)
  602. {
  603. UINT_8 ucRegulatoryClass = 0, ucBufferSize = 0;
  604. P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL;
  605. P_CHANNEL_ENTRY_FIELD_T prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) NULL;
  606. UINT_32 u4Idx = 0;
  607. do {
  608. ASSERT_BREAK(prAdapter != NULL);
  609. prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings;
  610. ucBufferSize = prP2pConnSetting->ucRfChannelListSize;
  611. prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField;
  612. while (ucBufferSize != 0) {
  613. for (u4Idx = 0; u4Idx < prChannelEntryField->ucNumberOfChannels; u4Idx++) {
  614. if (prChannelEntryField->aucChannelList[u4Idx] == ucChannelNum) {
  615. ucRegulatoryClass = prChannelEntryField->ucRegulatoryClass;
  616. break;
  617. }
  618. }
  619. if (ucRegulatoryClass != 0)
  620. break; /* while */
  621. prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryField +
  622. P2P_ATTRI_LEN_CHANNEL_ENTRY +
  623. (ULONG)prChannelEntryField->ucNumberOfChannels);
  624. ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels);
  625. }
  626. } while (FALSE);
  627. return ucRegulatoryClass;
  628. } /* rlmFuncFindOperatingClass */
  629. /*----------------------------------------------------------------------------*/
  630. /*!
  631. * \brief
  632. *
  633. * \param[in]
  634. *
  635. * \return none
  636. */
  637. /*----------------------------------------------------------------------------*/
  638. BOOLEAN
  639. rlmFuncFindAvailableChannel(IN P_ADAPTER_T prAdapter,
  640. IN UINT_8 ucCheckChnl,
  641. IN PUINT_8 pucSuggestChannel, IN BOOLEAN fgIsSocialChannel, IN BOOLEAN fgIsDefaultChannel)
  642. {
  643. BOOLEAN fgIsResultAvailable = FALSE;
  644. P_CHANNEL_ENTRY_FIELD_T prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T) NULL;
  645. P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL;
  646. UINT_8 ucBufferSize = 0, ucIdx = 0, ucChannelSelected = 0;
  647. do {
  648. ASSERT_BREAK(prAdapter != NULL);
  649. if (fgIsDefaultChannel)
  650. ucChannelSelected = P2P_DEFAULT_LISTEN_CHANNEL;
  651. prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings;
  652. ucBufferSize = prP2pConnSetting->ucRfChannelListSize;
  653. prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField;
  654. while ((ucBufferSize != 0) && (!fgIsResultAvailable)) {
  655. for (ucIdx = 0; ucIdx < prChannelEntry->ucNumberOfChannels; ucIdx++) {
  656. if ((!fgIsSocialChannel) ||
  657. (prChannelEntry->aucChannelList[ucIdx] == 1) ||
  658. (prChannelEntry->aucChannelList[ucIdx] == 6) ||
  659. (prChannelEntry->aucChannelList[ucIdx] == 11)) {
  660. if (prChannelEntry->aucChannelList[ucIdx] <= 11) {
  661. /* 2.4G. */
  662. ucChannelSelected = prChannelEntry->aucChannelList[ucIdx];
  663. } else if ((prChannelEntry->aucChannelList[ucIdx] < 52) &&
  664. (prChannelEntry->aucChannelList[ucIdx] > 14)) {
  665. /* 2.4G + 5G. */
  666. ucChannelSelected = prChannelEntry->aucChannelList[ucIdx];
  667. }
  668. if (ucChannelSelected == ucCheckChnl) {
  669. fgIsResultAvailable = TRUE;
  670. break;
  671. }
  672. }
  673. }
  674. ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntry->ucNumberOfChannels);
  675. prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntry +
  676. P2P_ATTRI_LEN_CHANNEL_ENTRY +
  677. (ULONG) prChannelEntry->ucNumberOfChannels);
  678. }
  679. if ((!fgIsResultAvailable) && (pucSuggestChannel != NULL)) {
  680. DBGLOG(P2P, TRACE,
  681. "The request channel %d is not available, sugguested channel:%d\n", ucCheckChnl,
  682. ucChannelSelected);
  683. /* Given a suggested channel. */
  684. *pucSuggestChannel = ucChannelSelected;
  685. }
  686. } while (FALSE);
  687. return fgIsResultAvailable;
  688. }
  689. /*----------------------------------------------------------------------------*/
  690. /*!
  691. * \brief
  692. *
  693. * \param[in]
  694. *
  695. * \return none
  696. */
  697. /*----------------------------------------------------------------------------*/
  698. ENUM_CHNL_EXT_T rlmDecideScoForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo)
  699. {
  700. P_DOMAIN_SUBBAND_INFO prSubband;
  701. P_DOMAIN_INFO_ENTRY prDomainInfo;
  702. UINT_8 ucSecondChannel, i, j;
  703. ENUM_CHNL_EXT_T eSCO;
  704. eSCO = CHNL_EXT_SCN;
  705. if (prBssInfo->eBand == BAND_2G4) {
  706. if (prBssInfo->ucPrimaryChannel != 14)
  707. eSCO = (prBssInfo->ucPrimaryChannel > 7) ? CHNL_EXT_SCB : CHNL_EXT_SCA;
  708. } else {
  709. prDomainInfo = rlmDomainGetDomainInfo(prAdapter);
  710. ASSERT(prDomainInfo);
  711. for (i = 0; i < MAX_SUBBAND_NUM; i++) {
  712. prSubband = &prDomainInfo->rSubBand[i];
  713. if (prSubband->ucBand == prBssInfo->eBand) {
  714. for (j = 0; j < prSubband->ucNumChannels; j++) {
  715. if ((prSubband->ucFirstChannelNum + j * prSubband->ucChannelSpan)
  716. == prBssInfo->ucPrimaryChannel) {
  717. eSCO = (j & 1) ? CHNL_EXT_SCB : CHNL_EXT_SCA;
  718. break;
  719. }
  720. }
  721. if (j < prSubband->ucNumChannels)
  722. break; /* Found */
  723. }
  724. }
  725. }
  726. /* Check if it is boundary channel and 40MHz BW is permitted */
  727. if (eSCO != CHNL_EXT_SCN) {
  728. ucSecondChannel = (eSCO == CHNL_EXT_SCA) ?
  729. (prBssInfo->ucPrimaryChannel + 4) : (prBssInfo->ucPrimaryChannel - 4);
  730. if (!rlmDomainIsLegalChannel(prAdapter, prBssInfo->eBand, ucSecondChannel))
  731. eSCO = CHNL_EXT_SCN;
  732. }
  733. return eSCO;
  734. }