/*
 * Copyright (c) 2008-2011 Atheros Communications Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <linux/export.h>
#include "hw.h"
#include "hw-ops.h"
#include "ar9003_phy.h"
#include "ar9003_mci.h"
#include "ar9003_aic.h"

static void ar9003_mci_reset_req_wakeup(struct ath_hw *ah)
{
	REG_RMW_FIELD(ah, AR_MCI_COMMAND2,
		      AR_MCI_COMMAND2_RESET_REQ_WAKEUP, 1);
	udelay(1);
	REG_RMW_FIELD(ah, AR_MCI_COMMAND2,
		      AR_MCI_COMMAND2_RESET_REQ_WAKEUP, 0);
}

static int ar9003_mci_wait_for_interrupt(struct ath_hw *ah, u32 address,
					u32 bit_position, int time_out)
{
	struct ath_common *common = ath9k_hw_common(ah);

	while (time_out) {
		if (!(REG_READ(ah, address) & bit_position)) {
			udelay(10);
			time_out -= 10;

			if (time_out < 0)
				break;
			else
				continue;
		}
		REG_WRITE(ah, address, bit_position);

		if (address != AR_MCI_INTERRUPT_RX_MSG_RAW)
			break;

		if (bit_position & AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)
			ar9003_mci_reset_req_wakeup(ah);

		if (bit_position & (AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING |
				    AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING))
			REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
				  AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE);

		REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, AR_MCI_INTERRUPT_RX_MSG);
		break;
	}

	if (time_out <= 0) {
		ath_dbg(common, MCI,
			"MCI Wait for Reg 0x%08x = 0x%08x timeout\n",
			address, bit_position);
		ath_dbg(common, MCI,
			"MCI INT_RAW = 0x%08x, RX_MSG_RAW = 0x%08x\n",
			REG_READ(ah, AR_MCI_INTERRUPT_RAW),
			REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW));
		time_out = 0;
	}

	return time_out;
}

static void ar9003_mci_remote_reset(struct ath_hw *ah, bool wait_done)
{
	u32 payload[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffff00};

	ar9003_mci_send_message(ah, MCI_REMOTE_RESET, 0, payload, 16,
				wait_done, false);
	udelay(5);
}

static void ar9003_mci_send_lna_transfer(struct ath_hw *ah, bool wait_done)
{
	u32 payload = 0x00000000;

	ar9003_mci_send_message(ah, MCI_LNA_TRANS, 0, &payload, 1,
				wait_done, false);
}

static void ar9003_mci_send_req_wake(struct ath_hw *ah, bool wait_done)
{
	ar9003_mci_send_message(ah, MCI_REQ_WAKE, MCI_FLAG_DISABLE_TIMESTAMP,
				NULL, 0, wait_done, false);
	udelay(5);
}

static void ar9003_mci_send_sys_waking(struct ath_hw *ah, bool wait_done)
{
	ar9003_mci_send_message(ah, MCI_SYS_WAKING, MCI_FLAG_DISABLE_TIMESTAMP,
				NULL, 0, wait_done, false);
}

static void ar9003_mci_send_lna_take(struct ath_hw *ah, bool wait_done)
{
	u32 payload = 0x70000000;

	ar9003_mci_send_message(ah, MCI_LNA_TAKE, 0, &payload, 1,
				wait_done, false);
}

static void ar9003_mci_send_sys_sleeping(struct ath_hw *ah, bool wait_done)
{
	ar9003_mci_send_message(ah, MCI_SYS_SLEEPING,
				MCI_FLAG_DISABLE_TIMESTAMP,
				NULL, 0, wait_done, false);
}

static void ar9003_mci_send_coex_version_query(struct ath_hw *ah,
					       bool wait_done)
{
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
	u32 payload[4] = {0, 0, 0, 0};

	if (mci->bt_version_known ||
	    (mci->bt_state == MCI_BT_SLEEP))
		return;

	MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT,
				MCI_GPM_COEX_VERSION_QUERY);
	ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, true);
}

static void ar9003_mci_send_coex_version_response(struct ath_hw *ah,
						  bool wait_done)
{
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
	u32 payload[4] = {0, 0, 0, 0};

	MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT,
				MCI_GPM_COEX_VERSION_RESPONSE);
	*(((u8 *)payload) + MCI_GPM_COEX_B_MAJOR_VERSION) =
		mci->wlan_ver_major;
	*(((u8 *)payload) + MCI_GPM_COEX_B_MINOR_VERSION) =
		mci->wlan_ver_minor;
	ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, true);
}

static void ar9003_mci_send_coex_wlan_channels(struct ath_hw *ah,
					       bool wait_done)
{
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
	u32 *payload = &mci->wlan_channels[0];

	if (!mci->wlan_channels_update ||
	    (mci->bt_state == MCI_BT_SLEEP))
		return;

	MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT,
				MCI_GPM_COEX_WLAN_CHANNELS);
	ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, true);
	MCI_GPM_SET_TYPE_OPCODE(payload, 0xff, 0xff);
}

static void ar9003_mci_send_coex_bt_status_query(struct ath_hw *ah,
						bool wait_done, u8 query_type)
{
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
	u32 payload[4] = {0, 0, 0, 0};
	bool query_btinfo;

	if (mci->bt_state == MCI_BT_SLEEP)
		return;

	query_btinfo = !!(query_type & (MCI_GPM_COEX_QUERY_BT_ALL_INFO |
					MCI_GPM_COEX_QUERY_BT_TOPOLOGY));
	MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT,
				MCI_GPM_COEX_STATUS_QUERY);

	*(((u8 *)payload) + MCI_GPM_COEX_B_BT_BITMAP) = query_type;

	/*
	 * If bt_status_query message is  not sent successfully,
	 * then need_flush_btinfo should be set again.
	 */
	if (!ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16,
				wait_done, true)) {
		if (query_btinfo)
			mci->need_flush_btinfo = true;
	}

	if (query_btinfo)
		mci->query_bt = false;
}

static void ar9003_mci_send_coex_halt_bt_gpm(struct ath_hw *ah, bool halt,
					     bool wait_done)
{
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
	u32 payload[4] = {0, 0, 0, 0};

	MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT,
				MCI_GPM_COEX_HALT_BT_GPM);

	if (halt) {
		mci->query_bt = true;
		/* Send next unhalt no matter halt sent or not */
		mci->unhalt_bt_gpm = true;
		mci->need_flush_btinfo = true;
		*(((u8 *)payload) + MCI_GPM_COEX_B_HALT_STATE) =
			MCI_GPM_COEX_BT_GPM_HALT;
	} else
		*(((u8 *)payload) + MCI_GPM_COEX_B_HALT_STATE) =
			MCI_GPM_COEX_BT_GPM_UNHALT;

	ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, true);
}

static void ar9003_mci_prep_interface(struct ath_hw *ah)
{
	struct ath_common *common = ath9k_hw_common(ah);
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
	u32 saved_mci_int_en;
	u32 mci_timeout = 150;

	mci->bt_state = MCI_BT_SLEEP;
	saved_mci_int_en = REG_READ(ah, AR_MCI_INTERRUPT_EN);

	REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0);
	REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
		  REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW));
	REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
		  REG_READ(ah, AR_MCI_INTERRUPT_RAW));

	ar9003_mci_remote_reset(ah, true);
	ar9003_mci_send_req_wake(ah, true);

	if (!ar9003_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
				  AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING, 500))
		goto clear_redunt;

	mci->bt_state = MCI_BT_AWAKE;

	/*
	 * we don't need to send more remote_reset at this moment.
	 * If BT receive first remote_reset, then BT HW will
	 * be cleaned up and will be able to receive req_wake
	 * and BT HW will respond sys_waking.
	 * In this case, WLAN will receive BT's HW sys_waking.
	 * Otherwise, if BT SW missed initial remote_reset,
	 * that remote_reset will still clean up BT MCI RX,
	 * and the req_wake will wake BT up,
	 * and BT SW will respond this req_wake with a remote_reset and
	 * sys_waking. In this case, WLAN will receive BT's SW
	 * sys_waking. In either case, BT's RX is cleaned up. So we
	 * don't need to reply BT's remote_reset now, if any.
	 * Similarly, if in any case, WLAN can receive BT's sys_waking,
	 * that means WLAN's RX is also fine.
	 */
	ar9003_mci_send_sys_waking(ah, true);
	udelay(10);

	/*
	 * Set BT priority interrupt value to be 0xff to
	 * avoid having too many BT PRIORITY interrupts.
	 */
	REG_WRITE(ah, AR_MCI_BT_PRI0, 0xFFFFFFFF);
	REG_WRITE(ah, AR_MCI_BT_PRI1, 0xFFFFFFFF);
	REG_WRITE(ah, AR_MCI_BT_PRI2, 0xFFFFFFFF);
	REG_WRITE(ah, AR_MCI_BT_PRI3, 0xFFFFFFFF);
	REG_WRITE(ah, AR_MCI_BT_PRI, 0X000000FF);

	/*
	 * A contention reset will be received after send out
	 * sys_waking. Also BT priority interrupt bits will be set.
	 * Clear those bits before the next step.
	 */

	REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
		  AR_MCI_INTERRUPT_RX_MSG_CONT_RST);
	REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, AR_MCI_INTERRUPT_BT_PRI);

	if (mci->is_2g && MCI_ANT_ARCH_PA_LNA_SHARED(mci)) {
		ar9003_mci_send_lna_transfer(ah, true);
		udelay(5);
	}

	if (mci->is_2g && !mci->update_2g5g && MCI_ANT_ARCH_PA_LNA_SHARED(mci)) {
		if (ar9003_mci_wait_for_interrupt(ah,
					AR_MCI_INTERRUPT_RX_MSG_RAW,
					AR_MCI_INTERRUPT_RX_MSG_LNA_INFO,
					mci_timeout))
			ath_dbg(common, MCI,
				"MCI WLAN has control over the LNA & BT obeys it\n");
		else
			ath_dbg(common, MCI,
				"MCI BT didn't respond to LNA_TRANS\n");
	}

clear_redunt:
	/* Clear the extra redundant SYS_WAKING from BT */
	if ((mci->bt_state == MCI_BT_AWAKE) &&
	    (REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
			    AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING)) &&
	    (REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
			    AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) == 0)) {
		REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
			  AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING);
		REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
			  AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE);
	}

	REG_WRITE(ah, AR_MCI_INTERRUPT_EN, saved_mci_int_en);
}

void ar9003_mci_set_full_sleep(struct ath_hw *ah)
{
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;

	if (ar9003_mci_state(ah, MCI_STATE_ENABLE) &&
	    (mci->bt_state != MCI_BT_SLEEP) &&
	    !mci->halted_bt_gpm) {
		ar9003_mci_send_coex_halt_bt_gpm(ah, true, true);
	}

	mci->ready = false;
}

static void ar9003_mci_disable_interrupt(struct ath_hw *ah)
{
	REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0);
	REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 0);
}

static void ar9003_mci_enable_interrupt(struct ath_hw *ah)
{
	REG_WRITE(ah, AR_MCI_INTERRUPT_EN, AR_MCI_INTERRUPT_DEFAULT);
	REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN,
		  AR_MCI_INTERRUPT_RX_MSG_DEFAULT);
}

static bool ar9003_mci_check_int(struct ath_hw *ah, u32 ints)
{
	u32 intr;

	intr = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW);
	return ((intr & ints) == ints);
}

void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr,
			      u32 *rx_msg_intr)
{
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;

	*raw_intr = mci->raw_intr;
	*rx_msg_intr = mci->rx_msg_intr;

	/* Clean int bits after the values are read. */
	mci->raw_intr = 0;
	mci->rx_msg_intr = 0;
}
EXPORT_SYMBOL(ar9003_mci_get_interrupt);

void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
{
	struct ath_common *common = ath9k_hw_common(ah);
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
	u32 raw_intr, rx_msg_intr;

	rx_msg_intr = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW);
	raw_intr = REG_READ(ah, AR_MCI_INTERRUPT_RAW);

	if ((raw_intr == 0xdeadbeef) || (rx_msg_intr == 0xdeadbeef)) {
		ath_dbg(common, MCI,
			"MCI gets 0xdeadbeef during int processing\n");
	} else {
		mci->rx_msg_intr |= rx_msg_intr;
		mci->raw_intr |= raw_intr;
		*masked |= ATH9K_INT_MCI;

		if (rx_msg_intr & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO)
			mci->cont_status = REG_READ(ah, AR_MCI_CONT_STATUS);

		REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, rx_msg_intr);
		REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, raw_intr);
	}
}

static void ar9003_mci_2g5g_changed(struct ath_hw *ah, bool is_2g)
{
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;

	if (!mci->update_2g5g &&
	    (mci->is_2g != is_2g))
		mci->update_2g5g = true;

	mci->is_2g = is_2g;
}

static bool ar9003_mci_is_gpm_valid(struct ath_hw *ah, u32 msg_index)
{
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
	u32 *payload;
	u32 recv_type, offset;

	if (msg_index == MCI_GPM_INVALID)
		return false;

	offset = msg_index << 4;

	payload = (u32 *)(mci->gpm_buf + offset);
	recv_type = MCI_GPM_TYPE(payload);

	if (recv_type == MCI_GPM_RSVD_PATTERN)
		return false;

	return true;
}

static void ar9003_mci_observation_set_up(struct ath_hw *ah)
{
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;

	if (mci->config & ATH_MCI_CONFIG_MCI_OBS_MCI) {
		ath9k_hw_cfg_output(ah, 3, AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA);
		ath9k_hw_cfg_output(ah, 2, AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK);
		ath9k_hw_cfg_output(ah, 1, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA);
		ath9k_hw_cfg_output(ah, 0, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK);
	} else if (mci->config & ATH_MCI_CONFIG_MCI_OBS_TXRX) {
		ath9k_hw_cfg_output(ah, 3, AR_GPIO_OUTPUT_MUX_AS_WL_IN_TX);
		ath9k_hw_cfg_output(ah, 2, AR_GPIO_OUTPUT_MUX_AS_WL_IN_RX);
		ath9k_hw_cfg_output(ah, 1, AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX);
		ath9k_hw_cfg_output(ah, 0, AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX);
		ath9k_hw_cfg_output(ah, 5, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
	} else if (mci->config & ATH_MCI_CONFIG_MCI_OBS_BT) {
		ath9k_hw_cfg_output(ah, 3, AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX);
		ath9k_hw_cfg_output(ah, 2, AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX);
		ath9k_hw_cfg_output(ah, 1, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA);
		ath9k_hw_cfg_output(ah, 0, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK);
	} else
		return;

	REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);

	REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, AR_GLB_DS_JTAG_DISABLE, 1);
	REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, AR_GLB_WLAN_UART_INTF_EN, 0);
	REG_SET_BIT(ah, AR_GLB_GPIO_CONTROL, ATH_MCI_CONFIG_MCI_OBS_GPIO);

	REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_GPIO_OBS_SEL, 0);
	REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_MAC_BB_OBS_SEL, 1);
	REG_WRITE(ah, AR_OBS, 0x4b);
	REG_RMW_FIELD(ah, AR_DIAG_SW, AR_DIAG_OBS_PT_SEL1, 0x03);
	REG_RMW_FIELD(ah, AR_DIAG_SW, AR_DIAG_OBS_PT_SEL2, 0x01);
	REG_RMW_FIELD(ah, AR_MACMISC, AR_MACMISC_MISC_OBS_BUS_LSB, 0x02);
	REG_RMW_FIELD(ah, AR_MACMISC, AR_MACMISC_MISC_OBS_BUS_MSB, 0x03);
	REG_RMW_FIELD(ah, AR_PHY_TEST_CTL_STATUS,
		      AR_PHY_TEST_CTL_DEBUGPORT_SEL, 0x07);
}

static bool ar9003_mci_send_coex_bt_flags(struct ath_hw *ah, bool wait_done,
					  u8 opcode, u32 bt_flags)
{
	u32 pld[4] = {0, 0, 0, 0};

	MCI_GPM_SET_TYPE_OPCODE(pld, MCI_GPM_COEX_AGENT,
				MCI_GPM_COEX_BT_UPDATE_FLAGS);

	*(((u8 *)pld) + MCI_GPM_COEX_B_BT_FLAGS_OP)  = opcode;
	*(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 0) = bt_flags & 0xFF;
	*(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 1) = (bt_flags >> 8) & 0xFF;
	*(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 2) = (bt_flags >> 16) & 0xFF;
	*(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 3) = (bt_flags >> 24) & 0xFF;

	return ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16,
				       wait_done, true);
}

static void ar9003_mci_sync_bt_state(struct ath_hw *ah)
{
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
	u32 cur_bt_state;

	cur_bt_state = ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP);

	if (mci->bt_state != cur_bt_state)
		mci->bt_state = cur_bt_state;

	if (mci->bt_state != MCI_BT_SLEEP) {

		ar9003_mci_send_coex_version_query(ah, true);
		ar9003_mci_send_coex_wlan_channels(ah, true);

		if (mci->unhalt_bt_gpm == true)
			ar9003_mci_send_coex_halt_bt_gpm(ah, false, true);
	}
}

void ar9003_mci_check_bt(struct ath_hw *ah)
{
	struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;

	if (!mci_hw->ready)
		return;

	/*
	 * check BT state again to make
	 * sure it's not changed.
	 */
	ar9003_mci_sync_bt_state(ah);
	ar9003_mci_2g5g_switch(ah, true);

	if ((mci_hw->bt_state == MCI_BT_AWAKE) &&
	    (mci_hw->query_bt == true)) {
		mci_hw->need_flush_btinfo = true;
	}
}

static void ar9003_mci_process_gpm_extra(struct ath_hw *ah, u8 gpm_type,
					 u8 gpm_opcode, u32 *p_gpm)
{
	struct ath_common *common = ath9k_hw_common(ah);
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
	u8 *p_data = (u8 *) p_gpm;

	if (gpm_type != MCI_GPM_COEX_AGENT)
		return;

	switch (gpm_opcode) {
	case MCI_GPM_COEX_VERSION_QUERY:
		ath_dbg(common, MCI, "MCI Recv GPM COEX Version Query\n");
		ar9003_mci_send_coex_version_response(ah, true);
		break;
	case MCI_GPM_COEX_VERSION_RESPONSE:
		ath_dbg(common, MCI, "MCI Recv GPM COEX Version Response\n");
		mci->bt_ver_major =
			*(p_data + MCI_GPM_COEX_B_MAJOR_VERSION);
		mci->bt_ver_minor =
			*(p_data + MCI_GPM_COEX_B_MINOR_VERSION);
		mci->bt_version_known = true;
		ath_dbg(common, MCI, "MCI BT Coex version: %d.%d\n",
			mci->bt_ver_major, mci->bt_ver_minor);
		break;
	case MCI_GPM_COEX_STATUS_QUERY:
		ath_dbg(common, MCI,
			"MCI Recv GPM COEX Status Query = 0x%02X\n",
			*(p_data + MCI_GPM_COEX_B_WLAN_BITMAP));
		mci->wlan_channels_update = true;
		ar9003_mci_send_coex_wlan_channels(ah, true);
		break;
	case MCI_GPM_COEX_BT_PROFILE_INFO:
		mci->query_bt = true;
		ath_dbg(common, MCI, "MCI Recv GPM COEX BT_Profile_Info\n");
		break;
	case MCI_GPM_COEX_BT_STATUS_UPDATE:
		mci->query_bt = true;
		ath_dbg(common, MCI,
			"MCI Recv GPM COEX BT_Status_Update SEQ=%d (drop&query)\n",
			*(p_gpm + 3));
		break;
	default:
		break;
	}
}

static u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type,
				   u8 gpm_opcode, int time_out)
{
	struct ath_common *common = ath9k_hw_common(ah);
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
	u32 *p_gpm = NULL, mismatch = 0, more_data;
	u32 offset;
	u8 recv_type = 0, recv_opcode = 0;
	bool b_is_bt_cal_done = (gpm_type == MCI_GPM_BT_CAL_DONE);

	more_data = time_out ? MCI_GPM_NOMORE : MCI_GPM_MORE;

	while (time_out > 0) {
		if (p_gpm) {
			MCI_GPM_RECYCLE(p_gpm);
			p_gpm = NULL;
		}

		if (more_data != MCI_GPM_MORE)
			time_out = ar9003_mci_wait_for_interrupt(ah,
					AR_MCI_INTERRUPT_RX_MSG_RAW,
					AR_MCI_INTERRUPT_RX_MSG_GPM,
					time_out);

		if (!time_out)
			break;

		offset = ar9003_mci_get_next_gpm_offset(ah, &more_data);

		if (offset == MCI_GPM_INVALID)
			continue;

		p_gpm = (u32 *) (mci->gpm_buf + offset);
		recv_type = MCI_GPM_TYPE(p_gpm);
		recv_opcode = MCI_GPM_OPCODE(p_gpm);

		if (MCI_GPM_IS_CAL_TYPE(recv_type)) {
			if (recv_type == gpm_type) {
				if ((gpm_type == MCI_GPM_BT_CAL_DONE) &&
				    !b_is_bt_cal_done) {
					gpm_type = MCI_GPM_BT_CAL_GRANT;
					continue;
				}
				break;
			}
		} else if ((recv_type == gpm_type) &&
			   (recv_opcode == gpm_opcode))
			break;

		/*
		 * check if it's cal_grant
		 *
		 * When we're waiting for cal_grant in reset routine,
		 * it's possible that BT sends out cal_request at the
		 * same time. Since BT's calibration doesn't happen
		 * that often, we'll let BT completes calibration then
		 * we continue to wait for cal_grant from BT.
		 * Orginal: Wait BT_CAL_GRANT.
		 * New: Receive BT_CAL_REQ -> send WLAN_CAL_GRANT->wait
		 * BT_CAL_DONE -> Wait BT_CAL_GRANT.
		 */

		if ((gpm_type == MCI_GPM_BT_CAL_GRANT) &&
		    (recv_type == MCI_GPM_BT_CAL_REQ)) {

			u32 payload[4] = {0, 0, 0, 0};

			gpm_type = MCI_GPM_BT_CAL_DONE;
			MCI_GPM_SET_CAL_TYPE(payload,
					     MCI_GPM_WLAN_CAL_GRANT);
			ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16,
						false, false);
			continue;
		} else {
			ath_dbg(common, MCI, "MCI GPM subtype not match 0x%x\n",
				*(p_gpm + 1));
			mismatch++;
			ar9003_mci_process_gpm_extra(ah, recv_type,
						     recv_opcode, p_gpm);
		}
	}

	if (p_gpm) {
		MCI_GPM_RECYCLE(p_gpm);
		p_gpm = NULL;
	}

	if (time_out <= 0)
		time_out = 0;

	while (more_data == MCI_GPM_MORE) {
		offset = ar9003_mci_get_next_gpm_offset(ah, &more_data);
		if (offset == MCI_GPM_INVALID)
			break;

		p_gpm = (u32 *) (mci->gpm_buf + offset);
		recv_type = MCI_GPM_TYPE(p_gpm);
		recv_opcode = MCI_GPM_OPCODE(p_gpm);

		if (!MCI_GPM_IS_CAL_TYPE(recv_type))
			ar9003_mci_process_gpm_extra(ah, recv_type,
						     recv_opcode, p_gpm);

		MCI_GPM_RECYCLE(p_gpm);
	}

	return time_out;
}

bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan)
{
	struct ath_common *common = ath9k_hw_common(ah);
	struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
	u32 payload[4] = {0, 0, 0, 0};

	ar9003_mci_2g5g_changed(ah, IS_CHAN_2GHZ(chan));

	if (mci_hw->bt_state != MCI_BT_CAL_START)
		return false;

	mci_hw->bt_state = MCI_BT_CAL;

	/*
	 * MCI FIX: disable mci interrupt here. This is to avoid
	 * SW_MSG_DONE or RX_MSG bits to trigger MCI_INT and
	 * lead to mci_intr reentry.
	 */
	ar9003_mci_disable_interrupt(ah);

	MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_GRANT);
	ar9003_mci_send_message(ah, MCI_GPM, 0, payload,
				16, true, false);

	/* Wait BT calibration to be completed for 25ms */

	if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_DONE,
				    0, 25000))
		ath_dbg(common, MCI, "MCI BT_CAL_DONE received\n");
	else
		ath_dbg(common, MCI,
			"MCI BT_CAL_DONE not received\n");

	mci_hw->bt_state = MCI_BT_AWAKE;
	/* MCI FIX: enable mci interrupt here */
	ar9003_mci_enable_interrupt(ah);

	return true;
}

int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan,
			 struct ath9k_hw_cal_data *caldata)
{
	struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;

	if (!mci_hw->ready)
		return 0;

	if (!IS_CHAN_2GHZ(chan) || (mci_hw->bt_state != MCI_BT_SLEEP))
		goto exit;

	if (!ar9003_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET) &&
	    !ar9003_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE))
		goto exit;

	/*
	 * BT is sleeping. Check if BT wakes up during
	 * WLAN calibration. If BT wakes up during
	 * WLAN calibration, need to go through all
	 * message exchanges again and recal.
	 */
	REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
		  (AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET |
		   AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE));

	ar9003_mci_remote_reset(ah, true);
	ar9003_mci_send_sys_waking(ah, true);
	udelay(1);

	if (IS_CHAN_2GHZ(chan))
		ar9003_mci_send_lna_transfer(ah, true);

	mci_hw->bt_state = MCI_BT_AWAKE;

	REG_CLR_BIT(ah, AR_PHY_TIMING4,
		    1 << AR_PHY_TIMING_CONTROL4_DO_GAIN_DC_IQ_CAL_SHIFT);

	if (caldata) {
		clear_bit(TXIQCAL_DONE, &caldata->cal_flags);
		clear_bit(TXCLCAL_DONE, &caldata->cal_flags);
		clear_bit(RTT_DONE, &caldata->cal_flags);
	}

	if (!ath9k_hw_init_cal(ah, chan))
		return -EIO;

	REG_SET_BIT(ah, AR_PHY_TIMING4,
		    1 << AR_PHY_TIMING_CONTROL4_DO_GAIN_DC_IQ_CAL_SHIFT);

exit:
	ar9003_mci_enable_interrupt(ah);
	return 0;
}

static void ar9003_mci_mute_bt(struct ath_hw *ah)
{
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;

	/* disable all MCI messages */
	REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 0xffff0000);
	REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, 0xffffffff);
	REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS1, 0xffffffff);
	REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS2, 0xffffffff);
	REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS3, 0xffffffff);
	REG_SET_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);

	/* wait pending HW messages to flush out */
	udelay(10);

	/*
	 * Send LNA_TAKE and SYS_SLEEPING when
	 * 1. reset not after resuming from full sleep
	 * 2. before reset MCI RX, to quiet BT and avoid MCI RX misalignment
	 */
	if (MCI_ANT_ARCH_PA_LNA_SHARED(mci)) {
		ar9003_mci_send_lna_take(ah, true);
		udelay(5);
	}

	ar9003_mci_send_sys_sleeping(ah, true);
}

static void ar9003_mci_osla_setup(struct ath_hw *ah, bool enable)
{
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
	u32 thresh;

	if (!enable) {
		REG_CLR_BIT(ah, AR_BTCOEX_CTRL,
			    AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
		return;
	}
	REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, AR_MCI_SCHD_TABLE_2_HW_BASED, 1);
	REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2,
		      AR_MCI_SCHD_TABLE_2_MEM_BASED, 1);

	if (AR_SREV_9565(ah))
		REG_RMW_FIELD(ah, AR_MCI_MISC, AR_MCI_MISC_HW_FIX_EN, 1);

	if (!(mci->config & ATH_MCI_CONFIG_DISABLE_AGGR_THRESH)) {
		thresh = MS(mci->config, ATH_MCI_CONFIG_AGGR_THRESH);
		REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,
			      AR_BTCOEX_CTRL_AGGR_THRESH, thresh);
		REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,
			      AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 1);
	} else
		REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,
			      AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 0);

	REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,
		      AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN, 1);
}

static void ar9003_mci_stat_setup(struct ath_hw *ah)
{
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;

	if (!AR_SREV_9565(ah))
		return;

	if (mci->config & ATH_MCI_CONFIG_MCI_STAT_DBG) {
		REG_RMW_FIELD(ah, AR_MCI_DBG_CNT_CTRL,
			      AR_MCI_DBG_CNT_CTRL_ENABLE, 1);
		REG_RMW_FIELD(ah, AR_MCI_DBG_CNT_CTRL,
			      AR_MCI_DBG_CNT_CTRL_BT_LINKID,
			      MCI_STAT_ALL_BT_LINKID);
	} else {
		REG_RMW_FIELD(ah, AR_MCI_DBG_CNT_CTRL,
			      AR_MCI_DBG_CNT_CTRL_ENABLE, 0);
	}
}

static void ar9003_mci_set_btcoex_ctrl_9565_1ANT(struct ath_hw *ah)
{
	u32 regval;

	regval = SM(1, AR_BTCOEX_CTRL_AR9462_MODE) |
		 SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) |
		 SM(1, AR_BTCOEX_CTRL_PA_SHARED) |
		 SM(1, AR_BTCOEX_CTRL_LNA_SHARED) |
		 SM(1, AR_BTCOEX_CTRL_NUM_ANTENNAS) |
		 SM(1, AR_BTCOEX_CTRL_RX_CHAIN_MASK) |
		 SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) |
		 SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) |
		 SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);

	REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2,
		      AR_BTCOEX_CTRL2_TX_CHAIN_MASK, 0x1);
	REG_WRITE(ah, AR_BTCOEX_CTRL, regval);
}

static void ar9003_mci_set_btcoex_ctrl_9565_2ANT(struct ath_hw *ah)
{
	u32 regval;

	regval = SM(1, AR_BTCOEX_CTRL_AR9462_MODE) |
		 SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) |
		 SM(0, AR_BTCOEX_CTRL_PA_SHARED) |
		 SM(0, AR_BTCOEX_CTRL_LNA_SHARED) |
		 SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS) |
		 SM(1, AR_BTCOEX_CTRL_RX_CHAIN_MASK) |
		 SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) |
		 SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) |
		 SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);

	REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2,
		      AR_BTCOEX_CTRL2_TX_CHAIN_MASK, 0x0);
	REG_WRITE(ah, AR_BTCOEX_CTRL, regval);
}

static void ar9003_mci_set_btcoex_ctrl_9462(struct ath_hw *ah)
{
	u32 regval;

        regval = SM(1, AR_BTCOEX_CTRL_AR9462_MODE) |
		 SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) |
		 SM(1, AR_BTCOEX_CTRL_PA_SHARED) |
		 SM(1, AR_BTCOEX_CTRL_LNA_SHARED) |
		 SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS) |
		 SM(3, AR_BTCOEX_CTRL_RX_CHAIN_MASK) |
		 SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) |
		 SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) |
		 SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);

	REG_WRITE(ah, AR_BTCOEX_CTRL, regval);
}

int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
		     bool is_full_sleep)
{
	struct ath_common *common = ath9k_hw_common(ah);
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
	u32 regval, i;

	ath_dbg(common, MCI, "MCI Reset (full_sleep = %d, is_2g = %d)\n",
		is_full_sleep, is_2g);

	if (REG_READ(ah, AR_BTCOEX_CTRL) == 0xdeadbeef) {
		ath_err(common, "BTCOEX control register is dead\n");
		return -EINVAL;
	}

	/* Program MCI DMA related registers */
	REG_WRITE(ah, AR_MCI_GPM_0, mci->gpm_addr);
	REG_WRITE(ah, AR_MCI_GPM_1, mci->gpm_len);
	REG_WRITE(ah, AR_MCI_SCHD_TABLE_0, mci->sched_addr);

	/*
	* To avoid MCI state machine be affected by incoming remote MCI msgs,
	* MCI mode will be enabled later, right before reset the MCI TX and RX.
	*/
	if (AR_SREV_9565(ah)) {
		u8 ant = MS(mci->config, ATH_MCI_CONFIG_ANT_ARCH);

		if (ant == ATH_MCI_ANT_ARCH_1_ANT_PA_LNA_SHARED)
			ar9003_mci_set_btcoex_ctrl_9565_1ANT(ah);
		else
			ar9003_mci_set_btcoex_ctrl_9565_2ANT(ah);
	} else {
		ar9003_mci_set_btcoex_ctrl_9462(ah);
	}

	if (is_2g && !(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA))
		ar9003_mci_osla_setup(ah, true);
	else
		ar9003_mci_osla_setup(ah, false);

	REG_SET_BIT(ah, AR_PHY_GLB_CONTROL,
		    AR_BTCOEX_CTRL_SPDT_ENABLE);
	REG_RMW_FIELD(ah, AR_BTCOEX_CTRL3,
		      AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT, 20);

	REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_RX_DEWEIGHT, 0);
	REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0);

	/* Set the time out to 3.125ms (5 BT slots) */
	REG_RMW_FIELD(ah, AR_BTCOEX_WL_LNA, AR_BTCOEX_WL_LNA_TIMEOUT, 0x3D090);

	/* concurrent tx priority */
	if (mci->config & ATH_MCI_CONFIG_CONCUR_TX) {
		REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2,
			      AR_BTCOEX_CTRL2_DESC_BASED_TXPWR_ENABLE, 0);
		REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2,
			      AR_BTCOEX_CTRL2_TXPWR_THRESH, 0x7f);
		REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,
			      AR_BTCOEX_CTRL_REDUCE_TXPWR, 0);
		for (i = 0; i < 8; i++)
			REG_WRITE(ah, AR_BTCOEX_MAX_TXPWR(i), 0x7f7f7f7f);
	}

	regval = MS(mci->config, ATH_MCI_CONFIG_CLK_DIV);
	REG_RMW_FIELD(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_CLK_DIV, regval);
	REG_SET_BIT(ah, AR_BTCOEX_CTRL, AR_BTCOEX_CTRL_MCI_MODE_EN);

	/* Resetting the Rx and Tx paths of MCI */
	regval = REG_READ(ah, AR_MCI_COMMAND2);
	regval |= SM(1, AR_MCI_COMMAND2_RESET_TX);
	REG_WRITE(ah, AR_MCI_COMMAND2, regval);

	udelay(1);

	regval &= ~SM(1, AR_MCI_COMMAND2_RESET_TX);
	REG_WRITE(ah, AR_MCI_COMMAND2, regval);

	if (is_full_sleep) {
		ar9003_mci_mute_bt(ah);
		udelay(100);
	}

	/* Check pending GPM msg before MCI Reset Rx */
	ar9003_mci_check_gpm_offset(ah);

	regval |= SM(1, AR_MCI_COMMAND2_RESET_RX);
	REG_WRITE(ah, AR_MCI_COMMAND2, regval);
	udelay(1);
	regval &= ~SM(1, AR_MCI_COMMAND2_RESET_RX);
	REG_WRITE(ah, AR_MCI_COMMAND2, regval);

	/* Init GPM offset after MCI Reset Rx */
	ar9003_mci_state(ah, MCI_STATE_INIT_GPM_OFFSET);

	REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE,
		  (SM(0xe801, AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR) |
		   SM(0x0000, AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM)));

	if (MCI_ANT_ARCH_PA_LNA_SHARED(mci))
		REG_CLR_BIT(ah, AR_MCI_TX_CTRL,
			    AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
	else
		REG_SET_BIT(ah, AR_MCI_TX_CTRL,
			    AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);

	ar9003_mci_observation_set_up(ah);

	mci->ready = true;
	ar9003_mci_prep_interface(ah);
	ar9003_mci_stat_setup(ah);

	if (en_int)
		ar9003_mci_enable_interrupt(ah);

	if (ath9k_hw_is_aic_enabled(ah))
		ar9003_aic_start_normal(ah);

	return 0;
}

void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep)
{
	struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;

	ar9003_mci_disable_interrupt(ah);

	if (mci_hw->ready && !save_fullsleep) {
		ar9003_mci_mute_bt(ah);
		udelay(20);
		REG_WRITE(ah, AR_BTCOEX_CTRL, 0);
	}

	mci_hw->bt_state = MCI_BT_SLEEP;
	mci_hw->ready = false;
}

static void ar9003_mci_send_2g5g_status(struct ath_hw *ah, bool wait_done)
{
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
	u32 new_flags, to_set, to_clear;

	if (!mci->update_2g5g || (mci->bt_state == MCI_BT_SLEEP))
		return;

	if (mci->is_2g) {
		new_flags = MCI_2G_FLAGS;
		to_clear = MCI_2G_FLAGS_CLEAR_MASK;
		to_set = MCI_2G_FLAGS_SET_MASK;
	} else {
		new_flags = MCI_5G_FLAGS;
		to_clear = MCI_5G_FLAGS_CLEAR_MASK;
		to_set = MCI_5G_FLAGS_SET_MASK;
	}

	if (to_clear)
		ar9003_mci_send_coex_bt_flags(ah, wait_done,
					      MCI_GPM_COEX_BT_FLAGS_CLEAR,
					      to_clear);
	if (to_set)
		ar9003_mci_send_coex_bt_flags(ah, wait_done,
					      MCI_GPM_COEX_BT_FLAGS_SET,
					      to_set);
}

static void ar9003_mci_queue_unsent_gpm(struct ath_hw *ah, u8 header,
					u32 *payload, bool queue)
{
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
	u8 type, opcode;

	/* check if the message is to be queued */
	if (header != MCI_GPM)
		return;

	type = MCI_GPM_TYPE(payload);
	opcode = MCI_GPM_OPCODE(payload);

	if (type != MCI_GPM_COEX_AGENT)
		return;

	switch (opcode) {
	case MCI_GPM_COEX_BT_UPDATE_FLAGS:
		if (*(((u8 *)payload) + MCI_GPM_COEX_B_BT_FLAGS_OP) ==
		    MCI_GPM_COEX_BT_FLAGS_READ)
			break;

		mci->update_2g5g = queue;

		break;
	case MCI_GPM_COEX_WLAN_CHANNELS:
		mci->wlan_channels_update = queue;
		break;
	case MCI_GPM_COEX_HALT_BT_GPM:
		if (*(((u8 *)payload) + MCI_GPM_COEX_B_HALT_STATE) ==
		    MCI_GPM_COEX_BT_GPM_UNHALT) {
			mci->unhalt_bt_gpm = queue;

			if (!queue)
				mci->halted_bt_gpm = false;
		}

		if (*(((u8 *)payload) + MCI_GPM_COEX_B_HALT_STATE) ==
				MCI_GPM_COEX_BT_GPM_HALT) {

			mci->halted_bt_gpm = !queue;
		}

		break;
	default:
		break;
	}
}

void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool force)
{
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;

	if (!mci->update_2g5g && !force)
		return;

	if (mci->is_2g) {
		ar9003_mci_send_2g5g_status(ah, true);
		ar9003_mci_send_lna_transfer(ah, true);
		udelay(5);

		REG_CLR_BIT(ah, AR_MCI_TX_CTRL,
			    AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
		REG_CLR_BIT(ah, AR_PHY_GLB_CONTROL,
			    AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL);

		if (!(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA))
			ar9003_mci_osla_setup(ah, true);

		if (AR_SREV_9462(ah))
			REG_WRITE(ah, AR_SELFGEN_MASK, 0x02);
	} else {
		ar9003_mci_send_lna_take(ah, true);
		udelay(5);

		REG_SET_BIT(ah, AR_MCI_TX_CTRL,
			    AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
		REG_SET_BIT(ah, AR_PHY_GLB_CONTROL,
			    AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL);

		ar9003_mci_osla_setup(ah, false);
		ar9003_mci_send_2g5g_status(ah, true);
	}
}

bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag,
			     u32 *payload, u8 len, bool wait_done,
			     bool check_bt)
{
	struct ath_common *common = ath9k_hw_common(ah);
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
	bool msg_sent = false;
	u32 regval;
	u32 saved_mci_int_en;
	int i;

	saved_mci_int_en = REG_READ(ah, AR_MCI_INTERRUPT_EN);
	regval = REG_READ(ah, AR_BTCOEX_CTRL);

	if ((regval == 0xdeadbeef) || !(regval & AR_BTCOEX_CTRL_MCI_MODE_EN)) {
		ath_dbg(common, MCI,
			"MCI Not sending 0x%x. MCI is not enabled. full_sleep = %d\n",
			header, (ah->power_mode == ATH9K_PM_FULL_SLEEP) ? 1 : 0);
		ar9003_mci_queue_unsent_gpm(ah, header, payload, true);
		return false;
	} else if (check_bt && (mci->bt_state == MCI_BT_SLEEP)) {
		ath_dbg(common, MCI,
			"MCI Don't send message 0x%x. BT is in sleep state\n",
			header);
		ar9003_mci_queue_unsent_gpm(ah, header, payload, true);
		return false;
	}

	if (wait_done)
		REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0);

	/* Need to clear SW_MSG_DONE raw bit before wait */

	REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
		  (AR_MCI_INTERRUPT_SW_MSG_DONE |
		   AR_MCI_INTERRUPT_MSG_FAIL_MASK));

	if (payload) {
		for (i = 0; (i * 4) < len; i++)
			REG_WRITE(ah, (AR_MCI_TX_PAYLOAD0 + i * 4),
				  *(payload + i));
	}

	REG_WRITE(ah, AR_MCI_COMMAND0,
		  (SM((flag & MCI_FLAG_DISABLE_TIMESTAMP),
		      AR_MCI_COMMAND0_DISABLE_TIMESTAMP) |
		   SM(len, AR_MCI_COMMAND0_LEN) |
		   SM(header, AR_MCI_COMMAND0_HEADER)));

	if (wait_done &&
	    !(ar9003_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RAW,
					    AR_MCI_INTERRUPT_SW_MSG_DONE, 500)))
		ar9003_mci_queue_unsent_gpm(ah, header, payload, true);
	else {
		ar9003_mci_queue_unsent_gpm(ah, header, payload, false);
		msg_sent = true;
	}

	if (wait_done)
		REG_WRITE(ah, AR_MCI_INTERRUPT_EN, saved_mci_int_en);

	return msg_sent;
}
EXPORT_SYMBOL(ar9003_mci_send_message);

void ar9003_mci_init_cal_req(struct ath_hw *ah, bool *is_reusable)
{
	struct ath_common *common = ath9k_hw_common(ah);
	struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
	u32 pld[4] = {0, 0, 0, 0};

	if ((mci_hw->bt_state != MCI_BT_AWAKE) ||
	    (mci_hw->config & ATH_MCI_CONFIG_DISABLE_MCI_CAL))
		return;

	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);

	if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_GRANT, 0, 50000)) {
		ath_dbg(common, MCI, "MCI BT_CAL_GRANT received\n");
	} else {
		*is_reusable = false;
		ath_dbg(common, MCI, "MCI BT_CAL_GRANT not received\n");
	}
}

void ar9003_mci_init_cal_done(struct ath_hw *ah)
{
	struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
	u32 pld[4] = {0, 0, 0, 0};

	if ((mci_hw->bt_state != MCI_BT_AWAKE) ||
	    (mci_hw->config & ATH_MCI_CONFIG_DISABLE_MCI_CAL))
		return;

	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);
}

int ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
		     u16 len, u32 sched_addr)
{
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;

	mci->gpm_addr = gpm_addr;
	mci->gpm_buf = gpm_buf;
	mci->gpm_len = len;
	mci->sched_addr = sched_addr;

	return ar9003_mci_reset(ah, true, true, true);
}
EXPORT_SYMBOL(ar9003_mci_setup);

void ar9003_mci_cleanup(struct ath_hw *ah)
{
	/* Turn off MCI and Jupiter mode. */
	REG_WRITE(ah, AR_BTCOEX_CTRL, 0x00);
	ar9003_mci_disable_interrupt(ah);
}
EXPORT_SYMBOL(ar9003_mci_cleanup);

u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type)
{
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
	u32 value = 0, tsf;
	u8 query_type;

	switch (state_type) {
	case MCI_STATE_ENABLE:
		if (mci->ready) {
			value = REG_READ(ah, AR_BTCOEX_CTRL);

			if ((value == 0xdeadbeef) || (value == 0xffffffff))
				value = 0;
		}
		value &= AR_BTCOEX_CTRL_MCI_MODE_EN;
		break;
	case MCI_STATE_INIT_GPM_OFFSET:
		value = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);

		if (value < mci->gpm_len)
			mci->gpm_idx = value;
		else
			mci->gpm_idx = 0;
		break;
	case MCI_STATE_LAST_SCHD_MSG_OFFSET:
		value = MS(REG_READ(ah, AR_MCI_RX_STATUS),
				    AR_MCI_RX_LAST_SCHD_MSG_INDEX);
		/* Make it in bytes */
		value <<= 4;
		break;
	case MCI_STATE_REMOTE_SLEEP:
		value = MS(REG_READ(ah, AR_MCI_RX_STATUS),
			   AR_MCI_RX_REMOTE_SLEEP) ?
			MCI_BT_SLEEP : MCI_BT_AWAKE;
		break;
	case MCI_STATE_SET_BT_AWAKE:
		mci->bt_state = MCI_BT_AWAKE;
		ar9003_mci_send_coex_version_query(ah, true);
		ar9003_mci_send_coex_wlan_channels(ah, true);

		if (mci->unhalt_bt_gpm)
			ar9003_mci_send_coex_halt_bt_gpm(ah, false, true);

		ar9003_mci_2g5g_switch(ah, false);
		break;
	case MCI_STATE_RESET_REQ_WAKE:
		ar9003_mci_reset_req_wakeup(ah);
		mci->update_2g5g = true;

		if (mci->config & ATH_MCI_CONFIG_MCI_OBS_MASK) {
			/* Check if we still have control of the GPIOs */
			if ((REG_READ(ah, AR_GLB_GPIO_CONTROL) &
			     ATH_MCI_CONFIG_MCI_OBS_GPIO) !=
			    ATH_MCI_CONFIG_MCI_OBS_GPIO) {
				ar9003_mci_observation_set_up(ah);
			}
		}
		break;
	case MCI_STATE_SEND_WLAN_COEX_VERSION:
		ar9003_mci_send_coex_version_response(ah, true);
		break;
	case MCI_STATE_SEND_VERSION_QUERY:
		ar9003_mci_send_coex_version_query(ah, true);
		break;
	case MCI_STATE_SEND_STATUS_QUERY:
		query_type = MCI_GPM_COEX_QUERY_BT_TOPOLOGY;
		ar9003_mci_send_coex_bt_status_query(ah, true, query_type);
		break;
	case MCI_STATE_RECOVER_RX:
		tsf = ath9k_hw_gettsf32(ah);
		if ((tsf - mci->last_recovery) <= MCI_RECOVERY_DUR_TSF) {
			ath_dbg(ath9k_hw_common(ah), MCI,
				"(MCI) ignore Rx recovery\n");
			break;
		}
		ath_dbg(ath9k_hw_common(ah), MCI, "(MCI) RECOVER RX\n");
		mci->last_recovery = tsf;
		ar9003_mci_prep_interface(ah);
		mci->query_bt = true;
		mci->need_flush_btinfo = true;
		ar9003_mci_send_coex_wlan_channels(ah, true);
		ar9003_mci_2g5g_switch(ah, false);
		break;
	case MCI_STATE_NEED_FTP_STOMP:
		value = !(mci->config & ATH_MCI_CONFIG_DISABLE_FTP_STOMP);
		break;
	case MCI_STATE_NEED_FLUSH_BT_INFO:
		value = (!mci->unhalt_bt_gpm && mci->need_flush_btinfo) ? 1 : 0;
		mci->need_flush_btinfo = false;
		break;
	case MCI_STATE_AIC_CAL:
		if (ath9k_hw_is_aic_enabled(ah))
			value = ar9003_aic_calibration(ah);
		break;
	case MCI_STATE_AIC_START:
		if (ath9k_hw_is_aic_enabled(ah))
			ar9003_aic_start_normal(ah);
		break;
	case MCI_STATE_AIC_CAL_RESET:
		if (ath9k_hw_is_aic_enabled(ah))
			value = ar9003_aic_cal_reset(ah);
		break;
	case MCI_STATE_AIC_CAL_SINGLE:
		if (ath9k_hw_is_aic_enabled(ah))
			value = ar9003_aic_calibration_single(ah);
		break;
	default:
		break;
	}

	return value;
}
EXPORT_SYMBOL(ar9003_mci_state);

void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah)
{
	struct ath_common *common = ath9k_hw_common(ah);
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;

	ath_dbg(common, MCI, "Give LNA and SPDT control to BT\n");

	ar9003_mci_send_lna_take(ah, true);
	udelay(50);

	REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL);
	mci->is_2g = false;
	mci->update_2g5g = true;
	ar9003_mci_send_2g5g_status(ah, true);

	/* Force another 2g5g update at next scanning */
	mci->update_2g5g = true;
}

void ar9003_mci_set_power_awake(struct ath_hw *ah)
{
	u32 btcoex_ctrl2, diag_sw;
	int i;
	u8 lna_ctrl, bt_sleep;

	for (i = 0; i < AH_WAIT_TIMEOUT; i++) {
		btcoex_ctrl2 = REG_READ(ah, AR_BTCOEX_CTRL2);
		if (btcoex_ctrl2 != 0xdeadbeef)
			break;
		udelay(AH_TIME_QUANTUM);
	}
	REG_WRITE(ah, AR_BTCOEX_CTRL2, (btcoex_ctrl2 | BIT(23)));

	for (i = 0; i < AH_WAIT_TIMEOUT; i++) {
		diag_sw = REG_READ(ah, AR_DIAG_SW);
		if (diag_sw != 0xdeadbeef)
			break;
		udelay(AH_TIME_QUANTUM);
	}
	REG_WRITE(ah, AR_DIAG_SW, (diag_sw | BIT(27) | BIT(19) | BIT(18)));
	lna_ctrl = REG_READ(ah, AR_OBS_BUS_CTRL) & 0x3;
	bt_sleep = MS(REG_READ(ah, AR_MCI_RX_STATUS), AR_MCI_RX_REMOTE_SLEEP);

	REG_WRITE(ah, AR_BTCOEX_CTRL2, btcoex_ctrl2);
	REG_WRITE(ah, AR_DIAG_SW, diag_sw);

	if (bt_sleep && (lna_ctrl == 2)) {
		REG_SET_BIT(ah, AR_BTCOEX_RC, 0x1);
		REG_CLR_BIT(ah, AR_BTCOEX_RC, 0x1);
		udelay(50);
	}
}

void ar9003_mci_check_gpm_offset(struct ath_hw *ah)
{
	struct ath_common *common = ath9k_hw_common(ah);
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
	u32 offset;

	/*
	 * This should only be called before "MAC Warm Reset" or "MCI Reset Rx".
	 */
	offset = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
	if (mci->gpm_idx == offset)
		return;
	ath_dbg(common, MCI, "GPM cached write pointer mismatch %d %d\n",
		mci->gpm_idx, offset);
	mci->query_bt = true;
	mci->need_flush_btinfo = true;
	mci->gpm_idx = 0;
}

u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, u32 *more)
{
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
	u32 offset, more_gpm = 0, gpm_ptr;

	/*
	 * This could be useful to avoid new GPM message interrupt which
	 * may lead to spurious interrupt after power sleep, or multiple
	 * entry of ath_mci_intr().
	 * Adding empty GPM check by returning HAL_MCI_GPM_INVALID can
	 * alleviate this effect, but clearing GPM RX interrupt bit is
	 * safe, because whether this is called from hw or driver code
	 * there must be an interrupt bit set/triggered initially
	 */
	REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
			AR_MCI_INTERRUPT_RX_MSG_GPM);

	gpm_ptr = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
	offset = gpm_ptr;

	if (!offset)
		offset = mci->gpm_len - 1;
	else if (offset >= mci->gpm_len) {
		if (offset != 0xFFFF)
			offset = 0;
	} else {
		offset--;
	}

	if ((offset == 0xFFFF) || (gpm_ptr == mci->gpm_idx)) {
		offset = MCI_GPM_INVALID;
		more_gpm = MCI_GPM_NOMORE;
		goto out;
	}
	for (;;) {
		u32 temp_index;

		/* skip reserved GPM if any */

		if (offset != mci->gpm_idx)
			more_gpm = MCI_GPM_MORE;
		else
			more_gpm = MCI_GPM_NOMORE;

		temp_index = mci->gpm_idx;

		if (temp_index >= mci->gpm_len)
			temp_index = 0;

		mci->gpm_idx++;

		if (mci->gpm_idx >= mci->gpm_len)
			mci->gpm_idx = 0;

		if (ar9003_mci_is_gpm_valid(ah, temp_index)) {
			offset = temp_index;
			break;
		}

		if (more_gpm == MCI_GPM_NOMORE) {
			offset = MCI_GPM_INVALID;
			break;
		}
	}

	if (offset != MCI_GPM_INVALID)
		offset <<= 4;
out:
	if (more)
		*more = more_gpm;

	return offset;
}
EXPORT_SYMBOL(ar9003_mci_get_next_gpm_offset);

void ar9003_mci_set_bt_version(struct ath_hw *ah, u8 major, u8 minor)
{
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;

	mci->bt_ver_major = major;
	mci->bt_ver_minor = minor;
	mci->bt_version_known = true;
	ath_dbg(ath9k_hw_common(ah), MCI, "MCI BT version set: %d.%d\n",
		mci->bt_ver_major, mci->bt_ver_minor);
}
EXPORT_SYMBOL(ar9003_mci_set_bt_version);

void ar9003_mci_send_wlan_channels(struct ath_hw *ah)
{
	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;

	mci->wlan_channels_update = true;
	ar9003_mci_send_coex_wlan_channels(ah, true);
}
EXPORT_SYMBOL(ar9003_mci_send_wlan_channels);

u16 ar9003_mci_get_max_txpower(struct ath_hw *ah, u8 ctlmode)
{
	if (!ah->btcoex_hw.mci.concur_tx)
		goto out;

	if (ctlmode == CTL_2GHT20)
		return ATH_BTCOEX_HT20_MAX_TXPOWER;
	else if (ctlmode == CTL_2GHT40)
		return ATH_BTCOEX_HT40_MAX_TXPOWER;

out:
	return -1;
}
