summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/cds/inc/cds_reg_service.h15
-rw-r--r--core/cds/src/cds_reg_service.c10
-rw-r--r--core/hdd/inc/wlan_hdd_main.h37
-rw-r--r--core/hdd/src/wlan_hdd_cfg80211.h10
-rw-r--r--core/hdd/src/wlan_hdd_hostapd.c184
-rw-r--r--core/hdd/src/wlan_hdd_ioctl.c244
-rw-r--r--core/hdd/src/wlan_hdd_main.c7
-rw-r--r--core/hdd/src/wlan_hdd_softap_tx_rx.c2
-rw-r--r--core/hdd/src/wlan_hdd_wext.c6
9 files changed, 509 insertions, 6 deletions
diff --git a/core/cds/inc/cds_reg_service.h b/core/cds/inc/cds_reg_service.h
index fb84151b01df..b64d9d6763c4 100644
--- a/core/cds/inc/cds_reg_service.h
+++ b/core/cds/inc/cds_reg_service.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -385,6 +385,19 @@ QDF_STATUS cds_get_channel_list_with_power(struct channel_power
*base_channels,
uint8_t *num_base_channels);
+/**
+ * cds_set_channel_state() - API to set the channel state in reg table
+ * @chan_num - input channel enum
+ * @state - state of the channel to be set
+ * CHANNEL_STATE_DISABLE
+ * CHANNEL_STATE_DFS
+ * CHANNEL_STATE_ENABLE
+ * CHANNEL_STATE_INVALID
+ *
+ * Return: Void
+ */
+void cds_set_channel_state(uint32_t chan_num, enum channel_state state);
+
enum channel_state cds_get_channel_state(uint32_t chan_num);
QDF_STATUS cds_get_dfs_region(enum dfs_region *dfs_reg);
QDF_STATUS cds_put_dfs_region(enum dfs_region dfs_reg);
diff --git a/core/cds/src/cds_reg_service.c b/core/cds/src/cds_reg_service.c
index 4ebfe3cedafa..5e8cc979950d 100644
--- a/core/cds/src/cds_reg_service.c
+++ b/core/cds/src/cds_reg_service.c
@@ -224,6 +224,16 @@ enum channel_enum cds_get_channel_enum(uint32_t chan_num)
return INVALID_CHANNEL;
}
+void cds_set_channel_state(uint32_t chan_num, enum channel_state state)
+{
+ enum channel_enum chan_enum;
+
+ chan_enum = cds_get_channel_enum(chan_num);
+ if (INVALID_CHANNEL == chan_enum)
+ return;
+
+ reg_channels[chan_enum].state = state;
+}
/**
* cds_get_channel_state() - get the channel state
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index 82081c84c900..6cf2fe2c27ea 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -1883,6 +1883,33 @@ enum hdd_sta_smps_param {
};
/**
+ * struct hdd_cache_channel_info - Structure of the channel info
+ * which needs to be cached
+ * @channel_num: channel number
+ * @reg_status: Current regulatory status of the channel
+ * Enable
+ * Disable
+ * DFS
+ * Invalid
+ * @wiphy_status: Current wiphy status
+ */
+struct hdd_cache_channel_info {
+ uint32_t channel_num;
+ enum channel_state reg_status;
+ uint32_t wiphy_status;
+};
+
+/**
+ * struct hdd_cache_channels - Structure of the channels to be cached
+ * @num_channels: Number of channels to be cached
+ * @channel_info: Structure of the channel info
+ */
+struct hdd_cache_channels {
+ uint32_t num_channels;
+ struct hdd_cache_channel_info *channel_info;
+};
+
+/**
* struct hdd_context_s
* @adapter_nodes: an array of adapter nodes for keeping track of hdd adapters
*/
@@ -2204,6 +2231,8 @@ struct hdd_context_s {
/* mutex lock to block concurrent access */
struct mutex power_stats_lock;
#endif
+ struct hdd_cache_channels *original_channels;
+ qdf_mutex_t cache_channel_lock;
};
int hdd_validate_channel_and_bandwidth(hdd_adapter_t *adapter,
@@ -3088,4 +3117,12 @@ void hdd_driver_memdump_deinit(void);
*/
bool hdd_is_cli_iface_up(hdd_context_t *hdd_ctx);
+/**
+ * wlan_hdd_free_cache_channels() - Free the cache channels list
+ * @hdd_ctx: Pointer to HDD context
+ *
+ * Return: None
+ */
+void wlan_hdd_free_cache_channels(hdd_context_t *hdd_ctx);
+
#endif /* end #if !defined(WLAN_HDD_MAIN_H) */
diff --git a/core/hdd/src/wlan_hdd_cfg80211.h b/core/hdd/src/wlan_hdd_cfg80211.h
index a07b47866c13..c4078264cde9 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.h
+++ b/core/hdd/src/wlan_hdd_cfg80211.h
@@ -706,4 +706,14 @@ QDF_STATUS wlan_hdd_send_sta_authorized_event(
hdd_adapter_t *pAdapter,
hdd_context_t *pHddCtx,
const struct qdf_mac_addr *mac_addr);
+
+/**
+ * wlan_hdd_restore_channels() - Restore the channels which were cached
+ * and disabled in wlan_hdd_disable_channels api.
+ * @hdd_ctx: Pointer to the HDD context
+ *
+ * Return: 0 on success, Error code on failure
+ */
+int wlan_hdd_restore_channels(hdd_context_t *hdd_ctx);
+
#endif
diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c
index 5b9c00d6a54b..d3f32319367d 100644
--- a/core/hdd/src/wlan_hdd_hostapd.c
+++ b/core/hdd/src/wlan_hdd_hostapd.c
@@ -5278,7 +5278,7 @@ static int __iw_get_ap_freq(struct net_device *dev,
return -EIO;
}
status = hdd_wlan_get_freq(channel, &freq);
- if (true == status) {
+ if (0 == status) {
/* Set Exponent parameter as 6 (MHZ) in struct
* iw_freq * iwlist & iwconfig command
* shows frequency into proper
@@ -5290,7 +5290,7 @@ static int __iw_get_ap_freq(struct net_device *dev,
} else {
channel = pHddApCtx->operatingChannel;
status = hdd_wlan_get_freq(channel, &freq);
- if (true == status) {
+ if (0 == status) {
/* Set Exponent parameter as 6 (MHZ) in struct iw_freq
* iwlist & iwconfig command shows frequency into proper
* format (2.412 GHz instead of 246.2 MHz)
@@ -7906,6 +7906,173 @@ static void hdd_check_and_disconnect_sta_on_invalid_channel(
}
/**
+ * wlan_hdd_get_wiphy_channel() - Get wiphy channel
+ * @wiphy: Pointer to wiphy structure
+ * @freq: Frequency of the channel for which the wiphy hw value is required
+ *
+ * Return: wiphy channel for valid frequency else return NULL
+ */
+static struct ieee80211_channel *wlan_hdd_get_wiphy_channel(
+ struct wiphy *wiphy,
+ uint32_t freq)
+{
+ uint32_t band_num, channel_num;
+ struct ieee80211_channel *wiphy_channel = NULL;
+
+ for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
+ for (channel_num = 0; channel_num <
+ wiphy->bands[band_num]->n_channels;
+ channel_num++) {
+ wiphy_channel = &(wiphy->bands[band_num]->
+ channels[channel_num]);
+ if (wiphy_channel->center_freq == freq)
+ return wiphy_channel;
+ }
+ }
+ return wiphy_channel;
+}
+
+int wlan_hdd_restore_channels(hdd_context_t *hdd_ctx)
+{
+ struct hdd_cache_channels *cache_chann;
+ struct wiphy *wiphy;
+ int freq, status, rf_channel;
+ int i;
+ struct ieee80211_channel *wiphy_channel = NULL;
+
+ ENTER();
+
+ if (!hdd_ctx) {
+ hdd_err("HDD Context is NULL");
+ return -EINVAL;
+ }
+
+ wiphy = hdd_ctx->wiphy;
+ if (!wiphy) {
+ hdd_err("Wiphy is NULL");
+ return -EINVAL;
+ }
+
+ qdf_mutex_acquire(&hdd_ctx->cache_channel_lock);
+
+ cache_chann = hdd_ctx->original_channels;
+
+ if (!cache_chann || !cache_chann->num_channels) {
+ qdf_mutex_release(&hdd_ctx->cache_channel_lock);
+ hdd_err("channel list is NULL or num channels are zero");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < cache_chann->num_channels; i++) {
+ status = hdd_wlan_get_freq(
+ cache_chann->channel_info[i].channel_num,
+ &freq);
+ if (status)
+ continue;
+
+ wiphy_channel = wlan_hdd_get_wiphy_channel(wiphy, freq);
+ if (!wiphy_channel)
+ continue;
+ rf_channel = wiphy_channel->hw_value;
+ /*
+ * Restore the orginal states of the channels
+ * only if we have cached non zero values
+ */
+ if (cache_chann->channel_info[i].reg_status)
+ cds_set_channel_state(rf_channel,
+ cache_chann->
+ channel_info[i].reg_status);
+
+ if (cache_chann->channel_info[i].wiphy_status && wiphy_channel)
+ wiphy_channel->flags =
+ cache_chann->channel_info[i].wiphy_status;
+ }
+
+ qdf_mutex_release(&hdd_ctx->cache_channel_lock);
+
+ status = sme_update_channel_list(hdd_ctx->hHal);
+ if (status)
+ hdd_err("Can't Restore channel list");
+ EXIT();
+
+ return 0;
+}
+
+/**
+ * wlan_hdd_disable_channels() - Cache the channels
+ * and current state of the channels from the channel list
+ * received in the command and disable the channels on the
+ * wiphy and reg table.
+ * @hdd_ctx: Pointer to hdd context
+ *
+ * Return: 0 on success, Error code on failure
+ */
+static int wlan_hdd_disable_channels(hdd_context_t *hdd_ctx)
+{
+ struct hdd_cache_channels *cache_chann;
+ struct wiphy *wiphy;
+ int freq, status, rf_channel;
+ int i;
+ struct ieee80211_channel *wiphy_channel = NULL;
+
+ ENTER();
+
+ if (!hdd_ctx) {
+ hdd_err("HDD Context is NULL");
+ return -EINVAL;
+ }
+
+ wiphy = hdd_ctx->wiphy;
+ if (!wiphy) {
+ hdd_err("Wiphy is NULL");
+ return -EINVAL;
+ }
+
+ qdf_mutex_acquire(&hdd_ctx->cache_channel_lock);
+ cache_chann = hdd_ctx->original_channels;
+
+ if (!cache_chann || !cache_chann->num_channels) {
+ qdf_mutex_release(&hdd_ctx->cache_channel_lock);
+ hdd_err("channel list is NULL or num channels are zero");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < cache_chann->num_channels; i++) {
+ status = hdd_wlan_get_freq(
+ cache_chann->channel_info[i].channel_num,
+ &freq);
+ if (status)
+ continue;
+ wiphy_channel = wlan_hdd_get_wiphy_channel(wiphy, freq);
+ if (!wiphy_channel)
+ continue;
+ rf_channel = wiphy_channel->hw_value;
+ /*
+ * Cache the current states of
+ * the channels
+ */
+ cache_chann->channel_info[i].reg_status =
+ cds_get_channel_state(
+ rf_channel);
+ cache_chann->channel_info[i].wiphy_status =
+ wiphy_channel->flags;
+ hdd_debug("Disable channel %d reg_stat %d wiphy_stat 0x%x",
+ cache_chann->channel_info[i].channel_num,
+ cache_chann->channel_info[i].reg_status,
+ wiphy_channel->flags);
+
+ cds_set_channel_state(rf_channel, CHANNEL_STATE_DISABLE);
+ wiphy_channel->flags |= IEEE80211_CHAN_DISABLED;
+ }
+
+ qdf_mutex_release(&hdd_ctx->cache_channel_lock);
+ status = sme_update_channel_list(hdd_ctx->hHal);
+
+ EXIT();
+ return status;
+}
+
+/**
* wlan_hdd_cfg80211_start_bss() - start bss
* @pHostapdAdapter: Pointer to hostapd adapter
* @params: Pointer to start bss beacon parameters
@@ -8017,6 +8184,17 @@ int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
pHddCtx);
}
+ if (pHostapdAdapter->device_mode == QDF_SAP_MODE) {
+ /*
+ * Disable the channels received in command
+ * SET_DISABLE_CHANNEL_LIST
+ */
+ status = wlan_hdd_disable_channels(pHddCtx);
+ if (!QDF_IS_STATUS_SUCCESS(status))
+ hdd_err("Disable channel list fail");
+ hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
+ }
+
pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
@@ -8623,6 +8801,8 @@ int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
return 0;
error:
+ if (pHostapdAdapter->device_mode == QDF_SAP_MODE)
+ wlan_hdd_restore_channels(pHddCtx);
/* Revert the indoor to passive marking if START BSS fails */
if (iniConfig->disable_indoor_channel) {
hdd_update_indoor_channel(pHddCtx, false);
diff --git a/core/hdd/src/wlan_hdd_ioctl.c b/core/hdd/src/wlan_hdd_ioctl.c
index daf7cd8f4fe5..42f96973ff0f 100644
--- a/core/hdd/src/wlan_hdd_ioctl.c
+++ b/core/hdd/src/wlan_hdd_ioctl.c
@@ -6858,6 +6858,249 @@ static int drv_cmd_set_channel_switch(hdd_adapter_t *adapter,
return 0;
}
+void wlan_hdd_free_cache_channels(hdd_context_t *hdd_ctx)
+{
+ ENTER();
+
+ if (!hdd_ctx->original_channels)
+ return;
+
+ qdf_mutex_acquire(&hdd_ctx->cache_channel_lock);
+ hdd_ctx->original_channels->num_channels = 0;
+ qdf_mem_free(hdd_ctx->original_channels->channel_info);
+ hdd_ctx->original_channels->channel_info = NULL;
+ qdf_mem_free(hdd_ctx->original_channels);
+ hdd_ctx->original_channels = NULL;
+ qdf_mutex_release(&hdd_ctx->cache_channel_lock);
+
+ EXIT();
+}
+
+/**
+ * hdd_alloc_chan_cache() - Allocate the memory to cache the channel
+ * info for the channels received in command SET_DISABLE_CHANNEL_LIST
+ * @hdd_ctx: Pointer to HDD context
+ * @num_chan: Number of channels for which memory needs to
+ * be allocated
+ *
+ * Return: 0 on success and error code on failure
+ */
+static int hdd_alloc_chan_cache(hdd_context_t *hdd_ctx, int num_chan)
+{
+ hdd_ctx->original_channels =
+ qdf_mem_malloc(sizeof(struct hdd_cache_channels));
+ if (!hdd_ctx->original_channels) {
+ hdd_err("QDF_MALLOC_ERR");
+ return -ENOMEM;
+ }
+ hdd_ctx->original_channels->num_channels = num_chan;
+ hdd_ctx->original_channels->channel_info =
+ qdf_mem_malloc(num_chan *
+ sizeof(struct hdd_cache_channel_info));
+ if (!hdd_ctx->original_channels->channel_info) {
+ hdd_err("QDF_MALLOC_ERR");
+ hdd_ctx->original_channels->num_channels = 0;
+ qdf_mem_free(hdd_ctx->original_channels);
+ hdd_ctx->original_channels = NULL;
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+/**
+ * hdd_parse_disable_chan_cmd() - Parse the channel list received
+ * in command.
+ * @adapter: pointer to hdd adapter
+ * @ptr: Pointer to the command string
+ *
+ * This function parses the channel list received in the command.
+ * command should be a string having format
+ * SET_DISABLE_CHANNEL_LIST <num of channels>
+ * <channels separated by spaces>.
+ * If the command comes multiple times than this function will compare
+ * the channels received in the command with the channles cached in the
+ * first command, if the channel list matches with the cached channles,
+ * it returns success otherwise returns failure.
+ *
+ * Return: 0 on success, Error code on failure
+ */
+
+static int hdd_parse_disable_chan_cmd(hdd_adapter_t *adapter, uint8_t *ptr)
+{
+ hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+ uint8_t *param;
+ int j, i, temp_int, ret = 0, num_channels;
+ int parsed_channels[MAX_CHANNEL];
+ bool is_command_repeated = false;
+
+ if (NULL == hdd_ctx) {
+ hdd_err("HDD Context is NULL");
+ return -EINVAL;
+ }
+
+ param = strnchr(ptr, strlen(ptr), ' ');
+ /*no argument after the command*/
+ if (NULL == param)
+ return -EINVAL;
+
+ /*no space after the command*/
+ else if (SPACE_ASCII_VALUE != *param)
+ return -EINVAL;
+
+ param++;
+
+ /*removing empty spaces*/
+ while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
+ param++;
+
+ /*no argument followed by spaces*/
+ if ('\0' == *param)
+ return -EINVAL;
+
+ /*getting the first argument ie the number of channels*/
+ if (sscanf(param, "%d ", &temp_int) != 1) {
+ hdd_err("Cannot get number of channels from input");
+ return -EINVAL;
+ }
+
+ if (temp_int < 0 || temp_int > MAX_CHANNEL) {
+ hdd_err("Invalid Number of channel received");
+ return -EINVAL;
+ }
+
+ hdd_debug("Number of channel to disable are: %d", temp_int);
+
+ if (!temp_int) {
+ if (!wlan_hdd_restore_channels(hdd_ctx)) {
+ /*
+ * Free the cache channels only when the command is
+ * received with num channels as 0
+ */
+ wlan_hdd_free_cache_channels(hdd_ctx);
+ }
+ return 0;
+ }
+
+ qdf_mutex_acquire(&hdd_ctx->cache_channel_lock);
+
+ if (!hdd_ctx->original_channels) {
+ if (hdd_alloc_chan_cache(hdd_ctx, temp_int)) {
+ ret = -ENOMEM;
+ goto mem_alloc_failed;
+ }
+ } else if (hdd_ctx->original_channels->num_channels != temp_int) {
+ hdd_err("Invalid Number of channels");
+ ret = -EINVAL;
+ is_command_repeated = true;
+ goto parse_failed;
+ } else {
+ is_command_repeated = true;
+ }
+ num_channels = temp_int;
+ for (j = 0; j < num_channels; j++) {
+ /*
+ * param pointing to the beginning of first space
+ * after number of channels
+ */
+ param = strpbrk(param, " ");
+ /*no channel list after the number of channels argument*/
+ if (NULL == param) {
+ hdd_err("Invalid No of channel provided in the list");
+ ret = -EINVAL;
+ goto parse_failed;
+ }
+
+ param++;
+
+ /*removing empty space*/
+ while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
+ param++;
+
+ if ('\0' == *param) {
+ hdd_err("No channel is provided in the list");
+ ret = -EINVAL;
+ goto parse_failed;
+ }
+
+ if (sscanf(param, "%d ", &temp_int) != 1) {
+ hdd_err("Cannot read channel number");
+ ret = -EINVAL;
+ goto parse_failed;
+ }
+
+ if (!IS_CHANNEL_VALID(temp_int)) {
+ hdd_err("Invalid channel number received");
+ ret = -EINVAL;
+ goto parse_failed;
+ }
+
+ hdd_debug("channel[%d] = %d", j, temp_int);
+ parsed_channels[j] = temp_int;
+ }
+
+ /*extra arguments check*/
+ param = strpbrk(param, " ");
+ if (NULL != param) {
+ while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
+ param++;
+
+ if ('\0' != *param) {
+ hdd_err("Invalid argument received");
+ ret = -EINVAL;
+ goto parse_failed;
+ }
+ }
+
+ /*
+ * If command is received first time, cache the channels to
+ * be disabled else compare the channels received in the
+ * command with the cached channels, if channel list matches
+ * return success otherewise return failure.
+ */
+ if (!is_command_repeated)
+ for (j = 0; j < num_channels; j++)
+ hdd_ctx->original_channels->
+ channel_info[j].channel_num =
+ parsed_channels[j];
+ else {
+ for (i = 0; i < num_channels; i++) {
+ for (j = 0; j < num_channels; j++)
+ if (hdd_ctx->original_channels->
+ channel_info[i].channel_num ==
+ parsed_channels[j])
+ break;
+ if (j == num_channels) {
+ ret = -EINVAL;
+ goto parse_failed;
+ }
+ }
+ ret = 0;
+ }
+mem_alloc_failed:
+
+ qdf_mutex_release(&hdd_ctx->cache_channel_lock);
+ EXIT();
+
+ return ret;
+
+parse_failed:
+ qdf_mutex_release(&hdd_ctx->cache_channel_lock);
+ if (!is_command_repeated)
+ wlan_hdd_free_cache_channels(hdd_ctx);
+ EXIT();
+
+ return ret;
+}
+
+static int drv_cmd_set_disable_chan_list(hdd_adapter_t *adapter,
+ hdd_context_t *hdd_ctx,
+ uint8_t *command,
+ uint8_t command_len,
+ hdd_priv_data_t *priv_data)
+{
+ return hdd_parse_disable_chan_cmd(adapter, command);
+}
+
/*
* The following table contains all supported WLAN HDD
* IOCTL driver commands and the handler for each of them.
@@ -6968,6 +7211,7 @@ static const struct hdd_drv_cmd hdd_drv_cmds[] = {
{"CHANNEL_SWITCH", drv_cmd_set_channel_switch, true},
{"SETANTENNAMODE", drv_cmd_set_antenna_mode, true},
{"GETANTENNAMODE", drv_cmd_get_antenna_mode, false},
+ {"SET_DISABLE_CHANNEL_LIST", drv_cmd_set_disable_chan_list, true},
{"STOP", drv_cmd_dummy, false},
};
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index dcf5c42dd48a..bcb928b57869 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -6417,6 +6417,7 @@ static void hdd_wlan_exit(hdd_context_t *hdd_ctx)
qdf_spinlock_destroy(&hdd_ctx->hdd_adapter_lock);
qdf_spinlock_destroy(&hdd_ctx->sta_update_info_lock);
qdf_spinlock_destroy(&hdd_ctx->connection_status_lock);
+ qdf_mutex_destroy(&hdd_ctx->cache_channel_lock);
/*
* Close CDS
@@ -10545,6 +10546,8 @@ int hdd_wlan_stop_modules(hdd_context_t *hdd_ctx, bool ftm_mode)
hdd_err("CNSS power down failed put device into Low power mode:%d",
ret);
}
+ /* Free the cache channels of the command SET_DISABLE_CHANNEL_LIST */
+ wlan_hdd_free_cache_channels(hdd_ctx);
/* many adapter resources are not freed by design in SSR case */
if (!is_recover_stop)
@@ -10740,6 +10743,10 @@ int hdd_wlan_startup(struct device *dev)
if (ret)
goto err_hdd_free_context;
+ ret = qdf_mutex_create(&hdd_ctx->cache_channel_lock);
+ if (QDF_IS_STATUS_ERROR(ret))
+ goto err_hdd_free_context;
+
hdd_request_manager_init();
hdd_green_ap_init(hdd_ctx);
diff --git a/core/hdd/src/wlan_hdd_softap_tx_rx.c b/core/hdd/src/wlan_hdd_softap_tx_rx.c
index 390dc97aac93..44d19d64622a 100644
--- a/core/hdd/src/wlan_hdd_softap_tx_rx.c
+++ b/core/hdd/src/wlan_hdd_softap_tx_rx.c
@@ -1015,6 +1015,8 @@ QDF_STATUS hdd_softap_stop_bss(hdd_adapter_t *pAdapter)
}
}
}
+ if (pAdapter->device_mode == QDF_SAP_MODE)
+ wlan_hdd_restore_channels(pHddCtx);
/* Mark the indoor channel (passive) to enable */
if (pHddCtx->config->disable_indoor_channel) {
diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c
index 8eebb5402f8c..352cec67d35e 100644
--- a/core/hdd/src/wlan_hdd_wext.c
+++ b/core/hdd/src/wlan_hdd_wext.c
@@ -3367,7 +3367,7 @@ int hdd_wlan_get_frag_threshold(hdd_adapter_t *pAdapter,
* @channel: channel to be converted
* @pfreq: where to store the frequency
*
- * Return: 1 on success, otherwise a negative errno
+ * Return: 0 on success, otherwise a negative errno
*/
int hdd_wlan_get_freq(uint32_t channel, uint32_t *pfreq)
{
@@ -3377,7 +3377,7 @@ int hdd_wlan_get_freq(uint32_t channel, uint32_t *pfreq)
for (i = 0; i < FREQ_CHAN_MAP_TABLE_SIZE; i++) {
if (channel == freq_chan_map[i].chan) {
*pfreq = freq_chan_map[i].freq;
- return 1;
+ return 0;
}
}
}
@@ -4865,7 +4865,7 @@ static int __iw_get_freq(struct net_device *dev, struct iw_request_info *info,
return -EIO;
}
status = hdd_wlan_get_freq(channel, &freq);
- if (true == status) {
+ if (0 == status) {
/* Set Exponent parameter as 6 (MHZ)
* in struct iw_freq iwlist & iwconfig
* command shows frequency into proper