wifi: ath12k: Prevent multicast duplication for dynamic VLAN
authorMuna Sinada <muna.sinada@oss.qualcomm.com>
Thu, 24 Apr 2025 22:14:04 +0000 (15:14 -0700)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Fri, 16 May 2025 19:38:56 +0000 (12:38 -0700)
Since dynamic VLAN traffic is software encrypted and encapsulated,
mac80211 handles the duplication on each link for MLO dynamic VLAN
multicast.

Currently in ath12k_mac_op_tx(), all multicast frames are duplicated
and are assigned a mcbc_gsn. This is causing dynamic VLAN multicast
traffic to be dropped in hardware.

Prevent dynamic VLAN multicast traffic from being duplicated again in
the driver. Check if incoming packet is a dynamic VLAN packet and
avoid defaulting to multicast conditional.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3

Signed-off-by: Muna Sinada <muna.sinada@oss.qualcomm.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Link: https://patch.msgid.link/20250424221404.1262597-1-muna.sinada@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath12k/mac.c

index 0fb4b7bc845b9320d9c4cf804351b2739369b895..aea03a96bdc933857362468876dfb8e5878302cd 100644 (file)
@@ -7485,6 +7485,7 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw,
        struct ath12k_peer *peer;
        unsigned long links_map;
        bool is_mcast = false;
+       bool is_dvlan = false;
        struct ethhdr *eth;
        bool is_prb_rsp;
        u16 mcbc_gsn;
@@ -7550,7 +7551,14 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw,
        if (vif->type == NL80211_IFTYPE_AP && vif->p2p)
                ath12k_mac_add_p2p_noa_ie(ar, vif, skb, is_prb_rsp);
 
-       if (!vif->valid_links || !is_mcast ||
+       /* Checking if it is a DVLAN frame */
+       if (!test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) &&
+           !(skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) &&
+           !(skb_cb->flags & ATH12K_SKB_CIPHER_SET) &&
+           ieee80211_has_protected(hdr->frame_control))
+               is_dvlan = true;
+
+       if (!vif->valid_links || !is_mcast || is_dvlan ||
            test_bit(ATH12K_FLAG_RAW_MODE, &ar->ab->dev_flags)) {
                ret = ath12k_dp_tx(ar, arvif, skb, false, 0, is_mcast);
                if (unlikely(ret)) {