summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mm-modem-helpers-qmi.c133
-rw-r--r--src/mm-modem-helpers-qmi.h11
-rw-r--r--src/mm-shared-qmi.c58
3 files changed, 175 insertions, 27 deletions
diff --git a/src/mm-modem-helpers-qmi.c b/src/mm-modem-helpers-qmi.c
index 5df344786..b43005afd 100644
--- a/src/mm-modem-helpers-qmi.c
+++ b/src/mm-modem-helpers-qmi.c
@@ -302,15 +302,51 @@ dms_add_qmi_lte_bands (GArray *mm_bands,
}
}
+static void
+dms_add_extended_qmi_lte_bands (GArray *mm_bands,
+ GArray *extended_qmi_bands)
+{
+ guint i;
+
+ g_assert (mm_bands != NULL);
+
+ if (!extended_qmi_bands)
+ return;
+
+ for (i = 0; i < extended_qmi_bands->len; i++) {
+ guint16 val;
+
+ val = g_array_index (extended_qmi_bands, guint16, i);
+
+ /* MM_MODEM_BAND_EUTRAN_1 = 31,
+ * ...
+ * MM_MODEM_BAND_EUTRAN_71 = 101
+ */
+ if (val < 1 || val > 71)
+ mm_dbg ("Unexpected LTE band supported by module: EUTRAN %u", val);
+ else {
+ MMModemBand band;
+
+ band = (MMModemBand)(val + MM_MODEM_BAND_EUTRAN_1 - 1);
+ g_array_append_val (mm_bands, band);
+ }
+ }
+}
+
GArray *
mm_modem_bands_from_qmi_band_capabilities (QmiDmsBandCapability qmi_bands,
- QmiDmsLteBandCapability qmi_lte_bands)
+ QmiDmsLteBandCapability qmi_lte_bands,
+ GArray *extended_qmi_lte_bands)
{
GArray *mm_bands;
mm_bands = g_array_new (FALSE, FALSE, sizeof (MMModemBand));
dms_add_qmi_bands (mm_bands, qmi_bands);
- dms_add_qmi_lte_bands (mm_bands, qmi_lte_bands);
+
+ if (extended_qmi_lte_bands)
+ dms_add_extended_qmi_lte_bands (mm_bands, extended_qmi_lte_bands);
+ else
+ dms_add_qmi_lte_bands (mm_bands, qmi_lte_bands);
return mm_bands;
}
@@ -463,15 +499,57 @@ nas_add_qmi_lte_bands (GArray *mm_bands,
}
}
+static void
+nas_add_extended_qmi_lte_bands (GArray *mm_bands,
+ const guint64 *extended_qmi_lte_bands,
+ guint extended_qmi_lte_bands_size)
+{
+ guint i;
+
+ g_assert (mm_bands != NULL);
+
+ for (i = 0; i < extended_qmi_lte_bands_size; i++) {
+ guint j;
+
+ for (j = 0; j < 64; j++) {
+ guint val;
+
+ if (!(extended_qmi_lte_bands[i] & (((guint64) 1) << j)))
+ continue;
+
+ val = 1 + j + (i * 64);
+
+ /* MM_MODEM_BAND_EUTRAN_1 = 31,
+ * ...
+ * MM_MODEM_BAND_EUTRAN_71 = 101
+ */
+ if (val < 1 || val > 71)
+ mm_dbg ("Unexpected LTE band supported by module: EUTRAN %u", val);
+ else {
+ MMModemBand band;
+
+ band = (val + MM_MODEM_BAND_EUTRAN_1 - 1);
+ g_array_append_val (mm_bands, band);
+ }
+ }
+ }
+}
+
GArray *
mm_modem_bands_from_qmi_band_preference (QmiNasBandPreference qmi_bands,
- QmiNasLteBandPreference qmi_lte_bands)
+ QmiNasLteBandPreference qmi_lte_bands,
+ const guint64 *extended_qmi_lte_bands,
+ guint extended_qmi_lte_bands_size)
{
GArray *mm_bands;
mm_bands = g_array_new (FALSE, FALSE, sizeof (MMModemBand));
nas_add_qmi_bands (mm_bands, qmi_bands);
- nas_add_qmi_lte_bands (mm_bands, qmi_lte_bands);
+
+ if (extended_qmi_lte_bands && extended_qmi_lte_bands_size)
+ nas_add_extended_qmi_lte_bands (mm_bands, extended_qmi_lte_bands, extended_qmi_lte_bands_size);
+ else
+ nas_add_qmi_lte_bands (mm_bands, qmi_lte_bands);
return mm_bands;
}
@@ -479,32 +557,53 @@ mm_modem_bands_from_qmi_band_preference (QmiNasBandPreference qmi_bands,
void
mm_modem_bands_to_qmi_band_preference (GArray *mm_bands,
QmiNasBandPreference *qmi_bands,
- QmiNasLteBandPreference *qmi_lte_bands)
+ QmiNasLteBandPreference *qmi_lte_bands,
+ guint64 *extended_qmi_lte_bands,
+ guint extended_qmi_lte_bands_size)
{
guint i;
*qmi_bands = 0;
*qmi_lte_bands = 0;
+ for (i = 0; i < extended_qmi_lte_bands_size; i++)
+ extended_qmi_lte_bands[i] = 0;
for (i = 0; i < mm_bands->len; i++) {
MMModemBand band;
band = g_array_index (mm_bands, MMModemBand, i);
- if (band >= MM_MODEM_BAND_EUTRAN_1 && band <= MM_MODEM_BAND_EUTRAN_44) {
- /* Add LTE band preference */
- guint j;
-
- for (j = 0; j < G_N_ELEMENTS (nas_lte_bands_map); j++) {
- if (nas_lte_bands_map[j].mm_band == band) {
- *qmi_lte_bands |= nas_lte_bands_map[j].qmi_band;
- break;
+ if (band >= MM_MODEM_BAND_EUTRAN_1 && band <= MM_MODEM_BAND_EUTRAN_71) {
+ if (extended_qmi_lte_bands && extended_qmi_lte_bands_size) {
+ /* Add extended LTE band preference */
+ guint val;
+ guint j;
+ guint k;
+
+ /* it's really (band - MM_MODEM_BAND_EUTRAN_1 +1 -1), because
+ * we want EUTRAN1 in index 0 */
+ val = band - MM_MODEM_BAND_EUTRAN_1;
+ j = val / 64;
+ g_assert (j < extended_qmi_lte_bands_size);
+ k = val % 64;
+
+ mm_dbg ("band %u ---> j %u, k %u", band, j, k);
+ extended_qmi_lte_bands[j] |= ((guint64)1 << k);
+ } else {
+ /* Add LTE band preference */
+ guint j;
+
+ for (j = 0; j < G_N_ELEMENTS (nas_lte_bands_map); j++) {
+ if (nas_lte_bands_map[j].mm_band == band) {
+ *qmi_lte_bands |= nas_lte_bands_map[j].qmi_band;
+ break;
+ }
}
- }
- if (j == G_N_ELEMENTS (nas_lte_bands_map))
- mm_dbg ("Cannot add the following LTE band: '%s'",
- mm_modem_band_get_string (band));
+ if (j == G_N_ELEMENTS (nas_lte_bands_map))
+ mm_dbg ("Cannot add the following LTE band: '%s'",
+ mm_modem_band_get_string (band));
+ }
} else {
/* Add non-LTE band preference */
guint j;
diff --git a/src/mm-modem-helpers-qmi.h b/src/mm-modem-helpers-qmi.h
index 1deea7c36..a51c4f66e 100644
--- a/src/mm-modem-helpers-qmi.h
+++ b/src/mm-modem-helpers-qmi.h
@@ -35,7 +35,8 @@ gboolean mm_pin_enabled_from_qmi_uim_pin_status (QmiDmsUimPinStatus status);
QmiDmsUimFacility mm_3gpp_facility_to_qmi_uim_facility (MMModem3gppFacility mm);
GArray *mm_modem_bands_from_qmi_band_capabilities (QmiDmsBandCapability qmi_bands,
- QmiDmsLteBandCapability qmi_lte_bands);
+ QmiDmsLteBandCapability qmi_lte_bands,
+ GArray *extended_qmi_lte_bands);
/*****************************************************************************/
/* QMI/NAS to MM translations */
@@ -77,10 +78,14 @@ QmiNasGsmWcdmaAcquisitionOrderPreference mm_modem_mode_to_qmi_gsm_wcdma_acquisit
GArray *mm_modem_bands_from_qmi_rf_band_information_array (GArray *info_array);
GArray *mm_modem_bands_from_qmi_band_preference (QmiNasBandPreference qmi_bands,
- QmiNasLteBandPreference qmi_lte_bands);
+ QmiNasLteBandPreference qmi_lte_bands,
+ const guint64 *extended_qmi_lte_bands,
+ guint extended_qmi_lte_bands_size);
void mm_modem_bands_to_qmi_band_preference (GArray *mm_bands,
QmiNasBandPreference *qmi_bands,
- QmiNasLteBandPreference *qmi_lte_bands);
+ QmiNasLteBandPreference *qmi_lte_bands,
+ guint64 *extended_qmi_lte_bands,
+ guint extended_qmi_lte_bands_size);
MMModem3gppRegistrationState mm_modem_3gpp_registration_state_from_qmi_registration_state (QmiNasAttachState attach_state,
QmiNasRegistrationState registration_state,
diff --git a/src/mm-shared-qmi.c b/src/mm-shared-qmi.c
index aff43fd50..f3a1a47c3 100644
--- a/src/mm-shared-qmi.c
+++ b/src/mm-shared-qmi.c
@@ -53,6 +53,7 @@ typedef struct {
GArray *supported_radio_interfaces;
Feature feature_nas_technology_preference;
Feature feature_nas_system_selection_preference;
+ Feature feature_extended_lte_band_preference;
gboolean disable_4g_only_mode;
GArray *supported_bands;
@@ -1485,6 +1486,7 @@ dms_get_band_capabilities_ready (QmiClientDms *client,
GArray *mm_bands = NULL;
QmiDmsBandCapability qmi_bands = 0;
QmiDmsLteBandCapability qmi_lte_bands = 0;
+ GArray *extended_qmi_lte_bands = NULL;
self = g_task_get_source_object (task);
priv = get_private (self);
@@ -1503,8 +1505,12 @@ dms_get_band_capabilities_ready (QmiClientDms *client,
output,
&qmi_lte_bands,
NULL);
+ qmi_message_dms_get_band_capabilities_output_get_extended_lte_band_capability (
+ output,
+ &extended_qmi_lte_bands,
+ NULL);
- mm_bands = mm_modem_bands_from_qmi_band_capabilities (qmi_bands, qmi_lte_bands);
+ mm_bands = mm_modem_bands_from_qmi_band_capabilities (qmi_bands, qmi_lte_bands, extended_qmi_lte_bands);
if (mm_bands->len == 0) {
g_clear_pointer (&mm_bands, g_array_unref);
error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
@@ -1568,11 +1574,18 @@ load_bands_get_system_selection_preference_ready (QmiClientNas *client,
GAsyncResult *res,
GTask *task)
{
+ MMSharedQmi *self;
+ Private *priv;
QmiMessageNasGetSystemSelectionPreferenceOutput *output = NULL;
GError *error = NULL;
GArray *mm_bands = NULL;
QmiNasBandPreference band_preference_mask = 0;
QmiNasLteBandPreference lte_band_preference_mask = 0;
+ guint64 extended_lte_band_preference[4] = { 0 };
+ guint extended_lte_band_preference_size = 0;
+
+ self = g_task_get_source_object (task);
+ priv = get_private (self);
output = qmi_client_nas_get_system_selection_preference_finish (client, res, &error);
if (!output || !qmi_message_nas_get_system_selection_preference_output_get_result (output, &error)) {
@@ -1590,7 +1603,22 @@ load_bands_get_system_selection_preference_ready (QmiClientNas *client,
&lte_band_preference_mask,
NULL);
- mm_bands = mm_modem_bands_from_qmi_band_preference (band_preference_mask, lte_band_preference_mask);
+ if (qmi_message_nas_get_system_selection_preference_output_get_extended_lte_band_preference (
+ output,
+ &extended_lte_band_preference[0],
+ &extended_lte_band_preference[1],
+ &extended_lte_band_preference[2],
+ &extended_lte_band_preference[3],
+ NULL))
+ extended_lte_band_preference_size = G_N_ELEMENTS (extended_lte_band_preference);
+
+ if (G_UNLIKELY (priv->feature_extended_lte_band_preference == FEATURE_UNKNOWN))
+ priv->feature_extended_lte_band_preference = extended_lte_band_preference_size ? FEATURE_SUPPORTED : FEATURE_UNSUPPORTED;
+
+ mm_bands = mm_modem_bands_from_qmi_band_preference (band_preference_mask,
+ lte_band_preference_mask,
+ extended_lte_band_preference_size ? extended_lte_band_preference : NULL,
+ extended_lte_band_preference_size);
if (mm_bands->len == 0) {
g_clear_pointer (&mm_bands, g_array_unref);
@@ -1680,6 +1708,7 @@ mm_shared_qmi_set_current_bands (MMIfaceModem *self,
QmiClient *client = NULL;
QmiNasBandPreference qmi_bands = 0;
QmiNasLteBandPreference qmi_lte_bands = 0;
+ guint64 extended_qmi_lte_bands[4] = { 0 };
if (!mm_shared_qmi_ensure_client (MM_SHARED_QMI (self),
QMI_SERVICE_NAS, &client,
@@ -1697,14 +1726,29 @@ mm_shared_qmi_set_current_bands (MMIfaceModem *self,
g_object_unref (task);
return;
}
- mm_modem_bands_to_qmi_band_preference (priv->supported_bands, &qmi_bands, &qmi_lte_bands);
- } else
- mm_modem_bands_to_qmi_band_preference (bands_array, &qmi_bands, &qmi_lte_bands);
+ bands_array = priv->supported_bands;
+ }
+
+ mm_modem_bands_to_qmi_band_preference (bands_array,
+ &qmi_bands,
+ &qmi_lte_bands,
+ priv->feature_extended_lte_band_preference == FEATURE_SUPPORTED ? extended_qmi_lte_bands : NULL,
+ G_N_ELEMENTS (extended_qmi_lte_bands));
input = qmi_message_nas_set_system_selection_preference_input_new ();
qmi_message_nas_set_system_selection_preference_input_set_band_preference (input, qmi_bands, NULL);
- if (mm_iface_modem_is_3gpp_lte (self))
- qmi_message_nas_set_system_selection_preference_input_set_lte_band_preference (input, qmi_lte_bands, NULL);
+ if (mm_iface_modem_is_3gpp_lte (self)) {
+ if (priv->feature_extended_lte_band_preference == FEATURE_SUPPORTED)
+ qmi_message_nas_set_system_selection_preference_input_set_extended_lte_band_preference (
+ input,
+ extended_qmi_lte_bands[0],
+ extended_qmi_lte_bands[1],
+ extended_qmi_lte_bands[2],
+ extended_qmi_lte_bands[3],
+ NULL);
+ else
+ qmi_message_nas_set_system_selection_preference_input_set_lte_band_preference (input, qmi_lte_bands, NULL);
+ }
qmi_message_nas_set_system_selection_preference_input_set_change_duration (input, QMI_NAS_CHANGE_DURATION_PERMANENT, NULL);
qmi_client_nas_set_system_selection_preference (