The branch main has been updated by bz:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=32ea8209825af594cbfa1fc654d45eb9a6aab528

commit 32ea8209825af594cbfa1fc654d45eb9a6aab528
Author:     Bjoern A. Zeeb <[email protected]>
AuthorDate: 2025-12-28 17:03:41 +0000
Commit:     Bjoern A. Zeeb <[email protected]>
CommitDate: 2025-12-29 02:48:14 +0000

    LinuxKPI: 802.11: add compat.linuxkpi.80211.IF.dump_stas_queues
    
    Extend the normal compat.linuxkpi.80211.IF.dump_stas sysctl by
    queue information.  This was helpful for debugging various issues,
    like selecting the outbound queue, stopping queues for BAR and helped
    finding multiple bugs.
    
    Sponsored by:   The FreeBSD Foundation
    MFC after:      3 days
---
 share/man/man4/linuxkpi_wlan.4               |  9 +++-
 sys/compat/linuxkpi/common/src/linux_80211.c | 78 ++++++++++++++++++++++++++--
 sys/compat/linuxkpi/common/src/linux_80211.h |  4 ++
 3 files changed, 85 insertions(+), 6 deletions(-)

diff --git a/share/man/man4/linuxkpi_wlan.4 b/share/man/man4/linuxkpi_wlan.4
index 136e04c32bb7..65c77d8d7631 100644
--- a/share/man/man4/linuxkpi_wlan.4
+++ b/share/man/man4/linuxkpi_wlan.4
@@ -6,7 +6,7 @@
 .\" This documentation was written by Bj\xc3\xb6rn Zeeb under sponsorship from
 .\" the FreeBSD Foundation.
 .\"
-.Dd June 13, 2025
+.Dd December 28, 2025
 .Dt LINUXKPI_WLAN 4
 .Os
 .Sh NAME
@@ -112,6 +112,13 @@ Print statistics for a given, associated
 .Xr wlan 4
 interface; typically IF would be
 .Em wlan0 .
+.It Va compat.linuxkpi.80211.IF.dump_stas_queues
+Like
+.Va compat.linuxkpi.80211.IF.dump_stas
+but also print queue statistics.
+This sysctl is
+.Sq hidden
+and normally only needed for debugging purposes.
 .El
 .Sh SEE ALSO
 .Xr iwlwifi 4 ,
diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c 
b/sys/compat/linuxkpi/common/src/linux_80211.c
index 02724433d89d..28c9c62309fe 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.c
+++ b/sys/compat/linuxkpi/common/src/linux_80211.c
@@ -282,7 +282,7 @@ lkpi_nl80211_sta_info_to_str(struct sbuf *s, const char 
*prefix,
 }
 
 static void
-lkpi_80211_dump_lvif_stas(struct lkpi_vif *lvif, struct sbuf *s)
+lkpi_80211_dump_lvif_stas(struct lkpi_vif *lvif, struct sbuf *s, bool 
dump_queues)
 {
        struct lkpi_hw *lhw;
        struct ieee80211_hw *hw;
@@ -292,6 +292,7 @@ lkpi_80211_dump_lvif_stas(struct lkpi_vif *lvif, struct 
sbuf *s)
        struct ieee80211_sta *sta;
        struct station_info sinfo;
        int error;
+       uint8_t tid;
 
        vif = LVIF_TO_VIF(lvif);
        vap = LVIF_TO_VAP(lvif);
@@ -376,6 +377,39 @@ lkpi_80211_dump_lvif_stas(struct lkpi_vif *lvif, struct 
sbuf *s)
                sbuf_printf(s, "         he_dcm %u he_gi %u he_ru_alloc %u 
eht_gi %u\n",
                    sinfo.txrate.he_dcm, sinfo.txrate.he_gi, 
sinfo.txrate.he_ru_alloc,
                    sinfo.txrate.eht_gi);
+
+               if (!dump_queues)
+                       continue;
+
+               /* Dump queue information. */
+               sbuf_printf(s, " Queue information:\n");
+               sbuf_printf(s, "  frms direct tx %ju\n", lsta->frms_tx);
+               for (tid = 0; tid <= IEEE80211_NUM_TIDS; tid++) {
+                       struct lkpi_txq *ltxq;
+
+                       if (sta->txq[tid] == NULL) {
+                               sbuf_printf(s, "  tid %-2u NOQ\n", tid);
+                               continue;
+                       }
+
+                       ltxq = TXQ_TO_LTXQ(sta->txq[tid]);
+#ifdef __notyet__
+                       sbuf_printf(s, "  tid %-2u flags: %b "
+                           "txq_generation %u skbq len %d\n",
+                           tid, ltxq->flags, LKPI_TXQ_FLAGS_BITS,
+                           ltxq->txq_generation,
+                           skb_queue_len_lockless(&ltxq->skbq));
+#else
+                       sbuf_printf(s, "  tid %-2u "
+                           "txq_generation %u skbq len %d\n",
+                           tid,
+                           ltxq->txq_generation,
+                           skb_queue_len_lockless(&ltxq->skbq));
+#endif
+                       sbuf_printf(s, "         frms_enqueued %ju 
frms_dequeued %ju "
+                           "frms_tx %ju\n",
+                           ltxq->frms_enqueued, ltxq->frms_dequeued, 
ltxq->frms_tx);
+               }
        }
        wiphy_unlock(hw->wiphy);
 }
@@ -393,7 +427,28 @@ lkpi_80211_dump_stas(SYSCTL_HANDLER_ARGS)
 
        sbuf_new_for_sysctl(&s, NULL, 1024, req);
 
-       lkpi_80211_dump_lvif_stas(lvif, &s);
+       lkpi_80211_dump_lvif_stas(lvif, &s, false);
+
+       sbuf_finish(&s);
+       sbuf_delete(&s);
+
+       return (0);
+}
+
+static int
+lkpi_80211_dump_sta_queues(SYSCTL_HANDLER_ARGS)
+{
+       struct lkpi_vif *lvif;
+       struct sbuf s;
+
+       if (req->newptr)
+               return (EPERM);
+
+       lvif = (struct lkpi_vif *)arg1;
+
+       sbuf_new_for_sysctl(&s, NULL, 1024, req);
+
+       lkpi_80211_dump_lvif_stas(lvif, &s, true);
 
        sbuf_finish(&s);
        sbuf_delete(&s);
@@ -4173,6 +4228,11 @@ lkpi_ic_vap_create(struct ieee80211com *ic, const char 
name[IFNAMSIZ],
            SYSCTL_CHILDREN(node), OID_AUTO, "dump_stas",
            CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, lvif, 0,
            lkpi_80211_dump_stas, "A", "Dump sta statistics of this vif");
+       SYSCTL_ADD_PROC(&lvif->sysctl_ctx,
+           SYSCTL_CHILDREN(node), OID_AUTO, "dump_stas_queues",
+           CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE | CTLFLAG_SKIP, lvif, 
0,
+           lkpi_80211_dump_sta_queues, "A",
+           "Dump queue statistics for any sta of this vif");
 
        IMPROVE();
 
@@ -5690,6 +5750,7 @@ lkpi_80211_txq_tx_one(struct lkpi_sta *lsta, struct mbuf 
*m)
 
        LKPI_80211_LTXQ_LOCK(ltxq);
        skb_queue_tail(&ltxq->skbq, skb);
+       ltxq->frms_enqueued++;
 #ifdef LINUXKPI_DEBUG_80211
        if (linuxkpi_debug_80211 & D80211_TRACE_TX)
                printf("%s:%d mo_wake_tx_queue :: %d %lu lsta %p sta %p "
@@ -5719,6 +5780,7 @@ ops_tx:
        control.sta = sta;
        wiphy_lock(hw->wiphy);
        lkpi_80211_mo_tx(hw, &control, skb);
+       lsta->frms_tx++;
        wiphy_unlock(hw->wiphy);
 }
 
@@ -8121,6 +8183,8 @@ linuxkpi_ieee80211_tx_dequeue(struct ieee80211_hw *hw,
 
        LKPI_80211_LTXQ_LOCK(ltxq);
        skb = skb_dequeue(&ltxq->skbq);
+       if (skb != NULL)
+               ltxq->frms_dequeued++;
        LKPI_80211_LTXQ_UNLOCK(ltxq);
 
 stopped:
@@ -8769,18 +8833,21 @@ linuxkpi_ieee80211_handle_wake_tx_queue(struct 
ieee80211_hw *hw,
     struct ieee80211_txq *txq)
 {
        struct lkpi_hw *lhw;
-       struct ieee80211_txq *ntxq;
-       struct ieee80211_tx_control control;
-        struct sk_buff *skb;
 
        lhw = HW_TO_LHW(hw);
 
        LKPI_80211_LHW_TXQ_LOCK(lhw);
        ieee80211_txq_schedule_start(hw, txq->ac);
        do {
+               struct lkpi_txq *ltxq;
+               struct ieee80211_txq *ntxq;
+               struct ieee80211_tx_control control;
+               struct sk_buff *skb;
+
                ntxq = ieee80211_next_txq(hw, txq->ac);
                if (ntxq == NULL)
                        break;
+               ltxq = TXQ_TO_LTXQ(ntxq);
 
                memset(&control, 0, sizeof(control));
                control.sta = ntxq->sta;
@@ -8788,6 +8855,7 @@ linuxkpi_ieee80211_handle_wake_tx_queue(struct 
ieee80211_hw *hw,
                        skb = linuxkpi_ieee80211_tx_dequeue(hw, ntxq);
                        if (skb == NULL)
                                break;
+                       ltxq->frms_tx++;
                        lkpi_80211_mo_tx(hw, &control, skb);
                } while(1);
 
diff --git a/sys/compat/linuxkpi/common/src/linux_80211.h 
b/sys/compat/linuxkpi/common/src/linux_80211.h
index fcbef46fc6de..d4f18fcafbba 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.h
+++ b/sys/compat/linuxkpi/common/src/linux_80211.h
@@ -154,6 +154,9 @@ struct lkpi_txq {
        bool                    stopped;
        uint32_t                txq_generation;
        struct sk_buff_head     skbq;
+       uint64_t                frms_enqueued;
+       uint64_t                frms_dequeued;
+       uint64_t                frms_tx;
 
        /* Must be last! */
        struct ieee80211_txq    txq __aligned(CACHE_LINE_SIZE);
@@ -180,6 +183,7 @@ struct lkpi_sta {
        bool                    in_mgd;                         /* XXX-BZ 
should this be per-vif? */
 
        struct station_info     sinfo;                          /* statistics */
+       uint64_t                frms_tx;                        /* (*tx) */
 
        /* Must be last! */
        struct ieee80211_sta    sta __aligned(CACHE_LINE_SIZE);

Reply via email to