linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/5] nl80211: add an option to set driver action for beacon loss
@ 2016-03-17 13:41 Emmanuel Grumbach
  2016-03-17 13:41 ` [PATCH 2/5] mac80211: add an option to not disconnect on " Emmanuel Grumbach
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Emmanuel Grumbach @ 2016-03-17 13:41 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Avraham Stern, Emmanuel Grumbach

From: Avraham Stern <avraham.stern@intel.com>

When beacon loss is detected the driver will try to probe the AP and
if the AP does not respond, it will disconnect. However, userspace
may not want to disconnect immediately but look for a roaming
candidate first.
So add a flag to connect and association commands that indicates that
for the current connection the driver should not disconnect when
beacon loss is detected but only send an event to userspace.

Signed-off-by: Avraham Stern <avraham.stern@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
---
 include/net/cfg80211.h       |  3 +++
 include/uapi/linux/nl80211.h | 11 +++++++++++
 net/wireless/nl80211.c       | 15 +++++++++++++++
 3 files changed, 29 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 0bbfbf3..3f49867 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1728,11 +1728,14 @@ struct cfg80211_auth_request {
  * @ASSOC_REQ_DISABLE_HT:  Disable HT (802.11n)
  * @ASSOC_REQ_DISABLE_VHT:  Disable VHT
  * @ASSOC_REQ_USE_RRM: Declare RRM capability in this association
+ * @ASSOC_REQ_BEACON_LOSS_DO_NOT_DISCONNECT: Do not disconnect when beacon loss
+ *	is detected but only send a beacon loss event.
  */
 enum cfg80211_assoc_req_flags {
 	ASSOC_REQ_DISABLE_HT		= BIT(0),
 	ASSOC_REQ_DISABLE_VHT		= BIT(1),
 	ASSOC_REQ_USE_RRM		= BIT(2),
+	ASSOC_REQ_BEACON_LOSS_DO_NOT_DISCONNECT	= BIT(3),
 };
 
 /**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index b2a8d8c..673328a 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1804,6 +1804,9 @@ enum nl80211_commands {
  *	it contains the behaviour-specific attribute containing the parameters for
  *	BSS selection to be done by driver and/or firmware.
  *
+ * @NL80211_ATTR_BEACON_LOSS_DO_NOT_DISCONNECT: If set, the driver should not
+ *	take action (e.g. disconnect) upon beacon loss besides sending an event.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2182,6 +2185,8 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_BSS_SELECT,
 
+	NL80211_ATTR_BEACON_LOSS_DO_NOT_DISCONNECT,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -4419,6 +4424,11 @@ enum nl80211_feature_flags {
  *	%NL80211_CMD_ASSOCIATE and %NL80211_CMD_CONNECT requests, which will set
  *	the ASSOC_REQ_USE_RRM flag in the association request even if
  *	NL80211_FEATURE_QUIET is not advertized.
+ * @NL80211_EXT_FEATURE_BEACON_LOSS_DO_NOT_DISCONNECT: The driver supports
+ *	configuration in which the driver will not disconnect when beacon loss
+ *	is detected but it will only send a beacon loss event.
+ *	%NL80211_ATTR_BEACON_LOSS_DO_NOT_DISCONNECT flag attribute is used to
+ *	enable this configuration.
  *
  * @NUM_NL80211_EXT_FEATURES: number of extended features.
  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -4426,6 +4436,7 @@ enum nl80211_feature_flags {
 enum nl80211_ext_feature_index {
 	NL80211_EXT_FEATURE_VHT_IBSS,
 	NL80211_EXT_FEATURE_RRM,
+	NL80211_EXT_FEATURE_BEACON_LOSS_DO_NOT_DISCONNECT,
 
 	/* add new features before the definition below */
 	NUM_NL80211_EXT_FEATURES,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index c4233a0..749e315 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -403,6 +403,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
 	[NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
 	[NL80211_ATTR_PBSS] = { .type = NLA_FLAG },
 	[NL80211_ATTR_BSS_SELECT] = { .type = NLA_NESTED },
+	[NL80211_ATTR_BEACON_LOSS_DO_NOT_DISCONNECT] = { .type = NLA_FLAG },
 };
 
 /* policy for the key attributes */
@@ -7397,6 +7398,13 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
 		req.flags |= ASSOC_REQ_USE_RRM;
 	}
 
+	if (nla_get_flag(info->attrs[NL80211_ATTR_BEACON_LOSS_DO_NOT_DISCONNECT])) {
+		if (!wiphy_ext_feature_isset(&rdev->wiphy,
+					     NL80211_EXT_FEATURE_BEACON_LOSS_DO_NOT_DISCONNECT))
+			return -EINVAL;
+		req.flags |= ASSOC_REQ_BEACON_LOSS_DO_NOT_DISCONNECT;
+	}
+
 	err = nl80211_crypto_settings(rdev, info, &req.crypto, 1);
 	if (!err) {
 		wdev_lock(dev->ieee80211_ptr);
@@ -8112,6 +8120,13 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
 		}
 	}
 
+	if (nla_get_flag(info->attrs[NL80211_ATTR_BEACON_LOSS_DO_NOT_DISCONNECT])) {
+		if (!wiphy_ext_feature_isset(&rdev->wiphy,
+					     NL80211_EXT_FEATURE_BEACON_LOSS_DO_NOT_DISCONNECT))
+			return -EINVAL;
+		connect.flags |= ASSOC_REQ_BEACON_LOSS_DO_NOT_DISCONNECT;
+	}
+
 	wdev_lock(dev->ieee80211_ptr);
 	err = cfg80211_connect(rdev, dev, &connect, connkeys, NULL);
 	wdev_unlock(dev->ieee80211_ptr);
-- 
2.5.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/5] mac80211: add an option to not disconnect on beacon loss
  2016-03-17 13:41 [PATCH 1/5] nl80211: add an option to set driver action for beacon loss Emmanuel Grumbach
@ 2016-03-17 13:41 ` Emmanuel Grumbach
  2016-03-19  9:57   ` Johannes Berg
  2016-03-17 13:41 ` [PATCH 3/5] mac80211: avoid useless memory write on each frame RX Emmanuel Grumbach
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 7+ messages in thread
From: Emmanuel Grumbach @ 2016-03-17 13:41 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Avraham Stern, Emmanuel Grumbach

From: Avraham Stern <avraham.stern@intel.com>

Add the option to set mac80211 to not disconnect on beacon loss.
If this option is set, mac80211 will send a beacon loss event
to userspace but will not disconnect.
The beacon loss event is sent only once as long as no response
is received from the AP. If after receiving response from the AP the
beacon loss threshold is hit again, another beacon loss event will
be sent.
The default behavior remains as it was: probe the AP and disconnect
if the AP does not respond.

Signed-off-by: Avraham Stern <avraham.stern@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
---
 net/mac80211/ieee80211_i.h |  2 ++
 net/mac80211/main.c        |  2 ++
 net/mac80211/mlme.c        | 14 +++++++++++++-
 3 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index c6830fb..0008f28 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -356,6 +356,8 @@ enum ieee80211_sta_flags {
 	IEEE80211_STA_DISABLE_160MHZ	= BIT(13),
 	IEEE80211_STA_DISABLE_WMM	= BIT(14),
 	IEEE80211_STA_ENABLE_RRM	= BIT(15),
+	IEEE80211_STA_BEACON_LOSS_DO_NOT_DISCONNECT	= BIT(16),
+	IEEE80211_STA_BEACON_LOSS_REPORTED	= BIT(17),
 };
 
 struct ieee80211_mgd_auth_data {
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 33c80de..6083256 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -554,6 +554,8 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
 		wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN |
 				   NL80211_FEATURE_AP_SCAN;
 
+	wiphy_ext_feature_set(wiphy,
+			      NL80211_EXT_FEATURE_BEACON_LOSS_DO_NOT_DISCONNECT);
 
 	if (!ops->set_key)
 		wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 281b8d6..8968a96 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -126,6 +126,7 @@ void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata)
 		return;
 
 	ifmgd->probe_send_count = 0;
+	sdata->u.mgd.flags &= ~IEEE80211_STA_BEACON_LOSS_REPORTED;
 
 	if (ieee80211_hw_check(&sdata->local->hw, CONNECTION_MONITOR))
 		return;
@@ -1926,6 +1927,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
 
 	/* just to be sure */
 	ieee80211_stop_poll(sdata);
+	sdata->u.mgd.flags &= ~IEEE80211_STA_BEACON_LOSS_REPORTED;
 
 	ieee80211_led_assoc(local, 1);
 
@@ -1984,6 +1986,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
 		return;
 
 	ieee80211_stop_poll(sdata);
+	ifmgd->flags &= ~IEEE80211_STA_BEACON_LOSS_REPORTED;
 
 	ifmgd->associated = NULL;
 	netif_carrier_off(sdata->dev);
@@ -2422,8 +2425,12 @@ static void ieee80211_beacon_connection_loss_work(struct work_struct *work)
 		sdata_info(sdata, "Connection to AP %pM lost\n",
 			   ifmgd->bssid);
 		__ieee80211_disconnect(sdata);
-	} else {
+	} else if (!(ifmgd->flags & IEEE80211_STA_BEACON_LOSS_DO_NOT_DISCONNECT)) {
 		ieee80211_mgd_probe_ap(sdata, true);
+	} else if (!(ifmgd->flags & IEEE80211_STA_BEACON_LOSS_REPORTED)) {
+		ieee80211_cqm_beacon_loss_notify(&sdata->vif,
+						 GFP_KERNEL);
+		ifmgd->flags |= IEEE80211_STA_BEACON_LOSS_REPORTED;
 	}
 }
 
@@ -4742,6 +4749,11 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
 	sdata->encrypt_headroom = ieee80211_cs_headroom(local, &req->crypto,
 							sdata->vif.type);
 
+	if (req->flags & ASSOC_REQ_BEACON_LOSS_DO_NOT_DISCONNECT)
+		ifmgd->flags |= IEEE80211_STA_BEACON_LOSS_DO_NOT_DISCONNECT;
+	else
+		ifmgd->flags &= ~IEEE80211_STA_BEACON_LOSS_DO_NOT_DISCONNECT;
+
 	/* kick off associate process */
 
 	ifmgd->assoc_data = assoc_data;
-- 
2.5.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/5] mac80211: avoid useless memory write on each frame RX
  2016-03-17 13:41 [PATCH 1/5] nl80211: add an option to set driver action for beacon loss Emmanuel Grumbach
  2016-03-17 13:41 ` [PATCH 2/5] mac80211: add an option to not disconnect on " Emmanuel Grumbach
@ 2016-03-17 13:41 ` Emmanuel Grumbach
  2016-03-17 13:41 ` [PATCH 4/5] cfg80211: allow userspace to specify client P2P PS support Emmanuel Grumbach
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Emmanuel Grumbach @ 2016-03-17 13:41 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Johannes Berg, Emmanuel Grumbach

From: Johannes Berg <johannes.berg@intel.com>

In the likely case that probe_count is 0 and the flag is clear,
don't write to the memory there. This will avoid cache bouncing
when adding parallel RX support.

Also use ifmgd consistently in the function, instead of using
sdata->u.mgd as well.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
---
 net/mac80211/mlme.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 8968a96..219e34d 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -122,16 +122,18 @@ void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata)
 {
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 
-	if (unlikely(!sdata->u.mgd.associated))
+	if (unlikely(!ifmgd->associated))
 		return;
 
-	ifmgd->probe_send_count = 0;
-	sdata->u.mgd.flags &= ~IEEE80211_STA_BEACON_LOSS_REPORTED;
+	if (ifmgd->probe_send_count)
+		ifmgd->probe_send_count = 0;
+	if (ifmgd->flags & IEEE80211_STA_BEACON_LOSS_REPORTED)
+		ifmgd->flags &= ~IEEE80211_STA_BEACON_LOSS_REPORTED;
 
 	if (ieee80211_hw_check(&sdata->local->hw, CONNECTION_MONITOR))
 		return;
 
-	mod_timer(&sdata->u.mgd.conn_mon_timer,
+	mod_timer(&ifmgd->conn_mon_timer,
 		  round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME));
 }
 
-- 
2.5.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/5] cfg80211: allow userspace to specify client P2P PS support
  2016-03-17 13:41 [PATCH 1/5] nl80211: add an option to set driver action for beacon loss Emmanuel Grumbach
  2016-03-17 13:41 ` [PATCH 2/5] mac80211: add an option to not disconnect on " Emmanuel Grumbach
  2016-03-17 13:41 ` [PATCH 3/5] mac80211: avoid useless memory write on each frame RX Emmanuel Grumbach
@ 2016-03-17 13:41 ` Emmanuel Grumbach
  2016-03-17 13:41 ` [PATCH 5/5] mac80211: track and tell driver about GO client P2P PS abilities Emmanuel Grumbach
  2016-04-05 10:18 ` [PATCH 1/5] nl80211: add an option to set driver action for beacon loss Johannes Berg
  4 siblings, 0 replies; 7+ messages in thread
From: Emmanuel Grumbach @ 2016-03-17 13:41 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Ayala Beker, Emmanuel Grumbach

From: Ayala Beker <ayala.beker@intel.com>

Legacy clients don't support P2P power save mechanisms, and thus
if a P2P GO has a legacy client connected to it, it has to make
some changes in the PS behavior.

To handle this, add an attribute to specify whether a station supports
P2P PS or not. If the attribute was not specified cfg80211 will assume
that station supports it for P2P GO interface, and does NOT support it
for AP interface, matching the current assumptions in the code.

Signed-off-by: Ayala Beker <ayala.beker@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
---
 include/net/cfg80211.h       |  2 ++
 include/uapi/linux/nl80211.h | 19 +++++++++++++++++++
 net/wireless/nl80211.c       | 34 ++++++++++++++++++++++++++++++++++
 3 files changed, 55 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 3f49867..c7fa0b3 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -816,6 +816,7 @@ enum station_parameters_apply_mask {
  * @supported_oper_classes_len: number of supported operating classes
  * @opmode_notif: operating mode field from Operating Mode Notification
  * @opmode_notif_used: information if operating mode field is used
+ * @support_p2p_ps: information if station supports P2P PS mechanism
  */
 struct station_parameters {
 	const u8 *supported_rates;
@@ -841,6 +842,7 @@ struct station_parameters {
 	u8 supported_oper_classes_len;
 	u8 opmode_notif;
 	bool opmode_notif_used;
+	int support_p2p_ps;
 };
 
 /**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 673328a..53dd160 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1807,6 +1807,9 @@ enum nl80211_commands {
  * @NL80211_ATTR_BEACON_LOSS_DO_NOT_DISCONNECT: If set, the driver should not
  *	take action (e.g. disconnect) upon beacon loss besides sending an event.
  *
+ * @NL80211_ATTR_STA_SUPPORT_P2P_PS: whether P2P PS mechanism supported
+ *	or not. u8, one of the values of &enum nl80211_sta_p2p_ps_status
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2187,6 +2190,8 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_BEACON_LOSS_DO_NOT_DISCONNECT,
 
+	NL80211_ATTR_STA_SUPPORT_P2P_PS,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -2330,6 +2335,20 @@ enum nl80211_sta_flags {
 	NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1
 };
 
+/**
+ * enum nl80211_sta_p2p_ps_status - station support of P2P PS
+ *
+ * @NL80211_P2P_PS_UNSUPPORTED: station doesn't support P2P PS mechanism
+ * @@NL80211_P2P_PS_SUPPORTED: station supports P2P PS mechanism
+ * @NUM_NL80211_P2P_PS_STATUS: number of values
+ */
+enum nl80211_sta_p2p_ps_status {
+	NL80211_P2P_PS_UNSUPPORTED = 0,
+	NL80211_P2P_PS_SUPPORTED,
+
+	NUM_NL80211_P2P_PS_STATUS,
+};
+
 #define NL80211_STA_FLAG_MAX_OLD_API	NL80211_STA_FLAG_TDLS_PEER
 
 /**
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 749e315..f8022538 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -404,6 +404,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
 	[NL80211_ATTR_PBSS] = { .type = NLA_FLAG },
 	[NL80211_ATTR_BSS_SELECT] = { .type = NLA_NESTED },
 	[NL80211_ATTR_BEACON_LOSS_DO_NOT_DISCONNECT] = { .type = NLA_FLAG },
+	[NL80211_ATTR_STA_SUPPORT_P2P_PS] = { .type = NLA_U8 },
 };
 
 /* policy for the key attributes */
@@ -4007,6 +4008,10 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
 	    statype != CFG80211_STA_AP_CLIENT_UNASSOC)
 		return -EINVAL;
 
+	if (params->support_p2p_ps != -1 &&
+	    statype != CFG80211_STA_AP_CLIENT_UNASSOC)
+		return -EINVAL;
+
 	if (params->aid &&
 	    !(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
 	    statype != CFG80211_STA_AP_CLIENT_UNASSOC)
@@ -4300,6 +4305,18 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
 	else
 		params.listen_interval = -1;
 
+	if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]) {
+		u8 tmp;
+
+		tmp = nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
+		if (tmp >= NUM_NL80211_P2P_PS_STATUS)
+			return -EINVAL;
+
+		params.support_p2p_ps = tmp;
+	} else {
+		params.support_p2p_ps = -1;
+	}
+
 	if (!info->attrs[NL80211_ATTR_MAC])
 		return -EINVAL;
 
@@ -4423,6 +4440,23 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
 	params.listen_interval =
 		nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
 
+	if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]) {
+		u8 tmp;
+
+		tmp = nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
+		if (tmp >= NUM_NL80211_P2P_PS_STATUS)
+			return -EINVAL;
+
+		params.support_p2p_ps = tmp;
+	} else {
+		/*
+		 * if not specified, assume it's supported for P2P GO interface,
+		 * and is NOT supported for AP interface
+		 */
+		params.support_p2p_ps =
+			dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO;
+	}
+
 	if (info->attrs[NL80211_ATTR_PEER_AID])
 		params.aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
 	else
-- 
2.5.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 5/5] mac80211: track and tell driver about GO client P2P PS abilities
  2016-03-17 13:41 [PATCH 1/5] nl80211: add an option to set driver action for beacon loss Emmanuel Grumbach
                   ` (2 preceding siblings ...)
  2016-03-17 13:41 ` [PATCH 4/5] cfg80211: allow userspace to specify client P2P PS support Emmanuel Grumbach
@ 2016-03-17 13:41 ` Emmanuel Grumbach
  2016-04-05 10:18 ` [PATCH 1/5] nl80211: add an option to set driver action for beacon loss Johannes Berg
  4 siblings, 0 replies; 7+ messages in thread
From: Emmanuel Grumbach @ 2016-03-17 13:41 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Ayala Beker, Emmanuel Grumbach

From: Ayala Beker <ayala.beker@intel.com>

Legacy clients don't support P2P power save mechanism, and thus if a P2P GO
has a legacy client connected to it, it should disable P2P PS mechanisms.
Let the driver know about this with a new bss_conf parameter.

Signed-off-by: Ayala Beker <ayala.beker@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
---
 include/net/mac80211.h  |  8 +++++++-
 net/mac80211/cfg.c      |  4 ++++
 net/mac80211/sta_info.c | 29 +++++++++++++++++++++++++++++
 3 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index a53333c..6e34675 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -291,7 +291,7 @@ struct ieee80211_vif_chanctx_switch {
  * @BSS_CHANGED_PS: PS changed for this BSS (STA mode)
  * @BSS_CHANGED_TXPOWER: TX power setting changed for this interface
  * @BSS_CHANGED_P2P_PS: P2P powersave settings (CTWindow, opportunistic PS)
- *	changed (currently only in P2P client mode, GO mode will be later)
+ *	changed
  * @BSS_CHANGED_BEACON_INFO: Data from the AP's beacon became available:
  *	currently dtim_period only is under consideration.
  * @BSS_CHANGED_BANDWIDTH: The bandwidth used by this interface changed,
@@ -526,6 +526,9 @@ struct ieee80211_mu_group_data {
  *	userspace), whereas TPC is disabled if %txpower_type is set to
  *	NL80211_TX_POWER_FIXED (use value configured from userspace)
  * @p2p_noa_attr: P2P NoA attribute for P2P powersave
+ * @allow_p2p_go_ps: indication for AP or P2P GO interface, whether it's allowed
+ *	to use P2P PS mechanism or not. AP/P2P GO is not allowed to use P2P PS
+ *	if it has associated clients without P2P PS support.
  */
 struct ieee80211_bss_conf {
 	const u8 *bssid;
@@ -563,6 +566,7 @@ struct ieee80211_bss_conf {
 	int txpower;
 	enum nl80211_tx_power_setting txpower_type;
 	struct ieee80211_p2p_noa_attr p2p_noa_attr;
+	bool allow_p2p_go_ps;
 };
 
 /**
@@ -1741,6 +1745,7 @@ struct ieee80211_sta_rates {
  *		  size is min(max_amsdu_len, 7935) bytes.
  *	Both additional HT limits must be enforced by the low level driver.
  *	This is defined by the spec (IEEE 802.11-2012 section 8.3.2.2 NOTE 2).
+ * @support_p2p_ps: indicates whether the STA supports P2P PS mechanism or not.
  * @txq: per-TID data TX queues (if driver uses the TXQ abstraction)
  */
 struct ieee80211_sta {
@@ -1761,6 +1766,7 @@ struct ieee80211_sta {
 	bool mfp;
 	u8 max_amsdu_subframes;
 	u16 max_amsdu_len;
+	bool support_p2p_ps;
 
 	struct ieee80211_txq *txq[IEEE80211_NUM_TIDS];
 
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index b37adb6..62a90f2 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -732,6 +732,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
 	sdata->vif.bss_conf.beacon_int = params->beacon_interval;
 	sdata->vif.bss_conf.dtim_period = params->dtim_period;
 	sdata->vif.bss_conf.enable_beacon = true;
+	sdata->vif.bss_conf.allow_p2p_go_ps = sdata->vif.p2p;
 
 	sdata->vif.bss_conf.ssid_len = params->ssid_len;
 	if (params->ssid_len)
@@ -1202,6 +1203,9 @@ static int sta_apply_parameters(struct ieee80211_local *local,
 					      params->opmode_notif, band);
 	}
 
+	if (params->support_p2p_ps >= 0)
+		sta->sta.support_p2p_ps = params->support_p2p_ps;
+
 	if (ieee80211_vif_is_mesh(&sdata->vif))
 		sta_apply_mesh_params(local, sta, params);
 
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 00c82fb..01e070c 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -1767,6 +1767,31 @@ void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta,
 }
 EXPORT_SYMBOL(ieee80211_sta_set_buffered);
 
+static void
+ieee80211_recalc_p2p_go_ps_allowed(struct ieee80211_sub_if_data *sdata)
+{
+	struct ieee80211_local *local = sdata->local;
+	bool allow_p2p_go_ps = sdata->vif.p2p;
+	struct sta_info *sta;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(sta, &local->sta_list, list) {
+		if (sdata != sta->sdata ||
+		    !test_sta_flag(sta, WLAN_STA_ASSOC))
+			continue;
+		if (!sta->sta.support_p2p_ps) {
+			allow_p2p_go_ps = false;
+			break;
+		}
+	}
+	rcu_read_unlock();
+
+	if (allow_p2p_go_ps != sdata->vif.bss_conf.allow_p2p_go_ps) {
+		sdata->vif.bss_conf.allow_p2p_go_ps = allow_p2p_go_ps;
+		ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_P2P_PS);
+	}
+}
+
 int sta_info_move_state(struct sta_info *sta,
 			enum ieee80211_sta_state new_state)
 {
@@ -1828,12 +1853,16 @@ int sta_info_move_state(struct sta_info *sta,
 		} else if (sta->sta_state == IEEE80211_STA_ASSOC) {
 			clear_bit(WLAN_STA_ASSOC, &sta->_flags);
 			ieee80211_recalc_min_chandef(sta->sdata);
+			if (!sta->sta.support_p2p_ps)
+				ieee80211_recalc_p2p_go_ps_allowed(sta->sdata);
 		}
 		break;
 	case IEEE80211_STA_ASSOC:
 		if (sta->sta_state == IEEE80211_STA_AUTH) {
 			set_bit(WLAN_STA_ASSOC, &sta->_flags);
 			ieee80211_recalc_min_chandef(sta->sdata);
+			if (!sta->sta.support_p2p_ps)
+				ieee80211_recalc_p2p_go_ps_allowed(sta->sdata);
 		} else if (sta->sta_state == IEEE80211_STA_AUTHORIZED) {
 			if (sta->sdata->vif.type == NL80211_IFTYPE_AP ||
 			    (sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
-- 
2.5.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/5] mac80211: add an option to not disconnect on beacon loss
  2016-03-17 13:41 ` [PATCH 2/5] mac80211: add an option to not disconnect on " Emmanuel Grumbach
@ 2016-03-19  9:57   ` Johannes Berg
  0 siblings, 0 replies; 7+ messages in thread
From: Johannes Berg @ 2016-03-19  9:57 UTC (permalink / raw)
  To: Emmanuel Grumbach; +Cc: linux-wireless, Avraham Stern

On Thu, 2016-03-17 at 15:41 +0200, Emmanuel Grumbach wrote:

>  	ifmgd->probe_send_count = 0;
> +	sdata->u.mgd.flags &= ~IEEE80211_STA_BEACON_LOSS_REPORTED;

This is very racy, concurrent RX will corrupt the flags value since
this requires a read-modify-write and cannot be done with locking.

I can't apply this.

johannes

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/5] nl80211: add an option to set driver action for beacon loss
  2016-03-17 13:41 [PATCH 1/5] nl80211: add an option to set driver action for beacon loss Emmanuel Grumbach
                   ` (3 preceding siblings ...)
  2016-03-17 13:41 ` [PATCH 5/5] mac80211: track and tell driver about GO client P2P PS abilities Emmanuel Grumbach
@ 2016-04-05 10:18 ` Johannes Berg
  4 siblings, 0 replies; 7+ messages in thread
From: Johannes Berg @ 2016-04-05 10:18 UTC (permalink / raw)
  To: Emmanuel Grumbach; +Cc: linux-wireless, Avraham Stern

I've applied 1,3-5 of this series.

johannes

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-04-05 10:18 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-03-17 13:41 [PATCH 1/5] nl80211: add an option to set driver action for beacon loss Emmanuel Grumbach
2016-03-17 13:41 ` [PATCH 2/5] mac80211: add an option to not disconnect on " Emmanuel Grumbach
2016-03-19  9:57   ` Johannes Berg
2016-03-17 13:41 ` [PATCH 3/5] mac80211: avoid useless memory write on each frame RX Emmanuel Grumbach
2016-03-17 13:41 ` [PATCH 4/5] cfg80211: allow userspace to specify client P2P PS support Emmanuel Grumbach
2016-03-17 13:41 ` [PATCH 5/5] mac80211: track and tell driver about GO client P2P PS abilities Emmanuel Grumbach
2016-04-05 10:18 ` [PATCH 1/5] nl80211: add an option to set driver action for beacon loss Johannes Berg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).