diff mbox series

[29/38] ra6w: add stats.c

Message ID 20250417135236.52410-30-oleksandr.savchenko.dn@bp.renesas.com
State New
Headers show
Series wireless: ra6w driver for Renesas IEEE 802.11ax devices | expand

Commit Message

Alexander Savchenko April 17, 2025, 1:52 p.m. UTC
Part of the split. Please, take a look at the cover letter for more details

Reviewed-by: Viktor Barna <viktor.barna.rj@bp.renesas.com>
Reviewed-by: Gal Gur <gal.gur.jx@renesas.com>
Signed-off-by: Alexander Savchenko <oleksandr.savchenko.dn@bp.renesas.com>
---
 drivers/net/wireless/renesas/ra6w/stats.c | 94 +++++++++++++++++++++++
 1 file changed, 94 insertions(+)
 create mode 100644 drivers/net/wireless/renesas/ra6w/stats.c
diff mbox series

Patch

diff --git a/drivers/net/wireless/renesas/ra6w/stats.c b/drivers/net/wireless/renesas/ra6w/stats.c
new file mode 100644
index 000000000000..59f431b3f158
--- /dev/null
+++ b/drivers/net/wireless/renesas/ra6w/stats.c
@@ -0,0 +1,94 @@ 
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * This file contains statistics routine.
+ *
+ * Copyright (C) [2022-2025] Renesas Electronics Corporation and/or its affiliates.
+ */
+
+#include "cfg80211.h"
+#include "stats.h"
+
+void ra6w_stats_rx_update(struct ra6w_stats *stats,
+			  const struct ra6w_cfg80211_sta_stats *sta_stats)
+{
+	struct ra6w_stats_rx *rx_stats = stats->rx_stats;
+	const struct ra6w_rx_ext_hdr *last_rx = &sta_stats->last_rx_data_ext;
+
+	if (!stats->stats_enabled || !rx_stats)
+		return;
+
+	rx_stats->format_mode = last_rx->format_mod;
+
+	switch (last_rx->format_mod) {
+	case RA6W_CFG80211_FORMATMOD_NON_HT:
+		rx_stats->flags |= RA6W_STATS_RX_OFDM_BIT;
+		rx_stats->non_ht.ofdm++;
+		fallthrough;
+	case RA6W_CFG80211_FORMATMOD_NON_HT_DUP_OFDM:
+		rx_stats->flags |= RA6W_STATS_RX_CCK_BIT;
+		rx_stats->non_ht.cck++;
+		rx_stats->non_ht.bw = last_rx->ch_bw;
+		break;
+	case RA6W_CFG80211_FORMATMOD_HT_MF:
+	case RA6W_CFG80211_FORMATMOD_HT_GF:
+		rx_stats->flags |= RA6W_STATS_RX_HT_BIT;
+		rx_stats->ht.bw = last_rx->ch_bw & 0x1;
+		rx_stats->ht.nss = last_rx->ht.num_extn_ss & 0x3;
+		rx_stats->ht.mcs = last_rx->ht.mcs & 0x7;
+		rx_stats->ht.gi = last_rx->ht.short_gi & 0x1;
+		rx_stats->ht.ht[rx_stats->ht.gi][rx_stats->ht.mcs]++;
+		break;
+	case RA6W_CFG80211_FORMATMOD_VHT:
+		rx_stats->flags |= RA6W_STATS_RX_VHT_BIT;
+		rx_stats->vht.bw = last_rx->ch_bw;
+		rx_stats->vht.nss = last_rx->vht.nss;
+		rx_stats->vht.mcs = last_rx->vht.mcs;
+		rx_stats->vht.gi = last_rx->vht.short_gi & 0x1;
+		rx_stats->vht.vht[rx_stats->vht.gi][rx_stats->vht.mcs]++;
+		break;
+	case RA6W_CFG80211_FORMATMOD_HE_MU:
+	case RA6W_CFG80211_FORMATMOD_HE_SU:
+	case RA6W_CFG80211_FORMATMOD_HE_ER:
+	case RA6W_CFG80211_FORMATMOD_HE_TB:
+		rx_stats->flags |= RA6W_STATS_RX_HE_SU_BIT;
+		rx_stats->he_su.mcs = last_rx->he.mcs;
+		rx_stats->he_su.nss = last_rx->he.nss;
+		rx_stats->he_su.gi = last_rx->he.gi_type;
+		rx_stats->he_su.he[rx_stats->he_su.gi][rx_stats->he_su.mcs]++;
+		break;
+	default:
+		break;
+	}
+}
+
+int ra6w_stats_init(struct ra6w_stats *stats)
+{
+	struct ra6w_stats_rx *rx_stats = NULL;
+
+	if (stats->stats_enabled)
+		return 0;
+
+	rx_stats = kzalloc(sizeof(*rx_stats), GFP_KERNEL);
+	if (!rx_stats)
+		return -ENOMEM;
+
+	stats->rx_stats = rx_stats;
+	stats->stats_enabled = true;
+
+	return 0;
+}
+
+void ra6w_stats_deinit(struct ra6w_stats *stats)
+{
+	struct ra6w_cfg80211_vif *vif =  container_of(stats, struct ra6w_cfg80211_vif, stats);
+	struct ra6w_cfg80211_priv *priv = vif->priv;
+
+	if (!stats->stats_enabled)
+		return;
+
+	ra6w_ctrl_stats_tx_start_req(&priv->core->ctrl, RA6W_STATS_TX_STOP_BIT);
+
+	stats->stats_enabled = false;
+	kfree(stats->rx_stats);
+	stats->rx_stats = NULL;
+}