diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 513a85403924dcb25ddc8c97d83ea58cbc75af49..406cf1cb945cfe330be0185f17dd7cd9f173cd53 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -1310,6 +1310,7 @@ static ssize_t iwl_dbgfs_d0i3_refs_read(struct file *file, PRINT_MVM_REF(IWL_MVM_REF_FW_DBG_COLLECT); PRINT_MVM_REF(IWL_MVM_REF_INIT_UCODE); PRINT_MVM_REF(IWL_MVM_REF_SENDING_CMD); + PRINT_MVM_REF(IWL_MVM_REF_RX); return simple_read_from_buffer(user_buf, count, ppos, buf, pos); } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 23d7539edf179d112e4a19cdece3b236658ad002..820f8d661e159a2fb60d1939cda27d49fde27c4a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -302,6 +302,7 @@ enum iwl_mvm_ref_type { IWL_MVM_REF_FW_DBG_COLLECT, IWL_MVM_REF_INIT_UCODE, IWL_MVM_REF_SENDING_CMD, + IWL_MVM_REF_RX, /* update debugfs.c when changing this */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c index 58e7e4feed3a4a4a96a625900ac38913e0b396a8..ab7f7eda9c13834efa6d9fe56a9f954ad5a78fab 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c @@ -272,6 +272,7 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi, u32 rate_n_flags; u32 rx_pkt_status; u8 crypt_len = 0; + bool take_ref; phy_info = &mvm->last_phy_info; rx_res = (struct iwl_rx_mpdu_res_start *)pkt->data; @@ -458,8 +459,22 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi, ieee80211_is_probe_resp(hdr->frame_control))) rx_status->boottime_ns = ktime_get_boot_ns(); + /* Take a reference briefly to kick off a d0i3 entry delay so + * we can handle bursts of RX packets without toggling the + * state too often. But don't do this for beacons if we are + * going to idle because the beacon filtering changes we make + * cause the firmware to send us collateral beacons. */ + take_ref = !(test_bit(STATUS_TRANS_GOING_IDLE, &mvm->trans->status) && + ieee80211_is_beacon(hdr->frame_control)); + + if (take_ref) + iwl_mvm_ref(mvm, IWL_MVM_REF_RX); + iwl_mvm_pass_packet_to_mac80211(mvm, sta, napi, skb, hdr, len, ampdu_status, crypt_len, rxb); + + if (take_ref) + iwl_mvm_unref(mvm, IWL_MVM_REF_RX); } static void iwl_mvm_update_rx_statistics(struct iwl_mvm *mvm,