1: 477ecd982462 ! 1: 11ed65530b3f wifi: rtw88: 8812a, 8814a: enable STBC for HT transmissions @@ Commit message  8812a and 8814a support STBC, enable it.  + 8822c will lose reporting TX STBC capability if efuse reports + only 1 path, but this is correct, since it in that case it doesn't + actually support STBC. + Signed-off-by: Ho Jie Feng   ## drivers/net/wireless/realtek/rtw88/main.c ## 2: e757681e159e ! 2: 3552416ed0a9 wifi: rtw88: 88xxa: receive VHT SU beamformed transmissions @@ drivers/net/wireless/realtek/rtw88/bf.h #define BIT_DIS_CHK_VHTSIGB_CRC BIT(6) #define BIT_DIS_CHK_VHTSIGA_CRC BIT(5)  + ## drivers/net/wireless/realtek/rtw88/main.c ## +@@ drivers/net/wireless/realtek/rtw88/main.c: static void rtw_init_ht_cap(struct rtw_dev *rtwdev, + static void rtw_init_vht_cap(struct rtw_dev *rtwdev, + struct ieee80211_sta_vht_cap *vht_cap) + { ++ const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_efuse *efuse = &rtwdev->efuse; + u16 mcs_map = 0; + __le16 highest; +@@ drivers/net/wireless/realtek/rtw88/main.c: static void rtw_init_vht_cap(struct rtw_dev *rtwdev, + 0; + if (rtwdev->hal.rf_path_num > 1) + vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC; +- vht_cap->cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE | +- IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; +- vht_cap->cap |= (rtwdev->hal.bfee_sts_cap << +- IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT); ++ if (rtw_bf_support && chip->bfer_su_max_num) { ++ vht_cap->cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; ++ vht_cap->cap |= rtwdev->hal.bfee_sts_cap << ++ IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT; ++ } ++ if (rtw_bf_support && chip->bfer_mu_max_num) ++ vht_cap->cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE; +  + if (rtw_chip_has_rx_ldpc(rtwdev)) + vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC; + ## drivers/net/wireless/realtek/rtw88/reg.h ##  @@ #define REG_IQK_COM96 0x0984 @@ drivers/net/wireless/realtek/rtw88/rtw8814a.c: static void rtw8814a_led_set(stru  +{  + rtw_bf_enable_bfee_su(rtwdev, vif, bfee);  + -+ rtw_write16(rtwdev, REG_SND_PTCL_CTRL + 1, 0x0202); ++ rtw_write32_mask(rtwdev, REG_SND_PTCL_CTRL, MASKBYTE1 | MASKBYTE2, ++ 0x0202);  + rtw_write8(rtwdev, REG_SND_PTCL_CTRL, RTW_SND_CTRL_SOUNDING_8814A);  + rtw_write8(rtwdev, REG_SND_PTCL_CTRL + 3,  + RTW_NDP_RX_STANDBY_TIME_8814A); @@ drivers/net/wireless/realtek/rtw88/rtw88xxa.c: static void rtw88xxa_read_usb_typ efuse->hw_cap.nss = 1; else efuse->hw_cap.nss = 2; -+ rtwdev->hal.bfee_sts_cap = 1; ++ hal->bfee_sts_cap = 1;  if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) goto print_hw_cap; @@ drivers/net/wireless/realtek/rtw88/rtw88xxa.c: static void rtw88xxa_read_usb_typ  + return;  +  + addr_bfer_info = slot ? REG_ASSOCIATED_BFMER1_INFO : -+ REG_ASSOCIATED_BFMER0_INFO; ++ REG_ASSOCIATED_BFMER0_INFO;  + -+ rtw_dbg(rtwdev, RTW_DBG_BF, "chip %d SU beamformee %s slot %u\n", -+ rtwdev->chip->id, enable ? "enable" : "disable", slot); ++ rtw_dbg(rtwdev, RTW_DBG_BF, "SU beamformee %s slot %u\n", ++ enable ? "enable" : "disable", slot);  +  + if (!enable) {  + rtw_write32(rtwdev, addr_bfer_info, 0); @@ drivers/net/wireless/realtek/rtw88/rtw88xxa.c: static void rtw88xxa_read_usb_typ  + return;  + }  + -+ if (hweight8(rtwdev->hal.antenna_rx) == 2) { ++ if (rtwdev->efuse.hw_cap.nss == 2) {  + rtw_write32(rtwdev, REG_CSI_CONTENT_VALUE, 0);  + csi_param = 0x01090109;  + } else { @@ drivers/net/wireless/realtek/rtw88/rtw88xxa.c: static void rtw88xxa_read_usb_typ  + csi_param = 0x01080108;  + }  + -+ rtw_write8(rtwdev, REG_SND_PTCL_CTRL, -+ RTW_SND_CTRL_SOUNDING_88XXA); ++ rtw_write8(rtwdev, REG_SND_PTCL_CTRL, RTW_SND_CTRL_SOUNDING_88XXA);  + for (i = 0; i < ETH_ALEN; i++)  + rtw_write8(rtwdev, addr_bfer_info + i, bfee->mac_addr[i]);  + @@ drivers/net/wireless/realtek/rtw88/rtw88xxa.c: static void rtw88xxa_read_usb_typ  +}  +EXPORT_SYMBOL(rtw88xxa_bf_config_bfee);  + - int rtw88xxa_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) + int rtw88xxa_read_efuse(struct rtw_dev *rtwdev, u8 *log_map, u8 *phy_map) { const struct rtw_chip_info *chip = rtwdev->chip;  3: cdb165ae672c < -: ------------ wifi: rtw88: correctly expose beamformee capabilities 4: 6e4873e20788 = 3: 8a341ff4326f wifi: rtw88: prepare frequency-offset correction for more chips 5: 603b4b07a154 ! 4: 4678ecbb9b4d wifi: rtw88: 88xxa: correct carrier-frequency offset @@ drivers/net/wireless/realtek/rtw88/phy.c: static void rtw_phy_parsing_cfo_iter(v 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; ++ /* rtl8814a has 4 paths, but only 2 of them report cfo */  + u8 path_num = min_t(u8, rtwdev->hal.rf_path_num, 2); u8 *bssid = iter_data->bssid; u8 i; @@ drivers/net/wireless/realtek/rtw88/phy.c: u8 rtw_phy_cfo_xcap_track(struct rtw_d s32 cfo_avg = 0;   + ## drivers/net/wireless/realtek/rtw88/phy.h ## +@@ drivers/net/wireless/realtek/rtw88/phy.h: 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) ++ + #endif + ## drivers/net/wireless/realtek/rtw88/rtw8812a.c ##  @@ drivers/net/wireless/realtek/rtw88/rtw8812a.c: static const struct rtw_chip_ops rtw8812a_ops = { .coex_set_rfe_type = rtw8821a_coex_cfg_rfe_type, @@ drivers/net/wireless/realtek/rtw88/rtw8812a.c: static const struct rtw_chip_ops static const struct rtw_page_table page_table_8812a[] = {  ## drivers/net/wireless/realtek/rtw88/rtw8814a.c ## -@@ drivers/net/wireless/realtek/rtw88/rtw8814a.c: static int rtw8814a_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) - efuse->usb_mode_switch = u8_get_bits(map->usb_mode, BIT(4)); +@@ drivers/net/wireless/realtek/rtw88/rtw8814a.c: 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; -+ efuse->crystal_cap = map->xtal_k & 0x3f; + 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]; @@ drivers/net/wireless/realtek/rtw88/rtw8814a.c: static void rtw8814a_bf_config_bf  + struct rtw_cfo_track *cfo = &rtwdev->dm_info.cfo_track;  + u8 crystal_cap;  + -+ crystal_cap = rtw_phy_cfo_xcap_track(rtwdev, 0x3f, false); ++ crystal_cap = rtw_phy_cfo_xcap_track(rtwdev, RTW_XCAP_MASK, false);  + if (crystal_cap == cfo->crystal_cap)  + return;  + @@ drivers/net/wireless/realtek/rtw88/rtw8821a.c: static const struct rtw_chip_ops static const struct rtw_page_table page_table_8821a[] = {  ## drivers/net/wireless/realtek/rtw88/rtw88xxa.c ## -@@ drivers/net/wireless/realtek/rtw88/rtw88xxa.c: int rtw88xxa_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) +@@ drivers/net/wireless/realtek/rtw88/rtw88xxa.c: 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 &= 0x3F; ++ 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; @@ drivers/net/wireless/realtek/rtw88/rtw88xxa.c: static void rtw88xxa_phy_bb_confi  - else  - rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x00FFF000,  - crystal_cap | (crystal_cap << 6)); -+ rtw88xxa_set_crystal_cap(rtwdev, rtwdev->efuse.crystal_cap & 0x3F); ++ rtw88xxa_set_crystal_cap(rtwdev, rtwdev->efuse.crystal_cap); }  static void rtw88xxa_phy_rf_config(struct rtw_dev *rtwdev) @@ drivers/net/wireless/realtek/rtw88/rtw88xxa.c: void rtw88xxa_phy_pwrtrack(struct  + bool bt_hold = rtwdev->efuse.btcoex && !rtw_coex_disabled(rtwdev);  + u8 crystal_cap;  + -+ crystal_cap = rtw_phy_cfo_xcap_track(rtwdev, 0x3F, bt_hold); ++ crystal_cap = rtw_phy_cfo_xcap_track(rtwdev, RTW_XCAP_MASK, bt_hold);  + if (crystal_cap == cfo->crystal_cap)  + return;  + 6: 60a9863efe85 < -: ------------ wifi: rtw88: 88xxa: adapt channel sensing to receiver gain 7: 4e835de5e99c ! 5: 9161e760a746 wifi: rtw88: 8812a, 8821a: respect peer A-MPDU size limits @@ drivers/net/wireless/realtek/rtw88/rtw8812a.c: static void rtw8812a_cfg_ldo25(st  +{  + factor = min_t(u8, factor, IEEE80211_VHT_MAX_AMPDU_128K);  + -+ rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, (8192 << factor) - 1); ++ rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, ++ ((8192 << factor) - 1) | BIT(31));  +}  + static void rtw8812a_do_lck(struct rtw_dev *rtwdev) @@ drivers/net/wireless/realtek/rtw88/rtw8821a.c: static void rtw8821a_cfg_ldo25(st   +static void rtw8821a_set_ampdu_factor(struct rtw_dev *rtwdev, u8 factor)  +{ -+ factor = min_t(u8, factor, IEEE80211_HT_MAX_AMPDU_64K); ++ factor = min_t(u8, factor, IEEE80211_VHT_MAX_AMPDU_64K);  + -+ rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, (8192 << factor) - 1); ++ rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, ++ ((8192 << factor) - 1) | BIT(31));  +}  + #define CAL_NUM_8821A 3