mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-18 09:51:26 +00:00
This series is based on * 2020-07-10 ipq6018-ilq-11-0_qca_oem-034672b0676c37b1f4519e5720e18e95fe6236ef Add support for * qsdk kernel/v4.4 * qsdk ethernet subsystem * v5.7 ath11k backport + QualComm staging patches (wlan_ap_1.0) * ath11k-firmware * hostapd/iw/... Feature support * full boot, system detection * sysupgrade to nand * HE support via latest hostapd * driver support for usb, crypto, hwmon, cpufreq, ... Missing * NSS/HW flow offloading - FW blob is not redistributable Using the qsdk v4.4 is an intermediate solution while the vanilla is being tested. Vanilla kernel is almost on feature par. Work has already started to upstream the ethernet and switch drivers. Once complete the target will be fully upstream. Signed-off-by: John Crispin <john@phrozen.org>
196 lines
6.4 KiB
Diff
196 lines
6.4 KiB
Diff
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
|
@@ -909,6 +909,13 @@ static void ath11k_peer_assoc_h_ht(struc
|
|
arg->bw_40 = true;
|
|
arg->peer_rate_caps |= WMI_HOST_RC_CW40_FLAG;
|
|
}
|
|
+ /* As firmware handles this two flags (IEEE80211_HT_CAP_SGI_20
|
|
+ * and IEEE80211_HT_CAP_SGI_40) for enabling SGI, we reset
|
|
+ * both flags if guard interval is Default GI
|
|
+ */
|
|
+ if (arvif->bitrate_mask.control[band].gi == NL80211_TXRATE_DEFAULT_GI)
|
|
+ arg->peer_ht_caps &= ~(IEEE80211_HT_CAP_SGI_20 |
|
|
+ IEEE80211_HT_CAP_SGI_40);
|
|
|
|
if (arvif->bitrate_mask.control[band].gi != NL80211_TXRATE_FORCE_LGI) {
|
|
if (ht_cap->cap & (IEEE80211_HT_CAP_SGI_20 |
|
|
@@ -1309,7 +1316,11 @@ static void ath11k_peer_assoc_h_he(struc
|
|
for (i = 0, max_nss = 0, he_mcs = 0; i < NL80211_HE_NSS_MAX; i++) {
|
|
he_mcs = __le16_to_cpu(he_tx_mcs) >> (2 * i) & 3;
|
|
|
|
- if (he_mcs != IEEE80211_HE_MCS_NOT_SUPPORTED &&
|
|
+ /* In case of fixed rates, MCS Range in he_tx_mcs might have
|
|
+ * unsupported range, with he_mcs_mask set, so check either of them
|
|
+ * to find nss.
|
|
+ */
|
|
+ if (he_mcs != IEEE80211_HE_MCS_NOT_SUPPORTED ||
|
|
he_mcs_mask[i])
|
|
max_nss = i + 1;
|
|
}
|
|
@@ -2762,6 +2773,10 @@ ath11k_mac_set_peer_vht_fixed_rate(struc
|
|
return -EINVAL;
|
|
}
|
|
|
|
+ /* Avoid updating invalid nss as fixed rate*/
|
|
+ if (nss > sta->rx_nss)
|
|
+ return -EINVAL;
|
|
+
|
|
ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
|
|
"Setting Fixed VHT Rate for peer %pM. Device will not switch to any other selected rates",
|
|
sta->addr);
|
|
@@ -2808,6 +2823,11 @@ ath11k_mac_set_peer_he_fixed_rate(struct
|
|
return -EINVAL;
|
|
}
|
|
|
|
+ /* Avoid updating invalid nss as fixed rate*/
|
|
+ if (nss > sta->rx_nss)
|
|
+ return -EINVAL;
|
|
+
|
|
+
|
|
ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
|
|
"Setting Fixed HE Rate for peer %pM. Device will not switch to any other selected rates",
|
|
sta->addr);
|
|
@@ -2837,7 +2857,7 @@ static int ath11k_station_assoc(struct a
|
|
struct cfg80211_chan_def def;
|
|
enum nl80211_band band;
|
|
struct cfg80211_bitrate_mask *mask;
|
|
- u8 num_vht_rates;
|
|
+ u8 num_vht_rates, num_he_rates;
|
|
|
|
lockdep_assert_held(&ar->conf_mutex);
|
|
|
|
@@ -2863,9 +2883,10 @@ static int ath11k_station_assoc(struct a
|
|
}
|
|
|
|
num_vht_rates = ath11k_mac_bitrate_mask_num_vht_rates(ar, band, mask);
|
|
+ num_he_rates = ath11k_mac_bitrate_mask_num_he_rates(ar, band, mask);
|
|
|
|
- /* If single VHT rate is configured (by set_bitrate_mask()),
|
|
- * peer_assoc will disable VHT. This is now enabled by a peer specific
|
|
+ /* If single VHT/HE rate is configured (by set_bitrate_mask()),
|
|
+ * peer_assoc will disable VHT/HE. This is now enabled by a peer specific
|
|
* fixed param.
|
|
* Note that all other rates and NSS will be disabled for this peer.
|
|
*/
|
|
@@ -2874,6 +2895,11 @@ static int ath11k_station_assoc(struct a
|
|
band);
|
|
if (ret)
|
|
return ret;
|
|
+ } else if (sta->he_cap.has_he && num_he_rates == 1) {
|
|
+ ret = ath11k_mac_set_peer_he_fixed_rate(arvif, sta, mask,
|
|
+ band);
|
|
+ if (ret)
|
|
+ return ret;
|
|
}
|
|
|
|
/* Re-assoc is run only to update supported rates for given station. It
|
|
@@ -3036,10 +3062,21 @@ static void ath11k_sta_rc_update_wk(stru
|
|
ath11k_mac_set_peer_he_fixed_rate(arvif, sta, mask,
|
|
band);
|
|
} else {
|
|
- /* If the peer is non-VHT or no fixed VHT rate
|
|
+ /* If the peer is non-VHT/HE or no fixed VHT/HE rate
|
|
* is provided in the new bitrate mask we set the
|
|
- * other rates using peer_assoc command.
|
|
+ * other rates using peer_assoc command. Also clear
|
|
+ * the peer fixed rate settings as it has higher proprity
|
|
+ * than peer assoc
|
|
*/
|
|
+ err = ath11k_wmi_set_peer_param(ar, sta->addr,
|
|
+ arvif->vdev_id,
|
|
+ WMI_PEER_PARAM_FIXED_RATE,
|
|
+ WMI_FIXED_RATE_NONE);
|
|
+ if (err)
|
|
+ ath11k_warn(ar->ab,
|
|
+ "failed to disable peer fixed rate for STA %pM ret %d\n",
|
|
+ sta->addr, err);
|
|
+
|
|
ath11k_peer_assoc_prepare(ar, arvif->vif, sta,
|
|
&peer_arg, true);
|
|
|
|
@@ -4498,6 +4535,7 @@ static int ath11k_mac_op_add_interface(s
|
|
|
|
for (i = 0; i < ARRAY_SIZE(arvif->bitrate_mask.control); i++) {
|
|
arvif->bitrate_mask.control[i].legacy = 0xffffffff;
|
|
+ arvif->bitrate_mask.control[i].gi = NL80211_TXRATE_FORCE_SGI;
|
|
memset(arvif->bitrate_mask.control[i].ht_mcs, 0xff,
|
|
sizeof(arvif->bitrate_mask.control[i].ht_mcs));
|
|
memset(arvif->bitrate_mask.control[i].vht_mcs, 0xff,
|
|
@@ -5762,6 +5800,53 @@ static void ath11k_mac_disable_peer_fixe
|
|
sta->addr, ret);
|
|
}
|
|
|
|
+static bool
|
|
+ath11k_mac_validate_vht_he_fixed_rate_settings(struct ath11k *ar, enum nl80211_band band,
|
|
+ const struct cfg80211_bitrate_mask *mask)
|
|
+{
|
|
+ bool he_fixed_rate = false, vht_fixed_rate = false;
|
|
+ struct ath11k_peer *peer, *tmp;
|
|
+ const u16 *vht_mcs_mask, *he_mcs_mask;
|
|
+ u8 vht_nss, he_nss;
|
|
+ bool ret = true;
|
|
+
|
|
+ vht_mcs_mask = mask->control[band].vht_mcs;
|
|
+ he_mcs_mask = mask->control[band].he_mcs;
|
|
+
|
|
+ if (ath11k_mac_bitrate_mask_num_vht_rates(ar, band, mask) == 1)
|
|
+ vht_fixed_rate = true;
|
|
+
|
|
+ if (ath11k_mac_bitrate_mask_num_he_rates(ar, band, mask) == 1)
|
|
+ he_fixed_rate = true;
|
|
+
|
|
+ if(!vht_fixed_rate && !he_fixed_rate)
|
|
+ return true;
|
|
+
|
|
+ vht_nss = ath11k_mac_max_vht_nss(vht_mcs_mask);
|
|
+ he_nss = ath11k_mac_max_he_nss(he_mcs_mask);
|
|
+
|
|
+ rcu_read_lock();
|
|
+ spin_lock_bh(&ar->ab->base_lock);
|
|
+ list_for_each_entry_safe(peer, tmp, &ar->ab->peers, list) {
|
|
+ if (peer->sta) {
|
|
+ if (vht_fixed_rate && (!peer->sta->vht_cap.vht_supported ||
|
|
+ peer->sta->rx_nss < vht_nss)) {
|
|
+ ret = false;
|
|
+ goto exit;
|
|
+ }
|
|
+ if (he_fixed_rate && (!peer->sta->he_cap.has_he ||
|
|
+ peer->sta->rx_nss < he_nss)) {
|
|
+ ret = false;
|
|
+ goto exit;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+exit:
|
|
+ spin_unlock_bh(&ar->ab->base_lock);
|
|
+ rcu_read_unlock();
|
|
+ return ret;
|
|
+}
|
|
+
|
|
static int
|
|
ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
|
|
struct ieee80211_vif *vif,
|
|
@@ -5824,6 +5909,11 @@ ath11k_mac_op_set_bitrate_mask(struct ie
|
|
nss = single_nss;
|
|
} else {
|
|
rate = WMI_FIXED_RATE_NONE;
|
|
+
|
|
+ if (!ath11k_mac_validate_vht_he_fixed_rate_settings(ar, band, mask))
|
|
+ ath11k_warn(ar->ab,
|
|
+ "could not update fixed rate settings to all peers due to mcs/nss incompaitiblity\n");
|
|
+
|
|
nss = min_t(u32, ar->num_tx_chains,
|
|
max(max(ath11k_mac_max_ht_nss(ht_mcs_mask),
|
|
ath11k_mac_max_vht_nss(vht_mcs_mask)),
|
|
@@ -5872,10 +5962,6 @@ ath11k_mac_op_set_bitrate_mask(struct ie
|
|
return -EINVAL;
|
|
}
|
|
|
|
- ieee80211_iterate_stations_atomic(ar->hw,
|
|
- ath11k_mac_disable_peer_fixed_rate,
|
|
- arvif);
|
|
-
|
|
mutex_lock(&ar->conf_mutex);
|
|
|
|
arvif->bitrate_mask = *mask;
|