diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2021-07-22 15:59:18 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2021-07-27 00:39:29 +0200 |
commit | 9be34affe25d317c4391be38d2a1887ac785d76a (patch) | |
tree | e63d3f8d3249cffeb51065d504ea9cc9c118c176 /src | |
parent | 939cf166dd43a3cebd17b1a29b52cdc300f8f7e9 (diff) |
port-qmi: support devices that only run in 802.3 mode
E.g. the ZTE MF190 has a very old QMI firmware that is not able to run
CTL Set Data Format (raw-ip).
ModemManager[666366]: [/dev/cdc-wdm0] QMI Device supports 4 services:
ModemManager[666366]: [/dev/cdc-wdm0] ctl (1.2)
ModemManager[666366]: [/dev/cdc-wdm0] wds (1.3)
ModemManager[666366]: [/dev/cdc-wdm0] dms (1.2)
ModemManager[666366]: [/dev/cdc-wdm0] nas (1.0)
ModemManager[666366]: [/dev/cdc-wdm0] Setting network port data format...
ModemManager[666366]: [/dev/cdc-wdm0] Sent message...
<<<<<< RAW:
<<<<<< length = 21
<<<<<< data = 01:14:00:00:00:00:00:03:26:00:09:00:10:02:00:02:00:01:01:00:00
ModemManager[666366]: [/dev/cdc-wdm0] Sent generic request (translated)...
<<<<<< QMUX:
<<<<<< length = 20
<<<<<< flags = 0x00
<<<<<< service = "ctl"
<<<<<< client = 0
<<<<<< QMI:
<<<<<< flags = "none"
<<<<<< transaction = 3
<<<<<< tlv_length = 9
<<<<<< message = "Set Data Format" (0x0026)
<<<<<< TLV:
<<<<<< type = "Protocol" (0x10)
<<<<<< length = 2
<<<<<< value = 02:00
<<<<<< translated = raw-ip
<<<<<< TLV:
<<<<<< type = "Format" (0x01)
<<<<<< length = 1
<<<<<< value = 00
<<<<<< translated = absent
ModemManager[666366]: [/dev/cdc-wdm0] Received message...
<<<<<< RAW:
<<<<<< length = 19
<<<<<< data = 01:12:00:80:00:00:01:03:26:00:07:00:02:04:00:01:00:2D:00
ModemManager[666366]: [/dev/cdc-wdm0] Received generic response (translated)...
<<<<<< QMUX:
<<<<<< length = 18
<<<<<< flags = 0x80
<<<<<< service = "ctl"
<<<<<< client = 0
<<<<<< QMI:
<<<<<< flags = "response"
<<<<<< transaction = 3
<<<<<< tlv_length = 7
<<<<<< message = "Set Data Format" (0x0026)
<<<<<< TLV:
<<<<<< type = "Result" (0x02)
<<<<<< length = 4
<<<<<< value = 01:00:2D:00
<<<<<< translated = FAILURE: InvalidDataFormat
ModemManager[666366]: <debug> [1626961628.001354] [cdc-wdm0/qmi] QMI port open operation failed: QMI protocol error (45): 'InvalidDataFormat'
ModemManager[666366]: <warn> [1626961628.002563] [modem0] couldn't start initialization: QMI protocol error (45): 'InvalidDataFormat'
ModemManager[666366]: <warn> [1626961628.004181] [modem0] couldn't initialize: 'Modem is unusable, cannot fully initialize'
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-port-qmi.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/src/mm-port-qmi.c b/src/mm-port-qmi.c index eb7ccbc6..ba81452d 100644 --- a/src/mm-port-qmi.c +++ b/src/mm-port-qmi.c @@ -2118,6 +2118,7 @@ typedef struct { PortOpenStep step; gboolean set_data_format; MMPortQmiKernelDataMode kernel_data_modes; + gboolean ctl_raw_ip_unsupported; } PortOpenContext; static void @@ -2174,13 +2175,29 @@ qmi_device_open_second_ready (QmiDevice *qmi_device, GAsyncResult *res, GTask *task) { - MMPortQmi *self; - PortOpenContext *ctx; + MMPortQmi *self; + PortOpenContext *ctx; + g_autoptr(GError) error = NULL; self = g_task_get_source_object (task); ctx = g_task_get_task_data (task); - if (qmi_device_open_finish (qmi_device, res, &ctx->error)) { + if (!qmi_device_open_finish (qmi_device, res, &error)) { + /* Not all devices support raw-ip, which is the first thing we try + * by default. Detect this case, and retry with 802.3 if so. */ + if ((g_strcmp0 (self->priv->net_driver, "qmi_wwan") == 0) && + g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_INVALID_DATA_FORMAT) && + (ctx->kernel_data_modes & MM_PORT_QMI_KERNEL_DATA_MODE_RAW_IP)) { + /* switch to 802.3 right away, so that the logic can successfully go on after that */ + qmi_device_set_expected_data_format (qmi_device, QMI_DEVICE_EXPECTED_DATA_FORMAT_802_3, NULL); + ctx->ctl_raw_ip_unsupported = TRUE; + port_open_step (task); + return; + } + + /* Otherwise, fatal */ + ctx->error = g_steal_pointer (&error); + } else { /* If the open with CTL data format is sucessful, update all settings * that we would have received with the internal setup data format * process */ @@ -2415,6 +2432,10 @@ port_open_step (GTask *task) ctx->kernel_data_modes = load_current_kernel_data_modes (self, ctx->device); + /* Skip trying raw-ip if we already tried and it failed */ + if (ctx->ctl_raw_ip_unsupported) + ctx->kernel_data_modes &= ~MM_PORT_QMI_KERNEL_DATA_MODE_RAW_IP; + /* Need to reopen setting 802.3/raw-ip using CTL */ if (ctx->kernel_data_modes & MM_PORT_QMI_KERNEL_DATA_MODE_RAW_IP) open_flags |= QMI_DEVICE_OPEN_FLAGS_NET_RAW_IP; |