From 35b3ac470b982ded560e1b2ec9206a8d186c3459 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 10 Jan 2011 10:26:00 +0800 Subject: [PATCH 01/10] iwmc3200wifi: Return proper error for iwm_if_alloc In the case of alloc_netdev_mq failure and kmalloc failure, current implementation returns ERR_PTR(0). As a result, the caller of iwm_if_alloc does not catch the error by IS_ERR macro. Fix it by setting proper error code for ret variable in the failure cases. Signed-off-by: Axel Lin Signed-off-by: John W. Linville --- drivers/net/wireless/iwmc3200wifi/netdev.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/iwmc3200wifi/netdev.c b/drivers/net/wireless/iwmc3200wifi/netdev.c index 13a69ebf2a94..5091d77e02ce 100644 --- a/drivers/net/wireless/iwmc3200wifi/netdev.c +++ b/drivers/net/wireless/iwmc3200wifi/netdev.c @@ -126,6 +126,7 @@ void *iwm_if_alloc(int sizeof_bus, struct device *dev, ndev = alloc_netdev_mq(0, "wlan%d", ether_setup, IWM_TX_QUEUES); if (!ndev) { dev_err(dev, "no memory for network device instance\n"); + ret = -ENOMEM; goto out_priv; } @@ -138,6 +139,7 @@ void *iwm_if_alloc(int sizeof_bus, struct device *dev, GFP_KERNEL); if (!iwm->umac_profile) { dev_err(dev, "Couldn't alloc memory for profile\n"); + ret = -ENOMEM; goto out_profile; } From ccbd4d412dde4b7e858159e5cc8ba7ee4a6cac07 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Tue, 11 Jan 2011 00:47:44 +0100 Subject: [PATCH 02/10] rt2x00: Don't leak mem in error path of rt2x00lib_request_firmware() We need to release_firmware() in order not to leak memory. Signed-off-by: Jesper Juhl Acked-by: Ivo van Doorn Acked-by: Pekka Enberg Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00firmware.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c index f0e1eb72befc..be0ff78c1b16 100644 --- a/drivers/net/wireless/rt2x00/rt2x00firmware.c +++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c @@ -58,6 +58,7 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev) if (!fw || !fw->size || !fw->data) { ERROR(rt2x00dev, "Failed to read Firmware.\n"); + release_firmware(fw); return -ENOENT; } From 8d661f1e462d50bd83de87ee628aaf820ce3c66c Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Tue, 11 Jan 2011 16:14:24 -0800 Subject: [PATCH 03/10] ieee80211: correct IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK macro It is defined in include/linux/ieee80211.h. As per IEEE spec. bit6 to bit15 in block ack parameter represents buffer size. So the bitmask should be 0xFFC0. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Cc: stable@kernel.org Reviewed-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/ieee80211.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 6042228954a7..294169e31364 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -959,7 +959,7 @@ struct ieee80211_ht_info { /* block-ack parameters */ #define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002 #define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C -#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFA0 +#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFC0 #define IEEE80211_DELBA_PARAM_TID_MASK 0xF000 #define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800 From 681c4d07dd5b2ce2ad9f6dbbf7841e479fbc7754 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 12 Jan 2011 13:40:33 +0100 Subject: [PATCH 04/10] mac80211: fix lockdep warning Since the introduction of the fixes for the reorder timer, mac80211 will cause lockdep warnings because lockdep confuses local->skb_queue and local->rx_skb_queue and treats their lock as the same. However, their locks are different, and are valid in different contexts (the former is used in IRQ context, the latter in BH only) and the only thing to be done is mark the former as a different lock class so that lockdep can tell the difference. Reported-by: Larry Finger Reported-by: Sujith Reported-by: Miles Lane Tested-by: Sujith Tested-by: Johannes Berg Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/main.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 485d36bc9a46..a46ff06d7cb8 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -39,6 +39,8 @@ module_param(ieee80211_disable_40mhz_24ghz, bool, 0644); MODULE_PARM_DESC(ieee80211_disable_40mhz_24ghz, "Disable 40MHz support in the 2.4GHz band"); +static struct lock_class_key ieee80211_rx_skb_queue_class; + void ieee80211_configure_filter(struct ieee80211_local *local) { u64 mc; @@ -569,7 +571,15 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, spin_lock_init(&local->filter_lock); spin_lock_init(&local->queue_stop_reason_lock); - skb_queue_head_init(&local->rx_skb_queue); + /* + * The rx_skb_queue is only accessed from tasklets, + * but other SKB queues are used from within IRQ + * context. Therefore, this one needs a different + * locking class so our direct, non-irq-safe use of + * the queue's lock doesn't throw lockdep warnings. + */ + skb_queue_head_init_class(&local->rx_skb_queue, + &ieee80211_rx_skb_queue_class); INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); From 82694f764dad783a123394e2220b92b9be721b43 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 12 Jan 2011 15:18:11 +0200 Subject: [PATCH 05/10] mac80211: use maximum number of AMPDU frames as default in BA RX When the buffer size is set to zero in the block ack parameter set field, we should use the maximum supported number of subframes. The existing code was bogus and was doing some unnecessary calculations that lead to wrong values. Thanks Johannes for helping me figure this one out. Cc: stable@kernel.org Cc: Johannes Berg Signed-off-by: Luciano Coelho Reviewed-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/agg-rx.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index f138b195d657..227ca82eef72 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c @@ -185,8 +185,6 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, struct ieee80211_mgmt *mgmt, size_t len) { - struct ieee80211_hw *hw = &local->hw; - struct ieee80211_conf *conf = &hw->conf; struct tid_ampdu_rx *tid_agg_rx; u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status; u8 dialog_token; @@ -231,13 +229,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, goto end_no_lock; } /* determine default buffer size */ - if (buf_size == 0) { - struct ieee80211_supported_band *sband; - - sband = local->hw.wiphy->bands[conf->channel->band]; - buf_size = IEEE80211_MIN_AMPDU_BUF; - buf_size = buf_size << sband->ht_cap.ampdu_factor; - } + if (buf_size == 0) + buf_size = IEEE80211_MAX_AMPDU_BUF; /* examine state machine */ From 58c5296991d233f2e492aa7a884635bba478cf12 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 13 Jan 2011 18:19:29 -0800 Subject: [PATCH 06/10] ath9k_hw: ASPM interoperability fix for AR9380/AR9382 There is an interoperability with AR9382/AR9380 in L1 state with a few root complexes which can cause a hang. This is fixed by setting some work around bits on the PCIE PHY. We fix by using a new ini array to modify these bits when the radio is idle. Cc: stable@kernel.org Cc: Jack Lee Cc: Carl Huang Cc: David Quan Cc: Nael Atallah Cc: Sarvesh Shrivastava Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h | 2 +- drivers/net/wireless/ath/ath9k/ar9003_hw.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index 81f9cf294dec..9ecca93392e8 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h @@ -1842,7 +1842,7 @@ static const u32 ar9300_2p2_soc_preamble[][2] = { static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2[][2] = { /* Addr allmodes */ - {0x00004040, 0x08212e5e}, + {0x00004040, 0x0821265e}, {0x00004040, 0x0008003b}, {0x00004044, 0x00000000}, }; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 6137634e46ca..06fb2c850535 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -146,8 +146,8 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) /* Sleep Setting */ INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, - ar9300PciePhy_clkreq_enable_L1_2p2, - ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p2), + ar9300PciePhy_pll_on_clkreq_disable_L1_2p2, + ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2), 2); /* Fast clock modal settings */ From dc738cb6c5d5594de4bdf3b7839a250b032152e7 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Sun, 16 Jan 2011 10:56:37 +0530 Subject: [PATCH 07/10] ath9k_htc: Fix endian issue in tx header Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 2 +- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 1ce506f23110..780ac5eac501 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -78,7 +78,7 @@ struct tx_frame_hdr { u8 node_idx; u8 vif_idx; u8 tidno; - u32 flags; /* ATH9K_HTC_TX_* */ + __be32 flags; /* ATH9K_HTC_TX_* */ u8 key_type; u8 keyix; u8 reserved[26]; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 33f36029fa4f..7a5ffca21958 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -113,6 +113,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) if (ieee80211_is_data(fc)) { struct tx_frame_hdr tx_hdr; + u32 flags = 0; u8 *qc; memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr)); @@ -136,13 +137,14 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) /* Check for RTS protection */ if (priv->hw->wiphy->rts_threshold != (u32) -1) if (skb->len > priv->hw->wiphy->rts_threshold) - tx_hdr.flags |= ATH9K_HTC_TX_RTSCTS; + flags |= ATH9K_HTC_TX_RTSCTS; /* CTS-to-self */ - if (!(tx_hdr.flags & ATH9K_HTC_TX_RTSCTS) && + if (!(flags & ATH9K_HTC_TX_RTSCTS) && (priv->op_flags & OP_PROTECT_ENABLE)) - tx_hdr.flags |= ATH9K_HTC_TX_CTSONLY; + flags |= ATH9K_HTC_TX_CTSONLY; + tx_hdr.flags = cpu_to_be32(flags); tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID; From 811ea256b30b37091b5bbf41517404cf98ab56c1 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 17 Jan 2011 15:21:40 +0530 Subject: [PATCH 08/10] ath9k_hw: do PA offset calibration only on longcal interval The power detector adc offset calibration has to be done on 4 minutes interval (longcal * pa_skip_count). But the commit "ath9k_hw: fix a noise floor calibration related race condition" makes the PA calibration executed more frequently beased on nfcal_pending value. Running PAOffset calibration lesser than longcal interval doesn't help anything and the worse part is that it causes NF load timeouts and RX deaf conditions. In a very noisy environment, where the distance b/w AP & station is ~10 meter and running a downlink udp traffic with frequent background scan causes "Timeout while waiting for nf to load: AR_PHY_AGC_CONTROL=0x40d1a" and moves the chip into deaf state. This issue was originaly reported in Android platform where the network-manager application does bgscan more frequently on AR9271 chips. (AR9285 family usb device). Cc: stable@kernel.org Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_calib.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index ea2e7d714bda..5e300bd3d264 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c @@ -679,10 +679,6 @@ static bool ar9002_hw_calibrate(struct ath_hw *ah, /* Do NF cal only at longer intervals */ if (longcal || nfcal_pending) { - /* Do periodic PAOffset Cal */ - ar9002_hw_pa_cal(ah, false); - ar9002_hw_olc_temp_compensation(ah); - /* * Get the value from the previous NF cal and update * history buffer. @@ -697,8 +693,12 @@ static bool ar9002_hw_calibrate(struct ath_hw *ah, ath9k_hw_loadnf(ah, ah->curchan); } - if (longcal) + if (longcal) { ath9k_hw_start_nfcal(ah, false); + /* Do periodic PAOffset Cal */ + ar9002_hw_pa_cal(ah, false); + ar9002_hw_olc_temp_compensation(ah); + } } return iscaldone; From 599b13adc2bf236da8f86a34b0b51168e19d3524 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Tue, 18 Jan 2011 08:06:43 -0500 Subject: [PATCH 09/10] ath5k: fix locking in tx_complete_poll_work ath5k_reset must be called with sc->lock. Since the tx queue watchdog runs in a workqueue and accesses sc, it's appropriate to just take the lock over the whole function. Signed-off-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 019a74d533a6..09ae4ef0fd51 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2294,6 +2294,8 @@ ath5k_tx_complete_poll_work(struct work_struct *work) int i; bool needreset = false; + mutex_lock(&sc->lock); + for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) { if (sc->txqs[i].setup) { txq = &sc->txqs[i]; @@ -2321,6 +2323,8 @@ ath5k_tx_complete_poll_work(struct work_struct *work) ath5k_reset(sc, NULL, true); } + mutex_unlock(&sc->lock); + ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT)); } From 38d59392b29437af3a702209b6a5196ef01f79a8 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 18 Jan 2011 07:59:13 -0800 Subject: [PATCH 10/10] iwlwifi: fix valid chain reading from EEPROM When read valid tx/rx chains from EEPROM, there is a bug to use the tx chain value for both tx and rx, the result of this cause low receive throughput on 1x2 devices becuase rx will only utilize single chain instead of two chains Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c index 97906dd442e6..14ceb4df72f6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c @@ -168,7 +168,7 @@ int iwl_eeprom_check_sku(struct iwl_priv *priv) /* not using .cfg overwrite */ radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); priv->cfg->valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg); - priv->cfg->valid_rx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg); + priv->cfg->valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg); if (!priv->cfg->valid_tx_ant || !priv->cfg->valid_rx_ant) { IWL_ERR(priv, "Invalid chain (0X%x, 0X%x)\n", priv->cfg->valid_tx_ant,