diff options
Diffstat (limited to 'drivers/net/wireless/ath')
36 files changed, 2274 insertions, 1826 deletions
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h index 9f9459860d8..8c8ce67971e 100644 --- a/drivers/net/wireless/ath/ar9170/ar9170.h +++ b/drivers/net/wireless/ath/ar9170/ar9170.h | |||
@@ -109,7 +109,6 @@ struct ar9170_rxstream_mpdu_merge { | |||
109 | bool has_plcp; | 109 | bool has_plcp; |
110 | }; | 110 | }; |
111 | 111 | ||
112 | #define AR9170_NUM_MAX_BA_RETRY 5 | ||
113 | #define AR9170_NUM_TID 16 | 112 | #define AR9170_NUM_TID 16 |
114 | #define WME_BA_BMP_SIZE 64 | 113 | #define WME_BA_BMP_SIZE 64 |
115 | #define AR9170_NUM_MAX_AGG_LEN (2 * WME_BA_BMP_SIZE) | 114 | #define AR9170_NUM_MAX_AGG_LEN (2 * WME_BA_BMP_SIZE) |
@@ -143,7 +142,12 @@ struct ar9170_sta_tid { | |||
143 | u16 tid; | 142 | u16 tid; |
144 | enum ar9170_tid_state state; | 143 | enum ar9170_tid_state state; |
145 | bool active; | 144 | bool active; |
146 | u8 retry; | 145 | }; |
146 | |||
147 | struct ar9170_tx_queue_stats { | ||
148 | unsigned int len; | ||
149 | unsigned int limit; | ||
150 | unsigned int count; | ||
147 | }; | 151 | }; |
148 | 152 | ||
149 | #define AR9170_QUEUE_TIMEOUT 64 | 153 | #define AR9170_QUEUE_TIMEOUT 64 |
@@ -154,6 +158,8 @@ struct ar9170_sta_tid { | |||
154 | 158 | ||
155 | #define AR9170_NUM_TX_STATUS 128 | 159 | #define AR9170_NUM_TX_STATUS 128 |
156 | #define AR9170_NUM_TX_AGG_MAX 30 | 160 | #define AR9170_NUM_TX_AGG_MAX 30 |
161 | #define AR9170_NUM_TX_LIMIT_HARD AR9170_TXQ_DEPTH | ||
162 | #define AR9170_NUM_TX_LIMIT_SOFT (AR9170_TXQ_DEPTH - 10) | ||
157 | 163 | ||
158 | struct ar9170 { | 164 | struct ar9170 { |
159 | struct ieee80211_hw *hw; | 165 | struct ieee80211_hw *hw; |
@@ -211,7 +217,7 @@ struct ar9170 { | |||
211 | 217 | ||
212 | /* qos queue settings */ | 218 | /* qos queue settings */ |
213 | spinlock_t tx_stats_lock; | 219 | spinlock_t tx_stats_lock; |
214 | struct ieee80211_tx_queue_stats tx_stats[5]; | 220 | struct ar9170_tx_queue_stats tx_stats[5]; |
215 | struct ieee80211_tx_queue_params edcf[5]; | 221 | struct ieee80211_tx_queue_params edcf[5]; |
216 | 222 | ||
217 | spinlock_t cmdlock; | 223 | spinlock_t cmdlock; |
@@ -248,13 +254,8 @@ struct ar9170_sta_info { | |||
248 | unsigned int ampdu_max_len; | 254 | unsigned int ampdu_max_len; |
249 | }; | 255 | }; |
250 | 256 | ||
251 | #define AR9170_TX_FLAG_WAIT_FOR_ACK BIT(0) | ||
252 | #define AR9170_TX_FLAG_NO_ACK BIT(1) | ||
253 | #define AR9170_TX_FLAG_BLOCK_ACK BIT(2) | ||
254 | |||
255 | struct ar9170_tx_info { | 257 | struct ar9170_tx_info { |
256 | unsigned long timeout; | 258 | unsigned long timeout; |
257 | unsigned int flags; | ||
258 | }; | 259 | }; |
259 | 260 | ||
260 | #define IS_STARTED(a) (((struct ar9170 *)a)->state >= AR9170_STARTED) | 261 | #define IS_STARTED(a) (((struct ar9170 *)a)->state >= AR9170_STARTED) |
diff --git a/drivers/net/wireless/ath/ar9170/hw.h b/drivers/net/wireless/ath/ar9170/hw.h index 701ddb7d840..0a1d4c28e68 100644 --- a/drivers/net/wireless/ath/ar9170/hw.h +++ b/drivers/net/wireless/ath/ar9170/hw.h | |||
@@ -276,6 +276,7 @@ struct ar9170_tx_control { | |||
276 | #define AR9170_TX_MAC_RATE_PROBE 0x8000 | 276 | #define AR9170_TX_MAC_RATE_PROBE 0x8000 |
277 | 277 | ||
278 | /* either-or */ | 278 | /* either-or */ |
279 | #define AR9170_TX_PHY_MOD_MASK 0x00000003 | ||
279 | #define AR9170_TX_PHY_MOD_CCK 0x00000000 | 280 | #define AR9170_TX_PHY_MOD_CCK 0x00000000 |
280 | #define AR9170_TX_PHY_MOD_OFDM 0x00000001 | 281 | #define AR9170_TX_PHY_MOD_OFDM 0x00000001 |
281 | #define AR9170_TX_PHY_MOD_HT 0x00000002 | 282 | #define AR9170_TX_PHY_MOD_HT 0x00000002 |
diff --git a/drivers/net/wireless/ath/ar9170/mac.c b/drivers/net/wireless/ath/ar9170/mac.c index ddc8c09dc79..857e8610429 100644 --- a/drivers/net/wireless/ath/ar9170/mac.c +++ b/drivers/net/wireless/ath/ar9170/mac.c | |||
@@ -117,7 +117,7 @@ int ar9170_set_qos(struct ar9170 *ar) | |||
117 | ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP, | 117 | ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP, |
118 | ar->edcf[0].txop | ar->edcf[1].txop << 16); | 118 | ar->edcf[0].txop | ar->edcf[1].txop << 16); |
119 | ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP, | 119 | ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP, |
120 | ar->edcf[1].txop | ar->edcf[3].txop << 16); | 120 | ar->edcf[2].txop | ar->edcf[3].txop << 16); |
121 | 121 | ||
122 | ar9170_regwrite_finish(); | 122 | ar9170_regwrite_finish(); |
123 | 123 | ||
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index f9d6db8d013..8a964f13036 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c | |||
@@ -194,12 +194,15 @@ static inline u16 ar9170_get_seq(struct sk_buff *skb) | |||
194 | return ar9170_get_seq_h((void *) txc->frame_data); | 194 | return ar9170_get_seq_h((void *) txc->frame_data); |
195 | } | 195 | } |
196 | 196 | ||
197 | static inline u16 ar9170_get_tid_h(struct ieee80211_hdr *hdr) | ||
198 | { | ||
199 | return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK; | ||
200 | } | ||
201 | |||
197 | static inline u16 ar9170_get_tid(struct sk_buff *skb) | 202 | static inline u16 ar9170_get_tid(struct sk_buff *skb) |
198 | { | 203 | { |
199 | struct ar9170_tx_control *txc = (void *) skb->data; | 204 | struct ar9170_tx_control *txc = (void *) skb->data; |
200 | struct ieee80211_hdr *hdr = (void *) txc->frame_data; | 205 | return ar9170_get_tid_h((struct ieee80211_hdr *) txc->frame_data); |
201 | |||
202 | return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK; | ||
203 | } | 206 | } |
204 | 207 | ||
205 | #define GET_NEXT_SEQ(seq) ((seq + 1) & 0x0fff) | 208 | #define GET_NEXT_SEQ(seq) ((seq + 1) & 0x0fff) |
@@ -213,10 +216,10 @@ static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb) | |||
213 | struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data; | 216 | struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data; |
214 | struct ieee80211_hdr *hdr = (void *) txc->frame_data; | 217 | struct ieee80211_hdr *hdr = (void *) txc->frame_data; |
215 | 218 | ||
216 | printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] flags:%x s:%d " | 219 | printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] s:%d " |
217 | "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n", | 220 | "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n", |
218 | wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb), | 221 | wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb), |
219 | ieee80211_get_DA(hdr), arinfo->flags, ar9170_get_seq_h(hdr), | 222 | ieee80211_get_DA(hdr), ar9170_get_seq_h(hdr), |
220 | le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control), | 223 | le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control), |
221 | jiffies_to_msecs(arinfo->timeout - jiffies)); | 224 | jiffies_to_msecs(arinfo->timeout - jiffies)); |
222 | } | 225 | } |
@@ -430,7 +433,7 @@ void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb) | |||
430 | spin_lock_irqsave(&ar->tx_stats_lock, flags); | 433 | spin_lock_irqsave(&ar->tx_stats_lock, flags); |
431 | ar->tx_stats[queue].len--; | 434 | ar->tx_stats[queue].len--; |
432 | 435 | ||
433 | if (skb_queue_empty(&ar->tx_pending[queue])) { | 436 | if (ar->tx_stats[queue].len < AR9170_NUM_TX_LIMIT_SOFT) { |
434 | #ifdef AR9170_QUEUE_STOP_DEBUG | 437 | #ifdef AR9170_QUEUE_STOP_DEBUG |
435 | printk(KERN_DEBUG "%s: wake queue %d\n", | 438 | printk(KERN_DEBUG "%s: wake queue %d\n", |
436 | wiphy_name(ar->hw->wiphy), queue); | 439 | wiphy_name(ar->hw->wiphy), queue); |
@@ -440,22 +443,17 @@ void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb) | |||
440 | } | 443 | } |
441 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | 444 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); |
442 | 445 | ||
443 | if (arinfo->flags & AR9170_TX_FLAG_BLOCK_ACK) { | 446 | if (info->flags & IEEE80211_TX_CTL_NO_ACK) { |
444 | ar9170_tx_ampdu_callback(ar, skb); | ||
445 | } else if (arinfo->flags & AR9170_TX_FLAG_WAIT_FOR_ACK) { | ||
446 | arinfo->timeout = jiffies + | ||
447 | msecs_to_jiffies(AR9170_TX_TIMEOUT); | ||
448 | |||
449 | skb_queue_tail(&ar->tx_status[queue], skb); | ||
450 | } else if (arinfo->flags & AR9170_TX_FLAG_NO_ACK) { | ||
451 | ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED); | 447 | ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED); |
452 | } else { | 448 | } else { |
453 | #ifdef AR9170_QUEUE_DEBUG | 449 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { |
454 | printk(KERN_DEBUG "%s: unsupported frame flags!\n", | 450 | ar9170_tx_ampdu_callback(ar, skb); |
455 | wiphy_name(ar->hw->wiphy)); | 451 | } else { |
456 | ar9170_print_txheader(ar, skb); | 452 | arinfo->timeout = jiffies + |
457 | #endif /* AR9170_QUEUE_DEBUG */ | 453 | msecs_to_jiffies(AR9170_TX_TIMEOUT); |
458 | dev_kfree_skb_any(skb); | 454 | |
455 | skb_queue_tail(&ar->tx_status[queue], skb); | ||
456 | } | ||
459 | } | 457 | } |
460 | 458 | ||
461 | if (!ar->tx_stats[queue].len && | 459 | if (!ar->tx_stats[queue].len && |
@@ -1407,17 +1405,6 @@ static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) | |||
1407 | 1405 | ||
1408 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && | 1406 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && |
1409 | (is_valid_ether_addr(ieee80211_get_DA(hdr)))) { | 1407 | (is_valid_ether_addr(ieee80211_get_DA(hdr)))) { |
1410 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { | ||
1411 | if (unlikely(!info->control.sta)) | ||
1412 | goto err_out; | ||
1413 | |||
1414 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR); | ||
1415 | arinfo->flags = AR9170_TX_FLAG_BLOCK_ACK; | ||
1416 | |||
1417 | goto out; | ||
1418 | } | ||
1419 | |||
1420 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE); | ||
1421 | /* | 1408 | /* |
1422 | * WARNING: | 1409 | * WARNING: |
1423 | * Putting the QoS queue bits into an unexplored territory is | 1410 | * Putting the QoS queue bits into an unexplored territory is |
@@ -1431,12 +1418,17 @@ static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) | |||
1431 | 1418 | ||
1432 | txc->phy_control |= | 1419 | txc->phy_control |= |
1433 | cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT); | 1420 | cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT); |
1434 | arinfo->flags = AR9170_TX_FLAG_WAIT_FOR_ACK; | 1421 | |
1435 | } else { | 1422 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { |
1436 | arinfo->flags = AR9170_TX_FLAG_NO_ACK; | 1423 | if (unlikely(!info->control.sta)) |
1424 | goto err_out; | ||
1425 | |||
1426 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR); | ||
1427 | } else { | ||
1428 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE); | ||
1429 | } | ||
1437 | } | 1430 | } |
1438 | 1431 | ||
1439 | out: | ||
1440 | return 0; | 1432 | return 0; |
1441 | 1433 | ||
1442 | err_out: | 1434 | err_out: |
@@ -1671,8 +1663,7 @@ static bool ar9170_tx_ampdu(struct ar9170 *ar) | |||
1671 | * tell the FW/HW that this is the last frame, | 1663 | * tell the FW/HW that this is the last frame, |
1672 | * that way it will wait for the immediate block ack. | 1664 | * that way it will wait for the immediate block ack. |
1673 | */ | 1665 | */ |
1674 | if (likely(skb_peek_tail(&agg))) | 1666 | ar9170_tx_indicate_immba(ar, skb_peek_tail(&agg)); |
1675 | ar9170_tx_indicate_immba(ar, skb_peek_tail(&agg)); | ||
1676 | 1667 | ||
1677 | #ifdef AR9170_TXAGG_DEBUG | 1668 | #ifdef AR9170_TXAGG_DEBUG |
1678 | printk(KERN_DEBUG "%s: generated A-MPDU looks like this:\n", | 1669 | printk(KERN_DEBUG "%s: generated A-MPDU looks like this:\n", |
@@ -1716,6 +1707,21 @@ static void ar9170_tx(struct ar9170 *ar) | |||
1716 | 1707 | ||
1717 | for (i = 0; i < __AR9170_NUM_TXQ; i++) { | 1708 | for (i = 0; i < __AR9170_NUM_TXQ; i++) { |
1718 | spin_lock_irqsave(&ar->tx_stats_lock, flags); | 1709 | spin_lock_irqsave(&ar->tx_stats_lock, flags); |
1710 | frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len, | ||
1711 | skb_queue_len(&ar->tx_pending[i])); | ||
1712 | |||
1713 | if (remaining_space < frames) { | ||
1714 | #ifdef AR9170_QUEUE_DEBUG | ||
1715 | printk(KERN_DEBUG "%s: tx quota reached queue:%d, " | ||
1716 | "remaining slots:%d, needed:%d\n", | ||
1717 | wiphy_name(ar->hw->wiphy), i, remaining_space, | ||
1718 | frames); | ||
1719 | #endif /* AR9170_QUEUE_DEBUG */ | ||
1720 | frames = remaining_space; | ||
1721 | } | ||
1722 | |||
1723 | ar->tx_stats[i].len += frames; | ||
1724 | ar->tx_stats[i].count += frames; | ||
1719 | if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) { | 1725 | if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) { |
1720 | #ifdef AR9170_QUEUE_DEBUG | 1726 | #ifdef AR9170_QUEUE_DEBUG |
1721 | printk(KERN_DEBUG "%s: queue %d full\n", | 1727 | printk(KERN_DEBUG "%s: queue %d full\n", |
@@ -1733,25 +1739,8 @@ static void ar9170_tx(struct ar9170 *ar) | |||
1733 | __ar9170_dump_txstats(ar); | 1739 | __ar9170_dump_txstats(ar); |
1734 | #endif /* AR9170_QUEUE_STOP_DEBUG */ | 1740 | #endif /* AR9170_QUEUE_STOP_DEBUG */ |
1735 | ieee80211_stop_queue(ar->hw, i); | 1741 | ieee80211_stop_queue(ar->hw, i); |
1736 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | ||
1737 | continue; | ||
1738 | } | ||
1739 | |||
1740 | frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len, | ||
1741 | skb_queue_len(&ar->tx_pending[i])); | ||
1742 | |||
1743 | if (remaining_space < frames) { | ||
1744 | #ifdef AR9170_QUEUE_DEBUG | ||
1745 | printk(KERN_DEBUG "%s: tx quota reached queue:%d, " | ||
1746 | "remaining slots:%d, needed:%d\n", | ||
1747 | wiphy_name(ar->hw->wiphy), i, remaining_space, | ||
1748 | frames); | ||
1749 | #endif /* AR9170_QUEUE_DEBUG */ | ||
1750 | frames = remaining_space; | ||
1751 | } | 1742 | } |
1752 | 1743 | ||
1753 | ar->tx_stats[i].len += frames; | ||
1754 | ar->tx_stats[i].count += frames; | ||
1755 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | 1744 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); |
1756 | 1745 | ||
1757 | if (!frames) | 1746 | if (!frames) |
@@ -1773,7 +1762,7 @@ static void ar9170_tx(struct ar9170 *ar) | |||
1773 | arinfo->timeout = jiffies + | 1762 | arinfo->timeout = jiffies + |
1774 | msecs_to_jiffies(AR9170_TX_TIMEOUT); | 1763 | msecs_to_jiffies(AR9170_TX_TIMEOUT); |
1775 | 1764 | ||
1776 | if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK) | 1765 | if (info->flags & IEEE80211_TX_CTL_AMPDU) |
1777 | atomic_inc(&ar->tx_ampdu_pending); | 1766 | atomic_inc(&ar->tx_ampdu_pending); |
1778 | 1767 | ||
1779 | #ifdef AR9170_QUEUE_DEBUG | 1768 | #ifdef AR9170_QUEUE_DEBUG |
@@ -1784,7 +1773,7 @@ static void ar9170_tx(struct ar9170 *ar) | |||
1784 | 1773 | ||
1785 | err = ar->tx(ar, skb); | 1774 | err = ar->tx(ar, skb); |
1786 | if (unlikely(err)) { | 1775 | if (unlikely(err)) { |
1787 | if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK) | 1776 | if (info->flags & IEEE80211_TX_CTL_AMPDU) |
1788 | atomic_dec(&ar->tx_ampdu_pending); | 1777 | atomic_dec(&ar->tx_ampdu_pending); |
1789 | 1778 | ||
1790 | frames_failed++; | 1779 | frames_failed++; |
@@ -1950,7 +1939,7 @@ err_free: | |||
1950 | } | 1939 | } |
1951 | 1940 | ||
1952 | static int ar9170_op_add_interface(struct ieee80211_hw *hw, | 1941 | static int ar9170_op_add_interface(struct ieee80211_hw *hw, |
1953 | struct ieee80211_if_init_conf *conf) | 1942 | struct ieee80211_vif *vif) |
1954 | { | 1943 | { |
1955 | struct ar9170 *ar = hw->priv; | 1944 | struct ar9170 *ar = hw->priv; |
1956 | struct ath_common *common = &ar->common; | 1945 | struct ath_common *common = &ar->common; |
@@ -1963,8 +1952,8 @@ static int ar9170_op_add_interface(struct ieee80211_hw *hw, | |||
1963 | goto unlock; | 1952 | goto unlock; |
1964 | } | 1953 | } |
1965 | 1954 | ||
1966 | ar->vif = conf->vif; | 1955 | ar->vif = vif; |
1967 | memcpy(common->macaddr, conf->mac_addr, ETH_ALEN); | 1956 | memcpy(common->macaddr, vif->addr, ETH_ALEN); |
1968 | 1957 | ||
1969 | if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) { | 1958 | if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) { |
1970 | ar->rx_software_decryption = true; | 1959 | ar->rx_software_decryption = true; |
@@ -1984,7 +1973,7 @@ unlock: | |||
1984 | } | 1973 | } |
1985 | 1974 | ||
1986 | static void ar9170_op_remove_interface(struct ieee80211_hw *hw, | 1975 | static void ar9170_op_remove_interface(struct ieee80211_hw *hw, |
1987 | struct ieee80211_if_init_conf *conf) | 1976 | struct ieee80211_vif *vif) |
1988 | { | 1977 | { |
1989 | struct ar9170 *ar = hw->priv; | 1978 | struct ar9170 *ar = hw->priv; |
1990 | 1979 | ||
@@ -2340,55 +2329,55 @@ out: | |||
2340 | return err; | 2329 | return err; |
2341 | } | 2330 | } |
2342 | 2331 | ||
2343 | static void ar9170_sta_notify(struct ieee80211_hw *hw, | 2332 | static int ar9170_sta_add(struct ieee80211_hw *hw, |
2344 | struct ieee80211_vif *vif, | 2333 | struct ieee80211_vif *vif, |
2345 | enum sta_notify_cmd cmd, | 2334 | struct ieee80211_sta *sta) |
2346 | struct ieee80211_sta *sta) | ||
2347 | { | 2335 | { |
2348 | struct ar9170 *ar = hw->priv; | 2336 | struct ar9170 *ar = hw->priv; |
2349 | struct ar9170_sta_info *sta_info = (void *) sta->drv_priv; | 2337 | struct ar9170_sta_info *sta_info = (void *) sta->drv_priv; |
2350 | unsigned int i; | 2338 | unsigned int i; |
2351 | 2339 | ||
2352 | switch (cmd) { | 2340 | memset(sta_info, 0, sizeof(*sta_info)); |
2353 | case STA_NOTIFY_ADD: | ||
2354 | memset(sta_info, 0, sizeof(*sta_info)); | ||
2355 | 2341 | ||
2356 | if (!sta->ht_cap.ht_supported) | 2342 | if (!sta->ht_cap.ht_supported) |
2357 | break; | 2343 | return 0; |
2358 | 2344 | ||
2359 | if (sta->ht_cap.ampdu_density > ar->global_ampdu_density) | 2345 | if (sta->ht_cap.ampdu_density > ar->global_ampdu_density) |
2360 | ar->global_ampdu_density = sta->ht_cap.ampdu_density; | 2346 | ar->global_ampdu_density = sta->ht_cap.ampdu_density; |
2361 | 2347 | ||
2362 | if (sta->ht_cap.ampdu_factor < ar->global_ampdu_factor) | 2348 | if (sta->ht_cap.ampdu_factor < ar->global_ampdu_factor) |
2363 | ar->global_ampdu_factor = sta->ht_cap.ampdu_factor; | 2349 | ar->global_ampdu_factor = sta->ht_cap.ampdu_factor; |
2364 | 2350 | ||
2365 | for (i = 0; i < AR9170_NUM_TID; i++) { | 2351 | for (i = 0; i < AR9170_NUM_TID; i++) { |
2366 | sta_info->agg[i].state = AR9170_TID_STATE_SHUTDOWN; | 2352 | sta_info->agg[i].state = AR9170_TID_STATE_SHUTDOWN; |
2367 | sta_info->agg[i].active = false; | 2353 | sta_info->agg[i].active = false; |
2368 | sta_info->agg[i].ssn = 0; | 2354 | sta_info->agg[i].ssn = 0; |
2369 | sta_info->agg[i].retry = 0; | 2355 | sta_info->agg[i].tid = i; |
2370 | sta_info->agg[i].tid = i; | 2356 | INIT_LIST_HEAD(&sta_info->agg[i].list); |
2371 | INIT_LIST_HEAD(&sta_info->agg[i].list); | 2357 | skb_queue_head_init(&sta_info->agg[i].queue); |
2372 | skb_queue_head_init(&sta_info->agg[i].queue); | 2358 | } |
2373 | } | ||
2374 | 2359 | ||
2375 | sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor); | 2360 | sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor); |
2376 | break; | ||
2377 | 2361 | ||
2378 | case STA_NOTIFY_REMOVE: | 2362 | return 0; |
2379 | if (!sta->ht_cap.ht_supported) | 2363 | } |
2380 | break; | ||
2381 | 2364 | ||
2382 | for (i = 0; i < AR9170_NUM_TID; i++) { | 2365 | static int ar9170_sta_remove(struct ieee80211_hw *hw, |
2383 | sta_info->agg[i].state = AR9170_TID_STATE_INVALID; | 2366 | struct ieee80211_vif *vif, |
2384 | skb_queue_purge(&sta_info->agg[i].queue); | 2367 | struct ieee80211_sta *sta) |
2385 | } | 2368 | { |
2369 | struct ar9170_sta_info *sta_info = (void *) sta->drv_priv; | ||
2370 | unsigned int i; | ||
2386 | 2371 | ||
2387 | break; | 2372 | if (!sta->ht_cap.ht_supported) |
2373 | return 0; | ||
2388 | 2374 | ||
2389 | default: | 2375 | for (i = 0; i < AR9170_NUM_TID; i++) { |
2390 | break; | 2376 | sta_info->agg[i].state = AR9170_TID_STATE_INVALID; |
2377 | skb_queue_purge(&sta_info->agg[i].queue); | ||
2391 | } | 2378 | } |
2379 | |||
2380 | return 0; | ||
2392 | } | 2381 | } |
2393 | 2382 | ||
2394 | static int ar9170_get_stats(struct ieee80211_hw *hw, | 2383 | static int ar9170_get_stats(struct ieee80211_hw *hw, |
@@ -2408,18 +2397,6 @@ static int ar9170_get_stats(struct ieee80211_hw *hw, | |||
2408 | return 0; | 2397 | return 0; |
2409 | } | 2398 | } |
2410 | 2399 | ||
2411 | static int ar9170_get_tx_stats(struct ieee80211_hw *hw, | ||
2412 | struct ieee80211_tx_queue_stats *tx_stats) | ||
2413 | { | ||
2414 | struct ar9170 *ar = hw->priv; | ||
2415 | |||
2416 | spin_lock_bh(&ar->tx_stats_lock); | ||
2417 | memcpy(tx_stats, ar->tx_stats, sizeof(tx_stats[0]) * hw->queues); | ||
2418 | spin_unlock_bh(&ar->tx_stats_lock); | ||
2419 | |||
2420 | return 0; | ||
2421 | } | ||
2422 | |||
2423 | static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue, | 2400 | static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue, |
2424 | const struct ieee80211_tx_queue_params *param) | 2401 | const struct ieee80211_tx_queue_params *param) |
2425 | { | 2402 | { |
@@ -2519,9 +2496,9 @@ static const struct ieee80211_ops ar9170_ops = { | |||
2519 | .bss_info_changed = ar9170_op_bss_info_changed, | 2496 | .bss_info_changed = ar9170_op_bss_info_changed, |
2520 | .get_tsf = ar9170_op_get_tsf, | 2497 | .get_tsf = ar9170_op_get_tsf, |
2521 | .set_key = ar9170_set_key, | 2498 | .set_key = ar9170_set_key, |
2522 | .sta_notify = ar9170_sta_notify, | 2499 | .sta_add = ar9170_sta_add, |
2500 | .sta_remove = ar9170_sta_remove, | ||
2523 | .get_stats = ar9170_get_stats, | 2501 | .get_stats = ar9170_get_stats, |
2524 | .get_tx_stats = ar9170_get_tx_stats, | ||
2525 | .ampdu_action = ar9170_ampdu_action, | 2502 | .ampdu_action = ar9170_ampdu_action, |
2526 | }; | 2503 | }; |
2527 | 2504 | ||
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c index e0799d92405..0f361186b78 100644 --- a/drivers/net/wireless/ath/ar9170/usb.c +++ b/drivers/net/wireless/ath/ar9170/usb.c | |||
@@ -84,6 +84,8 @@ static struct usb_device_id ar9170_usb_ids[] = { | |||
84 | { USB_DEVICE(0x0cde, 0x0023) }, | 84 | { USB_DEVICE(0x0cde, 0x0023) }, |
85 | /* Z-Com UB82 ABG */ | 85 | /* Z-Com UB82 ABG */ |
86 | { USB_DEVICE(0x0cde, 0x0026) }, | 86 | { USB_DEVICE(0x0cde, 0x0026) }, |
87 | /* Sphairon Homelink 1202 */ | ||
88 | { USB_DEVICE(0x0cde, 0x0027) }, | ||
87 | /* Arcadyan WN7512 */ | 89 | /* Arcadyan WN7512 */ |
88 | { USB_DEVICE(0x083a, 0xf522) }, | 90 | { USB_DEVICE(0x083a, 0xf522) }, |
89 | /* Planex GWUS300 */ | 91 | /* Planex GWUS300 */ |
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 9e05648356f..71fc960814f 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h | |||
@@ -74,7 +74,6 @@ struct ath_common; | |||
74 | 74 | ||
75 | struct ath_bus_ops { | 75 | struct ath_bus_ops { |
76 | void (*read_cachesize)(struct ath_common *common, int *csz); | 76 | void (*read_cachesize)(struct ath_common *common, int *csz); |
77 | void (*cleanup)(struct ath_common *common); | ||
78 | bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); | 77 | bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); |
79 | void (*bt_coex_prep)(struct ath_common *common); | 78 | void (*bt_coex_prep)(struct ath_common *common); |
80 | }; | 79 | }; |
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 6a2a9676111..ac67f02e26d 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | |||
@@ -535,13 +535,12 @@ struct ath5k_txq_info { | |||
535 | u32 tqi_cbr_period; /* Constant bit rate period */ | 535 | u32 tqi_cbr_period; /* Constant bit rate period */ |
536 | u32 tqi_cbr_overflow_limit; | 536 | u32 tqi_cbr_overflow_limit; |
537 | u32 tqi_burst_time; | 537 | u32 tqi_burst_time; |
538 | u32 tqi_ready_time; /* Not used */ | 538 | u32 tqi_ready_time; /* Time queue waits after an event */ |
539 | }; | 539 | }; |
540 | 540 | ||
541 | /* | 541 | /* |
542 | * Transmit packet types. | 542 | * Transmit packet types. |
543 | * used on tx control descriptor | 543 | * used on tx control descriptor |
544 | * TODO: Use them inside base.c corectly | ||
545 | */ | 544 | */ |
546 | enum ath5k_pkt_type { | 545 | enum ath5k_pkt_type { |
547 | AR5K_PKT_TYPE_NORMAL = 0, | 546 | AR5K_PKT_TYPE_NORMAL = 0, |
@@ -1063,6 +1062,7 @@ struct ath5k_hw { | |||
1063 | u32 ah_cw_min; | 1062 | u32 ah_cw_min; |
1064 | u32 ah_cw_max; | 1063 | u32 ah_cw_max; |
1065 | u32 ah_limit_tx_retries; | 1064 | u32 ah_limit_tx_retries; |
1065 | u8 ah_coverage_class; | ||
1066 | 1066 | ||
1067 | /* Antenna Control */ | 1067 | /* Antenna Control */ |
1068 | u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; | 1068 | u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; |
@@ -1200,6 +1200,7 @@ extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah); | |||
1200 | 1200 | ||
1201 | /* Protocol Control Unit Functions */ | 1201 | /* Protocol Control Unit Functions */ |
1202 | extern int ath5k_hw_set_opmode(struct ath5k_hw *ah); | 1202 | extern int ath5k_hw_set_opmode(struct ath5k_hw *ah); |
1203 | extern void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class); | ||
1203 | /* BSSID Functions */ | 1204 | /* BSSID Functions */ |
1204 | extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); | 1205 | extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); |
1205 | extern void ath5k_hw_set_associd(struct ath5k_hw *ah); | 1206 | extern void ath5k_hw_set_associd(struct ath5k_hw *ah); |
@@ -1231,6 +1232,10 @@ extern int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout); | |||
1231 | extern unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah); | 1232 | extern unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah); |
1232 | extern int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout); | 1233 | extern int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout); |
1233 | extern unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah); | 1234 | extern unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah); |
1235 | /* Clock rate related functions */ | ||
1236 | unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec); | ||
1237 | unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock); | ||
1238 | unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah); | ||
1234 | /* Key table (WEP) functions */ | 1239 | /* Key table (WEP) functions */ |
1235 | extern int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry); | 1240 | extern int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry); |
1236 | extern int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry); | 1241 | extern int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry); |
@@ -1310,24 +1315,6 @@ extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower); | |||
1310 | * Functions used internaly | 1315 | * Functions used internaly |
1311 | */ | 1316 | */ |
1312 | 1317 | ||
1313 | /* | ||
1314 | * Translate usec to hw clock units | ||
1315 | * TODO: Half/quarter rate | ||
1316 | */ | ||
1317 | static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo) | ||
1318 | { | ||
1319 | return turbo ? (usec * 80) : (usec * 40); | ||
1320 | } | ||
1321 | |||
1322 | /* | ||
1323 | * Translate hw clock units to usec | ||
1324 | * TODO: Half/quarter rate | ||
1325 | */ | ||
1326 | static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo) | ||
1327 | { | ||
1328 | return turbo ? (clock / 80) : (clock / 40); | ||
1329 | } | ||
1330 | |||
1331 | static inline struct ath_common *ath5k_hw_common(struct ath5k_hw *ah) | 1318 | static inline struct ath_common *ath5k_hw_common(struct ath5k_hw *ah) |
1332 | { | 1319 | { |
1333 | return &ah->common; | 1320 | return &ah->common; |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index e63b7c40d0e..8dce0077b02 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -83,7 +83,7 @@ MODULE_VERSION("0.6.0 (EXPERIMENTAL)"); | |||
83 | 83 | ||
84 | 84 | ||
85 | /* Known PCI ids */ | 85 | /* Known PCI ids */ |
86 | static const struct pci_device_id ath5k_pci_id_table[] = { | 86 | static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = { |
87 | { PCI_VDEVICE(ATHEROS, 0x0207) }, /* 5210 early */ | 87 | { PCI_VDEVICE(ATHEROS, 0x0207) }, /* 5210 early */ |
88 | { PCI_VDEVICE(ATHEROS, 0x0007) }, /* 5210 */ | 88 | { PCI_VDEVICE(ATHEROS, 0x0007) }, /* 5210 */ |
89 | { PCI_VDEVICE(ATHEROS, 0x0011) }, /* 5311 - this is on AHB bus !*/ | 89 | { PCI_VDEVICE(ATHEROS, 0x0011) }, /* 5311 - this is on AHB bus !*/ |
@@ -225,9 +225,9 @@ static int ath5k_reset_wake(struct ath5k_softc *sc); | |||
225 | static int ath5k_start(struct ieee80211_hw *hw); | 225 | static int ath5k_start(struct ieee80211_hw *hw); |
226 | static void ath5k_stop(struct ieee80211_hw *hw); | 226 | static void ath5k_stop(struct ieee80211_hw *hw); |
227 | static int ath5k_add_interface(struct ieee80211_hw *hw, | 227 | static int ath5k_add_interface(struct ieee80211_hw *hw, |
228 | struct ieee80211_if_init_conf *conf); | 228 | struct ieee80211_vif *vif); |
229 | static void ath5k_remove_interface(struct ieee80211_hw *hw, | 229 | static void ath5k_remove_interface(struct ieee80211_hw *hw, |
230 | struct ieee80211_if_init_conf *conf); | 230 | struct ieee80211_vif *vif); |
231 | static int ath5k_config(struct ieee80211_hw *hw, u32 changed); | 231 | static int ath5k_config(struct ieee80211_hw *hw, u32 changed); |
232 | static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, | 232 | static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, |
233 | int mc_count, struct dev_addr_list *mc_list); | 233 | int mc_count, struct dev_addr_list *mc_list); |
@@ -241,8 +241,6 @@ static int ath5k_set_key(struct ieee80211_hw *hw, | |||
241 | struct ieee80211_key_conf *key); | 241 | struct ieee80211_key_conf *key); |
242 | static int ath5k_get_stats(struct ieee80211_hw *hw, | 242 | static int ath5k_get_stats(struct ieee80211_hw *hw, |
243 | struct ieee80211_low_level_stats *stats); | 243 | struct ieee80211_low_level_stats *stats); |
244 | static int ath5k_get_tx_stats(struct ieee80211_hw *hw, | ||
245 | struct ieee80211_tx_queue_stats *stats); | ||
246 | static u64 ath5k_get_tsf(struct ieee80211_hw *hw); | 244 | static u64 ath5k_get_tsf(struct ieee80211_hw *hw); |
247 | static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf); | 245 | static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf); |
248 | static void ath5k_reset_tsf(struct ieee80211_hw *hw); | 246 | static void ath5k_reset_tsf(struct ieee80211_hw *hw); |
@@ -254,6 +252,8 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw, | |||
254 | u32 changes); | 252 | u32 changes); |
255 | static void ath5k_sw_scan_start(struct ieee80211_hw *hw); | 253 | static void ath5k_sw_scan_start(struct ieee80211_hw *hw); |
256 | static void ath5k_sw_scan_complete(struct ieee80211_hw *hw); | 254 | static void ath5k_sw_scan_complete(struct ieee80211_hw *hw); |
255 | static void ath5k_set_coverage_class(struct ieee80211_hw *hw, | ||
256 | u8 coverage_class); | ||
257 | 257 | ||
258 | static const struct ieee80211_ops ath5k_hw_ops = { | 258 | static const struct ieee80211_ops ath5k_hw_ops = { |
259 | .tx = ath5k_tx, | 259 | .tx = ath5k_tx, |
@@ -267,13 +267,13 @@ static const struct ieee80211_ops ath5k_hw_ops = { | |||
267 | .set_key = ath5k_set_key, | 267 | .set_key = ath5k_set_key, |
268 | .get_stats = ath5k_get_stats, | 268 | .get_stats = ath5k_get_stats, |
269 | .conf_tx = NULL, | 269 | .conf_tx = NULL, |
270 | .get_tx_stats = ath5k_get_tx_stats, | ||
271 | .get_tsf = ath5k_get_tsf, | 270 | .get_tsf = ath5k_get_tsf, |
272 | .set_tsf = ath5k_set_tsf, | 271 | .set_tsf = ath5k_set_tsf, |
273 | .reset_tsf = ath5k_reset_tsf, | 272 | .reset_tsf = ath5k_reset_tsf, |
274 | .bss_info_changed = ath5k_bss_info_changed, | 273 | .bss_info_changed = ath5k_bss_info_changed, |
275 | .sw_scan_start = ath5k_sw_scan_start, | 274 | .sw_scan_start = ath5k_sw_scan_start, |
276 | .sw_scan_complete = ath5k_sw_scan_complete, | 275 | .sw_scan_complete = ath5k_sw_scan_complete, |
276 | .set_coverage_class = ath5k_set_coverage_class, | ||
277 | }; | 277 | }; |
278 | 278 | ||
279 | /* | 279 | /* |
@@ -1246,6 +1246,29 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
1246 | return 0; | 1246 | return 0; |
1247 | } | 1247 | } |
1248 | 1248 | ||
1249 | static enum ath5k_pkt_type get_hw_packet_type(struct sk_buff *skb) | ||
1250 | { | ||
1251 | struct ieee80211_hdr *hdr; | ||
1252 | enum ath5k_pkt_type htype; | ||
1253 | __le16 fc; | ||
1254 | |||
1255 | hdr = (struct ieee80211_hdr *)skb->data; | ||
1256 | fc = hdr->frame_control; | ||
1257 | |||
1258 | if (ieee80211_is_beacon(fc)) | ||
1259 | htype = AR5K_PKT_TYPE_BEACON; | ||
1260 | else if (ieee80211_is_probe_resp(fc)) | ||
1261 | htype = AR5K_PKT_TYPE_PROBE_RESP; | ||
1262 | else if (ieee80211_is_atim(fc)) | ||
1263 | htype = AR5K_PKT_TYPE_ATIM; | ||
1264 | else if (ieee80211_is_pspoll(fc)) | ||
1265 | htype = AR5K_PKT_TYPE_PSPOLL; | ||
1266 | else | ||
1267 | htype = AR5K_PKT_TYPE_NORMAL; | ||
1268 | |||
1269 | return htype; | ||
1270 | } | ||
1271 | |||
1249 | static int | 1272 | static int |
1250 | ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | 1273 | ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, |
1251 | struct ath5k_txq *txq) | 1274 | struct ath5k_txq *txq) |
@@ -1300,7 +1323,8 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | |||
1300 | sc->vif, pktlen, info)); | 1323 | sc->vif, pktlen, info)); |
1301 | } | 1324 | } |
1302 | ret = ah->ah_setup_tx_desc(ah, ds, pktlen, | 1325 | ret = ah->ah_setup_tx_desc(ah, ds, pktlen, |
1303 | ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, | 1326 | ieee80211_get_hdrlen_from_skb(skb), |
1327 | get_hw_packet_type(skb), | ||
1304 | (sc->power_level * 2), | 1328 | (sc->power_level * 2), |
1305 | hw_rate, | 1329 | hw_rate, |
1306 | info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags, | 1330 | info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags, |
@@ -1329,7 +1353,6 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | |||
1329 | 1353 | ||
1330 | spin_lock_bh(&txq->lock); | 1354 | spin_lock_bh(&txq->lock); |
1331 | list_add_tail(&bf->list, &txq->q); | 1355 | list_add_tail(&bf->list, &txq->q); |
1332 | sc->tx_stats[txq->qnum].len++; | ||
1333 | if (txq->link == NULL) /* is this first packet? */ | 1356 | if (txq->link == NULL) /* is this first packet? */ |
1334 | ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr); | 1357 | ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr); |
1335 | else /* no, so only link it */ | 1358 | else /* no, so only link it */ |
@@ -1513,7 +1536,8 @@ ath5k_beaconq_config(struct ath5k_softc *sc) | |||
1513 | 1536 | ||
1514 | ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi); | 1537 | ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi); |
1515 | if (ret) | 1538 | if (ret) |
1516 | return ret; | 1539 | goto err; |
1540 | |||
1517 | if (sc->opmode == NL80211_IFTYPE_AP || | 1541 | if (sc->opmode == NL80211_IFTYPE_AP || |
1518 | sc->opmode == NL80211_IFTYPE_MESH_POINT) { | 1542 | sc->opmode == NL80211_IFTYPE_MESH_POINT) { |
1519 | /* | 1543 | /* |
@@ -1540,10 +1564,25 @@ ath5k_beaconq_config(struct ath5k_softc *sc) | |||
1540 | if (ret) { | 1564 | if (ret) { |
1541 | ATH5K_ERR(sc, "%s: unable to update parameters for beacon " | 1565 | ATH5K_ERR(sc, "%s: unable to update parameters for beacon " |
1542 | "hardware queue!\n", __func__); | 1566 | "hardware queue!\n", __func__); |
1543 | return ret; | 1567 | goto err; |
1544 | } | 1568 | } |
1569 | ret = ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */ | ||
1570 | if (ret) | ||
1571 | goto err; | ||
1572 | |||
1573 | /* reconfigure cabq with ready time to 80% of beacon_interval */ | ||
1574 | ret = ath5k_hw_get_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi); | ||
1575 | if (ret) | ||
1576 | goto err; | ||
1577 | |||
1578 | qi.tqi_ready_time = (sc->bintval * 80) / 100; | ||
1579 | ret = ath5k_hw_set_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi); | ||
1580 | if (ret) | ||
1581 | goto err; | ||
1545 | 1582 | ||
1546 | return ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */; | 1583 | ret = ath5k_hw_reset_tx_queue(ah, AR5K_TX_QUEUE_ID_CAB); |
1584 | err: | ||
1585 | return ret; | ||
1547 | } | 1586 | } |
1548 | 1587 | ||
1549 | static void | 1588 | static void |
@@ -1562,7 +1601,6 @@ ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq) | |||
1562 | ath5k_txbuf_free(sc, bf); | 1601 | ath5k_txbuf_free(sc, bf); |
1563 | 1602 | ||
1564 | spin_lock_bh(&sc->txbuflock); | 1603 | spin_lock_bh(&sc->txbuflock); |
1565 | sc->tx_stats[txq->qnum].len--; | ||
1566 | list_move_tail(&bf->list, &sc->txbuf); | 1604 | list_move_tail(&bf->list, &sc->txbuf); |
1567 | sc->txbuf_len++; | 1605 | sc->txbuf_len++; |
1568 | spin_unlock_bh(&sc->txbuflock); | 1606 | spin_unlock_bh(&sc->txbuflock); |
@@ -1992,10 +2030,8 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) | |||
1992 | } | 2030 | } |
1993 | 2031 | ||
1994 | ieee80211_tx_status(sc->hw, skb); | 2032 | ieee80211_tx_status(sc->hw, skb); |
1995 | sc->tx_stats[txq->qnum].count++; | ||
1996 | 2033 | ||
1997 | spin_lock(&sc->txbuflock); | 2034 | spin_lock(&sc->txbuflock); |
1998 | sc->tx_stats[txq->qnum].len--; | ||
1999 | list_move_tail(&bf->list, &sc->txbuf); | 2035 | list_move_tail(&bf->list, &sc->txbuf); |
2000 | sc->txbuf_len++; | 2036 | sc->txbuf_len++; |
2001 | spin_unlock(&sc->txbuflock); | 2037 | spin_unlock(&sc->txbuflock); |
@@ -2773,7 +2809,7 @@ static void ath5k_stop(struct ieee80211_hw *hw) | |||
2773 | } | 2809 | } |
2774 | 2810 | ||
2775 | static int ath5k_add_interface(struct ieee80211_hw *hw, | 2811 | static int ath5k_add_interface(struct ieee80211_hw *hw, |
2776 | struct ieee80211_if_init_conf *conf) | 2812 | struct ieee80211_vif *vif) |
2777 | { | 2813 | { |
2778 | struct ath5k_softc *sc = hw->priv; | 2814 | struct ath5k_softc *sc = hw->priv; |
2779 | int ret; | 2815 | int ret; |
@@ -2784,22 +2820,22 @@ static int ath5k_add_interface(struct ieee80211_hw *hw, | |||
2784 | goto end; | 2820 | goto end; |
2785 | } | 2821 | } |
2786 | 2822 | ||
2787 | sc->vif = conf->vif; | 2823 | sc->vif = vif; |
2788 | 2824 | ||
2789 | switch (conf->type) { | 2825 | switch (vif->type) { |
2790 | case NL80211_IFTYPE_AP: | 2826 | case NL80211_IFTYPE_AP: |
2791 | case NL80211_IFTYPE_STATION: | 2827 | case NL80211_IFTYPE_STATION: |
2792 | case NL80211_IFTYPE_ADHOC: | 2828 | case NL80211_IFTYPE_ADHOC: |
2793 | case NL80211_IFTYPE_MESH_POINT: | 2829 | case NL80211_IFTYPE_MESH_POINT: |
2794 | case NL80211_IFTYPE_MONITOR: | 2830 | case NL80211_IFTYPE_MONITOR: |
2795 | sc->opmode = conf->type; | 2831 | sc->opmode = vif->type; |
2796 | break; | 2832 | break; |
2797 | default: | 2833 | default: |
2798 | ret = -EOPNOTSUPP; | 2834 | ret = -EOPNOTSUPP; |
2799 | goto end; | 2835 | goto end; |
2800 | } | 2836 | } |
2801 | 2837 | ||
2802 | ath5k_hw_set_lladdr(sc->ah, conf->mac_addr); | 2838 | ath5k_hw_set_lladdr(sc->ah, vif->addr); |
2803 | ath5k_mode_setup(sc); | 2839 | ath5k_mode_setup(sc); |
2804 | 2840 | ||
2805 | ret = 0; | 2841 | ret = 0; |
@@ -2810,13 +2846,13 @@ end: | |||
2810 | 2846 | ||
2811 | static void | 2847 | static void |
2812 | ath5k_remove_interface(struct ieee80211_hw *hw, | 2848 | ath5k_remove_interface(struct ieee80211_hw *hw, |
2813 | struct ieee80211_if_init_conf *conf) | 2849 | struct ieee80211_vif *vif) |
2814 | { | 2850 | { |
2815 | struct ath5k_softc *sc = hw->priv; | 2851 | struct ath5k_softc *sc = hw->priv; |
2816 | u8 mac[ETH_ALEN] = {}; | 2852 | u8 mac[ETH_ALEN] = {}; |
2817 | 2853 | ||
2818 | mutex_lock(&sc->lock); | 2854 | mutex_lock(&sc->lock); |
2819 | if (sc->vif != conf->vif) | 2855 | if (sc->vif != vif) |
2820 | goto end; | 2856 | goto end; |
2821 | 2857 | ||
2822 | ath5k_hw_set_lladdr(sc->ah, mac); | 2858 | ath5k_hw_set_lladdr(sc->ah, mac); |
@@ -3097,17 +3133,6 @@ ath5k_get_stats(struct ieee80211_hw *hw, | |||
3097 | return 0; | 3133 | return 0; |
3098 | } | 3134 | } |
3099 | 3135 | ||
3100 | static int | ||
3101 | ath5k_get_tx_stats(struct ieee80211_hw *hw, | ||
3102 | struct ieee80211_tx_queue_stats *stats) | ||
3103 | { | ||
3104 | struct ath5k_softc *sc = hw->priv; | ||
3105 | |||
3106 | memcpy(stats, &sc->tx_stats, sizeof(sc->tx_stats)); | ||
3107 | |||
3108 | return 0; | ||
3109 | } | ||
3110 | |||
3111 | static u64 | 3136 | static u64 |
3112 | ath5k_get_tsf(struct ieee80211_hw *hw) | 3137 | ath5k_get_tsf(struct ieee80211_hw *hw) |
3113 | { | 3138 | { |
@@ -3262,3 +3287,22 @@ static void ath5k_sw_scan_complete(struct ieee80211_hw *hw) | |||
3262 | ath5k_hw_set_ledstate(sc->ah, sc->assoc ? | 3287 | ath5k_hw_set_ledstate(sc->ah, sc->assoc ? |
3263 | AR5K_LED_ASSOC : AR5K_LED_INIT); | 3288 | AR5K_LED_ASSOC : AR5K_LED_INIT); |
3264 | } | 3289 | } |
3290 | |||
3291 | /** | ||
3292 | * ath5k_set_coverage_class - Set IEEE 802.11 coverage class | ||
3293 | * | ||
3294 | * @hw: struct ieee80211_hw pointer | ||
3295 | * @coverage_class: IEEE 802.11 coverage class number | ||
3296 | * | ||
3297 | * Mac80211 callback. Sets slot time, ACK timeout and CTS timeout for given | ||
3298 | * coverage class. The values are persistent, they are restored after device | ||
3299 | * reset. | ||
3300 | */ | ||
3301 | static void ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) | ||
3302 | { | ||
3303 | struct ath5k_softc *sc = hw->priv; | ||
3304 | |||
3305 | mutex_lock(&sc->lock); | ||
3306 | ath5k_hw_set_coverage_class(sc->ah, coverage_class); | ||
3307 | mutex_unlock(&sc->lock); | ||
3308 | } | ||
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 952b3a21bbc..7e1a88a5abd 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h | |||
@@ -117,7 +117,6 @@ struct ath5k_softc { | |||
117 | struct pci_dev *pdev; /* for dma mapping */ | 117 | struct pci_dev *pdev; /* for dma mapping */ |
118 | void __iomem *iobase; /* address of the device */ | 118 | void __iomem *iobase; /* address of the device */ |
119 | struct mutex lock; /* dev-level lock */ | 119 | struct mutex lock; /* dev-level lock */ |
120 | struct ieee80211_tx_queue_stats tx_stats[AR5K_NUM_TX_QUEUES]; | ||
121 | struct ieee80211_low_level_stats ll_stats; | 120 | struct ieee80211_low_level_stats ll_stats; |
122 | struct ieee80211_hw *hw; /* IEEE 802.11 common */ | 121 | struct ieee80211_hw *hw; /* IEEE 802.11 common */ |
123 | struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; | 122 | struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; |
diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c index 60f547503d7..67aa52e9bf9 100644 --- a/drivers/net/wireless/ath/ath5k/led.c +++ b/drivers/net/wireless/ath/ath5k/led.c | |||
@@ -77,6 +77,8 @@ static const struct pci_device_id ath5k_led_devices[] = { | |||
77 | { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137a), ATH_LED(3, 1) }, | 77 | { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137a), ATH_LED(3, 1) }, |
78 | /* HP Compaq C700 (nitrousnrg@gmail.com) */ | 78 | /* HP Compaq C700 (nitrousnrg@gmail.com) */ |
79 | { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) }, | 79 | { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) }, |
80 | /* LiteOn AR5BXB63 (magooz@salug.it) */ | ||
81 | { ATH_SDEVICE(PCI_VENDOR_ID_ATHEROS, 0x3067), ATH_LED(3, 0) }, | ||
80 | /* IBM-specific AR5212 (all others) */ | 82 | /* IBM-specific AR5212 (all others) */ |
81 | { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) }, | 83 | { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) }, |
82 | /* Dell Vostro A860 (shahar@shahar-or.co.il) */ | 84 | /* Dell Vostro A860 (shahar@shahar-or.co.il) */ |
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index 64fc1eb9b6d..aefe84f9c04 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c | |||
@@ -187,8 +187,8 @@ unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah) | |||
187 | { | 187 | { |
188 | ATH5K_TRACE(ah->ah_sc); | 188 | ATH5K_TRACE(ah->ah_sc); |
189 | 189 | ||
190 | return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah, | 190 | return ath5k_hw_clocktoh(ah, AR5K_REG_MS(ath5k_hw_reg_read(ah, |
191 | AR5K_TIME_OUT), AR5K_TIME_OUT_ACK), ah->ah_turbo); | 191 | AR5K_TIME_OUT), AR5K_TIME_OUT_ACK)); |
192 | } | 192 | } |
193 | 193 | ||
194 | /** | 194 | /** |
@@ -200,12 +200,12 @@ unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah) | |||
200 | int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout) | 200 | int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout) |
201 | { | 201 | { |
202 | ATH5K_TRACE(ah->ah_sc); | 202 | ATH5K_TRACE(ah->ah_sc); |
203 | if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK), | 203 | if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK)) |
204 | ah->ah_turbo) <= timeout) | 204 | <= timeout) |
205 | return -EINVAL; | 205 | return -EINVAL; |
206 | 206 | ||
207 | AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK, | 207 | AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK, |
208 | ath5k_hw_htoclock(timeout, ah->ah_turbo)); | 208 | ath5k_hw_htoclock(ah, timeout)); |
209 | 209 | ||
210 | return 0; | 210 | return 0; |
211 | } | 211 | } |
@@ -218,8 +218,8 @@ int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout) | |||
218 | unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah) | 218 | unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah) |
219 | { | 219 | { |
220 | ATH5K_TRACE(ah->ah_sc); | 220 | ATH5K_TRACE(ah->ah_sc); |
221 | return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah, | 221 | return ath5k_hw_clocktoh(ah, AR5K_REG_MS(ath5k_hw_reg_read(ah, |
222 | AR5K_TIME_OUT), AR5K_TIME_OUT_CTS), ah->ah_turbo); | 222 | AR5K_TIME_OUT), AR5K_TIME_OUT_CTS)); |
223 | } | 223 | } |
224 | 224 | ||
225 | /** | 225 | /** |
@@ -231,17 +231,97 @@ unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah) | |||
231 | int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout) | 231 | int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout) |
232 | { | 232 | { |
233 | ATH5K_TRACE(ah->ah_sc); | 233 | ATH5K_TRACE(ah->ah_sc); |
234 | if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS), | 234 | if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS)) |
235 | ah->ah_turbo) <= timeout) | 235 | <= timeout) |
236 | return -EINVAL; | 236 | return -EINVAL; |
237 | 237 | ||
238 | AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS, | 238 | AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS, |
239 | ath5k_hw_htoclock(timeout, ah->ah_turbo)); | 239 | ath5k_hw_htoclock(ah, timeout)); |
240 | 240 | ||
241 | return 0; | 241 | return 0; |
242 | } | 242 | } |
243 | 243 | ||
244 | /** | 244 | /** |
245 | * ath5k_hw_htoclock - Translate usec to hw clock units | ||
246 | * | ||
247 | * @ah: The &struct ath5k_hw | ||
248 | * @usec: value in microseconds | ||
249 | */ | ||
250 | unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec) | ||
251 | { | ||
252 | return usec * ath5k_hw_get_clockrate(ah); | ||
253 | } | ||
254 | |||
255 | /** | ||
256 | * ath5k_hw_clocktoh - Translate hw clock units to usec | ||
257 | * @clock: value in hw clock units | ||
258 | */ | ||
259 | unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock) | ||
260 | { | ||
261 | return clock / ath5k_hw_get_clockrate(ah); | ||
262 | } | ||
263 | |||
264 | /** | ||
265 | * ath5k_hw_get_clockrate - Get the clock rate for current mode | ||
266 | * | ||
267 | * @ah: The &struct ath5k_hw | ||
268 | */ | ||
269 | unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah) | ||
270 | { | ||
271 | struct ieee80211_channel *channel = ah->ah_current_channel; | ||
272 | int clock; | ||
273 | |||
274 | if (channel->hw_value & CHANNEL_5GHZ) | ||
275 | clock = 40; /* 802.11a */ | ||
276 | else if (channel->hw_value & CHANNEL_CCK) | ||
277 | clock = 22; /* 802.11b */ | ||
278 | else | ||
279 | clock = 44; /* 802.11g */ | ||
280 | |||
281 | /* Clock rate in turbo modes is twice the normal rate */ | ||
282 | if (channel->hw_value & CHANNEL_TURBO) | ||
283 | clock *= 2; | ||
284 | |||
285 | return clock; | ||
286 | } | ||
287 | |||
288 | /** | ||
289 | * ath5k_hw_get_default_slottime - Get the default slot time for current mode | ||
290 | * | ||
291 | * @ah: The &struct ath5k_hw | ||
292 | */ | ||
293 | unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah) | ||
294 | { | ||
295 | struct ieee80211_channel *channel = ah->ah_current_channel; | ||
296 | |||
297 | if (channel->hw_value & CHANNEL_TURBO) | ||
298 | return 6; /* both turbo modes */ | ||
299 | |||
300 | if (channel->hw_value & CHANNEL_CCK) | ||
301 | return 20; /* 802.11b */ | ||
302 | |||
303 | return 9; /* 802.11 a/g */ | ||
304 | } | ||
305 | |||
306 | /** | ||
307 | * ath5k_hw_get_default_sifs - Get the default SIFS for current mode | ||
308 | * | ||
309 | * @ah: The &struct ath5k_hw | ||
310 | */ | ||
311 | unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah) | ||
312 | { | ||
313 | struct ieee80211_channel *channel = ah->ah_current_channel; | ||
314 | |||
315 | if (channel->hw_value & CHANNEL_TURBO) | ||
316 | return 8; /* both turbo modes */ | ||
317 | |||
318 | if (channel->hw_value & CHANNEL_5GHZ) | ||
319 | return 16; /* 802.11a */ | ||
320 | |||
321 | return 10; /* 802.11 b/g */ | ||
322 | } | ||
323 | |||
324 | /** | ||
245 | * ath5k_hw_set_lladdr - Set station id | 325 | * ath5k_hw_set_lladdr - Set station id |
246 | * | 326 | * |
247 | * @ah: The &struct ath5k_hw | 327 | * @ah: The &struct ath5k_hw |
@@ -1050,3 +1130,24 @@ int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac) | |||
1050 | return 0; | 1130 | return 0; |
1051 | } | 1131 | } |
1052 | 1132 | ||
1133 | /** | ||
1134 | * ath5k_hw_set_coverage_class - Set IEEE 802.11 coverage class | ||
1135 | * | ||
1136 | * @ah: The &struct ath5k_hw | ||
1137 | * @coverage_class: IEEE 802.11 coverage class number | ||
1138 | * | ||
1139 | * Sets slot time, ACK timeout and CTS timeout for given coverage class. | ||
1140 | */ | ||
1141 | void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class) | ||
1142 | { | ||
1143 | /* As defined by IEEE 802.11-2007 17.3.8.6 */ | ||
1144 | int slot_time = ath5k_hw_get_default_slottime(ah) + 3 * coverage_class; | ||
1145 | int ack_timeout = ath5k_hw_get_default_sifs(ah) + slot_time; | ||
1146 | int cts_timeout = ack_timeout; | ||
1147 | |||
1148 | ath5k_hw_set_slot_time(ah, slot_time); | ||
1149 | ath5k_hw_set_ack_timeout(ah, ack_timeout); | ||
1150 | ath5k_hw_set_cts_timeout(ah, cts_timeout); | ||
1151 | |||
1152 | ah->ah_coverage_class = coverage_class; | ||
1153 | } | ||
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index eeebb9aef20..9122a8556f4 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c | |||
@@ -408,12 +408,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) | |||
408 | break; | 408 | break; |
409 | 409 | ||
410 | case AR5K_TX_QUEUE_CAB: | 410 | case AR5K_TX_QUEUE_CAB: |
411 | /* XXX: use BCN_SENT_GT, if we can figure out how */ | ||
411 | AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), | 412 | AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), |
412 | AR5K_QCU_MISC_FRSHED_BCN_SENT_GT | | 413 | AR5K_QCU_MISC_FRSHED_DBA_GT | |
413 | AR5K_QCU_MISC_CBREXP_DIS | | 414 | AR5K_QCU_MISC_CBREXP_DIS | |
414 | AR5K_QCU_MISC_CBREXP_BCN_DIS); | 415 | AR5K_QCU_MISC_CBREXP_BCN_DIS); |
415 | 416 | ||
416 | ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL - | 417 | ath5k_hw_reg_write(ah, ((tq->tqi_ready_time - |
417 | (AR5K_TUNE_SW_BEACON_RESP - | 418 | (AR5K_TUNE_SW_BEACON_RESP - |
418 | AR5K_TUNE_DMA_BEACON_RESP) - | 419 | AR5K_TUNE_DMA_BEACON_RESP) - |
419 | AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) | | 420 | AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) | |
@@ -520,12 +521,16 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) | |||
520 | */ | 521 | */ |
521 | unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah) | 522 | unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah) |
522 | { | 523 | { |
524 | unsigned int slot_time_clock; | ||
525 | |||
523 | ATH5K_TRACE(ah->ah_sc); | 526 | ATH5K_TRACE(ah->ah_sc); |
527 | |||
524 | if (ah->ah_version == AR5K_AR5210) | 528 | if (ah->ah_version == AR5K_AR5210) |
525 | return ath5k_hw_clocktoh(ath5k_hw_reg_read(ah, | 529 | slot_time_clock = ath5k_hw_reg_read(ah, AR5K_SLOT_TIME); |
526 | AR5K_SLOT_TIME) & 0xffff, ah->ah_turbo); | ||
527 | else | 530 | else |
528 | return ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT) & 0xffff; | 531 | slot_time_clock = ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT); |
532 | |||
533 | return ath5k_hw_clocktoh(ah, slot_time_clock & 0xffff); | ||
529 | } | 534 | } |
530 | 535 | ||
531 | /* | 536 | /* |
@@ -533,15 +538,17 @@ unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah) | |||
533 | */ | 538 | */ |
534 | int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time) | 539 | int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time) |
535 | { | 540 | { |
541 | u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time); | ||
542 | |||
536 | ATH5K_TRACE(ah->ah_sc); | 543 | ATH5K_TRACE(ah->ah_sc); |
537 | if (slot_time < AR5K_SLOT_TIME_9 || slot_time > AR5K_SLOT_TIME_MAX) | 544 | |
545 | if (slot_time < 6 || slot_time_clock > AR5K_SLOT_TIME_MAX) | ||
538 | return -EINVAL; | 546 | return -EINVAL; |
539 | 547 | ||
540 | if (ah->ah_version == AR5K_AR5210) | 548 | if (ah->ah_version == AR5K_AR5210) |
541 | ath5k_hw_reg_write(ah, ath5k_hw_htoclock(slot_time, | 549 | ath5k_hw_reg_write(ah, slot_time_clock, AR5K_SLOT_TIME); |
542 | ah->ah_turbo), AR5K_SLOT_TIME); | ||
543 | else | 550 | else |
544 | ath5k_hw_reg_write(ah, slot_time, AR5K_DCU_GBL_IFS_SLOT); | 551 | ath5k_hw_reg_write(ah, slot_time_clock, AR5K_DCU_GBL_IFS_SLOT); |
545 | 552 | ||
546 | return 0; | 553 | return 0; |
547 | } | 554 | } |
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 62954fc7786..a35a7db0fc4 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c | |||
@@ -60,12 +60,11 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, | |||
60 | !(channel->hw_value & CHANNEL_OFDM)); | 60 | !(channel->hw_value & CHANNEL_OFDM)); |
61 | 61 | ||
62 | /* Get coefficient | 62 | /* Get coefficient |
63 | * ALGO: coef = (5 * clock * carrier_freq) / 2) | 63 | * ALGO: coef = (5 * clock / carrier_freq) / 2 |
64 | * we scale coef by shifting clock value by 24 for | 64 | * we scale coef by shifting clock value by 24 for |
65 | * better precision since we use integers */ | 65 | * better precision since we use integers */ |
66 | /* TODO: Half/quarter rate */ | 66 | /* TODO: Half/quarter rate */ |
67 | clock = ath5k_hw_htoclock(1, channel->hw_value & CHANNEL_TURBO); | 67 | clock = (channel->hw_value & CHANNEL_TURBO) ? 80 : 40; |
68 | |||
69 | coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq; | 68 | coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq; |
70 | 69 | ||
71 | /* Get exponent | 70 | /* Get exponent |
@@ -1317,6 +1316,10 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
1317 | /* Restore antenna mode */ | 1316 | /* Restore antenna mode */ |
1318 | ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode); | 1317 | ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode); |
1319 | 1318 | ||
1319 | /* Restore slot time and ACK timeouts */ | ||
1320 | if (ah->ah_coverage_class > 0) | ||
1321 | ath5k_hw_set_coverage_class(ah, ah->ah_coverage_class); | ||
1322 | |||
1320 | /* | 1323 | /* |
1321 | * Configure QCUs/DCUs | 1324 | * Configure QCUs/DCUs |
1322 | */ | 1325 | */ |
@@ -1371,8 +1374,9 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
1371 | * Set clocks to 32KHz operation and use an | 1374 | * Set clocks to 32KHz operation and use an |
1372 | * external 32KHz crystal when sleeping if one | 1375 | * external 32KHz crystal when sleeping if one |
1373 | * exists */ | 1376 | * exists */ |
1374 | if (ah->ah_version == AR5K_AR5212) | 1377 | if (ah->ah_version == AR5K_AR5212 && |
1375 | ath5k_hw_set_sleep_clock(ah, true); | 1378 | ah->ah_op_mode != NL80211_IFTYPE_AP) |
1379 | ath5k_hw_set_sleep_clock(ah, true); | ||
1376 | 1380 | ||
1377 | /* | 1381 | /* |
1378 | * Disable beacons and reset the register | 1382 | * Disable beacons and reset the register |
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 4985b2b1b0a..6b50d5eb9ec 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile | |||
@@ -1,4 +1,6 @@ | |||
1 | ath9k-y += beacon.o \ | 1 | ath9k-y += beacon.o \ |
2 | gpio.o \ | ||
3 | init.o \ | ||
2 | main.o \ | 4 | main.o \ |
3 | recv.o \ | 5 | recv.o \ |
4 | xmit.o \ | 6 | xmit.o \ |
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 329e6bc137a..ca4994f1315 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c | |||
@@ -27,12 +27,6 @@ static void ath_ahb_read_cachesize(struct ath_common *common, int *csz) | |||
27 | *csz = L1_CACHE_BYTES >> 2; | 27 | *csz = L1_CACHE_BYTES >> 2; |
28 | } | 28 | } |
29 | 29 | ||
30 | static void ath_ahb_cleanup(struct ath_common *common) | ||
31 | { | ||
32 | struct ath_softc *sc = (struct ath_softc *)common->priv; | ||
33 | iounmap(sc->mem); | ||
34 | } | ||
35 | |||
36 | static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data) | 30 | static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data) |
37 | { | 31 | { |
38 | struct ath_softc *sc = (struct ath_softc *)common->priv; | 32 | struct ath_softc *sc = (struct ath_softc *)common->priv; |
@@ -54,8 +48,6 @@ static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data) | |||
54 | 48 | ||
55 | static struct ath_bus_ops ath_ahb_bus_ops = { | 49 | static struct ath_bus_ops ath_ahb_bus_ops = { |
56 | .read_cachesize = ath_ahb_read_cachesize, | 50 | .read_cachesize = ath_ahb_read_cachesize, |
57 | .cleanup = ath_ahb_cleanup, | ||
58 | |||
59 | .eeprom_read = ath_ahb_eeprom_read, | 51 | .eeprom_read = ath_ahb_eeprom_read, |
60 | }; | 52 | }; |
61 | 53 | ||
@@ -121,16 +113,19 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
121 | sc->mem = mem; | 113 | sc->mem = mem; |
122 | sc->irq = irq; | 114 | sc->irq = irq; |
123 | 115 | ||
124 | ret = ath_init_device(AR5416_AR9100_DEVID, sc, 0x0, &ath_ahb_bus_ops); | 116 | /* Will be cleared in ath9k_start() */ |
117 | sc->sc_flags |= SC_OP_INVALID; | ||
118 | |||
119 | ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc); | ||
125 | if (ret) { | 120 | if (ret) { |
126 | dev_err(&pdev->dev, "failed to initialize device\n"); | 121 | dev_err(&pdev->dev, "request_irq failed\n"); |
127 | goto err_free_hw; | 122 | goto err_free_hw; |
128 | } | 123 | } |
129 | 124 | ||
130 | ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc); | 125 | ret = ath9k_init_device(AR5416_AR9100_DEVID, sc, 0x0, &ath_ahb_bus_ops); |
131 | if (ret) { | 126 | if (ret) { |
132 | dev_err(&pdev->dev, "request_irq failed\n"); | 127 | dev_err(&pdev->dev, "failed to initialize device\n"); |
133 | goto err_detach; | 128 | goto err_irq; |
134 | } | 129 | } |
135 | 130 | ||
136 | ah = sc->sc_ah; | 131 | ah = sc->sc_ah; |
@@ -143,8 +138,8 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
143 | 138 | ||
144 | return 0; | 139 | return 0; |
145 | 140 | ||
146 | err_detach: | 141 | err_irq: |
147 | ath_detach(sc); | 142 | free_irq(irq, sc); |
148 | err_free_hw: | 143 | err_free_hw: |
149 | ieee80211_free_hw(hw); | 144 | ieee80211_free_hw(hw); |
150 | platform_set_drvdata(pdev, NULL); | 145 | platform_set_drvdata(pdev, NULL); |
@@ -161,8 +156,12 @@ static int ath_ahb_remove(struct platform_device *pdev) | |||
161 | if (hw) { | 156 | if (hw) { |
162 | struct ath_wiphy *aphy = hw->priv; | 157 | struct ath_wiphy *aphy = hw->priv; |
163 | struct ath_softc *sc = aphy->sc; | 158 | struct ath_softc *sc = aphy->sc; |
159 | void __iomem *mem = sc->mem; | ||
164 | 160 | ||
165 | ath_cleanup(sc); | 161 | ath9k_deinit_device(sc); |
162 | free_irq(sc->irq, sc); | ||
163 | ieee80211_free_hw(sc->hw); | ||
164 | iounmap(mem); | ||
166 | platform_set_drvdata(pdev, NULL); | 165 | platform_set_drvdata(pdev, NULL); |
167 | } | 166 | } |
168 | 167 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 1597a42731e..83c7ea4c007 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -267,6 +267,7 @@ void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, | |||
267 | u16 tid, u16 *ssn); | 267 | u16 tid, u16 *ssn); |
268 | void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); | 268 | void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); |
269 | void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); | 269 | void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); |
270 | void ath9k_enable_ps(struct ath_softc *sc); | ||
270 | 271 | ||
271 | /********/ | 272 | /********/ |
272 | /* VIFs */ | 273 | /* VIFs */ |
@@ -341,6 +342,12 @@ int ath_beaconq_config(struct ath_softc *sc); | |||
341 | #define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */ | 342 | #define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */ |
342 | #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ | 343 | #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ |
343 | 344 | ||
345 | void ath_ani_calibrate(unsigned long data); | ||
346 | |||
347 | /**********/ | ||
348 | /* BTCOEX */ | ||
349 | /**********/ | ||
350 | |||
344 | /* Defines the BT AR_BT_COEX_WGHT used */ | 351 | /* Defines the BT AR_BT_COEX_WGHT used */ |
345 | enum ath_stomp_type { | 352 | enum ath_stomp_type { |
346 | ATH_BTCOEX_NO_STOMP, | 353 | ATH_BTCOEX_NO_STOMP, |
@@ -358,9 +365,14 @@ struct ath_btcoex { | |||
358 | int bt_stomp_type; /* Types of BT stomping */ | 365 | int bt_stomp_type; /* Types of BT stomping */ |
359 | u32 btcoex_no_stomp; /* in usec */ | 366 | u32 btcoex_no_stomp; /* in usec */ |
360 | u32 btcoex_period; /* in usec */ | 367 | u32 btcoex_period; /* in usec */ |
368 | u32 btscan_no_stomp; /* in usec */ | ||
361 | struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ | 369 | struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ |
362 | }; | 370 | }; |
363 | 371 | ||
372 | int ath_init_btcoex_timer(struct ath_softc *sc); | ||
373 | void ath9k_btcoex_timer_resume(struct ath_softc *sc); | ||
374 | void ath9k_btcoex_timer_pause(struct ath_softc *sc); | ||
375 | |||
364 | /********************/ | 376 | /********************/ |
365 | /* LED Control */ | 377 | /* LED Control */ |
366 | /********************/ | 378 | /********************/ |
@@ -385,6 +397,9 @@ struct ath_led { | |||
385 | bool registered; | 397 | bool registered; |
386 | }; | 398 | }; |
387 | 399 | ||
400 | void ath_init_leds(struct ath_softc *sc); | ||
401 | void ath_deinit_leds(struct ath_softc *sc); | ||
402 | |||
388 | /********************/ | 403 | /********************/ |
389 | /* Main driver core */ | 404 | /* Main driver core */ |
390 | /********************/ | 405 | /********************/ |
@@ -403,26 +418,29 @@ struct ath_led { | |||
403 | #define ATH_TXPOWER_MAX 100 /* .5 dBm units */ | 418 | #define ATH_TXPOWER_MAX 100 /* .5 dBm units */ |
404 | #define ATH_RATE_DUMMY_MARKER 0 | 419 | #define ATH_RATE_DUMMY_MARKER 0 |
405 | 420 | ||
406 | #define SC_OP_INVALID BIT(0) | 421 | #define SC_OP_INVALID BIT(0) |
407 | #define SC_OP_BEACONS BIT(1) | 422 | #define SC_OP_BEACONS BIT(1) |
408 | #define SC_OP_RXAGGR BIT(2) | 423 | #define SC_OP_RXAGGR BIT(2) |
409 | #define SC_OP_TXAGGR BIT(3) | 424 | #define SC_OP_TXAGGR BIT(3) |
410 | #define SC_OP_FULL_RESET BIT(4) | 425 | #define SC_OP_FULL_RESET BIT(4) |
411 | #define SC_OP_PREAMBLE_SHORT BIT(5) | 426 | #define SC_OP_PREAMBLE_SHORT BIT(5) |
412 | #define SC_OP_PROTECT_ENABLE BIT(6) | 427 | #define SC_OP_PROTECT_ENABLE BIT(6) |
413 | #define SC_OP_RXFLUSH BIT(7) | 428 | #define SC_OP_RXFLUSH BIT(7) |
414 | #define SC_OP_LED_ASSOCIATED BIT(8) | 429 | #define SC_OP_LED_ASSOCIATED BIT(8) |
415 | #define SC_OP_WAIT_FOR_BEACON BIT(12) | 430 | #define SC_OP_LED_ON BIT(9) |
416 | #define SC_OP_LED_ON BIT(13) | 431 | #define SC_OP_SCANNING BIT(10) |
417 | #define SC_OP_SCANNING BIT(14) | 432 | #define SC_OP_TSF_RESET BIT(11) |
418 | #define SC_OP_TSF_RESET BIT(15) | 433 | #define SC_OP_BT_PRIORITY_DETECTED BIT(12) |
419 | #define SC_OP_WAIT_FOR_CAB BIT(16) | 434 | #define SC_OP_BT_SCAN BIT(13) |
420 | #define SC_OP_WAIT_FOR_PSPOLL_DATA BIT(17) | 435 | |
421 | #define SC_OP_WAIT_FOR_TX_ACK BIT(18) | 436 | /* Powersave flags */ |
422 | #define SC_OP_BEACON_SYNC BIT(19) | 437 | #define PS_WAIT_FOR_BEACON BIT(0) |
423 | #define SC_OP_BT_PRIORITY_DETECTED BIT(21) | 438 | #define PS_WAIT_FOR_CAB BIT(1) |
424 | #define SC_OP_NULLFUNC_COMPLETED BIT(22) | 439 | #define PS_WAIT_FOR_PSPOLL_DATA BIT(2) |
425 | #define SC_OP_PS_ENABLED BIT(23) | 440 | #define PS_WAIT_FOR_TX_ACK BIT(3) |
441 | #define PS_BEACON_SYNC BIT(4) | ||
442 | #define PS_NULLFUNC_COMPLETED BIT(5) | ||
443 | #define PS_ENABLED BIT(6) | ||
426 | 444 | ||
427 | struct ath_wiphy; | 445 | struct ath_wiphy; |
428 | struct ath_rate_table; | 446 | struct ath_rate_table; |
@@ -453,16 +471,17 @@ struct ath_softc { | |||
453 | int irq; | 471 | int irq; |
454 | spinlock_t sc_resetlock; | 472 | spinlock_t sc_resetlock; |
455 | spinlock_t sc_serial_rw; | 473 | spinlock_t sc_serial_rw; |
456 | spinlock_t ani_lock; | ||
457 | spinlock_t sc_pm_lock; | 474 | spinlock_t sc_pm_lock; |
458 | struct mutex mutex; | 475 | struct mutex mutex; |
459 | 476 | ||
460 | u32 intrstatus; | 477 | u32 intrstatus; |
461 | u32 sc_flags; /* SC_OP_* */ | 478 | u32 sc_flags; /* SC_OP_* */ |
479 | u16 ps_flags; /* PS_* */ | ||
462 | u16 curtxpow; | 480 | u16 curtxpow; |
463 | u8 nbcnvifs; | 481 | u8 nbcnvifs; |
464 | u16 nvifs; | 482 | u16 nvifs; |
465 | bool ps_enabled; | 483 | bool ps_enabled; |
484 | bool ps_idle; | ||
466 | unsigned long ps_usecount; | 485 | unsigned long ps_usecount; |
467 | enum ath9k_int imask; | 486 | enum ath9k_int imask; |
468 | 487 | ||
@@ -509,6 +528,7 @@ struct ath_wiphy { | |||
509 | int chan_is_ht; | 528 | int chan_is_ht; |
510 | }; | 529 | }; |
511 | 530 | ||
531 | void ath9k_tasklet(unsigned long data); | ||
512 | int ath_reset(struct ath_softc *sc, bool retry_tx); | 532 | int ath_reset(struct ath_softc *sc, bool retry_tx); |
513 | int ath_get_hal_qnum(u16 queue, struct ath_softc *sc); | 533 | int ath_get_hal_qnum(u16 queue, struct ath_softc *sc); |
514 | int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc); | 534 | int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc); |
@@ -519,21 +539,16 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz) | |||
519 | common->bus_ops->read_cachesize(common, csz); | 539 | common->bus_ops->read_cachesize(common, csz); |
520 | } | 540 | } |
521 | 541 | ||
522 | static inline void ath_bus_cleanup(struct ath_common *common) | ||
523 | { | ||
524 | common->bus_ops->cleanup(common); | ||
525 | } | ||
526 | |||
527 | extern struct ieee80211_ops ath9k_ops; | 542 | extern struct ieee80211_ops ath9k_ops; |
543 | extern int modparam_nohwcrypt; | ||
528 | 544 | ||
529 | irqreturn_t ath_isr(int irq, void *dev); | 545 | irqreturn_t ath_isr(int irq, void *dev); |
530 | void ath_cleanup(struct ath_softc *sc); | 546 | int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, |
531 | int ath_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, | ||
532 | const struct ath_bus_ops *bus_ops); | 547 | const struct ath_bus_ops *bus_ops); |
533 | void ath_detach(struct ath_softc *sc); | 548 | void ath9k_deinit_device(struct ath_softc *sc); |
534 | const char *ath_mac_bb_name(u32 mac_bb_version); | 549 | const char *ath_mac_bb_name(u32 mac_bb_version); |
535 | const char *ath_rf_name(u16 rf_version); | 550 | const char *ath_rf_name(u16 rf_version); |
536 | void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); | 551 | void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); |
537 | void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, | 552 | void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, |
538 | struct ath9k_channel *ichan); | 553 | struct ath9k_channel *ichan); |
539 | void ath_update_chainmask(struct ath_softc *sc, int is_ht); | 554 | void ath_update_chainmask(struct ath_softc *sc, int is_ht); |
@@ -542,6 +557,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
542 | 557 | ||
543 | void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw); | 558 | void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw); |
544 | void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw); | 559 | void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw); |
560 | bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode); | ||
545 | 561 | ||
546 | #ifdef CONFIG_PCI | 562 | #ifdef CONFIG_PCI |
547 | int ath_pci_init(void); | 563 | int ath_pci_init(void); |
@@ -583,4 +599,8 @@ void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue); | |||
583 | void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue); | 599 | void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue); |
584 | 600 | ||
585 | int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype); | 601 | int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype); |
602 | |||
603 | void ath_start_rfkill_poll(struct ath_softc *sc); | ||
604 | extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw); | ||
605 | |||
586 | #endif /* ATH9K_H */ | 606 | #endif /* ATH9K_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 1660ef17aaf..b4a31a43a62 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -62,7 +62,7 @@ int ath_beaconq_config(struct ath_softc *sc) | |||
62 | * Beacons are always sent out at the lowest rate, and are not retried. | 62 | * Beacons are always sent out at the lowest rate, and are not retried. |
63 | */ | 63 | */ |
64 | static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, | 64 | static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, |
65 | struct ath_buf *bf) | 65 | struct ath_buf *bf, int rateidx) |
66 | { | 66 | { |
67 | struct sk_buff *skb = bf->bf_mpdu; | 67 | struct sk_buff *skb = bf->bf_mpdu; |
68 | struct ath_hw *ah = sc->sc_ah; | 68 | struct ath_hw *ah = sc->sc_ah; |
@@ -96,9 +96,9 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, | |||
96 | ds->ds_data = bf->bf_buf_addr; | 96 | ds->ds_data = bf->bf_buf_addr; |
97 | 97 | ||
98 | sband = &sc->sbands[common->hw->conf.channel->band]; | 98 | sband = &sc->sbands[common->hw->conf.channel->band]; |
99 | rate = sband->bitrates[0].hw_value; | 99 | rate = sband->bitrates[rateidx].hw_value; |
100 | if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) | 100 | if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) |
101 | rate |= sband->bitrates[0].hw_value_short; | 101 | rate |= sband->bitrates[rateidx].hw_value_short; |
102 | 102 | ||
103 | ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN, | 103 | ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN, |
104 | ATH9K_PKT_TYPE_BEACON, | 104 | ATH9K_PKT_TYPE_BEACON, |
@@ -206,7 +206,7 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, | |||
206 | } | 206 | } |
207 | } | 207 | } |
208 | 208 | ||
209 | ath_beacon_setup(sc, avp, bf); | 209 | ath_beacon_setup(sc, avp, bf, info->control.rates[0].idx); |
210 | 210 | ||
211 | while (skb) { | 211 | while (skb) { |
212 | ath_tx_cabq(hw, skb); | 212 | ath_tx_cabq(hw, skb); |
@@ -237,7 +237,7 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, | |||
237 | bf = avp->av_bcbuf; | 237 | bf = avp->av_bcbuf; |
238 | skb = bf->bf_mpdu; | 238 | skb = bf->bf_mpdu; |
239 | 239 | ||
240 | ath_beacon_setup(sc, avp, bf); | 240 | ath_beacon_setup(sc, avp, bf, 0); |
241 | 241 | ||
242 | /* NB: caller is known to have already stopped tx dma */ | 242 | /* NB: caller is known to have already stopped tx dma */ |
243 | ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr); | 243 | ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr); |
@@ -480,7 +480,8 @@ void ath_beacon_tasklet(unsigned long data) | |||
480 | sc->beacon.updateslot = COMMIT; /* commit next beacon */ | 480 | sc->beacon.updateslot = COMMIT; /* commit next beacon */ |
481 | sc->beacon.slotupdate = slot; | 481 | sc->beacon.slotupdate = slot; |
482 | } else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) { | 482 | } else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) { |
483 | ath9k_hw_setslottime(sc->sc_ah, sc->beacon.slottime); | 483 | ah->slottime = sc->beacon.slottime; |
484 | ath9k_hw_init_global_settings(ah); | ||
484 | sc->beacon.updateslot = OK; | 485 | sc->beacon.updateslot = OK; |
485 | } | 486 | } |
486 | if (bfaddr != 0) { | 487 | if (bfaddr != 0) { |
@@ -525,16 +526,13 @@ static void ath_beacon_config_ap(struct ath_softc *sc, | |||
525 | { | 526 | { |
526 | u32 nexttbtt, intval; | 527 | u32 nexttbtt, intval; |
527 | 528 | ||
528 | /* Configure the timers only when the TSF has to be reset */ | ||
529 | |||
530 | if (!(sc->sc_flags & SC_OP_TSF_RESET)) | ||
531 | return; | ||
532 | |||
533 | /* NB: the beacon interval is kept internally in TU's */ | 529 | /* NB: the beacon interval is kept internally in TU's */ |
534 | intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; | 530 | intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; |
535 | intval /= ATH_BCBUF; /* for staggered beacons */ | 531 | intval /= ATH_BCBUF; /* for staggered beacons */ |
536 | nexttbtt = intval; | 532 | nexttbtt = intval; |
537 | intval |= ATH9K_BEACON_RESET_TSF; | 533 | |
534 | if (sc->sc_flags & SC_OP_TSF_RESET) | ||
535 | intval |= ATH9K_BEACON_RESET_TSF; | ||
538 | 536 | ||
539 | /* | 537 | /* |
540 | * In AP mode we enable the beacon timers and SWBA interrupts to | 538 | * In AP mode we enable the beacon timers and SWBA interrupts to |
@@ -576,6 +574,13 @@ static void ath_beacon_config_sta(struct ath_softc *sc, | |||
576 | u64 tsf; | 574 | u64 tsf; |
577 | int num_beacons, offset, dtim_dec_count, cfp_dec_count; | 575 | int num_beacons, offset, dtim_dec_count, cfp_dec_count; |
578 | 576 | ||
577 | /* No need to configure beacon if we are not associated */ | ||
578 | if (!common->curaid) { | ||
579 | ath_print(common, ATH_DBG_BEACON, | ||
580 | "STA is not yet associated..skipping beacon config\n"); | ||
581 | return; | ||
582 | } | ||
583 | |||
579 | memset(&bs, 0, sizeof(bs)); | 584 | memset(&bs, 0, sizeof(bs)); |
580 | intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; | 585 | intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; |
581 | 586 | ||
@@ -738,7 +743,6 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
738 | enum nl80211_iftype iftype; | 743 | enum nl80211_iftype iftype; |
739 | 744 | ||
740 | /* Setup the beacon configuration parameters */ | 745 | /* Setup the beacon configuration parameters */ |
741 | |||
742 | if (vif) { | 746 | if (vif) { |
743 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | 747 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; |
744 | 748 | ||
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h index 1ba31a73317..1ee5a15ccbb 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.h +++ b/drivers/net/wireless/ath/ath9k/btcoex.h | |||
@@ -25,10 +25,12 @@ | |||
25 | 25 | ||
26 | #define ATH_BTCOEX_DEF_BT_PERIOD 45 | 26 | #define ATH_BTCOEX_DEF_BT_PERIOD 45 |
27 | #define ATH_BTCOEX_DEF_DUTY_CYCLE 55 | 27 | #define ATH_BTCOEX_DEF_DUTY_CYCLE 55 |
28 | #define ATH_BTCOEX_BTSCAN_DUTY_CYCLE 90 | ||
28 | #define ATH_BTCOEX_BMISS_THRESH 50 | 29 | #define ATH_BTCOEX_BMISS_THRESH 50 |
29 | 30 | ||
30 | #define ATH_BT_PRIORITY_TIME_THRESHOLD 1000 /* ms */ | 31 | #define ATH_BT_PRIORITY_TIME_THRESHOLD 1000 /* ms */ |
31 | #define ATH_BT_CNT_THRESHOLD 3 | 32 | #define ATH_BT_CNT_THRESHOLD 3 |
33 | #define ATH_BT_CNT_SCAN_THRESHOLD 15 | ||
32 | 34 | ||
33 | enum ath_btcoex_scheme { | 35 | enum ath_btcoex_scheme { |
34 | ATH_BTCOEX_CFG_NONE, | 36 | ATH_BTCOEX_CFG_NONE, |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index b66f72dbf7b..42d2a506845 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -75,17 +75,24 @@ static const struct file_operations fops_debug = { | |||
75 | 75 | ||
76 | #endif | 76 | #endif |
77 | 77 | ||
78 | #define DMA_BUF_LEN 1024 | ||
79 | |||
78 | static ssize_t read_file_dma(struct file *file, char __user *user_buf, | 80 | static ssize_t read_file_dma(struct file *file, char __user *user_buf, |
79 | size_t count, loff_t *ppos) | 81 | size_t count, loff_t *ppos) |
80 | { | 82 | { |
81 | struct ath_softc *sc = file->private_data; | 83 | struct ath_softc *sc = file->private_data; |
82 | struct ath_hw *ah = sc->sc_ah; | 84 | struct ath_hw *ah = sc->sc_ah; |
83 | char buf[1024]; | 85 | char *buf; |
86 | int retval; | ||
84 | unsigned int len = 0; | 87 | unsigned int len = 0; |
85 | u32 val[ATH9K_NUM_DMA_DEBUG_REGS]; | 88 | u32 val[ATH9K_NUM_DMA_DEBUG_REGS]; |
86 | int i, qcuOffset = 0, dcuOffset = 0; | 89 | int i, qcuOffset = 0, dcuOffset = 0; |
87 | u32 *qcuBase = &val[0], *dcuBase = &val[4]; | 90 | u32 *qcuBase = &val[0], *dcuBase = &val[4]; |
88 | 91 | ||
92 | buf = kmalloc(DMA_BUF_LEN, GFP_KERNEL); | ||
93 | if (!buf) | ||
94 | return 0; | ||
95 | |||
89 | ath9k_ps_wakeup(sc); | 96 | ath9k_ps_wakeup(sc); |
90 | 97 | ||
91 | REG_WRITE_D(ah, AR_MACMISC, | 98 | REG_WRITE_D(ah, AR_MACMISC, |
@@ -93,20 +100,20 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf, | |||
93 | (AR_MACMISC_MISC_OBS_BUS_1 << | 100 | (AR_MACMISC_MISC_OBS_BUS_1 << |
94 | AR_MACMISC_MISC_OBS_BUS_MSB_S))); | 101 | AR_MACMISC_MISC_OBS_BUS_MSB_S))); |
95 | 102 | ||
96 | len += snprintf(buf + len, sizeof(buf) - len, | 103 | len += snprintf(buf + len, DMA_BUF_LEN - len, |
97 | "Raw DMA Debug values:\n"); | 104 | "Raw DMA Debug values:\n"); |
98 | 105 | ||
99 | for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) { | 106 | for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) { |
100 | if (i % 4 == 0) | 107 | if (i % 4 == 0) |
101 | len += snprintf(buf + len, sizeof(buf) - len, "\n"); | 108 | len += snprintf(buf + len, DMA_BUF_LEN - len, "\n"); |
102 | 109 | ||
103 | val[i] = REG_READ_D(ah, AR_DMADBG_0 + (i * sizeof(u32))); | 110 | val[i] = REG_READ_D(ah, AR_DMADBG_0 + (i * sizeof(u32))); |
104 | len += snprintf(buf + len, sizeof(buf) - len, "%d: %08x ", | 111 | len += snprintf(buf + len, DMA_BUF_LEN - len, "%d: %08x ", |
105 | i, val[i]); | 112 | i, val[i]); |
106 | } | 113 | } |
107 | 114 | ||
108 | len += snprintf(buf + len, sizeof(buf) - len, "\n\n"); | 115 | len += snprintf(buf + len, DMA_BUF_LEN - len, "\n\n"); |
109 | len += snprintf(buf + len, sizeof(buf) - len, | 116 | len += snprintf(buf + len, DMA_BUF_LEN - len, |
110 | "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n"); | 117 | "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n"); |
111 | 118 | ||
112 | for (i = 0; i < ATH9K_NUM_QUEUES; i++, qcuOffset += 4, dcuOffset += 5) { | 119 | for (i = 0; i < ATH9K_NUM_QUEUES; i++, qcuOffset += 4, dcuOffset += 5) { |
@@ -120,7 +127,7 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf, | |||
120 | dcuBase++; | 127 | dcuBase++; |
121 | } | 128 | } |
122 | 129 | ||
123 | len += snprintf(buf + len, sizeof(buf) - len, | 130 | len += snprintf(buf + len, DMA_BUF_LEN - len, |
124 | "%2d %2x %1x %2x %2x\n", | 131 | "%2d %2x %1x %2x %2x\n", |
125 | i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset, | 132 | i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset, |
126 | (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3), | 133 | (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3), |
@@ -128,35 +135,37 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf, | |||
128 | (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset); | 135 | (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset); |
129 | } | 136 | } |
130 | 137 | ||
131 | len += snprintf(buf + len, sizeof(buf) - len, "\n"); | 138 | len += snprintf(buf + len, DMA_BUF_LEN - len, "\n"); |
132 | 139 | ||
133 | len += snprintf(buf + len, sizeof(buf) - len, | 140 | len += snprintf(buf + len, DMA_BUF_LEN - len, |
134 | "qcu_stitch state: %2x qcu_fetch state: %2x\n", | 141 | "qcu_stitch state: %2x qcu_fetch state: %2x\n", |
135 | (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22); | 142 | (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22); |
136 | len += snprintf(buf + len, sizeof(buf) - len, | 143 | len += snprintf(buf + len, DMA_BUF_LEN - len, |
137 | "qcu_complete state: %2x dcu_complete state: %2x\n", | 144 | "qcu_complete state: %2x dcu_complete state: %2x\n", |
138 | (val[3] & 0x1c000000) >> 26, (val[6] & 0x3)); | 145 | (val[3] & 0x1c000000) >> 26, (val[6] & 0x3)); |
139 | len += snprintf(buf + len, sizeof(buf) - len, | 146 | len += snprintf(buf + len, DMA_BUF_LEN - len, |
140 | "dcu_arb state: %2x dcu_fp state: %2x\n", | 147 | "dcu_arb state: %2x dcu_fp state: %2x\n", |
141 | (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27); | 148 | (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27); |
142 | len += snprintf(buf + len, sizeof(buf) - len, | 149 | len += snprintf(buf + len, DMA_BUF_LEN - len, |
143 | "chan_idle_dur: %3d chan_idle_dur_valid: %1d\n", | 150 | "chan_idle_dur: %3d chan_idle_dur_valid: %1d\n", |
144 | (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10); | 151 | (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10); |
145 | len += snprintf(buf + len, sizeof(buf) - len, | 152 | len += snprintf(buf + len, DMA_BUF_LEN - len, |
146 | "txfifo_valid_0: %1d txfifo_valid_1: %1d\n", | 153 | "txfifo_valid_0: %1d txfifo_valid_1: %1d\n", |
147 | (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12); | 154 | (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12); |
148 | len += snprintf(buf + len, sizeof(buf) - len, | 155 | len += snprintf(buf + len, DMA_BUF_LEN - len, |
149 | "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n", | 156 | "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n", |
150 | (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17); | 157 | (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17); |
151 | 158 | ||
152 | len += snprintf(buf + len, sizeof(buf) - len, "pcu observe: 0x%x \n", | 159 | len += snprintf(buf + len, DMA_BUF_LEN - len, "pcu observe: 0x%x \n", |
153 | REG_READ_D(ah, AR_OBS_BUS_1)); | 160 | REG_READ_D(ah, AR_OBS_BUS_1)); |
154 | len += snprintf(buf + len, sizeof(buf) - len, | 161 | len += snprintf(buf + len, DMA_BUF_LEN - len, |
155 | "AR_CR: 0x%x \n", REG_READ_D(ah, AR_CR)); | 162 | "AR_CR: 0x%x \n", REG_READ_D(ah, AR_CR)); |
156 | 163 | ||
157 | ath9k_ps_restore(sc); | 164 | ath9k_ps_restore(sc); |
158 | 165 | ||
159 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | 166 | retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); |
167 | kfree(buf); | ||
168 | return retval; | ||
160 | } | 169 | } |
161 | 170 | ||
162 | static const struct file_operations fops_dma = { | 171 | static const struct file_operations fops_dma = { |
@@ -289,23 +298,49 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf, | |||
289 | if (sc->cur_rate_table == NULL) | 298 | if (sc->cur_rate_table == NULL) |
290 | return 0; | 299 | return 0; |
291 | 300 | ||
292 | max = 80 + sc->cur_rate_table->rate_cnt * 64; | 301 | max = 80 + sc->cur_rate_table->rate_cnt * 1024; |
293 | buf = kmalloc(max + 1, GFP_KERNEL); | 302 | buf = kmalloc(max + 1, GFP_KERNEL); |
294 | if (buf == NULL) | 303 | if (buf == NULL) |
295 | return 0; | 304 | return 0; |
296 | buf[max] = 0; | 305 | buf[max] = 0; |
297 | 306 | ||
298 | len += sprintf(buf, "%5s %15s %8s %9s %3s\n\n", "Rate", "Success", | 307 | len += sprintf(buf, "%6s %6s %6s " |
299 | "Retries", "XRetries", "PER"); | 308 | "%10s %10s %10s %10s\n", |
309 | "HT", "MCS", "Rate", | ||
310 | "Success", "Retries", "XRetries", "PER"); | ||
300 | 311 | ||
301 | for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) { | 312 | for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) { |
302 | u32 ratekbps = sc->cur_rate_table->info[i].ratekbps; | 313 | u32 ratekbps = sc->cur_rate_table->info[i].ratekbps; |
303 | struct ath_rc_stats *stats = &sc->debug.stats.rcstats[i]; | 314 | struct ath_rc_stats *stats = &sc->debug.stats.rcstats[i]; |
315 | char mcs[5]; | ||
316 | char htmode[5]; | ||
317 | int used_mcs = 0, used_htmode = 0; | ||
318 | |||
319 | if (WLAN_RC_PHY_HT(sc->cur_rate_table->info[i].phy)) { | ||
320 | used_mcs = snprintf(mcs, 5, "%d", | ||
321 | sc->cur_rate_table->info[i].ratecode); | ||
322 | |||
323 | if (WLAN_RC_PHY_40(sc->cur_rate_table->info[i].phy)) | ||
324 | used_htmode = snprintf(htmode, 5, "HT40"); | ||
325 | else if (WLAN_RC_PHY_20(sc->cur_rate_table->info[i].phy)) | ||
326 | used_htmode = snprintf(htmode, 5, "HT20"); | ||
327 | else | ||
328 | used_htmode = snprintf(htmode, 5, "????"); | ||
329 | } | ||
330 | |||
331 | mcs[used_mcs] = '\0'; | ||
332 | htmode[used_htmode] = '\0'; | ||
304 | 333 | ||
305 | len += snprintf(buf + len, max - len, | 334 | len += snprintf(buf + len, max - len, |
306 | "%3u.%d: %8u %8u %8u %8u\n", ratekbps / 1000, | 335 | "%6s %6s %3u.%d: " |
307 | (ratekbps % 1000) / 100, stats->success, | 336 | "%10u %10u %10u %10u\n", |
308 | stats->retries, stats->xretries, | 337 | htmode, |
338 | mcs, | ||
339 | ratekbps / 1000, | ||
340 | (ratekbps % 1000) / 100, | ||
341 | stats->success, | ||
342 | stats->retries, | ||
343 | stats->xretries, | ||
309 | stats->per); | 344 | stats->per); |
310 | } | 345 | } |
311 | 346 | ||
@@ -554,6 +589,116 @@ static const struct file_operations fops_xmit = { | |||
554 | .owner = THIS_MODULE | 589 | .owner = THIS_MODULE |
555 | }; | 590 | }; |
556 | 591 | ||
592 | static ssize_t read_file_recv(struct file *file, char __user *user_buf, | ||
593 | size_t count, loff_t *ppos) | ||
594 | { | ||
595 | #define PHY_ERR(s, p) \ | ||
596 | len += snprintf(buf + len, size - len, "%18s : %10u\n", s, \ | ||
597 | sc->debug.stats.rxstats.phy_err_stats[p]); | ||
598 | |||
599 | struct ath_softc *sc = file->private_data; | ||
600 | char *buf; | ||
601 | unsigned int len = 0, size = 1152; | ||
602 | ssize_t retval = 0; | ||
603 | |||
604 | buf = kzalloc(size, GFP_KERNEL); | ||
605 | if (buf == NULL) | ||
606 | return 0; | ||
607 | |||
608 | len += snprintf(buf + len, size - len, | ||
609 | "%18s : %10u\n", "CRC ERR", | ||
610 | sc->debug.stats.rxstats.crc_err); | ||
611 | len += snprintf(buf + len, size - len, | ||
612 | "%18s : %10u\n", "DECRYPT CRC ERR", | ||
613 | sc->debug.stats.rxstats.decrypt_crc_err); | ||
614 | len += snprintf(buf + len, size - len, | ||
615 | "%18s : %10u\n", "PHY ERR", | ||
616 | sc->debug.stats.rxstats.phy_err); | ||
617 | len += snprintf(buf + len, size - len, | ||
618 | "%18s : %10u\n", "MIC ERR", | ||
619 | sc->debug.stats.rxstats.mic_err); | ||
620 | len += snprintf(buf + len, size - len, | ||
621 | "%18s : %10u\n", "PRE-DELIM CRC ERR", | ||
622 | sc->debug.stats.rxstats.pre_delim_crc_err); | ||
623 | len += snprintf(buf + len, size - len, | ||
624 | "%18s : %10u\n", "POST-DELIM CRC ERR", | ||
625 | sc->debug.stats.rxstats.post_delim_crc_err); | ||
626 | len += snprintf(buf + len, size - len, | ||
627 | "%18s : %10u\n", "DECRYPT BUSY ERR", | ||
628 | sc->debug.stats.rxstats.decrypt_busy_err); | ||
629 | |||
630 | PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN); | ||
631 | PHY_ERR("TIMING", ATH9K_PHYERR_TIMING); | ||
632 | PHY_ERR("PARITY", ATH9K_PHYERR_PARITY); | ||
633 | PHY_ERR("RATE", ATH9K_PHYERR_RATE); | ||
634 | PHY_ERR("LENGTH", ATH9K_PHYERR_LENGTH); | ||
635 | PHY_ERR("RADAR", ATH9K_PHYERR_RADAR); | ||
636 | PHY_ERR("SERVICE", ATH9K_PHYERR_SERVICE); | ||
637 | PHY_ERR("TOR", ATH9K_PHYERR_TOR); | ||
638 | PHY_ERR("OFDM-TIMING", ATH9K_PHYERR_OFDM_TIMING); | ||
639 | PHY_ERR("OFDM-SIGNAL-PARITY", ATH9K_PHYERR_OFDM_SIGNAL_PARITY); | ||
640 | PHY_ERR("OFDM-RATE", ATH9K_PHYERR_OFDM_RATE_ILLEGAL); | ||
641 | PHY_ERR("OFDM-LENGTH", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL); | ||
642 | PHY_ERR("OFDM-POWER-DROP", ATH9K_PHYERR_OFDM_POWER_DROP); | ||
643 | PHY_ERR("OFDM-SERVICE", ATH9K_PHYERR_OFDM_SERVICE); | ||
644 | PHY_ERR("OFDM-RESTART", ATH9K_PHYERR_OFDM_RESTART); | ||
645 | PHY_ERR("FALSE-RADAR-EXT", ATH9K_PHYERR_FALSE_RADAR_EXT); | ||
646 | PHY_ERR("CCK-TIMING", ATH9K_PHYERR_CCK_TIMING); | ||
647 | PHY_ERR("CCK-HEADER-CRC", ATH9K_PHYERR_CCK_HEADER_CRC); | ||
648 | PHY_ERR("CCK-RATE", ATH9K_PHYERR_CCK_RATE_ILLEGAL); | ||
649 | PHY_ERR("CCK-SERVICE", ATH9K_PHYERR_CCK_SERVICE); | ||
650 | PHY_ERR("CCK-RESTART", ATH9K_PHYERR_CCK_RESTART); | ||
651 | PHY_ERR("CCK-LENGTH", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL); | ||
652 | PHY_ERR("CCK-POWER-DROP", ATH9K_PHYERR_CCK_POWER_DROP); | ||
653 | PHY_ERR("HT-CRC", ATH9K_PHYERR_HT_CRC_ERROR); | ||
654 | PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL); | ||
655 | PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL); | ||
656 | |||
657 | retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
658 | kfree(buf); | ||
659 | |||
660 | return retval; | ||
661 | |||
662 | #undef PHY_ERR | ||
663 | } | ||
664 | |||
665 | void ath_debug_stat_rx(struct ath_softc *sc, struct ath_buf *bf) | ||
666 | { | ||
667 | #define RX_STAT_INC(c) sc->debug.stats.rxstats.c++ | ||
668 | #define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++ | ||
669 | |||
670 | struct ath_desc *ds = bf->bf_desc; | ||
671 | u32 phyerr; | ||
672 | |||
673 | if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC) | ||
674 | RX_STAT_INC(crc_err); | ||
675 | if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT) | ||
676 | RX_STAT_INC(decrypt_crc_err); | ||
677 | if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC) | ||
678 | RX_STAT_INC(mic_err); | ||
679 | if (ds->ds_rxstat.rs_status & ATH9K_RX_DELIM_CRC_PRE) | ||
680 | RX_STAT_INC(pre_delim_crc_err); | ||
681 | if (ds->ds_rxstat.rs_status & ATH9K_RX_DELIM_CRC_POST) | ||
682 | RX_STAT_INC(post_delim_crc_err); | ||
683 | if (ds->ds_rxstat.rs_status & ATH9K_RX_DECRYPT_BUSY) | ||
684 | RX_STAT_INC(decrypt_busy_err); | ||
685 | |||
686 | if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY) { | ||
687 | RX_STAT_INC(phy_err); | ||
688 | phyerr = ds->ds_rxstat.rs_phyerr & 0x24; | ||
689 | RX_PHY_ERR_INC(phyerr); | ||
690 | } | ||
691 | |||
692 | #undef RX_STAT_INC | ||
693 | #undef RX_PHY_ERR_INC | ||
694 | } | ||
695 | |||
696 | static const struct file_operations fops_recv = { | ||
697 | .read = read_file_recv, | ||
698 | .open = ath9k_debugfs_open, | ||
699 | .owner = THIS_MODULE | ||
700 | }; | ||
701 | |||
557 | int ath9k_init_debug(struct ath_hw *ah) | 702 | int ath9k_init_debug(struct ath_hw *ah) |
558 | { | 703 | { |
559 | struct ath_common *common = ath9k_hw_common(ah); | 704 | struct ath_common *common = ath9k_hw_common(ah); |
@@ -606,6 +751,13 @@ int ath9k_init_debug(struct ath_hw *ah) | |||
606 | if (!sc->debug.debugfs_xmit) | 751 | if (!sc->debug.debugfs_xmit) |
607 | goto err; | 752 | goto err; |
608 | 753 | ||
754 | sc->debug.debugfs_recv = debugfs_create_file("recv", | ||
755 | S_IRUSR, | ||
756 | sc->debug.debugfs_phy, | ||
757 | sc, &fops_recv); | ||
758 | if (!sc->debug.debugfs_recv) | ||
759 | goto err; | ||
760 | |||
609 | return 0; | 761 | return 0; |
610 | err: | 762 | err: |
611 | ath9k_exit_debug(ah); | 763 | ath9k_exit_debug(ah); |
@@ -617,6 +769,7 @@ void ath9k_exit_debug(struct ath_hw *ah) | |||
617 | struct ath_common *common = ath9k_hw_common(ah); | 769 | struct ath_common *common = ath9k_hw_common(ah); |
618 | struct ath_softc *sc = (struct ath_softc *) common->priv; | 770 | struct ath_softc *sc = (struct ath_softc *) common->priv; |
619 | 771 | ||
772 | debugfs_remove(sc->debug.debugfs_recv); | ||
620 | debugfs_remove(sc->debug.debugfs_xmit); | 773 | debugfs_remove(sc->debug.debugfs_xmit); |
621 | debugfs_remove(sc->debug.debugfs_wiphy); | 774 | debugfs_remove(sc->debug.debugfs_wiphy); |
622 | debugfs_remove(sc->debug.debugfs_rcstat); | 775 | debugfs_remove(sc->debug.debugfs_rcstat); |
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 536663e3ee1..86780e68b31 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
@@ -116,10 +116,35 @@ struct ath_tx_stats { | |||
116 | u32 delim_underrun; | 116 | u32 delim_underrun; |
117 | }; | 117 | }; |
118 | 118 | ||
119 | /** | ||
120 | * struct ath_rx_stats - RX Statistics | ||
121 | * @crc_err: No. of frames with incorrect CRC value | ||
122 | * @decrypt_crc_err: No. of frames whose CRC check failed after | ||
123 | decryption process completed | ||
124 | * @phy_err: No. of frames whose reception failed because the PHY | ||
125 | encountered an error | ||
126 | * @mic_err: No. of frames with incorrect TKIP MIC verification failure | ||
127 | * @pre_delim_crc_err: Pre-Frame delimiter CRC error detections | ||
128 | * @post_delim_crc_err: Post-Frame delimiter CRC error detections | ||
129 | * @decrypt_busy_err: Decryption interruptions counter | ||
130 | * @phy_err_stats: Individual PHY error statistics | ||
131 | */ | ||
132 | struct ath_rx_stats { | ||
133 | u32 crc_err; | ||
134 | u32 decrypt_crc_err; | ||
135 | u32 phy_err; | ||
136 | u32 mic_err; | ||
137 | u32 pre_delim_crc_err; | ||
138 | u32 post_delim_crc_err; | ||
139 | u32 decrypt_busy_err; | ||
140 | u32 phy_err_stats[ATH9K_PHYERR_MAX]; | ||
141 | }; | ||
142 | |||
119 | struct ath_stats { | 143 | struct ath_stats { |
120 | struct ath_interrupt_stats istats; | 144 | struct ath_interrupt_stats istats; |
121 | struct ath_rc_stats rcstats[RATE_TABLE_SIZE]; | 145 | struct ath_rc_stats rcstats[RATE_TABLE_SIZE]; |
122 | struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES]; | 146 | struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES]; |
147 | struct ath_rx_stats rxstats; | ||
123 | }; | 148 | }; |
124 | 149 | ||
125 | struct ath9k_debug { | 150 | struct ath9k_debug { |
@@ -130,6 +155,7 @@ struct ath9k_debug { | |||
130 | struct dentry *debugfs_rcstat; | 155 | struct dentry *debugfs_rcstat; |
131 | struct dentry *debugfs_wiphy; | 156 | struct dentry *debugfs_wiphy; |
132 | struct dentry *debugfs_xmit; | 157 | struct dentry *debugfs_xmit; |
158 | struct dentry *debugfs_recv; | ||
133 | struct ath_stats stats; | 159 | struct ath_stats stats; |
134 | }; | 160 | }; |
135 | 161 | ||
@@ -142,6 +168,7 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); | |||
142 | void ath_debug_stat_rc(struct ath_softc *sc, int final_rate); | 168 | void ath_debug_stat_rc(struct ath_softc *sc, int final_rate); |
143 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, | 169 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, |
144 | struct ath_buf *bf); | 170 | struct ath_buf *bf); |
171 | void ath_debug_stat_rx(struct ath_softc *sc, struct ath_buf *bf); | ||
145 | void ath_debug_stat_retries(struct ath_softc *sc, int rix, | 172 | void ath_debug_stat_retries(struct ath_softc *sc, int rix, |
146 | int xretries, int retries, u8 per); | 173 | int xretries, int retries, u8 per); |
147 | 174 | ||
@@ -181,6 +208,11 @@ static inline void ath_debug_stat_tx(struct ath_softc *sc, | |||
181 | { | 208 | { |
182 | } | 209 | } |
183 | 210 | ||
211 | static inline void ath_debug_stat_rx(struct ath_softc *sc, | ||
212 | struct ath_buf *bf) | ||
213 | { | ||
214 | } | ||
215 | |||
184 | static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix, | 216 | static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix, |
185 | int xretries, int retries, u8 per) | 217 | int xretries, int retries, u8 per) |
186 | { | 218 | { |
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c new file mode 100644 index 00000000000..deab8beb068 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/gpio.c | |||
@@ -0,0 +1,442 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "ath9k.h" | ||
18 | |||
19 | /********************************/ | ||
20 | /* LED functions */ | ||
21 | /********************************/ | ||
22 | |||
23 | static void ath_led_blink_work(struct work_struct *work) | ||
24 | { | ||
25 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
26 | ath_led_blink_work.work); | ||
27 | |||
28 | if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED)) | ||
29 | return; | ||
30 | |||
31 | if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) || | ||
32 | (sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE)) | ||
33 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0); | ||
34 | else | ||
35 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, | ||
36 | (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0); | ||
37 | |||
38 | ieee80211_queue_delayed_work(sc->hw, | ||
39 | &sc->ath_led_blink_work, | ||
40 | (sc->sc_flags & SC_OP_LED_ON) ? | ||
41 | msecs_to_jiffies(sc->led_off_duration) : | ||
42 | msecs_to_jiffies(sc->led_on_duration)); | ||
43 | |||
44 | sc->led_on_duration = sc->led_on_cnt ? | ||
45 | max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) : | ||
46 | ATH_LED_ON_DURATION_IDLE; | ||
47 | sc->led_off_duration = sc->led_off_cnt ? | ||
48 | max((ATH_LED_OFF_DURATION_IDLE - sc->led_off_cnt), 10) : | ||
49 | ATH_LED_OFF_DURATION_IDLE; | ||
50 | sc->led_on_cnt = sc->led_off_cnt = 0; | ||
51 | if (sc->sc_flags & SC_OP_LED_ON) | ||
52 | sc->sc_flags &= ~SC_OP_LED_ON; | ||
53 | else | ||
54 | sc->sc_flags |= SC_OP_LED_ON; | ||
55 | } | ||
56 | |||
57 | static void ath_led_brightness(struct led_classdev *led_cdev, | ||
58 | enum led_brightness brightness) | ||
59 | { | ||
60 | struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev); | ||
61 | struct ath_softc *sc = led->sc; | ||
62 | |||
63 | switch (brightness) { | ||
64 | case LED_OFF: | ||
65 | if (led->led_type == ATH_LED_ASSOC || | ||
66 | led->led_type == ATH_LED_RADIO) { | ||
67 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, | ||
68 | (led->led_type == ATH_LED_RADIO)); | ||
69 | sc->sc_flags &= ~SC_OP_LED_ASSOCIATED; | ||
70 | if (led->led_type == ATH_LED_RADIO) | ||
71 | sc->sc_flags &= ~SC_OP_LED_ON; | ||
72 | } else { | ||
73 | sc->led_off_cnt++; | ||
74 | } | ||
75 | break; | ||
76 | case LED_FULL: | ||
77 | if (led->led_type == ATH_LED_ASSOC) { | ||
78 | sc->sc_flags |= SC_OP_LED_ASSOCIATED; | ||
79 | ieee80211_queue_delayed_work(sc->hw, | ||
80 | &sc->ath_led_blink_work, 0); | ||
81 | } else if (led->led_type == ATH_LED_RADIO) { | ||
82 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0); | ||
83 | sc->sc_flags |= SC_OP_LED_ON; | ||
84 | } else { | ||
85 | sc->led_on_cnt++; | ||
86 | } | ||
87 | break; | ||
88 | default: | ||
89 | break; | ||
90 | } | ||
91 | } | ||
92 | |||
93 | static int ath_register_led(struct ath_softc *sc, struct ath_led *led, | ||
94 | char *trigger) | ||
95 | { | ||
96 | int ret; | ||
97 | |||
98 | led->sc = sc; | ||
99 | led->led_cdev.name = led->name; | ||
100 | led->led_cdev.default_trigger = trigger; | ||
101 | led->led_cdev.brightness_set = ath_led_brightness; | ||
102 | |||
103 | ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev); | ||
104 | if (ret) | ||
105 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, | ||
106 | "Failed to register led:%s", led->name); | ||
107 | else | ||
108 | led->registered = 1; | ||
109 | return ret; | ||
110 | } | ||
111 | |||
112 | static void ath_unregister_led(struct ath_led *led) | ||
113 | { | ||
114 | if (led->registered) { | ||
115 | led_classdev_unregister(&led->led_cdev); | ||
116 | led->registered = 0; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | void ath_deinit_leds(struct ath_softc *sc) | ||
121 | { | ||
122 | ath_unregister_led(&sc->assoc_led); | ||
123 | sc->sc_flags &= ~SC_OP_LED_ASSOCIATED; | ||
124 | ath_unregister_led(&sc->tx_led); | ||
125 | ath_unregister_led(&sc->rx_led); | ||
126 | ath_unregister_led(&sc->radio_led); | ||
127 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); | ||
128 | } | ||
129 | |||
130 | void ath_init_leds(struct ath_softc *sc) | ||
131 | { | ||
132 | char *trigger; | ||
133 | int ret; | ||
134 | |||
135 | if (AR_SREV_9287(sc->sc_ah)) | ||
136 | sc->sc_ah->led_pin = ATH_LED_PIN_9287; | ||
137 | else | ||
138 | sc->sc_ah->led_pin = ATH_LED_PIN_DEF; | ||
139 | |||
140 | /* Configure gpio 1 for output */ | ||
141 | ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin, | ||
142 | AR_GPIO_OUTPUT_MUX_AS_OUTPUT); | ||
143 | /* LED off, active low */ | ||
144 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); | ||
145 | |||
146 | INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work); | ||
147 | |||
148 | trigger = ieee80211_get_radio_led_name(sc->hw); | ||
149 | snprintf(sc->radio_led.name, sizeof(sc->radio_led.name), | ||
150 | "ath9k-%s::radio", wiphy_name(sc->hw->wiphy)); | ||
151 | ret = ath_register_led(sc, &sc->radio_led, trigger); | ||
152 | sc->radio_led.led_type = ATH_LED_RADIO; | ||
153 | if (ret) | ||
154 | goto fail; | ||
155 | |||
156 | trigger = ieee80211_get_assoc_led_name(sc->hw); | ||
157 | snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name), | ||
158 | "ath9k-%s::assoc", wiphy_name(sc->hw->wiphy)); | ||
159 | ret = ath_register_led(sc, &sc->assoc_led, trigger); | ||
160 | sc->assoc_led.led_type = ATH_LED_ASSOC; | ||
161 | if (ret) | ||
162 | goto fail; | ||
163 | |||
164 | trigger = ieee80211_get_tx_led_name(sc->hw); | ||
165 | snprintf(sc->tx_led.name, sizeof(sc->tx_led.name), | ||
166 | "ath9k-%s::tx", wiphy_name(sc->hw->wiphy)); | ||
167 | ret = ath_register_led(sc, &sc->tx_led, trigger); | ||
168 | sc->tx_led.led_type = ATH_LED_TX; | ||
169 | if (ret) | ||
170 | goto fail; | ||
171 | |||
172 | trigger = ieee80211_get_rx_led_name(sc->hw); | ||
173 | snprintf(sc->rx_led.name, sizeof(sc->rx_led.name), | ||
174 | "ath9k-%s::rx", wiphy_name(sc->hw->wiphy)); | ||
175 | ret = ath_register_led(sc, &sc->rx_led, trigger); | ||
176 | sc->rx_led.led_type = ATH_LED_RX; | ||
177 | if (ret) | ||
178 | goto fail; | ||
179 | |||
180 | return; | ||
181 | |||
182 | fail: | ||
183 | cancel_delayed_work_sync(&sc->ath_led_blink_work); | ||
184 | ath_deinit_leds(sc); | ||
185 | } | ||
186 | |||
187 | /*******************/ | ||
188 | /* Rfkill */ | ||
189 | /*******************/ | ||
190 | |||
191 | static bool ath_is_rfkill_set(struct ath_softc *sc) | ||
192 | { | ||
193 | struct ath_hw *ah = sc->sc_ah; | ||
194 | |||
195 | return ath9k_hw_gpio_get(ah, ah->rfkill_gpio) == | ||
196 | ah->rfkill_polarity; | ||
197 | } | ||
198 | |||
199 | void ath9k_rfkill_poll_state(struct ieee80211_hw *hw) | ||
200 | { | ||
201 | struct ath_wiphy *aphy = hw->priv; | ||
202 | struct ath_softc *sc = aphy->sc; | ||
203 | bool blocked = !!ath_is_rfkill_set(sc); | ||
204 | |||
205 | wiphy_rfkill_set_hw_state(hw->wiphy, blocked); | ||
206 | } | ||
207 | |||
208 | void ath_start_rfkill_poll(struct ath_softc *sc) | ||
209 | { | ||
210 | struct ath_hw *ah = sc->sc_ah; | ||
211 | |||
212 | if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | ||
213 | wiphy_rfkill_start_polling(sc->hw->wiphy); | ||
214 | } | ||
215 | |||
216 | /******************/ | ||
217 | /* BTCOEX */ | ||
218 | /******************/ | ||
219 | |||
220 | /* | ||
221 | * Detects if there is any priority bt traffic | ||
222 | */ | ||
223 | static void ath_detect_bt_priority(struct ath_softc *sc) | ||
224 | { | ||
225 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
226 | struct ath_hw *ah = sc->sc_ah; | ||
227 | |||
228 | if (ath9k_hw_gpio_get(sc->sc_ah, ah->btcoex_hw.btpriority_gpio)) | ||
229 | btcoex->bt_priority_cnt++; | ||
230 | |||
231 | if (time_after(jiffies, btcoex->bt_priority_time + | ||
232 | msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) { | ||
233 | sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN); | ||
234 | /* Detect if colocated bt started scanning */ | ||
235 | if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) { | ||
236 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX, | ||
237 | "BT scan detected"); | ||
238 | sc->sc_flags |= (SC_OP_BT_SCAN | | ||
239 | SC_OP_BT_PRIORITY_DETECTED); | ||
240 | } else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { | ||
241 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX, | ||
242 | "BT priority traffic detected"); | ||
243 | sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED; | ||
244 | } | ||
245 | |||
246 | btcoex->bt_priority_cnt = 0; | ||
247 | btcoex->bt_priority_time = jiffies; | ||
248 | } | ||
249 | } | ||
250 | |||
251 | /* | ||
252 | * Configures appropriate weight based on stomp type. | ||
253 | */ | ||
254 | static void ath9k_btcoex_bt_stomp(struct ath_softc *sc, | ||
255 | enum ath_stomp_type stomp_type) | ||
256 | { | ||
257 | struct ath_hw *ah = sc->sc_ah; | ||
258 | |||
259 | switch (stomp_type) { | ||
260 | case ATH_BTCOEX_STOMP_ALL: | ||
261 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
262 | AR_STOMP_ALL_WLAN_WGHT); | ||
263 | break; | ||
264 | case ATH_BTCOEX_STOMP_LOW: | ||
265 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
266 | AR_STOMP_LOW_WLAN_WGHT); | ||
267 | break; | ||
268 | case ATH_BTCOEX_STOMP_NONE: | ||
269 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
270 | AR_STOMP_NONE_WLAN_WGHT); | ||
271 | break; | ||
272 | default: | ||
273 | ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | ||
274 | "Invalid Stomptype\n"); | ||
275 | break; | ||
276 | } | ||
277 | |||
278 | ath9k_hw_btcoex_enable(ah); | ||
279 | } | ||
280 | |||
281 | static void ath9k_gen_timer_start(struct ath_hw *ah, | ||
282 | struct ath_gen_timer *timer, | ||
283 | u32 timer_next, | ||
284 | u32 timer_period) | ||
285 | { | ||
286 | struct ath_common *common = ath9k_hw_common(ah); | ||
287 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
288 | |||
289 | ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period); | ||
290 | |||
291 | if ((sc->imask & ATH9K_INT_GENTIMER) == 0) { | ||
292 | ath9k_hw_set_interrupts(ah, 0); | ||
293 | sc->imask |= ATH9K_INT_GENTIMER; | ||
294 | ath9k_hw_set_interrupts(ah, sc->imask); | ||
295 | } | ||
296 | } | ||
297 | |||
298 | static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer) | ||
299 | { | ||
300 | struct ath_common *common = ath9k_hw_common(ah); | ||
301 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
302 | struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; | ||
303 | |||
304 | ath9k_hw_gen_timer_stop(ah, timer); | ||
305 | |||
306 | /* if no timer is enabled, turn off interrupt mask */ | ||
307 | if (timer_table->timer_mask.val == 0) { | ||
308 | ath9k_hw_set_interrupts(ah, 0); | ||
309 | sc->imask &= ~ATH9K_INT_GENTIMER; | ||
310 | ath9k_hw_set_interrupts(ah, sc->imask); | ||
311 | } | ||
312 | } | ||
313 | |||
314 | /* | ||
315 | * This is the master bt coex timer which runs for every | ||
316 | * 45ms, bt traffic will be given priority during 55% of this | ||
317 | * period while wlan gets remaining 45% | ||
318 | */ | ||
319 | static void ath_btcoex_period_timer(unsigned long data) | ||
320 | { | ||
321 | struct ath_softc *sc = (struct ath_softc *) data; | ||
322 | struct ath_hw *ah = sc->sc_ah; | ||
323 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
324 | u32 timer_period; | ||
325 | bool is_btscan; | ||
326 | |||
327 | ath_detect_bt_priority(sc); | ||
328 | |||
329 | is_btscan = sc->sc_flags & SC_OP_BT_SCAN; | ||
330 | |||
331 | spin_lock_bh(&btcoex->btcoex_lock); | ||
332 | |||
333 | ath9k_btcoex_bt_stomp(sc, is_btscan ? ATH_BTCOEX_STOMP_ALL : | ||
334 | btcoex->bt_stomp_type); | ||
335 | |||
336 | spin_unlock_bh(&btcoex->btcoex_lock); | ||
337 | |||
338 | if (btcoex->btcoex_period != btcoex->btcoex_no_stomp) { | ||
339 | if (btcoex->hw_timer_enabled) | ||
340 | ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer); | ||
341 | |||
342 | timer_period = is_btscan ? btcoex->btscan_no_stomp : | ||
343 | btcoex->btcoex_no_stomp; | ||
344 | ath9k_gen_timer_start(ah, | ||
345 | btcoex->no_stomp_timer, | ||
346 | (ath9k_hw_gettsf32(ah) + | ||
347 | timer_period), timer_period * 10); | ||
348 | btcoex->hw_timer_enabled = true; | ||
349 | } | ||
350 | |||
351 | mod_timer(&btcoex->period_timer, jiffies + | ||
352 | msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD)); | ||
353 | } | ||
354 | |||
355 | /* | ||
356 | * Generic tsf based hw timer which configures weight | ||
357 | * registers to time slice between wlan and bt traffic | ||
358 | */ | ||
359 | static void ath_btcoex_no_stomp_timer(void *arg) | ||
360 | { | ||
361 | struct ath_softc *sc = (struct ath_softc *)arg; | ||
362 | struct ath_hw *ah = sc->sc_ah; | ||
363 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
364 | bool is_btscan = sc->sc_flags & SC_OP_BT_SCAN; | ||
365 | |||
366 | ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | ||
367 | "no stomp timer running \n"); | ||
368 | |||
369 | spin_lock_bh(&btcoex->btcoex_lock); | ||
370 | |||
371 | if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) | ||
372 | ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_NONE); | ||
373 | else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) | ||
374 | ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_LOW); | ||
375 | |||
376 | spin_unlock_bh(&btcoex->btcoex_lock); | ||
377 | } | ||
378 | |||
379 | int ath_init_btcoex_timer(struct ath_softc *sc) | ||
380 | { | ||
381 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
382 | |||
383 | btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000; | ||
384 | btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * | ||
385 | btcoex->btcoex_period / 100; | ||
386 | btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) * | ||
387 | btcoex->btcoex_period / 100; | ||
388 | |||
389 | setup_timer(&btcoex->period_timer, ath_btcoex_period_timer, | ||
390 | (unsigned long) sc); | ||
391 | |||
392 | spin_lock_init(&btcoex->btcoex_lock); | ||
393 | |||
394 | btcoex->no_stomp_timer = ath_gen_timer_alloc(sc->sc_ah, | ||
395 | ath_btcoex_no_stomp_timer, | ||
396 | ath_btcoex_no_stomp_timer, | ||
397 | (void *) sc, AR_FIRST_NDP_TIMER); | ||
398 | |||
399 | if (!btcoex->no_stomp_timer) | ||
400 | return -ENOMEM; | ||
401 | |||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | /* | ||
406 | * (Re)start btcoex timers | ||
407 | */ | ||
408 | void ath9k_btcoex_timer_resume(struct ath_softc *sc) | ||
409 | { | ||
410 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
411 | struct ath_hw *ah = sc->sc_ah; | ||
412 | |||
413 | ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | ||
414 | "Starting btcoex timers"); | ||
415 | |||
416 | /* make sure duty cycle timer is also stopped when resuming */ | ||
417 | if (btcoex->hw_timer_enabled) | ||
418 | ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer); | ||
419 | |||
420 | btcoex->bt_priority_cnt = 0; | ||
421 | btcoex->bt_priority_time = jiffies; | ||
422 | sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN); | ||
423 | |||
424 | mod_timer(&btcoex->period_timer, jiffies); | ||
425 | } | ||
426 | |||
427 | |||
428 | /* | ||
429 | * Pause btcoex timer and bt duty cycle timer | ||
430 | */ | ||
431 | void ath9k_btcoex_timer_pause(struct ath_softc *sc) | ||
432 | { | ||
433 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
434 | struct ath_hw *ah = sc->sc_ah; | ||
435 | |||
436 | del_timer_sync(&btcoex->period_timer); | ||
437 | |||
438 | if (btcoex->hw_timer_enabled) | ||
439 | ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer); | ||
440 | |||
441 | btcoex->hw_timer_enabled = false; | ||
442 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index ae371448b5a..2e767cf22f1 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -52,28 +52,6 @@ module_exit(ath9k_exit); | |||
52 | /* Helper Functions */ | 52 | /* Helper Functions */ |
53 | /********************/ | 53 | /********************/ |
54 | 54 | ||
55 | static u32 ath9k_hw_mac_usec(struct ath_hw *ah, u32 clks) | ||
56 | { | ||
57 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; | ||
58 | |||
59 | if (!ah->curchan) /* should really check for CCK instead */ | ||
60 | return clks / ATH9K_CLOCK_RATE_CCK; | ||
61 | if (conf->channel->band == IEEE80211_BAND_2GHZ) | ||
62 | return clks / ATH9K_CLOCK_RATE_2GHZ_OFDM; | ||
63 | |||
64 | return clks / ATH9K_CLOCK_RATE_5GHZ_OFDM; | ||
65 | } | ||
66 | |||
67 | static u32 ath9k_hw_mac_to_usec(struct ath_hw *ah, u32 clks) | ||
68 | { | ||
69 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; | ||
70 | |||
71 | if (conf_is_ht40(conf)) | ||
72 | return ath9k_hw_mac_usec(ah, clks) / 2; | ||
73 | else | ||
74 | return ath9k_hw_mac_usec(ah, clks); | ||
75 | } | ||
76 | |||
77 | static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs) | 55 | static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs) |
78 | { | 56 | { |
79 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; | 57 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; |
@@ -343,30 +321,6 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah) | |||
343 | return true; | 321 | return true; |
344 | } | 322 | } |
345 | 323 | ||
346 | static const char *ath9k_hw_devname(u16 devid) | ||
347 | { | ||
348 | switch (devid) { | ||
349 | case AR5416_DEVID_PCI: | ||
350 | return "Atheros 5416"; | ||
351 | case AR5416_DEVID_PCIE: | ||
352 | return "Atheros 5418"; | ||
353 | case AR9160_DEVID_PCI: | ||
354 | return "Atheros 9160"; | ||
355 | case AR5416_AR9100_DEVID: | ||
356 | return "Atheros 9100"; | ||
357 | case AR9280_DEVID_PCI: | ||
358 | case AR9280_DEVID_PCIE: | ||
359 | return "Atheros 9280"; | ||
360 | case AR9285_DEVID_PCIE: | ||
361 | return "Atheros 9285"; | ||
362 | case AR5416_DEVID_AR9287_PCI: | ||
363 | case AR5416_DEVID_AR9287_PCIE: | ||
364 | return "Atheros 9287"; | ||
365 | } | ||
366 | |||
367 | return NULL; | ||
368 | } | ||
369 | |||
370 | static void ath9k_hw_init_config(struct ath_hw *ah) | 324 | static void ath9k_hw_init_config(struct ath_hw *ah) |
371 | { | 325 | { |
372 | int i; | 326 | int i; |
@@ -380,7 +334,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah) | |||
380 | ah->config.pcie_clock_req = 0; | 334 | ah->config.pcie_clock_req = 0; |
381 | ah->config.pcie_waen = 0; | 335 | ah->config.pcie_waen = 0; |
382 | ah->config.analog_shiftreg = 1; | 336 | ah->config.analog_shiftreg = 1; |
383 | ah->config.ht_enable = 1; | ||
384 | ah->config.ofdm_trig_low = 200; | 337 | ah->config.ofdm_trig_low = 200; |
385 | ah->config.ofdm_trig_high = 500; | 338 | ah->config.ofdm_trig_high = 500; |
386 | ah->config.cck_trig_high = 200; | 339 | ah->config.cck_trig_high = 200; |
@@ -392,7 +345,12 @@ static void ath9k_hw_init_config(struct ath_hw *ah) | |||
392 | ah->config.spurchans[i][1] = AR_NO_SPUR; | 345 | ah->config.spurchans[i][1] = AR_NO_SPUR; |
393 | } | 346 | } |
394 | 347 | ||
395 | ah->config.intr_mitigation = true; | 348 | if (ah->hw_version.devid != AR2427_DEVID_PCIE) |
349 | ah->config.ht_enable = 1; | ||
350 | else | ||
351 | ah->config.ht_enable = 0; | ||
352 | |||
353 | ah->config.rx_intr_mitigation = true; | ||
396 | 354 | ||
397 | /* | 355 | /* |
398 | * We need this for PCI devices only (Cardbus, PCI, miniPCI) | 356 | * We need this for PCI devices only (Cardbus, PCI, miniPCI) |
@@ -437,8 +395,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah) | |||
437 | ah->beacon_interval = 100; | 395 | ah->beacon_interval = 100; |
438 | ah->enable_32kHz_clock = DONT_USE_32KHZ; | 396 | ah->enable_32kHz_clock = DONT_USE_32KHZ; |
439 | ah->slottime = (u32) -1; | 397 | ah->slottime = (u32) -1; |
440 | ah->acktimeout = (u32) -1; | ||
441 | ah->ctstimeout = (u32) -1; | ||
442 | ah->globaltxtimeout = (u32) -1; | 398 | ah->globaltxtimeout = (u32) -1; |
443 | ah->power_mode = ATH9K_PM_UNDEFINED; | 399 | ah->power_mode = ATH9K_PM_UNDEFINED; |
444 | } | 400 | } |
@@ -590,6 +546,7 @@ static bool ath9k_hw_devid_supported(u16 devid) | |||
590 | case AR5416_DEVID_AR9287_PCI: | 546 | case AR5416_DEVID_AR9287_PCI: |
591 | case AR5416_DEVID_AR9287_PCIE: | 547 | case AR5416_DEVID_AR9287_PCIE: |
592 | case AR9271_USB: | 548 | case AR9271_USB: |
549 | case AR2427_DEVID_PCIE: | ||
593 | return true; | 550 | return true; |
594 | default: | 551 | default: |
595 | break; | 552 | break; |
@@ -1183,7 +1140,7 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, | |||
1183 | AR_IMR_RXORN | | 1140 | AR_IMR_RXORN | |
1184 | AR_IMR_BCNMISC; | 1141 | AR_IMR_BCNMISC; |
1185 | 1142 | ||
1186 | if (ah->config.intr_mitigation) | 1143 | if (ah->config.rx_intr_mitigation) |
1187 | ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR; | 1144 | ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR; |
1188 | else | 1145 | else |
1189 | ah->mask_reg |= AR_IMR_RXOK; | 1146 | ah->mask_reg |= AR_IMR_RXOK; |
@@ -1203,34 +1160,25 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, | |||
1203 | } | 1160 | } |
1204 | } | 1161 | } |
1205 | 1162 | ||
1206 | static bool ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us) | 1163 | static void ath9k_hw_setslottime(struct ath_hw *ah, u32 us) |
1207 | { | 1164 | { |
1208 | if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) { | 1165 | u32 val = ath9k_hw_mac_to_clks(ah, us); |
1209 | ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, | 1166 | val = min(val, (u32) 0xFFFF); |
1210 | "bad ack timeout %u\n", us); | 1167 | REG_WRITE(ah, AR_D_GBL_IFS_SLOT, val); |
1211 | ah->acktimeout = (u32) -1; | ||
1212 | return false; | ||
1213 | } else { | ||
1214 | REG_RMW_FIELD(ah, AR_TIME_OUT, | ||
1215 | AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us)); | ||
1216 | ah->acktimeout = us; | ||
1217 | return true; | ||
1218 | } | ||
1219 | } | 1168 | } |
1220 | 1169 | ||
1221 | static bool ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us) | 1170 | static void ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us) |
1222 | { | 1171 | { |
1223 | if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) { | 1172 | u32 val = ath9k_hw_mac_to_clks(ah, us); |
1224 | ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, | 1173 | val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_ACK)); |
1225 | "bad cts timeout %u\n", us); | 1174 | REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_ACK, val); |
1226 | ah->ctstimeout = (u32) -1; | 1175 | } |
1227 | return false; | 1176 | |
1228 | } else { | 1177 | static void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us) |
1229 | REG_RMW_FIELD(ah, AR_TIME_OUT, | 1178 | { |
1230 | AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us)); | 1179 | u32 val = ath9k_hw_mac_to_clks(ah, us); |
1231 | ah->ctstimeout = us; | 1180 | val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_CTS)); |
1232 | return true; | 1181 | REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_CTS, val); |
1233 | } | ||
1234 | } | 1182 | } |
1235 | 1183 | ||
1236 | static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu) | 1184 | static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu) |
@@ -1247,31 +1195,48 @@ static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu) | |||
1247 | } | 1195 | } |
1248 | } | 1196 | } |
1249 | 1197 | ||
1250 | static void ath9k_hw_init_user_settings(struct ath_hw *ah) | 1198 | void ath9k_hw_init_global_settings(struct ath_hw *ah) |
1251 | { | 1199 | { |
1200 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; | ||
1201 | int acktimeout; | ||
1202 | int slottime; | ||
1203 | int sifstime; | ||
1204 | |||
1252 | ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n", | 1205 | ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n", |
1253 | ah->misc_mode); | 1206 | ah->misc_mode); |
1254 | 1207 | ||
1255 | if (ah->misc_mode != 0) | 1208 | if (ah->misc_mode != 0) |
1256 | REG_WRITE(ah, AR_PCU_MISC, | 1209 | REG_WRITE(ah, AR_PCU_MISC, |
1257 | REG_READ(ah, AR_PCU_MISC) | ah->misc_mode); | 1210 | REG_READ(ah, AR_PCU_MISC) | ah->misc_mode); |
1258 | if (ah->slottime != (u32) -1) | 1211 | |
1259 | ath9k_hw_setslottime(ah, ah->slottime); | 1212 | if (conf->channel && conf->channel->band == IEEE80211_BAND_5GHZ) |
1260 | if (ah->acktimeout != (u32) -1) | 1213 | sifstime = 16; |
1261 | ath9k_hw_set_ack_timeout(ah, ah->acktimeout); | 1214 | else |
1262 | if (ah->ctstimeout != (u32) -1) | 1215 | sifstime = 10; |
1263 | ath9k_hw_set_cts_timeout(ah, ah->ctstimeout); | 1216 | |
1217 | /* As defined by IEEE 802.11-2007 17.3.8.6 */ | ||
1218 | slottime = ah->slottime + 3 * ah->coverage_class; | ||
1219 | acktimeout = slottime + sifstime; | ||
1220 | |||
1221 | /* | ||
1222 | * Workaround for early ACK timeouts, add an offset to match the | ||
1223 | * initval's 64us ack timeout value. | ||
1224 | * This was initially only meant to work around an issue with delayed | ||
1225 | * BA frames in some implementations, but it has been found to fix ACK | ||
1226 | * timeout issues in other cases as well. | ||
1227 | */ | ||
1228 | if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ) | ||
1229 | acktimeout += 64 - sifstime - ah->slottime; | ||
1230 | |||
1231 | ath9k_hw_setslottime(ah, slottime); | ||
1232 | ath9k_hw_set_ack_timeout(ah, acktimeout); | ||
1233 | ath9k_hw_set_cts_timeout(ah, acktimeout); | ||
1264 | if (ah->globaltxtimeout != (u32) -1) | 1234 | if (ah->globaltxtimeout != (u32) -1) |
1265 | ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout); | 1235 | ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout); |
1266 | } | 1236 | } |
1237 | EXPORT_SYMBOL(ath9k_hw_init_global_settings); | ||
1267 | 1238 | ||
1268 | const char *ath9k_hw_probe(u16 vendorid, u16 devid) | 1239 | void ath9k_hw_deinit(struct ath_hw *ah) |
1269 | { | ||
1270 | return vendorid == ATHEROS_VENDOR_ID ? | ||
1271 | ath9k_hw_devname(devid) : NULL; | ||
1272 | } | ||
1273 | |||
1274 | void ath9k_hw_detach(struct ath_hw *ah) | ||
1275 | { | 1240 | { |
1276 | struct ath_common *common = ath9k_hw_common(ah); | 1241 | struct ath_common *common = ath9k_hw_common(ah); |
1277 | 1242 | ||
@@ -1289,7 +1254,7 @@ free_hw: | |||
1289 | kfree(ah); | 1254 | kfree(ah); |
1290 | ah = NULL; | 1255 | ah = NULL; |
1291 | } | 1256 | } |
1292 | EXPORT_SYMBOL(ath9k_hw_detach); | 1257 | EXPORT_SYMBOL(ath9k_hw_deinit); |
1293 | 1258 | ||
1294 | /*******/ | 1259 | /*******/ |
1295 | /* INI */ | 1260 | /* INI */ |
@@ -1345,6 +1310,16 @@ static void ath9k_hw_override_ini(struct ath_hw *ah, | |||
1345 | * Necessary to avoid issues on AR5416 2.0 | 1310 | * Necessary to avoid issues on AR5416 2.0 |
1346 | */ | 1311 | */ |
1347 | REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); | 1312 | REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); |
1313 | |||
1314 | /* | ||
1315 | * Disable RIFS search on some chips to avoid baseband | ||
1316 | * hang issues. | ||
1317 | */ | ||
1318 | if (AR_SREV_9100(ah) || AR_SREV_9160(ah)) { | ||
1319 | val = REG_READ(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS); | ||
1320 | val &= ~AR_PHY_RIFS_INIT_DELAY; | ||
1321 | REG_WRITE(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, val); | ||
1322 | } | ||
1348 | } | 1323 | } |
1349 | 1324 | ||
1350 | static u32 ath9k_hw_def_ini_fixup(struct ath_hw *ah, | 1325 | static u32 ath9k_hw_def_ini_fixup(struct ath_hw *ah, |
@@ -2090,7 +2065,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2090 | if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | 2065 | if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) |
2091 | ath9k_enable_rfkill(ah); | 2066 | ath9k_enable_rfkill(ah); |
2092 | 2067 | ||
2093 | ath9k_hw_init_user_settings(ah); | 2068 | ath9k_hw_init_global_settings(ah); |
2094 | 2069 | ||
2095 | if (AR_SREV_9287_12_OR_LATER(ah)) { | 2070 | if (AR_SREV_9287_12_OR_LATER(ah)) { |
2096 | REG_WRITE(ah, AR_D_GBL_IFS_SIFS, | 2071 | REG_WRITE(ah, AR_D_GBL_IFS_SIFS, |
@@ -2120,7 +2095,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2120 | 2095 | ||
2121 | REG_WRITE(ah, AR_OBS, 8); | 2096 | REG_WRITE(ah, AR_OBS, 8); |
2122 | 2097 | ||
2123 | if (ah->config.intr_mitigation) { | 2098 | if (ah->config.rx_intr_mitigation) { |
2124 | REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); | 2099 | REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); |
2125 | REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000); | 2100 | REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000); |
2126 | } | 2101 | } |
@@ -2780,7 +2755,7 @@ bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked) | |||
2780 | 2755 | ||
2781 | *masked = isr & ATH9K_INT_COMMON; | 2756 | *masked = isr & ATH9K_INT_COMMON; |
2782 | 2757 | ||
2783 | if (ah->config.intr_mitigation) { | 2758 | if (ah->config.rx_intr_mitigation) { |
2784 | if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) | 2759 | if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) |
2785 | *masked |= ATH9K_INT_RX; | 2760 | *masked |= ATH9K_INT_RX; |
2786 | } | 2761 | } |
@@ -2913,7 +2888,7 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) | |||
2913 | } | 2888 | } |
2914 | if (ints & ATH9K_INT_RX) { | 2889 | if (ints & ATH9K_INT_RX) { |
2915 | mask |= AR_IMR_RXERR; | 2890 | mask |= AR_IMR_RXERR; |
2916 | if (ah->config.intr_mitigation) | 2891 | if (ah->config.rx_intr_mitigation) |
2917 | mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM; | 2892 | mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM; |
2918 | else | 2893 | else |
2919 | mask |= AR_IMR_RXOK | AR_IMR_RXDESC; | 2894 | mask |= AR_IMR_RXOK | AR_IMR_RXDESC; |
@@ -3687,21 +3662,6 @@ u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp) | |||
3687 | } | 3662 | } |
3688 | EXPORT_SYMBOL(ath9k_hw_extend_tsf); | 3663 | EXPORT_SYMBOL(ath9k_hw_extend_tsf); |
3689 | 3664 | ||
3690 | bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us) | ||
3691 | { | ||
3692 | if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) { | ||
3693 | ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, | ||
3694 | "bad slot time %u\n", us); | ||
3695 | ah->slottime = (u32) -1; | ||
3696 | return false; | ||
3697 | } else { | ||
3698 | REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us)); | ||
3699 | ah->slottime = us; | ||
3700 | return true; | ||
3701 | } | ||
3702 | } | ||
3703 | EXPORT_SYMBOL(ath9k_hw_setslottime); | ||
3704 | |||
3705 | void ath9k_hw_set11nmac2040(struct ath_hw *ah) | 3665 | void ath9k_hw_set11nmac2040(struct ath_hw *ah) |
3706 | { | 3666 | { |
3707 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; | 3667 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index e2b0c73a616..dbbf7ca5f97 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -40,6 +40,7 @@ | |||
40 | #define AR9280_DEVID_PCI 0x0029 | 40 | #define AR9280_DEVID_PCI 0x0029 |
41 | #define AR9280_DEVID_PCIE 0x002a | 41 | #define AR9280_DEVID_PCIE 0x002a |
42 | #define AR9285_DEVID_PCIE 0x002b | 42 | #define AR9285_DEVID_PCIE 0x002b |
43 | #define AR2427_DEVID_PCIE 0x002c | ||
43 | 44 | ||
44 | #define AR5416_AR9100_DEVID 0x000b | 45 | #define AR5416_AR9100_DEVID 0x000b |
45 | 46 | ||
@@ -212,7 +213,7 @@ struct ath9k_ops_config { | |||
212 | u32 cck_trig_low; | 213 | u32 cck_trig_low; |
213 | u32 enable_ani; | 214 | u32 enable_ani; |
214 | int serialize_regmode; | 215 | int serialize_regmode; |
215 | bool intr_mitigation; | 216 | bool rx_intr_mitigation; |
216 | #define SPUR_DISABLE 0 | 217 | #define SPUR_DISABLE 0 |
217 | #define SPUR_ENABLE_IOCTL 1 | 218 | #define SPUR_ENABLE_IOCTL 1 |
218 | #define SPUR_ENABLE_EEPROM 2 | 219 | #define SPUR_ENABLE_EEPROM 2 |
@@ -551,10 +552,9 @@ struct ath_hw { | |||
551 | u32 *bank6Temp; | 552 | u32 *bank6Temp; |
552 | 553 | ||
553 | int16_t txpower_indexoffset; | 554 | int16_t txpower_indexoffset; |
555 | int coverage_class; | ||
554 | u32 beacon_interval; | 556 | u32 beacon_interval; |
555 | u32 slottime; | 557 | u32 slottime; |
556 | u32 acktimeout; | ||
557 | u32 ctstimeout; | ||
558 | u32 globaltxtimeout; | 558 | u32 globaltxtimeout; |
559 | 559 | ||
560 | /* ANI */ | 560 | /* ANI */ |
@@ -616,7 +616,7 @@ static inline struct ath_regulatory *ath9k_hw_regulatory(struct ath_hw *ah) | |||
616 | 616 | ||
617 | /* Initialization, Detach, Reset */ | 617 | /* Initialization, Detach, Reset */ |
618 | const char *ath9k_hw_probe(u16 vendorid, u16 devid); | 618 | const char *ath9k_hw_probe(u16 vendorid, u16 devid); |
619 | void ath9k_hw_detach(struct ath_hw *ah); | 619 | void ath9k_hw_deinit(struct ath_hw *ah); |
620 | int ath9k_hw_init(struct ath_hw *ah); | 620 | int ath9k_hw_init(struct ath_hw *ah); |
621 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | 621 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, |
622 | bool bChannelChange); | 622 | bool bChannelChange); |
@@ -668,7 +668,7 @@ void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64); | |||
668 | void ath9k_hw_reset_tsf(struct ath_hw *ah); | 668 | void ath9k_hw_reset_tsf(struct ath_hw *ah); |
669 | void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); | 669 | void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); |
670 | u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp); | 670 | u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp); |
671 | bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us); | 671 | void ath9k_hw_init_global_settings(struct ath_hw *ah); |
672 | void ath9k_hw_set11nmac2040(struct ath_hw *ah); | 672 | void ath9k_hw_set11nmac2040(struct ath_hw *ah); |
673 | void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); | 673 | void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); |
674 | void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, | 674 | void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c new file mode 100644 index 00000000000..623c2f88498 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -0,0 +1,863 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "ath9k.h" | ||
18 | |||
19 | static char *dev_info = "ath9k"; | ||
20 | |||
21 | MODULE_AUTHOR("Atheros Communications"); | ||
22 | MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards."); | ||
23 | MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards"); | ||
24 | MODULE_LICENSE("Dual BSD/GPL"); | ||
25 | |||
26 | static unsigned int ath9k_debug = ATH_DBG_DEFAULT; | ||
27 | module_param_named(debug, ath9k_debug, uint, 0); | ||
28 | MODULE_PARM_DESC(debug, "Debugging mask"); | ||
29 | |||
30 | int modparam_nohwcrypt; | ||
31 | module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); | ||
32 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); | ||
33 | |||
34 | /* We use the hw_value as an index into our private channel structure */ | ||
35 | |||
36 | #define CHAN2G(_freq, _idx) { \ | ||
37 | .center_freq = (_freq), \ | ||
38 | .hw_value = (_idx), \ | ||
39 | .max_power = 20, \ | ||
40 | } | ||
41 | |||
42 | #define CHAN5G(_freq, _idx) { \ | ||
43 | .band = IEEE80211_BAND_5GHZ, \ | ||
44 | .center_freq = (_freq), \ | ||
45 | .hw_value = (_idx), \ | ||
46 | .max_power = 20, \ | ||
47 | } | ||
48 | |||
49 | /* Some 2 GHz radios are actually tunable on 2312-2732 | ||
50 | * on 5 MHz steps, we support the channels which we know | ||
51 | * we have calibration data for all cards though to make | ||
52 | * this static */ | ||
53 | static struct ieee80211_channel ath9k_2ghz_chantable[] = { | ||
54 | CHAN2G(2412, 0), /* Channel 1 */ | ||
55 | CHAN2G(2417, 1), /* Channel 2 */ | ||
56 | CHAN2G(2422, 2), /* Channel 3 */ | ||
57 | CHAN2G(2427, 3), /* Channel 4 */ | ||
58 | CHAN2G(2432, 4), /* Channel 5 */ | ||
59 | CHAN2G(2437, 5), /* Channel 6 */ | ||
60 | CHAN2G(2442, 6), /* Channel 7 */ | ||
61 | CHAN2G(2447, 7), /* Channel 8 */ | ||
62 | CHAN2G(2452, 8), /* Channel 9 */ | ||
63 | CHAN2G(2457, 9), /* Channel 10 */ | ||
64 | CHAN2G(2462, 10), /* Channel 11 */ | ||
65 | CHAN2G(2467, 11), /* Channel 12 */ | ||
66 | CHAN2G(2472, 12), /* Channel 13 */ | ||
67 | CHAN2G(2484, 13), /* Channel 14 */ | ||
68 | }; | ||
69 | |||
70 | /* Some 5 GHz radios are actually tunable on XXXX-YYYY | ||
71 | * on 5 MHz steps, we support the channels which we know | ||
72 | * we have calibration data for all cards though to make | ||
73 | * this static */ | ||
74 | static struct ieee80211_channel ath9k_5ghz_chantable[] = { | ||
75 | /* _We_ call this UNII 1 */ | ||
76 | CHAN5G(5180, 14), /* Channel 36 */ | ||
77 | CHAN5G(5200, 15), /* Channel 40 */ | ||
78 | CHAN5G(5220, 16), /* Channel 44 */ | ||
79 | CHAN5G(5240, 17), /* Channel 48 */ | ||
80 | /* _We_ call this UNII 2 */ | ||
81 | CHAN5G(5260, 18), /* Channel 52 */ | ||
82 | CHAN5G(5280, 19), /* Channel 56 */ | ||
83 | CHAN5G(5300, 20), /* Channel 60 */ | ||
84 | CHAN5G(5320, 21), /* Channel 64 */ | ||
85 | /* _We_ call this "Middle band" */ | ||
86 | CHAN5G(5500, 22), /* Channel 100 */ | ||
87 | CHAN5G(5520, 23), /* Channel 104 */ | ||
88 | CHAN5G(5540, 24), /* Channel 108 */ | ||
89 | CHAN5G(5560, 25), /* Channel 112 */ | ||
90 | CHAN5G(5580, 26), /* Channel 116 */ | ||
91 | CHAN5G(5600, 27), /* Channel 120 */ | ||
92 | CHAN5G(5620, 28), /* Channel 124 */ | ||
93 | CHAN5G(5640, 29), /* Channel 128 */ | ||
94 | CHAN5G(5660, 30), /* Channel 132 */ | ||
95 | CHAN5G(5680, 31), /* Channel 136 */ | ||
96 | CHAN5G(5700, 32), /* Channel 140 */ | ||
97 | /* _We_ call this UNII 3 */ | ||
98 | CHAN5G(5745, 33), /* Channel 149 */ | ||
99 | CHAN5G(5765, 34), /* Channel 153 */ | ||
100 | CHAN5G(5785, 35), /* Channel 157 */ | ||
101 | CHAN5G(5805, 36), /* Channel 161 */ | ||
102 | CHAN5G(5825, 37), /* Channel 165 */ | ||
103 | }; | ||
104 | |||
105 | /* Atheros hardware rate code addition for short premble */ | ||
106 | #define SHPCHECK(__hw_rate, __flags) \ | ||
107 | ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0) | ||
108 | |||
109 | #define RATE(_bitrate, _hw_rate, _flags) { \ | ||
110 | .bitrate = (_bitrate), \ | ||
111 | .flags = (_flags), \ | ||
112 | .hw_value = (_hw_rate), \ | ||
113 | .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \ | ||
114 | } | ||
115 | |||
116 | static struct ieee80211_rate ath9k_legacy_rates[] = { | ||
117 | RATE(10, 0x1b, 0), | ||
118 | RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE), | ||
119 | RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE), | ||
120 | RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE), | ||
121 | RATE(60, 0x0b, 0), | ||
122 | RATE(90, 0x0f, 0), | ||
123 | RATE(120, 0x0a, 0), | ||
124 | RATE(180, 0x0e, 0), | ||
125 | RATE(240, 0x09, 0), | ||
126 | RATE(360, 0x0d, 0), | ||
127 | RATE(480, 0x08, 0), | ||
128 | RATE(540, 0x0c, 0), | ||
129 | }; | ||
130 | |||
131 | static void ath9k_deinit_softc(struct ath_softc *sc); | ||
132 | |||
133 | /* | ||
134 | * Read and write, they both share the same lock. We do this to serialize | ||
135 | * reads and writes on Atheros 802.11n PCI devices only. This is required | ||
136 | * as the FIFO on these devices can only accept sanely 2 requests. | ||
137 | */ | ||
138 | |||
139 | static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset) | ||
140 | { | ||
141 | struct ath_hw *ah = (struct ath_hw *) hw_priv; | ||
142 | struct ath_common *common = ath9k_hw_common(ah); | ||
143 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
144 | |||
145 | if (ah->config.serialize_regmode == SER_REG_MODE_ON) { | ||
146 | unsigned long flags; | ||
147 | spin_lock_irqsave(&sc->sc_serial_rw, flags); | ||
148 | iowrite32(val, sc->mem + reg_offset); | ||
149 | spin_unlock_irqrestore(&sc->sc_serial_rw, flags); | ||
150 | } else | ||
151 | iowrite32(val, sc->mem + reg_offset); | ||
152 | } | ||
153 | |||
154 | static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset) | ||
155 | { | ||
156 | struct ath_hw *ah = (struct ath_hw *) hw_priv; | ||
157 | struct ath_common *common = ath9k_hw_common(ah); | ||
158 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
159 | u32 val; | ||
160 | |||
161 | if (ah->config.serialize_regmode == SER_REG_MODE_ON) { | ||
162 | unsigned long flags; | ||
163 | spin_lock_irqsave(&sc->sc_serial_rw, flags); | ||
164 | val = ioread32(sc->mem + reg_offset); | ||
165 | spin_unlock_irqrestore(&sc->sc_serial_rw, flags); | ||
166 | } else | ||
167 | val = ioread32(sc->mem + reg_offset); | ||
168 | return val; | ||
169 | } | ||
170 | |||
171 | static const struct ath_ops ath9k_common_ops = { | ||
172 | .read = ath9k_ioread32, | ||
173 | .write = ath9k_iowrite32, | ||
174 | }; | ||
175 | |||
176 | /**************************/ | ||
177 | /* Initialization */ | ||
178 | /**************************/ | ||
179 | |||
180 | static void setup_ht_cap(struct ath_softc *sc, | ||
181 | struct ieee80211_sta_ht_cap *ht_info) | ||
182 | { | ||
183 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
184 | u8 tx_streams, rx_streams; | ||
185 | |||
186 | ht_info->ht_supported = true; | ||
187 | ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | | ||
188 | IEEE80211_HT_CAP_SM_PS | | ||
189 | IEEE80211_HT_CAP_SGI_40 | | ||
190 | IEEE80211_HT_CAP_DSSSCCK40; | ||
191 | |||
192 | ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; | ||
193 | ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; | ||
194 | |||
195 | /* set up supported mcs set */ | ||
196 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); | ||
197 | tx_streams = !(common->tx_chainmask & (common->tx_chainmask - 1)) ? | ||
198 | 1 : 2; | ||
199 | rx_streams = !(common->rx_chainmask & (common->rx_chainmask - 1)) ? | ||
200 | 1 : 2; | ||
201 | |||
202 | if (tx_streams != rx_streams) { | ||
203 | ath_print(common, ATH_DBG_CONFIG, | ||
204 | "TX streams %d, RX streams: %d\n", | ||
205 | tx_streams, rx_streams); | ||
206 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; | ||
207 | ht_info->mcs.tx_params |= ((tx_streams - 1) << | ||
208 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); | ||
209 | } | ||
210 | |||
211 | ht_info->mcs.rx_mask[0] = 0xff; | ||
212 | if (rx_streams >= 2) | ||
213 | ht_info->mcs.rx_mask[1] = 0xff; | ||
214 | |||
215 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED; | ||
216 | } | ||
217 | |||
218 | static int ath9k_reg_notifier(struct wiphy *wiphy, | ||
219 | struct regulatory_request *request) | ||
220 | { | ||
221 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); | ||
222 | struct ath_wiphy *aphy = hw->priv; | ||
223 | struct ath_softc *sc = aphy->sc; | ||
224 | struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah); | ||
225 | |||
226 | return ath_reg_notifier_apply(wiphy, request, reg); | ||
227 | } | ||
228 | |||
229 | /* | ||
230 | * This function will allocate both the DMA descriptor structure, and the | ||
231 | * buffers it contains. These are used to contain the descriptors used | ||
232 | * by the system. | ||
233 | */ | ||
234 | int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | ||
235 | struct list_head *head, const char *name, | ||
236 | int nbuf, int ndesc) | ||
237 | { | ||
238 | #define DS2PHYS(_dd, _ds) \ | ||
239 | ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) | ||
240 | #define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0) | ||
241 | #define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096) | ||
242 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
243 | struct ath_desc *ds; | ||
244 | struct ath_buf *bf; | ||
245 | int i, bsize, error; | ||
246 | |||
247 | ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n", | ||
248 | name, nbuf, ndesc); | ||
249 | |||
250 | INIT_LIST_HEAD(head); | ||
251 | /* ath_desc must be a multiple of DWORDs */ | ||
252 | if ((sizeof(struct ath_desc) % 4) != 0) { | ||
253 | ath_print(common, ATH_DBG_FATAL, | ||
254 | "ath_desc not DWORD aligned\n"); | ||
255 | BUG_ON((sizeof(struct ath_desc) % 4) != 0); | ||
256 | error = -ENOMEM; | ||
257 | goto fail; | ||
258 | } | ||
259 | |||
260 | dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc; | ||
261 | |||
262 | /* | ||
263 | * Need additional DMA memory because we can't use | ||
264 | * descriptors that cross the 4K page boundary. Assume | ||
265 | * one skipped descriptor per 4K page. | ||
266 | */ | ||
267 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) { | ||
268 | u32 ndesc_skipped = | ||
269 | ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len); | ||
270 | u32 dma_len; | ||
271 | |||
272 | while (ndesc_skipped) { | ||
273 | dma_len = ndesc_skipped * sizeof(struct ath_desc); | ||
274 | dd->dd_desc_len += dma_len; | ||
275 | |||
276 | ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len); | ||
277 | }; | ||
278 | } | ||
279 | |||
280 | /* allocate descriptors */ | ||
281 | dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len, | ||
282 | &dd->dd_desc_paddr, GFP_KERNEL); | ||
283 | if (dd->dd_desc == NULL) { | ||
284 | error = -ENOMEM; | ||
285 | goto fail; | ||
286 | } | ||
287 | ds = dd->dd_desc; | ||
288 | ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n", | ||
289 | name, ds, (u32) dd->dd_desc_len, | ||
290 | ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len); | ||
291 | |||
292 | /* allocate buffers */ | ||
293 | bsize = sizeof(struct ath_buf) * nbuf; | ||
294 | bf = kzalloc(bsize, GFP_KERNEL); | ||
295 | if (bf == NULL) { | ||
296 | error = -ENOMEM; | ||
297 | goto fail2; | ||
298 | } | ||
299 | dd->dd_bufptr = bf; | ||
300 | |||
301 | for (i = 0; i < nbuf; i++, bf++, ds += ndesc) { | ||
302 | bf->bf_desc = ds; | ||
303 | bf->bf_daddr = DS2PHYS(dd, ds); | ||
304 | |||
305 | if (!(sc->sc_ah->caps.hw_caps & | ||
306 | ATH9K_HW_CAP_4KB_SPLITTRANS)) { | ||
307 | /* | ||
308 | * Skip descriptor addresses which can cause 4KB | ||
309 | * boundary crossing (addr + length) with a 32 dword | ||
310 | * descriptor fetch. | ||
311 | */ | ||
312 | while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) { | ||
313 | BUG_ON((caddr_t) bf->bf_desc >= | ||
314 | ((caddr_t) dd->dd_desc + | ||
315 | dd->dd_desc_len)); | ||
316 | |||
317 | ds += ndesc; | ||
318 | bf->bf_desc = ds; | ||
319 | bf->bf_daddr = DS2PHYS(dd, ds); | ||
320 | } | ||
321 | } | ||
322 | list_add_tail(&bf->list, head); | ||
323 | } | ||
324 | return 0; | ||
325 | fail2: | ||
326 | dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc, | ||
327 | dd->dd_desc_paddr); | ||
328 | fail: | ||
329 | memset(dd, 0, sizeof(*dd)); | ||
330 | return error; | ||
331 | #undef ATH_DESC_4KB_BOUND_CHECK | ||
332 | #undef ATH_DESC_4KB_BOUND_NUM_SKIPPED | ||
333 | #undef DS2PHYS | ||
334 | } | ||
335 | |||
336 | static void ath9k_init_crypto(struct ath_softc *sc) | ||
337 | { | ||
338 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
339 | int i = 0; | ||
340 | |||
341 | /* Get the hardware key cache size. */ | ||
342 | common->keymax = sc->sc_ah->caps.keycache_size; | ||
343 | if (common->keymax > ATH_KEYMAX) { | ||
344 | ath_print(common, ATH_DBG_ANY, | ||
345 | "Warning, using only %u entries in %u key cache\n", | ||
346 | ATH_KEYMAX, common->keymax); | ||
347 | common->keymax = ATH_KEYMAX; | ||
348 | } | ||
349 | |||
350 | /* | ||
351 | * Reset the key cache since some parts do not | ||
352 | * reset the contents on initial power up. | ||
353 | */ | ||
354 | for (i = 0; i < common->keymax; i++) | ||
355 | ath9k_hw_keyreset(sc->sc_ah, (u16) i); | ||
356 | |||
357 | if (ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER, | ||
358 | ATH9K_CIPHER_TKIP, NULL)) { | ||
359 | /* | ||
360 | * Whether we should enable h/w TKIP MIC. | ||
361 | * XXX: if we don't support WME TKIP MIC, then we wouldn't | ||
362 | * report WMM capable, so it's always safe to turn on | ||
363 | * TKIP MIC in this case. | ||
364 | */ | ||
365 | ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_TKIP_MIC, 0, 1, NULL); | ||
366 | } | ||
367 | |||
368 | /* | ||
369 | * Check whether the separate key cache entries | ||
370 | * are required to handle both tx+rx MIC keys. | ||
371 | * With split mic keys the number of stations is limited | ||
372 | * to 27 otherwise 59. | ||
373 | */ | ||
374 | if (ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER, | ||
375 | ATH9K_CIPHER_TKIP, NULL) | ||
376 | && ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER, | ||
377 | ATH9K_CIPHER_MIC, NULL) | ||
378 | && ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_TKIP_SPLIT, | ||
379 | 0, NULL)) | ||
380 | common->splitmic = 1; | ||
381 | |||
382 | /* turn on mcast key search if possible */ | ||
383 | if (!ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL)) | ||
384 | (void)ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_MCAST_KEYSRCH, | ||
385 | 1, 1, NULL); | ||
386 | |||
387 | } | ||
388 | |||
389 | static int ath9k_init_btcoex(struct ath_softc *sc) | ||
390 | { | ||
391 | int r, qnum; | ||
392 | |||
393 | switch (sc->sc_ah->btcoex_hw.scheme) { | ||
394 | case ATH_BTCOEX_CFG_NONE: | ||
395 | break; | ||
396 | case ATH_BTCOEX_CFG_2WIRE: | ||
397 | ath9k_hw_btcoex_init_2wire(sc->sc_ah); | ||
398 | break; | ||
399 | case ATH_BTCOEX_CFG_3WIRE: | ||
400 | ath9k_hw_btcoex_init_3wire(sc->sc_ah); | ||
401 | r = ath_init_btcoex_timer(sc); | ||
402 | if (r) | ||
403 | return -1; | ||
404 | qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE); | ||
405 | ath9k_hw_init_btcoex_hw(sc->sc_ah, qnum); | ||
406 | sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; | ||
407 | break; | ||
408 | default: | ||
409 | WARN_ON(1); | ||
410 | break; | ||
411 | } | ||
412 | |||
413 | return 0; | ||
414 | } | ||
415 | |||
416 | static int ath9k_init_queues(struct ath_softc *sc) | ||
417 | { | ||
418 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
419 | int i = 0; | ||
420 | |||
421 | for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++) | ||
422 | sc->tx.hwq_map[i] = -1; | ||
423 | |||
424 | sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah); | ||
425 | if (sc->beacon.beaconq == -1) { | ||
426 | ath_print(common, ATH_DBG_FATAL, | ||
427 | "Unable to setup a beacon xmit queue\n"); | ||
428 | goto err; | ||
429 | } | ||
430 | |||
431 | sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); | ||
432 | if (sc->beacon.cabq == NULL) { | ||
433 | ath_print(common, ATH_DBG_FATAL, | ||
434 | "Unable to setup CAB xmit queue\n"); | ||
435 | goto err; | ||
436 | } | ||
437 | |||
438 | sc->config.cabqReadytime = ATH_CABQ_READY_TIME; | ||
439 | ath_cabq_update(sc); | ||
440 | |||
441 | if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) { | ||
442 | ath_print(common, ATH_DBG_FATAL, | ||
443 | "Unable to setup xmit queue for BK traffic\n"); | ||
444 | goto err; | ||
445 | } | ||
446 | |||
447 | if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) { | ||
448 | ath_print(common, ATH_DBG_FATAL, | ||
449 | "Unable to setup xmit queue for BE traffic\n"); | ||
450 | goto err; | ||
451 | } | ||
452 | if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) { | ||
453 | ath_print(common, ATH_DBG_FATAL, | ||
454 | "Unable to setup xmit queue for VI traffic\n"); | ||
455 | goto err; | ||
456 | } | ||
457 | if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) { | ||
458 | ath_print(common, ATH_DBG_FATAL, | ||
459 | "Unable to setup xmit queue for VO traffic\n"); | ||
460 | goto err; | ||
461 | } | ||
462 | |||
463 | return 0; | ||
464 | |||
465 | err: | ||
466 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | ||
467 | if (ATH_TXQ_SETUP(sc, i)) | ||
468 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | ||
469 | |||
470 | return -EIO; | ||
471 | } | ||
472 | |||
473 | static void ath9k_init_channels_rates(struct ath_softc *sc) | ||
474 | { | ||
475 | if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) { | ||
476 | sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable; | ||
477 | sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; | ||
478 | sc->sbands[IEEE80211_BAND_2GHZ].n_channels = | ||
479 | ARRAY_SIZE(ath9k_2ghz_chantable); | ||
480 | sc->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates; | ||
481 | sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates = | ||
482 | ARRAY_SIZE(ath9k_legacy_rates); | ||
483 | } | ||
484 | |||
485 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) { | ||
486 | sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable; | ||
487 | sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; | ||
488 | sc->sbands[IEEE80211_BAND_5GHZ].n_channels = | ||
489 | ARRAY_SIZE(ath9k_5ghz_chantable); | ||
490 | sc->sbands[IEEE80211_BAND_5GHZ].bitrates = | ||
491 | ath9k_legacy_rates + 4; | ||
492 | sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates = | ||
493 | ARRAY_SIZE(ath9k_legacy_rates) - 4; | ||
494 | } | ||
495 | } | ||
496 | |||
497 | static void ath9k_init_misc(struct ath_softc *sc) | ||
498 | { | ||
499 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
500 | int i = 0; | ||
501 | |||
502 | common->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR; | ||
503 | setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); | ||
504 | |||
505 | sc->config.txpowlimit = ATH_TXPOWER_MAX; | ||
506 | |||
507 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { | ||
508 | sc->sc_flags |= SC_OP_TXAGGR; | ||
509 | sc->sc_flags |= SC_OP_RXAGGR; | ||
510 | } | ||
511 | |||
512 | common->tx_chainmask = sc->sc_ah->caps.tx_chainmask; | ||
513 | common->rx_chainmask = sc->sc_ah->caps.rx_chainmask; | ||
514 | |||
515 | ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_DIVERSITY, 1, true, NULL); | ||
516 | sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah); | ||
517 | |||
518 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) | ||
519 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); | ||
520 | |||
521 | sc->beacon.slottime = ATH9K_SLOT_TIME_9; | ||
522 | |||
523 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) { | ||
524 | sc->beacon.bslot[i] = NULL; | ||
525 | sc->beacon.bslot_aphy[i] = NULL; | ||
526 | } | ||
527 | } | ||
528 | |||
529 | static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, | ||
530 | const struct ath_bus_ops *bus_ops) | ||
531 | { | ||
532 | struct ath_hw *ah = NULL; | ||
533 | struct ath_common *common; | ||
534 | int ret = 0, i; | ||
535 | int csz = 0; | ||
536 | |||
537 | ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL); | ||
538 | if (!ah) | ||
539 | return -ENOMEM; | ||
540 | |||
541 | ah->hw_version.devid = devid; | ||
542 | ah->hw_version.subsysid = subsysid; | ||
543 | sc->sc_ah = ah; | ||
544 | |||
545 | common = ath9k_hw_common(ah); | ||
546 | common->ops = &ath9k_common_ops; | ||
547 | common->bus_ops = bus_ops; | ||
548 | common->ah = ah; | ||
549 | common->hw = sc->hw; | ||
550 | common->priv = sc; | ||
551 | common->debug_mask = ath9k_debug; | ||
552 | |||
553 | spin_lock_init(&sc->wiphy_lock); | ||
554 | spin_lock_init(&sc->sc_resetlock); | ||
555 | spin_lock_init(&sc->sc_serial_rw); | ||
556 | spin_lock_init(&sc->sc_pm_lock); | ||
557 | mutex_init(&sc->mutex); | ||
558 | tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); | ||
559 | tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, | ||
560 | (unsigned long)sc); | ||
561 | |||
562 | /* | ||
563 | * Cache line size is used to size and align various | ||
564 | * structures used to communicate with the hardware. | ||
565 | */ | ||
566 | ath_read_cachesize(common, &csz); | ||
567 | common->cachelsz = csz << 2; /* convert to bytes */ | ||
568 | |||
569 | ret = ath9k_hw_init(ah); | ||
570 | if (ret) { | ||
571 | ath_print(common, ATH_DBG_FATAL, | ||
572 | "Unable to initialize hardware; " | ||
573 | "initialization status: %d\n", ret); | ||
574 | goto err_hw; | ||
575 | } | ||
576 | |||
577 | ret = ath9k_init_debug(ah); | ||
578 | if (ret) { | ||
579 | ath_print(common, ATH_DBG_FATAL, | ||
580 | "Unable to create debugfs files\n"); | ||
581 | goto err_debug; | ||
582 | } | ||
583 | |||
584 | ret = ath9k_init_queues(sc); | ||
585 | if (ret) | ||
586 | goto err_queues; | ||
587 | |||
588 | ret = ath9k_init_btcoex(sc); | ||
589 | if (ret) | ||
590 | goto err_btcoex; | ||
591 | |||
592 | ath9k_init_crypto(sc); | ||
593 | ath9k_init_channels_rates(sc); | ||
594 | ath9k_init_misc(sc); | ||
595 | |||
596 | return 0; | ||
597 | |||
598 | err_btcoex: | ||
599 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | ||
600 | if (ATH_TXQ_SETUP(sc, i)) | ||
601 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | ||
602 | err_queues: | ||
603 | ath9k_exit_debug(ah); | ||
604 | err_debug: | ||
605 | ath9k_hw_deinit(ah); | ||
606 | err_hw: | ||
607 | tasklet_kill(&sc->intr_tq); | ||
608 | tasklet_kill(&sc->bcon_tasklet); | ||
609 | |||
610 | kfree(ah); | ||
611 | sc->sc_ah = NULL; | ||
612 | |||
613 | return ret; | ||
614 | } | ||
615 | |||
616 | void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | ||
617 | { | ||
618 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
619 | |||
620 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | ||
621 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
622 | IEEE80211_HW_SIGNAL_DBM | | ||
623 | IEEE80211_HW_SUPPORTS_PS | | ||
624 | IEEE80211_HW_PS_NULLFUNC_STACK | | ||
625 | IEEE80211_HW_SPECTRUM_MGMT | | ||
626 | IEEE80211_HW_REPORTS_TX_ACK_STATUS; | ||
627 | |||
628 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) | ||
629 | hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; | ||
630 | |||
631 | if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt) | ||
632 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; | ||
633 | |||
634 | hw->wiphy->interface_modes = | ||
635 | BIT(NL80211_IFTYPE_AP) | | ||
636 | BIT(NL80211_IFTYPE_STATION) | | ||
637 | BIT(NL80211_IFTYPE_ADHOC) | | ||
638 | BIT(NL80211_IFTYPE_MESH_POINT); | ||
639 | |||
640 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
641 | |||
642 | hw->queues = 4; | ||
643 | hw->max_rates = 4; | ||
644 | hw->channel_change_time = 5000; | ||
645 | hw->max_listen_interval = 10; | ||
646 | hw->max_rate_tries = 10; | ||
647 | hw->sta_data_size = sizeof(struct ath_node); | ||
648 | hw->vif_data_size = sizeof(struct ath_vif); | ||
649 | |||
650 | hw->rate_control_algorithm = "ath9k_rate_control"; | ||
651 | |||
652 | if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) | ||
653 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | ||
654 | &sc->sbands[IEEE80211_BAND_2GHZ]; | ||
655 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) | ||
656 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | ||
657 | &sc->sbands[IEEE80211_BAND_5GHZ]; | ||
658 | |||
659 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { | ||
660 | if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) | ||
661 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); | ||
662 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) | ||
663 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); | ||
664 | } | ||
665 | |||
666 | SET_IEEE80211_PERM_ADDR(hw, common->macaddr); | ||
667 | } | ||
668 | |||
669 | int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, | ||
670 | const struct ath_bus_ops *bus_ops) | ||
671 | { | ||
672 | struct ieee80211_hw *hw = sc->hw; | ||
673 | struct ath_common *common; | ||
674 | struct ath_hw *ah; | ||
675 | int error = 0; | ||
676 | struct ath_regulatory *reg; | ||
677 | |||
678 | /* Bring up device */ | ||
679 | error = ath9k_init_softc(devid, sc, subsysid, bus_ops); | ||
680 | if (error != 0) | ||
681 | goto error_init; | ||
682 | |||
683 | ah = sc->sc_ah; | ||
684 | common = ath9k_hw_common(ah); | ||
685 | ath9k_set_hw_capab(sc, hw); | ||
686 | |||
687 | /* Initialize regulatory */ | ||
688 | error = ath_regd_init(&common->regulatory, sc->hw->wiphy, | ||
689 | ath9k_reg_notifier); | ||
690 | if (error) | ||
691 | goto error_regd; | ||
692 | |||
693 | reg = &common->regulatory; | ||
694 | |||
695 | /* Setup TX DMA */ | ||
696 | error = ath_tx_init(sc, ATH_TXBUF); | ||
697 | if (error != 0) | ||
698 | goto error_tx; | ||
699 | |||
700 | /* Setup RX DMA */ | ||
701 | error = ath_rx_init(sc, ATH_RXBUF); | ||
702 | if (error != 0) | ||
703 | goto error_rx; | ||
704 | |||
705 | /* Register with mac80211 */ | ||
706 | error = ieee80211_register_hw(hw); | ||
707 | if (error) | ||
708 | goto error_register; | ||
709 | |||
710 | /* Handle world regulatory */ | ||
711 | if (!ath_is_world_regd(reg)) { | ||
712 | error = regulatory_hint(hw->wiphy, reg->alpha2); | ||
713 | if (error) | ||
714 | goto error_world; | ||
715 | } | ||
716 | |||
717 | INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); | ||
718 | INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); | ||
719 | sc->wiphy_scheduler_int = msecs_to_jiffies(500); | ||
720 | |||
721 | ath_init_leds(sc); | ||
722 | ath_start_rfkill_poll(sc); | ||
723 | |||
724 | return 0; | ||
725 | |||
726 | error_world: | ||
727 | ieee80211_unregister_hw(hw); | ||
728 | error_register: | ||
729 | ath_rx_cleanup(sc); | ||
730 | error_rx: | ||
731 | ath_tx_cleanup(sc); | ||
732 | error_tx: | ||
733 | /* Nothing */ | ||
734 | error_regd: | ||
735 | ath9k_deinit_softc(sc); | ||
736 | error_init: | ||
737 | return error; | ||
738 | } | ||
739 | |||
740 | /*****************************/ | ||
741 | /* De-Initialization */ | ||
742 | /*****************************/ | ||
743 | |||
744 | static void ath9k_deinit_softc(struct ath_softc *sc) | ||
745 | { | ||
746 | int i = 0; | ||
747 | |||
748 | if ((sc->btcoex.no_stomp_timer) && | ||
749 | sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) | ||
750 | ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer); | ||
751 | |||
752 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | ||
753 | if (ATH_TXQ_SETUP(sc, i)) | ||
754 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | ||
755 | |||
756 | ath9k_exit_debug(sc->sc_ah); | ||
757 | ath9k_hw_deinit(sc->sc_ah); | ||
758 | |||
759 | tasklet_kill(&sc->intr_tq); | ||
760 | tasklet_kill(&sc->bcon_tasklet); | ||
761 | } | ||
762 | |||
763 | void ath9k_deinit_device(struct ath_softc *sc) | ||
764 | { | ||
765 | struct ieee80211_hw *hw = sc->hw; | ||
766 | int i = 0; | ||
767 | |||
768 | ath9k_ps_wakeup(sc); | ||
769 | |||
770 | wiphy_rfkill_stop_polling(sc->hw->wiphy); | ||
771 | ath_deinit_leds(sc); | ||
772 | |||
773 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
774 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | ||
775 | if (aphy == NULL) | ||
776 | continue; | ||
777 | sc->sec_wiphy[i] = NULL; | ||
778 | ieee80211_unregister_hw(aphy->hw); | ||
779 | ieee80211_free_hw(aphy->hw); | ||
780 | } | ||
781 | kfree(sc->sec_wiphy); | ||
782 | |||
783 | ieee80211_unregister_hw(hw); | ||
784 | ath_rx_cleanup(sc); | ||
785 | ath_tx_cleanup(sc); | ||
786 | ath9k_deinit_softc(sc); | ||
787 | } | ||
788 | |||
789 | void ath_descdma_cleanup(struct ath_softc *sc, | ||
790 | struct ath_descdma *dd, | ||
791 | struct list_head *head) | ||
792 | { | ||
793 | dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc, | ||
794 | dd->dd_desc_paddr); | ||
795 | |||
796 | INIT_LIST_HEAD(head); | ||
797 | kfree(dd->dd_bufptr); | ||
798 | memset(dd, 0, sizeof(*dd)); | ||
799 | } | ||
800 | |||
801 | /************************/ | ||
802 | /* Module Hooks */ | ||
803 | /************************/ | ||
804 | |||
805 | static int __init ath9k_init(void) | ||
806 | { | ||
807 | int error; | ||
808 | |||
809 | /* Register rate control algorithm */ | ||
810 | error = ath_rate_control_register(); | ||
811 | if (error != 0) { | ||
812 | printk(KERN_ERR | ||
813 | "ath9k: Unable to register rate control " | ||
814 | "algorithm: %d\n", | ||
815 | error); | ||
816 | goto err_out; | ||
817 | } | ||
818 | |||
819 | error = ath9k_debug_create_root(); | ||
820 | if (error) { | ||
821 | printk(KERN_ERR | ||
822 | "ath9k: Unable to create debugfs root: %d\n", | ||
823 | error); | ||
824 | goto err_rate_unregister; | ||
825 | } | ||
826 | |||
827 | error = ath_pci_init(); | ||
828 | if (error < 0) { | ||
829 | printk(KERN_ERR | ||
830 | "ath9k: No PCI devices found, driver not installed.\n"); | ||
831 | error = -ENODEV; | ||
832 | goto err_remove_root; | ||
833 | } | ||
834 | |||
835 | error = ath_ahb_init(); | ||
836 | if (error < 0) { | ||
837 | error = -ENODEV; | ||
838 | goto err_pci_exit; | ||
839 | } | ||
840 | |||
841 | return 0; | ||
842 | |||
843 | err_pci_exit: | ||
844 | ath_pci_exit(); | ||
845 | |||
846 | err_remove_root: | ||
847 | ath9k_debug_remove_root(); | ||
848 | err_rate_unregister: | ||
849 | ath_rate_control_unregister(); | ||
850 | err_out: | ||
851 | return error; | ||
852 | } | ||
853 | module_init(ath9k_init); | ||
854 | |||
855 | static void __exit ath9k_exit(void) | ||
856 | { | ||
857 | ath_ahb_exit(); | ||
858 | ath_pci_exit(); | ||
859 | ath9k_debug_remove_root(); | ||
860 | ath_rate_control_unregister(); | ||
861 | printk(KERN_INFO "%s: Driver unloaded\n", dev_info); | ||
862 | } | ||
863 | module_exit(ath9k_exit); | ||
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index e185479e295..29851e6376a 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h | |||
@@ -167,6 +167,40 @@ struct ath_rx_status { | |||
167 | #define ATH9K_RXKEYIX_INVALID ((u8)-1) | 167 | #define ATH9K_RXKEYIX_INVALID ((u8)-1) |
168 | #define ATH9K_TXKEYIX_INVALID ((u32)-1) | 168 | #define ATH9K_TXKEYIX_INVALID ((u32)-1) |
169 | 169 | ||
170 | enum ath9k_phyerr { | ||
171 | ATH9K_PHYERR_UNDERRUN = 0, /* Transmit underrun */ | ||
172 | ATH9K_PHYERR_TIMING = 1, /* Timing error */ | ||
173 | ATH9K_PHYERR_PARITY = 2, /* Illegal parity */ | ||
174 | ATH9K_PHYERR_RATE = 3, /* Illegal rate */ | ||
175 | ATH9K_PHYERR_LENGTH = 4, /* Illegal length */ | ||
176 | ATH9K_PHYERR_RADAR = 5, /* Radar detect */ | ||
177 | ATH9K_PHYERR_SERVICE = 6, /* Illegal service */ | ||
178 | ATH9K_PHYERR_TOR = 7, /* Transmit override receive */ | ||
179 | |||
180 | ATH9K_PHYERR_OFDM_TIMING = 17, | ||
181 | ATH9K_PHYERR_OFDM_SIGNAL_PARITY = 18, | ||
182 | ATH9K_PHYERR_OFDM_RATE_ILLEGAL = 19, | ||
183 | ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL = 20, | ||
184 | ATH9K_PHYERR_OFDM_POWER_DROP = 21, | ||
185 | ATH9K_PHYERR_OFDM_SERVICE = 22, | ||
186 | ATH9K_PHYERR_OFDM_RESTART = 23, | ||
187 | ATH9K_PHYERR_FALSE_RADAR_EXT = 24, | ||
188 | |||
189 | ATH9K_PHYERR_CCK_TIMING = 25, | ||
190 | ATH9K_PHYERR_CCK_HEADER_CRC = 26, | ||
191 | ATH9K_PHYERR_CCK_RATE_ILLEGAL = 27, | ||
192 | ATH9K_PHYERR_CCK_SERVICE = 30, | ||
193 | ATH9K_PHYERR_CCK_RESTART = 31, | ||
194 | ATH9K_PHYERR_CCK_LENGTH_ILLEGAL = 32, | ||
195 | ATH9K_PHYERR_CCK_POWER_DROP = 33, | ||
196 | |||
197 | ATH9K_PHYERR_HT_CRC_ERROR = 34, | ||
198 | ATH9K_PHYERR_HT_LENGTH_ILLEGAL = 35, | ||
199 | ATH9K_PHYERR_HT_RATE_ILLEGAL = 36, | ||
200 | |||
201 | ATH9K_PHYERR_MAX = 37, | ||
202 | }; | ||
203 | |||
170 | struct ath_desc { | 204 | struct ath_desc { |
171 | u32 ds_link; | 205 | u32 ds_link; |
172 | u32 ds_data; | 206 | u32 ds_data; |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 643bea35686..67ca4e5a601 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -18,118 +18,6 @@ | |||
18 | #include "ath9k.h" | 18 | #include "ath9k.h" |
19 | #include "btcoex.h" | 19 | #include "btcoex.h" |
20 | 20 | ||
21 | static char *dev_info = "ath9k"; | ||
22 | |||
23 | MODULE_AUTHOR("Atheros Communications"); | ||
24 | MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards."); | ||
25 | MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards"); | ||
26 | MODULE_LICENSE("Dual BSD/GPL"); | ||
27 | |||
28 | static int modparam_nohwcrypt; | ||
29 | module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); | ||
30 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); | ||
31 | |||
32 | static unsigned int ath9k_debug = ATH_DBG_DEFAULT; | ||
33 | module_param_named(debug, ath9k_debug, uint, 0); | ||
34 | MODULE_PARM_DESC(debug, "Debugging mask"); | ||
35 | |||
36 | /* We use the hw_value as an index into our private channel structure */ | ||
37 | |||
38 | #define CHAN2G(_freq, _idx) { \ | ||
39 | .center_freq = (_freq), \ | ||
40 | .hw_value = (_idx), \ | ||
41 | .max_power = 20, \ | ||
42 | } | ||
43 | |||
44 | #define CHAN5G(_freq, _idx) { \ | ||
45 | .band = IEEE80211_BAND_5GHZ, \ | ||
46 | .center_freq = (_freq), \ | ||
47 | .hw_value = (_idx), \ | ||
48 | .max_power = 20, \ | ||
49 | } | ||
50 | |||
51 | /* Some 2 GHz radios are actually tunable on 2312-2732 | ||
52 | * on 5 MHz steps, we support the channels which we know | ||
53 | * we have calibration data for all cards though to make | ||
54 | * this static */ | ||
55 | static struct ieee80211_channel ath9k_2ghz_chantable[] = { | ||
56 | CHAN2G(2412, 0), /* Channel 1 */ | ||
57 | CHAN2G(2417, 1), /* Channel 2 */ | ||
58 | CHAN2G(2422, 2), /* Channel 3 */ | ||
59 | CHAN2G(2427, 3), /* Channel 4 */ | ||
60 | CHAN2G(2432, 4), /* Channel 5 */ | ||
61 | CHAN2G(2437, 5), /* Channel 6 */ | ||
62 | CHAN2G(2442, 6), /* Channel 7 */ | ||
63 | CHAN2G(2447, 7), /* Channel 8 */ | ||
64 | CHAN2G(2452, 8), /* Channel 9 */ | ||
65 | CHAN2G(2457, 9), /* Channel 10 */ | ||
66 | CHAN2G(2462, 10), /* Channel 11 */ | ||
67 | CHAN2G(2467, 11), /* Channel 12 */ | ||
68 | CHAN2G(2472, 12), /* Channel 13 */ | ||
69 | CHAN2G(2484, 13), /* Channel 14 */ | ||
70 | }; | ||
71 | |||
72 | /* Some 5 GHz radios are actually tunable on XXXX-YYYY | ||
73 | * on 5 MHz steps, we support the channels which we know | ||
74 | * we have calibration data for all cards though to make | ||
75 | * this static */ | ||
76 | static struct ieee80211_channel ath9k_5ghz_chantable[] = { | ||
77 | /* _We_ call this UNII 1 */ | ||
78 | CHAN5G(5180, 14), /* Channel 36 */ | ||
79 | CHAN5G(5200, 15), /* Channel 40 */ | ||
80 | CHAN5G(5220, 16), /* Channel 44 */ | ||
81 | CHAN5G(5240, 17), /* Channel 48 */ | ||
82 | /* _We_ call this UNII 2 */ | ||
83 | CHAN5G(5260, 18), /* Channel 52 */ | ||
84 | CHAN5G(5280, 19), /* Channel 56 */ | ||
85 | CHAN5G(5300, 20), /* Channel 60 */ | ||
86 | CHAN5G(5320, 21), /* Channel 64 */ | ||
87 | /* _We_ call this "Middle band" */ | ||
88 | CHAN5G(5500, 22), /* Channel 100 */ | ||
89 | CHAN5G(5520, 23), /* Channel 104 */ | ||
90 | CHAN5G(5540, 24), /* Channel 108 */ | ||
91 | CHAN5G(5560, 25), /* Channel 112 */ | ||
92 | CHAN5G(5580, 26), /* Channel 116 */ | ||
93 | CHAN5G(5600, 27), /* Channel 120 */ | ||
94 | CHAN5G(5620, 28), /* Channel 124 */ | ||
95 | CHAN5G(5640, 29), /* Channel 128 */ | ||
96 | CHAN5G(5660, 30), /* Channel 132 */ | ||
97 | CHAN5G(5680, 31), /* Channel 136 */ | ||
98 | CHAN5G(5700, 32), /* Channel 140 */ | ||
99 | /* _We_ call this UNII 3 */ | ||
100 | CHAN5G(5745, 33), /* Channel 149 */ | ||
101 | CHAN5G(5765, 34), /* Channel 153 */ | ||
102 | CHAN5G(5785, 35), /* Channel 157 */ | ||
103 | CHAN5G(5805, 36), /* Channel 161 */ | ||
104 | CHAN5G(5825, 37), /* Channel 165 */ | ||
105 | }; | ||
106 | |||
107 | /* Atheros hardware rate code addition for short premble */ | ||
108 | #define SHPCHECK(__hw_rate, __flags) \ | ||
109 | ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0) | ||
110 | |||
111 | #define RATE(_bitrate, _hw_rate, _flags) { \ | ||
112 | .bitrate = (_bitrate), \ | ||
113 | .flags = (_flags), \ | ||
114 | .hw_value = (_hw_rate), \ | ||
115 | .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \ | ||
116 | } | ||
117 | |||
118 | static struct ieee80211_rate ath9k_legacy_rates[] = { | ||
119 | RATE(10, 0x1b, 0), | ||
120 | RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE), | ||
121 | RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE), | ||
122 | RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE), | ||
123 | RATE(60, 0x0b, 0), | ||
124 | RATE(90, 0x0f, 0), | ||
125 | RATE(120, 0x0a, 0), | ||
126 | RATE(180, 0x0e, 0), | ||
127 | RATE(240, 0x09, 0), | ||
128 | RATE(360, 0x0d, 0), | ||
129 | RATE(480, 0x08, 0), | ||
130 | RATE(540, 0x0c, 0), | ||
131 | }; | ||
132 | |||
133 | static void ath_cache_conf_rate(struct ath_softc *sc, | 21 | static void ath_cache_conf_rate(struct ath_softc *sc, |
134 | struct ieee80211_conf *conf) | 22 | struct ieee80211_conf *conf) |
135 | { | 23 | { |
@@ -221,7 +109,7 @@ static struct ath9k_channel *ath_get_curchannel(struct ath_softc *sc, | |||
221 | return channel; | 109 | return channel; |
222 | } | 110 | } |
223 | 111 | ||
224 | static bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode) | 112 | bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode) |
225 | { | 113 | { |
226 | unsigned long flags; | 114 | unsigned long flags; |
227 | bool ret; | 115 | bool ret; |
@@ -255,11 +143,13 @@ void ath9k_ps_restore(struct ath_softc *sc) | |||
255 | if (--sc->ps_usecount != 0) | 143 | if (--sc->ps_usecount != 0) |
256 | goto unlock; | 144 | goto unlock; |
257 | 145 | ||
258 | if (sc->ps_enabled && | 146 | if (sc->ps_idle) |
259 | !(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON | | 147 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); |
260 | SC_OP_WAIT_FOR_CAB | | 148 | else if (sc->ps_enabled && |
261 | SC_OP_WAIT_FOR_PSPOLL_DATA | | 149 | !(sc->ps_flags & (PS_WAIT_FOR_BEACON | |
262 | SC_OP_WAIT_FOR_TX_ACK))) | 150 | PS_WAIT_FOR_CAB | |
151 | PS_WAIT_FOR_PSPOLL_DATA | | ||
152 | PS_WAIT_FOR_TX_ACK))) | ||
263 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); | 153 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); |
264 | 154 | ||
265 | unlock: | 155 | unlock: |
@@ -316,7 +206,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
316 | r = ath9k_hw_reset(ah, hchan, fastcc); | 206 | r = ath9k_hw_reset(ah, hchan, fastcc); |
317 | if (r) { | 207 | if (r) { |
318 | ath_print(common, ATH_DBG_FATAL, | 208 | ath_print(common, ATH_DBG_FATAL, |
319 | "Unable to reset channel (%u Mhz) " | 209 | "Unable to reset channel (%u MHz), " |
320 | "reset status %d\n", | 210 | "reset status %d\n", |
321 | channel->center_freq, r); | 211 | channel->center_freq, r); |
322 | spin_unlock_bh(&sc->sc_resetlock); | 212 | spin_unlock_bh(&sc->sc_resetlock); |
@@ -349,7 +239,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
349 | * When the task is complete, it reschedules itself depending on the | 239 | * When the task is complete, it reschedules itself depending on the |
350 | * appropriate interval that was calculated. | 240 | * appropriate interval that was calculated. |
351 | */ | 241 | */ |
352 | static void ath_ani_calibrate(unsigned long data) | 242 | void ath_ani_calibrate(unsigned long data) |
353 | { | 243 | { |
354 | struct ath_softc *sc = (struct ath_softc *)data; | 244 | struct ath_softc *sc = (struct ath_softc *)data; |
355 | struct ath_hw *ah = sc->sc_ah; | 245 | struct ath_hw *ah = sc->sc_ah; |
@@ -363,14 +253,6 @@ static void ath_ani_calibrate(unsigned long data) | |||
363 | short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ? | 253 | short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ? |
364 | ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL; | 254 | ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL; |
365 | 255 | ||
366 | /* | ||
367 | * don't calibrate when we're scanning. | ||
368 | * we are most likely not on our home channel. | ||
369 | */ | ||
370 | spin_lock(&sc->ani_lock); | ||
371 | if (sc->sc_flags & SC_OP_SCANNING) | ||
372 | goto set_timer; | ||
373 | |||
374 | /* Only calibrate if awake */ | 256 | /* Only calibrate if awake */ |
375 | if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE) | 257 | if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE) |
376 | goto set_timer; | 258 | goto set_timer; |
@@ -437,7 +319,6 @@ static void ath_ani_calibrate(unsigned long data) | |||
437 | ath9k_ps_restore(sc); | 319 | ath9k_ps_restore(sc); |
438 | 320 | ||
439 | set_timer: | 321 | set_timer: |
440 | spin_unlock(&sc->ani_lock); | ||
441 | /* | 322 | /* |
442 | * Set timer interval based on previous results. | 323 | * Set timer interval based on previous results. |
443 | * The interval must be the shortest necessary to satisfy ANI, | 324 | * The interval must be the shortest necessary to satisfy ANI, |
@@ -513,7 +394,7 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) | |||
513 | ath_tx_node_cleanup(sc, an); | 394 | ath_tx_node_cleanup(sc, an); |
514 | } | 395 | } |
515 | 396 | ||
516 | static void ath9k_tasklet(unsigned long data) | 397 | void ath9k_tasklet(unsigned long data) |
517 | { | 398 | { |
518 | struct ath_softc *sc = (struct ath_softc *)data; | 399 | struct ath_softc *sc = (struct ath_softc *)data; |
519 | struct ath_hw *ah = sc->sc_ah; | 400 | struct ath_hw *ah = sc->sc_ah; |
@@ -545,7 +426,7 @@ static void ath9k_tasklet(unsigned long data) | |||
545 | */ | 426 | */ |
546 | ath_print(common, ATH_DBG_PS, | 427 | ath_print(common, ATH_DBG_PS, |
547 | "TSFOOR - Sync with next Beacon\n"); | 428 | "TSFOOR - Sync with next Beacon\n"); |
548 | sc->sc_flags |= SC_OP_WAIT_FOR_BEACON | SC_OP_BEACON_SYNC; | 429 | sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC; |
549 | } | 430 | } |
550 | 431 | ||
551 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) | 432 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) |
@@ -646,7 +527,7 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
646 | * receive frames */ | 527 | * receive frames */ |
647 | ath9k_setpower(sc, ATH9K_PM_AWAKE); | 528 | ath9k_setpower(sc, ATH9K_PM_AWAKE); |
648 | ath9k_hw_setrxabort(sc->sc_ah, 0); | 529 | ath9k_hw_setrxabort(sc->sc_ah, 0); |
649 | sc->sc_flags |= SC_OP_WAIT_FOR_BEACON; | 530 | sc->ps_flags |= PS_WAIT_FOR_BEACON; |
650 | } | 531 | } |
651 | 532 | ||
652 | chip_reset: | 533 | chip_reset: |
@@ -928,49 +809,12 @@ static void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf | |||
928 | 809 | ||
929 | clear_bit(key->hw_key_idx + 64, common->keymap); | 810 | clear_bit(key->hw_key_idx + 64, common->keymap); |
930 | if (common->splitmic) { | 811 | if (common->splitmic) { |
812 | ath9k_hw_keyreset(ah, key->hw_key_idx + 32); | ||
931 | clear_bit(key->hw_key_idx + 32, common->keymap); | 813 | clear_bit(key->hw_key_idx + 32, common->keymap); |
932 | clear_bit(key->hw_key_idx + 64 + 32, common->keymap); | 814 | clear_bit(key->hw_key_idx + 64 + 32, common->keymap); |
933 | } | 815 | } |
934 | } | 816 | } |
935 | 817 | ||
936 | static void setup_ht_cap(struct ath_softc *sc, | ||
937 | struct ieee80211_sta_ht_cap *ht_info) | ||
938 | { | ||
939 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
940 | u8 tx_streams, rx_streams; | ||
941 | |||
942 | ht_info->ht_supported = true; | ||
943 | ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | | ||
944 | IEEE80211_HT_CAP_SM_PS | | ||
945 | IEEE80211_HT_CAP_SGI_40 | | ||
946 | IEEE80211_HT_CAP_DSSSCCK40; | ||
947 | |||
948 | ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; | ||
949 | ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; | ||
950 | |||
951 | /* set up supported mcs set */ | ||
952 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); | ||
953 | tx_streams = !(common->tx_chainmask & (common->tx_chainmask - 1)) ? | ||
954 | 1 : 2; | ||
955 | rx_streams = !(common->rx_chainmask & (common->rx_chainmask - 1)) ? | ||
956 | 1 : 2; | ||
957 | |||
958 | if (tx_streams != rx_streams) { | ||
959 | ath_print(common, ATH_DBG_CONFIG, | ||
960 | "TX streams %d, RX streams: %d\n", | ||
961 | tx_streams, rx_streams); | ||
962 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; | ||
963 | ht_info->mcs.tx_params |= ((tx_streams - 1) << | ||
964 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); | ||
965 | } | ||
966 | |||
967 | ht_info->mcs.rx_mask[0] = 0xff; | ||
968 | if (rx_streams >= 2) | ||
969 | ht_info->mcs.rx_mask[1] = 0xff; | ||
970 | |||
971 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED; | ||
972 | } | ||
973 | |||
974 | static void ath9k_bss_assoc_info(struct ath_softc *sc, | 818 | static void ath9k_bss_assoc_info(struct ath_softc *sc, |
975 | struct ieee80211_vif *vif, | 819 | struct ieee80211_vif *vif, |
976 | struct ieee80211_bss_conf *bss_conf) | 820 | struct ieee80211_bss_conf *bss_conf) |
@@ -992,7 +836,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, | |||
992 | * on the receipt of the first Beacon frame (i.e., | 836 | * on the receipt of the first Beacon frame (i.e., |
993 | * after time sync with the AP). | 837 | * after time sync with the AP). |
994 | */ | 838 | */ |
995 | sc->sc_flags |= SC_OP_BEACON_SYNC; | 839 | sc->ps_flags |= PS_BEACON_SYNC; |
996 | 840 | ||
997 | /* Configure the beacon */ | 841 | /* Configure the beacon */ |
998 | ath_beacon_config(sc, vif); | 842 | ath_beacon_config(sc, vif); |
@@ -1009,174 +853,6 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, | |||
1009 | } | 853 | } |
1010 | } | 854 | } |
1011 | 855 | ||
1012 | /********************************/ | ||
1013 | /* LED functions */ | ||
1014 | /********************************/ | ||
1015 | |||
1016 | static void ath_led_blink_work(struct work_struct *work) | ||
1017 | { | ||
1018 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
1019 | ath_led_blink_work.work); | ||
1020 | |||
1021 | if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED)) | ||
1022 | return; | ||
1023 | |||
1024 | if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) || | ||
1025 | (sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE)) | ||
1026 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0); | ||
1027 | else | ||
1028 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, | ||
1029 | (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0); | ||
1030 | |||
1031 | ieee80211_queue_delayed_work(sc->hw, | ||
1032 | &sc->ath_led_blink_work, | ||
1033 | (sc->sc_flags & SC_OP_LED_ON) ? | ||
1034 | msecs_to_jiffies(sc->led_off_duration) : | ||
1035 | msecs_to_jiffies(sc->led_on_duration)); | ||
1036 | |||
1037 | sc->led_on_duration = sc->led_on_cnt ? | ||
1038 | max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) : | ||
1039 | ATH_LED_ON_DURATION_IDLE; | ||
1040 | sc->led_off_duration = sc->led_off_cnt ? | ||
1041 | max((ATH_LED_OFF_DURATION_IDLE - sc->led_off_cnt), 10) : | ||
1042 | ATH_LED_OFF_DURATION_IDLE; | ||
1043 | sc->led_on_cnt = sc->led_off_cnt = 0; | ||
1044 | if (sc->sc_flags & SC_OP_LED_ON) | ||
1045 | sc->sc_flags &= ~SC_OP_LED_ON; | ||
1046 | else | ||
1047 | sc->sc_flags |= SC_OP_LED_ON; | ||
1048 | } | ||
1049 | |||
1050 | static void ath_led_brightness(struct led_classdev *led_cdev, | ||
1051 | enum led_brightness brightness) | ||
1052 | { | ||
1053 | struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev); | ||
1054 | struct ath_softc *sc = led->sc; | ||
1055 | |||
1056 | switch (brightness) { | ||
1057 | case LED_OFF: | ||
1058 | if (led->led_type == ATH_LED_ASSOC || | ||
1059 | led->led_type == ATH_LED_RADIO) { | ||
1060 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, | ||
1061 | (led->led_type == ATH_LED_RADIO)); | ||
1062 | sc->sc_flags &= ~SC_OP_LED_ASSOCIATED; | ||
1063 | if (led->led_type == ATH_LED_RADIO) | ||
1064 | sc->sc_flags &= ~SC_OP_LED_ON; | ||
1065 | } else { | ||
1066 | sc->led_off_cnt++; | ||
1067 | } | ||
1068 | break; | ||
1069 | case LED_FULL: | ||
1070 | if (led->led_type == ATH_LED_ASSOC) { | ||
1071 | sc->sc_flags |= SC_OP_LED_ASSOCIATED; | ||
1072 | ieee80211_queue_delayed_work(sc->hw, | ||
1073 | &sc->ath_led_blink_work, 0); | ||
1074 | } else if (led->led_type == ATH_LED_RADIO) { | ||
1075 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0); | ||
1076 | sc->sc_flags |= SC_OP_LED_ON; | ||
1077 | } else { | ||
1078 | sc->led_on_cnt++; | ||
1079 | } | ||
1080 | break; | ||
1081 | default: | ||
1082 | break; | ||
1083 | } | ||
1084 | } | ||
1085 | |||
1086 | static int ath_register_led(struct ath_softc *sc, struct ath_led *led, | ||
1087 | char *trigger) | ||
1088 | { | ||
1089 | int ret; | ||
1090 | |||
1091 | led->sc = sc; | ||
1092 | led->led_cdev.name = led->name; | ||
1093 | led->led_cdev.default_trigger = trigger; | ||
1094 | led->led_cdev.brightness_set = ath_led_brightness; | ||
1095 | |||
1096 | ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev); | ||
1097 | if (ret) | ||
1098 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, | ||
1099 | "Failed to register led:%s", led->name); | ||
1100 | else | ||
1101 | led->registered = 1; | ||
1102 | return ret; | ||
1103 | } | ||
1104 | |||
1105 | static void ath_unregister_led(struct ath_led *led) | ||
1106 | { | ||
1107 | if (led->registered) { | ||
1108 | led_classdev_unregister(&led->led_cdev); | ||
1109 | led->registered = 0; | ||
1110 | } | ||
1111 | } | ||
1112 | |||
1113 | static void ath_deinit_leds(struct ath_softc *sc) | ||
1114 | { | ||
1115 | ath_unregister_led(&sc->assoc_led); | ||
1116 | sc->sc_flags &= ~SC_OP_LED_ASSOCIATED; | ||
1117 | ath_unregister_led(&sc->tx_led); | ||
1118 | ath_unregister_led(&sc->rx_led); | ||
1119 | ath_unregister_led(&sc->radio_led); | ||
1120 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); | ||
1121 | } | ||
1122 | |||
1123 | static void ath_init_leds(struct ath_softc *sc) | ||
1124 | { | ||
1125 | char *trigger; | ||
1126 | int ret; | ||
1127 | |||
1128 | if (AR_SREV_9287(sc->sc_ah)) | ||
1129 | sc->sc_ah->led_pin = ATH_LED_PIN_9287; | ||
1130 | else | ||
1131 | sc->sc_ah->led_pin = ATH_LED_PIN_DEF; | ||
1132 | |||
1133 | /* Configure gpio 1 for output */ | ||
1134 | ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin, | ||
1135 | AR_GPIO_OUTPUT_MUX_AS_OUTPUT); | ||
1136 | /* LED off, active low */ | ||
1137 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); | ||
1138 | |||
1139 | INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work); | ||
1140 | |||
1141 | trigger = ieee80211_get_radio_led_name(sc->hw); | ||
1142 | snprintf(sc->radio_led.name, sizeof(sc->radio_led.name), | ||
1143 | "ath9k-%s::radio", wiphy_name(sc->hw->wiphy)); | ||
1144 | ret = ath_register_led(sc, &sc->radio_led, trigger); | ||
1145 | sc->radio_led.led_type = ATH_LED_RADIO; | ||
1146 | if (ret) | ||
1147 | goto fail; | ||
1148 | |||
1149 | trigger = ieee80211_get_assoc_led_name(sc->hw); | ||
1150 | snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name), | ||
1151 | "ath9k-%s::assoc", wiphy_name(sc->hw->wiphy)); | ||
1152 | ret = ath_register_led(sc, &sc->assoc_led, trigger); | ||
1153 | sc->assoc_led.led_type = ATH_LED_ASSOC; | ||
1154 | if (ret) | ||
1155 | goto fail; | ||
1156 | |||
1157 | trigger = ieee80211_get_tx_led_name(sc->hw); | ||
1158 | snprintf(sc->tx_led.name, sizeof(sc->tx_led.name), | ||
1159 | "ath9k-%s::tx", wiphy_name(sc->hw->wiphy)); | ||
1160 | ret = ath_register_led(sc, &sc->tx_led, trigger); | ||
1161 | sc->tx_led.led_type = ATH_LED_TX; | ||
1162 | if (ret) | ||
1163 | goto fail; | ||
1164 | |||
1165 | trigger = ieee80211_get_rx_led_name(sc->hw); | ||
1166 | snprintf(sc->rx_led.name, sizeof(sc->rx_led.name), | ||
1167 | "ath9k-%s::rx", wiphy_name(sc->hw->wiphy)); | ||
1168 | ret = ath_register_led(sc, &sc->rx_led, trigger); | ||
1169 | sc->rx_led.led_type = ATH_LED_RX; | ||
1170 | if (ret) | ||
1171 | goto fail; | ||
1172 | |||
1173 | return; | ||
1174 | |||
1175 | fail: | ||
1176 | cancel_delayed_work_sync(&sc->ath_led_blink_work); | ||
1177 | ath_deinit_leds(sc); | ||
1178 | } | ||
1179 | |||
1180 | void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) | 856 | void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) |
1181 | { | 857 | { |
1182 | struct ath_hw *ah = sc->sc_ah; | 858 | struct ath_hw *ah = sc->sc_ah; |
@@ -1194,7 +870,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
1194 | r = ath9k_hw_reset(ah, ah->curchan, false); | 870 | r = ath9k_hw_reset(ah, ah->curchan, false); |
1195 | if (r) { | 871 | if (r) { |
1196 | ath_print(common, ATH_DBG_FATAL, | 872 | ath_print(common, ATH_DBG_FATAL, |
1197 | "Unable to reset channel %u (%uMhz) ", | 873 | "Unable to reset channel (%u MHz), " |
1198 | "reset status %d\n", | 874 | "reset status %d\n", |
1199 | channel->center_freq, r); | 875 | channel->center_freq, r); |
1200 | } | 876 | } |
@@ -1249,7 +925,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
1249 | r = ath9k_hw_reset(ah, ah->curchan, false); | 925 | r = ath9k_hw_reset(ah, ah->curchan, false); |
1250 | if (r) { | 926 | if (r) { |
1251 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, | 927 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, |
1252 | "Unable to reset channel %u (%uMhz) " | 928 | "Unable to reset channel (%u MHz), " |
1253 | "reset status %d\n", | 929 | "reset status %d\n", |
1254 | channel->center_freq, r); | 930 | channel->center_freq, r); |
1255 | } | 931 | } |
@@ -1261,711 +937,6 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
1261 | ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); | 937 | ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); |
1262 | } | 938 | } |
1263 | 939 | ||
1264 | /*******************/ | ||
1265 | /* Rfkill */ | ||
1266 | /*******************/ | ||
1267 | |||
1268 | static bool ath_is_rfkill_set(struct ath_softc *sc) | ||
1269 | { | ||
1270 | struct ath_hw *ah = sc->sc_ah; | ||
1271 | |||
1272 | return ath9k_hw_gpio_get(ah, ah->rfkill_gpio) == | ||
1273 | ah->rfkill_polarity; | ||
1274 | } | ||
1275 | |||
1276 | static void ath9k_rfkill_poll_state(struct ieee80211_hw *hw) | ||
1277 | { | ||
1278 | struct ath_wiphy *aphy = hw->priv; | ||
1279 | struct ath_softc *sc = aphy->sc; | ||
1280 | bool blocked = !!ath_is_rfkill_set(sc); | ||
1281 | |||
1282 | wiphy_rfkill_set_hw_state(hw->wiphy, blocked); | ||
1283 | } | ||
1284 | |||
1285 | static void ath_start_rfkill_poll(struct ath_softc *sc) | ||
1286 | { | ||
1287 | struct ath_hw *ah = sc->sc_ah; | ||
1288 | |||
1289 | if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | ||
1290 | wiphy_rfkill_start_polling(sc->hw->wiphy); | ||
1291 | } | ||
1292 | |||
1293 | static void ath9k_uninit_hw(struct ath_softc *sc) | ||
1294 | { | ||
1295 | struct ath_hw *ah = sc->sc_ah; | ||
1296 | |||
1297 | BUG_ON(!ah); | ||
1298 | |||
1299 | ath9k_exit_debug(ah); | ||
1300 | ath9k_hw_detach(ah); | ||
1301 | sc->sc_ah = NULL; | ||
1302 | } | ||
1303 | |||
1304 | static void ath_clean_core(struct ath_softc *sc) | ||
1305 | { | ||
1306 | struct ieee80211_hw *hw = sc->hw; | ||
1307 | struct ath_hw *ah = sc->sc_ah; | ||
1308 | int i = 0; | ||
1309 | |||
1310 | ath9k_ps_wakeup(sc); | ||
1311 | |||
1312 | dev_dbg(sc->dev, "Detach ATH hw\n"); | ||
1313 | |||
1314 | ath_deinit_leds(sc); | ||
1315 | wiphy_rfkill_stop_polling(sc->hw->wiphy); | ||
1316 | |||
1317 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
1318 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | ||
1319 | if (aphy == NULL) | ||
1320 | continue; | ||
1321 | sc->sec_wiphy[i] = NULL; | ||
1322 | ieee80211_unregister_hw(aphy->hw); | ||
1323 | ieee80211_free_hw(aphy->hw); | ||
1324 | } | ||
1325 | ieee80211_unregister_hw(hw); | ||
1326 | ath_rx_cleanup(sc); | ||
1327 | ath_tx_cleanup(sc); | ||
1328 | |||
1329 | tasklet_kill(&sc->intr_tq); | ||
1330 | tasklet_kill(&sc->bcon_tasklet); | ||
1331 | |||
1332 | if (!(sc->sc_flags & SC_OP_INVALID)) | ||
1333 | ath9k_setpower(sc, ATH9K_PM_AWAKE); | ||
1334 | |||
1335 | /* cleanup tx queues */ | ||
1336 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | ||
1337 | if (ATH_TXQ_SETUP(sc, i)) | ||
1338 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | ||
1339 | |||
1340 | if ((sc->btcoex.no_stomp_timer) && | ||
1341 | ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) | ||
1342 | ath_gen_timer_free(ah, sc->btcoex.no_stomp_timer); | ||
1343 | } | ||
1344 | |||
1345 | void ath_detach(struct ath_softc *sc) | ||
1346 | { | ||
1347 | ath_clean_core(sc); | ||
1348 | ath9k_uninit_hw(sc); | ||
1349 | } | ||
1350 | |||
1351 | void ath_cleanup(struct ath_softc *sc) | ||
1352 | { | ||
1353 | struct ath_hw *ah = sc->sc_ah; | ||
1354 | struct ath_common *common = ath9k_hw_common(ah); | ||
1355 | |||
1356 | ath_clean_core(sc); | ||
1357 | free_irq(sc->irq, sc); | ||
1358 | ath_bus_cleanup(common); | ||
1359 | kfree(sc->sec_wiphy); | ||
1360 | ieee80211_free_hw(sc->hw); | ||
1361 | |||
1362 | ath9k_uninit_hw(sc); | ||
1363 | } | ||
1364 | |||
1365 | static int ath9k_reg_notifier(struct wiphy *wiphy, | ||
1366 | struct regulatory_request *request) | ||
1367 | { | ||
1368 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); | ||
1369 | struct ath_wiphy *aphy = hw->priv; | ||
1370 | struct ath_softc *sc = aphy->sc; | ||
1371 | struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah); | ||
1372 | |||
1373 | return ath_reg_notifier_apply(wiphy, request, reg); | ||
1374 | } | ||
1375 | |||
1376 | /* | ||
1377 | * Detects if there is any priority bt traffic | ||
1378 | */ | ||
1379 | static void ath_detect_bt_priority(struct ath_softc *sc) | ||
1380 | { | ||
1381 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
1382 | struct ath_hw *ah = sc->sc_ah; | ||
1383 | |||
1384 | if (ath9k_hw_gpio_get(sc->sc_ah, ah->btcoex_hw.btpriority_gpio)) | ||
1385 | btcoex->bt_priority_cnt++; | ||
1386 | |||
1387 | if (time_after(jiffies, btcoex->bt_priority_time + | ||
1388 | msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) { | ||
1389 | if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { | ||
1390 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX, | ||
1391 | "BT priority traffic detected"); | ||
1392 | sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED; | ||
1393 | } else { | ||
1394 | sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED; | ||
1395 | } | ||
1396 | |||
1397 | btcoex->bt_priority_cnt = 0; | ||
1398 | btcoex->bt_priority_time = jiffies; | ||
1399 | } | ||
1400 | } | ||
1401 | |||
1402 | /* | ||
1403 | * Configures appropriate weight based on stomp type. | ||
1404 | */ | ||
1405 | static void ath9k_btcoex_bt_stomp(struct ath_softc *sc, | ||
1406 | enum ath_stomp_type stomp_type) | ||
1407 | { | ||
1408 | struct ath_hw *ah = sc->sc_ah; | ||
1409 | |||
1410 | switch (stomp_type) { | ||
1411 | case ATH_BTCOEX_STOMP_ALL: | ||
1412 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
1413 | AR_STOMP_ALL_WLAN_WGHT); | ||
1414 | break; | ||
1415 | case ATH_BTCOEX_STOMP_LOW: | ||
1416 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
1417 | AR_STOMP_LOW_WLAN_WGHT); | ||
1418 | break; | ||
1419 | case ATH_BTCOEX_STOMP_NONE: | ||
1420 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
1421 | AR_STOMP_NONE_WLAN_WGHT); | ||
1422 | break; | ||
1423 | default: | ||
1424 | ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | ||
1425 | "Invalid Stomptype\n"); | ||
1426 | break; | ||
1427 | } | ||
1428 | |||
1429 | ath9k_hw_btcoex_enable(ah); | ||
1430 | } | ||
1431 | |||
1432 | static void ath9k_gen_timer_start(struct ath_hw *ah, | ||
1433 | struct ath_gen_timer *timer, | ||
1434 | u32 timer_next, | ||
1435 | u32 timer_period) | ||
1436 | { | ||
1437 | struct ath_common *common = ath9k_hw_common(ah); | ||
1438 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
1439 | |||
1440 | ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period); | ||
1441 | |||
1442 | if ((sc->imask & ATH9K_INT_GENTIMER) == 0) { | ||
1443 | ath9k_hw_set_interrupts(ah, 0); | ||
1444 | sc->imask |= ATH9K_INT_GENTIMER; | ||
1445 | ath9k_hw_set_interrupts(ah, sc->imask); | ||
1446 | } | ||
1447 | } | ||
1448 | |||
1449 | static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer) | ||
1450 | { | ||
1451 | struct ath_common *common = ath9k_hw_common(ah); | ||
1452 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
1453 | struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; | ||
1454 | |||
1455 | ath9k_hw_gen_timer_stop(ah, timer); | ||
1456 | |||
1457 | /* if no timer is enabled, turn off interrupt mask */ | ||
1458 | if (timer_table->timer_mask.val == 0) { | ||
1459 | ath9k_hw_set_interrupts(ah, 0); | ||
1460 | sc->imask &= ~ATH9K_INT_GENTIMER; | ||
1461 | ath9k_hw_set_interrupts(ah, sc->imask); | ||
1462 | } | ||
1463 | } | ||
1464 | |||
1465 | /* | ||
1466 | * This is the master bt coex timer which runs for every | ||
1467 | * 45ms, bt traffic will be given priority during 55% of this | ||
1468 | * period while wlan gets remaining 45% | ||
1469 | */ | ||
1470 | static void ath_btcoex_period_timer(unsigned long data) | ||
1471 | { | ||
1472 | struct ath_softc *sc = (struct ath_softc *) data; | ||
1473 | struct ath_hw *ah = sc->sc_ah; | ||
1474 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
1475 | |||
1476 | ath_detect_bt_priority(sc); | ||
1477 | |||
1478 | spin_lock_bh(&btcoex->btcoex_lock); | ||
1479 | |||
1480 | ath9k_btcoex_bt_stomp(sc, btcoex->bt_stomp_type); | ||
1481 | |||
1482 | spin_unlock_bh(&btcoex->btcoex_lock); | ||
1483 | |||
1484 | if (btcoex->btcoex_period != btcoex->btcoex_no_stomp) { | ||
1485 | if (btcoex->hw_timer_enabled) | ||
1486 | ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer); | ||
1487 | |||
1488 | ath9k_gen_timer_start(ah, | ||
1489 | btcoex->no_stomp_timer, | ||
1490 | (ath9k_hw_gettsf32(ah) + | ||
1491 | btcoex->btcoex_no_stomp), | ||
1492 | btcoex->btcoex_no_stomp * 10); | ||
1493 | btcoex->hw_timer_enabled = true; | ||
1494 | } | ||
1495 | |||
1496 | mod_timer(&btcoex->period_timer, jiffies + | ||
1497 | msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD)); | ||
1498 | } | ||
1499 | |||
1500 | /* | ||
1501 | * Generic tsf based hw timer which configures weight | ||
1502 | * registers to time slice between wlan and bt traffic | ||
1503 | */ | ||
1504 | static void ath_btcoex_no_stomp_timer(void *arg) | ||
1505 | { | ||
1506 | struct ath_softc *sc = (struct ath_softc *)arg; | ||
1507 | struct ath_hw *ah = sc->sc_ah; | ||
1508 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
1509 | |||
1510 | ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | ||
1511 | "no stomp timer running \n"); | ||
1512 | |||
1513 | spin_lock_bh(&btcoex->btcoex_lock); | ||
1514 | |||
1515 | if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW) | ||
1516 | ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_NONE); | ||
1517 | else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) | ||
1518 | ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_LOW); | ||
1519 | |||
1520 | spin_unlock_bh(&btcoex->btcoex_lock); | ||
1521 | } | ||
1522 | |||
1523 | static int ath_init_btcoex_timer(struct ath_softc *sc) | ||
1524 | { | ||
1525 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
1526 | |||
1527 | btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000; | ||
1528 | btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * | ||
1529 | btcoex->btcoex_period / 100; | ||
1530 | |||
1531 | setup_timer(&btcoex->period_timer, ath_btcoex_period_timer, | ||
1532 | (unsigned long) sc); | ||
1533 | |||
1534 | spin_lock_init(&btcoex->btcoex_lock); | ||
1535 | |||
1536 | btcoex->no_stomp_timer = ath_gen_timer_alloc(sc->sc_ah, | ||
1537 | ath_btcoex_no_stomp_timer, | ||
1538 | ath_btcoex_no_stomp_timer, | ||
1539 | (void *) sc, AR_FIRST_NDP_TIMER); | ||
1540 | |||
1541 | if (!btcoex->no_stomp_timer) | ||
1542 | return -ENOMEM; | ||
1543 | |||
1544 | return 0; | ||
1545 | } | ||
1546 | |||
1547 | /* | ||
1548 | * Read and write, they both share the same lock. We do this to serialize | ||
1549 | * reads and writes on Atheros 802.11n PCI devices only. This is required | ||
1550 | * as the FIFO on these devices can only accept sanely 2 requests. After | ||
1551 | * that the device goes bananas. Serializing the reads/writes prevents this | ||
1552 | * from happening. | ||
1553 | */ | ||
1554 | |||
1555 | static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset) | ||
1556 | { | ||
1557 | struct ath_hw *ah = (struct ath_hw *) hw_priv; | ||
1558 | struct ath_common *common = ath9k_hw_common(ah); | ||
1559 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
1560 | |||
1561 | if (ah->config.serialize_regmode == SER_REG_MODE_ON) { | ||
1562 | unsigned long flags; | ||
1563 | spin_lock_irqsave(&sc->sc_serial_rw, flags); | ||
1564 | iowrite32(val, sc->mem + reg_offset); | ||
1565 | spin_unlock_irqrestore(&sc->sc_serial_rw, flags); | ||
1566 | } else | ||
1567 | iowrite32(val, sc->mem + reg_offset); | ||
1568 | } | ||
1569 | |||
1570 | static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset) | ||
1571 | { | ||
1572 | struct ath_hw *ah = (struct ath_hw *) hw_priv; | ||
1573 | struct ath_common *common = ath9k_hw_common(ah); | ||
1574 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
1575 | u32 val; | ||
1576 | |||
1577 | if (ah->config.serialize_regmode == SER_REG_MODE_ON) { | ||
1578 | unsigned long flags; | ||
1579 | spin_lock_irqsave(&sc->sc_serial_rw, flags); | ||
1580 | val = ioread32(sc->mem + reg_offset); | ||
1581 | spin_unlock_irqrestore(&sc->sc_serial_rw, flags); | ||
1582 | } else | ||
1583 | val = ioread32(sc->mem + reg_offset); | ||
1584 | return val; | ||
1585 | } | ||
1586 | |||
1587 | static const struct ath_ops ath9k_common_ops = { | ||
1588 | .read = ath9k_ioread32, | ||
1589 | .write = ath9k_iowrite32, | ||
1590 | }; | ||
1591 | |||
1592 | /* | ||
1593 | * Initialize and fill ath_softc, ath_sofct is the | ||
1594 | * "Software Carrier" struct. Historically it has existed | ||
1595 | * to allow the separation between hardware specific | ||
1596 | * variables (now in ath_hw) and driver specific variables. | ||
1597 | */ | ||
1598 | static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, | ||
1599 | const struct ath_bus_ops *bus_ops) | ||
1600 | { | ||
1601 | struct ath_hw *ah = NULL; | ||
1602 | struct ath_common *common; | ||
1603 | int r = 0, i; | ||
1604 | int csz = 0; | ||
1605 | int qnum; | ||
1606 | |||
1607 | /* XXX: hardware will not be ready until ath_open() being called */ | ||
1608 | sc->sc_flags |= SC_OP_INVALID; | ||
1609 | |||
1610 | spin_lock_init(&sc->wiphy_lock); | ||
1611 | spin_lock_init(&sc->sc_resetlock); | ||
1612 | spin_lock_init(&sc->sc_serial_rw); | ||
1613 | spin_lock_init(&sc->ani_lock); | ||
1614 | spin_lock_init(&sc->sc_pm_lock); | ||
1615 | mutex_init(&sc->mutex); | ||
1616 | tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); | ||
1617 | tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, | ||
1618 | (unsigned long)sc); | ||
1619 | |||
1620 | ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL); | ||
1621 | if (!ah) | ||
1622 | return -ENOMEM; | ||
1623 | |||
1624 | ah->hw_version.devid = devid; | ||
1625 | ah->hw_version.subsysid = subsysid; | ||
1626 | sc->sc_ah = ah; | ||
1627 | |||
1628 | common = ath9k_hw_common(ah); | ||
1629 | common->ops = &ath9k_common_ops; | ||
1630 | common->bus_ops = bus_ops; | ||
1631 | common->ah = ah; | ||
1632 | common->hw = sc->hw; | ||
1633 | common->priv = sc; | ||
1634 | common->debug_mask = ath9k_debug; | ||
1635 | |||
1636 | /* | ||
1637 | * Cache line size is used to size and align various | ||
1638 | * structures used to communicate with the hardware. | ||
1639 | */ | ||
1640 | ath_read_cachesize(common, &csz); | ||
1641 | /* XXX assert csz is non-zero */ | ||
1642 | common->cachelsz = csz << 2; /* convert to bytes */ | ||
1643 | |||
1644 | r = ath9k_hw_init(ah); | ||
1645 | if (r) { | ||
1646 | ath_print(common, ATH_DBG_FATAL, | ||
1647 | "Unable to initialize hardware; " | ||
1648 | "initialization status: %d\n", r); | ||
1649 | goto bad_free_hw; | ||
1650 | } | ||
1651 | |||
1652 | if (ath9k_init_debug(ah) < 0) { | ||
1653 | ath_print(common, ATH_DBG_FATAL, | ||
1654 | "Unable to create debugfs files\n"); | ||
1655 | goto bad_free_hw; | ||
1656 | } | ||
1657 | |||
1658 | /* Get the hardware key cache size. */ | ||
1659 | common->keymax = ah->caps.keycache_size; | ||
1660 | if (common->keymax > ATH_KEYMAX) { | ||
1661 | ath_print(common, ATH_DBG_ANY, | ||
1662 | "Warning, using only %u entries in %u key cache\n", | ||
1663 | ATH_KEYMAX, common->keymax); | ||
1664 | common->keymax = ATH_KEYMAX; | ||
1665 | } | ||
1666 | |||
1667 | /* | ||
1668 | * Reset the key cache since some parts do not | ||
1669 | * reset the contents on initial power up. | ||
1670 | */ | ||
1671 | for (i = 0; i < common->keymax; i++) | ||
1672 | ath9k_hw_keyreset(ah, (u16) i); | ||
1673 | |||
1674 | /* default to MONITOR mode */ | ||
1675 | sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR; | ||
1676 | |||
1677 | /* | ||
1678 | * Allocate hardware transmit queues: one queue for | ||
1679 | * beacon frames and one data queue for each QoS | ||
1680 | * priority. Note that the hal handles reseting | ||
1681 | * these queues at the needed time. | ||
1682 | */ | ||
1683 | sc->beacon.beaconq = ath9k_hw_beaconq_setup(ah); | ||
1684 | if (sc->beacon.beaconq == -1) { | ||
1685 | ath_print(common, ATH_DBG_FATAL, | ||
1686 | "Unable to setup a beacon xmit queue\n"); | ||
1687 | r = -EIO; | ||
1688 | goto bad2; | ||
1689 | } | ||
1690 | sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); | ||
1691 | if (sc->beacon.cabq == NULL) { | ||
1692 | ath_print(common, ATH_DBG_FATAL, | ||
1693 | "Unable to setup CAB xmit queue\n"); | ||
1694 | r = -EIO; | ||
1695 | goto bad2; | ||
1696 | } | ||
1697 | |||
1698 | sc->config.cabqReadytime = ATH_CABQ_READY_TIME; | ||
1699 | ath_cabq_update(sc); | ||
1700 | |||
1701 | for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++) | ||
1702 | sc->tx.hwq_map[i] = -1; | ||
1703 | |||
1704 | /* Setup data queues */ | ||
1705 | /* NB: ensure BK queue is the lowest priority h/w queue */ | ||
1706 | if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) { | ||
1707 | ath_print(common, ATH_DBG_FATAL, | ||
1708 | "Unable to setup xmit queue for BK traffic\n"); | ||
1709 | r = -EIO; | ||
1710 | goto bad2; | ||
1711 | } | ||
1712 | |||
1713 | if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) { | ||
1714 | ath_print(common, ATH_DBG_FATAL, | ||
1715 | "Unable to setup xmit queue for BE traffic\n"); | ||
1716 | r = -EIO; | ||
1717 | goto bad2; | ||
1718 | } | ||
1719 | if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) { | ||
1720 | ath_print(common, ATH_DBG_FATAL, | ||
1721 | "Unable to setup xmit queue for VI traffic\n"); | ||
1722 | r = -EIO; | ||
1723 | goto bad2; | ||
1724 | } | ||
1725 | if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) { | ||
1726 | ath_print(common, ATH_DBG_FATAL, | ||
1727 | "Unable to setup xmit queue for VO traffic\n"); | ||
1728 | r = -EIO; | ||
1729 | goto bad2; | ||
1730 | } | ||
1731 | |||
1732 | /* Initializes the noise floor to a reasonable default value. | ||
1733 | * Later on this will be updated during ANI processing. */ | ||
1734 | |||
1735 | common->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR; | ||
1736 | setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); | ||
1737 | |||
1738 | if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, | ||
1739 | ATH9K_CIPHER_TKIP, NULL)) { | ||
1740 | /* | ||
1741 | * Whether we should enable h/w TKIP MIC. | ||
1742 | * XXX: if we don't support WME TKIP MIC, then we wouldn't | ||
1743 | * report WMM capable, so it's always safe to turn on | ||
1744 | * TKIP MIC in this case. | ||
1745 | */ | ||
1746 | ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_TKIP_MIC, | ||
1747 | 0, 1, NULL); | ||
1748 | } | ||
1749 | |||
1750 | /* | ||
1751 | * Check whether the separate key cache entries | ||
1752 | * are required to handle both tx+rx MIC keys. | ||
1753 | * With split mic keys the number of stations is limited | ||
1754 | * to 27 otherwise 59. | ||
1755 | */ | ||
1756 | if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, | ||
1757 | ATH9K_CIPHER_TKIP, NULL) | ||
1758 | && ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, | ||
1759 | ATH9K_CIPHER_MIC, NULL) | ||
1760 | && ath9k_hw_getcapability(ah, ATH9K_CAP_TKIP_SPLIT, | ||
1761 | 0, NULL)) | ||
1762 | common->splitmic = 1; | ||
1763 | |||
1764 | /* turn on mcast key search if possible */ | ||
1765 | if (!ath9k_hw_getcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL)) | ||
1766 | (void)ath9k_hw_setcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 1, | ||
1767 | 1, NULL); | ||
1768 | |||
1769 | sc->config.txpowlimit = ATH_TXPOWER_MAX; | ||
1770 | |||
1771 | /* 11n Capabilities */ | ||
1772 | if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) { | ||
1773 | sc->sc_flags |= SC_OP_TXAGGR; | ||
1774 | sc->sc_flags |= SC_OP_RXAGGR; | ||
1775 | } | ||
1776 | |||
1777 | common->tx_chainmask = ah->caps.tx_chainmask; | ||
1778 | common->rx_chainmask = ah->caps.rx_chainmask; | ||
1779 | |||
1780 | ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL); | ||
1781 | sc->rx.defant = ath9k_hw_getdefantenna(ah); | ||
1782 | |||
1783 | if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) | ||
1784 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); | ||
1785 | |||
1786 | sc->beacon.slottime = ATH9K_SLOT_TIME_9; /* default to short slot time */ | ||
1787 | |||
1788 | /* initialize beacon slots */ | ||
1789 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) { | ||
1790 | sc->beacon.bslot[i] = NULL; | ||
1791 | sc->beacon.bslot_aphy[i] = NULL; | ||
1792 | } | ||
1793 | |||
1794 | /* setup channels and rates */ | ||
1795 | |||
1796 | if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) { | ||
1797 | sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable; | ||
1798 | sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; | ||
1799 | sc->sbands[IEEE80211_BAND_2GHZ].n_channels = | ||
1800 | ARRAY_SIZE(ath9k_2ghz_chantable); | ||
1801 | sc->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates; | ||
1802 | sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates = | ||
1803 | ARRAY_SIZE(ath9k_legacy_rates); | ||
1804 | } | ||
1805 | |||
1806 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) { | ||
1807 | sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable; | ||
1808 | sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; | ||
1809 | sc->sbands[IEEE80211_BAND_5GHZ].n_channels = | ||
1810 | ARRAY_SIZE(ath9k_5ghz_chantable); | ||
1811 | sc->sbands[IEEE80211_BAND_5GHZ].bitrates = | ||
1812 | ath9k_legacy_rates + 4; | ||
1813 | sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates = | ||
1814 | ARRAY_SIZE(ath9k_legacy_rates) - 4; | ||
1815 | } | ||
1816 | |||
1817 | switch (ah->btcoex_hw.scheme) { | ||
1818 | case ATH_BTCOEX_CFG_NONE: | ||
1819 | break; | ||
1820 | case ATH_BTCOEX_CFG_2WIRE: | ||
1821 | ath9k_hw_btcoex_init_2wire(ah); | ||
1822 | break; | ||
1823 | case ATH_BTCOEX_CFG_3WIRE: | ||
1824 | ath9k_hw_btcoex_init_3wire(ah); | ||
1825 | r = ath_init_btcoex_timer(sc); | ||
1826 | if (r) | ||
1827 | goto bad2; | ||
1828 | qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE); | ||
1829 | ath9k_hw_init_btcoex_hw(ah, qnum); | ||
1830 | sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; | ||
1831 | break; | ||
1832 | default: | ||
1833 | WARN_ON(1); | ||
1834 | break; | ||
1835 | } | ||
1836 | |||
1837 | return 0; | ||
1838 | bad2: | ||
1839 | /* cleanup tx queues */ | ||
1840 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | ||
1841 | if (ATH_TXQ_SETUP(sc, i)) | ||
1842 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | ||
1843 | |||
1844 | bad_free_hw: | ||
1845 | ath9k_uninit_hw(sc); | ||
1846 | return r; | ||
1847 | } | ||
1848 | |||
1849 | void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | ||
1850 | { | ||
1851 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | ||
1852 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
1853 | IEEE80211_HW_SIGNAL_DBM | | ||
1854 | IEEE80211_HW_AMPDU_AGGREGATION | | ||
1855 | IEEE80211_HW_SUPPORTS_PS | | ||
1856 | IEEE80211_HW_PS_NULLFUNC_STACK | | ||
1857 | IEEE80211_HW_SPECTRUM_MGMT; | ||
1858 | |||
1859 | if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt) | ||
1860 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; | ||
1861 | |||
1862 | hw->wiphy->interface_modes = | ||
1863 | BIT(NL80211_IFTYPE_AP) | | ||
1864 | BIT(NL80211_IFTYPE_STATION) | | ||
1865 | BIT(NL80211_IFTYPE_ADHOC) | | ||
1866 | BIT(NL80211_IFTYPE_MESH_POINT); | ||
1867 | |||
1868 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
1869 | |||
1870 | hw->queues = 4; | ||
1871 | hw->max_rates = 4; | ||
1872 | hw->channel_change_time = 5000; | ||
1873 | hw->max_listen_interval = 10; | ||
1874 | /* Hardware supports 10 but we use 4 */ | ||
1875 | hw->max_rate_tries = 4; | ||
1876 | hw->sta_data_size = sizeof(struct ath_node); | ||
1877 | hw->vif_data_size = sizeof(struct ath_vif); | ||
1878 | |||
1879 | hw->rate_control_algorithm = "ath9k_rate_control"; | ||
1880 | |||
1881 | if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) | ||
1882 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | ||
1883 | &sc->sbands[IEEE80211_BAND_2GHZ]; | ||
1884 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) | ||
1885 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | ||
1886 | &sc->sbands[IEEE80211_BAND_5GHZ]; | ||
1887 | } | ||
1888 | |||
1889 | /* Device driver core initialization */ | ||
1890 | int ath_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, | ||
1891 | const struct ath_bus_ops *bus_ops) | ||
1892 | { | ||
1893 | struct ieee80211_hw *hw = sc->hw; | ||
1894 | struct ath_common *common; | ||
1895 | struct ath_hw *ah; | ||
1896 | int error = 0, i; | ||
1897 | struct ath_regulatory *reg; | ||
1898 | |||
1899 | dev_dbg(sc->dev, "Attach ATH hw\n"); | ||
1900 | |||
1901 | error = ath_init_softc(devid, sc, subsysid, bus_ops); | ||
1902 | if (error != 0) | ||
1903 | return error; | ||
1904 | |||
1905 | ah = sc->sc_ah; | ||
1906 | common = ath9k_hw_common(ah); | ||
1907 | |||
1908 | /* get mac address from hardware and set in mac80211 */ | ||
1909 | |||
1910 | SET_IEEE80211_PERM_ADDR(hw, common->macaddr); | ||
1911 | |||
1912 | ath_set_hw_capab(sc, hw); | ||
1913 | |||
1914 | error = ath_regd_init(&common->regulatory, sc->hw->wiphy, | ||
1915 | ath9k_reg_notifier); | ||
1916 | if (error) | ||
1917 | return error; | ||
1918 | |||
1919 | reg = &common->regulatory; | ||
1920 | |||
1921 | if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) { | ||
1922 | if (test_bit(ATH9K_MODE_11G, ah->caps.wireless_modes)) | ||
1923 | setup_ht_cap(sc, | ||
1924 | &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); | ||
1925 | if (test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes)) | ||
1926 | setup_ht_cap(sc, | ||
1927 | &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); | ||
1928 | } | ||
1929 | |||
1930 | /* initialize tx/rx engine */ | ||
1931 | error = ath_tx_init(sc, ATH_TXBUF); | ||
1932 | if (error != 0) | ||
1933 | goto error_attach; | ||
1934 | |||
1935 | error = ath_rx_init(sc, ATH_RXBUF); | ||
1936 | if (error != 0) | ||
1937 | goto error_attach; | ||
1938 | |||
1939 | INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); | ||
1940 | INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); | ||
1941 | sc->wiphy_scheduler_int = msecs_to_jiffies(500); | ||
1942 | |||
1943 | error = ieee80211_register_hw(hw); | ||
1944 | |||
1945 | if (!ath_is_world_regd(reg)) { | ||
1946 | error = regulatory_hint(hw->wiphy, reg->alpha2); | ||
1947 | if (error) | ||
1948 | goto error_attach; | ||
1949 | } | ||
1950 | |||
1951 | /* Initialize LED control */ | ||
1952 | ath_init_leds(sc); | ||
1953 | |||
1954 | ath_start_rfkill_poll(sc); | ||
1955 | |||
1956 | return 0; | ||
1957 | |||
1958 | error_attach: | ||
1959 | /* cleanup tx queues */ | ||
1960 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | ||
1961 | if (ATH_TXQ_SETUP(sc, i)) | ||
1962 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | ||
1963 | |||
1964 | ath9k_uninit_hw(sc); | ||
1965 | |||
1966 | return error; | ||
1967 | } | ||
1968 | |||
1969 | int ath_reset(struct ath_softc *sc, bool retry_tx) | 940 | int ath_reset(struct ath_softc *sc, bool retry_tx) |
1970 | { | 941 | { |
1971 | struct ath_hw *ah = sc->sc_ah; | 942 | struct ath_hw *ah = sc->sc_ah; |
@@ -1976,6 +947,8 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
1976 | /* Stop ANI */ | 947 | /* Stop ANI */ |
1977 | del_timer_sync(&common->ani.timer); | 948 | del_timer_sync(&common->ani.timer); |
1978 | 949 | ||
950 | ieee80211_stop_queues(hw); | ||
951 | |||
1979 | ath9k_hw_set_interrupts(ah, 0); | 952 | ath9k_hw_set_interrupts(ah, 0); |
1980 | ath_drain_all_txq(sc, retry_tx); | 953 | ath_drain_all_txq(sc, retry_tx); |
1981 | ath_stoprecv(sc); | 954 | ath_stoprecv(sc); |
@@ -2017,131 +990,14 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
2017 | } | 990 | } |
2018 | } | 991 | } |
2019 | 992 | ||
993 | ieee80211_wake_queues(hw); | ||
994 | |||
2020 | /* Start ANI */ | 995 | /* Start ANI */ |
2021 | ath_start_ani(common); | 996 | ath_start_ani(common); |
2022 | 997 | ||
2023 | return r; | 998 | return r; |
2024 | } | 999 | } |
2025 | 1000 | ||
2026 | /* | ||
2027 | * This function will allocate both the DMA descriptor structure, and the | ||
2028 | * buffers it contains. These are used to contain the descriptors used | ||
2029 | * by the system. | ||
2030 | */ | ||
2031 | int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | ||
2032 | struct list_head *head, const char *name, | ||
2033 | int nbuf, int ndesc) | ||
2034 | { | ||
2035 | #define DS2PHYS(_dd, _ds) \ | ||
2036 | ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) | ||
2037 | #define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0) | ||
2038 | #define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096) | ||
2039 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2040 | struct ath_desc *ds; | ||
2041 | struct ath_buf *bf; | ||
2042 | int i, bsize, error; | ||
2043 | |||
2044 | ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n", | ||
2045 | name, nbuf, ndesc); | ||
2046 | |||
2047 | INIT_LIST_HEAD(head); | ||
2048 | /* ath_desc must be a multiple of DWORDs */ | ||
2049 | if ((sizeof(struct ath_desc) % 4) != 0) { | ||
2050 | ath_print(common, ATH_DBG_FATAL, | ||
2051 | "ath_desc not DWORD aligned\n"); | ||
2052 | BUG_ON((sizeof(struct ath_desc) % 4) != 0); | ||
2053 | error = -ENOMEM; | ||
2054 | goto fail; | ||
2055 | } | ||
2056 | |||
2057 | dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc; | ||
2058 | |||
2059 | /* | ||
2060 | * Need additional DMA memory because we can't use | ||
2061 | * descriptors that cross the 4K page boundary. Assume | ||
2062 | * one skipped descriptor per 4K page. | ||
2063 | */ | ||
2064 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) { | ||
2065 | u32 ndesc_skipped = | ||
2066 | ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len); | ||
2067 | u32 dma_len; | ||
2068 | |||
2069 | while (ndesc_skipped) { | ||
2070 | dma_len = ndesc_skipped * sizeof(struct ath_desc); | ||
2071 | dd->dd_desc_len += dma_len; | ||
2072 | |||
2073 | ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len); | ||
2074 | }; | ||
2075 | } | ||
2076 | |||
2077 | /* allocate descriptors */ | ||
2078 | dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len, | ||
2079 | &dd->dd_desc_paddr, GFP_KERNEL); | ||
2080 | if (dd->dd_desc == NULL) { | ||
2081 | error = -ENOMEM; | ||
2082 | goto fail; | ||
2083 | } | ||
2084 | ds = dd->dd_desc; | ||
2085 | ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n", | ||
2086 | name, ds, (u32) dd->dd_desc_len, | ||
2087 | ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len); | ||
2088 | |||
2089 | /* allocate buffers */ | ||
2090 | bsize = sizeof(struct ath_buf) * nbuf; | ||
2091 | bf = kzalloc(bsize, GFP_KERNEL); | ||
2092 | if (bf == NULL) { | ||
2093 | error = -ENOMEM; | ||
2094 | goto fail2; | ||
2095 | } | ||
2096 | dd->dd_bufptr = bf; | ||
2097 | |||
2098 | for (i = 0; i < nbuf; i++, bf++, ds += ndesc) { | ||
2099 | bf->bf_desc = ds; | ||
2100 | bf->bf_daddr = DS2PHYS(dd, ds); | ||
2101 | |||
2102 | if (!(sc->sc_ah->caps.hw_caps & | ||
2103 | ATH9K_HW_CAP_4KB_SPLITTRANS)) { | ||
2104 | /* | ||
2105 | * Skip descriptor addresses which can cause 4KB | ||
2106 | * boundary crossing (addr + length) with a 32 dword | ||
2107 | * descriptor fetch. | ||
2108 | */ | ||
2109 | while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) { | ||
2110 | BUG_ON((caddr_t) bf->bf_desc >= | ||
2111 | ((caddr_t) dd->dd_desc + | ||
2112 | dd->dd_desc_len)); | ||
2113 | |||
2114 | ds += ndesc; | ||
2115 | bf->bf_desc = ds; | ||
2116 | bf->bf_daddr = DS2PHYS(dd, ds); | ||
2117 | } | ||
2118 | } | ||
2119 | list_add_tail(&bf->list, head); | ||
2120 | } | ||
2121 | return 0; | ||
2122 | fail2: | ||
2123 | dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc, | ||
2124 | dd->dd_desc_paddr); | ||
2125 | fail: | ||
2126 | memset(dd, 0, sizeof(*dd)); | ||
2127 | return error; | ||
2128 | #undef ATH_DESC_4KB_BOUND_CHECK | ||
2129 | #undef ATH_DESC_4KB_BOUND_NUM_SKIPPED | ||
2130 | #undef DS2PHYS | ||
2131 | } | ||
2132 | |||
2133 | void ath_descdma_cleanup(struct ath_softc *sc, | ||
2134 | struct ath_descdma *dd, | ||
2135 | struct list_head *head) | ||
2136 | { | ||
2137 | dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc, | ||
2138 | dd->dd_desc_paddr); | ||
2139 | |||
2140 | INIT_LIST_HEAD(head); | ||
2141 | kfree(dd->dd_bufptr); | ||
2142 | memset(dd, 0, sizeof(*dd)); | ||
2143 | } | ||
2144 | |||
2145 | int ath_get_hal_qnum(u16 queue, struct ath_softc *sc) | 1001 | int ath_get_hal_qnum(u16 queue, struct ath_softc *sc) |
2146 | { | 1002 | { |
2147 | int qnum; | 1003 | int qnum; |
@@ -2220,28 +1076,6 @@ void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
2220 | /* mac80211 callbacks */ | 1076 | /* mac80211 callbacks */ |
2221 | /**********************/ | 1077 | /**********************/ |
2222 | 1078 | ||
2223 | /* | ||
2224 | * (Re)start btcoex timers | ||
2225 | */ | ||
2226 | static void ath9k_btcoex_timer_resume(struct ath_softc *sc) | ||
2227 | { | ||
2228 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
2229 | struct ath_hw *ah = sc->sc_ah; | ||
2230 | |||
2231 | ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | ||
2232 | "Starting btcoex timers"); | ||
2233 | |||
2234 | /* make sure duty cycle timer is also stopped when resuming */ | ||
2235 | if (btcoex->hw_timer_enabled) | ||
2236 | ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer); | ||
2237 | |||
2238 | btcoex->bt_priority_cnt = 0; | ||
2239 | btcoex->bt_priority_time = jiffies; | ||
2240 | sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED; | ||
2241 | |||
2242 | mod_timer(&btcoex->period_timer, jiffies); | ||
2243 | } | ||
2244 | |||
2245 | static int ath9k_start(struct ieee80211_hw *hw) | 1079 | static int ath9k_start(struct ieee80211_hw *hw) |
2246 | { | 1080 | { |
2247 | struct ath_wiphy *aphy = hw->priv; | 1081 | struct ath_wiphy *aphy = hw->priv; |
@@ -2411,11 +1245,11 @@ static int ath9k_tx(struct ieee80211_hw *hw, | |||
2411 | if (ieee80211_is_pspoll(hdr->frame_control)) { | 1245 | if (ieee80211_is_pspoll(hdr->frame_control)) { |
2412 | ath_print(common, ATH_DBG_PS, | 1246 | ath_print(common, ATH_DBG_PS, |
2413 | "Sending PS-Poll to pick a buffered frame\n"); | 1247 | "Sending PS-Poll to pick a buffered frame\n"); |
2414 | sc->sc_flags |= SC_OP_WAIT_FOR_PSPOLL_DATA; | 1248 | sc->ps_flags |= PS_WAIT_FOR_PSPOLL_DATA; |
2415 | } else { | 1249 | } else { |
2416 | ath_print(common, ATH_DBG_PS, | 1250 | ath_print(common, ATH_DBG_PS, |
2417 | "Wake up to complete TX\n"); | 1251 | "Wake up to complete TX\n"); |
2418 | sc->sc_flags |= SC_OP_WAIT_FOR_TX_ACK; | 1252 | sc->ps_flags |= PS_WAIT_FOR_TX_ACK; |
2419 | } | 1253 | } |
2420 | /* | 1254 | /* |
2421 | * The actual restore operation will happen only after | 1255 | * The actual restore operation will happen only after |
@@ -2468,22 +1302,6 @@ exit: | |||
2468 | return 0; | 1302 | return 0; |
2469 | } | 1303 | } |
2470 | 1304 | ||
2471 | /* | ||
2472 | * Pause btcoex timer and bt duty cycle timer | ||
2473 | */ | ||
2474 | static void ath9k_btcoex_timer_pause(struct ath_softc *sc) | ||
2475 | { | ||
2476 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
2477 | struct ath_hw *ah = sc->sc_ah; | ||
2478 | |||
2479 | del_timer_sync(&btcoex->period_timer); | ||
2480 | |||
2481 | if (btcoex->hw_timer_enabled) | ||
2482 | ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer); | ||
2483 | |||
2484 | btcoex->hw_timer_enabled = false; | ||
2485 | } | ||
2486 | |||
2487 | static void ath9k_stop(struct ieee80211_hw *hw) | 1305 | static void ath9k_stop(struct ieee80211_hw *hw) |
2488 | { | 1306 | { |
2489 | struct ath_wiphy *aphy = hw->priv; | 1307 | struct ath_wiphy *aphy = hw->priv; |
@@ -2550,12 +1368,12 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
2550 | } | 1368 | } |
2551 | 1369 | ||
2552 | static int ath9k_add_interface(struct ieee80211_hw *hw, | 1370 | static int ath9k_add_interface(struct ieee80211_hw *hw, |
2553 | struct ieee80211_if_init_conf *conf) | 1371 | struct ieee80211_vif *vif) |
2554 | { | 1372 | { |
2555 | struct ath_wiphy *aphy = hw->priv; | 1373 | struct ath_wiphy *aphy = hw->priv; |
2556 | struct ath_softc *sc = aphy->sc; | 1374 | struct ath_softc *sc = aphy->sc; |
2557 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1375 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
2558 | struct ath_vif *avp = (void *)conf->vif->drv_priv; | 1376 | struct ath_vif *avp = (void *)vif->drv_priv; |
2559 | enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED; | 1377 | enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED; |
2560 | int ret = 0; | 1378 | int ret = 0; |
2561 | 1379 | ||
@@ -2567,7 +1385,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
2567 | goto out; | 1385 | goto out; |
2568 | } | 1386 | } |
2569 | 1387 | ||
2570 | switch (conf->type) { | 1388 | switch (vif->type) { |
2571 | case NL80211_IFTYPE_STATION: | 1389 | case NL80211_IFTYPE_STATION: |
2572 | ic_opmode = NL80211_IFTYPE_STATION; | 1390 | ic_opmode = NL80211_IFTYPE_STATION; |
2573 | break; | 1391 | break; |
@@ -2578,11 +1396,11 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
2578 | ret = -ENOBUFS; | 1396 | ret = -ENOBUFS; |
2579 | goto out; | 1397 | goto out; |
2580 | } | 1398 | } |
2581 | ic_opmode = conf->type; | 1399 | ic_opmode = vif->type; |
2582 | break; | 1400 | break; |
2583 | default: | 1401 | default: |
2584 | ath_print(common, ATH_DBG_FATAL, | 1402 | ath_print(common, ATH_DBG_FATAL, |
2585 | "Interface type %d not yet supported\n", conf->type); | 1403 | "Interface type %d not yet supported\n", vif->type); |
2586 | ret = -EOPNOTSUPP; | 1404 | ret = -EOPNOTSUPP; |
2587 | goto out; | 1405 | goto out; |
2588 | } | 1406 | } |
@@ -2614,18 +1432,18 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
2614 | * Enable MIB interrupts when there are hardware phy counters. | 1432 | * Enable MIB interrupts when there are hardware phy counters. |
2615 | * Note we only do this (at the moment) for station mode. | 1433 | * Note we only do this (at the moment) for station mode. |
2616 | */ | 1434 | */ |
2617 | if ((conf->type == NL80211_IFTYPE_STATION) || | 1435 | if ((vif->type == NL80211_IFTYPE_STATION) || |
2618 | (conf->type == NL80211_IFTYPE_ADHOC) || | 1436 | (vif->type == NL80211_IFTYPE_ADHOC) || |
2619 | (conf->type == NL80211_IFTYPE_MESH_POINT)) { | 1437 | (vif->type == NL80211_IFTYPE_MESH_POINT)) { |
2620 | sc->imask |= ATH9K_INT_MIB; | 1438 | sc->imask |= ATH9K_INT_MIB; |
2621 | sc->imask |= ATH9K_INT_TSFOOR; | 1439 | sc->imask |= ATH9K_INT_TSFOOR; |
2622 | } | 1440 | } |
2623 | 1441 | ||
2624 | ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); | 1442 | ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); |
2625 | 1443 | ||
2626 | if (conf->type == NL80211_IFTYPE_AP || | 1444 | if (vif->type == NL80211_IFTYPE_AP || |
2627 | conf->type == NL80211_IFTYPE_ADHOC || | 1445 | vif->type == NL80211_IFTYPE_ADHOC || |
2628 | conf->type == NL80211_IFTYPE_MONITOR) | 1446 | vif->type == NL80211_IFTYPE_MONITOR) |
2629 | ath_start_ani(common); | 1447 | ath_start_ani(common); |
2630 | 1448 | ||
2631 | out: | 1449 | out: |
@@ -2634,12 +1452,12 @@ out: | |||
2634 | } | 1452 | } |
2635 | 1453 | ||
2636 | static void ath9k_remove_interface(struct ieee80211_hw *hw, | 1454 | static void ath9k_remove_interface(struct ieee80211_hw *hw, |
2637 | struct ieee80211_if_init_conf *conf) | 1455 | struct ieee80211_vif *vif) |
2638 | { | 1456 | { |
2639 | struct ath_wiphy *aphy = hw->priv; | 1457 | struct ath_wiphy *aphy = hw->priv; |
2640 | struct ath_softc *sc = aphy->sc; | 1458 | struct ath_softc *sc = aphy->sc; |
2641 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1459 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
2642 | struct ath_vif *avp = (void *)conf->vif->drv_priv; | 1460 | struct ath_vif *avp = (void *)vif->drv_priv; |
2643 | int i; | 1461 | int i; |
2644 | 1462 | ||
2645 | ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n"); | 1463 | ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n"); |
@@ -2662,7 +1480,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
2662 | sc->sc_flags &= ~SC_OP_BEACONS; | 1480 | sc->sc_flags &= ~SC_OP_BEACONS; |
2663 | 1481 | ||
2664 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) { | 1482 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) { |
2665 | if (sc->beacon.bslot[i] == conf->vif) { | 1483 | if (sc->beacon.bslot[i] == vif) { |
2666 | printk(KERN_DEBUG "%s: vif had allocated beacon " | 1484 | printk(KERN_DEBUG "%s: vif had allocated beacon " |
2667 | "slot\n", __func__); | 1485 | "slot\n", __func__); |
2668 | sc->beacon.bslot[i] = NULL; | 1486 | sc->beacon.bslot[i] = NULL; |
@@ -2675,6 +1493,19 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
2675 | mutex_unlock(&sc->mutex); | 1493 | mutex_unlock(&sc->mutex); |
2676 | } | 1494 | } |
2677 | 1495 | ||
1496 | void ath9k_enable_ps(struct ath_softc *sc) | ||
1497 | { | ||
1498 | sc->ps_enabled = true; | ||
1499 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { | ||
1500 | if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) { | ||
1501 | sc->imask |= ATH9K_INT_TIM_TIMER; | ||
1502 | ath9k_hw_set_interrupts(sc->sc_ah, | ||
1503 | sc->imask); | ||
1504 | } | ||
1505 | } | ||
1506 | ath9k_hw_setrxabort(sc->sc_ah, 1); | ||
1507 | } | ||
1508 | |||
2678 | static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | 1509 | static int ath9k_config(struct ieee80211_hw *hw, u32 changed) |
2679 | { | 1510 | { |
2680 | struct ath_wiphy *aphy = hw->priv; | 1511 | struct ath_wiphy *aphy = hw->priv; |
@@ -2713,6 +1544,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
2713 | spin_unlock_bh(&sc->wiphy_lock); | 1544 | spin_unlock_bh(&sc->wiphy_lock); |
2714 | 1545 | ||
2715 | if (enable_radio) { | 1546 | if (enable_radio) { |
1547 | sc->ps_idle = false; | ||
2716 | ath_radio_enable(sc, hw); | 1548 | ath_radio_enable(sc, hw); |
2717 | ath_print(common, ATH_DBG_CONFIG, | 1549 | ath_print(common, ATH_DBG_CONFIG, |
2718 | "not-idle: enabling radio\n"); | 1550 | "not-idle: enabling radio\n"); |
@@ -2727,36 +1559,27 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
2727 | */ | 1559 | */ |
2728 | if (changed & IEEE80211_CONF_CHANGE_PS) { | 1560 | if (changed & IEEE80211_CONF_CHANGE_PS) { |
2729 | if (conf->flags & IEEE80211_CONF_PS) { | 1561 | if (conf->flags & IEEE80211_CONF_PS) { |
2730 | sc->sc_flags |= SC_OP_PS_ENABLED; | 1562 | sc->ps_flags |= PS_ENABLED; |
2731 | if (!(ah->caps.hw_caps & | ||
2732 | ATH9K_HW_CAP_AUTOSLEEP)) { | ||
2733 | if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) { | ||
2734 | sc->imask |= ATH9K_INT_TIM_TIMER; | ||
2735 | ath9k_hw_set_interrupts(sc->sc_ah, | ||
2736 | sc->imask); | ||
2737 | } | ||
2738 | } | ||
2739 | /* | 1563 | /* |
2740 | * At this point we know hardware has received an ACK | 1564 | * At this point we know hardware has received an ACK |
2741 | * of a previously sent null data frame. | 1565 | * of a previously sent null data frame. |
2742 | */ | 1566 | */ |
2743 | if ((sc->sc_flags & SC_OP_NULLFUNC_COMPLETED)) { | 1567 | if ((sc->ps_flags & PS_NULLFUNC_COMPLETED)) { |
2744 | sc->sc_flags &= ~SC_OP_NULLFUNC_COMPLETED; | 1568 | sc->ps_flags &= ~PS_NULLFUNC_COMPLETED; |
2745 | sc->ps_enabled = true; | 1569 | ath9k_enable_ps(sc); |
2746 | ath9k_hw_setrxabort(sc->sc_ah, 1); | ||
2747 | } | 1570 | } |
2748 | } else { | 1571 | } else { |
2749 | sc->ps_enabled = false; | 1572 | sc->ps_enabled = false; |
2750 | sc->sc_flags &= ~(SC_OP_PS_ENABLED | | 1573 | sc->ps_flags &= ~(PS_ENABLED | |
2751 | SC_OP_NULLFUNC_COMPLETED); | 1574 | PS_NULLFUNC_COMPLETED); |
2752 | ath9k_setpower(sc, ATH9K_PM_AWAKE); | 1575 | ath9k_setpower(sc, ATH9K_PM_AWAKE); |
2753 | if (!(ah->caps.hw_caps & | 1576 | if (!(ah->caps.hw_caps & |
2754 | ATH9K_HW_CAP_AUTOSLEEP)) { | 1577 | ATH9K_HW_CAP_AUTOSLEEP)) { |
2755 | ath9k_hw_setrxabort(sc->sc_ah, 0); | 1578 | ath9k_hw_setrxabort(sc->sc_ah, 0); |
2756 | sc->sc_flags &= ~(SC_OP_WAIT_FOR_BEACON | | 1579 | sc->ps_flags &= ~(PS_WAIT_FOR_BEACON | |
2757 | SC_OP_WAIT_FOR_CAB | | 1580 | PS_WAIT_FOR_CAB | |
2758 | SC_OP_WAIT_FOR_PSPOLL_DATA | | 1581 | PS_WAIT_FOR_PSPOLL_DATA | |
2759 | SC_OP_WAIT_FOR_TX_ACK); | 1582 | PS_WAIT_FOR_TX_ACK); |
2760 | if (sc->imask & ATH9K_INT_TIM_TIMER) { | 1583 | if (sc->imask & ATH9K_INT_TIM_TIMER) { |
2761 | sc->imask &= ~ATH9K_INT_TIM_TIMER; | 1584 | sc->imask &= ~ATH9K_INT_TIM_TIMER; |
2762 | ath9k_hw_set_interrupts(sc->sc_ah, | 1585 | ath9k_hw_set_interrupts(sc->sc_ah, |
@@ -2766,6 +1589,14 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
2766 | } | 1589 | } |
2767 | } | 1590 | } |
2768 | 1591 | ||
1592 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) { | ||
1593 | if (conf->flags & IEEE80211_CONF_MONITOR) { | ||
1594 | ath_print(common, ATH_DBG_CONFIG, | ||
1595 | "HW opmode set to Monitor mode\n"); | ||
1596 | sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR; | ||
1597 | } | ||
1598 | } | ||
1599 | |||
2769 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | 1600 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
2770 | struct ieee80211_channel *curchan = hw->conf.channel; | 1601 | struct ieee80211_channel *curchan = hw->conf.channel; |
2771 | int pos = curchan->hw_value; | 1602 | int pos = curchan->hw_value; |
@@ -2801,8 +1632,10 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
2801 | } | 1632 | } |
2802 | 1633 | ||
2803 | skip_chan_change: | 1634 | skip_chan_change: |
2804 | if (changed & IEEE80211_CONF_CHANGE_POWER) | 1635 | if (changed & IEEE80211_CONF_CHANGE_POWER) { |
2805 | sc->config.txpowlimit = 2 * conf->power_level; | 1636 | sc->config.txpowlimit = 2 * conf->power_level; |
1637 | ath_update_txpow(sc); | ||
1638 | } | ||
2806 | 1639 | ||
2807 | spin_lock_bh(&sc->wiphy_lock); | 1640 | spin_lock_bh(&sc->wiphy_lock); |
2808 | disable_radio = ath9k_all_wiphys_idle(sc); | 1641 | disable_radio = ath9k_all_wiphys_idle(sc); |
@@ -2810,6 +1643,7 @@ skip_chan_change: | |||
2810 | 1643 | ||
2811 | if (disable_radio) { | 1644 | if (disable_radio) { |
2812 | ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n"); | 1645 | ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n"); |
1646 | sc->ps_idle = true; | ||
2813 | ath_radio_disable(sc, hw); | 1647 | ath_radio_disable(sc, hw); |
2814 | } | 1648 | } |
2815 | 1649 | ||
@@ -2850,24 +1684,28 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw, | |||
2850 | "Set HW RX filter: 0x%x\n", rfilt); | 1684 | "Set HW RX filter: 0x%x\n", rfilt); |
2851 | } | 1685 | } |
2852 | 1686 | ||
2853 | static void ath9k_sta_notify(struct ieee80211_hw *hw, | 1687 | static int ath9k_sta_add(struct ieee80211_hw *hw, |
2854 | struct ieee80211_vif *vif, | 1688 | struct ieee80211_vif *vif, |
2855 | enum sta_notify_cmd cmd, | 1689 | struct ieee80211_sta *sta) |
2856 | struct ieee80211_sta *sta) | ||
2857 | { | 1690 | { |
2858 | struct ath_wiphy *aphy = hw->priv; | 1691 | struct ath_wiphy *aphy = hw->priv; |
2859 | struct ath_softc *sc = aphy->sc; | 1692 | struct ath_softc *sc = aphy->sc; |
2860 | 1693 | ||
2861 | switch (cmd) { | 1694 | ath_node_attach(sc, sta); |
2862 | case STA_NOTIFY_ADD: | 1695 | |
2863 | ath_node_attach(sc, sta); | 1696 | return 0; |
2864 | break; | 1697 | } |
2865 | case STA_NOTIFY_REMOVE: | 1698 | |
2866 | ath_node_detach(sc, sta); | 1699 | static int ath9k_sta_remove(struct ieee80211_hw *hw, |
2867 | break; | 1700 | struct ieee80211_vif *vif, |
2868 | default: | 1701 | struct ieee80211_sta *sta) |
2869 | break; | 1702 | { |
2870 | } | 1703 | struct ath_wiphy *aphy = hw->priv; |
1704 | struct ath_softc *sc = aphy->sc; | ||
1705 | |||
1706 | ath_node_detach(sc, sta); | ||
1707 | |||
1708 | return 0; | ||
2871 | } | 1709 | } |
2872 | 1710 | ||
2873 | static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, | 1711 | static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, |
@@ -2966,6 +1804,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2966 | struct ath_hw *ah = sc->sc_ah; | 1804 | struct ath_hw *ah = sc->sc_ah; |
2967 | struct ath_common *common = ath9k_hw_common(ah); | 1805 | struct ath_common *common = ath9k_hw_common(ah); |
2968 | struct ath_vif *avp = (void *)vif->drv_priv; | 1806 | struct ath_vif *avp = (void *)vif->drv_priv; |
1807 | int slottime; | ||
2969 | int error; | 1808 | int error; |
2970 | 1809 | ||
2971 | mutex_lock(&sc->mutex); | 1810 | mutex_lock(&sc->mutex); |
@@ -3001,6 +1840,25 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
3001 | ath_beacon_config(sc, vif); | 1840 | ath_beacon_config(sc, vif); |
3002 | } | 1841 | } |
3003 | 1842 | ||
1843 | if (changed & BSS_CHANGED_ERP_SLOT) { | ||
1844 | if (bss_conf->use_short_slot) | ||
1845 | slottime = 9; | ||
1846 | else | ||
1847 | slottime = 20; | ||
1848 | if (vif->type == NL80211_IFTYPE_AP) { | ||
1849 | /* | ||
1850 | * Defer update, so that connected stations can adjust | ||
1851 | * their settings at the same time. | ||
1852 | * See beacon.c for more details | ||
1853 | */ | ||
1854 | sc->beacon.slottime = slottime; | ||
1855 | sc->beacon.updateslot = UPDATE; | ||
1856 | } else { | ||
1857 | ah->slottime = slottime; | ||
1858 | ath9k_hw_init_global_settings(ah); | ||
1859 | } | ||
1860 | } | ||
1861 | |||
3004 | /* Disable transmission of beacons */ | 1862 | /* Disable transmission of beacons */ |
3005 | if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) | 1863 | if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) |
3006 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | 1864 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); |
@@ -3133,6 +1991,7 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw) | |||
3133 | { | 1991 | { |
3134 | struct ath_wiphy *aphy = hw->priv; | 1992 | struct ath_wiphy *aphy = hw->priv; |
3135 | struct ath_softc *sc = aphy->sc; | 1993 | struct ath_softc *sc = aphy->sc; |
1994 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
3136 | 1995 | ||
3137 | mutex_lock(&sc->mutex); | 1996 | mutex_lock(&sc->mutex); |
3138 | if (ath9k_wiphy_scanning(sc)) { | 1997 | if (ath9k_wiphy_scanning(sc)) { |
@@ -3148,10 +2007,9 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw) | |||
3148 | 2007 | ||
3149 | aphy->state = ATH_WIPHY_SCAN; | 2008 | aphy->state = ATH_WIPHY_SCAN; |
3150 | ath9k_wiphy_pause_all_forced(sc, aphy); | 2009 | ath9k_wiphy_pause_all_forced(sc, aphy); |
3151 | |||
3152 | spin_lock_bh(&sc->ani_lock); | ||
3153 | sc->sc_flags |= SC_OP_SCANNING; | 2010 | sc->sc_flags |= SC_OP_SCANNING; |
3154 | spin_unlock_bh(&sc->ani_lock); | 2011 | del_timer_sync(&common->ani.timer); |
2012 | cancel_delayed_work_sync(&sc->tx_complete_work); | ||
3155 | mutex_unlock(&sc->mutex); | 2013 | mutex_unlock(&sc->mutex); |
3156 | } | 2014 | } |
3157 | 2015 | ||
@@ -3159,17 +2017,30 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) | |||
3159 | { | 2017 | { |
3160 | struct ath_wiphy *aphy = hw->priv; | 2018 | struct ath_wiphy *aphy = hw->priv; |
3161 | struct ath_softc *sc = aphy->sc; | 2019 | struct ath_softc *sc = aphy->sc; |
2020 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
3162 | 2021 | ||
3163 | mutex_lock(&sc->mutex); | 2022 | mutex_lock(&sc->mutex); |
3164 | spin_lock_bh(&sc->ani_lock); | ||
3165 | aphy->state = ATH_WIPHY_ACTIVE; | 2023 | aphy->state = ATH_WIPHY_ACTIVE; |
3166 | sc->sc_flags &= ~SC_OP_SCANNING; | 2024 | sc->sc_flags &= ~SC_OP_SCANNING; |
3167 | sc->sc_flags |= SC_OP_FULL_RESET; | 2025 | sc->sc_flags |= SC_OP_FULL_RESET; |
3168 | spin_unlock_bh(&sc->ani_lock); | 2026 | ath_start_ani(common); |
2027 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); | ||
3169 | ath_beacon_config(sc, NULL); | 2028 | ath_beacon_config(sc, NULL); |
3170 | mutex_unlock(&sc->mutex); | 2029 | mutex_unlock(&sc->mutex); |
3171 | } | 2030 | } |
3172 | 2031 | ||
2032 | static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) | ||
2033 | { | ||
2034 | struct ath_wiphy *aphy = hw->priv; | ||
2035 | struct ath_softc *sc = aphy->sc; | ||
2036 | struct ath_hw *ah = sc->sc_ah; | ||
2037 | |||
2038 | mutex_lock(&sc->mutex); | ||
2039 | ah->coverage_class = coverage_class; | ||
2040 | ath9k_hw_init_global_settings(ah); | ||
2041 | mutex_unlock(&sc->mutex); | ||
2042 | } | ||
2043 | |||
3173 | struct ieee80211_ops ath9k_ops = { | 2044 | struct ieee80211_ops ath9k_ops = { |
3174 | .tx = ath9k_tx, | 2045 | .tx = ath9k_tx, |
3175 | .start = ath9k_start, | 2046 | .start = ath9k_start, |
@@ -3178,7 +2049,8 @@ struct ieee80211_ops ath9k_ops = { | |||
3178 | .remove_interface = ath9k_remove_interface, | 2049 | .remove_interface = ath9k_remove_interface, |
3179 | .config = ath9k_config, | 2050 | .config = ath9k_config, |
3180 | .configure_filter = ath9k_configure_filter, | 2051 | .configure_filter = ath9k_configure_filter, |
3181 | .sta_notify = ath9k_sta_notify, | 2052 | .sta_add = ath9k_sta_add, |
2053 | .sta_remove = ath9k_sta_remove, | ||
3182 | .conf_tx = ath9k_conf_tx, | 2054 | .conf_tx = ath9k_conf_tx, |
3183 | .bss_info_changed = ath9k_bss_info_changed, | 2055 | .bss_info_changed = ath9k_bss_info_changed, |
3184 | .set_key = ath9k_set_key, | 2056 | .set_key = ath9k_set_key, |
@@ -3189,64 +2061,5 @@ struct ieee80211_ops ath9k_ops = { | |||
3189 | .sw_scan_start = ath9k_sw_scan_start, | 2061 | .sw_scan_start = ath9k_sw_scan_start, |
3190 | .sw_scan_complete = ath9k_sw_scan_complete, | 2062 | .sw_scan_complete = ath9k_sw_scan_complete, |
3191 | .rfkill_poll = ath9k_rfkill_poll_state, | 2063 | .rfkill_poll = ath9k_rfkill_poll_state, |
2064 | .set_coverage_class = ath9k_set_coverage_class, | ||
3192 | }; | 2065 | }; |
3193 | |||
3194 | static int __init ath9k_init(void) | ||
3195 | { | ||
3196 | int error; | ||
3197 | |||
3198 | /* Register rate control algorithm */ | ||
3199 | error = ath_rate_control_register(); | ||
3200 | if (error != 0) { | ||
3201 | printk(KERN_ERR | ||
3202 | "ath9k: Unable to register rate control " | ||
3203 | "algorithm: %d\n", | ||
3204 | error); | ||
3205 | goto err_out; | ||
3206 | } | ||
3207 | |||
3208 | error = ath9k_debug_create_root(); | ||
3209 | if (error) { | ||
3210 | printk(KERN_ERR | ||
3211 | "ath9k: Unable to create debugfs root: %d\n", | ||
3212 | error); | ||
3213 | goto err_rate_unregister; | ||
3214 | } | ||
3215 | |||
3216 | error = ath_pci_init(); | ||
3217 | if (error < 0) { | ||
3218 | printk(KERN_ERR | ||
3219 | "ath9k: No PCI devices found, driver not installed.\n"); | ||
3220 | error = -ENODEV; | ||
3221 | goto err_remove_root; | ||
3222 | } | ||
3223 | |||
3224 | error = ath_ahb_init(); | ||
3225 | if (error < 0) { | ||
3226 | error = -ENODEV; | ||
3227 | goto err_pci_exit; | ||
3228 | } | ||
3229 | |||
3230 | return 0; | ||
3231 | |||
3232 | err_pci_exit: | ||
3233 | ath_pci_exit(); | ||
3234 | |||
3235 | err_remove_root: | ||
3236 | ath9k_debug_remove_root(); | ||
3237 | err_rate_unregister: | ||
3238 | ath_rate_control_unregister(); | ||
3239 | err_out: | ||
3240 | return error; | ||
3241 | } | ||
3242 | module_init(ath9k_init); | ||
3243 | |||
3244 | static void __exit ath9k_exit(void) | ||
3245 | { | ||
3246 | ath_ahb_exit(); | ||
3247 | ath_pci_exit(); | ||
3248 | ath9k_debug_remove_root(); | ||
3249 | ath_rate_control_unregister(); | ||
3250 | printk(KERN_INFO "%s: Driver unloaded\n", dev_info); | ||
3251 | } | ||
3252 | module_exit(ath9k_exit); | ||
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index f7af5ea5475..9441c6718a3 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c | |||
@@ -18,13 +18,14 @@ | |||
18 | #include <linux/pci.h> | 18 | #include <linux/pci.h> |
19 | #include "ath9k.h" | 19 | #include "ath9k.h" |
20 | 20 | ||
21 | static struct pci_device_id ath_pci_id_table[] __devinitdata = { | 21 | static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = { |
22 | { PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI */ | 22 | { PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI */ |
23 | { PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */ | 23 | { PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */ |
24 | { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI */ | 24 | { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI */ |
25 | { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */ | 25 | { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */ |
26 | { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */ | 26 | { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */ |
27 | { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */ | 27 | { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */ |
28 | { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */ | ||
28 | { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */ | 29 | { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */ |
29 | { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */ | 30 | { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */ |
30 | { 0 } | 31 | { 0 } |
@@ -49,16 +50,6 @@ static void ath_pci_read_cachesize(struct ath_common *common, int *csz) | |||
49 | *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */ | 50 | *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */ |
50 | } | 51 | } |
51 | 52 | ||
52 | static void ath_pci_cleanup(struct ath_common *common) | ||
53 | { | ||
54 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
55 | struct pci_dev *pdev = to_pci_dev(sc->dev); | ||
56 | |||
57 | pci_iounmap(pdev, sc->mem); | ||
58 | pci_disable_device(pdev); | ||
59 | pci_release_region(pdev, 0); | ||
60 | } | ||
61 | |||
62 | static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data) | 53 | static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data) |
63 | { | 54 | { |
64 | struct ath_hw *ah = (struct ath_hw *) common->ah; | 55 | struct ath_hw *ah = (struct ath_hw *) common->ah; |
@@ -98,7 +89,6 @@ static void ath_pci_bt_coex_prep(struct ath_common *common) | |||
98 | 89 | ||
99 | static const struct ath_bus_ops ath_pci_bus_ops = { | 90 | static const struct ath_bus_ops ath_pci_bus_ops = { |
100 | .read_cachesize = ath_pci_read_cachesize, | 91 | .read_cachesize = ath_pci_read_cachesize, |
101 | .cleanup = ath_pci_cleanup, | ||
102 | .eeprom_read = ath_pci_eeprom_read, | 92 | .eeprom_read = ath_pci_eeprom_read, |
103 | .bt_coex_prep = ath_pci_bt_coex_prep, | 93 | .bt_coex_prep = ath_pci_bt_coex_prep, |
104 | }; | 94 | }; |
@@ -113,25 +103,22 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
113 | u16 subsysid; | 103 | u16 subsysid; |
114 | u32 val; | 104 | u32 val; |
115 | int ret = 0; | 105 | int ret = 0; |
116 | struct ath_hw *ah; | ||
117 | char hw_name[64]; | 106 | char hw_name[64]; |
118 | 107 | ||
119 | if (pci_enable_device(pdev)) | 108 | if (pci_enable_device(pdev)) |
120 | return -EIO; | 109 | return -EIO; |
121 | 110 | ||
122 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | 111 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); |
123 | |||
124 | if (ret) { | 112 | if (ret) { |
125 | printk(KERN_ERR "ath9k: 32-bit DMA not available\n"); | 113 | printk(KERN_ERR "ath9k: 32-bit DMA not available\n"); |
126 | goto bad; | 114 | goto err_dma; |
127 | } | 115 | } |
128 | 116 | ||
129 | ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); | 117 | ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); |
130 | |||
131 | if (ret) { | 118 | if (ret) { |
132 | printk(KERN_ERR "ath9k: 32-bit DMA consistent " | 119 | printk(KERN_ERR "ath9k: 32-bit DMA consistent " |
133 | "DMA enable failed\n"); | 120 | "DMA enable failed\n"); |
134 | goto bad; | 121 | goto err_dma; |
135 | } | 122 | } |
136 | 123 | ||
137 | /* | 124 | /* |
@@ -171,22 +158,22 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
171 | if (ret) { | 158 | if (ret) { |
172 | dev_err(&pdev->dev, "PCI memory region reserve error\n"); | 159 | dev_err(&pdev->dev, "PCI memory region reserve error\n"); |
173 | ret = -ENODEV; | 160 | ret = -ENODEV; |
174 | goto bad; | 161 | goto err_region; |
175 | } | 162 | } |
176 | 163 | ||
177 | mem = pci_iomap(pdev, 0, 0); | 164 | mem = pci_iomap(pdev, 0, 0); |
178 | if (!mem) { | 165 | if (!mem) { |
179 | printk(KERN_ERR "PCI memory map error\n") ; | 166 | printk(KERN_ERR "PCI memory map error\n") ; |
180 | ret = -EIO; | 167 | ret = -EIO; |
181 | goto bad1; | 168 | goto err_iomap; |
182 | } | 169 | } |
183 | 170 | ||
184 | hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) + | 171 | hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) + |
185 | sizeof(struct ath_softc), &ath9k_ops); | 172 | sizeof(struct ath_softc), &ath9k_ops); |
186 | if (!hw) { | 173 | if (!hw) { |
187 | dev_err(&pdev->dev, "no memory for ieee80211_hw\n"); | 174 | dev_err(&pdev->dev, "No memory for ieee80211_hw\n"); |
188 | ret = -ENOMEM; | 175 | ret = -ENOMEM; |
189 | goto bad2; | 176 | goto err_alloc_hw; |
190 | } | 177 | } |
191 | 178 | ||
192 | SET_IEEE80211_DEV(hw, &pdev->dev); | 179 | SET_IEEE80211_DEV(hw, &pdev->dev); |
@@ -201,25 +188,25 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
201 | sc->dev = &pdev->dev; | 188 | sc->dev = &pdev->dev; |
202 | sc->mem = mem; | 189 | sc->mem = mem; |
203 | 190 | ||
204 | pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsysid); | 191 | /* Will be cleared in ath9k_start() */ |
205 | ret = ath_init_device(id->device, sc, subsysid, &ath_pci_bus_ops); | 192 | sc->sc_flags |= SC_OP_INVALID; |
206 | if (ret) { | ||
207 | dev_err(&pdev->dev, "failed to initialize device\n"); | ||
208 | goto bad3; | ||
209 | } | ||
210 | |||
211 | /* setup interrupt service routine */ | ||
212 | 193 | ||
213 | ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc); | 194 | ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc); |
214 | if (ret) { | 195 | if (ret) { |
215 | dev_err(&pdev->dev, "request_irq failed\n"); | 196 | dev_err(&pdev->dev, "request_irq failed\n"); |
216 | goto bad4; | 197 | goto err_irq; |
217 | } | 198 | } |
218 | 199 | ||
219 | sc->irq = pdev->irq; | 200 | sc->irq = pdev->irq; |
220 | 201 | ||
221 | ah = sc->sc_ah; | 202 | pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsysid); |
222 | ath9k_hw_name(ah, hw_name, sizeof(hw_name)); | 203 | ret = ath9k_init_device(id->device, sc, subsysid, &ath_pci_bus_ops); |
204 | if (ret) { | ||
205 | dev_err(&pdev->dev, "Failed to initialize device\n"); | ||
206 | goto err_init; | ||
207 | } | ||
208 | |||
209 | ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name)); | ||
223 | printk(KERN_INFO | 210 | printk(KERN_INFO |
224 | "%s: %s mem=0x%lx, irq=%d\n", | 211 | "%s: %s mem=0x%lx, irq=%d\n", |
225 | wiphy_name(hw->wiphy), | 212 | wiphy_name(hw->wiphy), |
@@ -227,15 +214,18 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
227 | (unsigned long)mem, pdev->irq); | 214 | (unsigned long)mem, pdev->irq); |
228 | 215 | ||
229 | return 0; | 216 | return 0; |
230 | bad4: | 217 | |
231 | ath_detach(sc); | 218 | err_init: |
232 | bad3: | 219 | free_irq(sc->irq, sc); |
220 | err_irq: | ||
233 | ieee80211_free_hw(hw); | 221 | ieee80211_free_hw(hw); |
234 | bad2: | 222 | err_alloc_hw: |
235 | pci_iounmap(pdev, mem); | 223 | pci_iounmap(pdev, mem); |
236 | bad1: | 224 | err_iomap: |
237 | pci_release_region(pdev, 0); | 225 | pci_release_region(pdev, 0); |
238 | bad: | 226 | err_region: |
227 | /* Nothing */ | ||
228 | err_dma: | ||
239 | pci_disable_device(pdev); | 229 | pci_disable_device(pdev); |
240 | return ret; | 230 | return ret; |
241 | } | 231 | } |
@@ -245,8 +235,15 @@ static void ath_pci_remove(struct pci_dev *pdev) | |||
245 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | 235 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); |
246 | struct ath_wiphy *aphy = hw->priv; | 236 | struct ath_wiphy *aphy = hw->priv; |
247 | struct ath_softc *sc = aphy->sc; | 237 | struct ath_softc *sc = aphy->sc; |
238 | void __iomem *mem = sc->mem; | ||
239 | |||
240 | ath9k_deinit_device(sc); | ||
241 | free_irq(sc->irq, sc); | ||
242 | ieee80211_free_hw(sc->hw); | ||
248 | 243 | ||
249 | ath_cleanup(sc); | 244 | pci_iounmap(pdev, mem); |
245 | pci_disable_device(pdev); | ||
246 | pci_release_region(pdev, 0); | ||
250 | } | 247 | } |
251 | 248 | ||
252 | #ifdef CONFIG_PM | 249 | #ifdef CONFIG_PM |
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h index 31de27dc0c4..0999a495fd4 100644 --- a/drivers/net/wireless/ath/ath9k/phy.h +++ b/drivers/net/wireless/ath/ath9k/phy.h | |||
@@ -384,6 +384,9 @@ bool ath9k_hw_set_rf_regs(struct ath_hw *ah, | |||
384 | 384 | ||
385 | #define AR_PHY_HEAVY_CLIP_ENABLE 0x99E0 | 385 | #define AR_PHY_HEAVY_CLIP_ENABLE 0x99E0 |
386 | 386 | ||
387 | #define AR_PHY_HEAVY_CLIP_FACTOR_RIFS 0x99EC | ||
388 | #define AR_PHY_RIFS_INIT_DELAY 0x03ff0000 | ||
389 | |||
387 | #define AR_PHY_M_SLEEP 0x99f0 | 390 | #define AR_PHY_M_SLEEP 0x99f0 |
388 | #define AR_PHY_REFCLKDLY 0x99f4 | 391 | #define AR_PHY_REFCLKDLY 0x99f4 |
389 | #define AR_PHY_REFCLKPD 0x99f8 | 392 | #define AR_PHY_REFCLKPD 0x99f8 |
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 70fdb9d8db8..ac34a055c71 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
@@ -668,7 +668,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | |||
668 | struct ieee80211_tx_rate *rates = tx_info->control.rates; | 668 | struct ieee80211_tx_rate *rates = tx_info->control.rates; |
669 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 669 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
670 | __le16 fc = hdr->frame_control; | 670 | __le16 fc = hdr->frame_control; |
671 | u8 try_per_rate, i = 0, rix, nrix; | 671 | u8 try_per_rate, i = 0, rix; |
672 | int is_probe = 0; | 672 | int is_probe = 0; |
673 | 673 | ||
674 | if (rate_control_send_low(sta, priv_sta, txrc)) | 674 | if (rate_control_send_low(sta, priv_sta, txrc)) |
@@ -678,48 +678,47 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | |||
678 | * For Multi Rate Retry we use a different number of | 678 | * For Multi Rate Retry we use a different number of |
679 | * retry attempt counts. This ends up looking like this: | 679 | * retry attempt counts. This ends up looking like this: |
680 | * | 680 | * |
681 | * MRR[0] = 2 | 681 | * MRR[0] = 4 |
682 | * MRR[1] = 2 | 682 | * MRR[1] = 4 |
683 | * MRR[2] = 2 | 683 | * MRR[2] = 4 |
684 | * MRR[3] = 4 | 684 | * MRR[3] = 8 |
685 | * | 685 | * |
686 | */ | 686 | */ |
687 | try_per_rate = sc->hw->max_rate_tries; | 687 | try_per_rate = 4; |
688 | 688 | ||
689 | rate_table = sc->cur_rate_table; | 689 | rate_table = sc->cur_rate_table; |
690 | rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe); | 690 | rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe); |
691 | nrix = rix; | ||
692 | 691 | ||
693 | if (is_probe) { | 692 | if (is_probe) { |
694 | /* set one try for probe rates. For the | 693 | /* set one try for probe rates. For the |
695 | * probes don't enable rts */ | 694 | * probes don't enable rts */ |
696 | ath_rc_rate_set_series(rate_table, &rates[i++], txrc, | 695 | ath_rc_rate_set_series(rate_table, &rates[i++], txrc, |
697 | 1, nrix, 0); | 696 | 1, rix, 0); |
698 | 697 | ||
699 | /* Get the next tried/allowed rate. No RTS for the next series | 698 | /* Get the next tried/allowed rate. No RTS for the next series |
700 | * after the probe rate | 699 | * after the probe rate |
701 | */ | 700 | */ |
702 | ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix); | 701 | ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix); |
703 | ath_rc_rate_set_series(rate_table, &rates[i++], txrc, | 702 | ath_rc_rate_set_series(rate_table, &rates[i++], txrc, |
704 | try_per_rate, nrix, 0); | 703 | try_per_rate, rix, 0); |
705 | 704 | ||
706 | tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; | 705 | tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; |
707 | } else { | 706 | } else { |
708 | /* Set the choosen rate. No RTS for first series entry. */ | 707 | /* Set the choosen rate. No RTS for first series entry. */ |
709 | ath_rc_rate_set_series(rate_table, &rates[i++], txrc, | 708 | ath_rc_rate_set_series(rate_table, &rates[i++], txrc, |
710 | try_per_rate, nrix, 0); | 709 | try_per_rate, rix, 0); |
711 | } | 710 | } |
712 | 711 | ||
713 | /* Fill in the other rates for multirate retry */ | 712 | /* Fill in the other rates for multirate retry */ |
714 | for ( ; i < 4; i++) { | 713 | for ( ; i < 4; i++) { |
715 | /* Use twice the number of tries for the last MRR segment. */ | 714 | /* Use twice the number of tries for the last MRR segment. */ |
716 | if (i + 1 == 4) | 715 | if (i + 1 == 4) |
717 | try_per_rate = 4; | 716 | try_per_rate = 8; |
718 | 717 | ||
719 | ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix); | 718 | ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix); |
720 | /* All other rates in the series have RTS enabled */ | 719 | /* All other rates in the series have RTS enabled */ |
721 | ath_rc_rate_set_series(rate_table, &rates[i], txrc, | 720 | ath_rc_rate_set_series(rate_table, &rates[i], txrc, |
722 | try_per_rate, nrix, 1); | 721 | try_per_rate, rix, 1); |
723 | } | 722 | } |
724 | 723 | ||
725 | /* | 724 | /* |
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h index 9eb96f50699..4f6d6fd442f 100644 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ b/drivers/net/wireless/ath/ath9k/rc.h | |||
@@ -57,6 +57,10 @@ enum { | |||
57 | || (_phy == WLAN_RC_PHY_HT_40_DS) \ | 57 | || (_phy == WLAN_RC_PHY_HT_40_DS) \ |
58 | || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \ | 58 | || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \ |
59 | || (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) | 59 | || (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) |
60 | #define WLAN_RC_PHY_20(_phy) ((_phy == WLAN_RC_PHY_HT_20_SS) \ | ||
61 | || (_phy == WLAN_RC_PHY_HT_20_DS) \ | ||
62 | || (_phy == WLAN_RC_PHY_HT_20_SS_HGI) \ | ||
63 | || (_phy == WLAN_RC_PHY_HT_20_DS_HGI)) | ||
60 | #define WLAN_RC_PHY_40(_phy) ((_phy == WLAN_RC_PHY_HT_40_SS) \ | 64 | #define WLAN_RC_PHY_40(_phy) ((_phy == WLAN_RC_PHY_HT_40_SS) \ |
61 | || (_phy == WLAN_RC_PHY_HT_40_DS) \ | 65 | || (_phy == WLAN_RC_PHY_HT_40_DS) \ |
62 | || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \ | 66 | || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \ |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 477365e5ae6..1ca42e5148c 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -364,10 +364,10 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb) | |||
364 | if (memcmp(common->curbssid, mgmt->bssid, ETH_ALEN) != 0) | 364 | if (memcmp(common->curbssid, mgmt->bssid, ETH_ALEN) != 0) |
365 | return; /* not from our current AP */ | 365 | return; /* not from our current AP */ |
366 | 366 | ||
367 | sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON; | 367 | sc->ps_flags &= ~PS_WAIT_FOR_BEACON; |
368 | 368 | ||
369 | if (sc->sc_flags & SC_OP_BEACON_SYNC) { | 369 | if (sc->ps_flags & PS_BEACON_SYNC) { |
370 | sc->sc_flags &= ~SC_OP_BEACON_SYNC; | 370 | sc->ps_flags &= ~PS_BEACON_SYNC; |
371 | ath_print(common, ATH_DBG_PS, | 371 | ath_print(common, ATH_DBG_PS, |
372 | "Reconfigure Beacon timers based on " | 372 | "Reconfigure Beacon timers based on " |
373 | "timestamp from the AP\n"); | 373 | "timestamp from the AP\n"); |
@@ -384,17 +384,17 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb) | |||
384 | */ | 384 | */ |
385 | ath_print(common, ATH_DBG_PS, "Received DTIM beacon indicating " | 385 | ath_print(common, ATH_DBG_PS, "Received DTIM beacon indicating " |
386 | "buffered broadcast/multicast frame(s)\n"); | 386 | "buffered broadcast/multicast frame(s)\n"); |
387 | sc->sc_flags |= SC_OP_WAIT_FOR_CAB | SC_OP_WAIT_FOR_BEACON; | 387 | sc->ps_flags |= PS_WAIT_FOR_CAB | PS_WAIT_FOR_BEACON; |
388 | return; | 388 | return; |
389 | } | 389 | } |
390 | 390 | ||
391 | if (sc->sc_flags & SC_OP_WAIT_FOR_CAB) { | 391 | if (sc->ps_flags & PS_WAIT_FOR_CAB) { |
392 | /* | 392 | /* |
393 | * This can happen if a broadcast frame is dropped or the AP | 393 | * This can happen if a broadcast frame is dropped or the AP |
394 | * fails to send a frame indicating that all CAB frames have | 394 | * fails to send a frame indicating that all CAB frames have |
395 | * been delivered. | 395 | * been delivered. |
396 | */ | 396 | */ |
397 | sc->sc_flags &= ~SC_OP_WAIT_FOR_CAB; | 397 | sc->ps_flags &= ~PS_WAIT_FOR_CAB; |
398 | ath_print(common, ATH_DBG_PS, | 398 | ath_print(common, ATH_DBG_PS, |
399 | "PS wait for CAB frames timed out\n"); | 399 | "PS wait for CAB frames timed out\n"); |
400 | } | 400 | } |
@@ -408,10 +408,10 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb) | |||
408 | hdr = (struct ieee80211_hdr *)skb->data; | 408 | hdr = (struct ieee80211_hdr *)skb->data; |
409 | 409 | ||
410 | /* Process Beacon and CAB receive in PS state */ | 410 | /* Process Beacon and CAB receive in PS state */ |
411 | if ((sc->sc_flags & SC_OP_WAIT_FOR_BEACON) && | 411 | if ((sc->ps_flags & PS_WAIT_FOR_BEACON) && |
412 | ieee80211_is_beacon(hdr->frame_control)) | 412 | ieee80211_is_beacon(hdr->frame_control)) |
413 | ath_rx_ps_beacon(sc, skb); | 413 | ath_rx_ps_beacon(sc, skb); |
414 | else if ((sc->sc_flags & SC_OP_WAIT_FOR_CAB) && | 414 | else if ((sc->ps_flags & PS_WAIT_FOR_CAB) && |
415 | (ieee80211_is_data(hdr->frame_control) || | 415 | (ieee80211_is_data(hdr->frame_control) || |
416 | ieee80211_is_action(hdr->frame_control)) && | 416 | ieee80211_is_action(hdr->frame_control)) && |
417 | is_multicast_ether_addr(hdr->addr1) && | 417 | is_multicast_ether_addr(hdr->addr1) && |
@@ -420,20 +420,20 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb) | |||
420 | * No more broadcast/multicast frames to be received at this | 420 | * No more broadcast/multicast frames to be received at this |
421 | * point. | 421 | * point. |
422 | */ | 422 | */ |
423 | sc->sc_flags &= ~SC_OP_WAIT_FOR_CAB; | 423 | sc->ps_flags &= ~PS_WAIT_FOR_CAB; |
424 | ath_print(common, ATH_DBG_PS, | 424 | ath_print(common, ATH_DBG_PS, |
425 | "All PS CAB frames received, back to sleep\n"); | 425 | "All PS CAB frames received, back to sleep\n"); |
426 | } else if ((sc->sc_flags & SC_OP_WAIT_FOR_PSPOLL_DATA) && | 426 | } else if ((sc->ps_flags & PS_WAIT_FOR_PSPOLL_DATA) && |
427 | !is_multicast_ether_addr(hdr->addr1) && | 427 | !is_multicast_ether_addr(hdr->addr1) && |
428 | !ieee80211_has_morefrags(hdr->frame_control)) { | 428 | !ieee80211_has_morefrags(hdr->frame_control)) { |
429 | sc->sc_flags &= ~SC_OP_WAIT_FOR_PSPOLL_DATA; | 429 | sc->ps_flags &= ~PS_WAIT_FOR_PSPOLL_DATA; |
430 | ath_print(common, ATH_DBG_PS, | 430 | ath_print(common, ATH_DBG_PS, |
431 | "Going back to sleep after having received " | 431 | "Going back to sleep after having received " |
432 | "PS-Poll data (0x%x)\n", | 432 | "PS-Poll data (0x%lx)\n", |
433 | sc->sc_flags & (SC_OP_WAIT_FOR_BEACON | | 433 | sc->ps_flags & (PS_WAIT_FOR_BEACON | |
434 | SC_OP_WAIT_FOR_CAB | | 434 | PS_WAIT_FOR_CAB | |
435 | SC_OP_WAIT_FOR_PSPOLL_DATA | | 435 | PS_WAIT_FOR_PSPOLL_DATA | |
436 | SC_OP_WAIT_FOR_TX_ACK)); | 436 | PS_WAIT_FOR_TX_ACK)); |
437 | } | 437 | } |
438 | } | 438 | } |
439 | 439 | ||
@@ -571,6 +571,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
571 | hw = ath_get_virt_hw(sc, hdr); | 571 | hw = ath_get_virt_hw(sc, hdr); |
572 | rx_stats = &ds->ds_rxstat; | 572 | rx_stats = &ds->ds_rxstat; |
573 | 573 | ||
574 | ath_debug_stat_rx(sc, bf); | ||
575 | |||
574 | /* | 576 | /* |
575 | * If we're asked to flush receive queue, directly | 577 | * If we're asked to flush receive queue, directly |
576 | * chain it back at the queue without processing it. | 578 | * chain it back at the queue without processing it. |
@@ -631,9 +633,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
631 | sc->rx.rxotherant = 0; | 633 | sc->rx.rxotherant = 0; |
632 | } | 634 | } |
633 | 635 | ||
634 | if (unlikely(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON | | 636 | if (unlikely(sc->ps_flags & (PS_WAIT_FOR_BEACON | |
635 | SC_OP_WAIT_FOR_CAB | | 637 | PS_WAIT_FOR_CAB | |
636 | SC_OP_WAIT_FOR_PSPOLL_DATA))) | 638 | PS_WAIT_FOR_PSPOLL_DATA))) |
637 | ath_rx_ps(sc, skb); | 639 | ath_rx_ps(sc, skb); |
638 | 640 | ||
639 | ath_rx_send_to_mac80211(hw, sc, skb, rxs); | 641 | ath_rx_send_to_mac80211(hw, sc, skb, rxs); |
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 8e653fb937a..72cfa8ebd9a 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -1547,9 +1547,9 @@ enum { | |||
1547 | 1547 | ||
1548 | #define AR_BT_COEX_WEIGHT 0x8174 | 1548 | #define AR_BT_COEX_WEIGHT 0x8174 |
1549 | #define AR_BT_COEX_WGHT 0xff55 | 1549 | #define AR_BT_COEX_WGHT 0xff55 |
1550 | #define AR_STOMP_ALL_WLAN_WGHT 0xffcc | 1550 | #define AR_STOMP_ALL_WLAN_WGHT 0xfcfc |
1551 | #define AR_STOMP_LOW_WLAN_WGHT 0xaaa8 | 1551 | #define AR_STOMP_LOW_WLAN_WGHT 0xa8a8 |
1552 | #define AR_STOMP_NONE_WLAN_WGHT 0xaa00 | 1552 | #define AR_STOMP_NONE_WLAN_WGHT 0x0000 |
1553 | #define AR_BTCOEX_BT_WGHT 0x0000ffff | 1553 | #define AR_BTCOEX_BT_WGHT 0x0000ffff |
1554 | #define AR_BTCOEX_BT_WGHT_S 0 | 1554 | #define AR_BTCOEX_BT_WGHT_S 0 |
1555 | #define AR_BTCOEX_WL_WGHT 0xffff0000 | 1555 | #define AR_BTCOEX_WL_WGHT 0xffff0000 |
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c index cd26caaf44e..a43fbf84dab 100644 --- a/drivers/net/wireless/ath/ath9k/virtual.c +++ b/drivers/net/wireless/ath/ath9k/virtual.c | |||
@@ -152,7 +152,7 @@ int ath9k_wiphy_add(struct ath_softc *sc) | |||
152 | 152 | ||
153 | SET_IEEE80211_PERM_ADDR(hw, addr); | 153 | SET_IEEE80211_PERM_ADDR(hw, addr); |
154 | 154 | ||
155 | ath_set_hw_capab(sc, hw); | 155 | ath9k_set_hw_capab(sc, hw); |
156 | 156 | ||
157 | error = ieee80211_register_hw(hw); | 157 | error = ieee80211_register_hw(hw); |
158 | 158 | ||
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 29bf33692f7..47294f90bbe 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -1498,26 +1498,6 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) | |||
1498 | if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) | 1498 | if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) |
1499 | ctsrate |= rate->hw_value_short; | 1499 | ctsrate |= rate->hw_value_short; |
1500 | 1500 | ||
1501 | /* | ||
1502 | * ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. | ||
1503 | * Check the first rate in the series to decide whether RTS/CTS | ||
1504 | * or CTS-to-self has to be used. | ||
1505 | */ | ||
1506 | if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) | ||
1507 | flags = ATH9K_TXDESC_CTSENA; | ||
1508 | else if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) | ||
1509 | flags = ATH9K_TXDESC_RTSENA; | ||
1510 | |||
1511 | /* FIXME: Handle aggregation protection */ | ||
1512 | if (sc->config.ath_aggr_prot && | ||
1513 | (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) { | ||
1514 | flags = ATH9K_TXDESC_RTSENA; | ||
1515 | } | ||
1516 | |||
1517 | /* For AR5416 - RTS cannot be followed by a frame larger than 8K */ | ||
1518 | if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit)) | ||
1519 | flags &= ~(ATH9K_TXDESC_RTSENA); | ||
1520 | |||
1521 | for (i = 0; i < 4; i++) { | 1501 | for (i = 0; i < 4; i++) { |
1522 | bool is_40, is_sgi, is_sp; | 1502 | bool is_40, is_sgi, is_sp; |
1523 | int phy; | 1503 | int phy; |
@@ -1529,8 +1509,15 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) | |||
1529 | series[i].Tries = rates[i].count; | 1509 | series[i].Tries = rates[i].count; |
1530 | series[i].ChSel = common->tx_chainmask; | 1510 | series[i].ChSel = common->tx_chainmask; |
1531 | 1511 | ||
1532 | if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) | 1512 | if ((sc->config.ath_aggr_prot && bf_isaggr(bf)) || |
1513 | (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)) { | ||
1533 | series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; | 1514 | series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; |
1515 | flags |= ATH9K_TXDESC_RTSENA; | ||
1516 | } else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { | ||
1517 | series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; | ||
1518 | flags |= ATH9K_TXDESC_CTSENA; | ||
1519 | } | ||
1520 | |||
1534 | if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) | 1521 | if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) |
1535 | series[i].RateFlags |= ATH9K_RATESERIES_2040; | 1522 | series[i].RateFlags |= ATH9K_RATESERIES_2040; |
1536 | if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI) | 1523 | if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI) |
@@ -1568,6 +1555,14 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) | |||
1568 | phy, rate->bitrate * 100, bf->bf_frmlen, rix, is_sp); | 1555 | phy, rate->bitrate * 100, bf->bf_frmlen, rix, is_sp); |
1569 | } | 1556 | } |
1570 | 1557 | ||
1558 | /* For AR5416 - RTS cannot be followed by a frame larger than 8K */ | ||
1559 | if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit)) | ||
1560 | flags &= ~ATH9K_TXDESC_RTSENA; | ||
1561 | |||
1562 | /* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */ | ||
1563 | if (flags & ATH9K_TXDESC_RTSENA) | ||
1564 | flags &= ~ATH9K_TXDESC_CTSENA; | ||
1565 | |||
1571 | /* set dur_update_en for l-sig computation except for PS-Poll frames */ | 1566 | /* set dur_update_en for l-sig computation except for PS-Poll frames */ |
1572 | ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc, | 1567 | ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc, |
1573 | bf->bf_lastbf->bf_desc, | 1568 | bf->bf_lastbf->bf_desc, |
@@ -1648,7 +1643,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, | |||
1648 | /* tag if this is a nullfunc frame to enable PS when AP acks it */ | 1643 | /* tag if this is a nullfunc frame to enable PS when AP acks it */ |
1649 | if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc)) { | 1644 | if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc)) { |
1650 | bf->bf_isnullfunc = true; | 1645 | bf->bf_isnullfunc = true; |
1651 | sc->sc_flags &= ~SC_OP_NULLFUNC_COMPLETED; | 1646 | sc->ps_flags &= ~PS_NULLFUNC_COMPLETED; |
1652 | } else | 1647 | } else |
1653 | bf->bf_isnullfunc = false; | 1648 | bf->bf_isnullfunc = false; |
1654 | 1649 | ||
@@ -1858,15 +1853,15 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
1858 | skb_pull(skb, padsize); | 1853 | skb_pull(skb, padsize); |
1859 | } | 1854 | } |
1860 | 1855 | ||
1861 | if (sc->sc_flags & SC_OP_WAIT_FOR_TX_ACK) { | 1856 | if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) { |
1862 | sc->sc_flags &= ~SC_OP_WAIT_FOR_TX_ACK; | 1857 | sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK; |
1863 | ath_print(common, ATH_DBG_PS, | 1858 | ath_print(common, ATH_DBG_PS, |
1864 | "Going back to sleep after having " | 1859 | "Going back to sleep after having " |
1865 | "received TX status (0x%x)\n", | 1860 | "received TX status (0x%lx)\n", |
1866 | sc->sc_flags & (SC_OP_WAIT_FOR_BEACON | | 1861 | sc->ps_flags & (PS_WAIT_FOR_BEACON | |
1867 | SC_OP_WAIT_FOR_CAB | | 1862 | PS_WAIT_FOR_CAB | |
1868 | SC_OP_WAIT_FOR_PSPOLL_DATA | | 1863 | PS_WAIT_FOR_PSPOLL_DATA | |
1869 | SC_OP_WAIT_FOR_TX_ACK)); | 1864 | PS_WAIT_FOR_TX_ACK)); |
1870 | } | 1865 | } |
1871 | 1866 | ||
1872 | if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL)) | 1867 | if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL)) |
@@ -2053,11 +2048,10 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2053 | */ | 2048 | */ |
2054 | if (bf->bf_isnullfunc && | 2049 | if (bf->bf_isnullfunc && |
2055 | (ds->ds_txstat.ts_status & ATH9K_TX_ACKED)) { | 2050 | (ds->ds_txstat.ts_status & ATH9K_TX_ACKED)) { |
2056 | if ((sc->sc_flags & SC_OP_PS_ENABLED)) { | 2051 | if ((sc->ps_flags & PS_ENABLED)) |
2057 | sc->ps_enabled = true; | 2052 | ath9k_enable_ps(sc); |
2058 | ath9k_hw_setrxabort(sc->sc_ah, 1); | 2053 | else |
2059 | } else | 2054 | sc->ps_flags |= PS_NULLFUNC_COMPLETED; |
2060 | sc->sc_flags |= SC_OP_NULLFUNC_COMPLETED; | ||
2061 | } | 2055 | } |
2062 | 2056 | ||
2063 | /* | 2057 | /* |
diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h index d6b685a06c5..8263633c003 100644 --- a/drivers/net/wireless/ath/debug.h +++ b/drivers/net/wireless/ath/debug.h | |||
@@ -65,11 +65,11 @@ enum ATH_DEBUG { | |||
65 | #define ATH_DBG_DEFAULT (ATH_DBG_FATAL) | 65 | #define ATH_DBG_DEFAULT (ATH_DBG_FATAL) |
66 | 66 | ||
67 | #ifdef CONFIG_ATH_DEBUG | 67 | #ifdef CONFIG_ATH_DEBUG |
68 | void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...); | 68 | void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...) |
69 | __attribute__ ((format (printf, 3, 4))); | ||
69 | #else | 70 | #else |
70 | static inline void ath_print(struct ath_common *common, | 71 | static inline void __attribute__ ((format (printf, 3, 4))) |
71 | int dbg_mask, | 72 | ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...) |
72 | const char *fmt, ...) | ||
73 | { | 73 | { |
74 | } | 74 | } |
75 | #endif /* CONFIG_ATH_DEBUG */ | 75 | #endif /* CONFIG_ATH_DEBUG */ |
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 039ac490465..04abd1f556b 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c | |||
@@ -110,8 +110,9 @@ static const struct ieee80211_regdomain ath_world_regdom_67_68_6A = { | |||
110 | 110 | ||
111 | static inline bool is_wwr_sku(u16 regd) | 111 | static inline bool is_wwr_sku(u16 regd) |
112 | { | 112 | { |
113 | return ((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) || | 113 | return ((regd & COUNTRY_ERD_FLAG) != COUNTRY_ERD_FLAG) && |
114 | (regd == WORLD); | 114 | (((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) || |
115 | (regd == WORLD)); | ||
115 | } | 116 | } |
116 | 117 | ||
117 | static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg) | 118 | static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg) |