From 0172ebfcf761bdf7874faa4f7ae888022ab3bf25 Mon Sep 17 00:00:00 2001
From: "Pungavanam, Ramesh" <ramesh.pungavanam@intel.com>
Date: Thu, 12 Apr 2018 12:04:12 +0200
Subject: [PATCH] Merge pull request #298 in SW_PON/linux from
 wlan_xft_8x_er2_integ to 8.1_ER2

* commit '1f89bda7e536722de160883827dc7ff4b419ecab':
  Changes to kernel to update wlan driver
---
 include/net/cfg80211.h    |  2 ++
 include/net/mac80211.h    |  2 ++
 net/mac80211/cfg.c        |  8 ++++++++
 net/mac80211/driver-ops.h |  8 ++++++++
 net/wireless/mlme.c       |  2 +-
 net/wireless/nl80211.c    |  2 +-
 net/wireless/rdev-ops.h   |  8 ++++++++
 net/wireless/sme.c        | 16 +++++++++++++++-
 8 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index fbd0923af..dae041d19 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2970,6 +2970,8 @@ struct cfg80211_ops {
 	int	(*set_ap_chanwidth)(struct wiphy *wiphy, struct net_device *dev,
 				    struct cfg80211_chan_def *chandef);
 
+	bool    (*is_all_iface_idle)(struct wiphy *wiphy);
+
 	int	(*add_tx_ts)(struct wiphy *wiphy, struct net_device *dev,
 			     u8 tsid, const u8 *peer, u8 user_prio,
 			     u16 admitted_time);
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 3deba85dd..91ff69b57 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -3690,6 +3690,8 @@ struct ieee80211_ops {
 	int (*get_connection_alive)(struct ieee80211_hw *hw,
 				struct ieee80211_vif *vif);
 
+	bool (*is_all_iface_idle)(struct ieee80211_hw *hw);
+
 #if IS_ENABLED(CONFIG_IPV6)
 	void (*ipv6_addr_change)(struct ieee80211_hw *hw,
 				 struct ieee80211_vif *vif,
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 5e27811a4..91cfd1b20 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3183,6 +3183,13 @@ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
 	return err;
 }
 
+static bool ieee80211_is_all_iface_idle(struct wiphy *wiphy)
+{
+	struct ieee80211_local *local = wiphy_priv(wiphy);
+
+	return drv_is_all_iface_idle(local);
+}
+
 u64 ieee80211_mgmt_tx_cookie(struct ieee80211_local *local)
 {
 	lockdep_assert_held(&local->mtx);
@@ -3669,6 +3676,7 @@ const struct cfg80211_ops mac80211_config_ops = {
 	.get_channel = ieee80211_cfg_get_channel,
 	.start_radar_detection = ieee80211_start_radar_detection,
 	.channel_switch = ieee80211_channel_switch,
+	.is_all_iface_idle = ieee80211_is_all_iface_idle,
 	.set_qos_map = ieee80211_set_qos_map,
 	.set_ap_chanwidth = ieee80211_set_ap_chanwidth,
 	.add_tx_ts = ieee80211_add_tx_ts,
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 3be8346ef..f53f9c22d 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -655,6 +655,14 @@ static inline int drv_set_antenna(struct ieee80211_local *local,
 	return ret;
 }
 
+static inline bool drv_is_all_iface_idle(struct ieee80211_local *local)
+{
+	if (!local->ops->is_all_iface_idle)
+		return true;
+
+	return local->ops->is_all_iface_idle(&local->hw);
+}
+
 static inline int drv_get_antenna(struct ieee80211_local *local,
 				  u32 *tx_ant, u32 *rx_ant)
 {
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index c48e158c6..acec3a8dc 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -802,7 +802,7 @@ static void cfg80211_set_chans_dfs_state_bit_map (struct wiphy *wiphy, u32 cente
 		if (radar_bit_map & (1 << *bit_idx)) {
 			c = ieee80211_get_channel(wiphy, freq);
 			if (!c || !(c->flags & IEEE80211_CHAN_RADAR)) {
-				*bit_idx++;
+				(*bit_idx)++;
 				continue;
 			}
 
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index eb3250b08..bfdfed3a1 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -7431,7 +7431,7 @@ skip_beacons:
 	if (info->attrs[NL80211_ATTR_SB_DFS_BW])
 		params.sb_dfs_bw = nla_get_u8(info->attrs[NL80211_ATTR_SB_DFS_BW]);
 
-	if (NL80211_SB_DFS_BW_FULL == params.sb_dfs_bw)
+	if (params.sb_dfs_bw)
 		cfg80211_set_dfs_state(&rdev->wiphy, &params.chandef, NL80211_DFS_AVAILABLE);
 
 	if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 11cf83c8a..669bca63c 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -758,6 +758,14 @@ static inline int rdev_set_antenna(struct cfg80211_registered_device *rdev,
 	return ret;
 }
 
+static inline bool rdev_is_all_iface_idle(struct cfg80211_registered_device *rdev)
+{
+	if (!rdev->ops->is_all_iface_idle)
+		return true;
+
+	return rdev->ops->is_all_iface_idle(&rdev->wiphy);
+}
+
 static inline int rdev_get_antenna(struct cfg80211_registered_device *rdev,
 				   u32 *tx_ant, u32 *rx_ant)
 {
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index ece8a0ab7..dca8b57ff 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -640,10 +640,24 @@ static bool cfg80211_is_all_idle(void)
 	return is_all_idle;
 }
 
+static bool cfg80211_drv_is_all_idle(void)
+{
+	struct cfg80211_registered_device *rdev;
+	bool is_all_idle = true;
+
+	list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
+		if (!rdev_is_all_iface_idle(rdev))
+			is_all_idle = false;
+	 }
+
+	return is_all_idle;
+}
+
+
 static void disconnect_work(struct work_struct *work)
 {
 	rtnl_lock();
-	if (cfg80211_is_all_idle())
+	if (cfg80211_is_all_idle() && cfg80211_drv_is_all_idle())
 		regulatory_hint_disconnect();
 	rtnl_unlock();
 }
-- 
GitLab