mac80211: add boilerplate code for start / stop NAN
This code doesn't do much besides allowing to start and stop the vif. Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Ayala Beker <ayala.beker@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
cb3b7d8765
commit
708d50edb1
@ -3420,6 +3420,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,
|
||||
@ -3655,6 +3658,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);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -3,6 +3,7 @@
|
||||
*
|
||||
* Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright 2013-2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2015-2016 Intel Deutschland GmbH
|
||||
*
|
||||
* This file is GPLv2 as found in COPYING.
|
||||
*/
|
||||
@ -152,6 +153,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)
|
||||
@ -3464,4 +3498,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,
|
||||
};
|
||||
|
@ -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));
|
||||
|
||||
|
@ -162,6 +162,7 @@ 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_NAN ||
|
||||
(sdata->vif.type == NL80211_IFTYPE_MONITOR &&
|
||||
!sdata->vif.mu_mimo_owner)))
|
||||
return;
|
||||
@ -1165,4 +1166,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_conf *conf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
might_sleep();
|
||||
check_sdata_in_driver(sdata);
|
||||
|
||||
trace_drv_start_nan(local, sdata, conf);
|
||||
ret = local->ops->start_nan(&local->hw, &sdata->vif, conf);
|
||||
trace_drv_return_int(local, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void drv_stop_nan(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
might_sleep();
|
||||
check_sdata_in_driver(sdata);
|
||||
|
||||
trace_drv_stop_nan(local, sdata);
|
||||
local->ops->stop_nan(&local->hw, &sdata->vif);
|
||||
trace_drv_return_void(local);
|
||||
}
|
||||
|
||||
#endif /* __MAC80211_DRIVER_OPS */
|
||||
|
@ -327,6 +327,9 @@ static int ieee80211_check_queues(struct ieee80211_sub_if_data *sdata,
|
||||
int n_queues = sdata->local->hw.queues;
|
||||
int i;
|
||||
|
||||
if (iftype == NL80211_IFTYPE_NAN)
|
||||
return 0;
|
||||
|
||||
if (iftype != NL80211_IFTYPE_P2P_DEVICE) {
|
||||
for (i = 0; i < IEEE80211_NUM_ACS; i++) {
|
||||
if (WARN_ON_ONCE(sdata->vif.hw_queue[i] ==
|
||||
@ -647,7 +650,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
|
||||
local->fif_probe_req++;
|
||||
}
|
||||
|
||||
if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE)
|
||||
if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
|
||||
sdata->vif.type != NL80211_IFTYPE_NAN)
|
||||
changed |= ieee80211_reset_erp_info(sdata);
|
||||
ieee80211_bss_info_change_notify(sdata, changed);
|
||||
|
||||
@ -1726,7 +1730,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
if (type == NL80211_IFTYPE_P2P_DEVICE) {
|
||||
if (type == NL80211_IFTYPE_P2P_DEVICE || type == NL80211_IFTYPE_NAN) {
|
||||
struct wireless_dev *wdev;
|
||||
|
||||
sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size,
|
||||
|
@ -821,6 +821,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
|
||||
!local->ops->tdls_recv_channel_switch))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (WARN_ON(local->hw.wiphy->interface_modes &
|
||||
BIT(NL80211_IFTYPE_NAN) &&
|
||||
(!local->ops->start_nan || !local->ops->stop_nan)))
|
||||
return -EINVAL;
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
if (hw->wiphy->wowlan && (!local->ops->suspend || !local->ops->resume))
|
||||
return -EINVAL;
|
||||
|
@ -128,7 +128,8 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local)
|
||||
if (!ieee80211_sdata_running(sdata))
|
||||
continue;
|
||||
|
||||
if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE)
|
||||
if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE ||
|
||||
sdata->vif.type == NL80211_IFTYPE_NAN)
|
||||
continue;
|
||||
|
||||
if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
|
||||
|
@ -1700,6 +1700,56 @@ TRACE_EVENT(drv_get_expected_throughput,
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(drv_start_nan,
|
||||
TP_PROTO(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata,
|
||||
struct cfg80211_nan_conf *conf),
|
||||
|
||||
TP_ARGS(local, sdata, conf),
|
||||
TP_STRUCT__entry(
|
||||
LOCAL_ENTRY
|
||||
VIF_ENTRY
|
||||
__field(u8, master_pref)
|
||||
__field(u8, dual)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
LOCAL_ASSIGN;
|
||||
VIF_ASSIGN;
|
||||
__entry->master_pref = conf->master_pref;
|
||||
__entry->dual = conf->dual;
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
LOCAL_PR_FMT VIF_PR_FMT
|
||||
", master preference: %u, dual: %d",
|
||||
LOCAL_PR_ARG, VIF_PR_ARG, __entry->master_pref,
|
||||
__entry->dual
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(drv_stop_nan,
|
||||
TP_PROTO(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata),
|
||||
|
||||
TP_ARGS(local, sdata),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
LOCAL_ENTRY
|
||||
VIF_ENTRY
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
LOCAL_ASSIGN;
|
||||
VIF_ASSIGN;
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
LOCAL_PR_FMT VIF_PR_FMT,
|
||||
LOCAL_PR_ARG, VIF_PR_ARG
|
||||
)
|
||||
);
|
||||
|
||||
/*
|
||||
* Tracing for API calls that drivers call.
|
||||
*/
|
||||
|
@ -1209,7 +1209,8 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
|
||||
}
|
||||
|
||||
if (sdata->vif.type != NL80211_IFTYPE_MONITOR &&
|
||||
sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE) {
|
||||
sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
|
||||
sdata->vif.type != NL80211_IFTYPE_NAN) {
|
||||
sdata->vif.bss_conf.qos = enable_qos;
|
||||
if (bss_notify)
|
||||
ieee80211_bss_info_change_notify(sdata,
|
||||
|
Loading…
Reference in New Issue
Block a user