[PATCH ath12k-ng 05/12] wifi: ath12k: Move ieee80211_ops callback to the arch specific module
Ripan Deuri
quic_rdeuri at quicinc.com
Mon Nov 3 03:21:04 PST 2025
Move the ieee80211_ops Tx callback to the architecture-specific module
to avoid additional indirections caused by the common Tx function calling
the architecture-specific Tx functions via ops.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-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: Ripan Deuri <quic_rdeuri at quicinc.com>
---
drivers/net/wireless/ath/ath12k/core.c | 1 +
drivers/net/wireless/ath/ath12k/mac.c | 231 ++----------------
drivers/net/wireless/ath/ath12k/mac.h | 15 +-
drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 2 +
drivers/net/wireless/ath/ath12k/wifi7/hw.c | 208 +++++++++++++++-
5 files changed, 237 insertions(+), 220 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
index 3bba9c9a1a9b..4439f0a98ec4 100644
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -28,6 +28,7 @@
unsigned int ath12k_debug_mask;
module_param_named(debug_mask, ath12k_debug_mask, uint, 0644);
MODULE_PARM_DESC(debug_mask, "Debugging mask");
+EXPORT_SYMBOL(ath12k_debug_mask);
bool ath12k_ftm_mode;
module_param_named(ftm_mode, ath12k_ftm_mode, bool, 0444);
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index c40c55344e64..d04606559cdf 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -8833,8 +8833,8 @@ static void ath12k_mgmt_over_wmi_tx_work(struct wiphy *wiphy, struct wiphy_work
}
}
-static int ath12k_mac_mgmt_tx(struct ath12k *ar, struct sk_buff *skb,
- bool is_prb_rsp)
+int ath12k_mac_mgmt_tx(struct ath12k *ar, struct sk_buff *skb,
+ bool is_prb_rsp)
{
struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue;
@@ -8864,11 +8864,12 @@ static int ath12k_mac_mgmt_tx(struct ath12k *ar, struct sk_buff *skb,
return 0;
}
+EXPORT_SYMBOL(ath12k_mac_mgmt_tx);
-static void ath12k_mac_add_p2p_noa_ie(struct ath12k *ar,
- struct ieee80211_vif *vif,
- struct sk_buff *skb,
- bool is_prb_rsp)
+void ath12k_mac_add_p2p_noa_ie(struct ath12k *ar,
+ struct ieee80211_vif *vif,
+ struct sk_buff *skb,
+ bool is_prb_rsp)
{
struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif);
@@ -8885,11 +8886,12 @@ static void ath12k_mac_add_p2p_noa_ie(struct ath12k *ar,
spin_unlock_bh(&ar->data_lock);
}
+EXPORT_SYMBOL(ath12k_mac_add_p2p_noa_ie);
/* Note: called under rcu_read_lock() */
-static void ath12k_mlo_mcast_update_tx_link_address(struct ieee80211_vif *vif,
- u8 link_id, struct sk_buff *skb,
- u32 info_flags)
+void ath12k_mlo_mcast_update_tx_link_address(struct ieee80211_vif *vif,
+ u8 link_id, struct sk_buff *skb,
+ u32 info_flags)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_bss_conf *bss_conf;
@@ -8901,10 +8903,11 @@ static void ath12k_mlo_mcast_update_tx_link_address(struct ieee80211_vif *vif,
if (bss_conf)
ether_addr_copy(hdr->addr2, bss_conf->addr);
}
+EXPORT_SYMBOL(ath12k_mlo_mcast_update_tx_link_address);
/* Note: called under rcu_read_lock() */
-static u8 ath12k_mac_get_tx_link(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
- u8 link, struct sk_buff *skb, u32 info_flags)
+u8 ath12k_mac_get_tx_link(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
+ u8 link, struct sk_buff *skb, u32 info_flags)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif);
@@ -8999,211 +9002,7 @@ static u8 ath12k_mac_get_tx_link(struct ieee80211_sta *sta, struct ieee80211_vif
return link;
}
-
-/* Note: called under rcu_read_lock() */
-void ath12k_mac_op_tx(struct ieee80211_hw *hw,
- struct ieee80211_tx_control *control,
- struct sk_buff *skb)
-{
- struct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB(skb);
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct ieee80211_vif *vif = info->control.vif;
- struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif);
- struct ath12k_link_vif *arvif = &ahvif->deflink;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- struct ieee80211_key_conf *key = info->control.hw_key;
- struct ieee80211_sta *sta = control->sta;
- struct ath12k_link_vif *tmp_arvif;
- u32 info_flags = info->flags;
- struct sk_buff *msdu_copied;
- struct ath12k *ar, *tmp_ar;
- struct ath12k_pdev_dp *dp_pdev, *tmp_dp_pdev;
- struct ath12k_dp_link_peer *peer;
- unsigned long links_map;
- bool is_mcast = false;
- bool is_dvlan = false;
- struct ethhdr *eth;
- bool is_prb_rsp;
- u16 mcbc_gsn;
- u8 link_id;
- int ret;
- struct ath12k_dp *tmp_dp;
-
- if (ahvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {
- ieee80211_free_txskb(hw, skb);
- return;
- }
-
- link_id = u32_get_bits(info->control.flags, IEEE80211_TX_CTRL_MLO_LINK);
- memset(skb_cb, 0, sizeof(*skb_cb));
- skb_cb->vif = vif;
-
- if (key) {
- skb_cb->cipher = key->cipher;
- skb_cb->flags |= ATH12K_SKB_CIPHER_SET;
- }
-
- /* handle only for MLO case, use deflink for non MLO case */
- if (ieee80211_vif_is_mld(vif)) {
- link_id = ath12k_mac_get_tx_link(sta, vif, link_id, skb, info_flags);
- if (link_id >= IEEE80211_MLD_MAX_NUM_LINKS) {
- ieee80211_free_txskb(hw, skb);
- return;
- }
- } else {
- link_id = 0;
- }
-
- arvif = rcu_dereference(ahvif->link[link_id]);
- if (!arvif || !arvif->ar) {
- ath12k_warn(ahvif->ah, "failed to find arvif link id %u for frame transmission",
- link_id);
- ieee80211_free_txskb(hw, skb);
- return;
- }
-
- ar = arvif->ar;
- skb_cb->link_id = link_id;
- /* as skb_cb is common currently for dp and mgmt tx processing
- * set this in the common mac op tx function.
- */
- skb_cb->ar = ar;
- is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control);
-
- if (info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP) {
- eth = (struct ethhdr *)skb->data;
- is_mcast = is_multicast_ether_addr(eth->h_dest);
-
- skb_cb->flags |= ATH12K_SKB_HW_80211_ENCAP;
- } else if (ieee80211_is_mgmt(hdr->frame_control)) {
- if (sta && sta->mlo)
- skb_cb->flags |= ATH12K_SKB_MLO_STA;
-
- ret = ath12k_mac_mgmt_tx(ar, skb, is_prb_rsp);
- if (ret) {
- ath12k_warn(ar->ab, "failed to queue management frame %d\n",
- ret);
- ieee80211_free_txskb(hw, skb);
- }
- return;
- }
-
- if (!(info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP))
- is_mcast = is_multicast_ether_addr(hdr->addr1);
-
- /* This is case only for P2P_GO */
- if (vif->type == NL80211_IFTYPE_AP && vif->p2p)
- ath12k_mac_add_p2p_noa_ie(ar, vif, skb, is_prb_rsp);
-
- dp_pdev = ath12k_dp_to_pdev_dp(ar->ab->dp, ar->pdev_idx);
- if (!dp_pdev) {
- ieee80211_free_txskb(hw, skb);
- return;
- }
-
- /* 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 ||
- (skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) ||
- test_bit(ATH12K_FLAG_RAW_MODE, &ar->ab->dev_flags)) {
- ret = ath12k_wifi7_dp_tx(dp_pdev, arvif, skb, false, 0, is_mcast);
- if (unlikely(ret)) {
- ath12k_warn(ar->ab, "failed to transmit frame %d\n", ret);
- ieee80211_free_txskb(ar->ah->hw, skb);
- return;
- }
- } else {
- mcbc_gsn = atomic_inc_return(&ahvif->dp_vif.mcbc_gsn) & 0xfff;
-
- links_map = ahvif->links_map;
- for_each_set_bit(link_id, &links_map,
- IEEE80211_MLD_MAX_NUM_LINKS) {
- tmp_arvif = rcu_dereference(ahvif->link[link_id]);
- if (!tmp_arvif || !tmp_arvif->is_up)
- continue;
-
- tmp_ar = tmp_arvif->ar;
- tmp_dp_pdev = ath12k_dp_to_pdev_dp(tmp_ar->ab->dp,
- tmp_ar->pdev_idx);
- if (!tmp_dp_pdev)
- continue;
- msdu_copied = skb_copy(skb, GFP_ATOMIC);
- if (!msdu_copied) {
- ath12k_err(ar->ab,
- "skb copy failure link_id 0x%X vdevid 0x%X\n",
- link_id, tmp_arvif->vdev_id);
- continue;
- }
-
- ath12k_mlo_mcast_update_tx_link_address(vif, link_id,
- msdu_copied,
- info_flags);
-
- skb_cb = ATH12K_SKB_CB(msdu_copied);
- skb_cb->link_id = link_id;
- skb_cb->vif = vif;
- skb_cb->ar = tmp_ar;
-
- /* For open mode, skip peer find logic */
- if (unlikely(!ahvif->dp_vif.key_cipher))
- goto skip_peer_find;
-
- tmp_dp = ath12k_ab_to_dp(tmp_ar->ab);
- spin_lock_bh(&tmp_dp->dp_lock);
- peer = ath12k_dp_link_peer_find_by_addr(tmp_dp,
- tmp_arvif->bssid);
- if (!peer || !peer->dp_peer) {
- spin_unlock_bh(&tmp_dp->dp_lock);
- ath12k_warn(tmp_ar->ab,
- "failed to find peer for vdev_id 0x%X addr %pM link_map 0x%X\n",
- tmp_arvif->vdev_id, tmp_arvif->bssid,
- ahvif->links_map);
- dev_kfree_skb_any(msdu_copied);
- continue;
- }
-
- key = peer->dp_peer->keys[peer->dp_peer->mcast_keyidx];
- if (key) {
- skb_cb->cipher = key->cipher;
- skb_cb->flags |= ATH12K_SKB_CIPHER_SET;
-
- hdr = (struct ieee80211_hdr *)msdu_copied->data;
- if (!ieee80211_has_protected(hdr->frame_control))
- hdr->frame_control |=
- cpu_to_le16(IEEE80211_FCTL_PROTECTED);
- }
- spin_unlock_bh(&tmp_dp->dp_lock);
-
-skip_peer_find:
- ret = ath12k_wifi7_dp_tx(tmp_dp_pdev, tmp_arvif,
- msdu_copied, true, mcbc_gsn, is_mcast);
- if (unlikely(ret)) {
- if (ret == -ENOMEM) {
- /* Drops are expected during heavy multicast
- * frame flood. Print with debug log
- * level to avoid lot of console prints
- */
- ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
- "failed to transmit frame %d\n",
- ret);
- } else {
- ath12k_warn(ar->ab,
- "failed to transmit frame %d\n",
- ret);
- }
-
- dev_kfree_skb_any(msdu_copied);
- }
- }
- ieee80211_free_txskb(ar->ah->hw, skb);
- }
-}
-EXPORT_SYMBOL(ath12k_mac_op_tx);
+EXPORT_SYMBOL(ath12k_mac_get_tx_link);
void ath12k_mac_drain_tx(struct ath12k *ar)
{
diff --git a/drivers/net/wireless/ath/ath12k/mac.h b/drivers/net/wireless/ath/ath12k/mac.h
index f785a81860ce..0c73944f527b 100644
--- a/drivers/net/wireless/ath/ath12k/mac.h
+++ b/drivers/net/wireless/ath/ath12k/mac.h
@@ -191,9 +191,6 @@ void ath12k_mac_update_freq_range(struct ath12k *ar,
void ath12k_mac_fill_reg_tpc_info(struct ath12k *ar,
struct ath12k_link_vif *arvif,
struct ieee80211_chanctx_conf *ctx);
-void ath12k_mac_op_tx(struct ieee80211_hw *hw,
- struct ieee80211_tx_control *control,
- struct sk_buff *skb);
int ath12k_mac_op_start(struct ieee80211_hw *hw);
void ath12k_mac_op_stop(struct ieee80211_hw *hw, bool suspend);
void
@@ -317,4 +314,16 @@ int ath12k_mac_op_get_txpower(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
unsigned int link_id,
int *dbm);
+int ath12k_mac_mgmt_tx(struct ath12k *ar, struct sk_buff *skb,
+ bool is_prb_rsp);
+void ath12k_mac_add_p2p_noa_ie(struct ath12k *ar,
+ struct ieee80211_vif *vif,
+ struct sk_buff *skb,
+ bool is_prb_rsp);
+u8 ath12k_mac_get_tx_link(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
+ u8 link, struct sk_buff *skb, u32 info_flags);
+
+void ath12k_mlo_mcast_update_tx_link_address(struct ieee80211_vif *vif,
+ u8 link_id, struct sk_buff *skb,
+ u32 info_flags);
#endif
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c
index 737651341afc..7e16bc12e36a 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c
@@ -57,6 +57,7 @@ static int ath12k_wifi7_dp_prepare_htt_metadata(struct sk_buff *skb)
return 0;
}
+/* TODO: Remove the export once this file is built with wifi7 ko */
int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *arvif,
struct sk_buff *skb, bool gsn_valid, int mcbc_gsn,
bool is_mcast)
@@ -378,6 +379,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a
return ret;
}
+EXPORT_SYMBOL(ath12k_wifi7_dp_tx);
static void
ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab,
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
index 946771b96fb5..1f5dda73230d 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
@@ -24,6 +24,7 @@
#include "../debugfs_sta.h"
#include "../testmode.h"
#include "hal.h"
+#include "dp_tx.h"
static const guid_t wcn7850_uuid = GUID_INIT(0xf634f534, 0x6147, 0x11ec,
0x90, 0xd6, 0x02, 0x42,
@@ -653,8 +654,213 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
},
};
+/* Note: called under rcu_read_lock() */
+static void ath12k_wifi7_mac_op_tx(struct ieee80211_hw *hw,
+ struct ieee80211_tx_control *control,
+ struct sk_buff *skb)
+{
+ struct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB(skb);
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_vif *vif = info->control.vif;
+ struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif);
+ struct ath12k_link_vif *arvif = &ahvif->deflink;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct ieee80211_key_conf *key = info->control.hw_key;
+ struct ieee80211_sta *sta = control->sta;
+ struct ath12k_link_vif *tmp_arvif;
+ u32 info_flags = info->flags;
+ struct sk_buff *msdu_copied;
+ struct ath12k *ar, *tmp_ar;
+ struct ath12k_pdev_dp *dp_pdev, *tmp_dp_pdev;
+ struct ath12k_dp_link_peer *peer;
+ unsigned long links_map;
+ bool is_mcast = false;
+ bool is_dvlan = false;
+ struct ethhdr *eth;
+ bool is_prb_rsp;
+ u16 mcbc_gsn;
+ u8 link_id;
+ int ret;
+ struct ath12k_dp *tmp_dp;
+
+ if (ahvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {
+ ieee80211_free_txskb(hw, skb);
+ return;
+ }
+
+ link_id = u32_get_bits(info->control.flags, IEEE80211_TX_CTRL_MLO_LINK);
+ memset(skb_cb, 0, sizeof(*skb_cb));
+ skb_cb->vif = vif;
+
+ if (key) {
+ skb_cb->cipher = key->cipher;
+ skb_cb->flags |= ATH12K_SKB_CIPHER_SET;
+ }
+
+ /* handle only for MLO case, use deflink for non MLO case */
+ if (ieee80211_vif_is_mld(vif)) {
+ link_id = ath12k_mac_get_tx_link(sta, vif, link_id, skb, info_flags);
+ if (link_id >= IEEE80211_MLD_MAX_NUM_LINKS) {
+ ieee80211_free_txskb(hw, skb);
+ return;
+ }
+ } else {
+ link_id = 0;
+ }
+
+ arvif = rcu_dereference(ahvif->link[link_id]);
+ if (!arvif || !arvif->ar) {
+ ath12k_warn(ahvif->ah, "failed to find arvif link id %u for frame transmission",
+ link_id);
+ ieee80211_free_txskb(hw, skb);
+ return;
+ }
+
+ ar = arvif->ar;
+ skb_cb->link_id = link_id;
+ /*
+ * as skb_cb is common currently for dp and mgmt tx processing
+ * set this in the common mac op tx function.
+ */
+ skb_cb->ar = ar;
+ is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control);
+
+ if (info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP) {
+ eth = (struct ethhdr *)skb->data;
+ is_mcast = is_multicast_ether_addr(eth->h_dest);
+
+ skb_cb->flags |= ATH12K_SKB_HW_80211_ENCAP;
+ } else if (ieee80211_is_mgmt(hdr->frame_control)) {
+ if (sta && sta->mlo)
+ skb_cb->flags |= ATH12K_SKB_MLO_STA;
+
+ ret = ath12k_mac_mgmt_tx(ar, skb, is_prb_rsp);
+ if (ret) {
+ ath12k_warn(ar->ab, "failed to queue management frame %d\n",
+ ret);
+ ieee80211_free_txskb(hw, skb);
+ }
+ return;
+ }
+
+ if (!(info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP))
+ is_mcast = is_multicast_ether_addr(hdr->addr1);
+
+ /* This is case only for P2P_GO */
+ if (vif->type == NL80211_IFTYPE_AP && vif->p2p)
+ ath12k_mac_add_p2p_noa_ie(ar, vif, skb, is_prb_rsp);
+
+ dp_pdev = ath12k_dp_to_pdev_dp(ar->ab->dp, ar->pdev_idx);
+ if (!dp_pdev) {
+ ieee80211_free_txskb(hw, skb);
+ return;
+ }
+
+ /* 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 ||
+ (skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) ||
+ test_bit(ATH12K_FLAG_RAW_MODE, &ar->ab->dev_flags)) {
+ ret = ath12k_wifi7_dp_tx(dp_pdev, arvif, skb, false, 0, is_mcast);
+ if (unlikely(ret)) {
+ ath12k_warn(ar->ab, "failed to transmit frame %d\n", ret);
+ ieee80211_free_txskb(ar->ah->hw, skb);
+ return;
+ }
+ } else {
+ mcbc_gsn = atomic_inc_return(&ahvif->dp_vif.mcbc_gsn) & 0xfff;
+
+ links_map = ahvif->links_map;
+ for_each_set_bit(link_id, &links_map,
+ IEEE80211_MLD_MAX_NUM_LINKS) {
+ tmp_arvif = rcu_dereference(ahvif->link[link_id]);
+ if (!tmp_arvif || !tmp_arvif->is_up)
+ continue;
+
+ tmp_ar = tmp_arvif->ar;
+ tmp_dp_pdev = ath12k_dp_to_pdev_dp(tmp_ar->ab->dp,
+ tmp_ar->pdev_idx);
+ if (!tmp_dp_pdev)
+ continue;
+ msdu_copied = skb_copy(skb, GFP_ATOMIC);
+ if (!msdu_copied) {
+ ath12k_err(ar->ab,
+ "skb copy failure link_id 0x%X vdevid 0x%X\n",
+ link_id, tmp_arvif->vdev_id);
+ continue;
+ }
+
+ ath12k_mlo_mcast_update_tx_link_address(vif, link_id,
+ msdu_copied,
+ info_flags);
+
+ skb_cb = ATH12K_SKB_CB(msdu_copied);
+ skb_cb->link_id = link_id;
+ skb_cb->vif = vif;
+ skb_cb->ar = tmp_ar;
+
+ /* For open mode, skip peer find logic */
+ if (unlikely(!ahvif->dp_vif.key_cipher))
+ goto skip_peer_find;
+
+ tmp_dp = ath12k_ab_to_dp(tmp_ar->ab);
+ spin_lock_bh(&tmp_dp->dp_lock);
+ peer = ath12k_dp_link_peer_find_by_addr(tmp_dp,
+ tmp_arvif->bssid);
+ if (!peer || !peer->dp_peer) {
+ spin_unlock_bh(&tmp_dp->dp_lock);
+ ath12k_warn(tmp_ar->ab,
+ "failed to find peer for vdev_id 0x%X addr %pM link_map 0x%X\n",
+ tmp_arvif->vdev_id, tmp_arvif->bssid,
+ ahvif->links_map);
+ dev_kfree_skb_any(msdu_copied);
+ continue;
+ }
+
+ key = peer->dp_peer->keys[peer->dp_peer->mcast_keyidx];
+ if (key) {
+ skb_cb->cipher = key->cipher;
+ skb_cb->flags |= ATH12K_SKB_CIPHER_SET;
+
+ hdr = (struct ieee80211_hdr *)msdu_copied->data;
+ if (!ieee80211_has_protected(hdr->frame_control))
+ hdr->frame_control |=
+ cpu_to_le16(IEEE80211_FCTL_PROTECTED);
+ }
+ spin_unlock_bh(&tmp_dp->dp_lock);
+
+skip_peer_find:
+ ret = ath12k_wifi7_dp_tx(tmp_dp_pdev, tmp_arvif,
+ msdu_copied, true, mcbc_gsn, is_mcast);
+ if (unlikely(ret)) {
+ if (ret == -ENOMEM) {
+ /* Drops are expected during heavy multicast
+ * frame flood. Print with debug log
+ * level to avoid lot of console prints
+ */
+ ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
+ "failed to transmit frame %d\n",
+ ret);
+ } else {
+ ath12k_warn(ar->ab,
+ "failed to transmit frame %d\n",
+ ret);
+ }
+
+ dev_kfree_skb_any(msdu_copied);
+ }
+ }
+ ieee80211_free_txskb(ar->ah->hw, skb);
+ }
+}
+
static const struct ieee80211_ops ath12k_ops_wifi7 = {
- .tx = ath12k_mac_op_tx,
+ .tx = ath12k_wifi7_mac_op_tx,
.wake_tx_queue = ieee80211_handle_wake_tx_queue,
.start = ath12k_mac_op_start,
.stop = ath12k_mac_op_stop,
--
2.34.1
More information about the ath12k
mailing list