mirror of https://gitee.com/openkylin/linux.git
mac80211: handle SMPS action frames
When a peer changes SMPS state we should update rate control so it doesn't have to detect it by itself. It can't detect "dynamic" mode anyway since that just requires rts-cts handshaking. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
645d35902c
commit
1d8d3dec5f
|
@ -3502,9 +3502,12 @@ void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn);
|
|||
*
|
||||
* @IEEE80211_RC_HT_CHANGED: The HT parameters of the operating channel have
|
||||
* changed, rate control algorithm can update its internal state if needed.
|
||||
* @IEEE80211_RC_SMPS_CHANGED: The SMPS state of the station changed, the rate
|
||||
* control algorithm needs to adjust accordingly.
|
||||
*/
|
||||
enum rate_control_changed {
|
||||
IEEE80211_RC_HT_CHANGED = BIT(0)
|
||||
IEEE80211_RC_HT_CHANGED = BIT(0),
|
||||
IEEE80211_RC_SMPS_CHANGED = BIT(1),
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "wpa.h"
|
||||
#include "tkip.h"
|
||||
#include "wme.h"
|
||||
#include "rate.h"
|
||||
|
||||
/*
|
||||
* monitor mode reception
|
||||
|
@ -2233,6 +2234,63 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
|
|||
return RX_DROP_UNUSABLE;
|
||||
|
||||
switch (mgmt->u.action.category) {
|
||||
case WLAN_CATEGORY_HT:
|
||||
/* reject HT action frames from stations not supporting HT */
|
||||
if (!rx->sta->sta.ht_cap.ht_supported)
|
||||
goto invalid;
|
||||
|
||||
if (sdata->vif.type != NL80211_IFTYPE_STATION &&
|
||||
sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
|
||||
sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
|
||||
sdata->vif.type != NL80211_IFTYPE_AP &&
|
||||
sdata->vif.type != NL80211_IFTYPE_ADHOC)
|
||||
break;
|
||||
|
||||
/* verify action & smps_control are present */
|
||||
if (len < IEEE80211_MIN_ACTION_SIZE + 2)
|
||||
goto invalid;
|
||||
|
||||
switch (mgmt->u.action.u.ht_smps.action) {
|
||||
case WLAN_HT_ACTION_SMPS: {
|
||||
struct ieee80211_supported_band *sband;
|
||||
u8 smps;
|
||||
|
||||
/* convert to HT capability */
|
||||
switch (mgmt->u.action.u.ht_smps.smps_control) {
|
||||
case WLAN_HT_SMPS_CONTROL_DISABLED:
|
||||
smps = WLAN_HT_CAP_SM_PS_DISABLED;
|
||||
break;
|
||||
case WLAN_HT_SMPS_CONTROL_STATIC:
|
||||
smps = WLAN_HT_CAP_SM_PS_STATIC;
|
||||
break;
|
||||
case WLAN_HT_SMPS_CONTROL_DYNAMIC:
|
||||
smps = WLAN_HT_CAP_SM_PS_DYNAMIC;
|
||||
break;
|
||||
default:
|
||||
goto invalid;
|
||||
}
|
||||
smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT;
|
||||
|
||||
/* if no change do nothing */
|
||||
if ((rx->sta->sta.ht_cap.cap &
|
||||
IEEE80211_HT_CAP_SM_PS) == smps)
|
||||
goto handled;
|
||||
|
||||
rx->sta->sta.ht_cap.cap &= ~IEEE80211_HT_CAP_SM_PS;
|
||||
rx->sta->sta.ht_cap.cap |= smps;
|
||||
|
||||
sband = rx->local->hw.wiphy->bands[status->band];
|
||||
|
||||
rate_control_rate_update(local, sband, rx->sta,
|
||||
IEEE80211_RC_SMPS_CHANGED,
|
||||
local->_oper_channel_type);
|
||||
goto handled;
|
||||
}
|
||||
default:
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
break;
|
||||
case WLAN_CATEGORY_BACK:
|
||||
if (sdata->vif.type != NL80211_IFTYPE_STATION &&
|
||||
sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
|
||||
|
|
Loading…
Reference in New Issue