diff --git a/os_if/linux/spectral/src/wlan_cfg80211_spectral.c b/os_if/linux/spectral/src/wlan_cfg80211_spectral.c index c05e8531800a..9d462fca2501 100644 --- a/os_if/linux/spectral/src/wlan_cfg80211_spectral.c +++ b/os_if/linux/spectral/src/wlan_cfg80211_spectral.c @@ -141,6 +141,47 @@ convert_spectral_mode_nl_to_internal return QDF_STATUS_SUCCESS; } +/** + * convert_spectral_err_code_internal_to_nl() - Get Spectral error code + * @spectral_err_code: Spectral error code used internally + * @nl_err_code: Spectral error code for cfg80211 + * + * Return: QDF_STATUS_SUCCESS on success, else QDF_STATUS_E_FAILURE + */ +static QDF_STATUS +convert_spectral_err_code_internal_to_nl + (enum spectral_cp_error_code spectral_err_code, + enum qca_wlan_vendor_spectral_scan_error_code *nl_err_code) +{ + switch (spectral_err_code) { + case SPECTRAL_SCAN_ERR_PARAM_UNSUPPORTED: + *nl_err_code = + QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_PARAM_UNSUPPORTED; + break; + + case SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED: + *nl_err_code = + QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED; + break; + + case SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE: + *nl_err_code = + QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE; + break; + + case SPECTRAL_SCAN_ERR_PARAM_NOT_INITIALIZED: + *nl_err_code = + QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_PARAM_NOT_INITIALIZED; + break; + + default: + osif_err("Invalid spectral error code %u", spectral_err_code); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} + int wlan_cfg80211_spectral_scan_config_and_start(struct wiphy *wiphy, struct wlan_objmgr_pdev *pdev, const void *data, @@ -155,6 +196,7 @@ int wlan_cfg80211_spectral_scan_config_and_start(struct wiphy *wiphy, uint32_t scan_req_type = 0; struct spectral_cp_request sscan_req; enum spectral_scan_mode sscan_mode = SPECTRAL_SCAN_MODE_NORMAL; + uint16_t skb_len; if (wlan_cfg80211_nla_parse( tb, @@ -275,6 +317,17 @@ int wlan_cfg80211_spectral_scan_config_and_start(struct wiphy *wiphy, scan_req_type = nla_get_u32(tb [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_REQUEST_TYPE]); + skb_len = NLMSG_HDRLEN; + /* QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_ERROR_CODE */ + skb_len += NLA_HDRLEN + sizeof(u32); + /* QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_COOKIE */ + skb_len += NLA_HDRLEN + sizeof(u64); + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, skb_len); + if (!skb) { + osif_err(" reply skb alloc failed"); + return -ENOMEM; + } + if (CONFIG_REQUESTED(scan_req_type)) { sscan_req.ss_mode = sscan_mode; sscan_req.req_id = SPECTRAL_SET_CONFIG; @@ -282,23 +335,66 @@ int wlan_cfg80211_spectral_scan_config_and_start(struct wiphy *wiphy, 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 (QDF_IS_STATUS_ERROR(status)) { + enum qca_wlan_vendor_spectral_scan_error_code + spectral_nl_err_code; + + /* No error reasons populated, just return error */ + if (sscan_req.config_req.sscan_err_code == + SPECTRAL_SCAN_ERR_INVALID) { + kfree_skb(skb); + return qdf_status_to_os_return(status); + } + + status = convert_spectral_err_code_internal_to_nl + (sscan_req.config_req.sscan_err_code, + &spectral_nl_err_code); + if (QDF_IS_STATUS_ERROR(status)) { + kfree_skb(skb); + return -EINVAL; + } + + if (nla_put_u32 + (skb, + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_ERROR_CODE, + spectral_nl_err_code)) { + kfree_skb(skb); + return -EINVAL; + } + } } if (SCAN_REQUESTED(scan_req_type)) { 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; - } + if (QDF_IS_STATUS_ERROR(status)) { + enum qca_wlan_vendor_spectral_scan_error_code + spectral_nl_err_code; - skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u64) + - NLA_HDRLEN + NLMSG_HDRLEN); - if (!skb) { - osif_err(" reply skb alloc failed"); - return -ENOMEM; + /* No error reasons populated, just return error */ + if (sscan_req.action_req.sscan_err_code == + SPECTRAL_SCAN_ERR_INVALID) { + kfree_skb(skb); + return qdf_status_to_os_return(status); + } + + status = convert_spectral_err_code_internal_to_nl + (sscan_req.action_req.sscan_err_code, + &spectral_nl_err_code); + if (QDF_IS_STATUS_ERROR(status)) { + kfree_skb(skb); + return -EINVAL; + } + + if (nla_put_u32 + (skb, + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_ERROR_CODE, + spectral_nl_err_code)) { + kfree_skb(skb); + return -EINVAL; + } + } } cookie = 0; @@ -323,6 +419,7 @@ int wlan_cfg80211_spectral_scan_stop(struct wiphy *wiphy, QDF_STATUS status; struct spectral_cp_request sscan_req; enum spectral_scan_mode sscan_mode = SPECTRAL_SCAN_MODE_NORMAL; + struct sk_buff *skb; if (wlan_cfg80211_nla_parse( tb, @@ -345,8 +442,37 @@ int wlan_cfg80211_spectral_scan_stop(struct wiphy *wiphy, 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; + if (QDF_IS_STATUS_ERROR(status)) { + enum qca_wlan_vendor_spectral_scan_error_code + spectral_nl_err_code; + + /* No error reasons populated, just return error */ + if (sscan_req.action_req.sscan_err_code == + SPECTRAL_SCAN_ERR_INVALID) + return qdf_status_to_os_return(status); + + status = convert_spectral_err_code_internal_to_nl + (sscan_req.action_req.sscan_err_code, + &spectral_nl_err_code); + if (QDF_IS_STATUS_ERROR(status)) + return -EINVAL; + + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, NLMSG_HDRLEN + + sizeof(u32) + NLA_HDRLEN); + if (!skb) { + osif_err(" reply skb alloc failed"); + return -ENOMEM; + } + + if (nla_put_u32 + (skb, + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_ERROR_CODE, + spectral_nl_err_code)) { + kfree_skb(skb); + return -EINVAL; + } + qal_devcfg_send_response((qdf_nbuf_t)skb); + } return 0; } diff --git a/spectral/core/spectral_common.c b/spectral/core/spectral_common.c index c955dca798b0..52d586955028 100644 --- a/spectral/core/spectral_common.c +++ b/spectral/core/spectral_common.c @@ -429,7 +429,8 @@ spectral_control_cmn(struct wlan_objmgr_pdev *pdev, break; case SPECTRAL_STOP_SCAN: - sc->sptrlc_stop_spectral_scan(pdev, smode); + err = &sscan_req->action_req.sscan_err_code; + sc->sptrlc_stop_spectral_scan(pdev, smode, err); break; case SPECTRAL_GET_CAPABILITY_INFO: diff --git a/spectral/core/spectral_defs_i.h b/spectral/core/spectral_defs_i.h index 52abd90ff73b..ad4944b824af 100644 --- a/spectral/core/spectral_defs_i.h +++ b/spectral/core/spectral_defs_i.h @@ -143,8 +143,10 @@ struct spectral_context { (struct wlan_objmgr_pdev *pdev, const enum spectral_scan_mode smode, enum spectral_cp_error_code *err); - QDF_STATUS (*sptrlc_stop_spectral_scan)(struct wlan_objmgr_pdev *pdev, - enum spectral_scan_mode smode); + QDF_STATUS (*sptrlc_stop_spectral_scan) + (struct wlan_objmgr_pdev *pdev, + enum spectral_scan_mode smode, + enum spectral_cp_error_code *err); bool (*sptrlc_is_spectral_active)(struct wlan_objmgr_pdev *pdev, enum spectral_scan_mode smode); bool (*sptrlc_is_spectral_enabled)(struct wlan_objmgr_pdev *pdev, diff --git a/spectral/dispatcher/inc/spectral_ioctl.h b/spectral/dispatcher/inc/spectral_ioctl.h index 2f24c6baf6c4..88cd7e314fb1 100644 --- a/spectral/dispatcher/inc/spectral_ioctl.h +++ b/spectral/dispatcher/inc/spectral_ioctl.h @@ -56,7 +56,7 @@ * ioctl parameter types */ enum spectral_params { - SPECTRAL_PARAM_FFT_PERIOD = 1, + SPECTRAL_PARAM_FFT_PERIOD, SPECTRAL_PARAM_SCAN_PERIOD, SPECTRAL_PARAM_SCAN_COUNT, SPECTRAL_PARAM_SHORT_REPORT, @@ -80,8 +80,7 @@ enum spectral_params { SPECTRAL_PARAM_STOP, SPECTRAL_PARAM_ENABLE, SPECTRAL_PARAM_FREQUENCY, - SPECTRAL_PARAM_AFTER_LAST, - SPECTRAL_PARAM_MAX = SPECTRAL_PARAM_AFTER_LAST - 1, + SPECTRAL_PARAM_MAX, }; /** diff --git a/spectral/dispatcher/inc/wlan_spectral_public_structs.h b/spectral/dispatcher/inc/wlan_spectral_public_structs.h index 4096eb4bea3e..725e8aeb2b7e 100644 --- a/spectral/dispatcher/inc/wlan_spectral_public_structs.h +++ b/spectral/dispatcher/inc/wlan_spectral_public_structs.h @@ -218,12 +218,14 @@ enum spectral_capability_type { /** * enum spectral_cp_error_code - Spectral control path response code + * @SPECTRAL_SCAN_RESP_ERR_INVALID: Invalid error identifier * @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_INVALID, SPECTRAL_SCAN_ERR_PARAM_UNSUPPORTED, SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED, SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE, diff --git a/spectral/dispatcher/inc/wlan_spectral_tgt_api.h b/spectral/dispatcher/inc/wlan_spectral_tgt_api.h index 4a1ee4dbbda6..eb917749cc08 100644 --- a/spectral/dispatcher/inc/wlan_spectral_tgt_api.h +++ b/spectral/dispatcher/inc/wlan_spectral_tgt_api.h @@ -102,7 +102,7 @@ QDF_STATUS tgt_get_spectral_config(struct wlan_objmgr_pdev *pdev, * tgt_start_spectral_scan() - Start spectral scan * @pdev: Pointer to pdev object * @smode: Spectral scan mode - * @res: Spectral control path error code + * @err: Spectral control path error code * * Implementation for starting spectral scan * @@ -116,13 +116,15 @@ QDF_STATUS tgt_start_spectral_scan(struct wlan_objmgr_pdev *pdev, * tgt_stop_spectral_scan() - Stop spectral scan * @pdev: Pointer to pdev object * @smode: Spectral scan mode + * @err: Spectral control path error code * * Implementation for stop spectral scan * * Return: QDF_STATUS_SUCCESS on success, else QDF_STATUS_E_FAILURE */ QDF_STATUS tgt_stop_spectral_scan(struct wlan_objmgr_pdev *pdev, - enum spectral_scan_mode smode); + enum spectral_scan_mode smode, + enum spectral_cp_error_code *err); /** * tgt_is_spectral_active() - Get whether Spectral is active diff --git a/spectral/dispatcher/src/wlan_spectral_tgt_api.c b/spectral/dispatcher/src/wlan_spectral_tgt_api.c index eabd2f4075b0..bc2a85a07aa6 100644 --- a/spectral/dispatcher/src/wlan_spectral_tgt_api.c +++ b/spectral/dispatcher/src/wlan_spectral_tgt_api.c @@ -125,13 +125,14 @@ tgt_start_spectral_scan(struct wlan_objmgr_pdev *pdev, QDF_STATUS tgt_stop_spectral_scan(struct wlan_objmgr_pdev *pdev, - enum spectral_scan_mode smode) + enum spectral_scan_mode smode, + enum spectral_cp_error_code *err) { - struct wlan_objmgr_psoc *psoc = NULL; + struct wlan_objmgr_psoc *psoc; psoc = wlan_pdev_get_psoc(pdev); return psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_stop_spectral_scan( - pdev, smode); + pdev, smode, err); } bool diff --git a/target_if/spectral/target_if_spectral.c b/target_if/spectral/target_if_spectral.c index 2ade123cf0f3..5b0eb9455031 100644 --- a/target_if/spectral/target_if_spectral.c +++ b/target_if/spectral/target_if_spectral.c @@ -2138,21 +2138,33 @@ target_if_set_spectral_config(struct wlan_objmgr_pdev *pdev, enum spectral_cp_error_code *err) { struct spectral_config params; - struct target_if_spectral_ops *p_sops = NULL; - struct target_if_spectral *spectral = NULL; + struct target_if_spectral_ops *p_sops; + struct target_if_spectral *spectral; struct spectral_config *sparams; + if (!err) { + spectral_err("Error code argument is null"); + QDF_ASSERT(0); + } + *err = SPECTRAL_SCAN_ERR_INVALID; + + if (smode >= SPECTRAL_SCAN_MODE_MAX) { + spectral_err("Invalid Spectral mode %u", smode); + *err = SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED; + return QDF_STATUS_E_FAILURE; + } + + if (!pdev) { + spectral_err("pdev object is NULL"); + return QDF_STATUS_E_FAILURE; + } spectral = get_target_if_spectral_handle_from_pdev(pdev); - p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); if (!spectral) { spectral_err("spectral object is NULL"); return QDF_STATUS_E_FAILURE; } + p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); - if (smode >= SPECTRAL_SCAN_MODE_MAX) { - spectral_err("Invalid Spectral mode %u", smode); - return QDF_STATUS_E_FAILURE; - } sparams = &spectral->params[smode]; if (!spectral->params_valid[smode]) { @@ -2182,8 +2194,10 @@ target_if_set_spectral_config(struct wlan_objmgr_pdev *pdev, break; case SPECTRAL_PARAM_FFT_SIZE: if ((value < spectral->fft_size_min) || - (value > spectral->fft_size_max)) + (value > spectral->fft_size_max)) { + *err = SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE; return QDF_STATUS_E_FAILURE; + } sparams->ss_fft_size = value; break; case SPECTRAL_PARAM_GC_ENA: @@ -2218,8 +2232,10 @@ target_if_set_spectral_config(struct wlan_objmgr_pdev *pdev, break; case SPECTRAL_PARAM_RPT_MODE: if ((value < SPECTRAL_PARAM_RPT_MODE_MIN) || - (value > SPECTRAL_PARAM_RPT_MODE_MAX)) + (value > SPECTRAL_PARAM_RPT_MODE_MAX)) { + *err = SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE; return QDF_STATUS_E_FAILURE; + } sparams->ss_rpt_mode = value; break; case SPECTRAL_PARAM_BIN_SCALE: @@ -2672,17 +2688,28 @@ target_if_start_spectral_scan(struct wlan_objmgr_pdev *pdev, const enum spectral_scan_mode smode, enum spectral_cp_error_code *err) { - struct target_if_spectral_ops *p_sops = NULL; - struct target_if_spectral *spectral = NULL; + struct target_if_spectral_ops *p_sops; + struct target_if_spectral *spectral; - spectral = get_target_if_spectral_handle_from_pdev(pdev); - if (!spectral) { - spectral_err("Spectral LMAC object is NUll"); + if (!err) { + spectral_err("Error code argument is null"); + QDF_ASSERT(0); + } + *err = SPECTRAL_SCAN_ERR_INVALID; + + if (smode >= SPECTRAL_SCAN_MODE_MAX) { + *err = SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED; + spectral_err("Invalid Spectral mode %u", smode); return QDF_STATUS_E_FAILURE; } - if (smode >= SPECTRAL_SCAN_MODE_MAX) { - spectral_err("Invalid Spectral mode %u", smode); + if (!pdev) { + spectral_err("pdev object is NUll"); + return QDF_STATUS_E_FAILURE; + } + spectral = get_target_if_spectral_handle_from_pdev(pdev); + if (!spectral) { + spectral_err("Spectral LMAC object is NUll"); return QDF_STATUS_E_FAILURE; } @@ -2698,6 +2725,13 @@ target_if_start_spectral_scan(struct wlan_objmgr_pdev *pdev, } qdf_spin_lock(&spectral->spectral_lock); + if (smode == SPECTRAL_SCAN_MODE_AGILE && + !spectral->params[smode].ss_frequency) { + *err = SPECTRAL_SCAN_ERR_PARAM_NOT_INITIALIZED; + qdf_spin_unlock(&spectral->spectral_lock); + return QDF_STATUS_E_FAILURE; + } + target_if_spectral_scan_enable_params(spectral, &spectral->params[smode], smode, err); @@ -2708,11 +2742,28 @@ target_if_start_spectral_scan(struct wlan_objmgr_pdev *pdev, QDF_STATUS target_if_stop_spectral_scan(struct wlan_objmgr_pdev *pdev, - const enum spectral_scan_mode smode) + const enum spectral_scan_mode smode, + enum spectral_cp_error_code *err) { - struct target_if_spectral_ops *p_sops = NULL; - struct target_if_spectral *spectral = NULL; + struct target_if_spectral_ops *p_sops; + struct target_if_spectral *spectral; + if (!err) { + spectral_err("Error code argument is null"); + QDF_ASSERT(0); + } + *err = SPECTRAL_SCAN_ERR_INVALID; + + if (smode >= SPECTRAL_SCAN_MODE_MAX) { + *err = SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED; + spectral_err("Invalid Spectral mode %u", smode); + return QDF_STATUS_E_FAILURE; + } + + if (!pdev) { + spectral_err("pdev object is NUll "); + return QDF_STATUS_E_FAILURE; + } spectral = get_target_if_spectral_handle_from_pdev(pdev); if (!spectral) { spectral_err("Spectral LMAC object is NUll "); @@ -2720,11 +2771,6 @@ target_if_stop_spectral_scan(struct wlan_objmgr_pdev *pdev, } p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); - if (smode >= SPECTRAL_SCAN_MODE_MAX) { - spectral_err("Invalid Spectral mode %u", smode); - return QDF_STATUS_E_FAILURE; - } - qdf_spin_lock(&spectral->spectral_lock); p_sops->stop_spectral_scan(spectral, smode); if (spectral->classify_scan) { diff --git a/target_if/spectral/target_if_spectral.h b/target_if/spectral/target_if_spectral.h index 01253b6cee3b..96d046b2f5df 100644 --- a/target_if/spectral/target_if_spectral.h +++ b/target_if/spectral/target_if_spectral.h @@ -1103,13 +1103,15 @@ void target_if_spectral_send_intf_found_msg( * target_if_stop_spectral_scan() - Stop spectral scan * @pdev: Pointer to pdev object * @smode: Spectral scan mode + * @err: Pointer to error code * * API to stop the current on-going spectral scan * * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE */ QDF_STATUS target_if_stop_spectral_scan(struct wlan_objmgr_pdev *pdev, - const enum spectral_scan_mode smode); + const enum spectral_scan_mode smode, + enum spectral_cp_error_code *err); /** * target_if_spectral_get_vdev() - Get pointer to vdev to be used for Spectral diff --git a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h index 2c0335ae1cc9..b64d36c193b7 100644 --- a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h +++ b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h @@ -531,7 +531,8 @@ struct wlan_lmac_if_sptrl_tx_ops { enum spectral_cp_error_code *err); QDF_STATUS (*sptrlto_stop_spectral_scan) (struct wlan_objmgr_pdev *pdev, - const enum spectral_scan_mode smode); + const enum spectral_scan_mode smode, + enum spectral_cp_error_code *err); bool (*sptrlto_is_spectral_active)(struct wlan_objmgr_pdev *pdev, const enum spectral_scan_mode smode); bool (*sptrlto_is_spectral_enabled)(struct wlan_objmgr_pdev *pdev,