Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 3/7] wifi: ath12k: Avoid fetch Error bitmap and decap format from Rx TLV
From: Karthikeyan Periyasamy @ 2025-01-07  2:10 UTC (permalink / raw)
  To: ath12k; +Cc: linux-wireless, P Praneesh, Karthikeyan Periyasamy
In-Reply-To: <20250107021017.3857555-1-quic_periyasa@quicinc.com>

From: P Praneesh <quic_ppranees@quicinc.com>

Currently, error bitmap and decap format information are fetched from the
MSDU Rx TLV data. This logic is inherited from ath11k. However, for ath12k
802.11be hardware, the Rx TLV will not be present in the MSDU data.
Instead, this information is reported separately under the MSDU END TLV
tag. Therefore, remove the existing fetch code, handle the MSDU END TLV
tag and fetch the above information to store it in the mon_mpdu data
structure for use in the merge MSDU procedure.

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

Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
---
 drivers/net/wireless/ath/ath12k/dp_mon.c | 58 ++++++++++--------------
 1 file changed, 23 insertions(+), 35 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c
index c82dc71f8790..4e5c645b56e0 100644
--- a/drivers/net/wireless/ath/ath12k/dp_mon.c
+++ b/drivers/net/wireless/ath/ath12k/dp_mon.c
@@ -1731,30 +1731,26 @@ static void ath12k_dp_mon_rx_msdus_set_payload(struct ath12k *ar,
 
 static struct sk_buff *
 ath12k_dp_mon_rx_merg_msdus(struct ath12k *ar,
-			    struct sk_buff *head_msdu, struct sk_buff *tail_msdu,
-			    struct ieee80211_rx_status *rxs, bool *fcs_err)
+			    struct dp_mon_mpdu *mon_mpdu,
+			    struct ieee80211_rx_status *rxs)
 {
 	struct ath12k_base *ab = ar->ab;
 	struct sk_buff *msdu, *mpdu_buf, *prev_buf, *head_frag_list;
+	struct sk_buff *head_msdu, *tail_msdu;
 	struct hal_rx_desc *rx_desc, *tail_rx_desc;
-	u8 *hdr_desc, *dest, decap_format;
+	u8 *hdr_desc, *dest, decap_format = mon_mpdu->decap_format;
 	struct ieee80211_hdr_3addr *wh;
-	u32 err_bitmap, frag_list_sum_len = 0;
+	u32 frag_list_sum_len = 0;
 
 	mpdu_buf = NULL;
+	head_msdu = mon_mpdu->head;
+	tail_msdu = mon_mpdu->tail;
 
 	if (!head_msdu)
 		goto err_merge_fail;
 
-	rx_desc = (struct hal_rx_desc *)head_msdu->data;
 	tail_rx_desc = (struct hal_rx_desc *)tail_msdu->data;
 
-	err_bitmap = ath12k_dp_rx_h_mpdu_err(ab, tail_rx_desc);
-	if (err_bitmap & HAL_RX_MPDU_ERR_FCS)
-		*fcs_err = true;
-
-	decap_format = ath12k_dp_rx_h_decap_type(ab, tail_rx_desc);
-
 	ath12k_dp_rx_h_ppdu(ar, tail_rx_desc, rxs);
 
 	if (decap_format == DP_RX_DECAP_TYPE_RAW) {
@@ -1983,7 +1979,8 @@ static void ath12k_dp_mon_update_radiotap(struct ath12k *ar,
 
 static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi,
 					  struct sk_buff *msdu,
-					  struct ieee80211_rx_status *status)
+					  struct ieee80211_rx_status *status,
+					  u8 decap)
 {
 	static const struct ieee80211_radiotap_he known = {
 		.data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN |
@@ -1995,7 +1992,6 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct
 	struct ieee80211_sta *pubsta = NULL;
 	struct ath12k_peer *peer;
 	struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
-	u8 decap = DP_RX_DECAP_TYPE_RAW;
 	bool is_mcbc = rxcb->is_mcbc;
 	bool is_eapol_tkip = rxcb->is_eapol;
 
@@ -2008,8 +2004,6 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct
 		status->flag |= RX_FLAG_RADIOTAP_HE;
 	}
 
-	if (!(status->flag & RX_FLAG_ONLY_MONITOR))
-		decap = ath12k_dp_rx_h_decap_type(ar->ab, rxcb->rx_desc);
 	spin_lock_bh(&ar->ab->base_lock);
 	peer = ath12k_dp_rx_h_find_peer(ar->ab, msdu);
 	if (peer && peer->sta) {
@@ -2066,25 +2060,23 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct
 }
 
 static int ath12k_dp_mon_rx_deliver(struct ath12k *ar,
-				    struct sk_buff *head_msdu, struct sk_buff *tail_msdu,
+				    struct dp_mon_mpdu *mon_mpdu,
 				    struct hal_rx_mon_ppdu_info *ppduinfo,
 				    struct napi_struct *napi)
 {
 	struct ath12k_pdev_dp *dp = &ar->dp;
 	struct sk_buff *mon_skb, *skb_next, *header;
 	struct ieee80211_rx_status *rxs = &dp->rx_status;
-	bool fcs_err = false;
+	u8 decap = DP_RX_DECAP_TYPE_RAW;
 
-	mon_skb = ath12k_dp_mon_rx_merg_msdus(ar,
-					      head_msdu, tail_msdu,
-					      rxs, &fcs_err);
+	mon_skb = ath12k_dp_mon_rx_merg_msdus(ar, mon_mpdu, rxs);
 	if (!mon_skb)
 		goto mon_deliver_fail;
 
 	header = mon_skb;
 	rxs->flag = 0;
 
-	if (fcs_err)
+	if (mon_mpdu->err_bitmap & HAL_RX_MPDU_ERR_FCS)
 		rxs->flag = RX_FLAG_FAILED_FCS_CRC;
 
 	do {
@@ -2101,8 +2093,12 @@ static int ath12k_dp_mon_rx_deliver(struct ath12k *ar,
 			rxs->flag |= RX_FLAG_ALLOW_SAME_PN;
 		}
 		rxs->flag |= RX_FLAG_ONLY_MONITOR;
+
+		if (!(rxs->flag & RX_FLAG_ONLY_MONITOR))
+			decap = mon_mpdu->decap_format;
+
 		ath12k_dp_mon_update_radiotap(ar, ppduinfo, mon_skb, rxs);
-		ath12k_dp_mon_rx_deliver_msdu(ar, napi, mon_skb, rxs);
+		ath12k_dp_mon_rx_deliver_msdu(ar, napi, mon_skb, rxs, decap);
 		mon_skb = skb_next;
 	} while (mon_skb);
 	rxs->flag = 0;
@@ -2110,7 +2106,7 @@ static int ath12k_dp_mon_rx_deliver(struct ath12k *ar,
 	return 0;
 
 mon_deliver_fail:
-	mon_skb = head_msdu;
+	mon_skb = mon_mpdu->head;
 	while (mon_skb) {
 		skb_next = mon_skb->next;
 		dev_kfree_skb_any(mon_skb);
@@ -2316,7 +2312,6 @@ ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar,
 	struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info;
 	struct dp_mon_mpdu *tmp;
 	struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu;
-	struct sk_buff *head_msdu, *tail_msdu;
 	enum hal_rx_mon_status hal_status;
 
 	hal_status = ath12k_dp_mon_parse_rx_dest(ar, pmon, skb);
@@ -2325,13 +2320,9 @@ ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar,
 
 	list_for_each_entry_safe(mon_mpdu, tmp, &pmon->dp_rx_mon_mpdu_list, list) {
 		list_del(&mon_mpdu->list);
-		head_msdu = mon_mpdu->head;
-		tail_msdu = mon_mpdu->tail;
 
-		if (head_msdu && tail_msdu) {
-			ath12k_dp_mon_rx_deliver(ar, head_msdu,
-						 tail_msdu, ppdu_info, napi);
-		}
+		if (mon_mpdu->head && mon_mpdu->tail)
+			ath12k_dp_mon_rx_deliver(ar, mon_mpdu, ppdu_info, napi);
 
 		kfree(mon_mpdu);
 	}
@@ -3016,16 +3007,13 @@ ath12k_dp_mon_tx_process_ppdu_info(struct ath12k *ar,
 				   struct dp_mon_tx_ppdu_info *tx_ppdu_info)
 {
 	struct dp_mon_mpdu *tmp, *mon_mpdu;
-	struct sk_buff *head_msdu, *tail_msdu;
 
 	list_for_each_entry_safe(mon_mpdu, tmp,
 				 &tx_ppdu_info->dp_tx_mon_mpdu_list, list) {
 		list_del(&mon_mpdu->list);
-		head_msdu = mon_mpdu->head;
-		tail_msdu = mon_mpdu->tail;
 
-		if (head_msdu)
-			ath12k_dp_mon_rx_deliver(ar, head_msdu, tail_msdu,
+		if (mon_mpdu->head)
+			ath12k_dp_mon_rx_deliver(ar, mon_mpdu,
 						 &tx_ppdu_info->rx_status, napi);
 
 		kfree(mon_mpdu);
-- 
2.34.1


^ permalink raw reply related

* [PATCH 2/7] wifi: ath12k: Add extra TLV tag parsing support in monitor Rx path
From: Karthikeyan Periyasamy @ 2025-01-07  2:10 UTC (permalink / raw)
  To: ath12k; +Cc: linux-wireless, P Praneesh, Karthikeyan Periyasamy
In-Reply-To: <20250107021017.3857555-1-quic_periyasa@quicinc.com>

From: P Praneesh <quic_ppranees@quicinc.com>

Currently, the monitor Rx parser handler is inherited from the ath11k.
However, the ath12k 802.11be hardware does not report the Rx TLV header
in the MSDU data. Instead, the hardware reports those TLVs under the
following TLV tags:

1. Buffer address
2. MPDU start
3. MPDU end
4. MSDU end

Therefore, add support for parsing the above TLVs in the Rx monitor path
and use this information for MSDU buffer and status updates.

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

Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
---
 drivers/net/wireless/ath/ath12k/dp.h     |   4 +-
 drivers/net/wireless/ath/ath12k/dp_mon.c | 157 ++++++++++++++++++++++-
 drivers/net/wireless/ath/ath12k/dp_mon.h |   4 +-
 drivers/net/wireless/ath/ath12k/dp_rx.c  |   3 +-
 drivers/net/wireless/ath/ath12k/hal_rx.h |  14 +-
 5 files changed, 172 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h
index 07bad88552c7..6d063958ab2c 100644
--- a/drivers/net/wireless/ath/ath12k/dp.h
+++ b/drivers/net/wireless/ath/ath12k/dp.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-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef ATH12K_DP_H
@@ -106,6 +106,8 @@ struct dp_mon_mpdu {
 	struct list_head list;
 	struct sk_buff *head;
 	struct sk_buff *tail;
+	u32 err_bitmap;
+	u8 decap_format;
 };
 
 #define DP_MON_MAX_STATUS_BUF 32
diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c
index 84289e4dacb1..c82dc71f8790 100644
--- a/drivers/net/wireless/ath/ath12k/dp_mon.c
+++ b/drivers/net/wireless/ath/ath12k/dp_mon.c
@@ -1676,7 +1676,7 @@ ath12k_dp_mon_rx_parse_status_tlv(struct ath12k *ar,
 				u32_get_bits(info[0], HAL_RX_MPDU_START_INFO0_PPDU_ID);
 		}
 
-		break;
+		return HAL_RX_MON_STATUS_MPDU_START;
 	}
 	case HAL_RX_MSDU_START:
 		/* TODO: add msdu start parsing logic */
@@ -2119,6 +2119,144 @@ static int ath12k_dp_mon_rx_deliver(struct ath12k *ar,
 	return -EINVAL;
 }
 
+static int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len)
+{
+	if (skb->len > len) {
+		skb_trim(skb, len);
+	} else {
+		if (skb_tailroom(skb) < len - skb->len) {
+			if ((pskb_expand_head(skb, 0,
+					      len - skb->len - skb_tailroom(skb),
+					      GFP_ATOMIC))) {
+				return -ENOMEM;
+			}
+		}
+		skb_put(skb, (len - skb->len));
+	}
+
+	return 0;
+}
+
+static void ath12k_dp_mon_parse_rx_msdu_end_err(u32 info, u32 *errmap)
+{
+	if (info & RX_MSDU_END_INFO13_FCS_ERR)
+		*errmap |= HAL_RX_MPDU_ERR_FCS;
+
+	if (info & RX_MSDU_END_INFO13_DECRYPT_ERR)
+		*errmap |= HAL_RX_MPDU_ERR_DECRYPT;
+
+	if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR)
+		*errmap |= HAL_RX_MPDU_ERR_TKIP_MIC;
+
+	if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR)
+		*errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR;
+
+	if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR)
+		*errmap |= HAL_RX_MPDU_ERR_OVERFLOW;
+
+	if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR)
+		*errmap |= HAL_RX_MPDU_ERR_MSDU_LEN;
+
+	if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR)
+		*errmap |= HAL_RX_MPDU_ERR_MPDU_LEN;
+}
+
+static int
+ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon,
+				    const struct hal_rx_msdu_end *msdu_end)
+{
+	struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu;
+
+	ath12k_dp_mon_parse_rx_msdu_end_err(__le32_to_cpu(msdu_end->info2),
+					    &mon_mpdu->err_bitmap);
+
+	mon_mpdu->decap_format = le32_get_bits(msdu_end->info1,
+					       RX_MSDU_END_INFO11_DECAP_FORMAT);
+
+	return 0;
+}
+
+static int
+ath12k_dp_mon_parse_status_buf(struct ath12k *ar,
+			       struct ath12k_mon_data *pmon,
+			       const struct dp_mon_packet_info *packet_info)
+{
+	struct ath12k_base *ab = ar->ab;
+	struct dp_rxdma_mon_ring *buf_ring = &ab->dp.rxdma_mon_buf_ring;
+	struct sk_buff *msdu;
+	int buf_id;
+	u32 offset;
+
+	buf_id = u32_get_bits(packet_info->cookie, DP_RXDMA_BUF_COOKIE_BUF_ID);
+
+	spin_lock_bh(&buf_ring->idr_lock);
+	msdu = idr_remove(&buf_ring->bufs_idr, buf_id);
+	spin_unlock_bh(&buf_ring->idr_lock);
+
+	if (unlikely(!msdu)) {
+		ath12k_warn(ab, "mon dest desc with inval buf_id %d\n", buf_id);
+		return 0;
+	}
+
+	dma_unmap_single(ab->dev, ATH12K_SKB_RXCB(msdu)->paddr,
+			 msdu->len + skb_tailroom(msdu),
+			 DMA_FROM_DEVICE);
+
+	offset = packet_info->dma_length + ATH12K_MON_RX_DOT11_OFFSET;
+	if (ath12k_dp_pkt_set_pktlen(msdu, offset)) {
+		dev_kfree_skb_any(msdu);
+		goto dest_replenish;
+	}
+
+	if (!pmon->mon_mpdu->head)
+		pmon->mon_mpdu->head = msdu;
+	else
+		pmon->mon_mpdu->tail->next = msdu;
+
+	pmon->mon_mpdu->tail = msdu;
+
+dest_replenish:
+	ath12k_dp_mon_buf_replenish(ab, buf_ring, 1);
+
+	return 0;
+}
+
+static int
+ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k *ar,
+				struct ath12k_mon_data *pmon,
+				enum hal_rx_mon_status hal_status,
+				const void *tlv_data)
+{
+	switch (hal_status) {
+	case HAL_RX_MON_STATUS_MPDU_START:
+		if (WARN_ON_ONCE(pmon->mon_mpdu))
+			break;
+
+		pmon->mon_mpdu = kzalloc(sizeof(*pmon->mon_mpdu), GFP_ATOMIC);
+		if (!pmon->mon_mpdu)
+			return -ENOMEM;
+		break;
+	case HAL_RX_MON_STATUS_BUF_ADDR:
+		return ath12k_dp_mon_parse_status_buf(ar, pmon, tlv_data);
+	case HAL_RX_MON_STATUS_MPDU_END:
+		/* If no MSDU then free empty MPDU */
+		if (pmon->mon_mpdu->tail) {
+			pmon->mon_mpdu->tail->next = NULL;
+			list_add_tail(&pmon->mon_mpdu->list, &pmon->dp_rx_mon_mpdu_list);
+		} else {
+			kfree(pmon->mon_mpdu);
+		}
+		pmon->mon_mpdu = NULL;
+		break;
+	case HAL_RX_MON_STATUS_MSDU_END:
+		return ath12k_dp_mon_parse_status_msdu_end(pmon, tlv_data);
+	default:
+		break;
+	}
+
+	return 0;
+}
+
 static enum hal_rx_mon_status
 ath12k_dp_mon_parse_rx_dest(struct ath12k *ar, struct ath12k_mon_data *pmon,
 			    struct sk_buff *skb)
@@ -2145,14 +2283,20 @@ ath12k_dp_mon_parse_rx_dest(struct ath12k *ar, struct ath12k_mon_data *pmon,
 			tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN);
 
 		hal_status = ath12k_dp_mon_rx_parse_status_tlv(ar, pmon, tlv);
+
+		if (ar->monitor_started &&
+		    ath12k_dp_mon_parse_rx_dest_tlv(ar, pmon, hal_status, tlv->value))
+			return HAL_RX_MON_STATUS_PPDU_DONE;
+
 		ptr += sizeof(*tlv) + tlv_len;
 		ptr = PTR_ALIGN(ptr, HAL_TLV_64_ALIGN);
 
-		if ((ptr - skb->data) >= DP_RX_BUFFER_SIZE)
+		if ((ptr - skb->data) > skb->len)
 			break;
 
 	} while ((hal_status == HAL_RX_MON_STATUS_PPDU_NOT_DONE) ||
 		 (hal_status == HAL_RX_MON_STATUS_BUF_ADDR) ||
+		 (hal_status == HAL_RX_MON_STATUS_MPDU_START) ||
 		 (hal_status == HAL_RX_MON_STATUS_MPDU_END) ||
 		 (hal_status == HAL_RX_MON_STATUS_MSDU_END));
 
@@ -2173,9 +2317,11 @@ ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar,
 	struct dp_mon_mpdu *tmp;
 	struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu;
 	struct sk_buff *head_msdu, *tail_msdu;
-	enum hal_rx_mon_status hal_status = HAL_RX_MON_STATUS_BUF_DONE;
+	enum hal_rx_mon_status hal_status;
 
-	ath12k_dp_mon_parse_rx_dest(ar, pmon, skb);
+	hal_status = ath12k_dp_mon_parse_rx_dest(ar, pmon, skb);
+	if (hal_status != HAL_RX_MON_STATUS_PPDU_DONE)
+		return hal_status;
 
 	list_for_each_entry_safe(mon_mpdu, tmp, &pmon->dp_rx_mon_mpdu_list, list) {
 		list_del(&mon_mpdu->list);
@@ -2189,6 +2335,7 @@ ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar,
 
 		kfree(mon_mpdu);
 	}
+
 	return hal_status;
 }
 
@@ -3375,7 +3522,7 @@ int ath12k_dp_mon_srng_process(struct ath12k *ar, int *budget,
 		ath12k_dp_mon_rx_memset_ppdu_info(ppdu_info);
 
 	while ((skb = __skb_dequeue(&skb_list))) {
-		hal_status = ath12k_dp_mon_parse_rx_dest(ar, pmon, skb);
+		hal_status = ath12k_dp_mon_rx_parse_mon_status(ar, pmon, skb, napi);
 		if (hal_status != HAL_RX_MON_STATUS_PPDU_DONE) {
 			ppdu_info->ppdu_continuation = true;
 			dev_kfree_skb_any(skb);
diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h
index e4368eb42aca..b039f6b9277c 100644
--- a/drivers/net/wireless/ath/ath12k/dp_mon.h
+++ b/drivers/net/wireless/ath/ath12k/dp_mon.h
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: BSD-3-Clause-Clear */
 /*
  * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef ATH12K_DP_MON_H
@@ -9,6 +9,8 @@
 
 #include "core.h"
 
+#define ATH12K_MON_RX_DOT11_OFFSET	5
+
 enum dp_monitor_mode {
 	ATH12K_DP_TX_MONITOR_MODE,
 	ATH12K_DP_RX_MONITOR_MODE
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
index 689a011439f8..0aacd6f80efe 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.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-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/ieee80211.h>
@@ -4439,6 +4439,7 @@ int ath12k_dp_rx_pdev_mon_attach(struct ath12k *ar)
 
 	pmon->mon_last_linkdesc_paddr = 0;
 	pmon->mon_last_buf_cookie = DP_RX_DESC_COOKIE_MAX + 1;
+	INIT_LIST_HEAD(&pmon->dp_rx_mon_mpdu_list);
 	spin_lock_init(&pmon->mon_lock);
 
 	return 0;
diff --git a/drivers/net/wireless/ath/ath12k/hal_rx.h b/drivers/net/wireless/ath/ath12k/hal_rx.h
index 764730c447de..ec272e341481 100644
--- a/drivers/net/wireless/ath/ath12k/hal_rx.h
+++ b/drivers/net/wireless/ath/ath12k/hal_rx.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-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef ATH12K_HAL_RX_H
@@ -111,11 +111,12 @@ enum hal_rx_mon_status {
 	HAL_RX_MON_STATUS_PPDU_DONE,
 	HAL_RX_MON_STATUS_BUF_DONE,
 	HAL_RX_MON_STATUS_BUF_ADDR,
+	HAL_RX_MON_STATUS_MPDU_START,
 	HAL_RX_MON_STATUS_MPDU_END,
 	HAL_RX_MON_STATUS_MSDU_END,
 };
 
-#define HAL_RX_MAX_MPDU		256
+#define HAL_RX_MAX_MPDU				1024
 #define HAL_RX_NUM_WORDS_PER_PPDU_BITMAP	(HAL_RX_MAX_MPDU >> 5)
 
 struct hal_rx_user_status {
@@ -509,6 +510,15 @@ struct hal_rx_mpdu_start {
 	__le32 rsvd2[16];
 } __packed;
 
+struct hal_rx_msdu_end {
+	__le32 info0;
+	__le32 rsvd0[18];
+	__le32 info1;
+	__le32 rsvd1[10];
+	__le32 info2;
+	__le32 rsvd2;
+} __packed;
+
 #define HAL_RX_PPDU_END_DURATION	GENMASK(23, 0)
 struct hal_rx_ppdu_end_duration {
 	__le32 rsvd0[9];
-- 
2.34.1


^ permalink raw reply related

* [PATCH 1/7] wifi: ath12k: fix link valid field initialization in the monitor Rx
From: Karthikeyan Periyasamy @ 2025-01-07  2:10 UTC (permalink / raw)
  To: ath12k; +Cc: linux-wireless, Hari Chandrakanthan, Karthikeyan Periyasamy
In-Reply-To: <20250107021017.3857555-1-quic_periyasa@quicinc.com>

From: Hari Chandrakanthan <quic_haric@quicinc.com>

Currently, the link_valid field is not initialized in the monitor Rx path.
This can result in random values for the link_valid and link_id leads to
undefined behaviour in mac80211. Therefore, initialize the link_valid
field in the monitor Rx path.

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

Signed-off-by: Hari Chandrakanthan <quic_haric@quicinc.com>
Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
---
 drivers/net/wireless/ath/ath12k/dp_mon.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c
index d78ea638451e..84289e4dacb1 100644
--- a/drivers/net/wireless/ath/ath12k/dp_mon.c
+++ b/drivers/net/wireless/ath/ath12k/dp_mon.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: BSD-3-Clause-Clear
 /*
  * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include "dp_mon.h"
@@ -1999,6 +1999,8 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct
 	bool is_mcbc = rxcb->is_mcbc;
 	bool is_eapol_tkip = rxcb->is_eapol;
 
+	status->link_valid = 0;
+
 	if ((status->encoding == RX_ENC_HE) && !(status->flag & RX_FLAG_RADIOTAP_HE) &&
 	    !(status->flag & RX_FLAG_SKIP_MONITOR)) {
 		he = skb_push(msdu, sizeof(known));
-- 
2.34.1


^ permalink raw reply related

* [PATCH 0/7] wifi: ath12k: Add monitor interface support on QCN9274
From: Karthikeyan Periyasamy @ 2025-01-07  2:10 UTC (permalink / raw)
  To: ath12k; +Cc: linux-wireless, Karthikeyan Periyasamy

Currently, monitor interface not supported. Therefore, add the missed TLV
tags parsing in the monitor parser, configure the monitor vdev state
identifier with HTT filter setup.

Depends-On:
	[PATCH v3 0/3] wifi: ath12k: Refactor monitor Rx handler
	https://lore.kernel.org/all/20241224143613.164921-1-quic_periyasa@quicinc.com/

	[PATCH v2 00/14] wifi: ath12k: Enable monitor ring for updating station dump in QCN9274
	https://lore.kernel.org/all/20241223060132.3506372-1-quic_ppranees@quicinc.com/

	[PATCH v2 00/10] wifi: ath12k: Add peer extended Rx statistics debugfs support
	https://lore.kernel.org/all/20241224161442.263729-1-quic_periyasa@quicinc.com/

Hari Chandrakanthan (1):
  wifi: ath12k: fix link valid field initialization in the monitor Rx

Karthikeyan Periyasamy (1):
  wifi: ath12k: Replace band define G with GHZ where appropriate

P Praneesh (5):
  wifi: ath12k: Add extra TLV tag parsing support in monitor Rx path
  wifi: ath12k: Avoid fetch Error bitmap and decap format from Rx TLV
  wifi: ath12k: change the status update in the monitor Rx
  wifi: ath12k: Avoid packet offset and FCS length from Rx TLV
  wifi: ath12k: add monitor interface support on QCN9274

 drivers/net/wireless/ath/ath12k/core.c   |   7 +-
 drivers/net/wireless/ath/ath12k/core.h   |  20 +-
 drivers/net/wireless/ath/ath12k/dp.h     |   4 +-
 drivers/net/wireless/ath/ath12k/dp_mon.c | 364 +++++++++++++++++++----
 drivers/net/wireless/ath/ath12k/dp_mon.h |   5 +-
 drivers/net/wireless/ath/ath12k/dp_rx.c  |   7 +-
 drivers/net/wireless/ath/ath12k/dp_tx.c  |   4 +-
 drivers/net/wireless/ath/ath12k/hal_rx.h |  17 +-
 drivers/net/wireless/ath/ath12k/hw.c     |   4 +-
 drivers/net/wireless/ath/ath12k/mac.c    |  76 +++--
 drivers/net/wireless/ath/ath12k/wmi.c    |  38 +--
 drivers/net/wireless/ath/ath12k/wmi.h    |  20 +-
 12 files changed, 439 insertions(+), 127 deletions(-)


base-commit: 09fa3b6974a1245ddd0751747609431494ba5b4f
prerequisite-patch-id: 5f5721a4c9f1c26659fd8f09a8eda648d8ecccf5
prerequisite-patch-id: 59cc2121e734e4e1e7e461a3ae24f3f1f9d0fa02
prerequisite-patch-id: fdc512e43ea7cb6c097ba4c0d9c661a74c0c2a6f
prerequisite-patch-id: afb04ab90da26435239077de723d1276946a194a
prerequisite-patch-id: 1b12bea72973c14f461b8202eed9432f27932876
prerequisite-patch-id: a6719494f46b8568504be8c64255676e67b4deda
prerequisite-patch-id: 054756eb1705babff324a743e62685bb78035198
prerequisite-patch-id: 889c4a0174fac23261705a42b46e923d7e7a0a18
prerequisite-patch-id: ea0321fbd8a59c09191873f59b6aea8225f4b8e5
prerequisite-patch-id: 3c8ccb635d319f8755649e445b68feb615fd82c4
prerequisite-patch-id: d516b2a3196218f42fdf4567516a1fd2c8b4c40f
prerequisite-patch-id: a2c59b4e468384e27d934a986e5fe9a951685fd9
prerequisite-patch-id: 359fecf93ef53f39243cc1b3466ab06fbd33cc71
prerequisite-patch-id: bf0b6542c65299c0bfa7fef2da6f09dd8453c39f
prerequisite-patch-id: 1dc79cafb399be590d1e418afcc5a719ae35834f
prerequisite-patch-id: fb1e39f2dce024ff692b0e6b112dc90c6a43ad00
prerequisite-patch-id: 9ea3943ae0b6e6a5a09cb648eaa35f8087967ac3
prerequisite-patch-id: 35da9ccb2466675b50e819029c13cbda70702fc2
prerequisite-patch-id: 282cdacca7b9bbef5a94b1a78457304d38362af2
prerequisite-patch-id: 5bdb2bd29cd4c92d23708432f451e92951c23f0e
prerequisite-patch-id: 4b6f75cfa4d25f974f8fa61adbc85fff35a187fa
prerequisite-patch-id: 6a015b7d89f3d61adb5d60eff2d63fea10d9c3b0
prerequisite-patch-id: eab7d17c9891dd9a1c6152d8e180b72a08980956
prerequisite-patch-id: 12367e8ecdccf254c41bd0518cea6877e4673bb3
prerequisite-patch-id: d94f4a9c9b0b3bdc9e709efcae0cba4983bf440f
prerequisite-patch-id: 8c9df1e16a25c3b9a3fb709ba9bc8d37e6f14a5e
prerequisite-patch-id: 35a364a01fcf09cff2d3c7a7630465e4977b5c06
-- 
2.34.1


^ permalink raw reply

* Re: [PATCH] wifi: ath12k: fix tx power, max reg power update to firmware
From: Aditya Kumar Singh @ 2025-01-07  1:27 UTC (permalink / raw)
  To: Santhosh Ramesh, ath12k; +Cc: linux-wireless, Sathishkumar Muruganandam
In-Reply-To: <20240909073049.3423035-1-quic_santrame@quicinc.com>

On 9/9/24 13:00, Santhosh Ramesh wrote:
> From: Sathishkumar Muruganandam <quic_murugana@quicinc.com>
> 
> Currently, when the vdev start WMI cmd is sent from host, vdev related
> parameters such as max_reg_power, max_power, and max_antenna_gain are
> multiplied by 2 before being sent to the firmware. This is incorrect
> because the firmware uses 1 dBm steps for power calculations.
> 
> This leads to incorrect power values being used in the firmware and
> radio, potentially causing incorrect behavior.
> 
> Fix the update of max_reg_power, max_power, and max_antenna_gain values
> in the ath12k_mac_vdev_start_restart function, ensuring accurate
> power settings in the firmware by sending these values as-is,
> without multiplication.
> 
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.1.1-00214-QCAHKSWPL_SILICONZ-1
> 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: Sathishkumar Muruganandam <quic_murugana@quicinc.com>
> Signed-off-by: Santhosh Ramesh <quic_santrame@quicinc.com>
> ---

Hi Jeff/Kalle,

It would be good, if Fixes tag can be added while applying this patch.


-- 
Aditya

^ permalink raw reply

* RE: [PATCH] wifi: rtw88: sdio: Fix disconnection after beacon loss
From: Ping-Ke Shih @ 2025-01-07  0:27 UTC (permalink / raw)
  To: Fiona Klute, linux-wireless@vger.kernel.org
  Cc: Vasily Khoruzhick, Kalle Valo, Bitterblue Smith, Ondrej Jirman,
	stable@vger.kernel.org
In-Reply-To: <20250106135434.35936-1-fiona.klute@gmx.de>

Fiona Klute <fiona.klute@gmx.de> wrote:
> This is the equivalent of 28818b4d871bc93cc4f5c7c7d7c526a6a096c09c

Normally use 12 digits as pattern like: 

Commit 28818b4d871b ("wifi: rtw88: usb: Fix disconnection after beacon loss")

I can spin this during merging. 

> "wifi: rtw88: usb: Fix disconnection after beacon loss" for SDIO
> chips. Tested on Pinephone (RTL8723CS), random disconnections became
> rare, instead of a frequent nuisance.
> 
> Cc: stable@vger.kernel.org
> Signed-off-by: Fiona Klute <fiona.klute@gmx.de>

Acked-by: Ping-Ke Shih <pkshih@realtek.com>

> ---
>  drivers/net/wireless/realtek/rtw88/sdio.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c
> index 799230eb5f1..e024061bdbf 100644
> --- a/drivers/net/wireless/realtek/rtw88/sdio.c
> +++ b/drivers/net/wireless/realtek/rtw88/sdio.c
> @@ -1192,6 +1192,8 @@ static void rtw_sdio_indicate_tx_status(struct rtw_dev *rtwdev,
>         struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
>         struct ieee80211_hw *hw = rtwdev->hw;
> 
> +       skb_pull(skb, rtwdev->chip->tx_pkt_desc_sz);
> +
>         /* enqueue to wait for tx report */
>         if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) {
>                 rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn);
> --
> 2.47.1


^ permalink raw reply

* Re: [PATCH v2 0/6] wifi: ath12k: Support Sounding, Latency, Trigger, FSE stats
From: Jeff Johnson @ 2025-01-06 20:46 UTC (permalink / raw)
  To: Roopni Devanathan, ath12k; +Cc: linux-wireless
In-Reply-To: <20241224102013.1530055-1-quic_rdevanat@quicinc.com>

On 12/24/2024 2:20 AM, Roopni Devanathan wrote:
> Add support to request HTT stats type 22, 25, 26, 27 and 28 from
> firmware. These stats give sounding stats, latency stats, trigger stats
> for uplink OFDMA and MUMIMO and FSE stats, respectively.
> 
> Depends-on:
> [PATCH 0/2] wifi: ath12k: Support Rate and OFDMA Stats
> Link: https://lore.kernel.org/all/20241128110949.3672364-1-quic_rdevanat@quicinc.com/
> 
> [PATCH v4 0/2] wifi: ath12k: Support AST and Puncture Stats
> Link: https://lore.kernel.org/all/20241217055408.1293764-1-quic_rdevanat@quicinc.com/
> 
> v2:
>  - Added line breaks where necessary, as pointed out by Kalle.
>  - Modified the use of pointer arithmetic print_array_to_buf_s8().
>  - Modified commit logs, as suggested by Kalle. 
> 
> Dinesh Karthikeyan (5):
>   wifi: ath12k: Support Sounding Stats
>   wifi: ath12k: Support Latency Stats
>   wifi: ath12k: Support Uplink OFDMA Trigger Stats
>   wifi: ath12k: Support Uplink MUMIMO Trigger Stats
>   wifi: ath12k: Support Received FSE Stats
> 
> Roopni Devanathan (1):
>   wifi: ath12k: Add API to print s8 arrays in HTT stats
> 
>  .../wireless/ath/ath12k/debugfs_htt_stats.c   | 736 ++++++++++++++++++
>  .../wireless/ath/ath12k/debugfs_htt_stats.h   | 267 ++++++-
>  2 files changed, 970 insertions(+), 33 deletions(-)
> 
> 
> base-commit: 09fa3b6974a1245ddd0751747609431494ba5b4f
> prerequisite-patch-id: c30df5e4af6f5773ed942d8f78de88c05ce2b18b
> prerequisite-patch-id: f2181eee4bce2e3487db9bd81ed962f477759e7e

FYI this is not applying to my test tree. Strangely, you list two 2-patch
dependencies but only have 2 prerequisite-patch-ids instead of 4.

I now have both "Rate and OFDMA Stats" and "AST and Puncture Stats" in the
pending branch. Look for those to be merged, and then rebase on the main
branch at that time.

/jeff

^ permalink raw reply

* [PATCH] wifi: brcmfmac: Add missing Return: to function documentation
From: Jeff Johnson @ 2025-01-06 20:34 UTC (permalink / raw)
  To: Arend van Spriel, Kalle Valo
  Cc: linux-wireless, brcm80211, brcm80211-dev-list.pdl, linux-kernel,
	Jeff Johnson

Running 'scripts/kernel-doc -Wall -Werror -none' flagged the following
kernel-doc issues:

drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c:823: warning: No description found for return value of 'brcmf_apsta_add_vif'
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c:907: warning: No description found for return value of 'brcmf_mon_add_vif'
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c:7419: warning: No description found for return value of 'brcmf_setup_ifmodes'

Add the missing 'Return:' tags to the kernel-doc of these functions.

Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
---
FYI these issues were observed as part of my internal pre-commit
checking of an upcoming cfg80211 change that modifies a driver API.
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 902ac3108782..4b70845e1a26 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -814,6 +814,8 @@ static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
  * @name: name of the new interface.
  * @params: contains mac address for AP or STA device.
  * @type: interface type.
+ *
+ * Return: pointer to new vif on success, ERR_PTR(-errno) if not
  */
 static
 struct wireless_dev *brcmf_apsta_add_vif(struct wiphy *wiphy, const char *name,
@@ -900,6 +902,8 @@ static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
  *
  * @wiphy: wiphy device of new interface.
  * @name: name of the new interface.
+ *
+ * Return: pointer to new vif on success, ERR_PTR(-errno) if not
  */
 static struct wireless_dev *brcmf_mon_add_vif(struct wiphy *wiphy,
 					      const char *name)
@@ -7412,6 +7416,8 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
  * p2p, rsdb, and no mbss:
  *	#STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 2, AP <= 2,
  *	 channels = 2, 4 total
+ *
+ * Return: 0 on success, negative errno on failure
  */
 static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
 {

---
base-commit: b73e56f16250c6124f8975636f1844472f6fd450
change-id: 20250106-brcmfmac-kdoc-1d498722babd


^ permalink raw reply related

* Re: [PATCH] wifi: brcmfmac: Check the return value of of_property_read_string_index
From: Stefan Dösinger @ 2025-01-06 18:53 UTC (permalink / raw)
  To: linux-wireless, Arend van Spriel
In-Reply-To: <4619776.LvFx2qVVIh@grey>

[-- Attachment #1: Type: text/plain, Size: 1747 bytes --]

Hello Arend,

Am Montag, 6. Januar 2025, 14:22:29 Ostafrikanische Zeit schrieb Stefan 
Dösinger:
> Am Montag, 6. Januar 2025, 14:02:17 Ostafrikanische Zeit schrieb Arend van
> 
> Spriel:
> > On 1/6/2025 11:37 AM, Stefan Dösinger wrote:
> > > Somewhen between 6.10 and 6.11 the driver started to crash on my
> > > MacBookPro14,3. The property doesn't exist and 'tmp' remains
> > > uninitialized, so we pass a random pointer to devm_kstrdup().
> > 
> > By the looks of it this is an intel-based platform. Is that correct? So
> > does it have a devicetree? I would expect the root node find to fail,
> > but apparently is does not. Strange though that root node does not have
> > a compatible property. Anyway, the analysis looks sane so ...
> 
> Yes, this is an Intel based MacBook Pro - the 2017 version.

I have an updated theory why the codepath was entered: My kernel config had 
CONFIG_OF (and CONFIG_OF_OVERLAY) enabled. I did not provide any DTBs on boot, 
but this configuration apparently resulted in an empty root node being found. 
I also see an empty (0 byte) /proc/device-tree/name file. With CONFIG_OF=n the 
of.c file isn't compiled in the first place.

I think we still want to patch the code. While enabling this option on 
standard x86 is arguably wrong, the driver shouldn't crash because of it.

I don't know where CONFIG_OF=y came from. This is a kernel configuration grown 
over 15 years. I might have accidentally enabled it in a "make oldconfig" run, 
or I enabled it 'just in case' without knowing what I was doing - this 
particular Linux installation is on a USB drive that I plug into many 
different x86_64 computers, so I enabled pretty much every driver (as a module 
if possible).

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH] wifi: rtw88: sdio: Fix disconnection after beacon loss
From: Vasily Khoruzhick @ 2025-01-06 18:01 UTC (permalink / raw)
  To: Fiona Klute
  Cc: Ping-Ke Shih, linux-wireless, Kalle Valo, Bitterblue Smith,
	Ondrej Jirman, stable
In-Reply-To: <20250106135434.35936-1-fiona.klute@gmx.de>

On Mon, Jan 6, 2025 at 5:54 AM Fiona Klute <fiona.klute@gmx.de> wrote:
>
> This is the equivalent of 28818b4d871bc93cc4f5c7c7d7c526a6a096c09c
> "wifi: rtw88: usb: Fix disconnection after beacon loss" for SDIO
> chips. Tested on Pinephone (RTL8723CS), random disconnections became
> rare, instead of a frequent nuisance.
>
> Cc: stable@vger.kernel.org
> Signed-off-by: Fiona Klute <fiona.klute@gmx.de>

Tested-by: Vasily Khoruzhick <anarsoul@gmail.com> # Tested on Pinebook

> ---
>  drivers/net/wireless/realtek/rtw88/sdio.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c
> index 799230eb5f1..e024061bdbf 100644
> --- a/drivers/net/wireless/realtek/rtw88/sdio.c
> +++ b/drivers/net/wireless/realtek/rtw88/sdio.c
> @@ -1192,6 +1192,8 @@ static void rtw_sdio_indicate_tx_status(struct rtw_dev *rtwdev,
>         struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
>         struct ieee80211_hw *hw = rtwdev->hw;
>
> +       skb_pull(skb, rtwdev->chip->tx_pkt_desc_sz);
> +
>         /* enqueue to wait for tx report */
>         if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) {
>                 rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn);
> --
> 2.47.1
>

^ permalink raw reply

* Re: brcmfmac SAE/WPA3 negotiation - Part 2
From: KeithG @ 2025-01-06 17:13 UTC (permalink / raw)
  To: Denis Kenzior
  Cc: Arend Van Spriel, James Prestwood, connman, brcm80211,
	linux-wireless
In-Reply-To: <eace9233-1b65-4793-8abe-abd3c640dba8@gmail.com>

On Mon, Jan 6, 2025 at 9:26 AM Denis Kenzior <denkenz@gmail.com> wrote:
>
> Hi Keith,
>
> On 1/5/25 6:41 PM, KeithG wrote:
> > I am looking at the iwmon logs for a successful wpa_supplicant
> > connection versus one from IWD. Both connect and both pass data and
> > both grab a DHCP address. I do note one difference in the connection,
> > though.
> >
> > Request : Connect
> > through the responses RTNL
> > wpa_supplicant knows it is dynamic
>
> wpa_supplicant doesn't manage network interfaces.  I assume you're using ConnMan
> for this? If so, ConnMan sets the IFF_DYNAMIC flag.  See
> https://git.kernel.org/pub/scm/network/connman/connman.git/tree/src/inet.c#n372
>
> >
> > Whereas the iwd log does not:
>
> iwd doesn't use IFF_DYNAMIC in its DHCP implementation at the moment.
>
> According to 'man netdevice':
>
>                IFF_DYNAMIC       The addresses are lost when the interface
>                                  goes down.
>
> I doubt this is the cause of your DHCP / connection problems.
>
> Regards,
> -Denis

Denis,

I am using connman to manage the connections. The connman config is
the same. The one iwmon snippet was with iwd masked and stopped but
wpa_supplicant installed and the connect performed in connmanctl. The
other is with wpa_supplicant removed and purged and iwd started,
running then restarted connman then initiated a connect form
connmanctl.

I pored over these logs yesterday and saw a few differences, but this
was one that stood out. I can look closer again tonight and see if I
notice anything else that I can summarize.

Keith

^ permalink raw reply

* [PATCH v2] wifi: brcmfmac: Check the return value of of_property_read_string_index
From: Stefan Dösinger @ 2025-01-06 17:09 UTC (permalink / raw)
  To: linux-wireless; +Cc: Arend van Spriel

Somewhen between 6.10 and 6.11 the driver started to crash on my
MacBookPro14,3. The property doesn't exist and 'tmp' remains
uninitialized, so we pass a random pointer to devm_kstrdup().

Signed-off-by: Stefan Dösinger <stefan@codeweavers.com>

---

v2: Don't assign err, inline of_property_read_string_index into the if
statement.

The crash I am getting looks like this:

BUG: unable to handle page fault for address: 00007f033c669379
PF: supervisor read access in kernel mode
PF: error_code(0x0001) - permissions violation
PGD 8000000101341067 P4D 8000000101341067 PUD 101340067 PMD 1013bb067 PTE 800000010aee9025
Oops: Oops: 0001 [#1] SMP PTI
CPU: 4 UID: 0 PID: 827 Comm: (udev-worker) Not tainted 6.11.8-gentoo #1
Hardware name: Apple Inc. MacBookPro14,3/Mac-551B86E5744E2388, BIOS 529.140.2.0.0 06/23/2024
RIP: 0010:strlen+0x4/0x30
Code: f7 75 ec 31 c0 c3 cc cc cc cc 48 89 f8 c3 cc cc cc cc 0f 1f 40 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa <80> 3f 00 74 14 48 89 f8 48 83 c0 01 80 38 00 75 f7 48 29 f8 c3 cc
RSP: 0018:ffffb4aac0683ad8 EFLAGS: 00010202
RAX: 00000000ffffffea RBX: 00007f033c669379 RCX: 0000000000000001
RDX: 0000000000000cc0 RSI: 00007f033c669379 RDI: 00007f033c669379
RBP: 00000000ffffffea R08: 0000000000000000 R09: 00000000c0ba916a
R10: ffffffffffffffff R11: ffffffffb61ea260 R12: ffff91f7815b50c8
R13: 0000000000000cc0 R14: ffff91fafefffe30 R15: ffffb4aac0683b30
FS:  00007f033ccbe8c0(0000) GS:ffff91faeed00000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f033c669379 CR3: 0000000107b1e004 CR4: 00000000003706f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
 <TASK>
 ? __die+0x23/0x70
 ? page_fault_oops+0x149/0x4c0
 ? raw_spin_rq_lock_nested+0xe/0x20
 ? sched_balance_newidle+0x22b/0x3c0
 ? update_load_avg+0x78/0x770
 ? exc_page_fault+0x6f/0x150
 ? asm_exc_page_fault+0x26/0x30
 ? __pfx_pci_conf1_write+0x10/0x10
 ? strlen+0x4/0x30
 devm_kstrdup+0x25/0x70
 brcmf_of_probe+0x273/0x350 [brcmfmac]
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
index c1f18e2fe540..1681ad00f82e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
@@ -99,13 +99,13 @@ int brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
 	/* Set board-type to the first string of the machine compatible prop */
 	root = of_find_node_by_path("/");
 	if (root && err) {
-		char *board_type;
+		char *board_type = NULL;
 		const char *tmp;
 
-		of_property_read_string_index(root, "compatible", 0, &tmp);
-
 		/* get rid of '/' in the compatible string to be able to find the FW */
-		board_type = devm_kstrdup(dev, tmp, GFP_KERNEL);
+		if (!of_property_read_string_index(root, "compatible", 0, &tmp))
+			board_type = devm_kstrdup(dev, tmp, GFP_KERNEL);
+
 		if (!board_type) {
 			of_node_put(root);
 			return 0;
-- 
2.45.2


^ permalink raw reply related

* Re: [PATCH v2] wifi: brcmfmac: of: Support interrupts-extended
From: Luca Weiss @ 2025-01-06 16:51 UTC (permalink / raw)
  To: Arend van Spriel, Kalle Valo, linux-wireless, brcm80211,
	brcm80211-dev-list.pdl, linux-kernel, Alex Bee
  Cc: ~postmarketos/upstreaming
In-Reply-To: <3f47bf7d-c8b1-464e-a824-406c4f66ee0a@gmail.com>

Hi Alex,

On zondag 5 januari 2025 21:36:25 Midden-Europese standaardtijd Alex Bee wrote:
> Hi Luca,
> 
> > Hi Alex,
> >
> > On zaterdag 22 juni 2024 23:54:16 Midden-Europese standaardtijd Alex Bee wrote:
> >> The currently existing of_property_present check for interrupts does not
> >> cover all ways interrupts can be defined in a device tree, e.g.
> >> "interrupts-extended".
> >>
> >> In order to support all current and future ways that can be done, drop that
> >> check and call of_irq_parse_one to figure out if an interrupt is defined
> >> and irq_create_of_mapping for the actual mapping and let it be handled by
> >> the interrupt subsystem.
> > This commit seems to break WiFi on qcom/apq8026-asus-sparrow on 6.11.11
> > release, and I'm guessing also other apq8026 devices that I have.
> >
> > dmesg looks like the following on this board:
> >
> > [   33.699503] brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac43430-sdio for chip BCM43430/1
> > [   33.811445] brcmfmac mmc1:0001:1: Direct firmware load for brcm/brcmfmac43430-sdio.clm_blob failed with error -2
> > [   36.565674] brcmfmac: brcmf_sdio_bus_rxctl: resumed on timeout
> > [   36.565725] ieee80211 phy0: brcmf_bus_started: failed: -110
> > [   36.565777] ieee80211 phy0: brcmf_attach: dongle is not responding: err=-110
> > [   36.575930] brcmfmac: brcmf_sdio_firmware_callback: brcmf_attach failed
> >
> > After reverting this commit it works well again:
> >
> > [  141.299739] cfg80211: Loading compiled-in X.509 certificates for regulatory database
> > [  141.355040] Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'
> > [  141.364695] Loaded X.509 cert 'wens: 61c038651aabdcf94bd0ac7ff06c7248db18c600'
> > [  141.469042] brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac43430-sdio for chip BCM43430/1
> > [  141.612365] brcmfmac mmc1:0001:1: Direct firmware load for brcm/brcmfmac43430-sdio.clm_blob failed with error -2
> > [  141.730597] brcmfmac: brcmf_c_process_clm_blob: no clm_blob available (err=-2), device may have limited channels available
> > [  141.730661] brcmfmac: brcmf_c_process_txcap_blob: no txcap_blob available (err=-2)
> > [  141.731778] brcmfmac: brcmf_c_preinit_dcmds: Firmware: BCM43430/1 wl0: Jun 23 2016 21:14:35 version 7.10.324.google.security.test (TOB) (r640416) FWID 01-495ddd98
> >
> > Would you have a different solution apart from just reverting this commit?
> 
> 
> it's very likely that the interrupts are wrongly defined in the device tree
> 
> and nobody noticed it yet because the driver didn't pick them up before
> this commit.

Ah, would make sense. At least from what I can find easily upstream only my
3 apq8026 boards and rk3368-lba3368 is using interrupts-extended. For example
qcom-msm8974pro-samsung-klte-common.dtsi is using interrupt-parent +
interrupts.

> 
> In particular, looking at qcom-apq8026-asus-sparrow.dts: I would guess that
> the IRQ_TYPE_EDGE_FALLING trigger doesn't make much sense if this pinctrl
> is set to bias-disable.
> 
> You could try changing this to IRQ_TYPE_EDGE_RISING. If changing the IRQ
> trigger flag doesn't help, you should check if your board's wifi interrupt
> pin is really connected to gpio46.

I was re-reading the downstream code and if I follow it correctly,
EDGE_RISING should be correct.

https://android.googlesource.com/kernel/msm/+/refs/heads/android-msm-sparrow-3.10-marshmallow-mr1-wear-release/arch/arm/mach-msm/board_wifi_bcm.c#451
(interesting lines are also with Ctrl-F for WLAN_HOSTWAKE)

> 
> (Please don't forget to submit a patch if you can fix the problem)

For sure, I will test this since it looks like I copy pasted the wrong
definition to all of my apq8026 smartwatches.

> 
> Regards,
> Alex
> 
> > Regards
> > Luca
> >
> >> Signed-off-by: Alex Bee <knaerzche@gmail.com>
> >> ---
> >> Link to v1:
> >> https://lore.kernel.org/all/20240621225558.280462-1-knaerzche@gmail.com/
> >>
> >>   drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c | 5 +++--
> >>   1 file changed, 3 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
> >> index e406e11481a6..fe4f65756105 100644
> >> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
> >> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
> >> @@ -70,6 +70,7 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
> >>   {
> >>   	struct brcmfmac_sdio_pd *sdio = &settings->bus.sdio;
> >>   	struct device_node *root, *np = dev->of_node;
> >> +	struct of_phandle_args oirq;
> >>   	const char *prop;
> >>   	int irq;
> >>   	int err;
> >> @@ -129,10 +130,10 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
> >>   		sdio->drive_strength = val;
> >>   
> >>   	/* make sure there are interrupts defined in the node */
> >> -	if (!of_property_present(np, "interrupts"))
> >> +	if (of_irq_parse_one(np, 0, &oirq))
> >>   		return;
> >>   
> >> -	irq = irq_of_parse_and_map(np, 0);
> >> +	irq = irq_create_of_mapping(&oirq);
> >>   	if (!irq) {
> >>   		brcmf_err("interrupt could not be mapped\n");
> >>   		return;
> >>
> >
> >
> >
> 





^ permalink raw reply

* Re: brcmfmac SAE/WPA3 negotiation - Part 2
From: Denis Kenzior @ 2025-01-06 15:26 UTC (permalink / raw)
  To: KeithG, Arend Van Spriel
  Cc: James Prestwood, connman, brcm80211, linux-wireless
In-Reply-To: <CAG17S_NfqFjjaWj6vGS1HXux6JDy0QKcg8aQAR=aOzNGhO0a3w@mail.gmail.com>

Hi Keith,

On 1/5/25 6:41 PM, KeithG wrote:
> I am looking at the iwmon logs for a successful wpa_supplicant
> connection versus one from IWD. Both connect and both pass data and
> both grab a DHCP address. I do note one difference in the connection,
> though.
> 
> Request : Connect
> through the responses RTNL
> wpa_supplicant knows it is dynamic

wpa_supplicant doesn't manage network interfaces.  I assume you're using ConnMan 
for this? If so, ConnMan sets the IFF_DYNAMIC flag.  See
https://git.kernel.org/pub/scm/network/connman/connman.git/tree/src/inet.c#n372

> 
> Whereas the iwd log does not:

iwd doesn't use IFF_DYNAMIC in its DHCP implementation at the moment.

According to 'man netdevice':

               IFF_DYNAMIC       The addresses are lost when the interface
                                 goes down.

I doubt this is the cause of your DHCP / connection problems.

Regards,
-Denis

^ permalink raw reply

* [PATCH] wifi: rtw88: sdio: Fix disconnection after beacon loss
From: Fiona Klute @ 2025-01-06 13:54 UTC (permalink / raw)
  To: Ping-Ke Shih, linux-wireless
  Cc: Vasily Khoruzhick, Kalle Valo, Bitterblue Smith, Ondrej Jirman,
	Fiona Klute, stable

This is the equivalent of 28818b4d871bc93cc4f5c7c7d7c526a6a096c09c
"wifi: rtw88: usb: Fix disconnection after beacon loss" for SDIO
chips. Tested on Pinephone (RTL8723CS), random disconnections became
rare, instead of a frequent nuisance.

Cc: stable@vger.kernel.org
Signed-off-by: Fiona Klute <fiona.klute@gmx.de>
---
 drivers/net/wireless/realtek/rtw88/sdio.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c
index 799230eb5f1..e024061bdbf 100644
--- a/drivers/net/wireless/realtek/rtw88/sdio.c
+++ b/drivers/net/wireless/realtek/rtw88/sdio.c
@@ -1192,6 +1192,8 @@ static void rtw_sdio_indicate_tx_status(struct rtw_dev *rtwdev,
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_hw *hw = rtwdev->hw;
 
+	skb_pull(skb, rtwdev->chip->tx_pkt_desc_sz);
+
 	/* enqueue to wait for tx report */
 	if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) {
 		rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn);
-- 
2.47.1


^ permalink raw reply related

* [PATCH net-next v6 1/8] page_pool: introduce page_pool_get_pp() API
From: Yunsheng Lin @ 2025-01-06 13:01 UTC (permalink / raw)
  To: davem, kuba, pabeni
  Cc: liuyonglong, fanghaiqing, zhangkun09, Yunsheng Lin, Wei Fang,
	Shenwei Wang, Clark Wang, Andrew Lunn, Eric Dumazet,
	Jeroen de Borst, Praveen Kaligineedi, Shailend Chand, Tony Nguyen,
	Przemek Kitszel, Alexander Lobakin, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend,
	Saeed Mahameed, Leon Romanovsky, Tariq Toukan, Felix Fietkau,
	Lorenzo Bianconi, Ryder Lee, Shayne Chen, Sean Wang, Kalle Valo,
	Matthias Brugger, AngeloGioacchino Del Regno, Simon Horman,
	Ilias Apalodimas, imx, netdev, linux-kernel, intel-wired-lan, bpf,
	linux-rdma, linux-wireless, linux-arm-kernel, linux-mediatek
In-Reply-To: <20250106130116.457938-1-linyunsheng@huawei.com>

introduce page_pool_get_pp() API to avoid caller accessing
page->pp directly.

Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
---
 drivers/net/ethernet/freescale/fec_main.c          |  8 +++++---
 .../net/ethernet/google/gve/gve_buffer_mgmt_dqo.c  |  2 +-
 drivers/net/ethernet/intel/iavf/iavf_txrx.c        |  6 ++++--
 drivers/net/ethernet/intel/idpf/idpf_txrx.c        | 14 +++++++++-----
 drivers/net/ethernet/intel/libeth/rx.c             |  2 +-
 drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c   |  3 ++-
 drivers/net/netdevsim/netdev.c                     |  6 ++++--
 drivers/net/wireless/mediatek/mt76/mt76.h          |  2 +-
 include/net/libeth/rx.h                            |  3 ++-
 include/net/page_pool/helpers.h                    |  5 +++++
 10 files changed, 34 insertions(+), 17 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index b2daed55bf6c..18d2119dbec1 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1009,7 +1009,8 @@ static void fec_enet_bd_init(struct net_device *dev)
 				struct page *page = txq->tx_buf[i].buf_p;
 
 				if (page)
-					page_pool_put_page(page->pp, page, 0, false);
+					page_pool_put_page(page_pool_get_pp(page),
+							   page, 0, false);
 			}
 
 			txq->tx_buf[i].buf_p = NULL;
@@ -1549,7 +1550,7 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id, int budget)
 			xdp_return_frame_rx_napi(xdpf);
 		} else { /* recycle pages of XDP_TX frames */
 			/* The dma_sync_size = 0 as XDP_TX has already synced DMA for_device */
-			page_pool_put_page(page->pp, page, 0, true);
+			page_pool_put_page(page_pool_get_pp(page), page, 0, true);
 		}
 
 		txq->tx_buf[index].buf_p = NULL;
@@ -3307,7 +3308,8 @@ static void fec_enet_free_buffers(struct net_device *ndev)
 			} else {
 				struct page *page = txq->tx_buf[i].buf_p;
 
-				page_pool_put_page(page->pp, page, 0, false);
+				page_pool_put_page(page_pool_get_pp(page),
+						   page, 0, false);
 			}
 
 			txq->tx_buf[i].buf_p = NULL;
diff --git a/drivers/net/ethernet/google/gve/gve_buffer_mgmt_dqo.c b/drivers/net/ethernet/google/gve/gve_buffer_mgmt_dqo.c
index 403f0f335ba6..87422b8828ff 100644
--- a/drivers/net/ethernet/google/gve/gve_buffer_mgmt_dqo.c
+++ b/drivers/net/ethernet/google/gve/gve_buffer_mgmt_dqo.c
@@ -210,7 +210,7 @@ void gve_free_to_page_pool(struct gve_rx_ring *rx,
 	if (!page)
 		return;
 
-	page_pool_put_full_page(page->pp, page, allow_direct);
+	page_pool_put_full_page(page_pool_get_pp(page), page, allow_direct);
 	buf_state->page_info.page = NULL;
 }
 
diff --git a/drivers/net/ethernet/intel/iavf/iavf_txrx.c b/drivers/net/ethernet/intel/iavf/iavf_txrx.c
index 26b424fd6718..e1bf5554f6e3 100644
--- a/drivers/net/ethernet/intel/iavf/iavf_txrx.c
+++ b/drivers/net/ethernet/intel/iavf/iavf_txrx.c
@@ -1050,7 +1050,8 @@ static void iavf_add_rx_frag(struct sk_buff *skb,
 			     const struct libeth_fqe *rx_buffer,
 			     unsigned int size)
 {
-	u32 hr = rx_buffer->page->pp->p.offset;
+	struct page_pool *pool = page_pool_get_pp(rx_buffer->page);
+	u32 hr = pool->p.offset;
 
 	skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, rx_buffer->page,
 			rx_buffer->offset + hr, size, rx_buffer->truesize);
@@ -1067,7 +1068,8 @@ static void iavf_add_rx_frag(struct sk_buff *skb,
 static struct sk_buff *iavf_build_skb(const struct libeth_fqe *rx_buffer,
 				      unsigned int size)
 {
-	u32 hr = rx_buffer->page->pp->p.offset;
+	struct page_pool *pool = page_pool_get_pp(rx_buffer->page);
+	u32 hr = pool->p.offset;
 	struct sk_buff *skb;
 	void *va;
 
diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
index 2fa9c36e33c9..04f2347716ca 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
@@ -385,7 +385,8 @@ static void idpf_rx_page_rel(struct libeth_fqe *rx_buf)
 	if (unlikely(!rx_buf->page))
 		return;
 
-	page_pool_put_full_page(rx_buf->page->pp, rx_buf->page, false);
+	page_pool_put_full_page(page_pool_get_pp(rx_buf->page), rx_buf->page,
+				false);
 
 	rx_buf->page = NULL;
 	rx_buf->offset = 0;
@@ -3098,7 +3099,8 @@ idpf_rx_process_skb_fields(struct idpf_rx_queue *rxq, struct sk_buff *skb,
 void idpf_rx_add_frag(struct idpf_rx_buf *rx_buf, struct sk_buff *skb,
 		      unsigned int size)
 {
-	u32 hr = rx_buf->page->pp->p.offset;
+	struct page_pool *pool = page_pool_get_pp(rx_buf->page);
+	u32 hr = pool->p.offset;
 
 	skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, rx_buf->page,
 			rx_buf->offset + hr, size, rx_buf->truesize);
@@ -3130,8 +3132,10 @@ static u32 idpf_rx_hsplit_wa(const struct libeth_fqe *hdr,
 	if (!libeth_rx_sync_for_cpu(buf, copy))
 		return 0;
 
-	dst = page_address(hdr->page) + hdr->offset + hdr->page->pp->p.offset;
-	src = page_address(buf->page) + buf->offset + buf->page->pp->p.offset;
+	dst = page_address(hdr->page) + hdr->offset +
+		page_pool_get_pp(hdr->page)->p.offset;
+	src = page_address(buf->page) + buf->offset +
+		page_pool_get_pp(buf->page)->p.offset;
 	memcpy(dst, src, LARGEST_ALIGN(copy));
 
 	buf->offset += copy;
@@ -3149,7 +3153,7 @@ static u32 idpf_rx_hsplit_wa(const struct libeth_fqe *hdr,
  */
 struct sk_buff *idpf_rx_build_skb(const struct libeth_fqe *buf, u32 size)
 {
-	u32 hr = buf->page->pp->p.offset;
+	u32 hr = page_pool_get_pp(buf->page)->p.offset;
 	struct sk_buff *skb;
 	void *va;
 
diff --git a/drivers/net/ethernet/intel/libeth/rx.c b/drivers/net/ethernet/intel/libeth/rx.c
index 66d1d23b8ad2..8de0c3a3b146 100644
--- a/drivers/net/ethernet/intel/libeth/rx.c
+++ b/drivers/net/ethernet/intel/libeth/rx.c
@@ -207,7 +207,7 @@ EXPORT_SYMBOL_NS_GPL(libeth_rx_fq_destroy, "LIBETH");
  */
 void libeth_rx_recycle_slow(struct page *page)
 {
-	page_pool_recycle_direct(page->pp, page);
+	page_pool_recycle_direct(page_pool_get_pp(page), page);
 }
 EXPORT_SYMBOL_NS_GPL(libeth_rx_recycle_slow, "LIBETH");
 
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
index 94b291662087..30baca49c71e 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
@@ -716,7 +716,8 @@ static void mlx5e_free_xdpsq_desc(struct mlx5e_xdpsq *sq,
 				/* No need to check ((page->pp_magic & ~0x3UL) == PP_SIGNATURE)
 				 * as we know this is a page_pool page.
 				 */
-				page_pool_recycle_direct(page->pp, page);
+				page_pool_recycle_direct(page_pool_get_pp(page),
+							 page);
 			} while (++n < num);
 
 			break;
diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
index e068a9761c09..e583415f9088 100644
--- a/drivers/net/netdevsim/netdev.c
+++ b/drivers/net/netdevsim/netdev.c
@@ -632,7 +632,8 @@ nsim_pp_hold_write(struct file *file, const char __user *data,
 		if (!ns->page)
 			ret = -ENOMEM;
 	} else {
-		page_pool_put_full_page(ns->page->pp, ns->page, false);
+		page_pool_put_full_page(page_pool_get_pp(ns->page), ns->page,
+					false);
 		ns->page = NULL;
 	}
 
@@ -831,7 +832,8 @@ void nsim_destroy(struct netdevsim *ns)
 
 	/* Put this intentionally late to exercise the orphaning path */
 	if (ns->page) {
-		page_pool_put_full_page(ns->page->pp, ns->page, false);
+		page_pool_put_full_page(page_pool_get_pp(ns->page), ns->page,
+					false);
 		ns->page = NULL;
 	}
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index ca2dba3ac65d..4d0e41a7bf4a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -1688,7 +1688,7 @@ static inline void mt76_put_page_pool_buf(void *buf, bool allow_direct)
 {
 	struct page *page = virt_to_head_page(buf);
 
-	page_pool_put_full_page(page->pp, page, allow_direct);
+	page_pool_put_full_page(page_pool_get_pp(page), page, allow_direct);
 }
 
 static inline void *
diff --git a/include/net/libeth/rx.h b/include/net/libeth/rx.h
index 43574bd6612f..f4ae75f9cc1b 100644
--- a/include/net/libeth/rx.h
+++ b/include/net/libeth/rx.h
@@ -137,7 +137,8 @@ static inline bool libeth_rx_sync_for_cpu(const struct libeth_fqe *fqe,
 		return false;
 	}
 
-	page_pool_dma_sync_for_cpu(page->pp, page, fqe->offset, len);
+	page_pool_dma_sync_for_cpu(page_pool_get_pp(page), page, fqe->offset,
+				   len);
 
 	return true;
 }
diff --git a/include/net/page_pool/helpers.h b/include/net/page_pool/helpers.h
index 543f54fa3020..9c4dbd2289b1 100644
--- a/include/net/page_pool/helpers.h
+++ b/include/net/page_pool/helpers.h
@@ -83,6 +83,11 @@ static inline u64 *page_pool_ethtool_stats_get(u64 *data, const void *stats)
 }
 #endif
 
+static inline struct page_pool *page_pool_get_pp(struct page *page)
+{
+	return page->pp;
+}
+
 /**
  * page_pool_dev_alloc_pages() - allocate a page.
  * @pool:	pool from which to allocate
-- 
2.33.0


^ permalink raw reply related

* Re: [PATCH] wifi: brcmfmac: Check the return value of of_property_read_string_index
From: Stefan Dösinger @ 2025-01-06 11:22 UTC (permalink / raw)
  To: linux-wireless, Arend van Spriel
In-Reply-To: <058aba76-817c-480a-9404-38b030325890@broadcom.com>

[-- Attachment #1: Type: text/plain, Size: 1528 bytes --]

Am Montag, 6. Januar 2025, 14:02:17 Ostafrikanische Zeit schrieb Arend van 
Spriel:
> On 1/6/2025 11:37 AM, Stefan Dösinger wrote:
> > Somewhen between 6.10 and 6.11 the driver started to crash on my
> > MacBookPro14,3. The property doesn't exist and 'tmp' remains
> > uninitialized, so we pass a random pointer to devm_kstrdup().
> 
> By the looks of it this is an intel-based platform. Is that correct? So
> does it have a devicetree? I would expect the root node find to fail,
> but apparently is does not. Strange though that root node does not have
> a compatible property. Anyway, the analysis looks sane so ...

Yes, this is an Intel based MacBook Pro - the 2017 version.

I was curious about the same thing and tried to find out where it expects to 
get those properties from. I didn't find a definitive answer and concluded 
that it reads the properties from somewhere on the wifi cards ROM rather than 
the computer's firmware / ACPI Tabes / whatever. If you can tell me where I 
should look I can see if I find out more.

If you think it is helpful or might point towards deeper issues I can try do a 
bisect for whatever patch broke this. I vaguely suspect though that it was 
always broken but by random luck a NULL pointer happened to be on the stack in 
the right place.

> No need to use 'err'. You can directly do
> of_property_read_string_index() in the if statement below.

Check, I'll resend. I found both styles in use (though admittedly reusing 
'err' to print it to dmesg).

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH] wifi: brcmfmac: Check the return value of of_property_read_string_index
From: Arend van Spriel @ 2025-01-06 11:02 UTC (permalink / raw)
  To: Stefan Dösinger, linux-wireless
In-Reply-To: <20250106103749.5764-1-stefan@codeweavers.com>

On 1/6/2025 11:37 AM, Stefan Dösinger wrote:
> Somewhen between 6.10 and 6.11 the driver started to crash on my
> MacBookPro14,3. The property doesn't exist and 'tmp' remains
> uninitialized, so we pass a random pointer to devm_kstrdup().

By the looks of it this is an intel-based platform. Is that correct? So 
does it have a devicetree? I would expect the root node find to fail, 
but apparently is does not. Strange though that root node does not have 
a compatible property. Anyway, the analysis looks sane so ...

minor remark below.

Acked-by: Arend van Spriel
> Signed-off-by: Stefan Dösinger <stefan@codeweavers.com>
> 

[...]

> ---
>   drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c | 8 +++++---
>   1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
> index c1f18e2fe540..ee589a7b4f4f 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
> @@ -99,13 +99,15 @@ int brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
>   	/* Set board-type to the first string of the machine compatible prop */
>   	root = of_find_node_by_path("/");
>   	if (root && err) {
> -		char *board_type;
> +		char *board_type = NULL;
>   		const char *tmp;
>   
> -		of_property_read_string_index(root, "compatible", 0, &tmp);
> +		err = of_property_read_string_index(root, "compatible", 0, &tmp);
>   
>   		/* get rid of '/' in the compatible string to be able to find the FW */
> -		board_type = devm_kstrdup(dev, tmp, GFP_KERNEL);

No need to use 'err'. You can directly do 
of_property_read_string_index() in the if statement below.

> +		if (!err)
> +			board_type = devm_kstrdup(dev, tmp, GFP_KERNEL);
> +
>   		if (!board_type) {
>   			of_node_put(root);
>   			return 0;


^ permalink raw reply

* [PATCH] wifi: brcmfmac: Check the return value of of_property_read_string_index
From: Stefan Dösinger @ 2025-01-06 10:37 UTC (permalink / raw)
  To: linux-wireless; +Cc: Arend van Spriel

Somewhen between 6.10 and 6.11 the driver started to crash on my
MacBookPro14,3. The property doesn't exist and 'tmp' remains
uninitialized, so we pass a random pointer to devm_kstrdup().

Signed-off-by: Stefan Dösinger <stefan@codeweavers.com>

---

The crash I am getting looks like this:

BUG: unable to handle page fault for address: 00007f033c669379
PF: supervisor read access in kernel mode
PF: error_code(0x0001) - permissions violation
PGD 8000000101341067 P4D 8000000101341067 PUD 101340067 PMD 1013bb067 PTE 800000010aee9025
Oops: Oops: 0001 [#1] SMP PTI
CPU: 4 UID: 0 PID: 827 Comm: (udev-worker) Not tainted 6.11.8-gentoo #1
Hardware name: Apple Inc. MacBookPro14,3/Mac-551B86E5744E2388, BIOS 529.140.2.0.0 06/23/2024
RIP: 0010:strlen+0x4/0x30
Code: f7 75 ec 31 c0 c3 cc cc cc cc 48 89 f8 c3 cc cc cc cc 0f 1f 40 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa <80> 3f 00 74 14 48 89 f8 48 83 c0 01 80 38 00 75 f7 48 29 f8 c3 cc
RSP: 0018:ffffb4aac0683ad8 EFLAGS: 00010202
RAX: 00000000ffffffea RBX: 00007f033c669379 RCX: 0000000000000001
RDX: 0000000000000cc0 RSI: 00007f033c669379 RDI: 00007f033c669379
RBP: 00000000ffffffea R08: 0000000000000000 R09: 00000000c0ba916a
R10: ffffffffffffffff R11: ffffffffb61ea260 R12: ffff91f7815b50c8
R13: 0000000000000cc0 R14: ffff91fafefffe30 R15: ffffb4aac0683b30
FS:  00007f033ccbe8c0(0000) GS:ffff91faeed00000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f033c669379 CR3: 0000000107b1e004 CR4: 00000000003706f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
 <TASK>
 ? __die+0x23/0x70
 ? page_fault_oops+0x149/0x4c0
 ? raw_spin_rq_lock_nested+0xe/0x20
 ? sched_balance_newidle+0x22b/0x3c0
 ? update_load_avg+0x78/0x770
 ? exc_page_fault+0x6f/0x150
 ? asm_exc_page_fault+0x26/0x30
 ? __pfx_pci_conf1_write+0x10/0x10
 ? strlen+0x4/0x30
 devm_kstrdup+0x25/0x70
 brcmf_of_probe+0x273/0x350 [brcmfmac]
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
index c1f18e2fe540..ee589a7b4f4f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
@@ -99,13 +99,15 @@ int brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
 	/* Set board-type to the first string of the machine compatible prop */
 	root = of_find_node_by_path("/");
 	if (root && err) {
-		char *board_type;
+		char *board_type = NULL;
 		const char *tmp;
 
-		of_property_read_string_index(root, "compatible", 0, &tmp);
+		err = of_property_read_string_index(root, "compatible", 0, &tmp);
 
 		/* get rid of '/' in the compatible string to be able to find the FW */
-		board_type = devm_kstrdup(dev, tmp, GFP_KERNEL);
+		if (!err)
+			board_type = devm_kstrdup(dev, tmp, GFP_KERNEL);
+
 		if (!board_type) {
 			of_node_put(root);
 			return 0;
-- 
2.45.2


^ permalink raw reply related

* [syzbot] [wireless?] WARNING: ODEBUG bug in __mod_timer (2)
From: syzbot @ 2025-01-06 10:03 UTC (permalink / raw)
  To: johannes, linux-kernel, linux-wireless, netdev, syzkaller-bugs

Hello,

syzbot found the following issue on:

HEAD commit:    ccb98ccef0e5 Merge tag 'platform-drivers-x86-v6.13-4' of g..
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=11a2d6df980000
kernel config:  https://syzkaller.appspot.com/x/.config?x=86dd15278dbfe19f
dashboard link: https://syzkaller.appspot.com/bug?extid=50abac586029cf8758e0
compiler:       gcc (Debian 12.2.0-14) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40

Unfortunately, I don't have any reproducer for this issue yet.

Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/d24eb225cff7/disk-ccb98cce.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/dd81532f8240/vmlinux-ccb98cce.xz
kernel image: https://storage.googleapis.com/syzbot-assets/18b08e4bbf40/bzImage-ccb98cce.xz

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+50abac586029cf8758e0@syzkaller.appspotmail.com

------------[ cut here ]------------
ODEBUG: assert_init not available (active state 0) object: ffff888068a59b28 object type: timer_list hint: ieee80211_ibss_timer+0x0/0x90
WARNING: CPU: 0 PID: 7396 at lib/debugobjects.c:612 debug_print_object+0x1a2/0x2b0 lib/debugobjects.c:612
Modules linked in:
CPU: 0 UID: 0 PID: 7396 Comm: kworker/u8:11 Not tainted 6.13.0-rc5-syzkaller-00004-gccb98ccef0e5 #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024
Workqueue: events_unbound cfg80211_wiphy_work
RIP: 0010:debug_print_object+0x1a2/0x2b0 lib/debugobjects.c:612
Code: fc ff df 48 89 fa 48 c1 ea 03 80 3c 02 00 75 54 48 8b 14 dd e0 81 b1 8b 41 56 4c 89 e6 48 c7 c7 60 76 b1 8b e8 5f 4d bc fc 90 <0f> 0b 90 90 58 83 05 c6 4f 7f 0b 01 48 83 c4 18 5b 5d 41 5c 41 5d
RSP: 0000:ffffc900045ef7c8 EFLAGS: 00010286
RAX: 0000000000000000 RBX: 0000000000000005 RCX: ffffffff815a1789
RDX: ffff88807ea2da00 RSI: ffffffff815a1796 RDI: 0000000000000001
RBP: 0000000000000001 R08: 0000000000000001 R09: 0000000000000000
R10: 0000000000000001 R11: 0000000000000001 R12: ffffffff8bb17d40
R13: ffffffff8b4f81a0 R14: ffffffff8a928850 R15: ffffc900045ef888
FS:  0000000000000000(0000) GS:ffff8880b8600000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f19769f4d58 CR3: 0000000032a52000 CR4: 00000000003526f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
 <TASK>
 debug_object_assert_init+0x1ee/0x2f0 lib/debugobjects.c:1020
 debug_timer_assert_init kernel/time/timer.c:845 [inline]
 debug_assert_init kernel/time/timer.c:890 [inline]
 __mod_timer+0xae/0xdc0 kernel/time/timer.c:1071
 ieee80211_sta_merge_ibss net/mac80211/ibss.c:1272 [inline]
 ieee80211_ibss_work+0x481/0x14c0 net/mac80211/ibss.c:1672
 ieee80211_iface_work+0xd01/0xf00 net/mac80211/iface.c:1689
 cfg80211_wiphy_work+0x3de/0x560 net/wireless/core.c:440
 process_one_work+0x958/0x1b30 kernel/workqueue.c:3229
 process_scheduled_works kernel/workqueue.c:3310 [inline]
 worker_thread+0x6c8/0xf00 kernel/workqueue.c:3391
 kthread+0x2c1/0x3a0 kernel/kthread.c:389
 ret_from_fork+0x45/0x80 arch/x86/kernel/process.c:147
 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
 </TASK>


---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.

syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.

If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title

If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)

If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report

If you want to undo deduplication, reply with:
#syz undup

^ permalink raw reply

* Inquiry Mesh Point Mode Support for mt7921au USB
From: Jingwei LI @ 2025-01-06  9:06 UTC (permalink / raw)
  To: linux-wireless@vger.kernel.org

Dear Developers,

I'm working with MT7921au USB and found it doesn't support mesh point, while mt76 driver entry is marked "yes" in linux-wireless driver capability table.
Could you kindly clarify if it is due to hardware restrictions, a firmware limitation, or a driver issue? Besides, if it could potentially be addressed through driver development?

Thank you in advance for your time and any insights.

Best regards,
Jingwei

^ permalink raw reply

* Re: [PATCH] net: ethernet: toshiba: ps3_gelic_wireless: Remove driver using deprecated API wext
From: Johannes Berg @ 2025-01-06  8:06 UTC (permalink / raw)
  To: Arnd Bergmann, Philipp Hortmann, Andrew Lunn, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Geoff Levand,
	Simon Horman, Alexander Lobakin, Netdev, linux-kernel
  Cc: Kalle Valo, Alexandre Belloni, Claudiu Beznea, Geert Uytterhoeven,
	Greg Kroah-Hartman, Jeff Johnson, Larry Finger, Nicolas Ferre,
	Pavel Machek, Stanislaw Gruszka, Gregory Greenman, linuxppc-dev,
	linux-staging, linux-wireless, Stefan Lippers-Hollmann
In-Reply-To: <cecd584c-46c0-4c0b-b3fb-b5cee4bbfd12@app.fastmail.com>

On Sat, 2025-01-04 at 05:15 +0100, Arnd Bergmann wrote:
> 
> I would assume that once removing CFG80211_WEXT becomes an option, we
> can just put the remaining parts of net/wireless/wext-*.c into both
> ps3_gelic and ipw2x00, duplicating and then simplifying the
> implementation. As far as I can tell, there is very little that is
> actually shared between the two anyway.

Indeed.

Note that net/wireless/wext-{core,proc,priv}.c are not even related to
CFG80211_WEXT (wext-{compat,sme}.c are), and just form the core wext
code that can be treated completely orthogonal and independent of
cfg80211. This driver doesn't even use CFG80211_WEXT code at all.

johannes

^ permalink raw reply

* Re: [PATCH 1/2] rt2x00: Remove unusued value
From: Ariel Otilibili-Anieli @ 2025-01-06  7:23 UTC (permalink / raw)
  To: Daniel Golle
  Cc: Shiji Yang, Stanislaw Gruszka, linux-wireless, netdev, Kalle Valo,
	Tomislav Požega, Linux-kernel
In-Reply-To: <Z3r3vxy8cRRH6w1m@pidgin.makrotopia.org>

Hi Daniel, hi Shiji, hi Stanislaw,

On Sunday, January 05, 2025 22:21 CET, Daniel Golle <daniel@makrotopia.org> wrote:

> H again,
> 
> 
> On Sat, Jan 04, 2025 at 01:51:25PM +0100, Ariel Otilibili-Anieli wrote:
> > Great, then; thanks for having acked the patch as such.
> 
> I just noticed that Shiji Yang had posted a series of patches for
> OpenWrt which also addresses the same issue, however, instead of
> removing the augmented assignment, it fixes it to the supposedly
> originally intended way.
> 
> See
> https://git.openwrt.org/?p=openwrt/openwrt.git;a=blob;f=package/kernel/mac80211/patches/rt2x00/621-04-rt2x00-fix-register-operation-on-RXIQ-calibration.patch;h=aa6f9c437c6447831490588b2cead6919accda58;hb=5d583901657bdfbbf9fad77d9247872427aa5c99
> 
> I suppose this was tested together with the other changes of the same
> series, so we may want to pick that instead.

Thanks for having put some time into the research, Daniel; I looked into the openwrt archives for 2024, none of Shiji’s messages mentions that patch.

Though, if you three agree, I will push a new series, modelled on that patch, and you as Suggested-by.

Have a good week,
Ariel
> 
> 
> Cheers
> 
> 
> Daniel
>


^ permalink raw reply

* Re: [PATCH v2] wifi: ath9k: Obtain system GPIOS from descriptors
From: Michał Kępień @ 2025-01-06  6:38 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Kalle Valo, Andy Shevchenko, Arnd Bergmann, Alban Bedel,
	Bartosz Golaszewski, Toke Høiland-Jørgensen,
	linux-wireless, brcm80211-dev-list.pdl, linux-gpio
In-Reply-To: <20240423-descriptors-wireless-v2-1-6d1d03b30bfa@linaro.org>

Hi Linus,

> The ath9k has an odd use of system-wide GPIOs: if the chip
> does not have internal GPIO capability, it will try to obtain a
> GPIO line from the system GPIO controller:
> 
>   if (BIT(gpio) & ah->caps.gpio_mask)
>         ath9k_hw_gpio_cfg_wmac(...);
>   else if (AR_SREV_SOC(ah))
>         ath9k_hw_gpio_cfg_soc(ah, gpio, out, label);
> 
> Where ath9k_hw_gpio_cfg_soc() will attempt to issue
> gpio_request_one() passing the local GPIO number of the controller
> (0..31) to gpio_request_one().
> 
> This is somewhat peculiar and possibly even dangerous: there is
> nowadays no guarantee of the numbering of these system-wide
> GPIOs, and assuming that GPIO 0..31 as used by ath9k would
> correspond to GPIOs 0..31 on the system as a whole seems a bit
> wild.
> 
> Register all 32 GPIOs at index 0..31 directly in the ATH79K
> GPIO driver and associate with WIFI if and only if we are probing
> ATH79K wifi from the AHB bus (used for SoCs).

I don't know how likely it is today that this patch will get merged, but
it turned out to be useful for fixing an OpenWRT issue [1][2].  However,
the patch required some tweaking in order to make it work, so I assumed
it cannot hurt to provide some feedback on it.

> 
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> Changes in v2:
> - Define all the descriptors directly in the ATH79K
>   GPIO driver in case the driver want to request them directly.
> - Link to v1: https://lore.kernel.org/r/20240131-descriptors-wireless-v1-0-e1c7c5d68746@linaro.org
> ---
>  drivers/gpio/gpio-ath79.c           | 47 ++++++++++++++++++++++++++++++++++++-
>  drivers/net/wireless/ath/ath9k/hw.c | 29 ++++++++++++-----------
>  drivers/net/wireless/ath/ath9k/hw.h |  3 ++-
>  3 files changed, 63 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpio/gpio-ath79.c b/drivers/gpio/gpio-ath79.c
> index f0c0c0f77eb0..f83ce0595ea8 100644
> --- a/drivers/gpio/gpio-ath79.c
> +++ b/drivers/gpio/gpio-ath79.c
> @@ -9,6 +9,7 @@
>   */
>  
>  #include <linux/gpio/driver.h>
> +#include <linux/gpio/machine.h> /* For WLAN GPIOs */
>  #include <linux/platform_device.h>
>  #include <linux/platform_data/gpio-ath79.h>
>  #include <linux/of.h>
> @@ -222,6 +223,46 @@ static const struct of_device_id ath79_gpio_of_match[] = {
>  };
>  MODULE_DEVICE_TABLE(of, ath79_gpio_of_match);
>  
> +#if IS_ENABLED(CONFIG_ATH9K_AHB)
> +/*
> + * This registers all of the ath79k GPIOs as descriptors to be picked
> + * directly from the ATH79K wifi driver if the two are jitted together
> + * in the same SoC.
> + */
> +#define ATH79K_WIFI_DESCS 32
> +static int ath79_gpio_register_wifi_descriptors(struct device *dev,
> +						const char *label)
> +{
> +	struct gpiod_lookup_table *lookup;
> +	int i;
> +
> +	/* Create a gpiod lookup using gpiochip-local offsets + 1 for NULL */
> +        lookup = devm_kzalloc(dev,
> +			      struct_size(lookup, table, ATH79K_WIFI_DESCS + 1),
> +			      GFP_KERNEL);
> +
> +	if (!lookup)
> +		return -ENOMEM;
> +
> +	lookup->dev_id = "ath9k";

Since the devm_gpiod_get_index() call in ath9k_hw_gpio_cfg_soc() passes
ah->dev as the first argument, "ath9k" is not the string that
gpiod_find_lookup_table() will use for matching the lookup table;
instead, it will be the wireless device's name, e.g. "18100000.wmac" on
my router (which is built on Atheros 9344).  This causes
devm_gpiod_get_index() to return -ENOENT [3].

> +
> +	for (i = 0; i < ATH79K_WIFI_DESCS; i++) {
> +		lookup->table[i] = (struct gpiod_lookup)
> +			GPIO_LOOKUP_IDX(label, 0, NULL, i,

This sets the chip_hwnum member of every registered lookup table entry
to 0 (second GPIO_LOOKUP_IDX() argument), which causes all 32 GPIOs
registered here to be erroneously mapped to the GPIO chip's first line.
I believe the second argument for GPIO_LOOKUP_IDX() should also be 'i'
here - or at least that is what made the patch work for me (after fixing
the lookup table matching issue).

> +					GPIO_ACTIVE_HIGH);
> +	}
> +
> +	gpiod_add_lookup_table(lookup);
> +
> +	return 0;
> +}
> +#else
> +static int ath79_gpio_register_wifi_descriptors(struct device *dev,
> +						const char *label)
> +{
> +}
> +#endif
> +
>  static int ath79_gpio_probe(struct platform_device *pdev)
>  {
>  	struct ath79_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
> @@ -291,7 +332,11 @@ static int ath79_gpio_probe(struct platform_device *pdev)
>  		girq->handler = handle_simple_irq;
>  	}
>  
> -	return devm_gpiochip_add_data(dev, &ctrl->gc, ctrl);
> +	err = devm_gpiochip_add_data(dev, &ctrl->gc, ctrl);
> +	if (err)
> +		return err;
> +
> +	return ath79_gpio_register_wifi_descriptors(dev, ctrl->gc.label);
>  }
>  
>  static struct platform_driver ath79_gpio_driver = {
> diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
> index 5982e0db45f9..ee6705836746 100644
> --- a/drivers/net/wireless/ath/ath9k/hw.c
> +++ b/drivers/net/wireless/ath/ath9k/hw.c
> @@ -20,7 +20,7 @@
>  #include <linux/time.h>
>  #include <linux/bitops.h>
>  #include <linux/etherdevice.h>
> -#include <linux/gpio.h>
> +#include <linux/gpio/consumer.h>
>  #include <asm/unaligned.h>
>  
>  #include "hw.h"
> @@ -2727,19 +2727,25 @@ static void ath9k_hw_gpio_cfg_output_mux(struct ath_hw *ah, u32 gpio, u32 type)
>  static void ath9k_hw_gpio_cfg_soc(struct ath_hw *ah, u32 gpio, bool out,
>  				  const char *label)
>  {
> +	enum gpiod_flags flags = out ? GPIOD_OUT_LOW : GPIOD_IN;
> +	struct gpio_desc *gpiod;
>  	int err;
>  
> -	if (ah->caps.gpio_requested & BIT(gpio))
> +	if (ah->gpiods[gpio])
>  		return;
>  
> -	err = gpio_request_one(gpio, out ? GPIOF_OUT_INIT_LOW : GPIOF_IN, label);
> -	if (err) {
> +	/* Obtains a system specific GPIO descriptor from another GPIO controller */
> +	gpiod = devm_gpiod_get_index(ah->dev, NULL, gpio, flags);

Since using the resource-managed version of gpiod_get_index() requires
providing a valid pointer to a struct device as the first argument and
the name of that device is not going to be "ath9k", some other means of
matching this call with the lookup table registered in
ath79_gpio_register_wifi_descriptors() needs to be devised.

I resorted to the NULL-matching fallback in gpiod_find_lookup_table(),
which enables a lookup table with dev_id set to NULL to be matched for a
gpiod_get_index() call with dev also set to NULL, coupled with setting
con_id in all the lookup table entries and in the gpiod_get_index() call
to a matching string, e.g.:

	// in ath79_gpio_register_wifi_descriptors()

	for (i = 0; i < ATH79K_WIFI_DESCS; i++) {
		lookup->table[i] = (struct gpiod_lookup)
			GPIO_LOOKUP_IDX(label, i, "ath9k", i,
					GPIO_ACTIVE_HIGH);

	// in ath9k_hw_gpio_cfg_soc()

	gpiod = gpiod_get_index(NULL, "ath9k", gpio, flags);

This requires manually releasing the GPIO descriptor when the wireless
driver is done with it (because we're losing the benefits of using
resource-managed functions), so...

> +
> +	if (IS_ERR(gpiod)) {
> +		err = PTR_ERR(gpiod);
>  		ath_err(ath9k_hw_common(ah), "request GPIO%d failed:%d\n",
>  			gpio, err);
>  		return;
>  	}
>  
> -	ah->caps.gpio_requested |= BIT(gpio);
> +	gpiod_set_consumer_name(gpiod, label);
> +	ah->gpiods[gpio] = gpiod;
>  }
>  
>  static void ath9k_hw_gpio_cfg_wmac(struct ath_hw *ah, u32 gpio, bool out,
> @@ -2800,11 +2806,6 @@ void ath9k_hw_gpio_free(struct ath_hw *ah, u32 gpio)
>  		return;
>  
>  	WARN_ON(gpio >= ah->caps.num_gpio_pins);
> -
> -	if (ah->caps.gpio_requested & BIT(gpio)) {
> -		gpio_free(gpio);
> -		ah->caps.gpio_requested &= ~BIT(gpio);
> -	}

...ath9k_hw_gpio_free() would still need a bit like this:

	if (ah->gpiods[gpio]) {
		gpiod_put(ah->gpiods[gpio]);
		ah->gpiods[gpio] = NULL;
	}

I don't know if such an approach is appropriate, but it did at least
make the patch work for me.

Hope this helps,

[1] https://github.com/openwrt/openwrt/pull/17402#issuecomment-2566157016
[2] https://github.com/openwrt/openwrt/pull/17402#issuecomment-2566763575
[3] https://github.com/openwrt/openwrt/pull/17445#issuecomment-2569439459

-- 
Best regards,
Michał Kępień

^ permalink raw reply

* Re: [PATCH v2] wifi: wlcore: fix unbalanced pm_runtime calls
From: Nemanov, Michael @ 2025-01-06  6:22 UTC (permalink / raw)
  To: akemnade, kvalo, rmk+kernel, johannes.berg,
	miriam.rachel.korenblit, leitao, andreas, emmanuel.grumbach, tony,
	linux-wireless, linux-kernel
In-Reply-To: <20250104195507.402673-1-akemnade@kernel.org>

On 1/4/2025 9:55 PM, akemnade@kernel.org wrote:
> From: Andreas Kemnade <andreas@kemnade.info>
> 
> If firmware boot failes, runtime pm is put too often:
> [12092.708099] wlcore: ERROR firmware boot failed despite 3 retries
> [12092.708099] wl18xx_driver wl18xx.1.auto: Runtime PM usage count underflow!
> Fix that by redirecting all error gotos before runtime_get so that runtime is
> not put.
> 
> Fixes: c40aad28a3cf ("wlcore: Make sure firmware is initialized in wl1271_op_add_interface()")
> Signed-off-by: Andreas Kemnade <andreas@kemnade.info>

Reviewed-by: Michael Nemanov <michael.nemanov@ti.com>

Best regards,
Michael.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox