/*----------------------------------------------------------------------------*/ VOID rlmBssInitForAP( P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo ) { ENUM_BAND_T eBand; UINT_8 ucChannel; ENUM_CHNL_EXT_T eSCO; ASSERT(prAdapter); ASSERT(prBssInfo); if (prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) { return; } /* Operation band, channel shall be ready before invoking this function. * Bandwidth may be ready if other network is connected */ prBssInfo->fg40mBwAllowed = FALSE; prBssInfo->fgAssoc40mBwAllowed = FALSE; prBssInfo->eBssSCO = CHNL_EXT_SCN; if (RLM_AP_IS_BW_40_ALLOWED(prAdapter, prBssInfo)) { /* In this case, the first BSS's SCO is 40MHz and known, so AP can * apply 40MHz bandwidth, but the first BSS's SCO may be changed * later if its Beacon lost timeout occurs */ if (cnmPreferredChannel(prAdapter, &eBand, &ucChannel, &eSCO) && eSCO != CHNL_EXT_SCN && ucChannel == prBssInfo->ucPrimaryChannel && eBand == prBssInfo->eBand) { prBssInfo->eBssSCO = eSCO; } else if (cnmBss40mBwPermitted(prAdapter, prBssInfo->ucNetTypeIndex)) { prBssInfo->eBssSCO = rlmDecideScoForAP(prAdapter, prBssInfo); } if (prBssInfo->eBssSCO != CHNL_EXT_SCN) { prBssInfo->fg40mBwAllowed = TRUE; prBssInfo->fgAssoc40mBwAllowed = TRUE; prBssInfo->ucHtOpInfo1 = (UINT_8) (((UINT_32) prBssInfo->eBssSCO) | HT_OP_INFO1_STA_CHNL_WIDTH); rlmUpdateBwByChListForAP(prAdapter, prBssInfo); } } DBGLOG(RLM, INFO, ("WLAN AP SCO=%d\n", prBssInfo->eBssSCO)); }
/*----------------------------------------------------------------------------*/ VOID rlmBssInitForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) { ENUM_BAND_T eBand; UINT_8 ucChannel, i; ENUM_CHNL_EXT_T eSCO; ASSERT(prAdapter); ASSERT(prBssInfo); if (prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) { return; } /* Operation band, channel shall be ready before invoking this function. * Bandwidth may be ready if other network is connected */ prBssInfo->fg40mBwAllowed = FALSE; prBssInfo->fgAssoc40mBwAllowed = FALSE; prBssInfo->eBssSCO = CHNL_EXT_SCN; /* Check if AP can set its bw to 40MHz * But if any of BSS is setup in 40MHz, the second BSS would prefer to use 20MHz * in order to remain in SCC case */ if (cnmBss40mBwPermitted(prAdapter, prBssInfo->ucBssIndex)) { /* In this case, the first BSS's SCO is 40MHz and known, so AP can * apply 40MHz bandwidth, but the first BSS's SCO may be changed * later if its Beacon lost timeout occurs */ if (cnmPreferredChannel(prAdapter, &eBand, &ucChannel, &eSCO) && eSCO != CHNL_EXT_SCN && ucChannel == prBssInfo->ucPrimaryChannel && eBand == prBssInfo->eBand) { prBssInfo->eBssSCO = eSCO; } else { prBssInfo->eBssSCO = rlmDecideScoForAP(prAdapter, prBssInfo); } if (prBssInfo->eBssSCO != CHNL_EXT_SCN) { prBssInfo->fg40mBwAllowed = TRUE; prBssInfo->fgAssoc40mBwAllowed = TRUE; prBssInfo->ucHtOpInfo1 = (UINT_8) (((UINT_32) prBssInfo->eBssSCO) | HT_OP_INFO1_STA_CHNL_WIDTH); rlmUpdateBwByChListForAP(prAdapter, prBssInfo); } } /* Filled the VHT BW/S1/S2 and MCS rate set */ if(prBssInfo->ucPhyTypeSet & PHY_TYPE_BIT_VHT) { for(i = 0 ; i < 8 ; i++ ){ prBssInfo->u2VhtBasicMcsSet |= BITS(2*i,(2*i+1)); } prBssInfo->u2VhtBasicMcsSet &= (VHT_CAP_INFO_MCS_MAP_MCS9 << VHT_CAP_INFO_MCS_1SS_OFFSET); if(cnmGetBssMaxBw(prAdapter, prBssInfo->ucBssIndex) < MAX_BW_80MHZ || prBssInfo->eBand == BAND_2G4) { prBssInfo->ucVhtChannelWidth = VHT_OP_CHANNEL_WIDTH_20_40; prBssInfo->ucVhtChannelFrequencyS1 = 0; prBssInfo->ucVhtChannelFrequencyS2 = 0; } else if(cnmGetBssMaxBw(prAdapter, prBssInfo->ucBssIndex) == MAX_BW_80MHZ) { prBssInfo->ucVhtChannelWidth = VHT_OP_CHANNEL_WIDTH_80; prBssInfo->ucVhtChannelFrequencyS1 = nicGetVhtS1(prBssInfo->ucPrimaryChannel); prBssInfo->ucVhtChannelFrequencyS2 = 0; } else { //4 TODO: BW160 / BW80+80 support } } else { prBssInfo->ucVhtChannelWidth = VHT_OP_CHANNEL_WIDTH_20_40; prBssInfo->ucVhtChannelFrequencyS1 = 0; prBssInfo->ucVhtChannelFrequencyS2 = 0; } DBGLOG(RLM, INFO, ("WLAN AP SCO=%d BW=%d S1=%d S2=%d CH=%d Band=%d\n", prBssInfo->eBssSCO, prBssInfo->ucVhtChannelWidth, prBssInfo->ucVhtChannelFrequencyS1, prBssInfo->ucVhtChannelFrequencyS2, prBssInfo->ucVhtChannelWidth, prBssInfo->eBand )); }
/*----------------------------------------------------------------------------*/ VOID rlmProcessPublicAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) { P_ACTION_20_40_COEXIST_FRAME prRxFrame; P_IE_20_40_COEXIST_T prCoexist; P_IE_INTOLERANT_CHNL_REPORT_T prChnlReport; P_BSS_INFO_T prBssInfo; P_STA_RECORD_T prStaRec; PUINT_8 pucIE; UINT_16 u2IELength, u2Offset; UINT_8 i, j; ASSERT(prAdapter); ASSERT(prSwRfb); prRxFrame = (P_ACTION_20_40_COEXIST_FRAME) prSwRfb->pvHeader; prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); if (prRxFrame->ucAction != ACTION_PUBLIC_20_40_COEXIST || !prStaRec || prStaRec->ucStaState != STA_STATE_3 || prSwRfb->u2PacketLen < (WLAN_MAC_MGMT_HEADER_LEN + 5) || prSwRfb->prStaRec->ucBssIndex != /* HIF_RX_HDR_GET_NETWORK_IDX(prSwRfb->prHifRxHdr) != */ prStaRec->ucBssIndex) { return; } prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex); ASSERT(prBssInfo); if (!IS_BSS_ACTIVE(prBssInfo) || prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT || prBssInfo->eBssSCO == CHNL_EXT_SCN) { return; } prCoexist = &prRxFrame->rBssCoexist; if (prCoexist->ucData & (BSS_COEXIST_40M_INTOLERANT | BSS_COEXIST_20M_REQ)) { ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G); for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { if (prBssInfo->auc2G_20mReqChnlList[i] == prBssInfo->ucPrimaryChannel) { break; } } if ((i > prBssInfo->auc2G_20mReqChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { prBssInfo->auc2G_20mReqChnlList[i] = prBssInfo->ucPrimaryChannel; prBssInfo->auc2G_20mReqChnlList[0]++; } } /* Process intolerant channel report IE */ pucIE = (PUINT_8) &prRxFrame->rChnlReport; u2IELength = prSwRfb->u2PacketLen - (WLAN_MAC_MGMT_HEADER_LEN + 5); IE_FOR_EACH(pucIE, u2IELength, u2Offset) { switch (IE_ID(pucIE)) { case ELEM_ID_20_40_INTOLERANT_CHNL_REPORT: prChnlReport = (P_IE_INTOLERANT_CHNL_REPORT_T) pucIE; if (prChnlReport->ucLength <= 1) { break; } /* To do: process regulatory class. Now we assume 2.4G band */ for (j = 0; j < prChnlReport->ucLength - 1; j++) { /* Update non-HT channel list */ ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { if (prBssInfo->auc2G_NonHtChnlList[i] == prChnlReport->aucChannelList[j]) { break; } } if ((i > prBssInfo->auc2G_NonHtChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { prBssInfo->auc2G_NonHtChnlList[i] = prChnlReport->aucChannelList[j]; prBssInfo->auc2G_NonHtChnlList[0]++; } } break; default: break; } } /* end of IE_FOR_EACH */ if (rlmUpdateBwByChListForAP(prAdapter, prBssInfo)) { bssUpdateBeaconContent(prAdapter, prBssInfo->ucBssIndex); rlmSyncOperationParams(prAdapter, prBssInfo); } /* Check if OBSS scan exemption response should be sent */ if (prCoexist->ucData & BSS_COEXIST_OBSS_SCAN_EXEMPTION_REQ) { rlmObssScanExemptionRsp(prAdapter, prBssInfo, prSwRfb); } }