intel: XMM7360: Allow re-trying the first RPC init command command once

It seems that the very first XMM7360 RPC init command often times out after
resuming the laptop from s2idle for unknown reasons.
This makes the modem unusable in such situation until the next sleep/resume
cycle.

Re-trying this RPC command allows the modem to initialize normally.

It's possible that this is a kernel iosm driver or modem firmware issue
but considering that the kernel driver seems orphaned by Intel and one
can't really expect much firmware support for this modem either let's do
the easiest thing and simply allow retrying (once) the very first RPC init
command if it fails or times out.

Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
This commit is contained in:
Maciej S. Szmigiero
2025-06-14 16:02:23 -05:00
committed by Dan Williams
parent 4c319181e2
commit 0d29f6dfa5
4 changed files with 36 additions and 10 deletions
+2
View File
@@ -674,6 +674,7 @@ static const MMBroadbandModemXmm7360RpcCommand disconnect_sequence[] = {
},
3,
FALSE,
FALSE,
mm_broadband_modem_xmm7360_rpc_response_processor_continue_on_success
/* response will be: L(0x0) L(0x0) L(0x5dffffff) L(0x0) (meaning unknown) */
},
@@ -687,6 +688,7 @@ static const MMBroadbandModemXmm7360RpcCommand disconnect_sequence[] = {
},
3,
FALSE,
FALSE,
mm_broadband_modem_xmm7360_rpc_response_processor_final
/* response will be: L(0x0) (meaning unknown) */
},
@@ -84,6 +84,7 @@ typedef struct {
gulong cancelled_id;
GCancellable *parent_cancellable;
const MMBroadbandModemXmm7360RpcCommand *current;
gboolean current_retry;
const MMBroadbandModemXmm7360RpcCommand *sequence;
guint next_command_wait_id;
} RpcSequenceContext;
@@ -152,6 +153,7 @@ rpc_sequence_parse_response (MMPortSerialXmmrpcXmm7360 *port,
RpcSequenceContext *ctx;
Xmm7360RpcResponse *response = NULL;
g_autoptr(GError) command_error = NULL;
gboolean command_retry = FALSE;
response = mm_port_serial_xmmrpc_xmm7360_command_finish (port, res, &command_error);
@@ -173,6 +175,20 @@ rpc_sequence_parse_response (MMPortSerialXmmrpcXmm7360 *port,
next->callid ? FALSE : TRUE, /* Last command in sequence? */
command_error,
&result_error);
if (processor_result == MM_BROADBAND_MODEM_XMM7360_RPC_RESPONSE_PROCESSOR_RESULT_FAILURE
&& ctx->current->allow_retry_once && !ctx->current_retry) {
mm_obj_warn (port, "Command failed (%s), retrying once",
result_error ? result_error->message : "UNKNOWN");
if (response)
xmm7360_rpc_response_free (response);
g_clear_error (&result_error);
command_retry = TRUE;
goto skip_result;
}
switch (processor_result) {
case MM_BROADBAND_MODEM_XMM7360_RPC_RESPONSE_PROCESSOR_RESULT_CONTINUE:
g_assert (!result_error);
@@ -195,8 +211,14 @@ rpc_sequence_parse_response (MMPortSerialXmmrpcXmm7360 *port,
}
}
if (processor_result == MM_BROADBAND_MODEM_XMM7360_RPC_RESPONSE_PROCESSOR_RESULT_CONTINUE) {
ctx->current++;
skip_result:
if (processor_result == MM_BROADBAND_MODEM_XMM7360_RPC_RESPONSE_PROCESSOR_RESULT_CONTINUE ||
command_retry) {
if (!command_retry) {
ctx->current++;
}
ctx->current_retry = command_retry;
if (ctx->current->callid) {
g_assert (!ctx->next_command_wait_id);
ctx->next_command_wait_id = g_timeout_add_seconds (ctx->current->wait_seconds,
@@ -204,6 +226,7 @@ rpc_sequence_parse_response (MMPortSerialXmmrpcXmm7360 *port,
task);
return;
}
g_assert (!command_retry);
/* On last command, end. */
}
@@ -61,6 +61,7 @@ typedef struct {
guint timeout;
/* Flag to allow cached replies */
gboolean allow_cached;
gboolean allow_retry_once;
/* The response processor */
MMBroadbandModemXmm7360RpcResponseProcessor response_processor;
/* Time to wait before sending this command (in seconds) */
@@ -1090,14 +1090,14 @@ static const Xmm7360RpcMsgArg set_radio_signal_reporting_args[] = {
};
static const MMBroadbandModemXmm7360RpcCommand init_sequence[] = {
{ XMM7360_RPC_CALL_UTA_MS_SMS_INIT, FALSE, NULL, 3, FALSE, mm_broadband_modem_xmm7360_rpc_response_processor_continue_on_success },
{ XMM7360_RPC_CALL_UTA_MS_CBS_INIT, FALSE, NULL, 3, FALSE, mm_broadband_modem_xmm7360_rpc_response_processor_continue_on_success },
{ XMM7360_RPC_CALL_UTA_MS_NET_OPEN, FALSE, NULL, 3, FALSE, mm_broadband_modem_xmm7360_rpc_response_processor_continue_on_success },
{ XMM7360_RPC_CALL_UTA_MS_NET_SET_RADIO_SIGNAL_REPORTING, FALSE, set_radio_signal_reporting_args, 3, FALSE, mm_broadband_modem_xmm7360_rpc_response_processor_continue_on_success},
{ XMM7360_RPC_CALL_UTA_MS_CALL_CS_INIT, FALSE, NULL, 3, FALSE, mm_broadband_modem_xmm7360_rpc_response_processor_continue_on_success },
{ XMM7360_RPC_CALL_UTA_MS_CALL_PS_INITIALIZE, FALSE, NULL, 3, FALSE, mm_broadband_modem_xmm7360_rpc_response_processor_continue_on_success },
{ XMM7360_RPC_CALL_UTA_MS_SS_INIT, FALSE, NULL, 3, FALSE, mm_broadband_modem_xmm7360_rpc_response_processor_continue_on_success },
{ XMM7360_RPC_CALL_UTA_MS_SIM_OPEN_REQ, FALSE, NULL, 3, FALSE, mm_broadband_modem_xmm7360_rpc_response_processor_final },
{ XMM7360_RPC_CALL_UTA_MS_SMS_INIT, FALSE, NULL, 3, FALSE, TRUE, mm_broadband_modem_xmm7360_rpc_response_processor_continue_on_success },
{ XMM7360_RPC_CALL_UTA_MS_CBS_INIT, FALSE, NULL, 3, FALSE, FALSE, mm_broadband_modem_xmm7360_rpc_response_processor_continue_on_success },
{ XMM7360_RPC_CALL_UTA_MS_NET_OPEN, FALSE, NULL, 3, FALSE, FALSE, mm_broadband_modem_xmm7360_rpc_response_processor_continue_on_success },
{ XMM7360_RPC_CALL_UTA_MS_NET_SET_RADIO_SIGNAL_REPORTING, FALSE, set_radio_signal_reporting_args, 3, FALSE, FALSE, mm_broadband_modem_xmm7360_rpc_response_processor_continue_on_success},
{ XMM7360_RPC_CALL_UTA_MS_CALL_CS_INIT, FALSE, NULL, 3, FALSE, FALSE, mm_broadband_modem_xmm7360_rpc_response_processor_continue_on_success },
{ XMM7360_RPC_CALL_UTA_MS_CALL_PS_INITIALIZE, FALSE, NULL, 3, FALSE, FALSE, mm_broadband_modem_xmm7360_rpc_response_processor_continue_on_success },
{ XMM7360_RPC_CALL_UTA_MS_SS_INIT, FALSE, NULL, 3, FALSE, FALSE, mm_broadband_modem_xmm7360_rpc_response_processor_continue_on_success },
{ XMM7360_RPC_CALL_UTA_MS_SIM_OPEN_REQ, FALSE, NULL, 3, FALSE, FALSE, mm_broadband_modem_xmm7360_rpc_response_processor_final },
{ 0 }
};