summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/realtek/rtw89/mac.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/realtek/rtw89/mac.h')
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac.h221
1 files changed, 217 insertions, 4 deletions
diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h
index 18579c020548..0007229d6753 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.h
+++ b/drivers/net/wireless/realtek/rtw89/mac.h
@@ -6,9 +6,12 @@
#define __RTW89_MAC_H__
#include "core.h"
+#include "fw.h"
#include "reg.h"
-#define MAC_MEM_DUMP_PAGE_SIZE 0x40000
+#define MAC_MEM_DUMP_PAGE_SIZE_AX 0x40000
+#define MAC_MEM_DUMP_PAGE_SIZE_BE 0x80000
+
#define ADDR_CAM_ENT_SIZE 0x40
#define ADDR_CAM_ENT_SHORT_SIZE 0x20
#define BSSID_CAM_ENT_SIZE 0x08
@@ -169,6 +172,20 @@ enum rtw89_mac_ax_l0_to_l1_event {
MAC_AX_L0_TO_L1_EVENT_MAX = 15,
};
+enum rtw89_mac_phy_rpt_size {
+ MAC_AX_PHY_RPT_SIZE_0 = 0,
+ MAC_AX_PHY_RPT_SIZE_8 = 1,
+ MAC_AX_PHY_RPT_SIZE_16 = 2,
+ MAC_AX_PHY_RPT_SIZE_24 = 3,
+};
+
+enum rtw89_mac_hdr_cnv_size {
+ MAC_AX_HDR_CNV_SIZE_0 = 0,
+ MAC_AX_HDR_CNV_SIZE_32 = 1,
+ MAC_AX_HDR_CNV_SIZE_64 = 2,
+ MAC_AX_HDR_CNV_SIZE_96 = 3,
+};
+
enum rtw89_mac_wow_fw_status {
WOWLAN_NOT_READY = 0x00,
WOWLAN_SLEEP_READY = 0x01,
@@ -356,6 +373,7 @@ enum rtw89_mac_mem_sel {
RTW89_MAC_MEM_TXD_FIFO_0_V1,
RTW89_MAC_MEM_TXD_FIFO_1_V1,
RTW89_MAC_MEM_WD_PAGE,
+ RTW89_MAC_MEM_MLD_TBL,
/* keep last */
RTW89_MAC_MEM_NUM,
@@ -401,6 +419,7 @@ enum rtw89_mac_c2h_info_func {
RTW89_MAC_C2H_FUNC_DONE_ACK,
RTW89_MAC_C2H_FUNC_C2H_LOG,
RTW89_MAC_C2H_FUNC_BCN_CNT,
+ RTW89_MAC_C2H_FUNC_BCN_UPD_DONE = 0x06,
RTW89_MAC_C2H_FUNC_INFO_MAX,
};
@@ -413,6 +432,24 @@ enum rtw89_mac_c2h_mcc_func {
NUM_OF_RTW89_MAC_C2H_FUNC_MCC,
};
+enum rtw89_mac_c2h_misc_func {
+ RTW89_MAC_C2H_FUNC_TX_REPORT = 1,
+
+ NUM_OF_RTW89_MAC_C2H_FUNC_MISC,
+};
+
+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,
@@ -426,6 +463,12 @@ enum rtw89_mac_c2h_wow_func {
NUM_OF_RTW89_MAC_C2H_FUNC_WOW,
};
+enum rtw89_mac_c2h_ap_func {
+ RTW89_MAC_C2H_FUNC_PWR_INT_NOTIFY = 0,
+
+ NUM_OF_RTW89_MAC_C2H_FUNC_AP,
+};
+
enum rtw89_mac_c2h_class {
RTW89_MAC_C2H_CLASS_INFO = 0x0,
RTW89_MAC_C2H_CLASS_OFLD = 0x1,
@@ -433,7 +476,11 @@ 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_MISC = 0x9,
+ RTW89_MAC_C2H_CLASS_MLO = 0xc,
RTW89_MAC_C2H_CLASS_MRC = 0xe,
+ RTW89_MAC_C2H_CLASS_AP = 0x18,
+ RTW89_MAC_C2H_CLASS_ROLE = 0x1b,
RTW89_MAC_C2H_CLASS_MAX,
};
@@ -534,8 +581,6 @@ enum rtw89_mac_bf_rrsc_rate {
RTW89_MAC_BF_RRSC_MAX = 32
};
-#define RTW89_R32_EA 0xEAEAEAEA
-#define RTW89_R32_DEAD 0xDEADBEEF
#define MAC_REG_POOL_COUNT 10
#define ACCESS_CMAC(_addr) \
({typeof(_addr) __addr = (_addr); \
@@ -877,32 +922,45 @@ struct rtw89_mac_size_set {
const struct rtw89_hfc_prec_cfg hfc_prec_cfg_c0;
const struct rtw89_hfc_prec_cfg hfc_prec_cfg_c2;
const struct rtw89_dle_size wde_size0;
+ const struct rtw89_dle_size wde_size1;
const struct rtw89_dle_size wde_size0_v1;
const struct rtw89_dle_size wde_size4;
const struct rtw89_dle_size wde_size4_v1;
const struct rtw89_dle_size wde_size6;
const struct rtw89_dle_size wde_size7;
const struct rtw89_dle_size wde_size9;
+ const struct rtw89_dle_size wde_size17;
const struct rtw89_dle_size wde_size18;
const struct rtw89_dle_size wde_size19;
const struct rtw89_dle_size wde_size23;
+ const struct rtw89_dle_size wde_size25;
+ const struct rtw89_dle_size wde_size31;
const struct rtw89_dle_size ple_size0;
+ const struct rtw89_dle_size ple_size1;
const struct rtw89_dle_size ple_size0_v1;
const struct rtw89_dle_size ple_size3_v1;
const struct rtw89_dle_size ple_size4;
const struct rtw89_dle_size ple_size6;
const struct rtw89_dle_size ple_size8;
const struct rtw89_dle_size ple_size9;
+ const struct rtw89_dle_size ple_size17;
const struct rtw89_dle_size ple_size18;
const struct rtw89_dle_size ple_size19;
+ const struct rtw89_dle_size ple_size32;
+ const struct rtw89_dle_size ple_size33;
+ const struct rtw89_dle_size ple_size34;
const struct rtw89_wde_quota wde_qt0;
+ const struct rtw89_wde_quota wde_qt1;
const struct rtw89_wde_quota wde_qt0_v1;
const struct rtw89_wde_quota wde_qt4;
const struct rtw89_wde_quota wde_qt6;
const struct rtw89_wde_quota wde_qt7;
+ const struct rtw89_wde_quota wde_qt16;
const struct rtw89_wde_quota wde_qt17;
const struct rtw89_wde_quota wde_qt18;
const struct rtw89_wde_quota wde_qt23;
+ const struct rtw89_wde_quota wde_qt25;
+ const struct rtw89_wde_quota wde_qt31;
const struct rtw89_ple_quota ple_qt0;
const struct rtw89_ple_quota ple_qt1;
const struct rtw89_ple_quota ple_qt4;
@@ -910,6 +968,10 @@ struct rtw89_mac_size_set {
const struct rtw89_ple_quota ple_qt9;
const struct rtw89_ple_quota ple_qt13;
const struct rtw89_ple_quota ple_qt18;
+ const struct rtw89_ple_quota ple_qt25;
+ const struct rtw89_ple_quota ple_qt26;
+ const struct rtw89_ple_quota ple_qt42;
+ const struct rtw89_ple_quota ple_qt43;
const struct rtw89_ple_quota ple_qt44;
const struct rtw89_ple_quota ple_qt45;
const struct rtw89_ple_quota ple_qt46;
@@ -917,6 +979,12 @@ struct rtw89_mac_size_set {
const struct rtw89_ple_quota ple_qt57;
const struct rtw89_ple_quota ple_qt58;
const struct rtw89_ple_quota ple_qt59;
+ const struct rtw89_ple_quota ple_qt72;
+ const struct rtw89_ple_quota ple_qt73;
+ const struct rtw89_ple_quota ple_qt74;
+ const struct rtw89_ple_quota ple_qt75;
+ const struct rtw89_ple_quota ple_qt78;
+ const struct rtw89_ple_quota ple_qt79;
const struct rtw89_ple_quota ple_qt_52a_wow;
const struct rtw89_ple_quota ple_qt_52b_wow;
const struct rtw89_ple_quota ple_qt_52bt_wow;
@@ -934,6 +1002,7 @@ struct rtw89_mac_gen_def {
u32 filter_model_addr;
u32 indir_access_addr;
const u32 *mem_base_addrs;
+ u32 mem_page_size;
u32 rx_fltr;
const struct rtw89_port_reg *port_base;
u32 agg_len_ht;
@@ -943,6 +1012,8 @@ struct rtw89_mac_gen_def {
struct rtw89_reg_def bfee_ctrl;
struct rtw89_reg_def narrow_bw_ru_dis;
struct rtw89_reg_def wow_ctrl;
+ struct rtw89_reg_def agg_limit;
+ struct rtw89_reg_def txcnt_limit;
int (*check_mac_en)(struct rtw89_dev *rtwdev, u8 band,
enum rtw89_mac_hwmod_sel sel);
@@ -961,6 +1032,7 @@ struct rtw89_mac_gen_def {
enum rtw89_mac_fwd_target fwd_target,
u8 mac_idx);
int (*cfg_ppdu_status)(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable);
+ void (*cfg_phy_rpt)(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable);
int (*dle_mix_cfg)(struct rtw89_dev *rtwdev, const struct rtw89_dle_mem *cfg);
int (*chk_dle_rdy)(struct rtw89_dev *rtwdev, bool wde_or_ple);
@@ -1007,8 +1079,11 @@ struct rtw89_mac_gen_def {
bool (*is_txq_empty)(struct rtw89_dev *rtwdev);
+ int (*prep_chan_list)(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link);
+ void (*free_chan_list)(struct rtw89_dev *rtwdev);
int (*add_chan_list)(struct rtw89_dev *rtwdev,
- struct rtw89_vif_link *rtwvif_link, bool connected);
+ struct rtw89_vif_link *rtwvif_link);
int (*add_chan_list_pno)(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link);
int (*scan_offload)(struct rtw89_dev *rtwdev,
@@ -1123,8 +1198,10 @@ rtw89_write32_port_set(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_l
rtw89_write32_set(rtwdev, reg, bit);
}
+int rtw89_mac_pwr_on(struct rtw89_dev *rtwdev);
void rtw89_mac_pwr_off(struct rtw89_dev *rtwdev);
int rtw89_mac_partial_init(struct rtw89_dev *rtwdev, bool include_bb);
+int rtw89_mac_preinit(struct rtw89_dev *rtwdev);
int rtw89_mac_init(struct rtw89_dev *rtwdev);
int rtw89_mac_dle_init(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode,
enum rtw89_qta_mode ext_mode);
@@ -1163,6 +1240,8 @@ void rtw89_mac_port_cfg_rx_sync(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link, bool en);
void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link);
+void rtw89_mac_set_he_tb(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link);
void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en);
int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif);
@@ -1216,6 +1295,27 @@ int rtw89_mac_stop_sch_tx_v2(struct rtw89_dev *rtwdev, u8 mac_idx,
int rtw89_mac_resume_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en);
int rtw89_mac_resume_sch_tx_v1(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en);
int rtw89_mac_resume_sch_tx_v2(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en);
+void rtw89_mac_cfg_phy_rpt_be(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable);
+
+static inline
+void rtw89_mac_cfg_phy_rpt(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable)
+{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+
+ if (mac->cfg_phy_rpt)
+ mac->cfg_phy_rpt(rtwdev, mac_idx, enable);
+}
+
+static inline
+void rtw89_mac_cfg_phy_rpt_bands(struct rtw89_dev *rtwdev, bool enable)
+{
+ rtw89_mac_cfg_phy_rpt(rtwdev, RTW89_MAC_0, enable);
+
+ if (!rtwdev->dbcc_en)
+ return;
+
+ rtw89_mac_cfg_phy_rpt(rtwdev, RTW89_MAC_1, enable);
+}
static inline
int rtw89_mac_cfg_ppdu_status(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable)
@@ -1240,6 +1340,7 @@ int rtw89_mac_cfg_ppdu_status_bands(struct rtw89_dev *rtwdev, bool enable)
return rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_1, enable);
}
+void rtw89_mac_set_rx_fltr(struct rtw89_dev *rtwdev, u8 mac_idx, u32 rx_fltr);
void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev);
void rtw89_mac_flush_txq(struct rtw89_dev *rtwdev, u32 queues, bool drop);
int rtw89_mac_coex_init(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex *coex);
@@ -1506,4 +1607,116 @@ void rtw89_fwdl_secure_idmem_share_mode(struct rtw89_dev *rtwdev, u8 mode)
return mac->fwdl_secure_idmem_share_mode(rtwdev, mode);
}
+
+static inline
+int rtw89_mac_scan_offload(struct rtw89_dev *rtwdev,
+ struct rtw89_scan_option *option,
+ struct rtw89_vif_link *rtwvif_link,
+ bool wowlan)
+{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+ int ret;
+
+ ret = mac->scan_offload(rtwdev, option, rtwvif_link, wowlan);
+
+ if (option->enable) {
+ /*
+ * At this point, new scan request is acknowledged by firmware,
+ * so scan events of previous scan request become obsoleted.
+ * Purge the queued scan events to prevent interference to
+ * current new request.
+ */
+ rtw89_fw_c2h_purge_obsoleted_scan_events(rtwdev);
+ }
+
+ return ret;
+}
+
+static inline
+void rtw89_tx_rpt_init(struct rtw89_dev *rtwdev,
+ struct rtw89_core_tx_request *tx_req)
+{
+ struct rtw89_tx_rpt *tx_rpt = &rtwdev->tx_rpt;
+
+ if (!rtwdev->hci.tx_rpt_enabled)
+ return;
+
+ tx_req->desc_info.report = true;
+ /* firmware maintains a 4-bit sequence number */
+ tx_req->desc_info.sn = atomic_inc_return(&tx_rpt->sn) &
+ RTW89_MAX_TX_RPTS_MASK;
+ tx_req->desc_info.tx_cnt_lmt_en = true;
+ tx_req->desc_info.tx_cnt_lmt = 8;
+}
+
+static inline
+bool rtw89_is_tx_rpt_skb(struct rtw89_dev *rtwdev, struct sk_buff *skb)
+{
+ struct rtw89_tx_skb_data *skb_data = RTW89_TX_SKB_CB(skb);
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
+ return rtw89_core_is_tx_wait(rtwdev, skb_data) ||
+ (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS);
+}
+
+static inline
+void rtw89_tx_rpt_tx_status(struct rtw89_dev *rtwdev, struct sk_buff *skb,
+ u8 tx_status)
+{
+ struct rtw89_tx_skb_data *skb_data = RTW89_TX_SKB_CB(skb);
+ struct ieee80211_tx_info *info;
+
+ if (rtw89_core_tx_wait_complete(rtwdev, skb_data, tx_status))
+ return;
+
+ info = IEEE80211_SKB_CB(skb);
+ ieee80211_tx_info_clear_status(info);
+
+ if (tx_status == RTW89_TX_DONE)
+ info->flags |= IEEE80211_TX_STAT_ACK;
+ else
+ info->flags &= ~IEEE80211_TX_STAT_ACK;
+
+ ieee80211_tx_status_irqsafe(rtwdev->hw, skb);
+}
+
+static inline
+void rtw89_tx_rpt_skb_add(struct rtw89_dev *rtwdev, struct sk_buff *skb)
+{
+ struct rtw89_tx_rpt *tx_rpt = &rtwdev->tx_rpt;
+ struct rtw89_tx_skb_data *skb_data;
+ u8 idx;
+
+ skb_data = RTW89_TX_SKB_CB(skb);
+ idx = skb_data->tx_rpt_sn;
+
+ scoped_guard(spinlock_irqsave, &tx_rpt->skb_lock) {
+ /* if skb having the similar seq number is still in the queue,
+ * this means the queue is overflowed - it isn't normal and
+ * should indicate firmware doesn't provide TX reports in time;
+ * report the old skb as dropped, we can't do much more here
+ */
+ if (tx_rpt->skbs[idx])
+ rtw89_tx_rpt_tx_status(rtwdev, tx_rpt->skbs[idx],
+ RTW89_TX_MACID_DROP);
+ tx_rpt->skbs[idx] = skb;
+ }
+}
+
+static inline
+void rtw89_tx_rpt_skbs_purge(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_tx_rpt *tx_rpt = &rtwdev->tx_rpt;
+ struct sk_buff *skbs[RTW89_MAX_TX_RPTS];
+
+ scoped_guard(spinlock_irqsave, &tx_rpt->skb_lock) {
+ memcpy(skbs, tx_rpt->skbs, sizeof(tx_rpt->skbs));
+ memset(tx_rpt->skbs, 0, sizeof(tx_rpt->skbs));
+ }
+
+ for (int i = 0; i < ARRAY_SIZE(skbs); i++)
+ if (skbs[i])
+ rtw89_tx_rpt_tx_status(rtwdev, skbs[i],
+ RTW89_TX_MACID_DROP);
+}
#endif