Search Linux Wireless

Re: [PATCH] mac80211: add a function for setting the TIM bit for a specific station

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, 2011-04-17 at 17:45 +0200, Felix Fietkau wrote:
> This allows a driver to buffer frames for a PS station and tell mac80211
> to wake it up even though mac80211 does not have any buffered frames for
> it.
> This is necessary for properly handling aggregation related buffering,
> in ath9k, because the driver needs to keep its frames in order to keep
> track of the Block-ACK window.

Indeed, I thought I'd solved these cases with the WLAN_STA_PS_DRIVER
thing but that's not true of course because it blocks wakeup until all
frames have been filtered, which will never happen here. I think I'll
probably need to implement using this in iwlwifi as well.

The only question I have is how will PS-Poll be handled while an
aggregation session is active?? Is it even allowed to poll a-MPDUs?

johannes

> Signed-off-by: Felix Fietkau <nbd@xxxxxxxxxxx>
> ---
>  include/net/mac80211.h  |   12 ++++++++++++
>  net/mac80211/sta_info.c |   13 ++++++++++++-
>  net/mac80211/sta_info.h |    3 +++
>  3 files changed, 27 insertions(+), 1 deletions(-)
> 
> diff --git a/include/net/mac80211.h b/include/net/mac80211.h
> index 6c9c4e9..d23dd6c 100644
> --- a/include/net/mac80211.h
> +++ b/include/net/mac80211.h
> @@ -2227,6 +2227,18 @@ static inline int ieee80211_sta_ps_transition_ni(struct ieee80211_sta *sta,
>  #define IEEE80211_TX_STATUS_HEADROOM	13
>  
>  /**
> + * ieee80211_sta_set_tim - set the TIM bit for a sleeping station
> + *
> + * If a driver buffers frames for a powersave station instead of passing
> + * them back to mac80211 for retransmission, the station needs to be told
> + * to wake up using the TIM bitmap in the beacon.
> + *
> + * This function sets the station's TIM bit - it will be cleared when the
> + * station wakes up.
> + */
> +void ieee80211_sta_set_tim(struct ieee80211_sta *sta);
> +
> +/**
>   * ieee80211_tx_status - transmit status callback
>   *
>   * Call this function for all transmitted frames after they have been
> diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
> index 9421760..a03d8a3 100644
> --- a/net/mac80211/sta_info.c
> +++ b/net/mac80211/sta_info.c
> @@ -612,7 +612,8 @@ static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
>  #endif
>  		dev_kfree_skb(skb);
>  
> -		if (skb_queue_empty(&sta->ps_tx_buf))
> +		if (skb_queue_empty(&sta->ps_tx_buf) &&
> +		    !test_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF))
>  			sta_info_clear_tim_bit(sta);
>  	}
>  
> @@ -896,6 +897,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
>  	struct ieee80211_local *local = sdata->local;
>  	int sent, buffered;
>  
> +	clear_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF);
>  	if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS))
>  		drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta);
>  
> @@ -988,3 +990,12 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
>  		ieee80211_queue_work(hw, &sta->drv_unblock_wk);
>  }
>  EXPORT_SYMBOL(ieee80211_sta_block_awake);
> +
> +void ieee80211_sta_set_tim(struct ieee80211_sta *pubsta)
> +{
> +	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
> +
> +	set_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF);
> +	sta_info_set_tim_bit(sta);
> +}
> +EXPORT_SYMBOL(ieee80211_sta_set_tim);
> diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
> index 3415136..aa0adcb 100644
> --- a/net/mac80211/sta_info.h
> +++ b/net/mac80211/sta_info.h
> @@ -43,6 +43,8 @@
>   *	be in the queues
>   * @WLAN_STA_PSPOLL: Station sent PS-poll while driver was keeping
>   *	station in power-save mode, reply when the driver unblocks.
> + * @WLAN_STA_PS_DRIVER_BUF: Station has frames pending in driver internal
> + *	buffers. Automatically cleared on station wake-up.
>   */
>  enum ieee80211_sta_info_flags {
>  	WLAN_STA_AUTH		= 1<<0,
> @@ -58,6 +60,7 @@ enum ieee80211_sta_info_flags {
>  	WLAN_STA_BLOCK_BA	= 1<<11,
>  	WLAN_STA_PS_DRIVER	= 1<<12,
>  	WLAN_STA_PSPOLL		= 1<<13,
> +	WLAN_STA_PS_DRIVER_BUF	= 1<<14,
>  };
>  
>  #define STA_TID_NUM 16


--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux