From d2de8ff226cfdc10b4e8c4d1260fcea3b901f653 Mon Sep 17 00:00:00 2001 From: Daniele Palmas Date: Tue, 14 Oct 2025 14:54:34 +0200 Subject: [PATCH] port-qmi: allow setting initial mux-id value when using rmnet multiplexing Qualcomm suggests to use mux id values >= 0x81: though this does not seem a strict mandatory rule, there are scenarios in which the usage of a specifix mux id is required otherwise various kind of issues could happen (e.g. call failure, limited throughput...). A new ID_MM_INITIAL_QMAP_MUX_ID udev tag allows setting the first initial mux id value to be used when creating the multiplexed data connection. Signed-off-by: Daniele Palmas --- docs/reference/api/ModemManager-sections.txt | 1 + include/ModemManager-tags.h | 14 +++++ src/mm-port-qmi.c | 63 ++++++++++++++------ 3 files changed, 61 insertions(+), 17 deletions(-) diff --git a/docs/reference/api/ModemManager-sections.txt b/docs/reference/api/ModemManager-sections.txt index 5ce0bf1b..94bfc458 100644 --- a/docs/reference/api/ModemManager-sections.txt +++ b/docs/reference/api/ModemManager-sections.txt @@ -229,6 +229,7 @@ ID_MM_TTY_BAUDRATE ID_MM_TTY_FLOW_CONTROL ID_MM_REQUIRED ID_MM_MAX_MULTIPLEXED_LINKS +ID_MM_INITIAL_QMAP_MUX_ID ID_MM_TTY_BLACKLIST ID_MM_TTY_MANUAL_SCAN_ONLY diff --git a/include/ModemManager-tags.h b/include/ModemManager-tags.h index 57067785..2d14ce44 100644 --- a/include/ModemManager-tags.h +++ b/include/ModemManager-tags.h @@ -323,6 +323,20 @@ */ #define ID_MM_TTY_AT_PROBE_TRIES "ID_MM_TTY_AT_PROBE_TRIES" +/** + * ID_MM_INITIAL_QMAP_MUX_ID: + * + * This is a device-specific tag that allows users to specify the initial value + * of the QMAP multiplexed id to be used. + * + * An integer value greater or equal than 1 and smaller than 255. + * + * This setting does nothing if the modem doesn't support multiplexing. + * + * Since: 1.26 + */ +#define ID_MM_INITIAL_QMAP_MUX_ID "ID_MM_INITIAL_QMAP_MUX_ID" + /* * The following symbols are deprecated. We don't add them to -compat * because this -tags file is not really part of the installed API. diff --git a/src/mm-port-qmi.c b/src/mm-port-qmi.c index 6e198b5b..79511689 100644 --- a/src/mm-port-qmi.c +++ b/src/mm-port-qmi.c @@ -60,6 +60,7 @@ struct _MMPortQmiPrivate { gchar *net_driver; gchar *net_sysfs_path; guint net_preallocated_links_requested; + guint net_initial_mux_id; #if defined WITH_QRTR QrtrNode *node; #endif @@ -563,14 +564,24 @@ initialize_preallocated_links_next (GTask *task) return; } - qmi_device_add_link_with_flags (self->priv->qmi_device, - ctx->preallocated_links->len + 1, - mm_kernel_device_get_name (mm_port_peek_kernel_device (ctx->data)), - ctx->link_prefix_hint, - ctx->flags, - NULL, - (GAsyncReadyCallback) device_add_link_preallocated_ready, - task); + if (self->priv->net_initial_mux_id) + qmi_device_add_link_with_flags_and_initial_mux_id (self->priv->qmi_device, + self->priv->net_initial_mux_id + ctx->preallocated_links->len, + mm_kernel_device_get_name (mm_port_peek_kernel_device (ctx->data)), + ctx->link_prefix_hint, + ctx->flags, + NULL, + (GAsyncReadyCallback) device_add_link_preallocated_ready, + task); + else + qmi_device_add_link_with_flags (self->priv->qmi_device, + ctx->preallocated_links->len + 1, + mm_kernel_device_get_name (mm_port_peek_kernel_device (ctx->data)), + ctx->link_prefix_hint, + ctx->flags, + NULL, + (GAsyncReadyCallback) device_add_link_preallocated_ready, + task); } static void @@ -635,12 +646,17 @@ device_add_link_ready (QmiDevice *device, GAsyncResult *res, GTask *task) { + MMPortQmi *self; SetupLinkContext *ctx; GError *error = NULL; + self = g_task_get_source_object (task); ctx = g_task_get_task_data (task); - ctx->link_name = qmi_device_add_link_with_flags_finish (device, res, &ctx->mux_id, &error); + if (self->priv->net_initial_mux_id) + ctx->link_name = qmi_device_add_link_with_flags_and_initial_mux_id_finish (device, res, &ctx->mux_id, &error); + else + ctx->link_name = qmi_device_add_link_with_flags_finish (device, res, &ctx->mux_id, &error); if (!ctx->link_name) { g_prefix_error (&error, "failed to add link for device: "); g_task_return_error (task, error); @@ -810,14 +826,24 @@ mm_port_qmi_setup_link (MMPortQmi *self, /* No preallocated links required and using rmnet, just try to add link in the QmiDevice */ if (self->priv->kernel_data_modes & MM_PORT_QMI_KERNEL_DATA_MODE_MUX_RMNET) { - qmi_device_add_link_with_flags (self->priv->qmi_device, - QMI_DEVICE_MUX_ID_AUTOMATIC, - mm_kernel_device_get_name (mm_port_peek_kernel_device (data)), - link_prefix_hint, - get_rmnet_device_add_link_flags (self), - NULL, - (GAsyncReadyCallback) device_add_link_ready, - task); + if (self->priv->net_initial_mux_id) + qmi_device_add_link_with_flags_and_initial_mux_id (self->priv->qmi_device, + self->priv->net_initial_mux_id, + mm_kernel_device_get_name (mm_port_peek_kernel_device (data)), + link_prefix_hint, + get_rmnet_device_add_link_flags (self), + NULL, + (GAsyncReadyCallback) device_add_link_ready, + task); + else + qmi_device_add_link_with_flags (self->priv->qmi_device, + QMI_DEVICE_MUX_ID_AUTOMATIC, + mm_kernel_device_get_name (mm_port_peek_kernel_device (data)), + link_prefix_hint, + get_rmnet_device_add_link_flags (self), + NULL, + (GAsyncReadyCallback) device_add_link_ready, + task); return; } @@ -2723,6 +2749,9 @@ mm_port_qmi_set_net_details (MMPortQmi *self, g_assert (!self->priv->net_preallocated_links_requested); self->priv->net_preallocated_links_requested = mm_kernel_device_get_global_property_as_int (first_net_dev, "ID_MM_QMI_PREALLOCATED_LINKS"); + g_assert (!self->priv->net_initial_mux_id); + self->priv->net_initial_mux_id = mm_kernel_device_get_global_property_as_int (first_net_dev, "ID_MM_INITIAL_QMAP_MUX_ID"); + initialize_endpoint_info (self); }