summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CORE/HDD/inc/wlan_hdd_main.h4
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg80211.c92
-rw-r--r--CORE/HDD/src/wlan_hdd_main.c137
3 files changed, 175 insertions, 58 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index 174873dab76b..03ee1c172bc1 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -2202,5 +2202,9 @@ static inline void hdd_deinit_packet_filtering(hdd_adapter_t *adapter)
}
#endif
enum sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode);
+void hdd_ch_avoid_cb(void *hdd_context, void *indi_param);
+uint8_t hdd_find_prefd_safe_chnl(hdd_context_t *hdd_ctxt,
+ hdd_adapter_t *ap_adapter);
+void hdd_unsafe_channel_restart_sap(hdd_context_t *hdd_ctx);
#endif // end #if !defined( WLAN_HDD_MAIN_H )
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index afaa48d54339..f98305bfe340 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -10777,6 +10777,87 @@ static int wlan_hdd_cfg80211_sta_roam_policy(struct wiphy *wiphy,
return ret;
}
+#ifdef FEATURE_WLAN_CH_AVOID
+/**
+ * __wlan_hdd_cfg80211_avoid_freq() - ask driver to restart SAP if SAP
+ * is on unsafe channel.
+ * @wiphy: wiphy structure pointer
+ * @wdev: Wireless device structure pointer
+ * @data: Pointer to the data received
+ * @data_len: Length of @data
+ *
+ * wlan_hdd_cfg80211_avoid_freq do restart the sap if sap is already
+ * on any of unsafe channels.
+ * If sap is on any of unsafe channel, hdd_unsafe_channel_restart_sap
+ * will send WLAN_SVC_LTE_COEX_IND indication to userspace to restart.
+ *
+ * Return: 0 on success; errno on failure
+ */
+static int
+__wlan_hdd_cfg80211_avoid_freq(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data, int data_len)
+{
+ hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
+ int ret;
+ uint16_t unsafe_channel_count;
+ int unsafe_channel_index;
+
+ ENTER();
+
+ if (VOS_FTM_MODE == hdd_get_conparam()) {
+ hddLog(LOGE, FL("Command not allowed in FTM mode"));
+ return -EINVAL;
+ }
+
+ ret = wlan_hdd_validate_context(hdd_ctx);
+ if (0 != ret)
+ return -EINVAL;
+ cnss_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);
+ for (unsafe_channel_index = 0;
+ unsafe_channel_index < unsafe_channel_count;
+ unsafe_channel_index++) {
+ hddLog(LOGE, FL("Channel %d is not safe. "),
+ hdd_ctx->unsafe_channel_list[unsafe_channel_index]);
+ }
+ hdd_unsafe_channel_restart_sap(hdd_ctx);
+ return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_avoid_freq() - ask driver to restart SAP if SAP
+ * is on unsafe channel.
+ * @wiphy: wiphy structure pointer
+ * @wdev: Wireless device structure pointer
+ * @data: Pointer to the data received
+ * @data_len: Length of @data
+ *
+ * wlan_hdd_cfg80211_avoid_freq do restart the sap if sap is already
+ * on any of unsafe channels.
+ * If sap is on any of unsafe channel, hdd_unsafe_channel_restart_sap
+ * will send WLAN_SVC_LTE_COEX_IND indication to userspace to restart.
+ *
+ * Return: 0 on success; errno on failure
+ */
+static int wlan_hdd_cfg80211_avoid_freq(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data, int data_len)
+{
+ int ret;
+
+ vos_ssr_protect(__func__);
+ ret = __wlan_hdd_cfg80211_avoid_freq(wiphy, wdev, data, data_len);
+ vos_ssr_unprotect(__func__);
+
+ return ret;
+}
+#endif
+
const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
{
{
@@ -11257,7 +11338,6 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
WIPHY_VENDOR_CMD_NEED_RUNNING,
.doit = wlan_hdd_cfg80211_acs_dfs_mode
},
-
{
.info.vendor_id = QCA_NL80211_VENDOR_ID,
.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_STA_CONNECT_ROAM_POLICY,
@@ -11266,6 +11346,16 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
WIPHY_VENDOR_CMD_NEED_RUNNING,
.doit = wlan_hdd_cfg80211_sta_roam_policy
},
+#ifdef FEATURE_WLAN_CH_AVOID
+ {
+ .info.vendor_id = QCA_NL80211_VENDOR_ID,
+ .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY,
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+ WIPHY_VENDOR_CMD_NEED_NETDEV |
+ WIPHY_VENDOR_CMD_NEED_RUNNING,
+ .doit = wlan_hdd_cfg80211_avoid_freq
+ },
+#endif
};
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 442bf47e13d6..0d416edbaba6 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -110,7 +110,6 @@
#include "regdomain_common.h"
extern int hdd_hostapd_stop (struct net_device *dev);
-void hdd_ch_avoid_cb(void *hdd_context,void *indi_param);
#endif /* FEATURE_WLAN_CH_AVOID */
#ifdef WLAN_FEATURE_NAN
@@ -16327,7 +16326,7 @@ VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
#ifdef FEATURE_WLAN_CH_AVOID
/**
- * hdd_find_prefd_safe_chnl : Finds safe channel within preferred channel
+ * hdd_find_prefd_safe_chnl - Finds safe channel within preferred channel
* @hdd_ctxt: hdd context pointer
* @ap_adapter: hdd hostapd adapter pointer
*
@@ -16340,7 +16339,7 @@ VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
* 0: could not found preferred safe channel
*/
-static uint8_t hdd_find_prefd_safe_chnl(hdd_context_t *hdd_ctxt,
+uint8_t hdd_find_prefd_safe_chnl(hdd_context_t *hdd_ctxt,
hdd_adapter_t *ap_adapter)
{
uint16_t safe_channels[NUM_20MHZ_RF_CHANNELS];
@@ -16396,6 +16395,82 @@ static uint8_t hdd_find_prefd_safe_chnl(hdd_context_t *hdd_ctxt,
return 0;
}
+/**
+ * hdd_unsafe_channel_restart_sap - restart sap if sap is on unsafe channel
+ * @hdd_ctx: hdd context pointer
+ *
+ * hdd_unsafe_channel_restart_sap check all unsafe channel list
+ * and if ACS is enabled, driver will ask userspace to restart the
+ * sap. User space on LTE coex indication restart driver.
+ *
+ * Return - none
+ */
+void hdd_unsafe_channel_restart_sap(hdd_context_t *hdd_ctx)
+{
+ hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
+ eRfChannels channel_loop;
+ hdd_adapter_t *adapter;
+ VOS_STATUS status;
+
+ static bool restart_sap_in_progress = false;
+
+ status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
+ while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
+ adapter = adapter_node->pAdapter;
+
+ if (!(adapter && (WLAN_HDD_SOFTAP == adapter->device_mode))) {
+ status = hdd_get_next_adapter(hdd_ctx, adapter_node,
+ &next);
+ adapter_node = next;
+ continue;
+ }
+ /*
+ * If auto channel select is enabled
+ * preferred channel is in safe channel,
+ * re-start softap interface with safe channel.
+ * no overlap with preferred channel and safe channel
+ * do not re-start softap interface
+ * stay current operating channel.
+ */
+ if ((adapter->sessionCtx.ap.sapConfig.acs_cfg.acs_mode) &&
+ (!hdd_find_prefd_safe_chnl(hdd_ctx, adapter)))
+ return;
+ hddLog(LOG1, FL("Current operation channel %d"),
+ adapter->sessionCtx.ap.operatingChannel);
+
+ hddLog(LOG1, FL("sessionCtx.ap.sapConfig.channel %d"),
+ adapter->sessionCtx.ap.sapConfig.channel);
+
+ for (channel_loop = 0;
+ channel_loop < hdd_ctx->unsafe_channel_count;
+ channel_loop++) {
+ if (((hdd_ctx->unsafe_channel_list[channel_loop] ==
+ adapter->sessionCtx.ap.operatingChannel)) &&
+ (adapter->sessionCtx.ap.sapConfig.acs_cfg.
+ acs_mode == true) &&
+ !restart_sap_in_progress) {
+ hddLog(LOGE,
+ FL("Restarting SAP due to unsafe channel"));
+ wlan_hdd_send_svc_nlink_msg(
+ hdd_ctx->radio_index,
+ WLAN_SVC_LTE_COEX_IND,
+ NULL,
+ 0);
+ restart_sap_in_progress = true;
+ /*
+ * current operating channel
+ * is un-safe channel, restart driver
+ */
+ hdd_hostapd_stop(adapter->dev);
+ return;
+ }
+ }
+ status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
+ adapter_node = next;
+ }
+ return;
+}
+
/**---------------------------------------------------------------------------
\brief hdd_ch_avoid_cb() -
@@ -16416,7 +16491,6 @@ void hdd_ch_avoid_cb
void *indi_param
)
{
- hdd_adapter_t *hostapd_adapter = NULL;
hdd_context_t *hdd_ctxt;
tSirChAvoidIndType *ch_avoid_indi;
v_U8_t range_loop;
@@ -16425,11 +16499,8 @@ void hdd_ch_avoid_cb
v_U16_t start_channel;
v_U16_t end_channel;
v_CONTEXT_t vos_context;
- static int restart_sap_in_progress = 0;
tHddAvoidFreqList hdd_avoid_freq_list;
tANI_U32 i;
- hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
- VOS_STATUS status;
/* Basic sanity */
if (!hdd_context || !indi_param)
@@ -16556,56 +16627,8 @@ void hdd_ch_avoid_cb
if (0 == hdd_ctxt->unsafe_channel_count)
return;
-
- status = hdd_get_front_adapter(hdd_ctxt, &adapter_node);
- while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
- hostapd_adapter = adapter_node->pAdapter;
-
- if( hostapd_adapter && (WLAN_HDD_SOFTAP ==
- hostapd_adapter->device_mode)) {
- /* If auto channel select is enabled
- * preferred channel is in safe channel,
- * re-start softap interface with safe channel.
- * no overlap with preferred channel and safe channel
- * do not re-start softap interface
- * stay current operating channel.
- */
- if ((hostapd_adapter->sessionCtx.ap.sapConfig.acs_cfg.acs_mode) &&
- (!hdd_find_prefd_safe_chnl(hdd_ctxt, hostapd_adapter)))
- return;
-
- hddLog(LOG1, FL("Current operation channel %d"),
- hostapd_adapter->sessionCtx.ap.operatingChannel);
-
- hddLog(LOG1, FL("sessionCtx.ap.sapConfig.channel %d"),
- hostapd_adapter->sessionCtx.ap.sapConfig.channel);
-
- for (channel_loop = 0;
- channel_loop < hdd_ctxt->unsafe_channel_count;
- channel_loop++) {
- if (((hdd_ctxt->unsafe_channel_list[channel_loop] ==
- hostapd_adapter->sessionCtx.ap.operatingChannel)) &&
- (hostapd_adapter->sessionCtx.ap.sapConfig.acs_cfg.acs_mode
- == true)
- && !restart_sap_in_progress) {
-
- hddLog(LOG1, FL("Restarting SAP"));
- wlan_hdd_send_svc_nlink_msg(hdd_ctxt->radio_index,
- WLAN_SVC_LTE_COEX_IND, NULL,
- 0);
- restart_sap_in_progress = 1;
- /* current operating channel is un-safe channel,
- * restart driver
- */
- hdd_hostapd_stop(hostapd_adapter->dev);
- return;
- }
- }
- }
- status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
- adapter_node = next;
- }
- return;
+ hdd_unsafe_channel_restart_sap(hdd_ctxt);
+ return;
}
#endif /* FEATURE_WLAN_CH_AVOID */