From c72d45ce461fa1378c23802a7abfeca4c012983b Mon Sep 17 00:00:00 2001 From: lifeng Date: Tue, 10 Jan 2017 18:28:31 +0800 Subject: qcacld-2.0: Update the supported rates when channel switching Fix the regression issue introduced by commit 329c3375edfcf5c434ed57fdec5dd27229611d8a that the supported rates are populated by hostapd which cause that the supported rates won't update althought cross-band switching from 2G to 5G, then the sap will reject any sta who intends to join the bss. The Fix now is to populate the intersection of rates generated by hostapd and driver itself. Change-Id: Ica336398865a8b5e16297e4555dbb7de5e79567e CRs-fixed: 1109564 --- CORE/MAC/inc/sirMacProtDef.h | 10 ++- CORE/SME/src/csr/csrApiRoam.c | 141 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 134 insertions(+), 17 deletions(-) diff --git a/CORE/MAC/inc/sirMacProtDef.h b/CORE/MAC/inc/sirMacProtDef.h index 699a141e9c1d..323b8c9ff7db 100644 --- a/CORE/MAC/inc/sirMacProtDef.h +++ b/CORE/MAC/inc/sirMacProtDef.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -1039,6 +1039,14 @@ typedef __ani_attr_pre_packed struct sSirMacRateSet tANI_U8 rate[SIR_MAC_RATESET_EID_MAX]; } __ani_attr_packed tSirMacRateSet; +/** struct merged_mac_rate_set - merged mac rate set + * @num_rates: num of rates + * @rate: rate list + */ +struct merged_mac_rate_set { + uint8_t num_rates; + uint8_t rate[2 * SIR_MAC_RATESET_EID_MAX]; +}; typedef __ani_attr_pre_packed struct sSirMacSSid { diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c index 47fa7960086f..61caf51753fd 100644 --- a/CORE/SME/src/csr/csrApiRoam.c +++ b/CORE/SME/src/csr/csrApiRoam.c @@ -12709,7 +12709,7 @@ csr_convert_mode_to_nw_type(eCsrCfgDot11Mode dot11_mode, eCsrBand band) * * Return: void */ -static void csr_populate_supported_rates_from_hostapd(tSirMacRateSet *opr_rates, +void csr_populate_supported_rates_from_hostapd(tSirMacRateSet *opr_rates, tSirMacRateSet *ext_rates, tCsrRoamProfile *pProfile) { @@ -12735,6 +12735,105 @@ static void csr_populate_supported_rates_from_hostapd(tSirMacRateSet *opr_rates, } } +/** + * csr_merge_supported_and_extended_rates() - merge supported rates and + * extended rates + * @rates: merged rates + * @supported_rates: supported rates + * @extended_rates: extended rates + * + * Return: None + */ +static void csr_merge_supported_and_extended_rates( + struct merged_mac_rate_set *rates, + tSirMacRateSet *supported_rates, + tSirMacRateSet *extended_rates) +{ + int i; + + vos_mem_copy(rates->rate, + supported_rates->rate, + supported_rates->numRates); + rates->num_rates = supported_rates->numRates; + + vos_mem_copy(rates->rate + rates->num_rates, + extended_rates->rate, + extended_rates->numRates); + rates->num_rates += extended_rates->numRates; + + for (i = 0; i < rates->num_rates; i++) + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Merge rate is %2x"), rates->rate[i]); +} + +/** + * csr_populate_intersection_driver_and_hostpd_rates() - populate + * intersection of driver rates and hostapd rates + * @pParam: csr roam start bss params + * @driver_rates: rates generated by driver + * @hostapd_rates: rates generated by hostapd + * + * Return: None + */ +static void csr_populate_intersection_driver_and_hostpd_rates( + tCsrRoamStartBssParams *pParam, + struct merged_mac_rate_set *driver_rates, + struct merged_mac_rate_set *hostapd_rates) +{ + int i, j; + struct merged_mac_rate_set rates; + uint8_t driver_rate, hostapd_rate; + tSirMacRateSet *opr_rates = &pParam->operationalRateSet; + tSirMacRateSet *ext_rates = &pParam->extendedRateSet; + + rates.num_rates = 0; + + for (i = 0; i < driver_rates->num_rates; i++) { + driver_rate = driver_rates->rate[i]; + if (CSR_IS_BASIC_RATE(driver_rate)) + BITS_OFF(driver_rate, + CSR_DOT11_BASIC_RATE_MASK); + + for (j = 0; j < hostapd_rates->num_rates; j++) { + hostapd_rate = hostapd_rates->rate[j]; + if (CSR_IS_BASIC_RATE(hostapd_rate)) + BITS_OFF(hostapd_rate, + CSR_DOT11_BASIC_RATE_MASK); + + if (driver_rate == hostapd_rate) { + if (CSR_IS_BASIC_RATE(driver_rates->rate[i]) || + CSR_IS_BASIC_RATE(hostapd_rates->rate[j])) + BITS_ON(driver_rate, + CSR_DOT11_BASIC_RATE_MASK); + + rates.rate[rates.num_rates++] = driver_rate; + break; + } + } + } + + for (i = 0; i < rates.num_rates; i++) + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Intersection rate is %2x"), rates.rate[i]); + + opr_rates->numRates = 0; + ext_rates->numRates = 0; + if (rates.num_rates <= MAX_NUM_SUPPORTED_RATES) { + opr_rates->numRates = rates.num_rates; + vos_mem_copy(opr_rates->rate, + rates.rate, + opr_rates->numRates); + } else { + opr_rates->numRates = MAX_NUM_SUPPORTED_RATES; + vos_mem_copy(opr_rates->rate, + rates.rate, + MAX_NUM_SUPPORTED_RATES); + ext_rates->numRates = rates.num_rates - MAX_NUM_SUPPORTED_RATES; + vos_mem_copy(ext_rates->rate, + rates.rate + MAX_NUM_SUPPORTED_RATES, + ext_rates->numRates); + } +} /** * csrRoamGetBssStartParms() - get bss start param from profile * @pMac: mac global context @@ -12775,21 +12874,7 @@ static void csrRoamGetBssStartParms(tpAniSirGlobal pMac, } nwType = csr_convert_mode_to_nw_type(pParam->uCfgDot11Mode, eBand); pParam->extendedRateSet.numRates = 0; - /* - * hostapd.conf will populate its basic and extended rates - * as per hw_mode but if acs in ini is enabled, driver should - * ignore basic and extended rates from hostapd.conf and should - * populate default rates. - */ - if (pProfile->supported_rates.numRates || - pProfile->extended_rates.numRates) { - csr_populate_supported_rates_from_hostapd(opr_rates, - ext_rates, pProfile); - pParam->operationChn = operation_channel; - pParam->sirNwType = nwType; - pParam->vht_channel_width = pProfile->vht_channel_width; - return; - } + switch (nwType) { default: smsLog(pMac, LOGE, FL("sees an unknown pSirNwType (%d)"), @@ -12839,6 +12924,30 @@ static void csrRoamGetBssStartParms(tpAniSirGlobal pMac, channel = operation_channel; break; } + + if (pProfile->supported_rates.numRates || + pProfile->extended_rates.numRates) { + struct merged_mac_rate_set rates_driver, rates_hostapd; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "Merge rates driver"); + csr_merge_supported_and_extended_rates(&rates_driver, + opr_rates, + ext_rates); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "Merge rates hostapd"); + csr_merge_supported_and_extended_rates(&rates_hostapd, + &pProfile->supported_rates, + &pProfile->extended_rates); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "Populate rates intersection"); + csr_populate_intersection_driver_and_hostpd_rates(pParam, + &rates_driver, + &rates_hostapd); + } + pParam->operationChn = channel; pParam->sirNwType = nwType; pParam->vht_channel_width = pProfile->vht_channel_width; -- cgit v1.2.3