2 ** $Id: @(#) p2p_rlm.c@@
10 /*******************************************************************************
11 * Copyright (c) 2007 MediaTek Inc.
13 * All rights reserved. Copying, compilation, modification, distribution
14 * or any other use whatsoever of this material is strictly prohibited
15 * except in accordance with a Software License Agreement with
17 ********************************************************************************
20 /*******************************************************************************
23 * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND
24 * AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK
25 * SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE
26 * PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY
27 * DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
28 * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
29 * PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE
30 * ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY
31 * WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK
32 * SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY
33 * WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE
34 * FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO
35 * CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
37 * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
38 * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL
39 * BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT
40 * ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY
41 * BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
43 * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
44 * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT
45 * OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING
46 * THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN
47 * FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE
49 ********************************************************************************
53 /*******************************************************************************
54 * C O M P I L E R F L A G S
55 ********************************************************************************
58 /*******************************************************************************
59 * E X T E R N A L R E F E R E N C E S
60 ********************************************************************************
66 rlmSyncOperationParams (
67 P_ADAPTER_T prAdapter,
68 P_BSS_INFO_T prBssInfo
71 /*******************************************************************************
73 ********************************************************************************
76 /*******************************************************************************
78 ********************************************************************************
81 /*******************************************************************************
83 ********************************************************************************
86 /*******************************************************************************
87 * P R I V A T E D A T A
88 ********************************************************************************
91 /*******************************************************************************
93 ********************************************************************************
96 /*******************************************************************************
97 * F U N C T I O N D E C L A R A T I O N S
98 ********************************************************************************
101 /*******************************************************************************
103 ********************************************************************************
106 /*----------------------------------------------------------------------------*/
114 /*----------------------------------------------------------------------------*/
117 P_ADAPTER_T prAdapter,
118 P_BSS_INFO_T prBssInfo
123 ENUM_CHNL_EXT_T eSCO;
128 if (prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) {
132 /* Operation band, channel shall be ready before invoking this function.
133 * Bandwidth may be ready if other network is connected
135 prBssInfo->fg40mBwAllowed = FALSE;
136 prBssInfo->fgAssoc40mBwAllowed = FALSE;
137 prBssInfo->eBssSCO = CHNL_EXT_SCN;
139 if (RLM_AP_IS_BW_40_ALLOWED(prAdapter, prBssInfo)) {
140 /* In this case, the first BSS's SCO is 40MHz and known, so AP can
141 * apply 40MHz bandwidth, but the first BSS's SCO may be changed
142 * later if its Beacon lost timeout occurs
144 if (cnmPreferredChannel(prAdapter, &eBand, &ucChannel, &eSCO) &&
145 eSCO != CHNL_EXT_SCN && ucChannel == prBssInfo->ucPrimaryChannel &&
146 eBand == prBssInfo->eBand) {
147 prBssInfo->eBssSCO = eSCO;
149 else if (cnmBss40mBwPermitted(prAdapter, prBssInfo->ucNetTypeIndex)) {
150 prBssInfo->eBssSCO = rlmDecideScoForAP(prAdapter, prBssInfo);
153 if (prBssInfo->eBssSCO != CHNL_EXT_SCN) {
154 prBssInfo->fg40mBwAllowed = TRUE;
155 prBssInfo->fgAssoc40mBwAllowed = TRUE;
157 prBssInfo->ucHtOpInfo1 = (UINT_8)
158 (((UINT_32) prBssInfo->eBssSCO) | HT_OP_INFO1_STA_CHNL_WIDTH);
160 rlmUpdateBwByChListForAP(prAdapter, prBssInfo);
164 DBGLOG(RLM, INFO, ("WLAN AP SCO=%d\n", prBssInfo->eBssSCO));
167 /*----------------------------------------------------------------------------*/
169 * \brief For probe response (GO, IBSS) and association response
175 /*----------------------------------------------------------------------------*/
177 rlmRspGenerateObssScanIE (
178 P_ADAPTER_T prAdapter,
179 P_MSDU_INFO_T prMsduInfo
182 P_BSS_INFO_T prBssInfo;
183 P_IE_OBSS_SCAN_PARAM_T prObssScanIe;
184 P_STA_RECORD_T prStaRec = (P_STA_RECORD_T)NULL;
188 ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType));
190 prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
192 prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType];
195 if (RLM_NET_IS_11N(prBssInfo) && !RLM_NET_IS_BOW(prBssInfo) &&
196 prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT &&
197 (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) &&
198 prBssInfo->eBand == BAND_2G4 &&
199 prBssInfo->eBssSCO != CHNL_EXT_SCN) {
201 prObssScanIe = (P_IE_OBSS_SCAN_PARAM_T)
202 (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength);
204 /* Add 20/40 BSS coexistence IE */
205 prObssScanIe->ucId = ELEM_ID_OBSS_SCAN_PARAMS;
206 prObssScanIe->ucLength = sizeof(IE_OBSS_SCAN_PARAM_T) - ELEM_HDR_LEN;
208 prObssScanIe->u2ScanPassiveDwell =
209 dot11OBSSScanPassiveDwell;
210 prObssScanIe->u2ScanActiveDwell =
211 dot11OBSSScanActiveDwell;
212 prObssScanIe->u2TriggerScanInterval =
213 dot11BSSWidthTriggerScanInterval;
214 prObssScanIe->u2ScanPassiveTotalPerChnl =
215 dot11OBSSScanPassiveTotalPerChannel;
216 prObssScanIe->u2ScanActiveTotalPerChnl =
217 dot11OBSSScanActiveTotalPerChannel;
218 prObssScanIe->u2WidthTransDelayFactor =
219 dot11BSSWidthChannelTransitionDelayFactor;
220 prObssScanIe->u2ScanActivityThres =
221 dot11OBSSScanActivityThreshold;
223 ASSERT(IE_SIZE(prObssScanIe) <= (ELEM_HDR_LEN+ ELEM_MAX_LEN_OBSS_SCAN));
225 prMsduInfo->u2FrameLength += IE_SIZE(prObssScanIe);
229 /*----------------------------------------------------------------------------*/
237 /*----------------------------------------------------------------------------*/
239 rlmUpdateBwByChListForAP (
240 P_ADAPTER_T prAdapter,
241 P_BSS_INFO_T prBssInfo
252 if (prBssInfo->eBssSCO == CHNL_EXT_SCN) {
256 ucLevel = rlmObssChnlLevel(prBssInfo, prBssInfo->eBand,
257 prBssInfo->ucPrimaryChannel, prBssInfo->eBssSCO);
259 if (ucLevel == CHNL_LEVEL0) {
260 /* Forced to 20MHz, so extended channel is SCN and STA width is zero */
261 prBssInfo->fgObssActionForcedTo20M = TRUE;
263 if (prBssInfo->ucHtOpInfo1 != (UINT_8) CHNL_EXT_SCN) {
264 prBssInfo->ucHtOpInfo1 = (UINT_8) CHNL_EXT_SCN;
268 cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer,
269 OBSS_20_40M_TIMEOUT * MSEC_PER_SEC);
272 /* Clear up all channel lists */
273 prBssInfo->auc2G_20mReqChnlList[0] = 0;
274 prBssInfo->auc2G_NonHtChnlList[0] = 0;
275 prBssInfo->auc2G_PriChnlList[0] = 0;
276 prBssInfo->auc2G_SecChnlList[0] = 0;
277 prBssInfo->auc5G_20mReqChnlList[0] = 0;
278 prBssInfo->auc5G_NonHtChnlList[0] = 0;
279 prBssInfo->auc5G_PriChnlList[0] = 0;
280 prBssInfo->auc5G_SecChnlList[0] = 0;
285 /*----------------------------------------------------------------------------*/
293 /*----------------------------------------------------------------------------*/
295 rlmProcessPublicAction (
296 P_ADAPTER_T prAdapter,
300 P_ACTION_20_40_COEXIST_FRAME prRxFrame;
301 P_IE_20_40_COEXIST_T prCoexist;
302 P_IE_INTOLERANT_CHNL_REPORT_T prChnlReport;
303 P_BSS_INFO_T prBssInfo;
304 P_STA_RECORD_T prStaRec;
306 UINT_16 u2IELength, u2Offset;
312 prRxFrame = (P_ACTION_20_40_COEXIST_FRAME) prSwRfb->pvHeader;
313 prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
315 if (prRxFrame->ucAction != ACTION_PUBLIC_20_40_COEXIST ||
316 !prStaRec || prStaRec->ucStaState != STA_STATE_3 ||
317 prSwRfb->u2PacketLen < (WLAN_MAC_MGMT_HEADER_LEN + 5) ||
318 HIF_RX_HDR_GET_NETWORK_IDX(prSwRfb->prHifRxHdr) !=
319 NETWORK_TYPE_P2P_INDEX) {
323 prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX];
326 if (!IS_BSS_ACTIVE(prBssInfo) ||
327 prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT ||
328 prBssInfo->eBssSCO == CHNL_EXT_SCN) {
332 prCoexist = &prRxFrame->rBssCoexist;
333 if (prCoexist->ucData & (BSS_COEXIST_40M_INTOLERANT|BSS_COEXIST_20M_REQ)) {
334 ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G);
335 for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] &&
336 i <= CHNL_LIST_SZ_2G; i++) {
337 if (prBssInfo->auc2G_20mReqChnlList[i] ==
338 prBssInfo->ucPrimaryChannel) {
342 if ((i > prBssInfo->auc2G_20mReqChnlList[0]) &&
343 (i <= CHNL_LIST_SZ_2G)){
344 prBssInfo->auc2G_20mReqChnlList[i] = prBssInfo->ucPrimaryChannel;
345 prBssInfo->auc2G_20mReqChnlList[0]++;
349 /* Process intolerant channel report IE */
350 pucIE = (PUINT_8) &prRxFrame->rChnlReport;
351 u2IELength = prSwRfb->u2PacketLen - (WLAN_MAC_MGMT_HEADER_LEN + 5);
353 IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
354 switch (IE_ID(pucIE)) {
355 case ELEM_ID_20_40_INTOLERANT_CHNL_REPORT:
356 prChnlReport = (P_IE_INTOLERANT_CHNL_REPORT_T) pucIE;
358 if (prChnlReport->ucLength <= 1) {
362 /* To do: process regulatory class. Now we assume 2.4G band */
364 for (j = 0; j < prChnlReport->ucLength - 1; j++) {
365 /* Update non-HT channel list */
366 ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G);
367 for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] &&
368 i <= CHNL_LIST_SZ_2G; i++) {
369 if (prBssInfo->auc2G_NonHtChnlList[i] ==
370 prChnlReport->aucChannelList[j]) {
374 if ((i > prBssInfo->auc2G_NonHtChnlList[0]) &&
375 (i <= CHNL_LIST_SZ_2G)) {
376 prBssInfo->auc2G_NonHtChnlList[i] =
377 prChnlReport->aucChannelList[j];
378 prBssInfo->auc2G_NonHtChnlList[0]++;
386 } /* end of IE_FOR_EACH */
388 if (rlmUpdateBwByChListForAP(prAdapter, prBssInfo)) {
389 bssUpdateBeaconContent(prAdapter, prBssInfo->ucNetTypeIndex);
390 rlmSyncOperationParams(prAdapter, prBssInfo);
393 /* Check if OBSS scan exemption response should be sent */
394 if (prCoexist->ucData & BSS_COEXIST_OBSS_SCAN_EXEMPTION_REQ) {
395 rlmObssScanExemptionRsp(prAdapter, prBssInfo, prSwRfb);
399 /*----------------------------------------------------------------------------*/
407 /*----------------------------------------------------------------------------*/
410 P_ADAPTER_T prAdapter,
414 P_ACTION_NOTIFY_CHNL_WIDTH_FRAME prRxFrame;
415 P_STA_RECORD_T prStaRec;
420 prRxFrame = (P_ACTION_NOTIFY_CHNL_WIDTH_FRAME) prSwRfb->pvHeader;
421 prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
423 if (prRxFrame->ucAction != ACTION_HT_NOTIFY_CHANNEL_WIDTH ||
424 !prStaRec || prStaRec->ucStaState != STA_STATE_3 ||
425 prSwRfb->u2PacketLen < sizeof(ACTION_NOTIFY_CHNL_WIDTH_FRAME)) {
429 /* To do: depending regulation class 13 and 14 based on spec
430 * Note: (ucChannelWidth==1) shall restored back to original capability,
431 * not current setting to 40MHz BW here
433 if (prRxFrame->ucChannelWidth == 0) {
434 prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH;
436 else if (prRxFrame->ucChannelWidth == 1) {
437 prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH;
439 cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3);
442 /*----------------------------------------------------------------------------*/
450 /*----------------------------------------------------------------------------*/
452 rlmHandleObssStatusEventPkt (
453 P_ADAPTER_T prAdapter,
454 P_EVENT_AP_OBSS_STATUS_T prObssStatus
457 P_BSS_INFO_T prBssInfo;
460 ASSERT(prObssStatus);
461 ASSERT(prObssStatus->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX);
463 prBssInfo = &prAdapter->rWifiVar.arBssInfo[prObssStatus->ucNetTypeIndex];
464 ASSERT(prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT);
466 prBssInfo->fgObssErpProtectMode =
467 (BOOLEAN) prObssStatus->ucObssErpProtectMode;
468 prBssInfo->eObssHtProtectMode =
469 (ENUM_HT_PROTECT_MODE_T) prObssStatus->ucObssHtProtectMode;
470 prBssInfo->eObssGfOperationMode =
471 (ENUM_GF_MODE_T) prObssStatus->ucObssGfOperationMode;
472 prBssInfo->fgObssRifsOperationMode =
473 (BOOLEAN) prObssStatus->ucObssRifsOperationMode;
474 prBssInfo->fgObssBeaconForcedTo20M =
475 (BOOLEAN) prObssStatus->ucObssBeaconForcedTo20M;
477 /* Check if Beacon content need to be updated */
478 rlmUpdateParamsForAP(prAdapter, prBssInfo, TRUE);
482 /*----------------------------------------------------------------------------*/
484 * \brief It is only for AP mode in NETWORK_TYPE_P2P_INDEX.
490 /*----------------------------------------------------------------------------*/
492 rlmUpdateParamsForAP (
493 P_ADAPTER_T prAdapter,
494 P_BSS_INFO_T prBssInfo,
495 BOOLEAN fgUpdateBeacon
499 P_STA_RECORD_T prStaRec;
500 BOOLEAN fgErpProtectMode, fgSta40mIntolerant;
501 BOOLEAN fgUseShortPreamble, fgUseShortSlotTime;
502 ENUM_HT_PROTECT_MODE_T eHtProtectMode;
503 ENUM_GF_MODE_T eGfOperationMode;
509 if (!IS_BSS_ACTIVE(prBssInfo) ||
510 prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) {
514 fgErpProtectMode = FALSE;
515 eHtProtectMode = HT_PROTECT_MODE_NONE;
516 eGfOperationMode = GF_MODE_NORMAL;
517 fgSta40mIntolerant = FALSE;
518 fgUseShortPreamble = prBssInfo->fgIsShortPreambleAllowed;
519 fgUseShortSlotTime = TRUE;
520 ucHtOpInfo1 = (UINT_8) CHNL_EXT_SCN;
522 prStaList = &prBssInfo->rStaRecOfClientList;
524 LINK_FOR_EACH_ENTRY(prStaRec, prStaList, rLinkEntry, STA_RECORD_T) {
527 DBGLOG(P2P, TRACE, ("prStaRec is NULL in rlmUpdateParamsForAP() \n"));
530 if (prStaRec->fgIsInUse && prStaRec->ucStaState == STA_STATE_3 &&
531 prStaRec->ucNetTypeIndex == prBssInfo->ucNetTypeIndex) {
532 if (!(prStaRec->ucPhyTypeSet &
533 (PHY_TYPE_SET_802_11GN | PHY_TYPE_SET_802_11A))) {
534 /* B-only mode, so mode 1 (ERP protection) */
535 fgErpProtectMode = TRUE;
538 if (!(prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) {
539 /* BG-only or A-only */
540 eHtProtectMode = HT_PROTECT_MODE_NON_HT;
542 else if (!(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH)) {
544 if (eHtProtectMode == HT_PROTECT_MODE_NONE &&
545 prBssInfo->fgAssoc40mBwAllowed) {
546 eHtProtectMode = HT_PROTECT_MODE_20M;
550 if (!(prStaRec->u2HtCapInfo & HT_CAP_INFO_HT_GF)) {
551 eGfOperationMode = GF_MODE_PROTECT;
554 if (!(prStaRec->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)) {
555 fgUseShortPreamble = FALSE;
558 if (!(prStaRec->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME)) {
559 fgUseShortSlotTime = FALSE;
562 if (prStaRec->u2HtCapInfo & HT_CAP_INFO_40M_INTOLERANT) {
563 fgSta40mIntolerant = TRUE;
566 } /* end of LINK_FOR_EACH_ENTRY */
568 /* Check if HT operation IE about 20/40M bandwidth shall be updated */
569 if (prBssInfo->eBssSCO != CHNL_EXT_SCN) {
570 if (/*!LINK_IS_EMPTY(prStaList) && */ !fgSta40mIntolerant &&
571 !prBssInfo->fgObssActionForcedTo20M &&
572 !prBssInfo->fgObssBeaconForcedTo20M) {
574 ucHtOpInfo1 = (UINT_8)
575 (((UINT_32) prBssInfo->eBssSCO) | HT_OP_INFO1_STA_CHNL_WIDTH);
579 /* Check if any new parameter may be updated */
580 if (prBssInfo->fgErpProtectMode != fgErpProtectMode ||
581 prBssInfo->eHtProtectMode != eHtProtectMode ||
582 prBssInfo->eGfOperationMode != eGfOperationMode ||
583 prBssInfo->ucHtOpInfo1 != ucHtOpInfo1 ||
584 prBssInfo->fgUseShortPreamble != fgUseShortPreamble ||
585 prBssInfo->fgUseShortSlotTime != fgUseShortSlotTime) {
587 prBssInfo->fgErpProtectMode = fgErpProtectMode;
588 prBssInfo->eHtProtectMode = eHtProtectMode;
589 prBssInfo->eGfOperationMode = eGfOperationMode;
590 prBssInfo->ucHtOpInfo1 = ucHtOpInfo1;
591 prBssInfo->fgUseShortPreamble = fgUseShortPreamble;
592 prBssInfo->fgUseShortSlotTime = fgUseShortSlotTime;
594 if (fgUseShortSlotTime) {
595 prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME;
598 prBssInfo->u2CapInfo &= ~CAP_INFO_SHORT_SLOT_TIME;
601 rlmSyncOperationParams(prAdapter, prBssInfo);
602 fgUpdateBeacon = TRUE;
605 /* Update Beacon content if related IE content is changed */
606 if (fgUpdateBeacon) {
607 bssUpdateBeaconContent(prAdapter, prBssInfo->ucNetTypeIndex);
612 /*----------------------------------------------------------------------------*/
614 * \brief Initial the channel list from the domain information.
615 * This function is called after P2P initial and Domain information changed.
616 * Make sure the device is disconnected while changing domain information.
618 * \param[in] prAdapter Pointer of ADAPTER_T
620 * \return boolean value if probe response frame is
622 /*----------------------------------------------------------------------------*/
624 rlmFuncInitialChannelList (
625 IN P_ADAPTER_T prAdapter
628 P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T)NULL;
629 P_DOMAIN_INFO_ENTRY prDomainInfoEntry = (P_DOMAIN_INFO_ENTRY)NULL;
630 P_DOMAIN_SUBBAND_INFO prDomainSubBand = (P_DOMAIN_SUBBAND_INFO)NULL;
631 P_CHANNEL_ENTRY_FIELD_T prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T)NULL;
632 UINT_32 u4Idx = 0, u4IdxII = 0;
633 UINT_8 ucBufferSize = P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE;
635 UINT_8 ucSocialChnlSupport = 0, ucAutoChnl = 0;
639 ASSERT_BREAK(prAdapter != NULL);
641 prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings;
643 ucAutoChnl = prP2pConnSetting->ucOperatingChnl;
646 prDomainInfoEntry = rlmDomainGetDomainInfo(prAdapter);
648 ASSERT_BREAK((prDomainInfoEntry != NULL) && (prP2pConnSetting != NULL));
650 prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T)prP2pConnSetting->aucChannelEntriesField;
652 for (u4Idx = 0; u4Idx < MAX_SUBBAND_NUM; u4Idx++) {
653 prDomainSubBand = &prDomainInfoEntry->rSubBand[u4Idx];
656 if (((prDomainSubBand->ucBand == BAND_5G) && (!prAdapter->fgEnable5GBand)) ||
657 (prDomainSubBand->ucBand == BAND_NULL)) {
662 if (ucBufferSize < (P2P_ATTRI_LEN_CHANNEL_ENTRY + prDomainSubBand->ucNumChannels)) {
663 /* Buffer is not enough to include all supported channels. */
667 prChannelEntryField->ucRegulatoryClass = prDomainSubBand->ucRegClass;
668 prChannelEntryField->ucNumberOfChannels = prDomainSubBand->ucNumChannels;
670 for (u4IdxII = 0; u4IdxII < prDomainSubBand->ucNumChannels; u4IdxII++) {
671 prChannelEntryField->aucChannelList[u4IdxII] = prDomainSubBand->ucFirstChannelNum +
672 (u4IdxII * prDomainSubBand->ucChannelSpan);
675 switch (prChannelEntryField->aucChannelList[u4IdxII]) {
677 ucSocialChnlSupport = 1;
680 ucSocialChnlSupport = 6;
683 ucSocialChnlSupport = 11;
692 if (ucBufferSize >= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels)) {
693 ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels);
700 prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T)((UINT_32)prChannelEntryField +
701 P2P_ATTRI_LEN_CHANNEL_ENTRY +
702 (UINT_32)prChannelEntryField->ucNumberOfChannels);
707 if (prP2pConnSetting->ucListenChnl == 0) {
708 prP2pConnSetting->ucListenChnl = P2P_DEFAULT_LISTEN_CHANNEL;
710 if (ucSocialChnlSupport != 0) {
711 /* 1. User Not Set LISTEN channel.
712 * 2. Social channel is not empty.
714 prP2pConnSetting->ucListenChnl = ucSocialChnlSupport;
720 // TODO: 20110921 frog -
721 /* If LISTEN channel is not set,
722 * a random supported channel would be set.
723 * If no social channel is supported, DEFAULT channel would be set.
726 prP2pConnSetting->ucRfChannelListSize = P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE - ucBufferSize;
729 if (prP2pConnSetting->ucOperatingChnl == 0) { /* User not set OPERATE channel. */
731 if (scnQuerySparseChannel(prAdapter, NULL, &ucAutoChnl)) {
735 ucBufferSize = prP2pConnSetting->ucRfChannelListSize;
737 prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T)prP2pConnSetting->aucChannelEntriesField;
739 while (ucBufferSize != 0) {
740 if (prChannelEntryField->ucNumberOfChannels != 0) {
741 ucAutoChnl = prChannelEntryField->aucChannelList[0];
746 prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T)((UINT_32)prChannelEntryField +
747 P2P_ATTRI_LEN_CHANNEL_ENTRY +
748 (UINT_32)prChannelEntryField->ucNumberOfChannels);
750 ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels);
760 /* We assume user would not set a channel not in the channel list.
761 * If so, the operating channel still depends on target deivce supporting capability.
764 // TODO: 20110921 frog -
765 /* If the Operating channel is not set, a channel from supported channel list is set automatically.
766 * If there is no supported channel in channel list, a DEFAULT channel is set.
772 prP2pConnSetting->ucOperatingChnl = ucAutoChnl;
775 } /* rlmFuncInitialChannelList */
777 /*----------------------------------------------------------------------------*/
779 * \brief Find a common channel list from the local channel list info & target channel list info.
781 * \param[in] prAdapter Pointer of ADAPTER_T
783 * \return boolean value if probe response frame is
785 /*----------------------------------------------------------------------------*/
787 rlmFuncCommonChannelList (
788 IN P_ADAPTER_T prAdapter,
789 IN P_CHANNEL_ENTRY_FIELD_T prChannelEntryII,
790 IN UINT_8 ucChannelListSize
793 P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T)NULL;
794 P_CHANNEL_ENTRY_FIELD_T prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T)NULL, prChannelEntryIII = (P_CHANNEL_ENTRY_FIELD_T)NULL;
795 UINT_8 aucCommonChannelList[P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE];
796 UINT_8 ucOriChnlSize = 0, ucNewChnlSize = 0;
801 ASSERT_BREAK(prAdapter != NULL);
803 prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings;
805 prChannelEntryIII = (P_CHANNEL_ENTRY_FIELD_T)aucCommonChannelList;
807 while (ucChannelListSize > 0) {
809 prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T)prP2pConnSetting->aucChannelEntriesField;
810 ucOriChnlSize = prP2pConnSetting->ucRfChannelListSize;
812 while (ucOriChnlSize > 0) {
813 if (prChannelEntryI->ucRegulatoryClass == prChannelEntryII->ucRegulatoryClass) {
814 prChannelEntryIII->ucRegulatoryClass = prChannelEntryI->ucRegulatoryClass;
815 // TODO: Currently we assume that the regulatory class the same, the channels are the same.
816 kalMemCopy(prChannelEntryIII->aucChannelList, prChannelEntryII->aucChannelList, prChannelEntryII->ucNumberOfChannels);
817 prChannelEntryIII->ucNumberOfChannels = prChannelEntryII->ucNumberOfChannels;
819 ucNewChnlSize += P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryIII->ucNumberOfChannels;
821 prChannelEntryIII = (P_CHANNEL_ENTRY_FIELD_T)((UINT_32)prChannelEntryIII +
822 P2P_ATTRI_LEN_CHANNEL_ENTRY +
823 (UINT_32)prChannelEntryIII->ucNumberOfChannels);
826 ucOriChnlSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryI->ucNumberOfChannels);
828 prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T)((UINT_32)prChannelEntryI +
829 P2P_ATTRI_LEN_CHANNEL_ENTRY +
830 (UINT_32)prChannelEntryI->ucNumberOfChannels);
836 ucChannelListSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryII->ucNumberOfChannels);
838 prChannelEntryII = (P_CHANNEL_ENTRY_FIELD_T)((UINT_32)prChannelEntryII +
839 P2P_ATTRI_LEN_CHANNEL_ENTRY +
840 (UINT_32)prChannelEntryII->ucNumberOfChannels);
846 kalMemCopy(prP2pConnSetting->aucChannelEntriesField, aucCommonChannelList, ucNewChnlSize);
847 prP2pConnSetting->ucRfChannelListSize = ucNewChnlSize;
852 } /* rlmFuncCommonChannelList */
855 /*----------------------------------------------------------------------------*/
863 /*----------------------------------------------------------------------------*/
865 rlmFuncFindOperatingClass (
866 IN P_ADAPTER_T prAdapter,
867 IN UINT_8 ucChannelNum
870 UINT_8 ucRegulatoryClass = 0, ucBufferSize = 0;
871 P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T)NULL;
872 P_CHANNEL_ENTRY_FIELD_T prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T)NULL;
876 ASSERT_BREAK(prAdapter != NULL);
878 prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings;
879 ucBufferSize = prP2pConnSetting->ucRfChannelListSize;
880 prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T)prP2pConnSetting->aucChannelEntriesField;
882 while (ucBufferSize != 0) {
884 for (u4Idx = 0; u4Idx < prChannelEntryField->ucNumberOfChannels; u4Idx++) {
885 if (prChannelEntryField->aucChannelList[u4Idx] == ucChannelNum) {
886 ucRegulatoryClass = prChannelEntryField->ucRegulatoryClass;
893 if (ucRegulatoryClass != 0) {
897 prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T)((UINT_32)prChannelEntryField +
898 P2P_ATTRI_LEN_CHANNEL_ENTRY +
899 (UINT_32)prChannelEntryField->ucNumberOfChannels);
901 ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels);
909 return ucRegulatoryClass;
910 } /* rlmFuncFindOperatingClass */
913 /*----------------------------------------------------------------------------*/
921 /*----------------------------------------------------------------------------*/
923 rlmFuncFindAvailableChannel (
924 IN P_ADAPTER_T prAdapter,
925 IN UINT_8 ucCheckChnl,
926 IN PUINT_8 pucSuggestChannel,
927 IN BOOLEAN fgIsSocialChannel,
928 IN BOOLEAN fgIsDefaultChannel
931 BOOLEAN fgIsResultAvailable = FALSE;
932 P_CHANNEL_ENTRY_FIELD_T prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T)NULL;
933 P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T)NULL;
934 UINT_8 ucBufferSize = 0, ucIdx = 0, ucChannelSelected = 0;
937 ASSERT_BREAK(prAdapter != NULL);
939 if (fgIsDefaultChannel) {
940 ucChannelSelected = P2P_DEFAULT_LISTEN_CHANNEL;
944 prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings;
945 ucBufferSize = prP2pConnSetting->ucRfChannelListSize;
946 prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T)prP2pConnSetting->aucChannelEntriesField;
948 while ((ucBufferSize != 0) && (!fgIsResultAvailable)) {
950 for (ucIdx = 0; ucIdx < prChannelEntry->ucNumberOfChannels; ucIdx++) {
951 if ((!fgIsSocialChannel) ||
952 (prChannelEntry->aucChannelList[ucIdx] == 1) ||
953 (prChannelEntry->aucChannelList[ucIdx] == 6) ||
954 (prChannelEntry->aucChannelList[ucIdx] == 11)) {
956 if (prChannelEntry->aucChannelList[ucIdx] <= 11) {
958 ucChannelSelected = prChannelEntry->aucChannelList[ucIdx];
960 else if ((prChannelEntry->aucChannelList[ucIdx] < 52) &&
961 (prChannelEntry->aucChannelList[ucIdx] > 14)) {
963 ucChannelSelected = prChannelEntry->aucChannelList[ucIdx];
966 if (ucChannelSelected == ucCheckChnl) {
967 fgIsResultAvailable = TRUE;
975 ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntry->ucNumberOfChannels);
977 prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T)((UINT_32)prChannelEntry +
978 P2P_ATTRI_LEN_CHANNEL_ENTRY +
979 (UINT_32)prChannelEntry->ucNumberOfChannels);
985 if ((!fgIsResultAvailable) && (pucSuggestChannel != NULL)) {
986 DBGLOG(P2P, TRACE, ("The request channel %d is not available, sugguested channel:%d\n", ucCheckChnl, ucChannelSelected));
987 // Given a suggested channel.
988 *pucSuggestChannel = ucChannelSelected;
994 return fgIsResultAvailable;
997 /*----------------------------------------------------------------------------*/
1005 /*----------------------------------------------------------------------------*/
1008 P_ADAPTER_T prAdapter,
1009 P_BSS_INFO_T prBssInfo
1012 P_DOMAIN_SUBBAND_INFO prSubband;
1013 P_DOMAIN_INFO_ENTRY prDomainInfo;
1014 UINT_8 ucSecondChannel, i, j;
1015 ENUM_CHNL_EXT_T eSCO;
1017 eSCO = CHNL_EXT_SCN;
1019 if (prBssInfo->eBand == BAND_2G4) {
1020 if (prBssInfo->ucPrimaryChannel != 14) {
1021 eSCO = (prBssInfo->ucPrimaryChannel > 7) ?
1022 CHNL_EXT_SCB : CHNL_EXT_SCA;
1026 prDomainInfo = rlmDomainGetDomainInfo(prAdapter);
1027 ASSERT(prDomainInfo);
1029 for (i = 0; i < MAX_SUBBAND_NUM; i++) {
1030 prSubband = &prDomainInfo->rSubBand[i];
1031 if (prSubband->ucBand == prBssInfo->eBand) {
1032 for (j = 0; j < prSubband->ucNumChannels; j++) {
1033 if ((prSubband->ucFirstChannelNum + j*prSubband->ucChannelSpan)
1034 == prBssInfo->ucPrimaryChannel) {
1035 eSCO = (j & 1) ? CHNL_EXT_SCB : CHNL_EXT_SCA;
1040 if (j < prSubband->ucNumChannels) {
1047 /* Check if it is boundary channel and 40MHz BW is permitted */
1048 if (eSCO != CHNL_EXT_SCN) {
1049 ucSecondChannel = (eSCO == CHNL_EXT_SCA) ?
1050 (prBssInfo->ucPrimaryChannel+ 4) : (prBssInfo->ucPrimaryChannel- 4);
1052 if (!rlmDomainIsLegalChannel(prAdapter, prBssInfo->eBand, ucSecondChannel)){
1053 eSCO = CHNL_EXT_SCN;