mac80211: enable spatial multiplexing powersave
Enable spatial multiplexing in mac80211 by telling the driver what to do and, where necessary, sending action frames to the AP to update the requested SMPS mode. Also includes a trivial implementation for hwsim that just logs the requested mode. For now, the userspace interface is in debugfs only, and let you toggle the requested mode at any time. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
committed by
John W. Linville
parent
18974b5b0b
commit
0f78231bff
@@ -134,6 +134,40 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_mgmt *mgmt = (void *) skb->data;
|
||||
struct ieee80211_local *local = sta->local;
|
||||
struct ieee80211_sub_if_data *sdata = sta->sdata;
|
||||
|
||||
if (ieee80211_is_action(mgmt->frame_control) &&
|
||||
sdata->vif.type == NL80211_IFTYPE_STATION &&
|
||||
mgmt->u.action.category == WLAN_CATEGORY_HT &&
|
||||
mgmt->u.action.u.ht_smps.action == WLAN_HT_ACTION_SMPS) {
|
||||
/*
|
||||
* This update looks racy, but isn't -- if we come
|
||||
* here we've definitely got a station that we're
|
||||
* talking to, and on a managed interface that can
|
||||
* only be the AP. And the only other place updating
|
||||
* this variable is before we're associated.
|
||||
*/
|
||||
switch (mgmt->u.action.u.ht_smps.smps_control) {
|
||||
case WLAN_HT_SMPS_CONTROL_DYNAMIC:
|
||||
sta->sdata->u.mgd.ap_smps = IEEE80211_SMPS_DYNAMIC;
|
||||
break;
|
||||
case WLAN_HT_SMPS_CONTROL_STATIC:
|
||||
sta->sdata->u.mgd.ap_smps = IEEE80211_SMPS_STATIC;
|
||||
break;
|
||||
case WLAN_HT_SMPS_CONTROL_DISABLED:
|
||||
default: /* shouldn't happen since we don't send that */
|
||||
sta->sdata->u.mgd.ap_smps = IEEE80211_SMPS_OFF;
|
||||
break;
|
||||
}
|
||||
|
||||
ieee80211_queue_work(&local->hw, &local->recalc_smps);
|
||||
}
|
||||
}
|
||||
|
||||
void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
{
|
||||
struct sk_buff *skb2;
|
||||
@@ -210,6 +244,10 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
rate_control_tx_status(local, sband, sta, skb);
|
||||
if (ieee80211_vif_is_mesh(&sta->sdata->vif))
|
||||
ieee80211s_update_metric(local, sta, skb);
|
||||
|
||||
if (!(info->flags & IEEE80211_TX_CTL_INJECTED) &&
|
||||
(info->flags & IEEE80211_TX_STAT_ACK))
|
||||
ieee80211_frame_acked(sta, skb);
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
|
Reference in New Issue
Block a user