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

Commit 4136214f authored by Yan-Hsuan Chuang's avatar Yan-Hsuan Chuang Committed by Kalle Valo
Browse files

rtw88: add BT co-existence support



Both RTL8822BE/RTL8822CE are WiFi + BT combo chips. Since
WiFi and BT use 2.4GHz to transmit, it is important to
make sure they run concurrently without interfering each
other. To achieve this, WiFi driver requires a mechanism
to collaborate with BT, whether they share the antenna(s)
or not.

The final decision made by the co-existence mechanism is
to choose a proper strategy, or called "tdma/table", and
inform either firmware or hardware of the strategy.
To choose a strategy, co-existence mechanism needs to
have enough information from WiFi and BT.

BT information is provided through firmware C2H.
The contents describe the current status of BT, such as
if BT is connected or is idle, or the profile that is
being used.

WiFi information can be provided by WiFi itself. The WiFi
driver will call various of "notify" functions each time
the state of WiFi changed, such as WiFi is going to switch
channel or is connected. Also WiFi driver can know if it
shares antenna with BT by reading efuse content. Antenna
configuration of the module will finally get a different
strategy.

Upon receiving any information from WiFi or BT, the WiFi
driver will run the co-existence mechanism immediately.
It will set the RF antenna configuration according to the
strategy through the TDMA H2C to firmware and a hardware
table. Based on the tdma/table, WiFi + BT should work with
each other, and having a better user experience.

Signed-off-by: default avatarYan-Hsuan Chuang <yhchuang@realtek.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 713a30de
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ rtw88-y += main.o \
	   rx.o \
	   mac.o \
	   phy.o \
	   coex.o \
	   efuse.o \
	   fw.o \
	   ps.o \
+2507 −0

File added.

Preview size limit exceeded, changes collapsed.

+369 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2018-2019  Realtek Corporation
 */

#ifndef __RTW_COEX_H__
#define __RTW_COEX_H__

/* BT profile map bit definition */
#define BPM_HFP		BIT(0)
#define BPM_HID		BIT(1)
#define BPM_A2DP		BIT(2)
#define BPM_PAN		BIT(3)

#define COEX_RESP_ACK_BY_WL_FW	0x1
#define COEX_REQUEST_TIMEOUT	msecs_to_jiffies(10)

#define COEX_MIN_DELAY		10 /* delay unit in ms */
#define COEX_RFK_TIMEOUT	600 /* RFK timeout in ms */

#define COEX_RF_OFF	0x0
#define COEX_RF_ON	0x1

#define COEX_H2C69_WL_LEAKAP	0xc
#define PARA1_H2C69_DIS_5MS	0x1
#define PARA1_H2C69_EN_5MS	0x0

#define COEX_H2C69_TDMA_SLOT	0xb
#define PARA1_H2C69_TDMA_4SLOT	0xc1
#define PARA1_H2C69_TDMA_2SLOT	0x1

#define TDMA_4SLOT	BIT(8)

#define COEX_RSSI_STEP		4
#define COEX_RSSI_HIGH(rssi) \
	({ typeof(rssi) __rssi__ = rssi; \
	   (__rssi__ == COEX_RSSI_STATE_HIGH || \
	    __rssi__ == COEX_RSSI_STATE_STAY_HIGH ? true : false); })

#define COEX_RSSI_MEDIUM(rssi) \
	({ typeof(rssi) __rssi__ = rssi; \
	   (__rssi__ == COEX_RSSI_STATE_MEDIUM || \
	    __rssi__ == COEX_RSSI_STATE_STAY_MEDIUM ? true : false); })

#define COEX_RSSI_LOW(rssi) \
	({ typeof(rssi) __rssi__ = rssi; \
	   (__rssi__ == COEX_RSSI_STATE_LOW || \
	    __rssi__ == COEX_RSSI_STATE_STAY_LOW ? true : false); })

#define GET_COEX_RESP_BT_SCAN_TYPE(payload)				\
	le64_get_bits(*((__le64 *)(payload)), GENMASK(31, 24))

enum coex_mp_info_op {
	BT_MP_INFO_OP_PATCH_VER	= 0x00,
	BT_MP_INFO_OP_READ_REG	= 0x11,
	BT_MP_INFO_OP_SUPP_FEAT	= 0x2a,
	BT_MP_INFO_OP_SUPP_VER	= 0x2b,
	BT_MP_INFO_OP_SCAN_TYPE	= 0x2d,
	BT_MP_INFO_OP_LNA_CONSTRAINT	= 0x32,
};

enum coex_set_ant_phase {
	COEX_SET_ANT_INIT,
	COEX_SET_ANT_WONLY,
	COEX_SET_ANT_WOFF,
	COEX_SET_ANT_2G,
	COEX_SET_ANT_5G,
	COEX_SET_ANT_POWERON,
	COEX_SET_ANT_2G_WLBT,
	COEX_SET_ANT_2G_FREERUN,

	COEX_SET_ANT_MAX
};

enum coex_runreason {
	COEX_RSN_2GSCANSTART	= 0,
	COEX_RSN_5GSCANSTART	= 1,
	COEX_RSN_SCANFINISH	= 2,
	COEX_RSN_2GSWITCHBAND	= 3,
	COEX_RSN_5GSWITCHBAND	= 4,
	COEX_RSN_2GCONSTART	= 5,
	COEX_RSN_5GCONSTART	= 6,
	COEX_RSN_2GCONFINISH	= 7,
	COEX_RSN_5GCONFINISH	= 8,
	COEX_RSN_2GMEDIA	= 9,
	COEX_RSN_5GMEDIA	= 10,
	COEX_RSN_MEDIADISCON	= 11,
	COEX_RSN_BTINFO		= 12,
	COEX_RSN_LPS		= 13,
	COEX_RSN_WLSTATUS	= 14,

	COEX_RSN_MAX
};

enum coex_lte_coex_table_type {
	COEX_CTT_WL_VS_LTE,
	COEX_CTT_BT_VS_LTE,
};

enum coex_gnt_setup_state {
	COEX_GNT_SET_HW_PTA	= 0x0,
	COEX_GNT_SET_SW_LOW	= 0x1,
	COEX_GNT_SET_SW_HIGH	= 0x3,
};

enum coex_ext_ant_switch_pos_type {
	COEX_SWITCH_TO_BT,
	COEX_SWITCH_TO_WLG,
	COEX_SWITCH_TO_WLA,
	COEX_SWITCH_TO_NOCARE,
	COEX_SWITCH_TO_WLG_BT,

	COEX_SWITCH_TO_MAX
};

enum coex_ext_ant_switch_ctrl_type {
	COEX_SWITCH_CTRL_BY_BBSW,
	COEX_SWITCH_CTRL_BY_PTA,
	COEX_SWITCH_CTRL_BY_ANTDIV,
	COEX_SWITCH_CTRL_BY_MAC,
	COEX_SWITCH_CTRL_BY_BT,
	COEX_SWITCH_CTRL_BY_FW,

	COEX_SWITCH_CTRL_MAX
};

enum coex_algorithm {
	COEX_ALGO_NOPROFILE	= 0,
	COEX_ALGO_HFP		= 1,
	COEX_ALGO_HID		= 2,
	COEX_ALGO_A2DP		= 3,
	COEX_ALGO_PAN		= 4,
	COEX_ALGO_A2DP_HID	= 5,
	COEX_ALGO_A2DP_PAN	= 6,
	COEX_ALGO_PAN_HID	= 7,
	COEX_ALGO_A2DP_PAN_HID	= 8,

	COEX_ALGO_MAX
};

enum coex_wl_link_mode {
	COEX_WLINK_2G1PORT	= 0x0,
	COEX_WLINK_5G		= 0x3,
	COEX_WLINK_MAX
};

enum coex_wl2bt_scoreboard {
	COEX_SCBD_ACTIVE	= BIT(0),
	COEX_SCBD_ONOFF		= BIT(1),
	COEX_SCBD_SCAN		= BIT(2),
	COEX_SCBD_UNDERTEST	= BIT(3),
	COEX_SCBD_RXGAIN	= BIT(4),
	COEX_SCBD_BT_RFK	= BIT(5),
	COEX_SCBD_WLBUSY	= BIT(6),
	COEX_SCBD_EXTFEM	= BIT(8),
	COEX_SCBD_TDMA		= BIT(9),
	COEX_SCBD_FIX2M		= BIT(10),
	COEX_SCBD_ALL		= GENMASK(15, 0),
};

enum coex_power_save_type {
	COEX_PS_WIFI_NATIVE	= 0,
	COEX_PS_LPS_ON		= 1,
	COEX_PS_LPS_OFF		= 2,
};

enum coex_rssi_state {
	COEX_RSSI_STATE_HIGH,
	COEX_RSSI_STATE_MEDIUM,
	COEX_RSSI_STATE_LOW,
	COEX_RSSI_STATE_STAY_HIGH,
	COEX_RSSI_STATE_STAY_MEDIUM,
	COEX_RSSI_STATE_STAY_LOW,
};

enum coex_notify_type_ips {
	COEX_IPS_LEAVE		= 0x0,
	COEX_IPS_ENTER		= 0x1,
};

enum coex_notify_type_lps {
	COEX_LPS_DISABLE	= 0x0,
	COEX_LPS_ENABLE		= 0x1,
};

enum coex_notify_type_scan {
	COEX_SCAN_FINISH,
	COEX_SCAN_START,
	COEX_SCAN_START_2G,
	COEX_SCAN_START_5G,
};

enum coex_notify_type_switchband {
	COEX_NOT_SWITCH,
	COEX_SWITCH_TO_24G,
	COEX_SWITCH_TO_5G,
	COEX_SWITCH_TO_24G_NOFORSCAN,
};

enum coex_notify_type_associate {
	COEX_ASSOCIATE_FINISH,
	COEX_ASSOCIATE_START,
	COEX_ASSOCIATE_5G_FINISH,
	COEX_ASSOCIATE_5G_START,
};

enum coex_notify_type_media_status {
	COEX_MEDIA_DISCONNECT,
	COEX_MEDIA_CONNECT,
	COEX_MEDIA_CONNECT_5G,
};

enum coex_bt_status {
	COEX_BTSTATUS_NCON_IDLE		= 0,
	COEX_BTSTATUS_CON_IDLE		= 1,
	COEX_BTSTATUS_INQ_PAGE		= 2,
	COEX_BTSTATUS_ACL_BUSY		= 3,
	COEX_BTSTATUS_SCO_BUSY		= 4,
	COEX_BTSTATUS_ACL_SCO_BUSY	= 5,

	COEX_BTSTATUS_MAX
};

enum coex_wl_tput_dir {
	COEX_WL_TPUT_TX			= 0x0,
	COEX_WL_TPUT_RX			= 0x1,
	COEX_WL_TPUT_MAX
};

enum coex_wl_priority_mask {
	COEX_WLPRI_RX_RSP	= 2,
	COEX_WLPRI_TX_RSP	= 3,
	COEX_WLPRI_TX_BEACON	= 4,
	COEX_WLPRI_TX_OFDM	= 11,
	COEX_WLPRI_TX_CCK	= 12,
	COEX_WLPRI_TX_BEACONQ	= 27,
	COEX_WLPRI_RX_CCK	= 28,
	COEX_WLPRI_RX_OFDM	= 29,
	COEX_WLPRI_MAX
};

enum coex_commom_chip_setup {
	COEX_CSETUP_INIT_HW		= 0x0,
	COEX_CSETUP_ANT_SWITCH		= 0x1,
	COEX_CSETUP_GNT_FIX		= 0x2,
	COEX_CSETUP_GNT_DEBUG		= 0x3,
	COEX_CSETUP_RFE_TYPE		= 0x4,
	COEX_CSETUP_COEXINFO_HW		= 0x5,
	COEX_CSETUP_WL_TX_POWER		= 0x6,
	COEX_CSETUP_WL_RX_GAIN		= 0x7,
	COEX_CSETUP_WLAN_ACT_IPS	= 0x8,
	COEX_CSETUP_MAX
};

enum coex_indirect_reg_type {
	COEX_INDIRECT_1700		= 0x0,
	COEX_INDIRECT_7C0		= 0x1,
	COEX_INDIRECT_MAX
};

enum coex_pstdma_type {
	COEX_PSTDMA_FORCE_LPSOFF	= 0x0,
	COEX_PSTDMA_FORCE_LPSON		= 0x1,
	COEX_PSTDMA_MAX
};

enum coex_btrssi_type {
	COEX_BTRSSI_RATIO		= 0x0,
	COEX_BTRSSI_DBM			= 0x1,
	COEX_BTRSSI_MAX
};

struct coex_table_para {
	u32 bt;
	u32 wl;
};

struct coex_tdma_para {
	u8 para[5];
};

struct coex_5g_afh_map {
	u32 wl_5g_ch;
	u8 bt_skip_ch;
	u8 bt_skip_span;
};

struct coex_rf_para {
	u8 wl_pwr_dec_lvl;
	u8 bt_pwr_dec_lvl;
	bool wl_low_gain_en;
	u8 bt_lna_lvl;
};

static inline void rtw_coex_set_init(struct rtw_dev *rtwdev)
{
	struct rtw_chip_info *chip = rtwdev->chip;

	chip->ops->coex_set_init(rtwdev);
}

static inline
void rtw_coex_set_ant_switch(struct rtw_dev *rtwdev, u8 ctrl_type, u8 pos_type)
{
	struct rtw_chip_info *chip = rtwdev->chip;

	if (!chip->ops->coex_set_ant_switch)
		return;

	chip->ops->coex_set_ant_switch(rtwdev, ctrl_type, pos_type);
}

static inline void rtw_coex_set_gnt_fix(struct rtw_dev *rtwdev)
{
	struct rtw_chip_info *chip = rtwdev->chip;

	chip->ops->coex_set_gnt_fix(rtwdev);
}

static inline void rtw_coex_set_gnt_debug(struct rtw_dev *rtwdev)
{
	struct rtw_chip_info *chip = rtwdev->chip;

	chip->ops->coex_set_gnt_debug(rtwdev);
}

static inline  void rtw_coex_set_rfe_type(struct rtw_dev *rtwdev)
{
	struct rtw_chip_info *chip = rtwdev->chip;

	chip->ops->coex_set_rfe_type(rtwdev);
}

static inline void rtw_coex_set_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr)
{
	struct rtw_chip_info *chip = rtwdev->chip;

	chip->ops->coex_set_wl_tx_power(rtwdev, wl_pwr);
}

static inline
void rtw_coex_set_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain)
{
	struct rtw_chip_info *chip = rtwdev->chip;

	chip->ops->coex_set_wl_rx_gain(rtwdev, low_gain);
}

void rtw_coex_info_response(struct rtw_dev *rtwdev, struct sk_buff *skb);
void rtw_coex_write_indirect_reg(struct rtw_dev *rtwdev, u16 addr,
				 u32 mask, u32 val);
void rtw_coex_write_scbd(struct rtw_dev *rtwdev, u16 bitpos, bool set);

void rtw_coex_bt_relink_work(struct work_struct *work);
void rtw_coex_bt_reenable_work(struct work_struct *work);
void rtw_coex_defreeze_work(struct work_struct *work);

void rtw_coex_power_on_setting(struct rtw_dev *rtwdev);
void rtw_coex_init_hw_config(struct rtw_dev *rtwdev, bool wifi_only);
void rtw_coex_ips_notify(struct rtw_dev *rtwdev, u8 type);
void rtw_coex_lps_notify(struct rtw_dev *rtwdev, u8 type);
void rtw_coex_scan_notify(struct rtw_dev *rtwdev, u8 type);
void rtw_coex_connect_notify(struct rtw_dev *rtwdev, u8 action);
void rtw_coex_media_status_notify(struct rtw_dev *rtwdev, u8 status);
void rtw_coex_bt_info_notify(struct rtw_dev *rtwdev, u8 *buf, u8 len);
void rtw_coex_wl_fwdbginfo_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length);
void rtw_coex_switchband_notify(struct rtw_dev *rtwdev, u8 type);
void rtw_coex_wl_status_change_notify(struct rtw_dev *rtwdev);

#endif
+106 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
 */

#include "main.h"
#include "coex.h"
#include "fw.h"
#include "tx.h"
#include "reg.h"
@@ -39,6 +40,12 @@ void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb)
	mutex_lock(&rtwdev->mutex);

	switch (c2h->id) {
	case C2H_BT_INFO:
		rtw_coex_bt_info_notify(rtwdev, c2h->payload, len);
		break;
	case C2H_WLAN_INFO:
		rtw_coex_wl_fwdbginfo_notify(rtwdev, c2h->payload, len);
		break;
	case C2H_HALMAC:
		rtw_fw_c2h_cmd_handle_ext(rtwdev, skb);
		break;
@@ -63,6 +70,9 @@ void rtw_fw_c2h_cmd_rx_irqsafe(struct rtw_dev *rtwdev, u32 pkt_offset,
		c2h->id, c2h->seq, len);

	switch (c2h->id) {
	case C2H_BT_MP_INFO:
		rtw_coex_info_response(rtwdev, skb);
		break;
	default:
		/* pass offset for further operation */
		*((u32 *)skb->cb) = pkt_offset;
@@ -206,6 +216,102 @@ void rtw_fw_do_iqk(struct rtw_dev *rtwdev, struct rtw_iqk_para *para)
	rtw_fw_send_h2c_packet(rtwdev, h2c_pkt);
}

void rtw_fw_query_bt_info(struct rtw_dev *rtwdev)
{
	u8 h2c_pkt[H2C_PKT_SIZE] = {0};

	SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_QUERY_BT_INFO);

	SET_QUERY_BT_INFO(h2c_pkt, true);

	rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
}

void rtw_fw_wl_ch_info(struct rtw_dev *rtwdev, u8 link, u8 ch, u8 bw)
{
	u8 h2c_pkt[H2C_PKT_SIZE] = {0};

	SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_WL_CH_INFO);

	SET_WL_CH_INFO_LINK(h2c_pkt, link);
	SET_WL_CH_INFO_CHNL(h2c_pkt, ch);
	SET_WL_CH_INFO_BW(h2c_pkt, bw);

	rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
}

void rtw_fw_query_bt_mp_info(struct rtw_dev *rtwdev,
			     struct rtw_coex_info_req *req)
{
	u8 h2c_pkt[H2C_PKT_SIZE] = {0};

	SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_QUERY_BT_MP_INFO);

	SET_BT_MP_INFO_SEQ(h2c_pkt, req->seq);
	SET_BT_MP_INFO_OP_CODE(h2c_pkt, req->op_code);
	SET_BT_MP_INFO_PARA1(h2c_pkt, req->para1);
	SET_BT_MP_INFO_PARA2(h2c_pkt, req->para2);
	SET_BT_MP_INFO_PARA3(h2c_pkt, req->para3);

	rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
}

void rtw_fw_force_bt_tx_power(struct rtw_dev *rtwdev, u8 bt_pwr_dec_lvl)
{
	u8 h2c_pkt[H2C_PKT_SIZE] = {0};
	u8 index = 0 - bt_pwr_dec_lvl;

	SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_FORCE_BT_TX_POWER);

	SET_BT_TX_POWER_INDEX(h2c_pkt, index);

	rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
}

void rtw_fw_bt_ignore_wlan_action(struct rtw_dev *rtwdev, bool enable)
{
	u8 h2c_pkt[H2C_PKT_SIZE] = {0};

	SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_IGNORE_WLAN_ACTION);

	SET_IGNORE_WLAN_ACTION_EN(h2c_pkt, enable);

	rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
}

void rtw_fw_coex_tdma_type(struct rtw_dev *rtwdev,
			   u8 para1, u8 para2, u8 para3, u8 para4, u8 para5)
{
	u8 h2c_pkt[H2C_PKT_SIZE] = {0};

	SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_COEX_TDMA_TYPE);

	SET_COEX_TDMA_TYPE_PARA1(h2c_pkt, para1);
	SET_COEX_TDMA_TYPE_PARA2(h2c_pkt, para2);
	SET_COEX_TDMA_TYPE_PARA3(h2c_pkt, para3);
	SET_COEX_TDMA_TYPE_PARA4(h2c_pkt, para4);
	SET_COEX_TDMA_TYPE_PARA5(h2c_pkt, para5);

	rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
}

void rtw_fw_bt_wifi_control(struct rtw_dev *rtwdev, u8 op_code, u8 *data)
{
	u8 h2c_pkt[H2C_PKT_SIZE] = {0};

	SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_BT_WIFI_CONTROL);

	SET_BT_WIFI_CONTROL_OP_CODE(h2c_pkt, op_code);

	SET_BT_WIFI_CONTROL_DATA1(h2c_pkt, *data);
	SET_BT_WIFI_CONTROL_DATA2(h2c_pkt, *(data + 1));
	SET_BT_WIFI_CONTROL_DATA3(h2c_pkt, *(data + 2));
	SET_BT_WIFI_CONTROL_DATA4(h2c_pkt, *(data + 3));
	SET_BT_WIFI_CONTROL_DATA5(h2c_pkt, *(data + 4));

	rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
}

void rtw_fw_send_rssi_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)
{
	u8 h2c_pkt[H2C_PKT_SIZE] = {0};
+71 −0
Original line number Diff line number Diff line
@@ -35,7 +35,9 @@

enum rtw_c2h_cmd_id {
	C2H_BT_INFO = 0x09,
	C2H_BT_MP_INFO = 0x0b,
	C2H_HW_FEATURE_REPORT = 0x19,
	C2H_WLAN_INFO = 0x27,
	C2H_HW_FEATURE_DUMP = 0xfd,
	C2H_HALMAC = 0xff,
};
@@ -71,6 +73,14 @@ enum rtw_fw_rf_type {
	FW_RF_MAX_TYPE = 0xF,
};

struct rtw_coex_info_req {
	u8 seq;
	u8 op_code;
	u8 para1;
	u8 para2;
	u8 para3;
};

struct rtw_iqk_para {
	u8 clear;
	u8 segment_iqk;
@@ -139,6 +149,14 @@ static inline void rtw_h2c_pkt_set_header(u8 *h2c_pkt, u8 sub_id)
#define H2C_CMD_RA_INFO			0x40
#define H2C_CMD_RSSI_MONITOR		0x42

#define H2C_CMD_COEX_TDMA_TYPE		0x60
#define H2C_CMD_QUERY_BT_INFO		0x61
#define H2C_CMD_FORCE_BT_TX_POWER	0x62
#define H2C_CMD_IGNORE_WLAN_ACTION	0x63
#define H2C_CMD_WL_CH_INFO		0x66
#define H2C_CMD_QUERY_BT_MP_INFO	0x67
#define H2C_CMD_BT_WIFI_CONTROL		0x69

#define SET_H2C_CMD_ID_CLASS(h2c_pkt, value)				       \
	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(7, 0))

@@ -191,6 +209,50 @@ static inline void rtw_h2c_pkt_set_header(u8 *h2c_pkt, u8 sub_id)
	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(23, 16))
#define SET_RA_INFO_RA_MASK3(h2c_pkt, value)                                   \
	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(31, 24))
#define SET_QUERY_BT_INFO(h2c_pkt, value)                                      \
	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8))
#define SET_WL_CH_INFO_LINK(h2c_pkt, value)                                    \
	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 8))
#define SET_WL_CH_INFO_CHNL(h2c_pkt, value)                                    \
	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16))
#define SET_WL_CH_INFO_BW(h2c_pkt, value)                                      \
	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(31, 24))
#define SET_BT_MP_INFO_SEQ(h2c_pkt, value)                                     \
	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 12))
#define SET_BT_MP_INFO_OP_CODE(h2c_pkt, value)                                 \
	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16))
#define SET_BT_MP_INFO_PARA1(h2c_pkt, value)                                   \
	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(31, 24))
#define SET_BT_MP_INFO_PARA2(h2c_pkt, value)                                   \
	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(7, 0))
#define SET_BT_MP_INFO_PARA3(h2c_pkt, value)                                   \
	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(15, 8))
#define SET_BT_TX_POWER_INDEX(h2c_pkt, value)                                  \
	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 8))
#define SET_IGNORE_WLAN_ACTION_EN(h2c_pkt, value)                              \
	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8))
#define SET_COEX_TDMA_TYPE_PARA1(h2c_pkt, value)                               \
	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 8))
#define SET_COEX_TDMA_TYPE_PARA2(h2c_pkt, value)                               \
	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16))
#define SET_COEX_TDMA_TYPE_PARA3(h2c_pkt, value)                               \
	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(31, 24))
#define SET_COEX_TDMA_TYPE_PARA4(h2c_pkt, value)                               \
	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(7, 0))
#define SET_COEX_TDMA_TYPE_PARA5(h2c_pkt, value)                               \
	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(15, 8))
#define SET_BT_WIFI_CONTROL_OP_CODE(h2c_pkt, value)                            \
	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 8))
#define SET_BT_WIFI_CONTROL_DATA1(h2c_pkt, value)                              \
	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16))
#define SET_BT_WIFI_CONTROL_DATA2(h2c_pkt, value)                              \
	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(31, 24))
#define SET_BT_WIFI_CONTROL_DATA3(h2c_pkt, value)                              \
	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(7, 0))
#define SET_BT_WIFI_CONTROL_DATA4(h2c_pkt, value)                              \
	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(15, 8))
#define SET_BT_WIFI_CONTROL_DATA5(h2c_pkt, value)                              \
	le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(23, 16))

static inline struct rtw_c2h_cmd *get_c2h_from_skb(struct sk_buff *skb)
{
@@ -208,6 +270,15 @@ void rtw_fw_send_phydm_info(struct rtw_dev *rtwdev);

void rtw_fw_do_iqk(struct rtw_dev *rtwdev, struct rtw_iqk_para *para);
void rtw_fw_set_pwr_mode(struct rtw_dev *rtwdev);
void rtw_fw_query_bt_info(struct rtw_dev *rtwdev);
void rtw_fw_wl_ch_info(struct rtw_dev *rtwdev, u8 link, u8 ch, u8 bw);
void rtw_fw_query_bt_mp_info(struct rtw_dev *rtwdev,
			     struct rtw_coex_info_req *req);
void rtw_fw_force_bt_tx_power(struct rtw_dev *rtwdev, u8 bt_pwr_dec_lvl);
void rtw_fw_bt_ignore_wlan_action(struct rtw_dev *rtwdev, bool enable);
void rtw_fw_coex_tdma_type(struct rtw_dev *rtwdev,
			   u8 para1, u8 para2, u8 para3, u8 para4, u8 para5);
void rtw_fw_bt_wifi_control(struct rtw_dev *rtwdev, u8 op_code, u8 *data);
void rtw_fw_send_rssi_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si);
void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si);
void rtw_fw_media_status_report(struct rtw_dev *rtwdev, u8 mac_id, bool conn);
Loading