From b6ac3ce47c7c798b75179c3dc96b540f96df6269 Mon Sep 17 00:00:00 2001 From: Srishti Piplani Date: Mon, 22 Apr 2019 14:29:11 +0530 Subject: [PATCH] [NEUS7920-218] [9610] wlbt: Check validity of AP channel Check validity of AP channel before selecting the channel for starting the AP, for Wi-Fi Sharing scenario. Select the channel only if it is non indoor , non DFS. Change-Id: Ie81bcf8e561bf89b83416647c8f27860561b0d6f SCSC-Bug-Id: SSB-51899 Signed-off-by: Srishti Piplani --- drivers/net/wireless/scsc/cfg80211_ops.c | 15 ++++++++-- drivers/net/wireless/scsc/dev.c | 8 +++++ drivers/net/wireless/scsc/mgt.c | 37 ++++++++++++++++++++++-- drivers/net/wireless/scsc/mgt.h | 3 +- 4 files changed, 57 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/scsc/cfg80211_ops.c b/drivers/net/wireless/scsc/cfg80211_ops.c index 697c6d6ac0d3..e4771fd4644b 100755 --- a/drivers/net/wireless/scsc/cfg80211_ops.c +++ b/drivers/net/wireless/scsc/cfg80211_ops.c @@ -2015,7 +2015,9 @@ int slsi_start_ap(struct wiphy *wiphy, struct net_device *dev, #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING int wifi_sharing_channel_switched = 0; struct netdev_vif *ndev_sta_vif; + int invalid_channel = 0; #endif + int skip_indoor_check_for_wifi_sharing = 0; u8 *ds_params_ie = NULL; struct ieee80211_mgmt *mgmt; u16 beacon_ie_head_len; @@ -2049,7 +2051,15 @@ int slsi_start_ap(struct wiphy *wiphy, struct net_device *dev, if ((ndev_sta_vif->activated) && (ndev_sta_vif->vif_type == FAPI_VIFTYPE_STATION) && (ndev_sta_vif->sta.vif_status == SLSI_VIF_STATUS_CONNECTING || ndev_sta_vif->sta.vif_status == SLSI_VIF_STATUS_CONNECTED)) { - slsi_select_wifi_sharing_ap_channel(wiphy, dev, settings, sdev, &wifi_sharing_channel_switched); + invalid_channel = slsi_select_wifi_sharing_ap_channel(wiphy, dev, settings, sdev, + &wifi_sharing_channel_switched); + skip_indoor_check_for_wifi_sharing = 1; + if (invalid_channel) { + SLSI_NET_ERR(dev, "Rejecting AP start req at host (invalid channel)\n"); + SLSI_MUTEX_UNLOCK(ndev_sta_vif->vif_mutex); + r = -EINVAL; + goto exit_with_vif_mutex; + } } SLSI_MUTEX_UNLOCK(ndev_sta_vif->vif_mutex); } @@ -2071,7 +2081,8 @@ int slsi_start_ap(struct wiphy *wiphy, struct net_device *dev, } } } - if (sdev->band_5g_supported && ((settings->chandef.chan->center_freq / 1000) == 5)) { + if (!skip_indoor_check_for_wifi_sharing && sdev->band_5g_supported && + ((settings->chandef.chan->center_freq / 1000) == 5)) { channel = ieee80211_get_channel(sdev->wiphy, settings->chandef.chan->center_freq); if (!channel) { SLSI_ERR(sdev, "Invalid frequency %d used to start AP. Channel not found\n", diff --git a/drivers/net/wireless/scsc/dev.c b/drivers/net/wireless/scsc/dev.c index d229eed9afd6..be8837c7f656 100755 --- a/drivers/net/wireless/scsc/dev.c +++ b/drivers/net/wireless/scsc/dev.c @@ -373,7 +373,15 @@ struct slsi_dev *slsi_dev_attach(struct device *dev, struct scsc_mx *core, struc #if CONFIG_SCSC_WLAN_MAX_INTERFACES >= 4 if (slsi_netif_register(sdev, sdev->netdev[SLSI_NET_INDEX_NAN]) != 0) { SLSI_ERR(sdev, "failed to register with NAN netdev\n"); +#ifdef CONFIG_SCSC_WLAN_WIFI_SHARING +#if defined(CONFIG_SCSC_WLAN_MHS_STATIC_INTERFACE) || (defined(ANDROID_VERSION) && ANDROID_VERSION >= 90000) goto err_p2px_wlan_registered; +#else + goto err_p2p_registered; +#endif +#else + goto err_p2p_registered; +#endif } #endif #endif diff --git a/drivers/net/wireless/scsc/mgt.c b/drivers/net/wireless/scsc/mgt.c index cd361aa7127c..ea1238f50742 100755 --- a/drivers/net/wireless/scsc/mgt.c +++ b/drivers/net/wireless/scsc/mgt.c @@ -4817,7 +4817,33 @@ bool slsi_if_valid_wifi_sharing_channel(struct slsi_dev *sdev, int freq) return 0; } -void slsi_select_wifi_sharing_ap_channel(struct wiphy *wiphy, struct net_device *dev, +int slsi_check_if_non_indoor_channel(struct slsi_dev *sdev, int freq) +{ + struct ieee80211_channel *channel = NULL; + u32 chan_flags = 0; + + channel = ieee80211_get_channel(sdev->wiphy, freq); + if (!channel) { + SLSI_ERR(sdev, "Invalid frequency %d used to start AP. Channel not found\n", freq); + return 0; + } + + chan_flags = (IEEE80211_CHAN_INDOOR_ONLY | + IEEE80211_CHAN_DISABLED | +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 10, 13) + IEEE80211_CHAN_PASSIVE_SCAN +#else + IEEE80211_CHAN_NO_IR +#endif + ); + + if ((channel->flags) & chan_flags) + return 0; + + return 1; +} + +int slsi_select_wifi_sharing_ap_channel(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ap_settings *settings, struct slsi_dev *sdev, int *wifi_sharing_channel_switched) { @@ -4840,7 +4866,8 @@ void slsi_select_wifi_sharing_ap_channel(struct wiphy *wiphy, struct net_device if ((((settings->chandef.chan->center_freq) / 1000) == 5) && !(slsi_check_if_channel_restricted_already(sdev, ieee80211_frequency_to_channel(settings->chandef.chan->center_freq))) && - slsi_if_valid_wifi_sharing_channel(sdev, settings->chandef.chan->center_freq)) { + slsi_if_valid_wifi_sharing_channel(sdev, settings->chandef.chan->center_freq) && + slsi_check_if_non_indoor_channel(sdev, settings->chandef.chan->center_freq)) { settings->chandef.chan = ieee80211_get_channel(wiphy, settings->chandef.chan->center_freq); settings->chandef.center_freq1 = settings->chandef.chan->center_freq; } else { @@ -4856,6 +4883,8 @@ void slsi_select_wifi_sharing_ap_channel(struct wiphy *wiphy, struct net_device else { /* For 5GHz */ /* For single antenna */ #ifdef CONFIG_SCSC_WLAN_SINGLE_ANTENNA + if (!slsi_check_if_non_indoor_channel(sdev, sta_frequency)) + return 1; /*AP cannot start on indoor channel so we will reject request from the host*/ if ((settings->chandef.chan->center_freq) != (sta_frequency)) { *wifi_sharing_channel_switched = 1; settings->chandef.chan = ieee80211_get_channel(wiphy, sta_frequency); @@ -4867,7 +4896,8 @@ void slsi_select_wifi_sharing_ap_channel(struct wiphy *wiphy, struct net_device if (((settings->chandef.chan->center_freq) / 1000) == 5) { if (!(slsi_check_if_channel_restricted_already(sdev, ieee80211_frequency_to_channel(sta_frequency))) && - slsi_if_valid_wifi_sharing_channel(sdev, sta_frequency)) { + slsi_if_valid_wifi_sharing_channel(sdev, sta_frequency) && + slsi_check_if_non_indoor_channel(sdev, sta_frequency)) { if ((settings->chandef.chan->center_freq) != (sta_frequency)) { *wifi_sharing_channel_switched = 1; settings->chandef.chan = ieee80211_get_channel(wiphy, sta_frequency); @@ -4882,6 +4912,7 @@ void slsi_select_wifi_sharing_ap_channel(struct wiphy *wiphy, struct net_device } SLSI_DBG1(sdev, SLSI_CFG80211, "AP frequency chosen: %d\n", settings->chandef.chan->center_freq); + return 0; } int slsi_get_byte_position(int bit) diff --git a/drivers/net/wireless/scsc/mgt.h b/drivers/net/wireless/scsc/mgt.h index d1d2257ae855..b18e80974872 100755 --- a/drivers/net/wireless/scsc/mgt.h +++ b/drivers/net/wireless/scsc/mgt.h @@ -482,7 +482,8 @@ void slsi_modify_ies_on_channel_switch(struct net_device *dev, struct cfg80211_a #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING bool slsi_if_valid_wifi_sharing_channel(struct slsi_dev *sdev, int freq); void slsi_extract_valid_wifi_sharing_channels(struct slsi_dev *sdev); -void slsi_select_wifi_sharing_ap_channel(struct wiphy *wiphy, struct net_device *dev, +int slsi_check_if_non_indoor_channel(struct slsi_dev *sdev, int freq); +int slsi_select_wifi_sharing_ap_channel(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ap_settings *settings, struct slsi_dev *sdev, int *wifi_sharing_channel_switched); int slsi_set_mib_wifi_sharing_5ghz_channel(struct slsi_dev *sdev, u16 psid, int value, -- 2.20.1