]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-client.git/commitdiff
wifi: mac80211: run NAN DE code only when appropriate
authorMiri Korenblit <miriam.rachel.korenblit@intel.com>
Thu, 26 Mar 2026 10:14:34 +0000 (12:14 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 7 Apr 2026 13:36:02 +0000 (15:36 +0200)
NAN DE (Discovery Engine) may be handled in the device or in user space.
When handled in user space, all the NAN func management code should not
run. Moreover, devices with user space DE should not provide the
add/del_nan_func callbaks. For such devices, ieee80211_reconfig_nan will
always fail.

Make it clear what parts of ieee80211_if_nan are relevant to DE
management, and touch those only when DE is offloaded.

Add a check that makes sure that a driver doesn't register with
add_del/nan_func callbacks if DE is in user space.

Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260326121156.6665f64865cd.Iee24bef3bae2e1d502216192e760c1e699d271c9@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/cfg.c
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/main.c
net/mac80211/util.c

index b6163dcc7e92c2f9c18c24d24b7d437ed05a3c37..3a6c5fed2420a17d0ca54621ccf16754e0ae1eb9 100644 (file)
@@ -502,12 +502,15 @@ static int ieee80211_add_nan_func(struct wiphy *wiphy,
        if (!ieee80211_sdata_running(sdata))
                return -ENETDOWN;
 
-       spin_lock_bh(&sdata->u.nan.func_lock);
+       if (WARN_ON(wiphy->nan_capa.flags & WIPHY_NAN_FLAGS_USERSPACE_DE))
+               return -EOPNOTSUPP;
+
+       spin_lock_bh(&sdata->u.nan.de.func_lock);
 
-       ret = idr_alloc(&sdata->u.nan.function_inst_ids,
+       ret = idr_alloc(&sdata->u.nan.de.function_inst_ids,
                        nan_func, 1, sdata->local->hw.max_nan_de_entries + 1,
                        GFP_ATOMIC);
-       spin_unlock_bh(&sdata->u.nan.func_lock);
+       spin_unlock_bh(&sdata->u.nan.de.func_lock);
 
        if (ret < 0)
                return ret;
@@ -518,10 +521,10 @@ static int ieee80211_add_nan_func(struct wiphy *wiphy,
 
        ret = drv_add_nan_func(sdata->local, sdata, nan_func);
        if (ret) {
-               spin_lock_bh(&sdata->u.nan.func_lock);
-               idr_remove(&sdata->u.nan.function_inst_ids,
+               spin_lock_bh(&sdata->u.nan.de.func_lock);
+               idr_remove(&sdata->u.nan.de.function_inst_ids,
                           nan_func->instance_id);
-               spin_unlock_bh(&sdata->u.nan.func_lock);
+               spin_unlock_bh(&sdata->u.nan.de.func_lock);
        }
 
        return ret;
@@ -534,9 +537,9 @@ ieee80211_find_nan_func_by_cookie(struct ieee80211_sub_if_data *sdata,
        struct cfg80211_nan_func *func;
        int id;
 
-       lockdep_assert_held(&sdata->u.nan.func_lock);
+       lockdep_assert_held(&sdata->u.nan.de.func_lock);
 
-       idr_for_each_entry(&sdata->u.nan.function_inst_ids, func, id) {
+       idr_for_each_entry(&sdata->u.nan.de.function_inst_ids, func, id) {
                if (func->cookie == cookie)
                        return func;
        }
@@ -555,13 +558,16 @@ static void ieee80211_del_nan_func(struct wiphy *wiphy,
            !ieee80211_sdata_running(sdata))
                return;
 
-       spin_lock_bh(&sdata->u.nan.func_lock);
+       if (WARN_ON(wiphy->nan_capa.flags & WIPHY_NAN_FLAGS_USERSPACE_DE))
+               return;
+
+       spin_lock_bh(&sdata->u.nan.de.func_lock);
 
        func = ieee80211_find_nan_func_by_cookie(sdata, cookie);
        if (func)
                instance_id = func->instance_id;
 
-       spin_unlock_bh(&sdata->u.nan.func_lock);
+       spin_unlock_bh(&sdata->u.nan.de.func_lock);
 
        if (instance_id)
                drv_del_nan_func(sdata->local, sdata, instance_id);
@@ -4888,18 +4894,22 @@ void ieee80211_nan_func_terminated(struct ieee80211_vif *vif,
        if (WARN_ON(vif->type != NL80211_IFTYPE_NAN))
                return;
 
-       spin_lock_bh(&sdata->u.nan.func_lock);
+       if (WARN_ON(sdata->local->hw.wiphy->nan_capa.flags &
+                   WIPHY_NAN_FLAGS_USERSPACE_DE))
+               return;
+
+       spin_lock_bh(&sdata->u.nan.de.func_lock);
 
-       func = idr_find(&sdata->u.nan.function_inst_ids, inst_id);
+       func = idr_find(&sdata->u.nan.de.function_inst_ids, inst_id);
        if (WARN_ON(!func)) {
-               spin_unlock_bh(&sdata->u.nan.func_lock);
+               spin_unlock_bh(&sdata->u.nan.de.func_lock);
                return;
        }
 
        cookie = func->cookie;
-       idr_remove(&sdata->u.nan.function_inst_ids, inst_id);
+       idr_remove(&sdata->u.nan.de.function_inst_ids, inst_id);
 
-       spin_unlock_bh(&sdata->u.nan.func_lock);
+       spin_unlock_bh(&sdata->u.nan.de.func_lock);
 
        cfg80211_free_nan_func(func);
 
@@ -4918,16 +4928,20 @@ void ieee80211_nan_func_match(struct ieee80211_vif *vif,
        if (WARN_ON(vif->type != NL80211_IFTYPE_NAN))
                return;
 
-       spin_lock_bh(&sdata->u.nan.func_lock);
+       if (WARN_ON(sdata->local->hw.wiphy->nan_capa.flags &
+                   WIPHY_NAN_FLAGS_USERSPACE_DE))
+               return;
+
+       spin_lock_bh(&sdata->u.nan.de.func_lock);
 
-       func = idr_find(&sdata->u.nan.function_inst_ids,  match->inst_id);
+       func = idr_find(&sdata->u.nan.de.function_inst_ids,  match->inst_id);
        if (WARN_ON(!func)) {
-               spin_unlock_bh(&sdata->u.nan.func_lock);
+               spin_unlock_bh(&sdata->u.nan.de.func_lock);
                return;
        }
        match->cookie = func->cookie;
 
-       spin_unlock_bh(&sdata->u.nan.func_lock);
+       spin_unlock_bh(&sdata->u.nan.de.func_lock);
 
        cfg80211_nan_match(ieee80211_vif_to_wdev(vif), match, gfp);
 }
index 53d78376964245f48ee946da38bf18c575b9924f..8d5f9a725fdfeb6a19f9e9789dbaca0679067dce 100644 (file)
@@ -987,16 +987,19 @@ struct ieee80211_if_mntr {
  *
  * @conf: current NAN configuration
  * @started: true iff NAN is started
- * @func_lock: lock for @func_inst_ids
- * @function_inst_ids: a bitmap of available instance_id's
+ * @de: Discovery Engine state (only valid if !WIPHY_NAN_FLAGS_USERSPACE_DE)
+ * @de.func_lock: lock for @de.function_inst_ids
+ * @de.function_inst_ids: a bitmap of available instance_id's
  */
 struct ieee80211_if_nan {
        struct cfg80211_nan_conf conf;
        bool started;
 
-       /* protects function_inst_ids */
-       spinlock_t func_lock;
-       struct idr function_inst_ids;
+       struct {
+               /* protects function_inst_ids */
+               spinlock_t func_lock;
+               struct idr function_inst_ids;
+       } de;
 };
 
 struct ieee80211_link_data_managed {
index 7518dcbcdf1c6ceccc8603766638211e63288678..f0a5a675c5a5e0a4388849934e06e109d947fc04 100644 (file)
@@ -622,15 +622,19 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
                break;
        case NL80211_IFTYPE_NAN:
                /* clean all the functions */
-               spin_lock_bh(&sdata->u.nan.func_lock);
+               if (!(local->hw.wiphy->nan_capa.flags &
+                     WIPHY_NAN_FLAGS_USERSPACE_DE)) {
+                       spin_lock_bh(&sdata->u.nan.de.func_lock);
+
+                       idr_for_each_entry(&sdata->u.nan.de.function_inst_ids,
+                                          func, i) {
+                               idr_remove(&sdata->u.nan.de.function_inst_ids, i);
+                               cfg80211_free_nan_func(func);
+                       }
+                       idr_destroy(&sdata->u.nan.de.function_inst_ids);
 
-               idr_for_each_entry(&sdata->u.nan.function_inst_ids, func, i) {
-                       idr_remove(&sdata->u.nan.function_inst_ids, i);
-                       cfg80211_free_nan_func(func);
+                       spin_unlock_bh(&sdata->u.nan.de.func_lock);
                }
-               idr_destroy(&sdata->u.nan.function_inst_ids);
-
-               spin_unlock_bh(&sdata->u.nan.func_lock);
                break;
        default:
                wiphy_work_cancel(sdata->local->hw.wiphy, &sdata->work);
@@ -1942,8 +1946,11 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
                                      MONITOR_FLAG_OTHER_BSS;
                break;
        case NL80211_IFTYPE_NAN:
-               idr_init(&sdata->u.nan.function_inst_ids);
-               spin_lock_init(&sdata->u.nan.func_lock);
+               if (!(sdata->local->hw.wiphy->nan_capa.flags &
+                     WIPHY_NAN_FLAGS_USERSPACE_DE)) {
+                       idr_init(&sdata->u.nan.de.function_inst_ids);
+                       spin_lock_init(&sdata->u.nan.de.func_lock);
+               }
                sdata->vif.bss_conf.bssid = sdata->vif.addr;
                break;
        case NL80211_IFTYPE_AP_VLAN:
index d1bb6353908dbcb9257c39e1ed73ef49c9d17491..f47dd58770adb9b88fa8067f6cc363d907e356f5 100644 (file)
@@ -1157,7 +1157,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 
        if (WARN_ON(local->hw.wiphy->interface_modes &
                        BIT(NL80211_IFTYPE_NAN) &&
-                   (!local->ops->start_nan || !local->ops->stop_nan)))
+                   ((!local->ops->start_nan || !local->ops->stop_nan) ||
+                    (local->hw.wiphy->nan_capa.flags & WIPHY_NAN_FLAGS_USERSPACE_DE &&
+                    (local->ops->add_nan_func || local->ops->del_nan_func)))))
                return -EINVAL;
 
        if (hw->wiphy->flags & WIPHY_FLAG_SUPPORTS_MLO) {
index 38b0c42c4c131316f2f9f4e008e2c0e5c8b56dbe..36795529ff82297278c85c4f12b46d72fbb14a62 100644 (file)
@@ -1754,6 +1754,10 @@ static int ieee80211_reconfig_nan(struct ieee80211_sub_if_data *sdata)
        if (WARN_ON(res))
                return res;
 
+       if (sdata->local->hw.wiphy->nan_capa.flags &
+           WIPHY_NAN_FLAGS_USERSPACE_DE)
+               return 0;
+
        funcs = kzalloc_objs(*funcs, sdata->local->hw.max_nan_de_entries + 1);
        if (!funcs)
                return -ENOMEM;
@@ -1762,12 +1766,12 @@ static int ieee80211_reconfig_nan(struct ieee80211_sub_if_data *sdata)
         * This is a little bit ugly. We need to call a potentially sleeping
         * callback for each NAN function, so we can't hold the spinlock.
         */
-       spin_lock_bh(&sdata->u.nan.func_lock);
+       spin_lock_bh(&sdata->u.nan.de.func_lock);
 
-       idr_for_each_entry(&sdata->u.nan.function_inst_ids, func, id)
+       idr_for_each_entry(&sdata->u.nan.de.function_inst_ids, func, id)
                funcs[i++] = func;
 
-       spin_unlock_bh(&sdata->u.nan.func_lock);
+       spin_unlock_bh(&sdata->u.nan.de.func_lock);
 
        for (i = 0; funcs[i]; i++) {
                res = drv_add_nan_func(sdata->local, sdata, funcs[i]);