Skip to content

Commit

Permalink
wifi: rtw89: use frequency domain RSSI
Browse files Browse the repository at this point in the history
To get more accurate RSSI, this commit includes frequency domain RSSI
info in RSSI calculation. Add correspond physts parsing and macro to
get frequency domain RSSI information for supported IC.

Signed-off-by: Eric Huang <[email protected]>
Signed-off-by: Ping-Ke Shih <[email protected]>
Link: https://patch.msgid.link/[email protected]
(cherry picked from commit c9ac071e30ba4f2e770a0705564790502a7b931f)
  • Loading branch information
Eric Huang authored and opsiff committed Nov 7, 2024
1 parent 6334b37 commit 1e40d46
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 2 deletions.
73 changes: 72 additions & 1 deletion drivers/net/wireless/realtek/rtw89/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1554,11 +1554,27 @@ static u16 rtw89_core_get_phy_status_ie_len(struct rtw89_dev *rtwdev,
return ie_len;
}

static void rtw89_core_parse_phy_status_ie01_v2(struct rtw89_dev *rtwdev,
const struct rtw89_phy_sts_iehdr *iehdr,
struct rtw89_rx_phy_ppdu *phy_ppdu)
{
const struct rtw89_phy_sts_ie01_v2 *ie;
u8 *rpl_fd = phy_ppdu->rpl_fd;

ie = (const struct rtw89_phy_sts_ie01_v2 *)iehdr;
rpl_fd[RF_PATH_A] = le32_get_bits(ie->w8, RTW89_PHY_STS_IE01_V2_W8_RPL_FD_A);
rpl_fd[RF_PATH_B] = le32_get_bits(ie->w8, RTW89_PHY_STS_IE01_V2_W8_RPL_FD_B);
rpl_fd[RF_PATH_C] = le32_get_bits(ie->w9, RTW89_PHY_STS_IE01_V2_W9_RPL_FD_C);
rpl_fd[RF_PATH_D] = le32_get_bits(ie->w9, RTW89_PHY_STS_IE01_V2_W9_RPL_FD_D);

phy_ppdu->bw_idx = le32_get_bits(ie->w5, RTW89_PHY_STS_IE01_V2_W5_BW_IDX);
}

static void rtw89_core_parse_phy_status_ie01(struct rtw89_dev *rtwdev,
const struct rtw89_phy_sts_iehdr *iehdr,
struct rtw89_rx_phy_ppdu *phy_ppdu)
{
const struct rtw89_phy_sts_ie0 *ie = (const struct rtw89_phy_sts_ie0 *)iehdr;
const struct rtw89_phy_sts_ie01 *ie = (const struct rtw89_phy_sts_ie01 *)iehdr;
s16 cfo;
u32 t;

Expand All @@ -1569,12 +1585,17 @@ static void rtw89_core_parse_phy_status_ie01(struct rtw89_dev *rtwdev,
phy_ppdu->stbc = le32_get_bits(ie->w2, RTW89_PHY_STS_IE01_W2_STBC);
}

if (!phy_ppdu->hdr_2_en)
phy_ppdu->rx_path_en =
le32_get_bits(ie->w0, RTW89_PHY_STS_IE01_W0_RX_PATH_EN);

if (phy_ppdu->rate < RTW89_HW_RATE_OFDM6)
return;

if (!phy_ppdu->to_self)
return;

phy_ppdu->rpl_avg = le32_get_bits(ie->w0, RTW89_PHY_STS_IE01_W0_RSSI_AVG_FD);
phy_ppdu->ofdm.avg_snr = le32_get_bits(ie->w2, RTW89_PHY_STS_IE01_W2_AVG_SNR);
phy_ppdu->ofdm.evm_max = le32_get_bits(ie->w2, RTW89_PHY_STS_IE01_W2_EVM_MAX);
phy_ppdu->ofdm.evm_min = le32_get_bits(ie->w2, RTW89_PHY_STS_IE01_W2_EVM_MIN);
Expand All @@ -1590,6 +1611,39 @@ static void rtw89_core_parse_phy_status_ie01(struct rtw89_dev *rtwdev,
}

rtw89_phy_cfo_parse(rtwdev, cfo, phy_ppdu);

if (rtwdev->chip->chip_gen == RTW89_CHIP_BE)
rtw89_core_parse_phy_status_ie01_v2(rtwdev, iehdr, phy_ppdu);
}

static void rtw89_core_parse_phy_status_ie00(struct rtw89_dev *rtwdev,
const struct rtw89_phy_sts_iehdr *iehdr,
struct rtw89_rx_phy_ppdu *phy_ppdu)
{
const struct rtw89_phy_sts_ie00 *ie = (const struct rtw89_phy_sts_ie00 *)iehdr;
u16 tmp_rpl;

tmp_rpl = le32_get_bits(ie->w0, RTW89_PHY_STS_IE00_W0_RPL);
phy_ppdu->rpl_avg = tmp_rpl >> 1;
}

static void rtw89_core_parse_phy_status_ie00_v2(struct rtw89_dev *rtwdev,
const struct rtw89_phy_sts_iehdr *iehdr,
struct rtw89_rx_phy_ppdu *phy_ppdu)
{
const struct rtw89_phy_sts_ie00_v2 *ie;
u8 *rpl_path = phy_ppdu->rpl_path;
u16 tmp_rpl[RF_PATH_MAX];
u8 i;

ie = (const struct rtw89_phy_sts_ie00_v2 *)iehdr;
tmp_rpl[RF_PATH_A] = le32_get_bits(ie->w4, RTW89_PHY_STS_IE00_V2_W4_RPL_TD_A);
tmp_rpl[RF_PATH_B] = le32_get_bits(ie->w4, RTW89_PHY_STS_IE00_V2_W4_RPL_TD_B);
tmp_rpl[RF_PATH_C] = le32_get_bits(ie->w4, RTW89_PHY_STS_IE00_V2_W4_RPL_TD_C);
tmp_rpl[RF_PATH_D] = le32_get_bits(ie->w5, RTW89_PHY_STS_IE00_V2_W5_RPL_TD_D);

for (i = 0; i < RF_PATH_MAX; i++)
rpl_path[i] = tmp_rpl[i] >> 1;
}

static int rtw89_core_process_phy_status_ie(struct rtw89_dev *rtwdev,
Expand All @@ -1601,6 +1655,11 @@ static int rtw89_core_process_phy_status_ie(struct rtw89_dev *rtwdev,
ie = le32_get_bits(iehdr->w0, RTW89_PHY_STS_IEHDR_TYPE);

switch (ie) {
case RTW89_PHYSTS_IE00_CMN_CCK:
rtw89_core_parse_phy_status_ie00(rtwdev, iehdr, phy_ppdu);
if (rtwdev->chip->chip_gen == RTW89_CHIP_BE)
rtw89_core_parse_phy_status_ie00_v2(rtwdev, iehdr, phy_ppdu);
break;
case RTW89_PHYSTS_IE01_CMN_OFDM:
rtw89_core_parse_phy_status_ie01(rtwdev, iehdr, phy_ppdu);
break;
Expand All @@ -1611,6 +1670,13 @@ static int rtw89_core_process_phy_status_ie(struct rtw89_dev *rtwdev,
return 0;
}

static void rtw89_core_update_phy_ppdu_hdr_v2(struct rtw89_rx_phy_ppdu *phy_ppdu)
{
const struct rtw89_phy_sts_hdr_v2 *hdr = phy_ppdu->buf + PHY_STS_HDR_LEN;

phy_ppdu->rx_path_en = le32_get_bits(hdr->w0, RTW89_PHY_STS_HDR_V2_W0_PATH_EN);
}

static void rtw89_core_update_phy_ppdu(struct rtw89_rx_phy_ppdu *phy_ppdu)
{
const struct rtw89_phy_sts_hdr *hdr = phy_ppdu->buf;
Expand All @@ -1622,6 +1688,10 @@ static void rtw89_core_update_phy_ppdu(struct rtw89_rx_phy_ppdu *phy_ppdu)
rssi[RF_PATH_B] = le32_get_bits(hdr->w1, RTW89_PHY_STS_HDR_W1_RSSI_B);
rssi[RF_PATH_C] = le32_get_bits(hdr->w1, RTW89_PHY_STS_HDR_W1_RSSI_C);
rssi[RF_PATH_D] = le32_get_bits(hdr->w1, RTW89_PHY_STS_HDR_W1_RSSI_D);

phy_ppdu->hdr_2_en = le32_get_bits(hdr->w0, RTW89_PHY_STS_HDR_W0_HDR_2_EN);
if (phy_ppdu->hdr_2_en)
rtw89_core_update_phy_ppdu_hdr_v2(phy_ppdu);
}

static int rtw89_core_rx_process_phy_ppdu(struct rtw89_dev *rtwdev,
Expand Down Expand Up @@ -1674,6 +1744,7 @@ static int rtw89_core_rx_parse_phy_sts(struct rtw89_dev *rtwdev,
}
}

rtw89_chip_convert_rpl_to_rssi(rtwdev, phy_ppdu);
rtw89_phy_antdiv_parse(rtwdev, phy_ppdu);

return 0;
Expand Down
17 changes: 17 additions & 0 deletions drivers/net/wireless/realtek/rtw89/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,11 @@ struct rtw89_rx_phy_ppdu {
u8 chan_idx;
u8 ie;
u16 rate;
u8 rpl_avg;
u8 rpl_path[RF_PATH_MAX];
u8 rpl_fd[RF_PATH_MAX];
u8 bw_idx;
u8 rx_path_en;
struct {
bool has;
u8 avg_snr;
Expand All @@ -856,6 +861,7 @@ struct rtw89_rx_phy_ppdu {
bool stbc;
bool to_self;
bool valid;
bool hdr_2_en;
};

enum rtw89_mac_idx {
Expand Down Expand Up @@ -3597,6 +3603,8 @@ struct rtw89_chip_ops {
void (*query_ppdu)(struct rtw89_dev *rtwdev,
struct rtw89_rx_phy_ppdu *phy_ppdu,
struct ieee80211_rx_status *status);
void (*convert_rpl_to_rssi)(struct rtw89_dev *rtwdev,
struct rtw89_rx_phy_ppdu *phy_ppdu);
void (*ctrl_nbtg_bt_tx)(struct rtw89_dev *rtwdev, bool en,
enum rtw89_phy_idx phy_idx);
void (*cfg_txrx_path)(struct rtw89_dev *rtwdev);
Expand Down Expand Up @@ -6211,6 +6219,15 @@ static inline void rtw89_chip_query_ppdu(struct rtw89_dev *rtwdev,
chip->ops->query_ppdu(rtwdev, phy_ppdu, status);
}

static inline void rtw89_chip_convert_rpl_to_rssi(struct rtw89_dev *rtwdev,
struct rtw89_rx_phy_ppdu *phy_ppdu)
{
const struct rtw89_chip_info *chip = rtwdev->chip;

if (chip->ops->convert_rpl_to_rssi)
chip->ops->convert_rpl_to_rssi(rtwdev, phy_ppdu);
}

static inline void rtw89_ctrl_nbtg_bt_tx(struct rtw89_dev *rtwdev, bool en,
enum rtw89_phy_idx phy_idx)
{
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/realtek/rtw89/rtw8851b.c
Original file line number Diff line number Diff line change
Expand Up @@ -2370,6 +2370,7 @@ static const struct rtw89_chip_ops rtw8851b_chip_ops = {
.get_thermal = rtw8851b_get_thermal,
.ctrl_btg_bt_rx = rtw8851b_ctrl_btg_bt_rx,
.query_ppdu = rtw8851b_query_ppdu,
.convert_rpl_to_rssi = NULL,
.ctrl_nbtg_bt_tx = rtw8851b_ctrl_nbtg_bt_tx,
.cfg_txrx_path = rtw8851b_bb_cfg_txrx_path,
.set_txpwr_ul_tb_offset = rtw8851b_set_txpwr_ul_tb_offset,
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/realtek/rtw89/rtw8852a.c
Original file line number Diff line number Diff line change
Expand Up @@ -2094,6 +2094,7 @@ static const struct rtw89_chip_ops rtw8852a_chip_ops = {
.get_thermal = rtw8852a_get_thermal,
.ctrl_btg_bt_rx = rtw8852a_ctrl_btg_bt_rx,
.query_ppdu = rtw8852a_query_ppdu,
.convert_rpl_to_rssi = NULL,
.ctrl_nbtg_bt_tx = rtw8852a_ctrl_nbtg_bt_tx,
.cfg_txrx_path = NULL,
.set_txpwr_ul_tb_offset = rtw8852a_set_txpwr_ul_tb_offset,
Expand Down
15 changes: 15 additions & 0 deletions drivers/net/wireless/realtek/rtw89/rtw8852b.c
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,20 @@ static void rtw8852b_efuse_parsing_gain_offset(struct rtw89_dev *rtwdev,
gain->offset_valid = valid;
}

static inline
void rtw8852bx_convert_rpl_to_rssi(struct rtw89_dev *rtwdev,
struct rtw89_rx_phy_ppdu *phy_ppdu)
{
u8 delta = phy_ppdu->rpl_avg - phy_ppdu->rssi_avg;
u8 *rssi = phy_ppdu->rssi;
u8 i;

for (i = 0; i < RF_PATH_NUM_8852B; i++)
rssi[i] += delta;

phy_ppdu->rssi_avg = phy_ppdu->rpl_avg;
}

static int rtw8852b_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map,
enum rtw89_efuse_block block)
{
Expand Down Expand Up @@ -2531,6 +2545,7 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = {
.get_thermal = rtw8852b_get_thermal,
.ctrl_btg_bt_rx = rtw8852b_ctrl_btg_bt_rx,
.query_ppdu = rtw8852b_query_ppdu,
.convert_rpl_to_rssi = rtw8852bx_convert_rpl_to_rssi,
.ctrl_nbtg_bt_tx = rtw8852b_ctrl_nbtg_bt_tx,
.cfg_txrx_path = rtw8852b_bb_cfg_txrx_path,
.set_txpwr_ul_tb_offset = rtw8852b_set_txpwr_ul_tb_offset,
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/realtek/rtw89/rtw8852c.c
Original file line number Diff line number Diff line change
Expand Up @@ -2864,6 +2864,7 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = {
.get_thermal = rtw8852c_get_thermal,
.ctrl_btg_bt_rx = rtw8852c_ctrl_btg_bt_rx,
.query_ppdu = rtw8852c_query_ppdu,
.convert_rpl_to_rssi = NULL,
.ctrl_nbtg_bt_tx = rtw8852c_ctrl_nbtg_bt_tx,
.cfg_txrx_path = rtw8852c_bb_cfg_txrx_path,
.set_txpwr_ul_tb_offset = rtw8852c_set_txpwr_ul_tb_offset,
Expand Down
33 changes: 33 additions & 0 deletions drivers/net/wireless/realtek/rtw89/rtw8922a.c
Original file line number Diff line number Diff line change
Expand Up @@ -2422,6 +2422,38 @@ static void rtw8922a_query_ppdu(struct rtw89_dev *rtwdev,
rtw8922a_fill_freq_with_ppdu(rtwdev, phy_ppdu, status);
}

static void rtw8922a_convert_rpl_to_rssi(struct rtw89_dev *rtwdev,
struct rtw89_rx_phy_ppdu *phy_ppdu)
{
/* Mapping to BW: 5, 10, 20, 40, 80, 160, 80_80 */
static const u8 bw_compensate[] = {0, 0, 0, 6, 12, 18, 0};
u8 *rssi = phy_ppdu->rssi;
u8 compensate = 0;
u16 rpl_tmp;
u8 i;

if (phy_ppdu->bw_idx < ARRAY_SIZE(bw_compensate))
compensate = bw_compensate[phy_ppdu->bw_idx];

for (i = 0; i < RF_PATH_NUM_8922A; i++) {
if (!(phy_ppdu->rx_path_en & BIT(i))) {
rssi[i] = 0;
phy_ppdu->rpl_path[i] = 0;
phy_ppdu->rpl_fd[i] = 0;
}
if (phy_ppdu->rate >= RTW89_HW_RATE_OFDM6) {
rpl_tmp = phy_ppdu->rpl_fd[i];
if (rpl_tmp)
rpl_tmp += compensate;

phy_ppdu->rpl_path[i] = rpl_tmp;
}
rssi[i] = phy_ppdu->rpl_path[i];
}

phy_ppdu->rssi_avg = phy_ppdu->rpl_avg;
}

static int rtw8922a_mac_enable_bb_rf(struct rtw89_dev *rtwdev)
{
rtw89_write8_set(rtwdev, R_BE_FEN_RST_ENABLE,
Expand Down Expand Up @@ -2477,6 +2509,7 @@ static const struct rtw89_chip_ops rtw8922a_chip_ops = {
.get_thermal = rtw8922a_get_thermal,
.ctrl_btg_bt_rx = rtw8922a_ctrl_btg_bt_rx,
.query_ppdu = rtw8922a_query_ppdu,
.convert_rpl_to_rssi = rtw8922a_convert_rpl_to_rssi,
.ctrl_nbtg_bt_tx = rtw8922a_ctrl_nbtg_bt_tx,
.cfg_txrx_path = rtw8922a_bb_cfg_txrx_path,
.set_txpwr_ul_tb_offset = NULL,
Expand Down
59 changes: 58 additions & 1 deletion drivers/net/wireless/realtek/rtw89/txrx.h
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@ struct rtw89_phy_sts_hdr {
} __packed;

#define RTW89_PHY_STS_HDR_W0_IE_MAP GENMASK(4, 0)
#define RTW89_PHY_STS_HDR_W0_HDR_2_EN BIT(5)
#define RTW89_PHY_STS_HDR_W0_VALID BIT(7)
#define RTW89_PHY_STS_HDR_W0_LEN GENMASK(15, 8)
#define RTW89_PHY_STS_HDR_W0_RSSI_AVG GENMASK(31, 24)
Expand All @@ -443,6 +444,13 @@ struct rtw89_phy_sts_hdr {
#define RTW89_PHY_STS_HDR_W1_RSSI_C GENMASK(23, 16)
#define RTW89_PHY_STS_HDR_W1_RSSI_D GENMASK(31, 24)

struct rtw89_phy_sts_hdr_v2 {
__le32 w0;
__le32 w1;
} __packed;

#define RTW89_PHY_STS_HDR_V2_W0_PATH_EN GENMASK(20, 16)

struct rtw89_phy_sts_iehdr {
__le32 w0;
};
Expand Down Expand Up @@ -546,13 +554,43 @@ struct rtw89_phy_sts_iehdr {
#define BE_RXD_HDR_OFFSET_MASK GENMASK(20, 16)
#define BE_RXD_WL_HD_IV_LEN_MASK GENMASK(26, 21)

struct rtw89_phy_sts_ie0 {
struct rtw89_phy_sts_ie00 {
__le32 w0;
__le32 w1;
__le32 w2;
__le32 w3;
} __packed;

#define RTW89_PHY_STS_IE00_W0_RPL GENMASK(15, 7)

struct rtw89_phy_sts_ie00_v2 {
__le32 w0;
__le32 w1;
__le32 w2;
__le32 w3;
__le32 w4;
__le32 w5;
__le32 w6;
__le32 w7;
} __packed;

#define RTW89_PHY_STS_IE00_V2_W4_RPL_TD_A GENMASK(8, 0)
#define RTW89_PHY_STS_IE00_V2_W4_RPL_TD_B GENMASK(17, 9)
#define RTW89_PHY_STS_IE00_V2_W4_RPL_TD_C GENMASK(26, 18)
#define RTW89_PHY_STS_IE00_V2_W5_RPL_TD_D GENMASK(8, 0)

struct rtw89_phy_sts_ie01 {
__le32 w0;
__le32 w1;
__le32 w2;
__le32 w3;
__le32 w4;
__le32 w5;
} __packed;

#define RTW89_PHY_STS_IE01_W0_CH_IDX GENMASK(23, 16)
#define RTW89_PHY_STS_IE01_W0_RSSI_AVG_FD GENMASK(15, 8)
#define RTW89_PHY_STS_IE01_W0_RX_PATH_EN GENMASK(31, 28)
#define RTW89_PHY_STS_IE01_W1_FD_CFO GENMASK(19, 8)
#define RTW89_PHY_STS_IE01_W1_PREMB_CFO GENMASK(31, 20)
#define RTW89_PHY_STS_IE01_W2_AVG_SNR GENMASK(5, 0)
Expand All @@ -561,6 +599,25 @@ struct rtw89_phy_sts_ie0 {
#define RTW89_PHY_STS_IE01_W2_LDPC BIT(28)
#define RTW89_PHY_STS_IE01_W2_STBC BIT(30)

struct rtw89_phy_sts_ie01_v2 {
__le32 w0;
__le32 w1;
__le32 w2;
__le32 w3;
__le32 w4;
__le32 w5;
__le32 w6;
__le32 w7;
__le32 w8;
__le32 w9;
} __packed;

#define RTW89_PHY_STS_IE01_V2_W5_BW_IDX GENMASK(31, 29)
#define RTW89_PHY_STS_IE01_V2_W8_RPL_FD_A GENMASK(11, 4)
#define RTW89_PHY_STS_IE01_V2_W8_RPL_FD_B GENMASK(23, 16)
#define RTW89_PHY_STS_IE01_V2_W9_RPL_FD_C GENMASK(11, 4)
#define RTW89_PHY_STS_IE01_V2_W9_RPL_FD_D GENMASK(23, 16)

enum rtw89_tx_channel {
RTW89_TXCH_ACH0 = 0,
RTW89_TXCH_ACH1 = 1,
Expand Down

0 comments on commit 1e40d46

Please sign in to comment.