diff options
Diffstat (limited to 'drivers/net/wireless/rtlwifi/btcoexist')
| -rw-r--r-- | drivers/net/wireless/rtlwifi/btcoexist/Makefile | 7 | ||||
| -rw-r--r-- | drivers/net/wireless/rtlwifi/btcoexist/halbt_precomp.h | 75 | ||||
| -rw-r--r-- | drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c | 3698 | ||||
| -rw-r--r-- | drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.h | 173 | ||||
| -rw-r--r-- | drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c | 1001 | ||||
| -rw-r--r-- | drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h | 559 | ||||
| -rw-r--r-- | drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.c | 218 | ||||
| -rw-r--r-- | drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.h | 52 | 
8 files changed, 5783 insertions, 0 deletions
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/Makefile b/drivers/net/wireless/rtlwifi/btcoexist/Makefile new file mode 100644 index 00000000000..47ceecfcb7d --- /dev/null +++ b/drivers/net/wireless/rtlwifi/btcoexist/Makefile @@ -0,0 +1,7 @@ +btcoexist-objs :=	halbtc8723b2ant.o	\ +			halbtcoutsrc.o		\ +			rtl_btc.o + +obj-$(CONFIG_RTLBTCOEXIST) += btcoexist.o + +ccflags-y += -D__CHECK_ENDIAN__ diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbt_precomp.h b/drivers/net/wireless/rtlwifi/btcoexist/halbt_precomp.h new file mode 100644 index 00000000000..d76684eb24d --- /dev/null +++ b/drivers/net/wireless/rtlwifi/btcoexist/halbt_precomp.h @@ -0,0 +1,75 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ + +#ifndef	__HALBT_PRECOMP_H__ +#define __HALBT_PRECOMP_H__ +/************************************************************* + * include files + *************************************************************/ +#include "../wifi.h" +#include "../efuse.h" +#include "../base.h" +#include "../regd.h" +#include "../cam.h" +#include "../ps.h" +#include "../pci.h" + +#include "halbtcoutsrc.h" + +#include "halbtc8723b2ant.h" + +#define BIT0	0x00000001 +#define BIT1	0x00000002 +#define BIT2	0x00000004 +#define BIT3	0x00000008 +#define BIT4	0x00000010 +#define BIT5	0x00000020 +#define BIT6	0x00000040 +#define BIT7	0x00000080 +#define BIT8	0x00000100 +#define BIT9	0x00000200 +#define BIT10	0x00000400 +#define BIT11	0x00000800 +#define BIT12	0x00001000 +#define BIT13	0x00002000 +#define BIT14	0x00004000 +#define BIT15	0x00008000 +#define BIT16	0x00010000 +#define BIT17	0x00020000 +#define BIT18	0x00040000 +#define BIT19	0x00080000 +#define BIT20	0x00100000 +#define BIT21	0x00200000 +#define BIT22	0x00400000 +#define BIT23	0x00800000 +#define BIT24	0x01000000 +#define BIT25	0x02000000 +#define BIT26	0x04000000 +#define BIT27	0x08000000 +#define BIT28	0x10000000 +#define BIT29	0x20000000 +#define BIT30	0x40000000 +#define BIT31	0x80000000 + +#endif	/* __HALBT_PRECOMP_H__ */ diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c new file mode 100644 index 00000000000..d916ab9f3c3 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c @@ -0,0 +1,3698 @@ +/****************************************************************************** + * + * Copyright(c) 2012  Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger <Larry.Finger@lwfinger.net> + * + *****************************************************************************/ +/*************************************************************** + * Description: + * + * This file is for RTL8723B Co-exist mechanism + * + * History + * 2012/11/15 Cosa first check in. + * + **************************************************************/ +/************************************************************** + * include files + **************************************************************/ +#include "halbt_precomp.h" +/************************************************************** + * Global variables, these are static variables + **************************************************************/ +static struct coex_dm_8723b_2ant glcoex_dm_8723b_2ant; +static struct coex_dm_8723b_2ant *coex_dm = &glcoex_dm_8723b_2ant; +static struct coex_sta_8723b_2ant glcoex_sta_8723b_2ant; +static struct coex_sta_8723b_2ant *coex_sta = &glcoex_sta_8723b_2ant; + +static const char *const glbt_info_src_8723b_2ant[] = { +	"BT Info[wifi fw]", +	"BT Info[bt rsp]", +	"BT Info[bt auto report]", +}; + +static u32 glcoex_ver_date_8723b_2ant = 20130731; +static u32 glcoex_ver_8723b_2ant = 0x3b; + +/************************************************************** + * local function proto type if needed + **************************************************************/ +/************************************************************** + * local function start with btc8723b2ant_ + **************************************************************/ +static u8 btc8723b2ant_bt_rssi_state(u8 level_num, u8 rssi_thresh, +				     u8 rssi_thresh1) +{ +	s32 bt_rssi = 0; +	u8 bt_rssi_state = coex_sta->pre_bt_rssi_state; + +	bt_rssi = coex_sta->bt_rssi; + +	if (level_num == 2) { +		if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) || +		    (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { +			if (bt_rssi >= rssi_thresh + +				       BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT) { +				bt_rssi_state = BTC_RSSI_STATE_HIGH; +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, +					  "[BTCoex], BT Rssi state " +					  "switch to High\n"); +			} else { +				bt_rssi_state = BTC_RSSI_STATE_STAY_LOW; +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, +					  "[BTCoex], BT Rssi state " +					  "stay at Low\n"); +			} +		} else { +			if (bt_rssi < rssi_thresh) { +				bt_rssi_state = BTC_RSSI_STATE_LOW; +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, +					  "[BTCoex], BT Rssi state " +					  "switch to Low\n"); +			} else { +				bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH; +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, +					  "[BTCoex], BT Rssi state " +					  "stay at High\n"); +			} +		} +	} else if (level_num == 3) { +		if (rssi_thresh > rssi_thresh1) { +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, +				  "[BTCoex], BT Rssi thresh error!!\n"); +			return coex_sta->pre_bt_rssi_state; +		} + +		if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) || +		    (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { +			if (bt_rssi >= rssi_thresh + +				       BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT) { +				bt_rssi_state = BTC_RSSI_STATE_MEDIUM; +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, +					  "[BTCoex], BT Rssi state " +					  "switch to Medium\n"); +			} else { +				bt_rssi_state = BTC_RSSI_STATE_STAY_LOW; +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, +					  "[BTCoex], BT Rssi state " +					  "stay at Low\n"); +			} +		} else if ((coex_sta->pre_bt_rssi_state == +						BTC_RSSI_STATE_MEDIUM) || +			   (coex_sta->pre_bt_rssi_state == +						BTC_RSSI_STATE_STAY_MEDIUM)) { +			if (bt_rssi >= rssi_thresh1 + +				       BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT) { +				bt_rssi_state = BTC_RSSI_STATE_HIGH; +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, +					  "[BTCoex], BT Rssi state " +					  "switch to High\n"); +			} else if (bt_rssi < rssi_thresh) { +				bt_rssi_state = BTC_RSSI_STATE_LOW; +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, +					  "[BTCoex], BT Rssi state " +					  "switch to Low\n"); +			} else { +				bt_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM; +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, +					  "[BTCoex], BT Rssi state " +					  "stay at Medium\n"); +			} +		} else { +			if (bt_rssi < rssi_thresh1) { +				bt_rssi_state = BTC_RSSI_STATE_MEDIUM; +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, +					  "[BTCoex], BT Rssi state " +					  "switch to Medium\n"); +			} else { +				bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH; +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, +					  "[BTCoex], BT Rssi state " +					  "stay at High\n"); +			} +		} +	} + +	coex_sta->pre_bt_rssi_state = bt_rssi_state; + +	return bt_rssi_state; +} + +static u8 btc8723b2ant_wifi_rssi_state(struct btc_coexist *btcoexist, +				       u8 index, u8 level_num, +				       u8 rssi_thresh, u8 rssi_thresh1) +{ +	s32 wifi_rssi = 0; +	u8 wifi_rssi_state = coex_sta->pre_wifi_rssi_state[index]; + +	btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); + +	if (level_num == 2) { +		if ((coex_sta->pre_wifi_rssi_state[index] == +						BTC_RSSI_STATE_LOW) || +		    (coex_sta->pre_wifi_rssi_state[index] == +						BTC_RSSI_STATE_STAY_LOW)) { +			if (wifi_rssi >= rssi_thresh + +					 BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT) { +				wifi_rssi_state = BTC_RSSI_STATE_HIGH; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_WIFI_RSSI_STATE, +					  "[BTCoex], wifi RSSI state " +					  "switch to High\n"); +			} else { +				wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_WIFI_RSSI_STATE, +					  "[BTCoex], wifi RSSI state " +					  "stay at Low\n"); +			} +		} else { +			if (wifi_rssi < rssi_thresh) { +				wifi_rssi_state = BTC_RSSI_STATE_LOW; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_WIFI_RSSI_STATE, +					  "[BTCoex], wifi RSSI state " +					  "switch to Low\n"); +			} else { +				wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_WIFI_RSSI_STATE, +					  "[BTCoex], wifi RSSI state " +					  "stay at High\n"); +			} +		} +	} else if (level_num == 3) { +		if (rssi_thresh > rssi_thresh1) { +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, +				  "[BTCoex], wifi RSSI thresh error!!\n"); +			return coex_sta->pre_wifi_rssi_state[index]; +		} + +		if ((coex_sta->pre_wifi_rssi_state[index] == +						BTC_RSSI_STATE_LOW) || +		    (coex_sta->pre_wifi_rssi_state[index] == +						BTC_RSSI_STATE_STAY_LOW)) { +			if (wifi_rssi >= rssi_thresh + +					BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT) { +				wifi_rssi_state = BTC_RSSI_STATE_MEDIUM; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_WIFI_RSSI_STATE, +					  "[BTCoex], wifi RSSI state " +					  "switch to Medium\n"); +			} else { +				wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_WIFI_RSSI_STATE, +					  "[BTCoex], wifi RSSI state " +					  "stay at Low\n"); +			} +		} else if ((coex_sta->pre_wifi_rssi_state[index] == +						BTC_RSSI_STATE_MEDIUM) || +			   (coex_sta->pre_wifi_rssi_state[index] == +						BTC_RSSI_STATE_STAY_MEDIUM)) { +			if (wifi_rssi >= rssi_thresh1 + +					 BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT) { +				wifi_rssi_state = BTC_RSSI_STATE_HIGH; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_WIFI_RSSI_STATE, +					  "[BTCoex], wifi RSSI state " +					  "switch to High\n"); +			} else if (wifi_rssi < rssi_thresh) { +				wifi_rssi_state = BTC_RSSI_STATE_LOW; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_WIFI_RSSI_STATE, +					  "[BTCoex], wifi RSSI state " +					  "switch to Low\n"); +			} else { +				wifi_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_WIFI_RSSI_STATE, +					  "[BTCoex], wifi RSSI state " +					  "stay at Medium\n"); +			} +		} else { +			if (wifi_rssi < rssi_thresh1) { +				wifi_rssi_state = BTC_RSSI_STATE_MEDIUM; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_WIFI_RSSI_STATE, +					  "[BTCoex], wifi RSSI state " +					  "switch to Medium\n"); +			} else { +				wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_WIFI_RSSI_STATE, +					  "[BTCoex], wifi RSSI state " +					  "stay at High\n"); +			} +		} +	} + +	coex_sta->pre_wifi_rssi_state[index] = wifi_rssi_state; + +	return wifi_rssi_state; +} + +static void btc8723b2ant_monitor_bt_ctr(struct btc_coexist *btcoexist) +{ +	u32 reg_hp_txrx, reg_lp_txrx, u32tmp; +	u32 reg_hp_tx = 0, reg_hp_rx = 0; +	u32 reg_lp_tx = 0, reg_lp_rx = 0; + +	reg_hp_txrx = 0x770; +	reg_lp_txrx = 0x774; + +	u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_hp_txrx); +	reg_hp_tx = u32tmp & MASKLWORD; +	reg_hp_rx = (u32tmp & MASKHWORD) >> 16; + +	u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_lp_txrx); +	reg_lp_tx = u32tmp & MASKLWORD; +	reg_lp_rx = (u32tmp & MASKHWORD) >> 16; + +	coex_sta->high_priority_tx = reg_hp_tx; +	coex_sta->high_priority_rx = reg_hp_rx; +	coex_sta->low_priority_tx = reg_lp_tx; +	coex_sta->low_priority_rx = reg_lp_rx; + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, +		  "[BTCoex], High Priority Tx/Rx(reg 0x%x)=0x%x(%d)/0x%x(%d)\n", +		  reg_hp_txrx, reg_hp_tx, reg_hp_tx, reg_hp_rx, reg_hp_rx); +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, +		  "[BTCoex], Low Priority Tx/Rx(reg 0x%x)=0x%x(%d)/0x%x(%d)\n", +		  reg_lp_txrx, reg_lp_tx, reg_lp_tx, reg_lp_rx, reg_lp_rx); + +	/* reset counter */ +	btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc); +} + +static bool btc8723b2ant_is_wifi_status_changed(struct btc_coexist *btcoexist) +{ +	static bool pre_wifi_busy; +	static bool pre_under_4way; +	static bool pre_bt_hs_on; +	bool wifi_busy = false, under_4way = false, bt_hs_on = false; +	bool wifi_connected = false; + +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, +			   &wifi_connected); +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); +	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, +			   &under_4way); + +	if (wifi_connected) { +		if (wifi_busy != pre_wifi_busy) { +			pre_wifi_busy = wifi_busy; +			return true; +		} + +		if (under_4way != pre_under_4way) { +			pre_under_4way = under_4way; +			return true; +		} + +		if (bt_hs_on != pre_bt_hs_on) { +			pre_bt_hs_on = bt_hs_on; +			return true; +		} +	} + +	return false; +} + +static void btc8723b2ant_update_bt_link_info(struct btc_coexist *btcoexist) +{ +	/*struct btc_stack_info *stack_info = &btcoexist->stack_info;*/ +	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; +	bool bt_hs_on = false; + +#if (BT_AUTO_REPORT_ONLY_8723B_2ANT == 1) /* profile from bt patch */ +	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + +	bt_link_info->bt_link_exist = coex_sta->bt_link_exist; +	bt_link_info->sco_exist = coex_sta->sco_exist; +	bt_link_info->a2dp_exist = coex_sta->a2dp_exist; +	bt_link_info->pan_exist = coex_sta->pan_exist; +	bt_link_info->hid_exist = coex_sta->hid_exist; + +	/* work around for HS mode. */ +	if (bt_hs_on) { +		bt_link_info->pan_exist = true; +		bt_link_info->bt_link_exist = true; +	} +#else	/* profile from bt stack */ +	bt_link_info->bt_link_exist = stack_info->bt_link_exist; +	bt_link_info->sco_exist = stack_info->sco_exist; +	bt_link_info->a2dp_exist = stack_info->a2dp_exist; +	bt_link_info->pan_exist = stack_info->pan_exist; +	bt_link_info->hid_exist = stack_info->hid_exist; + +	/*for win-8 stack HID report error*/ +	if (!stack_info->hid_exist) +		stack_info->hid_exist = coex_sta->hid_exist; +	/*sync  BTInfo with BT firmware and stack*/ +	/* when stack HID report error, here we use the info from bt fw.*/ +	if (!stack_info->bt_link_exist) +		stack_info->bt_link_exist = coex_sta->bt_link_exist; +#endif +	/* check if Sco only */ +	if (bt_link_info->sco_exist && !bt_link_info->a2dp_exist && +	    !bt_link_info->pan_exist && !bt_link_info->hid_exist) +		bt_link_info->sco_only = true; +	else +		bt_link_info->sco_only = false; + +	/* check if A2dp only */ +	if (!bt_link_info->sco_exist && bt_link_info->a2dp_exist && +	    !bt_link_info->pan_exist && !bt_link_info->hid_exist) +		bt_link_info->a2dp_only = true; +	else +		bt_link_info->a2dp_only = false; + +	/* check if Pan only */ +	if (!bt_link_info->sco_exist && !bt_link_info->a2dp_exist && +	    bt_link_info->pan_exist && !bt_link_info->hid_exist) +		bt_link_info->pan_only = true; +	else +		bt_link_info->pan_only = false; + +	/* check if Hid only */ +	if (!bt_link_info->sco_exist && !bt_link_info->a2dp_exist && +	    !bt_link_info->pan_exist && bt_link_info->hid_exist) +		bt_link_info->hid_only = true; +	else +		bt_link_info->hid_only = false; +} + +static u8 btc8723b2ant_action_algorithm(struct btc_coexist *btcoexist) +{ +	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; +	bool bt_hs_on = false; +	u8 algorithm = BT_8723B_2ANT_COEX_ALGO_UNDEFINED; +	u8 num_of_diff_profile = 0; + +	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + +	if (!bt_link_info->bt_link_exist) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +			  "[BTCoex], No BT link exists!!!\n"); +		return algorithm; +	} + +	if (bt_link_info->sco_exist) +		num_of_diff_profile++; +	if (bt_link_info->hid_exist) +		num_of_diff_profile++; +	if (bt_link_info->pan_exist) +		num_of_diff_profile++; +	if (bt_link_info->a2dp_exist) +		num_of_diff_profile++; + +	if (num_of_diff_profile == 1) { +		if (bt_link_info->sco_exist) { +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], SCO only\n"); +			algorithm = BT_8723B_2ANT_COEX_ALGO_SCO; +		} else { +			if (bt_link_info->hid_exist) { +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +					  "[BTCoex], HID only\n"); +				algorithm = BT_8723B_2ANT_COEX_ALGO_HID; +			} else if (bt_link_info->a2dp_exist) { +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +					  "[BTCoex], A2DP only\n"); +				algorithm = BT_8723B_2ANT_COEX_ALGO_A2DP; +			} else if (bt_link_info->pan_exist) { +				if (bt_hs_on) { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], PAN(HS) only\n"); +					algorithm = +						BT_8723B_2ANT_COEX_ALGO_PANHS; +				} else { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], PAN(EDR) only\n"); +					algorithm = +						BT_8723B_2ANT_COEX_ALGO_PANEDR; +				} +			} +		} +	} else if (num_of_diff_profile == 2) { +		if (bt_link_info->sco_exist) { +			if (bt_link_info->hid_exist) { +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +					  "[BTCoex], SCO + HID\n"); +				algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; +			} else if (bt_link_info->a2dp_exist) { +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +					  "[BTCoex], SCO + A2DP ==> SCO\n"); +				algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; +			} else if (bt_link_info->pan_exist) { +				if (bt_hs_on) { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], SCO + PAN(HS)\n"); +					algorithm = BT_8723B_2ANT_COEX_ALGO_SCO; +				} else { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], SCO + PAN(EDR)\n"); +					algorithm = +					    BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; +				} +			} +		} else { +			if (bt_link_info->hid_exist && +			    bt_link_info->a2dp_exist) { +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +					  "[BTCoex], HID + A2DP\n"); +				algorithm = BT_8723B_2ANT_COEX_ALGO_HID_A2DP; +			} else if (bt_link_info->hid_exist && +				   bt_link_info->pan_exist) { +				if (bt_hs_on) { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], HID + PAN(HS)\n"); +					algorithm = BT_8723B_2ANT_COEX_ALGO_HID; +				} else { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], HID + PAN(EDR)\n"); +					algorithm = +					    BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; +				} +			} else if (bt_link_info->pan_exist && +				   bt_link_info->a2dp_exist) { +				if (bt_hs_on) { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], A2DP + PAN(HS)\n"); +					algorithm = +					    BT_8723B_2ANT_COEX_ALGO_A2DP_PANHS; +				} else { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex],A2DP + PAN(EDR)\n"); +					algorithm = +					    BT_8723B_2ANT_COEX_ALGO_PANEDR_A2DP; +				} +			} +		} +	} else if (num_of_diff_profile == 3) { +		if (bt_link_info->sco_exist) { +			if (bt_link_info->hid_exist && +			    bt_link_info->a2dp_exist) { +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +					  "[BTCoex], SCO + HID + A2DP" +					  " ==> HID\n"); +				algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; +			} else if (bt_link_info->hid_exist && +				   bt_link_info->pan_exist) { +				if (bt_hs_on) { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], SCO + HID + " +						  "PAN(HS)\n"); +					algorithm = +					    BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; +				} else { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], SCO + HID + " +						  "PAN(EDR)\n"); +					algorithm = +					    BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; +				} +			} else if (bt_link_info->pan_exist && +				   bt_link_info->a2dp_exist) { +				if (bt_hs_on) { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], SCO + A2DP + " +						  "PAN(HS)\n"); +					algorithm = +					    BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; +				} else { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], SCO + A2DP + " +						  "PAN(EDR) ==> HID\n"); +					algorithm = +					    BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; +				} +			} +		} else { +			if (bt_link_info->hid_exist && +			    bt_link_info->pan_exist && +			    bt_link_info->a2dp_exist) { +				if (bt_hs_on) { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], HID + A2DP + " +						  "PAN(HS)\n"); +					algorithm = +					    BT_8723B_2ANT_COEX_ALGO_HID_A2DP; +				} else { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], HID + A2DP + " +						  "PAN(EDR)\n"); +					algorithm = +					BT_8723B_2ANT_COEX_ALGO_HID_A2DP_PANEDR; +				} +			} +		} +	} else if (num_of_diff_profile >= 3) { +		if (bt_link_info->sco_exist) { +			if (bt_link_info->hid_exist && +			    bt_link_info->pan_exist && +			    bt_link_info->a2dp_exist) { +				if (bt_hs_on) { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], Error!!! SCO + HID" +						  " + A2DP + PAN(HS)\n"); +				} else { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], SCO + HID + A2DP +" +						  " PAN(EDR)==>PAN(EDR)+HID\n"); +					algorithm = +					    BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; +				} +			} +		} +	} +	return algorithm; +} + +static bool btc8723b_need_dec_pwr(struct btc_coexist *btcoexist) +{ +	bool ret = false; +	bool bt_hs_on = false, wifi_connected = false; +	s32 bt_hs_rssi = 0; +	u8 bt_rssi_state; + +	if (!btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on)) +		return false; +	if (!btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, +				&wifi_connected)) +		return false; +	if (!btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi)) +		return false; + +	bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); + +	if (wifi_connected) { +		if (bt_hs_on) { +			if (bt_hs_rssi > 37) { +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, +					  "[BTCoex], Need to decrease bt " +					  "power for HS mode!!\n"); +				ret = true; +			} +		} else { +			if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || +			    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, +					  "[BTCoex], Need to decrease bt " +					  "power for Wifi is connected!!\n"); +				ret = true; +			} +		} +	} + +	return ret; +} + +static void btc8723b2ant_set_fw_dac_swing_level(struct btc_coexist *btcoexist, +						u8 dac_swing_lvl) +{ +	u8 h2c_parameter[1] = {0}; + +	/* There are several type of dacswing +	 * 0x18/ 0x10/ 0xc/ 0x8/ 0x4/ 0x6 +	 */ +	h2c_parameter[0] = dac_swing_lvl; + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, +		  "[BTCoex], Set Dac Swing Level=0x%x\n", dac_swing_lvl); +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, +		  "[BTCoex], FW write 0x64=0x%x\n", h2c_parameter[0]); + +	btcoexist->btc_fill_h2c(btcoexist, 0x64, 1, h2c_parameter); +} + +static void btc8723b2ant_set_fw_dec_bt_pwr(struct btc_coexist *btcoexist, +					   bool dec_bt_pwr) +{ +	u8 h2c_parameter[1] = {0}; + +	h2c_parameter[0] = 0; + +	if (dec_bt_pwr) +		h2c_parameter[0] |= BIT1; + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, +		  "[BTCoex], decrease Bt Power : %s, FW write 0x62=0x%x\n", +		  (dec_bt_pwr ? "Yes!!" : "No!!"), h2c_parameter[0]); + +	btcoexist->btc_fill_h2c(btcoexist, 0x62, 1, h2c_parameter); +} + +static void btc8723b2ant_dec_bt_pwr(struct btc_coexist *btcoexist, +				    bool force_exec, bool dec_bt_pwr) +{ +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, +		  "[BTCoex], %s Dec BT power = %s\n", +		  (force_exec ? "force to" : ""), (dec_bt_pwr ? "ON" : "OFF")); +	coex_dm->cur_dec_bt_pwr = dec_bt_pwr; + +	if (!force_exec) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], bPreDecBtPwr=%d, bCurDecBtPwr=%d\n", +			  coex_dm->pre_dec_bt_pwr, coex_dm->cur_dec_bt_pwr); + +		if (coex_dm->pre_dec_bt_pwr == coex_dm->cur_dec_bt_pwr) +			return; +	} +	btc8723b2ant_set_fw_dec_bt_pwr(btcoexist, coex_dm->cur_dec_bt_pwr); + +	coex_dm->pre_dec_bt_pwr = coex_dm->cur_dec_bt_pwr; +} + +static void btc8723b2ant_fw_dac_swing_lvl(struct btc_coexist *btcoexist, +					  bool force_exec, u8 fw_dac_swing_lvl) +{ +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, +		  "[BTCoex], %s set FW Dac Swing level = %d\n", +		  (force_exec ? "force to" : ""), fw_dac_swing_lvl); +	coex_dm->cur_fw_dac_swing_lvl = fw_dac_swing_lvl; + +	if (!force_exec) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], preFwDacSwingLvl=%d, " +			  "curFwDacSwingLvl=%d\n", +			  coex_dm->pre_fw_dac_swing_lvl, +			  coex_dm->cur_fw_dac_swing_lvl); + +		if (coex_dm->pre_fw_dac_swing_lvl == +		   coex_dm->cur_fw_dac_swing_lvl) +			return; +	} + +	btc8723b2ant_set_fw_dac_swing_level(btcoexist, +					    coex_dm->cur_fw_dac_swing_lvl); +	coex_dm->pre_fw_dac_swing_lvl = coex_dm->cur_fw_dac_swing_lvl; +} + +static void btc8723b2ant_set_sw_rf_rx_lpf_corner(struct btc_coexist *btcoexist, +						 bool rx_rf_shrink_on) +{ +	if (rx_rf_shrink_on) { +		/* Shrink RF Rx LPF corner */ +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +			  "[BTCoex], Shrink RF Rx LPF corner!!\n"); +		btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1e, +					  0xfffff, 0xffffc); +	} else { +		/* Resume RF Rx LPF corner */ +		/* After initialized, we can use coex_dm->btRf0x1eBackup */ +		if (btcoexist->initilized) { +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +				  "[BTCoex], Resume RF Rx LPF corner!!\n"); +			btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1e, +						  0xfffff, +						  coex_dm->bt_rf0x1e_backup); +		} +	} +} + +static void btc8723b2ant_rf_shrink(struct btc_coexist *btcoexist, +				   bool force_exec, bool rx_rf_shrink_on) +{ +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, +		  "[BTCoex], %s turn Rx RF Shrink = %s\n", +		  (force_exec ? "force to" : ""), (rx_rf_shrink_on ? +		  "ON" : "OFF")); +	coex_dm->cur_rf_rx_lpf_shrink = rx_rf_shrink_on; + +	if (!force_exec) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, +			  "[BTCoex], bPreRfRxLpfShrink=%d, " +			  "bCurRfRxLpfShrink=%d\n", +			  coex_dm->pre_rf_rx_lpf_shrink, +			  coex_dm->cur_rf_rx_lpf_shrink); + +		if (coex_dm->pre_rf_rx_lpf_shrink == +		    coex_dm->cur_rf_rx_lpf_shrink) +			return; +	} +	btc8723b2ant_set_sw_rf_rx_lpf_corner(btcoexist, +					     coex_dm->cur_rf_rx_lpf_shrink); + +	coex_dm->pre_rf_rx_lpf_shrink = coex_dm->cur_rf_rx_lpf_shrink; +} + +static void btc8723b_set_penalty_txrate(struct btc_coexist *btcoexist, +					bool low_penalty_ra) +{ +	u8 h2c_parameter[6] = {0}; + +	h2c_parameter[0] = 0x6;	/* opCode, 0x6= Retry_Penalty*/ + +	if (low_penalty_ra) { +		h2c_parameter[1] |= BIT0; +		/*normal rate except MCS7/6/5, OFDM54/48/36*/ +		h2c_parameter[2] = 0x00; +		h2c_parameter[3] = 0xf7;  /*MCS7 or OFDM54*/ +		h2c_parameter[4] = 0xf8;  /*MCS6 or OFDM48*/ +		h2c_parameter[5] = 0xf9;  /*MCS5 or OFDM36*/ +	} + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, +		  "[BTCoex], set WiFi Low-Penalty Retry: %s", +		  (low_penalty_ra ? "ON!!" : "OFF!!")); + +	btcoexist->btc_fill_h2c(btcoexist, 0x69, 6, h2c_parameter); +} + +static void btc8723b2ant_low_penalty_ra(struct btc_coexist *btcoexist, +					bool force_exec, bool low_penalty_ra) +{ +	/*return; */ +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, +		  "[BTCoex], %s turn LowPenaltyRA = %s\n", +		  (force_exec ? "force to" : ""), (low_penalty_ra ? +		  "ON" : "OFF")); +	coex_dm->cur_low_penalty_ra = low_penalty_ra; + +	if (!force_exec) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, +			  "[BTCoex], bPreLowPenaltyRa=%d, " +			  "bCurLowPenaltyRa=%d\n", +			  coex_dm->pre_low_penalty_ra, +			  coex_dm->cur_low_penalty_ra); + +		if (coex_dm->pre_low_penalty_ra == coex_dm->cur_low_penalty_ra) +			return; +	} +	btc8723b_set_penalty_txrate(btcoexist, coex_dm->cur_low_penalty_ra); + +	coex_dm->pre_low_penalty_ra = coex_dm->cur_low_penalty_ra; +} + +static void btc8723b2ant_set_dac_swing_reg(struct btc_coexist *btcoexist, +					   u32 level) +{ +	u8 val = (u8) level; +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +		  "[BTCoex], Write SwDacSwing = 0x%x\n", level); +	btcoexist->btc_write_1byte_bitmask(btcoexist, 0x883, 0x3e, val); +} + +static void btc8723b2ant_set_sw_fulltime_dac_swing(struct btc_coexist *btcoex, +						   bool sw_dac_swing_on, +						   u32 sw_dac_swing_lvl) +{ +	if (sw_dac_swing_on) +		btc8723b2ant_set_dac_swing_reg(btcoex, sw_dac_swing_lvl); +	else +		btc8723b2ant_set_dac_swing_reg(btcoex, 0x18); +} + + +static void btc8723b2ant_dac_swing(struct btc_coexist *btcoexist, +				   bool force_exec, bool dac_swing_on, +				   u32 dac_swing_lvl) +{ +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, +		  "[BTCoex], %s turn DacSwing=%s, dac_swing_lvl=0x%x\n", +		  (force_exec ? "force to" : ""), +		  (dac_swing_on ? "ON" : "OFF"), dac_swing_lvl); +	coex_dm->cur_dac_swing_on = dac_swing_on; +	coex_dm->cur_dac_swing_lvl = dac_swing_lvl; + +	if (!force_exec) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, +			  "[BTCoex], bPreDacSwingOn=%d, preDacSwingLvl=0x%x," +			  " bCurDacSwingOn=%d, curDacSwingLvl=0x%x\n", +			  coex_dm->pre_dac_swing_on, coex_dm->pre_dac_swing_lvl, +			  coex_dm->cur_dac_swing_on, +			  coex_dm->cur_dac_swing_lvl); + +		if ((coex_dm->pre_dac_swing_on == coex_dm->cur_dac_swing_on) && +		    (coex_dm->pre_dac_swing_lvl == coex_dm->cur_dac_swing_lvl)) +			return; +	} +	mdelay(30); +	btc8723b2ant_set_sw_fulltime_dac_swing(btcoexist, dac_swing_on, +					       dac_swing_lvl); + +	coex_dm->pre_dac_swing_on = coex_dm->cur_dac_swing_on; +	coex_dm->pre_dac_swing_lvl = coex_dm->cur_dac_swing_lvl; +} + +static void btc8723b2ant_set_agc_table(struct btc_coexist *btcoexist, +				       bool agc_table_en) +{ +	u8 rssi_adjust_val = 0; + +	/*  BB AGC Gain Table */ +	if (agc_table_en) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +			  "[BTCoex], BB Agc Table On!\n"); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x6e1A0001); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x6d1B0001); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x6c1C0001); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x6b1D0001); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x6a1E0001); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x691F0001); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x68200001); +	} else { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +			  "[BTCoex], BB Agc Table Off!\n"); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xaa1A0001); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa91B0001); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa81C0001); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa71D0001); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa61E0001); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa51F0001); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa4200001); +	} + + +	/* RF Gain */ +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0xef, 0xfffff, 0x02000); +	if (agc_table_en) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +			  "[BTCoex], Agc Table On!\n"); +		btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x3b, +					  0xfffff, 0x38fff); +		btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x3b, +					  0xfffff, 0x38ffe); +	} else { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +			  "[BTCoex], Agc Table Off!\n"); +		btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x3b, +					  0xfffff, 0x380c3); +		btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x3b, +					  0xfffff, 0x28ce6); +	} +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0xef, 0xfffff, 0x0); + +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0xed, 0xfffff, 0x1); + +	if (agc_table_en) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +			  "[BTCoex], Agc Table On!\n"); +		btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x40, +					  0xfffff, 0x38fff); +		btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x40, +					  0xfffff, 0x38ffe); +	} else { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +			  "[BTCoex], Agc Table Off!\n"); +		btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x40, +					  0xfffff, 0x380c3); +		btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x40, +					  0xfffff, 0x28ce6); +	} +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0xed, 0xfffff, 0x0); + +	/* set rssiAdjustVal for wifi module. */ +	if (agc_table_en) +		rssi_adjust_val = 8; +	btcoexist->btc_set(btcoexist, BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON, +			   &rssi_adjust_val); +} + +static void btc8723b2ant_agc_table(struct btc_coexist *btcoexist, +				   bool force_exec, bool agc_table_en) +{ +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, +		  "[BTCoex], %s %s Agc Table\n", +		  (force_exec ? "force to" : ""), +		  (agc_table_en ? "Enable" : "Disable")); +	coex_dm->cur_agc_table_en = agc_table_en; + +	if (!force_exec) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, +			  "[BTCoex], bPreAgcTableEn=%d, bCurAgcTableEn=%d\n", +			  coex_dm->pre_agc_table_en, coex_dm->cur_agc_table_en); + +		if (coex_dm->pre_agc_table_en == coex_dm->cur_agc_table_en) +			return; +	} +	btc8723b2ant_set_agc_table(btcoexist, agc_table_en); + +	coex_dm->pre_agc_table_en = coex_dm->cur_agc_table_en; +} + +static void btc8723b2ant_set_coex_table(struct btc_coexist *btcoexist, +					u32 val0x6c0, u32 val0x6c4, +					u32 val0x6c8, u8 val0x6cc) +{ +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +		  "[BTCoex], set coex table, set 0x6c0=0x%x\n", val0x6c0); +	btcoexist->btc_write_4byte(btcoexist, 0x6c0, val0x6c0); + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +		  "[BTCoex], set coex table, set 0x6c4=0x%x\n", val0x6c4); +	btcoexist->btc_write_4byte(btcoexist, 0x6c4, val0x6c4); + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +		  "[BTCoex], set coex table, set 0x6c8=0x%x\n", val0x6c8); +	btcoexist->btc_write_4byte(btcoexist, 0x6c8, val0x6c8); + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +		  "[BTCoex], set coex table, set 0x6cc=0x%x\n", val0x6cc); +	btcoexist->btc_write_1byte(btcoexist, 0x6cc, val0x6cc); +} + +static void btc8723b2ant_coex_table(struct btc_coexist *btcoexist, +				    bool force_exec, u32 val0x6c0, +				    u32 val0x6c4, u32 val0x6c8, +				    u8 val0x6cc) +{ +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, +		  "[BTCoex], %s write Coex Table 0x6c0=0x%x," +		  " 0x6c4=0x%x, 0x6c8=0x%x, 0x6cc=0x%x\n", +		  (force_exec ? "force to" : ""), val0x6c0, +		  val0x6c4, val0x6c8, val0x6cc); +	coex_dm->cur_val0x6c0 = val0x6c0; +	coex_dm->cur_val0x6c4 = val0x6c4; +	coex_dm->cur_val0x6c8 = val0x6c8; +	coex_dm->cur_val0x6cc = val0x6cc; + +	if (!force_exec) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, +			  "[BTCoex], preVal0x6c0=0x%x, " +			  "preVal0x6c4=0x%x, preVal0x6c8=0x%x, " +			  "preVal0x6cc=0x%x !!\n", +			  coex_dm->pre_val0x6c0, coex_dm->pre_val0x6c4, +			  coex_dm->pre_val0x6c8, coex_dm->pre_val0x6cc); +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, +			  "[BTCoex], curVal0x6c0=0x%x, " +			  "curVal0x6c4=0x%x, curVal0x6c8=0x%x, " +			  "curVal0x6cc=0x%x !!\n", +			  coex_dm->cur_val0x6c0, coex_dm->cur_val0x6c4, +			  coex_dm->cur_val0x6c8, coex_dm->cur_val0x6cc); + +		if ((coex_dm->pre_val0x6c0 == coex_dm->cur_val0x6c0) && +		    (coex_dm->pre_val0x6c4 == coex_dm->cur_val0x6c4) && +		    (coex_dm->pre_val0x6c8 == coex_dm->cur_val0x6c8) && +		    (coex_dm->pre_val0x6cc == coex_dm->cur_val0x6cc)) +			return; +	} +	btc8723b2ant_set_coex_table(btcoexist, val0x6c0, val0x6c4, +				    val0x6c8, val0x6cc); + +	coex_dm->pre_val0x6c0 = coex_dm->cur_val0x6c0; +	coex_dm->pre_val0x6c4 = coex_dm->cur_val0x6c4; +	coex_dm->pre_val0x6c8 = coex_dm->cur_val0x6c8; +	coex_dm->pre_val0x6cc = coex_dm->cur_val0x6cc; +} + +static void btc8723b_coex_tbl_type(struct btc_coexist *btcoexist, +				   bool force_exec, u8 type) +{ +	switch (type) { +	case 0: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0x55555555, +					0x55555555, 0xffff, 0x3); +		break; +	case 1: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0x55555555, +					0x5afa5afa, 0xffff, 0x3); +		break; +	case 2: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a, +					0x5a5a5a5a, 0xffff, 0x3); +		break; +	case 3: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0xaaaaaaaa, +					0xaaaaaaaa, 0xffff, 0x3); +		break; +	case 4: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0xffffffff, +					0xffffffff, 0xffff, 0x3); +		break; +	case 5: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0x5fff5fff, +					0x5fff5fff, 0xffff, 0x3); +		break; +	case 6: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0x55ff55ff, +					0x5a5a5a5a, 0xffff, 0x3); +		break; +	case 7: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0x55ff55ff, +					0x5afa5afa, 0xffff, 0x3); +		break; +	case 8: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0x5aea5aea, +					0x5aea5aea, 0xffff, 0x3); +		break; +	case 9: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0x55ff55ff, +					0x5aea5aea, 0xffff, 0x3); +		break; +	case 10: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0x55ff55ff, +					0x5aff5aff, 0xffff, 0x3); +		break; +	case 11: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0x55ff55ff, +					0x5a5f5a5f, 0xffff, 0x3); +		break; +	case 12: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0x55ff55ff, +					0x5f5f5f5f, 0xffff, 0x3); +		break; +	default: +		break; +	} +} + +static void btc8723b2ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoexist, +						bool enable) +{ +	u8 h2c_parameter[1] = {0}; + +	if (enable) +		h2c_parameter[0] |= BIT0;/* function enable*/ + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, +		  "[BTCoex], set FW for BT Ignore Wlan_Act, " +		  "FW write 0x63=0x%x\n", h2c_parameter[0]); + +	btcoexist->btc_fill_h2c(btcoexist, 0x63, 1, h2c_parameter); +} + +static void btc8723b2ant_ignore_wlan_act(struct btc_coexist *btcoexist, +					 bool force_exec, bool enable) +{ +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, +		  "[BTCoex], %s turn Ignore WlanAct %s\n", +		  (force_exec ? "force to" : ""), (enable ? "ON" : "OFF")); +	coex_dm->cur_ignore_wlan_act = enable; + +	if (!force_exec) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], bPreIgnoreWlanAct = %d, " +			  "bCurIgnoreWlanAct = %d!!\n", +			  coex_dm->pre_ignore_wlan_act, +			  coex_dm->cur_ignore_wlan_act); + +		if (coex_dm->pre_ignore_wlan_act == +		    coex_dm->cur_ignore_wlan_act) +			return; +	} +	btc8723b2ant_set_fw_ignore_wlan_act(btcoexist, enable); + +	coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act; +} + +static void btc8723b2ant_set_fw_ps_tdma(struct btc_coexist *btcoexist, u8 byte1, +					u8 byte2, u8 byte3, u8 byte4, u8 byte5) +{ +	u8 h2c_parameter[5]; + +	h2c_parameter[0] = byte1; +	h2c_parameter[1] = byte2; +	h2c_parameter[2] = byte3; +	h2c_parameter[3] = byte4; +	h2c_parameter[4] = byte5; + +	coex_dm->ps_tdma_para[0] = byte1; +	coex_dm->ps_tdma_para[1] = byte2; +	coex_dm->ps_tdma_para[2] = byte3; +	coex_dm->ps_tdma_para[3] = byte4; +	coex_dm->ps_tdma_para[4] = byte5; + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, +		  "[BTCoex], FW write 0x60(5bytes)=0x%x%08x\n", +		  h2c_parameter[0], +		  h2c_parameter[1] << 24 | h2c_parameter[2] << 16 | +		  h2c_parameter[3] << 8 | h2c_parameter[4]); + +	btcoexist->btc_fill_h2c(btcoexist, 0x60, 5, h2c_parameter); +} + +static void btc8723b2ant_sw_mechanism1(struct btc_coexist *btcoexist, +				       bool shrink_rx_lpf, bool low_penalty_ra, +				       bool limited_dig, bool bt_lna_constrain) +{ +	btc8723b2ant_rf_shrink(btcoexist, NORMAL_EXEC, shrink_rx_lpf); +	btc8723b2ant_low_penalty_ra(btcoexist, NORMAL_EXEC, low_penalty_ra); +} + +static void btc8723b2ant_sw_mechanism2(struct btc_coexist *btcoexist, +				       bool agc_table_shift, bool adc_backoff, +				       bool sw_dac_swing, u32 dac_swing_lvl) +{ +	btc8723b2ant_agc_table(btcoexist, NORMAL_EXEC, agc_table_shift); +	btc8723b2ant_dac_swing(btcoexist, NORMAL_EXEC, sw_dac_swing, +			       dac_swing_lvl); +} + +static void btc8723b2ant_ps_tdma(struct btc_coexist *btcoexist, bool force_exec, +			     bool turn_on, u8 type) +{ +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, +		  "[BTCoex], %s turn %s PS TDMA, type=%d\n", +		  (force_exec ? "force to" : ""), +		  (turn_on ? "ON" : "OFF"), type); +	coex_dm->cur_ps_tdma_on = turn_on; +	coex_dm->cur_ps_tdma = type; + +	if (!force_exec) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], bPrePsTdmaOn = %d, bCurPsTdmaOn = %d!!\n", +			  coex_dm->pre_ps_tdma_on, coex_dm->cur_ps_tdma_on); +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], prePsTdma = %d, curPsTdma = %d!!\n", +			  coex_dm->pre_ps_tdma, coex_dm->cur_ps_tdma); + +		if ((coex_dm->pre_ps_tdma_on == coex_dm->cur_ps_tdma_on) && +		    (coex_dm->pre_ps_tdma == coex_dm->cur_ps_tdma)) +			return; +	} +	if (turn_on) { +		switch (type) { +		case 1: +		default: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a, +						    0x1a, 0xe1, 0x90); +			break; +		case 2: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x12, +						    0x12, 0xe1, 0x90); +			break; +		case 3: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1c, +						    0x3, 0xf1, 0x90); +			break; +		case 4: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x10, +						    0x03, 0xf1, 0x90); +			break; +		case 5: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a, +						    0x1a, 0x60, 0x90); +			break; +		case 6: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x12, +						    0x12, 0x60, 0x90); +			break; +		case 7: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1c, +						    0x3, 0x70, 0x90); +			break; +		case 8: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xa3, 0x10, +						    0x3, 0x70, 0x90); +			break; +		case 9: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a, +						    0x1a, 0xe1, 0x90); +			break; +		case 10: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x12, +						    0x12, 0xe1, 0x90); +			break; +		case 11: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa, +						    0xa, 0xe1, 0x90); +			break; +		case 12: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x5, +						    0x5, 0xe1, 0x90); +			break; +		case 13: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a, +						    0x1a, 0x60, 0x90); +			break; +		case 14: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x12, +						    0x12, 0x60, 0x90); +			break; +		case 15: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa, +						    0xa, 0x60, 0x90); +			break; +		case 16: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x5, +						    0x5, 0x60, 0x90); +			break; +		case 17: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xa3, 0x2f, +						    0x2f, 0x60, 0x90); +			break; +		case 18: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x5, +						    0x5, 0xe1, 0x90); +			break; +		case 19: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25, +						    0x25, 0xe1, 0x90); +			break; +		case 20: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25, +						    0x25, 0x60, 0x90); +			break; +		case 21: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x15, +						    0x03, 0x70, 0x90); +			break; +		case 71: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a, +						    0x1a, 0xe1, 0x90); +			break; +		} +	} else { +		/* disable PS tdma */ +		switch (type) { +		case 0: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0, +						    0x40, 0x0); +			break; +		case 1: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0, +						    0x48, 0x0); +			break; +		default: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0, +						    0x40, 0x0); +			break; +		} +	} + +	/* update pre state */ +	coex_dm->pre_ps_tdma_on = coex_dm->cur_ps_tdma_on; +	coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma; +} + +static void btc8723b2ant_coex_alloff(struct btc_coexist *btcoexist) +{ +	/* fw all off */ +	btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); +	btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); +	btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +	/* sw all off */ +	btc8723b2ant_sw_mechanism1(btcoexist, false, false, false, false); +	btc8723b2ant_sw_mechanism2(btcoexist, false, false, false, 0x18); + +	/* hw all off */ +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); +	btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 0); +} + +static void btc8723b2ant_init_coex_dm(struct btc_coexist *btcoexist) +{ +	/* force to reset coex mechanism*/ + +	btc8723b2ant_ps_tdma(btcoexist, FORCE_EXEC, false, 1); +	btc8723b2ant_fw_dac_swing_lvl(btcoexist, FORCE_EXEC, 6); +	btc8723b2ant_dec_bt_pwr(btcoexist, FORCE_EXEC, false); + +	btc8723b2ant_sw_mechanism1(btcoexist, false, false, false, false); +	btc8723b2ant_sw_mechanism2(btcoexist, false, false, false, 0x18); +} + +static void btc8723b2ant_action_bt_inquiry(struct btc_coexist *btcoexist) +{ +	bool wifi_connected = false; +	bool low_pwr_disable = true; + +	btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, +			   &low_pwr_disable); +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, +			   &wifi_connected); + +	if (wifi_connected) { +		btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7); +		btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); +	} else { +		btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 0); +		btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); +	} +	btc8723b2ant_fw_dac_swing_lvl(btcoexist, FORCE_EXEC, 6); +	btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +	btc8723b2ant_sw_mechanism1(btcoexist, false, false, false, false); +	btc8723b2ant_sw_mechanism2(btcoexist, false, false, false, 0x18); + +	coex_dm->need_recover_0x948 = true; +	coex_dm->backup_0x948 = btcoexist->btc_read_2byte(btcoexist, 0x948); + +	btcoexist->btc_write_2byte(btcoexist, 0x948, 0x280); +} + +static bool btc8723b2ant_is_common_action(struct btc_coexist *btcoexist) +{ +	bool common = false, wifi_connected = false; +	bool wifi_busy = false; +	bool bt_hs_on = false, low_pwr_disable = false; + +	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, +			   &wifi_connected); +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + +	if (!wifi_connected) { +		low_pwr_disable = false; +		btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, +				   &low_pwr_disable); + +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +			  "[BTCoex], Wifi non-connected idle!!\n"); + +		btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, +					  0x0); +		btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 0); +		btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); +		btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +		btc8723b2ant_sw_mechanism1(btcoexist, false, false, false, +					   false); +		btc8723b2ant_sw_mechanism2(btcoexist, false, false, false, +					   0x18); + +		common = true; +	} else { +		if (BT_8723B_2ANT_BT_STATUS_NON_CONNECTED_IDLE == +		    coex_dm->bt_status) { +			low_pwr_disable = false; +			btcoexist->btc_set(btcoexist, +					   BTC_SET_ACT_DISABLE_LOW_POWER, +					   &low_pwr_disable); + +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Wifi connected + " +				  "BT non connected-idle!!\n"); + +			btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, +						  0xfffff, 0x0); +			btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 0); +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); +			btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, +						      0xb); +			btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, +						false); + +			btc8723b2ant_sw_mechanism1(btcoexist, false, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); + +			common = true; +		} else if (BT_8723B_2ANT_BT_STATUS_CONNECTED_IDLE == +			   coex_dm->bt_status) { +			low_pwr_disable = true; +			btcoexist->btc_set(btcoexist, +					   BTC_SET_ACT_DISABLE_LOW_POWER, +					   &low_pwr_disable); + +			if (bt_hs_on) +				return false; +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Wifi connected + " +				  "BT connected-idle!!\n"); + +			btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, +						  0xfffff, 0x0); +			btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 0); +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); +			btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, +						      0xb); +			btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, +						false); + +			btc8723b2ant_sw_mechanism1(btcoexist, true, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); + +			common = true; +		} else { +			low_pwr_disable = true; +			btcoexist->btc_set(btcoexist, +					   BTC_SET_ACT_DISABLE_LOW_POWER, +					   &low_pwr_disable); + +			if (wifi_busy) { +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +					  "[BTCoex], Wifi Connected-Busy + " +					  "BT Busy!!\n"); +				common = false; +			} else { +				if (bt_hs_on) +					return false; + +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +					  "[BTCoex], Wifi Connected-Idle + " +					  "BT Busy!!\n"); + +				btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, +							  0x1, 0xfffff, 0x0); +				btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, +						       7); +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 21); +				btc8723b2ant_fw_dac_swing_lvl(btcoexist, +							      NORMAL_EXEC, +							      0xb); +				if (btc8723b_need_dec_pwr(btcoexist)) +					btc8723b2ant_dec_bt_pwr(btcoexist, +								NORMAL_EXEC, +								true); +				else +					btc8723b2ant_dec_bt_pwr(btcoexist, +								NORMAL_EXEC, +								false); +				btc8723b2ant_sw_mechanism1(btcoexist, false, +							   false, false, +							   false); +				btc8723b2ant_sw_mechanism2(btcoexist, false, +							   false, false, +							   0x18); +				common = true; +			} +		} +	} + +	return common; +} + +static void set_tdma_int1(struct btc_coexist *btcoexist, bool tx_pause, +			  s32 result) +{ +	/* Set PS TDMA for max interval == 1 */ +	if (tx_pause) { +		BTC_PRINT(BTC_MSG_ALGORITHM, +			  ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], TxPause = 1\n"); + +		if (coex_dm->cur_ps_tdma == 71) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +					     true, 5); +			coex_dm->tdma_adj_type = 5; +		} else if (coex_dm->cur_ps_tdma == 1) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +					     true, 5); +			coex_dm->tdma_adj_type = 5; +		} else if (coex_dm->cur_ps_tdma == 2) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +					     true, 6); +			coex_dm->tdma_adj_type = 6; +		} else if (coex_dm->cur_ps_tdma == 3) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +					     true, 7); +			coex_dm->tdma_adj_type = 7; +		} else if (coex_dm->cur_ps_tdma == 4) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +					     true, 8); +			coex_dm->tdma_adj_type = 8; +		} else if (coex_dm->cur_ps_tdma == 9) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +					     true, 13); +			coex_dm->tdma_adj_type = 13; +		} else if (coex_dm->cur_ps_tdma == 10) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +					     true, 14); +			coex_dm->tdma_adj_type = 14; +		} else if (coex_dm->cur_ps_tdma == 11) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +					     true, 15); +			coex_dm->tdma_adj_type = 15; +		} else if (coex_dm->cur_ps_tdma == 12) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +					     true, 16); +			coex_dm->tdma_adj_type = 16; +		} + +		if (result == -1) { +			if (coex_dm->cur_ps_tdma == 5) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 6); +				coex_dm->tdma_adj_type = 6; +			} else if (coex_dm->cur_ps_tdma == 6) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 7); +				coex_dm->tdma_adj_type = 7; +			} else if (coex_dm->cur_ps_tdma == 7) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 8); +				coex_dm->tdma_adj_type = 8; +			} else if (coex_dm->cur_ps_tdma == 13) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 14); +				coex_dm->tdma_adj_type = 14; +			} else if (coex_dm->cur_ps_tdma == 14) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 15); +				coex_dm->tdma_adj_type = 15; +			} else if (coex_dm->cur_ps_tdma == 15) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 16); +				coex_dm->tdma_adj_type = 16; +			} +		}  else if (result == 1) { +			if (coex_dm->cur_ps_tdma == 8) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 7); +				coex_dm->tdma_adj_type = 7; +			} else if (coex_dm->cur_ps_tdma == 7) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 6); +				coex_dm->tdma_adj_type = 6; +			} else if (coex_dm->cur_ps_tdma == 6) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 5); +				coex_dm->tdma_adj_type = 5; +			} else if (coex_dm->cur_ps_tdma == 16) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 15); +				coex_dm->tdma_adj_type = 15; +			} else if (coex_dm->cur_ps_tdma == 15) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 14); +				coex_dm->tdma_adj_type = 14; +			} else if (coex_dm->cur_ps_tdma == 14) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 13); +				coex_dm->tdma_adj_type = 13; +			} +		} +	} else { +		BTC_PRINT(BTC_MSG_ALGORITHM, +			  ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], TxPause = 0\n"); +		if (coex_dm->cur_ps_tdma == 5) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 71); +			coex_dm->tdma_adj_type = 71; +		} else if (coex_dm->cur_ps_tdma == 6) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 2); +			coex_dm->tdma_adj_type = 2; +		} else if (coex_dm->cur_ps_tdma == 7) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); +			coex_dm->tdma_adj_type = 3; +		} else if (coex_dm->cur_ps_tdma == 8) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 4); +			coex_dm->tdma_adj_type = 4; +		} else if (coex_dm->cur_ps_tdma == 13) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9); +			coex_dm->tdma_adj_type = 9; +		} else if (coex_dm->cur_ps_tdma == 14) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10); +			coex_dm->tdma_adj_type = 10; +		} else if (coex_dm->cur_ps_tdma == 15) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11); +			coex_dm->tdma_adj_type = 11; +		} else if (coex_dm->cur_ps_tdma == 16) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 12); +			coex_dm->tdma_adj_type = 12; +		} + +		if (result == -1) { +			if (coex_dm->cur_ps_tdma == 71) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 1); +				coex_dm->tdma_adj_type = 1; +			} else if (coex_dm->cur_ps_tdma == 1) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 2); +				coex_dm->tdma_adj_type = 2; +			} else if (coex_dm->cur_ps_tdma == 2) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 3); +				coex_dm->tdma_adj_type = 3; +			} else if (coex_dm->cur_ps_tdma == 3) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 4); +				coex_dm->tdma_adj_type = 4; +			} else if (coex_dm->cur_ps_tdma == 9) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 10); +				coex_dm->tdma_adj_type = 10; +			} else if (coex_dm->cur_ps_tdma == 10) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 11); +				coex_dm->tdma_adj_type = 11; +			} else if (coex_dm->cur_ps_tdma == 11) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 12); +				coex_dm->tdma_adj_type = 12; +			} +		}  else if (result == 1) { +			int tmp = coex_dm->cur_ps_tdma; +			switch (tmp) { +			case 4: +			case 3: +			case 2: +			case 12: +			case 11: +			case 10: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, tmp - 1); +				coex_dm->tdma_adj_type = tmp - 1; +				break; +			case 1: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 71); +				coex_dm->tdma_adj_type = 71; +				break; +			} +		} +	} +} + +static void set_tdma_int2(struct btc_coexist *btcoexist, bool tx_pause, +			  s32 result) +{ +	/* Set PS TDMA for max interval == 2 */ +	if (tx_pause) { +		BTC_PRINT(BTC_MSG_ALGORITHM, +			  ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], TxPause = 1\n"); +		if (coex_dm->cur_ps_tdma == 1) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 6); +			coex_dm->tdma_adj_type = 6; +		} else if (coex_dm->cur_ps_tdma == 2) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 6); +			coex_dm->tdma_adj_type = 6; +		} else if (coex_dm->cur_ps_tdma == 3) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 7); +			coex_dm->tdma_adj_type = 7; +		} else if (coex_dm->cur_ps_tdma == 4) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 8); +			coex_dm->tdma_adj_type = 8; +		} else if (coex_dm->cur_ps_tdma == 9) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14); +			coex_dm->tdma_adj_type = 14; +		} else if (coex_dm->cur_ps_tdma == 10) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14); +			coex_dm->tdma_adj_type = 14; +		} else if (coex_dm->cur_ps_tdma == 11) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 15); +			coex_dm->tdma_adj_type = 15; +		} else if (coex_dm->cur_ps_tdma == 12) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 16); +			coex_dm->tdma_adj_type = 16; +		} +		if (result == -1) { +			if (coex_dm->cur_ps_tdma == 5) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 6); +				coex_dm->tdma_adj_type = 6; +			} else if (coex_dm->cur_ps_tdma == 6) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 7); +				coex_dm->tdma_adj_type = 7; +			} else if (coex_dm->cur_ps_tdma == 7) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 8); +				coex_dm->tdma_adj_type = 8; +			} else if (coex_dm->cur_ps_tdma == 13) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 14); +				coex_dm->tdma_adj_type = 14; +			} else if (coex_dm->cur_ps_tdma == 14) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 15); +				coex_dm->tdma_adj_type = 15; +			} else if (coex_dm->cur_ps_tdma == 15) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 16); +				coex_dm->tdma_adj_type = 16; +			} +		}  else if (result == 1) { +			if (coex_dm->cur_ps_tdma == 8) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 7); +				coex_dm->tdma_adj_type = 7; +			} else if (coex_dm->cur_ps_tdma == 7) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 6); +				coex_dm->tdma_adj_type = 6; +			} else if (coex_dm->cur_ps_tdma == 6) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 6); +				coex_dm->tdma_adj_type = 6; +			} else if (coex_dm->cur_ps_tdma == 16) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 15); +				coex_dm->tdma_adj_type = 15; +			} else if (coex_dm->cur_ps_tdma == 15) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 14); +				coex_dm->tdma_adj_type = 14; +			} else if (coex_dm->cur_ps_tdma == 14) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 14); +				coex_dm->tdma_adj_type = 14; +			} +		} +	} else { +		BTC_PRINT(BTC_MSG_ALGORITHM, +			  ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], TxPause = 0\n"); +		if (coex_dm->cur_ps_tdma == 5) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 2); +			coex_dm->tdma_adj_type = 2; +		} else if (coex_dm->cur_ps_tdma == 6) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 2); +			coex_dm->tdma_adj_type = 2; +		} else if (coex_dm->cur_ps_tdma == 7) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); +			coex_dm->tdma_adj_type = 3; +		} else if (coex_dm->cur_ps_tdma == 8) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 4); +			coex_dm->tdma_adj_type = 4; +		} else if (coex_dm->cur_ps_tdma == 13) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10); +			coex_dm->tdma_adj_type = 10; +		} else if (coex_dm->cur_ps_tdma == 14) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10); +			coex_dm->tdma_adj_type = 10; +		} else if (coex_dm->cur_ps_tdma == 15) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11); +			coex_dm->tdma_adj_type = 11; +		} else if (coex_dm->cur_ps_tdma == 16) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 12); +			coex_dm->tdma_adj_type = 12; +		} +		if (result == -1) { +			if (coex_dm->cur_ps_tdma == 1) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 2); +				coex_dm->tdma_adj_type = 2; +			} else if (coex_dm->cur_ps_tdma == 2) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 3); +				coex_dm->tdma_adj_type = 3; +			} else if (coex_dm->cur_ps_tdma == 3) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 4); +				coex_dm->tdma_adj_type = 4; +			} else if (coex_dm->cur_ps_tdma == 9) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 10); +				coex_dm->tdma_adj_type = 10; +			} else if (coex_dm->cur_ps_tdma == 10) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 11); +				coex_dm->tdma_adj_type = 11; +			} else if (coex_dm->cur_ps_tdma == 11) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 12); +				coex_dm->tdma_adj_type = 12; +			} +		} else if (result == 1) { +			if (coex_dm->cur_ps_tdma == 4) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 3); +				coex_dm->tdma_adj_type = 3; +			} else if (coex_dm->cur_ps_tdma == 3) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 2); +				coex_dm->tdma_adj_type = 2; +			} else if (coex_dm->cur_ps_tdma == 2) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 2); +				coex_dm->tdma_adj_type = 2; +			} else if (coex_dm->cur_ps_tdma == 12) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 11); +				coex_dm->tdma_adj_type = 11; +			} else if (coex_dm->cur_ps_tdma == 11) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 10); +				coex_dm->tdma_adj_type = 10; +			} else if (coex_dm->cur_ps_tdma == 10) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 10); +				coex_dm->tdma_adj_type = 10; +			} +		} +	} +} + +static void set_tdma_int3(struct btc_coexist *btcoexist, bool tx_pause, +			  s32 result) +{ +	/* Set PS TDMA for max interval == 3 */ +	if (tx_pause) { +		BTC_PRINT(BTC_MSG_ALGORITHM, +			  ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], TxPause = 1\n"); +		if (coex_dm->cur_ps_tdma == 1) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 7); +			coex_dm->tdma_adj_type = 7; +		} else if (coex_dm->cur_ps_tdma == 2) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 7); +			coex_dm->tdma_adj_type = 7; +		} else if (coex_dm->cur_ps_tdma == 3) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 7); +			coex_dm->tdma_adj_type = 7; +		} else if (coex_dm->cur_ps_tdma == 4) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 8); +			coex_dm->tdma_adj_type = 8; +		} else if (coex_dm->cur_ps_tdma == 9) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 15); +			coex_dm->tdma_adj_type = 15; +		} else if (coex_dm->cur_ps_tdma == 10) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 15); +			coex_dm->tdma_adj_type = 15; +		} else if (coex_dm->cur_ps_tdma == 11) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 15); +			coex_dm->tdma_adj_type = 15; +		} else if (coex_dm->cur_ps_tdma == 12) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 16); +			coex_dm->tdma_adj_type = 16; +		} +		if (result == -1) { +			if (coex_dm->cur_ps_tdma == 5) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 7); +				coex_dm->tdma_adj_type = 7; +			} else if (coex_dm->cur_ps_tdma == 6) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 7); +				coex_dm->tdma_adj_type = 7; +			} else if (coex_dm->cur_ps_tdma == 7) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 8); +				coex_dm->tdma_adj_type = 8; +			} else if (coex_dm->cur_ps_tdma == 13) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 15); +				coex_dm->tdma_adj_type = 15; +			} else if (coex_dm->cur_ps_tdma == 14) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 15); +				coex_dm->tdma_adj_type = 15; +			} else if (coex_dm->cur_ps_tdma == 15) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 16); +				coex_dm->tdma_adj_type = 16; +			} +		}  else if (result == 1) { +			if (coex_dm->cur_ps_tdma == 8) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 7); +				coex_dm->tdma_adj_type = 7; +			} else if (coex_dm->cur_ps_tdma == 7) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 7); +				coex_dm->tdma_adj_type = 7; +			} else if (coex_dm->cur_ps_tdma == 6) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 7); +				coex_dm->tdma_adj_type = 7; +			} else if (coex_dm->cur_ps_tdma == 16) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 15); +				coex_dm->tdma_adj_type = 15; +			} else if (coex_dm->cur_ps_tdma == 15) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 15); +				coex_dm->tdma_adj_type = 15; +			} else if (coex_dm->cur_ps_tdma == 14) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 15); +				coex_dm->tdma_adj_type = 15; +			} +		} +	} else { +		BTC_PRINT(BTC_MSG_ALGORITHM, +			  ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], TxPause = 0\n"); +		switch (coex_dm->cur_ps_tdma) { +		case 5: +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); +			coex_dm->tdma_adj_type = 3; +			break; +		case 6: +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); +			coex_dm->tdma_adj_type = 3; +			break; +		case 7: +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); +			coex_dm->tdma_adj_type = 3; +			break; +		case 8: +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 4); +			coex_dm->tdma_adj_type = 4; +			break; +		case 13: +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11); +			coex_dm->tdma_adj_type = 11; +			break; +		case 14: +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11); +			coex_dm->tdma_adj_type = 11; +			break; +		case 15: +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11); +			coex_dm->tdma_adj_type = 11; +			break; +		case 16: +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 12); +			coex_dm->tdma_adj_type = 12; +			break; +		} +		if (result == -1) { +			switch (coex_dm->cur_ps_tdma) { +			case 1: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 3); +				coex_dm->tdma_adj_type = 3; +				break; +			case 2: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 3); +				coex_dm->tdma_adj_type = 3; +				break; +			case 3: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 4); +				coex_dm->tdma_adj_type = 4; +				break; +			case 9: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 11); +				coex_dm->tdma_adj_type = 11; +				break; +			case 10: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 11); +				coex_dm->tdma_adj_type = 11; +				break; +			case 11: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 12); +				coex_dm->tdma_adj_type = 12; +				break; +			} +		} else if (result == 1) { +			switch (coex_dm->cur_ps_tdma) { +			case 4: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 3); +				coex_dm->tdma_adj_type = 3; +				break; +			case 3: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 3); +				coex_dm->tdma_adj_type = 3; +				break; +			case 2: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 3); +				coex_dm->tdma_adj_type = 3; +				break; +			case 12: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 11); +				coex_dm->tdma_adj_type = 11; +				break; +			case 11: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 11); +				coex_dm->tdma_adj_type = 11; +				break; +			case 10: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 11); +				coex_dm->tdma_adj_type = 11; +			} +		} +	} +} + +static void btc8723b2ant_tdma_duration_adjust(struct btc_coexist *btcoexist, +					  bool sco_hid, bool tx_pause, +					  u8 max_interval) +{ +	static s32 up, dn, m, n, wait_count; +	/*0: no change, +1: increase WiFi duration, -1: decrease WiFi duration*/ +	s32 result; +	u8 retry_count = 0; + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, +		  "[BTCoex], TdmaDurationAdjust()\n"); + +	if (!coex_dm->auto_tdma_adjust) { +		coex_dm->auto_tdma_adjust = true; +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], first run TdmaDurationAdjust()!!\n"); +		if (sco_hid) { +			if (tx_pause) { +				if (max_interval == 1) { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 13); +					coex_dm->tdma_adj_type = 13; +				} else if (max_interval == 2) { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 14); +					coex_dm->tdma_adj_type = 14; +				} else if (max_interval == 3) { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 15); +					coex_dm->tdma_adj_type = 15; +				} else { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 15); +					coex_dm->tdma_adj_type = 15; +				} +			} else { +				if (max_interval == 1) { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 9); +					coex_dm->tdma_adj_type = 9; +				} else if (max_interval == 2) { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 10); +					coex_dm->tdma_adj_type = 10; +				} else if (max_interval == 3) { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 11); +					coex_dm->tdma_adj_type = 11; +				} else { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 11); +					coex_dm->tdma_adj_type = 11; +				} +			} +		} else { +			if (tx_pause) { +				if (max_interval == 1) { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 5); +					coex_dm->tdma_adj_type = 5; +				} else if (max_interval == 2) { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 6); +					coex_dm->tdma_adj_type = 6; +				} else if (max_interval == 3) { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 7); +					coex_dm->tdma_adj_type = 7; +				} else { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 7); +					coex_dm->tdma_adj_type = 7; +				} +			} else { +				if (max_interval == 1) { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 1); +					coex_dm->tdma_adj_type = 1; +				} else if (max_interval == 2) { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 2); +					coex_dm->tdma_adj_type = 2; +				} else if (max_interval == 3) { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 3); +					coex_dm->tdma_adj_type = 3; +				} else { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 3); +					coex_dm->tdma_adj_type = 3; +				} +			} +		} + +		up = 0; +		dn = 0; +		m = 1; +		n = 3; +		result = 0; +		wait_count = 0; +	} else { +		/*accquire the BT TRx retry count from BT_Info byte2*/ +		retry_count = coex_sta->bt_retry_cnt; +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], retry_count = %d\n", retry_count); +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], up=%d, dn=%d, m=%d, n=%d, wait_count=%d\n", +			  up, dn, m, n, wait_count); +		result = 0; +		wait_count++; +		 /* no retry in the last 2-second duration*/ +		if (retry_count == 0) { +			up++; +			dn--; + +			if (dn <= 0) +				dn = 0; + +			if (up >= n) { +				wait_count = 0; +				n = 3; +				up = 0; +				dn = 0; +				result = 1; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_TRACE_FW_DETAIL, +					  "[BTCoex], Increase wifi " +					  "duration!!\n"); +			} /* <=3 retry in the last 2-second duration*/ +		} else if (retry_count <= 3) { +			up--; +			dn++; + +			if (up <= 0) +				up = 0; + +			if (dn == 2) { +				if (wait_count <= 2) +					m++; +				else +					m = 1; + +				if (m >= 20) +					m = 20; + +				n = 3 * m; +				up = 0; +				dn = 0; +				wait_count = 0; +				result = -1; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_TRACE_FW_DETAIL, +					  "[BTCoex], Decrease wifi duration " +					  "for retry_counter<3!!\n"); +			} +		} else { +			if (wait_count == 1) +				m++; +			else +				m = 1; + +			if (m >= 20) +				m = 20; + +			n = 3 * m; +			up = 0; +			dn = 0; +			wait_count = 0; +			result = -1; +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, +				  "[BTCoex], Decrease wifi duration " +				  "for retry_counter>3!!\n"); +		} + +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], max Interval = %d\n", max_interval); +		if (max_interval == 1) +			set_tdma_int1(btcoexist, tx_pause, result); +		else if (max_interval == 2) +			set_tdma_int2(btcoexist, tx_pause, result); +		else if (max_interval == 3) +			set_tdma_int3(btcoexist, tx_pause, result); +	} + +	/*if current PsTdma not match with the recorded one (when scan, dhcp..), +	 *then we have to adjust it back to the previous recorded one. +	 */ +	if (coex_dm->cur_ps_tdma != coex_dm->tdma_adj_type) { +		bool scan = false, link = false, roam = false; +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], PsTdma type dismatch!!!, " +			  "curPsTdma=%d, recordPsTdma=%d\n", +			  coex_dm->cur_ps_tdma, coex_dm->tdma_adj_type); + +		btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); +		btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); +		btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); + +		if (!scan && !link && !roam) +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, +					     coex_dm->tdma_adj_type); +		else +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, +				  "[BTCoex], roaming/link/scan is under" +				  " progress, will adjust next time!!!\n"); +	} +} + +/* SCO only or SCO+PAN(HS) */ +static void btc8723b2ant_action_sco(struct btc_coexist *btcoexist) +{ +	u8 wifi_rssi_state; +	u32 wifi_bw; + +	wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, +						       0, 2, 15, 0); + +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + +	btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 4); + +	if (btc8723b_need_dec_pwr(btcoexist)) +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); +	else +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + +	/*for SCO quality at 11b/g mode*/ +	if (BTC_WIFI_BW_LEGACY == wifi_bw) +		btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 2); +	else  /*for SCO quality & wifi performance balance at 11n mode*/ +		btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 8); + +	/*for voice quality */ +	btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0); + +	/* sw mechanism */ +	if (BTC_WIFI_BW_HT40 == wifi_bw) { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, true, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   true, 0x4); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, true, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   true, 0x4); +		} +	} else { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, false, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   true, 0x4); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, false, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   true, 0x4); +		} +	} +} + +static void btc8723b2ant_action_hid(struct btc_coexist *btcoexist) +{ +	u8 wifi_rssi_state, bt_rssi_state; +	u32 wifi_bw; + +	wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, +						       0, 2, 15, 0); +	bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); + +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + +	btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + +	if (btc8723b_need_dec_pwr(btcoexist)) +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); +	else +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + +	if (BTC_WIFI_BW_LEGACY == wifi_bw) /*/for HID at 11b/g mode*/ +		btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7); +	else  /*for HID quality & wifi performance balance at 11n mode*/ +		btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 9); + +	if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || +	    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) +		btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9); +	else +		btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 13); + +	/* sw mechanism */ +	if (BTC_WIFI_BW_HT40 == wifi_bw) { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, true, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, true, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} else { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, false, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, false, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} +} + +/*A2DP only / PAN(EDR) only/ A2DP+PAN(HS)*/ +static void btc8723b2ant_action_a2dp(struct btc_coexist *btcoexist) +{ +	u8 wifi_rssi_state, bt_rssi_state; +	u32 wifi_bw; + +	wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, +						       0, 2, 15, 0); +	bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); + +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + +	btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + +	if (btc8723b_need_dec_pwr(btcoexist)) +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); +	else +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +	btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7); + +	if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || +	    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) +		btc8723b2ant_tdma_duration_adjust(btcoexist, false, +						  false, 1); +	else +		btc8723b2ant_tdma_duration_adjust(btcoexist, false, true, 1); + +	/* sw mechanism */ +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); +	if (BTC_WIFI_BW_HT40 == wifi_bw) { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, true, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, true, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} else { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, false, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, false, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} +} + +static void btc8723b2ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist) +{ +	u8 wifi_rssi_state; +	u32 wifi_bw; + +	wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, +						       0, 2, 15, 0); + +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + +	btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + +	if (btc8723b_need_dec_pwr(btcoexist)) +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); +	else +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +	btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7); + +	btc8723b2ant_tdma_duration_adjust(btcoexist, false, true, 2); + +	/* sw mechanism */ +	btcoexist->btc_get(btcoexist, +		BTC_GET_U4_WIFI_BW, &wifi_bw); +	if (BTC_WIFI_BW_HT40 == wifi_bw) { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, true, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, true, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} else { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, false, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, false, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} +} + +static void btc8723b2ant_action_pan_edr(struct btc_coexist *btcoexist) +{ +	u8 wifi_rssi_state, bt_rssi_state; +	u32 wifi_bw; + +	wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, +						       0, 2, 15, 0); +	bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); + +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + +	btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + +	if (btc8723b_need_dec_pwr(btcoexist)) +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); +	else +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +	btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 10); + +	if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || +	    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) +		btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 1); +	else +		btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5); + +	/* sw mechanism */ +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); +	if (BTC_WIFI_BW_HT40 == wifi_bw) { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, true, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, true, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} else { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, false, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, false, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} +} + +/*PAN(HS) only*/ +static void btc8723b2ant_action_pan_hs(struct btc_coexist *btcoexist) +{ +	u8 wifi_rssi_state; +	u32 wifi_bw; + +	wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, +						       0, 2, 15, 0); + +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + +	btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + +	if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +	    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); +	else +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +	btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7); + +	btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); + +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); +	if (BTC_WIFI_BW_HT40 == wifi_bw) { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, true, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, true, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} else { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, false, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, false, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} +} + +/*PAN(EDR)+A2DP*/ +static void btc8723b2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist) +{ +	u8 wifi_rssi_state, bt_rssi_state; +	u32 wifi_bw; + +	wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, +						       0, 2, 15, 0); +	bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); + +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + +	btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + +	if (btc8723b_need_dec_pwr(btcoexist)) +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); +	else +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + +	if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || +	    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +		btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 12); +		if (BTC_WIFI_BW_HT40 == wifi_bw) +			btc8723b2ant_tdma_duration_adjust(btcoexist, false, +							  true, 3); +		else +			btc8723b2ant_tdma_duration_adjust(btcoexist, false, +							  false, 3); +	} else { +		btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7); +		btc8723b2ant_tdma_duration_adjust(btcoexist, false, true, 3); +	} + +	/* sw mechanism	*/ +	if (BTC_WIFI_BW_HT40 == wifi_bw) { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, true, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, true, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} else { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, false, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, false, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} +} + +static void btc8723b2ant_action_pan_edr_hid(struct btc_coexist *btcoexist) +{ +	u8 wifi_rssi_state, bt_rssi_state; +	u32 wifi_bw; + +	wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, +						       0, 2, 15, 0); +	bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + +	if (btc8723b_need_dec_pwr(btcoexist)) +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); +	else +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +	if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || +	    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +		if (BTC_WIFI_BW_HT40 == wifi_bw) { +			btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, +						      3); +			btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 11); +			btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, +						  0xfffff, 0x780); +		} else { +			btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, +						      6); +			btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7); +			btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, +						  0xfffff, 0x0); +		} +		btc8723b2ant_tdma_duration_adjust(btcoexist, true, false, 2); +	} else { +		btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); +		btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 11); +		btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, +					  0x0); +		btc8723b2ant_tdma_duration_adjust(btcoexist, true, true, 2); +	} + +	/* sw mechanism */ +	if (BTC_WIFI_BW_HT40 == wifi_bw) { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, true, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, true, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} else { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, false, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, false, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} +} + +/* HID+A2DP+PAN(EDR) */ +static void btc8723b2ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist) +{ +	u8 wifi_rssi_state, bt_rssi_state; +	u32 wifi_bw; + +	wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, +						       0, 2, 15, 0); +	bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); + +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + +	btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + +	if (btc8723b_need_dec_pwr(btcoexist)) +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); +	else +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + +	btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7); + +	if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || +	    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +		if (BTC_WIFI_BW_HT40 == wifi_bw) +			btc8723b2ant_tdma_duration_adjust(btcoexist, true, +							  true, 2); +		else +			btc8723b2ant_tdma_duration_adjust(btcoexist, true, +							  false, 3); +	} else { +		btc8723b2ant_tdma_duration_adjust(btcoexist, true, true, 3); +	} + +	/* sw mechanism */ +	if (BTC_WIFI_BW_HT40 == wifi_bw) { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, true, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, true, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} else { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, false, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, false, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} +} + +static void btc8723b2ant_action_hid_a2dp(struct btc_coexist *btcoexist) +{ +	u8 wifi_rssi_state, bt_rssi_state; +	u32 wifi_bw; + +	wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, +							  0, 2, 15, 0); +	bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); + +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + +	btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + +	if (btc8723b_need_dec_pwr(btcoexist)) +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); +	else +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + +	btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7); + +	if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || +	    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) +		btc8723b2ant_tdma_duration_adjust(btcoexist, true, false, 2); +	else +		btc8723b2ant_tdma_duration_adjust(btcoexist, true, true, 2); + +	/* sw mechanism */ +	if (BTC_WIFI_BW_HT40 == wifi_bw) { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, true, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, true, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} else { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, false, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, false, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} +} + +static void btc8723b2ant_run_coexist_mechanism(struct btc_coexist *btcoexist) +{ +	u8 algorithm = 0; + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +		  "[BTCoex], RunCoexistMechanism()===>\n"); + +	if (btcoexist->manual_control) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +			  "[BTCoex], RunCoexistMechanism(), " +			  "return for Manual CTRL <===\n"); +		return; +	} + +	if (coex_sta->under_ips) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +			  "[BTCoex], wifi is under IPS !!!\n"); +		return; +	} + +	algorithm = btc8723b2ant_action_algorithm(btcoexist); +	if (coex_sta->c2h_bt_inquiry_page && +	    (BT_8723B_2ANT_COEX_ALGO_PANHS != algorithm)) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +			  "[BTCoex], BT is under inquiry/page scan !!\n"); +		btc8723b2ant_action_bt_inquiry(btcoexist); +		return; +	} else { +		if (coex_dm->need_recover_0x948) { +			coex_dm->need_recover_0x948 = false; +			btcoexist->btc_write_2byte(btcoexist, 0x948, +						   coex_dm->backup_0x948); +		} +	} + +	coex_dm->cur_algorithm = algorithm; +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, "[BTCoex], Algorithm = %d\n", +		  coex_dm->cur_algorithm); + +	if (btc8723b2ant_is_common_action(btcoexist)) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +			  "[BTCoex], Action 2-Ant common.\n"); +		coex_dm->auto_tdma_adjust = false; +	} else { +		if (coex_dm->cur_algorithm != coex_dm->pre_algorithm) { +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], preAlgorithm=%d, " +				  "curAlgorithm=%d\n", coex_dm->pre_algorithm, +				  coex_dm->cur_algorithm); +			coex_dm->auto_tdma_adjust = false; +		} +		switch (coex_dm->cur_algorithm) { +		case BT_8723B_2ANT_COEX_ALGO_SCO: +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Action 2-Ant, algorithm = SCO.\n"); +			btc8723b2ant_action_sco(btcoexist); +			break; +		case BT_8723B_2ANT_COEX_ALGO_HID: +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Action 2-Ant, algorithm = HID.\n"); +			btc8723b2ant_action_hid(btcoexist); +			break; +		case BT_8723B_2ANT_COEX_ALGO_A2DP: +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Action 2-Ant, " +				  "algorithm = A2DP.\n"); +			btc8723b2ant_action_a2dp(btcoexist); +			break; +		case BT_8723B_2ANT_COEX_ALGO_A2DP_PANHS: +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Action 2-Ant, " +				  "algorithm = A2DP+PAN(HS).\n"); +			btc8723b2ant_action_a2dp_pan_hs(btcoexist); +			break; +		case BT_8723B_2ANT_COEX_ALGO_PANEDR: +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Action 2-Ant, " +				  "algorithm = PAN(EDR).\n"); +			btc8723b2ant_action_pan_edr(btcoexist); +			break; +		case BT_8723B_2ANT_COEX_ALGO_PANHS: +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Action 2-Ant, " +				  "algorithm = HS mode.\n"); +			btc8723b2ant_action_pan_hs(btcoexist); +				break; +		case BT_8723B_2ANT_COEX_ALGO_PANEDR_A2DP: +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Action 2-Ant, " +				  "algorithm = PAN+A2DP.\n"); +			btc8723b2ant_action_pan_edr_a2dp(btcoexist); +			break; +		case BT_8723B_2ANT_COEX_ALGO_PANEDR_HID: +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Action 2-Ant, " +				  "algorithm = PAN(EDR)+HID.\n"); +			btc8723b2ant_action_pan_edr_hid(btcoexist); +			break; +		case BT_8723B_2ANT_COEX_ALGO_HID_A2DP_PANEDR: +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Action 2-Ant, " +				  "algorithm = HID+A2DP+PAN.\n"); +			btc8723b2ant_action_hid_a2dp_pan_edr(btcoexist); +			break; +		case BT_8723B_2ANT_COEX_ALGO_HID_A2DP: +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Action 2-Ant, " +				  "algorithm = HID+A2DP.\n"); +			btc8723b2ant_action_hid_a2dp(btcoexist); +			break; +		default: +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Action 2-Ant, " +				  "algorithm = coexist All Off!!\n"); +			btc8723b2ant_coex_alloff(btcoexist); +			break; +		} +		coex_dm->pre_algorithm = coex_dm->cur_algorithm; +	} +} + + + +/********************************************************************* + *  work around function start with wa_btc8723b2ant_ + *********************************************************************/ +/********************************************************************* + *  extern function start with EXbtc8723b2ant_ + *********************************************************************/ +void ex_halbtc8723b2ant_init_hwconfig(struct btc_coexist *btcoexist) +{ +	struct btc_board_info *board_info = &btcoexist->board_info; +	u32 u32tmp = 0, fw_ver; +	u8 u8tmp = 0; +	u8 h2c_parameter[2] = {0}; + + +	BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, +		  "[BTCoex], 2Ant Init HW Config!!\n"); + +	/* backup rf 0x1e value */ +	coex_dm->bt_rf0x1e_backup = btcoexist->btc_get_rf_reg(btcoexist, +							      BTC_RF_A, 0x1e, +							      0xfffff); + +	/* 0x4c[23]=0, 0x4c[24]=1  Antenna control by WL/BT */ +	u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c); +	u32tmp &= ~BIT23; +	u32tmp |= BIT24; +	btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp); + +	btcoexist->btc_write_1byte(btcoexist, 0x974, 0xff); +	btcoexist->btc_write_1byte_bitmask(btcoexist, 0x944, 0x3, 0x3); +	btcoexist->btc_write_1byte(btcoexist, 0x930, 0x77); +	btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 0x20, 0x1); + +	/* Antenna switch control parameter */ +	/* btcoexist->btc_write_4byte(btcoexist, 0x858, 0x55555555);*/ + +	/*Force GNT_BT to low*/ +	btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x0); +	btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0); + +	/* 0x790[5:0]=0x5 */ +	u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x790); +	u8tmp &= 0xc0; +	u8tmp |= 0x5; +	btcoexist->btc_write_1byte(btcoexist, 0x790, u8tmp); + + +	/*Antenna config	*/ +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); + + /*ext switch for fw ver < 0xc */ +	if (fw_ver < 0xc00) { +		if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) { +			btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c, +							   0x3, 0x1); +			/*Main Ant to  BT for IPS case 0x4c[23]=1*/ +			btcoexist->btc_write_1byte_bitmask(btcoexist, 0x64, 0x1, +							   0x1); + +			/*tell firmware "no antenna inverse"*/ +			h2c_parameter[0] = 0; +			h2c_parameter[1] = 1;  /* ext switch type */ +			btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, +						h2c_parameter); +		} else { +			btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c, +							   0x3, 0x2); +			/*Aux Ant to  BT for IPS case 0x4c[23]=1*/ +			btcoexist->btc_write_1byte_bitmask(btcoexist, 0x64, 0x1, +							   0x0); + +			/*tell firmware "antenna inverse"*/ +			h2c_parameter[0] = 1; +			h2c_parameter[1] = 1;  /*ext switch type*/ +			btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, +						h2c_parameter); +		} +	} else { +		/*ext switch always at s1 (if exist) */ +		btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c, 0x3, 0x1); +		/*Main Ant to  BT for IPS case 0x4c[23]=1*/ +		btcoexist->btc_write_1byte_bitmask(btcoexist, 0x64, 0x1, 0x1); + +		if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) { +			/*tell firmware "no antenna inverse"*/ +			h2c_parameter[0] = 0; +			h2c_parameter[1] = 0;  /*ext switch type*/ +			btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, +						h2c_parameter); +		} else { +			/*tell firmware "antenna inverse"*/ +			h2c_parameter[0] = 1; +			h2c_parameter[1] = 0;  /*ext switch type*/ +			btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, +						h2c_parameter); +		} +	} + +	/* PTA parameter */ +	btc8723b_coex_tbl_type(btcoexist, FORCE_EXEC, 0); + +	/* Enable counter statistics */ +	/*0x76e[3] =1, WLAN_Act control by PTA*/ +	btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc); +	btcoexist->btc_write_1byte(btcoexist, 0x778, 0x3); +	btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1); +} + +void ex_halbtc8723b2ant_init_coex_dm(struct btc_coexist *btcoexist) +{ +	BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, +		  "[BTCoex], Coex Mechanism Init!!\n"); +	btc8723b2ant_init_coex_dm(btcoexist); +} + +void ex_halbtc8723b2ant_display_coex_info(struct btc_coexist *btcoexist) +{ +	struct btc_board_info *board_info = &btcoexist->board_info; +	struct btc_stack_info *stack_info = &btcoexist->stack_info; +	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; +	u8 *cli_buf = btcoexist->cli_buf; +	u8 u8tmp[4], i, bt_info_ext, ps_tdma_case = 0; +	u32 u32tmp[4]; +	bool roam = false, scan = false; +	bool link = false, wifi_under_5g = false; +	bool bt_hs_on = false, wifi_busy = false; +	s32 wifi_rssi = 0, bt_hs_rssi = 0; +	u32 wifi_bw, wifi_traffic_dir, fa_ofdm, fa_cck; +	u8 wifi_dot11_chnl, wifi_hs_chnl; +	u32 fw_ver = 0, bt_patch_ver = 0; + +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, +		   "\r\n ============[BT Coexist info]============"); +	CL_PRINTF(cli_buf); + +	if (btcoexist->manual_control) { +		CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, +			   "\r\n ==========[Under Manual Control]============"); +		CL_PRINTF(cli_buf); +		CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, +			   "\r\n =========================================="); +		CL_PRINTF(cli_buf); +	} + +	if (!board_info->bt_exist) { +		CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n BT not exists !!!"); +		CL_PRINTF(cli_buf); +		return; +	} + +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", +		   "Ant PG number/ Ant mechanism:", +		   board_info->pg_ant_num, board_info->btdm_ant_num); +	CL_PRINTF(cli_buf); + +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", +		   "BT stack/ hci ext ver", +		   ((stack_info->profile_notified) ? "Yes" : "No"), +		   stack_info->hci_version); +	CL_PRINTF(cli_buf); + +	btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver); +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, +		   "\r\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)", +		   "CoexVer/ FwVer/ PatchVer", +		   glcoex_ver_date_8723b_2ant, glcoex_ver_8723b_2ant, +		   fw_ver, bt_patch_ver, bt_patch_ver); +	CL_PRINTF(cli_buf); + +	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); +	btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL, +			   &wifi_dot11_chnl); +	btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl); + +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)", +		   "Dot11 channel / HsChnl(HsMode)", +		   wifi_dot11_chnl, wifi_hs_chnl, bt_hs_on); +	CL_PRINTF(cli_buf); + +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", +		   "H2C Wifi inform bt chnl Info", coex_dm->wifi_chnl_info[0], +		   coex_dm->wifi_chnl_info[1], coex_dm->wifi_chnl_info[2]); +	CL_PRINTF(cli_buf); + +	btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); +	btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", +		   "Wifi rssi/ HS rssi", wifi_rssi, bt_hs_rssi); +	CL_PRINTF(cli_buf); + +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", +		   "Wifi link/ roam/ scan", link, roam, scan); +	CL_PRINTF(cli_buf); + +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, +			   &wifi_traffic_dir); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s ", +		   "Wifi status", (wifi_under_5g ? "5G" : "2.4G"), +		   ((BTC_WIFI_BW_LEGACY == wifi_bw) ? "Legacy" : +		   (((BTC_WIFI_BW_HT40 == wifi_bw) ? "HT40" : "HT20"))), +		   ((!wifi_busy) ? "idle" : +		   ((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ? +		   "uplink" : "downlink"))); +	CL_PRINTF(cli_buf); + +	CL_PRINTF(cli_buf); + +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d", +		   "SCO/HID/PAN/A2DP", +		   bt_link_info->sco_exist, bt_link_info->hid_exist, +		   bt_link_info->pan_exist, bt_link_info->a2dp_exist); +	CL_PRINTF(cli_buf); +	btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO); + +	bt_info_ext = coex_sta->bt_info_ext; +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", +		   "BT Info A2DP rate", +		   (bt_info_ext&BIT0) ? "Basic rate" : "EDR rate"); +	CL_PRINTF(cli_buf); + +	for (i = 0; i < BT_INFO_SRC_8723B_2ANT_MAX; i++) { +		if (coex_sta->bt_info_c2h_cnt[i]) { +			CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, +				   "\r\n %-35s = %02x %02x %02x " +				   "%02x %02x %02x %02x(%d)", +				   glbt_info_src_8723b_2ant[i], +				   coex_sta->bt_info_c2h[i][0], +				   coex_sta->bt_info_c2h[i][1], +				   coex_sta->bt_info_c2h[i][2], +				   coex_sta->bt_info_c2h[i][3], +				   coex_sta->bt_info_c2h[i][4], +				   coex_sta->bt_info_c2h[i][5], +				   coex_sta->bt_info_c2h[i][6], +				   coex_sta->bt_info_c2h_cnt[i]); +			CL_PRINTF(cli_buf); +		} +	} + +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/%s", +		   "PS state, IPS/LPS", +		   ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")), +		   ((coex_sta->under_lps ? "LPS ON" : "LPS OFF"))); +	CL_PRINTF(cli_buf); +	btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD); + +	/* Sw mechanism	*/ +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, +		   "\r\n %-35s", "============[Sw mechanism]============"); +	CL_PRINTF(cli_buf); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", +		   "SM1[ShRf/ LpRA/ LimDig]", coex_dm->cur_rf_rx_lpf_shrink, +		   coex_dm->cur_low_penalty_ra, coex_dm->limited_dig); +	CL_PRINTF(cli_buf); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d(0x%x) ", +		   "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]", +		   coex_dm->cur_agc_table_en, coex_dm->cur_adc_back_off, +		   coex_dm->cur_dac_swing_on, coex_dm->cur_dac_swing_lvl); +	CL_PRINTF(cli_buf); + +	/* Fw mechanism	*/ +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s", +		   "============[Fw mechanism]============"); +	CL_PRINTF(cli_buf); + +	ps_tdma_case = coex_dm->cur_ps_tdma; +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, +		   "\r\n %-35s = %02x %02x %02x %02x %02x case-%d (auto:%d)", +		   "PS TDMA", coex_dm->ps_tdma_para[0], +		   coex_dm->ps_tdma_para[1], coex_dm->ps_tdma_para[2], +		   coex_dm->ps_tdma_para[3], coex_dm->ps_tdma_para[4], +		   ps_tdma_case, coex_dm->auto_tdma_adjust); +	CL_PRINTF(cli_buf); + +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", +		   "DecBtPwr/ IgnWlanAct", coex_dm->cur_dec_bt_pwr, +		   coex_dm->cur_ignore_wlan_act); +	CL_PRINTF(cli_buf); + +	/* Hw setting */ +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s", +		   "============[Hw setting]============"); +	CL_PRINTF(cli_buf); + +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", +		   "RF-A, 0x1e initVal", coex_dm->bt_rf0x1e_backup); +	CL_PRINTF(cli_buf); + +	u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778); +	u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x880); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", +		   "0x778/0x880[29:25]", u8tmp[0], +		   (u32tmp[0]&0x3e000000) >> 25); +	CL_PRINTF(cli_buf); + +	u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x948); +	u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x67); +	u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x765); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", +		   "0x948/ 0x67[5] / 0x765", +		   u32tmp[0], ((u8tmp[0]&0x20) >> 5), u8tmp[1]); +	CL_PRINTF(cli_buf); + +	u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x92c); +	u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x930); +	u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x944); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", +		   "0x92c[1:0]/ 0x930[7:0]/0x944[1:0]", +		   u32tmp[0]&0x3, u32tmp[1]&0xff, u32tmp[2]&0x3); +	CL_PRINTF(cli_buf); + + +	u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x39); +	u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x40); +	u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c); +	u8tmp[2] = btcoexist->btc_read_1byte(btcoexist, 0x64); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, +		   "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", +		   "0x38[11]/0x40/0x4c[24:23]/0x64[0]", +		   ((u8tmp[0] & 0x8)>>3), u8tmp[1], +		   ((u32tmp[0]&0x01800000)>>23), u8tmp[2]&0x1); +	CL_PRINTF(cli_buf); + +	u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550); +	u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", +		   "0x550(bcn ctrl)/0x522", u32tmp[0], u8tmp[0]); +	CL_PRINTF(cli_buf); + +	u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50); +	u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x49c); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", +		   "0xc50(dig)/0x49c(null-drop)", u32tmp[0]&0xff, u8tmp[0]); +	CL_PRINTF(cli_buf); + +	u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xda0); +	u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0xda4); +	u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0xda8); +	u32tmp[3] = btcoexist->btc_read_4byte(btcoexist, 0xcf0); + +	u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa5b); +	u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xa5c); + +	fa_ofdm = ((u32tmp[0]&0xffff0000) >> 16) + +		  ((u32tmp[1]&0xffff0000) >> 16) + +		   (u32tmp[1] & 0xffff) + +		   (u32tmp[2] & 0xffff) + +		  ((u32tmp[3]&0xffff0000) >> 16) + +		   (u32tmp[3] & 0xffff); +	fa_cck = (u8tmp[0] << 8) + u8tmp[1]; + +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", +		   "OFDM-CCA/OFDM-FA/CCK-FA", +		   u32tmp[0]&0xffff, fa_ofdm, fa_cck); +	CL_PRINTF(cli_buf); + +	u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0); +	u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4); +	u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8); +	u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x6cc); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, +		   "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", +		   "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", +		   u32tmp[0], u32tmp[1], u32tmp[2], u8tmp[0]); +	CL_PRINTF(cli_buf); + +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", +		   "0x770(high-pri rx/tx)", +		   coex_sta->high_priority_rx, coex_sta->high_priority_tx); +	CL_PRINTF(cli_buf); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", +		   "0x774(low-pri rx/tx)", coex_sta->low_priority_rx, +		   coex_sta->low_priority_tx); +	CL_PRINTF(cli_buf); +#if (BT_AUTO_REPORT_ONLY_8723B_2ANT == 1) +	btc8723b2ant_monitor_bt_ctr(btcoexist); +#endif +	btcoexist->btc_disp_dbg_msg(btcoexist, +	BTC_DBG_DISP_COEX_STATISTICS); +} + + +void ex_halbtc8723b2ant_ips_notify(struct btc_coexist *btcoexist, u8 type) +{ +	if (BTC_IPS_ENTER == type) { +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex], IPS ENTER notify\n"); +		coex_sta->under_ips = true; +		btc8723b2ant_coex_alloff(btcoexist); +	} else if (BTC_IPS_LEAVE == type) { +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex], IPS LEAVE notify\n"); +		coex_sta->under_ips = false; +	} +} + +void ex_halbtc8723b2ant_lps_notify(struct btc_coexist *btcoexist, u8 type) +{ +	if (BTC_LPS_ENABLE == type) { +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex], LPS ENABLE notify\n"); +		coex_sta->under_lps = true; +	} else if (BTC_LPS_DISABLE == type) { +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex], LPS DISABLE notify\n"); +		coex_sta->under_lps = false; +	} +} + +void ex_halbtc8723b2ant_scan_notify(struct btc_coexist *btcoexist, u8 type) +{ +	if (BTC_SCAN_START == type) +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex], SCAN START notify\n"); +	else if (BTC_SCAN_FINISH == type) +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex], SCAN FINISH notify\n"); +} + +void ex_halbtc8723b2ant_connect_notify(struct btc_coexist *btcoexist, u8 type) +{ +	if (BTC_ASSOCIATE_START == type) +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex], CONNECT START notify\n"); +	else if (BTC_ASSOCIATE_FINISH == type) +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex], CONNECT FINISH notify\n"); +} + +void btc8723b_med_stat_notify(struct btc_coexist *btcoexist, +					    u8 type) +{ +	u8 h2c_parameter[3] = {0}; +	u32 wifi_bw; +	u8 wifi_central_chnl; + +	if (BTC_MEDIA_CONNECT == type) +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex], MEDIA connect notify\n"); +	else +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex], MEDIA disconnect notify\n"); + +	/* only 2.4G we need to inform bt the chnl mask */ +	btcoexist->btc_get(btcoexist, +		BTC_GET_U1_WIFI_CENTRAL_CHNL, &wifi_central_chnl); +	if ((BTC_MEDIA_CONNECT == type) && +	    (wifi_central_chnl <= 14)) { +		h2c_parameter[0] = 0x1; +		h2c_parameter[1] = wifi_central_chnl; +		btcoexist->btc_get(btcoexist, +			BTC_GET_U4_WIFI_BW, &wifi_bw); +		if (BTC_WIFI_BW_HT40 == wifi_bw) +			h2c_parameter[2] = 0x30; +		else +			h2c_parameter[2] = 0x20; +	} + +	coex_dm->wifi_chnl_info[0] = h2c_parameter[0]; +	coex_dm->wifi_chnl_info[1] = h2c_parameter[1]; +	coex_dm->wifi_chnl_info[2] = h2c_parameter[2]; + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, +		  "[BTCoex], FW write 0x66=0x%x\n", +		  h2c_parameter[0] << 16 | h2c_parameter[1] << 8 | +		  h2c_parameter[2]); + +	btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter); +} + +void ex_halbtc8723b2ant_special_packet_notify(struct btc_coexist *btcoexist, +					      u8 type) +{ +	if (type == BTC_PACKET_DHCP) +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex], DHCP Packet notify\n"); +} + +void ex_halbtc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist, +				       u8 *tmpbuf, u8 length) +{ +	u8 bt_info = 0; +	u8 i, rsp_source = 0; +	bool bt_busy = false, limited_dig = false; +	bool wifi_connected = false; + +	coex_sta->c2h_bt_info_req_sent = false; + +	rsp_source = tmpbuf[0]&0xf; +	if (rsp_source >= BT_INFO_SRC_8723B_2ANT_MAX) +		rsp_source = BT_INFO_SRC_8723B_2ANT_WIFI_FW; +	coex_sta->bt_info_c2h_cnt[rsp_source]++; + +	BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +		  "[BTCoex], Bt info[%d], length=%d, hex data=[", +		  rsp_source, length); +	for (i = 0; i < length; i++) { +		coex_sta->bt_info_c2h[rsp_source][i] = tmpbuf[i]; +		if (i == 1) +			bt_info = tmpbuf[i]; +		if (i == length-1) +			BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +				  "0x%02x]\n", tmpbuf[i]); +		else +			BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +				  "0x%02x, ", tmpbuf[i]); +	} + +	if (btcoexist->manual_control) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +			  "[BTCoex], BtInfoNotify(), " +			  "return for Manual CTRL<===\n"); +		return; +	} + +	if (BT_INFO_SRC_8723B_2ANT_WIFI_FW != rsp_source) { +		coex_sta->bt_retry_cnt =	/* [3:0]*/ +			coex_sta->bt_info_c2h[rsp_source][2] & 0xf; + +		coex_sta->bt_rssi = +			coex_sta->bt_info_c2h[rsp_source][3] * 2 + 10; + +		coex_sta->bt_info_ext = +			coex_sta->bt_info_c2h[rsp_source][4]; + +		/* Here we need to resend some wifi info to BT +		 * because bt is reset and loss of the info. +		 */ +		if ((coex_sta->bt_info_ext & BIT1)) { +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], BT ext info bit1 check," +				  " send wifi BW&Chnl to BT!!\n"); +			btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, +					   &wifi_connected); +			if (wifi_connected) +				btc8723b_med_stat_notify(btcoexist, +							 BTC_MEDIA_CONNECT); +			else +				btc8723b_med_stat_notify(btcoexist, +							 BTC_MEDIA_DISCONNECT); +		} + +		if ((coex_sta->bt_info_ext & BIT3)) { +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], BT ext info bit3 check, " +				  "set BT NOT to ignore Wlan active!!\n"); +			btc8723b2ant_ignore_wlan_act(btcoexist, FORCE_EXEC, +						     false); +		} else { +			/* BT already NOT ignore Wlan active, do nothing here.*/ +		} +#if (BT_AUTO_REPORT_ONLY_8723B_2ANT == 0) +		if ((coex_sta->bt_info_ext & BIT4)) { +			/* BT auto report already enabled, do nothing*/ +		} else { +			btc8723b2ant_bt_auto_report(btcoexist, FORCE_EXEC, +						    true); +		} +#endif +	} + +	/* check BIT2 first ==> check if bt is under inquiry or page scan*/ +	if (bt_info & BT_INFO_8723B_2ANT_B_INQ_PAGE) +		coex_sta->c2h_bt_inquiry_page = true; +	else +		coex_sta->c2h_bt_inquiry_page = false; + +	/* set link exist status*/ +	if (!(bt_info & BT_INFO_8723B_2ANT_B_CONNECTION)) { +		coex_sta->bt_link_exist = false; +		coex_sta->pan_exist = false; +		coex_sta->a2dp_exist = false; +		coex_sta->hid_exist = false; +		coex_sta->sco_exist = false; +	} else { /*  connection exists */ +		coex_sta->bt_link_exist = true; +		if (bt_info & BT_INFO_8723B_2ANT_B_FTP) +			coex_sta->pan_exist = true; +		else +			coex_sta->pan_exist = false; +		if (bt_info & BT_INFO_8723B_2ANT_B_A2DP) +			coex_sta->a2dp_exist = true; +		else +			coex_sta->a2dp_exist = false; +		if (bt_info & BT_INFO_8723B_2ANT_B_HID) +			coex_sta->hid_exist = true; +		else +			coex_sta->hid_exist = false; +		if (bt_info & BT_INFO_8723B_2ANT_B_SCO_ESCO) +			coex_sta->sco_exist = true; +		else +			coex_sta->sco_exist = false; +	} + +	btc8723b2ant_update_bt_link_info(btcoexist); + +	if (!(bt_info & BT_INFO_8723B_2ANT_B_CONNECTION)) { +		coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_NON_CONNECTED_IDLE; +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +			  "[BTCoex], BtInfoNotify(), " +			  "BT Non-Connected idle!!!\n"); +	/* connection exists but no busy */ +	} else if (bt_info == BT_INFO_8723B_2ANT_B_CONNECTION) { +		coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_CONNECTED_IDLE; +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +			  "[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n"); +	} else if ((bt_info & BT_INFO_8723B_2ANT_B_SCO_ESCO) || +		   (bt_info & BT_INFO_8723B_2ANT_B_SCO_BUSY)) { +		coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_SCO_BUSY; +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +			  "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n"); +	} else if (bt_info & BT_INFO_8723B_2ANT_B_ACL_BUSY) { +		coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_ACL_BUSY; +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +			  "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n"); +	} else { +		coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_MAX; +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +			  "[BTCoex], BtInfoNotify(), " +			  "BT Non-Defined state!!!\n"); +	} + +	if ((BT_8723B_2ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) || +	    (BT_8723B_2ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) || +	    (BT_8723B_2ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status)) { +		bt_busy = true; +		limited_dig = true; +	} else { +		bt_busy = false; +		limited_dig = false; +	} + +	btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy); + +	coex_dm->limited_dig = limited_dig; +	btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_LIMITED_DIG, &limited_dig); + +	btc8723b2ant_run_coexist_mechanism(btcoexist); +} + +void ex_halbtc8723b2ant_stack_operation_notify(struct btc_coexist *btcoexist, +					       u8 type) +{ +	if (BTC_STACK_OP_INQ_PAGE_PAIR_START == type) +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex],StackOP Inquiry/page/pair start notify\n"); +	else if (BTC_STACK_OP_INQ_PAGE_PAIR_FINISH == type) +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex],StackOP Inquiry/page/pair finish notify\n"); +} + +void ex_halbtc8723b2ant_halt_notify(struct btc_coexist *btcoexist) +{ +	BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, "[BTCoex], Halt notify\n"); + +	btc8723b2ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true); +	btc8723b_med_stat_notify(btcoexist, BTC_MEDIA_DISCONNECT); +} + +void ex_halbtc8723b2ant_periodical(struct btc_coexist *btcoexist) +{ +	struct btc_board_info *board_info = &btcoexist->board_info; +	struct btc_stack_info *stack_info = &btcoexist->stack_info; +	static u8 dis_ver_info_cnt; +	u32 fw_ver = 0, bt_patch_ver = 0; + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +		  "[BTCoex], ==========================" +		  "Periodical===========================\n"); + +	if (dis_ver_info_cnt <= 5) { +		dis_ver_info_cnt += 1; +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, +			  "[BTCoex], ****************************" +			  "************************************\n"); +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, +			  "[BTCoex], Ant PG Num/ Ant Mech/ " +			  "Ant Pos = %d/ %d/ %d\n", board_info->pg_ant_num, +			  board_info->btdm_ant_num, board_info->btdm_ant_pos); +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, +			  "[BTCoex], BT stack/ hci ext ver = %s / %d\n", +			  ((stack_info->profile_notified) ? "Yes" : "No"), +			  stack_info->hci_version); +		btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, +				   &bt_patch_ver); +		btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, +			  "[BTCoex], CoexVer/ FwVer/ PatchVer = " +			  "%d_%x/ 0x%x/ 0x%x(%d)\n", +			  glcoex_ver_date_8723b_2ant, glcoex_ver_8723b_2ant, +			  fw_ver, bt_patch_ver, bt_patch_ver); +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, +			  "[BTCoex], *****************************" +			  "***********************************\n"); +	} + +#if (BT_AUTO_REPORT_ONLY_8723B_2ANT == 0) +	btc8723b2ant_query_bt_info(btcoexist); +	btc8723b2ant_monitor_bt_ctr(btcoexist); +	btc8723b2ant_monitor_bt_enable_disable(btcoexist); +#else +	if (btc8723b2ant_is_wifi_status_changed(btcoexist) || +	    coex_dm->auto_tdma_adjust) +		btc8723b2ant_run_coexist_mechanism(btcoexist); +#endif +} diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.h b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.h new file mode 100644 index 00000000000..e0ad8e545f8 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.h @@ -0,0 +1,173 @@ +/****************************************************************************** + * + * Copyright(c) 2012  Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger <Larry.Finger@lwfinger.net> + * + *****************************************************************************/ +#ifndef _HAL8723B_2_ANT +#define _HAL8723B_2_ANT + +/************************************************************************ + * The following is for 8723B 2Ant BT Co-exist definition + ************************************************************************/ +#define	BT_AUTO_REPORT_ONLY_8723B_2ANT			1 + +#define	BT_INFO_8723B_2ANT_B_FTP			BIT7 +#define	BT_INFO_8723B_2ANT_B_A2DP			BIT6 +#define	BT_INFO_8723B_2ANT_B_HID			BIT5 +#define	BT_INFO_8723B_2ANT_B_SCO_BUSY			BIT4 +#define	BT_INFO_8723B_2ANT_B_ACL_BUSY			BIT3 +#define	BT_INFO_8723B_2ANT_B_INQ_PAGE			BIT2 +#define	BT_INFO_8723B_2ANT_B_SCO_ESCO			BIT1 +#define	BT_INFO_8723B_2ANT_B_CONNECTION			BIT0 + +#define BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT		2 + +enum BT_INFO_SRC_8723B_2ANT { +	BT_INFO_SRC_8723B_2ANT_WIFI_FW			= 0x0, +	BT_INFO_SRC_8723B_2ANT_BT_RSP			= 0x1, +	BT_INFO_SRC_8723B_2ANT_BT_ACTIVE_SEND		= 0x2, +	BT_INFO_SRC_8723B_2ANT_MAX +}; + +enum BT_8723B_2ANT_BT_STATUS { +	BT_8723B_2ANT_BT_STATUS_NON_CONNECTED_IDLE	= 0x0, +	BT_8723B_2ANT_BT_STATUS_CONNECTED_IDLE		= 0x1, +	BT_8723B_2ANT_BT_STATUS_INQ_PAGE		= 0x2, +	BT_8723B_2ANT_BT_STATUS_ACL_BUSY		= 0x3, +	BT_8723B_2ANT_BT_STATUS_SCO_BUSY		= 0x4, +	BT_8723B_2ANT_BT_STATUS_ACL_SCO_BUSY		= 0x5, +	BT_8723B_2ANT_BT_STATUS_MAX +}; + +enum BT_8723B_2ANT_COEX_ALGO { +	BT_8723B_2ANT_COEX_ALGO_UNDEFINED		= 0x0, +	BT_8723B_2ANT_COEX_ALGO_SCO			= 0x1, +	BT_8723B_2ANT_COEX_ALGO_HID			= 0x2, +	BT_8723B_2ANT_COEX_ALGO_A2DP			= 0x3, +	BT_8723B_2ANT_COEX_ALGO_A2DP_PANHS		= 0x4, +	BT_8723B_2ANT_COEX_ALGO_PANEDR			= 0x5, +	BT_8723B_2ANT_COEX_ALGO_PANHS			= 0x6, +	BT_8723B_2ANT_COEX_ALGO_PANEDR_A2DP		= 0x7, +	BT_8723B_2ANT_COEX_ALGO_PANEDR_HID		= 0x8, +	BT_8723B_2ANT_COEX_ALGO_HID_A2DP_PANEDR		= 0x9, +	BT_8723B_2ANT_COEX_ALGO_HID_A2DP		= 0xa, +	BT_8723B_2ANT_COEX_ALGO_MAX			= 0xb, +}; + +struct coex_dm_8723b_2ant { +	/* fw mechanism */ +	bool pre_dec_bt_pwr; +	bool cur_dec_bt_pwr; +	u8 pre_fw_dac_swing_lvl; +	u8 cur_fw_dac_swing_lvl; +	bool cur_ignore_wlan_act; +	bool pre_ignore_wlan_act; +	u8 pre_ps_tdma; +	u8 cur_ps_tdma; +	u8 ps_tdma_para[5]; +	u8 tdma_adj_type; +	bool reset_tdma_adjust; +	bool auto_tdma_adjust; +	bool pre_ps_tdma_on; +	bool cur_ps_tdma_on; +	bool pre_bt_auto_report; +	bool cur_bt_auto_report; + +	/* sw mechanism */ +	bool pre_rf_rx_lpf_shrink; +	bool cur_rf_rx_lpf_shrink; +	u32 bt_rf0x1e_backup; +	bool pre_low_penalty_ra; +	bool cur_low_penalty_ra; +	bool pre_dac_swing_on; +	u32 pre_dac_swing_lvl; +	bool cur_dac_swing_on; +	u32 cur_dac_swing_lvl; +	bool pre_adc_back_off; +	bool cur_adc_back_off; +	bool pre_agc_table_en; +	bool cur_agc_table_en; +	u32 pre_val0x6c0; +	u32 cur_val0x6c0; +	u32 pre_val0x6c4; +	u32 cur_val0x6c4; +	u32 pre_val0x6c8; +	u32 cur_val0x6c8; +	u8 pre_val0x6cc; +	u8 cur_val0x6cc; +	bool limited_dig; + +	/* algorithm related */ +	u8 pre_algorithm; +	u8 cur_algorithm; +	u8 bt_status; +	u8 wifi_chnl_info[3]; + +	bool need_recover_0x948; +	u16 backup_0x948; +}; + +struct coex_sta_8723b_2ant { +	bool bt_link_exist; +	bool sco_exist; +	bool a2dp_exist; +	bool hid_exist; +	bool pan_exist; + +	bool under_lps; +	bool under_ips; +	u32 high_priority_tx; +	u32 high_priority_rx; +	u32 low_priority_tx; +	u32 low_priority_rx; +	u8 bt_rssi; +	u8 pre_bt_rssi_state; +	u8 pre_wifi_rssi_state[4]; +	bool c2h_bt_info_req_sent; +	u8 bt_info_c2h[BT_INFO_SRC_8723B_2ANT_MAX][10]; +	u32 bt_info_c2h_cnt[BT_INFO_SRC_8723B_2ANT_MAX]; +	bool c2h_bt_inquiry_page; +	u8 bt_retry_cnt; +	u8 bt_info_ext; +}; + +/********************************************************************* + * The following is interface which will notify coex module. + *********************************************************************/ +void ex_halbtc8723b2ant_init_hwconfig(struct btc_coexist *btcoexist); +void ex_halbtc8723b2ant_init_coex_dm(struct btc_coexist *btcoexist); +void ex_halbtc8723b2ant_ips_notify(struct btc_coexist *btcoexist, u8 type); +void ex_halbtc8723b2ant_lps_notify(struct btc_coexist *btcoexist, u8 type); +void ex_halbtc8723b2ant_scan_notify(struct btc_coexist *btcoexist, u8 type); +void ex_halbtc8723b2ant_connect_notify(struct btc_coexist *btcoexist, u8 type); +void btc8723b_med_stat_notify(struct btc_coexist *btcoexist, u8 type); +void ex_halbtc8723b2ant_special_packet_notify(struct btc_coexist *btcoexist, +					      u8 type); +void ex_halbtc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist, +				       u8 *tmpbuf, u8 length); +void ex_halbtc8723b2ant_stack_operation_notify(struct btc_coexist *btcoexist, +					       u8 type); +void ex_halbtc8723b2ant_halt_notify(struct btc_coexist *btcoexist); +void ex_halbtc8723b2ant_periodical(struct btc_coexist *btcoexist); +void ex_halbtc8723b2ant_display_coex_info(struct btc_coexist *btcoexist); + +#endif diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c new file mode 100644 index 00000000000..33da3dfcfa4 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c @@ -0,0 +1,1001 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2013 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ + +#include "halbt_precomp.h" + +/*********************************************** + *		Global variables + ***********************************************/ + +struct btc_coexist gl_bt_coexist; + +u32 btc_dbg_type[BTC_MSG_MAX]; +static u8 btc_dbg_buf[100]; + +/*************************************************** + *		Debug related function + ***************************************************/ +static bool halbtc_is_bt_coexist_available(struct btc_coexist *btcoexist) +{ +	if (!btcoexist->binded || NULL == btcoexist->adapter) +		return false; + +	return true; +} + +static bool halbtc_is_wifi_busy(struct rtl_priv *rtlpriv) +{ +	if (rtlpriv->link_info.busytraffic) +		return true; +	else +		return false; +} + +static void halbtc_dbg_init(void) +{ +	u8 i; + +	for (i = 0; i < BTC_MSG_MAX; i++) +		btc_dbg_type[i] = 0; + +	btc_dbg_type[BTC_MSG_INTERFACE] = +/*			INTF_INIT				| */ +/*			INTF_NOTIFY				| */ +			0; + +	btc_dbg_type[BTC_MSG_ALGORITHM] = +/*			ALGO_BT_RSSI_STATE			| */ +/*			ALGO_WIFI_RSSI_STATE			| */ +/*			ALGO_BT_MONITOR				| */ +/*			ALGO_TRACE				| */ +/*			ALGO_TRACE_FW				| */ +/*			ALGO_TRACE_FW_DETAIL			| */ +/*			ALGO_TRACE_FW_EXEC			| */ +/*			ALGO_TRACE_SW				| */ +/*			ALGO_TRACE_SW_DETAIL			| */ +/*			ALGO_TRACE_SW_EXEC			| */ +			0; +} + +static bool halbtc_is_bt40(struct rtl_priv *adapter) +{ +	struct rtl_priv *rtlpriv = adapter; +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	bool is_ht40 = true; +	enum ht_channel_width bw = rtlphy->current_chan_bw; + +	if (bw == HT_CHANNEL_WIDTH_20) +		is_ht40 = false; +	else if (bw == HT_CHANNEL_WIDTH_20_40) +		is_ht40 = true; + +	return is_ht40; +} + +static bool halbtc_legacy(struct rtl_priv *adapter) +{ +	struct rtl_priv *rtlpriv = adapter; +	struct rtl_mac *mac = rtl_mac(rtlpriv); + +	bool is_legacy = false; + +	if ((mac->mode == WIRELESS_MODE_B) || (mac->mode == WIRELESS_MODE_B)) +		is_legacy = true; + +	return is_legacy; +} + +bool halbtc_is_wifi_uplink(struct rtl_priv *adapter) +{ +	struct rtl_priv *rtlpriv = adapter; + +	if (rtlpriv->link_info.tx_busy_traffic) +		return true; +	else +		return false; +} + +static u32 halbtc_get_wifi_bw(struct btc_coexist *btcoexist) +{ +	struct rtl_priv *rtlpriv = +		(struct rtl_priv *)btcoexist->adapter; +	u32 wifi_bw = BTC_WIFI_BW_HT20; + +	if (halbtc_is_bt40(rtlpriv)) { +		wifi_bw = BTC_WIFI_BW_HT40; +	} else { +		if (halbtc_legacy(rtlpriv)) +			wifi_bw = BTC_WIFI_BW_LEGACY; +		else +			wifi_bw = BTC_WIFI_BW_HT20; +	} +	return wifi_bw; +} + +static u8 halbtc_get_wifi_central_chnl(struct btc_coexist *btcoexist) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_phy	*rtlphy = &(rtlpriv->phy); +	u8 chnl = 1; + +	if (rtlphy->current_channel != 0) +		chnl = rtlphy->current_channel; +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +		  "static halbtc_get_wifi_central_chnl:%d\n", chnl); +	return chnl; +} + +static void halbtc_leave_lps(struct btc_coexist *btcoexist) +{ +	struct rtl_priv *rtlpriv; +	struct rtl_ps_ctl *ppsc; +	bool ap_enable = false; + +	rtlpriv = btcoexist->adapter; +	ppsc = rtl_psc(rtlpriv); + +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, +			   &ap_enable); + +	if (ap_enable) { +		pr_info("halbtc_leave_lps()<--dont leave lps under AP mode\n"); +		return; +	} + +	btcoexist->bt_info.bt_ctrl_lps = true; +	btcoexist->bt_info.bt_lps_on = false; +} + +static void halbtc_enter_lps(struct btc_coexist *btcoexist) +{ +	struct rtl_priv *rtlpriv; +	struct rtl_ps_ctl *ppsc; +	bool ap_enable = false; + +	rtlpriv = btcoexist->adapter; +	ppsc = rtl_psc(rtlpriv); + +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, +			   &ap_enable); + +	if (ap_enable) { +		pr_info("halbtc_enter_lps()<--dont enter lps under AP mode\n"); +		return; +	} + +	btcoexist->bt_info.bt_ctrl_lps = true; +	btcoexist->bt_info.bt_lps_on = false; +} + +static void halbtc_normal_lps(struct btc_coexist *btcoexist) +{ +	if (btcoexist->bt_info.bt_ctrl_lps) { +		btcoexist->bt_info.bt_lps_on = false; +		btcoexist->bt_info.bt_ctrl_lps = false; +	} +} + +static void halbtc_leave_low_power(void) +{ +} + +static void halbtc_nomal_low_power(void) +{ +} + +static void halbtc_disable_low_power(void) +{ +} + +static void halbtc_aggregation_check(void) +{ +} + +static u32 halbtc_get_bt_patch_version(struct btc_coexist *btcoexist) +{ +	return 0; +} + +static s32 halbtc_get_wifi_rssi(struct rtl_priv *adapter) +{ +	struct rtl_priv *rtlpriv = adapter; +	s32	undec_sm_pwdb = 0; + +	if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) +		undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; +	else /* associated entry pwdb */ +		undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; +	return undec_sm_pwdb; +} + +static bool halbtc_get(void *void_btcoexist, u8 get_type, void *out_buf) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)void_btcoexist; +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	struct rtl_mac *mac = rtl_mac(rtlpriv); +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	bool *bool_tmp = (bool *)out_buf; +	int *s32_tmp = (int *)out_buf; +	u32 *u32_tmp = (u32 *)out_buf; +	u8 *u8_tmp = (u8 *)out_buf; +	bool tmp = false; + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return false; + +	switch (get_type) { +	case BTC_GET_BL_HS_OPERATION: +		*bool_tmp = false; +		break; +	case BTC_GET_BL_HS_CONNECTING: +		*bool_tmp = false; +		break; +	case BTC_GET_BL_WIFI_CONNECTED: +		if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) +			tmp = true; +		*bool_tmp = tmp; +		break; +	case BTC_GET_BL_WIFI_BUSY: +		if (halbtc_is_wifi_busy(rtlpriv)) +			*bool_tmp = true; +		else +			*bool_tmp = false; +		break; +	case BTC_GET_BL_WIFI_SCAN: +		if (mac->act_scanning) +			*bool_tmp = true; +		else +			*bool_tmp = false; +		break; +	case BTC_GET_BL_WIFI_LINK: +		if (mac->link_state == MAC80211_LINKING) +			*bool_tmp = true; +		else +			*bool_tmp = false; +		break; +	case BTC_GET_BL_WIFI_ROAM:	/*TODO*/ +		if (mac->link_state == MAC80211_LINKING) +			*bool_tmp = true; +		else +			*bool_tmp = false; +		break; +	case BTC_GET_BL_WIFI_4_WAY_PROGRESS:	/*TODO*/ +			*bool_tmp = false; + +		break; +	case BTC_GET_BL_WIFI_UNDER_5G: +		*bool_tmp = false; /*TODO*/ + +	case BTC_GET_BL_WIFI_DHCP:	/*TODO*/ +		break; +	case BTC_GET_BL_WIFI_SOFTAP_IDLE: +		*bool_tmp = true; +		break; +	case BTC_GET_BL_WIFI_SOFTAP_LINKING: +		*bool_tmp = false; +		break; +	case BTC_GET_BL_WIFI_IN_EARLY_SUSPEND: +		*bool_tmp = false; +		break; +	case BTC_GET_BL_WIFI_AP_MODE_ENABLE: +		*bool_tmp = false; +		break; +	case BTC_GET_BL_WIFI_ENABLE_ENCRYPTION: +		if (NO_ENCRYPTION == rtlpriv->sec.pairwise_enc_algorithm) +			*bool_tmp = false; +		else +			*bool_tmp = true; +		break; +	case BTC_GET_BL_WIFI_UNDER_B_MODE: +		*bool_tmp = false; /*TODO*/ +		break; +	case BTC_GET_BL_EXT_SWITCH: +		*bool_tmp = false; +		break; +	case BTC_GET_S4_WIFI_RSSI: +		*s32_tmp = halbtc_get_wifi_rssi(rtlpriv); +		break; +	case BTC_GET_S4_HS_RSSI:	/*TODO*/ +		*s32_tmp = halbtc_get_wifi_rssi(rtlpriv); +		break; +	case BTC_GET_U4_WIFI_BW: +		*u32_tmp = halbtc_get_wifi_bw(btcoexist); +		break; +	case BTC_GET_U4_WIFI_TRAFFIC_DIRECTION: +		if (halbtc_is_wifi_uplink(rtlpriv)) +			*u32_tmp = BTC_WIFI_TRAFFIC_TX; +		else +			*u32_tmp = BTC_WIFI_TRAFFIC_RX; +		break; +	case BTC_GET_U4_WIFI_FW_VER: +		*u32_tmp = rtlhal->fw_version; +		break; +	case BTC_GET_U4_BT_PATCH_VER: +		*u32_tmp = halbtc_get_bt_patch_version(btcoexist); +		break; +	case BTC_GET_U1_WIFI_DOT11_CHNL: +		*u8_tmp = rtlphy->current_channel; +		break; +	case BTC_GET_U1_WIFI_CENTRAL_CHNL: +		*u8_tmp = halbtc_get_wifi_central_chnl(btcoexist); +		break; +	case BTC_GET_U1_WIFI_HS_CHNL: +		*u8_tmp = 1;/*BT_OperateChnl(rtlpriv);*/ +		break; +	case BTC_GET_U1_MAC_PHY_MODE: +		*u8_tmp = BTC_MP_UNKNOWN; +		break; + +		/************* 1Ant **************/ +	case BTC_GET_U1_LPS_MODE: +		*u8_tmp = btcoexist->pwr_mode_val[0]; +		break; + +	default: +		break; +	} + +	return true; +} + +static bool halbtc_set(void *void_btcoexist, u8 set_type, void *in_buf) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)void_btcoexist; +	bool *bool_tmp = (bool *)in_buf; +	u8 *u8_tmp = (u8 *)in_buf; +	u32 *u32_tmp = (u32 *)in_buf; + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return false; + +	switch (set_type) { +	/* set some bool type variables. */ +	case BTC_SET_BL_BT_DISABLE: +		btcoexist->bt_info.bt_disabled = *bool_tmp; +		break; +	case BTC_SET_BL_BT_TRAFFIC_BUSY: +		btcoexist->bt_info.bt_busy = *bool_tmp; +		break; +	case BTC_SET_BL_BT_LIMITED_DIG: +		btcoexist->bt_info.limited_dig = *bool_tmp; +		break; +	case BTC_SET_BL_FORCE_TO_ROAM: +		btcoexist->bt_info.force_to_roam = *bool_tmp; +		break; +	case BTC_SET_BL_TO_REJ_AP_AGG_PKT: +		btcoexist->bt_info.reject_agg_pkt = *bool_tmp; +		break; +	case BTC_SET_BL_BT_CTRL_AGG_SIZE: +		btcoexist->bt_info.b_bt_ctrl_buf_size = *bool_tmp; +		break; +	case BTC_SET_BL_INC_SCAN_DEV_NUM: +		btcoexist->bt_info.increase_scan_dev_num = *bool_tmp; +		break; +		/* set some u1Byte type variables. */ +	case BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON: +		btcoexist->bt_info.rssi_adjust_for_agc_table_on = *u8_tmp; +		break; +	case BTC_SET_U1_AGG_BUF_SIZE: +		btcoexist->bt_info.agg_buf_size = *u8_tmp; +		break; +		/* the following are some action which will be triggered */ +	case BTC_SET_ACT_GET_BT_RSSI: +		/*BTHCI_SendGetBtRssiEvent(rtlpriv);*/ +		break; +	case BTC_SET_ACT_AGGREGATE_CTRL: +		halbtc_aggregation_check(); +		break; + +		/* 1Ant */ +	case BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE: +		btcoexist->bt_info.rssi_adjust_for_1ant_coex_type = *u8_tmp; +		break; +	case BTC_SET_UI_SCAN_SIG_COMPENSATION: +	/*	rtlpriv->mlmepriv.scan_compensation = *u8_tmp;  */ +		break; +	case BTC_SET_U1_1ANT_LPS: +		btcoexist->bt_info.lps_1ant = *u8_tmp; +		break; +	case BTC_SET_U1_1ANT_RPWM: +		btcoexist->bt_info.rpwm_1ant = *u8_tmp; +		break; +	/* the following are some action which will be triggered  */ +	case BTC_SET_ACT_LEAVE_LPS: +		halbtc_leave_lps(btcoexist); +		break; +	case BTC_SET_ACT_ENTER_LPS: +		halbtc_enter_lps(btcoexist); +		break; +	case BTC_SET_ACT_NORMAL_LPS: +		halbtc_normal_lps(btcoexist); +		break; +	case BTC_SET_ACT_DISABLE_LOW_POWER: +		halbtc_disable_low_power(); +		break; +	case BTC_SET_ACT_UPDATE_ra_mask: +		btcoexist->bt_info.ra_mask = *u32_tmp; +		break; +	case BTC_SET_ACT_SEND_MIMO_PS: +		break; +	case BTC_SET_ACT_INC_FORCE_EXEC_PWR_CMD_CNT: +		btcoexist->bt_info.force_exec_pwr_cmd_cnt++; +		break; +	case BTC_SET_ACT_CTRL_BT_INFO: /*wait for 8812/8821*/ +		break; +	case BTC_SET_ACT_CTRL_BT_COEX: +		break; +	default: +		break; +	} + +	return true; +} + +static void halbtc_display_coex_statistics(struct btc_coexist *btcoexist) +{ +} + +static void halbtc_display_bt_link_info(struct btc_coexist *btcoexist) +{ +} + +static void halbtc_display_bt_fw_info(struct btc_coexist *btcoexist) +{ +} + +static void halbtc_display_fw_pwr_mode_cmd(struct btc_coexist *btcoexist) +{ +} + +/************************************************************ + *		IO related function + ************************************************************/ +static u8 halbtc_read_1byte(void *bt_context, u32 reg_addr) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; +	struct rtl_priv *rtlpriv = btcoexist->adapter; + +	return	rtl_read_byte(rtlpriv, reg_addr); +} + +static u16 halbtc_read_2byte(void *bt_context, u32 reg_addr) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; +	struct rtl_priv *rtlpriv = btcoexist->adapter; + +	return	rtl_read_word(rtlpriv, reg_addr); +} + +static u32 halbtc_read_4byte(void *bt_context, u32 reg_addr) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; +	struct rtl_priv *rtlpriv = btcoexist->adapter; + +	return	rtl_read_dword(rtlpriv, reg_addr); +} + +static void halbtc_write_1byte(void *bt_context, u32 reg_addr, u8 data) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; +	struct rtl_priv *rtlpriv = btcoexist->adapter; + +	rtl_write_byte(rtlpriv, reg_addr, data); +} + +static void halbtc_bitmask_write_1byte(void *bt_context, u32 reg_addr, +				       u32 bit_mask, u8 data) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	u8 original_value, bit_shift = 0; +	u8 i; + +	if (bit_mask != MASKDWORD) {/*if not "double word" write*/ +		original_value = rtl_read_byte(rtlpriv, reg_addr); +		for (i = 0; i <= 7; i++) { +			if ((bit_mask>>i) & 0x1) +				break; +		} +		bit_shift = i; +		data = (original_value & (~bit_mask)) | +			((data << bit_shift) & bit_mask); +	} +	rtl_write_byte(rtlpriv, reg_addr, data); +} + +static void halbtc_write_2byte(void *bt_context, u32 reg_addr, u16 data) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; +	struct rtl_priv *rtlpriv = btcoexist->adapter; + +	rtl_write_word(rtlpriv, reg_addr, data); +} + +static void halbtc_write_4byte(void *bt_context, u32 reg_addr, u32 data) +{ +	struct btc_coexist *btcoexist = +		(struct btc_coexist *)bt_context; +	struct rtl_priv *rtlpriv = btcoexist->adapter; + +	rtl_write_dword(rtlpriv, reg_addr, data); +} + +static void halbtc_set_bbreg(void *bt_context, u32 reg_addr, u32 bit_mask, +			     u32 data) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; +	struct rtl_priv *rtlpriv = btcoexist->adapter; + +	rtl_set_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask, data); +} + +static u32 halbtc_get_bbreg(void *bt_context, u32 reg_addr, u32 bit_mask) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; +	struct rtl_priv *rtlpriv = btcoexist->adapter; + +	return rtl_get_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask); +} + +static void halbtc_set_rfreg(void *bt_context, u8 rf_path, u32 reg_addr, +			     u32 bit_mask, u32 data) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; +	struct rtl_priv *rtlpriv = btcoexist->adapter; + +	rtl_set_rfreg(rtlpriv->mac80211.hw, rf_path, reg_addr, bit_mask, data); +} + +static u32 halbtc_get_rfreg(void *bt_context, u8 rf_path, u32 reg_addr, +			    u32 bit_mask) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; +	struct rtl_priv *rtlpriv = btcoexist->adapter; + +	return rtl_get_rfreg(rtlpriv->mac80211.hw, rf_path, reg_addr, bit_mask); +} + +static void halbtc_fill_h2c_cmd(void *bt_context, u8 element_id, +				u32 cmd_len, u8 *cmd_buf) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; +	struct rtl_priv *rtlpriv = btcoexist->adapter; + +	rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->mac80211.hw, element_id, +					cmd_len, cmd_buf); +} + +static void halbtc_display_dbg_msg(void *bt_context, u8 disp_type) +{ +	struct btc_coexist *btcoexist =	(struct btc_coexist *)bt_context; +	switch (disp_type) { +	case BTC_DBG_DISP_COEX_STATISTICS: +		halbtc_display_coex_statistics(btcoexist); +		break; +	case BTC_DBG_DISP_BT_LINK_INFO: +		halbtc_display_bt_link_info(btcoexist); +		break; +	case BTC_DBG_DISP_BT_FW_VER: +		halbtc_display_bt_fw_info(btcoexist); +		break; +	case BTC_DBG_DISP_FW_PWR_MODE_CMD: +		halbtc_display_fw_pwr_mode_cmd(btcoexist); +		break; +	default: +		break; +	} +} + +/***************************************************************** + *         Extern functions called by other module + *****************************************************************/ +bool exhalbtc_initlize_variables(struct rtl_priv *adapter) +{ +	struct btc_coexist *btcoexist = &gl_bt_coexist; + +	btcoexist->statistics.cnt_bind++; + +	halbtc_dbg_init(); + +	if (btcoexist->binded) +		return false; +	else +		btcoexist->binded = true; + +	btcoexist->chip_interface = BTC_INTF_UNKNOWN; + +	if (NULL == btcoexist->adapter) +		btcoexist->adapter = adapter; + +	btcoexist->stack_info.profile_notified = false; + +	btcoexist->btc_read_1byte = halbtc_read_1byte; +	btcoexist->btc_write_1byte = halbtc_write_1byte; +	btcoexist->btc_write_1byte_bitmask = halbtc_bitmask_write_1byte; +	btcoexist->btc_read_2byte = halbtc_read_2byte; +	btcoexist->btc_write_2byte = halbtc_write_2byte; +	btcoexist->btc_read_4byte = halbtc_read_4byte; +	btcoexist->btc_write_4byte = halbtc_write_4byte; + +	btcoexist->btc_set_bb_reg = halbtc_set_bbreg; +	btcoexist->btc_get_bb_reg = halbtc_get_bbreg; + +	btcoexist->btc_set_rf_reg = halbtc_set_rfreg; +	btcoexist->btc_get_rf_reg = halbtc_get_rfreg; + +	btcoexist->btc_fill_h2c = halbtc_fill_h2c_cmd; +	btcoexist->btc_disp_dbg_msg = halbtc_display_dbg_msg; + +	btcoexist->btc_get = halbtc_get; +	btcoexist->btc_set = halbtc_set; + +	btcoexist->cli_buf = &btc_dbg_buf[0]; + +	btcoexist->bt_info.b_bt_ctrl_buf_size = false; +	btcoexist->bt_info.agg_buf_size = 5; + +	btcoexist->bt_info.increase_scan_dev_num = false; +	return true; +} + +void exhalbtc_init_hw_config(struct btc_coexist *btcoexist) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; + +	btcoexist->statistics.cnt_init_hw_config++; + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		ex_halbtc8723b2ant_init_hwconfig(btcoexist); +} + +void exhalbtc_init_coex_dm(struct btc_coexist *btcoexist) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; + +	btcoexist->statistics.cnt_init_coex_dm++; + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		ex_halbtc8723b2ant_init_coex_dm(btcoexist); + +	btcoexist->initilized = true; +} + +void exhalbtc_ips_notify(struct btc_coexist *btcoexist, u8 type) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	u8 ips_type; + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; +	btcoexist->statistics.cnt_ips_notify++; +	if (btcoexist->manual_control) +		return; + +	if (ERFOFF == type) +		ips_type = BTC_IPS_ENTER; +	else +		ips_type = BTC_IPS_LEAVE; + +	halbtc_leave_low_power(); + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		ex_halbtc8723b2ant_ips_notify(btcoexist, ips_type); + +	halbtc_nomal_low_power(); +} + +void exhalbtc_lps_notify(struct btc_coexist *btcoexist, u8 type) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	u8 lps_type; + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; +	btcoexist->statistics.cnt_lps_notify++; +	if (btcoexist->manual_control) +		return; + +	if (EACTIVE == type) +		lps_type = BTC_LPS_DISABLE; +	else +		lps_type = BTC_LPS_ENABLE; + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		ex_halbtc8723b2ant_lps_notify(btcoexist, lps_type); +} + +void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	u8 scan_type; + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; +	btcoexist->statistics.cnt_scan_notify++; +	if (btcoexist->manual_control) +		return; + +	if (type) +		scan_type = BTC_SCAN_START; +	else +		scan_type = BTC_SCAN_FINISH; + +	halbtc_leave_low_power(); + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		ex_halbtc8723b2ant_scan_notify(btcoexist, scan_type); + +	halbtc_nomal_low_power(); +} + +void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	u8 asso_type; + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; +	btcoexist->statistics.cnt_connect_notify++; +	if (btcoexist->manual_control) +		return; + +	if (action) +		asso_type = BTC_ASSOCIATE_START; +	else +		asso_type = BTC_ASSOCIATE_FINISH; + +	halbtc_leave_low_power(); + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		ex_halbtc8723b2ant_connect_notify(btcoexist, asso_type); +} + +void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist, +				 enum _RT_MEDIA_STATUS media_status) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	u8 status; + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; +	btcoexist->statistics.cnt_media_status_notify++; +	if (btcoexist->manual_control) +		return; + +	if (RT_MEDIA_CONNECT == media_status) +		status = BTC_MEDIA_CONNECT; +	else +		status = BTC_MEDIA_DISCONNECT; + +	halbtc_leave_low_power(); + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		btc8723b_med_stat_notify(btcoexist, status); + +	halbtc_nomal_low_power(); +} + +void exhalbtc_special_packet_notify(struct btc_coexist *btcoexist, u8 pkt_type) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	u8 packet_type; + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; +	btcoexist->statistics.cnt_special_packet_notify++; +	if (btcoexist->manual_control) +		return; + +	packet_type = BTC_PACKET_DHCP; + +	halbtc_leave_low_power(); + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		ex_halbtc8723b2ant_special_packet_notify(btcoexist, +							 packet_type); + +	halbtc_nomal_low_power(); +} + +void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist, +			     u8 *tmp_buf, u8 length) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; +	btcoexist->statistics.cnt_bt_info_notify++; + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		ex_halbtc8723b2ant_bt_info_notify(btcoexist, tmp_buf, length); +} + +void exhalbtc_stack_operation_notify(struct btc_coexist *btcoexist, u8 type) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	u8 stack_op_type; + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; +	btcoexist->statistics.cnt_stack_operation_notify++; +	if (btcoexist->manual_control) +		return; + +	stack_op_type = BTC_STACK_OP_NONE; + +	halbtc_leave_low_power(); + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		ex_halbtc8723b2ant_stack_operation_notify(btcoexist, +							  stack_op_type); + +	halbtc_nomal_low_power(); +} + +void exhalbtc_halt_notify(struct btc_coexist *btcoexist) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		ex_halbtc8723b2ant_halt_notify(btcoexist); +} + +void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state) +{ +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; +} + +void exhalbtc_periodical(struct btc_coexist *btcoexist) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; +	btcoexist->statistics.cnt_periodical++; + +	halbtc_leave_low_power(); + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		ex_halbtc8723b2ant_periodical(btcoexist); + +	halbtc_nomal_low_power(); +} + +void exhalbtc_dbg_control(struct btc_coexist *btcoexist, +			  u8 code, u8 len, u8 *data) +{ +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; +	btcoexist->statistics.cnt_dbg_ctrl++; +} + +void exhalbtc_stack_update_profile_info(void) +{ +} + +void exhalbtc_update_min_bt_rssi(char bt_rssi) +{ +	struct btc_coexist *btcoexist = &gl_bt_coexist; + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; + +	btcoexist->stack_info.min_bt_rssi = bt_rssi; +} + +void exhalbtc_set_hci_version(u16 hci_version) +{ +	struct btc_coexist *btcoexist = &gl_bt_coexist; + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; + +	btcoexist->stack_info.hci_version = hci_version; +} + +void exhalbtc_set_bt_patch_version(u16 bt_hci_version, u16 bt_patch_version) +{ +	struct btc_coexist *btcoexist = &gl_bt_coexist; + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; + +	btcoexist->bt_info.bt_real_fw_ver = bt_patch_version; +	btcoexist->bt_info.bt_hci_ver = bt_hci_version; +} + +void exhalbtc_set_bt_exist(bool bt_exist) +{ +	gl_bt_coexist.board_info.bt_exist = bt_exist; +} + +void exhalbtc_set_chip_type(u8 chip_type) +{ +	switch (chip_type) { +	default: +	case BT_2WIRE: +	case BT_ISSC_3WIRE: +	case BT_ACCEL: +	case BT_RTL8756: +		gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_UNDEF; +		break; +	case BT_CSR_BC4: +		gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_CSR_BC4; +		break; +	case BT_CSR_BC8: +		gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_CSR_BC8; +		break; +	case BT_RTL8723A: +		gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_RTL8723A; +		break; +	case BT_RTL8821A: +		gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_RTL8821; +		break; +	case BT_RTL8723B: +		gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_RTL8723B; +		break; +	} +} + +void exhalbtc_set_ant_num(u8 type, u8 ant_num) +{ +	if (BT_COEX_ANT_TYPE_PG == type) { +		gl_bt_coexist.board_info.pg_ant_num = ant_num; +		gl_bt_coexist.board_info.btdm_ant_num = ant_num; +	} else if (BT_COEX_ANT_TYPE_ANTDIV == type) { +		gl_bt_coexist.board_info.btdm_ant_num = ant_num; +	} +} + +void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		ex_halbtc8723b2ant_display_coex_info(btcoexist); +} diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h new file mode 100644 index 00000000000..871fc3c6d55 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h @@ -0,0 +1,559 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2012  Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger <Larry.Finger@lwfinger.net> + * + *****************************************************************************/ +#ifndef	__HALBTC_OUT_SRC_H__ +#define __HALBTC_OUT_SRC_H__ + +#include	"../wifi.h" + +#define		NORMAL_EXEC				false +#define		FORCE_EXEC				true + +#define		BTC_RF_A				RF90_PATH_A +#define		BTC_RF_B				RF90_PATH_B +#define		BTC_RF_C				RF90_PATH_C +#define		BTC_RF_D				RF90_PATH_D + +#define		BTC_SMSP				SINGLEMAC_SINGLEPHY +#define		BTC_DMDP				DUALMAC_DUALPHY +#define		BTC_DMSP				DUALMAC_SINGLEPHY +#define		BTC_MP_UNKNOWN				0xff + +#define		IN +#define		OUT + +#define		BT_TMP_BUF_SIZE				100 + +#define		BT_COEX_ANT_TYPE_PG			0 +#define		BT_COEX_ANT_TYPE_ANTDIV			1 +#define		BT_COEX_ANT_TYPE_DETECTED		2 + +#define		BTC_MIMO_PS_STATIC			0 +#define		BTC_MIMO_PS_DYNAMIC			1 + +#define		BTC_RATE_DISABLE			0 +#define		BTC_RATE_ENABLE				1 + +#define		BTC_ANT_PATH_WIFI			0 +#define		BTC_ANT_PATH_BT				1 +#define		BTC_ANT_PATH_PTA			2 + +enum btc_chip_interface { +	BTC_INTF_UNKNOWN	= 0, +	BTC_INTF_PCI		= 1, +	BTC_INTF_USB		= 2, +	BTC_INTF_SDIO		= 3, +	BTC_INTF_GSPI		= 4, +	BTC_INTF_MAX +}; + +enum BTC_CHIP_TYPE { +	BTC_CHIP_UNDEF		= 0, +	BTC_CHIP_CSR_BC4	= 1, +	BTC_CHIP_CSR_BC8	= 2, +	BTC_CHIP_RTL8723A	= 3, +	BTC_CHIP_RTL8821	= 4, +	BTC_CHIP_RTL8723B	= 5, +	BTC_CHIP_MAX +}; + +enum BTC_MSG_TYPE { +	BTC_MSG_INTERFACE	= 0x0, +	BTC_MSG_ALGORITHM	= 0x1, +	BTC_MSG_MAX +}; +extern u32 btc_dbg_type[]; + +/* following is for BTC_MSG_INTERFACE */ +#define		INTF_INIT				BIT0 +#define		INTF_NOTIFY				BIT2 + +/* following is for BTC_ALGORITHM */ +#define		ALGO_BT_RSSI_STATE			BIT0 +#define		ALGO_WIFI_RSSI_STATE			BIT1 +#define		ALGO_BT_MONITOR				BIT2 +#define		ALGO_TRACE				BIT3 +#define		ALGO_TRACE_FW				BIT4 +#define		ALGO_TRACE_FW_DETAIL			BIT5 +#define		ALGO_TRACE_FW_EXEC			BIT6 +#define		ALGO_TRACE_SW				BIT7 +#define		ALGO_TRACE_SW_DETAIL			BIT8 +#define		ALGO_TRACE_SW_EXEC			BIT9 + +#define		BT_COEX_ANT_TYPE_PG			0 +#define		BT_COEX_ANT_TYPE_ANTDIV			1 +#define		BT_COEX_ANT_TYPE_DETECTED		2 +#define		BTC_MIMO_PS_STATIC			0 +#define		BTC_MIMO_PS_DYNAMIC			1 +#define		BTC_RATE_DISABLE			0 +#define		BTC_RATE_ENABLE				1 +#define		BTC_ANT_PATH_WIFI			0 +#define		BTC_ANT_PATH_BT				1 +#define		BTC_ANT_PATH_PTA			2 + + +#define	CL_SPRINTF	snprintf +#define	CL_PRINTF	printk + +#define	BTC_PRINT(dbgtype, dbgflag, printstr, ...)		\ +	do {							\ +		if (unlikely(btc_dbg_type[dbgtype] & dbgflag)) {\ +			printk(printstr, ##__VA_ARGS__);	\ +		}						\ +	} while (0) + +#define	BTC_PRINT_F(dbgtype, dbgflag, printstr, ...)		\ +	do {							\ +		if (unlikely(btc_dbg_type[dbgtype] & dbgflag)) {\ +			pr_info("%s: ", __func__);	\ +			printk(printstr, ##__VA_ARGS__);	\ +		}						\ +	} while (0) + +#define	BTC_PRINT_ADDR(dbgtype, dbgflag, printstr, _ptr)	\ +	do {							\ +		if (unlikely(btc_dbg_type[dbgtype] & dbgflag)) {	\ +			int __i;				\ +			u8 *__ptr = (u8 *)_ptr;			\ +			printk printstr;			\ +			for (__i = 0; __i < 6; __i++)		\ +				printk("%02X%s", __ptr[__i], (__i == 5) ? \ +				       "" : "-");		\ +			pr_info("\n");				\ +		}						\ +	} while (0) + +#define BTC_PRINT_DATA(dbgtype, dbgflag, _titlestring, _hexdata, _hexdatalen) \ +	do {								\ +		if (unlikely(btc_dbg_type[dbgtype] & dbgflag))	{	\ +			int __i;					\ +			u8 *__ptr = (u8 *)_hexdata;			\ +			printk(_titlestring);				\ +			for (__i = 0; __i < (int)_hexdatalen; __i++) {	\ +				printk("%02X%s", __ptr[__i], (((__i + 1) % 4) \ +							== 0) ? "  " : " ");\ +				if (((__i + 1) % 16) == 0)		\ +					printk("\n");			\ +			}						\ +			pr_debug("\n");					\ +		}							\ +	} while (0) + +#define BTC_ANT_PATH_WIFI	0 +#define BTC_ANT_PATH_BT		1 +#define BTC_ANT_PATH_PTA	2 + +enum btc_power_save_type { +	BTC_PS_WIFI_NATIVE = 0, +	BTC_PS_LPS_ON = 1, +	BTC_PS_LPS_OFF = 2, +	BTC_PS_LPS_MAX +}; + +struct btc_board_info { +	/* The following is some board information */ +	u8 bt_chip_type; +	u8 pg_ant_num;	/* pg ant number */ +	u8 btdm_ant_num;	/* ant number for btdm */ +	u8 btdm_ant_pos; +	bool bt_exist; +}; + +enum btc_dbg_opcode { +	BTC_DBG_SET_COEX_NORMAL = 0x0, +	BTC_DBG_SET_COEX_WIFI_ONLY = 0x1, +	BTC_DBG_SET_COEX_BT_ONLY = 0x2, +	BTC_DBG_MAX +}; + +enum btc_rssi_state { +	BTC_RSSI_STATE_HIGH = 0x0, +	BTC_RSSI_STATE_MEDIUM = 0x1, +	BTC_RSSI_STATE_LOW = 0x2, +	BTC_RSSI_STATE_STAY_HIGH = 0x3, +	BTC_RSSI_STATE_STAY_MEDIUM = 0x4, +	BTC_RSSI_STATE_STAY_LOW = 0x5, +	BTC_RSSI_MAX +}; + +enum btc_wifi_role { +	BTC_ROLE_STATION = 0x0, +	BTC_ROLE_AP = 0x1, +	BTC_ROLE_IBSS = 0x2, +	BTC_ROLE_HS_MODE = 0x3, +	BTC_ROLE_MAX +}; + +enum btc_wifi_bw_mode { +	BTC_WIFI_BW_LEGACY = 0x0, +	BTC_WIFI_BW_HT20 = 0x1, +	BTC_WIFI_BW_HT40 = 0x2, +	BTC_WIFI_BW_MAX +}; + +enum btc_wifi_traffic_dir { +	BTC_WIFI_TRAFFIC_TX = 0x0, +	BTC_WIFI_TRAFFIC_RX = 0x1, +	BTC_WIFI_TRAFFIC_MAX +}; + +enum btc_wifi_pnp { +	BTC_WIFI_PNP_WAKE_UP = 0x0, +	BTC_WIFI_PNP_SLEEP = 0x1, +	BTC_WIFI_PNP_MAX +}; + + +enum btc_get_type { +	/* type bool */ +	BTC_GET_BL_HS_OPERATION, +	BTC_GET_BL_HS_CONNECTING, +	BTC_GET_BL_WIFI_CONNECTED, +	BTC_GET_BL_WIFI_BUSY, +	BTC_GET_BL_WIFI_SCAN, +	BTC_GET_BL_WIFI_LINK, +	BTC_GET_BL_WIFI_DHCP, +	BTC_GET_BL_WIFI_SOFTAP_IDLE, +	BTC_GET_BL_WIFI_SOFTAP_LINKING, +	BTC_GET_BL_WIFI_IN_EARLY_SUSPEND, +	BTC_GET_BL_WIFI_ROAM, +	BTC_GET_BL_WIFI_4_WAY_PROGRESS, +	BTC_GET_BL_WIFI_UNDER_5G, +	BTC_GET_BL_WIFI_AP_MODE_ENABLE, +	BTC_GET_BL_WIFI_ENABLE_ENCRYPTION, +	BTC_GET_BL_WIFI_UNDER_B_MODE, +	BTC_GET_BL_EXT_SWITCH, + +	/* type s4Byte */ +	BTC_GET_S4_WIFI_RSSI, +	BTC_GET_S4_HS_RSSI, + +	/* type u32 */ +	BTC_GET_U4_WIFI_BW, +	BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, +	BTC_GET_U4_WIFI_FW_VER, +	BTC_GET_U4_BT_PATCH_VER, + +	/* type u1Byte */ +	BTC_GET_U1_WIFI_DOT11_CHNL, +	BTC_GET_U1_WIFI_CENTRAL_CHNL, +	BTC_GET_U1_WIFI_HS_CHNL, +	BTC_GET_U1_MAC_PHY_MODE, + +	/* for 1Ant */ +	BTC_GET_U1_LPS_MODE, +	BTC_GET_BL_BT_SCO_BUSY, + +	/* for test mode */ +	BTC_GET_DRIVER_TEST_CFG, +	BTC_GET_MAX +}; + + +enum btc_set_type { +	/* type bool */ +	BTC_SET_BL_BT_DISABLE, +	BTC_SET_BL_BT_TRAFFIC_BUSY, +	BTC_SET_BL_BT_LIMITED_DIG, +	BTC_SET_BL_FORCE_TO_ROAM, +	BTC_SET_BL_TO_REJ_AP_AGG_PKT, +	BTC_SET_BL_BT_CTRL_AGG_SIZE, +	BTC_SET_BL_INC_SCAN_DEV_NUM, + +	/* type u1Byte */ +	BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON, +	BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE, +	BTC_SET_UI_SCAN_SIG_COMPENSATION, +	BTC_SET_U1_AGG_BUF_SIZE, + +	/* type trigger some action */ +	BTC_SET_ACT_GET_BT_RSSI, +	BTC_SET_ACT_AGGREGATE_CTRL, + +	/********* for 1Ant **********/ +	/* type bool */ +	BTC_SET_BL_BT_SCO_BUSY, +	/* type u1Byte */ +	BTC_SET_U1_1ANT_LPS, +	BTC_SET_U1_1ANT_RPWM, +	/* type trigger some action */ +	BTC_SET_ACT_LEAVE_LPS, +	BTC_SET_ACT_ENTER_LPS, +	BTC_SET_ACT_NORMAL_LPS, +	BTC_SET_ACT_INC_FORCE_EXEC_PWR_CMD_CNT, +	BTC_SET_ACT_DISABLE_LOW_POWER, +	BTC_SET_ACT_UPDATE_ra_mask, +	BTC_SET_ACT_SEND_MIMO_PS, +	/* BT Coex related */ +	BTC_SET_ACT_CTRL_BT_INFO, +	BTC_SET_ACT_CTRL_BT_COEX, +	/***************************/ +	BTC_SET_MAX +}; + +enum btc_dbg_disp_type { +	BTC_DBG_DISP_COEX_STATISTICS = 0x0, +	BTC_DBG_DISP_BT_LINK_INFO = 0x1, +	BTC_DBG_DISP_BT_FW_VER = 0x2, +	BTC_DBG_DISP_FW_PWR_MODE_CMD = 0x3, +	BTC_DBG_DISP_MAX +}; + +enum btc_notify_type_ips { +	BTC_IPS_LEAVE = 0x0, +	BTC_IPS_ENTER = 0x1, +	BTC_IPS_MAX +}; + +enum btc_notify_type_lps { +	BTC_LPS_DISABLE = 0x0, +	BTC_LPS_ENABLE = 0x1, +	BTC_LPS_MAX +}; + +enum btc_notify_type_scan { +	BTC_SCAN_FINISH = 0x0, +	BTC_SCAN_START = 0x1, +	BTC_SCAN_MAX +}; + +enum btc_notify_type_associate { +	BTC_ASSOCIATE_FINISH = 0x0, +	BTC_ASSOCIATE_START = 0x1, +	BTC_ASSOCIATE_MAX +}; + +enum btc_notify_type_media_status { +	BTC_MEDIA_DISCONNECT = 0x0, +	BTC_MEDIA_CONNECT = 0x1, +	BTC_MEDIA_MAX +}; + +enum btc_notify_type_special_packet { +	BTC_PACKET_UNKNOWN = 0x0, +	BTC_PACKET_DHCP = 0x1, +	BTC_PACKET_ARP = 0x2, +	BTC_PACKET_EAPOL = 0x3, +	BTC_PACKET_MAX +}; + +enum btc_notify_type_stack_operation { +	BTC_STACK_OP_NONE = 0x0, +	BTC_STACK_OP_INQ_PAGE_PAIR_START = 0x1, +	BTC_STACK_OP_INQ_PAGE_PAIR_FINISH = 0x2, +	BTC_STACK_OP_MAX +}; + + +typedef u8 (*bfp_btc_r1)(void *btc_context, u32 reg_addr); + +typedef u16 (*bfp_btc_r2)(void *btc_context, u32 reg_addr); + +typedef u32 (*bfp_btc_r4)(void *btc_context, u32 reg_addr); + +typedef void (*bfp_btc_w1)(void *btc_context, u32 reg_addr, u8 data); + +typedef void (*bfp_btc_w1_bit_mak)(void *btc_context, u32 reg_addr, +				   u32 bit_mask, u8 data1b); + +typedef void (*bfp_btc_w2)(void *btc_context, u32 reg_addr, u16 data); + +typedef void (*bfp_btc_w4)(void *btc_context, u32 reg_addr, u32 data); + +typedef void (*bfp_btc_wr_1byte_bit_mask)(void *btc_context, u32 reg_addr, +					  u8 bit_mask, u8 data); + +typedef void (*bfp_btc_set_bb_reg)(void *btc_context, u32 reg_addr, +				   u32 bit_mask, u32 data); + +typedef u32 (*bfp_btc_get_bb_reg)(void *btc_context, u32 reg_addr, +				  u32 bit_mask); + +typedef void (*bfp_btc_set_rf_reg)(void *btc_context, u8 rf_path, u32 reg_addr, +				   u32 bit_mask, u32 data); + +typedef u32 (*bfp_btc_get_rf_reg)(void *btc_context, u8 rf_path, +				  u32 reg_addr, u32 bit_mask); + +typedef void (*bfp_btc_fill_h2c)(void *btc_context, u8 element_id, +				 u32 cmd_len, u8 *cmd_buffer); + +typedef	bool (*bfp_btc_get)(void *btcoexist, u8 get_type, void *out_buf); + +typedef	bool (*bfp_btc_set)(void *btcoexist, u8 set_type, void *in_buf); + +typedef void (*bfp_btc_disp_dbg_msg)(void *btcoexist, u8 disp_type); + +struct btc_bt_info { +	bool bt_disabled; +	u8 rssi_adjust_for_agc_table_on; +	u8 rssi_adjust_for_1ant_coex_type; +	bool bt_busy; +	u8 agg_buf_size; +	bool limited_dig; +	bool reject_agg_pkt; +	bool b_bt_ctrl_buf_size; +	bool increase_scan_dev_num; +	u16 bt_hci_ver; +	u16 bt_real_fw_ver; +	u8 bt_fw_ver; + +	/* the following is for 1Ant solution */ +	bool bt_ctrl_lps; +	bool bt_pwr_save_mode; +	bool bt_lps_on; +	bool force_to_roam; +	u8 force_exec_pwr_cmd_cnt; +	u8 lps_1ant; +	u8 rpwm_1ant; +	u32 ra_mask; +}; + +struct btc_stack_info { +	bool profile_notified; +	u16 hci_version;	/* stack hci version */ +	u8 num_of_link; +	bool bt_link_exist; +	bool sco_exist; +	bool acl_exist; +	bool a2dp_exist; +	bool hid_exist; +	u8 num_of_hid; +	bool pan_exist; +	bool unknown_acl_exist; +	char min_bt_rssi; +}; + +struct btc_statistics { +	u32 cnt_bind; +	u32 cnt_init_hw_config; +	u32 cnt_init_coex_dm; +	u32 cnt_ips_notify; +	u32 cnt_lps_notify; +	u32 cnt_scan_notify; +	u32 cnt_connect_notify; +	u32 cnt_media_status_notify; +	u32 cnt_special_packet_notify; +	u32 cnt_bt_info_notify; +	u32 cnt_periodical; +	u32 cnt_stack_operation_notify; +	u32 cnt_dbg_ctrl; +}; + +struct btc_bt_link_info { +	bool bt_link_exist; +	bool sco_exist; +	bool sco_only; +	bool a2dp_exist; +	bool a2dp_only; +	bool hid_exist; +	bool hid_only; +	bool pan_exist; +	bool pan_only; +}; + +enum btc_antenna_pos { +	BTC_ANTENNA_AT_MAIN_PORT = 0x1, +	BTC_ANTENNA_AT_AUX_PORT = 0x2, +}; + +struct btc_coexist { +	/* make sure only one adapter can bind the data context  */ +	bool binded; +	/* default adapter */ +	void *adapter; +	struct btc_board_info board_info; +	/* some bt info referenced by non-bt module */ +	struct btc_bt_info bt_info; +	struct btc_stack_info stack_info; +	enum btc_chip_interface	chip_interface; +	struct btc_bt_link_info bt_link_info; + +	bool initilized; +	bool stop_coex_dm; +	bool manual_control; +	u8 *cli_buf; +	struct btc_statistics statistics; +	u8 pwr_mode_val[10]; + +	/* function pointers - io related */ +	bfp_btc_r1 btc_read_1byte; +	bfp_btc_w1 btc_write_1byte; +	bfp_btc_w1_bit_mak btc_write_1byte_bitmask; +	bfp_btc_r2 btc_read_2byte; +	bfp_btc_w2 btc_write_2byte; +	bfp_btc_r4 btc_read_4byte; +	bfp_btc_w4 btc_write_4byte; + +	bfp_btc_set_bb_reg btc_set_bb_reg; +	bfp_btc_get_bb_reg btc_get_bb_reg; + + +	bfp_btc_set_rf_reg btc_set_rf_reg; +	bfp_btc_get_rf_reg btc_get_rf_reg; + +	bfp_btc_fill_h2c btc_fill_h2c; + +	bfp_btc_disp_dbg_msg btc_disp_dbg_msg; + +	bfp_btc_get btc_get; +	bfp_btc_set btc_set; +}; + +bool halbtc_is_wifi_uplink(struct rtl_priv *adapter); + +extern struct btc_coexist gl_bt_coexist; + +bool exhalbtc_initlize_variables(struct rtl_priv *adapter); +void exhalbtc_init_hw_config(struct btc_coexist *btcoexist); +void exhalbtc_init_coex_dm(struct btc_coexist *btcoexist); +void exhalbtc_ips_notify(struct btc_coexist *btcoexist, u8 type); +void exhalbtc_lps_notify(struct btc_coexist *btcoexist, u8 type); +void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type); +void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action); +void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist, +				 enum _RT_MEDIA_STATUS media_status); +void exhalbtc_special_packet_notify(struct btc_coexist *btcoexist, u8 pkt_type); +void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist, u8 *tmp_buf, +			     u8 length); +void exhalbtc_stack_operation_notify(struct btc_coexist *btcoexist, u8 type); +void exhalbtc_halt_notify(struct btc_coexist *btcoexist); +void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state); +void exhalbtc_periodical(struct btc_coexist *btcoexist); +void exhalbtc_dbg_control(struct btc_coexist *btcoexist, u8 code, u8 len, +			  u8 *data); +void exhalbtc_stack_update_profile_info(void); +void exhalbtc_set_hci_version(u16 hci_version); +void exhalbtc_set_bt_patch_version(u16 bt_hci_version, u16 bt_patch_version); +void exhalbtc_update_min_bt_rssi(char bt_rssi); +void exhalbtc_set_bt_exist(bool bt_exist); +void exhalbtc_set_chip_type(u8 chip_type); +void exhalbtc_set_ant_num(u8 type, u8 ant_num); +void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist); +void exhalbtc_signal_compensation(struct btc_coexist *btcoexist, +				  u8 *rssi_wifi, u8 *rssi_bt); +void exhalbtc_lps_leave(struct btc_coexist *btcoexist); +void exhalbtc_low_wifi_traffic_notify(struct btc_coexist *btcoexist); + +#endif diff --git a/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.c b/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.c new file mode 100644 index 00000000000..0ab94fe4cbb --- /dev/null +++ b/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.c @@ -0,0 +1,218 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2013  Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger <Larry.Finger@lwfinger.net> + * + *****************************************************************************/ + +#include "../wifi.h" +#include "rtl_btc.h" +#include "halbt_precomp.h" + +#include <linux/vmalloc.h> +#include <linux/module.h> + +static struct rtl_btc_ops rtl_btc_operation = { +	.btc_init_variables = rtl_btc_init_variables, +	.btc_init_hal_vars = rtl_btc_init_hal_vars, +	.btc_init_hw_config = rtl_btc_init_hw_config, +	.btc_ips_notify = rtl_btc_ips_notify, +	.btc_scan_notify = rtl_btc_scan_notify, +	.btc_connect_notify = rtl_btc_connect_notify, +	.btc_mediastatus_notify = rtl_btc_mediastatus_notify, +	.btc_periodical = rtl_btc_periodical, +	.btc_halt_notify = rtl_btc_halt_notify, +	.btc_btinfo_notify = rtl_btc_btinfo_notify, +	.btc_is_limited_dig = rtl_btc_is_limited_dig, +	.btc_is_disable_edca_turbo = rtl_btc_is_disable_edca_turbo, +	.btc_is_bt_disabled = rtl_btc_is_bt_disabled, +}; + +void rtl_btc_init_variables(struct rtl_priv *rtlpriv) +{ +	exhalbtc_initlize_variables(rtlpriv); +} + +void rtl_btc_init_hal_vars(struct rtl_priv *rtlpriv) +{ +	u8 ant_num; +	u8 bt_exist; +	u8 bt_type; + +	ant_num = rtl_get_hwpg_ant_num(rtlpriv); +	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, +		 "%s, antNum is %d\n", __func__, ant_num); + +	bt_exist = rtl_get_hwpg_bt_exist(rtlpriv); +	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, +		 "%s, bt_exist is %d\n", __func__, bt_exist); +	exhalbtc_set_bt_exist(bt_exist); + +	bt_type = rtl_get_hwpg_bt_type(rtlpriv); +	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%s, bt_type is %d\n", +		 __func__, bt_type); +	exhalbtc_set_chip_type(bt_type); + +	exhalbtc_set_ant_num(BT_COEX_ANT_TYPE_PG, ant_num); +} + +void rtl_btc_init_hw_config(struct rtl_priv *rtlpriv) +{ +	exhalbtc_init_hw_config(&gl_bt_coexist); +	exhalbtc_init_coex_dm(&gl_bt_coexist); +} + +void rtl_btc_ips_notify(struct rtl_priv *rtlpriv, u8 type) +{ +	exhalbtc_ips_notify(&gl_bt_coexist, type); +} + +void rtl_btc_scan_notify(struct rtl_priv *rtlpriv, u8 scantype) +{ +	exhalbtc_scan_notify(&gl_bt_coexist, scantype); +} + +void rtl_btc_connect_notify(struct rtl_priv *rtlpriv, u8 action) +{ +	exhalbtc_connect_notify(&gl_bt_coexist, action); +} + +void rtl_btc_mediastatus_notify(struct rtl_priv *rtlpriv, +				enum _RT_MEDIA_STATUS mstatus) +{ +	exhalbtc_mediastatus_notify(&gl_bt_coexist, mstatus); +} + +void rtl_btc_periodical(struct rtl_priv *rtlpriv) +{ +	exhalbtc_periodical(&gl_bt_coexist); +} + +void rtl_btc_halt_notify(void) +{ +	exhalbtc_halt_notify(&gl_bt_coexist); +} + +void rtl_btc_btinfo_notify(struct rtl_priv *rtlpriv, u8 *tmp_buf, u8 length) +{ +	exhalbtc_bt_info_notify(&gl_bt_coexist, tmp_buf, length); +} + +bool rtl_btc_is_limited_dig(struct rtl_priv *rtlpriv) +{ +	return gl_bt_coexist.bt_info.limited_dig; +} + +bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv) +{ +	bool bt_change_edca = false; +	u32 cur_edca_val; +	u32 edca_bt_hs_uplink = 0x5ea42b, edca_bt_hs_downlink = 0x5ea42b; +	u32 edca_hs; +	u32 edca_addr = 0x504; + +	cur_edca_val = rtl_read_dword(rtlpriv, edca_addr); +	if (halbtc_is_wifi_uplink(rtlpriv)) { +		if (cur_edca_val != edca_bt_hs_uplink) { +			edca_hs = edca_bt_hs_uplink; +			bt_change_edca = true; +		} +	} else { +		if (cur_edca_val != edca_bt_hs_downlink) { +			edca_hs = edca_bt_hs_downlink; +			bt_change_edca = true; +		} +	} + +	if (bt_change_edca) +		rtl_write_dword(rtlpriv, edca_addr, edca_hs); + +	return true; +} + +bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv) +{ +	if (gl_bt_coexist.bt_info.bt_disabled) +		return true; +	else +		return false; +} + +struct rtl_btc_ops *rtl_btc_get_ops_pointer(void) +{ +	return &rtl_btc_operation; +} +EXPORT_SYMBOL(rtl_btc_get_ops_pointer); + +u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv) +{ +	u8 num; + +	if (rtlpriv->btcoexist.btc_info.ant_num == ANT_X2) +		num = 2; +	else +		num = 1; + +	return num; +} + +enum _RT_MEDIA_STATUS mgnt_link_status_query(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	enum _RT_MEDIA_STATUS    m_status = RT_MEDIA_DISCONNECT; + +	u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0; + +	if (bibss || rtlpriv->mac80211.link_state >= MAC80211_LINKED) +		m_status = RT_MEDIA_CONNECT; + +	return m_status; +} + +u8 rtl_get_hwpg_bt_exist(struct rtl_priv *rtlpriv) +{ +	return rtlpriv->btcoexist.btc_info.btcoexist; +} + +u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv) +{ +	return rtlpriv->btcoexist.btc_info.bt_type; +} + +MODULE_AUTHOR("Page He	<page_he@realsil.com.cn>"); +MODULE_AUTHOR("Realtek WlanFAE	<wlanfae@realtek.com>"); +MODULE_AUTHOR("Larry Finger	<Larry.FInger@lwfinger.net>"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core"); + +static int __init rtl_btcoexist_module_init(void) +{ +	return 0; +} + +static void __exit rtl_btcoexist_module_exit(void) +{ +	return; +} + +module_init(rtl_btcoexist_module_init); +module_exit(rtl_btcoexist_module_exit); diff --git a/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.h b/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.h new file mode 100644 index 00000000000..805b22cc8fc --- /dev/null +++ b/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.h @@ -0,0 +1,52 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010  Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * Larry Finger <Larry.Finger@lwfinger.net> + * + *****************************************************************************/ + +#ifndef __RTL_BTC_H__ +#define __RTL_BTC_H__ + +#include "halbt_precomp.h" + +void rtl_btc_init_variables(struct rtl_priv *rtlpriv); +void rtl_btc_init_hal_vars(struct rtl_priv *rtlpriv); +void rtl_btc_init_hw_config(struct rtl_priv *rtlpriv); +void rtl_btc_ips_notify(struct rtl_priv *rtlpriv, u8 type); +void rtl_btc_scan_notify(struct rtl_priv *rtlpriv, u8 scantype); +void rtl_btc_connect_notify(struct rtl_priv *rtlpriv, u8 action); +void rtl_btc_mediastatus_notify(struct rtl_priv *rtlpriv, +				enum _RT_MEDIA_STATUS mstatus); +void rtl_btc_periodical(struct rtl_priv *rtlpriv); +void rtl_btc_halt_notify(void); +void rtl_btc_btinfo_notify(struct rtl_priv *rtlpriv, u8 *tmpbuf, u8 length); +bool rtl_btc_is_limited_dig(struct rtl_priv *rtlpriv); +bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv); +bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv); + +struct rtl_btc_ops *rtl_btc_get_ops_pointer(void); + +u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv); +u8 rtl_get_hwpg_bt_exist(struct rtl_priv *rtlpriv); +u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv); +enum _RT_MEDIA_STATUS mgnt_link_status_query(struct ieee80211_hw *hw); + +#endif  | 
