mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
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:
parent
025ef5f4f6
commit
e9e25a9578
|
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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 *
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user