Commit a0f68763 authored by John W. Linville's avatar John W. Linville

Merge branch 'master' of...

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless into for-davem
parents 3fdcbd45 7b21aea0
...@@ -2415,6 +2415,22 @@ ath5k_tx_complete_poll_work(struct work_struct *work) ...@@ -2415,6 +2415,22 @@ ath5k_tx_complete_poll_work(struct work_struct *work)
* Initialization routines * * Initialization routines *
\*************************/ \*************************/
static const struct ieee80211_iface_limit if_limits[] = {
{ .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) },
{ .max = 4, .types =
#ifdef CONFIG_MAC80211_MESH
BIT(NL80211_IFTYPE_MESH_POINT) |
#endif
BIT(NL80211_IFTYPE_AP) },
};
static const struct ieee80211_iface_combination if_comb = {
.limits = if_limits,
.n_limits = ARRAY_SIZE(if_limits),
.max_interfaces = 2048,
.num_different_channels = 1,
};
int __devinit int __devinit
ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops) ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops)
{ {
...@@ -2436,6 +2452,9 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops) ...@@ -2436,6 +2452,9 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops)
BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_MESH_POINT); BIT(NL80211_IFTYPE_MESH_POINT);
hw->wiphy->iface_combinations = &if_comb;
hw->wiphy->n_iface_combinations = 1;
/* SW support for IBSS_RSN is provided by mac80211 */ /* SW support for IBSS_RSN is provided by mac80211 */
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
......
...@@ -3809,7 +3809,7 @@ static bool is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set) ...@@ -3809,7 +3809,7 @@ static bool is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set)
return true; return true;
} }
static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
{ {
int internal_regulator = int internal_regulator =
ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR); ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR);
......
...@@ -334,4 +334,7 @@ u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz); ...@@ -334,4 +334,7 @@ u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz);
unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah, unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
struct ath9k_channel *chan); struct ath9k_channel *chan);
void ar9003_hw_internal_regulator_apply(struct ath_hw *ah);
#endif #endif
...@@ -1468,6 +1468,9 @@ static bool ath9k_hw_chip_reset(struct ath_hw *ah, ...@@ -1468,6 +1468,9 @@ static bool ath9k_hw_chip_reset(struct ath_hw *ah,
return false; return false;
ah->chip_fullsleep = false; ah->chip_fullsleep = false;
if (AR_SREV_9330(ah))
ar9003_hw_internal_regulator_apply(ah);
ath9k_hw_init_pll(ah, chan); ath9k_hw_init_pll(ah, chan);
ath9k_hw_set_rfmode(ah, chan); ath9k_hw_set_rfmode(ah, chan);
......
...@@ -239,7 +239,7 @@ static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) ...@@ -239,7 +239,7 @@ static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush)
{ {
struct ath_hw *ah = sc->sc_ah; struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
bool ret; bool ret = true;
ieee80211_stop_queues(sc->hw); ieee80211_stop_queues(sc->hw);
...@@ -250,11 +250,12 @@ static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) ...@@ -250,11 +250,12 @@ static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush)
ath9k_debug_samp_bb_mac(sc); ath9k_debug_samp_bb_mac(sc);
ath9k_hw_disable_interrupts(ah); ath9k_hw_disable_interrupts(ah);
ret = ath_drain_all_txq(sc, retry_tx);
if (!ath_stoprecv(sc)) if (!ath_stoprecv(sc))
ret = false; ret = false;
if (!ath_drain_all_txq(sc, retry_tx))
ret = false;
if (!flush) { if (!flush) {
if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
ath_rx_tasklet(sc, 1, true); ath_rx_tasklet(sc, 1, true);
......
...@@ -64,7 +64,8 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, ...@@ -64,7 +64,8 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
struct ath_txq *txq, struct ath_txq *txq,
struct ath_atx_tid *tid, struct ath_atx_tid *tid,
struct sk_buff *skb); struct sk_buff *skb,
bool dequeue);
enum { enum {
MCS_HT20, MCS_HT20,
...@@ -811,7 +812,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, ...@@ -811,7 +812,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
fi = get_frame_info(skb); fi = get_frame_info(skb);
bf = fi->bf; bf = fi->bf;
if (!fi->bf) if (!fi->bf)
bf = ath_tx_setup_buffer(sc, txq, tid, skb); bf = ath_tx_setup_buffer(sc, txq, tid, skb, true);
if (!bf) if (!bf)
continue; continue;
...@@ -1726,7 +1727,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, ...@@ -1726,7 +1727,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
return; return;
} }
bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb); bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false);
if (!bf) if (!bf)
return; return;
...@@ -1753,7 +1754,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, ...@@ -1753,7 +1754,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
bf = fi->bf; bf = fi->bf;
if (!bf) if (!bf)
bf = ath_tx_setup_buffer(sc, txq, tid, skb); bf = ath_tx_setup_buffer(sc, txq, tid, skb, false);
if (!bf) if (!bf)
return; return;
...@@ -1814,7 +1815,8 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate) ...@@ -1814,7 +1815,8 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
struct ath_txq *txq, struct ath_txq *txq,
struct ath_atx_tid *tid, struct ath_atx_tid *tid,
struct sk_buff *skb) struct sk_buff *skb,
bool dequeue)
{ {
struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_frame_info *fi = get_frame_info(skb); struct ath_frame_info *fi = get_frame_info(skb);
...@@ -1863,6 +1865,8 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, ...@@ -1863,6 +1865,8 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
return bf; return bf;
error: error:
if (dequeue)
__skb_unlink(skb, &tid->buf_q);
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return NULL; return NULL;
} }
...@@ -1893,7 +1897,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb, ...@@ -1893,7 +1897,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb,
*/ */
ath_tx_send_ampdu(sc, tid, skb, txctl); ath_tx_send_ampdu(sc, tid, skb, txctl);
} else { } else {
bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb); bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false);
if (!bf) if (!bf)
return; return;
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/vmalloc.h>
#include <net/cfg80211.h> #include <net/cfg80211.h>
#include <defs.h> #include <defs.h>
...@@ -1239,7 +1240,7 @@ static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo) ...@@ -1239,7 +1240,7 @@ static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo)
return -EINVAL; return -EINVAL;
} }
devinfo->image = kmalloc(fw->size, GFP_ATOMIC); /* plus nvram */ devinfo->image = vmalloc(fw->size); /* plus nvram */
if (!devinfo->image) if (!devinfo->image)
return -ENOMEM; return -ENOMEM;
...@@ -1603,7 +1604,7 @@ static struct usb_driver brcmf_usbdrvr = { ...@@ -1603,7 +1604,7 @@ static struct usb_driver brcmf_usbdrvr = {
void brcmf_usb_exit(void) void brcmf_usb_exit(void)
{ {
usb_deregister(&brcmf_usbdrvr); usb_deregister(&brcmf_usbdrvr);
kfree(g_image.data); vfree(g_image.data);
g_image.data = NULL; g_image.data = NULL;
g_image.len = 0; g_image.len = 0;
} }
......
...@@ -137,11 +137,3 @@ config IWLWIFI_EXPERIMENTAL_MFP ...@@ -137,11 +137,3 @@ config IWLWIFI_EXPERIMENTAL_MFP
even if the microcode doesn't advertise it. even if the microcode doesn't advertise it.
Say Y only if you want to experiment with MFP. Say Y only if you want to experiment with MFP.
config IWLWIFI_UCODE16
bool "support uCode 16.0"
depends on IWLWIFI
help
This option enables support for uCode version 16.0.
Say Y if you want to use 16.0 microcode.
...@@ -18,7 +18,6 @@ iwlwifi-objs += iwl-notif-wait.o ...@@ -18,7 +18,6 @@ iwlwifi-objs += iwl-notif-wait.o
iwlwifi-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o iwlwifi-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o
iwlwifi-$(CONFIG_IWLWIFI_UCODE16) += iwl-phy-db.o
iwlwifi-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o iwlwifi-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-testmode.o iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-testmode.o
......
...@@ -79,7 +79,7 @@ static const struct iwl_base_params iwl2000_base_params = { ...@@ -79,7 +79,7 @@ static const struct iwl_base_params iwl2000_base_params = {
.chain_noise_scale = 1000, .chain_noise_scale = 1000,
.wd_timeout = IWL_DEF_WD_TIMEOUT, .wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 512, .max_event_log_size = 512,
.shadow_reg_enable = true, .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
.hd_v2 = true, .hd_v2 = true,
}; };
...@@ -97,7 +97,7 @@ static const struct iwl_base_params iwl2030_base_params = { ...@@ -97,7 +97,7 @@ static const struct iwl_base_params iwl2030_base_params = {
.chain_noise_scale = 1000, .chain_noise_scale = 1000,
.wd_timeout = IWL_LONG_WD_TIMEOUT, .wd_timeout = IWL_LONG_WD_TIMEOUT,
.max_event_log_size = 512, .max_event_log_size = 512,
.shadow_reg_enable = true, .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
.hd_v2 = true, .hd_v2 = true,
}; };
......
...@@ -86,7 +86,7 @@ static const struct iwl_base_params iwl6000_base_params = { ...@@ -86,7 +86,7 @@ static const struct iwl_base_params iwl6000_base_params = {
.chain_noise_scale = 1000, .chain_noise_scale = 1000,
.wd_timeout = IWL_DEF_WD_TIMEOUT, .wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 512, .max_event_log_size = 512,
.shadow_reg_enable = true, .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
}; };
static const struct iwl_base_params iwl6050_base_params = { static const struct iwl_base_params iwl6050_base_params = {
...@@ -102,7 +102,7 @@ static const struct iwl_base_params iwl6050_base_params = { ...@@ -102,7 +102,7 @@ static const struct iwl_base_params iwl6050_base_params = {
.chain_noise_scale = 1500, .chain_noise_scale = 1500,
.wd_timeout = IWL_DEF_WD_TIMEOUT, .wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 1024, .max_event_log_size = 1024,
.shadow_reg_enable = true, .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
}; };
static const struct iwl_base_params iwl6000_g2_base_params = { static const struct iwl_base_params iwl6000_g2_base_params = {
...@@ -118,7 +118,7 @@ static const struct iwl_base_params iwl6000_g2_base_params = { ...@@ -118,7 +118,7 @@ static const struct iwl_base_params iwl6000_g2_base_params = {
.chain_noise_scale = 1000, .chain_noise_scale = 1000,
.wd_timeout = IWL_LONG_WD_TIMEOUT, .wd_timeout = IWL_LONG_WD_TIMEOUT,
.max_event_log_size = 512, .max_event_log_size = 512,
.shadow_reg_enable = true, .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
}; };
static const struct iwl_ht_params iwl6000_ht_params = { static const struct iwl_ht_params iwl6000_ht_params = {
......
...@@ -884,6 +884,7 @@ static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, ...@@ -884,6 +884,7 @@ static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
if ((priv->bt_traffic_load != priv->last_bt_traffic_load) || if ((priv->bt_traffic_load != priv->last_bt_traffic_load) ||
(priv->bt_full_concurrent != full_concurrent)) { (priv->bt_full_concurrent != full_concurrent)) {
priv->bt_full_concurrent = full_concurrent; priv->bt_full_concurrent = full_concurrent;
priv->last_bt_traffic_load = priv->bt_traffic_load;
/* Update uCode's rate table. */ /* Update uCode's rate table. */
tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
......
...@@ -772,7 +772,7 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) ...@@ -772,7 +772,7 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
~IWL_STA_DRIVER_ACTIVE; ~IWL_STA_DRIVER_ACTIVE;
priv->stations[i].used &= priv->stations[i].used &=
~IWL_STA_UCODE_INPROGRESS; ~IWL_STA_UCODE_INPROGRESS;
spin_unlock_bh(&priv->sta_lock); continue;
} }
/* /*
* Rate scaling has already been initialized, send * Rate scaling has already been initialized, send
......
...@@ -657,17 +657,17 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, ...@@ -657,17 +657,17 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
return -EINVAL; return -EINVAL;
} }
static int alloc_pci_desc(struct iwl_drv *drv, static int iwl_alloc_ucode(struct iwl_drv *drv,
struct iwl_firmware_pieces *pieces, struct iwl_firmware_pieces *pieces,
enum iwl_ucode_type type) enum iwl_ucode_type type)
{ {
int i; int i;
for (i = 0; for (i = 0;
i < IWL_UCODE_SECTION_MAX && get_sec_size(pieces, type, i); i < IWL_UCODE_SECTION_MAX && get_sec_size(pieces, type, i);
i++) i++)
if (iwl_alloc_fw_desc(drv, &(drv->fw.img[type].sec[i]), if (iwl_alloc_fw_desc(drv, &(drv->fw.img[type].sec[i]),
get_sec(pieces, type, i))) get_sec(pieces, type, i)))
return -1; return -ENOMEM;
return 0; return 0;
} }
...@@ -825,8 +825,8 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) ...@@ -825,8 +825,8 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
* 1) unmodified from disk * 1) unmodified from disk
* 2) backup cache for save/restore during power-downs */ * 2) backup cache for save/restore during power-downs */
for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
if (alloc_pci_desc(drv, &pieces, i)) if (iwl_alloc_ucode(drv, &pieces, i))
goto err_pci_alloc; goto out_free_fw;
/* Now that we can no longer fail, copy information */ /* Now that we can no longer fail, copy information */
...@@ -866,7 +866,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) ...@@ -866,7 +866,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
drv->op_mode = iwl_dvm_ops.start(drv->trans, drv->cfg, &drv->fw); drv->op_mode = iwl_dvm_ops.start(drv->trans, drv->cfg, &drv->fw);
if (!drv->op_mode) if (!drv->op_mode)
goto out_unbind; goto out_free_fw;
return; return;
...@@ -877,7 +877,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) ...@@ -877,7 +877,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
goto out_unbind; goto out_unbind;
return; return;
err_pci_alloc: out_free_fw:
IWL_ERR(drv, "failed to allocate pci memory\n"); IWL_ERR(drv, "failed to allocate pci memory\n");
iwl_dealloc_ucode(drv); iwl_dealloc_ucode(drv);
release_firmware(ucode_raw); release_firmware(ucode_raw);
......
/******************************************************************************
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* GPL LICENSE SUMMARY
*
* Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
* USA
*
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.GPL.
*
* Contact Information:
* Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
*
* Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#include <linux/slab.h>
#include <linux/string.h>
#include "iwl-debug.h"
#include "iwl-dev.h"
#include "iwl-phy-db.h"
#define CHANNEL_NUM_SIZE 4 /* num of channels in calib_ch size */
struct iwl_phy_db *iwl_phy_db_init(struct device *dev)
{
struct iwl_phy_db *phy_db = kzalloc(sizeof(struct iwl_phy_db),
GFP_KERNEL);
if (!phy_db)
return phy_db;
phy_db->dev = dev;
/* TODO: add default values of the phy db. */
return phy_db;
}
/*
* get phy db section: returns a pointer to a phy db section specified by
* type and channel group id.
*/
static struct iwl_phy_db_entry *
iwl_phy_db_get_section(struct iwl_phy_db *phy_db,
enum iwl_phy_db_section_type type,
u16 chg_id)
{
if (!phy_db || type < 0 || type >= IWL_PHY_DB_MAX)
return NULL;
switch (type) {
case IWL_PHY_DB_CFG:
return &phy_db->cfg;
case IWL_PHY_DB_CALIB_NCH:
return &phy_db->calib_nch;
case IWL_PHY_DB_CALIB_CH:
return &phy_db->calib_ch;
case IWL_PHY_DB_CALIB_CHG_PAPD:
if (chg_id < 0 || chg_id >= IWL_NUM_PAPD_CH_GROUPS)
return NULL;
return &phy_db->calib_ch_group_papd[chg_id];
case IWL_PHY_DB_CALIB_CHG_TXP:
if (chg_id < 0 || chg_id >= IWL_NUM_TXP_CH_GROUPS)
return NULL;
return &phy_db->calib_ch_group_txp[chg_id];
default:
return NULL;
}
return NULL;
}
static void iwl_phy_db_free_section(struct iwl_phy_db *phy_db,
enum iwl_phy_db_section_type type,
u16 chg_id)
{
struct iwl_phy_db_entry *entry =
iwl_phy_db_get_section(phy_db, type, chg_id);
if (!entry)
return;
kfree(entry->data);
entry->data = NULL;
entry->size = 0;
}
void iwl_phy_db_free(struct iwl_phy_db *phy_db)
{
int i;
if (!phy_db)
return;
iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CFG, 0);
iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_NCH, 0);
iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_CH, 0);
for (i = 0; i < IWL_NUM_PAPD_CH_GROUPS; i++)
iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_CHG_PAPD, i);
for (i = 0; i < IWL_NUM_TXP_CH_GROUPS; i++)
iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_CHG_TXP, i);
kfree(phy_db);
}
int iwl_phy_db_set_section(struct iwl_phy_db *phy_db,
enum iwl_phy_db_section_type type, u8 *data,
u16 size, gfp_t alloc_ctx)
{
struct iwl_phy_db_entry *entry;
u16 chg_id = 0;
if (!phy_db)
return -EINVAL;
if (type == IWL_PHY_DB_CALIB_CHG_PAPD ||
type == IWL_PHY_DB_CALIB_CHG_TXP)
chg_id = le16_to_cpup((__le16 *)data);
entry = iwl_phy_db_get_section(phy_db, type, chg_id);
if (!entry)
return -EINVAL;
kfree(entry->data);
entry->data = kmemdup(data, size, alloc_ctx);
if (!entry->data) {
entry->size = 0;
return -ENOMEM;
}
entry->size = size;
if (type == IWL_PHY_DB_CALIB_CH) {
phy_db->channel_num = le32_to_cpup((__le32 *)data);
phy_db->channel_size =
(size - CHANNEL_NUM_SIZE) / phy_db->channel_num;
}
return 0;
}
static int is_valid_channel(u16 ch_id)
{
if (ch_id <= 14 ||
(36 <= ch_id && ch_id <= 64 && ch_id % 4 == 0) ||
(100 <= ch_id && ch_id <= 140 && ch_id % 4 == 0) ||
(145 <= ch_id && ch_id <= 165 && ch_id % 4 == 1))
return 1;
return 0;
}
static u8 ch_id_to_ch_index(u16 ch_id)
{
if (WARN_ON(!is_valid_channel(ch_id)))
return 0xff;
if (ch_id <= 14)
return ch_id - 1;
if (ch_id <= 64)
return (ch_id + 20) / 4;
if (ch_id <= 140)
return (ch_id - 12) / 4;
return (ch_id - 13) / 4;
}
static u16 channel_id_to_papd(u16 ch_id)
{
if (WARN_ON(!is_valid_channel(ch_id)))
return 0xff;
if (1 <= ch_id && ch_id <= 14)
return 0;
if (36 <= ch_id && ch_id <= 64)
return 1;
if (100 <= ch_id && ch_id <= 140)
return 2;
return 3;
}
static u16 channel_id_to_txp(struct iwl_phy_db *phy_db, u16 ch_id)
{
struct iwl_phy_db_chg_txp *txp_chg;
int i;
u8 ch_index = ch_id_to_ch_index(ch_id);
if (ch_index == 0xff)
return 0xff;
for (i = 0; i < IWL_NUM_TXP_CH_GROUPS; i++) {
txp_chg = (void *)phy_db->calib_ch_group_txp[i].data;
if (!txp_chg)
return 0xff;
/*
* Looking for the first channel group that its max channel is
* higher then wanted channel.
*/
if (le16_to_cpu(txp_chg->max_channel_idx) >= ch_index)
return i;
}
return 0xff;
}
int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db,
enum iwl_phy_db_section_type type, u8 **data,
u16 *size, u16 ch_id)
{
struct iwl_phy_db_entry *entry;
u32 channel_num;
u32 channel_size;
u16 ch_group_id = 0;
u16 index;
if (!phy_db)
return -EINVAL;
/* find wanted channel group */
if (type == IWL_PHY_DB_CALIB_CHG_PAPD)
ch_group_id = channel_id_to_papd(ch_id);
else if (type == IWL_PHY_DB_CALIB_CHG_TXP)
ch_group_id = channel_id_to_txp(phy_db, ch_id);
entry = iwl_phy_db_get_section(phy_db, type, ch_group_id);
if (!entry)
return -EINVAL;
if (type == IWL_PHY_DB_CALIB_CH) {
index = ch_id_to_ch_index(ch_id);
channel_num = phy_db->channel_num;
channel_size = phy_db->channel_size;
if (index >= channel_num) {
IWL_ERR(phy_db, "Wrong channel number %d", ch_id);
return -EINVAL;
}
*data = entry->data + CHANNEL_NUM_SIZE + index * channel_size;
*size = channel_size;
} else {
*data = entry->data;
*size = entry->size;
}
return 0;
}
/******************************************************************************
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* GPL LICENSE SUMMARY
*
* Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
* USA
*
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.GPL.
*
* Contact Information:
* Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
*
* Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#ifndef __IWL_PHYDB_H__
#define __IWL_PHYDB_H__
#include <linux/types.h>
#define IWL_NUM_PAPD_CH_GROUPS 4
#define IWL_NUM_TXP_CH_GROUPS 8
struct iwl_phy_db_entry {
u16 size;
u8 *data;
};
struct iwl_shared;
/**
* struct iwl_phy_db - stores phy configuration and calibration data.
*
* @cfg: phy configuration.
* @calib_nch: non channel specific calibration data.
* @calib_ch: channel specific calibration data.
* @calib_ch_group_papd: calibration data related to papd channel group.
* @calib_ch_group_txp: calibration data related to tx power chanel group.
*/
struct iwl_phy_db {
struct iwl_phy_db_entry cfg;
struct iwl_phy_db_entry calib_nch;
struct iwl_phy_db_entry calib_ch;
struct iwl_phy_db_entry calib_ch_group_papd[IWL_NUM_PAPD_CH_GROUPS];
struct iwl_phy_db_entry calib_ch_group_txp[IWL_NUM_TXP_CH_GROUPS];
u32 channel_num;
u32 channel_size;
/* for an access to the logger */
struct device *dev;
};
enum iwl_phy_db_section_type {
IWL_PHY_DB_CFG = 1,
IWL_PHY_DB_CALIB_NCH,
IWL_PHY_DB_CALIB_CH,
IWL_PHY_DB_CALIB_CHG_PAPD,
IWL_PHY_DB_CALIB_CHG_TXP,
IWL_PHY_DB_MAX
};
/* for parsing of tx power channel group data that comes from the firmware*/
struct iwl_phy_db_chg_txp {
__le32 space;
__le16 max_channel_idx;
} __packed;
struct iwl_phy_db *iwl_phy_db_init(struct device *dev);
void iwl_phy_db_free(struct iwl_phy_db *phy_db);
int iwl_phy_db_set_section(struct iwl_phy_db *phy_db,
enum iwl_phy_db_section_type type, u8 *data,
u16 size, gfp_t alloc_ctx);
int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db,
enum iwl_phy_db_section_type type, u8 **data,
u16 *size, u16 ch_id);
#endif /* __IWL_PHYDB_H__ */
...@@ -347,7 +347,7 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, ...@@ -347,7 +347,7 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans,
void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, int queue, int fifo, void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, int queue, int fifo,
int sta_id, int tid, int frame_limit, u16 ssn); int sta_id, int tid, int frame_limit, u16 ssn);
void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq,
int index, enum dma_data_direction dma_dir); enum dma_data_direction dma_dir);
int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index,
struct sk_buff_head *skbs); struct sk_buff_head *skbs);
int iwl_queue_space(const struct iwl_queue *q); int iwl_queue_space(const struct iwl_queue *q);
......
...@@ -204,33 +204,39 @@ static void iwlagn_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta, ...@@ -204,33 +204,39 @@ static void iwlagn_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta,
for (i = 1; i < num_tbs; i++) for (i = 1; i < num_tbs; i++)
dma_unmap_single(trans->dev, iwl_tfd_tb_get_addr(tfd, i), dma_unmap_single(trans->dev, iwl_tfd_tb_get_addr(tfd, i),
iwl_tfd_tb_get_len(tfd, i), dma_dir); iwl_tfd_tb_get_len(tfd, i), dma_dir);
tfd->num_tbs = 0;
} }
/** /**
* iwlagn_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] * iwlagn_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
* @trans - transport private data * @trans - transport private data
* @txq - tx queue * @txq - tx queue
* @index - the index of the TFD to be freed * @dma_dir - the direction of the DMA mapping
*@dma_dir - the direction of the DMA mapping
* *
* Does NOT advance any TFD circular buffer read/write indexes * Does NOT advance any TFD circular buffer read/write indexes
* Does NOT free the TFD itself (which is within circular buffer) * Does NOT free the TFD itself (which is within circular buffer)
*/ */
void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq,
int index, enum dma_data_direction dma_dir) enum dma_data_direction dma_dir)
{ {
struct iwl_tfd *tfd_tmp = txq->tfds; struct iwl_tfd *tfd_tmp = txq->tfds;
/* rd_ptr is bounded by n_bd and idx is bounded by n_window */
int rd_ptr = txq->q.read_ptr;
int idx = get_cmd_index(&txq->q, rd_ptr);
lockdep_assert_held(&txq->lock); lockdep_assert_held(&txq->lock);
iwlagn_unmap_tfd(trans, &txq->entries[index].meta, /* We have only q->n_window txq->entries, but we use q->n_bd tfds */
&tfd_tmp[index], dma_dir); iwlagn_unmap_tfd(trans, &txq->entries[idx].meta,
&tfd_tmp[rd_ptr], dma_dir);
/* free SKB */ /* free SKB */
if (txq->entries) { if (txq->entries) {
struct sk_buff *skb; struct sk_buff *skb;
skb = txq->entries[index].skb; skb = txq->entries[idx].skb;
/* Can be called from irqs-disabled context /* Can be called from irqs-disabled context
* If skb is not NULL, it means that the whole queue is being * If skb is not NULL, it means that the whole queue is being
...@@ -238,7 +244,7 @@ void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, ...@@ -238,7 +244,7 @@ void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq,
*/ */
if (skb) { if (skb) {
iwl_op_mode_free_skb(trans->op_mode, skb); iwl_op_mode_free_skb(trans->op_mode, skb);
txq->entries[index].skb = NULL; txq->entries[idx].skb = NULL;
} }
} }
} }
...@@ -973,7 +979,7 @@ int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, ...@@ -973,7 +979,7 @@ int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index,
iwlagn_txq_inval_byte_cnt_tbl(trans, txq); iwlagn_txq_inval_byte_cnt_tbl(trans, txq);
iwlagn_txq_free_tfd(trans, txq, txq->q.read_ptr, DMA_TO_DEVICE); iwlagn_txq_free_tfd(trans, txq, DMA_TO_DEVICE);
freed++; freed++;
} }
......
...@@ -435,9 +435,7 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id) ...@@ -435,9 +435,7 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id)
spin_lock_bh(&txq->lock); spin_lock_bh(&txq->lock);
while (q->write_ptr != q->read_ptr) { while (q->write_ptr != q->read_ptr) {
/* The read_ptr needs to bound by q->n_window */ iwlagn_txq_free_tfd(trans, txq, dma_dir);
iwlagn_txq_free_tfd(trans, txq, get_cmd_index(q, q->read_ptr),
dma_dir);
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
} }
spin_unlock_bh(&txq->lock); spin_unlock_bh(&txq->lock);
......
...@@ -260,6 +260,7 @@ static int wl1251_sdio_probe(struct sdio_func *func, ...@@ -260,6 +260,7 @@ static int wl1251_sdio_probe(struct sdio_func *func,
} }
if (wl->irq) { if (wl->irq) {
irq_set_status_flags(wl->irq, IRQ_NOAUTOEN);
ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl); ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl);
if (ret < 0) { if (ret < 0) {
wl1251_error("request_irq() failed: %d", ret); wl1251_error("request_irq() failed: %d", ret);
...@@ -267,7 +268,6 @@ static int wl1251_sdio_probe(struct sdio_func *func, ...@@ -267,7 +268,6 @@ static int wl1251_sdio_probe(struct sdio_func *func,
} }
irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
disable_irq(wl->irq);
wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq; wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq;
wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq; wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq;
......
...@@ -281,6 +281,7 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi) ...@@ -281,6 +281,7 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi)
wl->use_eeprom = pdata->use_eeprom; wl->use_eeprom = pdata->use_eeprom;
irq_set_status_flags(wl->irq, IRQ_NOAUTOEN);
ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl); ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl);
if (ret < 0) { if (ret < 0) {
wl1251_error("request_irq() failed: %d", ret); wl1251_error("request_irq() failed: %d", ret);
...@@ -289,8 +290,6 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi) ...@@ -289,8 +290,6 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi)
irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
disable_irq(wl->irq);
ret = wl1251_init_ieee80211(wl); ret = wl1251_init_ieee80211(wl);
if (ret) if (ret)
goto out_irq; goto out_irq;
......
...@@ -1715,6 +1715,7 @@ int wl12xx_acx_config_hangover(struct wl1271 *wl) ...@@ -1715,6 +1715,7 @@ int wl12xx_acx_config_hangover(struct wl1271 *wl)
} }
#ifdef CONFIG_PM
/* Set the global behaviour of RX filters - On/Off + default action */ /* Set the global behaviour of RX filters - On/Off + default action */
int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable, int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable,
enum rx_filter_action action) enum rx_filter_action action)
...@@ -1794,3 +1795,4 @@ int wl1271_acx_set_rx_filter(struct wl1271 *wl, u8 index, bool enable, ...@@ -1794,3 +1795,4 @@ int wl1271_acx_set_rx_filter(struct wl1271 *wl, u8 index, bool enable,
kfree(acx); kfree(acx);
return ret; return ret;
} }
#endif /* CONFIG_PM */
...@@ -1330,9 +1330,11 @@ int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr); ...@@ -1330,9 +1330,11 @@ int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr);
int wl1271_acx_fm_coex(struct wl1271 *wl); int wl1271_acx_fm_coex(struct wl1271 *wl);
int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl); int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl);
int wl12xx_acx_config_hangover(struct wl1271 *wl); int wl12xx_acx_config_hangover(struct wl1271 *wl);
#ifdef CONFIG_PM
int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable, int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable,
enum rx_filter_action action); enum rx_filter_action action);
int wl1271_acx_set_rx_filter(struct wl1271 *wl, u8 index, bool enable, int wl1271_acx_set_rx_filter(struct wl1271 *wl, u8 index, bool enable,
struct wl12xx_rx_filter *filter); struct wl12xx_rx_filter *filter);
#endif /* CONFIG_PM */
#endif /* __WL1271_ACX_H__ */ #endif /* __WL1271_ACX_H__ */
...@@ -279,6 +279,7 @@ void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status *status) ...@@ -279,6 +279,7 @@ void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status *status)
wl12xx_rearm_rx_streaming(wl, active_hlids); wl12xx_rearm_rx_streaming(wl, active_hlids);
} }
#ifdef CONFIG_PM
int wl1271_rx_filter_enable(struct wl1271 *wl, int wl1271_rx_filter_enable(struct wl1271 *wl,
int index, bool enable, int index, bool enable,
struct wl12xx_rx_filter *filter) struct wl12xx_rx_filter *filter)
...@@ -314,3 +315,4 @@ void wl1271_rx_filter_clear_all(struct wl1271 *wl) ...@@ -314,3 +315,4 @@ void wl1271_rx_filter_clear_all(struct wl1271 *wl)
wl1271_rx_filter_enable(wl, i, 0, NULL); wl1271_rx_filter_enable(wl, i, 0, NULL);
} }
} }
#endif /* CONFIG_PM */
...@@ -232,7 +232,7 @@ static int pn544_hci_i2c_write(struct i2c_client *client, u8 *buf, int len) ...@@ -232,7 +232,7 @@ static int pn544_hci_i2c_write(struct i2c_client *client, u8 *buf, int len)
static int check_crc(u8 *buf, int buflen) static int check_crc(u8 *buf, int buflen)
{ {
u8 len; int len;
u16 crc; u16 crc;
len = buf[0] + 1; len = buf[0] + 1;
......
...@@ -1522,6 +1522,8 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) ...@@ -1522,6 +1522,8 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
* anymore. The timeout will be reset if the frame is ACKed by * anymore. The timeout will be reset if the frame is ACKed by
* the AP. * the AP.
*/ */
ifmgd->probe_send_count++;
if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) {
ifmgd->nullfunc_failed = false; ifmgd->nullfunc_failed = false;
ieee80211_send_nullfunc(sdata->local, sdata, 0); ieee80211_send_nullfunc(sdata->local, sdata, 0);
...@@ -1538,7 +1540,6 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) ...@@ -1538,7 +1540,6 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
0, (u32) -1, true, false); 0, (u32) -1, true, false);
} }
ifmgd->probe_send_count++;
ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms); ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms);
run_again(ifmgd, ifmgd->probe_timeout); run_again(ifmgd, ifmgd->probe_timeout);
if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
......
...@@ -153,7 +153,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, ...@@ -153,7 +153,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
/* Don't calculate ACKs for QoS Frames with NoAck Policy set */ /* Don't calculate ACKs for QoS Frames with NoAck Policy set */
if (ieee80211_is_data_qos(hdr->frame_control) && if (ieee80211_is_data_qos(hdr->frame_control) &&
*(ieee80211_get_qos_ctl(hdr)) | IEEE80211_QOS_CTL_ACK_POLICY_NOACK) *(ieee80211_get_qos_ctl(hdr)) & IEEE80211_QOS_CTL_ACK_POLICY_NOACK)
dur = 0; dur = 0;
else else
/* Time needed to transmit ACK /* Time needed to transmit ACK
......
...@@ -1371,6 +1371,12 @@ int ieee80211_reconfig(struct ieee80211_local *local) ...@@ -1371,6 +1371,12 @@ int ieee80211_reconfig(struct ieee80211_local *local)
} }
} }
/* add back keys */
list_for_each_entry(sdata, &local->interfaces, list)
if (ieee80211_sdata_running(sdata))
ieee80211_enable_keys(sdata);
wake_up:
/* /*
* Clear the WLAN_STA_BLOCK_BA flag so new aggregation * Clear the WLAN_STA_BLOCK_BA flag so new aggregation
* sessions can be established after a resume. * sessions can be established after a resume.
...@@ -1392,12 +1398,6 @@ int ieee80211_reconfig(struct ieee80211_local *local) ...@@ -1392,12 +1398,6 @@ int ieee80211_reconfig(struct ieee80211_local *local)
mutex_unlock(&local->sta_mtx); mutex_unlock(&local->sta_mtx);
} }
/* add back keys */
list_for_each_entry(sdata, &local->interfaces, list)
if (ieee80211_sdata_running(sdata))
ieee80211_enable_keys(sdata);
wake_up:
ieee80211_wake_queues_by_reason(hw, ieee80211_wake_queues_by_reason(hw,
IEEE80211_QUEUE_STOP_REASON_SUSPEND); IEEE80211_QUEUE_STOP_REASON_SUSPEND);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment