mirror of
https://github.com/torvalds/linux.git
synced 2026-06-02 11:33:28 +02:00
wifi: rtw89: add handling of mlo_link_cfg H2C command and C2H event
The mlo_link_cfg H2C command is used to tell FW to enter/leave PS mode on a given link. And, need to wait for status of C2H event to ensure if FW deals with it successfully. Signed-off-by: Po-Hao Huang <phhuang@realtek.com> Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com> Link: https://patch.msgid.link/20250505072440.45113-6-pkshih@realtek.com
This commit is contained in:
parent
5b6247de57
commit
c3dba0653b
|
|
@ -4945,6 +4945,7 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
|
|||
rtwdev->total_sta_assoc = 0;
|
||||
|
||||
rtw89_init_wait(&rtwdev->mcc.wait);
|
||||
rtw89_init_wait(&rtwdev->mlo.wait);
|
||||
rtw89_init_wait(&rtwdev->mac.fw_ofld_wait);
|
||||
rtw89_init_wait(&rtwdev->wow.wait);
|
||||
rtw89_init_wait(&rtwdev->mac.ps_wait);
|
||||
|
|
|
|||
|
|
@ -5738,6 +5738,10 @@ struct rtw89_mcc_info {
|
|||
struct rtw89_mcc_config config;
|
||||
};
|
||||
|
||||
struct rtw89_mlo_info {
|
||||
struct rtw89_wait_info wait;
|
||||
};
|
||||
|
||||
struct rtw89_dev {
|
||||
struct ieee80211_hw *hw;
|
||||
struct device *dev;
|
||||
|
|
@ -5753,6 +5757,7 @@ struct rtw89_dev {
|
|||
const struct rtw89_rfe_parms *rfe_parms;
|
||||
struct rtw89_hal hal;
|
||||
struct rtw89_mcc_info mcc;
|
||||
struct rtw89_mlo_info mlo;
|
||||
struct rtw89_mac_info mac;
|
||||
struct rtw89_fw_info fw;
|
||||
struct rtw89_hci_info hci;
|
||||
|
|
|
|||
|
|
@ -8956,6 +8956,47 @@ int rtw89_fw_h2c_ap_info_refcount(struct rtw89_dev *rtwdev, bool en)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int rtw89_fw_h2c_mlo_link_cfg(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
|
||||
bool enable)
|
||||
{
|
||||
struct rtw89_wait_info *wait = &rtwdev->mlo.wait;
|
||||
struct rtw89_h2c_mlo_link_cfg *h2c;
|
||||
u8 mac_id = rtwvif_link->mac_id;
|
||||
u32 len = sizeof(*h2c);
|
||||
struct sk_buff *skb;
|
||||
unsigned int cond;
|
||||
int ret;
|
||||
|
||||
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
|
||||
if (!skb) {
|
||||
rtw89_err(rtwdev, "failed to alloc skb for mlo link cfg\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
skb_put(skb, len);
|
||||
h2c = (struct rtw89_h2c_mlo_link_cfg *)skb->data;
|
||||
|
||||
h2c->w0 = le32_encode_bits(mac_id, RTW89_H2C_MLO_LINK_CFG_W0_MACID) |
|
||||
le32_encode_bits(enable, RTW89_H2C_MLO_LINK_CFG_W0_OPTION);
|
||||
|
||||
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
|
||||
H2C_CAT_MAC,
|
||||
H2C_CL_MLO,
|
||||
H2C_FUNC_MLO_LINK_CFG, 0, 0,
|
||||
len);
|
||||
|
||||
cond = RTW89_MLO_WAIT_COND(mac_id, H2C_FUNC_MLO_LINK_CFG);
|
||||
|
||||
ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, cond);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "mlo link cfg (%s link id %u) failed: %d\n",
|
||||
str_enable_disable(enable), rtwvif_link->link_id, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool __fw_txpwr_entry_zero_ext(const void *ext_ptr, u8 ext_len)
|
||||
{
|
||||
static const u8 zeros[U8_MAX] = {};
|
||||
|
|
|
|||
|
|
@ -2865,6 +2865,13 @@ struct rtw89_h2c_fwips {
|
|||
#define RTW89_H2C_FW_IPS_W0_MACID GENMASK(7, 0)
|
||||
#define RTW89_H2C_FW_IPS_W0_ENABLE BIT(8)
|
||||
|
||||
struct rtw89_h2c_mlo_link_cfg {
|
||||
__le32 w0;
|
||||
};
|
||||
|
||||
#define RTW89_H2C_MLO_LINK_CFG_W0_MACID GENMASK(15, 0)
|
||||
#define RTW89_H2C_MLO_LINK_CFG_W0_OPTION GENMASK(19, 16)
|
||||
|
||||
static inline void RTW89_SET_FWCMD_P2P_MACID(void *cmd, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)cmd, val, GENMASK(7, 0));
|
||||
|
|
@ -3733,6 +3740,25 @@ static_assert(sizeof(struct rtw89_mac_mcc_tsf_rpt) <= RTW89_COMPLETION_BUF_SIZE)
|
|||
#define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_TSF_HIGH(c2h) \
|
||||
le32_get_bits(*((const __le32 *)(c2h) + 4), GENMASK(31, 0))
|
||||
|
||||
struct rtw89_c2h_mlo_link_cfg_rpt {
|
||||
struct rtw89_c2h_hdr hdr;
|
||||
__le32 w2;
|
||||
} __packed;
|
||||
|
||||
#define RTW89_C2H_MLO_LINK_CFG_RPT_W2_MACID GENMASK(15, 0)
|
||||
#define RTW89_C2H_MLO_LINK_CFG_RPT_W2_STATUS GENMASK(19, 16)
|
||||
|
||||
enum rtw89_c2h_mlo_link_status {
|
||||
RTW89_C2H_MLO_LINK_CFG_IDLE = 0,
|
||||
RTW89_C2H_MLO_LINK_CFG_DONE = 1,
|
||||
RTW89_C2H_MLO_LINK_CFG_ISSUE_NULL_FAIL = 2,
|
||||
RTW89_C2H_MLO_LINK_CFG_TX_NULL_FAIL = 3,
|
||||
RTW89_C2H_MLO_LINK_CFG_ROLE_NOT_EXIST = 4,
|
||||
RTW89_C2H_MLO_LINK_CFG_NULL_1_TIMEOUT = 5,
|
||||
RTW89_C2H_MLO_LINK_CFG_NULL_0_TIMEOUT = 6,
|
||||
RTW89_C2H_MLO_LINK_CFG_RUNNING = 0xff,
|
||||
};
|
||||
|
||||
struct rtw89_mac_mrc_tsf_rpt {
|
||||
unsigned int num;
|
||||
u64 tsfs[RTW89_MAC_MRC_MAX_REQ_TSF_NUM];
|
||||
|
|
@ -4252,6 +4278,26 @@ enum rtw89_mcc_h2c_func {
|
|||
#define RTW89_MCC_WAIT_COND(group, func) \
|
||||
((group) * NUM_OF_RTW89_MCC_H2C_FUNC + (func))
|
||||
|
||||
/* CLASS 20 - MLO */
|
||||
#define H2C_CL_MLO 0x14
|
||||
enum rtw89_mlo_h2c_func {
|
||||
H2C_FUNC_MLO_TBL_CFG = 0x0,
|
||||
H2C_FUNC_MLO_STA_CFG = 0x1,
|
||||
H2C_FUNC_MLO_TTLM = 0x2,
|
||||
H2C_FUNC_MLO_DM_CFG = 0x3,
|
||||
H2C_FUNC_MLO_EMLSR_STA_CFG = 0x4,
|
||||
H2C_FUNC_MLO_MCMLO_RELINK_DROP = 0x5,
|
||||
H2C_FUNC_MLO_MCMLO_SN_SYNC = 0x6,
|
||||
H2C_FUNC_MLO_RELINK = 0x7,
|
||||
H2C_FUNC_MLO_LINK_CFG = 0x8,
|
||||
H2C_FUNC_MLO_DM_DBG = 0x9,
|
||||
|
||||
NUM_OF_RTW89_MLO_H2C_FUNC,
|
||||
};
|
||||
|
||||
#define RTW89_MLO_WAIT_COND(macid, func) \
|
||||
((macid) * NUM_OF_RTW89_MLO_H2C_FUNC + (func))
|
||||
|
||||
/* CLASS 24 - MRC */
|
||||
#define H2C_CL_MRC 0x18
|
||||
enum rtw89_mrc_h2c_func {
|
||||
|
|
@ -4829,6 +4875,8 @@ int rtw89_fw_h2c_mrc_sync(struct rtw89_dev *rtwdev,
|
|||
int rtw89_fw_h2c_mrc_upd_duration(struct rtw89_dev *rtwdev,
|
||||
const struct rtw89_fw_mrc_upd_duration_arg *arg);
|
||||
int rtw89_fw_h2c_ap_info_refcount(struct rtw89_dev *rtwdev, bool en);
|
||||
int rtw89_fw_h2c_mlo_link_cfg(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
|
||||
bool enable);
|
||||
|
||||
static inline void rtw89_fw_h2c_init_ba_cam(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5408,6 +5408,27 @@ rtw89_mac_c2h_wow_aoac_rpt(struct rtw89_dev *rtwdev, struct sk_buff *skb, u32 le
|
|||
rtw89_complete_cond(wait, RTW89_WOW_WAIT_COND_AOAC, &data);
|
||||
}
|
||||
|
||||
static void
|
||||
rtw89_mac_c2h_mlo_link_cfg_stat(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
|
||||
{
|
||||
const struct rtw89_c2h_mlo_link_cfg_rpt *c2h_rpt;
|
||||
struct rtw89_wait_info *wait = &rtwdev->mlo.wait;
|
||||
struct rtw89_completion_data data = {};
|
||||
unsigned int cond;
|
||||
u16 mac_id;
|
||||
u8 status;
|
||||
|
||||
c2h_rpt = (const struct rtw89_c2h_mlo_link_cfg_rpt *)c2h->data;
|
||||
|
||||
mac_id = le32_get_bits(c2h_rpt->w2, RTW89_C2H_MLO_LINK_CFG_RPT_W2_MACID);
|
||||
status = le32_get_bits(c2h_rpt->w2, RTW89_C2H_MLO_LINK_CFG_RPT_W2_STATUS);
|
||||
|
||||
data.err = status == RTW89_C2H_MLO_LINK_CFG_ROLE_NOT_EXIST ||
|
||||
status == RTW89_C2H_MLO_LINK_CFG_RUNNING;
|
||||
cond = RTW89_MLO_WAIT_COND(mac_id, H2C_FUNC_MLO_LINK_CFG);
|
||||
rtw89_complete_cond(wait, cond, &data);
|
||||
}
|
||||
|
||||
static void
|
||||
rtw89_mac_c2h_mrc_status_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
|
||||
{
|
||||
|
|
@ -5562,6 +5583,18 @@ void (* const rtw89_mac_c2h_mcc_handler[])(struct rtw89_dev *rtwdev,
|
|||
[RTW89_MAC_C2H_FUNC_MCC_STATUS_RPT] = rtw89_mac_c2h_mcc_status_rpt,
|
||||
};
|
||||
|
||||
static
|
||||
void (* const rtw89_mac_c2h_mlo_handler[])(struct rtw89_dev *rtwdev,
|
||||
struct sk_buff *c2h, u32 len) = {
|
||||
[RTW89_MAC_C2H_FUNC_MLO_GET_TBL] = NULL,
|
||||
[RTW89_MAC_C2H_FUNC_MLO_EMLSR_TRANS_DONE] = NULL,
|
||||
[RTW89_MAC_C2H_FUNC_MLO_EMLSR_STA_CFG_DONE] = NULL,
|
||||
[RTW89_MAC_C2H_FUNC_MCMLO_RELINK_RPT] = NULL,
|
||||
[RTW89_MAC_C2H_FUNC_MCMLO_SN_SYNC_RPT] = NULL,
|
||||
[RTW89_MAC_C2H_FUNC_MLO_LINK_CFG_STAT] = rtw89_mac_c2h_mlo_link_cfg_stat,
|
||||
[RTW89_MAC_C2H_FUNC_MLO_DM_DBG_DUMP] = NULL,
|
||||
};
|
||||
|
||||
static
|
||||
void (* const rtw89_mac_c2h_mrc_handler[])(struct rtw89_dev *rtwdev,
|
||||
struct sk_buff *c2h, u32 len) = {
|
||||
|
|
@ -5631,6 +5664,8 @@ bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
|
|||
}
|
||||
case RTW89_MAC_C2H_CLASS_MCC:
|
||||
return true;
|
||||
case RTW89_MAC_C2H_CLASS_MLO:
|
||||
return true;
|
||||
case RTW89_MAC_C2H_CLASS_MRC:
|
||||
return true;
|
||||
case RTW89_MAC_C2H_CLASS_WOW:
|
||||
|
|
@ -5664,6 +5699,10 @@ void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
|
|||
if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MCC)
|
||||
handler = rtw89_mac_c2h_mcc_handler[func];
|
||||
break;
|
||||
case RTW89_MAC_C2H_CLASS_MLO:
|
||||
if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MLO)
|
||||
handler = rtw89_mac_c2h_mlo_handler[func];
|
||||
break;
|
||||
case RTW89_MAC_C2H_CLASS_MRC:
|
||||
if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MRC)
|
||||
handler = rtw89_mac_c2h_mrc_handler[func];
|
||||
|
|
|
|||
|
|
@ -427,6 +427,18 @@ enum rtw89_mac_c2h_mcc_func {
|
|||
NUM_OF_RTW89_MAC_C2H_FUNC_MCC,
|
||||
};
|
||||
|
||||
enum rtw89_mac_c2h_mlo_func {
|
||||
RTW89_MAC_C2H_FUNC_MLO_GET_TBL = 0x0,
|
||||
RTW89_MAC_C2H_FUNC_MLO_EMLSR_TRANS_DONE = 0x1,
|
||||
RTW89_MAC_C2H_FUNC_MLO_EMLSR_STA_CFG_DONE = 0x2,
|
||||
RTW89_MAC_C2H_FUNC_MCMLO_RELINK_RPT = 0x3,
|
||||
RTW89_MAC_C2H_FUNC_MCMLO_SN_SYNC_RPT = 0x4,
|
||||
RTW89_MAC_C2H_FUNC_MLO_LINK_CFG_STAT = 0x5,
|
||||
RTW89_MAC_C2H_FUNC_MLO_DM_DBG_DUMP = 0x6,
|
||||
|
||||
NUM_OF_RTW89_MAC_C2H_FUNC_MLO,
|
||||
};
|
||||
|
||||
enum rtw89_mac_c2h_mrc_func {
|
||||
RTW89_MAC_C2H_FUNC_MRC_TSF_RPT = 0,
|
||||
RTW89_MAC_C2H_FUNC_MRC_STATUS_RPT = 1,
|
||||
|
|
@ -453,6 +465,7 @@ enum rtw89_mac_c2h_class {
|
|||
RTW89_MAC_C2H_CLASS_WOW = 0x3,
|
||||
RTW89_MAC_C2H_CLASS_MCC = 0x4,
|
||||
RTW89_MAC_C2H_CLASS_FWDBG = 0x5,
|
||||
RTW89_MAC_C2H_CLASS_MLO = 0xc,
|
||||
RTW89_MAC_C2H_CLASS_MRC = 0xe,
|
||||
RTW89_MAC_C2H_CLASS_AP = 0x18,
|
||||
RTW89_MAC_C2H_CLASS_MAX,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user