diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index c9c4ec1d93af..7fe979e47ad5 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -6302,6 +6302,8 @@ int rtw89_core_init(struct rtw89_dev *rtwdev) struct rtw89_btc *btc = &rtwdev->btc; u8 band; + rtwdev->io = rtw89_fw_cmd_ofld_alloc_and_get_io_ops(rtwdev); + bitmap_or(rtwdev->quirks, rtwdev->quirks, &rtwdev->chip->default_quirks, NUM_OF_RTW89_QUIRKS); diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 0b212f6edc8b..bf5585c701ad 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -27,6 +27,7 @@ struct rtw89_phy_calc_efuse_gain; struct rtw89_debugfs; struct rtw89_regd_data; struct rtw89_wow_cam_info; +struct rtw89_fw_cmd_ofld_info; extern const struct ieee80211_ops rtw89_ops; @@ -4569,6 +4570,7 @@ struct rtw89_chip_info { bool support_tas; bool support_sar_by_ant; bool support_noise; + bool support_fw_cmd_ofld; bool ul_tb_waveform_ctrl; bool ul_tb_pwr_diff; bool rx_freq_from_ie; @@ -6202,10 +6204,26 @@ struct rtw89_tid_stats { bool started; }; +struct rtw89_io_ops { + int (*pack)(struct rtw89_dev *rtwdev); + int (*unpack)(struct rtw89_dev *rtwdev); + void (*do_udelay)(struct rtw89_dev *rtwdev, u32 us); + void (*do_mdelay)(struct rtw89_dev *rtwdev, u32 ms); + void (*write8)(struct rtw89_dev *rtwdev, u32 addr, u8 data); + void (*write16)(struct rtw89_dev *rtwdev, u32 addr, u16 data); + void (*write32)(struct rtw89_dev *rtwdev, u32 addr, u32 data); + void (*phy_write8)(struct rtw89_dev *rtwdev, u32 addr, u8 data); + void (*phy_write16)(struct rtw89_dev *rtwdev, u32 addr, u16 data); + void (*phy_write32)(struct rtw89_dev *rtwdev, u32 addr, u32 data); + void (*write_rf)(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask, u32 data); +}; + struct rtw89_dev { struct ieee80211_hw *hw; struct device *dev; const struct ieee80211_ops *ops; + const struct rtw89_io_ops *io; bool dbcc_en; bool support_mlo; @@ -6227,6 +6245,8 @@ struct rtw89_dev { struct rtw89_rfe_data *rfe_data; enum rtw89_custid custid; + struct rtw89_fw_cmd_ofld_info *fw_cmd_ofld_info; + struct rtw89_sta_link __rcu *assoc_link_on_macid[RTW89_MAX_MAC_ID_NUM]; refcount_t refcount_ap_info; @@ -6688,6 +6708,38 @@ struct rtw89_tx_skb_data *RTW89_TX_SKB_CB(struct sk_buff *skb) return (struct rtw89_tx_skb_data *)info->driver_data; } +static inline int rtw89_io_pack(struct rtw89_dev *rtwdev) +{ + if (rtwdev->io->pack) + return rtwdev->io->pack(rtwdev); + + return 0; +} + +static inline int rtw89_io_unpack(struct rtw89_dev *rtwdev) +{ + if (rtwdev->io->unpack) + return rtwdev->io->unpack(rtwdev); + + return 0; +} + +static inline void rtw89_io_udelay(struct rtw89_dev *rtwdev, u32 us) +{ + if (rtwdev->io->do_udelay) + rtwdev->io->do_udelay(rtwdev, us); + else + udelay(us); +} + +static inline void rtw89_io_mdelay(struct rtw89_dev *rtwdev, u32 ms) +{ + if (rtwdev->io->do_mdelay) + rtwdev->io->do_mdelay(rtwdev, ms); + else + mdelay(ms); +} + static inline u8 rtw89_read8(struct rtw89_dev *rtwdev, u32 addr) { return rtwdev->hci.ops->read8(rtwdev, addr); @@ -6703,21 +6755,36 @@ static inline u32 rtw89_read32(struct rtw89_dev *rtwdev, u32 addr) return rtwdev->hci.ops->read32(rtwdev, addr); } -static inline void rtw89_write8(struct rtw89_dev *rtwdev, u32 addr, u8 data) +static inline void rtw89_raw_write8(struct rtw89_dev *rtwdev, u32 addr, u8 data) { rtwdev->hci.ops->write8(rtwdev, addr, data); } -static inline void rtw89_write16(struct rtw89_dev *rtwdev, u32 addr, u16 data) +static inline void rtw89_raw_write16(struct rtw89_dev *rtwdev, u32 addr, u16 data) { rtwdev->hci.ops->write16(rtwdev, addr, data); } -static inline void rtw89_write32(struct rtw89_dev *rtwdev, u32 addr, u32 data) +static inline void rtw89_raw_write32(struct rtw89_dev *rtwdev, u32 addr, u32 data) { rtwdev->hci.ops->write32(rtwdev, addr, data); } +static inline void rtw89_write8(struct rtw89_dev *rtwdev, u32 addr, u8 data) +{ + rtwdev->io->write8(rtwdev, addr, data); +} + +static inline void rtw89_write16(struct rtw89_dev *rtwdev, u32 addr, u16 data) +{ + rtwdev->io->write16(rtwdev, addr, data); +} + +static inline void rtw89_write32(struct rtw89_dev *rtwdev, u32 addr, u32 data) +{ + rtwdev->io->write32(rtwdev, addr, data); +} + static inline void rtw89_write8_set(struct rtw89_dev *rtwdev, u32 addr, u8 bit) { @@ -6862,13 +6929,20 @@ rtw89_read_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, return rtwdev->chip->ops->read_rf(rtwdev, rf_path, addr, mask); } +static inline void +rtw89_raw_write_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + u32 addr, u32 mask, u32 data) +{ + rtwdev->chip->ops->write_rf(rtwdev, rf_path, addr, mask, data); +} + static inline void rtw89_write_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, u32 addr, u32 mask, u32 data) { lockdep_assert_wiphy(rtwdev->hw->wiphy); - rtwdev->chip->ops->write_rf(rtwdev, rf_path, addr, mask, data); + rtwdev->io->write_rf(rtwdev, rf_path, addr, mask, data); } static inline u32 rtw89_read32_pci_cfg(struct rtw89_dev *rtwdev, u32 addr) diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index b578f5316b5f..b5d2540cf212 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -11344,3 +11344,350 @@ rtw89_load_rfe_data_from_fw(struct rtw89_dev *rtwdev, return parms; } + +static int rtw89_fw_cmd_ofld_pack(struct rtw89_dev *rtwdev) +{ + struct rtw89_fw_cmd_ofld_info *info = rtwdev->fw_cmd_ofld_info; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + info->pack_level++; + + return 0; +} + +static void rtw89_fw_cmd_ofld_flush(struct rtw89_dev *rtwdev) +{ + struct rtw89_fw_cmd_ofld_info *info = rtwdev->fw_cmd_ofld_info; + struct sk_buff *skb; + int ret; + u32 len; + + len = info->cnt * sizeof(info->cmds[0]); + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "alloc skb fail\n"); + return; + } + + skb_put_data(skb, info->cmds, len); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, + H2C_CL_MAC_FW_OFLD, + H2C_FUNC_CMD_OFLD_PKT, 0, 0, + len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send cmd ofld\n"); + dev_kfree_skb_any(skb); + return; + } + + if (info->accu_delay) + fsleep(info->accu_delay); + + info->cnt = 0; + info->accu_delay = 0; +} + +static int rtw89_fw_cmd_ofld_unpack(struct rtw89_dev *rtwdev) +{ + struct rtw89_fw_cmd_ofld_info *info = rtwdev->fw_cmd_ofld_info; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + if (info->pack_level == 0) + return -EFAULT; + + if (--info->pack_level != 0) + return 0; + + if (info->cnt == 0) + return 0; + + rtw89_fw_cmd_ofld_flush(rtwdev); + + return 0; +} + +static int rtw89_fw_cmd_ofld_enqueue(struct rtw89_dev *rtwdev, + const struct rtw89_fw_cmd_ofld_arg *cmd) +{ + struct rtw89_fw_cmd_ofld_info *info = rtwdev->fw_cmd_ofld_info; + struct rtw89_h2c_cmd_ofld *h2c; + u32 base_off; + + lockdep_assert_wiphy(rtwdev->hw->wiphy); + + if (info->pack_level == 0) + return 1; + + if (!test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) + return -EBUSY; + + if (cmd->type != RTW89_FW_CMD_OFLD_DELAY && + cmd->src != RTW89_FW_CMD_OFLD_SRC_RF && + cmd->src != RTW89_FW_CMD_OFLD_SRC_RF_DDIE && + !IS_ALIGNED(cmd->offset, 4)) + return -EFAULT; + + if (info->cnt >= ARRAY_SIZE(info->cmds)) + rtw89_fw_cmd_ofld_flush(rtwdev); + + h2c = &info->cmds[info->cnt++]; + + h2c->w0 = le32_encode_bits(cmd->src, RTW89_H2C_CMD_OFLD_W0_SRC) | + le32_encode_bits(cmd->type, RTW89_H2C_CMD_OFLD_W0_TYPE) | + le32_encode_bits(cmd->rf_path, RTW89_H2C_CMD_OFLD_W0_PATH) | + le32_encode_bits(info->cnt, RTW89_H2C_CMD_OFLD_W0_CMD_NUM) | + le32_encode_bits(cmd->offset, RTW89_H2C_CMD_OFLD_W0_OFFSET); + + if (cmd->src == RTW89_FW_CMD_OFLD_SRC_RF_DDIE) + base_off = 1; + else if (cmd->src == RTW89_FW_CMD_OFLD_SRC_RF) + base_off = 0; + else + base_off = cmd->offset >> 16; + + h2c->w1 = le32_encode_bits(cmd->id, RTW89_H2C_CMD_OFLD_W1_ID) | + le32_encode_bits(base_off, RTW89_H2C_CMD_OFLD_W1_BASE_OFFSET); + h2c->w2 = le32_encode_bits(cmd->value, RTW89_H2C_CMD_OFLD_W2_VALUE); + h2c->w3 = le32_encode_bits(cmd->mask, RTW89_H2C_CMD_OFLD_W3_MASK); + + if (cmd->type == RTW89_FW_CMD_OFLD_DELAY) + info->accu_delay += cmd->value; + + return 0; +} + +static const struct rtw89_io_ops rtw89_raw_io = { + .pack = NULL, + .unpack = NULL, + .write8 = rtw89_raw_write8, + .write16 = rtw89_raw_write16, + .write32 = rtw89_raw_write32, + .phy_write8 = rtw89_raw_phy_write8, + .phy_write16 = rtw89_raw_phy_write16, + .phy_write32 = rtw89_raw_phy_write32, + .write_rf = rtw89_raw_write_rf, +}; + +static +void rtw89_fw_cmd_ofld_phy_write8(struct rtw89_dev *rtwdev, u32 addr, u8 data) +{ + struct rtw89_fw_cmd_ofld_arg cmd = { + .src = RTW89_FW_CMD_OFLD_SRC_BB, + .type = RTW89_FW_CMD_OFLD_WRITE, + .offset = ALIGN_DOWN(addr, 4), + .mask = RTW89_W8_MASK_OF_ALIGNED_ADDR(addr), + .value = data, + }; + int ret; + + ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); + if (ret) + rtw89_raw_io.phy_write8(rtwdev, addr, data); +} + +static +void rtw89_fw_cmd_ofld_phy_write16(struct rtw89_dev *rtwdev, u32 addr, u16 data) +{ + struct rtw89_fw_cmd_ofld_arg cmd = { + .src = RTW89_FW_CMD_OFLD_SRC_BB, + .type = RTW89_FW_CMD_OFLD_WRITE, + .offset = ALIGN_DOWN(addr, 2), + .mask = RTW89_W16_MASK_OF_ALIGNED_ADDR(addr), + .value = data, + }; + int ret; + + ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); + if (ret) + rtw89_raw_io.phy_write16(rtwdev, addr, data); +} + +static +void rtw89_fw_cmd_ofld_phy_write32(struct rtw89_dev *rtwdev, u32 addr, u32 data) +{ + struct rtw89_fw_cmd_ofld_arg cmd = { + .src = RTW89_FW_CMD_OFLD_SRC_BB, + .type = RTW89_FW_CMD_OFLD_WRITE, + .offset = addr, + .mask = MASKDWORD, + .value = data, + }; + int ret; + + ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); + if (ret) + rtw89_raw_io.phy_write32(rtwdev, addr, data); +} + +static +void rtw89_fw_cmd_ofld_write8(struct rtw89_dev *rtwdev, u32 addr, u8 data) +{ + struct rtw89_fw_cmd_ofld_arg cmd = { + .src = RTW89_FW_CMD_OFLD_SRC_MAC, + .type = RTW89_FW_CMD_OFLD_WRITE, + .offset = ALIGN_DOWN(addr, 4), + .mask = RTW89_W8_MASK_OF_ALIGNED_ADDR(addr), + .value = data, + }; + int ret; + + ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); + if (ret) + rtw89_raw_io.write8(rtwdev, addr, data); +} + +static +void rtw89_fw_cmd_ofld_write16(struct rtw89_dev *rtwdev, u32 addr, u16 data) +{ + struct rtw89_fw_cmd_ofld_arg cmd = { + .src = RTW89_FW_CMD_OFLD_SRC_MAC, + .type = RTW89_FW_CMD_OFLD_WRITE, + .offset = ALIGN_DOWN(addr, 2), + .mask = RTW89_W16_MASK_OF_ALIGNED_ADDR(addr), + .value = data, + }; + int ret; + + ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); + if (ret) + rtw89_raw_io.write16(rtwdev, addr, data); +} + +static +void rtw89_fw_cmd_ofld_write32(struct rtw89_dev *rtwdev, u32 addr, u32 data) +{ + struct rtw89_fw_cmd_ofld_arg cmd = { + .src = RTW89_FW_CMD_OFLD_SRC_MAC, + .type = RTW89_FW_CMD_OFLD_WRITE, + .offset = addr, + .mask = MASKDWORD, + .value = data, + }; + int ret; + + ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); + if (ret) + rtw89_raw_io.write32(rtwdev, addr, data); +} + +static void rtw89_fw_cmd_ofld_write_rf_ddv(struct rtw89_dev *rtwdev, + struct rtw89_fw_cmd_ofld_arg *cmd, + enum rtw89_rf_path rf_path, u32 addr, u32 mask, + u32 data) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + *cmd = (typeof(*cmd)){ + .src = RTW89_FW_CMD_OFLD_SRC_BB, + .type = RTW89_FW_CMD_OFLD_WRITE, + .rf_path = 0, /* Set rf_path to zero in rf_ddv */ + .offset = chip->rf_base_addr[rf_path] + ((addr & 0xff) << 2), + .mask = mask, + .value = data, + }; +} + +static void rtw89_fw_cmd_ofld_write_rf_dav(struct rtw89_dev *rtwdev, + struct rtw89_fw_cmd_ofld_arg *cmd, + enum rtw89_rf_path rf_path, u32 addr, u32 mask, + u32 data) +{ + *cmd = (typeof(*cmd)){ + .src = RTW89_FW_CMD_OFLD_SRC_RF, + .type = RTW89_FW_CMD_OFLD_WRITE, + .rf_path = rf_path, + .offset = addr, + .mask = mask, + .value = data, + }; +} + +static void rtw89_fw_cmd_ofld_write_rf(struct rtw89_dev *rtwdev, + enum rtw89_rf_path rf_path, u32 addr, u32 mask, + u32 data) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + bool ad_sel = u32_get_bits(addr, RTW89_RF_ADDR_ADSEL_MASK); + struct rtw89_fw_cmd_ofld_arg cmd; + int ret; + + if (unlikely(rf_path >= chip->rf_path_num)) { + rtw89_warn(rtwdev, "unsupported rf path (%d) in fw offload\n", rf_path); + return; + } + + if (ad_sel) + rtw89_fw_cmd_ofld_write_rf_ddv(rtwdev, &cmd, rf_path, addr, mask, data); + else + rtw89_fw_cmd_ofld_write_rf_dav(rtwdev, &cmd, rf_path, addr, mask, data); + + ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); + if (ret) + rtw89_raw_io.write_rf(rtwdev, rf_path, addr, mask, data); +} + +static void rtw89_fw_cmd_ofld_udelay(struct rtw89_dev *rtwdev, u32 us) +{ + struct rtw89_fw_cmd_ofld_arg cmd = { + .src = RTW89_FW_CMD_OFLD_SRC_OTHER, + .type = RTW89_FW_CMD_OFLD_DELAY, + .value = us, + }; + int ret; + + ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); + if (ret) + udelay(us); +} + +static void rtw89_fw_cmd_ofld_mdelay(struct rtw89_dev *rtwdev, u32 ms) +{ + struct rtw89_fw_cmd_ofld_arg cmd = { + .src = RTW89_FW_CMD_OFLD_SRC_OTHER, + .type = RTW89_FW_CMD_OFLD_DELAY, + .value = ms * 1000, + }; + int ret; + + ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd); + if (ret) + mdelay(ms); +} + +static const struct rtw89_io_ops rtw89_fw_cmd_ofld_io = { + .pack = rtw89_fw_cmd_ofld_pack, + .unpack = rtw89_fw_cmd_ofld_unpack, + .do_udelay = rtw89_fw_cmd_ofld_udelay, + .do_mdelay = rtw89_fw_cmd_ofld_mdelay, + .write8 = rtw89_fw_cmd_ofld_write8, + .write16 = rtw89_fw_cmd_ofld_write16, + .write32 = rtw89_fw_cmd_ofld_write32, + .phy_write8 = rtw89_fw_cmd_ofld_phy_write8, + .phy_write16 = rtw89_fw_cmd_ofld_phy_write16, + .phy_write32 = rtw89_fw_cmd_ofld_phy_write32, + .write_rf = rtw89_fw_cmd_ofld_write_rf, +}; + +const struct rtw89_io_ops * +rtw89_fw_cmd_ofld_alloc_and_get_io_ops(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_fw_cmd_ofld_info *info; + + if (!(rtwdev->hci.type == RTW89_HCI_TYPE_USB && chip->support_fw_cmd_ofld)) + return &rtw89_raw_io; + + info = devm_kzalloc(rtwdev->dev, sizeof(*info), GFP_KERNEL); + if (!info) + return &rtw89_raw_io; + + rtwdev->fw_cmd_ofld_info = info; + + return &rtw89_fw_cmd_ofld_io; +} diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index db252d45e498..4d94a7195708 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -3115,6 +3115,59 @@ struct rtw89_h2c_trx_protect { #define RTW89_H2C_TRX_PROTECT_W1_CHINFO_EN BIT(0) #define RTW89_H2C_TRX_PROTECT_W1_DFS_EN BIT(1) +enum rtw89_fw_cmd_ofld_arg_src { + RTW89_FW_CMD_OFLD_SRC_BB, + RTW89_FW_CMD_OFLD_SRC_RF, + RTW89_FW_CMD_OFLD_SRC_MAC, + RTW89_FW_CMD_OFLD_SRC_RF_DDIE, + RTW89_FW_CMD_OFLD_SRC_OTHER, +}; + +enum rtw89_fw_cmd_ofld_arg_type { + RTW89_FW_CMD_OFLD_WRITE, + RTW89_FW_CMD_OFLD_COMPARE, + RTW89_FW_CMD_OFLD_DELAY, + RTW89_FW_CMD_OFLD_MOVE, +}; + +struct rtw89_fw_cmd_ofld_arg { + enum rtw89_fw_cmd_ofld_arg_src src; + enum rtw89_fw_cmd_ofld_arg_type type; + enum rtw89_rf_path rf_path; + u32 value; + u32 mask; + u32 offset; + u16 id; +}; + +struct rtw89_h2c_cmd_ofld { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; +} __packed; + +#define RTW89_H2C_CMD_OFLD_W0_SRC GENMASK(1, 0) +#define RTW89_H2C_CMD_OFLD_W0_TYPE GENMASK(3, 2) +#define RTW89_H2C_CMD_OFLD_W0_LC BIT(4) +#define RTW89_H2C_CMD_OFLD_W0_PATH GENMASK(6, 5) +#define RTW89_H2C_CMD_OFLD_W0_CMD_NUM GENMASK(14, 8) +#define RTW89_H2C_CMD_OFLD_W0_OFFSET GENMASK(31, 16) +#define RTW89_H2C_CMD_OFLD_W1_ID GENMASK(15, 0) +#define RTW89_H2C_CMD_OFLD_W1_BASE_OFFSET GENMASK(31, 16) +#define RTW89_H2C_CMD_OFLD_W2_VALUE GENMASK(31, 0) +#define RTW89_H2C_CMD_OFLD_W3_MASK GENMASK(31, 0) +#define RTW89_W8_MASK_OF_ALIGNED_ADDR(offset) (0xff << (((offset) & 0x3) << 3)) +#define RTW89_W16_MASK_OF_ALIGNED_ADDR(offset) (0xffff << (((offset) & 0x2) * 8)) + +#define RTW89_FW_CMD_OFLD_NR 125 +struct rtw89_fw_cmd_ofld_info { + unsigned int pack_level; + u32 cnt; + u32 accu_delay; + struct rtw89_h2c_cmd_ofld cmds[RTW89_FW_CMD_OFLD_NR]; +}; + struct rtw89_h2c_fwips { __le32 w0; } __packed; @@ -4606,6 +4659,7 @@ enum rtw89_fw_ofld_h2c_func { H2C_FUNC_MAC_MACID_PAUSE = 0x8, H2C_FUNC_USR_EDCA = 0xF, H2C_FUNC_TSF32_TOGL = 0x10, + H2C_FUNC_CMD_OFLD_PKT = 0x13, H2C_FUNC_OFLD_CFG = 0x14, H2C_FUNC_ADD_SCANOFLD_CH = 0x16, H2C_FUNC_SCANOFLD = 0x17, @@ -5737,4 +5791,7 @@ enum rtw89_wow_wakeup_ver { RTW89_WOW_REASON_NUM, }; +const struct rtw89_io_ops * +rtw89_fw_cmd_ofld_alloc_and_get_io_ops(struct rtw89_dev *rtwdev); + #endif diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h index bde419edf744..3f9d306ff1ca 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.h +++ b/drivers/net/wireless/realtek/rtw89/phy.h @@ -576,30 +576,48 @@ extern const struct rtw89_phy_gen_def rtw89_phy_gen_ax; extern const struct rtw89_phy_gen_def rtw89_phy_gen_be; extern const struct rtw89_phy_gen_def rtw89_phy_gen_be_v1; -static inline void rtw89_phy_write8(struct rtw89_dev *rtwdev, - u32 addr, u8 data) +static inline void rtw89_raw_phy_write8(struct rtw89_dev *rtwdev, + u32 addr, u8 data) { const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; rtw89_write8(rtwdev, addr + phy->cr_base, data); } -static inline void rtw89_phy_write16(struct rtw89_dev *rtwdev, - u32 addr, u16 data) +static inline void rtw89_raw_phy_write16(struct rtw89_dev *rtwdev, + u32 addr, u16 data) { const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; rtw89_write16(rtwdev, addr + phy->cr_base, data); } -static inline void rtw89_phy_write32(struct rtw89_dev *rtwdev, - u32 addr, u32 data) +static inline void rtw89_raw_phy_write32(struct rtw89_dev *rtwdev, + u32 addr, u32 data) { const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def; rtw89_write32(rtwdev, addr + phy->cr_base, data); } +static inline void rtw89_phy_write8(struct rtw89_dev *rtwdev, + u32 addr, u8 data) +{ + rtwdev->io->phy_write8(rtwdev, addr, data); +} + +static inline void rtw89_phy_write16(struct rtw89_dev *rtwdev, + u32 addr, u16 data) +{ + rtwdev->io->phy_write16(rtwdev, addr, data); +} + +static inline void rtw89_phy_write32(struct rtw89_dev *rtwdev, + u32 addr, u32 data) +{ + rtwdev->io->phy_write32(rtwdev, addr, data); +} + static inline void rtw89_phy_write32_set(struct rtw89_dev *rtwdev, u32 addr, u32 bits) { diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b.c b/drivers/net/wireless/realtek/rtw89/rtw8851b.c index ff4113eb9114..d9a144b4bf58 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c @@ -2640,6 +2640,7 @@ const struct rtw89_chip_info rtw8851b_chip_info = { .support_tas = false, .support_sar_by_ant = false, .support_noise = false, + .support_fw_cmd_ofld = false, .ul_tb_waveform_ctrl = true, .ul_tb_pwr_diff = false, .rx_freq_from_ie = true, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index ea4d22616512..9cd4c88ee57e 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -2377,6 +2377,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = { .support_tas = false, .support_sar_by_ant = false, .support_noise = true, + .support_fw_cmd_ofld = false, .ul_tb_waveform_ctrl = false, .ul_tb_pwr_diff = false, .rx_freq_from_ie = true, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c index 417b1502a2dd..13c942127225 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c @@ -973,6 +973,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = { .support_tas = false, .support_sar_by_ant = true, .support_noise = false, + .support_fw_cmd_ofld = false, .ul_tb_waveform_ctrl = true, .ul_tb_pwr_diff = false, .rx_freq_from_ie = true, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c index c2184b092395..3fd5990a8bc4 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c @@ -812,6 +812,7 @@ const struct rtw89_chip_info rtw8852bt_chip_info = { .support_tas = false, .support_sar_by_ant = true, .support_noise = false, + .support_fw_cmd_ofld = false, .ul_tb_waveform_ctrl = true, .ul_tb_pwr_diff = false, .rx_freq_from_ie = true, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 9c2c05f80393..9ef469c1080e 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -3170,6 +3170,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = { .support_tas = true, .support_sar_by_ant = true, .support_noise = false, + .support_fw_cmd_ofld = true, .ul_tb_waveform_ctrl = false, .ul_tb_pwr_diff = true, .rx_freq_from_ie = false, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c index 3f94a5e80afe..ebb91fcbd6ab 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c @@ -3173,6 +3173,7 @@ const struct rtw89_chip_info rtw8922a_chip_info = { .support_tas = true, .support_sar_by_ant = true, .support_noise = false, + .support_fw_cmd_ofld = false, .ul_tb_waveform_ctrl = false, .ul_tb_pwr_diff = false, .rx_freq_from_ie = false, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922d.c b/drivers/net/wireless/realtek/rtw89/rtw8922d.c index a550ff8de8fc..d79cdbc67103 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8922d.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8922d.c @@ -2986,6 +2986,7 @@ const struct rtw89_chip_info rtw8922d_chip_info = { .support_tas = false, .support_sar_by_ant = true, .support_noise = false, + .support_fw_cmd_ofld = false, .ul_tb_waveform_ctrl = false, .ul_tb_pwr_diff = false, .rx_freq_from_ie = false,