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>steinar/wifi_calib_4_9_kernel
parent
cb3b7d8765
commit
708d50edb1
|
@ -3420,6 +3420,9 @@ enum ieee80211_reconfig_type {
|
||||||
* synchronization which is needed in case driver has in its RSS queues
|
* synchronization which is needed in case driver has in its RSS queues
|
||||||
* pending frames that were received prior to the control path action
|
* pending frames that were received prior to the control path action
|
||||||
* currently taken (e.g. disassociation) but are not processed yet.
|
* 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 {
|
struct ieee80211_ops {
|
||||||
void (*tx)(struct ieee80211_hw *hw,
|
void (*tx)(struct ieee80211_hw *hw,
|
||||||
|
@ -3655,6 +3658,12 @@ struct ieee80211_ops {
|
||||||
void (*wake_tx_queue)(struct ieee80211_hw *hw,
|
void (*wake_tx_queue)(struct ieee80211_hw *hw,
|
||||||
struct ieee80211_txq *txq);
|
struct ieee80211_txq *txq);
|
||||||
void (*sync_rx_queues)(struct ieee80211_hw *hw);
|
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 2006-2010 Johannes Berg <johannes@sipsolutions.net>
|
||||||
* Copyright 2013-2015 Intel Mobile Communications GmbH
|
* Copyright 2013-2015 Intel Mobile Communications GmbH
|
||||||
|
* Copyright (C) 2015-2016 Intel Deutschland GmbH
|
||||||
*
|
*
|
||||||
* This file is GPLv2 as found in COPYING.
|
* 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));
|
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,
|
static int ieee80211_set_noack_map(struct wiphy *wiphy,
|
||||||
struct net_device *dev,
|
struct net_device *dev,
|
||||||
u16 noack_map)
|
u16 noack_map)
|
||||||
|
@ -3464,4 +3498,6 @@ const struct cfg80211_ops mac80211_config_ops = {
|
||||||
.set_ap_chanwidth = ieee80211_set_ap_chanwidth,
|
.set_ap_chanwidth = ieee80211_set_ap_chanwidth,
|
||||||
.add_tx_ts = ieee80211_add_tx_ts,
|
.add_tx_ts = ieee80211_add_tx_ts,
|
||||||
.del_tx_ts = ieee80211_del_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;
|
struct ieee80211_chanctx *curr_ctx = NULL;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_NAN))
|
||||||
|
return -ENOTSUPP;
|
||||||
|
|
||||||
conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
|
conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
|
||||||
lockdep_is_held(&local->chanctx_mtx));
|
lockdep_is_held(&local->chanctx_mtx));
|
||||||
|
|
||||||
|
|
|
@ -162,6 +162,7 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE ||
|
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.type == NL80211_IFTYPE_MONITOR &&
|
||||||
!sdata->vif.mu_mimo_owner)))
|
!sdata->vif.mu_mimo_owner)))
|
||||||
return;
|
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);
|
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 */
|
#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 n_queues = sdata->local->hw.queues;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (iftype == NL80211_IFTYPE_NAN)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (iftype != NL80211_IFTYPE_P2P_DEVICE) {
|
if (iftype != NL80211_IFTYPE_P2P_DEVICE) {
|
||||||
for (i = 0; i < IEEE80211_NUM_ACS; i++) {
|
for (i = 0; i < IEEE80211_NUM_ACS; i++) {
|
||||||
if (WARN_ON_ONCE(sdata->vif.hw_queue[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++;
|
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);
|
changed |= ieee80211_reset_erp_info(sdata);
|
||||||
ieee80211_bss_info_change_notify(sdata, changed);
|
ieee80211_bss_info_change_notify(sdata, changed);
|
||||||
|
|
||||||
|
@ -1726,7 +1730,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
|
||||||
|
|
||||||
ASSERT_RTNL();
|
ASSERT_RTNL();
|
||||||
|
|
||||||
if (type == NL80211_IFTYPE_P2P_DEVICE) {
|
if (type == NL80211_IFTYPE_P2P_DEVICE || type == NL80211_IFTYPE_NAN) {
|
||||||
struct wireless_dev *wdev;
|
struct wireless_dev *wdev;
|
||||||
|
|
||||||
sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size,
|
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))
|
!local->ops->tdls_recv_channel_switch))
|
||||||
return -EOPNOTSUPP;
|
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
|
#ifdef CONFIG_PM
|
||||||
if (hw->wiphy->wowlan && (!local->ops->suspend || !local->ops->resume))
|
if (hw->wiphy->wowlan && (!local->ops->suspend || !local->ops->resume))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -128,7 +128,8 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local)
|
||||||
if (!ieee80211_sdata_running(sdata))
|
if (!ieee80211_sdata_running(sdata))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE)
|
if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE ||
|
||||||
|
sdata->vif.type == NL80211_IFTYPE_NAN)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
|
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.
|
* 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 &&
|
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;
|
sdata->vif.bss_conf.qos = enable_qos;
|
||||||
if (bss_notify)
|
if (bss_notify)
|
||||||
ieee80211_bss_info_change_notify(sdata,
|
ieee80211_bss_info_change_notify(sdata,
|
||||||
|
|
Loading…
Reference in New Issue