Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b2283dad authored by Ping-Ke Shih's avatar Ping-Ke Shih Committed by Kalle Valo
Browse files

rtlwifi: btcoex: Add common function for qeurying BT information



This commit implement the common function to sort old features, and add
more new features that are get_supported_feature, get_supported_version,
get_ant_det_val, ble_scan_type, ble_scan_para, bt_dev_info,
forbidden_slot_val, afh_map and etc.

Signed-off-by: default avatarPing-Ke Shih <pkshih@realtek.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 3afb7da4
Loading
Loading
Loading
Loading
+277 −32
Original line number Diff line number Diff line
@@ -207,6 +207,102 @@ u8 rtl_get_hwpg_package_type(struct rtl_priv *rtlpriv)
	return rtlhal->package_type;
}

static
bool halbtc_is_hw_mailbox_exist(struct btc_coexist *btcoexist)
{
	if (IS_HARDWARE_TYPE_8812(btcoexist->adapter))
		return false;
	else
		return true;
}

static
bool halbtc_send_bt_mp_operation(struct btc_coexist *btcoexist, u8 op_code,
				 u8 *cmd, u32 len, unsigned long wait_ms)
{
	struct rtl_priv *rtlpriv;
	const u8 oper_ver = 0;
	u8 req_num;

	if (!halbtc_is_hw_mailbox_exist(btcoexist))
		return false;

	if (wait_ms)	/* before h2c to avoid race condition */
		reinit_completion(&btcoexist->bt_mp_comp);

	rtlpriv = btcoexist->adapter;

	/* fill req_num by op_code, and rtl_btc_btmpinfo_notify() use it
	 * to know message type
	 */
	switch (op_code) {
	case BT_OP_GET_BT_VERSION:
		req_num = BT_SEQ_GET_BT_VERSION;
		break;
	case BT_OP_GET_AFH_MAP_L:
		req_num = BT_SEQ_GET_AFH_MAP_L;
		break;
	case BT_OP_GET_AFH_MAP_M:
		req_num = BT_SEQ_GET_AFH_MAP_M;
		break;
	case BT_OP_GET_AFH_MAP_H:
		req_num = BT_SEQ_GET_AFH_MAP_H;
		break;
	case BT_OP_GET_BT_COEX_SUPPORTED_FEATURE:
		req_num = BT_SEQ_GET_BT_COEX_SUPPORTED_FEATURE;
		break;
	case BT_OP_GET_BT_COEX_SUPPORTED_VERSION:
		req_num = BT_SEQ_GET_BT_COEX_SUPPORTED_VERSION;
		break;
	case BT_OP_GET_BT_ANT_DET_VAL:
		req_num = BT_SEQ_GET_BT_ANT_DET_VAL;
		break;
	case BT_OP_GET_BT_BLE_SCAN_PARA:
		req_num = BT_SEQ_GET_BT_BLE_SCAN_PARA;
		break;
	case BT_OP_GET_BT_BLE_SCAN_TYPE:
		req_num = BT_SEQ_GET_BT_BLE_SCAN_TYPE;
		break;
	case BT_OP_GET_BT_DEVICE_INFO:
		req_num = BT_SEQ_GET_BT_DEVICE_INFO;
		break;
	case BT_OP_GET_BT_FORBIDDEN_SLOT_VAL:
		req_num = BT_SEQ_GET_BT_FORB_SLOT_VAL;
		break;
	case BT_OP_WRITE_REG_ADDR:
	case BT_OP_WRITE_REG_VALUE:
	case BT_OP_READ_REG:
	default:
		req_num = BT_SEQ_DONT_CARE;
		break;
	}

	cmd[0] |= (oper_ver & 0x0f);		/* Set OperVer */
	cmd[0] |= ((req_num << 4) & 0xf0);	/* Set ReqNum */
	cmd[1] = op_code;
	rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->mac80211.hw, 0x67, len, cmd);

	/* wait? */
	if (!wait_ms)
		return true;

	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "btmpinfo wait req_num=%d wait=%ld\n", req_num, wait_ms);

	if (in_interrupt())
		return false;

	if (wait_for_completion_timeout(&btcoexist->bt_mp_comp,
					msecs_to_jiffies(wait_ms)) == 0) {
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
			 "btmpinfo wait (req_num=%d) timeout\n", req_num);

		return false;	/* timeout */
	}

	return true;
}

static void halbtc_leave_lps(struct btc_coexist *btcoexist)
{
	struct rtl_priv *rtlpriv;
@@ -334,24 +430,79 @@ static void halbtc_aggregation_check(struct btc_coexist *btcoexist)

static u32 halbtc_get_bt_patch_version(struct btc_coexist *btcoexist)
{
	struct rtl_priv *rtlpriv = btcoexist->adapter;
	u8 cmd_buffer[4] = {0};
	u8 oper_ver = 0;
	u8 req_num = 0x0E;

	if (btcoexist->bt_info.bt_real_fw_ver)
		goto label_done;

	cmd_buffer[0] |= (oper_ver & 0x0f);	/* Set OperVer */
	cmd_buffer[0] |= ((req_num << 4) & 0xf0);	/* Set ReqNum */
	cmd_buffer[1] = 0; /* BT_OP_GET_BT_VERSION = 0 */
	rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->mac80211.hw, 0x67, 4,
					&cmd_buffer[0]);
	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
	halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_BT_VERSION,
				    cmd_buffer, 4, 200);

label_done:
	return btcoexist->bt_info.bt_real_fw_ver;
}

static u32 halbtc_get_bt_coex_supported_feature(void *btc_context)
{
	struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
	u8 cmd_buffer[4] = {0};

	if (btcoexist->bt_info.bt_supported_feature)
		goto label_done;

	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
	halbtc_send_bt_mp_operation(btcoexist,
				    BT_OP_GET_BT_COEX_SUPPORTED_FEATURE,
				    cmd_buffer, 4, 200);

label_done:
	return btcoexist->bt_info.bt_supported_feature;
}

static u32 halbtc_get_bt_coex_supported_version(void *btc_context)
{
	struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
	u8 cmd_buffer[4] = {0};

	if (btcoexist->bt_info.bt_supported_version)
		goto label_done;

	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
	halbtc_send_bt_mp_operation(btcoexist,
				    BT_OP_GET_BT_COEX_SUPPORTED_VERSION,
				    cmd_buffer, 4, 200);

label_done:
	return btcoexist->bt_info.bt_supported_version;
}

static u32 halbtc_get_bt_device_info(void *btc_context)
{
	struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
	u8 cmd_buffer[4] = {0};

	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
	halbtc_send_bt_mp_operation(btcoexist,
				    BT_OP_GET_BT_DEVICE_INFO,
				    cmd_buffer, 4, 200);

	return btcoexist->bt_info.bt_device_info;
}

static u32 halbtc_get_bt_forbidden_slot_val(void *btc_context)
{
	struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
	u8 cmd_buffer[4] = {0};

	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
	halbtc_send_bt_mp_operation(btcoexist,
				    BT_OP_GET_BT_FORBIDDEN_SLOT_VAL,
				    cmd_buffer, 4, 200);

	return btcoexist->bt_info.bt_forb_slot_val;
}

u32 halbtc_get_wifi_link_status(struct btc_coexist *btcoexist)
{
	/* return value:
@@ -513,6 +664,18 @@ static bool halbtc_get(void *void_btcoexist, u8 get_type, void *out_buf)
	case BTC_GET_U4_VENDOR:
		*u32_tmp = BTC_VENDOR_OTHER;
		break;
	case BTC_GET_U4_SUPPORTED_VERSION:
		*u32_tmp = halbtc_get_bt_coex_supported_version(btcoexist);
		break;
	case BTC_GET_U4_SUPPORTED_FEATURE:
		*u32_tmp = halbtc_get_bt_coex_supported_feature(btcoexist);
		break;
	case BTC_GET_U4_BT_DEVICE_INFO:
		*u32_tmp = halbtc_get_bt_device_info(btcoexist);
		break;
	case BTC_GET_U4_BT_FORBIDDEN_SLOT_VAL:
		*u32_tmp = halbtc_get_bt_forbidden_slot_val(btcoexist);
		break;
	case BTC_GET_U1_WIFI_DOT11_CHNL:
		*u8_tmp = rtlphy->current_channel;
		break;
@@ -893,32 +1056,20 @@ static void halbtc_fill_h2c_cmd(void *bt_context, u8 element_id,
void halbtc_set_bt_reg(void *btc_context, u8 reg_type, u32 offset, u32 set_val)
{
	struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
	struct rtl_priv *rtlpriv = btcoexist->adapter;
	u8 cmd_buffer1[4] = {0};
	u8 cmd_buffer2[4] = {0};
	u8 *addr_to_set = (u8 *)&offset;
	u8 *value_to_set = (u8 *)&set_val;
	u8 oper_ver = 0;
	u8 req_num = 0;

	if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
		cmd_buffer1[0] |= (oper_ver & 0x0f);	/* Set OperVer */
		cmd_buffer1[0] |= ((req_num << 4) & 0xf0);	/* Set ReqNum */
		cmd_buffer1[1] = 0x0d;	/* OpCode: BT_LO_OP_WRITE_REG_VALUE */
		cmd_buffer1[2] = value_to_set[0];	/* Set WriteRegValue */
		rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->mac80211.hw, 0x67, 4,
						&cmd_buffer1[0]);

		msleep(200);
		req_num++;
	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
	*((__le16 *)&cmd_buffer1[2]) = cpu_to_le16((u16)set_val);
	if (!halbtc_send_bt_mp_operation(btcoexist, BT_OP_WRITE_REG_VALUE,
					 cmd_buffer1, 4, 200))
		return;

		cmd_buffer2[0] |= (oper_ver & 0x0f);	/* Set OperVer */
		cmd_buffer2[0] |= ((req_num << 4) & 0xf0);	/* Set ReqNum */
		cmd_buffer2[1] = 0x0c;	/* OpCode: BT_LO_OP_WRITE_REG_ADDR */
		cmd_buffer2[3] = addr_to_set[0];	/* Set WriteRegAddr */
		rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->mac80211.hw, 0x67, 4,
						&cmd_buffer2[0]);
	}
	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
	cmd_buffer2[2] = reg_type;
	*((u8 *)&cmd_buffer2[3]) = (u8)offset;
	halbtc_send_bt_mp_operation(btcoexist, BT_OP_WRITE_REG_ADDR,
				    cmd_buffer2, 4, 200);
}

static void halbtc_display_dbg_msg(void *bt_context, u8 disp_type,
@@ -959,6 +1110,86 @@ bool halbtc_under_ips(struct btc_coexist *btcoexist)
	return false;
}

static u8 halbtc_get_ant_det_val_from_bt(void *btc_context)
{
	struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
	u8 cmd_buffer[4] = {0};

	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
	halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_BT_ANT_DET_VAL,
				    cmd_buffer, 4, 200);

	/* need wait completion to return correct value */

	return btcoexist->bt_info.bt_ant_det_val;
}

static u8 halbtc_get_ble_scan_type_from_bt(void *btc_context)
{
	struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
	u8 cmd_buffer[4] = {0};

	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
	halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_BT_BLE_SCAN_TYPE,
				    cmd_buffer, 4, 200);

	/* need wait completion to return correct value */

	return btcoexist->bt_info.bt_ble_scan_type;
}

static u32 halbtc_get_ble_scan_para_from_bt(void *btc_context, u8 scan_type)
{
	struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
	u8 cmd_buffer[4] = {0};

	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
	halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_BT_BLE_SCAN_PARA,
				    cmd_buffer, 4, 200);

	/* need wait completion to return correct value */

	return btcoexist->bt_info.bt_ble_scan_para;
}

static bool halbtc_get_bt_afh_map_from_bt(void *btc_context, u8 map_type,
					  u8 *afh_map)
{
	struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
	u8 cmd_buffer[2] = {0};
	bool ret;
	u32 *afh_map_l = (u32 *)afh_map;
	u32 *afh_map_m = (u32 *)(afh_map + 4);
	u16 *afh_map_h = (u16 *)(afh_map + 8);

	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
	ret = halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_AFH_MAP_L,
					  cmd_buffer, 2, 200);
	if (!ret)
		goto exit;

	*afh_map_l = btcoexist->bt_info.afh_map_l;

	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
	ret = halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_AFH_MAP_M,
					  cmd_buffer, 2, 200);
	if (!ret)
		goto exit;

	*afh_map_m = btcoexist->bt_info.afh_map_m;

	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
	ret = halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_AFH_MAP_H,
					  cmd_buffer, 2, 200);
	if (!ret)
		goto exit;

	*afh_map_h = btcoexist->bt_info.afh_map_h;

exit:
	return ret;
}

/*****************************************************************
 *         Extern functions called by other module
 *****************************************************************/
@@ -993,11 +1224,25 @@ bool exhalbtc_initlize_variables(struct rtl_priv *rtlpriv)
	btcoexist->btc_set = halbtc_set;
	btcoexist->btc_set_bt_reg = halbtc_set_bt_reg;


	btcoexist->bt_info.bt_ctrl_buf_size = false;
	btcoexist->bt_info.agg_buf_size = 5;

	btcoexist->bt_info.increase_scan_dev_num = false;

	btcoexist->btc_get_bt_coex_supported_feature =
					halbtc_get_bt_coex_supported_feature;
	btcoexist->btc_get_bt_coex_supported_version =
					halbtc_get_bt_coex_supported_version;
	btcoexist->btc_get_ant_det_val_from_bt = halbtc_get_ant_det_val_from_bt;
	btcoexist->btc_get_ble_scan_type_from_bt =
					halbtc_get_ble_scan_type_from_bt;
	btcoexist->btc_get_ble_scan_para_from_bt =
					halbtc_get_ble_scan_para_from_bt;
	btcoexist->btc_get_bt_afh_map_from_bt =
					halbtc_get_bt_afh_map_from_bt;

	init_completion(&btcoexist->bt_mp_comp);

	return true;
}

+56 −0
Original line number Diff line number Diff line
@@ -278,6 +278,8 @@ enum btc_get_type {
	BTC_GET_U4_VENDOR,
	BTC_GET_U4_SUPPORTED_VERSION,
	BTC_GET_U4_SUPPORTED_FEATURE,
	BTC_GET_U4_BT_DEVICE_INFO,
	BTC_GET_U4_BT_FORBIDDEN_SLOT_VAL,
	BTC_GET_U4_WIFI_IQK_TOTAL,
	BTC_GET_U4_WIFI_IQK_OK,
	BTC_GET_U4_WIFI_IQK_FAIL,
@@ -452,6 +454,17 @@ struct btc_bt_info {
	u8 lps_val;
	u8 rpwm_val;
	u32 ra_mask;

	u32 afh_map_l;
	u32 afh_map_m;
	u16 afh_map_h;
	u32 bt_supported_feature;
	u32 bt_supported_version;
	u32 bt_device_info;
	u32 bt_forb_slot_val;
	u8 bt_ant_det_val;
	u8 bt_ble_scan_type;
	u32 bt_ble_scan_para;
};

struct btc_stack_info {
@@ -507,6 +520,40 @@ enum btc_antenna_pos {
	BTC_ANTENNA_AT_AUX_PORT = 0x2,
};

enum btc_mp_h2c_op_code {
	BT_OP_GET_BT_VERSION			= 0,
	BT_OP_WRITE_REG_ADDR			= 12,
	BT_OP_WRITE_REG_VALUE			= 13,
	BT_OP_READ_REG				= 17,
	BT_OP_GET_AFH_MAP_L			= 30,
	BT_OP_GET_AFH_MAP_M			= 31,
	BT_OP_GET_AFH_MAP_H			= 32,
	BT_OP_GET_BT_COEX_SUPPORTED_FEATURE	= 42,
	BT_OP_GET_BT_COEX_SUPPORTED_VERSION	= 43,
	BT_OP_GET_BT_ANT_DET_VAL		= 44,
	BT_OP_GET_BT_BLE_SCAN_PARA		= 45,
	BT_OP_GET_BT_BLE_SCAN_TYPE		= 46,
	BT_OP_GET_BT_DEVICE_INFO		= 48,
	BT_OP_GET_BT_FORBIDDEN_SLOT_VAL		= 49,
	BT_OP_MAX
};

enum btc_mp_h2c_req_num {
	/* 4 bits only */
	BT_SEQ_DONT_CARE			= 0,
	BT_SEQ_GET_BT_VERSION			= 0xE,
	BT_SEQ_GET_AFH_MAP_L			= 0x5,
	BT_SEQ_GET_AFH_MAP_M			= 0x6,
	BT_SEQ_GET_AFH_MAP_H			= 0x9,
	BT_SEQ_GET_BT_COEX_SUPPORTED_FEATURE	= 0x7,
	BT_SEQ_GET_BT_COEX_SUPPORTED_VERSION	= 0x8,
	BT_SEQ_GET_BT_ANT_DET_VAL		= 0x2,
	BT_SEQ_GET_BT_BLE_SCAN_PARA		= 0x3,
	BT_SEQ_GET_BT_BLE_SCAN_TYPE		= 0x4,
	BT_SEQ_GET_BT_DEVICE_INFO		= 0xA,
	BT_SEQ_GET_BT_FORB_SLOT_VAL		= 0xB,
};

struct btc_coexist {
	/* make sure only one adapter can bind the data context  */
	bool binded;
@@ -530,6 +577,8 @@ struct btc_coexist {
	struct btc_statistics statistics;
	u8 pwr_mode_val[10];

	struct completion bt_mp_comp;

	/* function pointers - io related */
	u8 (*btc_read_1byte)(void *btc_context, u32 reg_addr);
	void (*btc_write_1byte)(void *btc_context, u32 reg_addr, u32 data);
@@ -562,6 +611,13 @@ struct btc_coexist {

	void (*btc_set_bt_reg)(void *btc_context, u8 reg_type, u32 offset,
			       u32 value);
	u32 (*btc_get_bt_coex_supported_feature)(void *btcoexist);
	u32 (*btc_get_bt_coex_supported_version)(void *btcoexist);
	u8 (*btc_get_ant_det_val_from_bt)(void *btcoexist);
	u8 (*btc_get_ble_scan_type_from_bt)(void *btcoexist);
	u32 (*btc_get_ble_scan_para_from_bt)(void *btcoexist, u8 scan_type);
	bool (*btc_get_bt_afh_map_from_bt)(void *btcoexist, u8 map_type,
					   u8 *afh_map);
};

bool halbtc_is_wifi_uplink(struct rtl_priv *adapter);
+47 −1
Original line number Diff line number Diff line
@@ -291,6 +291,7 @@ void rtl_btc_btmpinfo_notify(struct rtl_priv *rtlpriv, u8 *tmp_buf, u8 length)
	u8 extid, seq, len;
	u16 bt_real_fw_ver;
	u8 bt_fw_ver;
	u8 *data;

	if (!btcoexist)
		return;
@@ -305,15 +306,60 @@ void rtl_btc_btmpinfo_notify(struct rtl_priv *rtlpriv, u8 *tmp_buf, u8 length)

	len = tmp_buf[1] >> 4;
	seq = tmp_buf[2] >> 4;
	data = &tmp_buf[3];

	/* BT Firmware version response */
	if (seq == 0x0E) {
	switch (seq) {
	case BT_SEQ_GET_BT_VERSION:
		bt_real_fw_ver = tmp_buf[3] | (tmp_buf[4] << 8);
		bt_fw_ver = tmp_buf[5];

		btcoexist->bt_info.bt_real_fw_ver = bt_real_fw_ver;
		btcoexist->bt_info.bt_fw_ver = bt_fw_ver;
	}
		break;
	case BT_SEQ_GET_AFH_MAP_L:
		btcoexist->bt_info.afh_map_l = le32_to_cpu(*(__le32 *)data);
		break;
	case BT_SEQ_GET_AFH_MAP_M:
		btcoexist->bt_info.afh_map_m = le32_to_cpu(*(__le32 *)data);
		break;
	case BT_SEQ_GET_AFH_MAP_H:
		btcoexist->bt_info.afh_map_h = le16_to_cpu(*(__le16 *)data);
		break;
	case BT_SEQ_GET_BT_COEX_SUPPORTED_FEATURE:
		btcoexist->bt_info.bt_supported_feature = tmp_buf[3] |
							  (tmp_buf[4] << 8);
		break;
	case BT_SEQ_GET_BT_COEX_SUPPORTED_VERSION:
		btcoexist->bt_info.bt_supported_version = tmp_buf[3] |
							  (tmp_buf[4] << 8);
		break;
	case BT_SEQ_GET_BT_ANT_DET_VAL:
		btcoexist->bt_info.bt_ant_det_val = tmp_buf[3];
		break;
	case BT_SEQ_GET_BT_BLE_SCAN_PARA:
		btcoexist->bt_info.bt_ble_scan_para = tmp_buf[3] |
						      (tmp_buf[4] << 8) |
						      (tmp_buf[5] << 16) |
						      (tmp_buf[6] << 24);
		break;
	case BT_SEQ_GET_BT_BLE_SCAN_TYPE:
		btcoexist->bt_info.bt_ble_scan_type = tmp_buf[3];
		break;
	case BT_SEQ_GET_BT_DEVICE_INFO:
		btcoexist->bt_info.bt_device_info =
						le32_to_cpu(*(__le32 *)data);
		break;
	case BT_OP_GET_BT_FORBIDDEN_SLOT_VAL:
		btcoexist->bt_info.bt_forb_slot_val =
						le32_to_cpu(*(__le32 *)data);
		break;
	}

	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "btmpinfo complete req_num=%d\n", seq);

	complete(&btcoexist->bt_mp_comp);
}

bool rtl_btc_is_limited_dig(struct rtl_priv *rtlpriv)