Commit e390cf2e authored by Ching-Te Ku's avatar Ching-Te Ku Committed by Kalle Valo

rtw89: coex: update WL role info v1 for RTL8852C branch using

The H2C format and support feature are different. The newer Wi-Fi firmware
and driver branch need to handshake more information like DBCC or P2P
connection info.
Signed-off-by: default avatarChing-Te Ku <ku920601@realtek.com>
Signed-off-by: default avatarPing-Ke Shih <pkshih@realtek.com>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20220725023509.43114-7-pkshih@realtek.com
parent ce986f3d
This diff is collapsed.
......@@ -1123,6 +1123,27 @@ struct rtw89_btc_wl_active_role {
u16 rx_rate;
};
struct rtw89_btc_wl_active_role_v1 {
u8 connected: 1;
u8 pid: 3;
u8 phy: 1;
u8 noa: 1;
u8 band: 2;
u8 client_ps: 1;
u8 bw: 7;
u8 role;
u8 ch;
u16 tx_lvl;
u16 rx_lvl;
u16 tx_rate;
u16 rx_rate;
u32 noa_duration; /* ms */
};
struct rtw89_btc_wl_role_info_bpos {
u16 none: 1;
u16 station: 1;
......@@ -1150,6 +1171,21 @@ struct rtw89_btc_wl_role_info { /* struct size must be n*4 bytes */
struct rtw89_btc_wl_active_role active_role[RTW89_PORT_NUM];
};
struct rtw89_btc_wl_role_info_v1 { /* struct size must be n*4 bytes */
u8 connect_cnt;
u8 link_mode;
union rtw89_btc_wl_role_info_map role_map;
struct rtw89_btc_wl_active_role_v1 active_role_v1[RTW89_PORT_NUM];
u32 mrole_type; /* btc_wl_mrole_type */
u32 mrole_noa_duration; /* ms */
u32 dbcc_en: 1;
u32 dbcc_chg: 1;
u32 dbcc_2g_phy: 2; /* which phy operate in 2G, HW_PHY_0 or HW_PHY_1 */
u32 link_mode_chg: 1;
u32 rsvd: 27;
};
struct rtw89_btc_wl_ver_info {
u32 fw_coex; /* match with which coex_ver */
u32 fw;
......@@ -1255,6 +1291,7 @@ struct rtw89_btc_wl_info {
struct rtw89_btc_wl_ver_info ver_info;
struct rtw89_btc_wl_afh_info afh_info;
struct rtw89_btc_wl_role_info role_info;
struct rtw89_btc_wl_role_info_v1 role_info_v1;
struct rtw89_btc_wl_scan_info scan_info;
struct rtw89_btc_wl_dbcc_info dbcc_info;
struct rtw89_btc_rf_para rf_para;
......
......@@ -1448,7 +1448,12 @@ int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev)
return -EBUSY;
}
#define PORT_DATA_OFFSET 4
#define H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN 12
#define H2C_LEN_CXDRVINFO_ROLE (4 + 12 * RTW89_PORT_NUM + H2C_LEN_CXDRVHDR)
#define H2C_LEN_CXDRVINFO_ROLE_V1 (4 + 16 * RTW89_PORT_NUM + \
H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN + \
H2C_LEN_CXDRVHDR)
int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
......@@ -1457,6 +1462,7 @@ int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev)
struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role;
struct rtw89_btc_wl_active_role *active = role_info->active_role;
struct sk_buff *skb;
u8 offset = 0;
u8 *cmd;
int i;
......@@ -1488,19 +1494,19 @@ int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev)
RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan);
for (i = 0; i < RTW89_PORT_NUM; i++, active++) {
RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, active->connected, i);
RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, active->pid, i);
RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, active->phy, i);
RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, active->noa, i);
RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, active->band, i);
RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, active->client_ps, i);
RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, active->bw, i);
RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, active->role, i);
RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, active->ch, i);
RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, active->tx_lvl, i);
RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, active->rx_lvl, i);
RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, active->tx_rate, i);
RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, active->rx_rate, i);
RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, active->connected, i, offset);
RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, active->pid, i, offset);
RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, active->phy, i, offset);
RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, active->noa, i, offset);
RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, active->band, i, offset);
RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, active->client_ps, i, offset);
RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, active->bw, i, offset);
RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, active->role, i, offset);
RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, active->ch, i, offset);
RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, active->tx_lvl, i, offset);
RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, active->rx_lvl, i, offset);
RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, active->tx_rate, i, offset);
RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, active->rx_rate, i, offset);
}
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
......@@ -1520,6 +1526,87 @@ int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev)
return -EBUSY;
}
int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_wl_role_info_v1 *role_info = &wl->role_info_v1;
struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role;
struct rtw89_btc_wl_active_role_v1 *active = role_info->active_role_v1;
struct sk_buff *skb;
u8 *cmd, offset;
int i;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_ROLE_V1);
if (!skb) {
rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n");
return -ENOMEM;
}
skb_put(skb, H2C_LEN_CXDRVINFO_ROLE_V1);
cmd = skb->data;
RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_ROLE);
RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_ROLE_V1 - H2C_LEN_CXDRVHDR);
RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt);
RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode);
RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none);
RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station);
RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap);
RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap);
RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc);
RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master);
RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh);
RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter);
RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device);
RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc);
RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go);
RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan);
offset = PORT_DATA_OFFSET;
for (i = 0; i < RTW89_PORT_NUM; i++, active++) {
RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, active->connected, i, offset);
RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, active->pid, i, offset);
RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, active->phy, i, offset);
RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, active->noa, i, offset);
RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, active->band, i, offset);
RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, active->client_ps, i, offset);
RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, active->bw, i, offset);
RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, active->role, i, offset);
RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, active->ch, i, offset);
RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, active->tx_lvl, i, offset);
RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, active->rx_lvl, i, offset);
RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, active->tx_rate, i, offset);
RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, active->rx_rate, i, offset);
RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR(cmd, active->noa_duration, i, offset);
}
offset = H2C_LEN_CXDRVINFO_ROLE_V1 - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN;
RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, role_info->mrole_type, offset);
RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, role_info->mrole_noa_duration, offset);
RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, role_info->dbcc_en, offset);
RTW89_SET_FWCMD_CXROLE_DBCC_CHG(cmd, role_info->dbcc_chg, offset);
RTW89_SET_FWCMD_CXROLE_DBCC_2G_PHY(cmd, role_info->dbcc_2g_phy, offset);
RTW89_SET_FWCMD_CXROLE_LINK_MODE_CHG(cmd, role_info->link_mode_chg, offset);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_OUTSRC, BTFC_SET,
SET_DRV_INFO, 0, 0,
H2C_LEN_CXDRVINFO_ROLE_V1);
if (rtw89_h2c_tx(rtwdev, skb, false)) {
rtw89_err(rtwdev, "failed to send h2c\n");
goto fail;
}
return 0;
fail:
dev_kfree_skb_any(skb);
return -EBUSY;
}
#define H2C_LEN_CXDRVINFO_CTRL (4 + H2C_LEN_CXDRVHDR)
int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev)
{
......
......@@ -2006,69 +2006,104 @@ static inline void RTW89_SET_FWCMD_CXROLE_ROLE_NAN(void *cmd, u16 val)
le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(11));
}
static inline void RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(void *cmd, u8 val, int n)
static inline void RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(void *cmd, u8 val, int n, u8 offset)
{
u8p_replace_bits((u8 *)(cmd) + (6 + 12 * (n)), val, BIT(0));
u8p_replace_bits((u8 *)cmd + (6 + (12 + offset) * n), val, BIT(0));
}
static inline void RTW89_SET_FWCMD_CXROLE_ACT_PID(void *cmd, u8 val, int n)
static inline void RTW89_SET_FWCMD_CXROLE_ACT_PID(void *cmd, u8 val, int n, u8 offset)
{
u8p_replace_bits((u8 *)(cmd) + (6 + 12 * (n)), val, GENMASK(3, 1));
u8p_replace_bits((u8 *)cmd + (6 + (12 + offset) * n), val, GENMASK(3, 1));
}
static inline void RTW89_SET_FWCMD_CXROLE_ACT_PHY(void *cmd, u8 val, int n)
static inline void RTW89_SET_FWCMD_CXROLE_ACT_PHY(void *cmd, u8 val, int n, u8 offset)
{
u8p_replace_bits((u8 *)(cmd) + (6 + 12 * (n)), val, BIT(4));
u8p_replace_bits((u8 *)cmd + (6 + (12 + offset) * n), val, BIT(4));
}
static inline void RTW89_SET_FWCMD_CXROLE_ACT_NOA(void *cmd, u8 val, int n)
static inline void RTW89_SET_FWCMD_CXROLE_ACT_NOA(void *cmd, u8 val, int n, u8 offset)
{
u8p_replace_bits((u8 *)(cmd) + (6 + 12 * (n)), val, BIT(5));
u8p_replace_bits((u8 *)cmd + (6 + (12 + offset) * n), val, BIT(5));
}
static inline void RTW89_SET_FWCMD_CXROLE_ACT_BAND(void *cmd, u8 val, int n)
static inline void RTW89_SET_FWCMD_CXROLE_ACT_BAND(void *cmd, u8 val, int n, u8 offset)
{
u8p_replace_bits((u8 *)(cmd) + (6 + 12 * (n)), val, GENMASK(7, 6));
u8p_replace_bits((u8 *)cmd + (6 + (12 + offset) * n), val, GENMASK(7, 6));
}
static inline void RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(void *cmd, u8 val, int n)
static inline void RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(void *cmd, u8 val, int n, u8 offset)
{
u8p_replace_bits((u8 *)(cmd) + (7 + 12 * (n)), val, BIT(0));
u8p_replace_bits((u8 *)cmd + (7 + (12 + offset) * n), val, BIT(0));
}
static inline void RTW89_SET_FWCMD_CXROLE_ACT_BW(void *cmd, u8 val, int n)
static inline void RTW89_SET_FWCMD_CXROLE_ACT_BW(void *cmd, u8 val, int n, u8 offset)
{
u8p_replace_bits((u8 *)(cmd) + (7 + 12 * (n)), val, GENMASK(7, 1));
u8p_replace_bits((u8 *)cmd + (7 + (12 + offset) * n), val, GENMASK(7, 1));
}
static inline void RTW89_SET_FWCMD_CXROLE_ACT_ROLE(void *cmd, u8 val, int n)
static inline void RTW89_SET_FWCMD_CXROLE_ACT_ROLE(void *cmd, u8 val, int n, u8 offset)
{
u8p_replace_bits((u8 *)(cmd) + (8 + 12 * (n)), val, GENMASK(7, 0));
u8p_replace_bits((u8 *)cmd + (8 + (12 + offset) * n), val, GENMASK(7, 0));
}
static inline void RTW89_SET_FWCMD_CXROLE_ACT_CH(void *cmd, u8 val, int n)
static inline void RTW89_SET_FWCMD_CXROLE_ACT_CH(void *cmd, u8 val, int n, u8 offset)
{
u8p_replace_bits((u8 *)(cmd) + (9 + 12 * (n)), val, GENMASK(7, 0));
u8p_replace_bits((u8 *)cmd + (9 + (12 + offset) * n), val, GENMASK(7, 0));
}
static inline void RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(void *cmd, u16 val, int n)
static inline void RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(void *cmd, u16 val, int n, u8 offset)
{
le16p_replace_bits((__le16 *)((u8 *)(cmd) + (10 + 12 * (n))), val, GENMASK(15, 0));
le16p_replace_bits((__le16 *)((u8 *)cmd + (10 + (12 + offset) * n)), val, GENMASK(15, 0));
}
static inline void RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(void *cmd, u16 val, int n)
static inline void RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(void *cmd, u16 val, int n, u8 offset)
{
le16p_replace_bits((__le16 *)((u8 *)(cmd) + (12 + 12 * (n))), val, GENMASK(15, 0));
le16p_replace_bits((__le16 *)((u8 *)cmd + (12 + (12 + offset) * n)), val, GENMASK(15, 0));
}
static inline void RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(void *cmd, u16 val, int n)
static inline void RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(void *cmd, u16 val, int n, u8 offset)
{
le16p_replace_bits((__le16 *)((u8 *)(cmd) + (14 + 12 * (n))), val, GENMASK(15, 0));
le16p_replace_bits((__le16 *)((u8 *)cmd + (14 + (12 + offset) * n)), val, GENMASK(15, 0));
}
static inline void RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(void *cmd, u16 val, int n)
static inline void RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(void *cmd, u16 val, int n, u8 offset)
{
le16p_replace_bits((__le16 *)((u8 *)(cmd) + (16 + 12 * (n))), val, GENMASK(15, 0));
le16p_replace_bits((__le16 *)((u8 *)cmd + (16 + (12 + offset) * n)), val, GENMASK(15, 0));
}
static inline void RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR(void *cmd, u32 val, int n, u8 offset)
{
le32p_replace_bits((__le32 *)((u8 *)cmd + (20 + (12 + offset) * n)), val, GENMASK(31, 0));
}
static inline void RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(void *cmd, u32 val, u8 offset)
{
le32p_replace_bits((__le32 *)((u8 *)cmd + offset), val, GENMASK(31, 0));
}
static inline void RTW89_SET_FWCMD_CXROLE_MROLE_NOA(void *cmd, u32 val, u8 offset)
{
le32p_replace_bits((__le32 *)((u8 *)cmd + offset + 4), val, GENMASK(31, 0));
}
static inline void RTW89_SET_FWCMD_CXROLE_DBCC_EN(void *cmd, u32 val, u8 offset)
{
le32p_replace_bits((__le32 *)((u8 *)cmd + offset + 8), val, BIT(0));
}
static inline void RTW89_SET_FWCMD_CXROLE_DBCC_CHG(void *cmd, u32 val, u8 offset)
{
le32p_replace_bits((__le32 *)((u8 *)cmd + offset + 8), val, BIT(1));
}
static inline void RTW89_SET_FWCMD_CXROLE_DBCC_2G_PHY(void *cmd, u32 val, u8 offset)
{
le32p_replace_bits((__le32 *)((u8 *)cmd + offset + 8), val, GENMASK(3, 2));
}
static inline void RTW89_SET_FWCMD_CXROLE_LINK_MODE_CHG(void *cmd, u32 val, u8 offset)
{
le32p_replace_bits((__le32 *)((u8 *)cmd + offset + 8), val, BIT(4));
}
static inline void RTW89_SET_FWCMD_CXCTRL_MANUAL(void *cmd, u32 val)
......@@ -2610,6 +2645,7 @@ int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev);
int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi);
int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev);
int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev);
int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev);
int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev);
int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev);
int rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev *rtwdev, u8 id);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment