2024-02-26 06:02:51

by Kang Yang

[permalink] [raw]
Subject: [PATCH 0/6] wifi: ath11k: P2P support for QCA6390/WCN6855/QCA2066

Add P2P support for QCA6390/WCN6855/QCA2066.

Kang Yang (6):
wifi: ath11k: change interface combination for P2P mode
wifi: ath11k: add P2P IE in beacon template
wifi: ath11k: implement handling of P2P NoA event
wifi: ath11k: change WLAN_SCAN_PARAMS_MAX_IE_LEN from 256 to 512
wifi: ath11k: invert scan flag WMI_SCAN_FILTER_PROBE_REQ for
QCA6390/WCN6855/QCA2066
wifi: ath11k: advertise P2P dev support for QCA6390/WCN6855/QCA2066

drivers/net/wireless/ath/ath11k/Makefile | 3 +-
drivers/net/wireless/ath/ath11k/core.c | 20 ++-
drivers/net/wireless/ath/ath11k/mac.c | 159 ++++++++++++++++++-----
drivers/net/wireless/ath/ath11k/p2p.c | 145 +++++++++++++++++++++
drivers/net/wireless/ath/ath11k/p2p.h | 23 ++++
drivers/net/wireless/ath/ath11k/wmi.c | 99 +++++++++++++-
drivers/net/wireless/ath/ath11k/wmi.h | 42 +++++-
7 files changed, 454 insertions(+), 37 deletions(-)
create mode 100644 drivers/net/wireless/ath/ath11k/p2p.c
create mode 100644 drivers/net/wireless/ath/ath11k/p2p.h


base-commit: c39a5cfa0448f3afbee78373f16d87815a674f11
--
2.34.1



2024-02-26 06:02:54

by Kang Yang

[permalink] [raw]
Subject: [PATCH 5/6] wifi: ath11k: invert scan flag WMI_SCAN_FILTER_PROBE_REQ for QCA6390/WCN6855/QCA2066

Current ROC scan will filter probe request. But probe request is
necessary for P2P mode. A P2P device cannot be discovered by others if
it doesn't respond to others' probe request.

So invert scan flag WMI_SCAN_FILTER_PROBE_REQ for
QCA6390/WCN6855/QCA2066.

Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.37
Tested-on: QCA2066 hw2.1 PCI WLAN.HSP.1.1-03926.13-QCAHSPSWPL_V2_SILICONZ_CE-2.52297.2

Signed-off-by: Kang Yang <[email protected]>
---
drivers/net/wireless/ath/ath11k/wmi.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
index bbccddd7d729..1dd0cbdda199 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -2317,6 +2317,9 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar,
ether_addr_copy(cmd->mac_addr.addr, params->mac_addr.addr);
ether_addr_copy(cmd->mac_mask.addr, params->mac_mask.addr);

+ if (ar->ab->hw_params.single_pdev_only)
+ cmd->scan_ctrl_flags ^= WMI_SCAN_FILTER_PROBE_REQ;
+
ptr += sizeof(*cmd);

len = params->num_chan * sizeof(u32);
--
2.34.1


2024-02-26 06:02:59

by Kang Yang

[permalink] [raw]
Subject: [PATCH 3/6] wifi: ath11k: implement handling of P2P NoA event

The NoA(Notice of Absence) attribute is used by the P2P Group Owner to
signal its absence due to power save timing, concurrent operation, or
off-channel scanning. It is also used in the P2P Presence Request-Response
mechanism.

The NoA attribute shall be present in the P2P IE in the beacon frames
transmitted by a P2P Group Owner when a NoA schedule is being advertised,
or when the CTWindow is non-zero.

So add support to update P2P information after P2P GO is up through
event WMI_P2P_NOA_EVENTID, and always put it in probe resp.

Create p2p.c and p2p.h for P2P related functions and definitions.

Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.37
Tested-on: QCA2066 hw2.1 PCI WLAN.HSP.1.1-03926.13-QCAHSPSWPL_V2_SILICONZ_CE-2.52297.2

Signed-off-by: Kang Yang <[email protected]>
---
drivers/net/wireless/ath/ath11k/Makefile | 3 +-
drivers/net/wireless/ath/ath11k/p2p.c | 145 +++++++++++++++++++++++
drivers/net/wireless/ath/ath11k/p2p.h | 23 ++++
drivers/net/wireless/ath/ath11k/wmi.c | 57 ++++++++-
drivers/net/wireless/ath/ath11k/wmi.h | 31 +++++
5 files changed, 257 insertions(+), 2 deletions(-)
create mode 100644 drivers/net/wireless/ath/ath11k/p2p.c
create mode 100644 drivers/net/wireless/ath/ath11k/p2p.h

diff --git a/drivers/net/wireless/ath/ath11k/Makefile b/drivers/net/wireless/ath/ath11k/Makefile
index 2c94d50ae36f..43d2d8ddcdc0 100644
--- a/drivers/net/wireless/ath/ath11k/Makefile
+++ b/drivers/net/wireless/ath/ath11k/Makefile
@@ -18,7 +18,8 @@ ath11k-y += core.o \
dbring.o \
hw.o \
pcic.o \
- fw.o
+ fw.o \
+ p2p.o

ath11k-$(CONFIG_ATH11K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o
ath11k-$(CONFIG_NL80211_TESTMODE) += testmode.o
diff --git a/drivers/net/wireless/ath/ath11k/p2p.c b/drivers/net/wireless/ath/ath11k/p2p.c
new file mode 100644
index 000000000000..bfaeea12bc09
--- /dev/null
+++ b/drivers/net/wireless/ath/ath11k/p2p.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: BSD-3-Clause-Clear
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "core.h"
+#include "wmi.h"
+#include "mac.h"
+#include "p2p.h"
+
+static void ath11k_p2p_noa_ie_fill(u8 *data, size_t len,
+ const struct ath11k_wmi_p2p_noa_info *noa)
+{
+ struct ieee80211_p2p_noa_attr *noa_attr;
+ u8 ctwindow = u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_CTWIN_TU);
+ bool oppps = u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_OPP_PS);
+ __le16 *noa_attr_len;
+ u16 attr_len;
+ u8 noa_descriptors = u32_get_bits(noa->noa_attr,
+ WMI_P2P_NOA_INFO_DESC_NUM);
+ int i;
+
+ /* P2P IE */
+ data[0] = WLAN_EID_VENDOR_SPECIFIC;
+ data[1] = len - 2;
+ data[2] = (WLAN_OUI_WFA >> 16) & 0xff;
+ data[3] = (WLAN_OUI_WFA >> 8) & 0xff;
+ data[4] = (WLAN_OUI_WFA >> 0) & 0xff;
+ data[5] = WLAN_OUI_TYPE_WFA_P2P;
+
+ /* NOA ATTR */
+ data[6] = IEEE80211_P2P_ATTR_ABSENCE_NOTICE;
+ noa_attr_len = (__le16 *)&data[7]; /* 2 bytes */
+ noa_attr = (struct ieee80211_p2p_noa_attr *)&data[9];
+
+ noa_attr->index = u32_get_bits(noa->noa_attr,
+ WMI_P2P_NOA_INFO_INDEX);
+ noa_attr->oppps_ctwindow = ctwindow;
+ if (oppps)
+ noa_attr->oppps_ctwindow |= IEEE80211_P2P_OPPPS_ENABLE_BIT;
+
+ for (i = 0; i < noa_descriptors; i++) {
+ noa_attr->desc[i].count = noa->descriptors[i].type_count;
+ noa_attr->desc[i].duration =
+ cpu_to_le32(noa->descriptors[i].duration);
+ noa_attr->desc[i].interval =
+ cpu_to_le32(noa->descriptors[i].interval);
+ noa_attr->desc[i].start_time =
+ cpu_to_le32(noa->descriptors[i].start_time);
+ }
+
+ attr_len = 2; /* index + oppps_ctwindow */
+ attr_len += noa_descriptors * sizeof(struct ieee80211_p2p_noa_desc);
+ *noa_attr_len = __cpu_to_le16(attr_len);
+}
+
+static size_t
+ath11k_p2p_noa_ie_len_compute(const struct ath11k_wmi_p2p_noa_info *noa)
+{
+ size_t len = 0;
+
+ if (!(u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_DESC_NUM)) &&
+ !(u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_OPP_PS)))
+ return 0;
+
+ len += 1 + 1 + 4; /* EID + len + OUI */
+ len += 1 + 2; /* noa attr + attr len */
+ len += 1 + 1; /* index + oppps_ctwindow */
+ len += u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_DESC_NUM) *
+ sizeof(struct ieee80211_p2p_noa_desc);
+
+ return len;
+}
+
+static void ath11k_p2p_noa_ie_assign(struct ath11k_vif *arvif, void *ie,
+ size_t len)
+{
+ struct ath11k *ar = arvif->ar;
+
+ lockdep_assert_held(&ar->data_lock);
+
+ kfree(arvif->u.ap.noa_data);
+
+ arvif->u.ap.noa_data = ie;
+ arvif->u.ap.noa_len = len;
+}
+
+static void __ath11k_p2p_noa_update(struct ath11k_vif *arvif,
+ const struct ath11k_wmi_p2p_noa_info *noa)
+{
+ struct ath11k *ar = arvif->ar;
+ void *ie;
+ size_t len;
+
+ lockdep_assert_held(&ar->data_lock);
+
+ ath11k_p2p_noa_ie_assign(arvif, NULL, 0);
+
+ len = ath11k_p2p_noa_ie_len_compute(noa);
+ if (!len)
+ return;
+
+ ie = kmalloc(len, GFP_ATOMIC);
+ if (!ie)
+ return;
+
+ ath11k_p2p_noa_ie_fill(ie, len, noa);
+ ath11k_p2p_noa_ie_assign(arvif, ie, len); }
+
+void ath11k_p2p_noa_update(struct ath11k_vif *arvif,
+ const struct ath11k_wmi_p2p_noa_info *noa)
+{
+ struct ath11k *ar = arvif->ar;
+
+ spin_lock_bh(&ar->data_lock);
+ __ath11k_p2p_noa_update(arvif, noa);
+ spin_unlock_bh(&ar->data_lock);
+}
+
+static void ath11k_p2p_noa_update_vdev_iter(void *data, u8 *mac,
+ struct ieee80211_vif *vif)
+{
+ struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
+ struct ath11k_p2p_noa_arg *arg = data;
+
+ if (arvif->vdev_id != arg->vdev_id)
+ return;
+
+ ath11k_p2p_noa_update(arvif, arg->noa);
+}
+
+void ath11k_p2p_noa_update_by_vdev_id(struct ath11k *ar, u32 vdev_id,
+ const struct ath11k_wmi_p2p_noa_info *noa)
+{
+ struct ath11k_p2p_noa_arg arg = {
+ .vdev_id = vdev_id,
+ .noa = noa,
+ };
+
+ ieee80211_iterate_active_interfaces_atomic(ar->hw,
+ IEEE80211_IFACE_ITER_NORMAL,
+ ath11k_p2p_noa_update_vdev_iter,
+ &arg);
+}
+
diff --git a/drivers/net/wireless/ath/ath11k/p2p.h b/drivers/net/wireless/ath/ath11k/p2p.h
new file mode 100644
index 000000000000..ebd076f7fe7f
--- /dev/null
+++ b/drivers/net/wireless/ath/ath11k/p2p.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: BSD-3-Clause-Clear */
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef ATH11K_P2P_H
+#define ATH11K_P2P_H
+
+#include "wmi.h"
+
+struct ath11k_wmi_p2p_noa_info;
+
+struct ath11k_p2p_noa_arg {
+ u32 vdev_id;
+ const struct ath11k_wmi_p2p_noa_info *noa;
+};
+
+void ath11k_p2p_noa_update(struct ath11k_vif *arvif,
+ const struct ath11k_wmi_p2p_noa_info *noa);
+void ath11k_p2p_noa_update_by_vdev_id(struct ath11k *ar, u32 vdev_id,
+ const struct ath11k_wmi_p2p_noa_info *noa);
+#endif
+
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
index d86fcdd374c6..bbccddd7d729 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -20,6 +20,7 @@
#include "hw.h"
#include "peer.h"
#include "testmode.h"
+#include "p2p.h"

struct wmi_tlv_policy {
size_t min_len;
@@ -154,6 +155,10 @@ static const struct wmi_tlv_policy wmi_tlv_policies[] = {
.min_len = sizeof(struct wmi_per_chain_rssi_stats) },
[WMI_TAG_TWT_ADD_DIALOG_COMPLETE_EVENT] = {
.min_len = sizeof(struct wmi_twt_add_dialog_event) },
+ [WMI_TAG_P2P_NOA_INFO] = {
+ .min_len = sizeof(struct ath11k_wmi_p2p_noa_info) },
+ [WMI_TAG_P2P_NOA_EVENT] = {
+ .min_len = sizeof(struct wmi_p2p_noa_event) },
};

#define PRIMAP(_hw_mode_) \
@@ -981,7 +986,7 @@ int ath11k_wmi_vdev_start(struct ath11k *ar, struct wmi_vdev_start_req_arg *arg,
FIELD_PREP(WMI_TLV_LEN, 0);

/* Note: This is a nested TLV containing:
- * [wmi_tlv][wmi_p2p_noa_descriptor][wmi_tlv]..
+ * [wmi_tlv][ath11k_wmi_p2p_noa_descriptor][wmi_tlv]..
*/

ptr += sizeof(*tlv);
@@ -8645,6 +8650,53 @@ static void ath11k_wmi_gtk_offload_status_event(struct ath11k_base *ab,
kfree(tb);
}

+static int ath11k_wmi_p2p_noa_event(struct ath11k_base *ab,
+ struct sk_buff *skb)
+{
+ const void **tb;
+ const struct wmi_p2p_noa_event *ev;
+ const struct ath11k_wmi_p2p_noa_info *noa;
+ struct ath11k *ar;
+ int ret, vdev_id;
+
+ tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ if (IS_ERR(tb)) {
+ ret = PTR_ERR(tb);
+ ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
+ return ret;
+ }
+
+ ev = tb[WMI_TAG_P2P_NOA_EVENT];
+ noa = tb[WMI_TAG_P2P_NOA_INFO];
+
+ if (!ev || !noa) {
+ ret = -EPROTO;
+ goto out;
+ }
+
+ vdev_id = ev->vdev_id;
+
+ ath11k_dbg(ab, ATH11K_DBG_WMI,
+ "wmi tlv p2p noa vdev_id %i descriptors %u\n",
+ vdev_id, u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_DESC_NUM));
+ rcu_read_lock();
+ ar = ath11k_mac_get_ar_by_vdev_id(ab, vdev_id);
+ if (!ar) {
+ ath11k_warn(ab, "invalid vdev id %d in P2P NoA event\n",
+ vdev_id);
+ ret = -EINVAL;
+ goto unlock;
+ }
+
+ ath11k_p2p_noa_update_by_vdev_id(ar, vdev_id, noa);
+
+unlock:
+ rcu_read_unlock();
+out:
+ kfree(tb);
+ return 0;
+}
+
static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb)
{
struct wmi_cmd_hdr *cmd_hdr;
@@ -8772,6 +8824,9 @@ static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb)
case WMI_GTK_OFFLOAD_STATUS_EVENTID:
ath11k_wmi_gtk_offload_status_event(ab, skb);
break;
+ case WMI_P2P_NOA_EVENTID:
+ ath11k_wmi_p2p_noa_event(ab, skb);
+ break;
default:
ath11k_dbg(ab, ATH11K_DBG_WMI, "unsupported event id 0x%x\n", id);
break;
diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
index 4c20202947c7..564f4a9ac8ce 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -3630,6 +3630,37 @@ struct wmi_ftm_event_msg {
u8 data[];
} __packed;

+#define WMI_P2P_MAX_NOA_DESCRIPTORS 4
+
+struct wmi_p2p_noa_event {
+ u32 vdev_id;
+} __packed;
+
+struct ath11k_wmi_p2p_noa_descriptor {
+ u32 type_count; /* 255: continuous schedule, 0: reserved */
+ u32 duration; /* Absent period duration in micro seconds */
+ u32 interval; /* Absent period interval in micro seconds */
+ u32 start_time; /* 32 bit tsf time when in starts */
+} __packed;
+
+#define WMI_P2P_NOA_INFO_CHANGED_FLAG BIT(0)
+#define WMI_P2P_NOA_INFO_INDEX GENMASK(15, 8)
+#define WMI_P2P_NOA_INFO_OPP_PS BIT(16)
+#define WMI_P2P_NOA_INFO_CTWIN_TU GENMASK(23, 17)
+#define WMI_P2P_NOA_INFO_DESC_NUM GENMASK(31, 24)
+
+struct ath11k_wmi_p2p_noa_info {
+ /* Bit 0 - Flag to indicate an update in NOA schedule
+ * Bits 7-1 - Reserved
+ * Bits 15-8 - Index (identifies the instance of NOA sub element)
+ * Bit 16 - Opp PS state of the AP
+ * Bits 23-17 - Ctwindow in TUs
+ * Bits 31-24 - Number of NOA descriptors
+ */
+ u32 noa_attr;
+ struct ath11k_wmi_p2p_noa_descriptor descriptors[WMI_P2P_MAX_NOA_DESCRIPTORS];
+} __packed;
+
#define WMI_BEACON_TX_BUFFER_SIZE 512

#define WMI_EMA_TMPL_IDX_SHIFT 8
--
2.34.1


2024-02-26 06:03:05

by Kang Yang

[permalink] [raw]
Subject: [PATCH 2/6] wifi: ath11k: add P2P IE in beacon template

P2P Element is a necessary component of P2P protocol communication.
It contains the Vendor Specific Information Element which includes
the WFA OUI and an OUI Type indicating P2P.

Add P2P IE in beacon template, and implement WMI interface for it.

Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.37
Tested-on: QCA2066 hw2.1 PCI WLAN.HSP.1.1-03926.13-QCAHSPSWPL_V2_SILICONZ_CE-2.52297.2

Signed-off-by: Kang Yang <[email protected]>
---
drivers/net/wireless/ath/ath11k/mac.c | 103 ++++++++++++++++++++++++--
drivers/net/wireless/ath/ath11k/wmi.c | 39 ++++++++++
drivers/net/wireless/ath/ath11k/wmi.h | 9 +++
3 files changed, 143 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 9240dedf3217..f52dd52dabbb 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -1430,10 +1430,67 @@ static bool ath11k_mac_set_nontx_vif_params(struct ath11k_vif *tx_arvif,
return false;
}

-static void ath11k_mac_set_vif_params(struct ath11k_vif *arvif,
- struct sk_buff *bcn)
+static int ath11k_mac_setup_bcn_p2p_ie(struct ath11k_vif *arvif,
+ struct sk_buff *bcn)
{
+ struct ath11k *ar = arvif->ar;
+ struct ieee80211_mgmt *mgmt;
+ const u8 *p2p_ie;
+ int ret = 0;
+
+ mgmt = (void *)bcn->data;
+ p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
+ mgmt->u.beacon.variable,
+ bcn->len - (mgmt->u.beacon.variable -
+ bcn->data));
+ if (!p2p_ie)
+ return -ENOENT;
+
+ ret = ath11k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie);
+ if (ret) {
+ ath11k_warn(ar->ab, "failed to submit P2P GO bcn ie for vdev %i: %d\n",
+ arvif->vdev_id, ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int ath11k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
+ u8 oui_type, size_t ie_offset)
+{
+ size_t len;
+ const u8 *next, *end;
+ u8 *ie;
+
+ if (WARN_ON(skb->len < ie_offset))
+ return -EINVAL;
+
+ ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,
+ skb->data + ie_offset,
+ skb->len - ie_offset);
+ if (!ie)
+ return -ENOENT;
+
+ len = ie[1] + 2;
+ end = skb->data + skb->len;
+ next = ie + len;
+
+ if (WARN_ON(next > end))
+ return -EINVAL;
+
+ memmove(ie, next, end - next);
+ skb_trim(skb, skb->len - len);
+
+ return 0;
+}
+
+static int ath11k_mac_set_vif_params(struct ath11k_vif *arvif,
+ struct sk_buff *bcn)
+{
+ struct ath11k_base *ab = arvif->ar->ab;
struct ieee80211_mgmt *mgmt;
+ int ret = 0;
u8 *ies;

ies = bcn->data + ieee80211_get_hdrlen_from_skb(bcn);
@@ -1451,6 +1508,32 @@ static void ath11k_mac_set_vif_params(struct ath11k_vif *arvif,
arvif->wpaie_present = true;
else
arvif->wpaie_present = false;
+
+ if (arvif->vif->type != NL80211_IFTYPE_AP || !arvif->vif->p2p)
+ return ret;
+
+ ret = ath11k_mac_setup_bcn_p2p_ie(arvif, bcn);
+ if (ret) {
+ ath11k_warn(ab, "failed to setup P2P GO bcn ie: %d\n",
+ ret);
+ return ret;
+ }
+
+ /* P2P IE is inserted by firmware automatically (as
+ * configured above) so remove it from the base beacon
+ * template to avoid duplicate P2P IEs in beacon frames.
+ */
+ ret = ath11k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA,
+ WLAN_OUI_TYPE_WFA_P2P,
+ offsetof(struct ieee80211_mgmt,
+ u.beacon.variable));
+ if (ret) {
+ ath11k_warn(ab, "failed to remove P2P vendor ie: %d\n",
+ ret);
+ return ret;
+ }
+
+ return ret;
}

static int ath11k_mac_setup_bcn_tmpl_ema(struct ath11k_vif *arvif)
@@ -1472,10 +1555,12 @@ static int ath11k_mac_setup_bcn_tmpl_ema(struct ath11k_vif *arvif)
return -EPERM;
}

- if (tx_arvif == arvif)
- ath11k_mac_set_vif_params(tx_arvif, beacons->bcn[0].skb);
- else
+ if (tx_arvif == arvif) {
+ if (ath11k_mac_set_vif_params(tx_arvif, beacons->bcn[0].skb))
+ return -EINVAL;
+ } else {
arvif->wpaie_present = tx_arvif->wpaie_present;
+ }

for (i = 0; i < beacons->cnt; i++) {
if (tx_arvif != arvif && !nontx_vif_params_set)
@@ -1534,10 +1619,12 @@ static int ath11k_mac_setup_bcn_tmpl_mbssid(struct ath11k_vif *arvif)
return -EPERM;
}

- if (tx_arvif == arvif)
- ath11k_mac_set_vif_params(tx_arvif, bcn);
- else if (!ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, bcn))
+ if (tx_arvif == arvif) {
+ if (ath11k_mac_set_vif_params(tx_arvif, bcn))
+ return -EINVAL;
+ } else if (!ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, bcn)) {
return -EINVAL;
+ }

ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn, 0);
kfree_skb(bcn);
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
index 34ab9631ff36..d86fcdd374c6 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -1704,6 +1704,45 @@ int ath11k_wmi_send_bcn_offload_control_cmd(struct ath11k *ar,
return ret;
}

+int ath11k_wmi_p2p_go_bcn_ie(struct ath11k *ar, u32 vdev_id,
+ const u8 *p2p_ie)
+{
+ struct ath11k_pdev_wmi *wmi = ar->wmi;
+ struct wmi_p2p_go_set_beacon_ie_cmd *cmd;
+ size_t p2p_ie_len, aligned_len;
+ struct wmi_tlv *tlv;
+ struct sk_buff *skb;
+ int ret, len;
+
+ p2p_ie_len = p2p_ie[1] + 2;
+ aligned_len = roundup(p2p_ie_len, 4);
+
+ len = sizeof(*cmd) + TLV_HDR_SIZE + aligned_len;
+
+ skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_p2p_go_set_beacon_ie_cmd *)skb->data;
+ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_P2P_GO_SET_BEACON_IE) |
+ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
+ cmd->vdev_id = vdev_id;
+ cmd->ie_buf_len = p2p_ie_len;
+
+ tlv = (struct wmi_tlv *)cmd->tlv;
+ tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
+ FIELD_PREP(WMI_TLV_LEN, aligned_len);
+ memcpy(tlv->value, p2p_ie, p2p_ie_len);
+
+ ret = ath11k_wmi_cmd_send(wmi, skb, WMI_P2P_GO_SET_BEACON_IE);
+ if (ret) {
+ ath11k_warn(ar->ab, "failed to send WMI_P2P_GO_SET_BEACON_IE\n");
+ dev_kfree_skb(skb);
+ }
+
+ return ret;
+}
+
int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
struct ieee80211_mutable_offsets *offs,
struct sk_buff *bcn, u32 ema_params)
diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
index bb419e3abb00..4c20202947c7 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -3653,6 +3653,13 @@ struct wmi_bcn_tmpl_cmd {
u32 ema_params;
} __packed;

+struct wmi_p2p_go_set_beacon_ie_cmd {
+ u32 tlv_header;
+ u32 vdev_id;
+ u32 ie_buf_len;
+ u8 tlv[];
+} __packed;
+
struct wmi_key_seq_counter {
u32 key_seq_counter_l;
u32 key_seq_counter_h;
@@ -6349,6 +6356,8 @@ int ath11k_wmi_cmd_send(struct ath11k_pdev_wmi *wmi, struct sk_buff *skb,
struct sk_buff *ath11k_wmi_alloc_skb(struct ath11k_wmi_base *wmi_sc, u32 len);
int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id,
struct sk_buff *frame);
+int ath11k_wmi_p2p_go_bcn_ie(struct ath11k *ar, u32 vdev_id,
+ const u8 *p2p_ie);
int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
struct ieee80211_mutable_offsets *offs,
struct sk_buff *bcn, u32 ema_param);
--
2.34.1


2024-02-26 06:03:11

by Kang Yang

[permalink] [raw]
Subject: [PATCH 4/6] wifi: ath11k: change WLAN_SCAN_PARAMS_MAX_IE_LEN from 256 to 512

Mac80211 needs more space for P2P scan ie in P2P mode, 256 is not
enough, resize it to 512.

Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.37
Tested-on: QCA2066 hw2.1 PCI WLAN.HSP.1.1-03926.13-QCAHSPSWPL_V2_SILICONZ_CE-2.52297.2

Signed-off-by: Kang Yang <[email protected]>
---
drivers/net/wireless/ath/ath11k/wmi.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
index 564f4a9ac8ce..ae788949bf40 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -66,7 +66,7 @@ struct wmi_tlv {

#define WLAN_SCAN_PARAMS_MAX_SSID 16
#define WLAN_SCAN_PARAMS_MAX_BSSID 4
-#define WLAN_SCAN_PARAMS_MAX_IE_LEN 256
+#define WLAN_SCAN_PARAMS_MAX_IE_LEN 512

#define WMI_APPEND_TO_EXISTING_CHAN_LIST_FLAG 1

--
2.34.1


2024-02-26 06:03:23

by Kang Yang

[permalink] [raw]
Subject: [PATCH 6/6] wifi: ath11k: advertise P2P dev support for QCA6390/WCN6855/QCA2066

Now that all the necessary pieces are implemented we can enable P2P
support for QCA6390/WCN6855/QCA2066.

Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.37
Tested-on: QCA2066 hw2.1 PCI WLAN.HSP.1.1-03926.13-QCAHSPSWPL_V2_SILICONZ_CE-2.52297.2

Signed-off-by: Kang Yang <[email protected]>
---
drivers/net/wireless/ath/ath11k/core.c | 20 ++++++++++++++++----
drivers/net/wireless/ath/ath11k/mac.c | 9 +++++++++
2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
index c78bce19bd75..6e9f16f01ebd 100644
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -247,7 +247,10 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
},

.interface_modes = BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_AP),
+ BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_P2P_DEVICE) |
+ BIT(NL80211_IFTYPE_P2P_CLIENT) |
+ BIT(NL80211_IFTYPE_P2P_GO),
.supports_monitor = false,
.full_monitor_mode = false,
.supports_shadow_regs = true,
@@ -416,7 +419,10 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
},

.interface_modes = BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_AP),
+ BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_P2P_DEVICE) |
+ BIT(NL80211_IFTYPE_P2P_CLIENT) |
+ BIT(NL80211_IFTYPE_P2P_GO),
.supports_monitor = false,
.full_monitor_mode = false,
.supports_shadow_regs = true,
@@ -501,7 +507,10 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
},

.interface_modes = BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_AP),
+ BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_P2P_DEVICE) |
+ BIT(NL80211_IFTYPE_P2P_CLIENT) |
+ BIT(NL80211_IFTYPE_P2P_GO),
.supports_monitor = false,
.supports_shadow_regs = true,
.idle_ps = true,
@@ -750,7 +759,10 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
},

.interface_modes = BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_AP),
+ BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_P2P_DEVICE) |
+ BIT(NL80211_IFTYPE_P2P_CLIENT) |
+ BIT(NL80211_IFTYPE_P2P_GO),
.supports_monitor = false,
.full_monitor_mode = false,
.supports_shadow_regs = true,
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index f52dd52dabbb..053785e0eba8 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -6657,17 +6657,26 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,
case NL80211_IFTYPE_UNSPECIFIED:
case NL80211_IFTYPE_STATION:
arvif->vdev_type = WMI_VDEV_TYPE_STA;
+ if (vif->p2p)
+ arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_CLIENT;
break;
case NL80211_IFTYPE_MESH_POINT:
arvif->vdev_subtype = WMI_VDEV_SUBTYPE_MESH_11S;
fallthrough;
case NL80211_IFTYPE_AP:
arvif->vdev_type = WMI_VDEV_TYPE_AP;
+ if (vif->p2p)
+ arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_GO;
break;
case NL80211_IFTYPE_MONITOR:
arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;
ar->monitor_vdev_id = bit;
break;
+ case NL80211_IFTYPE_P2P_DEVICE:
+ arvif->vdev_type = WMI_VDEV_TYPE_STA;
+ arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_DEVICE;
+ break;
+
default:
WARN_ON(1);
break;
--
2.34.1


2024-02-26 19:40:58

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH 2/6] wifi: ath11k: add P2P IE in beacon template

On 2/25/2024 10:01 PM, Kang Yang wrote:
> P2P Element is a necessary component of P2P protocol communication.
> It contains the Vendor Specific Information Element which includes
> the WFA OUI and an OUI Type indicating P2P.
>
> Add P2P IE in beacon template, and implement WMI interface for it.
>
> Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.37
> Tested-on: QCA2066 hw2.1 PCI WLAN.HSP.1.1-03926.13-QCAHSPSWPL_V2_SILICONZ_CE-2.52297.2
>
> Signed-off-by: Kang Yang <[email protected]>
> ---
> drivers/net/wireless/ath/ath11k/mac.c | 103 ++++++++++++++++++++++++--
> drivers/net/wireless/ath/ath11k/wmi.c | 39 ++++++++++
> drivers/net/wireless/ath/ath11k/wmi.h | 9 +++
> 3 files changed, 143 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
> index 9240dedf3217..f52dd52dabbb 100644
> --- a/drivers/net/wireless/ath/ath11k/mac.c
> +++ b/drivers/net/wireless/ath/ath11k/mac.c
> @@ -1430,10 +1430,67 @@ static bool ath11k_mac_set_nontx_vif_params(struct ath11k_vif *tx_arvif,
> return false;
> }
>
> -static void ath11k_mac_set_vif_params(struct ath11k_vif *arvif,
> - struct sk_buff *bcn)
> +static int ath11k_mac_setup_bcn_p2p_ie(struct ath11k_vif *arvif,
> + struct sk_buff *bcn)
> {
> + struct ath11k *ar = arvif->ar;
> + struct ieee80211_mgmt *mgmt;
> + const u8 *p2p_ie;
> + int ret = 0;
> +
> + mgmt = (void *)bcn->data;
> + p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
> + mgmt->u.beacon.variable,
> + bcn->len - (mgmt->u.beacon.variable -
> + bcn->data));
> + if (!p2p_ie)
> + return -ENOENT;
> +
> + ret = ath11k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie);
> + if (ret) {
> + ath11k_warn(ar->ab, "failed to submit P2P GO bcn ie for vdev %i: %d\n",
> + arvif->vdev_id, ret);
> + return ret;
> + }
> +
> + return ret;
> +}
> +
> +static int ath11k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
> + u8 oui_type, size_t ie_offset)
> +{
> + size_t len;
> + const u8 *next, *end;
> + u8 *ie;
> +
> + if (WARN_ON(skb->len < ie_offset))
> + return -EINVAL;
> +
> + ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,
> + skb->data + ie_offset,
> + skb->len - ie_offset);
> + if (!ie)
> + return -ENOENT;
> +
> + len = ie[1] + 2;
> + end = skb->data + skb->len;
> + next = ie + len;
> +
> + if (WARN_ON(next > end))
> + return -EINVAL;
> +
> + memmove(ie, next, end - next);
> + skb_trim(skb, skb->len - len);
> +
> + return 0;
> +}
> +
> +static int ath11k_mac_set_vif_params(struct ath11k_vif *arvif,
> + struct sk_buff *bcn)
> +{
> + struct ath11k_base *ab = arvif->ar->ab;
> struct ieee80211_mgmt *mgmt;
> + int ret = 0;
> u8 *ies;
>
> ies = bcn->data + ieee80211_get_hdrlen_from_skb(bcn);
> @@ -1451,6 +1508,32 @@ static void ath11k_mac_set_vif_params(struct ath11k_vif *arvif,
> arvif->wpaie_present = true;
> else
> arvif->wpaie_present = false;
> +
> + if (arvif->vif->type != NL80211_IFTYPE_AP || !arvif->vif->p2p)

this logic isn't applicable for NL80211_IFTYPE_P2P_GO ?

> + return ret;
> +
> + ret = ath11k_mac_setup_bcn_p2p_ie(arvif, bcn);
> + if (ret) {
> + ath11k_warn(ab, "failed to setup P2P GO bcn ie: %d\n",
> + ret);
> + return ret;
> + }
> +
> + /* P2P IE is inserted by firmware automatically (as
> + * configured above) so remove it from the base beacon
> + * template to avoid duplicate P2P IEs in beacon frames.
> + */
> + ret = ath11k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA,
> + WLAN_OUI_TYPE_WFA_P2P,
> + offsetof(struct ieee80211_mgmt,
> + u.beacon.variable));
> + if (ret) {
> + ath11k_warn(ab, "failed to remove P2P vendor ie: %d\n",
> + ret);
> + return ret;
> + }
> +
> + return ret;
> }
>
> static int ath11k_mac_setup_bcn_tmpl_ema(struct ath11k_vif *arvif)
> @@ -1472,10 +1555,12 @@ static int ath11k_mac_setup_bcn_tmpl_ema(struct ath11k_vif *arvif)
> return -EPERM;
> }
>
> - if (tx_arvif == arvif)
> - ath11k_mac_set_vif_params(tx_arvif, beacons->bcn[0].skb);
> - else
> + if (tx_arvif == arvif) {
> + if (ath11k_mac_set_vif_params(tx_arvif, beacons->bcn[0].skb))
> + return -EINVAL;
> + } else {
> arvif->wpaie_present = tx_arvif->wpaie_present;
> + }
>
> for (i = 0; i < beacons->cnt; i++) {
> if (tx_arvif != arvif && !nontx_vif_params_set)
> @@ -1534,10 +1619,12 @@ static int ath11k_mac_setup_bcn_tmpl_mbssid(struct ath11k_vif *arvif)
> return -EPERM;
> }
>
> - if (tx_arvif == arvif)
> - ath11k_mac_set_vif_params(tx_arvif, bcn);
> - else if (!ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, bcn))
> + if (tx_arvif == arvif) {
> + if (ath11k_mac_set_vif_params(tx_arvif, bcn))
> + return -EINVAL;
> + } else if (!ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, bcn)) {
> return -EINVAL;
> + }
>
> ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn, 0);
> kfree_skb(bcn);
> diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
> index 34ab9631ff36..d86fcdd374c6 100644
> --- a/drivers/net/wireless/ath/ath11k/wmi.c
> +++ b/drivers/net/wireless/ath/ath11k/wmi.c
> @@ -1704,6 +1704,45 @@ int ath11k_wmi_send_bcn_offload_control_cmd(struct ath11k *ar,
> return ret;
> }
>
> +int ath11k_wmi_p2p_go_bcn_ie(struct ath11k *ar, u32 vdev_id,
> + const u8 *p2p_ie)
> +{
> + struct ath11k_pdev_wmi *wmi = ar->wmi;
> + struct wmi_p2p_go_set_beacon_ie_cmd *cmd;
> + size_t p2p_ie_len, aligned_len;
> + struct wmi_tlv *tlv;
> + struct sk_buff *skb;
> + int ret, len;
> +
> + p2p_ie_len = p2p_ie[1] + 2;
> + aligned_len = roundup(p2p_ie_len, 4);
> +
> + len = sizeof(*cmd) + TLV_HDR_SIZE + aligned_len;
> +
> + skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
> + if (!skb)
> + return -ENOMEM;
> +
> + cmd = (struct wmi_p2p_go_set_beacon_ie_cmd *)skb->data;
> + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_P2P_GO_SET_BEACON_IE) |
> + FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
> + cmd->vdev_id = vdev_id;
> + cmd->ie_buf_len = p2p_ie_len;
> +
> + tlv = (struct wmi_tlv *)cmd->tlv;
> + tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
> + FIELD_PREP(WMI_TLV_LEN, aligned_len);
> + memcpy(tlv->value, p2p_ie, p2p_ie_len);
> +
> + ret = ath11k_wmi_cmd_send(wmi, skb, WMI_P2P_GO_SET_BEACON_IE);
> + if (ret) {
> + ath11k_warn(ar->ab, "failed to send WMI_P2P_GO_SET_BEACON_IE\n");
> + dev_kfree_skb(skb);
> + }
> +
> + return ret;
> +}
> +
> int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
> struct ieee80211_mutable_offsets *offs,
> struct sk_buff *bcn, u32 ema_params)
> diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
> index bb419e3abb00..4c20202947c7 100644
> --- a/drivers/net/wireless/ath/ath11k/wmi.h
> +++ b/drivers/net/wireless/ath/ath11k/wmi.h
> @@ -3653,6 +3653,13 @@ struct wmi_bcn_tmpl_cmd {
> u32 ema_params;
> } __packed;
>
> +struct wmi_p2p_go_set_beacon_ie_cmd {
> + u32 tlv_header;
> + u32 vdev_id;
> + u32 ie_buf_len;
> + u8 tlv[];
> +} __packed;
> +
> struct wmi_key_seq_counter {
> u32 key_seq_counter_l;
> u32 key_seq_counter_h;
> @@ -6349,6 +6356,8 @@ int ath11k_wmi_cmd_send(struct ath11k_pdev_wmi *wmi, struct sk_buff *skb,
> struct sk_buff *ath11k_wmi_alloc_skb(struct ath11k_wmi_base *wmi_sc, u32 len);
> int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id,
> struct sk_buff *frame);
> +int ath11k_wmi_p2p_go_bcn_ie(struct ath11k *ar, u32 vdev_id,
> + const u8 *p2p_ie);
> int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
> struct ieee80211_mutable_offsets *offs,
> struct sk_buff *bcn, u32 ema_param);


2024-02-26 19:55:17

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH 4/6] wifi: ath11k: change WLAN_SCAN_PARAMS_MAX_IE_LEN from 256 to 512

On 2/25/2024 10:02 PM, Kang Yang wrote:
> Mac80211 needs more space for P2P scan ie in P2P mode, 256 is not
> enough, resize it to 512.
>
> Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.37
> Tested-on: QCA2066 hw2.1 PCI WLAN.HSP.1.1-03926.13-QCAHSPSWPL_V2_SILICONZ_CE-2.52297.2
>
> Signed-off-by: Kang Yang <[email protected]>
Acked-by: Jeff Johnson <[email protected]>


2024-02-26 20:00:29

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH 2/6] wifi: ath11k: add P2P IE in beacon template

On 2/25/2024 10:01 PM, Kang Yang wrote:
> P2P Element is a necessary component of P2P protocol communication.
> It contains the Vendor Specific Information Element which includes
> the WFA OUI and an OUI Type indicating P2P.
>
> Add P2P IE in beacon template, and implement WMI interface for it.
>
> Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.37
> Tested-on: QCA2066 hw2.1 PCI WLAN.HSP.1.1-03926.13-QCAHSPSWPL_V2_SILICONZ_CE-2.52297.2
>
> Signed-off-by: Kang Yang <[email protected]>
> ---
> drivers/net/wireless/ath/ath11k/mac.c | 103 ++++++++++++++++++++++++--
> drivers/net/wireless/ath/ath11k/wmi.c | 39 ++++++++++
> drivers/net/wireless/ath/ath11k/wmi.h | 9 +++
> 3 files changed, 143 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
> index 9240dedf3217..f52dd52dabbb 100644
> --- a/drivers/net/wireless/ath/ath11k/mac.c
> +++ b/drivers/net/wireless/ath/ath11k/mac.c
> @@ -1430,10 +1430,67 @@ static bool ath11k_mac_set_nontx_vif_params(struct ath11k_vif *tx_arvif,
> return false;
> }
>
> -static void ath11k_mac_set_vif_params(struct ath11k_vif *arvif,
> - struct sk_buff *bcn)
> +static int ath11k_mac_setup_bcn_p2p_ie(struct ath11k_vif *arvif,
> + struct sk_buff *bcn)
> {
> + struct ath11k *ar = arvif->ar;
> + struct ieee80211_mgmt *mgmt;
> + const u8 *p2p_ie;
> + int ret = 0;

unnecessary initializer?

> +
> + mgmt = (void *)bcn->data;
> + p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
> + mgmt->u.beacon.variable,
> + bcn->len - (mgmt->u.beacon.variable -
> + bcn->data));
> + if (!p2p_ie)
> + return -ENOENT;
> +
> + ret = ath11k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie);
> + if (ret) {
> + ath11k_warn(ar->ab, "failed to submit P2P GO bcn ie for vdev %i: %d\n",
> + arvif->vdev_id, ret);
> + return ret;
> + }
> +
> + return ret;
> +}
> +
> +static int ath11k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
> + u8 oui_type, size_t ie_offset)
> +{
> + size_t len;
> + const u8 *next, *end;
> + u8 *ie;
> +
> + if (WARN_ON(skb->len < ie_offset))
> + return -EINVAL;
> +
> + ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,
> + skb->data + ie_offset,
> + skb->len - ie_offset);
> + if (!ie)
> + return -ENOENT;
> +
> + len = ie[1] + 2;
> + end = skb->data + skb->len;
> + next = ie + len;
> +
> + if (WARN_ON(next > end))
> + return -EINVAL;
> +
> + memmove(ie, next, end - next);
> + skb_trim(skb, skb->len - len);
> +
> + return 0;
> +}
> +
> +static int ath11k_mac_set_vif_params(struct ath11k_vif *arvif,
> + struct sk_buff *bcn)
> +{
> + struct ath11k_base *ab = arvif->ar->ab;
> struct ieee80211_mgmt *mgmt;
> + int ret = 0;
> u8 *ies;
>
> ies = bcn->data + ieee80211_get_hdrlen_from_skb(bcn);
> @@ -1451,6 +1508,32 @@ static void ath11k_mac_set_vif_params(struct ath11k_vif *arvif,
> arvif->wpaie_present = true;
> else
> arvif->wpaie_present = false;
> +
> + if (arvif->vif->type != NL80211_IFTYPE_AP || !arvif->vif->p2p)
> + return ret;
> +
> + ret = ath11k_mac_setup_bcn_p2p_ie(arvif, bcn);
> + if (ret) {
> + ath11k_warn(ab, "failed to setup P2P GO bcn ie: %d\n",
> + ret);
> + return ret;
> + }
> +
> + /* P2P IE is inserted by firmware automatically (as
> + * configured above) so remove it from the base beacon
> + * template to avoid duplicate P2P IEs in beacon frames.
> + */
> + ret = ath11k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA,
> + WLAN_OUI_TYPE_WFA_P2P,
> + offsetof(struct ieee80211_mgmt,
> + u.beacon.variable));
> + if (ret) {
> + ath11k_warn(ab, "failed to remove P2P vendor ie: %d\n",
> + ret);
> + return ret;
> + }
> +
> + return ret;
> }
>
> static int ath11k_mac_setup_bcn_tmpl_ema(struct ath11k_vif *arvif)
> @@ -1472,10 +1555,12 @@ static int ath11k_mac_setup_bcn_tmpl_ema(struct ath11k_vif *arvif)
> return -EPERM;
> }
>
> - if (tx_arvif == arvif)
> - ath11k_mac_set_vif_params(tx_arvif, beacons->bcn[0].skb);
> - else
> + if (tx_arvif == arvif) {
> + if (ath11k_mac_set_vif_params(tx_arvif, beacons->bcn[0].skb))
> + return -EINVAL;
> + } else {
> arvif->wpaie_present = tx_arvif->wpaie_present;
> + }
>
> for (i = 0; i < beacons->cnt; i++) {
> if (tx_arvif != arvif && !nontx_vif_params_set)
> @@ -1534,10 +1619,12 @@ static int ath11k_mac_setup_bcn_tmpl_mbssid(struct ath11k_vif *arvif)
> return -EPERM;
> }
>
> - if (tx_arvif == arvif)
> - ath11k_mac_set_vif_params(tx_arvif, bcn);
> - else if (!ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, bcn))
> + if (tx_arvif == arvif) {
> + if (ath11k_mac_set_vif_params(tx_arvif, bcn))
> + return -EINVAL;
> + } else if (!ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, bcn)) {
> return -EINVAL;
> + }
>
> ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn, 0);
> kfree_skb(bcn);
> diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
> index 34ab9631ff36..d86fcdd374c6 100644
> --- a/drivers/net/wireless/ath/ath11k/wmi.c
> +++ b/drivers/net/wireless/ath/ath11k/wmi.c
> @@ -1704,6 +1704,45 @@ int ath11k_wmi_send_bcn_offload_control_cmd(struct ath11k *ar,
> return ret;
> }
>
> +int ath11k_wmi_p2p_go_bcn_ie(struct ath11k *ar, u32 vdev_id,
> + const u8 *p2p_ie)
> +{
> + struct ath11k_pdev_wmi *wmi = ar->wmi;
> + struct wmi_p2p_go_set_beacon_ie_cmd *cmd;
> + size_t p2p_ie_len, aligned_len;
> + struct wmi_tlv *tlv;
> + struct sk_buff *skb;
> + int ret, len;
> +
> + p2p_ie_len = p2p_ie[1] + 2;
> + aligned_len = roundup(p2p_ie_len, 4);
> +
> + len = sizeof(*cmd) + TLV_HDR_SIZE + aligned_len;
> +
> + skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
> + if (!skb)
> + return -ENOMEM;
> +
> + cmd = (struct wmi_p2p_go_set_beacon_ie_cmd *)skb->data;
> + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_P2P_GO_SET_BEACON_IE) |
> + FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
> + cmd->vdev_id = vdev_id;
> + cmd->ie_buf_len = p2p_ie_len;
> +
> + tlv = (struct wmi_tlv *)cmd->tlv;
> + tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
> + FIELD_PREP(WMI_TLV_LEN, aligned_len);
> + memcpy(tlv->value, p2p_ie, p2p_ie_len);
> +
> + ret = ath11k_wmi_cmd_send(wmi, skb, WMI_P2P_GO_SET_BEACON_IE);
> + if (ret) {
> + ath11k_warn(ar->ab, "failed to send WMI_P2P_GO_SET_BEACON_IE\n");
> + dev_kfree_skb(skb);
> + }
> +
> + return ret;
> +}
> +
> int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
> struct ieee80211_mutable_offsets *offs,
> struct sk_buff *bcn, u32 ema_params)
> diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
> index bb419e3abb00..4c20202947c7 100644
> --- a/drivers/net/wireless/ath/ath11k/wmi.h
> +++ b/drivers/net/wireless/ath/ath11k/wmi.h
> @@ -3653,6 +3653,13 @@ struct wmi_bcn_tmpl_cmd {
> u32 ema_params;
> } __packed;
>
> +struct wmi_p2p_go_set_beacon_ie_cmd {
> + u32 tlv_header;
> + u32 vdev_id;
> + u32 ie_buf_len;
> + u8 tlv[];
> +} __packed;
> +
> struct wmi_key_seq_counter {
> u32 key_seq_counter_l;
> u32 key_seq_counter_h;
> @@ -6349,6 +6356,8 @@ int ath11k_wmi_cmd_send(struct ath11k_pdev_wmi *wmi, struct sk_buff *skb,
> struct sk_buff *ath11k_wmi_alloc_skb(struct ath11k_wmi_base *wmi_sc, u32 len);
> int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id,
> struct sk_buff *frame);
> +int ath11k_wmi_p2p_go_bcn_ie(struct ath11k *ar, u32 vdev_id,
> + const u8 *p2p_ie);
> int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
> struct ieee80211_mutable_offsets *offs,
> struct sk_buff *bcn, u32 ema_param);


2024-02-26 20:01:58

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH 3/6] wifi: ath11k: implement handling of P2P NoA event

On 2/25/2024 10:02 PM, Kang Yang wrote:
> The NoA(Notice of Absence) attribute is used by the P2P Group Owner to
> signal its absence due to power save timing, concurrent operation, or
> off-channel scanning. It is also used in the P2P Presence Request-Response
> mechanism.
>
> The NoA attribute shall be present in the P2P IE in the beacon frames
> transmitted by a P2P Group Owner when a NoA schedule is being advertised,
> or when the CTWindow is non-zero.
>
> So add support to update P2P information after P2P GO is up through
> event WMI_P2P_NOA_EVENTID, and always put it in probe resp.
>
> Create p2p.c and p2p.h for P2P related functions and definitions.
>
> Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.37
> Tested-on: QCA2066 hw2.1 PCI WLAN.HSP.1.1-03926.13-QCAHSPSWPL_V2_SILICONZ_CE-2.52297.2
>
> Signed-off-by: Kang Yang <[email protected]>
> ---
> drivers/net/wireless/ath/ath11k/Makefile | 3 +-
> drivers/net/wireless/ath/ath11k/p2p.c | 145 +++++++++++++++++++++++
> drivers/net/wireless/ath/ath11k/p2p.h | 23 ++++
> drivers/net/wireless/ath/ath11k/wmi.c | 57 ++++++++-
> drivers/net/wireless/ath/ath11k/wmi.h | 31 +++++
> 5 files changed, 257 insertions(+), 2 deletions(-)
> create mode 100644 drivers/net/wireless/ath/ath11k/p2p.c
> create mode 100644 drivers/net/wireless/ath/ath11k/p2p.h
>
> diff --git a/drivers/net/wireless/ath/ath11k/Makefile b/drivers/net/wireless/ath/ath11k/Makefile
> index 2c94d50ae36f..43d2d8ddcdc0 100644
> --- a/drivers/net/wireless/ath/ath11k/Makefile
> +++ b/drivers/net/wireless/ath/ath11k/Makefile
> @@ -18,7 +18,8 @@ ath11k-y += core.o \
> dbring.o \
> hw.o \
> pcic.o \
> - fw.o
> + fw.o \
> + p2p.o
>
> ath11k-$(CONFIG_ATH11K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o
> ath11k-$(CONFIG_NL80211_TESTMODE) += testmode.o
> diff --git a/drivers/net/wireless/ath/ath11k/p2p.c b/drivers/net/wireless/ath/ath11k/p2p.c
> new file mode 100644
> index 000000000000..bfaeea12bc09
> --- /dev/null
> +++ b/drivers/net/wireless/ath/ath11k/p2p.c
> @@ -0,0 +1,145 @@
> +// SPDX-License-Identifier: BSD-3-Clause-Clear
> +/*
> + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +
> +#include "core.h"
> +#include "wmi.h"
> +#include "mac.h"
> +#include "p2p.h"
> +
> +static void ath11k_p2p_noa_ie_fill(u8 *data, size_t len,
> + const struct ath11k_wmi_p2p_noa_info *noa)
> +{
> + struct ieee80211_p2p_noa_attr *noa_attr;
> + u8 ctwindow = u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_CTWIN_TU);
> + bool oppps = u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_OPP_PS);
> + __le16 *noa_attr_len;
> + u16 attr_len;
> + u8 noa_descriptors = u32_get_bits(noa->noa_attr,
> + WMI_P2P_NOA_INFO_DESC_NUM);

do you need to validate that this doesn't exceed
WMI_P2P_MAX_NOA_DESCRIPTORS?

> + int i;
> +
> + /* P2P IE */
> + data[0] = WLAN_EID_VENDOR_SPECIFIC;
> + data[1] = len - 2;
> + data[2] = (WLAN_OUI_WFA >> 16) & 0xff;
> + data[3] = (WLAN_OUI_WFA >> 8) & 0xff;
> + data[4] = (WLAN_OUI_WFA >> 0) & 0xff;
> + data[5] = WLAN_OUI_TYPE_WFA_P2P;
> +
> + /* NOA ATTR */
> + data[6] = IEEE80211_P2P_ATTR_ABSENCE_NOTICE;
> + noa_attr_len = (__le16 *)&data[7]; /* 2 bytes */
> + noa_attr = (struct ieee80211_p2p_noa_attr *)&data[9];
> +
> + noa_attr->index = u32_get_bits(noa->noa_attr,
> + WMI_P2P_NOA_INFO_INDEX);
> + noa_attr->oppps_ctwindow = ctwindow;
> + if (oppps)
> + noa_attr->oppps_ctwindow |= IEEE80211_P2P_OPPPS_ENABLE_BIT;
> +
> + for (i = 0; i < noa_descriptors; i++) {
> + noa_attr->desc[i].count = noa->descriptors[i].type_count;
> + noa_attr->desc[i].duration =
> + cpu_to_le32(noa->descriptors[i].duration);
> + noa_attr->desc[i].interval =
> + cpu_to_le32(noa->descriptors[i].interval);
> + noa_attr->desc[i].start_time =
> + cpu_to_le32(noa->descriptors[i].start_time);
> + }
> +
> + attr_len = 2; /* index + oppps_ctwindow */
> + attr_len += noa_descriptors * sizeof(struct ieee80211_p2p_noa_desc);
> + *noa_attr_len = __cpu_to_le16(attr_len);
> +}
> +
> +static size_t
> +ath11k_p2p_noa_ie_len_compute(const struct ath11k_wmi_p2p_noa_info *noa)
> +{
> + size_t len = 0;
> +
> + if (!(u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_DESC_NUM)) &&
> + !(u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_OPP_PS)))
> + return 0;
> +
> + len += 1 + 1 + 4; /* EID + len + OUI */
> + len += 1 + 2; /* noa attr + attr len */
> + len += 1 + 1; /* index + oppps_ctwindow */
> + len += u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_DESC_NUM) *

here again do you need to validate that this doesn't exceed
WMI_P2P_MAX_NOA_DESCRIPTORS?

also rather than call u32_get_bits() twice for the same field, call it
once and cache the result

> + sizeof(struct ieee80211_p2p_noa_desc);
> +
> + return len;
> +}
> +
> +static void ath11k_p2p_noa_ie_assign(struct ath11k_vif *arvif, void *ie,
> + size_t len)
> +{
> + struct ath11k *ar = arvif->ar;
> +
> + lockdep_assert_held(&ar->data_lock);
> +
> + kfree(arvif->u.ap.noa_data);
> +
> + arvif->u.ap.noa_data = ie;
> + arvif->u.ap.noa_len = len;
> +}
> +
> +static void __ath11k_p2p_noa_update(struct ath11k_vif *arvif,
> + const struct ath11k_wmi_p2p_noa_info *noa)
> +{
> + struct ath11k *ar = arvif->ar;
> + void *ie;
> + size_t len;
> +
> + lockdep_assert_held(&ar->data_lock);
> +
> + ath11k_p2p_noa_ie_assign(arvif, NULL, 0);
> +
> + len = ath11k_p2p_noa_ie_len_compute(noa);
> + if (!len)
> + return;
> +
> + ie = kmalloc(len, GFP_ATOMIC);
> + if (!ie)
> + return;
> +
> + ath11k_p2p_noa_ie_fill(ie, len, noa);
> + ath11k_p2p_noa_ie_assign(arvif, ie, len); }
> +
> +void ath11k_p2p_noa_update(struct ath11k_vif *arvif,
> + const struct ath11k_wmi_p2p_noa_info *noa)
> +{
> + struct ath11k *ar = arvif->ar;
> +
> + spin_lock_bh(&ar->data_lock);
> + __ath11k_p2p_noa_update(arvif, noa);
> + spin_unlock_bh(&ar->data_lock);
> +}
> +
> +static void ath11k_p2p_noa_update_vdev_iter(void *data, u8 *mac,
> + struct ieee80211_vif *vif)
> +{
> + struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
> + struct ath11k_p2p_noa_arg *arg = data;
> +
> + if (arvif->vdev_id != arg->vdev_id)
> + return;
> +
> + ath11k_p2p_noa_update(arvif, arg->noa);
> +}
> +
> +void ath11k_p2p_noa_update_by_vdev_id(struct ath11k *ar, u32 vdev_id,
> + const struct ath11k_wmi_p2p_noa_info *noa)
> +{
> + struct ath11k_p2p_noa_arg arg = {
> + .vdev_id = vdev_id,
> + .noa = noa,
> + };
> +
> + ieee80211_iterate_active_interfaces_atomic(ar->hw,
> + IEEE80211_IFACE_ITER_NORMAL,
> + ath11k_p2p_noa_update_vdev_iter,
> + &arg);
> +}
> +

As part of "b4 shazam" I'm getting:
ath/.git/rebase-apply/patch:175: new blank line at EOF.
+

which I think comes from here. so remove the blank line at the end of file

> diff --git a/drivers/net/wireless/ath/ath11k/p2p.h b/drivers/net/wireless/ath/ath11k/p2p.h
> new file mode 100644
> index 000000000000..ebd076f7fe7f
> --- /dev/null
> +++ b/drivers/net/wireless/ath/ath11k/p2p.h
> @@ -0,0 +1,23 @@
> +/* SPDX-License-Identifier: BSD-3-Clause-Clear */
> +/*
> + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +
> +#ifndef ATH11K_P2P_H
> +#define ATH11K_P2P_H
> +
> +#include "wmi.h"
> +
> +struct ath11k_wmi_p2p_noa_info;
> +
> +struct ath11k_p2p_noa_arg {
> + u32 vdev_id;
> + const struct ath11k_wmi_p2p_noa_info *noa;
> +};
> +
> +void ath11k_p2p_noa_update(struct ath11k_vif *arvif,
> + const struct ath11k_wmi_p2p_noa_info *noa);
> +void ath11k_p2p_noa_update_by_vdev_id(struct ath11k *ar, u32 vdev_id,
> + const struct ath11k_wmi_p2p_noa_info *noa);
> +#endif
> +

ditto here:
ath/.git/rebase-apply/patch:204: new blank line at EOF.
+


> diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
> index d86fcdd374c6..bbccddd7d729 100644
> --- a/drivers/net/wireless/ath/ath11k/wmi.c
> +++ b/drivers/net/wireless/ath/ath11k/wmi.c
> @@ -20,6 +20,7 @@
> #include "hw.h"
> #include "peer.h"
> #include "testmode.h"
> +#include "p2p.h"
>
> struct wmi_tlv_policy {
> size_t min_len;
> @@ -154,6 +155,10 @@ static const struct wmi_tlv_policy wmi_tlv_policies[] = {
> .min_len = sizeof(struct wmi_per_chain_rssi_stats) },
> [WMI_TAG_TWT_ADD_DIALOG_COMPLETE_EVENT] = {
> .min_len = sizeof(struct wmi_twt_add_dialog_event) },
> + [WMI_TAG_P2P_NOA_INFO] = {
> + .min_len = sizeof(struct ath11k_wmi_p2p_noa_info) },
> + [WMI_TAG_P2P_NOA_EVENT] = {
> + .min_len = sizeof(struct wmi_p2p_noa_event) },
> };
>
> #define PRIMAP(_hw_mode_) \
> @@ -981,7 +986,7 @@ int ath11k_wmi_vdev_start(struct ath11k *ar, struct wmi_vdev_start_req_arg *arg,
> FIELD_PREP(WMI_TLV_LEN, 0);
>
> /* Note: This is a nested TLV containing:
> - * [wmi_tlv][wmi_p2p_noa_descriptor][wmi_tlv]..
> + * [wmi_tlv][ath11k_wmi_p2p_noa_descriptor][wmi_tlv]..
> */
>
> ptr += sizeof(*tlv);
> @@ -8645,6 +8650,53 @@ static void ath11k_wmi_gtk_offload_status_event(struct ath11k_base *ab,
> kfree(tb);
> }
>
> +static int ath11k_wmi_p2p_noa_event(struct ath11k_base *ab,
> + struct sk_buff *skb)
> +{
> + const void **tb;
> + const struct wmi_p2p_noa_event *ev;
> + const struct ath11k_wmi_p2p_noa_info *noa;
> + struct ath11k *ar;
> + int ret, vdev_id;
> +
> + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
> + if (IS_ERR(tb)) {
> + ret = PTR_ERR(tb);
> + ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
> + return ret;
> + }
> +
> + ev = tb[WMI_TAG_P2P_NOA_EVENT];
> + noa = tb[WMI_TAG_P2P_NOA_INFO];
> +
> + if (!ev || !noa) {
> + ret = -EPROTO;
> + goto out;
> + }
> +
> + vdev_id = ev->vdev_id;
> +
> + ath11k_dbg(ab, ATH11K_DBG_WMI,
> + "wmi tlv p2p noa vdev_id %i descriptors %u\n",
> + vdev_id, u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_DESC_NUM));
> + rcu_read_lock();
> + ar = ath11k_mac_get_ar_by_vdev_id(ab, vdev_id);
> + if (!ar) {
> + ath11k_warn(ab, "invalid vdev id %d in P2P NoA event\n",
> + vdev_id);
> + ret = -EINVAL;
> + goto unlock;
> + }
> +
> + ath11k_p2p_noa_update_by_vdev_id(ar, vdev_id, noa);
> +
> +unlock:
> + rcu_read_unlock();
> +out:
> + kfree(tb);
> + return 0;
> +}
> +
> static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb)
> {
> struct wmi_cmd_hdr *cmd_hdr;
> @@ -8772,6 +8824,9 @@ static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb)
> case WMI_GTK_OFFLOAD_STATUS_EVENTID:
> ath11k_wmi_gtk_offload_status_event(ab, skb);
> break;
> + case WMI_P2P_NOA_EVENTID:
> + ath11k_wmi_p2p_noa_event(ab, skb);
> + break;
> default:
> ath11k_dbg(ab, ATH11K_DBG_WMI, "unsupported event id 0x%x\n", id);
> break;
> diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
> index 4c20202947c7..564f4a9ac8ce 100644
> --- a/drivers/net/wireless/ath/ath11k/wmi.h
> +++ b/drivers/net/wireless/ath/ath11k/wmi.h

drivers/net/wireless/ath/ath11k/wmi.h QuIC copyright missing 2024

> @@ -3630,6 +3630,37 @@ struct wmi_ftm_event_msg {
> u8 data[];
> } __packed;
>
> +#define WMI_P2P_MAX_NOA_DESCRIPTORS 4
> +
> +struct wmi_p2p_noa_event {
> + u32 vdev_id;
> +} __packed;
> +
> +struct ath11k_wmi_p2p_noa_descriptor {
> + u32 type_count; /* 255: continuous schedule, 0: reserved */
> + u32 duration; /* Absent period duration in micro seconds */
> + u32 interval; /* Absent period interval in micro seconds */
> + u32 start_time; /* 32 bit tsf time when in starts */
> +} __packed;
> +
> +#define WMI_P2P_NOA_INFO_CHANGED_FLAG BIT(0)
> +#define WMI_P2P_NOA_INFO_INDEX GENMASK(15, 8)
> +#define WMI_P2P_NOA_INFO_OPP_PS BIT(16)
> +#define WMI_P2P_NOA_INFO_CTWIN_TU GENMASK(23, 17)
> +#define WMI_P2P_NOA_INFO_DESC_NUM GENMASK(31, 24)
> +
> +struct ath11k_wmi_p2p_noa_info {
> + /* Bit 0 - Flag to indicate an update in NOA schedule
> + * Bits 7-1 - Reserved
> + * Bits 15-8 - Index (identifies the instance of NOA sub element)
> + * Bit 16 - Opp PS state of the AP
> + * Bits 23-17 - Ctwindow in TUs
> + * Bits 31-24 - Number of NOA descriptors
> + */
> + u32 noa_attr;
> + struct ath11k_wmi_p2p_noa_descriptor descriptors[WMI_P2P_MAX_NOA_DESCRIPTORS];

so firmware always sends the max number of records even if Bits 31-24 -
Number of NOA descriptors indicates a smaller number?

> +} __packed;
> +
> #define WMI_BEACON_TX_BUFFER_SIZE 512
>
> #define WMI_EMA_TMPL_IDX_SHIFT 8

I'm seeing things today I probably missed in the ath12k review, so let's
make sure that when this is merged that ath12k si updated as well.

/jeff

2024-02-26 20:41:07

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH 5/6] wifi: ath11k: invert scan flag WMI_SCAN_FILTER_PROBE_REQ for QCA6390/WCN6855/QCA2066

On 2/25/2024 10:02 PM, Kang Yang wrote:
> Current ROC scan will filter probe request. But probe request is
> necessary for P2P mode. A P2P device cannot be discovered by others if
> it doesn't respond to others' probe request.
>
> So invert scan flag WMI_SCAN_FILTER_PROBE_REQ for
> QCA6390/WCN6855/QCA2066.
>
> Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.37
> Tested-on: QCA2066 hw2.1 PCI WLAN.HSP.1.1-03926.13-QCAHSPSWPL_V2_SILICONZ_CE-2.52297.2
>
> Signed-off-by: Kang Yang <[email protected]>
> ---
> drivers/net/wireless/ath/ath11k/wmi.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
> index bbccddd7d729..1dd0cbdda199 100644
> --- a/drivers/net/wireless/ath/ath11k/wmi.c
> +++ b/drivers/net/wireless/ath/ath11k/wmi.c
> @@ -2317,6 +2317,9 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar,
> ether_addr_copy(cmd->mac_addr.addr, params->mac_addr.addr);
> ether_addr_copy(cmd->mac_mask.addr, params->mac_mask.addr);
>
> + if (ar->ab->hw_params.single_pdev_only)
> + cmd->scan_ctrl_flags ^= WMI_SCAN_FILTER_PROBE_REQ;
> +

Why is this being done in WMI? Ideally WMI should just be doing host to
firmware translation, so seems this should be further up the stack, i.e.
in ath11k_mac_op_hw_scan() / ath11k_mac_op_remain_on_channel()

It also seems strange to invert the flag (which assumes a known starting
value) instead of just explicitly setting it to the required value.

> ptr += sizeof(*cmd);
>
> len = params->num_chan * sizeof(u32);


2024-02-26 20:42:06

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH 6/6] wifi: ath11k: advertise P2P dev support for QCA6390/WCN6855/QCA2066

On 2/25/2024 10:02 PM, Kang Yang wrote:
> Now that all the necessary pieces are implemented we can enable P2P
> support for QCA6390/WCN6855/QCA2066.
>
> Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.37
> Tested-on: QCA2066 hw2.1 PCI WLAN.HSP.1.1-03926.13-QCAHSPSWPL_V2_SILICONZ_CE-2.52297.2
>
> Signed-off-by: Kang Yang <[email protected]>
Acked-by: Jeff Johnson <[email protected]>


2024-02-26 20:59:54

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH 3/6] wifi: ath11k: implement handling of P2P NoA event

On 2/26/2024 11:53 AM, Jeff Johnson wrote:
> On 2/25/2024 10:02 PM, Kang Yang wrote:
>> diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
>> index 4c20202947c7..564f4a9ac8ce 100644
>> --- a/drivers/net/wireless/ath/ath11k/wmi.h
>> +++ b/drivers/net/wireless/ath/ath11k/wmi.h
>
> drivers/net/wireless/ath/ath11k/wmi.h QuIC copyright missing 2024

I just posted the following patch (spotted while reviewing your series):
wifi: ath11k: remove obsolete struct wmi_start_scan_arg

My patch is updating this copyright so you don't need to.

/jeff


2024-02-27 03:17:01

by Kang Yang

[permalink] [raw]
Subject: Re: [PATCH 3/6] wifi: ath11k: implement handling of P2P NoA event



On 2/27/2024 3:53 AM, Jeff Johnson wrote:
> On 2/25/2024 10:02 PM, Kang Yang wrote:
>> The NoA(Notice of Absence) attribute is used by the P2P Group Owner to
>> signal its absence due to power save timing, concurrent operation, or
>> off-channel scanning. It is also used in the P2P Presence Request-Response
>> mechanism.
>>
>> The NoA attribute shall be present in the P2P IE in the beacon frames
>> transmitted by a P2P Group Owner when a NoA schedule is being advertised,
>> or when the CTWindow is non-zero.
>>
>> So add support to update P2P information after P2P GO is up through
>> event WMI_P2P_NOA_EVENTID, and always put it in probe resp.
>>
>> Create p2p.c and p2p.h for P2P related functions and definitions.
>>
>> Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.37
>> Tested-on: QCA2066 hw2.1 PCI WLAN.HSP.1.1-03926.13-QCAHSPSWPL_V2_SILICONZ_CE-2.52297.2
>>
>> Signed-off-by: Kang Yang <[email protected]>
>> ---
>> drivers/net/wireless/ath/ath11k/Makefile | 3 +-
>> drivers/net/wireless/ath/ath11k/p2p.c | 145 +++++++++++++++++++++++
>> drivers/net/wireless/ath/ath11k/p2p.h | 23 ++++
>> drivers/net/wireless/ath/ath11k/wmi.c | 57 ++++++++-
>> drivers/net/wireless/ath/ath11k/wmi.h | 31 +++++
>> 5 files changed, 257 insertions(+), 2 deletions(-)
>> create mode 100644 drivers/net/wireless/ath/ath11k/p2p.c
>> create mode 100644 drivers/net/wireless/ath/ath11k/p2p.h
>>
>> diff --git a/drivers/net/wireless/ath/ath11k/Makefile b/drivers/net/wireless/ath/ath11k/Makefile
>> index 2c94d50ae36f..43d2d8ddcdc0 100644
>> --- a/drivers/net/wireless/ath/ath11k/Makefile
>> +++ b/drivers/net/wireless/ath/ath11k/Makefile
>> @@ -18,7 +18,8 @@ ath11k-y += core.o \
>> dbring.o \
>> hw.o \
>> pcic.o \
>> - fw.o
>> + fw.o \
>> + p2p.o
>>
>> ath11k-$(CONFIG_ATH11K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o
>> ath11k-$(CONFIG_NL80211_TESTMODE) += testmode.o
>> diff --git a/drivers/net/wireless/ath/ath11k/p2p.c b/drivers/net/wireless/ath/ath11k/p2p.c
>> new file mode 100644
>> index 000000000000..bfaeea12bc09
>> --- /dev/null
>> +++ b/drivers/net/wireless/ath/ath11k/p2p.c
>> @@ -0,0 +1,145 @@
>> +// SPDX-License-Identifier: BSD-3-Clause-Clear
>> +/*
>> + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
>> + */
>> +
>> +#include "core.h"
>> +#include "wmi.h"
>> +#include "mac.h"
>> +#include "p2p.h"
>> +
>> +static void ath11k_p2p_noa_ie_fill(u8 *data, size_t len,
>> + const struct ath11k_wmi_p2p_noa_info *noa)
>> +{
>> + struct ieee80211_p2p_noa_attr *noa_attr;
>> + u8 ctwindow = u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_CTWIN_TU);
>> + bool oppps = u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_OPP_PS);
>> + __le16 *noa_attr_len;
>> + u16 attr_len;
>> + u8 noa_descriptors = u32_get_bits(noa->noa_attr,
>> + WMI_P2P_NOA_INFO_DESC_NUM);
>
> do you need to validate that this doesn't exceed
> WMI_P2P_MAX_NOA_DESCRIPTORS?

Will add this check.

>
>> + int i;
>> +
>> + /* P2P IE */
>> + data[0] = WLAN_EID_VENDOR_SPECIFIC;
>> + data[1] = len - 2;
>> + data[2] = (WLAN_OUI_WFA >> 16) & 0xff;
>> + data[3] = (WLAN_OUI_WFA >> 8) & 0xff;
>> + data[4] = (WLAN_OUI_WFA >> 0) & 0xff;
>> + data[5] = WLAN_OUI_TYPE_WFA_P2P;
>> +
>> + /* NOA ATTR */
>> + data[6] = IEEE80211_P2P_ATTR_ABSENCE_NOTICE;
>> + noa_attr_len = (__le16 *)&data[7]; /* 2 bytes */
>> + noa_attr = (struct ieee80211_p2p_noa_attr *)&data[9];
>> +
>> + noa_attr->index = u32_get_bits(noa->noa_attr,
>> + WMI_P2P_NOA_INFO_INDEX);
>> + noa_attr->oppps_ctwindow = ctwindow;
>> + if (oppps)
>> + noa_attr->oppps_ctwindow |= IEEE80211_P2P_OPPPS_ENABLE_BIT;
>> +
>> + for (i = 0; i < noa_descriptors; i++) {
>> + noa_attr->desc[i].count = noa->descriptors[i].type_count;
>> + noa_attr->desc[i].duration =
>> + cpu_to_le32(noa->descriptors[i].duration);
>> + noa_attr->desc[i].interval =
>> + cpu_to_le32(noa->descriptors[i].interval);
>> + noa_attr->desc[i].start_time =
>> + cpu_to_le32(noa->descriptors[i].start_time);
>> + }
>> +
>> + attr_len = 2; /* index + oppps_ctwindow */
>> + attr_len += noa_descriptors * sizeof(struct ieee80211_p2p_noa_desc);
>> + *noa_attr_len = __cpu_to_le16(attr_len);
>> +}
>> +
>> +static size_t
>> +ath11k_p2p_noa_ie_len_compute(const struct ath11k_wmi_p2p_noa_info *noa)
>> +{
>> + size_t len = 0;
>> +
>> + if (!(u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_DESC_NUM)) &&
>> + !(u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_OPP_PS)))
>> + return 0;
>> +
>> + len += 1 + 1 + 4; /* EID + len + OUI */
>> + len += 1 + 2; /* noa attr + attr len */
>> + len += 1 + 1; /* index + oppps_ctwindow */
>> + len += u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_DESC_NUM) *
>
> here again do you need to validate that this doesn't exceed
> WMI_P2P_MAX_NOA_DESCRIPTORS?
>
> also rather than call u32_get_bits() twice for the same field, call it
> once and cache the result
>
>> + sizeof(struct ieee80211_p2p_noa_desc);
>> +
>> + return len;
>> +}
>> +
>> +static void ath11k_p2p_noa_ie_assign(struct ath11k_vif *arvif, void *ie,
>> + size_t len)
>> +{
>> + struct ath11k *ar = arvif->ar;
>> +
>> + lockdep_assert_held(&ar->data_lock);
>> +
>> + kfree(arvif->u.ap.noa_data);
>> +
>> + arvif->u.ap.noa_data = ie;
>> + arvif->u.ap.noa_len = len;
>> +}
>> +
>> +static void __ath11k_p2p_noa_update(struct ath11k_vif *arvif,
>> + const struct ath11k_wmi_p2p_noa_info *noa)
>> +{
>> + struct ath11k *ar = arvif->ar;
>> + void *ie;
>> + size_t len;
>> +
>> + lockdep_assert_held(&ar->data_lock);
>> +
>> + ath11k_p2p_noa_ie_assign(arvif, NULL, 0);
>> +
>> + len = ath11k_p2p_noa_ie_len_compute(noa);
>> + if (!len)
>> + return;
>> +
>> + ie = kmalloc(len, GFP_ATOMIC);
>> + if (!ie)
>> + return;
>> +
>> + ath11k_p2p_noa_ie_fill(ie, len, noa);
>> + ath11k_p2p_noa_ie_assign(arvif, ie, len); }
>> +
>> +void ath11k_p2p_noa_update(struct ath11k_vif *arvif,
>> + const struct ath11k_wmi_p2p_noa_info *noa)
>> +{
>> + struct ath11k *ar = arvif->ar;
>> +
>> + spin_lock_bh(&ar->data_lock);
>> + __ath11k_p2p_noa_update(arvif, noa);
>> + spin_unlock_bh(&ar->data_lock);
>> +}
>> +
>> +static void ath11k_p2p_noa_update_vdev_iter(void *data, u8 *mac,
>> + struct ieee80211_vif *vif)
>> +{
>> + struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
>> + struct ath11k_p2p_noa_arg *arg = data;
>> +
>> + if (arvif->vdev_id != arg->vdev_id)
>> + return;
>> +
>> + ath11k_p2p_noa_update(arvif, arg->noa);
>> +}
>> +
>> +void ath11k_p2p_noa_update_by_vdev_id(struct ath11k *ar, u32 vdev_id,
>> + const struct ath11k_wmi_p2p_noa_info *noa)
>> +{
>> + struct ath11k_p2p_noa_arg arg = {
>> + .vdev_id = vdev_id,
>> + .noa = noa,
>> + };
>> +
>> + ieee80211_iterate_active_interfaces_atomic(ar->hw,
>> + IEEE80211_IFACE_ITER_NORMAL,
>> + ath11k_p2p_noa_update_vdev_iter,
>> + &arg);
>> +}
>> +
>
> As part of "b4 shazam" I'm getting:
> ath/.git/rebase-apply/patch:175: new blank line at EOF.
> +
>
> which I think comes from here. so remove the blank line at the end of file
>
>> diff --git a/drivers/net/wireless/ath/ath11k/p2p.h b/drivers/net/wireless/ath/ath11k/p2p.h
>> new file mode 100644
>> index 000000000000..ebd076f7fe7f
>> --- /dev/null
>> +++ b/drivers/net/wireless/ath/ath11k/p2p.h
>> @@ -0,0 +1,23 @@
>> +/* SPDX-License-Identifier: BSD-3-Clause-Clear */
>> +/*
>> + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
>> + */
>> +
>> +#ifndef ATH11K_P2P_H
>> +#define ATH11K_P2P_H
>> +
>> +#include "wmi.h"
>> +
>> +struct ath11k_wmi_p2p_noa_info;
>> +
>> +struct ath11k_p2p_noa_arg {
>> + u32 vdev_id;
>> + const struct ath11k_wmi_p2p_noa_info *noa;
>> +};
>> +
>> +void ath11k_p2p_noa_update(struct ath11k_vif *arvif,
>> + const struct ath11k_wmi_p2p_noa_info *noa);
>> +void ath11k_p2p_noa_update_by_vdev_id(struct ath11k *ar, u32 vdev_id,
>> + const struct ath11k_wmi_p2p_noa_info *noa);
>> +#endif
>> +
>
> ditto here:
> ath/.git/rebase-apply/patch:204: new blank line at EOF.
> +
>
>
>> diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
>> index d86fcdd374c6..bbccddd7d729 100644
>> --- a/drivers/net/wireless/ath/ath11k/wmi.c
>> +++ b/drivers/net/wireless/ath/ath11k/wmi.c
>> @@ -20,6 +20,7 @@
>> #include "hw.h"
>> #include "peer.h"
>> #include "testmode.h"
>> +#include "p2p.h"
>>
>> struct wmi_tlv_policy {
>> size_t min_len;
>> @@ -154,6 +155,10 @@ static const struct wmi_tlv_policy wmi_tlv_policies[] = {
>> .min_len = sizeof(struct wmi_per_chain_rssi_stats) },
>> [WMI_TAG_TWT_ADD_DIALOG_COMPLETE_EVENT] = {
>> .min_len = sizeof(struct wmi_twt_add_dialog_event) },
>> + [WMI_TAG_P2P_NOA_INFO] = {
>> + .min_len = sizeof(struct ath11k_wmi_p2p_noa_info) },
>> + [WMI_TAG_P2P_NOA_EVENT] = {
>> + .min_len = sizeof(struct wmi_p2p_noa_event) },
>> };
>>
>> #define PRIMAP(_hw_mode_) \
>> @@ -981,7 +986,7 @@ int ath11k_wmi_vdev_start(struct ath11k *ar, struct wmi_vdev_start_req_arg *arg,
>> FIELD_PREP(WMI_TLV_LEN, 0);
>>
>> /* Note: This is a nested TLV containing:
>> - * [wmi_tlv][wmi_p2p_noa_descriptor][wmi_tlv]..
>> + * [wmi_tlv][ath11k_wmi_p2p_noa_descriptor][wmi_tlv]..
>> */
>>
>> ptr += sizeof(*tlv);
>> @@ -8645,6 +8650,53 @@ static void ath11k_wmi_gtk_offload_status_event(struct ath11k_base *ab,
>> kfree(tb);
>> }
>>
>> +static int ath11k_wmi_p2p_noa_event(struct ath11k_base *ab,
>> + struct sk_buff *skb)
>> +{
>> + const void **tb;
>> + const struct wmi_p2p_noa_event *ev;
>> + const struct ath11k_wmi_p2p_noa_info *noa;
>> + struct ath11k *ar;
>> + int ret, vdev_id;
>> +
>> + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
>> + if (IS_ERR(tb)) {
>> + ret = PTR_ERR(tb);
>> + ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
>> + return ret;
>> + }
>> +
>> + ev = tb[WMI_TAG_P2P_NOA_EVENT];
>> + noa = tb[WMI_TAG_P2P_NOA_INFO];
>> +
>> + if (!ev || !noa) {
>> + ret = -EPROTO;
>> + goto out;
>> + }
>> +
>> + vdev_id = ev->vdev_id;
>> +
>> + ath11k_dbg(ab, ATH11K_DBG_WMI,
>> + "wmi tlv p2p noa vdev_id %i descriptors %u\n",
>> + vdev_id, u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_DESC_NUM));
>> + rcu_read_lock();
>> + ar = ath11k_mac_get_ar_by_vdev_id(ab, vdev_id);
>> + if (!ar) {
>> + ath11k_warn(ab, "invalid vdev id %d in P2P NoA event\n",
>> + vdev_id);
>> + ret = -EINVAL;
>> + goto unlock;
>> + }
>> +
>> + ath11k_p2p_noa_update_by_vdev_id(ar, vdev_id, noa);
>> +
>> +unlock:
>> + rcu_read_unlock();
>> +out:
>> + kfree(tb);
>> + return 0;
>> +}
>> +
>> static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb)
>> {
>> struct wmi_cmd_hdr *cmd_hdr;
>> @@ -8772,6 +8824,9 @@ static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb)
>> case WMI_GTK_OFFLOAD_STATUS_EVENTID:
>> ath11k_wmi_gtk_offload_status_event(ab, skb);
>> break;
>> + case WMI_P2P_NOA_EVENTID:
>> + ath11k_wmi_p2p_noa_event(ab, skb);
>> + break;
>> default:
>> ath11k_dbg(ab, ATH11K_DBG_WMI, "unsupported event id 0x%x\n", id);
>> break;
>> diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
>> index 4c20202947c7..564f4a9ac8ce 100644
>> --- a/drivers/net/wireless/ath/ath11k/wmi.h
>> +++ b/drivers/net/wireless/ath/ath11k/wmi.h
>
> drivers/net/wireless/ath/ath11k/wmi.h QuIC copyright missing 2024
>
>> @@ -3630,6 +3630,37 @@ struct wmi_ftm_event_msg {
>> u8 data[];
>> } __packed;
>>
>> +#define WMI_P2P_MAX_NOA_DESCRIPTORS 4
>> +
>> +struct wmi_p2p_noa_event {
>> + u32 vdev_id;
>> +} __packed;
>> +
>> +struct ath11k_wmi_p2p_noa_descriptor {
>> + u32 type_count; /* 255: continuous schedule, 0: reserved */
>> + u32 duration; /* Absent period duration in micro seconds */
>> + u32 interval; /* Absent period interval in micro seconds */
>> + u32 start_time; /* 32 bit tsf time when in starts */
>> +} __packed;
>> +
>> +#define WMI_P2P_NOA_INFO_CHANGED_FLAG BIT(0)
>> +#define WMI_P2P_NOA_INFO_INDEX GENMASK(15, 8)
>> +#define WMI_P2P_NOA_INFO_OPP_PS BIT(16)
>> +#define WMI_P2P_NOA_INFO_CTWIN_TU GENMASK(23, 17)
>> +#define WMI_P2P_NOA_INFO_DESC_NUM GENMASK(31, 24)
>> +
>> +struct ath11k_wmi_p2p_noa_info {
>> + /* Bit 0 - Flag to indicate an update in NOA schedule
>> + * Bits 7-1 - Reserved
>> + * Bits 15-8 - Index (identifies the instance of NOA sub element)
>> + * Bit 16 - Opp PS state of the AP
>> + * Bits 23-17 - Ctwindow in TUs
>> + * Bits 31-24 - Number of NOA descriptors
>> + */
>> + u32 noa_attr;
>> + struct ath11k_wmi_p2p_noa_descriptor descriptors[WMI_P2P_MAX_NOA_DESCRIPTORS];
>
> so firmware always sends the max number of records even if Bits 31-24 -
> Number of NOA descriptors indicates a smaller number?
>
>> +} __packed;
>> +
>> #define WMI_BEACON_TX_BUFFER_SIZE 512
>>
>> #define WMI_EMA_TMPL_IDX_SHIFT 8
>
> I'm seeing things today I probably missed in the ath12k review, so let's
> make sure that when this is merged that ath12k si updated as well.
>
> /jeff

2024-02-27 03:17:14

by Kang Yang

[permalink] [raw]
Subject: Re: [PATCH 5/6] wifi: ath11k: invert scan flag WMI_SCAN_FILTER_PROBE_REQ for QCA6390/WCN6855/QCA2066



On 2/27/2024 4:40 AM, Jeff Johnson wrote:
> On 2/25/2024 10:02 PM, Kang Yang wrote:
>> Current ROC scan will filter probe request. But probe request is
>> necessary for P2P mode. A P2P device cannot be discovered by others if
>> it doesn't respond to others' probe request.
>>
>> So invert scan flag WMI_SCAN_FILTER_PROBE_REQ for
>> QCA6390/WCN6855/QCA2066.
>>
>> Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.37
>> Tested-on: QCA2066 hw2.1 PCI WLAN.HSP.1.1-03926.13-QCAHSPSWPL_V2_SILICONZ_CE-2.52297.2
>>
>> Signed-off-by: Kang Yang <[email protected]>
>> ---
>> drivers/net/wireless/ath/ath11k/wmi.c | 3 +++
>> 1 file changed, 3 insertions(+)
>>
>> diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
>> index bbccddd7d729..1dd0cbdda199 100644
>> --- a/drivers/net/wireless/ath/ath11k/wmi.c
>> +++ b/drivers/net/wireless/ath/ath11k/wmi.c
>> @@ -2317,6 +2317,9 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar,
>> ether_addr_copy(cmd->mac_addr.addr, params->mac_addr.addr);
>> ether_addr_copy(cmd->mac_mask.addr, params->mac_mask.addr);
>>
>> + if (ar->ab->hw_params.single_pdev_only)
>> + cmd->scan_ctrl_flags ^= WMI_SCAN_FILTER_PROBE_REQ;
>> +
>
> Why is this being done in WMI? Ideally WMI should just be doing host to
> firmware translation, so seems this should be further up the stack, i.e.
> in ath11k_mac_op_hw_scan() / ath11k_mac_op_remain_on_channel()
>

I referred to ath10k
you are right, i will move to hw_scan().


> It also seems strange to invert the flag (which assumes a known starting
> value) instead of just explicitly setting it to the required value.
>

When work as P2P, will call remain_on_channel(), then hw_scan().
scan_ctrl_flags will set WMI_SCAN_FILTER_PROBE_REQ in
remain_on_channel(). so later should reset this flag to 0 (1 -> 0,
accept probe request).

When work as station, won't call remain_on_channel(). There is no need
to accept probe request for station(i should also explain this point),
so need to set this flag to 1 (0 -> 1).

That's why i invert this flag here, but move to hw_scan() is better.



>> ptr += sizeof(*cmd);
>>
>> len = params->num_chan * sizeof(u32);
>

2024-02-27 07:06:05

by Kang Yang

[permalink] [raw]
Subject: Re: [PATCH 2/6] wifi: ath11k: add P2P IE in beacon template



On 2/27/2024 3:05 AM, Jeff Johnson wrote:
> On 2/25/2024 10:01 PM, Kang Yang wrote:
>> P2P Element is a necessary component of P2P protocol communication.
>> It contains the Vendor Specific Information Element which includes
>> the WFA OUI and an OUI Type indicating P2P.
>>
>> Add P2P IE in beacon template, and implement WMI interface for it.
>>
>> Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.37
>> Tested-on: QCA2066 hw2.1 PCI WLAN.HSP.1.1-03926.13-QCAHSPSWPL_V2_SILICONZ_CE-2.52297.2
>>
>> Signed-off-by: Kang Yang <[email protected]>
>> ---
>> drivers/net/wireless/ath/ath11k/mac.c | 103 ++++++++++++++++++++++++--
>> drivers/net/wireless/ath/ath11k/wmi.c | 39 ++++++++++
>> drivers/net/wireless/ath/ath11k/wmi.h | 9 +++
>> 3 files changed, 143 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
>> index 9240dedf3217..f52dd52dabbb 100644
>> --- a/drivers/net/wireless/ath/ath11k/mac.c
>> +++ b/drivers/net/wireless/ath/ath11k/mac.c
>> @@ -1430,10 +1430,67 @@ static bool ath11k_mac_set_nontx_vif_params(struct ath11k_vif *tx_arvif,
>> return false;
>> }
>>
>> -static void ath11k_mac_set_vif_params(struct ath11k_vif *arvif,
>> - struct sk_buff *bcn)
>> +static int ath11k_mac_setup_bcn_p2p_ie(struct ath11k_vif *arvif,
>> + struct sk_buff *bcn)
>> {
>> + struct ath11k *ar = arvif->ar;
>> + struct ieee80211_mgmt *mgmt;
>> + const u8 *p2p_ie;
>> + int ret = 0;
>> +
>> + mgmt = (void *)bcn->data;
>> + p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
>> + mgmt->u.beacon.variable,
>> + bcn->len - (mgmt->u.beacon.variable -
>> + bcn->data));
>> + if (!p2p_ie)
>> + return -ENOENT;
>> +
>> + ret = ath11k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie);
>> + if (ret) {
>> + ath11k_warn(ar->ab, "failed to submit P2P GO bcn ie for vdev %i: %d\n",
>> + arvif->vdev_id, ret);
>> + return ret;
>> + }
>> +
>> + return ret;
>> +}
>> +
>> +static int ath11k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
>> + u8 oui_type, size_t ie_offset)
>> +{
>> + size_t len;
>> + const u8 *next, *end;
>> + u8 *ie;
>> +
>> + if (WARN_ON(skb->len < ie_offset))
>> + return -EINVAL;
>> +
>> + ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,
>> + skb->data + ie_offset,
>> + skb->len - ie_offset);
>> + if (!ie)
>> + return -ENOENT;
>> +
>> + len = ie[1] + 2;
>> + end = skb->data + skb->len;
>> + next = ie + len;
>> +
>> + if (WARN_ON(next > end))
>> + return -EINVAL;
>> +
>> + memmove(ie, next, end - next);
>> + skb_trim(skb, skb->len - len);
>> +
>> + return 0;
>> +}
>> +
>> +static int ath11k_mac_set_vif_params(struct ath11k_vif *arvif,
>> + struct sk_buff *bcn)
>> +{
>> + struct ath11k_base *ab = arvif->ar->ab;
>> struct ieee80211_mgmt *mgmt;
>> + int ret = 0;
>> u8 *ies;
>>
>> ies = bcn->data + ieee80211_get_hdrlen_from_skb(bcn);
>> @@ -1451,6 +1508,32 @@ static void ath11k_mac_set_vif_params(struct ath11k_vif *arvif,
>> arvif->wpaie_present = true;
>> else
>> arvif->wpaie_present = false;
>> +
>> + if (arvif->vif->type != NL80211_IFTYPE_AP || !arvif->vif->p2p)
>
> this logic isn't applicable for NL80211_IFTYPE_P2P_GO ?

The original intention here is to determine if it is P2P GO, if yes,
continue, otherwise return.


Maybe this judgment is a bit misleading, let me replace with
if (arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO) ?


>
>> + return ret;
>> +
>> + ret = ath11k_mac_setup_bcn_p2p_ie(arvif, bcn);
>> + if (ret) {
>> + ath11k_warn(ab, "failed to setup P2P GO bcn ie: %d\n",
>> + ret);
>> + return ret;
>> + }
>> +
>> + /* P2P IE is inserted by firmware automatically (as
>> + * configured above) so remove it from the base beacon
>> + * template to avoid duplicate P2P IEs in beacon frames.
>> + */
>> + ret = ath11k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA,
>> + WLAN_OUI_TYPE_WFA_P2P,
>> + offsetof(struct ieee80211_mgmt,
>> + u.beacon.variable));
>> + if (ret) {
>> + ath11k_warn(ab, "failed to remove P2P vendor ie: %d\n",
>> + ret);
>> + return ret;
>> + }
>> +
>> + return ret;
>> }
>>
>> static int ath11k_mac_setup_bcn_tmpl_ema(struct ath11k_vif *arvif)
>> @@ -1472,10 +1555,12 @@ static int ath11k_mac_setup_bcn_tmpl_ema(struct ath11k_vif *arvif)
>> return -EPERM;
>> }
>>
>> - if (tx_arvif == arvif)
>> - ath11k_mac_set_vif_params(tx_arvif, beacons->bcn[0].skb);
>> - else
>> + if (tx_arvif == arvif) {
>> + if (ath11k_mac_set_vif_params(tx_arvif, beacons->bcn[0].skb))
>> + return -EINVAL;
>> + } else {
>> arvif->wpaie_present = tx_arvif->wpaie_present;
>> + }
>>
>> for (i = 0; i < beacons->cnt; i++) {
>> if (tx_arvif != arvif && !nontx_vif_params_set)
>> @@ -1534,10 +1619,12 @@ static int ath11k_mac_setup_bcn_tmpl_mbssid(struct ath11k_vif *arvif)
>> return -EPERM;
>> }
>>
>> - if (tx_arvif == arvif)
>> - ath11k_mac_set_vif_params(tx_arvif, bcn);
>> - else if (!ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, bcn))
>> + if (tx_arvif == arvif) {
>> + if (ath11k_mac_set_vif_params(tx_arvif, bcn))
>> + return -EINVAL;
>> + } else if (!ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, bcn)) {
>> return -EINVAL;
>> + }
>>
>> ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn, 0);
>> kfree_skb(bcn);
>> diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
>> index 34ab9631ff36..d86fcdd374c6 100644
>> --- a/drivers/net/wireless/ath/ath11k/wmi.c
>> +++ b/drivers/net/wireless/ath/ath11k/wmi.c
>> @@ -1704,6 +1704,45 @@ int ath11k_wmi_send_bcn_offload_control_cmd(struct ath11k *ar,
>> return ret;
>> }
>>
>> +int ath11k_wmi_p2p_go_bcn_ie(struct ath11k *ar, u32 vdev_id,
>> + const u8 *p2p_ie)
>> +{
>> + struct ath11k_pdev_wmi *wmi = ar->wmi;
>> + struct wmi_p2p_go_set_beacon_ie_cmd *cmd;
>> + size_t p2p_ie_len, aligned_len;
>> + struct wmi_tlv *tlv;
>> + struct sk_buff *skb;
>> + int ret, len;
>> +
>> + p2p_ie_len = p2p_ie[1] + 2;
>> + aligned_len = roundup(p2p_ie_len, 4);
>> +
>> + len = sizeof(*cmd) + TLV_HDR_SIZE + aligned_len;
>> +
>> + skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
>> + if (!skb)
>> + return -ENOMEM;
>> +
>> + cmd = (struct wmi_p2p_go_set_beacon_ie_cmd *)skb->data;
>> + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_P2P_GO_SET_BEACON_IE) |
>> + FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
>> + cmd->vdev_id = vdev_id;
>> + cmd->ie_buf_len = p2p_ie_len;
>> +
>> + tlv = (struct wmi_tlv *)cmd->tlv;
>> + tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
>> + FIELD_PREP(WMI_TLV_LEN, aligned_len);
>> + memcpy(tlv->value, p2p_ie, p2p_ie_len);
>> +
>> + ret = ath11k_wmi_cmd_send(wmi, skb, WMI_P2P_GO_SET_BEACON_IE);
>> + if (ret) {
>> + ath11k_warn(ar->ab, "failed to send WMI_P2P_GO_SET_BEACON_IE\n");
>> + dev_kfree_skb(skb);
>> + }
>> +
>> + return ret;
>> +}
>> +
>> int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
>> struct ieee80211_mutable_offsets *offs,
>> struct sk_buff *bcn, u32 ema_params)
>> diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
>> index bb419e3abb00..4c20202947c7 100644
>> --- a/drivers/net/wireless/ath/ath11k/wmi.h
>> +++ b/drivers/net/wireless/ath/ath11k/wmi.h
>> @@ -3653,6 +3653,13 @@ struct wmi_bcn_tmpl_cmd {
>> u32 ema_params;
>> } __packed;
>>
>> +struct wmi_p2p_go_set_beacon_ie_cmd {
>> + u32 tlv_header;
>> + u32 vdev_id;
>> + u32 ie_buf_len;
>> + u8 tlv[];
>> +} __packed;
>> +
>> struct wmi_key_seq_counter {
>> u32 key_seq_counter_l;
>> u32 key_seq_counter_h;
>> @@ -6349,6 +6356,8 @@ int ath11k_wmi_cmd_send(struct ath11k_pdev_wmi *wmi, struct sk_buff *skb,
>> struct sk_buff *ath11k_wmi_alloc_skb(struct ath11k_wmi_base *wmi_sc, u32 len);
>> int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id,
>> struct sk_buff *frame);
>> +int ath11k_wmi_p2p_go_bcn_ie(struct ath11k *ar, u32 vdev_id,
>> + const u8 *p2p_ie);
>> int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
>> struct ieee80211_mutable_offsets *offs,
>> struct sk_buff *bcn, u32 ema_param);
>

2024-02-27 07:41:55

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 2/6] wifi: ath11k: add P2P IE in beacon template

On Tue, 2024-02-27 at 14:58 +0800, Kang Yang wrote:
>
> > > + if (arvif->vif->type != NL80211_IFTYPE_AP || !arvif->vif->p2p)
> >
> > this logic isn't applicable for NL80211_IFTYPE_P2P_GO ?
>
> The original intention here is to determine if it is P2P GO, if yes,
> continue, otherwise return.
>
>
> Maybe this judgment is a bit misleading, let me replace with
> if (arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO) ?

There's also

ieee80211_vif_type_p2p(arvif->vif) != NL80211_IFTYPE_P2P_GO

if you wanted to write it that way.

@Jeff: NL80211_IFTYPE_P2P_GO is not used by mac80211 internally, it
translates that to vif->type==NL80211_IFTYPE_AP && vif->p2p==true.

johannes


2024-02-27 11:51:32

by Kang Yang

[permalink] [raw]
Subject: Re: [PATCH 3/6] wifi: ath11k: implement handling of P2P NoA event


>> +
>> +static void ath11k_p2p_noa_ie_fill(u8 *data, size_t len,
>> + const struct ath11k_wmi_p2p_noa_info *noa)
>> +{
>> + struct ieee80211_p2p_noa_attr *noa_attr;
>> + u8 ctwindow = u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_CTWIN_TU);
>> + bool oppps = u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_OPP_PS);
>> + __le16 *noa_attr_len;
>> + u16 attr_len;
>> + u8 noa_descriptors = u32_get_bits(noa->noa_attr,
>> + WMI_P2P_NOA_INFO_DESC_NUM);
>
> do you need to validate that this doesn't exceed
> WMI_P2P_MAX_NOA_DESCRIPTORS?
>
>> + int i;
>> +
>> + /* P2P IE */
……

>> +
>> +static size_t
>> +ath11k_p2p_noa_ie_len_compute(const struct ath11k_wmi_p2p_noa_info *noa)
>> +{
>> + size_t len = 0;
>> +
>> + if (!(u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_DESC_NUM)) &&
>> + !(u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_OPP_PS)))
>> + return 0;
>> +
>> + len += 1 + 1 + 4; /* EID + len + OUI */
>> + len += 1 + 2; /* noa attr + attr len */
>> + len += 1 + 1; /* index + oppps_ctwindow */
>> + len += u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_DESC_NUM) *
>
> here again do you need to validate that this doesn't exceed
> WMI_P2P_MAX_NOA_DESCRIPTORS?
>
> also rather than call u32_get_bits() twice for the same field, call it
> once and cache the result


Will add this check in ath11k_wmi_p2p_noa_event(), cause
ath11k_p2p_noa_ie_fill() and ath11k_p2p_noa_ie_len_compute will only be
called through ath11k_wmi_p2p_noa_event().


>
>> + sizeof(struct ieee80211_p2p_noa_desc);
>> +
>> + return len;
>> +}
>> +

……

>>
>> +static int ath11k_wmi_p2p_noa_event(struct ath11k_base *ab,
>> + struct sk_buff *skb)
>> +{
>> + const void **tb;
>> + const struct wmi_p2p_noa_event *ev;
>> + const struct ath11k_wmi_p2p_noa_info *noa;
>> + struct ath11k *ar;
>> + int ret, vdev_id;
>> +
>> + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
>> + if (IS_ERR(tb)) {
>> + ret = PTR_ERR(tb);
>> + ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
>> + return ret;
>> + }
>> +
>> + ev = tb[WMI_TAG_P2P_NOA_EVENT];
>> + noa = tb[WMI_TAG_P2P_NOA_INFO];
>> +
>> + if (!ev || !noa) {
>> + ret = -EPROTO;
>> + goto out;
>> + }
>> +
>> + vdev_id = ev->vdev_id;
>> +
>> + ath11k_dbg(ab, ATH11K_DBG_WMI,
>> + "wmi tlv p2p noa vdev_id %i descriptors %u\n",
>> + vdev_id, u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_DESC_NUM));
>> + rcu_read_lock();
>> + ar = ath11k_mac_get_ar_by_vdev_id(ab, vdev_id);
>> + if (!ar) {
>> + ath11k_warn(ab, "invalid vdev id %d in P2P NoA event\n",
>> + vdev_id);
>> + ret = -EINVAL;
>> + goto unlock;
>> + }
>> +
>> + ath11k_p2p_noa_update_by_vdev_id(ar, vdev_id, noa);
>> +
>> +unlock:
>> + rcu_read_unlock();
>> +out:
>> + kfree(tb);
>> + return 0;
>> +}
>> +
>> static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb)
>> {
>> struct wmi_cmd_hdr *cmd_hdr;
>> @@ -8772,6 +8824,9 @@ static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb)
>> case WMI_GTK_OFFLOAD_STATUS_EVENTID:
>> ath11k_wmi_gtk_offload_status_event(ab, skb);
>> break;
>> + case WMI_P2P_NOA_EVENTID:
>> + ath11k_wmi_p2p_noa_event(ab, skb);
>> + break;
>> default:
>> ath11k_dbg(ab, ATH11K_DBG_WMI, "unsupported event id 0x%x\n", id);
>> break;
>> diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
>> index 4c20202947c7..564f4a9ac8ce 100644
>> --- a/drivers/net/wireless/ath/ath11k/wmi.h
>> +++ b/drivers/net/wireless/ath/ath11k/wmi.h
>
> drivers/net/wireless/ath/ath11k/wmi.h QuIC copyright missing 2024
>
>> @@ -3630,6 +3630,37 @@ struct wmi_ftm_event_msg {
>> u8 data[];
>> } __packed;
>>
>> +#define WMI_P2P_MAX_NOA_DESCRIPTORS 4
>> +
>> +struct wmi_p2p_noa_event {
>> + u32 vdev_id;
>> +} __packed;
>> +
>> +struct ath11k_wmi_p2p_noa_descriptor {
>> + u32 type_count; /* 255: continuous schedule, 0: reserved */
>> + u32 duration; /* Absent period duration in micro seconds */
>> + u32 interval; /* Absent period interval in micro seconds */
>> + u32 start_time; /* 32 bit tsf time when in starts */
>> +} __packed;
>> +
>> +#define WMI_P2P_NOA_INFO_CHANGED_FLAG BIT(0)
>> +#define WMI_P2P_NOA_INFO_INDEX GENMASK(15, 8)
>> +#define WMI_P2P_NOA_INFO_OPP_PS BIT(16)
>> +#define WMI_P2P_NOA_INFO_CTWIN_TU GENMASK(23, 17)
>> +#define WMI_P2P_NOA_INFO_DESC_NUM GENMASK(31, 24)
>> +
>> +struct ath11k_wmi_p2p_noa_info {
>> + /* Bit 0 - Flag to indicate an update in NOA schedule
>> + * Bits 7-1 - Reserved
>> + * Bits 15-8 - Index (identifies the instance of NOA sub element)
>> + * Bit 16 - Opp PS state of the AP
>> + * Bits 23-17 - Ctwindow in TUs
>> + * Bits 31-24 - Number of NOA descriptors
>> + */
>> + u32 noa_attr;
>> + struct ath11k_wmi_p2p_noa_descriptor descriptors[WMI_P2P_MAX_NOA_DESCRIPTORS];
>
> so firmware always sends the max number of records even if Bits 31-24 -
> Number of NOA descriptors indicates a smaller number?
>

I just checked this, firmware will fill this according to valid number,
not max number.
But when fill WMI event for P2P NOA, the TLV length is based on max number.

Even if the valid number does not reach the max number, the remain part
is just empty.



So i think this definition is OK.



>> +} __packed;
>> +
>> #define WMI_BEACON_TX_BUFFER_SIZE 512
>>
>> #define WMI_EMA_TMPL_IDX_SHIFT 8
>
> I'm seeing things today I probably missed in the ath12k review, so let's
> make sure that when this is merged that ath12k si updated as well.

> /jeff

2024-02-27 15:07:54

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH 2/6] wifi: ath11k: add P2P IE in beacon template

On 2/26/2024 11:32 PM, Johannes Berg wrote:
> @Jeff: NL80211_IFTYPE_P2P_GO is not used by mac80211 internally, it
> translates that to vif->type==NL80211_IFTYPE_AP && vif->p2p==true.

Yesterday I was looking at another patch and while doing so noticed this
as well. Too many years of working with our downstream Android driver
where we use the P2P iftypes directly...

/jeff


2024-02-27 15:13:44

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 2/6] wifi: ath11k: add P2P IE in beacon template

On Tue, 2024-02-27 at 07:05 -0800, Jeff Johnson wrote:
> On 2/26/2024 11:32 PM, Johannes Berg wrote:
> > @Jeff: NL80211_IFTYPE_P2P_GO is not used by mac80211 internally, it
> > translates that to vif->type==NL80211_IFTYPE_AP && vif->p2p==true.
>
> Yesterday I was looking at another patch and while doing so noticed this
> as well. Too many years of working with our downstream Android driver
> where we use the P2P iftypes directly...

I do sometimes wonder if this was the right decision ... but I think
it'll be quite difficult to change it now.

johannes