diff options
| author | Miri Korenblit <miriam.rachel.korenblit@intel.com> | 2026-03-26 12:14:36 +0200 |
|---|---|---|
| committer | Johannes Berg <johannes.berg@intel.com> | 2026-04-07 15:36:03 +0200 |
| commit | d6c470def51cd9ccc59c882e14ace478022b5a4a (patch) | |
| tree | a8155a7e3daac6e0ba9f6bc31d30251876de6892 /net/mac80211/iface.c | |
| parent | 589c06e8fdeec592e018004cebe283370160e581 (diff) | |
| download | linux-next-d6c470def51cd9ccc59c882e14ace478022b5a4a.tar.gz linux-next-d6c470def51cd9ccc59c882e14ace478022b5a4a.zip | |
wifi: mac80211: support open and close for NAN_DATA interfaces
Support opening and closing a NAN_DATA interface.
Track the NAN (NMI) interface, for convenience.
Allow opening an NAN_DATA interface only if the NAN interface is running
(NAN has started).
When closing the NAN interface, make sure all NAN_DATA interfaces are
closed first, and warn if this is not the case.
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260326121156.a19de68119e5.Ia6724dac6a0e17cb69989dd714d14f4df1c69bef@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/iface.c')
| -rw-r--r-- | net/mac80211/iface.c | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 0f3e49cdbb39..507c5e016ec8 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -362,6 +362,17 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, return -EBUSY; /* + * A NAN DATA interface is correlated to the NAN + * (management) one + */ + if (iftype == NL80211_IFTYPE_NAN_DATA && + nsdata->vif.type == NL80211_IFTYPE_NAN) { + if (!nsdata->u.nan.started) + return -EINVAL; + rcu_assign_pointer(sdata->u.nan_data.nmi, nsdata); + } + + /* * Allow only a single IBSS interface to be up at any * time. This is restricted because beacon distribution * cannot work properly if both are in the same IBSS. @@ -475,6 +486,7 @@ static int ieee80211_open(struct net_device *dev) static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_down) { struct ieee80211_local *local = sdata->local; + struct ieee80211_sub_if_data *iter; unsigned long flags; struct sk_buff_head freeq; struct sk_buff *skb, *tmp; @@ -621,6 +633,12 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do } break; case NL80211_IFTYPE_NAN: + /* Check if any open NAN_DATA interfaces */ + list_for_each_entry(iter, &local->interfaces, list) { + WARN_ON(iter->vif.type == NL80211_IFTYPE_NAN_DATA && + ieee80211_sdata_running(iter)); + } + /* clean all the functions */ if (!(local->hw.wiphy->nan_capa.flags & WIPHY_NAN_FLAGS_USERSPACE_DE)) { @@ -636,6 +654,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do spin_unlock_bh(&sdata->u.nan.de.func_lock); } break; + case NL80211_IFTYPE_NAN_DATA: + RCU_INIT_POINTER(sdata->u.nan_data.nmi, NULL); + fallthrough; default: wiphy_work_cancel(sdata->local->hw.wiphy, &sdata->work); /* @@ -1384,9 +1405,12 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) case NL80211_IFTYPE_P2P_DEVICE: case NL80211_IFTYPE_OCB: case NL80211_IFTYPE_NAN: - case NL80211_IFTYPE_NAN_DATA: /* no special treatment */ break; + case NL80211_IFTYPE_NAN_DATA: + if (WARN_ON(!rcu_access_pointer(sdata->u.nan_data.nmi))) + return -ENOLINK; + break; case NL80211_IFTYPE_UNSPECIFIED: case NUM_NL80211_IFTYPES: case NL80211_IFTYPE_P2P_CLIENT: @@ -1404,8 +1428,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) res = drv_start(local); if (res) { /* - * no need to worry about AP_VLAN cleanup since in that - * case we can't have open_count == 0 + * no need to worry about AP_VLAN/NAN_DATA cleanup since + * in that case we can't have open_count == 0 */ return res; } @@ -1524,6 +1548,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) case NL80211_IFTYPE_AP: case NL80211_IFTYPE_MESH_POINT: case NL80211_IFTYPE_OCB: + case NL80211_IFTYPE_NAN_DATA: netif_carrier_off(dev); break; case NL80211_IFTYPE_P2P_DEVICE: @@ -1570,6 +1595,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) err_stop: if (!local->open_count) drv_stop(local, false); + if (sdata->vif.type == NL80211_IFTYPE_NAN_DATA) + RCU_INIT_POINTER(sdata->u.nan_data.nmi, NULL); if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) list_del(&sdata->u.vlan.list); /* Might not be initialized yet, but it is harmless */ |
