Commit 34259977 authored by David S. Miller's avatar David S. Miller

Merge tag 'wireless-drivers-for-davem-2019-04-30' of...

Merge tag 'wireless-drivers-for-davem-2019-04-30' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers

Kalle Valo says:

====================
wireless-drivers fixes for 5.1

Third set of fixes for 5.1.

iwlwifi

* fix an oops when creating debugfs entries

* fix bug when trying to capture debugging info while in rfkill

* prevent potential uninitialized memory dumps into debugging logs

* fix some initialization parameters for AX210 devices

* fix an oops with non-MSIX devices

* fix an oops when we receive a packet with bogus lengths

* fix a bug that prevented 5350 devices from working

* fix a small merge damage from the previous series

mwifiex

* fig regression with resume on SDIO

ath10k

* fix locking problem with crashdump

* fix warnings during suspend and resume

Also note that this pull conflicts with net-next. And I want to emphasie
that it's really net-next, so when you pull this to net tree it should
go without conflicts. Stephen reported the conflict here:

https://lkml.kernel.org/r/20190429115338.5decb50b@canb.auug.org.au

In iwlwifi oddly commit 154d4899 adds the IS_ERR_OR_NULL() in
wireless-drivers but commit c9af7528 removes the whole check in
wireless-drivers-next. The fix is easy, just drop the whole check for
mvmvif->dbgfs_dir in iwlwifi/mvm/debugfs-vif.c, it's unneeded anyway.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a622b400 7a0f8ad5
...@@ -1855,7 +1855,7 @@ void ath10k_ce_dump_registers(struct ath10k *ar, ...@@ -1855,7 +1855,7 @@ void ath10k_ce_dump_registers(struct ath10k *ar,
struct ath10k_ce_crash_data ce_data; struct ath10k_ce_crash_data ce_data;
u32 addr, id; u32 addr, id;
lockdep_assert_held(&ar->data_lock); lockdep_assert_held(&ar->dump_mutex);
ath10k_err(ar, "Copy Engine register dump:\n"); ath10k_err(ar, "Copy Engine register dump:\n");
......
...@@ -3119,6 +3119,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, ...@@ -3119,6 +3119,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
goto err_free_wq; goto err_free_wq;
mutex_init(&ar->conf_mutex); mutex_init(&ar->conf_mutex);
mutex_init(&ar->dump_mutex);
spin_lock_init(&ar->data_lock); spin_lock_init(&ar->data_lock);
INIT_LIST_HEAD(&ar->peers); INIT_LIST_HEAD(&ar->peers);
......
...@@ -1063,6 +1063,9 @@ struct ath10k { ...@@ -1063,6 +1063,9 @@ struct ath10k {
/* prevents concurrent FW reconfiguration */ /* prevents concurrent FW reconfiguration */
struct mutex conf_mutex; struct mutex conf_mutex;
/* protects coredump data */
struct mutex dump_mutex;
/* protects shared structure data */ /* protects shared structure data */
spinlock_t data_lock; spinlock_t data_lock;
......
...@@ -1102,7 +1102,7 @@ struct ath10k_fw_crash_data *ath10k_coredump_new(struct ath10k *ar) ...@@ -1102,7 +1102,7 @@ struct ath10k_fw_crash_data *ath10k_coredump_new(struct ath10k *ar)
{ {
struct ath10k_fw_crash_data *crash_data = ar->coredump.fw_crash_data; struct ath10k_fw_crash_data *crash_data = ar->coredump.fw_crash_data;
lockdep_assert_held(&ar->data_lock); lockdep_assert_held(&ar->dump_mutex);
if (ath10k_coredump_mask == 0) if (ath10k_coredump_mask == 0)
/* coredump disabled */ /* coredump disabled */
...@@ -1146,7 +1146,7 @@ static struct ath10k_dump_file_data *ath10k_coredump_build(struct ath10k *ar) ...@@ -1146,7 +1146,7 @@ static struct ath10k_dump_file_data *ath10k_coredump_build(struct ath10k *ar)
if (!buf) if (!buf)
return NULL; return NULL;
spin_lock_bh(&ar->data_lock); mutex_lock(&ar->dump_mutex);
dump_data = (struct ath10k_dump_file_data *)(buf); dump_data = (struct ath10k_dump_file_data *)(buf);
strlcpy(dump_data->df_magic, "ATH10K-FW-DUMP", strlcpy(dump_data->df_magic, "ATH10K-FW-DUMP",
...@@ -1213,7 +1213,7 @@ static struct ath10k_dump_file_data *ath10k_coredump_build(struct ath10k *ar) ...@@ -1213,7 +1213,7 @@ static struct ath10k_dump_file_data *ath10k_coredump_build(struct ath10k *ar)
sofar += sizeof(*dump_tlv) + crash_data->ramdump_buf_len; sofar += sizeof(*dump_tlv) + crash_data->ramdump_buf_len;
} }
spin_unlock_bh(&ar->data_lock); mutex_unlock(&ar->dump_mutex);
return dump_data; return dump_data;
} }
......
...@@ -5774,7 +5774,7 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, ...@@ -5774,7 +5774,7 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
} }
if (changed & BSS_CHANGED_MCAST_RATE && if (changed & BSS_CHANGED_MCAST_RATE &&
!WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def))) { !ath10k_mac_vif_chan(arvif->vif, &def)) {
band = def.chan->band; band = def.chan->band;
rateidx = vif->bss_conf.mcast_rate[band] - 1; rateidx = vif->bss_conf.mcast_rate[band] - 1;
...@@ -5812,7 +5812,7 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, ...@@ -5812,7 +5812,7 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
} }
if (changed & BSS_CHANGED_BASIC_RATES) { if (changed & BSS_CHANGED_BASIC_RATES) {
if (WARN_ON(ath10k_mac_vif_chan(vif, &def))) { if (ath10k_mac_vif_chan(vif, &def)) {
mutex_unlock(&ar->conf_mutex); mutex_unlock(&ar->conf_mutex);
return; return;
} }
......
...@@ -1441,7 +1441,7 @@ static void ath10k_pci_dump_registers(struct ath10k *ar, ...@@ -1441,7 +1441,7 @@ static void ath10k_pci_dump_registers(struct ath10k *ar,
__le32 reg_dump_values[REG_DUMP_COUNT_QCA988X] = {}; __le32 reg_dump_values[REG_DUMP_COUNT_QCA988X] = {};
int i, ret; int i, ret;
lockdep_assert_held(&ar->data_lock); lockdep_assert_held(&ar->dump_mutex);
ret = ath10k_pci_diag_read_hi(ar, &reg_dump_values[0], ret = ath10k_pci_diag_read_hi(ar, &reg_dump_values[0],
hi_failure_state, hi_failure_state,
...@@ -1656,7 +1656,7 @@ static void ath10k_pci_dump_memory(struct ath10k *ar, ...@@ -1656,7 +1656,7 @@ static void ath10k_pci_dump_memory(struct ath10k *ar,
int ret, i; int ret, i;
u8 *buf; u8 *buf;
lockdep_assert_held(&ar->data_lock); lockdep_assert_held(&ar->dump_mutex);
if (!crash_data) if (!crash_data)
return; return;
...@@ -1734,14 +1734,19 @@ static void ath10k_pci_dump_memory(struct ath10k *ar, ...@@ -1734,14 +1734,19 @@ static void ath10k_pci_dump_memory(struct ath10k *ar,
} }
} }
static void ath10k_pci_fw_crashed_dump(struct ath10k *ar) static void ath10k_pci_fw_dump_work(struct work_struct *work)
{ {
struct ath10k_pci *ar_pci = container_of(work, struct ath10k_pci,
dump_work);
struct ath10k_fw_crash_data *crash_data; struct ath10k_fw_crash_data *crash_data;
struct ath10k *ar = ar_pci->ar;
char guid[UUID_STRING_LEN + 1]; char guid[UUID_STRING_LEN + 1];
spin_lock_bh(&ar->data_lock); mutex_lock(&ar->dump_mutex);
spin_lock_bh(&ar->data_lock);
ar->stats.fw_crash_counter++; ar->stats.fw_crash_counter++;
spin_unlock_bh(&ar->data_lock);
crash_data = ath10k_coredump_new(ar); crash_data = ath10k_coredump_new(ar);
...@@ -1756,11 +1761,18 @@ static void ath10k_pci_fw_crashed_dump(struct ath10k *ar) ...@@ -1756,11 +1761,18 @@ static void ath10k_pci_fw_crashed_dump(struct ath10k *ar)
ath10k_ce_dump_registers(ar, crash_data); ath10k_ce_dump_registers(ar, crash_data);
ath10k_pci_dump_memory(ar, crash_data); ath10k_pci_dump_memory(ar, crash_data);
spin_unlock_bh(&ar->data_lock); mutex_unlock(&ar->dump_mutex);
queue_work(ar->workqueue, &ar->restart_work); queue_work(ar->workqueue, &ar->restart_work);
} }
static void ath10k_pci_fw_crashed_dump(struct ath10k *ar)
{
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
queue_work(ar->workqueue, &ar_pci->dump_work);
}
void ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe, void ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe,
int force) int force)
{ {
...@@ -3442,6 +3454,8 @@ int ath10k_pci_setup_resource(struct ath10k *ar) ...@@ -3442,6 +3454,8 @@ int ath10k_pci_setup_resource(struct ath10k *ar)
spin_lock_init(&ar_pci->ps_lock); spin_lock_init(&ar_pci->ps_lock);
mutex_init(&ar_pci->ce_diag_mutex); mutex_init(&ar_pci->ce_diag_mutex);
INIT_WORK(&ar_pci->dump_work, ath10k_pci_fw_dump_work);
timer_setup(&ar_pci->rx_post_retry, ath10k_pci_rx_replenish_retry, 0); timer_setup(&ar_pci->rx_post_retry, ath10k_pci_rx_replenish_retry, 0);
if (QCA_REV_6174(ar) || QCA_REV_9377(ar)) if (QCA_REV_6174(ar) || QCA_REV_9377(ar))
......
...@@ -121,6 +121,8 @@ struct ath10k_pci { ...@@ -121,6 +121,8 @@ struct ath10k_pci {
/* For protecting ce_diag */ /* For protecting ce_diag */
struct mutex ce_diag_mutex; struct mutex ce_diag_mutex;
struct work_struct dump_work;
struct ath10k_ce ce; struct ath10k_ce ce;
struct timer_list rx_post_retry; struct timer_list rx_post_retry;
......
...@@ -201,7 +201,7 @@ static const struct iwl_ht_params iwl_22000_ht_params = { ...@@ -201,7 +201,7 @@ static const struct iwl_ht_params iwl_22000_ht_params = {
#define IWL_DEVICE_AX210 \ #define IWL_DEVICE_AX210 \
IWL_DEVICE_AX200_COMMON, \ IWL_DEVICE_AX200_COMMON, \
.device_family = IWL_DEVICE_FAMILY_AX210, \ .device_family = IWL_DEVICE_FAMILY_AX210, \
.base_params = &iwl_22000_base_params, \ .base_params = &iwl_22560_base_params, \
.csr = &iwl_csr_v1, \ .csr = &iwl_csr_v1, \
.min_txq_size = 128 .min_txq_size = 128
......
/****************************************************************************** /******************************************************************************
* *
* Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2018 Intel Corporation * Copyright(c) 2018 - 2019 Intel Corporation
* *
* This program is free software; you can redistribute it and/or modify it * 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 * under the terms of version 2 of the GNU General Public License as
...@@ -136,6 +136,7 @@ const struct iwl_cfg iwl5350_agn_cfg = { ...@@ -136,6 +136,7 @@ const struct iwl_cfg iwl5350_agn_cfg = {
.ht_params = &iwl5000_ht_params, .ht_params = &iwl5000_ht_params,
.led_mode = IWL_LED_BLINK, .led_mode = IWL_LED_BLINK,
.internal_wimax_coex = true, .internal_wimax_coex = true,
.csr = &iwl_csr_v1,
}; };
#define IWL_DEVICE_5150 \ #define IWL_DEVICE_5150 \
......
...@@ -93,7 +93,7 @@ struct iwl_ucode_header { ...@@ -93,7 +93,7 @@ struct iwl_ucode_header {
} u; } u;
}; };
#define IWL_UCODE_INI_TLV_GROUP BIT(24) #define IWL_UCODE_INI_TLV_GROUP 0x1000000
/* /*
* new TLV uCode file layout * new TLV uCode file layout
...@@ -148,11 +148,14 @@ enum iwl_ucode_tlv_type { ...@@ -148,11 +148,14 @@ enum iwl_ucode_tlv_type {
IWL_UCODE_TLV_UMAC_DEBUG_ADDRS = 54, IWL_UCODE_TLV_UMAC_DEBUG_ADDRS = 54,
IWL_UCODE_TLV_LMAC_DEBUG_ADDRS = 55, IWL_UCODE_TLV_LMAC_DEBUG_ADDRS = 55,
IWL_UCODE_TLV_FW_RECOVERY_INFO = 57, IWL_UCODE_TLV_FW_RECOVERY_INFO = 57,
IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION = IWL_UCODE_INI_TLV_GROUP | 0x1,
IWL_UCODE_TLV_TYPE_HCMD = IWL_UCODE_INI_TLV_GROUP | 0x2, IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION = IWL_UCODE_INI_TLV_GROUP + 0x1,
IWL_UCODE_TLV_TYPE_REGIONS = IWL_UCODE_INI_TLV_GROUP | 0x3, IWL_UCODE_TLV_DEBUG_BASE = IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION,
IWL_UCODE_TLV_TYPE_TRIGGERS = IWL_UCODE_INI_TLV_GROUP | 0x4, IWL_UCODE_TLV_TYPE_HCMD = IWL_UCODE_INI_TLV_GROUP + 0x2,
IWL_UCODE_TLV_TYPE_DEBUG_FLOW = IWL_UCODE_INI_TLV_GROUP | 0x5, IWL_UCODE_TLV_TYPE_REGIONS = IWL_UCODE_INI_TLV_GROUP + 0x3,
IWL_UCODE_TLV_TYPE_TRIGGERS = IWL_UCODE_INI_TLV_GROUP + 0x4,
IWL_UCODE_TLV_TYPE_DEBUG_FLOW = IWL_UCODE_INI_TLV_GROUP + 0x5,
IWL_UCODE_TLV_DEBUG_MAX = IWL_UCODE_TLV_TYPE_DEBUG_FLOW,
/* TLVs 0x1000-0x2000 are for internal driver usage */ /* TLVs 0x1000-0x2000 are for internal driver usage */
IWL_UCODE_TLV_FW_DBG_DUMP_LST = 0x1000, IWL_UCODE_TLV_FW_DBG_DUMP_LST = 0x1000,
......
...@@ -126,7 +126,8 @@ void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data, ...@@ -126,7 +126,8 @@ void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data,
len -= ALIGN(tlv_len, 4); len -= ALIGN(tlv_len, 4);
data += sizeof(*tlv) + ALIGN(tlv_len, 4); data += sizeof(*tlv) + ALIGN(tlv_len, 4);
if (!(tlv_type & IWL_UCODE_INI_TLV_GROUP)) if (tlv_type < IWL_UCODE_TLV_DEBUG_BASE ||
tlv_type > IWL_UCODE_TLV_DEBUG_MAX)
continue; continue;
hdr = (void *)&tlv->data[0]; hdr = (void *)&tlv->data[0];
......
...@@ -774,8 +774,7 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif) ...@@ -774,8 +774,7 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
return; return;
mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir); mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir);
if (IS_ERR_OR_NULL(mvmvif->dbgfs_dir)) {
if (!mvmvif->dbgfs_dir) {
IWL_ERR(mvm, "Failed to create debugfs directory under %pd\n", IWL_ERR(mvm, "Failed to create debugfs directory under %pd\n",
dbgfs_dir); dbgfs_dir);
return; return;
......
...@@ -1121,7 +1121,9 @@ int iwl_mvm_up(struct iwl_mvm *mvm) ...@@ -1121,7 +1121,9 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
ret = iwl_mvm_load_rt_fw(mvm); ret = iwl_mvm_load_rt_fw(mvm);
if (ret) { if (ret) {
IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret); IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret);
iwl_fw_dbg_error_collect(&mvm->fwrt, FW_DBG_TRIGGER_DRIVER); if (ret != -ERFKILL)
iwl_fw_dbg_error_collect(&mvm->fwrt,
FW_DBG_TRIGGER_DRIVER);
goto error; goto error;
} }
......
...@@ -834,7 +834,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, ...@@ -834,7 +834,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
mutex_lock(&mvm->mutex); mutex_lock(&mvm->mutex);
iwl_mvm_ref(mvm, IWL_MVM_REF_INIT_UCODE); iwl_mvm_ref(mvm, IWL_MVM_REF_INIT_UCODE);
err = iwl_run_init_mvm_ucode(mvm, true); err = iwl_run_init_mvm_ucode(mvm, true);
if (err) if (err && err != -ERFKILL)
iwl_fw_dbg_error_collect(&mvm->fwrt, FW_DBG_TRIGGER_DRIVER); iwl_fw_dbg_error_collect(&mvm->fwrt, FW_DBG_TRIGGER_DRIVER);
if (!iwlmvm_mod_params.init_dbg || !err) if (!iwlmvm_mod_params.init_dbg || !err)
iwl_mvm_stop_device(mvm); iwl_mvm_stop_device(mvm);
......
...@@ -169,8 +169,8 @@ static inline int iwl_mvm_check_pn(struct iwl_mvm *mvm, struct sk_buff *skb, ...@@ -169,8 +169,8 @@ static inline int iwl_mvm_check_pn(struct iwl_mvm *mvm, struct sk_buff *skb,
} }
/* iwl_mvm_create_skb Adds the rxb to a new skb */ /* iwl_mvm_create_skb Adds the rxb to a new skb */
static void iwl_mvm_create_skb(struct sk_buff *skb, struct ieee80211_hdr *hdr, static int iwl_mvm_create_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
u16 len, u8 crypt_len, struct ieee80211_hdr *hdr, u16 len, u8 crypt_len,
struct iwl_rx_cmd_buffer *rxb) struct iwl_rx_cmd_buffer *rxb)
{ {
struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_rx_packet *pkt = rxb_addr(rxb);
...@@ -204,6 +204,20 @@ static void iwl_mvm_create_skb(struct sk_buff *skb, struct ieee80211_hdr *hdr, ...@@ -204,6 +204,20 @@ static void iwl_mvm_create_skb(struct sk_buff *skb, struct ieee80211_hdr *hdr,
* present before copying packet data. * present before copying packet data.
*/ */
hdrlen += crypt_len; hdrlen += crypt_len;
if (WARN_ONCE(headlen < hdrlen,
"invalid packet lengths (hdrlen=%d, len=%d, crypt_len=%d)\n",
hdrlen, len, crypt_len)) {
/*
* We warn and trace because we want to be able to see
* it in trace-cmd as well.
*/
IWL_DEBUG_RX(mvm,
"invalid packet lengths (hdrlen=%d, len=%d, crypt_len=%d)\n",
hdrlen, len, crypt_len);
return -EINVAL;
}
skb_put_data(skb, hdr, hdrlen); skb_put_data(skb, hdr, hdrlen);
skb_put_data(skb, (u8 *)hdr + hdrlen + pad_len, headlen - hdrlen); skb_put_data(skb, (u8 *)hdr + hdrlen + pad_len, headlen - hdrlen);
...@@ -216,6 +230,8 @@ static void iwl_mvm_create_skb(struct sk_buff *skb, struct ieee80211_hdr *hdr, ...@@ -216,6 +230,8 @@ static void iwl_mvm_create_skb(struct sk_buff *skb, struct ieee80211_hdr *hdr,
skb_add_rx_frag(skb, 0, rxb_steal_page(rxb), offset, skb_add_rx_frag(skb, 0, rxb_steal_page(rxb), offset,
fraglen, rxb->truesize); fraglen, rxb->truesize);
} }
return 0;
} }
static void iwl_mvm_add_rtap_sniffer_config(struct iwl_mvm *mvm, static void iwl_mvm_add_rtap_sniffer_config(struct iwl_mvm *mvm,
...@@ -1671,7 +1687,11 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, ...@@ -1671,7 +1687,11 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
rx_status->boottime_ns = ktime_get_boot_ns(); rx_status->boottime_ns = ktime_get_boot_ns();
} }
iwl_mvm_create_skb(skb, hdr, len, crypt_len, rxb); if (iwl_mvm_create_skb(mvm, skb, hdr, len, crypt_len, rxb)) {
kfree_skb(skb);
goto out;
}
if (!iwl_mvm_reorder(mvm, napi, queue, sta, skb, desc)) if (!iwl_mvm_reorder(mvm, napi, queue, sta, skb, desc))
iwl_mvm_pass_packet_to_mac80211(mvm, napi, skb, queue, iwl_mvm_pass_packet_to_mac80211(mvm, napi, skb, queue,
sta, csi); sta, csi);
......
...@@ -3644,20 +3644,27 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, ...@@ -3644,20 +3644,27 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
void iwl_trans_pcie_sync_nmi(struct iwl_trans *trans) void iwl_trans_pcie_sync_nmi(struct iwl_trans *trans)
{ {
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
unsigned long timeout = jiffies + IWL_TRANS_NMI_TIMEOUT; unsigned long timeout = jiffies + IWL_TRANS_NMI_TIMEOUT;
u32 inta_addr, sw_err_bit;
if (trans_pcie->msix_enabled) {
inta_addr = CSR_MSIX_HW_INT_CAUSES_AD;
sw_err_bit = MSIX_HW_INT_CAUSES_REG_SW_ERR;
} else {
inta_addr = CSR_INT;
sw_err_bit = CSR_INT_BIT_SW_ERR;
}
iwl_disable_interrupts(trans); iwl_disable_interrupts(trans);
iwl_force_nmi(trans); iwl_force_nmi(trans);
while (time_after(timeout, jiffies)) { while (time_after(timeout, jiffies)) {
u32 inta_hw = iwl_read32(trans, u32 inta_hw = iwl_read32(trans, inta_addr);
CSR_MSIX_HW_INT_CAUSES_AD);
/* Error detected by uCode */ /* Error detected by uCode */
if (inta_hw & MSIX_HW_INT_CAUSES_REG_SW_ERR) { if (inta_hw & sw_err_bit) {
/* Clear causes register */ /* Clear causes register */
iwl_write32(trans, CSR_MSIX_HW_INT_CAUSES_AD, iwl_write32(trans, inta_addr, inta_hw & sw_err_bit);
inta_hw &
MSIX_HW_INT_CAUSES_REG_SW_ERR);
break; break;
} }
......
...@@ -181,7 +181,7 @@ static int mwifiex_sdio_resume(struct device *dev) ...@@ -181,7 +181,7 @@ static int mwifiex_sdio_resume(struct device *dev)
adapter = card->adapter; adapter = card->adapter;
if (test_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags)) { if (!test_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags)) {
mwifiex_dbg(adapter, WARN, mwifiex_dbg(adapter, WARN,
"device already resumed\n"); "device already resumed\n");
return 0; return 0;
......
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