wlan-ap-Telecominfraproject/feeds/wifi-ax/mac80211/patches/qca/149-ath11k-fix-4addr-tx-failure-AP-STA-modes.patch
John Crispin 528a778e38 open-converged-wireless: Import 21.02 based uCentral tree
Signed-off-by: John Crispin <john@phrozen.org>
2021-03-25 12:19:47 +01:00

148 lines
4.7 KiB
Diff

--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -379,6 +379,7 @@ struct ath11k_sta {
enum hal_pn_type pn_type;
struct work_struct update_wk;
+ struct work_struct use_4addr_wk;
struct rate_info txrate;
struct rate_info last_txrate;
u64 rx_duration;
@@ -391,6 +392,8 @@ struct ath11k_sta {
/* protected by conf_mutex */
bool aggr_mode;
#endif
+
+ bool use_4addr_set;
};
#define ATH11K_MIN_5G_FREQ 4150
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -3591,6 +3591,31 @@ static void ath11k_sta_rc_update_wk(stru
mutex_unlock(&ar->conf_mutex);
}
+static void ath11k_sta_use_4addr_wk(struct work_struct *wk)
+{
+ struct ath11k *ar;
+ struct ath11k_vif *arvif;
+ struct ath11k_sta *arsta;
+ struct ieee80211_sta *sta;
+ int ret = 0;
+
+ arsta = container_of(wk, struct ath11k_sta, use_4addr_wk);
+ sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
+ arvif = arsta->arvif;
+ ar = arvif->ar;
+
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
+ "setting USE_4ADDR for STA %pM\n", sta->addr);
+
+ ret = ath11k_wmi_set_peer_param(ar, sta->addr,
+ arvif->vdev_id,
+ WMI_PEER_USE_4ADDR, 1);
+
+ if (ret)
+ ath11k_warn(ar->ab, "failed to set 4addr for STA %pM: %d\n",
+ sta->addr, ret);
+}
+
static int ath11k_mac_inc_num_stations(struct ath11k_vif *arvif,
struct ieee80211_sta *sta)
{
@@ -3702,12 +3727,15 @@ static int ath11k_mac_station_add(struct
}
}
- if (ieee80211_vif_is_mesh(vif)) {
+ if (ieee80211_vif_is_mesh(vif) ||
+ (vif->type == NL80211_IFTYPE_STATION && vif->use_4addr)) {
+ ath11k_dbg(ab, ATH11K_DBG_MAC,
+ "setting USE_4ADDR for peer %pM\n", sta->addr);
ret = ath11k_wmi_set_peer_param(ar, sta->addr,
arvif->vdev_id,
WMI_PEER_USE_4ADDR, 1);
if (ret) {
- ath11k_warn(ab, "failed to STA %pM 4addr capability: %d\n",
+ ath11k_warn(ab, "failed to set STA %pM 4addr capability: %d\n",
sta->addr, ret);
goto free_tx_stats;
}
@@ -3758,8 +3786,10 @@ static int ath11k_mac_op_sta_state(struc
/* cancel must be done outside the mutex to avoid deadlock */
if ((old_state == IEEE80211_STA_NONE &&
- new_state == IEEE80211_STA_NOTEXIST))
+ new_state == IEEE80211_STA_NOTEXIST)) {
cancel_work_sync(&arsta->update_wk);
+ cancel_work_sync(&arsta->use_4addr_wk);
+ }
mutex_lock(&ar->conf_mutex);
@@ -3768,6 +3798,7 @@ static int ath11k_mac_op_sta_state(struc
memset(arsta, 0, sizeof(*arsta));
arsta->arvif = arvif;
INIT_WORK(&arsta->update_wk, ath11k_sta_rc_update_wk);
+ INIT_WORK(&arsta->use_4addr_wk, ath11k_sta_use_4addr_wk);
ret = ath11k_mac_station_add(ar, vif, sta);
if (ret)
@@ -3865,6 +3896,19 @@ out:
return ret;
}
+static void ath11k_mac_op_sta_use_4addr(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ struct ath11k *ar = hw->priv;
+ struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
+
+ if (!arsta->use_4addr_set) {
+ ieee80211_queue_work(ar->hw, &arsta->use_4addr_wk);
+ arsta->use_4addr_set = true;
+ }
+}
+
static void ath11k_mac_op_sta_rc_update(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
@@ -5115,6 +5159,7 @@ static int ath11k_mac_op_add_interface(s
int i;
int ret, free_err;
int bit;
+ bool use_4addr = false;
vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
@@ -5165,6 +5210,7 @@ static int ath11k_mac_op_add_interface(s
case NL80211_IFTYPE_UNSPECIFIED:
case NL80211_IFTYPE_STATION:
arvif->vdev_type = WMI_VDEV_TYPE_STA;
+ use_4addr = vif->use_4addr;
break;
case NL80211_IFTYPE_MESH_POINT:
arvif->vdev_subtype = WMI_VDEV_SUBTYPE_MESH_11S;
@@ -5181,9 +5227,9 @@ static int ath11k_mac_op_add_interface(s
break;
}
- ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac add interface id %d type %d subtype %d map %llx\n",
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac add interface id %d type %d subtype %d map %llx %s\n",
arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype,
- ab->free_vdev_map);
+ ab->free_vdev_map, (use_4addr ? "4addr" : " "));
vif->cab_queue = arvif->vdev_id % (ATH11K_HW_MAX_QUEUES - 1);
for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++)
@@ -6967,6 +7013,7 @@ static const struct ieee80211_ops ath11k
.cancel_hw_scan = ath11k_mac_op_cancel_hw_scan,
.set_key = ath11k_mac_op_set_key,
.sta_state = ath11k_mac_op_sta_state,
+ .sta_use_4addr = ath11k_mac_op_sta_use_4addr,
.sta_set_txpwr = ath11k_mac_op_sta_set_txpwr,
.sta_rc_update = ath11k_mac_op_sta_rc_update,
.conf_tx = ath11k_mac_op_conf_tx,