diff options
author | John W. Linville <linville@tuxdriver.com> | 2011-06-09 20:23:30 +0200 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-06-09 20:23:30 +0200 |
commit | e23535ca11525945bd7fca05ac5941efba232498 (patch) | |
tree | 43ddf01415e60988b73f832d97ca2c07a6f8053e /drivers | |
parent | netpoll: prevent netpoll setup on slave devices (diff) | |
parent | iwlegacy: fix channel switch locking (diff) | |
download | linux-e23535ca11525945bd7fca05ac5941efba232498.tar.xz linux-e23535ca11525945bd7fca05ac5941efba232498.zip |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6 into for-davem
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/iwlegacy/iwl-4965.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/iwl-core.c | 30 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/iwl-core.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/iwl-dev.h | 13 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/iwl4965-base.c | 20 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-5000.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 13 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00config.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/rtlwifi/pci.c | 30 |
11 files changed, 65 insertions, 75 deletions
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965.c b/drivers/net/wireless/iwlegacy/iwl-4965.c index f9db25bb35c3..facc94e74b07 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965.c @@ -1218,10 +1218,10 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c * receive commit_rxon request * abort any previous channel switch if still in process */ - if (priv->switch_rxon.switch_in_progress && - (priv->switch_rxon.channel != ctx->staging.channel)) { + if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status) && + (priv->switch_channel != ctx->staging.channel)) { IWL_DEBUG_11H(priv, "abort channel switch on %d\n", - le16_to_cpu(priv->switch_rxon.channel)); + le16_to_cpu(priv->switch_channel)); iwl_legacy_chswitch_done(priv, false); } @@ -1237,7 +1237,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); iwl_legacy_print_rx_config_cmd(priv, ctx); - return 0; + goto set_tx_power; } /* If we are currently associated and the new config requires @@ -1317,6 +1317,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c iwl4965_init_sensitivity(priv); +set_tx_power: /* If we issue a new RXON command which required a tune then we must * send a new TXPOWER command or we won't be able to Tx any frames */ ret = iwl_legacy_set_tx_power(priv, priv->tx_power_next, true); @@ -1403,9 +1404,6 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, return rc; } - priv->switch_rxon.channel = cmd.channel; - priv->switch_rxon.switch_in_progress = true; - return iwl_legacy_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd); } diff --git a/drivers/net/wireless/iwlegacy/iwl-core.c b/drivers/net/wireless/iwlegacy/iwl-core.c index 42df8321dae8..3be76bd5499a 100644 --- a/drivers/net/wireless/iwlegacy/iwl-core.c +++ b/drivers/net/wireless/iwlegacy/iwl-core.c @@ -859,12 +859,8 @@ void iwl_legacy_chswitch_done(struct iwl_priv *priv, bool is_success) if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - if (priv->switch_rxon.switch_in_progress) { + if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) ieee80211_chswitch_done(ctx->vif, is_success); - mutex_lock(&priv->mutex); - priv->switch_rxon.switch_in_progress = false; - mutex_unlock(&priv->mutex); - } } EXPORT_SYMBOL(iwl_legacy_chswitch_done); @@ -876,19 +872,19 @@ void iwl_legacy_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; struct iwl_legacy_rxon_cmd *rxon = (void *)&ctx->active; - if (priv->switch_rxon.switch_in_progress) { - if (!le32_to_cpu(csa->status) && - (csa->channel == priv->switch_rxon.channel)) { - rxon->channel = csa->channel; - ctx->staging.channel = csa->channel; - IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", - le16_to_cpu(csa->channel)); - iwl_legacy_chswitch_done(priv, true); - } else { - IWL_ERR(priv, "CSA notif (fail) : channel %d\n", + if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) + return; + + if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) { + rxon->channel = csa->channel; + ctx->staging.channel = csa->channel; + IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", le16_to_cpu(csa->channel)); - iwl_legacy_chswitch_done(priv, false); - } + iwl_legacy_chswitch_done(priv, true); + } else { + IWL_ERR(priv, "CSA notif (fail) : channel %d\n", + le16_to_cpu(csa->channel)); + iwl_legacy_chswitch_done(priv, false); } } EXPORT_SYMBOL(iwl_legacy_rx_csa); diff --git a/drivers/net/wireless/iwlegacy/iwl-core.h b/drivers/net/wireless/iwlegacy/iwl-core.h index bc66c604106c..c5fbda0760de 100644 --- a/drivers/net/wireless/iwlegacy/iwl-core.h +++ b/drivers/net/wireless/iwlegacy/iwl-core.h @@ -560,7 +560,7 @@ void iwl_legacy_free_geos(struct iwl_priv *priv); #define STATUS_SCAN_HW 15 #define STATUS_POWER_PMI 16 #define STATUS_FW_ERROR 17 - +#define STATUS_CHANNEL_SWITCH_PENDING 18 static inline int iwl_legacy_is_ready(struct iwl_priv *priv) { diff --git a/drivers/net/wireless/iwlegacy/iwl-dev.h b/drivers/net/wireless/iwlegacy/iwl-dev.h index be0106c6a2da..ea30122669ee 100644 --- a/drivers/net/wireless/iwlegacy/iwl-dev.h +++ b/drivers/net/wireless/iwlegacy/iwl-dev.h @@ -855,17 +855,6 @@ struct traffic_stats { }; /* - * iwl_switch_rxon: "channel switch" structure - * - * @ switch_in_progress: channel switch in progress - * @ channel: new channel - */ -struct iwl_switch_rxon { - bool switch_in_progress; - __le16 channel; -}; - -/* * schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds * to perform continuous uCode event logging operation if enabled */ @@ -1115,7 +1104,7 @@ struct iwl_priv { struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX]; - struct iwl_switch_rxon switch_rxon; + __le16 switch_channel; /* 1st responses from initialize and runtime uCode images. * _4965's initialize alive response contains some calibration data. */ diff --git a/drivers/net/wireless/iwlegacy/iwl4965-base.c b/drivers/net/wireless/iwlegacy/iwl4965-base.c index af2ae22fcfd3..7157ba529680 100644 --- a/drivers/net/wireless/iwlegacy/iwl4965-base.c +++ b/drivers/net/wireless/iwlegacy/iwl4965-base.c @@ -2861,16 +2861,13 @@ void iwl4965_mac_channel_switch(struct ieee80211_hw *hw, goto out; if (test_bit(STATUS_EXIT_PENDING, &priv->status) || - test_bit(STATUS_SCANNING, &priv->status)) + test_bit(STATUS_SCANNING, &priv->status) || + test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) goto out; if (!iwl_legacy_is_associated_ctx(ctx)) goto out; - /* channel switch in progress */ - if (priv->switch_rxon.switch_in_progress == true) - goto out; - if (priv->cfg->ops->lib->set_channel_switch) { ch = channel->hw_value; @@ -2919,15 +2916,18 @@ void iwl4965_mac_channel_switch(struct ieee80211_hw *hw, * at this point, staging_rxon has the * configuration for channel switch */ - if (priv->cfg->ops->lib->set_channel_switch(priv, - ch_switch)) - priv->switch_rxon.switch_in_progress = false; + set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); + priv->switch_channel = cpu_to_le16(ch); + if (priv->cfg->ops->lib->set_channel_switch(priv, ch_switch)) { + clear_bit(STATUS_CHANNEL_SWITCH_PENDING, + &priv->status); + priv->switch_channel = 0; + ieee80211_chswitch_done(ctx->vif, false); + } } } out: mutex_unlock(&priv->mutex); - if (!priv->switch_rxon.switch_in_progress) - ieee80211_chswitch_done(ctx->vif, false); IWL_DEBUG_MAC80211(priv, "leave\n"); } diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 5b721c56aee9..f99f9c193352 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -423,7 +423,6 @@ static struct iwl_base_params iwl5000_base_params = { }; static struct iwl_ht_params iwl5000_ht_params = { .ht_greenfield_support = true, - .use_rts_for_aggregation = true, /* use rts/cts protection */ }; #define IWL_DEVICE_5000 \ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index b12c72d63ccb..23fa93deae96 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -163,17 +163,9 @@ static void iwlagn_tx_cmd_protection(struct iwl_priv *priv, __le16 fc, __le32 *tx_flags) { if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS || - info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { + info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT || + info->flags & IEEE80211_TX_CTL_AMPDU) *tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK; - return; - } - - if (priv->cfg->ht_params && - priv->cfg->ht_params->use_rts_for_aggregation && - info->flags & IEEE80211_TX_CTL_AMPDU) { - *tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK; - return; - } } /* Calc max signal level (dBm) among 3 possible receivers */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 2532c7db3aff..09f679d6046f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -325,6 +325,14 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) return 0; } + /* + * force CTS-to-self frames protection if RTS-CTS is not preferred + * one aggregation protection method + */ + if (!(priv->cfg->ht_params && + priv->cfg->ht_params->use_rts_for_aggregation)) + ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; + if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) || !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK)) ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; @@ -362,6 +370,11 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) } memcpy(active, &ctx->staging, sizeof(*active)); + /* + * We do not commit tx power settings while channel changing, + * do it now if after settings changed. + */ + iwl_set_tx_power(priv, priv->tx_power_next, false); return 0; } diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 555180d8f4aa..b704e5b183d0 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -250,7 +250,8 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) rt2x00link_reset_tuner(rt2x00dev, false); - if (test_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags) && + if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && + test_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags) && (ieee80211_flags & IEEE80211_CONF_CHANGE_PS) && (conf->flags & IEEE80211_CONF_PS)) { beacon_diff = (long)jiffies - (long)rt2x00dev->last_beacon; diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index c018d67aab8e..939821b4af2f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -146,6 +146,9 @@ static void rt2x00lib_autowakeup(struct work_struct *work) struct rt2x00_dev *rt2x00dev = container_of(work, struct rt2x00_dev, autowakeup_work.work); + if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) + return; + if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE)) ERROR(rt2x00dev, "Device failed to wakeup.\n"); clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags); @@ -1160,6 +1163,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) * Stop all work. */ cancel_work_sync(&rt2x00dev->intf_work); + cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); if (rt2x00_is_usb(rt2x00dev)) { del_timer_sync(&rt2x00dev->txstatus_timer); cancel_work_sync(&rt2x00dev->rxdone_work); diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 89100e7c553b..9f8ccae93317 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -669,6 +669,19 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) &rx_status, (u8 *) pdesc, skb); + new_skb = dev_alloc_skb(rtlpci->rxbuffersize); + if (unlikely(!new_skb)) { + RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), + DBG_DMESG, + ("can't alloc skb for rx\n")); + goto done; + } + + pci_unmap_single(rtlpci->pdev, + *((dma_addr_t *) skb->cb), + rtlpci->rxbuffersize, + PCI_DMA_FROMDEVICE); + skb_put(skb, rtlpriv->cfg->ops->get_desc((u8 *) pdesc, false, HW_DESC_RXPKT_LEN)); @@ -685,22 +698,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) hdr = rtl_get_hdr(skb); fc = rtl_get_fc(skb); - /* try for new buffer - if allocation fails, drop - * frame and reuse old buffer - */ - new_skb = dev_alloc_skb(rtlpci->rxbuffersize); - if (unlikely(!new_skb)) { - RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), - DBG_DMESG, - ("can't alloc skb for rx\n")); - goto done; - } - pci_unmap_single(rtlpci->pdev, - *((dma_addr_t *) skb->cb), - rtlpci->rxbuffersize, - PCI_DMA_FROMDEVICE); - - if (!stats.crc || !stats.hwerror) { + if (!stats.crc && !stats.hwerror) { memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); |