Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 171370
b: refs/heads/master
c: 3f3e037
h: refs/heads/master
v: v3
  • Loading branch information
Wey-Yi Guy authored and John W. Linville committed Nov 2, 2009
1 parent 93d742a commit 1cb9db5
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 11 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: fe1bcbfda77bf6fa3bbad8bf26b9e9ab23fbe345
refs/heads/master: 3f3e0376bb14ac7bfd8ac3e9824b2ad04d945e18
2 changes: 2 additions & 0 deletions trunk/drivers/net/wireless/iwlwifi/iwl-6000.c
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
.supports_idle = true,
.adv_thermal_throttle = true,
.support_ct_kill_exit = true,
.support_sm_ps = true,
};

struct iwl_cfg iwl6050_2abg_cfg = {
Expand Down Expand Up @@ -579,6 +580,7 @@ struct iwl_cfg iwl6050_3agn_cfg = {
.supports_idle = true,
.adv_thermal_throttle = true,
.support_ct_kill_exit = true,
.support_sm_ps = true,
};

MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
Expand Down
4 changes: 4 additions & 0 deletions trunk/drivers/net/wireless/iwlwifi/iwl-agn.c
Original file line number Diff line number Diff line change
Expand Up @@ -3011,6 +3011,10 @@ static int iwl_init_drv(struct iwl_priv *priv)
priv->band = IEEE80211_BAND_2GHZ;

priv->iw_mode = NL80211_IFTYPE_STATION;
if (priv->cfg->support_sm_ps)
priv->current_ht_config.sm_ps = WLAN_HT_CAP_SM_PS_DYNAMIC;
else
priv->current_ht_config.sm_ps = WLAN_HT_CAP_SM_PS_DISABLED;

/* Choose which receivers/antennas to use */
if (priv->cfg->ops->hcmd->set_rxon_chain)
Expand Down
48 changes: 38 additions & 10 deletions trunk/drivers/net/wireless/iwlwifi/iwl-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,8 +414,12 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
if (priv->cfg->ht_greenfield_support)
ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
(WLAN_HT_CAP_SM_PS_DISABLED << 2));
if (priv->cfg->support_sm_ps)
ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
(WLAN_HT_CAP_SM_PS_DYNAMIC << 2));
else
ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
(WLAN_HT_CAP_SM_PS_DISABLED << 2));

max_bit_rate = MAX_BIT_RATE_20_MHZ;
if (priv->hw_params.ht40_channel & BIT(band)) {
Expand Down Expand Up @@ -963,17 +967,35 @@ static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
}

/*
* When we are in power saving, there's no difference between
* using multiple chains or just a single chain, but due to the
* lack of SM PS we lose a lot of throughput if we use just a
* single chain.
*
* Therefore, use the active count here (which will use multiple
* chains unless connected to a legacy AP).
* When we are in power saving mode, unless device support spatial
* multiplexing power save, use the active count for rx chain count.
*/
static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
{
return active_cnt;
int idle_cnt = active_cnt;
bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);

if (priv->cfg->support_sm_ps) {
/* # Rx chains when idling and maybe trying to save power */
switch (priv->current_ht_config.sm_ps) {
case WLAN_HT_CAP_SM_PS_STATIC:
case WLAN_HT_CAP_SM_PS_DYNAMIC:
idle_cnt = (is_cam) ? IWL_NUM_IDLE_CHAINS_DUAL :
IWL_NUM_IDLE_CHAINS_SINGLE;
break;
case WLAN_HT_CAP_SM_PS_DISABLED:
idle_cnt = (is_cam) ? active_cnt :
IWL_NUM_IDLE_CHAINS_SINGLE;
break;
case WLAN_HT_CAP_SM_PS_INVALID:
default:
IWL_ERR(priv, "invalid sm_ps mode %d\n",
priv->current_ht_config.sm_ps);
WARN_ON(1);
break;
}
}
return idle_cnt;
}

/* up to 4 chains */
Expand Down Expand Up @@ -2257,6 +2279,12 @@ static void iwl_ht_conf(struct iwl_priv *priv,
>> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
maxstreams += 1;

ht_conf->sm_ps =
(u8)((ht_cap->cap & IEEE80211_HT_CAP_SM_PS)
>> 2);
IWL_DEBUG_MAC80211(priv, "sm_ps: 0x%x\n",
ht_conf->sm_ps);

if ((ht_cap->mcs.rx_mask[1] == 0) &&
(ht_cap->mcs.rx_mask[2] == 0))
ht_conf->single_chain_sufficient = true;
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/net/wireless/iwlwifi/iwl-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ struct iwl_mod_params {
* @chain_noise_num_beacons: number of beacons used to compute chain noise
* @adv_thermal_throttle: support advance thermal throttle
* @support_ct_kill_exit: support ct kill exit condition
* @support_sm_ps: support spatial multiplexing power save
*
* We enable the driver to be backward compatible wrt API version. The
* driver specifies which APIs it supports (with @ucode_api_max being the
Expand Down Expand Up @@ -283,6 +284,7 @@ struct iwl_cfg {
const bool supports_idle;
bool adv_thermal_throttle;
bool support_ct_kill_exit;
bool support_sm_ps;
};

/***************************
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/net/wireless/iwlwifi/iwl-dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,7 @@ struct iwl_ht_config {
bool is_ht;
bool is_40mhz;
bool single_chain_sufficient;
u8 sm_ps;
/* BSS related data */
u8 extension_chan_offset;
u8 ht_protection;
Expand Down
5 changes: 5 additions & 0 deletions trunk/drivers/net/wireless/iwlwifi/iwl-sta.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,11 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
goto done;

mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2;
IWL_DEBUG_ASSOC(priv, "spatial multiplexing power save mode: %s\n",
(mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ?
"static" :
(mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ?
"dynamic" : "disabled");

sta_flags = priv->stations[index].sta.station_flags;

Expand Down

0 comments on commit 1cb9db5

Please sign in to comment.