struct beacon_data *presp;
        enum nl80211_bss_scan_width scan_width;
        bool have_higher_than_11mbit;
+       bool radar_required = false;
        int err;
 
        sdata_assert_lock(sdata);
                }
                chandef.width = NL80211_CHAN_WIDTH_20;
                chandef.center_freq1 = chan->center_freq;
+               /* check again for downgraded chandef */
+               if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) {
+                       sdata_info(sdata,
+                                  "Failed to join IBSS, beacons forbidden\n");
+                       return;
+               }
+       }
+
+       err = cfg80211_chandef_dfs_required(sdata->local->hw.wiphy,
+                                           &chandef);
+       if (err > 0) {
+               if (!ifibss->userspace_handles_dfs) {
+                       sdata_info(sdata,
+                                  "Failed to join IBSS, DFS channel without control program\n");
+                       return;
+               }
+               radar_required = true;
        }
 
        ieee80211_vif_release_channel(sdata);
        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;
        ieee80211_queue_work(&sdata->local->hw, &sdata->work);
 }
 
+static void ieee80211_ibss_csa_mark_radar(struct ieee80211_sub_if_data *sdata)
+{
+       struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
+       int err;
+
+       /* if the current channel is a DFS channel, mark the channel as
+        * unavailable.
+        */
+       err = cfg80211_chandef_dfs_required(sdata->local->hw.wiphy,
+                                           &ifibss->chandef);
+       if (err > 0)
+               cfg80211_radar_event(sdata->local->hw.wiphy, &ifibss->chandef,
+                                    GFP_ATOMIC);
+}
+
 static bool
 ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
                                  struct ieee802_11_elems *elems,
                goto disconnect;
        }
 
-       if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, ¶ms.chandef,
-                                    IEEE80211_CHAN_DISABLED)) {
+       if (!cfg80211_reg_can_beacon(sdata->local->hw.wiphy, ¶ms.chandef)) {
                sdata_info(sdata,
                           "IBSS %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n",
                           ifibss->bssid,
        if (err < 0)
                goto disconnect;
        if (err) {
-               params.radar_required = true;
+               /* IBSS-DFS only allowed with a control program */
+               if (!ifibss->userspace_handles_dfs)
+                       goto disconnect;
 
-               /* TODO: IBSS-DFS not (yet) supported, disconnect. */
-               goto disconnect;
+               params.radar_required = true;
        }
 
        rcu_read_lock();
        ieee80211_bss_info_change_notify(sdata, err);
        drv_channel_switch_beacon(sdata, ¶ms.chandef);
 
+       ieee80211_ibss_csa_mark_radar(sdata);
+
        return true;
 disconnect:
        ibss_dbg(sdata, "Can't handle channel switch, disconnect\n");
        ieee80211_queue_work(&sdata->local->hw,
                             &ifibss->csa_connection_drop_work);
 
+       ieee80211_ibss_csa_mark_radar(sdata);
+
        return true;
 }
 
 
        sdata->u.ibss.privacy = params->privacy;
        sdata->u.ibss.control_port = params->control_port;
+       sdata->u.ibss.userspace_handles_dfs = params->userspace_handles_dfs;
        sdata->u.ibss.basic_rates = params->basic_rates;
 
        /* fix basic_rates if channel does not support these rates */