diff options
author | Kalle Valo <kvalo@qca.qualcomm.com> | 2012-06-14 07:20:18 -0400 |
---|---|---|
committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2012-06-14 07:44:49 -0400 |
commit | d987dd137bac8dca9b0015763d3106f48bb8a596 (patch) | |
tree | ef887505b3c904c548d58ec9bb6f4970a0877042 /drivers/net/wireless/ath | |
parent | c85251f8562095cd6fd63ae786354283c5318303 (diff) | |
parent | 211c17aaee644bb808fbdeef547ac99db92c01ed (diff) |
Merge remote branch 'wireless-next/master' into ath6kl-next
Conflicts:
drivers/net/wireless/ath/ath6kl/cfg80211.c
Diffstat (limited to 'drivers/net/wireless/ath')
68 files changed, 3294 insertions, 2825 deletions
diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index 8faa129da5a0..aec33cc207fd 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/nl80211.h> | 19 | #include <linux/nl80211.h> |
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/etherdevice.h> | 21 | #include <linux/etherdevice.h> |
22 | #include <linux/export.h> | ||
22 | #include <ar231x_platform.h> | 23 | #include <ar231x_platform.h> |
23 | #include "ath5k.h" | 24 | #include "ath5k.h" |
24 | #include "debug.h" | 25 | #include "debug.h" |
@@ -119,7 +120,7 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
119 | if (res == NULL) { | 120 | if (res == NULL) { |
120 | dev_err(&pdev->dev, "no IRQ resource found\n"); | 121 | dev_err(&pdev->dev, "no IRQ resource found\n"); |
121 | ret = -ENXIO; | 122 | ret = -ENXIO; |
122 | goto err_out; | 123 | goto err_iounmap; |
123 | } | 124 | } |
124 | 125 | ||
125 | irq = res->start; | 126 | irq = res->start; |
@@ -128,7 +129,7 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
128 | if (hw == NULL) { | 129 | if (hw == NULL) { |
129 | dev_err(&pdev->dev, "no memory for ieee80211_hw\n"); | 130 | dev_err(&pdev->dev, "no memory for ieee80211_hw\n"); |
130 | ret = -ENOMEM; | 131 | ret = -ENOMEM; |
131 | goto err_out; | 132 | goto err_iounmap; |
132 | } | 133 | } |
133 | 134 | ||
134 | ah = hw->priv; | 135 | ah = hw->priv; |
@@ -185,6 +186,8 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
185 | err_free_hw: | 186 | err_free_hw: |
186 | ieee80211_free_hw(hw); | 187 | ieee80211_free_hw(hw); |
187 | platform_set_drvdata(pdev, NULL); | 188 | platform_set_drvdata(pdev, NULL); |
189 | err_iounmap: | ||
190 | iounmap(mem); | ||
188 | err_out: | 191 | err_out: |
189 | return ret; | 192 | return ret; |
190 | } | 193 | } |
@@ -217,6 +220,7 @@ static int ath_ahb_remove(struct platform_device *pdev) | |||
217 | } | 220 | } |
218 | 221 | ||
219 | ath5k_deinit_ah(ah); | 222 | ath5k_deinit_ah(ah); |
223 | iounmap(ah->iobase); | ||
220 | platform_set_drvdata(pdev, NULL); | 224 | platform_set_drvdata(pdev, NULL); |
221 | ieee80211_free_hw(hw); | 225 | ieee80211_free_hw(hw); |
222 | 226 | ||
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 55ef93dd7438..64a453a6dfe4 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | |||
@@ -1527,7 +1527,7 @@ void ath5k_eeprom_detach(struct ath5k_hw *ah); | |||
1527 | 1527 | ||
1528 | /* Protocol Control Unit Functions */ | 1528 | /* Protocol Control Unit Functions */ |
1529 | /* Helpers */ | 1529 | /* Helpers */ |
1530 | int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, | 1530 | int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, enum ieee80211_band band, |
1531 | int len, struct ieee80211_rate *rate, bool shortpre); | 1531 | int len, struct ieee80211_rate *rate, bool shortpre); |
1532 | unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah); | 1532 | unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah); |
1533 | unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah); | 1533 | unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah); |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 3007bba12d94..fbaa30930076 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -462,7 +462,7 @@ void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | |||
462 | } | 462 | } |
463 | 463 | ||
464 | if (iter_data->need_set_hw_addr && iter_data->hw_macaddr) | 464 | if (iter_data->need_set_hw_addr && iter_data->hw_macaddr) |
465 | if (compare_ether_addr(iter_data->hw_macaddr, mac) == 0) | 465 | if (ether_addr_equal(iter_data->hw_macaddr, mac)) |
466 | iter_data->need_set_hw_addr = false; | 466 | iter_data->need_set_hw_addr = false; |
467 | 467 | ||
468 | if (!iter_data->any_assoc) { | 468 | if (!iter_data->any_assoc) { |
@@ -1170,7 +1170,7 @@ ath5k_check_ibss_tsf(struct ath5k_hw *ah, struct sk_buff *skb, | |||
1170 | 1170 | ||
1171 | if (ieee80211_is_beacon(mgmt->frame_control) && | 1171 | if (ieee80211_is_beacon(mgmt->frame_control) && |
1172 | le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS && | 1172 | le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS && |
1173 | memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) == 0) { | 1173 | ether_addr_equal(mgmt->bssid, common->curbssid)) { |
1174 | /* | 1174 | /* |
1175 | * Received an IBSS beacon with the same BSSID. Hardware *must* | 1175 | * Received an IBSS beacon with the same BSSID. Hardware *must* |
1176 | * have updated the local TSF. We have to work around various | 1176 | * have updated the local TSF. We have to work around various |
@@ -1234,7 +1234,7 @@ ath5k_update_beacon_rssi(struct ath5k_hw *ah, struct sk_buff *skb, int rssi) | |||
1234 | 1234 | ||
1235 | /* only beacons from our BSSID */ | 1235 | /* only beacons from our BSSID */ |
1236 | if (!ieee80211_is_beacon(mgmt->frame_control) || | 1236 | if (!ieee80211_is_beacon(mgmt->frame_control) || |
1237 | memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) != 0) | 1237 | !ether_addr_equal(mgmt->bssid, common->curbssid)) |
1238 | return; | 1238 | return; |
1239 | 1239 | ||
1240 | ewma_add(&ah->ah_beacon_rssi_avg, rssi); | 1240 | ewma_add(&ah->ah_beacon_rssi_avg, rssi); |
@@ -2415,6 +2415,22 @@ ath5k_tx_complete_poll_work(struct work_struct *work) | |||
2415 | * Initialization routines * | 2415 | * Initialization routines * |
2416 | \*************************/ | 2416 | \*************************/ |
2417 | 2417 | ||
2418 | static const struct ieee80211_iface_limit if_limits[] = { | ||
2419 | { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) }, | ||
2420 | { .max = 4, .types = | ||
2421 | #ifdef CONFIG_MAC80211_MESH | ||
2422 | BIT(NL80211_IFTYPE_MESH_POINT) | | ||
2423 | #endif | ||
2424 | BIT(NL80211_IFTYPE_AP) }, | ||
2425 | }; | ||
2426 | |||
2427 | static const struct ieee80211_iface_combination if_comb = { | ||
2428 | .limits = if_limits, | ||
2429 | .n_limits = ARRAY_SIZE(if_limits), | ||
2430 | .max_interfaces = 2048, | ||
2431 | .num_different_channels = 1, | ||
2432 | }; | ||
2433 | |||
2418 | int __devinit | 2434 | int __devinit |
2419 | ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops) | 2435 | ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops) |
2420 | { | 2436 | { |
@@ -2436,6 +2452,9 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops) | |||
2436 | BIT(NL80211_IFTYPE_ADHOC) | | 2452 | BIT(NL80211_IFTYPE_ADHOC) | |
2437 | BIT(NL80211_IFTYPE_MESH_POINT); | 2453 | BIT(NL80211_IFTYPE_MESH_POINT); |
2438 | 2454 | ||
2455 | hw->wiphy->iface_combinations = &if_comb; | ||
2456 | hw->wiphy->n_iface_combinations = 1; | ||
2457 | |||
2439 | /* SW support for IBSS_RSN is provided by mac80211 */ | 2458 | /* SW support for IBSS_RSN is provided by mac80211 */ |
2440 | hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; | 2459 | hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; |
2441 | 2460 | ||
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index 9be885707e20..9d00dab666a8 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c | |||
@@ -74,13 +74,6 @@ static unsigned int ath5k_debug; | |||
74 | module_param_named(debug, ath5k_debug, uint, 0); | 74 | module_param_named(debug, ath5k_debug, uint, 0); |
75 | 75 | ||
76 | 76 | ||
77 | static int ath5k_debugfs_open(struct inode *inode, struct file *file) | ||
78 | { | ||
79 | file->private_data = inode->i_private; | ||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | |||
84 | /* debugfs: registers */ | 77 | /* debugfs: registers */ |
85 | 78 | ||
86 | struct reg { | 79 | struct reg { |
@@ -268,7 +261,7 @@ static ssize_t write_file_beacon(struct file *file, | |||
268 | static const struct file_operations fops_beacon = { | 261 | static const struct file_operations fops_beacon = { |
269 | .read = read_file_beacon, | 262 | .read = read_file_beacon, |
270 | .write = write_file_beacon, | 263 | .write = write_file_beacon, |
271 | .open = ath5k_debugfs_open, | 264 | .open = simple_open, |
272 | .owner = THIS_MODULE, | 265 | .owner = THIS_MODULE, |
273 | .llseek = default_llseek, | 266 | .llseek = default_llseek, |
274 | }; | 267 | }; |
@@ -288,7 +281,7 @@ static ssize_t write_file_reset(struct file *file, | |||
288 | 281 | ||
289 | static const struct file_operations fops_reset = { | 282 | static const struct file_operations fops_reset = { |
290 | .write = write_file_reset, | 283 | .write = write_file_reset, |
291 | .open = ath5k_debugfs_open, | 284 | .open = simple_open, |
292 | .owner = THIS_MODULE, | 285 | .owner = THIS_MODULE, |
293 | .llseek = noop_llseek, | 286 | .llseek = noop_llseek, |
294 | }; | 287 | }; |
@@ -368,7 +361,7 @@ static ssize_t write_file_debug(struct file *file, | |||
368 | static const struct file_operations fops_debug = { | 361 | static const struct file_operations fops_debug = { |
369 | .read = read_file_debug, | 362 | .read = read_file_debug, |
370 | .write = write_file_debug, | 363 | .write = write_file_debug, |
371 | .open = ath5k_debugfs_open, | 364 | .open = simple_open, |
372 | .owner = THIS_MODULE, | 365 | .owner = THIS_MODULE, |
373 | .llseek = default_llseek, | 366 | .llseek = default_llseek, |
374 | }; | 367 | }; |
@@ -480,7 +473,7 @@ static ssize_t write_file_antenna(struct file *file, | |||
480 | static const struct file_operations fops_antenna = { | 473 | static const struct file_operations fops_antenna = { |
481 | .read = read_file_antenna, | 474 | .read = read_file_antenna, |
482 | .write = write_file_antenna, | 475 | .write = write_file_antenna, |
483 | .open = ath5k_debugfs_open, | 476 | .open = simple_open, |
484 | .owner = THIS_MODULE, | 477 | .owner = THIS_MODULE, |
485 | .llseek = default_llseek, | 478 | .llseek = default_llseek, |
486 | }; | 479 | }; |
@@ -535,7 +528,7 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf, | |||
535 | 528 | ||
536 | static const struct file_operations fops_misc = { | 529 | static const struct file_operations fops_misc = { |
537 | .read = read_file_misc, | 530 | .read = read_file_misc, |
538 | .open = ath5k_debugfs_open, | 531 | .open = simple_open, |
539 | .owner = THIS_MODULE, | 532 | .owner = THIS_MODULE, |
540 | }; | 533 | }; |
541 | 534 | ||
@@ -650,7 +643,7 @@ static ssize_t write_file_frameerrors(struct file *file, | |||
650 | static const struct file_operations fops_frameerrors = { | 643 | static const struct file_operations fops_frameerrors = { |
651 | .read = read_file_frameerrors, | 644 | .read = read_file_frameerrors, |
652 | .write = write_file_frameerrors, | 645 | .write = write_file_frameerrors, |
653 | .open = ath5k_debugfs_open, | 646 | .open = simple_open, |
654 | .owner = THIS_MODULE, | 647 | .owner = THIS_MODULE, |
655 | .llseek = default_llseek, | 648 | .llseek = default_llseek, |
656 | }; | 649 | }; |
@@ -813,7 +806,7 @@ static ssize_t write_file_ani(struct file *file, | |||
813 | static const struct file_operations fops_ani = { | 806 | static const struct file_operations fops_ani = { |
814 | .read = read_file_ani, | 807 | .read = read_file_ani, |
815 | .write = write_file_ani, | 808 | .write = write_file_ani, |
816 | .open = ath5k_debugfs_open, | 809 | .open = simple_open, |
817 | .owner = THIS_MODULE, | 810 | .owner = THIS_MODULE, |
818 | .llseek = default_llseek, | 811 | .llseek = default_llseek, |
819 | }; | 812 | }; |
@@ -884,7 +877,7 @@ static ssize_t write_file_queue(struct file *file, | |||
884 | static const struct file_operations fops_queue = { | 877 | static const struct file_operations fops_queue = { |
885 | .read = read_file_queue, | 878 | .read = read_file_queue, |
886 | .write = write_file_queue, | 879 | .write = write_file_queue, |
887 | .open = ath5k_debugfs_open, | 880 | .open = simple_open, |
888 | .owner = THIS_MODULE, | 881 | .owner = THIS_MODULE, |
889 | .llseek = default_llseek, | 882 | .llseek = default_llseek, |
890 | }; | 883 | }; |
diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c index 53424e8e6d82..dff48fbc63bf 100644 --- a/drivers/net/wireless/ath/ath5k/pci.c +++ b/drivers/net/wireless/ath/ath5k/pci.c | |||
@@ -47,6 +47,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = { | |||
47 | { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */ | 47 | { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */ |
48 | { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */ | 48 | { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */ |
49 | { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */ | 49 | { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */ |
50 | { PCI_VDEVICE(ATHEROS, 0xff1b) }, /* AR5BXB63 */ | ||
50 | { 0 } | 51 | { 0 } |
51 | }; | 52 | }; |
52 | MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table); | 53 | MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table); |
@@ -339,28 +340,4 @@ static struct pci_driver ath5k_pci_driver = { | |||
339 | .driver.pm = ATH5K_PM_OPS, | 340 | .driver.pm = ATH5K_PM_OPS, |
340 | }; | 341 | }; |
341 | 342 | ||
342 | /* | 343 | module_pci_driver(ath5k_pci_driver); |
343 | * Module init/exit functions | ||
344 | */ | ||
345 | static int __init | ||
346 | init_ath5k_pci(void) | ||
347 | { | ||
348 | int ret; | ||
349 | |||
350 | ret = pci_register_driver(&ath5k_pci_driver); | ||
351 | if (ret) { | ||
352 | pr_err("pci: can't register pci driver\n"); | ||
353 | return ret; | ||
354 | } | ||
355 | |||
356 | return 0; | ||
357 | } | ||
358 | |||
359 | static void __exit | ||
360 | exit_ath5k_pci(void) | ||
361 | { | ||
362 | pci_unregister_driver(&ath5k_pci_driver); | ||
363 | } | ||
364 | |||
365 | module_init(init_ath5k_pci); | ||
366 | module_exit(exit_ath5k_pci); | ||
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index cebfd6fd31d3..1f16b4227d8f 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c | |||
@@ -110,7 +110,7 @@ static const unsigned int ack_rates_high[] = | |||
110 | * bwmodes. | 110 | * bwmodes. |
111 | */ | 111 | */ |
112 | int | 112 | int |
113 | ath5k_hw_get_frame_duration(struct ath5k_hw *ah, | 113 | ath5k_hw_get_frame_duration(struct ath5k_hw *ah, enum ieee80211_band band, |
114 | int len, struct ieee80211_rate *rate, bool shortpre) | 114 | int len, struct ieee80211_rate *rate, bool shortpre) |
115 | { | 115 | { |
116 | int sifs, preamble, plcp_bits, sym_time; | 116 | int sifs, preamble, plcp_bits, sym_time; |
@@ -120,7 +120,7 @@ ath5k_hw_get_frame_duration(struct ath5k_hw *ah, | |||
120 | /* Fallback */ | 120 | /* Fallback */ |
121 | if (!ah->ah_bwmode) { | 121 | if (!ah->ah_bwmode) { |
122 | __le16 raw_dur = ieee80211_generic_frame_duration(ah->hw, | 122 | __le16 raw_dur = ieee80211_generic_frame_duration(ah->hw, |
123 | NULL, len, rate); | 123 | NULL, band, len, rate); |
124 | 124 | ||
125 | /* subtract difference between long and short preamble */ | 125 | /* subtract difference between long and short preamble */ |
126 | dur = le16_to_cpu(raw_dur); | 126 | dur = le16_to_cpu(raw_dur); |
@@ -302,14 +302,15 @@ ath5k_hw_write_rate_duration(struct ath5k_hw *ah) | |||
302 | * actual rate for this rate. See mac80211 tx.c | 302 | * actual rate for this rate. See mac80211 tx.c |
303 | * ieee80211_duration() for a brief description of | 303 | * ieee80211_duration() for a brief description of |
304 | * what rate we should choose to TX ACKs. */ | 304 | * what rate we should choose to TX ACKs. */ |
305 | tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false); | 305 | tx_time = ath5k_hw_get_frame_duration(ah, band, 10, |
306 | rate, false); | ||
306 | 307 | ||
307 | ath5k_hw_reg_write(ah, tx_time, reg); | 308 | ath5k_hw_reg_write(ah, tx_time, reg); |
308 | 309 | ||
309 | if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)) | 310 | if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)) |
310 | continue; | 311 | continue; |
311 | 312 | ||
312 | tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, true); | 313 | tx_time = ath5k_hw_get_frame_duration(ah, band, 10, rate, true); |
313 | ath5k_hw_reg_write(ah, tx_time, | 314 | ath5k_hw_reg_write(ah, tx_time, |
314 | reg + (AR5K_SET_SHORT_PREAMBLE << 2)); | 315 | reg + (AR5K_SET_SHORT_PREAMBLE << 2)); |
315 | } | 316 | } |
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index a6de200538c3..65fe929529a8 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c | |||
@@ -565,6 +565,7 @@ ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) | |||
565 | int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time) | 565 | int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time) |
566 | { | 566 | { |
567 | struct ieee80211_channel *channel = ah->ah_current_channel; | 567 | struct ieee80211_channel *channel = ah->ah_current_channel; |
568 | enum ieee80211_band band; | ||
568 | struct ieee80211_rate *rate; | 569 | struct ieee80211_rate *rate; |
569 | u32 ack_tx_time, eifs, eifs_clock, sifs, sifs_clock; | 570 | u32 ack_tx_time, eifs, eifs_clock, sifs, sifs_clock; |
570 | u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time); | 571 | u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time); |
@@ -600,11 +601,12 @@ int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time) | |||
600 | * Also we have different lowest rate for 802.11a | 601 | * Also we have different lowest rate for 802.11a |
601 | */ | 602 | */ |
602 | if (channel->band == IEEE80211_BAND_5GHZ) | 603 | if (channel->band == IEEE80211_BAND_5GHZ) |
603 | rate = &ah->sbands[IEEE80211_BAND_5GHZ].bitrates[0]; | 604 | band = IEEE80211_BAND_5GHZ; |
604 | else | 605 | else |
605 | rate = &ah->sbands[IEEE80211_BAND_2GHZ].bitrates[0]; | 606 | band = IEEE80211_BAND_2GHZ; |
606 | 607 | ||
607 | ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false); | 608 | rate = &ah->sbands[band].bitrates[0]; |
609 | ack_tx_time = ath5k_hw_get_frame_duration(ah, band, 10, rate, false); | ||
608 | 610 | ||
609 | /* ack_tx_time includes an SIFS already */ | 611 | /* ack_tx_time includes an SIFS already */ |
610 | eifs = ack_tx_time + sifs + 2 * slot_time; | 612 | eifs = ack_tx_time + sifs + 2 * slot_time; |
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index f00d377343d9..fd7dbd4609df 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c | |||
@@ -2650,35 +2650,6 @@ static int ath6kl_set_ies(struct ath6kl_vif *vif, | |||
2650 | return 0; | 2650 | return 0; |
2651 | } | 2651 | } |
2652 | 2652 | ||
2653 | static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev, | ||
2654 | struct ieee80211_channel *chan, | ||
2655 | enum nl80211_channel_type channel_type) | ||
2656 | { | ||
2657 | struct ath6kl_vif *vif; | ||
2658 | |||
2659 | /* | ||
2660 | * 'dev' could be NULL if a channel change is required for the hardware | ||
2661 | * device itself, instead of a particular VIF. | ||
2662 | * | ||
2663 | * FIXME: To be handled properly when monitor mode is supported. | ||
2664 | */ | ||
2665 | if (!dev) | ||
2666 | return -EBUSY; | ||
2667 | |||
2668 | vif = netdev_priv(dev); | ||
2669 | |||
2670 | if (!ath6kl_cfg80211_ready(vif)) | ||
2671 | return -EIO; | ||
2672 | |||
2673 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: center_freq=%u hw_value=%u\n", | ||
2674 | __func__, chan->center_freq, chan->hw_value); | ||
2675 | vif->next_chan = chan->center_freq; | ||
2676 | vif->next_ch_type = channel_type; | ||
2677 | vif->next_ch_band = chan->band; | ||
2678 | |||
2679 | return 0; | ||
2680 | } | ||
2681 | |||
2682 | void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif, bool enable) | 2653 | void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif, bool enable) |
2683 | { | 2654 | { |
2684 | int err; | 2655 | int err; |
@@ -2886,7 +2857,7 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
2886 | p.ssid_len = vif->ssid_len; | 2857 | p.ssid_len = vif->ssid_len; |
2887 | memcpy(p.ssid, vif->ssid, vif->ssid_len); | 2858 | memcpy(p.ssid, vif->ssid, vif->ssid_len); |
2888 | p.dot11_auth_mode = vif->dot11_auth_mode; | 2859 | p.dot11_auth_mode = vif->dot11_auth_mode; |
2889 | p.ch = cpu_to_le16(vif->next_chan); | 2860 | p.ch = cpu_to_le16(info->channel->center_freq); |
2890 | 2861 | ||
2891 | /* Enable uAPSD support by default */ | 2862 | /* Enable uAPSD support by default */ |
2892 | res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true); | 2863 | res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true); |
@@ -2910,8 +2881,8 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
2910 | return res; | 2881 | return res; |
2911 | } | 2882 | } |
2912 | 2883 | ||
2913 | if (ath6kl_set_htcap(vif, vif->next_ch_band, | 2884 | if (ath6kl_set_htcap(vif, info->channel->band, |
2914 | vif->next_ch_type != NL80211_CHAN_NO_HT)) | 2885 | info->channel_type != NL80211_CHAN_NO_HT)) |
2915 | return -EIO; | 2886 | return -EIO; |
2916 | 2887 | ||
2917 | /* | 2888 | /* |
@@ -3392,7 +3363,6 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = { | |||
3392 | .suspend = __ath6kl_cfg80211_suspend, | 3363 | .suspend = __ath6kl_cfg80211_suspend, |
3393 | .resume = __ath6kl_cfg80211_resume, | 3364 | .resume = __ath6kl_cfg80211_resume, |
3394 | #endif | 3365 | #endif |
3395 | .set_channel = ath6kl_set_channel, | ||
3396 | .start_ap = ath6kl_start_ap, | 3366 | .start_ap = ath6kl_start_ap, |
3397 | .change_beacon = ath6kl_change_beacon, | 3367 | .change_beacon = ath6kl_change_beacon, |
3398 | .stop_ap = ath6kl_stop_ap, | 3368 | .stop_ap = ath6kl_stop_ap, |
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index b3eee10cf016..d38a31de344c 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h | |||
@@ -577,9 +577,6 @@ struct ath6kl_vif { | |||
577 | u32 last_cancel_roc_id; | 577 | u32 last_cancel_roc_id; |
578 | u32 send_action_id; | 578 | u32 send_action_id; |
579 | bool probe_req_report; | 579 | bool probe_req_report; |
580 | u16 next_chan; | ||
581 | enum nl80211_channel_type next_ch_type; | ||
582 | enum ieee80211_band next_ch_band; | ||
583 | u16 assoc_bss_beacon_int; | 580 | u16 assoc_bss_beacon_int; |
584 | u16 listen_intvl_t; | 581 | u16 listen_intvl_t; |
585 | u16 bmiss_time_t; | 582 | u16 bmiss_time_t; |
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index ced6c6fe5470..15cfe30e54fd 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c | |||
@@ -217,12 +217,6 @@ void dump_cred_dist_stats(struct htc_target *target) | |||
217 | target->credit_info->cur_free_credits); | 217 | target->credit_info->cur_free_credits); |
218 | } | 218 | } |
219 | 219 | ||
220 | static int ath6kl_debugfs_open(struct inode *inode, struct file *file) | ||
221 | { | ||
222 | file->private_data = inode->i_private; | ||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | void ath6kl_debug_war(struct ath6kl *ar, enum ath6kl_war war) | 220 | void ath6kl_debug_war(struct ath6kl *ar, enum ath6kl_war war) |
227 | { | 221 | { |
228 | switch (war) { | 222 | switch (war) { |
@@ -263,7 +257,7 @@ static ssize_t read_file_war_stats(struct file *file, char __user *user_buf, | |||
263 | 257 | ||
264 | static const struct file_operations fops_war_stats = { | 258 | static const struct file_operations fops_war_stats = { |
265 | .read = read_file_war_stats, | 259 | .read = read_file_war_stats, |
266 | .open = ath6kl_debugfs_open, | 260 | .open = simple_open, |
267 | .owner = THIS_MODULE, | 261 | .owner = THIS_MODULE, |
268 | .llseek = default_llseek, | 262 | .llseek = default_llseek, |
269 | }; | 263 | }; |
@@ -490,7 +484,7 @@ static ssize_t ath6kl_fwlog_mask_write(struct file *file, | |||
490 | } | 484 | } |
491 | 485 | ||
492 | static const struct file_operations fops_fwlog_mask = { | 486 | static const struct file_operations fops_fwlog_mask = { |
493 | .open = ath6kl_debugfs_open, | 487 | .open = simple_open, |
494 | .read = ath6kl_fwlog_mask_read, | 488 | .read = ath6kl_fwlog_mask_read, |
495 | .write = ath6kl_fwlog_mask_write, | 489 | .write = ath6kl_fwlog_mask_write, |
496 | .owner = THIS_MODULE, | 490 | .owner = THIS_MODULE, |
@@ -642,7 +636,7 @@ static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf, | |||
642 | 636 | ||
643 | static const struct file_operations fops_tgt_stats = { | 637 | static const struct file_operations fops_tgt_stats = { |
644 | .read = read_file_tgt_stats, | 638 | .read = read_file_tgt_stats, |
645 | .open = ath6kl_debugfs_open, | 639 | .open = simple_open, |
646 | .owner = THIS_MODULE, | 640 | .owner = THIS_MODULE, |
647 | .llseek = default_llseek, | 641 | .llseek = default_llseek, |
648 | }; | 642 | }; |
@@ -707,7 +701,7 @@ static ssize_t read_file_credit_dist_stats(struct file *file, | |||
707 | 701 | ||
708 | static const struct file_operations fops_credit_dist_stats = { | 702 | static const struct file_operations fops_credit_dist_stats = { |
709 | .read = read_file_credit_dist_stats, | 703 | .read = read_file_credit_dist_stats, |
710 | .open = ath6kl_debugfs_open, | 704 | .open = simple_open, |
711 | .owner = THIS_MODULE, | 705 | .owner = THIS_MODULE, |
712 | .llseek = default_llseek, | 706 | .llseek = default_llseek, |
713 | }; | 707 | }; |
@@ -810,7 +804,7 @@ static ssize_t ath6kl_endpoint_stats_write(struct file *file, | |||
810 | } | 804 | } |
811 | 805 | ||
812 | static const struct file_operations fops_endpoint_stats = { | 806 | static const struct file_operations fops_endpoint_stats = { |
813 | .open = ath6kl_debugfs_open, | 807 | .open = simple_open, |
814 | .read = ath6kl_endpoint_stats_read, | 808 | .read = ath6kl_endpoint_stats_read, |
815 | .write = ath6kl_endpoint_stats_write, | 809 | .write = ath6kl_endpoint_stats_write, |
816 | .owner = THIS_MODULE, | 810 | .owner = THIS_MODULE, |
@@ -883,7 +877,7 @@ static ssize_t ath6kl_regread_write(struct file *file, | |||
883 | static const struct file_operations fops_diag_reg_read = { | 877 | static const struct file_operations fops_diag_reg_read = { |
884 | .read = ath6kl_regread_read, | 878 | .read = ath6kl_regread_read, |
885 | .write = ath6kl_regread_write, | 879 | .write = ath6kl_regread_write, |
886 | .open = ath6kl_debugfs_open, | 880 | .open = simple_open, |
887 | .owner = THIS_MODULE, | 881 | .owner = THIS_MODULE, |
888 | .llseek = default_llseek, | 882 | .llseek = default_llseek, |
889 | }; | 883 | }; |
@@ -1007,7 +1001,7 @@ static ssize_t ath6kl_lrssi_roam_read(struct file *file, | |||
1007 | static const struct file_operations fops_lrssi_roam_threshold = { | 1001 | static const struct file_operations fops_lrssi_roam_threshold = { |
1008 | .read = ath6kl_lrssi_roam_read, | 1002 | .read = ath6kl_lrssi_roam_read, |
1009 | .write = ath6kl_lrssi_roam_write, | 1003 | .write = ath6kl_lrssi_roam_write, |
1010 | .open = ath6kl_debugfs_open, | 1004 | .open = simple_open, |
1011 | .owner = THIS_MODULE, | 1005 | .owner = THIS_MODULE, |
1012 | .llseek = default_llseek, | 1006 | .llseek = default_llseek, |
1013 | }; | 1007 | }; |
@@ -1069,7 +1063,7 @@ static ssize_t ath6kl_regwrite_write(struct file *file, | |||
1069 | static const struct file_operations fops_diag_reg_write = { | 1063 | static const struct file_operations fops_diag_reg_write = { |
1070 | .read = ath6kl_regwrite_read, | 1064 | .read = ath6kl_regwrite_read, |
1071 | .write = ath6kl_regwrite_write, | 1065 | .write = ath6kl_regwrite_write, |
1072 | .open = ath6kl_debugfs_open, | 1066 | .open = simple_open, |
1073 | .owner = THIS_MODULE, | 1067 | .owner = THIS_MODULE, |
1074 | .llseek = default_llseek, | 1068 | .llseek = default_llseek, |
1075 | }; | 1069 | }; |
@@ -1174,7 +1168,7 @@ static ssize_t ath6kl_roam_table_read(struct file *file, char __user *user_buf, | |||
1174 | 1168 | ||
1175 | static const struct file_operations fops_roam_table = { | 1169 | static const struct file_operations fops_roam_table = { |
1176 | .read = ath6kl_roam_table_read, | 1170 | .read = ath6kl_roam_table_read, |
1177 | .open = ath6kl_debugfs_open, | 1171 | .open = simple_open, |
1178 | .owner = THIS_MODULE, | 1172 | .owner = THIS_MODULE, |
1179 | .llseek = default_llseek, | 1173 | .llseek = default_llseek, |
1180 | }; | 1174 | }; |
@@ -1212,7 +1206,7 @@ static ssize_t ath6kl_force_roam_write(struct file *file, | |||
1212 | 1206 | ||
1213 | static const struct file_operations fops_force_roam = { | 1207 | static const struct file_operations fops_force_roam = { |
1214 | .write = ath6kl_force_roam_write, | 1208 | .write = ath6kl_force_roam_write, |
1215 | .open = ath6kl_debugfs_open, | 1209 | .open = simple_open, |
1216 | .owner = THIS_MODULE, | 1210 | .owner = THIS_MODULE, |
1217 | .llseek = default_llseek, | 1211 | .llseek = default_llseek, |
1218 | }; | 1212 | }; |
@@ -1252,7 +1246,7 @@ static ssize_t ath6kl_roam_mode_write(struct file *file, | |||
1252 | 1246 | ||
1253 | static const struct file_operations fops_roam_mode = { | 1247 | static const struct file_operations fops_roam_mode = { |
1254 | .write = ath6kl_roam_mode_write, | 1248 | .write = ath6kl_roam_mode_write, |
1255 | .open = ath6kl_debugfs_open, | 1249 | .open = simple_open, |
1256 | .owner = THIS_MODULE, | 1250 | .owner = THIS_MODULE, |
1257 | .llseek = default_llseek, | 1251 | .llseek = default_llseek, |
1258 | }; | 1252 | }; |
@@ -1294,7 +1288,7 @@ static ssize_t ath6kl_keepalive_write(struct file *file, | |||
1294 | } | 1288 | } |
1295 | 1289 | ||
1296 | static const struct file_operations fops_keepalive = { | 1290 | static const struct file_operations fops_keepalive = { |
1297 | .open = ath6kl_debugfs_open, | 1291 | .open = simple_open, |
1298 | .read = ath6kl_keepalive_read, | 1292 | .read = ath6kl_keepalive_read, |
1299 | .write = ath6kl_keepalive_write, | 1293 | .write = ath6kl_keepalive_write, |
1300 | .owner = THIS_MODULE, | 1294 | .owner = THIS_MODULE, |
@@ -1339,7 +1333,7 @@ static ssize_t ath6kl_disconnect_timeout_write(struct file *file, | |||
1339 | } | 1333 | } |
1340 | 1334 | ||
1341 | static const struct file_operations fops_disconnect_timeout = { | 1335 | static const struct file_operations fops_disconnect_timeout = { |
1342 | .open = ath6kl_debugfs_open, | 1336 | .open = simple_open, |
1343 | .read = ath6kl_disconnect_timeout_read, | 1337 | .read = ath6kl_disconnect_timeout_read, |
1344 | .write = ath6kl_disconnect_timeout_write, | 1338 | .write = ath6kl_disconnect_timeout_write, |
1345 | .owner = THIS_MODULE, | 1339 | .owner = THIS_MODULE, |
@@ -1520,7 +1514,7 @@ static ssize_t ath6kl_create_qos_write(struct file *file, | |||
1520 | 1514 | ||
1521 | static const struct file_operations fops_create_qos = { | 1515 | static const struct file_operations fops_create_qos = { |
1522 | .write = ath6kl_create_qos_write, | 1516 | .write = ath6kl_create_qos_write, |
1523 | .open = ath6kl_debugfs_open, | 1517 | .open = simple_open, |
1524 | .owner = THIS_MODULE, | 1518 | .owner = THIS_MODULE, |
1525 | .llseek = default_llseek, | 1519 | .llseek = default_llseek, |
1526 | }; | 1520 | }; |
@@ -1568,7 +1562,7 @@ static ssize_t ath6kl_delete_qos_write(struct file *file, | |||
1568 | 1562 | ||
1569 | static const struct file_operations fops_delete_qos = { | 1563 | static const struct file_operations fops_delete_qos = { |
1570 | .write = ath6kl_delete_qos_write, | 1564 | .write = ath6kl_delete_qos_write, |
1571 | .open = ath6kl_debugfs_open, | 1565 | .open = simple_open, |
1572 | .owner = THIS_MODULE, | 1566 | .owner = THIS_MODULE, |
1573 | .llseek = default_llseek, | 1567 | .llseek = default_llseek, |
1574 | }; | 1568 | }; |
@@ -1608,7 +1602,7 @@ static ssize_t ath6kl_bgscan_int_write(struct file *file, | |||
1608 | 1602 | ||
1609 | static const struct file_operations fops_bgscan_int = { | 1603 | static const struct file_operations fops_bgscan_int = { |
1610 | .write = ath6kl_bgscan_int_write, | 1604 | .write = ath6kl_bgscan_int_write, |
1611 | .open = ath6kl_debugfs_open, | 1605 | .open = simple_open, |
1612 | .owner = THIS_MODULE, | 1606 | .owner = THIS_MODULE, |
1613 | .llseek = default_llseek, | 1607 | .llseek = default_llseek, |
1614 | }; | 1608 | }; |
@@ -1666,7 +1660,7 @@ static ssize_t ath6kl_listen_int_read(struct file *file, | |||
1666 | static const struct file_operations fops_listen_int = { | 1660 | static const struct file_operations fops_listen_int = { |
1667 | .read = ath6kl_listen_int_read, | 1661 | .read = ath6kl_listen_int_read, |
1668 | .write = ath6kl_listen_int_write, | 1662 | .write = ath6kl_listen_int_write, |
1669 | .open = ath6kl_debugfs_open, | 1663 | .open = simple_open, |
1670 | .owner = THIS_MODULE, | 1664 | .owner = THIS_MODULE, |
1671 | .llseek = default_llseek, | 1665 | .llseek = default_llseek, |
1672 | }; | 1666 | }; |
@@ -1726,7 +1720,7 @@ static ssize_t ath6kl_power_params_write(struct file *file, | |||
1726 | 1720 | ||
1727 | static const struct file_operations fops_power_params = { | 1721 | static const struct file_operations fops_power_params = { |
1728 | .write = ath6kl_power_params_write, | 1722 | .write = ath6kl_power_params_write, |
1729 | .open = ath6kl_debugfs_open, | 1723 | .open = simple_open, |
1730 | .owner = THIS_MODULE, | 1724 | .owner = THIS_MODULE, |
1731 | .llseek = default_llseek, | 1725 | .llseek = default_llseek, |
1732 | }; | 1726 | }; |
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index 45621baca24a..c189e28e86a9 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c | |||
@@ -602,7 +602,6 @@ static int ath6kl_commit_ch_switch(struct ath6kl_vif *vif, u16 channel) | |||
602 | 602 | ||
603 | struct ath6kl *ar = vif->ar; | 603 | struct ath6kl *ar = vif->ar; |
604 | 604 | ||
605 | vif->next_chan = channel; | ||
606 | vif->profile.ch = cpu_to_le16(channel); | 605 | vif->profile.ch = cpu_to_le16(channel); |
607 | 606 | ||
608 | switch (vif->nw_type) { | 607 | switch (vif->nw_type) { |
diff --git a/drivers/net/wireless/ath/ath6kl/testmode.c b/drivers/net/wireless/ath/ath6kl/testmode.c index 6675c92b542b..acc9aa832f76 100644 --- a/drivers/net/wireless/ath/ath6kl/testmode.c +++ b/drivers/net/wireless/ath/ath6kl/testmode.c | |||
@@ -55,8 +55,9 @@ void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, size_t buf_len) | |||
55 | ath6kl_warn("failed to allocate testmode rx skb!\n"); | 55 | ath6kl_warn("failed to allocate testmode rx skb!\n"); |
56 | return; | 56 | return; |
57 | } | 57 | } |
58 | NLA_PUT_U32(skb, ATH6KL_TM_ATTR_CMD, ATH6KL_TM_CMD_TCMD); | 58 | if (nla_put_u32(skb, ATH6KL_TM_ATTR_CMD, ATH6KL_TM_CMD_TCMD) || |
59 | NLA_PUT(skb, ATH6KL_TM_ATTR_DATA, buf_len, buf); | 59 | nla_put(skb, ATH6KL_TM_ATTR_DATA, buf_len, buf)) |
60 | goto nla_put_failure; | ||
60 | cfg80211_testmode_event(skb, GFP_KERNEL); | 61 | cfg80211_testmode_event(skb, GFP_KERNEL); |
61 | return; | 62 | return; |
62 | 63 | ||
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c index dfbbe9e7ff75..3740c3d6ab88 100644 --- a/drivers/net/wireless/ath/ath6kl/usb.c +++ b/drivers/net/wireless/ath/ath6kl/usb.c | |||
@@ -1191,6 +1191,7 @@ static struct usb_driver ath6kl_usb_driver = { | |||
1191 | .disconnect = ath6kl_usb_remove, | 1191 | .disconnect = ath6kl_usb_remove, |
1192 | .id_table = ath6kl_usb_ids, | 1192 | .id_table = ath6kl_usb_ids, |
1193 | .supports_autosuspend = true, | 1193 | .supports_autosuspend = true, |
1194 | .disable_hub_initiated_lpm = 1, | ||
1194 | }; | 1195 | }; |
1195 | 1196 | ||
1196 | static int ath6kl_usb_init(void) | 1197 | static int ath6kl_usb_init(void) |
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 3f0b84723789..9c41232b0cd0 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile | |||
@@ -3,7 +3,9 @@ ath9k-y += beacon.o \ | |||
3 | init.o \ | 3 | init.o \ |
4 | main.o \ | 4 | main.o \ |
5 | recv.o \ | 5 | recv.o \ |
6 | xmit.o | 6 | xmit.o \ |
7 | link.o \ | ||
8 | antenna.o | ||
7 | 9 | ||
8 | ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o | 10 | ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o |
9 | ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o | 11 | ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o |
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 5e47ca6d16a8..4a4e8a2b9d2c 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c | |||
@@ -126,7 +126,7 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
126 | sc->irq = irq; | 126 | sc->irq = irq; |
127 | 127 | ||
128 | /* Will be cleared in ath9k_start() */ | 128 | /* Will be cleared in ath9k_start() */ |
129 | sc->sc_flags |= SC_OP_INVALID; | 129 | set_bit(SC_OP_INVALID, &sc->sc_flags); |
130 | 130 | ||
131 | ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc); | 131 | ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc); |
132 | if (ret) { | 132 | if (ret) { |
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 47a9fb4a116a..b4c77f9d7470 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c | |||
@@ -274,7 +274,9 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel) | |||
274 | aniState->rssiThrLow, aniState->rssiThrHigh); | 274 | aniState->rssiThrLow, aniState->rssiThrHigh); |
275 | 275 | ||
276 | if (aniState->update_ani) | 276 | if (aniState->update_ani) |
277 | aniState->ofdmNoiseImmunityLevel = immunityLevel; | 277 | aniState->ofdmNoiseImmunityLevel = |
278 | (immunityLevel > ATH9K_ANI_OFDM_DEF_LEVEL) ? | ||
279 | immunityLevel : ATH9K_ANI_OFDM_DEF_LEVEL; | ||
278 | 280 | ||
279 | entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel]; | 281 | entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel]; |
280 | entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel]; | 282 | entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel]; |
@@ -340,7 +342,9 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel) | |||
340 | immunityLevel = ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI; | 342 | immunityLevel = ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI; |
341 | 343 | ||
342 | if (aniState->update_ani) | 344 | if (aniState->update_ani) |
343 | aniState->cckNoiseImmunityLevel = immunityLevel; | 345 | aniState->cckNoiseImmunityLevel = |
346 | (immunityLevel > ATH9K_ANI_CCK_DEF_LEVEL) ? | ||
347 | immunityLevel : ATH9K_ANI_CCK_DEF_LEVEL; | ||
344 | 348 | ||
345 | entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel]; | 349 | entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel]; |
346 | entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel]; | 350 | entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel]; |
diff --git a/drivers/net/wireless/ath/ath9k/antenna.c b/drivers/net/wireless/ath/ath9k/antenna.c new file mode 100644 index 000000000000..bbcfeb3b2a60 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/antenna.c | |||
@@ -0,0 +1,776 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "ath9k.h" | ||
18 | |||
19 | static inline bool ath_is_alt_ant_ratio_better(int alt_ratio, int maxdelta, | ||
20 | int mindelta, int main_rssi_avg, | ||
21 | int alt_rssi_avg, int pkt_count) | ||
22 | { | ||
23 | return (((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && | ||
24 | (alt_rssi_avg > main_rssi_avg + maxdelta)) || | ||
25 | (alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50); | ||
26 | } | ||
27 | |||
28 | static inline bool ath_ant_div_comb_alt_check(u8 div_group, int alt_ratio, | ||
29 | int curr_main_set, int curr_alt_set, | ||
30 | int alt_rssi_avg, int main_rssi_avg) | ||
31 | { | ||
32 | bool result = false; | ||
33 | switch (div_group) { | ||
34 | case 0: | ||
35 | if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) | ||
36 | result = true; | ||
37 | break; | ||
38 | case 1: | ||
39 | case 2: | ||
40 | if ((((curr_main_set == ATH_ANT_DIV_COMB_LNA2) && | ||
41 | (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) && | ||
42 | (alt_rssi_avg >= (main_rssi_avg - 5))) || | ||
43 | ((curr_main_set == ATH_ANT_DIV_COMB_LNA1) && | ||
44 | (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) && | ||
45 | (alt_rssi_avg >= (main_rssi_avg - 2)))) && | ||
46 | (alt_rssi_avg >= 4)) | ||
47 | result = true; | ||
48 | else | ||
49 | result = false; | ||
50 | break; | ||
51 | } | ||
52 | |||
53 | return result; | ||
54 | } | ||
55 | |||
56 | static void ath_lnaconf_alt_good_scan(struct ath_ant_comb *antcomb, | ||
57 | struct ath_hw_antcomb_conf ant_conf, | ||
58 | int main_rssi_avg) | ||
59 | { | ||
60 | antcomb->quick_scan_cnt = 0; | ||
61 | |||
62 | if (ant_conf.main_lna_conf == ATH_ANT_DIV_COMB_LNA2) | ||
63 | antcomb->rssi_lna2 = main_rssi_avg; | ||
64 | else if (ant_conf.main_lna_conf == ATH_ANT_DIV_COMB_LNA1) | ||
65 | antcomb->rssi_lna1 = main_rssi_avg; | ||
66 | |||
67 | switch ((ant_conf.main_lna_conf << 4) | ant_conf.alt_lna_conf) { | ||
68 | case 0x10: /* LNA2 A-B */ | ||
69 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
70 | antcomb->first_quick_scan_conf = | ||
71 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
72 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1; | ||
73 | break; | ||
74 | case 0x20: /* LNA1 A-B */ | ||
75 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
76 | antcomb->first_quick_scan_conf = | ||
77 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
78 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2; | ||
79 | break; | ||
80 | case 0x21: /* LNA1 LNA2 */ | ||
81 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA2; | ||
82 | antcomb->first_quick_scan_conf = | ||
83 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
84 | antcomb->second_quick_scan_conf = | ||
85 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
86 | break; | ||
87 | case 0x12: /* LNA2 LNA1 */ | ||
88 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1; | ||
89 | antcomb->first_quick_scan_conf = | ||
90 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
91 | antcomb->second_quick_scan_conf = | ||
92 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
93 | break; | ||
94 | case 0x13: /* LNA2 A+B */ | ||
95 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
96 | antcomb->first_quick_scan_conf = | ||
97 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
98 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1; | ||
99 | break; | ||
100 | case 0x23: /* LNA1 A+B */ | ||
101 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
102 | antcomb->first_quick_scan_conf = | ||
103 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
104 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2; | ||
105 | break; | ||
106 | default: | ||
107 | break; | ||
108 | } | ||
109 | } | ||
110 | |||
111 | static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb, | ||
112 | struct ath_hw_antcomb_conf *div_ant_conf, | ||
113 | int main_rssi_avg, int alt_rssi_avg, | ||
114 | int alt_ratio) | ||
115 | { | ||
116 | /* alt_good */ | ||
117 | switch (antcomb->quick_scan_cnt) { | ||
118 | case 0: | ||
119 | /* set alt to main, and alt to first conf */ | ||
120 | div_ant_conf->main_lna_conf = antcomb->main_conf; | ||
121 | div_ant_conf->alt_lna_conf = antcomb->first_quick_scan_conf; | ||
122 | break; | ||
123 | case 1: | ||
124 | /* set alt to main, and alt to first conf */ | ||
125 | div_ant_conf->main_lna_conf = antcomb->main_conf; | ||
126 | div_ant_conf->alt_lna_conf = antcomb->second_quick_scan_conf; | ||
127 | antcomb->rssi_first = main_rssi_avg; | ||
128 | antcomb->rssi_second = alt_rssi_avg; | ||
129 | |||
130 | if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) { | ||
131 | /* main is LNA1 */ | ||
132 | if (ath_is_alt_ant_ratio_better(alt_ratio, | ||
133 | ATH_ANT_DIV_COMB_LNA1_DELTA_HI, | ||
134 | ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, | ||
135 | main_rssi_avg, alt_rssi_avg, | ||
136 | antcomb->total_pkt_count)) | ||
137 | antcomb->first_ratio = true; | ||
138 | else | ||
139 | antcomb->first_ratio = false; | ||
140 | } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) { | ||
141 | if (ath_is_alt_ant_ratio_better(alt_ratio, | ||
142 | ATH_ANT_DIV_COMB_LNA1_DELTA_MID, | ||
143 | ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, | ||
144 | main_rssi_avg, alt_rssi_avg, | ||
145 | antcomb->total_pkt_count)) | ||
146 | antcomb->first_ratio = true; | ||
147 | else | ||
148 | antcomb->first_ratio = false; | ||
149 | } else { | ||
150 | if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && | ||
151 | (alt_rssi_avg > main_rssi_avg + | ||
152 | ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) || | ||
153 | (alt_rssi_avg > main_rssi_avg)) && | ||
154 | (antcomb->total_pkt_count > 50)) | ||
155 | antcomb->first_ratio = true; | ||
156 | else | ||
157 | antcomb->first_ratio = false; | ||
158 | } | ||
159 | break; | ||
160 | case 2: | ||
161 | antcomb->alt_good = false; | ||
162 | antcomb->scan_not_start = false; | ||
163 | antcomb->scan = false; | ||
164 | antcomb->rssi_first = main_rssi_avg; | ||
165 | antcomb->rssi_third = alt_rssi_avg; | ||
166 | |||
167 | if (antcomb->second_quick_scan_conf == ATH_ANT_DIV_COMB_LNA1) | ||
168 | antcomb->rssi_lna1 = alt_rssi_avg; | ||
169 | else if (antcomb->second_quick_scan_conf == | ||
170 | ATH_ANT_DIV_COMB_LNA2) | ||
171 | antcomb->rssi_lna2 = alt_rssi_avg; | ||
172 | else if (antcomb->second_quick_scan_conf == | ||
173 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2) { | ||
174 | if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) | ||
175 | antcomb->rssi_lna2 = main_rssi_avg; | ||
176 | else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) | ||
177 | antcomb->rssi_lna1 = main_rssi_avg; | ||
178 | } | ||
179 | |||
180 | if (antcomb->rssi_lna2 > antcomb->rssi_lna1 + | ||
181 | ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA) | ||
182 | div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA2; | ||
183 | else | ||
184 | div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1; | ||
185 | |||
186 | if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) { | ||
187 | if (ath_is_alt_ant_ratio_better(alt_ratio, | ||
188 | ATH_ANT_DIV_COMB_LNA1_DELTA_HI, | ||
189 | ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, | ||
190 | main_rssi_avg, alt_rssi_avg, | ||
191 | antcomb->total_pkt_count)) | ||
192 | antcomb->second_ratio = true; | ||
193 | else | ||
194 | antcomb->second_ratio = false; | ||
195 | } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) { | ||
196 | if (ath_is_alt_ant_ratio_better(alt_ratio, | ||
197 | ATH_ANT_DIV_COMB_LNA1_DELTA_MID, | ||
198 | ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, | ||
199 | main_rssi_avg, alt_rssi_avg, | ||
200 | antcomb->total_pkt_count)) | ||
201 | antcomb->second_ratio = true; | ||
202 | else | ||
203 | antcomb->second_ratio = false; | ||
204 | } else { | ||
205 | if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && | ||
206 | (alt_rssi_avg > main_rssi_avg + | ||
207 | ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) || | ||
208 | (alt_rssi_avg > main_rssi_avg)) && | ||
209 | (antcomb->total_pkt_count > 50)) | ||
210 | antcomb->second_ratio = true; | ||
211 | else | ||
212 | antcomb->second_ratio = false; | ||
213 | } | ||
214 | |||
215 | /* set alt to the conf with maximun ratio */ | ||
216 | if (antcomb->first_ratio && antcomb->second_ratio) { | ||
217 | if (antcomb->rssi_second > antcomb->rssi_third) { | ||
218 | /* first alt*/ | ||
219 | if ((antcomb->first_quick_scan_conf == | ||
220 | ATH_ANT_DIV_COMB_LNA1) || | ||
221 | (antcomb->first_quick_scan_conf == | ||
222 | ATH_ANT_DIV_COMB_LNA2)) | ||
223 | /* Set alt LNA1 or LNA2*/ | ||
224 | if (div_ant_conf->main_lna_conf == | ||
225 | ATH_ANT_DIV_COMB_LNA2) | ||
226 | div_ant_conf->alt_lna_conf = | ||
227 | ATH_ANT_DIV_COMB_LNA1; | ||
228 | else | ||
229 | div_ant_conf->alt_lna_conf = | ||
230 | ATH_ANT_DIV_COMB_LNA2; | ||
231 | else | ||
232 | /* Set alt to A+B or A-B */ | ||
233 | div_ant_conf->alt_lna_conf = | ||
234 | antcomb->first_quick_scan_conf; | ||
235 | } else if ((antcomb->second_quick_scan_conf == | ||
236 | ATH_ANT_DIV_COMB_LNA1) || | ||
237 | (antcomb->second_quick_scan_conf == | ||
238 | ATH_ANT_DIV_COMB_LNA2)) { | ||
239 | /* Set alt LNA1 or LNA2 */ | ||
240 | if (div_ant_conf->main_lna_conf == | ||
241 | ATH_ANT_DIV_COMB_LNA2) | ||
242 | div_ant_conf->alt_lna_conf = | ||
243 | ATH_ANT_DIV_COMB_LNA1; | ||
244 | else | ||
245 | div_ant_conf->alt_lna_conf = | ||
246 | ATH_ANT_DIV_COMB_LNA2; | ||
247 | } else { | ||
248 | /* Set alt to A+B or A-B */ | ||
249 | div_ant_conf->alt_lna_conf = | ||
250 | antcomb->second_quick_scan_conf; | ||
251 | } | ||
252 | } else if (antcomb->first_ratio) { | ||
253 | /* first alt */ | ||
254 | if ((antcomb->first_quick_scan_conf == | ||
255 | ATH_ANT_DIV_COMB_LNA1) || | ||
256 | (antcomb->first_quick_scan_conf == | ||
257 | ATH_ANT_DIV_COMB_LNA2)) | ||
258 | /* Set alt LNA1 or LNA2 */ | ||
259 | if (div_ant_conf->main_lna_conf == | ||
260 | ATH_ANT_DIV_COMB_LNA2) | ||
261 | div_ant_conf->alt_lna_conf = | ||
262 | ATH_ANT_DIV_COMB_LNA1; | ||
263 | else | ||
264 | div_ant_conf->alt_lna_conf = | ||
265 | ATH_ANT_DIV_COMB_LNA2; | ||
266 | else | ||
267 | /* Set alt to A+B or A-B */ | ||
268 | div_ant_conf->alt_lna_conf = | ||
269 | antcomb->first_quick_scan_conf; | ||
270 | } else if (antcomb->second_ratio) { | ||
271 | /* second alt */ | ||
272 | if ((antcomb->second_quick_scan_conf == | ||
273 | ATH_ANT_DIV_COMB_LNA1) || | ||
274 | (antcomb->second_quick_scan_conf == | ||
275 | ATH_ANT_DIV_COMB_LNA2)) | ||
276 | /* Set alt LNA1 or LNA2 */ | ||
277 | if (div_ant_conf->main_lna_conf == | ||
278 | ATH_ANT_DIV_COMB_LNA2) | ||
279 | div_ant_conf->alt_lna_conf = | ||
280 | ATH_ANT_DIV_COMB_LNA1; | ||
281 | else | ||
282 | div_ant_conf->alt_lna_conf = | ||
283 | ATH_ANT_DIV_COMB_LNA2; | ||
284 | else | ||
285 | /* Set alt to A+B or A-B */ | ||
286 | div_ant_conf->alt_lna_conf = | ||
287 | antcomb->second_quick_scan_conf; | ||
288 | } else { | ||
289 | /* main is largest */ | ||
290 | if ((antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) || | ||
291 | (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2)) | ||
292 | /* Set alt LNA1 or LNA2 */ | ||
293 | if (div_ant_conf->main_lna_conf == | ||
294 | ATH_ANT_DIV_COMB_LNA2) | ||
295 | div_ant_conf->alt_lna_conf = | ||
296 | ATH_ANT_DIV_COMB_LNA1; | ||
297 | else | ||
298 | div_ant_conf->alt_lna_conf = | ||
299 | ATH_ANT_DIV_COMB_LNA2; | ||
300 | else | ||
301 | /* Set alt to A+B or A-B */ | ||
302 | div_ant_conf->alt_lna_conf = antcomb->main_conf; | ||
303 | } | ||
304 | break; | ||
305 | default: | ||
306 | break; | ||
307 | } | ||
308 | } | ||
309 | |||
310 | static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, | ||
311 | struct ath_ant_comb *antcomb, | ||
312 | int alt_ratio) | ||
313 | { | ||
314 | if (ant_conf->div_group == 0) { | ||
315 | /* Adjust the fast_div_bias based on main and alt lna conf */ | ||
316 | switch ((ant_conf->main_lna_conf << 4) | | ||
317 | ant_conf->alt_lna_conf) { | ||
318 | case 0x01: /* A-B LNA2 */ | ||
319 | ant_conf->fast_div_bias = 0x3b; | ||
320 | break; | ||
321 | case 0x02: /* A-B LNA1 */ | ||
322 | ant_conf->fast_div_bias = 0x3d; | ||
323 | break; | ||
324 | case 0x03: /* A-B A+B */ | ||
325 | ant_conf->fast_div_bias = 0x1; | ||
326 | break; | ||
327 | case 0x10: /* LNA2 A-B */ | ||
328 | ant_conf->fast_div_bias = 0x7; | ||
329 | break; | ||
330 | case 0x12: /* LNA2 LNA1 */ | ||
331 | ant_conf->fast_div_bias = 0x2; | ||
332 | break; | ||
333 | case 0x13: /* LNA2 A+B */ | ||
334 | ant_conf->fast_div_bias = 0x7; | ||
335 | break; | ||
336 | case 0x20: /* LNA1 A-B */ | ||
337 | ant_conf->fast_div_bias = 0x6; | ||
338 | break; | ||
339 | case 0x21: /* LNA1 LNA2 */ | ||
340 | ant_conf->fast_div_bias = 0x0; | ||
341 | break; | ||
342 | case 0x23: /* LNA1 A+B */ | ||
343 | ant_conf->fast_div_bias = 0x6; | ||
344 | break; | ||
345 | case 0x30: /* A+B A-B */ | ||
346 | ant_conf->fast_div_bias = 0x1; | ||
347 | break; | ||
348 | case 0x31: /* A+B LNA2 */ | ||
349 | ant_conf->fast_div_bias = 0x3b; | ||
350 | break; | ||
351 | case 0x32: /* A+B LNA1 */ | ||
352 | ant_conf->fast_div_bias = 0x3d; | ||
353 | break; | ||
354 | default: | ||
355 | break; | ||
356 | } | ||
357 | } else if (ant_conf->div_group == 1) { | ||
358 | /* Adjust the fast_div_bias based on main and alt_lna_conf */ | ||
359 | switch ((ant_conf->main_lna_conf << 4) | | ||
360 | ant_conf->alt_lna_conf) { | ||
361 | case 0x01: /* A-B LNA2 */ | ||
362 | ant_conf->fast_div_bias = 0x1; | ||
363 | ant_conf->main_gaintb = 0; | ||
364 | ant_conf->alt_gaintb = 0; | ||
365 | break; | ||
366 | case 0x02: /* A-B LNA1 */ | ||
367 | ant_conf->fast_div_bias = 0x1; | ||
368 | ant_conf->main_gaintb = 0; | ||
369 | ant_conf->alt_gaintb = 0; | ||
370 | break; | ||
371 | case 0x03: /* A-B A+B */ | ||
372 | ant_conf->fast_div_bias = 0x1; | ||
373 | ant_conf->main_gaintb = 0; | ||
374 | ant_conf->alt_gaintb = 0; | ||
375 | break; | ||
376 | case 0x10: /* LNA2 A-B */ | ||
377 | if (!(antcomb->scan) && | ||
378 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
379 | ant_conf->fast_div_bias = 0x3f; | ||
380 | else | ||
381 | ant_conf->fast_div_bias = 0x1; | ||
382 | ant_conf->main_gaintb = 0; | ||
383 | ant_conf->alt_gaintb = 0; | ||
384 | break; | ||
385 | case 0x12: /* LNA2 LNA1 */ | ||
386 | ant_conf->fast_div_bias = 0x1; | ||
387 | ant_conf->main_gaintb = 0; | ||
388 | ant_conf->alt_gaintb = 0; | ||
389 | break; | ||
390 | case 0x13: /* LNA2 A+B */ | ||
391 | if (!(antcomb->scan) && | ||
392 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
393 | ant_conf->fast_div_bias = 0x3f; | ||
394 | else | ||
395 | ant_conf->fast_div_bias = 0x1; | ||
396 | ant_conf->main_gaintb = 0; | ||
397 | ant_conf->alt_gaintb = 0; | ||
398 | break; | ||
399 | case 0x20: /* LNA1 A-B */ | ||
400 | if (!(antcomb->scan) && | ||
401 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
402 | ant_conf->fast_div_bias = 0x3f; | ||
403 | else | ||
404 | ant_conf->fast_div_bias = 0x1; | ||
405 | ant_conf->main_gaintb = 0; | ||
406 | ant_conf->alt_gaintb = 0; | ||
407 | break; | ||
408 | case 0x21: /* LNA1 LNA2 */ | ||
409 | ant_conf->fast_div_bias = 0x1; | ||
410 | ant_conf->main_gaintb = 0; | ||
411 | ant_conf->alt_gaintb = 0; | ||
412 | break; | ||
413 | case 0x23: /* LNA1 A+B */ | ||
414 | if (!(antcomb->scan) && | ||
415 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
416 | ant_conf->fast_div_bias = 0x3f; | ||
417 | else | ||
418 | ant_conf->fast_div_bias = 0x1; | ||
419 | ant_conf->main_gaintb = 0; | ||
420 | ant_conf->alt_gaintb = 0; | ||
421 | break; | ||
422 | case 0x30: /* A+B A-B */ | ||
423 | ant_conf->fast_div_bias = 0x1; | ||
424 | ant_conf->main_gaintb = 0; | ||
425 | ant_conf->alt_gaintb = 0; | ||
426 | break; | ||
427 | case 0x31: /* A+B LNA2 */ | ||
428 | ant_conf->fast_div_bias = 0x1; | ||
429 | ant_conf->main_gaintb = 0; | ||
430 | ant_conf->alt_gaintb = 0; | ||
431 | break; | ||
432 | case 0x32: /* A+B LNA1 */ | ||
433 | ant_conf->fast_div_bias = 0x1; | ||
434 | ant_conf->main_gaintb = 0; | ||
435 | ant_conf->alt_gaintb = 0; | ||
436 | break; | ||
437 | default: | ||
438 | break; | ||
439 | } | ||
440 | } else if (ant_conf->div_group == 2) { | ||
441 | /* Adjust the fast_div_bias based on main and alt_lna_conf */ | ||
442 | switch ((ant_conf->main_lna_conf << 4) | | ||
443 | ant_conf->alt_lna_conf) { | ||
444 | case 0x01: /* A-B LNA2 */ | ||
445 | ant_conf->fast_div_bias = 0x1; | ||
446 | ant_conf->main_gaintb = 0; | ||
447 | ant_conf->alt_gaintb = 0; | ||
448 | break; | ||
449 | case 0x02: /* A-B LNA1 */ | ||
450 | ant_conf->fast_div_bias = 0x1; | ||
451 | ant_conf->main_gaintb = 0; | ||
452 | ant_conf->alt_gaintb = 0; | ||
453 | break; | ||
454 | case 0x03: /* A-B A+B */ | ||
455 | ant_conf->fast_div_bias = 0x1; | ||
456 | ant_conf->main_gaintb = 0; | ||
457 | ant_conf->alt_gaintb = 0; | ||
458 | break; | ||
459 | case 0x10: /* LNA2 A-B */ | ||
460 | if (!(antcomb->scan) && | ||
461 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
462 | ant_conf->fast_div_bias = 0x1; | ||
463 | else | ||
464 | ant_conf->fast_div_bias = 0x2; | ||
465 | ant_conf->main_gaintb = 0; | ||
466 | ant_conf->alt_gaintb = 0; | ||
467 | break; | ||
468 | case 0x12: /* LNA2 LNA1 */ | ||
469 | ant_conf->fast_div_bias = 0x1; | ||
470 | ant_conf->main_gaintb = 0; | ||
471 | ant_conf->alt_gaintb = 0; | ||
472 | break; | ||
473 | case 0x13: /* LNA2 A+B */ | ||
474 | if (!(antcomb->scan) && | ||
475 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
476 | ant_conf->fast_div_bias = 0x1; | ||
477 | else | ||
478 | ant_conf->fast_div_bias = 0x2; | ||
479 | ant_conf->main_gaintb = 0; | ||
480 | ant_conf->alt_gaintb = 0; | ||
481 | break; | ||
482 | case 0x20: /* LNA1 A-B */ | ||
483 | if (!(antcomb->scan) && | ||
484 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
485 | ant_conf->fast_div_bias = 0x1; | ||
486 | else | ||
487 | ant_conf->fast_div_bias = 0x2; | ||
488 | ant_conf->main_gaintb = 0; | ||
489 | ant_conf->alt_gaintb = 0; | ||
490 | break; | ||
491 | case 0x21: /* LNA1 LNA2 */ | ||
492 | ant_conf->fast_div_bias = 0x1; | ||
493 | ant_conf->main_gaintb = 0; | ||
494 | ant_conf->alt_gaintb = 0; | ||
495 | break; | ||
496 | case 0x23: /* LNA1 A+B */ | ||
497 | if (!(antcomb->scan) && | ||
498 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
499 | ant_conf->fast_div_bias = 0x1; | ||
500 | else | ||
501 | ant_conf->fast_div_bias = 0x2; | ||
502 | ant_conf->main_gaintb = 0; | ||
503 | ant_conf->alt_gaintb = 0; | ||
504 | break; | ||
505 | case 0x30: /* A+B A-B */ | ||
506 | ant_conf->fast_div_bias = 0x1; | ||
507 | ant_conf->main_gaintb = 0; | ||
508 | ant_conf->alt_gaintb = 0; | ||
509 | break; | ||
510 | case 0x31: /* A+B LNA2 */ | ||
511 | ant_conf->fast_div_bias = 0x1; | ||
512 | ant_conf->main_gaintb = 0; | ||
513 | ant_conf->alt_gaintb = 0; | ||
514 | break; | ||
515 | case 0x32: /* A+B LNA1 */ | ||
516 | ant_conf->fast_div_bias = 0x1; | ||
517 | ant_conf->main_gaintb = 0; | ||
518 | ant_conf->alt_gaintb = 0; | ||
519 | break; | ||
520 | default: | ||
521 | break; | ||
522 | } | ||
523 | } | ||
524 | } | ||
525 | |||
526 | void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs) | ||
527 | { | ||
528 | struct ath_hw_antcomb_conf div_ant_conf; | ||
529 | struct ath_ant_comb *antcomb = &sc->ant_comb; | ||
530 | int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set; | ||
531 | int curr_main_set; | ||
532 | int main_rssi = rs->rs_rssi_ctl0; | ||
533 | int alt_rssi = rs->rs_rssi_ctl1; | ||
534 | int rx_ant_conf, main_ant_conf; | ||
535 | bool short_scan = false; | ||
536 | |||
537 | rx_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_CURRENT_SHIFT) & | ||
538 | ATH_ANT_RX_MASK; | ||
539 | main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) & | ||
540 | ATH_ANT_RX_MASK; | ||
541 | |||
542 | /* Record packet only when both main_rssi and alt_rssi is positive */ | ||
543 | if (main_rssi > 0 && alt_rssi > 0) { | ||
544 | antcomb->total_pkt_count++; | ||
545 | antcomb->main_total_rssi += main_rssi; | ||
546 | antcomb->alt_total_rssi += alt_rssi; | ||
547 | if (main_ant_conf == rx_ant_conf) | ||
548 | antcomb->main_recv_cnt++; | ||
549 | else | ||
550 | antcomb->alt_recv_cnt++; | ||
551 | } | ||
552 | |||
553 | /* Short scan check */ | ||
554 | if (antcomb->scan && antcomb->alt_good) { | ||
555 | if (time_after(jiffies, antcomb->scan_start_time + | ||
556 | msecs_to_jiffies(ATH_ANT_DIV_COMB_SHORT_SCAN_INTR))) | ||
557 | short_scan = true; | ||
558 | else | ||
559 | if (antcomb->total_pkt_count == | ||
560 | ATH_ANT_DIV_COMB_SHORT_SCAN_PKTCOUNT) { | ||
561 | alt_ratio = ((antcomb->alt_recv_cnt * 100) / | ||
562 | antcomb->total_pkt_count); | ||
563 | if (alt_ratio < ATH_ANT_DIV_COMB_ALT_ANT_RATIO) | ||
564 | short_scan = true; | ||
565 | } | ||
566 | } | ||
567 | |||
568 | if (((antcomb->total_pkt_count < ATH_ANT_DIV_COMB_MAX_PKTCOUNT) || | ||
569 | rs->rs_moreaggr) && !short_scan) | ||
570 | return; | ||
571 | |||
572 | if (antcomb->total_pkt_count) { | ||
573 | alt_ratio = ((antcomb->alt_recv_cnt * 100) / | ||
574 | antcomb->total_pkt_count); | ||
575 | main_rssi_avg = (antcomb->main_total_rssi / | ||
576 | antcomb->total_pkt_count); | ||
577 | alt_rssi_avg = (antcomb->alt_total_rssi / | ||
578 | antcomb->total_pkt_count); | ||
579 | } | ||
580 | |||
581 | |||
582 | ath9k_hw_antdiv_comb_conf_get(sc->sc_ah, &div_ant_conf); | ||
583 | curr_alt_set = div_ant_conf.alt_lna_conf; | ||
584 | curr_main_set = div_ant_conf.main_lna_conf; | ||
585 | |||
586 | antcomb->count++; | ||
587 | |||
588 | if (antcomb->count == ATH_ANT_DIV_COMB_MAX_COUNT) { | ||
589 | if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) { | ||
590 | ath_lnaconf_alt_good_scan(antcomb, div_ant_conf, | ||
591 | main_rssi_avg); | ||
592 | antcomb->alt_good = true; | ||
593 | } else { | ||
594 | antcomb->alt_good = false; | ||
595 | } | ||
596 | |||
597 | antcomb->count = 0; | ||
598 | antcomb->scan = true; | ||
599 | antcomb->scan_not_start = true; | ||
600 | } | ||
601 | |||
602 | if (!antcomb->scan) { | ||
603 | if (ath_ant_div_comb_alt_check(div_ant_conf.div_group, | ||
604 | alt_ratio, curr_main_set, curr_alt_set, | ||
605 | alt_rssi_avg, main_rssi_avg)) { | ||
606 | if (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) { | ||
607 | /* Switch main and alt LNA */ | ||
608 | div_ant_conf.main_lna_conf = | ||
609 | ATH_ANT_DIV_COMB_LNA2; | ||
610 | div_ant_conf.alt_lna_conf = | ||
611 | ATH_ANT_DIV_COMB_LNA1; | ||
612 | } else if (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) { | ||
613 | div_ant_conf.main_lna_conf = | ||
614 | ATH_ANT_DIV_COMB_LNA1; | ||
615 | div_ant_conf.alt_lna_conf = | ||
616 | ATH_ANT_DIV_COMB_LNA2; | ||
617 | } | ||
618 | |||
619 | goto div_comb_done; | ||
620 | } else if ((curr_alt_set != ATH_ANT_DIV_COMB_LNA1) && | ||
621 | (curr_alt_set != ATH_ANT_DIV_COMB_LNA2)) { | ||
622 | /* Set alt to another LNA */ | ||
623 | if (curr_main_set == ATH_ANT_DIV_COMB_LNA2) | ||
624 | div_ant_conf.alt_lna_conf = | ||
625 | ATH_ANT_DIV_COMB_LNA1; | ||
626 | else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1) | ||
627 | div_ant_conf.alt_lna_conf = | ||
628 | ATH_ANT_DIV_COMB_LNA2; | ||
629 | |||
630 | goto div_comb_done; | ||
631 | } | ||
632 | |||
633 | if ((alt_rssi_avg < (main_rssi_avg + | ||
634 | div_ant_conf.lna1_lna2_delta))) | ||
635 | goto div_comb_done; | ||
636 | } | ||
637 | |||
638 | if (!antcomb->scan_not_start) { | ||
639 | switch (curr_alt_set) { | ||
640 | case ATH_ANT_DIV_COMB_LNA2: | ||
641 | antcomb->rssi_lna2 = alt_rssi_avg; | ||
642 | antcomb->rssi_lna1 = main_rssi_avg; | ||
643 | antcomb->scan = true; | ||
644 | /* set to A+B */ | ||
645 | div_ant_conf.main_lna_conf = | ||
646 | ATH_ANT_DIV_COMB_LNA1; | ||
647 | div_ant_conf.alt_lna_conf = | ||
648 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
649 | break; | ||
650 | case ATH_ANT_DIV_COMB_LNA1: | ||
651 | antcomb->rssi_lna1 = alt_rssi_avg; | ||
652 | antcomb->rssi_lna2 = main_rssi_avg; | ||
653 | antcomb->scan = true; | ||
654 | /* set to A+B */ | ||
655 | div_ant_conf.main_lna_conf = ATH_ANT_DIV_COMB_LNA2; | ||
656 | div_ant_conf.alt_lna_conf = | ||
657 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
658 | break; | ||
659 | case ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2: | ||
660 | antcomb->rssi_add = alt_rssi_avg; | ||
661 | antcomb->scan = true; | ||
662 | /* set to A-B */ | ||
663 | div_ant_conf.alt_lna_conf = | ||
664 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
665 | break; | ||
666 | case ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2: | ||
667 | antcomb->rssi_sub = alt_rssi_avg; | ||
668 | antcomb->scan = false; | ||
669 | if (antcomb->rssi_lna2 > | ||
670 | (antcomb->rssi_lna1 + | ||
671 | ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA)) { | ||
672 | /* use LNA2 as main LNA */ | ||
673 | if ((antcomb->rssi_add > antcomb->rssi_lna1) && | ||
674 | (antcomb->rssi_add > antcomb->rssi_sub)) { | ||
675 | /* set to A+B */ | ||
676 | div_ant_conf.main_lna_conf = | ||
677 | ATH_ANT_DIV_COMB_LNA2; | ||
678 | div_ant_conf.alt_lna_conf = | ||
679 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
680 | } else if (antcomb->rssi_sub > | ||
681 | antcomb->rssi_lna1) { | ||
682 | /* set to A-B */ | ||
683 | div_ant_conf.main_lna_conf = | ||
684 | ATH_ANT_DIV_COMB_LNA2; | ||
685 | div_ant_conf.alt_lna_conf = | ||
686 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
687 | } else { | ||
688 | /* set to LNA1 */ | ||
689 | div_ant_conf.main_lna_conf = | ||
690 | ATH_ANT_DIV_COMB_LNA2; | ||
691 | div_ant_conf.alt_lna_conf = | ||
692 | ATH_ANT_DIV_COMB_LNA1; | ||
693 | } | ||
694 | } else { | ||
695 | /* use LNA1 as main LNA */ | ||
696 | if ((antcomb->rssi_add > antcomb->rssi_lna2) && | ||
697 | (antcomb->rssi_add > antcomb->rssi_sub)) { | ||
698 | /* set to A+B */ | ||
699 | div_ant_conf.main_lna_conf = | ||
700 | ATH_ANT_DIV_COMB_LNA1; | ||
701 | div_ant_conf.alt_lna_conf = | ||
702 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
703 | } else if (antcomb->rssi_sub > | ||
704 | antcomb->rssi_lna1) { | ||
705 | /* set to A-B */ | ||
706 | div_ant_conf.main_lna_conf = | ||
707 | ATH_ANT_DIV_COMB_LNA1; | ||
708 | div_ant_conf.alt_lna_conf = | ||
709 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
710 | } else { | ||
711 | /* set to LNA2 */ | ||
712 | div_ant_conf.main_lna_conf = | ||
713 | ATH_ANT_DIV_COMB_LNA1; | ||
714 | div_ant_conf.alt_lna_conf = | ||
715 | ATH_ANT_DIV_COMB_LNA2; | ||
716 | } | ||
717 | } | ||
718 | break; | ||
719 | default: | ||
720 | break; | ||
721 | } | ||
722 | } else { | ||
723 | if (!antcomb->alt_good) { | ||
724 | antcomb->scan_not_start = false; | ||
725 | /* Set alt to another LNA */ | ||
726 | if (curr_main_set == ATH_ANT_DIV_COMB_LNA2) { | ||
727 | div_ant_conf.main_lna_conf = | ||
728 | ATH_ANT_DIV_COMB_LNA2; | ||
729 | div_ant_conf.alt_lna_conf = | ||
730 | ATH_ANT_DIV_COMB_LNA1; | ||
731 | } else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1) { | ||
732 | div_ant_conf.main_lna_conf = | ||
733 | ATH_ANT_DIV_COMB_LNA1; | ||
734 | div_ant_conf.alt_lna_conf = | ||
735 | ATH_ANT_DIV_COMB_LNA2; | ||
736 | } | ||
737 | goto div_comb_done; | ||
738 | } | ||
739 | } | ||
740 | |||
741 | ath_select_ant_div_from_quick_scan(antcomb, &div_ant_conf, | ||
742 | main_rssi_avg, alt_rssi_avg, | ||
743 | alt_ratio); | ||
744 | |||
745 | antcomb->quick_scan_cnt++; | ||
746 | |||
747 | div_comb_done: | ||
748 | ath_ant_div_conf_fast_divbias(&div_ant_conf, antcomb, alt_ratio); | ||
749 | ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf); | ||
750 | |||
751 | antcomb->scan_start_time = jiffies; | ||
752 | antcomb->total_pkt_count = 0; | ||
753 | antcomb->main_total_rssi = 0; | ||
754 | antcomb->alt_total_rssi = 0; | ||
755 | antcomb->main_recv_cnt = 0; | ||
756 | antcomb->alt_recv_cnt = 0; | ||
757 | } | ||
758 | |||
759 | void ath_ant_comb_update(struct ath_softc *sc) | ||
760 | { | ||
761 | struct ath_hw *ah = sc->sc_ah; | ||
762 | struct ath_hw_antcomb_conf div_ant_conf; | ||
763 | u8 lna_conf; | ||
764 | |||
765 | ath9k_hw_antdiv_comb_conf_get(ah, &div_ant_conf); | ||
766 | |||
767 | if (sc->ant_rx == 1) | ||
768 | lna_conf = ATH_ANT_DIV_COMB_LNA1; | ||
769 | else | ||
770 | lna_conf = ATH_ANT_DIV_COMB_LNA2; | ||
771 | |||
772 | div_ant_conf.main_lna_conf = lna_conf; | ||
773 | div_ant_conf.alt_lna_conf = lna_conf; | ||
774 | |||
775 | ath9k_hw_antdiv_comb_conf_set(ah, &div_ant_conf); | ||
776 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 52ff5caf2d0b..c7492c6a2519 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c | |||
@@ -245,7 +245,6 @@ static int ar5008_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | |||
245 | REG_WRITE(ah, AR_PHY(0x37), reg32); | 245 | REG_WRITE(ah, AR_PHY(0x37), reg32); |
246 | 246 | ||
247 | ah->curchan = chan; | 247 | ah->curchan = chan; |
248 | ah->curchan_rad_index = -1; | ||
249 | 248 | ||
250 | return 0; | 249 | return 0; |
251 | } | 250 | } |
@@ -619,19 +618,10 @@ static void ar5008_hw_init_bb(struct ath_hw *ah, | |||
619 | u32 synthDelay; | 618 | u32 synthDelay; |
620 | 619 | ||
621 | synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; | 620 | synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; |
622 | if (IS_CHAN_B(chan)) | ||
623 | synthDelay = (4 * synthDelay) / 22; | ||
624 | else | ||
625 | synthDelay /= 10; | ||
626 | |||
627 | if (IS_CHAN_HALF_RATE(chan)) | ||
628 | synthDelay *= 2; | ||
629 | else if (IS_CHAN_QUARTER_RATE(chan)) | ||
630 | synthDelay *= 4; | ||
631 | 621 | ||
632 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); | 622 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); |
633 | 623 | ||
634 | udelay(synthDelay + BASE_ACTIVATE_DELAY); | 624 | ath9k_hw_synth_delay(ah, chan, synthDelay); |
635 | } | 625 | } |
636 | 626 | ||
637 | static void ar5008_hw_init_chain_masks(struct ath_hw *ah) | 627 | static void ar5008_hw_init_chain_masks(struct ath_hw *ah) |
@@ -869,7 +859,7 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, | |||
869 | ar5008_hw_set_channel_regs(ah, chan); | 859 | ar5008_hw_set_channel_regs(ah, chan); |
870 | ar5008_hw_init_chain_masks(ah); | 860 | ar5008_hw_init_chain_masks(ah); |
871 | ath9k_olc_init(ah); | 861 | ath9k_olc_init(ah); |
872 | ath9k_hw_apply_txpower(ah, chan); | 862 | ath9k_hw_apply_txpower(ah, chan, false); |
873 | 863 | ||
874 | /* Write analog registers */ | 864 | /* Write analog registers */ |
875 | if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { | 865 | if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { |
@@ -949,12 +939,8 @@ static bool ar5008_hw_rfbus_req(struct ath_hw *ah) | |||
949 | static void ar5008_hw_rfbus_done(struct ath_hw *ah) | 939 | static void ar5008_hw_rfbus_done(struct ath_hw *ah) |
950 | { | 940 | { |
951 | u32 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; | 941 | u32 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; |
952 | if (IS_CHAN_B(ah->curchan)) | ||
953 | synthDelay = (4 * synthDelay) / 22; | ||
954 | else | ||
955 | synthDelay /= 10; | ||
956 | 942 | ||
957 | udelay(synthDelay + BASE_ACTIVATE_DELAY); | 943 | ath9k_hw_synth_delay(ah, ah->curchan, synthDelay); |
958 | 944 | ||
959 | REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0); | 945 | REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0); |
960 | } | 946 | } |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index aa2abaf31cba..8d78253c26ce 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c | |||
@@ -136,6 +136,7 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) | |||
136 | } | 136 | } |
137 | 137 | ||
138 | if (sync_cause) { | 138 | if (sync_cause) { |
139 | ath9k_debug_sync_cause(common, sync_cause); | ||
139 | fatal_int = | 140 | fatal_int = |
140 | (sync_cause & | 141 | (sync_cause & |
141 | (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR)) | 142 | (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR)) |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c index 3cbbb033fcea..846dd7974eb8 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c | |||
@@ -152,7 +152,6 @@ static int ar9002_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | |||
152 | REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32); | 152 | REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32); |
153 | 153 | ||
154 | ah->curchan = chan; | 154 | ah->curchan = chan; |
155 | ah->curchan_rad_index = -1; | ||
156 | 155 | ||
157 | return 0; | 156 | return 0; |
158 | } | 157 | } |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 63089cc1fafd..d7deb8c9f299 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c | |||
@@ -653,7 +653,6 @@ static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement, | |||
653 | } | 653 | } |
654 | 654 | ||
655 | static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, | 655 | static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, |
656 | u8 num_chains, | ||
657 | struct coeff *coeff, | 656 | struct coeff *coeff, |
658 | bool is_reusable) | 657 | bool is_reusable) |
659 | { | 658 | { |
@@ -677,7 +676,9 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, | |||
677 | } | 676 | } |
678 | 677 | ||
679 | /* Load the average of 2 passes */ | 678 | /* Load the average of 2 passes */ |
680 | for (i = 0; i < num_chains; i++) { | 679 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { |
680 | if (!(ah->txchainmask & (1 << i))) | ||
681 | continue; | ||
681 | nmeasurement = REG_READ_FIELD(ah, | 682 | nmeasurement = REG_READ_FIELD(ah, |
682 | AR_PHY_TX_IQCAL_STATUS_B0, | 683 | AR_PHY_TX_IQCAL_STATUS_B0, |
683 | AR_PHY_CALIBRATED_GAINS_0); | 684 | AR_PHY_CALIBRATED_GAINS_0); |
@@ -767,16 +768,13 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, bool is_reusable) | |||
767 | }; | 768 | }; |
768 | struct coeff coeff; | 769 | struct coeff coeff; |
769 | s32 iq_res[6]; | 770 | s32 iq_res[6]; |
770 | u8 num_chains = 0; | ||
771 | int i, im, j; | 771 | int i, im, j; |
772 | int nmeasurement; | 772 | int nmeasurement; |
773 | 773 | ||
774 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | 774 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { |
775 | if (ah->txchainmask & (1 << i)) | 775 | if (!(ah->txchainmask & (1 << i))) |
776 | num_chains++; | 776 | continue; |
777 | } | ||
778 | 777 | ||
779 | for (i = 0; i < num_chains; i++) { | ||
780 | nmeasurement = REG_READ_FIELD(ah, | 778 | nmeasurement = REG_READ_FIELD(ah, |
781 | AR_PHY_TX_IQCAL_STATUS_B0, | 779 | AR_PHY_TX_IQCAL_STATUS_B0, |
782 | AR_PHY_CALIBRATED_GAINS_0); | 780 | AR_PHY_CALIBRATED_GAINS_0); |
@@ -839,8 +837,7 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, bool is_reusable) | |||
839 | coeff.phs_coeff[i][im] -= 128; | 837 | coeff.phs_coeff[i][im] -= 128; |
840 | } | 838 | } |
841 | } | 839 | } |
842 | ar9003_hw_tx_iqcal_load_avg_2_passes(ah, num_chains, | 840 | ar9003_hw_tx_iqcal_load_avg_2_passes(ah, &coeff, is_reusable); |
843 | &coeff, is_reusable); | ||
844 | 841 | ||
845 | return; | 842 | return; |
846 | 843 | ||
@@ -892,34 +889,6 @@ static void ar9003_hw_tx_iq_cal_reload(struct ath_hw *ah) | |||
892 | AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); | 889 | AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); |
893 | } | 890 | } |
894 | 891 | ||
895 | static bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan) | ||
896 | { | ||
897 | struct ath9k_rtt_hist *hist; | ||
898 | u32 *table; | ||
899 | int i; | ||
900 | bool restore; | ||
901 | |||
902 | if (!ah->caldata) | ||
903 | return false; | ||
904 | |||
905 | hist = &ah->caldata->rtt_hist; | ||
906 | if (!hist->num_readings) | ||
907 | return false; | ||
908 | |||
909 | ar9003_hw_rtt_enable(ah); | ||
910 | ar9003_hw_rtt_set_mask(ah, 0x00); | ||
911 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | ||
912 | if (!(ah->rxchainmask & (1 << i))) | ||
913 | continue; | ||
914 | table = &hist->table[i][hist->num_readings][0]; | ||
915 | ar9003_hw_rtt_load_hist(ah, i, table); | ||
916 | } | ||
917 | restore = ar9003_hw_rtt_force_restore(ah); | ||
918 | ar9003_hw_rtt_disable(ah); | ||
919 | |||
920 | return restore; | ||
921 | } | ||
922 | |||
923 | static bool ar9003_hw_init_cal(struct ath_hw *ah, | 892 | static bool ar9003_hw_init_cal(struct ath_hw *ah, |
924 | struct ath9k_channel *chan) | 893 | struct ath9k_channel *chan) |
925 | { | 894 | { |
@@ -929,7 +898,6 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
929 | bool is_reusable = true, status = true; | 898 | bool is_reusable = true, status = true; |
930 | bool run_rtt_cal = false, run_agc_cal; | 899 | bool run_rtt_cal = false, run_agc_cal; |
931 | bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT); | 900 | bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT); |
932 | bool mci = !!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI); | ||
933 | u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL | | 901 | u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL | |
934 | AR_PHY_AGC_CONTROL_FLTR_CAL | | 902 | AR_PHY_AGC_CONTROL_FLTR_CAL | |
935 | AR_PHY_AGC_CONTROL_PKDET_CAL; | 903 | AR_PHY_AGC_CONTROL_PKDET_CAL; |
@@ -942,9 +910,10 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
942 | if (!ar9003_hw_rtt_restore(ah, chan)) | 910 | if (!ar9003_hw_rtt_restore(ah, chan)) |
943 | run_rtt_cal = true; | 911 | run_rtt_cal = true; |
944 | 912 | ||
945 | ath_dbg(common, CALIBRATE, "RTT restore %s\n", | 913 | if (run_rtt_cal) |
946 | run_rtt_cal ? "failed" : "succeed"); | 914 | ath_dbg(common, CALIBRATE, "RTT calibration to be done\n"); |
947 | } | 915 | } |
916 | |||
948 | run_agc_cal = run_rtt_cal; | 917 | run_agc_cal = run_rtt_cal; |
949 | 918 | ||
950 | if (run_rtt_cal) { | 919 | if (run_rtt_cal) { |
@@ -997,13 +966,15 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
997 | } else if (caldata && !caldata->done_txiqcal_once) | 966 | } else if (caldata && !caldata->done_txiqcal_once) |
998 | run_agc_cal = true; | 967 | run_agc_cal = true; |
999 | 968 | ||
1000 | if (mci && IS_CHAN_2GHZ(chan) && run_agc_cal) | 969 | if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) |
1001 | ar9003_mci_init_cal_req(ah, &is_reusable); | 970 | ar9003_mci_init_cal_req(ah, &is_reusable); |
1002 | 971 | ||
1003 | txiqcal_done = ar9003_hw_tx_iq_cal_run(ah); | 972 | if (!(IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan))) { |
1004 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); | 973 | txiqcal_done = ar9003_hw_tx_iq_cal_run(ah); |
1005 | udelay(5); | 974 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); |
1006 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); | 975 | udelay(5); |
976 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); | ||
977 | } | ||
1007 | 978 | ||
1008 | skip_tx_iqcal: | 979 | skip_tx_iqcal: |
1009 | if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) { | 980 | if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) { |
@@ -1018,7 +989,7 @@ skip_tx_iqcal: | |||
1018 | 0, AH_WAIT_TIMEOUT); | 989 | 0, AH_WAIT_TIMEOUT); |
1019 | } | 990 | } |
1020 | 991 | ||
1021 | if (mci && IS_CHAN_2GHZ(chan) && run_agc_cal) | 992 | if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) |
1022 | ar9003_mci_init_cal_done(ah); | 993 | ar9003_mci_init_cal_done(ah); |
1023 | 994 | ||
1024 | if (rtt && !run_rtt_cal) { | 995 | if (rtt && !run_rtt_cal) { |
@@ -1067,17 +1038,14 @@ skip_tx_iqcal: | |||
1067 | #undef CL_TAB_ENTRY | 1038 | #undef CL_TAB_ENTRY |
1068 | 1039 | ||
1069 | if (run_rtt_cal && caldata) { | 1040 | if (run_rtt_cal && caldata) { |
1070 | struct ath9k_rtt_hist *hist = &caldata->rtt_hist; | 1041 | if (is_reusable) { |
1071 | if (is_reusable && (hist->num_readings < RTT_HIST_MAX)) { | 1042 | if (!ath9k_hw_rfbus_req(ah)) |
1072 | u32 *table; | 1043 | ath_err(ath9k_hw_common(ah), |
1044 | "Could not stop baseband\n"); | ||
1045 | else | ||
1046 | ar9003_hw_rtt_fill_hist(ah); | ||
1073 | 1047 | ||
1074 | hist->num_readings++; | 1048 | ath9k_hw_rfbus_done(ah); |
1075 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | ||
1076 | if (!(ah->rxchainmask & (1 << i))) | ||
1077 | continue; | ||
1078 | table = &hist->table[i][hist->num_readings][0]; | ||
1079 | ar9003_hw_rtt_fill_hist(ah, i, table); | ||
1080 | } | ||
1081 | } | 1049 | } |
1082 | 1050 | ||
1083 | ar9003_hw_rtt_disable(ah); | 1051 | ar9003_hw_rtt_disable(ah); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 6bb4db052bb0..2cdf82bdb11d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -30,11 +30,6 @@ | |||
30 | #define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE) | 30 | #define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE) |
31 | #define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE) | 31 | #define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE) |
32 | #define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE) | 32 | #define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE) |
33 | #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */ | ||
34 | #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */ | ||
35 | #define PWRINCR_3_TO_1_CHAIN 9 /* 10*log(3)*2 */ | ||
36 | #define PWRINCR_3_TO_2_CHAIN 3 /* floor(10*log(3/2)*2) */ | ||
37 | #define PWRINCR_2_TO_1_CHAIN 6 /* 10*log(2)*2 */ | ||
38 | 33 | ||
39 | #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */ | 34 | #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */ |
40 | #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */ | 35 | #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */ |
@@ -2936,15 +2931,6 @@ static const struct ar9300_eeprom *ar9003_eeprom_struct_find_by_id(int id) | |||
2936 | #undef N_LOOP | 2931 | #undef N_LOOP |
2937 | } | 2932 | } |
2938 | 2933 | ||
2939 | |||
2940 | static u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz) | ||
2941 | { | ||
2942 | if (fbin == AR5416_BCHAN_UNUSED) | ||
2943 | return fbin; | ||
2944 | |||
2945 | return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin)); | ||
2946 | } | ||
2947 | |||
2948 | static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah) | 2934 | static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah) |
2949 | { | 2935 | { |
2950 | return 0; | 2936 | return 0; |
@@ -3426,11 +3412,11 @@ static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, | |||
3426 | if (!dump_base_hdr) { | 3412 | if (!dump_base_hdr) { |
3427 | len += snprintf(buf + len, size - len, | 3413 | len += snprintf(buf + len, size - len, |
3428 | "%20s :\n", "2GHz modal Header"); | 3414 | "%20s :\n", "2GHz modal Header"); |
3429 | len += ar9003_dump_modal_eeprom(buf, len, size, | 3415 | len = ar9003_dump_modal_eeprom(buf, len, size, |
3430 | &eep->modalHeader2G); | 3416 | &eep->modalHeader2G); |
3431 | len += snprintf(buf + len, size - len, | 3417 | len += snprintf(buf + len, size - len, |
3432 | "%20s :\n", "5GHz modal Header"); | 3418 | "%20s :\n", "5GHz modal Header"); |
3433 | len += ar9003_dump_modal_eeprom(buf, len, size, | 3419 | len = ar9003_dump_modal_eeprom(buf, len, size, |
3434 | &eep->modalHeader5G); | 3420 | &eep->modalHeader5G); |
3435 | goto out; | 3421 | goto out; |
3436 | } | 3422 | } |
@@ -3627,6 +3613,7 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) | |||
3627 | value = ar9003_switch_com_spdt_get(ah, is2ghz); | 3613 | value = ar9003_switch_com_spdt_get(ah, is2ghz); |
3628 | REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, | 3614 | REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, |
3629 | AR_SWITCH_TABLE_COM_SPDT_ALL, value); | 3615 | AR_SWITCH_TABLE_COM_SPDT_ALL, value); |
3616 | REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, AR_BTCOEX_CTRL_SPDT_ENABLE); | ||
3630 | } | 3617 | } |
3631 | 3618 | ||
3632 | value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz); | 3619 | value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz); |
@@ -3823,7 +3810,7 @@ static bool is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set) | |||
3823 | return true; | 3810 | return true; |
3824 | } | 3811 | } |
3825 | 3812 | ||
3826 | static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) | 3813 | void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) |
3827 | { | 3814 | { |
3828 | int internal_regulator = | 3815 | int internal_regulator = |
3829 | ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR); | 3816 | ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR); |
@@ -4070,7 +4057,7 @@ static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah, | |||
4070 | * targetpower piers stored on eeprom | 4057 | * targetpower piers stored on eeprom |
4071 | */ | 4058 | */ |
4072 | for (i = 0; i < numPiers; i++) { | 4059 | for (i = 0; i < numPiers; i++) { |
4073 | freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz); | 4060 | freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz); |
4074 | targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex]; | 4061 | targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex]; |
4075 | } | 4062 | } |
4076 | 4063 | ||
@@ -4106,7 +4093,7 @@ static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah, | |||
4106 | * from targetpower piers stored on eeprom | 4093 | * from targetpower piers stored on eeprom |
4107 | */ | 4094 | */ |
4108 | for (i = 0; i < numPiers; i++) { | 4095 | for (i = 0; i < numPiers; i++) { |
4109 | freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz); | 4096 | freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz); |
4110 | targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex]; | 4097 | targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex]; |
4111 | } | 4098 | } |
4112 | 4099 | ||
@@ -4142,7 +4129,7 @@ static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah, | |||
4142 | * targetpower piers stored on eeprom | 4129 | * targetpower piers stored on eeprom |
4143 | */ | 4130 | */ |
4144 | for (i = 0; i < numPiers; i++) { | 4131 | for (i = 0; i < numPiers; i++) { |
4145 | freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz); | 4132 | freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz); |
4146 | targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex]; | 4133 | targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex]; |
4147 | } | 4134 | } |
4148 | 4135 | ||
@@ -4167,7 +4154,7 @@ static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah, | |||
4167 | * targetpower piers stored on eeprom | 4154 | * targetpower piers stored on eeprom |
4168 | */ | 4155 | */ |
4169 | for (i = 0; i < numPiers; i++) { | 4156 | for (i = 0; i < numPiers; i++) { |
4170 | freqArray[i] = FBIN2FREQ(pFreqBin[i], 1); | 4157 | freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], 1); |
4171 | targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex]; | 4158 | targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex]; |
4172 | } | 4159 | } |
4173 | 4160 | ||
@@ -4295,18 +4282,10 @@ static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray) | |||
4295 | #undef POW_SM | 4282 | #undef POW_SM |
4296 | } | 4283 | } |
4297 | 4284 | ||
4298 | static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq, | 4285 | static void ar9003_hw_get_legacy_target_powers(struct ath_hw *ah, u16 freq, |
4299 | u8 *targetPowerValT2) | 4286 | u8 *targetPowerValT2, |
4287 | bool is2GHz) | ||
4300 | { | 4288 | { |
4301 | /* XXX: hard code for now, need to get from eeprom struct */ | ||
4302 | u8 ht40PowerIncForPdadc = 0; | ||
4303 | bool is2GHz = false; | ||
4304 | unsigned int i = 0; | ||
4305 | struct ath_common *common = ath9k_hw_common(ah); | ||
4306 | |||
4307 | if (freq < 4000) | ||
4308 | is2GHz = true; | ||
4309 | |||
4310 | targetPowerValT2[ALL_TARGET_LEGACY_6_24] = | 4289 | targetPowerValT2[ALL_TARGET_LEGACY_6_24] = |
4311 | ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq, | 4290 | ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq, |
4312 | is2GHz); | 4291 | is2GHz); |
@@ -4319,6 +4298,11 @@ static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq, | |||
4319 | targetPowerValT2[ALL_TARGET_LEGACY_54] = | 4298 | targetPowerValT2[ALL_TARGET_LEGACY_54] = |
4320 | ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq, | 4299 | ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq, |
4321 | is2GHz); | 4300 | is2GHz); |
4301 | } | ||
4302 | |||
4303 | static void ar9003_hw_get_cck_target_powers(struct ath_hw *ah, u16 freq, | ||
4304 | u8 *targetPowerValT2) | ||
4305 | { | ||
4322 | targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] = | 4306 | targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] = |
4323 | ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L, | 4307 | ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L, |
4324 | freq); | 4308 | freq); |
@@ -4328,6 +4312,11 @@ static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq, | |||
4328 | ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq); | 4312 | ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq); |
4329 | targetPowerValT2[ALL_TARGET_LEGACY_11S] = | 4313 | targetPowerValT2[ALL_TARGET_LEGACY_11S] = |
4330 | ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq); | 4314 | ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq); |
4315 | } | ||
4316 | |||
4317 | static void ar9003_hw_get_ht20_target_powers(struct ath_hw *ah, u16 freq, | ||
4318 | u8 *targetPowerValT2, bool is2GHz) | ||
4319 | { | ||
4331 | targetPowerValT2[ALL_TARGET_HT20_0_8_16] = | 4320 | targetPowerValT2[ALL_TARGET_HT20_0_8_16] = |
4332 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq, | 4321 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq, |
4333 | is2GHz); | 4322 | is2GHz); |
@@ -4370,6 +4359,16 @@ static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq, | |||
4370 | targetPowerValT2[ALL_TARGET_HT20_23] = | 4359 | targetPowerValT2[ALL_TARGET_HT20_23] = |
4371 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq, | 4360 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq, |
4372 | is2GHz); | 4361 | is2GHz); |
4362 | } | ||
4363 | |||
4364 | static void ar9003_hw_get_ht40_target_powers(struct ath_hw *ah, | ||
4365 | u16 freq, | ||
4366 | u8 *targetPowerValT2, | ||
4367 | bool is2GHz) | ||
4368 | { | ||
4369 | /* XXX: hard code for now, need to get from eeprom struct */ | ||
4370 | u8 ht40PowerIncForPdadc = 0; | ||
4371 | |||
4373 | targetPowerValT2[ALL_TARGET_HT40_0_8_16] = | 4372 | targetPowerValT2[ALL_TARGET_HT40_0_8_16] = |
4374 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq, | 4373 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq, |
4375 | is2GHz) + ht40PowerIncForPdadc; | 4374 | is2GHz) + ht40PowerIncForPdadc; |
@@ -4413,6 +4412,26 @@ static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq, | |||
4413 | targetPowerValT2[ALL_TARGET_HT40_23] = | 4412 | targetPowerValT2[ALL_TARGET_HT40_23] = |
4414 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq, | 4413 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq, |
4415 | is2GHz) + ht40PowerIncForPdadc; | 4414 | is2GHz) + ht40PowerIncForPdadc; |
4415 | } | ||
4416 | |||
4417 | static void ar9003_hw_get_target_power_eeprom(struct ath_hw *ah, | ||
4418 | struct ath9k_channel *chan, | ||
4419 | u8 *targetPowerValT2) | ||
4420 | { | ||
4421 | bool is2GHz = IS_CHAN_2GHZ(chan); | ||
4422 | unsigned int i = 0; | ||
4423 | struct ath_common *common = ath9k_hw_common(ah); | ||
4424 | u16 freq = chan->channel; | ||
4425 | |||
4426 | if (is2GHz) | ||
4427 | ar9003_hw_get_cck_target_powers(ah, freq, targetPowerValT2); | ||
4428 | |||
4429 | ar9003_hw_get_legacy_target_powers(ah, freq, targetPowerValT2, is2GHz); | ||
4430 | ar9003_hw_get_ht20_target_powers(ah, freq, targetPowerValT2, is2GHz); | ||
4431 | |||
4432 | if (IS_CHAN_HT40(chan)) | ||
4433 | ar9003_hw_get_ht40_target_powers(ah, freq, targetPowerValT2, | ||
4434 | is2GHz); | ||
4416 | 4435 | ||
4417 | for (i = 0; i < ar9300RateSize; i++) { | 4436 | for (i = 0; i < ar9300RateSize; i++) { |
4418 | ath_dbg(common, EEPROM, "TPC[%02d] 0x%08x\n", | 4437 | ath_dbg(common, EEPROM, "TPC[%02d] 0x%08x\n", |
@@ -4464,7 +4483,7 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah, | |||
4464 | is2GHz = 1; | 4483 | is2GHz = 1; |
4465 | } | 4484 | } |
4466 | 4485 | ||
4467 | *pfrequency = FBIN2FREQ(*pCalPier, is2GHz); | 4486 | *pfrequency = ath9k_hw_fbin2freq(*pCalPier, is2GHz); |
4468 | *pcorrection = pCalPierStruct->refPower; | 4487 | *pcorrection = pCalPierStruct->refPower; |
4469 | *ptemperature = pCalPierStruct->tempMeas; | 4488 | *ptemperature = pCalPierStruct->tempMeas; |
4470 | *pvoltage = pCalPierStruct->voltMeas; | 4489 | *pvoltage = pCalPierStruct->voltMeas; |
@@ -4789,34 +4808,9 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah, | |||
4789 | bool is2ghz = IS_CHAN_2GHZ(chan); | 4808 | bool is2ghz = IS_CHAN_2GHZ(chan); |
4790 | 4809 | ||
4791 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | 4810 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); |
4792 | scaledPower = powerLimit - antenna_reduction; | 4811 | scaledPower = ath9k_hw_get_scaled_power(ah, powerLimit, |
4793 | 4812 | antenna_reduction); | |
4794 | /* | ||
4795 | * Reduce scaled Power by number of chains active to get | ||
4796 | * to per chain tx power level | ||
4797 | */ | ||
4798 | switch (ar5416_get_ntxchains(ah->txchainmask)) { | ||
4799 | case 1: | ||
4800 | break; | ||
4801 | case 2: | ||
4802 | if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN) | ||
4803 | scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; | ||
4804 | else | ||
4805 | scaledPower = 0; | ||
4806 | break; | ||
4807 | case 3: | ||
4808 | if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN) | ||
4809 | scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; | ||
4810 | else | ||
4811 | scaledPower = 0; | ||
4812 | break; | ||
4813 | } | ||
4814 | 4813 | ||
4815 | scaledPower = max((u16)0, scaledPower); | ||
4816 | |||
4817 | /* | ||
4818 | * Get target powers from EEPROM - our baseline for TX Power | ||
4819 | */ | ||
4820 | if (is2ghz) { | 4814 | if (is2ghz) { |
4821 | /* Setup for CTL modes */ | 4815 | /* Setup for CTL modes */ |
4822 | /* CTL_11B, CTL_11G, CTL_2GHT20 */ | 4816 | /* CTL_11B, CTL_11G, CTL_2GHT20 */ |
@@ -4988,7 +4982,12 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, | |||
4988 | unsigned int i = 0, paprd_scale_factor = 0; | 4982 | unsigned int i = 0, paprd_scale_factor = 0; |
4989 | u8 pwr_idx, min_pwridx = 0; | 4983 | u8 pwr_idx, min_pwridx = 0; |
4990 | 4984 | ||
4991 | ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2); | 4985 | memset(targetPowerValT2, 0 , sizeof(targetPowerValT2)); |
4986 | |||
4987 | /* | ||
4988 | * Get target powers from EEPROM - our baseline for TX Power | ||
4989 | */ | ||
4990 | ar9003_hw_get_target_power_eeprom(ah, chan, targetPowerValT2); | ||
4992 | 4991 | ||
4993 | if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) { | 4992 | if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) { |
4994 | if (IS_CHAN_2GHZ(chan)) | 4993 | if (IS_CHAN_2GHZ(chan)) |
@@ -5060,8 +5059,6 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, | |||
5060 | i, targetPowerValT2[i]); | 5059 | i, targetPowerValT2[i]); |
5061 | } | 5060 | } |
5062 | 5061 | ||
5063 | ah->txpower_limit = regulatory->max_power_level; | ||
5064 | |||
5065 | /* Write target power array to registers */ | 5062 | /* Write target power array to registers */ |
5066 | ar9003_hw_tx_power_regwrite(ah, targetPowerValT2); | 5063 | ar9003_hw_tx_power_regwrite(ah, targetPowerValT2); |
5067 | ar9003_hw_calibration_apply(ah, chan->channel); | 5064 | ar9003_hw_calibration_apply(ah, chan->channel); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index bb223fe82816..8396d150ce01 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | |||
@@ -42,7 +42,6 @@ | |||
42 | #define AR9300_EEPMISC_WOW 0x02 | 42 | #define AR9300_EEPMISC_WOW 0x02 |
43 | #define AR9300_CUSTOMER_DATA_SIZE 20 | 43 | #define AR9300_CUSTOMER_DATA_SIZE 20 |
44 | 44 | ||
45 | #define FBIN2FREQ(x, y) ((y) ? (2300 + x) : (4800 + 5 * x)) | ||
46 | #define AR9300_MAX_CHAINS 3 | 45 | #define AR9300_MAX_CHAINS 3 |
47 | #define AR9300_ANT_16S 25 | 46 | #define AR9300_ANT_16S 25 |
48 | #define AR9300_FUTURE_MODAL_SZ 6 | 47 | #define AR9300_FUTURE_MODAL_SZ 6 |
@@ -335,4 +334,7 @@ u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz); | |||
335 | 334 | ||
336 | unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah, | 335 | unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah, |
337 | struct ath9k_channel *chan); | 336 | struct ath9k_channel *chan); |
337 | |||
338 | void ar9003_hw_internal_regulator_apply(struct ath_hw *ah); | ||
339 | |||
338 | #endif | 340 | #endif |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 0f56e322dd3b..a0e3394b10dc 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c | |||
@@ -305,11 +305,6 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) | |||
305 | ar9462_common_rx_gain_table_2p0, | 305 | ar9462_common_rx_gain_table_2p0, |
306 | ARRAY_SIZE(ar9462_common_rx_gain_table_2p0), 2); | 306 | ARRAY_SIZE(ar9462_common_rx_gain_table_2p0), 2); |
307 | 307 | ||
308 | INIT_INI_ARRAY(&ah->ini_BTCOEX_MAX_TXPWR, | ||
309 | ar9462_2p0_BTCOEX_MAX_TXPWR_table, | ||
310 | ARRAY_SIZE(ar9462_2p0_BTCOEX_MAX_TXPWR_table), | ||
311 | 2); | ||
312 | |||
313 | /* Awake -> Sleep Setting */ | 308 | /* Awake -> Sleep Setting */ |
314 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | 309 | INIT_INI_ARRAY(&ah->iniPcieSerdes, |
315 | PCIE_PLL_ON_CREQ_DIS_L1_2P0, | 310 | PCIE_PLL_ON_CREQ_DIS_L1_2P0, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index a66a13b76848..78816b8b2173 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c | |||
@@ -181,11 +181,14 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) | |||
181 | u32 mask2 = 0; | 181 | u32 mask2 = 0; |
182 | struct ath9k_hw_capabilities *pCap = &ah->caps; | 182 | struct ath9k_hw_capabilities *pCap = &ah->caps; |
183 | struct ath_common *common = ath9k_hw_common(ah); | 183 | struct ath_common *common = ath9k_hw_common(ah); |
184 | u32 sync_cause = 0, async_cause; | 184 | u32 sync_cause = 0, async_cause, async_mask = AR_INTR_MAC_IRQ; |
185 | |||
186 | if (ath9k_hw_mci_is_enabled(ah)) | ||
187 | async_mask |= AR_INTR_ASYNC_MASK_MCI; | ||
185 | 188 | ||
186 | async_cause = REG_READ(ah, AR_INTR_ASYNC_CAUSE); | 189 | async_cause = REG_READ(ah, AR_INTR_ASYNC_CAUSE); |
187 | 190 | ||
188 | if (async_cause & (AR_INTR_MAC_IRQ | AR_INTR_ASYNC_MASK_MCI)) { | 191 | if (async_cause & async_mask) { |
189 | if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) | 192 | if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) |
190 | == AR_RTC_STATUS_ON) | 193 | == AR_RTC_STATUS_ON) |
191 | isr = REG_READ(ah, AR_ISR); | 194 | isr = REG_READ(ah, AR_ISR); |
@@ -306,6 +309,8 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) | |||
306 | ar9003_mci_get_isr(ah, masked); | 309 | ar9003_mci_get_isr(ah, masked); |
307 | 310 | ||
308 | if (sync_cause) { | 311 | if (sync_cause) { |
312 | ath9k_debug_sync_cause(common, sync_cause); | ||
313 | |||
309 | if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { | 314 | if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { |
310 | REG_WRITE(ah, AR_RC, AR_RC_HOSTIF); | 315 | REG_WRITE(ah, AR_RC, AR_RC_HOSTIF); |
311 | REG_WRITE(ah, AR_RC, 0); | 316 | REG_WRITE(ah, AR_RC, 0); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index 3cac293a2849..cc2853ade8f8 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c | |||
@@ -35,31 +35,30 @@ static int ar9003_mci_wait_for_interrupt(struct ath_hw *ah, u32 address, | |||
35 | struct ath_common *common = ath9k_hw_common(ah); | 35 | struct ath_common *common = ath9k_hw_common(ah); |
36 | 36 | ||
37 | while (time_out) { | 37 | while (time_out) { |
38 | if (REG_READ(ah, address) & bit_position) { | 38 | if (!(REG_READ(ah, address) & bit_position)) { |
39 | REG_WRITE(ah, address, bit_position); | 39 | udelay(10); |
40 | 40 | time_out -= 10; | |
41 | if (address == AR_MCI_INTERRUPT_RX_MSG_RAW) { | ||
42 | if (bit_position & | ||
43 | AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE) | ||
44 | ar9003_mci_reset_req_wakeup(ah); | ||
45 | |||
46 | if (bit_position & | ||
47 | (AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING | | ||
48 | AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING)) | ||
49 | REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, | ||
50 | AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE); | ||
51 | |||
52 | REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, | ||
53 | AR_MCI_INTERRUPT_RX_MSG); | ||
54 | } | ||
55 | break; | ||
56 | } | ||
57 | 41 | ||
58 | udelay(10); | 42 | if (time_out < 0) |
59 | time_out -= 10; | 43 | break; |
44 | else | ||
45 | continue; | ||
46 | } | ||
47 | REG_WRITE(ah, address, bit_position); | ||
60 | 48 | ||
61 | if (time_out < 0) | 49 | if (address != AR_MCI_INTERRUPT_RX_MSG_RAW) |
62 | break; | 50 | break; |
51 | |||
52 | if (bit_position & AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE) | ||
53 | ar9003_mci_reset_req_wakeup(ah); | ||
54 | |||
55 | if (bit_position & (AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING | | ||
56 | AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING)) | ||
57 | REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, | ||
58 | AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE); | ||
59 | |||
60 | REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, AR_MCI_INTERRUPT_RX_MSG); | ||
61 | break; | ||
63 | } | 62 | } |
64 | 63 | ||
65 | if (time_out <= 0) { | 64 | if (time_out <= 0) { |
@@ -127,14 +126,13 @@ static void ar9003_mci_send_coex_version_query(struct ath_hw *ah, | |||
127 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | 126 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; |
128 | u32 payload[4] = {0, 0, 0, 0}; | 127 | u32 payload[4] = {0, 0, 0, 0}; |
129 | 128 | ||
130 | if (!mci->bt_version_known && | 129 | if (mci->bt_version_known || |
131 | (mci->bt_state != MCI_BT_SLEEP)) { | 130 | (mci->bt_state == MCI_BT_SLEEP)) |
132 | MCI_GPM_SET_TYPE_OPCODE(payload, | 131 | return; |
133 | MCI_GPM_COEX_AGENT, | 132 | |
134 | MCI_GPM_COEX_VERSION_QUERY); | 133 | MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT, |
135 | ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, | 134 | MCI_GPM_COEX_VERSION_QUERY); |
136 | wait_done, true); | 135 | ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, true); |
137 | } | ||
138 | } | 136 | } |
139 | 137 | ||
140 | static void ar9003_mci_send_coex_version_response(struct ath_hw *ah, | 138 | static void ar9003_mci_send_coex_version_response(struct ath_hw *ah, |
@@ -158,15 +156,14 @@ static void ar9003_mci_send_coex_wlan_channels(struct ath_hw *ah, | |||
158 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | 156 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; |
159 | u32 *payload = &mci->wlan_channels[0]; | 157 | u32 *payload = &mci->wlan_channels[0]; |
160 | 158 | ||
161 | if ((mci->wlan_channels_update == true) && | 159 | if (!mci->wlan_channels_update || |
162 | (mci->bt_state != MCI_BT_SLEEP)) { | 160 | (mci->bt_state == MCI_BT_SLEEP)) |
163 | MCI_GPM_SET_TYPE_OPCODE(payload, | 161 | return; |
164 | MCI_GPM_COEX_AGENT, | 162 | |
165 | MCI_GPM_COEX_WLAN_CHANNELS); | 163 | MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT, |
166 | ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, | 164 | MCI_GPM_COEX_WLAN_CHANNELS); |
167 | wait_done, true); | 165 | ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, true); |
168 | MCI_GPM_SET_TYPE_OPCODE(payload, 0xff, 0xff); | 166 | MCI_GPM_SET_TYPE_OPCODE(payload, 0xff, 0xff); |
169 | } | ||
170 | } | 167 | } |
171 | 168 | ||
172 | static void ar9003_mci_send_coex_bt_status_query(struct ath_hw *ah, | 169 | static void ar9003_mci_send_coex_bt_status_query(struct ath_hw *ah, |
@@ -174,29 +171,30 @@ static void ar9003_mci_send_coex_bt_status_query(struct ath_hw *ah, | |||
174 | { | 171 | { |
175 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | 172 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; |
176 | u32 payload[4] = {0, 0, 0, 0}; | 173 | u32 payload[4] = {0, 0, 0, 0}; |
177 | bool query_btinfo = !!(query_type & (MCI_GPM_COEX_QUERY_BT_ALL_INFO | | 174 | bool query_btinfo; |
178 | MCI_GPM_COEX_QUERY_BT_TOPOLOGY)); | ||
179 | 175 | ||
180 | if (mci->bt_state != MCI_BT_SLEEP) { | 176 | if (mci->bt_state == MCI_BT_SLEEP) |
177 | return; | ||
181 | 178 | ||
182 | MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT, | 179 | query_btinfo = !!(query_type & (MCI_GPM_COEX_QUERY_BT_ALL_INFO | |
183 | MCI_GPM_COEX_STATUS_QUERY); | 180 | MCI_GPM_COEX_QUERY_BT_TOPOLOGY)); |
181 | MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT, | ||
182 | MCI_GPM_COEX_STATUS_QUERY); | ||
184 | 183 | ||
185 | *(((u8 *)payload) + MCI_GPM_COEX_B_BT_BITMAP) = query_type; | 184 | *(((u8 *)payload) + MCI_GPM_COEX_B_BT_BITMAP) = query_type; |
186 | |||
187 | /* | ||
188 | * If bt_status_query message is not sent successfully, | ||
189 | * then need_flush_btinfo should be set again. | ||
190 | */ | ||
191 | if (!ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, | ||
192 | wait_done, true)) { | ||
193 | if (query_btinfo) | ||
194 | mci->need_flush_btinfo = true; | ||
195 | } | ||
196 | 185 | ||
186 | /* | ||
187 | * If bt_status_query message is not sent successfully, | ||
188 | * then need_flush_btinfo should be set again. | ||
189 | */ | ||
190 | if (!ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, | ||
191 | wait_done, true)) { | ||
197 | if (query_btinfo) | 192 | if (query_btinfo) |
198 | mci->query_bt = false; | 193 | mci->need_flush_btinfo = true; |
199 | } | 194 | } |
195 | |||
196 | if (query_btinfo) | ||
197 | mci->query_bt = false; | ||
200 | } | 198 | } |
201 | 199 | ||
202 | static void ar9003_mci_send_coex_halt_bt_gpm(struct ath_hw *ah, bool halt, | 200 | static void ar9003_mci_send_coex_halt_bt_gpm(struct ath_hw *ah, bool halt, |
@@ -241,73 +239,73 @@ static void ar9003_mci_prep_interface(struct ath_hw *ah) | |||
241 | ar9003_mci_remote_reset(ah, true); | 239 | ar9003_mci_remote_reset(ah, true); |
242 | ar9003_mci_send_req_wake(ah, true); | 240 | ar9003_mci_send_req_wake(ah, true); |
243 | 241 | ||
244 | if (ar9003_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, | 242 | if (!ar9003_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, |
245 | AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING, 500)) { | 243 | AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING, 500)) |
244 | goto clear_redunt; | ||
246 | 245 | ||
247 | mci->bt_state = MCI_BT_AWAKE; | 246 | mci->bt_state = MCI_BT_AWAKE; |
248 | 247 | ||
249 | /* | 248 | /* |
250 | * we don't need to send more remote_reset at this moment. | 249 | * we don't need to send more remote_reset at this moment. |
251 | * If BT receive first remote_reset, then BT HW will | 250 | * If BT receive first remote_reset, then BT HW will |
252 | * be cleaned up and will be able to receive req_wake | 251 | * be cleaned up and will be able to receive req_wake |
253 | * and BT HW will respond sys_waking. | 252 | * and BT HW will respond sys_waking. |
254 | * In this case, WLAN will receive BT's HW sys_waking. | 253 | * In this case, WLAN will receive BT's HW sys_waking. |
255 | * Otherwise, if BT SW missed initial remote_reset, | 254 | * Otherwise, if BT SW missed initial remote_reset, |
256 | * that remote_reset will still clean up BT MCI RX, | 255 | * that remote_reset will still clean up BT MCI RX, |
257 | * and the req_wake will wake BT up, | 256 | * and the req_wake will wake BT up, |
258 | * and BT SW will respond this req_wake with a remote_reset and | 257 | * and BT SW will respond this req_wake with a remote_reset and |
259 | * sys_waking. In this case, WLAN will receive BT's SW | 258 | * sys_waking. In this case, WLAN will receive BT's SW |
260 | * sys_waking. In either case, BT's RX is cleaned up. So we | 259 | * sys_waking. In either case, BT's RX is cleaned up. So we |
261 | * don't need to reply BT's remote_reset now, if any. | 260 | * don't need to reply BT's remote_reset now, if any. |
262 | * Similarly, if in any case, WLAN can receive BT's sys_waking, | 261 | * Similarly, if in any case, WLAN can receive BT's sys_waking, |
263 | * that means WLAN's RX is also fine. | 262 | * that means WLAN's RX is also fine. |
264 | */ | 263 | */ |
265 | ar9003_mci_send_sys_waking(ah, true); | 264 | ar9003_mci_send_sys_waking(ah, true); |
266 | udelay(10); | 265 | udelay(10); |
267 | 266 | ||
268 | /* | 267 | /* |
269 | * Set BT priority interrupt value to be 0xff to | 268 | * Set BT priority interrupt value to be 0xff to |
270 | * avoid having too many BT PRIORITY interrupts. | 269 | * avoid having too many BT PRIORITY interrupts. |
271 | */ | 270 | */ |
272 | REG_WRITE(ah, AR_MCI_BT_PRI0, 0xFFFFFFFF); | 271 | REG_WRITE(ah, AR_MCI_BT_PRI0, 0xFFFFFFFF); |
273 | REG_WRITE(ah, AR_MCI_BT_PRI1, 0xFFFFFFFF); | 272 | REG_WRITE(ah, AR_MCI_BT_PRI1, 0xFFFFFFFF); |
274 | REG_WRITE(ah, AR_MCI_BT_PRI2, 0xFFFFFFFF); | 273 | REG_WRITE(ah, AR_MCI_BT_PRI2, 0xFFFFFFFF); |
275 | REG_WRITE(ah, AR_MCI_BT_PRI3, 0xFFFFFFFF); | 274 | REG_WRITE(ah, AR_MCI_BT_PRI3, 0xFFFFFFFF); |
276 | REG_WRITE(ah, AR_MCI_BT_PRI, 0X000000FF); | 275 | REG_WRITE(ah, AR_MCI_BT_PRI, 0X000000FF); |
277 | 276 | ||
278 | /* | 277 | /* |
279 | * A contention reset will be received after send out | 278 | * A contention reset will be received after send out |
280 | * sys_waking. Also BT priority interrupt bits will be set. | 279 | * sys_waking. Also BT priority interrupt bits will be set. |
281 | * Clear those bits before the next step. | 280 | * Clear those bits before the next step. |
282 | */ | 281 | */ |
283 | 282 | ||
284 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, | 283 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, |
285 | AR_MCI_INTERRUPT_RX_MSG_CONT_RST); | 284 | AR_MCI_INTERRUPT_RX_MSG_CONT_RST); |
286 | REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, | 285 | REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, AR_MCI_INTERRUPT_BT_PRI); |
287 | AR_MCI_INTERRUPT_BT_PRI); | ||
288 | 286 | ||
289 | if (mci->is_2g) { | 287 | if (mci->is_2g) { |
290 | ar9003_mci_send_lna_transfer(ah, true); | 288 | ar9003_mci_send_lna_transfer(ah, true); |
291 | udelay(5); | 289 | udelay(5); |
292 | } | 290 | } |
293 | 291 | ||
294 | if ((mci->is_2g && !mci->update_2g5g)) { | 292 | if ((mci->is_2g && !mci->update_2g5g)) { |
295 | if (ar9003_mci_wait_for_interrupt(ah, | 293 | if (ar9003_mci_wait_for_interrupt(ah, |
296 | AR_MCI_INTERRUPT_RX_MSG_RAW, | 294 | AR_MCI_INTERRUPT_RX_MSG_RAW, |
297 | AR_MCI_INTERRUPT_RX_MSG_LNA_INFO, | 295 | AR_MCI_INTERRUPT_RX_MSG_LNA_INFO, |
298 | mci_timeout)) | 296 | mci_timeout)) |
299 | ath_dbg(common, MCI, | 297 | ath_dbg(common, MCI, |
300 | "MCI WLAN has control over the LNA & BT obeys it\n"); | 298 | "MCI WLAN has control over the LNA & BT obeys it\n"); |
301 | else | 299 | else |
302 | ath_dbg(common, MCI, | 300 | ath_dbg(common, MCI, |
303 | "MCI BT didn't respond to LNA_TRANS\n"); | 301 | "MCI BT didn't respond to LNA_TRANS\n"); |
304 | } | ||
305 | } | 302 | } |
306 | 303 | ||
304 | clear_redunt: | ||
307 | /* Clear the extra redundant SYS_WAKING from BT */ | 305 | /* Clear the extra redundant SYS_WAKING from BT */ |
308 | if ((mci->bt_state == MCI_BT_AWAKE) && | 306 | if ((mci->bt_state == MCI_BT_AWAKE) && |
309 | (REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, | 307 | (REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, |
310 | AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING)) && | 308 | AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING)) && |
311 | (REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, | 309 | (REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, |
312 | AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) == 0)) { | 310 | AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) == 0)) { |
313 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, | 311 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, |
@@ -323,14 +321,13 @@ void ar9003_mci_set_full_sleep(struct ath_hw *ah) | |||
323 | { | 321 | { |
324 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | 322 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; |
325 | 323 | ||
326 | if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) && | 324 | if (ar9003_mci_state(ah, MCI_STATE_ENABLE) && |
327 | (mci->bt_state != MCI_BT_SLEEP) && | 325 | (mci->bt_state != MCI_BT_SLEEP) && |
328 | !mci->halted_bt_gpm) { | 326 | !mci->halted_bt_gpm) { |
329 | ar9003_mci_send_coex_halt_bt_gpm(ah, true, true); | 327 | ar9003_mci_send_coex_halt_bt_gpm(ah, true, true); |
330 | } | 328 | } |
331 | 329 | ||
332 | mci->ready = false; | 330 | mci->ready = false; |
333 | REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2); | ||
334 | } | 331 | } |
335 | 332 | ||
336 | static void ar9003_mci_disable_interrupt(struct ath_hw *ah) | 333 | static void ar9003_mci_disable_interrupt(struct ath_hw *ah) |
@@ -487,7 +484,7 @@ static void ar9003_mci_sync_bt_state(struct ath_hw *ah) | |||
487 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | 484 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; |
488 | u32 cur_bt_state; | 485 | u32 cur_bt_state; |
489 | 486 | ||
490 | cur_bt_state = ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL); | 487 | cur_bt_state = ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP); |
491 | 488 | ||
492 | if (mci->bt_state != cur_bt_state) | 489 | if (mci->bt_state != cur_bt_state) |
493 | mci->bt_state = cur_bt_state; | 490 | mci->bt_state = cur_bt_state; |
@@ -596,8 +593,7 @@ static u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type, | |||
596 | if (!time_out) | 593 | if (!time_out) |
597 | break; | 594 | break; |
598 | 595 | ||
599 | offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET, | 596 | offset = ar9003_mci_get_next_gpm_offset(ah, false, &more_data); |
600 | &more_data); | ||
601 | 597 | ||
602 | if (offset == MCI_GPM_INVALID) | 598 | if (offset == MCI_GPM_INVALID) |
603 | continue; | 599 | continue; |
@@ -615,9 +611,9 @@ static u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type, | |||
615 | } | 611 | } |
616 | break; | 612 | break; |
617 | } | 613 | } |
618 | } else if ((recv_type == gpm_type) && (recv_opcode == gpm_opcode)) { | 614 | } else if ((recv_type == gpm_type) && |
615 | (recv_opcode == gpm_opcode)) | ||
619 | break; | 616 | break; |
620 | } | ||
621 | 617 | ||
622 | /* | 618 | /* |
623 | * check if it's cal_grant | 619 | * check if it's cal_grant |
@@ -661,8 +657,7 @@ static u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type, | |||
661 | time_out = 0; | 657 | time_out = 0; |
662 | 658 | ||
663 | while (more_data == MCI_GPM_MORE) { | 659 | while (more_data == MCI_GPM_MORE) { |
664 | offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET, | 660 | offset = ar9003_mci_get_next_gpm_offset(ah, false, &more_data); |
665 | &more_data); | ||
666 | if (offset == MCI_GPM_INVALID) | 661 | if (offset == MCI_GPM_INVALID) |
667 | break; | 662 | break; |
668 | 663 | ||
@@ -731,38 +726,38 @@ int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
731 | if (!IS_CHAN_2GHZ(chan) || (mci_hw->bt_state != MCI_BT_SLEEP)) | 726 | if (!IS_CHAN_2GHZ(chan) || (mci_hw->bt_state != MCI_BT_SLEEP)) |
732 | goto exit; | 727 | goto exit; |
733 | 728 | ||
734 | if (ar9003_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET) || | 729 | if (!ar9003_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET) && |
735 | ar9003_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)) { | 730 | !ar9003_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)) |
731 | goto exit; | ||
736 | 732 | ||
737 | /* | 733 | /* |
738 | * BT is sleeping. Check if BT wakes up during | 734 | * BT is sleeping. Check if BT wakes up during |
739 | * WLAN calibration. If BT wakes up during | 735 | * WLAN calibration. If BT wakes up during |
740 | * WLAN calibration, need to go through all | 736 | * WLAN calibration, need to go through all |
741 | * message exchanges again and recal. | 737 | * message exchanges again and recal. |
742 | */ | 738 | */ |
743 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, | 739 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, |
744 | AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET | | 740 | (AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET | |
745 | AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE); | 741 | AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)); |
746 | 742 | ||
747 | ar9003_mci_remote_reset(ah, true); | 743 | ar9003_mci_remote_reset(ah, true); |
748 | ar9003_mci_send_sys_waking(ah, true); | 744 | ar9003_mci_send_sys_waking(ah, true); |
749 | udelay(1); | 745 | udelay(1); |
750 | 746 | ||
751 | if (IS_CHAN_2GHZ(chan)) | 747 | if (IS_CHAN_2GHZ(chan)) |
752 | ar9003_mci_send_lna_transfer(ah, true); | 748 | ar9003_mci_send_lna_transfer(ah, true); |
753 | 749 | ||
754 | mci_hw->bt_state = MCI_BT_AWAKE; | 750 | mci_hw->bt_state = MCI_BT_AWAKE; |
755 | 751 | ||
756 | if (caldata) { | 752 | if (caldata) { |
757 | caldata->done_txiqcal_once = false; | 753 | caldata->done_txiqcal_once = false; |
758 | caldata->done_txclcal_once = false; | 754 | caldata->done_txclcal_once = false; |
759 | caldata->rtt_hist.num_readings = 0; | 755 | caldata->rtt_done = false; |
760 | } | 756 | } |
761 | 757 | ||
762 | if (!ath9k_hw_init_cal(ah, chan)) | 758 | if (!ath9k_hw_init_cal(ah, chan)) |
763 | return -EIO; | 759 | return -EIO; |
764 | 760 | ||
765 | } | ||
766 | exit: | 761 | exit: |
767 | ar9003_mci_enable_interrupt(ah); | 762 | ar9003_mci_enable_interrupt(ah); |
768 | return 0; | 763 | return 0; |
@@ -798,29 +793,27 @@ static void ar9003_mci_osla_setup(struct ath_hw *ah, bool enable) | |||
798 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | 793 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; |
799 | u32 thresh; | 794 | u32 thresh; |
800 | 795 | ||
801 | if (enable) { | 796 | if (!enable) { |
802 | REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, | ||
803 | AR_MCI_SCHD_TABLE_2_HW_BASED, 1); | ||
804 | REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, | ||
805 | AR_MCI_SCHD_TABLE_2_MEM_BASED, 1); | ||
806 | |||
807 | if (!(mci->config & ATH_MCI_CONFIG_DISABLE_AGGR_THRESH)) { | ||
808 | thresh = MS(mci->config, ATH_MCI_CONFIG_AGGR_THRESH); | ||
809 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, | ||
810 | AR_BTCOEX_CTRL_AGGR_THRESH, thresh); | ||
811 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, | ||
812 | AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 1); | ||
813 | } else { | ||
814 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, | ||
815 | AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 0); | ||
816 | } | ||
817 | |||
818 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, | ||
819 | AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN, 1); | ||
820 | } else { | ||
821 | REG_CLR_BIT(ah, AR_BTCOEX_CTRL, | 797 | REG_CLR_BIT(ah, AR_BTCOEX_CTRL, |
822 | AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); | 798 | AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); |
799 | return; | ||
823 | } | 800 | } |
801 | REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, AR_MCI_SCHD_TABLE_2_HW_BASED, 1); | ||
802 | REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, | ||
803 | AR_MCI_SCHD_TABLE_2_MEM_BASED, 1); | ||
804 | |||
805 | if (!(mci->config & ATH_MCI_CONFIG_DISABLE_AGGR_THRESH)) { | ||
806 | thresh = MS(mci->config, ATH_MCI_CONFIG_AGGR_THRESH); | ||
807 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, | ||
808 | AR_BTCOEX_CTRL_AGGR_THRESH, thresh); | ||
809 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, | ||
810 | AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 1); | ||
811 | } else | ||
812 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, | ||
813 | AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 0); | ||
814 | |||
815 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, | ||
816 | AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN, 1); | ||
824 | } | 817 | } |
825 | 818 | ||
826 | void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, | 819 | void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, |
@@ -898,13 +891,16 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, | |||
898 | udelay(100); | 891 | udelay(100); |
899 | } | 892 | } |
900 | 893 | ||
894 | /* Check pending GPM msg before MCI Reset Rx */ | ||
895 | ar9003_mci_check_gpm_offset(ah); | ||
896 | |||
901 | regval |= SM(1, AR_MCI_COMMAND2_RESET_RX); | 897 | regval |= SM(1, AR_MCI_COMMAND2_RESET_RX); |
902 | REG_WRITE(ah, AR_MCI_COMMAND2, regval); | 898 | REG_WRITE(ah, AR_MCI_COMMAND2, regval); |
903 | udelay(1); | 899 | udelay(1); |
904 | regval &= ~SM(1, AR_MCI_COMMAND2_RESET_RX); | 900 | regval &= ~SM(1, AR_MCI_COMMAND2_RESET_RX); |
905 | REG_WRITE(ah, AR_MCI_COMMAND2, regval); | 901 | REG_WRITE(ah, AR_MCI_COMMAND2, regval); |
906 | 902 | ||
907 | ar9003_mci_state(ah, MCI_STATE_INIT_GPM_OFFSET, NULL); | 903 | ar9003_mci_get_next_gpm_offset(ah, true, NULL); |
908 | 904 | ||
909 | REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, | 905 | REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, |
910 | (SM(0xe801, AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR) | | 906 | (SM(0xe801, AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR) | |
@@ -943,26 +939,27 @@ static void ar9003_mci_send_2g5g_status(struct ath_hw *ah, bool wait_done) | |||
943 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | 939 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; |
944 | u32 new_flags, to_set, to_clear; | 940 | u32 new_flags, to_set, to_clear; |
945 | 941 | ||
946 | if (mci->update_2g5g && (mci->bt_state != MCI_BT_SLEEP)) { | 942 | if (!mci->update_2g5g || (mci->bt_state == MCI_BT_SLEEP)) |
947 | if (mci->is_2g) { | 943 | return; |
948 | new_flags = MCI_2G_FLAGS; | 944 | |
949 | to_clear = MCI_2G_FLAGS_CLEAR_MASK; | 945 | if (mci->is_2g) { |
950 | to_set = MCI_2G_FLAGS_SET_MASK; | 946 | new_flags = MCI_2G_FLAGS; |
951 | } else { | 947 | to_clear = MCI_2G_FLAGS_CLEAR_MASK; |
952 | new_flags = MCI_5G_FLAGS; | 948 | to_set = MCI_2G_FLAGS_SET_MASK; |
953 | to_clear = MCI_5G_FLAGS_CLEAR_MASK; | 949 | } else { |
954 | to_set = MCI_5G_FLAGS_SET_MASK; | 950 | new_flags = MCI_5G_FLAGS; |
955 | } | 951 | to_clear = MCI_5G_FLAGS_CLEAR_MASK; |
952 | to_set = MCI_5G_FLAGS_SET_MASK; | ||
953 | } | ||
956 | 954 | ||
957 | if (to_clear) | 955 | if (to_clear) |
958 | ar9003_mci_send_coex_bt_flags(ah, wait_done, | 956 | ar9003_mci_send_coex_bt_flags(ah, wait_done, |
959 | MCI_GPM_COEX_BT_FLAGS_CLEAR, | 957 | MCI_GPM_COEX_BT_FLAGS_CLEAR, |
960 | to_clear); | 958 | to_clear); |
961 | if (to_set) | 959 | if (to_set) |
962 | ar9003_mci_send_coex_bt_flags(ah, wait_done, | 960 | ar9003_mci_send_coex_bt_flags(ah, wait_done, |
963 | MCI_GPM_COEX_BT_FLAGS_SET, | 961 | MCI_GPM_COEX_BT_FLAGS_SET, |
964 | to_set); | 962 | to_set); |
965 | } | ||
966 | } | 963 | } |
967 | 964 | ||
968 | static void ar9003_mci_queue_unsent_gpm(struct ath_hw *ah, u8 header, | 965 | static void ar9003_mci_queue_unsent_gpm(struct ath_hw *ah, u8 header, |
@@ -1014,38 +1011,32 @@ static void ar9003_mci_queue_unsent_gpm(struct ath_hw *ah, u8 header, | |||
1014 | } | 1011 | } |
1015 | } | 1012 | } |
1016 | 1013 | ||
1017 | void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done) | 1014 | void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool force) |
1018 | { | 1015 | { |
1019 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | 1016 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; |
1020 | 1017 | ||
1021 | if (mci->update_2g5g) { | 1018 | if (!mci->update_2g5g && !force) |
1022 | if (mci->is_2g) { | 1019 | return; |
1023 | ar9003_mci_send_2g5g_status(ah, true); | ||
1024 | ar9003_mci_send_lna_transfer(ah, true); | ||
1025 | udelay(5); | ||
1026 | 1020 | ||
1027 | REG_CLR_BIT(ah, AR_MCI_TX_CTRL, | 1021 | if (mci->is_2g) { |
1028 | AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); | 1022 | ar9003_mci_send_2g5g_status(ah, true); |
1029 | REG_CLR_BIT(ah, AR_PHY_GLB_CONTROL, | ||
1030 | AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); | ||
1031 | 1023 | ||
1032 | if (!(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA)) { | 1024 | REG_SET_BIT(ah, AR_MCI_TX_CTRL, |
1033 | REG_SET_BIT(ah, AR_BTCOEX_CTRL, | 1025 | AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); |
1034 | AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); | 1026 | REG_CLR_BIT(ah, AR_PHY_GLB_CONTROL, |
1035 | } | 1027 | AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); |
1036 | } else { | ||
1037 | ar9003_mci_send_lna_take(ah, true); | ||
1038 | udelay(5); | ||
1039 | 1028 | ||
1040 | REG_SET_BIT(ah, AR_MCI_TX_CTRL, | 1029 | if (!(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA)) |
1041 | AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); | 1030 | ar9003_mci_osla_setup(ah, true); |
1042 | REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, | 1031 | } else { |
1043 | AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); | 1032 | REG_SET_BIT(ah, AR_MCI_TX_CTRL, |
1044 | REG_CLR_BIT(ah, AR_BTCOEX_CTRL, | 1033 | AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); |
1045 | AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); | 1034 | REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, |
1035 | AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); | ||
1046 | 1036 | ||
1037 | ar9003_mci_osla_setup(ah, false); | ||
1038 | if (!force) | ||
1047 | ar9003_mci_send_2g5g_status(ah, true); | 1039 | ar9003_mci_send_2g5g_status(ah, true); |
1048 | } | ||
1049 | } | 1040 | } |
1050 | } | 1041 | } |
1051 | 1042 | ||
@@ -1132,7 +1123,7 @@ void ar9003_mci_init_cal_req(struct ath_hw *ah, bool *is_reusable) | |||
1132 | if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_GRANT, 0, 50000)) { | 1123 | if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_GRANT, 0, 50000)) { |
1133 | ath_dbg(common, MCI, "MCI BT_CAL_GRANT received\n"); | 1124 | ath_dbg(common, MCI, "MCI BT_CAL_GRANT received\n"); |
1134 | } else { | 1125 | } else { |
1135 | is_reusable = false; | 1126 | *is_reusable = false; |
1136 | ath_dbg(common, MCI, "MCI BT_CAL_GRANT not received\n"); | 1127 | ath_dbg(common, MCI, "MCI BT_CAL_GRANT not received\n"); |
1137 | } | 1128 | } |
1138 | } | 1129 | } |
@@ -1173,11 +1164,10 @@ void ar9003_mci_cleanup(struct ath_hw *ah) | |||
1173 | } | 1164 | } |
1174 | EXPORT_SYMBOL(ar9003_mci_cleanup); | 1165 | EXPORT_SYMBOL(ar9003_mci_cleanup); |
1175 | 1166 | ||
1176 | u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) | 1167 | u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type) |
1177 | { | 1168 | { |
1178 | struct ath_common *common = ath9k_hw_common(ah); | ||
1179 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | 1169 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; |
1180 | u32 value = 0, more_gpm = 0, gpm_ptr; | 1170 | u32 value = 0; |
1181 | u8 query_type; | 1171 | u8 query_type; |
1182 | 1172 | ||
1183 | switch (state_type) { | 1173 | switch (state_type) { |
@@ -1190,81 +1180,6 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) | |||
1190 | } | 1180 | } |
1191 | value &= AR_BTCOEX_CTRL_MCI_MODE_EN; | 1181 | value &= AR_BTCOEX_CTRL_MCI_MODE_EN; |
1192 | break; | 1182 | break; |
1193 | case MCI_STATE_INIT_GPM_OFFSET: | ||
1194 | value = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); | ||
1195 | mci->gpm_idx = value; | ||
1196 | break; | ||
1197 | case MCI_STATE_NEXT_GPM_OFFSET: | ||
1198 | case MCI_STATE_LAST_GPM_OFFSET: | ||
1199 | /* | ||
1200 | * This could be useful to avoid new GPM message interrupt which | ||
1201 | * may lead to spurious interrupt after power sleep, or multiple | ||
1202 | * entry of ath_mci_intr(). | ||
1203 | * Adding empty GPM check by returning HAL_MCI_GPM_INVALID can | ||
1204 | * alleviate this effect, but clearing GPM RX interrupt bit is | ||
1205 | * safe, because whether this is called from hw or driver code | ||
1206 | * there must be an interrupt bit set/triggered initially | ||
1207 | */ | ||
1208 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, | ||
1209 | AR_MCI_INTERRUPT_RX_MSG_GPM); | ||
1210 | |||
1211 | gpm_ptr = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); | ||
1212 | value = gpm_ptr; | ||
1213 | |||
1214 | if (value == 0) | ||
1215 | value = mci->gpm_len - 1; | ||
1216 | else if (value >= mci->gpm_len) { | ||
1217 | if (value != 0xFFFF) | ||
1218 | value = 0; | ||
1219 | } else { | ||
1220 | value--; | ||
1221 | } | ||
1222 | |||
1223 | if (value == 0xFFFF) { | ||
1224 | value = MCI_GPM_INVALID; | ||
1225 | more_gpm = MCI_GPM_NOMORE; | ||
1226 | } else if (state_type == MCI_STATE_NEXT_GPM_OFFSET) { | ||
1227 | if (gpm_ptr == mci->gpm_idx) { | ||
1228 | value = MCI_GPM_INVALID; | ||
1229 | more_gpm = MCI_GPM_NOMORE; | ||
1230 | } else { | ||
1231 | for (;;) { | ||
1232 | u32 temp_index; | ||
1233 | |||
1234 | /* skip reserved GPM if any */ | ||
1235 | |||
1236 | if (value != mci->gpm_idx) | ||
1237 | more_gpm = MCI_GPM_MORE; | ||
1238 | else | ||
1239 | more_gpm = MCI_GPM_NOMORE; | ||
1240 | |||
1241 | temp_index = mci->gpm_idx; | ||
1242 | mci->gpm_idx++; | ||
1243 | |||
1244 | if (mci->gpm_idx >= | ||
1245 | mci->gpm_len) | ||
1246 | mci->gpm_idx = 0; | ||
1247 | |||
1248 | if (ar9003_mci_is_gpm_valid(ah, | ||
1249 | temp_index)) { | ||
1250 | value = temp_index; | ||
1251 | break; | ||
1252 | } | ||
1253 | |||
1254 | if (more_gpm == MCI_GPM_NOMORE) { | ||
1255 | value = MCI_GPM_INVALID; | ||
1256 | break; | ||
1257 | } | ||
1258 | } | ||
1259 | } | ||
1260 | if (p_data) | ||
1261 | *p_data = more_gpm; | ||
1262 | } | ||
1263 | |||
1264 | if (value != MCI_GPM_INVALID) | ||
1265 | value <<= 4; | ||
1266 | |||
1267 | break; | ||
1268 | case MCI_STATE_LAST_SCHD_MSG_OFFSET: | 1183 | case MCI_STATE_LAST_SCHD_MSG_OFFSET: |
1269 | value = MS(REG_READ(ah, AR_MCI_RX_STATUS), | 1184 | value = MS(REG_READ(ah, AR_MCI_RX_STATUS), |
1270 | AR_MCI_RX_LAST_SCHD_MSG_INDEX); | 1185 | AR_MCI_RX_LAST_SCHD_MSG_INDEX); |
@@ -1276,21 +1191,6 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) | |||
1276 | AR_MCI_RX_REMOTE_SLEEP) ? | 1191 | AR_MCI_RX_REMOTE_SLEEP) ? |
1277 | MCI_BT_SLEEP : MCI_BT_AWAKE; | 1192 | MCI_BT_SLEEP : MCI_BT_AWAKE; |
1278 | break; | 1193 | break; |
1279 | case MCI_STATE_CONT_RSSI_POWER: | ||
1280 | value = MS(mci->cont_status, AR_MCI_CONT_RSSI_POWER); | ||
1281 | break; | ||
1282 | case MCI_STATE_CONT_PRIORITY: | ||
1283 | value = MS(mci->cont_status, AR_MCI_CONT_RRIORITY); | ||
1284 | break; | ||
1285 | case MCI_STATE_CONT_TXRX: | ||
1286 | value = MS(mci->cont_status, AR_MCI_CONT_TXRX); | ||
1287 | break; | ||
1288 | case MCI_STATE_BT: | ||
1289 | value = mci->bt_state; | ||
1290 | break; | ||
1291 | case MCI_STATE_SET_BT_SLEEP: | ||
1292 | mci->bt_state = MCI_BT_SLEEP; | ||
1293 | break; | ||
1294 | case MCI_STATE_SET_BT_AWAKE: | 1194 | case MCI_STATE_SET_BT_AWAKE: |
1295 | mci->bt_state = MCI_BT_AWAKE; | 1195 | mci->bt_state = MCI_BT_AWAKE; |
1296 | ar9003_mci_send_coex_version_query(ah, true); | 1196 | ar9003_mci_send_coex_version_query(ah, true); |
@@ -1299,7 +1199,7 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) | |||
1299 | if (mci->unhalt_bt_gpm) | 1199 | if (mci->unhalt_bt_gpm) |
1300 | ar9003_mci_send_coex_halt_bt_gpm(ah, false, true); | 1200 | ar9003_mci_send_coex_halt_bt_gpm(ah, false, true); |
1301 | 1201 | ||
1302 | ar9003_mci_2g5g_switch(ah, true); | 1202 | ar9003_mci_2g5g_switch(ah, false); |
1303 | break; | 1203 | break; |
1304 | case MCI_STATE_SET_BT_CAL_START: | 1204 | case MCI_STATE_SET_BT_CAL_START: |
1305 | mci->bt_state = MCI_BT_CAL_START; | 1205 | mci->bt_state = MCI_BT_CAL_START; |
@@ -1323,34 +1223,6 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) | |||
1323 | case MCI_STATE_SEND_WLAN_COEX_VERSION: | 1223 | case MCI_STATE_SEND_WLAN_COEX_VERSION: |
1324 | ar9003_mci_send_coex_version_response(ah, true); | 1224 | ar9003_mci_send_coex_version_response(ah, true); |
1325 | break; | 1225 | break; |
1326 | case MCI_STATE_SET_BT_COEX_VERSION: | ||
1327 | if (!p_data) | ||
1328 | ath_dbg(common, MCI, | ||
1329 | "MCI Set BT Coex version with NULL data!!\n"); | ||
1330 | else { | ||
1331 | mci->bt_ver_major = (*p_data >> 8) & 0xff; | ||
1332 | mci->bt_ver_minor = (*p_data) & 0xff; | ||
1333 | mci->bt_version_known = true; | ||
1334 | ath_dbg(common, MCI, "MCI BT version set: %d.%d\n", | ||
1335 | mci->bt_ver_major, mci->bt_ver_minor); | ||
1336 | } | ||
1337 | break; | ||
1338 | case MCI_STATE_SEND_WLAN_CHANNELS: | ||
1339 | if (p_data) { | ||
1340 | if (((mci->wlan_channels[1] & 0xffff0000) == | ||
1341 | (*(p_data + 1) & 0xffff0000)) && | ||
1342 | (mci->wlan_channels[2] == *(p_data + 2)) && | ||
1343 | (mci->wlan_channels[3] == *(p_data + 3))) | ||
1344 | break; | ||
1345 | |||
1346 | mci->wlan_channels[0] = *p_data++; | ||
1347 | mci->wlan_channels[1] = *p_data++; | ||
1348 | mci->wlan_channels[2] = *p_data++; | ||
1349 | mci->wlan_channels[3] = *p_data++; | ||
1350 | } | ||
1351 | mci->wlan_channels_update = true; | ||
1352 | ar9003_mci_send_coex_wlan_channels(ah, true); | ||
1353 | break; | ||
1354 | case MCI_STATE_SEND_VERSION_QUERY: | 1226 | case MCI_STATE_SEND_VERSION_QUERY: |
1355 | ar9003_mci_send_coex_version_query(ah, true); | 1227 | ar9003_mci_send_coex_version_query(ah, true); |
1356 | break; | 1228 | break; |
@@ -1358,38 +1230,16 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) | |||
1358 | query_type = MCI_GPM_COEX_QUERY_BT_TOPOLOGY; | 1230 | query_type = MCI_GPM_COEX_QUERY_BT_TOPOLOGY; |
1359 | ar9003_mci_send_coex_bt_status_query(ah, true, query_type); | 1231 | ar9003_mci_send_coex_bt_status_query(ah, true, query_type); |
1360 | break; | 1232 | break; |
1361 | case MCI_STATE_NEED_FLUSH_BT_INFO: | ||
1362 | /* | ||
1363 | * btcoex_hw.mci.unhalt_bt_gpm means whether it's | ||
1364 | * needed to send UNHALT message. It's set whenever | ||
1365 | * there's a request to send HALT message. | ||
1366 | * mci_halted_bt_gpm means whether HALT message is sent | ||
1367 | * out successfully. | ||
1368 | * | ||
1369 | * Checking (mci_unhalt_bt_gpm == false) instead of | ||
1370 | * checking (ah->mci_halted_bt_gpm == false) will make | ||
1371 | * sure currently is in UNHALT-ed mode and BT can | ||
1372 | * respond to status query. | ||
1373 | */ | ||
1374 | value = (!mci->unhalt_bt_gpm && | ||
1375 | mci->need_flush_btinfo) ? 1 : 0; | ||
1376 | if (p_data) | ||
1377 | mci->need_flush_btinfo = | ||
1378 | (*p_data != 0) ? true : false; | ||
1379 | break; | ||
1380 | case MCI_STATE_RECOVER_RX: | 1233 | case MCI_STATE_RECOVER_RX: |
1381 | ar9003_mci_prep_interface(ah); | 1234 | ar9003_mci_prep_interface(ah); |
1382 | mci->query_bt = true; | 1235 | mci->query_bt = true; |
1383 | mci->need_flush_btinfo = true; | 1236 | mci->need_flush_btinfo = true; |
1384 | ar9003_mci_send_coex_wlan_channels(ah, true); | 1237 | ar9003_mci_send_coex_wlan_channels(ah, true); |
1385 | ar9003_mci_2g5g_switch(ah, true); | 1238 | ar9003_mci_2g5g_switch(ah, false); |
1386 | break; | 1239 | break; |
1387 | case MCI_STATE_NEED_FTP_STOMP: | 1240 | case MCI_STATE_NEED_FTP_STOMP: |
1388 | value = !(mci->config & ATH_MCI_CONFIG_DISABLE_FTP_STOMP); | 1241 | value = !(mci->config & ATH_MCI_CONFIG_DISABLE_FTP_STOMP); |
1389 | break; | 1242 | break; |
1390 | case MCI_STATE_NEED_TUNING: | ||
1391 | value = !(mci->config & ATH_MCI_CONFIG_DISABLE_TUNING); | ||
1392 | break; | ||
1393 | default: | 1243 | default: |
1394 | break; | 1244 | break; |
1395 | } | 1245 | } |
@@ -1397,3 +1247,170 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) | |||
1397 | return value; | 1247 | return value; |
1398 | } | 1248 | } |
1399 | EXPORT_SYMBOL(ar9003_mci_state); | 1249 | EXPORT_SYMBOL(ar9003_mci_state); |
1250 | |||
1251 | void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah) | ||
1252 | { | ||
1253 | struct ath_common *common = ath9k_hw_common(ah); | ||
1254 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | ||
1255 | |||
1256 | ath_dbg(common, MCI, "Give LNA and SPDT control to BT\n"); | ||
1257 | |||
1258 | REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); | ||
1259 | mci->is_2g = false; | ||
1260 | mci->update_2g5g = true; | ||
1261 | ar9003_mci_send_2g5g_status(ah, true); | ||
1262 | |||
1263 | /* Force another 2g5g update at next scanning */ | ||
1264 | mci->update_2g5g = true; | ||
1265 | } | ||
1266 | |||
1267 | void ar9003_mci_set_power_awake(struct ath_hw *ah) | ||
1268 | { | ||
1269 | u32 btcoex_ctrl2, diag_sw; | ||
1270 | int i; | ||
1271 | u8 lna_ctrl, bt_sleep; | ||
1272 | |||
1273 | for (i = 0; i < AH_WAIT_TIMEOUT; i++) { | ||
1274 | btcoex_ctrl2 = REG_READ(ah, AR_BTCOEX_CTRL2); | ||
1275 | if (btcoex_ctrl2 != 0xdeadbeef) | ||
1276 | break; | ||
1277 | udelay(AH_TIME_QUANTUM); | ||
1278 | } | ||
1279 | REG_WRITE(ah, AR_BTCOEX_CTRL2, (btcoex_ctrl2 | BIT(23))); | ||
1280 | |||
1281 | for (i = 0; i < AH_WAIT_TIMEOUT; i++) { | ||
1282 | diag_sw = REG_READ(ah, AR_DIAG_SW); | ||
1283 | if (diag_sw != 0xdeadbeef) | ||
1284 | break; | ||
1285 | udelay(AH_TIME_QUANTUM); | ||
1286 | } | ||
1287 | REG_WRITE(ah, AR_DIAG_SW, (diag_sw | BIT(27) | BIT(19) | BIT(18))); | ||
1288 | lna_ctrl = REG_READ(ah, AR_OBS_BUS_CTRL) & 0x3; | ||
1289 | bt_sleep = REG_READ(ah, AR_MCI_RX_STATUS) & AR_MCI_RX_REMOTE_SLEEP; | ||
1290 | |||
1291 | REG_WRITE(ah, AR_BTCOEX_CTRL2, btcoex_ctrl2); | ||
1292 | REG_WRITE(ah, AR_DIAG_SW, diag_sw); | ||
1293 | |||
1294 | if (bt_sleep && (lna_ctrl == 2)) { | ||
1295 | REG_SET_BIT(ah, AR_BTCOEX_RC, 0x1); | ||
1296 | REG_CLR_BIT(ah, AR_BTCOEX_RC, 0x1); | ||
1297 | udelay(50); | ||
1298 | } | ||
1299 | } | ||
1300 | |||
1301 | void ar9003_mci_check_gpm_offset(struct ath_hw *ah) | ||
1302 | { | ||
1303 | struct ath_common *common = ath9k_hw_common(ah); | ||
1304 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | ||
1305 | u32 offset; | ||
1306 | |||
1307 | /* | ||
1308 | * This should only be called before "MAC Warm Reset" or "MCI Reset Rx". | ||
1309 | */ | ||
1310 | offset = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); | ||
1311 | if (mci->gpm_idx == offset) | ||
1312 | return; | ||
1313 | ath_dbg(common, MCI, "GPM cached write pointer mismatch %d %d\n", | ||
1314 | mci->gpm_idx, offset); | ||
1315 | mci->query_bt = true; | ||
1316 | mci->need_flush_btinfo = true; | ||
1317 | mci->gpm_idx = 0; | ||
1318 | } | ||
1319 | |||
1320 | u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, bool first, u32 *more) | ||
1321 | { | ||
1322 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | ||
1323 | u32 offset, more_gpm = 0, gpm_ptr; | ||
1324 | |||
1325 | if (first) { | ||
1326 | gpm_ptr = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); | ||
1327 | mci->gpm_idx = gpm_ptr; | ||
1328 | return gpm_ptr; | ||
1329 | } | ||
1330 | |||
1331 | /* | ||
1332 | * This could be useful to avoid new GPM message interrupt which | ||
1333 | * may lead to spurious interrupt after power sleep, or multiple | ||
1334 | * entry of ath_mci_intr(). | ||
1335 | * Adding empty GPM check by returning HAL_MCI_GPM_INVALID can | ||
1336 | * alleviate this effect, but clearing GPM RX interrupt bit is | ||
1337 | * safe, because whether this is called from hw or driver code | ||
1338 | * there must be an interrupt bit set/triggered initially | ||
1339 | */ | ||
1340 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, | ||
1341 | AR_MCI_INTERRUPT_RX_MSG_GPM); | ||
1342 | |||
1343 | gpm_ptr = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); | ||
1344 | offset = gpm_ptr; | ||
1345 | |||
1346 | if (!offset) | ||
1347 | offset = mci->gpm_len - 1; | ||
1348 | else if (offset >= mci->gpm_len) { | ||
1349 | if (offset != 0xFFFF) | ||
1350 | offset = 0; | ||
1351 | } else { | ||
1352 | offset--; | ||
1353 | } | ||
1354 | |||
1355 | if ((offset == 0xFFFF) || (gpm_ptr == mci->gpm_idx)) { | ||
1356 | offset = MCI_GPM_INVALID; | ||
1357 | more_gpm = MCI_GPM_NOMORE; | ||
1358 | goto out; | ||
1359 | } | ||
1360 | for (;;) { | ||
1361 | u32 temp_index; | ||
1362 | |||
1363 | /* skip reserved GPM if any */ | ||
1364 | |||
1365 | if (offset != mci->gpm_idx) | ||
1366 | more_gpm = MCI_GPM_MORE; | ||
1367 | else | ||
1368 | more_gpm = MCI_GPM_NOMORE; | ||
1369 | |||
1370 | temp_index = mci->gpm_idx; | ||
1371 | mci->gpm_idx++; | ||
1372 | |||
1373 | if (mci->gpm_idx >= mci->gpm_len) | ||
1374 | mci->gpm_idx = 0; | ||
1375 | |||
1376 | if (ar9003_mci_is_gpm_valid(ah, temp_index)) { | ||
1377 | offset = temp_index; | ||
1378 | break; | ||
1379 | } | ||
1380 | |||
1381 | if (more_gpm == MCI_GPM_NOMORE) { | ||
1382 | offset = MCI_GPM_INVALID; | ||
1383 | break; | ||
1384 | } | ||
1385 | } | ||
1386 | |||
1387 | if (offset != MCI_GPM_INVALID) | ||
1388 | offset <<= 4; | ||
1389 | out: | ||
1390 | if (more) | ||
1391 | *more = more_gpm; | ||
1392 | |||
1393 | return offset; | ||
1394 | } | ||
1395 | EXPORT_SYMBOL(ar9003_mci_get_next_gpm_offset); | ||
1396 | |||
1397 | void ar9003_mci_set_bt_version(struct ath_hw *ah, u8 major, u8 minor) | ||
1398 | { | ||
1399 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | ||
1400 | |||
1401 | mci->bt_ver_major = major; | ||
1402 | mci->bt_ver_minor = minor; | ||
1403 | mci->bt_version_known = true; | ||
1404 | ath_dbg(ath9k_hw_common(ah), MCI, "MCI BT version set: %d.%d\n", | ||
1405 | mci->bt_ver_major, mci->bt_ver_minor); | ||
1406 | } | ||
1407 | EXPORT_SYMBOL(ar9003_mci_set_bt_version); | ||
1408 | |||
1409 | void ar9003_mci_send_wlan_channels(struct ath_hw *ah) | ||
1410 | { | ||
1411 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | ||
1412 | |||
1413 | mci->wlan_channels_update = true; | ||
1414 | ar9003_mci_send_coex_wlan_channels(ah, true); | ||
1415 | } | ||
1416 | EXPORT_SYMBOL(ar9003_mci_send_wlan_channels); | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h index 4842f6c06b8c..d33b8e128855 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h | |||
@@ -189,30 +189,18 @@ enum mci_bt_state { | |||
189 | /* Type of state query */ | 189 | /* Type of state query */ |
190 | enum mci_state_type { | 190 | enum mci_state_type { |
191 | MCI_STATE_ENABLE, | 191 | MCI_STATE_ENABLE, |
192 | MCI_STATE_INIT_GPM_OFFSET, | ||
193 | MCI_STATE_NEXT_GPM_OFFSET, | ||
194 | MCI_STATE_LAST_GPM_OFFSET, | ||
195 | MCI_STATE_BT, | ||
196 | MCI_STATE_SET_BT_SLEEP, | ||
197 | MCI_STATE_SET_BT_AWAKE, | 192 | MCI_STATE_SET_BT_AWAKE, |
198 | MCI_STATE_SET_BT_CAL_START, | 193 | MCI_STATE_SET_BT_CAL_START, |
199 | MCI_STATE_SET_BT_CAL, | 194 | MCI_STATE_SET_BT_CAL, |
200 | MCI_STATE_LAST_SCHD_MSG_OFFSET, | 195 | MCI_STATE_LAST_SCHD_MSG_OFFSET, |
201 | MCI_STATE_REMOTE_SLEEP, | 196 | MCI_STATE_REMOTE_SLEEP, |
202 | MCI_STATE_CONT_RSSI_POWER, | ||
203 | MCI_STATE_CONT_PRIORITY, | ||
204 | MCI_STATE_CONT_TXRX, | ||
205 | MCI_STATE_RESET_REQ_WAKE, | 197 | MCI_STATE_RESET_REQ_WAKE, |
206 | MCI_STATE_SEND_WLAN_COEX_VERSION, | 198 | MCI_STATE_SEND_WLAN_COEX_VERSION, |
207 | MCI_STATE_SET_BT_COEX_VERSION, | ||
208 | MCI_STATE_SEND_WLAN_CHANNELS, | ||
209 | MCI_STATE_SEND_VERSION_QUERY, | 199 | MCI_STATE_SEND_VERSION_QUERY, |
210 | MCI_STATE_SEND_STATUS_QUERY, | 200 | MCI_STATE_SEND_STATUS_QUERY, |
211 | MCI_STATE_NEED_FLUSH_BT_INFO, | ||
212 | MCI_STATE_SET_CONCUR_TX_PRI, | 201 | MCI_STATE_SET_CONCUR_TX_PRI, |
213 | MCI_STATE_RECOVER_RX, | 202 | MCI_STATE_RECOVER_RX, |
214 | MCI_STATE_NEED_FTP_STOMP, | 203 | MCI_STATE_NEED_FTP_STOMP, |
215 | MCI_STATE_NEED_TUNING, | ||
216 | MCI_STATE_DEBUG, | 204 | MCI_STATE_DEBUG, |
217 | MCI_STATE_MAX | 205 | MCI_STATE_MAX |
218 | }; | 206 | }; |
@@ -260,28 +248,26 @@ enum mci_gpm_coex_opcode { | |||
260 | bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag, | 248 | bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag, |
261 | u32 *payload, u8 len, bool wait_done, | 249 | u32 *payload, u8 len, bool wait_done, |
262 | bool check_bt); | 250 | bool check_bt); |
263 | u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data); | 251 | u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type); |
264 | void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, | 252 | void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, |
265 | u16 len, u32 sched_addr); | 253 | u16 len, u32 sched_addr); |
266 | void ar9003_mci_cleanup(struct ath_hw *ah); | 254 | void ar9003_mci_cleanup(struct ath_hw *ah); |
267 | void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, | 255 | void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, |
268 | u32 *rx_msg_intr); | 256 | u32 *rx_msg_intr); |
269 | 257 | u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, bool first, u32 *more); | |
258 | void ar9003_mci_set_bt_version(struct ath_hw *ah, u8 major, u8 minor); | ||
259 | void ar9003_mci_send_wlan_channels(struct ath_hw *ah); | ||
270 | /* | 260 | /* |
271 | * These functions are used by ath9k_hw. | 261 | * These functions are used by ath9k_hw. |
272 | */ | 262 | */ |
273 | 263 | ||
274 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT | 264 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT |
275 | 265 | ||
276 | static inline bool ar9003_mci_is_ready(struct ath_hw *ah) | ||
277 | { | ||
278 | return ah->btcoex_hw.mci.ready; | ||
279 | } | ||
280 | void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep); | 266 | void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep); |
281 | void ar9003_mci_init_cal_req(struct ath_hw *ah, bool *is_reusable); | 267 | void ar9003_mci_init_cal_req(struct ath_hw *ah, bool *is_reusable); |
282 | void ar9003_mci_init_cal_done(struct ath_hw *ah); | 268 | void ar9003_mci_init_cal_done(struct ath_hw *ah); |
283 | void ar9003_mci_set_full_sleep(struct ath_hw *ah); | 269 | void ar9003_mci_set_full_sleep(struct ath_hw *ah); |
284 | void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done); | 270 | void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool force); |
285 | void ar9003_mci_check_bt(struct ath_hw *ah); | 271 | void ar9003_mci_check_bt(struct ath_hw *ah); |
286 | bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan); | 272 | bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan); |
287 | int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, | 273 | int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, |
@@ -289,13 +275,12 @@ int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
289 | void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, | 275 | void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, |
290 | bool is_full_sleep); | 276 | bool is_full_sleep); |
291 | void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked); | 277 | void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked); |
278 | void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah); | ||
279 | void ar9003_mci_set_power_awake(struct ath_hw *ah); | ||
280 | void ar9003_mci_check_gpm_offset(struct ath_hw *ah); | ||
292 | 281 | ||
293 | #else | 282 | #else |
294 | 283 | ||
295 | static inline bool ar9003_mci_is_ready(struct ath_hw *ah) | ||
296 | { | ||
297 | return false; | ||
298 | } | ||
299 | static inline void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep) | 284 | static inline void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep) |
300 | { | 285 | { |
301 | } | 286 | } |
@@ -330,6 +315,15 @@ static inline void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, | |||
330 | static inline void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked) | 315 | static inline void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked) |
331 | { | 316 | { |
332 | } | 317 | } |
318 | static inline void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah) | ||
319 | { | ||
320 | } | ||
321 | static inline void ar9003_mci_set_power_awake(struct ath_hw *ah) | ||
322 | { | ||
323 | } | ||
324 | static inline void ar9003_mci_check_gpm_offset(struct ath_hw *ah) | ||
325 | { | ||
326 | } | ||
333 | #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ | 327 | #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ |
334 | 328 | ||
335 | #endif | 329 | #endif |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 59647a3ceb7f..3d400e8d6535 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c | |||
@@ -54,7 +54,7 @@ void ar9003_paprd_enable(struct ath_hw *ah, bool val) | |||
54 | 54 | ||
55 | if (val) { | 55 | if (val) { |
56 | ah->paprd_table_write_done = true; | 56 | ah->paprd_table_write_done = true; |
57 | ath9k_hw_apply_txpower(ah, chan); | 57 | ath9k_hw_apply_txpower(ah, chan, false); |
58 | } | 58 | } |
59 | 59 | ||
60 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0, | 60 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 79070bf04eab..d6baf69cdc14 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -152,7 +152,6 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | |||
152 | REG_WRITE(ah, AR_PHY_65NM_CH0_SYNTH7, reg32); | 152 | REG_WRITE(ah, AR_PHY_65NM_CH0_SYNTH7, reg32); |
153 | 153 | ||
154 | ah->curchan = chan; | 154 | ah->curchan = chan; |
155 | ah->curchan_rad_index = -1; | ||
156 | 155 | ||
157 | return 0; | 156 | return 0; |
158 | } | 157 | } |
@@ -209,11 +208,12 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, | |||
209 | continue; | 208 | continue; |
210 | negative = 0; | 209 | negative = 0; |
211 | if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah)) | 210 | if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah)) |
212 | cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i], | 211 | cur_bb_spur = ath9k_hw_fbin2freq(spur_fbin_ptr[i], |
213 | IS_CHAN_2GHZ(chan)) - synth_freq; | 212 | IS_CHAN_2GHZ(chan)); |
214 | else | 213 | else |
215 | cur_bb_spur = spur_freq[i] - synth_freq; | 214 | cur_bb_spur = spur_freq[i]; |
216 | 215 | ||
216 | cur_bb_spur -= synth_freq; | ||
217 | if (cur_bb_spur < 0) { | 217 | if (cur_bb_spur < 0) { |
218 | negative = 1; | 218 | negative = 1; |
219 | cur_bb_spur = -cur_bb_spur; | 219 | cur_bb_spur = -cur_bb_spur; |
@@ -373,7 +373,7 @@ static void ar9003_hw_spur_ofdm_work(struct ath_hw *ah, | |||
373 | else | 373 | else |
374 | spur_subchannel_sd = 0; | 374 | spur_subchannel_sd = 0; |
375 | 375 | ||
376 | spur_freq_sd = (freq_offset << 9) / 11; | 376 | spur_freq_sd = ((freq_offset + 10) << 9) / 11; |
377 | 377 | ||
378 | } else { | 378 | } else { |
379 | if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL, | 379 | if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL, |
@@ -382,7 +382,7 @@ static void ar9003_hw_spur_ofdm_work(struct ath_hw *ah, | |||
382 | else | 382 | else |
383 | spur_subchannel_sd = 1; | 383 | spur_subchannel_sd = 1; |
384 | 384 | ||
385 | spur_freq_sd = (freq_offset << 9) / 11; | 385 | spur_freq_sd = ((freq_offset - 10) << 9) / 11; |
386 | 386 | ||
387 | } | 387 | } |
388 | 388 | ||
@@ -443,7 +443,8 @@ static void ar9003_hw_spur_mitigate_ofdm(struct ath_hw *ah, | |||
443 | ar9003_hw_spur_ofdm_clear(ah); | 443 | ar9003_hw_spur_ofdm_clear(ah); |
444 | 444 | ||
445 | for (i = 0; i < AR_EEPROM_MODAL_SPURS && spurChansPtr[i]; i++) { | 445 | for (i = 0; i < AR_EEPROM_MODAL_SPURS && spurChansPtr[i]; i++) { |
446 | freq_offset = FBIN2FREQ(spurChansPtr[i], mode) - synth_freq; | 446 | freq_offset = ath9k_hw_fbin2freq(spurChansPtr[i], mode); |
447 | freq_offset -= synth_freq; | ||
447 | if (abs(freq_offset) < range) { | 448 | if (abs(freq_offset) < range) { |
448 | ar9003_hw_spur_ofdm_work(ah, chan, freq_offset); | 449 | ar9003_hw_spur_ofdm_work(ah, chan, freq_offset); |
449 | break; | 450 | break; |
@@ -525,22 +526,10 @@ static void ar9003_hw_init_bb(struct ath_hw *ah, | |||
525 | * Value is in 100ns increments. | 526 | * Value is in 100ns increments. |
526 | */ | 527 | */ |
527 | synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; | 528 | synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; |
528 | if (IS_CHAN_B(chan)) | ||
529 | synthDelay = (4 * synthDelay) / 22; | ||
530 | else | ||
531 | synthDelay /= 10; | ||
532 | 529 | ||
533 | /* Activate the PHY (includes baseband activate + synthesizer on) */ | 530 | /* Activate the PHY (includes baseband activate + synthesizer on) */ |
534 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); | 531 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); |
535 | 532 | ath9k_hw_synth_delay(ah, chan, synthDelay); | |
536 | /* | ||
537 | * There is an issue if the AP starts the calibration before | ||
538 | * the base band timeout completes. This could result in the | ||
539 | * rx_clear false triggering. As a workaround we add delay an | ||
540 | * extra BASE_ACTIVATE_DELAY usecs to ensure this condition | ||
541 | * does not happen. | ||
542 | */ | ||
543 | udelay(synthDelay + BASE_ACTIVATE_DELAY); | ||
544 | } | 533 | } |
545 | 534 | ||
546 | static void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx) | 535 | static void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx) |
@@ -684,17 +673,18 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, | |||
684 | 673 | ||
685 | REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites); | 674 | REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites); |
686 | 675 | ||
687 | if (AR_SREV_9462(ah)) | ||
688 | ar9003_hw_prog_ini(ah, &ah->ini_BTCOEX_MAX_TXPWR, 1); | ||
689 | |||
690 | if (chan->channel == 2484) | 676 | if (chan->channel == 2484) |
691 | ar9003_hw_prog_ini(ah, &ah->ini_japan2484, 1); | 677 | ar9003_hw_prog_ini(ah, &ah->ini_japan2484, 1); |
692 | 678 | ||
679 | if (AR_SREV_9462(ah)) | ||
680 | REG_WRITE(ah, AR_GLB_SWREG_DISCONT_MODE, | ||
681 | AR_GLB_SWREG_DISCONT_EN_BT_WLAN); | ||
682 | |||
693 | ah->modes_index = modesIndex; | 683 | ah->modes_index = modesIndex; |
694 | ar9003_hw_override_ini(ah); | 684 | ar9003_hw_override_ini(ah); |
695 | ar9003_hw_set_channel_regs(ah, chan); | 685 | ar9003_hw_set_channel_regs(ah, chan); |
696 | ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); | 686 | ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); |
697 | ath9k_hw_apply_txpower(ah, chan); | 687 | ath9k_hw_apply_txpower(ah, chan, false); |
698 | 688 | ||
699 | if (AR_SREV_9462(ah)) { | 689 | if (AR_SREV_9462(ah)) { |
700 | if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0, | 690 | if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0, |
@@ -725,6 +715,14 @@ static void ar9003_hw_set_rfmode(struct ath_hw *ah, | |||
725 | 715 | ||
726 | if (IS_CHAN_A_FAST_CLOCK(ah, chan)) | 716 | if (IS_CHAN_A_FAST_CLOCK(ah, chan)) |
727 | rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE); | 717 | rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE); |
718 | if (IS_CHAN_QUARTER_RATE(chan)) | ||
719 | rfMode |= AR_PHY_MODE_QUARTER; | ||
720 | if (IS_CHAN_HALF_RATE(chan)) | ||
721 | rfMode |= AR_PHY_MODE_HALF; | ||
722 | |||
723 | if (rfMode & (AR_PHY_MODE_QUARTER | AR_PHY_MODE_HALF)) | ||
724 | REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, | ||
725 | AR_PHY_FRAME_CTL_CF_OVERLAP_WINDOW, 3); | ||
728 | 726 | ||
729 | REG_WRITE(ah, AR_PHY_MODE, rfMode); | 727 | REG_WRITE(ah, AR_PHY_MODE, rfMode); |
730 | } | 728 | } |
@@ -795,12 +793,8 @@ static bool ar9003_hw_rfbus_req(struct ath_hw *ah) | |||
795 | static void ar9003_hw_rfbus_done(struct ath_hw *ah) | 793 | static void ar9003_hw_rfbus_done(struct ath_hw *ah) |
796 | { | 794 | { |
797 | u32 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; | 795 | u32 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; |
798 | if (IS_CHAN_B(ah->curchan)) | ||
799 | synthDelay = (4 * synthDelay) / 22; | ||
800 | else | ||
801 | synthDelay /= 10; | ||
802 | 796 | ||
803 | udelay(synthDelay + BASE_ACTIVATE_DELAY); | 797 | ath9k_hw_synth_delay(ah, ah->curchan, synthDelay); |
804 | 798 | ||
805 | REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0); | 799 | REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0); |
806 | } | 800 | } |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index d834d97fe727..ed662c3bae5b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h | |||
@@ -468,6 +468,9 @@ | |||
468 | #define AR_PHY_ADDAC_PARA_CTL (AR_SM_BASE + 0x150) | 468 | #define AR_PHY_ADDAC_PARA_CTL (AR_SM_BASE + 0x150) |
469 | #define AR_PHY_XPA_CFG (AR_SM_BASE + 0x158) | 469 | #define AR_PHY_XPA_CFG (AR_SM_BASE + 0x158) |
470 | 470 | ||
471 | #define AR_PHY_FRAME_CTL_CF_OVERLAP_WINDOW 3 | ||
472 | #define AR_PHY_FRAME_CTL_CF_OVERLAP_WINDOW_S 0 | ||
473 | |||
471 | #define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A 0x0001FC00 | 474 | #define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A 0x0001FC00 |
472 | #define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A_S 10 | 475 | #define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A_S 10 |
473 | #define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A 0x3FF | 476 | #define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A 0x3FF |
@@ -817,18 +820,26 @@ | |||
817 | #define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x0001 | 820 | #define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x0001 |
818 | #define AR_PHY_RX_DELAY_DELAY 0x00003FFF | 821 | #define AR_PHY_RX_DELAY_DELAY 0x00003FFF |
819 | #define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010 | 822 | #define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010 |
820 | #define AR_PHY_SPECTRAL_SCAN_ENABLE 0x00000001 | 823 | |
821 | #define AR_PHY_SPECTRAL_SCAN_ENABLE_S 0 | 824 | #define AR_PHY_SPECTRAL_SCAN_ENABLE 0x00000001 |
822 | #define AR_PHY_SPECTRAL_SCAN_ACTIVE 0x00000002 | 825 | #define AR_PHY_SPECTRAL_SCAN_ENABLE_S 0 |
823 | #define AR_PHY_SPECTRAL_SCAN_ACTIVE_S 1 | 826 | #define AR_PHY_SPECTRAL_SCAN_ACTIVE 0x00000002 |
824 | #define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD 0x000000F0 | 827 | #define AR_PHY_SPECTRAL_SCAN_ACTIVE_S 1 |
825 | #define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_S 4 | 828 | #define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD 0x000000F0 |
826 | #define AR_PHY_SPECTRAL_SCAN_PERIOD 0x0000FF00 | 829 | #define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_S 4 |
827 | #define AR_PHY_SPECTRAL_SCAN_PERIOD_S 8 | 830 | #define AR_PHY_SPECTRAL_SCAN_PERIOD 0x0000FF00 |
828 | #define AR_PHY_SPECTRAL_SCAN_COUNT 0x00FF0000 | 831 | #define AR_PHY_SPECTRAL_SCAN_PERIOD_S 8 |
829 | #define AR_PHY_SPECTRAL_SCAN_COUNT_S 16 | 832 | #define AR_PHY_SPECTRAL_SCAN_COUNT 0x0FFF0000 |
830 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000 | 833 | #define AR_PHY_SPECTRAL_SCAN_COUNT_S 16 |
831 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24 | 834 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x10000000 |
835 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 28 | ||
836 | #define AR_PHY_SPECTRAL_SCAN_PRIORITY 0x20000000 | ||
837 | #define AR_PHY_SPECTRAL_SCAN_PRIORITY_S 29 | ||
838 | #define AR_PHY_SPECTRAL_SCAN_USE_ERR5 0x40000000 | ||
839 | #define AR_PHY_SPECTRAL_SCAN_USE_ERR5_S 30 | ||
840 | #define AR_PHY_SPECTRAL_SCAN_COMPRESSED_RPT 0x80000000 | ||
841 | #define AR_PHY_SPECTRAL_SCAN_COMPRESSED_RPT_S 31 | ||
842 | |||
832 | #define AR_PHY_CHANNEL_STATUS_RX_CLEAR 0x00000004 | 843 | #define AR_PHY_CHANNEL_STATUS_RX_CLEAR 0x00000004 |
833 | #define AR_PHY_RTT_CTRL_ENA_RADIO_RETENTION 0x00000001 | 844 | #define AR_PHY_RTT_CTRL_ENA_RADIO_RETENTION 0x00000001 |
834 | #define AR_PHY_RTT_CTRL_ENA_RADIO_RETENTION_S 0 | 845 | #define AR_PHY_RTT_CTRL_ENA_RADIO_RETENTION_S 0 |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_rtt.c b/drivers/net/wireless/ath/ath9k/ar9003_rtt.c index 458bedf0b0ae..74de3539c2c8 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_rtt.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_rtt.c | |||
@@ -15,6 +15,7 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include "hw.h" | 17 | #include "hw.h" |
18 | #include "hw-ops.h" | ||
18 | #include "ar9003_phy.h" | 19 | #include "ar9003_phy.h" |
19 | #include "ar9003_rtt.h" | 20 | #include "ar9003_rtt.h" |
20 | 21 | ||
@@ -69,7 +70,7 @@ bool ar9003_hw_rtt_force_restore(struct ath_hw *ah) | |||
69 | } | 70 | } |
70 | 71 | ||
71 | static void ar9003_hw_rtt_load_hist_entry(struct ath_hw *ah, u8 chain, | 72 | static void ar9003_hw_rtt_load_hist_entry(struct ath_hw *ah, u8 chain, |
72 | u32 index, u32 data28) | 73 | u32 index, u32 data28) |
73 | { | 74 | { |
74 | u32 val; | 75 | u32 val; |
75 | 76 | ||
@@ -100,12 +101,21 @@ static void ar9003_hw_rtt_load_hist_entry(struct ath_hw *ah, u8 chain, | |||
100 | RTT_ACCESS_TIMEOUT); | 101 | RTT_ACCESS_TIMEOUT); |
101 | } | 102 | } |
102 | 103 | ||
103 | void ar9003_hw_rtt_load_hist(struct ath_hw *ah, u8 chain, u32 *table) | 104 | void ar9003_hw_rtt_load_hist(struct ath_hw *ah) |
104 | { | 105 | { |
105 | int i; | 106 | int chain, i; |
106 | 107 | ||
107 | for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) | 108 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { |
108 | ar9003_hw_rtt_load_hist_entry(ah, chain, i, table[i]); | 109 | if (!(ah->rxchainmask & (1 << chain))) |
110 | continue; | ||
111 | for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) { | ||
112 | ar9003_hw_rtt_load_hist_entry(ah, chain, i, | ||
113 | ah->caldata->rtt_table[chain][i]); | ||
114 | ath_dbg(ath9k_hw_common(ah), CALIBRATE, | ||
115 | "Load RTT value at idx %d, chain %d: 0x%x\n", | ||
116 | i, chain, ah->caldata->rtt_table[chain][i]); | ||
117 | } | ||
118 | } | ||
109 | } | 119 | } |
110 | 120 | ||
111 | static int ar9003_hw_rtt_fill_hist_entry(struct ath_hw *ah, u8 chain, u32 index) | 121 | static int ar9003_hw_rtt_fill_hist_entry(struct ath_hw *ah, u8 chain, u32 index) |
@@ -128,27 +138,71 @@ static int ar9003_hw_rtt_fill_hist_entry(struct ath_hw *ah, u8 chain, u32 index) | |||
128 | RTT_ACCESS_TIMEOUT)) | 138 | RTT_ACCESS_TIMEOUT)) |
129 | return RTT_BAD_VALUE; | 139 | return RTT_BAD_VALUE; |
130 | 140 | ||
131 | val = REG_READ(ah, AR_PHY_RTT_TABLE_SW_INTF_1_B(chain)); | 141 | val = MS(REG_READ(ah, AR_PHY_RTT_TABLE_SW_INTF_1_B(chain)), |
142 | AR_PHY_RTT_SW_RTT_TABLE_DATA); | ||
143 | |||
132 | 144 | ||
133 | return val; | 145 | return val; |
134 | } | 146 | } |
135 | 147 | ||
136 | void ar9003_hw_rtt_fill_hist(struct ath_hw *ah, u8 chain, u32 *table) | 148 | void ar9003_hw_rtt_fill_hist(struct ath_hw *ah) |
137 | { | 149 | { |
138 | int i; | 150 | int chain, i; |
151 | |||
152 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { | ||
153 | if (!(ah->rxchainmask & (1 << chain))) | ||
154 | continue; | ||
155 | for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) { | ||
156 | ah->caldata->rtt_table[chain][i] = | ||
157 | ar9003_hw_rtt_fill_hist_entry(ah, chain, i); | ||
158 | ath_dbg(ath9k_hw_common(ah), CALIBRATE, | ||
159 | "RTT value at idx %d, chain %d is: 0x%x\n", | ||
160 | i, chain, ah->caldata->rtt_table[chain][i]); | ||
161 | } | ||
162 | } | ||
139 | 163 | ||
140 | for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) | 164 | ah->caldata->rtt_done = true; |
141 | table[i] = ar9003_hw_rtt_fill_hist_entry(ah, chain, i); | ||
142 | } | 165 | } |
143 | 166 | ||
144 | void ar9003_hw_rtt_clear_hist(struct ath_hw *ah) | 167 | void ar9003_hw_rtt_clear_hist(struct ath_hw *ah) |
145 | { | 168 | { |
146 | int i, j; | 169 | int chain, i; |
147 | 170 | ||
148 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | 171 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { |
149 | if (!(ah->rxchainmask & (1 << i))) | 172 | if (!(ah->rxchainmask & (1 << chain))) |
150 | continue; | 173 | continue; |
151 | for (j = 0; j < MAX_RTT_TABLE_ENTRY; j++) | 174 | for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) |
152 | ar9003_hw_rtt_load_hist_entry(ah, i, j, 0); | 175 | ar9003_hw_rtt_load_hist_entry(ah, chain, i, 0); |
153 | } | 176 | } |
177 | |||
178 | if (ah->caldata) | ||
179 | ah->caldata->rtt_done = false; | ||
180 | } | ||
181 | |||
182 | bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan) | ||
183 | { | ||
184 | bool restore; | ||
185 | |||
186 | if (!ah->caldata) | ||
187 | return false; | ||
188 | |||
189 | if (!ah->caldata->rtt_done) | ||
190 | return false; | ||
191 | |||
192 | ar9003_hw_rtt_enable(ah); | ||
193 | ar9003_hw_rtt_set_mask(ah, 0x10); | ||
194 | |||
195 | if (!ath9k_hw_rfbus_req(ah)) { | ||
196 | ath_err(ath9k_hw_common(ah), "Could not stop baseband\n"); | ||
197 | restore = false; | ||
198 | goto fail; | ||
199 | } | ||
200 | |||
201 | ar9003_hw_rtt_load_hist(ah); | ||
202 | restore = ar9003_hw_rtt_force_restore(ah); | ||
203 | |||
204 | fail: | ||
205 | ath9k_hw_rfbus_done(ah); | ||
206 | ar9003_hw_rtt_disable(ah); | ||
207 | return restore; | ||
154 | } | 208 | } |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_rtt.h b/drivers/net/wireless/ath/ath9k/ar9003_rtt.h index 030758d087d6..a43b30d723a4 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_rtt.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_rtt.h | |||
@@ -21,8 +21,9 @@ void ar9003_hw_rtt_enable(struct ath_hw *ah); | |||
21 | void ar9003_hw_rtt_disable(struct ath_hw *ah); | 21 | void ar9003_hw_rtt_disable(struct ath_hw *ah); |
22 | void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask); | 22 | void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask); |
23 | bool ar9003_hw_rtt_force_restore(struct ath_hw *ah); | 23 | bool ar9003_hw_rtt_force_restore(struct ath_hw *ah); |
24 | void ar9003_hw_rtt_load_hist(struct ath_hw *ah, u8 chain, u32 *table); | 24 | void ar9003_hw_rtt_load_hist(struct ath_hw *ah); |
25 | void ar9003_hw_rtt_fill_hist(struct ath_hw *ah, u8 chain, u32 *table); | 25 | void ar9003_hw_rtt_fill_hist(struct ath_hw *ah); |
26 | void ar9003_hw_rtt_clear_hist(struct ath_hw *ah); | 26 | void ar9003_hw_rtt_clear_hist(struct ath_hw *ah); |
27 | bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan); | ||
27 | 28 | ||
28 | #endif | 29 | #endif |
diff --git a/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h b/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h index f11d9b2677fd..1bd3a3d22101 100644 --- a/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2011 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2012 Qualcomm Atheros Inc. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
@@ -18,7 +19,7 @@ | |||
18 | #define INITVALS_9330_1P1_H | 19 | #define INITVALS_9330_1P1_H |
19 | 20 | ||
20 | static const u32 ar9331_1p1_baseband_postamble[][5] = { | 21 | static const u32 ar9331_1p1_baseband_postamble[][5] = { |
21 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 22 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
22 | {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005}, | 23 | {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005}, |
23 | {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e}, | 24 | {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e}, |
24 | {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, | 25 | {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, |
@@ -27,10 +28,10 @@ static const u32 ar9331_1p1_baseband_postamble[][5] = { | |||
27 | {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, | 28 | {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, |
28 | {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044}, | 29 | {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044}, |
29 | {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a4, 0x037216a4}, | 30 | {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a4, 0x037216a4}, |
30 | {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020}, | 31 | {0x00009e04, 0x00202020, 0x00202020, 0x00202020, 0x00202020}, |
31 | {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, | 32 | {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, |
32 | {0x00009e10, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e}, | 33 | {0x00009e10, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e}, |
33 | {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, | 34 | {0x00009e14, 0x31365d5e, 0x3136605e, 0x3136605e, 0x31365d5e}, |
34 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 35 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
35 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, | 36 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, |
36 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, | 37 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, |
@@ -55,7 +56,7 @@ static const u32 ar9331_1p1_baseband_postamble[][5] = { | |||
55 | {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 56 | {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
56 | {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 57 | {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
57 | {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, | 58 | {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, |
58 | {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071981}, | 59 | {0x0000a2d0, 0x00071982, 0x00071982, 0x00071982, 0x00071982}, |
59 | {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, | 60 | {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, |
60 | {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 61 | {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
61 | {0x0000ae04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, | 62 | {0x0000ae04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, |
@@ -63,7 +64,7 @@ static const u32 ar9331_1p1_baseband_postamble[][5] = { | |||
63 | }; | 64 | }; |
64 | 65 | ||
65 | static const u32 ar9331_modes_lowest_ob_db_tx_gain_1p1[][5] = { | 66 | static const u32 ar9331_modes_lowest_ob_db_tx_gain_1p1[][5] = { |
66 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 67 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
67 | {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, | 68 | {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, |
68 | {0x0000a2dc, 0xffff2a52, 0xffff2a52, 0xffff2a52, 0xffff2a52}, | 69 | {0x0000a2dc, 0xffff2a52, 0xffff2a52, 0xffff2a52, 0xffff2a52}, |
69 | {0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84}, | 70 | {0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84}, |
@@ -155,7 +156,7 @@ static const u32 ar9331_modes_lowest_ob_db_tx_gain_1p1[][5] = { | |||
155 | }; | 156 | }; |
156 | 157 | ||
157 | static const u32 ar9331_modes_high_ob_db_tx_gain_1p1[][5] = { | 158 | static const u32 ar9331_modes_high_ob_db_tx_gain_1p1[][5] = { |
158 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 159 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
159 | {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, | 160 | {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, |
160 | {0x0000a2dc, 0xffaa9a52, 0xffaa9a52, 0xffaa9a52, 0xffaa9a52}, | 161 | {0x0000a2dc, 0xffaa9a52, 0xffaa9a52, 0xffaa9a52, 0xffaa9a52}, |
161 | {0x0000a2e0, 0xffb31c84, 0xffb31c84, 0xffb31c84, 0xffb31c84}, | 162 | {0x0000a2e0, 0xffb31c84, 0xffb31c84, 0xffb31c84, 0xffb31c84}, |
@@ -245,7 +246,7 @@ static const u32 ar9331_modes_high_ob_db_tx_gain_1p1[][5] = { | |||
245 | }; | 246 | }; |
246 | 247 | ||
247 | static const u32 ar9331_modes_low_ob_db_tx_gain_1p1[][5] = { | 248 | static const u32 ar9331_modes_low_ob_db_tx_gain_1p1[][5] = { |
248 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 249 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
249 | {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, | 250 | {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, |
250 | {0x0000a2dc, 0xffff2a52, 0xffff2a52, 0xffff2a52, 0xffff2a52}, | 251 | {0x0000a2dc, 0xffff2a52, 0xffff2a52, 0xffff2a52, 0xffff2a52}, |
251 | {0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84}, | 252 | {0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84}, |
@@ -377,14 +378,14 @@ static const u32 ar9331_1p1_radio_core[][2] = { | |||
377 | {0x000160b4, 0x92480040}, | 378 | {0x000160b4, 0x92480040}, |
378 | {0x000160c0, 0x006db6db}, | 379 | {0x000160c0, 0x006db6db}, |
379 | {0x000160c4, 0x0186db60}, | 380 | {0x000160c4, 0x0186db60}, |
380 | {0x000160c8, 0x6db6db6c}, | 381 | {0x000160c8, 0x6db4db6c}, |
381 | {0x000160cc, 0x6de6c300}, | 382 | {0x000160cc, 0x6de6c300}, |
382 | {0x000160d0, 0x14500820}, | 383 | {0x000160d0, 0x14500820}, |
383 | {0x00016100, 0x04cb0001}, | 384 | {0x00016100, 0x04cb0001}, |
384 | {0x00016104, 0xfff80015}, | 385 | {0x00016104, 0xfff80015}, |
385 | {0x00016108, 0x00080010}, | 386 | {0x00016108, 0x00080010}, |
386 | {0x0001610c, 0x00170000}, | 387 | {0x0001610c, 0x00170000}, |
387 | {0x00016140, 0x10804000}, | 388 | {0x00016140, 0x10800000}, |
388 | {0x00016144, 0x01884080}, | 389 | {0x00016144, 0x01884080}, |
389 | {0x00016148, 0x000080c0}, | 390 | {0x00016148, 0x000080c0}, |
390 | {0x00016280, 0x01000015}, | 391 | {0x00016280, 0x01000015}, |
@@ -417,7 +418,7 @@ static const u32 ar9331_1p1_radio_core[][2] = { | |||
417 | }; | 418 | }; |
418 | 419 | ||
419 | static const u32 ar9331_1p1_soc_postamble[][5] = { | 420 | static const u32 ar9331_1p1_soc_postamble[][5] = { |
420 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 421 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
421 | {0x00007010, 0x00000022, 0x00000022, 0x00000022, 0x00000022}, | 422 | {0x00007010, 0x00000022, 0x00000022, 0x00000022, 0x00000022}, |
422 | }; | 423 | }; |
423 | 424 | ||
@@ -691,7 +692,7 @@ static const u32 ar9331_1p1_baseband_core[][2] = { | |||
691 | }; | 692 | }; |
692 | 693 | ||
693 | static const u32 ar9331_modes_high_power_tx_gain_1p1[][5] = { | 694 | static const u32 ar9331_modes_high_power_tx_gain_1p1[][5] = { |
694 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 695 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
695 | {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, | 696 | {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, |
696 | {0x0000a2dc, 0xffff2a52, 0xffff2a52, 0xffff2a52, 0xffff2a52}, | 697 | {0x0000a2dc, 0xffff2a52, 0xffff2a52, 0xffff2a52, 0xffff2a52}, |
697 | {0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84}, | 698 | {0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84}, |
@@ -783,7 +784,7 @@ static const u32 ar9331_modes_high_power_tx_gain_1p1[][5] = { | |||
783 | }; | 784 | }; |
784 | 785 | ||
785 | static const u32 ar9331_1p1_mac_postamble[][5] = { | 786 | static const u32 ar9331_1p1_mac_postamble[][5] = { |
786 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 787 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
787 | {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, | 788 | {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, |
788 | {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, | 789 | {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, |
789 | {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, | 790 | {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, |
@@ -973,26 +974,27 @@ static const u32 ar9331_1p1_mac_core[][2] = { | |||
973 | 974 | ||
974 | static const u32 ar9331_common_rx_gain_1p1[][2] = { | 975 | static const u32 ar9331_common_rx_gain_1p1[][2] = { |
975 | /* Addr allmodes */ | 976 | /* Addr allmodes */ |
976 | {0x0000a000, 0x00010000}, | 977 | {0x00009e18, 0x05000000}, |
977 | {0x0000a004, 0x00030002}, | 978 | {0x0000a000, 0x00060005}, |
978 | {0x0000a008, 0x00050004}, | 979 | {0x0000a004, 0x00810080}, |
979 | {0x0000a00c, 0x00810080}, | 980 | {0x0000a008, 0x00830082}, |
980 | {0x0000a010, 0x00830082}, | 981 | {0x0000a00c, 0x00850084}, |
981 | {0x0000a014, 0x01810180}, | 982 | {0x0000a010, 0x01820181}, |
982 | {0x0000a018, 0x01830182}, | 983 | {0x0000a014, 0x01840183}, |
983 | {0x0000a01c, 0x01850184}, | 984 | {0x0000a018, 0x01880185}, |
984 | {0x0000a020, 0x01890188}, | 985 | {0x0000a01c, 0x018a0189}, |
985 | {0x0000a024, 0x018b018a}, | 986 | {0x0000a020, 0x02850284}, |
986 | {0x0000a028, 0x018d018c}, | 987 | {0x0000a024, 0x02890288}, |
987 | {0x0000a02c, 0x01910190}, | 988 | {0x0000a028, 0x028b028a}, |
988 | {0x0000a030, 0x01930192}, | 989 | {0x0000a02c, 0x03850384}, |
989 | {0x0000a034, 0x01950194}, | 990 | {0x0000a030, 0x03890388}, |
990 | {0x0000a038, 0x038a0196}, | 991 | {0x0000a034, 0x038b038a}, |
991 | {0x0000a03c, 0x038c038b}, | 992 | {0x0000a038, 0x038d038c}, |
992 | {0x0000a040, 0x0390038d}, | 993 | {0x0000a03c, 0x03910390}, |
993 | {0x0000a044, 0x03920391}, | 994 | {0x0000a040, 0x03930392}, |
994 | {0x0000a048, 0x03940393}, | 995 | {0x0000a044, 0x03950394}, |
995 | {0x0000a04c, 0x03960395}, | 996 | {0x0000a048, 0x00000396}, |
997 | {0x0000a04c, 0x00000000}, | ||
996 | {0x0000a050, 0x00000000}, | 998 | {0x0000a050, 0x00000000}, |
997 | {0x0000a054, 0x00000000}, | 999 | {0x0000a054, 0x00000000}, |
998 | {0x0000a058, 0x00000000}, | 1000 | {0x0000a058, 0x00000000}, |
@@ -1005,15 +1007,15 @@ static const u32 ar9331_common_rx_gain_1p1[][2] = { | |||
1005 | {0x0000a074, 0x00000000}, | 1007 | {0x0000a074, 0x00000000}, |
1006 | {0x0000a078, 0x00000000}, | 1008 | {0x0000a078, 0x00000000}, |
1007 | {0x0000a07c, 0x00000000}, | 1009 | {0x0000a07c, 0x00000000}, |
1008 | {0x0000a080, 0x22222229}, | 1010 | {0x0000a080, 0x28282828}, |
1009 | {0x0000a084, 0x1d1d1d1d}, | 1011 | {0x0000a084, 0x28282828}, |
1010 | {0x0000a088, 0x1d1d1d1d}, | 1012 | {0x0000a088, 0x28282828}, |
1011 | {0x0000a08c, 0x1d1d1d1d}, | 1013 | {0x0000a08c, 0x28282828}, |
1012 | {0x0000a090, 0x171d1d1d}, | 1014 | {0x0000a090, 0x28282828}, |
1013 | {0x0000a094, 0x11111717}, | 1015 | {0x0000a094, 0x24242428}, |
1014 | {0x0000a098, 0x00030311}, | 1016 | {0x0000a098, 0x171e1e1e}, |
1015 | {0x0000a09c, 0x00000000}, | 1017 | {0x0000a09c, 0x02020b0b}, |
1016 | {0x0000a0a0, 0x00000000}, | 1018 | {0x0000a0a0, 0x02020202}, |
1017 | {0x0000a0a4, 0x00000000}, | 1019 | {0x0000a0a4, 0x00000000}, |
1018 | {0x0000a0a8, 0x00000000}, | 1020 | {0x0000a0a8, 0x00000000}, |
1019 | {0x0000a0ac, 0x00000000}, | 1021 | {0x0000a0ac, 0x00000000}, |
@@ -1021,27 +1023,27 @@ static const u32 ar9331_common_rx_gain_1p1[][2] = { | |||
1021 | {0x0000a0b4, 0x00000000}, | 1023 | {0x0000a0b4, 0x00000000}, |
1022 | {0x0000a0b8, 0x00000000}, | 1024 | {0x0000a0b8, 0x00000000}, |
1023 | {0x0000a0bc, 0x00000000}, | 1025 | {0x0000a0bc, 0x00000000}, |
1024 | {0x0000a0c0, 0x001f0000}, | 1026 | {0x0000a0c0, 0x22072208}, |
1025 | {0x0000a0c4, 0x01000101}, | 1027 | {0x0000a0c4, 0x22052206}, |
1026 | {0x0000a0c8, 0x011e011f}, | 1028 | {0x0000a0c8, 0x22032204}, |
1027 | {0x0000a0cc, 0x011c011d}, | 1029 | {0x0000a0cc, 0x22012202}, |
1028 | {0x0000a0d0, 0x02030204}, | 1030 | {0x0000a0d0, 0x221f2200}, |
1029 | {0x0000a0d4, 0x02010202}, | 1031 | {0x0000a0d4, 0x221d221e}, |
1030 | {0x0000a0d8, 0x021f0200}, | 1032 | {0x0000a0d8, 0x33023303}, |
1031 | {0x0000a0dc, 0x0302021e}, | 1033 | {0x0000a0dc, 0x33003301}, |
1032 | {0x0000a0e0, 0x03000301}, | 1034 | {0x0000a0e0, 0x331e331f}, |
1033 | {0x0000a0e4, 0x031e031f}, | 1035 | {0x0000a0e4, 0x4402331d}, |
1034 | {0x0000a0e8, 0x0402031d}, | 1036 | {0x0000a0e8, 0x44004401}, |
1035 | {0x0000a0ec, 0x04000401}, | 1037 | {0x0000a0ec, 0x441e441f}, |
1036 | {0x0000a0f0, 0x041e041f}, | 1038 | {0x0000a0f0, 0x55025503}, |
1037 | {0x0000a0f4, 0x0502041d}, | 1039 | {0x0000a0f4, 0x55005501}, |
1038 | {0x0000a0f8, 0x05000501}, | 1040 | {0x0000a0f8, 0x551e551f}, |
1039 | {0x0000a0fc, 0x051e051f}, | 1041 | {0x0000a0fc, 0x6602551d}, |
1040 | {0x0000a100, 0x06010602}, | 1042 | {0x0000a100, 0x66006601}, |
1041 | {0x0000a104, 0x061f0600}, | 1043 | {0x0000a104, 0x661e661f}, |
1042 | {0x0000a108, 0x061d061e}, | 1044 | {0x0000a108, 0x7703661d}, |
1043 | {0x0000a10c, 0x07020703}, | 1045 | {0x0000a10c, 0x77017702}, |
1044 | {0x0000a110, 0x07000701}, | 1046 | {0x0000a110, 0x00007700}, |
1045 | {0x0000a114, 0x00000000}, | 1047 | {0x0000a114, 0x00000000}, |
1046 | {0x0000a118, 0x00000000}, | 1048 | {0x0000a118, 0x00000000}, |
1047 | {0x0000a11c, 0x00000000}, | 1049 | {0x0000a11c, 0x00000000}, |
@@ -1054,26 +1056,26 @@ static const u32 ar9331_common_rx_gain_1p1[][2] = { | |||
1054 | {0x0000a138, 0x00000000}, | 1056 | {0x0000a138, 0x00000000}, |
1055 | {0x0000a13c, 0x00000000}, | 1057 | {0x0000a13c, 0x00000000}, |
1056 | {0x0000a140, 0x001f0000}, | 1058 | {0x0000a140, 0x001f0000}, |
1057 | {0x0000a144, 0x01000101}, | 1059 | {0x0000a144, 0x111f1100}, |
1058 | {0x0000a148, 0x011e011f}, | 1060 | {0x0000a148, 0x111d111e}, |
1059 | {0x0000a14c, 0x011c011d}, | 1061 | {0x0000a14c, 0x111b111c}, |
1060 | {0x0000a150, 0x02030204}, | 1062 | {0x0000a150, 0x22032204}, |
1061 | {0x0000a154, 0x02010202}, | 1063 | {0x0000a154, 0x22012202}, |
1062 | {0x0000a158, 0x021f0200}, | 1064 | {0x0000a158, 0x221f2200}, |
1063 | {0x0000a15c, 0x0302021e}, | 1065 | {0x0000a15c, 0x221d221e}, |
1064 | {0x0000a160, 0x03000301}, | 1066 | {0x0000a160, 0x33013302}, |
1065 | {0x0000a164, 0x031e031f}, | 1067 | {0x0000a164, 0x331f3300}, |
1066 | {0x0000a168, 0x0402031d}, | 1068 | {0x0000a168, 0x4402331e}, |
1067 | {0x0000a16c, 0x04000401}, | 1069 | {0x0000a16c, 0x44004401}, |
1068 | {0x0000a170, 0x041e041f}, | 1070 | {0x0000a170, 0x441e441f}, |
1069 | {0x0000a174, 0x0502041d}, | 1071 | {0x0000a174, 0x55015502}, |
1070 | {0x0000a178, 0x05000501}, | 1072 | {0x0000a178, 0x551f5500}, |
1071 | {0x0000a17c, 0x051e051f}, | 1073 | {0x0000a17c, 0x6602551e}, |
1072 | {0x0000a180, 0x06010602}, | 1074 | {0x0000a180, 0x66006601}, |
1073 | {0x0000a184, 0x061f0600}, | 1075 | {0x0000a184, 0x661e661f}, |
1074 | {0x0000a188, 0x061d061e}, | 1076 | {0x0000a188, 0x7703661d}, |
1075 | {0x0000a18c, 0x07020703}, | 1077 | {0x0000a18c, 0x77017702}, |
1076 | {0x0000a190, 0x07000701}, | 1078 | {0x0000a190, 0x00007700}, |
1077 | {0x0000a194, 0x00000000}, | 1079 | {0x0000a194, 0x00000000}, |
1078 | {0x0000a198, 0x00000000}, | 1080 | {0x0000a198, 0x00000000}, |
1079 | {0x0000a19c, 0x00000000}, | 1081 | {0x0000a19c, 0x00000000}, |
@@ -1100,14 +1102,14 @@ static const u32 ar9331_common_rx_gain_1p1[][2] = { | |||
1100 | {0x0000a1f0, 0x00000396}, | 1102 | {0x0000a1f0, 0x00000396}, |
1101 | {0x0000a1f4, 0x00000396}, | 1103 | {0x0000a1f4, 0x00000396}, |
1102 | {0x0000a1f8, 0x00000396}, | 1104 | {0x0000a1f8, 0x00000396}, |
1103 | {0x0000a1fc, 0x00000196}, | 1105 | {0x0000a1fc, 0x00000296}, |
1104 | }; | 1106 | }; |
1105 | 1107 | ||
1106 | static const u32 ar9331_common_tx_gain_offset1_1[][1] = { | 1108 | static const u32 ar9331_common_tx_gain_offset1_1[][1] = { |
1107 | {0}, | 1109 | {0x00000000}, |
1108 | {3}, | 1110 | {0x00000003}, |
1109 | {0}, | 1111 | {0x00000000}, |
1110 | {0}, | 1112 | {0x00000000}, |
1111 | }; | 1113 | }; |
1112 | 1114 | ||
1113 | static const u32 ar9331_1p1_chansel_xtal_25M[] = { | 1115 | static const u32 ar9331_1p1_chansel_xtal_25M[] = { |
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h index b6ba1e8149be..8f406ff2c95e 100644 --- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h | |||
@@ -52,7 +52,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = { | |||
52 | {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020}, | 52 | {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020}, |
53 | {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000d8}, | 53 | {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000d8}, |
54 | {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec86d2e}, | 54 | {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec86d2e}, |
55 | {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3376605e, 0x33795d5e}, | 55 | {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3376605e, 0x32395d5e}, |
56 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 56 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
57 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, | 57 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, |
58 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, | 58 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, |
@@ -958,7 +958,7 @@ static const u32 ar9462_2p0_radio_core[][2] = { | |||
958 | {0x0001604c, 0x2699e04f}, | 958 | {0x0001604c, 0x2699e04f}, |
959 | {0x00016050, 0x6db6db6c}, | 959 | {0x00016050, 0x6db6db6c}, |
960 | {0x00016058, 0x6c200000}, | 960 | {0x00016058, 0x6c200000}, |
961 | {0x00016080, 0x00040000}, | 961 | {0x00016080, 0x000c0000}, |
962 | {0x00016084, 0x9a68048c}, | 962 | {0x00016084, 0x9a68048c}, |
963 | {0x00016088, 0x54214514}, | 963 | {0x00016088, 0x54214514}, |
964 | {0x0001608c, 0x1203040b}, | 964 | {0x0001608c, 0x1203040b}, |
@@ -981,7 +981,7 @@ static const u32 ar9462_2p0_radio_core[][2] = { | |||
981 | {0x00016144, 0x02084080}, | 981 | {0x00016144, 0x02084080}, |
982 | {0x00016148, 0x000080c0}, | 982 | {0x00016148, 0x000080c0}, |
983 | {0x00016280, 0x050a0001}, | 983 | {0x00016280, 0x050a0001}, |
984 | {0x00016284, 0x3d841400}, | 984 | {0x00016284, 0x3d841418}, |
985 | {0x00016288, 0x00000000}, | 985 | {0x00016288, 0x00000000}, |
986 | {0x0001628c, 0xe3000000}, | 986 | {0x0001628c, 0xe3000000}, |
987 | {0x00016290, 0xa1005080}, | 987 | {0x00016290, 0xa1005080}, |
@@ -1007,6 +1007,7 @@ static const u32 ar9462_2p0_radio_core[][2] = { | |||
1007 | 1007 | ||
1008 | static const u32 ar9462_2p0_soc_preamble[][2] = { | 1008 | static const u32 ar9462_2p0_soc_preamble[][2] = { |
1009 | /* Addr allmodes */ | 1009 | /* Addr allmodes */ |
1010 | {0x000040a4 ,0x00a0c1c9}, | ||
1010 | {0x00007020, 0x00000000}, | 1011 | {0x00007020, 0x00000000}, |
1011 | {0x00007034, 0x00000002}, | 1012 | {0x00007034, 0x00000002}, |
1012 | {0x00007038, 0x000004c2}, | 1013 | {0x00007038, 0x000004c2}, |
@@ -1115,9 +1116,9 @@ static const u32 ar9462_2p0_mac_core[][2] = { | |||
1115 | {0x000081f8, 0x00000000}, | 1116 | {0x000081f8, 0x00000000}, |
1116 | {0x000081fc, 0x00000000}, | 1117 | {0x000081fc, 0x00000000}, |
1117 | {0x00008240, 0x00100000}, | 1118 | {0x00008240, 0x00100000}, |
1118 | {0x00008244, 0x0010f400}, | 1119 | {0x00008244, 0x0010f424}, |
1119 | {0x00008248, 0x00000800}, | 1120 | {0x00008248, 0x00000800}, |
1120 | {0x0000824c, 0x0001e800}, | 1121 | {0x0000824c, 0x0001e848}, |
1121 | {0x00008250, 0x00000000}, | 1122 | {0x00008250, 0x00000000}, |
1122 | {0x00008254, 0x00000000}, | 1123 | {0x00008254, 0x00000000}, |
1123 | {0x00008258, 0x00000000}, | 1124 | {0x00008258, 0x00000000}, |
@@ -1448,16 +1449,4 @@ static const u32 ar9462_common_mixed_rx_gain_table_2p0[][2] = { | |||
1448 | {0x0000b1fc, 0x00000196}, | 1449 | {0x0000b1fc, 0x00000196}, |
1449 | }; | 1450 | }; |
1450 | 1451 | ||
1451 | static const u32 ar9462_2p0_BTCOEX_MAX_TXPWR_table[][2] = { | ||
1452 | /* Addr allmodes */ | ||
1453 | {0x000018c0, 0x10101010}, | ||
1454 | {0x000018c4, 0x10101010}, | ||
1455 | {0x000018c8, 0x10101010}, | ||
1456 | {0x000018cc, 0x10101010}, | ||
1457 | {0x000018d0, 0x10101010}, | ||
1458 | {0x000018d4, 0x10101010}, | ||
1459 | {0x000018d8, 0x10101010}, | ||
1460 | {0x000018dc, 0x10101010}, | ||
1461 | }; | ||
1462 | |||
1463 | #endif /* INITVALS_9462_2P0_H */ | 1452 | #endif /* INITVALS_9462_2P0_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 0a37631390db..a8c050085648 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -307,6 +307,7 @@ struct ath_rx { | |||
307 | u8 defant; | 307 | u8 defant; |
308 | u8 rxotherant; | 308 | u8 rxotherant; |
309 | u32 *rxlink; | 309 | u32 *rxlink; |
310 | u32 num_pkts; | ||
310 | unsigned int rxfilter; | 311 | unsigned int rxfilter; |
311 | spinlock_t rxbuflock; | 312 | spinlock_t rxbuflock; |
312 | struct list_head rxbuf; | 313 | struct list_head rxbuf; |
@@ -325,6 +326,9 @@ int ath_rx_init(struct ath_softc *sc, int nbufs); | |||
325 | void ath_rx_cleanup(struct ath_softc *sc); | 326 | void ath_rx_cleanup(struct ath_softc *sc); |
326 | int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp); | 327 | int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp); |
327 | struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype); | 328 | struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype); |
329 | void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq); | ||
330 | void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq); | ||
331 | void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq); | ||
328 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); | 332 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); |
329 | bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx); | 333 | bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx); |
330 | void ath_draintxq(struct ath_softc *sc, | 334 | void ath_draintxq(struct ath_softc *sc, |
@@ -370,7 +374,7 @@ struct ath_vif { | |||
370 | * number of beacon intervals, the game's up. | 374 | * number of beacon intervals, the game's up. |
371 | */ | 375 | */ |
372 | #define BSTUCK_THRESH 9 | 376 | #define BSTUCK_THRESH 9 |
373 | #define ATH_BCBUF 4 | 377 | #define ATH_BCBUF 8 |
374 | #define ATH_DEFAULT_BINTVAL 100 /* TU */ | 378 | #define ATH_DEFAULT_BINTVAL 100 /* TU */ |
375 | #define ATH_DEFAULT_BMISS_LIMIT 10 | 379 | #define ATH_DEFAULT_BMISS_LIMIT 10 |
376 | #define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) | 380 | #define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) |
@@ -414,9 +418,9 @@ int ath_beaconq_config(struct ath_softc *sc); | |||
414 | void ath_set_beacon(struct ath_softc *sc); | 418 | void ath_set_beacon(struct ath_softc *sc); |
415 | void ath9k_set_beaconing_status(struct ath_softc *sc, bool status); | 419 | void ath9k_set_beaconing_status(struct ath_softc *sc, bool status); |
416 | 420 | ||
417 | /*******/ | 421 | /*******************/ |
418 | /* ANI */ | 422 | /* Link Monitoring */ |
419 | /*******/ | 423 | /*******************/ |
420 | 424 | ||
421 | #define ATH_STA_SHORT_CALINTERVAL 1000 /* 1 second */ | 425 | #define ATH_STA_SHORT_CALINTERVAL 1000 /* 1 second */ |
422 | #define ATH_AP_SHORT_CALINTERVAL 100 /* 100 ms */ | 426 | #define ATH_AP_SHORT_CALINTERVAL 100 /* 100 ms */ |
@@ -427,7 +431,9 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status); | |||
427 | #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ | 431 | #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ |
428 | 432 | ||
429 | #define ATH_PAPRD_TIMEOUT 100 /* msecs */ | 433 | #define ATH_PAPRD_TIMEOUT 100 /* msecs */ |
434 | #define ATH_PLL_WORK_INTERVAL 100 | ||
430 | 435 | ||
436 | void ath_tx_complete_poll_work(struct work_struct *work); | ||
431 | void ath_reset_work(struct work_struct *work); | 437 | void ath_reset_work(struct work_struct *work); |
432 | void ath_hw_check(struct work_struct *work); | 438 | void ath_hw_check(struct work_struct *work); |
433 | void ath_hw_pll_work(struct work_struct *work); | 439 | void ath_hw_pll_work(struct work_struct *work); |
@@ -436,22 +442,31 @@ void ath_start_rx_poll(struct ath_softc *sc, u8 nbeacon); | |||
436 | void ath_paprd_calibrate(struct work_struct *work); | 442 | void ath_paprd_calibrate(struct work_struct *work); |
437 | void ath_ani_calibrate(unsigned long data); | 443 | void ath_ani_calibrate(unsigned long data); |
438 | void ath_start_ani(struct ath_common *common); | 444 | void ath_start_ani(struct ath_common *common); |
445 | int ath_update_survey_stats(struct ath_softc *sc); | ||
446 | void ath_update_survey_nf(struct ath_softc *sc, int channel); | ||
439 | 447 | ||
440 | /**********/ | 448 | /**********/ |
441 | /* BTCOEX */ | 449 | /* BTCOEX */ |
442 | /**********/ | 450 | /**********/ |
443 | 451 | ||
452 | enum bt_op_flags { | ||
453 | BT_OP_PRIORITY_DETECTED, | ||
454 | BT_OP_SCAN, | ||
455 | }; | ||
456 | |||
444 | struct ath_btcoex { | 457 | struct ath_btcoex { |
445 | bool hw_timer_enabled; | 458 | bool hw_timer_enabled; |
446 | spinlock_t btcoex_lock; | 459 | spinlock_t btcoex_lock; |
447 | struct timer_list period_timer; /* Timer for BT period */ | 460 | struct timer_list period_timer; /* Timer for BT period */ |
448 | u32 bt_priority_cnt; | 461 | u32 bt_priority_cnt; |
449 | unsigned long bt_priority_time; | 462 | unsigned long bt_priority_time; |
463 | unsigned long op_flags; | ||
450 | int bt_stomp_type; /* Types of BT stomping */ | 464 | int bt_stomp_type; /* Types of BT stomping */ |
451 | u32 btcoex_no_stomp; /* in usec */ | 465 | u32 btcoex_no_stomp; /* in usec */ |
452 | u32 btcoex_period; /* in usec */ | 466 | u32 btcoex_period; /* in usec */ |
453 | u32 btscan_no_stomp; /* in usec */ | 467 | u32 btscan_no_stomp; /* in usec */ |
454 | u32 duty_cycle; | 468 | u32 duty_cycle; |
469 | u32 bt_wait_time; | ||
455 | struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ | 470 | struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ |
456 | struct ath_mci_profile mci; | 471 | struct ath_mci_profile mci; |
457 | }; | 472 | }; |
@@ -513,8 +528,10 @@ static inline void ath_deinit_leds(struct ath_softc *sc) | |||
513 | } | 528 | } |
514 | #endif | 529 | #endif |
515 | 530 | ||
516 | 531 | /*******************************/ | |
517 | /* Antenna diversity/combining */ | 532 | /* Antenna diversity/combining */ |
533 | /*******************************/ | ||
534 | |||
518 | #define ATH_ANT_RX_CURRENT_SHIFT 4 | 535 | #define ATH_ANT_RX_CURRENT_SHIFT 4 |
519 | #define ATH_ANT_RX_MAIN_SHIFT 2 | 536 | #define ATH_ANT_RX_MAIN_SHIFT 2 |
520 | #define ATH_ANT_RX_MASK 0x3 | 537 | #define ATH_ANT_RX_MASK 0x3 |
@@ -567,6 +584,9 @@ struct ath_ant_comb { | |||
567 | unsigned long scan_start_time; | 584 | unsigned long scan_start_time; |
568 | }; | 585 | }; |
569 | 586 | ||
587 | void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs); | ||
588 | void ath_ant_comb_update(struct ath_softc *sc); | ||
589 | |||
570 | /********************/ | 590 | /********************/ |
571 | /* Main driver core */ | 591 | /* Main driver core */ |
572 | /********************/ | 592 | /********************/ |
@@ -584,15 +604,15 @@ struct ath_ant_comb { | |||
584 | #define ATH_TXPOWER_MAX 100 /* .5 dBm units */ | 604 | #define ATH_TXPOWER_MAX 100 /* .5 dBm units */ |
585 | #define ATH_RATE_DUMMY_MARKER 0 | 605 | #define ATH_RATE_DUMMY_MARKER 0 |
586 | 606 | ||
587 | #define SC_OP_INVALID BIT(0) | 607 | enum sc_op_flags { |
588 | #define SC_OP_BEACONS BIT(1) | 608 | SC_OP_INVALID, |
589 | #define SC_OP_OFFCHANNEL BIT(2) | 609 | SC_OP_BEACONS, |
590 | #define SC_OP_RXFLUSH BIT(3) | 610 | SC_OP_RXFLUSH, |
591 | #define SC_OP_TSF_RESET BIT(4) | 611 | SC_OP_TSF_RESET, |
592 | #define SC_OP_BT_PRIORITY_DETECTED BIT(5) | 612 | SC_OP_ANI_RUN, |
593 | #define SC_OP_BT_SCAN BIT(6) | 613 | SC_OP_PRIM_STA_VIF, |
594 | #define SC_OP_ANI_RUN BIT(7) | 614 | SC_OP_HW_RESET, |
595 | #define SC_OP_PRIM_STA_VIF BIT(8) | 615 | }; |
596 | 616 | ||
597 | /* Powersave flags */ | 617 | /* Powersave flags */ |
598 | #define PS_WAIT_FOR_BEACON BIT(0) | 618 | #define PS_WAIT_FOR_BEACON BIT(0) |
@@ -638,9 +658,9 @@ struct ath_softc { | |||
638 | struct completion paprd_complete; | 658 | struct completion paprd_complete; |
639 | 659 | ||
640 | unsigned int hw_busy_count; | 660 | unsigned int hw_busy_count; |
661 | unsigned long sc_flags; | ||
641 | 662 | ||
642 | u32 intrstatus; | 663 | u32 intrstatus; |
643 | u32 sc_flags; /* SC_OP_* */ | ||
644 | u16 ps_flags; /* PS_* */ | 664 | u16 ps_flags; /* PS_* */ |
645 | u16 curtxpow; | 665 | u16 curtxpow; |
646 | bool ps_enabled; | 666 | bool ps_enabled; |
@@ -678,6 +698,7 @@ struct ath_softc { | |||
678 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT | 698 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT |
679 | struct ath_btcoex btcoex; | 699 | struct ath_btcoex btcoex; |
680 | struct ath_mci_coex mci_coex; | 700 | struct ath_mci_coex mci_coex; |
701 | struct work_struct mci_work; | ||
681 | #endif | 702 | #endif |
682 | 703 | ||
683 | struct ath_descdma txsdma; | 704 | struct ath_descdma txsdma; |
@@ -736,5 +757,4 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw, | |||
736 | struct ieee80211_vif *vif, | 757 | struct ieee80211_vif *vif, |
737 | struct ath9k_vif_iter_data *iter_data); | 758 | struct ath9k_vif_iter_data *iter_data); |
738 | 759 | ||
739 | |||
740 | #endif /* ATH9K_H */ | 760 | #endif /* ATH9K_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 626418222c85..40775da8941e 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -48,7 +48,10 @@ int ath_beaconq_config(struct ath_softc *sc) | |||
48 | txq = sc->tx.txq_map[WME_AC_BE]; | 48 | txq = sc->tx.txq_map[WME_AC_BE]; |
49 | ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be); | 49 | ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be); |
50 | qi.tqi_aifs = qi_be.tqi_aifs; | 50 | qi.tqi_aifs = qi_be.tqi_aifs; |
51 | qi.tqi_cwmin = 4*qi_be.tqi_cwmin; | 51 | if (ah->slottime == ATH9K_SLOT_TIME_20) |
52 | qi.tqi_cwmin = 2*qi_be.tqi_cwmin; | ||
53 | else | ||
54 | qi.tqi_cwmin = 4*qi_be.tqi_cwmin; | ||
52 | qi.tqi_cwmax = qi_be.tqi_cwmax; | 55 | qi.tqi_cwmax = qi_be.tqi_cwmax; |
53 | } | 56 | } |
54 | 57 | ||
@@ -91,7 +94,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif, | |||
91 | info.txpower = MAX_RATE_POWER; | 94 | info.txpower = MAX_RATE_POWER; |
92 | info.keyix = ATH9K_TXKEYIX_INVALID; | 95 | info.keyix = ATH9K_TXKEYIX_INVALID; |
93 | info.keytype = ATH9K_KEY_TYPE_CLEAR; | 96 | info.keytype = ATH9K_KEY_TYPE_CLEAR; |
94 | info.flags = ATH9K_TXDESC_NOACK | ATH9K_TXDESC_INTREQ; | 97 | info.flags = ATH9K_TXDESC_NOACK | ATH9K_TXDESC_CLRDMASK; |
95 | 98 | ||
96 | info.buf_addr[0] = bf->bf_buf_addr; | 99 | info.buf_addr[0] = bf->bf_buf_addr; |
97 | info.buf_len[0] = roundup(skb->len, 4); | 100 | info.buf_len[0] = roundup(skb->len, 4); |
@@ -359,6 +362,11 @@ void ath_beacon_tasklet(unsigned long data) | |||
359 | int slot; | 362 | int slot; |
360 | u32 bfaddr, bc = 0; | 363 | u32 bfaddr, bc = 0; |
361 | 364 | ||
365 | if (work_pending(&sc->hw_reset_work)) { | ||
366 | ath_dbg(common, RESET, | ||
367 | "reset work is pending, skip beaconing now\n"); | ||
368 | return; | ||
369 | } | ||
362 | /* | 370 | /* |
363 | * Check if the previous beacon has gone out. If | 371 | * Check if the previous beacon has gone out. If |
364 | * not don't try to post another, skip this period | 372 | * not don't try to post another, skip this period |
@@ -369,6 +377,9 @@ void ath_beacon_tasklet(unsigned long data) | |||
369 | if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) { | 377 | if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) { |
370 | sc->beacon.bmisscnt++; | 378 | sc->beacon.bmisscnt++; |
371 | 379 | ||
380 | if (!ath9k_hw_check_alive(ah)) | ||
381 | ieee80211_queue_work(sc->hw, &sc->hw_check_work); | ||
382 | |||
372 | if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) { | 383 | if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) { |
373 | ath_dbg(common, BSTUCK, | 384 | ath_dbg(common, BSTUCK, |
374 | "missed %u consecutive beacons\n", | 385 | "missed %u consecutive beacons\n", |
@@ -378,7 +389,8 @@ void ath_beacon_tasklet(unsigned long data) | |||
378 | ath9k_hw_bstuck_nfcal(ah); | 389 | ath9k_hw_bstuck_nfcal(ah); |
379 | } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { | 390 | } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { |
380 | ath_dbg(common, BSTUCK, "beacon is officially stuck\n"); | 391 | ath_dbg(common, BSTUCK, "beacon is officially stuck\n"); |
381 | sc->sc_flags |= SC_OP_TSF_RESET; | 392 | sc->beacon.bmisscnt = 0; |
393 | set_bit(SC_OP_TSF_RESET, &sc->sc_flags); | ||
382 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | 394 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); |
383 | } | 395 | } |
384 | 396 | ||
@@ -468,16 +480,16 @@ static void ath9k_beacon_init(struct ath_softc *sc, | |||
468 | u32 next_beacon, | 480 | u32 next_beacon, |
469 | u32 beacon_period) | 481 | u32 beacon_period) |
470 | { | 482 | { |
471 | if (sc->sc_flags & SC_OP_TSF_RESET) { | 483 | if (test_bit(SC_OP_TSF_RESET, &sc->sc_flags)) { |
472 | ath9k_ps_wakeup(sc); | 484 | ath9k_ps_wakeup(sc); |
473 | ath9k_hw_reset_tsf(sc->sc_ah); | 485 | ath9k_hw_reset_tsf(sc->sc_ah); |
474 | } | 486 | } |
475 | 487 | ||
476 | ath9k_hw_beaconinit(sc->sc_ah, next_beacon, beacon_period); | 488 | ath9k_hw_beaconinit(sc->sc_ah, next_beacon, beacon_period); |
477 | 489 | ||
478 | if (sc->sc_flags & SC_OP_TSF_RESET) { | 490 | if (test_bit(SC_OP_TSF_RESET, &sc->sc_flags)) { |
479 | ath9k_ps_restore(sc); | 491 | ath9k_ps_restore(sc); |
480 | sc->sc_flags &= ~SC_OP_TSF_RESET; | 492 | clear_bit(SC_OP_TSF_RESET, &sc->sc_flags); |
481 | } | 493 | } |
482 | } | 494 | } |
483 | 495 | ||
@@ -507,7 +519,7 @@ static void ath_beacon_config_ap(struct ath_softc *sc, | |||
507 | /* Set the computed AP beacon timers */ | 519 | /* Set the computed AP beacon timers */ |
508 | 520 | ||
509 | ath9k_hw_disable_interrupts(ah); | 521 | ath9k_hw_disable_interrupts(ah); |
510 | sc->sc_flags |= SC_OP_TSF_RESET; | 522 | set_bit(SC_OP_TSF_RESET, &sc->sc_flags); |
511 | ath9k_beacon_init(sc, nexttbtt, intval); | 523 | ath9k_beacon_init(sc, nexttbtt, intval); |
512 | sc->beacon.bmisscnt = 0; | 524 | sc->beacon.bmisscnt = 0; |
513 | ath9k_hw_set_interrupts(ah); | 525 | ath9k_hw_set_interrupts(ah); |
@@ -650,6 +662,8 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, | |||
650 | u32 tsf, intval, nexttbtt; | 662 | u32 tsf, intval, nexttbtt; |
651 | 663 | ||
652 | ath9k_reset_beacon_status(sc); | 664 | ath9k_reset_beacon_status(sc); |
665 | if (!test_bit(SC_OP_BEACONS, &sc->sc_flags)) | ||
666 | ath9k_hw_settsf64(ah, sc->beacon.bc_tstamp); | ||
653 | 667 | ||
654 | intval = TU_TO_USEC(conf->beacon_interval); | 668 | intval = TU_TO_USEC(conf->beacon_interval); |
655 | tsf = roundup(ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE), intval); | 669 | tsf = roundup(ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE), intval); |
@@ -713,7 +727,7 @@ static bool ath9k_allow_beacon_config(struct ath_softc *sc, | |||
713 | */ | 727 | */ |
714 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && | 728 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && |
715 | (vif->type == NL80211_IFTYPE_STATION) && | 729 | (vif->type == NL80211_IFTYPE_STATION) && |
716 | (sc->sc_flags & SC_OP_BEACONS) && | 730 | test_bit(SC_OP_BEACONS, &sc->sc_flags) && |
717 | !avp->primary_sta_vif) { | 731 | !avp->primary_sta_vif) { |
718 | ath_dbg(common, CONFIG, | 732 | ath_dbg(common, CONFIG, |
719 | "Beacon already configured for a station interface\n"); | 733 | "Beacon already configured for a station interface\n"); |
@@ -799,15 +813,17 @@ void ath_set_beacon(struct ath_softc *sc) | |||
799 | return; | 813 | return; |
800 | } | 814 | } |
801 | 815 | ||
802 | sc->sc_flags |= SC_OP_BEACONS; | 816 | set_bit(SC_OP_BEACONS, &sc->sc_flags); |
803 | } | 817 | } |
804 | 818 | ||
805 | void ath9k_set_beaconing_status(struct ath_softc *sc, bool status) | 819 | void ath9k_set_beaconing_status(struct ath_softc *sc, bool status) |
806 | { | 820 | { |
807 | struct ath_hw *ah = sc->sc_ah; | 821 | struct ath_hw *ah = sc->sc_ah; |
808 | 822 | ||
809 | if (!ath_has_valid_bslot(sc)) | 823 | if (!ath_has_valid_bslot(sc)) { |
824 | clear_bit(SC_OP_BEACONS, &sc->sc_flags); | ||
810 | return; | 825 | return; |
826 | } | ||
811 | 827 | ||
812 | ath9k_ps_wakeup(sc); | 828 | ath9k_ps_wakeup(sc); |
813 | if (status) { | 829 | if (status) { |
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c index ec3271993411..acd437384fe4 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.c +++ b/drivers/net/wireless/ath/ath9k/btcoex.c | |||
@@ -108,9 +108,7 @@ void ath9k_hw_btcoex_init_scheme(struct ath_hw *ah) | |||
108 | return; | 108 | return; |
109 | } | 109 | } |
110 | 110 | ||
111 | if (AR_SREV_9462(ah)) { | 111 | if (AR_SREV_9300_20_OR_LATER(ah)) { |
112 | btcoex_hw->scheme = ATH_BTCOEX_CFG_MCI; | ||
113 | } else if (AR_SREV_9300_20_OR_LATER(ah)) { | ||
114 | btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE; | 112 | btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE; |
115 | btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9300; | 113 | btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9300; |
116 | btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9300; | 114 | btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9300; |
@@ -284,11 +282,12 @@ void ath9k_hw_btcoex_enable(struct ath_hw *ah) | |||
284 | ath9k_hw_btcoex_enable_2wire(ah); | 282 | ath9k_hw_btcoex_enable_2wire(ah); |
285 | break; | 283 | break; |
286 | case ATH_BTCOEX_CFG_3WIRE: | 284 | case ATH_BTCOEX_CFG_3WIRE: |
285 | if (AR_SREV_9462(ah)) { | ||
286 | ath9k_hw_btcoex_enable_mci(ah); | ||
287 | return; | ||
288 | } | ||
287 | ath9k_hw_btcoex_enable_3wire(ah); | 289 | ath9k_hw_btcoex_enable_3wire(ah); |
288 | break; | 290 | break; |
289 | case ATH_BTCOEX_CFG_MCI: | ||
290 | ath9k_hw_btcoex_enable_mci(ah); | ||
291 | return; | ||
292 | } | 291 | } |
293 | 292 | ||
294 | REG_RMW(ah, AR_GPIO_PDPU, | 293 | REG_RMW(ah, AR_GPIO_PDPU, |
@@ -305,11 +304,12 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah) | |||
305 | int i; | 304 | int i; |
306 | 305 | ||
307 | btcoex_hw->enabled = false; | 306 | btcoex_hw->enabled = false; |
308 | if (btcoex_hw->scheme == ATH_BTCOEX_CFG_MCI) { | 307 | if (AR_SREV_9462(ah)) { |
309 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); | 308 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); |
310 | for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) | 309 | for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) |
311 | REG_WRITE(ah, AR_MCI_COEX_WL_WEIGHTS(i), | 310 | REG_WRITE(ah, AR_MCI_COEX_WL_WEIGHTS(i), |
312 | btcoex_hw->wlan_weight[i]); | 311 | btcoex_hw->wlan_weight[i]); |
312 | return; | ||
313 | } | 313 | } |
314 | ath9k_hw_set_gpio(ah, btcoex_hw->wlanactive_gpio, 0); | 314 | ath9k_hw_set_gpio(ah, btcoex_hw->wlanactive_gpio, 0); |
315 | 315 | ||
@@ -336,10 +336,16 @@ static void ar9003_btcoex_bt_stomp(struct ath_hw *ah, | |||
336 | enum ath_stomp_type stomp_type) | 336 | enum ath_stomp_type stomp_type) |
337 | { | 337 | { |
338 | struct ath_btcoex_hw *btcoex = &ah->btcoex_hw; | 338 | struct ath_btcoex_hw *btcoex = &ah->btcoex_hw; |
339 | const u32 *weight = AR_SREV_9462(ah) ? ar9003_wlan_weights[stomp_type] : | 339 | const u32 *weight = ar9003_wlan_weights[stomp_type]; |
340 | ar9462_wlan_weights[stomp_type]; | ||
341 | int i; | 340 | int i; |
342 | 341 | ||
342 | if (AR_SREV_9462(ah)) { | ||
343 | if ((stomp_type == ATH_BTCOEX_STOMP_LOW) && | ||
344 | btcoex->mci.stomp_ftp) | ||
345 | stomp_type = ATH_BTCOEX_STOMP_LOW_FTP; | ||
346 | weight = ar9462_wlan_weights[stomp_type]; | ||
347 | } | ||
348 | |||
343 | for (i = 0; i < AR9300_NUM_WLAN_WEIGHTS; i++) { | 349 | for (i = 0; i < AR9300_NUM_WLAN_WEIGHTS; i++) { |
344 | btcoex->bt_weight[i] = AR9300_BT_WGHT; | 350 | btcoex->bt_weight[i] = AR9300_BT_WGHT; |
345 | btcoex->wlan_weight[i] = weight[i]; | 351 | btcoex->wlan_weight[i] = weight[i]; |
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h index 8f93aef4414f..20092f98658f 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.h +++ b/drivers/net/wireless/ath/ath9k/btcoex.h | |||
@@ -36,6 +36,9 @@ | |||
36 | #define ATH_BT_CNT_THRESHOLD 3 | 36 | #define ATH_BT_CNT_THRESHOLD 3 |
37 | #define ATH_BT_CNT_SCAN_THRESHOLD 15 | 37 | #define ATH_BT_CNT_SCAN_THRESHOLD 15 |
38 | 38 | ||
39 | #define ATH_BTCOEX_RX_WAIT_TIME 100 | ||
40 | #define ATH_BTCOEX_STOMP_FTP_THRESH 5 | ||
41 | |||
39 | #define AR9300_NUM_BT_WEIGHTS 4 | 42 | #define AR9300_NUM_BT_WEIGHTS 4 |
40 | #define AR9300_NUM_WLAN_WEIGHTS 4 | 43 | #define AR9300_NUM_WLAN_WEIGHTS 4 |
41 | /* Defines the BT AR_BT_COEX_WGHT used */ | 44 | /* Defines the BT AR_BT_COEX_WGHT used */ |
@@ -51,7 +54,6 @@ enum ath_btcoex_scheme { | |||
51 | ATH_BTCOEX_CFG_NONE, | 54 | ATH_BTCOEX_CFG_NONE, |
52 | ATH_BTCOEX_CFG_2WIRE, | 55 | ATH_BTCOEX_CFG_2WIRE, |
53 | ATH_BTCOEX_CFG_3WIRE, | 56 | ATH_BTCOEX_CFG_3WIRE, |
54 | ATH_BTCOEX_CFG_MCI, | ||
55 | }; | 57 | }; |
56 | 58 | ||
57 | struct ath9k_hw_mci { | 59 | struct ath9k_hw_mci { |
@@ -81,6 +83,7 @@ struct ath9k_hw_mci { | |||
81 | u8 bt_ver_major; | 83 | u8 bt_ver_major; |
82 | u8 bt_ver_minor; | 84 | u8 bt_ver_minor; |
83 | u8 bt_state; | 85 | u8 bt_state; |
86 | u8 stomp_ftp; | ||
84 | }; | 87 | }; |
85 | 88 | ||
86 | struct ath_btcoex_hw { | 89 | struct ath_btcoex_hw { |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 244723a3ed41..2831258d9507 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -26,11 +26,6 @@ | |||
26 | #define REG_READ_D(_ah, _reg) \ | 26 | #define REG_READ_D(_ah, _reg) \ |
27 | ath9k_hw_common(_ah)->ops->read((_ah), (_reg)) | 27 | ath9k_hw_common(_ah)->ops->read((_ah), (_reg)) |
28 | 28 | ||
29 | static int ath9k_debugfs_open(struct inode *inode, struct file *file) | ||
30 | { | ||
31 | file->private_data = inode->i_private; | ||
32 | return 0; | ||
33 | } | ||
34 | 29 | ||
35 | static ssize_t ath9k_debugfs_read_buf(struct file *file, char __user *user_buf, | 30 | static ssize_t ath9k_debugfs_read_buf(struct file *file, char __user *user_buf, |
36 | size_t count, loff_t *ppos) | 31 | size_t count, loff_t *ppos) |
@@ -83,7 +78,7 @@ static ssize_t write_file_debug(struct file *file, const char __user *user_buf, | |||
83 | static const struct file_operations fops_debug = { | 78 | static const struct file_operations fops_debug = { |
84 | .read = read_file_debug, | 79 | .read = read_file_debug, |
85 | .write = write_file_debug, | 80 | .write = write_file_debug, |
86 | .open = ath9k_debugfs_open, | 81 | .open = simple_open, |
87 | .owner = THIS_MODULE, | 82 | .owner = THIS_MODULE, |
88 | .llseek = default_llseek, | 83 | .llseek = default_llseek, |
89 | }; | 84 | }; |
@@ -129,7 +124,7 @@ static ssize_t write_file_tx_chainmask(struct file *file, const char __user *use | |||
129 | static const struct file_operations fops_tx_chainmask = { | 124 | static const struct file_operations fops_tx_chainmask = { |
130 | .read = read_file_tx_chainmask, | 125 | .read = read_file_tx_chainmask, |
131 | .write = write_file_tx_chainmask, | 126 | .write = write_file_tx_chainmask, |
132 | .open = ath9k_debugfs_open, | 127 | .open = simple_open, |
133 | .owner = THIS_MODULE, | 128 | .owner = THIS_MODULE, |
134 | .llseek = default_llseek, | 129 | .llseek = default_llseek, |
135 | }; | 130 | }; |
@@ -172,7 +167,7 @@ static ssize_t write_file_rx_chainmask(struct file *file, const char __user *use | |||
172 | static const struct file_operations fops_rx_chainmask = { | 167 | static const struct file_operations fops_rx_chainmask = { |
173 | .read = read_file_rx_chainmask, | 168 | .read = read_file_rx_chainmask, |
174 | .write = write_file_rx_chainmask, | 169 | .write = write_file_rx_chainmask, |
175 | .open = ath9k_debugfs_open, | 170 | .open = simple_open, |
176 | .owner = THIS_MODULE, | 171 | .owner = THIS_MODULE, |
177 | .llseek = default_llseek, | 172 | .llseek = default_llseek, |
178 | }; | 173 | }; |
@@ -210,10 +205,10 @@ static ssize_t write_file_disable_ani(struct file *file, | |||
210 | common->disable_ani = !!disable_ani; | 205 | common->disable_ani = !!disable_ani; |
211 | 206 | ||
212 | if (disable_ani) { | 207 | if (disable_ani) { |
213 | sc->sc_flags &= ~SC_OP_ANI_RUN; | 208 | clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); |
214 | del_timer_sync(&common->ani.timer); | 209 | del_timer_sync(&common->ani.timer); |
215 | } else { | 210 | } else { |
216 | sc->sc_flags |= SC_OP_ANI_RUN; | 211 | set_bit(SC_OP_ANI_RUN, &sc->sc_flags); |
217 | ath_start_ani(common); | 212 | ath_start_ani(common); |
218 | } | 213 | } |
219 | 214 | ||
@@ -223,7 +218,7 @@ static ssize_t write_file_disable_ani(struct file *file, | |||
223 | static const struct file_operations fops_disable_ani = { | 218 | static const struct file_operations fops_disable_ani = { |
224 | .read = read_file_disable_ani, | 219 | .read = read_file_disable_ani, |
225 | .write = write_file_disable_ani, | 220 | .write = write_file_disable_ani, |
226 | .open = ath9k_debugfs_open, | 221 | .open = simple_open, |
227 | .owner = THIS_MODULE, | 222 | .owner = THIS_MODULE, |
228 | .llseek = default_llseek, | 223 | .llseek = default_llseek, |
229 | }; | 224 | }; |
@@ -324,7 +319,7 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf, | |||
324 | 319 | ||
325 | static const struct file_operations fops_dma = { | 320 | static const struct file_operations fops_dma = { |
326 | .read = read_file_dma, | 321 | .read = read_file_dma, |
327 | .open = ath9k_debugfs_open, | 322 | .open = simple_open, |
328 | .owner = THIS_MODULE, | 323 | .owner = THIS_MODULE, |
329 | .llseek = default_llseek, | 324 | .llseek = default_llseek, |
330 | }; | 325 | }; |
@@ -379,74 +374,89 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status) | |||
379 | sc->debug.stats.istats.dtim++; | 374 | sc->debug.stats.istats.dtim++; |
380 | if (status & ATH9K_INT_TSFOOR) | 375 | if (status & ATH9K_INT_TSFOOR) |
381 | sc->debug.stats.istats.tsfoor++; | 376 | sc->debug.stats.istats.tsfoor++; |
377 | if (status & ATH9K_INT_MCI) | ||
378 | sc->debug.stats.istats.mci++; | ||
382 | } | 379 | } |
383 | 380 | ||
384 | static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, | 381 | static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, |
385 | size_t count, loff_t *ppos) | 382 | size_t count, loff_t *ppos) |
386 | { | 383 | { |
387 | struct ath_softc *sc = file->private_data; | 384 | struct ath_softc *sc = file->private_data; |
388 | char buf[512]; | ||
389 | unsigned int len = 0; | 385 | unsigned int len = 0; |
386 | int rv; | ||
387 | int mxlen = 4000; | ||
388 | char *buf = kmalloc(mxlen, GFP_KERNEL); | ||
389 | if (!buf) | ||
390 | return -ENOMEM; | ||
391 | |||
392 | #define PR_IS(a, s) \ | ||
393 | do { \ | ||
394 | len += snprintf(buf + len, mxlen - len, \ | ||
395 | "%21s: %10u\n", a, \ | ||
396 | sc->debug.stats.istats.s); \ | ||
397 | } while (0) | ||
390 | 398 | ||
391 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | 399 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { |
392 | len += snprintf(buf + len, sizeof(buf) - len, | 400 | PR_IS("RXLP", rxlp); |
393 | "%8s: %10u\n", "RXLP", sc->debug.stats.istats.rxlp); | 401 | PR_IS("RXHP", rxhp); |
394 | len += snprintf(buf + len, sizeof(buf) - len, | 402 | PR_IS("WATHDOG", bb_watchdog); |
395 | "%8s: %10u\n", "RXHP", sc->debug.stats.istats.rxhp); | ||
396 | len += snprintf(buf + len, sizeof(buf) - len, | ||
397 | "%8s: %10u\n", "WATCHDOG", | ||
398 | sc->debug.stats.istats.bb_watchdog); | ||
399 | } else { | 403 | } else { |
400 | len += snprintf(buf + len, sizeof(buf) - len, | 404 | PR_IS("RX", rxok); |
401 | "%8s: %10u\n", "RX", sc->debug.stats.istats.rxok); | ||
402 | } | 405 | } |
403 | len += snprintf(buf + len, sizeof(buf) - len, | 406 | PR_IS("RXEOL", rxeol); |
404 | "%8s: %10u\n", "RXEOL", sc->debug.stats.istats.rxeol); | 407 | PR_IS("RXORN", rxorn); |
405 | len += snprintf(buf + len, sizeof(buf) - len, | 408 | PR_IS("TX", txok); |
406 | "%8s: %10u\n", "RXORN", sc->debug.stats.istats.rxorn); | 409 | PR_IS("TXURN", txurn); |
407 | len += snprintf(buf + len, sizeof(buf) - len, | 410 | PR_IS("MIB", mib); |
408 | "%8s: %10u\n", "TX", sc->debug.stats.istats.txok); | 411 | PR_IS("RXPHY", rxphyerr); |
409 | len += snprintf(buf + len, sizeof(buf) - len, | 412 | PR_IS("RXKCM", rx_keycache_miss); |
410 | "%8s: %10u\n", "TXURN", sc->debug.stats.istats.txurn); | 413 | PR_IS("SWBA", swba); |
411 | len += snprintf(buf + len, sizeof(buf) - len, | 414 | PR_IS("BMISS", bmiss); |
412 | "%8s: %10u\n", "MIB", sc->debug.stats.istats.mib); | 415 | PR_IS("BNR", bnr); |
413 | len += snprintf(buf + len, sizeof(buf) - len, | 416 | PR_IS("CST", cst); |
414 | "%8s: %10u\n", "RXPHY", sc->debug.stats.istats.rxphyerr); | 417 | PR_IS("GTT", gtt); |
415 | len += snprintf(buf + len, sizeof(buf) - len, | 418 | PR_IS("TIM", tim); |
416 | "%8s: %10u\n", "RXKCM", sc->debug.stats.istats.rx_keycache_miss); | 419 | PR_IS("CABEND", cabend); |
417 | len += snprintf(buf + len, sizeof(buf) - len, | 420 | PR_IS("DTIMSYNC", dtimsync); |
418 | "%8s: %10u\n", "SWBA", sc->debug.stats.istats.swba); | 421 | PR_IS("DTIM", dtim); |
419 | len += snprintf(buf + len, sizeof(buf) - len, | 422 | PR_IS("TSFOOR", tsfoor); |
420 | "%8s: %10u\n", "BMISS", sc->debug.stats.istats.bmiss); | 423 | PR_IS("MCI", mci); |
421 | len += snprintf(buf + len, sizeof(buf) - len, | 424 | PR_IS("TOTAL", total); |
422 | "%8s: %10u\n", "BNR", sc->debug.stats.istats.bnr); | 425 | |
423 | len += snprintf(buf + len, sizeof(buf) - len, | 426 | len += snprintf(buf + len, mxlen - len, |
424 | "%8s: %10u\n", "CST", sc->debug.stats.istats.cst); | 427 | "SYNC_CAUSE stats:\n"); |
425 | len += snprintf(buf + len, sizeof(buf) - len, | 428 | |
426 | "%8s: %10u\n", "GTT", sc->debug.stats.istats.gtt); | 429 | PR_IS("Sync-All", sync_cause_all); |
427 | len += snprintf(buf + len, sizeof(buf) - len, | 430 | PR_IS("RTC-IRQ", sync_rtc_irq); |
428 | "%8s: %10u\n", "TIM", sc->debug.stats.istats.tim); | 431 | PR_IS("MAC-IRQ", sync_mac_irq); |
429 | len += snprintf(buf + len, sizeof(buf) - len, | 432 | PR_IS("EEPROM-Illegal-Access", eeprom_illegal_access); |
430 | "%8s: %10u\n", "CABEND", sc->debug.stats.istats.cabend); | 433 | PR_IS("APB-Timeout", apb_timeout); |
431 | len += snprintf(buf + len, sizeof(buf) - len, | 434 | PR_IS("PCI-Mode-Conflict", pci_mode_conflict); |
432 | "%8s: %10u\n", "DTIMSYNC", sc->debug.stats.istats.dtimsync); | 435 | PR_IS("HOST1-Fatal", host1_fatal); |
433 | len += snprintf(buf + len, sizeof(buf) - len, | 436 | PR_IS("HOST1-Perr", host1_perr); |
434 | "%8s: %10u\n", "DTIM", sc->debug.stats.istats.dtim); | 437 | PR_IS("TRCV-FIFO-Perr", trcv_fifo_perr); |
435 | len += snprintf(buf + len, sizeof(buf) - len, | 438 | PR_IS("RADM-CPL-EP", radm_cpl_ep); |
436 | "%8s: %10u\n", "TSFOOR", sc->debug.stats.istats.tsfoor); | 439 | PR_IS("RADM-CPL-DLLP-Abort", radm_cpl_dllp_abort); |
437 | len += snprintf(buf + len, sizeof(buf) - len, | 440 | PR_IS("RADM-CPL-TLP-Abort", radm_cpl_tlp_abort); |
438 | "%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total); | 441 | PR_IS("RADM-CPL-ECRC-Err", radm_cpl_ecrc_err); |
439 | 442 | PR_IS("RADM-CPL-Timeout", radm_cpl_timeout); | |
440 | 443 | PR_IS("Local-Bus-Timeout", local_timeout); | |
441 | if (len > sizeof(buf)) | 444 | PR_IS("PM-Access", pm_access); |
442 | len = sizeof(buf); | 445 | PR_IS("MAC-Awake", mac_awake); |
443 | 446 | PR_IS("MAC-Asleep", mac_asleep); | |
444 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | 447 | PR_IS("MAC-Sleep-Access", mac_sleep_access); |
448 | |||
449 | if (len > mxlen) | ||
450 | len = mxlen; | ||
451 | |||
452 | rv = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
453 | kfree(buf); | ||
454 | return rv; | ||
445 | } | 455 | } |
446 | 456 | ||
447 | static const struct file_operations fops_interrupt = { | 457 | static const struct file_operations fops_interrupt = { |
448 | .read = read_file_interrupt, | 458 | .read = read_file_interrupt, |
449 | .open = ath9k_debugfs_open, | 459 | .open = simple_open, |
450 | .owner = THIS_MODULE, | 460 | .owner = THIS_MODULE, |
451 | .llseek = default_llseek, | 461 | .llseek = default_llseek, |
452 | }; | 462 | }; |
@@ -853,28 +863,28 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, | |||
853 | 863 | ||
854 | static const struct file_operations fops_xmit = { | 864 | static const struct file_operations fops_xmit = { |
855 | .read = read_file_xmit, | 865 | .read = read_file_xmit, |
856 | .open = ath9k_debugfs_open, | 866 | .open = simple_open, |
857 | .owner = THIS_MODULE, | 867 | .owner = THIS_MODULE, |
858 | .llseek = default_llseek, | 868 | .llseek = default_llseek, |
859 | }; | 869 | }; |
860 | 870 | ||
861 | static const struct file_operations fops_stations = { | 871 | static const struct file_operations fops_stations = { |
862 | .read = read_file_stations, | 872 | .read = read_file_stations, |
863 | .open = ath9k_debugfs_open, | 873 | .open = simple_open, |
864 | .owner = THIS_MODULE, | 874 | .owner = THIS_MODULE, |
865 | .llseek = default_llseek, | 875 | .llseek = default_llseek, |
866 | }; | 876 | }; |
867 | 877 | ||
868 | static const struct file_operations fops_misc = { | 878 | static const struct file_operations fops_misc = { |
869 | .read = read_file_misc, | 879 | .read = read_file_misc, |
870 | .open = ath9k_debugfs_open, | 880 | .open = simple_open, |
871 | .owner = THIS_MODULE, | 881 | .owner = THIS_MODULE, |
872 | .llseek = default_llseek, | 882 | .llseek = default_llseek, |
873 | }; | 883 | }; |
874 | 884 | ||
875 | static const struct file_operations fops_reset = { | 885 | static const struct file_operations fops_reset = { |
876 | .read = read_file_reset, | 886 | .read = read_file_reset, |
877 | .open = ath9k_debugfs_open, | 887 | .open = simple_open, |
878 | .owner = THIS_MODULE, | 888 | .owner = THIS_MODULE, |
879 | .llseek = default_llseek, | 889 | .llseek = default_llseek, |
880 | }; | 890 | }; |
@@ -886,6 +896,13 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, | |||
886 | len += snprintf(buf + len, size - len, "%22s : %10u\n", s, \ | 896 | len += snprintf(buf + len, size - len, "%22s : %10u\n", s, \ |
887 | sc->debug.stats.rxstats.phy_err_stats[p]); | 897 | sc->debug.stats.rxstats.phy_err_stats[p]); |
888 | 898 | ||
899 | #define RXS_ERR(s, e) \ | ||
900 | do { \ | ||
901 | len += snprintf(buf + len, size - len, \ | ||
902 | "%22s : %10u\n", s, \ | ||
903 | sc->debug.stats.rxstats.e); \ | ||
904 | } while (0) | ||
905 | |||
889 | struct ath_softc *sc = file->private_data; | 906 | struct ath_softc *sc = file->private_data; |
890 | char *buf; | 907 | char *buf; |
891 | unsigned int len = 0, size = 1600; | 908 | unsigned int len = 0, size = 1600; |
@@ -895,42 +912,18 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, | |||
895 | if (buf == NULL) | 912 | if (buf == NULL) |
896 | return -ENOMEM; | 913 | return -ENOMEM; |
897 | 914 | ||
898 | len += snprintf(buf + len, size - len, | 915 | RXS_ERR("CRC ERR", crc_err); |
899 | "%22s : %10u\n", "CRC ERR", | 916 | RXS_ERR("DECRYPT CRC ERR", decrypt_crc_err); |
900 | sc->debug.stats.rxstats.crc_err); | 917 | RXS_ERR("PHY ERR", phy_err); |
901 | len += snprintf(buf + len, size - len, | 918 | RXS_ERR("MIC ERR", mic_err); |
902 | "%22s : %10u\n", "DECRYPT CRC ERR", | 919 | RXS_ERR("PRE-DELIM CRC ERR", pre_delim_crc_err); |
903 | sc->debug.stats.rxstats.decrypt_crc_err); | 920 | RXS_ERR("POST-DELIM CRC ERR", post_delim_crc_err); |
904 | len += snprintf(buf + len, size - len, | 921 | RXS_ERR("DECRYPT BUSY ERR", decrypt_busy_err); |
905 | "%22s : %10u\n", "PHY ERR", | 922 | RXS_ERR("RX-LENGTH-ERR", rx_len_err); |
906 | sc->debug.stats.rxstats.phy_err); | 923 | RXS_ERR("RX-OOM-ERR", rx_oom_err); |
907 | len += snprintf(buf + len, size - len, | 924 | RXS_ERR("RX-RATE-ERR", rx_rate_err); |
908 | "%22s : %10u\n", "MIC ERR", | 925 | RXS_ERR("RX-DROP-RXFLUSH", rx_drop_rxflush); |
909 | sc->debug.stats.rxstats.mic_err); | 926 | RXS_ERR("RX-TOO-MANY-FRAGS", rx_too_many_frags_err); |
910 | len += snprintf(buf + len, size - len, | ||
911 | "%22s : %10u\n", "PRE-DELIM CRC ERR", | ||
912 | sc->debug.stats.rxstats.pre_delim_crc_err); | ||
913 | len += snprintf(buf + len, size - len, | ||
914 | "%22s : %10u\n", "POST-DELIM CRC ERR", | ||
915 | sc->debug.stats.rxstats.post_delim_crc_err); | ||
916 | len += snprintf(buf + len, size - len, | ||
917 | "%22s : %10u\n", "DECRYPT BUSY ERR", | ||
918 | sc->debug.stats.rxstats.decrypt_busy_err); | ||
919 | len += snprintf(buf + len, size - len, | ||
920 | "%22s : %10u\n", "RX-LENGTH-ERR", | ||
921 | sc->debug.stats.rxstats.rx_len_err); | ||
922 | len += snprintf(buf + len, size - len, | ||
923 | "%22s : %10u\n", "RX-OOM-ERR", | ||
924 | sc->debug.stats.rxstats.rx_oom_err); | ||
925 | len += snprintf(buf + len, size - len, | ||
926 | "%22s : %10u\n", "RX-RATE-ERR", | ||
927 | sc->debug.stats.rxstats.rx_rate_err); | ||
928 | len += snprintf(buf + len, size - len, | ||
929 | "%22s : %10u\n", "RX-DROP-RXFLUSH", | ||
930 | sc->debug.stats.rxstats.rx_drop_rxflush); | ||
931 | len += snprintf(buf + len, size - len, | ||
932 | "%22s : %10u\n", "RX-TOO-MANY-FRAGS", | ||
933 | sc->debug.stats.rxstats.rx_too_many_frags_err); | ||
934 | 927 | ||
935 | PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN); | 928 | PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN); |
936 | PHY_ERR("TIMING ERR", ATH9K_PHYERR_TIMING); | 929 | PHY_ERR("TIMING ERR", ATH9K_PHYERR_TIMING); |
@@ -959,18 +952,10 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, | |||
959 | PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL); | 952 | PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL); |
960 | PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL); | 953 | PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL); |
961 | 954 | ||
962 | len += snprintf(buf + len, size - len, | 955 | RXS_ERR("RX-Pkts-All", rx_pkts_all); |
963 | "%22s : %10u\n", "RX-Pkts-All", | 956 | RXS_ERR("RX-Bytes-All", rx_bytes_all); |
964 | sc->debug.stats.rxstats.rx_pkts_all); | 957 | RXS_ERR("RX-Beacons", rx_beacons); |
965 | len += snprintf(buf + len, size - len, | 958 | RXS_ERR("RX-Frags", rx_frags); |
966 | "%22s : %10u\n", "RX-Bytes-All", | ||
967 | sc->debug.stats.rxstats.rx_bytes_all); | ||
968 | len += snprintf(buf + len, size - len, | ||
969 | "%22s : %10u\n", "RX-Beacons", | ||
970 | sc->debug.stats.rxstats.rx_beacons); | ||
971 | len += snprintf(buf + len, size - len, | ||
972 | "%22s : %10u\n", "RX-Frags", | ||
973 | sc->debug.stats.rxstats.rx_frags); | ||
974 | 959 | ||
975 | if (len > size) | 960 | if (len > size) |
976 | len = size; | 961 | len = size; |
@@ -980,6 +965,7 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, | |||
980 | 965 | ||
981 | return retval; | 966 | return retval; |
982 | 967 | ||
968 | #undef RXS_ERR | ||
983 | #undef PHY_ERR | 969 | #undef PHY_ERR |
984 | } | 970 | } |
985 | 971 | ||
@@ -1036,7 +1022,7 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) | |||
1036 | 1022 | ||
1037 | static const struct file_operations fops_recv = { | 1023 | static const struct file_operations fops_recv = { |
1038 | .read = read_file_recv, | 1024 | .read = read_file_recv, |
1039 | .open = ath9k_debugfs_open, | 1025 | .open = simple_open, |
1040 | .owner = THIS_MODULE, | 1026 | .owner = THIS_MODULE, |
1041 | .llseek = default_llseek, | 1027 | .llseek = default_llseek, |
1042 | }; | 1028 | }; |
@@ -1075,7 +1061,7 @@ static ssize_t write_file_regidx(struct file *file, const char __user *user_buf, | |||
1075 | static const struct file_operations fops_regidx = { | 1061 | static const struct file_operations fops_regidx = { |
1076 | .read = read_file_regidx, | 1062 | .read = read_file_regidx, |
1077 | .write = write_file_regidx, | 1063 | .write = write_file_regidx, |
1078 | .open = ath9k_debugfs_open, | 1064 | .open = simple_open, |
1079 | .owner = THIS_MODULE, | 1065 | .owner = THIS_MODULE, |
1080 | .llseek = default_llseek, | 1066 | .llseek = default_llseek, |
1081 | }; | 1067 | }; |
@@ -1122,7 +1108,7 @@ static ssize_t write_file_regval(struct file *file, const char __user *user_buf, | |||
1122 | static const struct file_operations fops_regval = { | 1108 | static const struct file_operations fops_regval = { |
1123 | .read = read_file_regval, | 1109 | .read = read_file_regval, |
1124 | .write = write_file_regval, | 1110 | .write = write_file_regval, |
1125 | .open = ath9k_debugfs_open, | 1111 | .open = simple_open, |
1126 | .owner = THIS_MODULE, | 1112 | .owner = THIS_MODULE, |
1127 | .llseek = default_llseek, | 1113 | .llseek = default_llseek, |
1128 | }; | 1114 | }; |
@@ -1211,7 +1197,7 @@ static ssize_t read_file_dump_nfcal(struct file *file, char __user *user_buf, | |||
1211 | 1197 | ||
1212 | static const struct file_operations fops_dump_nfcal = { | 1198 | static const struct file_operations fops_dump_nfcal = { |
1213 | .read = read_file_dump_nfcal, | 1199 | .read = read_file_dump_nfcal, |
1214 | .open = ath9k_debugfs_open, | 1200 | .open = simple_open, |
1215 | .owner = THIS_MODULE, | 1201 | .owner = THIS_MODULE, |
1216 | .llseek = default_llseek, | 1202 | .llseek = default_llseek, |
1217 | }; | 1203 | }; |
@@ -1239,7 +1225,7 @@ static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf, | |||
1239 | 1225 | ||
1240 | static const struct file_operations fops_base_eeprom = { | 1226 | static const struct file_operations fops_base_eeprom = { |
1241 | .read = read_file_base_eeprom, | 1227 | .read = read_file_base_eeprom, |
1242 | .open = ath9k_debugfs_open, | 1228 | .open = simple_open, |
1243 | .owner = THIS_MODULE, | 1229 | .owner = THIS_MODULE, |
1244 | .llseek = default_llseek, | 1230 | .llseek = default_llseek, |
1245 | }; | 1231 | }; |
@@ -1267,7 +1253,7 @@ static ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf, | |||
1267 | 1253 | ||
1268 | static const struct file_operations fops_modal_eeprom = { | 1254 | static const struct file_operations fops_modal_eeprom = { |
1269 | .read = read_file_modal_eeprom, | 1255 | .read = read_file_modal_eeprom, |
1270 | .open = ath9k_debugfs_open, | 1256 | .open = simple_open, |
1271 | .owner = THIS_MODULE, | 1257 | .owner = THIS_MODULE, |
1272 | .llseek = default_llseek, | 1258 | .llseek = default_llseek, |
1273 | }; | 1259 | }; |
@@ -1335,7 +1321,7 @@ static int open_file_bb_mac_samps(struct inode *inode, struct file *file) | |||
1335 | u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; | 1321 | u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; |
1336 | u8 nread; | 1322 | u8 nread; |
1337 | 1323 | ||
1338 | if (sc->sc_flags & SC_OP_INVALID) | 1324 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) |
1339 | return -EAGAIN; | 1325 | return -EAGAIN; |
1340 | 1326 | ||
1341 | buf = vmalloc(size); | 1327 | buf = vmalloc(size); |
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 17f6cc27af32..d0f851cea43a 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
@@ -60,6 +60,7 @@ struct ath_buf; | |||
60 | * @tsfoor: TSF out of range, indicates that the corrected TSF received | 60 | * @tsfoor: TSF out of range, indicates that the corrected TSF received |
61 | * from a beacon differs from the PCU's internal TSF by more than a | 61 | * from a beacon differs from the PCU's internal TSF by more than a |
62 | * (programmable) threshold | 62 | * (programmable) threshold |
63 | * @local_timeout: Internal bus timeout. | ||
63 | */ | 64 | */ |
64 | struct ath_interrupt_stats { | 65 | struct ath_interrupt_stats { |
65 | u32 total; | 66 | u32 total; |
@@ -85,8 +86,31 @@ struct ath_interrupt_stats { | |||
85 | u32 dtim; | 86 | u32 dtim; |
86 | u32 bb_watchdog; | 87 | u32 bb_watchdog; |
87 | u32 tsfoor; | 88 | u32 tsfoor; |
89 | u32 mci; | ||
90 | |||
91 | /* Sync-cause stats */ | ||
92 | u32 sync_cause_all; | ||
93 | u32 sync_rtc_irq; | ||
94 | u32 sync_mac_irq; | ||
95 | u32 eeprom_illegal_access; | ||
96 | u32 apb_timeout; | ||
97 | u32 pci_mode_conflict; | ||
98 | u32 host1_fatal; | ||
99 | u32 host1_perr; | ||
100 | u32 trcv_fifo_perr; | ||
101 | u32 radm_cpl_ep; | ||
102 | u32 radm_cpl_dllp_abort; | ||
103 | u32 radm_cpl_tlp_abort; | ||
104 | u32 radm_cpl_ecrc_err; | ||
105 | u32 radm_cpl_timeout; | ||
106 | u32 local_timeout; | ||
107 | u32 pm_access; | ||
108 | u32 mac_awake; | ||
109 | u32 mac_asleep; | ||
110 | u32 mac_sleep_access; | ||
88 | }; | 111 | }; |
89 | 112 | ||
113 | |||
90 | /** | 114 | /** |
91 | * struct ath_tx_stats - Statistics about TX | 115 | * struct ath_tx_stats - Statistics about TX |
92 | * @tx_pkts_all: No. of total frames transmitted, including ones that | 116 | * @tx_pkts_all: No. of total frames transmitted, including ones that |
diff --git a/drivers/net/wireless/ath/ath9k/dfs.c b/drivers/net/wireless/ath/ath9k/dfs.c index 92891f5fd454..ecc81792f2dc 100644 --- a/drivers/net/wireless/ath/ath9k/dfs.c +++ b/drivers/net/wireless/ath/ath9k/dfs.c | |||
@@ -148,11 +148,13 @@ void ath9k_dfs_process_phyerr(struct ath_softc *sc, void *data, | |||
148 | struct ath_hw *ah = sc->sc_ah; | 148 | struct ath_hw *ah = sc->sc_ah; |
149 | struct ath_common *common = ath9k_hw_common(ah); | 149 | struct ath_common *common = ath9k_hw_common(ah); |
150 | 150 | ||
151 | DFS_STAT_INC(sc, pulses_total); | ||
151 | if ((rs->rs_phyerr != ATH9K_PHYERR_RADAR) && | 152 | if ((rs->rs_phyerr != ATH9K_PHYERR_RADAR) && |
152 | (rs->rs_phyerr != ATH9K_PHYERR_FALSE_RADAR_EXT)) { | 153 | (rs->rs_phyerr != ATH9K_PHYERR_FALSE_RADAR_EXT)) { |
153 | ath_dbg(common, DFS, | 154 | ath_dbg(common, DFS, |
154 | "Error: rs_phyer=0x%x not a radar error\n", | 155 | "Error: rs_phyer=0x%x not a radar error\n", |
155 | rs->rs_phyerr); | 156 | rs->rs_phyerr); |
157 | DFS_STAT_INC(sc, pulses_no_dfs); | ||
156 | return; | 158 | return; |
157 | } | 159 | } |
158 | 160 | ||
@@ -188,7 +190,9 @@ void ath9k_dfs_process_phyerr(struct ath_softc *sc, void *data, | |||
188 | "width=%d, rssi=%d, delta_ts=%llu\n", | 190 | "width=%d, rssi=%d, delta_ts=%llu\n", |
189 | pe.freq, pe.ts, pe.width, pe.rssi, pe.ts-last_ts); | 191 | pe.freq, pe.ts, pe.width, pe.rssi, pe.ts-last_ts); |
190 | last_ts = pe.ts; | 192 | last_ts = pe.ts; |
193 | DFS_STAT_INC(sc, pulses_processed); | ||
191 | if (pd != NULL && pd->add_pulse(pd, &pe)) { | 194 | if (pd != NULL && pd->add_pulse(pd, &pe)) { |
195 | DFS_STAT_INC(sc, radar_detected); | ||
192 | /* | 196 | /* |
193 | * TODO: forward radar event to DFS management layer | 197 | * TODO: forward radar event to DFS management layer |
194 | */ | 198 | */ |
diff --git a/drivers/net/wireless/ath/ath9k/dfs_debug.c b/drivers/net/wireless/ath/ath9k/dfs_debug.c index 106d031d834a..55d28072adeb 100644 --- a/drivers/net/wireless/ath/ath9k/dfs_debug.c +++ b/drivers/net/wireless/ath/ath9k/dfs_debug.c | |||
@@ -21,9 +21,15 @@ | |||
21 | #include "ath9k.h" | 21 | #include "ath9k.h" |
22 | #include "dfs_debug.h" | 22 | #include "dfs_debug.h" |
23 | 23 | ||
24 | |||
25 | struct ath_dfs_pool_stats global_dfs_pool_stats = { 0 }; | ||
26 | |||
24 | #define ATH9K_DFS_STAT(s, p) \ | 27 | #define ATH9K_DFS_STAT(s, p) \ |
25 | len += snprintf(buf + len, size - len, "%28s : %10u\n", s, \ | 28 | len += snprintf(buf + len, size - len, "%28s : %10u\n", s, \ |
26 | sc->debug.stats.dfs_stats.p); | 29 | sc->debug.stats.dfs_stats.p); |
30 | #define ATH9K_DFS_POOL_STAT(s, p) \ | ||
31 | len += snprintf(buf + len, size - len, "%28s : %10u\n", s, \ | ||
32 | global_dfs_pool_stats.p); | ||
27 | 33 | ||
28 | static ssize_t read_file_dfs(struct file *file, char __user *user_buf, | 34 | static ssize_t read_file_dfs(struct file *file, char __user *user_buf, |
29 | size_t count, loff_t *ppos) | 35 | size_t count, loff_t *ppos) |
@@ -43,6 +49,9 @@ static ssize_t read_file_dfs(struct file *file, char __user *user_buf, | |||
43 | hw_ver->macVersion, hw_ver->macRev, | 49 | hw_ver->macVersion, hw_ver->macRev, |
44 | (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_DFS) ? | 50 | (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_DFS) ? |
45 | "enabled" : "disabled"); | 51 | "enabled" : "disabled"); |
52 | len += snprintf(buf + len, size - len, "Pulse detector statistics:\n"); | ||
53 | ATH9K_DFS_STAT("pulse events reported ", pulses_total); | ||
54 | ATH9K_DFS_STAT("invalid pulse events ", pulses_no_dfs); | ||
46 | ATH9K_DFS_STAT("DFS pulses detected ", pulses_detected); | 55 | ATH9K_DFS_STAT("DFS pulses detected ", pulses_detected); |
47 | ATH9K_DFS_STAT("Datalen discards ", datalen_discards); | 56 | ATH9K_DFS_STAT("Datalen discards ", datalen_discards); |
48 | ATH9K_DFS_STAT("RSSI discards ", rssi_discards); | 57 | ATH9K_DFS_STAT("RSSI discards ", rssi_discards); |
@@ -50,6 +59,18 @@ static ssize_t read_file_dfs(struct file *file, char __user *user_buf, | |||
50 | ATH9K_DFS_STAT("Primary channel pulses ", pri_phy_errors); | 59 | ATH9K_DFS_STAT("Primary channel pulses ", pri_phy_errors); |
51 | ATH9K_DFS_STAT("Secondary channel pulses", ext_phy_errors); | 60 | ATH9K_DFS_STAT("Secondary channel pulses", ext_phy_errors); |
52 | ATH9K_DFS_STAT("Dual channel pulses ", dc_phy_errors); | 61 | ATH9K_DFS_STAT("Dual channel pulses ", dc_phy_errors); |
62 | len += snprintf(buf + len, size - len, "Radar detector statistics " | ||
63 | "(current DFS region: %d)\n", sc->dfs_detector->region); | ||
64 | ATH9K_DFS_STAT("Pulse events processed ", pulses_processed); | ||
65 | ATH9K_DFS_STAT("Radars detected ", radar_detected); | ||
66 | len += snprintf(buf + len, size - len, "Global Pool statistics:\n"); | ||
67 | ATH9K_DFS_POOL_STAT("Pool references ", pool_reference); | ||
68 | ATH9K_DFS_POOL_STAT("Pulses allocated ", pulse_allocated); | ||
69 | ATH9K_DFS_POOL_STAT("Pulses alloc error ", pulse_alloc_error); | ||
70 | ATH9K_DFS_POOL_STAT("Pulses in use ", pulse_used); | ||
71 | ATH9K_DFS_POOL_STAT("Seqs. allocated ", pseq_allocated); | ||
72 | ATH9K_DFS_POOL_STAT("Seqs. alloc error ", pseq_alloc_error); | ||
73 | ATH9K_DFS_POOL_STAT("Seqs. in use ", pseq_used); | ||
53 | 74 | ||
54 | if (len > size) | 75 | if (len > size) |
55 | len = size; | 76 | len = size; |
@@ -60,16 +81,34 @@ static ssize_t read_file_dfs(struct file *file, char __user *user_buf, | |||
60 | return retval; | 81 | return retval; |
61 | } | 82 | } |
62 | 83 | ||
63 | static int ath9k_dfs_debugfs_open(struct inode *inode, struct file *file) | 84 | /* magic number to prevent accidental reset of DFS statistics */ |
85 | #define DFS_STATS_RESET_MAGIC 0x80000000 | ||
86 | static ssize_t write_file_dfs(struct file *file, const char __user *user_buf, | ||
87 | size_t count, loff_t *ppos) | ||
64 | { | 88 | { |
65 | file->private_data = inode->i_private; | 89 | struct ath_softc *sc = file->private_data; |
90 | unsigned long val; | ||
91 | char buf[32]; | ||
92 | ssize_t len; | ||
93 | |||
94 | len = min(count, sizeof(buf) - 1); | ||
95 | if (copy_from_user(buf, user_buf, len)) | ||
96 | return -EFAULT; | ||
97 | |||
98 | buf[len] = '\0'; | ||
99 | if (strict_strtoul(buf, 0, &val)) | ||
100 | return -EINVAL; | ||
66 | 101 | ||
67 | return 0; | 102 | if (val == DFS_STATS_RESET_MAGIC) |
103 | memset(&sc->debug.stats.dfs_stats, 0, | ||
104 | sizeof(sc->debug.stats.dfs_stats)); | ||
105 | return count; | ||
68 | } | 106 | } |
69 | 107 | ||
70 | static const struct file_operations fops_dfs_stats = { | 108 | static const struct file_operations fops_dfs_stats = { |
71 | .read = read_file_dfs, | 109 | .read = read_file_dfs, |
72 | .open = ath9k_dfs_debugfs_open, | 110 | .write = write_file_dfs, |
111 | .open = simple_open, | ||
73 | .owner = THIS_MODULE, | 112 | .owner = THIS_MODULE, |
74 | .llseek = default_llseek, | 113 | .llseek = default_llseek, |
75 | }; | 114 | }; |
diff --git a/drivers/net/wireless/ath/ath9k/dfs_debug.h b/drivers/net/wireless/ath/ath9k/dfs_debug.h index 4911724cb445..e36810a4b585 100644 --- a/drivers/net/wireless/ath/ath9k/dfs_debug.h +++ b/drivers/net/wireless/ath/ath9k/dfs_debug.h | |||
@@ -22,17 +22,23 @@ | |||
22 | #include "hw.h" | 22 | #include "hw.h" |
23 | 23 | ||
24 | /** | 24 | /** |
25 | * struct ath_dfs_stats - DFS Statistics | 25 | * struct ath_dfs_stats - DFS Statistics per wiphy |
26 | * | 26 | * @pulses_total: pulses reported by HW |
27 | * @pulses_detected: No. of pulses detected so far | 27 | * @pulses_no_dfs: pulses wrongly reported as DFS |
28 | * @datalen_discards: No. of pulses discarded due to invalid datalen | 28 | * @pulses_detected: pulses detected so far |
29 | * @rssi_discards: No. of pulses discarded due to invalid RSSI | 29 | * @datalen_discards: pulses discarded due to invalid datalen |
30 | * @bwinfo_discards: No. of pulses discarded due to invalid BW info | 30 | * @rssi_discards: pulses discarded due to invalid RSSI |
31 | * @pri_phy_errors: No. of pulses reported for primary channel | 31 | * @bwinfo_discards: pulses discarded due to invalid BW info |
32 | * @ext_phy_errors: No. of pulses reported for extension channel | 32 | * @pri_phy_errors: pulses reported for primary channel |
33 | * @dc_phy_errors: No. of pulses reported for primary + extension channel | 33 | * @ext_phy_errors: pulses reported for extension channel |
34 | * @dc_phy_errors: pulses reported for primary + extension channel | ||
35 | * @pulses_processed: pulses forwarded to detector | ||
36 | * @radar_detected: radars detected | ||
34 | */ | 37 | */ |
35 | struct ath_dfs_stats { | 38 | struct ath_dfs_stats { |
39 | /* pulse stats */ | ||
40 | u32 pulses_total; | ||
41 | u32 pulses_no_dfs; | ||
36 | u32 pulses_detected; | 42 | u32 pulses_detected; |
37 | u32 datalen_discards; | 43 | u32 datalen_discards; |
38 | u32 rssi_discards; | 44 | u32 rssi_discards; |
@@ -40,18 +46,39 @@ struct ath_dfs_stats { | |||
40 | u32 pri_phy_errors; | 46 | u32 pri_phy_errors; |
41 | u32 ext_phy_errors; | 47 | u32 ext_phy_errors; |
42 | u32 dc_phy_errors; | 48 | u32 dc_phy_errors; |
49 | /* pattern detection stats */ | ||
50 | u32 pulses_processed; | ||
51 | u32 radar_detected; | ||
43 | }; | 52 | }; |
44 | 53 | ||
54 | /** | ||
55 | * struct ath_dfs_pool_stats - DFS Statistics for global pools | ||
56 | */ | ||
57 | struct ath_dfs_pool_stats { | ||
58 | u32 pool_reference; | ||
59 | u32 pulse_allocated; | ||
60 | u32 pulse_alloc_error; | ||
61 | u32 pulse_used; | ||
62 | u32 pseq_allocated; | ||
63 | u32 pseq_alloc_error; | ||
64 | u32 pseq_used; | ||
65 | }; | ||
45 | #if defined(CONFIG_ATH9K_DFS_DEBUGFS) | 66 | #if defined(CONFIG_ATH9K_DFS_DEBUGFS) |
46 | 67 | ||
47 | #define DFS_STAT_INC(sc, c) (sc->debug.stats.dfs_stats.c++) | 68 | #define DFS_STAT_INC(sc, c) (sc->debug.stats.dfs_stats.c++) |
48 | void ath9k_dfs_init_debug(struct ath_softc *sc); | 69 | void ath9k_dfs_init_debug(struct ath_softc *sc); |
49 | 70 | ||
71 | #define DFS_POOL_STAT_INC(c) (global_dfs_pool_stats.c++) | ||
72 | #define DFS_POOL_STAT_DEC(c) (global_dfs_pool_stats.c--) | ||
73 | extern struct ath_dfs_pool_stats global_dfs_pool_stats; | ||
74 | |||
50 | #else | 75 | #else |
51 | 76 | ||
52 | #define DFS_STAT_INC(sc, c) do { } while (0) | 77 | #define DFS_STAT_INC(sc, c) do { } while (0) |
53 | static inline void ath9k_dfs_init_debug(struct ath_softc *sc) { } | 78 | static inline void ath9k_dfs_init_debug(struct ath_softc *sc) { } |
54 | 79 | ||
80 | #define DFS_POOL_STAT_INC(c) do { } while (0) | ||
81 | #define DFS_POOL_STAT_DEC(c) do { } while (0) | ||
55 | #endif /* CONFIG_ATH9K_DFS_DEBUGFS */ | 82 | #endif /* CONFIG_ATH9K_DFS_DEBUGFS */ |
56 | 83 | ||
57 | #endif /* ATH9K_DFS_DEBUG_H */ | 84 | #endif /* ATH9K_DFS_DEBUG_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c b/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c index 025e88a64fa4..91b8dceeadb1 100644 --- a/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c +++ b/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c | |||
@@ -15,9 +15,12 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/spinlock.h> | ||
18 | 19 | ||
20 | #include "ath9k.h" | ||
19 | #include "dfs_pattern_detector.h" | 21 | #include "dfs_pattern_detector.h" |
20 | #include "dfs_pri_detector.h" | 22 | #include "dfs_pri_detector.h" |
23 | #include "dfs_debug.h" | ||
21 | 24 | ||
22 | /** | 25 | /** |
23 | * struct pri_sequence - sequence of pulses matching one PRI | 26 | * struct pri_sequence - sequence of pulses matching one PRI |
@@ -94,6 +97,81 @@ static u32 pde_get_multiple(u32 val, u32 fraction, u32 tolerance) | |||
94 | static u32 singleton_pool_references; | 97 | static u32 singleton_pool_references; |
95 | static LIST_HEAD(pulse_pool); | 98 | static LIST_HEAD(pulse_pool); |
96 | static LIST_HEAD(pseq_pool); | 99 | static LIST_HEAD(pseq_pool); |
100 | static DEFINE_SPINLOCK(pool_lock); | ||
101 | |||
102 | static void pool_register_ref(void) | ||
103 | { | ||
104 | spin_lock_bh(&pool_lock); | ||
105 | singleton_pool_references++; | ||
106 | DFS_POOL_STAT_INC(pool_reference); | ||
107 | spin_unlock_bh(&pool_lock); | ||
108 | } | ||
109 | |||
110 | static void pool_deregister_ref(void) | ||
111 | { | ||
112 | spin_lock_bh(&pool_lock); | ||
113 | singleton_pool_references--; | ||
114 | DFS_POOL_STAT_DEC(pool_reference); | ||
115 | if (singleton_pool_references == 0) { | ||
116 | /* free singleton pools with no references left */ | ||
117 | struct pri_sequence *ps, *ps0; | ||
118 | struct pulse_elem *p, *p0; | ||
119 | |||
120 | list_for_each_entry_safe(p, p0, &pulse_pool, head) { | ||
121 | list_del(&p->head); | ||
122 | DFS_POOL_STAT_DEC(pulse_allocated); | ||
123 | kfree(p); | ||
124 | } | ||
125 | list_for_each_entry_safe(ps, ps0, &pseq_pool, head) { | ||
126 | list_del(&ps->head); | ||
127 | DFS_POOL_STAT_DEC(pseq_allocated); | ||
128 | kfree(ps); | ||
129 | } | ||
130 | } | ||
131 | spin_unlock_bh(&pool_lock); | ||
132 | } | ||
133 | |||
134 | static void pool_put_pulse_elem(struct pulse_elem *pe) | ||
135 | { | ||
136 | spin_lock_bh(&pool_lock); | ||
137 | list_add(&pe->head, &pulse_pool); | ||
138 | DFS_POOL_STAT_DEC(pulse_used); | ||
139 | spin_unlock_bh(&pool_lock); | ||
140 | } | ||
141 | |||
142 | static void pool_put_pseq_elem(struct pri_sequence *pse) | ||
143 | { | ||
144 | spin_lock_bh(&pool_lock); | ||
145 | list_add(&pse->head, &pseq_pool); | ||
146 | DFS_POOL_STAT_DEC(pseq_used); | ||
147 | spin_unlock_bh(&pool_lock); | ||
148 | } | ||
149 | |||
150 | static struct pri_sequence *pool_get_pseq_elem(void) | ||
151 | { | ||
152 | struct pri_sequence *pse = NULL; | ||
153 | spin_lock_bh(&pool_lock); | ||
154 | if (!list_empty(&pseq_pool)) { | ||
155 | pse = list_first_entry(&pseq_pool, struct pri_sequence, head); | ||
156 | list_del(&pse->head); | ||
157 | DFS_POOL_STAT_INC(pseq_used); | ||
158 | } | ||
159 | spin_unlock_bh(&pool_lock); | ||
160 | return pse; | ||
161 | } | ||
162 | |||
163 | static struct pulse_elem *pool_get_pulse_elem(void) | ||
164 | { | ||
165 | struct pulse_elem *pe = NULL; | ||
166 | spin_lock_bh(&pool_lock); | ||
167 | if (!list_empty(&pulse_pool)) { | ||
168 | pe = list_first_entry(&pulse_pool, struct pulse_elem, head); | ||
169 | list_del(&pe->head); | ||
170 | DFS_POOL_STAT_INC(pulse_used); | ||
171 | } | ||
172 | spin_unlock_bh(&pool_lock); | ||
173 | return pe; | ||
174 | } | ||
97 | 175 | ||
98 | static struct pulse_elem *pulse_queue_get_tail(struct pri_detector *pde) | 176 | static struct pulse_elem *pulse_queue_get_tail(struct pri_detector *pde) |
99 | { | 177 | { |
@@ -110,7 +188,7 @@ static bool pulse_queue_dequeue(struct pri_detector *pde) | |||
110 | list_del_init(&p->head); | 188 | list_del_init(&p->head); |
111 | pde->count--; | 189 | pde->count--; |
112 | /* give it back to pool */ | 190 | /* give it back to pool */ |
113 | list_add(&p->head, &pulse_pool); | 191 | pool_put_pulse_elem(p); |
114 | } | 192 | } |
115 | return (pde->count > 0); | 193 | return (pde->count > 0); |
116 | } | 194 | } |
@@ -138,16 +216,15 @@ static void pulse_queue_check_window(struct pri_detector *pde) | |||
138 | 216 | ||
139 | static bool pulse_queue_enqueue(struct pri_detector *pde, u64 ts) | 217 | static bool pulse_queue_enqueue(struct pri_detector *pde, u64 ts) |
140 | { | 218 | { |
141 | struct pulse_elem *p; | 219 | struct pulse_elem *p = pool_get_pulse_elem(); |
142 | if (!list_empty(&pulse_pool)) { | 220 | if (p == NULL) { |
143 | p = list_first_entry(&pulse_pool, struct pulse_elem, head); | ||
144 | list_del(&p->head); | ||
145 | } else { | ||
146 | p = kmalloc(sizeof(*p), GFP_KERNEL); | 221 | p = kmalloc(sizeof(*p), GFP_KERNEL); |
147 | if (p == NULL) { | 222 | if (p == NULL) { |
148 | pr_err("failed to allocate pulse_elem\n"); | 223 | DFS_POOL_STAT_INC(pulse_alloc_error); |
149 | return false; | 224 | return false; |
150 | } | 225 | } |
226 | DFS_POOL_STAT_INC(pulse_allocated); | ||
227 | DFS_POOL_STAT_INC(pulse_used); | ||
151 | } | 228 | } |
152 | INIT_LIST_HEAD(&p->head); | 229 | INIT_LIST_HEAD(&p->head); |
153 | p->ts = ts; | 230 | p->ts = ts; |
@@ -220,15 +297,15 @@ static bool pseq_handler_create_sequences(struct pri_detector *pde, | |||
220 | 297 | ||
221 | /* this is a valid one, add it */ | 298 | /* this is a valid one, add it */ |
222 | ps.deadline_ts = ps.first_ts + ps.dur; | 299 | ps.deadline_ts = ps.first_ts + ps.dur; |
223 | 300 | new_ps = pool_get_pseq_elem(); | |
224 | if (!list_empty(&pseq_pool)) { | 301 | if (new_ps == NULL) { |
225 | new_ps = list_first_entry(&pseq_pool, | ||
226 | struct pri_sequence, head); | ||
227 | list_del(&new_ps->head); | ||
228 | } else { | ||
229 | new_ps = kmalloc(sizeof(*new_ps), GFP_KERNEL); | 302 | new_ps = kmalloc(sizeof(*new_ps), GFP_KERNEL); |
230 | if (new_ps == NULL) | 303 | if (new_ps == NULL) { |
304 | DFS_POOL_STAT_INC(pseq_alloc_error); | ||
231 | return false; | 305 | return false; |
306 | } | ||
307 | DFS_POOL_STAT_INC(pseq_allocated); | ||
308 | DFS_POOL_STAT_INC(pseq_used); | ||
232 | } | 309 | } |
233 | memcpy(new_ps, &ps, sizeof(ps)); | 310 | memcpy(new_ps, &ps, sizeof(ps)); |
234 | INIT_LIST_HEAD(&new_ps->head); | 311 | INIT_LIST_HEAD(&new_ps->head); |
@@ -250,7 +327,7 @@ pseq_handler_add_to_existing_seqs(struct pri_detector *pde, u64 ts) | |||
250 | /* first ensure that sequence is within window */ | 327 | /* first ensure that sequence is within window */ |
251 | if (ts > ps->deadline_ts) { | 328 | if (ts > ps->deadline_ts) { |
252 | list_del_init(&ps->head); | 329 | list_del_init(&ps->head); |
253 | list_add(&ps->head, &pseq_pool); | 330 | pool_put_pseq_elem(ps); |
254 | continue; | 331 | continue; |
255 | } | 332 | } |
256 | 333 | ||
@@ -299,11 +376,11 @@ static void pri_detector_reset(struct pri_detector *pde, u64 ts) | |||
299 | struct pulse_elem *p, *p0; | 376 | struct pulse_elem *p, *p0; |
300 | list_for_each_entry_safe(ps, ps0, &pde->sequences, head) { | 377 | list_for_each_entry_safe(ps, ps0, &pde->sequences, head) { |
301 | list_del_init(&ps->head); | 378 | list_del_init(&ps->head); |
302 | list_add(&ps->head, &pseq_pool); | 379 | pool_put_pseq_elem(ps); |
303 | } | 380 | } |
304 | list_for_each_entry_safe(p, p0, &pde->pulses, head) { | 381 | list_for_each_entry_safe(p, p0, &pde->pulses, head) { |
305 | list_del_init(&p->head); | 382 | list_del_init(&p->head); |
306 | list_add(&p->head, &pulse_pool); | 383 | pool_put_pulse_elem(p); |
307 | } | 384 | } |
308 | pde->count = 0; | 385 | pde->count = 0; |
309 | pde->last_ts = ts; | 386 | pde->last_ts = ts; |
@@ -312,22 +389,7 @@ static void pri_detector_reset(struct pri_detector *pde, u64 ts) | |||
312 | static void pri_detector_exit(struct pri_detector *de) | 389 | static void pri_detector_exit(struct pri_detector *de) |
313 | { | 390 | { |
314 | pri_detector_reset(de, 0); | 391 | pri_detector_reset(de, 0); |
315 | 392 | pool_deregister_ref(); | |
316 | singleton_pool_references--; | ||
317 | if (singleton_pool_references == 0) { | ||
318 | /* free singleton pools with no references left */ | ||
319 | struct pri_sequence *ps, *ps0; | ||
320 | struct pulse_elem *p, *p0; | ||
321 | |||
322 | list_for_each_entry_safe(p, p0, &pulse_pool, head) { | ||
323 | list_del(&p->head); | ||
324 | kfree(p); | ||
325 | } | ||
326 | list_for_each_entry_safe(ps, ps0, &pseq_pool, head) { | ||
327 | list_del(&ps->head); | ||
328 | kfree(ps); | ||
329 | } | ||
330 | } | ||
331 | kfree(de); | 393 | kfree(de); |
332 | } | 394 | } |
333 | 395 | ||
@@ -385,6 +447,6 @@ pri_detector_init(const struct radar_detector_specs *rs) | |||
385 | de->max_count = rs->ppb * 2; | 447 | de->max_count = rs->ppb * 2; |
386 | de->rs = rs; | 448 | de->rs = rs; |
387 | 449 | ||
388 | singleton_pool_references++; | 450 | pool_register_ref(); |
389 | return de; | 451 | return de; |
390 | } | 452 | } |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index c43523233319..0512397a293c 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c | |||
@@ -16,14 +16,6 @@ | |||
16 | 16 | ||
17 | #include "hw.h" | 17 | #include "hw.h" |
18 | 18 | ||
19 | static inline u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz) | ||
20 | { | ||
21 | if (fbin == AR5416_BCHAN_UNUSED) | ||
22 | return fbin; | ||
23 | |||
24 | return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin)); | ||
25 | } | ||
26 | |||
27 | void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val) | 19 | void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val) |
28 | { | 20 | { |
29 | REG_WRITE(ah, reg, val); | 21 | REG_WRITE(ah, reg, val); |
@@ -290,6 +282,34 @@ u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower, | |||
290 | return twiceMaxEdgePower; | 282 | return twiceMaxEdgePower; |
291 | } | 283 | } |
292 | 284 | ||
285 | u16 ath9k_hw_get_scaled_power(struct ath_hw *ah, u16 power_limit, | ||
286 | u8 antenna_reduction) | ||
287 | { | ||
288 | u16 reduction = antenna_reduction; | ||
289 | |||
290 | /* | ||
291 | * Reduce scaled Power by number of chains active | ||
292 | * to get the per chain tx power level. | ||
293 | */ | ||
294 | switch (ar5416_get_ntxchains(ah->txchainmask)) { | ||
295 | case 1: | ||
296 | break; | ||
297 | case 2: | ||
298 | reduction += POWER_CORRECTION_FOR_TWO_CHAIN; | ||
299 | break; | ||
300 | case 3: | ||
301 | reduction += POWER_CORRECTION_FOR_THREE_CHAIN; | ||
302 | break; | ||
303 | } | ||
304 | |||
305 | if (power_limit > reduction) | ||
306 | power_limit -= reduction; | ||
307 | else | ||
308 | power_limit = 0; | ||
309 | |||
310 | return power_limit; | ||
311 | } | ||
312 | |||
293 | void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah) | 313 | void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah) |
294 | { | 314 | { |
295 | struct ath_common *common = ath9k_hw_common(ah); | 315 | struct ath_common *common = ath9k_hw_common(ah); |
@@ -299,10 +319,10 @@ void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah) | |||
299 | case 1: | 319 | case 1: |
300 | break; | 320 | break; |
301 | case 2: | 321 | case 2: |
302 | regulatory->max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN; | 322 | regulatory->max_power_level += POWER_CORRECTION_FOR_TWO_CHAIN; |
303 | break; | 323 | break; |
304 | case 3: | 324 | case 3: |
305 | regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN; | 325 | regulatory->max_power_level += POWER_CORRECTION_FOR_THREE_CHAIN; |
306 | break; | 326 | break; |
307 | default: | 327 | default: |
308 | ath_dbg(common, EEPROM, "Invalid chainmask configuration\n"); | 328 | ath_dbg(common, EEPROM, "Invalid chainmask configuration\n"); |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 5ff7ab965120..33acb920ed3f 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h | |||
@@ -79,8 +79,8 @@ | |||
79 | #define SUB_NUM_CTL_MODES_AT_5G_40 2 | 79 | #define SUB_NUM_CTL_MODES_AT_5G_40 2 |
80 | #define SUB_NUM_CTL_MODES_AT_2G_40 3 | 80 | #define SUB_NUM_CTL_MODES_AT_2G_40 3 |
81 | 81 | ||
82 | #define INCREASE_MAXPOW_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */ | 82 | #define POWER_CORRECTION_FOR_TWO_CHAIN 6 /* 10*log10(2)*2 */ |
83 | #define INCREASE_MAXPOW_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */ | 83 | #define POWER_CORRECTION_FOR_THREE_CHAIN 10 /* 10*log10(3)*2 */ |
84 | 84 | ||
85 | /* | 85 | /* |
86 | * For AR9285 and later chipsets, the following bits are not being programmed | 86 | * For AR9285 and later chipsets, the following bits are not being programmed |
@@ -686,6 +686,8 @@ void ath9k_hw_get_target_powers(struct ath_hw *ah, | |||
686 | u16 numRates, bool isHt40Target); | 686 | u16 numRates, bool isHt40Target); |
687 | u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower, | 687 | u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower, |
688 | bool is2GHz, int num_band_edges); | 688 | bool is2GHz, int num_band_edges); |
689 | u16 ath9k_hw_get_scaled_power(struct ath_hw *ah, u16 power_limit, | ||
690 | u8 antenna_reduction); | ||
689 | void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah); | 691 | void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah); |
690 | int ath9k_hw_eeprom_init(struct ath_hw *ah); | 692 | int ath9k_hw_eeprom_init(struct ath_hw *ah); |
691 | 693 | ||
@@ -697,6 +699,14 @@ void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah, | |||
697 | u16 *pPdGainBoundaries, u8 *pPDADCValues, | 699 | u16 *pPdGainBoundaries, u8 *pPDADCValues, |
698 | u16 numXpdGains); | 700 | u16 numXpdGains); |
699 | 701 | ||
702 | static inline u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz) | ||
703 | { | ||
704 | if (fbin == AR5416_BCHAN_UNUSED) | ||
705 | return fbin; | ||
706 | |||
707 | return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin)); | ||
708 | } | ||
709 | |||
700 | #define ar5416_get_ntxchains(_txchainmask) \ | 710 | #define ar5416_get_ntxchains(_txchainmask) \ |
701 | (((_txchainmask >> 2) & 1) + \ | 711 | (((_txchainmask >> 2) & 1) + \ |
702 | ((_txchainmask >> 1) & 1) + (_txchainmask & 1)) | 712 | ((_txchainmask >> 1) & 1) + (_txchainmask & 1)) |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index 4322ac80c203..a850f44fa767 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c | |||
@@ -135,7 +135,7 @@ static u32 ath9k_hw_4k_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, | |||
135 | if (!dump_base_hdr) { | 135 | if (!dump_base_hdr) { |
136 | len += snprintf(buf + len, size - len, | 136 | len += snprintf(buf + len, size - len, |
137 | "%20s :\n", "2GHz modal Header"); | 137 | "%20s :\n", "2GHz modal Header"); |
138 | len += ath9k_dump_4k_modal_eeprom(buf, len, size, | 138 | len = ath9k_dump_4k_modal_eeprom(buf, len, size, |
139 | &eep->modalHeader); | 139 | &eep->modalHeader); |
140 | goto out; | 140 | goto out; |
141 | } | 141 | } |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index f272236d8053..cd742fb944c2 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c | |||
@@ -132,7 +132,7 @@ static u32 ath9k_hw_ar9287_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, | |||
132 | if (!dump_base_hdr) { | 132 | if (!dump_base_hdr) { |
133 | len += snprintf(buf + len, size - len, | 133 | len += snprintf(buf + len, size - len, |
134 | "%20s :\n", "2GHz modal Header"); | 134 | "%20s :\n", "2GHz modal Header"); |
135 | len += ar9287_dump_modal_eeprom(buf, len, size, | 135 | len = ar9287_dump_modal_eeprom(buf, len, size, |
136 | &eep->modalHeader); | 136 | &eep->modalHeader); |
137 | goto out; | 137 | goto out; |
138 | } | 138 | } |
@@ -564,9 +564,6 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah, | |||
564 | (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \ | 564 | (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \ |
565 | ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL)) | 565 | ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL)) |
566 | 566 | ||
567 | #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 | ||
568 | #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 | ||
569 | |||
570 | u16 twiceMaxEdgePower; | 567 | u16 twiceMaxEdgePower; |
571 | int i; | 568 | int i; |
572 | struct cal_ctl_data_ar9287 *rep; | 569 | struct cal_ctl_data_ar9287 *rep; |
@@ -591,29 +588,8 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah, | |||
591 | tx_chainmask = ah->txchainmask; | 588 | tx_chainmask = ah->txchainmask; |
592 | 589 | ||
593 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | 590 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); |
594 | scaledPower = powerLimit - antenna_reduction; | 591 | scaledPower = ath9k_hw_get_scaled_power(ah, powerLimit, |
595 | 592 | antenna_reduction); | |
596 | /* | ||
597 | * Reduce scaled Power by number of chains active | ||
598 | * to get the per chain tx power level. | ||
599 | */ | ||
600 | switch (ar5416_get_ntxchains(tx_chainmask)) { | ||
601 | case 1: | ||
602 | break; | ||
603 | case 2: | ||
604 | if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN) | ||
605 | scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; | ||
606 | else | ||
607 | scaledPower = 0; | ||
608 | break; | ||
609 | case 3: | ||
610 | if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN) | ||
611 | scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; | ||
612 | else | ||
613 | scaledPower = 0; | ||
614 | break; | ||
615 | } | ||
616 | scaledPower = max((u16)0, scaledPower); | ||
617 | 593 | ||
618 | /* | 594 | /* |
619 | * Get TX power from EEPROM. | 595 | * Get TX power from EEPROM. |
@@ -786,8 +762,6 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah, | |||
786 | 762 | ||
787 | #undef CMP_CTL | 763 | #undef CMP_CTL |
788 | #undef CMP_NO_CTL | 764 | #undef CMP_NO_CTL |
789 | #undef REDUCE_SCALED_POWER_BY_TWO_CHAIN | ||
790 | #undef REDUCE_SCALED_POWER_BY_THREE_CHAIN | ||
791 | } | 765 | } |
792 | 766 | ||
793 | static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah, | 767 | static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah, |
@@ -824,6 +798,8 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah, | |||
824 | regulatory->max_power_level = ratesArray[i]; | 798 | regulatory->max_power_level = ratesArray[i]; |
825 | } | 799 | } |
826 | 800 | ||
801 | ath9k_hw_update_regulatory_maxpower(ah); | ||
802 | |||
827 | if (test) | 803 | if (test) |
828 | return; | 804 | return; |
829 | 805 | ||
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index 619b95d764ff..56290f318520 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c | |||
@@ -211,11 +211,11 @@ static u32 ath9k_hw_def_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, | |||
211 | if (!dump_base_hdr) { | 211 | if (!dump_base_hdr) { |
212 | len += snprintf(buf + len, size - len, | 212 | len += snprintf(buf + len, size - len, |
213 | "%20s :\n", "2GHz modal Header"); | 213 | "%20s :\n", "2GHz modal Header"); |
214 | len += ath9k_def_dump_modal_eeprom(buf, len, size, | 214 | len = ath9k_def_dump_modal_eeprom(buf, len, size, |
215 | &eep->modalHeader[0]); | 215 | &eep->modalHeader[0]); |
216 | len += snprintf(buf + len, size - len, | 216 | len += snprintf(buf + len, size - len, |
217 | "%20s :\n", "5GHz modal Header"); | 217 | "%20s :\n", "5GHz modal Header"); |
218 | len += ath9k_def_dump_modal_eeprom(buf, len, size, | 218 | len = ath9k_def_dump_modal_eeprom(buf, len, size, |
219 | &eep->modalHeader[1]); | 219 | &eep->modalHeader[1]); |
220 | goto out; | 220 | goto out; |
221 | } | 221 | } |
@@ -991,9 +991,6 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah, | |||
991 | u16 antenna_reduction, | 991 | u16 antenna_reduction, |
992 | u16 powerLimit) | 992 | u16 powerLimit) |
993 | { | 993 | { |
994 | #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */ | ||
995 | #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */ | ||
996 | |||
997 | struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; | 994 | struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; |
998 | u16 twiceMaxEdgePower; | 995 | u16 twiceMaxEdgePower; |
999 | int i; | 996 | int i; |
@@ -1027,24 +1024,8 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah, | |||
1027 | 1024 | ||
1028 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | 1025 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); |
1029 | 1026 | ||
1030 | scaledPower = powerLimit - antenna_reduction; | 1027 | scaledPower = ath9k_hw_get_scaled_power(ah, powerLimit, |
1031 | 1028 | antenna_reduction); | |
1032 | switch (ar5416_get_ntxchains(tx_chainmask)) { | ||
1033 | case 1: | ||
1034 | break; | ||
1035 | case 2: | ||
1036 | if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN) | ||
1037 | scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; | ||
1038 | else | ||
1039 | scaledPower = 0; | ||
1040 | break; | ||
1041 | case 3: | ||
1042 | if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN) | ||
1043 | scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; | ||
1044 | else | ||
1045 | scaledPower = 0; | ||
1046 | break; | ||
1047 | } | ||
1048 | 1029 | ||
1049 | if (IS_CHAN_2GHZ(chan)) { | 1030 | if (IS_CHAN_2GHZ(chan)) { |
1050 | numCtlModes = ARRAY_SIZE(ctlModesFor11g) - | 1031 | numCtlModes = ARRAY_SIZE(ctlModesFor11g) - |
@@ -1263,20 +1244,7 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah, | |||
1263 | regulatory->max_power_level = ratesArray[i]; | 1244 | regulatory->max_power_level = ratesArray[i]; |
1264 | } | 1245 | } |
1265 | 1246 | ||
1266 | switch(ar5416_get_ntxchains(ah->txchainmask)) { | 1247 | ath9k_hw_update_regulatory_maxpower(ah); |
1267 | case 1: | ||
1268 | break; | ||
1269 | case 2: | ||
1270 | regulatory->max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN; | ||
1271 | break; | ||
1272 | case 3: | ||
1273 | regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN; | ||
1274 | break; | ||
1275 | default: | ||
1276 | ath_dbg(ath9k_hw_common(ah), EEPROM, | ||
1277 | "Invalid chainmask configuration\n"); | ||
1278 | break; | ||
1279 | } | ||
1280 | 1248 | ||
1281 | if (test) | 1249 | if (test) |
1282 | return; | 1250 | return; |
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index fbe23de1297f..26032cb59b8a 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c | |||
@@ -41,6 +41,9 @@ void ath_init_leds(struct ath_softc *sc) | |||
41 | { | 41 | { |
42 | int ret; | 42 | int ret; |
43 | 43 | ||
44 | if (AR_SREV_9100(sc->sc_ah)) | ||
45 | return; | ||
46 | |||
44 | if (sc->sc_ah->led_pin < 0) { | 47 | if (sc->sc_ah->led_pin < 0) { |
45 | if (AR_SREV_9287(sc->sc_ah)) | 48 | if (AR_SREV_9287(sc->sc_ah)) |
46 | sc->sc_ah->led_pin = ATH_LED_PIN_9287; | 49 | sc->sc_ah->led_pin = ATH_LED_PIN_9287; |
@@ -129,17 +132,18 @@ static void ath_detect_bt_priority(struct ath_softc *sc) | |||
129 | 132 | ||
130 | if (time_after(jiffies, btcoex->bt_priority_time + | 133 | if (time_after(jiffies, btcoex->bt_priority_time + |
131 | msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) { | 134 | msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) { |
132 | sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN); | 135 | clear_bit(BT_OP_PRIORITY_DETECTED, &btcoex->op_flags); |
136 | clear_bit(BT_OP_SCAN, &btcoex->op_flags); | ||
133 | /* Detect if colocated bt started scanning */ | 137 | /* Detect if colocated bt started scanning */ |
134 | if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) { | 138 | if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) { |
135 | ath_dbg(ath9k_hw_common(sc->sc_ah), BTCOEX, | 139 | ath_dbg(ath9k_hw_common(sc->sc_ah), BTCOEX, |
136 | "BT scan detected\n"); | 140 | "BT scan detected\n"); |
137 | sc->sc_flags |= (SC_OP_BT_SCAN | | 141 | set_bit(BT_OP_PRIORITY_DETECTED, &btcoex->op_flags); |
138 | SC_OP_BT_PRIORITY_DETECTED); | 142 | set_bit(BT_OP_SCAN, &btcoex->op_flags); |
139 | } else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { | 143 | } else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { |
140 | ath_dbg(ath9k_hw_common(sc->sc_ah), BTCOEX, | 144 | ath_dbg(ath9k_hw_common(sc->sc_ah), BTCOEX, |
141 | "BT priority traffic detected\n"); | 145 | "BT priority traffic detected\n"); |
142 | sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED; | 146 | set_bit(BT_OP_PRIORITY_DETECTED, &btcoex->op_flags); |
143 | } | 147 | } |
144 | 148 | ||
145 | btcoex->bt_priority_cnt = 0; | 149 | btcoex->bt_priority_cnt = 0; |
@@ -187,13 +191,26 @@ static void ath_btcoex_period_timer(unsigned long data) | |||
187 | struct ath_softc *sc = (struct ath_softc *) data; | 191 | struct ath_softc *sc = (struct ath_softc *) data; |
188 | struct ath_hw *ah = sc->sc_ah; | 192 | struct ath_hw *ah = sc->sc_ah; |
189 | struct ath_btcoex *btcoex = &sc->btcoex; | 193 | struct ath_btcoex *btcoex = &sc->btcoex; |
194 | struct ath_mci_profile *mci = &btcoex->mci; | ||
190 | u32 timer_period; | 195 | u32 timer_period; |
191 | bool is_btscan; | 196 | bool is_btscan; |
192 | 197 | ||
193 | ath9k_ps_wakeup(sc); | 198 | ath9k_ps_wakeup(sc); |
194 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) | 199 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) |
195 | ath_detect_bt_priority(sc); | 200 | ath_detect_bt_priority(sc); |
196 | is_btscan = sc->sc_flags & SC_OP_BT_SCAN; | 201 | is_btscan = test_bit(BT_OP_SCAN, &btcoex->op_flags); |
202 | |||
203 | btcoex->bt_wait_time += btcoex->btcoex_period; | ||
204 | if (btcoex->bt_wait_time > ATH_BTCOEX_RX_WAIT_TIME) { | ||
205 | if (ar9003_mci_state(ah, MCI_STATE_NEED_FTP_STOMP) && | ||
206 | (mci->num_pan || mci->num_other_acl)) | ||
207 | ah->btcoex_hw.mci.stomp_ftp = | ||
208 | (sc->rx.num_pkts < ATH_BTCOEX_STOMP_FTP_THRESH); | ||
209 | else | ||
210 | ah->btcoex_hw.mci.stomp_ftp = false; | ||
211 | btcoex->bt_wait_time = 0; | ||
212 | sc->rx.num_pkts = 0; | ||
213 | } | ||
197 | 214 | ||
198 | spin_lock_bh(&btcoex->btcoex_lock); | 215 | spin_lock_bh(&btcoex->btcoex_lock); |
199 | 216 | ||
@@ -215,9 +232,8 @@ static void ath_btcoex_period_timer(unsigned long data) | |||
215 | } | 232 | } |
216 | 233 | ||
217 | ath9k_ps_restore(sc); | 234 | ath9k_ps_restore(sc); |
218 | timer_period = btcoex->btcoex_period / 1000; | 235 | timer_period = btcoex->btcoex_period; |
219 | mod_timer(&btcoex->period_timer, jiffies + | 236 | mod_timer(&btcoex->period_timer, jiffies + msecs_to_jiffies(timer_period)); |
220 | msecs_to_jiffies(timer_period)); | ||
221 | } | 237 | } |
222 | 238 | ||
223 | /* | 239 | /* |
@@ -230,14 +246,14 @@ static void ath_btcoex_no_stomp_timer(void *arg) | |||
230 | struct ath_hw *ah = sc->sc_ah; | 246 | struct ath_hw *ah = sc->sc_ah; |
231 | struct ath_btcoex *btcoex = &sc->btcoex; | 247 | struct ath_btcoex *btcoex = &sc->btcoex; |
232 | struct ath_common *common = ath9k_hw_common(ah); | 248 | struct ath_common *common = ath9k_hw_common(ah); |
233 | bool is_btscan = sc->sc_flags & SC_OP_BT_SCAN; | ||
234 | 249 | ||
235 | ath_dbg(common, BTCOEX, "no stomp timer running\n"); | 250 | ath_dbg(common, BTCOEX, "no stomp timer running\n"); |
236 | 251 | ||
237 | ath9k_ps_wakeup(sc); | 252 | ath9k_ps_wakeup(sc); |
238 | spin_lock_bh(&btcoex->btcoex_lock); | 253 | spin_lock_bh(&btcoex->btcoex_lock); |
239 | 254 | ||
240 | if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) | 255 | if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || |
256 | test_bit(BT_OP_SCAN, &btcoex->op_flags)) | ||
241 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); | 257 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); |
242 | else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) | 258 | else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) |
243 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW); | 259 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW); |
@@ -251,10 +267,10 @@ static int ath_init_btcoex_timer(struct ath_softc *sc) | |||
251 | { | 267 | { |
252 | struct ath_btcoex *btcoex = &sc->btcoex; | 268 | struct ath_btcoex *btcoex = &sc->btcoex; |
253 | 269 | ||
254 | btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000; | 270 | btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD; |
255 | btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * | 271 | btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * 1000 * |
256 | btcoex->btcoex_period / 100; | 272 | btcoex->btcoex_period / 100; |
257 | btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) * | 273 | btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) * 1000 * |
258 | btcoex->btcoex_period / 100; | 274 | btcoex->btcoex_period / 100; |
259 | 275 | ||
260 | setup_timer(&btcoex->period_timer, ath_btcoex_period_timer, | 276 | setup_timer(&btcoex->period_timer, ath_btcoex_period_timer, |
@@ -289,7 +305,7 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc) | |||
289 | 305 | ||
290 | btcoex->bt_priority_cnt = 0; | 306 | btcoex->bt_priority_cnt = 0; |
291 | btcoex->bt_priority_time = jiffies; | 307 | btcoex->bt_priority_time = jiffies; |
292 | sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN); | 308 | btcoex->op_flags &= ~(BT_OP_PRIORITY_DETECTED | BT_OP_SCAN); |
293 | 309 | ||
294 | mod_timer(&btcoex->period_timer, jiffies); | 310 | mod_timer(&btcoex->period_timer, jiffies); |
295 | } | 311 | } |
@@ -313,12 +329,13 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc) | |||
313 | 329 | ||
314 | u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen) | 330 | u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen) |
315 | { | 331 | { |
332 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
316 | struct ath_mci_profile *mci = &sc->btcoex.mci; | 333 | struct ath_mci_profile *mci = &sc->btcoex.mci; |
317 | u16 aggr_limit = 0; | 334 | u16 aggr_limit = 0; |
318 | 335 | ||
319 | if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && mci->aggr_limit) | 336 | if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && mci->aggr_limit) |
320 | aggr_limit = (max_4ms_framelen * mci->aggr_limit) >> 4; | 337 | aggr_limit = (max_4ms_framelen * mci->aggr_limit) >> 4; |
321 | else if (sc->sc_flags & SC_OP_BT_PRIORITY_DETECTED) | 338 | else if (test_bit(BT_OP_PRIORITY_DETECTED, &btcoex->op_flags)) |
322 | aggr_limit = min((max_4ms_framelen * 3) / 8, | 339 | aggr_limit = min((max_4ms_framelen * 3) / 8, |
323 | (u32)ATH_AMPDU_LIMIT_MAX); | 340 | (u32)ATH_AMPDU_LIMIT_MAX); |
324 | 341 | ||
@@ -362,7 +379,7 @@ void ath9k_stop_btcoex(struct ath_softc *sc) | |||
362 | ath9k_hw_btcoex_disable(ah); | 379 | ath9k_hw_btcoex_disable(ah); |
363 | if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) | 380 | if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) |
364 | ath9k_btcoex_timer_pause(sc); | 381 | ath9k_btcoex_timer_pause(sc); |
365 | if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_MCI) | 382 | if (AR_SREV_9462(ah)) |
366 | ath_mci_flush_profile(&sc->btcoex.mci); | 383 | ath_mci_flush_profile(&sc->btcoex.mci); |
367 | } | 384 | } |
368 | } | 385 | } |
@@ -373,7 +390,7 @@ void ath9k_deinit_btcoex(struct ath_softc *sc) | |||
373 | ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_3WIRE) | 390 | ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_3WIRE) |
374 | ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer); | 391 | ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer); |
375 | 392 | ||
376 | if (ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_MCI) | 393 | if (AR_SREV_9462(sc->sc_ah)) |
377 | ath_mci_cleanup(sc); | 394 | ath_mci_cleanup(sc); |
378 | } | 395 | } |
379 | 396 | ||
@@ -399,17 +416,16 @@ int ath9k_init_btcoex(struct ath_softc *sc) | |||
399 | txq = sc->tx.txq_map[WME_AC_BE]; | 416 | txq = sc->tx.txq_map[WME_AC_BE]; |
400 | ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum); | 417 | ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum); |
401 | sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; | 418 | sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; |
402 | break; | 419 | if (AR_SREV_9462(ah)) { |
403 | case ATH_BTCOEX_CFG_MCI: | 420 | sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE; |
404 | sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; | 421 | INIT_LIST_HEAD(&sc->btcoex.mci.info); |
405 | sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE; | ||
406 | INIT_LIST_HEAD(&sc->btcoex.mci.info); | ||
407 | 422 | ||
408 | r = ath_mci_setup(sc); | 423 | r = ath_mci_setup(sc); |
409 | if (r) | 424 | if (r) |
410 | return r; | 425 | return r; |
411 | 426 | ||
412 | ath9k_hw_btcoex_init_mci(ah); | 427 | ath9k_hw_btcoex_init_mci(ah); |
428 | } | ||
413 | 429 | ||
414 | break; | 430 | break; |
415 | default: | 431 | default: |
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 424aabb2c730..aa327adcc3d8 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c | |||
@@ -53,6 +53,8 @@ static struct usb_device_id ath9k_hif_usb_ids[] = { | |||
53 | .driver_info = AR9280_USB }, /* SMC Networks */ | 53 | .driver_info = AR9280_USB }, /* SMC Networks */ |
54 | { USB_DEVICE(0x0411, 0x017f), | 54 | { USB_DEVICE(0x0411, 0x017f), |
55 | .driver_info = AR9280_USB }, /* Sony UWA-BR100 */ | 55 | .driver_info = AR9280_USB }, /* Sony UWA-BR100 */ |
56 | { USB_DEVICE(0x04da, 0x3904), | ||
57 | .driver_info = AR9280_USB }, | ||
56 | 58 | ||
57 | { USB_DEVICE(0x0cf3, 0x20ff), | 59 | { USB_DEVICE(0x0cf3, 0x20ff), |
58 | .driver_info = STORAGE_DEVICE }, | 60 | .driver_info = STORAGE_DEVICE }, |
@@ -1356,6 +1358,7 @@ static struct usb_driver ath9k_hif_usb_driver = { | |||
1356 | #endif | 1358 | #endif |
1357 | .id_table = ath9k_hif_usb_ids, | 1359 | .id_table = ath9k_hif_usb_ids, |
1358 | .soft_unbind = 1, | 1360 | .soft_unbind = 1, |
1361 | .disable_hub_initiated_lpm = 1, | ||
1359 | }; | 1362 | }; |
1360 | 1363 | ||
1361 | int ath9k_hif_usb_init(void) | 1364 | int ath9k_hif_usb_init(void) |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c index d3ff33c71aa5..3035deb7a0cd 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c | |||
@@ -16,12 +16,6 @@ | |||
16 | 16 | ||
17 | #include "htc.h" | 17 | #include "htc.h" |
18 | 18 | ||
19 | static int ath9k_debugfs_open(struct inode *inode, struct file *file) | ||
20 | { | ||
21 | file->private_data = inode->i_private; | ||
22 | return 0; | ||
23 | } | ||
24 | |||
25 | static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf, | 19 | static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf, |
26 | size_t count, loff_t *ppos) | 20 | size_t count, loff_t *ppos) |
27 | { | 21 | { |
@@ -75,7 +69,7 @@ static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf, | |||
75 | 69 | ||
76 | static const struct file_operations fops_tgt_int_stats = { | 70 | static const struct file_operations fops_tgt_int_stats = { |
77 | .read = read_file_tgt_int_stats, | 71 | .read = read_file_tgt_int_stats, |
78 | .open = ath9k_debugfs_open, | 72 | .open = simple_open, |
79 | .owner = THIS_MODULE, | 73 | .owner = THIS_MODULE, |
80 | .llseek = default_llseek, | 74 | .llseek = default_llseek, |
81 | }; | 75 | }; |
@@ -145,7 +139,7 @@ static ssize_t read_file_tgt_tx_stats(struct file *file, char __user *user_buf, | |||
145 | 139 | ||
146 | static const struct file_operations fops_tgt_tx_stats = { | 140 | static const struct file_operations fops_tgt_tx_stats = { |
147 | .read = read_file_tgt_tx_stats, | 141 | .read = read_file_tgt_tx_stats, |
148 | .open = ath9k_debugfs_open, | 142 | .open = simple_open, |
149 | .owner = THIS_MODULE, | 143 | .owner = THIS_MODULE, |
150 | .llseek = default_llseek, | 144 | .llseek = default_llseek, |
151 | }; | 145 | }; |
@@ -191,7 +185,7 @@ static ssize_t read_file_tgt_rx_stats(struct file *file, char __user *user_buf, | |||
191 | 185 | ||
192 | static const struct file_operations fops_tgt_rx_stats = { | 186 | static const struct file_operations fops_tgt_rx_stats = { |
193 | .read = read_file_tgt_rx_stats, | 187 | .read = read_file_tgt_rx_stats, |
194 | .open = ath9k_debugfs_open, | 188 | .open = simple_open, |
195 | .owner = THIS_MODULE, | 189 | .owner = THIS_MODULE, |
196 | .llseek = default_llseek, | 190 | .llseek = default_llseek, |
197 | }; | 191 | }; |
@@ -243,7 +237,7 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, | |||
243 | 237 | ||
244 | static const struct file_operations fops_xmit = { | 238 | static const struct file_operations fops_xmit = { |
245 | .read = read_file_xmit, | 239 | .read = read_file_xmit, |
246 | .open = ath9k_debugfs_open, | 240 | .open = simple_open, |
247 | .owner = THIS_MODULE, | 241 | .owner = THIS_MODULE, |
248 | .llseek = default_llseek, | 242 | .llseek = default_llseek, |
249 | }; | 243 | }; |
@@ -364,7 +358,7 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, | |||
364 | 358 | ||
365 | static const struct file_operations fops_recv = { | 359 | static const struct file_operations fops_recv = { |
366 | .read = read_file_recv, | 360 | .read = read_file_recv, |
367 | .open = ath9k_debugfs_open, | 361 | .open = simple_open, |
368 | .owner = THIS_MODULE, | 362 | .owner = THIS_MODULE, |
369 | .llseek = default_llseek, | 363 | .llseek = default_llseek, |
370 | }; | 364 | }; |
@@ -399,7 +393,7 @@ static ssize_t read_file_slot(struct file *file, char __user *user_buf, | |||
399 | 393 | ||
400 | static const struct file_operations fops_slot = { | 394 | static const struct file_operations fops_slot = { |
401 | .read = read_file_slot, | 395 | .read = read_file_slot, |
402 | .open = ath9k_debugfs_open, | 396 | .open = simple_open, |
403 | .owner = THIS_MODULE, | 397 | .owner = THIS_MODULE, |
404 | .llseek = default_llseek, | 398 | .llseek = default_llseek, |
405 | }; | 399 | }; |
@@ -446,7 +440,7 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf, | |||
446 | 440 | ||
447 | static const struct file_operations fops_queue = { | 441 | static const struct file_operations fops_queue = { |
448 | .read = read_file_queue, | 442 | .read = read_file_queue, |
449 | .open = ath9k_debugfs_open, | 443 | .open = simple_open, |
450 | .owner = THIS_MODULE, | 444 | .owner = THIS_MODULE, |
451 | .llseek = default_llseek, | 445 | .llseek = default_llseek, |
452 | }; | 446 | }; |
@@ -487,7 +481,7 @@ static ssize_t write_file_debug(struct file *file, const char __user *user_buf, | |||
487 | static const struct file_operations fops_debug = { | 481 | static const struct file_operations fops_debug = { |
488 | .read = read_file_debug, | 482 | .read = read_file_debug, |
489 | .write = write_file_debug, | 483 | .write = write_file_debug, |
490 | .open = ath9k_debugfs_open, | 484 | .open = simple_open, |
491 | .owner = THIS_MODULE, | 485 | .owner = THIS_MODULE, |
492 | .llseek = default_llseek, | 486 | .llseek = default_llseek, |
493 | }; | 487 | }; |
@@ -636,7 +630,7 @@ static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf, | |||
636 | 630 | ||
637 | static const struct file_operations fops_base_eeprom = { | 631 | static const struct file_operations fops_base_eeprom = { |
638 | .read = read_file_base_eeprom, | 632 | .read = read_file_base_eeprom, |
639 | .open = ath9k_debugfs_open, | 633 | .open = simple_open, |
640 | .owner = THIS_MODULE, | 634 | .owner = THIS_MODULE, |
641 | .llseek = default_llseek, | 635 | .llseek = default_llseek, |
642 | }; | 636 | }; |
@@ -917,7 +911,7 @@ static ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf, | |||
917 | 911 | ||
918 | static const struct file_operations fops_modal_eeprom = { | 912 | static const struct file_operations fops_modal_eeprom = { |
919 | .read = read_file_modal_eeprom, | 913 | .read = read_file_modal_eeprom, |
920 | .open = ath9k_debugfs_open, | 914 | .open = simple_open, |
921 | .owner = THIS_MODULE, | 915 | .owner = THIS_MODULE, |
922 | .llseek = default_llseek, | 916 | .llseek = default_llseek, |
923 | }; | 917 | }; |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index d1345a8a2b15..784baee5db84 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -24,6 +24,8 @@ | |||
24 | #include "rc.h" | 24 | #include "rc.h" |
25 | #include "ar9003_mac.h" | 25 | #include "ar9003_mac.h" |
26 | #include "ar9003_mci.h" | 26 | #include "ar9003_mci.h" |
27 | #include "debug.h" | ||
28 | #include "ath9k.h" | ||
27 | 29 | ||
28 | static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type); | 30 | static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type); |
29 | 31 | ||
@@ -83,6 +85,53 @@ static void ath9k_hw_ani_cache_ini_regs(struct ath_hw *ah) | |||
83 | /* Helper Functions */ | 85 | /* Helper Functions */ |
84 | /********************/ | 86 | /********************/ |
85 | 87 | ||
88 | #ifdef CONFIG_ATH9K_DEBUGFS | ||
89 | |||
90 | void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause) | ||
91 | { | ||
92 | struct ath_softc *sc = common->priv; | ||
93 | if (sync_cause) | ||
94 | sc->debug.stats.istats.sync_cause_all++; | ||
95 | if (sync_cause & AR_INTR_SYNC_RTC_IRQ) | ||
96 | sc->debug.stats.istats.sync_rtc_irq++; | ||
97 | if (sync_cause & AR_INTR_SYNC_MAC_IRQ) | ||
98 | sc->debug.stats.istats.sync_mac_irq++; | ||
99 | if (sync_cause & AR_INTR_SYNC_EEPROM_ILLEGAL_ACCESS) | ||
100 | sc->debug.stats.istats.eeprom_illegal_access++; | ||
101 | if (sync_cause & AR_INTR_SYNC_APB_TIMEOUT) | ||
102 | sc->debug.stats.istats.apb_timeout++; | ||
103 | if (sync_cause & AR_INTR_SYNC_PCI_MODE_CONFLICT) | ||
104 | sc->debug.stats.istats.pci_mode_conflict++; | ||
105 | if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) | ||
106 | sc->debug.stats.istats.host1_fatal++; | ||
107 | if (sync_cause & AR_INTR_SYNC_HOST1_PERR) | ||
108 | sc->debug.stats.istats.host1_perr++; | ||
109 | if (sync_cause & AR_INTR_SYNC_TRCV_FIFO_PERR) | ||
110 | sc->debug.stats.istats.trcv_fifo_perr++; | ||
111 | if (sync_cause & AR_INTR_SYNC_RADM_CPL_EP) | ||
112 | sc->debug.stats.istats.radm_cpl_ep++; | ||
113 | if (sync_cause & AR_INTR_SYNC_RADM_CPL_DLLP_ABORT) | ||
114 | sc->debug.stats.istats.radm_cpl_dllp_abort++; | ||
115 | if (sync_cause & AR_INTR_SYNC_RADM_CPL_TLP_ABORT) | ||
116 | sc->debug.stats.istats.radm_cpl_tlp_abort++; | ||
117 | if (sync_cause & AR_INTR_SYNC_RADM_CPL_ECRC_ERR) | ||
118 | sc->debug.stats.istats.radm_cpl_ecrc_err++; | ||
119 | if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) | ||
120 | sc->debug.stats.istats.radm_cpl_timeout++; | ||
121 | if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) | ||
122 | sc->debug.stats.istats.local_timeout++; | ||
123 | if (sync_cause & AR_INTR_SYNC_PM_ACCESS) | ||
124 | sc->debug.stats.istats.pm_access++; | ||
125 | if (sync_cause & AR_INTR_SYNC_MAC_AWAKE) | ||
126 | sc->debug.stats.istats.mac_awake++; | ||
127 | if (sync_cause & AR_INTR_SYNC_MAC_ASLEEP) | ||
128 | sc->debug.stats.istats.mac_asleep++; | ||
129 | if (sync_cause & AR_INTR_SYNC_MAC_SLEEP_ACCESS) | ||
130 | sc->debug.stats.istats.mac_sleep_access++; | ||
131 | } | ||
132 | #endif | ||
133 | |||
134 | |||
86 | static void ath9k_hw_set_clockrate(struct ath_hw *ah) | 135 | static void ath9k_hw_set_clockrate(struct ath_hw *ah) |
87 | { | 136 | { |
88 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; | 137 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; |
@@ -142,6 +191,22 @@ bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout) | |||
142 | } | 191 | } |
143 | EXPORT_SYMBOL(ath9k_hw_wait); | 192 | EXPORT_SYMBOL(ath9k_hw_wait); |
144 | 193 | ||
194 | void ath9k_hw_synth_delay(struct ath_hw *ah, struct ath9k_channel *chan, | ||
195 | int hw_delay) | ||
196 | { | ||
197 | if (IS_CHAN_B(chan)) | ||
198 | hw_delay = (4 * hw_delay) / 22; | ||
199 | else | ||
200 | hw_delay /= 10; | ||
201 | |||
202 | if (IS_CHAN_HALF_RATE(chan)) | ||
203 | hw_delay *= 2; | ||
204 | else if (IS_CHAN_QUARTER_RATE(chan)) | ||
205 | hw_delay *= 4; | ||
206 | |||
207 | udelay(hw_delay + BASE_ACTIVATE_DELAY); | ||
208 | } | ||
209 | |||
145 | void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array, | 210 | void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array, |
146 | int column, unsigned int *writecnt) | 211 | int column, unsigned int *writecnt) |
147 | { | 212 | { |
@@ -325,14 +390,6 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah) | |||
325 | REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); | 390 | REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); |
326 | } | 391 | } |
327 | 392 | ||
328 | static void ath9k_hw_aspm_init(struct ath_hw *ah) | ||
329 | { | ||
330 | struct ath_common *common = ath9k_hw_common(ah); | ||
331 | |||
332 | if (common->bus_ops->aspm_init) | ||
333 | common->bus_ops->aspm_init(common); | ||
334 | } | ||
335 | |||
336 | /* This should work for all families including legacy */ | 393 | /* This should work for all families including legacy */ |
337 | static bool ath9k_hw_chip_test(struct ath_hw *ah) | 394 | static bool ath9k_hw_chip_test(struct ath_hw *ah) |
338 | { | 395 | { |
@@ -388,8 +445,8 @@ static void ath9k_hw_init_config(struct ath_hw *ah) | |||
388 | { | 445 | { |
389 | int i; | 446 | int i; |
390 | 447 | ||
391 | ah->config.dma_beacon_response_time = 2; | 448 | ah->config.dma_beacon_response_time = 1; |
392 | ah->config.sw_beacon_response_time = 10; | 449 | ah->config.sw_beacon_response_time = 6; |
393 | ah->config.additional_swba_backoff = 0; | 450 | ah->config.additional_swba_backoff = 0; |
394 | ah->config.ack_6mb = 0x0; | 451 | ah->config.ack_6mb = 0x0; |
395 | ah->config.cwm_ignore_extcca = 0; | 452 | ah->config.cwm_ignore_extcca = 0; |
@@ -445,7 +502,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah) | |||
445 | AR_STA_ID1_MCAST_KSRCH; | 502 | AR_STA_ID1_MCAST_KSRCH; |
446 | if (AR_SREV_9100(ah)) | 503 | if (AR_SREV_9100(ah)) |
447 | ah->sta_id1_defaults |= AR_STA_ID1_AR9100_BA_FIX; | 504 | ah->sta_id1_defaults |= AR_STA_ID1_AR9100_BA_FIX; |
448 | ah->enable_32kHz_clock = DONT_USE_32KHZ; | ||
449 | ah->slottime = ATH9K_SLOT_TIME_9; | 505 | ah->slottime = ATH9K_SLOT_TIME_9; |
450 | ah->globaltxtimeout = (u32) -1; | 506 | ah->globaltxtimeout = (u32) -1; |
451 | ah->power_mode = ATH9K_PM_UNDEFINED; | 507 | ah->power_mode = ATH9K_PM_UNDEFINED; |
@@ -629,9 +685,6 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
629 | if (r) | 685 | if (r) |
630 | return r; | 686 | return r; |
631 | 687 | ||
632 | if (ah->is_pciexpress) | ||
633 | ath9k_hw_aspm_init(ah); | ||
634 | |||
635 | r = ath9k_hw_init_macaddr(ah); | 688 | r = ath9k_hw_init_macaddr(ah); |
636 | if (r) { | 689 | if (r) { |
637 | ath_err(common, "Failed to initialize MAC address\n"); | 690 | ath_err(common, "Failed to initialize MAC address\n"); |
@@ -972,7 +1025,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) | |||
972 | struct ath_common *common = ath9k_hw_common(ah); | 1025 | struct ath_common *common = ath9k_hw_common(ah); |
973 | struct ieee80211_conf *conf = &common->hw->conf; | 1026 | struct ieee80211_conf *conf = &common->hw->conf; |
974 | const struct ath9k_channel *chan = ah->curchan; | 1027 | const struct ath9k_channel *chan = ah->curchan; |
975 | int acktimeout, ctstimeout; | 1028 | int acktimeout, ctstimeout, ack_offset = 0; |
976 | int slottime; | 1029 | int slottime; |
977 | int sifstime; | 1030 | int sifstime; |
978 | int rx_lat = 0, tx_lat = 0, eifs = 0; | 1031 | int rx_lat = 0, tx_lat = 0, eifs = 0; |
@@ -993,6 +1046,11 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) | |||
993 | rx_lat = 37; | 1046 | rx_lat = 37; |
994 | tx_lat = 54; | 1047 | tx_lat = 54; |
995 | 1048 | ||
1049 | if (IS_CHAN_5GHZ(chan)) | ||
1050 | sifstime = 16; | ||
1051 | else | ||
1052 | sifstime = 10; | ||
1053 | |||
996 | if (IS_CHAN_HALF_RATE(chan)) { | 1054 | if (IS_CHAN_HALF_RATE(chan)) { |
997 | eifs = 175; | 1055 | eifs = 175; |
998 | rx_lat *= 2; | 1056 | rx_lat *= 2; |
@@ -1000,8 +1058,9 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) | |||
1000 | if (IS_CHAN_A_FAST_CLOCK(ah, chan)) | 1058 | if (IS_CHAN_A_FAST_CLOCK(ah, chan)) |
1001 | tx_lat += 11; | 1059 | tx_lat += 11; |
1002 | 1060 | ||
1061 | sifstime *= 2; | ||
1062 | ack_offset = 16; | ||
1003 | slottime = 13; | 1063 | slottime = 13; |
1004 | sifstime = 32; | ||
1005 | } else if (IS_CHAN_QUARTER_RATE(chan)) { | 1064 | } else if (IS_CHAN_QUARTER_RATE(chan)) { |
1006 | eifs = 340; | 1065 | eifs = 340; |
1007 | rx_lat = (rx_lat * 4) - 1; | 1066 | rx_lat = (rx_lat * 4) - 1; |
@@ -1009,8 +1068,9 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) | |||
1009 | if (IS_CHAN_A_FAST_CLOCK(ah, chan)) | 1068 | if (IS_CHAN_A_FAST_CLOCK(ah, chan)) |
1010 | tx_lat += 22; | 1069 | tx_lat += 22; |
1011 | 1070 | ||
1071 | sifstime *= 4; | ||
1072 | ack_offset = 32; | ||
1012 | slottime = 21; | 1073 | slottime = 21; |
1013 | sifstime = 64; | ||
1014 | } else { | 1074 | } else { |
1015 | if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah)) { | 1075 | if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah)) { |
1016 | eifs = AR_D_GBL_IFS_EIFS_ASYNC_FIFO; | 1076 | eifs = AR_D_GBL_IFS_EIFS_ASYNC_FIFO; |
@@ -1024,14 +1084,10 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) | |||
1024 | tx_lat = MS(reg, AR_USEC_TX_LAT); | 1084 | tx_lat = MS(reg, AR_USEC_TX_LAT); |
1025 | 1085 | ||
1026 | slottime = ah->slottime; | 1086 | slottime = ah->slottime; |
1027 | if (IS_CHAN_5GHZ(chan)) | ||
1028 | sifstime = 16; | ||
1029 | else | ||
1030 | sifstime = 10; | ||
1031 | } | 1087 | } |
1032 | 1088 | ||
1033 | /* As defined by IEEE 802.11-2007 17.3.8.6 */ | 1089 | /* As defined by IEEE 802.11-2007 17.3.8.6 */ |
1034 | acktimeout = slottime + sifstime + 3 * ah->coverage_class; | 1090 | acktimeout = slottime + sifstime + 3 * ah->coverage_class + ack_offset; |
1035 | ctstimeout = acktimeout; | 1091 | ctstimeout = acktimeout; |
1036 | 1092 | ||
1037 | /* | 1093 | /* |
@@ -1041,7 +1097,8 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) | |||
1041 | * BA frames in some implementations, but it has been found to fix ACK | 1097 | * BA frames in some implementations, but it has been found to fix ACK |
1042 | * timeout issues in other cases as well. | 1098 | * timeout issues in other cases as well. |
1043 | */ | 1099 | */ |
1044 | if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ) { | 1100 | if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ && |
1101 | !IS_CHAN_HALF_RATE(chan) && !IS_CHAN_QUARTER_RATE(chan)) { | ||
1045 | acktimeout += 64 - sifstime - ah->slottime; | 1102 | acktimeout += 64 - sifstime - ah->slottime; |
1046 | ctstimeout += 48 - sifstime - ah->slottime; | 1103 | ctstimeout += 48 - sifstime - ah->slottime; |
1047 | } | 1104 | } |
@@ -1291,6 +1348,9 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) | |||
1291 | } | 1348 | } |
1292 | } | 1349 | } |
1293 | 1350 | ||
1351 | if (ath9k_hw_mci_is_enabled(ah)) | ||
1352 | ar9003_mci_check_gpm_offset(ah); | ||
1353 | |||
1294 | REG_WRITE(ah, AR_RTC_RC, rst_flags); | 1354 | REG_WRITE(ah, AR_RTC_RC, rst_flags); |
1295 | 1355 | ||
1296 | REGWRITE_BUFFER_FLUSH(ah); | 1356 | REGWRITE_BUFFER_FLUSH(ah); |
@@ -1375,9 +1435,6 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) | |||
1375 | break; | 1435 | break; |
1376 | } | 1436 | } |
1377 | 1437 | ||
1378 | if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) | ||
1379 | REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2); | ||
1380 | |||
1381 | return ret; | 1438 | return ret; |
1382 | } | 1439 | } |
1383 | 1440 | ||
@@ -1400,6 +1457,9 @@ static bool ath9k_hw_chip_reset(struct ath_hw *ah, | |||
1400 | return false; | 1457 | return false; |
1401 | 1458 | ||
1402 | ah->chip_fullsleep = false; | 1459 | ah->chip_fullsleep = false; |
1460 | |||
1461 | if (AR_SREV_9330(ah)) | ||
1462 | ar9003_hw_internal_regulator_apply(ah); | ||
1403 | ath9k_hw_init_pll(ah, chan); | 1463 | ath9k_hw_init_pll(ah, chan); |
1404 | ath9k_hw_set_rfmode(ah, chan); | 1464 | ath9k_hw_set_rfmode(ah, chan); |
1405 | 1465 | ||
@@ -1454,7 +1514,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, | |||
1454 | return false; | 1514 | return false; |
1455 | } | 1515 | } |
1456 | ath9k_hw_set_clockrate(ah); | 1516 | ath9k_hw_set_clockrate(ah); |
1457 | ath9k_hw_apply_txpower(ah, chan); | 1517 | ath9k_hw_apply_txpower(ah, chan, false); |
1458 | ath9k_hw_rfbus_done(ah); | 1518 | ath9k_hw_rfbus_done(ah); |
1459 | 1519 | ||
1460 | if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) | 1520 | if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) |
@@ -1619,6 +1679,10 @@ static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan) | |||
1619 | if (chan->channel == ah->curchan->channel) | 1679 | if (chan->channel == ah->curchan->channel) |
1620 | goto fail; | 1680 | goto fail; |
1621 | 1681 | ||
1682 | if ((ah->curchan->channelFlags | chan->channelFlags) & | ||
1683 | (CHANNEL_HALF | CHANNEL_QUARTER)) | ||
1684 | goto fail; | ||
1685 | |||
1622 | if ((chan->channelFlags & CHANNEL_ALL) != | 1686 | if ((chan->channelFlags & CHANNEL_ALL) != |
1623 | (ah->curchan->channelFlags & CHANNEL_ALL)) | 1687 | (ah->curchan->channelFlags & CHANNEL_ALL)) |
1624 | goto fail; | 1688 | goto fail; |
@@ -1630,10 +1694,10 @@ static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan) | |||
1630 | * For AR9462, make sure that calibration data for | 1694 | * For AR9462, make sure that calibration data for |
1631 | * re-using are present. | 1695 | * re-using are present. |
1632 | */ | 1696 | */ |
1633 | if (AR_SREV_9462(ah) && (!ah->caldata || | 1697 | if (AR_SREV_9462(ah) && (ah->caldata && |
1634 | !ah->caldata->done_txiqcal_once || | 1698 | (!ah->caldata->done_txiqcal_once || |
1635 | !ah->caldata->done_txclcal_once || | 1699 | !ah->caldata->done_txclcal_once || |
1636 | !ah->caldata->rtt_hist.num_readings)) | 1700 | !ah->caldata->rtt_done))) |
1637 | goto fail; | 1701 | goto fail; |
1638 | 1702 | ||
1639 | ath_dbg(common, RESET, "FastChannelChange for %d -> %d\n", | 1703 | ath_dbg(common, RESET, "FastChannelChange for %d -> %d\n", |
@@ -1646,8 +1710,8 @@ static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan) | |||
1646 | ath9k_hw_loadnf(ah, ah->curchan); | 1710 | ath9k_hw_loadnf(ah, ah->curchan); |
1647 | ath9k_hw_start_nfcal(ah, true); | 1711 | ath9k_hw_start_nfcal(ah, true); |
1648 | 1712 | ||
1649 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && ar9003_mci_is_ready(ah)) | 1713 | if (ath9k_hw_mci_is_enabled(ah)) |
1650 | ar9003_mci_2g5g_switch(ah, true); | 1714 | ar9003_mci_2g5g_switch(ah, false); |
1651 | 1715 | ||
1652 | if (AR_SREV_9271(ah)) | 1716 | if (AR_SREV_9271(ah)) |
1653 | ar9002_hw_load_ani_reg(ah, chan); | 1717 | ar9002_hw_load_ani_reg(ah, chan); |
@@ -1667,10 +1731,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1667 | u64 tsf = 0; | 1731 | u64 tsf = 0; |
1668 | int i, r; | 1732 | int i, r; |
1669 | bool start_mci_reset = false; | 1733 | bool start_mci_reset = false; |
1670 | bool mci = !!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI); | ||
1671 | bool save_fullsleep = ah->chip_fullsleep; | 1734 | bool save_fullsleep = ah->chip_fullsleep; |
1672 | 1735 | ||
1673 | if (mci) { | 1736 | if (ath9k_hw_mci_is_enabled(ah)) { |
1674 | start_mci_reset = ar9003_mci_start_reset(ah, chan); | 1737 | start_mci_reset = ar9003_mci_start_reset(ah, chan); |
1675 | if (start_mci_reset) | 1738 | if (start_mci_reset) |
1676 | return 0; | 1739 | return 0; |
@@ -1699,7 +1762,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1699 | return r; | 1762 | return r; |
1700 | } | 1763 | } |
1701 | 1764 | ||
1702 | if (mci) | 1765 | if (ath9k_hw_mci_is_enabled(ah)) |
1703 | ar9003_mci_stop_bt(ah, save_fullsleep); | 1766 | ar9003_mci_stop_bt(ah, save_fullsleep); |
1704 | 1767 | ||
1705 | saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA); | 1768 | saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA); |
@@ -1757,7 +1820,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1757 | if (r) | 1820 | if (r) |
1758 | return r; | 1821 | return r; |
1759 | 1822 | ||
1760 | if (mci) | 1823 | if (ath9k_hw_mci_is_enabled(ah)) |
1761 | ar9003_mci_reset(ah, false, IS_CHAN_2GHZ(chan), save_fullsleep); | 1824 | ar9003_mci_reset(ah, false, IS_CHAN_2GHZ(chan), save_fullsleep); |
1762 | 1825 | ||
1763 | /* | 1826 | /* |
@@ -1852,7 +1915,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1852 | 1915 | ||
1853 | ath9k_hw_set_dma(ah); | 1916 | ath9k_hw_set_dma(ah); |
1854 | 1917 | ||
1855 | REG_WRITE(ah, AR_OBS, 8); | 1918 | if (!ath9k_hw_mci_is_enabled(ah)) |
1919 | REG_WRITE(ah, AR_OBS, 8); | ||
1856 | 1920 | ||
1857 | if (ah->config.rx_intr_mitigation) { | 1921 | if (ah->config.rx_intr_mitigation) { |
1858 | REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); | 1922 | REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); |
@@ -1869,7 +1933,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1869 | if (caldata) { | 1933 | if (caldata) { |
1870 | caldata->done_txiqcal_once = false; | 1934 | caldata->done_txiqcal_once = false; |
1871 | caldata->done_txclcal_once = false; | 1935 | caldata->done_txclcal_once = false; |
1872 | caldata->rtt_hist.num_readings = 0; | ||
1873 | } | 1936 | } |
1874 | if (!ath9k_hw_init_cal(ah, chan)) | 1937 | if (!ath9k_hw_init_cal(ah, chan)) |
1875 | return -EIO; | 1938 | return -EIO; |
@@ -1877,7 +1940,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1877 | ath9k_hw_loadnf(ah, chan); | 1940 | ath9k_hw_loadnf(ah, chan); |
1878 | ath9k_hw_start_nfcal(ah, true); | 1941 | ath9k_hw_start_nfcal(ah, true); |
1879 | 1942 | ||
1880 | if (mci && ar9003_mci_end_reset(ah, chan, caldata)) | 1943 | if (ath9k_hw_mci_is_enabled(ah) && ar9003_mci_end_reset(ah, chan, caldata)) |
1881 | return -EIO; | 1944 | return -EIO; |
1882 | 1945 | ||
1883 | ENABLE_REGWRITE_BUFFER(ah); | 1946 | ENABLE_REGWRITE_BUFFER(ah); |
@@ -1922,7 +1985,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1922 | if (ath9k_hw_btcoex_is_enabled(ah)) | 1985 | if (ath9k_hw_btcoex_is_enabled(ah)) |
1923 | ath9k_hw_btcoex_enable(ah); | 1986 | ath9k_hw_btcoex_enable(ah); |
1924 | 1987 | ||
1925 | if (mci) | 1988 | if (ath9k_hw_mci_is_enabled(ah)) |
1926 | ar9003_mci_check_bt(ah); | 1989 | ar9003_mci_check_bt(ah); |
1927 | 1990 | ||
1928 | if (AR_SREV_9300_20_OR_LATER(ah)) { | 1991 | if (AR_SREV_9300_20_OR_LATER(ah)) { |
@@ -1945,39 +2008,35 @@ EXPORT_SYMBOL(ath9k_hw_reset); | |||
1945 | * Notify Power Mgt is disabled in self-generated frames. | 2008 | * Notify Power Mgt is disabled in self-generated frames. |
1946 | * If requested, force chip to sleep. | 2009 | * If requested, force chip to sleep. |
1947 | */ | 2010 | */ |
1948 | static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip) | 2011 | static void ath9k_set_power_sleep(struct ath_hw *ah) |
1949 | { | 2012 | { |
1950 | REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); | 2013 | REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); |
1951 | if (setChip) { | ||
1952 | if (AR_SREV_9462(ah)) { | ||
1953 | REG_WRITE(ah, AR_TIMER_MODE, | ||
1954 | REG_READ(ah, AR_TIMER_MODE) & 0xFFFFFF00); | ||
1955 | REG_WRITE(ah, AR_NDP2_TIMER_MODE, REG_READ(ah, | ||
1956 | AR_NDP2_TIMER_MODE) & 0xFFFFFF00); | ||
1957 | REG_WRITE(ah, AR_SLP32_INC, | ||
1958 | REG_READ(ah, AR_SLP32_INC) & 0xFFF00000); | ||
1959 | /* xxx Required for WLAN only case ? */ | ||
1960 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 0); | ||
1961 | udelay(100); | ||
1962 | } | ||
1963 | 2014 | ||
1964 | /* | 2015 | if (AR_SREV_9462(ah)) { |
1965 | * Clear the RTC force wake bit to allow the | 2016 | REG_CLR_BIT(ah, AR_TIMER_MODE, 0xff); |
1966 | * mac to go to sleep. | 2017 | REG_CLR_BIT(ah, AR_NDP2_TIMER_MODE, 0xff); |
1967 | */ | 2018 | REG_CLR_BIT(ah, AR_SLP32_INC, 0xfffff); |
1968 | REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); | 2019 | /* xxx Required for WLAN only case ? */ |
2020 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 0); | ||
2021 | udelay(100); | ||
2022 | } | ||
1969 | 2023 | ||
1970 | if (AR_SREV_9462(ah)) | 2024 | /* |
1971 | udelay(100); | 2025 | * Clear the RTC force wake bit to allow the |
2026 | * mac to go to sleep. | ||
2027 | */ | ||
2028 | REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); | ||
1972 | 2029 | ||
1973 | if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah)) | 2030 | if (ath9k_hw_mci_is_enabled(ah)) |
1974 | REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF); | 2031 | udelay(100); |
1975 | 2032 | ||
1976 | /* Shutdown chip. Active low */ | 2033 | if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah)) |
1977 | if (!AR_SREV_5416(ah) && !AR_SREV_9271(ah)) { | 2034 | REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF); |
1978 | REG_CLR_BIT(ah, AR_RTC_RESET, AR_RTC_RESET_EN); | 2035 | |
1979 | udelay(2); | 2036 | /* Shutdown chip. Active low */ |
1980 | } | 2037 | if (!AR_SREV_5416(ah) && !AR_SREV_9271(ah)) { |
2038 | REG_CLR_BIT(ah, AR_RTC_RESET, AR_RTC_RESET_EN); | ||
2039 | udelay(2); | ||
1981 | } | 2040 | } |
1982 | 2041 | ||
1983 | /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */ | 2042 | /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */ |
@@ -1990,44 +2049,38 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip) | |||
1990 | * frames. If request, set power mode of chip to | 2049 | * frames. If request, set power mode of chip to |
1991 | * auto/normal. Duration in units of 128us (1/8 TU). | 2050 | * auto/normal. Duration in units of 128us (1/8 TU). |
1992 | */ | 2051 | */ |
1993 | static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip) | 2052 | static void ath9k_set_power_network_sleep(struct ath_hw *ah) |
1994 | { | 2053 | { |
1995 | u32 val; | 2054 | struct ath9k_hw_capabilities *pCap = &ah->caps; |
1996 | 2055 | ||
1997 | REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); | 2056 | REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); |
1998 | if (setChip) { | ||
1999 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
2000 | 2057 | ||
2001 | if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { | 2058 | if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { |
2002 | /* Set WakeOnInterrupt bit; clear ForceWake bit */ | 2059 | /* Set WakeOnInterrupt bit; clear ForceWake bit */ |
2003 | REG_WRITE(ah, AR_RTC_FORCE_WAKE, | 2060 | REG_WRITE(ah, AR_RTC_FORCE_WAKE, |
2004 | AR_RTC_FORCE_WAKE_ON_INT); | 2061 | AR_RTC_FORCE_WAKE_ON_INT); |
2005 | } else { | 2062 | } else { |
2006 | 2063 | ||
2007 | /* When chip goes into network sleep, it could be waken | 2064 | /* When chip goes into network sleep, it could be waken |
2008 | * up by MCI_INT interrupt caused by BT's HW messages | 2065 | * up by MCI_INT interrupt caused by BT's HW messages |
2009 | * (LNA_xxx, CONT_xxx) which chould be in a very fast | 2066 | * (LNA_xxx, CONT_xxx) which chould be in a very fast |
2010 | * rate (~100us). This will cause chip to leave and | 2067 | * rate (~100us). This will cause chip to leave and |
2011 | * re-enter network sleep mode frequently, which in | 2068 | * re-enter network sleep mode frequently, which in |
2012 | * consequence will have WLAN MCI HW to generate lots of | 2069 | * consequence will have WLAN MCI HW to generate lots of |
2013 | * SYS_WAKING and SYS_SLEEPING messages which will make | 2070 | * SYS_WAKING and SYS_SLEEPING messages which will make |
2014 | * BT CPU to busy to process. | 2071 | * BT CPU to busy to process. |
2015 | */ | 2072 | */ |
2016 | if (AR_SREV_9462(ah)) { | 2073 | if (ath9k_hw_mci_is_enabled(ah)) |
2017 | val = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_EN) & | 2074 | REG_CLR_BIT(ah, AR_MCI_INTERRUPT_RX_MSG_EN, |
2018 | ~AR_MCI_INTERRUPT_RX_HW_MSG_MASK; | 2075 | AR_MCI_INTERRUPT_RX_HW_MSG_MASK); |
2019 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, val); | 2076 | /* |
2020 | } | 2077 | * Clear the RTC force wake bit to allow the |
2021 | /* | 2078 | * mac to go to sleep. |
2022 | * Clear the RTC force wake bit to allow the | 2079 | */ |
2023 | * mac to go to sleep. | 2080 | REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); |
2024 | */ | 2081 | |
2025 | REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, | 2082 | if (ath9k_hw_mci_is_enabled(ah)) |
2026 | AR_RTC_FORCE_WAKE_EN); | 2083 | udelay(30); |
2027 | |||
2028 | if (AR_SREV_9462(ah)) | ||
2029 | udelay(30); | ||
2030 | } | ||
2031 | } | 2084 | } |
2032 | 2085 | ||
2033 | /* Clear Bit 14 of AR_WA after putting chip into Net Sleep mode. */ | 2086 | /* Clear Bit 14 of AR_WA after putting chip into Net Sleep mode. */ |
@@ -2035,7 +2088,7 @@ static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip) | |||
2035 | REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE); | 2088 | REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE); |
2036 | } | 2089 | } |
2037 | 2090 | ||
2038 | static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip) | 2091 | static bool ath9k_hw_set_power_awake(struct ath_hw *ah) |
2039 | { | 2092 | { |
2040 | u32 val; | 2093 | u32 val; |
2041 | int i; | 2094 | int i; |
@@ -2046,37 +2099,38 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip) | |||
2046 | udelay(10); | 2099 | udelay(10); |
2047 | } | 2100 | } |
2048 | 2101 | ||
2049 | if (setChip) { | 2102 | if ((REG_READ(ah, AR_RTC_STATUS) & |
2050 | if ((REG_READ(ah, AR_RTC_STATUS) & | 2103 | AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) { |
2051 | AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) { | 2104 | if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { |
2052 | if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { | 2105 | return false; |
2053 | return false; | ||
2054 | } | ||
2055 | if (!AR_SREV_9300_20_OR_LATER(ah)) | ||
2056 | ath9k_hw_init_pll(ah, NULL); | ||
2057 | } | 2106 | } |
2058 | if (AR_SREV_9100(ah)) | 2107 | if (!AR_SREV_9300_20_OR_LATER(ah)) |
2059 | REG_SET_BIT(ah, AR_RTC_RESET, | 2108 | ath9k_hw_init_pll(ah, NULL); |
2060 | AR_RTC_RESET_EN); | 2109 | } |
2110 | if (AR_SREV_9100(ah)) | ||
2111 | REG_SET_BIT(ah, AR_RTC_RESET, | ||
2112 | AR_RTC_RESET_EN); | ||
2113 | |||
2114 | REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, | ||
2115 | AR_RTC_FORCE_WAKE_EN); | ||
2116 | udelay(50); | ||
2061 | 2117 | ||
2118 | if (ath9k_hw_mci_is_enabled(ah)) | ||
2119 | ar9003_mci_set_power_awake(ah); | ||
2120 | |||
2121 | for (i = POWER_UP_TIME / 50; i > 0; i--) { | ||
2122 | val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M; | ||
2123 | if (val == AR_RTC_STATUS_ON) | ||
2124 | break; | ||
2125 | udelay(50); | ||
2062 | REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, | 2126 | REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, |
2063 | AR_RTC_FORCE_WAKE_EN); | 2127 | AR_RTC_FORCE_WAKE_EN); |
2064 | udelay(50); | 2128 | } |
2065 | 2129 | if (i == 0) { | |
2066 | for (i = POWER_UP_TIME / 50; i > 0; i--) { | 2130 | ath_err(ath9k_hw_common(ah), |
2067 | val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M; | 2131 | "Failed to wakeup in %uus\n", |
2068 | if (val == AR_RTC_STATUS_ON) | 2132 | POWER_UP_TIME / 20); |
2069 | break; | 2133 | return false; |
2070 | udelay(50); | ||
2071 | REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, | ||
2072 | AR_RTC_FORCE_WAKE_EN); | ||
2073 | } | ||
2074 | if (i == 0) { | ||
2075 | ath_err(ath9k_hw_common(ah), | ||
2076 | "Failed to wakeup in %uus\n", | ||
2077 | POWER_UP_TIME / 20); | ||
2078 | return false; | ||
2079 | } | ||
2080 | } | 2134 | } |
2081 | 2135 | ||
2082 | REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); | 2136 | REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); |
@@ -2087,7 +2141,7 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip) | |||
2087 | bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) | 2141 | bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) |
2088 | { | 2142 | { |
2089 | struct ath_common *common = ath9k_hw_common(ah); | 2143 | struct ath_common *common = ath9k_hw_common(ah); |
2090 | int status = true, setChip = true; | 2144 | int status = true; |
2091 | static const char *modes[] = { | 2145 | static const char *modes[] = { |
2092 | "AWAKE", | 2146 | "AWAKE", |
2093 | "FULL-SLEEP", | 2147 | "FULL-SLEEP", |
@@ -2103,25 +2157,17 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) | |||
2103 | 2157 | ||
2104 | switch (mode) { | 2158 | switch (mode) { |
2105 | case ATH9K_PM_AWAKE: | 2159 | case ATH9K_PM_AWAKE: |
2106 | status = ath9k_hw_set_power_awake(ah, setChip); | 2160 | status = ath9k_hw_set_power_awake(ah); |
2107 | |||
2108 | if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) | ||
2109 | REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2); | ||
2110 | |||
2111 | break; | 2161 | break; |
2112 | case ATH9K_PM_FULL_SLEEP: | 2162 | case ATH9K_PM_FULL_SLEEP: |
2113 | if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) | 2163 | if (ath9k_hw_mci_is_enabled(ah)) |
2114 | ar9003_mci_set_full_sleep(ah); | 2164 | ar9003_mci_set_full_sleep(ah); |
2115 | 2165 | ||
2116 | ath9k_set_power_sleep(ah, setChip); | 2166 | ath9k_set_power_sleep(ah); |
2117 | ah->chip_fullsleep = true; | 2167 | ah->chip_fullsleep = true; |
2118 | break; | 2168 | break; |
2119 | case ATH9K_PM_NETWORK_SLEEP: | 2169 | case ATH9K_PM_NETWORK_SLEEP: |
2120 | 2170 | ath9k_set_power_network_sleep(ah); | |
2121 | if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) | ||
2122 | REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2); | ||
2123 | |||
2124 | ath9k_set_power_network_sleep(ah, setChip); | ||
2125 | break; | 2171 | break; |
2126 | default: | 2172 | default: |
2127 | ath_err(common, "Unknown power mode %u\n", mode); | 2173 | ath_err(common, "Unknown power mode %u\n", mode); |
@@ -2691,6 +2737,9 @@ EXPORT_SYMBOL(ath9k_hw_setrxfilter); | |||
2691 | 2737 | ||
2692 | bool ath9k_hw_phy_disable(struct ath_hw *ah) | 2738 | bool ath9k_hw_phy_disable(struct ath_hw *ah) |
2693 | { | 2739 | { |
2740 | if (ath9k_hw_mci_is_enabled(ah)) | ||
2741 | ar9003_mci_bt_gain_ctrl(ah); | ||
2742 | |||
2694 | if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM)) | 2743 | if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM)) |
2695 | return false; | 2744 | return false; |
2696 | 2745 | ||
@@ -2725,7 +2774,8 @@ static int get_antenna_gain(struct ath_hw *ah, struct ath9k_channel *chan) | |||
2725 | return ah->eep_ops->get_eeprom(ah, gain_param); | 2774 | return ah->eep_ops->get_eeprom(ah, gain_param); |
2726 | } | 2775 | } |
2727 | 2776 | ||
2728 | void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan) | 2777 | void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan, |
2778 | bool test) | ||
2729 | { | 2779 | { |
2730 | struct ath_regulatory *reg = ath9k_hw_regulatory(ah); | 2780 | struct ath_regulatory *reg = ath9k_hw_regulatory(ah); |
2731 | struct ieee80211_channel *channel; | 2781 | struct ieee80211_channel *channel; |
@@ -2746,7 +2796,7 @@ void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan) | |||
2746 | 2796 | ||
2747 | ah->eep_ops->set_txpower(ah, chan, | 2797 | ah->eep_ops->set_txpower(ah, chan, |
2748 | ath9k_regd_get_ctl(reg, chan), | 2798 | ath9k_regd_get_ctl(reg, chan), |
2749 | ant_reduction, new_pwr, false); | 2799 | ant_reduction, new_pwr, test); |
2750 | } | 2800 | } |
2751 | 2801 | ||
2752 | void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test) | 2802 | void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test) |
@@ -2759,7 +2809,7 @@ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test) | |||
2759 | if (test) | 2809 | if (test) |
2760 | channel->max_power = MAX_RATE_POWER / 2; | 2810 | channel->max_power = MAX_RATE_POWER / 2; |
2761 | 2811 | ||
2762 | ath9k_hw_apply_txpower(ah, chan); | 2812 | ath9k_hw_apply_txpower(ah, chan, test); |
2763 | 2813 | ||
2764 | if (test) | 2814 | if (test) |
2765 | channel->max_power = DIV_ROUND_UP(reg->max_power_level, 2); | 2815 | channel->max_power = DIV_ROUND_UP(reg->max_power_level, 2); |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index aa1680a0c7fd..03d590924c64 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -348,12 +348,6 @@ enum ath9k_int { | |||
348 | CHANNEL_HT40MINUS) | 348 | CHANNEL_HT40MINUS) |
349 | 349 | ||
350 | #define MAX_RTT_TABLE_ENTRY 6 | 350 | #define MAX_RTT_TABLE_ENTRY 6 |
351 | #define RTT_HIST_MAX 3 | ||
352 | struct ath9k_rtt_hist { | ||
353 | u32 table[AR9300_MAX_CHAINS][RTT_HIST_MAX][MAX_RTT_TABLE_ENTRY]; | ||
354 | u8 num_readings; | ||
355 | }; | ||
356 | |||
357 | #define MAX_IQCAL_MEASUREMENT 8 | 351 | #define MAX_IQCAL_MEASUREMENT 8 |
358 | #define MAX_CL_TAB_ENTRY 16 | 352 | #define MAX_CL_TAB_ENTRY 16 |
359 | 353 | ||
@@ -363,6 +357,7 @@ struct ath9k_hw_cal_data { | |||
363 | int32_t CalValid; | 357 | int32_t CalValid; |
364 | int8_t iCoff; | 358 | int8_t iCoff; |
365 | int8_t qCoff; | 359 | int8_t qCoff; |
360 | bool rtt_done; | ||
366 | bool paprd_done; | 361 | bool paprd_done; |
367 | bool nfcal_pending; | 362 | bool nfcal_pending; |
368 | bool nfcal_interference; | 363 | bool nfcal_interference; |
@@ -373,8 +368,8 @@ struct ath9k_hw_cal_data { | |||
373 | u32 num_measures[AR9300_MAX_CHAINS]; | 368 | u32 num_measures[AR9300_MAX_CHAINS]; |
374 | int tx_corr_coeff[MAX_IQCAL_MEASUREMENT][AR9300_MAX_CHAINS]; | 369 | int tx_corr_coeff[MAX_IQCAL_MEASUREMENT][AR9300_MAX_CHAINS]; |
375 | u32 tx_clcal[AR9300_MAX_CHAINS][MAX_CL_TAB_ENTRY]; | 370 | u32 tx_clcal[AR9300_MAX_CHAINS][MAX_CL_TAB_ENTRY]; |
371 | u32 rtt_table[AR9300_MAX_CHAINS][MAX_RTT_TABLE_ENTRY]; | ||
376 | struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; | 372 | struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; |
377 | struct ath9k_rtt_hist rtt_hist; | ||
378 | }; | 373 | }; |
379 | 374 | ||
380 | struct ath9k_channel { | 375 | struct ath9k_channel { |
@@ -708,7 +703,6 @@ struct ath_hw { | |||
708 | struct ar5416Stats stats; | 703 | struct ar5416Stats stats; |
709 | struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES]; | 704 | struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES]; |
710 | 705 | ||
711 | int16_t curchan_rad_index; | ||
712 | enum ath9k_int imask; | 706 | enum ath9k_int imask; |
713 | u32 imrs2_reg; | 707 | u32 imrs2_reg; |
714 | u32 txok_interrupt_mask; | 708 | u32 txok_interrupt_mask; |
@@ -762,11 +756,6 @@ struct ath_hw { | |||
762 | 756 | ||
763 | u32 sta_id1_defaults; | 757 | u32 sta_id1_defaults; |
764 | u32 misc_mode; | 758 | u32 misc_mode; |
765 | enum { | ||
766 | AUTO_32KHZ, | ||
767 | USE_32KHZ, | ||
768 | DONT_USE_32KHZ, | ||
769 | } enable_32kHz_clock; | ||
770 | 759 | ||
771 | /* Private to hardware code */ | 760 | /* Private to hardware code */ |
772 | struct ath_hw_private_ops private_ops; | 761 | struct ath_hw_private_ops private_ops; |
@@ -783,7 +772,6 @@ struct ath_hw { | |||
783 | u32 *analogBank7Data; | 772 | u32 *analogBank7Data; |
784 | u32 *bank6Temp; | 773 | u32 *bank6Temp; |
785 | 774 | ||
786 | u8 txpower_limit; | ||
787 | int coverage_class; | 775 | int coverage_class; |
788 | u32 slottime; | 776 | u32 slottime; |
789 | u32 globaltxtimeout; | 777 | u32 globaltxtimeout; |
@@ -836,7 +824,6 @@ struct ath_hw { | |||
836 | struct ar5416IniArray ini_japan2484; | 824 | struct ar5416IniArray ini_japan2484; |
837 | struct ar5416IniArray iniModes_9271_ANI_reg; | 825 | struct ar5416IniArray iniModes_9271_ANI_reg; |
838 | struct ar5416IniArray ini_radio_post_sys2ant; | 826 | struct ar5416IniArray ini_radio_post_sys2ant; |
839 | struct ar5416IniArray ini_BTCOEX_MAX_TXPWR; | ||
840 | 827 | ||
841 | struct ar5416IniArray iniMac[ATH_INI_NUM_SPLIT]; | 828 | struct ar5416IniArray iniMac[ATH_INI_NUM_SPLIT]; |
842 | struct ar5416IniArray iniBB[ATH_INI_NUM_SPLIT]; | 829 | struct ar5416IniArray iniBB[ATH_INI_NUM_SPLIT]; |
@@ -848,7 +835,6 @@ struct ath_hw { | |||
848 | struct ath_gen_timer_table hw_gen_timers; | 835 | struct ath_gen_timer_table hw_gen_timers; |
849 | 836 | ||
850 | struct ar9003_txs *ts_ring; | 837 | struct ar9003_txs *ts_ring; |
851 | void *ts_start; | ||
852 | u32 ts_paddr_start; | 838 | u32 ts_paddr_start; |
853 | u32 ts_paddr_end; | 839 | u32 ts_paddr_end; |
854 | u16 ts_tail; | 840 | u16 ts_tail; |
@@ -915,7 +901,6 @@ static inline u8 get_streams(int mask) | |||
915 | } | 901 | } |
916 | 902 | ||
917 | /* Initialization, Detach, Reset */ | 903 | /* Initialization, Detach, Reset */ |
918 | const char *ath9k_hw_probe(u16 vendorid, u16 devid); | ||
919 | void ath9k_hw_deinit(struct ath_hw *ah); | 904 | void ath9k_hw_deinit(struct ath_hw *ah); |
920 | int ath9k_hw_init(struct ath_hw *ah); | 905 | int ath9k_hw_init(struct ath_hw *ah); |
921 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | 906 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, |
@@ -932,6 +917,8 @@ void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val); | |||
932 | void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna); | 917 | void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna); |
933 | 918 | ||
934 | /* General Operation */ | 919 | /* General Operation */ |
920 | void ath9k_hw_synth_delay(struct ath_hw *ah, struct ath9k_channel *chan, | ||
921 | int hw_delay); | ||
935 | bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout); | 922 | bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout); |
936 | void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array, | 923 | void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array, |
937 | int column, unsigned int *writecnt); | 924 | int column, unsigned int *writecnt); |
@@ -965,6 +952,13 @@ bool ath9k_hw_check_alive(struct ath_hw *ah); | |||
965 | 952 | ||
966 | bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode); | 953 | bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode); |
967 | 954 | ||
955 | #ifdef CONFIG_ATH9K_DEBUGFS | ||
956 | void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause); | ||
957 | #else | ||
958 | static inline void ath9k_debug_sync_cause(struct ath_common *common, | ||
959 | u32 sync_cause) {} | ||
960 | #endif | ||
961 | |||
968 | /* Generic hw timer primitives */ | 962 | /* Generic hw timer primitives */ |
969 | struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, | 963 | struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, |
970 | void (*trigger)(void *), | 964 | void (*trigger)(void *), |
@@ -985,7 +979,8 @@ void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len); | |||
985 | /* PHY */ | 979 | /* PHY */ |
986 | void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled, | 980 | void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled, |
987 | u32 *coef_mantissa, u32 *coef_exponent); | 981 | u32 *coef_mantissa, u32 *coef_exponent); |
988 | void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan); | 982 | void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan, |
983 | bool test); | ||
989 | 984 | ||
990 | /* | 985 | /* |
991 | * Code Specific to AR5008, AR9001 or AR9002, | 986 | * Code Specific to AR5008, AR9001 or AR9002, |
@@ -1011,7 +1006,6 @@ int ar9003_paprd_create_curve(struct ath_hw *ah, | |||
1011 | int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain); | 1006 | int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain); |
1012 | int ar9003_paprd_init_table(struct ath_hw *ah); | 1007 | int ar9003_paprd_init_table(struct ath_hw *ah); |
1013 | bool ar9003_paprd_is_done(struct ath_hw *ah); | 1008 | bool ar9003_paprd_is_done(struct ath_hw *ah); |
1014 | void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah, void *ds, u8 chains); | ||
1015 | 1009 | ||
1016 | /* Hardware family op attach helpers */ | 1010 | /* Hardware family op attach helpers */ |
1017 | void ar5008_hw_attach_phy_ops(struct ath_hw *ah); | 1011 | void ar5008_hw_attach_phy_ops(struct ath_hw *ah); |
@@ -1042,6 +1036,11 @@ static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah) | |||
1042 | { | 1036 | { |
1043 | return ah->btcoex_hw.enabled; | 1037 | return ah->btcoex_hw.enabled; |
1044 | } | 1038 | } |
1039 | static inline bool ath9k_hw_mci_is_enabled(struct ath_hw *ah) | ||
1040 | { | ||
1041 | return ah->btcoex_hw.enabled && (ah->caps.hw_caps & ATH9K_HW_CAP_MCI); | ||
1042 | |||
1043 | } | ||
1045 | void ath9k_hw_btcoex_enable(struct ath_hw *ah); | 1044 | void ath9k_hw_btcoex_enable(struct ath_hw *ah); |
1046 | static inline enum ath_btcoex_scheme | 1045 | static inline enum ath_btcoex_scheme |
1047 | ath9k_hw_get_btcoex_scheme(struct ath_hw *ah) | 1046 | ath9k_hw_get_btcoex_scheme(struct ath_hw *ah) |
@@ -1053,6 +1052,10 @@ static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah) | |||
1053 | { | 1052 | { |
1054 | return false; | 1053 | return false; |
1055 | } | 1054 | } |
1055 | static inline bool ath9k_hw_mci_is_enabled(struct ath_hw *ah) | ||
1056 | { | ||
1057 | return false; | ||
1058 | } | ||
1056 | static inline void ath9k_hw_btcoex_enable(struct ath_hw *ah) | 1059 | static inline void ath9k_hw_btcoex_enable(struct ath_hw *ah) |
1057 | { | 1060 | { |
1058 | } | 1061 | } |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 7a6b9f69a7b1..9dfce1a69c73 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -489,6 +489,7 @@ static void ath9k_init_misc(struct ath_softc *sc) | |||
489 | 489 | ||
490 | setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); | 490 | setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); |
491 | 491 | ||
492 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; | ||
492 | sc->config.txpowlimit = ATH_TXPOWER_MAX; | 493 | sc->config.txpowlimit = ATH_TXPOWER_MAX; |
493 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); | 494 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); |
494 | sc->beacon.slottime = ATH9K_SLOT_TIME_9; | 495 | sc->beacon.slottime = ATH9K_SLOT_TIME_9; |
@@ -560,6 +561,12 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
560 | tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, | 561 | tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, |
561 | (unsigned long)sc); | 562 | (unsigned long)sc); |
562 | 563 | ||
564 | INIT_WORK(&sc->hw_reset_work, ath_reset_work); | ||
565 | INIT_WORK(&sc->hw_check_work, ath_hw_check); | ||
566 | INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); | ||
567 | INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); | ||
568 | setup_timer(&sc->rx_poll_timer, ath_rx_poll, (unsigned long)sc); | ||
569 | |||
563 | /* | 570 | /* |
564 | * Cache line size is used to size and align various | 571 | * Cache line size is used to size and align various |
565 | * structures used to communicate with the hardware. | 572 | * structures used to communicate with the hardware. |
@@ -590,6 +597,9 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
590 | ath9k_cmn_init_crypto(sc->sc_ah); | 597 | ath9k_cmn_init_crypto(sc->sc_ah); |
591 | ath9k_init_misc(sc); | 598 | ath9k_init_misc(sc); |
592 | 599 | ||
600 | if (common->bus_ops->aspm_init) | ||
601 | common->bus_ops->aspm_init(common); | ||
602 | |||
593 | return 0; | 603 | return 0; |
594 | 604 | ||
595 | err_btcoex: | 605 | err_btcoex: |
@@ -646,6 +656,24 @@ void ath9k_reload_chainmask_settings(struct ath_softc *sc) | |||
646 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); | 656 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); |
647 | } | 657 | } |
648 | 658 | ||
659 | static const struct ieee80211_iface_limit if_limits[] = { | ||
660 | { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) | | ||
661 | BIT(NL80211_IFTYPE_P2P_CLIENT) | | ||
662 | BIT(NL80211_IFTYPE_WDS) }, | ||
663 | { .max = 8, .types = | ||
664 | #ifdef CONFIG_MAC80211_MESH | ||
665 | BIT(NL80211_IFTYPE_MESH_POINT) | | ||
666 | #endif | ||
667 | BIT(NL80211_IFTYPE_AP) | | ||
668 | BIT(NL80211_IFTYPE_P2P_GO) }, | ||
669 | }; | ||
670 | |||
671 | static const struct ieee80211_iface_combination if_comb = { | ||
672 | .limits = if_limits, | ||
673 | .n_limits = ARRAY_SIZE(if_limits), | ||
674 | .max_interfaces = 2048, | ||
675 | .num_different_channels = 1, | ||
676 | }; | ||
649 | 677 | ||
650 | void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | 678 | void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) |
651 | { | 679 | { |
@@ -675,6 +703,9 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
675 | BIT(NL80211_IFTYPE_ADHOC) | | 703 | BIT(NL80211_IFTYPE_ADHOC) | |
676 | BIT(NL80211_IFTYPE_MESH_POINT); | 704 | BIT(NL80211_IFTYPE_MESH_POINT); |
677 | 705 | ||
706 | hw->wiphy->iface_combinations = &if_comb; | ||
707 | hw->wiphy->n_iface_combinations = 1; | ||
708 | |||
678 | if (AR_SREV_5416(sc->sc_ah)) | 709 | if (AR_SREV_5416(sc->sc_ah)) |
679 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | 710 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
680 | 711 | ||
@@ -761,11 +792,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, | |||
761 | ARRAY_SIZE(ath9k_tpt_blink)); | 792 | ARRAY_SIZE(ath9k_tpt_blink)); |
762 | #endif | 793 | #endif |
763 | 794 | ||
764 | INIT_WORK(&sc->hw_reset_work, ath_reset_work); | ||
765 | INIT_WORK(&sc->hw_check_work, ath_hw_check); | ||
766 | INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); | ||
767 | INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); | ||
768 | |||
769 | /* Register with mac80211 */ | 795 | /* Register with mac80211 */ |
770 | error = ieee80211_register_hw(hw); | 796 | error = ieee80211_register_hw(hw); |
771 | if (error) | 797 | if (error) |
@@ -784,9 +810,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, | |||
784 | goto error_world; | 810 | goto error_world; |
785 | } | 811 | } |
786 | 812 | ||
787 | setup_timer(&sc->rx_poll_timer, ath_rx_poll, (unsigned long)sc); | ||
788 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; | ||
789 | |||
790 | ath_init_leds(sc); | 813 | ath_init_leds(sc); |
791 | ath_start_rfkill_poll(sc); | 814 | ath_start_rfkill_poll(sc); |
792 | 815 | ||
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c new file mode 100644 index 000000000000..a105c9426251 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/link.c | |||
@@ -0,0 +1,510 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "ath9k.h" | ||
18 | |||
19 | /* | ||
20 | * TX polling - checks if the TX engine is stuck somewhere | ||
21 | * and issues a chip reset if so. | ||
22 | */ | ||
23 | void ath_tx_complete_poll_work(struct work_struct *work) | ||
24 | { | ||
25 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
26 | tx_complete_work.work); | ||
27 | struct ath_txq *txq; | ||
28 | int i; | ||
29 | bool needreset = false; | ||
30 | #ifdef CONFIG_ATH9K_DEBUGFS | ||
31 | sc->tx_complete_poll_work_seen++; | ||
32 | #endif | ||
33 | |||
34 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | ||
35 | if (ATH_TXQ_SETUP(sc, i)) { | ||
36 | txq = &sc->tx.txq[i]; | ||
37 | ath_txq_lock(sc, txq); | ||
38 | if (txq->axq_depth) { | ||
39 | if (txq->axq_tx_inprogress) { | ||
40 | needreset = true; | ||
41 | ath_txq_unlock(sc, txq); | ||
42 | break; | ||
43 | } else { | ||
44 | txq->axq_tx_inprogress = true; | ||
45 | } | ||
46 | } | ||
47 | ath_txq_unlock_complete(sc, txq); | ||
48 | } | ||
49 | |||
50 | if (needreset) { | ||
51 | ath_dbg(ath9k_hw_common(sc->sc_ah), RESET, | ||
52 | "tx hung, resetting the chip\n"); | ||
53 | RESET_STAT_INC(sc, RESET_TYPE_TX_HANG); | ||
54 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | ||
55 | return; | ||
56 | } | ||
57 | |||
58 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, | ||
59 | msecs_to_jiffies(ATH_TX_COMPLETE_POLL_INT)); | ||
60 | } | ||
61 | |||
62 | /* | ||
63 | * Checks if the BB/MAC is hung. | ||
64 | */ | ||
65 | void ath_hw_check(struct work_struct *work) | ||
66 | { | ||
67 | struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work); | ||
68 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
69 | unsigned long flags; | ||
70 | int busy; | ||
71 | u8 is_alive, nbeacon = 1; | ||
72 | |||
73 | ath9k_ps_wakeup(sc); | ||
74 | is_alive = ath9k_hw_check_alive(sc->sc_ah); | ||
75 | |||
76 | if (is_alive && !AR_SREV_9300(sc->sc_ah)) | ||
77 | goto out; | ||
78 | else if (!is_alive && AR_SREV_9300(sc->sc_ah)) { | ||
79 | ath_dbg(common, RESET, | ||
80 | "DCU stuck is detected. Schedule chip reset\n"); | ||
81 | RESET_STAT_INC(sc, RESET_TYPE_MAC_HANG); | ||
82 | goto sched_reset; | ||
83 | } | ||
84 | |||
85 | spin_lock_irqsave(&common->cc_lock, flags); | ||
86 | busy = ath_update_survey_stats(sc); | ||
87 | spin_unlock_irqrestore(&common->cc_lock, flags); | ||
88 | |||
89 | ath_dbg(common, RESET, "Possible baseband hang, busy=%d (try %d)\n", | ||
90 | busy, sc->hw_busy_count + 1); | ||
91 | if (busy >= 99) { | ||
92 | if (++sc->hw_busy_count >= 3) { | ||
93 | RESET_STAT_INC(sc, RESET_TYPE_BB_HANG); | ||
94 | goto sched_reset; | ||
95 | } | ||
96 | } else if (busy >= 0) { | ||
97 | sc->hw_busy_count = 0; | ||
98 | nbeacon = 3; | ||
99 | } | ||
100 | |||
101 | ath_start_rx_poll(sc, nbeacon); | ||
102 | goto out; | ||
103 | |||
104 | sched_reset: | ||
105 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | ||
106 | out: | ||
107 | ath9k_ps_restore(sc); | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | * PLL-WAR for AR9485/AR9340 | ||
112 | */ | ||
113 | static bool ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum) | ||
114 | { | ||
115 | static int count; | ||
116 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
117 | |||
118 | if (pll_sqsum >= 0x40000) { | ||
119 | count++; | ||
120 | if (count == 3) { | ||
121 | ath_dbg(common, RESET, "PLL WAR, resetting the chip\n"); | ||
122 | RESET_STAT_INC(sc, RESET_TYPE_PLL_HANG); | ||
123 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | ||
124 | count = 0; | ||
125 | return true; | ||
126 | } | ||
127 | } else { | ||
128 | count = 0; | ||
129 | } | ||
130 | |||
131 | return false; | ||
132 | } | ||
133 | |||
134 | void ath_hw_pll_work(struct work_struct *work) | ||
135 | { | ||
136 | u32 pll_sqsum; | ||
137 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
138 | hw_pll_work.work); | ||
139 | /* | ||
140 | * ensure that the PLL WAR is executed only | ||
141 | * after the STA is associated (or) if the | ||
142 | * beaconing had started in interfaces that | ||
143 | * uses beacons. | ||
144 | */ | ||
145 | if (!test_bit(SC_OP_BEACONS, &sc->sc_flags)) | ||
146 | return; | ||
147 | |||
148 | ath9k_ps_wakeup(sc); | ||
149 | pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah); | ||
150 | ath9k_ps_restore(sc); | ||
151 | if (ath_hw_pll_rx_hang_check(sc, pll_sqsum)) | ||
152 | return; | ||
153 | |||
154 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, | ||
155 | msecs_to_jiffies(ATH_PLL_WORK_INTERVAL)); | ||
156 | } | ||
157 | |||
158 | /* | ||
159 | * RX Polling - monitors baseband hangs. | ||
160 | */ | ||
161 | void ath_start_rx_poll(struct ath_softc *sc, u8 nbeacon) | ||
162 | { | ||
163 | if (!AR_SREV_9300(sc->sc_ah)) | ||
164 | return; | ||
165 | |||
166 | if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) | ||
167 | return; | ||
168 | |||
169 | mod_timer(&sc->rx_poll_timer, jiffies + msecs_to_jiffies | ||
170 | (nbeacon * sc->cur_beacon_conf.beacon_interval)); | ||
171 | } | ||
172 | |||
173 | void ath_rx_poll(unsigned long data) | ||
174 | { | ||
175 | struct ath_softc *sc = (struct ath_softc *)data; | ||
176 | |||
177 | ieee80211_queue_work(sc->hw, &sc->hw_check_work); | ||
178 | } | ||
179 | |||
180 | /* | ||
181 | * PA Pre-distortion. | ||
182 | */ | ||
183 | static void ath_paprd_activate(struct ath_softc *sc) | ||
184 | { | ||
185 | struct ath_hw *ah = sc->sc_ah; | ||
186 | struct ath9k_hw_cal_data *caldata = ah->caldata; | ||
187 | int chain; | ||
188 | |||
189 | if (!caldata || !caldata->paprd_done) | ||
190 | return; | ||
191 | |||
192 | ath9k_ps_wakeup(sc); | ||
193 | ar9003_paprd_enable(ah, false); | ||
194 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { | ||
195 | if (!(ah->txchainmask & BIT(chain))) | ||
196 | continue; | ||
197 | |||
198 | ar9003_paprd_populate_single_table(ah, caldata, chain); | ||
199 | } | ||
200 | |||
201 | ar9003_paprd_enable(ah, true); | ||
202 | ath9k_ps_restore(sc); | ||
203 | } | ||
204 | |||
205 | static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int chain) | ||
206 | { | ||
207 | struct ieee80211_hw *hw = sc->hw; | ||
208 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
209 | struct ath_hw *ah = sc->sc_ah; | ||
210 | struct ath_common *common = ath9k_hw_common(ah); | ||
211 | struct ath_tx_control txctl; | ||
212 | int time_left; | ||
213 | |||
214 | memset(&txctl, 0, sizeof(txctl)); | ||
215 | txctl.txq = sc->tx.txq_map[WME_AC_BE]; | ||
216 | |||
217 | memset(tx_info, 0, sizeof(*tx_info)); | ||
218 | tx_info->band = hw->conf.channel->band; | ||
219 | tx_info->flags |= IEEE80211_TX_CTL_NO_ACK; | ||
220 | tx_info->control.rates[0].idx = 0; | ||
221 | tx_info->control.rates[0].count = 1; | ||
222 | tx_info->control.rates[0].flags = IEEE80211_TX_RC_MCS; | ||
223 | tx_info->control.rates[1].idx = -1; | ||
224 | |||
225 | init_completion(&sc->paprd_complete); | ||
226 | txctl.paprd = BIT(chain); | ||
227 | |||
228 | if (ath_tx_start(hw, skb, &txctl) != 0) { | ||
229 | ath_dbg(common, CALIBRATE, "PAPRD TX failed\n"); | ||
230 | dev_kfree_skb_any(skb); | ||
231 | return false; | ||
232 | } | ||
233 | |||
234 | time_left = wait_for_completion_timeout(&sc->paprd_complete, | ||
235 | msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); | ||
236 | |||
237 | if (!time_left) | ||
238 | ath_dbg(common, CALIBRATE, | ||
239 | "Timeout waiting for paprd training on TX chain %d\n", | ||
240 | chain); | ||
241 | |||
242 | return !!time_left; | ||
243 | } | ||
244 | |||
245 | void ath_paprd_calibrate(struct work_struct *work) | ||
246 | { | ||
247 | struct ath_softc *sc = container_of(work, struct ath_softc, paprd_work); | ||
248 | struct ieee80211_hw *hw = sc->hw; | ||
249 | struct ath_hw *ah = sc->sc_ah; | ||
250 | struct ieee80211_hdr *hdr; | ||
251 | struct sk_buff *skb = NULL; | ||
252 | struct ath9k_hw_cal_data *caldata = ah->caldata; | ||
253 | struct ath_common *common = ath9k_hw_common(ah); | ||
254 | int ftype; | ||
255 | int chain_ok = 0; | ||
256 | int chain; | ||
257 | int len = 1800; | ||
258 | |||
259 | if (!caldata) | ||
260 | return; | ||
261 | |||
262 | ath9k_ps_wakeup(sc); | ||
263 | |||
264 | if (ar9003_paprd_init_table(ah) < 0) | ||
265 | goto fail_paprd; | ||
266 | |||
267 | skb = alloc_skb(len, GFP_KERNEL); | ||
268 | if (!skb) | ||
269 | goto fail_paprd; | ||
270 | |||
271 | skb_put(skb, len); | ||
272 | memset(skb->data, 0, len); | ||
273 | hdr = (struct ieee80211_hdr *)skb->data; | ||
274 | ftype = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC; | ||
275 | hdr->frame_control = cpu_to_le16(ftype); | ||
276 | hdr->duration_id = cpu_to_le16(10); | ||
277 | memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN); | ||
278 | memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); | ||
279 | memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); | ||
280 | |||
281 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { | ||
282 | if (!(ah->txchainmask & BIT(chain))) | ||
283 | continue; | ||
284 | |||
285 | chain_ok = 0; | ||
286 | |||
287 | ath_dbg(common, CALIBRATE, | ||
288 | "Sending PAPRD frame for thermal measurement on chain %d\n", | ||
289 | chain); | ||
290 | if (!ath_paprd_send_frame(sc, skb, chain)) | ||
291 | goto fail_paprd; | ||
292 | |||
293 | ar9003_paprd_setup_gain_table(ah, chain); | ||
294 | |||
295 | ath_dbg(common, CALIBRATE, | ||
296 | "Sending PAPRD training frame on chain %d\n", chain); | ||
297 | if (!ath_paprd_send_frame(sc, skb, chain)) | ||
298 | goto fail_paprd; | ||
299 | |||
300 | if (!ar9003_paprd_is_done(ah)) { | ||
301 | ath_dbg(common, CALIBRATE, | ||
302 | "PAPRD not yet done on chain %d\n", chain); | ||
303 | break; | ||
304 | } | ||
305 | |||
306 | if (ar9003_paprd_create_curve(ah, caldata, chain)) { | ||
307 | ath_dbg(common, CALIBRATE, | ||
308 | "PAPRD create curve failed on chain %d\n", | ||
309 | chain); | ||
310 | break; | ||
311 | } | ||
312 | |||
313 | chain_ok = 1; | ||
314 | } | ||
315 | kfree_skb(skb); | ||
316 | |||
317 | if (chain_ok) { | ||
318 | caldata->paprd_done = true; | ||
319 | ath_paprd_activate(sc); | ||
320 | } | ||
321 | |||
322 | fail_paprd: | ||
323 | ath9k_ps_restore(sc); | ||
324 | } | ||
325 | |||
326 | /* | ||
327 | * ANI performs periodic noise floor calibration | ||
328 | * that is used to adjust and optimize the chip performance. This | ||
329 | * takes environmental changes (location, temperature) into account. | ||
330 | * When the task is complete, it reschedules itself depending on the | ||
331 | * appropriate interval that was calculated. | ||
332 | */ | ||
333 | void ath_ani_calibrate(unsigned long data) | ||
334 | { | ||
335 | struct ath_softc *sc = (struct ath_softc *)data; | ||
336 | struct ath_hw *ah = sc->sc_ah; | ||
337 | struct ath_common *common = ath9k_hw_common(ah); | ||
338 | bool longcal = false; | ||
339 | bool shortcal = false; | ||
340 | bool aniflag = false; | ||
341 | unsigned int timestamp = jiffies_to_msecs(jiffies); | ||
342 | u32 cal_interval, short_cal_interval, long_cal_interval; | ||
343 | unsigned long flags; | ||
344 | |||
345 | if (ah->caldata && ah->caldata->nfcal_interference) | ||
346 | long_cal_interval = ATH_LONG_CALINTERVAL_INT; | ||
347 | else | ||
348 | long_cal_interval = ATH_LONG_CALINTERVAL; | ||
349 | |||
350 | short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ? | ||
351 | ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL; | ||
352 | |||
353 | /* Only calibrate if awake */ | ||
354 | if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE) | ||
355 | goto set_timer; | ||
356 | |||
357 | ath9k_ps_wakeup(sc); | ||
358 | |||
359 | /* Long calibration runs independently of short calibration. */ | ||
360 | if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) { | ||
361 | longcal = true; | ||
362 | common->ani.longcal_timer = timestamp; | ||
363 | } | ||
364 | |||
365 | /* Short calibration applies only while caldone is false */ | ||
366 | if (!common->ani.caldone) { | ||
367 | if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) { | ||
368 | shortcal = true; | ||
369 | common->ani.shortcal_timer = timestamp; | ||
370 | common->ani.resetcal_timer = timestamp; | ||
371 | } | ||
372 | } else { | ||
373 | if ((timestamp - common->ani.resetcal_timer) >= | ||
374 | ATH_RESTART_CALINTERVAL) { | ||
375 | common->ani.caldone = ath9k_hw_reset_calvalid(ah); | ||
376 | if (common->ani.caldone) | ||
377 | common->ani.resetcal_timer = timestamp; | ||
378 | } | ||
379 | } | ||
380 | |||
381 | /* Verify whether we must check ANI */ | ||
382 | if (sc->sc_ah->config.enable_ani | ||
383 | && (timestamp - common->ani.checkani_timer) >= | ||
384 | ah->config.ani_poll_interval) { | ||
385 | aniflag = true; | ||
386 | common->ani.checkani_timer = timestamp; | ||
387 | } | ||
388 | |||
389 | /* Call ANI routine if necessary */ | ||
390 | if (aniflag) { | ||
391 | spin_lock_irqsave(&common->cc_lock, flags); | ||
392 | ath9k_hw_ani_monitor(ah, ah->curchan); | ||
393 | ath_update_survey_stats(sc); | ||
394 | spin_unlock_irqrestore(&common->cc_lock, flags); | ||
395 | } | ||
396 | |||
397 | /* Perform calibration if necessary */ | ||
398 | if (longcal || shortcal) { | ||
399 | common->ani.caldone = | ||
400 | ath9k_hw_calibrate(ah, ah->curchan, | ||
401 | ah->rxchainmask, longcal); | ||
402 | } | ||
403 | |||
404 | ath_dbg(common, ANI, | ||
405 | "Calibration @%lu finished: %s %s %s, caldone: %s\n", | ||
406 | jiffies, | ||
407 | longcal ? "long" : "", shortcal ? "short" : "", | ||
408 | aniflag ? "ani" : "", common->ani.caldone ? "true" : "false"); | ||
409 | |||
410 | ath9k_ps_restore(sc); | ||
411 | |||
412 | set_timer: | ||
413 | /* | ||
414 | * Set timer interval based on previous results. | ||
415 | * The interval must be the shortest necessary to satisfy ANI, | ||
416 | * short calibration and long calibration. | ||
417 | */ | ||
418 | ath9k_debug_samp_bb_mac(sc); | ||
419 | cal_interval = ATH_LONG_CALINTERVAL; | ||
420 | if (sc->sc_ah->config.enable_ani) | ||
421 | cal_interval = min(cal_interval, | ||
422 | (u32)ah->config.ani_poll_interval); | ||
423 | if (!common->ani.caldone) | ||
424 | cal_interval = min(cal_interval, (u32)short_cal_interval); | ||
425 | |||
426 | mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); | ||
427 | if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) { | ||
428 | if (!ah->caldata->paprd_done) | ||
429 | ieee80211_queue_work(sc->hw, &sc->paprd_work); | ||
430 | else if (!ah->paprd_table_write_done) | ||
431 | ath_paprd_activate(sc); | ||
432 | } | ||
433 | } | ||
434 | |||
435 | void ath_start_ani(struct ath_common *common) | ||
436 | { | ||
437 | struct ath_hw *ah = common->ah; | ||
438 | unsigned long timestamp = jiffies_to_msecs(jiffies); | ||
439 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
440 | |||
441 | if (!test_bit(SC_OP_ANI_RUN, &sc->sc_flags)) | ||
442 | return; | ||
443 | |||
444 | if (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) | ||
445 | return; | ||
446 | |||
447 | common->ani.longcal_timer = timestamp; | ||
448 | common->ani.shortcal_timer = timestamp; | ||
449 | common->ani.checkani_timer = timestamp; | ||
450 | |||
451 | mod_timer(&common->ani.timer, | ||
452 | jiffies + msecs_to_jiffies((u32)ah->config.ani_poll_interval)); | ||
453 | } | ||
454 | |||
455 | void ath_update_survey_nf(struct ath_softc *sc, int channel) | ||
456 | { | ||
457 | struct ath_hw *ah = sc->sc_ah; | ||
458 | struct ath9k_channel *chan = &ah->channels[channel]; | ||
459 | struct survey_info *survey = &sc->survey[channel]; | ||
460 | |||
461 | if (chan->noisefloor) { | ||
462 | survey->filled |= SURVEY_INFO_NOISE_DBM; | ||
463 | survey->noise = ath9k_hw_getchan_noise(ah, chan); | ||
464 | } | ||
465 | } | ||
466 | |||
467 | /* | ||
468 | * Updates the survey statistics and returns the busy time since last | ||
469 | * update in %, if the measurement duration was long enough for the | ||
470 | * result to be useful, -1 otherwise. | ||
471 | */ | ||
472 | int ath_update_survey_stats(struct ath_softc *sc) | ||
473 | { | ||
474 | struct ath_hw *ah = sc->sc_ah; | ||
475 | struct ath_common *common = ath9k_hw_common(ah); | ||
476 | int pos = ah->curchan - &ah->channels[0]; | ||
477 | struct survey_info *survey = &sc->survey[pos]; | ||
478 | struct ath_cycle_counters *cc = &common->cc_survey; | ||
479 | unsigned int div = common->clockrate * 1000; | ||
480 | int ret = 0; | ||
481 | |||
482 | if (!ah->curchan) | ||
483 | return -1; | ||
484 | |||
485 | if (ah->power_mode == ATH9K_PM_AWAKE) | ||
486 | ath_hw_cycle_counters_update(common); | ||
487 | |||
488 | if (cc->cycles > 0) { | ||
489 | survey->filled |= SURVEY_INFO_CHANNEL_TIME | | ||
490 | SURVEY_INFO_CHANNEL_TIME_BUSY | | ||
491 | SURVEY_INFO_CHANNEL_TIME_RX | | ||
492 | SURVEY_INFO_CHANNEL_TIME_TX; | ||
493 | survey->channel_time += cc->cycles / div; | ||
494 | survey->channel_time_busy += cc->rx_busy / div; | ||
495 | survey->channel_time_rx += cc->rx_frame / div; | ||
496 | survey->channel_time_tx += cc->tx_frame / div; | ||
497 | } | ||
498 | |||
499 | if (cc->cycles < div) | ||
500 | return -1; | ||
501 | |||
502 | if (cc->cycles > 0) | ||
503 | ret = cc->rx_busy * 100 / cc->cycles; | ||
504 | |||
505 | memset(cc, 0, sizeof(*cc)); | ||
506 | |||
507 | ath_update_survey_nf(sc, pos); | ||
508 | |||
509 | return ret; | ||
510 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index f7bd2532269c..04ef775ccee1 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c | |||
@@ -133,8 +133,16 @@ EXPORT_SYMBOL(ath9k_hw_updatetxtriglevel); | |||
133 | 133 | ||
134 | void ath9k_hw_abort_tx_dma(struct ath_hw *ah) | 134 | void ath9k_hw_abort_tx_dma(struct ath_hw *ah) |
135 | { | 135 | { |
136 | int maxdelay = 1000; | ||
136 | int i, q; | 137 | int i, q; |
137 | 138 | ||
139 | if (ah->curchan) { | ||
140 | if (IS_CHAN_HALF_RATE(ah->curchan)) | ||
141 | maxdelay *= 2; | ||
142 | else if (IS_CHAN_QUARTER_RATE(ah->curchan)) | ||
143 | maxdelay *= 4; | ||
144 | } | ||
145 | |||
138 | REG_WRITE(ah, AR_Q_TXD, AR_Q_TXD_M); | 146 | REG_WRITE(ah, AR_Q_TXD, AR_Q_TXD_M); |
139 | 147 | ||
140 | REG_SET_BIT(ah, AR_PCU_MISC, AR_PCU_FORCE_QUIET_COLL | AR_PCU_CLEAR_VMF); | 148 | REG_SET_BIT(ah, AR_PCU_MISC, AR_PCU_FORCE_QUIET_COLL | AR_PCU_CLEAR_VMF); |
@@ -142,7 +150,7 @@ void ath9k_hw_abort_tx_dma(struct ath_hw *ah) | |||
142 | REG_SET_BIT(ah, AR_D_GBL_IFS_MISC, AR_D_GBL_IFS_MISC_IGNORE_BACKOFF); | 150 | REG_SET_BIT(ah, AR_D_GBL_IFS_MISC, AR_D_GBL_IFS_MISC_IGNORE_BACKOFF); |
143 | 151 | ||
144 | for (q = 0; q < AR_NUM_QCU; q++) { | 152 | for (q = 0; q < AR_NUM_QCU; q++) { |
145 | for (i = 0; i < 1000; i++) { | 153 | for (i = 0; i < maxdelay; i++) { |
146 | if (i) | 154 | if (i) |
147 | udelay(5); | 155 | udelay(5); |
148 | 156 | ||
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 5de648c243bf..52561b341d68 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -101,6 +101,7 @@ void ath9k_ps_wakeup(struct ath_softc *sc) | |||
101 | spin_lock(&common->cc_lock); | 101 | spin_lock(&common->cc_lock); |
102 | ath_hw_cycle_counters_update(common); | 102 | ath_hw_cycle_counters_update(common); |
103 | memset(&common->cc_survey, 0, sizeof(common->cc_survey)); | 103 | memset(&common->cc_survey, 0, sizeof(common->cc_survey)); |
104 | memset(&common->cc_ani, 0, sizeof(common->cc_ani)); | ||
104 | spin_unlock(&common->cc_lock); | 105 | spin_unlock(&common->cc_lock); |
105 | } | 106 | } |
106 | 107 | ||
@@ -113,23 +114,25 @@ void ath9k_ps_restore(struct ath_softc *sc) | |||
113 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 114 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
114 | enum ath9k_power_mode mode; | 115 | enum ath9k_power_mode mode; |
115 | unsigned long flags; | 116 | unsigned long flags; |
117 | bool reset; | ||
116 | 118 | ||
117 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | 119 | spin_lock_irqsave(&sc->sc_pm_lock, flags); |
118 | if (--sc->ps_usecount != 0) | 120 | if (--sc->ps_usecount != 0) |
119 | goto unlock; | 121 | goto unlock; |
120 | 122 | ||
121 | if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) | 123 | if (sc->ps_idle) { |
122 | goto unlock; | 124 | ath9k_hw_setrxabort(sc->sc_ah, 1); |
123 | 125 | ath9k_hw_stopdmarecv(sc->sc_ah, &reset); | |
124 | if (sc->ps_idle) | ||
125 | mode = ATH9K_PM_FULL_SLEEP; | 126 | mode = ATH9K_PM_FULL_SLEEP; |
126 | else if (sc->ps_enabled && | 127 | } else if (sc->ps_enabled && |
127 | !(sc->ps_flags & (PS_WAIT_FOR_BEACON | | 128 | !(sc->ps_flags & (PS_WAIT_FOR_BEACON | |
128 | PS_WAIT_FOR_CAB | | 129 | PS_WAIT_FOR_CAB | |
129 | PS_WAIT_FOR_PSPOLL_DATA))) | 130 | PS_WAIT_FOR_PSPOLL_DATA | |
131 | PS_WAIT_FOR_TX_ACK))) { | ||
130 | mode = ATH9K_PM_NETWORK_SLEEP; | 132 | mode = ATH9K_PM_NETWORK_SLEEP; |
131 | else | 133 | } else { |
132 | goto unlock; | 134 | goto unlock; |
135 | } | ||
133 | 136 | ||
134 | spin_lock(&common->cc_lock); | 137 | spin_lock(&common->cc_lock); |
135 | ath_hw_cycle_counters_update(common); | 138 | ath_hw_cycle_counters_update(common); |
@@ -141,90 +144,15 @@ void ath9k_ps_restore(struct ath_softc *sc) | |||
141 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | 144 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); |
142 | } | 145 | } |
143 | 146 | ||
144 | void ath_start_ani(struct ath_common *common) | ||
145 | { | ||
146 | struct ath_hw *ah = common->ah; | ||
147 | unsigned long timestamp = jiffies_to_msecs(jiffies); | ||
148 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
149 | |||
150 | if (!(sc->sc_flags & SC_OP_ANI_RUN)) | ||
151 | return; | ||
152 | |||
153 | if (sc->sc_flags & SC_OP_OFFCHANNEL) | ||
154 | return; | ||
155 | |||
156 | common->ani.longcal_timer = timestamp; | ||
157 | common->ani.shortcal_timer = timestamp; | ||
158 | common->ani.checkani_timer = timestamp; | ||
159 | |||
160 | mod_timer(&common->ani.timer, | ||
161 | jiffies + | ||
162 | msecs_to_jiffies((u32)ah->config.ani_poll_interval)); | ||
163 | } | ||
164 | |||
165 | static void ath_update_survey_nf(struct ath_softc *sc, int channel) | ||
166 | { | ||
167 | struct ath_hw *ah = sc->sc_ah; | ||
168 | struct ath9k_channel *chan = &ah->channels[channel]; | ||
169 | struct survey_info *survey = &sc->survey[channel]; | ||
170 | |||
171 | if (chan->noisefloor) { | ||
172 | survey->filled |= SURVEY_INFO_NOISE_DBM; | ||
173 | survey->noise = ath9k_hw_getchan_noise(ah, chan); | ||
174 | } | ||
175 | } | ||
176 | |||
177 | /* | ||
178 | * Updates the survey statistics and returns the busy time since last | ||
179 | * update in %, if the measurement duration was long enough for the | ||
180 | * result to be useful, -1 otherwise. | ||
181 | */ | ||
182 | static int ath_update_survey_stats(struct ath_softc *sc) | ||
183 | { | ||
184 | struct ath_hw *ah = sc->sc_ah; | ||
185 | struct ath_common *common = ath9k_hw_common(ah); | ||
186 | int pos = ah->curchan - &ah->channels[0]; | ||
187 | struct survey_info *survey = &sc->survey[pos]; | ||
188 | struct ath_cycle_counters *cc = &common->cc_survey; | ||
189 | unsigned int div = common->clockrate * 1000; | ||
190 | int ret = 0; | ||
191 | |||
192 | if (!ah->curchan) | ||
193 | return -1; | ||
194 | |||
195 | if (ah->power_mode == ATH9K_PM_AWAKE) | ||
196 | ath_hw_cycle_counters_update(common); | ||
197 | |||
198 | if (cc->cycles > 0) { | ||
199 | survey->filled |= SURVEY_INFO_CHANNEL_TIME | | ||
200 | SURVEY_INFO_CHANNEL_TIME_BUSY | | ||
201 | SURVEY_INFO_CHANNEL_TIME_RX | | ||
202 | SURVEY_INFO_CHANNEL_TIME_TX; | ||
203 | survey->channel_time += cc->cycles / div; | ||
204 | survey->channel_time_busy += cc->rx_busy / div; | ||
205 | survey->channel_time_rx += cc->rx_frame / div; | ||
206 | survey->channel_time_tx += cc->tx_frame / div; | ||
207 | } | ||
208 | |||
209 | if (cc->cycles < div) | ||
210 | return -1; | ||
211 | |||
212 | if (cc->cycles > 0) | ||
213 | ret = cc->rx_busy * 100 / cc->cycles; | ||
214 | |||
215 | memset(cc, 0, sizeof(*cc)); | ||
216 | |||
217 | ath_update_survey_nf(sc, pos); | ||
218 | |||
219 | return ret; | ||
220 | } | ||
221 | |||
222 | static void __ath_cancel_work(struct ath_softc *sc) | 147 | static void __ath_cancel_work(struct ath_softc *sc) |
223 | { | 148 | { |
224 | cancel_work_sync(&sc->paprd_work); | 149 | cancel_work_sync(&sc->paprd_work); |
225 | cancel_work_sync(&sc->hw_check_work); | 150 | cancel_work_sync(&sc->hw_check_work); |
226 | cancel_delayed_work_sync(&sc->tx_complete_work); | 151 | cancel_delayed_work_sync(&sc->tx_complete_work); |
227 | cancel_delayed_work_sync(&sc->hw_pll_work); | 152 | cancel_delayed_work_sync(&sc->hw_pll_work); |
153 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT | ||
154 | cancel_work_sync(&sc->mci_work); | ||
155 | #endif | ||
228 | } | 156 | } |
229 | 157 | ||
230 | static void ath_cancel_work(struct ath_softc *sc) | 158 | static void ath_cancel_work(struct ath_softc *sc) |
@@ -233,11 +161,27 @@ static void ath_cancel_work(struct ath_softc *sc) | |||
233 | cancel_work_sync(&sc->hw_reset_work); | 161 | cancel_work_sync(&sc->hw_reset_work); |
234 | } | 162 | } |
235 | 163 | ||
164 | static void ath_restart_work(struct ath_softc *sc) | ||
165 | { | ||
166 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
167 | |||
168 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); | ||
169 | |||
170 | if (AR_SREV_9485(sc->sc_ah) || AR_SREV_9340(sc->sc_ah)) | ||
171 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, | ||
172 | msecs_to_jiffies(ATH_PLL_WORK_INTERVAL)); | ||
173 | |||
174 | ath_start_rx_poll(sc, 3); | ||
175 | |||
176 | if (!common->disable_ani) | ||
177 | ath_start_ani(common); | ||
178 | } | ||
179 | |||
236 | static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) | 180 | static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) |
237 | { | 181 | { |
238 | struct ath_hw *ah = sc->sc_ah; | 182 | struct ath_hw *ah = sc->sc_ah; |
239 | struct ath_common *common = ath9k_hw_common(ah); | 183 | struct ath_common *common = ath9k_hw_common(ah); |
240 | bool ret; | 184 | bool ret = true; |
241 | 185 | ||
242 | ieee80211_stop_queues(sc->hw); | 186 | ieee80211_stop_queues(sc->hw); |
243 | 187 | ||
@@ -248,11 +192,12 @@ static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) | |||
248 | ath9k_debug_samp_bb_mac(sc); | 192 | ath9k_debug_samp_bb_mac(sc); |
249 | ath9k_hw_disable_interrupts(ah); | 193 | ath9k_hw_disable_interrupts(ah); |
250 | 194 | ||
251 | ret = ath_drain_all_txq(sc, retry_tx); | ||
252 | |||
253 | if (!ath_stoprecv(sc)) | 195 | if (!ath_stoprecv(sc)) |
254 | ret = false; | 196 | ret = false; |
255 | 197 | ||
198 | if (!ath_drain_all_txq(sc, retry_tx)) | ||
199 | ret = false; | ||
200 | |||
256 | if (!flush) { | 201 | if (!flush) { |
257 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | 202 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) |
258 | ath_rx_tasklet(sc, 1, true); | 203 | ath_rx_tasklet(sc, 1, true); |
@@ -268,6 +213,7 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) | |||
268 | { | 213 | { |
269 | struct ath_hw *ah = sc->sc_ah; | 214 | struct ath_hw *ah = sc->sc_ah; |
270 | struct ath_common *common = ath9k_hw_common(ah); | 215 | struct ath_common *common = ath9k_hw_common(ah); |
216 | unsigned long flags; | ||
271 | 217 | ||
272 | if (ath_startrecv(sc) != 0) { | 218 | if (ath_startrecv(sc) != 0) { |
273 | ath_err(common, "Unable to restart recv logic\n"); | 219 | ath_err(common, "Unable to restart recv logic\n"); |
@@ -276,36 +222,30 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) | |||
276 | 222 | ||
277 | ath9k_cmn_update_txpow(ah, sc->curtxpow, | 223 | ath9k_cmn_update_txpow(ah, sc->curtxpow, |
278 | sc->config.txpowlimit, &sc->curtxpow); | 224 | sc->config.txpowlimit, &sc->curtxpow); |
225 | |||
226 | clear_bit(SC_OP_HW_RESET, &sc->sc_flags); | ||
279 | ath9k_hw_set_interrupts(ah); | 227 | ath9k_hw_set_interrupts(ah); |
280 | ath9k_hw_enable_interrupts(ah); | 228 | ath9k_hw_enable_interrupts(ah); |
281 | 229 | ||
282 | if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)) && start) { | 230 | if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) && start) { |
283 | if (sc->sc_flags & SC_OP_BEACONS) | 231 | if (!test_bit(SC_OP_BEACONS, &sc->sc_flags)) |
284 | ath_set_beacon(sc); | 232 | goto work; |
285 | 233 | ||
286 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); | 234 | ath_set_beacon(sc); |
287 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2); | ||
288 | ath_start_rx_poll(sc, 3); | ||
289 | if (!common->disable_ani) | ||
290 | ath_start_ani(common); | ||
291 | } | ||
292 | |||
293 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) && sc->ant_rx != 3) { | ||
294 | struct ath_hw_antcomb_conf div_ant_conf; | ||
295 | u8 lna_conf; | ||
296 | |||
297 | ath9k_hw_antdiv_comb_conf_get(ah, &div_ant_conf); | ||
298 | 235 | ||
299 | if (sc->ant_rx == 1) | 236 | if (ah->opmode == NL80211_IFTYPE_STATION && |
300 | lna_conf = ATH_ANT_DIV_COMB_LNA1; | 237 | test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { |
301 | else | 238 | spin_lock_irqsave(&sc->sc_pm_lock, flags); |
302 | lna_conf = ATH_ANT_DIV_COMB_LNA2; | 239 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; |
303 | div_ant_conf.main_lna_conf = lna_conf; | 240 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); |
304 | div_ant_conf.alt_lna_conf = lna_conf; | 241 | } |
305 | 242 | work: | |
306 | ath9k_hw_antdiv_comb_conf_set(ah, &div_ant_conf); | 243 | ath_restart_work(sc); |
307 | } | 244 | } |
308 | 245 | ||
246 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) && sc->ant_rx != 3) | ||
247 | ath_ant_comb_update(sc); | ||
248 | |||
309 | ieee80211_wake_queues(sc->hw); | 249 | ieee80211_wake_queues(sc->hw); |
310 | 250 | ||
311 | return true; | 251 | return true; |
@@ -325,7 +265,7 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, | |||
325 | 265 | ||
326 | spin_lock_bh(&sc->sc_pcu_lock); | 266 | spin_lock_bh(&sc->sc_pcu_lock); |
327 | 267 | ||
328 | if (!(sc->sc_flags & SC_OP_OFFCHANNEL)) { | 268 | if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) { |
329 | fastcc = false; | 269 | fastcc = false; |
330 | caldata = &sc->caldata; | 270 | caldata = &sc->caldata; |
331 | } | 271 | } |
@@ -368,7 +308,7 @@ static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
368 | { | 308 | { |
369 | int r; | 309 | int r; |
370 | 310 | ||
371 | if (sc->sc_flags & SC_OP_INVALID) | 311 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) |
372 | return -EIO; | 312 | return -EIO; |
373 | 313 | ||
374 | r = ath_reset_internal(sc, hchan, false); | 314 | r = ath_reset_internal(sc, hchan, false); |
@@ -376,258 +316,6 @@ static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
376 | return r; | 316 | return r; |
377 | } | 317 | } |
378 | 318 | ||
379 | static void ath_paprd_activate(struct ath_softc *sc) | ||
380 | { | ||
381 | struct ath_hw *ah = sc->sc_ah; | ||
382 | struct ath9k_hw_cal_data *caldata = ah->caldata; | ||
383 | int chain; | ||
384 | |||
385 | if (!caldata || !caldata->paprd_done) | ||
386 | return; | ||
387 | |||
388 | ath9k_ps_wakeup(sc); | ||
389 | ar9003_paprd_enable(ah, false); | ||
390 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { | ||
391 | if (!(ah->txchainmask & BIT(chain))) | ||
392 | continue; | ||
393 | |||
394 | ar9003_paprd_populate_single_table(ah, caldata, chain); | ||
395 | } | ||
396 | |||
397 | ar9003_paprd_enable(ah, true); | ||
398 | ath9k_ps_restore(sc); | ||
399 | } | ||
400 | |||
401 | static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int chain) | ||
402 | { | ||
403 | struct ieee80211_hw *hw = sc->hw; | ||
404 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
405 | struct ath_hw *ah = sc->sc_ah; | ||
406 | struct ath_common *common = ath9k_hw_common(ah); | ||
407 | struct ath_tx_control txctl; | ||
408 | int time_left; | ||
409 | |||
410 | memset(&txctl, 0, sizeof(txctl)); | ||
411 | txctl.txq = sc->tx.txq_map[WME_AC_BE]; | ||
412 | |||
413 | memset(tx_info, 0, sizeof(*tx_info)); | ||
414 | tx_info->band = hw->conf.channel->band; | ||
415 | tx_info->flags |= IEEE80211_TX_CTL_NO_ACK; | ||
416 | tx_info->control.rates[0].idx = 0; | ||
417 | tx_info->control.rates[0].count = 1; | ||
418 | tx_info->control.rates[0].flags = IEEE80211_TX_RC_MCS; | ||
419 | tx_info->control.rates[1].idx = -1; | ||
420 | |||
421 | init_completion(&sc->paprd_complete); | ||
422 | txctl.paprd = BIT(chain); | ||
423 | |||
424 | if (ath_tx_start(hw, skb, &txctl) != 0) { | ||
425 | ath_dbg(common, CALIBRATE, "PAPRD TX failed\n"); | ||
426 | dev_kfree_skb_any(skb); | ||
427 | return false; | ||
428 | } | ||
429 | |||
430 | time_left = wait_for_completion_timeout(&sc->paprd_complete, | ||
431 | msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); | ||
432 | |||
433 | if (!time_left) | ||
434 | ath_dbg(common, CALIBRATE, | ||
435 | "Timeout waiting for paprd training on TX chain %d\n", | ||
436 | chain); | ||
437 | |||
438 | return !!time_left; | ||
439 | } | ||
440 | |||
441 | void ath_paprd_calibrate(struct work_struct *work) | ||
442 | { | ||
443 | struct ath_softc *sc = container_of(work, struct ath_softc, paprd_work); | ||
444 | struct ieee80211_hw *hw = sc->hw; | ||
445 | struct ath_hw *ah = sc->sc_ah; | ||
446 | struct ieee80211_hdr *hdr; | ||
447 | struct sk_buff *skb = NULL; | ||
448 | struct ath9k_hw_cal_data *caldata = ah->caldata; | ||
449 | struct ath_common *common = ath9k_hw_common(ah); | ||
450 | int ftype; | ||
451 | int chain_ok = 0; | ||
452 | int chain; | ||
453 | int len = 1800; | ||
454 | |||
455 | if (!caldata) | ||
456 | return; | ||
457 | |||
458 | ath9k_ps_wakeup(sc); | ||
459 | |||
460 | if (ar9003_paprd_init_table(ah) < 0) | ||
461 | goto fail_paprd; | ||
462 | |||
463 | skb = alloc_skb(len, GFP_KERNEL); | ||
464 | if (!skb) | ||
465 | goto fail_paprd; | ||
466 | |||
467 | skb_put(skb, len); | ||
468 | memset(skb->data, 0, len); | ||
469 | hdr = (struct ieee80211_hdr *)skb->data; | ||
470 | ftype = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC; | ||
471 | hdr->frame_control = cpu_to_le16(ftype); | ||
472 | hdr->duration_id = cpu_to_le16(10); | ||
473 | memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN); | ||
474 | memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); | ||
475 | memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); | ||
476 | |||
477 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { | ||
478 | if (!(ah->txchainmask & BIT(chain))) | ||
479 | continue; | ||
480 | |||
481 | chain_ok = 0; | ||
482 | |||
483 | ath_dbg(common, CALIBRATE, | ||
484 | "Sending PAPRD frame for thermal measurement on chain %d\n", | ||
485 | chain); | ||
486 | if (!ath_paprd_send_frame(sc, skb, chain)) | ||
487 | goto fail_paprd; | ||
488 | |||
489 | ar9003_paprd_setup_gain_table(ah, chain); | ||
490 | |||
491 | ath_dbg(common, CALIBRATE, | ||
492 | "Sending PAPRD training frame on chain %d\n", chain); | ||
493 | if (!ath_paprd_send_frame(sc, skb, chain)) | ||
494 | goto fail_paprd; | ||
495 | |||
496 | if (!ar9003_paprd_is_done(ah)) { | ||
497 | ath_dbg(common, CALIBRATE, | ||
498 | "PAPRD not yet done on chain %d\n", chain); | ||
499 | break; | ||
500 | } | ||
501 | |||
502 | if (ar9003_paprd_create_curve(ah, caldata, chain)) { | ||
503 | ath_dbg(common, CALIBRATE, | ||
504 | "PAPRD create curve failed on chain %d\n", | ||
505 | chain); | ||
506 | break; | ||
507 | } | ||
508 | |||
509 | chain_ok = 1; | ||
510 | } | ||
511 | kfree_skb(skb); | ||
512 | |||
513 | if (chain_ok) { | ||
514 | caldata->paprd_done = true; | ||
515 | ath_paprd_activate(sc); | ||
516 | } | ||
517 | |||
518 | fail_paprd: | ||
519 | ath9k_ps_restore(sc); | ||
520 | } | ||
521 | |||
522 | /* | ||
523 | * This routine performs the periodic noise floor calibration function | ||
524 | * that is used to adjust and optimize the chip performance. This | ||
525 | * takes environmental changes (location, temperature) into account. | ||
526 | * When the task is complete, it reschedules itself depending on the | ||
527 | * appropriate interval that was calculated. | ||
528 | */ | ||
529 | void ath_ani_calibrate(unsigned long data) | ||
530 | { | ||
531 | struct ath_softc *sc = (struct ath_softc *)data; | ||
532 | struct ath_hw *ah = sc->sc_ah; | ||
533 | struct ath_common *common = ath9k_hw_common(ah); | ||
534 | bool longcal = false; | ||
535 | bool shortcal = false; | ||
536 | bool aniflag = false; | ||
537 | unsigned int timestamp = jiffies_to_msecs(jiffies); | ||
538 | u32 cal_interval, short_cal_interval, long_cal_interval; | ||
539 | unsigned long flags; | ||
540 | |||
541 | if (ah->caldata && ah->caldata->nfcal_interference) | ||
542 | long_cal_interval = ATH_LONG_CALINTERVAL_INT; | ||
543 | else | ||
544 | long_cal_interval = ATH_LONG_CALINTERVAL; | ||
545 | |||
546 | short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ? | ||
547 | ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL; | ||
548 | |||
549 | /* Only calibrate if awake */ | ||
550 | if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE) | ||
551 | goto set_timer; | ||
552 | |||
553 | ath9k_ps_wakeup(sc); | ||
554 | |||
555 | /* Long calibration runs independently of short calibration. */ | ||
556 | if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) { | ||
557 | longcal = true; | ||
558 | common->ani.longcal_timer = timestamp; | ||
559 | } | ||
560 | |||
561 | /* Short calibration applies only while caldone is false */ | ||
562 | if (!common->ani.caldone) { | ||
563 | if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) { | ||
564 | shortcal = true; | ||
565 | common->ani.shortcal_timer = timestamp; | ||
566 | common->ani.resetcal_timer = timestamp; | ||
567 | } | ||
568 | } else { | ||
569 | if ((timestamp - common->ani.resetcal_timer) >= | ||
570 | ATH_RESTART_CALINTERVAL) { | ||
571 | common->ani.caldone = ath9k_hw_reset_calvalid(ah); | ||
572 | if (common->ani.caldone) | ||
573 | common->ani.resetcal_timer = timestamp; | ||
574 | } | ||
575 | } | ||
576 | |||
577 | /* Verify whether we must check ANI */ | ||
578 | if (sc->sc_ah->config.enable_ani | ||
579 | && (timestamp - common->ani.checkani_timer) >= | ||
580 | ah->config.ani_poll_interval) { | ||
581 | aniflag = true; | ||
582 | common->ani.checkani_timer = timestamp; | ||
583 | } | ||
584 | |||
585 | /* Call ANI routine if necessary */ | ||
586 | if (aniflag) { | ||
587 | spin_lock_irqsave(&common->cc_lock, flags); | ||
588 | ath9k_hw_ani_monitor(ah, ah->curchan); | ||
589 | ath_update_survey_stats(sc); | ||
590 | spin_unlock_irqrestore(&common->cc_lock, flags); | ||
591 | } | ||
592 | |||
593 | /* Perform calibration if necessary */ | ||
594 | if (longcal || shortcal) { | ||
595 | common->ani.caldone = | ||
596 | ath9k_hw_calibrate(ah, ah->curchan, | ||
597 | ah->rxchainmask, longcal); | ||
598 | } | ||
599 | |||
600 | ath_dbg(common, ANI, | ||
601 | "Calibration @%lu finished: %s %s %s, caldone: %s\n", | ||
602 | jiffies, | ||
603 | longcal ? "long" : "", shortcal ? "short" : "", | ||
604 | aniflag ? "ani" : "", common->ani.caldone ? "true" : "false"); | ||
605 | |||
606 | ath9k_ps_restore(sc); | ||
607 | |||
608 | set_timer: | ||
609 | /* | ||
610 | * Set timer interval based on previous results. | ||
611 | * The interval must be the shortest necessary to satisfy ANI, | ||
612 | * short calibration and long calibration. | ||
613 | */ | ||
614 | ath9k_debug_samp_bb_mac(sc); | ||
615 | cal_interval = ATH_LONG_CALINTERVAL; | ||
616 | if (sc->sc_ah->config.enable_ani) | ||
617 | cal_interval = min(cal_interval, | ||
618 | (u32)ah->config.ani_poll_interval); | ||
619 | if (!common->ani.caldone) | ||
620 | cal_interval = min(cal_interval, (u32)short_cal_interval); | ||
621 | |||
622 | mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); | ||
623 | if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) { | ||
624 | if (!ah->caldata->paprd_done) | ||
625 | ieee80211_queue_work(sc->hw, &sc->paprd_work); | ||
626 | else if (!ah->paprd_table_write_done) | ||
627 | ath_paprd_activate(sc); | ||
628 | } | ||
629 | } | ||
630 | |||
631 | static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, | 319 | static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, |
632 | struct ieee80211_vif *vif) | 320 | struct ieee80211_vif *vif) |
633 | { | 321 | { |
@@ -642,7 +330,7 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, | |||
642 | an->sta = sta; | 330 | an->sta = sta; |
643 | an->vif = vif; | 331 | an->vif = vif; |
644 | 332 | ||
645 | if (sta->ht_cap.ht_supported) { | 333 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { |
646 | ath_tx_node_init(sc, an); | 334 | ath_tx_node_init(sc, an); |
647 | an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + | 335 | an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + |
648 | sta->ht_cap.ampdu_factor); | 336 | sta->ht_cap.ampdu_factor); |
@@ -661,17 +349,16 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) | |||
661 | an->sta = NULL; | 349 | an->sta = NULL; |
662 | #endif | 350 | #endif |
663 | 351 | ||
664 | if (sta->ht_cap.ht_supported) | 352 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) |
665 | ath_tx_node_cleanup(sc, an); | 353 | ath_tx_node_cleanup(sc, an); |
666 | } | 354 | } |
667 | 355 | ||
668 | |||
669 | void ath9k_tasklet(unsigned long data) | 356 | void ath9k_tasklet(unsigned long data) |
670 | { | 357 | { |
671 | struct ath_softc *sc = (struct ath_softc *)data; | 358 | struct ath_softc *sc = (struct ath_softc *)data; |
672 | struct ath_hw *ah = sc->sc_ah; | 359 | struct ath_hw *ah = sc->sc_ah; |
673 | struct ath_common *common = ath9k_hw_common(ah); | 360 | struct ath_common *common = ath9k_hw_common(ah); |
674 | 361 | unsigned long flags; | |
675 | u32 status = sc->intrstatus; | 362 | u32 status = sc->intrstatus; |
676 | u32 rxmask; | 363 | u32 rxmask; |
677 | 364 | ||
@@ -690,21 +377,12 @@ void ath9k_tasklet(unsigned long data) | |||
690 | 377 | ||
691 | RESET_STAT_INC(sc, type); | 378 | RESET_STAT_INC(sc, type); |
692 | #endif | 379 | #endif |
380 | set_bit(SC_OP_HW_RESET, &sc->sc_flags); | ||
693 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | 381 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); |
694 | goto out; | 382 | goto out; |
695 | } | 383 | } |
696 | 384 | ||
697 | /* | 385 | spin_lock_irqsave(&sc->sc_pm_lock, flags); |
698 | * Only run the baseband hang check if beacons stop working in AP or | ||
699 | * IBSS mode, because it has a high false positive rate. For station | ||
700 | * mode it should not be necessary, since the upper layers will detect | ||
701 | * this through a beacon miss automatically and the following channel | ||
702 | * change will trigger a hardware reset anyway | ||
703 | */ | ||
704 | if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0 && | ||
705 | !ath9k_hw_check_alive(ah)) | ||
706 | ieee80211_queue_work(sc->hw, &sc->hw_check_work); | ||
707 | |||
708 | if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) { | 386 | if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) { |
709 | /* | 387 | /* |
710 | * TSF sync does not look correct; remain awake to sync with | 388 | * TSF sync does not look correct; remain awake to sync with |
@@ -713,6 +391,7 @@ void ath9k_tasklet(unsigned long data) | |||
713 | ath_dbg(common, PS, "TSFOOR - Sync with next Beacon\n"); | 391 | ath_dbg(common, PS, "TSFOOR - Sync with next Beacon\n"); |
714 | sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC; | 392 | sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC; |
715 | } | 393 | } |
394 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | ||
716 | 395 | ||
717 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | 396 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) |
718 | rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL | | 397 | rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL | |
@@ -774,15 +453,17 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
774 | * touch anything. Note this can happen early | 453 | * touch anything. Note this can happen early |
775 | * on if the IRQ is shared. | 454 | * on if the IRQ is shared. |
776 | */ | 455 | */ |
777 | if (sc->sc_flags & SC_OP_INVALID) | 456 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) |
778 | return IRQ_NONE; | 457 | return IRQ_NONE; |
779 | 458 | ||
780 | |||
781 | /* shared irq, not for us */ | 459 | /* shared irq, not for us */ |
782 | 460 | ||
783 | if (!ath9k_hw_intrpend(ah)) | 461 | if (!ath9k_hw_intrpend(ah)) |
784 | return IRQ_NONE; | 462 | return IRQ_NONE; |
785 | 463 | ||
464 | if(test_bit(SC_OP_HW_RESET, &sc->sc_flags)) | ||
465 | return IRQ_HANDLED; | ||
466 | |||
786 | /* | 467 | /* |
787 | * Figure out the reason(s) for the interrupt. Note | 468 | * Figure out the reason(s) for the interrupt. Note |
788 | * that the hal returns a pseudo-ISR that may include | 469 | * that the hal returns a pseudo-ISR that may include |
@@ -860,8 +541,10 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
860 | /* Clear RxAbort bit so that we can | 541 | /* Clear RxAbort bit so that we can |
861 | * receive frames */ | 542 | * receive frames */ |
862 | ath9k_setpower(sc, ATH9K_PM_AWAKE); | 543 | ath9k_setpower(sc, ATH9K_PM_AWAKE); |
544 | spin_lock(&sc->sc_pm_lock); | ||
863 | ath9k_hw_setrxabort(sc->sc_ah, 0); | 545 | ath9k_hw_setrxabort(sc->sc_ah, 0); |
864 | sc->ps_flags |= PS_WAIT_FOR_BEACON; | 546 | sc->ps_flags |= PS_WAIT_FOR_BEACON; |
547 | spin_unlock(&sc->sc_pm_lock); | ||
865 | } | 548 | } |
866 | 549 | ||
867 | chip_reset: | 550 | chip_reset: |
@@ -910,87 +593,6 @@ void ath_reset_work(struct work_struct *work) | |||
910 | ath_reset(sc, true); | 593 | ath_reset(sc, true); |
911 | } | 594 | } |
912 | 595 | ||
913 | void ath_hw_check(struct work_struct *work) | ||
914 | { | ||
915 | struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work); | ||
916 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
917 | unsigned long flags; | ||
918 | int busy; | ||
919 | u8 is_alive, nbeacon = 1; | ||
920 | |||
921 | ath9k_ps_wakeup(sc); | ||
922 | is_alive = ath9k_hw_check_alive(sc->sc_ah); | ||
923 | |||
924 | if (is_alive && !AR_SREV_9300(sc->sc_ah)) | ||
925 | goto out; | ||
926 | else if (!is_alive && AR_SREV_9300(sc->sc_ah)) { | ||
927 | ath_dbg(common, RESET, | ||
928 | "DCU stuck is detected. Schedule chip reset\n"); | ||
929 | RESET_STAT_INC(sc, RESET_TYPE_MAC_HANG); | ||
930 | goto sched_reset; | ||
931 | } | ||
932 | |||
933 | spin_lock_irqsave(&common->cc_lock, flags); | ||
934 | busy = ath_update_survey_stats(sc); | ||
935 | spin_unlock_irqrestore(&common->cc_lock, flags); | ||
936 | |||
937 | ath_dbg(common, RESET, "Possible baseband hang, busy=%d (try %d)\n", | ||
938 | busy, sc->hw_busy_count + 1); | ||
939 | if (busy >= 99) { | ||
940 | if (++sc->hw_busy_count >= 3) { | ||
941 | RESET_STAT_INC(sc, RESET_TYPE_BB_HANG); | ||
942 | goto sched_reset; | ||
943 | } | ||
944 | } else if (busy >= 0) { | ||
945 | sc->hw_busy_count = 0; | ||
946 | nbeacon = 3; | ||
947 | } | ||
948 | |||
949 | ath_start_rx_poll(sc, nbeacon); | ||
950 | goto out; | ||
951 | |||
952 | sched_reset: | ||
953 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | ||
954 | out: | ||
955 | ath9k_ps_restore(sc); | ||
956 | } | ||
957 | |||
958 | static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum) | ||
959 | { | ||
960 | static int count; | ||
961 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
962 | |||
963 | if (pll_sqsum >= 0x40000) { | ||
964 | count++; | ||
965 | if (count == 3) { | ||
966 | /* Rx is hung for more than 500ms. Reset it */ | ||
967 | ath_dbg(common, RESET, "Possible RX hang, resetting\n"); | ||
968 | RESET_STAT_INC(sc, RESET_TYPE_PLL_HANG); | ||
969 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | ||
970 | count = 0; | ||
971 | } | ||
972 | } else | ||
973 | count = 0; | ||
974 | } | ||
975 | |||
976 | void ath_hw_pll_work(struct work_struct *work) | ||
977 | { | ||
978 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
979 | hw_pll_work.work); | ||
980 | u32 pll_sqsum; | ||
981 | |||
982 | if (AR_SREV_9485(sc->sc_ah)) { | ||
983 | |||
984 | ath9k_ps_wakeup(sc); | ||
985 | pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah); | ||
986 | ath9k_ps_restore(sc); | ||
987 | |||
988 | ath_hw_pll_rx_hang_check(sc, pll_sqsum); | ||
989 | |||
990 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5); | ||
991 | } | ||
992 | } | ||
993 | |||
994 | /**********************/ | 596 | /**********************/ |
995 | /* mac80211 callbacks */ | 597 | /* mac80211 callbacks */ |
996 | /**********************/ | 598 | /**********************/ |
@@ -1053,10 +655,9 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1053 | if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) | 655 | if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) |
1054 | ah->imask |= ATH9K_INT_CST; | 656 | ah->imask |= ATH9K_INT_CST; |
1055 | 657 | ||
1056 | if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) | 658 | ath_mci_enable(sc); |
1057 | ah->imask |= ATH9K_INT_MCI; | ||
1058 | 659 | ||
1059 | sc->sc_flags &= ~SC_OP_INVALID; | 660 | clear_bit(SC_OP_INVALID, &sc->sc_flags); |
1060 | sc->sc_ah->is_monitoring = false; | 661 | sc->sc_ah->is_monitoring = false; |
1061 | 662 | ||
1062 | if (!ath_complete_reset(sc, false)) { | 663 | if (!ath_complete_reset(sc, false)) { |
@@ -1098,6 +699,7 @@ static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1098 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 699 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1099 | struct ath_tx_control txctl; | 700 | struct ath_tx_control txctl; |
1100 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 701 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
702 | unsigned long flags; | ||
1101 | 703 | ||
1102 | if (sc->ps_enabled) { | 704 | if (sc->ps_enabled) { |
1103 | /* | 705 | /* |
@@ -1113,20 +715,14 @@ static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1113 | } | 715 | } |
1114 | } | 716 | } |
1115 | 717 | ||
1116 | /* | 718 | if (unlikely(sc->sc_ah->power_mode == ATH9K_PM_NETWORK_SLEEP)) { |
1117 | * Cannot tx while the hardware is in full sleep, it first needs a full | ||
1118 | * chip reset to recover from that | ||
1119 | */ | ||
1120 | if (unlikely(sc->sc_ah->power_mode == ATH9K_PM_FULL_SLEEP)) | ||
1121 | goto exit; | ||
1122 | |||
1123 | if (unlikely(sc->sc_ah->power_mode != ATH9K_PM_AWAKE)) { | ||
1124 | /* | 719 | /* |
1125 | * We are using PS-Poll and mac80211 can request TX while in | 720 | * We are using PS-Poll and mac80211 can request TX while in |
1126 | * power save mode. Need to wake up hardware for the TX to be | 721 | * power save mode. Need to wake up hardware for the TX to be |
1127 | * completed and if needed, also for RX of buffered frames. | 722 | * completed and if needed, also for RX of buffered frames. |
1128 | */ | 723 | */ |
1129 | ath9k_ps_wakeup(sc); | 724 | ath9k_ps_wakeup(sc); |
725 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | ||
1130 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) | 726 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) |
1131 | ath9k_hw_setrxabort(sc->sc_ah, 0); | 727 | ath9k_hw_setrxabort(sc->sc_ah, 0); |
1132 | if (ieee80211_is_pspoll(hdr->frame_control)) { | 728 | if (ieee80211_is_pspoll(hdr->frame_control)) { |
@@ -1139,12 +735,22 @@ static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1139 | } | 735 | } |
1140 | /* | 736 | /* |
1141 | * The actual restore operation will happen only after | 737 | * The actual restore operation will happen only after |
1142 | * the sc_flags bit is cleared. We are just dropping | 738 | * the ps_flags bit is cleared. We are just dropping |
1143 | * the ps_usecount here. | 739 | * the ps_usecount here. |
1144 | */ | 740 | */ |
741 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | ||
1145 | ath9k_ps_restore(sc); | 742 | ath9k_ps_restore(sc); |
1146 | } | 743 | } |
1147 | 744 | ||
745 | /* | ||
746 | * Cannot tx while the hardware is in full sleep, it first needs a full | ||
747 | * chip reset to recover from that | ||
748 | */ | ||
749 | if (unlikely(sc->sc_ah->power_mode == ATH9K_PM_FULL_SLEEP)) { | ||
750 | ath_err(common, "TX while HW is in FULL_SLEEP mode\n"); | ||
751 | goto exit; | ||
752 | } | ||
753 | |||
1148 | memset(&txctl, 0, sizeof(struct ath_tx_control)); | 754 | memset(&txctl, 0, sizeof(struct ath_tx_control)); |
1149 | txctl.txq = sc->tx.txq_map[skb_get_queue_mapping(skb)]; | 755 | txctl.txq = sc->tx.txq_map[skb_get_queue_mapping(skb)]; |
1150 | 756 | ||
@@ -1173,7 +779,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
1173 | ath_cancel_work(sc); | 779 | ath_cancel_work(sc); |
1174 | del_timer_sync(&sc->rx_poll_timer); | 780 | del_timer_sync(&sc->rx_poll_timer); |
1175 | 781 | ||
1176 | if (sc->sc_flags & SC_OP_INVALID) { | 782 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) { |
1177 | ath_dbg(common, ANY, "Device not present\n"); | 783 | ath_dbg(common, ANY, "Device not present\n"); |
1178 | mutex_unlock(&sc->mutex); | 784 | mutex_unlock(&sc->mutex); |
1179 | return; | 785 | return; |
@@ -1230,7 +836,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
1230 | 836 | ||
1231 | ath9k_ps_restore(sc); | 837 | ath9k_ps_restore(sc); |
1232 | 838 | ||
1233 | sc->sc_flags |= SC_OP_INVALID; | 839 | set_bit(SC_OP_INVALID, &sc->sc_flags); |
1234 | sc->ps_idle = prev_idle; | 840 | sc->ps_idle = prev_idle; |
1235 | 841 | ||
1236 | mutex_unlock(&sc->mutex); | 842 | mutex_unlock(&sc->mutex); |
@@ -1258,7 +864,6 @@ static void ath9k_reclaim_beacon(struct ath_softc *sc, | |||
1258 | ath9k_set_beaconing_status(sc, false); | 864 | ath9k_set_beaconing_status(sc, false); |
1259 | ath_beacon_return(sc, avp); | 865 | ath_beacon_return(sc, avp); |
1260 | ath9k_set_beaconing_status(sc, true); | 866 | ath9k_set_beaconing_status(sc, true); |
1261 | sc->sc_flags &= ~SC_OP_BEACONS; | ||
1262 | } | 867 | } |
1263 | 868 | ||
1264 | static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | 869 | static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) |
@@ -1335,11 +940,11 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, | |||
1335 | /* Set op-mode & TSF */ | 940 | /* Set op-mode & TSF */ |
1336 | if (iter_data.naps > 0) { | 941 | if (iter_data.naps > 0) { |
1337 | ath9k_hw_set_tsfadjust(ah, 1); | 942 | ath9k_hw_set_tsfadjust(ah, 1); |
1338 | sc->sc_flags |= SC_OP_TSF_RESET; | 943 | set_bit(SC_OP_TSF_RESET, &sc->sc_flags); |
1339 | ah->opmode = NL80211_IFTYPE_AP; | 944 | ah->opmode = NL80211_IFTYPE_AP; |
1340 | } else { | 945 | } else { |
1341 | ath9k_hw_set_tsfadjust(ah, 0); | 946 | ath9k_hw_set_tsfadjust(ah, 0); |
1342 | sc->sc_flags &= ~SC_OP_TSF_RESET; | 947 | clear_bit(SC_OP_TSF_RESET, &sc->sc_flags); |
1343 | 948 | ||
1344 | if (iter_data.nmeshes) | 949 | if (iter_data.nmeshes) |
1345 | ah->opmode = NL80211_IFTYPE_MESH_POINT; | 950 | ah->opmode = NL80211_IFTYPE_MESH_POINT; |
@@ -1370,12 +975,12 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, | |||
1370 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; | 975 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; |
1371 | 976 | ||
1372 | if (!common->disable_ani) { | 977 | if (!common->disable_ani) { |
1373 | sc->sc_flags |= SC_OP_ANI_RUN; | 978 | set_bit(SC_OP_ANI_RUN, &sc->sc_flags); |
1374 | ath_start_ani(common); | 979 | ath_start_ani(common); |
1375 | } | 980 | } |
1376 | 981 | ||
1377 | } else { | 982 | } else { |
1378 | sc->sc_flags &= ~SC_OP_ANI_RUN; | 983 | clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); |
1379 | del_timer_sync(&common->ani.timer); | 984 | del_timer_sync(&common->ani.timer); |
1380 | } | 985 | } |
1381 | } | 986 | } |
@@ -1389,40 +994,13 @@ static void ath9k_do_vif_add_setup(struct ieee80211_hw *hw, | |||
1389 | ath9k_calculate_summary_state(hw, vif); | 994 | ath9k_calculate_summary_state(hw, vif); |
1390 | 995 | ||
1391 | if (ath9k_uses_beacons(vif->type)) { | 996 | if (ath9k_uses_beacons(vif->type)) { |
1392 | int error; | 997 | /* Reserve a beacon slot for the vif */ |
1393 | /* This may fail because upper levels do not have beacons | ||
1394 | * properly configured yet. That's OK, we assume it | ||
1395 | * will be properly configured and then we will be notified | ||
1396 | * in the info_changed method and set up beacons properly | ||
1397 | * there. | ||
1398 | */ | ||
1399 | ath9k_set_beaconing_status(sc, false); | 998 | ath9k_set_beaconing_status(sc, false); |
1400 | error = ath_beacon_alloc(sc, vif); | 999 | ath_beacon_alloc(sc, vif); |
1401 | if (!error) | ||
1402 | ath_beacon_config(sc, vif); | ||
1403 | ath9k_set_beaconing_status(sc, true); | 1000 | ath9k_set_beaconing_status(sc, true); |
1404 | } | 1001 | } |
1405 | } | 1002 | } |
1406 | 1003 | ||
1407 | void ath_start_rx_poll(struct ath_softc *sc, u8 nbeacon) | ||
1408 | { | ||
1409 | if (!AR_SREV_9300(sc->sc_ah)) | ||
1410 | return; | ||
1411 | |||
1412 | if (!(sc->sc_flags & SC_OP_PRIM_STA_VIF)) | ||
1413 | return; | ||
1414 | |||
1415 | mod_timer(&sc->rx_poll_timer, jiffies + msecs_to_jiffies | ||
1416 | (nbeacon * sc->cur_beacon_conf.beacon_interval)); | ||
1417 | } | ||
1418 | |||
1419 | void ath_rx_poll(unsigned long data) | ||
1420 | { | ||
1421 | struct ath_softc *sc = (struct ath_softc *)data; | ||
1422 | |||
1423 | ieee80211_queue_work(sc->hw, &sc->hw_check_work); | ||
1424 | } | ||
1425 | |||
1426 | static int ath9k_add_interface(struct ieee80211_hw *hw, | 1004 | static int ath9k_add_interface(struct ieee80211_hw *hw, |
1427 | struct ieee80211_vif *vif) | 1005 | struct ieee80211_vif *vif) |
1428 | { | 1006 | { |
@@ -1458,15 +1036,6 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
1458 | } | 1036 | } |
1459 | } | 1037 | } |
1460 | 1038 | ||
1461 | if ((ah->opmode == NL80211_IFTYPE_ADHOC) || | ||
1462 | ((vif->type == NL80211_IFTYPE_ADHOC) && | ||
1463 | sc->nvifs > 0)) { | ||
1464 | ath_err(common, "Cannot create ADHOC interface when other" | ||
1465 | " interfaces already exist.\n"); | ||
1466 | ret = -EINVAL; | ||
1467 | goto out; | ||
1468 | } | ||
1469 | |||
1470 | ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type); | 1039 | ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type); |
1471 | 1040 | ||
1472 | sc->nvifs++; | 1041 | sc->nvifs++; |
@@ -1491,15 +1060,6 @@ static int ath9k_change_interface(struct ieee80211_hw *hw, | |||
1491 | mutex_lock(&sc->mutex); | 1060 | mutex_lock(&sc->mutex); |
1492 | ath9k_ps_wakeup(sc); | 1061 | ath9k_ps_wakeup(sc); |
1493 | 1062 | ||
1494 | /* See if new interface type is valid. */ | ||
1495 | if ((new_type == NL80211_IFTYPE_ADHOC) && | ||
1496 | (sc->nvifs > 1)) { | ||
1497 | ath_err(common, "When using ADHOC, it must be the only" | ||
1498 | " interface.\n"); | ||
1499 | ret = -EINVAL; | ||
1500 | goto out; | ||
1501 | } | ||
1502 | |||
1503 | if (ath9k_uses_beacons(new_type) && | 1063 | if (ath9k_uses_beacons(new_type) && |
1504 | !ath9k_uses_beacons(vif->type)) { | 1064 | !ath9k_uses_beacons(vif->type)) { |
1505 | if (sc->nbcnvifs >= ATH_BCBUF) { | 1065 | if (sc->nbcnvifs >= ATH_BCBUF) { |
@@ -1550,6 +1110,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
1550 | static void ath9k_enable_ps(struct ath_softc *sc) | 1110 | static void ath9k_enable_ps(struct ath_softc *sc) |
1551 | { | 1111 | { |
1552 | struct ath_hw *ah = sc->sc_ah; | 1112 | struct ath_hw *ah = sc->sc_ah; |
1113 | struct ath_common *common = ath9k_hw_common(ah); | ||
1553 | 1114 | ||
1554 | sc->ps_enabled = true; | 1115 | sc->ps_enabled = true; |
1555 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { | 1116 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { |
@@ -1559,11 +1120,13 @@ static void ath9k_enable_ps(struct ath_softc *sc) | |||
1559 | } | 1120 | } |
1560 | ath9k_hw_setrxabort(ah, 1); | 1121 | ath9k_hw_setrxabort(ah, 1); |
1561 | } | 1122 | } |
1123 | ath_dbg(common, PS, "PowerSave enabled\n"); | ||
1562 | } | 1124 | } |
1563 | 1125 | ||
1564 | static void ath9k_disable_ps(struct ath_softc *sc) | 1126 | static void ath9k_disable_ps(struct ath_softc *sc) |
1565 | { | 1127 | { |
1566 | struct ath_hw *ah = sc->sc_ah; | 1128 | struct ath_hw *ah = sc->sc_ah; |
1129 | struct ath_common *common = ath9k_hw_common(ah); | ||
1567 | 1130 | ||
1568 | sc->ps_enabled = false; | 1131 | sc->ps_enabled = false; |
1569 | ath9k_hw_setpower(ah, ATH9K_PM_AWAKE); | 1132 | ath9k_hw_setpower(ah, ATH9K_PM_AWAKE); |
@@ -1578,7 +1141,7 @@ static void ath9k_disable_ps(struct ath_softc *sc) | |||
1578 | ath9k_hw_set_interrupts(ah); | 1141 | ath9k_hw_set_interrupts(ah); |
1579 | } | 1142 | } |
1580 | } | 1143 | } |
1581 | 1144 | ath_dbg(common, PS, "PowerSave disabled\n"); | |
1582 | } | 1145 | } |
1583 | 1146 | ||
1584 | static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | 1147 | static int ath9k_config(struct ieee80211_hw *hw, u32 changed) |
@@ -1587,6 +1150,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1587 | struct ath_hw *ah = sc->sc_ah; | 1150 | struct ath_hw *ah = sc->sc_ah; |
1588 | struct ath_common *common = ath9k_hw_common(ah); | 1151 | struct ath_common *common = ath9k_hw_common(ah); |
1589 | struct ieee80211_conf *conf = &hw->conf; | 1152 | struct ieee80211_conf *conf = &hw->conf; |
1153 | bool reset_channel = false; | ||
1590 | 1154 | ||
1591 | ath9k_ps_wakeup(sc); | 1155 | ath9k_ps_wakeup(sc); |
1592 | mutex_lock(&sc->mutex); | 1156 | mutex_lock(&sc->mutex); |
@@ -1595,6 +1159,12 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1595 | sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE); | 1159 | sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE); |
1596 | if (sc->ps_idle) | 1160 | if (sc->ps_idle) |
1597 | ath_cancel_work(sc); | 1161 | ath_cancel_work(sc); |
1162 | else | ||
1163 | /* | ||
1164 | * The chip needs a reset to properly wake up from | ||
1165 | * full sleep | ||
1166 | */ | ||
1167 | reset_channel = ah->chip_fullsleep; | ||
1598 | } | 1168 | } |
1599 | 1169 | ||
1600 | /* | 1170 | /* |
@@ -1623,7 +1193,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1623 | } | 1193 | } |
1624 | } | 1194 | } |
1625 | 1195 | ||
1626 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | 1196 | if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) { |
1627 | struct ieee80211_channel *curchan = hw->conf.channel; | 1197 | struct ieee80211_channel *curchan = hw->conf.channel; |
1628 | int pos = curchan->hw_value; | 1198 | int pos = curchan->hw_value; |
1629 | int old_pos = -1; | 1199 | int old_pos = -1; |
@@ -1632,11 +1202,6 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1632 | if (ah->curchan) | 1202 | if (ah->curchan) |
1633 | old_pos = ah->curchan - &ah->channels[0]; | 1203 | old_pos = ah->curchan - &ah->channels[0]; |
1634 | 1204 | ||
1635 | if (hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) | ||
1636 | sc->sc_flags |= SC_OP_OFFCHANNEL; | ||
1637 | else | ||
1638 | sc->sc_flags &= ~SC_OP_OFFCHANNEL; | ||
1639 | |||
1640 | ath_dbg(common, CONFIG, "Set channel: %d MHz type: %d\n", | 1205 | ath_dbg(common, CONFIG, "Set channel: %d MHz type: %d\n", |
1641 | curchan->center_freq, conf->channel_type); | 1206 | curchan->center_freq, conf->channel_type); |
1642 | 1207 | ||
@@ -1678,6 +1243,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1678 | if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) { | 1243 | if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) { |
1679 | ath_err(common, "Unable to set channel\n"); | 1244 | ath_err(common, "Unable to set channel\n"); |
1680 | mutex_unlock(&sc->mutex); | 1245 | mutex_unlock(&sc->mutex); |
1246 | ath9k_ps_restore(sc); | ||
1681 | return -EINVAL; | 1247 | return -EINVAL; |
1682 | } | 1248 | } |
1683 | 1249 | ||
@@ -1916,16 +1482,16 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | |||
1916 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1482 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1917 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | 1483 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; |
1918 | struct ath_vif *avp = (void *)vif->drv_priv; | 1484 | struct ath_vif *avp = (void *)vif->drv_priv; |
1919 | 1485 | unsigned long flags; | |
1920 | /* | 1486 | /* |
1921 | * Skip iteration if primary station vif's bss info | 1487 | * Skip iteration if primary station vif's bss info |
1922 | * was not changed | 1488 | * was not changed |
1923 | */ | 1489 | */ |
1924 | if (sc->sc_flags & SC_OP_PRIM_STA_VIF) | 1490 | if (test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) |
1925 | return; | 1491 | return; |
1926 | 1492 | ||
1927 | if (bss_conf->assoc) { | 1493 | if (bss_conf->assoc) { |
1928 | sc->sc_flags |= SC_OP_PRIM_STA_VIF; | 1494 | set_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags); |
1929 | avp->primary_sta_vif = true; | 1495 | avp->primary_sta_vif = true; |
1930 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); | 1496 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); |
1931 | common->curaid = bss_conf->aid; | 1497 | common->curaid = bss_conf->aid; |
@@ -1938,7 +1504,10 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | |||
1938 | * on the receipt of the first Beacon frame (i.e., | 1504 | * on the receipt of the first Beacon frame (i.e., |
1939 | * after time sync with the AP). | 1505 | * after time sync with the AP). |
1940 | */ | 1506 | */ |
1507 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | ||
1941 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; | 1508 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; |
1509 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | ||
1510 | |||
1942 | /* Reset rssi stats */ | 1511 | /* Reset rssi stats */ |
1943 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; | 1512 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; |
1944 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; | 1513 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; |
@@ -1946,7 +1515,7 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | |||
1946 | ath_start_rx_poll(sc, 3); | 1515 | ath_start_rx_poll(sc, 3); |
1947 | 1516 | ||
1948 | if (!common->disable_ani) { | 1517 | if (!common->disable_ani) { |
1949 | sc->sc_flags |= SC_OP_ANI_RUN; | 1518 | set_bit(SC_OP_ANI_RUN, &sc->sc_flags); |
1950 | ath_start_ani(common); | 1519 | ath_start_ani(common); |
1951 | } | 1520 | } |
1952 | 1521 | ||
@@ -1966,7 +1535,8 @@ static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
1966 | if (avp->primary_sta_vif && !bss_conf->assoc) { | 1535 | if (avp->primary_sta_vif && !bss_conf->assoc) { |
1967 | ath_dbg(common, CONFIG, "Bss Info DISASSOC %d, bssid %pM\n", | 1536 | ath_dbg(common, CONFIG, "Bss Info DISASSOC %d, bssid %pM\n", |
1968 | common->curaid, common->curbssid); | 1537 | common->curaid, common->curbssid); |
1969 | sc->sc_flags &= ~(SC_OP_PRIM_STA_VIF | SC_OP_BEACONS); | 1538 | clear_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags); |
1539 | clear_bit(SC_OP_BEACONS, &sc->sc_flags); | ||
1970 | avp->primary_sta_vif = false; | 1540 | avp->primary_sta_vif = false; |
1971 | memset(common->curbssid, 0, ETH_ALEN); | 1541 | memset(common->curbssid, 0, ETH_ALEN); |
1972 | common->curaid = 0; | 1542 | common->curaid = 0; |
@@ -1979,10 +1549,9 @@ static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
1979 | * None of station vifs are associated. | 1549 | * None of station vifs are associated. |
1980 | * Clear bssid & aid | 1550 | * Clear bssid & aid |
1981 | */ | 1551 | */ |
1982 | if (!(sc->sc_flags & SC_OP_PRIM_STA_VIF)) { | 1552 | if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { |
1983 | ath9k_hw_write_associd(sc->sc_ah); | 1553 | ath9k_hw_write_associd(sc->sc_ah); |
1984 | /* Stop ANI */ | 1554 | clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); |
1985 | sc->sc_flags &= ~SC_OP_ANI_RUN; | ||
1986 | del_timer_sync(&common->ani.timer); | 1555 | del_timer_sync(&common->ani.timer); |
1987 | del_timer_sync(&sc->rx_poll_timer); | 1556 | del_timer_sync(&sc->rx_poll_timer); |
1988 | memset(&sc->caldata, 0, sizeof(sc->caldata)); | 1557 | memset(&sc->caldata, 0, sizeof(sc->caldata)); |
@@ -1999,7 +1568,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1999 | struct ath_common *common = ath9k_hw_common(ah); | 1568 | struct ath_common *common = ath9k_hw_common(ah); |
2000 | struct ath_vif *avp = (void *)vif->drv_priv; | 1569 | struct ath_vif *avp = (void *)vif->drv_priv; |
2001 | int slottime; | 1570 | int slottime; |
2002 | int error; | ||
2003 | 1571 | ||
2004 | ath9k_ps_wakeup(sc); | 1572 | ath9k_ps_wakeup(sc); |
2005 | mutex_lock(&sc->mutex); | 1573 | mutex_lock(&sc->mutex); |
@@ -2021,24 +1589,36 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2021 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; | 1589 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; |
2022 | 1590 | ||
2023 | if (!common->disable_ani) { | 1591 | if (!common->disable_ani) { |
2024 | sc->sc_flags |= SC_OP_ANI_RUN; | 1592 | set_bit(SC_OP_ANI_RUN, &sc->sc_flags); |
2025 | ath_start_ani(common); | 1593 | ath_start_ani(common); |
2026 | } | 1594 | } |
2027 | 1595 | ||
2028 | } else { | 1596 | } else { |
2029 | sc->sc_flags &= ~SC_OP_ANI_RUN; | 1597 | clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); |
2030 | del_timer_sync(&common->ani.timer); | 1598 | del_timer_sync(&common->ani.timer); |
2031 | del_timer_sync(&sc->rx_poll_timer); | 1599 | del_timer_sync(&sc->rx_poll_timer); |
2032 | } | 1600 | } |
2033 | } | 1601 | } |
2034 | 1602 | ||
2035 | /* Enable transmission of beacons (AP, IBSS, MESH) */ | 1603 | /* |
2036 | if ((changed & BSS_CHANGED_BEACON) || | 1604 | * In case of AP mode, the HW TSF has to be reset |
2037 | ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon)) { | 1605 | * when the beacon interval changes. |
1606 | */ | ||
1607 | if ((changed & BSS_CHANGED_BEACON_INT) && | ||
1608 | (vif->type == NL80211_IFTYPE_AP)) | ||
1609 | set_bit(SC_OP_TSF_RESET, &sc->sc_flags); | ||
1610 | |||
1611 | /* Configure beaconing (AP, IBSS, MESH) */ | ||
1612 | if (ath9k_uses_beacons(vif->type) && | ||
1613 | ((changed & BSS_CHANGED_BEACON) || | ||
1614 | (changed & BSS_CHANGED_BEACON_ENABLED) || | ||
1615 | (changed & BSS_CHANGED_BEACON_INT))) { | ||
2038 | ath9k_set_beaconing_status(sc, false); | 1616 | ath9k_set_beaconing_status(sc, false); |
2039 | error = ath_beacon_alloc(sc, vif); | 1617 | if (bss_conf->enable_beacon) |
2040 | if (!error) | 1618 | ath_beacon_alloc(sc, vif); |
2041 | ath_beacon_config(sc, vif); | 1619 | else |
1620 | avp->is_bslot_active = false; | ||
1621 | ath_beacon_config(sc, vif); | ||
2042 | ath9k_set_beaconing_status(sc, true); | 1622 | ath9k_set_beaconing_status(sc, true); |
2043 | } | 1623 | } |
2044 | 1624 | ||
@@ -2061,30 +1641,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2061 | } | 1641 | } |
2062 | } | 1642 | } |
2063 | 1643 | ||
2064 | /* Disable transmission of beacons */ | ||
2065 | if ((changed & BSS_CHANGED_BEACON_ENABLED) && | ||
2066 | !bss_conf->enable_beacon) { | ||
2067 | ath9k_set_beaconing_status(sc, false); | ||
2068 | avp->is_bslot_active = false; | ||
2069 | ath9k_set_beaconing_status(sc, true); | ||
2070 | } | ||
2071 | |||
2072 | if (changed & BSS_CHANGED_BEACON_INT) { | ||
2073 | /* | ||
2074 | * In case of AP mode, the HW TSF has to be reset | ||
2075 | * when the beacon interval changes. | ||
2076 | */ | ||
2077 | if (vif->type == NL80211_IFTYPE_AP) { | ||
2078 | sc->sc_flags |= SC_OP_TSF_RESET; | ||
2079 | ath9k_set_beaconing_status(sc, false); | ||
2080 | error = ath_beacon_alloc(sc, vif); | ||
2081 | if (!error) | ||
2082 | ath_beacon_config(sc, vif); | ||
2083 | ath9k_set_beaconing_status(sc, true); | ||
2084 | } else | ||
2085 | ath_beacon_config(sc, vif); | ||
2086 | } | ||
2087 | |||
2088 | mutex_unlock(&sc->mutex); | 1644 | mutex_unlock(&sc->mutex); |
2089 | ath9k_ps_restore(sc); | 1645 | ath9k_ps_restore(sc); |
2090 | } | 1646 | } |
@@ -2242,7 +1798,7 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop) | |||
2242 | return; | 1798 | return; |
2243 | } | 1799 | } |
2244 | 1800 | ||
2245 | if (sc->sc_flags & SC_OP_INVALID) { | 1801 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) { |
2246 | ath_dbg(common, ANY, "Device not present\n"); | 1802 | ath_dbg(common, ANY, "Device not present\n"); |
2247 | mutex_unlock(&sc->mutex); | 1803 | mutex_unlock(&sc->mutex); |
2248 | return; | 1804 | return; |
@@ -2407,6 +1963,134 @@ static int ath9k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) | |||
2407 | return 0; | 1963 | return 0; |
2408 | } | 1964 | } |
2409 | 1965 | ||
1966 | #ifdef CONFIG_ATH9K_DEBUGFS | ||
1967 | |||
1968 | /* Ethtool support for get-stats */ | ||
1969 | |||
1970 | #define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO" | ||
1971 | static const char ath9k_gstrings_stats[][ETH_GSTRING_LEN] = { | ||
1972 | "tx_pkts_nic", | ||
1973 | "tx_bytes_nic", | ||
1974 | "rx_pkts_nic", | ||
1975 | "rx_bytes_nic", | ||
1976 | AMKSTR(d_tx_pkts), | ||
1977 | AMKSTR(d_tx_bytes), | ||
1978 | AMKSTR(d_tx_mpdus_queued), | ||
1979 | AMKSTR(d_tx_mpdus_completed), | ||
1980 | AMKSTR(d_tx_mpdu_xretries), | ||
1981 | AMKSTR(d_tx_aggregates), | ||
1982 | AMKSTR(d_tx_ampdus_queued_hw), | ||
1983 | AMKSTR(d_tx_ampdus_queued_sw), | ||
1984 | AMKSTR(d_tx_ampdus_completed), | ||
1985 | AMKSTR(d_tx_ampdu_retries), | ||
1986 | AMKSTR(d_tx_ampdu_xretries), | ||
1987 | AMKSTR(d_tx_fifo_underrun), | ||
1988 | AMKSTR(d_tx_op_exceeded), | ||
1989 | AMKSTR(d_tx_timer_expiry), | ||
1990 | AMKSTR(d_tx_desc_cfg_err), | ||
1991 | AMKSTR(d_tx_data_underrun), | ||
1992 | AMKSTR(d_tx_delim_underrun), | ||
1993 | |||
1994 | "d_rx_decrypt_crc_err", | ||
1995 | "d_rx_phy_err", | ||
1996 | "d_rx_mic_err", | ||
1997 | "d_rx_pre_delim_crc_err", | ||
1998 | "d_rx_post_delim_crc_err", | ||
1999 | "d_rx_decrypt_busy_err", | ||
2000 | |||
2001 | "d_rx_phyerr_radar", | ||
2002 | "d_rx_phyerr_ofdm_timing", | ||
2003 | "d_rx_phyerr_cck_timing", | ||
2004 | |||
2005 | }; | ||
2006 | #define ATH9K_SSTATS_LEN ARRAY_SIZE(ath9k_gstrings_stats) | ||
2007 | |||
2008 | static void ath9k_get_et_strings(struct ieee80211_hw *hw, | ||
2009 | struct ieee80211_vif *vif, | ||
2010 | u32 sset, u8 *data) | ||
2011 | { | ||
2012 | if (sset == ETH_SS_STATS) | ||
2013 | memcpy(data, *ath9k_gstrings_stats, | ||
2014 | sizeof(ath9k_gstrings_stats)); | ||
2015 | } | ||
2016 | |||
2017 | static int ath9k_get_et_sset_count(struct ieee80211_hw *hw, | ||
2018 | struct ieee80211_vif *vif, int sset) | ||
2019 | { | ||
2020 | if (sset == ETH_SS_STATS) | ||
2021 | return ATH9K_SSTATS_LEN; | ||
2022 | return 0; | ||
2023 | } | ||
2024 | |||
2025 | #define PR_QNUM(_n) (sc->tx.txq_map[_n]->axq_qnum) | ||
2026 | #define AWDATA(elem) \ | ||
2027 | do { \ | ||
2028 | data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].elem; \ | ||
2029 | data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].elem; \ | ||
2030 | data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].elem; \ | ||
2031 | data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].elem; \ | ||
2032 | } while (0) | ||
2033 | |||
2034 | #define AWDATA_RX(elem) \ | ||
2035 | do { \ | ||
2036 | data[i++] = sc->debug.stats.rxstats.elem; \ | ||
2037 | } while (0) | ||
2038 | |||
2039 | static void ath9k_get_et_stats(struct ieee80211_hw *hw, | ||
2040 | struct ieee80211_vif *vif, | ||
2041 | struct ethtool_stats *stats, u64 *data) | ||
2042 | { | ||
2043 | struct ath_softc *sc = hw->priv; | ||
2044 | int i = 0; | ||
2045 | |||
2046 | data[i++] = (sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].tx_pkts_all + | ||
2047 | sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].tx_pkts_all + | ||
2048 | sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].tx_pkts_all + | ||
2049 | sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].tx_pkts_all); | ||
2050 | data[i++] = (sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].tx_bytes_all + | ||
2051 | sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].tx_bytes_all + | ||
2052 | sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].tx_bytes_all + | ||
2053 | sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].tx_bytes_all); | ||
2054 | AWDATA_RX(rx_pkts_all); | ||
2055 | AWDATA_RX(rx_bytes_all); | ||
2056 | |||
2057 | AWDATA(tx_pkts_all); | ||
2058 | AWDATA(tx_bytes_all); | ||
2059 | AWDATA(queued); | ||
2060 | AWDATA(completed); | ||
2061 | AWDATA(xretries); | ||
2062 | AWDATA(a_aggr); | ||
2063 | AWDATA(a_queued_hw); | ||
2064 | AWDATA(a_queued_sw); | ||
2065 | AWDATA(a_completed); | ||
2066 | AWDATA(a_retries); | ||
2067 | AWDATA(a_xretries); | ||
2068 | AWDATA(fifo_underrun); | ||
2069 | AWDATA(xtxop); | ||
2070 | AWDATA(timer_exp); | ||
2071 | AWDATA(desc_cfg_err); | ||
2072 | AWDATA(data_underrun); | ||
2073 | AWDATA(delim_underrun); | ||
2074 | |||
2075 | AWDATA_RX(decrypt_crc_err); | ||
2076 | AWDATA_RX(phy_err); | ||
2077 | AWDATA_RX(mic_err); | ||
2078 | AWDATA_RX(pre_delim_crc_err); | ||
2079 | AWDATA_RX(post_delim_crc_err); | ||
2080 | AWDATA_RX(decrypt_busy_err); | ||
2081 | |||
2082 | AWDATA_RX(phy_err_stats[ATH9K_PHYERR_RADAR]); | ||
2083 | AWDATA_RX(phy_err_stats[ATH9K_PHYERR_OFDM_TIMING]); | ||
2084 | AWDATA_RX(phy_err_stats[ATH9K_PHYERR_CCK_TIMING]); | ||
2085 | |||
2086 | WARN_ON(i != ATH9K_SSTATS_LEN); | ||
2087 | } | ||
2088 | |||
2089 | /* End of ethtool get-stats functions */ | ||
2090 | |||
2091 | #endif | ||
2092 | |||
2093 | |||
2410 | struct ieee80211_ops ath9k_ops = { | 2094 | struct ieee80211_ops ath9k_ops = { |
2411 | .tx = ath9k_tx, | 2095 | .tx = ath9k_tx, |
2412 | .start = ath9k_start, | 2096 | .start = ath9k_start, |
@@ -2435,4 +2119,10 @@ struct ieee80211_ops ath9k_ops = { | |||
2435 | .get_stats = ath9k_get_stats, | 2119 | .get_stats = ath9k_get_stats, |
2436 | .set_antenna = ath9k_set_antenna, | 2120 | .set_antenna = ath9k_set_antenna, |
2437 | .get_antenna = ath9k_get_antenna, | 2121 | .get_antenna = ath9k_get_antenna, |
2122 | |||
2123 | #ifdef CONFIG_ATH9K_DEBUGFS | ||
2124 | .get_et_sset_count = ath9k_get_et_sset_count, | ||
2125 | .get_et_stats = ath9k_get_et_stats, | ||
2126 | .get_et_strings = ath9k_get_et_strings, | ||
2127 | #endif | ||
2438 | }; | 2128 | }; |
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index 29fe52d69973..7d34a504d617 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include "ath9k.h" | 20 | #include "ath9k.h" |
21 | #include "mci.h" | 21 | #include "mci.h" |
22 | 22 | ||
23 | static const u8 ath_mci_duty_cycle[] = { 0, 50, 60, 70, 80, 85, 90, 95, 98 }; | 23 | static const u8 ath_mci_duty_cycle[] = { 55, 50, 60, 70, 80, 85, 90, 95, 98 }; |
24 | 24 | ||
25 | static struct ath_mci_profile_info* | 25 | static struct ath_mci_profile_info* |
26 | ath_mci_find_profile(struct ath_mci_profile *mci, | 26 | ath_mci_find_profile(struct ath_mci_profile *mci, |
@@ -28,11 +28,14 @@ ath_mci_find_profile(struct ath_mci_profile *mci, | |||
28 | { | 28 | { |
29 | struct ath_mci_profile_info *entry; | 29 | struct ath_mci_profile_info *entry; |
30 | 30 | ||
31 | if (list_empty(&mci->info)) | ||
32 | return NULL; | ||
33 | |||
31 | list_for_each_entry(entry, &mci->info, list) { | 34 | list_for_each_entry(entry, &mci->info, list) { |
32 | if (entry->conn_handle == info->conn_handle) | 35 | if (entry->conn_handle == info->conn_handle) |
33 | break; | 36 | return entry; |
34 | } | 37 | } |
35 | return entry; | 38 | return NULL; |
36 | } | 39 | } |
37 | 40 | ||
38 | static bool ath_mci_add_profile(struct ath_common *common, | 41 | static bool ath_mci_add_profile(struct ath_common *common, |
@@ -49,31 +52,21 @@ static bool ath_mci_add_profile(struct ath_common *common, | |||
49 | (info->type != MCI_GPM_COEX_PROFILE_VOICE)) | 52 | (info->type != MCI_GPM_COEX_PROFILE_VOICE)) |
50 | return false; | 53 | return false; |
51 | 54 | ||
52 | entry = ath_mci_find_profile(mci, info); | 55 | entry = kzalloc(sizeof(*entry), GFP_ATOMIC); |
56 | if (!entry) | ||
57 | return false; | ||
53 | 58 | ||
54 | if (entry) { | 59 | memcpy(entry, info, 10); |
55 | memcpy(entry, info, 10); | 60 | INC_PROF(mci, info); |
56 | } else { | 61 | list_add_tail(&entry->list, &mci->info); |
57 | entry = kzalloc(sizeof(*entry), GFP_KERNEL); | ||
58 | if (!entry) | ||
59 | return false; | ||
60 | |||
61 | memcpy(entry, info, 10); | ||
62 | INC_PROF(mci, info); | ||
63 | list_add_tail(&info->list, &mci->info); | ||
64 | } | ||
65 | 62 | ||
66 | return true; | 63 | return true; |
67 | } | 64 | } |
68 | 65 | ||
69 | static void ath_mci_del_profile(struct ath_common *common, | 66 | static void ath_mci_del_profile(struct ath_common *common, |
70 | struct ath_mci_profile *mci, | 67 | struct ath_mci_profile *mci, |
71 | struct ath_mci_profile_info *info) | 68 | struct ath_mci_profile_info *entry) |
72 | { | 69 | { |
73 | struct ath_mci_profile_info *entry; | ||
74 | |||
75 | entry = ath_mci_find_profile(mci, info); | ||
76 | |||
77 | if (!entry) | 70 | if (!entry) |
78 | return; | 71 | return; |
79 | 72 | ||
@@ -86,12 +79,16 @@ void ath_mci_flush_profile(struct ath_mci_profile *mci) | |||
86 | { | 79 | { |
87 | struct ath_mci_profile_info *info, *tinfo; | 80 | struct ath_mci_profile_info *info, *tinfo; |
88 | 81 | ||
82 | mci->aggr_limit = 0; | ||
83 | |||
84 | if (list_empty(&mci->info)) | ||
85 | return; | ||
86 | |||
89 | list_for_each_entry_safe(info, tinfo, &mci->info, list) { | 87 | list_for_each_entry_safe(info, tinfo, &mci->info, list) { |
90 | list_del(&info->list); | 88 | list_del(&info->list); |
91 | DEC_PROF(mci, info); | 89 | DEC_PROF(mci, info); |
92 | kfree(info); | 90 | kfree(info); |
93 | } | 91 | } |
94 | mci->aggr_limit = 0; | ||
95 | } | 92 | } |
96 | 93 | ||
97 | static void ath_mci_adjust_aggr_limit(struct ath_btcoex *btcoex) | 94 | static void ath_mci_adjust_aggr_limit(struct ath_btcoex *btcoex) |
@@ -116,42 +113,60 @@ static void ath_mci_update_scheme(struct ath_softc *sc) | |||
116 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 113 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
117 | struct ath_btcoex *btcoex = &sc->btcoex; | 114 | struct ath_btcoex *btcoex = &sc->btcoex; |
118 | struct ath_mci_profile *mci = &btcoex->mci; | 115 | struct ath_mci_profile *mci = &btcoex->mci; |
116 | struct ath9k_hw_mci *mci_hw = &sc->sc_ah->btcoex_hw.mci; | ||
119 | struct ath_mci_profile_info *info; | 117 | struct ath_mci_profile_info *info; |
120 | u32 num_profile = NUM_PROF(mci); | 118 | u32 num_profile = NUM_PROF(mci); |
121 | 119 | ||
120 | if (mci_hw->config & ATH_MCI_CONFIG_DISABLE_TUNING) | ||
121 | goto skip_tuning; | ||
122 | |||
123 | btcoex->duty_cycle = ath_mci_duty_cycle[num_profile]; | ||
124 | |||
122 | if (num_profile == 1) { | 125 | if (num_profile == 1) { |
123 | info = list_first_entry(&mci->info, | 126 | info = list_first_entry(&mci->info, |
124 | struct ath_mci_profile_info, | 127 | struct ath_mci_profile_info, |
125 | list); | 128 | list); |
126 | if (mci->num_sco && info->T == 12) { | 129 | if (mci->num_sco) { |
127 | mci->aggr_limit = 8; | 130 | if (info->T == 12) |
131 | mci->aggr_limit = 8; | ||
132 | else if (info->T == 6) { | ||
133 | mci->aggr_limit = 6; | ||
134 | btcoex->duty_cycle = 30; | ||
135 | } | ||
128 | ath_dbg(common, MCI, | 136 | ath_dbg(common, MCI, |
129 | "Single SCO, aggregation limit 2 ms\n"); | 137 | "Single SCO, aggregation limit %d 1/4 ms\n", |
130 | } else if ((info->type == MCI_GPM_COEX_PROFILE_BNEP) && | 138 | mci->aggr_limit); |
131 | !info->master) { | 139 | } else if (mci->num_pan || mci->num_other_acl) { |
132 | btcoex->btcoex_period = 60; | 140 | /* |
141 | * For single PAN/FTP profile, allocate 35% for BT | ||
142 | * to improve WLAN throughput. | ||
143 | */ | ||
144 | btcoex->duty_cycle = 35; | ||
145 | btcoex->btcoex_period = 53; | ||
133 | ath_dbg(common, MCI, | 146 | ath_dbg(common, MCI, |
134 | "Single slave PAN/FTP, bt period 60 ms\n"); | 147 | "Single PAN/FTP bt period %d ms dutycycle %d\n", |
135 | } else if ((info->type == MCI_GPM_COEX_PROFILE_HID) && | 148 | btcoex->duty_cycle, btcoex->btcoex_period); |
136 | (info->T > 0 && info->T < 50) && | 149 | } else if (mci->num_hid) { |
137 | (info->A > 1 || info->W > 1)) { | ||
138 | btcoex->duty_cycle = 30; | 150 | btcoex->duty_cycle = 30; |
139 | mci->aggr_limit = 8; | 151 | mci->aggr_limit = 6; |
140 | ath_dbg(common, MCI, | 152 | ath_dbg(common, MCI, |
141 | "Multiple attempt/timeout single HID " | 153 | "Multiple attempt/timeout single HID " |
142 | "aggregation limit 2 ms dutycycle 30%%\n"); | 154 | "aggregation limit 1.5 ms dutycycle 30%%\n"); |
143 | } | 155 | } |
144 | } else if ((num_profile == 2) && (mci->num_hid == 2)) { | 156 | } else if (num_profile == 2) { |
145 | btcoex->duty_cycle = 30; | 157 | if (mci->num_hid == 2) |
146 | mci->aggr_limit = 8; | 158 | btcoex->duty_cycle = 30; |
147 | ath_dbg(common, MCI, | ||
148 | "Two HIDs aggregation limit 2 ms dutycycle 30%%\n"); | ||
149 | } else if (num_profile > 3) { | ||
150 | mci->aggr_limit = 6; | 159 | mci->aggr_limit = 6; |
151 | ath_dbg(common, MCI, | 160 | ath_dbg(common, MCI, |
152 | "Three or more profiles aggregation limit 1.5 ms\n"); | 161 | "Two BT profiles aggr limit 1.5 ms dutycycle %d%%\n", |
162 | btcoex->duty_cycle); | ||
163 | } else if (num_profile >= 3) { | ||
164 | mci->aggr_limit = 4; | ||
165 | ath_dbg(common, MCI, | ||
166 | "Three or more profiles aggregation limit 1 ms\n"); | ||
153 | } | 167 | } |
154 | 168 | ||
169 | skip_tuning: | ||
155 | if (IS_CHAN_2GHZ(sc->sc_ah->curchan)) { | 170 | if (IS_CHAN_2GHZ(sc->sc_ah->curchan)) { |
156 | if (IS_CHAN_HT(sc->sc_ah->curchan)) | 171 | if (IS_CHAN_HT(sc->sc_ah->curchan)) |
157 | ath_mci_adjust_aggr_limit(btcoex); | 172 | ath_mci_adjust_aggr_limit(btcoex); |
@@ -165,12 +180,11 @@ static void ath_mci_update_scheme(struct ath_softc *sc) | |||
165 | if (IS_CHAN_5GHZ(sc->sc_ah->curchan)) | 180 | if (IS_CHAN_5GHZ(sc->sc_ah->curchan)) |
166 | return; | 181 | return; |
167 | 182 | ||
168 | btcoex->duty_cycle += (mci->num_bdr ? ATH_MCI_MAX_DUTY_CYCLE : 0); | 183 | btcoex->duty_cycle += (mci->num_bdr ? ATH_MCI_BDR_DUTY_CYCLE : 0); |
169 | if (btcoex->duty_cycle > ATH_MCI_MAX_DUTY_CYCLE) | 184 | if (btcoex->duty_cycle > ATH_MCI_MAX_DUTY_CYCLE) |
170 | btcoex->duty_cycle = ATH_MCI_MAX_DUTY_CYCLE; | 185 | btcoex->duty_cycle = ATH_MCI_MAX_DUTY_CYCLE; |
171 | 186 | ||
172 | btcoex->btcoex_period *= 1000; | 187 | btcoex->btcoex_no_stomp = btcoex->btcoex_period * 1000 * |
173 | btcoex->btcoex_no_stomp = btcoex->btcoex_period * | ||
174 | (100 - btcoex->duty_cycle) / 100; | 188 | (100 - btcoex->duty_cycle) / 100; |
175 | 189 | ||
176 | ath9k_hw_btcoex_enable(sc->sc_ah); | 190 | ath9k_hw_btcoex_enable(sc->sc_ah); |
@@ -181,20 +195,16 @@ static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) | |||
181 | { | 195 | { |
182 | struct ath_hw *ah = sc->sc_ah; | 196 | struct ath_hw *ah = sc->sc_ah; |
183 | struct ath_common *common = ath9k_hw_common(ah); | 197 | struct ath_common *common = ath9k_hw_common(ah); |
198 | struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; | ||
184 | u32 payload[4] = {0, 0, 0, 0}; | 199 | u32 payload[4] = {0, 0, 0, 0}; |
185 | 200 | ||
186 | switch (opcode) { | 201 | switch (opcode) { |
187 | case MCI_GPM_BT_CAL_REQ: | 202 | case MCI_GPM_BT_CAL_REQ: |
188 | if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_AWAKE) { | 203 | if (mci_hw->bt_state == MCI_BT_AWAKE) { |
189 | ar9003_mci_state(ah, MCI_STATE_SET_BT_CAL_START, NULL); | 204 | ar9003_mci_state(ah, MCI_STATE_SET_BT_CAL_START); |
190 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | 205 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); |
191 | } else { | ||
192 | ath_dbg(common, MCI, "MCI State mismatch: %d\n", | ||
193 | ar9003_mci_state(ah, MCI_STATE_BT, NULL)); | ||
194 | } | 206 | } |
195 | break; | 207 | ath_dbg(common, MCI, "MCI State : %d\n", mci_hw->bt_state); |
196 | case MCI_GPM_BT_CAL_DONE: | ||
197 | ar9003_mci_state(ah, MCI_STATE_BT, NULL); | ||
198 | break; | 208 | break; |
199 | case MCI_GPM_BT_CAL_GRANT: | 209 | case MCI_GPM_BT_CAL_GRANT: |
200 | MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_DONE); | 210 | MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_DONE); |
@@ -207,32 +217,42 @@ static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) | |||
207 | } | 217 | } |
208 | } | 218 | } |
209 | 219 | ||
220 | static void ath9k_mci_work(struct work_struct *work) | ||
221 | { | ||
222 | struct ath_softc *sc = container_of(work, struct ath_softc, mci_work); | ||
223 | |||
224 | ath_mci_update_scheme(sc); | ||
225 | } | ||
226 | |||
210 | static void ath_mci_process_profile(struct ath_softc *sc, | 227 | static void ath_mci_process_profile(struct ath_softc *sc, |
211 | struct ath_mci_profile_info *info) | 228 | struct ath_mci_profile_info *info) |
212 | { | 229 | { |
213 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 230 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
214 | struct ath_btcoex *btcoex = &sc->btcoex; | 231 | struct ath_btcoex *btcoex = &sc->btcoex; |
215 | struct ath_mci_profile *mci = &btcoex->mci; | 232 | struct ath_mci_profile *mci = &btcoex->mci; |
233 | struct ath_mci_profile_info *entry = NULL; | ||
234 | |||
235 | entry = ath_mci_find_profile(mci, info); | ||
236 | if (entry) | ||
237 | memcpy(entry, info, 10); | ||
216 | 238 | ||
217 | if (info->start) { | 239 | if (info->start) { |
218 | if (!ath_mci_add_profile(common, mci, info)) | 240 | if (!entry && !ath_mci_add_profile(common, mci, info)) |
219 | return; | 241 | return; |
220 | } else | 242 | } else |
221 | ath_mci_del_profile(common, mci, info); | 243 | ath_mci_del_profile(common, mci, entry); |
222 | 244 | ||
223 | btcoex->btcoex_period = ATH_MCI_DEF_BT_PERIOD; | 245 | btcoex->btcoex_period = ATH_MCI_DEF_BT_PERIOD; |
224 | mci->aggr_limit = mci->num_sco ? 6 : 0; | 246 | mci->aggr_limit = mci->num_sco ? 6 : 0; |
225 | 247 | ||
226 | if (NUM_PROF(mci)) { | 248 | btcoex->duty_cycle = ath_mci_duty_cycle[NUM_PROF(mci)]; |
249 | if (NUM_PROF(mci)) | ||
227 | btcoex->bt_stomp_type = ATH_BTCOEX_STOMP_LOW; | 250 | btcoex->bt_stomp_type = ATH_BTCOEX_STOMP_LOW; |
228 | btcoex->duty_cycle = ath_mci_duty_cycle[NUM_PROF(mci)]; | 251 | else |
229 | } else { | ||
230 | btcoex->bt_stomp_type = mci->num_mgmt ? ATH_BTCOEX_STOMP_ALL : | 252 | btcoex->bt_stomp_type = mci->num_mgmt ? ATH_BTCOEX_STOMP_ALL : |
231 | ATH_BTCOEX_STOMP_LOW; | 253 | ATH_BTCOEX_STOMP_LOW; |
232 | btcoex->duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE; | ||
233 | } | ||
234 | 254 | ||
235 | ath_mci_update_scheme(sc); | 255 | ieee80211_queue_work(sc->hw, &sc->mci_work); |
236 | } | 256 | } |
237 | 257 | ||
238 | static void ath_mci_process_status(struct ath_softc *sc, | 258 | static void ath_mci_process_status(struct ath_softc *sc, |
@@ -247,8 +267,6 @@ static void ath_mci_process_status(struct ath_softc *sc, | |||
247 | if (status->is_link) | 267 | if (status->is_link) |
248 | return; | 268 | return; |
249 | 269 | ||
250 | memset(&info, 0, sizeof(struct ath_mci_profile_info)); | ||
251 | |||
252 | info.conn_handle = status->conn_handle; | 270 | info.conn_handle = status->conn_handle; |
253 | if (ath_mci_find_profile(mci, &info)) | 271 | if (ath_mci_find_profile(mci, &info)) |
254 | return; | 272 | return; |
@@ -268,7 +286,7 @@ static void ath_mci_process_status(struct ath_softc *sc, | |||
268 | } while (++i < ATH_MCI_MAX_PROFILE); | 286 | } while (++i < ATH_MCI_MAX_PROFILE); |
269 | 287 | ||
270 | if (old_num_mgmt != mci->num_mgmt) | 288 | if (old_num_mgmt != mci->num_mgmt) |
271 | ath_mci_update_scheme(sc); | 289 | ieee80211_queue_work(sc->hw, &sc->mci_work); |
272 | } | 290 | } |
273 | 291 | ||
274 | static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) | 292 | static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) |
@@ -277,25 +295,20 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) | |||
277 | struct ath_mci_profile_info profile_info; | 295 | struct ath_mci_profile_info profile_info; |
278 | struct ath_mci_profile_status profile_status; | 296 | struct ath_mci_profile_status profile_status; |
279 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 297 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
280 | u32 version; | 298 | u8 major, minor; |
281 | u8 major; | ||
282 | u8 minor; | ||
283 | u32 seq_num; | 299 | u32 seq_num; |
284 | 300 | ||
285 | switch (opcode) { | 301 | switch (opcode) { |
286 | case MCI_GPM_COEX_VERSION_QUERY: | 302 | case MCI_GPM_COEX_VERSION_QUERY: |
287 | version = ar9003_mci_state(ah, MCI_STATE_SEND_WLAN_COEX_VERSION, | 303 | ar9003_mci_state(ah, MCI_STATE_SEND_WLAN_COEX_VERSION); |
288 | NULL); | ||
289 | break; | 304 | break; |
290 | case MCI_GPM_COEX_VERSION_RESPONSE: | 305 | case MCI_GPM_COEX_VERSION_RESPONSE: |
291 | major = *(rx_payload + MCI_GPM_COEX_B_MAJOR_VERSION); | 306 | major = *(rx_payload + MCI_GPM_COEX_B_MAJOR_VERSION); |
292 | minor = *(rx_payload + MCI_GPM_COEX_B_MINOR_VERSION); | 307 | minor = *(rx_payload + MCI_GPM_COEX_B_MINOR_VERSION); |
293 | version = (major << 8) + minor; | 308 | ar9003_mci_set_bt_version(ah, major, minor); |
294 | version = ar9003_mci_state(ah, MCI_STATE_SET_BT_COEX_VERSION, | ||
295 | &version); | ||
296 | break; | 309 | break; |
297 | case MCI_GPM_COEX_STATUS_QUERY: | 310 | case MCI_GPM_COEX_STATUS_QUERY: |
298 | ar9003_mci_state(ah, MCI_STATE_SEND_WLAN_CHANNELS, NULL); | 311 | ar9003_mci_send_wlan_channels(ah); |
299 | break; | 312 | break; |
300 | case MCI_GPM_COEX_BT_PROFILE_INFO: | 313 | case MCI_GPM_COEX_BT_PROFILE_INFO: |
301 | memcpy(&profile_info, | 314 | memcpy(&profile_info, |
@@ -362,6 +375,7 @@ int ath_mci_setup(struct ath_softc *sc) | |||
362 | mci->gpm_buf.bf_addr, (mci->gpm_buf.bf_len >> 4), | 375 | mci->gpm_buf.bf_addr, (mci->gpm_buf.bf_len >> 4), |
363 | mci->sched_buf.bf_paddr); | 376 | mci->sched_buf.bf_paddr); |
364 | 377 | ||
378 | INIT_WORK(&sc->mci_work, ath9k_mci_work); | ||
365 | ath_dbg(common, MCI, "MCI Initialized\n"); | 379 | ath_dbg(common, MCI, "MCI Initialized\n"); |
366 | 380 | ||
367 | return 0; | 381 | return 0; |
@@ -389,6 +403,7 @@ void ath_mci_intr(struct ath_softc *sc) | |||
389 | struct ath_mci_coex *mci = &sc->mci_coex; | 403 | struct ath_mci_coex *mci = &sc->mci_coex; |
390 | struct ath_hw *ah = sc->sc_ah; | 404 | struct ath_hw *ah = sc->sc_ah; |
391 | struct ath_common *common = ath9k_hw_common(ah); | 405 | struct ath_common *common = ath9k_hw_common(ah); |
406 | struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; | ||
392 | u32 mci_int, mci_int_rxmsg; | 407 | u32 mci_int, mci_int_rxmsg; |
393 | u32 offset, subtype, opcode; | 408 | u32 offset, subtype, opcode; |
394 | u32 *pgpm; | 409 | u32 *pgpm; |
@@ -397,8 +412,8 @@ void ath_mci_intr(struct ath_softc *sc) | |||
397 | 412 | ||
398 | ar9003_mci_get_interrupt(sc->sc_ah, &mci_int, &mci_int_rxmsg); | 413 | ar9003_mci_get_interrupt(sc->sc_ah, &mci_int, &mci_int_rxmsg); |
399 | 414 | ||
400 | if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) == 0) { | 415 | if (ar9003_mci_state(ah, MCI_STATE_ENABLE) == 0) { |
401 | ar9003_mci_state(ah, MCI_STATE_INIT_GPM_OFFSET, NULL); | 416 | ar9003_mci_get_next_gpm_offset(ah, true, NULL); |
402 | return; | 417 | return; |
403 | } | 418 | } |
404 | 419 | ||
@@ -417,46 +432,41 @@ void ath_mci_intr(struct ath_softc *sc) | |||
417 | NULL, 0, true, false); | 432 | NULL, 0, true, false); |
418 | 433 | ||
419 | mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE; | 434 | mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE; |
420 | ar9003_mci_state(ah, MCI_STATE_RESET_REQ_WAKE, NULL); | 435 | ar9003_mci_state(ah, MCI_STATE_RESET_REQ_WAKE); |
421 | 436 | ||
422 | /* | 437 | /* |
423 | * always do this for recovery and 2G/5G toggling and LNA_TRANS | 438 | * always do this for recovery and 2G/5G toggling and LNA_TRANS |
424 | */ | 439 | */ |
425 | ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE, NULL); | 440 | ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE); |
426 | } | 441 | } |
427 | 442 | ||
428 | if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING) { | 443 | if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING) { |
429 | mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING; | 444 | mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING; |
430 | 445 | ||
431 | if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_SLEEP) { | 446 | if ((mci_hw->bt_state == MCI_BT_SLEEP) && |
432 | if (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL) != | 447 | (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP) != |
433 | MCI_BT_SLEEP) | 448 | MCI_BT_SLEEP)) |
434 | ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE, | 449 | ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE); |
435 | NULL); | ||
436 | } | ||
437 | } | 450 | } |
438 | 451 | ||
439 | if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) { | 452 | if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) { |
440 | mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING; | 453 | mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING; |
441 | 454 | ||
442 | if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_AWAKE) { | 455 | if ((mci_hw->bt_state == MCI_BT_AWAKE) && |
443 | if (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL) != | 456 | (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP) != |
444 | MCI_BT_AWAKE) | 457 | MCI_BT_AWAKE)) |
445 | ar9003_mci_state(ah, MCI_STATE_SET_BT_SLEEP, | 458 | mci_hw->bt_state = MCI_BT_SLEEP; |
446 | NULL); | ||
447 | } | ||
448 | } | 459 | } |
449 | 460 | ||
450 | if ((mci_int & AR_MCI_INTERRUPT_RX_INVALID_HDR) || | 461 | if ((mci_int & AR_MCI_INTERRUPT_RX_INVALID_HDR) || |
451 | (mci_int & AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT)) { | 462 | (mci_int & AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT)) { |
452 | ar9003_mci_state(ah, MCI_STATE_RECOVER_RX, NULL); | 463 | ar9003_mci_state(ah, MCI_STATE_RECOVER_RX); |
453 | skip_gpm = true; | 464 | skip_gpm = true; |
454 | } | 465 | } |
455 | 466 | ||
456 | if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO) { | 467 | if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO) { |
457 | mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO; | 468 | mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO; |
458 | offset = ar9003_mci_state(ah, MCI_STATE_LAST_SCHD_MSG_OFFSET, | 469 | offset = ar9003_mci_state(ah, MCI_STATE_LAST_SCHD_MSG_OFFSET); |
459 | NULL); | ||
460 | } | 470 | } |
461 | 471 | ||
462 | if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_GPM) { | 472 | if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_GPM) { |
@@ -465,8 +475,8 @@ void ath_mci_intr(struct ath_softc *sc) | |||
465 | while (more_data == MCI_GPM_MORE) { | 475 | while (more_data == MCI_GPM_MORE) { |
466 | 476 | ||
467 | pgpm = mci->gpm_buf.bf_addr; | 477 | pgpm = mci->gpm_buf.bf_addr; |
468 | offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET, | 478 | offset = ar9003_mci_get_next_gpm_offset(ah, false, |
469 | &more_data); | 479 | &more_data); |
470 | 480 | ||
471 | if (offset == MCI_GPM_INVALID) | 481 | if (offset == MCI_GPM_INVALID) |
472 | break; | 482 | break; |
@@ -507,23 +517,17 @@ void ath_mci_intr(struct ath_softc *sc) | |||
507 | mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_LNA_INFO; | 517 | mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_LNA_INFO; |
508 | 518 | ||
509 | if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO) { | 519 | if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO) { |
510 | int value_dbm = ar9003_mci_state(ah, | 520 | int value_dbm = MS(mci_hw->cont_status, |
511 | MCI_STATE_CONT_RSSI_POWER, NULL); | 521 | AR_MCI_CONT_RSSI_POWER); |
512 | 522 | ||
513 | mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_CONT_INFO; | 523 | mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_CONT_INFO; |
514 | 524 | ||
515 | if (ar9003_mci_state(ah, MCI_STATE_CONT_TXRX, NULL)) | 525 | ath_dbg(common, MCI, |
516 | ath_dbg(common, MCI, | 526 | "MCI CONT_INFO: (%s) pri = %d pwr = %d dBm\n", |
517 | "MCI CONT_INFO: (tx) pri = %d, pwr = %d dBm\n", | 527 | MS(mci_hw->cont_status, AR_MCI_CONT_TXRX) ? |
518 | ar9003_mci_state(ah, | 528 | "tx" : "rx", |
519 | MCI_STATE_CONT_PRIORITY, NULL), | 529 | MS(mci_hw->cont_status, AR_MCI_CONT_PRIORITY), |
520 | value_dbm); | 530 | value_dbm); |
521 | else | ||
522 | ath_dbg(common, MCI, | ||
523 | "MCI CONT_INFO: (rx) pri = %d,pwr = %d dBm\n", | ||
524 | ar9003_mci_state(ah, | ||
525 | MCI_STATE_CONT_PRIORITY, NULL), | ||
526 | value_dbm); | ||
527 | } | 531 | } |
528 | 532 | ||
529 | if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_NACK) | 533 | if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_NACK) |
@@ -538,3 +542,14 @@ void ath_mci_intr(struct ath_softc *sc) | |||
538 | mci_int &= ~(AR_MCI_INTERRUPT_RX_INVALID_HDR | | 542 | mci_int &= ~(AR_MCI_INTERRUPT_RX_INVALID_HDR | |
539 | AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT); | 543 | AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT); |
540 | } | 544 | } |
545 | |||
546 | void ath_mci_enable(struct ath_softc *sc) | ||
547 | { | ||
548 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
549 | |||
550 | if (!common->btcoex_enabled) | ||
551 | return; | ||
552 | |||
553 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) | ||
554 | sc->sc_ah->imask |= ATH9K_INT_MCI; | ||
555 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/mci.h b/drivers/net/wireless/ath/ath9k/mci.h index c841444f53c2..fc14eea034eb 100644 --- a/drivers/net/wireless/ath/ath9k/mci.h +++ b/drivers/net/wireless/ath/ath9k/mci.h | |||
@@ -130,4 +130,13 @@ void ath_mci_flush_profile(struct ath_mci_profile *mci); | |||
130 | int ath_mci_setup(struct ath_softc *sc); | 130 | int ath_mci_setup(struct ath_softc *sc); |
131 | void ath_mci_cleanup(struct ath_softc *sc); | 131 | void ath_mci_cleanup(struct ath_softc *sc); |
132 | void ath_mci_intr(struct ath_softc *sc); | 132 | void ath_mci_intr(struct ath_softc *sc); |
133 | #endif | 133 | |
134 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT | ||
135 | void ath_mci_enable(struct ath_softc *sc); | ||
136 | #else | ||
137 | static inline void ath_mci_enable(struct ath_softc *sc) | ||
138 | { | ||
139 | } | ||
140 | #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ | ||
141 | |||
142 | #endif /* MCI_H*/ | ||
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index a856b51255f4..aa0e83ac51f4 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c | |||
@@ -115,6 +115,9 @@ static void ath_pci_aspm_init(struct ath_common *common) | |||
115 | int pos; | 115 | int pos; |
116 | u8 aspm; | 116 | u8 aspm; |
117 | 117 | ||
118 | if (!ah->is_pciexpress) | ||
119 | return; | ||
120 | |||
118 | pos = pci_pcie_cap(pdev); | 121 | pos = pci_pcie_cap(pdev); |
119 | if (!pos) | 122 | if (!pos) |
120 | return; | 123 | return; |
@@ -138,6 +141,7 @@ static void ath_pci_aspm_init(struct ath_common *common) | |||
138 | aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); | 141 | aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); |
139 | pci_write_config_byte(parent, pos + PCI_EXP_LNKCTL, aspm); | 142 | pci_write_config_byte(parent, pos + PCI_EXP_LNKCTL, aspm); |
140 | 143 | ||
144 | ath_info(common, "Disabling ASPM since BTCOEX is enabled\n"); | ||
141 | return; | 145 | return; |
142 | } | 146 | } |
143 | 147 | ||
@@ -147,6 +151,7 @@ static void ath_pci_aspm_init(struct ath_common *common) | |||
147 | ah->aspm_enabled = true; | 151 | ah->aspm_enabled = true; |
148 | /* Initialize PCIe PM and SERDES registers. */ | 152 | /* Initialize PCIe PM and SERDES registers. */ |
149 | ath9k_hw_configpcipowersave(ah, false); | 153 | ath9k_hw_configpcipowersave(ah, false); |
154 | ath_info(common, "ASPM enabled: 0x%x\n", aspm); | ||
150 | } | 155 | } |
151 | } | 156 | } |
152 | 157 | ||
@@ -246,7 +251,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
246 | sc->mem = mem; | 251 | sc->mem = mem; |
247 | 252 | ||
248 | /* Will be cleared in ath9k_start() */ | 253 | /* Will be cleared in ath9k_start() */ |
249 | sc->sc_flags |= SC_OP_INVALID; | 254 | set_bit(SC_OP_INVALID, &sc->sc_flags); |
250 | 255 | ||
251 | ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc); | 256 | ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc); |
252 | if (ret) { | 257 | if (ret) { |
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 5fff711fba1d..e034add9cd5a 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
@@ -770,7 +770,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | |||
770 | struct ieee80211_tx_rate *rates = tx_info->control.rates; | 770 | struct ieee80211_tx_rate *rates = tx_info->control.rates; |
771 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 771 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
772 | __le16 fc = hdr->frame_control; | 772 | __le16 fc = hdr->frame_control; |
773 | u8 try_per_rate, i = 0, rix, high_rix; | 773 | u8 try_per_rate, i = 0, rix; |
774 | int is_probe = 0; | 774 | int is_probe = 0; |
775 | 775 | ||
776 | if (rate_control_send_low(sta, priv_sta, txrc)) | 776 | if (rate_control_send_low(sta, priv_sta, txrc)) |
@@ -791,7 +791,6 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | |||
791 | rate_table = ath_rc_priv->rate_table; | 791 | rate_table = ath_rc_priv->rate_table; |
792 | rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, | 792 | rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, |
793 | &is_probe, false); | 793 | &is_probe, false); |
794 | high_rix = rix; | ||
795 | 794 | ||
796 | /* | 795 | /* |
797 | * If we're in HT mode and both us and our peer supports LDPC. | 796 | * If we're in HT mode and both us and our peer supports LDPC. |
@@ -839,16 +838,16 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | |||
839 | try_per_rate = 8; | 838 | try_per_rate = 8; |
840 | 839 | ||
841 | /* | 840 | /* |
842 | * Use a legacy rate as last retry to ensure that the frame | 841 | * If the last rate in the rate series is MCS and has |
843 | * is tried in both MCS and legacy rates. | 842 | * more than 80% of per thresh, then use a legacy rate |
843 | * as last retry to ensure that the frame is tried in both | ||
844 | * MCS and legacy rate. | ||
844 | */ | 845 | */ |
845 | if ((rates[2].flags & IEEE80211_TX_RC_MCS) && | 846 | ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix); |
846 | (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU) || | 847 | if (WLAN_RC_PHY_HT(rate_table->info[rix].phy) && |
847 | (ath_rc_priv->per[high_rix] > 45))) | 848 | (ath_rc_priv->per[rix] > 45)) |
848 | rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, | 849 | rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, |
849 | &is_probe, true); | 850 | &is_probe, true); |
850 | else | ||
851 | ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix); | ||
852 | 851 | ||
853 | /* All other rates in the series have RTS enabled */ | 852 | /* All other rates in the series have RTS enabled */ |
854 | ath_rc_rate_set_series(rate_table, &rates[i], txrc, | 853 | ath_rc_rate_set_series(rate_table, &rates[i], txrc, |
@@ -1479,12 +1478,6 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, | |||
1479 | 1478 | ||
1480 | #ifdef CONFIG_ATH9K_DEBUGFS | 1479 | #ifdef CONFIG_ATH9K_DEBUGFS |
1481 | 1480 | ||
1482 | static int ath9k_debugfs_open(struct inode *inode, struct file *file) | ||
1483 | { | ||
1484 | file->private_data = inode->i_private; | ||
1485 | return 0; | ||
1486 | } | ||
1487 | |||
1488 | static ssize_t read_file_rcstat(struct file *file, char __user *user_buf, | 1481 | static ssize_t read_file_rcstat(struct file *file, char __user *user_buf, |
1489 | size_t count, loff_t *ppos) | 1482 | size_t count, loff_t *ppos) |
1490 | { | 1483 | { |
@@ -1552,7 +1545,7 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf, | |||
1552 | 1545 | ||
1553 | static const struct file_operations fops_rcstat = { | 1546 | static const struct file_operations fops_rcstat = { |
1554 | .read = read_file_rcstat, | 1547 | .read = read_file_rcstat, |
1555 | .open = ath9k_debugfs_open, | 1548 | .open = simple_open, |
1556 | .owner = THIS_MODULE | 1549 | .owner = THIS_MODULE |
1557 | }; | 1550 | }; |
1558 | 1551 | ||
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 301ef3e57145..fbdcc80437fe 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -20,43 +20,6 @@ | |||
20 | 20 | ||
21 | #define SKB_CB_ATHBUF(__skb) (*((struct ath_buf **)__skb->cb)) | 21 | #define SKB_CB_ATHBUF(__skb) (*((struct ath_buf **)__skb->cb)) |
22 | 22 | ||
23 | static inline bool ath_is_alt_ant_ratio_better(int alt_ratio, int maxdelta, | ||
24 | int mindelta, int main_rssi_avg, | ||
25 | int alt_rssi_avg, int pkt_count) | ||
26 | { | ||
27 | return (((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && | ||
28 | (alt_rssi_avg > main_rssi_avg + maxdelta)) || | ||
29 | (alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50); | ||
30 | } | ||
31 | |||
32 | static inline bool ath_ant_div_comb_alt_check(u8 div_group, int alt_ratio, | ||
33 | int curr_main_set, int curr_alt_set, | ||
34 | int alt_rssi_avg, int main_rssi_avg) | ||
35 | { | ||
36 | bool result = false; | ||
37 | switch (div_group) { | ||
38 | case 0: | ||
39 | if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) | ||
40 | result = true; | ||
41 | break; | ||
42 | case 1: | ||
43 | case 2: | ||
44 | if ((((curr_main_set == ATH_ANT_DIV_COMB_LNA2) && | ||
45 | (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) && | ||
46 | (alt_rssi_avg >= (main_rssi_avg - 5))) || | ||
47 | ((curr_main_set == ATH_ANT_DIV_COMB_LNA1) && | ||
48 | (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) && | ||
49 | (alt_rssi_avg >= (main_rssi_avg - 2)))) && | ||
50 | (alt_rssi_avg >= 4)) | ||
51 | result = true; | ||
52 | else | ||
53 | result = false; | ||
54 | break; | ||
55 | } | ||
56 | |||
57 | return result; | ||
58 | } | ||
59 | |||
60 | static inline bool ath9k_check_auto_sleep(struct ath_softc *sc) | 23 | static inline bool ath9k_check_auto_sleep(struct ath_softc *sc) |
61 | { | 24 | { |
62 | return sc->ps_enabled && | 25 | return sc->ps_enabled && |
@@ -303,7 +266,7 @@ static void ath_edma_start_recv(struct ath_softc *sc) | |||
303 | 266 | ||
304 | ath_opmode_init(sc); | 267 | ath_opmode_init(sc); |
305 | 268 | ||
306 | ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_OFFCHANNEL)); | 269 | ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); |
307 | 270 | ||
308 | spin_unlock_bh(&sc->rx.rxbuflock); | 271 | spin_unlock_bh(&sc->rx.rxbuflock); |
309 | } | 272 | } |
@@ -322,8 +285,8 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) | |||
322 | int error = 0; | 285 | int error = 0; |
323 | 286 | ||
324 | spin_lock_init(&sc->sc_pcu_lock); | 287 | spin_lock_init(&sc->sc_pcu_lock); |
325 | sc->sc_flags &= ~SC_OP_RXFLUSH; | ||
326 | spin_lock_init(&sc->rx.rxbuflock); | 288 | spin_lock_init(&sc->rx.rxbuflock); |
289 | clear_bit(SC_OP_RXFLUSH, &sc->sc_flags); | ||
327 | 290 | ||
328 | common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 + | 291 | common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 + |
329 | sc->sc_ah->caps.rx_status_len; | 292 | sc->sc_ah->caps.rx_status_len; |
@@ -500,7 +463,7 @@ int ath_startrecv(struct ath_softc *sc) | |||
500 | 463 | ||
501 | start_recv: | 464 | start_recv: |
502 | ath_opmode_init(sc); | 465 | ath_opmode_init(sc); |
503 | ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_OFFCHANNEL)); | 466 | ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); |
504 | 467 | ||
505 | spin_unlock_bh(&sc->rx.rxbuflock); | 468 | spin_unlock_bh(&sc->rx.rxbuflock); |
506 | 469 | ||
@@ -535,11 +498,11 @@ bool ath_stoprecv(struct ath_softc *sc) | |||
535 | 498 | ||
536 | void ath_flushrecv(struct ath_softc *sc) | 499 | void ath_flushrecv(struct ath_softc *sc) |
537 | { | 500 | { |
538 | sc->sc_flags |= SC_OP_RXFLUSH; | 501 | set_bit(SC_OP_RXFLUSH, &sc->sc_flags); |
539 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | 502 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) |
540 | ath_rx_tasklet(sc, 1, true); | 503 | ath_rx_tasklet(sc, 1, true); |
541 | ath_rx_tasklet(sc, 1, false); | 504 | ath_rx_tasklet(sc, 1, false); |
542 | sc->sc_flags &= ~SC_OP_RXFLUSH; | 505 | clear_bit(SC_OP_RXFLUSH, &sc->sc_flags); |
543 | } | 506 | } |
544 | 507 | ||
545 | static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb) | 508 | static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb) |
@@ -624,13 +587,13 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb, bool mybeacon) | |||
624 | 587 | ||
625 | /* Process Beacon and CAB receive in PS state */ | 588 | /* Process Beacon and CAB receive in PS state */ |
626 | if (((sc->ps_flags & PS_WAIT_FOR_BEACON) || ath9k_check_auto_sleep(sc)) | 589 | if (((sc->ps_flags & PS_WAIT_FOR_BEACON) || ath9k_check_auto_sleep(sc)) |
627 | && mybeacon) | 590 | && mybeacon) { |
628 | ath_rx_ps_beacon(sc, skb); | 591 | ath_rx_ps_beacon(sc, skb); |
629 | else if ((sc->ps_flags & PS_WAIT_FOR_CAB) && | 592 | } else if ((sc->ps_flags & PS_WAIT_FOR_CAB) && |
630 | (ieee80211_is_data(hdr->frame_control) || | 593 | (ieee80211_is_data(hdr->frame_control) || |
631 | ieee80211_is_action(hdr->frame_control)) && | 594 | ieee80211_is_action(hdr->frame_control)) && |
632 | is_multicast_ether_addr(hdr->addr1) && | 595 | is_multicast_ether_addr(hdr->addr1) && |
633 | !ieee80211_has_moredata(hdr->frame_control)) { | 596 | !ieee80211_has_moredata(hdr->frame_control)) { |
634 | /* | 597 | /* |
635 | * No more broadcast/multicast frames to be received at this | 598 | * No more broadcast/multicast frames to be received at this |
636 | * point. | 599 | * point. |
@@ -812,6 +775,7 @@ static bool ath9k_rx_accept(struct ath_common *common, | |||
812 | is_valid_tkip = rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID && | 775 | is_valid_tkip = rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID && |
813 | test_bit(rx_stats->rs_keyix, common->tkip_keymap); | 776 | test_bit(rx_stats->rs_keyix, common->tkip_keymap); |
814 | strip_mic = is_valid_tkip && ieee80211_is_data(fc) && | 777 | strip_mic = is_valid_tkip && ieee80211_is_data(fc) && |
778 | ieee80211_has_protected(fc) && | ||
815 | !(rx_stats->rs_status & | 779 | !(rx_stats->rs_status & |
816 | (ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC | | 780 | (ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC | |
817 | ATH9K_RXERR_KEYMISS)); | 781 | ATH9K_RXERR_KEYMISS)); |
@@ -907,7 +871,7 @@ static int ath9k_process_rate(struct ath_common *common, | |||
907 | struct ieee80211_supported_band *sband; | 871 | struct ieee80211_supported_band *sband; |
908 | enum ieee80211_band band; | 872 | enum ieee80211_band band; |
909 | unsigned int i = 0; | 873 | unsigned int i = 0; |
910 | struct ath_softc *sc = (struct ath_softc *) common->priv; | 874 | struct ath_softc __maybe_unused *sc = common->priv; |
911 | 875 | ||
912 | band = hw->conf.channel->band; | 876 | band = hw->conf.channel->band; |
913 | sband = hw->wiphy->bands[band]; | 877 | sband = hw->wiphy->bands[band]; |
@@ -1066,709 +1030,6 @@ static void ath9k_rx_skb_postprocess(struct ath_common *common, | |||
1066 | rxs->flag &= ~RX_FLAG_DECRYPTED; | 1030 | rxs->flag &= ~RX_FLAG_DECRYPTED; |
1067 | } | 1031 | } |
1068 | 1032 | ||
1069 | static void ath_lnaconf_alt_good_scan(struct ath_ant_comb *antcomb, | ||
1070 | struct ath_hw_antcomb_conf ant_conf, | ||
1071 | int main_rssi_avg) | ||
1072 | { | ||
1073 | antcomb->quick_scan_cnt = 0; | ||
1074 | |||
1075 | if (ant_conf.main_lna_conf == ATH_ANT_DIV_COMB_LNA2) | ||
1076 | antcomb->rssi_lna2 = main_rssi_avg; | ||
1077 | else if (ant_conf.main_lna_conf == ATH_ANT_DIV_COMB_LNA1) | ||
1078 | antcomb->rssi_lna1 = main_rssi_avg; | ||
1079 | |||
1080 | switch ((ant_conf.main_lna_conf << 4) | ant_conf.alt_lna_conf) { | ||
1081 | case 0x10: /* LNA2 A-B */ | ||
1082 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1083 | antcomb->first_quick_scan_conf = | ||
1084 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1085 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1; | ||
1086 | break; | ||
1087 | case 0x20: /* LNA1 A-B */ | ||
1088 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1089 | antcomb->first_quick_scan_conf = | ||
1090 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1091 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2; | ||
1092 | break; | ||
1093 | case 0x21: /* LNA1 LNA2 */ | ||
1094 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA2; | ||
1095 | antcomb->first_quick_scan_conf = | ||
1096 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1097 | antcomb->second_quick_scan_conf = | ||
1098 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1099 | break; | ||
1100 | case 0x12: /* LNA2 LNA1 */ | ||
1101 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1; | ||
1102 | antcomb->first_quick_scan_conf = | ||
1103 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1104 | antcomb->second_quick_scan_conf = | ||
1105 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1106 | break; | ||
1107 | case 0x13: /* LNA2 A+B */ | ||
1108 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1109 | antcomb->first_quick_scan_conf = | ||
1110 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1111 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1; | ||
1112 | break; | ||
1113 | case 0x23: /* LNA1 A+B */ | ||
1114 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1115 | antcomb->first_quick_scan_conf = | ||
1116 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1117 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2; | ||
1118 | break; | ||
1119 | default: | ||
1120 | break; | ||
1121 | } | ||
1122 | } | ||
1123 | |||
1124 | static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb, | ||
1125 | struct ath_hw_antcomb_conf *div_ant_conf, | ||
1126 | int main_rssi_avg, int alt_rssi_avg, | ||
1127 | int alt_ratio) | ||
1128 | { | ||
1129 | /* alt_good */ | ||
1130 | switch (antcomb->quick_scan_cnt) { | ||
1131 | case 0: | ||
1132 | /* set alt to main, and alt to first conf */ | ||
1133 | div_ant_conf->main_lna_conf = antcomb->main_conf; | ||
1134 | div_ant_conf->alt_lna_conf = antcomb->first_quick_scan_conf; | ||
1135 | break; | ||
1136 | case 1: | ||
1137 | /* set alt to main, and alt to first conf */ | ||
1138 | div_ant_conf->main_lna_conf = antcomb->main_conf; | ||
1139 | div_ant_conf->alt_lna_conf = antcomb->second_quick_scan_conf; | ||
1140 | antcomb->rssi_first = main_rssi_avg; | ||
1141 | antcomb->rssi_second = alt_rssi_avg; | ||
1142 | |||
1143 | if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) { | ||
1144 | /* main is LNA1 */ | ||
1145 | if (ath_is_alt_ant_ratio_better(alt_ratio, | ||
1146 | ATH_ANT_DIV_COMB_LNA1_DELTA_HI, | ||
1147 | ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, | ||
1148 | main_rssi_avg, alt_rssi_avg, | ||
1149 | antcomb->total_pkt_count)) | ||
1150 | antcomb->first_ratio = true; | ||
1151 | else | ||
1152 | antcomb->first_ratio = false; | ||
1153 | } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) { | ||
1154 | if (ath_is_alt_ant_ratio_better(alt_ratio, | ||
1155 | ATH_ANT_DIV_COMB_LNA1_DELTA_MID, | ||
1156 | ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, | ||
1157 | main_rssi_avg, alt_rssi_avg, | ||
1158 | antcomb->total_pkt_count)) | ||
1159 | antcomb->first_ratio = true; | ||
1160 | else | ||
1161 | antcomb->first_ratio = false; | ||
1162 | } else { | ||
1163 | if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && | ||
1164 | (alt_rssi_avg > main_rssi_avg + | ||
1165 | ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) || | ||
1166 | (alt_rssi_avg > main_rssi_avg)) && | ||
1167 | (antcomb->total_pkt_count > 50)) | ||
1168 | antcomb->first_ratio = true; | ||
1169 | else | ||
1170 | antcomb->first_ratio = false; | ||
1171 | } | ||
1172 | break; | ||
1173 | case 2: | ||
1174 | antcomb->alt_good = false; | ||
1175 | antcomb->scan_not_start = false; | ||
1176 | antcomb->scan = false; | ||
1177 | antcomb->rssi_first = main_rssi_avg; | ||
1178 | antcomb->rssi_third = alt_rssi_avg; | ||
1179 | |||
1180 | if (antcomb->second_quick_scan_conf == ATH_ANT_DIV_COMB_LNA1) | ||
1181 | antcomb->rssi_lna1 = alt_rssi_avg; | ||
1182 | else if (antcomb->second_quick_scan_conf == | ||
1183 | ATH_ANT_DIV_COMB_LNA2) | ||
1184 | antcomb->rssi_lna2 = alt_rssi_avg; | ||
1185 | else if (antcomb->second_quick_scan_conf == | ||
1186 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2) { | ||
1187 | if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) | ||
1188 | antcomb->rssi_lna2 = main_rssi_avg; | ||
1189 | else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) | ||
1190 | antcomb->rssi_lna1 = main_rssi_avg; | ||
1191 | } | ||
1192 | |||
1193 | if (antcomb->rssi_lna2 > antcomb->rssi_lna1 + | ||
1194 | ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA) | ||
1195 | div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA2; | ||
1196 | else | ||
1197 | div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1; | ||
1198 | |||
1199 | if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) { | ||
1200 | if (ath_is_alt_ant_ratio_better(alt_ratio, | ||
1201 | ATH_ANT_DIV_COMB_LNA1_DELTA_HI, | ||
1202 | ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, | ||
1203 | main_rssi_avg, alt_rssi_avg, | ||
1204 | antcomb->total_pkt_count)) | ||
1205 | antcomb->second_ratio = true; | ||
1206 | else | ||
1207 | antcomb->second_ratio = false; | ||
1208 | } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) { | ||
1209 | if (ath_is_alt_ant_ratio_better(alt_ratio, | ||
1210 | ATH_ANT_DIV_COMB_LNA1_DELTA_MID, | ||
1211 | ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, | ||
1212 | main_rssi_avg, alt_rssi_avg, | ||
1213 | antcomb->total_pkt_count)) | ||
1214 | antcomb->second_ratio = true; | ||
1215 | else | ||
1216 | antcomb->second_ratio = false; | ||
1217 | } else { | ||
1218 | if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && | ||
1219 | (alt_rssi_avg > main_rssi_avg + | ||
1220 | ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) || | ||
1221 | (alt_rssi_avg > main_rssi_avg)) && | ||
1222 | (antcomb->total_pkt_count > 50)) | ||
1223 | antcomb->second_ratio = true; | ||
1224 | else | ||
1225 | antcomb->second_ratio = false; | ||
1226 | } | ||
1227 | |||
1228 | /* set alt to the conf with maximun ratio */ | ||
1229 | if (antcomb->first_ratio && antcomb->second_ratio) { | ||
1230 | if (antcomb->rssi_second > antcomb->rssi_third) { | ||
1231 | /* first alt*/ | ||
1232 | if ((antcomb->first_quick_scan_conf == | ||
1233 | ATH_ANT_DIV_COMB_LNA1) || | ||
1234 | (antcomb->first_quick_scan_conf == | ||
1235 | ATH_ANT_DIV_COMB_LNA2)) | ||
1236 | /* Set alt LNA1 or LNA2*/ | ||
1237 | if (div_ant_conf->main_lna_conf == | ||
1238 | ATH_ANT_DIV_COMB_LNA2) | ||
1239 | div_ant_conf->alt_lna_conf = | ||
1240 | ATH_ANT_DIV_COMB_LNA1; | ||
1241 | else | ||
1242 | div_ant_conf->alt_lna_conf = | ||
1243 | ATH_ANT_DIV_COMB_LNA2; | ||
1244 | else | ||
1245 | /* Set alt to A+B or A-B */ | ||
1246 | div_ant_conf->alt_lna_conf = | ||
1247 | antcomb->first_quick_scan_conf; | ||
1248 | } else if ((antcomb->second_quick_scan_conf == | ||
1249 | ATH_ANT_DIV_COMB_LNA1) || | ||
1250 | (antcomb->second_quick_scan_conf == | ||
1251 | ATH_ANT_DIV_COMB_LNA2)) { | ||
1252 | /* Set alt LNA1 or LNA2 */ | ||
1253 | if (div_ant_conf->main_lna_conf == | ||
1254 | ATH_ANT_DIV_COMB_LNA2) | ||
1255 | div_ant_conf->alt_lna_conf = | ||
1256 | ATH_ANT_DIV_COMB_LNA1; | ||
1257 | else | ||
1258 | div_ant_conf->alt_lna_conf = | ||
1259 | ATH_ANT_DIV_COMB_LNA2; | ||
1260 | } else { | ||
1261 | /* Set alt to A+B or A-B */ | ||
1262 | div_ant_conf->alt_lna_conf = | ||
1263 | antcomb->second_quick_scan_conf; | ||
1264 | } | ||
1265 | } else if (antcomb->first_ratio) { | ||
1266 | /* first alt */ | ||
1267 | if ((antcomb->first_quick_scan_conf == | ||
1268 | ATH_ANT_DIV_COMB_LNA1) || | ||
1269 | (antcomb->first_quick_scan_conf == | ||
1270 | ATH_ANT_DIV_COMB_LNA2)) | ||
1271 | /* Set alt LNA1 or LNA2 */ | ||
1272 | if (div_ant_conf->main_lna_conf == | ||
1273 | ATH_ANT_DIV_COMB_LNA2) | ||
1274 | div_ant_conf->alt_lna_conf = | ||
1275 | ATH_ANT_DIV_COMB_LNA1; | ||
1276 | else | ||
1277 | div_ant_conf->alt_lna_conf = | ||
1278 | ATH_ANT_DIV_COMB_LNA2; | ||
1279 | else | ||
1280 | /* Set alt to A+B or A-B */ | ||
1281 | div_ant_conf->alt_lna_conf = | ||
1282 | antcomb->first_quick_scan_conf; | ||
1283 | } else if (antcomb->second_ratio) { | ||
1284 | /* second alt */ | ||
1285 | if ((antcomb->second_quick_scan_conf == | ||
1286 | ATH_ANT_DIV_COMB_LNA1) || | ||
1287 | (antcomb->second_quick_scan_conf == | ||
1288 | ATH_ANT_DIV_COMB_LNA2)) | ||
1289 | /* Set alt LNA1 or LNA2 */ | ||
1290 | if (div_ant_conf->main_lna_conf == | ||
1291 | ATH_ANT_DIV_COMB_LNA2) | ||
1292 | div_ant_conf->alt_lna_conf = | ||
1293 | ATH_ANT_DIV_COMB_LNA1; | ||
1294 | else | ||
1295 | div_ant_conf->alt_lna_conf = | ||
1296 | ATH_ANT_DIV_COMB_LNA2; | ||
1297 | else | ||
1298 | /* Set alt to A+B or A-B */ | ||
1299 | div_ant_conf->alt_lna_conf = | ||
1300 | antcomb->second_quick_scan_conf; | ||
1301 | } else { | ||
1302 | /* main is largest */ | ||
1303 | if ((antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) || | ||
1304 | (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2)) | ||
1305 | /* Set alt LNA1 or LNA2 */ | ||
1306 | if (div_ant_conf->main_lna_conf == | ||
1307 | ATH_ANT_DIV_COMB_LNA2) | ||
1308 | div_ant_conf->alt_lna_conf = | ||
1309 | ATH_ANT_DIV_COMB_LNA1; | ||
1310 | else | ||
1311 | div_ant_conf->alt_lna_conf = | ||
1312 | ATH_ANT_DIV_COMB_LNA2; | ||
1313 | else | ||
1314 | /* Set alt to A+B or A-B */ | ||
1315 | div_ant_conf->alt_lna_conf = antcomb->main_conf; | ||
1316 | } | ||
1317 | break; | ||
1318 | default: | ||
1319 | break; | ||
1320 | } | ||
1321 | } | ||
1322 | |||
1323 | static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, | ||
1324 | struct ath_ant_comb *antcomb, int alt_ratio) | ||
1325 | { | ||
1326 | if (ant_conf->div_group == 0) { | ||
1327 | /* Adjust the fast_div_bias based on main and alt lna conf */ | ||
1328 | switch ((ant_conf->main_lna_conf << 4) | | ||
1329 | ant_conf->alt_lna_conf) { | ||
1330 | case 0x01: /* A-B LNA2 */ | ||
1331 | ant_conf->fast_div_bias = 0x3b; | ||
1332 | break; | ||
1333 | case 0x02: /* A-B LNA1 */ | ||
1334 | ant_conf->fast_div_bias = 0x3d; | ||
1335 | break; | ||
1336 | case 0x03: /* A-B A+B */ | ||
1337 | ant_conf->fast_div_bias = 0x1; | ||
1338 | break; | ||
1339 | case 0x10: /* LNA2 A-B */ | ||
1340 | ant_conf->fast_div_bias = 0x7; | ||
1341 | break; | ||
1342 | case 0x12: /* LNA2 LNA1 */ | ||
1343 | ant_conf->fast_div_bias = 0x2; | ||
1344 | break; | ||
1345 | case 0x13: /* LNA2 A+B */ | ||
1346 | ant_conf->fast_div_bias = 0x7; | ||
1347 | break; | ||
1348 | case 0x20: /* LNA1 A-B */ | ||
1349 | ant_conf->fast_div_bias = 0x6; | ||
1350 | break; | ||
1351 | case 0x21: /* LNA1 LNA2 */ | ||
1352 | ant_conf->fast_div_bias = 0x0; | ||
1353 | break; | ||
1354 | case 0x23: /* LNA1 A+B */ | ||
1355 | ant_conf->fast_div_bias = 0x6; | ||
1356 | break; | ||
1357 | case 0x30: /* A+B A-B */ | ||
1358 | ant_conf->fast_div_bias = 0x1; | ||
1359 | break; | ||
1360 | case 0x31: /* A+B LNA2 */ | ||
1361 | ant_conf->fast_div_bias = 0x3b; | ||
1362 | break; | ||
1363 | case 0x32: /* A+B LNA1 */ | ||
1364 | ant_conf->fast_div_bias = 0x3d; | ||
1365 | break; | ||
1366 | default: | ||
1367 | break; | ||
1368 | } | ||
1369 | } else if (ant_conf->div_group == 1) { | ||
1370 | /* Adjust the fast_div_bias based on main and alt_lna_conf */ | ||
1371 | switch ((ant_conf->main_lna_conf << 4) | | ||
1372 | ant_conf->alt_lna_conf) { | ||
1373 | case 0x01: /* A-B LNA2 */ | ||
1374 | ant_conf->fast_div_bias = 0x1; | ||
1375 | ant_conf->main_gaintb = 0; | ||
1376 | ant_conf->alt_gaintb = 0; | ||
1377 | break; | ||
1378 | case 0x02: /* A-B LNA1 */ | ||
1379 | ant_conf->fast_div_bias = 0x1; | ||
1380 | ant_conf->main_gaintb = 0; | ||
1381 | ant_conf->alt_gaintb = 0; | ||
1382 | break; | ||
1383 | case 0x03: /* A-B A+B */ | ||
1384 | ant_conf->fast_div_bias = 0x1; | ||
1385 | ant_conf->main_gaintb = 0; | ||
1386 | ant_conf->alt_gaintb = 0; | ||
1387 | break; | ||
1388 | case 0x10: /* LNA2 A-B */ | ||
1389 | if (!(antcomb->scan) && | ||
1390 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1391 | ant_conf->fast_div_bias = 0x3f; | ||
1392 | else | ||
1393 | ant_conf->fast_div_bias = 0x1; | ||
1394 | ant_conf->main_gaintb = 0; | ||
1395 | ant_conf->alt_gaintb = 0; | ||
1396 | break; | ||
1397 | case 0x12: /* LNA2 LNA1 */ | ||
1398 | ant_conf->fast_div_bias = 0x1; | ||
1399 | ant_conf->main_gaintb = 0; | ||
1400 | ant_conf->alt_gaintb = 0; | ||
1401 | break; | ||
1402 | case 0x13: /* LNA2 A+B */ | ||
1403 | if (!(antcomb->scan) && | ||
1404 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1405 | ant_conf->fast_div_bias = 0x3f; | ||
1406 | else | ||
1407 | ant_conf->fast_div_bias = 0x1; | ||
1408 | ant_conf->main_gaintb = 0; | ||
1409 | ant_conf->alt_gaintb = 0; | ||
1410 | break; | ||
1411 | case 0x20: /* LNA1 A-B */ | ||
1412 | if (!(antcomb->scan) && | ||
1413 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1414 | ant_conf->fast_div_bias = 0x3f; | ||
1415 | else | ||
1416 | ant_conf->fast_div_bias = 0x1; | ||
1417 | ant_conf->main_gaintb = 0; | ||
1418 | ant_conf->alt_gaintb = 0; | ||
1419 | break; | ||
1420 | case 0x21: /* LNA1 LNA2 */ | ||
1421 | ant_conf->fast_div_bias = 0x1; | ||
1422 | ant_conf->main_gaintb = 0; | ||
1423 | ant_conf->alt_gaintb = 0; | ||
1424 | break; | ||
1425 | case 0x23: /* LNA1 A+B */ | ||
1426 | if (!(antcomb->scan) && | ||
1427 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1428 | ant_conf->fast_div_bias = 0x3f; | ||
1429 | else | ||
1430 | ant_conf->fast_div_bias = 0x1; | ||
1431 | ant_conf->main_gaintb = 0; | ||
1432 | ant_conf->alt_gaintb = 0; | ||
1433 | break; | ||
1434 | case 0x30: /* A+B A-B */ | ||
1435 | ant_conf->fast_div_bias = 0x1; | ||
1436 | ant_conf->main_gaintb = 0; | ||
1437 | ant_conf->alt_gaintb = 0; | ||
1438 | break; | ||
1439 | case 0x31: /* A+B LNA2 */ | ||
1440 | ant_conf->fast_div_bias = 0x1; | ||
1441 | ant_conf->main_gaintb = 0; | ||
1442 | ant_conf->alt_gaintb = 0; | ||
1443 | break; | ||
1444 | case 0x32: /* A+B LNA1 */ | ||
1445 | ant_conf->fast_div_bias = 0x1; | ||
1446 | ant_conf->main_gaintb = 0; | ||
1447 | ant_conf->alt_gaintb = 0; | ||
1448 | break; | ||
1449 | default: | ||
1450 | break; | ||
1451 | } | ||
1452 | } else if (ant_conf->div_group == 2) { | ||
1453 | /* Adjust the fast_div_bias based on main and alt_lna_conf */ | ||
1454 | switch ((ant_conf->main_lna_conf << 4) | | ||
1455 | ant_conf->alt_lna_conf) { | ||
1456 | case 0x01: /* A-B LNA2 */ | ||
1457 | ant_conf->fast_div_bias = 0x1; | ||
1458 | ant_conf->main_gaintb = 0; | ||
1459 | ant_conf->alt_gaintb = 0; | ||
1460 | break; | ||
1461 | case 0x02: /* A-B LNA1 */ | ||
1462 | ant_conf->fast_div_bias = 0x1; | ||
1463 | ant_conf->main_gaintb = 0; | ||
1464 | ant_conf->alt_gaintb = 0; | ||
1465 | break; | ||
1466 | case 0x03: /* A-B A+B */ | ||
1467 | ant_conf->fast_div_bias = 0x1; | ||
1468 | ant_conf->main_gaintb = 0; | ||
1469 | ant_conf->alt_gaintb = 0; | ||
1470 | break; | ||
1471 | case 0x10: /* LNA2 A-B */ | ||
1472 | if (!(antcomb->scan) && | ||
1473 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1474 | ant_conf->fast_div_bias = 0x1; | ||
1475 | else | ||
1476 | ant_conf->fast_div_bias = 0x2; | ||
1477 | ant_conf->main_gaintb = 0; | ||
1478 | ant_conf->alt_gaintb = 0; | ||
1479 | break; | ||
1480 | case 0x12: /* LNA2 LNA1 */ | ||
1481 | ant_conf->fast_div_bias = 0x1; | ||
1482 | ant_conf->main_gaintb = 0; | ||
1483 | ant_conf->alt_gaintb = 0; | ||
1484 | break; | ||
1485 | case 0x13: /* LNA2 A+B */ | ||
1486 | if (!(antcomb->scan) && | ||
1487 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1488 | ant_conf->fast_div_bias = 0x1; | ||
1489 | else | ||
1490 | ant_conf->fast_div_bias = 0x2; | ||
1491 | ant_conf->main_gaintb = 0; | ||
1492 | ant_conf->alt_gaintb = 0; | ||
1493 | break; | ||
1494 | case 0x20: /* LNA1 A-B */ | ||
1495 | if (!(antcomb->scan) && | ||
1496 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1497 | ant_conf->fast_div_bias = 0x1; | ||
1498 | else | ||
1499 | ant_conf->fast_div_bias = 0x2; | ||
1500 | ant_conf->main_gaintb = 0; | ||
1501 | ant_conf->alt_gaintb = 0; | ||
1502 | break; | ||
1503 | case 0x21: /* LNA1 LNA2 */ | ||
1504 | ant_conf->fast_div_bias = 0x1; | ||
1505 | ant_conf->main_gaintb = 0; | ||
1506 | ant_conf->alt_gaintb = 0; | ||
1507 | break; | ||
1508 | case 0x23: /* LNA1 A+B */ | ||
1509 | if (!(antcomb->scan) && | ||
1510 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1511 | ant_conf->fast_div_bias = 0x1; | ||
1512 | else | ||
1513 | ant_conf->fast_div_bias = 0x2; | ||
1514 | ant_conf->main_gaintb = 0; | ||
1515 | ant_conf->alt_gaintb = 0; | ||
1516 | break; | ||
1517 | case 0x30: /* A+B A-B */ | ||
1518 | ant_conf->fast_div_bias = 0x1; | ||
1519 | ant_conf->main_gaintb = 0; | ||
1520 | ant_conf->alt_gaintb = 0; | ||
1521 | break; | ||
1522 | case 0x31: /* A+B LNA2 */ | ||
1523 | ant_conf->fast_div_bias = 0x1; | ||
1524 | ant_conf->main_gaintb = 0; | ||
1525 | ant_conf->alt_gaintb = 0; | ||
1526 | break; | ||
1527 | case 0x32: /* A+B LNA1 */ | ||
1528 | ant_conf->fast_div_bias = 0x1; | ||
1529 | ant_conf->main_gaintb = 0; | ||
1530 | ant_conf->alt_gaintb = 0; | ||
1531 | break; | ||
1532 | default: | ||
1533 | break; | ||
1534 | } | ||
1535 | } | ||
1536 | } | ||
1537 | |||
1538 | /* Antenna diversity and combining */ | ||
1539 | static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs) | ||
1540 | { | ||
1541 | struct ath_hw_antcomb_conf div_ant_conf; | ||
1542 | struct ath_ant_comb *antcomb = &sc->ant_comb; | ||
1543 | int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set; | ||
1544 | int curr_main_set; | ||
1545 | int main_rssi = rs->rs_rssi_ctl0; | ||
1546 | int alt_rssi = rs->rs_rssi_ctl1; | ||
1547 | int rx_ant_conf, main_ant_conf; | ||
1548 | bool short_scan = false; | ||
1549 | |||
1550 | rx_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_CURRENT_SHIFT) & | ||
1551 | ATH_ANT_RX_MASK; | ||
1552 | main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) & | ||
1553 | ATH_ANT_RX_MASK; | ||
1554 | |||
1555 | /* Record packet only when both main_rssi and alt_rssi is positive */ | ||
1556 | if (main_rssi > 0 && alt_rssi > 0) { | ||
1557 | antcomb->total_pkt_count++; | ||
1558 | antcomb->main_total_rssi += main_rssi; | ||
1559 | antcomb->alt_total_rssi += alt_rssi; | ||
1560 | if (main_ant_conf == rx_ant_conf) | ||
1561 | antcomb->main_recv_cnt++; | ||
1562 | else | ||
1563 | antcomb->alt_recv_cnt++; | ||
1564 | } | ||
1565 | |||
1566 | /* Short scan check */ | ||
1567 | if (antcomb->scan && antcomb->alt_good) { | ||
1568 | if (time_after(jiffies, antcomb->scan_start_time + | ||
1569 | msecs_to_jiffies(ATH_ANT_DIV_COMB_SHORT_SCAN_INTR))) | ||
1570 | short_scan = true; | ||
1571 | else | ||
1572 | if (antcomb->total_pkt_count == | ||
1573 | ATH_ANT_DIV_COMB_SHORT_SCAN_PKTCOUNT) { | ||
1574 | alt_ratio = ((antcomb->alt_recv_cnt * 100) / | ||
1575 | antcomb->total_pkt_count); | ||
1576 | if (alt_ratio < ATH_ANT_DIV_COMB_ALT_ANT_RATIO) | ||
1577 | short_scan = true; | ||
1578 | } | ||
1579 | } | ||
1580 | |||
1581 | if (((antcomb->total_pkt_count < ATH_ANT_DIV_COMB_MAX_PKTCOUNT) || | ||
1582 | rs->rs_moreaggr) && !short_scan) | ||
1583 | return; | ||
1584 | |||
1585 | if (antcomb->total_pkt_count) { | ||
1586 | alt_ratio = ((antcomb->alt_recv_cnt * 100) / | ||
1587 | antcomb->total_pkt_count); | ||
1588 | main_rssi_avg = (antcomb->main_total_rssi / | ||
1589 | antcomb->total_pkt_count); | ||
1590 | alt_rssi_avg = (antcomb->alt_total_rssi / | ||
1591 | antcomb->total_pkt_count); | ||
1592 | } | ||
1593 | |||
1594 | |||
1595 | ath9k_hw_antdiv_comb_conf_get(sc->sc_ah, &div_ant_conf); | ||
1596 | curr_alt_set = div_ant_conf.alt_lna_conf; | ||
1597 | curr_main_set = div_ant_conf.main_lna_conf; | ||
1598 | |||
1599 | antcomb->count++; | ||
1600 | |||
1601 | if (antcomb->count == ATH_ANT_DIV_COMB_MAX_COUNT) { | ||
1602 | if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) { | ||
1603 | ath_lnaconf_alt_good_scan(antcomb, div_ant_conf, | ||
1604 | main_rssi_avg); | ||
1605 | antcomb->alt_good = true; | ||
1606 | } else { | ||
1607 | antcomb->alt_good = false; | ||
1608 | } | ||
1609 | |||
1610 | antcomb->count = 0; | ||
1611 | antcomb->scan = true; | ||
1612 | antcomb->scan_not_start = true; | ||
1613 | } | ||
1614 | |||
1615 | if (!antcomb->scan) { | ||
1616 | if (ath_ant_div_comb_alt_check(div_ant_conf.div_group, | ||
1617 | alt_ratio, curr_main_set, curr_alt_set, | ||
1618 | alt_rssi_avg, main_rssi_avg)) { | ||
1619 | if (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) { | ||
1620 | /* Switch main and alt LNA */ | ||
1621 | div_ant_conf.main_lna_conf = | ||
1622 | ATH_ANT_DIV_COMB_LNA2; | ||
1623 | div_ant_conf.alt_lna_conf = | ||
1624 | ATH_ANT_DIV_COMB_LNA1; | ||
1625 | } else if (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) { | ||
1626 | div_ant_conf.main_lna_conf = | ||
1627 | ATH_ANT_DIV_COMB_LNA1; | ||
1628 | div_ant_conf.alt_lna_conf = | ||
1629 | ATH_ANT_DIV_COMB_LNA2; | ||
1630 | } | ||
1631 | |||
1632 | goto div_comb_done; | ||
1633 | } else if ((curr_alt_set != ATH_ANT_DIV_COMB_LNA1) && | ||
1634 | (curr_alt_set != ATH_ANT_DIV_COMB_LNA2)) { | ||
1635 | /* Set alt to another LNA */ | ||
1636 | if (curr_main_set == ATH_ANT_DIV_COMB_LNA2) | ||
1637 | div_ant_conf.alt_lna_conf = | ||
1638 | ATH_ANT_DIV_COMB_LNA1; | ||
1639 | else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1) | ||
1640 | div_ant_conf.alt_lna_conf = | ||
1641 | ATH_ANT_DIV_COMB_LNA2; | ||
1642 | |||
1643 | goto div_comb_done; | ||
1644 | } | ||
1645 | |||
1646 | if ((alt_rssi_avg < (main_rssi_avg + | ||
1647 | div_ant_conf.lna1_lna2_delta))) | ||
1648 | goto div_comb_done; | ||
1649 | } | ||
1650 | |||
1651 | if (!antcomb->scan_not_start) { | ||
1652 | switch (curr_alt_set) { | ||
1653 | case ATH_ANT_DIV_COMB_LNA2: | ||
1654 | antcomb->rssi_lna2 = alt_rssi_avg; | ||
1655 | antcomb->rssi_lna1 = main_rssi_avg; | ||
1656 | antcomb->scan = true; | ||
1657 | /* set to A+B */ | ||
1658 | div_ant_conf.main_lna_conf = | ||
1659 | ATH_ANT_DIV_COMB_LNA1; | ||
1660 | div_ant_conf.alt_lna_conf = | ||
1661 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1662 | break; | ||
1663 | case ATH_ANT_DIV_COMB_LNA1: | ||
1664 | antcomb->rssi_lna1 = alt_rssi_avg; | ||
1665 | antcomb->rssi_lna2 = main_rssi_avg; | ||
1666 | antcomb->scan = true; | ||
1667 | /* set to A+B */ | ||
1668 | div_ant_conf.main_lna_conf = ATH_ANT_DIV_COMB_LNA2; | ||
1669 | div_ant_conf.alt_lna_conf = | ||
1670 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1671 | break; | ||
1672 | case ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2: | ||
1673 | antcomb->rssi_add = alt_rssi_avg; | ||
1674 | antcomb->scan = true; | ||
1675 | /* set to A-B */ | ||
1676 | div_ant_conf.alt_lna_conf = | ||
1677 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1678 | break; | ||
1679 | case ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2: | ||
1680 | antcomb->rssi_sub = alt_rssi_avg; | ||
1681 | antcomb->scan = false; | ||
1682 | if (antcomb->rssi_lna2 > | ||
1683 | (antcomb->rssi_lna1 + | ||
1684 | ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA)) { | ||
1685 | /* use LNA2 as main LNA */ | ||
1686 | if ((antcomb->rssi_add > antcomb->rssi_lna1) && | ||
1687 | (antcomb->rssi_add > antcomb->rssi_sub)) { | ||
1688 | /* set to A+B */ | ||
1689 | div_ant_conf.main_lna_conf = | ||
1690 | ATH_ANT_DIV_COMB_LNA2; | ||
1691 | div_ant_conf.alt_lna_conf = | ||
1692 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1693 | } else if (antcomb->rssi_sub > | ||
1694 | antcomb->rssi_lna1) { | ||
1695 | /* set to A-B */ | ||
1696 | div_ant_conf.main_lna_conf = | ||
1697 | ATH_ANT_DIV_COMB_LNA2; | ||
1698 | div_ant_conf.alt_lna_conf = | ||
1699 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1700 | } else { | ||
1701 | /* set to LNA1 */ | ||
1702 | div_ant_conf.main_lna_conf = | ||
1703 | ATH_ANT_DIV_COMB_LNA2; | ||
1704 | div_ant_conf.alt_lna_conf = | ||
1705 | ATH_ANT_DIV_COMB_LNA1; | ||
1706 | } | ||
1707 | } else { | ||
1708 | /* use LNA1 as main LNA */ | ||
1709 | if ((antcomb->rssi_add > antcomb->rssi_lna2) && | ||
1710 | (antcomb->rssi_add > antcomb->rssi_sub)) { | ||
1711 | /* set to A+B */ | ||
1712 | div_ant_conf.main_lna_conf = | ||
1713 | ATH_ANT_DIV_COMB_LNA1; | ||
1714 | div_ant_conf.alt_lna_conf = | ||
1715 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1716 | } else if (antcomb->rssi_sub > | ||
1717 | antcomb->rssi_lna1) { | ||
1718 | /* set to A-B */ | ||
1719 | div_ant_conf.main_lna_conf = | ||
1720 | ATH_ANT_DIV_COMB_LNA1; | ||
1721 | div_ant_conf.alt_lna_conf = | ||
1722 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1723 | } else { | ||
1724 | /* set to LNA2 */ | ||
1725 | div_ant_conf.main_lna_conf = | ||
1726 | ATH_ANT_DIV_COMB_LNA1; | ||
1727 | div_ant_conf.alt_lna_conf = | ||
1728 | ATH_ANT_DIV_COMB_LNA2; | ||
1729 | } | ||
1730 | } | ||
1731 | break; | ||
1732 | default: | ||
1733 | break; | ||
1734 | } | ||
1735 | } else { | ||
1736 | if (!antcomb->alt_good) { | ||
1737 | antcomb->scan_not_start = false; | ||
1738 | /* Set alt to another LNA */ | ||
1739 | if (curr_main_set == ATH_ANT_DIV_COMB_LNA2) { | ||
1740 | div_ant_conf.main_lna_conf = | ||
1741 | ATH_ANT_DIV_COMB_LNA2; | ||
1742 | div_ant_conf.alt_lna_conf = | ||
1743 | ATH_ANT_DIV_COMB_LNA1; | ||
1744 | } else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1) { | ||
1745 | div_ant_conf.main_lna_conf = | ||
1746 | ATH_ANT_DIV_COMB_LNA1; | ||
1747 | div_ant_conf.alt_lna_conf = | ||
1748 | ATH_ANT_DIV_COMB_LNA2; | ||
1749 | } | ||
1750 | goto div_comb_done; | ||
1751 | } | ||
1752 | } | ||
1753 | |||
1754 | ath_select_ant_div_from_quick_scan(antcomb, &div_ant_conf, | ||
1755 | main_rssi_avg, alt_rssi_avg, | ||
1756 | alt_ratio); | ||
1757 | |||
1758 | antcomb->quick_scan_cnt++; | ||
1759 | |||
1760 | div_comb_done: | ||
1761 | ath_ant_div_conf_fast_divbias(&div_ant_conf, antcomb, alt_ratio); | ||
1762 | ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf); | ||
1763 | |||
1764 | antcomb->scan_start_time = jiffies; | ||
1765 | antcomb->total_pkt_count = 0; | ||
1766 | antcomb->main_total_rssi = 0; | ||
1767 | antcomb->alt_total_rssi = 0; | ||
1768 | antcomb->main_recv_cnt = 0; | ||
1769 | antcomb->alt_recv_cnt = 0; | ||
1770 | } | ||
1771 | |||
1772 | int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | 1033 | int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) |
1773 | { | 1034 | { |
1774 | struct ath_buf *bf; | 1035 | struct ath_buf *bf; |
@@ -1802,7 +1063,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1802 | 1063 | ||
1803 | do { | 1064 | do { |
1804 | /* If handling rx interrupt and flush is in progress => exit */ | 1065 | /* If handling rx interrupt and flush is in progress => exit */ |
1805 | if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0)) | 1066 | if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags) && (flush == 0)) |
1806 | break; | 1067 | break; |
1807 | 1068 | ||
1808 | memset(&rs, 0, sizeof(rs)); | 1069 | memset(&rs, 0, sizeof(rs)); |
@@ -1832,7 +1093,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1832 | if (ieee80211_is_beacon(hdr->frame_control)) { | 1093 | if (ieee80211_is_beacon(hdr->frame_control)) { |
1833 | RX_STAT_INC(rx_beacons); | 1094 | RX_STAT_INC(rx_beacons); |
1834 | if (!is_zero_ether_addr(common->curbssid) && | 1095 | if (!is_zero_ether_addr(common->curbssid) && |
1835 | !compare_ether_addr(hdr->addr3, common->curbssid)) | 1096 | ether_addr_equal(hdr->addr3, common->curbssid)) |
1836 | rs.is_mybeacon = true; | 1097 | rs.is_mybeacon = true; |
1837 | else | 1098 | else |
1838 | rs.is_mybeacon = false; | 1099 | rs.is_mybeacon = false; |
@@ -1840,13 +1101,14 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1840 | else | 1101 | else |
1841 | rs.is_mybeacon = false; | 1102 | rs.is_mybeacon = false; |
1842 | 1103 | ||
1104 | sc->rx.num_pkts++; | ||
1843 | ath_debug_stat_rx(sc, &rs); | 1105 | ath_debug_stat_rx(sc, &rs); |
1844 | 1106 | ||
1845 | /* | 1107 | /* |
1846 | * If we're asked to flush receive queue, directly | 1108 | * If we're asked to flush receive queue, directly |
1847 | * chain it back at the queue without processing it. | 1109 | * chain it back at the queue without processing it. |
1848 | */ | 1110 | */ |
1849 | if (sc->sc_flags & SC_OP_RXFLUSH) { | 1111 | if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags)) { |
1850 | RX_STAT_INC(rx_drop_rxflush); | 1112 | RX_STAT_INC(rx_drop_rxflush); |
1851 | goto requeue_drop_frag; | 1113 | goto requeue_drop_frag; |
1852 | } | 1114 | } |
@@ -1967,7 +1229,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1967 | skb_trim(skb, skb->len - 8); | 1229 | skb_trim(skb, skb->len - 8); |
1968 | 1230 | ||
1969 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | 1231 | spin_lock_irqsave(&sc->sc_pm_lock, flags); |
1970 | |||
1971 | if ((sc->ps_flags & (PS_WAIT_FOR_BEACON | | 1232 | if ((sc->ps_flags & (PS_WAIT_FOR_BEACON | |
1972 | PS_WAIT_FOR_CAB | | 1233 | PS_WAIT_FOR_CAB | |
1973 | PS_WAIT_FOR_PSPOLL_DATA)) || | 1234 | PS_WAIT_FOR_PSPOLL_DATA)) || |
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 458f81b4a7cb..75acefbd4937 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -2098,8 +2098,8 @@ enum { | |||
2098 | #define AR_MCI_CONT_STATUS 0x1848 | 2098 | #define AR_MCI_CONT_STATUS 0x1848 |
2099 | #define AR_MCI_CONT_RSSI_POWER 0x000000FF | 2099 | #define AR_MCI_CONT_RSSI_POWER 0x000000FF |
2100 | #define AR_MCI_CONT_RSSI_POWER_S 0 | 2100 | #define AR_MCI_CONT_RSSI_POWER_S 0 |
2101 | #define AR_MCI_CONT_RRIORITY 0x0000FF00 | 2101 | #define AR_MCI_CONT_PRIORITY 0x0000FF00 |
2102 | #define AR_MCI_CONT_RRIORITY_S 8 | 2102 | #define AR_MCI_CONT_PRIORITY_S 8 |
2103 | #define AR_MCI_CONT_TXRX 0x00010000 | 2103 | #define AR_MCI_CONT_TXRX 0x00010000 |
2104 | #define AR_MCI_CONT_TXRX_S 16 | 2104 | #define AR_MCI_CONT_TXRX_S 16 |
2105 | 2105 | ||
@@ -2211,5 +2211,7 @@ enum { | |||
2211 | #define AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT 0x00000fff | 2211 | #define AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT 0x00000fff |
2212 | #define AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT_S 0 | 2212 | #define AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT_S 0 |
2213 | 2213 | ||
2214 | #define AR_GLB_SWREG_DISCONT_MODE 0x2002c | ||
2215 | #define AR_GLB_SWREG_DISCONT_EN_BT_WLAN 0x3 | ||
2214 | 2216 | ||
2215 | #endif | 2217 | #endif |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 834e6bc45e8b..f777ddcd1172 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -64,7 +64,8 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, | |||
64 | static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, | 64 | static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, |
65 | struct ath_txq *txq, | 65 | struct ath_txq *txq, |
66 | struct ath_atx_tid *tid, | 66 | struct ath_atx_tid *tid, |
67 | struct sk_buff *skb); | 67 | struct sk_buff *skb, |
68 | bool dequeue); | ||
68 | 69 | ||
69 | enum { | 70 | enum { |
70 | MCS_HT20, | 71 | MCS_HT20, |
@@ -104,19 +105,19 @@ static int ath_max_4ms_framelen[4][32] = { | |||
104 | /* Aggregation logic */ | 105 | /* Aggregation logic */ |
105 | /*********************/ | 106 | /*********************/ |
106 | 107 | ||
107 | static void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq) | 108 | void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq) |
108 | __acquires(&txq->axq_lock) | 109 | __acquires(&txq->axq_lock) |
109 | { | 110 | { |
110 | spin_lock_bh(&txq->axq_lock); | 111 | spin_lock_bh(&txq->axq_lock); |
111 | } | 112 | } |
112 | 113 | ||
113 | static void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq) | 114 | void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq) |
114 | __releases(&txq->axq_lock) | 115 | __releases(&txq->axq_lock) |
115 | { | 116 | { |
116 | spin_unlock_bh(&txq->axq_lock); | 117 | spin_unlock_bh(&txq->axq_lock); |
117 | } | 118 | } |
118 | 119 | ||
119 | static void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq) | 120 | void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq) |
120 | __releases(&txq->axq_lock) | 121 | __releases(&txq->axq_lock) |
121 | { | 122 | { |
122 | struct sk_buff_head q; | 123 | struct sk_buff_head q; |
@@ -811,7 +812,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | |||
811 | fi = get_frame_info(skb); | 812 | fi = get_frame_info(skb); |
812 | bf = fi->bf; | 813 | bf = fi->bf; |
813 | if (!fi->bf) | 814 | if (!fi->bf) |
814 | bf = ath_tx_setup_buffer(sc, txq, tid, skb); | 815 | bf = ath_tx_setup_buffer(sc, txq, tid, skb, true); |
815 | 816 | ||
816 | if (!bf) | 817 | if (!bf) |
817 | continue; | 818 | continue; |
@@ -1535,7 +1536,7 @@ bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | |||
1535 | int i; | 1536 | int i; |
1536 | u32 npend = 0; | 1537 | u32 npend = 0; |
1537 | 1538 | ||
1538 | if (sc->sc_flags & SC_OP_INVALID) | 1539 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) |
1539 | return true; | 1540 | return true; |
1540 | 1541 | ||
1541 | ath9k_hw_abort_tx_dma(ah); | 1542 | ath9k_hw_abort_tx_dma(ah); |
@@ -1726,7 +1727,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, | |||
1726 | return; | 1727 | return; |
1727 | } | 1728 | } |
1728 | 1729 | ||
1729 | bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb); | 1730 | bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false); |
1730 | if (!bf) | 1731 | if (!bf) |
1731 | return; | 1732 | return; |
1732 | 1733 | ||
@@ -1753,7 +1754,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, | |||
1753 | 1754 | ||
1754 | bf = fi->bf; | 1755 | bf = fi->bf; |
1755 | if (!bf) | 1756 | if (!bf) |
1756 | bf = ath_tx_setup_buffer(sc, txq, tid, skb); | 1757 | bf = ath_tx_setup_buffer(sc, txq, tid, skb, false); |
1757 | 1758 | ||
1758 | if (!bf) | 1759 | if (!bf) |
1759 | return; | 1760 | return; |
@@ -1814,12 +1815,14 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate) | |||
1814 | static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, | 1815 | static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, |
1815 | struct ath_txq *txq, | 1816 | struct ath_txq *txq, |
1816 | struct ath_atx_tid *tid, | 1817 | struct ath_atx_tid *tid, |
1817 | struct sk_buff *skb) | 1818 | struct sk_buff *skb, |
1819 | bool dequeue) | ||
1818 | { | 1820 | { |
1819 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1821 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1820 | struct ath_frame_info *fi = get_frame_info(skb); | 1822 | struct ath_frame_info *fi = get_frame_info(skb); |
1821 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1823 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1822 | struct ath_buf *bf; | 1824 | struct ath_buf *bf; |
1825 | int fragno; | ||
1823 | u16 seqno; | 1826 | u16 seqno; |
1824 | 1827 | ||
1825 | bf = ath_tx_get_buffer(sc); | 1828 | bf = ath_tx_get_buffer(sc); |
@@ -1831,9 +1834,16 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, | |||
1831 | ATH_TXBUF_RESET(bf); | 1834 | ATH_TXBUF_RESET(bf); |
1832 | 1835 | ||
1833 | if (tid) { | 1836 | if (tid) { |
1837 | fragno = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; | ||
1834 | seqno = tid->seq_next; | 1838 | seqno = tid->seq_next; |
1835 | hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); | 1839 | hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); |
1836 | INCR(tid->seq_next, IEEE80211_SEQ_MAX); | 1840 | |
1841 | if (fragno) | ||
1842 | hdr->seq_ctrl |= cpu_to_le16(fragno); | ||
1843 | |||
1844 | if (!ieee80211_has_morefrags(hdr->frame_control)) | ||
1845 | INCR(tid->seq_next, IEEE80211_SEQ_MAX); | ||
1846 | |||
1837 | bf->bf_state.seqno = seqno; | 1847 | bf->bf_state.seqno = seqno; |
1838 | } | 1848 | } |
1839 | 1849 | ||
@@ -1855,6 +1865,8 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, | |||
1855 | return bf; | 1865 | return bf; |
1856 | 1866 | ||
1857 | error: | 1867 | error: |
1868 | if (dequeue) | ||
1869 | __skb_unlink(skb, &tid->buf_q); | ||
1858 | dev_kfree_skb_any(skb); | 1870 | dev_kfree_skb_any(skb); |
1859 | return NULL; | 1871 | return NULL; |
1860 | } | 1872 | } |
@@ -1885,7 +1897,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb, | |||
1885 | */ | 1897 | */ |
1886 | ath_tx_send_ampdu(sc, tid, skb, txctl); | 1898 | ath_tx_send_ampdu(sc, tid, skb, txctl); |
1887 | } else { | 1899 | } else { |
1888 | bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb); | 1900 | bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false); |
1889 | if (!bf) | 1901 | if (!bf) |
1890 | return; | 1902 | return; |
1891 | 1903 | ||
@@ -1982,6 +1994,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
1982 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1994 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1983 | struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; | 1995 | struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; |
1984 | int q, padpos, padsize; | 1996 | int q, padpos, padsize; |
1997 | unsigned long flags; | ||
1985 | 1998 | ||
1986 | ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb); | 1999 | ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb); |
1987 | 2000 | ||
@@ -2000,6 +2013,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
2000 | skb_pull(skb, padsize); | 2013 | skb_pull(skb, padsize); |
2001 | } | 2014 | } |
2002 | 2015 | ||
2016 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | ||
2003 | if ((sc->ps_flags & PS_WAIT_FOR_TX_ACK) && !txq->axq_depth) { | 2017 | if ((sc->ps_flags & PS_WAIT_FOR_TX_ACK) && !txq->axq_depth) { |
2004 | sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK; | 2018 | sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK; |
2005 | ath_dbg(common, PS, | 2019 | ath_dbg(common, PS, |
@@ -2009,6 +2023,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
2009 | PS_WAIT_FOR_PSPOLL_DATA | | 2023 | PS_WAIT_FOR_PSPOLL_DATA | |
2010 | PS_WAIT_FOR_TX_ACK)); | 2024 | PS_WAIT_FOR_TX_ACK)); |
2011 | } | 2025 | } |
2026 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | ||
2012 | 2027 | ||
2013 | q = skb_get_queue_mapping(skb); | 2028 | q = skb_get_queue_mapping(skb); |
2014 | if (txq == sc->tx.txq_map[q]) { | 2029 | if (txq == sc->tx.txq_map[q]) { |
@@ -2219,46 +2234,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2219 | ath_txq_unlock_complete(sc, txq); | 2234 | ath_txq_unlock_complete(sc, txq); |
2220 | } | 2235 | } |
2221 | 2236 | ||
2222 | static void ath_tx_complete_poll_work(struct work_struct *work) | ||
2223 | { | ||
2224 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
2225 | tx_complete_work.work); | ||
2226 | struct ath_txq *txq; | ||
2227 | int i; | ||
2228 | bool needreset = false; | ||
2229 | #ifdef CONFIG_ATH9K_DEBUGFS | ||
2230 | sc->tx_complete_poll_work_seen++; | ||
2231 | #endif | ||
2232 | |||
2233 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | ||
2234 | if (ATH_TXQ_SETUP(sc, i)) { | ||
2235 | txq = &sc->tx.txq[i]; | ||
2236 | ath_txq_lock(sc, txq); | ||
2237 | if (txq->axq_depth) { | ||
2238 | if (txq->axq_tx_inprogress) { | ||
2239 | needreset = true; | ||
2240 | ath_txq_unlock(sc, txq); | ||
2241 | break; | ||
2242 | } else { | ||
2243 | txq->axq_tx_inprogress = true; | ||
2244 | } | ||
2245 | } | ||
2246 | ath_txq_unlock_complete(sc, txq); | ||
2247 | } | ||
2248 | |||
2249 | if (needreset) { | ||
2250 | ath_dbg(ath9k_hw_common(sc->sc_ah), RESET, | ||
2251 | "tx hung, resetting the chip\n"); | ||
2252 | RESET_STAT_INC(sc, RESET_TYPE_TX_HANG); | ||
2253 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | ||
2254 | } | ||
2255 | |||
2256 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, | ||
2257 | msecs_to_jiffies(ATH_TX_COMPLETE_POLL_INT)); | ||
2258 | } | ||
2259 | |||
2260 | |||
2261 | |||
2262 | void ath_tx_tasklet(struct ath_softc *sc) | 2237 | void ath_tx_tasklet(struct ath_softc *sc) |
2263 | { | 2238 | { |
2264 | struct ath_hw *ah = sc->sc_ah; | 2239 | struct ath_hw *ah = sc->sc_ah; |
diff --git a/drivers/net/wireless/ath/carl9170/debug.c b/drivers/net/wireless/ath/carl9170/debug.c index 3c164226687f..93fe6003a493 100644 --- a/drivers/net/wireless/ath/carl9170/debug.c +++ b/drivers/net/wireless/ath/carl9170/debug.c | |||
@@ -48,11 +48,6 @@ | |||
48 | #define ADD(buf, off, max, fmt, args...) \ | 48 | #define ADD(buf, off, max, fmt, args...) \ |
49 | off += snprintf(&buf[off], max - off, fmt, ##args); | 49 | off += snprintf(&buf[off], max - off, fmt, ##args); |
50 | 50 | ||
51 | static int carl9170_debugfs_open(struct inode *inode, struct file *file) | ||
52 | { | ||
53 | file->private_data = inode->i_private; | ||
54 | return 0; | ||
55 | } | ||
56 | 51 | ||
57 | struct carl9170_debugfs_fops { | 52 | struct carl9170_debugfs_fops { |
58 | unsigned int read_bufsize; | 53 | unsigned int read_bufsize; |
@@ -178,7 +173,7 @@ static const struct carl9170_debugfs_fops carl_debugfs_##name ##_ops = {\ | |||
178 | .attr = _attr, \ | 173 | .attr = _attr, \ |
179 | .req_dev_state = _dstate, \ | 174 | .req_dev_state = _dstate, \ |
180 | .fops = { \ | 175 | .fops = { \ |
181 | .open = carl9170_debugfs_open, \ | 176 | .open = simple_open, \ |
182 | .read = carl9170_debugfs_read, \ | 177 | .read = carl9170_debugfs_read, \ |
183 | .write = carl9170_debugfs_write, \ | 178 | .write = carl9170_debugfs_write, \ |
184 | .owner = THIS_MODULE \ | 179 | .owner = THIS_MODULE \ |
diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c index dc99030ea8b6..84b22eec7abd 100644 --- a/drivers/net/wireless/ath/carl9170/rx.c +++ b/drivers/net/wireless/ath/carl9170/rx.c | |||
@@ -538,7 +538,7 @@ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len) | |||
538 | return; | 538 | return; |
539 | 539 | ||
540 | /* and only beacons from the associated BSSID, please */ | 540 | /* and only beacons from the associated BSSID, please */ |
541 | if (compare_ether_addr(hdr->addr3, ar->common.curbssid) || | 541 | if (!ether_addr_equal(hdr->addr3, ar->common.curbssid) || |
542 | !ar->common.curaid) | 542 | !ar->common.curaid) |
543 | return; | 543 | return; |
544 | 544 | ||
diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c index 89821e4835c7..888152ce3eca 100644 --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c | |||
@@ -1159,6 +1159,7 @@ static struct usb_driver carl9170_driver = { | |||
1159 | .resume = carl9170_usb_resume, | 1159 | .resume = carl9170_usb_resume, |
1160 | .reset_resume = carl9170_usb_resume, | 1160 | .reset_resume = carl9170_usb_resume, |
1161 | #endif /* CONFIG_PM */ | 1161 | #endif /* CONFIG_PM */ |
1162 | .disable_hub_initiated_lpm = 1, | ||
1162 | }; | 1163 | }; |
1163 | 1164 | ||
1164 | module_usb_driver(carl9170_driver); | 1165 | module_usb_driver(carl9170_driver); |