From d058dd07759569b215f8af5dc82ce3a55b5fd906 Mon Sep 17 00:00:00 2001 From: Florian Eckert Date: Fri, 20 Sep 2024 09:08:13 +0200 Subject: broadband-modem-mbim: add qdu firmware update check The manufacturers can offer a firmware update file 'ota.bin' with which the firmware can be updated in the modem via a manufacturer tool using windows. The tool is only available for Windows and can therefore not be used for embedded devices. A investigation has shown that this tool updates the firmware via 'mbim-qdu'. The update service 'fwupd' which has a 'modemmanager' plugin can install the firmware via 'mbim-qdu'. For this to work, the ModemManager must export this update method via the firmware interface. As the 'mbim-qdu' is a generic update method, the check is integrated into the 'mm-broadband-modem-mbim' class. If 'mbim-qdu' update method is supported by the mbim interface and the udev env variable 'ID_MM_MBIM_QDU' is set for this modem, then the 'mbim-qdu' update is exported via dbus. The following line must be added to the '77-mm-cinterion-port-types.rules' udev rules file, for example, so that the mbim-qdu update for the 'MV31' can be used. ATTRS{vendor}=="0x1e2d", ATTRS{device}=="0x00b3", ENV{ID_MM_MBIM_QDU}="1" This is the corresponding output of the 'mmcli' command to show the supported update method for the 'MV31'. root@G3-10940 ~ # mmcli -m Modem1 --firmware-status Firmware | method: mbim-qdu | device ids: USB\VID_1E2D&PID_00B3&REV_0414&CARRIER_GCF | USB\VID_1E2D&PID_00B3&REV_0414 | USB\VID_1E2D&PID_00B3 | USB\VID_1E2D | version: T99W175.F0.1.0.0.9.GC.004.063 - 0A000804 Signed-off-by: Florian Eckert --- src/mm-broadband-modem-mbim.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/mm-broadband-modem-mbim.c b/src/mm-broadband-modem-mbim.c index 9957fe9e..a7dc8dca 100644 --- a/src/mm-broadband-modem-mbim.c +++ b/src/mm-broadband-modem-mbim.c @@ -153,6 +153,7 @@ struct _MMBroadbandModemMbimPrivate { gboolean is_ms_sar_supported; gboolean is_google_carrier_lock_supported; gboolean is_ms_device_reset_supported; + gboolean is_qdu_supported; /* Process unsolicited notifications */ gulong notification_id; @@ -3537,6 +3538,12 @@ query_device_services_ready (MbimDevice *device, continue; } + if (service == MBIM_SERVICE_QDU) { + mm_obj_dbg (self, "Qualcomm Device Upgrade method mbim-qdu supported"); + self->priv->is_qdu_supported = TRUE; + continue; + } + /* no optional features to check in remaining services */ } mbim_device_service_element_array_free (device_services); @@ -10380,11 +10387,43 @@ modem_firmware_load_update_settings_finish (MMIfaceModemFirmware *self, return mm_iface_modem_firmware_load_update_settings_in_port_finish (self, res, error); } +static gboolean +modem_is_qdu_supported (MMBaseModem *modem, + MMKernelDevice *kernel_device) +{ + return mm_kernel_device_get_global_property_as_boolean (kernel_device, "ID_MM_MBIM_QDU"); +} + static void modem_firmware_load_update_settings (MMIfaceModemFirmware *self, GAsyncReadyCallback callback, gpointer user_data) { + GTask *task; + MMPortMbim *mbim_port; + MMKernelDevice *kernel_device; + MMModemFirmwareUpdateMethod update_methods; + g_autoptr(MMFirmwareUpdateSettings) update_settings = NULL; + + /* Check first if 'mbim-qdu' is supported and selected via udev. If the + * update method 'mbim-qdu' is not supported and not selected via udev, + * then the generic update method 'firehose/sahara' are checked. + */ + update_methods = MM_MODEM_FIRMWARE_UPDATE_METHOD_NONE; + mbim_port = mm_broadband_modem_mbim_peek_port_mbim (MM_BROADBAND_MODEM_MBIM (self)); + if (mbim_port) { + kernel_device = mm_port_peek_kernel_device (MM_PORT (mbim_port)); + if ((MM_BROADBAND_MODEM_MBIM (self)->priv->is_qdu_supported) && + modem_is_qdu_supported (MM_BASE_MODEM (self), kernel_device)) { + task = g_task_new (self, NULL, callback, user_data); + update_settings = mm_firmware_update_settings_new (update_methods); + mm_firmware_update_settings_set_method (update_settings, MM_MODEM_FIRMWARE_UPDATE_METHOD_MBIM_QDU); + g_task_return_pointer (task, g_object_ref (update_settings), (GDestroyNotify) g_object_unref); + g_object_unref (task); + return; + } + } + mm_iface_modem_firmware_load_update_settings_in_port ( self, MM_PORT (mm_broadband_modem_mbim_peek_port_mbim (MM_BROADBAND_MODEM_MBIM (self))), -- cgit v1.2.3-70-g09d2