diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/mac80211-ops.c')
| -rw-r--r-- | drivers/net/wireless/ath/ath5k/mac80211-ops.c | 49 |
1 files changed, 34 insertions, 15 deletions
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 6ed4c0717e3..afb23b3cc7b 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -41,6 +41,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <net/mac80211.h> #include <asm/unaligned.h> @@ -53,17 +55,18 @@ \********************/ static void -ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +ath5k_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, + struct sk_buff *skb) { struct ath5k_hw *ah = hw->priv; u16 qnum = skb_get_queue_mapping(skb); if (WARN_ON(qnum >= ah->ah_capabilities.cap_queues.q_tx_num)) { - dev_kfree_skb_any(skb); + ieee80211_free_txskb(hw, skb); return; } - ath5k_tx_queue(hw, skb, &ah->txqs[qnum]); + ath5k_tx_queue(hw, skb, &ah->txqs[qnum], control); } @@ -134,6 +137,8 @@ ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) ah->num_ap_vifs++; else if (avf->opmode == NL80211_IFTYPE_ADHOC) ah->num_adhoc_vifs++; + else if (avf->opmode == NL80211_IFTYPE_MESH_POINT) + ah->num_mesh_vifs++; } /* Any MAC address is fine, all others are included through the @@ -175,6 +180,8 @@ ath5k_remove_interface(struct ieee80211_hw *hw, ah->num_ap_vifs--; else if (avf->opmode == NL80211_IFTYPE_ADHOC) ah->num_adhoc_vifs--; + else if (avf->opmode == NL80211_IFTYPE_MESH_POINT) + ah->num_mesh_vifs--; ath5k_update_bssid_mask_and_opmode(ah, NULL); mutex_unlock(&ah->lock); @@ -195,14 +202,14 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed) mutex_lock(&ah->lock); if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { - ret = ath5k_chan_set(ah, conf->channel); + ret = ath5k_chan_set(ah, &conf->chandef); if (ret < 0) goto unlock; } if ((changed & IEEE80211_CONF_CHANGE_POWER) && - (ah->power_level != conf->power_level)) { - ah->power_level = conf->power_level; + (ah->ah_txpower.txp_requested != conf->power_level)) { + ah->ah_txpower.txp_requested = conf->power_level; /* Half dB steps */ ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2)); @@ -248,7 +255,6 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ath5k_vif *avf = (void *)vif->drv_priv; struct ath5k_hw *ah = hw->priv; struct ath_common *common = ath5k_hw_common(ah); - unsigned long flags; mutex_lock(&ah->lock); @@ -294,9 +300,9 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, } if (changes & BSS_CHANGED_BEACON) { - spin_lock_irqsave(&ah->block, flags); + spin_lock_bh(&ah->block); ath5k_beacon_update(hw, vif); - spin_unlock_irqrestore(&ah->block, flags); + spin_unlock_bh(&ah->block); } if (changes & BSS_CHANGED_BEACON_ENABLED) @@ -319,7 +325,7 @@ ath5k_prepare_multicast(struct ieee80211_hw *hw, struct netdev_hw_addr *ha; mfilt[0] = 0; - mfilt[1] = 1; + mfilt[1] = 0; netdev_hw_addr_list_for_each(ha, mc_list) { /* calculate XOR of eight 6-bit values */ @@ -446,8 +452,9 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, iter_data.hw_macaddr = NULL; iter_data.n_stas = 0; iter_data.need_set_hw_addr = false; - ieee80211_iterate_active_interfaces_atomic(ah->hw, ath5k_vif_iter, - &iter_data); + ieee80211_iterate_active_interfaces_atomic( + ah->hw, IEEE80211_IFACE_ITER_RESUME_ALL, + ath5k_vif_iter, &iter_data); /* Set up RX Filter */ if (iter_data.n_stas > 1) { @@ -483,6 +490,17 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (ath5k_modparam_nohwcrypt) return -EOPNOTSUPP; + if (key->flags & IEEE80211_KEY_FLAG_RX_MGMT) + return -EOPNOTSUPP; + + if (vif->type == NL80211_IFTYPE_ADHOC && + (key->cipher == WLAN_CIPHER_SUITE_TKIP || + key->cipher == WLAN_CIPHER_SUITE_CCMP) && + !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { + /* don't program group keys when using IBSS_RSN */ + return -EOPNOTSUPP; + } + switch (key->cipher) { case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: @@ -509,7 +527,7 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (key->cipher == WLAN_CIPHER_SUITE_TKIP) key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; if (key->cipher == WLAN_CIPHER_SUITE_CCMP) - key->flags |= IEEE80211_KEY_FLAG_SW_MGMT; + key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; ret = 0; } break; @@ -580,7 +598,7 @@ ath5k_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, qi.tqi_aifs = params->aifs; qi.tqi_cw_min = params->cw_min; qi.tqi_cw_max = params->cw_max; - qi.tqi_burst_time = params->txop; + qi.tqi_burst_time = params->txop * 32; ATH5K_DBG(ah, ATH5K_DEBUG_ANY, "Configure tx [queue %d], " @@ -660,9 +678,10 @@ ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey) memcpy(survey, &ah->survey, sizeof(*survey)); - survey->channel = conf->channel; + survey->channel = conf->chandef.chan; survey->noise = ah->ah_noise_floor; survey->filled = SURVEY_INFO_NOISE_DBM | + SURVEY_INFO_IN_USE | SURVEY_INFO_CHANNEL_TIME | SURVEY_INFO_CHANNEL_TIME_BUSY | SURVEY_INFO_CHANNEL_TIME_RX | |
