Bläddra i källkod

qcacmn: Spectral control path changes

Add a new request structure for Specteral control path.
This structure packages all the commands and their
required inputs. Response to the commands are filled
in this structure by the command handlers in lower
layers.

CRs-Fixed: 2446466
Change-Id: I3113e8721382d284b4e03e0f8fdab1e68d5cfaa1
Edayilliam Jayadev 6 år sedan
förälder
incheckning
14f9bd4194

+ 108 - 233
os_if/linux/spectral/src/wlan_cfg80211_spectral.c

@@ -107,185 +107,6 @@ static void wlan_spectral_intit_config(struct spectral_config *config_req)
 	config_req->ss_chn_mask =        SPECTRAL_PHYERR_PARAM_NOVAL;
 }
 
-static int wlan_spectral_set_config(struct wlan_objmgr_pdev *pdev,
-				    struct spectral_config *config_req)
-{
-	int status;
-
-	status = ucfg_spectral_control(pdev,
-				       SPECTRAL_SET_CONFIG,
-				       config_req,
-				       sizeof(struct spectral_config),
-				       NULL,
-				       NULL);
-	if (status < 0)
-		return -EINVAL;
-
-	return 0;
-}
-
-static int wlan_spectral_set_debug_level(struct wlan_objmgr_pdev *pdev,
-					 uint32_t spectral_dbg_level)
-{
-	int status;
-
-	status = ucfg_spectral_control(pdev,
-				       SPECTRAL_SET_DEBUG_LEVEL,
-				       &spectral_dbg_level,
-				       sizeof(uint32_t),
-				       NULL,
-				       NULL);
-	if (status < 0)
-		return -EINVAL;
-
-	return 0;
-}
-
-static int wlan_spectral_get_debug_level(struct wlan_objmgr_pdev *pdev,
-					 uint32_t *spectral_dbg_level)
-{
-	int status;
-	uint32_t outsize;
-
-	outsize = sizeof(uint32_t);
-	status = ucfg_spectral_control(pdev,
-				       SPECTRAL_GET_DEBUG_LEVEL,
-				       NULL,
-				       0,
-				       spectral_dbg_level,
-				       &outsize);
-	if (status < 0)
-		return -EINVAL;
-
-	return 0;
-}
-
-static int wlan_spectral_get_config(struct wlan_objmgr_pdev *pdev,
-				    struct spectral_config *config_req)
-{
-	int status;
-	uint32_t outsize;
-
-	outsize = sizeof(struct spectral_config);
-	status = ucfg_spectral_control(pdev,
-				       SPECTRAL_GET_CONFIG,
-				       NULL,
-				       0,
-				       config_req,
-				       &outsize);
-	if (status < 0)
-		return -EINVAL;
-
-	return 0;
-}
-
-static int wlan_spectral_get_cap(struct wlan_objmgr_pdev *pdev,
-				 struct spectral_caps *spectral_cap)
-{
-	int status;
-	uint32_t outsize;
-
-	outsize = sizeof(struct spectral_caps);
-	status = ucfg_spectral_control(pdev,
-				       SPECTRAL_GET_CAPABILITY_INFO,
-				       NULL,
-				       0,
-				       spectral_cap,
-				       &outsize);
-	if (status < 0)
-		return -EINVAL;
-
-	return 0;
-}
-
-static int wlan_spectral_get_diag_stats(
-		struct wlan_objmgr_pdev *pdev,
-		struct spectral_diag_stats *spectral_diag)
-{
-	int status;
-	uint32_t outsize;
-
-	outsize = sizeof(struct spectral_diag_stats);
-	status = ucfg_spectral_control(pdev,
-				       SPECTRAL_GET_DIAG_STATS,
-				       NULL,
-				       0,
-				       spectral_diag,
-				       &outsize);
-	if (status < 0)
-		return -EINVAL;
-
-	return 0;
-}
-
-static int wlan_spectral_scan_get_status(
-		struct wlan_objmgr_pdev *pdev,
-		struct spectral_scan_state *sscan_state)
-{
-	uint32_t is_active;
-	uint32_t is_enabled;
-	int status;
-	uint32_t outsize;
-
-	outsize = sizeof(uint32_t);
-	status = ucfg_spectral_control(pdev,
-				       SPECTRAL_IS_ACTIVE,
-				       NULL,
-				       0,
-				       &is_active,
-				       &outsize);
-	if (status < 0)
-		return -EINVAL;
-
-	sscan_state->is_active = is_active;
-
-	outsize = sizeof(uint32_t);
-	status = ucfg_spectral_control(pdev,
-				       SPECTRAL_IS_ENABLED,
-				       NULL,
-				       0,
-				       &is_enabled,
-				       &outsize);
-	if (status < 0)
-		return -EINVAL;
-
-	sscan_state->is_enabled = is_enabled;
-
-	return 0;
-}
-
-static int wlan_start_spectral_scan(struct wlan_objmgr_pdev *pdev)
-{
-	int status;
-
-	status = ucfg_spectral_control(pdev,
-				       SPECTRAL_ACTIVATE_SCAN,
-				       NULL,
-				       0,
-				       NULL,
-				       NULL);
-	if (status < 0)
-		return -EINVAL;
-
-	return 0;
-}
-
-static int wlan_stop_spectral_scan(struct wlan_objmgr_pdev *pdev)
-{
-	int status;
-
-	status = ucfg_spectral_control(pdev,
-				       SPECTRAL_STOP_SCAN,
-				       NULL,
-				       0,
-				       NULL,
-				       NULL);
-	if (status < 0)
-		return -EINVAL;
-
-	return 0;
-}
-
 int wlan_cfg80211_spectral_scan_config_and_start(struct wiphy *wiphy,
 						 struct wlan_objmgr_pdev *pdev,
 						 const void *data,
@@ -298,6 +119,8 @@ int wlan_cfg80211_spectral_scan_config_and_start(struct wiphy *wiphy,
 	struct sk_buff *skb;
 	uint32_t spectral_dbg_level;
 	uint32_t scan_req_type = 0;
+	struct spectral_cp_request sscan_req;
+	enum spectral_scan_mode sscan_mode = SPECTRAL_SCAN_MODE_NORMAL;
 
 	if (wlan_cfg80211_nla_parse(
 			tb,
@@ -394,9 +217,11 @@ int wlan_cfg80211_spectral_scan_config_and_start(struct wiphy *wiphy,
 	if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DEBUG_LEVEL]) {
 		spectral_dbg_level = nla_get_u32(tb
 		   [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DEBUG_LEVEL]);
-		status = wlan_spectral_set_debug_level(pdev,
-						       spectral_dbg_level);
-		if (QDF_STATUS_SUCCESS != status)
+		sscan_req.ss_mode = sscan_mode;
+		sscan_req.debug_req.spectral_dbg_level = spectral_dbg_level;
+		sscan_req.req_id = SPECTRAL_SET_DEBUG_LEVEL;
+		status = ucfg_spectral_control(pdev, &sscan_req);
+		if (QDF_IS_STATUS_ERROR(status))
 			return -EINVAL;
 	}
 
@@ -405,14 +230,21 @@ int wlan_cfg80211_spectral_scan_config_and_start(struct wiphy *wiphy,
 		   [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_REQUEST_TYPE]);
 
 	if (CONFIG_REQUESTED(scan_req_type)) {
-		status = wlan_spectral_set_config(pdev, &config_req);
-		if (QDF_STATUS_SUCCESS != status)
+		sscan_req.ss_mode = sscan_mode;
+		sscan_req.req_id = SPECTRAL_SET_CONFIG;
+		qdf_mem_copy(&sscan_req.config_req.sscan_config, &config_req,
+			     qdf_min(sizeof(sscan_req.config_req.sscan_config),
+				     sizeof(config_req)));
+		status = ucfg_spectral_control(pdev, &sscan_req);
+		if (QDF_IS_STATUS_ERROR(status))
 			return -EINVAL;
 	}
 
 	if (SCAN_REQUESTED(scan_req_type)) {
-		status = wlan_start_spectral_scan(pdev);
-		if (QDF_STATUS_SUCCESS != status)
+		sscan_req.ss_mode = sscan_mode;
+		sscan_req.req_id = SPECTRAL_ACTIVATE_SCAN;
+		status = ucfg_spectral_control(pdev, &sscan_req);
+		if (QDF_IS_STATUS_ERROR(status))
 			return -EINVAL;
 	}
 
@@ -442,10 +274,15 @@ int wlan_cfg80211_spectral_scan_stop(struct wiphy *wiphy,
 				     int data_len)
 {
 	QDF_STATUS status;
+	struct spectral_cp_request sscan_req;
+	enum spectral_scan_mode sscan_mode = SPECTRAL_SCAN_MODE_NORMAL;
 
-	status = wlan_stop_spectral_scan(pdev);
-	if (QDF_STATUS_SUCCESS != status)
+	sscan_req.ss_mode = sscan_mode;
+	sscan_req.req_id = SPECTRAL_STOP_SCAN;
+	status = ucfg_spectral_control(pdev, &sscan_req);
+	if (QDF_IS_STATUS_ERROR(status))
 		return -EINVAL;
+
 	return 0;
 }
 
@@ -454,12 +291,14 @@ int wlan_cfg80211_spectral_scan_get_config(struct wiphy *wiphy,
 					   const void *data,
 					   int data_len)
 {
-	struct spectral_config config_buf;
+	struct spectral_config *sconfig;
 	uint32_t spectral_dbg_level;
 	struct sk_buff *skb;
+	struct spectral_cp_request sscan_req;
+	enum spectral_scan_mode sscan_mode = SPECTRAL_SCAN_MODE_NORMAL;
+	QDF_STATUS status;
+
 
-	wlan_spectral_get_config(pdev, &config_buf);
-	wlan_spectral_get_debug_level(pdev, &spectral_dbg_level);
 
 	skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, (21 * sizeof(u32)) +
 		NLA_HDRLEN + NLMSG_HDRLEN);
@@ -468,68 +307,80 @@ int wlan_cfg80211_spectral_scan_get_config(struct wiphy *wiphy,
 		return -ENOMEM;
 	}
 
+	sscan_req.ss_mode = sscan_mode;
+	sscan_req.req_id = SPECTRAL_GET_CONFIG;
+	status = ucfg_spectral_control(pdev, &sscan_req);
+	sconfig = &sscan_req.config_req.sscan_config;
 	if (nla_put_u32(skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SCAN_COUNT,
-			config_buf.ss_count) ||
+			sconfig->ss_count) ||
 	    nla_put_u32(skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SCAN_PERIOD,
-			config_buf.ss_period) ||
+			sconfig->ss_period) ||
 	    nla_put_u32(skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_PRIORITY,
-			config_buf.ss_spectral_pri) ||
+			sconfig->ss_spectral_pri) ||
 	    nla_put_u32(skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_SIZE,
-			config_buf.ss_fft_size) ||
+			sconfig->ss_fft_size) ||
 	    nla_put_u32(skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_GC_ENA,
-			config_buf.ss_gc_ena) ||
+			sconfig->ss_gc_ena) ||
 	    nla_put_u32(skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RESTART_ENA,
-			config_buf.ss_restart_ena) ||
+			sconfig->ss_restart_ena) ||
 	    nla_put_u32(
 		skb,
 		QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_NOISE_FLOOR_REF,
-		config_buf.ss_noise_floor_ref) ||
+		sconfig->ss_noise_floor_ref) ||
 	    nla_put_u32(skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_INIT_DELAY,
-			config_buf.ss_init_delay) ||
+			sconfig->ss_init_delay) ||
 	    nla_put_u32(skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_NB_TONE_THR,
-			config_buf.ss_nb_tone_thr) ||
+			sconfig->ss_nb_tone_thr) ||
 	    nla_put_u32(skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_STR_BIN_THR,
-			config_buf.ss_str_bin_thr) ||
+			sconfig->ss_str_bin_thr) ||
 	    nla_put_u32(skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_WB_RPT_MODE,
-			config_buf.ss_wb_rpt_mode) ||
+			sconfig->ss_wb_rpt_mode) ||
 	    nla_put_u32(skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RSSI_RPT_MODE,
-			config_buf.ss_rssi_rpt_mode) ||
+			sconfig->ss_rssi_rpt_mode) ||
 	    nla_put_u32(skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RSSI_THR,
-			config_buf.ss_rssi_thr) ||
+			sconfig->ss_rssi_thr) ||
 	    nla_put_u32(skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_PWR_FORMAT,
-			config_buf.ss_pwr_format) ||
+			sconfig->ss_pwr_format) ||
 	    nla_put_u32(skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RPT_MODE,
-			config_buf.ss_rpt_mode) ||
+			sconfig->ss_rpt_mode) ||
 	    nla_put_u32(skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_BIN_SCALE,
-			config_buf.ss_bin_scale) ||
+			sconfig->ss_bin_scale) ||
 	    nla_put_u32(skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DBM_ADJ,
-			config_buf.ss_dbm_adj) ||
+			sconfig->ss_dbm_adj) ||
 	    nla_put_u32(skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_CHN_MASK,
-			config_buf.ss_chn_mask) ||
+			sconfig->ss_chn_mask) ||
 	    nla_put_u32(skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_PERIOD,
-			config_buf.ss_fft_period) ||
+			sconfig->ss_fft_period) ||
 	    nla_put_u32(skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SHORT_REPORT,
-			config_buf.ss_short_report) ||
-	    nla_put_u32(skb,
+			sconfig->ss_short_report)) {
+		kfree_skb(skb);
+		return -EINVAL;
+	}
+
+	sscan_req.ss_mode = sscan_mode;
+	sscan_req.req_id = SPECTRAL_GET_DEBUG_LEVEL;
+	status = ucfg_spectral_control(pdev, &sscan_req);
+	spectral_dbg_level = sscan_req.debug_req.spectral_dbg_level;
+	if (nla_put_u32(skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DEBUG_LEVEL,
 			spectral_dbg_level)) {
 		kfree_skb(skb);
@@ -545,10 +396,16 @@ int wlan_cfg80211_spectral_scan_get_cap(struct wiphy *wiphy,
 					const void *data,
 					int data_len)
 {
-	struct spectral_caps spectral_cap;
+	struct spectral_caps *scaps;
 	struct sk_buff *skb;
+	struct spectral_cp_request sscan_req;
+	enum spectral_scan_mode sscan_mode = SPECTRAL_SCAN_MODE_NORMAL;
+	QDF_STATUS status;
 
-	wlan_spectral_get_cap(pdev, &spectral_cap);
+	sscan_req.ss_mode = sscan_mode;
+	sscan_req.req_id = SPECTRAL_GET_CAPABILITY_INFO;
+	status = ucfg_spectral_control(pdev, &sscan_req);
+	scaps = &sscan_req.caps_req.sscan_caps;
 
 	skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, 10 * sizeof(u32) +
 		NLA_HDRLEN + NLMSG_HDRLEN);
@@ -557,24 +414,24 @@ int wlan_cfg80211_spectral_scan_get_cap(struct wiphy *wiphy,
 		return -ENOMEM;
 	}
 
-	if (spectral_cap.phydiag_cap)
+	if (scaps->phydiag_cap)
 		if (nla_put_flag(
 			skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_PHYDIAG))
 			goto fail;
 
-	if (spectral_cap.radar_cap)
+	if (scaps->radar_cap)
 		if (nla_put_flag(skb,
 				 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_RADAR))
 			goto fail;
 
-	if (spectral_cap.spectral_cap)
+	if (scaps->spectral_cap)
 		if (nla_put_flag(
 			skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_SPECTRAL))
 			goto fail;
 
-	if (spectral_cap.advncd_spectral_cap)
+	if (scaps->advncd_spectral_cap)
 		if (nla_put_flag(
 		skb,
 		QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_ADVANCED_SPECTRAL))
@@ -582,38 +439,38 @@ int wlan_cfg80211_spectral_scan_get_cap(struct wiphy *wiphy,
 
 	if (nla_put_u32(skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_HW_GEN,
-			spectral_cap.hw_gen))
+			scaps->hw_gen))
 		goto fail;
 
-	if (spectral_cap.is_scaling_params_populated) {
+	if (scaps->is_scaling_params_populated) {
 		if (nla_put_u16(
 			skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_FORMULA_ID,
-			spectral_cap.formula_id))
+			scaps->formula_id))
 			goto fail;
 
 		if (nla_put_u16(
 			skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_LOW_LEVEL_OFFSET,
-			spectral_cap.low_level_offset))
+			scaps->low_level_offset))
 			goto fail;
 
 		if (nla_put_u16(
 		       skb,
 		       QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_HIGH_LEVEL_OFFSET,
-		       spectral_cap.high_level_offset))
+		       scaps->high_level_offset))
 			goto fail;
 
 		if (nla_put_u16(
 			skb,
 			QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_RSSI_THR,
-			spectral_cap.rssi_thr))
+			scaps->rssi_thr))
 			goto fail;
 
 		if (nla_put_u8(
 		    skb,
 		    QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_DEFAULT_AGC_MAX_GAIN,
-		    spectral_cap.default_agc_max_gain))
+		    scaps->default_agc_max_gain))
 			goto fail;
 	}
 
@@ -631,10 +488,16 @@ int wlan_cfg80211_spectral_scan_get_diag_stats(struct wiphy *wiphy,
 					       const void *data,
 					       int data_len)
 {
-	struct spectral_diag_stats spetcral_diag;
+	struct spectral_diag_stats *spetcral_diag;
 	struct sk_buff *skb;
+	struct spectral_cp_request sscan_req;
+	enum spectral_scan_mode sscan_mode = SPECTRAL_SCAN_MODE_NORMAL;
+	QDF_STATUS status;
 
-	wlan_spectral_get_diag_stats(pdev, &spetcral_diag);
+	sscan_req.ss_mode = sscan_mode;
+	sscan_req.req_id = SPECTRAL_GET_DIAG_STATS;
+	status = ucfg_spectral_control(pdev, &sscan_req);
+	spetcral_diag = &sscan_req.diag_req.sscan_diag;
 
 	skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, 5 * sizeof(u64) +
 		NLA_HDRLEN + NLMSG_HDRLEN);
@@ -646,23 +509,23 @@ int wlan_cfg80211_spectral_scan_get_diag_stats(struct wiphy *wiphy,
 	if (wlan_cfg80211_nla_put_u64(
 		skb,
 		QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_SIG_MISMATCH,
-		spetcral_diag.spectral_mismatch) ||
+		spetcral_diag->spectral_mismatch) ||
 	    wlan_cfg80211_nla_put_u64(
 		skb,
 		QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_SEC80_SFFT_INSUFFLEN,
-		spetcral_diag.spectral_sec80_sfft_insufflen) ||
+		spetcral_diag->spectral_sec80_sfft_insufflen) ||
 	    wlan_cfg80211_nla_put_u64(
 		skb,
 		QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_NOSEC80_SFFT,
-		spetcral_diag.spectral_no_sec80_sfft) ||
+		spetcral_diag->spectral_no_sec80_sfft) ||
 	    wlan_cfg80211_nla_put_u64(
 		skb,
 		QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_VHTSEG1ID_MISMATCH,
-		spetcral_diag.spectral_vhtseg1id_mismatch) ||
+		spetcral_diag->spectral_vhtseg1id_mismatch) ||
 	    wlan_cfg80211_nla_put_u64(
 		skb,
 		QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_VHTSEG2ID_MISMATCH,
-		spetcral_diag.spectral_vhtseg2id_mismatch)) {
+		spetcral_diag->spectral_vhtseg2id_mismatch)) {
 		kfree_skb(skb);
 		return -EINVAL;
 	}
@@ -678,6 +541,9 @@ int wlan_cfg80211_spectral_scan_get_status(struct wiphy *wiphy,
 {
 	struct spectral_scan_state sscan_state = { 0 };
 	struct sk_buff *skb;
+	struct spectral_cp_request sscan_req;
+	enum spectral_scan_mode sscan_mode = SPECTRAL_SCAN_MODE_NORMAL;
+	QDF_STATUS status;
 
 	skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, 2 * sizeof(u32) +
 		NLA_HDRLEN + NLMSG_HDRLEN);
@@ -686,7 +552,16 @@ int wlan_cfg80211_spectral_scan_get_status(struct wiphy *wiphy,
 		return -ENOMEM;
 	}
 
-	wlan_spectral_scan_get_status(pdev, &sscan_state);
+	/* Sending a request and extracting response from it has to be atomic */
+	sscan_req.ss_mode = sscan_mode;
+	sscan_req.req_id = SPECTRAL_IS_ACTIVE;
+	status = ucfg_spectral_control(pdev, &sscan_req);
+	sscan_state.is_active = sscan_req.status_req.is_active;
+
+	sscan_req.ss_mode = sscan_mode;
+	sscan_req.req_id = SPECTRAL_IS_ENABLED;
+	status = ucfg_spectral_control(pdev, &sscan_req);
+	sscan_state.is_enabled = sscan_req.status_req.is_enabled;
 
 	if (sscan_state.is_enabled)
 		if (nla_put_flag(

+ 4 - 10
spectral/core/spectral_cmn_api_i.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
  *
  *
  * Permission to use, copy, modify, and/or distribute this software for
@@ -85,12 +85,8 @@ QDF_STATUS wlan_spectral_pdev_obj_destroy_handler(struct wlan_objmgr_pdev *pdev,
 /**
  * spectral_control_cmn()- common handler for demultiplexing requests from
  *                         higher layer
- * @pdev:    reference to global pdev object
- * @id:      spectral config command id
- * @indata:  reference to input data
- * @insize:  input data size
- * @outdata: reference to output data
- * @outsize: reference to output data size
+ * @pdev:      reference to global pdev object
+ * @sscan_req: pointer to Spectral scan request
  *
  * This function processes the spectral config command
  * and appropriate handlers are invoked.
@@ -98,9 +94,7 @@ QDF_STATUS wlan_spectral_pdev_obj_destroy_handler(struct wlan_objmgr_pdev *pdev,
  * Return: 0 success else failure
  */
 int spectral_control_cmn(struct wlan_objmgr_pdev *pdev,
-			 u_int id,
-			 void *indata,
-			 uint32_t insize, void *outdata, uint32_t *outsize);
+			 struct spectral_cp_request *sscan_req);
 
 /**
  * spectral_control_ol(): Offload handler for demultiplexing requests from

+ 21 - 67
spectral/core/spectral_common.c

@@ -113,9 +113,7 @@ spectral_register_cfg80211_handlers(struct wlan_objmgr_pdev *pdev)
 
 int
 spectral_control_cmn(struct wlan_objmgr_pdev *pdev,
-		     u_int id,
-		     void *indata,
-		     uint32_t insize, void *outdata, uint32_t *outsize)
+		     struct spectral_cp_request *sscan_req)
 {
 	int error = 0;
 	int temp_debug;
@@ -138,15 +136,10 @@ spectral_control_cmn(struct wlan_objmgr_pdev *pdev,
 		goto bad;
 	}
 
-	switch (id) {
+	switch (sscan_req->req_id) {
 	case SPECTRAL_SET_CONFIG:
 		{
-			if (insize < sizeof(struct spectral_config) ||
-			    !indata) {
-				error = -EINVAL;
-				break;
-			}
-			sp_in = (struct spectral_config *)indata;
+			sp_in = &sscan_req->config_req.sscan_config;
 			if (sp_in->ss_count !=
 			    SPECTRAL_PHYERR_PARAM_NOVAL) {
 				if (sc->sptrlc_set_spectral_config(
@@ -345,14 +338,8 @@ spectral_control_cmn(struct wlan_objmgr_pdev *pdev,
 
 	case SPECTRAL_GET_CONFIG:
 		{
-			if (!outdata || !outsize ||
-			    (*outsize < sizeof(struct spectral_config))) {
-				error = -EINVAL;
-				break;
-			}
-			*outsize = sizeof(struct spectral_config);
 			sc->sptrlc_get_spectral_config(pdev, &sp_out);
-			spectralparams = (struct spectral_config *)outdata;
+			spectralparams = &sscan_req->config_req.sscan_config;
 			spectralparams->ss_fft_period = sp_out.ss_fft_period;
 			spectralparams->ss_period = sp_out.ss_period;
 			spectralparams->ss_count = sp_out.ss_count;
@@ -382,51 +369,29 @@ spectral_control_cmn(struct wlan_objmgr_pdev *pdev,
 
 	case SPECTRAL_IS_ACTIVE:
 		{
-			if (!outdata || !outsize ||
-			    *outsize < sizeof(uint32_t)) {
-				error = -EINVAL;
-				break;
-			}
-			*outsize = sizeof(uint32_t);
-			*((uint32_t *)outdata) =
-			    (uint32_t)sc->sptrlc_is_spectral_active(pdev);
+			sscan_req->status_req.is_active =
+				(bool)sc->sptrlc_is_spectral_active(pdev);
 		}
 		break;
 
 	case SPECTRAL_IS_ENABLED:
 		{
-			if (!outdata || !outsize ||
-			    *outsize < sizeof(uint32_t)) {
-				error = -EINVAL;
-				break;
-			}
-			*outsize = sizeof(uint32_t);
-			*((uint32_t *)outdata) =
-			    (uint32_t)sc->sptrlc_is_spectral_enabled(pdev);
+			sscan_req->status_req.is_enabled =
+				(bool)sc->sptrlc_is_spectral_enabled(pdev);
 		}
 		break;
 
 	case SPECTRAL_SET_DEBUG_LEVEL:
 		{
-			if (insize < sizeof(uint32_t) || !indata) {
-				error = -EINVAL;
-				break;
-			}
-			temp_debug = *(uint32_t *)indata;
+			temp_debug = sscan_req->debug_req.spectral_dbg_level;
 			sc->sptrlc_set_debug_level(pdev, temp_debug);
 		}
 		break;
 
 	case SPECTRAL_GET_DEBUG_LEVEL:
 		{
-			if (!outdata || !outsize ||
-			    *outsize < sizeof(uint32_t)) {
-				error = -EINVAL;
-				break;
-			}
-			*outsize = sizeof(uint32_t);
-			*((uint32_t *)outdata) =
-			    (uint32_t)sc->sptrlc_get_debug_level(pdev);
+			sscan_req->debug_req.spectral_dbg_level =
+				(uint32_t)sc->sptrlc_get_debug_level(pdev);
 		}
 		break;
 
@@ -444,25 +409,19 @@ spectral_control_cmn(struct wlan_objmgr_pdev *pdev,
 
 	case SPECTRAL_GET_CAPABILITY_INFO:
 		{
-			if (!outdata || !outsize ||
-			    *outsize < sizeof(struct spectral_caps)) {
-				error = -EINVAL;
-				break;
-			}
-			*outsize = sizeof(struct spectral_caps);
-			sc->sptrlc_get_spectral_capinfo(pdev, outdata);
+			struct spectral_caps *caps;
+
+			caps  = &sscan_req->caps_req.sscan_caps;
+			sc->sptrlc_get_spectral_capinfo(pdev, caps);
 		}
 		break;
 
 	case SPECTRAL_GET_DIAG_STATS:
 		{
-			if (!outdata || !outsize ||
-			    (*outsize < sizeof(struct spectral_diag_stats))) {
-				error = -EINVAL;
-				break;
-			}
-			*outsize = sizeof(struct spectral_diag_stats);
-			sc->sptrlc_get_spectral_diagstats(pdev, outdata);
+			struct spectral_diag_stats *diag;
+
+			diag  = &sscan_req->diag_req.sscan_diag;
+			sc->sptrlc_get_spectral_diagstats(pdev, diag);
 		}
 		break;
 
@@ -477,13 +436,8 @@ spectral_control_cmn(struct wlan_objmgr_pdev *pdev,
 			chan_width = spectral_vdev_get_ch_width(vdev);
 			wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID);
 
-			if (!outdata || !outsize ||
-			    *outsize < sizeof(chan_width)) {
-				error = -EINVAL;
-				break;
-			}
-			*outsize = sizeof(chan_width);
-			*((uint32_t *)outdata) = (uint32_t)chan_width;
+			sscan_req->chan_width_req.chan_width =
+							(uint32_t)chan_width;
 		}
 		break;
 

+ 1 - 3
spectral/core/spectral_defs_i.h

@@ -123,9 +123,7 @@ struct spectral_context {
 	struct wlan_objmgr_psoc *psoc_obj;
 	struct spectral_legacy_cbacks legacy_cbacks;
 	int (*sptrlc_spectral_control)(struct wlan_objmgr_pdev *pdev,
-				       u_int id, void *indata,
-				       uint32_t insize, void *outdata,
-				       uint32_t *outsize);
+				       struct spectral_cp_request *sscan_req);
 	int (*sptrlc_ucfg_phyerr_config)(struct wlan_objmgr_pdev *pdev,
 					 void *ad);
 	void * (*sptrlc_pdev_spectral_init)(struct wlan_objmgr_pdev *pdev);

+ 105 - 0
spectral/dispatcher/inc/wlan_spectral_public_structs.h

@@ -187,6 +187,20 @@ enum spectral_capability_type {
 	SPECTRAL_CAP_ADVNCD_SPECTRAL_SCAN,
 };
 
+/**
+ * enum spectral_cp_error_code - Spectral control path response code
+ * @SPECTRAL_SCAN_RESP_ERR_PARAM_UNSUPPORTED: parameter unsupported
+ * @SPECTRAL_SCAN_RESP_ERR_MODE_UNSUPPORTED: mode unsupported
+ * @SPECTRAL_SCAN_RESP_ERR_PARAM_INVALID_VALUE: invalid parameter value
+ * @SPECTRAL_SCAN_RESP_ERR_PARAM_NOT_INITIALIZED: parameter uninitialized
+ */
+enum spectral_cp_error_code {
+	SPECTRAL_SCAN_ERR_PARAM_UNSUPPORTED,
+	SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED,
+	SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE,
+	SPECTRAL_SCAN_ERR_PARAM_NOT_INITIALIZED,
+};
+
 /**
  * struct spectral_chan_stats - channel status info
  * @cycle_count:         Cycle count
@@ -257,6 +271,97 @@ struct spectral_nl_cb {
 	void (*free_nbuff)(struct wlan_objmgr_pdev *pdev);
 };
 
+/**
+ * struct spectral_scan_config_request - Config request
+ * @sscan_config: Spectral parameters
+ * @sscan_err_code: Spectral scan error code
+ */
+struct spectral_scan_config_request {
+	struct spectral_config sscan_config;
+	enum spectral_cp_error_code sscan_err_code;
+};
+
+/**
+ * struct spectral_scan_action_request - Action request
+ * @sscan_err_code: Spectral scan error code
+ */
+struct spectral_scan_action_request {
+	enum spectral_cp_error_code sscan_err_code;
+};
+
+/**
+ * struct spectral_scan_get_caps_request - Get caps request
+ * @sscan_caps: Spectral capabilities
+ * @sscan_err_code: Spectral scan error code
+ */
+struct spectral_scan_get_caps_request {
+	struct spectral_caps sscan_caps;
+	enum spectral_cp_error_code sscan_err_code;
+};
+
+/**
+ * struct spectral_scan_get_diag_request - Get diag request
+ * @sscan_diag: Spectral diag stats
+ * @sscan_err_code: Spectral scan error code
+ */
+struct spectral_scan_get_diag_request {
+	struct spectral_diag_stats sscan_diag;
+	enum spectral_cp_error_code sscan_err_code;
+};
+
+/**
+ * struct spectral_scan_get_chan_width_request - Get channel width request
+ * @chan_width: Channel width
+ * @sscan_err_code: Spectral scan error code
+ */
+struct spectral_scan_get_chan_width_request {
+	uint32_t chan_width;
+	enum spectral_cp_error_code sscan_err_code;
+};
+
+/**
+ * struct spectral_scan_get_status_request - Get status request
+ * @is_active: is Spectral scan active
+ * @is_enabled: is Spectral scan enabled
+ * @sscan_err_code: Spectral scan error code
+ */
+struct spectral_scan_get_status_request {
+	bool is_active;
+	bool is_enabled;
+	enum spectral_cp_error_code sscan_err_code;
+};
+
+/**
+ * struct spectral_scan_debug_request - Get/set debug level request
+ * @spectral_dbg_level: Spectral debug level
+ * @sscan_err_code: Spectral scan error code
+ */
+struct spectral_scan_debug_request {
+	uint32_t spectral_dbg_level;
+	enum spectral_cp_error_code sscan_err_code;
+};
+
+/**
+ * struct spectral_cp_request - Spectral control path request
+ *                              Creating request and extracting response has to
+ *                              be atomic.
+ * @ss_mode: Spectral scan mode
+ * @req_id: Request identifier
+ */
+struct spectral_cp_request {
+	enum spectral_scan_mode ss_mode;
+	uint8_t req_id;
+	union {
+		struct spectral_scan_config_request config_req;
+		struct spectral_scan_action_request action_req;
+		struct spectral_scan_get_caps_request caps_req;
+		struct spectral_scan_get_diag_request diag_req;
+		struct spectral_scan_get_chan_width_request chan_width_req;
+		struct spectral_scan_get_status_request status_req;
+		struct spectral_scan_debug_request debug_req;
+	};
+};
+
 #ifndef __KERNEL__
 
 static inline int16_t

+ 3 - 8
spectral/dispatcher/inc/wlan_spectral_tgt_api.h

@@ -37,12 +37,8 @@ void *tgt_get_target_handle(struct wlan_objmgr_pdev *pdev);
 
 /**
  * tgt_spectral_control()- handler for demultiplexing requests from higher layer
- * @pdev:    reference to global pdev object
- * @id:      spectral config command id
- * @indata:  reference to input data
- * @insize:  input data size
- * @outdata: reference to output data
- * @outsize: output data size
+ * @pdev:      reference to global pdev object
+ * @sscan_req: pointer to Spectral scan request
  *
  * This function processes the spectral config command
  * and appropriate handlers are invoked.
@@ -50,8 +46,7 @@ void *tgt_get_target_handle(struct wlan_objmgr_pdev *pdev);
  * Return: 0 success else failure
  */
 int tgt_spectral_control(struct wlan_objmgr_pdev *pdev,
-			 u_int id, void *indata, u_int32_t insize,
-			 void *outdata, u_int32_t *outsize);
+			 struct spectral_cp_request *sscan_req);
 
 /**
  * tgt_pdev_spectral_init() - implementation for spectral init

+ 29 - 10
spectral/dispatcher/inc/wlan_spectral_ucfg_api.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
  *
  *
  * Permission to use, copy, modify, and/or distribute this software for
@@ -28,20 +28,14 @@
 /**
  * ucfg_spectral_control() - Carry out Spectral control operations
  * @pdev: Pointer to pdev
- * @id: Spectral operation ID
- * @indata: Pointer to input data
- * @insize: Size of indata buffer
- * @outdata: Pointer to buffer where the output should be stored
- * @outsize: Size of outdata buffer
+ * @sscan_req: spectral related control request
  *
  * Carry out Spectral specific UCFG control get/set operations
  *
  * Return: 0 on success, negative value on failure
  */
-int ucfg_spectral_control(struct wlan_objmgr_pdev *pdev,
-			  u_int id,
-			  void *indata,
-			  uint32_t insize, void *outdata, uint32_t *outsize);
+QDF_STATUS ucfg_spectral_control(struct wlan_objmgr_pdev *pdev,
+				 struct spectral_cp_request *sscan_req);
 
 /**
  * ucfg_spectral_scan_set_ppid() - configure pid of spectral tool
@@ -55,4 +49,29 @@ int ucfg_spectral_control(struct wlan_objmgr_pdev *pdev,
 void ucfg_spectral_scan_set_ppid(struct wlan_objmgr_pdev *pdev,
 					uint32_t ppid);
 
+/**
+ * ucfg_spectral_create_cp_req() - Create Spectral control path request
+ * @sscan_req: Pointer to Spectral scan request
+ * @indata: pointer input data
+ * @insize: Size of input data
+ *
+ * Create Spectral control path request structure
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure
+ */
+QDF_STATUS ucfg_spectral_create_cp_req(struct spectral_cp_request *sscan_req,
+				       void *indata, u_int32_t insize);
+
+/**
+ * ucfg_spectral_create_cp_req() - Extract response from Spectral CP request
+ * @sscan_req: Pointer to Spectral scan request
+ * @outdata: pointer output data
+ * @outsize: Size of output data
+ *
+ * Extract response from Spectral control path request
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure
+ */
+QDF_STATUS ucfg_spectral_extract_response(struct spectral_cp_request *sscan_req,
+					  void *outdata, u_int32_t *outsize);
 #endif /* _WLAN_SPECTRAL_UCFG_API_H_ */

+ 2 - 4
spectral/dispatcher/src/wlan_spectral_tgt_api.c

@@ -49,9 +49,7 @@ tgt_get_target_handle(struct wlan_objmgr_pdev *pdev)
 int
 tgt_spectral_control(
 	struct wlan_objmgr_pdev *pdev,
-	u_int id,
-	void *indata,
-	u_int32_t insize, void *outdata, u_int32_t *outsize)
+	struct spectral_cp_request *sscan_req)
 {
 	struct spectral_context *sc;
 
@@ -64,7 +62,7 @@ tgt_spectral_control(
 		spectral_err("spectral context is NULL!");
 		return -EPERM;
 	}
-	return spectral_control_cmn(pdev, id, indata, insize, outdata, outsize);
+	return spectral_control_cmn(pdev, sscan_req);
 }
 
 void *

+ 153 - 8
spectral/dispatcher/src/wlan_spectral_ucfg_api.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
  *
  *
  * Permission to use, copy, modify, and/or distribute this software for
@@ -23,11 +23,9 @@
 #include <qdf_module.h>
 #include <cfg_ucfg_api.h>
 
-int
+QDF_STATUS
 ucfg_spectral_control(struct wlan_objmgr_pdev *pdev,
-		      u_int id,
-		      void *indata,
-		      uint32_t insize, void *outdata, uint32_t *outsize)
+		      struct spectral_cp_request *sscan_req)
 {
 	struct spectral_context *sc;
 
@@ -47,9 +45,7 @@ ucfg_spectral_control(struct wlan_objmgr_pdev *pdev,
 		return -EPERM;
 	}
 
-	return sc->sptrlc_spectral_control(pdev,
-					   id,
-					   indata, insize, outdata, outsize);
+	return sc->sptrlc_spectral_control(pdev, sscan_req);
 }
 qdf_export_symbol(ucfg_spectral_control);
 
@@ -72,3 +68,152 @@ void ucfg_spectral_scan_set_ppid(struct wlan_objmgr_pdev *pdev, uint32_t ppid)
 
 	return;
 }
+
+QDF_STATUS ucfg_spectral_create_cp_req(struct spectral_cp_request *sscan_req,
+				       void *indata, u_int32_t insize)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	switch (sscan_req->req_id) {
+	case SPECTRAL_SET_CONFIG:
+		{
+			if (insize < sizeof(struct spectral_config) ||
+			    !indata) {
+				status = QDF_STATUS_E_FAILURE;
+				goto bad;
+			}
+			qdf_mem_copy(&sscan_req->config_req.sscan_config,
+				     indata,
+				     sizeof(struct spectral_config));
+		}
+		break;
+
+	case SPECTRAL_SET_DEBUG_LEVEL:
+		{
+			if (insize < sizeof(uint32_t) || !indata) {
+				status = QDF_STATUS_E_FAILURE;
+				goto bad;
+			}
+			sscan_req->debug_req.spectral_dbg_level =
+							*(uint32_t *)indata;
+		}
+		break;
+
+	default:
+		break;
+	}
+
+bad:
+	return status;
+}
+
+qdf_export_symbol(ucfg_spectral_create_cp_req);
+
+QDF_STATUS ucfg_spectral_extract_response(struct spectral_cp_request *sscan_req,
+					  void *outdata, u_int32_t *outsize)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	switch (sscan_req->req_id) {
+	case SPECTRAL_GET_CONFIG:
+		{
+			if (!outdata || !outsize ||
+			    (*outsize < sizeof(struct spectral_config))) {
+				status = QDF_STATUS_E_FAILURE;
+				goto bad;
+			}
+			*outsize = sizeof(struct spectral_config);
+			qdf_mem_copy(outdata,
+				     &sscan_req->config_req.sscan_config,
+				     sizeof(struct spectral_config));
+		}
+		break;
+
+	case SPECTRAL_IS_ACTIVE:
+		{
+			if (!outdata || !outsize ||
+			    *outsize < sizeof(uint32_t)) {
+				status = QDF_STATUS_E_FAILURE;
+				goto bad;
+			}
+			*outsize = sizeof(uint32_t);
+			*((uint32_t *)outdata) =
+				sscan_req->status_req.is_active;
+		}
+		break;
+
+	case SPECTRAL_IS_ENABLED:
+		{
+			if (!outdata || !outsize ||
+			    *outsize < sizeof(uint32_t)) {
+				status = QDF_STATUS_E_FAILURE;
+				goto bad;
+			}
+			*outsize = sizeof(uint32_t);
+			*((uint32_t *)outdata) =
+				sscan_req->status_req.is_enabled;
+		}
+		break;
+
+	case SPECTRAL_GET_DEBUG_LEVEL:
+		{
+			if (!outdata || !outsize ||
+			    *outsize < sizeof(uint32_t)) {
+				status = QDF_STATUS_E_FAILURE;
+				goto bad;
+			}
+			*outsize = sizeof(uint32_t);
+			*((uint32_t *)outdata) =
+				sscan_req->debug_req.spectral_dbg_level;
+		}
+		break;
+
+	case SPECTRAL_GET_CAPABILITY_INFO:
+		{
+			if (!outdata || !outsize ||
+			    *outsize < sizeof(struct spectral_caps)) {
+				status = QDF_STATUS_E_FAILURE;
+				goto bad;
+			}
+			*outsize = sizeof(struct spectral_caps);
+			qdf_mem_copy(outdata, &sscan_req->caps_req.sscan_caps,
+				     sizeof(struct spectral_caps));
+		}
+		break;
+
+	case SPECTRAL_GET_DIAG_STATS:
+		{
+			if (!outdata || !outsize ||
+			    (*outsize < sizeof(struct spectral_diag_stats))) {
+				status = QDF_STATUS_E_FAILURE;
+				goto bad;
+			}
+			*outsize = sizeof(struct spectral_diag_stats);
+			qdf_mem_copy(outdata, &sscan_req->diag_req.sscan_diag,
+				     sizeof(struct spectral_diag_stats));
+		}
+		break;
+
+	case SPECTRAL_GET_CHAN_WIDTH:
+		{
+			if (!outdata || !outsize ||
+			    *outsize < sizeof(uint32_t)) {
+				status = QDF_STATUS_E_FAILURE;
+				goto bad;
+			}
+			*outsize = sizeof(uint32_t);
+			*((uint32_t *)outdata) =
+				sscan_req->chan_width_req.chan_width;
+		}
+		break;
+
+	default:
+		break;
+	}
+
+bad:
+	return status;
+}
+
+qdf_export_symbol(ucfg_spectral_extract_response);
+