From 16cce00f95c57e1143e0e245e7277ba32aff2396 Mon Sep 17 00:00:00 2001 From: dlg Date: Tue, 29 Aug 2023 23:26:40 +0000 Subject: [PATCH] export mbim signal stats tested by mbuhl@ gerhard@ --- sys/dev/usb/if_umb.c | 105 ++++++++++++++++++++++++++++++++++++++++++- sys/dev/usb/if_umb.h | 5 ++- 2 files changed, 108 insertions(+), 2 deletions(-) diff --git a/sys/dev/usb/if_umb.c b/sys/dev/usb/if_umb.c index 9f98b65dd0a..fb8df89ea62 100644 --- a/sys/dev/usb/if_umb.c +++ b/sys/dev/usb/if_umb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_umb.c,v 1.52 2023/08/26 11:33:46 dlg Exp $ */ +/* $OpenBSD: if_umb.c,v 1.53 2023/08/29 23:26:40 dlg Exp $ */ /* * Copyright (c) 2016 genua mbH @@ -23,13 +23,16 @@ * Compliance testing guide * https://www.usb.org/sites/default/files/MBIM-Compliance-1.0.pdf */ + #include "bpfilter.h" +#include "kstat.h" #include #include #include #include #include +#include #if NBPFILTER > 0 #include @@ -203,6 +206,17 @@ void umb_decode_qmi(struct umb_softc *, uint8_t *, int); void umb_intr(struct usbd_xfer *, void *, usbd_status); +#if NKSTAT > 0 +void umb_kstat_attach(struct umb_softc *); +void umb_kstat_detach(struct umb_softc *); + +struct umb_kstat_signal { + struct kstat_kv rssi; + struct kstat_kv error_rate; + struct kstat_kv reports; +}; +#endif + int umb_xfer_tout = USBD_DEFAULT_TIMEOUT; uint8_t umb_uuid_basic_connect[] = MBIM_UUID_BASIC_CONNECT; @@ -618,6 +632,11 @@ umb_attach(struct device *parent, struct device *self, void *aux) #if NBPFILTER > 0 bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(uint32_t)); #endif + +#if NKSTAT > 0 + umb_kstat_attach(sc); +#endif + /* * Open the device now so that we are able to query device information. * XXX maybe close when done? @@ -645,6 +664,10 @@ umb_detach(struct device *self, int flags) umb_down(sc, 1); umb_close(sc); +#if NKSTAT > 0 + umb_kstat_detach(sc); +#endif + usb_rem_wait_task(sc->sc_udev, &sc->sc_get_response_task); if (timeout_initialized(&sc->sc_statechg_timer)) timeout_del(&sc->sc_statechg_timer); @@ -1670,6 +1693,9 @@ umb_decode_signal_state(struct umb_softc *sc, void *data, int len) struct mbim_cid_signal_state *ss = data; struct ifnet *ifp = GET_IFP(sc); int rssi; +#if NKSTAT > 0 + struct kstat *ks; +#endif if (len < sizeof (*ss)) return 0; @@ -1686,6 +1712,35 @@ umb_decode_signal_state(struct umb_softc *sc, void *data, int len) sc->sc_info.ber = letoh32(ss->err_rate); if (sc->sc_info.ber == -99) sc->sc_info.ber = UMB_VALUE_UNKNOWN; + +#if NKSTAT > 0 + ks = sc->sc_kstat_signal; + if (ks != NULL) { + struct umb_kstat_signal *uks = ks->ks_data; + + rw_enter_write(&sc->sc_kstat_lock); + kstat_kv_u64(&uks->reports)++; + + if (sc->sc_info.rssi == UMB_VALUE_UNKNOWN) + uks->rssi.kv_type = KSTAT_KV_T_NULL; + else { + uks->rssi.kv_type = KSTAT_KV_T_INT32; + kstat_kv_s32(&uks->rssi) = sc->sc_info.rssi; + } + + if (sc->sc_info.ber == UMB_VALUE_UNKNOWN) + uks->error_rate.kv_type = KSTAT_KV_T_NULL; + else { + uks->error_rate.kv_type = KSTAT_KV_T_INT32; + kstat_kv_s32(&uks->error_rate) = sc->sc_info.ber; + } + + ks->ks_interval.tv_sec = letoh32(ss->ss_intvl); + getnanouptime(&ks->ks_updated); + rw_exit_write(&sc->sc_kstat_lock); + } +#endif + return 1; } @@ -3146,3 +3201,51 @@ umb_dump(void *buf, int len) addlog("\n"); } #endif /* UMB_DEBUG */ + +#if NKSTAT > 0 + +void +umb_kstat_attach(struct umb_softc *sc) +{ + struct kstat *ks; + struct umb_kstat_signal *uks; + + rw_init(&sc->sc_kstat_lock, "umbkstat"); + + ks = kstat_create(DEVNAM(sc), 0, "mbim-signal", 0, KSTAT_T_KV, 0); + if (ks == NULL) + return; + + uks = malloc(sizeof(*uks), M_DEVBUF, M_WAITOK|M_ZERO); + kstat_kv_init(&uks->rssi, "rssi", KSTAT_KV_T_NULL); + kstat_kv_init(&uks->error_rate, "error rate", KSTAT_KV_T_NULL); + kstat_kv_init(&uks->reports, "reports", KSTAT_KV_T_COUNTER64); + + kstat_set_rlock(ks, &sc->sc_kstat_lock); + ks->ks_data = uks; + ks->ks_datalen = sizeof(*uks); + ks->ks_read = kstat_read_nop; + + ks->ks_softc = sc; + sc->sc_kstat_signal = ks; + kstat_install(ks); +} + +void +umb_kstat_detach(struct umb_softc *sc) +{ + struct kstat *ks = sc->sc_kstat_signal; + struct umb_kstat_signal *uks; + + if (ks == NULL) + return; + + kstat_remove(ks); + sc->sc_kstat_signal = NULL; + + uks = ks->ks_data; + free(uks, M_DEVBUF, sizeof(*uks)); + + kstat_destroy(ks); +} +#endif /* NKSTAT > 0 */ diff --git a/sys/dev/usb/if_umb.h b/sys/dev/usb/if_umb.h index 0b602b54258..a62b70d5502 100644 --- a/sys/dev/usb/if_umb.h +++ b/sys/dev/usb/if_umb.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_umb.h,v 1.10 2021/07/04 19:22:32 sthen Exp $ */ +/* $OpenBSD: if_umb.h,v 1.11 2023/08/29 23:26:40 dlg Exp $ */ /* * Copyright (c) 2016 genua mbH @@ -388,5 +388,8 @@ struct umb_softc { #define sc_state sc_info.state #define sc_roaming sc_info.enable_roaming struct umb_info sc_info; + + struct rwlock sc_kstat_lock; + struct kstat *sc_kstat_signal; }; #endif /* _KERNEL */ -- 2.20.1