2022-06-23 04:46:45

by Ping-Ke Shih

[permalink] [raw]
Subject: [PATCH v2 00/13] rtw89: support channel context

In order to support multiple channels, we prepare this patchset to have
initial skeleton of channel context, and only SCC (single channel
concurrence) is supported for now.

The channel context needs some features, like hardware scan, but not all
chips can support these features, so this implement can still support
chips without channel context. The chip_info defines a support_chanctx_num
field to discriminate a chip can support channel context or not, and we
use this as clue to hook channel context ops of mac80211.

We add a module parameter rtw89_use_chanctx to enable channel context,
but by default set rtw89_use_chanctx=0 to pevent to break users' setup.
When users want channel context to support concurrency, set module
parameter rtw89_use_chanctx=1. If a chip declare it can support channel
context and proper firmware with hardware scan is adopted, it can run with
channel context. Otherwise, it could be failed to probe, users should
set rtw89_use_chanctx=0 or upgrade firmware.

When we concentrate stuffs of channel, some patches with a lot of changes
are used to adjust code for new struct. But, not really change logic.

v2:
- patch 11/13: add link_id argument because ieee80211 ops prototype are
changed.
- patch 13/13: change to use module parameter rtw89_use_chanctx to prevent
breaking users' setup by default, and users can try to use channel
context after they upgrade firmware.

Zong-Zhe Yang (13):
rtw89: rewrite decision on channel by entity state
rtw89: introduce rtw89_chan for channel stuffs
rtw89: re-arrange channel related stuffs under HAL
rtw89: create rtw89_chan centrally to avoid breakage
rtw89: txpwr: concentrate channel related control to top
rtw89: rfk: concentrate parameter control while set_channel()
rtw89: concentrate parameter control for setting channel callback
rtw89: concentrate chandef setting to stack callback
rtw89: initialize entity and configure default chandef
rtw89: introduce entity mode and its recalculated prototype
rtw89: add skeleton of mac80211 chanctx ops support
rtw89: support mac80211 chanctx ops by chip
rtw89: ensure chanctx ops are used with HW scan

drivers/net/wireless/realtek/rtw89/Makefile | 1 +
drivers/net/wireless/realtek/rtw89/chan.c | 237 ++++++++++++++++
drivers/net/wireless/realtek/rtw89/chan.h | 66 +++++
drivers/net/wireless/realtek/rtw89/coex.c | 11 +-
drivers/net/wireless/realtek/rtw89/coex.h | 4 +-
drivers/net/wireless/realtek/rtw89/core.c | 260 +++++++++--------
drivers/net/wireless/realtek/rtw89/core.h | 149 +++++++---
drivers/net/wireless/realtek/rtw89/debug.c | 3 +-
drivers/net/wireless/realtek/rtw89/fw.c | 84 ++++--
drivers/net/wireless/realtek/rtw89/mac.c | 14 +-
drivers/net/wireless/realtek/rtw89/mac80211.c | 77 ++++-
drivers/net/wireless/realtek/rtw89/pci.c | 11 +-
drivers/net/wireless/realtek/rtw89/phy.c | 266 +++++++++++-------
drivers/net/wireless/realtek/rtw89/phy.h | 8 +-
drivers/net/wireless/realtek/rtw89/regd.c | 2 +-
drivers/net/wireless/realtek/rtw89/rtw8852a.c | 111 +++++---
.../net/wireless/realtek/rtw89/rtw8852a_rfk.c | 77 +++--
drivers/net/wireless/realtek/rtw89/rtw8852c.c | 231 ++++++++-------
.../net/wireless/realtek/rtw89/rtw8852c_rfk.c | 73 +++--
.../net/wireless/realtek/rtw89/rtw8852c_rfk.h | 2 +-
drivers/net/wireless/realtek/rtw89/sar.c | 8 +-
drivers/net/wireless/realtek/rtw89/ser.c | 2 +
22 files changed, 1171 insertions(+), 526 deletions(-)
create mode 100644 drivers/net/wireless/realtek/rtw89/chan.c
create mode 100644 drivers/net/wireless/realtek/rtw89/chan.h

--
2.25.1


2022-06-23 04:46:57

by Ping-Ke Shih

[permalink] [raw]
Subject: [PATCH v2 02/13] rtw89: introduce rtw89_chan for channel stuffs

From: Zong-Zhe Yang <[email protected]>

Introduce struct rtw89_chan ahead to encapsulate stuffs from struct
rtw89_channel_params. These stuffs have a clone in HAL and are used
throughout driver. After multiple channels support, it's expected that
each channel instance has a configuration of them. So, we refine them
with struct rtw89_chan by precise type first, and will re-arrange HAL
by struct rtw89_chan in the following as well.

(No logic has changed.)

Signed-off-by: Zong-Zhe Yang <[email protected]>
Signed-off-by: Ping-Ke Shih <[email protected]>
---
drivers/net/wireless/realtek/rtw89/core.c | 38 ++---
drivers/net/wireless/realtek/rtw89/core.h | 18 +--
drivers/net/wireless/realtek/rtw89/phy.c | 8 +-
drivers/net/wireless/realtek/rtw89/phy.h | 2 +-
drivers/net/wireless/realtek/rtw89/rtw8852a.c | 37 ++---
drivers/net/wireless/realtek/rtw89/rtw8852c.c | 138 +++++++++---------
.../net/wireless/realtek/rtw89/rtw8852c_rfk.c | 7 +-
.../net/wireless/realtek/rtw89/rtw8852c_rfk.h | 2 +-
8 files changed, 128 insertions(+), 122 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 68c9b12d223a0..d7c3a2ac137f8 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -226,7 +226,7 @@ static void rtw89_traffic_stats_accu(struct rtw89_dev *rtwdev,
}

static void rtw89_get_channel_params(struct cfg80211_chan_def *chandef,
- struct rtw89_channel_params *chan_param)
+ struct rtw89_chan *chan)
{
struct ieee80211_channel *channel = chandef->chan;
enum nl80211_chan_width width = chandef->width;
@@ -344,13 +344,13 @@ static void rtw89_get_channel_params(struct cfg80211_chan_def *chandef,
break;
}

- chan_param->center_chan = center_chan;
- chan_param->center_freq = center_freq;
- chan_param->primary_chan = channel->hw_value;
- chan_param->bandwidth = bandwidth;
- chan_param->pri_ch_idx = primary_chan_idx;
- chan_param->band_type = band;
- chan_param->subband_type = subband;
+ chan->channel = center_chan;
+ chan->freq = center_freq;
+ chan->primary_channel = channel->hw_value;
+ chan->band_type = band;
+ chan->band_width = bandwidth;
+ chan->subband_type = subband;
+ chan->pri_ch_idx = primary_chan_idx;
}

void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev)
@@ -371,7 +371,7 @@ void rtw89_set_channel(struct rtw89_dev *rtwdev)
struct ieee80211_hw *hw = rtwdev->hw;
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_hal *hal = &rtwdev->hal;
- struct rtw89_channel_params ch_param;
+ struct rtw89_chan chan;
struct rtw89_channel_help_params bak;
u8 center_chan, bandwidth;
bool band_changed;
@@ -379,28 +379,28 @@ void rtw89_set_channel(struct rtw89_dev *rtwdev)

entity_active = rtw89_get_entity_state(rtwdev);

- rtw89_get_channel_params(&hw->conf.chandef, &ch_param);
- if (WARN(ch_param.center_chan == 0, "Invalid channel\n"))
+ rtw89_get_channel_params(&hw->conf.chandef, &chan);
+ if (WARN(chan.channel == 0, "Invalid channel\n"))
return;

- center_chan = ch_param.center_chan;
- bandwidth = ch_param.bandwidth;
- band_changed = hal->current_band_type != ch_param.band_type;
+ center_chan = chan.channel;
+ bandwidth = chan.band_width;
+ band_changed = hal->current_band_type != chan.band_type;

hal->current_band_width = bandwidth;
hal->current_channel = center_chan;
- hal->current_freq = ch_param.center_freq;
+ hal->current_freq = chan.freq;
hal->prev_primary_channel = hal->current_primary_channel;
hal->prev_band_type = hal->current_band_type;
- hal->current_primary_channel = ch_param.primary_chan;
- hal->current_band_type = ch_param.band_type;
- hal->current_subband = ch_param.subband_type;
+ hal->current_primary_channel = chan.primary_channel;
+ hal->current_band_type = chan.band_type;
+ hal->current_subband = chan.subband_type;

rtw89_set_entity_state(rtwdev, true);

rtw89_chip_set_channel_prepare(rtwdev, &bak);

- chip->ops->set_channel(rtwdev, &ch_param);
+ chip->ops->set_channel(rtwdev, &chan);

rtw89_core_set_chip_txpwr(rtwdev);

diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 9d5aa47e03878..194cba379285b 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -624,14 +624,14 @@ enum rtw89_sc_offset {
RTW89_SC_40_LOWER = 10,
};

-struct rtw89_channel_params {
- u8 center_chan;
- u32 center_freq;
- u8 primary_chan;
- u8 bandwidth;
- u8 pri_ch_idx;
- u8 band_type;
- u8 subband_type;
+struct rtw89_chan {
+ u8 channel;
+ u32 freq;
+ u8 primary_channel;
+ enum rtw89_band band_type;
+ enum rtw89_bandwidth band_width;
+ enum rtw89_subband subband_type;
+ enum rtw89_sc_offset pri_ch_idx;
};

struct rtw89_channel_help_params {
@@ -2100,7 +2100,7 @@ struct rtw89_chip_ops {
bool (*write_rf)(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
u32 addr, u32 mask, u32 data);
void (*set_channel)(struct rtw89_dev *rtwdev,
- struct rtw89_channel_params *param);
+ const struct rtw89_chan *chan);
void (*set_channel_help)(struct rtw89_dev *rtwdev, bool enter,
struct rtw89_channel_help_params *p);
int (*read_efuse)(struct rtw89_dev *rtwdev, u8 *log_map);
diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
index 1532c0a6bbc44..ad86c93a36ebf 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.c
+++ b/drivers/net/wireless/realtek/rtw89/phy.c
@@ -542,12 +542,12 @@ void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta)
}

u8 rtw89_phy_get_txsc(struct rtw89_dev *rtwdev,
- struct rtw89_channel_params *param,
+ const struct rtw89_chan *chan,
enum rtw89_bandwidth dbw)
{
- enum rtw89_bandwidth cbw = param->bandwidth;
- u8 pri_ch = param->primary_chan;
- u8 central_ch = param->center_chan;
+ enum rtw89_bandwidth cbw = chan->band_width;
+ u8 pri_ch = chan->primary_channel;
+ u8 central_ch = chan->channel;
u8 txsc_idx = 0;
u8 tmp = 0;

diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h
index e20636f54b553..d1f6e38a98ce3 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.h
+++ b/drivers/net/wireless/realtek/rtw89/phy.h
@@ -439,7 +439,7 @@ rtw89_rfk_parser(struct rtw89_dev *rtwdev, const struct rtw89_rfk_tbl *tbl);
void rtw89_phy_write_reg3_tbl(struct rtw89_dev *rtwdev,
const struct rtw89_phy_reg3_tbl *tbl);
u8 rtw89_phy_get_txsc(struct rtw89_dev *rtwdev,
- struct rtw89_channel_params *param,
+ const struct rtw89_chan *chan,
enum rtw89_bandwidth dbw);
u32 rtw89_phy_read_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
u32 addr, u32 mask);
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
index 81bd0c4fe21bc..6a87f30ca25ca 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
@@ -660,7 +660,7 @@ static void rtw8852a_power_trim(struct rtw89_dev *rtwdev)
}

static void rtw8852a_set_channel_mac(struct rtw89_dev *rtwdev,
- struct rtw89_channel_params *param,
+ const struct rtw89_chan *chan,
u8 mac_idx)
{
u32 rf_mod = rtw89_mac_reg_by_idx(R_AX_WMAC_RFMOD, mac_idx);
@@ -669,20 +669,20 @@ static void rtw8852a_set_channel_mac(struct rtw89_dev *rtwdev,
u32 chk_rate = rtw89_mac_reg_by_idx(R_AX_TXRATE_CHK, mac_idx);
u8 txsc20 = 0, txsc40 = 0;

- switch (param->bandwidth) {
+ switch (chan->band_width) {
case RTW89_CHANNEL_WIDTH_80:
- txsc40 = rtw89_phy_get_txsc(rtwdev, param,
+ txsc40 = rtw89_phy_get_txsc(rtwdev, chan,
RTW89_CHANNEL_WIDTH_40);
fallthrough;
case RTW89_CHANNEL_WIDTH_40:
- txsc20 = rtw89_phy_get_txsc(rtwdev, param,
+ txsc20 = rtw89_phy_get_txsc(rtwdev, chan,
RTW89_CHANNEL_WIDTH_20);
break;
default:
break;
}

- switch (param->bandwidth) {
+ switch (chan->band_width) {
case RTW89_CHANNEL_WIDTH_80:
rtw89_write8_mask(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK, BIT(1));
rtw89_write32(rtwdev, sub_carr, txsc20 | (txsc40 << 4));
@@ -699,7 +699,7 @@ static void rtw8852a_set_channel_mac(struct rtw89_dev *rtwdev,
break;
}

- if (param->center_chan > 14)
+ if (chan->channel > 14)
rtw89_write8_set(rtwdev, chk_rate,
B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6);
else
@@ -1130,35 +1130,36 @@ static void rtw8852a_bbrst_for_rfk(struct rtw89_dev *rtwdev,
}

static void rtw8852a_set_channel_bb(struct rtw89_dev *rtwdev,
- struct rtw89_channel_params *param,
+ const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
- bool cck_en = param->center_chan <= 14;
- u8 pri_ch_idx = param->pri_ch_idx;
+ bool cck_en = chan->channel <= 14;
+ u8 pri_ch_idx = chan->pri_ch_idx;

if (cck_en)
- rtw8852a_ctrl_sco_cck(rtwdev, param->center_chan,
- param->primary_chan, param->bandwidth);
+ rtw8852a_ctrl_sco_cck(rtwdev, chan->channel,
+ chan->primary_channel,
+ chan->band_width);

- rtw8852a_ctrl_ch(rtwdev, param->center_chan, phy_idx);
- rtw8852a_ctrl_bw(rtwdev, pri_ch_idx, param->bandwidth, phy_idx);
+ rtw8852a_ctrl_ch(rtwdev, chan->channel, phy_idx);
+ rtw8852a_ctrl_bw(rtwdev, pri_ch_idx, chan->band_width, phy_idx);
if (cck_en) {
rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0);
} else {
rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 1);
rtw8852a_bbrst_for_rfk(rtwdev, phy_idx);
}
- rtw8852a_spur_elimination(rtwdev, param->center_chan);
+ rtw8852a_spur_elimination(rtwdev, chan->channel);
rtw89_phy_write32_mask(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0,
- param->primary_chan);
+ chan->primary_channel);
rtw8852a_bb_reset_all(rtwdev, phy_idx);
}

static void rtw8852a_set_channel(struct rtw89_dev *rtwdev,
- struct rtw89_channel_params *params)
+ const struct rtw89_chan *chan)
{
- rtw8852a_set_channel_mac(rtwdev, params, RTW89_MAC_0);
- rtw8852a_set_channel_bb(rtwdev, params, RTW89_PHY_0);
+ rtw8852a_set_channel_mac(rtwdev, chan, RTW89_MAC_0);
+ rtw8852a_set_channel_bb(rtwdev, chan, RTW89_PHY_0);
}

static void rtw8852a_dfs_en(struct rtw89_dev *rtwdev, bool en)
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
index b697aef2faf2d..8c00aaeedb920 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
@@ -567,7 +567,7 @@ static void rtw8852c_power_trim(struct rtw89_dev *rtwdev)
}

static void rtw8852c_set_channel_mac(struct rtw89_dev *rtwdev,
- struct rtw89_channel_params *param,
+ const struct rtw89_chan *chan,
u8 mac_idx)
{
u32 rf_mod = rtw89_mac_reg_by_idx(R_AX_WMAC_RFMOD, mac_idx);
@@ -578,24 +578,24 @@ static void rtw8852c_set_channel_mac(struct rtw89_dev *rtwdev,
u8 rf_mod_val = 0, chk_rate_mask = 0;
u32 txsc;

- switch (param->bandwidth) {
+ switch (chan->band_width) {
case RTW89_CHANNEL_WIDTH_160:
- txsc80 = rtw89_phy_get_txsc(rtwdev, param,
+ txsc80 = rtw89_phy_get_txsc(rtwdev, chan,
RTW89_CHANNEL_WIDTH_80);
fallthrough;
case RTW89_CHANNEL_WIDTH_80:
- txsc40 = rtw89_phy_get_txsc(rtwdev, param,
+ txsc40 = rtw89_phy_get_txsc(rtwdev, chan,
RTW89_CHANNEL_WIDTH_40);
fallthrough;
case RTW89_CHANNEL_WIDTH_40:
- txsc20 = rtw89_phy_get_txsc(rtwdev, param,
+ txsc20 = rtw89_phy_get_txsc(rtwdev, chan,
RTW89_CHANNEL_WIDTH_20);
break;
default:
break;
}

- switch (param->bandwidth) {
+ switch (chan->band_width) {
case RTW89_CHANNEL_WIDTH_160:
rf_mod_val = AX_WMAC_RFMOD_160M;
txsc = FIELD_PREP(B_AX_TXSC_20M_MASK, txsc20) |
@@ -620,7 +620,7 @@ static void rtw8852c_set_channel_mac(struct rtw89_dev *rtwdev,
rtw89_write8_mask(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK, rf_mod_val);
rtw89_write32(rtwdev, sub_carr, txsc);

- switch (param->band_type) {
+ switch (chan->band_type) {
case RTW89_BAND_2G:
chk_rate_mask = B_AX_BAND_MODE;
break;
@@ -629,7 +629,7 @@ static void rtw8852c_set_channel_mac(struct rtw89_dev *rtwdev,
chk_rate_mask = B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6;
break;
default:
- rtw89_warn(rtwdev, "Invalid band_type:%d\n", param->band_type);
+ rtw89_warn(rtwdev, "Invalid band_type:%d\n", chan->band_type);
return;
}
rtw89_write8_clr(rtwdev, chk_rate, B_AX_BAND_MODE | B_AX_CHECK_CCK_EN |
@@ -920,7 +920,7 @@ static void rtw8852c_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx,
}

static void rtw8852c_set_gain_offset(struct rtw89_dev *rtwdev,
- const struct rtw89_channel_params *param,
+ const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx,
enum rtw89_rf_path path)
{
@@ -939,7 +939,7 @@ static void rtw8852c_set_gain_offset(struct rtw89_dev *rtwdev,
if (rtwdev->dbcc_en && path == RF_PATH_B)
phy_idx = RTW89_PHY_1;

- if (param->band_type == RTW89_BAND_2G) {
+ if (chan->band_type == RTW89_BAND_2G) {
offset_q0 = efuse_gain->offset[path][RTW89_GAIN_OFFSET_2G_CCK];
offset_base_q4 = efuse_gain->offset_base[phy_idx];

@@ -948,7 +948,7 @@ static void rtw8852c_set_gain_offset(struct rtw89_dev *rtwdev,
rtw89_phy_write32_mask(rtwdev, R_RPL_OFST, B_RPL_OFST_MASK, tmp & 0x7f);
}

- switch (param->subband_type) {
+ switch (chan->subband_type) {
default:
case RTW89_CH_2G:
gain_band = RTW89_GAIN_OFFSET_2G_OFDM;
@@ -977,14 +977,14 @@ static void rtw8852c_set_gain_offset(struct rtw89_dev *rtwdev,
}

static void rtw8852c_ctrl_ch(struct rtw89_dev *rtwdev,
- const struct rtw89_channel_params *param,
+ const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
u8 sco;
- u16 central_freq = param->center_freq;
- u8 central_ch = param->center_chan;
- u8 band = param->band_type;
- u8 subband = param->subband_type;
+ u16 central_freq = chan->freq;
+ u8 central_ch = chan->channel;
+ u8 band = chan->band_type;
+ u8 subband = chan->subband_type;
bool is_2g = band == RTW89_BAND_2G;
u8 chan_idx;

@@ -996,7 +996,7 @@ static void rtw8852c_ctrl_ch(struct rtw89_dev *rtwdev,
if (phy_idx == RTW89_PHY_0) {
/* Path A */
rtw8852c_set_gain_error(rtwdev, subband, RF_PATH_A);
- rtw8852c_set_gain_offset(rtwdev, param, phy_idx, RF_PATH_A);
+ rtw8852c_set_gain_offset(rtwdev, chan, phy_idx, RF_PATH_A);

if (is_2g)
rtw89_phy_write32_idx(rtwdev, R_PATH0_BAND_SEL_V1,
@@ -1009,7 +1009,7 @@ static void rtw8852c_ctrl_ch(struct rtw89_dev *rtwdev,
/* Path B */
if (!rtwdev->dbcc_en) {
rtw8852c_set_gain_error(rtwdev, subband, RF_PATH_B);
- rtw8852c_set_gain_offset(rtwdev, param, phy_idx, RF_PATH_B);
+ rtw8852c_set_gain_offset(rtwdev, chan, phy_idx, RF_PATH_B);

if (is_2g)
rtw89_phy_write32_idx(rtwdev,
@@ -1038,7 +1038,7 @@ static void rtw8852c_ctrl_ch(struct rtw89_dev *rtwdev,
} else {
/* Path B */
rtw8852c_set_gain_error(rtwdev, subband, RF_PATH_B);
- rtw8852c_set_gain_offset(rtwdev, param, phy_idx, RF_PATH_B);
+ rtw8852c_set_gain_offset(rtwdev, chan, phy_idx, RF_PATH_B);

if (is_2g)
rtw89_phy_write32_idx(rtwdev, R_PATH1_BAND_SEL_V1,
@@ -1095,7 +1095,7 @@ static void rtw8852c_ctrl_ch(struct rtw89_dev *rtwdev,
}
}

- chan_idx = rtw8852c_encode_chan_idx(rtwdev, param->primary_chan, band);
+ chan_idx = rtw8852c_encode_chan_idx(rtwdev, chan->primary_channel, band);
rtw89_phy_write32_idx(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, chan_idx, phy_idx);
}

@@ -1246,12 +1246,12 @@ rtw8852c_ctrl_bw(struct rtw89_dev *rtwdev, u8 pri_ch, u8 bw,
}

static u32 rtw8852c_spur_freq(struct rtw89_dev *rtwdev,
- struct rtw89_channel_params *param)
+ const struct rtw89_chan *chan)
{
- u8 center_chan = param->center_chan;
- u8 bw = param->bandwidth;
+ u8 center_chan = chan->channel;
+ u8 bw = chan->band_width;

- switch (param->band_type) {
+ switch (chan->band_type) {
case RTW89_BAND_2G:
if (bw == RTW89_CHANNEL_WIDTH_20) {
if (center_chan >= 5 && center_chan <= 8)
@@ -1285,19 +1285,19 @@ static u32 rtw8852c_spur_freq(struct rtw89_dev *rtwdev,
#define MAX_TONE_NUM 2048

static void rtw8852c_set_csi_tone_idx(struct rtw89_dev *rtwdev,
- struct rtw89_channel_params *param,
+ const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
u32 spur_freq;
s32 freq_diff, csi_idx, csi_tone_idx;

- spur_freq = rtw8852c_spur_freq(rtwdev, param);
+ spur_freq = rtw8852c_spur_freq(rtwdev, chan);
if (spur_freq == 0) {
rtw89_phy_write32_idx(rtwdev, R_SEG0CSI_EN, B_SEG0CSI_EN, 0, phy_idx);
return;
}

- freq_diff = (spur_freq - param->center_freq) * 1000000;
+ freq_diff = (spur_freq - chan->freq) * 1000000;
csi_idx = s32_div_u32_round_closest(freq_diff, CARRIER_SPACING_78_125);
s32_div_u32_round_down(csi_idx, MAX_TONE_NUM, &csi_tone_idx);

@@ -1325,7 +1325,7 @@ static const struct rtw89_nbi_reg_def rtw8852c_nbi_reg_def[] = {
};

static void rtw8852c_set_nbi_tone_idx(struct rtw89_dev *rtwdev,
- struct rtw89_channel_params *param,
+ const struct rtw89_chan *chan,
enum rtw89_rf_path path)
{
const struct rtw89_nbi_reg_def *nbi = &rtw8852c_nbi_reg_def[path];
@@ -1335,34 +1335,37 @@ static void rtw8852c_set_nbi_tone_idx(struct rtw89_dev *rtwdev,
s32 nbi_frac_idx, nbi_frac_tone_idx;
bool notch2_chk = false;

- spur_freq = rtw8852c_spur_freq(rtwdev, param);
+ spur_freq = rtw8852c_spur_freq(rtwdev, chan);
if (spur_freq == 0) {
rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, nbi->notch1_en.mask, 0);
rtw89_phy_write32_mask(rtwdev, nbi->notch1_en.addr, nbi->notch1_en.mask, 0);
return;
}

- fc = param->center_freq;
- if (param->bandwidth == RTW89_CHANNEL_WIDTH_160) {
+ fc = chan->freq;
+ if (chan->band_width == RTW89_CHANNEL_WIDTH_160) {
fc = (spur_freq > fc) ? fc + 40 : fc - 40;
- if ((fc > spur_freq && param->center_chan < param->primary_chan) ||
- (fc < spur_freq && param->center_chan > param->primary_chan))
+ if ((fc > spur_freq &&
+ chan->channel < chan->primary_channel) ||
+ (fc < spur_freq &&
+ chan->channel > chan->primary_channel))
notch2_chk = true;
}

freq_diff = (spur_freq - fc) * 1000000;
nbi_idx = s32_div_u32_round_down(freq_diff, CARRIER_SPACING_312_5, &nbi_frac_idx);

- if (param->bandwidth == RTW89_CHANNEL_WIDTH_20) {
+ if (chan->band_width == RTW89_CHANNEL_WIDTH_20) {
s32_div_u32_round_down(nbi_idx + 32, 64, &nbi_tone_idx);
} else {
- u16 tone_para = (param->bandwidth == RTW89_CHANNEL_WIDTH_40) ? 128 : 256;
+ u16 tone_para = (chan->band_width == RTW89_CHANNEL_WIDTH_40) ?
+ 128 : 256;

s32_div_u32_round_down(nbi_idx, tone_para, &nbi_tone_idx);
}
nbi_frac_tone_idx = s32_div_u32_round_closest(nbi_frac_idx, CARRIER_SPACING_78_125);

- if (param->bandwidth == RTW89_CHANNEL_WIDTH_160 && notch2_chk) {
+ if (chan->band_width == RTW89_CHANNEL_WIDTH_160 && notch2_chk) {
rtw89_phy_write32_mask(rtwdev, nbi->notch2_idx.addr,
nbi->notch2_idx.mask, nbi_tone_idx);
rtw89_phy_write32_mask(rtwdev, nbi->notch2_frac_idx.addr,
@@ -1404,42 +1407,42 @@ static void rtw8852c_spur_notch(struct rtw89_dev *rtwdev, u32 val,
}

static void rtw8852c_spur_elimination(struct rtw89_dev *rtwdev,
- struct rtw89_channel_params *param,
+ const struct rtw89_chan *chan,
u8 pri_ch_idx,
enum rtw89_phy_idx phy_idx)
{
- rtw8852c_set_csi_tone_idx(rtwdev, param, phy_idx);
+ rtw8852c_set_csi_tone_idx(rtwdev, chan, phy_idx);

if (phy_idx == RTW89_PHY_0) {
- if (param->bandwidth == RTW89_CHANNEL_WIDTH_160 &&
+ if (chan->band_width == RTW89_CHANNEL_WIDTH_160 &&
(pri_ch_idx == RTW89_SC_20_LOWER ||
pri_ch_idx == RTW89_SC_20_UP3X)) {
rtw8852c_spur_notch(rtwdev, 0xe7f, RTW89_PHY_0);
if (!rtwdev->dbcc_en)
rtw8852c_spur_notch(rtwdev, 0xe7f, RTW89_PHY_1);
- } else if (param->bandwidth == RTW89_CHANNEL_WIDTH_160 &&
+ } else if (chan->band_width == RTW89_CHANNEL_WIDTH_160 &&
(pri_ch_idx == RTW89_SC_20_UPPER ||
pri_ch_idx == RTW89_SC_20_LOW3X)) {
rtw8852c_spur_notch(rtwdev, 0x280, RTW89_PHY_0);
if (!rtwdev->dbcc_en)
rtw8852c_spur_notch(rtwdev, 0x280, RTW89_PHY_1);
} else {
- rtw8852c_set_nbi_tone_idx(rtwdev, param, RF_PATH_A);
+ rtw8852c_set_nbi_tone_idx(rtwdev, chan, RF_PATH_A);
if (!rtwdev->dbcc_en)
- rtw8852c_set_nbi_tone_idx(rtwdev, param,
+ rtw8852c_set_nbi_tone_idx(rtwdev, chan,
RF_PATH_B);
}
} else {
- if (param->bandwidth == RTW89_CHANNEL_WIDTH_160 &&
+ if (chan->band_width == RTW89_CHANNEL_WIDTH_160 &&
(pri_ch_idx == RTW89_SC_20_LOWER ||
pri_ch_idx == RTW89_SC_20_UP3X)) {
rtw8852c_spur_notch(rtwdev, 0xe7f, RTW89_PHY_1);
- } else if (param->bandwidth == RTW89_CHANNEL_WIDTH_160 &&
+ } else if (chan->band_width == RTW89_CHANNEL_WIDTH_160 &&
(pri_ch_idx == RTW89_SC_20_UPPER ||
pri_ch_idx == RTW89_SC_20_LOW3X)) {
rtw8852c_spur_notch(rtwdev, 0x280, RTW89_PHY_1);
} else {
- rtw8852c_set_nbi_tone_idx(rtwdev, param, RF_PATH_B);
+ rtw8852c_set_nbi_tone_idx(rtwdev, chan, RF_PATH_B);
}
}

@@ -1450,14 +1453,14 @@ static void rtw8852c_spur_elimination(struct rtw89_dev *rtwdev,
}

static void rtw8852c_5m_mask(struct rtw89_dev *rtwdev,
- struct rtw89_channel_params *param,
+ const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
- u8 pri_ch = param->primary_chan;
+ u8 pri_ch = chan->primary_channel;
bool mask_5m_low;
bool mask_5m_en;

- switch (param->bandwidth) {
+ switch (chan->band_width) {
case RTW89_CHANNEL_WIDTH_40:
mask_5m_en = true;
mask_5m_low = pri_ch == 2;
@@ -1690,21 +1693,22 @@ static void rtw8852c_bb_sethw(struct rtw89_dev *rtwdev)
}

static void rtw8852c_set_channel_bb(struct rtw89_dev *rtwdev,
- struct rtw89_channel_params *param,
+ const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
- bool cck_en = param->band_type == RTW89_BAND_2G;
- u8 pri_ch_idx = param->pri_ch_idx;
+ bool cck_en = chan->band_type == RTW89_BAND_2G;
+ u8 pri_ch_idx = chan->pri_ch_idx;
u32 mask, reg;
u32 ru_alloc_msk[2] = {B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY0,
B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY1};

- if (param->band_type == RTW89_BAND_2G)
- rtw8852c_ctrl_sco_cck(rtwdev, param->center_chan,
- param->primary_chan, param->bandwidth);
+ if (chan->band_type == RTW89_BAND_2G)
+ rtw8852c_ctrl_sco_cck(rtwdev, chan->channel,
+ chan->primary_channel,
+ chan->band_width);

- rtw8852c_ctrl_ch(rtwdev, param, phy_idx);
- rtw8852c_ctrl_bw(rtwdev, pri_ch_idx, param->bandwidth, phy_idx);
+ rtw8852c_ctrl_ch(rtwdev, chan, phy_idx);
+ rtw8852c_ctrl_bw(rtwdev, pri_ch_idx, chan->band_width, phy_idx);
if (cck_en) {
rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_ENABLE_CCK, 1);
rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, 0);
@@ -1717,17 +1721,17 @@ static void rtw8852c_set_channel_bb(struct rtw89_dev *rtwdev,
B_PD_ARBITER_OFF, 0x1, phy_idx);
}

- rtw8852c_spur_elimination(rtwdev, param, pri_ch_idx, phy_idx);
- rtw8852c_ctrl_btg(rtwdev, param->band_type == RTW89_BAND_2G);
- rtw8852c_5m_mask(rtwdev, param, phy_idx);
+ rtw8852c_spur_elimination(rtwdev, chan, pri_ch_idx, phy_idx);
+ rtw8852c_ctrl_btg(rtwdev, chan->band_type == RTW89_BAND_2G);
+ rtw8852c_5m_mask(rtwdev, chan, phy_idx);

- if (param->bandwidth == RTW89_CHANNEL_WIDTH_160 &&
+ if (chan->band_width == RTW89_CHANNEL_WIDTH_160 &&
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);
- if (param->primary_chan > param->center_chan) {
+ if (chan->primary_channel > chan->channel) {
rtw89_phy_write32_mask(rtwdev,
R_P80_AT_HIGH_FREQ_RU_ALLOC,
ru_alloc_msk[phy_idx], 1);
@@ -1742,8 +1746,8 @@ static void rtw8852c_set_channel_bb(struct rtw89_dev *rtwdev,
}
}

- if (param->band_type == RTW89_BAND_6G &&
- param->bandwidth == RTW89_CHANNEL_WIDTH_160)
+ if (chan->band_type == RTW89_BAND_6G &&
+ chan->band_width == RTW89_CHANNEL_WIDTH_160)
rtw89_phy_write32_idx(rtwdev, R_CDD_EVM_CHK_EN,
B_CDD_EVM_CHK_EN, 0, phy_idx);
else
@@ -1773,11 +1777,11 @@ static void rtw8852c_set_channel_bb(struct rtw89_dev *rtwdev,
}

static void rtw8852c_set_channel(struct rtw89_dev *rtwdev,
- struct rtw89_channel_params *params)
+ const struct rtw89_chan *chan)
{
- rtw8852c_set_channel_mac(rtwdev, params, RTW89_MAC_0);
- rtw8852c_set_channel_bb(rtwdev, params, RTW89_PHY_0);
- rtw8852c_set_channel_rf(rtwdev, params, RTW89_PHY_0);
+ rtw8852c_set_channel_mac(rtwdev, chan, RTW89_MAC_0);
+ rtw8852c_set_channel_bb(rtwdev, chan, RTW89_PHY_0);
+ rtw8852c_set_channel_rf(rtwdev, chan, RTW89_PHY_0);
}

static void rtw8852c_dfs_en(struct rtw89_dev *rtwdev, bool en)
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c
index 4186d825d19b7..fa109ee673cfc 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c
@@ -3802,11 +3802,12 @@ void rtw8852c_ctrl_bw_ch(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
}

void rtw8852c_set_channel_rf(struct rtw89_dev *rtwdev,
- struct rtw89_channel_params *param,
+ const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
- rtw8852c_ctrl_bw_ch(rtwdev, phy_idx, param->center_chan, param->band_type,
- param->bandwidth);
+ rtw8852c_ctrl_bw_ch(rtwdev, phy_idx, chan->channel,
+ chan->band_type,
+ chan->band_width);
}

void rtw8852c_mcc_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h
index 5118a49da8d3e..928a587cdd056 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.h
@@ -21,7 +21,7 @@ void rtw8852c_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, u8 phy_idx)
void rtw8852c_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start,
enum rtw89_phy_idx phy_idx);
void rtw8852c_set_channel_rf(struct rtw89_dev *rtwdev,
- struct rtw89_channel_params *param,
+ const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx);
void rtw8852c_lck_init(struct rtw89_dev *rtwdev);
void rtw8852c_lck_track(struct rtw89_dev *rtwdev);
--
2.25.1

2022-06-23 04:46:58

by Ping-Ke Shih

[permalink] [raw]
Subject: [PATCH v2 12/13] rtw89: support mac80211 chanctx ops by chip

From: Zong-Zhe Yang <[email protected]>

HW scan feature should be required after we support mac80211 chanctx ops.
However, not all chips have FW to support HW scan feature at this time
being. So, support_chanctx_num is added under chip info to deal with this.
If it's configured as 0, e.g. 8852c, which has not owned a FW to support
HW scan yet, we won't hook chanctx ops and then the chip could run without
mac80211 chanctx as before.

To 8852a which has owned a FW to support HW scan, we configure 1 to its
support_chanctx_num because we support only single channel concurrent
for now.

Signed-off-by: Zong-Zhe Yang <[email protected]>
Signed-off-by: Ping-Ke Shih <[email protected]>
---
drivers/net/wireless/realtek/rtw89/chan.c | 3 +-
drivers/net/wireless/realtek/rtw89/core.c | 49 +++++++++++++++++++
drivers/net/wireless/realtek/rtw89/core.h | 5 ++
drivers/net/wireless/realtek/rtw89/pci.c | 11 ++---
drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 +
6 files changed, 63 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c
index 156a846363056..553e21925948f 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.c
+++ b/drivers/net/wireless/realtek/rtw89/chan.c
@@ -185,10 +185,11 @@ int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
{
struct rtw89_hal *hal = &rtwdev->hal;
struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
+ const struct rtw89_chip_info *chip = rtwdev->chip;
u8 idx;

idx = find_first_zero_bit(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
- if (idx > RTW89_SUB_ENTITY_0)
+ if (idx >= chip->support_chanctx_num)
return -ENOENT;

rtw89_config_entity_chandef(rtwdev, idx, &ctx->def);
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 885ef1525868a..60c8043749e28 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -3208,6 +3208,55 @@ void rtw89_core_unregister(struct rtw89_dev *rtwdev)
}
EXPORT_SYMBOL(rtw89_core_unregister);

+struct ieee80211_hw *rtw89_alloc_ieee80211_hw(u32 bus_data_size,
+ const struct rtw89_chip_info *chip)
+{
+ struct ieee80211_hw *hw;
+ struct rtw89_dev *rtwdev;
+ struct ieee80211_ops *ops;
+ u32 driver_data_size;
+
+ ops = kmemdup(&rtw89_ops, sizeof(rtw89_ops), GFP_KERNEL);
+ if (!ops)
+ goto err;
+
+ if (chip->support_chanctx_num == 0) {
+ ops->add_chanctx = NULL;
+ ops->remove_chanctx = NULL;
+ ops->change_chanctx = NULL;
+ ops->assign_vif_chanctx = NULL;
+ ops->unassign_vif_chanctx = NULL;
+ }
+
+ driver_data_size = sizeof(struct rtw89_dev) + bus_data_size;
+ hw = ieee80211_alloc_hw(driver_data_size, ops);
+ if (!hw)
+ goto err;
+
+ rtwdev = hw->priv;
+ rtwdev->ops = ops;
+
+ return hw;
+
+err:
+ kfree(ops);
+ return NULL;
+}
+EXPORT_SYMBOL(rtw89_alloc_ieee80211_hw);
+
+void rtw89_free_ieee80211_hw(struct ieee80211_hw *hw)
+{
+ struct rtw89_dev *rtwdev;
+ const struct ieee80211_ops *ops;
+
+ rtwdev = hw->priv;
+ ops = rtwdev->ops;
+ kfree(ops);
+
+ ieee80211_free_hw(hw);
+}
+EXPORT_SYMBOL(rtw89_free_ieee80211_hw);
+
MODULE_AUTHOR("Realtek Corporation");
MODULE_DESCRIPTION("Realtek 802.11ax wireless core module");
MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 26f1fc9561e04..25292465a3718 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -2408,6 +2408,7 @@ struct rtw89_chip_info {
const struct rtw89_hfc_param_ini *hfc_param_ini;
const struct rtw89_dle_mem *dle_mem;
u32 rf_base_addr[2];
+ u8 support_chanctx_num;
u8 support_bands;
bool support_bw160;
bool hw_sec_hdr;
@@ -3152,6 +3153,7 @@ struct rtw89_phy_efuse_gain {
struct rtw89_dev {
struct ieee80211_hw *hw;
struct device *dev;
+ const struct ieee80211_ops *ops;

bool dbcc_en;
struct rtw89_hw_scan_info scan_info;
@@ -3963,6 +3965,9 @@ int rtw89_core_init(struct rtw89_dev *rtwdev);
void rtw89_core_deinit(struct rtw89_dev *rtwdev);
int rtw89_core_register(struct rtw89_dev *rtwdev);
void rtw89_core_unregister(struct rtw89_dev *rtwdev);
+struct ieee80211_hw *rtw89_alloc_ieee80211_hw(u32 bus_data_size,
+ const struct rtw89_chip_info *chip);
+void rtw89_free_ieee80211_hw(struct ieee80211_hw *hw);
void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev);
void rtw89_get_default_chandef(struct cfg80211_chan_def *chandef);
void rtw89_set_channel(struct rtw89_dev *rtwdev);
diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c
index 73b3b7e9fe6f5..a564f5b37c8a1 100644
--- a/drivers/net/wireless/realtek/rtw89/pci.c
+++ b/drivers/net/wireless/realtek/rtw89/pci.c
@@ -3618,17 +3618,16 @@ int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
struct rtw89_dev *rtwdev;
const struct rtw89_driver_info *info;
const struct rtw89_pci_info *pci_info;
- int driver_data_size;
int ret;

- driver_data_size = sizeof(struct rtw89_dev) + sizeof(struct rtw89_pci);
- hw = ieee80211_alloc_hw(driver_data_size, &rtw89_ops);
+ info = (const struct rtw89_driver_info *)id->driver_data;
+
+ hw = rtw89_alloc_ieee80211_hw(sizeof(struct rtw89_pci), info->chip);
if (!hw) {
dev_err(&pdev->dev, "failed to allocate hw\n");
return -ENOMEM;
}

- info = (const struct rtw89_driver_info *)id->driver_data;
pci_info = info->bus.pci;

rtwdev = hw->priv;
@@ -3696,7 +3695,7 @@ int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
err_core_deinit:
rtw89_core_deinit(rtwdev);
err_release_hw:
- ieee80211_free_hw(hw);
+ rtw89_free_ieee80211_hw(hw);

return ret;
}
@@ -3715,7 +3714,7 @@ void rtw89_pci_remove(struct pci_dev *pdev)
rtw89_pci_clear_resource(rtwdev, pdev);
rtw89_pci_declaim_device(rtwdev, pdev);
rtw89_core_deinit(rtwdev);
- ieee80211_free_hw(hw);
+ rtw89_free_ieee80211_hw(hw);
}
EXPORT_SYMBOL(rtw89_pci_remove);

diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
index 2cf72dd322ba2..f6810fbb3fab1 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
@@ -2133,6 +2133,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
.txpwr_factor_mac = 1,
.dig_table = &rtw89_8852a_phy_dig_table,
.tssi_dbw_table = NULL,
+ .support_chanctx_num = 1,
.support_bands = BIT(NL80211_BAND_2GHZ) |
BIT(NL80211_BAND_5GHZ),
.support_bw160 = false,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
index 7a2822f3bdf04..0218fa90526ca 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
@@ -2981,6 +2981,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
.txpwr_factor_mac = 1,
.dig_table = NULL,
.tssi_dbw_table = &rtw89_8852c_tssi_dbw_table,
+ .support_chanctx_num = 0,
.support_bands = BIT(NL80211_BAND_2GHZ) |
BIT(NL80211_BAND_5GHZ) |
BIT(NL80211_BAND_6GHZ),
--
2.25.1

2022-06-23 04:47:15

by Ping-Ke Shih

[permalink] [raw]
Subject: [PATCH v2 09/13] rtw89: initialize entity and configure default chandef

From: Zong-Zhe Yang <[email protected]>

While idle, we need a default chandef to set channel for things,
such as scan. Before support of mac80211 chanctx, mac80211 would
configure a default one on ieee80211_hw::conf::chandef. And we
just queried it whenever we did set channel. However, after support
of mac80211 chanctx, the flow won't work like before.

Besides, we don't now query chandef from ieee80211_hw::conf::chandef
either. So, similar to mac80211 without using chanctx, we configure
the default chandef with ieee80211_channel of index 0 in 2GHz.

Although we have not added the support of mac80211 chanctx here,
this configuration should be compatible before that. So, we commit
this ahead.

Signed-off-by: Zong-Zhe Yang <[email protected]>
Signed-off-by: Ping-Ke Shih <[email protected]>
---
drivers/net/wireless/realtek/rtw89/chan.c | 16 ++++++++++++++++
drivers/net/wireless/realtek/rtw89/chan.h | 1 +
drivers/net/wireless/realtek/rtw89/core.c | 7 +++++++
drivers/net/wireless/realtek/rtw89/core.h | 1 +
drivers/net/wireless/realtek/rtw89/ser.c | 2 ++
5 files changed, 27 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c
index a9f0133f8089d..e0f1c89bbfa6b 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.c
+++ b/drivers/net/wireless/realtek/rtw89/chan.c
@@ -138,3 +138,19 @@ void rtw89_config_entity_chandef(struct rtw89_dev *rtwdev,
{
__rtw89_config_entity_chandef(rtwdev, idx, chandef, true);
}
+
+static void rtw89_config_default_chandef(struct rtw89_dev *rtwdev)
+{
+ struct cfg80211_chan_def chandef = {0};
+
+ rtw89_get_default_chandef(&chandef);
+ __rtw89_config_entity_chandef(rtwdev, RTW89_SUB_ENTITY_0, &chandef, false);
+}
+
+void rtw89_entity_init(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_hal *hal = &rtwdev->hal;
+
+ bitmap_zero(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
+ rtw89_config_default_chandef(rtwdev);
+}
diff --git a/drivers/net/wireless/realtek/rtw89/chan.h b/drivers/net/wireless/realtek/rtw89/chan.h
index b2022bb0afc6a..9c714f00c3c13 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.h
+++ b/drivers/net/wireless/realtek/rtw89/chan.h
@@ -29,5 +29,6 @@ bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev,
void rtw89_config_entity_chandef(struct rtw89_dev *rtwdev,
enum rtw89_sub_entity_idx idx,
const struct cfg80211_chan_def *chandef);
+void rtw89_entity_init(struct rtw89_dev *rtwdev);

#endif
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 4c25fef476e01..04ba705a14a7b 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -225,6 +225,12 @@ static void rtw89_traffic_stats_accu(struct rtw89_dev *rtwdev,
}
}

+void rtw89_get_default_chandef(struct cfg80211_chan_def *chandef)
+{
+ cfg80211_chandef_create(chandef, &rtw89_channels_2ghz[0],
+ NL80211_CHAN_NO_HT);
+}
+
static void rtw89_get_channel_params(const struct cfg80211_chan_def *chandef,
struct rtw89_chan *chan)
{
@@ -2935,6 +2941,7 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
return ret;
}
rtw89_ser_init(rtwdev);
+ rtw89_entity_init(rtwdev);

return 0;
}
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index f8027b9a36a0c..3b6660d76f797 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -3955,6 +3955,7 @@ void rtw89_core_deinit(struct rtw89_dev *rtwdev);
int rtw89_core_register(struct rtw89_dev *rtwdev);
void rtw89_core_unregister(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_set_channel(struct rtw89_dev *rtwdev);
u8 rtw89_core_acquire_bit_map(unsigned long *addr, unsigned long size);
void rtw89_core_release_bit_map(unsigned long *addr, u8 bit);
diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c
index 726223f25dc69..74af916ac7423 100644
--- a/drivers/net/wireless/realtek/rtw89/ser.c
+++ b/drivers/net/wireless/realtek/rtw89/ser.c
@@ -5,6 +5,7 @@
#include <linux/devcoredump.h>

#include "cam.h"
+#include "chan.h"
#include "debug.h"
#include "fw.h"
#include "mac.h"
@@ -601,6 +602,7 @@ static void ser_l2_reset_st_pre_hdl(struct rtw89_ser *ser)

ser_reset_mac_binding(rtwdev);
rtw89_core_stop(rtwdev);
+ rtw89_entity_init(rtwdev);
INIT_LIST_HEAD(&rtwdev->rtwvifs_list);
}

--
2.25.1

2022-06-23 04:47:15

by Ping-Ke Shih

[permalink] [raw]
Subject: [PATCH v2 03/13] rtw89: re-arrange channel related stuffs under HAL

From: Zong-Zhe Yang <[email protected]>

We are planning to support mac80211 chanctx. To reduce future works,
the driver architecture is adjusted first to isolate related things.

According to chip, our HW may have multiple sub-entities to support
multiple mac80211 chanctx. Struct rtw89_chan has been introduced for
things about channel/band/subband/... Now introduce struct rtw89_chan_rcd
to record difference after assigning new one of struct rtw89_chan.

We will implement and support chanctx with single channel first, i.e.
only use entry in RTW89_SUB_ENTITY_0, before handling dual channels.

Our hierarchy in planning will become as the following.
DEV
-> HAL
---> entity (manage status across sub-entities)
-----> sub-entity[*] (support mac80211 chanctx)
where each sub-entity contains one struct rtw89_chan.

Signed-off-by: Zong-Zhe Yang <[email protected]>
Signed-off-by: Ping-Ke Shih <[email protected]>
---
drivers/net/wireless/realtek/rtw89/Makefile | 1 +
drivers/net/wireless/realtek/rtw89/chan.c | 22 ++++++
drivers/net/wireless/realtek/rtw89/chan.h | 4 ++
drivers/net/wireless/realtek/rtw89/coex.c | 11 ++-
drivers/net/wireless/realtek/rtw89/coex.h | 4 +-
drivers/net/wireless/realtek/rtw89/core.c | 58 +++++++---------
drivers/net/wireless/realtek/rtw89/core.h | 40 ++++++++---
drivers/net/wireless/realtek/rtw89/debug.c | 3 +-
drivers/net/wireless/realtek/rtw89/fw.c | 35 ++++++----
drivers/net/wireless/realtek/rtw89/mac.c | 15 ++--
drivers/net/wireless/realtek/rtw89/mac80211.c | 3 +-
drivers/net/wireless/realtek/rtw89/phy.c | 39 +++++++----
drivers/net/wireless/realtek/rtw89/rtw8852a.c | 17 +++--
.../net/wireless/realtek/rtw89/rtw8852a_rfk.c | 68 +++++++++++--------
drivers/net/wireless/realtek/rtw89/rtw8852c.c | 28 +++++---
.../net/wireless/realtek/rtw89/rtw8852c_rfk.c | 66 ++++++++++--------
drivers/net/wireless/realtek/rtw89/sar.c | 6 +-
17 files changed, 257 insertions(+), 163 deletions(-)
create mode 100644 drivers/net/wireless/realtek/rtw89/chan.c

diff --git a/drivers/net/wireless/realtek/rtw89/Makefile b/drivers/net/wireless/realtek/rtw89/Makefile
index 3006482d25c77..a87f2aff4def2 100644
--- a/drivers/net/wireless/realtek/rtw89/Makefile
+++ b/drivers/net/wireless/realtek/rtw89/Makefile
@@ -12,6 +12,7 @@ rtw89_core-y += core.o \
sar.o \
coex.o \
ps.o \
+ chan.o \
ser.o

obj-$(CONFIG_RTW89_8852A) += rtw89_8852a.o
diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c
new file mode 100644
index 0000000000000..a5d1bf573ea62
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtw89/chan.c
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2020-2022 Realtek Corporation
+ */
+
+#include "chan.h"
+
+bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev,
+ enum rtw89_sub_entity_idx idx,
+ const struct rtw89_chan *new)
+{
+ struct rtw89_hal *hal = &rtwdev->hal;
+ struct rtw89_chan *chan = &hal->chan[idx];
+ struct rtw89_chan_rcd *rcd = &hal->chan_rcd[idx];
+ bool band_changed;
+
+ rcd->prev_primary_channel = chan->primary_channel;
+ rcd->prev_band_type = chan->band_type;
+ band_changed = new->band_type != chan->band_type;
+
+ *chan = *new;
+ return band_changed;
+}
diff --git a/drivers/net/wireless/realtek/rtw89/chan.h b/drivers/net/wireless/realtek/rtw89/chan.h
index bcaeb98670f17..ac5cc356b8182 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.h
+++ b/drivers/net/wireless/realtek/rtw89/chan.h
@@ -21,4 +21,8 @@ static inline void rtw89_set_entity_state(struct rtw89_dev *rtwdev, bool active)
WRITE_ONCE(hal->entity_active, active);
}

+bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev,
+ enum rtw89_sub_entity_idx idx,
+ const struct rtw89_chan *new);
+
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index 683854bba217b..5e169388867f8 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -4150,7 +4150,7 @@ 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)
{
- struct rtw89_hal *hal = &rtwdev->hal;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta);
struct rtw89_btc *btc = &rtwdev->btc;
@@ -4165,8 +4165,7 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif
vif->type == NL80211_IFTYPE_STATION);
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], port=%d\n", rtwvif->port);
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], band=%d ch=%d bw=%d\n",
- hal->current_band_type, hal->current_channel,
- hal->current_band_width);
+ chan->band_type, chan->channel, chan->band_width);
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], associated=%d\n",
state == BTC_ROLE_MSTS_STA_CONN_END);
rtw89_debug(rtwdev, RTW89_DBG_BTC,
@@ -4205,9 +4204,9 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif
r.connected = MLME_LINKED;
r.bcn_period = vif->bss_conf.beacon_int;
r.dtim_period = vif->bss_conf.dtim_period;
- r.band = hal->current_band_type;
- r.ch = hal->current_channel;
- r.bw = hal->current_band_width;
+ r.band = chan->band_type;
+ r.ch = chan->channel;
+ r.bw = chan->band_width;
ether_addr_copy(r.mac_addr, rtwvif->mac_addr);

if (rtwsta && vif->type == NL80211_IFTYPE_STATION)
diff --git a/drivers/net/wireless/realtek/rtw89/coex.h b/drivers/net/wireless/realtek/rtw89/coex.h
index c3a722d259d7f..b48a441ae6e23 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.h
+++ b/drivers/net/wireless/realtek/rtw89/coex.h
@@ -167,12 +167,12 @@ static inline u8 rtw89_btc_phymap(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
enum rtw89_rf_path_bit paths)
{
- struct rtw89_hal *hal = &rtwdev->hal;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 phy_map;

phy_map = FIELD_PREP(BTC_RFK_PATH_MAP, paths) |
FIELD_PREP(BTC_RFK_PHY_MAP, BIT(phy_idx)) |
- FIELD_PREP(BTC_RFK_BAND_MAP, hal->current_band_type);
+ FIELD_PREP(BTC_RFK_BAND_MAP, chan->band_type);

return phy_map;
}
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index d7c3a2ac137f8..78d9e6a7a0981 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -370,10 +370,8 @@ void rtw89_set_channel(struct rtw89_dev *rtwdev)
{
struct ieee80211_hw *hw = rtwdev->hw;
const struct rtw89_chip_info *chip = rtwdev->chip;
- struct rtw89_hal *hal = &rtwdev->hal;
struct rtw89_chan chan;
struct rtw89_channel_help_params bak;
- u8 center_chan, bandwidth;
bool band_changed;
bool entity_active;

@@ -383,18 +381,7 @@ void rtw89_set_channel(struct rtw89_dev *rtwdev)
if (WARN(chan.channel == 0, "Invalid channel\n"))
return;

- center_chan = chan.channel;
- bandwidth = chan.band_width;
- band_changed = hal->current_band_type != chan.band_type;
-
- hal->current_band_width = bandwidth;
- hal->current_channel = center_chan;
- hal->current_freq = chan.freq;
- hal->prev_primary_channel = hal->current_primary_channel;
- hal->prev_band_type = hal->current_band_type;
- hal->current_primary_channel = chan.primary_channel;
- hal->current_band_type = chan.band_type;
- hal->current_subband = chan.subband_type;
+ band_changed = rtw89_assign_entity_chan(rtwdev, RTW89_SUB_ENTITY_0, &chan);

rtw89_set_entity_state(rtwdev, true);

@@ -407,7 +394,7 @@ void rtw89_set_channel(struct rtw89_dev *rtwdev)
rtw89_chip_set_channel_done(rtwdev, &bak);

if (!entity_active || band_changed) {
- rtw89_btc_ntfy_switch_band(rtwdev, RTW89_PHY_0, hal->current_band_type);
+ rtw89_btc_ntfy_switch_band(rtwdev, RTW89_PHY_0, chan.band_type);
rtw89_chip_rfk_band_changed(rtwdev);
}
}
@@ -547,8 +534,8 @@ static u16 rtw89_core_get_mgmt_rate(struct rtw89_dev *rtwdev,
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;
- struct rtw89_hal *hal = &rtwdev->hal;
- u16 lowest_rate = hal->current_band_type == RTW89_BAND_2G ?
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ u16 lowest_rate = chan->band_type == RTW89_BAND_2G ?
RTW89_HW_RATE_CCK1 : RTW89_HW_RATE_OFDM6;

if (!vif || !vif->bss_conf.basic_rates || !tx_req->sta)
@@ -564,6 +551,7 @@ 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);
u8 qsel, ch_dma;

qsel = desc_info->hiq ? RTW89_TX_QSEL_B0_HI : RTW89_TX_QSEL_B0_MGMT;
@@ -582,9 +570,9 @@ rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev,
desc_info->data_rate = rtw89_core_get_mgmt_rate(rtwdev, tx_req);

rtw89_debug(rtwdev, RTW89_DBG_TXRX,
- "tx mgmt frame with rate 0x%x on channel %d (bw %d)\n",
- desc_info->data_rate, rtwdev->hal.current_channel,
- rtwdev->hal.current_band_width);
+ "tx mgmt frame with rate 0x%x on channel %d (band %d, bw %d)\n",
+ desc_info->data_rate, chan->channel, chan->band_type,
+ chan->band_width);
}

static void
@@ -609,15 +597,16 @@ 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 ||
- hal->current_band_type != RTW89_BAND_2G ||
- hal->current_band_width != RTW89_CHANNEL_WIDTH_40)
+ chan->band_type != RTW89_BAND_2G ||
+ chan->band_width != RTW89_CHANNEL_WIDTH_40)
return;

- om_bandwidth = hal->current_band_width < ARRAY_SIZE(rtw89_bandwidth_to_om) ?
- rtw89_bandwidth_to_om[hal->current_band_width] : 0;
+ om_bandwidth = chan->band_width < ARRAY_SIZE(rtw89_bandwidth_to_om) ?
+ rtw89_bandwidth_to_om[chan->band_width] : 0;
*htc = le32_encode_bits(RTW89_HTC_VARIANT_HE, RTW89_HTC_MASK_VARIANT) |
le32_encode_bits(RTW89_HTC_VARIANT_HE_CID_OM, RTW89_HTC_MASK_CTL_ID) |
le32_encode_bits(hal->rx_nss - 1, RTW89_HTC_MASK_HTC_OM_RX_NSS) |
@@ -731,7 +720,7 @@ rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif = tx_req->vif;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif->rate_pattern;
- struct rtw89_hal *hal = &rtwdev->hal;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
struct sk_buff *skb = tx_req->skb;
u8 tid, tid_indicate;
@@ -756,7 +745,7 @@ rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev,

if (rate_pattern->enable)
desc_info->data_retry_lowest_rate = rate_pattern->rate;
- else if (hal->current_band_type == RTW89_BAND_2G)
+ else if (chan->band_type == RTW89_BAND_2G)
desc_info->data_retry_lowest_rate = RTW89_HW_RATE_CCK1;
else
desc_info->data_retry_lowest_rate = RTW89_HW_RATE_OFDM6;
@@ -1466,8 +1455,11 @@ static void rtw89_core_rx_stats(struct rtw89_dev *rtwdev,
static void rtw89_correct_cck_chan(struct rtw89_dev *rtwdev,
struct ieee80211_rx_status *status)
{
- u16 chan = rtwdev->hal.prev_primary_channel;
- u8 band = chan <= 14 ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
+ 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;

if (status->band != NL80211_BAND_2GHZ &&
status->encoding == RX_ENC_LEGACY &&
@@ -1680,7 +1672,7 @@ static void rtw89_core_update_rx_status(struct rtw89_dev *rtwdev,
struct ieee80211_rx_status *rx_status)
{
struct ieee80211_hw *hw = rtwdev->hw;
- struct rtw89_hal *hal = &rtwdev->hal;
+ const struct rtw89_chan *cur = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u16 data_rate;
u8 data_rate_mode;

@@ -1690,8 +1682,8 @@ static void rtw89_core_update_rx_status(struct rtw89_dev *rtwdev,

if (rtwdev->scanning &&
RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) {
- u8 chan = hal->current_primary_channel;
- u8 band = hal->current_band_type;
+ u8 chan = cur->primary_channel;
+ u8 band = cur->band_type;
enum nl80211_band nl_band;

nl_band = rtw89_hw_to_nl80211_band(band);
@@ -3025,7 +3017,7 @@ 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)
{
- struct rtw89_hal *hal = &rtwdev->hal;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);

rtwdev->scanning = true;
rtw89_leave_lps(rtwdev);
@@ -3033,7 +3025,7 @@ void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
rtw89_leave_ips(rtwdev);

ether_addr_copy(rtwvif->mac_addr, mac_addr);
- rtw89_btc_ntfy_scan_start(rtwdev, RTW89_PHY_0, hal->current_band_type);
+ rtw89_btc_ntfy_scan_start(rtwdev, RTW89_PHY_0, chan->band_type);
rtw89_chip_rfk_scan(rtwdev, true);
rtw89_hci_recalc_int_mit(rtwdev);

diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 194cba379285b..86e7341198c6f 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -542,6 +542,12 @@ enum rtw89_phy_idx {
RTW89_PHY_MAX
};

+enum rtw89_sub_entity_idx {
+ RTW89_SUB_ENTITY_0 = 0,
+
+ NUM_OF_RTW89_SUB_ENTITY,
+};
+
enum rtw89_rf_path {
RF_PATH_A = 0,
RF_PATH_B = 1,
@@ -634,6 +640,11 @@ struct rtw89_chan {
enum rtw89_sc_offset pri_ch_idx;
};

+struct rtw89_chan_rcd {
+ u8 prev_primary_channel;
+ enum rtw89_band prev_band_type;
+};
+
struct rtw89_channel_help_params {
u32 tx_en;
};
@@ -2602,14 +2613,6 @@ struct rtw89_sar_info {
struct rtw89_hal {
u32 rx_fltr;
u8 cv;
- u8 current_channel;
- u32 current_freq;
- u8 prev_primary_channel;
- u8 current_primary_channel;
- enum rtw89_subband current_subband;
- u8 current_band_width;
- u8 prev_band_type;
- u8 current_band_type;
u32 sw_amsdu_max_size;
u32 antenna_tx;
u32 antenna_rx;
@@ -2619,6 +2622,9 @@ struct rtw89_hal {
bool support_igi;

bool entity_active;
+
+ struct rtw89_chan chan[NUM_OF_RTW89_SUB_ENTITY];
+ struct rtw89_chan_rcd chan_rcd[NUM_OF_RTW89_SUB_ENTITY];
};

#define RTW89_MAX_MAC_ID_NUM 128
@@ -3602,6 +3608,24 @@ void rtw89_chip_set_channel_done(struct rtw89_dev *rtwdev,
rtwdev->chip->ops->set_channel_help(rtwdev, false, p);
}

+static inline
+const struct rtw89_chan *rtw89_chan_get(struct rtw89_dev *rtwdev,
+ enum rtw89_sub_entity_idx idx)
+{
+ struct rtw89_hal *hal = &rtwdev->hal;
+
+ return &hal->chan[idx];
+}
+
+static inline
+const struct rtw89_chan_rcd *rtw89_chan_rcd_get(struct rtw89_dev *rtwdev,
+ enum rtw89_sub_entity_idx idx)
+{
+ struct rtw89_hal *hal = &rtwdev->hal;
+
+ return &hal->chan_rcd[idx];
+}
+
static inline void rtw89_chip_fem_setup(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c
index 829c61da99bb9..9c93117c62a44 100644
--- a/drivers/net/wireless/realtek/rtw89/debug.c
+++ b/drivers/net/wireless/realtek/rtw89/debug.c
@@ -525,7 +525,8 @@ static int __print_txpwr_map(struct seq_file *m, struct rtw89_dev *rtwdev,

static void __print_regd(struct seq_file *m, struct rtw89_dev *rtwdev)
{
- u8 band = rtwdev->hal.current_band_type;
+ 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);

switch (regd) {
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 6473015a6b2a1..8dcd02d90f457 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -3,6 +3,7 @@
*/

#include "cam.h"
+#include "chan.h"
#include "coex.h"
#include "debug.h"
#include "fw.h"
@@ -926,9 +927,9 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
struct ieee80211_sta *sta)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
- struct rtw89_hal *hal = &rtwdev->hal;
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);
struct sk_buff *skb;
u8 pads[RTW89_PPE_BW_NUM];
u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
@@ -947,7 +948,7 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
SET_CTRL_INFO_OPERATION(skb->data, 1);
SET_CMC_TBL_DISRTSFB(skb->data, 1);
SET_CMC_TBL_DISDATAFB(skb->data, 1);
- if (hal->current_band_type == RTW89_BAND_2G)
+ if (chan->band_type == RTW89_BAND_2G)
SET_CMC_TBL_RTS_RTY_LOWEST_RATE(skb->data, RTW89_HW_RATE_CCK1);
else
SET_CMC_TBL_RTS_RTY_LOWEST_RATE(skb->data, RTW89_HW_RATE_OFDM6);
@@ -1036,8 +1037,8 @@ int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev,
int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif)
{
- struct rtw89_hal *hal = &rtwdev->hal;
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
struct sk_buff *skb;
struct sk_buff *skb_beacon;
u16 tim_offset;
@@ -1066,7 +1067,7 @@ int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
SET_BCN_UPD_MACID(skb->data, rtwvif->mac_id);
SET_BCN_UPD_SSN_SEL(skb->data, RTW89_MGMT_HW_SSN_SEL);
SET_BCN_UPD_SSN_MODE(skb->data, RTW89_MGMT_HW_SEQ_MODE);
- SET_BCN_UPD_RATE(skb->data, hal->current_band_type == RTW89_BAND_2G ?
+ SET_BCN_UPD_RATE(skb->data, chan->band_type == RTW89_BAND_2G ?
RTW89_HW_RATE_CCK1 : RTW89_HW_RATE_OFDM6);

skb_put_data(skb, skb_beacon->data, skb_beacon->len);
@@ -1788,6 +1789,7 @@ int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev,

int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev)
{
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
struct rtw89_mcc_info *mcc_info = &rtwdev->mcc;
struct rtw89_fw_h2c_rf_get_mccch *mccch;
struct sk_buff *skb;
@@ -1804,8 +1806,8 @@ int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev)
mccch->ch_1 = cpu_to_le32(mcc_info->ch[1]);
mccch->band_0 = cpu_to_le32(mcc_info->band[0]);
mccch->band_1 = cpu_to_le32(mcc_info->band[1]);
- mccch->current_channel = cpu_to_le32(rtwdev->hal.current_channel);
- mccch->current_band_type = cpu_to_le32(rtwdev->hal.current_band_type);
+ mccch->current_channel = cpu_to_le32(chan->channel);
+ mccch->current_band_type = cpu_to_le32(chan->band_type);

rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY,
@@ -2377,18 +2379,21 @@ int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
void rtw89_store_op_chan(struct rtw89_dev *rtwdev, bool backup)
{
struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
- struct rtw89_hal *hal = &rtwdev->hal;
+ const struct rtw89_chan *cur = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ struct rtw89_chan new;

if (backup) {
- scan_info->op_pri_ch = hal->current_primary_channel;
- scan_info->op_chan = hal->current_channel;
- scan_info->op_bw = hal->current_band_width;
- scan_info->op_band = hal->current_band_type;
+ scan_info->op_pri_ch = cur->primary_channel;
+ scan_info->op_chan = cur->channel;
+ scan_info->op_bw = cur->band_width;
+ scan_info->op_band = cur->band_type;
} else {
- hal->current_primary_channel = scan_info->op_pri_ch;
- hal->current_channel = scan_info->op_chan;
- hal->current_band_width = scan_info->op_bw;
- hal->current_band_type = scan_info->op_band;
+ new = *cur;
+ new.primary_channel = scan_info->op_pri_ch;
+ new.channel = scan_info->op_chan;
+ new.band_width = scan_info->op_bw;
+ new.band_type = scan_info->op_band;
+ rtw89_assign_entity_chan(rtwdev, RTW89_SUB_ENTITY_0, &new);
}
}

diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index 85e333e995d2a..b9fb983b6ce24 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -3655,7 +3655,8 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
u32 len)
{
struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif;
- struct rtw89_hal *hal = &rtwdev->hal;
+ const struct rtw89_chan *cur = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ struct rtw89_chan new;
u8 reason, status, tx_fail, band;
u16 chan;

@@ -3681,12 +3682,12 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
rtw89_hw_scan_complete(rtwdev, vif, false);
break;
case RTW89_SCAN_ENTER_CH_NOTIFY:
- hal->prev_band_type = hal->current_band_type;
- hal->current_band_type = band;
- hal->prev_primary_channel = hal->current_primary_channel;
- hal->current_primary_channel = chan;
- hal->current_channel = chan;
- hal->current_band_width = RTW89_CHANNEL_WIDTH_20;
+ new = *cur;
+ new.channel = chan;
+ new.primary_channel = chan;
+ new.band_type = band;
+ new.band_width = RTW89_CHANNEL_WIDTH_20;
+ rtw89_assign_entity_chan(rtwdev, RTW89_SUB_ENTITY_0, &new);
if (rtw89_is_op_chan(rtwdev, band, chan)) {
rtw89_store_op_chan(rtwdev, false);
ieee80211_wake_queues(rtwdev->hw);
diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
index 20fb4c5500104..95ff4bafe5424 100644
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
@@ -235,11 +235,12 @@ 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);
u8 slot_time;
u8 sifs;

slot_time = vif->bss_conf.use_short_slot ? 9 : 20;
- sifs = rtwdev->hal.current_band_type == RTW89_BAND_5G ? 16 : 10;
+ sifs = chan->band_type == RTW89_BAND_5G ? 16 : 10;

return aifsn * slot_time + sifs;
}
diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
index ad86c93a36ebf..dce3ff0cde3ed 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.c
+++ b/drivers/net/wireless/realtek/rtw89/phy.c
@@ -142,8 +142,8 @@ static u64 rtw89_phy_ra_mask_recover(u64 ra_mask, u64 ra_mask_bak)

static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta)
{
- struct rtw89_hal *hal = &rtwdev->hal;
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;
@@ -151,7 +151,7 @@ static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev, struct rtw89_sta *rtw
if (!rtwsta->use_cfg_mask)
return -1;

- switch (hal->current_band_type) {
+ switch (chan->band_type) {
case RTW89_BAND_2G:
band = NL80211_BAND_2GHZ;
cfg_mask = u64_encode_bits(mask->control[NL80211_BAND_2GHZ].legacy,
@@ -168,7 +168,7 @@ static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev, struct rtw89_sta *rtw
RA_MASK_OFDM_RATES);
break;
default:
- rtw89_warn(rtwdev, "unhandled band type %d\n", hal->current_band_type);
+ rtw89_warn(rtwdev, "unhandled band type %d\n", chan->band_type);
return -1;
}

@@ -209,6 +209,7 @@ 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 u64 *high_rate_masks = rtw89_ra_mask_ht_rates;
u8 rssi = ewma_rssi_read(&rtwsta->avg_rssi);
u64 ra_mask = 0;
@@ -260,7 +261,7 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
ldpc_en = 1;
}

- switch (rtwdev->hal.current_band_type) {
+ switch (chan->band_type) {
case RTW89_BAND_2G:
ra_mask |= sta->deflink.supp_rates[NL80211_BAND_2GHZ];
if (sta->deflink.supp_rates[NL80211_BAND_2GHZ] <= 0xf)
@@ -416,6 +417,7 @@ 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,
@@ -428,7 +430,7 @@ void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
RTW89_HW_RATE_MCS8,
RTW89_HW_RATE_MCS16,
RTW89_HW_RATE_MCS24};
- u8 band = rtwdev->hal.current_band_type;
+ u8 band = chan->band_type;
enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band);
u8 tx_nss = rtwdev->hal.tx_nss;
u8 i;
@@ -1471,7 +1473,8 @@ EXPORT_SYMBOL(rtw89_phy_load_txpwr_byrate);
s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev,
const struct rtw89_rate_desc *rate_desc)
{
- enum rtw89_band band = rtwdev->hal.current_band_type;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ enum rtw89_band band = chan->band_type;
s8 *byr;
u8 idx;

@@ -1542,7 +1545,8 @@ s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev,
u8 bw, u8 ntx, u8 rs, u8 bf, u8 ch)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
- u8 band = rtwdev->hal.current_band_type;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ u8 band = chan->band_type;
u8 ch_idx = rtw89_channel_to_idx(rtwdev, band, ch);
u8 regd = rtw89_regd_get(rtwdev, band);
s8 lmt = 0, sar;
@@ -1729,9 +1733,10 @@ void rtw89_phy_fill_txpwr_limit(struct rtw89_dev *rtwdev,
struct rtw89_txpwr_limit *lmt,
u8 ntx)
{
- u8 pri_ch = rtwdev->hal.current_primary_channel;
- u8 ch = rtwdev->hal.current_channel;
- u8 bw = rtwdev->hal.current_band_width;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ u8 pri_ch = chan->primary_channel;
+ u8 ch = chan->channel;
+ u8 bw = chan->band_width;

memset(lmt, 0, sizeof(*lmt));

@@ -1756,7 +1761,8 @@ static s8 rtw89_phy_read_txpwr_limit_ru(struct rtw89_dev *rtwdev,
u8 ru, u8 ntx, u8 ch)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
- u8 band = rtwdev->hal.current_band_type;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ u8 band = chan->band_type;
u8 ch_idx = rtw89_channel_to_idx(rtwdev, band, ch);
u8 regd = rtw89_regd_get(rtwdev, band);
s8 lmt_ru = 0, sar;
@@ -1883,8 +1889,9 @@ void rtw89_phy_fill_txpwr_limit_ru(struct rtw89_dev *rtwdev,
struct rtw89_txpwr_limit_ru *lmt_ru,
u8 ntx)
{
- u8 ch = rtwdev->hal.current_channel;
- u8 bw = rtwdev->hal.current_band_width;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ u8 ch = chan->channel;
+ u8 bw = chan->band_width;

memset(lmt_ru, 0, sizeof(*lmt_ru));

@@ -3247,10 +3254,11 @@ static void rtw89_phy_dig_update_rssi_info(struct rtw89_dev *rtwdev)
static void rtw89_phy_dig_update_para(struct rtw89_dev *rtwdev)
{
struct rtw89_dig_info *dig = &rtwdev->dig;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
bool is_linked = rtwdev->total_sta_assoc > 0;
const u16 *fa_th_src = NULL;

- switch (rtwdev->hal.current_band_type) {
+ switch (chan->band_type) {
case RTW89_BAND_2G:
dig->lna_gain = dig->lna_gain_g;
dig->tia_gain = dig->tia_gain_g;
@@ -3483,7 +3491,8 @@ static void rtw89_phy_dig_config_igi(struct rtw89_dev *rtwdev)
static void rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev, u8 rssi,
bool enable)
{
- enum rtw89_bandwidth cbw = rtwdev->hal.current_band_width;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ enum rtw89_bandwidth cbw = chan->band_width;
struct rtw89_dig_info *dig = &rtwdev->dig;
u8 final_rssi = 0, under_region = dig->pd_low_th_ofst;
u8 ofdm_cca_th;
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
index 6a87f30ca25ca..ef200d32eab33 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
@@ -1381,7 +1381,8 @@ static void rtw8852a_set_txpwr_ref(struct rtw89_dev *rtwdev,
static void rtw8852a_set_txpwr_byrate(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx)
{
- u8 ch = rtwdev->hal.current_channel;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ u8 ch = chan->channel;
static const u8 rs[] = {
RTW89_RS_CCK,
RTW89_RS_OFDM,
@@ -1446,8 +1447,9 @@ static void rtw8852a_set_txpwr_limit(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx)
{
#define __MAC_TXPWR_LMT_PAGE_SIZE 40
- u8 ch = rtwdev->hal.current_channel;
- u8 bw = rtwdev->hal.current_band_width;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ u8 ch = chan->channel;
+ u8 bw = chan->band_width;
struct rtw89_txpwr_limit lmt[NTX_NUM_8852A];
u32 addr, val;
const s8 *ptr;
@@ -1477,8 +1479,9 @@ static void rtw8852a_set_txpwr_limit_ru(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx)
{
#define __MAC_TXPWR_LMT_RU_PAGE_SIZE 24
- u8 ch = rtwdev->hal.current_channel;
- u8 bw = rtwdev->hal.current_band_width;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ u8 ch = chan->channel;
+ u8 bw = chan->band_width;
struct rtw89_txpwr_limit_ru lmt_ru[NTX_NUM_8852A];
u32 addr, val;
const s8 *ptr;
@@ -1593,10 +1596,12 @@ void rtw8852a_bb_set_pmac_tx(struct rtw89_dev *rtwdev,
struct rtw8852a_bb_pmac_info *tx_info,
enum rtw89_phy_idx idx)
{
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+
if (!tx_info->en_pmac_tx) {
rtw8852a_stop_pmac_tx(rtwdev, tx_info, idx);
rtw89_phy_write32_idx(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0, idx);
- if (rtwdev->hal.current_band_type == RTW89_BAND_2G)
+ if (chan->band_type == RTW89_BAND_2G)
rtw89_phy_write32_clr(rtwdev, R_RXCCA, B_RXCCA_DIS);
return;
}
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c
index 3d60feb783121..32744201241ec 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c
@@ -1359,7 +1359,7 @@ static void _iqk_get_ch_info(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy, u8 path)
{
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
- struct rtw89_hal *hal = &rtwdev->hal;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u32 reg_rf18 = 0x0, reg_35c = 0x0;
u8 idx = 0;
u8 get_empty_table = false;
@@ -1380,9 +1380,9 @@ static void _iqk_get_ch_info(struct rtw89_dev *rtwdev,
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]cfg ch = %d\n", reg_rf18);
reg_35c = rtw89_phy_read32_mask(rtwdev, 0x35c, 0x00000c00);

- iqk_info->iqk_band[path] = hal->current_band_type;
- iqk_info->iqk_bw[path] = hal->current_band_width;
- iqk_info->iqk_ch[path] = hal->current_channel;
+ iqk_info->iqk_band[path] = chan->band_type;
+ iqk_info->iqk_bw[path] = chan->band_width;
+ iqk_info->iqk_ch[path] = chan->channel;

rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[IQK]iqk_info->iqk_band[%x] = 0x%x\n", path,
@@ -1879,13 +1879,12 @@ static void _dpk_information(struct rtw89_dev *rtwdev,
enum rtw89_rf_path path)
{
struct rtw89_dpk_info *dpk = &rtwdev->dpk;
- struct rtw89_hal *hal = &rtwdev->hal;
-
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 kidx = dpk->cur_idx[path];

- dpk->bp[path][kidx].band = hal->current_band_type;
- dpk->bp[path][kidx].ch = hal->current_channel;
- dpk->bp[path][kidx].bw = hal->current_band_width;
+ dpk->bp[path][kidx].band = chan->band_type;
+ dpk->bp[path][kidx].ch = chan->channel;
+ dpk->bp[path][kidx].bw = chan->band_width;

rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n",
@@ -2358,6 +2357,7 @@ static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
#define DPK_RXBB_UPPER 0x1f
#define DPK_RXBB_LOWER 0
#define DPK_GL_CRIT 7
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 tmp_txagc, tmp_rxbb = 0, tmp_gl_idx = 0;
u8 agc_cnt = 0;
bool limited_rxbb = false;
@@ -2404,7 +2404,7 @@ static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
"[DPK] Adjust RXBB (%d) = 0x%x\n", offset,
tmp_rxbb);
if (offset != 0 || agc_cnt == 0) {
- if (rtwdev->hal.current_band_width < RTW89_CHANNEL_WIDTH_80)
+ if (chan->band_width < RTW89_CHANNEL_WIDTH_80)
_dpk_bypass_rxcfir(rtwdev, path, true);
else
_dpk_lbk_rxiqk(rtwdev, phy, path);
@@ -2548,11 +2548,12 @@ static bool _dpk_reload_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
enum rtw89_rf_path path)
{
struct rtw89_dpk_info *dpk = &rtwdev->dpk;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
bool is_reload = false;
u8 idx, cur_band, cur_ch;

- cur_band = rtwdev->hal.current_band_type;
- cur_ch = rtwdev->hal.current_channel;
+ cur_band = chan->band_type;
+ cur_ch = chan->channel;

for (idx = 0; idx < RTW89_DPK_BKUP_NUM; idx++) {
if (cur_band != dpk->bp[path][idx].band ||
@@ -2681,12 +2682,13 @@ static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force,
static bool _dpk_bypass_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
{
struct rtw89_fem_info *fem = &rtwdev->fem;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);

- if (fem->epa_2g && rtwdev->hal.current_band_type == RTW89_BAND_2G) {
+ if (fem->epa_2g && chan->band_type == RTW89_BAND_2G) {
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[DPK] Skip DPK due to 2G_ext_PA exist!!\n");
return true;
- } else if (fem->epa_5g && rtwdev->hal.current_band_type == RTW89_BAND_5G) {
+ } else if (fem->epa_5g && chan->band_type == RTW89_BAND_5G) {
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[DPK] Skip DPK due to 5G_ext_PA exist!!\n");
return true;
@@ -2842,7 +2844,8 @@ static void _dpk_track(struct rtw89_dev *rtwdev)
static void _tssi_rf_setting(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
enum rtw89_rf_path path)
{
- enum rtw89_band band = rtwdev->hal.current_band_type;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ enum rtw89_band band = chan->band_type;

if (band == RTW89_BAND_2G)
rtw89_write_rf(rtwdev, path, RR_TXPOW, RR_TXPOW_TXG, 0x1);
@@ -2852,7 +2855,8 @@ static void _tssi_rf_setting(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,

static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
{
- enum rtw89_band band = rtwdev->hal.current_band_type;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ enum rtw89_band band = chan->band_type;

rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_sys_defs_tbl);
rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G,
@@ -2863,7 +2867,8 @@ static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
static void _tssi_ini_txpwr_ctrl_bb(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
enum rtw89_rf_path path)
{
- enum rtw89_band band = rtwdev->hal.current_band_type;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ enum rtw89_band band = chan->band_type;

rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A,
&rtw8852a_tssi_txpwr_ctrl_bb_defs_a_tbl,
@@ -2905,8 +2910,9 @@ static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx ph
__val; \
})
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- u8 ch = rtwdev->hal.current_channel;
- u8 subband = rtwdev->hal.current_subband;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ u8 ch = chan->channel;
+ u8 subband = chan->subband_type;
const s8 *thm_up_a = NULL;
const s8 *thm_down_a = NULL;
const s8 *thm_up_b = NULL;
@@ -3099,7 +3105,8 @@ static void _tssi_set_txagc_offset_mv_avg(struct rtw89_dev *rtwdev,
static void _tssi_pak(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
enum rtw89_rf_path path)
{
- u8 subband = rtwdev->hal.current_subband;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ u8 subband = chan->subband_type;

switch (subband) {
default:
@@ -3275,7 +3282,8 @@ static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
enum rtw89_rf_path path)
{
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- u8 ch = rtwdev->hal.current_channel;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ u8 ch = chan->channel;
u32 gidx, gidx_1st, gidx_2nd;
s8 de_1st = 0;
s8 de_2nd = 0;
@@ -3312,7 +3320,8 @@ static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev,
enum rtw89_rf_path path)
{
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- u8 ch = rtwdev->hal.current_channel;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ u8 ch = chan->channel;
u32 tgidx, tgidx_1st, tgidx_2nd;
s8 tde_1st = 0;
s8 tde_2nd = 0;
@@ -3350,6 +3359,7 @@ static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev,
{
#define __DE_MASK 0x003ff000
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
static const u32 r_cck_long[RF_PATH_NUM_8852A] = {0x5858, 0x7858};
static const u32 r_cck_short[RF_PATH_NUM_8852A] = {0x5860, 0x7860};
static const u32 r_mcs_20m[RF_PATH_NUM_8852A] = {0x5838, 0x7838};
@@ -3358,7 +3368,7 @@ static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev,
static const u32 r_mcs_80m_80m[RF_PATH_NUM_8852A] = {0x5850, 0x7850};
static const u32 r_mcs_5m[RF_PATH_NUM_8852A] = {0x5828, 0x7828};
static const u32 r_mcs_10m[RF_PATH_NUM_8852A] = {0x5830, 0x7830};
- u8 ch = rtwdev->hal.current_channel;
+ u8 ch = chan->channel;
u8 i, gidx;
s8 ofdm_de;
s8 trim_de;
@@ -3478,9 +3488,10 @@ static void _tssi_track(struct rtw89_dev *rtwdev)
static void _tssi_high_power(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
{
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- u8 ch = rtwdev->hal.current_channel, ch_tmp;
- u8 bw = rtwdev->hal.current_band_width;
- u8 subband = rtwdev->hal.current_subband;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ u8 ch = chan->channel, ch_tmp;
+ u8 bw = chan->band_width;
+ u8 subband = chan->subband_type;
s8 power;
s32 xdbm;

@@ -3523,9 +3534,10 @@ static void _tssi_hw_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
static void _tssi_pre_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
{
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
const struct rtw89_chip_info *mac_reg = rtwdev->chip;
- u8 ch = rtwdev->hal.current_channel, ch_tmp;
- u8 bw = rtwdev->hal.current_band_width;
+ u8 ch = chan->channel, ch_tmp;
+ u8 bw = chan->band_width;
u32 tx_en;
u8 phy_map = rtw89_btc_phymap(rtwdev, phy, 0);
s8 power;
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
index 8c00aaeedb920..b81aec0630969 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
@@ -1532,7 +1532,7 @@ static void rtw8852c_bb_reset_all(struct rtw89_dev *rtwdev,
static void rtw8852c_bb_reset_en(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx, bool en)
{
- struct rtw89_hal *hal = &rtwdev->hal;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);

if (en) {
rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS,
@@ -1541,7 +1541,7 @@ static void rtw8852c_bb_reset_en(struct rtw89_dev *rtwdev,
B_S1_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx);
rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1,
phy_idx);
- if (hal->current_band_type == RTW89_BAND_2G)
+ if (chan->band_type == RTW89_BAND_2G)
rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, 0x0);
rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x0);
} else {
@@ -1964,7 +1964,8 @@ static void rtw8852c_set_txpwr_ref(struct rtw89_dev *rtwdev,
static void rtw8852c_set_txpwr_byrate(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx)
{
- u8 ch = rtwdev->hal.current_channel;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ u8 ch = chan->channel;
static const u8 rs[] = {
RTW89_RS_CCK,
RTW89_RS_OFDM,
@@ -2049,7 +2050,8 @@ static void rtw8852c_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev,
__DECL_DFIR_ADDR(filter,
0x45BC, 0x45CC, 0x45D0, 0x45D4, 0x45D8, 0x45C0,
0x45C4, 0x45C8);
- u8 ch = rtwdev->hal.current_channel;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ u8 ch = chan->channel;
const u32 *param;
int i;

@@ -2082,7 +2084,8 @@ static void rtw8852c_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev,
static void rtw8852c_set_tx_shape(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx)
{
- u8 band = rtwdev->hal.current_band_type;
+ 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);
u8 tx_shape_cck = rtw89_8852c_tx_shape[band][RTW89_RS_CCK][regd];
u8 tx_shape_ofdm = rtw89_8852c_tx_shape[band][RTW89_RS_OFDM][regd];
@@ -2099,8 +2102,9 @@ static void rtw8852c_set_txpwr_limit(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx)
{
#define __MAC_TXPWR_LMT_PAGE_SIZE 40
- u8 ch = rtwdev->hal.current_channel;
- u8 bw = rtwdev->hal.current_band_width;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ u8 ch = chan->channel;
+ u8 bw = chan->band_width;
struct rtw89_txpwr_limit lmt[NTX_NUM_8852C];
u32 addr, val;
const s8 *ptr;
@@ -2130,8 +2134,9 @@ static void rtw8852c_set_txpwr_limit_ru(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx)
{
#define __MAC_TXPWR_LMT_RU_PAGE_SIZE 24
- u8 ch = rtwdev->hal.current_channel;
- u8 bw = rtwdev->hal.current_band_width;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ u8 ch = chan->channel;
+ u8 bw = chan->band_width;
struct rtw89_txpwr_limit_ru lmt_ru[NTX_NUM_8852C];
u32 addr, val;
const s8 *ptr;
@@ -2226,7 +2231,8 @@ rtw8852c_init_txpwr_unit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)

static void rtw8852c_bb_cfg_rx_path(struct rtw89_dev *rtwdev, u8 rx_path)
{
- struct rtw89_hal *hal = &rtwdev->hal;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ u8 band = chan->band_type;
u32 rst_mask0 = B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI;
u32 rst_mask1 = B_P1_TXPW_RSTB_MANON | B_P1_TXPW_RSTB_TSSI;

@@ -2320,7 +2326,7 @@ static void rtw8852c_bb_cfg_rx_path(struct rtw89_dev *rtwdev, u8 rx_path)
1);
rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS,
1);
- rtw8852c_ctrl_btg(rtwdev, hal->current_band_type == RTW89_BAND_2G);
+ rtw8852c_ctrl_btg(rtwdev, band == RTW89_BAND_2G);
rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
rst_mask0, 1);
rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c
index fa109ee673cfc..478a36de1bd3d 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c
@@ -1294,14 +1294,14 @@ static void _iqk_by_path(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u
static void _iqk_get_ch_info(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy, u8 path)
{
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
- struct rtw89_hal *hal = &rtwdev->hal;

rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__);

- iqk_info->iqk_band[path] = hal->current_band_type;
- iqk_info->iqk_bw[path] = hal->current_band_width;
- iqk_info->iqk_ch[path] = hal->current_channel;
+ iqk_info->iqk_band[path] = chan->band_type;
+ iqk_info->iqk_bw[path] = chan->band_width;
+ iqk_info->iqk_ch[path] = chan->channel;

rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[IQK]iqk_info->iqk_band[%x] = 0x%x\n", path,
@@ -1691,14 +1691,14 @@ static void _dpk_information(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy,
enum rtw89_rf_path path)
{
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
struct rtw89_dpk_info *dpk = &rtwdev->dpk;
- struct rtw89_hal *hal = &rtwdev->hal;

u8 kidx = dpk->cur_idx[path];

- dpk->bp[path][kidx].band = hal->current_band_type;
- dpk->bp[path][kidx].ch = hal->current_channel;
- dpk->bp[path][kidx].bw = hal->current_band_width;
+ dpk->bp[path][kidx].band = chan->band_type;
+ dpk->bp[path][kidx].ch = chan->channel;
+ dpk->bp[path][kidx].bw = chan->band_width;

rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n",
@@ -2272,12 +2272,13 @@ static void _dpk_idl_mpa(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
static bool _dpk_reload_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
enum rtw89_rf_path path)
{
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
struct rtw89_dpk_info *dpk = &rtwdev->dpk;
bool is_reload = false;
u8 idx, cur_band, cur_ch;

- cur_band = rtwdev->hal.current_band_type;
- cur_ch = rtwdev->hal.current_channel;
+ cur_band = chan->band_type;
+ cur_ch = chan->channel;

for (idx = 0; idx < RTW89_DPK_BKUP_NUM; idx++) {
if (cur_band != dpk->bp[path][idx].band ||
@@ -2530,17 +2531,19 @@ static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force,
static bool _dpk_bypass_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
{
struct rtw89_fem_info *fem = &rtwdev->fem;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ u8 band = chan->band_type;

- if (rtwdev->hal.cv == CHIP_CAV && rtwdev->hal.current_band_type != RTW89_BAND_2G) {
+ if (rtwdev->hal.cv == CHIP_CAV && band != RTW89_BAND_2G) {
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Skip DPK due to CAV & not 2G!!\n");
return true;
- } else if (fem->epa_2g && rtwdev->hal.current_band_type == RTW89_BAND_2G) {
+ } else if (fem->epa_2g && band == RTW89_BAND_2G) {
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Skip DPK due to 2G_ext_PA exist!!\n");
return true;
- } else if (fem->epa_5g && rtwdev->hal.current_band_type == RTW89_BAND_5G) {
+ } else if (fem->epa_5g && band == RTW89_BAND_5G) {
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Skip DPK due to 5G_ext_PA exist!!\n");
return true;
- } else if (fem->epa_6g && rtwdev->hal.current_band_type == RTW89_BAND_6G) {
+ } else if (fem->epa_6g && band == RTW89_BAND_6G) {
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Skip DPK due to 6G_ext_PA exist!!\n");
return true;
}
@@ -2663,7 +2666,8 @@ static void _dpk_track(struct rtw89_dev *rtwdev)
static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
enum rtw89_rf_path path)
{
- enum rtw89_band band = rtwdev->hal.current_band_type;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ enum rtw89_band band = chan->band_type;

rtw89_rfk_parser(rtwdev, &rtw8852c_tssi_sys_defs_tbl);

@@ -2697,7 +2701,8 @@ static void _tssi_ini_txpwr_ctrl_bb_he_tb(struct rtw89_dev *rtwdev,
static void _tssi_set_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
enum rtw89_rf_path path)
{
- enum rtw89_band band = rtwdev->hal.current_band_type;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ enum rtw89_band band = chan->band_type;

if (path == RF_PATH_A) {
rtw89_rfk_parser(rtwdev, &rtw8852c_tssi_dck_defs_a_tbl);
@@ -2735,8 +2740,9 @@ static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx ph
__val; \
})
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- u8 ch = rtwdev->hal.current_channel;
- u8 subband = rtwdev->hal.current_subband;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ u8 ch = chan->channel;
+ u8 subband = chan->subband_type;
const s8 *thm_up_a = NULL;
const s8 *thm_down_a = NULL;
const s8 *thm_up_b = NULL;
@@ -2908,7 +2914,8 @@ static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx ph
static void _tssi_slope_cal_org(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
enum rtw89_rf_path path)
{
- enum rtw89_band band = rtwdev->hal.current_band_type;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ enum rtw89_band band = chan->band_type;

if (path == RF_PATH_A) {
rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G,
@@ -2924,7 +2931,8 @@ static void _tssi_slope_cal_org(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy
static void _tssi_set_aligk_default(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
enum rtw89_rf_path path)
{
- enum rtw89_band band = rtwdev->hal.current_band_type;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ enum rtw89_band band = chan->band_type;
const struct rtw89_rfk_tbl *tbl;

if (path == RF_PATH_A) {
@@ -3335,8 +3343,9 @@ static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
enum rtw89_rf_path path)
{
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- enum rtw89_band band = rtwdev->hal.current_band_type;
- u8 ch = rtwdev->hal.current_channel;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ enum rtw89_band band = chan->band_type;
+ u8 ch = chan->channel;
u32 gidx, gidx_1st, gidx_2nd;
s8 de_1st;
s8 de_2nd;
@@ -3398,8 +3407,9 @@ static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev,
enum rtw89_rf_path path)
{
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- enum rtw89_band band = rtwdev->hal.current_band_type;
- u8 ch = rtwdev->hal.current_channel;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ enum rtw89_band band = chan->band_type;
+ u8 ch = chan->channel;
u32 tgidx, tgidx_1st, tgidx_2nd;
s8 tde_1st = 0;
s8 tde_2nd = 0;
@@ -3462,7 +3472,8 @@ static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy)
{
struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
- u8 ch = rtwdev->hal.current_channel;
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ u8 ch = chan->channel;
u8 gidx;
s8 ofdm_de;
s8 trim_de;
@@ -3812,6 +3823,7 @@ void rtw8852c_set_channel_rf(struct rtw89_dev *rtwdev,

void rtw8852c_mcc_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
{
+ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
struct rtw89_mcc_info *mcc_info = &rtwdev->mcc;
u8 idx = mcc_info->table_idx;
int i;
@@ -3824,8 +3836,8 @@ void rtw8852c_mcc_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_i
}

mcc_info->table_idx = idx;
- mcc_info->ch[idx] = rtwdev->hal.current_channel;
- mcc_info->band[idx] = rtwdev->hal.current_band_type;
+ mcc_info->ch[idx] = chan->channel;
+ mcc_info->band[idx] = chan->band_type;
}

void rtw8852c_rck(struct rtw89_dev *rtwdev)
diff --git a/drivers/net/wireless/realtek/rtw89/sar.c b/drivers/net/wireless/realtek/rtw89/sar.c
index 41cd619f4e980..dfccae81c3804 100644
--- a/drivers/net/wireless/realtek/rtw89/sar.c
+++ b/drivers/net/wireless/realtek/rtw89/sar.c
@@ -81,9 +81,9 @@ static const struct rtw89_sar_span rtw89_sar_overlapping_6ghz[] = {
static int rtw89_query_sar_config_common(struct rtw89_dev *rtwdev, s32 *cfg)
{
struct rtw89_sar_cfg_common *rtwsar = &rtwdev->sar.cfg_common;
- struct rtw89_hal *hal = &rtwdev->hal;
- enum rtw89_band band = hal->current_band_type;
- u32 center_freq = hal->current_freq;
+ 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;
--
2.25.1

2022-06-23 04:47:17

by Ping-Ke Shih

[permalink] [raw]
Subject: [PATCH v2 04/13] rtw89: create rtw89_chan centrally to avoid breakage

From: Zong-Zhe Yang <[email protected]>

Sometimes we need to write current rtw89_chan outside set_channel(),
e.g. during HW scan, we adjust it to align FW process through C2H.
However, we don't have full parameters to fill entire rtw89_chan.
And it will breakage if we update only part of current rtw89_chan.
That is what we don't want to see because most flows throughout
driver treat rtw89_chan as a whole.

So, we divide struct rtw89_chan to basic part and derived part. The
basic part contains the parameters which we are always able to know.
And the derived part will be calculated by the basic part. Then, a
central function, rtw89_chan_create(), is added to deal with this.

Signed-off-by: Zong-Zhe Yang <[email protected]>
Signed-off-by: Ping-Ke Shih <[email protected]>
---
drivers/net/wireless/realtek/rtw89/chan.c | 98 +++++++++++++++++++++++
drivers/net/wireless/realtek/rtw89/chan.h | 2 +
drivers/net/wireless/realtek/rtw89/core.c | 70 +---------------
drivers/net/wireless/realtek/rtw89/core.h | 6 +-
drivers/net/wireless/realtek/rtw89/fw.c | 7 +-
drivers/net/wireless/realtek/rtw89/mac.c | 7 +-
6 files changed, 109 insertions(+), 81 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c
index a5d1bf573ea62..0bf27a344d2b4 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.c
+++ b/drivers/net/wireless/realtek/rtw89/chan.c
@@ -4,6 +4,104 @@

#include "chan.h"

+static enum rtw89_subband rtw89_get_subband_type(enum rtw89_band band,
+ u8 center_chan)
+{
+ switch (band) {
+ default:
+ case RTW89_BAND_2G:
+ switch (center_chan) {
+ default:
+ case 1 ... 14:
+ return RTW89_CH_2G;
+ }
+ case RTW89_BAND_5G:
+ switch (center_chan) {
+ default:
+ case 36 ... 64:
+ return RTW89_CH_5G_BAND_1;
+ case 100 ... 144:
+ return RTW89_CH_5G_BAND_3;
+ case 149 ... 177:
+ return RTW89_CH_5G_BAND_4;
+ }
+ case RTW89_BAND_6G:
+ switch (center_chan) {
+ default:
+ case 1 ... 29:
+ return RTW89_CH_6G_BAND_IDX0;
+ case 33 ... 61:
+ return RTW89_CH_6G_BAND_IDX1;
+ case 65 ... 93:
+ return RTW89_CH_6G_BAND_IDX2;
+ case 97 ... 125:
+ return RTW89_CH_6G_BAND_IDX3;
+ case 129 ... 157:
+ return RTW89_CH_6G_BAND_IDX4;
+ case 161 ... 189:
+ return RTW89_CH_6G_BAND_IDX5;
+ case 193 ... 221:
+ return RTW89_CH_6G_BAND_IDX6;
+ case 225 ... 253:
+ return RTW89_CH_6G_BAND_IDX7;
+ }
+ }
+}
+
+static enum rtw89_sc_offset rtw89_get_primary_chan_idx(enum rtw89_bandwidth bw,
+ u32 center_freq,
+ u32 primary_freq)
+{
+ u8 primary_chan_idx;
+ u32 offset;
+
+ switch (bw) {
+ default:
+ case RTW89_CHANNEL_WIDTH_20:
+ primary_chan_idx = RTW89_SC_DONT_CARE;
+ break;
+ case RTW89_CHANNEL_WIDTH_40:
+ if (primary_freq > center_freq)
+ primary_chan_idx = RTW89_SC_20_UPPER;
+ else
+ primary_chan_idx = RTW89_SC_20_LOWER;
+ break;
+ case RTW89_CHANNEL_WIDTH_80:
+ case RTW89_CHANNEL_WIDTH_160:
+ if (primary_freq > center_freq) {
+ offset = (primary_freq - center_freq - 10) / 20;
+ primary_chan_idx = RTW89_SC_20_UPPER + offset * 2;
+ } else {
+ offset = (center_freq - primary_freq - 10) / 20;
+ primary_chan_idx = RTW89_SC_20_LOWER + offset * 2;
+ }
+ break;
+ }
+
+ return primary_chan_idx;
+}
+
+void rtw89_chan_create(struct rtw89_chan *chan, u8 center_chan, u8 primary_chan,
+ enum rtw89_band band, enum rtw89_bandwidth bandwidth)
+{
+ enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band);
+ u32 center_freq, primary_freq;
+
+ memset(chan, 0, sizeof(*chan));
+ chan->channel = center_chan;
+ chan->primary_channel = primary_chan;
+ chan->band_type = band;
+ chan->band_width = bandwidth;
+
+ center_freq = ieee80211_channel_to_frequency(center_chan, nl_band);
+ primary_freq = ieee80211_channel_to_frequency(primary_chan, nl_band);
+
+ chan->freq = center_freq;
+ chan->subband_type = rtw89_get_subband_type(band, center_chan);
+ chan->pri_ch_idx = rtw89_get_primary_chan_idx(bandwidth, center_freq,
+ primary_freq);
+}
+
bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev,
enum rtw89_sub_entity_idx idx,
const struct rtw89_chan *new)
diff --git a/drivers/net/wireless/realtek/rtw89/chan.h b/drivers/net/wireless/realtek/rtw89/chan.h
index ac5cc356b8182..d39311a3d5baf 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.h
+++ b/drivers/net/wireless/realtek/rtw89/chan.h
@@ -21,6 +21,8 @@ static inline void rtw89_set_entity_state(struct rtw89_dev *rtwdev, bool active)
WRITE_ONCE(hal->entity_active, active);
}

+void rtw89_chan_create(struct rtw89_chan *chan, u8 center_chan, u8 primary_chan,
+ enum rtw89_band band, enum rtw89_bandwidth bandwidth);
bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev,
enum rtw89_sub_entity_idx idx,
const struct rtw89_chan *new);
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 78d9e6a7a0981..6ffad5da9161e 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -233,10 +233,8 @@ static void rtw89_get_channel_params(struct cfg80211_chan_def *chandef,
u32 primary_freq, center_freq;
u8 center_chan;
u8 bandwidth = RTW89_CHANNEL_WIDTH_20;
- u8 primary_chan_idx = 0;
u32 offset;
u8 band;
- u8 subband;

center_chan = channel->hw_value;
primary_freq = channel->center_freq;
@@ -246,15 +244,12 @@ static void rtw89_get_channel_params(struct cfg80211_chan_def *chandef,
case NL80211_CHAN_WIDTH_20_NOHT:
case NL80211_CHAN_WIDTH_20:
bandwidth = RTW89_CHANNEL_WIDTH_20;
- primary_chan_idx = RTW89_SC_DONT_CARE;
break;
case NL80211_CHAN_WIDTH_40:
bandwidth = RTW89_CHANNEL_WIDTH_40;
if (primary_freq > center_freq) {
- primary_chan_idx = RTW89_SC_20_UPPER;
center_chan -= 2;
} else {
- primary_chan_idx = RTW89_SC_20_LOWER;
center_chan += 2;
}
break;
@@ -263,11 +258,9 @@ static void rtw89_get_channel_params(struct cfg80211_chan_def *chandef,
bandwidth = nl_to_rtw89_bandwidth(width);
if (primary_freq > center_freq) {
offset = (primary_freq - center_freq - 10) / 20;
- primary_chan_idx = RTW89_SC_20_UPPER + offset * 2;
center_chan -= 2 + offset * 4;
} else {
offset = (center_freq - primary_freq - 10) / 20;
- primary_chan_idx = RTW89_SC_20_LOWER + offset * 2;
center_chan += 2 + offset * 4;
}
break;
@@ -289,68 +282,7 @@ static void rtw89_get_channel_params(struct cfg80211_chan_def *chandef,
break;
}

- switch (band) {
- default:
- case RTW89_BAND_2G:
- switch (center_chan) {
- default:
- case 1 ... 14:
- subband = RTW89_CH_2G;
- break;
- }
- break;
- case RTW89_BAND_5G:
- switch (center_chan) {
- default:
- case 36 ... 64:
- subband = RTW89_CH_5G_BAND_1;
- break;
- case 100 ... 144:
- subband = RTW89_CH_5G_BAND_3;
- break;
- case 149 ... 177:
- subband = RTW89_CH_5G_BAND_4;
- break;
- }
- break;
- case RTW89_BAND_6G:
- switch (center_chan) {
- default:
- case 1 ... 29:
- subband = RTW89_CH_6G_BAND_IDX0;
- break;
- case 33 ... 61:
- subband = RTW89_CH_6G_BAND_IDX1;
- break;
- case 65 ... 93:
- subband = RTW89_CH_6G_BAND_IDX2;
- break;
- case 97 ... 125:
- subband = RTW89_CH_6G_BAND_IDX3;
- break;
- case 129 ... 157:
- subband = RTW89_CH_6G_BAND_IDX4;
- break;
- case 161 ... 189:
- subband = RTW89_CH_6G_BAND_IDX5;
- break;
- case 193 ... 221:
- subband = RTW89_CH_6G_BAND_IDX6;
- break;
- case 225 ... 253:
- subband = RTW89_CH_6G_BAND_IDX7;
- break;
- }
- break;
- }
-
- chan->channel = center_chan;
- chan->freq = center_freq;
- chan->primary_channel = channel->hw_value;
- chan->band_type = band;
- chan->band_width = bandwidth;
- chan->subband_type = subband;
- chan->pri_ch_idx = primary_chan_idx;
+ rtw89_chan_create(chan, center_chan, channel->hw_value, band, bandwidth);
}

void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev)
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 86e7341198c6f..cc61043fb5da6 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -632,10 +632,14 @@ enum rtw89_sc_offset {

struct rtw89_chan {
u8 channel;
- u32 freq;
u8 primary_channel;
enum rtw89_band band_type;
enum rtw89_bandwidth band_width;
+
+ /* The follow-up are derived from the above. We must ensure that it
+ * is assigned correctly in rtw89_chan_create() if new one is added.
+ */
+ u32 freq;
enum rtw89_subband subband_type;
enum rtw89_sc_offset pri_ch_idx;
};
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 8dcd02d90f457..cee9815b6df6f 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -2388,11 +2388,8 @@ void rtw89_store_op_chan(struct rtw89_dev *rtwdev, bool backup)
scan_info->op_bw = cur->band_width;
scan_info->op_band = cur->band_type;
} else {
- new = *cur;
- new.primary_channel = scan_info->op_pri_ch;
- new.channel = scan_info->op_chan;
- new.band_width = scan_info->op_bw;
- new.band_type = scan_info->op_band;
+ rtw89_chan_create(&new, scan_info->op_chan, scan_info->op_pri_ch,
+ scan_info->op_band, scan_info->op_bw);
rtw89_assign_entity_chan(rtwdev, RTW89_SUB_ENTITY_0, &new);
}
}
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index b9fb983b6ce24..b90ab56b1c771 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -3655,7 +3655,6 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
u32 len)
{
struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif;
- const struct rtw89_chan *cur = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
struct rtw89_chan new;
u8 reason, status, tx_fail, band;
u16 chan;
@@ -3682,11 +3681,7 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
rtw89_hw_scan_complete(rtwdev, vif, false);
break;
case RTW89_SCAN_ENTER_CH_NOTIFY:
- new = *cur;
- new.channel = chan;
- new.primary_channel = chan;
- new.band_type = band;
- new.band_width = RTW89_CHANNEL_WIDTH_20;
+ rtw89_chan_create(&new, chan, chan, band, RTW89_CHANNEL_WIDTH_20);
rtw89_assign_entity_chan(rtwdev, RTW89_SUB_ENTITY_0, &new);
if (rtw89_is_op_chan(rtwdev, band, chan)) {
rtw89_store_op_chan(rtwdev, false);
--
2.25.1

2022-06-23 04:47:24

by Ping-Ke Shih

[permalink] [raw]
Subject: [PATCH v2 05/13] rtw89: txpwr: concentrate channel related control to top

From: Zong-Zhe Yang <[email protected]>

For future support on multiple channels, it would be disturbing if we
still allow scattered leaf functions of TX power to query and manage
channel related control by themselves.

So, query rtw89_chan only on top functions. Then, pass it via functions
to make sure that the values coming from the same struct rtw89_chan.

Besides, fix rtw8852a_set_txpwr_offset() from rtw8852a_set_txpwr_ctrl()
to rtw8852a_set_txpwr(). TX power offset should consider current band,
so move it to chip_ops::set_txpwr() which will be called every time that
channel is set.

Signed-off-by: Zong-Zhe Yang <[email protected]>
Signed-off-by: Ping-Ke Shih <[email protected]>
---
drivers/net/wireless/realtek/rtw89/core.c | 4 +-
drivers/net/wireless/realtek/rtw89/core.h | 9 +-
drivers/net/wireless/realtek/rtw89/phy.c | 235 +++++++++++-------
drivers/net/wireless/realtek/rtw89/phy.h | 6 +-
drivers/net/wireless/realtek/rtw89/rtw8852a.c | 35 +--
.../net/wireless/realtek/rtw89/rtw8852a_rfk.c | 9 +-
drivers/net/wireless/realtek/rtw89/rtw8852c.c | 39 +--
7 files changed, 206 insertions(+), 131 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 6ffad5da9161e..ebe1980b0aa08 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -288,14 +288,16 @@ static void rtw89_get_channel_params(struct cfg80211_chan_def *chandef,
void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
+ const struct rtw89_chan *chan;
bool entity_active;

entity_active = rtw89_get_entity_state(rtwdev);
if (!entity_active)
return;

+ chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
if (chip->ops->set_txpwr)
- chip->ops->set_txpwr(rtwdev);
+ chip->ops->set_txpwr(rtwdev, chan, RTW89_PHY_0);
}

void rtw89_set_channel(struct rtw89_dev *rtwdev)
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index cc61043fb5da6..526a595882168 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -2127,8 +2127,11 @@ struct rtw89_chip_ops {
void (*rfk_scan)(struct rtw89_dev *rtwdev, bool start);
void (*rfk_track)(struct rtw89_dev *rtwdev);
void (*power_trim)(struct rtw89_dev *rtwdev);
- void (*set_txpwr)(struct rtw89_dev *rtwdev);
- void (*set_txpwr_ctrl)(struct rtw89_dev *rtwdev);
+ void (*set_txpwr)(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
+ enum rtw89_phy_idx phy_idx);
+ void (*set_txpwr_ctrl)(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx);
int (*init_txpwr_unit)(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
u8 (*get_thermal)(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path);
void (*ctrl_btg)(struct rtw89_dev *rtwdev, bool btg);
@@ -3691,7 +3694,7 @@ static inline void rtw89_chip_set_txpwr_ctrl(struct rtw89_dev *rtwdev)
const struct rtw89_chip_info *chip = rtwdev->chip;

if (chip->ops->set_txpwr_ctrl)
- chip->ops->set_txpwr_ctrl(rtwdev);
+ chip->ops->set_txpwr_ctrl(rtwdev, RTW89_PHY_0);
}

static inline void rtw89_chip_power_trim(struct rtw89_dev *rtwdev)
diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
index dce3ff0cde3ed..a4dfd2ec8fdf6 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.c
+++ b/drivers/net/wireless/realtek/rtw89/phy.c
@@ -1470,11 +1470,9 @@ EXPORT_SYMBOL(rtw89_phy_load_txpwr_byrate);
(txpwr_rf) >> (__c->txpwr_factor_rf - __c->txpwr_factor_mac); \
})

-s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev,
+s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev, u8 band,
const struct rtw89_rate_desc *rate_desc)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
- enum rtw89_band band = chan->band_type;
s8 *byr;
u8 idx;

@@ -1541,12 +1539,10 @@ static u8 rtw89_channel_to_idx(struct rtw89_dev *rtwdev, u8 band, u8 channel)
}
}

-s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev,
+s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, u8 band,
u8 bw, u8 ntx, u8 rs, u8 bf, u8 ch)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
- u8 band = chan->band_type;
u8 ch_idx = rtw89_channel_to_idx(rtwdev, band, ch);
u8 regd = rtw89_regd_get(rtwdev, band);
s8 lmt = 0, sar;
@@ -1582,11 +1578,12 @@ s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev,
}
EXPORT_SYMBOL(rtw89_phy_read_txpwr_limit);

-#define __fill_txpwr_limit_nonbf_bf(ptr, bw, ntx, rs, ch) \
+#define __fill_txpwr_limit_nonbf_bf(ptr, band, bw, ntx, rs, ch) \
do { \
u8 __i; \
for (__i = 0; __i < RTW89_BF_NUM; __i++) \
ptr[__i] = rtw89_phy_read_txpwr_limit(rtwdev, \
+ band, \
bw, ntx, \
rs, __i, \
(ch)); \
@@ -1594,64 +1591,75 @@ EXPORT_SYMBOL(rtw89_phy_read_txpwr_limit);

static void rtw89_phy_fill_txpwr_limit_20m(struct rtw89_dev *rtwdev,
struct rtw89_txpwr_limit *lmt,
- u8 ntx, u8 ch)
+ u8 band, u8 ntx, u8 ch)
{
- __fill_txpwr_limit_nonbf_bf(lmt->cck_20m, RTW89_CHANNEL_WIDTH_20,
+ __fill_txpwr_limit_nonbf_bf(lmt->cck_20m, band, RTW89_CHANNEL_WIDTH_20,
ntx, RTW89_RS_CCK, ch);
- __fill_txpwr_limit_nonbf_bf(lmt->cck_40m, RTW89_CHANNEL_WIDTH_40,
+ __fill_txpwr_limit_nonbf_bf(lmt->cck_40m, band, RTW89_CHANNEL_WIDTH_40,
ntx, RTW89_RS_CCK, ch);
- __fill_txpwr_limit_nonbf_bf(lmt->ofdm, RTW89_CHANNEL_WIDTH_20,
+ __fill_txpwr_limit_nonbf_bf(lmt->ofdm, band, RTW89_CHANNEL_WIDTH_20,
ntx, RTW89_RS_OFDM, ch);
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], RTW89_CHANNEL_WIDTH_20,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], band,
+ RTW89_CHANNEL_WIDTH_20,
ntx, RTW89_RS_MCS, ch);
}

static void rtw89_phy_fill_txpwr_limit_40m(struct rtw89_dev *rtwdev,
struct rtw89_txpwr_limit *lmt,
- u8 ntx, u8 ch, u8 pri_ch)
+ u8 band, u8 ntx, u8 ch, u8 pri_ch)
{
- __fill_txpwr_limit_nonbf_bf(lmt->cck_20m, RTW89_CHANNEL_WIDTH_20,
+ __fill_txpwr_limit_nonbf_bf(lmt->cck_20m, band, RTW89_CHANNEL_WIDTH_20,
ntx, RTW89_RS_CCK, ch - 2);
- __fill_txpwr_limit_nonbf_bf(lmt->cck_40m, RTW89_CHANNEL_WIDTH_40,
+ __fill_txpwr_limit_nonbf_bf(lmt->cck_40m, band, RTW89_CHANNEL_WIDTH_40,
ntx, RTW89_RS_CCK, ch);
- __fill_txpwr_limit_nonbf_bf(lmt->ofdm, RTW89_CHANNEL_WIDTH_20,
+ __fill_txpwr_limit_nonbf_bf(lmt->ofdm, band, RTW89_CHANNEL_WIDTH_20,
ntx, RTW89_RS_OFDM, pri_ch);
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], RTW89_CHANNEL_WIDTH_20,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], band,
+ RTW89_CHANNEL_WIDTH_20,
ntx, RTW89_RS_MCS, ch - 2);
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[1], RTW89_CHANNEL_WIDTH_20,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[1], band,
+ RTW89_CHANNEL_WIDTH_20,
ntx, RTW89_RS_MCS, ch + 2);
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[0], RTW89_CHANNEL_WIDTH_40,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[0], band,
+ RTW89_CHANNEL_WIDTH_40,
ntx, RTW89_RS_MCS, ch);
}

static void rtw89_phy_fill_txpwr_limit_80m(struct rtw89_dev *rtwdev,
struct rtw89_txpwr_limit *lmt,
- u8 ntx, u8 ch, u8 pri_ch)
+ u8 band, u8 ntx, u8 ch, u8 pri_ch)
{
s8 val_0p5_n[RTW89_BF_NUM];
s8 val_0p5_p[RTW89_BF_NUM];
u8 i;

- __fill_txpwr_limit_nonbf_bf(lmt->ofdm, RTW89_CHANNEL_WIDTH_20,
+ __fill_txpwr_limit_nonbf_bf(lmt->ofdm, band, RTW89_CHANNEL_WIDTH_20,
ntx, RTW89_RS_OFDM, pri_ch);
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], RTW89_CHANNEL_WIDTH_20,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], band,
+ RTW89_CHANNEL_WIDTH_20,
ntx, RTW89_RS_MCS, ch - 6);
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[1], RTW89_CHANNEL_WIDTH_20,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[1], band,
+ RTW89_CHANNEL_WIDTH_20,
ntx, RTW89_RS_MCS, ch - 2);
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[2], RTW89_CHANNEL_WIDTH_20,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[2], band,
+ RTW89_CHANNEL_WIDTH_20,
ntx, RTW89_RS_MCS, ch + 2);
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[3], RTW89_CHANNEL_WIDTH_20,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[3], band,
+ RTW89_CHANNEL_WIDTH_20,
ntx, RTW89_RS_MCS, ch + 6);
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[0], RTW89_CHANNEL_WIDTH_40,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[0], band,
+ RTW89_CHANNEL_WIDTH_40,
ntx, RTW89_RS_MCS, ch - 4);
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[1], RTW89_CHANNEL_WIDTH_40,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[1], band,
+ RTW89_CHANNEL_WIDTH_40,
ntx, RTW89_RS_MCS, ch + 4);
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_80m[0], RTW89_CHANNEL_WIDTH_80,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_80m[0], band,
+ RTW89_CHANNEL_WIDTH_80,
ntx, RTW89_RS_MCS, ch);

- __fill_txpwr_limit_nonbf_bf(val_0p5_n, RTW89_CHANNEL_WIDTH_40,
+ __fill_txpwr_limit_nonbf_bf(val_0p5_n, band, RTW89_CHANNEL_WIDTH_40,
ntx, RTW89_RS_MCS, ch - 4);
- __fill_txpwr_limit_nonbf_bf(val_0p5_p, RTW89_CHANNEL_WIDTH_40,
+ __fill_txpwr_limit_nonbf_bf(val_0p5_p, band, RTW89_CHANNEL_WIDTH_40,
ntx, RTW89_RS_MCS, ch + 4);

for (i = 0; i < RTW89_BF_NUM; i++)
@@ -1660,7 +1668,7 @@ static void rtw89_phy_fill_txpwr_limit_80m(struct rtw89_dev *rtwdev,

static void rtw89_phy_fill_txpwr_limit_160m(struct rtw89_dev *rtwdev,
struct rtw89_txpwr_limit *lmt,
- u8 ntx, u8 ch, u8 pri_ch)
+ u8 band, u8 ntx, u8 ch, u8 pri_ch)
{
s8 val_0p5_n[RTW89_BF_NUM];
s8 val_0p5_p[RTW89_BF_NUM];
@@ -1669,60 +1677,75 @@ static void rtw89_phy_fill_txpwr_limit_160m(struct rtw89_dev *rtwdev,
u8 i;

/* fill ofdm section */
- __fill_txpwr_limit_nonbf_bf(lmt->ofdm, RTW89_CHANNEL_WIDTH_20,
+ __fill_txpwr_limit_nonbf_bf(lmt->ofdm, band, RTW89_CHANNEL_WIDTH_20,
ntx, RTW89_RS_OFDM, pri_ch);

/* fill mcs 20m section */
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], RTW89_CHANNEL_WIDTH_20,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], band,
+ RTW89_CHANNEL_WIDTH_20,
ntx, RTW89_RS_MCS, ch - 14);
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[1], RTW89_CHANNEL_WIDTH_20,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[1], band,
+ RTW89_CHANNEL_WIDTH_20,
ntx, RTW89_RS_MCS, ch - 10);
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[2], RTW89_CHANNEL_WIDTH_20,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[2], band,
+ RTW89_CHANNEL_WIDTH_20,
ntx, RTW89_RS_MCS, ch - 6);
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[3], RTW89_CHANNEL_WIDTH_20,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[3], band,
+ RTW89_CHANNEL_WIDTH_20,
ntx, RTW89_RS_MCS, ch - 2);
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[4], RTW89_CHANNEL_WIDTH_20,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[4], band,
+ RTW89_CHANNEL_WIDTH_20,
ntx, RTW89_RS_MCS, ch + 2);
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[5], RTW89_CHANNEL_WIDTH_20,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[5], band,
+ RTW89_CHANNEL_WIDTH_20,
ntx, RTW89_RS_MCS, ch + 6);
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[6], RTW89_CHANNEL_WIDTH_20,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[6], band,
+ RTW89_CHANNEL_WIDTH_20,
ntx, RTW89_RS_MCS, ch + 10);
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[7], RTW89_CHANNEL_WIDTH_20,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[7], band,
+ RTW89_CHANNEL_WIDTH_20,
ntx, RTW89_RS_MCS, ch + 14);

/* fill mcs 40m section */
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[0], RTW89_CHANNEL_WIDTH_40,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[0], band,
+ RTW89_CHANNEL_WIDTH_40,
ntx, RTW89_RS_MCS, ch - 12);
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[1], RTW89_CHANNEL_WIDTH_40,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[1], band,
+ RTW89_CHANNEL_WIDTH_40,
ntx, RTW89_RS_MCS, ch - 4);
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[2], RTW89_CHANNEL_WIDTH_40,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[2], band,
+ RTW89_CHANNEL_WIDTH_40,
ntx, RTW89_RS_MCS, ch + 4);
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[3], RTW89_CHANNEL_WIDTH_40,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[3], band,
+ RTW89_CHANNEL_WIDTH_40,
ntx, RTW89_RS_MCS, ch + 12);

/* fill mcs 80m section */
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_80m[0], RTW89_CHANNEL_WIDTH_80,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_80m[0], band,
+ RTW89_CHANNEL_WIDTH_80,
ntx, RTW89_RS_MCS, ch - 8);
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_80m[1], RTW89_CHANNEL_WIDTH_80,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_80m[1], band,
+ RTW89_CHANNEL_WIDTH_80,
ntx, RTW89_RS_MCS, ch + 8);

/* fill mcs 160m section */
- __fill_txpwr_limit_nonbf_bf(lmt->mcs_160m, RTW89_CHANNEL_WIDTH_160,
+ __fill_txpwr_limit_nonbf_bf(lmt->mcs_160m, band,
+ RTW89_CHANNEL_WIDTH_160,
ntx, RTW89_RS_MCS, ch);

/* fill mcs 40m 0p5 section */
- __fill_txpwr_limit_nonbf_bf(val_0p5_n, RTW89_CHANNEL_WIDTH_40,
+ __fill_txpwr_limit_nonbf_bf(val_0p5_n, band, RTW89_CHANNEL_WIDTH_40,
ntx, RTW89_RS_MCS, ch - 4);
- __fill_txpwr_limit_nonbf_bf(val_0p5_p, RTW89_CHANNEL_WIDTH_40,
+ __fill_txpwr_limit_nonbf_bf(val_0p5_p, band, RTW89_CHANNEL_WIDTH_40,
ntx, RTW89_RS_MCS, ch + 4);

for (i = 0; i < RTW89_BF_NUM; i++)
lmt->mcs_40m_0p5[i] = min_t(s8, val_0p5_n[i], val_0p5_p[i]);

/* fill mcs 40m 2p5 section */
- __fill_txpwr_limit_nonbf_bf(val_2p5_n, RTW89_CHANNEL_WIDTH_40,
+ __fill_txpwr_limit_nonbf_bf(val_2p5_n, band, RTW89_CHANNEL_WIDTH_40,
ntx, RTW89_RS_MCS, ch - 8);
- __fill_txpwr_limit_nonbf_bf(val_2p5_p, RTW89_CHANNEL_WIDTH_40,
+ __fill_txpwr_limit_nonbf_bf(val_2p5_p, band, RTW89_CHANNEL_WIDTH_40,
ntx, RTW89_RS_MCS, ch + 8);

for (i = 0; i < RTW89_BF_NUM; i++)
@@ -1730,10 +1753,11 @@ static void rtw89_phy_fill_txpwr_limit_160m(struct rtw89_dev *rtwdev,
}

void rtw89_phy_fill_txpwr_limit(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
struct rtw89_txpwr_limit *lmt,
u8 ntx)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ u8 band = chan->band_type;
u8 pri_ch = chan->primary_channel;
u8 ch = chan->channel;
u8 bw = chan->band_width;
@@ -1742,27 +1766,28 @@ void rtw89_phy_fill_txpwr_limit(struct rtw89_dev *rtwdev,

switch (bw) {
case RTW89_CHANNEL_WIDTH_20:
- rtw89_phy_fill_txpwr_limit_20m(rtwdev, lmt, ntx, ch);
+ rtw89_phy_fill_txpwr_limit_20m(rtwdev, lmt, band, ntx, ch);
break;
case RTW89_CHANNEL_WIDTH_40:
- rtw89_phy_fill_txpwr_limit_40m(rtwdev, lmt, ntx, ch, pri_ch);
+ rtw89_phy_fill_txpwr_limit_40m(rtwdev, lmt, band, ntx, ch,
+ pri_ch);
break;
case RTW89_CHANNEL_WIDTH_80:
- rtw89_phy_fill_txpwr_limit_80m(rtwdev, lmt, ntx, ch, pri_ch);
+ rtw89_phy_fill_txpwr_limit_80m(rtwdev, lmt, band, ntx, ch,
+ pri_ch);
break;
case RTW89_CHANNEL_WIDTH_160:
- rtw89_phy_fill_txpwr_limit_160m(rtwdev, lmt, ntx, ch, pri_ch);
+ rtw89_phy_fill_txpwr_limit_160m(rtwdev, lmt, band, ntx, ch,
+ pri_ch);
break;
}
}
EXPORT_SYMBOL(rtw89_phy_fill_txpwr_limit);

-static s8 rtw89_phy_read_txpwr_limit_ru(struct rtw89_dev *rtwdev,
+static s8 rtw89_phy_read_txpwr_limit_ru(struct rtw89_dev *rtwdev, u8 band,
u8 ru, u8 ntx, u8 ch)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
- u8 band = chan->band_type;
u8 ch_idx = rtw89_channel_to_idx(rtwdev, band, ch);
u8 regd = rtw89_regd_get(rtwdev, band);
s8 lmt_ru = 0, sar;
@@ -1800,85 +1825,106 @@ static s8 rtw89_phy_read_txpwr_limit_ru(struct rtw89_dev *rtwdev,
static void
rtw89_phy_fill_txpwr_limit_ru_20m(struct rtw89_dev *rtwdev,
struct rtw89_txpwr_limit_ru *lmt_ru,
- u8 ntx, u8 ch)
+ u8 band, u8 ntx, u8 ch)
{
- lmt_ru->ru26[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26,
+ lmt_ru->ru26[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
+ RTW89_RU26,
ntx, ch);
- lmt_ru->ru52[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52,
+ lmt_ru->ru52[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
+ RTW89_RU52,
ntx, ch);
- lmt_ru->ru106[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106,
+ lmt_ru->ru106[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
+ RTW89_RU106,
ntx, ch);
}

static void
rtw89_phy_fill_txpwr_limit_ru_40m(struct rtw89_dev *rtwdev,
struct rtw89_txpwr_limit_ru *lmt_ru,
- u8 ntx, u8 ch)
+ u8 band, u8 ntx, u8 ch)
{
- lmt_ru->ru26[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26,
+ lmt_ru->ru26[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
+ RTW89_RU26,
ntx, ch - 2);
- lmt_ru->ru26[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26,
+ lmt_ru->ru26[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
+ RTW89_RU26,
ntx, ch + 2);
- lmt_ru->ru52[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52,
+ lmt_ru->ru52[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
+ RTW89_RU52,
ntx, ch - 2);
- lmt_ru->ru52[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52,
+ lmt_ru->ru52[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
+ RTW89_RU52,
ntx, ch + 2);
- lmt_ru->ru106[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106,
+ lmt_ru->ru106[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
+ RTW89_RU106,
ntx, ch - 2);
- lmt_ru->ru106[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106,
+ lmt_ru->ru106[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
+ RTW89_RU106,
ntx, ch + 2);
}

static void
rtw89_phy_fill_txpwr_limit_ru_80m(struct rtw89_dev *rtwdev,
struct rtw89_txpwr_limit_ru *lmt_ru,
- u8 ntx, u8 ch)
+ u8 band, u8 ntx, u8 ch)
{
- lmt_ru->ru26[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26,
+ lmt_ru->ru26[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
+ RTW89_RU26,
ntx, ch - 6);
- lmt_ru->ru26[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26,
+ lmt_ru->ru26[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
+ RTW89_RU26,
ntx, ch - 2);
- lmt_ru->ru26[2] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26,
+ lmt_ru->ru26[2] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
+ RTW89_RU26,
ntx, ch + 2);
- lmt_ru->ru26[3] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26,
+ lmt_ru->ru26[3] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
+ RTW89_RU26,
ntx, ch + 6);
- lmt_ru->ru52[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52,
+ lmt_ru->ru52[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
+ RTW89_RU52,
ntx, ch - 6);
- lmt_ru->ru52[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52,
+ lmt_ru->ru52[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
+ RTW89_RU52,
ntx, ch - 2);
- lmt_ru->ru52[2] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52,
+ lmt_ru->ru52[2] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
+ RTW89_RU52,
ntx, ch + 2);
- lmt_ru->ru52[3] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52,
+ lmt_ru->ru52[3] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
+ RTW89_RU52,
ntx, ch + 6);
- lmt_ru->ru106[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106,
+ lmt_ru->ru106[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
+ RTW89_RU106,
ntx, ch - 6);
- lmt_ru->ru106[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106,
+ lmt_ru->ru106[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
+ RTW89_RU106,
ntx, ch - 2);
- lmt_ru->ru106[2] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106,
+ lmt_ru->ru106[2] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
+ RTW89_RU106,
ntx, ch + 2);
- lmt_ru->ru106[3] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106,
+ lmt_ru->ru106[3] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
+ RTW89_RU106,
ntx, ch + 6);
}

static void
rtw89_phy_fill_txpwr_limit_ru_160m(struct rtw89_dev *rtwdev,
struct rtw89_txpwr_limit_ru *lmt_ru,
- u8 ntx, u8 ch)
+ u8 band, u8 ntx, u8 ch)
{
static const int ofst[] = { -14, -10, -6, -2, 2, 6, 10, 14 };
int i;

static_assert(ARRAY_SIZE(ofst) == RTW89_RU_SEC_NUM);
for (i = 0; i < RTW89_RU_SEC_NUM; i++) {
- lmt_ru->ru26[i] = rtw89_phy_read_txpwr_limit_ru(rtwdev,
+ lmt_ru->ru26[i] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
RTW89_RU26,
ntx,
ch + ofst[i]);
- lmt_ru->ru52[i] = rtw89_phy_read_txpwr_limit_ru(rtwdev,
+ lmt_ru->ru52[i] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
RTW89_RU52,
ntx,
ch + ofst[i]);
- lmt_ru->ru106[i] = rtw89_phy_read_txpwr_limit_ru(rtwdev,
+ lmt_ru->ru106[i] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
RTW89_RU106,
ntx,
ch + ofst[i]);
@@ -1886,10 +1932,11 @@ rtw89_phy_fill_txpwr_limit_ru_160m(struct rtw89_dev *rtwdev,
}

void rtw89_phy_fill_txpwr_limit_ru(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
struct rtw89_txpwr_limit_ru *lmt_ru,
u8 ntx)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ u8 band = chan->band_type;
u8 ch = chan->channel;
u8 bw = chan->band_width;

@@ -1897,16 +1944,20 @@ void rtw89_phy_fill_txpwr_limit_ru(struct rtw89_dev *rtwdev,

switch (bw) {
case RTW89_CHANNEL_WIDTH_20:
- rtw89_phy_fill_txpwr_limit_ru_20m(rtwdev, lmt_ru, ntx, ch);
+ rtw89_phy_fill_txpwr_limit_ru_20m(rtwdev, lmt_ru, band, ntx,
+ ch);
break;
case RTW89_CHANNEL_WIDTH_40:
- rtw89_phy_fill_txpwr_limit_ru_40m(rtwdev, lmt_ru, ntx, ch);
+ rtw89_phy_fill_txpwr_limit_ru_40m(rtwdev, lmt_ru, band, ntx,
+ ch);
break;
case RTW89_CHANNEL_WIDTH_80:
- rtw89_phy_fill_txpwr_limit_ru_80m(rtwdev, lmt_ru, ntx, ch);
+ rtw89_phy_fill_txpwr_limit_ru_80m(rtwdev, lmt_ru, band, ntx,
+ ch);
break;
case RTW89_CHANNEL_WIDTH_160:
- rtw89_phy_fill_txpwr_limit_ru_160m(rtwdev, lmt_ru, ntx, ch);
+ rtw89_phy_fill_txpwr_limit_ru_160m(rtwdev, lmt_ru, band, ntx,
+ ch);
break;
}
}
diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h
index d1f6e38a98ce3..e48d387d33afb 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.h
+++ b/drivers/net/wireless/realtek/rtw89/phy.h
@@ -460,15 +460,17 @@ void rtw89_phy_write32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
u32 data, enum rtw89_phy_idx phy_idx);
void rtw89_phy_load_txpwr_byrate(struct rtw89_dev *rtwdev,
const struct rtw89_txpwr_table *tbl);
-s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev,
+s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev, u8 band,
const struct rtw89_rate_desc *rate_desc);
void rtw89_phy_fill_txpwr_limit(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
struct rtw89_txpwr_limit *lmt,
u8 ntx);
void rtw89_phy_fill_txpwr_limit_ru(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
struct rtw89_txpwr_limit_ru *lmt_ru,
u8 ntx);
-s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev,
+s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, u8 band,
u8 bw, u8 ntx, u8 rs, u8 bf, u8 ch);
void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta);
void rtw89_phy_ra_update(struct rtw89_dev *rtwdev);
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
index ef200d32eab33..06e2c8205eeda 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
@@ -1379,9 +1379,10 @@ static void rtw8852a_set_txpwr_ref(struct rtw89_dev *rtwdev,
}

static void rtw8852a_set_txpwr_byrate(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ u8 band = chan->band_type;
u8 ch = chan->channel;
static const u8 rs[] = {
RTW89_RS_CCK,
@@ -1408,7 +1409,8 @@ static void rtw8852a_set_txpwr_byrate(struct rtw89_dev *rtwdev,
for (j = 0; j < rtw89_rs_idx_max[rs[i]]; j++) {
cur.idx = j;
shf = (j % 4) * 8;
- tmp = rtw89_phy_read_txpwr_byrate(rtwdev, &cur);
+ tmp = rtw89_phy_read_txpwr_byrate(rtwdev, band,
+ &cur);
val |= (tmp << shf);

if ((j + 1) % 4)
@@ -1423,8 +1425,10 @@ static void rtw8852a_set_txpwr_byrate(struct rtw89_dev *rtwdev,
}

static void rtw8852a_set_txpwr_offset(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
+ u8 band = chan->band_type;
struct rtw89_rate_desc desc = {
.nss = RTW89_NSS_1,
.rs = RTW89_RS_OFFSET,
@@ -1435,7 +1439,7 @@ static void rtw8852a_set_txpwr_offset(struct rtw89_dev *rtwdev,
rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr offset\n");

for (desc.idx = 0; desc.idx < RTW89_RATE_OFFSET_MAX; desc.idx++) {
- v = rtw89_phy_read_txpwr_byrate(rtwdev, &desc);
+ v = rtw89_phy_read_txpwr_byrate(rtwdev, band, &desc);
val |= ((v & 0xf) << (4 * desc.idx));
}

@@ -1444,10 +1448,10 @@ static void rtw8852a_set_txpwr_offset(struct rtw89_dev *rtwdev,
}

static void rtw8852a_set_txpwr_limit(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
#define __MAC_TXPWR_LMT_PAGE_SIZE 40
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 ch = chan->channel;
u8 bw = chan->band_width;
struct rtw89_txpwr_limit lmt[NTX_NUM_8852A];
@@ -1459,7 +1463,7 @@ static void rtw8852a_set_txpwr_limit(struct rtw89_dev *rtwdev,
"[TXPWR] set txpwr limit with ch=%d bw=%d\n", ch, bw);

for (i = 0; i < NTX_NUM_8852A; i++) {
- rtw89_phy_fill_txpwr_limit(rtwdev, &lmt[i], i);
+ rtw89_phy_fill_txpwr_limit(rtwdev, chan, &lmt[i], i);

for (j = 0; j < __MAC_TXPWR_LMT_PAGE_SIZE; j += 4) {
addr = R_AX_PWR_LMT + j + __MAC_TXPWR_LMT_PAGE_SIZE * i;
@@ -1476,10 +1480,10 @@ static void rtw8852a_set_txpwr_limit(struct rtw89_dev *rtwdev,
}

static void rtw8852a_set_txpwr_limit_ru(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
#define __MAC_TXPWR_LMT_RU_PAGE_SIZE 24
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 ch = chan->channel;
u8 bw = chan->band_width;
struct rtw89_txpwr_limit_ru lmt_ru[NTX_NUM_8852A];
@@ -1491,7 +1495,7 @@ static void rtw8852a_set_txpwr_limit_ru(struct rtw89_dev *rtwdev,
"[TXPWR] set txpwr limit ru with ch=%d bw=%d\n", ch, bw);

for (i = 0; i < NTX_NUM_8852A; i++) {
- rtw89_phy_fill_txpwr_limit_ru(rtwdev, &lmt_ru[i], i);
+ rtw89_phy_fill_txpwr_limit_ru(rtwdev, chan, &lmt_ru[i], i);

for (j = 0; j < __MAC_TXPWR_LMT_RU_PAGE_SIZE; j += 4) {
addr = R_AX_PWR_RU_LMT + j +
@@ -1509,17 +1513,20 @@ static void rtw8852a_set_txpwr_limit_ru(struct rtw89_dev *rtwdev,
#undef __MAC_TXPWR_LMT_RU_PAGE_SIZE
}

-static void rtw8852a_set_txpwr(struct rtw89_dev *rtwdev)
+static void rtw8852a_set_txpwr(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
+ enum rtw89_phy_idx phy_idx)
{
- rtw8852a_set_txpwr_byrate(rtwdev, RTW89_PHY_0);
- rtw8852a_set_txpwr_limit(rtwdev, RTW89_PHY_0);
- rtw8852a_set_txpwr_limit_ru(rtwdev, RTW89_PHY_0);
+ rtw8852a_set_txpwr_byrate(rtwdev, chan, phy_idx);
+ rtw8852a_set_txpwr_offset(rtwdev, chan, phy_idx);
+ rtw8852a_set_txpwr_limit(rtwdev, chan, phy_idx);
+ rtw8852a_set_txpwr_limit_ru(rtwdev, chan, phy_idx);
}

-static void rtw8852a_set_txpwr_ctrl(struct rtw89_dev *rtwdev)
+static void rtw8852a_set_txpwr_ctrl(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx)
{
- rtw8852a_set_txpwr_ref(rtwdev, RTW89_PHY_0);
- rtw8852a_set_txpwr_offset(rtwdev, RTW89_PHY_0);
+ rtw8852a_set_txpwr_ref(rtwdev, phy_idx);
}

static int
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c
index 32744201241ec..582ff0d3a9ea0 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c
@@ -3491,6 +3491,7 @@ static void _tssi_high_power(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 ch = chan->channel, ch_tmp;
u8 bw = chan->band_width;
+ u8 band = chan->band_type;
u8 subband = chan->subband_type;
s8 power;
s32 xdbm;
@@ -3502,7 +3503,7 @@ static void _tssi_high_power(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
else
ch_tmp = ch;

- power = rtw89_phy_read_txpwr_limit(rtwdev, bw, RTW89_1TX,
+ power = rtw89_phy_read_txpwr_limit(rtwdev, band, bw, RTW89_1TX,
RTW89_RS_MCS, RTW89_NONBF, ch_tmp);

xdbm = power * 100 / 4;
@@ -3538,6 +3539,7 @@ static void _tssi_pre_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
const struct rtw89_chip_info *mac_reg = rtwdev->chip;
u8 ch = chan->channel, ch_tmp;
u8 bw = chan->band_width;
+ u8 band = chan->band_type;
u32 tx_en;
u8 phy_map = rtw89_btc_phymap(rtwdev, phy, 0);
s8 power;
@@ -3551,8 +3553,9 @@ static void _tssi_pre_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
else
ch_tmp = ch;

- power = rtw89_phy_read_txpwr_limit(rtwdev, RTW89_CHANNEL_WIDTH_20, RTW89_1TX,
- RTW89_RS_OFDM, RTW89_NONBF, ch_tmp);
+ power = rtw89_phy_read_txpwr_limit(rtwdev, band, RTW89_CHANNEL_WIDTH_20,
+ RTW89_1TX, RTW89_RS_OFDM,
+ RTW89_NONBF, ch_tmp);

xdbm = (power * 100) >> mac_reg->txpwr_factor_mac;

diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
index b81aec0630969..1625089d83408 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
@@ -1962,9 +1962,10 @@ static void rtw8852c_set_txpwr_ref(struct rtw89_dev *rtwdev,
}

static void rtw8852c_set_txpwr_byrate(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+ u8 band = chan->band_type;
u8 ch = chan->channel;
static const u8 rs[] = {
RTW89_RS_CCK,
@@ -1991,7 +1992,8 @@ static void rtw8852c_set_txpwr_byrate(struct rtw89_dev *rtwdev,
for (j = 0; j < rtw89_rs_idx_max[rs[i]]; j++) {
cur.idx = j;
shf = (j % 4) * 8;
- tmp = rtw89_phy_read_txpwr_byrate(rtwdev, &cur);
+ tmp = rtw89_phy_read_txpwr_byrate(rtwdev, band,
+ &cur);
val |= (tmp << shf);

if ((j + 1) % 4)
@@ -2006,8 +2008,10 @@ static void rtw8852c_set_txpwr_byrate(struct rtw89_dev *rtwdev,
}

static void rtw8852c_set_txpwr_offset(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
+ u8 band = chan->band_type;
struct rtw89_rate_desc desc = {
.nss = RTW89_NSS_1,
.rs = RTW89_RS_OFFSET,
@@ -2018,7 +2022,7 @@ static void rtw8852c_set_txpwr_offset(struct rtw89_dev *rtwdev,
rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr offset\n");

for (desc.idx = 0; desc.idx < RTW89_RATE_OFFSET_MAX; desc.idx++) {
- v = rtw89_phy_read_txpwr_byrate(rtwdev, &desc);
+ v = rtw89_phy_read_txpwr_byrate(rtwdev, band, &desc);
val |= ((v & 0xf) << (4 * desc.idx));
}

@@ -2082,9 +2086,9 @@ static void rtw8852c_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev,
}

static void rtw8852c_set_tx_shape(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
- 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);
u8 tx_shape_cck = rtw89_8852c_tx_shape[band][RTW89_RS_CCK][regd];
@@ -2099,10 +2103,10 @@ static void rtw8852c_set_tx_shape(struct rtw89_dev *rtwdev,
}

static void rtw8852c_set_txpwr_limit(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
#define __MAC_TXPWR_LMT_PAGE_SIZE 40
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 ch = chan->channel;
u8 bw = chan->band_width;
struct rtw89_txpwr_limit lmt[NTX_NUM_8852C];
@@ -2114,7 +2118,7 @@ static void rtw8852c_set_txpwr_limit(struct rtw89_dev *rtwdev,
"[TXPWR] set txpwr limit with ch=%d bw=%d\n", ch, bw);

for (i = 0; i < NTX_NUM_8852C; i++) {
- rtw89_phy_fill_txpwr_limit(rtwdev, &lmt[i], i);
+ rtw89_phy_fill_txpwr_limit(rtwdev, chan, &lmt[i], i);

for (j = 0; j < __MAC_TXPWR_LMT_PAGE_SIZE; j += 4) {
addr = R_AX_PWR_LMT + j + __MAC_TXPWR_LMT_PAGE_SIZE * i;
@@ -2131,10 +2135,10 @@ static void rtw8852c_set_txpwr_limit(struct rtw89_dev *rtwdev,
}

static void rtw8852c_set_txpwr_limit_ru(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
#define __MAC_TXPWR_LMT_RU_PAGE_SIZE 24
- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
u8 ch = chan->channel;
u8 bw = chan->band_width;
struct rtw89_txpwr_limit_ru lmt_ru[NTX_NUM_8852C];
@@ -2146,7 +2150,7 @@ static void rtw8852c_set_txpwr_limit_ru(struct rtw89_dev *rtwdev,
"[TXPWR] set txpwr limit ru with ch=%d bw=%d\n", ch, bw);

for (i = 0; i < NTX_NUM_8852C; i++) {
- rtw89_phy_fill_txpwr_limit_ru(rtwdev, &lmt_ru[i], i);
+ rtw89_phy_fill_txpwr_limit_ru(rtwdev, chan, &lmt_ru[i], i);

for (j = 0; j < __MAC_TXPWR_LMT_RU_PAGE_SIZE; j += 4) {
addr = R_AX_PWR_RU_LMT + j +
@@ -2164,18 +2168,21 @@ static void rtw8852c_set_txpwr_limit_ru(struct rtw89_dev *rtwdev,
#undef __MAC_TXPWR_LMT_RU_PAGE_SIZE
}

-static void rtw8852c_set_txpwr(struct rtw89_dev *rtwdev)
+static void rtw8852c_set_txpwr(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan,
+ enum rtw89_phy_idx phy_idx)
{
- rtw8852c_set_txpwr_byrate(rtwdev, RTW89_PHY_0);
- rtw8852c_set_txpwr_offset(rtwdev, RTW89_PHY_0);
- rtw8852c_set_tx_shape(rtwdev, RTW89_PHY_0);
- rtw8852c_set_txpwr_limit(rtwdev, RTW89_PHY_0);
- rtw8852c_set_txpwr_limit_ru(rtwdev, RTW89_PHY_0);
+ rtw8852c_set_txpwr_byrate(rtwdev, chan, phy_idx);
+ rtw8852c_set_txpwr_offset(rtwdev, chan, phy_idx);
+ rtw8852c_set_tx_shape(rtwdev, chan, phy_idx);
+ rtw8852c_set_txpwr_limit(rtwdev, chan, phy_idx);
+ rtw8852c_set_txpwr_limit_ru(rtwdev, chan, phy_idx);
}

-static void rtw8852c_set_txpwr_ctrl(struct rtw89_dev *rtwdev)
+static void rtw8852c_set_txpwr_ctrl(struct rtw89_dev *rtwdev,
+ enum rtw89_phy_idx phy_idx)
{
- rtw8852c_set_txpwr_ref(rtwdev, RTW89_PHY_0);
+ rtw8852c_set_txpwr_ref(rtwdev, phy_idx);
}

static void
--
2.25.1

2022-06-23 04:47:28

by Ping-Ke Shih

[permalink] [raw]
Subject: [PATCH v2 08/13] rtw89: concentrate chandef setting to stack callback

From: Zong-Zhe Yang <[email protected]>

Originally, we didn't support mac80211 chanctx, so it's expected that
ieee80211_hw::conf::chandef would be filled by mac80211. And then, we
could just query it whenever we need the current chandef.

However, we are planing to support mac80211 chanctx. After that, the
above assumption would be broken. So, we adjust a bit ahead to reduce
future works about mac80211 chanctx.

After this, we don't query ieee80211_hw::conf::chandef directly, and
we add a map, entity_map, to HAL to indicate which chandef came from
stack. And it will later be used to recalcate entity mode.

Signed-off-by: Zong-Zhe Yang <[email protected]>
Signed-off-by: Ping-Ke Shih <[email protected]>
---
drivers/net/wireless/realtek/rtw89/chan.c | 20 +++++++++++++++++++
drivers/net/wireless/realtek/rtw89/chan.h | 3 +++
drivers/net/wireless/realtek/rtw89/core.c | 14 +++++++------
drivers/net/wireless/realtek/rtw89/core.h | 12 +++++++++++
drivers/net/wireless/realtek/rtw89/mac80211.c | 6 +++++-
5 files changed, 48 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c
index 0bf27a344d2b4..a9f0133f8089d 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.c
+++ b/drivers/net/wireless/realtek/rtw89/chan.c
@@ -118,3 +118,23 @@ bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev,
*chan = *new;
return band_changed;
}
+
+static void __rtw89_config_entity_chandef(struct rtw89_dev *rtwdev,
+ enum rtw89_sub_entity_idx idx,
+ const struct cfg80211_chan_def *chandef,
+ bool from_stack)
+{
+ struct rtw89_hal *hal = &rtwdev->hal;
+
+ hal->chandef[idx] = *chandef;
+
+ if (from_stack)
+ set_bit(idx, hal->entity_map);
+}
+
+void rtw89_config_entity_chandef(struct rtw89_dev *rtwdev,
+ enum rtw89_sub_entity_idx idx,
+ const struct cfg80211_chan_def *chandef)
+{
+ __rtw89_config_entity_chandef(rtwdev, idx, chandef, true);
+}
diff --git a/drivers/net/wireless/realtek/rtw89/chan.h b/drivers/net/wireless/realtek/rtw89/chan.h
index d39311a3d5baf..b2022bb0afc6a 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.h
+++ b/drivers/net/wireless/realtek/rtw89/chan.h
@@ -26,5 +26,8 @@ void rtw89_chan_create(struct rtw89_chan *chan, u8 center_chan, u8 primary_chan,
bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev,
enum rtw89_sub_entity_idx idx,
const struct rtw89_chan *new);
+void rtw89_config_entity_chandef(struct rtw89_dev *rtwdev,
+ enum rtw89_sub_entity_idx idx,
+ const struct cfg80211_chan_def *chandef);

#endif
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index fb3943c6ee9e2..4c25fef476e01 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -225,7 +225,7 @@ static void rtw89_traffic_stats_accu(struct rtw89_dev *rtwdev,
}
}

-static void rtw89_get_channel_params(struct cfg80211_chan_def *chandef,
+static void rtw89_get_channel_params(const struct cfg80211_chan_def *chandef,
struct rtw89_chan *chan)
{
struct ieee80211_channel *channel = chandef->chan;
@@ -302,7 +302,8 @@ void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev)

void rtw89_set_channel(struct rtw89_dev *rtwdev)
{
- struct ieee80211_hw *hw = rtwdev->hw;
+ const struct cfg80211_chan_def *chandef =
+ rtw89_chandef_get(rtwdev, RTW89_SUB_ENTITY_0);
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_chan chan;
struct rtw89_channel_help_params bak;
@@ -311,7 +312,7 @@ void rtw89_set_channel(struct rtw89_dev *rtwdev)

entity_active = rtw89_get_entity_state(rtwdev);

- rtw89_get_channel_params(&hw->conf.chandef, &chan);
+ rtw89_get_channel_params(chandef, &chan);
if (WARN(chan.channel == 0, "Invalid channel\n"))
return;

@@ -1607,14 +1608,15 @@ static void rtw89_core_update_rx_status(struct rtw89_dev *rtwdev,
struct rtw89_rx_desc_info *desc_info,
struct ieee80211_rx_status *rx_status)
{
- struct ieee80211_hw *hw = rtwdev->hw;
+ 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;

/* currently using single PHY */
- rx_status->freq = hw->conf.chandef.chan->center_freq;
- rx_status->band = hw->conf.chandef.chan->band;
+ rx_status->freq = chandef->chan->center_freq;
+ rx_status->band = chandef->chan->band;

if (rtwdev->scanning &&
RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) {
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 7de9e228c6187..f8027b9a36a0c 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -2634,6 +2634,9 @@ struct rtw89_hal {
bool support_cckpd;
bool support_igi;

+ DECLARE_BITMAP(entity_map, NUM_OF_RTW89_SUB_ENTITY);
+ struct cfg80211_chan_def chandef[NUM_OF_RTW89_SUB_ENTITY];
+
bool entity_active;

struct rtw89_chan chan[NUM_OF_RTW89_SUB_ENTITY];
@@ -3629,6 +3632,15 @@ void rtw89_chip_set_channel_done(struct rtw89_dev *rtwdev,
mac_idx, phy_idx);
}

+static inline
+const struct cfg80211_chan_def *rtw89_chandef_get(struct rtw89_dev *rtwdev,
+ enum rtw89_sub_entity_idx idx)
+{
+ struct rtw89_hal *hal = &rtwdev->hal;
+
+ return &hal->chandef[idx];
+}
+
static inline
const struct rtw89_chan *rtw89_chan_get(struct rtw89_dev *rtwdev,
enum rtw89_sub_entity_idx idx)
diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
index 95ff4bafe5424..2bfd570d7bd2e 100644
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
@@ -3,6 +3,7 @@
*/

#include "cam.h"
+#include "chan.h"
#include "coex.h"
#include "debug.h"
#include "fw.h"
@@ -85,8 +86,11 @@ static int rtw89_ops_config(struct ieee80211_hw *hw, u32 changed)
}
}

- if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
+ if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+ rtw89_config_entity_chandef(rtwdev, RTW89_SUB_ENTITY_0,
+ &hw->conf.chandef);
rtw89_set_channel(rtwdev);
+ }

if ((changed & IEEE80211_CONF_CHANGE_IDLE) &&
(hw->conf.flags & IEEE80211_CONF_IDLE))
--
2.25.1