* [RFC 1/7] mac80211: mesh power mode indication in QoS frames
@ 2011-10-21 8:36 Ivan Bezyazychnyy
2011-10-21 9:52 ` Johannes Berg
0 siblings, 1 reply; 4+ messages in thread
From: Ivan Bezyazychnyy @ 2011-10-21 8:36 UTC (permalink / raw)
To: linux-wireless
indicate non-peer mesh power mode in multicast and local
link-specific power mode in unicast QoS frames
Signed-off-by: Ivan Bezyazychnyy <ivan.bezyazychnyy@gmail.com>
---
include/linux/ieee80211.h | 3 ++
include/linux/nl80211.h | 29 ++++++++++++++++++++++++++
include/net/cfg80211.h | 2 +
net/mac80211/sta_info.h | 2 +
net/mac80211/tx.c | 50 ++++++++++++++++++++++++++++++++++++++++++++-
net/wireless/mesh.c | 1 +
6 files changed, 86 insertions(+), 1 deletions(-)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 48363c3..b206b94 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -133,6 +133,9 @@
/* Mesh Control 802.11s */
#define IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT 0x0100
+/* mesh power save level subfield mask */
+#define IEEE80211_QOS_CTL_PS_LEVEL 0x0200
+
/* U-APSD queue for WMM IEs sent by AP */
#define IEEE80211_WMM_IE_AP_QOSINFO_UAPSD (1<<7)
#define IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK 0x0f
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 8049bf7..001e9e3 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1915,6 +1915,35 @@ enum nl80211_mntr_flags {
};
/**
+ * enum nl80211_mesh_power_mode - mesh power save modes
+ *
+ * @__NL80211_MESH_POWER_INVALID - internal use
+ *
+ * @NL80211_MESH_POWER_ACTIVE - active mesh power mode, mesh STA
+ * in Awake state all the time
+ * @NL80211_MESH_POWER_LIGHT_SLEEP - light sleep mode, mesh STA
+ * alternate between Active and Doze states,
+ * mesh STA should listen to all the beacons
+ * @NL80211_MESH_POWER_DEEP_SLEEP - deep sleep mode, mesh STA
+ * alternates between Active and Doze states,
+ * may choose not listen to the beacons
+ *
+ * @__NL80211_MESH_POWER_AFTER_LAST - internal use
+ * @NL80211_MESH_POWER_MAX - highest possible power save level
+ */
+
+enum nl80211_mesh_power_mode {
+ __NL80211_MESH_POWER_INVALID,
+
+ NL80211_MESH_POWER_ACTIVE,
+ NL80211_MESH_POWER_LIGHT_SLEEP,
+ NL80211_MESH_POWER_DEEP_SLEEP,
+
+ __NL80211_MESH_POWER_AFTER_LAST,
+ NL80211_MESH_POWER_MAX = __NL80211_MESH_POWER_AFTER_LAST - 1
+};
+
+/**
* enum nl80211_meshconf_params - mesh configuration parameters
*
* Mesh configuration parameters. These can be changed while the mesh is
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 92cf1c2..e00e04e 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -765,6 +765,8 @@ struct mesh_config {
u16 dot11MeshMaxPeerLinks;
u8 dot11MeshMaxRetries;
u8 dot11MeshTTL;
+ /* non-peer mesh power save mode */
+ u8 power_mode;
/* ttl used in path selection information elements */
u8 element_ttl;
bool auto_open_plinks;
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 8c8ce05..8742668 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -250,6 +250,7 @@ struct sta_ampdu_mlme {
* @plink_retries: Retries in establishment
* @ignore_plink_timer: ignore the peer-link timer (used internally)
* @plink_state: peer link state
+ * @local_ps_mode: local link-specific power save mode
* @plink_timeout: timeout of peer link
* @plink_timer: peer link watch timer
* @plink_timer_was_running: used by suspend/resume to restore timers
@@ -338,6 +339,7 @@ struct sta_info {
bool ignore_plink_timer;
bool plink_timer_was_running;
enum nl80211_plink_state plink_state;
+ enum nl80211_mesh_power_mode local_ps_mode;
u32 plink_timeout;
struct timer_list plink_timer;
#endif
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 48bbb96..8f2bc51 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1033,6 +1033,48 @@ ieee80211_tx_h_calculate_duration(struct
ieee80211_tx_data *tx)
return TX_CONTINUE;
}
+#ifdef CONFIG_MAC80211_MESH
+static enum nl80211_mesh_power_mode
+ieee80211s_get_ps_mode(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_hdr *hdr)
+{
+ enum nl80211_mesh_power_mode pm = NL80211_MESH_POWER_ACTIVE;
+ struct mesh_path *mpath;
+
+ if (is_multicast_ether_addr(hdr->addr1)) {
+ pm = (enum nl80211_mesh_power_mode)
+ sdata->u.mesh.mshcfg.power_mode;
+ } else {
+ rcu_read_lock();
+ mpath = mesh_path_lookup(hdr->addr3, sdata);
+ if (mpath) {
+ pm = mpath->next_hop->local_ps_mode;
+ }
+ rcu_read_unlock();
+ }
+
+ return pm;
+}
+
+static void ieee80211_set_mesh_ps_fields(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_hdr *hdr)
+{
+ if (ieee80211_vif_is_mesh(&sdata->vif) &&
+ (ieee80211_is_data_qos(hdr->frame_control)
+ || ieee80211_is_qos_nullfunc(hdr->frame_control))) {
+ enum nl80211_mesh_power_mode
+ pm = ieee80211s_get_ps_mode(sdata, hdr);
+ if (pm != NL80211_MESH_POWER_ACTIVE) {
+ __le16 *qc = (__le16 *) ieee80211_get_qos_ctl(hdr);
+ hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
+ if (pm == NL80211_MESH_POWER_DEEP_SLEEP) {
+ *qc |= cpu_to_le16(IEEE80211_QOS_CTL_PS_LEVEL);
+ }
+ }
+ }
+}
+#endif /* CONFIG_MAC80211_MESH*/
+
/* actual transmit path */
static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx,
@@ -1437,6 +1479,9 @@ void ieee80211_xmit(struct ieee80211_sub_if_data
*sdata, struct sk_buff *skb)
}
ieee80211_set_qos_hdr(sdata, skb);
+#ifdef CONFIG_MAC80211_MESH
+ ieee80211_set_mesh_ps_fields(sdata, hdr);
+#endif /* CONFIG_MAC80211_MESH */
ieee80211_tx(sdata, skb, false);
rcu_read_unlock();
}
@@ -1887,7 +1932,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct
sk_buff *skb,
wme_sta = true;
/* receiver and we are QoS enabled, use a QoS type frame */
- if (wme_sta && local->hw.queues >= 4) {
+ if ((wme_sta && local->hw.queues >= 4) ||
+ (ieee80211_vif_is_mesh(&sdata->vif) &&
+ (ieee80211s_get_ps_mode(sdata, &hdr) !=
+ NL80211_MESH_POWER_ACTIVE))) {
fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
hdrlen += 2;
}
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 4423e64..5febd0b 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -52,6 +52,7 @@ const struct mesh_config default_mesh_config = {
.min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT,
.dot11MeshHWMPRannInterval = MESH_RANN_INTERVAL,
.dot11MeshGateAnnouncementProtocol = false,
+ .power_mode = NL80211_MESH_POWER_ACTIVE,
};
const struct mesh_setup default_mesh_setup = {
--
1.7.3.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [RFC 1/7] mac80211: mesh power mode indication in QoS frames
2011-10-21 8:36 [RFC 1/7] mac80211: mesh power mode indication in QoS frames Ivan Bezyazychnyy
@ 2011-10-21 9:52 ` Johannes Berg
2011-10-23 13:10 ` Ivan Bezyazychnyy
0 siblings, 1 reply; 4+ messages in thread
From: Johannes Berg @ 2011-10-21 9:52 UTC (permalink / raw)
To: Ivan Bezyazychnyy; +Cc: linux-wireless
On Fri, 2011-10-21 at 12:36 +0400, Ivan Bezyazychnyy wrote:
> +/* mesh power save level subfield mask */
> +#define IEEE80211_QOS_CTL_PS_LEVEL 0x0200
That looks like it could use a better name?
> --- a/include/linux/nl80211.h
Why is this in a mac80211 patch?
> --- a/include/net/cfg80211.h
> +++ b/include/net/cfg80211.h
> @@ -765,6 +765,8 @@ struct mesh_config {
> u16 dot11MeshMaxPeerLinks;
> u8 dot11MeshMaxRetries;
> u8 dot11MeshTTL;
> + /* non-peer mesh power save mode */
> + u8 power_mode;
Ditto.
> +#ifdef CONFIG_MAC80211_MESH
No ifdefs please. There's no need for these.
> ieee80211_set_qos_hdr(sdata, skb);
> +#ifdef CONFIG_MAC80211_MESH
> + ieee80211_set_mesh_ps_fields(sdata, hdr);
> +#endif /* CONFIG_MAC80211_MESH */
ditto.
> /* receiver and we are QoS enabled, use a QoS type frame */
> - if (wme_sta && local->hw.queues >= 4) {
> + if ((wme_sta && local->hw.queues >= 4) ||
> + (ieee80211_vif_is_mesh(&sdata->vif) &&
> + (ieee80211s_get_ps_mode(sdata, &hdr) !=
> + NL80211_MESH_POWER_ACTIVE))) {
> fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
This should not be necessary.
johannes
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFC 1/7] mac80211: mesh power mode indication in QoS frames
2011-10-21 9:52 ` Johannes Berg
@ 2011-10-23 13:10 ` Ivan Bezyazychnyy
2011-10-26 9:57 ` Johannes Berg
0 siblings, 1 reply; 4+ messages in thread
From: Ivan Bezyazychnyy @ 2011-10-23 13:10 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
On 21 October 2011 13:52, Johannes Berg <johannes@sipsolutions.net> wrote:
> On Fri, 2011-10-21 at 12:36 +0400, Ivan Bezyazychnyy wrote:
>
>> +/* mesh power save level subfield mask */
>> +#define IEEE80211_QOS_CTL_PS_LEVEL 0x0200
>
> That looks like it could use a better name?
Do you mean something like IEEE80211_QOS_CTL_MESH_POWER_SAVE_LEVEL?
The first half is similar to previous constants.
Thanks,
Ivan
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFC 1/7] mac80211: mesh power mode indication in QoS frames
2011-10-23 13:10 ` Ivan Bezyazychnyy
@ 2011-10-26 9:57 ` Johannes Berg
0 siblings, 0 replies; 4+ messages in thread
From: Johannes Berg @ 2011-10-26 9:57 UTC (permalink / raw)
To: Ivan Bezyazychnyy; +Cc: linux-wireless
On 10/23/2011 3:10 PM, Ivan Bezyazychnyy wrote:
> On 21 October 2011 13:52, Johannes Berg<johannes@sipsolutions.net> wrote:
>> On Fri, 2011-10-21 at 12:36 +0400, Ivan Bezyazychnyy wrote:
>>
>>> +/* mesh power save level subfield mask */
>>> +#define IEEE80211_QOS_CTL_PS_LEVEL 0x0200
>>
>> That looks like it could use a better name?
>
> Do you mean something like IEEE80211_QOS_CTL_MESH_POWER_SAVE_LEVEL?
> The first half is similar to previous constants.
Not really .. I mean, it's like you have two levels, 0 and 1, but you
say this is the level. Why not say this is the 1 level, and the 0 level
is implied otherwise?
For example, typically, if we have something like a bit in a field that
indicates the device is getting too hot, we'll call it
FOOBAR_DEVICE_TOO_HOT
and not
FOOBAR_DEVICE_TEMPERATURE_LEVEL
Basically I think that the constant name you have now tells me nothing
about what it means when the bit is set and I think it'd be better if it
did. That might not even be possible, but I think in that case you
really should add a comment, e.g.:
/*
* mesh power save level:
* set - the device is doing ...
* unset - the device is doing ...
*/
#define ...
johannes
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2011-10-26 17:22 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-10-21 8:36 [RFC 1/7] mac80211: mesh power mode indication in QoS frames Ivan Bezyazychnyy
2011-10-21 9:52 ` Johannes Berg
2011-10-23 13:10 ` Ivan Bezyazychnyy
2011-10-26 9:57 ` 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).