diff options
| author | Agrawal Ashish <ashishka@qti.qualcomm.com> | 2016-03-22 19:28:01 +0530 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2016-04-22 17:15:45 +0530 |
| commit | 2c99f033c828dbe0eff22fbff84ea6abd71e21d9 (patch) | |
| tree | bbfacd746d64a0feee1f8a16d348d9703346a774 | |
| parent | eccf50c0ca4a12c75c436518467a58b8d80c10ac (diff) | |
qcacld-2.0: Implement vendor command to avoid freq in SAP
Add support for vendor command which ask the driver
to restart the SAP if SAP is on unsafe channel.
QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY is used to send
driver to restart SAP device if SAP is on any unsafe channels.
Upon receiving this command, driver will restart the SAP device
if SAP is operating on any of one the unsafe channels.
Change-Id: I187a6e0c9f3eaa96c740e50c332a7aba5796dc74
CRs-Fixed: 998048
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_main.h | 4 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_cfg80211.c | 92 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_main.c | 137 |
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 */ |
