diff --git a/core/mac/inc/sir_mac_prot_def.h b/core/mac/inc/sir_mac_prot_def.h index 20c1516cf503..8ea6dceed498 100644 --- a/core/mac/inc/sir_mac_prot_def.h +++ b/core/mac/inc/sir_mac_prot_def.h @@ -361,6 +361,9 @@ #define SIR_MAC_CHNL_EXTENDED_SWITCH_ANN_EID_MIN 0 #define SIR_MAC_CHNL_EXTENDED_SWITCH_ANN_EID_MAX 255 +#define SIR_MAC_OPERATING_CLASS_EID 59 +#define SIR_MAC_OPERATING_CLASS_EID_MIN 2 +#define SIR_MAC_OPERATING_CLASS_EID_MAX 253 /* reserved 51-69 */ #define SIR_MAC_RM_ENABLED_CAPABILITY_EID 70 #define SIR_MAC_RM_ENABLED_CAPABILITY_EID_MIN 5 diff --git a/core/mac/src/cfg/cfgUtil/dot11f.frms b/core/mac/src/cfg/cfgUtil/dot11f.frms index 3c9004a007ae..5f50801751f5 100644 --- a/core/mac/src/cfg/cfgUtil/dot11f.frms +++ b/core/mac/src/cfg/cfgUtil/dot11f.frms @@ -2815,6 +2815,7 @@ FRAME Beacon // C.f. Sec. 7.2.3.1 OPTIE PowerConstraints; OPTIE ChanSwitchAnn; OPTIE ext_chan_switch_ann; + OPTIE SuppOperatingClasses; OPTIE Quiet; OPTIE TPCReport; OPTIE ERPInfo; @@ -2904,6 +2905,7 @@ FRAME Beacon2 OPTIE PowerConstraints; OPTIE ChanSwitchAnn; OPTIE ext_chan_switch_ann; + OPTIE SuppOperatingClasses; OPTIE Quiet; OPTIE TPCReport; OPTIE ERPInfo; @@ -2963,6 +2965,7 @@ FRAME BeaconIEs OPTIE PowerConstraints; OPTIE ChanSwitchAnn; OPTIE ext_chan_switch_ann; + OPTIE SuppOperatingClasses; OPTIE Quiet; OPTIE TPCReport; OPTIE ERPInfo; @@ -3178,6 +3181,7 @@ FRAME ProbeResponse // 7.2.3.9 OPTIE PowerConstraints; OPTIE ChanSwitchAnn; OPTIE ext_chan_switch_ann; + OPTIE SuppOperatingClasses; OPTIE Quiet; OPTIE TPCReport; OPTIE ERPInfo; diff --git a/core/mac/src/include/dot11f.h b/core/mac/src/include/dot11f.h index 09dfde671127..a174f5e35f9e 100644 --- a/core/mac/src/include/dot11f.h +++ b/core/mac/src/include/dot11f.h @@ -35,7 +35,7 @@ * * * This file was automatically generated by 'framesc' - * Mon Nov 16 10:55:21 2015 from the following file(s): + * Mon Nov 16 14:10:10 2015 from the following file(s): * * dot11f.frms * @@ -7533,6 +7533,7 @@ typedef struct sDot11fBeacon{ tDot11fIEPowerConstraints PowerConstraints; tDot11fIEChanSwitchAnn ChanSwitchAnn; tDot11fIEext_chan_switch_ann ext_chan_switch_ann; + tDot11fIESuppOperatingClasses SuppOperatingClasses; tDot11fIEQuiet Quiet; tDot11fIETPCReport TPCReport; tDot11fIEERPInfo ERPInfo; @@ -7627,6 +7628,7 @@ typedef struct sDot11fBeacon2{ tDot11fIEPowerConstraints PowerConstraints; tDot11fIEChanSwitchAnn ChanSwitchAnn; tDot11fIEext_chan_switch_ann ext_chan_switch_ann; + tDot11fIESuppOperatingClasses SuppOperatingClasses; tDot11fIEQuiet Quiet; tDot11fIETPCReport TPCReport; tDot11fIEERPInfo ERPInfo; @@ -7698,6 +7700,7 @@ typedef struct sDot11fBeaconIEs{ tDot11fIEPowerConstraints PowerConstraints; tDot11fIEChanSwitchAnn ChanSwitchAnn; tDot11fIEext_chan_switch_ann ext_chan_switch_ann; + tDot11fIESuppOperatingClasses SuppOperatingClasses; tDot11fIEQuiet Quiet; tDot11fIETPCReport TPCReport; tDot11fIEERPInfo ERPInfo; @@ -8110,6 +8113,7 @@ typedef struct sDot11fProbeResponse{ tDot11fIEPowerConstraints PowerConstraints; tDot11fIEChanSwitchAnn ChanSwitchAnn; tDot11fIEext_chan_switch_ann ext_chan_switch_ann; + tDot11fIESuppOperatingClasses SuppOperatingClasses; tDot11fIEQuiet Quiet; tDot11fIETPCReport TPCReport; tDot11fIEERPInfo ERPInfo; diff --git a/core/mac/src/include/parser_api.h b/core/mac/src/include/parser_api.h index afbfd5e339e6..42f016a09163 100644 --- a/core/mac/src/include/parser_api.h +++ b/core/mac/src/include/parser_api.h @@ -109,6 +109,7 @@ typedef struct sSirProbeRespBeacon { tDot11fIEChanSwitchAnn channelSwitchIE; tDot11fIEsec_chan_offset_ele sec_chan_offset; tDot11fIEext_chan_switch_ann ext_chan_switch; + tDot11fIESuppOperatingClasses supp_operating_classes; tSirMacAddr bssid; tDot11fIEQuiet quietIE; tDot11fIEHTCaps HTCaps; @@ -124,6 +125,7 @@ typedef struct sSirProbeRespBeacon { uint8_t ssidPresent; uint8_t suppRatesPresent; uint8_t extendedRatesPresent; + uint8_t supp_operating_class_present; uint8_t cfPresent; uint8_t dsParamsPresent; uint8_t timPresent; @@ -961,5 +963,7 @@ populate_dot11f_avoid_channel_ie(tpAniSirGlobal mac_ctx, tSirRetStatus populate_dot11f_timing_advert_frame(tpAniSirGlobal pMac, tDot11fTimingAdvertisementFrame *frame); +void populate_dot11_supp_operating_classes(tpAniSirGlobal mac_ptr, + tDot11fIESuppOperatingClasses *dot_11_ptr, tpPESession session_entry); #endif /* __PARSE_H__ */ diff --git a/core/mac/src/pe/sch/sch_beacon_gen.c b/core/mac/src/pe/sch/sch_beacon_gen.c index 7e0b23cbf2d9..28d19414a107 100644 --- a/core/mac/src/pe/sch/sch_beacon_gen.c +++ b/core/mac/src/pe/sch/sch_beacon_gen.c @@ -293,6 +293,8 @@ sch_set_fixed_beacon_fields(tpAniSirGlobal mac_ctx, tpPESession session) &bcn_2->ext_chan_switch_ann, session); + populate_dot11_supp_operating_classes(mac_ctx, + &bcn_2->SuppOperatingClasses, session); populate_dot11f_country(mac_ctx, &bcn_2->Country, session); if (bcn_1->Capabilities.qos) populate_dot11f_edca_param_set(mac_ctx, &bcn_2->EDCAParamSet, @@ -582,6 +584,15 @@ void lim_update_probe_rsp_template_ie_bitmap_beacon2(tpAniSirGlobal pMac, sizeof(beacon2->ext_chan_switch_ann)); } + /* Supported operating class */ + if (beacon2->SuppOperatingClasses.present) { + set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap, + SIR_MAC_OPERATING_CLASS_EID); + cdf_mem_copy((void *)&prb_rsp->SuppOperatingClasses, + (void *)&beacon2->SuppOperatingClasses, + sizeof(beacon2->SuppOperatingClasses)); + } + #ifdef FEATURE_AP_MCC_CH_AVOIDANCE if (beacon2->QComVendorIE.present) { set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap, diff --git a/core/mac/src/sys/legacy/src/utils/src/dot11f.c b/core/mac/src/sys/legacy/src/utils/src/dot11f.c index aed4bd917005..3cbbf29ae9e1 100644 --- a/core/mac/src/sys/legacy/src/utils/src/dot11f.c +++ b/core/mac/src/sys/legacy/src/utils/src/dot11f.c @@ -6136,6 +6136,10 @@ static const tIEDefn IES_Beacon[] = { offsetof(tDot11fIEext_chan_switch_ann, present), 0, "ext_chan_switch_ann", 0, 6, 6, SigIeext_chan_switch_ann, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXT_CHAN_SWITCH_ANN, 0, }, + { offsetof(tDot11fBeacon, SuppOperatingClasses), + offsetof(tDot11fIESuppOperatingClasses, present), 0, + "SuppOperatingClasses", 0, 3, 34, SigIeSuppOperatingClasses, + {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPOPERATINGCLASSES, 0, }, { offsetof(tDot11fBeacon, Quiet), offsetof(tDot11fIEQuiet, present), 0, "Quiet", 0, 8, 8, SigIeQuiet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QUIET, 0, }, { offsetof(tDot11fBeacon, TPCReport), offsetof(tDot11fIETPCReport, @@ -6331,6 +6335,10 @@ static const tIEDefn IES_Beacon2[] = { offsetof(tDot11fIEext_chan_switch_ann, present), 0, "ext_chan_switch_ann", 0, 6, 6, SigIeext_chan_switch_ann, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXT_CHAN_SWITCH_ANN, 0, }, + { offsetof(tDot11fBeacon2, SuppOperatingClasses), + offsetof(tDot11fIESuppOperatingClasses, present), 0, + "SuppOperatingClasses", 0, 3, 34, SigIeSuppOperatingClasses, + {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPOPERATINGCLASSES, 0, }, { offsetof(tDot11fBeacon2, Quiet), offsetof(tDot11fIEQuiet, present), 0, "Quiet", 0, 8, 8, SigIeQuiet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QUIET, 0, }, { offsetof(tDot11fBeacon2, TPCReport), offsetof(tDot11fIETPCReport, @@ -6507,6 +6515,10 @@ static const tIEDefn IES_BeaconIEs[] = { offsetof(tDot11fIEext_chan_switch_ann, present), 0, "ext_chan_switch_ann", 0, 6, 6, SigIeext_chan_switch_ann, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXT_CHAN_SWITCH_ANN, 0, }, + { offsetof(tDot11fBeaconIEs, SuppOperatingClasses), + offsetof(tDot11fIESuppOperatingClasses, present), 0, + "SuppOperatingClasses", 0, 3, 34, SigIeSuppOperatingClasses, + {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPOPERATINGCLASSES, 0, }, { offsetof(tDot11fBeaconIEs, Quiet), offsetof(tDot11fIEQuiet, present), 0, "Quiet", 0, 8, 8, SigIeQuiet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QUIET, 0, }, { offsetof(tDot11fBeaconIEs, TPCReport), offsetof(tDot11fIETPCReport, @@ -7115,6 +7127,10 @@ static const tIEDefn IES_ProbeResponse[] = { offsetof(tDot11fIEext_chan_switch_ann, present), 0, "ext_chan_switch_ann", 0, 6, 6, SigIeext_chan_switch_ann, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXT_CHAN_SWITCH_ANN, 0, }, + { offsetof(tDot11fProbeResponse, SuppOperatingClasses), + offsetof(tDot11fIESuppOperatingClasses, present), 0, + "SuppOperatingClasses", 0, 3, 34, SigIeSuppOperatingClasses, + {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPOPERATINGCLASSES, 0, }, { offsetof(tDot11fProbeResponse, Quiet), offsetof(tDot11fIEQuiet, present), 0, "Quiet", 0, 8, 8, SigIeQuiet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QUIET, 0, }, diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c index 42e618d60671..f7cfb78f38bb 100644 --- a/core/mac/src/sys/legacy/src/utils/src/parser_api.c +++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c @@ -275,6 +275,48 @@ populate_dot11f_chan_switch_ann(tpAniSirGlobal pMac, pDot11f->present = 1; } +/** + * populate_dot11_supp_operating_classes() - Function to populate supported + * operating class IE + * @mac_ptr: Pointer to PMAC structure + * @dot_11_ptr: Operating class element + * @session_entry: PE session entry + * + * Return: None + */ +void +populate_dot11_supp_operating_classes(tpAniSirGlobal mac_ptr, + tDot11fIESuppOperatingClasses *dot_11_ptr, + tpPESession session_entry) +{ + uint8_t ch_bandwidth; + + if (session_entry->vhtTxChannelWidthSet == eHT_CHANNEL_WIDTH_80MHZ) { + ch_bandwidth = BW80; + } else { + switch (session_entry->htSecondaryChannelOffset) { + case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: + ch_bandwidth = BW40_HIGH_PRIMARY; + break; + case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: + ch_bandwidth = BW40_LOW_PRIMARY; + break; + default: + ch_bandwidth = BW20; + break; + } + } + + cds_regdm_get_curr_opclasses(&dot_11_ptr->num_classes, + &dot_11_ptr->classes[1]); + dot_11_ptr->classes[0] = cds_regdm_get_opclass_from_channel( + mac_ptr->scan.countryCodeCurrent, + session_entry->currentOperChannel, + ch_bandwidth); + dot_11_ptr->num_classes++; + dot_11_ptr->present = 1; +} + void populate_dot11f_chan_switch_wrapper(tpAniSirGlobal pMac, tDot11fIEChannelSwitchWrapper *pDot11f, @@ -2293,6 +2335,13 @@ tSirRetStatus sir_convert_probe_frame2_struct(tpAniSirGlobal pMac, sizeof(tDot11fIEext_chan_switch_ann)); } + if (pr->SuppOperatingClasses.present) { + pProbeResp->supp_operating_class_present = 1; + cdf_mem_copy(&pProbeResp->supp_operating_classes, + &pr->SuppOperatingClasses, + sizeof(tDot11fIESuppOperatingClasses)); + } + if (pr->sec_chan_offset_ele.present) { pProbeResp->sec_chan_offset_present = 1; cdf_mem_copy(&pProbeResp->sec_chan_offset, @@ -3484,6 +3533,13 @@ sir_parse_beacon_ie(tpAniSirGlobal pMac, sizeof(pBeaconStruct->channelSwitchIE)); } + if (pBies->SuppOperatingClasses.present) { + pBeaconStruct->supp_operating_class_present = 1; + cdf_mem_copy(&pBeaconStruct->supp_operating_classes, + &pBies->SuppOperatingClasses, + sizeof(tDot11fIESuppOperatingClasses)); + } + if (pBies->ext_chan_switch_ann.present) { pBeaconStruct->ext_chan_switch_present = 1; cdf_mem_copy(&pBeaconStruct->ext_chan_switch, diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 39139da7c8b8..f9d06bd146d9 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -18602,6 +18602,7 @@ csr_update_op_class_array(tpAniSirGlobal mac_ctx, uint8_t j = 0, idx = 0, class = 0; bool found = false; uint8_t num_channels = channel_info->numChannels; + uint8_t ch_bandwidth; sms_log(mac_ctx, LOG1, FL("Num of %s channels, %d"), @@ -18609,23 +18610,28 @@ csr_update_op_class_array(tpAniSirGlobal mac_ctx, for (idx = 0; idx < num_channels && *i < (SIR_MAC_MAX_SUPP_OPER_CLASSES - 1); idx++) { - class = cds_regdm_get_opclass_from_channel( - mac_ctx->scan.countryCodeCurrent, - channel_info->channelList[idx], - BWALL); - sms_log(mac_ctx, LOG4, FL("for chan %d, op class: %d"), - channel_info->channelList[idx], class); + for (ch_bandwidth = BW20; ch_bandwidth < BWALL; + ch_bandwidth++) { + class = cds_regdm_get_opclass_from_channel( + mac_ctx->scan.countryCodeCurrent, + channel_info->channelList[idx], + ch_bandwidth); + sms_log(mac_ctx, LOG4, FL("for chan %d, op class: %d"), + channel_info->channelList[idx], class); - found = false; - for (j = 0; j < SIR_MAC_MAX_SUPP_OPER_CLASSES - 1; j++) { - if (op_classes[j] == class) { - found = true; - break; + found = false; + for (j = 0; j < SIR_MAC_MAX_SUPP_OPER_CLASSES - 1; + j++) { + if (op_classes[j] == class) { + found = true; + break; + } + } + + if (!found) { + op_classes[*i] = class; + *i = *i + 1; } - } - if (!found) { - op_classes[*i] = class; - *i = *i + 1; } } }