2024-04-29 11:50:17

by Karthikeyan Kathirvel

[permalink] [raw]
Subject: [PATCH v3 0/2] wifi: ath12k: drop failed transmitted frames from metric calculation

- Use ieee80211_free_txskb() instead of dev_kfree_skb_any().
- Drop failed transmitted frames from mesh metric calculation to avoid
false link metric averaging.

Karthikeyan Kathirvel (1):
wifi: ath12k: drop failed transmitted frames from metric calculation.

Sven Eckelmann (1):
wifi: ath12k: Don't drop tx_status in failure case

drivers/net/wireless/ath/ath12k/dp_tx.c | 43 ++++++++++++++++------
drivers/net/wireless/ath/ath12k/hal_desc.h | 22 ++++++++++-
2 files changed, 52 insertions(+), 13 deletions(-)


base-commit: 363e7193eaf258fe7f04e8db560bd8a282a12cd9
--
2.34.1



2024-04-29 11:50:22

by Karthikeyan Kathirvel

[permalink] [raw]
Subject: [PATCH v3 2/2] wifi: ath12k: drop failed transmitted frames from metric calculation.

In mesh node traffic, internal firmware-transmitted failures are
reported as transmitted failures in mesh metric calculation, leading
to the breakage of the mesh link.

Fix the issue by dropping the internal firmware-transmitted failures
before updating the TX completion status to mac80211, in order to
prevent false failure averaging in mesh metric calculation.

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

Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
Signed-off-by: Karthikeyan Kathirvel <[email protected]>
---
drivers/net/wireless/ath/ath12k/dp_tx.c | 38 ++++++++++++++++------
drivers/net/wireless/ath/ath12k/hal_desc.h | 22 ++++++++++++-
2 files changed, 49 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c
index 6a387f1f9567..72aab7ffcd5b 100644
--- a/drivers/net/wireless/ath/ath12k/dp_tx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_tx.c
@@ -482,18 +482,36 @@ static void ath12k_dp_tx_complete_msdu(struct ath12k *ar,
/* skip tx rate update from ieee80211_status*/
info->status.rates[0].idx = -1;

- if (ts->status == HAL_WBM_TQM_REL_REASON_FRAME_ACKED &&
- !(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
- info->flags |= IEEE80211_TX_STAT_ACK;
- info->status.ack_signal = ATH12K_DEFAULT_NOISE_FLOOR +
- ts->ack_rssi;
- info->status.flags = IEEE80211_TX_STATUS_ACK_SIGNAL_VALID;
+ switch (ts->status) {
+ case HAL_WBM_TQM_REL_REASON_FRAME_ACKED:
+ if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
+ info->flags |= IEEE80211_TX_STAT_ACK;
+ info->status.ack_signal = ATH12K_DEFAULT_NOISE_FLOOR +
+ ts->ack_rssi;
+ info->status.flags = IEEE80211_TX_STATUS_ACK_SIGNAL_VALID;
+ }
+ break;
+ case HAL_WBM_TQM_REL_REASON_CMD_REMOVE_TX:
+ if (info->flags & IEEE80211_TX_CTL_NO_ACK) {
+ info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
+ break;
+ }
+ fallthrough;
+ case HAL_WBM_TQM_REL_REASON_CMD_REMOVE_MPDU:
+ case HAL_WBM_TQM_REL_REASON_DROP_THRESHOLD:
+ case HAL_WBM_TQM_REL_REASON_CMD_REMOVE_AGED_FRAMES:
+ /* The failure status is due to internal firmware tx failure
+ * hence drop the frame; do not update the status of frame to
+ * the upper layer
+ */
+ ieee80211_free_txskb(ah->hw, msdu);
+ goto exit;
+ default:
+ ath12k_dbg(ab, ATH12K_DBG_DP_TX, "tx frame is not acked status %d\n",
+ ts->status);
+ break;
}

- if (ts->status == HAL_WBM_TQM_REL_REASON_CMD_REMOVE_TX &&
- (info->flags & IEEE80211_TX_CTL_NO_ACK))
- info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
-
/* NOTE: Tx rate status reporting. Tx completion status does not have
* necessary information (for example nss) to build the tx rate.
* Might end up reporting it out-of-band from HTT stats.
diff --git a/drivers/net/wireless/ath/ath12k/hal_desc.h b/drivers/net/wireless/ath/ath12k/hal_desc.h
index 63340256d3f6..71e8c8a091ae 100644
--- a/drivers/net/wireless/ath/ath12k/hal_desc.h
+++ b/drivers/net/wireless/ath/ath12k/hal_desc.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-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "core.h"

@@ -2048,6 +2048,19 @@ struct hal_wbm_release_ring {
* fw with fw_reason2.
* @HAL_WBM_TQM_REL_REASON_CMD_REMOVE_RESEAON3: Remove command initiated by
* fw with fw_reason3.
+ * @HAL_WBM_TQM_REL_REASON_CMD_DISABLE_QUEUE: Remove command initiated by
+ * fw with disable queue.
+ * @HAL_WBM_TQM_REL_REASON_CMD_TILL_NONMATCHING: Remove command initiated by
+ * fw to remove all mpdu until 1st non-match.
+ * @HAL_WBM_TQM_REL_REASON_DROP_THRESHOLD: Dropped due to drop threshold
+ * criteria
+ * @HAL_WBM_TQM_REL_REASON_DROP_LINK_DESC_UNAVAIL: Dropped due to link desc
+ * not available
+ * @HAL_WBM_TQM_REL_REASON_DROP_OR_INVALID_MSDU: Dropped due drop bit set or
+ * null flow
+ * @HAL_WBM_TQM_REL_REASON_MULTICAST_DROP: Dropped due mcast drop set for VDEV
+ * @HAL_WBM_TQM_REL_REASON_VDEV_MISMATCH_DROP: Dropped due to being set with
+ * 'TCL_drop_reason'
*/
enum hal_wbm_tqm_rel_reason {
HAL_WBM_TQM_REL_REASON_FRAME_ACKED,
@@ -2058,6 +2071,13 @@ enum hal_wbm_tqm_rel_reason {
HAL_WBM_TQM_REL_REASON_CMD_REMOVE_RESEAON1,
HAL_WBM_TQM_REL_REASON_CMD_REMOVE_RESEAON2,
HAL_WBM_TQM_REL_REASON_CMD_REMOVE_RESEAON3,
+ HAL_WBM_TQM_REL_REASON_CMD_DISABLE_QUEUE,
+ HAL_WBM_TQM_REL_REASON_CMD_TILL_NONMATCHING,
+ HAL_WBM_TQM_REL_REASON_DROP_THRESHOLD,
+ HAL_WBM_TQM_REL_REASON_DROP_LINK_DESC_UNAVAIL,
+ HAL_WBM_TQM_REL_REASON_DROP_OR_INVALID_MSDU,
+ HAL_WBM_TQM_REL_REASON_MULTICAST_DROP,
+ HAL_WBM_TQM_REL_REASON_VDEV_MISMATCH_DROP,
};

struct hal_wbm_buffer_ring {
--
2.34.1


2024-04-29 11:50:44

by Karthikeyan Kathirvel

[permalink] [raw]
Subject: [PATCH v3 1/2] wifi: ath12k: Don't drop tx_status when peer cannot be found

From: Sven Eckelmann <[email protected]>

When a station idles for a long time, hostapd will try to send a QoS Null
frame to the station as "poll". NL80211_CMD_PROBE_CLIENT is used for this
purpose. And the skb will be added to ack_status_frame - waiting for a
completion via ieee80211_report_ack_skb().

But when the peer was already removed before the tx_complete arrives, the
peer will be missing. And when using dev_kfree_skb_any (instead of going
through mac80211), the entry will stay inside ack_status_frames. This IDR
will therefore run full after 8K request were generated for such clients.
At this point, the access point will then just stall and not allow any new
clients because idr_alloc() for ack_status_frame will fail.

ieee80211_free_txskb() on the other hand will (when required) call
ieee80211_report_ack_skb() and make sure that (when required) remove the
entry from the ack_status_frame.

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

Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
Signed-off-by: Sven Eckelmann <[email protected]>
Signed-off-by: Sarika Sharma <[email protected]>
Signed-off-by: Karthikeyan Kathirvel <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
---
drivers/net/wireless/ath/ath12k/dp_tx.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c
index 9b6d7d72f57c..6a387f1f9567 100644
--- a/drivers/net/wireless/ath/ath12k/dp_tx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_tx.c
@@ -448,6 +448,7 @@ static void ath12k_dp_tx_complete_msdu(struct ath12k *ar,
struct hal_tx_status *ts)
{
struct ath12k_base *ab = ar->ab;
+ struct ath12k_hw *ah = ar->ah;
struct ieee80211_tx_info *info;
struct ath12k_skb_cb *skb_cb;

@@ -466,12 +467,12 @@ static void ath12k_dp_tx_complete_msdu(struct ath12k *ar,
rcu_read_lock();

if (!rcu_dereference(ab->pdevs_active[ar->pdev_idx])) {
- dev_kfree_skb_any(msdu);
+ ieee80211_free_txskb(ah->hw, msdu);
goto exit;
}

if (!skb_cb->vif) {
- dev_kfree_skb_any(msdu);
+ ieee80211_free_txskb(ah->hw, msdu);
goto exit;
}

--
2.34.1


2024-04-29 11:50:44

by Karthikeyan Kathirvel

[permalink] [raw]
Subject: [PATCH v3 1/2] wifi: ath12k: Don't drop tx_status in failure case

From: Sven Eckelmann <[email protected]>

When a station idles for a long time, hostapd will try to send
a QoS Null frame to the station as "poll". NL80211_CMD_PROBE_CLIENT
is used for this purpose.
And the skb will be added to ack_status_frame - waiting for a
completion via ieee80211_report_ack_skb().

But when the peer was already removed before the tx_complete arrives,
the peer will be missing. And when using dev_kfree_skb_any (instead
of going through mac80211), the entry will stay inside
ack_status_frames thus not clean up related information in its
internal data structures. This IDR will therefore run full after
8K request were generated for such clients.
At this point, the access point will then just stall and not allow
any new clients because idr_alloc() for ack_status_frame will fail.

ieee80211_free_txskb() on the other hand will (when required) call
ieee80211_report_ack_skb() and make sure that (when required) remove
the entry from the ack_status_frame and clean up related
information in its internal data structures.

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

Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
Signed-off-by: Sven Eckelmann <[email protected]>
Signed-off-by: Sarika Sharma <[email protected]>
Signed-off-by: Karthikeyan Kathirvel <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
---
drivers/net/wireless/ath/ath12k/dp_tx.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c
index 9b6d7d72f57c..6a387f1f9567 100644
--- a/drivers/net/wireless/ath/ath12k/dp_tx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_tx.c
@@ -448,6 +448,7 @@ static void ath12k_dp_tx_complete_msdu(struct ath12k *ar,
struct hal_tx_status *ts)
{
struct ath12k_base *ab = ar->ab;
+ struct ath12k_hw *ah = ar->ah;
struct ieee80211_tx_info *info;
struct ath12k_skb_cb *skb_cb;

@@ -466,12 +467,12 @@ static void ath12k_dp_tx_complete_msdu(struct ath12k *ar,
rcu_read_lock();

if (!rcu_dereference(ab->pdevs_active[ar->pdev_idx])) {
- dev_kfree_skb_any(msdu);
+ ieee80211_free_txskb(ah->hw, msdu);
goto exit;
}

if (!skb_cb->vif) {
- dev_kfree_skb_any(msdu);
+ ieee80211_free_txskb(ah->hw, msdu);
goto exit;
}

--
2.34.1


2024-04-29 12:11:55

by Sven Eckelmann

[permalink] [raw]
Subject: Re: [PATCH v3 1/2] wifi: ath12k: Don't drop tx_status in failure case

On Monday, 29 April 2024 13:48:39 CEST Karthikeyan Kathirvel wrote:
> From: Sven Eckelmann <[email protected]>
>
> When a station idles for a long time, hostapd will try to send
> a QoS Null frame to the station as "poll". NL80211_CMD_PROBE_CLIENT
> is used for this purpose.
> And the skb will be added to ack_status_frame - waiting for a
> completion via ieee80211_report_ack_skb().
>
> But when the peer was already removed before the tx_complete arrives,
> the peer will be missing. And when using dev_kfree_skb_any (instead
> of going through mac80211), the entry will stay inside
> ack_status_frames thus not clean up related information in its
> internal data structures. This IDR will therefore run full after
> 8K request were generated for such clients.
> At this point, the access point will then just stall and not allow
> any new clients because idr_alloc() for ack_status_frame will fail.
>
> ieee80211_free_txskb() on the other hand will (when required) call
> ieee80211_report_ack_skb() and make sure that (when required) remove
> the entry from the ack_status_frame and clean up related
> information in its internal data structures.
>
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1

Thanks for porting and testing both patches on ath12k.

Kind regards,
Sven


Attachments:
signature.asc (849.00 B)
This is a digitally signed message part.

2024-04-29 18:51:40

by Jeff Johnson

[permalink] [raw]
Subject: Re: [PATCH v3 0/2] wifi: ath12k: drop failed transmitted frames from metric calculation

On 4/29/2024 4:48 AM, Karthikeyan Kathirvel wrote:
> - Use ieee80211_free_txskb() instead of dev_kfree_skb_any().
> - Drop failed transmitted frames from mesh metric calculation to avoid
> false link metric averaging.
>
> Karthikeyan Kathirvel (1):
> wifi: ath12k: drop failed transmitted frames from metric calculation.
>
> Sven Eckelmann (1):
> wifi: ath12k: Don't drop tx_status in failure case
>
> drivers/net/wireless/ath/ath12k/dp_tx.c | 43 ++++++++++++++++------
> drivers/net/wireless/ath/ath12k/hal_desc.h | 22 ++++++++++-
> 2 files changed, 52 insertions(+), 13 deletions(-)
>
>
> base-commit: 363e7193eaf258fe7f04e8db560bd8a282a12cd9

'b4' is barfing on this series since you posted 3 patches instead of 2:
[PATCH v3 1/2] wifi: ath12k: Don't drop tx_status in failure case
[PATCH v3 1/2] wifi: ath12k: Don't drop tx_status when peer cannot be found
[PATCH v3 2/2] wifi: ath12k: drop failed transmitted frames from metric calculation.

Why are there two different 1/2 patches?

2024-04-30 07:42:44

by Karthikeyan Kathirvel

[permalink] [raw]
Subject: Re: [PATCH v3 0/2] wifi: ath12k: drop failed transmitted frames from metric calculation



On 4/30/2024 12:16 AM, Jeff Johnson wrote:
> On 4/29/2024 4:48 AM, Karthikeyan Kathirvel wrote:
>> - Use ieee80211_free_txskb() instead of dev_kfree_skb_any().
>> - Drop failed transmitted frames from mesh metric calculation to avoid
>> false link metric averaging.
>>
>> Karthikeyan Kathirvel (1):
>> wifi: ath12k: drop failed transmitted frames from metric calculation.
>>
>> Sven Eckelmann (1):
>> wifi: ath12k: Don't drop tx_status in failure case
>>
>> drivers/net/wireless/ath/ath12k/dp_tx.c | 43 ++++++++++++++++------
>> drivers/net/wireless/ath/ath12k/hal_desc.h | 22 ++++++++++-
>> 2 files changed, 52 insertions(+), 13 deletions(-)
>>
>>
>> base-commit: 363e7193eaf258fe7f04e8db560bd8a282a12cd9
>
> 'b4' is barfing on this series since you posted 3 patches instead of 2:
> [PATCH v3 1/2] wifi: ath12k: Don't drop tx_status in failure case
> [PATCH v3 1/2] wifi: ath12k: Don't drop tx_status when peer cannot be found
> [PATCH v3 2/2] wifi: ath12k: drop failed transmitted frames from metric calculation.
>
> Why are there two different 1/2 patches?
Uploaded an invalid patch by mistake, have removed it in next version v4
and also replaced a dev_kfree_skb_any() by ieee80211_free_txskb() in
ath12k_dp_tx_free_txbuf(),