aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn.c
diff options
context:
space:
mode:
authorMeenakshi Venkataraman <meenakshi.venkataraman@intel.com>2011-07-08 11:46:23 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-07-11 15:02:07 -0400
commit207ecc5eab908843449c167f7264a35d7d5d5e0b (patch)
tree3425f0964810c9d1edd0bcc097a5838ce1f5c726 /drivers/net/wireless/iwlwifi/iwl-agn.c
parent615f7b9bb1f8e0e3188470245cec44f175189084 (diff)
iwlagn: Enable/disable PS poll based on RSSI and BT coex traffic state
WiFi throughput drops drastically when BT is turned on, BT and WiFi are simultaneously transmitting/receiving traffic. This is particularly true when BT has higher priority over WiFi, and hence the device defers TX frames. The AP assumes that the channel is bad and reduces the data rate, implying longer airtime, which exacerbates the problem further, resulting ultimately in what is popularly called the "death-spiral" phenomenon. The use of PS-poll in such scenarios guarantees a low but consistent throughput. Since the death-spiral phenomenon is observed only when the RSSI is low, use PS-poll only when RSSI is low and disable when high, with a known hysterisis. This feature specifies the high and low thresholds and implements the callbacks registered with mac80211, which will be called when threshold events occur. iwlwifi: dynamic pspoll: optimize rssi monitor code Signed-off-by: Meenakshi Venkataraman <meenakshi.venkataraman@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 3a4fca14fef8..cbd8d101f6f8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2015,11 +2015,18 @@ int iwl_alive_start(struct iwl_priv *priv)
2015 if (priv->cfg->bt_params && 2015 if (priv->cfg->bt_params &&
2016 priv->cfg->bt_params->advanced_bt_coexist) { 2016 priv->cfg->bt_params->advanced_bt_coexist) {
2017 /* Configure Bluetooth device coexistence support */ 2017 /* Configure Bluetooth device coexistence support */
2018 if (priv->cfg->bt_params->bt_sco_disable)
2019 priv->bt_enable_pspoll = false;
2020 else
2021 priv->bt_enable_pspoll = true;
2022
2018 priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK; 2023 priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK;
2019 priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT; 2024 priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT;
2020 priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT; 2025 priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT;
2021 iwlagn_send_advance_bt_config(priv); 2026 iwlagn_send_advance_bt_config(priv);
2022 priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS; 2027 priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS;
2028 priv->cur_rssi_ctx = NULL;
2029
2023 iwlagn_send_prio_tbl(priv); 2030 iwlagn_send_prio_tbl(priv);
2024 2031
2025 /* FIXME: w/a to force change uCode BT state machine */ 2032 /* FIXME: w/a to force change uCode BT state machine */
@@ -2102,6 +2109,8 @@ static void __iwl_down(struct iwl_priv *priv)
2102 2109
2103 /* reset BT coex data */ 2110 /* reset BT coex data */
2104 priv->bt_status = 0; 2111 priv->bt_status = 0;
2112 priv->cur_rssi_ctx = NULL;
2113 priv->bt_is_sco = 0;
2105 if (priv->cfg->bt_params) 2114 if (priv->cfg->bt_params)
2106 priv->bt_traffic_load = 2115 priv->bt_traffic_load =
2107 priv->cfg->bt_params->bt_init_traffic_load; 2116 priv->cfg->bt_params->bt_init_traffic_load;
@@ -2277,6 +2286,7 @@ static void iwlagn_prepare_restart(struct iwl_priv *priv)
2277 u8 bt_ci_compliance; 2286 u8 bt_ci_compliance;
2278 u8 bt_load; 2287 u8 bt_load;
2279 u8 bt_status; 2288 u8 bt_status;
2289 bool bt_is_sco;
2280 2290
2281 lockdep_assert_held(&priv->mutex); 2291 lockdep_assert_held(&priv->mutex);
2282 2292
@@ -2297,6 +2307,7 @@ static void iwlagn_prepare_restart(struct iwl_priv *priv)
2297 bt_ci_compliance = priv->bt_ci_compliance; 2307 bt_ci_compliance = priv->bt_ci_compliance;
2298 bt_load = priv->bt_traffic_load; 2308 bt_load = priv->bt_traffic_load;
2299 bt_status = priv->bt_status; 2309 bt_status = priv->bt_status;
2310 bt_is_sco = priv->bt_is_sco;
2300 2311
2301 __iwl_down(priv); 2312 __iwl_down(priv);
2302 2313
@@ -2304,6 +2315,7 @@ static void iwlagn_prepare_restart(struct iwl_priv *priv)
2304 priv->bt_ci_compliance = bt_ci_compliance; 2315 priv->bt_ci_compliance = bt_ci_compliance;
2305 priv->bt_traffic_load = bt_load; 2316 priv->bt_traffic_load = bt_load;
2306 priv->bt_status = bt_status; 2317 priv->bt_status = bt_status;
2318 priv->bt_is_sco = bt_is_sco;
2307} 2319}
2308 2320
2309static void iwl_bg_restart(struct work_struct *data) 2321static void iwl_bg_restart(struct work_struct *data)
@@ -3330,6 +3342,29 @@ static void iwl_uninit_drv(struct iwl_priv *priv)
3330 kfree(priv->beacon_cmd); 3342 kfree(priv->beacon_cmd);
3331} 3343}
3332 3344
3345void iwl_mac_rssi_callback(struct ieee80211_hw *hw,
3346 enum ieee80211_rssi_event rssi_event)
3347{
3348 struct iwl_priv *priv = hw->priv;
3349
3350 mutex_lock(&priv->mutex);
3351
3352 if (priv->cfg->bt_params &&
3353 priv->cfg->bt_params->advanced_bt_coexist) {
3354 if (rssi_event == RSSI_EVENT_LOW)
3355 priv->bt_enable_pspoll = true;
3356 else if (rssi_event == RSSI_EVENT_HIGH)
3357 priv->bt_enable_pspoll = false;
3358
3359 iwlagn_send_advance_bt_config(priv);
3360 } else {
3361 IWL_DEBUG_MAC80211(priv, "Advanced BT coex disabled,"
3362 "ignoring RSSI callback\n");
3363 }
3364
3365 mutex_unlock(&priv->mutex);
3366}
3367
3333struct ieee80211_ops iwlagn_hw_ops = { 3368struct ieee80211_ops iwlagn_hw_ops = {
3334 .tx = iwlagn_mac_tx, 3369 .tx = iwlagn_mac_tx,
3335 .start = iwlagn_mac_start, 3370 .start = iwlagn_mac_start,
@@ -3355,6 +3390,7 @@ struct ieee80211_ops iwlagn_hw_ops = {
3355 .cancel_remain_on_channel = iwl_mac_cancel_remain_on_channel, 3390 .cancel_remain_on_channel = iwl_mac_cancel_remain_on_channel,
3356 .offchannel_tx = iwl_mac_offchannel_tx, 3391 .offchannel_tx = iwl_mac_offchannel_tx,
3357 .offchannel_tx_cancel_wait = iwl_mac_offchannel_tx_cancel_wait, 3392 .offchannel_tx_cancel_wait = iwl_mac_offchannel_tx_cancel_wait,
3393 .rssi_callback = iwl_mac_rssi_callback,
3358 CFG80211_TESTMODE_CMD(iwl_testmode_cmd) 3394 CFG80211_TESTMODE_CMD(iwl_testmode_cmd)
3359 CFG80211_TESTMODE_DUMP(iwl_testmode_dump) 3395 CFG80211_TESTMODE_DUMP(iwl_testmode_dump)
3360}; 3396};