+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -1001,7 +1001,6 @@ ieee80211_sta_process_chanswitch(struct
+ }
+
+ ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
+- sdata->vif.csa_active = true;
+
+ mutex_lock(&local->chanctx_mtx);
+ if (local->use_chanctx) {
+@@ -1039,6 +1038,7 @@ ieee80211_sta_process_chanswitch(struct
+ mutex_unlock(&local->chanctx_mtx);
+
+ sdata->csa_chandef = csa_ie.chandef;
++ sdata->vif.csa_active = true;
+
+ if (csa_ie.mode)
+ ieee80211_stop_queues_by_reason(&local->hw,
+--- a/net/mac80211/chan.c
++++ b/net/mac80211/chan.c
+@@ -196,6 +196,8 @@ static bool ieee80211_is_radar_required(
+ {
+ struct ieee80211_sub_if_data *sdata;
+
++ lockdep_assert_held(&local->mtx);
++
+ rcu_read_lock();
+ list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+ if (sdata->radar_required) {
+--- a/net/mac80211/ibss.c
++++ b/net/mac80211/ibss.c
+@@ -294,7 +294,6 @@ static void __ieee80211_sta_join_ibss(st
+ }
+
+ mutex_lock(&local->mtx);
+- ieee80211_vif_release_channel(sdata);
+ if (ieee80211_vif_use_channel(sdata, &chandef,
+ ifibss->fixed_channel ?
+ IEEE80211_CHANCTX_SHARED :
+@@ -303,6 +302,7 @@ static void __ieee80211_sta_join_ibss(st
+ mutex_unlock(&local->mtx);
+ return;
+ }
++ sdata->radar_required = radar_required;
+ mutex_unlock(&local->mtx);
+
+ memcpy(ifibss->bssid, bssid, ETH_ALEN);
+@@ -318,7 +318,6 @@ static void __ieee80211_sta_join_ibss(st
+ rcu_assign_pointer(ifibss->presp, presp);
+ mgmt = (void *)presp->head;
+
+- sdata->radar_required = radar_required;
+ sdata->vif.bss_conf.enable_beacon = true;
+ sdata->vif.bss_conf.beacon_int = beacon_int;
+ sdata->vif.bss_conf.basic_rates = basic_rates;
+@@ -386,7 +385,7 @@ static void __ieee80211_sta_join_ibss(st
+ presp->head_len, 0, GFP_KERNEL);
+ cfg80211_put_bss(local->hw.wiphy, bss);
+ netif_carrier_on(sdata->dev);
+- cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL);
++ cfg80211_ibss_joined(sdata->dev, ifibss->bssid, chan, GFP_KERNEL);
+ }
+
+ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
+@@ -802,6 +801,8 @@ ieee80211_ibss_process_chanswitch(struct
+ int err;
+ u32 sta_flags;
+
++ sdata_assert_lock(sdata);
++
+ sta_flags = IEEE80211_STA_DISABLE_VHT;
+ switch (ifibss->chandef.width) {
+ case NL80211_CHAN_WIDTH_5:
+@@ -1471,6 +1472,11 @@ static void ieee80211_rx_mgmt_probe_req(
+ memcpy(((struct ieee80211_mgmt *) skb->data)->da, mgmt->sa, ETH_ALEN);
+ ibss_dbg(sdata, "Sending ProbeResp to %pM\n", mgmt->sa);
+ IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
++
++ /* avoid excessive retries for probe request to wildcard SSIDs */
++ if (pos[1] == 0)
++ IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_NO_ACK;
++
+ ieee80211_tx_skb(sdata, skb);
+ }
+
+--- a/net/mac80211/mesh.c
++++ b/net/mac80211/mesh.c
+@@ -872,6 +872,8 @@ ieee80211_mesh_process_chnswitch(struct
+ if (!ifmsh->mesh_id)
+ return false;
+
++ sdata_assert_lock(sdata);
++
+ sta_flags = IEEE80211_STA_DISABLE_VHT;
+ switch (sdata->vif.bss_conf.chandef.width) {
+ case NL80211_CHAN_WIDTH_20_NOHT:
+--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+@@ -4658,6 +4658,7 @@ brcmf_notify_connect_status(struct brcmf
+ struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
+ struct net_device *ndev = ifp->ndev;
+ struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
++ struct ieee80211_channel *chan;
+ s32 err = 0;
+
+ if (ifp->vif->mode == WL_MODE_AP) {
+@@ -4665,9 +4666,10 @@ brcmf_notify_connect_status(struct brcmf
+ } else if (brcmf_is_linkup(e)) {
+ brcmf_dbg(CONN, "Linkup\n");
+ if (brcmf_is_ibssmode(ifp->vif)) {
++ chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
+ memcpy(profile->bssid, e->addr, ETH_ALEN);
+ wl_inform_ibss(cfg, ndev, e->addr);
+- cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
++ cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
+ clear_bit(BRCMF_VIF_STATUS_CONNECTING,
+ &ifp->vif->sme_state);
+ set_bit(BRCMF_VIF_STATUS_CONNECTED,
+--- a/drivers/net/wireless/libertas/cfg.c
++++ b/drivers/net/wireless/libertas/cfg.c
+@@ -1766,7 +1766,8 @@ static void lbs_join_post(struct lbs_pri
+ memcpy(priv->wdev->ssid, params->ssid, params->ssid_len);
+ priv->wdev->ssid_len = params->ssid_len;
+
+- cfg80211_ibss_joined(priv->dev, bssid, GFP_KERNEL);
++ cfg80211_ibss_joined(priv->dev, bssid, params->chandef.chan,
++ GFP_KERNEL);
+
+ /* TODO: consider doing this at MACREG_INT_CODE_LINK_SENSED time */
+ priv->connect_status = LBS_CONNECTED;
+--- a/drivers/net/wireless/mwifiex/cfg80211.c
++++ b/drivers/net/wireless/mwifiex/cfg80211.c
+@@ -1881,7 +1881,8 @@ mwifiex_cfg80211_join_ibss(struct wiphy
+ params->privacy);
+ done:
+ if (!ret) {
+- cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL);
++ cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid,
++ params->chandef.chan, GFP_KERNEL);
+ dev_dbg(priv->adapter->dev,
+ "info: joined/created adhoc network with bssid"
+ " %pM successfully\n", priv->cfg_bssid);
+--- a/drivers/net/wireless/rndis_wlan.c
++++ b/drivers/net/wireless/rndis_wlan.c
+@@ -2835,7 +2835,9 @@ static void rndis_wlan_do_link_up_work(s
+ bssid, req_ie, req_ie_len,
+ resp_ie, resp_ie_len, GFP_KERNEL);
+ } else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC)
+- cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL);
++ cfg80211_ibss_joined(usbdev->net, bssid,
++ get_current_channel(usbdev, NULL),
++ GFP_KERNEL);
+
+ kfree(info);
+
+--- a/net/wireless/ibss.c
++++ b/net/wireless/ibss.c
+@@ -14,7 +14,8 @@
+ #include "rdev-ops.h"
+
+
+-void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid)
++void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
++ struct ieee80211_channel *channel)
+ {
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct cfg80211_bss *bss;
+@@ -28,8 +29,7 @@ void __cfg80211_ibss_joined(struct net_d
+ if (!wdev->ssid_len)
+ return;
+
+- bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
+- wdev->ssid, wdev->ssid_len,
++ bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, NULL, 0,
+ WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS);
+
+ if (WARN_ON(!bss))
+@@ -54,21 +54,26 @@ void __cfg80211_ibss_joined(struct net_d
+ #endif
+ }
+
+-void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp)
++void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
++ struct ieee80211_channel *channel, gfp_t gfp)
+ {
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+ struct cfg80211_event *ev;
+ unsigned long flags;
+
+- trace_cfg80211_ibss_joined(dev, bssid);
++ trace_cfg80211_ibss_joined(dev, bssid, channel);
++
++ if (WARN_ON(!channel))
++ return;
+
+ ev = kzalloc(sizeof(*ev), gfp);
+ if (!ev)
+ return;
+
+ ev->type = EVENT_IBSS_JOINED;
+- memcpy(ev->cr.bssid, bssid, ETH_ALEN);
++ memcpy(ev->ij.bssid, bssid, ETH_ALEN);
++ ev->ij.channel = channel;
+
+ spin_lock_irqsave(&wdev->event_lock, flags);
+ list_add_tail(&ev->list, &wdev->event_list);
+@@ -117,6 +122,7 @@ int __cfg80211_join_ibss(struct cfg80211
+
+ wdev->ibss_fixed = params->channel_fixed;
+ wdev->ibss_dfs_possible = params->userspace_handles_dfs;
++ wdev->chandef = params->chandef;
+ #ifdef CPTCFG_CFG80211_WEXT
+ wdev->wext.ibss.chandef = params->chandef;
+ #endif
+@@ -200,6 +206,7 @@ static void __cfg80211_clear_ibss(struct
+
+ wdev->current_bss = NULL;
+ wdev->ssid_len = 0;
++ memset(&wdev->chandef, 0, sizeof(wdev->chandef));
+ #ifdef CPTCFG_CFG80211_WEXT
+ if (!nowext)
+ wdev->wext.ibss.ssid_len = 0;
+--- a/net/wireless/trace.h
++++ b/net/wireless/trace.h
+@@ -2278,11 +2278,6 @@ DECLARE_EVENT_CLASS(cfg80211_rx_evt,
+ TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT, NETDEV_PR_ARG, MAC_PR_ARG(addr))
+ );
+
+-DEFINE_EVENT(cfg80211_rx_evt, cfg80211_ibss_joined,
+- TP_PROTO(struct net_device *netdev, const u8 *addr),
+- TP_ARGS(netdev, addr)
+-);
+-
+ DEFINE_EVENT(cfg80211_rx_evt, cfg80211_rx_spurious_frame,
+ TP_PROTO(struct net_device *netdev, const u8 *addr),
+ TP_ARGS(netdev, addr)
+@@ -2293,6 +2288,24 @@ DEFINE_EVENT(cfg80211_rx_evt, cfg80211_r
+ TP_ARGS(netdev, addr)
+ );
+
++TRACE_EVENT(cfg80211_ibss_joined,
++ TP_PROTO(struct net_device *netdev, const u8 *bssid,
++ struct ieee80211_channel *channel),
++ TP_ARGS(netdev, bssid, channel),
++ TP_STRUCT__entry(
++ NETDEV_ENTRY
++ MAC_ENTRY(bssid)
++ CHAN_ENTRY
++ ),
++ TP_fast_assign(
++ NETDEV_ASSIGN;
++ MAC_ASSIGN(bssid, bssid);
++ CHAN_ASSIGN(channel);
++ ),
++ TP_printk(NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", " CHAN_PR_FMT,
++ NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG)
++);
++
+ TRACE_EVENT(cfg80211_probe_status,
+ TP_PROTO(struct net_device *netdev, const u8 *addr, u64 cookie,
+ bool acked),
+--- a/net/wireless/util.c
++++ b/net/wireless/util.c
+@@ -820,7 +820,8 @@ void cfg80211_process_wdev_events(struct
+ ev->dc.reason, true);
+ break;
+ case EVENT_IBSS_JOINED:
+- __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid);
++ __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid,
++ ev->ij.channel);
+ break;
+ }
+ wdev_unlock(wdev);
+@@ -1356,7 +1357,7 @@ int cfg80211_can_use_iftype_chan(struct
+ */
+ mutex_lock_nested(&wdev_iter->mtx, 1);
+ __acquire(wdev_iter->mtx);
+- cfg80211_get_chan_state(wdev_iter, &ch, &chmode);
++ cfg80211_get_chan_state(wdev_iter, &ch, &chmode, &radar_detect);
+ wdev_unlock(wdev_iter);
+
+ switch (chmode) {
+--- a/net/wireless/chan.c
++++ b/net/wireless/chan.c
+@@ -642,7 +642,8 @@ int cfg80211_set_monitor_channel(struct
+ void
+ cfg80211_get_chan_state(struct wireless_dev *wdev,
+ struct ieee80211_channel **chan,
+- enum cfg80211_chan_mode *chanmode)
++ enum cfg80211_chan_mode *chanmode,
++ u8 *radar_detect)
+ {
+ *chan = NULL;
+ *chanmode = CHAN_MODE_UNDEFINED;
+@@ -660,6 +661,11 @@ cfg80211_get_chan_state(struct wireless_
+ !wdev->ibss_dfs_possible)
+ ? CHAN_MODE_SHARED
+ : CHAN_MODE_EXCLUSIVE;
++
++ /* consider worst-case - IBSS can try to return to the
++ * original user-specified channel as creator */
++ if (wdev->ibss_dfs_possible)
++ *radar_detect |= BIT(wdev->chandef.width);
+ return;
+ }
+ break;
+@@ -674,17 +680,26 @@ cfg80211_get_chan_state(struct wireless_
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_P2P_GO:
+ if (wdev->cac_started) {
+- *chan = wdev->channel;
++ *chan = wdev->chandef.chan;
+ *chanmode = CHAN_MODE_SHARED;
++ *radar_detect |= BIT(wdev->chandef.width);
+ } else if (wdev->beacon_interval) {
+- *chan = wdev->channel;
++ *chan = wdev->chandef.chan;
+ *chanmode = CHAN_MODE_SHARED;
++
++ if (cfg80211_chandef_dfs_required(wdev->wiphy,
++ &wdev->chandef))
++ *radar_detect |= BIT(wdev->chandef.width);
+ }
+ return;
+ case NL80211_IFTYPE_MESH_POINT:
+ if (wdev->mesh_id_len) {
+- *chan = wdev->channel;
++ *chan = wdev->chandef.chan;
+ *chanmode = CHAN_MODE_SHARED;
++
++ if (cfg80211_chandef_dfs_required(wdev->wiphy,
++ &wdev->chandef))
++ *radar_detect |= BIT(wdev->chandef.width);
+ }
+ return;
+ case NL80211_IFTYPE_MONITOR:
+--- a/net/wireless/mesh.c
++++ b/net/wireless/mesh.c
+@@ -195,7 +195,7 @@ int __cfg80211_join_mesh(struct cfg80211
+ if (!err) {
+ memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len);
+ wdev->mesh_id_len = setup->mesh_id_len;
+- wdev->channel = setup->chandef.chan;
++ wdev->chandef = setup->chandef;
+ }
+
+ return err;
+@@ -244,7 +244,7 @@ int cfg80211_set_mesh_channel(struct cfg
+ err = rdev_libertas_set_mesh_channel(rdev, wdev->netdev,
+ chandef->chan);
+ if (!err)
+- wdev->channel = chandef->chan;
++ wdev->chandef = *chandef;
+
+ return err;
+ }
+@@ -276,7 +276,7 @@ static int __cfg80211_leave_mesh(struct
+ err = rdev_leave_mesh(rdev, dev);
+ if (!err) {
+ wdev->mesh_id_len = 0;
+- wdev->channel = NULL;
++ memset(&wdev->chandef, 0, sizeof(wdev->chandef));
+ rdev_set_qos_map(rdev, dev, NULL);
+ }
+
+--- a/net/wireless/mlme.c
++++ b/net/wireless/mlme.c
+@@ -772,7 +772,7 @@ void cfg80211_cac_event(struct net_devic
+ if (WARN_ON(!wdev->cac_started))
+ return;
+
+- if (WARN_ON(!wdev->channel))
++ if (WARN_ON(!wdev->chandef.chan))
+ return;
+
+ switch (event) {