This codes doens't do much besides allowing to start and
stop the vif.
Signed-off-by: Andrei Otcheretianski
Signed-off-by: Emmanuel Grumbach
---
include/net/mac80211.h| 9 +
net/mac80211/cfg.c| 35 +
net/mac80211/chan.c | 3 +++
net/mac80211/driver-ops.h | 29 ++-
net/mac80211/iface.c | 8 ++--
net/mac80211/main.c | 5 +
net/mac80211/offchannel.c | 3 ++-
net/mac80211/trace.h | 50 +++
net/mac80211/util.c | 3 ++-
9 files changed, 140 insertions(+), 5 deletions(-)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index a5c..12860de 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -3358,6 +3358,9 @@ enum ieee80211_reconfig_type {
* synchronization which is needed in case driver has in its RSS queues
* pending frames that were received prior to the control path action
* currently taken (e.g. disassociation) but are not processed yet.
+ *
+ * @start_nan: join an existing nan cluster, or create a new one.
+ * @stop_nan: leave the nan cluster.
*/
struct ieee80211_ops {
void (*tx)(struct ieee80211_hw *hw,
@@ -3596,6 +3599,12 @@ struct ieee80211_ops {
void (*wake_tx_queue)(struct ieee80211_hw *hw,
struct ieee80211_txq *txq);
void (*sync_rx_queues)(struct ieee80211_hw *hw);
+
+ int (*start_nan)(struct ieee80211_hw *hw,
+struct ieee80211_vif *vif,
+struct cfg80211_nan_conf *conf);
+ int (*stop_nan)(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif);
};
/**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 80a5958..a9d66b4 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -129,6 +129,39 @@ static void ieee80211_stop_p2p_device(struct wiphy *wiphy,
ieee80211_sdata_stop(IEEE80211_WDEV_TO_SUB_IF(wdev));
}
+static int ieee80211_start_nan(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ struct cfg80211_nan_conf *conf)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
+ int ret;
+
+ mutex_lock(&sdata->local->chanctx_mtx);
+ ret = ieee80211_check_combinations(sdata, NULL, 0, 0);
+ mutex_unlock(&sdata->local->chanctx_mtx);
+ if (ret < 0)
+ return ret;
+
+ ret = ieee80211_do_open(wdev, true);
+ if (ret)
+ return ret;
+
+ ret = drv_start_nan(sdata->local, sdata, conf);
+ if (ret)
+ ieee80211_sdata_stop(sdata);
+
+ return ret;
+}
+
+static void ieee80211_stop_nan(struct wiphy *wiphy,
+ struct wireless_dev *wdev)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
+
+ drv_stop_nan(sdata->local, sdata);
+ ieee80211_sdata_stop(sdata);
+}
+
static int ieee80211_set_noack_map(struct wiphy *wiphy,
struct net_device *dev,
u16 noack_map)
@@ -3438,4 +3471,6 @@ const struct cfg80211_ops mac80211_config_ops = {
.set_ap_chanwidth = ieee80211_set_ap_chanwidth,
.add_tx_ts = ieee80211_add_tx_ts,
.del_tx_ts = ieee80211_del_tx_ts,
+ .start_nan = ieee80211_start_nan,
+ .stop_nan = ieee80211_stop_nan,
};
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index acb50f8..e4d147e 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -647,6 +647,9 @@ static int ieee80211_assign_vif_chanctx(struct
ieee80211_sub_if_data *sdata,
struct ieee80211_chanctx *curr_ctx = NULL;
int ret = 0;
+ if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_NAN))
+ return -ENOTSUPP;
+
conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
lockdep_is_held(&local->chanctx_mtx));
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 184473c..3352ce2 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -162,7 +162,8 @@ static inline void drv_bss_info_changed(struct
ieee80211_local *local,
return;
if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE ||
-sdata->vif.type == NL80211_IFTYPE_MONITOR))
+sdata->vif.type == NL80211_IFTYPE_MONITOR ||
+sdata->vif.type == NL80211_IFTYPE_NAN))
return;
if (!check_sdata_in_driver(sdata))
@@ -1179,4 +1180,30 @@ static inline void drv_wake_tx_queue(struct
ieee80211_local *local,
local->ops->wake_tx_queue(&local->hw, &txq->txq);
}
+static inline int drv_start_nan(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_nan_co