]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
wifi: ath12k: add EMA beacon support
authorAloka Dixit <quic_alokad@quicinc.com>
Wed, 8 May 2024 20:29:11 +0000 (13:29 -0700)
committerKalle Valo <quic_kvalo@quicinc.com>
Thu, 16 May 2024 08:15:04 +0000 (11:15 +0300)
Add new function ath12k_mac_setup_bcn_tmpl_ema() which retrieves
a list of EMA (Enhanced Multi-BSSID Advertisements) beacon templates
from mac80211 and sends all to firmware. Add support to send EMA
configurations to firmware by adding a new parameter 'ema_params' in
struct wmi_bcn_tmpl_cmd.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1

Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://msgid.link/20240508202912.11902-9-quic_alokad@quicinc.com
drivers/net/wireless/ath/ath12k/mac.c
drivers/net/wireless/ath/ath12k/wmi.c
drivers/net/wireless/ath/ath12k/wmi.h

index 2cfed85990a98bdb6dc30f821bf776f82a100eed..e86af398b359d1566a269079894c2f64ae8cce8f 100644 (file)
@@ -1391,6 +1391,56 @@ static void ath12k_mac_set_arvif_ies(struct ath12k_vif *arvif, struct sk_buff *b
        }
 }
 
+static int ath12k_mac_setup_bcn_tmpl_ema(struct ath12k_vif *arvif)
+{
+       struct ieee80211_bss_conf *bss_conf = &arvif->vif->bss_conf;
+       struct ath12k_wmi_bcn_tmpl_ema_arg ema_args;
+       struct ieee80211_ema_beacons *beacons;
+       struct ath12k_vif *tx_arvif;
+       bool nontx_profile_found = false;
+       int ret = 0;
+       u8 i;
+
+       tx_arvif = ath12k_vif_to_arvif(arvif->vif->mbssid_tx_vif);
+       beacons = ieee80211_beacon_get_template_ema_list(ath12k_ar_to_hw(tx_arvif->ar),
+                                                        tx_arvif->vif, 0);
+       if (!beacons || !beacons->cnt) {
+               ath12k_warn(arvif->ar->ab,
+                           "failed to get ema beacon templates from mac80211\n");
+               return -EPERM;
+       }
+
+       if (tx_arvif == arvif)
+               ath12k_mac_set_arvif_ies(arvif, beacons->bcn[0].skb, 0, NULL);
+
+       for (i = 0; i < beacons->cnt; i++) {
+               if (tx_arvif != arvif && !nontx_profile_found)
+                       ath12k_mac_set_arvif_ies(arvif, beacons->bcn[i].skb,
+                                                bss_conf->bssid_index,
+                                                &nontx_profile_found);
+
+               ema_args.bcn_cnt = beacons->cnt;
+               ema_args.bcn_index = i;
+               ret = ath12k_wmi_bcn_tmpl(tx_arvif->ar, tx_arvif->vdev_id,
+                                         &beacons->bcn[i].offs,
+                                         beacons->bcn[i].skb, &ema_args);
+               if (ret) {
+                       ath12k_warn(tx_arvif->ar->ab,
+                                   "failed to set ema beacon template id %i error %d\n",
+                                   i, ret);
+                       break;
+               }
+       }
+
+       if (tx_arvif != arvif && !nontx_profile_found)
+               ath12k_warn(arvif->ar->ab,
+                           "nontransmitted bssid index %u not found in beacon template\n",
+                           bss_conf->bssid_index);
+
+       ieee80211_beacon_free_ema_list(beacons);
+       return ret;
+}
+
 static int ath12k_mac_setup_bcn_tmpl(struct ath12k_vif *arvif)
 {
        struct ath12k_vif *tx_arvif = arvif;
@@ -1409,6 +1459,9 @@ static int ath12k_mac_setup_bcn_tmpl(struct ath12k_vif *arvif)
                tx_arvif = ath12k_vif_to_arvif(vif->mbssid_tx_vif);
                if (tx_arvif != arvif && arvif->is_up)
                        return 0;
+
+               if (vif->bss_conf.ema_ap)
+                       return ath12k_mac_setup_bcn_tmpl_ema(arvif);
        }
 
        bcn = ieee80211_beacon_get_template(ath12k_ar_to_hw(tx_arvif->ar), tx_arvif->vif,
@@ -1452,7 +1505,7 @@ static int ath12k_mac_setup_bcn_tmpl(struct ath12k_vif *arvif)
                }
        }
 
-       ret = ath12k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn);
+       ret = ath12k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn, NULL);
 
        if (ret)
                ath12k_warn(ab, "failed to submit beacon template command: %d\n",
index 57fb01d66a0d2c21f953366c6c151f46eac8e036..99106b088311c115ac3dccc567e600298c4c9232 100644 (file)
@@ -1788,13 +1788,15 @@ int ath12k_wmi_p2p_go_bcn_ie(struct ath12k *ar, u32 vdev_id,
 
 int ath12k_wmi_bcn_tmpl(struct ath12k *ar, u32 vdev_id,
                        struct ieee80211_mutable_offsets *offs,
-                       struct sk_buff *bcn)
+                       struct sk_buff *bcn,
+                       struct ath12k_wmi_bcn_tmpl_ema_arg *ema_args)
 {
        struct ath12k_wmi_pdev *wmi = ar->wmi;
        struct wmi_bcn_tmpl_cmd *cmd;
        struct ath12k_wmi_bcn_prb_info_params *bcn_prb_info;
        struct wmi_tlv *tlv;
        struct sk_buff *skb;
+       u32 ema_params = 0;
        void *ptr;
        int ret, len;
        size_t aligned_len = roundup(bcn->len, 4);
@@ -1814,6 +1816,15 @@ int ath12k_wmi_bcn_tmpl(struct ath12k *ar, u32 vdev_id,
        cmd->ext_csa_switch_count_offset = cpu_to_le32(offs->cntdwn_counter_offs[1]);
        cmd->buf_len = cpu_to_le32(bcn->len);
        cmd->mbssid_ie_offset = cpu_to_le32(offs->mbssid_off);
+       if (ema_args) {
+               u32p_replace_bits(&ema_params, ema_args->bcn_cnt, WMI_EMA_BEACON_CNT);
+               u32p_replace_bits(&ema_params, ema_args->bcn_index, WMI_EMA_BEACON_IDX);
+               if (ema_args->bcn_index == 0)
+                       u32p_replace_bits(&ema_params, 1, WMI_EMA_BEACON_FIRST);
+               if (ema_args->bcn_index + 1 == ema_args->bcn_cnt)
+                       u32p_replace_bits(&ema_params, 1, WMI_EMA_BEACON_LAST);
+               cmd->ema_params = cpu_to_le32(ema_params);
+       }
 
        ptr = skb->data + sizeof(*cmd);
 
index 9b0166a5a575dd27a2d35de63ea0cad2f8bbb5bb..7f83c4583919a940d852fad776c670cb5c9ef597 100644 (file)
@@ -3533,6 +3533,16 @@ struct ath12k_wmi_p2p_noa_info {
 
 #define WMI_BEACON_TX_BUFFER_SIZE      512
 
+#define WMI_EMA_BEACON_CNT      GENMASK(7, 0)
+#define WMI_EMA_BEACON_IDX      GENMASK(15, 8)
+#define WMI_EMA_BEACON_FIRST    GENMASK(23, 16)
+#define WMI_EMA_BEACON_LAST     GENMASK(31, 24)
+
+struct ath12k_wmi_bcn_tmpl_ema_arg {
+       u8 bcn_cnt;
+       u8 bcn_index;
+};
+
 struct wmi_bcn_tmpl_cmd {
        __le32 tlv_header;
        __le32 vdev_id;
@@ -3543,6 +3553,11 @@ struct wmi_bcn_tmpl_cmd {
        __le32 csa_event_bitmap;
        __le32 mbssid_ie_offset;
        __le32 esp_ie_offset;
+       __le32 csc_switch_count_offset;
+       __le32 csc_event_bitmap;
+       __le32 mu_edca_ie_offset;
+       __le32 feature_enable_bitmap;
+       __le32 ema_params;
 } __packed;
 
 struct wmi_p2p_go_set_beacon_ie_cmd {
@@ -4900,7 +4915,8 @@ int ath12k_wmi_p2p_go_bcn_ie(struct ath12k *ar, u32 vdev_id,
                             const u8 *p2p_ie);
 int ath12k_wmi_bcn_tmpl(struct ath12k *ar, u32 vdev_id,
                        struct ieee80211_mutable_offsets *offs,
-                       struct sk_buff *bcn);
+                       struct sk_buff *bcn,
+                       struct ath12k_wmi_bcn_tmpl_ema_arg *ema_args);
 int ath12k_wmi_vdev_down(struct ath12k *ar, u8 vdev_id);
 int ath12k_wmi_vdev_up(struct ath12k *ar, struct ath12k_wmi_vdev_up_params *params);
 int ath12k_wmi_vdev_stop(struct ath12k *ar, u8 vdev_id);