qcacld-3.0: Validate update avoid frequency channel list

qcacld-2.0 to qcacld-3.0 propagation.

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: 2187477
This commit is contained in:
Ashish Kumar Dhanotiya
2018-02-09 20:08:21 +05:30
committed by snandini
parent d04cc3a105
commit 4be2a7b2a4
2 changed files with 77 additions and 11 deletions

View File

@@ -56,10 +56,12 @@
#define CDS_24_GHZ_BASE_FREQ (2407) #define CDS_24_GHZ_BASE_FREQ (2407)
#define CDS_5_GHZ_BASE_FREQ (5000) #define CDS_5_GHZ_BASE_FREQ (5000)
#define CDS_24_GHZ_CHANNEL_6 (6) #define CDS_24_GHZ_CHANNEL_6 (6)
#define CDS_24_GHZ_CHANNEL_1 (1)
#define CDS_5_GHZ_CHANNEL_36 (36) #define CDS_5_GHZ_CHANNEL_36 (36)
#define CDS_24_GHZ_CHANNEL_14 (14) #define CDS_24_GHZ_CHANNEL_14 (14)
#define CDS_24_GHZ_CHANNEL_15 (15) #define CDS_24_GHZ_CHANNEL_15 (15)
#define CDS_24_GHZ_CHANNEL_27 (27) #define CDS_24_GHZ_CHANNEL_27 (27)
#define CDS_5_GHZ_CHANNEL_165 (165)
#define CDS_5_GHZ_CHANNEL_170 (170) #define CDS_5_GHZ_CHANNEL_170 (170)
#define CDS_CHAN_SPACING_5MHZ (5) #define CDS_CHAN_SPACING_5MHZ (5)
#define CDS_CHAN_SPACING_20MHZ (20) #define CDS_CHAN_SPACING_20MHZ (20)

View File

@@ -10504,6 +10504,56 @@ static int wlan_hdd_cfg80211_sta_roam_policy(struct wiphy *wiphy,
} }
#ifdef FEATURE_WLAN_CH_AVOID #ifdef FEATURE_WLAN_CH_AVOID
static int hdd_validate_avoid_freq_chanlist(
struct hdd_context *hdd_ctx,
struct ch_avoid_ind_type *channel_list)
{
unsigned int range_idx, ch_idx;
unsigned int unsafe_channel_index, unsafe_channel_count = 0;
bool ch_found = false;
unsafe_channel_count = QDF_MIN((uint16_t)hdd_ctx->unsafe_channel_count,
(uint16_t)NUM_CHANNELS);
for (range_idx = 0; range_idx < channel_list->ch_avoid_range_cnt;
range_idx++) {
if ((channel_list->avoid_freq_range[range_idx].start_freq <
CDS_24_GHZ_CHANNEL_1) ||
(channel_list->avoid_freq_range[range_idx].end_freq >
CDS_5_GHZ_CHANNEL_165) ||
(channel_list->avoid_freq_range[range_idx].start_freq >
channel_list->avoid_freq_range[range_idx].end_freq))
continue;
for (ch_idx = channel_list->
avoid_freq_range[range_idx].start_freq;
ch_idx <= channel_list->
avoid_freq_range[range_idx].end_freq;
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]) {
hdd_log(QDF_TRACE_LEVEL_INFO,
"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 * __wlan_hdd_cfg80211_avoid_freq() - ask driver to restart SAP if SAP
* is on unsafe channel. * is on unsafe channel.
@@ -10526,11 +10576,11 @@ __wlan_hdd_cfg80211_avoid_freq(struct wiphy *wiphy,
{ {
struct hdd_context *hdd_ctx = wiphy_priv(wiphy); struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
int ret; int ret;
uint16_t unsafe_channel_count;
int unsafe_channel_index;
qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
uint16_t *local_unsafe_list; uint16_t *local_unsafe_list;
uint16_t local_unsafe_list_count; uint16_t unsafe_channel_index, local_unsafe_list_count;
struct ch_avoid_ind_type *channel_list;
enum tQDF_GLOBAL_CON_MODE curr_mode;
ENTER_DEV(wdev->netdev); ENTER_DEV(wdev->netdev);
@@ -10538,15 +10588,24 @@ __wlan_hdd_cfg80211_avoid_freq(struct wiphy *wiphy,
hdd_err("qdf_ctx is NULL"); hdd_err("qdf_ctx is NULL");
return -EINVAL; return -EINVAL;
} }
curr_mode = hdd_get_conparam();
if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { if (QDF_GLOBAL_FTM_MODE == curr_mode ||
hdd_err("Command not allowed in FTM mode"); QDF_GLOBAL_MONITOR_MODE == curr_mode) {
hdd_err("Command not allowed in FTM/MONITOR mode");
return -EINVAL; return -EINVAL;
} }
ret = wlan_hdd_validate_context(hdd_ctx); ret = wlan_hdd_validate_context(hdd_ctx);
if (0 != ret) if (0 != ret)
return ret; return ret;
channel_list = (struct ch_avoid_ind_type *)data;
if (!channel_list) {
hdd_log(QDF_TRACE_LEVEL_ERROR,
"Avoid frequency channel list empty");
return -EINVAL;
}
ret = hdd_clone_local_unsafe_chan(hdd_ctx, ret = hdd_clone_local_unsafe_chan(hdd_ctx,
&local_unsafe_list, &local_unsafe_list,
&local_unsafe_list_count); &local_unsafe_list_count);
@@ -10559,13 +10618,18 @@ __wlan_hdd_cfg80211_avoid_freq(struct wiphy *wiphy,
&(hdd_ctx->unsafe_channel_count), &(hdd_ctx->unsafe_channel_count),
sizeof(hdd_ctx->unsafe_channel_list)); sizeof(hdd_ctx->unsafe_channel_list));
unsafe_channel_count = QDF_MIN((uint16_t)hdd_ctx->unsafe_channel_count, hdd_ctx->unsafe_channel_count = hdd_validate_avoid_freq_chanlist(
(uint16_t)NUM_CHANNELS); hdd_ctx,
channel_list);
pld_set_wlan_unsafe_channel(qdf_ctx->dev, hdd_ctx->unsafe_channel_list,
hdd_ctx->unsafe_channel_count);
for (unsafe_channel_index = 0; for (unsafe_channel_index = 0;
unsafe_channel_index < unsafe_channel_count; unsafe_channel_index < hdd_ctx->unsafe_channel_count;
unsafe_channel_index++) { unsafe_channel_index++) {
hdd_debug("Channel %d is not safe", hdd_debug("Channel %d is not safe",
hdd_ctx->unsafe_channel_list[unsafe_channel_index]); hdd_ctx->unsafe_channel_list[unsafe_channel_index]);
} }
if (hdd_local_unsafe_channel_updated(hdd_ctx, local_unsafe_list, if (hdd_local_unsafe_channel_updated(hdd_ctx, local_unsafe_list,
local_unsafe_list_count)) local_unsafe_list_count))