aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAleksander Morgado <aleksandermj@chromium.org>2023-11-15 15:12:44 +0000
committerAleksander Morgado <aleksandermj@chromium.org>2024-02-15 21:01:52 +0000
commit1373ca7e51e790be6c1747947ccd73361a673358 (patch)
tree15b039ba276fd4d9f61b3c0961990f6fe8b5b8aa /src
parentf31f42dda1cced436b1927d06fab36507f58210f (diff)
mtk: expect async SLAAC only in FM350 >= 29.23.06
Async SLAAC implementation in the FM350 is only available since 29.23.06, so only wait for the IP configuration indications reporting the SLAAC result in newer versions.
Diffstat (limited to 'src')
-rw-r--r--src/plugins/meson.build1
-rw-r--r--src/plugins/mtk/mm-bearer-mbim-mtk-fibocom.c58
-rw-r--r--src/plugins/mtk/mm-bearer-mbim-mtk-fibocom.h53
-rw-r--r--src/plugins/mtk/mm-broadband-modem-mbim-mtk-fibocom.c149
-rw-r--r--src/plugins/mtk/mm-broadband-modem-mbim-mtk-fibocom.h2
5 files changed, 262 insertions, 1 deletions
diff --git a/src/plugins/meson.build b/src/plugins/meson.build
index 805c6846..b031da54 100644
--- a/src/plugins/meson.build
+++ b/src/plugins/meson.build
@@ -652,6 +652,7 @@ if plugins_options['mtk']
if enable_mbim
incs += [fibocom_inc]
sources += files(
+ 'mtk/mm-bearer-mbim-mtk-fibocom.c',
'mtk/mm-broadband-modem-mbim-mtk.c',
'mtk/mm-broadband-modem-mbim-mtk-fibocom.c'
)
diff --git a/src/plugins/mtk/mm-bearer-mbim-mtk-fibocom.c b/src/plugins/mtk/mm-bearer-mbim-mtk-fibocom.c
new file mode 100644
index 00000000..1effc603
--- /dev/null
+++ b/src/plugins/mtk/mm-bearer-mbim-mtk-fibocom.c
@@ -0,0 +1,58 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details:
+ *
+ * Copyright (C) 2024 Google, Inc.
+ */
+
+#include <config.h>
+
+#include <ModemManager.h>
+#define _LIBMM_INSIDE_MM
+#include <libmm-glib.h>
+
+#include "mm-bearer-mbim-mtk-fibocom.h"
+
+G_DEFINE_TYPE (MMBearerMbimMtkFibocom, mm_bearer_mbim_mtk_fibocom, MM_TYPE_BEARER_MBIM)
+
+/*****************************************************************************/
+
+MMBaseBearer *
+mm_bearer_mbim_mtk_fibocom_new (MMBroadbandModemMbim *modem,
+ gboolean is_async_slaac_supported,
+ MMBearerProperties *config)
+{
+ MMBaseBearer *bearer;
+
+ /* The Mbim bearer inherits from MMBaseBearer (so it's not a MMBroadbandBearer)
+ * and that means that the object is not async-initable, so we just use
+ * g_object_new() here */
+ bearer = g_object_new (MM_TYPE_BEARER_MBIM_MTK_FIBOCOM,
+ MM_BASE_BEARER_MODEM, modem,
+ MM_BASE_BEARER_CONFIG, config,
+ MM_BEARER_MBIM_ASYNC_SLAAC, is_async_slaac_supported,
+ NULL);
+
+ /* Only export valid bearers */
+ mm_base_bearer_export (bearer);
+
+ return bearer;
+}
+
+static void
+mm_bearer_mbim_mtk_fibocom_init (MMBearerMbimMtkFibocom *self)
+{
+}
+
+static void
+mm_bearer_mbim_mtk_fibocom_class_init (MMBearerMbimMtkFibocomClass *klass)
+{
+}
diff --git a/src/plugins/mtk/mm-bearer-mbim-mtk-fibocom.h b/src/plugins/mtk/mm-bearer-mbim-mtk-fibocom.h
new file mode 100644
index 00000000..736d3fc9
--- /dev/null
+++ b/src/plugins/mtk/mm-bearer-mbim-mtk-fibocom.h
@@ -0,0 +1,53 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details:
+ *
+ * Copyright (C) 2024 Google, Inc.
+ */
+
+#ifndef MM_BEARER_MBIM_MTK_FIBOCOM_H
+#define MM_BEARER_MBIM_MTK_FIBOCOM_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#define _LIBMM_INSIDE_MM
+#include <libmm-glib.h>
+
+#include "mm-bearer-mbim.h"
+
+#define MM_TYPE_BEARER_MBIM_MTK_FIBOCOM (mm_bearer_mbim_mtk_fibocom_get_type ())
+#define MM_BEARER_MBIM_MTK_FIBOCOM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_BEARER_MBIM_MTK_FIBOCOM, MMBearerMbimMtkFibocom))
+#define MM_BEARER_MBIM_MTK_FIBOCOM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_BEARER_MBIM_MTK_FIBOCOM, MMBearerMbimMtkFibocomClass))
+#define MM_IS_BEARER_MBIM_MTK_FIBOCOM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_BEARER_MBIM_MTK_FIBOCOM))
+#define MM_IS_BEARER_MBIM_MTK_FIBOCOM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_BEARER_MBIM_MTK_FIBOCOM))
+#define MM_BEARER_MBIM_MTK_FIBOCOM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_BEARER_MBIM_MTK_FIBOCOM, MMBearerMbimMtkFibocomClass))
+
+typedef struct _MMBearerMbimMtkFibocom MMBearerMbimMtkFibocom;
+typedef struct _MMBearerMbimMtkFibocomClass MMBearerMbimMtkFibocomClass;
+
+struct _MMBearerMbimMtkFibocom {
+ MMBearerMbim parent;
+};
+
+struct _MMBearerMbimMtkFibocomClass {
+ MMBearerMbimClass parent;
+};
+
+GType mm_bearer_mbim_mtk_fibocom_get_type (void);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (MMBearerMbimMtkFibocom, g_object_unref)
+
+/* MBIM bearer creation implementation */
+MMBaseBearer *mm_bearer_mbim_mtk_fibocom_new (MMBroadbandModemMbim *modem,
+ gboolean is_async_slaac_supported,
+ MMBearerProperties *config);
+
+#endif /* MM_BEARER_MBIM_MTK_FIBOCOM_H */
diff --git a/src/plugins/mtk/mm-broadband-modem-mbim-mtk-fibocom.c b/src/plugins/mtk/mm-broadband-modem-mbim-mtk-fibocom.c
index 7d6e78ae..17d4761a 100644
--- a/src/plugins/mtk/mm-broadband-modem-mbim-mtk-fibocom.c
+++ b/src/plugins/mtk/mm-broadband-modem-mbim-mtk-fibocom.c
@@ -25,16 +25,146 @@
#include "mm-log-object.h"
#include "mm-iface-modem.h"
#include "mm-iface-modem-3gpp.h"
+#include "mm-bearer-mbim-mtk-fibocom.h"
#include "mm-broadband-modem-mbim-mtk-fibocom.h"
#include "mm-shared-fibocom.h"
+static void iface_modem_init (MMIfaceModem *iface);
static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
static void shared_fibocom_init (MMSharedFibocom *iface);
+
+static MMIfaceModem *iface_modem_parent;
static MMIfaceModem3gpp *iface_modem_3gpp_parent;
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemMbimMtkFibocom, mm_broadband_modem_mbim_mtk_fibocom, MM_TYPE_BROADBAND_MODEM_MBIM_MTK, 0,
+ G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init)
- G_IMPLEMENT_INTERFACE (MM_TYPE_SHARED_FIBOCOM, shared_fibocom_init))
+ G_IMPLEMENT_INTERFACE (MM_TYPE_SHARED_FIBOCOM, shared_fibocom_init))
+
+struct _MMBroadbandModemMbimMtkFibocomPrivate {
+ /* Supported features */
+ gboolean is_async_slaac_supported;
+};
+
+/*****************************************************************************/
+
+/* Asynchronous indications of IP configuration updates during the initial
+ * modem-SLAAC operation with the network are not supported in old firmware
+ * versions. */
+#define ASYNC_SLAAC_SUPPORTED_VERSION 29, 23, 6
+
+static inline gboolean
+fm350_check_version (guint A1, guint A2, guint A3,
+ guint B1, guint B2, guint B3)
+{
+ return ((A1 > B1) || ((A1 == B1) && ((A2 > B2) || ((A2 == B2) && (A3 >= B3)))));
+}
+
+static void
+process_fm350_version_features (MMBroadbandModemMbimMtkFibocom *self,
+ const gchar *revision)
+{
+ g_auto(GStrv) split = NULL;
+ guint major;
+ guint minor;
+ guint micro;
+
+ /* Expected revision string is a multi-line value like this:
+ * 81600.0000.00.MM.mm.uu_GC
+ * F09
+ * For version comparison we care only about the "MM.mm.uu" part.
+ */
+ split = g_strsplit_set (revision, "._", -1);
+ if (!split || g_strv_length (split) < 6) {
+ mm_obj_warn (self, "failed to process FM350 firmware version string");
+ return;
+ }
+
+ if (!mm_get_uint_from_str (split[3], &major) ||
+ !mm_get_uint_from_str (split[4], &minor) ||
+ !mm_get_uint_from_str (split[5], &micro)) {
+ mm_obj_warn (self, "failed to process FM350 firmware version string: %s.%s.%s",
+ split[3], split[4], split[5]);
+ return;
+ }
+
+ /* Check if async SLAAC is supported */
+ self->priv->is_async_slaac_supported = fm350_check_version (major, minor, micro, ASYNC_SLAAC_SUPPORTED_VERSION);
+ mm_obj_info (self, "FM350 async SLAAC result indications are %ssupported",
+ self->priv->is_async_slaac_supported ? "" : "not ");
+}
+
+/*****************************************************************************/
+/* Revision loading (Modem interface) */
+
+static gchar *
+load_revision_finish (MMIfaceModem *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return g_task_propagate_pointer (G_TASK (res), error);
+}
+
+static void
+parent_load_revision_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ GError *error = NULL;
+ gchar *revision;
+
+ revision = iface_modem_parent->load_revision_finish (self, res, &error);
+ if (!revision) {
+ g_task_return_error (task, error);
+ } else {
+ process_fm350_version_features (MM_BROADBAND_MODEM_MBIM_MTK_FIBOCOM (self), revision);
+ g_task_return_pointer (task, revision, g_free);
+ }
+ g_object_unref (task);
+}
+
+static void
+load_revision (MMIfaceModem *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_assert (iface_modem_parent->load_revision);
+ g_assert (iface_modem_parent->load_revision_finish);
+ iface_modem_parent->load_revision (self,
+ (GAsyncReadyCallback)parent_load_revision_ready,
+ g_task_new (self, NULL, callback, user_data));
+}
+
+/*****************************************************************************/
+/* Create Bearer (Modem interface) */
+
+static MMBaseBearer *
+create_bearer_finish (MMIfaceModem *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return g_task_propagate_pointer (G_TASK (res), error);
+}
+
+static void
+create_bearer (MMIfaceModem *_self,
+ MMBearerProperties *properties,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ MMBroadbandModemMbimMtkFibocom *self = MM_BROADBAND_MODEM_MBIM_MTK_FIBOCOM (_self);
+ MMBaseBearer *bearer;
+ GTask *task;
+
+ task = g_task_new (self, NULL, callback, user_data);
+ mm_obj_dbg (self, "creating MTK Fibocom MBIM bearer (async SLAAC %s)",
+ self->priv->is_async_slaac_supported ? "supported" : "unsupported");
+ bearer = mm_bearer_mbim_mtk_fibocom_new (MM_BROADBAND_MODEM_MBIM (self),
+ self->priv->is_async_slaac_supported,
+ properties);
+ g_task_return_pointer (task, bearer, g_object_unref);
+ g_object_unref (task);
+}
/******************************************************************************/
@@ -67,6 +197,20 @@ mm_broadband_modem_mbim_mtk_fibocom_new (const gchar *device,
static void
mm_broadband_modem_mbim_mtk_fibocom_init (MMBroadbandModemMbimMtkFibocom *self)
{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+ MM_TYPE_BROADBAND_MODEM_MBIM_MTK_FIBOCOM,
+ MMBroadbandModemMbimMtkFibocomPrivate);
+}
+
+static void
+iface_modem_init (MMIfaceModem *iface)
+{
+ iface_modem_parent = g_type_interface_peek_parent (iface);
+
+ iface->load_revision = load_revision;
+ iface->load_revision_finish = load_revision_finish;
+ iface->create_bearer = create_bearer;
+ iface->create_bearer_finish = create_bearer_finish;
}
static void
@@ -93,4 +237,7 @@ shared_fibocom_init (MMSharedFibocom *iface)
static void
mm_broadband_modem_mbim_mtk_fibocom_class_init (MMBroadbandModemMbimMtkFibocomClass *klass)
{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof (MMBroadbandModemMbimMtkFibocomPrivate));
}
diff --git a/src/plugins/mtk/mm-broadband-modem-mbim-mtk-fibocom.h b/src/plugins/mtk/mm-broadband-modem-mbim-mtk-fibocom.h
index d5cd91ed..fcb011fc 100644
--- a/src/plugins/mtk/mm-broadband-modem-mbim-mtk-fibocom.h
+++ b/src/plugins/mtk/mm-broadband-modem-mbim-mtk-fibocom.h
@@ -27,9 +27,11 @@
typedef struct _MMBroadbandModemMbimMtkFibocom MMBroadbandModemMbimMtkFibocom;
typedef struct _MMBroadbandModemMbimMtkFibocomClass MMBroadbandModemMbimMtkFibocomClass;
+typedef struct _MMBroadbandModemMbimMtkFibocomPrivate MMBroadbandModemMbimMtkFibocomPrivate;
struct _MMBroadbandModemMbimMtkFibocom {
MMBroadbandModemMbimMtk parent;
+ MMBroadbandModemMbimMtkFibocomPrivate *priv;
};
struct _MMBroadbandModemMbimMtkFibocomClass{