iwlwifi: mvm: add a new mvm reference type for RX data
authorLuca Coelho <luciano.coelho@intel.com>
Wed, 30 Mar 2016 12:05:56 +0000 (15:05 +0300)
committerLuca Coelho <luciano.coelho@intel.com>
Tue, 10 May 2016 19:14:51 +0000 (22:14 +0300)
When a data packet is received, we need to make sure that we stay
awake until it can be processed and wait a while before trying to
enter runtime_suspend os system_suspend again.  To do so, add a new
reference type for RX data and take the reference when sending the
packet to mac80211.  We only do this for data packets, all the other
RX packets sent by the firmware (e.g. notifications) are not a reason
to prevent suspend.

Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
drivers/net/wireless/intel/iwlwifi/mvm/rx.c

index 513a85403924dcb25ddc8c97d83ea58cbc75af49..406cf1cb945cfe330be0185f17dd7cd9f173cd53 100644 (file)
@@ -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);
 }
index 23d7539edf179d112e4a19cdece3b236658ad002..820f8d661e159a2fb60d1939cda27d49fde27c4a 100644 (file)
@@ -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 */
 
index 58e7e4feed3a4a4a96a625900ac38913e0b396a8..ab7f7eda9c13834efa6d9fe56a9f954ad5a78fab 100644 (file)
@@ -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,