Use the newly promoted helpers to implement support for 88xxa Signed-off-by: Ho Jie Feng --- drivers/net/wireless/realtek/rtw88/phy.c | 5 +- drivers/net/wireless/realtek/rtw88/phy.h | 6 +++ drivers/net/wireless/realtek/rtw88/rtw8812a.c | 2 + drivers/net/wireless/realtek/rtw88/rtw8814a.c | 32 +++++++++++-- drivers/net/wireless/realtek/rtw88/rtw8821a.c | 2 + drivers/net/wireless/realtek/rtw88/rtw88xxa.c | 47 +++++++++++++++---- drivers/net/wireless/realtek/rtw88/rtw88xxa.h | 1 + 7 files changed, 81 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c index d0c1fb65be..b01601d707 100644 --- a/drivers/net/wireless/realtek/rtw88/phy.c +++ b/drivers/net/wireless/realtek/rtw88/phy.c @@ -687,13 +687,14 @@ static void rtw_phy_parsing_cfo_iter(void *data, u8 *mac, struct rtw_rx_pkt_stat *pkt_stat = iter_data->pkt_stat; struct rtw_dm_info *dm_info = &rtwdev->dm_info; struct rtw_cfo_track *cfo = &dm_info->cfo_track; + u8 path_num = min_t(u8, rtwdev->hal.rf_path_num, RTW_CFO_PATH_NUM_MAX); u8 *bssid = iter_data->bssid; u8 i; if (!ether_addr_equal(vif->bss_conf.bssid, bssid)) return; - for (i = 0; i < rtwdev->hal.rf_path_num; i++) { + for (i = 0; i < path_num; i++) { cfo->cfo_tail[i] += pkt_stat->cfo_tail[i]; cfo->cfo_cnt[i]++; } @@ -794,7 +795,7 @@ u8 rtw_phy_cfo_xcap_track(struct rtw_dev *rtwdev, u8 xcap_max, bool bt_hold) { struct rtw_dm_info *dm_info = &rtwdev->dm_info; struct rtw_cfo_track *cfo = &dm_info->cfo_track; - u8 path_num = rtwdev->hal.rf_path_num; + u8 path_num = min_t(u8, rtwdev->hal.rf_path_num, RTW_CFO_PATH_NUM_MAX); s8 crystal_cap = cfo->crystal_cap; s32 cfo_avg = 0; diff --git a/drivers/net/wireless/realtek/rtw88/phy.h b/drivers/net/wireless/realtek/rtw88/phy.h index b551cb860d..52e6546b52 100644 --- a/drivers/net/wireless/realtek/rtw88/phy.h +++ b/drivers/net/wireless/realtek/rtw88/phy.h @@ -204,4 +204,10 @@ enum rtw_phy_cck_pd_lv { #define RRSR_RATE_ORDER_MAX 0xfffff #define RRSR_RATE_ORDER_CCK_LEN 4 +/* crystal cap width of all chips except RTL8822C */ +#define RTW_XCAP_MASK GENMASK(5, 0) + +/* RTL8814A has 4 paths, but only paths A and B report CFO */ +#define RTW_CFO_PATH_NUM_MAX 2 + #endif diff --git a/drivers/net/wireless/realtek/rtw88/rtw8812a.c b/drivers/net/wireless/realtek/rtw88/rtw8812a.c index 5d58dff4fc..c8008cf43d 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8812a.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8812a.c @@ -943,6 +943,8 @@ static const struct rtw_chip_ops rtw8812a_ops = { .coex_set_rfe_type = rtw8821a_coex_cfg_rfe_type, .coex_set_wl_tx_power = rtw8821a_coex_cfg_wl_tx_power, .coex_set_wl_rx_gain = rtw8821a_coex_cfg_wl_rx_gain, + .cfo_init = rtw_phy_cfo_xcap_init, + .cfo_track = rtw88xxa_cfo_track, }; static const struct rtw_page_table page_table_8812a[] = { diff --git a/drivers/net/wireless/realtek/rtw88/rtw8814a.c b/drivers/net/wireless/realtek/rtw88/rtw8814a.c index 13c22d2e50..74c548cb5c 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8814a.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8814a.c @@ -146,6 +146,9 @@ static int rtw8814a_read_efuse(struct rtw_dev *rtwdev, u8 *log_map, u8 *phy_map) efuse->rfe_option = map->rfe_option; efuse->rf_board_option = map->rf_board_option; efuse->crystal_cap = map->xtal_k; + if (efuse->crystal_cap == 0xff) + efuse->crystal_cap = 0x20; + efuse->crystal_cap &= RTW_XCAP_MASK; efuse->channel_plan = map->channel_plan; efuse->country_code[0] = map->country_code[0]; efuse->country_code[1] = map->country_code[1]; @@ -284,9 +287,15 @@ static void rtw8814a_config_cck_rx_antenna_init(struct rtw_dev *rtwdev) rtw_write32_mask(rtwdev, REG_CCKTX, BIT_CMB_CCA_2R, 1); } +static void rtw8814a_set_crystal_cap(struct rtw_dev *rtwdev, u8 crystal_cap) +{ + rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x07ff8000, + crystal_cap | (crystal_cap << 6)); +} + static void rtw8814a_phy_set_param(struct rtw_dev *rtwdev) { - u32 crystal_cap, val32; + u32 val32; u8 val8, rf_path; /* power on BB/RF domain */ @@ -308,9 +317,7 @@ static void rtw8814a_phy_set_param(struct rtw_dev *rtwdev) rtw_load_table(rtwdev, rtwdev->chip->bb_tbl); rtw_load_table(rtwdev, rtwdev->chip->agc_tbl); - crystal_cap = rtwdev->efuse.crystal_cap & 0x3F; - crystal_cap |= crystal_cap << 6; - rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x07ff8000, crystal_cap); + rtw8814a_set_crystal_cap(rtwdev, rtwdev->efuse.crystal_cap); rtw8814a_config_trx_path(rtwdev); @@ -1269,6 +1276,8 @@ static void rtw8814a_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, pkt_stat->cfo_tail[i] = cfo[i]; dm_info->cfo_tail[i] = (cfo[i] * 5) >> 1; } + + rtw_phy_parsing_cfo(rtwdev, pkt_stat); } } @@ -2074,6 +2083,19 @@ static void rtw8814a_bf_config_bfee(struct rtw_dev *rtwdev, rtw_bf_remove_bfee_su(rtwdev, bfee); } +static void rtw8814a_cfo_track(struct rtw_dev *rtwdev) +{ + struct rtw_cfo_track *cfo = &rtwdev->dm_info.cfo_track; + u8 crystal_cap; + + crystal_cap = rtw_phy_cfo_xcap_track(rtwdev, RTW_XCAP_MASK, false); + if (crystal_cap == cfo->crystal_cap) + return; + + cfo->crystal_cap = crystal_cap; + rtw8814a_set_crystal_cap(rtwdev, crystal_cap); +} + static void rtw8814a_fill_txdesc_checksum(struct rtw_dev *rtwdev, struct rtw_tx_pkt_info *pkt_info, u8 *txdesc) @@ -2108,6 +2130,8 @@ static const struct rtw_chip_ops rtw8814a_ops = { .cfg_csi_rate = NULL, .led_set = rtw8814a_led_set, .fill_txdesc_checksum = rtw8814a_fill_txdesc_checksum, + .cfo_init = rtw_phy_cfo_xcap_init, + .cfo_track = rtw8814a_cfo_track, .coex_set_init = rtw8814a_coex_cfg_init, .coex_set_ant_switch = rtw8814a_coex_cfg_ant_switch, diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821a.c b/drivers/net/wireless/realtek/rtw88/rtw8821a.c index 6d106ae70d..17d3677ca4 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8821a.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8821a.c @@ -889,6 +889,8 @@ static const struct rtw_chip_ops rtw8821a_ops = { .coex_set_rfe_type = rtw8821a_coex_cfg_rfe_type, .coex_set_wl_tx_power = rtw8821a_coex_cfg_wl_tx_power, .coex_set_wl_rx_gain = rtw8821a_coex_cfg_wl_rx_gain, + .cfo_init = rtw_phy_cfo_xcap_init, + .cfo_track = rtw88xxa_cfo_track, }; static const struct rtw_page_table page_table_8821a[] = { diff --git a/drivers/net/wireless/realtek/rtw88/rtw88xxa.c b/drivers/net/wireless/realtek/rtw88/rtw88xxa.c index 9780999a9b..68a4ca8069 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw88xxa.c +++ b/drivers/net/wireless/realtek/rtw88/rtw88xxa.c @@ -290,6 +290,7 @@ int rtw88xxa_read_efuse(struct rtw_dev *rtwdev, u8 *log_map, u8 *phy_map) efuse->crystal_cap = map->xtal_k; if (efuse->crystal_cap == 0xff) efuse->crystal_cap = 0x20; + efuse->crystal_cap &= RTW_XCAP_MASK; efuse->pa_type_2g = map->pa_type; efuse->pa_type_5g = map->pa_type; efuse->lna_type_2g = map->lna_type_2g; @@ -643,9 +644,19 @@ static void rtw88xxa_init_beacon_parameters(struct rtw_dev *rtwdev) rtw_write16(rtwdev, REG_BCNTCFG, 0x4413); } +static void rtw88xxa_set_crystal_cap(struct rtw_dev *rtwdev, u8 crystal_cap) +{ + if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A) + rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x7FF80000, + crystal_cap | (crystal_cap << 6)); + else + rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x00FFF000, + crystal_cap | (crystal_cap << 6)); +} + static void rtw88xxa_phy_bb_config(struct rtw_dev *rtwdev) { - u8 val8, crystal_cap; + u8 val8; /* power on BB/RF domain */ val8 = rtw_read8(rtwdev, REG_SYS_FUNC_EN); @@ -664,13 +675,7 @@ static void rtw88xxa_phy_bb_config(struct rtw_dev *rtwdev) rtw_load_table(rtwdev, rtwdev->chip->bb_tbl); rtw_load_table(rtwdev, rtwdev->chip->agc_tbl); - crystal_cap = rtwdev->efuse.crystal_cap & 0x3F; - if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A) - rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x7FF80000, - crystal_cap | (crystal_cap << 6)); - else - rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x00FFF000, - crystal_cap | (crystal_cap << 6)); + rtw88xxa_set_crystal_cap(rtwdev, rtwdev->efuse.crystal_cap); } static void rtw88xxa_phy_rf_config(struct rtw_dev *rtwdev) @@ -1632,6 +1637,17 @@ void rtw88xxa_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, power_b = power_a; pkt_stat->signal_power = max3(power_a, power_b, min_rx_power); + + pkt_stat->cfo_tail[RF_PATH_A] = + (s8)le32_get_bits(rpt->w2, RTW_JGRPHY_W2_CFO_TAIL_A); + pkt_stat->cfo_tail[RF_PATH_B] = + (s8)le32_get_bits(rpt->w2, RTW_JGRPHY_W2_CFO_TAIL_B); + + /* convert to kHz (used only for debugfs) */ + for (i = RF_PATH_A; i < rtwdev->hal.rf_path_num; i++) + dm_info->cfo_tail[i] = (pkt_stat->cfo_tail[i] * 5) >> 1; + + rtw_phy_parsing_cfo(rtwdev, pkt_stat); } } EXPORT_SYMBOL(rtw88xxa_query_phy_status); @@ -2020,6 +2036,21 @@ void rtw88xxa_phy_pwrtrack(struct rtw_dev *rtwdev, } EXPORT_SYMBOL(rtw88xxa_phy_pwrtrack); +void rtw88xxa_cfo_track(struct rtw_dev *rtwdev) +{ + struct rtw_cfo_track *cfo = &rtwdev->dm_info.cfo_track; + bool bt_hold = rtwdev->efuse.btcoex && !rtw_coex_disabled(rtwdev); + u8 crystal_cap; + + crystal_cap = rtw_phy_cfo_xcap_track(rtwdev, RTW_XCAP_MASK, bt_hold); + if (crystal_cap == cfo->crystal_cap) + return; + + cfo->crystal_cap = crystal_cap; + rtw88xxa_set_crystal_cap(rtwdev, crystal_cap); +} +EXPORT_SYMBOL(rtw88xxa_cfo_track); + MODULE_AUTHOR("Realtek Corporation"); MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821a/8811a/8812a common code"); MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/realtek/rtw88/rtw88xxa.h b/drivers/net/wireless/realtek/rtw88/rtw88xxa.h index 150e86ea74..188b8f3a4b 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw88xxa.h +++ b/drivers/net/wireless/realtek/rtw88/rtw88xxa.h @@ -172,5 +172,6 @@ void rtw88xxa_phy_pwrtrack(struct rtw_dev *rtwdev, void (*do_iqk)(struct rtw_dev *rtwdev)); void rtw88xxa_bf_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif, struct rtw_bfee *bfee, bool enable); +void rtw88xxa_cfo_track(struct rtw_dev *rtwdev); #endif -- 2.53.0