Search Linux Wireless

Re: [PATCH v2] ath5k: Adjust opmode when interfaces are removed.

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

 



On Sat October 9 2010 04:01:15 greearb@xxxxxxxxxxxxxxx wrote:
> From: Ben Greear <greearb@xxxxxxxxxxxxxxx>
> 
> Otherwise, if there is an AP and a STATION, and AP
> is removed, the NIC will not revert back to STATION mode.
> 
> Reported-by: Eliad Peller <eliad@xxxxxxxxxx>
> Signed-off-by: Ben Greear <greearb@xxxxxxxxxxxxxxx>
> ---
> v1 -> v2:  Make setting opmode un-conditional, rename
>     method to:  ath5k_update_bssid_mask_and_opmode
> 
> :100644 100644 dad7265... c9732a6...
> :M	drivers/net/wireless/ath/ath5k/base.c
> 
>  drivers/net/wireless/ath/ath5k/base.c |   66
> ++++++++++++++++++++------------- 1 files changed, 40 insertions(+), 26
> deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath5k/base.c
> b/drivers/net/wireless/ath/ath5k/base.c index dad7265..c9732a6 100644
> --- a/drivers/net/wireless/ath/ath5k/base.c
> +++ b/drivers/net/wireless/ath/ath5k/base.c
> @@ -62,6 +62,7 @@
>  #include "reg.h"
>  #include "debug.h"
>  #include "ani.h"
> +#include "../debug.h"
> 
>  static int modparam_nohwcrypt;
>  module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
> @@ -517,12 +518,14 @@ struct ath_vif_iter_data {
>  	bool		need_set_hw_addr;
>  	bool		found_active;
>  	bool		any_assoc;
> +	enum nl80211_iftype opmode;
>  };
> 
>  static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
>  {
>  	struct ath_vif_iter_data *iter_data = data;
>  	int i;
> +	struct ath5k_vif *avf = (void *)vif->drv_priv;
> 
>  	if (iter_data->hw_macaddr)
>  		for (i = 0; i < ETH_ALEN; i++)
> @@ -539,13 +542,34 @@ static void ath_vif_iter(void *data, u8 *mac, struct
> ieee80211_vif *vif) iter_data->need_set_hw_addr = false;
> 
>  	if (!iter_data->any_assoc) {
> -		struct ath5k_vif *avf = (void *)vif->drv_priv;
>  		if (avf->assoc)
>  			iter_data->any_assoc = true;
>  	}
> +
> +	/* Calculate combined mode - when APs are active, operate in AP mode.
> +	 * Otherwise use the mode of the new interface. This can currently
> +	 * only deal with combinations of APs and STAs. Only one ad-hoc
> +	 * interfaces is allowed above.

the comment reference to "above" does not make sense here any more.

> +	 */
> +	if (avf->opmode == NL80211_IFTYPE_AP)
> +		iter_data->opmode = NL80211_IFTYPE_AP;
> +	else
> +		if (iter_data->opmode == NL80211_IFTYPE_UNSPECIFIED)
> +			iter_data->opmode = avf->opmode;
>  }
> 
> -void ath5k_update_bssid_mask(struct ath5k_softc *sc, struct ieee80211_vif
> *vif) +static void ath_do_set_opmode(struct ath5k_softc *sc)
> +{
> +	struct ath5k_hw *ah = sc->ah;
> +	ath5k_hw_set_opmode(ah, sc->opmode);
> +	ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d (%s)\n",
> +		  sc->opmode,
> +		  ath_opmode_to_string(sc->opmode) ?
> +		  ath_opmode_to_string(sc->opmode) : "UKNOWN");
> +}

what's the point of this function? just to add the debug print? 

> +void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
> +					struct ieee80211_vif *vif)
>  {
>  	struct ath_common *common = ath5k_hw_common(sc->ah);
>  	struct ath_vif_iter_data iter_data;
> @@ -558,6 +582,7 @@ void ath5k_update_bssid_mask(struct ath5k_softc *sc,
> struct ieee80211_vif *vif) memset(&iter_data.mask, 0xff, ETH_ALEN);
>  	iter_data.found_active = false;
>  	iter_data.need_set_hw_addr = true;
> +	iter_data.opmode = NL80211_IFTYPE_UNSPECIFIED;
> 
>  	if (vif)
>  		ath_vif_iter(&iter_data, vif->addr, vif);
> @@ -567,10 +592,18 @@ void ath5k_update_bssid_mask(struct ath5k_softc *sc,
> struct ieee80211_vif *vif) &iter_data);
>  	memcpy(sc->bssidmask, iter_data.mask, ETH_ALEN);
> 
> +	sc->opmode = iter_data.opmode;
> +	if (sc->opmode == NL80211_IFTYPE_UNSPECIFIED)
> +		/* Nothing active, default to station mode */
> +		sc->opmode = NL80211_IFTYPE_STATION;
> +
> +	ath_do_set_opmode(sc);
>  	if (iter_data.need_set_hw_addr && iter_data.found_active)
>  		ath5k_hw_set_lladdr(sc->ah, iter_data.active_mac);
> 
> -	ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
> +	if (ath5k_hw_hasbssidmask(sc->ah))
> +		ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
>  }
> 
>  static void
> @@ -582,15 +615,9 @@ ath5k_mode_setup(struct ath5k_softc *sc, struct
> ieee80211_vif *vif) /* configure rx filter */
>  	rfilt = sc->filter_flags;
>  	ath5k_hw_set_rx_filter(ah, rfilt);
> -
> -	if (ath5k_hw_hasbssidmask(ah))
> -		ath5k_update_bssid_mask(sc, vif);
> -
> -	/* configure operational mode */
> -	ath5k_hw_set_opmode(ah, sc->opmode);
> -
> -	ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d\n", sc->opmode);
>  	ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt);
> +
> +	ath5k_update_bssid_mask_and_opmode(sc, vif);
>  }
> 
>  static inline int
> @@ -2688,7 +2715,7 @@ ath5k_attach(struct pci_dev *pdev, struct
> ieee80211_hw *hw) SET_IEEE80211_PERM_ADDR(hw, mac);
>  	memcpy(&sc->lladdr, mac, ETH_ALEN);
>  	/* All MAC address bits matter for ACKs */
> -	ath5k_update_bssid_mask(sc, NULL);
> +	ath5k_update_bssid_mask_and_opmode(sc, NULL);
> 
>  	regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain;
>  	ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier);
> @@ -2786,7 +2813,6 @@ static int ath5k_add_interface(struct ieee80211_hw
> *hw, {
>  	struct ath5k_softc *sc = hw->priv;
>  	int ret;
> -	struct ath5k_hw *ah = sc->ah;
>  	struct ath5k_vif *avf = (void *)vif->drv_priv;
> 
>  	mutex_lock(&sc->lock);
> @@ -2850,18 +2876,6 @@ static int ath5k_add_interface(struct ieee80211_hw
> *hw, sc->num_adhoc_vifs++;
>  	}
> 
> -	/* Set combined mode - when APs are configured, operate in AP mode.
> -	 * Otherwise use the mode of the new interface. This can currently
> -	 * only deal with combinations of APs and STAs. Only one ad-hoc
> -	 * interfaces is allowed above.
> -	 */
> -	if (sc->num_ap_vifs)
> -		sc->opmode = NL80211_IFTYPE_AP;
> -	else
> -		sc->opmode = vif->type;
> -
> -	ath5k_hw_set_opmode(ah, sc->opmode);
> -

i think it makes sense to set the opmode here. and also do the same in 
ath5k_remove_interface. that way we figure out the opmode when interfaces are 
added/removed.

>  	/* Any MAC address is fine, all others are included through the
>  	 * filter.
>  	 */
> @@ -2905,7 +2919,7 @@ ath5k_remove_interface(struct ieee80211_hw *hw,
>  	else if (avf->opmode == NL80211_IFTYPE_ADHOC)
>  		sc->num_adhoc_vifs--;
> 
> -	ath5k_update_bssid_mask(sc, NULL);
> +	ath5k_update_bssid_mask_and_opmode(sc, NULL);
>  	mutex_unlock(&sc->lock);
>  }

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