diff options
Diffstat (limited to 'drivers/net/wireless/ath/ar9170/main.c')
-rw-r--r-- | drivers/net/wireless/ath/ar9170/main.c | 50 |
1 files changed, 31 insertions, 19 deletions
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index c1f8c69db165..f9d6db8d013e 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c | |||
@@ -414,9 +414,9 @@ static void ar9170_tx_ampdu_callback(struct ar9170 *ar, struct sk_buff *skb) | |||
414 | 414 | ||
415 | skb_queue_tail(&ar->tx_status_ampdu, skb); | 415 | skb_queue_tail(&ar->tx_status_ampdu, skb); |
416 | ar9170_tx_fake_ampdu_status(ar); | 416 | ar9170_tx_fake_ampdu_status(ar); |
417 | ar->tx_ampdu_pending--; | ||
418 | 417 | ||
419 | if (!list_empty(&ar->tx_ampdu_list) && !ar->tx_ampdu_pending) | 418 | if (atomic_dec_and_test(&ar->tx_ampdu_pending) && |
419 | !list_empty(&ar->tx_ampdu_list)) | ||
420 | ar9170_tx_ampdu(ar); | 420 | ar9170_tx_ampdu(ar); |
421 | } | 421 | } |
422 | 422 | ||
@@ -850,6 +850,7 @@ static int ar9170_rx_mac_status(struct ar9170 *ar, | |||
850 | } | 850 | } |
851 | break; | 851 | break; |
852 | 852 | ||
853 | case AR9170_RX_STATUS_MODULATION_DUPOFDM: | ||
853 | case AR9170_RX_STATUS_MODULATION_OFDM: | 854 | case AR9170_RX_STATUS_MODULATION_OFDM: |
854 | switch (head->plcp[0] & 0xf) { | 855 | switch (head->plcp[0] & 0xf) { |
855 | case 0xb: | 856 | case 0xb: |
@@ -897,8 +898,7 @@ static int ar9170_rx_mac_status(struct ar9170 *ar, | |||
897 | status->flag |= RX_FLAG_HT; | 898 | status->flag |= RX_FLAG_HT; |
898 | break; | 899 | break; |
899 | 900 | ||
900 | case AR9170_RX_STATUS_MODULATION_DUPOFDM: | 901 | default: |
901 | /* XXX */ | ||
902 | if (ar9170_nag_limiter(ar)) | 902 | if (ar9170_nag_limiter(ar)) |
903 | printk(KERN_ERR "%s: invalid modulation\n", | 903 | printk(KERN_ERR "%s: invalid modulation\n", |
904 | wiphy_name(ar->hw->wiphy)); | 904 | wiphy_name(ar->hw->wiphy)); |
@@ -1248,6 +1248,7 @@ static int ar9170_op_start(struct ieee80211_hw *hw) | |||
1248 | ar->global_ampdu_density = 6; | 1248 | ar->global_ampdu_density = 6; |
1249 | ar->global_ampdu_factor = 3; | 1249 | ar->global_ampdu_factor = 3; |
1250 | 1250 | ||
1251 | atomic_set(&ar->tx_ampdu_pending, 0); | ||
1251 | ar->bad_hw_nagger = jiffies; | 1252 | ar->bad_hw_nagger = jiffies; |
1252 | 1253 | ||
1253 | err = ar->open(ar); | 1254 | err = ar->open(ar); |
@@ -1773,7 +1774,7 @@ static void ar9170_tx(struct ar9170 *ar) | |||
1773 | msecs_to_jiffies(AR9170_TX_TIMEOUT); | 1774 | msecs_to_jiffies(AR9170_TX_TIMEOUT); |
1774 | 1775 | ||
1775 | if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK) | 1776 | if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK) |
1776 | ar->tx_ampdu_pending++; | 1777 | atomic_inc(&ar->tx_ampdu_pending); |
1777 | 1778 | ||
1778 | #ifdef AR9170_QUEUE_DEBUG | 1779 | #ifdef AR9170_QUEUE_DEBUG |
1779 | printk(KERN_DEBUG "%s: send frame q:%d =>\n", | 1780 | printk(KERN_DEBUG "%s: send frame q:%d =>\n", |
@@ -1784,7 +1785,7 @@ static void ar9170_tx(struct ar9170 *ar) | |||
1784 | err = ar->tx(ar, skb); | 1785 | err = ar->tx(ar, skb); |
1785 | if (unlikely(err)) { | 1786 | if (unlikely(err)) { |
1786 | if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK) | 1787 | if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK) |
1787 | ar->tx_ampdu_pending--; | 1788 | atomic_dec(&ar->tx_ampdu_pending); |
1788 | 1789 | ||
1789 | frames_failed++; | 1790 | frames_failed++; |
1790 | dev_kfree_skb_any(skb); | 1791 | dev_kfree_skb_any(skb); |
@@ -1931,7 +1932,7 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1931 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { | 1932 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { |
1932 | bool run = ar9170_tx_ampdu_queue(ar, skb); | 1933 | bool run = ar9170_tx_ampdu_queue(ar, skb); |
1933 | 1934 | ||
1934 | if (run || !ar->tx_ampdu_pending) | 1935 | if (run || !atomic_read(&ar->tx_ampdu_pending)) |
1935 | ar9170_tx_ampdu(ar); | 1936 | ar9170_tx_ampdu(ar); |
1936 | } else { | 1937 | } else { |
1937 | unsigned int queue = skb_get_queue_mapping(skb); | 1938 | unsigned int queue = skb_get_queue_mapping(skb); |
@@ -1952,6 +1953,7 @@ static int ar9170_op_add_interface(struct ieee80211_hw *hw, | |||
1952 | struct ieee80211_if_init_conf *conf) | 1953 | struct ieee80211_if_init_conf *conf) |
1953 | { | 1954 | { |
1954 | struct ar9170 *ar = hw->priv; | 1955 | struct ar9170 *ar = hw->priv; |
1956 | struct ath_common *common = &ar->common; | ||
1955 | int err = 0; | 1957 | int err = 0; |
1956 | 1958 | ||
1957 | mutex_lock(&ar->mutex); | 1959 | mutex_lock(&ar->mutex); |
@@ -1962,7 +1964,7 @@ static int ar9170_op_add_interface(struct ieee80211_hw *hw, | |||
1962 | } | 1964 | } |
1963 | 1965 | ||
1964 | ar->vif = conf->vif; | 1966 | ar->vif = conf->vif; |
1965 | memcpy(ar->mac_addr, conf->mac_addr, ETH_ALEN); | 1967 | memcpy(common->macaddr, conf->mac_addr, ETH_ALEN); |
1966 | 1968 | ||
1967 | if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) { | 1969 | if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) { |
1968 | ar->rx_software_decryption = true; | 1970 | ar->rx_software_decryption = true; |
@@ -2131,12 +2133,13 @@ static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw, | |||
2131 | u32 changed) | 2133 | u32 changed) |
2132 | { | 2134 | { |
2133 | struct ar9170 *ar = hw->priv; | 2135 | struct ar9170 *ar = hw->priv; |
2136 | struct ath_common *common = &ar->common; | ||
2134 | int err = 0; | 2137 | int err = 0; |
2135 | 2138 | ||
2136 | mutex_lock(&ar->mutex); | 2139 | mutex_lock(&ar->mutex); |
2137 | 2140 | ||
2138 | if (changed & BSS_CHANGED_BSSID) { | 2141 | if (changed & BSS_CHANGED_BSSID) { |
2139 | memcpy(ar->bssid, bss_conf->bssid, ETH_ALEN); | 2142 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); |
2140 | err = ar9170_set_operating_mode(ar); | 2143 | err = ar9170_set_operating_mode(ar); |
2141 | if (err) | 2144 | if (err) |
2142 | goto out; | 2145 | goto out; |
@@ -2190,22 +2193,30 @@ static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw) | |||
2190 | { | 2193 | { |
2191 | struct ar9170 *ar = hw->priv; | 2194 | struct ar9170 *ar = hw->priv; |
2192 | int err; | 2195 | int err; |
2193 | u32 tsf_low; | ||
2194 | u32 tsf_high; | ||
2195 | u64 tsf; | 2196 | u64 tsf; |
2197 | #define NR 3 | ||
2198 | static const u32 addr[NR] = { AR9170_MAC_REG_TSF_H, | ||
2199 | AR9170_MAC_REG_TSF_L, | ||
2200 | AR9170_MAC_REG_TSF_H }; | ||
2201 | u32 val[NR]; | ||
2202 | int loops = 0; | ||
2196 | 2203 | ||
2197 | mutex_lock(&ar->mutex); | 2204 | mutex_lock(&ar->mutex); |
2198 | err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_L, &tsf_low); | 2205 | |
2199 | if (!err) | 2206 | while (loops++ < 10) { |
2200 | err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_H, &tsf_high); | 2207 | err = ar9170_read_mreg(ar, NR, addr, val); |
2208 | if (err || val[0] == val[2]) | ||
2209 | break; | ||
2210 | } | ||
2211 | |||
2201 | mutex_unlock(&ar->mutex); | 2212 | mutex_unlock(&ar->mutex); |
2202 | 2213 | ||
2203 | if (WARN_ON(err)) | 2214 | if (WARN_ON(err)) |
2204 | return 0; | 2215 | return 0; |
2205 | 2216 | tsf = val[0]; | |
2206 | tsf = tsf_high; | 2217 | tsf = (tsf << 32) | val[1]; |
2207 | tsf = (tsf << 32) | tsf_low; | ||
2208 | return tsf; | 2218 | return tsf; |
2219 | #undef NR | ||
2209 | } | 2220 | } |
2210 | 2221 | ||
2211 | static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 2222 | static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
@@ -2430,6 +2441,7 @@ static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue, | |||
2430 | } | 2441 | } |
2431 | 2442 | ||
2432 | static int ar9170_ampdu_action(struct ieee80211_hw *hw, | 2443 | static int ar9170_ampdu_action(struct ieee80211_hw *hw, |
2444 | struct ieee80211_vif *vif, | ||
2433 | enum ieee80211_ampdu_mlme_action action, | 2445 | enum ieee80211_ampdu_mlme_action action, |
2434 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) | 2446 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) |
2435 | { | 2447 | { |
@@ -2459,7 +2471,7 @@ static int ar9170_ampdu_action(struct ieee80211_hw *hw, | |||
2459 | tid_info->state = AR9170_TID_STATE_PROGRESS; | 2471 | tid_info->state = AR9170_TID_STATE_PROGRESS; |
2460 | tid_info->active = false; | 2472 | tid_info->active = false; |
2461 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); | 2473 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); |
2462 | ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid); | 2474 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
2463 | break; | 2475 | break; |
2464 | 2476 | ||
2465 | case IEEE80211_AMPDU_TX_STOP: | 2477 | case IEEE80211_AMPDU_TX_STOP: |
@@ -2469,7 +2481,7 @@ static int ar9170_ampdu_action(struct ieee80211_hw *hw, | |||
2469 | tid_info->active = false; | 2481 | tid_info->active = false; |
2470 | skb_queue_purge(&tid_info->queue); | 2482 | skb_queue_purge(&tid_info->queue); |
2471 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); | 2483 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); |
2472 | ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid); | 2484 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
2473 | break; | 2485 | break; |
2474 | 2486 | ||
2475 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 2487 | case IEEE80211_AMPDU_TX_OPERATIONAL: |