mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
wifi: cfg80211: set and report chandef CAC ongoing
Allow to track and check CAC state from user mode by simple check phy channels eg. using iw phy1 channels command. This is done for regular CAC and background CAC. It is important for background CAC while we can start it from any app (eg. iw or hostapd). Signed-off-by: Janusz Dziedzic <janusz.dziedzic@gmail.com> Link: https://patch.msgid.link/20260206171830.553879-3-janusz.dziedzic@gmail.com Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
92fecd2744
commit
d69cb039ab
|
|
@ -190,6 +190,8 @@ enum ieee80211_channel_flags {
|
|||
* on this channel.
|
||||
* @dfs_state_entered: timestamp (jiffies) when the dfs state was entered.
|
||||
* @dfs_cac_ms: DFS CAC time in milliseconds, this is valid for DFS channels.
|
||||
* @cac_start_time: timestamp (CLOCK_BOOTTIME, nanoseconds) when CAC was
|
||||
* started on this channel. Zero when CAC is not in progress.
|
||||
* @psd: power spectral density (in dBm)
|
||||
*/
|
||||
struct ieee80211_channel {
|
||||
|
|
@ -207,6 +209,7 @@ struct ieee80211_channel {
|
|||
enum nl80211_dfs_state dfs_state;
|
||||
unsigned long dfs_state_entered;
|
||||
unsigned int dfs_cac_ms;
|
||||
u64 cac_start_time;
|
||||
s8 psd;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -4480,6 +4480,10 @@ enum nl80211_wmm_rule {
|
|||
* as a non-primary subchannel. Only applicable to S1G channels.
|
||||
* @NL80211_FREQUENCY_ATTR_NO_UHR: UHR operation is not allowed on this channel
|
||||
* in current regulatory domain.
|
||||
* @NL80211_FREQUENCY_ATTR_CAC_START_TIME: Channel Availability Check (CAC)
|
||||
* start time (CLOCK_BOOTTIME, nanoseconds). Only present when CAC is
|
||||
* currently in progress on this channel.
|
||||
* @NL80211_FREQUENCY_ATTR_PAD: attribute used for padding for 64-bit alignment
|
||||
* @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number
|
||||
* currently defined
|
||||
* @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use
|
||||
|
|
@ -4530,6 +4534,8 @@ enum nl80211_frequency_attr {
|
|||
NL80211_FREQUENCY_ATTR_NO_16MHZ,
|
||||
NL80211_FREQUENCY_ATTR_S1G_NO_PRIMARY,
|
||||
NL80211_FREQUENCY_ATTR_NO_UHR,
|
||||
NL80211_FREQUENCY_ATTR_CAC_START_TIME,
|
||||
NL80211_FREQUENCY_ATTR_PAD,
|
||||
|
||||
/* keep last */
|
||||
__NL80211_FREQUENCY_ATTR_AFTER_LAST,
|
||||
|
|
|
|||
|
|
@ -642,6 +642,33 @@ void cfg80211_set_dfs_state(struct wiphy *wiphy,
|
|||
}
|
||||
}
|
||||
|
||||
void cfg80211_set_cac_state(struct wiphy *wiphy,
|
||||
const struct cfg80211_chan_def *chandef,
|
||||
bool cac_ongoing)
|
||||
{
|
||||
struct ieee80211_channel *c;
|
||||
int width;
|
||||
u64 cac_time;
|
||||
|
||||
if (WARN_ON(!cfg80211_chandef_valid(chandef)))
|
||||
return;
|
||||
|
||||
width = cfg80211_chandef_get_width(chandef);
|
||||
if (width < 0)
|
||||
return;
|
||||
|
||||
/* Get the same timestamp for all subchannels */
|
||||
cac_time = cac_ongoing ? ktime_get_boottime_ns() : 0;
|
||||
|
||||
for_each_subchan(chandef, freq, cf) {
|
||||
c = ieee80211_get_channel_khz(wiphy, freq);
|
||||
if (!c)
|
||||
continue;
|
||||
|
||||
c->cac_start_time = cac_time;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
cfg80211_dfs_permissive_check_wdev(struct cfg80211_registered_device *rdev,
|
||||
enum nl80211_iftype iftype,
|
||||
|
|
|
|||
|
|
@ -481,6 +481,10 @@ void cfg80211_set_dfs_state(struct wiphy *wiphy,
|
|||
const struct cfg80211_chan_def *chandef,
|
||||
enum nl80211_dfs_state dfs_state);
|
||||
|
||||
void cfg80211_set_cac_state(struct wiphy *wiphy,
|
||||
const struct cfg80211_chan_def *chandef,
|
||||
bool cac_ongoing);
|
||||
|
||||
void cfg80211_dfs_channels_update_work(struct work_struct *work);
|
||||
|
||||
void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev);
|
||||
|
|
|
|||
|
|
@ -1162,9 +1162,11 @@ void cfg80211_cac_event(struct net_device *netdev,
|
|||
fallthrough;
|
||||
case NL80211_RADAR_CAC_ABORTED:
|
||||
wdev->links[link_id].cac_started = false;
|
||||
cfg80211_set_cac_state(wiphy, chandef, false);
|
||||
break;
|
||||
case NL80211_RADAR_CAC_STARTED:
|
||||
wdev->links[link_id].cac_started = true;
|
||||
cfg80211_set_cac_state(wiphy, chandef, true);
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
|
|
@ -1192,15 +1194,18 @@ __cfg80211_background_cac_event(struct cfg80211_registered_device *rdev,
|
|||
switch (event) {
|
||||
case NL80211_RADAR_CAC_FINISHED:
|
||||
cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
|
||||
cfg80211_set_cac_state(wiphy, chandef, false);
|
||||
memcpy(&rdev->cac_done_chandef, chandef, sizeof(*chandef));
|
||||
queue_work(cfg80211_wq, &rdev->propagate_cac_done_wk);
|
||||
cfg80211_sched_dfs_chan_update(rdev);
|
||||
break;
|
||||
case NL80211_RADAR_CAC_ABORTED:
|
||||
cfg80211_set_cac_state(wiphy, chandef, false);
|
||||
if (!cancel_delayed_work(&rdev->background_cac_done_wk))
|
||||
return;
|
||||
break;
|
||||
case NL80211_RADAR_CAC_STARTED:
|
||||
cfg80211_set_cac_state(wiphy, chandef, true);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
|
|
@ -1307,6 +1312,8 @@ void cfg80211_stop_radar_detection(struct wireless_dev *wdev)
|
|||
|
||||
chandef = *wdev_chandef(wdev, link_id);
|
||||
rdev_end_cac(rdev, wdev->netdev, link_id);
|
||||
wdev->links[link_id].cac_started = false;
|
||||
cfg80211_set_cac_state(wiphy, &chandef, false);
|
||||
nl80211_radar_notify(rdev, &chandef, NL80211_RADAR_CAC_ABORTED,
|
||||
wdev->netdev, GFP_KERNEL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1333,6 +1333,12 @@ static int nl80211_msg_put_channel(struct sk_buff *msg, struct wiphy *wiphy,
|
|||
if ((chan->flags & IEEE80211_CHAN_NO_UHR) &&
|
||||
nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_UHR))
|
||||
goto nla_put_failure;
|
||||
if (chan->cac_start_time &&
|
||||
nla_put_u64_64bit(msg,
|
||||
NL80211_FREQUENCY_ATTR_CAC_START_TIME,
|
||||
chan->cac_start_time,
|
||||
NL80211_FREQUENCY_ATTR_PAD))
|
||||
goto nla_put_failure;
|
||||
}
|
||||
|
||||
if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
|
||||
|
|
@ -11353,6 +11359,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
|
|||
wdev->links[link_id].cac_started = true;
|
||||
wdev->links[link_id].cac_start_time = jiffies;
|
||||
wdev->links[link_id].cac_time_ms = cac_time_ms;
|
||||
cfg80211_set_cac_state(wiphy, &chandef, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user