Skip to content

Commit 26ec17a

Browse files
Orr Mazorjmberg-intel
authored andcommitted
cfg80211: Fix radar event during another phy CAC
In case a radar event of CAC_FINISHED or RADAR_DETECTED happens during another phy is during CAC we might need to cancel that CAC. If we got a radar in a channel that another phy is now doing CAC on then the CAC should be canceled there. If, for example, 2 phys doing CAC on the same channels, or on comptable channels, once on of them will finish his CAC the other might need to cancel his CAC, since it is no longer relevant. To fix that the commit adds an callback and implement it in mac80211 to end CAC. This commit also adds a call to said callback if after a radar event we see the CAC is no longer relevant Signed-off-by: Orr Mazor <[email protected]> Reviewed-by: Sergey Matyukevich <[email protected]> Link: https://lore.kernel.org/r/[email protected] [slightly reformat/reword commit message] Signed-off-by: Johannes Berg <[email protected]>
1 parent c4b9d65 commit 26ec17a

File tree

5 files changed

+65
-1
lines changed

5 files changed

+65
-1
lines changed

include/net/cfg80211.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3548,6 +3548,9 @@ struct cfg80211_update_owe_info {
35483548
*
35493549
* @start_radar_detection: Start radar detection in the driver.
35503550
*
3551+
* @end_cac: End running CAC, probably because a related CAC
3552+
* was finished on another phy.
3553+
*
35513554
* @update_ft_ies: Provide updated Fast BSS Transition information to the
35523555
* driver. If the SME is in the driver/firmware, this information can be
35533556
* used in building Authentication and Reassociation Request frames.
@@ -3874,6 +3877,8 @@ struct cfg80211_ops {
38743877
struct net_device *dev,
38753878
struct cfg80211_chan_def *chandef,
38763879
u32 cac_time_ms);
3880+
void (*end_cac)(struct wiphy *wiphy,
3881+
struct net_device *dev);
38773882
int (*update_ft_ies)(struct wiphy *wiphy, struct net_device *dev,
38783883
struct cfg80211_update_ft_ies_params *ftie);
38793884
int (*crit_proto_start)(struct wiphy *wiphy,

net/mac80211/cfg.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2954,6 +2954,28 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy,
29542954
return err;
29552955
}
29562956

2957+
static void ieee80211_end_cac(struct wiphy *wiphy,
2958+
struct net_device *dev)
2959+
{
2960+
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2961+
struct ieee80211_local *local = sdata->local;
2962+
2963+
mutex_lock(&local->mtx);
2964+
list_for_each_entry(sdata, &local->interfaces, list) {
2965+
/* it might be waiting for the local->mtx, but then
2966+
* by the time it gets it, sdata->wdev.cac_started
2967+
* will no longer be true
2968+
*/
2969+
cancel_delayed_work(&sdata->dfs_cac_timer_work);
2970+
2971+
if (sdata->wdev.cac_started) {
2972+
ieee80211_vif_release_channel(sdata);
2973+
sdata->wdev.cac_started = false;
2974+
}
2975+
}
2976+
mutex_unlock(&local->mtx);
2977+
}
2978+
29572979
static struct cfg80211_beacon_data *
29582980
cfg80211_beacon_dup(struct cfg80211_beacon_data *beacon)
29592981
{
@@ -4023,6 +4045,7 @@ const struct cfg80211_ops mac80211_config_ops = {
40234045
#endif
40244046
.get_channel = ieee80211_cfg_get_channel,
40254047
.start_radar_detection = ieee80211_start_radar_detection,
4048+
.end_cac = ieee80211_end_cac,
40264049
.channel_switch = ieee80211_channel_switch,
40274050
.set_qos_map = ieee80211_set_qos_map,
40284051
.set_ap_chanwidth = ieee80211_set_ap_chanwidth,

net/wireless/rdev-ops.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,6 +1167,16 @@ rdev_start_radar_detection(struct cfg80211_registered_device *rdev,
11671167
return ret;
11681168
}
11691169

1170+
static inline void
1171+
rdev_end_cac(struct cfg80211_registered_device *rdev,
1172+
struct net_device *dev)
1173+
{
1174+
trace_rdev_end_cac(&rdev->wiphy, dev);
1175+
if (rdev->ops->end_cac)
1176+
rdev->ops->end_cac(&rdev->wiphy, dev);
1177+
trace_rdev_return_void(&rdev->wiphy);
1178+
}
1179+
11701180
static inline int
11711181
rdev_set_mcast_rate(struct cfg80211_registered_device *rdev,
11721182
struct net_device *dev,

net/wireless/reg.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3892,6 +3892,25 @@ bool regulatory_pre_cac_allowed(struct wiphy *wiphy)
38923892
}
38933893
EXPORT_SYMBOL(regulatory_pre_cac_allowed);
38943894

3895+
static void cfg80211_check_and_end_cac(struct cfg80211_registered_device *rdev)
3896+
{
3897+
struct wireless_dev *wdev;
3898+
/* If we finished CAC or received radar, we should end any
3899+
* CAC running on the same channels.
3900+
* the check !cfg80211_chandef_dfs_usable contain 2 options:
3901+
* either all channels are available - those the CAC_FINISHED
3902+
* event has effected another wdev state, or there is a channel
3903+
* in unavailable state in wdev chandef - those the RADAR_DETECTED
3904+
* event has effected another wdev state.
3905+
* In both cases we should end the CAC on the wdev.
3906+
*/
3907+
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
3908+
if (wdev->cac_started &&
3909+
!cfg80211_chandef_dfs_usable(&rdev->wiphy, &wdev->chandef))
3910+
rdev_end_cac(rdev, wdev->netdev);
3911+
}
3912+
}
3913+
38953914
void regulatory_propagate_dfs_state(struct wiphy *wiphy,
38963915
struct cfg80211_chan_def *chandef,
38973916
enum nl80211_dfs_state dfs_state,
@@ -3918,8 +3937,10 @@ void regulatory_propagate_dfs_state(struct wiphy *wiphy,
39183937
cfg80211_set_dfs_state(&rdev->wiphy, chandef, dfs_state);
39193938

39203939
if (event == NL80211_RADAR_DETECTED ||
3921-
event == NL80211_RADAR_CAC_FINISHED)
3940+
event == NL80211_RADAR_CAC_FINISHED) {
39223941
cfg80211_sched_dfs_chan_update(rdev);
3942+
cfg80211_check_and_end_cac(rdev);
3943+
}
39233944

39243945
nl80211_radar_notify(rdev, chandef, event, NULL, GFP_KERNEL);
39253946
}

net/wireless/trace.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,11 @@ DEFINE_EVENT(wiphy_netdev_evt, rdev_flush_pmksa,
646646
TP_ARGS(wiphy, netdev)
647647
);
648648

649+
DEFINE_EVENT(wiphy_netdev_evt, rdev_end_cac,
650+
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev),
651+
TP_ARGS(wiphy, netdev)
652+
);
653+
649654
DECLARE_EVENT_CLASS(station_add_change,
650655
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 *mac,
651656
struct station_parameters *params),

0 commit comments

Comments
 (0)