···7777 IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n",7878 sta_id);79798080- spin_lock(&priv->sta_lock);8080+ spin_lock_bh(&priv->sta_lock);81818282 switch (add_sta_resp->status) {8383 case ADD_STA_SUCCESS_MSK:···119119 priv->stations[sta_id].sta.mode ==120120 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",121121 addsta->sta.addr);122122- spin_unlock(&priv->sta_lock);122122+ spin_unlock_bh(&priv->sta_lock);123123124124 return ret;125125}
+8-8
drivers/net/wireless/iwlwifi/dvm/tx.c
···11171117 sta_id = (tx_resp->ra_tid & IWLAGN_TX_RES_RA_MSK) >>11181118 IWLAGN_TX_RES_RA_POS;1119111911201120- spin_lock(&priv->sta_lock);11201120+ spin_lock_bh(&priv->sta_lock);1121112111221122 if (is_agg)11231123 iwl_rx_reply_tx_agg(priv, tx_resp);···12391239 le16_to_cpu(tx_resp->seq_ctl));1240124012411241 iwl_check_abort_status(priv, tx_resp->frame_count, status);12421242- spin_unlock(&priv->sta_lock);12421242+ spin_unlock_bh(&priv->sta_lock);1243124312441244 while (!skb_queue_empty(&skbs)) {12451245 skb = __skb_dequeue(&skbs);12461246- ieee80211_tx_status(priv->hw, skb);12461246+ ieee80211_tx_status_ni(priv->hw, skb);12471247 }1248124812491249 if (is_offchannel_skb)···12901290 tid = ba_resp->tid;12911291 agg = &priv->tid_data[sta_id][tid].agg;1292129212931293- spin_lock(&priv->sta_lock);12931293+ spin_lock_bh(&priv->sta_lock);1294129412951295 if (unlikely(!agg->wait_for_ba)) {12961296 if (unlikely(ba_resp->bitmap))12971297 IWL_ERR(priv, "Received BA when not expected\n");12981298- spin_unlock(&priv->sta_lock);12981298+ spin_unlock_bh(&priv->sta_lock);12991299 return 0;13001300 }13011301···13091309 IWL_DEBUG_TX_QUEUES(priv,13101310 "Bad queue mapping txq_id=%d, agg_txq[sta:%d,tid:%d]=%d\n",13111311 scd_flow, sta_id, tid, agg->txq_id);13121312- spin_unlock(&priv->sta_lock);13121312+ spin_unlock_bh(&priv->sta_lock);13131313 return 0;13141314 }13151315···13781378 }13791379 }1380138013811381- spin_unlock(&priv->sta_lock);13811381+ spin_unlock_bh(&priv->sta_lock);1382138213831383 while (!skb_queue_empty(&reclaimed_skbs)) {13841384 skb = __skb_dequeue(&reclaimed_skbs);13851385- ieee80211_tx_status(priv->hw, skb);13851385+ ieee80211_tx_status_ni(priv->hw, skb);13861386 }1387138713881388 return 0;
+6-4
drivers/net/wireless/iwlwifi/iwl-op-mode.h
···113113 * May sleep114114 * @rx: Rx notification to the op_mode. rxb is the Rx buffer itself. Cmd is the115115 * HCMD the this Rx responds to.116116- * Must be atomic and called with BH disabled.116116+ * This callback may sleep, it is called from a threaded IRQ handler.117117 * @queue_full: notifies that a HW queue is full.118118 * Must be atomic and called with BH disabled.119119 * @queue_not_full: notifies that a HW queue is not full any more.120120 * Must be atomic and called with BH disabled.121121 * @hw_rf_kill:notifies of a change in the HW rf kill switch. True means that122122- * the radio is killed. Must be atomic.122122+ * the radio is killed. May sleep.123123 * @free_skb: allows the transport layer to free skbs that haven't been124124 * reclaimed by the op_mode. This can happen when the driver is freed and125125 * there are Tx packets pending in the transport layer.···130130 * called with BH disabled.131131 * @nic_config: configure NIC, called before firmware is started.132132 * May sleep133133- * @wimax_active: invoked when WiMax becomes active. Must be atomic and called134134- * with BH disabled.133133+ * @wimax_active: invoked when WiMax becomes active. May sleep135134 */136135struct iwl_op_mode_ops {137136 struct iwl_op_mode *(*start)(struct iwl_trans *trans,···177178 struct iwl_rx_cmd_buffer *rxb,178179 struct iwl_device_cmd *cmd)179180{181181+ might_sleep();180182 return op_mode->ops->rx(op_mode, rxb, cmd);181183}182184···196196static inline void iwl_op_mode_hw_rf_kill(struct iwl_op_mode *op_mode,197197 bool state)198198{199199+ might_sleep();199200 op_mode->ops->hw_rf_kill(op_mode, state);200201}201202···224223225224static inline void iwl_op_mode_wimax_active(struct iwl_op_mode *op_mode)226225{226226+ might_sleep();227227 op_mode->ops->wimax_active(op_mode);228228}229229
+27-2
drivers/net/wireless/iwlwifi/iwl-trans.h
···65656666#include <linux/ieee80211.h>6767#include <linux/mm.h> /* for page_address */6868+#include <linux/lockdep.h>68696970#include "iwl-debug.h"7071#include "iwl-config.h"···527526528527 struct dentry *dbgfs_dir;529528529529+#ifdef CONFIG_LOCKDEP530530+ struct lockdep_map sync_cmd_lockdep_map;531531+#endif532532+530533 /* pointer to trans specific struct */531534 /*Ensure that this pointer will always be aligned to sizeof pointer */532535 char trans_specific[0] __aligned(sizeof(void *));···607602}608603609604static inline int iwl_trans_send_cmd(struct iwl_trans *trans,610610- struct iwl_host_cmd *cmd)605605+ struct iwl_host_cmd *cmd)611606{607607+ int ret;608608+612609 WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,613610 "%s bad state = %d", __func__, trans->state);614611615615- return trans->ops->send_cmd(trans, cmd);612612+ if (!(cmd->flags & CMD_ASYNC))613613+ lock_map_acquire_read(&trans->sync_cmd_lockdep_map);614614+615615+ ret = trans->ops->send_cmd(trans, cmd);616616+617617+ if (!(cmd->flags & CMD_ASYNC))618618+ lock_map_release(&trans->sync_cmd_lockdep_map);619619+620620+ return ret;616621}617622618623static inline struct iwl_device_cmd *···805790******************************************************/806791int __must_check iwl_pci_register_driver(void);807792void iwl_pci_unregister_driver(void);793793+794794+static inline void trans_lockdep_init(struct iwl_trans *trans)795795+{796796+#ifdef CONFIG_LOCKDEP797797+ static struct lock_class_key __key;798798+799799+ lockdep_init_map(&trans->sync_cmd_lockdep_map, "sync_cmd_lockdep_map",800800+ &__key, 0);801801+#endif802802+}808803809804#endif /* __iwl_trans_h__ */
+144-30
drivers/net/wireless/iwlwifi/mvm/d3.c
···9797 struct inet6_ifaddr *ifa;9898 int idx = 0;9999100100- read_lock(&idev->lock);100100+ read_lock_bh(&idev->lock);101101 list_for_each_entry(ifa, &idev->addr_list, if_list) {102102 mvmvif->target_ipv6_addrs[idx] = ifa->addr;103103 idx++;104104 if (idx >= IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS)105105 break;106106 }107107- read_unlock(&idev->lock);107107+ read_unlock_bh(&idev->lock);108108109109 mvmvif->num_target_ipv6_addrs = idx;110110}···490490 return -EIO;491491 }492492493493- ret = iwl_mvm_sta_add_to_fw(mvm, ap_sta);493493+ ret = iwl_mvm_sta_send_to_fw(mvm, ap_sta, false);494494 if (ret)495495 return ret;496496 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], ap_sta);···763763 return ret;764764}765765766766+static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,767767+ struct ieee80211_vif *vif)768768+{769769+ u32 base = mvm->error_event_table;770770+ struct error_table_start {771771+ /* cf. struct iwl_error_event_table */772772+ u32 valid;773773+ u32 error_id;774774+ } err_info;775775+ struct cfg80211_wowlan_wakeup wakeup = {776776+ .pattern_idx = -1,777777+ };778778+ struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup;779779+ struct iwl_host_cmd cmd = {780780+ .id = WOWLAN_GET_STATUSES,781781+ .flags = CMD_SYNC | CMD_WANT_SKB,782782+ };783783+ struct iwl_wowlan_status *status;784784+ u32 reasons;785785+ int ret, len;786786+ bool pkt8023 = false;787787+ struct sk_buff *pkt = NULL;788788+789789+ iwl_trans_read_mem_bytes(mvm->trans, base,790790+ &err_info, sizeof(err_info));791791+792792+ if (err_info.valid) {793793+ IWL_INFO(mvm, "error table is valid (%d)\n",794794+ err_info.valid);795795+ if (err_info.error_id == RF_KILL_INDICATOR_FOR_WOWLAN) {796796+ wakeup.rfkill_release = true;797797+ ieee80211_report_wowlan_wakeup(vif, &wakeup,798798+ GFP_KERNEL);799799+ }800800+ return;801801+ }802802+803803+ /* only for tracing for now */804804+ ret = iwl_mvm_send_cmd_pdu(mvm, OFFLOADS_QUERY_CMD, CMD_SYNC, 0, NULL);805805+ if (ret)806806+ IWL_ERR(mvm, "failed to query offload statistics (%d)\n", ret);807807+808808+ ret = iwl_mvm_send_cmd(mvm, &cmd);809809+ if (ret) {810810+ IWL_ERR(mvm, "failed to query status (%d)\n", ret);811811+ return;812812+ }813813+814814+ /* RF-kill already asserted again... */815815+ if (!cmd.resp_pkt)816816+ return;817817+818818+ len = le32_to_cpu(cmd.resp_pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;819819+ if (len - sizeof(struct iwl_cmd_header) < sizeof(*status)) {820820+ IWL_ERR(mvm, "Invalid WoWLAN status response!\n");821821+ goto out;822822+ }823823+824824+ status = (void *)cmd.resp_pkt->data;825825+826826+ if (len - sizeof(struct iwl_cmd_header) !=827827+ sizeof(*status) + le32_to_cpu(status->wake_packet_bufsize)) {828828+ IWL_ERR(mvm, "Invalid WoWLAN status response!\n");829829+ goto out;830830+ }831831+832832+ reasons = le32_to_cpu(status->wakeup_reasons);833833+834834+ if (reasons == IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) {835835+ wakeup_report = NULL;836836+ goto report;837837+ }838838+839839+ if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET) {840840+ wakeup.magic_pkt = true;841841+ pkt8023 = true;842842+ }843843+844844+ if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN) {845845+ wakeup.pattern_idx =846846+ le16_to_cpu(status->pattern_number);847847+ pkt8023 = true;848848+ }849849+850850+ if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |851851+ IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH))852852+ wakeup.disconnect = true;853853+854854+ if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE) {855855+ wakeup.gtk_rekey_failure = true;856856+ pkt8023 = true;857857+ }858858+859859+ if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) {860860+ wakeup.rfkill_release = true;861861+ pkt8023 = true;862862+ }863863+864864+ if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST) {865865+ wakeup.eap_identity_req = true;866866+ pkt8023 = true;867867+ }868868+869869+ if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE) {870870+ wakeup.four_way_handshake = true;871871+ pkt8023 = true;872872+ }873873+874874+ if (status->wake_packet_bufsize) {875875+ u32 pktsize = le32_to_cpu(status->wake_packet_bufsize);876876+ u32 pktlen = le32_to_cpu(status->wake_packet_length);877877+878878+ if (pkt8023) {879879+ pkt = alloc_skb(pktsize, GFP_KERNEL);880880+ if (!pkt)881881+ goto report;882882+ memcpy(skb_put(pkt, pktsize), status->wake_packet,883883+ pktsize);884884+ if (ieee80211_data_to_8023(pkt, vif->addr, vif->type))885885+ goto report;886886+ wakeup.packet = pkt->data;887887+ wakeup.packet_present_len = pkt->len;888888+ wakeup.packet_len = pkt->len - (pktlen - pktsize);889889+ wakeup.packet_80211 = false;890890+ } else {891891+ wakeup.packet = status->wake_packet;892892+ wakeup.packet_present_len = pktsize;893893+ wakeup.packet_len = pktlen;894894+ wakeup.packet_80211 = true;895895+ }896896+ }897897+898898+ report:899899+ ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL);900900+ kfree_skb(pkt);901901+902902+ out:903903+ iwl_free_resp(&cmd);904904+}905905+766906int iwl_mvm_resume(struct ieee80211_hw *hw)767907{768908 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);···910770 .mvm = mvm,911771 };912772 struct ieee80211_vif *vif = NULL;913913- u32 base;914773 int ret;915774 enum iwl_d3_status d3_status;916916- struct error_table_start {917917- /* cf. struct iwl_error_event_table */918918- u32 valid;919919- u32 error_id;920920- } err_info;921775922776 mutex_lock(&mvm->mutex);923777···934800 goto out_unlock;935801 }936802937937- base = mvm->error_event_table;938938-939939- iwl_trans_read_mem_bytes(mvm->trans, base,940940- &err_info, sizeof(err_info));941941-942942- if (err_info.valid) {943943- IWL_INFO(mvm, "error table is valid (%d)\n",944944- err_info.valid);945945- if (err_info.error_id == RF_KILL_INDICATOR_FOR_WOWLAN)946946- IWL_ERR(mvm, "this was due to RF-kill\n");947947- goto out_unlock;948948- }949949-950950- /* TODO: get status and whatever else ... */951951- ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_GET_STATUSES, CMD_SYNC, 0, NULL);952952- if (ret)953953- IWL_ERR(mvm, "failed to query status (%d)\n", ret);954954-955955- ret = iwl_mvm_send_cmd_pdu(mvm, OFFLOADS_QUERY_CMD, CMD_SYNC, 0, NULL);956956- if (ret)957957- IWL_ERR(mvm, "failed to query offloads (%d)\n", ret);803803+ iwl_mvm_query_wakeup_reasons(mvm, vif);958804959805 out_unlock:960806 mutex_unlock(&mvm->mutex);
+3
drivers/net/wireless/iwlwifi/mvm/fw-api.h
···633633 __le32 phy;634634} __packed; /* BINDING_CMD_API_S_VER_1 */635635636636+/* The maximal number of fragments in the FW's schedule session */637637+#define IWL_MVM_MAX_QUOTA 128638638+636639/**637640 * struct iwl_time_quota_data - configuration of time quota per binding638641 * @id_and_color: ID and color of the relevant Binding
···584584 struct ieee80211_vif *vif,585585 struct iwl_mac_data_sta *ctxt_sta)586586{587587- ctxt_sta->is_assoc = cpu_to_le32(vif->bss_conf.assoc ? 1 : 0);587587+ /* We need the dtim_period to set the MAC as associated */588588+ if (vif->bss_conf.assoc && vif->bss_conf.dtim_period)589589+ ctxt_sta->is_assoc = cpu_to_le32(1);590590+ else591591+ ctxt_sta->is_assoc = cpu_to_le32(0);588592589593 ctxt_sta->bi = cpu_to_le32(vif->bss_conf.beacon_int);590594 ctxt_sta->bi_reciprocal =
+12-5
drivers/net/wireless/iwlwifi/mvm/mac80211.c
···474474 if (mvm->vif_count > 1) {475475 IWL_DEBUG_MAC80211(mvm,476476 "Disable power on existing interfaces\n");477477- ieee80211_iterate_active_interfaces(477477+ ieee80211_iterate_active_interfaces_atomic(478478 mvm->hw,479479 IEEE80211_IFACE_ITER_NORMAL,480480 iwl_mvm_pm_disable_iterator, mvm);···670670 IWL_ERR(mvm, "failed to update quotas\n");671671 return;672672 }673673- iwl_mvm_remove_time_event(mvm, mvmvif,674674- &mvmvif->time_event_data);675673 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {676674 /* remove AP station now that the MAC is unassoc */677675 ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id);···681683 if (ret)682684 IWL_ERR(mvm, "failed to update quotas\n");683685 }686686+ } else if (changes & BSS_CHANGED_DTIM_PERIOD) {687687+ /*688688+ * We received a beacon _after_ association so689689+ * remove the session protection.690690+ */691691+ iwl_mvm_remove_time_event(mvm, mvmvif,692692+ &mvmvif->time_event_data);684693 } else if (changes & BSS_CHANGED_PS) {685694 /*686695 * TODO: remove this temporary code.···926921 ret = 0;927922 } else if (old_state == IEEE80211_STA_AUTH &&928923 new_state == IEEE80211_STA_ASSOC) {929929- iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band);930930- ret = 0;924924+ ret = iwl_mvm_update_sta(mvm, vif, sta);925925+ if (ret == 0)926926+ iwl_mvm_rs_rate_init(mvm, sta,927927+ mvmvif->phy_ctxt->channel->band);931928 } else if (old_state == IEEE80211_STA_ASSOC &&932929 new_state == IEEE80211_STA_AUTHORIZED) {933930 ret = 0;
+20-17
drivers/net/wireless/iwlwifi/mvm/ops.c
···536536537537 for (i = 0; i < ARRAY_SIZE(iwl_mvm_rx_handlers); i++) {538538 const struct iwl_rx_handlers *rx_h = &iwl_mvm_rx_handlers[i];539539- if (rx_h->cmd_id == pkt->hdr.cmd) {540540- struct iwl_async_handler_entry *entry;541541- if (!rx_h->async)542542- return rx_h->fn(mvm, rxb, cmd);539539+ struct iwl_async_handler_entry *entry;543540544544- entry = kzalloc(sizeof(*entry), GFP_ATOMIC);545545- /* we can't do much... */546546- if (!entry)547547- return 0;541541+ if (rx_h->cmd_id != pkt->hdr.cmd)542542+ continue;548543549549- entry->rxb._page = rxb_steal_page(rxb);550550- entry->rxb._offset = rxb->_offset;551551- entry->rxb._rx_page_order = rxb->_rx_page_order;552552- entry->fn = rx_h->fn;553553- spin_lock(&mvm->async_handlers_lock);554554- list_add_tail(&entry->list, &mvm->async_handlers_list);555555- spin_unlock(&mvm->async_handlers_lock);556556- schedule_work(&mvm->async_handlers_wk);557557- }544544+ if (!rx_h->async)545545+ return rx_h->fn(mvm, rxb, cmd);546546+547547+ entry = kzalloc(sizeof(*entry), GFP_ATOMIC);548548+ /* we can't do much... */549549+ if (!entry)550550+ return 0;551551+552552+ entry->rxb._page = rxb_steal_page(rxb);553553+ entry->rxb._offset = rxb->_offset;554554+ entry->rxb._rx_page_order = rxb->_rx_page_order;555555+ entry->fn = rx_h->fn;556556+ spin_lock(&mvm->async_handlers_lock);557557+ list_add_tail(&entry->list, &mvm->async_handlers_list);558558+ spin_unlock(&mvm->async_handlers_lock);559559+ schedule_work(&mvm->async_handlers_wk);560560+ break;558561 }559562560563 return 0;
···8181 * 'processed' and 'read' driver indexes as well)8282 * + A received packet is processed and handed to the kernel network stack,8383 * detached from the iwl->rxq. The driver 'processed' index is updated.8484- * + The Host/Firmware iwl->rxq is replenished at tasklet time from the rx_free8585- * list. If there are no allocated buffers in iwl->rxq->rx_free, the READ8686- * INDEX is not incremented and iwl->status(RX_STALLED) is set. If there8787- * were enough free buffers and RX_STALLED is set it is cleared.8484+ * + The Host/Firmware iwl->rxq is replenished at irq thread time from the8585+ * rx_free list. If there are no allocated buffers in iwl->rxq->rx_free,8686+ * the READ INDEX is not incremented and iwl->status(RX_STALLED) is set.8787+ * If there were enough free buffers and RX_STALLED is set it is cleared.8888 *8989 *9090 * Driver sequence:···214214 /*215215 * If the device isn't enabled - not need to try to add buffers...216216 * This can happen when we stop the device and still have an interrupt217217- * pending. We stop the APM before we sync the interrupts / tasklets218218- * because we have to (see comment there). On the other hand, since219219- * the APM is stopped, we cannot access the HW (in particular not prph).217217+ * pending. We stop the APM before we sync the interrupts because we218218+ * have to (see comment there). On the other hand, since the APM is219219+ * stopped, we cannot access the HW (in particular not prph).220220 * So don't try to restock if the APM has been already stopped.221221 */222222 if (!test_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status))···796796 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status);797797 wake_up(&trans_pcie->wait_command_queue);798798799799+ local_bh_disable();799800 iwl_op_mode_nic_error(trans->op_mode);801801+ local_bh_enable();800802}801803802802-void iwl_pcie_tasklet(struct iwl_trans *trans)804804+irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id)803805{806806+ struct iwl_trans *trans = dev_id;804807 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);805808 struct isr_statistics *isr_stats = &trans_pcie->isr_stats;806809 u32 inta = 0;···813810#ifdef CONFIG_IWLWIFI_DEBUG814811 u32 inta_mask;815812#endif813813+814814+ lock_map_acquire(&trans->sync_cmd_lockdep_map);816815817816 spin_lock_irqsave(&trans_pcie->irq_lock, flags);818817···860855861856 handled |= CSR_INT_BIT_HW_ERR;862857863863- return;858858+ goto out;864859 }865860866861#ifdef CONFIG_IWLWIFI_DEBUG···10101005 /* Re-enable RF_KILL if it occurred */10111006 else if (handled & CSR_INT_BIT_RF_KILL)10121007 iwl_enable_rfkill_int(trans);10081008+10091009+out:10101010+ lock_map_release(&trans->sync_cmd_lockdep_map);10111011+ return IRQ_HANDLED;10131012}1014101310151014/******************************************************************************···1136112711371128 /* Disable (but don't clear!) interrupts here to avoid11381129 * back-to-back ISRs and sporadic interrupts from our NIC.11391139- * If we have something to service, the tasklet will re-enable ints.11301130+ * If we have something to service, the irq thread will re-enable ints.11401131 * If we *don't* have something, we'll re-enable before leaving here. */11411132 inta_mask = iwl_read32(trans, CSR_INT_MASK);11421133 iwl_write32(trans, CSR_INT_MASK, 0x00000000);···11761167#endif1177116811781169 trans_pcie->inta |= inta;11791179- /* iwl_pcie_tasklet() will service interrupts and re-enable them */11701170+ /* the thread will service interrupts and re-enable them */11801171 if (likely(inta))11811181- tasklet_schedule(&trans_pcie->irq_tasklet);11721172+ return IRQ_WAKE_THREAD;11821173 else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&11831174 !trans_pcie->inta)11841175 iwl_enable_interrupts(trans);···12861277 trans_pcie->inta |= inta;1287127812881279 /* iwl_pcie_tasklet() will service interrupts and re-enable them */12891289- if (likely(inta))12901290- tasklet_schedule(&trans_pcie->irq_tasklet);12911291- else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&12801280+ if (likely(inta)) {12811281+ spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);12821282+ return IRQ_WAKE_THREAD;12831283+ } else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&12921284 !trans_pcie->inta) {12931285 /* Allow interrupt if was disabled by this handler and12941286 * no tasklet was schedules, We should not enable interrupt,