Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 183293
b: refs/heads/master
c: 0f78231
h: refs/heads/master
i:
  183291: 825cc62
v: v3
  • Loading branch information
Johannes Berg authored and John W. Linville committed Dec 22, 2009
1 parent 9e1b63e commit fe4c197
Show file tree
Hide file tree
Showing 13 changed files with 519 additions and 13 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 18974b5b0b5e758d416c550553b143e5c8038281
refs/heads/master: 0f78231bffb868a30e8533aace142213266bb811
24 changes: 20 additions & 4 deletions trunk/drivers/net/wireless/mac80211_hwsim.c
Original file line number Diff line number Diff line change
Expand Up @@ -618,12 +618,26 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
{
struct mac80211_hwsim_data *data = hw->priv;
struct ieee80211_conf *conf = &hw->conf;

printk(KERN_DEBUG "%s:%s (freq=%d idle=%d ps=%d)\n",
static const char *chantypes[4] = {
[NL80211_CHAN_NO_HT] = "noht",
[NL80211_CHAN_HT20] = "ht20",
[NL80211_CHAN_HT40MINUS] = "ht40-",
[NL80211_CHAN_HT40PLUS] = "ht40+",
};
static const char *smps_modes[IEEE80211_SMPS_NUM_MODES] = {
[IEEE80211_SMPS_AUTOMATIC] = "auto",
[IEEE80211_SMPS_OFF] = "off",
[IEEE80211_SMPS_STATIC] = "static",
[IEEE80211_SMPS_DYNAMIC] = "dynamic",
};

printk(KERN_DEBUG "%s:%s (freq=%d/%s idle=%d ps=%d smps=%s)\n",
wiphy_name(hw->wiphy), __func__,
conf->channel->center_freq,
chantypes[conf->channel_type],
!!(conf->flags & IEEE80211_CONF_IDLE),
!!(conf->flags & IEEE80211_CONF_PS));
!!(conf->flags & IEEE80211_CONF_PS),
smps_modes[conf->smps_mode]);

data->idle = !!(conf->flags & IEEE80211_CONF_IDLE);

Expand Down Expand Up @@ -1082,7 +1096,9 @@ static int __init init_mac80211_hwsim(void)
BIT(NL80211_IFTYPE_MESH_POINT);

hw->flags = IEEE80211_HW_MFP_CAPABLE |
IEEE80211_HW_SIGNAL_DBM;
IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_SUPPORTS_STATIC_SMPS |
IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS;

/* ask mac80211 to reserve space for magic */
hw->vif_data_size = sizeof(struct hwsim_vif_priv);
Expand Down
25 changes: 24 additions & 1 deletion trunk/include/linux/ieee80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,10 @@ struct ieee80211_mgmt {
u8 action;
u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN];
} __attribute__ ((packed)) sa_query;
struct {
u8 action;
u8 smps_control;
} __attribute__ ((packed)) ht_smps;
} u;
} __attribute__ ((packed)) action;
} u;
Expand Down Expand Up @@ -824,6 +828,7 @@ struct ieee80211_ht_cap {
#define IEEE80211_HT_CAP_LDPC_CODING 0x0001
#define IEEE80211_HT_CAP_SUP_WIDTH_20_40 0x0002
#define IEEE80211_HT_CAP_SM_PS 0x000C
#define IEEE80211_HT_CAP_SM_PS_SHIFT 2
#define IEEE80211_HT_CAP_GRN_FLD 0x0010
#define IEEE80211_HT_CAP_SGI_20 0x0020
#define IEEE80211_HT_CAP_SGI_40 0x0040
Expand All @@ -839,6 +844,7 @@ struct ieee80211_ht_cap {
/* 802.11n HT capability AMPDU settings (for ampdu_params_info) */
#define IEEE80211_HT_AMPDU_PARM_FACTOR 0x03
#define IEEE80211_HT_AMPDU_PARM_DENSITY 0x1C
#define IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT 2

/*
* Maximum length of AMPDU that the STA can receive.
Expand Down Expand Up @@ -922,12 +928,17 @@ struct ieee80211_ht_info {
#define IEEE80211_MAX_AMPDU_BUF 0x40


/* Spatial Multiplexing Power Save Modes */
/* Spatial Multiplexing Power Save Modes (for capability) */
#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

/* for SM power control field lower two bits */
#define WLAN_HT_SMPS_CONTROL_DISABLED 0
#define WLAN_HT_SMPS_CONTROL_STATIC 1
#define WLAN_HT_SMPS_CONTROL_DYNAMIC 3

/* Authentication algorithms */
#define WLAN_AUTH_OPEN 0
#define WLAN_AUTH_SHARED_KEY 1
Expand Down Expand Up @@ -1150,6 +1161,18 @@ enum ieee80211_spectrum_mgmt_actioncode {
WLAN_ACTION_SPCT_CHL_SWITCH = 4,
};

/* HT action codes */
enum ieee80211_ht_actioncode {
WLAN_HT_ACTION_NOTIFY_CHANWIDTH = 0,
WLAN_HT_ACTION_SMPS = 1,
WLAN_HT_ACTION_PSMP = 2,
WLAN_HT_ACTION_PCO_PHASE = 3,
WLAN_HT_ACTION_CSI = 4,
WLAN_HT_ACTION_NONCOMPRESSED_BF = 5,
WLAN_HT_ACTION_COMPRESSED_BF = 6,
WLAN_HT_ACTION_ASEL_IDX_FEEDBACK = 7,
};

/* Security key length */
enum ieee80211_key_len {
WLAN_KEY_LEN_WEP40 = 5,
Expand Down
59 changes: 59 additions & 0 deletions trunk/include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -597,8 +597,10 @@ enum ieee80211_conf_flags {
* @IEEE80211_CONF_CHANGE_CHANNEL: the channel/channel_type changed
* @IEEE80211_CONF_CHANGE_RETRY_LIMITS: retry limits changed
* @IEEE80211_CONF_CHANGE_IDLE: Idle flag changed
* @IEEE80211_CONF_CHANGE_SMPS: Spatial multiplexing powersave mode changed
*/
enum ieee80211_conf_changed {
IEEE80211_CONF_CHANGE_SMPS = BIT(1),
IEEE80211_CONF_CHANGE_LISTEN_INTERVAL = BIT(2),
IEEE80211_CONF_CHANGE_MONITOR = BIT(3),
IEEE80211_CONF_CHANGE_PS = BIT(4),
Expand All @@ -608,6 +610,21 @@ enum ieee80211_conf_changed {
IEEE80211_CONF_CHANGE_IDLE = BIT(8),
};

/**
* enum ieee80211_smps_mode - spatial multiplexing power save mode
*
* @
*/
enum ieee80211_smps_mode {
IEEE80211_SMPS_AUTOMATIC,
IEEE80211_SMPS_OFF,
IEEE80211_SMPS_STATIC,
IEEE80211_SMPS_DYNAMIC,

/* keep last */
IEEE80211_SMPS_NUM_MODES,
};

/**
* struct ieee80211_conf - configuration of the device
*
Expand Down Expand Up @@ -636,6 +653,10 @@ enum ieee80211_conf_changed {
* @short_frame_max_tx_count: Maximum number of transmissions for a "short"
* frame, called "dot11ShortRetryLimit" in 802.11, but actually means the
* number of transmissions not the number of retries
*
* @smps_mode: spatial multiplexing powersave mode; note that
* %IEEE80211_SMPS_STATIC is used when the device is not
* configured for an HT channel
*/
struct ieee80211_conf {
u32 flags;
Expand All @@ -648,6 +669,7 @@ struct ieee80211_conf {

struct ieee80211_channel *channel;
enum nl80211_channel_type channel_type;
enum ieee80211_smps_mode smps_mode;
};

/**
Expand Down Expand Up @@ -930,6 +952,16 @@ enum ieee80211_tkip_key_type {
* @IEEE80211_HW_BEACON_FILTER:
* Hardware supports dropping of irrelevant beacon frames to
* avoid waking up cpu.
*
* @IEEE80211_HW_SUPPORTS_STATIC_SMPS:
* Hardware supports static spatial multiplexing powersave,
* ie. can turn off all but one chain even on HT connections
* that should be using more chains.
*
* @IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS:
* Hardware supports dynamic spatial multiplexing powersave,
* ie. can turn off all but one chain and then wake the rest
* up as required after, for example, rts/cts handshake.
*/
enum ieee80211_hw_flags {
IEEE80211_HW_HAS_RATE_CONTROL = 1<<0,
Expand All @@ -947,6 +979,8 @@ enum ieee80211_hw_flags {
IEEE80211_HW_SUPPORTS_DYNAMIC_PS = 1<<12,
IEEE80211_HW_MFP_CAPABLE = 1<<13,
IEEE80211_HW_BEACON_FILTER = 1<<14,
IEEE80211_HW_SUPPORTS_STATIC_SMPS = 1<<15,
IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS = 1<<16,
};

/**
Expand Down Expand Up @@ -1214,6 +1248,31 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
* signal strength threshold checking.
*/

/**
* DOC: Spatial multiplexing power save
*
* SMPS (Spatial multiplexing power save) is a mechanism to conserve
* power in an 802.11n implementation. For details on the mechanism
* and rationale, please refer to 802.11 (as amended by 802.11n-2009)
* "11.2.3 SM power save".
*
* The mac80211 implementation is capable of sending action frames
* to update the AP about the station's SMPS mode, and will instruct
* the driver to enter the specific mode. It will also announce the
* requested SMPS mode during the association handshake. Hardware
* support for this feature is required, and can be indicated by
* hardware flags.
*
* The default mode will be "automatic", which nl80211/cfg80211
* defines to be dynamic SMPS in (regular) powersave, and SMPS
* turned off otherwise.
*
* To support this feature, the driver must set the appropriate
* hardware support flags, and handle the SMPS flag to the config()
* operation. It will then with this mechanism be instructed to
* enter the requested SMPS mode while associated to an HT AP.
*/

/**
* DOC: Frame filtering
*
Expand Down
49 changes: 49 additions & 0 deletions trunk/net/mac80211/cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -1318,6 +1318,50 @@ static int ieee80211_testmode_cmd(struct wiphy *wiphy, void *data, int len)
}
#endif

int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
enum ieee80211_smps_mode smps_mode)
{
const u8 *ap;
enum ieee80211_smps_mode old_req;
int err;

old_req = sdata->u.mgd.req_smps;
sdata->u.mgd.req_smps = smps_mode;

if (old_req == smps_mode &&
smps_mode != IEEE80211_SMPS_AUTOMATIC)
return 0;

/*
* If not associated, or current association is not an HT
* association, there's no need to send an action frame.
*/
if (!sdata->u.mgd.associated ||
sdata->local->oper_channel_type == NL80211_CHAN_NO_HT) {
mutex_lock(&sdata->local->iflist_mtx);
ieee80211_recalc_smps(sdata->local, sdata);
mutex_unlock(&sdata->local->iflist_mtx);
return 0;
}

ap = sdata->u.mgd.associated->cbss.bssid;

if (smps_mode == IEEE80211_SMPS_AUTOMATIC) {
if (sdata->u.mgd.powersave)
smps_mode = IEEE80211_SMPS_DYNAMIC;
else
smps_mode = IEEE80211_SMPS_OFF;
}

/* send SM PS frame to AP */
err = ieee80211_send_smps_action(sdata, smps_mode,
ap, ap);
if (err)
sdata->u.mgd.req_smps = old_req;

return err;
}

static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
bool enabled, int timeout)
{
Expand All @@ -1335,6 +1379,11 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
sdata->u.mgd.powersave = enabled;
conf->dynamic_ps_timeout = timeout;

/* no change, but if automatic follow powersave */
mutex_lock(&sdata->u.mgd.mtx);
__ieee80211_request_smps(sdata, sdata->u.mgd.req_smps);
mutex_unlock(&sdata->u.mgd.mtx);

if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);

Expand Down
Loading

0 comments on commit fe4c197

Please sign in to comment.