aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mci.c142
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c129
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h10
3 files changed, 163 insertions, 118 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c
index 65db2cd44c9a..597e707a0c73 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c
@@ -16,6 +16,7 @@
16 16
17#include <linux/export.h> 17#include <linux/export.h>
18#include "hw.h" 18#include "hw.h"
19#include "hw-ops.h"
19#include "ar9003_phy.h" 20#include "ar9003_phy.h"
20#include "ar9003_mci.h" 21#include "ar9003_mci.h"
21 22
@@ -567,6 +568,131 @@ static bool ar9003_mci_send_coex_bt_flags(struct ath_hw *ah, bool wait_done,
567 wait_done, true); 568 wait_done, true);
568} 569}
569 570
571void ar9003_mci_check_bt(struct ath_hw *ah)
572{
573 struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
574
575 if (!mci_hw->ready)
576 return;
577
578 /*
579 * check BT state again to make
580 * sure it's not changed.
581 */
582 ar9003_mci_sync_bt_state(ah);
583 ar9003_mci_2g5g_switch(ah, true);
584
585 if ((mci_hw->bt_state == MCI_BT_AWAKE) &&
586 (mci_hw->query_bt == true)) {
587 mci_hw->need_flush_btinfo = true;
588 }
589}
590
591bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan)
592{
593 struct ath_common *common = ath9k_hw_common(ah);
594 struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
595 u32 payload[4] = {0, 0, 0, 0};
596
597 ar9003_mci_2g5g_changed(ah, IS_CHAN_2GHZ(chan));
598
599 if (mci_hw->bt_state != MCI_BT_CAL_START)
600 return false;
601
602 ath_dbg(common, MCI, "MCI stop rx for BT CAL\n");
603
604 mci_hw->bt_state = MCI_BT_CAL;
605
606 /*
607 * MCI FIX: disable mci interrupt here. This is to avoid
608 * SW_MSG_DONE or RX_MSG bits to trigger MCI_INT and
609 * lead to mci_intr reentry.
610 */
611
612 ar9003_mci_disable_interrupt(ah);
613
614 ath_dbg(common, MCI, "send WLAN_CAL_GRANT\n");
615
616 MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_GRANT);
617 ar9003_mci_send_message(ah, MCI_GPM, 0, payload,
618 16, true, false);
619
620 ath_dbg(common, MCI, "\nMCI BT is calibrating\n");
621
622 /* Wait BT calibration to be completed for 25ms */
623
624 if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_DONE,
625 0, 25000))
626 ath_dbg(common, MCI,
627 "MCI got BT_CAL_DONE\n");
628 else
629 ath_dbg(common, MCI,
630 "MCI ### BT cal takes to long, force bt_state to be bt_awake\n");
631
632 mci_hw->bt_state = MCI_BT_AWAKE;
633 /* MCI FIX: enable mci interrupt here */
634 ar9003_mci_enable_interrupt(ah);
635
636 return true;
637}
638
639int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan,
640 struct ath9k_hw_cal_data *caldata)
641{
642 struct ath_common *common = ath9k_hw_common(ah);
643 struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
644
645 if (!mci_hw->ready)
646 return 0;
647
648 if (!IS_CHAN_2GHZ(chan) || (mci_hw->bt_state != MCI_BT_SLEEP))
649 goto exit;
650
651 if (ar9003_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET) ||
652 ar9003_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)) {
653
654 /*
655 * BT is sleeping. Check if BT wakes up during
656 * WLAN calibration. If BT wakes up during
657 * WLAN calibration, need to go through all
658 * message exchanges again and recal.
659 */
660
661 ath_dbg(common, MCI,
662 "MCI BT wakes up during WLAN calibration\n");
663
664 REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
665 AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET |
666 AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE);
667
668 ath_dbg(common, MCI, "MCI send REMOTE_RESET\n");
669
670 ar9003_mci_remote_reset(ah, true);
671 ar9003_mci_send_sys_waking(ah, true);
672 udelay(1);
673
674 if (IS_CHAN_2GHZ(chan))
675 ar9003_mci_send_lna_transfer(ah, true);
676
677 mci_hw->bt_state = MCI_BT_AWAKE;
678
679 ath_dbg(common, MCI, "MCI re-cal\n");
680
681 if (caldata) {
682 caldata->done_txiqcal_once = false;
683 caldata->done_txclcal_once = false;
684 caldata->rtt_hist.num_readings = 0;
685 }
686
687 if (!ath9k_hw_init_cal(ah, chan))
688 return -EIO;
689
690 }
691exit:
692 ar9003_mci_enable_interrupt(ah);
693 return 0;
694}
695
570void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, 696void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
571 bool is_full_sleep) 697 bool is_full_sleep)
572{ 698{
@@ -696,6 +822,22 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
696 ar9003_mci_enable_interrupt(ah); 822 ar9003_mci_enable_interrupt(ah);
697} 823}
698 824
825void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep)
826{
827 struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
828
829 ar9003_mci_disable_interrupt(ah);
830
831 if (mci_hw->ready && !save_fullsleep) {
832 ar9003_mci_mute_bt(ah);
833 udelay(20);
834 REG_WRITE(ah, AR_BTCOEX_CTRL, 0);
835 }
836
837 mci_hw->bt_state = MCI_BT_SLEEP;
838 mci_hw->ready = false;
839}
840
699void ar9003_mci_mute_bt(struct ath_hw *ah) 841void ar9003_mci_mute_bt(struct ath_hw *ah)
700{ 842{
701 struct ath_common *common = ath9k_hw_common(ah); 843 struct ath_common *common = ath9k_hw_common(ah);
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 406ffd06b6db..475e4caee776 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1518,61 +1518,22 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1518 struct ath9k_hw_cal_data *caldata, bool bChannelChange) 1518 struct ath9k_hw_cal_data *caldata, bool bChannelChange)
1519{ 1519{
1520 struct ath_common *common = ath9k_hw_common(ah); 1520 struct ath_common *common = ath9k_hw_common(ah);
1521 struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
1522 u32 saveLedState; 1521 u32 saveLedState;
1523 struct ath9k_channel *curchan = ah->curchan; 1522 struct ath9k_channel *curchan = ah->curchan;
1524 u32 saveDefAntenna; 1523 u32 saveDefAntenna;
1525 u32 macStaId1; 1524 u32 macStaId1;
1526 u64 tsf = 0; 1525 u64 tsf = 0;
1527 int i, r; 1526 int i, r;
1528 bool allow_fbs = false; 1527 bool allow_fbs = false, start_mci_reset = false;
1529 bool mci = !!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI); 1528 bool mci = !!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI);
1530 bool save_fullsleep = ah->chip_fullsleep; 1529 bool save_fullsleep = ah->chip_fullsleep;
1531 1530
1532 if (mci) { 1531 if (mci) {
1533 1532 start_mci_reset = ar9003_mci_start_reset(ah, chan);
1534 ar9003_mci_2g5g_changed(ah, IS_CHAN_2GHZ(chan)); 1533 if (start_mci_reset)
1535 1534 return 0;
1536 if (mci_hw->bt_state == MCI_BT_CAL_START) {
1537 u32 payload[4] = {0, 0, 0, 0};
1538
1539 ath_dbg(common, MCI, "MCI stop rx for BT CAL\n");
1540
1541 mci_hw->bt_state = MCI_BT_CAL;
1542
1543 /*
1544 * MCI FIX: disable mci interrupt here. This is to avoid
1545 * SW_MSG_DONE or RX_MSG bits to trigger MCI_INT and
1546 * lead to mci_intr reentry.
1547 */
1548
1549 ar9003_mci_disable_interrupt(ah);
1550
1551 ath_dbg(common, MCI, "send WLAN_CAL_GRANT\n");
1552 MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_GRANT);
1553 ar9003_mci_send_message(ah, MCI_GPM, 0, payload,
1554 16, true, false);
1555
1556 ath_dbg(common, MCI, "\nMCI BT is calibrating\n");
1557
1558 /* Wait BT calibration to be completed for 25ms */
1559
1560 if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_DONE,
1561 0, 25000))
1562 ath_dbg(common, MCI,
1563 "MCI got BT_CAL_DONE\n");
1564 else
1565 ath_dbg(common, MCI,
1566 "MCI ### BT cal takes to long, force bt_state to be bt_awake\n");
1567 mci_hw->bt_state = MCI_BT_AWAKE;
1568 /* MCI FIX: enable mci interrupt here */
1569 ar9003_mci_enable_interrupt(ah);
1570
1571 return true;
1572 }
1573 } 1535 }
1574 1536
1575
1576 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) 1537 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
1577 return -EIO; 1538 return -EIO;
1578 1539
@@ -1609,7 +1570,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1609 if (ath9k_hw_channel_change(ah, chan)) { 1570 if (ath9k_hw_channel_change(ah, chan)) {
1610 ath9k_hw_loadnf(ah, ah->curchan); 1571 ath9k_hw_loadnf(ah, ah->curchan);
1611 ath9k_hw_start_nfcal(ah, true); 1572 ath9k_hw_start_nfcal(ah, true);
1612 if (mci && mci_hw->ready) 1573 if (mci && ar9003_mci_is_ready(ah))
1613 ar9003_mci_2g5g_switch(ah, true); 1574 ar9003_mci_2g5g_switch(ah, true);
1614 1575
1615 if (AR_SREV_9271(ah)) 1576 if (AR_SREV_9271(ah))
@@ -1618,19 +1579,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1618 } 1579 }
1619 } 1580 }
1620 1581
1621 if (mci) { 1582 if (mci)
1622 ar9003_mci_disable_interrupt(ah); 1583 ar9003_mci_stop_bt(ah, save_fullsleep);
1623
1624 if (mci_hw->ready && !save_fullsleep) {
1625 ar9003_mci_mute_bt(ah);
1626 udelay(20);
1627 REG_WRITE(ah, AR_BTCOEX_CTRL, 0);
1628 }
1629
1630 mci_hw->bt_state = MCI_BT_SLEEP;
1631 mci_hw->ready = false;
1632 }
1633
1634 1584
1635 saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA); 1585 saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA);
1636 if (saveDefAntenna == 0) 1586 if (saveDefAntenna == 0)
@@ -1807,53 +1757,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1807 ath9k_hw_loadnf(ah, chan); 1757 ath9k_hw_loadnf(ah, chan);
1808 ath9k_hw_start_nfcal(ah, true); 1758 ath9k_hw_start_nfcal(ah, true);
1809 1759
1810 if (mci && mci_hw->ready) { 1760 if (mci && ar9003_mci_end_reset(ah, chan, caldata))
1811 1761 return -EIO;
1812 if (IS_CHAN_2GHZ(chan) &&
1813 (mci_hw->bt_state == MCI_BT_SLEEP)) {
1814
1815 if (ar9003_mci_check_int(ah,
1816 AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET) ||
1817 ar9003_mci_check_int(ah,
1818 AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)) {
1819
1820 /*
1821 * BT is sleeping. Check if BT wakes up during
1822 * WLAN calibration. If BT wakes up during
1823 * WLAN calibration, need to go through all
1824 * message exchanges again and recal.
1825 */
1826
1827 ath_dbg(common, MCI,
1828 "MCI BT wakes up during WLAN calibration\n");
1829
1830 REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
1831 AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET |
1832 AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE);
1833 ath_dbg(common, MCI, "MCI send REMOTE_RESET\n");
1834 ar9003_mci_remote_reset(ah, true);
1835 ar9003_mci_send_sys_waking(ah, true);
1836 udelay(1);
1837 if (IS_CHAN_2GHZ(chan))
1838 ar9003_mci_send_lna_transfer(ah, true);
1839
1840 mci_hw->bt_state = MCI_BT_AWAKE;
1841
1842 ath_dbg(common, MCI, "MCI re-cal\n");
1843
1844 if (caldata) {
1845 caldata->done_txiqcal_once = false;
1846 caldata->done_txclcal_once = false;
1847 caldata->rtt_hist.num_readings = 0;
1848 }
1849
1850 if (!ath9k_hw_init_cal(ah, chan))
1851 return -EIO;
1852
1853 }
1854 }
1855 ar9003_mci_enable_interrupt(ah);
1856 }
1857 1762
1858 ENABLE_REGWRITE_BUFFER(ah); 1763 ENABLE_REGWRITE_BUFFER(ah);
1859 1764
@@ -1898,20 +1803,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1898 ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) 1803 ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE)
1899 ath9k_hw_btcoex_enable(ah); 1804 ath9k_hw_btcoex_enable(ah);
1900 1805
1901 if (mci && mci_hw->ready) { 1806 if (mci)
1902 /* 1807 ar9003_mci_check_bt(ah);
1903 * check BT state again to make
1904 * sure it's not changed.
1905 */
1906
1907 ar9003_mci_sync_bt_state(ah);
1908 ar9003_mci_2g5g_switch(ah, true);
1909
1910 if ((mci_hw->bt_state == MCI_BT_AWAKE) &&
1911 (mci_hw->query_bt == true)) {
1912 mci_hw->need_flush_btinfo = true;
1913 }
1914 }
1915 1808
1916 if (AR_SREV_9300_20_OR_LATER(ah)) { 1809 if (AR_SREV_9300_20_OR_LATER(ah)) {
1917 ar9003_hw_bb_watchdog_config(ah); 1810 ar9003_hw_bb_watchdog_config(ah);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index ff752546354f..0d108dc25c57 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -1209,6 +1209,7 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan);
1209bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag, 1209bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag,
1210 u32 *payload, u8 len, bool wait_done, 1210 u32 *payload, u8 len, bool wait_done,
1211 bool check_bt); 1211 bool check_bt);
1212void ar9003_mci_stop_bt(struct ath_hw *ah, bool sava_fullsleep);
1212void ar9003_mci_mute_bt(struct ath_hw *ah); 1213void ar9003_mci_mute_bt(struct ath_hw *ah);
1213u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data); 1214u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data);
1214void ar9003_mci_init_cal_req(struct ath_hw *ah, bool *is_reusable); 1215void ar9003_mci_init_cal_req(struct ath_hw *ah, bool *is_reusable);
@@ -1225,6 +1226,10 @@ void ar9003_mci_set_full_sleep(struct ath_hw *ah);
1225void ar9003_mci_disable_interrupt(struct ath_hw *ah); 1226void ar9003_mci_disable_interrupt(struct ath_hw *ah);
1226void ar9003_mci_enable_interrupt(struct ath_hw *ah); 1227void ar9003_mci_enable_interrupt(struct ath_hw *ah);
1227void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done); 1228void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done);
1229void ar9003_mci_check_bt(struct ath_hw *ah);
1230bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan);
1231int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1232 struct ath9k_hw_cal_data *caldata);
1228void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, 1233void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
1229 bool is_full_sleep); 1234 bool is_full_sleep);
1230bool ar9003_mci_check_int(struct ath_hw *ah, u32 ints); 1235bool ar9003_mci_check_int(struct ath_hw *ah, u32 ints);
@@ -1236,6 +1241,11 @@ void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr,
1236 u32 *rx_msg_intr); 1241 u32 *rx_msg_intr);
1237void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked); 1242void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked);
1238 1243
1244static inline bool ar9003_mci_is_ready(struct ath_hw *ah)
1245{
1246 return ah->btcoex_hw.mci.ready;
1247}
1248
1239#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT 1249#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
1240static inline enum ath_btcoex_scheme 1250static inline enum ath_btcoex_scheme
1241ath9k_hw_get_btcoex_scheme(struct ath_hw *ah) 1251ath9k_hw_get_btcoex_scheme(struct ath_hw *ah)