diff options
author | David S. Miller <davem@davemloft.net> | 2016-11-27 20:26:59 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-11-27 20:26:59 -0500 |
commit | 33f8a0458b2ce4546b681c5fae04427e3077a543 (patch) | |
tree | dc7e9750666fa02b19e0dad4aa8b514403f5e4ae /drivers/net/wireless/ath | |
parent | 5a717f4f8f2830f297b5511022481bdc27b9d576 (diff) | |
parent | 159a55a64d44acbbd6f0d8f3c082e628d6d75670 (diff) |
Merge tag 'wireless-drivers-next-for-davem-2016-11-25' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next
Kalle Valo says:
====================
wireless-drivers-next patches for 4.10
Major changes:
iwlwifi
* finalize and enable dynamic queue allocation
* use dev_coredumpmsg() to prevent locking the driver
* small fix to pass the AID to the FW
* use FW PS decisions with multi-queue
ath9k
* add device tree bindings
* switch to use mac80211 intermediate software queues to reduce
latency and fix bufferbloat
wl18xx
* allow scanning in AP mode
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/wireless/ath')
27 files changed, 716 insertions, 291 deletions
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index da7a7c8dafb2..f3f2784f6ebd 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h | |||
@@ -327,4 +327,10 @@ static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode) | |||
327 | } | 327 | } |
328 | #endif | 328 | #endif |
329 | 329 | ||
330 | extern const char *ath_bus_type_strings[]; | ||
331 | static inline const char *ath_bus_type_to_string(enum ath_bus_type bustype) | ||
332 | { | ||
333 | return ath_bus_type_strings[bustype]; | ||
334 | } | ||
335 | |||
330 | #endif /* ATH_H */ | 336 | #endif /* ATH_H */ |
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 21ae8d663e67..7005e2a98726 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c | |||
@@ -198,6 +198,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { | |||
198 | .name = "qca9984/qca9994 hw1.0", | 198 | .name = "qca9984/qca9994 hw1.0", |
199 | .patch_load_addr = QCA9984_HW_1_0_PATCH_LOAD_ADDR, | 199 | .patch_load_addr = QCA9984_HW_1_0_PATCH_LOAD_ADDR, |
200 | .uart_pin = 7, | 200 | .uart_pin = 7, |
201 | .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH, | ||
201 | .otp_exe_param = 0x00000700, | 202 | .otp_exe_param = 0x00000700, |
202 | .continuous_frag_desc = true, | 203 | .continuous_frag_desc = true, |
203 | .cck_rate_map_rev2 = true, | 204 | .cck_rate_map_rev2 = true, |
@@ -223,6 +224,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { | |||
223 | .name = "qca9888 hw2.0", | 224 | .name = "qca9888 hw2.0", |
224 | .patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR, | 225 | .patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR, |
225 | .uart_pin = 7, | 226 | .uart_pin = 7, |
227 | .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH, | ||
226 | .otp_exe_param = 0x00000700, | 228 | .otp_exe_param = 0x00000700, |
227 | .continuous_frag_desc = true, | 229 | .continuous_frag_desc = true, |
228 | .channel_counters_freq_hz = 150000, | 230 | .channel_counters_freq_hz = 150000, |
@@ -1560,6 +1562,15 @@ static void ath10k_core_restart(struct work_struct *work) | |||
1560 | mutex_unlock(&ar->conf_mutex); | 1562 | mutex_unlock(&ar->conf_mutex); |
1561 | } | 1563 | } |
1562 | 1564 | ||
1565 | static void ath10k_core_set_coverage_class_work(struct work_struct *work) | ||
1566 | { | ||
1567 | struct ath10k *ar = container_of(work, struct ath10k, | ||
1568 | set_coverage_class_work); | ||
1569 | |||
1570 | if (ar->hw_params.hw_ops->set_coverage_class) | ||
1571 | ar->hw_params.hw_ops->set_coverage_class(ar, -1); | ||
1572 | } | ||
1573 | |||
1563 | static int ath10k_core_init_firmware_features(struct ath10k *ar) | 1574 | static int ath10k_core_init_firmware_features(struct ath10k *ar) |
1564 | { | 1575 | { |
1565 | struct ath10k_fw_file *fw_file = &ar->normal_mode_fw.fw_file; | 1576 | struct ath10k_fw_file *fw_file = &ar->normal_mode_fw.fw_file; |
@@ -2342,6 +2353,8 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, | |||
2342 | 2353 | ||
2343 | INIT_WORK(&ar->register_work, ath10k_core_register_work); | 2354 | INIT_WORK(&ar->register_work, ath10k_core_register_work); |
2344 | INIT_WORK(&ar->restart_work, ath10k_core_restart); | 2355 | INIT_WORK(&ar->restart_work, ath10k_core_restart); |
2356 | INIT_WORK(&ar->set_coverage_class_work, | ||
2357 | ath10k_core_set_coverage_class_work); | ||
2345 | 2358 | ||
2346 | init_dummy_netdev(&ar->napi_dev); | 2359 | init_dummy_netdev(&ar->napi_dev); |
2347 | 2360 | ||
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 521f1c55c19e..e8decfaba5b6 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h | |||
@@ -557,10 +557,8 @@ enum ath10k_fw_features { | |||
557 | */ | 557 | */ |
558 | ATH10K_FW_FEATURE_BTCOEX_PARAM = 14, | 558 | ATH10K_FW_FEATURE_BTCOEX_PARAM = 14, |
559 | 559 | ||
560 | /* Older firmware with HTT delivers incorrect tx status for null func | 560 | /* Unused flag and proven to be not working, enable this if you want |
561 | * frames to driver, but this fixed in 10.2 and 10.4 firmware versions. | 561 | * to experiment sending NULL func data frames in HTT TX |
562 | * Also this workaround results in reporting of incorrect null func | ||
563 | * status for 10.4. This flag is used to skip the workaround. | ||
564 | */ | 562 | */ |
565 | ATH10K_FW_FEATURE_SKIP_NULL_FUNC_WAR = 15, | 563 | ATH10K_FW_FEATURE_SKIP_NULL_FUNC_WAR = 15, |
566 | 564 | ||
@@ -714,6 +712,7 @@ struct ath10k { | |||
714 | u32 phy_capability; | 712 | u32 phy_capability; |
715 | u32 hw_min_tx_power; | 713 | u32 hw_min_tx_power; |
716 | u32 hw_max_tx_power; | 714 | u32 hw_max_tx_power; |
715 | u32 hw_eeprom_rd; | ||
717 | u32 ht_cap_info; | 716 | u32 ht_cap_info; |
718 | u32 vht_cap_info; | 717 | u32 vht_cap_info; |
719 | u32 num_rf_chains; | 718 | u32 num_rf_chains; |
@@ -912,6 +911,19 @@ struct ath10k { | |||
912 | struct net_device napi_dev; | 911 | struct net_device napi_dev; |
913 | struct napi_struct napi; | 912 | struct napi_struct napi; |
914 | 913 | ||
914 | struct work_struct set_coverage_class_work; | ||
915 | /* protected by conf_mutex */ | ||
916 | struct { | ||
917 | /* writing also protected by data_lock */ | ||
918 | s16 coverage_class; | ||
919 | |||
920 | u32 reg_phyclk; | ||
921 | u32 reg_slottime_conf; | ||
922 | u32 reg_slottime_orig; | ||
923 | u32 reg_ack_cts_timeout_conf; | ||
924 | u32 reg_ack_cts_timeout_orig; | ||
925 | } fw_coverage; | ||
926 | |||
915 | /* must be last */ | 927 | /* must be last */ |
916 | u8 drv_priv[0] __aligned(sizeof(void *)); | 928 | u8 drv_priv[0] __aligned(sizeof(void *)); |
917 | }; | 929 | }; |
diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h index c458fa96a6d4..335512b11ca2 100644 --- a/drivers/net/wireless/ath/ath10k/debug.h +++ b/drivers/net/wireless/ath/ath10k/debug.h | |||
@@ -94,7 +94,19 @@ int ath10k_debug_get_et_sset_count(struct ieee80211_hw *hw, | |||
94 | void ath10k_debug_get_et_stats(struct ieee80211_hw *hw, | 94 | void ath10k_debug_get_et_stats(struct ieee80211_hw *hw, |
95 | struct ieee80211_vif *vif, | 95 | struct ieee80211_vif *vif, |
96 | struct ethtool_stats *stats, u64 *data); | 96 | struct ethtool_stats *stats, u64 *data); |
97 | |||
98 | static inline u64 ath10k_debug_get_fw_dbglog_mask(struct ath10k *ar) | ||
99 | { | ||
100 | return ar->debug.fw_dbglog_mask; | ||
101 | } | ||
102 | |||
103 | static inline u32 ath10k_debug_get_fw_dbglog_level(struct ath10k *ar) | ||
104 | { | ||
105 | return ar->debug.fw_dbglog_level; | ||
106 | } | ||
107 | |||
97 | #else | 108 | #else |
109 | |||
98 | static inline int ath10k_debug_start(struct ath10k *ar) | 110 | static inline int ath10k_debug_start(struct ath10k *ar) |
99 | { | 111 | { |
100 | return 0; | 112 | return 0; |
@@ -144,6 +156,16 @@ ath10k_debug_get_new_fw_crash_data(struct ath10k *ar) | |||
144 | return NULL; | 156 | return NULL; |
145 | } | 157 | } |
146 | 158 | ||
159 | static inline u64 ath10k_debug_get_fw_dbglog_mask(struct ath10k *ar) | ||
160 | { | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static inline u32 ath10k_debug_get_fw_dbglog_level(struct ath10k *ar) | ||
165 | { | ||
166 | return 0; | ||
167 | } | ||
168 | |||
147 | #define ATH10K_DFS_STAT_INC(ar, c) do { } while (0) | 169 | #define ATH10K_DFS_STAT_INC(ar, c) do { } while (0) |
148 | 170 | ||
149 | #define ath10k_debug_get_et_strings NULL | 171 | #define ath10k_debug_get_et_strings NULL |
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 0b4c1562420f..285b235268d7 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c | |||
@@ -1463,8 +1463,7 @@ static int ath10k_unchain_msdu(struct sk_buff_head *amsdu) | |||
1463 | } | 1463 | } |
1464 | 1464 | ||
1465 | static void ath10k_htt_rx_h_unchain(struct ath10k *ar, | 1465 | static void ath10k_htt_rx_h_unchain(struct ath10k *ar, |
1466 | struct sk_buff_head *amsdu, | 1466 | struct sk_buff_head *amsdu) |
1467 | bool chained) | ||
1468 | { | 1467 | { |
1469 | struct sk_buff *first; | 1468 | struct sk_buff *first; |
1470 | struct htt_rx_desc *rxd; | 1469 | struct htt_rx_desc *rxd; |
@@ -1475,9 +1474,6 @@ static void ath10k_htt_rx_h_unchain(struct ath10k *ar, | |||
1475 | decap = MS(__le32_to_cpu(rxd->msdu_start.common.info1), | 1474 | decap = MS(__le32_to_cpu(rxd->msdu_start.common.info1), |
1476 | RX_MSDU_START_INFO1_DECAP_FORMAT); | 1475 | RX_MSDU_START_INFO1_DECAP_FORMAT); |
1477 | 1476 | ||
1478 | if (!chained) | ||
1479 | return; | ||
1480 | |||
1481 | /* FIXME: Current unchaining logic can only handle simple case of raw | 1477 | /* FIXME: Current unchaining logic can only handle simple case of raw |
1482 | * msdu chaining. If decapping is other than raw the chaining may be | 1478 | * msdu chaining. If decapping is other than raw the chaining may be |
1483 | * more complex and this isn't handled by the current code. Don't even | 1479 | * more complex and this isn't handled by the current code. Don't even |
@@ -1555,7 +1551,11 @@ static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt) | |||
1555 | 1551 | ||
1556 | num_msdus = skb_queue_len(&amsdu); | 1552 | num_msdus = skb_queue_len(&amsdu); |
1557 | ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status, 0xffff); | 1553 | ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status, 0xffff); |
1558 | ath10k_htt_rx_h_unchain(ar, &amsdu, ret > 0); | 1554 | |
1555 | /* only for ret = 1 indicates chained msdus */ | ||
1556 | if (ret > 0) | ||
1557 | ath10k_htt_rx_h_unchain(ar, &amsdu); | ||
1558 | |||
1559 | ath10k_htt_rx_h_filter(ar, &amsdu, rx_status); | 1559 | ath10k_htt_rx_h_filter(ar, &amsdu, rx_status); |
1560 | ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status); | 1560 | ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status); |
1561 | ath10k_htt_rx_h_deliver(ar, &amsdu, rx_status); | 1561 | ath10k_htt_rx_h_deliver(ar, &amsdu, rx_status); |
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c index ae5b33fe5ba8..ccbc8c03abc1 100644 --- a/drivers/net/wireless/ath/ath10k/htt_tx.c +++ b/drivers/net/wireless/ath/ath10k/htt_tx.c | |||
@@ -229,6 +229,32 @@ void ath10k_htt_tx_free_msdu_id(struct ath10k_htt *htt, u16 msdu_id) | |||
229 | idr_remove(&htt->pending_tx, msdu_id); | 229 | idr_remove(&htt->pending_tx, msdu_id); |
230 | } | 230 | } |
231 | 231 | ||
232 | static void ath10k_htt_tx_free_cont_txbuf(struct ath10k_htt *htt) | ||
233 | { | ||
234 | struct ath10k *ar = htt->ar; | ||
235 | size_t size; | ||
236 | |||
237 | if (!htt->txbuf.vaddr) | ||
238 | return; | ||
239 | |||
240 | size = htt->max_num_pending_tx * sizeof(struct ath10k_htt_txbuf); | ||
241 | dma_free_coherent(ar->dev, size, htt->txbuf.vaddr, htt->txbuf.paddr); | ||
242 | } | ||
243 | |||
244 | static int ath10k_htt_tx_alloc_cont_txbuf(struct ath10k_htt *htt) | ||
245 | { | ||
246 | struct ath10k *ar = htt->ar; | ||
247 | size_t size; | ||
248 | |||
249 | size = htt->max_num_pending_tx * sizeof(struct ath10k_htt_txbuf); | ||
250 | htt->txbuf.vaddr = dma_alloc_coherent(ar->dev, size, &htt->txbuf.paddr, | ||
251 | GFP_KERNEL); | ||
252 | if (!htt->txbuf.vaddr) | ||
253 | return -ENOMEM; | ||
254 | |||
255 | return 0; | ||
256 | } | ||
257 | |||
232 | static void ath10k_htt_tx_free_cont_frag_desc(struct ath10k_htt *htt) | 258 | static void ath10k_htt_tx_free_cont_frag_desc(struct ath10k_htt *htt) |
233 | { | 259 | { |
234 | size_t size; | 260 | size_t size; |
@@ -256,10 +282,8 @@ static int ath10k_htt_tx_alloc_cont_frag_desc(struct ath10k_htt *htt) | |||
256 | htt->frag_desc.vaddr = dma_alloc_coherent(ar->dev, size, | 282 | htt->frag_desc.vaddr = dma_alloc_coherent(ar->dev, size, |
257 | &htt->frag_desc.paddr, | 283 | &htt->frag_desc.paddr, |
258 | GFP_KERNEL); | 284 | GFP_KERNEL); |
259 | if (!htt->frag_desc.vaddr) { | 285 | if (!htt->frag_desc.vaddr) |
260 | ath10k_err(ar, "failed to alloc fragment desc memory\n"); | ||
261 | return -ENOMEM; | 286 | return -ENOMEM; |
262 | } | ||
263 | 287 | ||
264 | return 0; | 288 | return 0; |
265 | } | 289 | } |
@@ -310,10 +334,26 @@ static int ath10k_htt_tx_alloc_txq(struct ath10k_htt *htt) | |||
310 | return 0; | 334 | return 0; |
311 | } | 335 | } |
312 | 336 | ||
337 | static void ath10k_htt_tx_free_txdone_fifo(struct ath10k_htt *htt) | ||
338 | { | ||
339 | WARN_ON(!kfifo_is_empty(&htt->txdone_fifo)); | ||
340 | kfifo_free(&htt->txdone_fifo); | ||
341 | } | ||
342 | |||
343 | static int ath10k_htt_tx_alloc_txdone_fifo(struct ath10k_htt *htt) | ||
344 | { | ||
345 | int ret; | ||
346 | size_t size; | ||
347 | |||
348 | size = roundup_pow_of_two(htt->max_num_pending_tx); | ||
349 | ret = kfifo_alloc(&htt->txdone_fifo, size, GFP_KERNEL); | ||
350 | return ret; | ||
351 | } | ||
352 | |||
313 | int ath10k_htt_tx_alloc(struct ath10k_htt *htt) | 353 | int ath10k_htt_tx_alloc(struct ath10k_htt *htt) |
314 | { | 354 | { |
315 | struct ath10k *ar = htt->ar; | 355 | struct ath10k *ar = htt->ar; |
316 | int ret, size; | 356 | int ret; |
317 | 357 | ||
318 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt tx max num pending tx %d\n", | 358 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt tx max num pending tx %d\n", |
319 | htt->max_num_pending_tx); | 359 | htt->max_num_pending_tx); |
@@ -321,13 +361,9 @@ int ath10k_htt_tx_alloc(struct ath10k_htt *htt) | |||
321 | spin_lock_init(&htt->tx_lock); | 361 | spin_lock_init(&htt->tx_lock); |
322 | idr_init(&htt->pending_tx); | 362 | idr_init(&htt->pending_tx); |
323 | 363 | ||
324 | size = htt->max_num_pending_tx * sizeof(struct ath10k_htt_txbuf); | 364 | ret = ath10k_htt_tx_alloc_cont_txbuf(htt); |
325 | htt->txbuf.vaddr = dma_alloc_coherent(ar->dev, size, | 365 | if (ret) { |
326 | &htt->txbuf.paddr, | 366 | ath10k_err(ar, "failed to alloc cont tx buffer: %d\n", ret); |
327 | GFP_KERNEL); | ||
328 | if (!htt->txbuf.vaddr) { | ||
329 | ath10k_err(ar, "failed to alloc tx buffer\n"); | ||
330 | ret = -ENOMEM; | ||
331 | goto free_idr_pending_tx; | 367 | goto free_idr_pending_tx; |
332 | } | 368 | } |
333 | 369 | ||
@@ -343,8 +379,7 @@ int ath10k_htt_tx_alloc(struct ath10k_htt *htt) | |||
343 | goto free_frag_desc; | 379 | goto free_frag_desc; |
344 | } | 380 | } |
345 | 381 | ||
346 | size = roundup_pow_of_two(htt->max_num_pending_tx); | 382 | ret = ath10k_htt_tx_alloc_txdone_fifo(htt); |
347 | ret = kfifo_alloc(&htt->txdone_fifo, size, GFP_KERNEL); | ||
348 | if (ret) { | 383 | if (ret) { |
349 | ath10k_err(ar, "failed to alloc txdone fifo: %d\n", ret); | 384 | ath10k_err(ar, "failed to alloc txdone fifo: %d\n", ret); |
350 | goto free_txq; | 385 | goto free_txq; |
@@ -359,10 +394,7 @@ free_frag_desc: | |||
359 | ath10k_htt_tx_free_cont_frag_desc(htt); | 394 | ath10k_htt_tx_free_cont_frag_desc(htt); |
360 | 395 | ||
361 | free_txbuf: | 396 | free_txbuf: |
362 | size = htt->max_num_pending_tx * | 397 | ath10k_htt_tx_free_cont_txbuf(htt); |
363 | sizeof(struct ath10k_htt_txbuf); | ||
364 | dma_free_coherent(htt->ar->dev, size, htt->txbuf.vaddr, | ||
365 | htt->txbuf.paddr); | ||
366 | 398 | ||
367 | free_idr_pending_tx: | 399 | free_idr_pending_tx: |
368 | idr_destroy(&htt->pending_tx); | 400 | idr_destroy(&htt->pending_tx); |
@@ -388,22 +420,13 @@ static int ath10k_htt_tx_clean_up_pending(int msdu_id, void *skb, void *ctx) | |||
388 | 420 | ||
389 | void ath10k_htt_tx_free(struct ath10k_htt *htt) | 421 | void ath10k_htt_tx_free(struct ath10k_htt *htt) |
390 | { | 422 | { |
391 | int size; | ||
392 | |||
393 | idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar); | 423 | idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar); |
394 | idr_destroy(&htt->pending_tx); | 424 | idr_destroy(&htt->pending_tx); |
395 | 425 | ||
396 | if (htt->txbuf.vaddr) { | 426 | ath10k_htt_tx_free_cont_txbuf(htt); |
397 | size = htt->max_num_pending_tx * | ||
398 | sizeof(struct ath10k_htt_txbuf); | ||
399 | dma_free_coherent(htt->ar->dev, size, htt->txbuf.vaddr, | ||
400 | htt->txbuf.paddr); | ||
401 | } | ||
402 | |||
403 | ath10k_htt_tx_free_txq(htt); | 427 | ath10k_htt_tx_free_txq(htt); |
404 | ath10k_htt_tx_free_cont_frag_desc(htt); | 428 | ath10k_htt_tx_free_cont_frag_desc(htt); |
405 | WARN_ON(!kfifo_is_empty(&htt->txdone_fifo)); | 429 | ath10k_htt_tx_free_txdone_fifo(htt); |
406 | kfifo_free(&htt->txdone_fifo); | ||
407 | } | 430 | } |
408 | 431 | ||
409 | void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb) | 432 | void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb) |
diff --git a/drivers/net/wireless/ath/ath10k/hw.c b/drivers/net/wireless/ath/ath10k/hw.c index 675e75d66db2..33fb26833cd0 100644 --- a/drivers/net/wireless/ath/ath10k/hw.c +++ b/drivers/net/wireless/ath/ath10k/hw.c | |||
@@ -17,11 +17,14 @@ | |||
17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | #include "core.h" | 18 | #include "core.h" |
19 | #include "hw.h" | 19 | #include "hw.h" |
20 | #include "hif.h" | ||
21 | #include "wmi-ops.h" | ||
20 | 22 | ||
21 | const struct ath10k_hw_regs qca988x_regs = { | 23 | const struct ath10k_hw_regs qca988x_regs = { |
22 | .rtc_soc_base_address = 0x00004000, | 24 | .rtc_soc_base_address = 0x00004000, |
23 | .rtc_wmac_base_address = 0x00005000, | 25 | .rtc_wmac_base_address = 0x00005000, |
24 | .soc_core_base_address = 0x00009000, | 26 | .soc_core_base_address = 0x00009000, |
27 | .wlan_mac_base_address = 0x00020000, | ||
25 | .ce_wrapper_base_address = 0x00057000, | 28 | .ce_wrapper_base_address = 0x00057000, |
26 | .ce0_base_address = 0x00057400, | 29 | .ce0_base_address = 0x00057400, |
27 | .ce1_base_address = 0x00057800, | 30 | .ce1_base_address = 0x00057800, |
@@ -48,6 +51,7 @@ const struct ath10k_hw_regs qca6174_regs = { | |||
48 | .rtc_soc_base_address = 0x00000800, | 51 | .rtc_soc_base_address = 0x00000800, |
49 | .rtc_wmac_base_address = 0x00001000, | 52 | .rtc_wmac_base_address = 0x00001000, |
50 | .soc_core_base_address = 0x0003a000, | 53 | .soc_core_base_address = 0x0003a000, |
54 | .wlan_mac_base_address = 0x00020000, | ||
51 | .ce_wrapper_base_address = 0x00034000, | 55 | .ce_wrapper_base_address = 0x00034000, |
52 | .ce0_base_address = 0x00034400, | 56 | .ce0_base_address = 0x00034400, |
53 | .ce1_base_address = 0x00034800, | 57 | .ce1_base_address = 0x00034800, |
@@ -74,6 +78,7 @@ const struct ath10k_hw_regs qca99x0_regs = { | |||
74 | .rtc_soc_base_address = 0x00080000, | 78 | .rtc_soc_base_address = 0x00080000, |
75 | .rtc_wmac_base_address = 0x00000000, | 79 | .rtc_wmac_base_address = 0x00000000, |
76 | .soc_core_base_address = 0x00082000, | 80 | .soc_core_base_address = 0x00082000, |
81 | .wlan_mac_base_address = 0x00030000, | ||
77 | .ce_wrapper_base_address = 0x0004d000, | 82 | .ce_wrapper_base_address = 0x0004d000, |
78 | .ce0_base_address = 0x0004a000, | 83 | .ce0_base_address = 0x0004a000, |
79 | .ce1_base_address = 0x0004a400, | 84 | .ce1_base_address = 0x0004a400, |
@@ -109,6 +114,7 @@ const struct ath10k_hw_regs qca99x0_regs = { | |||
109 | const struct ath10k_hw_regs qca4019_regs = { | 114 | const struct ath10k_hw_regs qca4019_regs = { |
110 | .rtc_soc_base_address = 0x00080000, | 115 | .rtc_soc_base_address = 0x00080000, |
111 | .soc_core_base_address = 0x00082000, | 116 | .soc_core_base_address = 0x00082000, |
117 | .wlan_mac_base_address = 0x00030000, | ||
112 | .ce_wrapper_base_address = 0x0004d000, | 118 | .ce_wrapper_base_address = 0x0004d000, |
113 | .ce0_base_address = 0x0004a000, | 119 | .ce0_base_address = 0x0004a000, |
114 | .ce1_base_address = 0x0004a400, | 120 | .ce1_base_address = 0x0004a400, |
@@ -220,7 +226,143 @@ void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey, | |||
220 | survey->time_busy = CCNT_TO_MSEC(ar, rcc); | 226 | survey->time_busy = CCNT_TO_MSEC(ar, rcc); |
221 | } | 227 | } |
222 | 228 | ||
229 | /* The firmware does not support setting the coverage class. Instead this | ||
230 | * function monitors and modifies the corresponding MAC registers. | ||
231 | */ | ||
232 | static void ath10k_hw_qca988x_set_coverage_class(struct ath10k *ar, | ||
233 | s16 value) | ||
234 | { | ||
235 | u32 slottime_reg; | ||
236 | u32 slottime; | ||
237 | u32 timeout_reg; | ||
238 | u32 ack_timeout; | ||
239 | u32 cts_timeout; | ||
240 | u32 phyclk_reg; | ||
241 | u32 phyclk; | ||
242 | u64 fw_dbglog_mask; | ||
243 | u32 fw_dbglog_level; | ||
244 | |||
245 | mutex_lock(&ar->conf_mutex); | ||
246 | |||
247 | /* Only modify registers if the core is started. */ | ||
248 | if ((ar->state != ATH10K_STATE_ON) && | ||
249 | (ar->state != ATH10K_STATE_RESTARTED)) | ||
250 | goto unlock; | ||
251 | |||
252 | /* Retrieve the current values of the two registers that need to be | ||
253 | * adjusted. | ||
254 | */ | ||
255 | slottime_reg = ath10k_hif_read32(ar, WLAN_MAC_BASE_ADDRESS + | ||
256 | WAVE1_PCU_GBL_IFS_SLOT); | ||
257 | timeout_reg = ath10k_hif_read32(ar, WLAN_MAC_BASE_ADDRESS + | ||
258 | WAVE1_PCU_ACK_CTS_TIMEOUT); | ||
259 | phyclk_reg = ath10k_hif_read32(ar, WLAN_MAC_BASE_ADDRESS + | ||
260 | WAVE1_PHYCLK); | ||
261 | phyclk = MS(phyclk_reg, WAVE1_PHYCLK_USEC) + 1; | ||
262 | |||
263 | if (value < 0) | ||
264 | value = ar->fw_coverage.coverage_class; | ||
265 | |||
266 | /* Break out if the coverage class and registers have the expected | ||
267 | * value. | ||
268 | */ | ||
269 | if (value == ar->fw_coverage.coverage_class && | ||
270 | slottime_reg == ar->fw_coverage.reg_slottime_conf && | ||
271 | timeout_reg == ar->fw_coverage.reg_ack_cts_timeout_conf && | ||
272 | phyclk_reg == ar->fw_coverage.reg_phyclk) | ||
273 | goto unlock; | ||
274 | |||
275 | /* Store new initial register values from the firmware. */ | ||
276 | if (slottime_reg != ar->fw_coverage.reg_slottime_conf) | ||
277 | ar->fw_coverage.reg_slottime_orig = slottime_reg; | ||
278 | if (timeout_reg != ar->fw_coverage.reg_ack_cts_timeout_conf) | ||
279 | ar->fw_coverage.reg_ack_cts_timeout_orig = timeout_reg; | ||
280 | ar->fw_coverage.reg_phyclk = phyclk_reg; | ||
281 | |||
282 | /* Calculat new value based on the (original) firmware calculation. */ | ||
283 | slottime_reg = ar->fw_coverage.reg_slottime_orig; | ||
284 | timeout_reg = ar->fw_coverage.reg_ack_cts_timeout_orig; | ||
285 | |||
286 | /* Do some sanity checks on the slottime register. */ | ||
287 | if (slottime_reg % phyclk) { | ||
288 | ath10k_warn(ar, | ||
289 | "failed to set coverage class: expected integer microsecond value in register\n"); | ||
290 | |||
291 | goto store_regs; | ||
292 | } | ||
293 | |||
294 | slottime = MS(slottime_reg, WAVE1_PCU_GBL_IFS_SLOT); | ||
295 | slottime = slottime / phyclk; | ||
296 | if (slottime != 9 && slottime != 20) { | ||
297 | ath10k_warn(ar, | ||
298 | "failed to set coverage class: expected slot time of 9 or 20us in HW register. It is %uus.\n", | ||
299 | slottime); | ||
300 | |||
301 | goto store_regs; | ||
302 | } | ||
303 | |||
304 | /* Recalculate the register values by adding the additional propagation | ||
305 | * delay (3us per coverage class). | ||
306 | */ | ||
307 | |||
308 | slottime = MS(slottime_reg, WAVE1_PCU_GBL_IFS_SLOT); | ||
309 | slottime += value * 3 * phyclk; | ||
310 | slottime = min_t(u32, slottime, WAVE1_PCU_GBL_IFS_SLOT_MAX); | ||
311 | slottime = SM(slottime, WAVE1_PCU_GBL_IFS_SLOT); | ||
312 | slottime_reg = (slottime_reg & ~WAVE1_PCU_GBL_IFS_SLOT_MASK) | slottime; | ||
313 | |||
314 | /* Update ack timeout (lower halfword). */ | ||
315 | ack_timeout = MS(timeout_reg, WAVE1_PCU_ACK_CTS_TIMEOUT_ACK); | ||
316 | ack_timeout += 3 * value * phyclk; | ||
317 | ack_timeout = min_t(u32, ack_timeout, WAVE1_PCU_ACK_CTS_TIMEOUT_MAX); | ||
318 | ack_timeout = SM(ack_timeout, WAVE1_PCU_ACK_CTS_TIMEOUT_ACK); | ||
319 | |||
320 | /* Update cts timeout (upper halfword). */ | ||
321 | cts_timeout = MS(timeout_reg, WAVE1_PCU_ACK_CTS_TIMEOUT_CTS); | ||
322 | cts_timeout += 3 * value * phyclk; | ||
323 | cts_timeout = min_t(u32, cts_timeout, WAVE1_PCU_ACK_CTS_TIMEOUT_MAX); | ||
324 | cts_timeout = SM(cts_timeout, WAVE1_PCU_ACK_CTS_TIMEOUT_CTS); | ||
325 | |||
326 | timeout_reg = ack_timeout | cts_timeout; | ||
327 | |||
328 | ath10k_hif_write32(ar, | ||
329 | WLAN_MAC_BASE_ADDRESS + WAVE1_PCU_GBL_IFS_SLOT, | ||
330 | slottime_reg); | ||
331 | ath10k_hif_write32(ar, | ||
332 | WLAN_MAC_BASE_ADDRESS + WAVE1_PCU_ACK_CTS_TIMEOUT, | ||
333 | timeout_reg); | ||
334 | |||
335 | /* Ensure we have a debug level of WARN set for the case that the | ||
336 | * coverage class is larger than 0. This is important as we need to | ||
337 | * set the registers again if the firmware does an internal reset and | ||
338 | * this way we will be notified of the event. | ||
339 | */ | ||
340 | fw_dbglog_mask = ath10k_debug_get_fw_dbglog_mask(ar); | ||
341 | fw_dbglog_level = ath10k_debug_get_fw_dbglog_level(ar); | ||
342 | |||
343 | if (value > 0) { | ||
344 | if (fw_dbglog_level > ATH10K_DBGLOG_LEVEL_WARN) | ||
345 | fw_dbglog_level = ATH10K_DBGLOG_LEVEL_WARN; | ||
346 | fw_dbglog_mask = ~0; | ||
347 | } | ||
348 | |||
349 | ath10k_wmi_dbglog_cfg(ar, fw_dbglog_mask, fw_dbglog_level); | ||
350 | |||
351 | store_regs: | ||
352 | /* After an error we will not retry setting the coverage class. */ | ||
353 | spin_lock_bh(&ar->data_lock); | ||
354 | ar->fw_coverage.coverage_class = value; | ||
355 | spin_unlock_bh(&ar->data_lock); | ||
356 | |||
357 | ar->fw_coverage.reg_slottime_conf = slottime_reg; | ||
358 | ar->fw_coverage.reg_ack_cts_timeout_conf = timeout_reg; | ||
359 | |||
360 | unlock: | ||
361 | mutex_unlock(&ar->conf_mutex); | ||
362 | } | ||
363 | |||
223 | const struct ath10k_hw_ops qca988x_ops = { | 364 | const struct ath10k_hw_ops qca988x_ops = { |
365 | .set_coverage_class = ath10k_hw_qca988x_set_coverage_class, | ||
224 | }; | 366 | }; |
225 | 367 | ||
226 | static int ath10k_qca99x0_rx_desc_get_l3_pad_bytes(struct htt_rx_desc *rxd) | 368 | static int ath10k_qca99x0_rx_desc_get_l3_pad_bytes(struct htt_rx_desc *rxd) |
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index 6038b7486f1d..883547f3347c 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h | |||
@@ -230,6 +230,7 @@ struct ath10k_hw_regs { | |||
230 | u32 rtc_soc_base_address; | 230 | u32 rtc_soc_base_address; |
231 | u32 rtc_wmac_base_address; | 231 | u32 rtc_wmac_base_address; |
232 | u32 soc_core_base_address; | 232 | u32 soc_core_base_address; |
233 | u32 wlan_mac_base_address; | ||
233 | u32 ce_wrapper_base_address; | 234 | u32 ce_wrapper_base_address; |
234 | u32 ce0_base_address; | 235 | u32 ce0_base_address; |
235 | u32 ce1_base_address; | 236 | u32 ce1_base_address; |
@@ -418,6 +419,7 @@ struct htt_rx_desc; | |||
418 | /* Defines needed for Rx descriptor abstraction */ | 419 | /* Defines needed for Rx descriptor abstraction */ |
419 | struct ath10k_hw_ops { | 420 | struct ath10k_hw_ops { |
420 | int (*rx_desc_get_l3_pad_bytes)(struct htt_rx_desc *rxd); | 421 | int (*rx_desc_get_l3_pad_bytes)(struct htt_rx_desc *rxd); |
422 | void (*set_coverage_class)(struct ath10k *ar, s16 value); | ||
421 | }; | 423 | }; |
422 | 424 | ||
423 | extern const struct ath10k_hw_ops qca988x_ops; | 425 | extern const struct ath10k_hw_ops qca988x_ops; |
@@ -614,7 +616,7 @@ ath10k_rx_desc_get_l3_pad_bytes(struct ath10k_hw_params *hw, | |||
614 | #define WLAN_SI_BASE_ADDRESS 0x00010000 | 616 | #define WLAN_SI_BASE_ADDRESS 0x00010000 |
615 | #define WLAN_GPIO_BASE_ADDRESS 0x00014000 | 617 | #define WLAN_GPIO_BASE_ADDRESS 0x00014000 |
616 | #define WLAN_ANALOG_INTF_BASE_ADDRESS 0x0001c000 | 618 | #define WLAN_ANALOG_INTF_BASE_ADDRESS 0x0001c000 |
617 | #define WLAN_MAC_BASE_ADDRESS 0x00020000 | 619 | #define WLAN_MAC_BASE_ADDRESS ar->regs->wlan_mac_base_address |
618 | #define EFUSE_BASE_ADDRESS 0x00030000 | 620 | #define EFUSE_BASE_ADDRESS 0x00030000 |
619 | #define FPGA_REG_BASE_ADDRESS 0x00039000 | 621 | #define FPGA_REG_BASE_ADDRESS 0x00039000 |
620 | #define WLAN_UART2_BASE_ADDRESS 0x00054c00 | 622 | #define WLAN_UART2_BASE_ADDRESS 0x00054c00 |
@@ -814,4 +816,28 @@ ath10k_rx_desc_get_l3_pad_bytes(struct ath10k_hw_params *hw, | |||
814 | 816 | ||
815 | #define RTC_STATE_V_GET(x) (((x) & RTC_STATE_V_MASK) >> RTC_STATE_V_LSB) | 817 | #define RTC_STATE_V_GET(x) (((x) & RTC_STATE_V_MASK) >> RTC_STATE_V_LSB) |
816 | 818 | ||
819 | /* Register definitions for first generation ath10k cards. These cards include | ||
820 | * a mac thich has a register allocation similar to ath9k and at least some | ||
821 | * registers including the ones relevant for modifying the coverage class are | ||
822 | * identical to the ath9k definitions. | ||
823 | * These registers are usually managed by the ath10k firmware. However by | ||
824 | * overriding them it is possible to support coverage class modifications. | ||
825 | */ | ||
826 | #define WAVE1_PCU_ACK_CTS_TIMEOUT 0x8014 | ||
827 | #define WAVE1_PCU_ACK_CTS_TIMEOUT_MAX 0x00003FFF | ||
828 | #define WAVE1_PCU_ACK_CTS_TIMEOUT_ACK_MASK 0x00003FFF | ||
829 | #define WAVE1_PCU_ACK_CTS_TIMEOUT_ACK_LSB 0 | ||
830 | #define WAVE1_PCU_ACK_CTS_TIMEOUT_CTS_MASK 0x3FFF0000 | ||
831 | #define WAVE1_PCU_ACK_CTS_TIMEOUT_CTS_LSB 16 | ||
832 | |||
833 | #define WAVE1_PCU_GBL_IFS_SLOT 0x1070 | ||
834 | #define WAVE1_PCU_GBL_IFS_SLOT_MASK 0x0000FFFF | ||
835 | #define WAVE1_PCU_GBL_IFS_SLOT_MAX 0x0000FFFF | ||
836 | #define WAVE1_PCU_GBL_IFS_SLOT_LSB 0 | ||
837 | #define WAVE1_PCU_GBL_IFS_SLOT_RESV0 0xFFFF0000 | ||
838 | |||
839 | #define WAVE1_PHYCLK 0x801C | ||
840 | #define WAVE1_PHYCLK_USEC_MASK 0x0000007F | ||
841 | #define WAVE1_PHYCLK_USEC_LSB 0 | ||
842 | |||
817 | #endif /* _HW_H_ */ | 843 | #endif /* _HW_H_ */ |
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index e322b6df0ebc..717b2fad9a8a 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include <net/mac80211.h> | 20 | #include <net/mac80211.h> |
21 | #include <linux/etherdevice.h> | 21 | #include <linux/etherdevice.h> |
22 | #include <linux/acpi.h> | ||
22 | 23 | ||
23 | #include "hif.h" | 24 | #include "hif.h" |
24 | #include "core.h" | 25 | #include "core.h" |
@@ -3179,7 +3180,8 @@ static void ath10k_mac_vif_handle_tx_pause(struct ath10k_vif *arvif, | |||
3179 | ath10k_mac_vif_tx_unlock(arvif, pause_id); | 3180 | ath10k_mac_vif_tx_unlock(arvif, pause_id); |
3180 | break; | 3181 | break; |
3181 | default: | 3182 | default: |
3182 | ath10k_warn(ar, "received unknown tx pause action %d on vdev %i, ignoring\n", | 3183 | ath10k_dbg(ar, ATH10K_DBG_BOOT, |
3184 | "received unknown tx pause action %d on vdev %i, ignoring\n", | ||
3183 | action, arvif->vdev_id); | 3185 | action, arvif->vdev_id); |
3184 | break; | 3186 | break; |
3185 | } | 3187 | } |
@@ -3255,8 +3257,6 @@ ath10k_mac_tx_h_get_txmode(struct ath10k *ar, | |||
3255 | if (ar->htt.target_version_major < 3 && | 3257 | if (ar->htt.target_version_major < 3 && |
3256 | (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) && | 3258 | (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) && |
3257 | !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX, | 3259 | !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX, |
3258 | ar->running_fw->fw_file.fw_features) && | ||
3259 | !test_bit(ATH10K_FW_FEATURE_SKIP_NULL_FUNC_WAR, | ||
3260 | ar->running_fw->fw_file.fw_features)) | 3260 | ar->running_fw->fw_file.fw_features)) |
3261 | return ATH10K_HW_TXRX_MGMT; | 3261 | return ATH10K_HW_TXRX_MGMT; |
3262 | 3262 | ||
@@ -4929,7 +4929,9 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, | |||
4929 | } | 4929 | } |
4930 | 4930 | ||
4931 | ar->free_vdev_map &= ~(1LL << arvif->vdev_id); | 4931 | ar->free_vdev_map &= ~(1LL << arvif->vdev_id); |
4932 | spin_lock_bh(&ar->data_lock); | ||
4932 | list_add(&arvif->list, &ar->arvifs); | 4933 | list_add(&arvif->list, &ar->arvifs); |
4934 | spin_unlock_bh(&ar->data_lock); | ||
4933 | 4935 | ||
4934 | /* It makes no sense to have firmware do keepalives. mac80211 already | 4936 | /* It makes no sense to have firmware do keepalives. mac80211 already |
4935 | * takes care of this with idle connection polling. | 4937 | * takes care of this with idle connection polling. |
@@ -5080,7 +5082,9 @@ err_peer_delete: | |||
5080 | err_vdev_delete: | 5082 | err_vdev_delete: |
5081 | ath10k_wmi_vdev_delete(ar, arvif->vdev_id); | 5083 | ath10k_wmi_vdev_delete(ar, arvif->vdev_id); |
5082 | ar->free_vdev_map |= 1LL << arvif->vdev_id; | 5084 | ar->free_vdev_map |= 1LL << arvif->vdev_id; |
5085 | spin_lock_bh(&ar->data_lock); | ||
5083 | list_del(&arvif->list); | 5086 | list_del(&arvif->list); |
5087 | spin_unlock_bh(&ar->data_lock); | ||
5084 | 5088 | ||
5085 | err: | 5089 | err: |
5086 | if (arvif->beacon_buf) { | 5090 | if (arvif->beacon_buf) { |
@@ -5126,7 +5130,9 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, | |||
5126 | arvif->vdev_id, ret); | 5130 | arvif->vdev_id, ret); |
5127 | 5131 | ||
5128 | ar->free_vdev_map |= 1LL << arvif->vdev_id; | 5132 | ar->free_vdev_map |= 1LL << arvif->vdev_id; |
5133 | spin_lock_bh(&ar->data_lock); | ||
5129 | list_del(&arvif->list); | 5134 | list_del(&arvif->list); |
5135 | spin_unlock_bh(&ar->data_lock); | ||
5130 | 5136 | ||
5131 | if (arvif->vdev_type == WMI_VDEV_TYPE_AP || | 5137 | if (arvif->vdev_type == WMI_VDEV_TYPE_AP || |
5132 | arvif->vdev_type == WMI_VDEV_TYPE_IBSS) { | 5138 | arvif->vdev_type == WMI_VDEV_TYPE_IBSS) { |
@@ -5410,6 +5416,20 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, | |||
5410 | mutex_unlock(&ar->conf_mutex); | 5416 | mutex_unlock(&ar->conf_mutex); |
5411 | } | 5417 | } |
5412 | 5418 | ||
5419 | static void ath10k_mac_op_set_coverage_class(struct ieee80211_hw *hw, s16 value) | ||
5420 | { | ||
5421 | struct ath10k *ar = hw->priv; | ||
5422 | |||
5423 | /* This function should never be called if setting the coverage class | ||
5424 | * is not supported on this hardware. | ||
5425 | */ | ||
5426 | if (!ar->hw_params.hw_ops->set_coverage_class) { | ||
5427 | WARN_ON_ONCE(1); | ||
5428 | return; | ||
5429 | } | ||
5430 | ar->hw_params.hw_ops->set_coverage_class(ar, value); | ||
5431 | } | ||
5432 | |||
5413 | static int ath10k_hw_scan(struct ieee80211_hw *hw, | 5433 | static int ath10k_hw_scan(struct ieee80211_hw *hw, |
5414 | struct ieee80211_vif *vif, | 5434 | struct ieee80211_vif *vif, |
5415 | struct ieee80211_scan_request *hw_req) | 5435 | struct ieee80211_scan_request *hw_req) |
@@ -7435,6 +7455,7 @@ static const struct ieee80211_ops ath10k_ops = { | |||
7435 | .remove_interface = ath10k_remove_interface, | 7455 | .remove_interface = ath10k_remove_interface, |
7436 | .configure_filter = ath10k_configure_filter, | 7456 | .configure_filter = ath10k_configure_filter, |
7437 | .bss_info_changed = ath10k_bss_info_changed, | 7457 | .bss_info_changed = ath10k_bss_info_changed, |
7458 | .set_coverage_class = ath10k_mac_op_set_coverage_class, | ||
7438 | .hw_scan = ath10k_hw_scan, | 7459 | .hw_scan = ath10k_hw_scan, |
7439 | .cancel_hw_scan = ath10k_cancel_hw_scan, | 7460 | .cancel_hw_scan = ath10k_cancel_hw_scan, |
7440 | .set_key = ath10k_set_key, | 7461 | .set_key = ath10k_set_key, |
@@ -7789,6 +7810,109 @@ struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id) | |||
7789 | return arvif_iter.arvif; | 7810 | return arvif_iter.arvif; |
7790 | } | 7811 | } |
7791 | 7812 | ||
7813 | #define WRD_METHOD "WRDD" | ||
7814 | #define WRDD_WIFI (0x07) | ||
7815 | |||
7816 | static u32 ath10k_mac_wrdd_get_mcc(struct ath10k *ar, union acpi_object *wrdd) | ||
7817 | { | ||
7818 | union acpi_object *mcc_pkg; | ||
7819 | union acpi_object *domain_type; | ||
7820 | union acpi_object *mcc_value; | ||
7821 | u32 i; | ||
7822 | |||
7823 | if (wrdd->type != ACPI_TYPE_PACKAGE || | ||
7824 | wrdd->package.count < 2 || | ||
7825 | wrdd->package.elements[0].type != ACPI_TYPE_INTEGER || | ||
7826 | wrdd->package.elements[0].integer.value != 0) { | ||
7827 | ath10k_warn(ar, "ignoring malformed/unsupported wrdd structure\n"); | ||
7828 | return 0; | ||
7829 | } | ||
7830 | |||
7831 | for (i = 1; i < wrdd->package.count; ++i) { | ||
7832 | mcc_pkg = &wrdd->package.elements[i]; | ||
7833 | |||
7834 | if (mcc_pkg->type != ACPI_TYPE_PACKAGE) | ||
7835 | continue; | ||
7836 | if (mcc_pkg->package.count < 2) | ||
7837 | continue; | ||
7838 | if (mcc_pkg->package.elements[0].type != ACPI_TYPE_INTEGER || | ||
7839 | mcc_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) | ||
7840 | continue; | ||
7841 | |||
7842 | domain_type = &mcc_pkg->package.elements[0]; | ||
7843 | if (domain_type->integer.value != WRDD_WIFI) | ||
7844 | continue; | ||
7845 | |||
7846 | mcc_value = &mcc_pkg->package.elements[1]; | ||
7847 | return mcc_value->integer.value; | ||
7848 | } | ||
7849 | return 0; | ||
7850 | } | ||
7851 | |||
7852 | static int ath10k_mac_get_wrdd_regulatory(struct ath10k *ar, u16 *rd) | ||
7853 | { | ||
7854 | struct pci_dev __maybe_unused *pdev = to_pci_dev(ar->dev); | ||
7855 | acpi_handle root_handle; | ||
7856 | acpi_handle handle; | ||
7857 | struct acpi_buffer wrdd = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
7858 | acpi_status status; | ||
7859 | u32 alpha2_code; | ||
7860 | char alpha2[3]; | ||
7861 | |||
7862 | root_handle = ACPI_HANDLE(&pdev->dev); | ||
7863 | if (!root_handle) | ||
7864 | return -EOPNOTSUPP; | ||
7865 | |||
7866 | status = acpi_get_handle(root_handle, (acpi_string)WRD_METHOD, &handle); | ||
7867 | if (ACPI_FAILURE(status)) { | ||
7868 | ath10k_dbg(ar, ATH10K_DBG_BOOT, | ||
7869 | "failed to get wrd method %d\n", status); | ||
7870 | return -EIO; | ||
7871 | } | ||
7872 | |||
7873 | status = acpi_evaluate_object(handle, NULL, NULL, &wrdd); | ||
7874 | if (ACPI_FAILURE(status)) { | ||
7875 | ath10k_dbg(ar, ATH10K_DBG_BOOT, | ||
7876 | "failed to call wrdc %d\n", status); | ||
7877 | return -EIO; | ||
7878 | } | ||
7879 | |||
7880 | alpha2_code = ath10k_mac_wrdd_get_mcc(ar, wrdd.pointer); | ||
7881 | kfree(wrdd.pointer); | ||
7882 | if (!alpha2_code) | ||
7883 | return -EIO; | ||
7884 | |||
7885 | alpha2[0] = (alpha2_code >> 8) & 0xff; | ||
7886 | alpha2[1] = (alpha2_code >> 0) & 0xff; | ||
7887 | alpha2[2] = '\0'; | ||
7888 | |||
7889 | ath10k_dbg(ar, ATH10K_DBG_BOOT, | ||
7890 | "regulatory hint from WRDD (alpha2-code): %s\n", alpha2); | ||
7891 | |||
7892 | *rd = ath_regd_find_country_by_name(alpha2); | ||
7893 | if (*rd == 0xffff) | ||
7894 | return -EIO; | ||
7895 | |||
7896 | *rd |= COUNTRY_ERD_FLAG; | ||
7897 | return 0; | ||
7898 | } | ||
7899 | |||
7900 | static int ath10k_mac_init_rd(struct ath10k *ar) | ||
7901 | { | ||
7902 | int ret; | ||
7903 | u16 rd; | ||
7904 | |||
7905 | ret = ath10k_mac_get_wrdd_regulatory(ar, &rd); | ||
7906 | if (ret) { | ||
7907 | ath10k_dbg(ar, ATH10K_DBG_BOOT, | ||
7908 | "fallback to eeprom programmed regulatory settings\n"); | ||
7909 | rd = ar->hw_eeprom_rd; | ||
7910 | } | ||
7911 | |||
7912 | ar->ath_common.regulatory.current_rd = rd; | ||
7913 | return 0; | ||
7914 | } | ||
7915 | |||
7792 | int ath10k_mac_register(struct ath10k *ar) | 7916 | int ath10k_mac_register(struct ath10k *ar) |
7793 | { | 7917 | { |
7794 | static const u32 cipher_suites[] = { | 7918 | static const u32 cipher_suites[] = { |
@@ -8013,6 +8137,16 @@ int ath10k_mac_register(struct ath10k *ar) | |||
8013 | ar->running_fw->fw_file.fw_features)) | 8137 | ar->running_fw->fw_file.fw_features)) |
8014 | ar->ops->wake_tx_queue = NULL; | 8138 | ar->ops->wake_tx_queue = NULL; |
8015 | 8139 | ||
8140 | ret = ath10k_mac_init_rd(ar); | ||
8141 | if (ret) { | ||
8142 | ath10k_err(ar, "failed to derive regdom: %d\n", ret); | ||
8143 | goto err_dfs_detector_exit; | ||
8144 | } | ||
8145 | |||
8146 | /* Disable set_coverage_class for chipsets that do not support it. */ | ||
8147 | if (!ar->hw_params.hw_ops->set_coverage_class) | ||
8148 | ar->ops->set_coverage_class = NULL; | ||
8149 | |||
8016 | ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy, | 8150 | ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy, |
8017 | ath10k_reg_notifier); | 8151 | ath10k_reg_notifier); |
8018 | if (ret) { | 8152 | if (ret) { |
diff --git a/drivers/net/wireless/ath/ath10k/spectral.c b/drivers/net/wireless/ath/ath10k/spectral.c index 7d9b0da1b010..2ffc1fe4923b 100644 --- a/drivers/net/wireless/ath/ath10k/spectral.c +++ b/drivers/net/wireless/ath/ath10k/spectral.c | |||
@@ -338,7 +338,7 @@ static ssize_t write_file_spec_scan_ctl(struct file *file, | |||
338 | } else { | 338 | } else { |
339 | res = -EINVAL; | 339 | res = -EINVAL; |
340 | } | 340 | } |
341 | } else if (strncmp("background", buf, 9) == 0) { | 341 | } else if (strncmp("background", buf, 10) == 0) { |
342 | res = ath10k_spectral_scan_config(ar, SPECTRAL_BACKGROUND); | 342 | res = ath10k_spectral_scan_config(ar, SPECTRAL_BACKGROUND); |
343 | } else if (strncmp("manual", buf, 6) == 0) { | 343 | } else if (strncmp("manual", buf, 6) == 0) { |
344 | res = ath10k_spectral_scan_config(ar, SPECTRAL_MANUAL); | 344 | res = ath10k_spectral_scan_config(ar, SPECTRAL_MANUAL); |
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 54df425bb0fc..387c4eede388 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c | |||
@@ -4676,7 +4676,7 @@ static void ath10k_wmi_event_service_ready_work(struct work_struct *work) | |||
4676 | ar->fw_version_build = (__le32_to_cpu(arg.sw_ver1) & 0x0000ffff); | 4676 | ar->fw_version_build = (__le32_to_cpu(arg.sw_ver1) & 0x0000ffff); |
4677 | ar->phy_capability = __le32_to_cpu(arg.phy_capab); | 4677 | ar->phy_capability = __le32_to_cpu(arg.phy_capab); |
4678 | ar->num_rf_chains = __le32_to_cpu(arg.num_rf_chains); | 4678 | ar->num_rf_chains = __le32_to_cpu(arg.num_rf_chains); |
4679 | ar->ath_common.regulatory.current_rd = __le32_to_cpu(arg.eeprom_rd); | 4679 | ar->hw_eeprom_rd = __le32_to_cpu(arg.eeprom_rd); |
4680 | 4680 | ||
4681 | ath10k_dbg_dump(ar, ATH10K_DBG_WMI, NULL, "wmi svc: ", | 4681 | ath10k_dbg_dump(ar, ATH10K_DBG_WMI, NULL, "wmi svc: ", |
4682 | arg.service_map, arg.service_map_len); | 4682 | arg.service_map, arg.service_map_len); |
@@ -4931,6 +4931,23 @@ exit: | |||
4931 | return 0; | 4931 | return 0; |
4932 | } | 4932 | } |
4933 | 4933 | ||
4934 | static inline void ath10k_wmi_queue_set_coverage_class_work(struct ath10k *ar) | ||
4935 | { | ||
4936 | if (ar->hw_params.hw_ops->set_coverage_class) { | ||
4937 | spin_lock_bh(&ar->data_lock); | ||
4938 | |||
4939 | /* This call only ensures that the modified coverage class | ||
4940 | * persists in case the firmware sets the registers back to | ||
4941 | * their default value. So calling it is only necessary if the | ||
4942 | * coverage class has a non-zero value. | ||
4943 | */ | ||
4944 | if (ar->fw_coverage.coverage_class) | ||
4945 | queue_work(ar->workqueue, &ar->set_coverage_class_work); | ||
4946 | |||
4947 | spin_unlock_bh(&ar->data_lock); | ||
4948 | } | ||
4949 | } | ||
4950 | |||
4934 | static void ath10k_wmi_op_rx(struct ath10k *ar, struct sk_buff *skb) | 4951 | static void ath10k_wmi_op_rx(struct ath10k *ar, struct sk_buff *skb) |
4935 | { | 4952 | { |
4936 | struct wmi_cmd_hdr *cmd_hdr; | 4953 | struct wmi_cmd_hdr *cmd_hdr; |
@@ -4951,6 +4968,7 @@ static void ath10k_wmi_op_rx(struct ath10k *ar, struct sk_buff *skb) | |||
4951 | return; | 4968 | return; |
4952 | case WMI_SCAN_EVENTID: | 4969 | case WMI_SCAN_EVENTID: |
4953 | ath10k_wmi_event_scan(ar, skb); | 4970 | ath10k_wmi_event_scan(ar, skb); |
4971 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
4954 | break; | 4972 | break; |
4955 | case WMI_CHAN_INFO_EVENTID: | 4973 | case WMI_CHAN_INFO_EVENTID: |
4956 | ath10k_wmi_event_chan_info(ar, skb); | 4974 | ath10k_wmi_event_chan_info(ar, skb); |
@@ -4960,15 +4978,18 @@ static void ath10k_wmi_op_rx(struct ath10k *ar, struct sk_buff *skb) | |||
4960 | break; | 4978 | break; |
4961 | case WMI_DEBUG_MESG_EVENTID: | 4979 | case WMI_DEBUG_MESG_EVENTID: |
4962 | ath10k_wmi_event_debug_mesg(ar, skb); | 4980 | ath10k_wmi_event_debug_mesg(ar, skb); |
4981 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
4963 | break; | 4982 | break; |
4964 | case WMI_UPDATE_STATS_EVENTID: | 4983 | case WMI_UPDATE_STATS_EVENTID: |
4965 | ath10k_wmi_event_update_stats(ar, skb); | 4984 | ath10k_wmi_event_update_stats(ar, skb); |
4966 | break; | 4985 | break; |
4967 | case WMI_VDEV_START_RESP_EVENTID: | 4986 | case WMI_VDEV_START_RESP_EVENTID: |
4968 | ath10k_wmi_event_vdev_start_resp(ar, skb); | 4987 | ath10k_wmi_event_vdev_start_resp(ar, skb); |
4988 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
4969 | break; | 4989 | break; |
4970 | case WMI_VDEV_STOPPED_EVENTID: | 4990 | case WMI_VDEV_STOPPED_EVENTID: |
4971 | ath10k_wmi_event_vdev_stopped(ar, skb); | 4991 | ath10k_wmi_event_vdev_stopped(ar, skb); |
4992 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
4972 | break; | 4993 | break; |
4973 | case WMI_PEER_STA_KICKOUT_EVENTID: | 4994 | case WMI_PEER_STA_KICKOUT_EVENTID: |
4974 | ath10k_wmi_event_peer_sta_kickout(ar, skb); | 4995 | ath10k_wmi_event_peer_sta_kickout(ar, skb); |
@@ -4984,12 +5005,14 @@ static void ath10k_wmi_op_rx(struct ath10k *ar, struct sk_buff *skb) | |||
4984 | break; | 5005 | break; |
4985 | case WMI_ROAM_EVENTID: | 5006 | case WMI_ROAM_EVENTID: |
4986 | ath10k_wmi_event_roam(ar, skb); | 5007 | ath10k_wmi_event_roam(ar, skb); |
5008 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
4987 | break; | 5009 | break; |
4988 | case WMI_PROFILE_MATCH: | 5010 | case WMI_PROFILE_MATCH: |
4989 | ath10k_wmi_event_profile_match(ar, skb); | 5011 | ath10k_wmi_event_profile_match(ar, skb); |
4990 | break; | 5012 | break; |
4991 | case WMI_DEBUG_PRINT_EVENTID: | 5013 | case WMI_DEBUG_PRINT_EVENTID: |
4992 | ath10k_wmi_event_debug_print(ar, skb); | 5014 | ath10k_wmi_event_debug_print(ar, skb); |
5015 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
4993 | break; | 5016 | break; |
4994 | case WMI_PDEV_QVIT_EVENTID: | 5017 | case WMI_PDEV_QVIT_EVENTID: |
4995 | ath10k_wmi_event_pdev_qvit(ar, skb); | 5018 | ath10k_wmi_event_pdev_qvit(ar, skb); |
@@ -5038,6 +5061,7 @@ static void ath10k_wmi_op_rx(struct ath10k *ar, struct sk_buff *skb) | |||
5038 | return; | 5061 | return; |
5039 | case WMI_READY_EVENTID: | 5062 | case WMI_READY_EVENTID: |
5040 | ath10k_wmi_event_ready(ar, skb); | 5063 | ath10k_wmi_event_ready(ar, skb); |
5064 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
5041 | break; | 5065 | break; |
5042 | default: | 5066 | default: |
5043 | ath10k_warn(ar, "Unknown eventid: %d\n", id); | 5067 | ath10k_warn(ar, "Unknown eventid: %d\n", id); |
@@ -5081,6 +5105,7 @@ static void ath10k_wmi_10_1_op_rx(struct ath10k *ar, struct sk_buff *skb) | |||
5081 | return; | 5105 | return; |
5082 | case WMI_10X_SCAN_EVENTID: | 5106 | case WMI_10X_SCAN_EVENTID: |
5083 | ath10k_wmi_event_scan(ar, skb); | 5107 | ath10k_wmi_event_scan(ar, skb); |
5108 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
5084 | break; | 5109 | break; |
5085 | case WMI_10X_CHAN_INFO_EVENTID: | 5110 | case WMI_10X_CHAN_INFO_EVENTID: |
5086 | ath10k_wmi_event_chan_info(ar, skb); | 5111 | ath10k_wmi_event_chan_info(ar, skb); |
@@ -5090,15 +5115,18 @@ static void ath10k_wmi_10_1_op_rx(struct ath10k *ar, struct sk_buff *skb) | |||
5090 | break; | 5115 | break; |
5091 | case WMI_10X_DEBUG_MESG_EVENTID: | 5116 | case WMI_10X_DEBUG_MESG_EVENTID: |
5092 | ath10k_wmi_event_debug_mesg(ar, skb); | 5117 | ath10k_wmi_event_debug_mesg(ar, skb); |
5118 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
5093 | break; | 5119 | break; |
5094 | case WMI_10X_UPDATE_STATS_EVENTID: | 5120 | case WMI_10X_UPDATE_STATS_EVENTID: |
5095 | ath10k_wmi_event_update_stats(ar, skb); | 5121 | ath10k_wmi_event_update_stats(ar, skb); |
5096 | break; | 5122 | break; |
5097 | case WMI_10X_VDEV_START_RESP_EVENTID: | 5123 | case WMI_10X_VDEV_START_RESP_EVENTID: |
5098 | ath10k_wmi_event_vdev_start_resp(ar, skb); | 5124 | ath10k_wmi_event_vdev_start_resp(ar, skb); |
5125 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
5099 | break; | 5126 | break; |
5100 | case WMI_10X_VDEV_STOPPED_EVENTID: | 5127 | case WMI_10X_VDEV_STOPPED_EVENTID: |
5101 | ath10k_wmi_event_vdev_stopped(ar, skb); | 5128 | ath10k_wmi_event_vdev_stopped(ar, skb); |
5129 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
5102 | break; | 5130 | break; |
5103 | case WMI_10X_PEER_STA_KICKOUT_EVENTID: | 5131 | case WMI_10X_PEER_STA_KICKOUT_EVENTID: |
5104 | ath10k_wmi_event_peer_sta_kickout(ar, skb); | 5132 | ath10k_wmi_event_peer_sta_kickout(ar, skb); |
@@ -5114,12 +5142,14 @@ static void ath10k_wmi_10_1_op_rx(struct ath10k *ar, struct sk_buff *skb) | |||
5114 | break; | 5142 | break; |
5115 | case WMI_10X_ROAM_EVENTID: | 5143 | case WMI_10X_ROAM_EVENTID: |
5116 | ath10k_wmi_event_roam(ar, skb); | 5144 | ath10k_wmi_event_roam(ar, skb); |
5145 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
5117 | break; | 5146 | break; |
5118 | case WMI_10X_PROFILE_MATCH: | 5147 | case WMI_10X_PROFILE_MATCH: |
5119 | ath10k_wmi_event_profile_match(ar, skb); | 5148 | ath10k_wmi_event_profile_match(ar, skb); |
5120 | break; | 5149 | break; |
5121 | case WMI_10X_DEBUG_PRINT_EVENTID: | 5150 | case WMI_10X_DEBUG_PRINT_EVENTID: |
5122 | ath10k_wmi_event_debug_print(ar, skb); | 5151 | ath10k_wmi_event_debug_print(ar, skb); |
5152 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
5123 | break; | 5153 | break; |
5124 | case WMI_10X_PDEV_QVIT_EVENTID: | 5154 | case WMI_10X_PDEV_QVIT_EVENTID: |
5125 | ath10k_wmi_event_pdev_qvit(ar, skb); | 5155 | ath10k_wmi_event_pdev_qvit(ar, skb); |
@@ -5159,6 +5189,7 @@ static void ath10k_wmi_10_1_op_rx(struct ath10k *ar, struct sk_buff *skb) | |||
5159 | return; | 5189 | return; |
5160 | case WMI_10X_READY_EVENTID: | 5190 | case WMI_10X_READY_EVENTID: |
5161 | ath10k_wmi_event_ready(ar, skb); | 5191 | ath10k_wmi_event_ready(ar, skb); |
5192 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
5162 | break; | 5193 | break; |
5163 | case WMI_10X_PDEV_UTF_EVENTID: | 5194 | case WMI_10X_PDEV_UTF_EVENTID: |
5164 | /* ignore utf events */ | 5195 | /* ignore utf events */ |
@@ -5205,6 +5236,7 @@ static void ath10k_wmi_10_2_op_rx(struct ath10k *ar, struct sk_buff *skb) | |||
5205 | return; | 5236 | return; |
5206 | case WMI_10_2_SCAN_EVENTID: | 5237 | case WMI_10_2_SCAN_EVENTID: |
5207 | ath10k_wmi_event_scan(ar, skb); | 5238 | ath10k_wmi_event_scan(ar, skb); |
5239 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
5208 | break; | 5240 | break; |
5209 | case WMI_10_2_CHAN_INFO_EVENTID: | 5241 | case WMI_10_2_CHAN_INFO_EVENTID: |
5210 | ath10k_wmi_event_chan_info(ar, skb); | 5242 | ath10k_wmi_event_chan_info(ar, skb); |
@@ -5214,15 +5246,18 @@ static void ath10k_wmi_10_2_op_rx(struct ath10k *ar, struct sk_buff *skb) | |||
5214 | break; | 5246 | break; |
5215 | case WMI_10_2_DEBUG_MESG_EVENTID: | 5247 | case WMI_10_2_DEBUG_MESG_EVENTID: |
5216 | ath10k_wmi_event_debug_mesg(ar, skb); | 5248 | ath10k_wmi_event_debug_mesg(ar, skb); |
5249 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
5217 | break; | 5250 | break; |
5218 | case WMI_10_2_UPDATE_STATS_EVENTID: | 5251 | case WMI_10_2_UPDATE_STATS_EVENTID: |
5219 | ath10k_wmi_event_update_stats(ar, skb); | 5252 | ath10k_wmi_event_update_stats(ar, skb); |
5220 | break; | 5253 | break; |
5221 | case WMI_10_2_VDEV_START_RESP_EVENTID: | 5254 | case WMI_10_2_VDEV_START_RESP_EVENTID: |
5222 | ath10k_wmi_event_vdev_start_resp(ar, skb); | 5255 | ath10k_wmi_event_vdev_start_resp(ar, skb); |
5256 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
5223 | break; | 5257 | break; |
5224 | case WMI_10_2_VDEV_STOPPED_EVENTID: | 5258 | case WMI_10_2_VDEV_STOPPED_EVENTID: |
5225 | ath10k_wmi_event_vdev_stopped(ar, skb); | 5259 | ath10k_wmi_event_vdev_stopped(ar, skb); |
5260 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
5226 | break; | 5261 | break; |
5227 | case WMI_10_2_PEER_STA_KICKOUT_EVENTID: | 5262 | case WMI_10_2_PEER_STA_KICKOUT_EVENTID: |
5228 | ath10k_wmi_event_peer_sta_kickout(ar, skb); | 5263 | ath10k_wmi_event_peer_sta_kickout(ar, skb); |
@@ -5238,12 +5273,14 @@ static void ath10k_wmi_10_2_op_rx(struct ath10k *ar, struct sk_buff *skb) | |||
5238 | break; | 5273 | break; |
5239 | case WMI_10_2_ROAM_EVENTID: | 5274 | case WMI_10_2_ROAM_EVENTID: |
5240 | ath10k_wmi_event_roam(ar, skb); | 5275 | ath10k_wmi_event_roam(ar, skb); |
5276 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
5241 | break; | 5277 | break; |
5242 | case WMI_10_2_PROFILE_MATCH: | 5278 | case WMI_10_2_PROFILE_MATCH: |
5243 | ath10k_wmi_event_profile_match(ar, skb); | 5279 | ath10k_wmi_event_profile_match(ar, skb); |
5244 | break; | 5280 | break; |
5245 | case WMI_10_2_DEBUG_PRINT_EVENTID: | 5281 | case WMI_10_2_DEBUG_PRINT_EVENTID: |
5246 | ath10k_wmi_event_debug_print(ar, skb); | 5282 | ath10k_wmi_event_debug_print(ar, skb); |
5283 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
5247 | break; | 5284 | break; |
5248 | case WMI_10_2_PDEV_QVIT_EVENTID: | 5285 | case WMI_10_2_PDEV_QVIT_EVENTID: |
5249 | ath10k_wmi_event_pdev_qvit(ar, skb); | 5286 | ath10k_wmi_event_pdev_qvit(ar, skb); |
@@ -5274,15 +5311,18 @@ static void ath10k_wmi_10_2_op_rx(struct ath10k *ar, struct sk_buff *skb) | |||
5274 | break; | 5311 | break; |
5275 | case WMI_10_2_VDEV_STANDBY_REQ_EVENTID: | 5312 | case WMI_10_2_VDEV_STANDBY_REQ_EVENTID: |
5276 | ath10k_wmi_event_vdev_standby_req(ar, skb); | 5313 | ath10k_wmi_event_vdev_standby_req(ar, skb); |
5314 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
5277 | break; | 5315 | break; |
5278 | case WMI_10_2_VDEV_RESUME_REQ_EVENTID: | 5316 | case WMI_10_2_VDEV_RESUME_REQ_EVENTID: |
5279 | ath10k_wmi_event_vdev_resume_req(ar, skb); | 5317 | ath10k_wmi_event_vdev_resume_req(ar, skb); |
5318 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
5280 | break; | 5319 | break; |
5281 | case WMI_10_2_SERVICE_READY_EVENTID: | 5320 | case WMI_10_2_SERVICE_READY_EVENTID: |
5282 | ath10k_wmi_event_service_ready(ar, skb); | 5321 | ath10k_wmi_event_service_ready(ar, skb); |
5283 | return; | 5322 | return; |
5284 | case WMI_10_2_READY_EVENTID: | 5323 | case WMI_10_2_READY_EVENTID: |
5285 | ath10k_wmi_event_ready(ar, skb); | 5324 | ath10k_wmi_event_ready(ar, skb); |
5325 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
5286 | break; | 5326 | break; |
5287 | case WMI_10_2_PDEV_TEMPERATURE_EVENTID: | 5327 | case WMI_10_2_PDEV_TEMPERATURE_EVENTID: |
5288 | ath10k_wmi_event_temperature(ar, skb); | 5328 | ath10k_wmi_event_temperature(ar, skb); |
@@ -5345,12 +5385,14 @@ static void ath10k_wmi_10_4_op_rx(struct ath10k *ar, struct sk_buff *skb) | |||
5345 | break; | 5385 | break; |
5346 | case WMI_10_4_DEBUG_MESG_EVENTID: | 5386 | case WMI_10_4_DEBUG_MESG_EVENTID: |
5347 | ath10k_wmi_event_debug_mesg(ar, skb); | 5387 | ath10k_wmi_event_debug_mesg(ar, skb); |
5388 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
5348 | break; | 5389 | break; |
5349 | case WMI_10_4_SERVICE_READY_EVENTID: | 5390 | case WMI_10_4_SERVICE_READY_EVENTID: |
5350 | ath10k_wmi_event_service_ready(ar, skb); | 5391 | ath10k_wmi_event_service_ready(ar, skb); |
5351 | return; | 5392 | return; |
5352 | case WMI_10_4_SCAN_EVENTID: | 5393 | case WMI_10_4_SCAN_EVENTID: |
5353 | ath10k_wmi_event_scan(ar, skb); | 5394 | ath10k_wmi_event_scan(ar, skb); |
5395 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
5354 | break; | 5396 | break; |
5355 | case WMI_10_4_CHAN_INFO_EVENTID: | 5397 | case WMI_10_4_CHAN_INFO_EVENTID: |
5356 | ath10k_wmi_event_chan_info(ar, skb); | 5398 | ath10k_wmi_event_chan_info(ar, skb); |
@@ -5360,12 +5402,14 @@ static void ath10k_wmi_10_4_op_rx(struct ath10k *ar, struct sk_buff *skb) | |||
5360 | break; | 5402 | break; |
5361 | case WMI_10_4_READY_EVENTID: | 5403 | case WMI_10_4_READY_EVENTID: |
5362 | ath10k_wmi_event_ready(ar, skb); | 5404 | ath10k_wmi_event_ready(ar, skb); |
5405 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
5363 | break; | 5406 | break; |
5364 | case WMI_10_4_PEER_STA_KICKOUT_EVENTID: | 5407 | case WMI_10_4_PEER_STA_KICKOUT_EVENTID: |
5365 | ath10k_wmi_event_peer_sta_kickout(ar, skb); | 5408 | ath10k_wmi_event_peer_sta_kickout(ar, skb); |
5366 | break; | 5409 | break; |
5367 | case WMI_10_4_ROAM_EVENTID: | 5410 | case WMI_10_4_ROAM_EVENTID: |
5368 | ath10k_wmi_event_roam(ar, skb); | 5411 | ath10k_wmi_event_roam(ar, skb); |
5412 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
5369 | break; | 5413 | break; |
5370 | case WMI_10_4_HOST_SWBA_EVENTID: | 5414 | case WMI_10_4_HOST_SWBA_EVENTID: |
5371 | ath10k_wmi_event_host_swba(ar, skb); | 5415 | ath10k_wmi_event_host_swba(ar, skb); |
@@ -5375,12 +5419,15 @@ static void ath10k_wmi_10_4_op_rx(struct ath10k *ar, struct sk_buff *skb) | |||
5375 | break; | 5419 | break; |
5376 | case WMI_10_4_DEBUG_PRINT_EVENTID: | 5420 | case WMI_10_4_DEBUG_PRINT_EVENTID: |
5377 | ath10k_wmi_event_debug_print(ar, skb); | 5421 | ath10k_wmi_event_debug_print(ar, skb); |
5422 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
5378 | break; | 5423 | break; |
5379 | case WMI_10_4_VDEV_START_RESP_EVENTID: | 5424 | case WMI_10_4_VDEV_START_RESP_EVENTID: |
5380 | ath10k_wmi_event_vdev_start_resp(ar, skb); | 5425 | ath10k_wmi_event_vdev_start_resp(ar, skb); |
5426 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
5381 | break; | 5427 | break; |
5382 | case WMI_10_4_VDEV_STOPPED_EVENTID: | 5428 | case WMI_10_4_VDEV_STOPPED_EVENTID: |
5383 | ath10k_wmi_event_vdev_stopped(ar, skb); | 5429 | ath10k_wmi_event_vdev_stopped(ar, skb); |
5430 | ath10k_wmi_queue_set_coverage_class_work(ar); | ||
5384 | break; | 5431 | break; |
5385 | case WMI_10_4_WOW_WAKEUP_HOST_EVENTID: | 5432 | case WMI_10_4_WOW_WAKEUP_HOST_EVENTID: |
5386 | case WMI_10_4_PEER_RATECODE_LIST_EVENTID: | 5433 | case WMI_10_4_PEER_RATECODE_LIST_EVENTID: |
@@ -5397,6 +5444,9 @@ static void ath10k_wmi_10_4_op_rx(struct ath10k *ar, struct sk_buff *skb) | |||
5397 | case WMI_10_4_PDEV_BSS_CHAN_INFO_EVENTID: | 5444 | case WMI_10_4_PDEV_BSS_CHAN_INFO_EVENTID: |
5398 | ath10k_wmi_event_pdev_bss_chan_info(ar, skb); | 5445 | ath10k_wmi_event_pdev_bss_chan_info(ar, skb); |
5399 | break; | 5446 | break; |
5447 | case WMI_10_4_PDEV_TPC_CONFIG_EVENTID: | ||
5448 | ath10k_wmi_event_pdev_tpc_config(ar, skb); | ||
5449 | break; | ||
5400 | default: | 5450 | default: |
5401 | ath10k_warn(ar, "Unknown eventid: %d\n", id); | 5451 | ath10k_warn(ar, "Unknown eventid: %d\n", id); |
5402 | break; | 5452 | break; |
@@ -6096,6 +6146,7 @@ void ath10k_wmi_start_scan_init(struct ath10k *ar, | |||
6096 | | WMI_SCAN_EVENT_COMPLETED | 6146 | | WMI_SCAN_EVENT_COMPLETED |
6097 | | WMI_SCAN_EVENT_BSS_CHANNEL | 6147 | | WMI_SCAN_EVENT_BSS_CHANNEL |
6098 | | WMI_SCAN_EVENT_FOREIGN_CHANNEL | 6148 | | WMI_SCAN_EVENT_FOREIGN_CHANNEL |
6149 | | WMI_SCAN_EVENT_FOREIGN_CHANNEL_EXIT | ||
6099 | | WMI_SCAN_EVENT_DEQUEUED; | 6150 | | WMI_SCAN_EVENT_DEQUEUED; |
6100 | arg->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; | 6151 | arg->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; |
6101 | arg->n_bssids = 1; | 6152 | arg->n_bssids = 1; |
@@ -8153,6 +8204,7 @@ static const struct wmi_ops wmi_10_4_ops = { | |||
8153 | .get_vdev_subtype = ath10k_wmi_10_4_op_get_vdev_subtype, | 8204 | .get_vdev_subtype = ath10k_wmi_10_4_op_get_vdev_subtype, |
8154 | .gen_pdev_bss_chan_info_req = ath10k_wmi_10_2_op_gen_pdev_bss_chan_info, | 8205 | .gen_pdev_bss_chan_info_req = ath10k_wmi_10_2_op_gen_pdev_bss_chan_info, |
8155 | .gen_echo = ath10k_wmi_op_gen_echo, | 8206 | .gen_echo = ath10k_wmi_op_gen_echo, |
8207 | .gen_pdev_get_tpc_config = ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config, | ||
8156 | }; | 8208 | }; |
8157 | 8209 | ||
8158 | int ath10k_wmi_attach(struct ath10k *ar) | 8210 | int ath10k_wmi_attach(struct ath10k *ar) |
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 76eb33679d4b..8ec66e74d06d 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c | |||
@@ -75,6 +75,8 @@ struct ath6kl_sdio { | |||
75 | #define CMD53_ARG_FIXED_ADDRESS 0 | 75 | #define CMD53_ARG_FIXED_ADDRESS 0 |
76 | #define CMD53_ARG_INCR_ADDRESS 1 | 76 | #define CMD53_ARG_INCR_ADDRESS 1 |
77 | 77 | ||
78 | static int ath6kl_sdio_config(struct ath6kl *ar); | ||
79 | |||
78 | static inline struct ath6kl_sdio *ath6kl_sdio_priv(struct ath6kl *ar) | 80 | static inline struct ath6kl_sdio *ath6kl_sdio_priv(struct ath6kl *ar) |
79 | { | 81 | { |
80 | return ar->hif_priv; | 82 | return ar->hif_priv; |
@@ -526,8 +528,15 @@ static int ath6kl_sdio_power_on(struct ath6kl *ar) | |||
526 | */ | 528 | */ |
527 | msleep(10); | 529 | msleep(10); |
528 | 530 | ||
531 | ret = ath6kl_sdio_config(ar); | ||
532 | if (ret) { | ||
533 | ath6kl_err("Failed to config sdio: %d\n", ret); | ||
534 | goto out; | ||
535 | } | ||
536 | |||
529 | ar_sdio->is_disabled = false; | 537 | ar_sdio->is_disabled = false; |
530 | 538 | ||
539 | out: | ||
531 | return ret; | 540 | return ret; |
532 | } | 541 | } |
533 | 542 | ||
@@ -703,8 +712,10 @@ static void ath6kl_sdio_cleanup_scatter(struct ath6kl *ar) | |||
703 | * ath6kl_hif_rw_comp_handler() with status -ECANCELED so | 712 | * ath6kl_hif_rw_comp_handler() with status -ECANCELED so |
704 | * that the packet is properly freed? | 713 | * that the packet is properly freed? |
705 | */ | 714 | */ |
706 | if (s_req->busrequest) | 715 | if (s_req->busrequest) { |
716 | s_req->busrequest->scat_req = 0; | ||
707 | ath6kl_sdio_free_bus_req(ar_sdio, s_req->busrequest); | 717 | ath6kl_sdio_free_bus_req(ar_sdio, s_req->busrequest); |
718 | } | ||
708 | kfree(s_req->virt_dma_buf); | 719 | kfree(s_req->virt_dma_buf); |
709 | kfree(s_req->sgentries); | 720 | kfree(s_req->sgentries); |
710 | kfree(s_req); | 721 | kfree(s_req); |
@@ -712,6 +723,8 @@ static void ath6kl_sdio_cleanup_scatter(struct ath6kl *ar) | |||
712 | spin_lock_bh(&ar_sdio->scat_lock); | 723 | spin_lock_bh(&ar_sdio->scat_lock); |
713 | } | 724 | } |
714 | spin_unlock_bh(&ar_sdio->scat_lock); | 725 | spin_unlock_bh(&ar_sdio->scat_lock); |
726 | |||
727 | ar_sdio->scatter_enabled = false; | ||
715 | } | 728 | } |
716 | 729 | ||
717 | /* setup of HIF scatter resources */ | 730 | /* setup of HIF scatter resources */ |
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 3fd1cc98fd2f..84a6d12c3f8a 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c | |||
@@ -421,10 +421,6 @@ int ath6kl_wmi_dot11_hdr_remove(struct wmi *wmi, struct sk_buff *skb) | |||
421 | 421 | ||
422 | switch ((le16_to_cpu(wh.frame_control)) & | 422 | switch ((le16_to_cpu(wh.frame_control)) & |
423 | (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) { | 423 | (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) { |
424 | case 0: | ||
425 | memcpy(eth_hdr.h_dest, wh.addr1, ETH_ALEN); | ||
426 | memcpy(eth_hdr.h_source, wh.addr2, ETH_ALEN); | ||
427 | break; | ||
428 | case IEEE80211_FCTL_TODS: | 424 | case IEEE80211_FCTL_TODS: |
429 | memcpy(eth_hdr.h_dest, wh.addr3, ETH_ALEN); | 425 | memcpy(eth_hdr.h_dest, wh.addr3, ETH_ALEN); |
430 | memcpy(eth_hdr.h_source, wh.addr2, ETH_ALEN); | 426 | memcpy(eth_hdr.h_source, wh.addr2, ETH_ALEN); |
@@ -435,6 +431,10 @@ int ath6kl_wmi_dot11_hdr_remove(struct wmi *wmi, struct sk_buff *skb) | |||
435 | break; | 431 | break; |
436 | case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS: | 432 | case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS: |
437 | break; | 433 | break; |
434 | default: | ||
435 | memcpy(eth_hdr.h_dest, wh.addr1, ETH_ALEN); | ||
436 | memcpy(eth_hdr.h_source, wh.addr2, ETH_ALEN); | ||
437 | break; | ||
438 | } | 438 | } |
439 | 439 | ||
440 | skb_pull(skb, sizeof(struct ath6kl_llc_snap_hdr)); | 440 | skb_pull(skb, sizeof(struct ath6kl_llc_snap_hdr)); |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 26fc8ecfe8c4..378d3458fddb 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -91,7 +91,6 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
91 | #define ATH_RXBUF 512 | 91 | #define ATH_RXBUF 512 |
92 | #define ATH_TXBUF 512 | 92 | #define ATH_TXBUF 512 |
93 | #define ATH_TXBUF_RESERVE 5 | 93 | #define ATH_TXBUF_RESERVE 5 |
94 | #define ATH_MAX_QDEPTH (ATH_TXBUF / 4 - ATH_TXBUF_RESERVE) | ||
95 | #define ATH_TXMAXTRY 13 | 94 | #define ATH_TXMAXTRY 13 |
96 | #define ATH_MAX_SW_RETRIES 30 | 95 | #define ATH_MAX_SW_RETRIES 30 |
97 | 96 | ||
@@ -145,7 +144,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
145 | #define BAW_WITHIN(_start, _bawsz, _seqno) \ | 144 | #define BAW_WITHIN(_start, _bawsz, _seqno) \ |
146 | ((((_seqno) - (_start)) & 4095) < (_bawsz)) | 145 | ((((_seqno) - (_start)) & 4095) < (_bawsz)) |
147 | 146 | ||
148 | #define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)]) | 147 | #define ATH_AN_2_TID(_an, _tidno) ath_node_to_tid(_an, _tidno) |
149 | 148 | ||
150 | #define IS_HT_RATE(rate) (rate & 0x80) | 149 | #define IS_HT_RATE(rate) (rate & 0x80) |
151 | #define IS_CCK_RATE(rate) ((rate >= 0x18) && (rate <= 0x1e)) | 150 | #define IS_CCK_RATE(rate) ((rate >= 0x18) && (rate <= 0x1e)) |
@@ -164,7 +163,6 @@ struct ath_txq { | |||
164 | spinlock_t axq_lock; | 163 | spinlock_t axq_lock; |
165 | u32 axq_depth; | 164 | u32 axq_depth; |
166 | u32 axq_ampdu_depth; | 165 | u32 axq_ampdu_depth; |
167 | bool stopped; | ||
168 | bool axq_tx_inprogress; | 166 | bool axq_tx_inprogress; |
169 | struct list_head txq_fifo[ATH_TXFIFO_DEPTH]; | 167 | struct list_head txq_fifo[ATH_TXFIFO_DEPTH]; |
170 | u8 txq_headidx; | 168 | u8 txq_headidx; |
@@ -232,7 +230,6 @@ struct ath_buf { | |||
232 | 230 | ||
233 | struct ath_atx_tid { | 231 | struct ath_atx_tid { |
234 | struct list_head list; | 232 | struct list_head list; |
235 | struct sk_buff_head buf_q; | ||
236 | struct sk_buff_head retry_q; | 233 | struct sk_buff_head retry_q; |
237 | struct ath_node *an; | 234 | struct ath_node *an; |
238 | struct ath_txq *txq; | 235 | struct ath_txq *txq; |
@@ -247,13 +244,13 @@ struct ath_atx_tid { | |||
247 | s8 bar_index; | 244 | s8 bar_index; |
248 | bool active; | 245 | bool active; |
249 | bool clear_ps_filter; | 246 | bool clear_ps_filter; |
247 | bool has_queued; | ||
250 | }; | 248 | }; |
251 | 249 | ||
252 | struct ath_node { | 250 | struct ath_node { |
253 | struct ath_softc *sc; | 251 | struct ath_softc *sc; |
254 | struct ieee80211_sta *sta; /* station struct we're part of */ | 252 | struct ieee80211_sta *sta; /* station struct we're part of */ |
255 | struct ieee80211_vif *vif; /* interface with which we're associated */ | 253 | struct ieee80211_vif *vif; /* interface with which we're associated */ |
256 | struct ath_atx_tid tid[IEEE80211_NUM_TIDS]; | ||
257 | 254 | ||
258 | u16 maxampdu; | 255 | u16 maxampdu; |
259 | u8 mpdudensity; | 256 | u8 mpdudensity; |
@@ -276,7 +273,6 @@ struct ath_tx_control { | |||
276 | struct ath_node *an; | 273 | struct ath_node *an; |
277 | struct ieee80211_sta *sta; | 274 | struct ieee80211_sta *sta; |
278 | u8 paprd; | 275 | u8 paprd; |
279 | bool force_channel; | ||
280 | }; | 276 | }; |
281 | 277 | ||
282 | 278 | ||
@@ -293,7 +289,6 @@ struct ath_tx { | |||
293 | struct ath_descdma txdma; | 289 | struct ath_descdma txdma; |
294 | struct ath_txq *txq_map[IEEE80211_NUM_ACS]; | 290 | struct ath_txq *txq_map[IEEE80211_NUM_ACS]; |
295 | struct ath_txq *uapsdq; | 291 | struct ath_txq *uapsdq; |
296 | u32 txq_max_pending[IEEE80211_NUM_ACS]; | ||
297 | u16 max_aggr_framelen[IEEE80211_NUM_ACS][4][32]; | 292 | u16 max_aggr_framelen[IEEE80211_NUM_ACS][4][32]; |
298 | }; | 293 | }; |
299 | 294 | ||
@@ -421,6 +416,22 @@ struct ath_offchannel { | |||
421 | int duration; | 416 | int duration; |
422 | }; | 417 | }; |
423 | 418 | ||
419 | static inline struct ath_atx_tid * | ||
420 | ath_node_to_tid(struct ath_node *an, u8 tidno) | ||
421 | { | ||
422 | struct ieee80211_sta *sta = an->sta; | ||
423 | struct ieee80211_vif *vif = an->vif; | ||
424 | struct ieee80211_txq *txq; | ||
425 | |||
426 | BUG_ON(!vif); | ||
427 | if (sta) | ||
428 | txq = sta->txq[tidno % ARRAY_SIZE(sta->txq)]; | ||
429 | else | ||
430 | txq = vif->txq; | ||
431 | |||
432 | return (struct ath_atx_tid *) txq->drv_priv; | ||
433 | } | ||
434 | |||
424 | #define case_rtn_string(val) case val: return #val | 435 | #define case_rtn_string(val) case val: return #val |
425 | 436 | ||
426 | #define ath_for_each_chanctx(_sc, _ctx) \ | 437 | #define ath_for_each_chanctx(_sc, _ctx) \ |
@@ -575,7 +586,6 @@ void ath_tx_edma_tasklet(struct ath_softc *sc); | |||
575 | int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, | 586 | int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, |
576 | u16 tid, u16 *ssn); | 587 | u16 tid, u16 *ssn); |
577 | void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); | 588 | void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); |
578 | void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); | ||
579 | 589 | ||
580 | void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an); | 590 | void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an); |
581 | void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, | 591 | void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, |
@@ -585,6 +595,7 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw, | |||
585 | u16 tids, int nframes, | 595 | u16 tids, int nframes, |
586 | enum ieee80211_frame_release_type reason, | 596 | enum ieee80211_frame_release_type reason, |
587 | bool more_data); | 597 | bool more_data); |
598 | void ath9k_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *queue); | ||
588 | 599 | ||
589 | /********/ | 600 | /********/ |
590 | /* VIFs */ | 601 | /* VIFs */ |
diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 57e26a640477..929dd70f48eb 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c | |||
@@ -1010,7 +1010,6 @@ static void ath_scan_send_probe(struct ath_softc *sc, | |||
1010 | goto error; | 1010 | goto error; |
1011 | 1011 | ||
1012 | txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO]; | 1012 | txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO]; |
1013 | txctl.force_channel = true; | ||
1014 | if (ath_tx_start(sc->hw, skb, &txctl)) | 1013 | if (ath_tx_start(sc->hw, skb, &txctl)) |
1015 | goto error; | 1014 | goto error; |
1016 | 1015 | ||
@@ -1133,7 +1132,6 @@ ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp, | |||
1133 | memset(&txctl, 0, sizeof(txctl)); | 1132 | memset(&txctl, 0, sizeof(txctl)); |
1134 | txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO]; | 1133 | txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO]; |
1135 | txctl.sta = sta; | 1134 | txctl.sta = sta; |
1136 | txctl.force_channel = true; | ||
1137 | if (ath_tx_start(sc->hw, skb, &txctl)) { | 1135 | if (ath_tx_start(sc->hw, skb, &txctl)) { |
1138 | ieee80211_free_txskb(sc->hw, skb); | 1136 | ieee80211_free_txskb(sc->hw, skb); |
1139 | return false; | 1137 | return false; |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index c56e40ff35e5..89a94dd5f2cb 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -600,7 +600,6 @@ static int read_file_xmit(struct seq_file *file, void *data) | |||
600 | PR("MPDUs XRetried: ", xretries); | 600 | PR("MPDUs XRetried: ", xretries); |
601 | PR("Aggregates: ", a_aggr); | 601 | PR("Aggregates: ", a_aggr); |
602 | PR("AMPDUs Queued HW:", a_queued_hw); | 602 | PR("AMPDUs Queued HW:", a_queued_hw); |
603 | PR("AMPDUs Queued SW:", a_queued_sw); | ||
604 | PR("AMPDUs Completed:", a_completed); | 603 | PR("AMPDUs Completed:", a_completed); |
605 | PR("AMPDUs Retried: ", a_retries); | 604 | PR("AMPDUs Retried: ", a_retries); |
606 | PR("AMPDUs XRetried: ", a_xretries); | 605 | PR("AMPDUs XRetried: ", a_xretries); |
@@ -629,8 +628,7 @@ static void print_queue(struct ath_softc *sc, struct ath_txq *txq, | |||
629 | seq_printf(file, "%s: %d ", "qnum", txq->axq_qnum); | 628 | seq_printf(file, "%s: %d ", "qnum", txq->axq_qnum); |
630 | seq_printf(file, "%s: %2d ", "qdepth", txq->axq_depth); | 629 | seq_printf(file, "%s: %2d ", "qdepth", txq->axq_depth); |
631 | seq_printf(file, "%s: %2d ", "ampdu-depth", txq->axq_ampdu_depth); | 630 | seq_printf(file, "%s: %2d ", "ampdu-depth", txq->axq_ampdu_depth); |
632 | seq_printf(file, "%s: %3d ", "pending", txq->pending_frames); | 631 | seq_printf(file, "%s: %3d\n", "pending", txq->pending_frames); |
633 | seq_printf(file, "%s: %d\n", "stopped", txq->stopped); | ||
634 | 632 | ||
635 | ath_txq_unlock(sc, txq); | 633 | ath_txq_unlock(sc, txq); |
636 | } | 634 | } |
@@ -1208,7 +1206,6 @@ static const char ath9k_gstrings_stats[][ETH_GSTRING_LEN] = { | |||
1208 | AMKSTR(d_tx_mpdu_xretries), | 1206 | AMKSTR(d_tx_mpdu_xretries), |
1209 | AMKSTR(d_tx_aggregates), | 1207 | AMKSTR(d_tx_aggregates), |
1210 | AMKSTR(d_tx_ampdus_queued_hw), | 1208 | AMKSTR(d_tx_ampdus_queued_hw), |
1211 | AMKSTR(d_tx_ampdus_queued_sw), | ||
1212 | AMKSTR(d_tx_ampdus_completed), | 1209 | AMKSTR(d_tx_ampdus_completed), |
1213 | AMKSTR(d_tx_ampdu_retries), | 1210 | AMKSTR(d_tx_ampdu_retries), |
1214 | AMKSTR(d_tx_ampdu_xretries), | 1211 | AMKSTR(d_tx_ampdu_xretries), |
@@ -1288,7 +1285,6 @@ void ath9k_get_et_stats(struct ieee80211_hw *hw, | |||
1288 | AWDATA(xretries); | 1285 | AWDATA(xretries); |
1289 | AWDATA(a_aggr); | 1286 | AWDATA(a_aggr); |
1290 | AWDATA(a_queued_hw); | 1287 | AWDATA(a_queued_hw); |
1291 | AWDATA(a_queued_sw); | ||
1292 | AWDATA(a_completed); | 1288 | AWDATA(a_completed); |
1293 | AWDATA(a_retries); | 1289 | AWDATA(a_retries); |
1294 | AWDATA(a_xretries); | 1290 | AWDATA(a_xretries); |
@@ -1346,14 +1342,6 @@ int ath9k_init_debug(struct ath_hw *ah) | |||
1346 | read_file_xmit); | 1342 | read_file_xmit); |
1347 | debugfs_create_devm_seqfile(sc->dev, "queues", sc->debug.debugfs_phy, | 1343 | debugfs_create_devm_seqfile(sc->dev, "queues", sc->debug.debugfs_phy, |
1348 | read_file_queues); | 1344 | read_file_queues); |
1349 | debugfs_create_u32("qlen_bk", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, | ||
1350 | &sc->tx.txq_max_pending[IEEE80211_AC_BK]); | ||
1351 | debugfs_create_u32("qlen_be", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, | ||
1352 | &sc->tx.txq_max_pending[IEEE80211_AC_BE]); | ||
1353 | debugfs_create_u32("qlen_vi", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, | ||
1354 | &sc->tx.txq_max_pending[IEEE80211_AC_VI]); | ||
1355 | debugfs_create_u32("qlen_vo", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, | ||
1356 | &sc->tx.txq_max_pending[IEEE80211_AC_VO]); | ||
1357 | debugfs_create_devm_seqfile(sc->dev, "misc", sc->debug.debugfs_phy, | 1345 | debugfs_create_devm_seqfile(sc->dev, "misc", sc->debug.debugfs_phy, |
1358 | read_file_misc); | 1346 | read_file_misc); |
1359 | debugfs_create_devm_seqfile(sc->dev, "reset", sc->debug.debugfs_phy, | 1347 | debugfs_create_devm_seqfile(sc->dev, "reset", sc->debug.debugfs_phy, |
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index cd68c5f0e751..a078cdd3170d 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
@@ -147,7 +147,6 @@ struct ath_interrupt_stats { | |||
147 | * @completed: Total MPDUs (non-aggr) completed | 147 | * @completed: Total MPDUs (non-aggr) completed |
148 | * @a_aggr: Total no. of aggregates queued | 148 | * @a_aggr: Total no. of aggregates queued |
149 | * @a_queued_hw: Total AMPDUs queued to hardware | 149 | * @a_queued_hw: Total AMPDUs queued to hardware |
150 | * @a_queued_sw: Total AMPDUs queued to software queues | ||
151 | * @a_completed: Total AMPDUs completed | 150 | * @a_completed: Total AMPDUs completed |
152 | * @a_retries: No. of AMPDUs retried (SW) | 151 | * @a_retries: No. of AMPDUs retried (SW) |
153 | * @a_xretries: No. of AMPDUs dropped due to xretries | 152 | * @a_xretries: No. of AMPDUs dropped due to xretries |
@@ -174,7 +173,6 @@ struct ath_tx_stats { | |||
174 | u32 xretries; | 173 | u32 xretries; |
175 | u32 a_aggr; | 174 | u32 a_aggr; |
176 | u32 a_queued_hw; | 175 | u32 a_queued_hw; |
177 | u32 a_queued_sw; | ||
178 | u32 a_completed; | 176 | u32 a_completed; |
179 | u32 a_retries; | 177 | u32 a_retries; |
180 | u32 a_xretries; | 178 | u32 a_xretries; |
diff --git a/drivers/net/wireless/ath/ath9k/debug_sta.c b/drivers/net/wireless/ath/ath9k/debug_sta.c index b66cfa91364f..2a3a3c4671bc 100644 --- a/drivers/net/wireless/ath/ath9k/debug_sta.c +++ b/drivers/net/wireless/ath/ath9k/debug_sta.c | |||
@@ -52,8 +52,8 @@ static ssize_t read_file_node_aggr(struct file *file, char __user *user_buf, | |||
52 | "TID", "SEQ_START", "SEQ_NEXT", "BAW_SIZE", | 52 | "TID", "SEQ_START", "SEQ_NEXT", "BAW_SIZE", |
53 | "BAW_HEAD", "BAW_TAIL", "BAR_IDX", "SCHED", "PAUSED"); | 53 | "BAW_HEAD", "BAW_TAIL", "BAR_IDX", "SCHED", "PAUSED"); |
54 | 54 | ||
55 | for (tidno = 0, tid = &an->tid[tidno]; | 55 | for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { |
56 | tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { | 56 | tid = ath_node_to_tid(an, tidno); |
57 | txq = tid->txq; | 57 | txq = tid->txq; |
58 | ath_txq_lock(sc, txq); | 58 | ath_txq_lock(sc, txq); |
59 | if (tid->active) { | 59 | if (tid->active) { |
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index fd85f996c554..8e6dae23669b 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c | |||
@@ -244,8 +244,8 @@ int htc_connect_service(struct htc_target *target, | |||
244 | /* Find an available endpoint */ | 244 | /* Find an available endpoint */ |
245 | endpoint = get_next_avail_ep(target->endpoint); | 245 | endpoint = get_next_avail_ep(target->endpoint); |
246 | if (!endpoint) { | 246 | if (!endpoint) { |
247 | dev_err(target->dev, "Endpoint is not available for" | 247 | dev_err(target->dev, "Endpoint is not available for service %d\n", |
248 | "service %d\n", service_connreq->service_id); | 248 | service_connreq->service_id); |
249 | return -EINVAL; | 249 | return -EINVAL; |
250 | } | 250 | } |
251 | 251 | ||
@@ -382,7 +382,7 @@ static void ath9k_htc_fw_panic_report(struct htc_target *htc_handle, | |||
382 | break; | 382 | break; |
383 | } | 383 | } |
384 | default: | 384 | default: |
385 | dev_err(htc_handle->dev, "ath: uknown panic pattern!\n"); | 385 | dev_err(htc_handle->dev, "ath: unknown panic pattern!\n"); |
386 | break; | 386 | break; |
387 | } | 387 | } |
388 | } | 388 | } |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 368d9b313823..20794660d6ae 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -20,6 +20,8 @@ | |||
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/ath9k_platform.h> | 21 | #include <linux/ath9k_platform.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/of.h> | ||
24 | #include <linux/of_net.h> | ||
23 | #include <linux/relay.h> | 25 | #include <linux/relay.h> |
24 | #include <net/ieee80211_radiotap.h> | 26 | #include <net/ieee80211_radiotap.h> |
25 | 27 | ||
@@ -358,7 +360,6 @@ static int ath9k_init_queues(struct ath_softc *sc) | |||
358 | for (i = 0; i < IEEE80211_NUM_ACS; i++) { | 360 | for (i = 0; i < IEEE80211_NUM_ACS; i++) { |
359 | sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i); | 361 | sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i); |
360 | sc->tx.txq_map[i]->mac80211_qnum = i; | 362 | sc->tx.txq_map[i]->mac80211_qnum = i; |
361 | sc->tx.txq_max_pending[i] = ATH_MAX_QDEPTH; | ||
362 | } | 363 | } |
363 | return 0; | 364 | return 0; |
364 | } | 365 | } |
@@ -555,6 +556,42 @@ static int ath9k_init_platform(struct ath_softc *sc) | |||
555 | return 0; | 556 | return 0; |
556 | } | 557 | } |
557 | 558 | ||
559 | static int ath9k_of_init(struct ath_softc *sc) | ||
560 | { | ||
561 | struct device_node *np = sc->dev->of_node; | ||
562 | struct ath_hw *ah = sc->sc_ah; | ||
563 | struct ath_common *common = ath9k_hw_common(ah); | ||
564 | enum ath_bus_type bus_type = common->bus_ops->ath_bus_type; | ||
565 | const char *mac; | ||
566 | char eeprom_name[100]; | ||
567 | int ret; | ||
568 | |||
569 | if (!of_device_is_available(np)) | ||
570 | return 0; | ||
571 | |||
572 | ath_dbg(common, CONFIG, "parsing configuration from OF node\n"); | ||
573 | |||
574 | if (of_property_read_bool(np, "qca,no-eeprom")) { | ||
575 | /* ath9k-eeprom-<bus>-<id>.bin */ | ||
576 | scnprintf(eeprom_name, sizeof(eeprom_name), | ||
577 | "ath9k-eeprom-%s-%s.bin", | ||
578 | ath_bus_type_to_string(bus_type), dev_name(ah->dev)); | ||
579 | |||
580 | ret = ath9k_eeprom_request(sc, eeprom_name); | ||
581 | if (ret) | ||
582 | return ret; | ||
583 | } | ||
584 | |||
585 | mac = of_get_mac_address(np); | ||
586 | if (mac) | ||
587 | ether_addr_copy(common->macaddr, mac); | ||
588 | |||
589 | ah->ah_flags &= ~AH_USE_EEPROM; | ||
590 | ah->ah_flags |= AH_NO_EEP_SWAP; | ||
591 | |||
592 | return 0; | ||
593 | } | ||
594 | |||
558 | static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | 595 | static int ath9k_init_softc(u16 devid, struct ath_softc *sc, |
559 | const struct ath_bus_ops *bus_ops) | 596 | const struct ath_bus_ops *bus_ops) |
560 | { | 597 | { |
@@ -611,6 +648,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
611 | if (ret) | 648 | if (ret) |
612 | return ret; | 649 | return ret; |
613 | 650 | ||
651 | ret = ath9k_of_init(sc); | ||
652 | if (ret) | ||
653 | return ret; | ||
654 | |||
614 | if (ath9k_led_active_high != -1) | 655 | if (ath9k_led_active_high != -1) |
615 | ah->config.led_active_high = ath9k_led_active_high == 1; | 656 | ah->config.led_active_high = ath9k_led_active_high == 1; |
616 | 657 | ||
@@ -883,6 +924,7 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
883 | hw->max_rate_tries = 10; | 924 | hw->max_rate_tries = 10; |
884 | hw->sta_data_size = sizeof(struct ath_node); | 925 | hw->sta_data_size = sizeof(struct ath_node); |
885 | hw->vif_data_size = sizeof(struct ath_vif); | 926 | hw->vif_data_size = sizeof(struct ath_vif); |
927 | hw->txq_data_size = sizeof(struct ath_atx_tid); | ||
886 | hw->extra_tx_headroom = 4; | 928 | hw->extra_tx_headroom = 4; |
887 | 929 | ||
888 | hw->wiphy->available_antennas_rx = BIT(ah->caps.max_rxchains) - 1; | 930 | hw->wiphy->available_antennas_rx = BIT(ah->caps.max_rxchains) - 1; |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index e9f32b52fc8c..59e3bd0f4c20 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1902,9 +1902,11 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
1902 | bool flush = false; | 1902 | bool flush = false; |
1903 | int ret = 0; | 1903 | int ret = 0; |
1904 | struct ieee80211_sta *sta = params->sta; | 1904 | struct ieee80211_sta *sta = params->sta; |
1905 | struct ath_node *an = (struct ath_node *)sta->drv_priv; | ||
1905 | enum ieee80211_ampdu_mlme_action action = params->action; | 1906 | enum ieee80211_ampdu_mlme_action action = params->action; |
1906 | u16 tid = params->tid; | 1907 | u16 tid = params->tid; |
1907 | u16 *ssn = ¶ms->ssn; | 1908 | u16 *ssn = ¶ms->ssn; |
1909 | struct ath_atx_tid *atid; | ||
1908 | 1910 | ||
1909 | mutex_lock(&sc->mutex); | 1911 | mutex_lock(&sc->mutex); |
1910 | 1912 | ||
@@ -1937,9 +1939,9 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
1937 | ath9k_ps_restore(sc); | 1939 | ath9k_ps_restore(sc); |
1938 | break; | 1940 | break; |
1939 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 1941 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
1940 | ath9k_ps_wakeup(sc); | 1942 | atid = ath_node_to_tid(an, tid); |
1941 | ath_tx_aggr_resume(sc, sta, tid); | 1943 | atid->baw_size = IEEE80211_MIN_AMPDU_BUF << |
1942 | ath9k_ps_restore(sc); | 1944 | sta->ht_cap.ampdu_factor; |
1943 | break; | 1945 | break; |
1944 | default: | 1946 | default: |
1945 | ath_err(ath9k_hw_common(sc->sc_ah), "Unknown AMPDU action\n"); | 1947 | ath_err(ath9k_hw_common(sc->sc_ah), "Unknown AMPDU action\n"); |
@@ -2701,4 +2703,5 @@ struct ieee80211_ops ath9k_ops = { | |||
2701 | .sw_scan_start = ath9k_sw_scan_start, | 2703 | .sw_scan_start = ath9k_sw_scan_start, |
2702 | .sw_scan_complete = ath9k_sw_scan_complete, | 2704 | .sw_scan_complete = ath9k_sw_scan_complete, |
2703 | .get_txpower = ath9k_get_txpower, | 2705 | .get_txpower = ath9k_get_txpower, |
2706 | .wake_tx_queue = ath9k_wake_tx_queue, | ||
2704 | }; | 2707 | }; |
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 0dd454acf22a..aff473dfa10d 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c | |||
@@ -26,7 +26,6 @@ static const struct pci_device_id ath_pci_id_table[] = { | |||
26 | { PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI */ | 26 | { PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI */ |
27 | { PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */ | 27 | { PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */ |
28 | { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI */ | 28 | { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI */ |
29 | { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */ | ||
30 | 29 | ||
31 | #ifdef CONFIG_ATH9K_PCOEM | 30 | #ifdef CONFIG_ATH9K_PCOEM |
32 | /* Mini PCI AR9220 MB92 cards: Compex WLM200NX, Wistron DNMA-92 */ | 31 | /* Mini PCI AR9220 MB92 cards: Compex WLM200NX, Wistron DNMA-92 */ |
@@ -37,7 +36,7 @@ static const struct pci_device_id ath_pci_id_table[] = { | |||
37 | .driver_data = ATH9K_PCI_LED_ACT_HI }, | 36 | .driver_data = ATH9K_PCI_LED_ACT_HI }, |
38 | #endif | 37 | #endif |
39 | 38 | ||
40 | { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */ | 39 | { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */ |
41 | 40 | ||
42 | #ifdef CONFIG_ATH9K_PCOEM | 41 | #ifdef CONFIG_ATH9K_PCOEM |
43 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | 42 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, |
@@ -85,7 +84,11 @@ static const struct pci_device_id ath_pci_id_table[] = { | |||
85 | 0x10CF, /* Fujitsu */ | 84 | 0x10CF, /* Fujitsu */ |
86 | 0x1536), | 85 | 0x1536), |
87 | .driver_data = ATH9K_PCI_D3_L1_WAR }, | 86 | .driver_data = ATH9K_PCI_D3_L1_WAR }, |
87 | #endif | ||
88 | 88 | ||
89 | { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */ | ||
90 | |||
91 | #ifdef CONFIG_ATH9K_PCOEM | ||
89 | /* AR9285 card for Asus */ | 92 | /* AR9285 card for Asus */ |
90 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | 93 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, |
91 | 0x002B, | 94 | 0x002B, |
diff --git a/drivers/net/wireless/ath/ath9k/rng.c b/drivers/net/wireless/ath/ath9k/rng.c index d38e50f96db7..568b1c6c2b2b 100644 --- a/drivers/net/wireless/ath/ath9k/rng.c +++ b/drivers/net/wireless/ath/ath9k/rng.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include "ar9003_phy.h" | 22 | #include "ar9003_phy.h" |
23 | 23 | ||
24 | #define ATH9K_RNG_BUF_SIZE 320 | 24 | #define ATH9K_RNG_BUF_SIZE 320 |
25 | #define ATH9K_RNG_ENTROPY(x) (((x) * 8 * 320) >> 10) /* quality: 320/1024 */ | 25 | #define ATH9K_RNG_ENTROPY(x) (((x) * 8 * 10) >> 5) /* quality: 10/32 */ |
26 | 26 | ||
27 | static int ath9k_rng_data_read(struct ath_softc *sc, u32 *buf, u32 buf_size) | 27 | static int ath9k_rng_data_read(struct ath_softc *sc, u32 *buf, u32 buf_size) |
28 | { | 28 | { |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 52bfbb988611..486afa98a5b8 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -67,6 +67,8 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, | |||
67 | struct ath_txq *txq, | 67 | struct ath_txq *txq, |
68 | struct ath_atx_tid *tid, | 68 | struct ath_atx_tid *tid, |
69 | struct sk_buff *skb); | 69 | struct sk_buff *skb); |
70 | static int ath_tx_prepare(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
71 | struct ath_tx_control *txctl); | ||
70 | 72 | ||
71 | enum { | 73 | enum { |
72 | MCS_HT20, | 74 | MCS_HT20, |
@@ -137,6 +139,26 @@ static void ath_tx_queue_tid(struct ath_softc *sc, struct ath_txq *txq, | |||
137 | list_add_tail(&tid->list, list); | 139 | list_add_tail(&tid->list, list); |
138 | } | 140 | } |
139 | 141 | ||
142 | void ath9k_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *queue) | ||
143 | { | ||
144 | struct ath_softc *sc = hw->priv; | ||
145 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
146 | struct ath_atx_tid *tid = (struct ath_atx_tid *) queue->drv_priv; | ||
147 | struct ath_txq *txq = tid->txq; | ||
148 | |||
149 | ath_dbg(common, QUEUE, "Waking TX queue: %pM (%d)\n", | ||
150 | queue->sta ? queue->sta->addr : queue->vif->addr, | ||
151 | tid->tidno); | ||
152 | |||
153 | ath_txq_lock(sc, txq); | ||
154 | |||
155 | tid->has_queued = true; | ||
156 | ath_tx_queue_tid(sc, txq, tid); | ||
157 | ath_txq_schedule(sc, txq); | ||
158 | |||
159 | ath_txq_unlock(sc, txq); | ||
160 | } | ||
161 | |||
140 | static struct ath_frame_info *get_frame_info(struct sk_buff *skb) | 162 | static struct ath_frame_info *get_frame_info(struct sk_buff *skb) |
141 | { | 163 | { |
142 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 164 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
@@ -164,7 +186,6 @@ static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta, | |||
164 | static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq, | 186 | static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq, |
165 | struct sk_buff *skb) | 187 | struct sk_buff *skb) |
166 | { | 188 | { |
167 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
168 | struct ath_frame_info *fi = get_frame_info(skb); | 189 | struct ath_frame_info *fi = get_frame_info(skb); |
169 | int q = fi->txq; | 190 | int q = fi->txq; |
170 | 191 | ||
@@ -175,14 +196,6 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq, | |||
175 | if (WARN_ON(--txq->pending_frames < 0)) | 196 | if (WARN_ON(--txq->pending_frames < 0)) |
176 | txq->pending_frames = 0; | 197 | txq->pending_frames = 0; |
177 | 198 | ||
178 | if (txq->stopped && | ||
179 | txq->pending_frames < sc->tx.txq_max_pending[q]) { | ||
180 | if (ath9k_is_chanctx_enabled()) | ||
181 | ieee80211_wake_queue(sc->hw, info->hw_queue); | ||
182 | else | ||
183 | ieee80211_wake_queue(sc->hw, q); | ||
184 | txq->stopped = false; | ||
185 | } | ||
186 | } | 199 | } |
187 | 200 | ||
188 | static struct ath_atx_tid * | 201 | static struct ath_atx_tid * |
@@ -192,9 +205,48 @@ ath_get_skb_tid(struct ath_softc *sc, struct ath_node *an, struct sk_buff *skb) | |||
192 | return ATH_AN_2_TID(an, tidno); | 205 | return ATH_AN_2_TID(an, tidno); |
193 | } | 206 | } |
194 | 207 | ||
208 | static struct sk_buff * | ||
209 | ath_tid_pull(struct ath_atx_tid *tid) | ||
210 | { | ||
211 | struct ieee80211_txq *txq = container_of((void*)tid, struct ieee80211_txq, drv_priv); | ||
212 | struct ath_softc *sc = tid->an->sc; | ||
213 | struct ieee80211_hw *hw = sc->hw; | ||
214 | struct ath_tx_control txctl = { | ||
215 | .txq = tid->txq, | ||
216 | .sta = tid->an->sta, | ||
217 | }; | ||
218 | struct sk_buff *skb; | ||
219 | struct ath_frame_info *fi; | ||
220 | int q; | ||
221 | |||
222 | if (!tid->has_queued) | ||
223 | return NULL; | ||
224 | |||
225 | skb = ieee80211_tx_dequeue(hw, txq); | ||
226 | if (!skb) { | ||
227 | tid->has_queued = false; | ||
228 | return NULL; | ||
229 | } | ||
230 | |||
231 | if (ath_tx_prepare(hw, skb, &txctl)) { | ||
232 | ieee80211_free_txskb(hw, skb); | ||
233 | return NULL; | ||
234 | } | ||
235 | |||
236 | q = skb_get_queue_mapping(skb); | ||
237 | if (tid->txq == sc->tx.txq_map[q]) { | ||
238 | fi = get_frame_info(skb); | ||
239 | fi->txq = q; | ||
240 | ++tid->txq->pending_frames; | ||
241 | } | ||
242 | |||
243 | return skb; | ||
244 | } | ||
245 | |||
246 | |||
195 | static bool ath_tid_has_buffered(struct ath_atx_tid *tid) | 247 | static bool ath_tid_has_buffered(struct ath_atx_tid *tid) |
196 | { | 248 | { |
197 | return !skb_queue_empty(&tid->buf_q) || !skb_queue_empty(&tid->retry_q); | 249 | return !skb_queue_empty(&tid->retry_q) || tid->has_queued; |
198 | } | 250 | } |
199 | 251 | ||
200 | static struct sk_buff *ath_tid_dequeue(struct ath_atx_tid *tid) | 252 | static struct sk_buff *ath_tid_dequeue(struct ath_atx_tid *tid) |
@@ -203,46 +255,11 @@ static struct sk_buff *ath_tid_dequeue(struct ath_atx_tid *tid) | |||
203 | 255 | ||
204 | skb = __skb_dequeue(&tid->retry_q); | 256 | skb = __skb_dequeue(&tid->retry_q); |
205 | if (!skb) | 257 | if (!skb) |
206 | skb = __skb_dequeue(&tid->buf_q); | 258 | skb = ath_tid_pull(tid); |
207 | 259 | ||
208 | return skb; | 260 | return skb; |
209 | } | 261 | } |
210 | 262 | ||
211 | /* | ||
212 | * ath_tx_tid_change_state: | ||
213 | * - clears a-mpdu flag of previous session | ||
214 | * - force sequence number allocation to fix next BlockAck Window | ||
215 | */ | ||
216 | static void | ||
217 | ath_tx_tid_change_state(struct ath_softc *sc, struct ath_atx_tid *tid) | ||
218 | { | ||
219 | struct ath_txq *txq = tid->txq; | ||
220 | struct ieee80211_tx_info *tx_info; | ||
221 | struct sk_buff *skb, *tskb; | ||
222 | struct ath_buf *bf; | ||
223 | struct ath_frame_info *fi; | ||
224 | |||
225 | skb_queue_walk_safe(&tid->buf_q, skb, tskb) { | ||
226 | fi = get_frame_info(skb); | ||
227 | bf = fi->bf; | ||
228 | |||
229 | tx_info = IEEE80211_SKB_CB(skb); | ||
230 | tx_info->flags &= ~IEEE80211_TX_CTL_AMPDU; | ||
231 | |||
232 | if (bf) | ||
233 | continue; | ||
234 | |||
235 | bf = ath_tx_setup_buffer(sc, txq, tid, skb); | ||
236 | if (!bf) { | ||
237 | __skb_unlink(skb, &tid->buf_q); | ||
238 | ath_txq_skb_done(sc, txq, skb); | ||
239 | ieee80211_free_txskb(sc->hw, skb); | ||
240 | continue; | ||
241 | } | ||
242 | } | ||
243 | |||
244 | } | ||
245 | |||
246 | static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | 263 | static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) |
247 | { | 264 | { |
248 | struct ath_txq *txq = tid->txq; | 265 | struct ath_txq *txq = tid->txq; |
@@ -883,20 +900,16 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, | |||
883 | 900 | ||
884 | static struct ath_buf * | 901 | static struct ath_buf * |
885 | ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq, | 902 | ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq, |
886 | struct ath_atx_tid *tid, struct sk_buff_head **q) | 903 | struct ath_atx_tid *tid) |
887 | { | 904 | { |
888 | struct ieee80211_tx_info *tx_info; | 905 | struct ieee80211_tx_info *tx_info; |
889 | struct ath_frame_info *fi; | 906 | struct ath_frame_info *fi; |
890 | struct sk_buff *skb; | 907 | struct sk_buff *skb, *first_skb = NULL; |
891 | struct ath_buf *bf; | 908 | struct ath_buf *bf; |
892 | u16 seqno; | 909 | u16 seqno; |
893 | 910 | ||
894 | while (1) { | 911 | while (1) { |
895 | *q = &tid->retry_q; | 912 | skb = ath_tid_dequeue(tid); |
896 | if (skb_queue_empty(*q)) | ||
897 | *q = &tid->buf_q; | ||
898 | |||
899 | skb = skb_peek(*q); | ||
900 | if (!skb) | 913 | if (!skb) |
901 | break; | 914 | break; |
902 | 915 | ||
@@ -908,7 +921,6 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq, | |||
908 | bf->bf_state.stale = false; | 921 | bf->bf_state.stale = false; |
909 | 922 | ||
910 | if (!bf) { | 923 | if (!bf) { |
911 | __skb_unlink(skb, *q); | ||
912 | ath_txq_skb_done(sc, txq, skb); | 924 | ath_txq_skb_done(sc, txq, skb); |
913 | ieee80211_free_txskb(sc->hw, skb); | 925 | ieee80211_free_txskb(sc->hw, skb); |
914 | continue; | 926 | continue; |
@@ -937,8 +949,20 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq, | |||
937 | seqno = bf->bf_state.seqno; | 949 | seqno = bf->bf_state.seqno; |
938 | 950 | ||
939 | /* do not step over block-ack window */ | 951 | /* do not step over block-ack window */ |
940 | if (!BAW_WITHIN(tid->seq_start, tid->baw_size, seqno)) | 952 | if (!BAW_WITHIN(tid->seq_start, tid->baw_size, seqno)) { |
953 | __skb_queue_tail(&tid->retry_q, skb); | ||
954 | |||
955 | /* If there are other skbs in the retry q, they are | ||
956 | * probably within the BAW, so loop immediately to get | ||
957 | * one of them. Otherwise the queue can get stuck. */ | ||
958 | if (!skb_queue_is_first(&tid->retry_q, skb) && | ||
959 | !WARN_ON(skb == first_skb)) { | ||
960 | if(!first_skb) /* infinite loop prevention */ | ||
961 | first_skb = skb; | ||
962 | continue; | ||
963 | } | ||
941 | break; | 964 | break; |
965 | } | ||
942 | 966 | ||
943 | if (tid->bar_index > ATH_BA_INDEX(tid->seq_start, seqno)) { | 967 | if (tid->bar_index > ATH_BA_INDEX(tid->seq_start, seqno)) { |
944 | struct ath_tx_status ts = {}; | 968 | struct ath_tx_status ts = {}; |
@@ -946,7 +970,6 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq, | |||
946 | 970 | ||
947 | INIT_LIST_HEAD(&bf_head); | 971 | INIT_LIST_HEAD(&bf_head); |
948 | list_add(&bf->list, &bf_head); | 972 | list_add(&bf->list, &bf_head); |
949 | __skb_unlink(skb, *q); | ||
950 | ath_tx_update_baw(sc, tid, seqno); | 973 | ath_tx_update_baw(sc, tid, seqno); |
951 | ath_tx_complete_buf(sc, bf, txq, &bf_head, NULL, &ts, 0); | 974 | ath_tx_complete_buf(sc, bf, txq, &bf_head, NULL, &ts, 0); |
952 | continue; | 975 | continue; |
@@ -958,11 +981,10 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq, | |||
958 | return NULL; | 981 | return NULL; |
959 | } | 982 | } |
960 | 983 | ||
961 | static bool | 984 | static int |
962 | ath_tx_form_aggr(struct ath_softc *sc, struct ath_txq *txq, | 985 | ath_tx_form_aggr(struct ath_softc *sc, struct ath_txq *txq, |
963 | struct ath_atx_tid *tid, struct list_head *bf_q, | 986 | struct ath_atx_tid *tid, struct list_head *bf_q, |
964 | struct ath_buf *bf_first, struct sk_buff_head *tid_q, | 987 | struct ath_buf *bf_first) |
965 | int *aggr_len) | ||
966 | { | 988 | { |
967 | #define PADBYTES(_len) ((4 - ((_len) % 4)) % 4) | 989 | #define PADBYTES(_len) ((4 - ((_len) % 4)) % 4) |
968 | struct ath_buf *bf = bf_first, *bf_prev = NULL; | 990 | struct ath_buf *bf = bf_first, *bf_prev = NULL; |
@@ -972,12 +994,13 @@ ath_tx_form_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
972 | struct ieee80211_tx_info *tx_info; | 994 | struct ieee80211_tx_info *tx_info; |
973 | struct ath_frame_info *fi; | 995 | struct ath_frame_info *fi; |
974 | struct sk_buff *skb; | 996 | struct sk_buff *skb; |
975 | bool closed = false; | 997 | |
976 | 998 | ||
977 | bf = bf_first; | 999 | bf = bf_first; |
978 | aggr_limit = ath_lookup_rate(sc, bf, tid); | 1000 | aggr_limit = ath_lookup_rate(sc, bf, tid); |
979 | 1001 | ||
980 | do { | 1002 | while (bf) |
1003 | { | ||
981 | skb = bf->bf_mpdu; | 1004 | skb = bf->bf_mpdu; |
982 | fi = get_frame_info(skb); | 1005 | fi = get_frame_info(skb); |
983 | 1006 | ||
@@ -986,12 +1009,12 @@ ath_tx_form_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
986 | if (nframes) { | 1009 | if (nframes) { |
987 | if (aggr_limit < al + bpad + al_delta || | 1010 | if (aggr_limit < al + bpad + al_delta || |
988 | ath_lookup_legacy(bf) || nframes >= h_baw) | 1011 | ath_lookup_legacy(bf) || nframes >= h_baw) |
989 | break; | 1012 | goto stop; |
990 | 1013 | ||
991 | tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); | 1014 | tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); |
992 | if ((tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) || | 1015 | if ((tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) || |
993 | !(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) | 1016 | !(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) |
994 | break; | 1017 | goto stop; |
995 | } | 1018 | } |
996 | 1019 | ||
997 | /* add padding for previous frame to aggregation length */ | 1020 | /* add padding for previous frame to aggregation length */ |
@@ -1013,20 +1036,18 @@ ath_tx_form_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
1013 | ath_tx_addto_baw(sc, tid, bf); | 1036 | ath_tx_addto_baw(sc, tid, bf); |
1014 | bf->bf_state.ndelim = ndelim; | 1037 | bf->bf_state.ndelim = ndelim; |
1015 | 1038 | ||
1016 | __skb_unlink(skb, tid_q); | ||
1017 | list_add_tail(&bf->list, bf_q); | 1039 | list_add_tail(&bf->list, bf_q); |
1018 | if (bf_prev) | 1040 | if (bf_prev) |
1019 | bf_prev->bf_next = bf; | 1041 | bf_prev->bf_next = bf; |
1020 | 1042 | ||
1021 | bf_prev = bf; | 1043 | bf_prev = bf; |
1022 | 1044 | ||
1023 | bf = ath_tx_get_tid_subframe(sc, txq, tid, &tid_q); | 1045 | bf = ath_tx_get_tid_subframe(sc, txq, tid); |
1024 | if (!bf) { | 1046 | } |
1025 | closed = true; | 1047 | goto finish; |
1026 | break; | 1048 | stop: |
1027 | } | 1049 | __skb_queue_tail(&tid->retry_q, bf->bf_mpdu); |
1028 | } while (ath_tid_has_buffered(tid)); | 1050 | finish: |
1029 | |||
1030 | bf = bf_first; | 1051 | bf = bf_first; |
1031 | bf->bf_lastbf = bf_prev; | 1052 | bf->bf_lastbf = bf_prev; |
1032 | 1053 | ||
@@ -1037,9 +1058,7 @@ ath_tx_form_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
1037 | TX_STAT_INC(txq->axq_qnum, a_aggr); | 1058 | TX_STAT_INC(txq->axq_qnum, a_aggr); |
1038 | } | 1059 | } |
1039 | 1060 | ||
1040 | *aggr_len = al; | 1061 | return al; |
1041 | |||
1042 | return closed; | ||
1043 | #undef PADBYTES | 1062 | #undef PADBYTES |
1044 | } | 1063 | } |
1045 | 1064 | ||
@@ -1416,18 +1435,15 @@ static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf, | |||
1416 | static void | 1435 | static void |
1417 | ath_tx_form_burst(struct ath_softc *sc, struct ath_txq *txq, | 1436 | ath_tx_form_burst(struct ath_softc *sc, struct ath_txq *txq, |
1418 | struct ath_atx_tid *tid, struct list_head *bf_q, | 1437 | struct ath_atx_tid *tid, struct list_head *bf_q, |
1419 | struct ath_buf *bf_first, struct sk_buff_head *tid_q) | 1438 | struct ath_buf *bf_first) |
1420 | { | 1439 | { |
1421 | struct ath_buf *bf = bf_first, *bf_prev = NULL; | 1440 | struct ath_buf *bf = bf_first, *bf_prev = NULL; |
1422 | struct sk_buff *skb; | ||
1423 | int nframes = 0; | 1441 | int nframes = 0; |
1424 | 1442 | ||
1425 | do { | 1443 | do { |
1426 | struct ieee80211_tx_info *tx_info; | 1444 | struct ieee80211_tx_info *tx_info; |
1427 | skb = bf->bf_mpdu; | ||
1428 | 1445 | ||
1429 | nframes++; | 1446 | nframes++; |
1430 | __skb_unlink(skb, tid_q); | ||
1431 | list_add_tail(&bf->list, bf_q); | 1447 | list_add_tail(&bf->list, bf_q); |
1432 | if (bf_prev) | 1448 | if (bf_prev) |
1433 | bf_prev->bf_next = bf; | 1449 | bf_prev->bf_next = bf; |
@@ -1436,13 +1452,15 @@ ath_tx_form_burst(struct ath_softc *sc, struct ath_txq *txq, | |||
1436 | if (nframes >= 2) | 1452 | if (nframes >= 2) |
1437 | break; | 1453 | break; |
1438 | 1454 | ||
1439 | bf = ath_tx_get_tid_subframe(sc, txq, tid, &tid_q); | 1455 | bf = ath_tx_get_tid_subframe(sc, txq, tid); |
1440 | if (!bf) | 1456 | if (!bf) |
1441 | break; | 1457 | break; |
1442 | 1458 | ||
1443 | tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); | 1459 | tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); |
1444 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) | 1460 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { |
1461 | __skb_queue_tail(&tid->retry_q, bf->bf_mpdu); | ||
1445 | break; | 1462 | break; |
1463 | } | ||
1446 | 1464 | ||
1447 | ath_set_rates(tid->an->vif, tid->an->sta, bf); | 1465 | ath_set_rates(tid->an->vif, tid->an->sta, bf); |
1448 | } while (1); | 1466 | } while (1); |
@@ -1453,34 +1471,33 @@ static bool ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
1453 | { | 1471 | { |
1454 | struct ath_buf *bf; | 1472 | struct ath_buf *bf; |
1455 | struct ieee80211_tx_info *tx_info; | 1473 | struct ieee80211_tx_info *tx_info; |
1456 | struct sk_buff_head *tid_q; | ||
1457 | struct list_head bf_q; | 1474 | struct list_head bf_q; |
1458 | int aggr_len = 0; | 1475 | int aggr_len = 0; |
1459 | bool aggr, last = true; | 1476 | bool aggr; |
1460 | 1477 | ||
1461 | if (!ath_tid_has_buffered(tid)) | 1478 | if (!ath_tid_has_buffered(tid)) |
1462 | return false; | 1479 | return false; |
1463 | 1480 | ||
1464 | INIT_LIST_HEAD(&bf_q); | 1481 | INIT_LIST_HEAD(&bf_q); |
1465 | 1482 | ||
1466 | bf = ath_tx_get_tid_subframe(sc, txq, tid, &tid_q); | 1483 | bf = ath_tx_get_tid_subframe(sc, txq, tid); |
1467 | if (!bf) | 1484 | if (!bf) |
1468 | return false; | 1485 | return false; |
1469 | 1486 | ||
1470 | tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); | 1487 | tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); |
1471 | aggr = !!(tx_info->flags & IEEE80211_TX_CTL_AMPDU); | 1488 | aggr = !!(tx_info->flags & IEEE80211_TX_CTL_AMPDU); |
1472 | if ((aggr && txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) || | 1489 | if ((aggr && txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) || |
1473 | (!aggr && txq->axq_depth >= ATH_NON_AGGR_MIN_QDEPTH)) { | 1490 | (!aggr && txq->axq_depth >= ATH_NON_AGGR_MIN_QDEPTH)) { |
1491 | __skb_queue_tail(&tid->retry_q, bf->bf_mpdu); | ||
1474 | *stop = true; | 1492 | *stop = true; |
1475 | return false; | 1493 | return false; |
1476 | } | 1494 | } |
1477 | 1495 | ||
1478 | ath_set_rates(tid->an->vif, tid->an->sta, bf); | 1496 | ath_set_rates(tid->an->vif, tid->an->sta, bf); |
1479 | if (aggr) | 1497 | if (aggr) |
1480 | last = ath_tx_form_aggr(sc, txq, tid, &bf_q, bf, | 1498 | aggr_len = ath_tx_form_aggr(sc, txq, tid, &bf_q, bf); |
1481 | tid_q, &aggr_len); | ||
1482 | else | 1499 | else |
1483 | ath_tx_form_burst(sc, txq, tid, &bf_q, bf, tid_q); | 1500 | ath_tx_form_burst(sc, txq, tid, &bf_q, bf); |
1484 | 1501 | ||
1485 | if (list_empty(&bf_q)) | 1502 | if (list_empty(&bf_q)) |
1486 | return false; | 1503 | return false; |
@@ -1523,9 +1540,6 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, | |||
1523 | an->mpdudensity = density; | 1540 | an->mpdudensity = density; |
1524 | } | 1541 | } |
1525 | 1542 | ||
1526 | /* force sequence number allocation for pending frames */ | ||
1527 | ath_tx_tid_change_state(sc, txtid); | ||
1528 | |||
1529 | txtid->active = true; | 1543 | txtid->active = true; |
1530 | *ssn = txtid->seq_start = txtid->seq_next; | 1544 | *ssn = txtid->seq_start = txtid->seq_next; |
1531 | txtid->bar_index = -1; | 1545 | txtid->bar_index = -1; |
@@ -1550,7 +1564,6 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) | |||
1550 | ath_txq_lock(sc, txq); | 1564 | ath_txq_lock(sc, txq); |
1551 | txtid->active = false; | 1565 | txtid->active = false; |
1552 | ath_tx_flush_tid(sc, txtid); | 1566 | ath_tx_flush_tid(sc, txtid); |
1553 | ath_tx_tid_change_state(sc, txtid); | ||
1554 | ath_txq_unlock_complete(sc, txq); | 1567 | ath_txq_unlock_complete(sc, txq); |
1555 | } | 1568 | } |
1556 | 1569 | ||
@@ -1560,14 +1573,12 @@ void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, | |||
1560 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1573 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1561 | struct ath_atx_tid *tid; | 1574 | struct ath_atx_tid *tid; |
1562 | struct ath_txq *txq; | 1575 | struct ath_txq *txq; |
1563 | bool buffered; | ||
1564 | int tidno; | 1576 | int tidno; |
1565 | 1577 | ||
1566 | ath_dbg(common, XMIT, "%s called\n", __func__); | 1578 | ath_dbg(common, XMIT, "%s called\n", __func__); |
1567 | 1579 | ||
1568 | for (tidno = 0, tid = &an->tid[tidno]; | 1580 | for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { |
1569 | tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { | 1581 | tid = ath_node_to_tid(an, tidno); |
1570 | |||
1571 | txq = tid->txq; | 1582 | txq = tid->txq; |
1572 | 1583 | ||
1573 | ath_txq_lock(sc, txq); | 1584 | ath_txq_lock(sc, txq); |
@@ -1577,13 +1588,12 @@ void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, | |||
1577 | continue; | 1588 | continue; |
1578 | } | 1589 | } |
1579 | 1590 | ||
1580 | buffered = ath_tid_has_buffered(tid); | 1591 | if (!skb_queue_empty(&tid->retry_q)) |
1592 | ieee80211_sta_set_buffered(sta, tid->tidno, true); | ||
1581 | 1593 | ||
1582 | list_del_init(&tid->list); | 1594 | list_del_init(&tid->list); |
1583 | 1595 | ||
1584 | ath_txq_unlock(sc, txq); | 1596 | ath_txq_unlock(sc, txq); |
1585 | |||
1586 | ieee80211_sta_set_buffered(sta, tidno, buffered); | ||
1587 | } | 1597 | } |
1588 | } | 1598 | } |
1589 | 1599 | ||
@@ -1596,49 +1606,20 @@ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an) | |||
1596 | 1606 | ||
1597 | ath_dbg(common, XMIT, "%s called\n", __func__); | 1607 | ath_dbg(common, XMIT, "%s called\n", __func__); |
1598 | 1608 | ||
1599 | for (tidno = 0, tid = &an->tid[tidno]; | 1609 | for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { |
1600 | tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { | 1610 | tid = ath_node_to_tid(an, tidno); |
1601 | |||
1602 | txq = tid->txq; | 1611 | txq = tid->txq; |
1603 | 1612 | ||
1604 | ath_txq_lock(sc, txq); | 1613 | ath_txq_lock(sc, txq); |
1605 | tid->clear_ps_filter = true; | 1614 | tid->clear_ps_filter = true; |
1606 | |||
1607 | if (ath_tid_has_buffered(tid)) { | 1615 | if (ath_tid_has_buffered(tid)) { |
1608 | ath_tx_queue_tid(sc, txq, tid); | 1616 | ath_tx_queue_tid(sc, txq, tid); |
1609 | ath_txq_schedule(sc, txq); | 1617 | ath_txq_schedule(sc, txq); |
1610 | } | 1618 | } |
1611 | |||
1612 | ath_txq_unlock_complete(sc, txq); | 1619 | ath_txq_unlock_complete(sc, txq); |
1613 | } | 1620 | } |
1614 | } | 1621 | } |
1615 | 1622 | ||
1616 | void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, | ||
1617 | u16 tidno) | ||
1618 | { | ||
1619 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
1620 | struct ath_atx_tid *tid; | ||
1621 | struct ath_node *an; | ||
1622 | struct ath_txq *txq; | ||
1623 | |||
1624 | ath_dbg(common, XMIT, "%s called\n", __func__); | ||
1625 | |||
1626 | an = (struct ath_node *)sta->drv_priv; | ||
1627 | tid = ATH_AN_2_TID(an, tidno); | ||
1628 | txq = tid->txq; | ||
1629 | |||
1630 | ath_txq_lock(sc, txq); | ||
1631 | |||
1632 | tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; | ||
1633 | |||
1634 | if (ath_tid_has_buffered(tid)) { | ||
1635 | ath_tx_queue_tid(sc, txq, tid); | ||
1636 | ath_txq_schedule(sc, txq); | ||
1637 | } | ||
1638 | |||
1639 | ath_txq_unlock_complete(sc, txq); | ||
1640 | } | ||
1641 | |||
1642 | void ath9k_release_buffered_frames(struct ieee80211_hw *hw, | 1623 | void ath9k_release_buffered_frames(struct ieee80211_hw *hw, |
1643 | struct ieee80211_sta *sta, | 1624 | struct ieee80211_sta *sta, |
1644 | u16 tids, int nframes, | 1625 | u16 tids, int nframes, |
@@ -1651,7 +1632,6 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw, | |||
1651 | struct ieee80211_tx_info *info; | 1632 | struct ieee80211_tx_info *info; |
1652 | struct list_head bf_q; | 1633 | struct list_head bf_q; |
1653 | struct ath_buf *bf_tail = NULL, *bf; | 1634 | struct ath_buf *bf_tail = NULL, *bf; |
1654 | struct sk_buff_head *tid_q; | ||
1655 | int sent = 0; | 1635 | int sent = 0; |
1656 | int i; | 1636 | int i; |
1657 | 1637 | ||
@@ -1666,11 +1646,10 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw, | |||
1666 | 1646 | ||
1667 | ath_txq_lock(sc, tid->txq); | 1647 | ath_txq_lock(sc, tid->txq); |
1668 | while (nframes > 0) { | 1648 | while (nframes > 0) { |
1669 | bf = ath_tx_get_tid_subframe(sc, sc->tx.uapsdq, tid, &tid_q); | 1649 | bf = ath_tx_get_tid_subframe(sc, sc->tx.uapsdq, tid); |
1670 | if (!bf) | 1650 | if (!bf) |
1671 | break; | 1651 | break; |
1672 | 1652 | ||
1673 | __skb_unlink(bf->bf_mpdu, tid_q); | ||
1674 | list_add_tail(&bf->list, &bf_q); | 1653 | list_add_tail(&bf->list, &bf_q); |
1675 | ath_set_rates(tid->an->vif, tid->an->sta, bf); | 1654 | ath_set_rates(tid->an->vif, tid->an->sta, bf); |
1676 | if (bf_isampdu(bf)) { | 1655 | if (bf_isampdu(bf)) { |
@@ -1685,7 +1664,7 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw, | |||
1685 | sent++; | 1664 | sent++; |
1686 | TX_STAT_INC(txq->axq_qnum, a_queued_hw); | 1665 | TX_STAT_INC(txq->axq_qnum, a_queued_hw); |
1687 | 1666 | ||
1688 | if (an->sta && !ath_tid_has_buffered(tid)) | 1667 | if (an->sta && skb_queue_empty(&tid->retry_q)) |
1689 | ieee80211_sta_set_buffered(an->sta, i, false); | 1668 | ieee80211_sta_set_buffered(an->sta, i, false); |
1690 | } | 1669 | } |
1691 | ath_txq_unlock_complete(sc, tid->txq); | 1670 | ath_txq_unlock_complete(sc, tid->txq); |
@@ -1914,13 +1893,7 @@ bool ath_drain_all_txq(struct ath_softc *sc) | |||
1914 | if (!ATH_TXQ_SETUP(sc, i)) | 1893 | if (!ATH_TXQ_SETUP(sc, i)) |
1915 | continue; | 1894 | continue; |
1916 | 1895 | ||
1917 | /* | ||
1918 | * The caller will resume queues with ieee80211_wake_queues. | ||
1919 | * Mark the queue as not stopped to prevent ath_tx_complete | ||
1920 | * from waking the queue too early. | ||
1921 | */ | ||
1922 | txq = &sc->tx.txq[i]; | 1896 | txq = &sc->tx.txq[i]; |
1923 | txq->stopped = false; | ||
1924 | ath_draintxq(sc, txq); | 1897 | ath_draintxq(sc, txq); |
1925 | } | 1898 | } |
1926 | 1899 | ||
@@ -2319,16 +2292,14 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2319 | struct ath_softc *sc = hw->priv; | 2292 | struct ath_softc *sc = hw->priv; |
2320 | struct ath_txq *txq = txctl->txq; | 2293 | struct ath_txq *txq = txctl->txq; |
2321 | struct ath_atx_tid *tid = NULL; | 2294 | struct ath_atx_tid *tid = NULL; |
2295 | struct ath_node *an = NULL; | ||
2322 | struct ath_buf *bf; | 2296 | struct ath_buf *bf; |
2323 | bool queue, skip_uapsd = false, ps_resp; | 2297 | bool ps_resp; |
2324 | int q, ret; | 2298 | int q, ret; |
2325 | 2299 | ||
2326 | if (vif) | 2300 | if (vif) |
2327 | avp = (void *)vif->drv_priv; | 2301 | avp = (void *)vif->drv_priv; |
2328 | 2302 | ||
2329 | if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) | ||
2330 | txctl->force_channel = true; | ||
2331 | |||
2332 | ps_resp = !!(info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE); | 2303 | ps_resp = !!(info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE); |
2333 | 2304 | ||
2334 | ret = ath_tx_prepare(hw, skb, txctl); | 2305 | ret = ath_tx_prepare(hw, skb, txctl); |
@@ -2343,63 +2314,18 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2343 | 2314 | ||
2344 | q = skb_get_queue_mapping(skb); | 2315 | q = skb_get_queue_mapping(skb); |
2345 | 2316 | ||
2346 | ath_txq_lock(sc, txq); | 2317 | if (ps_resp) |
2347 | if (txq == sc->tx.txq_map[q]) { | ||
2348 | fi->txq = q; | ||
2349 | if (++txq->pending_frames > sc->tx.txq_max_pending[q] && | ||
2350 | !txq->stopped) { | ||
2351 | if (ath9k_is_chanctx_enabled()) | ||
2352 | ieee80211_stop_queue(sc->hw, info->hw_queue); | ||
2353 | else | ||
2354 | ieee80211_stop_queue(sc->hw, q); | ||
2355 | txq->stopped = true; | ||
2356 | } | ||
2357 | } | ||
2358 | |||
2359 | queue = ieee80211_is_data_present(hdr->frame_control); | ||
2360 | |||
2361 | /* If chanctx, queue all null frames while NOA could be there */ | ||
2362 | if (ath9k_is_chanctx_enabled() && | ||
2363 | ieee80211_is_nullfunc(hdr->frame_control) && | ||
2364 | !txctl->force_channel) | ||
2365 | queue = true; | ||
2366 | |||
2367 | /* Force queueing of all frames that belong to a virtual interface on | ||
2368 | * a different channel context, to ensure that they are sent on the | ||
2369 | * correct channel. | ||
2370 | */ | ||
2371 | if (((avp && avp->chanctx != sc->cur_chan) || | ||
2372 | sc->cur_chan->stopped) && !txctl->force_channel) { | ||
2373 | if (!txctl->an) | ||
2374 | txctl->an = &avp->mcast_node; | ||
2375 | queue = true; | ||
2376 | skip_uapsd = true; | ||
2377 | } | ||
2378 | |||
2379 | if (txctl->an && queue) | ||
2380 | tid = ath_get_skb_tid(sc, txctl->an, skb); | ||
2381 | |||
2382 | if (!skip_uapsd && ps_resp) { | ||
2383 | ath_txq_unlock(sc, txq); | ||
2384 | txq = sc->tx.uapsdq; | 2318 | txq = sc->tx.uapsdq; |
2385 | ath_txq_lock(sc, txq); | ||
2386 | } else if (txctl->an && queue) { | ||
2387 | WARN_ON(tid->txq != txctl->txq); | ||
2388 | 2319 | ||
2389 | if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) | 2320 | if (txctl->sta) { |
2390 | tid->clear_ps_filter = true; | 2321 | an = (struct ath_node *) sta->drv_priv; |
2391 | 2322 | tid = ath_get_skb_tid(sc, an, skb); | |
2392 | /* | 2323 | } |
2393 | * Add this frame to software queue for scheduling later | ||
2394 | * for aggregation. | ||
2395 | */ | ||
2396 | TX_STAT_INC(txq->axq_qnum, a_queued_sw); | ||
2397 | __skb_queue_tail(&tid->buf_q, skb); | ||
2398 | if (!txctl->an->sleeping) | ||
2399 | ath_tx_queue_tid(sc, txq, tid); | ||
2400 | 2324 | ||
2401 | ath_txq_schedule(sc, txq); | 2325 | ath_txq_lock(sc, txq); |
2402 | goto out; | 2326 | if (txq == sc->tx.txq_map[q]) { |
2327 | fi->txq = q; | ||
2328 | ++txq->pending_frames; | ||
2403 | } | 2329 | } |
2404 | 2330 | ||
2405 | bf = ath_tx_setup_buffer(sc, txq, tid, skb); | 2331 | bf = ath_tx_setup_buffer(sc, txq, tid, skb); |
@@ -2892,9 +2818,8 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) | |||
2892 | struct ath_atx_tid *tid; | 2818 | struct ath_atx_tid *tid; |
2893 | int tidno, acno; | 2819 | int tidno, acno; |
2894 | 2820 | ||
2895 | for (tidno = 0, tid = &an->tid[tidno]; | 2821 | for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { |
2896 | tidno < IEEE80211_NUM_TIDS; | 2822 | tid = ath_node_to_tid(an, tidno); |
2897 | tidno++, tid++) { | ||
2898 | tid->an = an; | 2823 | tid->an = an; |
2899 | tid->tidno = tidno; | 2824 | tid->tidno = tidno; |
2900 | tid->seq_start = tid->seq_next = 0; | 2825 | tid->seq_start = tid->seq_next = 0; |
@@ -2902,11 +2827,14 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) | |||
2902 | tid->baw_head = tid->baw_tail = 0; | 2827 | tid->baw_head = tid->baw_tail = 0; |
2903 | tid->active = false; | 2828 | tid->active = false; |
2904 | tid->clear_ps_filter = true; | 2829 | tid->clear_ps_filter = true; |
2905 | __skb_queue_head_init(&tid->buf_q); | 2830 | tid->has_queued = false; |
2906 | __skb_queue_head_init(&tid->retry_q); | 2831 | __skb_queue_head_init(&tid->retry_q); |
2907 | INIT_LIST_HEAD(&tid->list); | 2832 | INIT_LIST_HEAD(&tid->list); |
2908 | acno = TID_TO_WME_AC(tidno); | 2833 | acno = TID_TO_WME_AC(tidno); |
2909 | tid->txq = sc->tx.txq_map[acno]; | 2834 | tid->txq = sc->tx.txq_map[acno]; |
2835 | |||
2836 | if (!an->sta) | ||
2837 | break; /* just one multicast ath_atx_tid */ | ||
2910 | } | 2838 | } |
2911 | } | 2839 | } |
2912 | 2840 | ||
@@ -2916,9 +2844,8 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) | |||
2916 | struct ath_txq *txq; | 2844 | struct ath_txq *txq; |
2917 | int tidno; | 2845 | int tidno; |
2918 | 2846 | ||
2919 | for (tidno = 0, tid = &an->tid[tidno]; | 2847 | for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { |
2920 | tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { | 2848 | tid = ath_node_to_tid(an, tidno); |
2921 | |||
2922 | txq = tid->txq; | 2849 | txq = tid->txq; |
2923 | 2850 | ||
2924 | ath_txq_lock(sc, txq); | 2851 | ath_txq_lock(sc, txq); |
@@ -2930,6 +2857,9 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) | |||
2930 | tid->active = false; | 2857 | tid->active = false; |
2931 | 2858 | ||
2932 | ath_txq_unlock(sc, txq); | 2859 | ath_txq_unlock(sc, txq); |
2860 | |||
2861 | if (!an->sta) | ||
2862 | break; /* just one multicast ath_atx_tid */ | ||
2933 | } | 2863 | } |
2934 | } | 2864 | } |
2935 | 2865 | ||
diff --git a/drivers/net/wireless/ath/main.c b/drivers/net/wireless/ath/main.c index 338d72337604..89f4b0513946 100644 --- a/drivers/net/wireless/ath/main.c +++ b/drivers/net/wireless/ath/main.c | |||
@@ -90,3 +90,10 @@ void ath_printk(const char *level, const struct ath_common* common, | |||
90 | va_end(args); | 90 | va_end(args); |
91 | } | 91 | } |
92 | EXPORT_SYMBOL(ath_printk); | 92 | EXPORT_SYMBOL(ath_printk); |
93 | |||
94 | const char *ath_bus_type_strings[] = { | ||
95 | [ATH_PCI] = "pci", | ||
96 | [ATH_AHB] = "ahb", | ||
97 | [ATH_USB] = "usb", | ||
98 | }; | ||
99 | EXPORT_SYMBOL(ath_bus_type_strings); | ||
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index f8506037736f..43afa83a9f0c 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c | |||
@@ -449,7 +449,7 @@ static void ath_reg_apply_world_flags(struct wiphy *wiphy, | |||
449 | } | 449 | } |
450 | } | 450 | } |
451 | 451 | ||
452 | static u16 ath_regd_find_country_by_name(char *alpha2) | 452 | u16 ath_regd_find_country_by_name(char *alpha2) |
453 | { | 453 | { |
454 | unsigned int i; | 454 | unsigned int i; |
455 | 455 | ||
@@ -460,6 +460,7 @@ static u16 ath_regd_find_country_by_name(char *alpha2) | |||
460 | 460 | ||
461 | return -1; | 461 | return -1; |
462 | } | 462 | } |
463 | EXPORT_SYMBOL(ath_regd_find_country_by_name); | ||
463 | 464 | ||
464 | static int __ath_reg_dyn_country(struct wiphy *wiphy, | 465 | static int __ath_reg_dyn_country(struct wiphy *wiphy, |
465 | struct ath_regulatory *reg, | 466 | struct ath_regulatory *reg, |
diff --git a/drivers/net/wireless/ath/regd.h b/drivers/net/wireless/ath/regd.h index 565d3075f06e..5d80be213fac 100644 --- a/drivers/net/wireless/ath/regd.h +++ b/drivers/net/wireless/ath/regd.h | |||
@@ -251,6 +251,7 @@ enum CountryCode { | |||
251 | 251 | ||
252 | bool ath_is_world_regd(struct ath_regulatory *reg); | 252 | bool ath_is_world_regd(struct ath_regulatory *reg); |
253 | bool ath_is_49ghz_allowed(u16 redomain); | 253 | bool ath_is_49ghz_allowed(u16 redomain); |
254 | u16 ath_regd_find_country_by_name(char *alpha2); | ||
254 | int ath_regd_init(struct ath_regulatory *reg, struct wiphy *wiphy, | 255 | int ath_regd_init(struct ath_regulatory *reg, struct wiphy *wiphy, |
255 | void (*reg_notifier)(struct wiphy *wiphy, | 256 | void (*reg_notifier)(struct wiphy *wiphy, |
256 | struct regulatory_request *request)); | 257 | struct regulatory_request *request)); |