diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2021-02-25 22:12:04 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2021-03-10 15:17:59 +0100 |
commit | 4f4ce02c434423afbea81679d62cf9ecc09b6599 (patch) | |
tree | b42098b7470d82baec57f03cd18c62587ac1cc3a /src | |
parent | 499d954857fcfe7406aa7b1f724c8552e395391b (diff) |
port-qmi: compute max amount of multiplexed links supported
For the qmi_wwan driver, we have imposed a limitation of max 4 links
when using the add_mux/del_mux interface, because we're forced to
precreate links before multiplexing may be enabled.
When using rmnet over qmi_wwan, or rmnet over other drivers, we don't
have any limitation other than the one imposed by the WDA protocol
itself. The amount of links that may be created in this case is
1 + (QMI_DEVICE_MUX_ID_MAX - QMI_DEVICE_MUX_ID_MIN).
This information is loaded in the MMPortQmi, used to create the
MMBearerList in the QMI modem, and finally populated in the
'MaxActiveMultiplexedBearers' property of the modem interface.
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-broadband-modem-qmi.c | 34 | ||||
-rw-r--r-- | src/mm-port-qmi.c | 50 | ||||
-rw-r--r-- | src/mm-port-qmi.h | 1 |
3 files changed, 84 insertions, 1 deletions
diff --git a/src/mm-broadband-modem-qmi.c b/src/mm-broadband-modem-qmi.c index aea6cbf1..879e9fcf 100644 --- a/src/mm-broadband-modem-qmi.c +++ b/src/mm-broadband-modem-qmi.c @@ -333,6 +333,37 @@ modem_create_bearer (MMIfaceModem *self, } /*****************************************************************************/ +/* Create Bearer List (Modem interface) */ + +static MMBearerList * +modem_create_bearer_list (MMIfaceModem *self) +{ + MMPortQmi *port; + guint n; + guint n_multiplexed; + + /* The maximum number of available/connected modems is guessed from + * the size of the data ports list. */ + n = g_list_length (mm_base_modem_peek_data_ports (MM_BASE_MODEM (self))); + mm_obj_dbg (self, "allowed up to %u active bearers", n); + + /* The maximum number of multiplexed links is retrieved from the + * MMPortQmi */ + + port = mm_broadband_modem_qmi_peek_port_qmi (MM_BROADBAND_MODEM_QMI (self)); + if (!port) { + mm_obj_warn (self, "no port to query maximum number of supported network links"); + n_multiplexed = 0; + } else { + n_multiplexed = mm_port_qmi_get_max_multiplexed_links (port); + mm_obj_dbg (self, "allowed up to %u active multiplexed bearers", n_multiplexed); + } + + /* by default, no multiplexing support */ + return mm_bearer_list_new (n, n_multiplexed); +} + +/*****************************************************************************/ /* Manufacturer loading (Modem interface) */ static gchar * @@ -10379,9 +10410,10 @@ iface_modem_init (MMIfaceModem *iface) iface->setup_sim_hot_swap = mm_shared_qmi_setup_sim_hot_swap; iface->setup_sim_hot_swap_finish = mm_shared_qmi_setup_sim_hot_swap_finish; - /* Create QMI-specific bearer */ + /* Create QMI-specific bearer and bearer list */ iface->create_bearer = modem_create_bearer; iface->create_bearer_finish = modem_create_bearer_finish; + iface->create_bearer_list = modem_create_bearer_list; /* Other actions */ iface->reset = mm_shared_qmi_reset; diff --git a/src/mm-port-qmi.c b/src/mm-port-qmi.c index 82560e95..759a9196 100644 --- a/src/mm-port-qmi.c +++ b/src/mm-port-qmi.c @@ -50,6 +50,7 @@ struct _MMPortQmiPrivate { gboolean wda_unsupported; QmiWdaLinkLayerProtocol llp; QmiWdaDataAggregationProtocol dap; + guint max_multiplexed_links; /* preallocated links */ MMPort *preallocated_links_master; GArray *preallocated_links; @@ -965,6 +966,12 @@ mm_port_qmi_get_data_aggregation_protocol (MMPortQmi *self) return self->priv->dap; } +guint +mm_port_qmi_get_max_multiplexed_links (MMPortQmi *self) +{ + return self->priv->max_multiplexed_links; +} + /*****************************************************************************/ static QmiDeviceExpectedDataFormat @@ -999,12 +1006,14 @@ load_kernel_data_format_capabilities (MMPortQmi *self, QmiDevice *device, gboolean *supports_802_3, gboolean *supports_raw_ip, + gboolean *supports_qmap_raw_ip, gboolean *supports_qmap_pass_through) { /* For any driver other than qmi_wwan, assume raw-ip */ if (mm_port_get_subsys (MM_PORT (self)) != MM_PORT_SUBSYS_USBMISC) { *supports_802_3 = FALSE; *supports_raw_ip = TRUE; + *supports_qmap_raw_ip = TRUE; *supports_qmap_pass_through = FALSE; return; } @@ -1014,10 +1023,19 @@ load_kernel_data_format_capabilities (MMPortQmi *self, QMI_DEVICE_EXPECTED_DATA_FORMAT_RAW_IP, NULL); if (!*supports_raw_ip) { + *supports_qmap_raw_ip = FALSE; *supports_qmap_pass_through = FALSE; return; } + /* We switch to raw-ip to see if we can do link management with qmi_wwan. + * This switch would not truly be required, but the logic afterwards is robust + * enough to support this, nothing to worry about */ + if (qmi_device_set_expected_data_format (device, QMI_DEVICE_EXPECTED_DATA_FORMAT_RAW_IP, NULL)) + *supports_qmap_raw_ip = qmi_device_check_link_supported (device, NULL); + else + *supports_qmap_raw_ip = FALSE; + *supports_qmap_pass_through = qmi_device_check_expected_data_format_supported (device, QMI_DEVICE_EXPECTED_DATA_FORMAT_QMAP_PASS_THROUGH, NULL); @@ -1072,6 +1090,7 @@ typedef struct { QmiDeviceExpectedDataFormat kernel_data_format_requested; gboolean kernel_data_format_802_3_supported; gboolean kernel_data_format_raw_ip_supported; + gboolean kernel_data_format_qmap_raw_ip_supported; gboolean kernel_data_format_qmap_pass_through_supported; gboolean link_management_supported; @@ -1108,6 +1127,7 @@ internal_setup_data_format_finish (MMPortQmi *self, QmiDeviceExpectedDataFormat *out_kernel_data_format, QmiWdaLinkLayerProtocol *out_llp, QmiWdaDataAggregationProtocol *out_dap, + guint *out_max_multiplexed_links, GError **error) { InternalSetupDataFormatContext *ctx; @@ -1120,6 +1140,32 @@ internal_setup_data_format_finish (MMPortQmi *self, *out_llp = ctx->wda_llp_current; g_assert (ctx->wda_dl_dap_current == ctx->wda_ul_dap_current); *out_dap = ctx->wda_dl_dap_current; + + if (out_max_multiplexed_links) { + if (!ctx->wda_dap_supported) { + *out_max_multiplexed_links = 0; + mm_obj_dbg (self, "wda data aggregation protocol unsupported: no multiplexed bearers allowed"); + } else { + /* if multiplex backend may be rmnet, MAX-MIN */ + if ((mm_port_get_subsys (MM_PORT (self)) != MM_PORT_SUBSYS_USBMISC) || + ctx->kernel_data_format_qmap_pass_through_supported) { + *out_max_multiplexed_links = 1 + (QMI_DEVICE_MUX_ID_MAX - QMI_DEVICE_MUX_ID_MIN); + mm_obj_dbg (self, "rmnet link management supported: %u multiplexed bearers allowed", + *out_max_multiplexed_links); + } + /* if multiplex backend may be qmi_wwan, the max preallocated amount :/ */ + else if ((mm_port_get_subsys (MM_PORT (self)) == MM_PORT_SUBSYS_USBMISC) && + ctx->kernel_data_format_qmap_raw_ip_supported) { + *out_max_multiplexed_links = DEFAULT_LINK_PREALLOCATED_AMOUNT; + mm_obj_dbg (self, "qmi_wwan link management supported: %u multiplexed bearers allowed", + *out_max_multiplexed_links); + } else { + *out_max_multiplexed_links = 0; + mm_obj_dbg (self, "qmi_wwan link management unsupported: no multiplexed bearers allowed"); + } + } + } + return TRUE; } @@ -1501,6 +1547,7 @@ internal_setup_data_format_context_step (GTask *task) ctx->device, &ctx->kernel_data_format_802_3_supported, &ctx->kernel_data_format_raw_ip_supported, + &ctx->kernel_data_format_qmap_raw_ip_supported, &ctx->kernel_data_format_qmap_pass_through_supported); ctx->step++; /* Fall through */ @@ -1703,6 +1750,7 @@ internal_setup_data_format_ready (MMPortQmi *self, &self->priv->kernel_data_format, &self->priv->llp, &self->priv->dap, + NULL, /* not expected to update */ &error)) g_task_return_error (task, error); else @@ -1933,6 +1981,7 @@ qmi_device_open_second_ready (QmiDevice *qmi_device, else g_assert_not_reached (); self->priv->dap = QMI_WDA_DATA_AGGREGATION_PROTOCOL_DISABLED; + self->priv->max_multiplexed_links = 0; } /* In both error and success, we go to last step */ @@ -1974,6 +2023,7 @@ open_internal_setup_data_format_ready (MMPortQmi *self, &self->priv->kernel_data_format, &self->priv->llp, &self->priv->dap, + &self->priv->max_multiplexed_links, &error)) { /* Continue with fallback to LLP requested via CTL */ mm_obj_warn (self, "Couldn't setup data format: %s", error->message); diff --git a/src/mm-port-qmi.h b/src/mm-port-qmi.h index e03c262f..61369a43 100644 --- a/src/mm-port-qmi.h +++ b/src/mm-port-qmi.h @@ -99,6 +99,7 @@ guint mm_port_qmi_get_endpoint_interface_number (MMPortQmi *self); QmiWdaLinkLayerProtocol mm_port_qmi_get_link_layer_protocol (MMPortQmi *self); QmiWdaDataAggregationProtocol mm_port_qmi_get_data_aggregation_protocol (MMPortQmi *self); +guint mm_port_qmi_get_max_multiplexed_links (MMPortQmi *self); typedef enum { MM_PORT_QMI_SETUP_DATA_FORMAT_ACTION_QUERY, |