aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMohammed Shafi Shajakhan <mohammed@qca.qualcomm.com>2011-11-30 00:11:27 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-11-30 15:08:55 -0500
commit63d3296741e9f556d1edbdc34c07ce7dbe54a471 (patch)
tree07f7ce68414dc33e305cf08a541992bffb5ecd69
parent3ebfcdc43ae261e58e5b9b381ae1f278cda068e3 (diff)
ath9k_hw: Add MCI related changes in chip reset
here we check for BT state and if BT calibration has started, give 25ms for BT Calibration to finish. we also take care of 2G/5G switch and LNA transfer incase WLAN is operating in 5G. in case the BT state is awake when we do WLAN calibration re-calibrate and we reset the message exchange between WLAN and BT. BT is given preference when simultaneous CAL request happens. calibration for WLAN/BT is done assuming that the other co-existing module is in awake state, if not we continue to do calibration while if the other module's state changes we need to do restart the calibration handshake Cc: Wilson Tsao <wtsao@qca.qualcomm.com> Cc: Senthil Balasubramanian <senthilb@qca.qualcomm.com> Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com> Signed-off-by: Mohammed Shafi Shajakhan <mohammed@qca.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c132
1 files changed, 132 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 1d71d1ba202c..e2860d7cd684 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1514,6 +1514,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1514 struct ath9k_hw_cal_data *caldata, bool bChannelChange) 1514 struct ath9k_hw_cal_data *caldata, bool bChannelChange)
1515{ 1515{
1516 struct ath_common *common = ath9k_hw_common(ah); 1516 struct ath_common *common = ath9k_hw_common(ah);
1517 struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
1517 u32 saveLedState; 1518 u32 saveLedState;
1518 struct ath9k_channel *curchan = ah->curchan; 1519 struct ath9k_channel *curchan = ah->curchan;
1519 u32 saveDefAntenna; 1520 u32 saveDefAntenna;
@@ -1521,6 +1522,53 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1521 u64 tsf = 0; 1522 u64 tsf = 0;
1522 int i, r; 1523 int i, r;
1523 bool allow_fbs = false; 1524 bool allow_fbs = false;
1525 bool mci = !!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI);
1526 bool save_fullsleep = ah->chip_fullsleep;
1527
1528 if (mci) {
1529
1530 ar9003_mci_2g5g_changed(ah, IS_CHAN_2GHZ(chan));
1531
1532 if (mci_hw->bt_state == MCI_BT_CAL_START) {
1533 u32 payload[4] = {0, 0, 0, 0};
1534
1535 ath_dbg(common, ATH_DBG_MCI, "MCI stop rx for BT CAL");
1536
1537 mci_hw->bt_state = MCI_BT_CAL;
1538
1539 /*
1540 * MCI FIX: disable mci interrupt here. This is to avoid
1541 * SW_MSG_DONE or RX_MSG bits to trigger MCI_INT and
1542 * lead to mci_intr reentry.
1543 */
1544
1545 ar9003_mci_disable_interrupt(ah);
1546
1547 ath_dbg(common, ATH_DBG_MCI, "send WLAN_CAL_GRANT");
1548 MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_GRANT);
1549 ar9003_mci_send_message(ah, MCI_GPM, 0, payload,
1550 16, true, false);
1551
1552 ath_dbg(common, ATH_DBG_MCI, "\nMCI BT is calibrating");
1553
1554 /* Wait BT calibration to be completed for 25ms */
1555
1556 if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_DONE,
1557 0, 25000))
1558 ath_dbg(common, ATH_DBG_MCI,
1559 "MCI got BT_CAL_DONE\n");
1560 else
1561 ath_dbg(common, ATH_DBG_MCI,
1562 "MCI ### BT cal takes to long, force"
1563 "bt_state to be bt_awake\n");
1564 mci_hw->bt_state = MCI_BT_AWAKE;
1565 /* MCI FIX: enable mci interrupt here */
1566 ar9003_mci_enable_interrupt(ah);
1567
1568 return true;
1569 }
1570 }
1571
1524 1572
1525 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) 1573 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
1526 return -EIO; 1574 return -EIO;
@@ -1558,12 +1606,29 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1558 if (ath9k_hw_channel_change(ah, chan)) { 1606 if (ath9k_hw_channel_change(ah, chan)) {
1559 ath9k_hw_loadnf(ah, ah->curchan); 1607 ath9k_hw_loadnf(ah, ah->curchan);
1560 ath9k_hw_start_nfcal(ah, true); 1608 ath9k_hw_start_nfcal(ah, true);
1609 if (mci && mci_hw->ready)
1610 ar9003_mci_2g5g_switch(ah, true);
1611
1561 if (AR_SREV_9271(ah)) 1612 if (AR_SREV_9271(ah))
1562 ar9002_hw_load_ani_reg(ah, chan); 1613 ar9002_hw_load_ani_reg(ah, chan);
1563 return 0; 1614 return 0;
1564 } 1615 }
1565 } 1616 }
1566 1617
1618 if (mci) {
1619 ar9003_mci_disable_interrupt(ah);
1620
1621 if (mci_hw->ready && !save_fullsleep) {
1622 ar9003_mci_mute_bt(ah);
1623 udelay(20);
1624 REG_WRITE(ah, AR_BTCOEX_CTRL, 0);
1625 }
1626
1627 mci_hw->bt_state = MCI_BT_SLEEP;
1628 mci_hw->ready = false;
1629 }
1630
1631
1567 saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA); 1632 saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA);
1568 if (saveDefAntenna == 0) 1633 if (saveDefAntenna == 0)
1569 saveDefAntenna = 1; 1634 saveDefAntenna = 1;
@@ -1619,6 +1684,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1619 if (r) 1684 if (r)
1620 return r; 1685 return r;
1621 1686
1687 if (mci)
1688 ar9003_mci_reset(ah, false, IS_CHAN_2GHZ(chan), save_fullsleep);
1689
1622 /* 1690 /*
1623 * Some AR91xx SoC devices frequently fail to accept TSF writes 1691 * Some AR91xx SoC devices frequently fail to accept TSF writes
1624 * right after the chip reset. When that happens, write a new 1692 * right after the chip reset. When that happens, write a new
@@ -1736,6 +1804,55 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1736 ath9k_hw_loadnf(ah, chan); 1804 ath9k_hw_loadnf(ah, chan);
1737 ath9k_hw_start_nfcal(ah, true); 1805 ath9k_hw_start_nfcal(ah, true);
1738 1806
1807 if (mci && mci_hw->ready) {
1808
1809 if (IS_CHAN_2GHZ(chan) &&
1810 (mci_hw->bt_state == MCI_BT_SLEEP)) {
1811
1812 if (ar9003_mci_check_int(ah,
1813 AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET) ||
1814 ar9003_mci_check_int(ah,
1815 AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)) {
1816
1817 /*
1818 * BT is sleeping. Check if BT wakes up during
1819 * WLAN calibration. If BT wakes up during
1820 * WLAN calibration, need to go through all
1821 * message exchanges again and recal.
1822 */
1823
1824 ath_dbg(common, ATH_DBG_MCI, "MCI BT wakes up"
1825 "during WLAN calibration\n");
1826
1827 REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
1828 AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET |
1829 AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE);
1830 ath_dbg(common, ATH_DBG_MCI, "MCI send"
1831 "REMOTE_RESET\n");
1832 ar9003_mci_remote_reset(ah, true);
1833 ar9003_mci_send_sys_waking(ah, true);
1834 udelay(1);
1835 if (IS_CHAN_2GHZ(chan))
1836 ar9003_mci_send_lna_transfer(ah, true);
1837
1838 mci_hw->bt_state = MCI_BT_AWAKE;
1839
1840 ath_dbg(common, ATH_DBG_MCI, "MCI re-cal\n");
1841
1842 if (caldata) {
1843 caldata->done_txiqcal_once = false;
1844 caldata->done_txclcal_once = false;
1845 caldata->rtt_hist.num_readings = 0;
1846 }
1847
1848 if (!ath9k_hw_init_cal(ah, chan))
1849 return -EIO;
1850
1851 }
1852 }
1853 ar9003_mci_enable_interrupt(ah);
1854 }
1855
1739 ENABLE_REGWRITE_BUFFER(ah); 1856 ENABLE_REGWRITE_BUFFER(ah);
1740 1857
1741 ath9k_hw_restore_chainmask(ah); 1858 ath9k_hw_restore_chainmask(ah);
@@ -1778,6 +1895,21 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1778 if (ah->btcoex_hw.enabled) 1895 if (ah->btcoex_hw.enabled)
1779 ath9k_hw_btcoex_enable(ah); 1896 ath9k_hw_btcoex_enable(ah);
1780 1897
1898 if (mci && mci_hw->ready) {
1899 /*
1900 * check BT state again to make
1901 * sure it's not changed.
1902 */
1903
1904 ar9003_mci_sync_bt_state(ah);
1905 ar9003_mci_2g5g_switch(ah, true);
1906
1907 if ((mci_hw->bt_state == MCI_BT_AWAKE) &&
1908 (mci_hw->query_bt == true)) {
1909 mci_hw->need_flush_btinfo = true;
1910 }
1911 }
1912
1781 if (AR_SREV_9300_20_OR_LATER(ah)) { 1913 if (AR_SREV_9300_20_OR_LATER(ah)) {
1782 ar9003_hw_bb_watchdog_config(ah); 1914 ar9003_hw_bb_watchdog_config(ah);
1783 1915