mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-16 04:13:31 +00:00
124 lines
4.5 KiB
Diff
124 lines
4.5 KiB
Diff
From e20cfa3b62aeb1b5fc5ffa86a007af97f9954767 Mon Sep 17 00:00:00 2001
|
|
From: Karthikeyan Periyasamy <periyasa@codeaurora.org>
|
|
Date: Wed, 21 Jul 2021 00:31:47 +0300
|
|
Subject: [PATCH 003/120] ath11k: 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.
|
|
|
|
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01641-QCAHKSWPL_SILICONZ-1
|
|
|
|
Signed-off-by: Karthikeyan Periyasamy <periyasa@codeaurora.org>
|
|
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
|
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
|
Link: https://lore.kernel.org/r/20210720213147.90042-2-jouni@codeaurora.org
|
|
---
|
|
drivers/net/wireless/ath/ath11k/core.h | 1 +
|
|
drivers/net/wireless/ath/ath11k/dp_tx.c | 12 ++++++++++--
|
|
drivers/net/wireless/ath/ath11k/dp_tx.h | 2 +-
|
|
drivers/net/wireless/ath/ath11k/mac.c | 6 +++++-
|
|
drivers/net/wireless/ath/ath11k/peer.c | 11 +++++++++++
|
|
5 files changed, 28 insertions(+), 4 deletions(-)
|
|
|
|
--- a/drivers/net/wireless/ath/ath11k/core.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
|
@@ -377,6 +377,7 @@ struct ath11k_sta {
|
|
#endif
|
|
|
|
bool use_4addr_set;
|
|
+ u16 tcl_metadata;
|
|
};
|
|
|
|
#define ATH11K_MIN_5G_FREQ 4150
|
|
--- a/drivers/net/wireless/ath/ath11k/dp_tx.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
|
|
@@ -78,7 +78,7 @@ enum hal_encrypt_type ath11k_dp_tx_get_e
|
|
}
|
|
|
|
int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
|
|
- struct sk_buff *skb)
|
|
+ struct ath11k_sta *arsta, struct sk_buff *skb)
|
|
{
|
|
struct ath11k_base *ab = ar->ab;
|
|
struct ath11k_dp *dp = &ab->dp;
|
|
@@ -145,7 +145,15 @@ tcl_ring_sel:
|
|
FIELD_PREP(DP_TX_DESC_ID_MSDU_ID, ret) |
|
|
FIELD_PREP(DP_TX_DESC_ID_POOL_ID, pool_id);
|
|
ti.encap_type = ath11k_dp_tx_get_encap_type(arvif, skb);
|
|
- 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_INFO1_TO_FW, 1);
|
|
+ } else {
|
|
+ ti.meta_data_flags = arvif->tcl_metadata;
|
|
+ }
|
|
|
|
if (ti.encap_type == HAL_TCL_ENCAP_TYPE_RAW) {
|
|
if (skb_cb->flags & ATH11K_SKB_CIPHER_SET) {
|
|
--- a/drivers/net/wireless/ath/ath11k/dp_tx.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.h
|
|
@@ -17,7 +17,7 @@ struct ath11k_dp_htt_wbm_tx_status {
|
|
|
|
int ath11k_dp_tx_htt_h2t_ver_req_msg(struct ath11k_base *ab);
|
|
int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
|
|
- struct sk_buff *skb);
|
|
+ struct ath11k_sta *arsta, struct sk_buff *skb);
|
|
void ath11k_dp_tx_completion_handler(struct ath11k_base *ab, int ring_id);
|
|
int ath11k_dp_tx_send_reo_cmd(struct ath11k_base *ab, struct dp_rx_tid *rx_tid,
|
|
enum hal_reo_cmd_type type,
|
|
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
|
@@ -4356,6 +4356,7 @@ static void ath11k_mac_op_tx(struct ieee
|
|
struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
|
|
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
|
struct ieee80211_key_conf *key = info->control.hw_key;
|
|
+ struct ath11k_sta *arsta = NULL;
|
|
u32 info_flags = info->flags;
|
|
bool is_prb_rsp;
|
|
int ret;
|
|
@@ -4381,7 +4382,10 @@ static void ath11k_mac_op_tx(struct ieee
|
|
return;
|
|
}
|
|
|
|
- ret = ath11k_dp_tx(ar, arvif, skb);
|
|
+ if (control->sta)
|
|
+ arsta = (struct ath11k_sta *)control->sta->drv_priv;
|
|
+
|
|
+ ret = ath11k_dp_tx(ar, arvif, arsta, skb);
|
|
if (ret) {
|
|
ath11k_warn(ar->ab, "failed to transmit frame %d\n", ret);
|
|
ieee80211_free_txskb(ar->hw, skb);
|
|
--- a/drivers/net/wireless/ath/ath11k/peer.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/peer.c
|
|
@@ -251,6 +251,7 @@ int ath11k_peer_create(struct ath11k *ar
|
|
struct ieee80211_sta *sta, struct peer_create_params *param)
|
|
{
|
|
struct ath11k_peer *peer;
|
|
+ struct ath11k_sta *arsta;
|
|
int ret;
|
|
|
|
lockdep_assert_held(&ar->conf_mutex);
|
|
@@ -319,6 +320,16 @@ int ath11k_peer_create(struct ath11k *ar
|
|
peer->sec_type = HAL_ENCRYPT_TYPE_OPEN;
|
|
peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN;
|
|
|
|
+ if (sta) {
|
|
+ arsta = (struct ath11k_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);
|