wifi: mac80211: implement NAN non-evacuable channels

Implement the nan_set_non_evac_channels operation in mac80211. It marks
the provided channels as non-evacuable in the current local schedule and
clears the flag on all other channels. All provided channels must exist
in the current schedule, otherwise -ENOENT is returned.

ieee80211_nan_find_evac_chan() skips channels marked as non-evacuable
when selecting a channel to evacuate for concurrent operations.

Fixes: 42c9de58d9 ("wifi: mac80211: add NAN channel evacuation support")
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260921215936.ef5884349253.I38b685378c3557679ed6387922a94a7da821555c@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Andrei Otcheretianski 2026-09-21 22:00:23 +03:00 committed by Johannes Berg
parent 025ef5f4f6
commit e9e25a9578
4 changed files with 50 additions and 0 deletions

View File

@ -923,12 +923,14 @@ struct ieee80211_bss_conf {
* @channel_entry: the Channel Entry blob as defined in Wi-Fi Aware
* (TM) 4.0 specification Table 100 (Channel Entry format for the NAN
* Availability attribute).
* @no_evacuate: if set, this channel must not be evacuated
*/
struct ieee80211_nan_channel {
struct ieee80211_chan_req chanreq;
u8 needed_rx_chains;
struct ieee80211_chanctx_conf *chanctx_conf;
u8 channel_entry[6];
bool no_evacuate;
};
/**

View File

@ -6012,6 +6012,18 @@ ieee80211_set_peer_nan_sched(struct wiphy *wiphy,
return ieee80211_nan_set_peer_sched(sdata, sched);
}
static int
ieee80211_set_nan_non_evac_channels(struct wiphy *wiphy,
struct wireless_dev *wdev,
struct cfg80211_nan_non_evac_channels *channels)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
lockdep_assert_wiphy(wiphy);
return ieee80211_nan_set_non_evac_channels(sdata, channels);
}
const struct cfg80211_ops mac80211_config_ops = {
.add_virtual_intf = ieee80211_add_iface,
.del_virtual_intf = ieee80211_del_iface,
@ -6130,4 +6142,5 @@ const struct cfg80211_ops mac80211_config_ops = {
.set_epcs = ieee80211_set_epcs,
.nan_set_local_sched = ieee80211_set_local_nan_sched,
.nan_set_peer_sched = ieee80211_set_peer_nan_sched,
.nan_set_non_evac_channels = ieee80211_set_nan_non_evac_channels,
};

View File

@ -2091,6 +2091,8 @@ int ieee80211_nan_set_local_sched(struct ieee80211_sub_if_data *sdata,
struct cfg80211_nan_local_sched *sched);
int ieee80211_nan_set_peer_sched(struct ieee80211_sub_if_data *sdata,
struct cfg80211_nan_peer_sched *sched);
int ieee80211_nan_set_non_evac_channels(struct ieee80211_sub_if_data *sdata,
struct cfg80211_nan_non_evac_channels *channels);
void ieee80211_nan_free_peer_sched(struct ieee80211_nan_peer_sched *sched);
void ieee80211_nan_update_ndi_carrier(struct ieee80211_sub_if_data *ndi_sdata);
struct ieee80211_nan_channel *

View File

@ -248,6 +248,35 @@ ieee80211_nan_find_free_channel(struct ieee80211_nan_sched_cfg *sched_cfg)
return NULL;
}
int
ieee80211_nan_set_non_evac_channels(struct ieee80211_sub_if_data *sdata,
struct cfg80211_nan_non_evac_channels *channels)
{
struct ieee80211_nan_sched_cfg *sched_cfg = &sdata->vif.cfg.nan_sched;
/*
* cfg80211 already validated that all provided channels belong to the
* current schedule, so just clear all non-evacuable flags and set the
* ones in the list.
*/
for (int j = 0; j < ARRAY_SIZE(sched_cfg->channels); j++)
sched_cfg->channels[j].no_evacuate = false;
for (int i = 0; i < channels->n_channels; i++) {
for (int j = 0; j < ARRAY_SIZE(sched_cfg->channels); j++) {
if (!sched_cfg->channels[j].chanreq.oper.chan)
continue;
if (cfg80211_chandef_identical(&sched_cfg->channels[j].chanreq.oper,
&channels->chandefs[i])) {
sched_cfg->channels[j].no_evacuate = true;
break;
}
}
}
return 0;
}
int ieee80211_nan_set_local_sched(struct ieee80211_sub_if_data *sdata,
struct cfg80211_nan_local_sched *sched)
{
@ -785,6 +814,10 @@ ieee80211_nan_find_evac_chan(struct ieee80211_local *local,
usable_channels++;
/* No-evacuate channel is usable but cannot be evacuated */
if (chan->no_evacuate)
continue;
chan_ctx = container_of(chan->chanctx_conf,
struct ieee80211_chanctx, conf);