diff options
Diffstat (limited to 'drivers/net/wireless/ath')
31 files changed, 1117 insertions, 233 deletions
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index e0ba7cd14252..b59cfbe0276b 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #ifndef ATH_H | 17 | #ifndef ATH_H |
18 | #define ATH_H | 18 | #define ATH_H |
19 | 19 | ||
20 | #include <linux/etherdevice.h> | ||
20 | #include <linux/skbuff.h> | 21 | #include <linux/skbuff.h> |
21 | #include <linux/if_ether.h> | 22 | #include <linux/if_ether.h> |
22 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
@@ -165,6 +166,7 @@ struct ath_common { | |||
165 | struct sk_buff *ath_rxbuf_alloc(struct ath_common *common, | 166 | struct sk_buff *ath_rxbuf_alloc(struct ath_common *common, |
166 | u32 len, | 167 | u32 len, |
167 | gfp_t gfp_mask); | 168 | gfp_t gfp_mask); |
169 | bool ath_is_mybeacon(struct ath_common *common, struct ieee80211_hdr *hdr); | ||
168 | 170 | ||
169 | void ath_hw_setbssidmask(struct ath_common *common); | 171 | void ath_hw_setbssidmask(struct ath_common *common); |
170 | void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key); | 172 | void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key); |
diff --git a/drivers/net/wireless/ath/ath10k/Kconfig b/drivers/net/wireless/ath/ath10k/Kconfig index 82e8088ca9b4..a6f5285235af 100644 --- a/drivers/net/wireless/ath/ath10k/Kconfig +++ b/drivers/net/wireless/ath/ath10k/Kconfig | |||
@@ -37,3 +37,10 @@ config ATH10K_TRACING | |||
37 | ---help--- | 37 | ---help--- |
38 | Select this to ath10k use tracing infrastructure. | 38 | Select this to ath10k use tracing infrastructure. |
39 | 39 | ||
40 | config ATH10K_DFS_CERTIFIED | ||
41 | bool "Atheros DFS support for certified platforms" | ||
42 | depends on ATH10K && CFG80211_CERTIFICATION_ONUS | ||
43 | default n | ||
44 | ---help--- | ||
45 | This option enables DFS support for initiating radiation on | ||
46 | ath10k. | ||
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 79726e0fe2f0..ade1781c7186 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h | |||
@@ -253,6 +253,9 @@ struct ath10k_vif { | |||
253 | u8 bssid[ETH_ALEN]; | 253 | u8 bssid[ETH_ALEN]; |
254 | } ibss; | 254 | } ibss; |
255 | } u; | 255 | } u; |
256 | |||
257 | u8 fixed_rate; | ||
258 | u8 fixed_nss; | ||
256 | }; | 259 | }; |
257 | 260 | ||
258 | struct ath10k_vif_iter { | 261 | struct ath10k_vif_iter { |
@@ -272,6 +275,8 @@ struct ath10k_debug { | |||
272 | struct delayed_work htt_stats_dwork; | 275 | struct delayed_work htt_stats_dwork; |
273 | struct ath10k_dfs_stats dfs_stats; | 276 | struct ath10k_dfs_stats dfs_stats; |
274 | struct ath_dfs_pool_stats dfs_pool_stats; | 277 | struct ath_dfs_pool_stats dfs_pool_stats; |
278 | |||
279 | u32 fw_dbglog_mask; | ||
275 | }; | 280 | }; |
276 | 281 | ||
277 | enum ath10k_state { | 282 | enum ath10k_state { |
@@ -306,6 +311,9 @@ enum ath10k_fw_features { | |||
306 | /* firmware support tx frame management over WMI, otherwise it's HTT */ | 311 | /* firmware support tx frame management over WMI, otherwise it's HTT */ |
307 | ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX = 2, | 312 | ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX = 2, |
308 | 313 | ||
314 | /* Firmware does not support P2P */ | ||
315 | ATH10K_FW_FEATURE_NO_P2P = 3, | ||
316 | |||
309 | /* keep last */ | 317 | /* keep last */ |
310 | ATH10K_FW_FEATURE_COUNT, | 318 | ATH10K_FW_FEATURE_COUNT, |
311 | }; | 319 | }; |
@@ -429,6 +437,9 @@ struct ath10k { | |||
429 | struct list_head peers; | 437 | struct list_head peers; |
430 | wait_queue_head_t peer_mapping_wq; | 438 | wait_queue_head_t peer_mapping_wq; |
431 | 439 | ||
440 | /* number of created peers; protected by data_lock */ | ||
441 | int num_peers; | ||
442 | |||
432 | struct work_struct offchan_tx_work; | 443 | struct work_struct offchan_tx_work; |
433 | struct sk_buff_head offchan_tx_queue; | 444 | struct sk_buff_head offchan_tx_queue; |
434 | struct completion offchan_tx_completed; | 445 | struct completion offchan_tx_completed; |
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 6bdfad3144af..6debd281350a 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c | |||
@@ -614,6 +614,61 @@ static const struct file_operations fops_htt_stats_mask = { | |||
614 | .llseek = default_llseek, | 614 | .llseek = default_llseek, |
615 | }; | 615 | }; |
616 | 616 | ||
617 | static ssize_t ath10k_read_fw_dbglog(struct file *file, | ||
618 | char __user *user_buf, | ||
619 | size_t count, loff_t *ppos) | ||
620 | { | ||
621 | struct ath10k *ar = file->private_data; | ||
622 | unsigned int len; | ||
623 | char buf[32]; | ||
624 | |||
625 | len = scnprintf(buf, sizeof(buf), "0x%08x\n", | ||
626 | ar->debug.fw_dbglog_mask); | ||
627 | |||
628 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
629 | } | ||
630 | |||
631 | static ssize_t ath10k_write_fw_dbglog(struct file *file, | ||
632 | const char __user *user_buf, | ||
633 | size_t count, loff_t *ppos) | ||
634 | { | ||
635 | struct ath10k *ar = file->private_data; | ||
636 | unsigned long mask; | ||
637 | int ret; | ||
638 | |||
639 | ret = kstrtoul_from_user(user_buf, count, 0, &mask); | ||
640 | if (ret) | ||
641 | return ret; | ||
642 | |||
643 | mutex_lock(&ar->conf_mutex); | ||
644 | |||
645 | ar->debug.fw_dbglog_mask = mask; | ||
646 | |||
647 | if (ar->state == ATH10K_STATE_ON) { | ||
648 | ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask); | ||
649 | if (ret) { | ||
650 | ath10k_warn("dbglog cfg failed from debugfs: %d\n", | ||
651 | ret); | ||
652 | goto exit; | ||
653 | } | ||
654 | } | ||
655 | |||
656 | ret = count; | ||
657 | |||
658 | exit: | ||
659 | mutex_unlock(&ar->conf_mutex); | ||
660 | |||
661 | return ret; | ||
662 | } | ||
663 | |||
664 | static const struct file_operations fops_fw_dbglog = { | ||
665 | .read = ath10k_read_fw_dbglog, | ||
666 | .write = ath10k_write_fw_dbglog, | ||
667 | .open = simple_open, | ||
668 | .owner = THIS_MODULE, | ||
669 | .llseek = default_llseek, | ||
670 | }; | ||
671 | |||
617 | int ath10k_debug_start(struct ath10k *ar) | 672 | int ath10k_debug_start(struct ath10k *ar) |
618 | { | 673 | { |
619 | int ret; | 674 | int ret; |
@@ -625,6 +680,14 @@ int ath10k_debug_start(struct ath10k *ar) | |||
625 | /* continue normally anyway, this isn't serious */ | 680 | /* continue normally anyway, this isn't serious */ |
626 | ath10k_warn("failed to start htt stats workqueue: %d\n", ret); | 681 | ath10k_warn("failed to start htt stats workqueue: %d\n", ret); |
627 | 682 | ||
683 | if (ar->debug.fw_dbglog_mask) { | ||
684 | ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask); | ||
685 | if (ret) | ||
686 | /* not serious */ | ||
687 | ath10k_warn("failed to enable dbglog during start: %d", | ||
688 | ret); | ||
689 | } | ||
690 | |||
628 | return 0; | 691 | return 0; |
629 | } | 692 | } |
630 | 693 | ||
@@ -747,6 +810,9 @@ int ath10k_debug_create(struct ath10k *ar) | |||
747 | debugfs_create_file("htt_stats_mask", S_IRUSR, ar->debug.debugfs_phy, | 810 | debugfs_create_file("htt_stats_mask", S_IRUSR, ar->debug.debugfs_phy, |
748 | ar, &fops_htt_stats_mask); | 811 | ar, &fops_htt_stats_mask); |
749 | 812 | ||
813 | debugfs_create_file("fw_dbglog", S_IRUSR, ar->debug.debugfs_phy, | ||
814 | ar, &fops_fw_dbglog); | ||
815 | |||
750 | if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) { | 816 | if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) { |
751 | debugfs_create_file("dfs_simulate_radar", S_IWUSR, | 817 | debugfs_create_file("dfs_simulate_radar", S_IWUSR, |
752 | ar->debug.debugfs_phy, ar, | 818 | ar->debug.debugfs_phy, ar, |
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h index 7fc7919ea5f5..b93ae355bc08 100644 --- a/drivers/net/wireless/ath/ath10k/htt.h +++ b/drivers/net/wireless/ath/ath10k/htt.h | |||
@@ -1183,6 +1183,7 @@ struct htt_rx_info { | |||
1183 | } rate; | 1183 | } rate; |
1184 | bool fcs_err; | 1184 | bool fcs_err; |
1185 | bool amsdu_more; | 1185 | bool amsdu_more; |
1186 | bool mic_err; | ||
1186 | }; | 1187 | }; |
1187 | 1188 | ||
1188 | struct ath10k_htt { | 1189 | struct ath10k_htt { |
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index fcb534f2f28f..fe8bd1b59f0e 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c | |||
@@ -838,6 +838,20 @@ static bool ath10k_htt_rx_has_fcs_err(struct sk_buff *skb) | |||
838 | return false; | 838 | return false; |
839 | } | 839 | } |
840 | 840 | ||
841 | static bool ath10k_htt_rx_has_mic_err(struct sk_buff *skb) | ||
842 | { | ||
843 | struct htt_rx_desc *rxd; | ||
844 | u32 flags; | ||
845 | |||
846 | rxd = (void *)skb->data - sizeof(*rxd); | ||
847 | flags = __le32_to_cpu(rxd->attention.flags); | ||
848 | |||
849 | if (flags & RX_ATTENTION_FLAGS_TKIP_MIC_ERR) | ||
850 | return true; | ||
851 | |||
852 | return false; | ||
853 | } | ||
854 | |||
841 | static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb) | 855 | static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb) |
842 | { | 856 | { |
843 | struct htt_rx_desc *rxd; | 857 | struct htt_rx_desc *rxd; |
@@ -960,6 +974,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, | |||
960 | 974 | ||
961 | info.skb = msdu_head; | 975 | info.skb = msdu_head; |
962 | info.fcs_err = ath10k_htt_rx_has_fcs_err(msdu_head); | 976 | info.fcs_err = ath10k_htt_rx_has_fcs_err(msdu_head); |
977 | info.mic_err = ath10k_htt_rx_has_mic_err(msdu_head); | ||
963 | info.signal = ATH10K_DEFAULT_NOISE_FLOOR; | 978 | info.signal = ATH10K_DEFAULT_NOISE_FLOOR; |
964 | info.signal += rx->ppdu.combined_rssi; | 979 | info.signal += rx->ppdu.combined_rssi; |
965 | 980 | ||
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index 9535eaa09f09..f1505a25d810 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h | |||
@@ -115,6 +115,7 @@ enum ath10k_mcast2ucast_mode { | |||
115 | #define TARGET_10X_MAC_AGGR_DELIM 0 | 115 | #define TARGET_10X_MAC_AGGR_DELIM 0 |
116 | #define TARGET_10X_AST_SKID_LIMIT 16 | 116 | #define TARGET_10X_AST_SKID_LIMIT 16 |
117 | #define TARGET_10X_NUM_PEERS (128 + (TARGET_10X_NUM_VDEVS)) | 117 | #define TARGET_10X_NUM_PEERS (128 + (TARGET_10X_NUM_VDEVS)) |
118 | #define TARGET_10X_NUM_PEERS_MAX 128 | ||
118 | #define TARGET_10X_NUM_OFFLOAD_PEERS 0 | 119 | #define TARGET_10X_NUM_OFFLOAD_PEERS 0 |
119 | #define TARGET_10X_NUM_OFFLOAD_REORDER_BUFS 0 | 120 | #define TARGET_10X_NUM_OFFLOAD_REORDER_BUFS 0 |
120 | #define TARGET_10X_NUM_PEER_KEYS 2 | 121 | #define TARGET_10X_NUM_PEER_KEYS 2 |
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index ce9ef3499ecb..776e364eadcd 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c | |||
@@ -332,6 +332,9 @@ static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr) | |||
332 | ath10k_warn("Failed to wait for created wmi peer: %i\n", ret); | 332 | ath10k_warn("Failed to wait for created wmi peer: %i\n", ret); |
333 | return ret; | 333 | return ret; |
334 | } | 334 | } |
335 | spin_lock_bh(&ar->data_lock); | ||
336 | ar->num_peers++; | ||
337 | spin_unlock_bh(&ar->data_lock); | ||
335 | 338 | ||
336 | return 0; | 339 | return 0; |
337 | } | 340 | } |
@@ -377,6 +380,10 @@ static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr) | |||
377 | if (ret) | 380 | if (ret) |
378 | return ret; | 381 | return ret; |
379 | 382 | ||
383 | spin_lock_bh(&ar->data_lock); | ||
384 | ar->num_peers--; | ||
385 | spin_unlock_bh(&ar->data_lock); | ||
386 | |||
380 | return 0; | 387 | return 0; |
381 | } | 388 | } |
382 | 389 | ||
@@ -396,6 +403,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id) | |||
396 | 403 | ||
397 | list_del(&peer->list); | 404 | list_del(&peer->list); |
398 | kfree(peer); | 405 | kfree(peer); |
406 | ar->num_peers--; | ||
399 | } | 407 | } |
400 | spin_unlock_bh(&ar->data_lock); | 408 | spin_unlock_bh(&ar->data_lock); |
401 | } | 409 | } |
@@ -411,6 +419,7 @@ static void ath10k_peer_cleanup_all(struct ath10k *ar) | |||
411 | list_del(&peer->list); | 419 | list_del(&peer->list); |
412 | kfree(peer); | 420 | kfree(peer); |
413 | } | 421 | } |
422 | ar->num_peers = 0; | ||
414 | spin_unlock_bh(&ar->data_lock); | 423 | spin_unlock_bh(&ar->data_lock); |
415 | } | 424 | } |
416 | 425 | ||
@@ -2205,7 +2214,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, | |||
2205 | struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); | 2214 | struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); |
2206 | enum wmi_sta_powersave_param param; | 2215 | enum wmi_sta_powersave_param param; |
2207 | int ret = 0; | 2216 | int ret = 0; |
2208 | u32 value; | 2217 | u32 value, param_id; |
2209 | int bit; | 2218 | int bit; |
2210 | u32 vdev_param; | 2219 | u32 vdev_param; |
2211 | 2220 | ||
@@ -2297,6 +2306,13 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, | |||
2297 | ath10k_warn("Failed to create peer for AP: %d\n", ret); | 2306 | ath10k_warn("Failed to create peer for AP: %d\n", ret); |
2298 | goto err_vdev_delete; | 2307 | goto err_vdev_delete; |
2299 | } | 2308 | } |
2309 | |||
2310 | param_id = ar->wmi.pdev_param->sta_kickout_th; | ||
2311 | |||
2312 | /* Disable STA KICKOUT functionality in FW */ | ||
2313 | ret = ath10k_wmi_pdev_set_param(ar, param_id, 0); | ||
2314 | if (ret) | ||
2315 | ath10k_warn("Failed to disable STA KICKOUT\n"); | ||
2300 | } | 2316 | } |
2301 | 2317 | ||
2302 | if (arvif->vdev_type == WMI_VDEV_TYPE_STA) { | 2318 | if (arvif->vdev_type == WMI_VDEV_TYPE_STA) { |
@@ -2842,6 +2858,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, | |||
2842 | { | 2858 | { |
2843 | struct ath10k *ar = hw->priv; | 2859 | struct ath10k *ar = hw->priv; |
2844 | struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); | 2860 | struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); |
2861 | int max_num_peers; | ||
2845 | int ret = 0; | 2862 | int ret = 0; |
2846 | 2863 | ||
2847 | mutex_lock(&ar->conf_mutex); | 2864 | mutex_lock(&ar->conf_mutex); |
@@ -2852,9 +2869,21 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, | |||
2852 | /* | 2869 | /* |
2853 | * New station addition. | 2870 | * New station addition. |
2854 | */ | 2871 | */ |
2872 | if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) | ||
2873 | max_num_peers = TARGET_10X_NUM_PEERS_MAX - 1; | ||
2874 | else | ||
2875 | max_num_peers = TARGET_NUM_PEERS; | ||
2876 | |||
2877 | if (ar->num_peers >= max_num_peers) { | ||
2878 | ath10k_warn("Number of peers exceeded: peers number %d (max peers %d)\n", | ||
2879 | ar->num_peers, max_num_peers); | ||
2880 | ret = -ENOBUFS; | ||
2881 | goto exit; | ||
2882 | } | ||
2883 | |||
2855 | ath10k_dbg(ATH10K_DBG_MAC, | 2884 | ath10k_dbg(ATH10K_DBG_MAC, |
2856 | "mac vdev %d peer create %pM (new sta)\n", | 2885 | "mac vdev %d peer create %pM (new sta) num_peers %d\n", |
2857 | arvif->vdev_id, sta->addr); | 2886 | arvif->vdev_id, sta->addr, ar->num_peers); |
2858 | 2887 | ||
2859 | ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr); | 2888 | ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr); |
2860 | if (ret) | 2889 | if (ret) |
@@ -2904,7 +2933,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, | |||
2904 | ath10k_warn("Failed to disassociate station: %pM\n", | 2933 | ath10k_warn("Failed to disassociate station: %pM\n", |
2905 | sta->addr); | 2934 | sta->addr); |
2906 | } | 2935 | } |
2907 | 2936 | exit: | |
2908 | mutex_unlock(&ar->conf_mutex); | 2937 | mutex_unlock(&ar->conf_mutex); |
2909 | return ret; | 2938 | return ret; |
2910 | } | 2939 | } |
@@ -3310,6 +3339,307 @@ exit: | |||
3310 | return ret; | 3339 | return ret; |
3311 | } | 3340 | } |
3312 | 3341 | ||
3342 | /* Helper table for legacy fixed_rate/bitrate_mask */ | ||
3343 | static const u8 cck_ofdm_rate[] = { | ||
3344 | /* CCK */ | ||
3345 | 3, /* 1Mbps */ | ||
3346 | 2, /* 2Mbps */ | ||
3347 | 1, /* 5.5Mbps */ | ||
3348 | 0, /* 11Mbps */ | ||
3349 | /* OFDM */ | ||
3350 | 3, /* 6Mbps */ | ||
3351 | 7, /* 9Mbps */ | ||
3352 | 2, /* 12Mbps */ | ||
3353 | 6, /* 18Mbps */ | ||
3354 | 1, /* 24Mbps */ | ||
3355 | 5, /* 36Mbps */ | ||
3356 | 0, /* 48Mbps */ | ||
3357 | 4, /* 54Mbps */ | ||
3358 | }; | ||
3359 | |||
3360 | /* Check if only one bit set */ | ||
3361 | static int ath10k_check_single_mask(u32 mask) | ||
3362 | { | ||
3363 | int bit; | ||
3364 | |||
3365 | bit = ffs(mask); | ||
3366 | if (!bit) | ||
3367 | return 0; | ||
3368 | |||
3369 | mask &= ~BIT(bit - 1); | ||
3370 | if (mask) | ||
3371 | return 2; | ||
3372 | |||
3373 | return 1; | ||
3374 | } | ||
3375 | |||
3376 | static bool | ||
3377 | ath10k_default_bitrate_mask(struct ath10k *ar, | ||
3378 | enum ieee80211_band band, | ||
3379 | const struct cfg80211_bitrate_mask *mask) | ||
3380 | { | ||
3381 | u32 legacy = 0x00ff; | ||
3382 | u8 ht = 0xff, i; | ||
3383 | u16 vht = 0x3ff; | ||
3384 | |||
3385 | switch (band) { | ||
3386 | case IEEE80211_BAND_2GHZ: | ||
3387 | legacy = 0x00fff; | ||
3388 | vht = 0; | ||
3389 | break; | ||
3390 | case IEEE80211_BAND_5GHZ: | ||
3391 | break; | ||
3392 | default: | ||
3393 | return false; | ||
3394 | } | ||
3395 | |||
3396 | if (mask->control[band].legacy != legacy) | ||
3397 | return false; | ||
3398 | |||
3399 | for (i = 0; i < ar->num_rf_chains; i++) | ||
3400 | if (mask->control[band].ht_mcs[i] != ht) | ||
3401 | return false; | ||
3402 | |||
3403 | for (i = 0; i < ar->num_rf_chains; i++) | ||
3404 | if (mask->control[band].vht_mcs[i] != vht) | ||
3405 | return false; | ||
3406 | |||
3407 | return true; | ||
3408 | } | ||
3409 | |||
3410 | static bool | ||
3411 | ath10k_bitrate_mask_nss(const struct cfg80211_bitrate_mask *mask, | ||
3412 | enum ieee80211_band band, | ||
3413 | u8 *fixed_nss) | ||
3414 | { | ||
3415 | int ht_nss = 0, vht_nss = 0, i; | ||
3416 | |||
3417 | /* check legacy */ | ||
3418 | if (ath10k_check_single_mask(mask->control[band].legacy)) | ||
3419 | return false; | ||
3420 | |||
3421 | /* check HT */ | ||
3422 | for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) { | ||
3423 | if (mask->control[band].ht_mcs[i] == 0xff) | ||
3424 | continue; | ||
3425 | else if (mask->control[band].ht_mcs[i] == 0x00) | ||
3426 | break; | ||
3427 | else | ||
3428 | return false; | ||
3429 | } | ||
3430 | |||
3431 | ht_nss = i; | ||
3432 | |||
3433 | /* check VHT */ | ||
3434 | for (i = 0; i < NL80211_VHT_NSS_MAX; i++) { | ||
3435 | if (mask->control[band].vht_mcs[i] == 0x03ff) | ||
3436 | continue; | ||
3437 | else if (mask->control[band].vht_mcs[i] == 0x0000) | ||
3438 | break; | ||
3439 | else | ||
3440 | return false; | ||
3441 | } | ||
3442 | |||
3443 | vht_nss = i; | ||
3444 | |||
3445 | if (ht_nss > 0 && vht_nss > 0) | ||
3446 | return false; | ||
3447 | |||
3448 | if (ht_nss) | ||
3449 | *fixed_nss = ht_nss; | ||
3450 | else if (vht_nss) | ||
3451 | *fixed_nss = vht_nss; | ||
3452 | else | ||
3453 | return false; | ||
3454 | |||
3455 | return true; | ||
3456 | } | ||
3457 | |||
3458 | static bool | ||
3459 | ath10k_bitrate_mask_correct(const struct cfg80211_bitrate_mask *mask, | ||
3460 | enum ieee80211_band band, | ||
3461 | enum wmi_rate_preamble *preamble) | ||
3462 | { | ||
3463 | int legacy = 0, ht = 0, vht = 0, i; | ||
3464 | |||
3465 | *preamble = WMI_RATE_PREAMBLE_OFDM; | ||
3466 | |||
3467 | /* check legacy */ | ||
3468 | legacy = ath10k_check_single_mask(mask->control[band].legacy); | ||
3469 | if (legacy > 1) | ||
3470 | return false; | ||
3471 | |||
3472 | /* check HT */ | ||
3473 | for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) | ||
3474 | ht += ath10k_check_single_mask(mask->control[band].ht_mcs[i]); | ||
3475 | if (ht > 1) | ||
3476 | return false; | ||
3477 | |||
3478 | /* check VHT */ | ||
3479 | for (i = 0; i < NL80211_VHT_NSS_MAX; i++) | ||
3480 | vht += ath10k_check_single_mask(mask->control[band].vht_mcs[i]); | ||
3481 | if (vht > 1) | ||
3482 | return false; | ||
3483 | |||
3484 | /* Currently we support only one fixed_rate */ | ||
3485 | if ((legacy + ht + vht) != 1) | ||
3486 | return false; | ||
3487 | |||
3488 | if (ht) | ||
3489 | *preamble = WMI_RATE_PREAMBLE_HT; | ||
3490 | else if (vht) | ||
3491 | *preamble = WMI_RATE_PREAMBLE_VHT; | ||
3492 | |||
3493 | return true; | ||
3494 | } | ||
3495 | |||
3496 | static bool | ||
3497 | ath10k_bitrate_mask_rate(const struct cfg80211_bitrate_mask *mask, | ||
3498 | enum ieee80211_band band, | ||
3499 | u8 *fixed_rate, | ||
3500 | u8 *fixed_nss) | ||
3501 | { | ||
3502 | u8 rate = 0, pream = 0, nss = 0, i; | ||
3503 | enum wmi_rate_preamble preamble; | ||
3504 | |||
3505 | /* Check if single rate correct */ | ||
3506 | if (!ath10k_bitrate_mask_correct(mask, band, &preamble)) | ||
3507 | return false; | ||
3508 | |||
3509 | pream = preamble; | ||
3510 | |||
3511 | switch (preamble) { | ||
3512 | case WMI_RATE_PREAMBLE_CCK: | ||
3513 | case WMI_RATE_PREAMBLE_OFDM: | ||
3514 | i = ffs(mask->control[band].legacy) - 1; | ||
3515 | |||
3516 | if (band == IEEE80211_BAND_2GHZ && i < 4) | ||
3517 | pream = WMI_RATE_PREAMBLE_CCK; | ||
3518 | |||
3519 | if (band == IEEE80211_BAND_5GHZ) | ||
3520 | i += 4; | ||
3521 | |||
3522 | if (i >= ARRAY_SIZE(cck_ofdm_rate)) | ||
3523 | return false; | ||
3524 | |||
3525 | rate = cck_ofdm_rate[i]; | ||
3526 | break; | ||
3527 | case WMI_RATE_PREAMBLE_HT: | ||
3528 | for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) | ||
3529 | if (mask->control[band].ht_mcs[i]) | ||
3530 | break; | ||
3531 | |||
3532 | if (i == IEEE80211_HT_MCS_MASK_LEN) | ||
3533 | return false; | ||
3534 | |||
3535 | rate = ffs(mask->control[band].ht_mcs[i]) - 1; | ||
3536 | nss = i; | ||
3537 | break; | ||
3538 | case WMI_RATE_PREAMBLE_VHT: | ||
3539 | for (i = 0; i < NL80211_VHT_NSS_MAX; i++) | ||
3540 | if (mask->control[band].vht_mcs[i]) | ||
3541 | break; | ||
3542 | |||
3543 | if (i == NL80211_VHT_NSS_MAX) | ||
3544 | return false; | ||
3545 | |||
3546 | rate = ffs(mask->control[band].vht_mcs[i]) - 1; | ||
3547 | nss = i; | ||
3548 | break; | ||
3549 | } | ||
3550 | |||
3551 | *fixed_nss = nss + 1; | ||
3552 | nss <<= 4; | ||
3553 | pream <<= 6; | ||
3554 | |||
3555 | ath10k_dbg(ATH10K_DBG_MAC, "mac fixed rate pream 0x%02x nss 0x%02x rate 0x%02x\n", | ||
3556 | pream, nss, rate); | ||
3557 | |||
3558 | *fixed_rate = pream | nss | rate; | ||
3559 | |||
3560 | return true; | ||
3561 | } | ||
3562 | |||
3563 | static bool ath10k_get_fixed_rate_nss(const struct cfg80211_bitrate_mask *mask, | ||
3564 | enum ieee80211_band band, | ||
3565 | u8 *fixed_rate, | ||
3566 | u8 *fixed_nss) | ||
3567 | { | ||
3568 | /* First check full NSS mask, if we can simply limit NSS */ | ||
3569 | if (ath10k_bitrate_mask_nss(mask, band, fixed_nss)) | ||
3570 | return true; | ||
3571 | |||
3572 | /* Next Check single rate is set */ | ||
3573 | return ath10k_bitrate_mask_rate(mask, band, fixed_rate, fixed_nss); | ||
3574 | } | ||
3575 | |||
3576 | static int ath10k_set_fixed_rate_param(struct ath10k_vif *arvif, | ||
3577 | u8 fixed_rate, | ||
3578 | u8 fixed_nss) | ||
3579 | { | ||
3580 | struct ath10k *ar = arvif->ar; | ||
3581 | u32 vdev_param; | ||
3582 | int ret = 0; | ||
3583 | |||
3584 | mutex_lock(&ar->conf_mutex); | ||
3585 | |||
3586 | if (arvif->fixed_rate == fixed_rate && | ||
3587 | arvif->fixed_nss == fixed_nss) | ||
3588 | goto exit; | ||
3589 | |||
3590 | if (fixed_rate == WMI_FIXED_RATE_NONE) | ||
3591 | ath10k_dbg(ATH10K_DBG_MAC, "mac disable fixed bitrate mask\n"); | ||
3592 | |||
3593 | vdev_param = ar->wmi.vdev_param->fixed_rate; | ||
3594 | ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, | ||
3595 | vdev_param, fixed_rate); | ||
3596 | if (ret) { | ||
3597 | ath10k_warn("Could not set fixed_rate param 0x%02x: %d\n", | ||
3598 | fixed_rate, ret); | ||
3599 | ret = -EINVAL; | ||
3600 | goto exit; | ||
3601 | } | ||
3602 | |||
3603 | arvif->fixed_rate = fixed_rate; | ||
3604 | |||
3605 | vdev_param = ar->wmi.vdev_param->nss; | ||
3606 | ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, | ||
3607 | vdev_param, fixed_nss); | ||
3608 | |||
3609 | if (ret) { | ||
3610 | ath10k_warn("Could not set fixed_nss param %d: %d\n", | ||
3611 | fixed_nss, ret); | ||
3612 | ret = -EINVAL; | ||
3613 | goto exit; | ||
3614 | } | ||
3615 | |||
3616 | arvif->fixed_nss = fixed_nss; | ||
3617 | |||
3618 | exit: | ||
3619 | mutex_unlock(&ar->conf_mutex); | ||
3620 | return ret; | ||
3621 | } | ||
3622 | |||
3623 | static int ath10k_set_bitrate_mask(struct ieee80211_hw *hw, | ||
3624 | struct ieee80211_vif *vif, | ||
3625 | const struct cfg80211_bitrate_mask *mask) | ||
3626 | { | ||
3627 | struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); | ||
3628 | struct ath10k *ar = arvif->ar; | ||
3629 | enum ieee80211_band band = ar->hw->conf.chandef.chan->band; | ||
3630 | u8 fixed_rate = WMI_FIXED_RATE_NONE; | ||
3631 | u8 fixed_nss = ar->num_rf_chains; | ||
3632 | |||
3633 | if (!ath10k_default_bitrate_mask(ar, band, mask)) { | ||
3634 | if (!ath10k_get_fixed_rate_nss(mask, band, | ||
3635 | &fixed_rate, | ||
3636 | &fixed_nss)) | ||
3637 | return -EINVAL; | ||
3638 | } | ||
3639 | |||
3640 | return ath10k_set_fixed_rate_param(arvif, fixed_rate, fixed_nss); | ||
3641 | } | ||
3642 | |||
3313 | static const struct ieee80211_ops ath10k_ops = { | 3643 | static const struct ieee80211_ops ath10k_ops = { |
3314 | .tx = ath10k_tx, | 3644 | .tx = ath10k_tx, |
3315 | .start = ath10k_start, | 3645 | .start = ath10k_start, |
@@ -3332,6 +3662,7 @@ static const struct ieee80211_ops ath10k_ops = { | |||
3332 | .tx_last_beacon = ath10k_tx_last_beacon, | 3662 | .tx_last_beacon = ath10k_tx_last_beacon, |
3333 | .restart_complete = ath10k_restart_complete, | 3663 | .restart_complete = ath10k_restart_complete, |
3334 | .get_survey = ath10k_get_survey, | 3664 | .get_survey = ath10k_get_survey, |
3665 | .set_bitrate_mask = ath10k_set_bitrate_mask, | ||
3335 | #ifdef CONFIG_PM | 3666 | #ifdef CONFIG_PM |
3336 | .suspend = ath10k_suspend, | 3667 | .suspend = ath10k_suspend, |
3337 | .resume = ath10k_resume, | 3668 | .resume = ath10k_resume, |
@@ -3464,14 +3795,12 @@ static const struct ieee80211_iface_limit ath10k_if_limits[] = { | |||
3464 | }, | 3795 | }, |
3465 | }; | 3796 | }; |
3466 | 3797 | ||
3467 | #ifdef CONFIG_ATH10K_DFS_CERTIFIED | 3798 | static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = { |
3468 | static const struct ieee80211_iface_limit ath10k_if_dfs_limits[] = { | ||
3469 | { | 3799 | { |
3470 | .max = 8, | 3800 | .max = 8, |
3471 | .types = BIT(NL80211_IFTYPE_AP) | 3801 | .types = BIT(NL80211_IFTYPE_AP) |
3472 | }, | 3802 | }, |
3473 | }; | 3803 | }; |
3474 | #endif | ||
3475 | 3804 | ||
3476 | static const struct ieee80211_iface_combination ath10k_if_comb[] = { | 3805 | static const struct ieee80211_iface_combination ath10k_if_comb[] = { |
3477 | { | 3806 | { |
@@ -3481,19 +3810,22 @@ static const struct ieee80211_iface_combination ath10k_if_comb[] = { | |||
3481 | .num_different_channels = 1, | 3810 | .num_different_channels = 1, |
3482 | .beacon_int_infra_match = true, | 3811 | .beacon_int_infra_match = true, |
3483 | }, | 3812 | }, |
3484 | #ifdef CONFIG_ATH10K_DFS_CERTIFIED | 3813 | }; |
3814 | |||
3815 | static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = { | ||
3485 | { | 3816 | { |
3486 | .limits = ath10k_if_dfs_limits, | 3817 | .limits = ath10k_10x_if_limits, |
3487 | .n_limits = ARRAY_SIZE(ath10k_if_dfs_limits), | 3818 | .n_limits = ARRAY_SIZE(ath10k_10x_if_limits), |
3488 | .max_interfaces = 8, | 3819 | .max_interfaces = 8, |
3489 | .num_different_channels = 1, | 3820 | .num_different_channels = 1, |
3490 | .beacon_int_infra_match = true, | 3821 | .beacon_int_infra_match = true, |
3822 | #ifdef CONFIG_ATH10K_DFS_CERTIFIED | ||
3491 | .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | | 3823 | .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | |
3492 | BIT(NL80211_CHAN_WIDTH_20) | | 3824 | BIT(NL80211_CHAN_WIDTH_20) | |
3493 | BIT(NL80211_CHAN_WIDTH_40) | | 3825 | BIT(NL80211_CHAN_WIDTH_40) | |
3494 | BIT(NL80211_CHAN_WIDTH_80), | 3826 | BIT(NL80211_CHAN_WIDTH_80), |
3495 | } | ||
3496 | #endif | 3827 | #endif |
3828 | }, | ||
3497 | }; | 3829 | }; |
3498 | 3830 | ||
3499 | static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar) | 3831 | static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar) |
@@ -3672,9 +4004,12 @@ int ath10k_mac_register(struct ath10k *ar) | |||
3672 | ar->hw->wiphy->interface_modes = | 4004 | ar->hw->wiphy->interface_modes = |
3673 | BIT(NL80211_IFTYPE_STATION) | | 4005 | BIT(NL80211_IFTYPE_STATION) | |
3674 | BIT(NL80211_IFTYPE_ADHOC) | | 4006 | BIT(NL80211_IFTYPE_ADHOC) | |
3675 | BIT(NL80211_IFTYPE_AP) | | 4007 | BIT(NL80211_IFTYPE_AP); |
3676 | BIT(NL80211_IFTYPE_P2P_CLIENT) | | 4008 | |
3677 | BIT(NL80211_IFTYPE_P2P_GO); | 4009 | if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->fw_features)) |
4010 | ar->hw->wiphy->interface_modes |= | ||
4011 | BIT(NL80211_IFTYPE_P2P_CLIENT) | | ||
4012 | BIT(NL80211_IFTYPE_P2P_GO); | ||
3678 | 4013 | ||
3679 | ar->hw->flags = IEEE80211_HW_SIGNAL_DBM | | 4014 | ar->hw->flags = IEEE80211_HW_SIGNAL_DBM | |
3680 | IEEE80211_HW_SUPPORTS_PS | | 4015 | IEEE80211_HW_SUPPORTS_PS | |
@@ -3704,7 +4039,6 @@ int ath10k_mac_register(struct ath10k *ar) | |||
3704 | 4039 | ||
3705 | ar->hw->vif_data_size = sizeof(struct ath10k_vif); | 4040 | ar->hw->vif_data_size = sizeof(struct ath10k_vif); |
3706 | 4041 | ||
3707 | ar->hw->channel_change_time = 5000; | ||
3708 | ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL; | 4042 | ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL; |
3709 | 4043 | ||
3710 | ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; | 4044 | ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; |
@@ -3717,8 +4051,15 @@ int ath10k_mac_register(struct ath10k *ar) | |||
3717 | */ | 4051 | */ |
3718 | ar->hw->queues = 4; | 4052 | ar->hw->queues = 4; |
3719 | 4053 | ||
3720 | ar->hw->wiphy->iface_combinations = ath10k_if_comb; | 4054 | if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { |
3721 | ar->hw->wiphy->n_iface_combinations = ARRAY_SIZE(ath10k_if_comb); | 4055 | ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb; |
4056 | ar->hw->wiphy->n_iface_combinations = | ||
4057 | ARRAY_SIZE(ath10k_10x_if_comb); | ||
4058 | } else { | ||
4059 | ar->hw->wiphy->iface_combinations = ath10k_if_comb; | ||
4060 | ar->hw->wiphy->n_iface_combinations = | ||
4061 | ARRAY_SIZE(ath10k_if_comb); | ||
4062 | } | ||
3722 | 4063 | ||
3723 | ar->hw->netdev_features = NETIF_F_HW_CSUM; | 4064 | ar->hw->netdev_features = NETIF_F_HW_CSUM; |
3724 | 4065 | ||
diff --git a/drivers/net/wireless/ath/ath10k/trace.h b/drivers/net/wireless/ath/ath10k/trace.h index 90817ddc92ba..4eb2ecbc06ef 100644 --- a/drivers/net/wireless/ath/ath10k/trace.h +++ b/drivers/net/wireless/ath/ath10k/trace.h | |||
@@ -182,6 +182,27 @@ TRACE_EVENT(ath10k_htt_stats, | |||
182 | ) | 182 | ) |
183 | ); | 183 | ); |
184 | 184 | ||
185 | TRACE_EVENT(ath10k_wmi_dbglog, | ||
186 | TP_PROTO(void *buf, size_t buf_len), | ||
187 | |||
188 | TP_ARGS(buf, buf_len), | ||
189 | |||
190 | TP_STRUCT__entry( | ||
191 | __field(size_t, buf_len) | ||
192 | __dynamic_array(u8, buf, buf_len) | ||
193 | ), | ||
194 | |||
195 | TP_fast_assign( | ||
196 | __entry->buf_len = buf_len; | ||
197 | memcpy(__get_dynamic_array(buf), buf, buf_len); | ||
198 | ), | ||
199 | |||
200 | TP_printk( | ||
201 | "len %zu", | ||
202 | __entry->buf_len | ||
203 | ) | ||
204 | ); | ||
205 | |||
185 | #endif /* _TRACE_H_ || TRACE_HEADER_MULTI_READ*/ | 206 | #endif /* _TRACE_H_ || TRACE_HEADER_MULTI_READ*/ |
186 | 207 | ||
187 | /* we don't want to use include/trace/events */ | 208 | /* we don't want to use include/trace/events */ |
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c index 22829803f087..74f45fa6f428 100644 --- a/drivers/net/wireless/ath/ath10k/txrx.c +++ b/drivers/net/wireless/ath/ath10k/txrx.c | |||
@@ -231,7 +231,7 @@ void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info) | |||
231 | ~IEEE80211_FCTL_PROTECTED); | 231 | ~IEEE80211_FCTL_PROTECTED); |
232 | } | 232 | } |
233 | 233 | ||
234 | if (info->status == HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR) | 234 | if (info->mic_err) |
235 | status->flag |= RX_FLAG_MMIC_ERROR; | 235 | status->flag |= RX_FLAG_MMIC_ERROR; |
236 | 236 | ||
237 | if (info->fcs_err) | 237 | if (info->fcs_err) |
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 1260a8d15dc3..712a606a080a 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c | |||
@@ -16,6 +16,7 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/skbuff.h> | 18 | #include <linux/skbuff.h> |
19 | #include <linux/ctype.h> | ||
19 | 20 | ||
20 | #include "core.h" | 21 | #include "core.h" |
21 | #include "htc.h" | 22 | #include "htc.h" |
@@ -875,6 +876,7 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) | |||
875 | struct wmi_mgmt_rx_event_v2 *ev_v2; | 876 | struct wmi_mgmt_rx_event_v2 *ev_v2; |
876 | struct wmi_mgmt_rx_hdr_v1 *ev_hdr; | 877 | struct wmi_mgmt_rx_hdr_v1 *ev_hdr; |
877 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 878 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
879 | struct ieee80211_channel *ch; | ||
878 | struct ieee80211_hdr *hdr; | 880 | struct ieee80211_hdr *hdr; |
879 | u32 rx_status; | 881 | u32 rx_status; |
880 | u32 channel; | 882 | u32 channel; |
@@ -927,7 +929,25 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) | |||
927 | if (rx_status & WMI_RX_STATUS_ERR_MIC) | 929 | if (rx_status & WMI_RX_STATUS_ERR_MIC) |
928 | status->flag |= RX_FLAG_MMIC_ERROR; | 930 | status->flag |= RX_FLAG_MMIC_ERROR; |
929 | 931 | ||
930 | status->band = phy_mode_to_band(phy_mode); | 932 | /* HW can Rx CCK rates on 5GHz. In that case phy_mode is set to |
933 | * MODE_11B. This means phy_mode is not a reliable source for the band | ||
934 | * of mgmt rx. */ | ||
935 | |||
936 | ch = ar->scan_channel; | ||
937 | if (!ch) | ||
938 | ch = ar->rx_channel; | ||
939 | |||
940 | if (ch) { | ||
941 | status->band = ch->band; | ||
942 | |||
943 | if (phy_mode == MODE_11B && | ||
944 | status->band == IEEE80211_BAND_5GHZ) | ||
945 | ath10k_dbg(ATH10K_DBG_MGMT, "wmi mgmt rx 11b (CCK) on 5GHz\n"); | ||
946 | } else { | ||
947 | ath10k_warn("using (unreliable) phy_mode to extract band for mgmt rx\n"); | ||
948 | status->band = phy_mode_to_band(phy_mode); | ||
949 | } | ||
950 | |||
931 | status->freq = ieee80211_channel_to_frequency(channel, status->band); | 951 | status->freq = ieee80211_channel_to_frequency(channel, status->band); |
932 | status->signal = snr + ATH10K_DEFAULT_NOISE_FLOOR; | 952 | status->signal = snr + ATH10K_DEFAULT_NOISE_FLOOR; |
933 | status->rate_idx = get_rate_idx(rate, status->band); | 953 | status->rate_idx = get_rate_idx(rate, status->band); |
@@ -937,7 +957,11 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) | |||
937 | hdr = (struct ieee80211_hdr *)skb->data; | 957 | hdr = (struct ieee80211_hdr *)skb->data; |
938 | fc = le16_to_cpu(hdr->frame_control); | 958 | fc = le16_to_cpu(hdr->frame_control); |
939 | 959 | ||
940 | if (fc & IEEE80211_FCTL_PROTECTED) { | 960 | /* FW delivers WEP Shared Auth frame with Protected Bit set and |
961 | * encrypted payload. However in case of PMF it delivers decrypted | ||
962 | * frames with Protected Bit set. */ | ||
963 | if (ieee80211_has_protected(hdr->frame_control) && | ||
964 | !ieee80211_is_auth(hdr->frame_control)) { | ||
941 | status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_IV_STRIPPED | | 965 | status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_IV_STRIPPED | |
942 | RX_FLAG_MMIC_STRIPPED; | 966 | RX_FLAG_MMIC_STRIPPED; |
943 | hdr->frame_control = __cpu_to_le16(fc & | 967 | hdr->frame_control = __cpu_to_le16(fc & |
@@ -1047,9 +1071,14 @@ static void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb) | |||
1047 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_ECHO_EVENTID\n"); | 1071 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_ECHO_EVENTID\n"); |
1048 | } | 1072 | } |
1049 | 1073 | ||
1050 | static void ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb) | 1074 | static int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb) |
1051 | { | 1075 | { |
1052 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_DEBUG_MESG_EVENTID\n"); | 1076 | ath10k_dbg(ATH10K_DBG_WMI, "wmi event debug mesg len %d\n", |
1077 | skb->len); | ||
1078 | |||
1079 | trace_ath10k_wmi_dbglog(skb->data, skb->len); | ||
1080 | |||
1081 | return 0; | ||
1053 | } | 1082 | } |
1054 | 1083 | ||
1055 | static void ath10k_wmi_event_update_stats(struct ath10k *ar, | 1084 | static void ath10k_wmi_event_update_stats(struct ath10k *ar, |
@@ -1653,9 +1682,37 @@ static void ath10k_wmi_event_profile_match(struct ath10k *ar, | |||
1653 | } | 1682 | } |
1654 | 1683 | ||
1655 | static void ath10k_wmi_event_debug_print(struct ath10k *ar, | 1684 | static void ath10k_wmi_event_debug_print(struct ath10k *ar, |
1656 | struct sk_buff *skb) | 1685 | struct sk_buff *skb) |
1657 | { | 1686 | { |
1658 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_DEBUG_PRINT_EVENTID\n"); | 1687 | char buf[101], c; |
1688 | int i; | ||
1689 | |||
1690 | for (i = 0; i < sizeof(buf) - 1; i++) { | ||
1691 | if (i >= skb->len) | ||
1692 | break; | ||
1693 | |||
1694 | c = skb->data[i]; | ||
1695 | |||
1696 | if (c == '\0') | ||
1697 | break; | ||
1698 | |||
1699 | if (isascii(c) && isprint(c)) | ||
1700 | buf[i] = c; | ||
1701 | else | ||
1702 | buf[i] = '.'; | ||
1703 | } | ||
1704 | |||
1705 | if (i == sizeof(buf) - 1) | ||
1706 | ath10k_warn("wmi debug print truncated: %d\n", skb->len); | ||
1707 | |||
1708 | /* for some reason the debug prints end with \n, remove that */ | ||
1709 | if (skb->data[i - 1] == '\n') | ||
1710 | i--; | ||
1711 | |||
1712 | /* the last byte is always reserved for the null character */ | ||
1713 | buf[i] = '\0'; | ||
1714 | |||
1715 | ath10k_dbg(ATH10K_DBG_WMI, "wmi event debug print '%s'\n", buf); | ||
1659 | } | 1716 | } |
1660 | 1717 | ||
1661 | static void ath10k_wmi_event_pdev_qvit(struct ath10k *ar, struct sk_buff *skb) | 1718 | static void ath10k_wmi_event_pdev_qvit(struct ath10k *ar, struct sk_buff *skb) |
@@ -3445,3 +3502,40 @@ int ath10k_wmi_force_fw_hang(struct ath10k *ar, | |||
3445 | type, delay_ms); | 3502 | type, delay_ms); |
3446 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid); | 3503 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid); |
3447 | } | 3504 | } |
3505 | |||
3506 | int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable) | ||
3507 | { | ||
3508 | struct wmi_dbglog_cfg_cmd *cmd; | ||
3509 | struct sk_buff *skb; | ||
3510 | u32 cfg; | ||
3511 | |||
3512 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); | ||
3513 | if (!skb) | ||
3514 | return -ENOMEM; | ||
3515 | |||
3516 | cmd = (struct wmi_dbglog_cfg_cmd *)skb->data; | ||
3517 | |||
3518 | if (module_enable) { | ||
3519 | cfg = SM(ATH10K_DBGLOG_LEVEL_VERBOSE, | ||
3520 | ATH10K_DBGLOG_CFG_LOG_LVL); | ||
3521 | } else { | ||
3522 | /* set back defaults, all modules with WARN level */ | ||
3523 | cfg = SM(ATH10K_DBGLOG_LEVEL_WARN, | ||
3524 | ATH10K_DBGLOG_CFG_LOG_LVL); | ||
3525 | module_enable = ~0; | ||
3526 | } | ||
3527 | |||
3528 | cmd->module_enable = __cpu_to_le32(module_enable); | ||
3529 | cmd->module_valid = __cpu_to_le32(~0); | ||
3530 | cmd->config_enable = __cpu_to_le32(cfg); | ||
3531 | cmd->config_valid = __cpu_to_le32(ATH10K_DBGLOG_CFG_LOG_LVL_MASK); | ||
3532 | |||
3533 | ath10k_dbg(ATH10K_DBG_WMI, | ||
3534 | "wmi dbglog cfg modules %08x %08x config %08x %08x\n", | ||
3535 | __le32_to_cpu(cmd->module_enable), | ||
3536 | __le32_to_cpu(cmd->module_valid), | ||
3537 | __le32_to_cpu(cmd->config_enable), | ||
3538 | __le32_to_cpu(cmd->config_valid)); | ||
3539 | |||
3540 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->dbglog_cfg_cmdid); | ||
3541 | } | ||
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index 0087d699b85b..4b5e7d3d32b6 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h | |||
@@ -3003,6 +3003,18 @@ struct wmi_vdev_install_key_arg { | |||
3003 | const void *key_data; | 3003 | const void *key_data; |
3004 | }; | 3004 | }; |
3005 | 3005 | ||
3006 | /* | ||
3007 | * vdev fixed rate format: | ||
3008 | * - preamble - b7:b6 - see WMI_RATE_PREMABLE_ | ||
3009 | * - nss - b5:b4 - ss number (0 mean 1ss) | ||
3010 | * - rate_mcs - b3:b0 - as below | ||
3011 | * CCK: 0 - 11Mbps, 1 - 5,5Mbps, 2 - 2Mbps, 3 - 1Mbps, | ||
3012 | * 4 - 11Mbps (s), 5 - 5,5Mbps (s), 6 - 2Mbps (s) | ||
3013 | * OFDM: 0 - 48Mbps, 1 - 24Mbps, 2 - 12Mbps, 3 - 6Mbps, | ||
3014 | * 4 - 54Mbps, 5 - 36Mbps, 6 - 18Mbps, 7 - 9Mbps | ||
3015 | * HT/VHT: MCS index | ||
3016 | */ | ||
3017 | |||
3006 | /* Preamble types to be used with VDEV fixed rate configuration */ | 3018 | /* Preamble types to be used with VDEV fixed rate configuration */ |
3007 | enum wmi_rate_preamble { | 3019 | enum wmi_rate_preamble { |
3008 | WMI_RATE_PREAMBLE_OFDM, | 3020 | WMI_RATE_PREAMBLE_OFDM, |
@@ -4090,6 +4102,54 @@ struct wmi_force_fw_hang_cmd { | |||
4090 | __le32 delay_ms; | 4102 | __le32 delay_ms; |
4091 | } __packed; | 4103 | } __packed; |
4092 | 4104 | ||
4105 | enum ath10k_dbglog_level { | ||
4106 | ATH10K_DBGLOG_LEVEL_VERBOSE = 0, | ||
4107 | ATH10K_DBGLOG_LEVEL_INFO = 1, | ||
4108 | ATH10K_DBGLOG_LEVEL_WARN = 2, | ||
4109 | ATH10K_DBGLOG_LEVEL_ERR = 3, | ||
4110 | }; | ||
4111 | |||
4112 | /* VAP ids to enable dbglog */ | ||
4113 | #define ATH10K_DBGLOG_CFG_VAP_LOG_LSB 0 | ||
4114 | #define ATH10K_DBGLOG_CFG_VAP_LOG_MASK 0x0000ffff | ||
4115 | |||
4116 | /* to enable dbglog in the firmware */ | ||
4117 | #define ATH10K_DBGLOG_CFG_REPORTING_ENABLE_LSB 16 | ||
4118 | #define ATH10K_DBGLOG_CFG_REPORTING_ENABLE_MASK 0x00010000 | ||
4119 | |||
4120 | /* timestamp resolution */ | ||
4121 | #define ATH10K_DBGLOG_CFG_RESOLUTION_LSB 17 | ||
4122 | #define ATH10K_DBGLOG_CFG_RESOLUTION_MASK 0x000E0000 | ||
4123 | |||
4124 | /* number of queued messages before sending them to the host */ | ||
4125 | #define ATH10K_DBGLOG_CFG_REPORT_SIZE_LSB 20 | ||
4126 | #define ATH10K_DBGLOG_CFG_REPORT_SIZE_MASK 0x0ff00000 | ||
4127 | |||
4128 | /* | ||
4129 | * Log levels to enable. This defines the minimum level to enable, this is | ||
4130 | * not a bitmask. See enum ath10k_dbglog_level for the values. | ||
4131 | */ | ||
4132 | #define ATH10K_DBGLOG_CFG_LOG_LVL_LSB 28 | ||
4133 | #define ATH10K_DBGLOG_CFG_LOG_LVL_MASK 0x70000000 | ||
4134 | |||
4135 | /* | ||
4136 | * Note: this is a cleaned up version of a struct firmware uses. For | ||
4137 | * example, config_valid was hidden inside an array. | ||
4138 | */ | ||
4139 | struct wmi_dbglog_cfg_cmd { | ||
4140 | /* bitmask to hold mod id config*/ | ||
4141 | __le32 module_enable; | ||
4142 | |||
4143 | /* see ATH10K_DBGLOG_CFG_ */ | ||
4144 | __le32 config_enable; | ||
4145 | |||
4146 | /* mask of module id bits to be changed */ | ||
4147 | __le32 module_valid; | ||
4148 | |||
4149 | /* mask of config bits to be changed, see ATH10K_DBGLOG_CFG_ */ | ||
4150 | __le32 config_valid; | ||
4151 | } __packed; | ||
4152 | |||
4093 | #define ATH10K_RTS_MAX 2347 | 4153 | #define ATH10K_RTS_MAX 2347 |
4094 | #define ATH10K_FRAGMT_THRESHOLD_MIN 540 | 4154 | #define ATH10K_FRAGMT_THRESHOLD_MIN 540 |
4095 | #define ATH10K_FRAGMT_THRESHOLD_MAX 2346 | 4155 | #define ATH10K_FRAGMT_THRESHOLD_MAX 2346 |
@@ -4167,5 +4227,6 @@ int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id); | |||
4167 | int ath10k_wmi_force_fw_hang(struct ath10k *ar, | 4227 | int ath10k_wmi_force_fw_hang(struct ath10k *ar, |
4168 | enum wmi_force_fw_hang_type type, u32 delay_ms); | 4228 | enum wmi_force_fw_hang_type type, u32 delay_ms); |
4169 | int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb); | 4229 | int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb); |
4230 | int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable); | ||
4170 | 4231 | ||
4171 | #endif /* _WMI_H_ */ | 4232 | #endif /* _WMI_H_ */ |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 6396ad4bce67..ef35da84f63b 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -1238,14 +1238,11 @@ static void | |||
1238 | ath5k_check_ibss_tsf(struct ath5k_hw *ah, struct sk_buff *skb, | 1238 | ath5k_check_ibss_tsf(struct ath5k_hw *ah, struct sk_buff *skb, |
1239 | struct ieee80211_rx_status *rxs) | 1239 | struct ieee80211_rx_status *rxs) |
1240 | { | 1240 | { |
1241 | struct ath_common *common = ath5k_hw_common(ah); | ||
1242 | u64 tsf, bc_tstamp; | 1241 | u64 tsf, bc_tstamp; |
1243 | u32 hw_tu; | 1242 | u32 hw_tu; |
1244 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; | 1243 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; |
1245 | 1244 | ||
1246 | if (ieee80211_is_beacon(mgmt->frame_control) && | 1245 | if (le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS) { |
1247 | le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS && | ||
1248 | ether_addr_equal_64bits(mgmt->bssid, common->curbssid)) { | ||
1249 | /* | 1246 | /* |
1250 | * Received an IBSS beacon with the same BSSID. Hardware *must* | 1247 | * Received an IBSS beacon with the same BSSID. Hardware *must* |
1251 | * have updated the local TSF. We have to work around various | 1248 | * have updated the local TSF. We have to work around various |
@@ -1301,23 +1298,6 @@ ath5k_check_ibss_tsf(struct ath5k_hw *ah, struct sk_buff *skb, | |||
1301 | } | 1298 | } |
1302 | } | 1299 | } |
1303 | 1300 | ||
1304 | static void | ||
1305 | ath5k_update_beacon_rssi(struct ath5k_hw *ah, struct sk_buff *skb, int rssi) | ||
1306 | { | ||
1307 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; | ||
1308 | struct ath_common *common = ath5k_hw_common(ah); | ||
1309 | |||
1310 | /* only beacons from our BSSID */ | ||
1311 | if (!ieee80211_is_beacon(mgmt->frame_control) || | ||
1312 | !ether_addr_equal_64bits(mgmt->bssid, common->curbssid)) | ||
1313 | return; | ||
1314 | |||
1315 | ewma_add(&ah->ah_beacon_rssi_avg, rssi); | ||
1316 | |||
1317 | /* in IBSS mode we should keep RSSI statistics per neighbour */ | ||
1318 | /* le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS */ | ||
1319 | } | ||
1320 | |||
1321 | /* | 1301 | /* |
1322 | * Compute padding position. skb must contain an IEEE 802.11 frame | 1302 | * Compute padding position. skb must contain an IEEE 802.11 frame |
1323 | */ | 1303 | */ |
@@ -1390,6 +1370,7 @@ ath5k_receive_frame(struct ath5k_hw *ah, struct sk_buff *skb, | |||
1390 | struct ath5k_rx_status *rs) | 1370 | struct ath5k_rx_status *rs) |
1391 | { | 1371 | { |
1392 | struct ieee80211_rx_status *rxs; | 1372 | struct ieee80211_rx_status *rxs; |
1373 | struct ath_common *common = ath5k_hw_common(ah); | ||
1393 | 1374 | ||
1394 | ath5k_remove_padding(skb); | 1375 | ath5k_remove_padding(skb); |
1395 | 1376 | ||
@@ -1442,11 +1423,13 @@ ath5k_receive_frame(struct ath5k_hw *ah, struct sk_buff *skb, | |||
1442 | 1423 | ||
1443 | trace_ath5k_rx(ah, skb); | 1424 | trace_ath5k_rx(ah, skb); |
1444 | 1425 | ||
1445 | ath5k_update_beacon_rssi(ah, skb, rs->rs_rssi); | 1426 | if (ath_is_mybeacon(common, (struct ieee80211_hdr *)skb->data)) { |
1427 | ewma_add(&ah->ah_beacon_rssi_avg, rs->rs_rssi); | ||
1446 | 1428 | ||
1447 | /* check beacons in IBSS mode */ | 1429 | /* check beacons in IBSS mode */ |
1448 | if (ah->opmode == NL80211_IFTYPE_ADHOC) | 1430 | if (ah->opmode == NL80211_IFTYPE_ADHOC) |
1449 | ath5k_check_ibss_tsf(ah, skb, rxs); | 1431 | ath5k_check_ibss_tsf(ah, skb, rxs); |
1432 | } | ||
1450 | 1433 | ||
1451 | ieee80211_rx(ah->hw, skb); | 1434 | ieee80211_rx(ah->hw, skb); |
1452 | } | 1435 | } |
@@ -2549,7 +2532,6 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops) | |||
2549 | hw->wiphy->available_antennas_rx = 0x3; | 2532 | hw->wiphy->available_antennas_rx = 0x3; |
2550 | 2533 | ||
2551 | hw->extra_tx_headroom = 2; | 2534 | hw->extra_tx_headroom = 2; |
2552 | hw->channel_change_time = 5000; | ||
2553 | 2535 | ||
2554 | /* | 2536 | /* |
2555 | * Mark the device as detached to avoid processing | 2537 | * Mark the device as detached to avoid processing |
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index 30d273c61bff..7b96b3e5712d 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig | |||
@@ -65,6 +65,14 @@ config ATH9K_DEBUGFS | |||
65 | 65 | ||
66 | Also required for changing debug message flags at run time. | 66 | Also required for changing debug message flags at run time. |
67 | 67 | ||
68 | config ATH9K_STATION_STATISTICS | ||
69 | bool "Detailed station statistics" | ||
70 | depends on ATH9K && ATH9K_DEBUGFS && DEBUG_FS | ||
71 | select MAC80211_DEBUGFS | ||
72 | default n | ||
73 | ---help--- | ||
74 | This option enables detailed statistics for association stations. | ||
75 | |||
68 | config ATH9K_DFS_CERTIFIED | 76 | config ATH9K_DFS_CERTIFIED |
69 | bool "Atheros DFS support for certified platforms" | 77 | bool "Atheros DFS support for certified platforms" |
70 | depends on ATH9K && CFG80211_CERTIFICATION_ONUS | 78 | depends on ATH9K && CFG80211_CERTIFICATION_ONUS |
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index e9904e5ccd81..a40e5c5d7418 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile | |||
@@ -19,6 +19,8 @@ ath9k-$(CONFIG_ATH9K_WOW) += wow.o | |||
19 | ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o \ | 19 | ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o \ |
20 | spectral.o | 20 | spectral.o |
21 | 21 | ||
22 | ath9k-$(CONFIG_ATH9K_STATION_STATISTICS) += debug_sta.o | ||
23 | |||
22 | obj-$(CONFIG_ATH9K) += ath9k.o | 24 | obj-$(CONFIG_ATH9K) += ath9k.o |
23 | 25 | ||
24 | ath9k_hw-y:= \ | 26 | ath9k_hw-y:= \ |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 8c145cd98c1c..a352128c40ad 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c | |||
@@ -565,7 +565,7 @@ static bool ar9003_hw_solve_iq_cal(struct ath_hw *ah, | |||
565 | const s32 result_shift = 1 << 15; | 565 | const s32 result_shift = 1 << 15; |
566 | struct ath_common *common = ath9k_hw_common(ah); | 566 | struct ath_common *common = ath9k_hw_common(ah); |
567 | 567 | ||
568 | f2 = (f1 * f1 + f3 * f3) / result_shift; | 568 | f2 = ((f1 >> 3) * (f1 >> 3) + (f3 >> 3) * (f3 >> 3)) >> 9; |
569 | 569 | ||
570 | if (!f2) { | 570 | if (!f2) { |
571 | ath_dbg(common, CALIBRATE, "Divide by 0\n"); | 571 | ath_dbg(common, CALIBRATE, "Divide by 0\n"); |
@@ -655,8 +655,8 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, | |||
655 | if (i2_m_q2_a0_d1 > 0x800) | 655 | if (i2_m_q2_a0_d1 > 0x800) |
656 | i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1); | 656 | i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1); |
657 | 657 | ||
658 | if (i2_p_q2_a0_d1 > 0x800) | 658 | if (i2_p_q2_a0_d1 > 0x1000) |
659 | i2_p_q2_a0_d1 = -((0xfff - i2_p_q2_a0_d1) + 1); | 659 | i2_p_q2_a0_d1 = -((0x1fff - i2_p_q2_a0_d1) + 1); |
660 | 660 | ||
661 | if (iq_corr_a0_d1 > 0x800) | 661 | if (iq_corr_a0_d1 > 0x800) |
662 | iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1); | 662 | iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1); |
@@ -700,6 +700,19 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, | |||
700 | return false; | 700 | return false; |
701 | } | 701 | } |
702 | 702 | ||
703 | if ((i2_p_q2_a0_d0 < 1024) || (i2_p_q2_a0_d0 > 2047) || | ||
704 | (i2_p_q2_a1_d0 < 0) || (i2_p_q2_a1_d1 < 0) || | ||
705 | (i2_p_q2_a0_d0 <= i2_m_q2_a0_d0) || | ||
706 | (i2_p_q2_a0_d0 <= iq_corr_a0_d0) || | ||
707 | (i2_p_q2_a0_d1 <= i2_m_q2_a0_d1) || | ||
708 | (i2_p_q2_a0_d1 <= iq_corr_a0_d1) || | ||
709 | (i2_p_q2_a1_d0 <= i2_m_q2_a1_d0) || | ||
710 | (i2_p_q2_a1_d0 <= iq_corr_a1_d0) || | ||
711 | (i2_p_q2_a1_d1 <= i2_m_q2_a1_d1) || | ||
712 | (i2_p_q2_a1_d1 <= iq_corr_a1_d1)) { | ||
713 | return false; | ||
714 | } | ||
715 | |||
703 | mag_a0_d0 = (i2_m_q2_a0_d0 * res_scale) / i2_p_q2_a0_d0; | 716 | mag_a0_d0 = (i2_m_q2_a0_d0 * res_scale) / i2_p_q2_a0_d0; |
704 | phs_a0_d0 = (iq_corr_a0_d0 * res_scale) / i2_p_q2_a0_d0; | 717 | phs_a0_d0 = (iq_corr_a0_d0 * res_scale) / i2_p_q2_a0_d0; |
705 | 718 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index f622a986c8cc..b5ac32cfbeb8 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -146,7 +146,9 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
146 | 146 | ||
147 | #define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)]) | 147 | #define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)]) |
148 | 148 | ||
149 | #define IS_CCK_RATE(rate) ((rate >= 0x18) && (rate <= 0x1e)) | 149 | #define IS_HT_RATE(rate) (rate & 0x80) |
150 | #define IS_CCK_RATE(rate) ((rate >= 0x18) && (rate <= 0x1e)) | ||
151 | #define IS_OFDM_RATE(rate) ((rate >= 0x8) && (rate <= 0xf)) | ||
150 | 152 | ||
151 | struct ath_txq { | 153 | struct ath_txq { |
152 | int mac80211_qnum; /* mac80211 queue number, -1 means not mac80211 Q */ | 154 | int mac80211_qnum; /* mac80211 queue number, -1 means not mac80211 Q */ |
@@ -262,6 +264,10 @@ struct ath_node { | |||
262 | 264 | ||
263 | bool sleeping; | 265 | bool sleeping; |
264 | bool no_ps_filter; | 266 | bool no_ps_filter; |
267 | |||
268 | #ifdef CONFIG_ATH9K_STATION_STATISTICS | ||
269 | struct ath_rx_rate_stats rx_rate_stats; | ||
270 | #endif | ||
265 | }; | 271 | }; |
266 | 272 | ||
267 | struct ath_tx_control { | 273 | struct ath_tx_control { |
@@ -685,6 +691,7 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs); | |||
685 | #define DEFAULT_CACHELINE 32 | 691 | #define DEFAULT_CACHELINE 32 |
686 | #define ATH_CABQ_READY_TIME 80 /* % of beacon interval */ | 692 | #define ATH_CABQ_READY_TIME 80 /* % of beacon interval */ |
687 | #define ATH_TXPOWER_MAX 100 /* .5 dBm units */ | 693 | #define ATH_TXPOWER_MAX 100 /* .5 dBm units */ |
694 | #define MAX_GTT_CNT 5 | ||
688 | 695 | ||
689 | enum sc_op_flags { | 696 | enum sc_op_flags { |
690 | SC_OP_INVALID, | 697 | SC_OP_INVALID, |
@@ -727,6 +734,7 @@ struct ath_softc { | |||
727 | unsigned long sc_flags; | 734 | unsigned long sc_flags; |
728 | unsigned long driver_data; | 735 | unsigned long driver_data; |
729 | 736 | ||
737 | u8 gtt_cnt; | ||
730 | u32 intrstatus; | 738 | u32 intrstatus; |
731 | u16 ps_flags; /* PS_* */ | 739 | u16 ps_flags; /* PS_* */ |
732 | u16 curtxpow; | 740 | u16 curtxpow; |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index b041052a10ee..ab7264c1d8f7 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -943,14 +943,10 @@ static const struct file_operations fops_reset = { | |||
943 | static ssize_t read_file_recv(struct file *file, char __user *user_buf, | 943 | static ssize_t read_file_recv(struct file *file, char __user *user_buf, |
944 | size_t count, loff_t *ppos) | 944 | size_t count, loff_t *ppos) |
945 | { | 945 | { |
946 | #define PHY_ERR(s, p) \ | ||
947 | len += scnprintf(buf + len, size - len, "%22s : %10u\n", s, \ | ||
948 | sc->debug.stats.rxstats.phy_err_stats[p]); | ||
949 | |||
950 | #define RXS_ERR(s, e) \ | 946 | #define RXS_ERR(s, e) \ |
951 | do { \ | 947 | do { \ |
952 | len += scnprintf(buf + len, size - len, \ | 948 | len += scnprintf(buf + len, size - len, \ |
953 | "%22s : %10u\n", s, \ | 949 | "%18s : %10u\n", s, \ |
954 | sc->debug.stats.rxstats.e);\ | 950 | sc->debug.stats.rxstats.e);\ |
955 | } while (0) | 951 | } while (0) |
956 | 952 | ||
@@ -963,6 +959,12 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, | |||
963 | if (buf == NULL) | 959 | if (buf == NULL) |
964 | return -ENOMEM; | 960 | return -ENOMEM; |
965 | 961 | ||
962 | RXS_ERR("PKTS-ALL", rx_pkts_all); | ||
963 | RXS_ERR("BYTES-ALL", rx_bytes_all); | ||
964 | RXS_ERR("BEACONS", rx_beacons); | ||
965 | RXS_ERR("FRAGS", rx_frags); | ||
966 | RXS_ERR("SPECTRAL", rx_spectral); | ||
967 | |||
966 | RXS_ERR("CRC ERR", crc_err); | 968 | RXS_ERR("CRC ERR", crc_err); |
967 | RXS_ERR("DECRYPT CRC ERR", decrypt_crc_err); | 969 | RXS_ERR("DECRYPT CRC ERR", decrypt_crc_err); |
968 | RXS_ERR("PHY ERR", phy_err); | 970 | RXS_ERR("PHY ERR", phy_err); |
@@ -970,43 +972,10 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, | |||
970 | RXS_ERR("PRE-DELIM CRC ERR", pre_delim_crc_err); | 972 | RXS_ERR("PRE-DELIM CRC ERR", pre_delim_crc_err); |
971 | RXS_ERR("POST-DELIM CRC ERR", post_delim_crc_err); | 973 | RXS_ERR("POST-DELIM CRC ERR", post_delim_crc_err); |
972 | RXS_ERR("DECRYPT BUSY ERR", decrypt_busy_err); | 974 | RXS_ERR("DECRYPT BUSY ERR", decrypt_busy_err); |
973 | RXS_ERR("RX-LENGTH-ERR", rx_len_err); | 975 | RXS_ERR("LENGTH-ERR", rx_len_err); |
974 | RXS_ERR("RX-OOM-ERR", rx_oom_err); | 976 | RXS_ERR("OOM-ERR", rx_oom_err); |
975 | RXS_ERR("RX-RATE-ERR", rx_rate_err); | 977 | RXS_ERR("RATE-ERR", rx_rate_err); |
976 | RXS_ERR("RX-TOO-MANY-FRAGS", rx_too_many_frags_err); | 978 | RXS_ERR("TOO-MANY-FRAGS", rx_too_many_frags_err); |
977 | |||
978 | PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN); | ||
979 | PHY_ERR("TIMING ERR", ATH9K_PHYERR_TIMING); | ||
980 | PHY_ERR("PARITY ERR", ATH9K_PHYERR_PARITY); | ||
981 | PHY_ERR("RATE ERR", ATH9K_PHYERR_RATE); | ||
982 | PHY_ERR("LENGTH ERR", ATH9K_PHYERR_LENGTH); | ||
983 | PHY_ERR("RADAR ERR", ATH9K_PHYERR_RADAR); | ||
984 | PHY_ERR("SERVICE ERR", ATH9K_PHYERR_SERVICE); | ||
985 | PHY_ERR("TOR ERR", ATH9K_PHYERR_TOR); | ||
986 | PHY_ERR("OFDM-TIMING ERR", ATH9K_PHYERR_OFDM_TIMING); | ||
987 | PHY_ERR("OFDM-SIGNAL-PARITY ERR", ATH9K_PHYERR_OFDM_SIGNAL_PARITY); | ||
988 | PHY_ERR("OFDM-RATE ERR", ATH9K_PHYERR_OFDM_RATE_ILLEGAL); | ||
989 | PHY_ERR("OFDM-LENGTH ERR", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL); | ||
990 | PHY_ERR("OFDM-POWER-DROP ERR", ATH9K_PHYERR_OFDM_POWER_DROP); | ||
991 | PHY_ERR("OFDM-SERVICE ERR", ATH9K_PHYERR_OFDM_SERVICE); | ||
992 | PHY_ERR("OFDM-RESTART ERR", ATH9K_PHYERR_OFDM_RESTART); | ||
993 | PHY_ERR("FALSE-RADAR-EXT ERR", ATH9K_PHYERR_FALSE_RADAR_EXT); | ||
994 | PHY_ERR("CCK-TIMING ERR", ATH9K_PHYERR_CCK_TIMING); | ||
995 | PHY_ERR("CCK-HEADER-CRC ERR", ATH9K_PHYERR_CCK_HEADER_CRC); | ||
996 | PHY_ERR("CCK-RATE ERR", ATH9K_PHYERR_CCK_RATE_ILLEGAL); | ||
997 | PHY_ERR("CCK-SERVICE ERR", ATH9K_PHYERR_CCK_SERVICE); | ||
998 | PHY_ERR("CCK-RESTART ERR", ATH9K_PHYERR_CCK_RESTART); | ||
999 | PHY_ERR("CCK-LENGTH ERR", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL); | ||
1000 | PHY_ERR("CCK-POWER-DROP ERR", ATH9K_PHYERR_CCK_POWER_DROP); | ||
1001 | PHY_ERR("HT-CRC ERR", ATH9K_PHYERR_HT_CRC_ERROR); | ||
1002 | PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL); | ||
1003 | PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL); | ||
1004 | |||
1005 | RXS_ERR("RX-Pkts-All", rx_pkts_all); | ||
1006 | RXS_ERR("RX-Bytes-All", rx_bytes_all); | ||
1007 | RXS_ERR("RX-Beacons", rx_beacons); | ||
1008 | RXS_ERR("RX-Frags", rx_frags); | ||
1009 | RXS_ERR("RX-Spectral", rx_spectral); | ||
1010 | 979 | ||
1011 | if (len > size) | 980 | if (len > size) |
1012 | len = size; | 981 | len = size; |
@@ -1017,7 +986,6 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, | |||
1017 | return retval; | 986 | return retval; |
1018 | 987 | ||
1019 | #undef RXS_ERR | 988 | #undef RXS_ERR |
1020 | #undef PHY_ERR | ||
1021 | } | 989 | } |
1022 | 990 | ||
1023 | void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) | 991 | void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) |
@@ -1056,6 +1024,67 @@ static const struct file_operations fops_recv = { | |||
1056 | .llseek = default_llseek, | 1024 | .llseek = default_llseek, |
1057 | }; | 1025 | }; |
1058 | 1026 | ||
1027 | static ssize_t read_file_phy_err(struct file *file, char __user *user_buf, | ||
1028 | size_t count, loff_t *ppos) | ||
1029 | { | ||
1030 | #define PHY_ERR(s, p) \ | ||
1031 | len += scnprintf(buf + len, size - len, "%22s : %10u\n", s, \ | ||
1032 | sc->debug.stats.rxstats.phy_err_stats[p]); | ||
1033 | |||
1034 | struct ath_softc *sc = file->private_data; | ||
1035 | char *buf; | ||
1036 | unsigned int len = 0, size = 1600; | ||
1037 | ssize_t retval = 0; | ||
1038 | |||
1039 | buf = kzalloc(size, GFP_KERNEL); | ||
1040 | if (buf == NULL) | ||
1041 | return -ENOMEM; | ||
1042 | |||
1043 | PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN); | ||
1044 | PHY_ERR("TIMING ERR", ATH9K_PHYERR_TIMING); | ||
1045 | PHY_ERR("PARITY ERR", ATH9K_PHYERR_PARITY); | ||
1046 | PHY_ERR("RATE ERR", ATH9K_PHYERR_RATE); | ||
1047 | PHY_ERR("LENGTH ERR", ATH9K_PHYERR_LENGTH); | ||
1048 | PHY_ERR("RADAR ERR", ATH9K_PHYERR_RADAR); | ||
1049 | PHY_ERR("SERVICE ERR", ATH9K_PHYERR_SERVICE); | ||
1050 | PHY_ERR("TOR ERR", ATH9K_PHYERR_TOR); | ||
1051 | PHY_ERR("OFDM-TIMING ERR", ATH9K_PHYERR_OFDM_TIMING); | ||
1052 | PHY_ERR("OFDM-SIGNAL-PARITY ERR", ATH9K_PHYERR_OFDM_SIGNAL_PARITY); | ||
1053 | PHY_ERR("OFDM-RATE ERR", ATH9K_PHYERR_OFDM_RATE_ILLEGAL); | ||
1054 | PHY_ERR("OFDM-LENGTH ERR", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL); | ||
1055 | PHY_ERR("OFDM-POWER-DROP ERR", ATH9K_PHYERR_OFDM_POWER_DROP); | ||
1056 | PHY_ERR("OFDM-SERVICE ERR", ATH9K_PHYERR_OFDM_SERVICE); | ||
1057 | PHY_ERR("OFDM-RESTART ERR", ATH9K_PHYERR_OFDM_RESTART); | ||
1058 | PHY_ERR("FALSE-RADAR-EXT ERR", ATH9K_PHYERR_FALSE_RADAR_EXT); | ||
1059 | PHY_ERR("CCK-TIMING ERR", ATH9K_PHYERR_CCK_TIMING); | ||
1060 | PHY_ERR("CCK-HEADER-CRC ERR", ATH9K_PHYERR_CCK_HEADER_CRC); | ||
1061 | PHY_ERR("CCK-RATE ERR", ATH9K_PHYERR_CCK_RATE_ILLEGAL); | ||
1062 | PHY_ERR("CCK-SERVICE ERR", ATH9K_PHYERR_CCK_SERVICE); | ||
1063 | PHY_ERR("CCK-RESTART ERR", ATH9K_PHYERR_CCK_RESTART); | ||
1064 | PHY_ERR("CCK-LENGTH ERR", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL); | ||
1065 | PHY_ERR("CCK-POWER-DROP ERR", ATH9K_PHYERR_CCK_POWER_DROP); | ||
1066 | PHY_ERR("HT-CRC ERR", ATH9K_PHYERR_HT_CRC_ERROR); | ||
1067 | PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL); | ||
1068 | PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL); | ||
1069 | |||
1070 | if (len > size) | ||
1071 | len = size; | ||
1072 | |||
1073 | retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
1074 | kfree(buf); | ||
1075 | |||
1076 | return retval; | ||
1077 | |||
1078 | #undef PHY_ERR | ||
1079 | } | ||
1080 | |||
1081 | static const struct file_operations fops_phy_err = { | ||
1082 | .read = read_file_phy_err, | ||
1083 | .open = simple_open, | ||
1084 | .owner = THIS_MODULE, | ||
1085 | .llseek = default_llseek, | ||
1086 | }; | ||
1087 | |||
1059 | static ssize_t read_file_regidx(struct file *file, char __user *user_buf, | 1088 | static ssize_t read_file_regidx(struct file *file, char __user *user_buf, |
1060 | size_t count, loff_t *ppos) | 1089 | size_t count, loff_t *ppos) |
1061 | { | 1090 | { |
@@ -1322,86 +1351,6 @@ static const struct file_operations fops_btcoex = { | |||
1322 | }; | 1351 | }; |
1323 | #endif | 1352 | #endif |
1324 | 1353 | ||
1325 | static ssize_t read_file_node_stat(struct file *file, char __user *user_buf, | ||
1326 | size_t count, loff_t *ppos) | ||
1327 | { | ||
1328 | struct ath_node *an = file->private_data; | ||
1329 | struct ath_softc *sc = an->sc; | ||
1330 | struct ath_atx_tid *tid; | ||
1331 | struct ath_atx_ac *ac; | ||
1332 | struct ath_txq *txq; | ||
1333 | u32 len = 0, size = 4096; | ||
1334 | char *buf; | ||
1335 | size_t retval; | ||
1336 | int tidno, acno; | ||
1337 | |||
1338 | buf = kzalloc(size, GFP_KERNEL); | ||
1339 | if (buf == NULL) | ||
1340 | return -ENOMEM; | ||
1341 | |||
1342 | if (!an->sta->ht_cap.ht_supported) { | ||
1343 | len = scnprintf(buf, size, "%s\n", | ||
1344 | "HT not supported"); | ||
1345 | goto exit; | ||
1346 | } | ||
1347 | |||
1348 | len = scnprintf(buf, size, "Max-AMPDU: %d\n", | ||
1349 | an->maxampdu); | ||
1350 | len += scnprintf(buf + len, size - len, "MPDU Density: %d\n\n", | ||
1351 | an->mpdudensity); | ||
1352 | |||
1353 | len += scnprintf(buf + len, size - len, | ||
1354 | "%2s%7s\n", "AC", "SCHED"); | ||
1355 | |||
1356 | for (acno = 0, ac = &an->ac[acno]; | ||
1357 | acno < IEEE80211_NUM_ACS; acno++, ac++) { | ||
1358 | txq = ac->txq; | ||
1359 | ath_txq_lock(sc, txq); | ||
1360 | len += scnprintf(buf + len, size - len, | ||
1361 | "%2d%7d\n", | ||
1362 | acno, ac->sched); | ||
1363 | ath_txq_unlock(sc, txq); | ||
1364 | } | ||
1365 | |||
1366 | len += scnprintf(buf + len, size - len, | ||
1367 | "\n%3s%11s%10s%10s%10s%10s%9s%6s%8s\n", | ||
1368 | "TID", "SEQ_START", "SEQ_NEXT", "BAW_SIZE", | ||
1369 | "BAW_HEAD", "BAW_TAIL", "BAR_IDX", "SCHED", "PAUSED"); | ||
1370 | |||
1371 | for (tidno = 0, tid = &an->tid[tidno]; | ||
1372 | tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { | ||
1373 | txq = tid->ac->txq; | ||
1374 | ath_txq_lock(sc, txq); | ||
1375 | len += scnprintf(buf + len, size - len, | ||
1376 | "%3d%11d%10d%10d%10d%10d%9d%6d%8d\n", | ||
1377 | tid->tidno, tid->seq_start, tid->seq_next, | ||
1378 | tid->baw_size, tid->baw_head, tid->baw_tail, | ||
1379 | tid->bar_index, tid->sched, tid->paused); | ||
1380 | ath_txq_unlock(sc, txq); | ||
1381 | } | ||
1382 | exit: | ||
1383 | retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
1384 | kfree(buf); | ||
1385 | |||
1386 | return retval; | ||
1387 | } | ||
1388 | |||
1389 | static const struct file_operations fops_node_stat = { | ||
1390 | .read = read_file_node_stat, | ||
1391 | .open = simple_open, | ||
1392 | .owner = THIS_MODULE, | ||
1393 | .llseek = default_llseek, | ||
1394 | }; | ||
1395 | |||
1396 | void ath9k_sta_add_debugfs(struct ieee80211_hw *hw, | ||
1397 | struct ieee80211_vif *vif, | ||
1398 | struct ieee80211_sta *sta, | ||
1399 | struct dentry *dir) | ||
1400 | { | ||
1401 | struct ath_node *an = (struct ath_node *)sta->drv_priv; | ||
1402 | debugfs_create_file("node_stat", S_IRUGO, dir, an, &fops_node_stat); | ||
1403 | } | ||
1404 | |||
1405 | /* Ethtool support for get-stats */ | 1354 | /* Ethtool support for get-stats */ |
1406 | 1355 | ||
1407 | #define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO" | 1356 | #define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO" |
@@ -1569,6 +1518,8 @@ int ath9k_init_debug(struct ath_hw *ah) | |||
1569 | &fops_reset); | 1518 | &fops_reset); |
1570 | debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, sc, | 1519 | debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, sc, |
1571 | &fops_recv); | 1520 | &fops_recv); |
1521 | debugfs_create_file("phy_err", S_IRUSR, sc->debug.debugfs_phy, sc, | ||
1522 | &fops_phy_err); | ||
1572 | debugfs_create_u8("rx_chainmask", S_IRUSR, sc->debug.debugfs_phy, | 1523 | debugfs_create_u8("rx_chainmask", S_IRUSR, sc->debug.debugfs_phy, |
1573 | &ah->rxchainmask); | 1524 | &ah->rxchainmask); |
1574 | debugfs_create_u8("tx_chainmask", S_IRUSR, sc->debug.debugfs_phy, | 1525 | debugfs_create_u8("tx_chainmask", S_IRUSR, sc->debug.debugfs_phy, |
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index ec02d38ea8ea..cc7a025d833e 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
@@ -27,11 +27,13 @@ struct fft_sample_tlv; | |||
27 | 27 | ||
28 | #ifdef CONFIG_ATH9K_DEBUGFS | 28 | #ifdef CONFIG_ATH9K_DEBUGFS |
29 | #define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++ | 29 | #define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++ |
30 | #define RX_STAT_INC(c) (sc->debug.stats.rxstats.c++) | ||
30 | #define RESET_STAT_INC(sc, type) sc->debug.stats.reset[type]++ | 31 | #define RESET_STAT_INC(sc, type) sc->debug.stats.reset[type]++ |
31 | #define ANT_STAT_INC(i, c) sc->debug.stats.ant_stats[i].c++ | 32 | #define ANT_STAT_INC(i, c) sc->debug.stats.ant_stats[i].c++ |
32 | #define ANT_LNA_INC(i, c) sc->debug.stats.ant_stats[i].lna_recv_cnt[c]++; | 33 | #define ANT_LNA_INC(i, c) sc->debug.stats.ant_stats[i].lna_recv_cnt[c]++; |
33 | #else | 34 | #else |
34 | #define TX_STAT_INC(q, c) do { } while (0) | 35 | #define TX_STAT_INC(q, c) do { } while (0) |
36 | #define RX_STAT_INC(c) | ||
35 | #define RESET_STAT_INC(sc, type) do { } while (0) | 37 | #define RESET_STAT_INC(sc, type) do { } while (0) |
36 | #define ANT_STAT_INC(i, c) do { } while (0) | 38 | #define ANT_STAT_INC(i, c) do { } while (0) |
37 | #define ANT_LNA_INC(i, c) do { } while (0) | 39 | #define ANT_LNA_INC(i, c) do { } while (0) |
@@ -42,6 +44,7 @@ enum ath_reset_type { | |||
42 | RESET_TYPE_BB_WATCHDOG, | 44 | RESET_TYPE_BB_WATCHDOG, |
43 | RESET_TYPE_FATAL_INT, | 45 | RESET_TYPE_FATAL_INT, |
44 | RESET_TYPE_TX_ERROR, | 46 | RESET_TYPE_TX_ERROR, |
47 | RESET_TYPE_TX_GTT, | ||
45 | RESET_TYPE_TX_HANG, | 48 | RESET_TYPE_TX_HANG, |
46 | RESET_TYPE_PLL_HANG, | 49 | RESET_TYPE_PLL_HANG, |
47 | RESET_TYPE_MAC_HANG, | 50 | RESET_TYPE_MAC_HANG, |
@@ -201,7 +204,23 @@ struct ath_tx_stats { | |||
201 | TXSTATS[PR_QNUM(IEEE80211_AC_VO)].elem); \ | 204 | TXSTATS[PR_QNUM(IEEE80211_AC_VO)].elem); \ |
202 | } while(0) | 205 | } while(0) |
203 | 206 | ||
204 | #define RX_STAT_INC(c) (sc->debug.stats.rxstats.c++) | 207 | struct ath_rx_rate_stats { |
208 | struct { | ||
209 | u32 ht20_cnt; | ||
210 | u32 ht40_cnt; | ||
211 | u32 sgi_cnt; | ||
212 | u32 lgi_cnt; | ||
213 | } ht_stats[24]; | ||
214 | |||
215 | struct { | ||
216 | u32 ofdm_cnt; | ||
217 | } ofdm_stats[8]; | ||
218 | |||
219 | struct { | ||
220 | u32 cck_lp_cnt; | ||
221 | u32 cck_sp_cnt; | ||
222 | } cck_stats[4]; | ||
223 | }; | ||
205 | 224 | ||
206 | /** | 225 | /** |
207 | * struct ath_rx_stats - RX Statistics | 226 | * struct ath_rx_stats - RX Statistics |
@@ -299,8 +318,6 @@ void ath9k_debug_sync_cause(struct ath_softc *sc, u32 sync_cause); | |||
299 | 318 | ||
300 | #else | 319 | #else |
301 | 320 | ||
302 | #define RX_STAT_INC(c) /* NOP */ | ||
303 | |||
304 | static inline int ath9k_init_debug(struct ath_hw *ah) | 321 | static inline int ath9k_init_debug(struct ath_hw *ah) |
305 | { | 322 | { |
306 | return 0; | 323 | return 0; |
@@ -338,4 +355,16 @@ ath9k_debug_sync_cause(struct ath_softc *sc, u32 sync_cause) | |||
338 | 355 | ||
339 | #endif /* CONFIG_ATH9K_DEBUGFS */ | 356 | #endif /* CONFIG_ATH9K_DEBUGFS */ |
340 | 357 | ||
358 | #ifdef CONFIG_ATH9K_STATION_STATISTICS | ||
359 | void ath_debug_rate_stats(struct ath_softc *sc, | ||
360 | struct ath_rx_status *rs, | ||
361 | struct sk_buff *skb); | ||
362 | #else | ||
363 | static inline void ath_debug_rate_stats(struct ath_softc *sc, | ||
364 | struct ath_rx_status *rs, | ||
365 | struct sk_buff *skb) | ||
366 | { | ||
367 | } | ||
368 | #endif /* CONFIG_ATH9K_STATION_STATISTICS */ | ||
369 | |||
341 | #endif /* DEBUG_H */ | 370 | #endif /* DEBUG_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/debug_sta.c b/drivers/net/wireless/ath/ath9k/debug_sta.c new file mode 100644 index 000000000000..d76e6e0120d2 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/debug_sta.c | |||
@@ -0,0 +1,269 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2013 Qualcomm Atheros, 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 | /* node_aggr */ | ||
21 | /*************/ | ||
22 | |||
23 | static ssize_t read_file_node_aggr(struct file *file, char __user *user_buf, | ||
24 | size_t count, loff_t *ppos) | ||
25 | { | ||
26 | struct ath_node *an = file->private_data; | ||
27 | struct ath_softc *sc = an->sc; | ||
28 | struct ath_atx_tid *tid; | ||
29 | struct ath_atx_ac *ac; | ||
30 | struct ath_txq *txq; | ||
31 | u32 len = 0, size = 4096; | ||
32 | char *buf; | ||
33 | size_t retval; | ||
34 | int tidno, acno; | ||
35 | |||
36 | buf = kzalloc(size, GFP_KERNEL); | ||
37 | if (buf == NULL) | ||
38 | return -ENOMEM; | ||
39 | |||
40 | if (!an->sta->ht_cap.ht_supported) { | ||
41 | len = scnprintf(buf, size, "%s\n", | ||
42 | "HT not supported"); | ||
43 | goto exit; | ||
44 | } | ||
45 | |||
46 | len = scnprintf(buf, size, "Max-AMPDU: %d\n", | ||
47 | an->maxampdu); | ||
48 | len += scnprintf(buf + len, size - len, "MPDU Density: %d\n\n", | ||
49 | an->mpdudensity); | ||
50 | |||
51 | len += scnprintf(buf + len, size - len, | ||
52 | "%2s%7s\n", "AC", "SCHED"); | ||
53 | |||
54 | for (acno = 0, ac = &an->ac[acno]; | ||
55 | acno < IEEE80211_NUM_ACS; acno++, ac++) { | ||
56 | txq = ac->txq; | ||
57 | ath_txq_lock(sc, txq); | ||
58 | len += scnprintf(buf + len, size - len, | ||
59 | "%2d%7d\n", | ||
60 | acno, ac->sched); | ||
61 | ath_txq_unlock(sc, txq); | ||
62 | } | ||
63 | |||
64 | len += scnprintf(buf + len, size - len, | ||
65 | "\n%3s%11s%10s%10s%10s%10s%9s%6s%8s\n", | ||
66 | "TID", "SEQ_START", "SEQ_NEXT", "BAW_SIZE", | ||
67 | "BAW_HEAD", "BAW_TAIL", "BAR_IDX", "SCHED", "PAUSED"); | ||
68 | |||
69 | for (tidno = 0, tid = &an->tid[tidno]; | ||
70 | tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { | ||
71 | txq = tid->ac->txq; | ||
72 | ath_txq_lock(sc, txq); | ||
73 | if (tid->active) { | ||
74 | len += scnprintf(buf + len, size - len, | ||
75 | "%3d%11d%10d%10d%10d%10d%9d%6d%8d\n", | ||
76 | tid->tidno, | ||
77 | tid->seq_start, | ||
78 | tid->seq_next, | ||
79 | tid->baw_size, | ||
80 | tid->baw_head, | ||
81 | tid->baw_tail, | ||
82 | tid->bar_index, | ||
83 | tid->sched, | ||
84 | tid->paused); | ||
85 | } | ||
86 | ath_txq_unlock(sc, txq); | ||
87 | } | ||
88 | exit: | ||
89 | retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
90 | kfree(buf); | ||
91 | |||
92 | return retval; | ||
93 | } | ||
94 | |||
95 | static const struct file_operations fops_node_aggr = { | ||
96 | .read = read_file_node_aggr, | ||
97 | .open = simple_open, | ||
98 | .owner = THIS_MODULE, | ||
99 | .llseek = default_llseek, | ||
100 | }; | ||
101 | |||
102 | /*************/ | ||
103 | /* node_recv */ | ||
104 | /*************/ | ||
105 | |||
106 | void ath_debug_rate_stats(struct ath_softc *sc, | ||
107 | struct ath_rx_status *rs, | ||
108 | struct sk_buff *skb) | ||
109 | { | ||
110 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
111 | struct ath_hw *ah = sc->sc_ah; | ||
112 | struct ieee80211_rx_status *rxs; | ||
113 | struct ath_rx_rate_stats *rstats; | ||
114 | struct ieee80211_sta *sta; | ||
115 | struct ath_node *an; | ||
116 | |||
117 | if (!ieee80211_is_data(hdr->frame_control)) | ||
118 | return; | ||
119 | |||
120 | rcu_read_lock(); | ||
121 | |||
122 | sta = ieee80211_find_sta_by_ifaddr(sc->hw, hdr->addr2, NULL); | ||
123 | if (!sta) | ||
124 | goto exit; | ||
125 | |||
126 | an = (struct ath_node *) sta->drv_priv; | ||
127 | rstats = &an->rx_rate_stats; | ||
128 | rxs = IEEE80211_SKB_RXCB(skb); | ||
129 | |||
130 | if (IS_HT_RATE(rs->rs_rate)) { | ||
131 | if (rxs->rate_idx >= ARRAY_SIZE(rstats->ht_stats)) | ||
132 | goto exit; | ||
133 | |||
134 | if (rxs->flag & RX_FLAG_40MHZ) | ||
135 | rstats->ht_stats[rxs->rate_idx].ht40_cnt++; | ||
136 | else | ||
137 | rstats->ht_stats[rxs->rate_idx].ht20_cnt++; | ||
138 | |||
139 | if (rxs->flag & RX_FLAG_SHORT_GI) | ||
140 | rstats->ht_stats[rxs->rate_idx].sgi_cnt++; | ||
141 | else | ||
142 | rstats->ht_stats[rxs->rate_idx].lgi_cnt++; | ||
143 | |||
144 | goto exit; | ||
145 | } | ||
146 | |||
147 | if (IS_CCK_RATE(rs->rs_rate)) { | ||
148 | if (rxs->flag & RX_FLAG_SHORTPRE) | ||
149 | rstats->cck_stats[rxs->rate_idx].cck_sp_cnt++; | ||
150 | else | ||
151 | rstats->cck_stats[rxs->rate_idx].cck_lp_cnt++; | ||
152 | |||
153 | goto exit; | ||
154 | } | ||
155 | |||
156 | if (IS_OFDM_RATE(rs->rs_rate)) { | ||
157 | if (ah->curchan->chan->band == IEEE80211_BAND_2GHZ) | ||
158 | rstats->ofdm_stats[rxs->rate_idx - 4].ofdm_cnt++; | ||
159 | else | ||
160 | rstats->ofdm_stats[rxs->rate_idx].ofdm_cnt++; | ||
161 | } | ||
162 | exit: | ||
163 | rcu_read_unlock(); | ||
164 | } | ||
165 | |||
166 | #define PRINT_CCK_RATE(str, i, sp) \ | ||
167 | do { \ | ||
168 | len += scnprintf(buf + len, size - len, \ | ||
169 | "%11s : %10u\n", \ | ||
170 | str, \ | ||
171 | (sp) ? rstats->cck_stats[i].cck_sp_cnt : \ | ||
172 | rstats->cck_stats[i].cck_lp_cnt); \ | ||
173 | } while (0) | ||
174 | |||
175 | #define PRINT_OFDM_RATE(str, i) \ | ||
176 | do { \ | ||
177 | len += scnprintf(buf + len, size - len, \ | ||
178 | "%11s : %10u\n", \ | ||
179 | str, \ | ||
180 | rstats->ofdm_stats[i].ofdm_cnt); \ | ||
181 | } while (0) | ||
182 | |||
183 | static ssize_t read_file_node_recv(struct file *file, char __user *user_buf, | ||
184 | size_t count, loff_t *ppos) | ||
185 | { | ||
186 | struct ath_node *an = file->private_data; | ||
187 | struct ath_softc *sc = an->sc; | ||
188 | struct ath_hw *ah = sc->sc_ah; | ||
189 | struct ath_rx_rate_stats *rstats; | ||
190 | struct ieee80211_sta *sta = an->sta; | ||
191 | enum ieee80211_band band; | ||
192 | u32 len = 0, size = 4096; | ||
193 | char *buf; | ||
194 | size_t retval; | ||
195 | int i; | ||
196 | |||
197 | buf = kzalloc(size, GFP_KERNEL); | ||
198 | if (buf == NULL) | ||
199 | return -ENOMEM; | ||
200 | |||
201 | band = ah->curchan->chan->band; | ||
202 | rstats = &an->rx_rate_stats; | ||
203 | |||
204 | if (!sta->ht_cap.ht_supported) | ||
205 | goto legacy; | ||
206 | |||
207 | len += scnprintf(buf + len, size - len, | ||
208 | "%24s%10s%10s%10s\n", | ||
209 | "HT20", "HT40", "SGI", "LGI"); | ||
210 | |||
211 | for (i = 0; i < 24; i++) { | ||
212 | len += scnprintf(buf + len, size - len, | ||
213 | "%8s%3u : %10u%10u%10u%10u\n", | ||
214 | "MCS", i, | ||
215 | rstats->ht_stats[i].ht20_cnt, | ||
216 | rstats->ht_stats[i].ht40_cnt, | ||
217 | rstats->ht_stats[i].sgi_cnt, | ||
218 | rstats->ht_stats[i].lgi_cnt); | ||
219 | } | ||
220 | |||
221 | len += scnprintf(buf + len, size - len, "\n"); | ||
222 | |||
223 | legacy: | ||
224 | if (band == IEEE80211_BAND_2GHZ) { | ||
225 | PRINT_CCK_RATE("CCK-1M/LP", 0, false); | ||
226 | PRINT_CCK_RATE("CCK-2M/LP", 1, false); | ||
227 | PRINT_CCK_RATE("CCK-5.5M/LP", 2, false); | ||
228 | PRINT_CCK_RATE("CCK-11M/LP", 3, false); | ||
229 | |||
230 | PRINT_CCK_RATE("CCK-2M/SP", 1, true); | ||
231 | PRINT_CCK_RATE("CCK-5.5M/SP", 2, true); | ||
232 | PRINT_CCK_RATE("CCK-11M/SP", 3, true); | ||
233 | } | ||
234 | |||
235 | PRINT_OFDM_RATE("OFDM-6M", 0); | ||
236 | PRINT_OFDM_RATE("OFDM-9M", 1); | ||
237 | PRINT_OFDM_RATE("OFDM-12M", 2); | ||
238 | PRINT_OFDM_RATE("OFDM-18M", 3); | ||
239 | PRINT_OFDM_RATE("OFDM-24M", 4); | ||
240 | PRINT_OFDM_RATE("OFDM-36M", 5); | ||
241 | PRINT_OFDM_RATE("OFDM-48M", 6); | ||
242 | PRINT_OFDM_RATE("OFDM-54M", 7); | ||
243 | |||
244 | retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
245 | kfree(buf); | ||
246 | |||
247 | return retval; | ||
248 | } | ||
249 | |||
250 | #undef PRINT_OFDM_RATE | ||
251 | #undef PRINT_CCK_RATE | ||
252 | |||
253 | static const struct file_operations fops_node_recv = { | ||
254 | .read = read_file_node_recv, | ||
255 | .open = simple_open, | ||
256 | .owner = THIS_MODULE, | ||
257 | .llseek = default_llseek, | ||
258 | }; | ||
259 | |||
260 | void ath9k_sta_add_debugfs(struct ieee80211_hw *hw, | ||
261 | struct ieee80211_vif *vif, | ||
262 | struct ieee80211_sta *sta, | ||
263 | struct dentry *dir) | ||
264 | { | ||
265 | struct ath_node *an = (struct ath_node *)sta->drv_priv; | ||
266 | |||
267 | debugfs_create_file("node_aggr", S_IRUGO, dir, an, &fops_node_aggr); | ||
268 | debugfs_create_file("node_recv", S_IRUGO, dir, an, &fops_node_recv); | ||
269 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index b576c44bb314..f4e1de20d99c 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -748,7 +748,6 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, | |||
748 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; | 748 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; |
749 | 749 | ||
750 | hw->queues = 4; | 750 | hw->queues = 4; |
751 | hw->channel_change_time = 5000; | ||
752 | hw->max_listen_interval = 1; | 751 | hw->max_listen_interval = 1; |
753 | 752 | ||
754 | hw->vif_data_size = sizeof(struct ath9k_htc_vif); | 753 | hw->vif_data_size = sizeof(struct ath9k_htc_vif); |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index b41e008298dc..12e0f32a4905 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | |||
@@ -1075,9 +1075,7 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, | |||
1075 | 1075 | ||
1076 | last_rssi = priv->rx.last_rssi; | 1076 | last_rssi = priv->rx.last_rssi; |
1077 | 1077 | ||
1078 | if (ieee80211_is_beacon(hdr->frame_control) && | 1078 | if (ath_is_mybeacon(common, hdr)) { |
1079 | !is_zero_ether_addr(common->curbssid) && | ||
1080 | ether_addr_equal_64bits(hdr->addr3, common->curbssid)) { | ||
1081 | s8 rssi = rxbuf->rxstatus.rs_rssi; | 1079 | s8 rssi = rxbuf->rxstatus.rs_rssi; |
1082 | 1080 | ||
1083 | if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) | 1081 | if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index f2a17fcf1ae4..c36de303c8f3 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -946,7 +946,6 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
946 | 946 | ||
947 | hw->queues = 4; | 947 | hw->queues = 4; |
948 | hw->max_rates = 4; | 948 | hw->max_rates = 4; |
949 | hw->channel_change_time = 5000; | ||
950 | hw->max_listen_interval = 1; | 949 | hw->max_listen_interval = 1; |
951 | hw->max_rate_tries = 10; | 950 | hw->max_rate_tries = 10; |
952 | hw->sta_data_size = sizeof(struct ath_node); | 951 | hw->sta_data_size = sizeof(struct ath_node); |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index d0c3aec7c74e..73a36551a5ed 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -258,6 +258,7 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) | |||
258 | } | 258 | } |
259 | } | 259 | } |
260 | 260 | ||
261 | sc->gtt_cnt = 0; | ||
261 | ieee80211_wake_queues(sc->hw); | 262 | ieee80211_wake_queues(sc->hw); |
262 | 263 | ||
263 | return true; | 264 | return true; |
@@ -476,6 +477,19 @@ void ath9k_tasklet(unsigned long data) | |||
476 | } | 477 | } |
477 | } | 478 | } |
478 | 479 | ||
480 | if (status & ATH9K_INT_GTT) { | ||
481 | sc->gtt_cnt++; | ||
482 | |||
483 | if ((sc->gtt_cnt >= MAX_GTT_CNT) && !ath9k_hw_check_alive(ah)) { | ||
484 | type = RESET_TYPE_TX_GTT; | ||
485 | ath9k_queue_reset(sc, type); | ||
486 | atomic_inc(&ah->intr_ref_cnt); | ||
487 | ath_dbg(common, ANY, | ||
488 | "GTT: Skipping interrupts\n"); | ||
489 | goto out; | ||
490 | } | ||
491 | } | ||
492 | |||
479 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | 493 | spin_lock_irqsave(&sc->sc_pm_lock, flags); |
480 | if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) { | 494 | if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) { |
481 | /* | 495 | /* |
@@ -503,10 +517,19 @@ void ath9k_tasklet(unsigned long data) | |||
503 | } | 517 | } |
504 | 518 | ||
505 | if (status & ATH9K_INT_TX) { | 519 | if (status & ATH9K_INT_TX) { |
506 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | 520 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { |
521 | /* | ||
522 | * For EDMA chips, TX completion is enabled for the | ||
523 | * beacon queue, so if a beacon has been transmitted | ||
524 | * successfully after a GTT interrupt, the GTT counter | ||
525 | * gets reset to zero here. | ||
526 | */ | ||
527 | /* sc->gtt_cnt = 0; */ | ||
528 | |||
507 | ath_tx_edma_tasklet(sc); | 529 | ath_tx_edma_tasklet(sc); |
508 | else | 530 | } else { |
509 | ath_tx_tasklet(sc); | 531 | ath_tx_tasklet(sc); |
532 | } | ||
510 | 533 | ||
511 | wake_up(&sc->tx_wait); | 534 | wake_up(&sc->tx_wait); |
512 | } | 535 | } |
@@ -536,13 +559,13 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
536 | ATH9K_INT_TX | \ | 559 | ATH9K_INT_TX | \ |
537 | ATH9K_INT_BMISS | \ | 560 | ATH9K_INT_BMISS | \ |
538 | ATH9K_INT_CST | \ | 561 | ATH9K_INT_CST | \ |
562 | ATH9K_INT_GTT | \ | ||
539 | ATH9K_INT_TSFOOR | \ | 563 | ATH9K_INT_TSFOOR | \ |
540 | ATH9K_INT_GENTIMER | \ | 564 | ATH9K_INT_GENTIMER | \ |
541 | ATH9K_INT_MCI) | 565 | ATH9K_INT_MCI) |
542 | 566 | ||
543 | struct ath_softc *sc = dev; | 567 | struct ath_softc *sc = dev; |
544 | struct ath_hw *ah = sc->sc_ah; | 568 | struct ath_hw *ah = sc->sc_ah; |
545 | struct ath_common *common = ath9k_hw_common(ah); | ||
546 | enum ath9k_int status; | 569 | enum ath9k_int status; |
547 | u32 sync_cause = 0; | 570 | u32 sync_cause = 0; |
548 | bool sched = false; | 571 | bool sched = false; |
@@ -603,14 +626,12 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
603 | #ifdef CONFIG_ATH9K_WOW | 626 | #ifdef CONFIG_ATH9K_WOW |
604 | if (status & ATH9K_INT_BMISS) { | 627 | if (status & ATH9K_INT_BMISS) { |
605 | if (atomic_read(&sc->wow_sleep_proc_intr) == 0) { | 628 | if (atomic_read(&sc->wow_sleep_proc_intr) == 0) { |
606 | ath_dbg(common, ANY, "during WoW we got a BMISS\n"); | ||
607 | atomic_inc(&sc->wow_got_bmiss_intr); | 629 | atomic_inc(&sc->wow_got_bmiss_intr); |
608 | atomic_dec(&sc->wow_sleep_proc_intr); | 630 | atomic_dec(&sc->wow_sleep_proc_intr); |
609 | } | 631 | } |
610 | } | 632 | } |
611 | #endif | 633 | #endif |
612 | 634 | ||
613 | |||
614 | if (status & ATH9K_INT_SWBA) | 635 | if (status & ATH9K_INT_SWBA) |
615 | tasklet_schedule(&sc->bcon_tasklet); | 636 | tasklet_schedule(&sc->bcon_tasklet); |
616 | 637 | ||
@@ -735,7 +756,12 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
735 | if (ah->config.hw_hang_checks & HW_BB_WATCHDOG) | 756 | if (ah->config.hw_hang_checks & HW_BB_WATCHDOG) |
736 | ah->imask |= ATH9K_INT_BB_WATCHDOG; | 757 | ah->imask |= ATH9K_INT_BB_WATCHDOG; |
737 | 758 | ||
738 | ah->imask |= ATH9K_INT_GTT; | 759 | /* |
760 | * Enable GTT interrupts only for AR9003/AR9004 chips | ||
761 | * for now. | ||
762 | */ | ||
763 | if (AR_SREV_9300_20_OR_LATER(ah)) | ||
764 | ah->imask |= ATH9K_INT_GTT; | ||
739 | 765 | ||
740 | if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) | 766 | if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) |
741 | ah->imask |= ATH9K_INT_CST; | 767 | ah->imask |= ATH9K_INT_CST; |
@@ -2111,7 +2137,7 @@ struct ieee80211_ops ath9k_ops = { | |||
2111 | .get_et_strings = ath9k_get_et_strings, | 2137 | .get_et_strings = ath9k_get_et_strings, |
2112 | #endif | 2138 | #endif |
2113 | 2139 | ||
2114 | #if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS) | 2140 | #if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_STATION_STATISTICS) |
2115 | .sta_add_debugfs = ath9k_sta_add_debugfs, | 2141 | .sta_add_debugfs = ath9k_sta_add_debugfs, |
2116 | #endif | 2142 | #endif |
2117 | .sw_scan_start = ath9k_sw_scan_start, | 2143 | .sw_scan_start = ath9k_sw_scan_start, |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index f7cc5b37a18f..a0ebdd000fc2 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -969,21 +969,6 @@ static void ath9k_process_tsf(struct ath_rx_status *rs, | |||
969 | rxs->mactime += 0x100000000ULL; | 969 | rxs->mactime += 0x100000000ULL; |
970 | } | 970 | } |
971 | 971 | ||
972 | static bool ath9k_is_mybeacon(struct ath_softc *sc, struct ieee80211_hdr *hdr) | ||
973 | { | ||
974 | struct ath_hw *ah = sc->sc_ah; | ||
975 | struct ath_common *common = ath9k_hw_common(ah); | ||
976 | |||
977 | if (ieee80211_is_beacon(hdr->frame_control)) { | ||
978 | RX_STAT_INC(rx_beacons); | ||
979 | if (!is_zero_ether_addr(common->curbssid) && | ||
980 | ether_addr_equal_64bits(hdr->addr3, common->curbssid)) | ||
981 | return true; | ||
982 | } | ||
983 | |||
984 | return false; | ||
985 | } | ||
986 | |||
987 | /* | 972 | /* |
988 | * For Decrypt or Demic errors, we only mark packet status here and always push | 973 | * For Decrypt or Demic errors, we only mark packet status here and always push |
989 | * up the frame up to let mac80211 handle the actual error case, be it no | 974 | * up the frame up to let mac80211 handle the actual error case, be it no |
@@ -1071,7 +1056,10 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
1071 | goto exit; | 1056 | goto exit; |
1072 | } | 1057 | } |
1073 | 1058 | ||
1074 | rx_stats->is_mybeacon = ath9k_is_mybeacon(sc, hdr); | 1059 | if (ath_is_mybeacon(common, hdr)) { |
1060 | RX_STAT_INC(rx_beacons); | ||
1061 | rx_stats->is_mybeacon = true; | ||
1062 | } | ||
1075 | 1063 | ||
1076 | /* | 1064 | /* |
1077 | * This shouldn't happen, but have a safety check anyway. | 1065 | * This shouldn't happen, but have a safety check anyway. |
@@ -1354,8 +1342,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1354 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | 1342 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); |
1355 | 1343 | ||
1356 | ath9k_antenna_check(sc, &rs); | 1344 | ath9k_antenna_check(sc, &rs); |
1357 | |||
1358 | ath9k_apply_ampdu_details(sc, &rs, rxs); | 1345 | ath9k_apply_ampdu_details(sc, &rs, rxs); |
1346 | ath_debug_rate_stats(sc, &rs, skb); | ||
1359 | 1347 | ||
1360 | ieee80211_rx(hw, skb); | 1348 | ieee80211_rx(hw, skb); |
1361 | 1349 | ||
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index e8d0e7fc77da..0a75e2f68c9d 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -47,8 +47,6 @@ static u16 bits_per_symbol[][2] = { | |||
47 | { 260, 540 }, /* 7: 64-QAM 5/6 */ | 47 | { 260, 540 }, /* 7: 64-QAM 5/6 */ |
48 | }; | 48 | }; |
49 | 49 | ||
50 | #define IS_HT_RATE(_rate) ((_rate) & 0x80) | ||
51 | |||
52 | static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, | 50 | static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, |
53 | struct ath_atx_tid *tid, struct sk_buff *skb); | 51 | struct ath_atx_tid *tid, struct sk_buff *skb); |
54 | static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | 52 | static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, |
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 4c3f576c3144..4c8cdb097b65 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c | |||
@@ -1967,18 +1967,6 @@ static int carl9170_parse_eeprom(struct ar9170 *ar) | |||
1967 | return -ENOMEM; | 1967 | return -ENOMEM; |
1968 | ar->num_channels = chans; | 1968 | ar->num_channels = chans; |
1969 | 1969 | ||
1970 | /* | ||
1971 | * I measured this, a bandswitch takes roughly | ||
1972 | * 135 ms and a frequency switch about 80. | ||
1973 | * | ||
1974 | * FIXME: measure these values again once EEPROM settings | ||
1975 | * are used, that will influence them! | ||
1976 | */ | ||
1977 | if (bands == 2) | ||
1978 | ar->hw->channel_change_time = 135 * 1000; | ||
1979 | else | ||
1980 | ar->hw->channel_change_time = 80 * 1000; | ||
1981 | |||
1982 | regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]); | 1970 | regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]); |
1983 | 1971 | ||
1984 | /* second part of wiphy init */ | 1972 | /* second part of wiphy init */ |
diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c index 1b1b20751ead..536bc46a2912 100644 --- a/drivers/net/wireless/ath/carl9170/rx.c +++ b/drivers/net/wireless/ath/carl9170/rx.c | |||
@@ -519,6 +519,7 @@ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len) | |||
519 | { | 519 | { |
520 | struct ieee80211_hdr *hdr = data; | 520 | struct ieee80211_hdr *hdr = data; |
521 | struct ieee80211_tim_ie *tim_ie; | 521 | struct ieee80211_tim_ie *tim_ie; |
522 | struct ath_common *common = &ar->common; | ||
522 | u8 *tim; | 523 | u8 *tim; |
523 | u8 tim_len; | 524 | u8 tim_len; |
524 | bool cam; | 525 | bool cam; |
@@ -526,17 +527,13 @@ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len) | |||
526 | if (likely(!(ar->hw->conf.flags & IEEE80211_CONF_PS))) | 527 | if (likely(!(ar->hw->conf.flags & IEEE80211_CONF_PS))) |
527 | return; | 528 | return; |
528 | 529 | ||
529 | /* check if this really is a beacon */ | ||
530 | if (!ieee80211_is_beacon(hdr->frame_control)) | ||
531 | return; | ||
532 | |||
533 | /* min. beacon length + FCS_LEN */ | 530 | /* min. beacon length + FCS_LEN */ |
534 | if (len <= 40 + FCS_LEN) | 531 | if (len <= 40 + FCS_LEN) |
535 | return; | 532 | return; |
536 | 533 | ||
534 | /* check if this really is a beacon */ | ||
537 | /* and only beacons from the associated BSSID, please */ | 535 | /* and only beacons from the associated BSSID, please */ |
538 | if (!ether_addr_equal_64bits(hdr->addr3, ar->common.curbssid) || | 536 | if (!ath_is_mybeacon(common, hdr) || !common->curaid) |
539 | !ar->common.curaid) | ||
540 | return; | 537 | return; |
541 | 538 | ||
542 | ar->ps.last_beacon = jiffies; | 539 | ar->ps.last_beacon = jiffies; |
diff --git a/drivers/net/wireless/ath/main.c b/drivers/net/wireless/ath/main.c index 8e99540cd90e..8b0ac14d5c32 100644 --- a/drivers/net/wireless/ath/main.c +++ b/drivers/net/wireless/ath/main.c | |||
@@ -59,6 +59,14 @@ struct sk_buff *ath_rxbuf_alloc(struct ath_common *common, | |||
59 | } | 59 | } |
60 | EXPORT_SYMBOL(ath_rxbuf_alloc); | 60 | EXPORT_SYMBOL(ath_rxbuf_alloc); |
61 | 61 | ||
62 | bool ath_is_mybeacon(struct ath_common *common, struct ieee80211_hdr *hdr) | ||
63 | { | ||
64 | return ieee80211_is_beacon(hdr->frame_control) && | ||
65 | !is_zero_ether_addr(common->curbssid) && | ||
66 | ether_addr_equal_64bits(hdr->addr3, common->curbssid); | ||
67 | } | ||
68 | EXPORT_SYMBOL(ath_is_mybeacon); | ||
69 | |||
62 | void ath_printk(const char *level, const struct ath_common* common, | 70 | void ath_printk(const char *level, const struct ath_common* common, |
63 | const char *fmt, ...) | 71 | const char *fmt, ...) |
64 | { | 72 | { |
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 9e154732afaa..e5e905910db4 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c | |||
@@ -632,7 +632,8 @@ ath_regd_init_wiphy(struct ath_regulatory *reg, | |||
632 | const struct ieee80211_regdomain *regd; | 632 | const struct ieee80211_regdomain *regd; |
633 | 633 | ||
634 | wiphy->reg_notifier = reg_notifier; | 634 | wiphy->reg_notifier = reg_notifier; |
635 | wiphy->regulatory_flags |= REGULATORY_STRICT_REG; | 635 | wiphy->regulatory_flags |= REGULATORY_STRICT_REG | |
636 | REGULATORY_CUSTOM_REG; | ||
636 | 637 | ||
637 | if (ath_is_world_regd(reg)) { | 638 | if (ath_is_world_regd(reg)) { |
638 | /* | 639 | /* |
@@ -640,8 +641,7 @@ ath_regd_init_wiphy(struct ath_regulatory *reg, | |||
640 | * saved on the wiphy orig_* parameters | 641 | * saved on the wiphy orig_* parameters |
641 | */ | 642 | */ |
642 | regd = ath_world_regdomain(reg); | 643 | regd = ath_world_regdomain(reg); |
643 | wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG | | 644 | wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_FOLLOW_POWER; |
644 | REGULATORY_COUNTRY_IE_FOLLOW_POWER; | ||
645 | } else { | 645 | } else { |
646 | /* | 646 | /* |
647 | * This gets applied in the case of the absence of CRDA, | 647 | * This gets applied in the case of the absence of CRDA, |
@@ -650,6 +650,7 @@ ath_regd_init_wiphy(struct ath_regulatory *reg, | |||
650 | */ | 650 | */ |
651 | regd = ath_default_world_regdomain(); | 651 | regd = ath_default_world_regdomain(); |
652 | } | 652 | } |
653 | |||
653 | wiphy_apply_custom_regulatory(wiphy, regd); | 654 | wiphy_apply_custom_regulatory(wiphy, regd); |
654 | ath_reg_apply_radar_flags(wiphy); | 655 | ath_reg_apply_radar_flags(wiphy); |
655 | ath_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg); | 656 | ath_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg); |
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index 9b88440ef05b..0b0975d88b43 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <linux/ip.h> | 21 | #include <linux/ip.h> |
22 | #include <linux/ipv6.h> | 22 | #include <linux/ipv6.h> |
23 | #include <net/ipv6.h> | 23 | #include <net/ipv6.h> |
24 | #include <asm/processor.h> | 24 | #include <linux/prefetch.h> |
25 | 25 | ||
26 | #include "wil6210.h" | 26 | #include "wil6210.h" |
27 | #include "wmi.h" | 27 | #include "wmi.h" |