2020-04-23 12:31:16

by Tony Chuang

[permalink] [raw]
Subject: [PATCH v2 0/8] rtw88: 8723d: add BB related routines

From: Yan-Hsuan Chuang <[email protected]>

Add BB related routines for 8723D.
The BB controls the channel, RX decoding, and RX gain. So, add DIG
parameters and RX descriptor parsing for the RX frames. And the false
alarm statistics help the driver to choose better DIG values.
The 8723D devices have more settings for CCK rates for DIG, mostly
because that the 8723D is 802.11n device.

The 8723D devices cannot recieve LDPC frames, do not advertise it.


v1 -> v2
* make a patchset contains less patches for review


Ping-Ke Shih (8):
rtw88: 8723d: Add DIG parameter
rtw88: 8723d: Add query_rx_desc
rtw88: 8723d: Add set_channel
rtw88: handle C2H_CCX_TX_RPT to know if packet TX'ed successfully
rtw88: 8723d: 11N chips don't support LDPC
rtw88: 8723d: Add chip_ops::false_alarm_statistics
rtw88: 8723d: Set IG register for CCK rate
rtw88: 8723d: add interface configurations table

drivers/net/wireless/realtek/rtw88/fw.c | 6 +-
drivers/net/wireless/realtek/rtw88/fw.h | 7 +-
drivers/net/wireless/realtek/rtw88/mac.c | 3 +
drivers/net/wireless/realtek/rtw88/main.c | 2 +-
drivers/net/wireless/realtek/rtw88/main.h | 1 +
drivers/net/wireless/realtek/rtw88/phy.c | 4 +
drivers/net/wireless/realtek/rtw88/rtw8723d.c | 399 ++++++++++++++++++
drivers/net/wireless/realtek/rtw88/rtw8723d.h | 75 ++++
drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 +
drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 +
drivers/net/wireless/realtek/rtw88/tx.c | 11 +-
drivers/net/wireless/realtek/rtw88/tx.h | 2 +-
12 files changed, 504 insertions(+), 8 deletions(-)

--
2.17.1


2020-04-23 12:31:16

by Tony Chuang

[permalink] [raw]
Subject: [PATCH v2 7/8] rtw88: 8723d: Set IG register for CCK rate

From: Ping-Ke Shih <[email protected]>

DIG sets only one IG register for most chips, but 8723D need to set
additional register for CCK rate.

Signed-off-by: Ping-Ke Shih <[email protected]>
Signed-off-by: Yan-Hsuan Chuang <[email protected]>
---
drivers/net/wireless/realtek/rtw88/main.h | 1 +
drivers/net/wireless/realtek/rtw88/phy.c | 4 ++++
drivers/net/wireless/realtek/rtw88/rtw8723d.c | 5 +++++
drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 +
drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 +
5 files changed, 12 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index 157aca641f6d..d51eeda3627c 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -1099,6 +1099,7 @@ struct rtw_chip_info {
const struct rtw_intf_phy_para_table *intf_table;

const struct rtw_hw_reg *dig;
+ const struct rtw_hw_reg *dig_cck;
u32 rf_base_addr[2];
u32 rf_sipi_addr[2];
const struct rtw_rf_sipi_addr *rf_sipi_read_addr;
diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c
index 8489abfdc12e..72a16eff9db3 100644
--- a/drivers/net/wireless/realtek/rtw88/phy.c
+++ b/drivers/net/wireless/realtek/rtw88/phy.c
@@ -140,9 +140,13 @@ void rtw_phy_dig_write(struct rtw_dev *rtwdev, u8 igi)
{
struct rtw_chip_info *chip = rtwdev->chip;
struct rtw_hal *hal = &rtwdev->hal;
+ const struct rtw_hw_reg *dig_cck = &chip->dig_cck[0];
u32 addr, mask;
u8 path;

+ if (dig_cck)
+ rtw_write32_mask(rtwdev, dig_cck->addr, dig_cck->mask, igi >> 1);
+
for (path = 0; path < hal->rf_path_num; path++) {
addr = chip->dig[path].addr;
mask = chip->dig[path].mask;
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
index df78d3b4b07a..dd8943426bb3 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
@@ -1077,6 +1077,10 @@ static const struct rtw_hw_reg rtw8723d_dig[] = {
[1] = { .addr = 0xc50, .mask = 0x7f },
};

+static const struct rtw_hw_reg rtw8723d_dig_cck[] = {
+ [0] = { .addr = 0xa0c, .mask = 0x3f00 },
+};
+
static const struct rtw_rf_sipi_addr rtw8723d_rf_sipi_addr[] = {
[RF_PATH_A] = { .hssi_1 = 0x820, .lssi_read = 0x8a0,
.hssi_2 = 0x824, .lssi_read_pi = 0x8b8},
@@ -1119,6 +1123,7 @@ struct rtw_chip_info rtw8723d_hw_spec = {
.page_table = page_table_8723d,
.rqpn_table = rqpn_table_8723d,
.dig = rtw8723d_dig,
+ .dig_cck = rtw8723d_dig_cck,
.rf_sipi_addr = {0x840, 0x844},
.rf_sipi_read_addr = rtw8723d_rf_sipi_addr,
.fix_rf_phy_num = 2,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
index ffee8111d145..51b16a831162 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
@@ -2435,6 +2435,7 @@ struct rtw_chip_info rtw8822b_hw_spec = {
.rqpn_table = rqpn_table_8822b,
.intf_table = &phy_para_table_8822b,
.dig = rtw8822b_dig,
+ .dig_cck = NULL,
.rf_base_addr = {0x2800, 0x2c00},
.rf_sipi_addr = {0xc90, 0xe90},
.mac_tbl = &rtw8822b_mac_tbl,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
index 8dd92136145d..009921c94242 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
@@ -4296,6 +4296,7 @@ struct rtw_chip_info rtw8822c_hw_spec = {
.rqpn_table = rqpn_table_8822c,
.intf_table = &phy_para_table_8822c,
.dig = rtw8822c_dig,
+ .dig_cck = NULL,
.rf_base_addr = {0x3c00, 0x4c00},
.rf_sipi_addr = {0x1808, 0x4108},
.mac_tbl = &rtw8822c_mac_tbl,
--
2.17.1

2020-04-23 12:31:19

by Tony Chuang

[permalink] [raw]
Subject: [PATCH v2 6/8] rtw88: 8723d: Add chip_ops::false_alarm_statistics

From: Ping-Ke Shih <[email protected]>

This ops is used to do statistics of false alarm periodically, and then
fine tune RX initial gain to adaptive different circumstance.

There are three steps, hold/get/reset counter, to retrieve false alarm
counters that consist of CCK and OFDM. In addition to false alarm
counters, it also collects CRC ok/error counters of CCK, OFDM and HT.

Signed-off-by: Ping-Ke Shih <[email protected]>
Signed-off-by: Yan-Hsuan Chuang <[email protected]>
---
drivers/net/wireless/realtek/rtw88/rtw8723d.c | 65 +++++++++++++++++++
drivers/net/wireless/realtek/rtw88/rtw8723d.h | 41 ++++++++++++
2 files changed, 106 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
index c619ee289561..df78d3b4b07a 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
@@ -563,6 +563,70 @@ static void rtw8723d_efuse_grant(struct rtw_dev *rtwdev, bool on)
}
}

+static void rtw8723d_false_alarm_statistics(struct rtw_dev *rtwdev)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ u32 cck_fa_cnt;
+ u32 ofdm_fa_cnt;
+ u32 crc32_cnt;
+ u32 val32;
+
+ /* hold counter */
+ rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 1);
+ rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 1);
+ rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KEEP, 1);
+ rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KEEP, 1);
+
+ cck_fa_cnt = rtw_read32_mask(rtwdev, REG_CCK_FA_LSB_11N, MASKBYTE0);
+ cck_fa_cnt += rtw_read32_mask(rtwdev, REG_CCK_FA_MSB_11N, MASKBYTE3) << 8;
+
+ val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE1_11N);
+ ofdm_fa_cnt = u32_get_bits(val32, BIT_MASK_OFDM_FF_CNT);
+ ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_SF_CNT);
+ val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE2_11N);
+ dm_info->ofdm_cca_cnt = u32_get_bits(val32, BIT_MASK_OFDM_CCA_CNT);
+ ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_PF_CNT);
+ val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE3_11N);
+ ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_RI_CNT);
+ ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_CRC_CNT);
+ val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE4_11N);
+ ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_MNS_CNT);
+
+ dm_info->cck_fa_cnt = cck_fa_cnt;
+ dm_info->ofdm_fa_cnt = ofdm_fa_cnt;
+ dm_info->total_fa_cnt = cck_fa_cnt + ofdm_fa_cnt;
+
+ dm_info->cck_err_cnt = rtw_read32(rtwdev, REG_IGI_C_11N);
+ dm_info->cck_ok_cnt = rtw_read32(rtwdev, REG_IGI_D_11N);
+ crc32_cnt = rtw_read32(rtwdev, REG_OFDM_CRC32_CNT_11N);
+ dm_info->ofdm_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_ERR);
+ dm_info->ofdm_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_OK);
+ crc32_cnt = rtw_read32(rtwdev, REG_HT_CRC32_CNT_11N);
+ dm_info->ht_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_ERR);
+ dm_info->ht_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_OK);
+ dm_info->vht_err_cnt = 0;
+ dm_info->vht_ok_cnt = 0;
+
+ val32 = rtw_read32(rtwdev, REG_CCK_CCA_CNT_11N);
+ dm_info->cck_cca_cnt = (u32_get_bits(val32, BIT_MASK_CCK_FA_MSB) << 8) |
+ u32_get_bits(val32, BIT_MASK_CCK_FA_LSB);
+ dm_info->total_cca_cnt = dm_info->cck_cca_cnt + dm_info->ofdm_cca_cnt;
+
+ /* reset counter */
+ rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 1);
+ rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 0);
+ rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 1);
+ rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 0);
+ rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 0);
+ rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 0);
+ rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 0);
+ rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 2);
+ rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 0);
+ rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 2);
+ rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 1);
+ rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 0);
+}
+
static struct rtw_chip_ops rtw8723d_ops = {
.phy_set_param = rtw8723d_phy_set_param,
.read_efuse = rtw8723d_read_efuse,
@@ -575,6 +639,7 @@ static struct rtw_chip_ops rtw8723d_ops = {
.set_antenna = NULL,
.cfg_ldo25 = rtw8723d_cfg_ldo25,
.efuse_grant = rtw8723d_efuse_grant,
+ .false_alarm_statistics = rtw8723d_false_alarm_statistics,
.config_bfee = NULL,
.set_gid_table = NULL,
.cfg_csi_rate = NULL,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.h b/drivers/net/wireless/realtek/rtw88/rtw8723d.h
index c08c351ba657..b5b7fc9cd1c8 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.h
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.h
@@ -72,13 +72,54 @@ struct rtw8723d_efuse {
#define REG_FPGA1_RFMOD 0x0900
#define REG_BBRX_DFIR 0x0954
#define REG_CCK0_SYS 0x0a00
+#define REG_CCK_FA_RST_11N 0x0a2c
+#define BIT_MASK_CCK_CNT_KEEP BIT(12)
+#define BIT_MASK_CCK_CNT_EN BIT(13)
+#define BIT_MASK_CCK_CNT_KPEN (BIT_MASK_CCK_CNT_KEEP | BIT_MASK_CCK_CNT_EN)
+#define BIT_MASK_CCK_FA_KEEP BIT(14)
+#define BIT_MASK_CCK_FA_EN BIT(15)
+#define BIT_MASK_CCK_FA_KPEN (BIT_MASK_CCK_FA_KEEP | BIT_MASK_CCK_FA_EN)
+#define REG_CCK_FA_LSB_11N 0x0a5c
+#define REG_CCK_FA_MSB_11N 0x0a58
+#define REG_CCK_CCA_CNT_11N 0x0a60
+#define BIT_MASK_CCK_FA_MSB GENMASK(7, 0)
+#define BIT_MASK_CCK_FA_LSB GENMASK(15, 8)
+#define REG_OFDM_FA_HOLDC_11N 0x0c00
+#define BIT_MASK_OFDM_FA_KEEP BIT(31)
+#define REG_OFDM_FA_RSTC_11N 0x0c0c
+#define BIT_MASK_OFDM_FA_RST BIT(31)
#define REG_OFDM0_RXDSP 0x0c40
#define REG_OFDM0_XAAGC1 0x0c50
#define REG_OFDM0_XBAGC1 0x0c58
+#define REG_OFDM_FA_TYPE1_11N 0x0cf0
+#define BIT_MASK_OFDM_FF_CNT GENMASK(15, 0)
+#define BIT_MASK_OFDM_SF_CNT GENMASK(31, 16)
+#define REG_OFDM_FA_RSTD_11N 0x0d00
+#define BIT_MASK_OFDM_FA_RST1 BIT(27)
+#define BIT_MASK_OFDM_FA_KEEP1 BIT(31)
#define REG_OFDM1_CFOTRK 0x0d2c
#define REG_OFDM1_CSI1 0x0d40
#define REG_OFDM1_CSI2 0x0d44
#define REG_OFDM1_CSI3 0x0d48
#define REG_OFDM1_CSI4 0x0d4c
+#define REG_OFDM_FA_TYPE2_11N 0x0da0
+#define BIT_MASK_OFDM_CCA_CNT GENMASK(15, 0)
+#define BIT_MASK_OFDM_PF_CNT GENMASK(31, 16)
+#define REG_OFDM_FA_TYPE3_11N 0x0da4
+#define BIT_MASK_OFDM_RI_CNT GENMASK(15, 0)
+#define BIT_MASK_OFDM_CRC_CNT GENMASK(31, 16)
+#define REG_OFDM_FA_TYPE4_11N 0x0da8
+#define BIT_MASK_OFDM_MNS_CNT GENMASK(15, 0)
+#define REG_PAGE_F_RST_11N 0x0f14
+#define BIT_MASK_F_RST_ALL BIT(16)
+#define REG_IGI_C_11N 0x0f84
+#define REG_IGI_D_11N 0x0f88
+#define REG_HT_CRC32_CNT_11N 0x0f90
+#define BIT_MASK_HT_CRC_OK GENMASK(15, 0)
+#define BIT_MASK_HT_CRC_ERR GENMASK(31, 16)
+#define REG_OFDM_CRC32_CNT_11N 0x0f94
+#define BIT_MASK_OFDM_LCRC_OK GENMASK(15, 0)
+#define BIT_MASK_OFDM_LCRC_ERR GENMASK(31, 16)
+#define REG_HT_CRC32_CNT_11N_AGG 0x0fb8

#endif
--
2.17.1

2020-04-23 12:31:31

by Tony Chuang

[permalink] [raw]
Subject: [PATCH v2 5/8] rtw88: 8723d: 11N chips don't support LDPC

From: Ping-Ke Shih <[email protected]>

Since 8723D devices don't support LDPC, tell mac80211 not to advertise
LDPC capability to peer.

Signed-off-by: Ping-Ke Shih <[email protected]>
Signed-off-by: Yan-Hsuan Chuang <[email protected]>
---
drivers/net/wireless/realtek/rtw88/main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index b0dadff0dc7b..21371576a6b2 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -933,7 +933,7 @@ static void rtw_init_ht_cap(struct rtw_dev *rtwdev,
ht_cap->cap = 0;
ht_cap->cap |= IEEE80211_HT_CAP_SGI_20 |
IEEE80211_HT_CAP_MAX_AMSDU |
- IEEE80211_HT_CAP_LDPC_CODING |
+ (rtw_chip_wcpu_11ac(rtwdev) ? IEEE80211_HT_CAP_LDPC_CODING : 0) |
(1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
if (efuse->hw_cap.bw & BIT(RTW_CHANNEL_WIDTH_40))
ht_cap->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
--
2.17.1

2020-04-23 12:31:47

by Tony Chuang

[permalink] [raw]
Subject: [PATCH v2 2/8] rtw88: 8723d: Add query_rx_desc

From: Ping-Ke Shih <[email protected]>

This ops is used to parse RX descriptor to know the length of received
packet and containing PHY status. If PHY status is existing, the order is
RX descriptor, PHY status and then packet.

There are two types of PHY status, named CCK and OFDM. Their size are the
same, but formats are different.

struct ieee80211_rx_status is also filled depends on above information.

Signed-off-by: Ping-Ke Shih <[email protected]>
Signed-off-by: Yan-Hsuan Chuang <[email protected]>
---
drivers/net/wireless/realtek/rtw88/rtw8723d.c | 116 ++++++++++++++++++
drivers/net/wireless/realtek/rtw88/rtw8723d.h | 22 ++++
2 files changed, 138 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
index 52afa72caf8f..653cfa9445fc 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
@@ -172,6 +172,121 @@ static int rtw8723d_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
return 0;
}

+static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status,
+ struct rtw_rx_pkt_stat *pkt_stat)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ s8 min_rx_power = -120;
+ u8 pwdb = GET_PHY_STAT_P0_PWDB(phy_status);
+
+ pkt_stat->rx_power[RF_PATH_A] = pwdb - 97;
+ pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1);
+ pkt_stat->bw = RTW_CHANNEL_WIDTH_20;
+ pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A],
+ min_rx_power);
+ dm_info->rssi[RF_PATH_A] = pkt_stat->rssi;
+}
+
+static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status,
+ struct rtw_rx_pkt_stat *pkt_stat)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ u8 rxsc, bw;
+ s8 min_rx_power = -120;
+ s8 rx_evm;
+
+ if (pkt_stat->rate > DESC_RATE11M && pkt_stat->rate < DESC_RATEMCS0)
+ rxsc = GET_PHY_STAT_P1_L_RXSC(phy_status);
+ else
+ rxsc = GET_PHY_STAT_P1_HT_RXSC(phy_status);
+
+ if (GET_PHY_STAT_P1_RF_MODE(phy_status) == 0)
+ bw = RTW_CHANNEL_WIDTH_20;
+ else if ((rxsc == 1) || (rxsc == 2))
+ bw = RTW_CHANNEL_WIDTH_20;
+ else
+ bw = RTW_CHANNEL_WIDTH_40;
+
+ pkt_stat->rx_power[RF_PATH_A] = GET_PHY_STAT_P1_PWDB_A(phy_status) - 110;
+ pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1);
+ pkt_stat->bw = bw;
+ pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A],
+ min_rx_power);
+ pkt_stat->rx_evm[RF_PATH_A] = GET_PHY_STAT_P1_RXEVM_A(phy_status);
+ pkt_stat->rx_snr[RF_PATH_A] = GET_PHY_STAT_P1_RXSNR_A(phy_status);
+ pkt_stat->cfo_tail[RF_PATH_A] = GET_PHY_STAT_P1_CFO_TAIL_A(phy_status);
+
+ dm_info->curr_rx_rate = pkt_stat->rate;
+ dm_info->rssi[RF_PATH_A] = pkt_stat->rssi;
+ dm_info->rx_snr[RF_PATH_A] = pkt_stat->rx_snr[RF_PATH_A] >> 1;
+ dm_info->cfo_tail[RF_PATH_A] = (pkt_stat->cfo_tail[RF_PATH_A] * 5) >> 1;
+
+ rx_evm = clamp_t(s8, -pkt_stat->rx_evm[RF_PATH_A] >> 1, 0, 64);
+ rx_evm &= 0x3F; /* 64->0: second path of 1SS rate is 64 */
+ dm_info->rx_evm_dbm[RF_PATH_A] = rx_evm;
+}
+
+static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
+ struct rtw_rx_pkt_stat *pkt_stat)
+{
+ u8 page;
+
+ page = *phy_status & 0xf;
+
+ switch (page) {
+ case 0:
+ query_phy_status_page0(rtwdev, phy_status, pkt_stat);
+ break;
+ case 1:
+ query_phy_status_page1(rtwdev, phy_status, pkt_stat);
+ break;
+ default:
+ rtw_warn(rtwdev, "unused phy status page (%d)\n", page);
+ return;
+ }
+}
+
+static void rtw8723d_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
+ struct rtw_rx_pkt_stat *pkt_stat,
+ struct ieee80211_rx_status *rx_status)
+{
+ struct ieee80211_hdr *hdr;
+ u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
+ u8 *phy_status = NULL;
+
+ memset(pkt_stat, 0, sizeof(*pkt_stat));
+
+ pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
+ pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
+ pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
+ pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
+ GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
+ pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
+ pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
+ pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
+ pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
+ pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
+ pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
+ pkt_stat->ppdu_cnt = 0;
+ pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
+
+ /* drv_info_sz is in unit of 8-bytes */
+ pkt_stat->drv_info_sz *= 8;
+
+ /* c2h cmd pkt's rx/phy status is not interested */
+ if (pkt_stat->is_c2h)
+ return;
+
+ hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
+ pkt_stat->drv_info_sz);
+ if (pkt_stat->phy_status) {
+ phy_status = rx_desc + desc_sz + pkt_stat->shift;
+ query_phy_status(rtwdev, phy_status, pkt_stat);
+ }
+
+ rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
+}
+
#define BIT_CFENDFORM BIT(9)
#define BIT_WMAC_TCR_ERR0 BIT(12)
#define BIT_WMAC_TCR_ERR1 BIT(13)
@@ -267,6 +382,7 @@ static void rtw8723d_efuse_grant(struct rtw_dev *rtwdev, bool on)
static struct rtw_chip_ops rtw8723d_ops = {
.phy_set_param = rtw8723d_phy_set_param,
.read_efuse = rtw8723d_read_efuse,
+ .query_rx_desc = rtw8723d_query_rx_desc,
.mac_init = rtw8723d_mac_init,
.read_rf = rtw_phy_read_rf_sipi,
.write_rf = rtw_phy_write_rf_reg_sipi,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.h b/drivers/net/wireless/realtek/rtw88/rtw8723d.h
index 6321dea83519..035049a29e7c 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.h
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.h
@@ -44,6 +44,28 @@ struct rtw8723d_efuse {
struct rtw8723de_efuse e;
};

+/* phy status page0 */
+#define GET_PHY_STAT_P0_PWDB(phy_stat) \
+ le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(15, 8))
+
+/* phy status page1 */
+#define GET_PHY_STAT_P1_PWDB_A(phy_stat) \
+ le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(15, 8))
+#define GET_PHY_STAT_P1_PWDB_B(phy_stat) \
+ le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(23, 16))
+#define GET_PHY_STAT_P1_RF_MODE(phy_stat) \
+ le32_get_bits(*((__le32 *)(phy_stat) + 0x03), GENMASK(29, 28))
+#define GET_PHY_STAT_P1_L_RXSC(phy_stat) \
+ le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(11, 8))
+#define GET_PHY_STAT_P1_HT_RXSC(phy_stat) \
+ le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(15, 12))
+#define GET_PHY_STAT_P1_RXEVM_A(phy_stat) \
+ le32_get_bits(*((__le32 *)(phy_stat) + 0x04), GENMASK(7, 0))
+#define GET_PHY_STAT_P1_CFO_TAIL_A(phy_stat) \
+ le32_get_bits(*((__le32 *)(phy_stat) + 0x05), GENMASK(7, 0))
+#define GET_PHY_STAT_P1_RXSNR_A(phy_stat) \
+ le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(7, 0))
+
#define REG_OFDM0_XAAGC1 0x0c50
#define REG_OFDM0_XBAGC1 0x0c58

--
2.17.1

2020-04-23 12:32:07

by Tony Chuang

[permalink] [raw]
Subject: [PATCH v2 3/8] rtw88: 8723d: Add set_channel

From: Ping-Ke Shih <[email protected]>

Set MAC/BB/RF register according to specified channel. The function
rtw_set_channel_mac() is used to set MAC registers, but 8723D only need
some of them.

For channel 14, we need to set different CCK DFIR values, so restore the
values when channel 1 to 13 is selected.

Spur calibration is needed in channel 13 and 14, and we do notch if spur
is over threshold.

Signed-off-by: Ping-Ke Shih <[email protected]>
Signed-off-by: Yan-Hsuan Chuang <[email protected]>
---
drivers/net/wireless/realtek/rtw88/mac.c | 3 +
drivers/net/wireless/realtek/rtw88/rtw8723d.c | 185 ++++++++++++++++++
drivers/net/wireless/realtek/rtw88/rtw8723d.h | 12 ++
3 files changed, 200 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c
index 645207a01525..c42d0f681dda 100644
--- a/drivers/net/wireless/realtek/rtw88/mac.c
+++ b/drivers/net/wireless/realtek/rtw88/mac.c
@@ -40,6 +40,9 @@ void rtw_set_channel_mac(struct rtw_dev *rtwdev, u8 channel, u8 bw,
}
rtw_write32(rtwdev, REG_WMAC_TRXPTCL_CTL, value32);

+ if (rtw_chip_wcpu_11n(rtwdev))
+ return;
+
value32 = rtw_read32(rtwdev, REG_AFE_CTRL1) & ~(BIT_MAC_CLK_SEL);
value32 |= (MAC_CLK_HW_DEF_80M << BIT_SHIFT_MAC_CLK_SEL);
rtw_write32(rtwdev, REG_AFE_CTRL1, value32);
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
index 653cfa9445fc..c619ee289561 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
@@ -287,6 +287,190 @@ static void rtw8723d_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
}

+static
+bool rtw8723d_check_spur_ov_thres(struct rtw_dev *rtwdev, u8 channel, u32 thres)
+{
+#define DIS_3WIRE 0xccf000c0
+#define EN_3WIRE 0xccc000c0
+#define START_PSD 0x400000
+#define FREQ_CH13 0xFCCD
+#define FREQ_CH14 0xFF9A
+
+ u32 freq;
+ bool ret = false;
+
+ if (channel == 13)
+ freq = FREQ_CH13;
+ else if (channel == 14)
+ freq = FREQ_CH14;
+ else
+ return false;
+
+ rtw_write32(rtwdev, REG_ANALOG_P4, DIS_3WIRE);
+ rtw_write32(rtwdev, REG_PSDFN, freq);
+ rtw_write32(rtwdev, REG_PSDFN, START_PSD | freq);
+
+ msleep(30);
+ if (rtw_read32(rtwdev, REG_PSDRPT) >= thres)
+ ret = true;
+
+ rtw_write32(rtwdev, REG_PSDFN, freq);
+ rtw_write32(rtwdev, REG_ANALOG_P4, EN_3WIRE);
+
+ return ret;
+}
+
+static void rtw8723d_cfg_notch(struct rtw_dev *rtwdev, u8 channel, bool notch)
+{
+#define BIT_MASK_RXDSP (BIT(28) | BIT(27) | BIT(26) | BIT(25) | BIT(24))
+#define BIT_EN_RXDSP BIT(9)
+#define BIT_EN_CFOTRK BIT(28)
+
+ if (!notch)
+ goto no_notch;
+
+ switch (channel) {
+ case 13:
+ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0xB);
+ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1);
+ rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x04000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000);
+ rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1);
+ break;
+ case 14:
+ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x5);
+ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1);
+ rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00080000);
+ rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1);
+ break;
+ default:
+ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x0);
+ rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x0);
+ break;
+ }
+
+ return;
+
+no_notch:
+ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x1f);
+ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x0);
+ rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000);
+ rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000);
+ rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x0);
+}
+
+static void rtw8723d_spur_cal(struct rtw_dev *rtwdev, u8 channel)
+{
+#define SPUR_THRES 0x16
+ bool notch = false;
+
+ if (channel < 13)
+ goto do_notch;
+
+ notch = rtw8723d_check_spur_ov_thres(rtwdev, channel, SPUR_THRES);
+
+do_notch:
+ rtw8723d_cfg_notch(rtwdev, channel, notch);
+}
+
+static void rtw8723d_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw)
+{
+#define RFCFGCH_CHANNEL_MASK GENMASK(7, 0)
+#define RFCFGCH_BW_MASK (BIT(11) | BIT(10))
+#define RFCFGCH_BW_20M (BIT(11) | BIT(10))
+#define RFCFGCH_BW_40M (BIT(10))
+
+ u32 rf_cfgch[2];
+
+ rf_cfgch[0] = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK);
+ rf_cfgch[1] = rtw_read_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK);
+
+ rf_cfgch[0] &= ~RFCFGCH_CHANNEL_MASK;
+ rf_cfgch[1] &= ~RFCFGCH_CHANNEL_MASK;
+ rf_cfgch[0] |= (channel & RFCFGCH_CHANNEL_MASK);
+ rf_cfgch[1] |= (channel & RFCFGCH_CHANNEL_MASK);
+
+ rf_cfgch[0] &= ~RFCFGCH_BW_MASK;
+ switch (bw) {
+ case RTW_CHANNEL_WIDTH_20:
+ rf_cfgch[0] |= RFCFGCH_BW_20M;
+ break;
+ case RTW_CHANNEL_WIDTH_40:
+ rf_cfgch[0] |= RFCFGCH_BW_40M;
+ break;
+ default:
+ break;
+ }
+
+ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, rf_cfgch[0]);
+ rtw_write_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK, rf_cfgch[1]);
+
+ rtw8723d_spur_cal(rtwdev, channel);
+}
+
+#define CCK_DFIR_NR 3
+static const struct rtw_backup_info cck_dfir_cfg[][CCK_DFIR_NR] = {
+ [0] = {
+ { .len = 4, .reg = 0xA24, .val = 0x64B80C1C },
+ { .len = 4, .reg = 0xA28, .val = 0x00008810 },
+ { .len = 4, .reg = 0xAAC, .val = 0x01235667 },
+ },
+ [1] = {
+ { .len = 4, .reg = 0xA24, .val = 0x0000B81C },
+ { .len = 4, .reg = 0xA28, .val = 0x00000000 },
+ { .len = 4, .reg = 0xAAC, .val = 0x00003667 },
+ },
+};
+
+static void rtw8723d_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw,
+ u8 primary_ch_idx)
+{
+#define BIT_CCK_SIDE_BAND BIT(4)
+#define BIT_MASK_RFMOD BIT(0)
+#define BIT_RXBB_DFIR_EN BIT(19)
+#define BIT_MASK_RXBB_DFIR (BIT(27) | BIT(26) | BIT(25) | BIT(24))
+
+ const struct rtw_backup_info *cck_dfir =
+ channel <= 13 ? cck_dfir_cfg[0] : cck_dfir_cfg[1];
+ int i;
+
+ for (i = 0; i < CCK_DFIR_NR; i++, cck_dfir++)
+ rtw_write32(rtwdev, cck_dfir->reg, cck_dfir->val);
+
+ switch (bw) {
+ case RTW_CHANNEL_WIDTH_20:
+ rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, 0x0);
+ rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, 0x0);
+ rtw_write32_mask(rtwdev, REG_BBRX_DFIR, BIT_RXBB_DFIR_EN, 1);
+ rtw_write32_mask(rtwdev, REG_BBRX_DFIR, BIT_MASK_RXBB_DFIR, 0xa);
+ break;
+ case RTW_CHANNEL_WIDTH_40:
+ rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, 0x1);
+ rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, 0x1);
+ rtw_write32_mask(rtwdev, REG_BBRX_DFIR, BIT_RXBB_DFIR_EN, 0);
+ rtw_write32_mask(rtwdev, REG_CCK0_SYS, BIT_CCK_SIDE_BAND,
+ (primary_ch_idx == RTW_SC_20_UPPER ? 1 : 0));
+ break;
+ default:
+ break;
+ }
+}
+
+static void rtw8723d_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw,
+ u8 primary_chan_idx)
+{
+ rtw8723d_set_channel_rf(rtwdev, channel, bw);
+ rtw_set_channel_mac(rtwdev, channel, bw, primary_chan_idx);
+ rtw8723d_set_channel_bb(rtwdev, channel, bw, primary_chan_idx);
+}
+
#define BIT_CFENDFORM BIT(9)
#define BIT_WMAC_TCR_ERR0 BIT(12)
#define BIT_WMAC_TCR_ERR1 BIT(13)
@@ -383,6 +567,7 @@ static struct rtw_chip_ops rtw8723d_ops = {
.phy_set_param = rtw8723d_phy_set_param,
.read_efuse = rtw8723d_read_efuse,
.query_rx_desc = rtw8723d_query_rx_desc,
+ .set_channel = rtw8723d_set_channel,
.mac_init = rtw8723d_mac_init,
.read_rf = rtw_phy_read_rf_sipi,
.write_rf = rtw_phy_write_rf_reg_sipi,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.h b/drivers/net/wireless/realtek/rtw88/rtw8723d.h
index 035049a29e7c..c08c351ba657 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.h
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.h
@@ -66,7 +66,19 @@ struct rtw8723d_efuse {
#define GET_PHY_STAT_P1_RXSNR_A(phy_stat) \
le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(7, 0))

+#define REG_PSDFN 0x0808
+#define REG_ANALOG_P4 0x088c
+#define REG_PSDRPT 0x08b4
+#define REG_FPGA1_RFMOD 0x0900
+#define REG_BBRX_DFIR 0x0954
+#define REG_CCK0_SYS 0x0a00
+#define REG_OFDM0_RXDSP 0x0c40
#define REG_OFDM0_XAAGC1 0x0c50
#define REG_OFDM0_XBAGC1 0x0c58
+#define REG_OFDM1_CFOTRK 0x0d2c
+#define REG_OFDM1_CSI1 0x0d40
+#define REG_OFDM1_CSI2 0x0d44
+#define REG_OFDM1_CSI3 0x0d48
+#define REG_OFDM1_CSI4 0x0d4c

#endif
--
2.17.1

2020-04-23 12:33:46

by Tony Chuang

[permalink] [raw]
Subject: [PATCH v2 8/8] rtw88: 8723d: add interface configurations table

From: Ping-Ke Shih <[email protected]>

Interface configuration table is used to configure PCI PHY that are
normally decided by design or bootstrap pin, and driver can do additional
settings by this table.

Signed-off-by: Ping-Ke Shih <[email protected]>
Signed-off-by: Yan-Hsuan Chuang <[email protected]>
---
drivers/net/wireless/realtek/rtw88/rtw8723d.c | 21 +++++++++++++++++++
1 file changed, 21 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
index dd8943426bb3..cf897af380c1 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
@@ -1072,6 +1072,26 @@ static const struct rtw_rqpn rqpn_table_8723d[] = {
RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
};

+static const struct rtw_intf_phy_para pcie_gen1_param_8723d[] = {
+ {0x0008, 0x4a22,
+ RTW_IP_SEL_PHY,
+ RTW_INTF_PHY_CUT_ALL,
+ RTW_INTF_PHY_PLATFORM_ALL},
+ {0x0009, 0x1000,
+ RTW_IP_SEL_PHY,
+ ~(RTW_INTF_PHY_CUT_A | RTW_INTF_PHY_CUT_B),
+ RTW_INTF_PHY_PLATFORM_ALL},
+ {0xFFFF, 0x0000,
+ RTW_IP_SEL_PHY,
+ RTW_INTF_PHY_CUT_ALL,
+ RTW_INTF_PHY_PLATFORM_ALL},
+};
+
+static const struct rtw_intf_phy_para_table phy_para_table_8723d = {
+ .gen1_para = pcie_gen1_param_8723d,
+ .n_gen1_para = ARRAY_SIZE(pcie_gen1_param_8723d),
+};
+
static const struct rtw_hw_reg rtw8723d_dig[] = {
[0] = { .addr = 0xc50, .mask = 0x7f },
[1] = { .addr = 0xc50, .mask = 0x7f },
@@ -1122,6 +1142,7 @@ struct rtw_chip_info rtw8723d_hw_spec = {
.pwr_off_seq = card_disable_flow_8723d,
.page_table = page_table_8723d,
.rqpn_table = rqpn_table_8723d,
+ .intf_table = &phy_para_table_8723d,
.dig = rtw8723d_dig,
.dig_cck = rtw8723d_dig_cck,
.rf_sipi_addr = {0x840, 0x844},
--
2.17.1

2020-04-23 12:33:46

by Tony Chuang

[permalink] [raw]
Subject: [PATCH v2 1/8] rtw88: 8723d: Add DIG parameter

From: Ping-Ke Shih <[email protected]>

To improve user experience in field, we need DIG to adjust RX initial gain
depends on field situation. Since each chip has its own register address,
this commit defines 8723d specific address.

Signed-off-by: Ping-Ke Shih <[email protected]>
Signed-off-by: Yan-Hsuan Chuang <[email protected]>
---
drivers/net/wireless/realtek/rtw88/rtw8723d.c | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
index 8ca4d5794434..52afa72caf8f 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
@@ -706,6 +706,11 @@ static const struct rtw_rqpn rqpn_table_8723d[] = {
RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
};

+static const struct rtw_hw_reg rtw8723d_dig[] = {
+ [0] = { .addr = 0xc50, .mask = 0x7f },
+ [1] = { .addr = 0xc50, .mask = 0x7f },
+};
+
static const struct rtw_rf_sipi_addr rtw8723d_rf_sipi_addr[] = {
[RF_PATH_A] = { .hssi_1 = 0x820, .lssi_read = 0x8a0,
.hssi_2 = 0x824, .lssi_read_pi = 0x8b8},
@@ -738,6 +743,7 @@ struct rtw_chip_info rtw8723d_hw_spec = {
.csi_buf_pg_num = 0,
.band = RTW_BAND_2G,
.page_size = 128,
+ .dig_min = 0x20,
.ht_supported = true,
.vht_supported = false,
.lps_deep_mode_supported = 0,
@@ -746,6 +752,7 @@ struct rtw_chip_info rtw8723d_hw_spec = {
.pwr_off_seq = card_disable_flow_8723d,
.page_table = page_table_8723d,
.rqpn_table = rqpn_table_8723d,
+ .dig = rtw8723d_dig,
.rf_sipi_addr = {0x840, 0x844},
.rf_sipi_read_addr = rtw8723d_rf_sipi_addr,
.fix_rf_phy_num = 2,
--
2.17.1

2020-04-23 12:35:32

by Tony Chuang

[permalink] [raw]
Subject: [PATCH v2 4/8] rtw88: handle C2H_CCX_TX_RPT to know if packet TX'ed successfully

From: Ping-Ke Shih <[email protected]>

TX status report of 8723D differs from 8822B/8822C, it uses
C2H_CCX_TX_RPT (0x03) with different format. With sequence number
and TX status, driver can know if certain packet was transmitted
successfully.

Signed-off-by: Ping-Ke Shih <[email protected]>
Signed-off-by: Yan-Hsuan Chuang <[email protected]>
---
drivers/net/wireless/realtek/rtw88/fw.c | 6 +++++-
drivers/net/wireless/realtek/rtw88/fw.h | 7 +++++--
drivers/net/wireless/realtek/rtw88/tx.c | 11 ++++++++---
drivers/net/wireless/realtek/rtw88/tx.h | 2 +-
4 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
index dde7823143ea..11fa1fc7f1cb 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.c
+++ b/drivers/net/wireless/realtek/rtw88/fw.c
@@ -25,7 +25,7 @@ static void rtw_fw_c2h_cmd_handle_ext(struct rtw_dev *rtwdev,

switch (sub_cmd_id) {
case C2H_CCX_RPT:
- rtw_tx_report_handle(rtwdev, skb);
+ rtw_tx_report_handle(rtwdev, skb, C2H_CCX_RPT);
break;
default:
break;
@@ -142,6 +142,9 @@ void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb)
goto unlock;

switch (c2h->id) {
+ case C2H_CCX_TX_RPT:
+ rtw_tx_report_handle(rtwdev, skb, C2H_CCX_TX_RPT);
+ break;
case C2H_BT_INFO:
rtw_coex_bt_info_notify(rtwdev, c2h->payload, len);
break;
@@ -155,6 +158,7 @@ void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb)
rtw_fw_ra_report_handle(rtwdev, c2h->payload, len);
break;
default:
+ rtw_dbg(rtwdev, RTW_DBG_FW, "C2H 0x%x isn't handled\n", c2h->id);
break;
}

diff --git a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/realtek/rtw88/fw.h
index 2933ef741e53..470e1809645a 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.h
+++ b/drivers/net/wireless/realtek/rtw88/fw.h
@@ -26,6 +26,7 @@
#define FW_START_ADDR_LEGACY 0x1000

enum rtw_c2h_cmd_id {
+ C2H_CCX_TX_RPT = 0x03,
C2H_BT_INFO = 0x09,
C2H_BT_MP_INFO = 0x0b,
C2H_RA_RPT = 0x0c,
@@ -218,8 +219,10 @@ struct rtw_fw_hdr_legacy {
} __packed;

/* C2H */
-#define GET_CCX_REPORT_SEQNUM(c2h_payload) (c2h_payload[8] & 0xfc)
-#define GET_CCX_REPORT_STATUS(c2h_payload) (c2h_payload[9] & 0xc0)
+#define GET_CCX_REPORT_SEQNUM_V0(c2h_payload) (c2h_payload[6] & 0xfc)
+#define GET_CCX_REPORT_STATUS_V0(c2h_payload) (c2h_payload[0] & 0xc0)
+#define GET_CCX_REPORT_SEQNUM_V1(c2h_payload) (c2h_payload[8] & 0xfc)
+#define GET_CCX_REPORT_STATUS_V1(c2h_payload) (c2h_payload[9] & 0xc0)

#define GET_RA_REPORT_RATE(c2h_payload) (c2h_payload[0] & 0x7f)
#define GET_RA_REPORT_SGI(c2h_payload) ((c2h_payload[0] & 0x80) >> 7)
diff --git a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c
index 60989987f67b..79c42118825f 100644
--- a/drivers/net/wireless/realtek/rtw88/tx.c
+++ b/drivers/net/wireless/realtek/rtw88/tx.c
@@ -196,7 +196,7 @@ static void rtw_tx_report_tx_status(struct rtw_dev *rtwdev,
ieee80211_tx_status_irqsafe(rtwdev->hw, skb);
}

-void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb)
+void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb, int src)
{
struct rtw_tx_report *tx_report = &rtwdev->tx_report;
struct rtw_c2h_cmd *c2h;
@@ -207,8 +207,13 @@ void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb)

c2h = get_c2h_from_skb(skb);

- sn = GET_CCX_REPORT_SEQNUM(c2h->payload);
- st = GET_CCX_REPORT_STATUS(c2h->payload);
+ if (src == C2H_CCX_TX_RPT) {
+ sn = GET_CCX_REPORT_SEQNUM_V0(c2h->payload);
+ st = GET_CCX_REPORT_STATUS_V0(c2h->payload);
+ } else {
+ sn = GET_CCX_REPORT_SEQNUM_V1(c2h->payload);
+ st = GET_CCX_REPORT_STATUS_V1(c2h->payload);
+ }

spin_lock_irqsave(&tx_report->q_lock, flags);
skb_queue_walk_safe(&tx_report->queue, cur, tmp) {
diff --git a/drivers/net/wireless/realtek/rtw88/tx.h b/drivers/net/wireless/realtek/rtw88/tx.h
index b973de0f4dc0..72dfd4059f03 100644
--- a/drivers/net/wireless/realtek/rtw88/tx.h
+++ b/drivers/net/wireless/realtek/rtw88/tx.h
@@ -95,7 +95,7 @@ void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev,
struct sk_buff *skb);
void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb);
void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn);
-void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb);
+void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb, int src);
void rtw_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info,
struct sk_buff *skb);
--
2.17.1

2020-04-27 05:46:08

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v2 3/8] rtw88: 8723d: Add set_channel

<[email protected]> writes:

> From: Ping-Ke Shih <[email protected]>
>
> Set MAC/BB/RF register according to specified channel. The function
> rtw_set_channel_mac() is used to set MAC registers, but 8723D only need
> some of them.
>
> For channel 14, we need to set different CCK DFIR values, so restore the
> values when channel 1 to 13 is selected.
>
> Spur calibration is needed in channel 13 and 14, and we do notch if spur
> is over threshold.
>
> Signed-off-by: Ping-Ke Shih <[email protected]>
> Signed-off-by: Yan-Hsuan Chuang <[email protected]>

[...]

> --- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c
> +++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
> @@ -287,6 +287,190 @@ static void rtw8723d_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
> rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
> }
>
> +static
> +bool rtw8723d_check_spur_ov_thres(struct rtw_dev *rtwdev, u8 channel, u32 thres)
> +{
> +#define DIS_3WIRE 0xccf000c0
> +#define EN_3WIRE 0xccc000c0
> +#define START_PSD 0x400000
> +#define FREQ_CH13 0xFCCD
> +#define FREQ_CH14 0xFF9A

Why this style of adding defines within a function? You use it in
multiple functions in this patch.

The normal upstream style is to have these kind of values defined in a
.h file somewhere.

--
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2020-04-29 07:17:40

by Tony Chuang

[permalink] [raw]
Subject: RE: [PATCH v2 3/8] rtw88: 8723d: Add set_channel

Kalle Valo <[email protected]> writes:

> <[email protected]> writes:
>
> > From: Ping-Ke Shih <[email protected]>
> >
> > Set MAC/BB/RF register according to specified channel. The function
> > rtw_set_channel_mac() is used to set MAC registers, but 8723D only need
> > some of them.
> >
> > For channel 14, we need to set different CCK DFIR values, so restore the
> > values when channel 1 to 13 is selected.
> >
> > Spur calibration is needed in channel 13 and 14, and we do notch if spur
> > is over threshold.
> >
> > Signed-off-by: Ping-Ke Shih <[email protected]>
> > Signed-off-by: Yan-Hsuan Chuang <[email protected]>
>
> [...]
>
> > --- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c
> > +++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c
> > @@ -287,6 +287,190 @@ static void rtw8723d_query_rx_desc(struct
> rtw_dev *rtwdev, u8 *rx_desc,
> > rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
> > }
> >
> > +static
> > +bool rtw8723d_check_spur_ov_thres(struct rtw_dev *rtwdev, u8 channel,
> u32 thres)
> > +{
> > +#define DIS_3WIRE 0xccf000c0
> > +#define EN_3WIRE 0xccc000c0
> > +#define START_PSD 0x400000
> > +#define FREQ_CH13 0xFCCD
> > +#define FREQ_CH14 0xFF9A
>
> Why this style of adding defines within a function? You use it in
> multiple functions in this patch.
>
> The normal upstream style is to have these kind of values defined in a
> .h file somewhere.
>

Thought they are used just for the function, but yes, should put them
into rtw8723d.h or something like that :)

Yen-Hsuan