From 23daf1b4c91db9b26f8425cc7039cf96d22ccbfe Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 15 May 2024 14:16:00 +0200 Subject: wifi: nl80211: disallow setting special AP channel widths Setting the AP channel width is meant for use with the normal 20/40/... MHz channel width progression, and switching around in S1G or narrow channels isn't supported. Disallow that. Reported-by: syzbot+bc0f5b92cc7091f45fb6@syzkaller.appspotmail.com Link: https://msgid.link/20240515141600.d4a9590bfe32.I19a32d60097e81b527eafe6b0924f6c5fbb2dc45@changeid Signed-off-by: Johannes Berg --- net/wireless/nl80211.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'net/wireless') diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 3c0bca4238d3..93c313149f57 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -3415,6 +3415,33 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, if (chandef.chan != cur_chan) return -EBUSY; + /* only allow this for regular channel widths */ + switch (wdev->links[link_id].ap.chandef.width) { + case NL80211_CHAN_WIDTH_20_NOHT: + case NL80211_CHAN_WIDTH_20: + case NL80211_CHAN_WIDTH_40: + case NL80211_CHAN_WIDTH_80: + case NL80211_CHAN_WIDTH_80P80: + case NL80211_CHAN_WIDTH_160: + case NL80211_CHAN_WIDTH_320: + break; + default: + return -EINVAL; + } + + switch (chandef.width) { + case NL80211_CHAN_WIDTH_20_NOHT: + case NL80211_CHAN_WIDTH_20: + case NL80211_CHAN_WIDTH_40: + case NL80211_CHAN_WIDTH_80: + case NL80211_CHAN_WIDTH_80P80: + case NL80211_CHAN_WIDTH_160: + case NL80211_CHAN_WIDTH_320: + break; + default: + return -EINVAL; + } + result = rdev_set_ap_chanwidth(rdev, dev, link_id, &chandef); if (result) -- cgit v1.2.3 From 2449db1f2186e6cd8410631d0ee9e951289fe5ae Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 6 May 2024 21:00:02 +0200 Subject: wifi: cfg80211: sort trace events again They were meant to be split into ops and APIs, but some ops were added in the wrong place. Fix that. Reviewed-by: Miriam Rachel Korenblit Link: https://msgid.link/20240506210002.0b3a86a5d8d7.I5591c03223bdb95597e181de63a2eded424de34c@changeid Signed-off-by: Johannes Berg --- net/wireless/trace.h | 138 +++++++++++++++++++++++++-------------------------- 1 file changed, 69 insertions(+), 69 deletions(-) (limited to 'net/wireless') diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 9bf987519811..b76e3b21051a 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -2889,6 +2889,75 @@ DEFINE_EVENT(wiphy_wdev_link_evt, rdev_del_intf_link, TP_ARGS(wiphy, wdev, link_id) ); +TRACE_EVENT(rdev_del_link_station, + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, + struct link_station_del_parameters *params), + TP_ARGS(wiphy, netdev, params), + TP_STRUCT__entry( + WIPHY_ENTRY + NETDEV_ENTRY + __array(u8, mld_mac, 6) + __field(u32, link_id) + ), + TP_fast_assign( + WIPHY_ASSIGN; + NETDEV_ASSIGN; + memset(__entry->mld_mac, 0, 6); + if (params->mld_mac) + memcpy(__entry->mld_mac, params->mld_mac, 6); + __entry->link_id = params->link_id; + ), + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: %pM" + ", link id: %u", + WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->mld_mac, + __entry->link_id) +); + +TRACE_EVENT(rdev_set_hw_timestamp, + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, + struct cfg80211_set_hw_timestamp *hwts), + + TP_ARGS(wiphy, netdev, hwts), + + TP_STRUCT__entry( + WIPHY_ENTRY + NETDEV_ENTRY + MAC_ENTRY(macaddr) + __field(bool, enable) + ), + + TP_fast_assign( + WIPHY_ASSIGN; + NETDEV_ASSIGN; + MAC_ASSIGN(macaddr, hwts->macaddr); + __entry->enable = hwts->enable; + ), + + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", mac %pM, enable: %u", + WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->macaddr, + __entry->enable) +); + +TRACE_EVENT(rdev_set_ttlm, + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, + struct cfg80211_ttlm_params *params), + TP_ARGS(wiphy, netdev, params), + TP_STRUCT__entry( + WIPHY_ENTRY + NETDEV_ENTRY + __array(u8, dlink, sizeof(u16) * 8) + __array(u8, ulink, sizeof(u16) * 8) + ), + TP_fast_assign( + WIPHY_ASSIGN; + NETDEV_ASSIGN; + memcpy(__entry->dlink, params->dlink, sizeof(params->dlink)); + memcpy(__entry->ulink, params->ulink, sizeof(params->ulink)); + ), + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT, + WIPHY_PR_ARG, NETDEV_PR_ARG) +); + /************************************************************* * cfg80211 exported functions traces * *************************************************************/ @@ -3923,55 +3992,6 @@ DEFINE_EVENT(link_station_add_mod, rdev_mod_link_station, TP_ARGS(wiphy, netdev, params) ); -TRACE_EVENT(rdev_del_link_station, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - struct link_station_del_parameters *params), - TP_ARGS(wiphy, netdev, params), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - __array(u8, mld_mac, 6) - __field(u32, link_id) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - memset(__entry->mld_mac, 0, 6); - if (params->mld_mac) - memcpy(__entry->mld_mac, params->mld_mac, 6); - __entry->link_id = params->link_id; - ), - TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: %pM" - ", link id: %u", - WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->mld_mac, - __entry->link_id) -); - -TRACE_EVENT(rdev_set_hw_timestamp, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - struct cfg80211_set_hw_timestamp *hwts), - - TP_ARGS(wiphy, netdev, hwts), - - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - MAC_ENTRY(macaddr) - __field(bool, enable) - ), - - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - MAC_ASSIGN(macaddr, hwts->macaddr); - __entry->enable = hwts->enable; - ), - - TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", mac %pM, enable: %u", - WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->macaddr, - __entry->enable) -); - TRACE_EVENT(cfg80211_links_removed, TP_PROTO(struct net_device *netdev, u16 link_mask), TP_ARGS(netdev, link_mask), @@ -3987,26 +4007,6 @@ TRACE_EVENT(cfg80211_links_removed, __entry->link_mask) ); -TRACE_EVENT(rdev_set_ttlm, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - struct cfg80211_ttlm_params *params), - TP_ARGS(wiphy, netdev, params), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - __array(u8, dlink, sizeof(u16) * 8) - __array(u8, ulink, sizeof(u16) * 8) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - memcpy(__entry->dlink, params->dlink, sizeof(params->dlink)); - memcpy(__entry->ulink, params->ulink, sizeof(params->ulink)); - ), - TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT, - WIPHY_PR_ARG, NETDEV_PR_ARG) -); - #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ #undef TRACE_INCLUDE_PATH -- cgit v1.2.3 From eb745c7c854e200d7fd6ba0944691a1aaf882d4d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 6 May 2024 21:00:03 +0200 Subject: wifi: cfg80211: add tracing for wiphy work Add trace events to trace when wiphy works are queued (or delayed ones scheduled), and other APIs are called. Also add an event when the worker starts, before acquiring the mutex, to be able to see potential delays due to locking. Reviewed-by: Miriam Rachel Korenblit Reviewed-by: Benjamin Berg Link: https://msgid.link/20240506210002.bf1840a1d22d.I4abba048c1c4017345640219cf1384a0b2288dd3@changeid Signed-off-by: Johannes Berg --- net/wireless/core.c | 12 +++++++++ net/wireless/trace.h | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) (limited to 'net/wireless') diff --git a/net/wireless/core.c b/net/wireless/core.c index 3fb1b637352a..61f7cd8a8e9c 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -421,6 +421,8 @@ static void cfg80211_wiphy_work(struct work_struct *work) rdev = container_of(work, struct cfg80211_registered_device, wiphy_work); + trace_wiphy_work_worker_start(&rdev->wiphy); + wiphy_lock(&rdev->wiphy); if (rdev->suspended) goto out; @@ -434,6 +436,7 @@ static void cfg80211_wiphy_work(struct work_struct *work) schedule_work(work); spin_unlock_irq(&rdev->wiphy_work_lock); + trace_wiphy_work_run(&rdev->wiphy, wk); wk->func(&rdev->wiphy, wk); } else { spin_unlock_irq(&rdev->wiphy_work_lock); @@ -1066,6 +1069,7 @@ void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev, list_del_init(&wk->entry); spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags); + trace_wiphy_work_run(&rdev->wiphy, wk); wk->func(&rdev->wiphy, wk); spin_lock_irqsave(&rdev->wiphy_work_lock, flags); @@ -1610,6 +1614,8 @@ void wiphy_work_queue(struct wiphy *wiphy, struct wiphy_work *work) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); unsigned long flags; + trace_wiphy_work_queue(wiphy, work); + spin_lock_irqsave(&rdev->wiphy_work_lock, flags); if (list_empty(&work->entry)) list_add_tail(&work->entry, &rdev->wiphy_work_list); @@ -1626,6 +1632,8 @@ void wiphy_work_cancel(struct wiphy *wiphy, struct wiphy_work *work) lockdep_assert_held(&wiphy->mtx); + trace_wiphy_work_cancel(wiphy, work); + spin_lock_irqsave(&rdev->wiphy_work_lock, flags); if (!list_empty(&work->entry)) list_del_init(&work->entry); @@ -1639,6 +1647,8 @@ void wiphy_work_flush(struct wiphy *wiphy, struct wiphy_work *work) unsigned long flags; bool run; + trace_wiphy_work_flush(wiphy, work); + spin_lock_irqsave(&rdev->wiphy_work_lock, flags); run = !work || !list_empty(&work->entry); spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags); @@ -1660,6 +1670,8 @@ void wiphy_delayed_work_queue(struct wiphy *wiphy, struct wiphy_delayed_work *dwork, unsigned long delay) { + trace_wiphy_delayed_work_queue(wiphy, &dwork->work, delay); + if (!delay) { del_timer(&dwork->timer); wiphy_work_queue(wiphy, &dwork->work); diff --git a/net/wireless/trace.h b/net/wireless/trace.h index b76e3b21051a..14cfa0aba93a 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -242,6 +242,80 @@ } \ } while (0) +/************************************************************* + * wiphy work traces * + *************************************************************/ + +DECLARE_EVENT_CLASS(wiphy_work_event, + TP_PROTO(struct wiphy *wiphy, struct wiphy_work *work), + TP_ARGS(wiphy, work), + TP_STRUCT__entry( + WIPHY_ENTRY + __field(void *, instance) + __field(void *, func) + ), + TP_fast_assign( + WIPHY_ASSIGN; + __entry->instance = work; + __entry->func = work ? work->func : NULL; + ), + TP_printk(WIPHY_PR_FMT " instance=%p func=%pS", + WIPHY_PR_ARG, __entry->instance, __entry->func) +); + +DEFINE_EVENT(wiphy_work_event, wiphy_work_queue, + TP_PROTO(struct wiphy *wiphy, struct wiphy_work *work), + TP_ARGS(wiphy, work) +); + +DEFINE_EVENT(wiphy_work_event, wiphy_work_run, + TP_PROTO(struct wiphy *wiphy, struct wiphy_work *work), + TP_ARGS(wiphy, work) +); + +DEFINE_EVENT(wiphy_work_event, wiphy_work_cancel, + TP_PROTO(struct wiphy *wiphy, struct wiphy_work *work), + TP_ARGS(wiphy, work) +); + +DEFINE_EVENT(wiphy_work_event, wiphy_work_flush, + TP_PROTO(struct wiphy *wiphy, struct wiphy_work *work), + TP_ARGS(wiphy, work) +); + +TRACE_EVENT(wiphy_delayed_work_queue, + TP_PROTO(struct wiphy *wiphy, struct wiphy_work *work, + unsigned long delay), + TP_ARGS(wiphy, work, delay), + TP_STRUCT__entry( + WIPHY_ENTRY + __field(void *, instance) + __field(void *, func) + __field(unsigned long, delay) + ), + TP_fast_assign( + WIPHY_ASSIGN; + __entry->instance = work; + __entry->func = work->func; + __entry->delay = delay; + ), + TP_printk(WIPHY_PR_FMT " instance=%p func=%pS delay=%ld", + WIPHY_PR_ARG, __entry->instance, __entry->func, + __entry->delay) +); + +TRACE_EVENT(wiphy_work_worker_start, + TP_PROTO(struct wiphy *wiphy), + TP_ARGS(wiphy), + TP_STRUCT__entry( + WIPHY_ENTRY + ), + TP_fast_assign( + WIPHY_ASSIGN; + ), + TP_printk(WIPHY_PR_FMT, WIPHY_PR_ARG) +); + /************************************************************* * rdev->ops traces * *************************************************************/ -- cgit v1.2.3 From 2d33ecf5d0148671c74e68e18755b9411a7ba923 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 6 May 2024 21:11:59 +0200 Subject: wifi: cfg80211: restrict operation during radar detection Just like it's not currently possible to start radar detection while already operating, it shouldn't be possible to start operating while radar detection is running. Fix that. Also, improve the check whether operating (carrier might not be up if e.g. attempting to join IBSS). Reviewed-by: Miriam Rachel Korenblit Link: https://msgid.link/20240506211158.ae8dca3d0d6c.I7c70a66a5fbdbc63a78fee8a34f31d1995491bc3@changeid Signed-off-by: Johannes Berg --- net/wireless/ibss.c | 5 ++++- net/wireless/mesh.c | 5 ++++- net/wireless/nl80211.c | 21 +++++++++++++++------ 3 files changed, 23 insertions(+), 8 deletions(-) (limited to 'net/wireless') diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 9f02ee5f08be..34e5acff3935 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c @@ -3,7 +3,7 @@ * Some IBSS support code for cfg80211. * * Copyright 2009 Johannes Berg - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2024 Intel Corporation */ #include @@ -94,6 +94,9 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, lockdep_assert_held(&rdev->wiphy.mtx); + if (wdev->cac_started) + return -EBUSY; + if (wdev->u.ibss.ssid_len) return -EALREADY; diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index 83306979fbe2..aaca65b66af4 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* * Portions - * Copyright (C) 2022-2023 Intel Corporation + * Copyright (C) 2022-2024 Intel Corporation */ #include #include @@ -127,6 +127,9 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, if (!rdev->ops->join_mesh) return -EOPNOTSUPP; + if (wdev->cac_started) + return -EBUSY; + if (!setup->chandef.chan) { /* if no channel explicitly given, use preset channel */ setup->chandef = wdev->u.mesh.preset_chandef; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 93c313149f57..6ba988a6f5a2 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -5964,6 +5964,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) if (!rdev->ops->start_ap) return -EOPNOTSUPP; + if (wdev->cac_started) + return -EBUSY; + if (wdev->links[link_id].ap.beacon_interval) return -EALREADY; @@ -9956,6 +9959,17 @@ static int nl80211_start_radar_detection(struct sk_buff *skb, flush_delayed_work(&rdev->dfs_update_channels_wk); + switch (wdev->iftype) { + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: + case NL80211_IFTYPE_MESH_POINT: + case NL80211_IFTYPE_ADHOC: + break; + default: + /* caution - see cfg80211_beaconing_iface_active() below */ + return -EINVAL; + } + wiphy_lock(wiphy); dfs_region = reg_get_dfs_region(wiphy); @@ -9986,12 +10000,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb, goto unlock; } - if (netif_carrier_ok(dev)) { - err = -EBUSY; - goto unlock; - } - - if (wdev->cac_started) { + if (cfg80211_beaconing_iface_active(wdev) || wdev->cac_started) { err = -EBUSY; goto unlock; } -- cgit v1.2.3 From 8526f8c877baf3f9e678b31fd7d1066b776775cc Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 23 May 2024 12:02:13 +0200 Subject: wifi: nl80211: clean up coalescing rule handling There's no need to allocate a tiny struct and then an array again, just allocate the two together and use __counted_by(). Also unify the freeing. Reviewed-by: Miriam Rachel Korenblit Link: https://msgid.link/20240523120213.48a40cfb96f9.Ia02bf8f8fefbf533c64c5fa26175848d4a3a7899@changeid Signed-off-by: Johannes Berg --- net/wireless/core.c | 3 ++- net/wireless/nl80211.c | 47 ++++++++++++++++------------------------------- net/wireless/nl80211.h | 4 ++-- 3 files changed, 20 insertions(+), 34 deletions(-) (limited to 'net/wireless') diff --git a/net/wireless/core.c b/net/wireless/core.c index 61f7cd8a8e9c..7c35349b9596 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -1145,7 +1145,8 @@ void wiphy_unregister(struct wiphy *wiphy) flush_work(&rdev->background_cac_abort_wk); cfg80211_rdev_free_wowlan(rdev); - cfg80211_rdev_free_coalesce(rdev); + cfg80211_free_coalesce(rdev->coalesce); + rdev->coalesce = NULL; } EXPORT_SYMBOL(wiphy_unregister); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 6ba988a6f5a2..8ff5f79d446a 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -13897,9 +13897,8 @@ nla_put_failure: return -ENOBUFS; } -void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev) +void cfg80211_free_coalesce(struct cfg80211_coalesce *coalesce) { - struct cfg80211_coalesce *coalesce = rdev->coalesce; int i, j; struct cfg80211_coalesce_rules *rule; @@ -13908,13 +13907,13 @@ void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev) for (i = 0; i < coalesce->n_rules; i++) { rule = &coalesce->rules[i]; + if (!rule) + continue; for (j = 0; j < rule->n_patterns; j++) kfree(rule->patterns[j].mask); kfree(rule->patterns); } - kfree(coalesce->rules); kfree(coalesce); - rdev->coalesce = NULL; } static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev, @@ -14012,17 +14011,16 @@ static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce; - struct cfg80211_coalesce new_coalesce = {}; - struct cfg80211_coalesce *n_coalesce; - int err, rem_rule, n_rules = 0, i, j; + struct cfg80211_coalesce *new_coalesce; + int err, rem_rule, n_rules = 0, i; struct nlattr *rule; - struct cfg80211_coalesce_rules *tmp_rule; if (!rdev->wiphy.coalesce || !rdev->ops->set_coalesce) return -EOPNOTSUPP; if (!info->attrs[NL80211_ATTR_COALESCE_RULE]) { - cfg80211_rdev_free_coalesce(rdev); + cfg80211_free_coalesce(rdev->coalesce); + rdev->coalesce = NULL; rdev_set_coalesce(rdev, NULL); return 0; } @@ -14033,47 +14031,34 @@ static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info) if (n_rules > coalesce->n_rules) return -EINVAL; - new_coalesce.rules = kcalloc(n_rules, sizeof(new_coalesce.rules[0]), - GFP_KERNEL); - if (!new_coalesce.rules) + new_coalesce = kzalloc(struct_size(new_coalesce, rules, n_rules), + GFP_KERNEL); + if (!new_coalesce) return -ENOMEM; - new_coalesce.n_rules = n_rules; + new_coalesce->n_rules = n_rules; i = 0; nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE], rem_rule) { err = nl80211_parse_coalesce_rule(rdev, rule, - &new_coalesce.rules[i]); + &new_coalesce->rules[i]); if (err) goto error; i++; } - err = rdev_set_coalesce(rdev, &new_coalesce); + err = rdev_set_coalesce(rdev, new_coalesce); if (err) goto error; - n_coalesce = kmemdup(&new_coalesce, sizeof(new_coalesce), GFP_KERNEL); - if (!n_coalesce) { - err = -ENOMEM; - goto error; - } - cfg80211_rdev_free_coalesce(rdev); - rdev->coalesce = n_coalesce; + cfg80211_free_coalesce(rdev->coalesce); + rdev->coalesce = new_coalesce; return 0; error: - for (i = 0; i < new_coalesce.n_rules; i++) { - tmp_rule = &new_coalesce.rules[i]; - if (!tmp_rule) - continue; - for (j = 0; j < tmp_rule->n_patterns; j++) - kfree(tmp_rule->patterns[j].mask); - kfree(tmp_rule->patterns); - } - kfree(new_coalesce.rules); + cfg80211_free_coalesce(new_coalesce); return err; } diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index 6376f3a87f8a..ffaab9a92e5b 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* * Portions of this file - * Copyright (C) 2018, 2020-2022 Intel Corporation + * Copyright (C) 2018, 2020-2024 Intel Corporation */ #ifndef __NET_WIRELESS_NL80211_H #define __NET_WIRELESS_NL80211_H @@ -119,7 +119,7 @@ nl80211_radar_notify(struct cfg80211_registered_device *rdev, void nl80211_send_ap_stopped(struct wireless_dev *wdev, unsigned int link_id); -void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev); +void cfg80211_free_coalesce(struct cfg80211_coalesce *coalesce); /* peer measurement */ int nl80211_pmsr_start(struct sk_buff *skb, struct genl_info *info); -- cgit v1.2.3