2024-01-30 04:03:39

by Kang Yang

[permalink] [raw]
Subject: [PATCH v6 00/11] wifi: ath12k: P2P support for WCN7850

Add P2P support for WCN7850.

Kang Yang (11):
wifi: ath12k: fix broken structure wmi_vdev_create_cmd
wifi: ath12k: fix incorrect logic of calculating vdev_stats_id
wifi: ath12k: change interface combination for P2P mode
wifi: ath12k: add P2P IE in beacon template
wifi: ath12k: implement handling of P2P NoA event
wifi: ath12k: implement remain on channel for P2P mode
wifi: ath12k: change WLAN_SCAN_PARAMS_MAX_IE_LEN from 256 to 512
wifi: ath12k: allow specific mgmt frame tx while vdev is not up
wifi: ath12k: move peer delete after vdev stop of station for WCN7850
wifi: ath12k: designating channel frequency for ROC scan
wifi: ath12k: advertise P2P dev support for WCN7850

v6: move patch #7, #8 to patch #1, #2(Jeff).
v5:
1. move patch #10 to patch #8.
2. change commit log for patch #6 and patch #8.
3. simplify assignment logic for patch #7(Jeff).
v4: add a new patch #10 to fix warning(Kalle).
v3: rebase on new ath-tag, use ath12k_ah_to_ar() get ar(Karthikeyan).
v2:
1. add Tested-on tag of QCN9274.
2. update copyright in patch #1, #2, #4 and #10(Jeff).

drivers/net/wireless/ath/ath12k/Makefile | 3 +-
drivers/net/wireless/ath/ath12k/core.c | 1 +
drivers/net/wireless/ath/ath12k/hw.c | 7 +-
drivers/net/wireless/ath/ath12k/mac.c | 368 +++++++++++++++++++----
drivers/net/wireless/ath/ath12k/p2p.c | 142 +++++++++
drivers/net/wireless/ath/ath12k/p2p.h | 23 ++
drivers/net/wireless/ath/ath12k/wmi.c | 114 ++++++-
drivers/net/wireless/ath/ath12k/wmi.h | 50 ++-
8 files changed, 642 insertions(+), 66 deletions(-)
create mode 100644 drivers/net/wireless/ath/ath12k/p2p.c
create mode 100644 drivers/net/wireless/ath/ath12k/p2p.h


base-commit: 17f4b952f067b1f87d14e6df4c8c216fe7a245d1
--
2.34.1



2024-01-30 04:03:41

by Kang Yang

[permalink] [raw]
Subject: [PATCH v6 02/11] wifi: ath12k: fix incorrect logic of calculating vdev_stats_id

During calculate vdev_stats_id, will compare vdev_stats_id with
ATH12K_INVAL_VDEV_STATS_ID by '<='. If vdev_stats_id is relatively
small, then assign ATH12K_INVAL_VDEV_STATS_ID to vdev_stats_id.

This logic is incorrect. Firstly, should use '>=' instead of '<=' to
check if this u8 variable exceeds the max valid range.

Secondly, should use the maximum value as comparison value.

Correct comparison symbols and use the maximum value
ATH12K_MAX_VDEV_STATS_ID for comparison.

Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")

Signed-off-by: Kang Yang <[email protected]>
---

v6: position adjustment.
v5: no change.
v4: no change.
v3: no change.
v2:
1. add Tested-on tag of QCN9274.
2. update copyright.

---
drivers/net/wireless/ath/ath12k/mac.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index a27480a69b27..6d9660f68074 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -5366,7 +5366,7 @@ ath12k_mac_get_vdev_stats_id(struct ath12k_vif *arvif)
do {
if (ab->free_vdev_stats_id_map & (1LL << vdev_stats_id)) {
vdev_stats_id++;
- if (vdev_stats_id <= ATH12K_INVAL_VDEV_STATS_ID) {
+ if (vdev_stats_id >= ATH12K_MAX_VDEV_STATS_ID) {
vdev_stats_id = ATH12K_INVAL_VDEV_STATS_ID;
break;
}
--
2.34.1


2024-01-30 04:03:48

by Kang Yang

[permalink] [raw]
Subject: [PATCH v6 01/11] wifi: ath12k: fix broken structure wmi_vdev_create_cmd

Current structure wmi_vdev_create_cmd is not matched to the firmware
definition. So update it.

And update vdev_stats_id_valid for vdev_stats_id.

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

Signed-off-by: Kang Yang <[email protected]>
---

v6: position adjustment.
v5: no change.
v4: no change.
v3: no change.
v2:
1. add Tested-on tag of QCN9274.
2. update copyright.

---
drivers/net/wireless/ath/ath12k/wmi.c | 3 +++
drivers/net/wireless/ath/ath12k/wmi.h | 3 +++
2 files changed, 6 insertions(+)

diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index 2fa724e5851a..d8ebaf4b8359 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -826,6 +826,9 @@ int ath12k_wmi_vdev_create(struct ath12k *ar, u8 *macaddr,
cmd->vdev_stats_id = cpu_to_le32(args->if_stats_id);
ether_addr_copy(cmd->vdev_macaddr.addr, macaddr);

+ if (args->if_stats_id != ATH12K_INVAL_VDEV_STATS_ID)
+ cmd->vdev_stats_id_valid = cpu_to_le32(true);
+
ptr = skb->data + sizeof(*cmd);
len = WMI_NUM_SUPPORTED_BAND_MAX * sizeof(*txrx_streams);

diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
index 06e5b9b4049b..4afc6ca15c91 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.h
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
@@ -2716,6 +2716,9 @@ struct wmi_vdev_create_cmd {
struct ath12k_wmi_mac_addr_params vdev_macaddr;
__le32 num_cfg_txrx_streams;
__le32 pdev_id;
+ __le32 mbssid_flags;
+ __le32 mbssid_tx_vdev_id;
+ __le32 vdev_stats_id_valid;
__le32 vdev_stats_id;
} __packed;

--
2.34.1


2024-01-30 04:03:58

by Kang Yang

[permalink] [raw]
Subject: [PATCH v6 03/11] wifi: ath12k: change interface combination for P2P mode

Current interface combination doesn't support P2P mode. Change the
combination for P2P mode.

Also, there is a bug that when mesh is enabled but ap is not enabled.
In this situation, the mesh's max_interface of interface combination
won't be set.

So assign the max_interfaces for mesh directly.

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

Signed-off-by: Kang Yang <[email protected]>
---

v6: no change.
v5: no change.
v4: no change.
v3: no change.
v2:
1. add Tested-on tag of QCN9274.
2. update copyright.

---
drivers/net/wireless/ath/ath12k/mac.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 6d9660f68074..cf3c1d83063d 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -7479,9 +7479,10 @@ static int ath12k_mac_setup_iface_combinations(struct ath12k_hw *ah)
struct ieee80211_iface_combination *combinations;
struct ieee80211_iface_limit *limits;
int n_limits, max_interfaces;
- bool ap, mesh;
+ bool ap, mesh, p2p;

ap = ath12k_mac_is_iface_mode_enable(ah, NL80211_IFTYPE_AP);
+ p2p = ath12k_mac_is_iface_mode_enable(ah, NL80211_IFTYPE_P2P_DEVICE);

mesh = IS_ENABLED(CONFIG_MAC80211_MESH) &&
ath12k_mac_is_iface_mode_enable(ah, NL80211_IFTYPE_MESH_POINT);
@@ -7490,9 +7491,15 @@ static int ath12k_mac_setup_iface_combinations(struct ath12k_hw *ah)
if (!combinations)
return -ENOMEM;

- if (ap || mesh) {
+ if ((ap || mesh) && !p2p) {
n_limits = 2;
max_interfaces = 16;
+ } else if (p2p) {
+ n_limits = 3;
+ if (ap || mesh)
+ max_interfaces = 16;
+ else
+ max_interfaces = 3;
} else {
n_limits = 1;
max_interfaces = 1;
@@ -7507,14 +7514,22 @@ static int ath12k_mac_setup_iface_combinations(struct ath12k_hw *ah)
limits[0].max = 1;
limits[0].types |= BIT(NL80211_IFTYPE_STATION);

- if (ap) {
+ if (ap || mesh || p2p)
limits[1].max = max_interfaces;
+
+ if (ap)
limits[1].types |= BIT(NL80211_IFTYPE_AP);
- }

if (mesh)
limits[1].types |= BIT(NL80211_IFTYPE_MESH_POINT);

+ if (p2p) {
+ limits[1].types |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
+ BIT(NL80211_IFTYPE_P2P_GO);
+ limits[2].max = 1;
+ limits[2].types |= BIT(NL80211_IFTYPE_P2P_DEVICE);
+ }
+
combinations[0].limits = limits;
combinations[0].n_limits = n_limits;
combinations[0].max_interfaces = max_interfaces;
--
2.34.1


2024-01-30 04:03:59

by Kang Yang

[permalink] [raw]
Subject: [PATCH v6 04/11] wifi: ath12k: 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: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1

Signed-off-by: Kang Yang <[email protected]>
---

v6: no change.
v5: no change.
v4: no change.
v3: no change.
v2:
1. add Tested-on tag of QCN9274.
2. update copyright.

---
drivers/net/wireless/ath/ath12k/mac.c | 85 ++++++++++++++++++++++++++-
drivers/net/wireless/ath/ath12k/wmi.c | 39 ++++++++++++
drivers/net/wireless/ath/ath12k/wmi.h | 10 +++-
3 files changed, 131 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index cf3c1d83063d..1604597d8825 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -1138,6 +1138,64 @@ static int ath12k_mac_op_config(struct ieee80211_hw *hw, u32 changed)
return ret;
}

+static int ath12k_mac_setup_bcn_p2p_ie(struct ath12k_vif *arvif,
+ struct sk_buff *bcn)
+{
+ struct ath12k *ar = arvif->ar;
+ struct ieee80211_mgmt *mgmt;
+ const u8 *p2p_ie;
+ int ret;
+
+ 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) {
+ ath12k_warn(ar->ab, "no P2P ie found in beacon\n");
+ return -ENOENT;
+ }
+
+ ret = ath12k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie);
+ if (ret) {
+ ath12k_warn(ar->ab, "failed to submit P2P GO bcn ie for vdev %i: %d\n",
+ arvif->vdev_id, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ath12k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
+ u8 oui_type, size_t ie_offset)
+{
+ size_t len;
+ const u8 *next;
+ const u8 *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 ath12k_mac_setup_bcn_tmpl(struct ath12k_vif *arvif)
{
struct ath12k *ar = arvif->ar;
@@ -1170,14 +1228,37 @@ static int ath12k_mac_setup_bcn_tmpl(struct ath12k_vif *arvif)
ies, (skb_tail_pointer(bcn) - ies)))
arvif->wpaie_present = true;

- ret = ath12k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn);
+ if (arvif->vif->type == NL80211_IFTYPE_AP && arvif->vif->p2p) {
+ ret = ath12k_mac_setup_bcn_p2p_ie(arvif, bcn);
+ if (ret) {
+ ath12k_warn(ab, "failed to setup P2P GO bcn ie: %d\n",
+ ret);
+ goto free_bcn_skb;
+ }

- kfree_skb(bcn);
+ /* 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 = ath12k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA,
+ WLAN_OUI_TYPE_WFA_P2P,
+ offsetof(struct ieee80211_mgmt,
+ u.beacon.variable));
+ if (ret) {
+ ath12k_warn(ab, "failed to remove P2P vendor ie: %d\n",
+ ret);
+ goto free_bcn_skb;
+ }
+ }
+
+ ret = ath12k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn);

if (ret)
ath12k_warn(ab, "failed to submit beacon template command: %d\n",
ret);

+free_bcn_skb:
+ kfree_skb(bcn);
return ret;
}

diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index d8ebaf4b8359..98c27954f04f 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -1713,6 +1713,45 @@ int ath12k_wmi_send_bcn_offload_control_cmd(struct ath12k *ar,
return ret;
}

+int ath12k_wmi_p2p_go_bcn_ie(struct ath12k *ar, u32 vdev_id,
+ const u8 *p2p_ie)
+{
+ struct ath12k_wmi_pdev *wmi = ar->wmi;
+ struct wmi_p2p_go_set_beacon_ie_cmd *cmd;
+ struct wmi_tlv *tlv;
+ struct sk_buff *skb;
+ void *ptr;
+ int ret, len;
+ size_t p2p_ie_len = p2p_ie[1] + 2;
+ size_t aligned_len = roundup(p2p_ie_len, sizeof(u32));
+
+ len = sizeof(*cmd) + TLV_HDR_SIZE + aligned_len;
+
+ skb = ath12k_wmi_alloc_skb(wmi->wmi_ab, len);
+ if (!skb)
+ return -ENOMEM;
+ ptr = skb->data;
+ cmd = ptr;
+ cmd->tlv_header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_P2P_GO_SET_BEACON_IE,
+ sizeof(*cmd));
+ cmd->vdev_id = cpu_to_le32(vdev_id);
+ cmd->ie_buf_len = cpu_to_le32(p2p_ie_len);
+
+ ptr = skb->data + sizeof(*cmd);
+ tlv = ptr;
+ tlv->header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_ARRAY_BYTE,
+ aligned_len);
+ memcpy(tlv->value, p2p_ie, p2p_ie_len);
+
+ ret = ath12k_wmi_cmd_send(wmi, skb, WMI_P2P_GO_SET_BEACON_IE);
+ if (ret) {
+ ath12k_warn(ar->ab, "failed to send WMI_P2P_GO_SET_BEACON_IE\n");
+ dev_kfree_skb(skb);
+ }
+
+ return ret;
+}
+
int ath12k_wmi_bcn_tmpl(struct ath12k *ar, u32 vdev_id,
struct ieee80211_mutable_offsets *offs,
struct sk_buff *bcn)
diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
index 4afc6ca15c91..b017e36e1d85 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.h
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/

#ifndef ATH12K_WMI_H
@@ -3506,6 +3506,12 @@ struct wmi_bcn_tmpl_cmd {
__le32 esp_ie_offset;
} __packed;

+struct wmi_p2p_go_set_beacon_ie_cmd {
+ __le32 tlv_header;
+ __le32 vdev_id;
+ __le32 ie_buf_len;
+} __packed;
+
struct wmi_vdev_install_key_cmd {
__le32 tlv_header;
__le32 vdev_id;
@@ -4809,6 +4815,8 @@ int ath12k_wmi_cmd_send(struct ath12k_wmi_pdev *wmi, struct sk_buff *skb,
struct sk_buff *ath12k_wmi_alloc_skb(struct ath12k_wmi_base *wmi_sc, u32 len);
int ath12k_wmi_mgmt_send(struct ath12k *ar, u32 vdev_id, u32 buf_id,
struct sk_buff *frame);
+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);
--
2.34.1


2024-01-30 04:04:03

by Kang Yang

[permalink] [raw]
Subject: [PATCH v6 05/11] wifi: ath12k: 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: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1

Signed-off-by: Kang Yang <[email protected]>
---

v6: no change.
v5: no change.
v4: no change.
v3: use ath12k_ah_to_ar() to get ar.
v2: add Tested-on tag of QCN9274.

---
drivers/net/wireless/ath/ath12k/Makefile | 3 +-
drivers/net/wireless/ath/ath12k/mac.c | 27 ++++-
drivers/net/wireless/ath/ath12k/p2p.c | 142 +++++++++++++++++++++++
drivers/net/wireless/ath/ath12k/p2p.h | 23 ++++
drivers/net/wireless/ath/ath12k/wmi.c | 51 +++++++-
drivers/net/wireless/ath/ath12k/wmi.h | 31 +++++
6 files changed, 274 insertions(+), 3 deletions(-)
create mode 100644 drivers/net/wireless/ath/ath12k/p2p.c
create mode 100644 drivers/net/wireless/ath/ath12k/p2p.h

diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile
index 62c52e733b5e..e296fe7f8d64 100644
--- a/drivers/net/wireless/ath/ath12k/Makefile
+++ b/drivers/net/wireless/ath/ath12k/Makefile
@@ -19,7 +19,8 @@ ath12k-y += core.o \
hw.o \
mhi.o \
pci.o \
- dp_mon.o
+ dp_mon.o \
+ p2p.o

ath12k-$(CONFIG_ATH12K_TRACING) += trace.o

diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 1604597d8825..0cfcf297872d 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -5119,6 +5119,27 @@ static int ath12k_mac_mgmt_tx(struct ath12k *ar, struct sk_buff *skb,
return 0;
}

+static void ath12k_mac_add_p2p_noa_ie(struct ath12k *ar,
+ struct ieee80211_vif *vif,
+ struct sk_buff *skb,
+ bool is_prb_rsp)
+{
+ struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif);
+
+ if (likely(!is_prb_rsp))
+ return;
+
+ spin_lock_bh(&ar->data_lock);
+
+ if (arvif->u.ap.noa_data &&
+ !pskb_expand_head(skb, 0, arvif->u.ap.noa_len,
+ GFP_ATOMIC))
+ skb_put_data(skb, arvif->u.ap.noa_data,
+ arvif->u.ap.noa_len);
+
+ spin_unlock_bh(&ar->data_lock);
+}
+
static void ath12k_mac_op_tx(struct ieee80211_hw *hw,
struct ieee80211_tx_control *control,
struct sk_buff *skb)
@@ -5142,10 +5163,10 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw,
skb_cb->flags |= ATH12K_SKB_CIPHER_SET;
}

+ is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control);
if (info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP) {
skb_cb->flags |= ATH12K_SKB_HW_80211_ENCAP;
} else if (ieee80211_is_mgmt(hdr->frame_control)) {
- is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control);
ret = ath12k_mac_mgmt_tx(ar, skb, is_prb_rsp);
if (ret) {
ath12k_warn(ar->ab, "failed to queue management frame %d\n",
@@ -5155,6 +5176,10 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw,
return;
}

+ /* This is case only for P2P_GO */
+ if (vif->type == NL80211_IFTYPE_AP && vif->p2p)
+ ath12k_mac_add_p2p_noa_ie(ar, vif, skb, is_prb_rsp);
+
ret = ath12k_dp_tx(ar, arvif, skb);
if (ret) {
ath12k_warn(ar->ab, "failed to transmit frame %d\n", ret);
diff --git a/drivers/net/wireless/ath/ath12k/p2p.c b/drivers/net/wireless/ath/ath12k/p2p.c
new file mode 100644
index 000000000000..61e919b23b16
--- /dev/null
+++ b/drivers/net/wireless/ath/ath12k/p2p.c
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: ISC
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <net/mac80211.h>
+#include "core.h"
+#include "mac.h"
+#include "p2p.h"
+
+static void ath12k_p2p_noa_ie_fill(u8 *data, size_t len,
+ const struct ath12k_wmi_p2p_noa_info *noa)
+{
+ struct ieee80211_p2p_noa_attr *noa_attr;
+ u8 ctwindow = le32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_CTWIN_TU);
+ bool oppps = le32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_OPP_PS);
+ __le16 *noa_attr_len;
+ u16 attr_len;
+ u8 noa_descriptors = le32_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 = le32_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 =
+ __le32_to_cpu(noa->descriptors[i].type_count);
+ noa_attr->desc[i].duration = noa->descriptors[i].duration;
+ noa_attr->desc[i].interval = noa->descriptors[i].interval;
+ noa_attr->desc[i].start_time = 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 ath12k_p2p_noa_ie_len_compute(const struct ath12k_wmi_p2p_noa_info *noa)
+{
+ size_t len = 0;
+
+ if (!(le32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_DESC_NUM)) &&
+ !(le32_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 += le32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_DESC_NUM) *
+ sizeof(struct ieee80211_p2p_noa_desc);
+
+ return len;
+}
+
+static void ath12k_p2p_noa_ie_assign(struct ath12k_vif *arvif, void *ie,
+ size_t len)
+{
+ struct ath12k *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 __ath12k_p2p_noa_update(struct ath12k_vif *arvif,
+ const struct ath12k_wmi_p2p_noa_info *noa)
+{
+ struct ath12k *ar = arvif->ar;
+ void *ie;
+ size_t len;
+
+ lockdep_assert_held(&ar->data_lock);
+
+ ath12k_p2p_noa_ie_assign(arvif, NULL, 0);
+
+ len = ath12k_p2p_noa_ie_len_compute(noa);
+ if (!len)
+ return;
+
+ ie = kmalloc(len, GFP_ATOMIC);
+ if (!ie)
+ return;
+
+ ath12k_p2p_noa_ie_fill(ie, len, noa);
+ ath12k_p2p_noa_ie_assign(arvif, ie, len);
+}
+
+void ath12k_p2p_noa_update(struct ath12k_vif *arvif,
+ const struct ath12k_wmi_p2p_noa_info *noa)
+{
+ struct ath12k *ar = arvif->ar;
+
+ spin_lock_bh(&ar->data_lock);
+ __ath12k_p2p_noa_update(arvif, noa);
+ spin_unlock_bh(&ar->data_lock);
+}
+
+static void ath12k_p2p_noa_update_vdev_iter(void *data, u8 *mac,
+ struct ieee80211_vif *vif)
+{
+ struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif);
+ struct ath12k_p2p_noa_arg *arg = data;
+
+ if (arvif->vdev_id != arg->vdev_id)
+ return;
+
+ ath12k_p2p_noa_update(arvif, arg->noa);
+}
+
+void ath12k_p2p_noa_update_by_vdev_id(struct ath12k *ar, u32 vdev_id,
+ const struct ath12k_wmi_p2p_noa_info *noa)
+{
+ struct ath12k_p2p_noa_arg arg = {
+ .vdev_id = vdev_id,
+ .noa = noa,
+ };
+
+ ieee80211_iterate_active_interfaces_atomic(ath12k_ar_to_hw(ar),
+ IEEE80211_IFACE_ITER_NORMAL,
+ ath12k_p2p_noa_update_vdev_iter,
+ &arg);
+}
diff --git a/drivers/net/wireless/ath/ath12k/p2p.h b/drivers/net/wireless/ath/ath12k/p2p.h
new file mode 100644
index 000000000000..b6f177fe4ff4
--- /dev/null
+++ b/drivers/net/wireless/ath/ath12k/p2p.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: ISC */
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved..
+ */
+
+#ifndef ATH12K_P2P_H
+#define ATH12K_P2P_H
+
+#include "wmi.h"
+
+struct ath12k_wmi_p2p_noa_info;
+
+struct ath12k_p2p_noa_arg {
+ u32 vdev_id;
+ const struct ath12k_wmi_p2p_noa_info *noa;
+};
+
+void ath12k_p2p_noa_update(struct ath12k_vif *arvif,
+ const struct ath12k_wmi_p2p_noa_info *noa);
+void ath12k_p2p_noa_update_by_vdev_id(struct ath12k *ar, u32 vdev_id,
+ const struct ath12k_wmi_p2p_noa_info *noa);
+
+#endif
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index 98c27954f04f..cafe269f9f28 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -19,6 +19,7 @@
#include "mac.h"
#include "hw.h"
#include "peer.h"
+#include "p2p.h"

struct ath12k_wmi_svc_ready_parse {
bool wmi_svc_bitmap_done;
@@ -162,6 +163,10 @@ static const struct ath12k_wmi_tlv_policy ath12k_wmi_tlv_policies[] = {
.min_len = sizeof(struct wmi_probe_resp_tx_status_event) },
[WMI_TAG_VDEV_DELETE_RESP_EVENT] = {
.min_len = sizeof(struct wmi_vdev_delete_resp_event) },
+ [WMI_TAG_P2P_NOA_INFO] = {
+ .min_len = sizeof(struct ath12k_wmi_p2p_noa_info) },
+ [WMI_TAG_P2P_NOA_EVENT] = {
+ .min_len = sizeof(struct wmi_p2p_noa_event) },
};

static __le32 ath12k_wmi_tlv_hdr(u32 cmd, u32 len)
@@ -1054,7 +1059,7 @@ int ath12k_wmi_vdev_start(struct ath12k *ar, struct wmi_vdev_start_req_arg *arg,
tlv->header = ath12k_wmi_tlv_hdr(WMI_TAG_ARRAY_STRUCT, 0);

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

ptr += sizeof(*tlv);
@@ -6672,6 +6677,47 @@ static void ath12k_probe_resp_tx_status_event(struct ath12k_base *ab,
kfree(tb);
}

+static int ath12k_wmi_p2p_noa_event(struct ath12k_base *ab,
+ struct sk_buff *skb)
+{
+ const void **tb;
+ const struct wmi_p2p_noa_event *ev;
+ const struct ath12k_wmi_p2p_noa_info *noa;
+ struct ath12k *ar;
+ int ret, vdev_id;
+
+ tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ if (IS_ERR(tb)) {
+ ret = PTR_ERR(tb);
+ ath12k_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) {
+ kfree(tb);
+ return -EPROTO;
+ }
+
+ vdev_id = __le32_to_cpu(ev->vdev_id);
+
+ ath12k_dbg(ab, ATH12K_DBG_WMI,
+ "wmi tlv p2p noa vdev_id %i descriptors %u\n",
+ vdev_id, le32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_DESC_NUM));
+ ar = ath12k_mac_get_ar_by_vdev_id(ab, vdev_id);
+ if (!ar) {
+ ath12k_warn(ab, "invalid vdev id %d in P2P NoA event\n",
+ vdev_id);
+ return -EINVAL;
+ }
+
+ ath12k_p2p_noa_update_by_vdev_id(ar, vdev_id, noa);
+ kfree(tb);
+ return 0;
+}
+
static void ath12k_rfkill_state_change_event(struct ath12k_base *ab,
struct sk_buff *skb)
{
@@ -6807,6 +6853,9 @@ static void ath12k_wmi_op_rx(struct ath12k_base *ab, struct sk_buff *skb)
case WMI_RFKILL_STATE_CHANGE_EVENTID:
ath12k_rfkill_state_change_event(ab, skb);
break;
+ case WMI_P2P_NOA_EVENTID:
+ ath12k_wmi_p2p_noa_event(ab, skb);
+ break;
/* add Unsupported events here */
case WMI_TBTTOFFSET_EXT_UPDATE_EVENTID:
case WMI_PEER_OPER_MODE_CHANGE_EVENTID:
diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
index b017e36e1d85..6fb8c1a787a5 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.h
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
@@ -3492,6 +3492,37 @@ struct wmi_get_pdev_temperature_cmd {
__le32 pdev_id;
} __packed;

+#define WMI_P2P_MAX_NOA_DESCRIPTORS 4
+
+struct wmi_p2p_noa_event {
+ __le32 vdev_id;
+} __packed;
+
+struct ath12k_wmi_p2p_noa_descriptor {
+ __le32 type_count; /* 255: continuous schedule, 0: reserved */
+ __le32 duration; /* Absent period duration in micro seconds */
+ __le32 interval; /* Absent period interval in micro seconds */
+ __le32 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 ath12k_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
+ */
+ __le32 noa_attr;
+ struct ath12k_wmi_p2p_noa_descriptor descriptors[WMI_P2P_MAX_NOA_DESCRIPTORS];
+} __packed;
+
#define WMI_BEACON_TX_BUFFER_SIZE 512

struct wmi_bcn_tmpl_cmd {
--
2.34.1


2024-01-30 04:04:04

by Kang Yang

[permalink] [raw]
Subject: [PATCH v6 07/11] wifi: ath12k: 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.

Also delete the duplicate macro definitions in wmi.h.

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

Signed-off-by: Kang Yang <[email protected]>
---

v6: no change.
v5: no change.
v4: no change.
v3: no change.
v2: add Tested-on tag of QCN9274.

---
drivers/net/wireless/ath/ath12k/wmi.h | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
index 6fb8c1a787a5..74b0ee9f86bf 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.h
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
@@ -168,10 +168,6 @@ struct wmi_tlv {
#define WLAN_SCAN_MAX_HINT_BSSID 10
#define MAX_RNR_BSS 5

-#define WLAN_SCAN_PARAMS_MAX_SSID 16
-#define WLAN_SCAN_PARAMS_MAX_BSSID 4
-#define WLAN_SCAN_PARAMS_MAX_IE_LEN 256
-
#define WMI_APPEND_TO_EXISTING_CHAN_LIST_FLAG 1

#define WMI_BA_MODE_BUFFER_SIZE_256 3
@@ -3149,7 +3145,7 @@ struct ath12k_wmi_element_info_arg {

#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

/* Values lower than this may be refused by some firmware revisions with a scan
* completion with a timedout reason.
--
2.34.1


2024-01-30 04:04:09

by Kang Yang

[permalink] [raw]
Subject: [PATCH v6 06/11] wifi: ath12k: implement remain on channel for P2P mode

Implement remain on channel for p2p mode in ath12k_ops:
ath12k_mac_op_remain_on_channel
ath12k_mac_op_cancel_remain_on_channel

P2P device can trigger ROC scan. Then keep listening or sending management
frames on particular channels.

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

Signed-off-by: Kang Yang <[email protected]>
---

v6: no change.
v5: no change.
v4: no change.
v3: use ath12k_ah_to_ar() to get ar.
v2:
1. add Tested-on tag of QCN9274.
2. update copyright.

---
drivers/net/wireless/ath/ath12k/core.c | 1 +
drivers/net/wireless/ath/ath12k/mac.c | 119 +++++++++++++++++++++++++
drivers/net/wireless/ath/ath12k/wmi.c | 4 +
3 files changed, 124 insertions(+)

diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
index 1baad3302157..ffe4fd6e36f5 100644
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -950,6 +950,7 @@ static void ath12k_core_pre_reconfigure_recovery(struct ath12k_base *ab)
ath12k_mac_drain_tx(ar);
complete(&ar->scan.started);
complete(&ar->scan.completed);
+ complete(&ar->scan.on_channel);
complete(&ar->peer_assoc_done);
complete(&ar->peer_delete_done);
complete(&ar->install_key_done);
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 0cfcf297872d..ec90a21fcd7f 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -7391,6 +7391,122 @@ static void ath12k_mac_op_sta_statistics(struct ieee80211_hw *hw,
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
}

+static int ath12k_mac_op_cancel_remain_on_channel(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
+ struct ath12k *ar;
+
+ ar = ath12k_ah_to_ar(ah);
+
+ mutex_lock(&ar->conf_mutex);
+
+ spin_lock_bh(&ar->data_lock);
+ ar->scan.roc_notify = false;
+ spin_unlock_bh(&ar->data_lock);
+
+ ath12k_scan_abort(ar);
+
+ mutex_unlock(&ar->conf_mutex);
+
+ cancel_delayed_work_sync(&ar->scan.timeout);
+
+ return 0;
+}
+
+static int ath12k_mac_op_remain_on_channel(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_channel *chan,
+ int duration,
+ enum ieee80211_roc_type type)
+{
+ struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
+ struct ath12k *ar;
+ struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif);
+ struct ath12k_wmi_scan_req_arg arg;
+ int ret;
+ u32 scan_time_msec;
+
+ ar = ath12k_ah_to_ar(ah);
+
+ mutex_lock(&ar->conf_mutex);
+ spin_lock_bh(&ar->data_lock);
+ switch (ar->scan.state) {
+ case ATH12K_SCAN_IDLE:
+ reinit_completion(&ar->scan.started);
+ reinit_completion(&ar->scan.completed);
+ reinit_completion(&ar->scan.on_channel);
+ ar->scan.state = ATH12K_SCAN_STARTING;
+ ar->scan.is_roc = true;
+ ar->scan.vdev_id = arvif->vdev_id;
+ ar->scan.roc_freq = chan->center_freq;
+ ar->scan.roc_notify = true;
+ ret = 0;
+ break;
+ case ATH12K_SCAN_STARTING:
+ case ATH12K_SCAN_RUNNING:
+ case ATH12K_SCAN_ABORTING:
+ ret = -EBUSY;
+ break;
+ }
+ spin_unlock_bh(&ar->data_lock);
+
+ if (ret)
+ goto exit;
+
+ scan_time_msec = hw->wiphy->max_remain_on_channel_duration * 2;
+
+ memset(&arg, 0, sizeof(arg));
+ ath12k_wmi_start_scan_init(ar, &arg);
+ arg.num_chan = 1;
+ arg.chan_list = kcalloc(arg.num_chan, sizeof(*arg.chan_list),
+ GFP_KERNEL);
+ if (!arg.chan_list) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+
+ arg.vdev_id = arvif->vdev_id;
+ arg.scan_id = ATH12K_SCAN_ID;
+ arg.chan_list[0] = chan->center_freq;
+ arg.dwell_time_active = scan_time_msec;
+ arg.dwell_time_passive = scan_time_msec;
+ arg.max_scan_time = scan_time_msec;
+ arg.scan_flags |= WMI_SCAN_FLAG_PASSIVE;
+ arg.burst_duration = duration;
+
+ ret = ath12k_start_scan(ar, &arg);
+ if (ret) {
+ ath12k_warn(ar->ab, "failed to start roc scan: %d\n", ret);
+
+ spin_lock_bh(&ar->data_lock);
+ ar->scan.state = ATH12K_SCAN_IDLE;
+ spin_unlock_bh(&ar->data_lock);
+ goto free_chan_list;
+ }
+
+ ret = wait_for_completion_timeout(&ar->scan.on_channel, 3 * HZ);
+ if (ret == 0) {
+ ath12k_warn(ar->ab, "failed to switch to channel for roc scan\n");
+ ret = ath12k_scan_stop(ar);
+ if (ret)
+ ath12k_warn(ar->ab, "failed to stop scan: %d\n", ret);
+ ret = -ETIMEDOUT;
+ goto free_chan_list;
+ }
+
+ ieee80211_queue_delayed_work(hw, &ar->scan.timeout,
+ msecs_to_jiffies(duration));
+
+ ret = 0;
+
+free_chan_list:
+ kfree(arg.chan_list);
+exit:
+ mutex_unlock(&ar->conf_mutex);
+ return ret;
+}
+
static const struct ieee80211_ops ath12k_ops = {
.tx = ath12k_mac_op_tx,
.wake_tx_queue = ieee80211_handle_wake_tx_queue,
@@ -7425,6 +7541,8 @@ static const struct ieee80211_ops ath12k_ops = {
.get_survey = ath12k_mac_op_get_survey,
.flush = ath12k_mac_op_flush,
.sta_statistics = ath12k_mac_op_sta_statistics,
+ .remain_on_channel = ath12k_mac_op_remain_on_channel,
+ .cancel_remain_on_channel = ath12k_mac_op_cancel_remain_on_channel,
};

static void ath12k_mac_update_ch_list(struct ath12k *ar,
@@ -7952,6 +8070,7 @@ static void ath12k_mac_setup(struct ath12k *ar)
init_completion(&ar->bss_survey_done);
init_completion(&ar->scan.started);
init_completion(&ar->scan.completed);
+ init_completion(&ar->scan.on_channel);

INIT_DELAYED_WORK(&ar->scan.timeout, ath12k_scan_timeout_work);
INIT_WORK(&ar->regd_update_work, ath12k_regd_update_work);
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index cafe269f9f28..c4fe90b5ff32 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -5053,6 +5053,8 @@ static void ath12k_wmi_event_scan_started(struct ath12k *ar)
break;
case ATH12K_SCAN_STARTING:
ar->scan.state = ATH12K_SCAN_RUNNING;
+ if (ar->scan.is_roc)
+ ieee80211_ready_on_channel(ath12k_ar_to_hw(ar));
complete(&ar->scan.started);
break;
}
@@ -5137,6 +5139,8 @@ static void ath12k_wmi_event_scan_foreign_chan(struct ath12k *ar, u32 freq)
case ATH12K_SCAN_RUNNING:
case ATH12K_SCAN_ABORTING:
ar->scan_channel = ieee80211_get_channel(hw->wiphy, freq);
+ if (ar->scan.is_roc && ar->scan.roc_freq == freq)
+ complete(&ar->scan.on_channel);
break;
}
}
--
2.34.1


2024-01-30 04:04:17

by Kang Yang

[permalink] [raw]
Subject: [PATCH v6 08/11] wifi: ath12k: allow specific mgmt frame tx while vdev is not up

In current code, the management frames must be sent after vdev is started.
But for P2P device, vdev won't start until P2P negotiation is done. So
this logic doesn't make sense for P2P device.

Also use ar->conf_mutex to synchronize ar to avoid potential conflicts.

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

Signed-off-by: Kang Yang <[email protected]>
---

v6: no change.
v5: change commit log.
v4: no change.
v3: no change.
v2: add Tested-on tag of QCN9274.

---
drivers/net/wireless/ath/ath12k/mac.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index ec90a21fcd7f..1377b710bdcb 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -5069,8 +5069,8 @@ static void ath12k_mgmt_over_wmi_tx_work(struct work_struct *work)
}

arvif = ath12k_vif_to_arvif(skb_cb->vif);
- if (ar->allocated_vdev_map & (1LL << arvif->vdev_id) &&
- arvif->is_started) {
+ mutex_lock(&ar->conf_mutex);
+ if (ar->allocated_vdev_map & (1LL << arvif->vdev_id)) {
ret = ath12k_mac_mgmt_tx_wmi(ar, arvif, skb);
if (ret) {
ath12k_warn(ar->ab, "failed to tx mgmt frame, vdev_id %d :%d\n",
@@ -5084,6 +5084,7 @@ static void ath12k_mgmt_over_wmi_tx_work(struct work_struct *work)
arvif->is_started);
ath12k_mgmt_over_wmi_tx_drop(ar, skb);
}
+ mutex_unlock(&ar->conf_mutex);
}
}

--
2.34.1


2024-01-30 04:04:22

by Kang Yang

[permalink] [raw]
Subject: [PATCH v6 10/11] wifi: ath12k: designating channel frequency for ROC scan

For P2P mode, the WLAN interface may be requested to remain on a
specific channel and then to send some management frames on that
channel. Now chananel frequency of wmi_mgmt_send_cmd is set as 0. As
a result, firmware may choose a default but wrong channel.

Fix it by assigning chanfreq field with the ROC channel frequency.

This change only applies to WCN7850, other chips are not affected.

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

Signed-off-by: Kang Yang <[email protected]>
---

v6: no change.
v5: no change.
v4: no change.
v3: no change.
v2: add Tested-on tag of QCN9274.

---
drivers/net/wireless/ath/ath12k/wmi.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index c4fe90b5ff32..5af69bce8997 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -732,6 +732,20 @@ static int ath12k_service_ready_event(struct ath12k_base *ab, struct sk_buff *sk
return 0;
}

+static u32 ath12k_wmi_mgmt_get_freq(struct ath12k *ar,
+ struct ieee80211_tx_info *info)
+{
+ struct ath12k_base *ab = ar->ab;
+ u32 freq = 0;
+
+ if (ab->hw_params->single_pdev_only &&
+ ar->scan.is_roc &&
+ (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN))
+ freq = ar->scan.roc_freq;
+
+ return freq;
+}
+
struct sk_buff *ath12k_wmi_alloc_skb(struct ath12k_wmi_base *wmi_ab, u32 len)
{
struct sk_buff *skb;
@@ -757,6 +771,7 @@ int ath12k_wmi_mgmt_send(struct ath12k *ar, u32 vdev_id, u32 buf_id,
{
struct ath12k_wmi_pdev *wmi = ar->wmi;
struct wmi_mgmt_send_cmd *cmd;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(frame);
struct wmi_tlv *frame_tlv;
struct sk_buff *skb;
u32 buf_len;
@@ -775,7 +790,7 @@ int ath12k_wmi_mgmt_send(struct ath12k *ar, u32 vdev_id, u32 buf_id,
sizeof(*cmd));
cmd->vdev_id = cpu_to_le32(vdev_id);
cmd->desc_id = cpu_to_le32(buf_id);
- cmd->chanfreq = 0;
+ cmd->chanfreq = cpu_to_le32(ath12k_wmi_mgmt_get_freq(ar, info));
cmd->paddr_lo = cpu_to_le32(lower_32_bits(ATH12K_SKB_CB(frame)->paddr));
cmd->paddr_hi = cpu_to_le32(upper_32_bits(ATH12K_SKB_CB(frame)->paddr));
cmd->frame_len = cpu_to_le32(frame->len);
--
2.34.1


2024-01-30 04:04:23

by Kang Yang

[permalink] [raw]
Subject: [PATCH v6 09/11] wifi: ath12k: move peer delete after vdev stop of station for WCN7850

In current code, when STA/P2P Client connect to AP/P2P GO, the WMI
command sequence is:

peer_create->vdev_start->vdev_up

And sequence of STA/P2P Client disconnect from AP/P2P GO is:

peer_delete->vdev_down->vdev_stop

This sequence of disconnect is not opposite of connect. For STA or P2P
GO, bss peer is not needed by firmware during handling vdev stop
command. So with this sequence, STA and P2P GO can work normally.

But for P2P Client, firmware needs bss peer in some functions during
handling vdev stop command. The opposite sequence of disconnect should
be:

vdev_down->vdev_stop->peer_delete

So change the sequence of disconnect as above opposite sequence for
WCN7850.

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

Signed-off-by: Kang Yang <[email protected]>
---

v6: no change.
v5: no change.
v4: no change.
v3: no change.
v2: add Tested-on tag of QCN9274.

---
drivers/net/wireless/ath/ath12k/mac.c | 99 +++++++++++++++------------
1 file changed, 54 insertions(+), 45 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 1377b710bdcb..6b8b92d22553 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -1083,6 +1083,46 @@ static int ath12k_mac_monitor_stop(struct ath12k *ar)
return ret;
}

+static int ath12k_mac_vdev_stop(struct ath12k_vif *arvif)
+{
+ struct ath12k *ar = arvif->ar;
+ int ret;
+
+ lockdep_assert_held(&ar->conf_mutex);
+
+ reinit_completion(&ar->vdev_setup_done);
+
+ ret = ath12k_wmi_vdev_stop(ar, arvif->vdev_id);
+ if (ret) {
+ ath12k_warn(ar->ab, "failed to stop WMI vdev %i: %d\n",
+ arvif->vdev_id, ret);
+ goto err;
+ }
+
+ ret = ath12k_mac_vdev_setup_sync(ar);
+ if (ret) {
+ ath12k_warn(ar->ab, "failed to synchronize setup for vdev %i: %d\n",
+ arvif->vdev_id, ret);
+ goto err;
+ }
+
+ WARN_ON(ar->num_started_vdevs == 0);
+
+ ar->num_started_vdevs--;
+ ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "vdev %pM stopped, vdev_id %d\n",
+ arvif->vif->addr, arvif->vdev_id);
+
+ if (test_bit(ATH12K_CAC_RUNNING, &ar->dev_flags)) {
+ clear_bit(ATH12K_CAC_RUNNING, &ar->dev_flags);
+ ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "CAC Stopped for vdev %d\n",
+ arvif->vdev_id);
+ }
+
+ return 0;
+err:
+ return ret;
+}
+
static int ath12k_mac_config(struct ath12k *ar, u32 changed)
{
struct ieee80211_hw *hw = ath12k_ar_to_hw(ar);
@@ -3905,6 +3945,13 @@ static int ath12k_mac_op_sta_state(struct ieee80211_hw *hw,
sta->addr, arvif->vdev_id);
} else if ((old_state == IEEE80211_STA_NONE &&
new_state == IEEE80211_STA_NOTEXIST)) {
+ if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
+ ath12k_bss_disassoc(ar, arvif);
+ ret = ath12k_mac_vdev_stop(arvif);
+ if (ret)
+ ath12k_warn(ar->ab, "failed to stop vdev %i: %d\n",
+ arvif->vdev_id, ret);
+ }
ath12k_dp_peer_cleanup(ar, arvif->vdev_id, sta->addr);

ret = ath12k_peer_delete(ar, arvif->vdev_id, sta->addr);
@@ -6336,46 +6383,6 @@ ath12k_mac_vdev_start_restart(struct ath12k_vif *arvif,
return 0;
}

-static int ath12k_mac_vdev_stop(struct ath12k_vif *arvif)
-{
- struct ath12k *ar = arvif->ar;
- int ret;
-
- lockdep_assert_held(&ar->conf_mutex);
-
- reinit_completion(&ar->vdev_setup_done);
-
- ret = ath12k_wmi_vdev_stop(ar, arvif->vdev_id);
- if (ret) {
- ath12k_warn(ar->ab, "failed to stop WMI vdev %i: %d\n",
- arvif->vdev_id, ret);
- goto err;
- }
-
- ret = ath12k_mac_vdev_setup_sync(ar);
- if (ret) {
- ath12k_warn(ar->ab, "failed to synchronize setup for vdev %i: %d\n",
- arvif->vdev_id, ret);
- goto err;
- }
-
- WARN_ON(ar->num_started_vdevs == 0);
-
- ar->num_started_vdevs--;
- ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "vdev %pM stopped, vdev_id %d\n",
- arvif->vif->addr, arvif->vdev_id);
-
- if (test_bit(ATH12K_CAC_RUNNING, &ar->dev_flags)) {
- clear_bit(ATH12K_CAC_RUNNING, &ar->dev_flags);
- ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "CAC Stopped for vdev %d\n",
- arvif->vdev_id);
- }
-
- return 0;
-err:
- return ret;
-}
-
static int ath12k_mac_vdev_start(struct ath12k_vif *arvif,
struct ieee80211_chanctx_conf *ctx)
{
@@ -6742,11 +6749,13 @@ ath12k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
arvif->is_started = false;
}

- ret = ath12k_mac_vdev_stop(arvif);
- if (ret)
- ath12k_warn(ab, "failed to stop vdev %i: %d\n",
- arvif->vdev_id, ret);
-
+ if (arvif->vdev_type != WMI_VDEV_TYPE_STA) {
+ ath12k_bss_disassoc(ar, arvif);
+ ret = ath12k_mac_vdev_stop(arvif);
+ if (ret)
+ ath12k_warn(ab, "failed to stop vdev %i: %d\n",
+ arvif->vdev_id, ret);
+ }
arvif->is_started = false;

if (ab->hw_params->vdev_start_delay &&
--
2.34.1


2024-01-30 04:04:33

by Kang Yang

[permalink] [raw]
Subject: [PATCH v6 11/11] wifi: ath12k: advertise P2P dev support for WCN7850

Now that all the necessary pieces are implemented we can enable P2P
support for WCN7850.

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

Signed-off-by: Kang Yang <[email protected]>
---

v6: no change.
v5: no change.
v4: no change.
v3: no change.
v2:
1. add Tested-on tag of QCN9274.
2. update copyright.

---
drivers/net/wireless/ath/ath12k/hw.c | 7 +++++--
drivers/net/wireless/ath/ath12k/mac.c | 8 ++++++++
2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/hw.c b/drivers/net/wireless/ath/ath12k/hw.c
index cbb6e2b6d826..b804d9f88a1b 100644
--- a/drivers/net/wireless/ath/ath12k/hw.c
+++ b/drivers/net/wireless/ath/ath12k/hw.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/

#include <linux/types.h>
@@ -953,7 +953,10 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
.vdev_start_delay = true,

.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,

.idle_ps = true,
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 6b8b92d22553..1632cd3322fa 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -5745,17 +5745,25 @@ static int ath12k_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-01-30 16:49:07

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH v6 01/11] wifi: ath12k: fix broken structure wmi_vdev_create_cmd

On 1/29/2024 8:02 PM, Kang Yang wrote:
> Current structure wmi_vdev_create_cmd is not matched to the firmware
> definition. So update it.
>
> And update vdev_stats_id_valid for vdev_stats_id.
>
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Kang Yang <[email protected]>
Acked-by: Jeff Johnson <[email protected]>

Note that if you respin a series, and if a given patch has not been
substantially modified, you should add any previously given tags to the
new patch since they are not automatically carried forward in patchwork.
That saves the reviewers the overhead of revisiting patches they've
already approved.



2024-01-30 16:52:48

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH v6 03/11] wifi: ath12k: change interface combination for P2P mode

On 1/29/2024 8:02 PM, Kang Yang wrote:
> Current interface combination doesn't support P2P mode. Change the
> combination for P2P mode.
>
> Also, there is a bug that when mesh is enabled but ap is not enabled.
> In this situation, the mesh's max_interface of interface combination
> won't be set.
>
> So assign the max_interfaces for mesh directly.
>
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Kang Yang <[email protected]>
Acked-by: Jeff Johnson <[email protected]>


2024-01-30 17:14:11

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH v6 02/11] wifi: ath12k: fix incorrect logic of calculating vdev_stats_id

On 1/29/2024 8:02 PM, Kang Yang wrote:
> During calculate vdev_stats_id, will compare vdev_stats_id with
> ATH12K_INVAL_VDEV_STATS_ID by '<='. If vdev_stats_id is relatively
> small, then assign ATH12K_INVAL_VDEV_STATS_ID to vdev_stats_id.
>
> This logic is incorrect. Firstly, should use '>=' instead of '<=' to
> check if this u8 variable exceeds the max valid range.
>
> Secondly, should use the maximum value as comparison value.
>
> Correct comparison symbols and use the maximum value
> ATH12K_MAX_VDEV_STATS_ID for comparison.
>
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3

should be blank line between unofficial Tested-on tag and official Fixes tag

> Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
>
And no blank line here since all the official tags should be together

> Signed-off-by: Kang Yang <[email protected]>

Kalle can fix the above when he moves into the pending branch

Acked-by: Jeff Johnson <[email protected]>


2024-01-30 17:14:47

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH v6 05/11] wifi: ath12k: implement handling of P2P NoA event

On 1/29/2024 8: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: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Kang Yang <[email protected]>
Acked-by: Jeff Johnson <[email protected]>


2024-01-30 17:16:47

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH v6 06/11] wifi: ath12k: implement remain on channel for P2P mode

On 1/29/2024 8:02 PM, Kang Yang wrote:
> Implement remain on channel for p2p mode in ath12k_ops:
> ath12k_mac_op_remain_on_channel
> ath12k_mac_op_cancel_remain_on_channel
>
> P2P device can trigger ROC scan. Then keep listening or sending management
> frames on particular channels.
>
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Kang Yang <[email protected]>
Acked-by: Jeff Johnson <[email protected]>


2024-01-30 17:19:20

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH v6 07/11] wifi: ath12k: change WLAN_SCAN_PARAMS_MAX_IE_LEN from 256 to 512

On 1/29/2024 8:02 PM, Kang Yang wrote:
> Mac80211 needs more space for P2P scan ie in P2P mode, 256 is not
> enough, resize it to 512.
>
> Also delete the duplicate macro definitions in wmi.h.
>
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Kang Yang <[email protected]>
Acked-by: Jeff Johnson <[email protected]>


2024-01-30 17:23:50

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH v6 04/11] wifi: ath12k: add P2P IE in beacon template

On 1/29/2024 8:02 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: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Kang Yang <[email protected]>
> ---
>
> v6: no change.
> v5: no change.
> v4: no change.
> v3: no change.
> v2:
> 1. add Tested-on tag of QCN9274.
> 2. update copyright.
>
> ---
> drivers/net/wireless/ath/ath12k/mac.c | 85 ++++++++++++++++++++++++++-
> drivers/net/wireless/ath/ath12k/wmi.c | 39 ++++++++++++
> drivers/net/wireless/ath/ath12k/wmi.h | 10 +++-
> 3 files changed, 131 insertions(+), 3 deletions(-)
...
> --- a/drivers/net/wireless/ath/ath12k/wmi.c
> +++ b/drivers/net/wireless/ath/ath12k/wmi.c
> @@ -1713,6 +1713,45 @@ int ath12k_wmi_send_bcn_offload_control_cmd(struct ath12k *ar,
> return ret;
> }
>
> +int ath12k_wmi_p2p_go_bcn_ie(struct ath12k *ar, u32 vdev_id,
> + const u8 *p2p_ie)
> +{
...
> + ptr = skb->data;
> + cmd = ptr;
> + cmd->tlv_header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_P2P_GO_SET_BEACON_IE,
> + sizeof(*cmd));
> + cmd->vdev_id = cpu_to_le32(vdev_id);
> + cmd->ie_buf_len = cpu_to_le32(p2p_ie_len);
> +
> + ptr = skb->data + sizeof(*cmd);

IMO better would be: ptr += sizeof(*cmd);

Kalle can probably adjust this in the pending branch

> + tlv = ptr;
> + tlv->header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_ARRAY_BYTE,
> + aligned_len);
> + memcpy(tlv->value, p2p_ie, p2p_ie_len);
> +
> + ret = ath12k_wmi_cmd_send(wmi, skb, WMI_P2P_GO_SET_BEACON_IE);
> + if (ret) {
> + ath12k_warn(ar->ab, "failed to send WMI_P2P_GO_SET_BEACON_IE\n");
> + dev_kfree_skb(skb);
> + }
> +
> + return ret;
> +}

Acked-by: Jeff Johnson <[email protected]>



2024-01-30 17:24:07

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH v6 08/11] wifi: ath12k: allow specific mgmt frame tx while vdev is not up

On 1/29/2024 8:03 PM, Kang Yang wrote:
> In current code, the management frames must be sent after vdev is started.
> But for P2P device, vdev won't start until P2P negotiation is done. So
> this logic doesn't make sense for P2P device.
>
> Also use ar->conf_mutex to synchronize ar to avoid potential conflicts.
>
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Kang Yang <[email protected]>
Acked-by: Jeff Johnson <[email protected]>


2024-01-30 17:24:11

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH v6 09/11] wifi: ath12k: move peer delete after vdev stop of station for WCN7850

On 1/29/2024 8:03 PM, Kang Yang wrote:
> In current code, when STA/P2P Client connect to AP/P2P GO, the WMI
> command sequence is:
>
> peer_create->vdev_start->vdev_up
>
> And sequence of STA/P2P Client disconnect from AP/P2P GO is:
>
> peer_delete->vdev_down->vdev_stop
>
> This sequence of disconnect is not opposite of connect. For STA or P2P
> GO, bss peer is not needed by firmware during handling vdev stop
> command. So with this sequence, STA and P2P GO can work normally.
>
> But for P2P Client, firmware needs bss peer in some functions during
> handling vdev stop command. The opposite sequence of disconnect should
> be:
>
> vdev_down->vdev_stop->peer_delete
>
> So change the sequence of disconnect as above opposite sequence for
> WCN7850.
>
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Kang Yang <[email protected]>
Acked-by: Jeff Johnson <[email protected]>


2024-01-30 17:24:58

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH v6 10/11] wifi: ath12k: designating channel frequency for ROC scan

On 1/29/2024 8:03 PM, Kang Yang wrote:
> For P2P mode, the WLAN interface may be requested to remain on a
> specific channel and then to send some management frames on that
> channel. Now chananel frequency of wmi_mgmt_send_cmd is set as 0. As
> a result, firmware may choose a default but wrong channel.
>
> Fix it by assigning chanfreq field with the ROC channel frequency.
>
> This change only applies to WCN7850, other chips are not affected.
>
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Kang Yang <[email protected]>
Acked-by: Jeff Johnson <[email protected]>


2024-01-30 17:25:24

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH v6 11/11] wifi: ath12k: advertise P2P dev support for WCN7850

On 1/29/2024 8:03 PM, Kang Yang wrote:
> Now that all the necessary pieces are implemented we can enable P2P
> support for WCN7850.
>
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Kang Yang <[email protected]>
Acked-by: Jeff Johnson <[email protected]>


2024-02-02 14:13:32

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v6 05/11] wifi: ath12k: implement handling of P2P NoA event

Kang Yang <[email protected]> writes:

> 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: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Kang Yang <[email protected]>

This patch 5 had simple conflicts in wmi.c, please check:

https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=pending&id=cbcb45c458a93d32a48b9280c13294e0853fa5dd

--
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2024-02-02 16:27:10

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH v6 05/11] wifi: ath12k: implement handling of P2P NoA event

On 2/2/2024 5:53 AM, Kalle Valo wrote:
> Kang Yang <[email protected]> writes:
>
>> 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: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
>> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>>
>> Signed-off-by: Kang Yang <[email protected]>
>
> This patch 5 had simple conflicts in wmi.c, please check:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=pending&id=cbcb45c458a93d32a48b9280c13294e0853fa5dd
>
LGTM

2024-02-05 15:40:28

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v6 00/11] wifi: ath12k: P2P support for WCN7850

Kang Yang <[email protected]> writes:

> Add P2P support for WCN7850.
>
> Kang Yang (11):
> wifi: ath12k: fix broken structure wmi_vdev_create_cmd
> wifi: ath12k: fix incorrect logic of calculating vdev_stats_id
> wifi: ath12k: change interface combination for P2P mode
> wifi: ath12k: add P2P IE in beacon template
> wifi: ath12k: implement handling of P2P NoA event
> wifi: ath12k: implement remain on channel for P2P mode
> wifi: ath12k: change WLAN_SCAN_PARAMS_MAX_IE_LEN from 256 to 512
> wifi: ath12k: allow specific mgmt frame tx while vdev is not up
> wifi: ath12k: move peer delete after vdev stop of station for WCN7850
> wifi: ath12k: designating channel frequency for ROC scan
> wifi: ath12k: advertise P2P dev support for WCN7850

I did some quick tests by running various p2p commands with wpa_cli and
noticed the warning below. We might have some issues with our RCU usage,
please check. But no need to resend because of this, followup patch
fixing this is fine.

[ 1108.916980] =============================
[ 1108.917068] WARNING: suspicious RCU usage
[ 1108.917151] 6.8.0-rc2-wt-ath+ #1273 Not tainted
[ 1108.917235] -----------------------------
[ 1108.917318] drivers/net/wireless/ath/ath12k/mac.c:583 suspicious rcu_dereference_check() usage!
[ 1108.917400] #012[ 1108.917400] other info that might help us debug this:#012[ 1108.917400]
[ 1108.917484] #012[ 1108.917484] rcu_scheduler_active = 2, debug_locks = 1
[ 1108.917566] no locks held by swapper/3/0.
[ 1108.917649] #012[ 1108.917649] stack backtrace:
[ 1108.917729] CPU: 3 PID: 0 Comm: swapper/3 Not tainted 6.8.0-rc2-wt-ath+ #1273
[ 1108.917810] Hardware name: Intel(R) Client Systems NUC8i7HVK/NUC8i7HVB, BIOS HNKBLi70.86A.0067.2021.0528.1339 05/28/2021
[ 1108.917892] Call Trace:
[ 1108.917968] <IRQ>
[ 1108.918046] dump_stack_lvl+0x82/0xc0
[ 1108.918132] dump_stack+0x10/0x20
[ 1108.918206] lockdep_rcu_suspicious+0x210/0x3a0
[ 1108.918285] ath12k_mac_get_ar_by_vdev_id+0x18e/0x210 [ath12k]
[ 1108.918403] ath12k_wmi_op_rx+0x2bb/0x1a30 [ath12k]
[ 1108.918511] ? ath12k_chan_info_event+0x970/0x970 [ath12k]
[ 1108.918624] ? __lock_acquire+0xd45/0x1de0
[ 1108.918706] ? __kasan_check_read+0x11/0x20
[ 1108.918789] ? debug_smp_processor_id+0x17/0x20
[ 1108.918863] ? __lock_release.isra.0+0x49d/0xae0
[ 1108.918934] ? debug_smp_processor_id+0x17/0x20
[ 1108.919007] ? reacquire_held_locks+0x4d0/0x4d0
[ 1108.919080] ? ath12k_ce_recv_process_cb+0x4b3/0x960 [ath12k]
[ 1108.919195] ath12k_htc_rx_completion_handler+0x361/0x650 [ath12k]
[ 1108.919302] ? ath12k_ce_recv_process_cb+0x4b3/0x960 [ath12k]
[ 1108.919409] ? trace_hardirqs_on+0x49/0x50
[ 1108.919485] ath12k_ce_recv_process_cb+0x5c6/0x960 [ath12k]
[ 1108.919591] ? ath12k_ce_rx_post_pipe+0x990/0x990 [ath12k]
[ 1108.919658] ? __wake_up_bit+0x120/0x120
[ 1108.919705] ? handle_irq_event+0x10e/0x1c0
[ 1108.919752] ath12k_ce_per_engine_service+0xda/0x110 [ath12k]
[ 1108.919817] ath12k_pci_ce_tasklet+0x65/0x120 [ath12k]
[ 1108.919879] ? trace_tasklet_entry+0xe4/0x110
[ 1108.919945] tasklet_action_common.isra.0+0x24c/0x3d0
[ 1108.920007] tasklet_action+0x4f/0x70
[ 1108.920068] __do_softirq+0x1c2/0x868
[ 1108.920116] irq_exit_rcu+0xab/0x110
[ 1108.920159] common_interrupt+0xad/0xd0
[ 1108.920201] </IRQ>
[ 1108.920309] <TASK>
[ 1108.920355] asm_common_interrupt+0x27/0x40
[ 1108.920399] RIP: 0010:cpuidle_enter_state+0xdc/0x580
[ 1108.920448] Code: ff ff ff ff 49 89 c7 e8 e2 fa 55 ff 31 ff e8 cb 29 54 fd 80 7d d0 00 0f 85 4a 02 00 00 e8 0c f9 55 ff 84 c0 0f 84 32 02 00 00 <45> 85 f6 0f 88 95 01 00 00 49 63 d6 48 83 fa 0a 0f 83 dd 02 00 00
[ 1108.920496] RSP: 0018:ffffc900001afd20 EFLAGS: 00000202
[ 1108.920545] RAX: 000000000065289d RBX: ffff888116413400 RCX: 1ffffffff47726c1
[ 1108.920593] RDX: 0000000000000000 RSI: ffffffffa2278020 RDI: ffffffffa24176e0
[ 1108.920639] RBP: ffffc900001afd70 R08: 0000000000000001 R09: fffffbfff4772c1a
[ 1108.920686] R10: ffffffffa3b960d7 R11: 0000000000000000 R12: ffffffffa34c1740
[ 1108.920733] R13: 0000000000000002 R14: 0000000000000002 R15: 000001023093b5a2
[ 1108.920793] cpuidle_enter+0x4a/0xa0
[ 1108.920840] call_cpuidle+0x42/0xb0
[ 1108.920882] ? tick_nohz_idle_retain_tick+0x70/0xa0
[ 1108.920946] cpuidle_idle_call+0x1c9/0x290
[ 1108.921002] ? arch_cpu_idle_exit+0x30/0x30
[ 1108.921045] ? debug_smp_processor_id+0x17/0x20
[ 1108.921092] do_idle+0xfb/0x160
[ 1108.921137] cpu_startup_entry+0x54/0x60
[ 1108.921182] start_secondary+0x201/0x290
[ 1108.921227] ? set_cpu_sibling_map+0x1f20/0x1f20
[ 1108.921273] secondary_startup_64_no_verify+0x15e/0x16b
[ 1108.921324] </TASK>


--
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2024-02-05 15:44:59

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v6 02/11] wifi: ath12k: fix incorrect logic of calculating vdev_stats_id

Jeff Johnson <[email protected]> writes:

> On 1/29/2024 8:02 PM, Kang Yang wrote:
>> During calculate vdev_stats_id, will compare vdev_stats_id with
>> ATH12K_INVAL_VDEV_STATS_ID by '<='. If vdev_stats_id is relatively
>> small, then assign ATH12K_INVAL_VDEV_STATS_ID to vdev_stats_id.
>>
>> This logic is incorrect. Firstly, should use '>=' instead of '<=' to
>> check if this u8 variable exceeds the max valid range.
>>
>> Secondly, should use the maximum value as comparison value.
>>
>> Correct comparison symbols and use the maximum value
>> ATH12K_MAX_VDEV_STATS_ID for comparison.
>>
>> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
>
> should be blank line between unofficial Tested-on tag and official Fixes tag
>
>> Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
>>
> And no blank line here since all the official tags should be together
>
>> Signed-off-by: Kang Yang <[email protected]>
>
> Kalle can fix the above when he moves into the pending branch

Yes, fixed those now.

--
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2024-02-05 15:46:47

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v6 01/11] wifi: ath12k: fix broken structure wmi_vdev_create_cmd

Kang Yang <[email protected]> writes:

> Current structure wmi_vdev_create_cmd is not matched to the firmware
> definition. So update it.
>
> And update vdev_stats_id_valid for vdev_stats_id.
>
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Kang Yang <[email protected]>
> ---
>
> v6: position adjustment.
> v5: no change.
> v4: no change.
> v3: no change.
> v2:
> 1. add Tested-on tag of QCN9274.
> 2. update copyright.

BTW it's quite a lot of work to add changelog to every patch, especially
if there are 11 patches. It's totally fine to have the list of changes
between versions in the cover letter, no need to add them individually
to every patch. Though this is not a problem, just trying to reduce your
workload.

> ---
> drivers/net/wireless/ath/ath12k/wmi.c | 3 +++
> drivers/net/wireless/ath/ath12k/wmi.h | 3 +++
> 2 files changed, 6 insertions(+)
>
> diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
> index 2fa724e5851a..d8ebaf4b8359 100644
> --- a/drivers/net/wireless/ath/ath12k/wmi.c
> +++ b/drivers/net/wireless/ath/ath12k/wmi.c
> @@ -826,6 +826,9 @@ int ath12k_wmi_vdev_create(struct ath12k *ar, u8 *macaddr,
> cmd->vdev_stats_id = cpu_to_le32(args->if_stats_id);
> ether_addr_copy(cmd->vdev_macaddr.addr, macaddr);
>
> + if (args->if_stats_id != ATH12K_INVAL_VDEV_STATS_ID)
> + cmd->vdev_stats_id_valid = cpu_to_le32(true);

Using 'true' in a firmware interface looks odd to me and I think what we
mean is BIT(0), right? I'll change this in the pending branch.

--
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2024-02-05 16:17:21

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v6 04/11] wifi: ath12k: add P2P IE in beacon template

Kang Yang <[email protected]> writes:

> 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: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Kang Yang <[email protected]>

[...]

> +static int ath12k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
> + u8 oui_type, size_t ie_offset)
> +{
> + size_t len;
> + const u8 *next;
> + const u8 *end;
> + u8 *ie;

Reverse xmas tree and you can merge next and end:

const u8 *next, *end;
size_t len;
u8 *ie;

I changed that in the pending branch.

> + 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);

So cfg80211_find_vendor_ie() returns:

static inline const u8 *
cfg80211_find_vendor_ie(unsigned int oui, int oui_type,
const u8 *ies, unsigned int len)

You are casting away the const here. I see that other drivers do the
same as the assumption is that the pointer points to the same buffer,
but I still don't really like casting away const. Thoughts?

--
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2024-02-05 16:24:15

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v6 04/11] wifi: ath12k: add P2P IE in beacon template

Jeff Johnson <[email protected]> writes:

> On 1/29/2024 8:02 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: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
>> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>>
>> Signed-off-by: Kang Yang <[email protected]>

[...]

>> +int ath12k_wmi_p2p_go_bcn_ie(struct ath12k *ar, u32 vdev_id,
>> + const u8 *p2p_ie)
>> +{
> ...
>> + ptr = skb->data;
>> + cmd = ptr;
>> + cmd->tlv_header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_P2P_GO_SET_BEACON_IE,
>> + sizeof(*cmd));
>> + cmd->vdev_id = cpu_to_le32(vdev_id);
>> + cmd->ie_buf_len = cpu_to_le32(p2p_ie_len);
>> +
>> + ptr = skb->data + sizeof(*cmd);
>
> IMO better would be: ptr += sizeof(*cmd);
>
> Kalle can probably adjust this in the pending branch

Yeah, I changed that.

But I think even better would be to avoid pointer arightmetic and do something
like this:

struct wmi_p2p_go_set_beacon_ie_cmd {
__le32 tlv_header;
__le32 vdev_id;
__le32 ie_buf_len;
u8 tlv[];
} __packed;

tlv = cmd->tlv;
tlv->header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_ARRAY_BYTE,
aligned_len);

But that's separate cleanup, I see pointer arithmetic used quite a lot
in wmi.c.

--
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2024-02-05 16:36:49

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH v6 04/11] wifi: ath12k: add P2P IE in beacon template

On 2/5/2024 8:17 AM, Kalle Valo wrote:
> Kang Yang <[email protected]> writes:
>> + 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);
>
> So cfg80211_find_vendor_ie() returns:
>
> static inline const u8 *
> cfg80211_find_vendor_ie(unsigned int oui, int oui_type,
> const u8 *ies, unsigned int len)
>
> You are casting away the const here. I see that other drivers do the
> same as the assumption is that the pointer points to the same buffer,
> but I still don't really like casting away const. Thoughts?

I'm not a fan of typecasting either.

However, the problem here is that from the perspective of
cfg80211_find_vendor_ie() the buffer is const (not modified in any way
by the function), but from the perspective of every caller the buffer is
part of a message that is in RAM.

So you have to decide if you want to change the prototype to remove the
const from cfg80211_find_vendor_ie() or if you want to keep the current
semantic to cast away the const.

This is one of the rare cases where I think the typecast is ok.

/jeff

2024-02-06 02:22:05

by Kang Yang

[permalink] [raw]
Subject: Re: [PATCH v6 05/11] wifi: ath12k: implement handling of P2P NoA event



On 2/2/2024 9:53 PM, Kalle Valo wrote:
> Kang Yang <[email protected]> writes:
>
>> 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: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
>> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>>
>> Signed-off-by: Kang Yang <[email protected]>
>
> This patch 5 had simple conflicts in wmi.c, please check:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=pending&id=cbcb45c458a93d32a48b9280c13294e0853fa5dd
>

Sorry for late reply, I am in Spring Festival holiday. It seems i have
conflict in adding WMI event, because you merge TWT patch-set before.


conflict:
root@Mayan:/home/yk/ath12k-upstream/drivers/net/wireless/ath/ath12k# cat
wmi.c.rej
diff a/drivers/net/wireless/ath/ath12k/wmi.c
b/drivers/net/wireless/ath/ath12k/wmi.c (rejected hunks)
@@ -162,6 +163,10 @@ static const struct ath12k_wmi_tlv_policy
ath12k_wmi_tlv_policies[] = {
.min_len = sizeof(struct wmi_probe_resp_tx_status_event) },
[WMI_TAG_VDEV_DELETE_RESP_EVENT] = {
.min_len = sizeof(struct wmi_vdev_delete_resp_event) },
+ [WMI_TAG_P2P_NOA_INFO] = {
+ .min_len = sizeof(struct ath12k_wmi_p2p_noa_info) },
+ [WMI_TAG_P2P_NOA_EVENT] = {
+ .min_len = sizeof(struct wmi_p2p_noa_event) },
};

static __le32 ath12k_wmi_tlv_hdr(u32 cmd, u32 len)
@@ -6807,6 +6853,9 @@ static void ath12k_wmi_op_rx(struct ath12k_base
*ab, struct sk_buff *skb)
case WMI_RFKILL_STATE_CHANGE_EVENTID:
ath12k_rfkill_state_change_event(ab, skb);
break;
+ case WMI_P2P_NOA_EVENTID:
+ ath12k_wmi_p2p_noa_event(ab, skb);
+ break;
/* add Unsupported events here */
case WMI_TBTTOFFSET_EXT_UPDATE_EVENTID:
case WMI_PEER_OPER_MODE_CHANGE_EVENTID:



TWT patch change:

@@ -164,6 +164,8 @@ static const struct ath12k_wmi_tlv_policy
ath12k_wmi_tlv_policies[] = {
.min_len = sizeof(struct wmi_vdev_delete_resp_event) },
[WMI_TAG_TWT_ENABLE_COMPLETE_EVENT] = {
.min_len = sizeof(struct wmi_twt_enable_event) },
+ [WMI_TAG_TWT_DISABLE_COMPLETE_EVENT] = {
+ .min_len = sizeof(struct wmi_twt_disable_event) },
};

@@ -6798,10 +6829,12 @@ static void ath12k_wmi_op_rx(struct ath12k_base
*ab, struct sk_buff *skb)
case WMI_TWT_ENABLE_EVENTID:
ath12k_wmi_twt_enable_event(ab, skb);
break;
+ case WMI_TWT_DISABLE_EVENTID:
+ ath12k_wmi_twt_disable_event(ab, skb);
+ break;
/* add Unsupported events here */




Do i need to send a new version ?



2024-02-06 09:52:44

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v6 04/11] wifi: ath12k: add P2P IE in beacon template

Jeff Johnson <[email protected]> writes:

> On 2/5/2024 8:17 AM, Kalle Valo wrote:
>> Kang Yang <[email protected]> writes:
>>> + 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);
>>
>> So cfg80211_find_vendor_ie() returns:
>>
>> static inline const u8 *
>> cfg80211_find_vendor_ie(unsigned int oui, int oui_type,
>> const u8 *ies, unsigned int len)
>>
>> You are casting away the const here. I see that other drivers do the
>> same as the assumption is that the pointer points to the same buffer,
>> but I still don't really like casting away const. Thoughts?
>
> I'm not a fan of typecasting either.
>
> However, the problem here is that from the perspective of
> cfg80211_find_vendor_ie() the buffer is const (not modified in any way
> by the function), but from the perspective of every caller the buffer is
> part of a message that is in RAM.
>
> So you have to decide if you want to change the prototype to remove the
> const from cfg80211_find_vendor_ie() or if you want to keep the current
> semantic to cast away the const.
>
> This is one of the rare cases where I think the typecast is ok.

Makes sense, thanks for the comment.

--
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2024-02-06 09:56:46

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v6 05/11] wifi: ath12k: implement handling of P2P NoA event

Kang Yang <[email protected]> writes:

> On 2/2/2024 9:53 PM, Kalle Valo wrote:
>> Kang Yang <[email protected]> writes:
>>
>>> 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: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
>>> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>>>
>>> Signed-off-by: Kang Yang <[email protected]>
>> This patch 5 had simple conflicts in wmi.c, please check:
>> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=pending&id=cbcb45c458a93d32a48b9280c13294e0853fa5dd
>>
>
> Sorry for late reply, I am in Spring Festival holiday.

No worries, enjoy the holidays!

> It seems i have conflict in adding WMI event, because you merge TWT
> patch-set before.

Correct, that's pretty normal as we have several patches in patchwork at
the same time.

> Do i need to send a new version ?

In this case no need to send a new version.

In general I usually try to fix the simple conflicts myself (like here).
If the conflicts are too difficult when I might ask for the author to
fix the conflicts and submit a new version.

--
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2024-02-06 16:11:48

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v6 05/11] wifi: ath12k: implement handling of P2P NoA event

Kang Yang <[email protected]> writes:

> 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: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Kang Yang <[email protected]>

[...]

> +static int ath12k_wmi_p2p_noa_event(struct ath12k_base *ab,
> + struct sk_buff *skb)
> +{
> + const void **tb;
> + const struct wmi_p2p_noa_event *ev;
> + const struct ath12k_wmi_p2p_noa_info *noa;
> + struct ath12k *ar;
> + int ret, vdev_id;
> +
> + tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
> + if (IS_ERR(tb)) {
> + ret = PTR_ERR(tb);
> + ath12k_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) {
> + kfree(tb);
> + return -EPROTO;
> + }
> +
> + vdev_id = __le32_to_cpu(ev->vdev_id);
> +
> + ath12k_dbg(ab, ATH12K_DBG_WMI,
> + "wmi tlv p2p noa vdev_id %i descriptors %u\n",
> + vdev_id, le32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_DESC_NUM));
> + ar = ath12k_mac_get_ar_by_vdev_id(ab, vdev_id);
> + if (!ar) {
> + ath12k_warn(ab, "invalid vdev id %d in P2P NoA event\n",
> + vdev_id);
> + return -EINVAL;
> + }

Aren't we leaking tb here? In this function I revamped the error
handling to use the out label to make sure we are freeing tb in every
error. Please review:

https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=pending&id=12e182b47078a48169e873c51d438d7417e7e0c8

--
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2024-02-06 16:24:34

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v6 08/11] wifi: ath12k: allow specific mgmt frame tx while vdev is not up

Kang Yang <[email protected]> writes:

> In current code, the management frames must be sent after vdev is started.
> But for P2P device, vdev won't start until P2P negotiation is done. So
> this logic doesn't make sense for P2P device.
>
> Also use ar->conf_mutex to synchronize ar to avoid potential conflicts.

Please do locking changes in a separate followup patch, I removed this
in the pending branch:

https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=pending&id=d357dcb3cd0cd3bf57064dc673b5477d884454b3

I assume you are referring to ar->allocated_vdev_map and access to that
indeed doesn't look consistent. Most of the places take conf->mutex but
I see some places which it's accessed without the mutex, for example
ath12k_mac_get_arvif_by_vdev_id() and ath12k_mac_get_ar_by_vdev_id().

I recommend in the followup patch checking all the access to
ar->allocated_vdev_map, fixing that if needed and adding documentation
to struct ath12k::allocated_vdev_map how it's supposed to be protected.

--
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2024-02-06 18:17:25

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v6 05/11] wifi: ath12k: implement handling of P2P NoA event

Kalle Valo <[email protected]> writes:

> Kang Yang <[email protected]> writes:
>
>> 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: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
>> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>>
>> Signed-off-by: Kang Yang <[email protected]>
>
> [...]
>
>> +static int ath12k_wmi_p2p_noa_event(struct ath12k_base *ab,
>> + struct sk_buff *skb)
>> +{
>> + const void **tb;
>> + const struct wmi_p2p_noa_event *ev;
>> + const struct ath12k_wmi_p2p_noa_info *noa;
>> + struct ath12k *ar;
>> + int ret, vdev_id;
>> +
>> + tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
>> + if (IS_ERR(tb)) {
>> + ret = PTR_ERR(tb);
>> + ath12k_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) {
>> + kfree(tb);
>> + return -EPROTO;
>> + }
>> +
>> + vdev_id = __le32_to_cpu(ev->vdev_id);
>> +
>> + ath12k_dbg(ab, ATH12K_DBG_WMI,
>> + "wmi tlv p2p noa vdev_id %i descriptors %u\n",
>> + vdev_id, le32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_DESC_NUM));
>> + ar = ath12k_mac_get_ar_by_vdev_id(ab, vdev_id);
>> + if (!ar) {
>> + ath12k_warn(ab, "invalid vdev id %d in P2P NoA event\n",
>> + vdev_id);
>> + return -EINVAL;
>> + }
>
> Aren't we leaking tb here? In this function I revamped the error
> handling to use the out label to make sure we are freeing tb in every
> error. Please review:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=pending&id=12e182b47078a48169e873c51d438d7417e7e0c8

I realised that ret was uninitialised when no error, new version:

https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=pending&id=43f3069f6580b8a67969a6f32377d35aa7dd8d9a

--
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2024-02-07 04:37:36

by Kang Yang

[permalink] [raw]
Subject: Re: [PATCH v6 05/11] wifi: ath12k: implement handling of P2P NoA event



On 2/7/2024 12:11 AM, Kalle Valo wrote:
> Kang Yang <[email protected]> writes:
>
>> 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: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
>> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>>
>> Signed-off-by: Kang Yang <[email protected]>
>
> [...]
>
>> +static int ath12k_wmi_p2p_noa_event(struct ath12k_base *ab,
>> + struct sk_buff *skb)
>> +{
>> + const void **tb;
>> + const struct wmi_p2p_noa_event *ev;
>> + const struct ath12k_wmi_p2p_noa_info *noa;
>> + struct ath12k *ar;
>> + int ret, vdev_id;
>> +
>> + tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
>> + if (IS_ERR(tb)) {
>> + ret = PTR_ERR(tb);
>> + ath12k_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) {
>> + kfree(tb);
>> + return -EPROTO;
>> + }
>> +
>> + vdev_id = __le32_to_cpu(ev->vdev_id);
>> +
>> + ath12k_dbg(ab, ATH12K_DBG_WMI,
>> + "wmi tlv p2p noa vdev_id %i descriptors %u\n",
>> + vdev_id, le32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_DESC_NUM));
>> + ar = ath12k_mac_get_ar_by_vdev_id(ab, vdev_id);
>> + if (!ar) {
>> + ath12k_warn(ab, "invalid vdev id %d in P2P NoA event\n",
>> + vdev_id);
>> + return -EINVAL;
>> + }
>
> Aren't we leaking tb here? In this function I revamped the error
> handling to use the out label to make sure we are freeing tb in every
> error. Please review:

Yes, i forget to free(tb) here, thanks!


>
> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=pending&id=12e182b47078a48169e873c51d438d7417e7e0c8
>

2024-02-07 04:45:07

by Kang Yang

[permalink] [raw]
Subject: Re: [PATCH v6 08/11] wifi: ath12k: allow specific mgmt frame tx while vdev is not up



On 2/7/2024 12:24 AM, Kalle Valo wrote:
> Kang Yang <[email protected]> writes:
>
>> In current code, the management frames must be sent after vdev is started.
>> But for P2P device, vdev won't start until P2P negotiation is done. So
>> this logic doesn't make sense for P2P device.
>>
>> Also use ar->conf_mutex to synchronize ar to avoid potential conflicts.
>
> Please do locking changes in a separate followup patch, I removed this
> in the pending branch:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=pending&id=d357dcb3cd0cd3bf57064dc673b5477d884454b3
>
> I assume you are referring to ar->allocated_vdev_map and access to that
> indeed doesn't look consistent. Most of the places take conf->mutex but
> I see some places which it's accessed without the mutex, for example
> ath12k_mac_get_arvif_by_vdev_id() and ath12k_mac_get_ar_by_vdev_id().
>
> I recommend in the followup patch checking all the access to
> ar->allocated_vdev_map, fixing that if needed and adding documentation
> to struct ath12k::allocated_vdev_map how it's supposed to be protected.


Will do it in the future.

>

2024-02-07 06:50:59

by Kang Yang

[permalink] [raw]
Subject: Re: [PATCH v6 00/11] wifi: ath12k: P2P support for WCN7850



On 2/5/2024 11:40 PM, Kalle Valo wrote:
> Kang Yang <[email protected]> writes:
>
>> Add P2P support for WCN7850.
>>
>> Kang Yang (11):
>> wifi: ath12k: fix broken structure wmi_vdev_create_cmd
>> wifi: ath12k: fix incorrect logic of calculating vdev_stats_id
>> wifi: ath12k: change interface combination for P2P mode
>> wifi: ath12k: add P2P IE in beacon template
>> wifi: ath12k: implement handling of P2P NoA event
>> wifi: ath12k: implement remain on channel for P2P mode
>> wifi: ath12k: change WLAN_SCAN_PARAMS_MAX_IE_LEN from 256 to 512
>> wifi: ath12k: allow specific mgmt frame tx while vdev is not up
>> wifi: ath12k: move peer delete after vdev stop of station for WCN7850
>> wifi: ath12k: designating channel frequency for ROC scan
>> wifi: ath12k: advertise P2P dev support for WCN7850
>
> I did some quick tests by running various p2p commands with wpa_cli and
> noticed the warning below. We might have some issues with our RCU usage,
> please check. But no need to resend because of this, followup patch
> fixing this is fine.
>
> [ 1108.916980] =============================
> [ 1108.917068] WARNING: suspicious RCU usage
> [ 1108.917151] 6.8.0-rc2-wt-ath+ #1273 Not tainted
> [ 1108.917235] -----------------------------
> [ 1108.917318] drivers/net/wireless/ath/ath12k/mac.c:583 suspicious rcu_dereference_check() usage!
> [ 1108.917400] #012[ 1108.917400] other info that might help us debug this:#012[ 1108.917400]
> [ 1108.917484] #012[ 1108.917484] rcu_scheduler_active = 2, debug_locks = 1
> [ 1108.917566] no locks held by swapper/3/0.


I conducted a simple test, but cannot reproduce.

It seems i need to use rcu_read_lock() and rcu_read_unlock() for
rcu_dereference().

Will fix it in a separate patch.


> [ 1108.917649] #012[ 1108.917649] stack backtrace:
> [ 1108.917729] CPU: 3 PID: 0 Comm: swapper/3 Not tainted 6.8.0-rc2-wt-ath+ #1273
> [ 1108.917810] Hardware name: Intel(R) Client Systems NUC8i7HVK/NUC8i7HVB, BIOS HNKBLi70.86A.0067.2021.0528.1339 05/28/2021
> [ 1108.917892] Call Trace:
> [ 1108.917968] <IRQ>
> [ 1108.918046] dump_stack_lvl+0x82/0xc0
> [ 1108.918132] dump_stack+0x10/0x20
> [ 1108.918206] lockdep_rcu_suspicious+0x210/0x3a0
> [ 1108.918285] ath12k_mac_get_ar_by_vdev_id+0x18e/0x210 [ath12k]
> [ 1108.918403] ath12k_wmi_op_rx+0x2bb/0x1a30 [ath12k]
> [ 1108.918511] ? ath12k_chan_info_event+0x970/0x970 [ath12k]
> [ 1108.918624] ? __lock_acquire+0xd45/0x1de0
> [ 1108.918706] ? __kasan_check_read+0x11/0x20
> [ 1108.918789] ? debug_smp_processor_id+0x17/0x20
> [ 1108.918863] ? __lock_release.isra.0+0x49d/0xae0
> [ 1108.918934] ? debug_smp_processor_id+0x17/0x20
> [ 1108.919007] ? reacquire_held_locks+0x4d0/0x4d0
> [ 1108.919080] ? ath12k_ce_recv_process_cb+0x4b3/0x960 [ath12k]
> [ 1108.919195] ath12k_htc_rx_completion_handler+0x361/0x650 [ath12k]
> [ 1108.919302] ? ath12k_ce_recv_process_cb+0x4b3/0x960 [ath12k]
> [ 1108.919409] ? trace_hardirqs_on+0x49/0x50
> [ 1108.919485] ath12k_ce_recv_process_cb+0x5c6/0x960 [ath12k]
> [ 1108.919591] ? ath12k_ce_rx_post_pipe+0x990/0x990 [ath12k]
> [ 1108.919658] ? __wake_up_bit+0x120/0x120
> [ 1108.919705] ? handle_irq_event+0x10e/0x1c0
> [ 1108.919752] ath12k_ce_per_engine_service+0xda/0x110 [ath12k]
> [ 1108.919817] ath12k_pci_ce_tasklet+0x65/0x120 [ath12k]
> [ 1108.919879] ? trace_tasklet_entry+0xe4/0x110
> [ 1108.919945] tasklet_action_common.isra.0+0x24c/0x3d0
> [ 1108.920007] tasklet_action+0x4f/0x70
> [ 1108.920068] __do_softirq+0x1c2/0x868
> [ 1108.920116] irq_exit_rcu+0xab/0x110
> [ 1108.920159] common_interrupt+0xad/0xd0
> [ 1108.920201] </IRQ>
> [ 1108.920309] <TASK>
> [ 1108.920355] asm_common_interrupt+0x27/0x40
> [ 1108.920399] RIP: 0010:cpuidle_enter_state+0xdc/0x580
> [ 1108.920448] Code: ff ff ff ff 49 89 c7 e8 e2 fa 55 ff 31 ff e8 cb 29 54 fd 80 7d d0 00 0f 85 4a 02 00 00 e8 0c f9 55 ff 84 c0 0f 84 32 02 00 00 <45> 85 f6 0f 88 95 01 00 00 49 63 d6 48 83 fa 0a 0f 83 dd 02 00 00
> [ 1108.920496] RSP: 0018:ffffc900001afd20 EFLAGS: 00000202
> [ 1108.920545] RAX: 000000000065289d RBX: ffff888116413400 RCX: 1ffffffff47726c1
> [ 1108.920593] RDX: 0000000000000000 RSI: ffffffffa2278020 RDI: ffffffffa24176e0
> [ 1108.920639] RBP: ffffc900001afd70 R08: 0000000000000001 R09: fffffbfff4772c1a
> [ 1108.920686] R10: ffffffffa3b960d7 R11: 0000000000000000 R12: ffffffffa34c1740
> [ 1108.920733] R13: 0000000000000002 R14: 0000000000000002 R15: 000001023093b5a2
> [ 1108.920793] cpuidle_enter+0x4a/0xa0
> [ 1108.920840] call_cpuidle+0x42/0xb0
> [ 1108.920882] ? tick_nohz_idle_retain_tick+0x70/0xa0
> [ 1108.920946] cpuidle_idle_call+0x1c9/0x290
> [ 1108.921002] ? arch_cpu_idle_exit+0x30/0x30
> [ 1108.921045] ? debug_smp_processor_id+0x17/0x20
> [ 1108.921092] do_idle+0xfb/0x160
> [ 1108.921137] cpu_startup_entry+0x54/0x60
> [ 1108.921182] start_secondary+0x201/0x290
> [ 1108.921227] ? set_cpu_sibling_map+0x1f20/0x1f20
> [ 1108.921273] secondary_startup_64_no_verify+0x15e/0x16b
> [ 1108.921324] </TASK>
>
>

2024-02-07 15:11:59

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v6 01/11] wifi: ath12k: fix broken structure wmi_vdev_create_cmd

Kang Yang <[email protected]> wrote:

> Current structure wmi_vdev_create_cmd is not matched to the firmware
> definition. So update it.
>
> And update vdev_stats_id_valid for vdev_stats_id.
>
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Kang Yang <[email protected]>
> Acked-by: Jeff Johnson <[email protected]>
> Signed-off-by: Kalle Valo <[email protected]>

11 patches applied to ath-next branch of ath.git, thanks.

4f684533afe2 wifi: ath12k: fix broken structure wmi_vdev_create_cmd
019b58dcb6ed wifi: ath12k: fix incorrect logic of calculating vdev_stats_id
ef860c6a3adf wifi: ath12k: change interface combination for P2P mode
575ec73cb880 wifi: ath12k: add P2P IE in beacon template
9411eecb60cb wifi: ath12k: implement handling of P2P NoA event
2830bc9e784f wifi: ath12k: implement remain on channel for P2P mode
28035a88f8b3 wifi: ath12k: change WLAN_SCAN_PARAMS_MAX_IE_LEN from 256 to 512
32e7b12e2611 wifi: ath12k: allow specific mgmt frame tx while vdev is not up
c9e4e41e71ff wifi: ath12k: move peer delete after vdev stop of station for WCN7850
cf0425eead75 wifi: ath12k: designating channel frequency for ROC scan
e65a63986575 wifi: ath12k: advertise P2P dev support for WCN7850

--
https://patchwork.kernel.org/project/linux-wireless/patch/[email protected]/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches


2024-02-07 17:45:55

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH v6 05/11] wifi: ath12k: implement handling of P2P NoA event

On 2/6/2024 10:17 AM, Kalle Valo wrote:
> Kalle Valo <[email protected]> writes:
>
>> Kang Yang <[email protected]> writes:
>>
>>> 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: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
>>> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>>>
>>> Signed-off-by: Kang Yang <[email protected]>
>>
>> [...]
>>
>>> +static int ath12k_wmi_p2p_noa_event(struct ath12k_base *ab,
>>> + struct sk_buff *skb)
>>> +{
>>> + const void **tb;
>>> + const struct wmi_p2p_noa_event *ev;
>>> + const struct ath12k_wmi_p2p_noa_info *noa;
>>> + struct ath12k *ar;
>>> + int ret, vdev_id;
>>> +
>>> + tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
>>> + if (IS_ERR(tb)) {
>>> + ret = PTR_ERR(tb);
>>> + ath12k_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) {
>>> + kfree(tb);
>>> + return -EPROTO;
>>> + }
>>> +
>>> + vdev_id = __le32_to_cpu(ev->vdev_id);
>>> +
>>> + ath12k_dbg(ab, ATH12K_DBG_WMI,
>>> + "wmi tlv p2p noa vdev_id %i descriptors %u\n",
>>> + vdev_id, le32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_DESC_NUM));
>>> + ar = ath12k_mac_get_ar_by_vdev_id(ab, vdev_id);
>>> + if (!ar) {
>>> + ath12k_warn(ab, "invalid vdev id %d in P2P NoA event\n",
>>> + vdev_id);
>>> + return -EINVAL;
>>> + }
>>
>> Aren't we leaking tb here? In this function I revamped the error
>> handling to use the out label to make sure we are freeing tb in every
>> error. Please review:
>>
>> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=pending&id=12e182b47078a48169e873c51d438d7417e7e0c8
>
> I realised that ret was uninitialised when no error, new version:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=pending&id=43f3069f6580b8a67969a6f32377d35aa7dd8d9a

Thanks Kalle, looks like I had a review failure on the original :(
The version here LGTM :)

/jeff
>


2024-03-07 09:47:39

by Kang Yang

[permalink] [raw]
Subject: Re: [PATCH v6 08/11] wifi: ath12k: allow specific mgmt frame tx while vdev is not up



On 2/7/2024 12:24 AM, Kalle Valo wrote:
> Kang Yang <[email protected]> writes:
>
>> In current code, the management frames must be sent after vdev is started.
>> But for P2P device, vdev won't start until P2P negotiation is done. So
>> this logic doesn't make sense for P2P device.
>>
>> Also use ar->conf_mutex to synchronize ar to avoid potential conflicts.
>
> Please do locking changes in a separate followup patch, I removed this
> in the pending branch:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=pending&id=d357dcb3cd0cd3bf57064dc673b5477d884454b3
>
> I assume you are referring to ar->allocated_vdev_map and access to that
> indeed doesn't look consistent. Most of the places take conf->mutex but
> I see some places which it's accessed without the mutex, for example
> ath12k_mac_get_arvif_by_vdev_id() and ath12k_mac_get_ar_by_vdev_id().
>


Hi, kalle:

I just take a look for ath12k_mac_get_arvif_by_vdev_id() and
ath12k_mac_get_ar_by_vdev_id.

Both of them use rcu_read_lock(), so we don't need mutex_lock() anymore,
right?

I also tried to add mutex_lock() for them, cannot work well:
[ 7804.291286] BUG: sleeping function called from invalid context at
kernel/locking/mutex.c:585
[ 7804.291349] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 0,
name: swapper/8
[ 7804.291358] preempt_count: 101, expected: 0
[ 7804.291366] RCU nest depth: 1, expected: 0
[ 7804.291374] 1 lock held by swapper/8/0:
……


> I recommend in the followup patch checking all the access to
> ar->allocated_vdev_map, fixing that if needed and adding documentation
> to struct ath12k::allocated_vdev_map how it's supposed to be protected.
>


So i think the initial change is sufficient: just use mutex_lock() in
ath12k_mgmt_over_wmi_tx_work().