All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] mac80211: client-side P2P powersave
@ 2012-11-05 14:40 Johannes Berg
  2012-11-05 14:40 ` [PATCH 1/2] wireless: add utility function to get P2P attribute Johannes Berg
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Johannes Berg @ 2012-11-05 14:40 UTC (permalink / raw)
  To: linux-wireless

Implement passing the P2P powersave parameters (except NoA
schedules) to the mac80211 hardware driver. To do this, I
introduced a generic function to get a copy of some P2P
attribute into a buffer, I did it that way because of the
potential for fragmentation into multiple IEs.

The only change over the RFC is that I now use the correct
attribute ID definition from Arend's patch.

johannes


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

* [PATCH 1/2] wireless: add utility function to get P2P attribute
  2012-11-05 14:40 [PATCH 0/2] mac80211: client-side P2P powersave Johannes Berg
@ 2012-11-05 14:40 ` Johannes Berg
  2012-11-05 14:40 ` [PATCH 2/2] mac80211: pass P2P powersave parameters to driver Johannes Berg
  2012-11-06 12:23 ` [PATCH 0/2] mac80211: client-side P2P powersave Johannes Berg
  2 siblings, 0 replies; 4+ messages in thread
From: Johannes Berg @ 2012-11-05 14:40 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg

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

Parsing the P2P attributes can be tricky as their
contents can be split across multiple (vendor) IEs.
Thus, it's not possible to parse them like IEs (by
returning a pointer to the data.) Instead, provide
a function that copies the attribute data into a
caller-provided buffer and returns the size needed
(useful in case the buffer was too small.)

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 include/net/cfg80211.h | 19 ++++++++++
 net/wireless/util.c    | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 118 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 83a2c82..ae6d5e5 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -3623,6 +3623,25 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate);
  */
 void cfg80211_unregister_wdev(struct wireless_dev *wdev);
 
+/**
+ * cfg80211_get_p2p_attr - find and copy a P2P attribute from IE buffer
+ * @ies: the input IE buffer
+ * @len: the input length
+ * @attr: the attribute ID to find
+ * @buf: output buffer, can be %NULL if the data isn't needed, e.g.
+ *	if the function is only called to get the needed buffer size
+ * @bufsize: size of the output buffer
+ *
+ * The function finds a given P2P attribute in the (vendor) IEs and
+ * copies its contents to the given buffer.
+ *
+ * The return value is a negative error code (-%EILSEQ or -%ENOENT) if
+ * the data is malformed or the attribute can't be found (respectively),
+ * or the length of the found attribute (which can be zero).
+ */
+unsigned int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len,
+				   u8 attr, u8 *buf, unsigned int bufsize);
+
 /* Logging, debugging and troubleshooting/diagnostic helpers. */
 
 /* wiphy_printk helpers, similar to dev_printk */
diff --git a/net/wireless/util.c b/net/wireless/util.c
index cf11239..2964223 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -980,6 +980,105 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate)
 }
 EXPORT_SYMBOL(cfg80211_calculate_bitrate);
 
+unsigned int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len,
+				   u8 attr, u8 *buf, unsigned int bufsize)
+{
+	u8 *out = buf;
+	u16 attr_remaining = 0;
+	bool desired_attr = false;
+	u16 desired_len = 0;
+
+	while (len > 0) {
+		unsigned int iedatalen;
+		unsigned int copy;
+		const u8 *iedata;
+
+		if (len < 2)
+			return -EILSEQ;
+		iedatalen = ies[1];
+		if (iedatalen + 2 > len)
+			return -EILSEQ;
+
+		if (ies[0] != WLAN_EID_VENDOR_SPECIFIC)
+			goto cont;
+
+		if (iedatalen < 4)
+			goto cont;
+
+		iedata = ies + 2;
+
+		/* check WFA OUI, P2P subtype */
+		if (iedata[0] != 0x50 || iedata[1] != 0x6f ||
+		    iedata[2] != 0x9a || iedata[3] != 0x09)
+			goto cont;
+
+		iedatalen -= 4;
+		iedata += 4;
+
+		/* check attribute continuation into this IE */
+		copy = min_t(unsigned int, attr_remaining, iedatalen);
+		if (copy && desired_attr) {
+			desired_len += copy;
+			if (out) {
+				memcpy(out, iedata, min(bufsize, copy));
+				out += min(bufsize, copy);
+				bufsize -= min(bufsize, copy);
+			}
+
+
+			if (copy == attr_remaining)
+				return desired_len;
+		}
+
+		attr_remaining -= copy;
+		if (attr_remaining)
+			goto cont;
+
+		iedatalen -= copy;
+		iedata += copy;
+
+		while (iedatalen > 0) {
+			u16 attr_len;
+
+			/* P2P attribute ID & size must fit */
+			if (iedatalen < 3)
+				return -EILSEQ;
+			desired_attr = iedata[0] == attr;
+			attr_len = get_unaligned_le16(iedata + 1);
+			iedatalen -= 3;
+			iedata += 3;
+
+			copy = min_t(unsigned int, attr_len, iedatalen);
+
+			if (desired_attr) {
+				desired_len += copy;
+				if (out) {
+					memcpy(out, iedata, min(bufsize, copy));
+					out += min(bufsize, copy);
+					bufsize -= min(bufsize, copy);
+				}
+
+				if (copy == attr_len)
+					return desired_len;
+			}
+
+			iedata += copy;
+			iedatalen -= copy;
+			attr_remaining = attr_len - copy;
+		}
+
+ cont:
+		len -= ies[1] + 2;
+		ies += ies[1] + 2;
+	}
+
+	if (attr_remaining && desired_attr)
+		return -EILSEQ;
+
+	return -ENOENT;
+}
+EXPORT_SYMBOL(cfg80211_get_p2p_attr);
+
 bool ieee80211_operating_class_to_band(u8 operating_class,
 				       enum ieee80211_band *band)
 {
-- 
1.8.0


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

* [PATCH 2/2] mac80211: pass P2P powersave parameters to driver
  2012-11-05 14:40 [PATCH 0/2] mac80211: client-side P2P powersave Johannes Berg
  2012-11-05 14:40 ` [PATCH 1/2] wireless: add utility function to get P2P attribute Johannes Berg
@ 2012-11-05 14:40 ` Johannes Berg
  2012-11-06 12:23 ` [PATCH 0/2] mac80211: client-side P2P powersave Johannes Berg
  2 siblings, 0 replies; 4+ messages in thread
From: Johannes Berg @ 2012-11-05 14:40 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg

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

While connected to a GO, parse the P2P NoA attribute
and pass the CT Window and opportunistic powersave
parameters to the driver.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 include/net/mac80211.h     |  7 +++++++
 net/mac80211/ieee80211_i.h |  2 ++
 net/mac80211/mlme.c        | 40 ++++++++++++++++++++++++++++++++++++++++
 net/mac80211/trace.h       |  4 ++++
 4 files changed, 53 insertions(+)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index dfa589b..23803ad 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -208,6 +208,8 @@ struct ieee80211_chanctx_conf {
  * @BSS_CHANGED_AP_PROBE_RESP: Probe Response changed for this BSS (AP mode)
  * @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)
  */
 enum ieee80211_bss_change {
 	BSS_CHANGED_ASSOC		= 1<<0,
@@ -229,6 +231,7 @@ enum ieee80211_bss_change {
 	BSS_CHANGED_AP_PROBE_RESP	= 1<<16,
 	BSS_CHANGED_PS			= 1<<17,
 	BSS_CHANGED_TXPOWER		= 1<<18,
+	BSS_CHANGED_P2P_PS		= 1<<19,
 
 	/* when adding here, make sure to change ieee80211_reconfig */
 };
@@ -312,6 +315,8 @@ enum ieee80211_rssi_event {
  * @ssid_len: Length of SSID given in @ssid.
  * @hidden_ssid: The SSID of the current vif is hidden. Only valid in AP-mode.
  * @txpower: TX power in dBm
+ * @p2p_ctwindow: P2P CTWindow, only for P2P client interfaces
+ * @p2p_oppps: P2P opportunistic PS is enabled
  */
 struct ieee80211_bss_conf {
 	const u8 *bssid;
@@ -345,6 +350,8 @@ struct ieee80211_bss_conf {
 	size_t ssid_len;
 	bool hidden_ssid;
 	int txpower;
+	u8 p2p_ctwindow;
+	bool p2p_oppps;
 };
 
 /**
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 37c08d3..904b4d8 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -473,6 +473,8 @@ struct ieee80211_if_managed {
 
 	u8 use_4addr;
 
+	u8 p2p_noa_index;
+
 	/* Signal strength from the last Beacon frame in the current BSS. */
 	int last_beacon_signal;
 
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 35afbbc..856e562 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1364,6 +1364,22 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
 
 	sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE;
 
+	if (sdata->vif.p2p) {
+		u8 noa[2];
+		int ret;
+
+		ret = cfg80211_get_p2p_attr(cbss->information_elements,
+					    cbss->len_information_elements,
+					    IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
+					    noa, sizeof(noa));
+		if (ret >= 2) {
+			bss_conf->p2p_oppps = noa[1] & 0x80;
+			bss_conf->p2p_ctwindow = noa[1] & 0x7f;
+			bss_info_changed |= BSS_CHANGED_P2P_PS;
+			sdata->u.mgd.p2p_noa_index = noa[0];
+		}
+	}
+
 	/* just to be sure */
 	ieee80211_stop_poll(sdata);
 
@@ -1486,6 +1502,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
 	changed |= BSS_CHANGED_ASSOC;
 	sdata->vif.bss_conf.assoc = false;
 
+	sdata->vif.bss_conf.p2p_ctwindow = 0;
+	sdata->vif.bss_conf.p2p_oppps = false;
+
 	/* on the next assoc, re-program HT parameters */
 	memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa));
 	memset(&ifmgd->ht_capa_mask, 0, sizeof(ifmgd->ht_capa_mask));
@@ -2617,6 +2636,27 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
 		}
 	}
 
+	if (sdata->vif.p2p) {
+		u8 noa[2];
+		int ret;
+
+		ret = cfg80211_get_p2p_attr(mgmt->u.beacon.variable,
+					    len - baselen,
+					    IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
+					    noa, sizeof(noa));
+		if (ret >= 2 && sdata->u.mgd.p2p_noa_index != noa[0]) {
+			bss_conf->p2p_oppps = noa[1] & 0x80;
+			bss_conf->p2p_ctwindow = noa[1] & 0x7f;
+			changed |= BSS_CHANGED_P2P_PS;
+			sdata->u.mgd.p2p_noa_index = noa[0];
+			/*
+			 * make sure we update all information, the CRC
+			 * mechanism doesn't look at P2P attributes.
+			 */
+			ifmgd->beacon_crc_valid = false;
+		}
+	}
+
 	if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid)
 		return;
 	ifmgd->beacon_crc = ncrc;
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index eeebbd9..7794e53 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -343,6 +343,8 @@ TRACE_EVENT(drv_bss_info_changed,
 		__dynamic_array(u8, ssid, info->ssid_len);
 		__field(bool, hidden_ssid);
 		__field(int, txpower)
+		__field(u8, p2p_ctwindow)
+		__field(bool, p2p_oppps)
 	),
 
 	TP_fast_assign(
@@ -378,6 +380,8 @@ TRACE_EVENT(drv_bss_info_changed,
 		memcpy(__get_dynamic_array(ssid), info->ssid, info->ssid_len);
 		__entry->hidden_ssid = info->hidden_ssid;
 		__entry->txpower = info->txpower;
+		__entry->p2p_ctwindow = info->p2p_ctwindow;
+		__entry->p2p_oppps = info->p2p_oppps;
 	),
 
 	TP_printk(
-- 
1.8.0


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

* Re: [PATCH 0/2] mac80211: client-side P2P powersave
  2012-11-05 14:40 [PATCH 0/2] mac80211: client-side P2P powersave Johannes Berg
  2012-11-05 14:40 ` [PATCH 1/2] wireless: add utility function to get P2P attribute Johannes Berg
  2012-11-05 14:40 ` [PATCH 2/2] mac80211: pass P2P powersave parameters to driver Johannes Berg
@ 2012-11-06 12:23 ` Johannes Berg
  2 siblings, 0 replies; 4+ messages in thread
From: Johannes Berg @ 2012-11-06 12:23 UTC (permalink / raw)
  To: linux-wireless

On Mon, 2012-11-05 at 15:40 +0100, Johannes Berg wrote:
> Implement passing the P2P powersave parameters (except NoA
> schedules) to the mac80211 hardware driver. To do this, I
> introduced a generic function to get a copy of some P2P
> attribute into a buffer, I did it that way because of the
> potential for fragmentation into multiple IEs.
> 
> The only change over the RFC is that I now use the correct
> attribute ID definition from Arend's patch.

Applied both.

johannes


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

end of thread, other threads:[~2012-11-06 12:22 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-11-05 14:40 [PATCH 0/2] mac80211: client-side P2P powersave Johannes Berg
2012-11-05 14:40 ` [PATCH 1/2] wireless: add utility function to get P2P attribute Johannes Berg
2012-11-05 14:40 ` [PATCH 2/2] mac80211: pass P2P powersave parameters to driver Johannes Berg
2012-11-06 12:23 ` [PATCH 0/2] mac80211: client-side P2P powersave Johannes Berg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.