qcacld-2.0: Validate avoid frequency channel list
Validate the avoid frequency channel list of
QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY command and update the
driver's unsafe channel list with the channels received in the command.
Change-Id: I1a10e668bf6fe6dbb22f7f2f8aef929fc6e7fc65
CRs-Fixed: 1100216
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 73dbedf..f805735 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -13049,6 +13049,53 @@
}
#ifdef FEATURE_WLAN_CH_AVOID
+
+static int hdd_validate_avoid_freq_chanlist(hdd_context_t *hdd_ctx,
+ tHddAvoidFreqList *channel_list)
+{
+ unsigned int range_idx, ch_idx;
+ unsigned int unsafe_channel_index, unsafe_channel_count = 0;
+ bool ch_found = false;
+
+ unsafe_channel_count = VOS_MIN((uint16_t)hdd_ctx->unsafe_channel_count,
+ (uint16_t)NUM_20MHZ_RF_CHANNELS);
+
+ for (range_idx = 0; range_idx < channel_list->avoidFreqRangeCount;
+ range_idx++) {
+ if ((channel_list->avoidFreqRange[range_idx].startFreq <
+ VOS_24_GHZ_CHANNEL_1) ||
+ (channel_list->avoidFreqRange[range_idx].endFreq >
+ VOS_5_GHZ_CHANNEL_165) ||
+ (channel_list->avoidFreqRange[range_idx].startFreq >
+ channel_list->avoidFreqRange[range_idx].endFreq))
+ continue;
+
+ for (ch_idx = channel_list->avoidFreqRange[range_idx].startFreq;
+ ch_idx <= channel_list->avoidFreqRange[range_idx].endFreq;
+ ch_idx++) {
+ for (unsafe_channel_index = 0;
+ unsafe_channel_index < unsafe_channel_count;
+ unsafe_channel_index++) {
+ if (ch_idx ==
+ hdd_ctx->unsafe_channel_list[
+ unsafe_channel_index]) {
+ hddLog(VOS_TRACE_LEVEL_INFO,
+ FL("Duplicate channel %d"),
+ ch_idx);
+ ch_found = true;
+ break;
+ }
+ }
+ if (!ch_found) {
+ hdd_ctx->unsafe_channel_list[
+ unsafe_channel_count++] = ch_idx;
+ }
+ ch_found = false;
+ }
+ }
+ return unsafe_channel_count;
+}
+
/**
* __wlan_hdd_cfg80211_avoid_freq() - ask driver to restart SAP if SAP
* is on unsafe channel.
@@ -13071,28 +13118,43 @@
{
hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
int ret;
- uint16_t unsafe_channel_count;
int unsafe_channel_index;
+ tHddAvoidFreqList *channel_list;
+ tVOS_CON_MODE curr_mode;
ENTER();
- if (VOS_FTM_MODE == hdd_get_conparam()) {
- hddLog(LOGE, FL("Command not allowed in FTM mode"));
+ curr_mode = hdd_get_conparam();
+ if (VOS_FTM_MODE == curr_mode ||
+ VOS_MONITOR_MODE == curr_mode) {
+ hddLog(LOGE, FL("Command not allowed in FTM/MONITOR mode"));
return -EINVAL;
}
ret = wlan_hdd_validate_context(hdd_ctx);
if (0 != ret)
return -EINVAL;
+
+ channel_list = (tHddAvoidFreqList *)data;
+ if (!channel_list) {
+ hddLog(LOGE, FL("Avoid frequency channel list empty"));
+ return -EINVAL;
+ }
+
vos_get_wlan_unsafe_channel(hdd_ctx->unsafe_channel_list,
&(hdd_ctx->unsafe_channel_count),
sizeof(hdd_ctx->unsafe_channel_list));
- unsafe_channel_count = VOS_MIN((uint16_t)hdd_ctx->unsafe_channel_count,
- (uint16_t)NUM_20MHZ_RF_CHANNELS);
+ hdd_ctx->unsafe_channel_count =
+ hdd_validate_avoid_freq_chanlist(hdd_ctx,
+ channel_list);
+
+ vos_set_wlan_unsafe_channel(hdd_ctx->unsafe_channel_list,
+ hdd_ctx->unsafe_channel_count);
+
for (unsafe_channel_index = 0;
- unsafe_channel_index < unsafe_channel_count;
- unsafe_channel_index++) {
+ unsafe_channel_index < hdd_ctx->unsafe_channel_count;
+ unsafe_channel_index++) {
hddLog(LOGE, FL("Channel %d is not safe. "),
hdd_ctx->unsafe_channel_list[unsafe_channel_index]);
}
diff --git a/CORE/VOSS/inc/vos_utils.h b/CORE/VOSS/inc/vos_utils.h
index e4af65b..f86e796 100644
--- a/CORE/VOSS/inc/vos_utils.h
+++ b/CORE/VOSS/inc/vos_utils.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2012, 2014-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2012, 2014-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -61,9 +61,11 @@
#define VOS_24_GHZ_BASE_FREQ 2407
#define VOS_5_GHZ_BASE_FREQ 5000
+#define VOS_24_GHZ_CHANNEL_1 1
#define VOS_24_GHZ_CHANNEL_14 14
#define VOS_24_GHZ_CHANNEL_15 15
#define VOS_24_GHZ_CHANNEL_27 27
+#define VOS_5_GHZ_CHANNEL_165 165
#define VOS_5_GHZ_CHANNEL_170 170
#define VOS_CHAN_SPACING_5MHZ 5
#define VOS_CHAN_SPACING_20MHZ 20