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); 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 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_indicate_addressing_running = wifi_indicate_addressing_running;
platform_class->wifi_get_wake_on_wlan = wifi_get_wake_on_wlan; 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_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_get_channel = mesh_get_channel;
platform_class->mesh_set_channel = mesh_set_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); 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 guint32
nm_platform_mesh_get_channel(NMPlatform *self, int ifindex) nm_platform_mesh_get_channel(NMPlatform *self, int ifindex)
{ {

View file

@ -8,6 +8,7 @@
#include "libnm-platform/nmp-base.h" #include "libnm-platform/nmp-base.h"
#include "libnm-base/nm-base.h" #include "libnm-base/nm-base.h"
#include "libnm-platform/wifi/nm-wifi-utils.h"
#include "nmp-plobj.h" #include "nmp-plobj.h"
#define NM_TYPE_PLATFORM (nm_platform_get_type()) #define NM_TYPE_PLATFORM (nm_platform_get_type())
@ -1284,6 +1285,11 @@ typedef struct {
gboolean (*wifi_set_wake_on_wlan)(NMPlatform *self, gboolean (*wifi_set_wake_on_wlan)(NMPlatform *self,
int ifindex, int ifindex,
_NMSettingWirelessWakeOnWLan wowl); _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); guint32 (*mesh_get_channel)(NMPlatform *self, int ifindex);
gboolean (*mesh_set_channel)(NMPlatform *self, int ifindex, guint32 channel); 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 gboolean
nm_platform_wifi_set_wake_on_wlan(NMPlatform *self, int ifindex, _NMSettingWirelessWakeOnWLan wowl); 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); 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_channel(NMPlatform *self, int ifindex, guint32 channel);
gboolean nm_platform_mesh_set_ssid(NMPlatform *self, int ifindex, const guint8 *ssid, gsize len); 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. * Returns: %TRUE if the combination is allowed, %FALSE otherwise.
*/ */
gboolean gboolean
nm_wifi_utils_can_concurrent(NMWifiUtils *data, nm_wifi_utils_can_concurrent(NMWifiUtils *data,
guint32 iftype1, NMWifiIfaceType iftype1,
guint32 iftype2, NMWifiIfaceType iftype2,
guint8 *out_num_channels) guint8 *out_num_channels)
{ {
GArray *combs; GArray *combs;
guint i, j, k; guint i, j, k;

View file

@ -10,6 +10,24 @@
#include "libnm-platform/nm-netlink.h" #include "libnm-platform/nm-netlink.h"
#include "libnm-base/nm-base.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; typedef struct NMWifiUtils NMWifiUtils;
#define NM_TYPE_WIFI_UTILS (nm_wifi_utils_get_type()) #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. * Returns: %TRUE if the combination is allowed, %FALSE otherwise.
*/ */
gboolean nm_wifi_utils_can_concurrent(NMWifiUtils *data, gboolean nm_wifi_utils_can_concurrent(NMWifiUtils *data,
guint32 iftype1, NMWifiIfaceType iftype1,
guint32 iftype2, NMWifiIfaceType iftype2,
guint8 *out_num_channels); guint8 *out_num_channels);
#endif /* __WIFI_UTILS_H__ */ #endif /* __WIFI_UTILS_H__ */