diff options
author | John W. Linville <linville@tuxdriver.com> | 2014-01-13 14:40:03 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-01-13 14:40:03 -0500 |
commit | 559c33d84da71e07816e692bfd73ad92675256a6 (patch) | |
tree | d599948e9c88f115cf697b2a52f0359b3ecd77d4 /drivers/net | |
parent | ec665facde820179d71d0f064e692f449df2b94f (diff) | |
parent | 51ab1a0a09a894442e8b091d57222c5425b6d700 (diff) |
Merge branch 'for-linville' of git://github.com/kvalo/ath
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/ath/ath10k/Kconfig | 7 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/core.h | 11 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/debug.c | 66 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/htt.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/htt_rx.c | 15 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/hw.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/mac.c | 374 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/trace.h | 21 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/txrx.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/wmi.c | 106 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/wmi.h | 61 |
11 files changed, 642 insertions, 23 deletions
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..7aa6c4d702d6 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 | |
@@ -3717,8 +4052,15 @@ int ath10k_mac_register(struct ath10k *ar) | |||
3717 | */ | 4052 | */ |
3718 | ar->hw->queues = 4; | 4053 | ar->hw->queues = 4; |
3719 | 4054 | ||
3720 | ar->hw->wiphy->iface_combinations = ath10k_if_comb; | 4055 | if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { |
3721 | ar->hw->wiphy->n_iface_combinations = ARRAY_SIZE(ath10k_if_comb); | 4056 | ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb; |
4057 | ar->hw->wiphy->n_iface_combinations = | ||
4058 | ARRAY_SIZE(ath10k_10x_if_comb); | ||
4059 | } else { | ||
4060 | ar->hw->wiphy->iface_combinations = ath10k_if_comb; | ||
4061 | ar->hw->wiphy->n_iface_combinations = | ||
4062 | ARRAY_SIZE(ath10k_if_comb); | ||
4063 | } | ||
3722 | 4064 | ||
3723 | ar->hw->netdev_features = NETIF_F_HW_CSUM; | 4065 | ar->hw->netdev_features = NETIF_F_HW_CSUM; |
3724 | 4066 | ||
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_ */ |