From: Tomas Winkler <tomas.winkler@intel.com>
To: linville@tuxdriver.com, johannes@sipsolutions.net, yi.zhu@intel.com
Cc: linux-wireless@vger.kernel.org,
Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Subject: [PATCH 1/1] mac80211: send action frame when toggling SM PS mode
Date: Sun, 28 Sep 2008 19:14:53 +0300 [thread overview]
Message-ID: <1222618493-19019-1-git-send-email-tomas.winkler@intel.com> (raw)
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
This patch makes mac80211 able to send action frames when toggling
(SM PS) Spacial Multiplexing Power Save mode.
Example:
1.
Low lever driver may close some of RX chains in power save mode
and needs to announce to AP that a RTS frame is need in order to wake all
RX chains, on other hand SM PS can be disabled on CAM mode or if HW is able
to wake all chains without RTS frame.
2.
iwlwifi can call this function when it detects that only
one antenna can effectively receive then MS PS mode is set to STATIC and
AP is asked not to send MIMO rates packets.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
include/linux/ieee80211.h | 14 +++++++-
include/net/mac80211.h | 10 ++++++
net/mac80211/ht.c | 79 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 102 insertions(+), 1 deletions(-)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 14126bc..c037b40 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -623,6 +623,10 @@ struct ieee80211_mgmt {
} __attribute__((packed)) addba_resp;
struct{
u8 action_code;
+ u8 ps_ctrl;
+ } __attribute__((packed)) sm_ps;
+ struct{
+ u8 action_code;
__le16 params;
__le16 reason_code;
} __attribute__((packed)) delba;
@@ -759,12 +763,14 @@ struct ieee80211_ht_addt_info {
#define IEEE80211_MIN_AMPDU_BUF 0x8
#define IEEE80211_MAX_AMPDU_BUF 0x40
-
/* Spatial Multiplexing Power Save Modes */
#define WLAN_HT_CAP_SM_PS_STATIC 0
#define WLAN_HT_CAP_SM_PS_DYNAMIC 1
#define WLAN_HT_CAP_SM_PS_INVALID 2
#define WLAN_HT_CAP_SM_PS_DISABLED 3
+/* Spatial Multiplexing control bits */
+#define IEEE80211_SM_PS_ENABLE 0x1
+#define IEEE80211_SM_PS_DYNAMIC 0x2
/* Authentication algorithms */
#define WLAN_AUTH_OPEN 0
@@ -963,6 +969,7 @@ enum ieee80211_category {
WLAN_CATEGORY_SPECTRUM_MGMT = 0,
WLAN_CATEGORY_QOS = 1,
WLAN_CATEGORY_DLS = 2,
+ WLAN_CATEGORY_HT = 7,
WLAN_CATEGORY_BACK = 3,
WLAN_CATEGORY_WMM = 17,
};
@@ -976,6 +983,11 @@ enum ieee80211_spectrum_mgmt_actioncode {
WLAN_ACTION_SPCT_CHL_SWITCH = 4,
};
+/* HT action code */
+enum ieee80211_ht_actioncode {
+ WLAN_ACTION_SM_PS = 1,
+};
+
/* BACK action code */
enum ieee80211_back_actioncode {
WLAN_ACTION_ADDBA_REQ = 0,
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index f5f5b1f..f15e495 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1868,4 +1868,14 @@ rate_lowest_index(struct ieee80211_supported_band *sband,
int ieee80211_rate_control_register(struct rate_control_ops *ops);
void ieee80211_rate_control_unregister(struct rate_control_ops *ops);
+/**
+ * ieee80211_send_sm_ps_update - send SM Power Save Action frame
+ * @hw: pointer as obtained from ieee80211_alloc_hw().
+ * @new_mode: new SM Power Save mode WLAN_HT_CAP_SM_PS_*
+ *
+ * This function must be called by low level driver to inform AP about change
+ * in SM Power Save state.
+ */
+void ieee80211_sm_ps_update(struct ieee80211_hw *hw, u8 new_mode);
+
#endif /* MAC80211_H */
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index dc7d9a3..e468137 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -990,3 +990,82 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
WLAN_BACK_RECIPIENT);
}
}
+
+static void ieee80211_send_sm_ps(struct ieee80211_sub_if_data *sdata, u8 mode)
+{
+ struct ieee80211_local *local = sdata->local;
+ struct ieee80211_mgmt *mgmt;
+ struct sk_buff *skb;
+ DECLARE_MAC_BUF(mac);
+
+ struct ieee80211_if_sta *ifsta = &sdata->u.sta;
+ struct net_device *dev = sdata->dev;
+
+ /* Implemented for STA only */
+ if (sdata->vif.type != NL80211_IFTYPE_STATION)
+ return;
+
+ skb = dev_alloc_skb(sizeof(*mgmt) +
+ local->hw.extra_tx_headroom);
+
+ if (!skb) {
+ printk(KERN_ERR "%s: failed to allocate buffer "
+ "for SM_PS frame\n", dev->name);
+ return;
+ }
+ skb_reserve(skb, local->hw.extra_tx_headroom);
+ mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
+ memset(mgmt, 0, 24);
+ memcpy(mgmt->da, ifsta->bssid, ETH_ALEN);
+ memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN);
+ memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
+
+ mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+ IEEE80211_STYPE_ACTION);
+
+ skb_put(skb, 1 + sizeof(mgmt->u.action.u.sm_ps));
+
+ mgmt->u.action.category = WLAN_CATEGORY_HT;
+ mgmt->u.action.u.sm_ps.action_code = WLAN_ACTION_SM_PS;
+
+ switch (mode) {
+
+ case WLAN_HT_CAP_SM_PS_DISABLED:
+ mgmt->u.action.u.sm_ps.ps_ctrl &=
+ ~(IEEE80211_SM_PS_ENABLE |
+ IEEE80211_SM_PS_DYNAMIC);
+ break;
+ case WLAN_HT_CAP_SM_PS_DYNAMIC:
+ mgmt->u.action.u.sm_ps.ps_ctrl |=
+ IEEE80211_SM_PS_ENABLE |
+ IEEE80211_SM_PS_DYNAMIC;
+ break;
+ case WLAN_HT_CAP_SM_PS_STATIC:
+ mgmt->u.action.u.sm_ps.ps_ctrl |=
+ IEEE80211_SM_PS_ENABLE;
+ mgmt->u.action.u.sm_ps.ps_ctrl &=
+ ~IEEE80211_SM_PS_DYNAMIC;
+ break;
+ default:
+ printk(KERN_DEBUG "%s: invalid power save mode\n",
+ dev->name);
+ WARN_ON(1);
+ }
+
+ if (ifsta->flags & IEEE80211_STA_ASSOCIATED)
+ ieee80211_tx_skb(sdata, skb, 0);
+}
+
+void ieee80211_sm_ps_update(struct ieee80211_hw *hw, u8 new_mode)
+{
+ struct ieee80211_sub_if_data *sdata;
+ struct ieee80211_local *local = hw_to_local(hw);
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+ ieee80211_send_sm_ps(sdata, new_mode);
+ }
+ rcu_read_unlock();
+}
+EXPORT_SYMBOL(ieee80211_sm_ps_update);
+
--
1.5.4.3
---------------------------------------------------------------------
Intel Israel (74) Limited
This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.
next reply other threads:[~2008-09-28 16:14 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-09-28 16:14 Tomas Winkler [this message]
2008-09-28 16:19 ` [PATCH 1/1] mac80211: send action frame when toggling SM PS mode Johannes Berg
2008-09-28 16:24 ` Tomas Winkler
2008-09-28 16:26 ` Johannes Berg
2008-09-28 16:39 ` Tomas Winkler
2008-09-28 17:21 ` Johannes Berg
2008-10-01 10:40 ` Tomas Winkler
2008-10-01 11:14 ` Luis R. Rodriguez
2008-10-01 18:21 ` Johannes Berg
2008-10-01 18:39 ` Luis R. Rodriguez
2008-10-01 18:20 ` Johannes Berg
2008-09-29 8:14 ` Luis R. Rodriguez
2008-09-29 8:33 ` Tomas Winkler
2008-09-29 14:44 ` John W. Linville
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1222618493-19019-1-git-send-email-tomas.winkler@intel.com \
--to=tomas.winkler@intel.com \
--cc=emmanuel.grumbach@intel.com \
--cc=johannes@sipsolutions.net \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@tuxdriver.com \
--cc=yi.zhu@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox