From b6363276015652f0fcfe7947a0795814e258be34 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 10 May 2024 14:23:38 +0200 Subject: [PATCH] modem: cmux: Implement modem backend statistics Implement modem backend statistics into modem CMUX DLCI channel receive buffer and CMUX transmit and receive buffers. Signed-off-by: Bjarki Arge Andreasen --- include/zephyr/modem/cmux.h | 12 +++++ subsys/modem/modem_cmux.c | 104 ++++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) diff --git a/include/zephyr/modem/cmux.h b/include/zephyr/modem/cmux.h index 57ee6a8505b..2e6990f5aa0 100644 --- a/include/zephyr/modem/cmux.h +++ b/include/zephyr/modem/cmux.h @@ -25,6 +25,7 @@ #include #include +#include #ifndef ZEPHYR_MODEM_CMUX_ #define ZEPHYR_MODEM_CMUX_ @@ -102,6 +103,11 @@ struct modem_cmux_dlci { /* State */ enum modem_cmux_dlci_state state; + + /* Statistics */ +#if CONFIG_MODEM_STATS + struct modem_stats_buffer receive_buf_stats; +#endif }; struct modem_cmux_frame { @@ -160,6 +166,12 @@ struct modem_cmux { /* Synchronize actions */ struct k_event event; + + /* Statistics */ +#if CONFIG_MODEM_STATS + struct modem_stats_buffer receive_buf_stats; + struct modem_stats_buffer transmit_buf_stats; +#endif }; /** diff --git a/subsys/modem/modem_cmux.c b/subsys/modem/modem_cmux.c index 3fcca3d6068..f4e2280dccb 100644 --- a/subsys/modem/modem_cmux.c +++ b/subsys/modem/modem_cmux.c @@ -144,6 +144,54 @@ static void modem_cmux_log_received_frame(const struct modem_cmux_frame *frame) modem_cmux_log_frame(frame, "rcvd", frame->data_len); } +#if CONFIG_MODEM_STATS +static uint32_t modem_cmux_get_receive_buf_length(struct modem_cmux *cmux) +{ + return cmux->receive_buf_len; +} + +static uint32_t modem_cmux_get_receive_buf_size(struct modem_cmux *cmux) +{ + return cmux->receive_buf_size; +} + +static uint32_t modem_cmux_get_transmit_buf_length(struct modem_cmux *cmux) +{ + return ring_buf_size_get(&cmux->transmit_rb); +} + +static uint32_t modem_cmux_get_transmit_buf_size(struct modem_cmux *cmux) +{ + return ring_buf_capacity_get(&cmux->transmit_rb); +} + +static void modem_cmux_init_buf_stats(struct modem_cmux *cmux) +{ + uint32_t size; + + size = modem_cmux_get_receive_buf_size(cmux); + modem_stats_buffer_init(&cmux->receive_buf_stats, "cmux_rx", size); + size = modem_cmux_get_transmit_buf_size(cmux); + modem_stats_buffer_init(&cmux->transmit_buf_stats, "cmux_tx", size); +} + +static void modem_cmux_advertise_transmit_buf_stats(struct modem_cmux *cmux) +{ + uint32_t length; + + length = modem_cmux_get_transmit_buf_length(cmux); + modem_stats_buffer_advertise_length(&cmux->transmit_buf_stats, length); +} + +static void modem_cmux_advertise_receive_buf_stats(struct modem_cmux *cmux) +{ + uint32_t length; + + length = modem_cmux_get_receive_buf_length(cmux); + modem_stats_buffer_advertise_length(&cmux->receive_buf_stats, length); +} +#endif + static const char *modem_cmux_command_type_to_str(enum modem_cmux_command_types command_type) { switch (command_type) { @@ -649,6 +697,10 @@ static void modem_cmux_on_dlci_frame(struct modem_cmux *cmux) static void modem_cmux_on_frame(struct modem_cmux *cmux) { +#if CONFIG_MODEM_STATS + modem_cmux_advertise_receive_buf_stats(cmux); +#endif + if (cmux->frame.dlci_address == 0) { modem_cmux_on_control_frame(cmux); } else { @@ -658,6 +710,10 @@ static void modem_cmux_on_frame(struct modem_cmux *cmux) static void modem_cmux_drop_frame(struct modem_cmux *cmux) { +#if CONFIG_MODEM_STATS + modem_cmux_advertise_receive_buf_stats(cmux); +#endif + LOG_WRN("Dropped frame"); cmux->receive_state = MODEM_CMUX_RECEIVE_STATE_SOF; @@ -884,6 +940,10 @@ static void modem_cmux_transmit_handler(struct k_work *item) k_mutex_lock(&cmux->transmit_rb_lock, K_FOREVER); +#if CONFIG_MODEM_STATS + modem_cmux_advertise_transmit_buf_stats(cmux); +#endif + while (true) { transmit_rb_empty = ring_buf_is_empty(&cmux->transmit_rb); @@ -975,6 +1035,36 @@ static void modem_cmux_disconnect_handler(struct k_work *item) k_work_schedule(&cmux->disconnect_work, MODEM_CMUX_T1_TIMEOUT); } +#if CONFIG_MODEM_STATS +static uint32_t modem_cmux_dlci_get_receive_buf_length(struct modem_cmux_dlci *dlci) +{ + return ring_buf_size_get(&dlci->receive_rb); +} + +static uint32_t modem_cmux_dlci_get_receive_buf_size(struct modem_cmux_dlci *dlci) +{ + return ring_buf_capacity_get(&dlci->receive_rb); +} + +static void modem_cmux_dlci_init_buf_stats(struct modem_cmux_dlci *dlci) +{ + uint32_t size; + char name[sizeof("dlci_xxxxx_rx")]; + + size = modem_cmux_dlci_get_receive_buf_size(dlci); + snprintk(name, sizeof(name), "dlci_%u_rx", dlci->dlci_address); + modem_stats_buffer_init(&dlci->receive_buf_stats, name, size); +} + +static void modem_cmux_dlci_advertise_receive_buf_stat(struct modem_cmux_dlci *dlci) +{ + uint32_t length; + + length = modem_cmux_dlci_get_receive_buf_length(dlci); + modem_stats_buffer_advertise_length(&dlci->receive_buf_stats, length); +} +#endif + static int modem_cmux_dlci_pipe_api_open(void *data) { struct modem_cmux_dlci *dlci = (struct modem_cmux_dlci *)data; @@ -1010,6 +1100,11 @@ static int modem_cmux_dlci_pipe_api_receive(void *data, uint8_t *buf, size_t siz uint32_t ret; k_mutex_lock(&dlci->receive_rb_lock, K_FOREVER); + +#if CONFIG_MODEM_STATS + modem_cmux_dlci_advertise_receive_buf_stat(dlci); +#endif + ret = ring_buf_get(&dlci->receive_rb, buf, size); k_mutex_unlock(&dlci->receive_rb_lock); return ret; @@ -1126,6 +1221,10 @@ void modem_cmux_init(struct modem_cmux *cmux, const struct modem_cmux_config *co k_event_init(&cmux->event); k_event_clear(&cmux->event, MODEM_CMUX_EVENT_CONNECTED_BIT); k_event_post(&cmux->event, MODEM_CMUX_EVENT_DISCONNECTED_BIT); + +#if CONFIG_MODEM_STATS + modem_cmux_init_buf_stats(cmux); +#endif } struct modem_pipe *modem_cmux_dlci_init(struct modem_cmux *cmux, struct modem_cmux_dlci *dlci, @@ -1148,6 +1247,11 @@ struct modem_pipe *modem_cmux_dlci_init(struct modem_cmux *cmux, struct modem_cm k_work_init_delayable(&dlci->close_work, modem_cmux_dlci_close_handler); dlci->state = MODEM_CMUX_DLCI_STATE_CLOSED; sys_slist_append(&dlci->cmux->dlcis, &dlci->node); + +#if CONFIG_MODEM_STATS + modem_cmux_dlci_init_buf_stats(dlci); +#endif + return &dlci->pipe; }