mm-shared-qmi,mm-modem-helpers: Fix supported capabilities and modes for multimode device
We use capability switching logic exclusively for configuring GSM/UMTS+CDMA/EVDO devices (regardless of whether it has LTE/5GNR or not) to add or remove the GSM/UMTS and CDMA/EVDO capabilities. Based on the same logic, we will allow 4 combinations for GSM/UMTS+CDMA/EVDO+LTE+5GNR device: "GSM/UMTS+CDMA/EVDO+LTE+5GNR", "GSM/UMTS+LTE+5GNR", "CDMA/EVDO+LTE+5GNR" and "LTE+5GNR" Similarly, we will allow 4 combinations for GSM/UMTS+CDMA/EVDO+LTE device: "GSM/UMTS+CDMA/EVDO+LTE", "GSM/UMTS+LTE", "CDMA/EVDO+LTE" and "LTE" And, we will allow 3 combinations for GSM/UMTS+CDMA/EVDO device: "GSM/UMTS+CDMA/EVDO", "GSM/UMTS" and "CDMA/EVDO" Also, supported combination modes should be based on current capabilities and not entirely upon supported radio interfaces. 1) If current capability has "gsm-umts" or "cdma-evdo" or both, do not support 4G only, 5G only, or 4G+5G combination modes 2) If current capability neither has "gsm-umts" nor "cdma-evdo", only support combination modes involving 4G and 5G.
This commit is contained in:

committed by
Aleksander Morgado

parent
f05258e757
commit
38f067c4e4
@@ -13,6 +13,7 @@
|
|||||||
* Copyright (C) 2008 - 2009 Novell, Inc.
|
* Copyright (C) 2008 - 2009 Novell, Inc.
|
||||||
* Copyright (C) 2009 - 2012 Red Hat, Inc.
|
* Copyright (C) 2009 - 2012 Red Hat, Inc.
|
||||||
* Copyright (C) 2012 Google, Inc.
|
* Copyright (C) 2012 Google, Inc.
|
||||||
|
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
@@ -393,7 +394,6 @@ mm_filter_supported_modes (const GArray *all,
|
|||||||
MMModemModeCombination all_item;
|
MMModemModeCombination all_item;
|
||||||
guint i;
|
guint i;
|
||||||
GArray *filtered_combinations;
|
GArray *filtered_combinations;
|
||||||
gboolean all_item_added = FALSE;
|
|
||||||
|
|
||||||
g_return_val_if_fail (all != NULL, NULL);
|
g_return_val_if_fail (all != NULL, NULL);
|
||||||
g_return_val_if_fail (all->len == 1, NULL);
|
g_return_val_if_fail (all->len == 1, NULL);
|
||||||
@@ -416,8 +416,6 @@ mm_filter_supported_modes (const GArray *all,
|
|||||||
* containing all supported modes, we're already good to go. This allows us to have a
|
* containing all supported modes, we're already good to go. This allows us to have a
|
||||||
* default with preferred != NONE (e.g. Wavecom 2G modem with allowed=CS+2G and
|
* default with preferred != NONE (e.g. Wavecom 2G modem with allowed=CS+2G and
|
||||||
* preferred=2G */
|
* preferred=2G */
|
||||||
if (all_item.allowed == mode->allowed)
|
|
||||||
all_item_added = TRUE;
|
|
||||||
g_array_append_val (filtered_combinations, *mode);
|
g_array_append_val (filtered_combinations, *mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -425,12 +423,6 @@ mm_filter_supported_modes (const GArray *all,
|
|||||||
if (filtered_combinations->len == 0)
|
if (filtered_combinations->len == 0)
|
||||||
mm_obj_warn (log_object, "all supported mode combinations were filtered out");
|
mm_obj_warn (log_object, "all supported mode combinations were filtered out");
|
||||||
|
|
||||||
/* Add default entry with the generic mask including all items */
|
|
||||||
if (!all_item_added) {
|
|
||||||
mm_obj_dbg (log_object, "adding an explicit item with all supported modes allowed");
|
|
||||||
g_array_append_val (filtered_combinations, all_item);
|
|
||||||
}
|
|
||||||
|
|
||||||
mm_obj_dbg (log_object, "device supports %u different mode combinations",
|
mm_obj_dbg (log_object, "device supports %u different mode combinations",
|
||||||
filtered_combinations->len);
|
filtered_combinations->len);
|
||||||
|
|
||||||
|
@@ -77,7 +77,6 @@ typedef struct {
|
|||||||
Feature feature_nas_ssp_extended_lte_band_preference;
|
Feature feature_nas_ssp_extended_lte_band_preference;
|
||||||
Feature feature_nas_ssp_acquisition_order_preference;
|
Feature feature_nas_ssp_acquisition_order_preference;
|
||||||
GArray *feature_nas_ssp_acquisition_order_preference_array;
|
GArray *feature_nas_ssp_acquisition_order_preference_array;
|
||||||
gboolean disable_4g_only_mode;
|
|
||||||
GArray *supported_bands;
|
GArray *supported_bands;
|
||||||
|
|
||||||
/* Location helpers */
|
/* Location helpers */
|
||||||
@@ -1133,35 +1132,23 @@ mm_shared_qmi_load_supported_capabilities (MMIfaceModem *self,
|
|||||||
* switching only when switching GSM/UMTS+CDMA/EVDO multimode devices, and only if
|
* switching only when switching GSM/UMTS+CDMA/EVDO multimode devices, and only if
|
||||||
* we have support for the commands doing it.
|
* we have support for the commands doing it.
|
||||||
*/
|
*/
|
||||||
|
#define MULTIMODE (MM_MODEM_CAPABILITY_GSM_UMTS | MM_MODEM_CAPABILITY_CDMA_EVDO)
|
||||||
if (priv->feature_nas_tp == FEATURE_SUPPORTED || priv->feature_nas_ssp == FEATURE_SUPPORTED) {
|
if (priv->feature_nas_tp == FEATURE_SUPPORTED || priv->feature_nas_ssp == FEATURE_SUPPORTED) {
|
||||||
if (mask == (MM_MODEM_CAPABILITY_GSM_UMTS | MM_MODEM_CAPABILITY_CDMA_EVDO)) {
|
if ((mask & MULTIMODE) == MULTIMODE) {
|
||||||
/* Multimode GSM/UMTS+CDMA/EVDO device switched to GSM/UMTS only */
|
/* Multimode GSM/UMTS+CDMA/EVDO+(LTE/5GNR) device switched to GSM/UMTS+(LTE/5GNR) device */
|
||||||
single = MM_MODEM_CAPABILITY_GSM_UMTS;
|
single = MM_MODEM_CAPABILITY_GSM_UMTS | (MULTIMODE ^ mask);
|
||||||
g_array_append_val (supported_combinations, single);
|
g_array_append_val (supported_combinations, single);
|
||||||
/* Multimode GSM/UMTS+CDMA/EVDO device switched to CDMA/EVDO only */
|
/* Multimode GSM/UMTS+CDMA/EVDO+(LTE/5GNR) device switched to CDMA/EVDO+(LTE/5GNR) device */
|
||||||
single = MM_MODEM_CAPABILITY_CDMA_EVDO;
|
single = MM_MODEM_CAPABILITY_CDMA_EVDO | (MULTIMODE ^ mask);
|
||||||
g_array_append_val (supported_combinations, single);
|
|
||||||
} else if (mask == (MM_MODEM_CAPABILITY_GSM_UMTS | MM_MODEM_CAPABILITY_CDMA_EVDO | MM_MODEM_CAPABILITY_LTE)) {
|
|
||||||
/* Multimode GSM/UMTS+CDMA/EVDO+LTE device switched to GSM/UMTS+LTE only */
|
|
||||||
single = MM_MODEM_CAPABILITY_GSM_UMTS | MM_MODEM_CAPABILITY_LTE;
|
|
||||||
g_array_append_val (supported_combinations, single);
|
|
||||||
/* Multimode GSM/UMTS+CDMA/EVDO+LTE device switched to CDMA/EVDO+LTE only */
|
|
||||||
single = MM_MODEM_CAPABILITY_CDMA_EVDO | MM_MODEM_CAPABILITY_LTE;
|
|
||||||
g_array_append_val (supported_combinations, single);
|
g_array_append_val (supported_combinations, single);
|
||||||
/*
|
/*
|
||||||
* Multimode GSM/UMTS+CDMA/EVDO+LTE device switched to LTE only.
|
* Multimode GSM/UMTS+CDMA/EVDO+(LTE/5GNR) device switched to (LTE/5GNR) device
|
||||||
*
|
*
|
||||||
* This case is required because we use the same methods and operations to
|
* This case is required because we use the same methods and operations to
|
||||||
* switch capabilities and modes. For the LTE capability there is a direct
|
* switch capabilities and modes.
|
||||||
* related 4G mode, and so we cannot select a '4G only' mode in this device
|
*/
|
||||||
* because we wouldn't be able to know the full list of current capabilities
|
if ((single = (MULTIMODE ^ mask)))
|
||||||
* if the device was rebooted, as we would only see LTE capability. So,
|
g_array_append_val (supported_combinations, single);
|
||||||
* handle this special case so that the LTE/4G-only mode can exclusively be
|
|
||||||
* selected as capability switching in this kind of devices.
|
|
||||||
*/
|
|
||||||
priv->disable_4g_only_mode = TRUE;
|
|
||||||
single = MM_MODEM_CAPABILITY_LTE;
|
|
||||||
g_array_append_val (supported_combinations, single);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1731,6 +1718,7 @@ mm_shared_qmi_load_supported_modes (MMIfaceModem *self,
|
|||||||
|
|
||||||
priv = get_private (MM_SHARED_QMI (self));
|
priv = get_private (MM_SHARED_QMI (self));
|
||||||
g_assert (priv->supported_radio_interfaces);
|
g_assert (priv->supported_radio_interfaces);
|
||||||
|
g_assert (priv->current_capabilities);
|
||||||
|
|
||||||
/* Build all, based on the supported radio interfaces */
|
/* Build all, based on the supported radio interfaces */
|
||||||
mask_all = MM_MODEM_MODE_NONE;
|
mask_all = MM_MODEM_MODE_NONE;
|
||||||
@@ -1782,34 +1770,42 @@ mm_shared_qmi_load_supported_modes (MMIfaceModem *self,
|
|||||||
g_array_append_val (combinations, mode); \
|
g_array_append_val (combinations, mode); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
#define MULTIMODE (MM_MODEM_CAPABILITY_GSM_UMTS | MM_MODEM_CAPABILITY_CDMA_EVDO)
|
||||||
|
|
||||||
/* 2G-only, 3G-only */
|
if ((priv->current_capabilities & MULTIMODE)) {
|
||||||
ADD_MODE_PREFERENCE (MM_MODEM_MODE_2G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
|
/* 2G-only, 3G-only */
|
||||||
ADD_MODE_PREFERENCE (MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
|
ADD_MODE_PREFERENCE (MM_MODEM_MODE_2G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
|
||||||
|
ADD_MODE_PREFERENCE (MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
/* 4G-only mode is not possible in multimode GSM/UMTS+CDMA/EVDO+LTE
|
if (!(priv->current_capabilities & MULTIMODE)) {
|
||||||
* devices. This configuration may be selected as "LTE only" capability
|
/* 4G-only */
|
||||||
* instead. */
|
|
||||||
if (!priv->disable_4g_only_mode)
|
|
||||||
ADD_MODE_PREFERENCE (MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
|
ADD_MODE_PREFERENCE (MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
/* 2G, 3G, 4G combinations */
|
if ((priv->current_capabilities & MULTIMODE)) {
|
||||||
ADD_MODE_PREFERENCE (MM_MODEM_MODE_2G, MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
|
/* 2G, 3G, 4G combinations */
|
||||||
ADD_MODE_PREFERENCE (MM_MODEM_MODE_2G, MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
|
ADD_MODE_PREFERENCE (MM_MODEM_MODE_2G, MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
|
||||||
ADD_MODE_PREFERENCE (MM_MODEM_MODE_3G, MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
|
ADD_MODE_PREFERENCE (MM_MODEM_MODE_2G, MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
|
||||||
ADD_MODE_PREFERENCE (MM_MODEM_MODE_2G, MM_MODEM_MODE_3G, MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE);
|
ADD_MODE_PREFERENCE (MM_MODEM_MODE_3G, MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
|
||||||
|
ADD_MODE_PREFERENCE (MM_MODEM_MODE_2G, MM_MODEM_MODE_3G, MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
/* 5G related mode combinations are only supported when NAS SSP is supported,
|
/* 5G related mode combinations are only supported when NAS SSP is supported,
|
||||||
* as there is no 5G support in NAS TP. */
|
* as there is no 5G support in NAS TP. */
|
||||||
if (priv->feature_nas_ssp != FEATURE_UNSUPPORTED) {
|
if (priv->feature_nas_ssp != FEATURE_UNSUPPORTED) {
|
||||||
ADD_MODE_PREFERENCE (MM_MODEM_MODE_5G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
|
if (!(priv->current_capabilities & MULTIMODE)) {
|
||||||
ADD_MODE_PREFERENCE (MM_MODEM_MODE_2G, MM_MODEM_MODE_5G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
|
ADD_MODE_PREFERENCE (MM_MODEM_MODE_5G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
|
||||||
ADD_MODE_PREFERENCE (MM_MODEM_MODE_3G, MM_MODEM_MODE_5G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
|
ADD_MODE_PREFERENCE (MM_MODEM_MODE_4G, MM_MODEM_MODE_5G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
|
||||||
ADD_MODE_PREFERENCE (MM_MODEM_MODE_4G, MM_MODEM_MODE_5G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
|
}
|
||||||
ADD_MODE_PREFERENCE (MM_MODEM_MODE_2G, MM_MODEM_MODE_3G, MM_MODEM_MODE_5G, MM_MODEM_MODE_NONE);
|
if ((priv->current_capabilities & MULTIMODE)) {
|
||||||
ADD_MODE_PREFERENCE (MM_MODEM_MODE_2G, MM_MODEM_MODE_4G, MM_MODEM_MODE_5G, MM_MODEM_MODE_NONE);
|
ADD_MODE_PREFERENCE (MM_MODEM_MODE_2G, MM_MODEM_MODE_5G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
|
||||||
ADD_MODE_PREFERENCE (MM_MODEM_MODE_3G, MM_MODEM_MODE_4G, MM_MODEM_MODE_5G, MM_MODEM_MODE_NONE);
|
ADD_MODE_PREFERENCE (MM_MODEM_MODE_3G, MM_MODEM_MODE_5G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
|
||||||
ADD_MODE_PREFERENCE (MM_MODEM_MODE_2G, MM_MODEM_MODE_3G, MM_MODEM_MODE_4G, MM_MODEM_MODE_5G);
|
ADD_MODE_PREFERENCE (MM_MODEM_MODE_2G, MM_MODEM_MODE_3G, MM_MODEM_MODE_5G, MM_MODEM_MODE_NONE);
|
||||||
|
ADD_MODE_PREFERENCE (MM_MODEM_MODE_2G, MM_MODEM_MODE_4G, MM_MODEM_MODE_5G, MM_MODEM_MODE_NONE);
|
||||||
|
ADD_MODE_PREFERENCE (MM_MODEM_MODE_3G, MM_MODEM_MODE_4G, MM_MODEM_MODE_5G, MM_MODEM_MODE_NONE);
|
||||||
|
ADD_MODE_PREFERENCE (MM_MODEM_MODE_2G, MM_MODEM_MODE_3G, MM_MODEM_MODE_4G, MM_MODEM_MODE_5G);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Filter out unsupported modes */
|
/* Filter out unsupported modes */
|
||||||
|
Reference in New Issue
Block a user