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'
This commit is contained in:
@@ -2118,6 +2118,7 @@ typedef struct {
|
|||||||
PortOpenStep step;
|
PortOpenStep step;
|
||||||
gboolean set_data_format;
|
gboolean set_data_format;
|
||||||
MMPortQmiKernelDataMode kernel_data_modes;
|
MMPortQmiKernelDataMode kernel_data_modes;
|
||||||
|
gboolean ctl_raw_ip_unsupported;
|
||||||
} PortOpenContext;
|
} PortOpenContext;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -2174,13 +2175,29 @@ qmi_device_open_second_ready (QmiDevice *qmi_device,
|
|||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
GTask *task)
|
GTask *task)
|
||||||
{
|
{
|
||||||
MMPortQmi *self;
|
MMPortQmi *self;
|
||||||
PortOpenContext *ctx;
|
PortOpenContext *ctx;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
self = g_task_get_source_object (task);
|
self = g_task_get_source_object (task);
|
||||||
ctx = g_task_get_task_data (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
|
/* If the open with CTL data format is sucessful, update all settings
|
||||||
* that we would have received with the internal setup data format
|
* that we would have received with the internal setup data format
|
||||||
* process */
|
* process */
|
||||||
@@ -2415,6 +2432,10 @@ port_open_step (GTask *task)
|
|||||||
|
|
||||||
ctx->kernel_data_modes = load_current_kernel_data_modes (self, ctx->device);
|
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 */
|
/* Need to reopen setting 802.3/raw-ip using CTL */
|
||||||
if (ctx->kernel_data_modes & MM_PORT_QMI_KERNEL_DATA_MODE_RAW_IP)
|
if (ctx->kernel_data_modes & MM_PORT_QMI_KERNEL_DATA_MODE_RAW_IP)
|
||||||
open_flags |= QMI_DEVICE_OPEN_FLAGS_NET_RAW_IP;
|
open_flags |= QMI_DEVICE_OPEN_FLAGS_NET_RAW_IP;
|
||||||
|
Reference in New Issue
Block a user