Search Linux Wireless

Re: [PATCH] mac80211/ath9k: Support AMPDU with multiple VIFs.

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

 



On Thu, 2010-09-23 at 09:44 -0700, greearb@xxxxxxxxxxxxxxx wrote:
> From: Ben Greear <greearb@xxxxxxxxxxxxxxx>
> 
> The old ieee80211_find_sta_by_hw method didn't properly
> find VIFS when there was more than one per AP.  This caused
> AMPDU logic in ath9k to get the wrong VIF when trying to
> account for transmitted SKBs.
> 
> This patch changes ieee80211_find_sta_by_hw to take a
> localaddr argument to distinguish between VIFs with the
> same AP but different local addresses.  The method name
> is changed to ieee80211_find_sta_by_ifaddr.
> 
> Signed-off-by: Ben Greear <greearb@xxxxxxxxxxxxxxx>

Acked-by: Johannes Berg <johannes@xxxxxxxxxxxxxxxx>

> ---
> :100644 100644 c5e7af4... 9cd0597... M	drivers/net/wireless/ath/ath9k/recv.c
> :100644 100644 85a7323... f7da6b2... M	drivers/net/wireless/ath/ath9k/xmit.c
> :100644 100644 12a49f0... a0afea1... M	include/net/mac80211.h
> :100644 100644 44e10a9... ca2cba9... M	net/mac80211/sta_info.c
>  drivers/net/wireless/ath/ath9k/recv.c |    6 +++++-
>  drivers/net/wireless/ath/ath9k/xmit.c |    3 +--
>  include/net/mac80211.h                |   25 ++++++++++++++-----------
>  net/mac80211/sta_info.c               |   15 +++++++++++----
>  4 files changed, 31 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
> index c5e7af4..9cd0597 100644
> --- a/drivers/net/wireless/ath/ath9k/recv.c
> +++ b/drivers/net/wireless/ath/ath9k/recv.c
> @@ -977,7 +977,11 @@ static void ath9k_process_rssi(struct ath_common *common,
>  	 * at least one sdata of a wiphy on mac80211 but with ath9k virtual
>  	 * wiphy you'd have to iterate over every wiphy and each sdata.
>  	 */
> -	sta = ieee80211_find_sta_by_hw(hw, hdr->addr2);
> +	if (is_multicast_ether_addr(hdr->addr1))
> +		sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr2, NULL);
> +	else
> +		sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr2, hdr->addr1);
> +		
>  	if (sta) {
>  		an = (struct ath_node *) sta->drv_priv;
>  		if (rx_stats->rs_rssi != ATH9K_RSSI_BAD &&
> diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
> index 85a7323..f7da6b2 100644
> --- a/drivers/net/wireless/ath/ath9k/xmit.c
> +++ b/drivers/net/wireless/ath/ath9k/xmit.c
> @@ -328,8 +328,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
>  
>  	rcu_read_lock();
>  
> -	/* XXX: use ieee80211_find_sta! */
> -	sta = ieee80211_find_sta_by_hw(hw, hdr->addr1);
> +	sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2);
>  	if (!sta) {
>  		rcu_read_unlock();
>  
> diff --git a/include/net/mac80211.h b/include/net/mac80211.h
> index 12a49f0..a0afea1 100644
> --- a/include/net/mac80211.h
> +++ b/include/net/mac80211.h
> @@ -2416,25 +2416,28 @@ struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif,
>  					 const u8 *addr);
>  
>  /**
> - * ieee80211_find_sta_by_hw - find a station on hardware
> + * ieee80211_find_sta_by_ifaddr - find a station on hardware
>   *
>   * @hw: pointer as obtained from ieee80211_alloc_hw()
> - * @addr: station's address
> + * @addr: remote station's address
> + * @localaddr: local address (vif->sdata->vif.addr). Use NULL for 'any'.
>   *
>   * This function must be called under RCU lock and the
>   * resulting pointer is only valid under RCU lock as well.
>   *
> - * NOTE: This function should not be used! When mac80211 is converted
> - *	 internally to properly keep track of stations on multiple
> - *	 virtual interfaces, it will not always know which station to
> - *	 return here since a single address might be used by multiple
> - *	 logical stations (e.g. consider a station connecting to another
> - *	 BSSID on the same AP hardware without disconnecting first).
> + * NOTE: You may pass NULL for localaddr, but then you will just get
> + *      the first STA that matches the remote address 'addr'.
> + *      We can have multiple STA associated with multiple
> + *      logical stations (e.g. consider a station connecting to another
> + *      BSSID on the same AP hardware without disconnecting first).
> + *      In this case, the result of this method with localaddr NULL
> + *      is not reliable.
>   *
> - * DO NOT USE THIS FUNCTION.
> + * DO NOT USE THIS FUNCTION with localaddr NULL if at all possible.
>   */
> -struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw,
> -					       const u8 *addr);
> +struct ieee80211_sta *ieee80211_find_sta_by_ifaddr(struct ieee80211_hw *hw,
> +					       const u8 *addr,
> +					       const u8 *localaddr);
>  
>  /**
>   * ieee80211_sta_block_awake - block station from waking up
> diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
> index 44e10a9..ca2cba9 100644
> --- a/net/mac80211/sta_info.c
> +++ b/net/mac80211/sta_info.c
> @@ -838,13 +838,20 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
>  	mutex_unlock(&local->sta_mtx);
>  }
>  
> -struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw,
> -					       const u8 *addr)
> +struct ieee80211_sta *ieee80211_find_sta_by_ifaddr(struct ieee80211_hw *hw,
> +					       const u8 *addr,
> +					       const u8 *localaddr)
>  {
>  	struct sta_info *sta, *nxt;
>  
> -	/* Just return a random station ... first in list ... */
> +	/*
> +	 * Just return a random station if localaddr is NULL
> +	 * ... first in list.
> +	 */
>  	for_each_sta_info(hw_to_local(hw), addr, sta, nxt) {
> +		if (localaddr &&
> +		    compare_ether_addr(sta->sdata->vif.addr, localaddr) != 0)
> +			continue;
>  		if (!sta->uploaded)
>  			return NULL;
>  		return &sta->sta;
> @@ -852,7 +859,7 @@ struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw,
>  
>  	return NULL;
>  }
> -EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw);
> +EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_ifaddr);
>  
>  struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif,
>  					 const u8 *addr)


--
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