From 02018b39a75057541c7946a9173561d1a76a0bfe Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 6 May 2009 22:35:58 +0200 Subject: wireless: WL12XX should depend on GENERIC_HARDIRQS m68k allmodconfig: | drivers/net/wireless/wl12xx/main.c: In function 'wl12xx_probe': | drivers/net/wireless/wl12xx/main.c:1273: error: implicit declaration of function 'set_irq_type' | make[1]: *** [drivers/net/wireless/wl12xx/main.o] Error 1 Signed-off-by: Geert Uytterhoeven Acked-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig index 20a9633569f2..a82c4cd436d8 100644 --- a/drivers/net/wireless/wl12xx/Kconfig +++ b/drivers/net/wireless/wl12xx/Kconfig @@ -1,6 +1,6 @@ config WL12XX tristate "TI wl1251/wl1271 support" - depends on MAC80211 && WLAN_80211 && SPI_MASTER && EXPERIMENTAL + depends on MAC80211 && WLAN_80211 && SPI_MASTER && GENERIC_HARDIRQS && EXPERIMENTAL select FW_LOADER select CRC7 ---help--- -- cgit v1.2.3-59-g8ed1b From 782571f46fc7d2bbb0288ab0d676c47a88449a5c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 8 May 2009 19:31:42 +0200 Subject: iwlwifi: make iwl_set_rate static It's not needed outside iwl-core.c Signed-off-by: Johannes Berg Acked-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 3 +-- drivers/net/wireless/iwlwifi/iwl-core.h | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 1366222bb50a..77f4b43b9b74 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1120,7 +1120,7 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode) } EXPORT_SYMBOL(iwl_connection_init_rx_config); -void iwl_set_rate(struct iwl_priv *priv) +static void iwl_set_rate(struct iwl_priv *priv) { const struct ieee80211_supported_band *hw = NULL; struct ieee80211_rate *rate; @@ -1166,7 +1166,6 @@ void iwl_set_rate(struct iwl_priv *priv) priv->staging_rxon.ofdm_basic_rates = (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; } -EXPORT_SYMBOL(iwl_set_rate); void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index bd7f9d9616bc..f3544ea559a2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -363,8 +363,6 @@ int iwl_hwrate_to_plcp_idx(u32 rate_n_flags); u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv); -void iwl_set_rate(struct iwl_priv *priv); - u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx); static inline u32 iwl_ant_idx_to_flags(u8 ant_idx) -- cgit v1.2.3-59-g8ed1b From 5a9940118a616266183c53a9ee4352feadb9c2e8 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Fri, 8 May 2009 18:30:43 +0200 Subject: rt2x00: Fix chipset detection for rt73usb The lower 4 bytes of the chipset revision must contain a non-zero value. This bug was introduced by "rt2x00: Simplify rt2x00_check_rev". Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt73usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index d10af3687a8e..270dd4e59f7f 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1847,7 +1847,7 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_chip(rt2x00dev, RT2571, value, reg); if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0x25730) || - !rt2x00_check_rev(&rt2x00dev->chip, 0x0000000f, 0)) { + rt2x00_check_rev(&rt2x00dev->chip, 0x0000000f, 0)) { ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); return -ENODEV; } -- cgit v1.2.3-59-g8ed1b From 9ed6bcce77f75d98af6ee07069deac6041948bee Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 8 May 2009 20:47:39 +0200 Subject: mac80211: move HT operation mode BSS info There really is no need to have a separate struct for a single variable. The fact that it exists is due to the code legacy, but we can remove that now. Very simple. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 4 ++-- drivers/net/wireless/mac80211_hwsim.c | 2 +- drivers/net/wireless/mwl8k.c | 2 +- include/net/mac80211.h | 12 +++--------- net/mac80211/mlme.c | 11 ++++------- 5 files changed, 11 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 77f4b43b9b74..a9a4fcef7e42 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2225,9 +2225,9 @@ static void iwl_ht_conf(struct iwl_priv *priv, iwl_conf->tx_chan_width = iwl_conf->supported_chan_width != 0; iwl_conf->ht_protection = - bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION; + bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION; iwl_conf->non_GF_STA_present = - !!(bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); + !!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); rcu_read_unlock(); diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index b1213b6a6b9f..61a4ad7cc1c2 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -642,7 +642,7 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_HT) { printk(KERN_DEBUG " %s: HT: op_mode=0x%x\n", wiphy_name(hw->wiphy), - info->ht.operation_mode); + info->ht_operation_mode); } if (changed & BSS_CHANGED_BASIC_RATES) { diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 46b288dc8f4d..a263d5c84c08 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -2369,7 +2369,7 @@ static int mwl8k_cmd_set_aid(struct ieee80211_hw *hw, if (info->use_cts_prot) { prot_mode = MWL8K_FRAME_PROT_11G; } else { - switch (info->ht.operation_mode & + switch (info->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION) { case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ: prot_mode = MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY; diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 38dc1cd10270..03591fcf519c 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -170,14 +170,6 @@ enum ieee80211_bss_change { BSS_CHANGED_BEACON_ENABLED = 1<<9, }; -/** - * struct ieee80211_bss_ht_conf - BSS's changing HT configuration - * @operation_mode: HT operation mode (like in &struct ieee80211_ht_info) - */ -struct ieee80211_bss_ht_conf { - u16 operation_mode; -}; - /** * struct ieee80211_bss_conf - holds the BSS's changing parameters * @@ -203,6 +195,8 @@ struct ieee80211_bss_ht_conf { * the current band. * @bssid: The BSSID for this BSS * @enable_beacon: whether beaconing should be enabled or not + * @ht_operation_mode: HT operation mode (like in &struct ieee80211_ht_info). + * This field is only valid when the channel type is one of the HT types. */ struct ieee80211_bss_conf { const u8 *bssid; @@ -219,7 +213,7 @@ struct ieee80211_bss_conf { u16 assoc_capability; u64 timestamp; u32 basic_rates; - struct ieee80211_bss_ht_conf ht; + u16 ht_operation_mode; }; /** diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index c5445bae9d6c..a1f2332a6fed 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -95,16 +95,14 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, struct ieee80211_local *local = sdata->local; struct ieee80211_supported_band *sband; struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; - struct ieee80211_bss_ht_conf ht; struct sta_info *sta; u32 changed = 0; + u16 ht_opmode; bool enable_ht = true, ht_changed; enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; - memset(&ht, 0, sizeof(ht)); - /* HT is not supported */ if (!sband->ht_cap.ht_supported) enable_ht = false; @@ -148,19 +146,18 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, IEEE80211_RC_HT_CHANGED); rcu_read_unlock(); - } /* disable HT */ if (!enable_ht) return 0; - ht.operation_mode = le16_to_cpu(hti->operation_mode); + ht_opmode = le16_to_cpu(hti->operation_mode); /* if bss configuration changed store the new one */ - if (memcmp(&sdata->vif.bss_conf.ht, &ht, sizeof(ht))) { + if (sdata->vif.bss_conf.ht_operation_mode != ht_opmode) { changed |= BSS_CHANGED_HT; - sdata->vif.bss_conf.ht = ht; + sdata->vif.bss_conf.ht_operation_mode = ht_opmode; } return changed; -- cgit v1.2.3-59-g8ed1b From 19cc10870ece942d287241937944c237130f50f4 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 8 May 2009 13:44:36 -0700 Subject: iwlwifi: do proper hw restart When the microcode fails for any reason, ask mac80211 to recover instead of trying ourselves and failing at it. Signed-off-by: Johannes Berg Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 43 +++++++++-------------------- drivers/net/wireless/iwlwifi/iwl-core.c | 5 ---- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 - drivers/net/wireless/iwlwifi/iwl3945-base.c | 36 ++++++++---------------- 4 files changed, 24 insertions(+), 61 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 6cdee0b4b486..43bc8a66864e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -190,8 +190,7 @@ int iwl_commit_rxon(struct iwl_priv *priv) priv->cfg->ops->smgmt->clear_station_table(priv); - if (!priv->error_recovering) - priv->start_calib = 0; + priv->start_calib = 0; /* Add the broadcast address so we can send broadcast frames */ if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) == @@ -967,23 +966,6 @@ static inline void iwl_synchronize_irq(struct iwl_priv *priv) tasklet_kill(&priv->irq_tasklet); } -static void iwl_error_recovery(struct iwl_priv *priv) -{ - unsigned long flags; - - memcpy(&priv->staging_rxon, &priv->recovery_rxon, - sizeof(priv->staging_rxon)); - priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv); - - iwl_rxon_add_station(priv, priv->bssid, 1); - - spin_lock_irqsave(&priv->lock, flags); - priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id); - priv->error_recovering = 0; - spin_unlock_irqrestore(&priv->lock, flags); -} - static void iwl_irq_tasklet(struct iwl_priv *priv) { u32 inta, handled = 0; @@ -1514,9 +1496,6 @@ static void iwl_alive_start(struct iwl_priv *priv) set_bit(STATUS_READY, &priv->status); wake_up_interruptible(&priv->wait_command_queue); - if (priv->error_recovering) - iwl_error_recovery(priv); - iwl_power_update_mode(priv, 1); /* reassociate for ADHOC mode */ @@ -1715,9 +1694,6 @@ static int __iwl_up(struct iwl_priv *priv) continue; } - /* Clear out the uCode error bit if it is set */ - clear_bit(STATUS_FW_ERROR, &priv->status); - /* start card; "initialize" will load runtime ucode */ iwl_nic_start(priv); @@ -1812,8 +1788,17 @@ static void iwl_bg_restart(struct work_struct *data) if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - iwl_down(priv); - queue_work(priv->workqueue, &priv->up); + if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { + mutex_lock(&priv->mutex); + priv->vif = NULL; + priv->is_open = 0; + mutex_unlock(&priv->mutex); + iwl_down(priv); + ieee80211_restart_hw(priv->hw); + } else { + iwl_down(priv); + queue_work(priv->workqueue, &priv->up); + } } static void iwl_bg_rx_replenish(struct work_struct *data) @@ -2007,10 +1992,8 @@ static void iwl_mac_stop(struct ieee80211_hw *hw) IWL_DEBUG_MAC80211(priv, "enter\n"); - if (!priv->is_open) { - IWL_DEBUG_MAC80211(priv, "leave - skip\n"); + if (!priv->is_open) return; - } priv->is_open = 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index a9a4fcef7e42..aa1e1dc95ef6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1229,11 +1229,6 @@ void iwl_irq_handle_error(struct iwl_priv *priv) IWL_DEBUG(priv, IWL_DL_FW_ERRORS, "Restarting adapter due to uCode error.\n"); - if (iwl_is_associated(priv)) { - memcpy(&priv->recovery_rxon, &priv->active_rxon, - sizeof(priv->recovery_rxon)); - priv->error_recovering = 1; - } if (priv->cfg->mod_params->restart_fw) queue_work(priv->workqueue, &priv->restart); } diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 5aa76a706320..0f2c1b217515 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -933,7 +933,6 @@ struct iwl_priv { const struct iwl_rxon_cmd active_rxon; struct iwl_rxon_cmd staging_rxon; - int error_recovering; struct iwl_rxon_cmd recovery_rxon; /* 1st responses from initialize and runtime uCode images. diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index f6c1489a0c4a..271e5d1f8425 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -1837,23 +1837,6 @@ static void iwl3945_dump_nic_event_log(struct iwl_priv *priv) iwl_release_nic_access(priv); } -static void iwl3945_error_recovery(struct iwl_priv *priv) -{ - unsigned long flags; - - memcpy(&priv->staging_rxon, &priv->recovery_rxon, - sizeof(priv->staging_rxon)); - priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv); - - priv->cfg->ops->smgmt->add_station(priv, priv->bssid, 1, 0, NULL); - - spin_lock_irqsave(&priv->lock, flags); - priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id); - priv->error_recovering = 0; - spin_unlock_irqrestore(&priv->lock, flags); -} - static void iwl3945_irq_tasklet(struct iwl_priv *priv) { u32 inta, handled = 0; @@ -2683,9 +2666,6 @@ static void iwl3945_alive_start(struct iwl_priv *priv) /* After the ALIVE response, we can send commands to 3945 uCode */ set_bit(STATUS_ALIVE, &priv->status); - /* Clear out the uCode error bit if it is set */ - clear_bit(STATUS_FW_ERROR, &priv->status); - if (iwl_is_rfkill(priv)) return; @@ -2722,9 +2702,6 @@ static void iwl3945_alive_start(struct iwl_priv *priv) set_bit(STATUS_READY, &priv->status); wake_up_interruptible(&priv->wait_command_queue); - if (priv->error_recovering) - iwl3945_error_recovery(priv); - /* reassociate for ADHOC mode */ if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) { struct sk_buff *beacon = ieee80211_beacon_get(priv->hw, @@ -3231,8 +3208,17 @@ static void iwl3945_bg_restart(struct work_struct *data) if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - iwl3945_down(priv); - queue_work(priv->workqueue, &priv->up); + if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { + mutex_lock(&priv->mutex); + priv->vif = NULL; + priv->is_open = 0; + mutex_unlock(&priv->mutex); + iwl3945_down(priv); + ieee80211_restart_hw(priv->hw); + } else { + iwl3945_down(priv); + queue_work(priv->workqueue, &priv->up); + } } static void iwl3945_bg_rx_replenish(struct work_struct *data) -- cgit v1.2.3-59-g8ed1b From f0f74a0e65a69d4cc579e60f76a30b38ad7dbe06 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 8 May 2009 13:44:37 -0700 Subject: iwlwifi: fix PS disable status race iwlwifi internally needs to keep track of whether PS is enabled in the firmware or not. To do this, it keeps a bit in the status flags, called STATUS_POWER_PMI. The code to set this bit looks as follows: static int iwl_set_power(struct iwl_priv *priv, void *cmd) { return iwl_send_cmd_pdu_async(priv, POWER_TABLE_CMD, sizeof(struct iwl_powertable_cmd), cmd, NULL); } int iwl_power_update_mode(...) { [...] if (final_mode != IWL_POWER_MODE_CAM) set_bit(STATUS_POWER_PMI, &priv->status); iwl_update_power_cmd(priv, &cmd, final_mode); cmd.keep_alive_beacons = 0; if (final_mode == IWL_POWER_INDEX_5) cmd.flags |= IWL_POWER_FAST_PD; ret = iwl_set_power(priv, &cmd); if (final_mode == IWL_POWER_MODE_CAM) clear_bit(STATUS_POWER_PMI, &priv->status); else set_bit(STATUS_POWER_PMI, &priv->status); if (priv->cfg->ops->lib->update_chain_flags && update_chains) priv->cfg->ops->lib->update_chain_flags(priv); [...] } Now, this bit really needs to track what the _firmware_ thinks, not what the driver thinks. Therefore, there is a race condition here -- the driver sets the bit before it knows that the async command sent to the card in the iwl_set_power function has been processed. As a result, the call to update_chain_flags() may think that the card has been woken up (PMI bit cleared) while in reality it hasn't processed the async POWER_TABLE_CMD yet. This leads to bugs -- any commands the update_chain_flags function sends can get stuck and subsequent commands also fail. The fix is almost trivial: since there's no reason to send an async command here (in fact, there almost never should be since many mac80211 callbacks can sleep) just make the function wait for the card to process the command and then return and clear the PMI bit. Signed-off-by: Johannes Berg Acked-by: Mohamed Abbas Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-power.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 47c894530eb5..c913069a2496 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -106,9 +106,8 @@ static struct iwl_power_vec_entry range_2[IWL_POWER_MAX] = { /* set card power command */ static int iwl_set_power(struct iwl_priv *priv, void *cmd) { - return iwl_send_cmd_pdu_async(priv, POWER_TABLE_CMD, - sizeof(struct iwl_powertable_cmd), - cmd, NULL); + return iwl_send_cmd_pdu(priv, POWER_TABLE_CMD, + sizeof(struct iwl_powertable_cmd), cmd); } /* decide the right power level according to association status * and battery status -- cgit v1.2.3-59-g8ed1b From 7af2c460789a78d9c0d4dc7776fcb87acdc71052 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 8 May 2009 13:44:38 -0700 Subject: iwlwifi: clean up PS code This removes all the dead code that tries to adjust the power saving level based on the system AC state (inacceptable policy in the kernel) or based on overtemp conditions (unused). Also, pass _all_ policy wrt. enabling PS to mac80211, since we do not use the power_disabled internally I now use that to mirror the mac80211 CONF_PS setting. When mac80211 turns off CONF_PS we follow suit. This means that the user power level (which can currently only be set from sysfs) is not touched for mac80211 powersave changes. This means no "association status" checks are necessary since mac80211 will not allow power save to be enabled when not associated. Signed-off-by: Johannes Berg Acked-by: Mohamed Abbas Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 24 +-- drivers/net/wireless/iwlwifi/iwl-calib.c | 2 +- drivers/net/wireless/iwlwifi/iwl-core.c | 26 +--- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 - drivers/net/wireless/iwlwifi/iwl-power.c | 228 ++++------------------------ drivers/net/wireless/iwlwifi/iwl-power.h | 39 +---- drivers/net/wireless/iwlwifi/iwl3945-base.c | 20 +-- 7 files changed, 48 insertions(+), 292 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 43bc8a66864e..13a35dc710a4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1838,7 +1838,6 @@ void iwl_post_associate(struct iwl_priv *priv) if (!priv->vif || !priv->is_open) return; - iwl_power_cancel_timeout(priv); iwl_scan_cancel_timeout(priv, 200); conf = ieee80211_get_hw_conf(priv->hw); @@ -1914,7 +1913,7 @@ void iwl_post_associate(struct iwl_priv *priv) * If chain noise has already been run, then we need to enable * power management here */ if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE) - iwl_power_enable_management(priv); + iwl_power_update_mode(priv, 0); /* Enable Rx differential gain and sensitivity calibrations */ iwl_chain_noise_reset(priv); @@ -2465,26 +2464,11 @@ static ssize_t show_power_level(struct device *d, { struct iwl_priv *priv = dev_get_drvdata(d); int mode = priv->power_data.user_power_setting; - int system = priv->power_data.system_power_setting; int level = priv->power_data.power_mode; char *p = buf; - switch (system) { - case IWL_POWER_SYS_AUTO: - p += sprintf(p, "SYSTEM:auto"); - break; - case IWL_POWER_SYS_AC: - p += sprintf(p, "SYSTEM:ac"); - break; - case IWL_POWER_SYS_BATTERY: - p += sprintf(p, "SYSTEM:battery"); - break; - } - - p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO) ? - "fixed" : "auto"); - p += sprintf(p, "\tINDEX:%d", level); - p += sprintf(p, "\n"); + p += sprintf(p, "INDEX:%d\t", level); + p += sprintf(p, "USER:%d\n", mode); return p - buf + 1; } @@ -2553,7 +2537,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); iwl_setup_scan_deferred_work(priv); - iwl_setup_power_deferred_work(priv); if (priv->cfg->ops->lib->setup_deferred_work) priv->cfg->ops->lib->setup_deferred_work(priv); @@ -2573,7 +2556,6 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv) cancel_delayed_work_sync(&priv->init_alive_start); cancel_delayed_work(&priv->scan_check); - cancel_delayed_work_sync(&priv->set_power_save); cancel_delayed_work(&priv->alive_start); cancel_work_sync(&priv->beacon_update); del_timer_sync(&priv->statistics_periodic); diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c index 735f3f19928c..a5d63672ad39 100644 --- a/drivers/net/wireless/iwlwifi/iwl-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-calib.c @@ -857,7 +857,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, priv->cfg->ops->lib->update_chain_flags(priv); data->state = IWL_CHAIN_NOISE_DONE; - iwl_power_enable_management(priv); + iwl_power_update_mode(priv, 0); } EXPORT_SYMBOL(iwl_chain_noise_calibration); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index aa1e1dc95ef6..112bfa50b8fa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1352,7 +1352,6 @@ int iwl_init_drv(struct iwl_priv *priv) priv->ibss_beacon = NULL; spin_lock_init(&priv->lock); - spin_lock_init(&priv->power_data.lock); spin_lock_init(&priv->sta_lock); spin_lock_init(&priv->hcmd_lock); @@ -2576,14 +2575,13 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) iwl_set_rate(priv); } - if (changed & IEEE80211_CONF_CHANGE_PS) { - if (conf->flags & IEEE80211_CONF_PS) - ret = iwl_power_set_user_mode(priv, IWL_POWER_INDEX_3); - else - ret = iwl_power_set_user_mode(priv, IWL_POWER_MODE_CAM); + if (changed & IEEE80211_CONF_CHANGE_PS && + priv->iw_mode == NL80211_IFTYPE_STATION) { + priv->power_data.power_disabled = + !(conf->flags & IEEE80211_CONF_PS); + ret = iwl_power_update_mode(priv, 0); if (ret) IWL_DEBUG_MAC80211(priv, "Error setting power level\n"); - } if (changed & IEEE80211_CONF_CHANGE_POWER) { @@ -2719,21 +2717,7 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw) iwlcore_commit_rxon(priv); } - iwl_power_update_mode(priv, 0); - - /* Per mac80211.h: This is only used in IBSS mode... */ if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { - - /* switch to CAM during association period. - * the ucode will block any association/authentication - * frome during assiciation period if it can not hear - * the AP because of PM. the timer enable PM back is - * association do not complete - */ - if (priv->hw->conf.channel->flags & - (IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_RADAR)) - iwl_power_disable_management(priv, 3000); - IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n"); mutex_unlock(&priv->mutex); return; diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 0f2c1b217515..3049ba25c3fc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1075,7 +1075,6 @@ struct iwl_priv { struct tasklet_struct irq_tasklet; - struct delayed_work set_power_save; struct delayed_work init_alive_start; struct delayed_work alive_start; struct delayed_work scan_check; diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index c913069a2496..f2ea3f05f6e1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -41,38 +41,33 @@ #include "iwl-power.h" /* - * Setting power level allow the card to go to sleep when not busy - * there are three factor that decide the power level to go to, they - * are list here with its priority - * 1- critical_power_setting this will be set according to card temperature. - * 2- system_power_setting this will be set by system PM manager. - * 3- user_power_setting this will be set by user either by writing to sys or - * mac80211 + * Setting power level allow the card to go to sleep when not busy. * - * if system_power_setting and user_power_setting is set to auto - * the power level will be decided according to association status and battery - * status. + * The power level is set to INDEX_1 (the least deep state) by + * default, and will, in the future, be the deepest state unless + * otherwise required by pm_qos network latency requirements. * + * Using INDEX_1 without pm_qos is ok because mac80211 will disable + * PS when even checking every beacon for the TIM bit would exceed + * the required latency. */ -#define MSEC_TO_USEC 1024 #define IWL_POWER_RANGE_0_MAX (2) #define IWL_POWER_RANGE_1_MAX (10) - -#define IWL_POWER_ON_BATTERY IWL_POWER_INDEX_5 -#define IWL_POWER_ON_AC_DISASSOC IWL_POWER_MODE_CAM -#define IWL_POWER_ON_AC_ASSOC IWL_POWER_MODE_CAM - - -#define IWL_CT_KILL_TEMPERATURE 110 -#define IWL_MIN_POWER_TEMPERATURE 100 -#define IWL_REDUCED_POWER_TEMPERATURE 95 - +#define NOSLP cpu_to_le16(0), 0, 0 +#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0 +#define TU_TO_USEC 1024 +#define SLP_TOUT(T) cpu_to_le32((T) * TU_TO_USEC) +#define SLP_VEC(X0, X1, X2, X3, X4) {cpu_to_le32(X0), \ + cpu_to_le32(X1), \ + cpu_to_le32(X2), \ + cpu_to_le32(X3), \ + cpu_to_le32(X4)} /* default power management (not Tx power) table values */ -/* for TIM 0-10 */ -static struct iwl_power_vec_entry range_0[IWL_POWER_MAX] = { +/* for DTIM period 0 through IWL_POWER_RANGE_0_MAX */ +static const struct iwl_power_vec_entry range_0[IWL_POWER_NUM] = { {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0}, {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0}, @@ -82,8 +77,8 @@ static struct iwl_power_vec_entry range_0[IWL_POWER_MAX] = { }; -/* for TIM = 3-10 */ -static struct iwl_power_vec_entry range_1[IWL_POWER_MAX] = { +/* for DTIM period IWL_POWER_RANGE_0_MAX + 1 through IWL_POWER_RANGE_1_MAX */ +static const struct iwl_power_vec_entry range_1[IWL_POWER_NUM] = { {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0}, {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0}, @@ -92,8 +87,8 @@ static struct iwl_power_vec_entry range_1[IWL_POWER_MAX] = { {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 4, 7, 10, 10)}, 2} }; -/* for TIM > 11 */ -static struct iwl_power_vec_entry range_2[IWL_POWER_MAX] = { +/* for DTIM period > IWL_POWER_RANGE_1_MAX */ +static const struct iwl_power_vec_entry range_2[IWL_POWER_NUM] = { {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0}, {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0}, @@ -109,35 +104,12 @@ static int iwl_set_power(struct iwl_priv *priv, void *cmd) return iwl_send_cmd_pdu(priv, POWER_TABLE_CMD, sizeof(struct iwl_powertable_cmd), cmd); } -/* decide the right power level according to association status - * and battery status - */ -static u16 iwl_get_auto_power_mode(struct iwl_priv *priv) -{ - u16 mode; - - switch (priv->power_data.user_power_setting) { - case IWL_POWER_AUTO: - /* if running on battery */ - if (priv->power_data.is_battery_active) - mode = IWL_POWER_ON_BATTERY; - else if (iwl_is_associated(priv)) - mode = IWL_POWER_ON_AC_ASSOC; - else - mode = IWL_POWER_ON_AC_DISASSOC; - break; - default: - mode = priv->power_data.user_power_setting; - break; - } - return mode; -} /* initialize to default */ static void iwl_power_init_handle(struct iwl_priv *priv) { struct iwl_power_mgr *pow_data; - int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX; + int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_NUM; struct iwl_powertable_cmd *cmd; int i; u16 lctl; @@ -156,7 +128,7 @@ static void iwl_power_init_handle(struct iwl_priv *priv) IWL_DEBUG_POWER(priv, "adjust power command flags\n"); - for (i = 0; i < IWL_POWER_MAX; i++) { + for (i = 0; i < IWL_POWER_NUM; i++) { cmd = &pow_data->pwr_range_0[i].cmd; if (lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN) @@ -246,33 +218,12 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE || priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE; - /* If on battery, set to 3, - * if plugged into AC power, set to CAM ("continuously aware mode"), - * else user level */ - - switch (setting->system_power_setting) { - case IWL_POWER_SYS_AUTO: - final_mode = iwl_get_auto_power_mode(priv); - break; - case IWL_POWER_SYS_BATTERY: - final_mode = IWL_POWER_INDEX_3; - break; - case IWL_POWER_SYS_AC: - final_mode = IWL_POWER_MODE_CAM; - break; - default: - final_mode = IWL_POWER_INDEX_3; - WARN_ON(1); - } - - if (setting->critical_power_setting > final_mode) - final_mode = setting->critical_power_setting; + final_mode = priv->power_data.user_power_setting; - /* driver only support CAM for non STA network */ - if (priv->iw_mode != NL80211_IFTYPE_STATION) + if (setting->power_disabled) final_mode = IWL_POWER_MODE_CAM; - if (iwl_is_ready_rf(priv) && !setting->power_disabled && + if (iwl_is_ready_rf(priv) && ((setting->power_mode != final_mode) || force)) { struct iwl_powertable_cmd cmd; @@ -289,8 +240,6 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) if (final_mode == IWL_POWER_MODE_CAM) clear_bit(STATUS_POWER_PMI, &priv->status); - else - set_bit(STATUS_POWER_PMI, &priv->status); if (priv->cfg->ops->lib->update_chain_flags && update_chains) priv->cfg->ops->lib->update_chain_flags(priv); @@ -306,51 +255,10 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) } EXPORT_SYMBOL(iwl_power_update_mode); -/* Allow other iwl code to disable/enable power management active - * this will be useful for rate scale to disable PM during heavy - * Tx/Rx activities - */ -int iwl_power_disable_management(struct iwl_priv *priv, u32 ms) -{ - u16 prev_mode; - int ret = 0; - - if (priv->power_data.power_disabled) - return -EBUSY; - - prev_mode = priv->power_data.user_power_setting; - priv->power_data.user_power_setting = IWL_POWER_MODE_CAM; - ret = iwl_power_update_mode(priv, 0); - priv->power_data.power_disabled = 1; - priv->power_data.user_power_setting = prev_mode; - cancel_delayed_work(&priv->set_power_save); - if (ms) - queue_delayed_work(priv->workqueue, &priv->set_power_save, - msecs_to_jiffies(ms)); - - - return ret; -} -EXPORT_SYMBOL(iwl_power_disable_management); - -/* Allow other iwl code to disable/enable power management active - * this will be useful for rate scale to disable PM during high - * volume activities - */ -int iwl_power_enable_management(struct iwl_priv *priv) -{ - int ret = 0; - - priv->power_data.power_disabled = 0; - ret = iwl_power_update_mode(priv, 0); - return ret; -} -EXPORT_SYMBOL(iwl_power_enable_management); - /* set user_power_setting */ int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode) { - if (mode > IWL_POWER_MAX) + if (mode >= IWL_POWER_NUM) return -EINVAL; priv->power_data.user_power_setting = mode; @@ -359,86 +267,12 @@ int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode) } EXPORT_SYMBOL(iwl_power_set_user_mode); -/* set system_power_setting. This should be set by over all - * PM application. - */ -int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode) -{ - if (mode < IWL_POWER_SYS_MAX) - priv->power_data.system_power_setting = mode; - else - return -EINVAL; - return iwl_power_update_mode(priv, 0); -} -EXPORT_SYMBOL(iwl_power_set_system_mode); - /* initialize to default */ void iwl_power_initialize(struct iwl_priv *priv) { iwl_power_init_handle(priv); - priv->power_data.user_power_setting = IWL_POWER_AUTO; - priv->power_data.system_power_setting = IWL_POWER_SYS_AUTO; - priv->power_data.power_disabled = 0; - priv->power_data.is_battery_active = 0; - priv->power_data.critical_power_setting = 0; + priv->power_data.user_power_setting = IWL_POWER_INDEX_1; + /* default to disabled until mac80211 says otherwise */ + priv->power_data.power_disabled = 1; } EXPORT_SYMBOL(iwl_power_initialize); - -/* set critical_power_setting according to temperature value */ -int iwl_power_temperature_change(struct iwl_priv *priv) -{ - int ret = 0; - s32 temperature = KELVIN_TO_CELSIUS(priv->last_temperature); - u16 new_critical = priv->power_data.critical_power_setting; - - if (temperature > IWL_CT_KILL_TEMPERATURE) - return 0; - else if (temperature > IWL_MIN_POWER_TEMPERATURE) - new_critical = IWL_POWER_INDEX_5; - else if (temperature > IWL_REDUCED_POWER_TEMPERATURE) - new_critical = IWL_POWER_INDEX_3; - else - new_critical = IWL_POWER_MODE_CAM; - - if (new_critical != priv->power_data.critical_power_setting) - priv->power_data.critical_power_setting = new_critical; - - if (priv->power_data.critical_power_setting > - priv->power_data.power_mode) - ret = iwl_power_update_mode(priv, 0); - - return ret; -} -EXPORT_SYMBOL(iwl_power_temperature_change); - -static void iwl_bg_set_power_save(struct work_struct *work) -{ - struct iwl_priv *priv = container_of(work, - struct iwl_priv, set_power_save.work); - IWL_DEBUG_POWER(priv, "update power\n"); - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - mutex_lock(&priv->mutex); - - /* on starting association we disable power management - * until association, if association failed then this - * timer will expire and enable PM again. - */ - if (!iwl_is_associated(priv)) - iwl_power_enable_management(priv); - - mutex_unlock(&priv->mutex); -} -void iwl_setup_power_deferred_work(struct iwl_priv *priv) -{ - INIT_DELAYED_WORK(&priv->set_power_save, iwl_bg_set_power_save); -} -EXPORT_SYMBOL(iwl_setup_power_deferred_work); - -void iwl_power_cancel_timeout(struct iwl_priv *priv) -{ - cancel_delayed_work(&priv->set_power_save); -} -EXPORT_SYMBOL(iwl_power_cancel_timeout); diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h index 18963392121e..37ba3bb7a25a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.h +++ b/drivers/net/wireless/iwlwifi/iwl-power.h @@ -40,56 +40,29 @@ enum { IWL_POWER_INDEX_3, IWL_POWER_INDEX_4, IWL_POWER_INDEX_5, - IWL_POWER_AUTO, - IWL_POWER_MAX = IWL_POWER_AUTO, + IWL_POWER_NUM }; -enum { - IWL_POWER_SYS_AUTO, - IWL_POWER_SYS_AC, - IWL_POWER_SYS_BATTERY, - IWL_POWER_SYS_MAX, -}; - - /* Power management (not Tx power) structures */ -#define NOSLP cpu_to_le16(0), 0, 0 -#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0 -#define SLP_TOUT(T) cpu_to_le32((T) * MSEC_TO_USEC) -#define SLP_VEC(X0, X1, X2, X3, X4) {cpu_to_le32(X0), \ - cpu_to_le32(X1), \ - cpu_to_le32(X2), \ - cpu_to_le32(X3), \ - cpu_to_le32(X4)} struct iwl_power_vec_entry { struct iwl_powertable_cmd cmd; u8 no_dtim; }; struct iwl_power_mgr { - spinlock_t lock; - struct iwl_power_vec_entry pwr_range_0[IWL_POWER_MAX]; - struct iwl_power_vec_entry pwr_range_1[IWL_POWER_MAX]; - struct iwl_power_vec_entry pwr_range_2[IWL_POWER_MAX]; + struct iwl_power_vec_entry pwr_range_0[IWL_POWER_NUM]; + struct iwl_power_vec_entry pwr_range_1[IWL_POWER_NUM]; + struct iwl_power_vec_entry pwr_range_2[IWL_POWER_NUM]; u32 dtim_period; /* final power level that used to calculate final power command */ u8 power_mode; - u8 user_power_setting; /* set by user through mac80211 or sysfs */ - u8 system_power_setting; /* set by kernel system tools */ - u8 critical_power_setting; /* set if driver over heated */ - u8 is_battery_active; /* DC/AC power */ - u8 power_disabled; /* flag to disable using power saving level */ + u8 user_power_setting; /* set by user through sysfs */ + u8 power_disabled; /* set by mac80211's CONF_PS */ }; -void iwl_setup_power_deferred_work(struct iwl_priv *priv); -void iwl_power_cancel_timeout(struct iwl_priv *priv); int iwl_power_update_mode(struct iwl_priv *priv, bool force); -int iwl_power_disable_management(struct iwl_priv *priv, u32 ms); -int iwl_power_enable_management(struct iwl_priv *priv); int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode); -int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode); void iwl_power_initialize(struct iwl_priv *priv); -int iwl_power_temperature_change(struct iwl_priv *priv); #endif /* __iwl_power_setting_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 271e5d1f8425..c32ec809053f 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3845,26 +3845,11 @@ static ssize_t show_power_level(struct device *d, { struct iwl_priv *priv = dev_get_drvdata(d); int mode = priv->power_data.user_power_setting; - int system = priv->power_data.system_power_setting; int level = priv->power_data.power_mode; char *p = buf; - switch (system) { - case IWL_POWER_SYS_AUTO: - p += sprintf(p, "SYSTEM:auto"); - break; - case IWL_POWER_SYS_AC: - p += sprintf(p, "SYSTEM:ac"); - break; - case IWL_POWER_SYS_BATTERY: - p += sprintf(p, "SYSTEM:battery"); - break; - } - - p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO) ? - "fixed" : "auto"); - p += sprintf(p, "\tINDEX:%d", level); - p += sprintf(p, "\n"); + p += sprintf(p, "INDEX:%d\t", level); + p += sprintf(p, "USER:%d\n", mode); return p - buf + 1; } @@ -4108,7 +4093,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv) priv->ibss_beacon = NULL; spin_lock_init(&priv->lock); - spin_lock_init(&priv->power_data.lock); spin_lock_init(&priv->sta_lock); spin_lock_init(&priv->hcmd_lock); -- cgit v1.2.3-59-g8ed1b From d6e933993fdad4a270c557fa5317f668bef1d824 Mon Sep 17 00:00:00 2001 From: Mohamed Abbas Date: Fri, 8 May 2009 13:44:39 -0700 Subject: iwlagn: improve rate scale table search iwlagn rate scaling will periodically search other rate scale tables to switch to the best table regarding performance. In the past the number of search tables were 3. Every time the rate scale algorithm goes through these available tables in will stay in current table for some time before start searching again. Recent driver support more feature and antenna, so we have more tables to search. This patch make sure we go through all available tables. Signed-off-by: Mohamed Abbas Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 47 +++++++++++++++++++++++++------ drivers/net/wireless/iwlwifi/iwl-agn-rs.h | 2 ++ 2 files changed, 40 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 0a71bb55d0ee..3fa06afce86a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -100,6 +100,7 @@ struct iwl_scale_tbl_info { u8 is_fat; /* 1 = 40 MHz channel width */ u8 is_dup; /* 1 = duplicated data streams */ u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */ + u8 max_search; /* maximun number of tables we can search */ s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */ u32 current_rate; /* rate_n_flags, uCode API format */ struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ @@ -579,6 +580,7 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags, tbl->is_dup = 0; tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS); tbl->lq_type = LQ_NONE; + tbl->max_search = IWL_MAX_SEARCH; /* legacy rate format */ if (!(rate_n_flags & RATE_MCS_HT_MSK)) { @@ -612,8 +614,10 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags, tbl->lq_type = LQ_MIMO2; /* MIMO3 */ } else { - if (num_of_ant == 3) + if (num_of_ant == 3) { + tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH; tbl->lq_type = LQ_MIMO3; + } } } return 0; @@ -771,6 +775,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta, tbl->is_fat = 0; tbl->is_SGI = 0; + tbl->max_search = IWL_MAX_SEARCH; } rate_mask = rs_get_supported_rates(lq_sta, NULL, tbl->lq_type); @@ -1026,6 +1031,7 @@ static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy, lq_sta->total_failed = 0; lq_sta->total_success = 0; lq_sta->flush_timer = jiffies; + lq_sta->action_counter = 0; } /* @@ -1205,6 +1211,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv, tbl->lq_type = LQ_MIMO2; tbl->is_dup = lq_sta->is_dup; tbl->action = 0; + tbl->max_search = IWL_MAX_SEARCH; rate_mask = lq_sta->active_mimo2_rate; if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap)) @@ -1270,6 +1277,7 @@ static int rs_switch_to_mimo3(struct iwl_priv *priv, tbl->lq_type = LQ_MIMO3; tbl->is_dup = lq_sta->is_dup; tbl->action = 0; + tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH; rate_mask = lq_sta->active_mimo3_rate; if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap)) @@ -1328,6 +1336,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv, tbl->is_dup = lq_sta->is_dup; tbl->lq_type = LQ_SISO; tbl->action = 0; + tbl->max_search = IWL_MAX_SEARCH; rate_mask = lq_sta->active_siso_rate; if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap)) @@ -1384,15 +1393,15 @@ static int rs_move_legacy_other(struct iwl_priv *priv, u8 valid_tx_ant = priv->hw_params.valid_tx_ant; u8 tx_chains_num = priv->hw_params.tx_chains_num; int ret = 0; + u8 update_search_tbl_counter = 0; for (; ;) { + lq_sta->action_counter++; switch (tbl->action) { case IWL_LEGACY_SWITCH_ANTENNA1: case IWL_LEGACY_SWITCH_ANTENNA2: IWL_DEBUG_RATE(priv, "LQ: Legacy toggle Antenna\n"); - lq_sta->action_counter++; - if ((tbl->action == IWL_LEGACY_SWITCH_ANTENNA1 && tx_chains_num <= 1) || (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2 && @@ -1408,6 +1417,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv, if (rs_toggle_antenna(valid_tx_ant, &search_tbl->current_rate, search_tbl)) { + update_search_tbl_counter = 1; rs_set_expected_tpt_table(lq_sta, search_tbl); goto out; } @@ -1489,6 +1499,8 @@ out: tbl->action++; if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC) tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; + if (update_search_tbl_counter) + search_tbl->action = tbl->action; return 0; } @@ -1511,6 +1523,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, u8 start_action = tbl->action; u8 valid_tx_ant = priv->hw_params.valid_tx_ant; u8 tx_chains_num = priv->hw_params.tx_chains_num; + u8 update_search_tbl_counter = 0; int ret; for (;;) { @@ -1531,8 +1544,10 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, memcpy(search_tbl, tbl, sz); if (rs_toggle_antenna(valid_tx_ant, - &search_tbl->current_rate, search_tbl)) + &search_tbl->current_rate, search_tbl)) { + update_search_tbl_counter = 1; goto out; + } break; case IWL_SISO_SWITCH_MIMO2_AB: case IWL_SISO_SWITCH_MIMO2_AC: @@ -1586,6 +1601,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, search_tbl->current_rate = rate_n_flags_from_tbl(priv, search_tbl, index, is_green); + update_search_tbl_counter = 1; goto out; case IWL_SISO_SWITCH_MIMO3_ABC: IWL_DEBUG_RATE(priv, "LQ: SISO switch to MIMO3\n"); @@ -1617,6 +1633,9 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, tbl->action++; if (tbl->action > IWL_SISO_SWITCH_MIMO3_ABC) tbl->action = IWL_SISO_SWITCH_ANTENNA1; + if (update_search_tbl_counter) + search_tbl->action = tbl->action; + return 0; } @@ -1638,6 +1657,7 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv, u8 start_action = tbl->action; u8 valid_tx_ant = priv->hw_params.valid_tx_ant; u8 tx_chains_num = priv->hw_params.tx_chains_num; + u8 update_search_tbl_counter = 0; int ret; for (;;) { @@ -1655,8 +1675,10 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv, memcpy(search_tbl, tbl, sz); if (rs_toggle_antenna(valid_tx_ant, - &search_tbl->current_rate, search_tbl)) + &search_tbl->current_rate, search_tbl)) { + update_search_tbl_counter = 1; goto out; + } break; case IWL_MIMO2_SWITCH_SISO_A: case IWL_MIMO2_SWITCH_SISO_B: @@ -1713,6 +1735,7 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv, search_tbl->current_rate = rate_n_flags_from_tbl(priv, search_tbl, index, is_green); + update_search_tbl_counter = 1; goto out; case IWL_MIMO2_SWITCH_MIMO3_ABC: @@ -1745,6 +1768,9 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv, tbl->action++; if (tbl->action > IWL_MIMO2_SWITCH_MIMO3_ABC) tbl->action = IWL_MIMO2_SWITCH_ANTENNA1; + if (update_search_tbl_counter) + search_tbl->action = tbl->action; + return 0; } @@ -1768,6 +1794,7 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv, u8 valid_tx_ant = priv->hw_params.valid_tx_ant; u8 tx_chains_num = priv->hw_params.tx_chains_num; int ret; + u8 update_search_tbl_counter = 0; for (;;) { lq_sta->action_counter++; @@ -1866,6 +1893,7 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv, search_tbl->current_rate = rate_n_flags_from_tbl(priv, search_tbl, index, is_green); + update_search_tbl_counter = 1; goto out; } tbl->action++; @@ -1882,6 +1910,9 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv, tbl->action++; if (tbl->action > IWL_MIMO3_SWITCH_GI) tbl->action = IWL_MIMO3_SWITCH_ANTENNA1; + if (update_search_tbl_counter) + search_tbl->action = tbl->action; + return 0; } @@ -2326,8 +2357,7 @@ lq_update: * before next round of mode comparisons. */ tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); if (is_legacy(tbl1->lq_type) && !conf_is_ht(conf) && - lq_sta->action_counter >= 1) { - lq_sta->action_counter = 0; + lq_sta->action_counter > tbl1->max_search) { IWL_DEBUG_RATE(priv, "LQ: STAY in legacy table\n"); rs_set_stay_in_table(priv, 1, lq_sta); } @@ -2336,7 +2366,7 @@ lq_update: * have been tried and compared, stay in this best modulation * mode for a while before next round of mode comparisons. */ if (lq_sta->enable_counter && - (lq_sta->action_counter >= IWL_ACTION_LIMIT)) { + (lq_sta->action_counter >= tbl1->max_search)) { if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) && (lq_sta->tx_agg_tid_en & (1 << tid)) && (tid != MAX_TID_COUNT)) { @@ -2350,7 +2380,6 @@ lq_update: lq_sta, sta); } } - lq_sta->action_counter = 0; rs_set_stay_in_table(priv, 0, lq_sta); } } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h index f875136bc5dc..25050bf315a2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h @@ -275,6 +275,8 @@ enum { #define IWL_MIMO3_SWITCH_GI 8 +#define IWL_MAX_11N_MIMO3_SEARCH IWL_MIMO3_SWITCH_GI +#define IWL_MAX_SEARCH IWL_MIMO2_SWITCH_MIMO3_ABC /*FIXME:RS:add possible actions for MIMO3*/ -- cgit v1.2.3-59-g8ed1b From 9906a07e1607e86957ac8780c35a9acf425c4c95 Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Fri, 8 May 2009 13:44:40 -0700 Subject: iwlwifi: more descriptive unsupported hardware message Somehow these pre-production cards are showing up in the community. With this message we hope that it will be clear that the hardware is not supported. Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-eeprom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 75517d05df08..401438aec19c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -285,7 +285,7 @@ int iwl_eeprom_check_version(struct iwl_priv *priv) return 0; err: - IWL_ERR(priv, "Unsupported EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n", + IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n", eeprom_ver, priv->cfg->eeprom_ver, calib_ver, priv->cfg->eeprom_calib_ver); return -EINVAL; -- cgit v1.2.3-59-g8ed1b From 43121432e2d3a9018c40e820b1e44f3f180aa0d6 Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Fri, 8 May 2009 13:44:41 -0700 Subject: iwl3945: read rev id in nic config Read rev id in nic_config instead of nic_init. Nic_config has some checking for rev_id but we actually don't read the rev_id in there. Signed-off-by: Abhijeet Kolekar Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-3945.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 41f1d66cfeba..5b0c6e5bda92 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -1110,6 +1110,11 @@ static void iwl3945_nic_config(struct iwl_priv *priv) spin_lock_irqsave(&priv->lock, flags); + /* Determine HW type */ + pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id); + + IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id); + if (rev_id & PCI_CFG_REV_ID_BIT_RTP) IWL_DEBUG_INFO(priv, "RTP type \n"); else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) { @@ -1163,7 +1168,6 @@ static void iwl3945_nic_config(struct iwl_priv *priv) int iwl3945_hw_nic_init(struct iwl_priv *priv) { - u8 rev_id; int rc; unsigned long flags; struct iwl_rx_queue *rxq = &priv->rxq; @@ -1172,12 +1176,6 @@ int iwl3945_hw_nic_init(struct iwl_priv *priv) priv->cfg->ops->lib->apm_ops.init(priv); spin_unlock_irqrestore(&priv->lock, flags); - /* Determine HW type */ - rc = pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id); - if (rc) - return rc; - IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id); - rc = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN); if (rc) return rc; -- cgit v1.2.3-59-g8ed1b From fff7a4346c07c30a39910c3b627434fc0e7ccc33 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 8 May 2009 13:44:42 -0700 Subject: iwlwifi: use #define instead of hard coded value Instead of hard coded value, use the define in iwl-commands.h for better code maintenance Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 8 ++++---- drivers/net/wireless/iwlwifi/iwl-scan.c | 14 ++++++++------ 2 files changed, 12 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 112bfa50b8fa..597d9552fe4b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -960,10 +960,10 @@ void iwl_set_rxon_chain(struct iwl_priv *priv) if (iwl_is_monitor_mode(priv) && !(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) && ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)) { - rx_chain = 0x07 << RXON_RX_CHAIN_VALID_POS; - rx_chain |= 0x06 << RXON_RX_CHAIN_FORCE_SEL_POS; - rx_chain |= 0x07 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS; - rx_chain |= 0x01 << RXON_RX_CHAIN_DRIVER_FORCE_POS; + rx_chain = ANT_ABC << RXON_RX_CHAIN_VALID_POS; + rx_chain |= ANT_BC << RXON_RX_CHAIN_FORCE_SEL_POS; + rx_chain |= ANT_ABC << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS; + rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; } priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain); diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index dd8766b80b34..065214b55895 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -580,9 +580,10 @@ static void iwl_bg_request_scan(struct work_struct *data) int ret = 0; u32 rate_flags = 0; u16 cmd_len; + u16 rx_chain = 0; enum ieee80211_band band; u8 n_probes = 0; - u8 rx_chain = priv->hw_params.valid_rx_ant; + u8 rx_ant = priv->hw_params.valid_rx_ant; u8 rate; bool is_active = false; @@ -723,7 +724,7 @@ static void iwl_bg_request_scan(struct work_struct *data) * Avoid A (0x1) because of its off-channel reception on A-band. */ if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) - rx_chain = 0x6; + rx_ant = ANT_BC; } else { IWL_WARN(priv, "Invalid scan band count\n"); goto done; @@ -735,10 +736,11 @@ static void iwl_bg_request_scan(struct work_struct *data) scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags); /* MIMO is not used here, but value is required */ - scan->rx_chain = RXON_RX_CHAIN_DRIVER_FORCE_MSK | - cpu_to_le16((0x7 << RXON_RX_CHAIN_VALID_POS) | - (rx_chain << RXON_RX_CHAIN_FORCE_SEL_POS) | - (0x7 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS)); + rx_chain |= ANT_ABC << RXON_RX_CHAIN_VALID_POS; + rx_chain |= ANT_ABC << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS; + rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; + rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; + scan->rx_chain = cpu_to_le16(rx_chain); cmd_len = iwl_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, priv->scan_request->ie, -- cgit v1.2.3-59-g8ed1b From 38167459da50e3fe9a10635308bfb0048cc36e8e Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 8 May 2009 13:44:43 -0700 Subject: iwlagn: show current rate scale data in debugfs Add "rate_scale_data" debugfs file to show current bit rate (HT and Legacy), plus additional information (rssi, noise, tsf, beacon time stamp). Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 42 +++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 3fa06afce86a..4c88e8715df2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -161,6 +161,7 @@ struct iwl_lq_sta { #ifdef CONFIG_MAC80211_DEBUGFS struct dentry *rs_sta_dbgfs_scale_table_file; struct dentry *rs_sta_dbgfs_stats_table_file; + struct dentry *rs_sta_dbgfs_rate_scale_data_file; struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file; u32 dbg_fixed_rate; #endif @@ -2984,6 +2985,43 @@ static const struct file_operations rs_sta_dbgfs_stats_table_ops = { .open = open_file_generic, }; +static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file, + char __user *user_buf, size_t count, loff_t *ppos) +{ + char buff[120]; + int desc = 0; + ssize_t ret; + + struct iwl_lq_sta *lq_sta = file->private_data; + struct iwl_priv *priv; + struct iwl_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl]; + + priv = lq_sta->drv; + + if (is_Ht(tbl->lq_type)) + desc += sprintf(buff+desc, + "Bit Rate= %d Mb/s\n", + tbl->expected_tpt[lq_sta->last_txrate_idx]); + else + desc += sprintf(buff+desc, + "Bit Rate= %d Mb/s\n", + iwl_rates[lq_sta->last_txrate_idx].ieee >> 1); + desc += sprintf(buff+desc, + "Signal Level= %d dBm\tNoise Level= %d dBm\n", + priv->last_rx_rssi, priv->last_rx_noise); + desc += sprintf(buff+desc, + "Tsf= 0x%llx\tBeacon time= 0x%08X\n", + priv->last_tsf, priv->last_beacon_time); + + ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); + return ret; +} + +static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = { + .read = rs_sta_dbgfs_rate_scale_data_read, + .open = open_file_generic, +}; + static void rs_add_debugfs(void *priv, void *priv_sta, struct dentry *dir) { @@ -2994,6 +3032,9 @@ static void rs_add_debugfs(void *priv, void *priv_sta, lq_sta->rs_sta_dbgfs_stats_table_file = debugfs_create_file("rate_stats_table", 0600, dir, lq_sta, &rs_sta_dbgfs_stats_table_ops); + lq_sta->rs_sta_dbgfs_rate_scale_data_file = + debugfs_create_file("rate_scale_data", 0600, dir, + lq_sta, &rs_sta_dbgfs_rate_scale_data_ops); lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file = debugfs_create_u8("tx_agg_tid_enable", 0600, dir, &lq_sta->tx_agg_tid_en); @@ -3005,6 +3046,7 @@ static void rs_remove_debugfs(void *priv, void *priv_sta) struct iwl_lq_sta *lq_sta = priv_sta; debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file); debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); + debugfs_remove(lq_sta->rs_sta_dbgfs_rate_scale_data_file); debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file); } #endif -- cgit v1.2.3-59-g8ed1b From 0b4d0ab44fa2f7bda7b14312741ba3f337a02d5a Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 8 May 2009 13:44:44 -0700 Subject: iwlwifi: show qos AC parameters Show current qos AC parameters in sysfs Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 13a35dc710a4..3ebf6cf53a51 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2475,6 +2475,26 @@ static ssize_t show_power_level(struct device *d, static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level, store_power_level); +static ssize_t show_qos(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; + char *p = buf; + int q; + + for (q = 0; q < AC_NUM; q++) { + p += sprintf(p, "\tcw_min\tcw_max\taifsn\ttxop\n"); + p += sprintf(p, "AC[%d]\t%u\t%u\t%u\t%u\n", q, + priv->qos_data.def_qos_parm.ac[q].cw_min, + priv->qos_data.def_qos_parm.ac[q].cw_max, + priv->qos_data.def_qos_parm.ac[q].aifsn, + priv->qos_data.def_qos_parm.ac[q].edca_txop); + } + + return p - buf + 1; +} + +static DEVICE_ATTR(qos, S_IRUGO, show_qos, NULL); static ssize_t show_statistics(struct device *d, struct device_attribute *attr, char *buf) @@ -2572,7 +2592,7 @@ static struct attribute *iwl_sysfs_entries[] = { &dev_attr_debug_level.attr, #endif &dev_attr_version.attr, - + &dev_attr_qos.attr, NULL }; -- cgit v1.2.3-59-g8ed1b From f2c95b04aba3510323381fe49a0539c23da2e8f4 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 8 May 2009 13:44:45 -0700 Subject: iwlwifi: default WMM AC parameters Set the default WMM AC parameters for BK/BE/VI/VO parameters: AC CWmin CW max AIFSN TXOP Limit TXOP Limit (802.11b) (802.11a/g) AC_BK 15 1023 7 0 0 AC_BE 15 1023 3 0 0 AC_VI 7 15 2 188 94 (6.016ms) (3.008ms) AC_VO 3 7 2 102 47 (3.264ms) (1.504ms) Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 597d9552fe4b..5393fb3f452c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -273,6 +273,14 @@ void iwl_activate_qos(struct iwl_priv *priv, u8 force) } EXPORT_SYMBOL(iwl_activate_qos); +/* + * AC CWmin CW max AIFSN TXOP Limit TXOP Limit + * (802.11b) (802.11a/g) + * AC_BK 15 1023 7 0 0 + * AC_BE 15 1023 3 0 0 + * AC_VI 7 15 2 6.016ms 3.008ms + * AC_VO 3 7 2 3.264ms 1.504ms + */ void iwl_reset_qos(struct iwl_priv *priv) { u16 cw_min = 15; @@ -304,6 +312,7 @@ void iwl_reset_qos(struct iwl_priv *priv) if (priv->qos_data.qos_active) aifs = 3; + /* AC_BE */ priv->qos_data.def_qos_parm.ac[0].cw_min = cpu_to_le16(cw_min); priv->qos_data.def_qos_parm.ac[0].cw_max = cpu_to_le16(cw_max); priv->qos_data.def_qos_parm.ac[0].aifsn = aifs; @@ -311,6 +320,7 @@ void iwl_reset_qos(struct iwl_priv *priv) priv->qos_data.def_qos_parm.ac[0].reserved1 = 0; if (priv->qos_data.qos_active) { + /* AC_BK */ i = 1; priv->qos_data.def_qos_parm.ac[i].cw_min = cpu_to_le16(cw_min); priv->qos_data.def_qos_parm.ac[i].cw_max = cpu_to_le16(cw_max); @@ -318,11 +328,12 @@ void iwl_reset_qos(struct iwl_priv *priv) priv->qos_data.def_qos_parm.ac[i].edca_txop = 0; priv->qos_data.def_qos_parm.ac[i].reserved1 = 0; + /* AC_VI */ i = 2; priv->qos_data.def_qos_parm.ac[i].cw_min = cpu_to_le16((cw_min + 1) / 2 - 1); priv->qos_data.def_qos_parm.ac[i].cw_max = - cpu_to_le16(cw_max); + cpu_to_le16(cw_min); priv->qos_data.def_qos_parm.ac[i].aifsn = 2; if (is_legacy) priv->qos_data.def_qos_parm.ac[i].edca_txop = @@ -332,11 +343,12 @@ void iwl_reset_qos(struct iwl_priv *priv) cpu_to_le16(3008); priv->qos_data.def_qos_parm.ac[i].reserved1 = 0; + /* AC_VO */ i = 3; priv->qos_data.def_qos_parm.ac[i].cw_min = cpu_to_le16((cw_min + 1) / 4 - 1); priv->qos_data.def_qos_parm.ac[i].cw_max = - cpu_to_le16((cw_max + 1) / 2 - 1); + cpu_to_le16((cw_min + 1) / 2 - 1); priv->qos_data.def_qos_parm.ac[i].aifsn = 2; priv->qos_data.def_qos_parm.ac[i].reserved1 = 0; if (is_legacy) -- cgit v1.2.3-59-g8ed1b From 19eddca67628e5fb722e4ebbbba8c307a884d0e8 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Fri, 8 May 2009 17:54:50 -0700 Subject: ath9k: Remove bogus break after return Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 5879c731e9e7..9e1db85e5651 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1617,11 +1617,9 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) switch (type) { case ATH9K_RESET_POWER_ON: return ath9k_hw_set_reset_power_on(ah); - break; case ATH9K_RESET_WARM: case ATH9K_RESET_COLD: return ath9k_hw_set_reset(ah, type); - break; default: return false; } -- cgit v1.2.3-59-g8ed1b From 8fbff4b838c53945d6baeafe609c627000f85cd6 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Fri, 8 May 2009 17:54:51 -0700 Subject: ath9k: Cleanup ineffective return values This patch makes the return type of some of the functions void as those functions always return true Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/eeprom.c | 51 +++++++---------------------- drivers/net/wireless/ath/ath9k/eeprom.h | 2 +- drivers/net/wireless/ath/ath9k/hw.c | 57 +++++++++++---------------------- drivers/net/wireless/ath/ath9k/hw.h | 2 +- drivers/net/wireless/ath/ath9k/phy.c | 7 ++-- drivers/net/wireless/ath/ath9k/phy.h | 2 +- 6 files changed, 36 insertions(+), 85 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index 44fee5ae8925..a2fda702b620 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c @@ -694,7 +694,7 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah, #undef TMP_VAL_VPD_TABLE } -static bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, +static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, struct ath9k_channel *chan, int16_t *pTxPowerIndexOffset) { @@ -805,11 +805,9 @@ static bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, } *pTxPowerIndexOffset = 0; - - return true; } -static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah, +static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah, struct ath9k_channel *chan, int16_t *ratesArray, u16 cfgCtl, @@ -1041,10 +1039,9 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah, ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0]; ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0]; } - return true; } -static int ath9k_hw_4k_set_txpower(struct ath_hw *ah, +static void ath9k_hw_4k_set_txpower(struct ath_hw *ah, struct ath9k_channel *chan, u16 cfgCtl, u8 twiceAntennaReduction, @@ -1065,22 +1062,13 @@ static int ath9k_hw_4k_set_txpower(struct ath_hw *ah, ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; } - if (!ath9k_hw_set_4k_power_per_rate_table(ah, chan, + ath9k_hw_set_4k_power_per_rate_table(ah, chan, &ratesArray[0], cfgCtl, twiceAntennaReduction, twiceMaxRegulatoryPower, - powerLimit)) { - DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, - "ath9k_hw_set_txpower: unable to set " - "tx power per rate table\n"); - return -EIO; - } + powerLimit); - if (!ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset)) { - DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, - "ath9k_hw_set_txpower: unable to set power table\n"); - return -EIO; - } + ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset); for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); @@ -1168,7 +1156,6 @@ static int ath9k_hw_4k_set_txpower(struct ath_hw *ah, else ah->regulatory.max_power_level = ratesArray[i]; - return 0; } static void ath9k_hw_4k_set_addac(struct ath_hw *ah, @@ -2103,7 +2090,7 @@ static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah, return; } -static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, +static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, struct ath9k_channel *chan, int16_t *pTxPowerIndexOffset) { @@ -2255,13 +2242,11 @@ static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, } *pTxPowerIndexOffset = 0; - - return true; #undef SM_PD_GAIN #undef SM_PDGAIN_B } -static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah, +static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah, struct ath9k_channel *chan, int16_t *ratesArray, u16 cfgCtl, @@ -2549,10 +2534,9 @@ static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah, targetPowerCckExt.tPow2x[0]; } } - return true; } -static int ath9k_hw_def_set_txpower(struct ath_hw *ah, +static void ath9k_hw_def_set_txpower(struct ath_hw *ah, struct ath9k_channel *chan, u16 cfgCtl, u8 twiceAntennaReduction, @@ -2575,22 +2559,13 @@ static int ath9k_hw_def_set_txpower(struct ath_hw *ah, ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; } - if (!ath9k_hw_set_def_power_per_rate_table(ah, chan, + ath9k_hw_set_def_power_per_rate_table(ah, chan, &ratesArray[0], cfgCtl, twiceAntennaReduction, twiceMaxRegulatoryPower, - powerLimit)) { - DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, - "ath9k_hw_set_txpower: unable to set " - "tx power per rate table\n"); - return -EIO; - } + powerLimit); - if (!ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset)) { - DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, - "ath9k_hw_set_txpower: unable to set power table\n"); - return -EIO; - } + ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset); for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); @@ -2717,8 +2692,6 @@ static int ath9k_hw_def_set_txpower(struct ath_hw *ah, "Invalid chainmask configuration\n"); break; } - - return 0; } static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah, diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 7c59dc47f912..67b8bd12941a 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h @@ -494,7 +494,7 @@ struct eeprom_ops { struct ath9k_channel *chan); void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan); void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan); - int (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan, + void (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan, u16 cfgCtl, u8 twiceAntennaReduction, u8 twiceMaxRegulatoryPower, u8 powerLimit); u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz); diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 9e1db85e5651..4acfab514916 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1274,7 +1274,6 @@ static int ath9k_hw_process_ini(struct ath_hw *ah, int i, regWrites = 0; struct ieee80211_channel *channel = chan->chan; u32 modesIndex, freqIndex; - int status; switch (chan->chanmode) { case CHANNEL_A: @@ -1376,17 +1375,12 @@ static int ath9k_hw_process_ini(struct ath_hw *ah, if (OLC_FOR_AR9280_20_LATER) ath9k_olc_init(ah); - status = ah->eep_ops->set_txpower(ah, chan, - ath9k_regd_get_ctl(&ah->regulatory, chan), - channel->max_antenna_gain * 2, - channel->max_power * 2, - min((u32) MAX_RATE_POWER, - (u32) ah->regulatory.power_limit)); - if (status != 0) { - DPRINTF(ah->ah_sc, ATH_DBG_FATAL, - "Error initializing transmit power\n"); - return -EIO; - } + ah->eep_ops->set_txpower(ah, chan, + ath9k_regd_get_ctl(&ah->regulatory, chan), + channel->max_antenna_gain * 2, + channel->max_power * 2, + min((u32) MAX_RATE_POWER, + (u32) ah->regulatory.power_limit)); if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { DPRINTF(ah->ah_sc, ATH_DBG_FATAL, @@ -1701,11 +1695,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, ath9k_hw_set_regs(ah, chan, macmode); if (AR_SREV_9280_10_OR_LATER(ah)) { - if (!(ath9k_hw_ar9280_set_channel(ah, chan))) { - DPRINTF(ah->ah_sc, ATH_DBG_FATAL, - "Failed to set channel\n"); - return false; - } + ath9k_hw_ar9280_set_channel(ah, chan); } else { if (!(ath9k_hw_set_channel(ah, chan))) { DPRINTF(ah->ah_sc, ATH_DBG_FATAL, @@ -1714,16 +1704,12 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, } } - if (ah->eep_ops->set_txpower(ah, chan, + ah->eep_ops->set_txpower(ah, chan, ath9k_regd_get_ctl(&ah->regulatory, chan), channel->max_antenna_gain * 2, channel->max_power * 2, min((u32) MAX_RATE_POWER, - (u32) ah->regulatory.power_limit)) != 0) { - DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, - "Error initializing transmit power\n"); - return false; - } + (u32) ah->regulatory.power_limit)); synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; if (IS_CHAN_B(chan)) @@ -2311,13 +2297,11 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); - if (AR_SREV_9280_10_OR_LATER(ah)) { - if (!(ath9k_hw_ar9280_set_channel(ah, chan))) - return -EIO; - } else { + if (AR_SREV_9280_10_OR_LATER(ah)) + ath9k_hw_ar9280_set_channel(ah, chan); + else if (!(ath9k_hw_set_channel(ah, chan))) return -EIO; - } for (i = 0; i < AR_NUM_DCU; i++) REG_WRITE(ah, AR_DQCUMASK(i), 1 << i); @@ -3748,22 +3732,19 @@ bool ath9k_hw_disable(struct ath_hw *ah) return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD); } -bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit) +void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit) { struct ath9k_channel *chan = ah->curchan; struct ieee80211_channel *channel = chan->chan; ah->regulatory.power_limit = min(limit, (u32) MAX_RATE_POWER); - if (ah->eep_ops->set_txpower(ah, chan, - ath9k_regd_get_ctl(&ah->regulatory, chan), - channel->max_antenna_gain * 2, - channel->max_power * 2, - min((u32) MAX_RATE_POWER, - (u32) ah->regulatory.power_limit)) != 0) - return false; - - return true; + ah->eep_ops->set_txpower(ah, chan, + ath9k_regd_get_ctl(&ah->regulatory, chan), + channel->max_antenna_gain * 2, + channel->max_power * 2, + min((u32) MAX_RATE_POWER, + (u32) ah->regulatory.power_limit)); } void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac) diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index ddb24c47ebcf..dd8508ef6e05 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -590,7 +590,7 @@ u32 ath9k_hw_getrxfilter(struct ath_hw *ah); void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits); bool ath9k_hw_phy_disable(struct ath_hw *ah); bool ath9k_hw_disable(struct ath_hw *ah); -bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit); +void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit); void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac); void ath9k_hw_setopmode(struct ath_hw *ah); void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1); diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c index 5ec9ce91d979..aaa941561c36 100644 --- a/drivers/net/wireless/ath/ath9k/phy.c +++ b/drivers/net/wireless/ath/ath9k/phy.c @@ -96,9 +96,8 @@ ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) return true; } -bool -ath9k_hw_ar9280_set_channel(struct ath_hw *ah, - struct ath9k_channel *chan) +void ath9k_hw_ar9280_set_channel(struct ath_hw *ah, + struct ath9k_channel *chan) { u16 bMode, fracMode, aModeRefSel = 0; u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0; @@ -169,8 +168,6 @@ ath9k_hw_ar9280_set_channel(struct ath_hw *ah, ah->curchan = chan; ah->curchan_rad_index = -1; - - return true; } static void diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h index 296d0e985f25..c70f530642f6 100644 --- a/drivers/net/wireless/ath/ath9k/phy.h +++ b/drivers/net/wireless/ath/ath9k/phy.h @@ -17,7 +17,7 @@ #ifndef PHY_H #define PHY_H -bool ath9k_hw_ar9280_set_channel(struct ath_hw *ah, +void ath9k_hw_ar9280_set_channel(struct ath_hw *ah, struct ath9k_channel *chan); bool ath9k_hw_set_channel(struct ath_hw *ah, -- cgit v1.2.3-59-g8ed1b