Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rtw88: 8821c: add beamformee support

Beamforming is used for directional signal transmission/reception.
Beamformee plays the role for signal reception, and makes the RX
performance better in middle distance range.

Implement beamformee related callbacks for 8821c.

Since 8821c only support 1ss rate, nc_index in beamformee setting
needs to be adjusted based on the capability.

Signed-off-by: Tzu-En Huang <tehuang@realtek.com>
Signed-off-by: Yan-Hsuan Chuang <yhchuang@realtek.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20200603094218.19942-4-yhchuang@realtek.com

authored by

Tzu-En Huang and committed by
Kalle Valo
5f4eab88 3a431282

+48 -2
+3 -2
drivers/net/wireless/realtek/rtw88/bf.c
··· 183 183 void rtw_bf_enable_bfee_su(struct rtw_dev *rtwdev, struct rtw_vif *vif, 184 184 struct rtw_bfee *bfee) 185 185 { 186 - u8 nc_index = 1; 186 + u8 nc_index = hweight8(rtwdev->hal.antenna_rx) - 1; 187 187 u8 nr_index = bfee->sound_dim; 188 188 u8 grouping = 0, codebookinfo = 1, coefficientsize = 3; 189 189 u32 addr_bfer_info, addr_csi_rpt, csi_param; ··· 231 231 { 232 232 struct rtw_bf_info *bf_info = &rtwdev->bf_info; 233 233 struct mu_bfer_init_para param; 234 - u8 nc_index = 1, nr_index = 1; 234 + u8 nc_index = hweight8(rtwdev->hal.antenna_rx) - 1; 235 + u8 nr_index = 1; 235 236 u8 grouping = 0, codebookinfo = 1, coefficientsize = 0; 236 237 u32 csi_param; 237 238
+45
drivers/net/wireless/realtek/rtw88/rtw8821c.c
··· 101 101 dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; 102 102 } 103 103 104 + static void rtw8821c_phy_bf_init(struct rtw_dev *rtwdev) 105 + { 106 + rtw_bf_phy_init(rtwdev); 107 + /* Grouping bitmap parameters */ 108 + rtw_write32(rtwdev, 0x1C94, 0xAFFFAFFF); 109 + } 110 + 104 111 static void rtw8821c_phy_set_param(struct rtw_dev *rtwdev) 105 112 { 106 113 u8 crystal_cap, val; ··· 152 145 rtwdev->dm_info.cck_pd_default = rtw_read8(rtwdev, REG_CSRATIO) & 0x1f; 153 146 154 147 rtw8821c_pwrtrack_init(rtwdev); 148 + 149 + rtw8821c_phy_bf_init(rtwdev); 155 150 } 156 151 157 152 static int rtw8821c_mac_init(struct rtw_dev *rtwdev) ··· 795 786 dm_info->pwr_trk_triggered = false; 796 787 } 797 788 789 + static void rtw8821c_bf_config_bfee_su(struct rtw_dev *rtwdev, 790 + struct rtw_vif *vif, 791 + struct rtw_bfee *bfee, bool enable) 792 + { 793 + if (enable) 794 + rtw_bf_enable_bfee_su(rtwdev, vif, bfee); 795 + else 796 + rtw_bf_remove_bfee_su(rtwdev, bfee); 797 + } 798 + 799 + static void rtw8821c_bf_config_bfee_mu(struct rtw_dev *rtwdev, 800 + struct rtw_vif *vif, 801 + struct rtw_bfee *bfee, bool enable) 802 + { 803 + if (enable) 804 + rtw_bf_enable_bfee_mu(rtwdev, vif, bfee); 805 + else 806 + rtw_bf_remove_bfee_mu(rtwdev, bfee); 807 + } 808 + 809 + static void rtw8821c_bf_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif, 810 + struct rtw_bfee *bfee, bool enable) 811 + { 812 + if (bfee->role == RTW_BFEE_SU) 813 + rtw8821c_bf_config_bfee_su(rtwdev, vif, bfee, enable); 814 + else if (bfee->role == RTW_BFEE_MU) 815 + rtw8821c_bf_config_bfee_mu(rtwdev, vif, bfee, enable); 816 + else 817 + rtw_warn(rtwdev, "wrong bfee role\n"); 818 + } 819 + 798 820 static void rtw8821c_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl) 799 821 { 800 822 struct rtw_dm_info *dm_info = &rtwdev->dm_info; ··· 1290 1250 .phy_calibration = rtw8821c_phy_calibration, 1291 1251 .cck_pd_set = rtw8821c_phy_cck_pd_set, 1292 1252 .pwr_track = rtw8821c_pwr_track, 1253 + .config_bfee = rtw8821c_bf_config_bfee, 1254 + .set_gid_table = rtw_bf_set_gid_table, 1255 + .cfg_csi_rate = rtw_bf_cfg_csi_rate, 1293 1256 }; 1294 1257 1295 1258 static const u8 rtw8821c_pwrtrk_5gb_n[][RTW_PWR_TRK_TBL_SZ] = { ··· 1438 1395 .rx_ldpc = false, 1439 1396 .pwr_track_tbl = &rtw8821c_rtw_pwr_track_tbl, 1440 1397 .iqk_threshold = 8, 1398 + .bfer_su_max_num = 2, 1399 + .bfer_mu_max_num = 1, 1441 1400 }; 1442 1401 EXPORT_SYMBOL(rtw8821c_hw_spec); 1443 1402