diff options
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/rx.c')
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/rx.c | 28 | 
1 files changed, 24 insertions, 4 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c index 485cfc1a4daa..ab7f7eda9c13 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c @@ -97,6 +97,7 @@ void iwl_mvm_rx_rx_phy_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)   * Adds the rxb to a new skb and give it to mac80211   */  static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm, +					    struct ieee80211_sta *sta,  					    struct napi_struct *napi,  					    struct sk_buff *skb,  					    struct ieee80211_hdr *hdr, u16 len, @@ -131,7 +132,7 @@ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm,  				fraglen, rxb->truesize);  	} -	ieee80211_rx_napi(mvm->hw, skb, napi); +	ieee80211_rx_napi(mvm->hw, sta, skb, napi);  }  /* @@ -271,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; @@ -319,7 +321,7 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi,  	rx_status->device_timestamp = le32_to_cpu(phy_info->system_timestamp);  	rx_status->band =  		(phy_info->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_BAND_24)) ? -				IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; +				NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;  	rx_status->freq =  		ieee80211_channel_to_frequency(le16_to_cpu(phy_info->channel),  					       rx_status->band); @@ -453,8 +455,26 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi,  		     mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_ENABLED))  		mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_FOUND; -	iwl_mvm_pass_packet_to_mac80211(mvm, napi, skb, hdr, len, ampdu_status, -					crypt_len, rxb); +	if (unlikely(ieee80211_is_beacon(hdr->frame_control) || +		     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,  | 
