diff options
| author | Agrawal Ashish <ashishka@qti.qualcomm.com> | 2016-02-26 16:24:10 +0530 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2016-03-01 14:44:48 +0530 |
| commit | 642c5aa4e597b91ce6460ed61135fc7aa2e8195e (patch) | |
| tree | d6e2ffed3bac816459df0c1e4f0194891a8e8ea0 | |
| parent | 2f3a4011d25d1b4d6af03bab4e8b727e6bf559cc (diff) | |
qcacld-2.0: Correct handling for Setband
Currently whenever country code changes, nvtable is updated
only for channels which are enabled in wiphy.
vos_update_band updates wiphy on basis of nv table.
There can be an issue when band change, country code and again band
change happens.
Driver will not have channel information to enable channels for second
band change as at the time of driver change nv table will have only
channels associated with previous band.
Now with this fix, nv table will have all the channels.
Along with channels nv table will store wiphy flags as well.
vos_update_band will update those flags whenever band
change happens.
Change-Id: Ia1d7d85cd0acbfa95e23410825559506253a579c
CRs-Fixed: 978660
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_cfg80211.c | 62 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_wext.c | 4 | ||||
| -rw-r--r-- | CORE/VOSS/inc/vos_nvitem.h | 4 | ||||
| -rw-r--r-- | CORE/VOSS/src/vos_nvitem.c | 138 | ||||
| -rw-r--r-- | wcnss/inc/wlan_nv.h | 7 |
5 files changed, 135 insertions, 80 deletions
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c index 298b3554b155..c009d739a9da 100644 --- a/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -10938,68 +10938,6 @@ struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size) } /* - * FUNCTION: wlan_hdd_cfg80211_update_band - * This function is called from the supplicant through a - * private ioctl to change the band value - */ -int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand) -{ - int i, j; - eNVChannelEnabledType channelEnabledState; - - ENTER(); - - for (i = 0; i < IEEE80211_NUM_BANDS; i++) - { - - if (NULL == wiphy->bands[i]) - continue; - - for (j = 0; j < wiphy->bands[i]->n_channels; j++) - { - struct ieee80211_supported_band *band = wiphy->bands[i]; - - channelEnabledState = vos_nv_getChannelEnabledState( - band->channels[j].hw_value); - - if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only - { -#ifdef WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY - // Enable Social channels for P2P - if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) && - NV_CHANNEL_ENABLE == channelEnabledState) - band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED; - else -#endif - band->channels[j].flags |= IEEE80211_CHAN_DISABLED; - continue; - } - else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only - { - band->channels[j].flags |= IEEE80211_CHAN_DISABLED; - continue; - } - - if (NV_CHANNEL_DISABLE == channelEnabledState || - NV_CHANNEL_INVALID == channelEnabledState) - { - band->channels[j].flags |= IEEE80211_CHAN_DISABLED; - } - else if (NV_CHANNEL_DFS == channelEnabledState) - { - band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED; - band->channels[j].flags |= IEEE80211_CHAN_RADAR; - } - else - { - band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED - |IEEE80211_CHAN_RADAR); - } - } - } - return 0; -} -/* * FUNCTION: wlan_hdd_cfg80211_init * This function is called by hdd_wlan_startup() * during initialization. diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c index bf2c4edf2168..0398a593de3d 100644 --- a/CORE/HDD/src/wlan_hdd_wext.c +++ b/CORE/HDD/src/wlan_hdd_wext.c @@ -109,12 +109,12 @@ #include "wlan_hdd_ocb.h" #include "wlan_hdd_tsf.h" +#include "vos_nvitem.h" #define HDD_FINISH_ULA_TIME_OUT 800 #define HDD_SET_MCBC_FILTERS_TO_FW 1 #define HDD_DELETE_MCBC_FILTERS_FROM_FW 0 -extern int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand); static int ioctl_debug; module_param(ioctl_debug, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); @@ -10965,7 +10965,7 @@ int hdd_setBand(struct net_device *dev, u8 ui_band) FL("Failed to set the band value to %u"), band); return -EINVAL; } - wlan_hdd_cfg80211_update_band(pHddCtx->wiphy, (eCsrBand)band); + vos_update_band((eCsrBand)band); } EXIT(); return 0; diff --git a/CORE/VOSS/inc/vos_nvitem.h b/CORE/VOSS/inc/vos_nvitem.h index ef3efc7fb02f..96ddcca934cc 100644 --- a/CORE/VOSS/inc/vos_nvitem.h +++ b/CORE/VOSS/inc/vos_nvitem.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -266,4 +266,6 @@ VOS_STATUS vos_init_wiphy_from_nv_bin(void); const char * voss_DomainIdtoString(const v_U8_t domainIdCurrent); VOS_STATUS vos_init_wiphy_from_eeprom(void); bool vos_is_dsrc_channel(uint16_t); +uint32_t vos_nv_get_channel_flags(uint32_t rf_channel); +int vos_update_band(uint8_t band); #endif // __VOS_NVITEM_H diff --git a/CORE/VOSS/src/vos_nvitem.c b/CORE/VOSS/src/vos_nvitem.c index 42a5434df4c2..2f98fcef663a 100644 --- a/CORE/VOSS/src/vos_nvitem.c +++ b/CORE/VOSS/src/vos_nvitem.c @@ -977,6 +977,37 @@ eNVChannelEnabledType vos_nv_getChannelEnabledState return regChannels[channelEnum].enabled; } +/** + * vos_nv_get_channel_flags: Get channel flags + * @rf_channel: Channel number. + * This function is called to know associated flags with channel + * + * Return: updated Wiphy struct + */ +uint32_t vos_nv_get_channel_flags +( + uint32_t rf_channel +) +{ + uint32_t channel_loop; + eRfChannels channel_enum = INVALID_RF_CHANNEL; + + for(channel_loop = 0; channel_loop <= RF_CHAN_184; channel_loop++) { + if(rfChannels[channel_loop].channelNum == rf_channel) { + channel_enum = (eRfChannels)channel_loop; + break; + } + } + + if (INVALID_RF_CHANNEL == channel_enum) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "vos_nv_get_channel_flags, invalid channel %d", + rf_channel); + return NV_CHANNEL_INVALID; + } + return regChannels[channel_enum].flags; +} + /****************************************************************** Add CRDA regulatory support *******************************************************************/ @@ -1246,7 +1277,93 @@ bool vos_is_dsrc_channel(uint16_t center_freq) } return 0; } +/** + * vos_update_band: Update the band + * @eBand: Band value + * + * This function is called from the supplicant through a + * private ioctl to change the band value. + * + * Return: updated Wiphy struct + */ +int vos_update_band(v_U8_t band_capability) +{ + v_CONTEXT_t vos_ctx = NULL; + hdd_context_t *hdd_ctx = NULL; + struct wiphy *wiphy = NULL; + int i, j; + eNVChannelEnabledType channel_enabled_state; + uint32_t flags; + ENTER(); + vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if (NULL != vos_ctx) + hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx); + else + return VOS_STATUS_E_EXISTS; + if (NULL == hdd_ctx) { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Invalid hdd_ctx pointer") ); + return VOS_STATUS_E_FAULT; + } + + if (hdd_ctx->isLogpInProgress) { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + (" SSR in progress, return") ); + return VOS_STATUS_SUCCESS; + } + + wiphy = hdd_ctx->wiphy; + + if (false == wiphy->registered) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("wiphy is not yet registered with the kernel")); + return VOS_STATUS_E_FAULT; + } + + for (i = 0; i < IEEE80211_NUM_BANDS; i++) { + if (NULL == wiphy->bands[i]) + continue; + + for (j = 0; j < wiphy->bands[i]->n_channels; j++) { + struct ieee80211_supported_band *band = wiphy->bands[i]; + + flags = vos_nv_get_channel_flags( + band->channels[j].hw_value); + channel_enabled_state = + vos_nv_getChannelEnabledState( + band->channels[j].hw_value); + /* 5G only */ + if (IEEE80211_BAND_2GHZ == i && + eCSR_BAND_5G == band_capability) { +#ifdef WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY + /* Enable Social channels for P2P */ + if (WLAN_HDD_IS_SOCIAL_CHANNEL( + band->channels[j].center_freq) && + NV_CHANNEL_ENABLE == + channel_enabled_state) + band->channels[j].flags &= + ~IEEE80211_CHAN_DISABLED; + else +#endif + band->channels[j].flags |= + IEEE80211_CHAN_DISABLED; + continue; + } else if (IEEE80211_BAND_5GHZ == i && + eCSR_BAND_24 == band_capability) { + /* 2.4G only */ + band->channels[j].flags |= + IEEE80211_CHAN_DISABLED; + continue; + } + if (NV_CHANNEL_DISABLE != channel_enabled_state) + band->channels[j].flags = flags; + + } + } + return 0; +} /* create_linux_regulatory_entry to populate internal structures from wiphy */ static int create_linux_regulatory_entry(struct wiphy *wiphy, @@ -1291,14 +1408,6 @@ static int create_linux_regulatory_entry(struct wiphy *wiphy, for (i = 0, m = 0; i<IEEE80211_NUM_BANDS; i++) { - /* 5G only */ - if (i == IEEE80211_BAND_2GHZ && nBandCapability == eCSR_BAND_5G) - continue; - - /* 2G only */ - else if (i == IEEE80211_BAND_5GHZ && nBandCapability == eCSR_BAND_24) - continue; - if (wiphy->bands[i] == NULL) continue; @@ -1554,9 +1663,12 @@ static int create_linux_regulatory_entry(struct wiphy *wiphy, } } - - /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain - is real gain which should be provided by the real design */ + /* Copy wiphy flags in nv table */ + if (n != -1) + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain]. + channels[n].flags = wiphy->bands[i]->channels[j].flags; + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain]. + channels[k].flags = wiphy->bands[i]->channels[j].flags; } } @@ -1572,6 +1684,7 @@ static int create_linux_regulatory_entry(struct wiphy *wiphy, if (k == 0) return -1; + vos_update_band(nBandCapability); return 0; } @@ -1754,7 +1867,8 @@ int __wlan_hdd_linux_reg_notifier(struct wiphy *wiphy, temp_reg_domain = REGDOMAIN_WORLD; isVHT80Allowed = pHddCtx->isVHT80Allowed; - + regChannels = + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels; if (create_linux_regulatory_entry(wiphy, nBandCapability, reset) == 0) diff --git a/wcnss/inc/wlan_nv.h b/wcnss/inc/wlan_nv.h index c274858771bc..7c8e172c0ea8 100644 --- a/wcnss/inc/wlan_nv.h +++ b/wcnss/inc/wlan_nv.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014 The Linux Foundation. All rights reserved. + * Copyright (c) 2012, 2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -406,8 +406,9 @@ typedef uint8 eNVChannelEnabledType; typedef PACKED_PRE struct PACKED_POST { - eNVChannelEnabledType enabled; - tPowerdBm pwrLimit; + uint32_t enabled:4; + uint32_t flags:28; + tPowerdBm pwrLimit; }sRegulatoryChannel; typedef PACKED_PRE struct PACKED_POST |
