diff options
author | Kalle Valo <kvalo@codeaurora.org> | 2018-03-29 08:55:28 -0400 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2018-03-29 08:55:28 -0400 |
commit | 14c99949a3398a655c47b262ca8e2e83edfae7fd (patch) | |
tree | 769385b16a9b3a3057afaca2bc195120cc8a2bb6 | |
parent | 63f5be0a81e0c607255e8debab16e62670305fee (diff) | |
parent | a72c92629108bb8ad756f31b74791c51e1de2af4 (diff) |
Merge ath-next from git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
ath.git patches for 4.17. Major changes:
ath10k
* enable chip temperature measurement for QCA6174/QCA9377
* add firmware memory dump for QCA9984
* enable buffer STA on TDLS link for QCA6174
* support different beacon internals in multiple interface scenario
for QCA988X/QCA99X0/QCA9984/QCA4019
20 files changed, 580 insertions, 150 deletions
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index f3f2784f6ebd..7a364eca46d6 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h | |||
@@ -33,8 +33,6 @@ | |||
33 | */ | 33 | */ |
34 | #define ATH_KEYMAX 128 /* max key cache size we handle */ | 34 | #define ATH_KEYMAX 128 /* max key cache size we handle */ |
35 | 35 | ||
36 | static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | ||
37 | |||
38 | struct ath_ani { | 36 | struct ath_ani { |
39 | bool caldone; | 37 | bool caldone; |
40 | unsigned int longcal_timer; | 38 | unsigned int longcal_timer; |
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 830b7fe466f3..8a3020dbd4cf 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c | |||
@@ -2041,7 +2041,8 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar) | |||
2041 | ar->max_num_vdevs = TARGET_10_4_NUM_VDEVS; | 2041 | ar->max_num_vdevs = TARGET_10_4_NUM_VDEVS; |
2042 | ar->num_tids = TARGET_10_4_TGT_NUM_TIDS; | 2042 | ar->num_tids = TARGET_10_4_TGT_NUM_TIDS; |
2043 | ar->fw_stats_req_mask = WMI_10_4_STAT_PEER | | 2043 | ar->fw_stats_req_mask = WMI_10_4_STAT_PEER | |
2044 | WMI_10_4_STAT_PEER_EXTD; | 2044 | WMI_10_4_STAT_PEER_EXTD | |
2045 | WMI_10_4_STAT_VDEV_EXTD; | ||
2045 | ar->max_spatial_stream = ar->hw_params.max_spatial_stream; | 2046 | ar->max_spatial_stream = ar->hw_params.max_spatial_stream; |
2046 | ar->max_num_tdls_vdevs = TARGET_10_4_NUM_TDLS_VDEVS; | 2047 | ar->max_num_tdls_vdevs = TARGET_10_4_NUM_TDLS_VDEVS; |
2047 | 2048 | ||
@@ -2282,6 +2283,9 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode, | |||
2282 | if (ath10k_peer_stats_enabled(ar)) | 2283 | if (ath10k_peer_stats_enabled(ar)) |
2283 | val = WMI_10_4_PEER_STATS; | 2284 | val = WMI_10_4_PEER_STATS; |
2284 | 2285 | ||
2286 | /* Enable vdev stats by default */ | ||
2287 | val |= WMI_10_4_VDEV_STATS; | ||
2288 | |||
2285 | if (test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map)) | 2289 | if (test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map)) |
2286 | val |= WMI_10_4_BSS_CHANNEL_INFO_64; | 2290 | val |= WMI_10_4_BSS_CHANNEL_INFO_64; |
2287 | 2291 | ||
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 73712c830be7..c17d805d68cc 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h | |||
@@ -222,6 +222,27 @@ struct ath10k_fw_stats_vdev { | |||
222 | u32 beacon_rssi_history[10]; | 222 | u32 beacon_rssi_history[10]; |
223 | }; | 223 | }; |
224 | 224 | ||
225 | struct ath10k_fw_stats_vdev_extd { | ||
226 | struct list_head list; | ||
227 | |||
228 | u32 vdev_id; | ||
229 | u32 ppdu_aggr_cnt; | ||
230 | u32 ppdu_noack; | ||
231 | u32 mpdu_queued; | ||
232 | u32 ppdu_nonaggr_cnt; | ||
233 | u32 mpdu_sw_requeued; | ||
234 | u32 mpdu_suc_retry; | ||
235 | u32 mpdu_suc_multitry; | ||
236 | u32 mpdu_fail_retry; | ||
237 | u32 tx_ftm_suc; | ||
238 | u32 tx_ftm_suc_retry; | ||
239 | u32 tx_ftm_fail; | ||
240 | u32 rx_ftmr_cnt; | ||
241 | u32 rx_ftmr_dup_cnt; | ||
242 | u32 rx_iftmr_cnt; | ||
243 | u32 rx_iftmr_dup_cnt; | ||
244 | }; | ||
245 | |||
225 | struct ath10k_fw_stats_pdev { | 246 | struct ath10k_fw_stats_pdev { |
226 | struct list_head list; | 247 | struct list_head list; |
227 | 248 | ||
diff --git a/drivers/net/wireless/ath/ath10k/coredump.c b/drivers/net/wireless/ath/ath10k/coredump.c index 7173b3743b43..f90cec0ebb1c 100644 --- a/drivers/net/wireless/ath/ath10k/coredump.c +++ b/drivers/net/wireless/ath/ath10k/coredump.c | |||
@@ -701,6 +701,89 @@ static const struct ath10k_mem_region qca988x_hw20_mem_regions[] = { | |||
701 | }, | 701 | }, |
702 | }; | 702 | }; |
703 | 703 | ||
704 | static const struct ath10k_mem_region qca9984_hw10_mem_regions[] = { | ||
705 | { | ||
706 | .type = ATH10K_MEM_REGION_TYPE_DRAM, | ||
707 | .start = 0x400000, | ||
708 | .len = 0x80000, | ||
709 | .name = "DRAM", | ||
710 | .section_table = { | ||
711 | .sections = NULL, | ||
712 | .size = 0, | ||
713 | }, | ||
714 | }, | ||
715 | { | ||
716 | .type = ATH10K_MEM_REGION_TYPE_REG, | ||
717 | .start = 0x98000, | ||
718 | .len = 0x50000, | ||
719 | .name = "IRAM", | ||
720 | .section_table = { | ||
721 | .sections = NULL, | ||
722 | .size = 0, | ||
723 | }, | ||
724 | }, | ||
725 | { | ||
726 | .type = ATH10K_MEM_REGION_TYPE_IOSRAM, | ||
727 | .start = 0xC0000, | ||
728 | .len = 0x40000, | ||
729 | .name = "SRAM", | ||
730 | .section_table = { | ||
731 | .sections = NULL, | ||
732 | .size = 0, | ||
733 | }, | ||
734 | }, | ||
735 | { | ||
736 | .type = ATH10K_MEM_REGION_TYPE_IOREG, | ||
737 | .start = 0x30000, | ||
738 | .len = 0x7000, | ||
739 | .name = "APB REG 1", | ||
740 | .section_table = { | ||
741 | .sections = NULL, | ||
742 | .size = 0, | ||
743 | }, | ||
744 | }, | ||
745 | { | ||
746 | .type = ATH10K_MEM_REGION_TYPE_IOREG, | ||
747 | .start = 0x3f000, | ||
748 | .len = 0x3000, | ||
749 | .name = "APB REG 2", | ||
750 | .section_table = { | ||
751 | .sections = NULL, | ||
752 | .size = 0, | ||
753 | }, | ||
754 | }, | ||
755 | { | ||
756 | .type = ATH10K_MEM_REGION_TYPE_IOREG, | ||
757 | .start = 0x43000, | ||
758 | .len = 0x3000, | ||
759 | .name = "WIFI REG", | ||
760 | .section_table = { | ||
761 | .sections = NULL, | ||
762 | .size = 0, | ||
763 | }, | ||
764 | }, | ||
765 | { | ||
766 | .type = ATH10K_MEM_REGION_TYPE_IOREG, | ||
767 | .start = 0x4A000, | ||
768 | .len = 0x5000, | ||
769 | .name = "CE REG", | ||
770 | .section_table = { | ||
771 | .sections = NULL, | ||
772 | .size = 0, | ||
773 | }, | ||
774 | }, | ||
775 | { | ||
776 | .type = ATH10K_MEM_REGION_TYPE_IOREG, | ||
777 | .start = 0x80000, | ||
778 | .len = 0x6000, | ||
779 | .name = "SOC REG", | ||
780 | .section_table = { | ||
781 | .sections = NULL, | ||
782 | .size = 0, | ||
783 | }, | ||
784 | }, | ||
785 | }; | ||
786 | |||
704 | static const struct ath10k_hw_mem_layout hw_mem_layouts[] = { | 787 | static const struct ath10k_hw_mem_layout hw_mem_layouts[] = { |
705 | { | 788 | { |
706 | .hw_id = QCA6174_HW_1_0_VERSION, | 789 | .hw_id = QCA6174_HW_1_0_VERSION, |
@@ -758,6 +841,13 @@ static const struct ath10k_hw_mem_layout hw_mem_layouts[] = { | |||
758 | .size = ARRAY_SIZE(qca988x_hw20_mem_regions), | 841 | .size = ARRAY_SIZE(qca988x_hw20_mem_regions), |
759 | }, | 842 | }, |
760 | }, | 843 | }, |
844 | { | ||
845 | .hw_id = QCA9984_HW_1_0_DEV_VERSION, | ||
846 | .region_table = { | ||
847 | .regions = qca9984_hw10_mem_regions, | ||
848 | .size = ARRAY_SIZE(qca9984_hw10_mem_regions), | ||
849 | }, | ||
850 | }, | ||
761 | }; | 851 | }; |
762 | 852 | ||
763 | static u32 ath10k_coredump_get_ramdump_size(struct ath10k *ar) | 853 | static u32 ath10k_coredump_get_ramdump_size(struct ath10k *ar) |
diff --git a/drivers/net/wireless/ath/ath10k/coredump.h b/drivers/net/wireless/ath/ath10k/coredump.h index bfee13038e59..3baaf9d2cbcd 100644 --- a/drivers/net/wireless/ath/ath10k/coredump.h +++ b/drivers/net/wireless/ath/ath10k/coredump.h | |||
@@ -124,6 +124,8 @@ enum ath10k_mem_region_type { | |||
124 | ATH10K_MEM_REGION_TYPE_AXI = 3, | 124 | ATH10K_MEM_REGION_TYPE_AXI = 3, |
125 | ATH10K_MEM_REGION_TYPE_IRAM1 = 4, | 125 | ATH10K_MEM_REGION_TYPE_IRAM1 = 4, |
126 | ATH10K_MEM_REGION_TYPE_IRAM2 = 5, | 126 | ATH10K_MEM_REGION_TYPE_IRAM2 = 5, |
127 | ATH10K_MEM_REGION_TYPE_IOSRAM = 6, | ||
128 | ATH10K_MEM_REGION_TYPE_IOREG = 7, | ||
127 | }; | 129 | }; |
128 | 130 | ||
129 | /* Define a section of the region which should be copied. As not all parts | 131 | /* Define a section of the region which should be copied. As not all parts |
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 64996aba1485..5e02e26158f6 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c | |||
@@ -724,6 +724,28 @@ struct amsdu_subframe_hdr { | |||
724 | 724 | ||
725 | #define GROUP_ID_IS_SU_MIMO(x) ((x) == 0 || (x) == 63) | 725 | #define GROUP_ID_IS_SU_MIMO(x) ((x) == 0 || (x) == 63) |
726 | 726 | ||
727 | static inline u8 ath10k_bw_to_mac80211_bw(u8 bw) | ||
728 | { | ||
729 | u8 ret = 0; | ||
730 | |||
731 | switch (bw) { | ||
732 | case 0: | ||
733 | ret = RATE_INFO_BW_20; | ||
734 | break; | ||
735 | case 1: | ||
736 | ret = RATE_INFO_BW_40; | ||
737 | break; | ||
738 | case 2: | ||
739 | ret = RATE_INFO_BW_80; | ||
740 | break; | ||
741 | case 3: | ||
742 | ret = RATE_INFO_BW_160; | ||
743 | break; | ||
744 | } | ||
745 | |||
746 | return ret; | ||
747 | } | ||
748 | |||
727 | static void ath10k_htt_rx_h_rates(struct ath10k *ar, | 749 | static void ath10k_htt_rx_h_rates(struct ath10k *ar, |
728 | struct ieee80211_rx_status *status, | 750 | struct ieee80211_rx_status *status, |
729 | struct htt_rx_desc *rxd) | 751 | struct htt_rx_desc *rxd) |
@@ -826,23 +848,7 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar, | |||
826 | if (sgi) | 848 | if (sgi) |
827 | status->enc_flags |= RX_ENC_FLAG_SHORT_GI; | 849 | status->enc_flags |= RX_ENC_FLAG_SHORT_GI; |
828 | 850 | ||
829 | switch (bw) { | 851 | status->bw = ath10k_bw_to_mac80211_bw(bw); |
830 | /* 20MHZ */ | ||
831 | case 0: | ||
832 | break; | ||
833 | /* 40MHZ */ | ||
834 | case 1: | ||
835 | status->bw = RATE_INFO_BW_40; | ||
836 | break; | ||
837 | /* 80MHZ */ | ||
838 | case 2: | ||
839 | status->bw = RATE_INFO_BW_80; | ||
840 | break; | ||
841 | case 3: | ||
842 | status->bw = RATE_INFO_BW_160; | ||
843 | break; | ||
844 | } | ||
845 | |||
846 | status->encoding = RX_ENC_VHT; | 852 | status->encoding = RX_ENC_VHT; |
847 | break; | 853 | break; |
848 | default: | 854 | default: |
@@ -2550,7 +2556,7 @@ ath10k_update_per_peer_tx_stats(struct ath10k *ar, | |||
2550 | arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; | 2556 | arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; |
2551 | 2557 | ||
2552 | arsta->txrate.nss = txrate.nss; | 2558 | arsta->txrate.nss = txrate.nss; |
2553 | arsta->txrate.bw = txrate.bw + RATE_INFO_BW_20; | 2559 | arsta->txrate.bw = ath10k_bw_to_mac80211_bw(txrate.bw); |
2554 | } | 2560 | } |
2555 | 2561 | ||
2556 | static void ath10k_htt_fetch_peer_stats(struct ath10k *ar, | 2562 | static void ath10k_htt_fetch_peer_stats(struct ath10k *ar, |
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 02674ee04435..bf05a3689558 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c | |||
@@ -2977,7 +2977,7 @@ static int ath10k_station_assoc(struct ath10k *ar, | |||
2977 | } | 2977 | } |
2978 | 2978 | ||
2979 | /* Plumb cached keys only for static WEP */ | 2979 | /* Plumb cached keys only for static WEP */ |
2980 | if (arvif->def_wep_key_idx != -1) { | 2980 | if ((arvif->def_wep_key_idx != -1) && (!sta->tdls)) { |
2981 | ret = ath10k_install_peer_wep_keys(arvif, sta->addr); | 2981 | ret = ath10k_install_peer_wep_keys(arvif, sta->addr); |
2982 | if (ret) { | 2982 | if (ret) { |
2983 | ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n", | 2983 | ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n", |
@@ -5932,6 +5932,10 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
5932 | ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr); | 5932 | ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr); |
5933 | spin_unlock_bh(&ar->data_lock); | 5933 | spin_unlock_bh(&ar->data_lock); |
5934 | 5934 | ||
5935 | if (sta && sta->tdls) | ||
5936 | ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr, | ||
5937 | WMI_PEER_AUTHORIZE, 1); | ||
5938 | |||
5935 | exit: | 5939 | exit: |
5936 | mutex_unlock(&ar->conf_mutex); | 5940 | mutex_unlock(&ar->conf_mutex); |
5937 | return ret; | 5941 | return ret; |
@@ -6046,9 +6050,8 @@ static void ath10k_sta_rc_update_wk(struct work_struct *wk) | |||
6046 | sta->addr, smps, err); | 6050 | sta->addr, smps, err); |
6047 | } | 6051 | } |
6048 | 6052 | ||
6049 | if (changed & IEEE80211_RC_SUPP_RATES_CHANGED || | 6053 | if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) { |
6050 | changed & IEEE80211_RC_NSS_CHANGED) { | 6054 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates\n", |
6051 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates/nss\n", | ||
6052 | sta->addr); | 6055 | sta->addr); |
6053 | 6056 | ||
6054 | err = ath10k_station_assoc(ar, arvif->vif, sta, true); | 6057 | err = ath10k_station_assoc(ar, arvif->vif, sta, true); |
@@ -7902,6 +7905,7 @@ static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = { | |||
7902 | .max_interfaces = 8, | 7905 | .max_interfaces = 8, |
7903 | .num_different_channels = 1, | 7906 | .num_different_channels = 1, |
7904 | .beacon_int_infra_match = true, | 7907 | .beacon_int_infra_match = true, |
7908 | .beacon_int_min_gcd = 1, | ||
7905 | #ifdef CONFIG_ATH10K_DFS_CERTIFIED | 7909 | #ifdef CONFIG_ATH10K_DFS_CERTIFIED |
7906 | .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | | 7910 | .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | |
7907 | BIT(NL80211_CHAN_WIDTH_20) | | 7911 | BIT(NL80211_CHAN_WIDTH_20) | |
@@ -8025,6 +8029,7 @@ static const struct ieee80211_iface_combination ath10k_10_4_if_comb[] = { | |||
8025 | .max_interfaces = 16, | 8029 | .max_interfaces = 16, |
8026 | .num_different_channels = 1, | 8030 | .num_different_channels = 1, |
8027 | .beacon_int_infra_match = true, | 8031 | .beacon_int_infra_match = true, |
8032 | .beacon_int_min_gcd = 1, | ||
8028 | #ifdef CONFIG_ATH10K_DFS_CERTIFIED | 8033 | #ifdef CONFIG_ATH10K_DFS_CERTIFIED |
8029 | .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | | 8034 | .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | |
8030 | BIT(NL80211_CHAN_WIDTH_20) | | 8035 | BIT(NL80211_CHAN_WIDTH_20) | |
@@ -8326,6 +8331,9 @@ int ath10k_mac_register(struct ath10k *ar) | |||
8326 | ieee80211_hw_set(ar->hw, TDLS_WIDER_BW); | 8331 | ieee80211_hw_set(ar->hw, TDLS_WIDER_BW); |
8327 | } | 8332 | } |
8328 | 8333 | ||
8334 | if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, ar->wmi.svc_map)) | ||
8335 | ieee80211_hw_set(ar->hw, SUPPORTS_TDLS_BUFFER_STA); | ||
8336 | |||
8329 | ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; | 8337 | ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; |
8330 | ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; | 8338 | ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; |
8331 | ar->hw->wiphy->max_remain_on_channel_duration = 5000; | 8339 | ar->hw->wiphy->max_remain_on_channel_duration = 5000; |
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 808f3d67ba90..fd1566cd7d2b 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c | |||
@@ -57,6 +57,10 @@ MODULE_PARM_DESC(reset_mode, "0: auto, 1: warm only (default: 0)"); | |||
57 | */ | 57 | */ |
58 | #define ATH10K_DIAG_TRANSFER_LIMIT 0x5000 | 58 | #define ATH10K_DIAG_TRANSFER_LIMIT 0x5000 |
59 | 59 | ||
60 | #define QCA99X0_PCIE_BAR0_START_REG 0x81030 | ||
61 | #define QCA99X0_CPU_MEM_ADDR_REG 0x4d00c | ||
62 | #define QCA99X0_CPU_MEM_DATA_REG 0x4d010 | ||
63 | |||
60 | static const struct pci_device_id ath10k_pci_id_table[] = { | 64 | static const struct pci_device_id ath10k_pci_id_table[] = { |
61 | /* PCI-E QCA988X V2 (Ubiquiti branded) */ | 65 | /* PCI-E QCA988X V2 (Ubiquiti branded) */ |
62 | { PCI_VDEVICE(UBIQUITI, QCA988X_2_0_DEVICE_ID_UBNT) }, | 66 | { PCI_VDEVICE(UBIQUITI, QCA988X_2_0_DEVICE_ID_UBNT) }, |
@@ -1584,6 +1588,69 @@ static int ath10k_pci_set_ram_config(struct ath10k *ar, u32 config) | |||
1584 | return 0; | 1588 | return 0; |
1585 | } | 1589 | } |
1586 | 1590 | ||
1591 | /* if an error happened returns < 0, otherwise the length */ | ||
1592 | static int ath10k_pci_dump_memory_sram(struct ath10k *ar, | ||
1593 | const struct ath10k_mem_region *region, | ||
1594 | u8 *buf) | ||
1595 | { | ||
1596 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | ||
1597 | u32 base_addr, i; | ||
1598 | |||
1599 | base_addr = ioread32(ar_pci->mem + QCA99X0_PCIE_BAR0_START_REG); | ||
1600 | base_addr += region->start; | ||
1601 | |||
1602 | for (i = 0; i < region->len; i += 4) { | ||
1603 | iowrite32(base_addr + i, ar_pci->mem + QCA99X0_CPU_MEM_ADDR_REG); | ||
1604 | *(u32 *)(buf + i) = ioread32(ar_pci->mem + QCA99X0_CPU_MEM_DATA_REG); | ||
1605 | } | ||
1606 | |||
1607 | return region->len; | ||
1608 | } | ||
1609 | |||
1610 | /* if an error happened returns < 0, otherwise the length */ | ||
1611 | static int ath10k_pci_dump_memory_reg(struct ath10k *ar, | ||
1612 | const struct ath10k_mem_region *region, | ||
1613 | u8 *buf) | ||
1614 | { | ||
1615 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | ||
1616 | u32 i; | ||
1617 | |||
1618 | for (i = 0; i < region->len; i += 4) | ||
1619 | *(u32 *)(buf + i) = ioread32(ar_pci->mem + region->start + i); | ||
1620 | |||
1621 | return region->len; | ||
1622 | } | ||
1623 | |||
1624 | /* if an error happened returns < 0, otherwise the length */ | ||
1625 | static int ath10k_pci_dump_memory_generic(struct ath10k *ar, | ||
1626 | const struct ath10k_mem_region *current_region, | ||
1627 | u8 *buf) | ||
1628 | { | ||
1629 | int ret; | ||
1630 | |||
1631 | if (current_region->section_table.size > 0) | ||
1632 | /* Copy each section individually. */ | ||
1633 | return ath10k_pci_dump_memory_section(ar, | ||
1634 | current_region, | ||
1635 | buf, | ||
1636 | current_region->len); | ||
1637 | |||
1638 | /* No individiual memory sections defined so we can | ||
1639 | * copy the entire memory region. | ||
1640 | */ | ||
1641 | ret = ath10k_pci_diag_read_mem(ar, | ||
1642 | current_region->start, | ||
1643 | buf, | ||
1644 | current_region->len); | ||
1645 | if (ret) { | ||
1646 | ath10k_warn(ar, "failed to copy ramdump region %s: %d\n", | ||
1647 | current_region->name, ret); | ||
1648 | return ret; | ||
1649 | } | ||
1650 | |||
1651 | return current_region->len; | ||
1652 | } | ||
1653 | |||
1587 | static void ath10k_pci_dump_memory(struct ath10k *ar, | 1654 | static void ath10k_pci_dump_memory(struct ath10k *ar, |
1588 | struct ath10k_fw_crash_data *crash_data) | 1655 | struct ath10k_fw_crash_data *crash_data) |
1589 | { | 1656 | { |
@@ -1642,27 +1709,20 @@ static void ath10k_pci_dump_memory(struct ath10k *ar, | |||
1642 | buf += sizeof(*hdr); | 1709 | buf += sizeof(*hdr); |
1643 | buf_len -= sizeof(*hdr); | 1710 | buf_len -= sizeof(*hdr); |
1644 | 1711 | ||
1645 | if (current_region->section_table.size > 0) { | 1712 | switch (current_region->type) { |
1646 | /* Copy each section individually. */ | 1713 | case ATH10K_MEM_REGION_TYPE_IOSRAM: |
1647 | count = ath10k_pci_dump_memory_section(ar, | 1714 | count = ath10k_pci_dump_memory_sram(ar, current_region, buf); |
1648 | current_region, | 1715 | break; |
1649 | buf, | 1716 | case ATH10K_MEM_REGION_TYPE_IOREG: |
1650 | current_region->len); | 1717 | count = ath10k_pci_dump_memory_reg(ar, current_region, buf); |
1651 | } else { | 1718 | break; |
1652 | /* No individiual memory sections defined so we can | 1719 | default: |
1653 | * copy the entire memory region. | 1720 | ret = ath10k_pci_dump_memory_generic(ar, current_region, buf); |
1654 | */ | 1721 | if (ret < 0) |
1655 | ret = ath10k_pci_diag_read_mem(ar, | ||
1656 | current_region->start, | ||
1657 | buf, | ||
1658 | current_region->len); | ||
1659 | if (ret) { | ||
1660 | ath10k_warn(ar, "failed to copy ramdump region %s: %d\n", | ||
1661 | current_region->name, ret); | ||
1662 | break; | 1722 | break; |
1663 | } | ||
1664 | 1723 | ||
1665 | count = current_region->len; | 1724 | count = ret; |
1725 | break; | ||
1666 | } | 1726 | } |
1667 | 1727 | ||
1668 | hdr->region_type = cpu_to_le32(current_region->type); | 1728 | hdr->region_type = cpu_to_le32(current_region->type); |
@@ -3718,5 +3778,6 @@ MODULE_FIRMWARE(QCA6174_HW_3_0_FW_DIR "/" QCA6174_HW_3_0_BOARD_DATA_FILE); | |||
3718 | MODULE_FIRMWARE(QCA6174_HW_3_0_FW_DIR "/" ATH10K_BOARD_API2_FILE); | 3778 | MODULE_FIRMWARE(QCA6174_HW_3_0_FW_DIR "/" ATH10K_BOARD_API2_FILE); |
3719 | 3779 | ||
3720 | /* QCA9377 1.0 firmware files */ | 3780 | /* QCA9377 1.0 firmware files */ |
3781 | MODULE_FIRMWARE(QCA9377_HW_1_0_FW_DIR "/" ATH10K_FW_API6_FILE); | ||
3721 | MODULE_FIRMWARE(QCA9377_HW_1_0_FW_DIR "/" ATH10K_FW_API5_FILE); | 3782 | MODULE_FIRMWARE(QCA9377_HW_1_0_FW_DIR "/" ATH10K_FW_API5_FILE); |
3722 | MODULE_FIRMWARE(QCA9377_HW_1_0_FW_DIR "/" QCA9377_HW_1_0_BOARD_DATA_FILE); | 3783 | MODULE_FIRMWARE(QCA9377_HW_1_0_FW_DIR "/" QCA9377_HW_1_0_BOARD_DATA_FILE); |
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c index 523af3f8bb62..9d1b0a459069 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c | |||
@@ -413,6 +413,62 @@ static int ath10k_wmi_tlv_event_tx_pause(struct ath10k *ar, | |||
413 | return 0; | 413 | return 0; |
414 | } | 414 | } |
415 | 415 | ||
416 | static int ath10k_wmi_tlv_event_temperature(struct ath10k *ar, | ||
417 | struct sk_buff *skb) | ||
418 | { | ||
419 | const struct wmi_tlv_pdev_temperature_event *ev; | ||
420 | |||
421 | ev = (struct wmi_tlv_pdev_temperature_event *)skb->data; | ||
422 | if (WARN_ON(skb->len < sizeof(*ev))) | ||
423 | return -EPROTO; | ||
424 | |||
425 | ath10k_thermal_event_temperature(ar, __le32_to_cpu(ev->temperature)); | ||
426 | return 0; | ||
427 | } | ||
428 | |||
429 | static void ath10k_wmi_event_tdls_peer(struct ath10k *ar, struct sk_buff *skb) | ||
430 | { | ||
431 | struct ieee80211_sta *station; | ||
432 | const struct wmi_tlv_tdls_peer_event *ev; | ||
433 | const void **tb; | ||
434 | struct ath10k_vif *arvif; | ||
435 | |||
436 | tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); | ||
437 | if (IS_ERR(tb)) { | ||
438 | ath10k_warn(ar, "tdls peer failed to parse tlv"); | ||
439 | return; | ||
440 | } | ||
441 | ev = tb[WMI_TLV_TAG_STRUCT_TDLS_PEER_EVENT]; | ||
442 | if (!ev) { | ||
443 | kfree(tb); | ||
444 | ath10k_warn(ar, "tdls peer NULL event"); | ||
445 | return; | ||
446 | } | ||
447 | |||
448 | switch (__le32_to_cpu(ev->peer_reason)) { | ||
449 | case WMI_TDLS_TEARDOWN_REASON_TX: | ||
450 | case WMI_TDLS_TEARDOWN_REASON_RSSI: | ||
451 | case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT: | ||
452 | station = ieee80211_find_sta_by_ifaddr(ar->hw, | ||
453 | ev->peer_macaddr.addr, | ||
454 | NULL); | ||
455 | if (!station) { | ||
456 | ath10k_warn(ar, "did not find station from tdls peer event"); | ||
457 | kfree(tb); | ||
458 | return; | ||
459 | } | ||
460 | arvif = ath10k_get_arvif(ar, __le32_to_cpu(ev->vdev_id)); | ||
461 | ieee80211_tdls_oper_request( | ||
462 | arvif->vif, station->addr, | ||
463 | NL80211_TDLS_TEARDOWN, | ||
464 | WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE, | ||
465 | GFP_ATOMIC | ||
466 | ); | ||
467 | break; | ||
468 | } | ||
469 | kfree(tb); | ||
470 | } | ||
471 | |||
416 | /***********/ | 472 | /***********/ |
417 | /* TLV ops */ | 473 | /* TLV ops */ |
418 | /***********/ | 474 | /***********/ |
@@ -553,6 +609,12 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb) | |||
553 | case WMI_TLV_TX_PAUSE_EVENTID: | 609 | case WMI_TLV_TX_PAUSE_EVENTID: |
554 | ath10k_wmi_tlv_event_tx_pause(ar, skb); | 610 | ath10k_wmi_tlv_event_tx_pause(ar, skb); |
555 | break; | 611 | break; |
612 | case WMI_TLV_PDEV_TEMPERATURE_EVENTID: | ||
613 | ath10k_wmi_tlv_event_temperature(ar, skb); | ||
614 | break; | ||
615 | case WMI_TLV_TDLS_PEER_EVENTID: | ||
616 | ath10k_wmi_event_tdls_peer(ar, skb); | ||
617 | break; | ||
556 | default: | 618 | default: |
557 | ath10k_warn(ar, "Unknown eventid: %d\n", id); | 619 | ath10k_warn(ar, "Unknown eventid: %d\n", id); |
558 | break; | 620 | break; |
@@ -2658,6 +2720,25 @@ ath10k_wmi_tlv_op_gen_pktlog_enable(struct ath10k *ar, u32 filter) | |||
2658 | } | 2720 | } |
2659 | 2721 | ||
2660 | static struct sk_buff * | 2722 | static struct sk_buff * |
2723 | ath10k_wmi_tlv_op_gen_pdev_get_temperature(struct ath10k *ar) | ||
2724 | { | ||
2725 | struct wmi_tlv_pdev_get_temp_cmd *cmd; | ||
2726 | struct wmi_tlv *tlv; | ||
2727 | struct sk_buff *skb; | ||
2728 | |||
2729 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); | ||
2730 | if (!skb) | ||
2731 | return ERR_PTR(-ENOMEM); | ||
2732 | |||
2733 | tlv = (void *)skb->data; | ||
2734 | tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_GET_TEMPERATURE_CMD); | ||
2735 | tlv->len = __cpu_to_le16(sizeof(*cmd)); | ||
2736 | cmd = (void *)tlv->value; | ||
2737 | ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev get temperature tlv\n"); | ||
2738 | return skb; | ||
2739 | } | ||
2740 | |||
2741 | static struct sk_buff * | ||
2661 | ath10k_wmi_tlv_op_gen_pktlog_disable(struct ath10k *ar) | 2742 | ath10k_wmi_tlv_op_gen_pktlog_disable(struct ath10k *ar) |
2662 | { | 2743 | { |
2663 | struct wmi_tlv_pktlog_disable *cmd; | 2744 | struct wmi_tlv_pktlog_disable *cmd; |
@@ -2851,6 +2932,15 @@ ath10k_wmi_tlv_op_gen_update_fw_tdls_state(struct ath10k *ar, u32 vdev_id, | |||
2851 | */ | 2932 | */ |
2852 | u32 options = 0; | 2933 | u32 options = 0; |
2853 | 2934 | ||
2935 | if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, ar->wmi.svc_map)) | ||
2936 | options |= WMI_TLV_TDLS_BUFFER_STA_EN; | ||
2937 | |||
2938 | /* WMI_TDLS_ENABLE_ACTIVE_EXTERNAL_CONTROL means firm will handle TDLS | ||
2939 | * link inactivity detecting logic. | ||
2940 | */ | ||
2941 | if (state == WMI_TDLS_ENABLE_ACTIVE) | ||
2942 | state = WMI_TDLS_ENABLE_ACTIVE_EXTERNAL_CONTROL; | ||
2943 | |||
2854 | len = sizeof(*tlv) + sizeof(*cmd); | 2944 | len = sizeof(*tlv) + sizeof(*cmd); |
2855 | skb = ath10k_wmi_alloc_skb(ar, len); | 2945 | skb = ath10k_wmi_alloc_skb(ar, len); |
2856 | if (!skb) | 2946 | if (!skb) |
@@ -3439,7 +3529,7 @@ static struct wmi_cmd_map wmi_tlv_cmd_map = { | |||
3439 | .force_fw_hang_cmdid = WMI_TLV_FORCE_FW_HANG_CMDID, | 3529 | .force_fw_hang_cmdid = WMI_TLV_FORCE_FW_HANG_CMDID, |
3440 | .gpio_config_cmdid = WMI_TLV_GPIO_CONFIG_CMDID, | 3530 | .gpio_config_cmdid = WMI_TLV_GPIO_CONFIG_CMDID, |
3441 | .gpio_output_cmdid = WMI_TLV_GPIO_OUTPUT_CMDID, | 3531 | .gpio_output_cmdid = WMI_TLV_GPIO_OUTPUT_CMDID, |
3442 | .pdev_get_temperature_cmdid = WMI_TLV_CMD_UNSUPPORTED, | 3532 | .pdev_get_temperature_cmdid = WMI_TLV_PDEV_GET_TEMPERATURE_CMDID, |
3443 | .vdev_set_wmm_params_cmdid = WMI_TLV_VDEV_SET_WMM_PARAMS_CMDID, | 3533 | .vdev_set_wmm_params_cmdid = WMI_TLV_VDEV_SET_WMM_PARAMS_CMDID, |
3444 | .tdls_set_state_cmdid = WMI_TLV_TDLS_SET_STATE_CMDID, | 3534 | .tdls_set_state_cmdid = WMI_TLV_TDLS_SET_STATE_CMDID, |
3445 | .tdls_peer_update_cmdid = WMI_TLV_TDLS_PEER_UPDATE_CMDID, | 3535 | .tdls_peer_update_cmdid = WMI_TLV_TDLS_PEER_UPDATE_CMDID, |
@@ -3702,7 +3792,7 @@ static const struct wmi_ops wmi_tlv_ops = { | |||
3702 | .gen_pktlog_enable = ath10k_wmi_tlv_op_gen_pktlog_enable, | 3792 | .gen_pktlog_enable = ath10k_wmi_tlv_op_gen_pktlog_enable, |
3703 | .gen_pktlog_disable = ath10k_wmi_tlv_op_gen_pktlog_disable, | 3793 | .gen_pktlog_disable = ath10k_wmi_tlv_op_gen_pktlog_disable, |
3704 | /* .gen_pdev_set_quiet_mode not implemented */ | 3794 | /* .gen_pdev_set_quiet_mode not implemented */ |
3705 | /* .gen_pdev_get_temperature not implemented */ | 3795 | .gen_pdev_get_temperature = ath10k_wmi_tlv_op_gen_pdev_get_temperature, |
3706 | /* .gen_addba_clear_resp not implemented */ | 3796 | /* .gen_addba_clear_resp not implemented */ |
3707 | /* .gen_addba_send not implemented */ | 3797 | /* .gen_addba_send not implemented */ |
3708 | /* .gen_addba_set_resp not implemented */ | 3798 | /* .gen_addba_set_resp not implemented */ |
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h index da89128e8dd6..fa3773ec7c68 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h | |||
@@ -1340,6 +1340,17 @@ struct wmi_tlv_init_cmd { | |||
1340 | __le32 num_host_mem_chunks; | 1340 | __le32 num_host_mem_chunks; |
1341 | } __packed; | 1341 | } __packed; |
1342 | 1342 | ||
1343 | struct wmi_tlv_pdev_get_temp_cmd { | ||
1344 | __le32 pdev_id; /* not used */ | ||
1345 | } __packed; | ||
1346 | |||
1347 | struct wmi_tlv_pdev_temperature_event { | ||
1348 | __le32 tlv_hdr; | ||
1349 | /* temperature value in Celcius degree */ | ||
1350 | __le32 temperature; | ||
1351 | __le32 pdev_id; | ||
1352 | } __packed; | ||
1353 | |||
1343 | struct wmi_tlv_pdev_set_param_cmd { | 1354 | struct wmi_tlv_pdev_set_param_cmd { |
1344 | __le32 pdev_id; /* not used yet */ | 1355 | __le32 pdev_id; /* not used yet */ |
1345 | __le32 param_id; | 1356 | __le32 param_id; |
@@ -1746,6 +1757,13 @@ struct wmi_tlv_tx_pause_ev { | |||
1746 | __le32 tid_map; | 1757 | __le32 tid_map; |
1747 | } __packed; | 1758 | } __packed; |
1748 | 1759 | ||
1760 | struct wmi_tlv_tdls_peer_event { | ||
1761 | struct wmi_mac_addr peer_macaddr; | ||
1762 | __le32 peer_status; | ||
1763 | __le32 peer_reason; | ||
1764 | __le32 vdev_id; | ||
1765 | } __packed; | ||
1766 | |||
1749 | void ath10k_wmi_tlv_attach(struct ath10k *ar); | 1767 | void ath10k_wmi_tlv_attach(struct ath10k *ar); |
1750 | 1768 | ||
1751 | struct wmi_tlv_mgmt_tx_cmd { | 1769 | struct wmi_tlv_mgmt_tx_cmd { |
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 9649bb752bbd..c5e1ca5945db 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c | |||
@@ -2708,6 +2708,28 @@ ath10k_wmi_10_4_pull_peer_stats(const struct wmi_10_4_peer_stats *src, | |||
2708 | dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate); | 2708 | dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate); |
2709 | } | 2709 | } |
2710 | 2710 | ||
2711 | static void | ||
2712 | ath10k_wmi_10_4_pull_vdev_stats(const struct wmi_vdev_stats_extd *src, | ||
2713 | struct ath10k_fw_stats_vdev_extd *dst) | ||
2714 | { | ||
2715 | dst->vdev_id = __le32_to_cpu(src->vdev_id); | ||
2716 | dst->ppdu_aggr_cnt = __le32_to_cpu(src->ppdu_aggr_cnt); | ||
2717 | dst->ppdu_noack = __le32_to_cpu(src->ppdu_noack); | ||
2718 | dst->mpdu_queued = __le32_to_cpu(src->mpdu_queued); | ||
2719 | dst->ppdu_nonaggr_cnt = __le32_to_cpu(src->ppdu_nonaggr_cnt); | ||
2720 | dst->mpdu_sw_requeued = __le32_to_cpu(src->mpdu_sw_requeued); | ||
2721 | dst->mpdu_suc_retry = __le32_to_cpu(src->mpdu_suc_retry); | ||
2722 | dst->mpdu_suc_multitry = __le32_to_cpu(src->mpdu_suc_multitry); | ||
2723 | dst->mpdu_fail_retry = __le32_to_cpu(src->mpdu_fail_retry); | ||
2724 | dst->tx_ftm_suc = __le32_to_cpu(src->tx_ftm_suc); | ||
2725 | dst->tx_ftm_suc_retry = __le32_to_cpu(src->tx_ftm_suc_retry); | ||
2726 | dst->tx_ftm_fail = __le32_to_cpu(src->tx_ftm_fail); | ||
2727 | dst->rx_ftmr_cnt = __le32_to_cpu(src->rx_ftmr_cnt); | ||
2728 | dst->rx_ftmr_dup_cnt = __le32_to_cpu(src->rx_ftmr_dup_cnt); | ||
2729 | dst->rx_iftmr_cnt = __le32_to_cpu(src->rx_iftmr_cnt); | ||
2730 | dst->rx_iftmr_dup_cnt = __le32_to_cpu(src->rx_iftmr_dup_cnt); | ||
2731 | } | ||
2732 | |||
2711 | static int ath10k_wmi_main_op_pull_fw_stats(struct ath10k *ar, | 2733 | static int ath10k_wmi_main_op_pull_fw_stats(struct ath10k *ar, |
2712 | struct sk_buff *skb, | 2734 | struct sk_buff *skb, |
2713 | struct ath10k_fw_stats *stats) | 2735 | struct ath10k_fw_stats *stats) |
@@ -3047,7 +3069,16 @@ static int ath10k_wmi_10_4_op_pull_fw_stats(struct ath10k *ar, | |||
3047 | */ | 3069 | */ |
3048 | } | 3070 | } |
3049 | 3071 | ||
3050 | /* fw doesn't implement vdev stats */ | 3072 | for (i = 0; i < num_vdev_stats; i++) { |
3073 | const struct wmi_vdev_stats *src; | ||
3074 | |||
3075 | /* Ignore vdev stats here as it has only vdev id. Actual vdev | ||
3076 | * stats will be retrieved from vdev extended stats. | ||
3077 | */ | ||
3078 | src = (void *)skb->data; | ||
3079 | if (!skb_pull(skb, sizeof(*src))) | ||
3080 | return -EPROTO; | ||
3081 | } | ||
3051 | 3082 | ||
3052 | for (i = 0; i < num_peer_stats; i++) { | 3083 | for (i = 0; i < num_peer_stats; i++) { |
3053 | const struct wmi_10_4_peer_stats *src; | 3084 | const struct wmi_10_4_peer_stats *src; |
@@ -3079,26 +3110,43 @@ static int ath10k_wmi_10_4_op_pull_fw_stats(struct ath10k *ar, | |||
3079 | */ | 3110 | */ |
3080 | } | 3111 | } |
3081 | 3112 | ||
3082 | if ((stats_id & WMI_10_4_STAT_PEER_EXTD) == 0) | 3113 | if (stats_id & WMI_10_4_STAT_PEER_EXTD) { |
3083 | return 0; | 3114 | stats->extended = true; |
3084 | 3115 | ||
3085 | stats->extended = true; | 3116 | for (i = 0; i < num_peer_stats; i++) { |
3117 | const struct wmi_10_4_peer_extd_stats *src; | ||
3118 | struct ath10k_fw_extd_stats_peer *dst; | ||
3086 | 3119 | ||
3087 | for (i = 0; i < num_peer_stats; i++) { | 3120 | src = (void *)skb->data; |
3088 | const struct wmi_10_4_peer_extd_stats *src; | 3121 | if (!skb_pull(skb, sizeof(*src))) |
3089 | struct ath10k_fw_extd_stats_peer *dst; | 3122 | return -EPROTO; |
3090 | 3123 | ||
3091 | src = (void *)skb->data; | 3124 | dst = kzalloc(sizeof(*dst), GFP_ATOMIC); |
3092 | if (!skb_pull(skb, sizeof(*src))) | 3125 | if (!dst) |
3093 | return -EPROTO; | 3126 | continue; |
3094 | 3127 | ||
3095 | dst = kzalloc(sizeof(*dst), GFP_ATOMIC); | 3128 | ether_addr_copy(dst->peer_macaddr, |
3096 | if (!dst) | 3129 | src->peer_macaddr.addr); |
3097 | continue; | 3130 | dst->rx_duration = __le32_to_cpu(src->rx_duration); |
3131 | list_add_tail(&dst->list, &stats->peers_extd); | ||
3132 | } | ||
3133 | } | ||
3098 | 3134 | ||
3099 | ether_addr_copy(dst->peer_macaddr, src->peer_macaddr.addr); | 3135 | if (stats_id & WMI_10_4_STAT_VDEV_EXTD) { |
3100 | dst->rx_duration = __le32_to_cpu(src->rx_duration); | 3136 | for (i = 0; i < num_vdev_stats; i++) { |
3101 | list_add_tail(&dst->list, &stats->peers_extd); | 3137 | const struct wmi_vdev_stats_extd *src; |
3138 | struct ath10k_fw_stats_vdev_extd *dst; | ||
3139 | |||
3140 | src = (void *)skb->data; | ||
3141 | if (!skb_pull(skb, sizeof(*src))) | ||
3142 | return -EPROTO; | ||
3143 | |||
3144 | dst = kzalloc(sizeof(*dst), GFP_ATOMIC); | ||
3145 | if (!dst) | ||
3146 | continue; | ||
3147 | ath10k_wmi_10_4_pull_vdev_stats(src, dst); | ||
3148 | list_add_tail(&dst->list, &stats->vdevs); | ||
3149 | } | ||
3102 | } | 3150 | } |
3103 | 3151 | ||
3104 | return 0; | 3152 | return 0; |
@@ -5786,6 +5834,7 @@ static void ath10k_wmi_10_4_op_rx(struct ath10k *ar, struct sk_buff *skb) | |||
5786 | case WMI_10_4_WOW_WAKEUP_HOST_EVENTID: | 5834 | case WMI_10_4_WOW_WAKEUP_HOST_EVENTID: |
5787 | case WMI_10_4_PEER_RATECODE_LIST_EVENTID: | 5835 | case WMI_10_4_PEER_RATECODE_LIST_EVENTID: |
5788 | case WMI_10_4_WDS_PEER_EVENTID: | 5836 | case WMI_10_4_WDS_PEER_EVENTID: |
5837 | case WMI_10_4_DEBUG_FATAL_CONDITION_EVENTID: | ||
5789 | ath10k_dbg(ar, ATH10K_DBG_WMI, | 5838 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
5790 | "received event id %d not implemented\n", id); | 5839 | "received event id %d not implemented\n", id); |
5791 | break; | 5840 | break; |
@@ -8003,6 +8052,72 @@ ath10k_wmi_op_gen_pdev_enable_adaptive_cca(struct ath10k *ar, u8 enable, | |||
8003 | return skb; | 8052 | return skb; |
8004 | } | 8053 | } |
8005 | 8054 | ||
8055 | static void | ||
8056 | ath10k_wmi_fw_vdev_stats_extd_fill(const struct ath10k_fw_stats_vdev_extd *vdev, | ||
8057 | char *buf, u32 *length) | ||
8058 | { | ||
8059 | u32 len = *length; | ||
8060 | u32 buf_len = ATH10K_FW_STATS_BUF_SIZE; | ||
8061 | u32 val; | ||
8062 | |||
8063 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8064 | "vdev id", vdev->vdev_id); | ||
8065 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8066 | "ppdu aggr count", vdev->ppdu_aggr_cnt); | ||
8067 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8068 | "ppdu noack", vdev->ppdu_noack); | ||
8069 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8070 | "mpdu queued", vdev->mpdu_queued); | ||
8071 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8072 | "ppdu nonaggr count", vdev->ppdu_nonaggr_cnt); | ||
8073 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8074 | "mpdu sw requeued", vdev->mpdu_sw_requeued); | ||
8075 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8076 | "mpdu success retry", vdev->mpdu_suc_retry); | ||
8077 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8078 | "mpdu success multitry", vdev->mpdu_suc_multitry); | ||
8079 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8080 | "mpdu fail retry", vdev->mpdu_fail_retry); | ||
8081 | val = vdev->tx_ftm_suc; | ||
8082 | if (val & WMI_VDEV_STATS_FTM_COUNT_VALID) | ||
8083 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8084 | "tx ftm success", | ||
8085 | MS(val, WMI_VDEV_STATS_FTM_COUNT)); | ||
8086 | val = vdev->tx_ftm_suc_retry; | ||
8087 | if (val & WMI_VDEV_STATS_FTM_COUNT_VALID) | ||
8088 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8089 | "tx ftm success retry", | ||
8090 | MS(val, WMI_VDEV_STATS_FTM_COUNT)); | ||
8091 | val = vdev->tx_ftm_fail; | ||
8092 | if (val & WMI_VDEV_STATS_FTM_COUNT_VALID) | ||
8093 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8094 | "tx ftm fail", | ||
8095 | MS(val, WMI_VDEV_STATS_FTM_COUNT)); | ||
8096 | val = vdev->rx_ftmr_cnt; | ||
8097 | if (val & WMI_VDEV_STATS_FTM_COUNT_VALID) | ||
8098 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8099 | "rx ftm request count", | ||
8100 | MS(val, WMI_VDEV_STATS_FTM_COUNT)); | ||
8101 | val = vdev->rx_ftmr_dup_cnt; | ||
8102 | if (val & WMI_VDEV_STATS_FTM_COUNT_VALID) | ||
8103 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8104 | "rx ftm request dup count", | ||
8105 | MS(val, WMI_VDEV_STATS_FTM_COUNT)); | ||
8106 | val = vdev->rx_iftmr_cnt; | ||
8107 | if (val & WMI_VDEV_STATS_FTM_COUNT_VALID) | ||
8108 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8109 | "rx initial ftm req count", | ||
8110 | MS(val, WMI_VDEV_STATS_FTM_COUNT)); | ||
8111 | val = vdev->rx_iftmr_dup_cnt; | ||
8112 | if (val & WMI_VDEV_STATS_FTM_COUNT_VALID) | ||
8113 | len += scnprintf(buf + len, buf_len - len, "%30s %u\n", | ||
8114 | "rx initial ftm req dup cnt", | ||
8115 | MS(val, WMI_VDEV_STATS_FTM_COUNT)); | ||
8116 | len += scnprintf(buf + len, buf_len - len, "\n"); | ||
8117 | |||
8118 | *length = len; | ||
8119 | } | ||
8120 | |||
8006 | void ath10k_wmi_10_4_op_fw_stats_fill(struct ath10k *ar, | 8121 | void ath10k_wmi_10_4_op_fw_stats_fill(struct ath10k *ar, |
8007 | struct ath10k_fw_stats *fw_stats, | 8122 | struct ath10k_fw_stats *fw_stats, |
8008 | char *buf) | 8123 | char *buf) |
@@ -8010,7 +8125,7 @@ void ath10k_wmi_10_4_op_fw_stats_fill(struct ath10k *ar, | |||
8010 | u32 len = 0; | 8125 | u32 len = 0; |
8011 | u32 buf_len = ATH10K_FW_STATS_BUF_SIZE; | 8126 | u32 buf_len = ATH10K_FW_STATS_BUF_SIZE; |
8012 | const struct ath10k_fw_stats_pdev *pdev; | 8127 | const struct ath10k_fw_stats_pdev *pdev; |
8013 | const struct ath10k_fw_stats_vdev *vdev; | 8128 | const struct ath10k_fw_stats_vdev_extd *vdev; |
8014 | const struct ath10k_fw_stats_peer *peer; | 8129 | const struct ath10k_fw_stats_peer *peer; |
8015 | size_t num_peers; | 8130 | size_t num_peers; |
8016 | size_t num_vdevs; | 8131 | size_t num_vdevs; |
@@ -8063,9 +8178,8 @@ void ath10k_wmi_10_4_op_fw_stats_fill(struct ath10k *ar, | |||
8063 | "ath10k VDEV stats", num_vdevs); | 8178 | "ath10k VDEV stats", num_vdevs); |
8064 | len += scnprintf(buf + len, buf_len - len, "%30s\n\n", | 8179 | len += scnprintf(buf + len, buf_len - len, "%30s\n\n", |
8065 | "================="); | 8180 | "================="); |
8066 | |||
8067 | list_for_each_entry(vdev, &fw_stats->vdevs, list) { | 8181 | list_for_each_entry(vdev, &fw_stats->vdevs, list) { |
8068 | ath10k_wmi_fw_vdev_stats_fill(vdev, buf, &len); | 8182 | ath10k_wmi_fw_vdev_stats_extd_fill(vdev, buf, &len); |
8069 | } | 8183 | } |
8070 | 8184 | ||
8071 | len += scnprintf(buf + len, buf_len - len, "\n"); | 8185 | len += scnprintf(buf + len, buf_len - len, "\n"); |
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index c8fc45d8090e..6fbc84c29521 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h | |||
@@ -4413,6 +4413,7 @@ enum wmi_10_4_stats_id { | |||
4413 | WMI_10_4_STAT_AP = BIT(1), | 4413 | WMI_10_4_STAT_AP = BIT(1), |
4414 | WMI_10_4_STAT_INST = BIT(2), | 4414 | WMI_10_4_STAT_INST = BIT(2), |
4415 | WMI_10_4_STAT_PEER_EXTD = BIT(3), | 4415 | WMI_10_4_STAT_PEER_EXTD = BIT(3), |
4416 | WMI_10_4_STAT_VDEV_EXTD = BIT(4), | ||
4416 | }; | 4417 | }; |
4417 | 4418 | ||
4418 | struct wlan_inst_rssi_args { | 4419 | struct wlan_inst_rssi_args { |
@@ -4552,12 +4553,36 @@ struct wmi_10_4_pdev_stats { | |||
4552 | 4553 | ||
4553 | /* | 4554 | /* |
4554 | * VDEV statistics | 4555 | * VDEV statistics |
4555 | * TODO: add all VDEV stats here | ||
4556 | */ | 4556 | */ |
4557 | |||
4558 | #define WMI_VDEV_STATS_FTM_COUNT_VALID BIT(31) | ||
4559 | #define WMI_VDEV_STATS_FTM_COUNT_LSB 0 | ||
4560 | #define WMI_VDEV_STATS_FTM_COUNT_MASK 0x7fffffff | ||
4561 | |||
4557 | struct wmi_vdev_stats { | 4562 | struct wmi_vdev_stats { |
4558 | __le32 vdev_id; | 4563 | __le32 vdev_id; |
4559 | } __packed; | 4564 | } __packed; |
4560 | 4565 | ||
4566 | struct wmi_vdev_stats_extd { | ||
4567 | __le32 vdev_id; | ||
4568 | __le32 ppdu_aggr_cnt; | ||
4569 | __le32 ppdu_noack; | ||
4570 | __le32 mpdu_queued; | ||
4571 | __le32 ppdu_nonaggr_cnt; | ||
4572 | __le32 mpdu_sw_requeued; | ||
4573 | __le32 mpdu_suc_retry; | ||
4574 | __le32 mpdu_suc_multitry; | ||
4575 | __le32 mpdu_fail_retry; | ||
4576 | __le32 tx_ftm_suc; | ||
4577 | __le32 tx_ftm_suc_retry; | ||
4578 | __le32 tx_ftm_fail; | ||
4579 | __le32 rx_ftmr_cnt; | ||
4580 | __le32 rx_ftmr_dup_cnt; | ||
4581 | __le32 rx_iftmr_cnt; | ||
4582 | __le32 rx_iftmr_dup_cnt; | ||
4583 | __le32 reserved[6]; | ||
4584 | } __packed; | ||
4585 | |||
4561 | /* | 4586 | /* |
4562 | * peer statistics. | 4587 | * peer statistics. |
4563 | * TODO: add more stats | 4588 | * TODO: add more stats |
@@ -6792,6 +6817,7 @@ enum wmi_tdls_state { | |||
6792 | WMI_TDLS_DISABLE, | 6817 | WMI_TDLS_DISABLE, |
6793 | WMI_TDLS_ENABLE_PASSIVE, | 6818 | WMI_TDLS_ENABLE_PASSIVE, |
6794 | WMI_TDLS_ENABLE_ACTIVE, | 6819 | WMI_TDLS_ENABLE_ACTIVE, |
6820 | WMI_TDLS_ENABLE_ACTIVE_EXTERNAL_CONTROL, | ||
6795 | }; | 6821 | }; |
6796 | 6822 | ||
6797 | enum wmi_tdls_peer_state { | 6823 | enum wmi_tdls_peer_state { |
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index 233054bd6b52..12d3a6c92ba4 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c | |||
@@ -327,7 +327,7 @@ int ath5k_hw_init(struct ath5k_hw *ah) | |||
327 | ath5k_hw_set_lladdr(ah, zero_mac); | 327 | ath5k_hw_set_lladdr(ah, zero_mac); |
328 | 328 | ||
329 | /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ | 329 | /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ |
330 | memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN); | 330 | eth_broadcast_addr(common->curbssid); |
331 | ath5k_hw_set_bssid(ah); | 331 | ath5k_hw_set_bssid(ah); |
332 | ath5k_hw_set_opmode(ah, ah->opmode); | 332 | ath5k_hw_set_opmode(ah, ah->opmode); |
333 | 333 | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index f246e9ed4a81..214c68269a69 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -591,7 +591,7 @@ static void ath9k_init_misc(struct ath9k_htc_priv *priv) | |||
591 | { | 591 | { |
592 | struct ath_common *common = ath9k_hw_common(priv->ah); | 592 | struct ath_common *common = ath9k_hw_common(priv->ah); |
593 | 593 | ||
594 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); | 594 | eth_broadcast_addr(common->bssidmask); |
595 | 595 | ||
596 | common->last_rssi = ATH_RSSI_DUMMY_MARKER; | 596 | common->last_rssi = ATH_RSSI_DUMMY_MARKER; |
597 | priv->ah->opmode = NL80211_IFTYPE_STATION; | 597 | priv->ah->opmode = NL80211_IFTYPE_STATION; |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index e479fae5aab9..c070a9e51ebf 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -257,6 +257,11 @@ static void ath9k_reg_notifier(struct wiphy *wiphy, | |||
257 | 257 | ||
258 | ath_reg_notifier_apply(wiphy, request, reg); | 258 | ath_reg_notifier_apply(wiphy, request, reg); |
259 | 259 | ||
260 | /* synchronize DFS detector if regulatory domain changed */ | ||
261 | if (sc->dfs_detector != NULL) | ||
262 | sc->dfs_detector->set_dfs_domain(sc->dfs_detector, | ||
263 | request->dfs_region); | ||
264 | |||
260 | /* Set tx power */ | 265 | /* Set tx power */ |
261 | if (!ah->curchan) | 266 | if (!ah->curchan) |
262 | return; | 267 | return; |
@@ -267,10 +272,6 @@ static void ath9k_reg_notifier(struct wiphy *wiphy, | |||
267 | ath9k_cmn_update_txpow(ah, sc->cur_chan->cur_txpower, | 272 | ath9k_cmn_update_txpow(ah, sc->cur_chan->cur_txpower, |
268 | sc->cur_chan->txpower, | 273 | sc->cur_chan->txpower, |
269 | &sc->cur_chan->cur_txpower); | 274 | &sc->cur_chan->cur_txpower); |
270 | /* synchronize DFS detector if regulatory domain changed */ | ||
271 | if (sc->dfs_detector != NULL) | ||
272 | sc->dfs_detector->set_dfs_domain(sc->dfs_detector, | ||
273 | request->dfs_region); | ||
274 | ath9k_ps_restore(sc); | 275 | ath9k_ps_restore(sc); |
275 | } | 276 | } |
276 | 277 | ||
@@ -427,7 +428,7 @@ static void ath9k_init_misc(struct ath_softc *sc) | |||
427 | timer_setup(&common->ani.timer, ath_ani_calibrate, 0); | 428 | timer_setup(&common->ani.timer, ath_ani_calibrate, 0); |
428 | 429 | ||
429 | common->last_rssi = ATH_RSSI_DUMMY_MARKER; | 430 | common->last_rssi = ATH_RSSI_DUMMY_MARKER; |
430 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); | 431 | eth_broadcast_addr(common->bssidmask); |
431 | sc->beacon.slottime = 9; | 432 | sc->beacon.slottime = 9; |
432 | 433 | ||
433 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) | 434 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) |
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c b/drivers/net/wireless/ath/wcn36xx/dxe.c index 7d5ecaf02288..2c3b899a88fa 100644 --- a/drivers/net/wireless/ath/wcn36xx/dxe.c +++ b/drivers/net/wireless/ath/wcn36xx/dxe.c | |||
@@ -27,15 +27,6 @@ | |||
27 | #include "wcn36xx.h" | 27 | #include "wcn36xx.h" |
28 | #include "txrx.h" | 28 | #include "txrx.h" |
29 | 29 | ||
30 | void *wcn36xx_dxe_get_next_bd(struct wcn36xx *wcn, bool is_low) | ||
31 | { | ||
32 | struct wcn36xx_dxe_ch *ch = is_low ? | ||
33 | &wcn->dxe_tx_l_ch : | ||
34 | &wcn->dxe_tx_h_ch; | ||
35 | |||
36 | return ch->head_blk_ctl->bd_cpu_addr; | ||
37 | } | ||
38 | |||
39 | static void wcn36xx_ccu_write_register(struct wcn36xx *wcn, int addr, int data) | 30 | static void wcn36xx_ccu_write_register(struct wcn36xx *wcn, int addr, int data) |
40 | { | 31 | { |
41 | wcn36xx_dbg(WCN36XX_DBG_DXE, | 32 | wcn36xx_dbg(WCN36XX_DBG_DXE, |
@@ -648,6 +639,7 @@ void wcn36xx_dxe_free_mem_pools(struct wcn36xx *wcn) | |||
648 | 639 | ||
649 | int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn, | 640 | int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn, |
650 | struct wcn36xx_vif *vif_priv, | 641 | struct wcn36xx_vif *vif_priv, |
642 | struct wcn36xx_tx_bd *bd, | ||
651 | struct sk_buff *skb, | 643 | struct sk_buff *skb, |
652 | bool is_low) | 644 | bool is_low) |
653 | { | 645 | { |
@@ -681,6 +673,9 @@ int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn, | |||
681 | ctl->skb = NULL; | 673 | ctl->skb = NULL; |
682 | desc = ctl->desc; | 674 | desc = ctl->desc; |
683 | 675 | ||
676 | /* write buffer descriptor */ | ||
677 | memcpy(ctl->bd_cpu_addr, bd, sizeof(*bd)); | ||
678 | |||
684 | /* Set source address of the BD we send */ | 679 | /* Set source address of the BD we send */ |
685 | desc->src_addr_l = ctl->bd_phy_addr; | 680 | desc->src_addr_l = ctl->bd_phy_addr; |
686 | 681 | ||
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.h b/drivers/net/wireless/ath/wcn36xx/dxe.h index 2bc376c5391b..ce580960d109 100644 --- a/drivers/net/wireless/ath/wcn36xx/dxe.h +++ b/drivers/net/wireless/ath/wcn36xx/dxe.h | |||
@@ -452,6 +452,7 @@ struct wcn36xx_dxe_mem_pool { | |||
452 | dma_addr_t phy_addr; | 452 | dma_addr_t phy_addr; |
453 | }; | 453 | }; |
454 | 454 | ||
455 | struct wcn36xx_tx_bd; | ||
455 | struct wcn36xx_vif; | 456 | struct wcn36xx_vif; |
456 | int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn); | 457 | int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn); |
457 | void wcn36xx_dxe_free_mem_pools(struct wcn36xx *wcn); | 458 | void wcn36xx_dxe_free_mem_pools(struct wcn36xx *wcn); |
@@ -463,8 +464,8 @@ void wcn36xx_dxe_deinit(struct wcn36xx *wcn); | |||
463 | int wcn36xx_dxe_init_channels(struct wcn36xx *wcn); | 464 | int wcn36xx_dxe_init_channels(struct wcn36xx *wcn); |
464 | int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn, | 465 | int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn, |
465 | struct wcn36xx_vif *vif_priv, | 466 | struct wcn36xx_vif *vif_priv, |
467 | struct wcn36xx_tx_bd *bd, | ||
466 | struct sk_buff *skb, | 468 | struct sk_buff *skb, |
467 | bool is_low); | 469 | bool is_low); |
468 | void wcn36xx_dxe_tx_ack_ind(struct wcn36xx *wcn, u32 status); | 470 | void wcn36xx_dxe_tx_ack_ind(struct wcn36xx *wcn, u32 status); |
469 | void *wcn36xx_dxe_get_next_bd(struct wcn36xx *wcn, bool is_low); | ||
470 | #endif /* _DXE_H_ */ | 471 | #endif /* _DXE_H_ */ |
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index 621e72b6ec99..69d6be59d97f 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c | |||
@@ -1152,8 +1152,6 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn) | |||
1152 | wcn->hw->wiphy->cipher_suites = cipher_suites; | 1152 | wcn->hw->wiphy->cipher_suites = cipher_suites; |
1153 | wcn->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); | 1153 | wcn->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); |
1154 | 1154 | ||
1155 | wcn->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; | ||
1156 | |||
1157 | #ifdef CONFIG_PM | 1155 | #ifdef CONFIG_PM |
1158 | wcn->hw->wiphy->wowlan = &wowlan_support; | 1156 | wcn->hw->wiphy->wowlan = &wowlan_support; |
1159 | #endif | 1157 | #endif |
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c index def6b23b777f..8932af5e4d8d 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.c +++ b/drivers/net/wireless/ath/wcn36xx/smd.c | |||
@@ -2411,54 +2411,63 @@ static void wcn36xx_ind_smd_work(struct work_struct *work) | |||
2411 | { | 2411 | { |
2412 | struct wcn36xx *wcn = | 2412 | struct wcn36xx *wcn = |
2413 | container_of(work, struct wcn36xx, hal_ind_work); | 2413 | container_of(work, struct wcn36xx, hal_ind_work); |
2414 | struct wcn36xx_hal_msg_header *msg_header; | ||
2415 | struct wcn36xx_hal_ind_msg *hal_ind_msg; | ||
2416 | unsigned long flags; | ||
2417 | 2414 | ||
2418 | spin_lock_irqsave(&wcn->hal_ind_lock, flags); | 2415 | for (;;) { |
2416 | struct wcn36xx_hal_msg_header *msg_header; | ||
2417 | struct wcn36xx_hal_ind_msg *hal_ind_msg; | ||
2418 | unsigned long flags; | ||
2419 | 2419 | ||
2420 | hal_ind_msg = list_first_entry(&wcn->hal_ind_queue, | 2420 | spin_lock_irqsave(&wcn->hal_ind_lock, flags); |
2421 | struct wcn36xx_hal_ind_msg, | ||
2422 | list); | ||
2423 | list_del(wcn->hal_ind_queue.next); | ||
2424 | spin_unlock_irqrestore(&wcn->hal_ind_lock, flags); | ||
2425 | 2421 | ||
2426 | msg_header = (struct wcn36xx_hal_msg_header *)hal_ind_msg->msg; | 2422 | if (list_empty(&wcn->hal_ind_queue)) { |
2423 | spin_unlock_irqrestore(&wcn->hal_ind_lock, flags); | ||
2424 | return; | ||
2425 | } | ||
2427 | 2426 | ||
2428 | switch (msg_header->msg_type) { | 2427 | hal_ind_msg = list_first_entry(&wcn->hal_ind_queue, |
2429 | case WCN36XX_HAL_COEX_IND: | 2428 | struct wcn36xx_hal_ind_msg, |
2430 | case WCN36XX_HAL_DEL_BA_IND: | 2429 | list); |
2431 | case WCN36XX_HAL_AVOID_FREQ_RANGE_IND: | 2430 | list_del(&hal_ind_msg->list); |
2432 | break; | 2431 | spin_unlock_irqrestore(&wcn->hal_ind_lock, flags); |
2433 | case WCN36XX_HAL_OTA_TX_COMPL_IND: | 2432 | |
2434 | wcn36xx_smd_tx_compl_ind(wcn, | 2433 | msg_header = (struct wcn36xx_hal_msg_header *)hal_ind_msg->msg; |
2435 | hal_ind_msg->msg, | 2434 | |
2436 | hal_ind_msg->msg_len); | 2435 | switch (msg_header->msg_type) { |
2437 | break; | 2436 | case WCN36XX_HAL_COEX_IND: |
2438 | case WCN36XX_HAL_MISSED_BEACON_IND: | 2437 | case WCN36XX_HAL_DEL_BA_IND: |
2439 | wcn36xx_smd_missed_beacon_ind(wcn, | 2438 | case WCN36XX_HAL_AVOID_FREQ_RANGE_IND: |
2440 | hal_ind_msg->msg, | 2439 | break; |
2441 | hal_ind_msg->msg_len); | 2440 | case WCN36XX_HAL_OTA_TX_COMPL_IND: |
2442 | break; | 2441 | wcn36xx_smd_tx_compl_ind(wcn, |
2443 | case WCN36XX_HAL_DELETE_STA_CONTEXT_IND: | 2442 | hal_ind_msg->msg, |
2444 | wcn36xx_smd_delete_sta_context_ind(wcn, | 2443 | hal_ind_msg->msg_len); |
2445 | hal_ind_msg->msg, | 2444 | break; |
2446 | hal_ind_msg->msg_len); | 2445 | case WCN36XX_HAL_MISSED_BEACON_IND: |
2447 | break; | 2446 | wcn36xx_smd_missed_beacon_ind(wcn, |
2448 | case WCN36XX_HAL_PRINT_REG_INFO_IND: | 2447 | hal_ind_msg->msg, |
2449 | wcn36xx_smd_print_reg_info_ind(wcn, | 2448 | hal_ind_msg->msg_len); |
2450 | hal_ind_msg->msg, | 2449 | break; |
2451 | hal_ind_msg->msg_len); | 2450 | case WCN36XX_HAL_DELETE_STA_CONTEXT_IND: |
2452 | break; | 2451 | wcn36xx_smd_delete_sta_context_ind(wcn, |
2453 | case WCN36XX_HAL_SCAN_OFFLOAD_IND: | 2452 | hal_ind_msg->msg, |
2454 | wcn36xx_smd_hw_scan_ind(wcn, hal_ind_msg->msg, | 2453 | hal_ind_msg->msg_len); |
2455 | hal_ind_msg->msg_len); | 2454 | break; |
2456 | break; | 2455 | case WCN36XX_HAL_PRINT_REG_INFO_IND: |
2457 | default: | 2456 | wcn36xx_smd_print_reg_info_ind(wcn, |
2458 | wcn36xx_err("SMD_EVENT (%d) not supported\n", | 2457 | hal_ind_msg->msg, |
2459 | msg_header->msg_type); | 2458 | hal_ind_msg->msg_len); |
2459 | break; | ||
2460 | case WCN36XX_HAL_SCAN_OFFLOAD_IND: | ||
2461 | wcn36xx_smd_hw_scan_ind(wcn, hal_ind_msg->msg, | ||
2462 | hal_ind_msg->msg_len); | ||
2463 | break; | ||
2464 | default: | ||
2465 | wcn36xx_err("SMD_EVENT (%d) not supported\n", | ||
2466 | msg_header->msg_type); | ||
2467 | } | ||
2468 | |||
2469 | kfree(hal_ind_msg); | ||
2460 | } | 2470 | } |
2461 | kfree(hal_ind_msg); | ||
2462 | } | 2471 | } |
2463 | int wcn36xx_smd_open(struct wcn36xx *wcn) | 2472 | int wcn36xx_smd_open(struct wcn36xx *wcn) |
2464 | { | 2473 | { |
diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.c b/drivers/net/wireless/ath/wcn36xx/txrx.c index 22304edc5948..b1768ed6b0be 100644 --- a/drivers/net/wireless/ath/wcn36xx/txrx.c +++ b/drivers/net/wireless/ath/wcn36xx/txrx.c | |||
@@ -272,21 +272,9 @@ int wcn36xx_start_tx(struct wcn36xx *wcn, | |||
272 | bool is_low = ieee80211_is_data(hdr->frame_control); | 272 | bool is_low = ieee80211_is_data(hdr->frame_control); |
273 | bool bcast = is_broadcast_ether_addr(hdr->addr1) || | 273 | bool bcast = is_broadcast_ether_addr(hdr->addr1) || |
274 | is_multicast_ether_addr(hdr->addr1); | 274 | is_multicast_ether_addr(hdr->addr1); |
275 | struct wcn36xx_tx_bd *bd = wcn36xx_dxe_get_next_bd(wcn, is_low); | 275 | struct wcn36xx_tx_bd bd; |
276 | |||
277 | if (!bd) { | ||
278 | /* | ||
279 | * TX DXE are used in pairs. One for the BD and one for the | ||
280 | * actual frame. The BD DXE's has a preallocated buffer while | ||
281 | * the skb ones does not. If this isn't true something is really | ||
282 | * wierd. TODO: Recover from this situation | ||
283 | */ | ||
284 | |||
285 | wcn36xx_err("bd address may not be NULL for BD DXE\n"); | ||
286 | return -EINVAL; | ||
287 | } | ||
288 | 276 | ||
289 | memset(bd, 0, sizeof(*bd)); | 277 | memset(&bd, 0, sizeof(bd)); |
290 | 278 | ||
291 | wcn36xx_dbg(WCN36XX_DBG_TX, | 279 | wcn36xx_dbg(WCN36XX_DBG_TX, |
292 | "tx skb %p len %d fc %04x sn %d %s %s\n", | 280 | "tx skb %p len %d fc %04x sn %d %s %s\n", |
@@ -296,10 +284,10 @@ int wcn36xx_start_tx(struct wcn36xx *wcn, | |||
296 | 284 | ||
297 | wcn36xx_dbg_dump(WCN36XX_DBG_TX_DUMP, "", skb->data, skb->len); | 285 | wcn36xx_dbg_dump(WCN36XX_DBG_TX_DUMP, "", skb->data, skb->len); |
298 | 286 | ||
299 | bd->dpu_rf = WCN36XX_BMU_WQ_TX; | 287 | bd.dpu_rf = WCN36XX_BMU_WQ_TX; |
300 | 288 | ||
301 | bd->tx_comp = !!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS); | 289 | bd.tx_comp = !!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS); |
302 | if (bd->tx_comp) { | 290 | if (bd.tx_comp) { |
303 | wcn36xx_dbg(WCN36XX_DBG_DXE, "TX_ACK status requested\n"); | 291 | wcn36xx_dbg(WCN36XX_DBG_DXE, "TX_ACK status requested\n"); |
304 | spin_lock_irqsave(&wcn->dxe_lock, flags); | 292 | spin_lock_irqsave(&wcn->dxe_lock, flags); |
305 | if (wcn->tx_ack_skb) { | 293 | if (wcn->tx_ack_skb) { |
@@ -321,13 +309,13 @@ int wcn36xx_start_tx(struct wcn36xx *wcn, | |||
321 | 309 | ||
322 | /* Data frames served first*/ | 310 | /* Data frames served first*/ |
323 | if (is_low) | 311 | if (is_low) |
324 | wcn36xx_set_tx_data(bd, wcn, &vif_priv, sta_priv, skb, bcast); | 312 | wcn36xx_set_tx_data(&bd, wcn, &vif_priv, sta_priv, skb, bcast); |
325 | else | 313 | else |
326 | /* MGMT and CTRL frames are handeld here*/ | 314 | /* MGMT and CTRL frames are handeld here*/ |
327 | wcn36xx_set_tx_mgmt(bd, wcn, &vif_priv, skb, bcast); | 315 | wcn36xx_set_tx_mgmt(&bd, wcn, &vif_priv, skb, bcast); |
328 | 316 | ||
329 | buff_to_be((u32 *)bd, sizeof(*bd)/sizeof(u32)); | 317 | buff_to_be((u32 *)&bd, sizeof(bd)/sizeof(u32)); |
330 | bd->tx_bd_sign = 0xbdbdbdbd; | 318 | bd.tx_bd_sign = 0xbdbdbdbd; |
331 | 319 | ||
332 | return wcn36xx_dxe_tx_frame(wcn, vif_priv, skb, is_low); | 320 | return wcn36xx_dxe_tx_frame(wcn, vif_priv, &bd, skb, is_low); |
333 | } | 321 | } |