summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/realtek/rtw89
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/realtek/rtw89')
-rw-r--r--drivers/net/wireless/realtek/rtw89/chan.c124
-rw-r--r--drivers/net/wireless/realtek/rtw89/chan.h5
-rw-r--r--drivers/net/wireless/realtek/rtw89/coex.c3
-rw-r--r--drivers/net/wireless/realtek/rtw89/coex.h9
-rw-r--r--drivers/net/wireless/realtek/rtw89/core.c156
-rw-r--r--drivers/net/wireless/realtek/rtw89/core.h350
-rw-r--r--drivers/net/wireless/realtek/rtw89/debug.c88
-rw-r--r--drivers/net/wireless/realtek/rtw89/fw.c690
-rw-r--r--drivers/net/wireless/realtek/rtw89/fw.h372
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac.c202
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac.h69
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac80211.c14
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac_be.c38
-rw-r--r--drivers/net/wireless/realtek/rtw89/pci.c2
-rw-r--r--drivers/net/wireless/realtek/rtw89/phy.c374
-rw-r--r--drivers/net/wireless/realtek/rtw89/phy.h114
-rw-r--r--drivers/net/wireless/realtek/rtw89/phy_be.c77
-rw-r--r--drivers/net/wireless/realtek/rtw89/ps.c75
-rw-r--r--drivers/net/wireless/realtek/rtw89/ps.h4
-rw-r--r--drivers/net/wireless/realtek/rtw89/reg.h38
-rw-r--r--drivers/net/wireless/realtek/rtw89/regd.c27
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8851b.c20
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852a.c21
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852b.c20
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c4
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852c.c26
-rw-r--r--drivers/net/wireless/realtek/rtw89/sar.c220
-rw-r--r--drivers/net/wireless/realtek/rtw89/sar.h10
-rw-r--r--drivers/net/wireless/realtek/rtw89/ser.c20
-rw-r--r--drivers/net/wireless/realtek/rtw89/txrx.h47
-rw-r--r--drivers/net/wireless/realtek/rtw89/wow.c3
31 files changed, 2555 insertions, 667 deletions
diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c
index 4663db4ce2f6..e1bc3606f9ae 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.c
+++ b/drivers/net/wireless/realtek/rtw89/chan.c
@@ -4,6 +4,8 @@
#include "chan.h"
#include "debug.h"
+#include "fw.h"
+#include "ps.h"
#include "util.h"
static enum rtw89_subband rtw89_get_subband_type(enum rtw89_band band,
@@ -116,6 +118,7 @@ bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev,
rcd->prev_primary_channel = chan->primary_channel;
rcd->prev_band_type = chan->band_type;
band_changed = new->band_type != chan->band_type;
+ rcd->band_changed = band_changed;
*chan = *new;
return band_changed;
@@ -193,8 +196,12 @@ void rtw89_entity_init(struct rtw89_dev *rtwdev)
enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
{
struct rtw89_hal *hal = &rtwdev->hal;
+ const struct cfg80211_chan_def *chandef;
enum rtw89_entity_mode mode;
+ struct rtw89_chan chan;
u8 weight;
+ u8 last;
+ u8 idx;
weight = bitmap_weight(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
switch (weight) {
@@ -206,14 +213,121 @@ enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
rtw89_config_default_chandef(rtwdev);
fallthrough;
case 1:
+ last = RTW89_SUB_ENTITY_0;
mode = RTW89_ENTITY_MODE_SCC;
break;
+ case 2:
+ last = RTW89_SUB_ENTITY_1;
+ mode = rtw89_get_entity_mode(rtwdev);
+ if (mode == RTW89_ENTITY_MODE_MCC)
+ break;
+
+ mode = RTW89_ENTITY_MODE_MCC_PREPARE;
+ break;
+ }
+
+ for (idx = 0; idx <= last; idx++) {
+ chandef = rtw89_chandef_get(rtwdev, idx);
+ rtw89_get_channel_params(chandef, &chan);
+ if (chan.channel == 0) {
+ WARN(1, "Invalid channel on chanctx %d\n", idx);
+ return RTW89_ENTITY_MODE_INVALID;
+ }
+
+ rtw89_assign_entity_chan(rtwdev, idx, &chan);
}
rtw89_set_entity_mode(rtwdev, mode);
return mode;
}
+static void rtw89_chanctx_notify(struct rtw89_dev *rtwdev,
+ enum rtw89_chanctx_state state)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ const struct rtw89_chanctx_listener *listener = chip->chanctx_listener;
+ int i;
+
+ if (!listener)
+ return;
+
+ for (i = 0; i < NUM_OF_RTW89_CHANCTX_CALLBACKS; i++) {
+ if (!listener->callbacks[i])
+ continue;
+
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN,
+ "chanctx notify listener: cb %d, state %d\n",
+ i, state);
+
+ listener->callbacks[i](rtwdev, state);
+ }
+}
+
+static int rtw89_mcc_start(struct rtw89_dev *rtwdev)
+{
+ if (rtwdev->scanning)
+ rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif);
+
+ rtw89_leave_lps(rtwdev);
+
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC start\n");
+ rtw89_chanctx_notify(rtwdev, RTW89_CHANCTX_STATE_MCC_START);
+ return 0;
+}
+
+static void rtw89_mcc_stop(struct rtw89_dev *rtwdev)
+{
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC stop\n");
+ rtw89_chanctx_notify(rtwdev, RTW89_CHANCTX_STATE_MCC_STOP);
+}
+
+void rtw89_chanctx_work(struct work_struct *work)
+{
+ struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
+ chanctx_work.work);
+ enum rtw89_entity_mode mode;
+ int ret;
+
+ mutex_lock(&rtwdev->mutex);
+
+ mode = rtw89_get_entity_mode(rtwdev);
+ switch (mode) {
+ case RTW89_ENTITY_MODE_MCC_PREPARE:
+ rtw89_set_entity_mode(rtwdev, RTW89_ENTITY_MODE_MCC);
+ rtw89_set_channel(rtwdev);
+
+ ret = rtw89_mcc_start(rtwdev);
+ if (ret)
+ rtw89_warn(rtwdev, "failed to start MCC: %d\n", ret);
+ break;
+ default:
+ break;
+ }
+
+ mutex_unlock(&rtwdev->mutex);
+}
+
+void rtw89_queue_chanctx_work(struct rtw89_dev *rtwdev)
+{
+ enum rtw89_entity_mode mode;
+ u32 delay;
+
+ mode = rtw89_get_entity_mode(rtwdev);
+ switch (mode) {
+ default:
+ return;
+ case RTW89_ENTITY_MODE_MCC_PREPARE:
+ delay = ieee80211_tu_to_usec(RTW89_CHANCTX_TIME_MCC_PREPARE);
+ break;
+ }
+
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN,
+ "queue chanctx work for mode %d with delay %d us\n",
+ mode, delay);
+ ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->chanctx_work,
+ usecs_to_jiffies(delay));
+}
+
int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
struct ieee80211_chanctx_conf *ctx)
{
@@ -238,6 +352,7 @@ void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev,
{
struct rtw89_hal *hal = &rtwdev->hal;
struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
+ enum rtw89_entity_mode mode;
struct rtw89_vif *rtwvif;
u8 drop, roll;
@@ -267,6 +382,15 @@ void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev,
drop = roll;
out:
+ mode = rtw89_get_entity_mode(rtwdev);
+ switch (mode) {
+ case RTW89_ENTITY_MODE_MCC:
+ rtw89_mcc_stop(rtwdev);
+ break;
+ default:
+ break;
+ }
+
clear_bit(drop, hal->entity_map);
rtw89_set_channel(rtwdev);
}
diff --git a/drivers/net/wireless/realtek/rtw89/chan.h b/drivers/net/wireless/realtek/rtw89/chan.h
index bdf369db5041..448e6c5df9f1 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.h
+++ b/drivers/net/wireless/realtek/rtw89/chan.h
@@ -7,6 +7,9 @@
#include "core.h"
+/* The dwell time in TU before doing rtw89_chanctx_work(). */
+#define RTW89_CHANCTX_TIME_MCC_PREPARE 100
+
static inline bool rtw89_get_entity_state(struct rtw89_dev *rtwdev)
{
struct rtw89_hal *hal = &rtwdev->hal;
@@ -50,6 +53,8 @@ void rtw89_config_roc_chandef(struct rtw89_dev *rtwdev,
const struct cfg80211_chan_def *chandef);
void rtw89_entity_init(struct rtw89_dev *rtwdev);
enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev);
+void rtw89_chanctx_work(struct work_struct *work);
+void rtw89_queue_chanctx_work(struct rtw89_dev *rtwdev);
int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
struct ieee80211_chanctx_conf *ctx);
void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev,
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index bda0e1e99a8c..4ba8b3df70ae 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -5666,7 +5666,8 @@ enum btc_wl_mode {
void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta, enum btc_role_state state)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
+ rtwvif->sub_entity_idx);
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta);
struct rtw89_btc *btc = &rtwdev->btc;
diff --git a/drivers/net/wireless/realtek/rtw89/coex.h b/drivers/net/wireless/realtek/rtw89/coex.h
index f16421cb30ef..e76153709793 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.h
+++ b/drivers/net/wireless/realtek/rtw89/coex.h
@@ -193,4 +193,13 @@ static inline u8 rtw89_btc_path_phymap(struct rtw89_dev *rtwdev,
return rtw89_btc_phymap(rtwdev, phy_idx, BIT(path));
}
+/* return bt req len in TU */
+static inline u16 rtw89_coex_query_bt_req_len(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+
+ return btc->bt_req_len;
+}
+
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 69b181fa2966..133bf289bacb 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -256,8 +256,8 @@ void rtw89_get_default_chandef(struct cfg80211_chan_def *chandef)
NL80211_CHAN_NO_HT);
}
-static void rtw89_get_channel_params(const struct cfg80211_chan_def *chandef,
- struct rtw89_chan *chan)
+void rtw89_get_channel_params(const struct cfg80211_chan_def *chandef,
+ struct rtw89_chan *chan)
{
struct ieee80211_channel *channel = chandef->chan;
enum nl80211_chan_width width = chandef->width;
@@ -318,9 +318,11 @@ static void rtw89_get_channel_params(const struct cfg80211_chan_def *chandef,
void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev)
{
+ struct rtw89_hal *hal = &rtwdev->hal;
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_chan *chan;
enum rtw89_sub_entity_idx sub_entity_idx;
+ enum rtw89_sub_entity_idx roc_idx;
enum rtw89_phy_idx phy_idx;
enum rtw89_entity_mode mode;
bool entity_active;
@@ -330,10 +332,23 @@ void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev)
return;
mode = rtw89_get_entity_mode(rtwdev);
- if (WARN(mode != RTW89_ENTITY_MODE_SCC, "Invalid ent mode: %d\n", mode))
+ switch (mode) {
+ case RTW89_ENTITY_MODE_SCC:
+ case RTW89_ENTITY_MODE_MCC:
+ sub_entity_idx = RTW89_SUB_ENTITY_0;
+ break;
+ case RTW89_ENTITY_MODE_MCC_PREPARE:
+ sub_entity_idx = RTW89_SUB_ENTITY_1;
+ break;
+ default:
+ WARN(1, "Invalid ent mode: %d\n", mode);
return;
+ }
+
+ roc_idx = atomic_read(&hal->roc_entity_idx);
+ if (roc_idx != RTW89_SUB_ENTITY_IDLE)
+ sub_entity_idx = roc_idx;
- sub_entity_idx = RTW89_SUB_ENTITY_0;
phy_idx = RTW89_PHY_0;
chan = rtw89_chan_get(rtwdev, sub_entity_idx);
chip->ops->set_txpwr(rtwdev, chan, phy_idx);
@@ -341,43 +356,54 @@ void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev)
void rtw89_set_channel(struct rtw89_dev *rtwdev)
{
+ struct rtw89_hal *hal = &rtwdev->hal;
const struct rtw89_chip_info *chip = rtwdev->chip;
- const struct cfg80211_chan_def *chandef;
+ const struct rtw89_chan_rcd *chan_rcd;
+ const struct rtw89_chan *chan;
enum rtw89_sub_entity_idx sub_entity_idx;
+ enum rtw89_sub_entity_idx roc_idx;
enum rtw89_mac_idx mac_idx;
enum rtw89_phy_idx phy_idx;
- struct rtw89_chan chan;
struct rtw89_channel_help_params bak;
enum rtw89_entity_mode mode;
- bool band_changed;
bool entity_active;
entity_active = rtw89_get_entity_state(rtwdev);
mode = rtw89_entity_recalc(rtwdev);
- if (WARN(mode != RTW89_ENTITY_MODE_SCC, "Invalid ent mode: %d\n", mode))
+ switch (mode) {
+ case RTW89_ENTITY_MODE_SCC:
+ case RTW89_ENTITY_MODE_MCC:
+ sub_entity_idx = RTW89_SUB_ENTITY_0;
+ break;
+ case RTW89_ENTITY_MODE_MCC_PREPARE:
+ sub_entity_idx = RTW89_SUB_ENTITY_1;
+ break;
+ default:
+ WARN(1, "Invalid ent mode: %d\n", mode);
return;
+ }
+
+ roc_idx = atomic_read(&hal->roc_entity_idx);
+ if (roc_idx != RTW89_SUB_ENTITY_IDLE)
+ sub_entity_idx = roc_idx;
- sub_entity_idx = RTW89_SUB_ENTITY_0;
mac_idx = RTW89_MAC_0;
phy_idx = RTW89_PHY_0;
- chandef = rtw89_chandef_get(rtwdev, sub_entity_idx);
- rtw89_get_channel_params(chandef, &chan);
- if (WARN(chan.channel == 0, "Invalid channel\n"))
- return;
- band_changed = rtw89_assign_entity_chan(rtwdev, sub_entity_idx, &chan);
+ chan = rtw89_chan_get(rtwdev, sub_entity_idx);
+ chan_rcd = rtw89_chan_rcd_get(rtwdev, sub_entity_idx);
- rtw89_chip_set_channel_prepare(rtwdev, &bak, &chan, mac_idx, phy_idx);
+ rtw89_chip_set_channel_prepare(rtwdev, &bak, chan, mac_idx, phy_idx);
- chip->ops->set_channel(rtwdev, &chan, mac_idx, phy_idx);
+ chip->ops->set_channel(rtwdev, chan, mac_idx, phy_idx);
- chip->ops->set_txpwr(rtwdev, &chan, phy_idx);
+ chip->ops->set_txpwr(rtwdev, chan, phy_idx);
- rtw89_chip_set_channel_done(rtwdev, &bak, &chan, mac_idx, phy_idx);
+ rtw89_chip_set_channel_done(rtwdev, &bak, chan, mac_idx, phy_idx);
- if (!entity_active || band_changed) {
- rtw89_btc_ntfy_switch_band(rtwdev, phy_idx, chan.band_type);
+ if (!entity_active || chan_rcd->band_changed) {
+ rtw89_btc_ntfy_switch_band(rtwdev, phy_idx, chan->band_type);
rtw89_chip_rfk_band_changed(rtwdev, phy_idx);
}
@@ -523,12 +549,12 @@ rtw89_core_tx_update_sec_key(struct rtw89_dev *rtwdev,
}
static u16 rtw89_core_get_mgmt_rate(struct rtw89_dev *rtwdev,
- struct rtw89_core_tx_request *tx_req)
+ struct rtw89_core_tx_request *tx_req,
+ const struct rtw89_chan *chan)
{
struct sk_buff *skb = tx_req->skb;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_vif *vif = tx_info->control.vif;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u16 lowest_rate;
if (tx_info->flags & IEEE80211_TX_CTL_NO_CCK_RATE ||
@@ -567,7 +593,8 @@ rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif = tx_req->vif;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
+ rtwvif->sub_entity_idx);
u8 qsel, ch_dma;
qsel = desc_info->hiq ? RTW89_TX_QSEL_B0_HI : RTW89_TX_QSEL_B0_MGMT;
@@ -584,7 +611,7 @@ rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev,
desc_info->en_wd_info = true;
desc_info->use_rate = true;
desc_info->dis_data_fb = true;
- desc_info->data_rate = rtw89_core_get_mgmt_rate(rtwdev, tx_req);
+ desc_info->data_rate = rtw89_core_get_mgmt_rate(rtwdev, tx_req, chan);
rtw89_debug(rtwdev, RTW89_DBG_TXRX,
"tx mgmt frame with rate 0x%x on channel %d (band %d, bw %d)\n",
@@ -603,7 +630,8 @@ rtw89_core_tx_update_h2c_info(struct rtw89_dev *rtwdev,
desc_info->ch_dma = RTW89_DMA_H2C;
}
-static void rtw89_core_get_no_ul_ofdma_htc(struct rtw89_dev *rtwdev, __le32 *htc)
+static void rtw89_core_get_no_ul_ofdma_htc(struct rtw89_dev *rtwdev, __le32 *htc,
+ const struct rtw89_chan *chan)
{
static const u8 rtw89_bandwidth_to_om[] = {
[RTW89_CHANNEL_WIDTH_20] = HTC_OM_CHANNEL_WIDTH_20,
@@ -614,7 +642,6 @@ static void rtw89_core_get_no_ul_ofdma_htc(struct rtw89_dev *rtwdev, __le32 *htc
};
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_hal *hal = &rtwdev->hal;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 om_bandwidth;
if (!chip->dis_2g_40m_ul_ofdma ||
@@ -1456,16 +1483,16 @@ static bool rtw89_core_rx_ppdu_match(struct rtw89_dev *rtwdev,
bool ret;
data_rate = desc_info->data_rate;
- data_rate_mode = GET_DATA_RATE_MODE(data_rate);
+ data_rate_mode = rtw89_get_data_rate_mode(rtwdev, data_rate);
if (data_rate_mode == DATA_RATE_MODE_NON_HT) {
- rate_idx = GET_DATA_RATE_NOT_HT_IDX(data_rate);
+ rate_idx = rtw89_get_data_not_ht_idx(rtwdev, data_rate);
/* rate_idx is still hardware value here */
} else if (data_rate_mode == DATA_RATE_MODE_HT) {
- rate_idx = GET_DATA_RATE_HT_IDX(data_rate);
+ rate_idx = rtw89_get_data_ht_mcs(rtwdev, data_rate);
} else if (data_rate_mode == DATA_RATE_MODE_VHT) {
- rate_idx = GET_DATA_RATE_VHT_HE_IDX(data_rate);
+ rate_idx = rtw89_get_data_mcs(rtwdev, data_rate);
} else if (data_rate_mode == DATA_RATE_MODE_HE) {
- rate_idx = GET_DATA_RATE_VHT_HE_IDX(data_rate);
+ rate_idx = rtw89_get_data_mcs(rtwdev, data_rate);
} else {
rtw89_warn(rtwdev, "invalid RX rate mode %d\n", data_rate_mode);
}
@@ -1659,8 +1686,7 @@ static void rtw89_correct_cck_chan(struct rtw89_dev *rtwdev,
const struct rtw89_chan_rcd *rcd =
rtw89_chan_rcd_get(rtwdev, RTW89_SUB_ENTITY_0);
u16 chan = rcd->prev_primary_channel;
- u8 band = rcd->prev_band_type == RTW89_BAND_2G ?
- NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
+ u8 band = rtw89_hw_to_nl80211_band(rcd->prev_band_type);
if (status->band != NL80211_BAND_2GHZ &&
status->encoding == RX_ENC_LEGACY &&
@@ -1900,7 +1926,6 @@ static void rtw89_core_update_rx_status(struct rtw89_dev *rtwdev,
{
const struct cfg80211_chan_def *chandef =
rtw89_chandef_get(rtwdev, RTW89_SUB_ENTITY_0);
- const struct rtw89_chan *cur = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u16 data_rate;
u8 data_rate_mode;
@@ -1910,6 +1935,7 @@ static void rtw89_core_update_rx_status(struct rtw89_dev *rtwdev,
if (rtwdev->scanning &&
RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) {
+ const struct rtw89_chan *cur = rtw89_scan_chan_get(rtwdev);
u8 chan = cur->primary_channel;
u8 band = cur->band_type;
enum nl80211_band nl_band;
@@ -1929,26 +1955,26 @@ static void rtw89_core_update_rx_status(struct rtw89_dev *rtwdev,
rx_status->bw = rtw89_hw_to_rate_info_bw(desc_info->bw);
data_rate = desc_info->data_rate;
- data_rate_mode = GET_DATA_RATE_MODE(data_rate);
+ data_rate_mode = rtw89_get_data_rate_mode(rtwdev, data_rate);
if (data_rate_mode == DATA_RATE_MODE_NON_HT) {
rx_status->encoding = RX_ENC_LEGACY;
- rx_status->rate_idx = GET_DATA_RATE_NOT_HT_IDX(data_rate);
+ rx_status->rate_idx = rtw89_get_data_not_ht_idx(rtwdev, data_rate);
/* convert rate_idx after we get the correct band */
} else if (data_rate_mode == DATA_RATE_MODE_HT) {
rx_status->encoding = RX_ENC_HT;
- rx_status->rate_idx = GET_DATA_RATE_HT_IDX(data_rate);
+ rx_status->rate_idx = rtw89_get_data_ht_mcs(rtwdev, data_rate);
if (desc_info->gi_ltf)
rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
} else if (data_rate_mode == DATA_RATE_MODE_VHT) {
rx_status->encoding = RX_ENC_VHT;
- rx_status->rate_idx = GET_DATA_RATE_VHT_HE_IDX(data_rate);
- rx_status->nss = GET_DATA_RATE_NSS(data_rate) + 1;
+ rx_status->rate_idx = rtw89_get_data_mcs(rtwdev, data_rate);
+ rx_status->nss = rtw89_get_data_nss(rtwdev, data_rate) + 1;
if (desc_info->gi_ltf)
rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
} else if (data_rate_mode == DATA_RATE_MODE_HE) {
rx_status->encoding = RX_ENC_HE;
- rx_status->rate_idx = GET_DATA_RATE_VHT_HE_IDX(data_rate);
- rx_status->nss = GET_DATA_RATE_NSS(data_rate) + 1;
+ rx_status->rate_idx = rtw89_get_data_mcs(rtwdev, data_rate);
+ rx_status->nss = rtw89_get_data_nss(rtwdev, data_rate) + 1;
} else {
rtw89_warn(rtwdev, "invalid RX rate mode %d\n", data_rate_mode);
}
@@ -2451,6 +2477,7 @@ out:
void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
struct ieee80211_hw *hw = rtwdev->hw;
struct rtw89_roc *roc = &rtwvif->roc;
struct cfg80211_chan_def roc_chan;
@@ -2478,7 +2505,7 @@ void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
rtw89_config_roc_chandef(rtwdev, rtwvif->sub_entity_idx, &roc_chan);
rtw89_set_channel(rtwdev);
rtw89_write32_clr(rtwdev,
- rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0),
+ rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0),
B_AX_A_UC_CAM_MATCH | B_AX_A_BC_CAM_MATCH);
ieee80211_ready_on_channel(hw);
@@ -2486,6 +2513,7 @@ void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
struct ieee80211_hw *hw = rtwdev->hw;
struct rtw89_roc *roc = &rtwvif->roc;
struct rtw89_vif *tmp;
@@ -2499,7 +2527,7 @@ void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
rtw89_leave_lps(rtwdev);
rtw89_write32_mask(rtwdev,
- rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0),
+ rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0),
B_AX_RX_FLTR_CFG_MASK,
rtwdev->hal.rx_fltr);
@@ -2682,6 +2710,7 @@ static void rtw89_track_work(struct work_struct *work)
rtw89_phy_tx_path_div_track(rtwdev);
rtw89_phy_antdiv_track(rtwdev);
rtw89_phy_ul_tb_ctrl_track(rtwdev);
+ rtw89_tas_track(rtwdev);
if (rtwdev->lps_enabled && !rtwdev->btc.lps)
rtw89_enter_lps_track(rtwdev);
@@ -2970,6 +2999,8 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif, rtwsta);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
+ rtwvif->sub_entity_idx);
int ret;
if (vif->type == NL80211_IFTYPE_AP || sta->tdls) {
@@ -3023,7 +3054,7 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev,
rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta,
BTC_ROLE_MSTS_STA_CONN_END);
- rtw89_core_get_no_ul_ofdma_htc(rtwdev, &rtwsta->htc_template);
+ rtw89_core_get_no_ul_ofdma_htc(rtwdev, &rtwsta->htc_template, chan);
rtw89_phy_ul_tb_assoc(rtwdev, rtwvif);
ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif, rtwsta->mac_id);
@@ -3463,6 +3494,27 @@ void rtw89_complete_cond(struct rtw89_wait_info *wait, unsigned int cond,
complete(&wait->completion);
}
+void rtw89_core_ntfy_btc_event(struct rtw89_dev *rtwdev, enum rtw89_btc_hmsg event)
+{
+ u16 bt_req_len;
+
+ switch (event) {
+ case RTW89_BTC_HMSG_SET_BT_REQ_SLOT:
+ bt_req_len = rtw89_coex_query_bt_req_len(rtwdev, RTW89_PHY_0);
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "coex updates BT req len to %d TU\n", bt_req_len);
+ break;
+ default:
+ if (event < NUM_OF_RTW89_BTC_HMSG)
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "unhandled BTC HMSG event: %d\n", event);
+ else
+ rtw89_warn(rtwdev,
+ "unrecognized BTC HMSG event: %d\n", event);
+ break;
+ }
+}
+
int rtw89_core_start(struct rtw89_dev *rtwdev)
{
int ret;
@@ -3496,6 +3548,8 @@ int rtw89_core_start(struct rtw89_dev *rtwdev)
rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true);
rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_0);
+ rtw89_tas_reset(rtwdev);
+
ret = rtw89_hci_start(rtwdev);
if (ret) {
rtw89_err(rtwdev, "failed to start hci\n");
@@ -3508,7 +3562,7 @@ int rtw89_core_start(struct rtw89_dev *rtwdev)
set_bit(RTW89_FLAG_RUNNING, rtwdev->flags);
rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_WL_ON);
- rtw89_fw_h2c_fw_log(rtwdev, rtwdev->fw.fw_log_enable);
+ rtw89_fw_h2c_fw_log(rtwdev, rtwdev->fw.log.enable);
rtw89_fw_h2c_init_ba_cam(rtwdev);
return 0;
@@ -3536,6 +3590,7 @@ void rtw89_core_stop(struct rtw89_dev *rtwdev)
cancel_work_sync(&btc->icmp_notify_work);
cancel_delayed_work_sync(&rtwdev->txq_reinvoke_work);
cancel_delayed_work_sync(&rtwdev->track_work);
+ cancel_delayed_work_sync(&rtwdev->chanctx_work);
cancel_delayed_work_sync(&rtwdev->coex_act1_work);
cancel_delayed_work_sync(&rtwdev->coex_bt_devinfo_work);
cancel_delayed_work_sync(&rtwdev->coex_rfk_chk_work);
@@ -3572,6 +3627,7 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
INIT_WORK(&rtwdev->txq_work, rtw89_core_txq_work);
INIT_DELAYED_WORK(&rtwdev->txq_reinvoke_work, rtw89_core_txq_reinvoke_work);
INIT_DELAYED_WORK(&rtwdev->track_work, rtw89_track_work);
+ INIT_DELAYED_WORK(&rtwdev->chanctx_work, rtw89_chanctx_work);
INIT_DELAYED_WORK(&rtwdev->coex_act1_work, rtw89_coex_act1_work);
INIT_DELAYED_WORK(&rtwdev->coex_bt_devinfo_work, rtw89_coex_bt_devinfo_work);
INIT_DELAYED_WORK(&rtwdev->coex_rfk_chk_work, rtw89_coex_rfk_chk_work);
@@ -3612,6 +3668,7 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
rtw89_ser_init(rtwdev);
rtw89_entity_init(rtwdev);
+ rtw89_tas_init(rtwdev);
return 0;
}
@@ -3632,7 +3689,8 @@ EXPORT_SYMBOL(rtw89_core_deinit);
void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
const u8 *mac_addr, bool hw_scan)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
+ rtwvif->sub_entity_idx);
rtwdev->scanning = true;
rtw89_leave_lps(rtwdev);
@@ -3779,6 +3837,12 @@ int rtw89_chip_info_setup(struct rtw89_dev *rtwdev)
return ret;
}
+ ret = rtw89_fw_recognize_elements(rtwdev);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to recognize firmware elements\n");
+ return ret;
+ }
+
ret = rtw89_chip_efuse_info_setup(rtwdev);
if (ret)
return ret;
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index d2c67db97db1..04ce221730f9 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -14,6 +14,8 @@
struct rtw89_dev;
struct rtw89_pci_info;
+struct rtw89_mac_gen_def;
+struct rtw89_phy_gen_def;
extern const struct ieee80211_ops rtw89_ops;
@@ -109,6 +111,14 @@ enum rtw89_core_chip_id {
RTL8852B,
RTL8852C,
RTL8851B,
+ RTL8922A,
+};
+
+enum rtw89_chip_gen {
+ RTW89_CHIP_AX,
+ RTW89_CHIP_BE,
+
+ RTW89_CHIP_GEN_NUM,
};
enum rtw89_cv {
@@ -387,10 +397,201 @@ enum rtw89_hw_rate {
RTW89_HW_RATE_HE_NSS4_MCS9 = 0x1B9,
RTW89_HW_RATE_HE_NSS4_MCS10 = 0x1BA,
RTW89_HW_RATE_HE_NSS4_MCS11 = 0x1BB,
+
+ RTW89_HW_RATE_V1_MCS0 = 0x100,
+ RTW89_HW_RATE_V1_MCS1 = 0x101,
+ RTW89_HW_RATE_V1_MCS2 = 0x102,
+ RTW89_HW_RATE_V1_MCS3 = 0x103,
+ RTW89_HW_RATE_V1_MCS4 = 0x104,
+ RTW89_HW_RATE_V1_MCS5 = 0x105,
+ RTW89_HW_RATE_V1_MCS6 = 0x106,
+ RTW89_HW_RATE_V1_MCS7 = 0x107,
+ RTW89_HW_RATE_V1_MCS8 = 0x108,
+ RTW89_HW_RATE_V1_MCS9 = 0x109,
+ RTW89_HW_RATE_V1_MCS10 = 0x10A,
+ RTW89_HW_RATE_V1_MCS11 = 0x10B,
+ RTW89_HW_RATE_V1_MCS12 = 0x10C,
+ RTW89_HW_RATE_V1_MCS13 = 0x10D,
+ RTW89_HW_RATE_V1_MCS14 = 0x10E,
+ RTW89_HW_RATE_V1_MCS15 = 0x10F,
+ RTW89_HW_RATE_V1_MCS16 = 0x110,
+ RTW89_HW_RATE_V1_MCS17 = 0x111,
+ RTW89_HW_RATE_V1_MCS18 = 0x112,
+ RTW89_HW_RATE_V1_MCS19 = 0x113,
+ RTW89_HW_RATE_V1_MCS20 = 0x114,
+ RTW89_HW_RATE_V1_MCS21 = 0x115,
+ RTW89_HW_RATE_V1_MCS22 = 0x116,
+ RTW89_HW_RATE_V1_MCS23 = 0x117,
+ RTW89_HW_RATE_V1_MCS24 = 0x118,
+ RTW89_HW_RATE_V1_MCS25 = 0x119,
+ RTW89_HW_RATE_V1_MCS26 = 0x11A,
+ RTW89_HW_RATE_V1_MCS27 = 0x11B,
+ RTW89_HW_RATE_V1_MCS28 = 0x11C,
+ RTW89_HW_RATE_V1_MCS29 = 0x11D,
+ RTW89_HW_RATE_V1_MCS30 = 0x11E,
+ RTW89_HW_RATE_V1_MCS31 = 0x11F,
+ RTW89_HW_RATE_V1_VHT_NSS1_MCS0 = 0x200,
+ RTW89_HW_RATE_V1_VHT_NSS1_MCS1 = 0x201,
+ RTW89_HW_RATE_V1_VHT_NSS1_MCS2 = 0x202,
+ RTW89_HW_RATE_V1_VHT_NSS1_MCS3 = 0x203,
+ RTW89_HW_RATE_V1_VHT_NSS1_MCS4 = 0x204,
+ RTW89_HW_RATE_V1_VHT_NSS1_MCS5 = 0x205,
+ RTW89_HW_RATE_V1_VHT_NSS1_MCS6 = 0x206,
+ RTW89_HW_RATE_V1_VHT_NSS1_MCS7 = 0x207,
+ RTW89_HW_RATE_V1_VHT_NSS1_MCS8 = 0x208,
+ RTW89_HW_RATE_V1_VHT_NSS1_MCS9 = 0x209,
+ RTW89_HW_RATE_V1_VHT_NSS1_MCS10 = 0x20A,
+ RTW89_HW_RATE_V1_VHT_NSS1_MCS11 = 0x20B,
+ RTW89_HW_RATE_V1_VHT_NSS2_MCS0 = 0x220,
+ RTW89_HW_RATE_V1_VHT_NSS2_MCS1 = 0x221,
+ RTW89_HW_RATE_V1_VHT_NSS2_MCS2 = 0x222,
+ RTW89_HW_RATE_V1_VHT_NSS2_MCS3 = 0x223,
+ RTW89_HW_RATE_V1_VHT_NSS2_MCS4 = 0x224,
+ RTW89_HW_RATE_V1_VHT_NSS2_MCS5 = 0x225,
+ RTW89_HW_RATE_V1_VHT_NSS2_MCS6 = 0x226,
+ RTW89_HW_RATE_V1_VHT_NSS2_MCS7 = 0x227,
+ RTW89_HW_RATE_V1_VHT_NSS2_MCS8 = 0x228,
+ RTW89_HW_RATE_V1_VHT_NSS2_MCS9 = 0x229,
+ RTW89_HW_RATE_V1_VHT_NSS2_MCS10 = 0x22A,
+ RTW89_HW_RATE_V1_VHT_NSS2_MCS11 = 0x22B,
+ RTW89_HW_RATE_V1_VHT_NSS3_MCS0 = 0x240,
+ RTW89_HW_RATE_V1_VHT_NSS3_MCS1 = 0x241,
+ RTW89_HW_RATE_V1_VHT_NSS3_MCS2 = 0x242,
+ RTW89_HW_RATE_V1_VHT_NSS3_MCS3 = 0x243,
+ RTW89_HW_RATE_V1_VHT_NSS3_MCS4 = 0x244,
+ RTW89_HW_RATE_V1_VHT_NSS3_MCS5 = 0x245,
+ RTW89_HW_RATE_V1_VHT_NSS3_MCS6 = 0x246,
+ RTW89_HW_RATE_V1_VHT_NSS3_MCS7 = 0x247,
+ RTW89_HW_RATE_V1_VHT_NSS3_MCS8 = 0x248,
+ RTW89_HW_RATE_V1_VHT_NSS3_MCS9 = 0x249,
+ RTW89_HW_RATE_V1_VHT_NSS3_MCS10 = 0x24A,
+ RTW89_HW_RATE_V1_VHT_NSS3_MCS11 = 0x24B,
+ RTW89_HW_RATE_V1_VHT_NSS4_MCS0 = 0x260,
+ RTW89_HW_RATE_V1_VHT_NSS4_MCS1 = 0x261,
+ RTW89_HW_RATE_V1_VHT_NSS4_MCS2 = 0x262,
+ RTW89_HW_RATE_V1_VHT_NSS4_MCS3 = 0x263,
+ RTW89_HW_RATE_V1_VHT_NSS4_MCS4 = 0x264,
+ RTW89_HW_RATE_V1_VHT_NSS4_MCS5 = 0x265,
+ RTW89_HW_RATE_V1_VHT_NSS4_MCS6 = 0x266,
+ RTW89_HW_RATE_V1_VHT_NSS4_MCS7 = 0x267,
+ RTW89_HW_RATE_V1_VHT_NSS4_MCS8 = 0x268,
+ RTW89_HW_RATE_V1_VHT_NSS4_MCS9 = 0x269,
+ RTW89_HW_RATE_V1_VHT_NSS4_MCS10 = 0x26A,
+ RTW89_HW_RATE_V1_VHT_NSS4_MCS11 = 0x26B,
+ RTW89_HW_RATE_V1_HE_NSS1_MCS0 = 0x300,
+ RTW89_HW_RATE_V1_HE_NSS1_MCS1 = 0x301,
+ RTW89_HW_RATE_V1_HE_NSS1_MCS2 = 0x302,
+ RTW89_HW_RATE_V1_HE_NSS1_MCS3 = 0x303,
+ RTW89_HW_RATE_V1_HE_NSS1_MCS4 = 0x304,
+ RTW89_HW_RATE_V1_HE_NSS1_MCS5 = 0x305,
+ RTW89_HW_RATE_V1_HE_NSS1_MCS6 = 0x306,
+ RTW89_HW_RATE_V1_HE_NSS1_MCS7 = 0x307,
+ RTW89_HW_RATE_V1_HE_NSS1_MCS8 = 0x308,
+ RTW89_HW_RATE_V1_HE_NSS1_MCS9 = 0x309,
+ RTW89_HW_RATE_V1_HE_NSS1_MCS10 = 0x30A,
+ RTW89_HW_RATE_V1_HE_NSS1_MCS11 = 0x30B,
+ RTW89_HW_RATE_V1_HE_NSS2_MCS0 = 0x320,
+ RTW89_HW_RATE_V1_HE_NSS2_MCS1 = 0x321,
+ RTW89_HW_RATE_V1_HE_NSS2_MCS2 = 0x322,
+ RTW89_HW_RATE_V1_HE_NSS2_MCS3 = 0x323,
+ RTW89_HW_RATE_V1_HE_NSS2_MCS4 = 0x324,
+ RTW89_HW_RATE_V1_HE_NSS2_MCS5 = 0x325,
+ RTW89_HW_RATE_V1_HE_NSS2_MCS6 = 0x326,
+ RTW89_HW_RATE_V1_HE_NSS2_MCS7 = 0x327,
+ RTW89_HW_RATE_V1_HE_NSS2_MCS8 = 0x328,
+ RTW89_HW_RATE_V1_HE_NSS2_MCS9 = 0x329,
+ RTW89_HW_RATE_V1_HE_NSS2_MCS10 = 0x32A,
+ RTW89_HW_RATE_V1_HE_NSS2_MCS11 = 0x32B,
+ RTW89_HW_RATE_V1_HE_NSS3_MCS0 = 0x340,
+ RTW89_HW_RATE_V1_HE_NSS3_MCS1 = 0x341,
+ RTW89_HW_RATE_V1_HE_NSS3_MCS2 = 0x342,
+ RTW89_HW_RATE_V1_HE_NSS3_MCS3 = 0x343,
+ RTW89_HW_RATE_V1_HE_NSS3_MCS4 = 0x344,
+ RTW89_HW_RATE_V1_HE_NSS3_MCS5 = 0x345,
+ RTW89_HW_RATE_V1_HE_NSS3_MCS6 = 0x346,
+ RTW89_HW_RATE_V1_HE_NSS3_MCS7 = 0x347,
+ RTW89_HW_RATE_V1_HE_NSS3_MCS8 = 0x348,
+ RTW89_HW_RATE_V1_HE_NSS3_MCS9 = 0x349,
+ RTW89_HW_RATE_V1_HE_NSS3_MCS10 = 0x34A,
+ RTW89_HW_RATE_V1_HE_NSS3_MCS11 = 0x34B,
+ RTW89_HW_RATE_V1_HE_NSS4_MCS0 = 0x360,
+ RTW89_HW_RATE_V1_HE_NSS4_MCS1 = 0x361,
+ RTW89_HW_RATE_V1_HE_NSS4_MCS2 = 0x362,
+ RTW89_HW_RATE_V1_HE_NSS4_MCS3 = 0x363,
+ RTW89_HW_RATE_V1_HE_NSS4_MCS4 = 0x364,
+ RTW89_HW_RATE_V1_HE_NSS4_MCS5 = 0x365,
+ RTW89_HW_RATE_V1_HE_NSS4_MCS6 = 0x366,
+ RTW89_HW_RATE_V1_HE_NSS4_MCS7 = 0x367,
+ RTW89_HW_RATE_V1_HE_NSS4_MCS8 = 0x368,
+ RTW89_HW_RATE_V1_HE_NSS4_MCS9 = 0x369,
+ RTW89_HW_RATE_V1_HE_NSS4_MCS10 = 0x36A,
+ RTW89_HW_RATE_V1_HE_NSS4_MCS11 = 0x36B,
+ RTW89_HW_RATE_V1_EHT_NSS1_MCS0 = 0x400,
+ RTW89_HW_RATE_V1_EHT_NSS1_MCS1 = 0x401,
+ RTW89_HW_RATE_V1_EHT_NSS1_MCS2 = 0x402,
+ RTW89_HW_RATE_V1_EHT_NSS1_MCS3 = 0x403,
+ RTW89_HW_RATE_V1_EHT_NSS1_MCS4 = 0x404,
+ RTW89_HW_RATE_V1_EHT_NSS1_MCS5 = 0x405,
+ RTW89_HW_RATE_V1_EHT_NSS1_MCS6 = 0x406,
+ RTW89_HW_RATE_V1_EHT_NSS1_MCS7 = 0x407,
+ RTW89_HW_RATE_V1_EHT_NSS1_MCS8 = 0x408,
+ RTW89_HW_RATE_V1_EHT_NSS1_MCS9 = 0x409,
+ RTW89_HW_RATE_V1_EHT_NSS1_MCS10 = 0x40A,
+ RTW89_HW_RATE_V1_EHT_NSS1_MCS11 = 0x40B,
+ RTW89_HW_RATE_V1_EHT_NSS1_MCS12 = 0x40C,
+ RTW89_HW_RATE_V1_EHT_NSS1_MCS13 = 0x40D,
+ RTW89_HW_RATE_V1_EHT_NSS1_MCS14 = 0x40E,
+ RTW89_HW_RATE_V1_EHT_NSS1_MCS15 = 0x40F,
+ RTW89_HW_RATE_V1_EHT_NSS2_MCS0 = 0x420,
+ RTW89_HW_RATE_V1_EHT_NSS2_MCS1 = 0x421,
+ RTW89_HW_RATE_V1_EHT_NSS2_MCS2 = 0x422,
+ RTW89_HW_RATE_V1_EHT_NSS2_MCS3 = 0x423,
+ RTW89_HW_RATE_V1_EHT_NSS2_MCS4 = 0x424,
+ RTW89_HW_RATE_V1_EHT_NSS2_MCS5 = 0x425,
+ RTW89_HW_RATE_V1_EHT_NSS2_MCS6 = 0x426,
+ RTW89_HW_RATE_V1_EHT_NSS2_MCS7 = 0x427,
+ RTW89_HW_RATE_V1_EHT_NSS2_MCS8 = 0x428,
+ RTW89_HW_RATE_V1_EHT_NSS2_MCS9 = 0x429,
+ RTW89_HW_RATE_V1_EHT_NSS2_MCS10 = 0x42A,
+ RTW89_HW_RATE_V1_EHT_NSS2_MCS11 = 0x42B,
+ RTW89_HW_RATE_V1_EHT_NSS2_MCS12 = 0x42C,
+ RTW89_HW_RATE_V1_EHT_NSS2_MCS13 = 0x42D,
+ RTW89_HW_RATE_V1_EHT_NSS3_MCS0 = 0x440,
+ RTW89_HW_RATE_V1_EHT_NSS3_MCS1 = 0x441,
+ RTW89_HW_RATE_V1_EHT_NSS3_MCS2 = 0x442,
+ RTW89_HW_RATE_V1_EHT_NSS3_MCS3 = 0x443,
+ RTW89_HW_RATE_V1_EHT_NSS3_MCS4 = 0x444,
+ RTW89_HW_RATE_V1_EHT_NSS3_MCS5 = 0x445,
+ RTW89_HW_RATE_V1_EHT_NSS3_MCS6 = 0x446,
+ RTW89_HW_RATE_V1_EHT_NSS3_MCS7 = 0x447,
+ RTW89_HW_RATE_V1_EHT_NSS3_MCS8 = 0x448,
+ RTW89_HW_RATE_V1_EHT_NSS3_MCS9 = 0x449,
+ RTW89_HW_RATE_V1_EHT_NSS3_MCS10 = 0x44A,
+ RTW89_HW_RATE_V1_EHT_NSS3_MCS11 = 0x44B,
+ RTW89_HW_RATE_V1_EHT_NSS3_MCS12 = 0x44C,
+ RTW89_HW_RATE_V1_EHT_NSS3_MCS13 = 0x44D,
+ RTW89_HW_RATE_V1_EHT_NSS4_MCS0 = 0x460,
+ RTW89_HW_RATE_V1_EHT_NSS4_MCS1 = 0x461,
+ RTW89_HW_RATE_V1_EHT_NSS4_MCS2 = 0x462,
+ RTW89_HW_RATE_V1_EHT_NSS4_MCS3 = 0x463,
+ RTW89_HW_RATE_V1_EHT_NSS4_MCS4 = 0x464,
+ RTW89_HW_RATE_V1_EHT_NSS4_MCS5 = 0x465,
+ RTW89_HW_RATE_V1_EHT_NSS4_MCS6 = 0x466,
+ RTW89_HW_RATE_V1_EHT_NSS4_MCS7 = 0x467,
+ RTW89_HW_RATE_V1_EHT_NSS4_MCS8 = 0x468,
+ RTW89_HW_RATE_V1_EHT_NSS4_MCS9 = 0x469,
+ RTW89_HW_RATE_V1_EHT_NSS4_MCS10 = 0x46A,
+ RTW89_HW_RATE_V1_EHT_NSS4_MCS11 = 0x46B,
+ RTW89_HW_RATE_V1_EHT_NSS4_MCS12 = 0x46C,
+ RTW89_HW_RATE_V1_EHT_NSS4_MCS13 = 0x46D,
+
RTW89_HW_RATE_NR,
+ RTW89_HW_RATE_INVAL,
RTW89_HW_RATE_MASK_MOD = GENMASK(8, 7),
RTW89_HW_RATE_MASK_VAL = GENMASK(6, 0),
+ RTW89_HW_RATE_V1_MASK_MOD = GENMASK(10, 8),
+ RTW89_HW_RATE_V1_MASK_VAL = GENMASK(7, 0),
};
/* 2G channels,
@@ -590,6 +791,7 @@ enum rtw89_phy_idx {
enum rtw89_sub_entity_idx {
RTW89_SUB_ENTITY_0 = 0,
+ RTW89_SUB_ENTITY_1 = 1,
NUM_OF_RTW89_SUB_ENTITY,
RTW89_SUB_ENTITY_IDLE = NUM_OF_RTW89_SUB_ENTITY,
@@ -701,6 +903,7 @@ struct rtw89_chan {
struct rtw89_chan_rcd {
u8 prev_primary_channel;
enum rtw89_band prev_band_type;
+ bool band_changed;
};
struct rtw89_channel_help_params {
@@ -2457,6 +2660,17 @@ struct rtw89_btc {
bool lps;
};
+enum rtw89_btc_hmsg {
+ RTW89_BTC_HMSG_TMR_EN = 0x0,
+ RTW89_BTC_HMSG_BT_REG_READBACK = 0x1,
+ RTW89_BTC_HMSG_SET_BT_REQ_SLOT = 0x2,
+ RTW89_BTC_HMSG_FW_EV = 0x3,
+ RTW89_BTC_HMSG_BT_LINK_CHG = 0x4,
+ RTW89_BTC_HMSG_SET_BT_REQ_STBC = 0x5,
+
+ NUM_OF_RTW89_BTC_HMSG,
+};
+
enum rtw89_ra_mode {
RTW89_RA_MODE_CCK = BIT(0),
RTW89_RA_MODE_OFDM = BIT(1),
@@ -2504,9 +2718,10 @@ struct rtw89_ra_info {
* Bit2 : HT
* Bit3 : VHT
* Bit4 : HE
+ * Bit5 : EHT
*/
- u8 mode_ctrl:5;
- u8 bw_cap:2;
+ u8 mode_ctrl:6;
+ u8 bw_cap:3; /* enum rtw89_bandwidth */
u8 macid;
u8 dcm_cap:1;
u8 er_cap:1;
@@ -2685,6 +2900,32 @@ struct rtw89_roc {
#define RTW89_P2P_MAX_NOA_NUM 2
+struct rtw89_p2p_ie_head {
+ u8 eid;
+ u8 ie_len;
+ u8 oui[3];
+ u8 oui_type;
+} __packed;
+
+struct rtw89_noa_attr_head {
+ u8 attr_type;
+ __le16 attr_len;
+ u8 index;
+ u8 oppps_ctwindow;
+} __packed;
+
+struct rtw89_p2p_noa_ie {
+ struct rtw89_p2p_ie_head p2p_head;
+ struct rtw89_noa_attr_head noa_head;
+ struct ieee80211_p2p_noa_desc noa_desc[RTW89_P2P_MAX_NOA_NUM];
+} __packed;
+
+struct rtw89_p2p_noa_setter {
+ struct rtw89_p2p_noa_ie ie;
+ u8 noa_count;
+ u8 noa_index;
+};
+
struct rtw89_vif {
struct list_head list;
struct rtw89_dev *rtwdev;
@@ -2727,6 +2968,7 @@ struct rtw89_vif {
struct cfg80211_scan_request *scan_req;
struct ieee80211_scan_ies *scan_ies;
struct list_head general_pkt_list;
+ struct rtw89_p2p_noa_setter p2p_noa;
};
enum rtw89_lv1_rcvy_step {
@@ -3139,6 +3381,10 @@ struct rtw89_dig_regs {
u32 seg0_pd_reg;
u32 pd_lower_bound_mask;
u32 pd_spatial_reuse_en;
+ u32 bmode_pd_reg;
+ u32 bmode_cca_rssi_limit_en;
+ u32 bmode_pd_lower_bound_reg;
+ u32 bmode_rssi_nocca_low_th_mask;
struct rtw89_reg_def p0_lna_init;
struct rtw89_reg_def p1_lna_init;
struct rtw89_reg_def p0_tia_init;
@@ -3175,12 +3421,32 @@ struct rtw89_antdiv_info {
bool get_stats;
};
+enum rtw89_chanctx_state {
+ RTW89_CHANCTX_STATE_MCC_START,
+ RTW89_CHANCTX_STATE_MCC_STOP,
+};
+
+enum rtw89_chanctx_callbacks {
+ RTW89_CHANCTX_CALLBACK_PLACEHOLDER,
+
+ NUM_OF_RTW89_CHANCTX_CALLBACKS,
+};
+
+struct rtw89_chanctx_listener {
+ void (*callbacks[NUM_OF_RTW89_CHANCTX_CALLBACKS])
+ (struct rtw89_dev *rtwdev, enum rtw89_chanctx_state state);
+};
+
struct rtw89_chip_info {
enum rtw89_core_chip_id chip_id;
+ enum rtw89_chip_gen chip_gen;
const struct rtw89_chip_ops *ops;
+ const struct rtw89_mac_gen_def *mac_def;
+ const struct rtw89_phy_gen_def *phy_def;
const char *fw_basename;
u8 fw_format_max;
bool try_ce_fw;
+ u32 needed_fw_elms;
u32 fifo_size;
bool small_fifo_size;
u32 dle_scc_rsvd_size;
@@ -3232,6 +3498,7 @@ struct rtw89_chip_info {
/* NULL if no rfe-specific, or a null-terminated array by rfe_parms */
const struct rtw89_rfe_parms_conf *rfe_parms_conf;
const struct rtw89_rfe_parms *dflt_parms;
+ const struct rtw89_chanctx_listener *chanctx_listener;
u8 txpwr_factor_rf;
u8 txpwr_factor_mac;
@@ -3347,6 +3614,9 @@ enum rtw89_fw_type {
RTW89_FW_NORMAL = 1,
RTW89_FW_WOWLAN = 3,
RTW89_FW_NORMAL_CE = 5,
+ RTW89_FW_BBMCU0 = 64,
+ RTW89_FW_BBMCU1 = 65,
+ RTW89_FW_LOGFMT = 255,
};
enum rtw89_fw_feature {
@@ -3361,6 +3631,7 @@ enum rtw89_fw_feature {
};
struct rtw89_fw_suit {
+ enum rtw89_fw_type type;
const u8 *data;
u32 size;
u8 major_ver;
@@ -3373,6 +3644,8 @@ struct rtw89_fw_suit {
u16 build_hour;
u16 build_min;
u8 cmd_ver;
+ u8 hdr_ver;
+ u32 commitid;
};
#define RTW89_FW_VER_CODE(major, minor, sub, idx) \
@@ -3397,6 +3670,22 @@ struct rtw89_fw_req_info {
struct completion completion;
};
+struct rtw89_fw_log {
+ struct rtw89_fw_suit suit;
+ bool enable;
+ u32 last_fmt_id;
+ u32 fmt_count;
+ const __le32 *fmt_ids;
+ const char *(*fmts)[];
+};
+
+struct rtw89_fw_elm_info {
+ struct rtw89_phy_table *bb_tbl;
+ struct rtw89_phy_table *bb_gain;
+ struct rtw89_phy_table *rf_radio[RF_PATH_MAX];
+ struct rtw89_phy_table *rf_nctl;
+};
+
struct rtw89_fw_info {
struct rtw89_fw_req_info req;
int fw_format;
@@ -3406,8 +3695,11 @@ struct rtw89_fw_info {
u8 c2h_counter;
struct rtw89_fw_suit normal;
struct rtw89_fw_suit wowlan;
- bool fw_log_enable;
+ struct rtw89_fw_suit bbmcu0;
+ struct rtw89_fw_suit bbmcu1;
+ struct rtw89_fw_log log;
u32 feature_map;
+ struct rtw89_fw_elm_info elm_info;
};
#define RTW89_CHK_FW_FEATURE(_feat, _fw) \
@@ -3463,12 +3755,34 @@ struct rtw89_sar_info {
};
};
+enum rtw89_tas_state {
+ RTW89_TAS_STATE_DPR_OFF,
+ RTW89_TAS_STATE_DPR_ON,
+ RTW89_TAS_STATE_DPR_FORBID,
+};
+
+#define RTW89_TAS_MAX_WINDOW 50
+struct rtw89_tas_info {
+ s16 txpwr_history[RTW89_TAS_MAX_WINDOW];
+ s32 total_txpwr;
+ u8 cur_idx;
+ s8 dpr_gap;
+ s8 delta;
+ enum rtw89_tas_state state;
+ bool enable;
+};
+
struct rtw89_chanctx_cfg {
enum rtw89_sub_entity_idx idx;
};
enum rtw89_entity_mode {
RTW89_ENTITY_MODE_SCC,
+ RTW89_ENTITY_MODE_MCC_PREPARE,
+ RTW89_ENTITY_MODE_MCC,
+
+ NUM_OF_RTW89_ENTITY_MODE,
+ RTW89_ENTITY_MODE_INVALID = NUM_OF_RTW89_ENTITY_MODE,
};
struct rtw89_sub_entity {
@@ -4125,6 +4439,7 @@ struct rtw89_dev {
struct rtw89_antdiv_info antdiv;
struct delayed_work track_work;
+ struct delayed_work chanctx_work;
struct delayed_work coex_act1_work;
struct delayed_work coex_bt_devinfo_work;
struct delayed_work coex_rfk_chk_work;
@@ -4138,6 +4453,7 @@ struct rtw89_dev {
struct rtw89_regulatory_info regulatory;
struct rtw89_sar_info sar;
+ struct rtw89_tas_info tas;
struct rtw89_btc btc;
enum rtw89_ps_mode ps_mode;
@@ -4673,6 +4989,18 @@ const struct rtw89_chan_rcd *rtw89_chan_rcd_get(struct rtw89_dev *rtwdev,
return &hal->sub[idx].rcd;
}
+static inline
+const struct rtw89_chan *rtw89_scan_chan_get(struct rtw89_dev *rtwdev)
+{
+ struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif;
+ struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
+
+ if (rtwvif)
+ return rtw89_chan_get(rtwdev, rtwvif->sub_entity_idx);
+ else
+ return rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+}
+
static inline void rtw89_chip_fem_setup(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
@@ -4940,8 +5268,19 @@ static inline struct rtw89_fw_suit *rtw89_fw_suit_get(struct rtw89_dev *rtwdev,
{
struct rtw89_fw_info *fw_info = &rtwdev->fw;
- if (type == RTW89_FW_WOWLAN)
+ switch (type) {
+ case RTW89_FW_WOWLAN:
return &fw_info->wowlan;
+ case RTW89_FW_LOGFMT:
+ return &fw_info->log.suit;
+ case RTW89_FW_BBMCU0:
+ return &fw_info->bbmcu0;
+ case RTW89_FW_BBMCU1:
+ return &fw_info->bbmcu1;
+ default:
+ break;
+ }
+
return &fw_info->normal;
}
@@ -5035,6 +5374,8 @@ struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device,
void rtw89_free_ieee80211_hw(struct rtw89_dev *rtwdev);
void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev);
void rtw89_get_default_chandef(struct cfg80211_chan_def *chandef);
+void rtw89_get_channel_params(const struct cfg80211_chan_def *chandef,
+ struct rtw89_chan *chan);
void rtw89_set_channel(struct rtw89_dev *rtwdev);
void rtw89_get_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
struct rtw89_chan *chan);
@@ -5069,5 +5410,6 @@ void rtw89_core_scan_complete(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif, bool hw_scan);
void rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif, bool active);
+void rtw89_core_ntfy_btc_event(struct rtw89_dev *rtwdev, enum rtw89_btc_hmsg event);
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c
index 1db2d59d33ff..d162e64f6064 100644
--- a/drivers/net/wireless/realtek/rtw89/debug.c
+++ b/drivers/net/wireless/realtek/rtw89/debug.c
@@ -572,9 +572,9 @@ static int __print_txpwr_map(struct seq_file *m, struct rtw89_dev *rtwdev,
seq_puts(m, #_regd "\n"); \
break
-static void __print_regd(struct seq_file *m, struct rtw89_dev *rtwdev)
+static void __print_regd(struct seq_file *m, struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 band = chan->band_type;
u8 regd = rtw89_regd_get(rtwdev, band);
@@ -604,16 +604,21 @@ static int rtw89_debug_priv_txpwr_table_get(struct seq_file *m, void *v)
{
struct rtw89_debugfs_priv *debugfs_priv = m->private;
struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
+ const struct rtw89_chan *chan;
int ret = 0;
mutex_lock(&rtwdev->mutex);
rtw89_leave_ps_mode(rtwdev);
+ chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
seq_puts(m, "[Regulatory] ");
- __print_regd(m, rtwdev);
+ __print_regd(m, rtwdev, chan);
seq_puts(m, "[SAR]\n");
- rtw89_print_sar(m, rtwdev);
+ rtw89_print_sar(m, rtwdev, chan->freq);
+
+ seq_puts(m, "[TAS]\n");
+ rtw89_print_tas(m, rtwdev);
seq_puts(m, "\n[TX power byrate]\n");
ret = __print_txpwr_map(m, rtwdev, &__txpwr_map_byr);
@@ -790,6 +795,9 @@ static void rtw89_debug_dump_mac_mem(struct seq_file *m,
struct rtw89_dev *rtwdev,
u8 sel, u32 start_addr, u32 len)
{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+ u32 filter_model_addr = mac->filter_model_addr;
+ u32 indir_access_addr = mac->indir_access_addr;
u32 base_addr, start_page, residue;
u32 i, j, p, pages;
u32 dump_len, remain;
@@ -799,17 +807,17 @@ static void rtw89_debug_dump_mac_mem(struct seq_file *m,
pages = len / MAC_MEM_DUMP_PAGE_SIZE + 1;
start_page = start_addr / MAC_MEM_DUMP_PAGE_SIZE;
residue = start_addr % MAC_MEM_DUMP_PAGE_SIZE;
- base_addr = rtw89_mac_mem_base_addrs[sel];
+ base_addr = mac->mem_base_addrs[sel];
base_addr += start_page * MAC_MEM_DUMP_PAGE_SIZE;
for (p = 0; p < pages; p++) {
dump_len = min_t(u32, remain, MAC_MEM_DUMP_PAGE_SIZE);
- rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, base_addr);
- for (i = R_AX_INDIR_ACCESS_ENTRY + residue;
- i < R_AX_INDIR_ACCESS_ENTRY + dump_len;) {
+ rtw89_write32(rtwdev, filter_model_addr, base_addr);
+ for (i = indir_access_addr + residue;
+ i < indir_access_addr + dump_len;) {
seq_printf(m, "%08xh:", i);
for (j = 0;
- j < 4 && i < R_AX_INDIR_ACCESS_ENTRY + dump_len;
+ j < 4 && i < indir_access_addr + dump_len;
j++, i += 4) {
val = rtw89_read32(rtwdev, i);
seq_printf(m, " %08x", val);
@@ -3026,17 +3034,18 @@ static ssize_t rtw89_debug_priv_send_h2c_set(struct file *filp,
struct rtw89_debugfs_priv *debugfs_priv = filp->private_data;
struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
u8 *h2c;
+ int ret;
u16 h2c_len = count / 2;
h2c = rtw89_hex2bin_user(rtwdev, user_buf, count);
if (IS_ERR(h2c))
return -EFAULT;
- rtw89_fw_h2c_raw(rtwdev, h2c, h2c_len);
+ ret = rtw89_fw_h2c_raw(rtwdev, h2c, h2c_len);
kfree(h2c);
- return count;
+ return ret ? ret : count;
}
static int
@@ -3192,29 +3201,33 @@ static ssize_t rtw89_debug_priv_btc_manual_set(struct file *filp,
struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
struct rtw89_btc *btc = &rtwdev->btc;
bool btc_manual;
+ int ret;
- if (kstrtobool_from_user(user_buf, count, &btc_manual))
- goto out;
+ ret = kstrtobool_from_user(user_buf, count, &btc_manual);
+ if (ret)
+ return ret;
btc->ctrl.manual = btc_manual;
-out:
+
return count;
}
-static ssize_t rtw89_debug_fw_log_btc_manual_set(struct file *filp,
- const char __user *user_buf,
- size_t count, loff_t *loff)
+static ssize_t rtw89_debug_fw_log_manual_set(struct file *filp,
+ const char __user *user_buf,
+ size_t count, loff_t *loff)
{
struct rtw89_debugfs_priv *debugfs_priv = filp->private_data;
struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
- struct rtw89_fw_info *fw_info = &rtwdev->fw;
+ struct rtw89_fw_log *log = &rtwdev->fw.log;
bool fw_log_manual;
if (kstrtobool_from_user(user_buf, count, &fw_log_manual))
goto out;
mutex_lock(&rtwdev->mutex);
- fw_info->fw_log_enable = fw_log_manual;
+ log->enable = fw_log_manual;
+ if (log->enable)
+ rtw89_fw_log_prepare(rtwdev);
rtw89_fw_h2c_fw_log(rtwdev, fw_log_manual);
mutex_unlock(&rtwdev->mutex);
out:
@@ -3322,20 +3335,26 @@ rtw89_debug_append_rx_rate(struct seq_file *m, struct rtw89_pkt_stat *pkt_stat,
pkt_stat->rx_rate_cnt[first_rate + i]);
}
+#define FIRST_RATE_SAME(rate) {RTW89_HW_RATE_ ## rate, RTW89_HW_RATE_ ## rate}
+#define FIRST_RATE_ENUM(rate) {RTW89_HW_RATE_ ## rate, RTW89_HW_RATE_V1_ ## rate}
+#define FIRST_RATE_GEV1(rate) {RTW89_HW_RATE_INVAL, RTW89_HW_RATE_V1_ ## rate}
+
static const struct rtw89_rx_rate_cnt_info {
- enum rtw89_hw_rate first_rate;
+ enum rtw89_hw_rate first_rate[RTW89_CHIP_GEN_NUM];
int len;
int ext;
const char *rate_mode;
} rtw89_rx_rate_cnt_infos[] = {
- {RTW89_HW_RATE_CCK1, 4, 0, "Legacy:"},
- {RTW89_HW_RATE_OFDM6, 8, 0, "OFDM:"},
- {RTW89_HW_RATE_MCS0, 8, 0, "HT 0:"},
- {RTW89_HW_RATE_MCS8, 8, 0, "HT 1:"},
- {RTW89_HW_RATE_VHT_NSS1_MCS0, 10, 2, "VHT 1SS:"},
- {RTW89_HW_RATE_VHT_NSS2_MCS0, 10, 2, "VHT 2SS:"},
- {RTW89_HW_RATE_HE_NSS1_MCS0, 12, 0, "HE 1SS:"},
- {RTW89_HW_RATE_HE_NSS2_MCS0, 12, 0, "HE 2ss:"},
+ {FIRST_RATE_SAME(CCK1), 4, 0, "Legacy:"},
+ {FIRST_RATE_SAME(OFDM6), 8, 0, "OFDM:"},
+ {FIRST_RATE_ENUM(MCS0), 8, 0, "HT 0:"},
+ {FIRST_RATE_ENUM(MCS8), 8, 0, "HT 1:"},
+ {FIRST_RATE_ENUM(VHT_NSS1_MCS0), 10, 2, "VHT 1SS:"},
+ {FIRST_RATE_ENUM(VHT_NSS2_MCS0), 10, 2, "VHT 2SS:"},
+ {FIRST_RATE_ENUM(HE_NSS1_MCS0), 12, 0, "HE 1SS:"},
+ {FIRST_RATE_ENUM(HE_NSS2_MCS0), 12, 0, "HE 2SS:"},
+ {FIRST_RATE_GEV1(EHT_NSS1_MCS0), 14, 2, "EHT 1SS:"},
+ {FIRST_RATE_GEV1(EHT_NSS2_MCS0), 14, 0, "EHT 2SS:"},
};
static int rtw89_debug_priv_phy_info_get(struct seq_file *m, void *v)
@@ -3344,7 +3363,9 @@ static int rtw89_debug_priv_phy_info_get(struct seq_file *m, void *v)
struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
struct rtw89_traffic_stats *stats = &rtwdev->stats;
struct rtw89_pkt_stat *pkt_stat = &rtwdev->phystat.last_pkt_stat;
+ const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_rx_rate_cnt_info *info;
+ enum rtw89_hw_rate first_rate;
int i;
seq_printf(m, "TP TX: %u [%u] Mbps (lv: %d), RX: %u [%u] Mbps (lv: %d)\n",
@@ -3356,15 +3377,20 @@ static int rtw89_debug_priv_phy_info_get(struct seq_file *m, void *v)
stats->rx_avg_len);
seq_puts(m, "RX count:\n");
+
for (i = 0; i < ARRAY_SIZE(rtw89_rx_rate_cnt_infos); i++) {
info = &rtw89_rx_rate_cnt_infos[i];
+ first_rate = info->first_rate[chip->chip_gen];
+ if (first_rate >= RTW89_HW_RATE_NR)
+ continue;
+
seq_printf(m, "%10s [", info->rate_mode);
rtw89_debug_append_rx_rate(m, pkt_stat,
- info->first_rate, info->len);
+ first_rate, info->len);
if (info->ext) {
seq_puts(m, "][");
rtw89_debug_append_rx_rate(m, pkt_stat,
- info->first_rate + info->len, info->ext);
+ first_rate + info->len, info->ext);
}
seq_puts(m, "]\n");
}
@@ -3568,7 +3594,7 @@ static struct rtw89_debugfs_priv rtw89_debug_priv_btc_manual = {
};
static struct rtw89_debugfs_priv rtw89_debug_priv_fw_log_manual = {
- .cb_write = rtw89_debug_fw_log_btc_manual_set,
+ .cb_write = rtw89_debug_fw_log_manual_set,
};
static struct rtw89_debugfs_priv rtw89_debug_priv_phy_info = {
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 9637f5e48d84..df1dc2f43c86 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -9,6 +9,7 @@
#include "fw.h"
#include "mac.h"
#include "phy.h"
+#include "ps.h"
#include "reg.h"
#include "util.h"
@@ -86,8 +87,8 @@ int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev)
return 0;
}
-static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len,
- struct rtw89_fw_bin_info *info)
+static int rtw89_fw_hdr_parser_v0(struct rtw89_dev *rtwdev, const u8 *fw, u32 len,
+ struct rtw89_fw_bin_info *info)
{
const struct rtw89_fw_hdr *fw_hdr = (const struct rtw89_fw_hdr *)fw;
struct rtw89_fw_hdr_section_info *section_info;
@@ -154,6 +155,94 @@ static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len,
return 0;
}
+static int rtw89_fw_hdr_parser_v1(struct rtw89_dev *rtwdev, const u8 *fw, u32 len,
+ struct rtw89_fw_bin_info *info)
+{
+ const struct rtw89_fw_hdr_v1 *fw_hdr = (const struct rtw89_fw_hdr_v1 *)fw;
+ struct rtw89_fw_hdr_section_info *section_info;
+ const struct rtw89_fw_dynhdr_hdr *fwdynhdr;
+ const struct rtw89_fw_hdr_section_v1 *section;
+ const u8 *fw_end = fw + len;
+ const u8 *bin;
+ u32 base_hdr_len;
+ u32 mssc_len = 0;
+ u32 i;
+
+ info->section_num = le32_get_bits(fw_hdr->w6, FW_HDR_V1_W6_SEC_NUM);
+ base_hdr_len = struct_size(fw_hdr, sections, info->section_num);
+ info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_DYN_HDR);
+
+ if (info->dynamic_hdr_en) {
+ info->hdr_len = le32_get_bits(fw_hdr->w5, FW_HDR_V1_W5_HDR_SIZE);
+ info->dynamic_hdr_len = info->hdr_len - base_hdr_len;
+ fwdynhdr = (const struct rtw89_fw_dynhdr_hdr *)(fw + base_hdr_len);
+ if (le32_to_cpu(fwdynhdr->hdr_len) != info->dynamic_hdr_len) {
+ rtw89_err(rtwdev, "[ERR]invalid fw dynamic header len\n");
+ return -EINVAL;
+ }
+ } else {
+ info->hdr_len = base_hdr_len;
+ info->dynamic_hdr_len = 0;
+ }
+
+ bin = fw + info->hdr_len;
+
+ /* jump to section header */
+ section_info = info->section_info;
+ for (i = 0; i < info->section_num; i++) {
+ section = &fw_hdr->sections[i];
+ section_info->type =
+ le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_SECTIONTYPE);
+ if (section_info->type == FWDL_SECURITY_SECTION_TYPE) {
+ section_info->mssc =
+ le32_get_bits(section->w2, FWSECTION_HDR_V1_W2_MSSC);
+ mssc_len += section_info->mssc * FWDL_SECURITY_SIGLEN;
+ } else {
+ section_info->mssc = 0;
+ }
+
+ section_info->len =
+ le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_SEC_SIZE);
+ if (le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_CHECKSUM))
+ section_info->len += FWDL_SECTION_CHKSUM_LEN;
+ section_info->redl = le32_get_bits(section->w1, FWSECTION_HDR_V1_W1_REDL);
+ section_info->dladdr =
+ le32_get_bits(section->w0, FWSECTION_HDR_V1_W0_DL_ADDR);
+ section_info->addr = bin;
+ bin += section_info->len;
+ section_info++;
+ }
+
+ if (fw_end != bin + mssc_len) {
+ rtw89_err(rtwdev, "[ERR]fw bin size\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev,
+ const struct rtw89_fw_suit *fw_suit,
+ struct rtw89_fw_bin_info *info)
+{
+ const u8 *fw = fw_suit->data;
+ u32 len = fw_suit->size;
+
+ if (!fw || !len) {
+ rtw89_err(rtwdev, "fw type %d isn't recognized\n", fw_suit->type);
+ return -ENOENT;
+ }
+
+ switch (fw_suit->hdr_ver) {
+ case 0:
+ return rtw89_fw_hdr_parser_v0(rtwdev, fw, len, info);
+ case 1:
+ return rtw89_fw_hdr_parser_v1(rtwdev, fw, len, info);
+ default:
+ return -ENOENT;
+ }
+}
+
static
int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
struct rtw89_fw_suit *fw_suit, bool nowarn)
@@ -178,42 +267,110 @@ int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
for (i = 0; i < mfw_hdr->fw_nr; i++) {
mfw_info = &mfw_hdr->info[i];
- if (mfw_info->cv != rtwdev->hal.cv ||
- mfw_info->type != type ||
- mfw_info->mp)
- continue;
-
- fw_suit->data = mfw + le32_to_cpu(mfw_info->shift);
- fw_suit->size = le32_to_cpu(mfw_info->size);
- return 0;
+ if (mfw_info->type == type) {
+ if (mfw_info->cv == rtwdev->hal.cv && !mfw_info->mp)
+ goto found;
+ if (type == RTW89_FW_LOGFMT)
+ goto found;
+ }
}
if (!nowarn)
rtw89_err(rtwdev, "no suitable firmware found\n");
return -ENOENT;
+
+found:
+ fw_suit->data = mfw + le32_to_cpu(mfw_info->shift);
+ fw_suit->size = le32_to_cpu(mfw_info->size);
+ return 0;
}
-static void rtw89_fw_update_ver(struct rtw89_dev *rtwdev,
- enum rtw89_fw_type type,
- struct rtw89_fw_suit *fw_suit)
+static u32 rtw89_mfw_get_size(struct rtw89_dev *rtwdev)
{
- const struct rtw89_fw_hdr *hdr = (const struct rtw89_fw_hdr *)fw_suit->data;
+ struct rtw89_fw_info *fw_info = &rtwdev->fw;
+ const struct firmware *firmware = fw_info->req.firmware;
+ const struct rtw89_mfw_hdr *mfw_hdr =
+ (const struct rtw89_mfw_hdr *)firmware->data;
+ const struct rtw89_mfw_info *mfw_info;
+ u32 size;
+
+ if (mfw_hdr->sig != RTW89_MFW_SIG) {
+ rtw89_warn(rtwdev, "not mfw format\n");
+ return 0;
+ }
+
+ mfw_info = &mfw_hdr->info[mfw_hdr->fw_nr - 1];
+ size = le32_to_cpu(mfw_info->shift) + le32_to_cpu(mfw_info->size);
+ return size;
+}
+
+static void rtw89_fw_update_ver_v0(struct rtw89_dev *rtwdev,
+ struct rtw89_fw_suit *fw_suit,
+ const struct rtw89_fw_hdr *hdr)
+{
fw_suit->major_ver = le32_get_bits(hdr->w1, FW_HDR_W1_MAJOR_VERSION);
fw_suit->minor_ver = le32_get_bits(hdr->w1, FW_HDR_W1_MINOR_VERSION);
fw_suit->sub_ver = le32_get_bits(hdr->w1, FW_HDR_W1_SUBVERSION);
fw_suit->sub_idex = le32_get_bits(hdr->w1, FW_HDR_W1_SUBINDEX);
+ fw_suit->commitid = le32_get_bits(hdr->w2, FW_HDR_W2_COMMITID);
fw_suit->build_year = le32_get_bits(hdr->w5, FW_HDR_W5_YEAR);
fw_suit->build_mon = le32_get_bits(hdr->w4, FW_HDR_W4_MONTH);
fw_suit->build_date = le32_get_bits(hdr->w4, FW_HDR_W4_DATE);
fw_suit->build_hour = le32_get_bits(hdr->w4, FW_HDR_W4_HOUR);
fw_suit->build_min = le32_get_bits(hdr->w4, FW_HDR_W4_MIN);
fw_suit->cmd_ver = le32_get_bits(hdr->w7, FW_HDR_W7_CMD_VERSERION);
+}
+
+static void rtw89_fw_update_ver_v1(struct rtw89_dev *rtwdev,
+ struct rtw89_fw_suit *fw_suit,
+ const struct rtw89_fw_hdr_v1 *hdr)
+{
+ fw_suit->major_ver = le32_get_bits(hdr->w1, FW_HDR_V1_W1_MAJOR_VERSION);
+ fw_suit->minor_ver = le32_get_bits(hdr->w1, FW_HDR_V1_W1_MINOR_VERSION);
+ fw_suit->sub_ver = le32_get_bits(hdr->w1, FW_HDR_V1_W1_SUBVERSION);
+ fw_suit->sub_idex = le32_get_bits(hdr->w1, FW_HDR_V1_W1_SUBINDEX);
+ fw_suit->commitid = le32_get_bits(hdr->w2, FW_HDR_V1_W2_COMMITID);
+ fw_suit->build_year = le32_get_bits(hdr->w5, FW_HDR_V1_W5_YEAR);
+ fw_suit->build_mon = le32_get_bits(hdr->w4, FW_HDR_V1_W4_MONTH);
+ fw_suit->build_date = le32_get_bits(hdr->w4, FW_HDR_V1_W4_DATE);
+ fw_suit->build_hour = le32_get_bits(hdr->w4, FW_HDR_V1_W4_HOUR);
+ fw_suit->build_min = le32_get_bits(hdr->w4, FW_HDR_V1_W4_MIN);
+ fw_suit->cmd_ver = le32_get_bits(hdr->w7, FW_HDR_V1_W3_CMD_VERSERION);
+}
+
+static int rtw89_fw_update_ver(struct rtw89_dev *rtwdev,
+ enum rtw89_fw_type type,
+ struct rtw89_fw_suit *fw_suit)
+{
+ const struct rtw89_fw_hdr *v0 = (const struct rtw89_fw_hdr *)fw_suit->data;
+ const struct rtw89_fw_hdr_v1 *v1 = (const struct rtw89_fw_hdr_v1 *)fw_suit->data;
+
+ if (type == RTW89_FW_LOGFMT)
+ return 0;
+
+ fw_suit->type = type;
+ fw_suit->hdr_ver = le32_get_bits(v0->w3, FW_HDR_W3_HDR_VER);
+
+ switch (fw_suit->hdr_ver) {
+ case 0:
+ rtw89_fw_update_ver_v0(rtwdev, fw_suit, v0);
+ break;
+ case 1:
+ rtw89_fw_update_ver_v1(rtwdev, fw_suit, v1);
+ break;
+ default:
+ rtw89_err(rtwdev, "Unknown firmware header version %u\n",
+ fw_suit->hdr_ver);
+ return -ENOENT;
+ }
rtw89_info(rtwdev,
- "Firmware version %u.%u.%u.%u, cmd version %u, type %u\n",
+ "Firmware version %u.%u.%u.%u (%08x), cmd version %u, type %u\n",
fw_suit->major_ver, fw_suit->minor_ver, fw_suit->sub_ver,
- fw_suit->sub_idex, fw_suit->cmd_ver, type);
+ fw_suit->sub_idex, fw_suit->commitid, fw_suit->cmd_ver, type);
+
+ return 0;
}
static
@@ -227,9 +384,22 @@ int __rtw89_fw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
if (ret)
return ret;
- rtw89_fw_update_ver(rtwdev, type, fw_suit);
+ return rtw89_fw_update_ver(rtwdev, type, fw_suit);
+}
- return 0;
+static
+int __rtw89_fw_recognize_from_elm(struct rtw89_dev *rtwdev,
+ const struct rtw89_fw_element_hdr *elm,
+ const void *data)
+{
+ enum rtw89_fw_type type = (enum rtw89_fw_type)data;
+ struct rtw89_fw_suit *fw_suit;
+
+ fw_suit = rtw89_fw_suit_get(rtwdev, type);
+ fw_suit->data = elm->u.common.contents;
+ fw_suit->size = le32_to_cpu(elm->size);
+
+ return rtw89_fw_update_ver(rtwdev, type, fw_suit);
}
#define __DEF_FW_FEAT_COND(__cond, __op) \
@@ -312,31 +482,17 @@ rtw89_early_fw_feature_recognize(struct device *device,
struct rtw89_fw_info *early_fw,
int *used_fw_format)
{
- union rtw89_compat_fw_hdr buf = {};
const struct firmware *firmware;
- bool full_req = false;
char fw_name[64];
int fw_format;
u32 ver_code;
int ret;
- /* If SECURITY_LOADPIN_ENFORCE is enabled, reading partial files will
- * be denied (-EPERM). Then, we don't get right firmware things as
- * expected. So, in this case, we have to request full firmware here.
- */
- if (IS_ENABLED(CONFIG_SECURITY_LOADPIN_ENFORCE))
- full_req = true;
-
for (fw_format = chip->fw_format_max; fw_format >= 0; fw_format--) {
rtw89_fw_get_filename(fw_name, sizeof(fw_name),
chip->fw_basename, fw_format);
- if (full_req)
- ret = request_firmware(&firmware, fw_name, device);
- else
- ret = request_partial_firmware_into_buf(&firmware, fw_name,
- device, &buf, sizeof(buf),
- 0);
+ ret = request_firmware(&firmware, fw_name, device);
if (!ret) {
dev_info(device, "loaded firmware %s\n", fw_name);
*used_fw_format = fw_format;
@@ -349,10 +505,7 @@ rtw89_early_fw_feature_recognize(struct device *device,
return NULL;
}
- if (full_req)
- ver_code = rtw89_compat_fw_hdr_ver_code(firmware->data);
- else
- ver_code = rtw89_compat_fw_hdr_ver_code(&buf);
+ ver_code = rtw89_compat_fw_hdr_ver_code(firmware->data);
if (!ver_code)
goto out;
@@ -360,11 +513,7 @@ rtw89_early_fw_feature_recognize(struct device *device,
rtw89_fw_iterate_feature_cfg(early_fw, chip, ver_code);
out:
- if (full_req)
- return firmware;
-
- release_firmware(firmware);
- return NULL;
+ return firmware;
}
int rtw89_fw_recognize(struct rtw89_dev *rtwdev)
@@ -386,6 +535,9 @@ normal_done:
/* It still works if wowlan firmware isn't existing. */
__rtw89_fw_recognize(rtwdev, RTW89_FW_WOWLAN, false);
+ /* It still works if log format file isn't existing. */
+ __rtw89_fw_recognize(rtwdev, RTW89_FW_LOGFMT, true);
+
rtw89_fw_recognize_features(rtwdev);
rtw89_coex_recognize_ver(rtwdev);
@@ -393,6 +545,153 @@ normal_done:
return 0;
}
+static
+int rtw89_build_phy_tbl_from_elm(struct rtw89_dev *rtwdev,
+ const struct rtw89_fw_element_hdr *elm,
+ const void *data)
+{
+ struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
+ struct rtw89_phy_table *tbl;
+ struct rtw89_reg2_def *regs;
+ enum rtw89_rf_path rf_path;
+ u32 n_regs, i;
+ u8 idx;
+
+ tbl = kzalloc(sizeof(*tbl), GFP_KERNEL);
+ if (!tbl)
+ return -ENOMEM;
+
+ switch (le32_to_cpu(elm->id)) {
+ case RTW89_FW_ELEMENT_ID_BB_REG:
+ elm_info->bb_tbl = tbl;
+ break;
+ case RTW89_FW_ELEMENT_ID_BB_GAIN:
+ elm_info->bb_gain = tbl;
+ break;
+ case RTW89_FW_ELEMENT_ID_RADIO_A:
+ case RTW89_FW_ELEMENT_ID_RADIO_B:
+ case RTW89_FW_ELEMENT_ID_RADIO_C:
+ case RTW89_FW_ELEMENT_ID_RADIO_D:
+ rf_path = (enum rtw89_rf_path)data;
+ idx = elm->u.reg2.idx;
+
+ elm_info->rf_radio[idx] = tbl;
+ tbl->rf_path = rf_path;
+ tbl->config = rtw89_phy_config_rf_reg_v1;
+ break;
+ case RTW89_FW_ELEMENT_ID_RF_NCTL:
+ elm_info->rf_nctl = tbl;
+ break;
+ default:
+ kfree(tbl);
+ return -ENOENT;
+ }
+
+ n_regs = le32_to_cpu(elm->size) / sizeof(tbl->regs[0]);
+ regs = kcalloc(n_regs, sizeof(tbl->regs[0]), GFP_KERNEL);
+ if (!regs)
+ goto out;
+
+ for (i = 0; i < n_regs; i++) {
+ regs[i].addr = le32_to_cpu(elm->u.reg2.regs[i].addr);
+ regs[i].data = le32_to_cpu(elm->u.reg2.regs[i].data);
+ }
+
+ tbl->n_regs = n_regs;
+ tbl->regs = regs;
+
+ return 0;
+
+out:
+ kfree(tbl);
+ return -ENOMEM;
+}
+
+struct rtw89_fw_element_handler {
+ int (*fn)(struct rtw89_dev *rtwdev,
+ const struct rtw89_fw_element_hdr *elm, const void *data);
+ const void *data;
+ const char *name;
+};
+
+static const struct rtw89_fw_element_handler __fw_element_handlers[] = {
+ [RTW89_FW_ELEMENT_ID_BBMCU0] = {__rtw89_fw_recognize_from_elm,
+ (const void *)RTW89_FW_BBMCU0, NULL},
+ [RTW89_FW_ELEMENT_ID_BBMCU1] = {__rtw89_fw_recognize_from_elm,
+ (const void *)RTW89_FW_BBMCU1, NULL},
+ [RTW89_FW_ELEMENT_ID_BB_REG] = {rtw89_build_phy_tbl_from_elm, NULL, "BB"},
+ [RTW89_FW_ELEMENT_ID_BB_GAIN] = {rtw89_build_phy_tbl_from_elm, NULL, NULL},
+ [RTW89_FW_ELEMENT_ID_RADIO_A] = {rtw89_build_phy_tbl_from_elm,
+ (const void *)RF_PATH_A, "radio A"},
+ [RTW89_FW_ELEMENT_ID_RADIO_B] = {rtw89_build_phy_tbl_from_elm,
+ (const void *)RF_PATH_B, NULL},
+ [RTW89_FW_ELEMENT_ID_RADIO_C] = {rtw89_build_phy_tbl_from_elm,
+ (const void *)RF_PATH_C, NULL},
+ [RTW89_FW_ELEMENT_ID_RADIO_D] = {rtw89_build_phy_tbl_from_elm,
+ (const void *)RF_PATH_D, NULL},
+ [RTW89_FW_ELEMENT_ID_RF_NCTL] = {rtw89_build_phy_tbl_from_elm, NULL, "NCTL"},
+};
+
+int rtw89_fw_recognize_elements(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_fw_info *fw_info = &rtwdev->fw;
+ const struct firmware *firmware = fw_info->req.firmware;
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ u32 unrecognized_elements = chip->needed_fw_elms;
+ const struct rtw89_fw_element_handler *handler;
+ const struct rtw89_fw_element_hdr *hdr;
+ u32 elm_size;
+ u32 elem_id;
+ u32 offset;
+ int ret;
+
+ BUILD_BUG_ON(sizeof(chip->needed_fw_elms) * 8 < RTW89_FW_ELEMENT_ID_NUM);
+
+ offset = rtw89_mfw_get_size(rtwdev);
+ offset = ALIGN(offset, RTW89_FW_ELEMENT_ALIGN);
+ if (offset == 0)
+ return -EINVAL;
+
+ while (offset + sizeof(*hdr) < firmware->size) {
+ hdr = (const struct rtw89_fw_element_hdr *)(firmware->data + offset);
+
+ elm_size = le32_to_cpu(hdr->size);
+ if (offset + elm_size >= firmware->size) {
+ rtw89_warn(rtwdev, "firmware element size exceeds\n");
+ break;
+ }
+
+ elem_id = le32_to_cpu(hdr->id);
+ if (elem_id >= ARRAY_SIZE(__fw_element_handlers))
+ goto next;
+
+ handler = &__fw_element_handlers[elem_id];
+ if (!handler->fn)
+ goto next;
+
+ ret = handler->fn(rtwdev, hdr, handler->data);
+ if (ret)
+ return ret;
+
+ if (handler->name)
+ rtw89_info(rtwdev, "Firmware element %s version: %4ph\n",
+ handler->name, hdr->ver);
+
+ unrecognized_elements &= ~BIT(elem_id);
+next:
+ offset += sizeof(*hdr) + elm_size;
+ offset = ALIGN(offset, RTW89_FW_ELEMENT_ALIGN);
+ }
+
+ if (unrecognized_elements) {
+ rtw89_err(rtwdev, "Firmware elements 0x%08x are unrecognized\n",
+ unrecognized_elements);
+ return -ENOENT;
+ }
+
+ return 0;
+}
+
void rtw89_h2c_pkt_set_hdr(struct rtw89_dev *rtwdev, struct sk_buff *skb,
u8 type, u8 cat, u8 class, u8 func,
bool rack, bool dack, u32 len)
@@ -593,8 +892,6 @@ int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type)
struct rtw89_fw_info *fw_info = &rtwdev->fw;
struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type);
struct rtw89_fw_bin_info info;
- const u8 *fw = fw_suit->data;
- u32 len = fw_suit->size;
u8 val;
int ret;
@@ -603,12 +900,7 @@ int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type)
if (ret)
return ret;
- if (!fw || !len) {
- rtw89_err(rtwdev, "fw type %d isn't recognized\n", type);
- return -ENOENT;
- }
-
- ret = rtw89_fw_hdr_parser(rtwdev, fw, len, &info);
+ ret = rtw89_fw_hdr_parser(rtwdev, fw_suit, &info);
if (ret) {
rtw89_err(rtwdev, "parse fw header fail\n");
goto fwdl_err;
@@ -622,13 +914,14 @@ int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type)
goto fwdl_err;
}
- ret = rtw89_fw_download_hdr(rtwdev, fw, info.hdr_len - info.dynamic_hdr_len);
+ ret = rtw89_fw_download_hdr(rtwdev, fw_suit->data, info.hdr_len -
+ info.dynamic_hdr_len);
if (ret) {
ret = -EBUSY;
goto fwdl_err;
}
- ret = rtw89_fw_download_main(rtwdev, fw, &info);
+ ret = rtw89_fw_download_main(rtwdev, fw_suit->data, &info);
if (ret) {
ret = -EBUSY;
goto fwdl_err;
@@ -695,6 +988,27 @@ void rtw89_load_firmware_work(struct work_struct *work)
rtw89_load_firmware_req(rtwdev, &rtwdev->fw.req, fw_name, false);
}
+static void rtw89_free_phy_tbl_from_elm(struct rtw89_phy_table *tbl)
+{
+ if (!tbl)
+ return;
+
+ kfree(tbl->regs);
+ kfree(tbl);
+}
+
+static void rtw89_unload_firmware_elements(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
+ int i;
+
+ rtw89_free_phy_tbl_from_elm(elm_info->bb_tbl);
+ rtw89_free_phy_tbl_from_elm(elm_info->bb_gain);
+ for (i = 0; i < ARRAY_SIZE(elm_info->rf_radio); i++)
+ rtw89_free_phy_tbl_from_elm(elm_info->rf_radio[i]);
+ rtw89_free_phy_tbl_from_elm(elm_info->rf_nctl);
+}
+
void rtw89_unload_firmware(struct rtw89_dev *rtwdev)
{
struct rtw89_fw_info *fw = &rtwdev->fw;
@@ -709,6 +1023,151 @@ void rtw89_unload_firmware(struct rtw89_dev *rtwdev)
*/
fw->req.firmware = NULL;
}
+
+ kfree(fw->log.fmts);
+ rtw89_unload_firmware_elements(rtwdev);
+}
+
+static u32 rtw89_fw_log_get_fmt_idx(struct rtw89_dev *rtwdev, u32 fmt_id)
+{
+ struct rtw89_fw_log *fw_log = &rtwdev->fw.log;
+ u32 i;
+
+ if (fmt_id > fw_log->last_fmt_id)
+ return 0;
+
+ for (i = 0; i < fw_log->fmt_count; i++) {
+ if (le32_to_cpu(fw_log->fmt_ids[i]) == fmt_id)
+ return i;
+ }
+ return 0;
+}
+
+static int rtw89_fw_log_create_fmts_dict(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_fw_log *log = &rtwdev->fw.log;
+ const struct rtw89_fw_logsuit_hdr *suit_hdr;
+ struct rtw89_fw_suit *suit = &log->suit;
+ const void *fmts_ptr, *fmts_end_ptr;
+ u32 fmt_count;
+ int i;
+
+ suit_hdr = (const struct rtw89_fw_logsuit_hdr *)suit->data;
+ fmt_count = le32_to_cpu(suit_hdr->count);
+ log->fmt_ids = suit_hdr->ids;
+ fmts_ptr = &suit_hdr->ids[fmt_count];
+ fmts_end_ptr = suit->data + suit->size;
+ log->fmts = kcalloc(fmt_count, sizeof(char *), GFP_KERNEL);
+ if (!log->fmts)
+ return -ENOMEM;
+
+ for (i = 0; i < fmt_count; i++) {
+ fmts_ptr = memchr_inv(fmts_ptr, 0, fmts_end_ptr - fmts_ptr);
+ if (!fmts_ptr)
+ break;
+
+ (*log->fmts)[i] = fmts_ptr;
+ log->last_fmt_id = le32_to_cpu(log->fmt_ids[i]);
+ log->fmt_count++;
+ fmts_ptr += strlen(fmts_ptr);
+ }
+
+ return 0;
+}
+
+int rtw89_fw_log_prepare(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_fw_log *log = &rtwdev->fw.log;
+ struct rtw89_fw_suit *suit = &log->suit;
+
+ if (!suit || !suit->data) {
+ rtw89_debug(rtwdev, RTW89_DBG_FW, "no log format file\n");
+ return -EINVAL;
+ }
+ if (log->fmts)
+ return 0;
+
+ return rtw89_fw_log_create_fmts_dict(rtwdev);
+}
+
+static void rtw89_fw_log_dump_data(struct rtw89_dev *rtwdev,
+ const struct rtw89_fw_c2h_log_fmt *log_fmt,
+ u32 fmt_idx, u8 para_int, bool raw_data)
+{
+ const char *(*fmts)[] = rtwdev->fw.log.fmts;
+ char str_buf[RTW89_C2H_FW_LOG_STR_BUF_SIZE];
+ u32 args[RTW89_C2H_FW_LOG_MAX_PARA_NUM] = {0};
+ int i;
+
+ if (log_fmt->argc > RTW89_C2H_FW_LOG_MAX_PARA_NUM) {
+ rtw89_warn(rtwdev, "C2H log: Arg count is unexpected %d\n",
+ log_fmt->argc);
+ return;
+ }
+
+ if (para_int)
+ for (i = 0 ; i < log_fmt->argc; i++)
+ args[i] = le32_to_cpu(log_fmt->u.argv[i]);
+
+ if (raw_data) {
+ if (para_int)
+ snprintf(str_buf, RTW89_C2H_FW_LOG_STR_BUF_SIZE,
+ "fw_enc(%d, %d, %d) %*ph", le32_to_cpu(log_fmt->fmt_id),
+ para_int, log_fmt->argc, (int)sizeof(args), args);
+ else
+ snprintf(str_buf, RTW89_C2H_FW_LOG_STR_BUF_SIZE,
+ "fw_enc(%d, %d, %d, %s)", le32_to_cpu(log_fmt->fmt_id),
+ para_int, log_fmt->argc, log_fmt->u.raw);
+ } else {
+ snprintf(str_buf, RTW89_C2H_FW_LOG_STR_BUF_SIZE, (*fmts)[fmt_idx],
+ args[0x0], args[0x1], args[0x2], args[0x3], args[0x4],
+ args[0x5], args[0x6], args[0x7], args[0x8], args[0x9],
+ args[0xa], args[0xb], args[0xc], args[0xd], args[0xe],
+ args[0xf]);
+ }
+
+ rtw89_info(rtwdev, "C2H log: %s", str_buf);
+}
+
+void rtw89_fw_log_dump(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
+{
+ const struct rtw89_fw_c2h_log_fmt *log_fmt;
+ u8 para_int;
+ u32 fmt_idx;
+
+ if (len < RTW89_C2H_HEADER_LEN) {
+ rtw89_err(rtwdev, "c2h log length is wrong!\n");
+ return;
+ }
+
+ buf += RTW89_C2H_HEADER_LEN;
+ len -= RTW89_C2H_HEADER_LEN;
+ log_fmt = (const struct rtw89_fw_c2h_log_fmt *)buf;
+
+ if (len < RTW89_C2H_FW_FORMATTED_LOG_MIN_LEN)
+ goto plain_log;
+
+ if (log_fmt->signature != cpu_to_le16(RTW89_C2H_FW_LOG_SIGNATURE))
+ goto plain_log;
+
+ if (!rtwdev->fw.log.fmts)
+ return;
+
+ para_int = u8_get_bits(log_fmt->feature, RTW89_C2H_FW_LOG_FEATURE_PARA_INT);
+ fmt_idx = rtw89_fw_log_get_fmt_idx(rtwdev, le32_to_cpu(log_fmt->fmt_id));
+
+ if (!para_int && log_fmt->argc != 0 && fmt_idx != 0)
+ rtw89_info(rtwdev, "C2H log: %s%s",
+ (*rtwdev->fw.log.fmts)[fmt_idx], log_fmt->u.raw);
+ else if (fmt_idx != 0 && para_int)
+ rtw89_fw_log_dump_data(rtwdev, log_fmt, fmt_idx, para_int, false);
+ else
+ rtw89_fw_log_dump_data(rtwdev, log_fmt, fmt_idx, para_int, true);
+ return;
+
+plain_log:
+ rtw89_info(rtwdev, "C2H log: %.*s", len, buf);
+
}
#define H2C_CAM_LEN 60
@@ -922,7 +1381,7 @@ int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable)
}
skb_put(skb, H2C_LOG_CFG_LEN);
- SET_LOG_CFG_LEVEL(skb->data, RTW89_FW_LOG_LEVEL_SER);
+ SET_LOG_CFG_LEVEL(skb->data, RTW89_FW_LOG_LEVEL_LOUD);
SET_LOG_CFG_PATH(skb->data, BIT(RTW89_FW_LOG_LEVEL_C2H));
SET_LOG_CFG_COMP(skb->data, comp);
SET_LOG_CFG_COMP_EXT(skb->data, 0);
@@ -1300,7 +1759,8 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
+ rtwvif->sub_entity_idx);
struct sk_buff *skb;
u8 pads[RTW89_PPE_BW_NUM];
u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
@@ -1457,12 +1917,15 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif)
{
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
+ rtwvif->sub_entity_idx);
struct sk_buff *skb;
struct sk_buff *skb_beacon;
u16 tim_offset;
int bcn_total_len;
u16 beacon_rate;
+ void *noa_data;
+ u8 noa_len;
int ret;
if (vif->p2p)
@@ -1479,6 +1942,13 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
return -ENOMEM;
}
+ noa_len = rtw89_p2p_noa_fetch(rtwvif, &noa_data);
+ if (noa_len &&
+ (noa_len <= skb_tailroom(skb_beacon) ||
+ pskb_expand_head(skb_beacon, 0, noa_len, GFP_KERNEL) == 0)) {
+ skb_put_data(skb_beacon, noa_data, noa_len);
+ }
+
bcn_total_len = H2C_BCN_BASE_LEN + skb_beacon->len;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, bcn_total_len);
if (!skb) {
@@ -1903,61 +2373,76 @@ fail:
return ret;
}
-#define H2C_RA_LEN 16
int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi)
{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ struct rtw89_h2c_ra_v1 *h2c_v1;
+ struct rtw89_h2c_ra *h2c;
+ u32 len = sizeof(*h2c);
+ bool format_v1 = false;
struct sk_buff *skb;
- u8 *cmd;
int ret;
- skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_RA_LEN);
+ if (chip->chip_gen == RTW89_CHIP_BE) {
+ len = sizeof(*h2c_v1);
+ format_v1 = true;
+ }
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
rtw89_err(rtwdev, "failed to alloc skb for h2c join\n");
return -ENOMEM;
}
- skb_put(skb, H2C_RA_LEN);
- cmd = skb->data;
+ skb_put(skb, len);
+ h2c = (struct rtw89_h2c_ra *)skb->data;
rtw89_debug(rtwdev, RTW89_DBG_RA,
"ra cmd msk: %llx ", ra->ra_mask);
- RTW89_SET_FWCMD_RA_MODE(cmd, ra->mode_ctrl);
- RTW89_SET_FWCMD_RA_BW_CAP(cmd, ra->bw_cap);
- RTW89_SET_FWCMD_RA_MACID(cmd, ra->macid);
- RTW89_SET_FWCMD_RA_DCM(cmd, ra->dcm_cap);
- RTW89_SET_FWCMD_RA_ER(cmd, ra->er_cap);
- RTW89_SET_FWCMD_RA_INIT_RATE_LV(cmd, ra->init_rate_lv);
- RTW89_SET_FWCMD_RA_UPD_ALL(cmd, ra->upd_all);
- RTW89_SET_FWCMD_RA_SGI(cmd, ra->en_sgi);
- RTW89_SET_FWCMD_RA_LDPC(cmd, ra->ldpc_cap);
- RTW89_SET_FWCMD_RA_STBC(cmd, ra->stbc_cap);
- RTW89_SET_FWCMD_RA_SS_NUM(cmd, ra->ss_num);
- RTW89_SET_FWCMD_RA_GILTF(cmd, ra->giltf);
- RTW89_SET_FWCMD_RA_UPD_BW_NSS_MASK(cmd, ra->upd_bw_nss_mask);
- RTW89_SET_FWCMD_RA_UPD_MASK(cmd, ra->upd_mask);
- RTW89_SET_FWCMD_RA_MASK_0(cmd, FIELD_GET(MASKBYTE0, ra->ra_mask));
- RTW89_SET_FWCMD_RA_MASK_1(cmd, FIELD_GET(MASKBYTE1, ra->ra_mask));
- RTW89_SET_FWCMD_RA_MASK_2(cmd, FIELD_GET(MASKBYTE2, ra->ra_mask));
- RTW89_SET_FWCMD_RA_MASK_3(cmd, FIELD_GET(MASKBYTE3, ra->ra_mask));
- RTW89_SET_FWCMD_RA_MASK_4(cmd, FIELD_GET(MASKBYTE4, ra->ra_mask));
- RTW89_SET_FWCMD_RA_FIX_GILTF_EN(cmd, ra->fix_giltf_en);
- RTW89_SET_FWCMD_RA_FIX_GILTF(cmd, ra->fix_giltf);
-
- if (csi) {
- RTW89_SET_FWCMD_RA_BFEE_CSI_CTL(cmd, 1);
- RTW89_SET_FWCMD_RA_BAND_NUM(cmd, ra->band_num);
- RTW89_SET_FWCMD_RA_CR_TBL_SEL(cmd, ra->cr_tbl_sel);
- RTW89_SET_FWCMD_RA_FIXED_CSI_RATE_EN(cmd, ra->fixed_csi_rate_en);
- RTW89_SET_FWCMD_RA_RA_CSI_RATE_EN(cmd, ra->ra_csi_rate_en);
- RTW89_SET_FWCMD_RA_FIXED_CSI_MCS_SS_IDX(cmd, ra->csi_mcs_ss_idx);
- RTW89_SET_FWCMD_RA_FIXED_CSI_MODE(cmd, ra->csi_mode);
- RTW89_SET_FWCMD_RA_FIXED_CSI_GI_LTF(cmd, ra->csi_gi_ltf);
- RTW89_SET_FWCMD_RA_FIXED_CSI_BW(cmd, ra->csi_bw);
- }
-
+ h2c->w0 = le32_encode_bits(ra->mode_ctrl, RTW89_H2C_RA_W0_MODE) |
+ le32_encode_bits(ra->bw_cap, RTW89_H2C_RA_W0_BW_CAP) |
+ le32_encode_bits(ra->macid, RTW89_H2C_RA_W0_MACID) |
+ le32_encode_bits(ra->dcm_cap, RTW89_H2C_RA_W0_DCM) |
+ le32_encode_bits(ra->er_cap, RTW89_H2C_RA_W0_ER) |
+ le32_encode_bits(ra->init_rate_lv, RTW89_H2C_RA_W0_INIT_RATE_LV) |
+ le32_encode_bits(ra->upd_all, RTW89_H2C_RA_W0_UPD_ALL) |
+ le32_encode_bits(ra->en_sgi, RTW89_H2C_RA_W0_SGI) |
+ le32_encode_bits(ra->ldpc_cap, RTW89_H2C_RA_W0_LDPC) |
+ le32_encode_bits(ra->stbc_cap, RTW89_H2C_RA_W0_STBC) |
+ le32_encode_bits(ra->ss_num, RTW89_H2C_RA_W0_SS_NUM) |
+ le32_encode_bits(ra->giltf, RTW89_H2C_RA_W0_GILTF) |
+ le32_encode_bits(ra->upd_bw_nss_mask, RTW89_H2C_RA_W0_UPD_BW_NSS_MASK) |
+ le32_encode_bits(ra->upd_mask, RTW89_H2C_RA_W0_UPD_MASK);
+ h2c->w1 = le32_encode_bits(ra->ra_mask, RTW89_H2C_RA_W1_RAMASK_LO32);
+ h2c->w2 = le32_encode_bits(ra->ra_mask >> 32, RTW89_H2C_RA_W2_RAMASK_HI32);
+ h2c->w3 = le32_encode_bits(ra->fix_giltf_en, RTW89_H2C_RA_W3_FIX_GILTF_EN) |
+ le32_encode_bits(ra->fix_giltf, RTW89_H2C_RA_W3_FIX_GILTF);
+
+ if (!format_v1)
+ goto csi;
+
+ h2c_v1 = (struct rtw89_h2c_ra_v1 *)h2c;
+ h2c_v1->w4 = le32_encode_bits(ra->mode_ctrl, RTW89_H2C_RA_V1_W4_MODE_EHT) |
+ le32_encode_bits(ra->bw_cap, RTW89_H2C_RA_V1_W4_BW_EHT);
+
+csi:
+ if (!csi)
+ goto done;
+
+ h2c->w2 |= le32_encode_bits(1, RTW89_H2C_RA_W2_BFEE_CSI_CTL);
+ h2c->w3 |= le32_encode_bits(ra->band_num, RTW89_H2C_RA_W3_BAND_NUM) |
+ le32_encode_bits(ra->cr_tbl_sel, RTW89_H2C_RA_W3_CR_TBL_SEL) |
+ le32_encode_bits(ra->fixed_csi_rate_en, RTW89_H2C_RA_W3_FIXED_CSI_RATE_EN) |
+ le32_encode_bits(ra->ra_csi_rate_en, RTW89_H2C_RA_W3_RA_CSI_RATE_EN) |
+ le32_encode_bits(ra->csi_mcs_ss_idx, RTW89_H2C_RA_W3_FIXED_CSI_MCS_SS_IDX) |
+ le32_encode_bits(ra->csi_mode, RTW89_H2C_RA_W3_FIXED_CSI_MODE) |
+ le32_encode_bits(ra->csi_gi_ltf, RTW89_H2C_RA_W3_FIXED_CSI_GI_LTF) |
+ le32_encode_bits(ra->csi_bw, RTW89_H2C_RA_W3_FIXED_CSI_BW);
+
+done:
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RA,
H2C_FUNC_OUTSRC_RA_MACIDCFG, 0, 0,
- H2C_RA_LEN);
+ len);
ret = rtw89_h2c_tx(rtwdev, skb, false);
if (ret) {
@@ -2815,12 +3300,13 @@ void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev)
static void rtw89_fw_c2h_parse_attr(struct sk_buff *c2h)
{
+ const struct rtw89_c2h_hdr *hdr = (const struct rtw89_c2h_hdr *)c2h->data;
struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(c2h);
- attr->category = RTW89_GET_C2H_CATEGORY(c2h->data);
- attr->class = RTW89_GET_C2H_CLASS(c2h->data);
- attr->func = RTW89_GET_C2H_FUNC(c2h->data);
- attr->len = RTW89_GET_C2H_LEN(c2h->data);
+ attr->category = le32_get_bits(hdr->w0, RTW89_C2H_HDR_W0_CATEGORY);
+ attr->class = le32_get_bits(hdr->w0, RTW89_C2H_HDR_W0_CLASS);
+ attr->func = le32_get_bits(hdr->w0, RTW89_C2H_HDR_W0_FUNC);
+ attr->len = le32_get_bits(hdr->w1, RTW89_C2H_HDR_W1_LEN);
}
static bool rtw89_fw_c2h_chk_atomic(struct rtw89_dev *rtwdev,
@@ -3377,6 +3863,7 @@ void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
struct ieee80211_scan_request *scan_req)
{
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
struct cfg80211_scan_request *req = &scan_req->req;
u32 rx_fltr = rtwdev->hal.rx_fltr;
u8 mac_addr[ETH_ALEN];
@@ -3399,7 +3886,7 @@ void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
rx_fltr &= ~B_AX_A_BC;
rx_fltr &= ~B_AX_A_A1_MATCH;
rtw89_write32_mask(rtwdev,
- rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0),
+ rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0),
B_AX_RX_FLTR_CFG_MASK,
rx_fltr);
}
@@ -3407,6 +3894,7 @@ void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
bool aborted)
{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
struct cfg80211_scan_info info = {
.aborted = aborted,
@@ -3417,7 +3905,7 @@ void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
return;
rtw89_write32_mask(rtwdev,
- rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0),
+ rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0),
B_AX_RX_FLTR_CFG_MASK,
rtwdev->hal.rx_fltr);
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index 45f927dc212e..775f4e8fbda4 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -291,160 +291,52 @@ struct rtw89_pktofld_info {
bool cancel;
};
-static inline void RTW89_SET_FWCMD_RA_IS_DIS(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(0));
-}
-
-static inline void RTW89_SET_FWCMD_RA_MODE(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(5, 1));
-}
-
-static inline void RTW89_SET_FWCMD_RA_BW_CAP(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(7, 6));
-}
-
-static inline void RTW89_SET_FWCMD_RA_MACID(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(15, 8));
-}
-
-static inline void RTW89_SET_FWCMD_RA_DCM(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(16));
-}
-
-static inline void RTW89_SET_FWCMD_RA_ER(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(17));
-}
-
-static inline void RTW89_SET_FWCMD_RA_INIT_RATE_LV(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(19, 18));
-}
-
-static inline void RTW89_SET_FWCMD_RA_UPD_ALL(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(20));
-}
-
-static inline void RTW89_SET_FWCMD_RA_SGI(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(21));
-}
-
-static inline void RTW89_SET_FWCMD_RA_LDPC(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(22));
-}
-
-static inline void RTW89_SET_FWCMD_RA_STBC(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(23));
-}
-
-static inline void RTW89_SET_FWCMD_RA_SS_NUM(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(26, 24));
-}
-
-static inline void RTW89_SET_FWCMD_RA_GILTF(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(29, 27));
-}
-
-static inline void RTW89_SET_FWCMD_RA_UPD_BW_NSS_MASK(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(30));
-}
-
-static inline void RTW89_SET_FWCMD_RA_UPD_MASK(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(31));
-}
-
-static inline void RTW89_SET_FWCMD_RA_MASK_0(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x01, val, GENMASK(7, 0));
-}
-
-static inline void RTW89_SET_FWCMD_RA_MASK_1(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x01, val, GENMASK(15, 8));
-}
-
-static inline void RTW89_SET_FWCMD_RA_MASK_2(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x01, val, GENMASK(23, 16));
-}
-
-static inline void RTW89_SET_FWCMD_RA_MASK_3(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x01, val, GENMASK(31, 24));
-}
-
-static inline void RTW89_SET_FWCMD_RA_MASK_4(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x02, val, GENMASK(7, 0));
-}
-
-static inline void RTW89_SET_FWCMD_RA_BFEE_CSI_CTL(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x02, val, BIT(31));
-}
-
-static inline void RTW89_SET_FWCMD_RA_BAND_NUM(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x03, val, GENMASK(7, 0));
-}
-
-static inline void RTW89_SET_FWCMD_RA_RA_CSI_RATE_EN(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x03, val, BIT(8));
-}
-
-static inline void RTW89_SET_FWCMD_RA_FIXED_CSI_RATE_EN(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x03, val, BIT(9));
-}
-
-static inline void RTW89_SET_FWCMD_RA_CR_TBL_SEL(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x03, val, BIT(10));
-}
-
-static inline void RTW89_SET_FWCMD_RA_FIX_GILTF_EN(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x03, val, BIT(11));
-}
-
-static inline void RTW89_SET_FWCMD_RA_FIX_GILTF(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x03, val, GENMASK(14, 12));
-}
-
-static inline void RTW89_SET_FWCMD_RA_FIXED_CSI_MCS_SS_IDX(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x03, val, GENMASK(23, 16));
-}
-
-static inline void RTW89_SET_FWCMD_RA_FIXED_CSI_MODE(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x03, val, GENMASK(25, 24));
-}
+struct rtw89_h2c_ra {
+ __le32 w0;
+ __le32 w1;
+ __le32 w2;
+ __le32 w3;
+} __packed;
-static inline void RTW89_SET_FWCMD_RA_FIXED_CSI_GI_LTF(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x03, val, GENMASK(28, 26));
-}
+#define RTW89_H2C_RA_W0_IS_DIS BIT(0)
+#define RTW89_H2C_RA_W0_MODE GENMASK(5, 1)
+#define RTW89_H2C_RA_W0_BW_CAP GENMASK(7, 6)
+#define RTW89_H2C_RA_W0_MACID GENMASK(15, 8)
+#define RTW89_H2C_RA_W0_DCM BIT(16)
+#define RTW89_H2C_RA_W0_ER BIT(17)
+#define RTW89_H2C_RA_W0_INIT_RATE_LV GENMASK(19, 18)
+#define RTW89_H2C_RA_W0_UPD_ALL BIT(20)
+#define RTW89_H2C_RA_W0_SGI BIT(21)
+#define RTW89_H2C_RA_W0_LDPC BIT(22)
+#define RTW89_H2C_RA_W0_STBC BIT(23)
+#define RTW89_H2C_RA_W0_SS_NUM GENMASK(26, 24)
+#define RTW89_H2C_RA_W0_GILTF GENMASK(29, 27)
+#define RTW89_H2C_RA_W0_UPD_BW_NSS_MASK BIT(30)
+#define RTW89_H2C_RA_W0_UPD_MASK BIT(31)
+#define RTW89_H2C_RA_W1_RAMASK_LO32 GENMASK(31, 0)
+#define RTW89_H2C_RA_W2_RAMASK_HI32 GENMASK(30, 0)
+#define RTW89_H2C_RA_W2_BFEE_CSI_CTL BIT(31)
+#define RTW89_H2C_RA_W3_BAND_NUM GENMASK(7, 0)
+#define RTW89_H2C_RA_W3_RA_CSI_RATE_EN BIT(8)
+#define RTW89_H2C_RA_W3_FIXED_CSI_RATE_EN BIT(9)
+#define RTW89_H2C_RA_W3_CR_TBL_SEL BIT(10)
+#define RTW89_H2C_RA_W3_FIX_GILTF_EN BIT(11)
+#define RTW89_H2C_RA_W3_FIX_GILTF GENMASK(14, 12)
+#define RTW89_H2C_RA_W3_FIXED_CSI_MCS_SS_IDX GENMASK(23, 16)
+#define RTW89_H2C_RA_W3_FIXED_CSI_MODE GENMASK(25, 24)
+#define RTW89_H2C_RA_W3_FIXED_CSI_GI_LTF GENMASK(28, 26)
+#define RTW89_H2C_RA_W3_FIXED_CSI_BW GENMASK(31, 29)
+
+struct rtw89_h2c_ra_v1 {
+ struct rtw89_h2c_ra v0;
+ __le32 w4;
+ __le32 w5;
+} __packed;
-static inline void RTW89_SET_FWCMD_RA_FIXED_CSI_BW(void *cmd, u32 val)
-{
- le32p_replace_bits((__le32 *)(cmd) + 0x03, val, GENMASK(31, 29));
-}
+#define RTW89_H2C_RA_V1_W4_MODE_EHT GENMASK(6, 0)
+#define RTW89_H2C_RA_V1_W4_BW_EHT GENMASK(10, 8)
+#define RTW89_H2C_RA_V1_W4_RAMASK_UHL16 GENMASK(31, 16)
+#define RTW89_H2C_RA_V1_W5_RAMASK_UHH16 GENMASK(15, 0)
static inline void RTW89_SET_FWCMD_SEC_IDX(void *cmd, u32 val)
{
@@ -571,7 +463,9 @@ struct rtw89_fw_hdr {
#define FW_HDR_W1_MINOR_VERSION GENMASK(15, 8)
#define FW_HDR_W1_SUBVERSION GENMASK(23, 16)
#define FW_HDR_W1_SUBINDEX GENMASK(31, 24)
+#define FW_HDR_W2_COMMITID GENMASK(31, 0)
#define FW_HDR_W3_LEN GENMASK(23, 16)
+#define FW_HDR_W3_HDR_VER GENMASK(31, 24)
#define FW_HDR_W4_MONTH GENMASK(7, 0)
#define FW_HDR_W4_DATE GENMASK(15, 8)
#define FW_HDR_W4_HOUR GENMASK(23, 16)
@@ -581,6 +475,54 @@ struct rtw89_fw_hdr {
#define FW_HDR_W7_DYN_HDR BIT(16)
#define FW_HDR_W7_CMD_VERSERION GENMASK(31, 24)
+struct rtw89_fw_hdr_section_v1 {
+ __le32 w0;
+ __le32 w1;
+ __le32 w2;
+ __le32 w3;
+} __packed;
+
+#define FWSECTION_HDR_V1_W0_DL_ADDR GENMASK(31, 0)
+#define FWSECTION_HDR_V1_W1_METADATA GENMASK(31, 24)
+#define FWSECTION_HDR_V1_W1_SECTIONTYPE GENMASK(27, 24)
+#define FWSECTION_HDR_V1_W1_SEC_SIZE GENMASK(23, 0)
+#define FWSECTION_HDR_V1_W1_CHECKSUM BIT(28)
+#define FWSECTION_HDR_V1_W1_REDL BIT(29)
+#define FWSECTION_HDR_V1_W2_MSSC GENMASK(7, 0)
+#define FWSECTION_HDR_V1_W2_BBMCU_IDX GENMASK(27, 24)
+
+struct rtw89_fw_hdr_v1 {
+ __le32 w0;
+ __le32 w1;
+ __le32 w2;
+ __le32 w3;
+ __le32 w4;
+ __le32 w5;
+ __le32 w6;
+ __le32 w7;
+ __le32 w8;
+ __le32 w9;
+ __le32 w10;
+ __le32 w11;
+ struct rtw89_fw_hdr_section_v1 sections[];
+} __packed;
+
+#define FW_HDR_V1_W1_MAJOR_VERSION GENMASK(7, 0)
+#define FW_HDR_V1_W1_MINOR_VERSION GENMASK(15, 8)
+#define FW_HDR_V1_W1_SUBVERSION GENMASK(23, 16)
+#define FW_HDR_V1_W1_SUBINDEX GENMASK(31, 24)
+#define FW_HDR_V1_W2_COMMITID GENMASK(31, 0)
+#define FW_HDR_V1_W3_CMD_VERSERION GENMASK(23, 16)
+#define FW_HDR_V1_W3_HDR_VER GENMASK(31, 24)
+#define FW_HDR_V1_W4_MONTH GENMASK(7, 0)
+#define FW_HDR_V1_W4_DATE GENMASK(15, 8)
+#define FW_HDR_V1_W4_HOUR GENMASK(23, 16)
+#define FW_HDR_V1_W4_MIN GENMASK(31, 24)
+#define FW_HDR_V1_W5_YEAR GENMASK(15, 0)
+#define FW_HDR_V1_W5_HDR_SIZE GENMASK(31, 16)
+#define FW_HDR_V1_W6_SEC_NUM GENMASK(15, 8)
+#define FW_HDR_V1_W7_DYN_HDR BIT(16)
+
static inline void SET_FW_HDR_PART_SIZE(void *fwhdr, u32 val)
{
le32p_replace_bits((__le32 *)fwhdr + 7, val, GENMASK(15, 0));
@@ -3209,14 +3151,15 @@ inline void RTW89_SET_FWCMD_MCC_SET_DURATION_DURATION_Y(void *cmd, u32 val)
#define RTW89_C2H_HEADER_LEN 8
-#define RTW89_GET_C2H_CATEGORY(c2h) \
- le32_get_bits(*((const __le32 *)c2h), GENMASK(1, 0))
-#define RTW89_GET_C2H_CLASS(c2h) \
- le32_get_bits(*((const __le32 *)c2h), GENMASK(7, 2))
-#define RTW89_GET_C2H_FUNC(c2h) \
- le32_get_bits(*((const __le32 *)c2h), GENMASK(15, 8))
-#define RTW89_GET_C2H_LEN(c2h) \
- le32_get_bits(*((const __le32 *)(c2h) + 1), GENMASK(13, 0))
+struct rtw89_c2h_hdr {
+ __le32 w0;
+ __le32 w1;
+} __packed;
+
+#define RTW89_C2H_HDR_W0_CATEGORY GENMASK(1, 0)
+#define RTW89_C2H_HDR_W0_CLASS GENMASK(7, 2)
+#define RTW89_C2H_HDR_W0_FUNC GENMASK(15, 8)
+#define RTW89_C2H_HDR_W1_LEN GENMASK(13, 0)
struct rtw89_fw_c2h_attr {
u8 category;
@@ -3232,9 +3175,6 @@ static inline struct rtw89_fw_c2h_attr *RTW89_SKB_C2H_CB(struct sk_buff *skb)
return (struct rtw89_fw_c2h_attr *)skb->cb;
}
-#define RTW89_GET_C2H_LOG_SRT_PRT(c2h) (char *)((__le32 *)(c2h) + 2)
-#define RTW89_GET_C2H_LOG_LEN(len) ((len) - RTW89_C2H_HEADER_LEN)
-
struct rtw89_c2h_done_ack {
__le32 w0;
__le32 w1;
@@ -3256,6 +3196,26 @@ struct rtw89_c2h_done_ack {
#define RTW89_GET_MAC_C2H_REV_ACK_H2C_SEQ(c2h) \
le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(23, 16))
+struct rtw89_fw_c2h_log_fmt {
+ __le16 signature;
+ u8 feature;
+ u8 syntax;
+ __le32 fmt_id;
+ u8 file_num;
+ __le16 line_num;
+ u8 argc;
+ union {
+ DECLARE_FLEX_ARRAY(u8, raw);
+ DECLARE_FLEX_ARRAY(__le32, argv);
+ } __packed u;
+} __packed;
+
+#define RTW89_C2H_FW_FORMATTED_LOG_MIN_LEN 11
+#define RTW89_C2H_FW_LOG_FEATURE_PARA_INT BIT(2)
+#define RTW89_C2H_FW_LOG_MAX_PARA_NUM 16
+#define RTW89_C2H_FW_LOG_SIGNATURE 0xA5A5
+#define RTW89_C2H_FW_LOG_STR_BUF_SIZE 512
+
struct rtw89_c2h_mac_bcnfltr_rpt {
__le32 w0;
__le32 w1;
@@ -3267,24 +3227,32 @@ struct rtw89_c2h_mac_bcnfltr_rpt {
#define RTW89_C2H_MAC_BCNFLTR_RPT_W2_EVENT GENMASK(11, 10)
#define RTW89_C2H_MAC_BCNFLTR_RPT_W2_MA GENMASK(23, 16)
-#define RTW89_GET_PHY_C2H_RA_RPT_MACID(c2h) \
- le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(15, 0))
-#define RTW89_GET_PHY_C2H_RA_RPT_RETRY_RATIO(c2h) \
- le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(23, 16))
-#define RTW89_GET_PHY_C2H_RA_RPT_MCSNSS(c2h) \
- le32_get_bits(*((const __le32 *)(c2h) + 3), GENMASK(6, 0))
-#define RTW89_GET_PHY_C2H_RA_RPT_MD_SEL(c2h) \
- le32_get_bits(*((const __le32 *)(c2h) + 3), GENMASK(9, 8))
-#define RTW89_GET_PHY_C2H_RA_RPT_GILTF(c2h) \
- le32_get_bits(*((const __le32 *)(c2h) + 3), GENMASK(12, 10))
-#define RTW89_GET_PHY_C2H_RA_RPT_BW(c2h) \
- le32_get_bits(*((const __le32 *)(c2h) + 3), GENMASK(14, 13))
-
-/* VHT, HE, HT-old: [6:4]: NSS, [3:0]: MCS
- * HT-new: [6:5]: NA, [4:0]: MCS
+struct rtw89_c2h_ra_rpt {
+ struct rtw89_c2h_hdr hdr;
+ __le32 w2;
+ __le32 w3;
+} __packed;
+
+#define RTW89_C2H_RA_RPT_W2_MACID GENMASK(15, 0)
+#define RTW89_C2H_RA_RPT_W2_RETRY_RATIO GENMASK(23, 16)
+#define RTW89_C2H_RA_RPT_W2_MCSNSS_B7 BIT(31)
+#define RTW89_C2H_RA_RPT_W3_MCSNSS GENMASK(6, 0)
+#define RTW89_C2H_RA_RPT_W3_MD_SEL GENMASK(9, 8)
+#define RTW89_C2H_RA_RPT_W3_GILTF GENMASK(12, 10)
+#define RTW89_C2H_RA_RPT_W3_BW GENMASK(14, 13)
+#define RTW89_C2H_RA_RPT_W3_MD_SEL_B2 BIT(15)
+#define RTW89_C2H_RA_RPT_W3_BW_B2 BIT(16)
+
+/* For WiFi 6 chips:
+ * VHT, HE, HT-old: [6:4]: NSS, [3:0]: MCS
+ * HT-new: [6:5]: NA, [4:0]: MCS
+ * For WiFi 7 chips (V1):
+ * HT, VHT, HE, EHT: [7:5]: NSS, [4:0]: MCS
*/
#define RTW89_RA_RATE_MASK_NSS GENMASK(6, 4)
#define RTW89_RA_RATE_MASK_MCS GENMASK(3, 0)
+#define RTW89_RA_RATE_MASK_NSS_V1 GENMASK(7, 5)
+#define RTW89_RA_RATE_MASK_MCS_V1 GENMASK(4, 0)
#define RTW89_RA_RATE_MASK_HT_MCS GENMASK(4, 0)
#define RTW89_MK_HT_RATE(nss, mcs) (FIELD_PREP(GENMASK(4, 3), nss) | \
FIELD_PREP(GENMASK(2, 0), mcs))
@@ -3426,6 +3394,51 @@ struct rtw89_mfw_hdr {
struct rtw89_mfw_info info[];
} __packed;
+struct rtw89_fw_logsuit_hdr {
+ __le32 rsvd;
+ __le32 count;
+ __le32 ids[];
+} __packed;
+
+#define RTW89_FW_ELEMENT_ALIGN 16
+
+enum rtw89_fw_element_id {
+ RTW89_FW_ELEMENT_ID_BBMCU0 = 0,
+ RTW89_FW_ELEMENT_ID_BBMCU1 = 1,
+ RTW89_FW_ELEMENT_ID_BB_REG = 2,
+ RTW89_FW_ELEMENT_ID_BB_GAIN = 3,
+ RTW89_FW_ELEMENT_ID_RADIO_A = 4,
+ RTW89_FW_ELEMENT_ID_RADIO_B = 5,
+ RTW89_FW_ELEMENT_ID_RADIO_C = 6,
+ RTW89_FW_ELEMENT_ID_RADIO_D = 7,
+ RTW89_FW_ELEMENT_ID_RF_NCTL = 8,
+
+ RTW89_FW_ELEMENT_ID_NUM,
+};
+
+struct rtw89_fw_element_hdr {
+ __le32 id; /* enum rtw89_fw_element_id */
+ __le32 size; /* exclude header size */
+ u8 ver[4];
+ __le32 rsvd0;
+ __le32 rsvd1;
+ __le32 rsvd2;
+ union {
+ struct {
+ u8 priv[8];
+ u8 contents[];
+ } __packed common;
+ struct {
+ u8 idx;
+ u8 rsvd[7];
+ struct {
+ __le32 addr;
+ __le32 data;
+ } __packed regs[];
+ } __packed reg2;
+ } __packed u;
+} __packed;
+
struct fwcmd_hdr {
__le32 hdr0;
__le32 hdr1;
@@ -3607,6 +3620,7 @@ struct rtw89_fw_h2c_rf_get_mccch {
int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev);
int rtw89_fw_recognize(struct rtw89_dev *rtwdev);
+int rtw89_fw_recognize_elements(struct rtw89_dev *rtwdev);
const struct firmware *
rtw89_early_fw_feature_recognize(struct device *device,
const struct rtw89_chip_info *chip,
@@ -3616,6 +3630,8 @@ int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type);
void rtw89_load_firmware_work(struct work_struct *work);
void rtw89_unload_firmware(struct rtw89_dev *rtwdev);
int rtw89_wait_firmware_completion(struct rtw89_dev *rtwdev);
+int rtw89_fw_log_prepare(struct rtw89_dev *rtwdev);
+void rtw89_fw_log_dump(struct rtw89_dev *rtwdev, u8 *buf, u32 len);
void rtw89_h2c_pkt_set_hdr(struct rtw89_dev *rtwdev, struct sk_buff *skb,
u8 type, u8 cat, u8 class, u8 func,
bool rack, bool dack, u32 len);
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index b114babec698..fab9f5004a75 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -12,7 +12,7 @@
#include "reg.h"
#include "util.h"
-const u32 rtw89_mac_mem_base_addrs[RTW89_MAC_MEM_NUM] = {
+static const u32 rtw89_mac_mem_base_addrs_ax[RTW89_MAC_MEM_NUM] = {
[RTW89_MAC_MEM_AXIDMA] = AXIDMA_BASE_ADDR,
[RTW89_MAC_MEM_SHARED_BUF] = SHARED_BUF_BASE_ADDR,
[RTW89_MAC_MEM_DMAC_TBL] = DMAC_TBL_BASE_ADDR,
@@ -39,19 +39,21 @@ const u32 rtw89_mac_mem_base_addrs[RTW89_MAC_MEM_NUM] = {
static void rtw89_mac_mem_write(struct rtw89_dev *rtwdev, u32 offset,
u32 val, enum rtw89_mac_mem_sel sel)
{
- u32 addr = rtw89_mac_mem_base_addrs[sel] + offset;
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+ u32 addr = mac->mem_base_addrs[sel] + offset;
- rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, addr);
- rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY, val);
+ rtw89_write32(rtwdev, mac->filter_model_addr, addr);
+ rtw89_write32(rtwdev, mac->indir_access_addr, val);
}
static u32 rtw89_mac_mem_read(struct rtw89_dev *rtwdev, u32 offset,
enum rtw89_mac_mem_sel sel)
{
- u32 addr = rtw89_mac_mem_base_addrs[sel] + offset;
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+ u32 addr = mac->mem_base_addrs[sel] + offset;
- rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, addr);
- return rtw89_read32(rtwdev, R_AX_INDIR_ACCESS_ENTRY);
+ rtw89_write32(rtwdev, mac->filter_model_addr, addr);
+ return rtw89_read32(rtwdev, mac->indir_access_addr);
}
int rtw89_mac_check_mac_en(struct rtw89_dev *rtwdev, u8 mac_idx,
@@ -2082,7 +2084,7 @@ static int addr_cam_init(struct rtw89_dev *rtwdev, u8 mac_idx)
if (ret)
return ret;
- reg = rtw89_mac_reg_by_idx(R_AX_ADDR_CAM_CTRL, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_ADDR_CAM_CTRL, mac_idx);
val = rtw89_read32(rtwdev, reg);
val |= u32_encode_bits(0x7f, B_AX_ADDR_CAM_RANGE_MASK) |
@@ -2109,7 +2111,7 @@ static int scheduler_init(struct rtw89_dev *rtwdev, u8 mac_idx)
if (ret)
return ret;
- reg = rtw89_mac_reg_by_idx(R_AX_PREBKF_CFG_1, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PREBKF_CFG_1, mac_idx);
if (rtwdev->chip->chip_id == RTL8852C)
rtw89_write32_mask(rtwdev, reg, B_AX_SIFS_MACTXEN_T1_MASK,
SIFS_MACTXEN_T1_V1);
@@ -2118,14 +2120,14 @@ static int scheduler_init(struct rtw89_dev *rtwdev, u8 mac_idx)
SIFS_MACTXEN_T1);
if (rtwdev->chip->chip_id == RTL8852B || rtwdev->chip->chip_id == RTL8851B) {
- reg = rtw89_mac_reg_by_idx(R_AX_SCH_EXT_CTRL, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_SCH_EXT_CTRL, mac_idx);
rtw89_write32_set(rtwdev, reg, B_AX_PORT_RST_TSF_ADV);
}
- reg = rtw89_mac_reg_by_idx(R_AX_CCA_CFG_0, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_CCA_CFG_0, mac_idx);
rtw89_write32_clr(rtwdev, reg, B_AX_BTCCA_EN);
- reg = rtw89_mac_reg_by_idx(R_AX_PREBKF_CFG_0, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PREBKF_CFG_0, mac_idx);
if (rtwdev->chip->chip_id == RTL8852C) {
val = rtw89_read32_mask(rtwdev, R_AX_SEC_ENG_CTRL,
B_AX_TX_PARTIAL_MODE);
@@ -2165,13 +2167,13 @@ int rtw89_mac_typ_fltr_opt(struct rtw89_dev *rtwdev,
switch (type) {
case RTW89_MGNT:
- reg = rtw89_mac_reg_by_idx(R_AX_MGNT_FLTR, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_MGNT_FLTR, mac_idx);
break;
case RTW89_CTRL:
- reg = rtw89_mac_reg_by_idx(R_AX_CTRL_FLTR, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_CTRL_FLTR, mac_idx);
break;
case RTW89_DATA:
- reg = rtw89_mac_reg_by_idx(R_AX_DATA_FLTR, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_DATA_FLTR, mac_idx);
break;
default:
rtw89_err(rtwdev, "[ERR]set rx filter type err\n");
@@ -2202,9 +2204,9 @@ static int rx_fltr_init(struct rtw89_dev *rtwdev, u8 mac_idx)
B_AX_LSIG_PARITY_CHK_EN | B_AX_SIGA_CRC_CHK |
B_AX_VHT_SU_SIGB_CRC_CHK | B_AX_VHT_MU_SIGB_CRC_CHK |
B_AX_HE_SIGB_CRC_CHK;
- rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, mac_idx),
+ rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(rtwdev, R_AX_RX_FLTR_OPT, mac_idx),
mac_ftlr);
- rtw89_write16(rtwdev, rtw89_mac_reg_by_idx(R_AX_PLCP_HDR_FLTR, mac_idx),
+ rtw89_write16(rtwdev, rtw89_mac_reg_by_idx(rtwdev, R_AX_PLCP_HDR_FLTR, mac_idx),
plcp_ftlr);
return 0;
@@ -2224,20 +2226,20 @@ static void _patch_dis_resp_chk(struct rtw89_dev *rtwdev, u8 mac_idx)
switch (rtwdev->chip->chip_id) {
case RTL8852A:
case RTL8852B:
- reg = rtw89_mac_reg_by_idx(R_AX_RSP_CHK_SIG, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RSP_CHK_SIG, mac_idx);
val32 = rtw89_read32(rtwdev, reg) & ~b_rsp_chk_nav;
rtw89_write32(rtwdev, reg, val32);
- reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_0, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_0, mac_idx);
val32 = rtw89_read32(rtwdev, reg) & ~b_rsp_chk_cca;
rtw89_write32(rtwdev, reg, val32);
break;
default:
- reg = rtw89_mac_reg_by_idx(R_AX_RSP_CHK_SIG, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RSP_CHK_SIG, mac_idx);
val32 = rtw89_read32(rtwdev, reg) | b_rsp_chk_nav;
rtw89_write32(rtwdev, reg, val32);
- reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_0, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_0, mac_idx);
val32 = rtw89_read32(rtwdev, reg) | b_rsp_chk_cca;
rtw89_write32(rtwdev, reg, val32);
break;
@@ -2253,7 +2255,7 @@ static int cca_ctrl_init(struct rtw89_dev *rtwdev, u8 mac_idx)
if (ret)
return ret;
- reg = rtw89_mac_reg_by_idx(R_AX_CCA_CONTROL, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_CCA_CONTROL, mac_idx);
val = rtw89_read32(rtwdev, reg);
val |= (B_AX_TB_CHK_BASIC_NAV | B_AX_TB_CHK_BTCCA |
B_AX_TB_CHK_EDCCA | B_AX_TB_CHK_CCA_P20 |
@@ -2294,7 +2296,7 @@ static int spatial_reuse_init(struct rtw89_dev *rtwdev, u8 mac_idx)
ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
if (ret)
return ret;
- reg = rtw89_mac_reg_by_idx(R_AX_RX_SR_CTRL, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RX_SR_CTRL, mac_idx);
rtw89_write8_clr(rtwdev, reg, B_AX_SR_EN);
return 0;
@@ -2309,13 +2311,13 @@ static int tmac_init(struct rtw89_dev *rtwdev, u8 mac_idx)
if (ret)
return ret;
- reg = rtw89_mac_reg_by_idx(R_AX_MAC_LOOPBACK, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_MAC_LOOPBACK, mac_idx);
rtw89_write32_clr(rtwdev, reg, B_AX_MACLBK_EN);
- reg = rtw89_mac_reg_by_idx(R_AX_TCR0, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TCR0, mac_idx);
rtw89_write32_mask(rtwdev, reg, B_AX_TCR_UDF_THSD_MASK, TCR_UDF_THSD);
- reg = rtw89_mac_reg_by_idx(R_AX_TXD_FIFO_CTRL, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TXD_FIFO_CTRL, mac_idx);
rtw89_write32_mask(rtwdev, reg, B_AX_TXDFIFO_HIGH_MCS_THRE_MASK, TXDFIFO_HIGH_MCS_THRE);
rtw89_write32_mask(rtwdev, reg, B_AX_TXDFIFO_LOW_MCS_THRE_MASK, TXDFIFO_LOW_MCS_THRE);
@@ -2333,7 +2335,7 @@ static int trxptcl_init(struct rtw89_dev *rtwdev, u8 mac_idx)
if (ret)
return ret;
- reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_0, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_0, mac_idx);
val = rtw89_read32(rtwdev, reg);
val &= ~B_AX_WMAC_SPEC_SIFS_CCK_MASK;
val |= FIELD_PREP(B_AX_WMAC_SPEC_SIFS_CCK_MASK, WMAC_SPEC_SIFS_CCK);
@@ -2353,12 +2355,12 @@ static int trxptcl_init(struct rtw89_dev *rtwdev, u8 mac_idx)
val |= FIELD_PREP(B_AX_WMAC_SPEC_SIFS_OFDM_MASK, sifs);
rtw89_write32(rtwdev, reg, val);
- reg = rtw89_mac_reg_by_idx(R_AX_RXTRIG_TEST_USER_2, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RXTRIG_TEST_USER_2, mac_idx);
rtw89_write32_set(rtwdev, reg, B_AX_RXTRIG_FCSCHK_EN);
- reg = rtw89_mac_reg_by_idx(rrsr->ref_rate.addr, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, rrsr->ref_rate.addr, mac_idx);
rtw89_write32_mask(rtwdev, reg, rrsr->ref_rate.mask, rrsr->ref_rate.data);
- reg = rtw89_mac_reg_by_idx(rrsr->rsc.addr, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, rrsr->rsc.addr, mac_idx);
rtw89_write32_mask(rtwdev, reg, rrsr->rsc.mask, rrsr->rsc.data);
return 0;
@@ -2397,10 +2399,10 @@ static int rmac_init(struct rtw89_dev *rtwdev, u8 mac_idx)
if (mac_idx == RTW89_MAC_0)
rst_bacam(rtwdev);
- reg = rtw89_mac_reg_by_idx(R_AX_RESPBA_CAM_CTRL, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RESPBA_CAM_CTRL, mac_idx);
rtw89_write8_set(rtwdev, reg, B_AX_SSN_SEL);
- reg = rtw89_mac_reg_by_idx(R_AX_DLK_PROTECT_CTL, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_DLK_PROTECT_CTL, mac_idx);
val = rtw89_read16(rtwdev, reg);
val = u16_replace_bits(val, TRXCFG_RMAC_DATA_TO,
B_AX_RX_DLK_DATA_TIME_MASK);
@@ -2408,10 +2410,10 @@ static int rmac_init(struct rtw89_dev *rtwdev, u8 mac_idx)
B_AX_RX_DLK_CCA_TIME_MASK);
rtw89_write16(rtwdev, reg, val);
- reg = rtw89_mac_reg_by_idx(R_AX_RCR, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RCR, mac_idx);
rtw89_write8_mask(rtwdev, reg, B_AX_CH_EN_MASK, 0x1);
- reg = rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RX_FLTR_OPT, mac_idx);
if (mac_idx == RTW89_MAC_0)
rx_qta = rtwdev->mac.dle_info.c0_rx_qta;
else
@@ -2425,13 +2427,13 @@ static int rmac_init(struct rtw89_dev *rtwdev, u8 mac_idx)
if (rtwdev->chip->chip_id == RTL8852A &&
rtwdev->hal.cv == CHIP_CBV) {
rtw89_write16_mask(rtwdev,
- rtw89_mac_reg_by_idx(R_AX_DLK_PROTECT_CTL, mac_idx),
+ rtw89_mac_reg_by_idx(rtwdev, R_AX_DLK_PROTECT_CTL, mac_idx),
B_AX_RX_DLK_CCA_TIME_MASK, 0);
- rtw89_write16_set(rtwdev, rtw89_mac_reg_by_idx(R_AX_RCR, mac_idx),
+ rtw89_write16_set(rtwdev, rtw89_mac_reg_by_idx(rtwdev, R_AX_RCR, mac_idx),
BIT(12));
}
- reg = rtw89_mac_reg_by_idx(R_AX_PLCP_HDR_FLTR, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PLCP_HDR_FLTR, mac_idx);
rtw89_write8_clr(rtwdev, reg, B_AX_VHT_SU_SIGB_CRC_CHK);
return ret;
@@ -2447,7 +2449,7 @@ static int cmac_com_init(struct rtw89_dev *rtwdev, u8 mac_idx)
if (ret)
return ret;
- reg = rtw89_mac_reg_by_idx(R_AX_TX_SUB_CARRIER_VALUE, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TX_SUB_CARRIER_VALUE, mac_idx);
val = rtw89_read32(rtwdev, reg);
val = u32_replace_bits(val, 0, B_AX_TXSC_20M_MASK);
val = u32_replace_bits(val, 0, B_AX_TXSC_40M_MASK);
@@ -2455,7 +2457,7 @@ static int cmac_com_init(struct rtw89_dev *rtwdev, u8 mac_idx)
rtw89_write32(rtwdev, reg, val);
if (chip_id == RTL8852A || chip_id == RTL8852B) {
- reg = rtw89_mac_reg_by_idx(R_AX_PTCL_RRSR1, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PTCL_RRSR1, mac_idx);
rtw89_write32_mask(rtwdev, reg, B_AX_RRSR_RATE_EN_MASK, RRSR_OFDM_CCK_EN);
}
@@ -2485,7 +2487,7 @@ static int ptcl_init(struct rtw89_dev *rtwdev, u8 mac_idx)
return ret;
if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) {
- reg = rtw89_mac_reg_by_idx(R_AX_SIFS_SETTING, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_SIFS_SETTING, mac_idx);
val = rtw89_read32(rtwdev, reg);
val = u32_replace_bits(val, S_AX_CTS2S_TH_1K,
B_AX_HW_CTS2SELF_PKT_LEN_TH_MASK);
@@ -2494,7 +2496,7 @@ static int ptcl_init(struct rtw89_dev *rtwdev, u8 mac_idx)
val |= B_AX_HW_CTS2SELF_EN;
rtw89_write32(rtwdev, reg, val);
- reg = rtw89_mac_reg_by_idx(R_AX_PTCL_FSM_MON, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PTCL_FSM_MON, mac_idx);
val = rtw89_read32(rtwdev, reg);
val = u32_replace_bits(val, S_AX_PTCL_TO_2MS, B_AX_PTCL_TX_ARB_TO_THR_MASK);
val &= ~B_AX_PTCL_TX_ARB_TO_MODE;
@@ -2524,14 +2526,14 @@ static int cmac_dma_init(struct rtw89_dev *rtwdev, u8 mac_idx)
u32 reg;
int ret;
- if (chip_id != RTL8852A && chip_id != RTL8852B)
+ if (chip_id != RTL8852B)
return 0;
ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
if (ret)
return ret;
- reg = rtw89_mac_reg_by_idx(R_AX_RXDMA_CTRL_0, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RXDMA_CTRL_0, mac_idx);
rtw89_write8_clr(rtwdev, reg, RX_FULL_MODE);
return 0;
@@ -2725,7 +2727,7 @@ static int rtw89_hw_sch_tx_en_h2c(struct rtw89_dev *rtwdev, u8 band,
static int rtw89_set_hw_sch_tx_en(struct rtw89_dev *rtwdev, u8 mac_idx,
u16 tx_en, u16 tx_en_mask)
{
- u32 reg = rtw89_mac_reg_by_idx(R_AX_CTN_TXEN, mac_idx);
+ u32 reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_CTN_TXEN, mac_idx);
u16 val;
int ret;
@@ -2747,7 +2749,7 @@ static int rtw89_set_hw_sch_tx_en(struct rtw89_dev *rtwdev, u8 mac_idx,
static int rtw89_set_hw_sch_tx_en_v1(struct rtw89_dev *rtwdev, u8 mac_idx,
u32 tx_en, u32 tx_en_mask)
{
- u32 reg = rtw89_mac_reg_by_idx(R_AX_CTN_DRV_TXEN, mac_idx);
+ u32 reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_CTN_DRV_TXEN, mac_idx);
u32 val;
int ret;
@@ -2768,7 +2770,7 @@ int rtw89_mac_stop_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx,
int ret;
*tx_en = rtw89_read16(rtwdev,
- rtw89_mac_reg_by_idx(R_AX_CTN_TXEN, mac_idx));
+ rtw89_mac_reg_by_idx(rtwdev, R_AX_CTN_TXEN, mac_idx));
switch (sel) {
case RTW89_SCH_TX_SEL_ALL:
@@ -2809,7 +2811,7 @@ int rtw89_mac_stop_sch_tx_v1(struct rtw89_dev *rtwdev, u8 mac_idx,
int ret;
*tx_en = rtw89_read32(rtwdev,
- rtw89_mac_reg_by_idx(R_AX_CTN_DRV_TXEN, mac_idx));
+ rtw89_mac_reg_by_idx(rtwdev, R_AX_CTN_DRV_TXEN, mac_idx));
switch (sel) {
case RTW89_SCH_TX_SEL_ALL:
@@ -3016,7 +3018,7 @@ static int band_idle_ck_b(struct rtw89_dev *rtwdev, u8 mac_idx)
if (ret)
return ret;
- reg = rtw89_mac_reg_by_idx(R_AX_PTCL_TX_CTN_SEL, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PTCL_TX_CTN_SEL, mac_idx);
ret = read_poll_timeout(rtw89_read8, val,
(val & B_AX_PTCL_TX_ON_STAT) == 0,
@@ -3224,7 +3226,7 @@ static void rtw89_scheduler_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx)
{
u32 reg;
- reg = rtw89_mac_reg_by_idx(R_AX_SCHEDULE_ERR_IMR, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_SCHEDULE_ERR_IMR, mac_idx);
rtw89_write32_clr(rtwdev, reg, B_AX_SORT_NON_IDLE_ERR_INT_EN |
B_AX_FSM_TIMEOUT_ERR_INT_EN);
rtw89_write32_set(rtwdev, reg, B_AX_FSM_TIMEOUT_ERR_INT_EN);
@@ -3235,7 +3237,7 @@ static void rtw89_ptcl_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx)
const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
u32 reg;
- reg = rtw89_mac_reg_by_idx(R_AX_PTCL_IMR0, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PTCL_IMR0, mac_idx);
rtw89_write32_clr(rtwdev, reg, imr->ptcl_imr_clr);
rtw89_write32_set(rtwdev, reg, imr->ptcl_imr_set);
}
@@ -3246,12 +3248,12 @@ static void rtw89_cdma_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx)
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
u32 reg;
- reg = rtw89_mac_reg_by_idx(imr->cdma_imr_0_reg, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, imr->cdma_imr_0_reg, mac_idx);
rtw89_write32_clr(rtwdev, reg, imr->cdma_imr_0_clr);
rtw89_write32_set(rtwdev, reg, imr->cdma_imr_0_set);
if (chip_id == RTL8852C) {
- reg = rtw89_mac_reg_by_idx(imr->cdma_imr_1_reg, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, imr->cdma_imr_1_reg, mac_idx);
rtw89_write32_clr(rtwdev, reg, imr->cdma_imr_1_clr);
rtw89_write32_set(rtwdev, reg, imr->cdma_imr_1_set);
}
@@ -3262,7 +3264,7 @@ static void rtw89_phy_intf_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx)
const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
u32 reg;
- reg = rtw89_mac_reg_by_idx(imr->phy_intf_imr_reg, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, imr->phy_intf_imr_reg, mac_idx);
rtw89_write32_clr(rtwdev, reg, imr->phy_intf_imr_clr);
rtw89_write32_set(rtwdev, reg, imr->phy_intf_imr_set);
}
@@ -3272,7 +3274,7 @@ static void rtw89_rmac_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx)
const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
u32 reg;
- reg = rtw89_mac_reg_by_idx(imr->rmac_imr_reg, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, imr->rmac_imr_reg, mac_idx);
rtw89_write32_clr(rtwdev, reg, imr->rmac_imr_clr);
rtw89_write32_set(rtwdev, reg, imr->rmac_imr_set);
}
@@ -3282,7 +3284,7 @@ static void rtw89_tmac_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx)
const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
u32 reg;
- reg = rtw89_mac_reg_by_idx(imr->tmac_imr_reg, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, imr->tmac_imr_reg, mac_idx);
rtw89_write32_clr(rtwdev, reg, imr->tmac_imr_clr);
rtw89_write32_set(rtwdev, reg, imr->tmac_imr_set);
}
@@ -3661,6 +3663,9 @@ static void rtw89_mac_dmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid)
{
u8 i;
+ if (rtwdev->chip->chip_gen != RTW89_CHIP_AX)
+ return;
+
for (i = 0; i < 4; i++) {
rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR,
DMAC_TBL_BASE_ADDR + (macid << 4) + (i << 2));
@@ -3670,6 +3675,9 @@ static void rtw89_mac_dmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid)
static void rtw89_mac_cmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid)
{
+ if (rtwdev->chip->chip_gen != RTW89_CHIP_AX)
+ return;
+
rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR,
CMAC_TBL_BASE_ADDR + macid * CCTL_INFO_SIZE);
rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY, 0x4);
@@ -3860,7 +3868,7 @@ static void rtw89_mac_port_cfg_hiq_win(struct rtw89_dev *rtwdev,
u8 port = rtwvif->port;
u32 reg;
- reg = rtw89_mac_reg_by_idx(hiq_win_addr[port], rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, hiq_win_addr[port], rtwvif->mac_idx);
rtw89_write8(rtwdev, reg, win);
}
@@ -3871,7 +3879,7 @@ static void rtw89_mac_port_cfg_hiq_dtim(struct rtw89_dev *rtwdev,
const struct rtw89_port_reg *p = &rtw_port_base;
u32 addr;
- addr = rtw89_mac_reg_by_idx(R_AX_MD_TSFT_STMP_CTL, rtwvif->mac_idx);
+ addr = rtw89_mac_reg_by_idx(rtwdev, R_AX_MD_TSFT_STMP_CTL, rtwvif->mac_idx);
rtw89_write8_set(rtwdev, addr, B_AX_UPD_HGQMD | B_AX_UPD_TIMIE);
rtw89_write16_port_mask(rtwdev, rtwvif, p->dtim_ctrl, B_AX_DTIM_NUM_MASK,
@@ -3930,7 +3938,7 @@ static void rtw89_mac_port_cfg_bss_color(struct rtw89_dev *rtwdev,
bss_color = vif->bss_conf.he_bss_color.color;
reg_base = port >= 4 ? R_AX_PTCL_BSS_COLOR_1 : R_AX_PTCL_BSS_COLOR_0;
- reg = rtw89_mac_reg_by_idx(reg_base, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, reg_base, rtwvif->mac_idx);
rtw89_write32_mask(rtwdev, reg, masks[port], bss_color);
}
@@ -3944,7 +3952,7 @@ static void rtw89_mac_port_cfg_mbssid(struct rtw89_dev *rtwdev,
return;
if (port == 0) {
- reg = rtw89_mac_reg_by_idx(R_AX_MBSSID_CTRL, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_MBSSID_CTRL, rtwvif->mac_idx);
rtw89_write32_clr(rtwdev, reg, B_AX_P0MB_ALL_MASK);
}
}
@@ -3956,7 +3964,7 @@ static void rtw89_mac_port_cfg_hiq_drop(struct rtw89_dev *rtwdev,
u32 reg;
u32 val;
- reg = rtw89_mac_reg_by_idx(R_AX_MBSSID_DROP_0, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_MBSSID_DROP_0, rtwvif->mac_idx);
val = rtw89_read32(rtwdev, reg);
val &= ~FIELD_PREP(B_AX_PORT_DROP_4_0_MASK, BIT(port));
if (port == 0)
@@ -4014,7 +4022,7 @@ void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev,
u32 val, reg;
val = RTW89_PORT_OFFSET_TU_TO_32US(offset_tu);
- reg = rtw89_mac_reg_by_idx(R_AX_PORT0_TSF_SYNC + rtwvif->port * 4,
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PORT0_TSF_SYNC + rtwvif->port * 4,
rtwvif->mac_idx);
rtw89_write32_mask(rtwdev, reg, B_AX_SYNC_PORT_SRC, rtwvif_src->port);
@@ -4204,7 +4212,7 @@ void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev,
rtw89_mac_check_he_obss_narrow_bw_ru_iter,
&tolerated);
- reg = rtw89_mac_reg_by_idx(R_AX_RXTRIG_TEST_USER_2, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RXTRIG_TEST_USER_2, rtwvif->mac_idx);
if (tolerated)
rtw89_write32_clr(rtwdev, reg, B_AX_RXTRIG_RU26_DIS);
else
@@ -4437,8 +4445,7 @@ rtw89_mac_c2h_done_ack(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h, u32 le
static void
rtw89_mac_c2h_log(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
{
- rtw89_info(rtwdev, "%*s", RTW89_GET_C2H_LOG_LEN(len),
- RTW89_GET_C2H_LOG_SRT_PRT(c2h->data));
+ rtw89_fw_log_dump(rtwdev, c2h->data, len);
}
static void
@@ -4732,7 +4739,7 @@ bool rtw89_mac_get_txpwr_cr(struct rtw89_dev *rtwdev,
{
const struct rtw89_dle_mem *dle_mem = rtwdev->chip->dle_mem;
enum rtw89_qta_mode mode = dle_mem->mode;
- u32 addr = rtw89_mac_reg_by_idx(reg_base, phy_idx);
+ u32 addr = rtw89_mac_reg_by_idx(rtwdev, reg_base, phy_idx);
if (addr < R_AX_PWR_RATE_CTRL || addr > CMAC1_END_ADDR) {
rtw89_err(rtwdev, "[TXPWR] addr=0x%x exceed txpwr cr\n",
@@ -4761,7 +4768,7 @@ EXPORT_SYMBOL(rtw89_mac_get_txpwr_cr);
int rtw89_mac_cfg_ppdu_status(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable)
{
- u32 reg = rtw89_mac_reg_by_idx(R_AX_PPDU_STAT, mac_idx);
+ u32 reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PPDU_STAT, mac_idx);
int ret;
ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
@@ -4808,7 +4815,7 @@ void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev, u8 mac_idx)
time_th = min_t(u32, time_th >> MAC_AX_TIME_TH_SH, MAC_AX_TIME_TH_MAX);
len_th = min_t(u32, len_th >> MAC_AX_LEN_TH_SH, MAC_AX_LEN_TH_MAX);
- reg = rtw89_mac_reg_by_idx(R_AX_AGG_LEN_HT_0, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_AGG_LEN_HT_0, mac_idx);
rtw89_write16_mask(rtwdev, reg, B_AX_RTS_TXTIME_TH_MASK, time_th);
rtw89_write16_mask(rtwdev, reg, B_AX_RTS_LEN_TH_MASK, len_th);
}
@@ -5044,7 +5051,7 @@ int rtw89_mac_cfg_plt(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_plt *plt)
if (ret)
return ret;
- reg = rtw89_mac_reg_by_idx(R_AX_BT_PLT, plt->band);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_BT_PLT, plt->band);
val = (plt->tx & RTW89_MAC_AX_PLT_LTE_RX ? B_AX_TX_PLT_GNT_LTE_RX : 0) |
(plt->tx & RTW89_MAC_AX_PLT_GNT_BT_TX ? B_AX_TX_PLT_GNT_BT_TX : 0) |
(plt->tx & RTW89_MAC_AX_PLT_GNT_BT_RX ? B_AX_TX_PLT_GNT_BT_RX : 0) |
@@ -5134,7 +5141,7 @@ u16 rtw89_mac_get_plt_cnt(struct rtw89_dev *rtwdev, u8 band)
u32 reg;
u16 cnt;
- reg = rtw89_mac_reg_by_idx(R_AX_BT_PLT, band);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_BT_PLT, band);
cnt = rtw89_read32_mask(rtwdev, reg, B_AX_BT_PLT_PKT_CNT_MASK);
rtw89_write16_set(rtwdev, reg, B_AX_BT_PLT_RST);
@@ -5147,7 +5154,7 @@ static void rtw89_mac_bfee_standby_timer(struct rtw89_dev *rtwdev, u8 mac_idx,
u32 reg;
rtw89_debug(rtwdev, RTW89_DBG_BF, "set bfee standby_timer to %d\n", keep);
- reg = rtw89_mac_reg_by_idx(R_AX_BFMEE_RESP_OPTION, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_BFMEE_RESP_OPTION, mac_idx);
if (keep) {
set_bit(RTW89_FLAG_BFEE_TIMER_KEEP, rtwdev->flags);
rtw89_write32_mask(rtwdev, reg, B_AX_BFMEE_BFRP_RX_STANDBY_TIMER_MASK,
@@ -5166,7 +5173,7 @@ static void rtw89_mac_bfee_ctrl(struct rtw89_dev *rtwdev, u8 mac_idx, bool en)
B_AX_BFMEE_HE_NDPA_EN;
rtw89_debug(rtwdev, RTW89_DBG_BF, "set bfee ndpa_en to %d\n", en);
- reg = rtw89_mac_reg_by_idx(R_AX_BFMEE_RESP_OPTION, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_BFMEE_RESP_OPTION, mac_idx);
if (en) {
set_bit(RTW89_FLAG_BFEE_EN, rtwdev->flags);
rtw89_write32_set(rtwdev, reg, mask);
@@ -5188,30 +5195,30 @@ static int rtw89_mac_init_bfee(struct rtw89_dev *rtwdev, u8 mac_idx)
/* AP mode set tx gid to 63 */
/* STA mode set tx gid to 0(default) */
- reg = rtw89_mac_reg_by_idx(R_AX_BFMER_CTRL_0, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_BFMER_CTRL_0, mac_idx);
rtw89_write32_set(rtwdev, reg, B_AX_BFMER_NDP_BFEN);
- reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_RRSC, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_RRSC, mac_idx);
rtw89_write32(rtwdev, reg, CSI_RRSC_BMAP);
- reg = rtw89_mac_reg_by_idx(R_AX_BFMEE_RESP_OPTION, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_BFMEE_RESP_OPTION, mac_idx);
val32 = FIELD_PREP(B_AX_BFMEE_NDP_RX_STANDBY_TIMER_MASK, NDP_RX_STANDBY_TIMER);
rtw89_write32(rtwdev, reg, val32);
rtw89_mac_bfee_standby_timer(rtwdev, mac_idx, true);
rtw89_mac_bfee_ctrl(rtwdev, mac_idx, true);
- reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
rtw89_write32_set(rtwdev, reg, B_AX_BFMEE_BFPARAM_SEL |
B_AX_BFMEE_USE_NSTS |
B_AX_BFMEE_CSI_GID_SEL |
B_AX_BFMEE_CSI_FORCE_RETE_EN);
- reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_RATE, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_RATE, mac_idx);
rtw89_write32(rtwdev, reg,
u32_encode_bits(CSI_INIT_RATE_HT, B_AX_BFMEE_HT_CSI_RATE_MASK) |
u32_encode_bits(CSI_INIT_RATE_VHT, B_AX_BFMEE_VHT_CSI_RATE_MASK) |
u32_encode_bits(CSI_INIT_RATE_HE, B_AX_BFMEE_HE_CSI_RATE_MASK));
- reg = rtw89_mac_reg_by_idx(R_AX_CSIRPT_OPTION, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_CSIRPT_OPTION, mac_idx);
rtw89_write32_set(rtwdev, reg,
B_AX_CSIPRT_VHTSU_AID_EN | B_AX_CSIPRT_HESU_AID_EN);
@@ -5255,7 +5262,7 @@ static int rtw89_mac_set_csi_para_reg(struct rtw89_dev *rtwdev,
nc = min(nc, sound_dim);
nr = min(nr, sound_dim);
- reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
rtw89_write32_set(rtwdev, reg, B_AX_BFMEE_BFPARAM_SEL);
val = FIELD_PREP(B_AX_BFMEE_CSIINFO0_NC_MASK, nc) |
@@ -5267,9 +5274,9 @@ static int rtw89_mac_set_csi_para_reg(struct rtw89_dev *rtwdev,
FIELD_PREP(B_AX_BFMEE_CSIINFO0_STBC_EN, stbc_en);
if (port_sel == 0)
- reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
else
- reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_CTRL_1, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_CTRL_1, mac_idx);
rtw89_write16(rtwdev, reg, val);
@@ -5305,11 +5312,11 @@ static int rtw89_mac_csi_rrsc(struct rtw89_dev *rtwdev,
BIT(RTW89_MAC_BF_RRSC_HT_MSC3) |
BIT(RTW89_MAC_BF_RRSC_HT_MSC5));
}
- reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
rtw89_write32_set(rtwdev, reg, B_AX_BFMEE_BFPARAM_SEL);
rtw89_write32_clr(rtwdev, reg, B_AX_BFMEE_CSI_FORCE_RETE_EN);
rtw89_write32(rtwdev,
- rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_RRSC, mac_idx),
+ rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_RRSC, mac_idx),
rrsc);
return 0;
@@ -5347,19 +5354,21 @@ void rtw89_mac_bf_set_gid_table(struct rtw89_dev *rtwdev, struct ieee80211_vif *
rtw89_debug(rtwdev, RTW89_DBG_BF, "update bf GID table\n");
p = (__le32 *)conf->mu_group.membership;
- rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_GID_POSITION_EN0, mac_idx),
+ rtw89_write32(rtwdev,
+ rtw89_mac_reg_by_idx(rtwdev, R_AX_GID_POSITION_EN0, mac_idx),
le32_to_cpu(p[0]));
- rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_GID_POSITION_EN1, mac_idx),
+ rtw89_write32(rtwdev,
+ rtw89_mac_reg_by_idx(rtwdev, R_AX_GID_POSITION_EN1, mac_idx),
le32_to_cpu(p[1]));
p = (__le32 *)conf->mu_group.position;
- rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_GID_POSITION0, mac_idx),
+ rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(rtwdev, R_AX_GID_POSITION0, mac_idx),
le32_to_cpu(p[0]));
- rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_GID_POSITION1, mac_idx),
+ rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(rtwdev, R_AX_GID_POSITION1, mac_idx),
le32_to_cpu(p[1]));
- rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_GID_POSITION2, mac_idx),
+ rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(rtwdev, R_AX_GID_POSITION2, mac_idx),
le32_to_cpu(p[2]));
- rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_GID_POSITION3, mac_idx),
+ rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(rtwdev, R_AX_GID_POSITION3, mac_idx),
le32_to_cpu(p[3]));
}
@@ -5450,7 +5459,7 @@ __rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
return ret;
}
- reg = rtw89_mac_reg_by_idx(R_AX_AMPDU_AGG_LIMIT, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_AMPDU_AGG_LIMIT, mac_idx);
rtw89_write32_mask(rtwdev, reg, B_AX_AMPDU_MAX_TIME_MASK,
max_tx_time >> 5);
}
@@ -5490,7 +5499,7 @@ int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
return ret;
}
- reg = rtw89_mac_reg_by_idx(R_AX_AMPDU_AGG_LIMIT, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_AMPDU_AGG_LIMIT, mac_idx);
*tx_time = rtw89_read32_mask(rtwdev, reg, B_AX_AMPDU_MAX_TIME_MASK) << 5;
}
@@ -5532,7 +5541,7 @@ int rtw89_mac_get_tx_retry_limit(struct rtw89_dev *rtwdev,
return ret;
}
- reg = rtw89_mac_reg_by_idx(R_AX_TXCNT, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TXCNT, mac_idx);
*tx_retry = rtw89_read32_mask(rtwdev, reg, B_AX_L_TXCNT_LMT_MASK);
}
@@ -5551,7 +5560,7 @@ int rtw89_mac_set_hw_muedca_ctrl(struct rtw89_dev *rtwdev,
if (ret)
return ret;
- reg = rtw89_mac_reg_by_idx(R_AX_MUEDCA_EN, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_MUEDCA_EN, mac_idx);
if (en)
rtw89_write16_set(rtwdev, reg, set);
else
@@ -5674,3 +5683,12 @@ int rtw89_mac_ptk_drop_by_band_and_wait(struct rtw89_dev *rtwdev,
}
return ret;
}
+
+const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
+ .band1_offset = RTW89_MAC_AX_BAND_REG_OFFSET,
+ .filter_model_addr = R_AX_FILTER_MODEL_ADDR,
+ .indir_access_addr = R_AX_INDIR_ACCESS_ENTRY,
+ .mem_base_addrs = rtw89_mac_mem_base_addrs_ax,
+ .rx_fltr = R_AX_RX_FLTR_OPT,
+};
+EXPORT_SYMBOL(rtw89_mac_gen_ax);
diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h
index 0e1570451c2c..7cf34137c0bc 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.h
+++ b/drivers/net/wireless/realtek/rtw89/mac.h
@@ -275,6 +275,7 @@ enum rtw89_mac_dbg_port_sel {
/* SRAM mem dump */
#define R_AX_INDIR_ACCESS_ENTRY 0x40000
+#define R_BE_INDIR_ACCESS_ENTRY 0x80000
#define AXIDMA_BASE_ADDR 0x18006000
#define STA_SCHED_BASE_ADDR 0x18808000
@@ -298,6 +299,31 @@ enum rtw89_mac_dbg_port_sel {
#define TXDATA_FIFO_1_BASE_ADDR 0x188A1000
#define CPU_LOCAL_BASE_ADDR 0x18003000
+#define WD_PAGE_BASE_ADDR_BE 0x0
+#define CPU_LOCAL_BASE_ADDR_BE 0x18003000
+#define AXIDMA_BASE_ADDR_BE 0x18006000
+#define SHARED_BUF_BASE_ADDR_BE 0x18700000
+#define DMAC_TBL_BASE_ADDR_BE 0x18800000
+#define SHCUT_MACHDR_BASE_ADDR_BE 0x18800800
+#define STA_SCHED_BASE_ADDR_BE 0x18818000
+#define NAT25_CAM_BASE_ADDR_BE 0x18820000
+#define RXPLD_FLTR_CAM_BASE_ADDR_BE 0x18823000
+#define SEC_CAM_BASE_ADDR_BE 0x18824000
+#define WOW_CAM_BASE_ADDR_BE 0x18828000
+#define MLD_TBL_BASE_ADDR_BE 0x18829000
+#define RX_CLSF_CAM_BASE_ADDR_BE 0x1882A000
+#define CMAC_TBL_BASE_ADDR_BE 0x18840000
+#define ADDR_CAM_BASE_ADDR_BE 0x18850000
+#define BSSID_CAM_BASE_ADDR_BE 0x18858000
+#define BA_CAM_BASE_ADDR_BE 0x18859000
+#define BCN_IE_CAM0_BASE_ADDR_BE 0x18860000
+#define TXDATA_FIFO_0_BASE_ADDR_BE 0x18861000
+#define TXD_FIFO_0_BASE_ADDR_BE 0x18862000
+#define BCN_IE_CAM1_BASE_ADDR_BE 0x18880000
+#define TXDATA_FIFO_1_BASE_ADDR_BE 0x18881000
+#define TXD_FIFO_1_BASE_ADDR_BE 0x18881800
+#define DCPU_LOCAL_BASE_ADDR_BE 0x19C02000
+
#define CCTL_INFO_SIZE 32
enum rtw89_mac_mem_sel {
@@ -322,13 +348,12 @@ enum rtw89_mac_mem_sel {
RTW89_MAC_MEM_BSSID_CAM,
RTW89_MAC_MEM_TXD_FIFO_0_V1,
RTW89_MAC_MEM_TXD_FIFO_1_V1,
+ RTW89_MAC_MEM_WD_PAGE,
/* keep last */
RTW89_MAC_MEM_NUM,
};
-extern const u32 rtw89_mac_mem_base_addrs[];
-
enum rtw89_rpwm_req_pwr_state {
RTW89_MAC_RPWM_REQ_PWR_STATE_ACTIVE = 0,
RTW89_MAC_RPWM_REQ_PWR_STATE_BAND0_RFON = 1,
@@ -478,6 +503,7 @@ enum rtw89_mac_bf_rrsc_rate {
({typeof(_addr) __addr = (_addr); \
__addr >= R_AX_CMAC_REG_START && __addr <= R_AX_CMAC_REG_END; })
#define RTW89_MAC_AX_BAND_REG_OFFSET 0x2000
+#define RTW89_MAC_BE_BAND_REG_OFFSET 0x4000
#define PTCL_IDLE_POLL_CNT 10000
#define SW_CVR_DUR_US 8
@@ -826,14 +852,29 @@ struct rtw89_mac_size_set {
extern const struct rtw89_mac_size_set rtw89_mac_size;
-static inline u32 rtw89_mac_reg_by_idx(u32 reg_base, u8 band)
+struct rtw89_mac_gen_def {
+ u32 band1_offset;
+ u32 filter_model_addr;
+ u32 indir_access_addr;
+ const u32 *mem_base_addrs;
+ u32 rx_fltr;
+};
+
+extern const struct rtw89_mac_gen_def rtw89_mac_gen_ax;
+extern const struct rtw89_mac_gen_def rtw89_mac_gen_be;
+
+static inline
+u32 rtw89_mac_reg_by_idx(struct rtw89_dev *rtwdev, u32 reg_base, u8 band)
{
- return band == 0 ? reg_base : (reg_base + 0x2000);
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+
+ return band == 0 ? reg_base : (reg_base + mac->band1_offset);
}
-static inline u32 rtw89_mac_reg_by_port(u32 base, u8 port, u8 mac_idx)
+static inline
+u32 rtw89_mac_reg_by_port(struct rtw89_dev *rtwdev, u32 base, u8 port, u8 mac_idx)
{
- return rtw89_mac_reg_by_idx(base + port * 0x40, mac_idx);
+ return rtw89_mac_reg_by_idx(rtwdev, base + port * 0x40, mac_idx);
}
static inline u32
@@ -841,7 +882,7 @@ rtw89_read32_port(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, u32 base)
{
u32 reg;
- reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
return rtw89_read32(rtwdev, reg);
}
@@ -851,7 +892,7 @@ rtw89_read32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
{
u32 reg;
- reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
return rtw89_read32_mask(rtwdev, reg, mask);
}
@@ -861,7 +902,7 @@ rtw89_write32_port(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, u32 base,
{
u32 reg;
- reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
rtw89_write32(rtwdev, reg, data);
}
@@ -871,7 +912,7 @@ rtw89_write32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
{
u32 reg;
- reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
rtw89_write32_mask(rtwdev, reg, mask, data);
}
@@ -881,7 +922,7 @@ rtw89_write16_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
{
u32 reg;
- reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
rtw89_write16_mask(rtwdev, reg, mask, data);
}
@@ -891,7 +932,7 @@ rtw89_write32_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
{
u32 reg;
- reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
rtw89_write32_clr(rtwdev, reg, bit);
}
@@ -901,7 +942,7 @@ rtw89_write16_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
{
u32 reg;
- reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
rtw89_write16_clr(rtwdev, reg, bit);
}
@@ -911,7 +952,7 @@ rtw89_write32_port_set(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
{
u32 reg;
- reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
rtw89_write32_set(rtwdev, reg, bit);
}
diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
index a66503eb35b8..5e48618706d9 100644
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
@@ -224,6 +224,7 @@ static void rtw89_ops_configure_filter(struct ieee80211_hw *hw,
u64 multicast)
{
struct rtw89_dev *rtwdev = hw->priv;
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
mutex_lock(&rtwdev->mutex);
rtw89_leave_ps_mode(rtwdev);
@@ -271,13 +272,13 @@ static void rtw89_ops_configure_filter(struct ieee80211_hw *hw,
}
rtw89_write32_mask(rtwdev,
- rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0),
+ rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0),
B_AX_RX_FLTR_CFG_MASK,
rtwdev->hal.rx_fltr);
if (!rtwdev->dbcc_en)
goto out;
rtw89_write32_mask(rtwdev,
- rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_1),
+ rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_1),
B_AX_RX_FLTR_CFG_MASK,
rtwdev->hal.rx_fltr);
@@ -296,7 +297,8 @@ static u8 rtw89_aifsn_to_aifs(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif, u8 aifsn)
{
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
+ rtwvif->sub_entity_idx);
u8 slot_time;
u8 sifs;
@@ -353,7 +355,7 @@ static void ____rtw89_conf_tx_mu_edca(struct rtw89_dev *rtwdev,
val = FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_TIMER_MASK, timer_32us) |
FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_CW_MASK, mu_edca->ecw_min_max) |
FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_AIFS_MASK, aifs);
- reg = rtw89_mac_reg_by_idx(ac_to_mu_edca_param[ac], rtwvif->mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, ac_to_mu_edca_param[ac], rtwvif->mac_idx);
rtw89_write32(rtwdev, reg, val);
rtw89_mac_set_hw_muedca_ctrl(rtwdev, rtwvif, true);
@@ -413,6 +415,8 @@ static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw,
rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, vif);
rtw89_mac_port_update(rtwdev, rtwvif);
rtw89_mac_set_he_obss_narrow_bw_ru(rtwdev, vif);
+
+ rtw89_queue_chanctx_work(rtwdev);
} else {
/* Abort ongoing scan if cancel_scan isn't issued
* when disconnected by peer
@@ -476,6 +480,8 @@ static int rtw89_ops_start_ap(struct ieee80211_hw *hw,
rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true);
rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL);
rtw89_chip_rfk_channel(rtwdev);
+
+ rtw89_queue_chanctx_work(rtwdev);
mutex_unlock(&rtwdev->mutex);
return 0;
diff --git a/drivers/net/wireless/realtek/rtw89/mac_be.c b/drivers/net/wireless/realtek/rtw89/mac_be.c
new file mode 100644
index 000000000000..9a63fb35e867
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw89/mac_be.c
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2019-2020 Realtek Corporation
+ */
+
+#include "mac.h"
+#include "reg.h"
+
+static const u32 rtw89_mac_mem_base_addrs_be[RTW89_MAC_MEM_NUM] = {
+ [RTW89_MAC_MEM_AXIDMA] = AXIDMA_BASE_ADDR_BE,
+ [RTW89_MAC_MEM_SHARED_BUF] = SHARED_BUF_BASE_ADDR_BE,
+ [RTW89_MAC_MEM_DMAC_TBL] = DMAC_TBL_BASE_ADDR_BE,
+ [RTW89_MAC_MEM_SHCUT_MACHDR] = SHCUT_MACHDR_BASE_ADDR_BE,
+ [RTW89_MAC_MEM_STA_SCHED] = STA_SCHED_BASE_ADDR_BE,
+ [RTW89_MAC_MEM_RXPLD_FLTR_CAM] = RXPLD_FLTR_CAM_BASE_ADDR_BE,
+ [RTW89_MAC_MEM_SECURITY_CAM] = SEC_CAM_BASE_ADDR_BE,
+ [RTW89_MAC_MEM_WOW_CAM] = WOW_CAM_BASE_ADDR_BE,
+ [RTW89_MAC_MEM_CMAC_TBL] = CMAC_TBL_BASE_ADDR_BE,
+ [RTW89_MAC_MEM_ADDR_CAM] = ADDR_CAM_BASE_ADDR_BE,
+ [RTW89_MAC_MEM_BA_CAM] = BA_CAM_BASE_ADDR_BE,
+ [RTW89_MAC_MEM_BCN_IE_CAM0] = BCN_IE_CAM0_BASE_ADDR_BE,
+ [RTW89_MAC_MEM_BCN_IE_CAM1] = BCN_IE_CAM1_BASE_ADDR_BE,
+ [RTW89_MAC_MEM_TXD_FIFO_0] = TXD_FIFO_0_BASE_ADDR_BE,
+ [RTW89_MAC_MEM_TXD_FIFO_1] = TXD_FIFO_1_BASE_ADDR_BE,
+ [RTW89_MAC_MEM_TXDATA_FIFO_0] = TXDATA_FIFO_0_BASE_ADDR_BE,
+ [RTW89_MAC_MEM_TXDATA_FIFO_1] = TXDATA_FIFO_1_BASE_ADDR_BE,
+ [RTW89_MAC_MEM_CPU_LOCAL] = CPU_LOCAL_BASE_ADDR_BE,
+ [RTW89_MAC_MEM_BSSID_CAM] = BSSID_CAM_BASE_ADDR_BE,
+ [RTW89_MAC_MEM_WD_PAGE] = WD_PAGE_BASE_ADDR_BE,
+};
+
+const struct rtw89_mac_gen_def rtw89_mac_gen_be = {
+ .band1_offset = RTW89_MAC_BE_BAND_REG_OFFSET,
+ .filter_model_addr = R_BE_FILTER_MODEL_ADDR,
+ .indir_access_addr = R_BE_INDIR_ACCESS_ENTRY,
+ .mem_base_addrs = rtw89_mac_mem_base_addrs_be,
+ .rx_fltr = R_BE_RX_FLTR_OPT,
+};
+EXPORT_SYMBOL(rtw89_mac_gen_be);
diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c
index 9402f1a0caea..3a4bfc44142b 100644
--- a/drivers/net/wireless/realtek/rtw89/pci.c
+++ b/drivers/net/wireless/realtek/rtw89/pci.c
@@ -3939,5 +3939,5 @@ void rtw89_pci_remove(struct pci_dev *pdev)
EXPORT_SYMBOL(rtw89_pci_remove);
MODULE_AUTHOR("Realtek Corporation");
-MODULE_DESCRIPTION("Realtek 802.11ax wireless PCI driver");
+MODULE_DESCRIPTION("Realtek PCI 802.11ax wireless driver");
MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
index fb15c852fdd4..7139146cb3fa 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.c
+++ b/drivers/net/wireless/realtek/rtw89/phy.c
@@ -133,10 +133,10 @@ static u64 rtw89_phy_ra_mask_recover(u64 ra_mask, u64 ra_mask_bak)
return ra_mask;
}
-static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta)
+static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
+ const struct rtw89_chan *chan)
{
struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta);
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
struct cfg80211_bitrate_mask *mask = &rtwsta->mask;
enum nl80211_band band;
u64 cfg_mask;
@@ -197,9 +197,9 @@ rtw89_ra_mask_he_rates[4] = {RA_MASK_HE_1SS_RATES, RA_MASK_HE_2SS_RATES,
static void rtw89_phy_ra_gi_ltf(struct rtw89_dev *rtwdev,
struct rtw89_sta *rtwsta,
+ const struct rtw89_chan *chan,
bool *fix_giltf_en, u8 *fix_giltf)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
struct cfg80211_bitrate_mask *mask = &rtwsta->mask;
u8 band = chan->band_type;
enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band);
@@ -236,7 +236,8 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif->rate_pattern;
struct rtw89_ra_info *ra = &rtwsta->ra;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
+ rtwvif->sub_entity_idx);
struct ieee80211_vif *vif = rtwvif_to_vif(rtwsta->rtwvif);
const u64 *high_rate_masks = rtw89_ra_mask_ht_rates;
u8 rssi = ewma_rssi_read(&rtwsta->avg_rssi);
@@ -265,7 +266,7 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[1] &
IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)
ldpc_en = 1;
- rtw89_phy_ra_gi_ltf(rtwdev, rtwsta, &fix_giltf_en, &fix_giltf);
+ rtw89_phy_ra_gi_ltf(rtwdev, rtwsta, chan, &fix_giltf_en, &fix_giltf);
} else if (sta->deflink.vht_cap.vht_supported) {
u16 mcs_map = le16_to_cpu(sta->deflink.vht_cap.vht_mcs.rx_mcs_map);
@@ -332,7 +333,7 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
ra_mask &= rtw89_phy_ra_mask_rssi(rtwdev, rssi, 0);
ra_mask = rtw89_phy_ra_mask_recover(ra_mask, ra_mask_bak);
- ra_mask &= rtw89_phy_ra_mask_cfg(rtwdev, rtwsta);
+ ra_mask &= rtw89_phy_ra_mask_cfg(rtwdev, rtwsta, chan);
switch (sta->deflink.bandwidth) {
case IEEE80211_STA_RX_BW_160:
@@ -362,7 +363,7 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
ra->dcm_cap = 1;
if (rate_pattern->enable && !vif->p2p) {
- ra_mask = rtw89_phy_ra_mask_cfg(rtwdev, rtwsta);
+ ra_mask = rtw89_phy_ra_mask_cfg(rtwdev, rtwsta, chan);
ra_mask &= rate_pattern->ra_mask;
mode = rate_pattern->ra_mode;
}
@@ -444,6 +445,12 @@ static bool __check_rate_pattern(struct rtw89_phy_rate_pattern *next,
return true;
}
+#define RTW89_HW_RATE_BY_CHIP_GEN(rate) \
+ { \
+ [RTW89_CHIP_AX] = RTW89_HW_RATE_ ## rate, \
+ [RTW89_CHIP_BE] = RTW89_HW_RATE_V1_ ## rate, \
+ }
+
void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
const struct cfg80211_bitrate_mask *mask)
@@ -451,40 +458,48 @@ void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
struct ieee80211_supported_band *sband;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct rtw89_phy_rate_pattern next_pattern = {0};
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
- static const u16 hw_rate_he[] = {RTW89_HW_RATE_HE_NSS1_MCS0,
- RTW89_HW_RATE_HE_NSS2_MCS0,
- RTW89_HW_RATE_HE_NSS3_MCS0,
- RTW89_HW_RATE_HE_NSS4_MCS0};
- static const u16 hw_rate_vht[] = {RTW89_HW_RATE_VHT_NSS1_MCS0,
- RTW89_HW_RATE_VHT_NSS2_MCS0,
- RTW89_HW_RATE_VHT_NSS3_MCS0,
- RTW89_HW_RATE_VHT_NSS4_MCS0};
- static const u16 hw_rate_ht[] = {RTW89_HW_RATE_MCS0,
- RTW89_HW_RATE_MCS8,
- RTW89_HW_RATE_MCS16,
- RTW89_HW_RATE_MCS24};
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
+ rtwvif->sub_entity_idx);
+ static const u16 hw_rate_he[][RTW89_CHIP_GEN_NUM] = {
+ RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS1_MCS0),
+ RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS2_MCS0),
+ RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS3_MCS0),
+ RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS4_MCS0),
+ };
+ static const u16 hw_rate_vht[][RTW89_CHIP_GEN_NUM] = {
+ RTW89_HW_RATE_BY_CHIP_GEN(VHT_NSS1_MCS0),
+ RTW89_HW_RATE_BY_CHIP_GEN(VHT_NSS2_MCS0),
+ RTW89_HW_RATE_BY_CHIP_GEN(VHT_NSS3_MCS0),
+ RTW89_HW_RATE_BY_CHIP_GEN(VHT_NSS4_MCS0),
+ };
+ static const u16 hw_rate_ht[][RTW89_CHIP_GEN_NUM] = {
+ RTW89_HW_RATE_BY_CHIP_GEN(MCS0),
+ RTW89_HW_RATE_BY_CHIP_GEN(MCS8),
+ RTW89_HW_RATE_BY_CHIP_GEN(MCS16),
+ RTW89_HW_RATE_BY_CHIP_GEN(MCS24),
+ };
u8 band = chan->band_type;
enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band);
+ enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen;
u8 tx_nss = rtwdev->hal.tx_nss;
u8 i;
for (i = 0; i < tx_nss; i++)
- if (!__check_rate_pattern(&next_pattern, hw_rate_he[i],
+ if (!__check_rate_pattern(&next_pattern, hw_rate_he[i][chip_gen],
RA_MASK_HE_RATES, RTW89_RA_MODE_HE,
mask->control[nl_band].he_mcs[i],
0, true))
goto out;
for (i = 0; i < tx_nss; i++)
- if (!__check_rate_pattern(&next_pattern, hw_rate_vht[i],
+ if (!__check_rate_pattern(&next_pattern, hw_rate_vht[i][chip_gen],
RA_MASK_VHT_RATES, RTW89_RA_MODE_VHT,
mask->control[nl_band].vht_mcs[i],
0, true))
goto out;
for (i = 0; i < tx_nss; i++)
- if (!__check_rate_pattern(&next_pattern, hw_rate_ht[i],
+ if (!__check_rate_pattern(&next_pattern, hw_rate_ht[i][chip_gen],
RA_MASK_HT_RATES, RTW89_RA_MODE_HT,
mask->control[nl_band].ht_mcs[i],
0, true))
@@ -1342,12 +1357,16 @@ static void rtw89_phy_init_reg(struct rtw89_dev *rtwdev,
void rtw89_phy_init_bb_reg(struct rtw89_dev *rtwdev)
{
+ struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
const struct rtw89_chip_info *chip = rtwdev->chip;
- const struct rtw89_phy_table *bb_table = chip->bb_table;
- const struct rtw89_phy_table *bb_gain_table = chip->bb_gain_table;
+ const struct rtw89_phy_table *bb_table;
+ const struct rtw89_phy_table *bb_gain_table;
+ bb_table = elm_info->bb_tbl ? elm_info->bb_tbl : chip->bb_table;
rtw89_phy_init_reg(rtwdev, bb_table, rtw89_phy_config_bb_reg, NULL);
rtw89_chip_init_txpwr_unit(rtwdev, RTW89_PHY_0);
+
+ bb_gain_table = elm_info->bb_gain ? elm_info->bb_gain : chip->bb_gain_table;
if (bb_gain_table)
rtw89_phy_init_reg(rtwdev, bb_gain_table,
rtw89_phy_config_bb_gain, NULL);
@@ -1365,6 +1384,7 @@ void rtw89_phy_init_rf_reg(struct rtw89_dev *rtwdev, bool noio)
{
void (*config)(struct rtw89_dev *rtwdev, const struct rtw89_reg2_def *reg,
enum rtw89_rf_path rf_path, void *data);
+ struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_phy_table *rf_table;
struct rtw89_fw_h2c_rf_reg_info *rf_reg_info;
@@ -1375,7 +1395,8 @@ void rtw89_phy_init_rf_reg(struct rtw89_dev *rtwdev, bool noio)
return;
for (path = RF_PATH_A; path < chip->rf_path_num; path++) {
- rf_table = chip->rf_table[path];
+ rf_table = elm_info->rf_radio[path] ?
+ elm_info->rf_radio[path] : chip->rf_table[path];
rf_reg_info->rf_path = rf_table->rf_path;
if (noio)
config = rtw89_phy_config_rf_reg_noio;
@@ -1392,6 +1413,7 @@ void rtw89_phy_init_rf_reg(struct rtw89_dev *rtwdev, bool noio)
static void rtw89_phy_init_rf_nctl(struct rtw89_dev *rtwdev)
{
+ struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_phy_table *nctl_table;
u32 val;
@@ -1414,7 +1436,7 @@ static void rtw89_phy_init_rf_nctl(struct rtw89_dev *rtwdev)
if (ret)
rtw89_err(rtwdev, "failed to poll nctl block\n");
- nctl_table = chip->nctl_table;
+ nctl_table = elm_info->rf_nctl ? elm_info->rf_nctl : chip->nctl_table;
rtw89_phy_init_reg(rtwdev, nctl_table, rtw89_phy_config_bb_reg, NULL);
if (chip->nctl_post_table)
@@ -1426,6 +1448,9 @@ static u32 rtw89_phy0_phy1_offset(struct rtw89_dev *rtwdev, u32 addr)
u32 phy_page = addr >> 8;
u32 ofst = 0;
+ if (rtwdev->chip->chip_gen == RTW89_CHIP_BE)
+ return addr < 0x10000 ? 0x20000 : 0;
+
switch (phy_page) {
case 0x6:
case 0x7:
@@ -1627,6 +1652,8 @@ s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, u8 band,
const struct rtw89_txpwr_rule_5ghz *rule_5ghz = &rfe_parms->rule_5ghz;
const struct rtw89_txpwr_rule_6ghz *rule_6ghz = &rfe_parms->rule_6ghz;
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
+ enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band);
+ u32 freq = ieee80211_channel_to_frequency(ch, nl_band);
u8 ch_idx = rtw89_channel_to_idx(rtwdev, band, ch);
u8 regd = rtw89_regd_get(rtwdev, band);
u8 reg6 = regulatory->reg_6ghz_power;
@@ -1662,7 +1689,7 @@ s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, u8 band,
}
lmt = _phy_txpwr_rf_to_mac(rtwdev, lmt);
- sar = rtw89_query_sar(rtwdev);
+ sar = rtw89_query_sar(rtwdev, freq);
return min(lmt, sar);
}
@@ -1882,6 +1909,8 @@ static s8 rtw89_phy_read_txpwr_limit_ru(struct rtw89_dev *rtwdev, u8 band,
const struct rtw89_txpwr_rule_5ghz *rule_5ghz = &rfe_parms->rule_5ghz;
const struct rtw89_txpwr_rule_6ghz *rule_6ghz = &rfe_parms->rule_6ghz;
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
+ enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band);
+ u32 freq = ieee80211_channel_to_frequency(ch, nl_band);
u8 ch_idx = rtw89_channel_to_idx(rtwdev, band, ch);
u8 regd = rtw89_regd_get(rtwdev, band);
u8 reg6 = regulatory->reg_6ghz_power;
@@ -1917,7 +1946,7 @@ static s8 rtw89_phy_read_txpwr_limit_ru(struct rtw89_dev *rtwdev, u8 band,
}
lmt_ru = _phy_txpwr_rf_to_mac(rtwdev, lmt_ru);
- sar = rtw89_query_sar(rtwdev);
+ sar = rtw89_query_sar(rtwdev, freq);
return min(lmt_ru, sar);
}
@@ -2231,21 +2260,34 @@ static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta)
struct rtw89_phy_iter_ra_data *ra_data = (struct rtw89_phy_iter_ra_data *)data;
struct rtw89_dev *rtwdev = ra_data->rtwdev;
struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+ const struct rtw89_c2h_ra_rpt *c2h =
+ (const struct rtw89_c2h_ra_rpt *)ra_data->c2h->data;
struct rtw89_ra_report *ra_report = &rtwsta->ra_report;
- struct sk_buff *c2h = ra_data->c2h;
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ bool format_v1 = chip->chip_gen == RTW89_CHIP_BE;
u8 mode, rate, bw, giltf, mac_id;
u16 legacy_bitrate;
bool valid;
u8 mcs = 0;
+ u8 t;
- mac_id = RTW89_GET_PHY_C2H_RA_RPT_MACID(c2h->data);
+ mac_id = le32_get_bits(c2h->w2, RTW89_C2H_RA_RPT_W2_MACID);
if (mac_id != rtwsta->mac_id)
return;
- rate = RTW89_GET_PHY_C2H_RA_RPT_MCSNSS(c2h->data);
- bw = RTW89_GET_PHY_C2H_RA_RPT_BW(c2h->data);
- giltf = RTW89_GET_PHY_C2H_RA_RPT_GILTF(c2h->data);
- mode = RTW89_GET_PHY_C2H_RA_RPT_MD_SEL(c2h->data);
+ rate = le32_get_bits(c2h->w3, RTW89_C2H_RA_RPT_W3_MCSNSS);
+ bw = le32_get_bits(c2h->w3, RTW89_C2H_RA_RPT_W3_BW);
+ giltf = le32_get_bits(c2h->w3, RTW89_C2H_RA_RPT_W3_GILTF);
+ mode = le32_get_bits(c2h->w3, RTW89_C2H_RA_RPT_W3_MD_SEL);
+
+ if (format_v1) {
+ t = le32_get_bits(c2h->w2, RTW89_C2H_RA_RPT_W2_MCSNSS_B7);
+ rate |= u8_encode_bits(t, BIT(7));
+ t = le32_get_bits(c2h->w3, RTW89_C2H_RA_RPT_W3_BW_B2);
+ bw |= u8_encode_bits(t, BIT(2));
+ t = le32_get_bits(c2h->w3, RTW89_C2H_RA_RPT_W3_MD_SEL_B2);
+ mode |= u8_encode_bits(t, BIT(2));
+ }
if (mode == RTW89_RA_RPT_MODE_LEGACY) {
valid = rtw89_ra_report_to_bitrate(rtwdev, rate, &legacy_bitrate);
@@ -2273,16 +2315,24 @@ static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta)
break;
case RTW89_RA_RPT_MODE_VHT:
ra_report->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
- ra_report->txrate.mcs = FIELD_GET(RTW89_RA_RATE_MASK_MCS, rate);
- ra_report->txrate.nss = FIELD_GET(RTW89_RA_RATE_MASK_NSS, rate) + 1;
+ ra_report->txrate.mcs = format_v1 ?
+ u8_get_bits(rate, RTW89_RA_RATE_MASK_MCS_V1) :
+ u8_get_bits(rate, RTW89_RA_RATE_MASK_MCS);
+ ra_report->txrate.nss = format_v1 ?
+ u8_get_bits(rate, RTW89_RA_RATE_MASK_NSS_V1) + 1 :
+ u8_get_bits(rate, RTW89_RA_RATE_MASK_NSS) + 1;
if (giltf)
ra_report->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
mcs = ra_report->txrate.mcs;
break;
case RTW89_RA_RPT_MODE_HE:
ra_report->txrate.flags |= RATE_INFO_FLAGS_HE_MCS;
- ra_report->txrate.mcs = FIELD_GET(RTW89_RA_RATE_MASK_MCS, rate);
- ra_report->txrate.nss = FIELD_GET(RTW89_RA_RATE_MASK_NSS, rate) + 1;
+ ra_report->txrate.mcs = format_v1 ?
+ u8_get_bits(rate, RTW89_RA_RATE_MASK_MCS_V1) :
+ u8_get_bits(rate, RTW89_RA_RATE_MASK_MCS);
+ ra_report->txrate.nss = format_v1 ?
+ u8_get_bits(rate, RTW89_RA_RATE_MASK_NSS_V1) + 1 :
+ u8_get_bits(rate, RTW89_RA_RATE_MASK_NSS) + 1;
if (giltf == RTW89_GILTF_2XHE08 || giltf == RTW89_GILTF_1XHE08)
ra_report->txrate.he_gi = NL80211_RATE_INFO_HE_GI_0_8;
else if (giltf == RTW89_GILTF_2XHE16 || giltf == RTW89_GILTF_1XHE16)
@@ -2295,8 +2345,11 @@ static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta)
ra_report->txrate.bw = rtw89_hw_to_rate_info_bw(bw);
ra_report->bit_rate = cfg80211_calculate_bitrate(&ra_report->txrate);
- ra_report->hw_rate = FIELD_PREP(RTW89_HW_RATE_MASK_MOD, mode) |
- FIELD_PREP(RTW89_HW_RATE_MASK_VAL, rate);
+ ra_report->hw_rate = format_v1 ?
+ u16_encode_bits(mode, RTW89_HW_RATE_V1_MASK_MOD) |
+ u16_encode_bits(rate, RTW89_HW_RATE_V1_MASK_VAL) :
+ u16_encode_bits(mode, RTW89_HW_RATE_MASK_MOD) |
+ u16_encode_bits(rate, RTW89_HW_RATE_MASK_VAL);
ra_report->might_fallback_legacy = mcs <= 2;
sta->deflink.agg.max_rc_amsdu_len = get_max_amsdu_len(rtwdev, ra_report);
rtwsta->max_agg_wait = sta->deflink.agg.max_rc_amsdu_len / 1500 - 1;
@@ -2841,7 +2894,8 @@ void rtw89_phy_cfo_parse(struct rtw89_dev *rtwdev, s16 cfo_val,
void rtw89_phy_ul_tb_assoc(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
+ rtwvif->sub_entity_idx);
struct rtw89_phy_ul_tb_info *ul_tb_info = &rtwdev->ul_tb_info;
if (!chip->support_ul_tb_ctrl)
@@ -2977,7 +3031,7 @@ static void rtw89_phy_antdiv_sts_instance_add(struct rtw89_dev *rtwdev,
struct rtw89_rx_phy_ppdu *phy_ppdu,
struct rtw89_antdiv_stats *stats)
{
- if (GET_DATA_RATE_MODE(phy_ppdu->rate) == DATA_RATE_MODE_NON_HT) {
+ if (rtw89_get_data_rate_mode(rtwdev, phy_ppdu->rate) == DATA_RATE_MODE_NON_HT) {
if (phy_ppdu->rate < RTW89_HW_RATE_OFDM6) {
ewma_rssi_add(&stats->cck_rssi_avg, phy_ppdu->rssi_avg);
stats->pkt_cnt_cck++;
@@ -3183,7 +3237,9 @@ static u32 rtw89_phy_ccx_idx_to_us(struct rtw89_dev *rtwdev, u16 idx)
static void rtw89_phy_ccx_top_setting_init(struct rtw89_dev *rtwdev)
{
+ const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
struct rtw89_env_monitor_info *env = &rtwdev->env_monitor;
+ const struct rtw89_ccx_regs *ccx = phy->ccx;
env->ccx_manual_ctrl = false;
env->ccx_ongoing = false;
@@ -3191,10 +3247,10 @@ static void rtw89_phy_ccx_top_setting_init(struct rtw89_dev *rtwdev)
env->ccx_period = 0;
env->ccx_unit_idx = RTW89_CCX_32_US;
- rtw89_phy_set_phy_regs(rtwdev, R_CCX, B_CCX_EN_MSK, 1);
- rtw89_phy_set_phy_regs(rtwdev, R_CCX, B_CCX_TRIG_OPT_MSK, 1);
- rtw89_phy_set_phy_regs(rtwdev, R_CCX, B_MEASUREMENT_TRIG_MSK, 1);
- rtw89_phy_set_phy_regs(rtwdev, R_CCX, B_CCX_EDCCA_OPT_MSK,
+ rtw89_phy_set_phy_regs(rtwdev, ccx->setting_addr, ccx->en_mask, 1);
+ rtw89_phy_set_phy_regs(rtwdev, ccx->setting_addr, ccx->trig_opt_mask, 1);
+ rtw89_phy_set_phy_regs(rtwdev, ccx->setting_addr, ccx->measurement_trig_mask, 1);
+ rtw89_phy_set_phy_regs(rtwdev, ccx->setting_addr, ccx->edcca_opt_mask,
RTW89_CCX_EDCCA_BW20_0);
}
@@ -3309,25 +3365,27 @@ ifs_update_finished:
static void rtw89_phy_ifs_clm_set_th_reg(struct rtw89_dev *rtwdev)
{
+ const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
struct rtw89_env_monitor_info *env = &rtwdev->env_monitor;
+ const struct rtw89_ccx_regs *ccx = phy->ccx;
u8 i = 0;
- rtw89_phy_set_phy_regs(rtwdev, R_IFS_T1, B_IFS_T1_TH_LOW_MSK,
+ rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t1_addr, ccx->ifs_t1_th_l_mask,
env->ifs_clm_th_l[0]);
- rtw89_phy_set_phy_regs(rtwdev, R_IFS_T2, B_IFS_T2_TH_LOW_MSK,
+ rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t2_addr, ccx->ifs_t2_th_l_mask,
env->ifs_clm_th_l[1]);
- rtw89_phy_set_phy_regs(rtwdev, R_IFS_T3, B_IFS_T3_TH_LOW_MSK,
+ rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t3_addr, ccx->ifs_t3_th_l_mask,
env->ifs_clm_th_l[2]);
- rtw89_phy_set_phy_regs(rtwdev, R_IFS_T4, B_IFS_T4_TH_LOW_MSK,
+ rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t4_addr, ccx->ifs_t4_th_l_mask,
env->ifs_clm_th_l[3]);
- rtw89_phy_set_phy_regs(rtwdev, R_IFS_T1, B_IFS_T1_TH_HIGH_MSK,
+ rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t1_addr, ccx->ifs_t1_th_h_mask,
env->ifs_clm_th_h[0]);
- rtw89_phy_set_phy_regs(rtwdev, R_IFS_T2, B_IFS_T2_TH_HIGH_MSK,
+ rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t2_addr, ccx->ifs_t2_th_h_mask,
env->ifs_clm_th_h[1]);
- rtw89_phy_set_phy_regs(rtwdev, R_IFS_T3, B_IFS_T3_TH_HIGH_MSK,
+ rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t3_addr, ccx->ifs_t3_th_h_mask,
env->ifs_clm_th_h[2]);
- rtw89_phy_set_phy_regs(rtwdev, R_IFS_T4, B_IFS_T4_TH_HIGH_MSK,
+ rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t4_addr, ccx->ifs_t4_th_h_mask,
env->ifs_clm_th_h[3]);
for (i = 0; i < RTW89_IFS_CLM_NUM; i++)
@@ -3338,7 +3396,9 @@ static void rtw89_phy_ifs_clm_set_th_reg(struct rtw89_dev *rtwdev)
static void rtw89_phy_ifs_clm_setting_init(struct rtw89_dev *rtwdev)
{
+ const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
struct rtw89_env_monitor_info *env = &rtwdev->env_monitor;
+ const struct rtw89_ccx_regs *ccx = phy->ccx;
struct rtw89_ccx_para_info para = {0};
env->ifs_clm_app = RTW89_IFS_CLM_BACKGROUND;
@@ -3348,12 +3408,11 @@ static void rtw89_phy_ifs_clm_setting_init(struct rtw89_dev *rtwdev)
if (rtw89_phy_ifs_clm_th_update_check(rtwdev, &para))
rtw89_phy_ifs_clm_set_th_reg(rtwdev);
- rtw89_phy_set_phy_regs(rtwdev, R_IFS_COUNTER, B_IFS_COLLECT_EN,
- true);
- rtw89_phy_set_phy_regs(rtwdev, R_IFS_T1, B_IFS_T1_EN_MSK, true);
- rtw89_phy_set_phy_regs(rtwdev, R_IFS_T2, B_IFS_T2_EN_MSK, true);
- rtw89_phy_set_phy_regs(rtwdev, R_IFS_T3, B_IFS_T3_EN_MSK, true);
- rtw89_phy_set_phy_regs(rtwdev, R_IFS_T4, B_IFS_T4_EN_MSK, true);
+ rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_cnt_addr, ccx->ifs_collect_en_mask, true);
+ rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t1_addr, ccx->ifs_t1_en_mask, true);
+ rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t2_addr, ccx->ifs_t2_en_mask, true);
+ rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t3_addr, ccx->ifs_t3_en_mask, true);
+ rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_t4_addr, ccx->ifs_t4_en_mask, true);
}
static int rtw89_phy_ccx_racing_ctrl(struct rtw89_dev *rtwdev,
@@ -3390,12 +3449,14 @@ static int rtw89_phy_ccx_racing_ctrl(struct rtw89_dev *rtwdev,
static void rtw89_phy_ccx_trigger(struct rtw89_dev *rtwdev)
{
+ const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
struct rtw89_env_monitor_info *env = &rtwdev->env_monitor;
+ const struct rtw89_ccx_regs *ccx = phy->ccx;
- rtw89_phy_set_phy_regs(rtwdev, R_IFS_COUNTER, B_IFS_COUNTER_CLR_MSK, 0);
- rtw89_phy_set_phy_regs(rtwdev, R_CCX, B_MEASUREMENT_TRIG_MSK, 0);
- rtw89_phy_set_phy_regs(rtwdev, R_IFS_COUNTER, B_IFS_COUNTER_CLR_MSK, 1);
- rtw89_phy_set_phy_regs(rtwdev, R_CCX, B_MEASUREMENT_TRIG_MSK, 1);
+ rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_cnt_addr, ccx->ifs_clm_cnt_clear_mask, 0);
+ rtw89_phy_set_phy_regs(rtwdev, ccx->setting_addr, ccx->measurement_trig_mask, 0);
+ rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_cnt_addr, ccx->ifs_clm_cnt_clear_mask, 1);
+ rtw89_phy_set_phy_regs(rtwdev, ccx->setting_addr, ccx->measurement_trig_mask, 1);
env->ccx_ongoing = true;
}
@@ -3467,63 +3528,79 @@ static void rtw89_phy_ifs_clm_get_utility(struct rtw89_dev *rtwdev)
static bool rtw89_phy_ifs_clm_get_result(struct rtw89_dev *rtwdev)
{
+ const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
struct rtw89_env_monitor_info *env = &rtwdev->env_monitor;
+ const struct rtw89_ccx_regs *ccx = phy->ccx;
u8 i = 0;
- if (rtw89_phy_read32_mask(rtwdev, R_IFSCNT, B_IFSCNT_DONE_MSK) == 0) {
+ if (rtw89_phy_read32_mask(rtwdev, ccx->ifs_total_addr,
+ ccx->ifs_cnt_done_mask) == 0) {
rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
"Get IFS_CLM report Fail\n");
return false;
}
env->ifs_clm_tx =
- rtw89_phy_read32_mask(rtwdev, R_IFS_CLM_TX_CNT,
- B_IFS_CLM_TX_CNT_MSK);
+ rtw89_phy_read32_mask(rtwdev, ccx->ifs_clm_tx_cnt_addr,
+ ccx->ifs_clm_tx_cnt_msk);
env->ifs_clm_edcca_excl_cca =
- rtw89_phy_read32_mask(rtwdev, R_IFS_CLM_TX_CNT,
- B_IFS_CLM_EDCCA_EXCLUDE_CCA_FA_MSK);
+ rtw89_phy_read32_mask(rtwdev, ccx->ifs_clm_tx_cnt_addr,
+ ccx->ifs_clm_edcca_excl_cca_fa_mask);
env->ifs_clm_cckcca_excl_fa =
- rtw89_phy_read32_mask(rtwdev, R_IFS_CLM_CCA,
- B_IFS_CLM_CCKCCA_EXCLUDE_FA_MSK);
+ rtw89_phy_read32_mask(rtwdev, ccx->ifs_clm_cca_addr,
+ ccx->ifs_clm_cckcca_excl_fa_mask);
env->ifs_clm_ofdmcca_excl_fa =
- rtw89_phy_read32_mask(rtwdev, R_IFS_CLM_CCA,
- B_IFS_CLM_OFDMCCA_EXCLUDE_FA_MSK);
+ rtw89_phy_read32_mask(rtwdev, ccx->ifs_clm_cca_addr,
+ ccx->ifs_clm_ofdmcca_excl_fa_mask);
env->ifs_clm_cckfa =
- rtw89_phy_read32_mask(rtwdev, R_IFS_CLM_FA,
- B_IFS_CLM_CCK_FA_MSK);
+ rtw89_phy_read32_mask(rtwdev, ccx->ifs_clm_fa_addr,
+ ccx->ifs_clm_cck_fa_mask);
env->ifs_clm_ofdmfa =
- rtw89_phy_read32_mask(rtwdev, R_IFS_CLM_FA,
- B_IFS_CLM_OFDM_FA_MSK);
+ rtw89_phy_read32_mask(rtwdev, ccx->ifs_clm_fa_addr,
+ ccx->ifs_clm_ofdm_fa_mask);
env->ifs_clm_his[0] =
- rtw89_phy_read32_mask(rtwdev, R_IFS_HIS, B_IFS_T1_HIS_MSK);
+ rtw89_phy_read32_mask(rtwdev, ccx->ifs_his_addr,
+ ccx->ifs_t1_his_mask);
env->ifs_clm_his[1] =
- rtw89_phy_read32_mask(rtwdev, R_IFS_HIS, B_IFS_T2_HIS_MSK);
+ rtw89_phy_read32_mask(rtwdev, ccx->ifs_his_addr,
+ ccx->ifs_t2_his_mask);
env->ifs_clm_his[2] =
- rtw89_phy_read32_mask(rtwdev, R_IFS_HIS, B_IFS_T3_HIS_MSK);
+ rtw89_phy_read32_mask(rtwdev, ccx->ifs_his_addr,
+ ccx->ifs_t3_his_mask);
env->ifs_clm_his[3] =
- rtw89_phy_read32_mask(rtwdev, R_IFS_HIS, B_IFS_T4_HIS_MSK);
+ rtw89_phy_read32_mask(rtwdev, ccx->ifs_his_addr,
+ ccx->ifs_t4_his_mask);
env->ifs_clm_avg[0] =
- rtw89_phy_read32_mask(rtwdev, R_IFS_AVG_L, B_IFS_T1_AVG_MSK);
+ rtw89_phy_read32_mask(rtwdev, ccx->ifs_avg_l_addr,
+ ccx->ifs_t1_avg_mask);
env->ifs_clm_avg[1] =
- rtw89_phy_read32_mask(rtwdev, R_IFS_AVG_L, B_IFS_T2_AVG_MSK);
+ rtw89_phy_read32_mask(rtwdev, ccx->ifs_avg_l_addr,
+ ccx->ifs_t2_avg_mask);
env->ifs_clm_avg[2] =
- rtw89_phy_read32_mask(rtwdev, R_IFS_AVG_H, B_IFS_T3_AVG_MSK);
+ rtw89_phy_read32_mask(rtwdev, ccx->ifs_avg_h_addr,
+ ccx->ifs_t3_avg_mask);
env->ifs_clm_avg[3] =
- rtw89_phy_read32_mask(rtwdev, R_IFS_AVG_H, B_IFS_T4_AVG_MSK);
+ rtw89_phy_read32_mask(rtwdev, ccx->ifs_avg_h_addr,
+ ccx->ifs_t4_avg_mask);
env->ifs_clm_cca[0] =
- rtw89_phy_read32_mask(rtwdev, R_IFS_CCA_L, B_IFS_T1_CCA_MSK);
+ rtw89_phy_read32_mask(rtwdev, ccx->ifs_cca_l_addr,
+ ccx->ifs_t1_cca_mask);
env->ifs_clm_cca[1] =
- rtw89_phy_read32_mask(rtwdev, R_IFS_CCA_L, B_IFS_T2_CCA_MSK);
+ rtw89_phy_read32_mask(rtwdev, ccx->ifs_cca_l_addr,
+ ccx->ifs_t2_cca_mask);
env->ifs_clm_cca[2] =
- rtw89_phy_read32_mask(rtwdev, R_IFS_CCA_H, B_IFS_T3_CCA_MSK);
+ rtw89_phy_read32_mask(rtwdev, ccx->ifs_cca_h_addr,
+ ccx->ifs_t3_cca_mask);
env->ifs_clm_cca[3] =
- rtw89_phy_read32_mask(rtwdev, R_IFS_CCA_H, B_IFS_T4_CCA_MSK);
+ rtw89_phy_read32_mask(rtwdev, ccx->ifs_cca_h_addr,
+ ccx->ifs_t4_cca_mask);
env->ifs_clm_total_ifs =
- rtw89_phy_read32_mask(rtwdev, R_IFSCNT, B_IFSCNT_TOTAL_CNT_MSK);
+ rtw89_phy_read32_mask(rtwdev, ccx->ifs_total_addr,
+ ccx->ifs_total_mask);
rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "IFS-CLM total_ifs = %d\n",
env->ifs_clm_total_ifs);
@@ -3551,7 +3628,9 @@ static bool rtw89_phy_ifs_clm_get_result(struct rtw89_dev *rtwdev)
static int rtw89_phy_ifs_clm_set(struct rtw89_dev *rtwdev,
struct rtw89_ccx_para_info *para)
{
+ const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
struct rtw89_env_monitor_info *env = &rtwdev->env_monitor;
+ const struct rtw89_ccx_regs *ccx = phy->ccx;
u32 period = 0;
u32 unit_idx = 0;
@@ -3567,10 +3646,11 @@ static int rtw89_phy_ifs_clm_set(struct rtw89_dev *rtwdev,
if (para->mntr_time != env->ifs_clm_mntr_time) {
rtw89_phy_ccx_ms_to_period_unit(rtwdev, para->mntr_time,
&period, &unit_idx);
- rtw89_phy_set_phy_regs(rtwdev, R_IFS_COUNTER,
- B_IFS_CLM_PERIOD_MSK, period);
- rtw89_phy_set_phy_regs(rtwdev, R_IFS_COUNTER,
- B_IFS_CLM_COUNTER_UNIT_MSK, unit_idx);
+ rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_cnt_addr,
+ ccx->ifs_clm_period_mask, period);
+ rtw89_phy_set_phy_regs(rtwdev, ccx->ifs_cnt_addr,
+ ccx->ifs_clm_cnt_unit_mask,
+ unit_idx);
rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
"Update IFS-CLM time ((%d)) -> ((%d))\n",
@@ -3688,16 +3768,19 @@ static void rtw89_physts_enable_fail_report(struct rtw89_dev *rtwdev,
bool enable,
enum rtw89_phy_idx phy_idx)
{
+ const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
+ const struct rtw89_physts_regs *physts = phy->physts;
+
if (enable) {
- rtw89_phy_write32_clr(rtwdev, R_PLCP_HISTOGRAM,
- B_STS_DIS_TRIG_BY_FAIL);
- rtw89_phy_write32_clr(rtwdev, R_PLCP_HISTOGRAM,
- B_STS_DIS_TRIG_BY_BRK);
+ rtw89_phy_write32_clr(rtwdev, physts->setting_addr,
+ physts->dis_trigger_fail_mask);
+ rtw89_phy_write32_clr(rtwdev, physts->setting_addr,
+ physts->dis_trigger_brk_mask);
} else {
- rtw89_phy_write32_set(rtwdev, R_PLCP_HISTOGRAM,
- B_STS_DIS_TRIG_BY_FAIL);
- rtw89_phy_write32_set(rtwdev, R_PLCP_HISTOGRAM,
- B_STS_DIS_TRIG_BY_BRK);
+ rtw89_phy_write32_set(rtwdev, physts->setting_addr,
+ physts->dis_trigger_fail_mask);
+ rtw89_phy_write32_set(rtwdev, physts->setting_addr,
+ physts->dis_trigger_brk_mask);
}
}
@@ -4125,10 +4208,10 @@ static void rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev, u8 rssi,
"igi=%d, cck_ccaTH=%d, backoff=%d, cck_PD_low=((%d))dB\n",
final_rssi, cck_cca_th, under_region, pd_val);
- rtw89_phy_write32_mask(rtwdev, R_BMODE_PDTH_EN_V1,
- B_BMODE_PDTH_LIMIT_EN_MSK_V1, enable);
- rtw89_phy_write32_mask(rtwdev, R_BMODE_PDTH_V1,
- B_BMODE_PDTH_LOWER_BOUND_MSK_V1, pd_val);
+ rtw89_phy_write32_mask(rtwdev, dig_regs->bmode_pd_reg,
+ dig_regs->bmode_cca_rssi_limit_en, enable);
+ rtw89_phy_write32_mask(rtwdev, dig_regs->bmode_pd_lower_bound_reg,
+ dig_regs->bmode_rssi_nocca_low_th_mask, pd_val);
}
void rtw89_phy_dig_reset(struct rtw89_dev *rtwdev)
@@ -4517,7 +4600,7 @@ void rtw89_phy_tssi_ctrl_set_fast_mode_cfg(struct rtw89_dev *rtwdev,
regs = rtw89_tssi_fastmode_regs_level;
for (i = 0; i < RTW89_TSSI_FAST_MODE_NUM; i++) {
- reg = rtw89_mac_reg_by_idx(regs[i].addr, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, regs[i].addr, mac_idx);
rtw89_write32_mask(rtwdev, reg, regs[i].mask, val);
}
}
@@ -4579,11 +4662,11 @@ void rtw89_phy_tssi_ctrl_set_bandedge_cfg(struct rtw89_dev *rtwdev,
data = chip->tssi_dbw_table->data[bandedge_cfg];
for (i = 0; i < RTW89_TSSI_SBW_NUM; i++) {
- reg = rtw89_mac_reg_by_idx(regs[i].addr, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, regs[i].addr, mac_idx);
rtw89_write32_mask(rtwdev, reg, regs[i].mask, data[i]);
}
- reg = rtw89_mac_reg_by_idx(R_AX_BANDEDGE_CFG, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_BANDEDGE_CFG, mac_idx);
rtw89_write32_mask(rtwdev, reg, B_AX_BANDEDGE_CFG_IDX_MASK, bandedge_cfg);
rtw89_phy_tssi_ctrl_set_fast_mode_cfg(rtwdev, mac_idx, bandedge_cfg,
@@ -4681,3 +4764,74 @@ void rtw89_phy_config_edcca(struct rtw89_dev *rtwdev, bool scan)
rtw89_phy_write32(rtwdev, reg, hal->edcca_bak);
}
}
+
+static const struct rtw89_ccx_regs rtw89_ccx_regs_ax = {
+ .setting_addr = R_CCX,
+ .edcca_opt_mask = B_CCX_EDCCA_OPT_MSK,
+ .measurement_trig_mask = B_MEASUREMENT_TRIG_MSK,
+ .trig_opt_mask = B_CCX_TRIG_OPT_MSK,
+ .en_mask = B_CCX_EN_MSK,
+ .ifs_cnt_addr = R_IFS_COUNTER,
+ .ifs_clm_period_mask = B_IFS_CLM_PERIOD_MSK,
+ .ifs_clm_cnt_unit_mask = B_IFS_CLM_COUNTER_UNIT_MSK,
+ .ifs_clm_cnt_clear_mask = B_IFS_COUNTER_CLR_MSK,
+ .ifs_collect_en_mask = B_IFS_COLLECT_EN,
+ .ifs_t1_addr = R_IFS_T1,
+ .ifs_t1_th_h_mask = B_IFS_T1_TH_HIGH_MSK,
+ .ifs_t1_en_mask = B_IFS_T1_EN_MSK,
+ .ifs_t1_th_l_mask = B_IFS_T1_TH_LOW_MSK,
+ .ifs_t2_addr = R_IFS_T2,
+ .ifs_t2_th_h_mask = B_IFS_T2_TH_HIGH_MSK,
+ .ifs_t2_en_mask = B_IFS_T2_EN_MSK,
+ .ifs_t2_th_l_mask = B_IFS_T2_TH_LOW_MSK,
+ .ifs_t3_addr = R_IFS_T3,
+ .ifs_t3_th_h_mask = B_IFS_T3_TH_HIGH_MSK,
+ .ifs_t3_en_mask = B_IFS_T3_EN_MSK,
+ .ifs_t3_th_l_mask = B_IFS_T3_TH_LOW_MSK,
+ .ifs_t4_addr = R_IFS_T4,
+ .ifs_t4_th_h_mask = B_IFS_T4_TH_HIGH_MSK,
+ .ifs_t4_en_mask = B_IFS_T4_EN_MSK,
+ .ifs_t4_th_l_mask = B_IFS_T4_TH_LOW_MSK,
+ .ifs_clm_tx_cnt_addr = R_IFS_CLM_TX_CNT,
+ .ifs_clm_edcca_excl_cca_fa_mask = B_IFS_CLM_EDCCA_EXCLUDE_CCA_FA_MSK,
+ .ifs_clm_tx_cnt_msk = B_IFS_CLM_TX_CNT_MSK,
+ .ifs_clm_cca_addr = R_IFS_CLM_CCA,
+ .ifs_clm_ofdmcca_excl_fa_mask = B_IFS_CLM_OFDMCCA_EXCLUDE_FA_MSK,
+ .ifs_clm_cckcca_excl_fa_mask = B_IFS_CLM_CCKCCA_EXCLUDE_FA_MSK,
+ .ifs_clm_fa_addr = R_IFS_CLM_FA,
+ .ifs_clm_ofdm_fa_mask = B_IFS_CLM_OFDM_FA_MSK,
+ .ifs_clm_cck_fa_mask = B_IFS_CLM_CCK_FA_MSK,
+ .ifs_his_addr = R_IFS_HIS,
+ .ifs_t4_his_mask = B_IFS_T4_HIS_MSK,
+ .ifs_t3_his_mask = B_IFS_T3_HIS_MSK,
+ .ifs_t2_his_mask = B_IFS_T2_HIS_MSK,
+ .ifs_t1_his_mask = B_IFS_T1_HIS_MSK,
+ .ifs_avg_l_addr = R_IFS_AVG_L,
+ .ifs_t2_avg_mask = B_IFS_T2_AVG_MSK,
+ .ifs_t1_avg_mask = B_IFS_T1_AVG_MSK,
+ .ifs_avg_h_addr = R_IFS_AVG_H,
+ .ifs_t4_avg_mask = B_IFS_T4_AVG_MSK,
+ .ifs_t3_avg_mask = B_IFS_T3_AVG_MSK,
+ .ifs_cca_l_addr = R_IFS_CCA_L,
+ .ifs_t2_cca_mask = B_IFS_T2_CCA_MSK,
+ .ifs_t1_cca_mask = B_IFS_T1_CCA_MSK,
+ .ifs_cca_h_addr = R_IFS_CCA_H,
+ .ifs_t4_cca_mask = B_IFS_T4_CCA_MSK,
+ .ifs_t3_cca_mask = B_IFS_T3_CCA_MSK,
+ .ifs_total_addr = R_IFSCNT,
+ .ifs_cnt_done_mask = B_IFSCNT_DONE_MSK,
+ .ifs_total_mask = B_IFSCNT_TOTAL_CNT_MSK,
+};
+
+static const struct rtw89_physts_regs rtw89_physts_regs_ax = {
+ .setting_addr = R_PLCP_HISTOGRAM,
+ .dis_trigger_fail_mask = B_STS_DIS_TRIG_BY_FAIL,
+ .dis_trigger_brk_mask = B_STS_DIS_TRIG_BY_BRK,
+};
+
+const struct rtw89_phy_gen_def rtw89_phy_gen_ax = {
+ .cr_base = 0x10000,
+ .ccx = &rtw89_ccx_regs_ax,
+ .physts = &rtw89_physts_regs_ax,
+};
+EXPORT_SYMBOL(rtw89_phy_gen_ax);
diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h
index ab174a0ba488..d6dc0cbbae43 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.h
+++ b/drivers/net/wireless/realtek/rtw89/phy.h
@@ -7,7 +7,6 @@
#include "core.h"
-#define RTW89_PHY_ADDR_OFFSET 0x10000
#define RTW89_RF_ADDR_ADSEL_MASK BIT(16)
#define get_phy_headline(addr) FIELD_GET(GENMASK(31, 28), addr)
@@ -337,61 +336,154 @@ struct rtw89_nbi_reg_def {
struct rtw89_reg_def notch2_en;
};
+struct rtw89_ccx_regs {
+ u32 setting_addr;
+ u32 edcca_opt_mask;
+ u32 measurement_trig_mask;
+ u32 trig_opt_mask;
+ u32 en_mask;
+ u32 ifs_cnt_addr;
+ u32 ifs_clm_period_mask;
+ u32 ifs_clm_cnt_unit_mask;
+ u32 ifs_clm_cnt_clear_mask;
+ u32 ifs_collect_en_mask;
+ u32 ifs_t1_addr;
+ u32 ifs_t1_th_h_mask;
+ u32 ifs_t1_en_mask;
+ u32 ifs_t1_th_l_mask;
+ u32 ifs_t2_addr;
+ u32 ifs_t2_th_h_mask;
+ u32 ifs_t2_en_mask;
+ u32 ifs_t2_th_l_mask;
+ u32 ifs_t3_addr;
+ u32 ifs_t3_th_h_mask;
+ u32 ifs_t3_en_mask;
+ u32 ifs_t3_th_l_mask;
+ u32 ifs_t4_addr;
+ u32 ifs_t4_th_h_mask;
+ u32 ifs_t4_en_mask;
+ u32 ifs_t4_th_l_mask;
+ u32 ifs_clm_tx_cnt_addr;
+ u32 ifs_clm_edcca_excl_cca_fa_mask;
+ u32 ifs_clm_tx_cnt_msk;
+ u32 ifs_clm_cca_addr;
+ u32 ifs_clm_ofdmcca_excl_fa_mask;
+ u32 ifs_clm_cckcca_excl_fa_mask;
+ u32 ifs_clm_fa_addr;
+ u32 ifs_clm_ofdm_fa_mask;
+ u32 ifs_clm_cck_fa_mask;
+ u32 ifs_his_addr;
+ u32 ifs_t4_his_mask;
+ u32 ifs_t3_his_mask;
+ u32 ifs_t2_his_mask;
+ u32 ifs_t1_his_mask;
+ u32 ifs_avg_l_addr;
+ u32 ifs_t2_avg_mask;
+ u32 ifs_t1_avg_mask;
+ u32 ifs_avg_h_addr;
+ u32 ifs_t4_avg_mask;
+ u32 ifs_t3_avg_mask;
+ u32 ifs_cca_l_addr;
+ u32 ifs_t2_cca_mask;
+ u32 ifs_t1_cca_mask;
+ u32 ifs_cca_h_addr;
+ u32 ifs_t4_cca_mask;
+ u32 ifs_t3_cca_mask;
+ u32 ifs_total_addr;
+ u32 ifs_cnt_done_mask;
+ u32 ifs_total_mask;
+};
+
+struct rtw89_physts_regs {
+ u32 setting_addr;
+ u32 dis_trigger_fail_mask;
+ u32 dis_trigger_brk_mask;
+};
+
+struct rtw89_phy_gen_def {
+ u32 cr_base;
+ const struct rtw89_ccx_regs *ccx;
+ const struct rtw89_physts_regs *physts;
+};
+
+extern const struct rtw89_phy_gen_def rtw89_phy_gen_ax;
+extern const struct rtw89_phy_gen_def rtw89_phy_gen_be;
+
static inline void rtw89_phy_write8(struct rtw89_dev *rtwdev,
u32 addr, u8 data)
{
- rtw89_write8(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, 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)
{
- rtw89_write16(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, 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)
{
- rtw89_write32(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, 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_write32_set(struct rtw89_dev *rtwdev,
u32 addr, u32 bits)
{
- rtw89_write32_set(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, bits);
+ const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
+
+ rtw89_write32_set(rtwdev, addr + phy->cr_base, bits);
}
static inline void rtw89_phy_write32_clr(struct rtw89_dev *rtwdev,
u32 addr, u32 bits)
{
- rtw89_write32_clr(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, bits);
+ const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
+
+ rtw89_write32_clr(rtwdev, addr + phy->cr_base, bits);
}
static inline void rtw89_phy_write32_mask(struct rtw89_dev *rtwdev,
u32 addr, u32 mask, u32 data)
{
- rtw89_write32_mask(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, mask, data);
+ const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
+
+ rtw89_write32_mask(rtwdev, addr + phy->cr_base, mask, data);
}
static inline u8 rtw89_phy_read8(struct rtw89_dev *rtwdev, u32 addr)
{
- return rtw89_read8(rtwdev, addr | RTW89_PHY_ADDR_OFFSET);
+ const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
+
+ return rtw89_read8(rtwdev, addr + phy->cr_base);
}
static inline u16 rtw89_phy_read16(struct rtw89_dev *rtwdev, u32 addr)
{
- return rtw89_read16(rtwdev, addr | RTW89_PHY_ADDR_OFFSET);
+ const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
+
+ return rtw89_read16(rtwdev, addr + phy->cr_base);
}
static inline u32 rtw89_phy_read32(struct rtw89_dev *rtwdev, u32 addr)
{
- return rtw89_read32(rtwdev, addr | RTW89_PHY_ADDR_OFFSET);
+ const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
+
+ return rtw89_read32(rtwdev, addr + phy->cr_base);
}
static inline u32 rtw89_phy_read32_mask(struct rtw89_dev *rtwdev,
u32 addr, u32 mask)
{
- return rtw89_read32_mask(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, mask);
+ const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
+
+ return rtw89_read32_mask(rtwdev, addr + phy->cr_base, mask);
}
static inline
diff --git a/drivers/net/wireless/realtek/rtw89/phy_be.c b/drivers/net/wireless/realtek/rtw89/phy_be.c
new file mode 100644
index 000000000000..778e4b0c8e87
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw89/phy_be.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2023 Realtek Corporation
+ */
+
+#include "phy.h"
+#include "reg.h"
+
+static const struct rtw89_ccx_regs rtw89_ccx_regs_be = {
+ .setting_addr = R_CCX,
+ .edcca_opt_mask = B_CCX_EDCCA_OPT_MSK_V1,
+ .measurement_trig_mask = B_MEASUREMENT_TRIG_MSK,
+ .trig_opt_mask = B_CCX_TRIG_OPT_MSK,
+ .en_mask = B_CCX_EN_MSK,
+ .ifs_cnt_addr = R_IFS_COUNTER,
+ .ifs_clm_period_mask = B_IFS_CLM_PERIOD_MSK,
+ .ifs_clm_cnt_unit_mask = B_IFS_CLM_COUNTER_UNIT_MSK,
+ .ifs_clm_cnt_clear_mask = B_IFS_COUNTER_CLR_MSK,
+ .ifs_collect_en_mask = B_IFS_COLLECT_EN,
+ .ifs_t1_addr = R_IFS_T1,
+ .ifs_t1_th_h_mask = B_IFS_T1_TH_HIGH_MSK,
+ .ifs_t1_en_mask = B_IFS_T1_EN_MSK,
+ .ifs_t1_th_l_mask = B_IFS_T1_TH_LOW_MSK,
+ .ifs_t2_addr = R_IFS_T2,
+ .ifs_t2_th_h_mask = B_IFS_T2_TH_HIGH_MSK,
+ .ifs_t2_en_mask = B_IFS_T2_EN_MSK,
+ .ifs_t2_th_l_mask = B_IFS_T2_TH_LOW_MSK,
+ .ifs_t3_addr = R_IFS_T3,
+ .ifs_t3_th_h_mask = B_IFS_T3_TH_HIGH_MSK,
+ .ifs_t3_en_mask = B_IFS_T3_EN_MSK,
+ .ifs_t3_th_l_mask = B_IFS_T3_TH_LOW_MSK,
+ .ifs_t4_addr = R_IFS_T4,
+ .ifs_t4_th_h_mask = B_IFS_T4_TH_HIGH_MSK,
+ .ifs_t4_en_mask = B_IFS_T4_EN_MSK,
+ .ifs_t4_th_l_mask = B_IFS_T4_TH_LOW_MSK,
+ .ifs_clm_tx_cnt_addr = R_IFS_CLM_TX_CNT_V1,
+ .ifs_clm_edcca_excl_cca_fa_mask = B_IFS_CLM_EDCCA_EXCLUDE_CCA_FA_MSK,
+ .ifs_clm_tx_cnt_msk = B_IFS_CLM_TX_CNT_MSK,
+ .ifs_clm_cca_addr = R_IFS_CLM_CCA_V1,
+ .ifs_clm_ofdmcca_excl_fa_mask = B_IFS_CLM_OFDMCCA_EXCLUDE_FA_MSK,
+ .ifs_clm_cckcca_excl_fa_mask = B_IFS_CLM_CCKCCA_EXCLUDE_FA_MSK,
+ .ifs_clm_fa_addr = R_IFS_CLM_FA_V1,
+ .ifs_clm_ofdm_fa_mask = B_IFS_CLM_OFDM_FA_MSK,
+ .ifs_clm_cck_fa_mask = B_IFS_CLM_CCK_FA_MSK,
+ .ifs_his_addr = R_IFS_HIS_V1,
+ .ifs_t4_his_mask = B_IFS_T4_HIS_MSK,
+ .ifs_t3_his_mask = B_IFS_T3_HIS_MSK,
+ .ifs_t2_his_mask = B_IFS_T2_HIS_MSK,
+ .ifs_t1_his_mask = B_IFS_T1_HIS_MSK,
+ .ifs_avg_l_addr = R_IFS_AVG_L_V1,
+ .ifs_t2_avg_mask = B_IFS_T2_AVG_MSK,
+ .ifs_t1_avg_mask = B_IFS_T1_AVG_MSK,
+ .ifs_avg_h_addr = R_IFS_AVG_H_V1,
+ .ifs_t4_avg_mask = B_IFS_T4_AVG_MSK,
+ .ifs_t3_avg_mask = B_IFS_T3_AVG_MSK,
+ .ifs_cca_l_addr = R_IFS_CCA_L_V1,
+ .ifs_t2_cca_mask = B_IFS_T2_CCA_MSK,
+ .ifs_t1_cca_mask = B_IFS_T1_CCA_MSK,
+ .ifs_cca_h_addr = R_IFS_CCA_H_V1,
+ .ifs_t4_cca_mask = B_IFS_T4_CCA_MSK,
+ .ifs_t3_cca_mask = B_IFS_T3_CCA_MSK,
+ .ifs_total_addr = R_IFSCNT_V1,
+ .ifs_cnt_done_mask = B_IFSCNT_DONE_MSK,
+ .ifs_total_mask = B_IFSCNT_TOTAL_CNT_MSK,
+};
+
+static const struct rtw89_physts_regs rtw89_physts_regs_be = {
+ .setting_addr = R_PLCP_HISTOGRAM,
+ .dis_trigger_fail_mask = B_STS_DIS_TRIG_BY_FAIL,
+ .dis_trigger_brk_mask = B_STS_DIS_TRIG_BY_BRK,
+};
+
+const struct rtw89_phy_gen_def rtw89_phy_gen_be = {
+ .cr_base = 0x20000,
+ .ccx = &rtw89_ccx_regs_be,
+ .physts = &rtw89_physts_regs_be,
+};
+EXPORT_SYMBOL(rtw89_phy_gen_be);
diff --git a/drivers/net/wireless/realtek/rtw89/ps.c b/drivers/net/wireless/realtek/rtw89/ps.c
index 84201ef19c17..917c01e5e9ed 100644
--- a/drivers/net/wireless/realtek/rtw89/ps.c
+++ b/drivers/net/wireless/realtek/rtw89/ps.c
@@ -2,6 +2,7 @@
/* Copyright(c) 2019-2020 Realtek Corporation
*/
+#include "chan.h"
#include "coex.h"
#include "core.h"
#include "debug.h"
@@ -257,8 +258,13 @@ void rtw89_recalc_lps(struct rtw89_dev *rtwdev)
{
struct ieee80211_vif *vif, *found_vif = NULL;
struct rtw89_vif *rtwvif;
+ enum rtw89_entity_mode mode;
int count = 0;
+ mode = rtw89_get_entity_mode(rtwdev);
+ if (mode == RTW89_ENTITY_MODE_MCC)
+ goto disable_lps;
+
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
vif = rtwvif_to_vif(rtwvif);
@@ -273,8 +279,71 @@ void rtw89_recalc_lps(struct rtw89_dev *rtwdev)
if (count == 1 && found_vif->cfg.ps) {
rtwdev->lps_enabled = true;
- } else {
- rtw89_leave_lps(rtwdev);
- rtwdev->lps_enabled = false;
+ return;
}
+
+disable_lps:
+ rtw89_leave_lps(rtwdev);
+ rtwdev->lps_enabled = false;
+}
+
+void rtw89_p2p_noa_renew(struct rtw89_vif *rtwvif)
+{
+ struct rtw89_p2p_noa_setter *setter = &rtwvif->p2p_noa;
+ struct rtw89_p2p_noa_ie *ie = &setter->ie;
+ struct rtw89_p2p_ie_head *p2p_head = &ie->p2p_head;
+ struct rtw89_noa_attr_head *noa_head = &ie->noa_head;
+
+ if (setter->noa_count) {
+ setter->noa_index++;
+ setter->noa_count = 0;
+ }
+
+ memset(ie, 0, sizeof(*ie));
+
+ p2p_head->eid = WLAN_EID_VENDOR_SPECIFIC;
+ p2p_head->ie_len = 4 + sizeof(*noa_head);
+ p2p_head->oui[0] = (WLAN_OUI_WFA >> 16) & 0xff;
+ p2p_head->oui[1] = (WLAN_OUI_WFA >> 8) & 0xff;
+ p2p_head->oui[2] = (WLAN_OUI_WFA >> 0) & 0xff;
+ p2p_head->oui_type = WLAN_OUI_TYPE_WFA_P2P;
+
+ noa_head->attr_type = IEEE80211_P2P_ATTR_ABSENCE_NOTICE;
+ noa_head->attr_len = cpu_to_le16(2);
+ noa_head->index = setter->noa_index;
+ noa_head->oppps_ctwindow = 0;
+}
+
+void rtw89_p2p_noa_append(struct rtw89_vif *rtwvif,
+ const struct ieee80211_p2p_noa_desc *desc)
+{
+ struct rtw89_p2p_noa_setter *setter = &rtwvif->p2p_noa;
+ struct rtw89_p2p_noa_ie *ie = &setter->ie;
+ struct rtw89_p2p_ie_head *p2p_head = &ie->p2p_head;
+ struct rtw89_noa_attr_head *noa_head = &ie->noa_head;
+
+ if (!desc->count || !desc->duration)
+ return;
+
+ if (setter->noa_count >= RTW89_P2P_MAX_NOA_NUM)
+ return;
+
+ p2p_head->ie_len += sizeof(*desc);
+ le16_add_cpu(&noa_head->attr_len, sizeof(*desc));
+
+ ie->noa_desc[setter->noa_count++] = *desc;
+}
+
+u8 rtw89_p2p_noa_fetch(struct rtw89_vif *rtwvif, void **data)
+{
+ struct rtw89_p2p_noa_setter *setter = &rtwvif->p2p_noa;
+ struct rtw89_p2p_noa_ie *ie = &setter->ie;
+ void *tail;
+
+ if (!setter->noa_count)
+ return 0;
+
+ *data = ie;
+ tail = ie->noa_desc + setter->noa_count;
+ return tail - *data;
}
diff --git a/drivers/net/wireless/realtek/rtw89/ps.h b/drivers/net/wireless/realtek/rtw89/ps.h
index 4c18f49204b2..aff0fba71cb0 100644
--- a/drivers/net/wireless/realtek/rtw89/ps.h
+++ b/drivers/net/wireless/realtek/rtw89/ps.h
@@ -16,6 +16,10 @@ void rtw89_leave_ips(struct rtw89_dev *rtwdev);
void rtw89_set_coex_ctrl_lps(struct rtw89_dev *rtwdev, bool btc_ctrl);
void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif);
void rtw89_recalc_lps(struct rtw89_dev *rtwdev);
+void rtw89_p2p_noa_renew(struct rtw89_vif *rtwvif);
+void rtw89_p2p_noa_append(struct rtw89_vif *rtwvif,
+ const struct ieee80211_p2p_noa_desc *desc);
+u8 rtw89_p2p_noa_fetch(struct rtw89_vif *rtwvif, void **data);
static inline void rtw89_leave_ips_by_hwflags(struct rtw89_dev *rtwdev)
{
diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h
index 55595fde7494..c0aac4d3678a 100644
--- a/drivers/net/wireless/realtek/rtw89/reg.h
+++ b/drivers/net/wireless/realtek/rtw89/reg.h
@@ -3625,6 +3625,27 @@
#define B_AX_GNT_BT_TX_SW_VAL BIT(1)
#define B_AX_GNT_BT_TX_SW_CTRL BIT(0)
+#define R_BE_FILTER_MODEL_ADDR 0x0C04
+
+#define R_BE_RX_FLTR_OPT 0x11420
+#define R_BE_RX_FLTR_OPT_C1 0x15420
+#define B_BE_UID_FILTER_MASK GENMASK(31, 24)
+#define B_BE_UNSPT_TYPE BIT(22)
+#define B_BE_RX_MPDU_MAX_LEN_MASK GENMASK(21, 16)
+#define B_BE_A_FTM_REQ BIT(14)
+#define B_BE_A_ERR_PKT BIT(13)
+#define B_BE_A_UNSUP_PKT BIT(12)
+#define B_BE_A_CRC32_ERR BIT(11)
+#define B_BE_A_BCN_CHK_RULE_MASK GENMASK(9, 8)
+#define B_BE_A_BCN_CHK_EN BIT(7)
+#define B_BE_A_MC_LIST_CAM_MATCH BIT(6)
+#define B_BE_A_BC_CAM_MATCH BIT(5)
+#define B_BE_A_UC_CAM_MATCH BIT(4)
+#define B_BE_A_MC BIT(3)
+#define B_BE_A_BC BIT(2)
+#define B_BE_A_A1_MATCH BIT(1)
+#define B_BE_SNIFFER_MODE BIT(0)
+
#define RR_MOD 0x00
#define RR_MOD_V1 0x10000
#define RR_MOD_IQK GENMASK(19, 4)
@@ -3977,6 +3998,7 @@
#define B_DBCC_80P80_SEL_EVM_RPT_EN BIT(0)
#define R_CCX 0x0C00
#define B_CCX_EDCCA_OPT_MSK GENMASK(6, 4)
+#define B_CCX_EDCCA_OPT_MSK_V1 GENMASK(7, 4)
#define B_MEASUREMENT_TRIG_MSK BIT(2)
#define B_CCX_TRIG_OPT_MSK BIT(1)
#define B_CCX_EN_MSK BIT(0)
@@ -4068,32 +4090,41 @@
#define B_SWSI_R_DATA_DONE_V1 BIT(26)
#define R_TX_COUNTER 0x1A40
#define R_IFS_CLM_TX_CNT 0x1ACC
+#define R_IFS_CLM_TX_CNT_V1 0x0ECC
#define B_IFS_CLM_EDCCA_EXCLUDE_CCA_FA_MSK GENMASK(31, 16)
#define B_IFS_CLM_TX_CNT_MSK GENMASK(15, 0)
#define R_IFS_CLM_CCA 0x1AD0
+#define R_IFS_CLM_CCA_V1 0x0ED0
#define B_IFS_CLM_OFDMCCA_EXCLUDE_FA_MSK GENMASK(31, 16)
#define B_IFS_CLM_CCKCCA_EXCLUDE_FA_MSK GENMASK(15, 0)
#define R_IFS_CLM_FA 0x1AD4
+#define R_IFS_CLM_FA_V1 0x0ED4
#define B_IFS_CLM_OFDM_FA_MSK GENMASK(31, 16)
#define B_IFS_CLM_CCK_FA_MSK GENMASK(15, 0)
#define R_IFS_HIS 0x1AD8
+#define R_IFS_HIS_V1 0x0ED8
#define B_IFS_T4_HIS_MSK GENMASK(31, 24)
#define B_IFS_T3_HIS_MSK GENMASK(23, 16)
#define B_IFS_T2_HIS_MSK GENMASK(15, 8)
#define B_IFS_T1_HIS_MSK GENMASK(7, 0)
#define R_IFS_AVG_L 0x1ADC
+#define R_IFS_AVG_L_V1 0x0EDC
#define B_IFS_T2_AVG_MSK GENMASK(31, 16)
#define B_IFS_T1_AVG_MSK GENMASK(15, 0)
#define R_IFS_AVG_H 0x1AE0
+#define R_IFS_AVG_H_V1 0x0EE0
#define B_IFS_T4_AVG_MSK GENMASK(31, 16)
#define B_IFS_T3_AVG_MSK GENMASK(15, 0)
#define R_IFS_CCA_L 0x1AE4
+#define R_IFS_CCA_L_V1 0x0EE4
#define B_IFS_T2_CCA_MSK GENMASK(31, 16)
#define B_IFS_T1_CCA_MSK GENMASK(15, 0)
#define R_IFS_CCA_H 0x1AE8
+#define R_IFS_CCA_H_V1 0x0EE8
#define B_IFS_T4_CCA_MSK GENMASK(31, 16)
#define B_IFS_T3_CCA_MSK GENMASK(15, 0)
#define R_IFSCNT 0x1AEC
+#define R_IFSCNT_V1 0x0EEC
#define B_IFSCNT_DONE_MSK BIT(16)
#define B_IFSCNT_TOTAL_CNT_MSK GENMASK(15, 0)
#define R_TXAGC_TP 0x1C04
@@ -4109,6 +4140,8 @@
#define B_TXAGC_BB_OFT GENMASK(31, 16)
#define B_TXAGC_BB GENMASK(31, 24)
#define B_TXAGC_RF GENMASK(5, 0)
+#define R_PATH0_TXPWR 0x1C78
+#define B_PATH0_TXPWR GENMASK(8, 0)
#define R_S0_ADDCK 0x1E00
#define B_S0_ADDCK_I GENMASK(9, 0)
#define B_S0_ADDCK_Q GENMASK(19, 10)
@@ -4184,6 +4217,8 @@
#define R_TXAGC_BB_S1 0x3C60
#define B_TXAGC_BB_S1_OFT GENMASK(31, 16)
#define B_TXAGC_BB_S1 GENMASK(31, 24)
+#define R_PATH1_TXPWR 0x3C78
+#define B_PATH1_TXPWR GENMASK(8, 0)
#define R_S1_ADDCK 0x3E00
#define B_S1_ADDCK_I GENMASK(9, 0)
#define B_S1_ADDCK_Q GENMASK(19, 10)
@@ -4360,6 +4395,7 @@
#define B_PKT_POP_EN BIT(8)
#define R_SEG0R_PD 0x481C
#define R_SEG0R_PD_V1 0x4860
+#define R_SEG0R_PD_V2 0x6A74
#define R_SEG0R_EDCCA_LVL 0x4840
#define R_SEG0R_EDCCA_LVL_V1 0x4884
#define B_SEG0R_PPDU_LVL_MSK GENMASK(31, 24)
@@ -4478,8 +4514,10 @@
#define R_DCFO_COMP_S0_V1 0x4A40
#define B_DCFO_COMP_S0_V1_MSK GENMASK(13, 0)
#define R_BMODE_PDTH_V1 0x4B64
+#define R_BMODE_PDTH_V2 0x6708
#define B_BMODE_PDTH_LOWER_BOUND_MSK_V1 GENMASK(31, 24)
#define R_BMODE_PDTH_EN_V1 0x4B74
+#define R_BMODE_PDTH_EN_V2 0x6718
#define B_BMODE_PDTH_LIMIT_EN_MSK_V1 BIT(30)
#define R_CFO_COMP_SEG1_L 0x5384
#define R_CFO_COMP_SEG1_H 0x5388
diff --git a/drivers/net/wireless/realtek/rtw89/regd.c b/drivers/net/wireless/realtek/rtw89/regd.c
index 34c4d40cfa02..9e2328db1865 100644
--- a/drivers/net/wireless/realtek/rtw89/regd.c
+++ b/drivers/net/wireless/realtek/rtw89/regd.c
@@ -13,10 +13,10 @@
}
static const struct rtw89_regd rtw89_ww_regd =
- COUNTRY_REGD("00", RTW89_WW, RTW89_WW);
+ COUNTRY_REGD("00", RTW89_WW, RTW89_WW, RTW89_WW);
static const struct rtw89_regd rtw89_regd_map[] = {
- COUNTRY_REGD("AR", RTW89_MEXICO, RTW89_MEXICO, RTW89_NA),
+ COUNTRY_REGD("AR", RTW89_MEXICO, RTW89_MEXICO, RTW89_FCC),
COUNTRY_REGD("BO", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("BR", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("CL", RTW89_CHILE, RTW89_CHILE, RTW89_CHILE),
@@ -26,7 +26,7 @@ static const struct rtw89_regd rtw89_regd_map[] = {
COUNTRY_REGD("SV", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("GT", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("HN", RTW89_FCC, RTW89_FCC, RTW89_FCC),
- COUNTRY_REGD("MX", RTW89_MEXICO, RTW89_MEXICO, RTW89_NA),
+ COUNTRY_REGD("MX", RTW89_MEXICO, RTW89_MEXICO, RTW89_FCC),
COUNTRY_REGD("NI", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("PA", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("PY", RTW89_FCC, RTW89_FCC, RTW89_NA),
@@ -81,7 +81,7 @@ static const struct rtw89_regd rtw89_regd_map[] = {
COUNTRY_REGD("KE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("KW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("KG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("LB", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
+ COUNTRY_REGD("LB", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("LS", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("MK", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("MA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
@@ -96,7 +96,7 @@ static const struct rtw89_regd rtw89_regd_map[] = {
COUNTRY_REGD("SN", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("RS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("ME", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("ZA", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
+ COUNTRY_REGD("ZA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("TR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("UA", RTW89_UKRAINE, RTW89_UKRAINE, RTW89_UKRAINE),
COUNTRY_REGD("AE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
@@ -115,7 +115,7 @@ static const struct rtw89_regd rtw89_regd_map[] = {
COUNTRY_REGD("SG", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("LK", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("TW", RTW89_FCC, RTW89_FCC, RTW89_NA),
- COUNTRY_REGD("TH", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
+ COUNTRY_REGD("TH", RTW89_WW, RTW89_WW, RTW89_WW),
COUNTRY_REGD("VN", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("AU", RTW89_ACMA, RTW89_ACMA, RTW89_ACMA),
COUNTRY_REGD("NZ", RTW89_ACMA, RTW89_ACMA, RTW89_ACMA),
@@ -148,7 +148,7 @@ static const struct rtw89_regd rtw89_regd_map[] = {
COUNTRY_REGD("IO", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("VG", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("BN", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("BF", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
+ COUNTRY_REGD("BF", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("MM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("BI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("CM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
@@ -164,7 +164,7 @@ static const struct rtw89_regd rtw89_regd_map[] = {
COUNTRY_REGD("CK", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("CI", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("DJ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("DM", RTW89_FCC, RTW89_FCC, RTW89_FCC),
+ COUNTRY_REGD("DM", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("GQ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("ER", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("ET", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
@@ -179,20 +179,21 @@ static const struct rtw89_regd rtw89_regd_map[] = {
COUNTRY_REGD("GE", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("GI", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("GL", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("GD", RTW89_FCC, RTW89_FCC, RTW89_FCC),
+ COUNTRY_REGD("GD", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("GP", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("GU", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("GG", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("GN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("GW", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("GY", RTW89_FCC, RTW89_FCC, RTW89_FCC),
- COUNTRY_REGD("HT", RTW89_FCC, RTW89_FCC, RTW89_NA),
+ COUNTRY_REGD("GY", RTW89_FCC, RTW89_FCC, RTW89_NA),
+ COUNTRY_REGD("HT", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("HM", RTW89_ACMA, RTW89_ACMA, RTW89_NA),
COUNTRY_REGD("VA", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("IM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("JE", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("KI", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
- COUNTRY_REGD("LA", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
+ COUNTRY_REGD("XK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
+ COUNTRY_REGD("LA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("LR", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("LY", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("MO", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
@@ -207,7 +208,7 @@ static const struct rtw89_regd rtw89_regd_map[] = {
COUNTRY_REGD("YT", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("FM", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("MD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
- COUNTRY_REGD("MN", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
+ COUNTRY_REGD("MN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("MS", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("NR", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("NP", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b.c b/drivers/net/wireless/realtek/rtw89/rtw8851b.c
index c3ffcb645ebf..103893f28b51 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c
@@ -185,6 +185,10 @@ static const struct rtw89_dig_regs rtw8851b_dig_regs = {
.seg0_pd_reg = R_SEG0R_PD_V1,
.pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK,
.pd_spatial_reuse_en = B_SEG0R_PD_SPATIAL_REUSE_EN_MSK_V1,
+ .bmode_pd_reg = R_BMODE_PDTH_EN_V1,
+ .bmode_cca_rssi_limit_en = B_BMODE_PDTH_LIMIT_EN_MSK_V1,
+ .bmode_pd_lower_bound_reg = R_BMODE_PDTH_V1,
+ .bmode_rssi_nocca_low_th_mask = B_BMODE_PDTH_LOWER_BOUND_MSK_V1,
.p0_lna_init = {R_PATH0_LNA_INIT_V1, B_PATH0_LNA_INIT_IDX_MSK},
.p1_lna_init = {R_PATH1_LNA_INIT_V1, B_PATH1_LNA_INIT_IDX_MSK},
.p0_tia_init = {R_PATH0_TIA_INIT_V1, B_PATH0_TIA_INIT_IDX_MSK_V1},
@@ -756,9 +760,9 @@ static void rtw8851b_set_channel_mac(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
u8 mac_idx)
{
- u32 sub_carr = rtw89_mac_reg_by_idx(R_AX_TX_SUB_CARRIER_VALUE, mac_idx);
- u32 chk_rate = rtw89_mac_reg_by_idx(R_AX_TXRATE_CHK, mac_idx);
- u32 rf_mod = rtw89_mac_reg_by_idx(R_AX_WMAC_RFMOD, mac_idx);
+ u32 sub_carr = rtw89_mac_reg_by_idx(rtwdev, R_AX_TX_SUB_CARRIER_VALUE, mac_idx);
+ u32 chk_rate = rtw89_mac_reg_by_idx(rtwdev, R_AX_TXRATE_CHK, mac_idx);
+ u32 rf_mod = rtw89_mac_reg_by_idx(rtwdev, R_AX_WMAC_RFMOD, mac_idx);
u8 txsc20 = 0, txsc40 = 0;
switch (chan->band_width) {
@@ -1740,14 +1744,14 @@ void rtw8851b_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
return;
}
- reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_CTRL, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_CTRL, mac_idx);
rtw89_write32_set(rtwdev, reg, B_AX_PWR_UL_TB_CTRL_EN);
- reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_1T, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_1T, mac_idx);
rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_1T_MASK, pw_ofst);
pw_ofst = max_t(s8, pw_ofst - 3, -16);
- reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_2T, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_2T, mac_idx);
rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_2T_MASK, pw_ofst);
}
@@ -2334,10 +2338,14 @@ static const struct wiphy_wowlan_support rtw_wowlan_stub_8851b = {
const struct rtw89_chip_info rtw8851b_chip_info = {
.chip_id = RTL8851B,
+ .chip_gen = RTW89_CHIP_AX,
.ops = &rtw8851b_chip_ops,
+ .mac_def = &rtw89_mac_gen_ax,
+ .phy_def = &rtw89_phy_gen_ax,
.fw_basename = RTW8851B_FW_BASENAME,
.fw_format_max = RTW8851B_FW_FORMAT_MAX,
.try_ce_fw = true,
+ .needed_fw_elms = 0,
.fifo_size = 196608,
.small_fifo_size = true,
.dle_scc_rsvd_size = 98304,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
index 6257414a3b4b..d068eae6a2f0 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
@@ -478,6 +478,10 @@ static const struct rtw89_dig_regs rtw8852a_dig_regs = {
.seg0_pd_reg = R_SEG0R_PD,
.pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK,
.pd_spatial_reuse_en = B_SEG0R_PD_SPATIAL_REUSE_EN_MSK,
+ .bmode_pd_reg = R_BMODE_PDTH_EN_V1,
+ .bmode_cca_rssi_limit_en = B_BMODE_PDTH_LIMIT_EN_MSK_V1,
+ .bmode_pd_lower_bound_reg = R_BMODE_PDTH_V1,
+ .bmode_rssi_nocca_low_th_mask = B_BMODE_PDTH_LOWER_BOUND_MSK_V1,
.p0_lna_init = {R_PATH0_LNA_INIT, B_PATH0_LNA_INIT_IDX_MSK},
.p1_lna_init = {R_PATH1_LNA_INIT, B_PATH1_LNA_INIT_IDX_MSK},
.p0_tia_init = {R_PATH0_TIA_INIT, B_PATH0_TIA_INIT_IDX_MSK},
@@ -704,10 +708,9 @@ static void rtw8852a_set_channel_mac(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
u8 mac_idx)
{
- u32 rf_mod = rtw89_mac_reg_by_idx(R_AX_WMAC_RFMOD, mac_idx);
- u32 sub_carr = rtw89_mac_reg_by_idx(R_AX_TX_SUB_CARRIER_VALUE,
- mac_idx);
- u32 chk_rate = rtw89_mac_reg_by_idx(R_AX_TXRATE_CHK, mac_idx);
+ u32 rf_mod = rtw89_mac_reg_by_idx(rtwdev, R_AX_WMAC_RFMOD, mac_idx);
+ u32 sub_carr = rtw89_mac_reg_by_idx(rtwdev, R_AX_TX_SUB_CARRIER_VALUE, mac_idx);
+ u32 chk_rate = rtw89_mac_reg_by_idx(rtwdev, R_AX_TXRATE_CHK, mac_idx);
u8 txsc20 = 0, txsc40 = 0;
switch (chan->band_width) {
@@ -1380,13 +1383,13 @@ void rtw8852a_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
pw_ofst);
return;
}
- reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_CTRL, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_CTRL, mac_idx);
rtw89_write32_set(rtwdev, reg, B_AX_PWR_UL_TB_CTRL_EN);
val_1t = pw_ofst;
- reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_1T, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_1T, mac_idx);
rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_1T_MASK, val_1t);
val_2t = max(val_1t - 3, -16);
- reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_2T, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_2T, mac_idx);
rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_2T_MASK, val_2t);
rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[ULTB] Set TB pwr_offset=(%d, %d)\n",
val_1t, val_2t);
@@ -2071,10 +2074,14 @@ static const struct rtw89_chip_ops rtw8852a_chip_ops = {
const struct rtw89_chip_info rtw8852a_chip_info = {
.chip_id = RTL8852A,
+ .chip_gen = RTW89_CHIP_AX,
.ops = &rtw8852a_chip_ops,
+ .mac_def = &rtw89_mac_gen_ax,
+ .phy_def = &rtw89_phy_gen_ax,
.fw_basename = RTW8852A_FW_BASENAME,
.fw_format_max = RTW8852A_FW_FORMAT_MAX,
.try_ce_fw = false,
+ .needed_fw_elms = 0,
.fifo_size = 458752,
.small_fifo_size = false,
.dle_scc_rsvd_size = 0,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c
index 718f993da62a..0063301952b3 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c
@@ -310,6 +310,10 @@ static const struct rtw89_dig_regs rtw8852b_dig_regs = {
.seg0_pd_reg = R_SEG0R_PD_V1,
.pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK,
.pd_spatial_reuse_en = B_SEG0R_PD_SPATIAL_REUSE_EN_MSK_V1,
+ .bmode_pd_reg = R_BMODE_PDTH_EN_V1,
+ .bmode_cca_rssi_limit_en = B_BMODE_PDTH_LIMIT_EN_MSK_V1,
+ .bmode_pd_lower_bound_reg = R_BMODE_PDTH_V1,
+ .bmode_rssi_nocca_low_th_mask = B_BMODE_PDTH_LOWER_BOUND_MSK_V1,
.p0_lna_init = {R_PATH0_LNA_INIT_V1, B_PATH0_LNA_INIT_IDX_MSK},
.p1_lna_init = {R_PATH1_LNA_INIT_V1, B_PATH1_LNA_INIT_IDX_MSK},
.p0_tia_init = {R_PATH0_TIA_INIT_V1, B_PATH0_TIA_INIT_IDX_MSK_V1},
@@ -843,9 +847,9 @@ static void rtw8852b_set_channel_mac(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
u8 mac_idx)
{
- u32 rf_mod = rtw89_mac_reg_by_idx(R_AX_WMAC_RFMOD, mac_idx);
- u32 sub_carr = rtw89_mac_reg_by_idx(R_AX_TX_SUB_CARRIER_VALUE, mac_idx);
- u32 chk_rate = rtw89_mac_reg_by_idx(R_AX_TXRATE_CHK, mac_idx);
+ u32 rf_mod = rtw89_mac_reg_by_idx(rtwdev, R_AX_WMAC_RFMOD, mac_idx);
+ u32 sub_carr = rtw89_mac_reg_by_idx(rtwdev, R_AX_TX_SUB_CARRIER_VALUE, mac_idx);
+ u32 chk_rate = rtw89_mac_reg_by_idx(rtwdev, R_AX_TXRATE_CHK, mac_idx);
u8 txsc20 = 0, txsc40 = 0;
switch (chan->band_width) {
@@ -1725,14 +1729,14 @@ void rtw8852b_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
return;
}
- reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_CTRL, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_CTRL, mac_idx);
rtw89_write32_set(rtwdev, reg, B_AX_PWR_UL_TB_CTRL_EN);
- reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_1T, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_1T, mac_idx);
rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_1T_MASK, pw_ofst);
pw_ofst = max_t(s8, pw_ofst - 3, -16);
- reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_2T, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_2T, mac_idx);
rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_2T_MASK, pw_ofst);
}
@@ -2503,10 +2507,14 @@ static const struct wiphy_wowlan_support rtw_wowlan_stub_8852b = {
const struct rtw89_chip_info rtw8852b_chip_info = {
.chip_id = RTL8852B,
+ .chip_gen = RTW89_CHIP_AX,
.ops = &rtw8852b_chip_ops,
+ .mac_def = &rtw89_mac_gen_ax,
+ .phy_def = &rtw89_phy_gen_ax,
.fw_basename = RTW8852B_FW_BASENAME,
.fw_format_max = RTW8852B_FW_FORMAT_MAX,
.try_ce_fw = true,
+ .needed_fw_elms = 0,
.fifo_size = 196608,
.small_fifo_size = true,
.dle_scc_rsvd_size = 98304,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c
index fa018e1f499b..259df67836a0 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c
@@ -846,7 +846,7 @@ static bool _iqk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
case ID_NBTXK:
rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0);
rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x011);
- iqk_cmd = 0x308 | (1 << (4 + path));
+ iqk_cmd = 0x408 | (1 << (4 + path));
break;
case ID_NBRXK:
rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
@@ -1078,7 +1078,7 @@ static bool _iqk_nbtxk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8
{
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
bool kfail;
- u8 gp = 0x3;
+ u8 gp = 0x2;
switch (iqk_info->iqk_band[path]) {
case RTW89_BAND_2G:
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
index 9c7c9812d4f4..1e16cc0a05dc 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
@@ -146,6 +146,10 @@ static const struct rtw89_dig_regs rtw8852c_dig_regs = {
.seg0_pd_reg = R_SEG0R_PD,
.pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK,
.pd_spatial_reuse_en = B_SEG0R_PD_SPATIAL_REUSE_EN_MSK,
+ .bmode_pd_reg = R_BMODE_PDTH_EN_V1,
+ .bmode_cca_rssi_limit_en = B_BMODE_PDTH_LIMIT_EN_MSK_V1,
+ .bmode_pd_lower_bound_reg = R_BMODE_PDTH_V1,
+ .bmode_rssi_nocca_low_th_mask = B_BMODE_PDTH_LOWER_BOUND_MSK_V1,
.p0_lna_init = {R_PATH0_LNA_INIT_V1, B_PATH0_LNA_INIT_IDX_MSK},
.p1_lna_init = {R_PATH1_LNA_INIT_V1, B_PATH1_LNA_INIT_IDX_MSK},
.p0_tia_init = {R_PATH0_TIA_INIT_V1, B_PATH0_TIA_INIT_IDX_MSK_V1},
@@ -606,10 +610,9 @@ static void rtw8852c_set_channel_mac(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
u8 mac_idx)
{
- u32 rf_mod = rtw89_mac_reg_by_idx(R_AX_WMAC_RFMOD, mac_idx);
- u32 sub_carr = rtw89_mac_reg_by_idx(R_AX_TX_SUB_CARRIER_VALUE,
- mac_idx);
- u32 chk_rate = rtw89_mac_reg_by_idx(R_AX_TXRATE_CHK, mac_idx);
+ u32 rf_mod = rtw89_mac_reg_by_idx(rtwdev, R_AX_WMAC_RFMOD, mac_idx);
+ u32 sub_carr = rtw89_mac_reg_by_idx(rtwdev, R_AX_TX_SUB_CARRIER_VALUE, mac_idx);
+ u32 chk_rate = rtw89_mac_reg_by_idx(rtwdev, R_AX_TXRATE_CHK, mac_idx);
u8 txsc20 = 0, txsc40 = 0, txsc80 = 0;
u8 rf_mod_val = 0, chk_rate_mask = 0;
u32 txsc;
@@ -1654,8 +1657,7 @@ static void rtw8852c_set_channel_bb(struct rtw89_dev *rtwdev,
rtwdev->hal.cv != CHIP_CAV) {
rtw89_phy_write32_idx(rtwdev, R_P80_AT_HIGH_FREQ,
B_P80_AT_HIGH_FREQ, 0x0, phy_idx);
- reg = rtw89_mac_reg_by_idx(R_P80_AT_HIGH_FREQ_BB_WRP,
- phy_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_P80_AT_HIGH_FREQ_BB_WRP, phy_idx);
if (chan->primary_channel > chan->channel) {
rtw89_phy_write32_mask(rtwdev,
R_P80_AT_HIGH_FREQ_RU_ALLOC,
@@ -1859,12 +1861,12 @@ void rtw8852c_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
for (i = 0; i < 4; i++) {
/* 1TX */
- reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_1T, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_1T, mac_idx);
rtw89_write32_mask(rtwdev, reg,
B_AX_PWR_UL_TB_1T_V1_MASK << (8 * i),
val_1t);
/* 2TX */
- reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_2T, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_2T, mac_idx);
rtw89_write32_mask(rtwdev, reg,
B_AX_PWR_UL_TB_2T_V1_MASK << (8 * i),
val_2t);
@@ -2181,7 +2183,7 @@ static void rtw8852c_ctrl_tx_path_tmac(struct rtw89_dev *rtwdev, u8 tx_path,
for (addr = R_AX_MACID_ANT_TABLE;
addr <= R_AX_MACID_ANT_TABLE_LAST; addr += 4) {
- reg = rtw89_mac_reg_by_idx(addr, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, addr, mac_idx);
rtw89_write32(rtwdev, reg, 0);
}
@@ -2211,7 +2213,7 @@ static void rtw8852c_ctrl_tx_path_tmac(struct rtw89_dev *rtwdev, u8 tx_path,
for (i = 0; i < cr_size; i++) {
rtw89_debug(rtwdev, RTW89_DBG_TSSI, "0x%x = 0x%x\n",
path_com[i].addr, path_com[i].data);
- reg = rtw89_mac_reg_by_idx(path_com[i].addr, mac_idx);
+ reg = rtw89_mac_reg_by_idx(rtwdev, path_com[i].addr, mac_idx);
rtw89_write32(rtwdev, reg, path_com[i].data);
}
}
@@ -2802,10 +2804,14 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = {
const struct rtw89_chip_info rtw8852c_chip_info = {
.chip_id = RTL8852C,
+ .chip_gen = RTW89_CHIP_AX,
.ops = &rtw8852c_chip_ops,
+ .mac_def = &rtw89_mac_gen_ax,
+ .phy_def = &rtw89_phy_gen_ax,
.fw_basename = RTW8852C_FW_BASENAME,
.fw_format_max = RTW8852C_FW_FORMAT_MAX,
.try_ce_fw = false,
+ .needed_fw_elms = 0,
.fifo_size = 458752,
.small_fifo_size = false,
.dle_scc_rsvd_size = 0,
diff --git a/drivers/net/wireless/realtek/rtw89/sar.c b/drivers/net/wireless/realtek/rtw89/sar.c
index dfccae81c380..aed05b026c6c 100644
--- a/drivers/net/wireless/realtek/rtw89/sar.c
+++ b/drivers/net/wireless/realtek/rtw89/sar.c
@@ -2,9 +2,16 @@
/* Copyright(c) 2019-2020 Realtek Corporation
*/
+#include "acpi.h"
#include "debug.h"
+#include "phy.h"
+#include "reg.h"
#include "sar.h"
+#define RTW89_TAS_FACTOR 2 /* unit: 0.25 dBm */
+#define RTW89_TAS_DPR_GAP (1 << RTW89_TAS_FACTOR)
+#define RTW89_TAS_DELTA (2 << RTW89_TAS_FACTOR)
+
static enum rtw89_sar_subband rtw89_sar_get_subband(struct rtw89_dev *rtwdev,
u32 center_freq)
{
@@ -78,17 +85,15 @@ static const struct rtw89_sar_span rtw89_sar_overlapping_6ghz[] = {
RTW89_DECL_SAR_6GHZ_SPAN(6885, SUBBAND_7_H, SUBBAND_8),
};
-static int rtw89_query_sar_config_common(struct rtw89_dev *rtwdev, s32 *cfg)
+static int rtw89_query_sar_config_common(struct rtw89_dev *rtwdev,
+ u32 center_freq, s32 *cfg)
{
struct rtw89_sar_cfg_common *rtwsar = &rtwdev->sar.cfg_common;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
- enum rtw89_band band = chan->band_type;
- u32 center_freq = chan->freq;
const struct rtw89_sar_span *span = NULL;
enum rtw89_sar_subband subband_l, subband_h;
int idx;
- if (band == RTW89_BAND_6G) {
+ if (center_freq >= RTW89_SAR_6GHZ_SPAN_HEAD) {
idx = RTW89_SAR_6GHZ_SPAN_IDX(center_freq);
/* To decrease size of rtw89_sar_overlapping_6ghz[],
* RTW89_SAR_6GHZ_SPAN_IDX() truncates the leading NULLs
@@ -108,8 +113,8 @@ static int rtw89_query_sar_config_common(struct rtw89_dev *rtwdev, s32 *cfg)
}
rtw89_debug(rtwdev, RTW89_DBG_SAR,
- "for {band %u, center_freq %u}, SAR subband: {%u, %u}\n",
- band, center_freq, subband_l, subband_h);
+ "center_freq %u: SAR subband {%u, %u}\n",
+ center_freq, subband_l, subband_h);
if (!rtwsar->set[subband_l] && !rtwsar->set[subband_h])
return -ENODATA;
@@ -157,11 +162,35 @@ static s8 rtw89_txpwr_sar_to_mac(struct rtw89_dev *rtwdev, u8 fct, s32 cfg)
RTW89_SAR_TXPWR_MAC_MAX);
}
-s8 rtw89_query_sar(struct rtw89_dev *rtwdev)
+static s8 rtw89_txpwr_tas_to_sar(const struct rtw89_sar_handler *sar_hdl,
+ s8 cfg)
+{
+ const u8 fct = sar_hdl->txpwr_factor_sar;
+
+ if (fct > RTW89_TAS_FACTOR)
+ return cfg << (fct - RTW89_TAS_FACTOR);
+ else
+ return cfg >> (RTW89_TAS_FACTOR - fct);
+}
+
+static s8 rtw89_txpwr_sar_to_tas(const struct rtw89_sar_handler *sar_hdl,
+ s8 cfg)
+{
+ const u8 fct = sar_hdl->txpwr_factor_sar;
+
+ if (fct > RTW89_TAS_FACTOR)
+ return cfg >> (fct - RTW89_TAS_FACTOR);
+ else
+ return cfg << (RTW89_TAS_FACTOR - fct);
+}
+
+s8 rtw89_query_sar(struct rtw89_dev *rtwdev, u32 center_freq)
{
const enum rtw89_sar_sources src = rtwdev->sar.src;
/* its members are protected by rtw89_sar_set_src() */
const struct rtw89_sar_handler *sar_hdl = &rtw89_sar_handlers[src];
+ struct rtw89_tas_info *tas = &rtwdev->tas;
+ s8 delta;
int ret;
s32 cfg;
u8 fct;
@@ -171,16 +200,30 @@ s8 rtw89_query_sar(struct rtw89_dev *rtwdev)
if (src == RTW89_SAR_SOURCE_NONE)
return RTW89_SAR_TXPWR_MAC_MAX;
- ret = sar_hdl->query_sar_config(rtwdev, &cfg);
+ ret = sar_hdl->query_sar_config(rtwdev, center_freq, &cfg);
if (ret)
return RTW89_SAR_TXPWR_MAC_MAX;
+ if (tas->enable) {
+ switch (tas->state) {
+ case RTW89_TAS_STATE_DPR_OFF:
+ return RTW89_SAR_TXPWR_MAC_MAX;
+ case RTW89_TAS_STATE_DPR_ON:
+ delta = rtw89_txpwr_tas_to_sar(sar_hdl, tas->delta);
+ cfg -= delta;
+ break;
+ case RTW89_TAS_STATE_DPR_FORBID:
+ default:
+ break;
+ }
+ }
+
fct = sar_hdl->txpwr_factor_sar;
return rtw89_txpwr_sar_to_mac(rtwdev, fct, cfg);
}
-void rtw89_print_sar(struct seq_file *m, struct rtw89_dev *rtwdev)
+void rtw89_print_sar(struct seq_file *m, struct rtw89_dev *rtwdev, u32 center_freq)
{
const enum rtw89_sar_sources src = rtwdev->sar.src;
/* its members are protected by rtw89_sar_set_src() */
@@ -199,7 +242,7 @@ void rtw89_print_sar(struct seq_file *m, struct rtw89_dev *rtwdev)
seq_printf(m, "source: %d (%s)\n", src, sar_hdl->descr_sar_source);
- ret = sar_hdl->query_sar_config(rtwdev, &cfg);
+ ret = sar_hdl->query_sar_config(rtwdev, center_freq, &cfg);
if (ret) {
seq_printf(m, "config: return code: %d\n", ret);
seq_printf(m, "assign: max setting: %d (unit: 1/%lu dBm)\n",
@@ -212,6 +255,19 @@ void rtw89_print_sar(struct seq_file *m, struct rtw89_dev *rtwdev)
seq_printf(m, "config: %d (unit: 1/%lu dBm)\n", cfg, BIT(fct));
}
+void rtw89_print_tas(struct seq_file *m, struct rtw89_dev *rtwdev)
+{
+ struct rtw89_tas_info *tas = &rtwdev->tas;
+
+ if (!tas->enable) {
+ seq_puts(m, "no TAS is applied\n");
+ return;
+ }
+
+ seq_printf(m, "DPR gap: %d\n", tas->dpr_gap);
+ seq_printf(m, "TAS delta: %d\n", tas->delta);
+}
+
static int rtw89_apply_sar_common(struct rtw89_dev *rtwdev,
const struct rtw89_sar_cfg_common *sar)
{
@@ -292,3 +348,145 @@ int rtw89_ops_set_sar_specs(struct ieee80211_hw *hw,
return rtw89_apply_sar_common(rtwdev, &sar_common);
}
+
+static void rtw89_tas_state_update(struct rtw89_dev *rtwdev)
+{
+ const enum rtw89_sar_sources src = rtwdev->sar.src;
+ /* its members are protected by rtw89_sar_set_src() */
+ const struct rtw89_sar_handler *sar_hdl = &rtw89_sar_handlers[src];
+ struct rtw89_tas_info *tas = &rtwdev->tas;
+ s32 txpwr_avg = tas->total_txpwr / RTW89_TAS_MAX_WINDOW / PERCENT;
+ s32 dpr_on_threshold, dpr_off_threshold, cfg;
+ enum rtw89_tas_state state = tas->state;
+ const struct rtw89_chan *chan;
+ int ret;
+
+ lockdep_assert_held(&rtwdev->mutex);
+
+ if (src == RTW89_SAR_SOURCE_NONE)
+ return;
+
+ chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ ret = sar_hdl->query_sar_config(rtwdev, chan->freq, &cfg);
+ if (ret)
+ return;
+
+ cfg = rtw89_txpwr_sar_to_tas(sar_hdl, cfg);
+
+ if (tas->delta >= cfg) {
+ rtw89_debug(rtwdev, RTW89_DBG_SAR,
+ "TAS delta exceed SAR limit\n");
+ state = RTW89_TAS_STATE_DPR_FORBID;
+ goto out;
+ }
+
+ dpr_on_threshold = cfg;
+ dpr_off_threshold = cfg - tas->dpr_gap;
+ rtw89_debug(rtwdev, RTW89_DBG_SAR,
+ "DPR_ON thold: %d, DPR_OFF thold: %d, txpwr_avg: %d\n",
+ dpr_on_threshold, dpr_off_threshold, txpwr_avg);
+
+ if (txpwr_avg >= dpr_on_threshold)
+ state = RTW89_TAS_STATE_DPR_ON;
+ else if (txpwr_avg < dpr_off_threshold)
+ state = RTW89_TAS_STATE_DPR_OFF;
+
+out:
+ if (tas->state == state)
+ return;
+
+ rtw89_debug(rtwdev, RTW89_DBG_SAR,
+ "TAS old state: %d, new state: %d\n", tas->state, state);
+ tas->state = state;
+ rtw89_core_set_chip_txpwr(rtwdev);
+}
+
+void rtw89_tas_init(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_tas_info *tas = &rtwdev->tas;
+ int ret;
+ u8 val;
+
+ ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_TAS_EN, &val);
+ if (ret) {
+ rtw89_debug(rtwdev, RTW89_DBG_SAR,
+ "acpi: cannot get TAS: %d\n", ret);
+ return;
+ }
+
+ switch (val) {
+ case 0:
+ tas->enable = false;
+ break;
+ case 1:
+ tas->enable = true;
+ break;
+ default:
+ break;
+ }
+
+ if (!tas->enable) {
+ rtw89_debug(rtwdev, RTW89_DBG_SAR, "TAS not enable\n");
+ return;
+ }
+
+ tas->dpr_gap = RTW89_TAS_DPR_GAP;
+ tas->delta = RTW89_TAS_DELTA;
+}
+
+void rtw89_tas_reset(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_tas_info *tas = &rtwdev->tas;
+
+ if (!tas->enable)
+ return;
+
+ memset(&tas->txpwr_history, 0, sizeof(tas->txpwr_history));
+ tas->total_txpwr = 0;
+ tas->cur_idx = 0;
+ tas->state = RTW89_TAS_STATE_DPR_OFF;
+}
+
+static const struct rtw89_reg_def txpwr_regs[] = {
+ {R_PATH0_TXPWR, B_PATH0_TXPWR},
+ {R_PATH1_TXPWR, B_PATH1_TXPWR},
+};
+
+void rtw89_tas_track(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor;
+ const enum rtw89_sar_sources src = rtwdev->sar.src;
+ u8 max_nss_num = rtwdev->chip->rf_path_num;
+ struct rtw89_tas_info *tas = &rtwdev->tas;
+ s16 tmp, txpwr, instant_txpwr = 0;
+ u32 val;
+ int i;
+
+ if (!tas->enable || src == RTW89_SAR_SOURCE_NONE)
+ return;
+
+ if (env->ccx_watchdog_result != RTW89_PHY_ENV_MON_IFS_CLM)
+ return;
+
+ for (i = 0; i < max_nss_num; i++) {
+ val = rtw89_phy_read32_mask(rtwdev, txpwr_regs[i].addr,
+ txpwr_regs[i].mask);
+ tmp = sign_extend32(val, 8);
+ if (tmp <= 0)
+ return;
+ instant_txpwr += tmp;
+ }
+
+ instant_txpwr /= max_nss_num;
+ /* in unit of 0.25 dBm multiply by percentage */
+ txpwr = instant_txpwr * env->ifs_clm_tx_ratio;
+ tas->total_txpwr += txpwr - tas->txpwr_history[tas->cur_idx];
+ tas->txpwr_history[tas->cur_idx] = txpwr;
+ rtw89_debug(rtwdev, RTW89_DBG_SAR,
+ "instant_txpwr: %d, tx_ratio: %d, txpwr: %d\n",
+ instant_txpwr, env->ifs_clm_tx_ratio, txpwr);
+
+ tas->cur_idx = (tas->cur_idx + 1) % RTW89_TAS_MAX_WINDOW;
+
+ rtw89_tas_state_update(rtwdev);
+}
diff --git a/drivers/net/wireless/realtek/rtw89/sar.h b/drivers/net/wireless/realtek/rtw89/sar.h
index 7b5484c84eb1..bd7a657188d9 100644
--- a/drivers/net/wireless/realtek/rtw89/sar.h
+++ b/drivers/net/wireless/realtek/rtw89/sar.h
@@ -13,14 +13,18 @@
struct rtw89_sar_handler {
const char *descr_sar_source;
u8 txpwr_factor_sar;
- int (*query_sar_config)(struct rtw89_dev *rtwdev, s32 *cfg);
+ int (*query_sar_config)(struct rtw89_dev *rtwdev, u32 center_freq, s32 *cfg);
};
extern const struct cfg80211_sar_capa rtw89_sar_capa;
-s8 rtw89_query_sar(struct rtw89_dev *rtwdev);
-void rtw89_print_sar(struct seq_file *m, struct rtw89_dev *rtwdev);
+s8 rtw89_query_sar(struct rtw89_dev *rtwdev, u32 center_freq);
+void rtw89_print_sar(struct seq_file *m, struct rtw89_dev *rtwdev, u32 center_freq);
+void rtw89_print_tas(struct seq_file *m, struct rtw89_dev *rtwdev);
int rtw89_ops_set_sar_specs(struct ieee80211_hw *hw,
const struct cfg80211_sar_specs *sar);
+void rtw89_tas_init(struct rtw89_dev *rtwdev);
+void rtw89_tas_reset(struct rtw89_dev *rtwdev);
+void rtw89_tas_track(struct rtw89_dev *rtwdev);
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c
index 0462ba693f6f..c1644353053f 100644
--- a/drivers/net/wireless/realtek/rtw89/ser.c
+++ b/drivers/net/wireless/realtek/rtw89/ser.c
@@ -529,6 +529,9 @@ static void ser_do_hci_st_hdl(struct rtw89_ser *ser, u8 evt)
static void ser_mac_mem_dump(struct rtw89_dev *rtwdev, u8 *buf,
u8 sel, u32 start_addr, u32 len)
{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+ u32 filter_model_addr = mac->filter_model_addr;
+ u32 indir_access_addr = mac->indir_access_addr;
u32 *ptr = (u32 *)buf;
u32 base_addr, start_page, residue;
u32 cnt = 0;
@@ -536,14 +539,14 @@ static void ser_mac_mem_dump(struct rtw89_dev *rtwdev, u8 *buf,
start_page = start_addr / MAC_MEM_DUMP_PAGE_SIZE;
residue = start_addr % MAC_MEM_DUMP_PAGE_SIZE;
- base_addr = rtw89_mac_mem_base_addrs[sel];
+ base_addr = mac->mem_base_addrs[sel];
base_addr += start_page * MAC_MEM_DUMP_PAGE_SIZE;
while (cnt < len) {
- rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, base_addr);
+ rtw89_write32(rtwdev, filter_model_addr, base_addr);
- for (i = R_AX_INDIR_ACCESS_ENTRY + residue;
- i < R_AX_INDIR_ACCESS_ENTRY + MAC_MEM_DUMP_PAGE_SIZE;
+ for (i = indir_access_addr + residue;
+ i < indir_access_addr + MAC_MEM_DUMP_PAGE_SIZE;
i += 4, ptr++) {
*ptr = rtw89_read32(rtwdev, i);
cnt += 4;
@@ -585,6 +588,9 @@ static int rtw89_ser_fw_backtrace_dump(struct rtw89_dev *rtwdev, u8 *buf,
const struct __fw_backtrace_entry *ent)
{
struct __fw_backtrace_info *ptr = (struct __fw_backtrace_info *)buf;
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+ u32 filter_model_addr = mac->filter_model_addr;
+ u32 indir_access_addr = mac->indir_access_addr;
u32 fwbt_addr = ent->wcpu_addr & RTW89_WCPU_BASE_MASK;
u32 fwbt_size = ent->size;
u32 fwbt_key = ent->key;
@@ -610,10 +616,10 @@ static int rtw89_ser_fw_backtrace_dump(struct rtw89_dev *rtwdev, u8 *buf,
}
rtw89_debug(rtwdev, RTW89_DBG_SER, "dump fw backtrace start\n");
- rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, fwbt_addr);
+ rtw89_write32(rtwdev, filter_model_addr, fwbt_addr);
- for (i = R_AX_INDIR_ACCESS_ENTRY;
- i < R_AX_INDIR_ACCESS_ENTRY + fwbt_size;
+ for (i = indir_access_addr;
+ i < indir_access_addr + fwbt_size;
i += RTW89_FW_BACKTRACE_INFO_SIZE, ptr++) {
*ptr = (struct __fw_backtrace_info){
.ra = rtw89_read32(rtwdev, i),
diff --git a/drivers/net/wireless/realtek/rtw89/txrx.h b/drivers/net/wireless/realtek/rtw89/txrx.h
index ec96da36eacc..02cff0f7d86b 100644
--- a/drivers/net/wireless/realtek/rtw89/txrx.h
+++ b/drivers/net/wireless/realtek/rtw89/txrx.h
@@ -8,19 +8,56 @@
#include "debug.h"
#define DATA_RATE_MODE_CTRL_MASK GENMASK(8, 7)
+#define DATA_RATE_MODE_CTRL_MASK_V1 GENMASK(10, 8)
#define DATA_RATE_NOT_HT_IDX_MASK GENMASK(3, 0)
#define DATA_RATE_MODE_NON_HT 0x0
#define DATA_RATE_HT_IDX_MASK GENMASK(4, 0)
+#define DATA_RATE_HT_IDX_MASK_V1 GENMASK(4, 0)
#define DATA_RATE_MODE_HT 0x1
#define DATA_RATE_VHT_HE_NSS_MASK GENMASK(6, 4)
#define DATA_RATE_VHT_HE_IDX_MASK GENMASK(3, 0)
+#define DATA_RATE_NSS_MASK_V1 GENMASK(7, 5)
+#define DATA_RATE_MCS_MASK_V1 GENMASK(4, 0)
#define DATA_RATE_MODE_VHT 0x2
#define DATA_RATE_MODE_HE 0x3
-#define GET_DATA_RATE_MODE(r) FIELD_GET(DATA_RATE_MODE_CTRL_MASK, r)
-#define GET_DATA_RATE_NOT_HT_IDX(r) FIELD_GET(DATA_RATE_NOT_HT_IDX_MASK, r)
-#define GET_DATA_RATE_HT_IDX(r) FIELD_GET(DATA_RATE_HT_IDX_MASK, r)
-#define GET_DATA_RATE_VHT_HE_IDX(r) FIELD_GET(DATA_RATE_VHT_HE_IDX_MASK, r)
-#define GET_DATA_RATE_NSS(r) FIELD_GET(DATA_RATE_VHT_HE_NSS_MASK, r)
+#define DATA_RATE_MODE_EHT 0x4
+
+static inline u8 rtw89_get_data_rate_mode(struct rtw89_dev *rtwdev, u16 hw_rate)
+{
+ if (rtwdev->chip->chip_gen == RTW89_CHIP_BE)
+ return u16_get_bits(hw_rate, DATA_RATE_MODE_CTRL_MASK_V1);
+
+ return u16_get_bits(hw_rate, DATA_RATE_MODE_CTRL_MASK);
+}
+
+static inline u8 rtw89_get_data_not_ht_idx(struct rtw89_dev *rtwdev, u16 hw_rate)
+{
+ return u16_get_bits(hw_rate, DATA_RATE_NOT_HT_IDX_MASK);
+}
+
+static inline u8 rtw89_get_data_ht_mcs(struct rtw89_dev *rtwdev, u16 hw_rate)
+{
+ if (rtwdev->chip->chip_gen == RTW89_CHIP_BE)
+ return u16_get_bits(hw_rate, DATA_RATE_HT_IDX_MASK_V1);
+
+ return u16_get_bits(hw_rate, DATA_RATE_HT_IDX_MASK);
+}
+
+static inline u8 rtw89_get_data_mcs(struct rtw89_dev *rtwdev, u16 hw_rate)
+{
+ if (rtwdev->chip->chip_gen == RTW89_CHIP_BE)
+ return u16_get_bits(hw_rate, DATA_RATE_MCS_MASK_V1);
+
+ return u16_get_bits(hw_rate, DATA_RATE_VHT_HE_IDX_MASK);
+}
+
+static inline u8 rtw89_get_data_nss(struct rtw89_dev *rtwdev, u16 hw_rate)
+{
+ if (rtwdev->chip->chip_gen == RTW89_CHIP_BE)
+ return u16_get_bits(hw_rate, DATA_RATE_NSS_MASK_V1);
+
+ return u16_get_bits(hw_rate, DATA_RATE_VHT_HE_NSS_MASK);
+}
/* TX WD BODY DWORD 0 */
#define RTW89_TXWD_BODY0_WP_OFFSET GENMASK(31, 24)
diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c
index 364e54622150..aa9efca04025 100644
--- a/drivers/net/wireless/realtek/rtw89/wow.c
+++ b/drivers/net/wireless/realtek/rtw89/wow.c
@@ -40,6 +40,7 @@ static void rtw89_wow_leave_lps(struct rtw89_dev *rtwdev)
static int rtw89_wow_config_mac(struct rtw89_dev *rtwdev, bool enable_wow)
{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
int ret;
if (enable_wow) {
@@ -49,7 +50,7 @@ static int rtw89_wow_config_mac(struct rtw89_dev *rtwdev, bool enable_wow)
return ret;
}
rtw89_write32_set(rtwdev, R_AX_RX_FUNCTION_STOP, B_AX_HDR_RX_STOP);
- rtw89_write32_clr(rtwdev, R_AX_RX_FLTR_OPT, B_AX_SNIFFER_MODE);
+ rtw89_write32_clr(rtwdev, mac->rx_fltr, B_AX_SNIFFER_MODE);
rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, false);
rtw89_write32(rtwdev, R_AX_ACTION_FWD0, 0);
rtw89_write32(rtwdev, R_AX_ACTION_FWD1, 0);