diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/main.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 114 |
1 files changed, 37 insertions, 77 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 3c02b977a613..3229c3993568 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -2956,90 +2956,62 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2956 | struct ath_hw *ah = sc->sc_ah; | 2956 | struct ath_hw *ah = sc->sc_ah; |
2957 | struct ath_common *common = ath9k_hw_common(ah); | 2957 | struct ath_common *common = ath9k_hw_common(ah); |
2958 | struct ath_vif *avp = (void *)vif->drv_priv; | 2958 | struct ath_vif *avp = (void *)vif->drv_priv; |
2959 | u32 rfilt = 0; | 2959 | int error; |
2960 | int error, i; | ||
2961 | 2960 | ||
2962 | mutex_lock(&sc->mutex); | 2961 | mutex_lock(&sc->mutex); |
2963 | 2962 | ||
2964 | /* | 2963 | if (changed & BSS_CHANGED_BSSID) { |
2965 | * TODO: Need to decide which hw opmode to use for | 2964 | /* Set BSSID */ |
2966 | * multi-interface cases | 2965 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); |
2967 | * XXX: This belongs into add_interface! | 2966 | memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN); |
2968 | */ | ||
2969 | if (vif->type == NL80211_IFTYPE_AP && | ||
2970 | ah->opmode != NL80211_IFTYPE_AP) { | ||
2971 | ah->opmode = NL80211_IFTYPE_STATION; | ||
2972 | ath9k_hw_setopmode(ah); | ||
2973 | memcpy(common->curbssid, common->macaddr, ETH_ALEN); | ||
2974 | common->curaid = 0; | 2967 | common->curaid = 0; |
2975 | ath9k_hw_write_associd(ah); | 2968 | ath9k_hw_write_associd(ah); |
2976 | /* Request full reset to get hw opmode changed properly */ | ||
2977 | sc->sc_flags |= SC_OP_FULL_RESET; | ||
2978 | } | ||
2979 | 2969 | ||
2980 | if ((changed & BSS_CHANGED_BSSID) && | 2970 | /* Set aggregation protection mode parameters */ |
2981 | !is_zero_ether_addr(bss_conf->bssid)) { | 2971 | sc->config.ath_aggr_prot = 0; |
2982 | switch (vif->type) { | ||
2983 | case NL80211_IFTYPE_STATION: | ||
2984 | case NL80211_IFTYPE_ADHOC: | ||
2985 | case NL80211_IFTYPE_MESH_POINT: | ||
2986 | /* Set BSSID */ | ||
2987 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); | ||
2988 | memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN); | ||
2989 | common->curaid = 0; | ||
2990 | ath9k_hw_write_associd(ah); | ||
2991 | 2972 | ||
2992 | /* Set aggregation protection mode parameters */ | 2973 | /* Only legacy IBSS for now */ |
2993 | sc->config.ath_aggr_prot = 0; | 2974 | if (vif->type == NL80211_IFTYPE_ADHOC) |
2975 | ath_update_chainmask(sc, 0); | ||
2994 | 2976 | ||
2995 | ath_print(common, ATH_DBG_CONFIG, | 2977 | ath_print(common, ATH_DBG_CONFIG, |
2996 | "RX filter 0x%x bssid %pM aid 0x%x\n", | 2978 | "BSSID: %pM aid: 0x%x\n", |
2997 | rfilt, common->curbssid, common->curaid); | 2979 | common->curbssid, common->curaid); |
2998 | 2980 | ||
2999 | /* need to reconfigure the beacon */ | 2981 | /* need to reconfigure the beacon */ |
3000 | sc->sc_flags &= ~SC_OP_BEACONS ; | 2982 | sc->sc_flags &= ~SC_OP_BEACONS ; |
2983 | } | ||
3001 | 2984 | ||
3002 | break; | 2985 | /* Enable transmission of beacons (AP, IBSS, MESH) */ |
3003 | default: | 2986 | if ((changed & BSS_CHANGED_BEACON) || |
3004 | break; | 2987 | ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon)) { |
3005 | } | 2988 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); |
2989 | error = ath_beacon_alloc(aphy, vif); | ||
2990 | if (!error) | ||
2991 | ath_beacon_config(sc, vif); | ||
3006 | } | 2992 | } |
3007 | 2993 | ||
3008 | if ((vif->type == NL80211_IFTYPE_ADHOC) || | 2994 | /* Disable transmission of beacons */ |
3009 | (vif->type == NL80211_IFTYPE_AP) || | 2995 | if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) |
3010 | (vif->type == NL80211_IFTYPE_MESH_POINT)) { | 2996 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); |
3011 | if ((changed & BSS_CHANGED_BEACON) || | ||
3012 | (changed & BSS_CHANGED_BEACON_ENABLED && | ||
3013 | bss_conf->enable_beacon)) { | ||
3014 | /* | ||
3015 | * Allocate and setup the beacon frame. | ||
3016 | * | ||
3017 | * Stop any previous beacon DMA. This may be | ||
3018 | * necessary, for example, when an ibss merge | ||
3019 | * causes reconfiguration; we may be called | ||
3020 | * with beacon transmission active. | ||
3021 | */ | ||
3022 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | ||
3023 | 2997 | ||
2998 | if (changed & BSS_CHANGED_BEACON_INT) { | ||
2999 | sc->beacon_interval = bss_conf->beacon_int; | ||
3000 | /* | ||
3001 | * In case of AP mode, the HW TSF has to be reset | ||
3002 | * when the beacon interval changes. | ||
3003 | */ | ||
3004 | if (vif->type == NL80211_IFTYPE_AP) { | ||
3005 | sc->sc_flags |= SC_OP_TSF_RESET; | ||
3006 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | ||
3024 | error = ath_beacon_alloc(aphy, vif); | 3007 | error = ath_beacon_alloc(aphy, vif); |
3025 | if (!error) | 3008 | if (!error) |
3026 | ath_beacon_config(sc, vif); | 3009 | ath_beacon_config(sc, vif); |
3010 | } else { | ||
3011 | ath_beacon_config(sc, vif); | ||
3027 | } | 3012 | } |
3028 | } | 3013 | } |
3029 | 3014 | ||
3030 | /* Check for WLAN_CAPABILITY_PRIVACY ? */ | ||
3031 | if ((avp->av_opmode != NL80211_IFTYPE_STATION)) { | ||
3032 | for (i = 0; i < IEEE80211_WEP_NKID; i++) | ||
3033 | if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i)) | ||
3034 | ath9k_hw_keysetmac(sc->sc_ah, | ||
3035 | (u16)i, | ||
3036 | common->curbssid); | ||
3037 | } | ||
3038 | |||
3039 | /* Only legacy IBSS for now */ | ||
3040 | if (vif->type == NL80211_IFTYPE_ADHOC) | ||
3041 | ath_update_chainmask(sc, 0); | ||
3042 | |||
3043 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { | 3015 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { |
3044 | ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", | 3016 | ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", |
3045 | bss_conf->use_short_preamble); | 3017 | bss_conf->use_short_preamble); |
@@ -3065,18 +3037,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
3065 | ath9k_bss_assoc_info(sc, vif, bss_conf); | 3037 | ath9k_bss_assoc_info(sc, vif, bss_conf); |
3066 | } | 3038 | } |
3067 | 3039 | ||
3068 | /* | ||
3069 | * The HW TSF has to be reset when the beacon interval changes. | ||
3070 | * We set the flag here, and ath_beacon_config_ap() would take this | ||
3071 | * into account when it gets called through the subsequent | ||
3072 | * config_interface() call - with IFCC_BEACON in the changed field. | ||
3073 | */ | ||
3074 | |||
3075 | if (changed & BSS_CHANGED_BEACON_INT) { | ||
3076 | sc->sc_flags |= SC_OP_TSF_RESET; | ||
3077 | sc->beacon_interval = bss_conf->beacon_int; | ||
3078 | } | ||
3079 | |||
3080 | mutex_unlock(&sc->mutex); | 3040 | mutex_unlock(&sc->mutex); |
3081 | } | 3041 | } |
3082 | 3042 | ||