diff --git a/components/nan/core/src/nan_api.c b/components/nan/core/src/nan_api.c
index 96f4801846..769c4722b0 100644
--- a/components/nan/core/src/nan_api.c
+++ b/components/nan/core/src/nan_api.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -29,6 +29,7 @@
#include "wlan_objmgr_psoc_obj.h"
#include "wlan_objmgr_pdev_obj.h"
#include "wlan_objmgr_vdev_obj.h"
+#include "nan_ucfg_api.h"
static QDF_STATUS nan_psoc_obj_created_notification(
struct wlan_objmgr_psoc *psoc, void *arg_list)
@@ -94,8 +95,18 @@ static QDF_STATUS nan_vdev_obj_created_notification(
{
struct nan_vdev_priv_obj *nan_obj;
QDF_STATUS status = QDF_STATUS_SUCCESS;
+ struct wlan_objmgr_psoc *psoc;
nan_debug("nan_vdev_create_notif called");
+ if (ucfg_is_nan_vdev(vdev)) {
+ psoc = wlan_vdev_get_psoc(vdev);
+ if (!psoc) {
+ nan_err("psoc is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+ target_if_nan_set_vdev_feature_config(psoc,
+ wlan_vdev_get_id(vdev));
+ }
if (wlan_vdev_mlme_get_opmode(vdev) != QDF_NDI_MODE) {
nan_debug("not a ndi vdev. do nothing");
return QDF_STATUS_SUCCESS;
diff --git a/components/nan/core/src/nan_main_i.h b/components/nan/core/src/nan_main_i.h
index 1ce050c9be..478e3a6631 100644
--- a/components/nan/core/src/nan_main_i.h
+++ b/components/nan/core/src/nan_main_i.h
@@ -85,6 +85,9 @@ enum nan_disc_state {
* Preference (MP) as 0 when a new device is enabling NAN
* @max_ndp_sessions: max ndp sessions host supports
* @max_ndi: max number of ndi host supports
+ * @nan_feature_config: Bitmap to enable/disable a particular NAN feature
+ * configuration in firmware. It's sent to firmware through
+ * WMI_VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES
*/
struct nan_cfg_params {
bool enable;
@@ -96,6 +99,7 @@ struct nan_cfg_params {
bool support_mp0_discovery;
uint32_t max_ndp_sessions;
uint32_t max_ndi;
+ uint32_t nan_feature_config;
};
/**
diff --git a/components/nan/dispatcher/inc/cfg_nan.h b/components/nan/dispatcher/inc/cfg_nan.h
index 2e0cc648e1..5de3336102 100644
--- a/components/nan/dispatcher/inc/cfg_nan.h
+++ b/components/nan/dispatcher/inc/cfg_nan.h
@@ -239,6 +239,38 @@
CFG_VALUE_OR_DEFAULT, \
"Max number of NDI host supports")
+/*
+ *
+ * nan_feature_config - Bitmap to enable/disable a particular NAN/NDP feature
+ *
+ * @Min: 0
+ * @Max: 0xFFFF
+ * @Default: 0x1
+ *
+ * This parameter helps to enable/disable a particular feature config by setting
+ * corresponding bit and send to firmware through the VDEV param
+ * WMI_VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES
+ * Acceptable values for this:
+ * BIT(0): Allow DW configuration from framework in sync role.
+ * If this is not set, firmware shall follow the spec/default behavior.
+ * BIT(1) to BIT(31): Reserved
+ *
+ * Related: None
+ *
+ * Supported Feature: NAN
+ *
+ * Usage: External
+ *
+ *
+ */
+#define CFG_NAN_FEATURE_CONFIG CFG_INI_UINT( \
+ "nan_feature_config", \
+ 0, \
+ 0xFFFF, \
+ 1, \
+ CFG_VALUE_OR_DEFAULT, \
+ "Enable the specified NAN features in firmware")
+
#ifdef WLAN_FEATURE_NAN
#define CFG_NAN_DISC CFG(CFG_NAN_ENABLE) \
CFG(CFG_NDP_KEEP_ALIVE_PERIOD) \
@@ -255,6 +287,7 @@
#define CFG_NAN_ALL CFG_NAN_DISC \
CFG_NAN_DP \
CFG(CFG_NDP_MAX_SESSIONS) \
- CFG(CFG_NDI_MAX_SUPPORT)
+ CFG(CFG_NDI_MAX_SUPPORT) \
+ CFG(CFG_NAN_FEATURE_CONFIG)
#endif
diff --git a/components/nan/dispatcher/inc/nan_ucfg_api.h b/components/nan/dispatcher/inc/nan_ucfg_api.h
index de4d6f14e5..f71dc005ff 100644
--- a/components/nan/dispatcher/inc/nan_ucfg_api.h
+++ b/components/nan/dispatcher/inc/nan_ucfg_api.h
@@ -423,6 +423,28 @@ QDF_STATUS ucfg_disable_nan_discovery(struct wlan_objmgr_psoc *psoc,
*/
QDF_STATUS
ucfg_nan_disable_ndi(struct wlan_objmgr_psoc *psoc, uint32_t ndi_vdev_id);
+
+/**
+ * ucfg_get_nan_feature_config() - Get NAN feature bitmap
+ * @psoc: pointer to psoc object
+ * @nan_feature_config: NAN feature config bitmap to be enabled in firmware
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ucfg_get_nan_feature_config(struct wlan_objmgr_psoc *psoc,
+ uint32_t *nan_feature_config);
+
+/**
+ * ucfg_is_nan_vdev() - Check if the current vdev supports NAN or not
+ * @vdev: pointer to vdev object
+ *
+ * Return true
+ * 1. If the VDEV type is NAN_DISC or
+ * 2. If the VDEV type is STA and nan_separate_iface feature is not supported
+ *
+ * Return: Bool
+ */
+bool ucfg_is_nan_vdev(struct wlan_objmgr_vdev *vdev);
#else /* WLAN_FEATURE_NAN */
static inline
@@ -511,5 +533,18 @@ bool ucfg_is_nan_disable_supported(struct wlan_objmgr_psoc *psoc)
{
return false;
}
+
+static inline
+QDF_STATUS ucfg_get_nan_feature_config(struct wlan_objmgr_psoc *psoc,
+ uint32_t *nan_feature_config)
+{
+ return QDF_STATUS_SUCCESS;
+}
+
+static inline
+bool ucfg_is_nan_vdev(struct wlan_objmgr_vdev *vdev)
+{
+ return false;
+}
#endif /* WLAN_FEATURE_NAN */
#endif /* _NAN_UCFG_API_H_ */
diff --git a/components/nan/dispatcher/src/nan_ucfg_api.c b/components/nan/dispatcher/src/nan_ucfg_api.c
index e057fcb657..be147f5c58 100644
--- a/components/nan/dispatcher/src/nan_ucfg_api.c
+++ b/components/nan/dispatcher/src/nan_ucfg_api.c
@@ -57,6 +57,8 @@ static void nan_cfg_init(struct wlan_objmgr_psoc *psoc,
nan_obj->cfg_param.max_ndp_sessions = cfg_get(psoc,
CFG_NDP_MAX_SESSIONS);
nan_obj->cfg_param.max_ndi = cfg_get(psoc, CFG_NDI_MAX_SUPPORT);
+ nan_obj->cfg_param.nan_feature_config =
+ cfg_get(psoc, CFG_NAN_FEATURE_CONFIG);
}
/**
@@ -1196,3 +1198,29 @@ ucfg_nan_set_vdev_creation_supp_by_fw(struct wlan_objmgr_psoc *psoc, bool set)
psoc_nan_obj->nan_caps.nan_vdev_allowed = set;
}
+
+QDF_STATUS ucfg_get_nan_feature_config(struct wlan_objmgr_psoc *psoc,
+ uint32_t *nan_feature_config)
+{
+ struct nan_psoc_priv_obj *psoc_nan_obj;
+
+ psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
+ if (!psoc_nan_obj) {
+ nan_err("psoc_nan_obj is null");
+ *nan_feature_config = cfg_default(CFG_NAN_FEATURE_CONFIG);
+ return QDF_STATUS_E_INVAL;
+ }
+
+ *nan_feature_config = psoc_nan_obj->cfg_param.nan_feature_config;
+ return QDF_STATUS_SUCCESS;
+}
+
+bool ucfg_is_nan_vdev(struct wlan_objmgr_vdev *vdev)
+{
+ if (wlan_vdev_mlme_get_opmode(vdev) == QDF_NAN_DISC_MODE ||
+ (!ucfg_nan_is_vdev_creation_allowed(wlan_vdev_get_psoc(vdev)) &&
+ wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE))
+ return true;
+
+ return false;
+}
diff --git a/components/target_if/nan/inc/target_if_nan.h b/components/target_if/nan/inc/target_if_nan.h
index be4a57a245..38370cdde9 100644
--- a/components/target_if/nan/inc/target_if_nan.h
+++ b/components/target_if/nan/inc/target_if_nan.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018, 2020 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -98,4 +98,14 @@ QDF_STATUS target_if_nan_deregister_events(struct wlan_objmgr_psoc *psoc);
* Return: 0 for success or error code
*/
int target_if_nan_rsp_handler(ol_scn_t scn, uint8_t *data, uint32_t len);
+
+/**
+ * target_if_nan_set_vdev_feature_config() - Init NAN feature config params
+ * @psoc: Pointer to PSOC Object
+ * @vdev_id: vdev_id of the current vdev
+ *
+ * This function updates NAN feature config bitmap to firmware
+ */
+void target_if_nan_set_vdev_feature_config(struct wlan_objmgr_psoc *psoc,
+ uint8_t vdev_id);
#endif /* _WIFI_POS_TGT_IF_H_ */
diff --git a/components/target_if/nan/src/target_if_nan.c b/components/target_if/nan/src/target_if_nan.c
index b44120a871..05bceb5117 100644
--- a/components/target_if/nan/src/target_if_nan.c
+++ b/components/target_if/nan/src/target_if_nan.c
@@ -27,6 +27,7 @@
#include "wlan_nan_api.h"
#include "wmi_unified_api.h"
#include "scheduler_api.h"
+#include
static QDF_STATUS target_if_nan_event_flush_cb(struct scheduler_msg *msg)
{
@@ -1163,3 +1164,29 @@ QDF_STATUS target_if_nan_deregister_events(struct wlan_objmgr_psoc *psoc)
else
return QDF_STATUS_SUCCESS;
}
+
+void target_if_nan_set_vdev_feature_config(struct wlan_objmgr_psoc *psoc,
+ uint8_t vdev_id)
+{
+ QDF_STATUS status;
+ uint32_t nan_features;
+ struct vdev_set_params param;
+ wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+
+ if (!wmi_handle) {
+ target_if_err("Invalid wmi handle");
+ return;
+ }
+
+ ucfg_get_nan_feature_config(psoc, &nan_features);
+ target_if_debug("vdev_id:%d NAN features:0x%x", vdev_id, nan_features);
+
+ param.vdev_id = vdev_id;
+ param.param_id = WMI_VDEV_PARAM_ENABLE_DISABLE_NAN_CONFIG_FEATURES;
+ param.param_value = nan_features;
+
+ status = wmi_unified_vdev_set_param_send(wmi_handle, ¶m);
+ if (QDF_IS_STATUS_ERROR(status))
+ target_if_err("failed to set NAN_CONFIG_FEATURES(status = %d)",
+ status);
+}