diff options
25 files changed, 422 insertions, 225 deletions
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 39fe4f3350aa..2bdf5408b0d9 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c | |||
@@ -1139,7 +1139,7 @@ static ssize_t ath10k_read_htt_max_amsdu_ampdu(struct file *file, | |||
1139 | { | 1139 | { |
1140 | struct ath10k *ar = file->private_data; | 1140 | struct ath10k *ar = file->private_data; |
1141 | char buf[64]; | 1141 | char buf[64]; |
1142 | u8 amsdu = 3, ampdu = 64; | 1142 | u8 amsdu, ampdu; |
1143 | unsigned int len; | 1143 | unsigned int len; |
1144 | 1144 | ||
1145 | mutex_lock(&ar->conf_mutex); | 1145 | mutex_lock(&ar->conf_mutex); |
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index bcb364d5d49f..b4bdeb07a012 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c | |||
@@ -250,7 +250,8 @@ static int ath10k_install_peer_wep_keys(struct ath10k_vif *arvif, | |||
250 | lockdep_assert_held(&ar->conf_mutex); | 250 | lockdep_assert_held(&ar->conf_mutex); |
251 | 251 | ||
252 | if (WARN_ON(arvif->vif->type != NL80211_IFTYPE_AP && | 252 | if (WARN_ON(arvif->vif->type != NL80211_IFTYPE_AP && |
253 | arvif->vif->type != NL80211_IFTYPE_ADHOC)) | 253 | arvif->vif->type != NL80211_IFTYPE_ADHOC && |
254 | arvif->vif->type != NL80211_IFTYPE_MESH_POINT)) | ||
254 | return -EINVAL; | 255 | return -EINVAL; |
255 | 256 | ||
256 | spin_lock_bh(&ar->data_lock); | 257 | spin_lock_bh(&ar->data_lock); |
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 2a44d63a03cd..a7c3d299639b 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c | |||
@@ -4312,34 +4312,58 @@ void ath10k_wmi_event_vdev_resume_req(struct ath10k *ar, struct sk_buff *skb) | |||
4312 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_RESUME_REQ_EVENTID\n"); | 4312 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_RESUME_REQ_EVENTID\n"); |
4313 | } | 4313 | } |
4314 | 4314 | ||
4315 | static int ath10k_wmi_alloc_host_mem(struct ath10k *ar, u32 req_id, | 4315 | static int ath10k_wmi_alloc_chunk(struct ath10k *ar, u32 req_id, |
4316 | u32 num_units, u32 unit_len) | 4316 | u32 num_units, u32 unit_len) |
4317 | { | 4317 | { |
4318 | dma_addr_t paddr; | 4318 | dma_addr_t paddr; |
4319 | u32 pool_size; | 4319 | u32 pool_size = 0; |
4320 | int idx = ar->wmi.num_mem_chunks; | 4320 | int idx = ar->wmi.num_mem_chunks; |
4321 | void *vaddr = NULL; | ||
4321 | 4322 | ||
4322 | pool_size = num_units * round_up(unit_len, 4); | 4323 | if (ar->wmi.num_mem_chunks == ARRAY_SIZE(ar->wmi.mem_chunks)) |
4324 | return -ENOMEM; | ||
4323 | 4325 | ||
4324 | if (!pool_size) | 4326 | while (!vaddr && num_units) { |
4325 | return -EINVAL; | 4327 | pool_size = num_units * round_up(unit_len, 4); |
4328 | if (!pool_size) | ||
4329 | return -EINVAL; | ||
4326 | 4330 | ||
4327 | ar->wmi.mem_chunks[idx].vaddr = dma_alloc_coherent(ar->dev, | 4331 | vaddr = kzalloc(pool_size, GFP_KERNEL | __GFP_NOWARN); |
4328 | pool_size, | 4332 | if (!vaddr) |
4329 | &paddr, | 4333 | num_units /= 2; |
4330 | GFP_KERNEL); | ||
4331 | if (!ar->wmi.mem_chunks[idx].vaddr) { | ||
4332 | ath10k_warn(ar, "failed to allocate memory chunk\n"); | ||
4333 | return -ENOMEM; | ||
4334 | } | 4334 | } |
4335 | 4335 | ||
4336 | memset(ar->wmi.mem_chunks[idx].vaddr, 0, pool_size); | 4336 | if (!num_units) |
4337 | return -ENOMEM; | ||
4338 | |||
4339 | paddr = dma_map_single(ar->dev, vaddr, pool_size, DMA_TO_DEVICE); | ||
4340 | if (dma_mapping_error(ar->dev, paddr)) { | ||
4341 | kfree(vaddr); | ||
4342 | return -ENOMEM; | ||
4343 | } | ||
4337 | 4344 | ||
4345 | ar->wmi.mem_chunks[idx].vaddr = vaddr; | ||
4338 | ar->wmi.mem_chunks[idx].paddr = paddr; | 4346 | ar->wmi.mem_chunks[idx].paddr = paddr; |
4339 | ar->wmi.mem_chunks[idx].len = pool_size; | 4347 | ar->wmi.mem_chunks[idx].len = pool_size; |
4340 | ar->wmi.mem_chunks[idx].req_id = req_id; | 4348 | ar->wmi.mem_chunks[idx].req_id = req_id; |
4341 | ar->wmi.num_mem_chunks++; | 4349 | ar->wmi.num_mem_chunks++; |
4342 | 4350 | ||
4351 | return num_units; | ||
4352 | } | ||
4353 | |||
4354 | static int ath10k_wmi_alloc_host_mem(struct ath10k *ar, u32 req_id, | ||
4355 | u32 num_units, u32 unit_len) | ||
4356 | { | ||
4357 | int ret; | ||
4358 | |||
4359 | while (num_units) { | ||
4360 | ret = ath10k_wmi_alloc_chunk(ar, req_id, num_units, unit_len); | ||
4361 | if (ret < 0) | ||
4362 | return ret; | ||
4363 | |||
4364 | num_units -= ret; | ||
4365 | } | ||
4366 | |||
4343 | return 0; | 4367 | return 0; |
4344 | } | 4368 | } |
4345 | 4369 | ||
@@ -7717,10 +7741,11 @@ void ath10k_wmi_free_host_mem(struct ath10k *ar) | |||
7717 | 7741 | ||
7718 | /* free the host memory chunks requested by firmware */ | 7742 | /* free the host memory chunks requested by firmware */ |
7719 | for (i = 0; i < ar->wmi.num_mem_chunks; i++) { | 7743 | for (i = 0; i < ar->wmi.num_mem_chunks; i++) { |
7720 | dma_free_coherent(ar->dev, | 7744 | dma_unmap_single(ar->dev, |
7721 | ar->wmi.mem_chunks[i].len, | 7745 | ar->wmi.mem_chunks[i].paddr, |
7722 | ar->wmi.mem_chunks[i].vaddr, | 7746 | ar->wmi.mem_chunks[i].len, |
7723 | ar->wmi.mem_chunks[i].paddr); | 7747 | DMA_TO_DEVICE); |
7748 | kfree(ar->wmi.mem_chunks[i].vaddr); | ||
7724 | } | 7749 | } |
7725 | 7750 | ||
7726 | ar->wmi.num_mem_chunks = 0; | 7751 | ar->wmi.num_mem_chunks = 0; |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 342563a3706f..3d946d8b2db2 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -767,7 +767,7 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf, | |||
767 | if (info->flags & IEEE80211_TX_CTL_NO_ACK) | 767 | if (info->flags & IEEE80211_TX_CTL_NO_ACK) |
768 | flags |= AR5K_TXDESC_NOACK; | 768 | flags |= AR5K_TXDESC_NOACK; |
769 | 769 | ||
770 | rc_flags = info->control.rates[0].flags; | 770 | rc_flags = bf->rates[0].flags; |
771 | 771 | ||
772 | hw_rate = ath5k_get_rate_hw_value(ah->hw, info, bf, 0); | 772 | hw_rate = ath5k_get_rate_hw_value(ah->hw, info, bf, 0); |
773 | 773 | ||
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 81ac8c59f0ec..7f3f94fbf157 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c | |||
@@ -3930,8 +3930,8 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) | |||
3930 | ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff; | 3930 | ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff; |
3931 | ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff; | 3931 | ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff; |
3932 | ath6kl_band_5ghz.ht_cap.mcs.rx_mask[1] = 0xff; | 3932 | ath6kl_band_5ghz.ht_cap.mcs.rx_mask[1] = 0xff; |
3933 | ar->hw.tx_ant = 2; | 3933 | ar->hw.tx_ant = 0x3; /* mask, 2 antenna */ |
3934 | ar->hw.rx_ant = 2; | 3934 | ar->hw.rx_ant = 0x3; |
3935 | } else { | 3935 | } else { |
3936 | ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff; | 3936 | ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff; |
3937 | ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff; | 3937 | ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff; |
diff --git a/drivers/net/wireless/ath/ath6kl/htc_mbox.c b/drivers/net/wireless/ath/ath6kl/htc_mbox.c index fffb65b3e652..65c31da43c47 100644 --- a/drivers/net/wireless/ath/ath6kl/htc_mbox.c +++ b/drivers/net/wireless/ath/ath6kl/htc_mbox.c | |||
@@ -2222,8 +2222,9 @@ int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target, | |||
2222 | } | 2222 | } |
2223 | 2223 | ||
2224 | if (status) { | 2224 | if (status) { |
2225 | ath6kl_err("failed to get pending recv messages: %d\n", | 2225 | if (status != -ECANCELED) |
2226 | status); | 2226 | ath6kl_err("failed to get pending recv messages: %d\n", |
2227 | status); | ||
2227 | 2228 | ||
2228 | /* cleanup any packets in sync completion queue */ | 2229 | /* cleanup any packets in sync completion queue */ |
2229 | list_for_each_entry_safe(packets, tmp_pkt, &comp_pktq, list) { | 2230 | list_for_each_entry_safe(packets, tmp_pkt, &comp_pktq, list) { |
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 6ae0734f86e0..da557dc742e6 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c | |||
@@ -954,8 +954,10 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name) | |||
954 | snprintf(filename, sizeof(filename), "%s/%s", ar->hw.fw.dir, name); | 954 | snprintf(filename, sizeof(filename), "%s/%s", ar->hw.fw.dir, name); |
955 | 955 | ||
956 | ret = request_firmware(&fw, filename, ar->dev); | 956 | ret = request_firmware(&fw, filename, ar->dev); |
957 | if (ret) | 957 | if (ret) { |
958 | ath6kl_err("Failed request firmware, rv: %d\n", ret); | ||
958 | return ret; | 959 | return ret; |
960 | } | ||
959 | 961 | ||
960 | data = fw->data; | 962 | data = fw->data; |
961 | len = fw->size; | 963 | len = fw->size; |
@@ -964,11 +966,15 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name) | |||
964 | magic_len = strlen(ATH6KL_FIRMWARE_MAGIC) + 1; | 966 | magic_len = strlen(ATH6KL_FIRMWARE_MAGIC) + 1; |
965 | 967 | ||
966 | if (len < magic_len) { | 968 | if (len < magic_len) { |
969 | ath6kl_err("Magic length is invalid, len: %zd magic_len: %zd\n", | ||
970 | len, magic_len); | ||
967 | ret = -EINVAL; | 971 | ret = -EINVAL; |
968 | goto out; | 972 | goto out; |
969 | } | 973 | } |
970 | 974 | ||
971 | if (memcmp(data, ATH6KL_FIRMWARE_MAGIC, magic_len) != 0) { | 975 | if (memcmp(data, ATH6KL_FIRMWARE_MAGIC, magic_len) != 0) { |
976 | ath6kl_err("Magic is invalid, magic_len: %zd\n", | ||
977 | magic_len); | ||
972 | ret = -EINVAL; | 978 | ret = -EINVAL; |
973 | goto out; | 979 | goto out; |
974 | } | 980 | } |
@@ -987,7 +993,12 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name) | |||
987 | len -= sizeof(*hdr); | 993 | len -= sizeof(*hdr); |
988 | data += sizeof(*hdr); | 994 | data += sizeof(*hdr); |
989 | 995 | ||
996 | ath6kl_dbg(ATH6KL_DBG_BOOT, "ie-id: %d len: %zd (0x%zx)\n", | ||
997 | ie_id, ie_len, ie_len); | ||
998 | |||
990 | if (len < ie_len) { | 999 | if (len < ie_len) { |
1000 | ath6kl_err("IE len is invalid, len: %zd ie_len: %zd ie-id: %d\n", | ||
1001 | len, ie_len, ie_id); | ||
991 | ret = -EINVAL; | 1002 | ret = -EINVAL; |
992 | goto out; | 1003 | goto out; |
993 | } | 1004 | } |
@@ -1008,6 +1019,7 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name) | |||
1008 | ar->fw_otp = kmemdup(data, ie_len, GFP_KERNEL); | 1019 | ar->fw_otp = kmemdup(data, ie_len, GFP_KERNEL); |
1009 | 1020 | ||
1010 | if (ar->fw_otp == NULL) { | 1021 | if (ar->fw_otp == NULL) { |
1022 | ath6kl_err("fw_otp cannot be allocated\n"); | ||
1011 | ret = -ENOMEM; | 1023 | ret = -ENOMEM; |
1012 | goto out; | 1024 | goto out; |
1013 | } | 1025 | } |
@@ -1025,6 +1037,7 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name) | |||
1025 | ar->fw = vmalloc(ie_len); | 1037 | ar->fw = vmalloc(ie_len); |
1026 | 1038 | ||
1027 | if (ar->fw == NULL) { | 1039 | if (ar->fw == NULL) { |
1040 | ath6kl_err("fw storage cannot be allocated, len: %zd\n", ie_len); | ||
1028 | ret = -ENOMEM; | 1041 | ret = -ENOMEM; |
1029 | goto out; | 1042 | goto out; |
1030 | } | 1043 | } |
@@ -1039,6 +1052,7 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name) | |||
1039 | ar->fw_patch = kmemdup(data, ie_len, GFP_KERNEL); | 1052 | ar->fw_patch = kmemdup(data, ie_len, GFP_KERNEL); |
1040 | 1053 | ||
1041 | if (ar->fw_patch == NULL) { | 1054 | if (ar->fw_patch == NULL) { |
1055 | ath6kl_err("fw_patch storage cannot be allocated, len: %zd\n", ie_len); | ||
1042 | ret = -ENOMEM; | 1056 | ret = -ENOMEM; |
1043 | goto out; | 1057 | goto out; |
1044 | } | 1058 | } |
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index fee0cadb0f5e..40fa915d6f35 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig | |||
@@ -176,3 +176,14 @@ config ATH9K_HTC_DEBUGFS | |||
176 | depends on ATH9K_HTC && DEBUG_FS | 176 | depends on ATH9K_HTC && DEBUG_FS |
177 | ---help--- | 177 | ---help--- |
178 | Say Y, if you need access to ath9k_htc's statistics. | 178 | Say Y, if you need access to ath9k_htc's statistics. |
179 | |||
180 | config ATH9K_HWRNG | ||
181 | bool "Random number generator support" | ||
182 | depends on ATH9K && (HW_RANDOM = y || HW_RANDOM = ATH9K) | ||
183 | default y | ||
184 | ---help--- | ||
185 | This option incorporates the ADC register output as a source of | ||
186 | randomness into Linux entropy pool (/dev/urandom and /dev/random) | ||
187 | |||
188 | Say Y, feeds the entropy directly from the WiFi driver to the input | ||
189 | pool. | ||
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index ecda613c2d54..76f9dc37500b 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile | |||
@@ -15,6 +15,7 @@ ath9k-$(CONFIG_ATH9K_DFS_DEBUGFS) += dfs_debug.o | |||
15 | ath9k-$(CONFIG_ATH9K_DFS_CERTIFIED) += dfs.o | 15 | ath9k-$(CONFIG_ATH9K_DFS_CERTIFIED) += dfs.o |
16 | ath9k-$(CONFIG_ATH9K_TX99) += tx99.o | 16 | ath9k-$(CONFIG_ATH9K_TX99) += tx99.o |
17 | ath9k-$(CONFIG_ATH9K_WOW) += wow.o | 17 | ath9k-$(CONFIG_ATH9K_WOW) += wow.o |
18 | ath9k-$(CONFIG_ATH9K_HWRNG) += rng.o | ||
18 | 19 | ||
19 | ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o | 20 | ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o |
20 | 21 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index b42f4a963ef4..5294595da5a7 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/leds.h> | 23 | #include <linux/leds.h> |
24 | #include <linux/completion.h> | 24 | #include <linux/completion.h> |
25 | #include <linux/time.h> | 25 | #include <linux/time.h> |
26 | #include <linux/hw_random.h> | ||
26 | 27 | ||
27 | #include "common.h" | 28 | #include "common.h" |
28 | #include "debug.h" | 29 | #include "debug.h" |
@@ -981,6 +982,7 @@ struct ath_softc { | |||
981 | struct ath_offchannel offchannel; | 982 | struct ath_offchannel offchannel; |
982 | struct ath_chanctx *next_chan; | 983 | struct ath_chanctx *next_chan; |
983 | struct completion go_beacon; | 984 | struct completion go_beacon; |
985 | struct timespec last_event_time; | ||
984 | #endif | 986 | #endif |
985 | 987 | ||
986 | unsigned long driver_data; | 988 | unsigned long driver_data; |
@@ -1040,6 +1042,11 @@ struct ath_softc { | |||
1040 | u32 wow_intr_before_sleep; | 1042 | u32 wow_intr_before_sleep; |
1041 | bool force_wow; | 1043 | bool force_wow; |
1042 | #endif | 1044 | #endif |
1045 | |||
1046 | #ifdef CONFIG_ATH9K_HWRNG | ||
1047 | u32 rng_last; | ||
1048 | struct task_struct *rng_task; | ||
1049 | #endif | ||
1043 | }; | 1050 | }; |
1044 | 1051 | ||
1045 | /********/ | 1052 | /********/ |
@@ -1062,6 +1069,22 @@ static inline int ath9k_tx99_send(struct ath_softc *sc, | |||
1062 | } | 1069 | } |
1063 | #endif /* CONFIG_ATH9K_TX99 */ | 1070 | #endif /* CONFIG_ATH9K_TX99 */ |
1064 | 1071 | ||
1072 | /***************************/ | ||
1073 | /* Random Number Generator */ | ||
1074 | /***************************/ | ||
1075 | #ifdef CONFIG_ATH9K_HWRNG | ||
1076 | void ath9k_rng_start(struct ath_softc *sc); | ||
1077 | void ath9k_rng_stop(struct ath_softc *sc); | ||
1078 | #else | ||
1079 | static inline void ath9k_rng_start(struct ath_softc *sc) | ||
1080 | { | ||
1081 | } | ||
1082 | |||
1083 | static inline void ath9k_rng_stop(struct ath_softc *sc) | ||
1084 | { | ||
1085 | } | ||
1086 | #endif | ||
1087 | |||
1065 | static inline void ath_read_cachesize(struct ath_common *common, int *csz) | 1088 | static inline void ath_read_cachesize(struct ath_common *common, int *csz) |
1066 | { | 1089 | { |
1067 | common->bus_ops->read_cachesize(common, csz); | 1090 | common->bus_ops->read_cachesize(common, csz); |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index f50a6bc5d06e..5cf0cd7cb2d1 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -148,7 +148,8 @@ static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw, | |||
148 | 148 | ||
149 | ath_assign_seq(common, skb); | 149 | ath_assign_seq(common, skb); |
150 | 150 | ||
151 | if (vif->p2p) | 151 | /* Always assign NOA attr when MCC enabled */ |
152 | if (ath9k_is_chanctx_enabled()) | ||
152 | ath9k_beacon_add_noa(sc, avp, skb); | 153 | ath9k_beacon_add_noa(sc, avp, skb); |
153 | 154 | ||
154 | bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, | 155 | bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, |
diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 90f5773a1a61..50e614b915f1 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c | |||
@@ -226,6 +226,20 @@ static const char *chanctx_state_string(enum ath_chanctx_state state) | |||
226 | } | 226 | } |
227 | } | 227 | } |
228 | 228 | ||
229 | static const u32 chanctx_event_delta(struct ath_softc *sc) | ||
230 | { | ||
231 | u64 ms; | ||
232 | struct timespec ts, *old; | ||
233 | |||
234 | getrawmonotonic(&ts); | ||
235 | old = &sc->last_event_time; | ||
236 | ms = ts.tv_sec * 1000 + ts.tv_nsec / 1000000; | ||
237 | ms -= old->tv_sec * 1000 + old->tv_nsec / 1000000; | ||
238 | sc->last_event_time = ts; | ||
239 | |||
240 | return (u32)ms; | ||
241 | } | ||
242 | |||
229 | void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx) | 243 | void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx) |
230 | { | 244 | { |
231 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 245 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
@@ -356,14 +370,16 @@ static void ath_chanctx_setup_timer(struct ath_softc *sc, u32 tsf_time) | |||
356 | { | 370 | { |
357 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 371 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
358 | struct ath_hw *ah = sc->sc_ah; | 372 | struct ath_hw *ah = sc->sc_ah; |
373 | unsigned long timeout; | ||
359 | 374 | ||
360 | ath9k_hw_gen_timer_start(ah, sc->p2p_ps_timer, tsf_time, 1000000); | 375 | ath9k_hw_gen_timer_start(ah, sc->p2p_ps_timer, tsf_time, 1000000); |
361 | tsf_time -= ath9k_hw_gettsf32(ah); | 376 | tsf_time -= ath9k_hw_gettsf32(ah); |
362 | tsf_time = msecs_to_jiffies(tsf_time / 1000) + 1; | 377 | timeout = msecs_to_jiffies(tsf_time / 1000) + 1; |
363 | mod_timer(&sc->sched.timer, jiffies + tsf_time); | 378 | mod_timer(&sc->sched.timer, jiffies + timeout); |
364 | 379 | ||
365 | ath_dbg(common, CHAN_CTX, | 380 | ath_dbg(common, CHAN_CTX, |
366 | "Setup chanctx timer with timeout: %d ms\n", jiffies_to_msecs(tsf_time)); | 381 | "Setup chanctx timer with timeout: %d (%d) ms\n", |
382 | tsf_time / 1000, jiffies_to_msecs(timeout)); | ||
367 | } | 383 | } |
368 | 384 | ||
369 | static void ath_chanctx_handle_bmiss(struct ath_softc *sc, | 385 | static void ath_chanctx_handle_bmiss(struct ath_softc *sc, |
@@ -403,7 +419,7 @@ static void ath_chanctx_offchannel_noa(struct ath_softc *sc, | |||
403 | avp->offchannel_duration = sc->sched.offchannel_duration; | 419 | avp->offchannel_duration = sc->sched.offchannel_duration; |
404 | 420 | ||
405 | ath_dbg(common, CHAN_CTX, | 421 | ath_dbg(common, CHAN_CTX, |
406 | "offchannel noa_duration: %d, noa_start: %d, noa_index: %d\n", | 422 | "offchannel noa_duration: %d, noa_start: %u, noa_index: %d\n", |
407 | avp->offchannel_duration, | 423 | avp->offchannel_duration, |
408 | avp->offchannel_start, | 424 | avp->offchannel_start, |
409 | avp->noa_index); | 425 | avp->noa_index); |
@@ -443,7 +459,7 @@ static void ath_chanctx_set_periodic_noa(struct ath_softc *sc, | |||
443 | avp->periodic_noa = true; | 459 | avp->periodic_noa = true; |
444 | 460 | ||
445 | ath_dbg(common, CHAN_CTX, | 461 | ath_dbg(common, CHAN_CTX, |
446 | "noa_duration: %d, noa_start: %d, noa_index: %d, periodic: %d\n", | 462 | "noa_duration: %d, noa_start: %u, noa_index: %d, periodic: %d\n", |
447 | avp->noa_duration, | 463 | avp->noa_duration, |
448 | avp->noa_start, | 464 | avp->noa_start, |
449 | avp->noa_index, | 465 | avp->noa_index, |
@@ -464,7 +480,7 @@ static void ath_chanctx_set_oneshot_noa(struct ath_softc *sc, | |||
464 | avp->noa_duration = duration + sc->sched.channel_switch_time; | 480 | avp->noa_duration = duration + sc->sched.channel_switch_time; |
465 | 481 | ||
466 | ath_dbg(common, CHAN_CTX, | 482 | ath_dbg(common, CHAN_CTX, |
467 | "oneshot noa_duration: %d, noa_start: %d, noa_index: %d, periodic: %d\n", | 483 | "oneshot noa_duration: %d, noa_start: %u, noa_index: %d, periodic: %d\n", |
468 | avp->noa_duration, | 484 | avp->noa_duration, |
469 | avp->noa_start, | 485 | avp->noa_start, |
470 | avp->noa_index, | 486 | avp->noa_index, |
@@ -487,10 +503,11 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, | |||
487 | 503 | ||
488 | spin_lock_bh(&sc->chan_lock); | 504 | spin_lock_bh(&sc->chan_lock); |
489 | 505 | ||
490 | ath_dbg(common, CHAN_CTX, "cur_chan: %d MHz, event: %s, state: %s\n", | 506 | ath_dbg(common, CHAN_CTX, "cur_chan: %d MHz, event: %s, state: %s, delta: %u ms\n", |
491 | sc->cur_chan->chandef.center_freq1, | 507 | sc->cur_chan->chandef.center_freq1, |
492 | chanctx_event_string(ev), | 508 | chanctx_event_string(ev), |
493 | chanctx_state_string(sc->sched.state)); | 509 | chanctx_state_string(sc->sched.state), |
510 | chanctx_event_delta(sc)); | ||
494 | 511 | ||
495 | switch (ev) { | 512 | switch (ev) { |
496 | case ATH_CHANCTX_EVENT_BEACON_PREPARE: | 513 | case ATH_CHANCTX_EVENT_BEACON_PREPARE: |
@@ -1099,6 +1116,7 @@ ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp, | |||
1099 | nullfunc->frame_control |= | 1116 | nullfunc->frame_control |= |
1100 | cpu_to_le16(IEEE80211_FCTL_PM); | 1117 | cpu_to_le16(IEEE80211_FCTL_PM); |
1101 | 1118 | ||
1119 | skb->priority = 7; | ||
1102 | skb_set_queue_mapping(skb, IEEE80211_AC_VO); | 1120 | skb_set_queue_mapping(skb, IEEE80211_AC_VO); |
1103 | if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta)) { | 1121 | if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta)) { |
1104 | dev_kfree_skb_any(skb); | 1122 | dev_kfree_skb_any(skb); |
@@ -1401,8 +1419,9 @@ void ath9k_chanctx_wake_queues(struct ath_softc *sc, struct ath_chanctx *ctx) | |||
1401 | 1419 | ||
1402 | static void ath9k_update_p2p_ps_timer(struct ath_softc *sc, struct ath_vif *avp) | 1420 | static void ath9k_update_p2p_ps_timer(struct ath_softc *sc, struct ath_vif *avp) |
1403 | { | 1421 | { |
1422 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
1404 | struct ath_hw *ah = sc->sc_ah; | 1423 | struct ath_hw *ah = sc->sc_ah; |
1405 | s32 tsf, target_tsf; | 1424 | u32 tsf, target_tsf; |
1406 | 1425 | ||
1407 | if (!avp || !avp->noa.has_next_tsf) | 1426 | if (!avp || !avp->noa.has_next_tsf) |
1408 | return; | 1427 | return; |
@@ -1414,11 +1433,17 @@ static void ath9k_update_p2p_ps_timer(struct ath_softc *sc, struct ath_vif *avp) | |||
1414 | target_tsf = avp->noa.next_tsf; | 1433 | target_tsf = avp->noa.next_tsf; |
1415 | if (!avp->noa.absent) | 1434 | if (!avp->noa.absent) |
1416 | target_tsf -= ATH_P2P_PS_STOP_TIME; | 1435 | target_tsf -= ATH_P2P_PS_STOP_TIME; |
1436 | else | ||
1437 | target_tsf += ATH_P2P_PS_STOP_TIME; | ||
1417 | 1438 | ||
1418 | if (target_tsf - tsf < ATH_P2P_PS_STOP_TIME) | 1439 | if (target_tsf - tsf < ATH_P2P_PS_STOP_TIME) |
1419 | target_tsf = tsf + ATH_P2P_PS_STOP_TIME; | 1440 | target_tsf = tsf + ATH_P2P_PS_STOP_TIME; |
1420 | 1441 | ||
1421 | ath9k_hw_gen_timer_start(ah, sc->p2p_ps_timer, (u32) target_tsf, 1000000); | 1442 | ath_dbg(common, CHAN_CTX, "%s absent %d tsf 0x%08X next_tsf 0x%08X (%dms)\n", |
1443 | __func__, avp->noa.absent, tsf, target_tsf, | ||
1444 | (target_tsf - tsf) / 1000); | ||
1445 | |||
1446 | ath9k_hw_gen_timer_start(ah, sc->p2p_ps_timer, target_tsf, 1000000); | ||
1422 | } | 1447 | } |
1423 | 1448 | ||
1424 | static void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif) | 1449 | static void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif) |
@@ -1433,6 +1458,10 @@ static void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
1433 | return; | 1458 | return; |
1434 | 1459 | ||
1435 | sc->p2p_ps_vif = avp; | 1460 | sc->p2p_ps_vif = avp; |
1461 | |||
1462 | if (sc->ps_flags & PS_BEACON_SYNC) | ||
1463 | return; | ||
1464 | |||
1436 | tsf = ath9k_hw_gettsf32(sc->sc_ah); | 1465 | tsf = ath9k_hw_gettsf32(sc->sc_ah); |
1437 | ieee80211_parse_p2p_noa(&vif->bss_conf.p2p_noa_attr, &avp->noa, tsf); | 1466 | ieee80211_parse_p2p_noa(&vif->bss_conf.p2p_noa_attr, &avp->noa, tsf); |
1438 | ath9k_update_p2p_ps_timer(sc, avp); | 1467 | ath9k_update_p2p_ps_timer(sc, avp); |
@@ -1495,6 +1524,8 @@ void ath9k_beacon_add_noa(struct ath_softc *sc, struct ath_vif *avp, | |||
1495 | 1524 | ||
1496 | noa->index = avp->noa_index; | 1525 | noa->index = avp->noa_index; |
1497 | noa->oppps_ctwindow = ath9k_get_ctwin(sc, avp); | 1526 | noa->oppps_ctwindow = ath9k_get_ctwin(sc, avp); |
1527 | if (noa->oppps_ctwindow) | ||
1528 | noa->oppps_ctwindow |= BIT(7); | ||
1498 | 1529 | ||
1499 | if (avp->noa_duration) { | 1530 | if (avp->noa_duration) { |
1500 | if (avp->periodic_noa) { | 1531 | if (avp->periodic_noa) { |
@@ -1536,6 +1567,8 @@ void ath9k_p2p_ps_timer(void *priv) | |||
1536 | tsf = ath9k_hw_gettsf32(sc->sc_ah); | 1567 | tsf = ath9k_hw_gettsf32(sc->sc_ah); |
1537 | if (!avp->noa.absent) | 1568 | if (!avp->noa.absent) |
1538 | tsf += ATH_P2P_PS_STOP_TIME; | 1569 | tsf += ATH_P2P_PS_STOP_TIME; |
1570 | else | ||
1571 | tsf -= ATH_P2P_PS_STOP_TIME; | ||
1539 | 1572 | ||
1540 | if (!avp->noa.has_next_tsf || | 1573 | if (!avp->noa.has_next_tsf || |
1541 | avp->noa.next_tsf - tsf > BIT(31)) | 1574 | avp->noa.next_tsf - tsf > BIT(31)) |
@@ -1571,8 +1604,7 @@ void ath9k_p2p_bss_info_changed(struct ath_softc *sc, | |||
1571 | 1604 | ||
1572 | spin_lock_bh(&sc->sc_pcu_lock); | 1605 | spin_lock_bh(&sc->sc_pcu_lock); |
1573 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | 1606 | spin_lock_irqsave(&sc->sc_pm_lock, flags); |
1574 | if (!(sc->ps_flags & PS_BEACON_SYNC)) | 1607 | ath9k_update_p2p_ps(sc, vif); |
1575 | ath9k_update_p2p_ps(sc, vif); | ||
1576 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | 1608 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); |
1577 | spin_unlock_bh(&sc->sc_pcu_lock); | 1609 | spin_unlock_bh(&sc->sc_pcu_lock); |
1578 | } | 1610 | } |
diff --git a/drivers/net/wireless/ath/ath9k/common-beacon.c b/drivers/net/wireless/ath/ath9k/common-beacon.c index 6ad44470d0f2..01d6d3205a65 100644 --- a/drivers/net/wireless/ath/ath9k/common-beacon.c +++ b/drivers/net/wireless/ath/ath9k/common-beacon.c | |||
@@ -18,30 +18,16 @@ | |||
18 | 18 | ||
19 | #define FUDGE 2 | 19 | #define FUDGE 2 |
20 | 20 | ||
21 | /* Calculate the modulo of a 64 bit TSF snapshot with a TU divisor */ | ||
22 | static u32 ath9k_mod_tsf64_tu(u64 tsf, u32 div_tu) | ||
23 | { | ||
24 | u32 tsf_mod, tsf_hi, tsf_lo, mod_hi, mod_lo; | ||
25 | |||
26 | tsf_mod = tsf & (BIT(10) - 1); | ||
27 | tsf_hi = tsf >> 32; | ||
28 | tsf_lo = ((u32) tsf) >> 10; | ||
29 | |||
30 | mod_hi = tsf_hi % div_tu; | ||
31 | mod_lo = ((mod_hi << 22) + tsf_lo) % div_tu; | ||
32 | |||
33 | return (mod_lo << 10) | tsf_mod; | ||
34 | } | ||
35 | |||
36 | static u32 ath9k_get_next_tbtt(struct ath_hw *ah, u64 tsf, | 21 | static u32 ath9k_get_next_tbtt(struct ath_hw *ah, u64 tsf, |
37 | unsigned int interval) | 22 | unsigned int interval) |
38 | { | 23 | { |
39 | unsigned int offset; | 24 | unsigned int offset, divisor; |
40 | 25 | ||
41 | tsf += TU_TO_USEC(FUDGE + ah->config.sw_beacon_response_time); | 26 | tsf += TU_TO_USEC(FUDGE + ah->config.sw_beacon_response_time); |
42 | offset = ath9k_mod_tsf64_tu(tsf, interval); | 27 | divisor = TU_TO_USEC(interval); |
28 | div_u64_rem(tsf, divisor, &offset); | ||
43 | 29 | ||
44 | return (u32) tsf + TU_TO_USEC(interval) - offset; | 30 | return (u32) tsf + divisor - offset; |
45 | } | 31 | } |
46 | 32 | ||
47 | /* | 33 | /* |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index cc81482c934d..f8c5065e5f5f 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c | |||
@@ -138,6 +138,80 @@ bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data) | |||
138 | return ret; | 138 | return ret; |
139 | } | 139 | } |
140 | 140 | ||
141 | int ath9k_hw_nvram_swap_data(struct ath_hw *ah, bool *swap_needed, int size) | ||
142 | { | ||
143 | u16 magic; | ||
144 | u16 *eepdata; | ||
145 | int i; | ||
146 | struct ath_common *common = ath9k_hw_common(ah); | ||
147 | |||
148 | if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) { | ||
149 | ath_err(common, "Reading Magic # failed\n"); | ||
150 | return -EIO; | ||
151 | } | ||
152 | |||
153 | if (magic == AR5416_EEPROM_MAGIC) { | ||
154 | *swap_needed = false; | ||
155 | } else if (swab16(magic) == AR5416_EEPROM_MAGIC) { | ||
156 | if (ah->ah_flags & AH_NO_EEP_SWAP) { | ||
157 | ath_info(common, | ||
158 | "Ignoring endianness difference in EEPROM magic bytes.\n"); | ||
159 | |||
160 | *swap_needed = false; | ||
161 | } else { | ||
162 | *swap_needed = true; | ||
163 | } | ||
164 | } else { | ||
165 | ath_err(common, | ||
166 | "Invalid EEPROM Magic (0x%04x).\n", magic); | ||
167 | return -EINVAL; | ||
168 | } | ||
169 | |||
170 | eepdata = (u16 *)(&ah->eeprom); | ||
171 | |||
172 | if (*swap_needed) { | ||
173 | ath_dbg(common, EEPROM, | ||
174 | "EEPROM Endianness is not native.. Changing.\n"); | ||
175 | |||
176 | for (i = 0; i < size; i++) | ||
177 | eepdata[i] = swab16(eepdata[i]); | ||
178 | } | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | bool ath9k_hw_nvram_validate_checksum(struct ath_hw *ah, int size) | ||
184 | { | ||
185 | u32 i, sum = 0; | ||
186 | u16 *eepdata = (u16 *)(&ah->eeprom); | ||
187 | struct ath_common *common = ath9k_hw_common(ah); | ||
188 | |||
189 | for (i = 0; i < size; i++) | ||
190 | sum ^= eepdata[i]; | ||
191 | |||
192 | if (sum != 0xffff) { | ||
193 | ath_err(common, "Bad EEPROM checksum 0x%x\n", sum); | ||
194 | return false; | ||
195 | } | ||
196 | |||
197 | return true; | ||
198 | } | ||
199 | |||
200 | bool ath9k_hw_nvram_check_version(struct ath_hw *ah, int version, int minrev) | ||
201 | { | ||
202 | struct ath_common *common = ath9k_hw_common(ah); | ||
203 | |||
204 | if (ah->eep_ops->get_eeprom_ver(ah) != version || | ||
205 | ah->eep_ops->get_eeprom_rev(ah) < minrev) { | ||
206 | ath_err(common, "Bad EEPROM VER 0x%04x or REV 0x%04x\n", | ||
207 | ah->eep_ops->get_eeprom_ver(ah), | ||
208 | ah->eep_ops->get_eeprom_rev(ah)); | ||
209 | return -EINVAL; | ||
210 | } | ||
211 | |||
212 | return true; | ||
213 | } | ||
214 | |||
141 | void ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList, | 215 | void ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList, |
142 | u8 *pVpdList, u16 numIntercepts, | 216 | u8 *pVpdList, u16 numIntercepts, |
143 | u8 *pRetVpdList) | 217 | u8 *pRetVpdList) |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 40d4f62d0f16..4465c6566f20 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h | |||
@@ -664,6 +664,9 @@ int16_t ath9k_hw_interpolate(u16 target, u16 srcLeft, u16 srcRight, | |||
664 | bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, u16 listSize, | 664 | bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, u16 listSize, |
665 | u16 *indexL, u16 *indexR); | 665 | u16 *indexL, u16 *indexR); |
666 | bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data); | 666 | bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data); |
667 | int ath9k_hw_nvram_swap_data(struct ath_hw *ah, bool *swap_needed, int size); | ||
668 | bool ath9k_hw_nvram_validate_checksum(struct ath_hw *ah, int size); | ||
669 | bool ath9k_hw_nvram_check_version(struct ath_hw *ah, int version, int minrev); | ||
667 | void ath9k_hw_usb_gen_fill_eeprom(struct ath_hw *ah, u16 *eep_data, | 670 | void ath9k_hw_usb_gen_fill_eeprom(struct ath_hw *ah, u16 *eep_data, |
668 | int eep_start_loc, int size); | 671 | int eep_start_loc, int size); |
669 | void ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList, | 672 | void ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList, |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index 4773da6dc6f2..5da0826bf1be 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c | |||
@@ -177,74 +177,30 @@ static u32 ath9k_hw_4k_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, | |||
177 | } | 177 | } |
178 | #endif | 178 | #endif |
179 | 179 | ||
180 | |||
181 | #undef SIZE_EEPROM_4K | ||
182 | |||
183 | static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah) | 180 | static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah) |
184 | { | 181 | { |
185 | #define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16)) | ||
186 | struct ath_common *common = ath9k_hw_common(ah); | ||
187 | struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; | 182 | struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; |
188 | u16 *eepdata, temp, magic, magic2; | 183 | u32 el; |
189 | u32 sum = 0, el; | 184 | bool need_swap; |
190 | bool need_swap = false; | 185 | int i, err; |
191 | int i, addr; | ||
192 | 186 | ||
193 | 187 | err = ath9k_hw_nvram_swap_data(ah, &need_swap, SIZE_EEPROM_4K); | |
194 | if (!ath9k_hw_use_flash(ah)) { | 188 | if (err) |
195 | if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, | 189 | return err; |
196 | &magic)) { | ||
197 | ath_err(common, "Reading Magic # failed\n"); | ||
198 | return false; | ||
199 | } | ||
200 | |||
201 | ath_dbg(common, EEPROM, "Read Magic = 0x%04X\n", magic); | ||
202 | |||
203 | if (magic != AR5416_EEPROM_MAGIC) { | ||
204 | magic2 = swab16(magic); | ||
205 | |||
206 | if (magic2 == AR5416_EEPROM_MAGIC) { | ||
207 | need_swap = true; | ||
208 | eepdata = (u16 *) (&ah->eeprom); | ||
209 | |||
210 | for (addr = 0; addr < EEPROM_4K_SIZE; addr++) { | ||
211 | temp = swab16(*eepdata); | ||
212 | *eepdata = temp; | ||
213 | eepdata++; | ||
214 | } | ||
215 | } else { | ||
216 | ath_err(common, | ||
217 | "Invalid EEPROM Magic. Endianness mismatch.\n"); | ||
218 | return -EINVAL; | ||
219 | } | ||
220 | } | ||
221 | } | ||
222 | |||
223 | ath_dbg(common, EEPROM, "need_swap = %s\n", | ||
224 | need_swap ? "True" : "False"); | ||
225 | 190 | ||
226 | if (need_swap) | 191 | if (need_swap) |
227 | el = swab16(ah->eeprom.map4k.baseEepHeader.length); | 192 | el = swab16(eep->baseEepHeader.length); |
228 | else | ||
229 | el = ah->eeprom.map4k.baseEepHeader.length; | ||
230 | |||
231 | if (el > sizeof(struct ar5416_eeprom_4k)) | ||
232 | el = sizeof(struct ar5416_eeprom_4k) / sizeof(u16); | ||
233 | else | 193 | else |
234 | el = el / sizeof(u16); | 194 | el = eep->baseEepHeader.length; |
235 | 195 | ||
236 | eepdata = (u16 *)(&ah->eeprom); | 196 | el = min(el / sizeof(u16), SIZE_EEPROM_4K); |
237 | 197 | if (!ath9k_hw_nvram_validate_checksum(ah, el)) | |
238 | for (i = 0; i < el; i++) | 198 | return -EINVAL; |
239 | sum ^= *eepdata++; | ||
240 | 199 | ||
241 | if (need_swap) { | 200 | if (need_swap) { |
242 | u32 integer; | 201 | u32 integer; |
243 | u16 word; | 202 | u16 word; |
244 | 203 | ||
245 | ath_dbg(common, EEPROM, | ||
246 | "EEPROM Endianness is not native.. Changing\n"); | ||
247 | |||
248 | word = swab16(eep->baseEepHeader.length); | 204 | word = swab16(eep->baseEepHeader.length); |
249 | eep->baseEepHeader.length = word; | 205 | eep->baseEepHeader.length = word; |
250 | 206 | ||
@@ -283,17 +239,15 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah) | |||
283 | } | 239 | } |
284 | } | 240 | } |
285 | 241 | ||
286 | if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER || | 242 | if (!ath9k_hw_nvram_check_version(ah, AR5416_EEP_VER, |
287 | ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) { | 243 | AR5416_EEP_NO_BACK_VER)) |
288 | ath_err(common, "Bad EEPROM checksum 0x%x or revision 0x%04x\n", | ||
289 | sum, ah->eep_ops->get_eeprom_ver(ah)); | ||
290 | return -EINVAL; | 244 | return -EINVAL; |
291 | } | ||
292 | 245 | ||
293 | return 0; | 246 | return 0; |
294 | #undef EEPROM_4K_SIZE | ||
295 | } | 247 | } |
296 | 248 | ||
249 | #undef SIZE_EEPROM_4K | ||
250 | |||
297 | static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah, | 251 | static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah, |
298 | enum eeprom_param param) | 252 | enum eeprom_param param) |
299 | { | 253 | { |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index 6ca33dfde1fd..1a019a39eda1 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c | |||
@@ -177,59 +177,24 @@ static u32 ath9k_hw_ar9287_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, | |||
177 | 177 | ||
178 | static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah) | 178 | static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah) |
179 | { | 179 | { |
180 | u32 sum = 0, el, integer; | 180 | u32 el, integer; |
181 | u16 temp, word, magic, magic2, *eepdata; | 181 | u16 word; |
182 | int i, addr; | 182 | int i, err; |
183 | bool need_swap = false; | 183 | bool need_swap; |
184 | struct ar9287_eeprom *eep = &ah->eeprom.map9287; | 184 | struct ar9287_eeprom *eep = &ah->eeprom.map9287; |
185 | struct ath_common *common = ath9k_hw_common(ah); | ||
186 | |||
187 | if (!ath9k_hw_use_flash(ah)) { | ||
188 | if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, | ||
189 | &magic)) { | ||
190 | ath_err(common, "Reading Magic # failed\n"); | ||
191 | return false; | ||
192 | } | ||
193 | |||
194 | ath_dbg(common, EEPROM, "Read Magic = 0x%04X\n", magic); | ||
195 | |||
196 | if (magic != AR5416_EEPROM_MAGIC) { | ||
197 | magic2 = swab16(magic); | ||
198 | |||
199 | if (magic2 == AR5416_EEPROM_MAGIC) { | ||
200 | need_swap = true; | ||
201 | eepdata = (u16 *)(&ah->eeprom); | ||
202 | |||
203 | for (addr = 0; addr < SIZE_EEPROM_AR9287; addr++) { | ||
204 | temp = swab16(*eepdata); | ||
205 | *eepdata = temp; | ||
206 | eepdata++; | ||
207 | } | ||
208 | } else { | ||
209 | ath_err(common, | ||
210 | "Invalid EEPROM Magic. Endianness mismatch.\n"); | ||
211 | return -EINVAL; | ||
212 | } | ||
213 | } | ||
214 | } | ||
215 | 185 | ||
216 | ath_dbg(common, EEPROM, "need_swap = %s\n", | 186 | err = ath9k_hw_nvram_swap_data(ah, &need_swap, SIZE_EEPROM_AR9287); |
217 | need_swap ? "True" : "False"); | 187 | if (err) |
188 | return err; | ||
218 | 189 | ||
219 | if (need_swap) | 190 | if (need_swap) |
220 | el = swab16(ah->eeprom.map9287.baseEepHeader.length); | 191 | el = swab16(eep->baseEepHeader.length); |
221 | else | ||
222 | el = ah->eeprom.map9287.baseEepHeader.length; | ||
223 | |||
224 | if (el > sizeof(struct ar9287_eeprom)) | ||
225 | el = sizeof(struct ar9287_eeprom) / sizeof(u16); | ||
226 | else | 192 | else |
227 | el = el / sizeof(u16); | 193 | el = eep->baseEepHeader.length; |
228 | |||
229 | eepdata = (u16 *)(&ah->eeprom); | ||
230 | 194 | ||
231 | for (i = 0; i < el; i++) | 195 | el = min(el / sizeof(u16), SIZE_EEPROM_AR9287); |
232 | sum ^= *eepdata++; | 196 | if (!ath9k_hw_nvram_validate_checksum(ah, el)) |
197 | return -EINVAL; | ||
233 | 198 | ||
234 | if (need_swap) { | 199 | if (need_swap) { |
235 | word = swab16(eep->baseEepHeader.length); | 200 | word = swab16(eep->baseEepHeader.length); |
@@ -270,16 +235,15 @@ static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah) | |||
270 | } | 235 | } |
271 | } | 236 | } |
272 | 237 | ||
273 | if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR9287_EEP_VER | 238 | if (!ath9k_hw_nvram_check_version(ah, AR9287_EEP_VER, |
274 | || ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) { | 239 | AR5416_EEP_NO_BACK_VER)) |
275 | ath_err(common, "Bad EEPROM checksum 0x%x or revision 0x%04x\n", | ||
276 | sum, ah->eep_ops->get_eeprom_ver(ah)); | ||
277 | return -EINVAL; | 240 | return -EINVAL; |
278 | } | ||
279 | 241 | ||
280 | return 0; | 242 | return 0; |
281 | } | 243 | } |
282 | 244 | ||
245 | #undef SIZE_EEPROM_AR9287 | ||
246 | |||
283 | static u32 ath9k_hw_ar9287_get_eeprom(struct ath_hw *ah, | 247 | static u32 ath9k_hw_ar9287_get_eeprom(struct ath_hw *ah, |
284 | enum eeprom_param param) | 248 | enum eeprom_param param) |
285 | { | 249 | { |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index 056f516bf017..959682f7909c 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c | |||
@@ -126,8 +126,6 @@ static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah) | |||
126 | return __ath9k_hw_def_fill_eeprom(ah); | 126 | return __ath9k_hw_def_fill_eeprom(ah); |
127 | } | 127 | } |
128 | 128 | ||
129 | #undef SIZE_EEPROM_DEF | ||
130 | |||
131 | #if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS) | 129 | #if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS) |
132 | static u32 ath9k_def_dump_modal_eeprom(char *buf, u32 len, u32 size, | 130 | static u32 ath9k_def_dump_modal_eeprom(char *buf, u32 len, u32 size, |
133 | struct modal_eep_header *modal_hdr) | 131 | struct modal_eep_header *modal_hdr) |
@@ -257,59 +255,31 @@ static u32 ath9k_hw_def_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, | |||
257 | } | 255 | } |
258 | #endif | 256 | #endif |
259 | 257 | ||
260 | |||
261 | static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) | 258 | static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) |
262 | { | 259 | { |
263 | struct ar5416_eeprom_def *eep = &ah->eeprom.def; | 260 | struct ar5416_eeprom_def *eep = &ah->eeprom.def; |
264 | struct ath_common *common = ath9k_hw_common(ah); | 261 | struct ath_common *common = ath9k_hw_common(ah); |
265 | u16 *eepdata, temp, magic; | 262 | u32 el; |
266 | u32 sum = 0, el; | 263 | bool need_swap; |
267 | bool need_swap = false; | 264 | int i, err; |
268 | int i, addr, size; | ||
269 | |||
270 | if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) { | ||
271 | ath_err(common, "Reading Magic # failed\n"); | ||
272 | return false; | ||
273 | } | ||
274 | |||
275 | if (swab16(magic) == AR5416_EEPROM_MAGIC && | ||
276 | !(ah->ah_flags & AH_NO_EEP_SWAP)) { | ||
277 | size = sizeof(struct ar5416_eeprom_def); | ||
278 | need_swap = true; | ||
279 | eepdata = (u16 *) (&ah->eeprom); | ||
280 | |||
281 | for (addr = 0; addr < size / sizeof(u16); addr++) { | ||
282 | temp = swab16(*eepdata); | ||
283 | *eepdata = temp; | ||
284 | eepdata++; | ||
285 | } | ||
286 | } | ||
287 | 265 | ||
288 | ath_dbg(common, EEPROM, "need_swap = %s\n", | 266 | err = ath9k_hw_nvram_swap_data(ah, &need_swap, SIZE_EEPROM_DEF); |
289 | need_swap ? "True" : "False"); | 267 | if (err) |
268 | return err; | ||
290 | 269 | ||
291 | if (need_swap) | 270 | if (need_swap) |
292 | el = swab16(ah->eeprom.def.baseEepHeader.length); | 271 | el = swab16(eep->baseEepHeader.length); |
293 | else | 272 | else |
294 | el = ah->eeprom.def.baseEepHeader.length; | 273 | el = eep->baseEepHeader.length; |
295 | 274 | ||
296 | if (el > sizeof(struct ar5416_eeprom_def)) | 275 | el = min(el / sizeof(u16), SIZE_EEPROM_DEF); |
297 | el = sizeof(struct ar5416_eeprom_def) / sizeof(u16); | 276 | if (!ath9k_hw_nvram_validate_checksum(ah, el)) |
298 | else | 277 | return -EINVAL; |
299 | el = el / sizeof(u16); | ||
300 | |||
301 | eepdata = (u16 *)(&ah->eeprom); | ||
302 | |||
303 | for (i = 0; i < el; i++) | ||
304 | sum ^= *eepdata++; | ||
305 | 278 | ||
306 | if (need_swap) { | 279 | if (need_swap) { |
307 | u32 integer, j; | 280 | u32 integer, j; |
308 | u16 word; | 281 | u16 word; |
309 | 282 | ||
310 | ath_dbg(common, EEPROM, | ||
311 | "EEPROM Endianness is not native.. Changing.\n"); | ||
312 | |||
313 | word = swab16(eep->baseEepHeader.length); | 283 | word = swab16(eep->baseEepHeader.length); |
314 | eep->baseEepHeader.length = word; | 284 | eep->baseEepHeader.length = word; |
315 | 285 | ||
@@ -356,12 +326,9 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) | |||
356 | } | 326 | } |
357 | } | 327 | } |
358 | 328 | ||
359 | if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER || | 329 | if (!ath9k_hw_nvram_check_version(ah, AR5416_EEP_VER, |
360 | ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) { | 330 | AR5416_EEP_NO_BACK_VER)) |
361 | ath_err(common, "Bad EEPROM checksum 0x%x or revision 0x%04x\n", | ||
362 | sum, ah->eep_ops->get_eeprom_ver(ah)); | ||
363 | return -EINVAL; | 331 | return -EINVAL; |
364 | } | ||
365 | 332 | ||
366 | /* Enable fixup for AR_AN_TOP2 if necessary */ | 333 | /* Enable fixup for AR_AN_TOP2 if necessary */ |
367 | if ((ah->hw_version.devid == AR9280_DEVID_PCI) && | 334 | if ((ah->hw_version.devid == AR9280_DEVID_PCI) && |
@@ -376,6 +343,8 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) | |||
376 | return 0; | 343 | return 0; |
377 | } | 344 | } |
378 | 345 | ||
346 | #undef SIZE_EEPROM_DEF | ||
347 | |||
379 | static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah, | 348 | static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah, |
380 | enum eeprom_param param) | 349 | enum eeprom_param param) |
381 | { | 350 | { |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 41382f89abe1..257f46ed4a04 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -2299,10 +2299,10 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, | |||
2299 | else | 2299 | else |
2300 | nextTbtt = bs->bs_nexttbtt; | 2300 | nextTbtt = bs->bs_nexttbtt; |
2301 | 2301 | ||
2302 | ath_dbg(common, BEACON, "next DTIM %d\n", bs->bs_nextdtim); | 2302 | ath_dbg(common, BEACON, "next DTIM %u\n", bs->bs_nextdtim); |
2303 | ath_dbg(common, BEACON, "next beacon %d\n", nextTbtt); | 2303 | ath_dbg(common, BEACON, "next beacon %u\n", nextTbtt); |
2304 | ath_dbg(common, BEACON, "beacon period %d\n", beaconintval); | 2304 | ath_dbg(common, BEACON, "beacon period %u\n", beaconintval); |
2305 | ath_dbg(common, BEACON, "DTIM period %d\n", dtimperiod); | 2305 | ath_dbg(common, BEACON, "DTIM period %u\n", dtimperiod); |
2306 | 2306 | ||
2307 | ENABLE_REGWRITE_BUFFER(ah); | 2307 | ENABLE_REGWRITE_BUFFER(ah); |
2308 | 2308 | ||
@@ -2761,9 +2761,6 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits) | |||
2761 | 2761 | ||
2762 | ENABLE_REGWRITE_BUFFER(ah); | 2762 | ENABLE_REGWRITE_BUFFER(ah); |
2763 | 2763 | ||
2764 | if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) | ||
2765 | bits |= ATH9K_RX_FILTER_CONTROL_WRAPPER; | ||
2766 | |||
2767 | REG_WRITE(ah, AR_RX_FILTER, bits); | 2764 | REG_WRITE(ah, AR_RX_FILTER, bits); |
2768 | 2765 | ||
2769 | phybits = 0; | 2766 | phybits = 0; |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index d184e682e636..c1b33fdcca08 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -739,6 +739,8 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
739 | 739 | ||
740 | ath9k_ps_restore(sc); | 740 | ath9k_ps_restore(sc); |
741 | 741 | ||
742 | ath9k_rng_start(sc); | ||
743 | |||
742 | return 0; | 744 | return 0; |
743 | } | 745 | } |
744 | 746 | ||
@@ -828,6 +830,8 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
828 | 830 | ||
829 | ath9k_deinit_channel_context(sc); | 831 | ath9k_deinit_channel_context(sc); |
830 | 832 | ||
833 | ath9k_rng_stop(sc); | ||
834 | |||
831 | mutex_lock(&sc->mutex); | 835 | mutex_lock(&sc->mutex); |
832 | 836 | ||
833 | ath_cancel_work(sc); | 837 | ath_cancel_work(sc); |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 994daf6c6297..32160fca876a 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -424,6 +424,9 @@ u32 ath_calcrxfilter(struct ath_softc *sc) | |||
424 | AR_SREV_9561(sc->sc_ah)) | 424 | AR_SREV_9561(sc->sc_ah)) |
425 | rfilt |= ATH9K_RX_FILTER_4ADDRESS; | 425 | rfilt |= ATH9K_RX_FILTER_4ADDRESS; |
426 | 426 | ||
427 | if (AR_SREV_9462(sc->sc_ah) || AR_SREV_9565(sc->sc_ah)) | ||
428 | rfilt |= ATH9K_RX_FILTER_CONTROL_WRAPPER; | ||
429 | |||
427 | if (ath9k_is_chanctx_enabled() && | 430 | if (ath9k_is_chanctx_enabled() && |
428 | test_bit(ATH_OP_SCANNING, &common->op_flags)) | 431 | test_bit(ATH_OP_SCANNING, &common->op_flags)) |
429 | rfilt |= ATH9K_RX_FILTER_BEACON; | 432 | rfilt |= ATH9K_RX_FILTER_BEACON; |
diff --git a/drivers/net/wireless/ath/ath9k/rng.c b/drivers/net/wireless/ath/ath9k/rng.c new file mode 100644 index 000000000000..c9cb2aad7b6f --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/rng.c | |||
@@ -0,0 +1,107 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2015 Qualcomm Atheros, Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include <linux/hw_random.h> | ||
18 | #include <linux/kthread.h> | ||
19 | |||
20 | #include "ath9k.h" | ||
21 | #include "hw.h" | ||
22 | #include "ar9003_phy.h" | ||
23 | |||
24 | #define ATH9K_RNG_BUF_SIZE 320 | ||
25 | #define ATH9K_RNG_ENTROPY(x) (((x) * 8 * 320) >> 10) /* quality: 320/1024 */ | ||
26 | |||
27 | static int ath9k_rng_data_read(struct ath_softc *sc, u32 *buf, u32 buf_size) | ||
28 | { | ||
29 | int i, j; | ||
30 | u32 v1, v2, rng_last = sc->rng_last; | ||
31 | struct ath_hw *ah = sc->sc_ah; | ||
32 | |||
33 | ath9k_ps_wakeup(sc); | ||
34 | |||
35 | REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_BBB_OBS_SEL, 1); | ||
36 | REG_CLR_BIT(ah, AR_PHY_TEST, AR_PHY_TEST_RX_OBS_SEL_BIT5); | ||
37 | REG_RMW_FIELD(ah, AR_PHY_TEST_CTL_STATUS, AR_PHY_TEST_CTL_RX_OBS_SEL, 0); | ||
38 | |||
39 | for (i = 0, j = 0; i < buf_size; i++) { | ||
40 | v1 = REG_READ(ah, AR_PHY_TST_ADC) & 0xffff; | ||
41 | v2 = REG_READ(ah, AR_PHY_TST_ADC) & 0xffff; | ||
42 | |||
43 | /* wait for data ready */ | ||
44 | if (v1 && v2 && rng_last != v1 && v1 != v2 && v1 != 0xffff && | ||
45 | v2 != 0xffff) | ||
46 | buf[j++] = (v1 << 16) | v2; | ||
47 | |||
48 | rng_last = v2; | ||
49 | } | ||
50 | |||
51 | ath9k_ps_restore(sc); | ||
52 | |||
53 | sc->rng_last = rng_last; | ||
54 | |||
55 | return j << 2; | ||
56 | } | ||
57 | |||
58 | static int ath9k_rng_kthread(void *data) | ||
59 | { | ||
60 | int bytes_read; | ||
61 | struct ath_softc *sc = data; | ||
62 | u32 *rng_buf; | ||
63 | |||
64 | rng_buf = kmalloc_array(ATH9K_RNG_BUF_SIZE, sizeof(u32), GFP_KERNEL); | ||
65 | if (!rng_buf) | ||
66 | goto out; | ||
67 | |||
68 | while (!kthread_should_stop()) { | ||
69 | bytes_read = ath9k_rng_data_read(sc, rng_buf, | ||
70 | ATH9K_RNG_BUF_SIZE); | ||
71 | if (unlikely(!bytes_read)) { | ||
72 | msleep_interruptible(10); | ||
73 | continue; | ||
74 | } | ||
75 | |||
76 | /* sleep until entropy bits under write_wakeup_threshold */ | ||
77 | add_hwgenerator_randomness((void *)rng_buf, bytes_read, | ||
78 | ATH9K_RNG_ENTROPY(bytes_read)); | ||
79 | } | ||
80 | |||
81 | kfree(rng_buf); | ||
82 | out: | ||
83 | sc->rng_task = NULL; | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | void ath9k_rng_start(struct ath_softc *sc) | ||
89 | { | ||
90 | struct ath_hw *ah = sc->sc_ah; | ||
91 | |||
92 | if (sc->rng_task) | ||
93 | return; | ||
94 | |||
95 | if (!AR_SREV_9300_20_OR_LATER(ah)) | ||
96 | return; | ||
97 | |||
98 | sc->rng_task = kthread_run(ath9k_rng_kthread, sc, "ath9k-hwrng"); | ||
99 | if (IS_ERR(sc->rng_task)) | ||
100 | sc->rng_task = NULL; | ||
101 | } | ||
102 | |||
103 | void ath9k_rng_stop(struct ath_softc *sc) | ||
104 | { | ||
105 | if (sc->rng_task) | ||
106 | kthread_stop(sc->rng_task); | ||
107 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 3e3dac3d7060..fe795fc5288c 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -1473,11 +1473,14 @@ static bool ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
1473 | int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, | 1473 | int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, |
1474 | u16 tid, u16 *ssn) | 1474 | u16 tid, u16 *ssn) |
1475 | { | 1475 | { |
1476 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
1476 | struct ath_atx_tid *txtid; | 1477 | struct ath_atx_tid *txtid; |
1477 | struct ath_txq *txq; | 1478 | struct ath_txq *txq; |
1478 | struct ath_node *an; | 1479 | struct ath_node *an; |
1479 | u8 density; | 1480 | u8 density; |
1480 | 1481 | ||
1482 | ath_dbg(common, XMIT, "%s called\n", __func__); | ||
1483 | |||
1481 | an = (struct ath_node *)sta->drv_priv; | 1484 | an = (struct ath_node *)sta->drv_priv; |
1482 | txtid = ATH_AN_2_TID(an, tid); | 1485 | txtid = ATH_AN_2_TID(an, tid); |
1483 | txq = txtid->txq; | 1486 | txq = txtid->txq; |
@@ -1512,10 +1515,13 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, | |||
1512 | 1515 | ||
1513 | void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) | 1516 | void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) |
1514 | { | 1517 | { |
1518 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
1515 | struct ath_node *an = (struct ath_node *)sta->drv_priv; | 1519 | struct ath_node *an = (struct ath_node *)sta->drv_priv; |
1516 | struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid); | 1520 | struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid); |
1517 | struct ath_txq *txq = txtid->txq; | 1521 | struct ath_txq *txq = txtid->txq; |
1518 | 1522 | ||
1523 | ath_dbg(common, XMIT, "%s called\n", __func__); | ||
1524 | |||
1519 | ath_txq_lock(sc, txq); | 1525 | ath_txq_lock(sc, txq); |
1520 | txtid->active = false; | 1526 | txtid->active = false; |
1521 | ath_tx_flush_tid(sc, txtid); | 1527 | ath_tx_flush_tid(sc, txtid); |
@@ -1526,11 +1532,14 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) | |||
1526 | void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, | 1532 | void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, |
1527 | struct ath_node *an) | 1533 | struct ath_node *an) |
1528 | { | 1534 | { |
1535 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
1529 | struct ath_atx_tid *tid; | 1536 | struct ath_atx_tid *tid; |
1530 | struct ath_txq *txq; | 1537 | struct ath_txq *txq; |
1531 | bool buffered; | 1538 | bool buffered; |
1532 | int tidno; | 1539 | int tidno; |
1533 | 1540 | ||
1541 | ath_dbg(common, XMIT, "%s called\n", __func__); | ||
1542 | |||
1534 | for (tidno = 0, tid = &an->tid[tidno]; | 1543 | for (tidno = 0, tid = &an->tid[tidno]; |
1535 | tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { | 1544 | tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { |
1536 | 1545 | ||
@@ -1555,10 +1564,13 @@ void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, | |||
1555 | 1564 | ||
1556 | void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an) | 1565 | void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an) |
1557 | { | 1566 | { |
1567 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
1558 | struct ath_atx_tid *tid; | 1568 | struct ath_atx_tid *tid; |
1559 | struct ath_txq *txq; | 1569 | struct ath_txq *txq; |
1560 | int tidno; | 1570 | int tidno; |
1561 | 1571 | ||
1572 | ath_dbg(common, XMIT, "%s called\n", __func__); | ||
1573 | |||
1562 | for (tidno = 0, tid = &an->tid[tidno]; | 1574 | for (tidno = 0, tid = &an->tid[tidno]; |
1563 | tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { | 1575 | tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { |
1564 | 1576 | ||
@@ -1579,10 +1591,13 @@ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an) | |||
1579 | void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, | 1591 | void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, |
1580 | u16 tidno) | 1592 | u16 tidno) |
1581 | { | 1593 | { |
1594 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
1582 | struct ath_atx_tid *tid; | 1595 | struct ath_atx_tid *tid; |
1583 | struct ath_node *an; | 1596 | struct ath_node *an; |
1584 | struct ath_txq *txq; | 1597 | struct ath_txq *txq; |
1585 | 1598 | ||
1599 | ath_dbg(common, XMIT, "%s called\n", __func__); | ||
1600 | |||
1586 | an = (struct ath_node *)sta->drv_priv; | 1601 | an = (struct ath_node *)sta->drv_priv; |
1587 | tid = ATH_AN_2_TID(an, tidno); | 1602 | tid = ATH_AN_2_TID(an, tidno); |
1588 | txq = tid->txq; | 1603 | txq = tid->txq; |
@@ -2316,6 +2331,12 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2316 | 2331 | ||
2317 | queue = ieee80211_is_data_present(hdr->frame_control); | 2332 | queue = ieee80211_is_data_present(hdr->frame_control); |
2318 | 2333 | ||
2334 | /* If chanctx, queue all null frames while NOA could be there */ | ||
2335 | if (ath9k_is_chanctx_enabled() && | ||
2336 | ieee80211_is_nullfunc(hdr->frame_control) && | ||
2337 | !txctl->force_channel) | ||
2338 | queue = true; | ||
2339 | |||
2319 | /* Force queueing of all frames that belong to a virtual interface on | 2340 | /* Force queueing of all frames that belong to a virtual interface on |
2320 | * a different channel context, to ensure that they are sent on the | 2341 | * a different channel context, to ensure that they are sent on the |
2321 | * correct channel. | 2342 | * correct channel. |
@@ -2894,7 +2915,7 @@ int ath9k_tx99_send(struct ath_softc *sc, struct sk_buff *skb, | |||
2894 | if (skb_headroom(skb) < padsize) { | 2915 | if (skb_headroom(skb) < padsize) { |
2895 | ath_dbg(common, XMIT, | 2916 | ath_dbg(common, XMIT, |
2896 | "tx99 padding failed\n"); | 2917 | "tx99 padding failed\n"); |
2897 | return -EINVAL; | 2918 | return -EINVAL; |
2898 | } | 2919 | } |
2899 | 2920 | ||
2900 | skb_push(skb, padsize); | 2921 | skb_push(skb, padsize); |
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 48687f128dc6..09b4daebab9d 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c | |||
@@ -781,8 +781,10 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) | |||
781 | wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false); | 781 | wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false); |
782 | wil_bcast_fini(wil); | 782 | wil_bcast_fini(wil); |
783 | 783 | ||
784 | /* prevent NAPI from being scheduled */ | 784 | /* prevent NAPI from being scheduled and prevent wmi commands */ |
785 | mutex_lock(&wil->wmi_mutex); | ||
785 | bitmap_zero(wil->status, wil_status_last); | 786 | bitmap_zero(wil->status, wil_status_last); |
787 | mutex_unlock(&wil->wmi_mutex); | ||
786 | 788 | ||
787 | if (wil->scan_request) { | 789 | if (wil->scan_request) { |
788 | wil_dbg_misc(wil, "Abort scan_request 0x%p\n", | 790 | wil_dbg_misc(wil, "Abort scan_request 0x%p\n", |
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index 6ed26baca0e5..e3ea74cdd4aa 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c | |||
@@ -228,6 +228,10 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len) | |||
228 | wil_dbg_wmi(wil, "Head 0x%08x -> 0x%08x\n", r->head, next_head); | 228 | wil_dbg_wmi(wil, "Head 0x%08x -> 0x%08x\n", r->head, next_head); |
229 | /* wait till FW finish with previous command */ | 229 | /* wait till FW finish with previous command */ |
230 | for (retry = 5; retry > 0; retry--) { | 230 | for (retry = 5; retry > 0; retry--) { |
231 | if (!test_bit(wil_status_fwready, wil->status)) { | ||
232 | wil_err(wil, "WMI: cannot send command while FW not ready\n"); | ||
233 | return -EAGAIN; | ||
234 | } | ||
231 | r->tail = wil_r(wil, RGF_MBOX + | 235 | r->tail = wil_r(wil, RGF_MBOX + |
232 | offsetof(struct wil6210_mbox_ctl, tx.tail)); | 236 | offsetof(struct wil6210_mbox_ctl, tx.tail)); |
233 | if (next_head != r->tail) | 237 | if (next_head != r->tail) |