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