aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/main.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c114
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