Message ID | 20190611180247.19524-4-sven@narfation.org (mailing list archive) |
---|---|
State | Not Applicable |
Delegated to: | Kalle Valo |
Headers | show |
Series | mac80211/ath11k: HE mesh support | expand |
On Tuesday, 11 June 2019 20:02:47 CEST Sven Eckelmann wrote: [...] > --- > This doesn't work currently as expected. No HE rates are used between > the two HE mesh peers: [...] There seems to be also an ordering problem. ath11k_peer_assoc_h_he is only called before ieee80211_he_cap_ie_to_sta_he_cap is called. So ath11k_bss_assoc will not have the information whether the remote has HE support or not. Looks like I have adjust mesh_sta_info_init to get this somehow to ath11k_peer_assoc_h_he. Maybe through ath11k_sta_rc_update but this is not called by mesh_sta_info_init at the moment. Just because rate_control_rate_init is called and not rate_control_rate_update. The easiest method seems to adjust the check at the end of mesh_sta_info_init to if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL) && !ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL)) { rate_control_rate_init(sta); } else { rate_control_rate_update(local, sband, sta, changed); } and to create a IEEE80211_RC_SUPP_RATES_CHANGED change when the has_he state changes. And yes, I know that Bob Copeland added this because it would have crashed ath10k when rate_control_rate_init is not used [1]. The other suggestion would be: if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) rate_control_rate_init(sta); /* inform drivers about changes */ rate_control_rate_update(local, sband, sta, changed); Both will at least cause a call to ath11k_peer_assoc_prepare + ath11k_wmi_send_peer_assoc_cmd but unfortunately the ath11k firmware hangs afterwards. Kind regards, Sven [1] https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?id=1d6741d86429a294f51f2773c751c8f7662e7ca2
On Tuesday, 11 June 2019 21:52:20 CEST Sven Eckelmann wrote: [...] > if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) > rate_control_rate_init(sta); > > /* inform drivers about changes */ > rate_control_rate_update(local, sband, sta, changed); > > Both will at least cause a call to ath11k_peer_assoc_prepare + > ath11k_wmi_send_peer_assoc_cmd but unfortunately the ath11k firmware hangs > afterwards. The fw hang seems to be related to the not set bss_conf.he_support in ath11k_mac_vdev_start_restart. This has to be set when ieee80211_join_mesh calls ieee80211_vif_use_channel. Otherwise the firmware will set a HT/VHT mode in the firmware. Any sta with an higher phy mode will just hang the firmware. So the two main problems right now are: * set bss_conf.he_support during mesh_join before ath11k_mac_vdev_start_restart is called - no clue what the best approach is * let ath11k redo the association procedure with he_cap->has_he set to true when wpa_supplicant is in control of the peers. Kind regards, Sven
On Tue, Jun 11, 2019 at 09:52:20PM +0200, Sven Eckelmann wrote: > On Tuesday, 11 June 2019 20:02:47 CEST Sven Eckelmann wrote: > [...] > > --- > > This doesn't work currently as expected. No HE rates are used between > > the two HE mesh peers: > [...] > > There seems to be also an ordering problem. ath11k_peer_assoc_h_he is only > called before ieee80211_he_cap_ie_to_sta_he_cap is called. So ath11k_bss_assoc > will not have the information whether the remote has HE support or not. > > Looks like I have adjust mesh_sta_info_init to get this somehow to > ath11k_peer_assoc_h_he. Maybe through ath11k_sta_rc_update but this is not > called by mesh_sta_info_init at the moment. Just because > rate_control_rate_init is called and not rate_control_rate_update. > > The easiest method seems to adjust the check at the end of mesh_sta_info_init > to > > if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL) && > !ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL)) { > rate_control_rate_init(sta); > } else { > rate_control_rate_update(local, sband, sta, changed); > } Maybe we should just do this? diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 76f303fda3ed..6f8bde840bb9 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c @@ -42,7 +42,7 @@ void rate_control_rate_init(struct sta_info *sta) ieee80211_sta_set_rx_nss(sta); if (!ref) - return; + goto out; rcu_read_lock(); @@ -59,6 +59,7 @@ void rate_control_rate_init(struct sta_info *sta) priv_sta); spin_unlock_bh(&sta->rate_ctrl_lock); rcu_read_unlock(); +out: set_sta_flag(sta, WLAN_STA_RATE_CONTROL); } That was my intent, anyway -- that NSS always got set before rate_control_rate_update() even if using HW rate control. > if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) > rate_control_rate_init(sta); > > /* inform drivers about changes */ > rate_control_rate_update(local, sband, sta, changed); > > Both will at least cause a call to ath11k_peer_assoc_prepare + > ath11k_wmi_send_peer_assoc_cmd but unfortunately the ath11k firmware hangs > afterwards. I think this would be OK.
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 13da2e8262ba..7dcf4bb896b5 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -3274,6 +3274,7 @@ static int ath11k_mac_copy_he_cap(struct ath11k *ar, switch (i) { case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_MESH_POINT: break; default: @@ -3314,6 +3315,61 @@ static int ath11k_mac_copy_he_cap(struct ath11k *ar, he_cap_elem->phy_cap_info[9] |= IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU; break; + case NL80211_IFTYPE_MESH_POINT: + he_cap_elem->mac_cap_info[0] &= + ~(IEEE80211_HE_MAC_CAP0_TWT_RES | + IEEE80211_HE_MAC_CAP0_TWT_REQ); + he_cap_elem->mac_cap_info[2] &= + ~(IEEE80211_HE_MAC_CAP2_TRS | + IEEE80211_HE_MAC_CAP2_BCAST_TWT | + IEEE80211_HE_MAC_CAP2_MU_CASCADING); + he_cap_elem->mac_cap_info[3] &= + ~(IEEE80211_HE_MAC_CAP3_FLEX_TWT_SCHED | + IEEE80211_HE_MAC_CAP2_BCAST_TWT | + IEEE80211_HE_MAC_CAP2_MU_CASCADING); + he_cap_elem->mac_cap_info[4] &= + ~(IEEE80211_HE_MAC_CAP4_BSRP_BQRP_A_MPDU_AGG | + IEEE80211_HE_MAC_CAP4_BQR); + he_cap_elem->mac_cap_info[5] &= + ~(IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECVITE_TRANSMISSION | + IEEE80211_HE_MAC_CAP5_UL_2x996_TONE_RU | + IEEE80211_HE_MAC_CAP5_PUNCTURED_SOUNDING | + IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX); + + he_cap_elem->phy_cap_info[2] &= + ~(IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO | + IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO); + he_cap_elem->phy_cap_info[3] &= + ~(IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA | + IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_MASK | + IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_MASK); + he_cap_elem->phy_cap_info[4] &= + ~IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER; + he_cap_elem->phy_cap_info[5] &= + ~IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK; + he_cap_elem->phy_cap_info[6] &= + ~(IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU | + IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB | + IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB | + IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO); + he_cap_elem->phy_cap_info[7] &= + ~(IEEE80211_HE_PHY_CAP7_SRP_BASED_SR | + IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR | + IEEE80211_HE_PHY_CAP7_STBC_TX_ABOVE_80MHZ | + IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ); + he_cap_elem->phy_cap_info[8] &= + ~(IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI | + IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G | + IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU | + IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU); + he_cap_elem->phy_cap_info[9] &= + ~(IEEE80211_HE_PHY_CAP9_LONGER_THAN_16_SIGB_OFDM_SYM | + IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK | + IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU | + IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU | + IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB | + IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB); + break; } he_cap->he_mcs_nss_supp.rx_mcs_80 =