platform: add wifi_can_concurrent API for interface combination check

Add nm_platform_wifi_can_concurrent() API to check if two interface
types can operate concurrently based on the hardware's interface
combination capabilities. This function bridges the low-level
nm_wifi_utils_can_concurrent() to upper layers.

The API accepts interface types (NL80211_IFTYPE_*) and returns whether
the hardware supports running them concurrently, along with the number
of different channels allowed.

This is part of the Wi-Fi P2P concurrent connections support.
This commit is contained in:
tinnci 2026-01-19 18:43:21 +08:00
parent 79c0730a7b
commit 716efd5377
5 changed files with 65 additions and 8 deletions

View file

@ -10329,6 +10329,18 @@ wifi_set_wake_on_wlan(NMPlatform *platform, int ifindex, _NMSettingWirelessWakeO
return nm_wifi_utils_set_wake_on_wlan(wifi_data, wowl);
}
static gboolean
wifi_can_concurrent(NMPlatform *platform,
int ifindex,
NMWifiIfaceType iftype1,
NMWifiIfaceType iftype2,
guint8 *out_num_channels)
{
WIFI_GET_WIFI_DATA_NETNS(wifi_data, platform, ifindex, FALSE);
return nm_wifi_utils_can_concurrent(wifi_data, iftype1, iftype2, out_num_channels);
}
/*****************************************************************************/
static gboolean
@ -12416,6 +12428,7 @@ nm_linux_platform_class_init(NMLinuxPlatformClass *klass)
platform_class->wifi_indicate_addressing_running = wifi_indicate_addressing_running;
platform_class->wifi_get_wake_on_wlan = wifi_get_wake_on_wlan;
platform_class->wifi_set_wake_on_wlan = wifi_set_wake_on_wlan;
platform_class->wifi_can_concurrent = wifi_can_concurrent;
platform_class->mesh_get_channel = mesh_get_channel;
platform_class->mesh_set_channel = mesh_set_channel;

View file

@ -3460,6 +3460,20 @@ nm_platform_wifi_set_wake_on_wlan(NMPlatform *self, int ifindex, _NMSettingWirel
return klass->wifi_set_wake_on_wlan(self, ifindex, wowl);
}
gboolean
nm_platform_wifi_can_concurrent(NMPlatform *self,
int ifindex,
NMWifiIfaceType iftype1,
NMWifiIfaceType iftype2,
guint8 *out_num_channels)
{
_CHECK_SELF(self, klass, FALSE);
g_return_val_if_fail(ifindex > 0, FALSE);
return klass->wifi_can_concurrent(self, ifindex, iftype1, iftype2, out_num_channels);
}
guint32
nm_platform_mesh_get_channel(NMPlatform *self, int ifindex)
{

View file

@ -8,6 +8,7 @@
#include "libnm-platform/nmp-base.h"
#include "libnm-base/nm-base.h"
#include "libnm-platform/wifi/nm-wifi-utils.h"
#include "nmp-plobj.h"
#define NM_TYPE_PLATFORM (nm_platform_get_type())
@ -1284,6 +1285,11 @@ typedef struct {
gboolean (*wifi_set_wake_on_wlan)(NMPlatform *self,
int ifindex,
_NMSettingWirelessWakeOnWLan wowl);
gboolean (*wifi_can_concurrent)(NMPlatform *self,
int ifindex,
NMWifiIfaceType iftype1,
NMWifiIfaceType iftype2,
guint8 *out_num_channels);
guint32 (*mesh_get_channel)(NMPlatform *self, int ifindex);
gboolean (*mesh_set_channel)(NMPlatform *self, int ifindex, guint32 channel);
@ -2233,6 +2239,12 @@ _NMSettingWirelessWakeOnWLan nm_platform_wifi_get_wake_on_wlan(NMPlatform *self,
gboolean
nm_platform_wifi_set_wake_on_wlan(NMPlatform *self, int ifindex, _NMSettingWirelessWakeOnWLan wowl);
gboolean nm_platform_wifi_can_concurrent(NMPlatform *self,
int ifindex,
NMWifiIfaceType iftype1,
NMWifiIfaceType iftype2,
guint8 *out_num_channels);
guint32 nm_platform_mesh_get_channel(NMPlatform *self, int ifindex);
gboolean nm_platform_mesh_set_channel(NMPlatform *self, int ifindex, guint32 channel);
gboolean nm_platform_mesh_set_ssid(NMPlatform *self, int ifindex, const guint8 *ssid, gsize len);

View file

@ -228,10 +228,10 @@ nm_wifi_utils_indicate_addressing_running(NMWifiUtils *data, gboolean running)
* Returns: %TRUE if the combination is allowed, %FALSE otherwise.
*/
gboolean
nm_wifi_utils_can_concurrent(NMWifiUtils *data,
guint32 iftype1,
guint32 iftype2,
guint8 *out_num_channels)
nm_wifi_utils_can_concurrent(NMWifiUtils *data,
NMWifiIfaceType iftype1,
NMWifiIfaceType iftype2,
guint8 *out_num_channels)
{
GArray *combs;
guint i, j, k;

View file

@ -10,6 +10,24 @@
#include "libnm-platform/nm-netlink.h"
#include "libnm-base/nm-base.h"
#include <linux/nl80211.h>
typedef enum {
NM_WIFI_IFACE_TYPE_UNSPEC = 0, /* NL80211_IFTYPE_UNSPEC */
NM_WIFI_IFACE_TYPE_ADHOC = NL80211_IFTYPE_ADHOC,
NM_WIFI_IFACE_TYPE_STATION = NL80211_IFTYPE_STATION,
NM_WIFI_IFACE_TYPE_AP = NL80211_IFTYPE_AP,
NM_WIFI_IFACE_TYPE_AP_VLAN = NL80211_IFTYPE_AP_VLAN,
NM_WIFI_IFACE_TYPE_WDS = NL80211_IFTYPE_WDS,
NM_WIFI_IFACE_TYPE_MONITOR = NL80211_IFTYPE_MONITOR,
NM_WIFI_IFACE_TYPE_MESH_POINT = NL80211_IFTYPE_MESH_POINT,
NM_WIFI_IFACE_TYPE_P2P_CLIENT = NL80211_IFTYPE_P2P_CLIENT,
NM_WIFI_IFACE_TYPE_P2P_GO = NL80211_IFTYPE_P2P_GO,
NM_WIFI_IFACE_TYPE_P2P_DEVICE = NL80211_IFTYPE_P2P_DEVICE,
NM_WIFI_IFACE_TYPE_OCB = NL80211_IFTYPE_OCB,
NM_WIFI_IFACE_TYPE_NAN = NL80211_IFTYPE_NAN,
} NMWifiIfaceType;
typedef struct NMWifiUtils NMWifiUtils;
#define NM_TYPE_WIFI_UTILS (nm_wifi_utils_get_type())
@ -81,9 +99,9 @@ gboolean nm_wifi_utils_set_mesh_ssid(NMWifiUtils *data, const guint8 *ssid, gsiz
*
* Returns: %TRUE if the combination is allowed, %FALSE otherwise.
*/
gboolean nm_wifi_utils_can_concurrent(NMWifiUtils *data,
guint32 iftype1,
guint32 iftype2,
guint8 *out_num_channels);
gboolean nm_wifi_utils_can_concurrent(NMWifiUtils *data,
NMWifiIfaceType iftype1,
NMWifiIfaceType iftype2,
guint8 *out_num_channels);
#endif /* __WIFI_UTILS_H__ */