From 3ebfcdc43ae261e58e5b9b381ae1f278cda068e3 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Wed, 30 Nov 2011 10:41:26 +0530 Subject: [PATCH] ath9k_hw: Add support for MCI WLAN calibration WLAN communicates with BT for its calibration by sending WLAN_CAL_REQ, waits for BT_CAL_GRANT. This is done with the help of GPM messages. also WLAN_CAL_DONE messages is sent once WLAN calibration is done. Cc: Wilson Tsao Cc: Senthil Balasubramanian Signed-off-by: Rajkumar Manoharan Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_calib.c | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index e5407df10ea0..ddeba8693fab 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -18,6 +18,7 @@ #include "hw-ops.h" #include "ar9003_phy.h" #include "ar9003_rtt.h" +#include "ar9003_mci.h" #define MAX_MEASUREMENT MAX_IQCAL_MEASUREMENT #define MAX_MAG_DELTA 11 @@ -934,10 +935,12 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, { struct ath_common *common = ath9k_hw_common(ah); struct ath9k_hw_cal_data *caldata = ah->caldata; + struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; bool txiqcal_done = false, txclcal_done = false; bool is_reusable = true, status = true; bool run_rtt_cal = false, run_agc_cal; bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT); + bool mci = !!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI); u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL | AR_PHY_AGC_CONTROL_FLTR_CAL | AR_PHY_AGC_CONTROL_PKDET_CAL; @@ -1005,6 +1008,31 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, } else if (caldata && !caldata->done_txiqcal_once) run_agc_cal = true; + if (mci && IS_CHAN_2GHZ(chan) && + (mci_hw->bt_state == MCI_BT_AWAKE) && + run_agc_cal && + !(mci_hw->config & ATH_MCI_CONFIG_DISABLE_MCI_CAL)) { + + u32 pld[4] = {0, 0, 0, 0}; + + /* send CAL_REQ only when BT is AWAKE. */ + ath_dbg(common, ATH_DBG_MCI, "MCI send WLAN_CAL_REQ 0x%x\n", + mci_hw->wlan_cal_seq); + MCI_GPM_SET_CAL_TYPE(pld, MCI_GPM_WLAN_CAL_REQ); + pld[MCI_GPM_WLAN_CAL_W_SEQUENCE] = mci_hw->wlan_cal_seq++; + ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, true, false); + + /* Wait BT_CAL_GRANT for 50ms */ + ath_dbg(common, ATH_DBG_MCI, "MCI wait for BT_CAL_GRANT"); + + if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_GRANT, 0, 50000)) + ath_dbg(common, ATH_DBG_MCI, "MCI got BT_CAL_GRANT"); + else { + is_reusable = false; + ath_dbg(common, ATH_DBG_MCI, "\nMCI BT is not responding"); + } + } + txiqcal_done = ar9003_hw_tx_iq_cal_run(ah); REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); udelay(5); @@ -1022,6 +1050,21 @@ skip_tx_iqcal: AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT); } + + if (mci && IS_CHAN_2GHZ(chan) && + (mci_hw->bt_state == MCI_BT_AWAKE) && + run_agc_cal && + !(mci_hw->config & ATH_MCI_CONFIG_DISABLE_MCI_CAL)) { + + u32 pld[4] = {0, 0, 0, 0}; + + ath_dbg(common, ATH_DBG_MCI, "MCI Send WLAN_CAL_DONE 0x%x\n", + mci_hw->wlan_cal_done); + MCI_GPM_SET_CAL_TYPE(pld, MCI_GPM_WLAN_CAL_DONE); + pld[MCI_GPM_WLAN_CAL_W_SEQUENCE] = mci_hw->wlan_cal_done++; + ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, true, false); + } + if (rtt && !run_rtt_cal) { agc_ctrl |= agc_supp_cals; REG_WRITE(ah, AR_PHY_AGC_CONTROL, agc_ctrl); -- 2.39.5