diff options
Diffstat (limited to 'net/mac80211/mesh_ps.c')
| -rw-r--r-- | net/mac80211/mesh_ps.c | 37 | 
1 files changed, 20 insertions, 17 deletions
diff --git a/net/mac80211/mesh_ps.c b/net/mac80211/mesh_ps.c index 22290a929b9..ad8b377b4b9 100644 --- a/net/mac80211/mesh_ps.c +++ b/net/mac80211/mesh_ps.c @@ -36,6 +36,7 @@ static struct sk_buff *mps_qos_null_get(struct sta_info *sta)  				      sdata->vif.addr);  	nullfunc->frame_control = fc;  	nullfunc->duration_id = 0; +	nullfunc->seq_ctrl = 0;  	/* no address resolution for this frame -> set addr 1 immediately */  	memcpy(nullfunc->addr1, sta->sta.addr, ETH_ALEN);  	memset(skb_put(skb, 2), 0, 2); /* append QoS control field */ @@ -152,6 +153,9 @@ u32 ieee80211_mps_set_sta_local_pm(struct sta_info *sta,  {  	struct ieee80211_sub_if_data *sdata = sta->sdata; +	if (sta->local_pm == pm) +		return 0; +  	mps_dbg(sdata, "local STA operates in mode %d with %pM\n",  		pm, sta->sta.addr); @@ -245,6 +249,14 @@ void ieee80211_mps_sta_status_update(struct sta_info *sta)  	do_buffer = (pm != NL80211_MESH_POWER_ACTIVE); +	/* clear the MPSP flags for non-peers or active STA */ +	if (sta->plink_state != NL80211_PLINK_ESTAB) { +		clear_sta_flag(sta, WLAN_STA_MPSP_OWNER); +		clear_sta_flag(sta, WLAN_STA_MPSP_RECIPIENT); +	} else if (!do_buffer) { +		clear_sta_flag(sta, WLAN_STA_MPSP_OWNER); +	} +  	/* Don't let the same PS state be set twice */  	if (test_sta_flag(sta, WLAN_STA_PS_STA) == do_buffer)  		return; @@ -257,14 +269,6 @@ void ieee80211_mps_sta_status_update(struct sta_info *sta)  	} else {  		ieee80211_sta_ps_deliver_wakeup(sta);  	} - -	/* clear the MPSP flags for non-peers or active STA */ -	if (sta->plink_state != NL80211_PLINK_ESTAB) { -		clear_sta_flag(sta, WLAN_STA_MPSP_OWNER); -		clear_sta_flag(sta, WLAN_STA_MPSP_RECIPIENT); -	} else if (!do_buffer) { -		clear_sta_flag(sta, WLAN_STA_MPSP_OWNER); -	}  }  static void mps_set_sta_peer_pm(struct sta_info *sta, @@ -444,8 +448,7 @@ static void mpsp_qos_null_append(struct sta_info *sta,   */  static void mps_frame_deliver(struct sta_info *sta, int n_frames)  { -	struct ieee80211_sub_if_data *sdata = sta->sdata; -	struct ieee80211_local *local = sdata->local; +	struct ieee80211_local *local = sta->sdata->local;  	int ac;  	struct sk_buff_head frames;  	struct sk_buff *skb; @@ -558,10 +561,10 @@ void ieee80211_mpsp_trigger_process(u8 *qc, struct sta_info *sta,  }  /** - * ieee80211_mps_frame_release - release buffered frames in response to beacon + * ieee80211_mps_frame_release - release frames buffered due to mesh power save   *   * @sta: mesh STA - * @elems: beacon IEs + * @elems: IEs of beacon or probe response   *   * For peers if we have individually-addressed frames buffered or the peer   * indicates buffered frames, send a corresponding MPSP trigger frame. Since @@ -574,10 +577,9 @@ void ieee80211_mps_frame_release(struct sta_info *sta,  	int ac, buffer_local = 0;  	bool has_buffered = false; -	/* TIM map only for LLID <= IEEE80211_MAX_AID */  	if (sta->plink_state == NL80211_PLINK_ESTAB)  		has_buffered = ieee80211_check_tim(elems->tim, elems->tim_len, -				le16_to_cpu(sta->llid) % IEEE80211_MAX_AID); +						   sta->llid);  	if (has_buffered)  		mps_dbg(sta->sdata, "%pM indicates buffered frames\n", @@ -588,9 +590,10 @@ void ieee80211_mps_frame_release(struct sta_info *sta,  	    (!elems->awake_window || !le16_to_cpu(*elems->awake_window)))  		return; -	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) -		buffer_local += skb_queue_len(&sta->ps_tx_buf[ac]) + -				skb_queue_len(&sta->tx_filtered[ac]); +	if (!test_sta_flag(sta, WLAN_STA_MPSP_OWNER)) +		for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) +			buffer_local += skb_queue_len(&sta->ps_tx_buf[ac]) + +					skb_queue_len(&sta->tx_filtered[ac]);  	if (!has_buffered && !buffer_local)  		return;  | 
