From 59a2c127331e63a8eac5b4dd746b0cb6c43b696f Mon Sep 17 00:00:00 2001 From: stsp Date: Sat, 2 Mar 2024 15:18:57 +0000 Subject: [PATCH] implement qwx(4) monitor status ring polling On QCNFA765 the monitor status ring does not trigger any interrupts. Unless the driver keeps polling this ring from a timer the device will eventually lock up if this ring is enabled. Even though we're not using this ring yet, add the tiny bits of code required to poll it so that the next person who enables this code won't have to waste time figuring out why the device stops working. The monitor status ring provides details about received frames in special TLV-format packets which the driver can parse and update statistics with. Interesting info includes per-frame RSSI. Which we already learn from beacons, so we don't need to enable an entire extra ring just for that. Another reason to keep this disabled is that it triggers mbuf corruption for reasons I haven't been able to figure out. Help welcome. --- sys/dev/ic/qwx.c | 38 +++++++++++++++++++++++++------------- sys/dev/ic/qwxvar.h | 5 ++++- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/sys/dev/ic/qwx.c b/sys/dev/ic/qwx.c index 54a98fa9ad4..b0707f81bac 100644 --- a/sys/dev/ic/qwx.c +++ b/sys/dev/ic/qwx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: qwx.c,v 1.56 2024/03/02 15:06:20 stsp Exp $ */ +/* $OpenBSD: qwx.c,v 1.57 2024/03/02 15:18:57 stsp Exp $ */ /* * Copyright 2023 Stefan Sperling @@ -151,6 +151,7 @@ int qwx_dp_tx_send_reo_cmd(struct qwx_softc *, struct dp_rx_tid *, enum hal_reo_cmd_type , struct ath11k_hal_reo_cmd *, void (*func)(struct qwx_dp *, void *, enum hal_reo_cmd_status)); void qwx_dp_rx_deliver_msdu(struct qwx_softc *, struct qwx_rx_msdu *); +void qwx_dp_service_mon_ring(void *); int qwx_scan(struct qwx_softc *); void qwx_scan_abort(struct qwx_softc *); @@ -272,6 +273,8 @@ qwx_stop(struct ifnet *ifp) rw_assert_wrlock(&sc->ioctl_rwl); + timeout_del(&sc->mon_reap_timer); + /* Disallow new tasks. */ set_bit(ATH11K_FLAG_CRASH_FLUSH, sc->sc_flags); @@ -14130,11 +14133,7 @@ qwx_dp_rx_pdev_srng_alloc(struct qwx_softc *sc) * init reap timer for QCA6390. */ if (!sc->hw_params.rxdma1_enable) { -#if 0 - //init mon status buffer reap timer - timer_setup(&ar->ab->mon_reap_timer, - ath11k_dp_service_mon_ring, 0); -#endif + timeout_set(&sc->mon_reap_timer, qwx_dp_service_mon_ring, sc); return 0; } #if 0 @@ -14835,6 +14834,8 @@ qwx_dp_pdev_free(struct qwx_softc *sc) { int i; + timeout_del(&sc->mon_reap_timer); + for (i = 0; i < sc->num_radios; i++) qwx_dp_rx_pdev_free(sc, i); } @@ -16541,7 +16542,6 @@ qwx_dp_rx_process_mon_status(struct qwx_softc *sc, int mac_id) struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; num_buffs_reaped = qwx_dp_rx_reap_mon_status_ring(sc, mac_id, &ml); - printf("%s: processing %d packets\n", __func__, num_buffs_reaped); if (!num_buffs_reaped) goto exit; @@ -16629,6 +16629,18 @@ qwx_dp_rx_process_mon_rings(struct qwx_softc *sc, int mac_id) return ret; } +void +qwx_dp_service_mon_ring(void *arg) +{ + struct qwx_softc *sc = arg; + int i; + + for (i = 0; i < sc->hw_params.num_rxmda_per_pdev; i++) + qwx_dp_rx_process_mon_rings(sc, i); + + timeout_add(&sc->mon_reap_timer, ATH11K_MON_TIMER_INTERVAL); +} + int qwx_dp_process_rxdma_err(struct qwx_softc *sc, int mac_id) { @@ -21747,7 +21759,7 @@ qwx_mac_config_mon_status_default(struct qwx_softc *sc, int enable) if (enable) tlv_filter = qwx_mac_mon_status_filter_default; -#if 0 +#if 0 /* mon status info is not useful and the code triggers mbuf corruption */ for (i = 0; i < sc->hw_params.num_rxmda_per_pdev; i++) { ring = &sc->pdev_dp.rx_mon_status_refill_ring[i]; ret = qwx_dp_tx_htt_rx_filter_setup(sc, @@ -21756,11 +21768,11 @@ qwx_mac_config_mon_status_default(struct qwx_softc *sc, int enable) if (ret) return ret; } -#endif -#if 0 - if (enable && !ar->ab->hw_params.rxdma1_enable) - mod_timer(&ar->ab->mon_reap_timer, jiffies + - msecs_to_jiffies(ATH11K_MON_TIMER_INTERVAL)); + + if (enable && !sc->hw_params.rxdma1_enable) { + timeout_add_msec(&sc->mon_reap_timer, + ATH11K_MON_TIMER_INTERVAL); + } #endif return ret; } diff --git a/sys/dev/ic/qwxvar.h b/sys/dev/ic/qwxvar.h index a84553d5bcb..6ee2012ab05 100644 --- a/sys/dev/ic/qwxvar.h +++ b/sys/dev/ic/qwxvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: qwxvar.h,v 1.23 2024/02/24 15:21:39 cheloha Exp $ */ +/* $OpenBSD: qwxvar.h,v 1.24 2024/03/02 15:18:57 stsp Exp $ */ /* * Copyright (c) 2018-2019 The Linux Foundation. @@ -1869,6 +1869,9 @@ struct qwx_softc { struct qwx_dmamem *m3_mem; + struct timeout mon_reap_timer; +#define ATH11K_MON_TIMER_INTERVAL 10 + /* Provided by attachment driver: */ struct qwx_ops ops; bus_dma_tag_t sc_dmat; -- 2.20.1