aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/ath.h2
-rw-r--r--drivers/net/wireless/ath/ath10k/Kconfig7
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h11
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.c66
-rw-r--r--drivers/net/wireless/ath/ath10k/htt.h1
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c15
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.h1
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c375
-rw-r--r--drivers/net/wireless/ath/ath10k/trace.h21
-rw-r--r--drivers/net/wireless/ath/ath10k/txrx.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c106
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.h61
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c34
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig8
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_calib.c19
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h10
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c197
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h35
-rw-r--r--drivers/net/wireless/ath/ath9k/debug_sta.c269
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c40
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c22
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c2
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c12
-rw-r--r--drivers/net/wireless/ath/carl9170/rx.c9
-rw-r--r--drivers/net/wireless/ath/main.c8
-rw-r--r--drivers/net/wireless/ath/regd.c7
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c2
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 {
165struct sk_buff *ath_rxbuf_alloc(struct ath_common *common, 166struct 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);
169bool ath_is_mybeacon(struct ath_common *common, struct ieee80211_hdr *hdr);
168 170
169void ath_hw_setbssidmask(struct ath_common *common); 171void ath_hw_setbssidmask(struct ath_common *common);
170void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key); 172void 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
40config 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
258struct ath10k_vif_iter { 261struct 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
277enum ath10k_state { 282enum 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
617static 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
631static 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
658exit:
659 mutex_unlock(&ar->conf_mutex);
660
661 return ret;
662}
663
664static 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
617int ath10k_debug_start(struct ath10k *ar) 672int 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
1188struct ath10k_htt { 1189struct 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
841static 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
841static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb) 855static 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 2936exit:
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 */
3343static 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 */
3361static 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
3376static bool
3377ath10k_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
3410static bool
3411ath10k_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
3458static bool
3459ath10k_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
3496static bool
3497ath10k_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
3563static 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
3576static 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
3618exit:
3619 mutex_unlock(&ar->conf_mutex);
3620 return ret;
3621}
3622
3623static 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
3313static const struct ieee80211_ops ath10k_ops = { 3643static 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 3798static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
3468static 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
3476static const struct ieee80211_iface_combination ath10k_if_comb[] = { 3805static 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
3815static 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
3499static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar) 3831static 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
185TRACE_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
1050static void ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb) 1074static 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
1055static void ath10k_wmi_event_update_stats(struct ath10k *ar, 1084static 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
1655static void ath10k_wmi_event_debug_print(struct ath10k *ar, 1684static 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
1661static void ath10k_wmi_event_pdev_qvit(struct ath10k *ar, struct sk_buff *skb) 1718static 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
3506int 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 */
3007enum wmi_rate_preamble { 3019enum 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
4105enum 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 */
4139struct 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);
4167int ath10k_wmi_force_fw_hang(struct ath10k *ar, 4227int 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);
4169int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb); 4229int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb);
4230int 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
1238ath5k_check_ibss_tsf(struct ath5k_hw *ah, struct sk_buff *skb, 1238ath5k_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
1304static void
1305ath5k_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
68config 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
68config ATH9K_DFS_CERTIFIED 76config 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
19ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o \ 19ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o \
20 spectral.o 20 spectral.o
21 21
22ath9k-$(CONFIG_ATH9K_STATION_STATISTICS) += debug_sta.o
23
22obj-$(CONFIG_ATH9K) += ath9k.o 24obj-$(CONFIG_ATH9K) += ath9k.o
23 25
24ath9k_hw-y:= \ 26ath9k_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
151struct ath_txq { 153struct 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
267struct ath_tx_control { 273struct 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
689enum sc_op_flags { 696enum 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 = {
943static ssize_t read_file_recv(struct file *file, char __user *user_buf, 943static 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
1023void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) 991void 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
1027static 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
1081static 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
1059static ssize_t read_file_regidx(struct file *file, char __user *user_buf, 1088static 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
1325static 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 }
1382exit:
1383 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1384 kfree(buf);
1385
1386 return retval;
1387}
1388
1389static 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
1396void 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++) 207struct 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
304static inline int ath9k_init_debug(struct ath_hw *ah) 321static 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
359void ath_debug_rate_stats(struct ath_softc *sc,
360 struct ath_rx_status *rs,
361 struct sk_buff *skb);
362#else
363static 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
23static 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 }
88exit:
89 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
90 kfree(buf);
91
92 return retval;
93}
94
95static 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
106void 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 }
162exit:
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
183static 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
223legacy:
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
253static 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
260void 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
972static 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
52static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, 50static 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);
54static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, 52static 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}
60EXPORT_SYMBOL(ath_rxbuf_alloc); 60EXPORT_SYMBOL(ath_rxbuf_alloc);
61 61
62bool 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}
68EXPORT_SYMBOL(ath_is_mybeacon);
69
62void ath_printk(const char *level, const struct ath_common* common, 70void 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"