wlan-ap-Telecominfraproject/feeds/ipq95xx/mac80211/patches/qca/641-0003-ath12k-fix-4addr-multicast-packet-tx.patch
John Crispin b9b03a6e38 ipq95xx: add Qualcomm wifi-7 support
Signed-off-by: John Crispin <john@phrozen.org>
2023-04-10 14:25:48 +02:00

135 lines
5.1 KiB
Diff

From c90451a158219231d1611a52112b677bec8f7079 Mon Sep 17 00:00:00 2001
From: Thiraviyam Mariyappan <quic_tmariyap@quicinc.com>
Date: Mon, 27 Jun 2022 11:43:42 +0530
Subject: [PATCH] ath12k: fix 4addr multicast packet tx
In 4addr, AP wired backbone to STA wired backbone ping fails due to ARP
request not getting answered. Here 4addr ARP multicast packet is sent in
3addr, so that 4addr STA not honouring the 3addr ARP multicast packet.
Fix this issue by sending out multicast packet in 4addr format, firmware
expects peer meta flag instead of vdev meta flag in Tx descriptor.
Signed-off-by: Thiraviyam Mariyappan <quic_tmariyap@quicinc.com>
Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
---
drivers/net/wireless/ath/ath12k/core.h | 1 +
drivers/net/wireless/ath/ath12k/dp_tx.c | 12 ++++++++++--
drivers/net/wireless/ath/ath12k/dp_tx.h | 2 +-
drivers/net/wireless/ath/ath12k/mac.c | 5 ++++-
drivers/net/wireless/ath/ath12k/peer.c | 13 +++++++++++++
5 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
index c7c9cc5..1d9d94e 100644
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -487,6 +487,7 @@ struct ath12k_sta {
bool aggr_mode;
#endif
bool use_4addr_set;
+ u16 tcl_metadata;
};
#define ATH12K_HALF_20MHZ_BW 10
diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c
index 862f261..fd5d675 100644
--- a/drivers/net/wireless/ath/ath12k/dp_tx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_tx.c
@@ -122,7 +122,7 @@ static void ath12k_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab, void *cmd,
}
int ath12k_dp_tx(struct ath12k *ar, struct ath12k_vif *arvif,
- struct sk_buff *skb)
+ struct ath12k_sta *arsta, struct sk_buff *skb)
{
struct ath12k_base *ab = ar->ab;
struct ath12k_dp *dp = &ab->dp;
@@ -175,7 +175,15 @@ tcl_ring_sel:
return -ENOMEM;
ti.bank_id = arvif->bank_id;
- ti.meta_data_flags = arvif->tcl_metadata;
+
+ if (ieee80211_has_a4(hdr->frame_control) &&
+ is_multicast_ether_addr(hdr->addr3) && arsta &&
+ arsta->use_4addr_set) {
+ ti.meta_data_flags = arsta->tcl_metadata;
+ ti.flags0 |= FIELD_PREP(HAL_TCL_DATA_CMD_INFO2_TO_FW, 1);
+ } else {
+ ti.meta_data_flags = arvif->tcl_metadata;
+ }
ti.encap_type = ath12k_dp_tx_get_encap_type(arvif, skb);
ti.addr_search_flags = arvif->hal_addr_search_flags;
diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.h b/drivers/net/wireless/ath/ath12k/dp_tx.h
index 422024e..98f7704 100644
--- a/drivers/net/wireless/ath/ath12k/dp_tx.h
+++ b/drivers/net/wireless/ath/ath12k/dp_tx.h
@@ -18,7 +18,7 @@ struct ath12k_dp_htt_wbm_tx_status {
void ath12k_dp_tx_update_txcompl(struct ath12k *ar, struct hal_tx_status *ts);
int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab);
int ath12k_dp_tx(struct ath12k *ar, struct ath12k_vif *arvif,
- struct sk_buff *skb);
+ struct ath12k_sta *arsta, struct sk_buff *skb);
void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id);
int ath12k_dp_tx_send_reo_cmd(struct ath12k_base *ab, struct dp_rx_tid *rx_tid,
enum hal_reo_cmd_type type,
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index d07e811..5e7e16c 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -6234,6 +6234,7 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw,
struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_key_conf *key = info->control.hw_key;
+ struct ath12k_sta *arsta = NULL;
u32 info_flags = info->flags;
bool is_prb_rsp;
int ret;
@@ -6258,8 +6259,10 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw,
}
return;
}
+ if (control->sta)
+ arsta = (struct ath12k_sta *)control->sta->drv_priv;
- ret = ath12k_dp_tx(ar, arvif, skb);
+ ret = ath12k_dp_tx(ar, arvif, arsta, skb);
if (ret) {
ath12k_warn(ar->ab, "failed to transmit frame %d\n", ret);
ieee80211_free_txskb(ar->hw, skb);
diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c
index ab0ea37..bfb4732 100644
--- a/drivers/net/wireless/ath/ath12k/peer.c
+++ b/drivers/net/wireless/ath/ath12k/peer.c
@@ -266,6 +266,8 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_vif *arvif,
struct ieee80211_sta *sta, struct peer_create_params *param)
{
struct ath12k_peer *peer;
+ struct ath12k_sta *arsta;
+
int ret;
lockdep_assert_held(&ar->conf_mutex);
@@ -334,6 +336,17 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_vif *arvif,
peer->sec_type = HAL_ENCRYPT_TYPE_OPEN;
peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN;
+ if (sta) {
+ arsta = (struct ath12k_sta *)sta->drv_priv;
+ arsta->tcl_metadata |= FIELD_PREP(HTT_TCL_META_DATA_TYPE, 0) |
+ FIELD_PREP(HTT_TCL_META_DATA_PEER_ID,
+ peer->peer_id);
+
+ /* set HTT extension valid bit to 0 by default */
+ arsta->tcl_metadata &= ~HTT_TCL_META_DATA_VALID_HTT;
+ }
+
+
ar->num_peers++;
spin_unlock_bh(&ar->ab->base_lock);
--
2.7.4