mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-24 21:02:35 +00:00
135 lines
5.1 KiB
Diff
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
|
|
|