aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAlexander Bondar <alexander.bondar@intel.com>2013-03-21 11:14:14 -0400
committerJohannes Berg <johannes.berg@intel.com>2013-06-25 06:21:19 -0400
commitbd4ace2a36e7c87bb5f3eceb54d3b304d395dcf0 (patch)
treee9e45b38d547a3a63800092ed627901284911b18 /drivers/net
parent9277326e1e5d395397fbe20c0f310cf30bfbacc2 (diff)
iwlwifi: mvm: Add support for Low Power RX
To improve power consumption in idle associated mode FW may lower RX power. This low linearity mode is acceptable for listening low rate RX such as beacons and groupcast. The driver enables LPRX only if PM is enabled and associated AP's beacon TX rate is 1Mbps or 6Mbps. LPRX RSSI threshold is used to limit a range where LPRX is applied. Signed-off-by: Alexander Bondar <alexander.bondar@intel.com> Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c24
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h5
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c22
4 files changed, 52 insertions, 3 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index 63d19d94b018..e56ed2a84888 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -344,6 +344,13 @@ static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm,
344 case MVM_DEBUGFS_PM_DISABLE_POWER_OFF: 344 case MVM_DEBUGFS_PM_DISABLE_POWER_OFF:
345 IWL_DEBUG_POWER(mvm, "disable_power_off=%d\n", val); 345 IWL_DEBUG_POWER(mvm, "disable_power_off=%d\n", val);
346 dbgfs_pm->disable_power_off = val; 346 dbgfs_pm->disable_power_off = val;
347 case MVM_DEBUGFS_PM_LPRX_ENA:
348 IWL_DEBUG_POWER(mvm, "lprx %s\n", val ? "enabled" : "disabled");
349 dbgfs_pm->lprx_ena = val;
350 break;
351 case MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD:
352 IWL_DEBUG_POWER(mvm, "lprx_rssi_threshold=%d\n", val);
353 dbgfs_pm->lprx_rssi_threshold = val;
347 break; 354 break;
348 } 355 }
349} 356}
@@ -387,6 +394,17 @@ static ssize_t iwl_dbgfs_pm_params_write(struct file *file,
387 if (sscanf(buf + 18, "%d", &val) != 1) 394 if (sscanf(buf + 18, "%d", &val) != 1)
388 return -EINVAL; 395 return -EINVAL;
389 param = MVM_DEBUGFS_PM_DISABLE_POWER_OFF; 396 param = MVM_DEBUGFS_PM_DISABLE_POWER_OFF;
397 } else if (!strncmp("lprx=", buf, 5)) {
398 if (sscanf(buf + 5, "%d", &val) != 1)
399 return -EINVAL;
400 param = MVM_DEBUGFS_PM_LPRX_ENA;
401 } else if (!strncmp("lprx_rssi_threshold=", buf, 20)) {
402 if (sscanf(buf + 20, "%d", &val) != 1)
403 return -EINVAL;
404 if (val > POWER_LPRX_RSSI_THRESHOLD_MAX || val <
405 POWER_LPRX_RSSI_THRESHOLD_MIN)
406 return -EINVAL;
407 param = MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD;
390 } else { 408 } else {
391 return -EINVAL; 409 return -EINVAL;
392 } 410 }
@@ -421,7 +439,7 @@ static ssize_t iwl_dbgfs_pm_params_read(struct file *file,
421 le32_to_cpu(cmd.skip_dtim_periods)); 439 le32_to_cpu(cmd.skip_dtim_periods));
422 pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n", 440 pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n",
423 iwlmvm_mod_params.power_scheme); 441 iwlmvm_mod_params.power_scheme);
424 pos += scnprintf(buf+pos, bufsz-pos, "flags = %d\n", 442 pos += scnprintf(buf+pos, bufsz-pos, "flags = 0x%x\n",
425 le16_to_cpu(cmd.flags)); 443 le16_to_cpu(cmd.flags));
426 pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n", 444 pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n",
427 cmd.keep_alive_seconds); 445 cmd.keep_alive_seconds);
@@ -435,6 +453,10 @@ static ssize_t iwl_dbgfs_pm_params_read(struct file *file,
435 le32_to_cpu(cmd.rx_data_timeout)); 453 le32_to_cpu(cmd.rx_data_timeout));
436 pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout = %d\n", 454 pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout = %d\n",
437 le32_to_cpu(cmd.tx_data_timeout)); 455 le32_to_cpu(cmd.tx_data_timeout));
456 if (cmd.flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK))
457 pos += scnprintf(buf+pos, bufsz-pos,
458 "lprx_rssi_threshold = %d\n",
459 le32_to_cpu(cmd.lprx_rssi_threshold));
438 } 460 }
439 461
440 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 462 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
index d8e19290b0f3..a6da359a80c3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
@@ -66,6 +66,11 @@
66 66
67/* Power Management Commands, Responses, Notifications */ 67/* Power Management Commands, Responses, Notifications */
68 68
69/* Radio LP RX Energy Threshold measured in dBm */
70#define POWER_LPRX_RSSI_THRESHOLD 75
71#define POWER_LPRX_RSSI_THRESHOLD_MAX 94
72#define POWER_LPRX_RSSI_THRESHOLD_MIN 30
73
69/** 74/**
70 * enum iwl_scan_flags - masks for power table command flags 75 * enum iwl_scan_flags - masks for power table command flags
71 * @POWER_FLAGS_POWER_SAVE_ENA_MSK: '1' Allow to save power by turning off 76 * @POWER_FLAGS_POWER_SAVE_ENA_MSK: '1' Allow to save power by turning off
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index c6ba553845cd..d40d7db185d6 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -158,6 +158,8 @@ enum iwl_dbgfs_pm_mask {
158 MVM_DEBUGFS_PM_RX_DATA_TIMEOUT = BIT(3), 158 MVM_DEBUGFS_PM_RX_DATA_TIMEOUT = BIT(3),
159 MVM_DEBUGFS_PM_TX_DATA_TIMEOUT = BIT(4), 159 MVM_DEBUGFS_PM_TX_DATA_TIMEOUT = BIT(4),
160 MVM_DEBUGFS_PM_DISABLE_POWER_OFF = BIT(5), 160 MVM_DEBUGFS_PM_DISABLE_POWER_OFF = BIT(5),
161 MVM_DEBUGFS_PM_LPRX_ENA = BIT(6),
162 MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD = BIT(7),
161}; 163};
162 164
163struct iwl_dbgfs_pm { 165struct iwl_dbgfs_pm {
@@ -167,6 +169,8 @@ struct iwl_dbgfs_pm {
167 bool skip_over_dtim; 169 bool skip_over_dtim;
168 u8 skip_dtim_periods; 170 u8 skip_dtim_periods;
169 bool disable_power_off; 171 bool disable_power_off;
172 bool lprx_ena;
173 u32 lprx_rssi_threshold;
170 int mask; 174 int mask;
171}; 175};
172 176
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index 3760a33ca3a4..e7ca965a89b8 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -137,11 +137,12 @@ static void iwl_mvm_power_log(struct iwl_mvm *mvm,
137 le32_to_cpu(cmd->rx_data_timeout)); 137 le32_to_cpu(cmd->rx_data_timeout));
138 IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n", 138 IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n",
139 le32_to_cpu(cmd->tx_data_timeout)); 139 le32_to_cpu(cmd->tx_data_timeout));
140 IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n",
141 cmd->lprx_rssi_threshold);
142 if (cmd->flags & cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) 140 if (cmd->flags & cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK))
143 IWL_DEBUG_POWER(mvm, "DTIM periods to skip = %u\n", 141 IWL_DEBUG_POWER(mvm, "DTIM periods to skip = %u\n",
144 le32_to_cpu(cmd->skip_dtim_periods)); 142 le32_to_cpu(cmd->skip_dtim_periods));
143 if (cmd->flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK))
144 IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n",
145 le32_to_cpu(cmd->lprx_rssi_threshold));
145 } 146 }
146} 147}
147 148
@@ -181,6 +182,14 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
181 182
182 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); 183 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK);
183 184
185 if (vif->bss_conf.beacon_rate &&
186 (vif->bss_conf.beacon_rate->bitrate == 10 ||
187 vif->bss_conf.beacon_rate->bitrate == 60)) {
188 cmd->flags |= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK);
189 cmd->lprx_rssi_threshold =
190 cpu_to_le32(POWER_LPRX_RSSI_THRESHOLD);
191 }
192
184 dtimper = hw->conf.ps_dtim_period ?: 1; 193 dtimper = hw->conf.ps_dtim_period ?: 1;
185 194
186 /* Check if radar detection is required on current channel */ 195 /* Check if radar detection is required on current channel */
@@ -236,6 +245,15 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
236 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS) 245 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS)
237 cmd->skip_dtim_periods = 246 cmd->skip_dtim_periods =
238 cpu_to_le32(mvmvif->dbgfs_pm.skip_dtim_periods); 247 cpu_to_le32(mvmvif->dbgfs_pm.skip_dtim_periods);
248 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_ENA) {
249 if (mvmvif->dbgfs_pm.lprx_ena)
250 cmd->flags |= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK);
251 else
252 cmd->flags &= cpu_to_le16(~POWER_FLAGS_LPRX_ENA_MSK);
253 }
254 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD)
255 cmd->lprx_rssi_threshold =
256 cpu_to_le32(mvmvif->dbgfs_pm.lprx_rssi_threshold);
239#endif /* CONFIG_IWLWIFI_DEBUGFS */ 257#endif /* CONFIG_IWLWIFI_DEBUGFS */
240} 258}
241 259