From 6db2e8f04da458488c374f1a6f6979ce7fe9b67d Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Wed, 16 Dec 2020 15:11:48 +0100 Subject: base: Add support for wwan subsystem Add support for the Linux wwan subsystem that started to expose control channel as character devices (e.g. /dev/wwan0p1MBIM...). Signed-off-by: Loic Poulain --- src/mm-base-modem.c | 26 ++++++++++++++++++++++++++ src/mm-modem-helpers-qmi.c | 7 +++++++ src/mm-plugin.c | 9 +++++++++ src/mm-port-probe.c | 9 ++++++++- src/mm-port.h | 3 ++- 5 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/mm-base-modem.c b/src/mm-base-modem.c index a00a4ae2..06562af4 100644 --- a/src/mm-base-modem.c +++ b/src/mm-base-modem.c @@ -284,6 +284,30 @@ base_modem_create_qrtr_port (MMBaseModem *self, } #endif +static MMPort * +base_modem_create_wwan_port (MMBaseModem *self, + const gchar *name, + MMPortType ptype) +{ +#if defined WITH_QMI + if (ptype == MM_PORT_TYPE_QMI) + return MM_PORT (mm_port_qmi_new (name, MM_PORT_SUBSYS_WWAN)); +#endif + +#if defined WITH_MBIM + if (ptype == MM_PORT_TYPE_MBIM) + return MM_PORT (mm_port_mbim_new (name, MM_PORT_SUBSYS_WWAN)); +#endif + + if (ptype == MM_PORT_TYPE_QCDM) + return MM_PORT (mm_port_serial_qcdm_new (name, MM_PORT_SUBSYS_WWAN)); + + if (ptype == MM_PORT_TYPE_AT) + return MM_PORT (mm_port_serial_at_new (name, MM_PORT_SUBSYS_WWAN)); + + return NULL; +} + static MMPort * base_modem_create_virtual_port (MMBaseModem *self, const gchar *name) @@ -334,6 +358,8 @@ base_modem_internal_grab_port (MMBaseModem *self, #endif else if (g_str_equal (subsys, "virtual")) port = base_modem_create_virtual_port (self, name); + else if (g_str_equal (subsys, "wwan")) + port = base_modem_create_wwan_port (self, name, ptype); if (!port) { g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, diff --git a/src/mm-modem-helpers-qmi.c b/src/mm-modem-helpers-qmi.c index a17e14ad..6e3c5008 100644 --- a/src/mm-modem-helpers-qmi.c +++ b/src/mm-modem-helpers-qmi.c @@ -1562,6 +1562,13 @@ mm_port_subsys_to_qmi_endpoint_type (MMPortSubsys subsys) case MM_PORT_SUBSYS_RPMSG: case MM_PORT_SUBSYS_QRTR: return QMI_DATA_ENDPOINT_TYPE_EMBEDDED; + /* The WWAN subsystem abstracts the underlying transport bus, and so + * endpoint type can not be deducted from that. This function should + * then be revisited, but in practice, only MHI/PCI modem ports are + * exposed through the WWAN subsystem for now. + */ + case MM_PORT_SUBSYS_WWAN: + return QMI_DATA_ENDPOINT_TYPE_PCIE; case MM_PORT_SUBSYS_UNKNOWN: case MM_PORT_SUBSYS_TTY: case MM_PORT_SUBSYS_NET: diff --git a/src/mm-plugin.c b/src/mm-plugin.c index 5dfb4e14..2020b376 100644 --- a/src/mm-plugin.c +++ b/src/mm-plugin.c @@ -786,6 +786,15 @@ mm_plugin_supports_port (MMPlugin *self, probe_run_flags |= MM_PORT_PROBE_AT; if (self->priv->qmi) probe_run_flags |= MM_PORT_PROBE_QMI; + } else if (g_str_equal (mm_kernel_device_get_subsystem (port), "wwan")) { + if (self->priv->mbim) + probe_run_flags |= MM_PORT_PROBE_MBIM; + if (self->priv->qmi) + probe_run_flags |= MM_PORT_PROBE_QMI; + if (self->priv->qcdm) + probe_run_flags |= MM_PORT_PROBE_QCDM; + if (self->priv->at) + probe_run_flags |= MM_PORT_PROBE_AT; } #if defined WITH_QRTR else if (g_str_equal (mm_kernel_device_get_subsystem (port), "qrtr")) { diff --git a/src/mm-port-probe.c b/src/mm-port-probe.c index f0efce59..e955a97e 100644 --- a/src/mm-port-probe.c +++ b/src/mm-port-probe.c @@ -745,6 +745,8 @@ serial_probe_qcdm (MMPortProbe *self) gint len; guint8 marker = 0x7E; PortProbeRunContext *ctx; + MMPortSubsys subsys = MM_PORT_SUBSYS_TTY; + g_assert (self->priv->task); ctx = g_task_get_task_data (self->priv->task); @@ -767,8 +769,11 @@ serial_probe_qcdm (MMPortProbe *self) g_object_unref (ctx->serial); } + if (g_str_equal (mm_kernel_device_get_subsystem (self->priv->port), "wwan")) + subsys = MM_PORT_SUBSYS_WWAN; + /* Open the QCDM port */ - ctx->serial = MM_PORT_SERIAL (mm_port_serial_qcdm_new (mm_kernel_device_get_name (self->priv->port), MM_PORT_SUBSYS_TTY)); + ctx->serial = MM_PORT_SERIAL (mm_port_serial_qcdm_new (mm_kernel_device_get_name (self->priv->port), subsys)); if (!ctx->serial) { port_probe_task_return_error (self, g_error_new (MM_CORE_ERROR, @@ -1296,6 +1301,8 @@ serial_open_at (MMPortProbe *self) subsys = MM_PORT_SUBSYS_USBMISC; else if (g_str_equal (mm_kernel_device_get_subsystem (self->priv->port), "rpmsg")) subsys = MM_PORT_SUBSYS_RPMSG; + else if (g_str_equal (mm_kernel_device_get_subsystem (self->priv->port), "wwan")) + subsys = MM_PORT_SUBSYS_WWAN; ctx->serial = MM_PORT_SERIAL (mm_port_serial_at_new (mm_kernel_device_get_name (self->priv->port), subsys)); if (!ctx->serial) { diff --git a/src/mm-port.h b/src/mm-port.h index 75595323..b5d58706 100644 --- a/src/mm-port.h +++ b/src/mm-port.h @@ -30,7 +30,8 @@ typedef enum { /*< underscore_name=mm_port_subsys >*/ MM_PORT_SUBSYS_UNIX, MM_PORT_SUBSYS_QRTR, MM_PORT_SUBSYS_RPMSG, - MM_PORT_SUBSYS_LAST = MM_PORT_SUBSYS_RPMSG /*< skip >*/ + MM_PORT_SUBSYS_WWAN, + MM_PORT_SUBSYS_LAST = MM_PORT_SUBSYS_WWAN /*< skip >*/ } MMPortSubsys; typedef enum { /*< underscore_name=mm_port_type >*/ -- cgit v1.2.3