From 21a96f9644e26196db07f840fa04b6671d0df63b Mon Sep 17 00:00:00 2001 From: Vignesh U Date: Thu, 3 May 2018 10:50:33 +0530 Subject: [PATCH 1/7] qcacmn: Add pdev param for host dfs confirmation Add pdev param to update host wait status timeout value. Change-Id: I63fd6ebab1244eaabdf9445e48a04469ea681a36 CRs-Fixed: 2211883 --- dp/inc/cdp_txrx_stats_struct.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dp/inc/cdp_txrx_stats_struct.h b/dp/inc/cdp_txrx_stats_struct.h index 03e10e5ed484..0e4ec47929a5 100644 --- a/dp/inc/cdp_txrx_stats_struct.h +++ b/dp/inc/cdp_txrx_stats_struct.h @@ -1239,6 +1239,9 @@ enum _ol_ath_param_t { OL_ATH_PARAM_PAPI_ENABLE = 364, OL_ATH_PARAM_ISOLATION = 365, OL_ATH_PARAM_MAX_CLIENTS_PER_RADIO = 366, +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) + OL_ATH_PARAM_DFS_HOST_WAIT_TIMEOUT = 367, +#endif }; /* Enumeration of PDEV Configuration parameter */ From 9951d56842c7de92dc6a03710da39f9517a0b2b1 Mon Sep 17 00:00:00 2001 From: Shashikala Prabhu Date: Wed, 16 May 2018 10:08:09 +0530 Subject: [PATCH 2/7] qcacmn: Add WMI changes for host DFS confirmation check Send average radar parameters to FW. Extract host dfs spoof check status from FW. Change-Id: I70c4e5aad0fe1eda55da37abd20cc6d70728edba CRs-Fixed: 2211883 --- wmi/inc/wmi_unified_api.h | 27 +++++++++++ wmi/inc/wmi_unified_param.h | 5 ++ wmi/inc/wmi_unified_priv.h | 10 ++++ wmi/src/wmi_unified_api.c | 27 +++++++++++ wmi/src/wmi_unified_non_tlv.c | 88 +++++++++++++++++++++++++++++++++++ 5 files changed, 157 insertions(+) diff --git a/wmi/inc/wmi_unified_api.h b/wmi/inc/wmi_unified_api.h index 6a3e2e4eccf6..a3b63971bb15 100644 --- a/wmi/inc/wmi_unified_api.h +++ b/wmi/inc/wmi_unified_api.h @@ -2260,4 +2260,31 @@ QDF_STATUS wmi_extract_cca_stats(wmi_unified_t wmi_handle, void *evt_buf, struct wmi_host_congestion_stats *stats); #endif /* QCA_SUPPORT_CP_STATS */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +/** + * wmi_unified_dfs_send_avg_params_cmd() - send average radar parameters cmd. + * @wmi_hdl: wmi handle + * @params: radar found params + * + * This function passes the average radar parameters to fw + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_dfs_send_avg_params_cmd(void *wmi_hdl, + struct dfs_radar_found_params *params); + +/** + * wmi_extract_dfs_status_from_fw() - extract host dfs status from fw. + * @wmi_hdl: wmi handle + * @evt_buf: pointer to event buffer + * @dfs_status_check: pointer to the host dfs status + * + * This function extracts the result of host dfs from fw + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_extract_dfs_status_from_fw(void *wmi_hdl, void *evt_buf, + uint32_t *dfs_status_check); +#endif #endif /* _WMI_UNIFIED_API_H_ */ diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index 64dc05dd526a..8e4db637af0d 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -432,6 +432,7 @@ typedef enum { typedef enum { WMI_HOST_VDEV_START_OK = 0, WMI_HOST_VDEV_START_CHAN_INVALID, + WMI_HOST_VDEV_START_CHAN_BLOCKED, } WMI_HOST_VDEV_START_STATUS; /* @@ -5519,6 +5520,9 @@ typedef enum { wmi_host_swfda_event_id, wmi_sar_get_limits_event_id, wmi_pdev_div_rssi_antid_event_id, +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) + wmi_host_dfs_status_check_event_id, +#endif wmi_events_max, } wmi_conv_event_id; @@ -5944,6 +5948,7 @@ typedef enum { wmi_service_ap_obss_detection_offload, wmi_service_bss_color_offload, wmi_service_gmac_offload_support, + wmi_service_host_dfs_check_support, wmi_services_max, } wmi_conv_service_ids; diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index dfe0097d556e..581b766ccd4b 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -1616,6 +1616,16 @@ QDF_STATUS (*extract_twt_resume_dialog_comp_event)(wmi_unified_t wmi_handle, QDF_STATUS (*extract_cca_stats)(wmi_unified_t wmi_handle, void *evt_buf, struct wmi_host_congestion_stats *stats); #endif /* QCA_SUPPORT_CP_STATS */ + +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +QDF_STATUS (*send_dfs_average_radar_params_cmd)( + wmi_unified_t wmi_handle, + struct dfs_radar_found_params *params); + +QDF_STATUS (*extract_dfs_status_from_fw)(wmi_unified_t wmi_handle, + void *evt_buf, + uint32_t *dfs_status_check); +#endif }; /* Forward declartion for psoc*/ diff --git a/wmi/src/wmi_unified_api.c b/wmi/src/wmi_unified_api.c index 4de0ee01c671..f4c10e344db3 100644 --- a/wmi/src/wmi_unified_api.c +++ b/wmi/src/wmi_unified_api.c @@ -7507,3 +7507,30 @@ QDF_STATUS wmi_extract_cca_stats(wmi_unified_t wmi_handle, void *evt_buf, return QDF_STATUS_E_FAILURE; } #endif /* QCA_SUPPORT_CP_STATS */ + +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +QDF_STATUS +wmi_unified_dfs_send_avg_params_cmd(void *wmi_hdl, + struct dfs_radar_found_params *params) +{ + wmi_unified_t wmi_handle = (wmi_unified_t)wmi_hdl; + + if (wmi_handle->ops->send_dfs_average_radar_params_cmd) + return wmi_handle->ops->send_dfs_average_radar_params_cmd( + wmi_handle, params); + + return QDF_STATUS_E_FAILURE; +} + +QDF_STATUS wmi_extract_dfs_status_from_fw(void *wmi_hdl, void *evt_buf, + uint32_t *dfs_status_check) +{ + wmi_unified_t wmi_handle = (wmi_unified_t)wmi_hdl; + + if (wmi_handle->ops->extract_dfs_status_from_fw) + return wmi_handle->ops->extract_dfs_status_from_fw(wmi_handle, + evt_buf, dfs_status_check); + + return QDF_STATUS_E_FAILURE; +} +#endif diff --git a/wmi/src/wmi_unified_non_tlv.c b/wmi/src/wmi_unified_non_tlv.c index a87de11fe24c..6629205e9173 100644 --- a/wmi/src/wmi_unified_non_tlv.c +++ b/wmi/src/wmi_unified_non_tlv.c @@ -8413,6 +8413,83 @@ QDF_STATUS send_wds_entry_list_cmd_non_tlv(wmi_unified_t wmi_handle) return QDF_STATUS_SUCCESS; } +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +/** + * send_dfs_average_radar_params_cmd_non_tlv() - send average radar params to + * fw. + * @wmi_handle: wmi handle + * @params: pointer to dfs_radar_found_params. + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +static QDF_STATUS send_dfs_average_radar_params_cmd_non_tlv( + wmi_unified_t wmi_handle, + struct dfs_radar_found_params *params) +{ + wmi_host_dfs_radar_found_cmd *cmd; + wmi_buf_t buf; + + int len = sizeof(wmi_host_dfs_radar_found_cmd); + + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) { + WMI_LOGD("%s:wmi_buf_alloc failed\n", __func__); + return QDF_STATUS_E_FAILURE; + } + + cmd = (wmi_host_dfs_radar_found_cmd *)wmi_buf_data(buf); + + /* Fill the WMI structure (PRI, duration, SIDX) from + * the radar_found_param structure and then send + * out. + */ + cmd->pri_min_value = params->pri_min; + cmd->pri_max_value = params->pri_max; + cmd->duration_min_value = params->duration_min; + cmd->duration_max_value = params->duration_max; + cmd->sidx_min_value = params->sidx_min; + cmd->sidx_max_value = params->sidx_max; + + if (wmi_unified_cmd_send(wmi_handle, buf, len, + WMI_HOST_DFS_RADAR_FOUND_CMDID)) { + WMI_LOGD("%s:Failed to send WMI command\n", __func__); + wmi_buf_free(buf); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} + +/** + * extract_dfs_status_from_fw_non_tlv() - extract the result of host dfs check + * from fw + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @fw_dfs_status_code: pointer to the status received from fw. + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +static QDF_STATUS +extract_dfs_status_from_fw_non_tlv(wmi_unified_t wmi_handle, + void *evt_buf, + uint32_t *fw_dfs_status_code) +{ + wmi_host_dfs_status_check_event *ev = + (wmi_host_dfs_status_check_event *)evt_buf; + + if ((ev->status == WMI_HOST_DFS_CHECK_PASSED) || + (ev->status == WMI_HOST_DFS_CHECK_FAILED) || + (ev->status == WMI_HOST_DFS_CHECK_HW_RADAR)) { + *fw_dfs_status_code = ev->status; + return QDF_STATUS_SUCCESS; + } + + WMI_LOGD("%s..Invalid status code : %d received\n", __func__, + ev->status); + + return QDF_STATUS_E_FAILURE; +} +#endif /** * wmi_non_tlv_pdev_id_conversion_enable() - Enable pdev_id conversion @@ -8659,6 +8736,11 @@ struct wmi_ops non_tlv_ops = { .extract_swfda_vdev_id = extract_swfda_vdev_id_non_tlv, #endif /* WLAN_SUPPORT_FILS */ .wmi_pdev_id_conversion_enable = wmi_non_tlv_pdev_id_conversion_enable, +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) + .send_dfs_average_radar_params_cmd = + send_dfs_average_radar_params_cmd_non_tlv, + .extract_dfs_status_from_fw = extract_dfs_status_from_fw_non_tlv, +#endif }; /** @@ -8852,6 +8934,8 @@ static void populate_non_tlv_service(uint32_t *wmi_service) wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_UNAVAILABLE; wmi_service[wmi_service_support_dma] = WMI_SERVICE_UNAVAILABLE; + wmi_service[wmi_service_host_dfs_check_support] = + WMI_SERVICE_HOST_DFS_CHECK_SUPPORT; } /** @@ -8951,6 +9035,10 @@ static void populate_non_tlv_events_id(uint32_t *event_ids) event_ids[wmi_pdev_wds_entry_list_event_id] = WMI_PDEV_WDS_ENTRY_LIST_EVENTID; event_ids[wmi_host_swfda_event_id] = WMI_HOST_SWFDA_EVENTID; +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) + event_ids[wmi_host_dfs_status_check_event_id] = + WMI_HOST_DFS_STATUS_CHECK_EVENTID; +#endif } /** From 0dc7935c0fbdb913c76a7ecdfa50d7817a641c06 Mon Sep 17 00:00:00 2001 From: Vignesh U Date: Wed, 18 Apr 2018 11:22:16 +0530 Subject: [PATCH 3/7] qcacmn: Add global dispatcher for host DFS confirmation check Add tx_ops and rx_ops for host dfs confirmation check. Change-Id: Id77b1561d933cae79276532f01de8ae7843f3bba CRs-Fixed: 2211883 --- .../lmac_if/inc/wlan_lmac_if_def.h | 60 ++++++++++++++----- .../lmac_if/src/wlan_lmac_if.c | 8 +++ 2 files changed, 52 insertions(+), 16 deletions(-) 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 a8e7a1d7c78d..698d9412434e 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 @@ -573,6 +573,9 @@ struct wlan_lmac_if_reg_tx_ops { * @dfs_is_pdev_5ghz: Check if the given pdev is 5GHz. * @dfs_set_phyerr_filter_offload: Config phyerr filter offload. * @dfs_send_offload_enable_cmd: Send dfs offload enable command to fw. + * @dfs_host_dfs_check_support: To check Host DFS confirmation feature + * support. + * @dfs_send_avg_radar_params_to_fw: Send average radar parameters to FW. */ struct wlan_lmac_if_dfs_tx_ops { @@ -616,6 +619,11 @@ struct wlan_lmac_if_dfs_tx_ops { QDF_STATUS (*dfs_send_offload_enable_cmd)( struct wlan_objmgr_pdev *pdev, bool enable); + QDF_STATUS (*dfs_host_dfs_check_support)(struct wlan_objmgr_pdev *pdev, + bool *enabled); + QDF_STATUS (*dfs_send_avg_radar_params_to_fw)( + struct wlan_objmgr_pdev *pdev, + struct dfs_radar_found_params *params); }; /** @@ -1023,6 +1031,7 @@ struct wlan_lmac_if_nan_rx_ops { * @dfs_process_phyerr: Process phyerr. * @dfs_destroy_object: Destroys the DFS object. * @dfs_radar_enable: Enables the radar. + * @dfs_is_radar_enabled: Check if the radar is enabled. * @dfs_control: Used to process ioctls related to DFS. * @dfs_is_precac_timer_running: Check whether precac timer is running. * @dfs_find_vht80_chan_for_precac: Find VHT80 channel for precac. @@ -1037,6 +1046,13 @@ struct wlan_lmac_if_nan_rx_ops { * @dfs_stop: Clear dfs timers. * @dfs_process_phyerr_filter_offload:Process radar event. * @dfs_is_phyerr_filter_offload: Check whether phyerr filter is offload. + * @dfs_action_on_status: Trigger the action to be taken based on + * on host dfs status received from fw. + * @dfs_override_status_timeout: Override the value of host dfs status + * wait timeout. + * @dfs_get_override_status_timeout: Get the value of host dfs status wait + * timeout. + * @dfs_reset_spoof_test: Checks if radar detection is enabled. */ struct wlan_lmac_if_dfs_rx_ops { QDF_STATUS (*dfs_get_radars)(struct wlan_objmgr_pdev *pdev); @@ -1051,24 +1067,27 @@ struct wlan_lmac_if_dfs_rx_ops { QDF_STATUS (*dfs_radar_enable)(struct wlan_objmgr_pdev *pdev, int no_cac, uint32_t opmode); + void (*dfs_is_radar_enabled)(struct wlan_objmgr_pdev *pdev, + int *ignore_dfs); QDF_STATUS (*dfs_control)(struct wlan_objmgr_pdev *pdev, - u_int id, - void *indata, - uint32_t insize, - void *outdata, - uint32_t *outsize, - int *error); + u_int id, + void *indata, + uint32_t insize, + void *outdata, + uint32_t *outsize, + int *error); QDF_STATUS (*dfs_is_precac_timer_running)(struct wlan_objmgr_pdev *pdev, - bool *is_precac_timer_running); - QDF_STATUS (*dfs_find_vht80_chan_for_precac)( - struct wlan_objmgr_pdev *pdev, - uint32_t chan_mode, - uint8_t ch_freq_seg1, - uint32_t *cfreq1, - uint32_t *cfreq2, - uint32_t *phy_mode, - bool *dfs_set_cfreq2, - bool *set_agile); + bool *is_precac_timer_running + ); + QDF_STATUS + (*dfs_find_vht80_chan_for_precac)(struct wlan_objmgr_pdev *pdev, + uint32_t chan_mode, + uint8_t ch_freq_seg1, + uint32_t *cfreq1, + uint32_t *cfreq2, + uint32_t *phy_mode, + bool *dfs_set_cfreq2, + bool *set_agile); QDF_STATUS (*dfs_cancel_precac_timer)(struct wlan_objmgr_pdev *pdev); QDF_STATUS (*dfs_override_precac_timeout)( struct wlan_objmgr_pdev *pdev, @@ -1100,6 +1119,15 @@ struct wlan_lmac_if_dfs_rx_ops { QDF_STATUS (*dfs_is_phyerr_filter_offload)( struct wlan_objmgr_psoc *psoc, bool *is_phyerr_filter_offload); + QDF_STATUS (*dfs_action_on_status)(struct wlan_objmgr_pdev *pdev, + u_int32_t *dfs_status_check); + QDF_STATUS (*dfs_override_status_timeout)( + struct wlan_objmgr_pdev *pdev, + int status_timeout); + QDF_STATUS (*dfs_get_override_status_timeout)( + struct wlan_objmgr_pdev *pdev, + int *status_timeout); + QDF_STATUS (*dfs_reset_spoof_test)(struct wlan_objmgr_pdev *pdev); }; struct wlan_lmac_if_mlme_rx_ops { diff --git a/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c b/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c index 9d7868b1e5f0..db2ce5ca477f 100644 --- a/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c +++ b/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c @@ -312,6 +312,7 @@ wlan_lmac_if_umac_dfs_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) dfs_rx_ops->dfs_process_phyerr = tgt_dfs_process_phyerr; dfs_rx_ops->dfs_destroy_object = tgt_dfs_destroy_object; dfs_rx_ops->dfs_radar_enable = tgt_dfs_radar_enable; + dfs_rx_ops->dfs_is_radar_enabled = tgt_dfs_is_radar_enabled; dfs_rx_ops->dfs_control = tgt_dfs_control; dfs_rx_ops->dfs_is_precac_timer_running = tgt_dfs_is_precac_timer_running; @@ -332,6 +333,13 @@ wlan_lmac_if_umac_dfs_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) tgt_dfs_process_phyerr_filter_offload; dfs_rx_ops->dfs_is_phyerr_filter_offload = tgt_dfs_is_phyerr_filter_offload; + dfs_rx_ops->dfs_action_on_status = tgt_dfs_action_on_status_from_fw; + dfs_rx_ops->dfs_override_status_timeout = + ucfg_dfs_set_override_status_timeout; + dfs_rx_ops->dfs_get_override_status_timeout = + ucfg_dfs_get_override_status_timeout; + dfs_rx_ops->dfs_reset_spoof_test = + tgt_dfs_reset_spoof_test; return QDF_STATUS_SUCCESS; } From 4159e623b5750724fc42aa02fd0143deda2cc349 Mon Sep 17 00:00:00 2001 From: Vignesh U Date: Wed, 18 Apr 2018 11:20:41 +0530 Subject: [PATCH 4/7] qcacmn: Add target_if changes for host DFS confirmation check Register for host dfs check event. Change-Id: I7d6a87e9a6d7e4a4b7a127e05d230b876581bb12 CRs-Fixed: 2211883 --- .../dfs/inc/target_if_dfs_partial_offload.h | 50 +++++++++- target_if/dfs/src/target_if_dfs.c | 43 ++++++++ .../dfs/src/target_if_dfs_partial_offload.c | 99 +++++++++++++++++++ 3 files changed, 189 insertions(+), 3 deletions(-) diff --git a/target_if/dfs/inc/target_if_dfs_partial_offload.h b/target_if/dfs/inc/target_if_dfs_partial_offload.h index 2a1b9c96ba78..f1f092906459 100644 --- a/target_if/dfs/inc/target_if_dfs_partial_offload.h +++ b/target_if/dfs/inc/target_if_dfs_partial_offload.h @@ -50,10 +50,54 @@ target_if_dfs_reg_phyerr_events(struct wlan_objmgr_psoc *psoc) */ #if defined(WLAN_DFS_PARTIAL_OFFLOAD) QDF_STATUS target_if_dfs_get_caps(struct wlan_objmgr_pdev *pdev, - struct wlan_dfs_caps *dfs_caps); + struct wlan_dfs_caps *dfs_caps); #else -static QDF_STATUS target_if_dfs_get_caps(struct wlan_objmgr_pdev *pdev, - struct wlan_dfs_caps *dfs_caps) +static inline QDF_STATUS target_if_dfs_get_caps(struct wlan_objmgr_pdev *pdev, + struct wlan_dfs_caps *dfs_caps) +{ + return QDF_STATUS_SUCCESS; +} +#endif + +/** + * target_if_dfs_status_check_event_handler() - Host dfs confirmation event + * handler. + * @scn: Handle to HIF context + * @data: radar event buffer + * @datalen: radar event buffer length + * + * Return: 0 on success + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +int target_if_dfs_status_check_event_handler(ol_scn_t scn, + uint8_t *data, + uint32_t datalen); +#else +static inline +int target_if_dfs_status_check_event_handler(ol_scn_t scn, + uint8_t *data, + uint32_t datalen) +{ + return 0; +} +#endif + +/** + * target_if_dfs_send_avg_params_to_fw() - Send average parameters to FW. + * @pdev: pdev pointer + * @params: Pointer to dfs_radar_found_params structure. + * + * Return: QDF_STATUS + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +QDF_STATUS target_if_dfs_send_avg_params_to_fw( + struct wlan_objmgr_pdev *pdev, + struct dfs_radar_found_params *params); +#else +static inline +QDF_STATUS target_if_dfs_send_avg_params_to_fw( + struct wlan_objmgr_pdev *pdev, + struct dfs_radar_found_params *params) { return QDF_STATUS_SUCCESS; } diff --git a/target_if/dfs/src/target_if_dfs.c b/target_if/dfs/src/target_if_dfs.c index 78d3d12ebe53..64d4c4189d0c 100644 --- a/target_if/dfs/src/target_if_dfs.c +++ b/target_if/dfs/src/target_if_dfs.c @@ -40,6 +40,44 @@ #include #include +/** + * target_if_dfs_register_host_status_check_event() - Register host dfs + * confirmation event. + * @psoc: pointer to psoc. + * + * Return: QDF_STATUS. + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +static QDF_STATUS target_if_dfs_register_host_status_check_event( + struct wlan_objmgr_psoc *psoc) + +{ + wmi_unified_t wmi_handle; + QDF_STATUS retval; + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("null wmi_handle"); + return QDF_STATUS_E_FAILURE; + } + + retval = wmi_unified_register_event(wmi_handle, + wmi_host_dfs_status_check_event_id, + target_if_dfs_status_check_event_handler); + if (QDF_IS_STATUS_ERROR(retval)) + target_if_err("wmi_dfs_radar_detection_event_id ret=%d", + retval); + + return retval; +} +#else +static QDF_STATUS target_if_dfs_register_host_status_check_event( + struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} +#endif + /** * target_if_is_dfs_3() - Is dfs3 support or not * @target_type: target type being used. @@ -174,6 +212,9 @@ static QDF_STATUS target_if_dfs_register_event_handler( target_if_err("null tgt_psoc_info"); return QDF_STATUS_E_FAILURE; } + + target_if_dfs_register_host_status_check_event(psoc); + if (target_if_is_dfs_3( target_psoc_get_target_type(tgt_psoc_info))) return target_if_dfs_reg_phyerr_events(psoc); @@ -316,6 +357,8 @@ QDF_STATUS target_if_register_dfs_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) &target_if_dfs_set_phyerr_filter_offload; dfs_tx_ops->dfs_get_caps = &target_if_dfs_get_caps; + dfs_tx_ops->dfs_send_avg_radar_params_to_fw = + &target_if_dfs_send_avg_params_to_fw; return QDF_STATUS_SUCCESS; } diff --git a/target_if/dfs/src/target_if_dfs_partial_offload.c b/target_if/dfs/src/target_if_dfs_partial_offload.c index fbe9a5edc885..af09b710a021 100644 --- a/target_if/dfs/src/target_if_dfs_partial_offload.c +++ b/target_if/dfs/src/target_if_dfs_partial_offload.c @@ -25,6 +25,7 @@ #include #include "target_type.h" #include "target_if_dfs_partial_offload.h" +#include "target_if_dfs.h" QDF_STATUS target_if_dfs_reg_phyerr_events(struct wlan_objmgr_psoc *psoc) { @@ -87,3 +88,101 @@ QDF_STATUS target_if_dfs_get_caps(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_SUCCESS; } + +#if defined(HOST_DFS_SPOOF_TEST) +QDF_STATUS target_if_dfs_send_avg_params_to_fw( + struct wlan_objmgr_pdev *pdev, + struct dfs_radar_found_params *params) +{ + QDF_STATUS status; + wmi_unified_t wmi_handle; + + if (!pdev) { + target_if_err("null pdev"); + return QDF_STATUS_E_FAILURE; + } + + wmi_handle = get_wmi_unified_hdl_from_pdev(pdev); + if (!wmi_handle) { + target_if_err("null wmi_handle"); + return QDF_STATUS_E_FAILURE; + } + + status = wmi_unified_dfs_send_avg_params_cmd(wmi_handle, + params); + if (QDF_IS_STATUS_ERROR(status)) + target_if_err("dfs radar found average parameters send failed: %d", + status); + + return status; +} + +int target_if_dfs_status_check_event_handler(ol_scn_t scn, + uint8_t *data, + uint32_t datalen) +{ + struct wlan_objmgr_psoc *psoc; + struct wlan_objmgr_pdev *pdev; + struct wlan_lmac_if_dfs_rx_ops *dfs_rx_ops; + u_int32_t dfs_status_check; + wmi_unified_t wmi_hdl; + + if (!scn || !data) { + target_if_err("scn: %pK, data: %pK", scn, data); + return -EINVAL; + } + + psoc = target_if_get_psoc_from_scn_hdl(scn); + if (!psoc) { + target_if_err("null psoc"); + return -EINVAL; + } + + /* Since Partial Offload chipsets have only one pdev per psoc, the first + * pdev from the pdev list is used. + */ + pdev = wlan_objmgr_get_pdev_by_id(psoc, 0, WLAN_DFS_ID); + if (!pdev) { + target_if_err("null pdev"); + return -EINVAL; + } + + dfs_rx_ops = target_if_dfs_get_rx_ops(psoc); + if (!dfs_rx_ops) { + target_if_err("null dfs_rx_ops"); + wlan_objmgr_pdev_release_ref(pdev, WLAN_DFS_ID); + return -EINVAL; + } + + if (!dfs_rx_ops->dfs_action_on_status) { + target_if_err("dfs_rx_ops->dfs_action_on_status is NULL"); + wlan_objmgr_pdev_release_ref(pdev, WLAN_DFS_ID); + return -EINVAL; + } + + wmi_hdl = get_wmi_unified_hdl_from_pdev(pdev); + if (!wmi_hdl) { + target_if_err("wmi_hdl is NULL"); + wlan_objmgr_pdev_release_ref(pdev, WLAN_DFS_ID); + return -EINVAL; + } + + if (wmi_extract_dfs_status_from_fw(wmi_hdl, data, &dfs_status_check) != + QDF_STATUS_SUCCESS) { + target_if_err("failed to extract status response from FW"); + wlan_objmgr_pdev_release_ref(pdev, WLAN_DFS_ID); + return -EINVAL; + } + + if (dfs_rx_ops->dfs_action_on_status(pdev, &dfs_status_check) != + QDF_STATUS_SUCCESS) { + target_if_err("dfs action on host dfs status from FW failed"); + wlan_objmgr_pdev_release_ref(pdev, WLAN_DFS_ID); + return -EINVAL; + } + + wlan_objmgr_pdev_release_ref(pdev, WLAN_DFS_ID); + + return 0; +} +#endif From 661654d37653d857d3ef631c9ad43c7b68d24de5 Mon Sep 17 00:00:00 2001 From: Vignesh U Date: Wed, 18 Apr 2018 13:36:27 +0530 Subject: [PATCH 5/7] qcacmn: Send radar found command to FW In FCC domain, process the radar pulses and send the summary of radar found information to FW. Change-Id: Ib30f57927a9718315fd90f5c44d47dae38bf36f0 CRs-Fixed: 2211883 --- umac/dfs/core/src/dfs.h | 42 ++++++ umac/dfs/core/src/dfs_partial_offload_radar.h | 87 ++++++++++++ .../core/src/dfs_process_radar_found_ind.h | 12 ++ .../src/filtering/dfs_partial_offload_radar.c | 124 ++++++++++++++++++ .../src/filtering/dfs_process_radarevent.c | 109 ++++++++++++--- umac/dfs/core/src/misc/dfs.c | 6 +- umac/dfs/core/src/misc/dfs_filter_init.c | 3 + .../dispatcher/inc/wlan_dfs_public_struct.h | 18 +++ umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h | 14 ++ umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h | 46 +++++++ umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c | 40 ++++++ umac/dfs/dispatcher/src/wlan_dfs_ucfg_api.c | 47 ++++++- 12 files changed, 526 insertions(+), 22 deletions(-) diff --git a/umac/dfs/core/src/dfs.h b/umac/dfs/core/src/dfs.h index 86e4573e56b5..1f7d294b524d 100644 --- a/umac/dfs/core/src/dfs.h +++ b/umac/dfs/core/src/dfs.h @@ -353,6 +353,13 @@ WLAN_DFSNOL_UNLOCK(dfs); \ } while (0) +/* Host sends the average parameters of the radar pulses and starts the status + * wait timer with this timeout. + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +#define HOST_DFS_STATUS_WAIT_TIMER_MS 100 +#endif + /** * struct dfs_pulseparams - DFS pulse param structure. * @p_time: Time for start of pulse in usecs. @@ -921,6 +928,26 @@ struct dfs_event_log { * @dfs_use_nol_subchannel_marking: Use subchannel marking logic to add only * radar affected subchannel instead of all * bonding channels. + * @dfs_host_wait_timer: The timer that is started from host after + * sending the average radar parameters. + * Before this timeout host expects its dfs + * status from fw. + * @dfs_average_pri: Average pri value of the received radar + * pulses. + * @dfs_average_duration: Average duration of the received radar + * pulses. + * @dfs_average_sidx: Average sidx of the received radar pulses. + * @dfs_is_host_wait_running: Indicates if host dfs status wait timer is + * running. + * @dfs_average_params_sent: Indicates if host has sent the average + * radar parameters. + * @dfs_no_res_from_fw: Indicates no response from fw. + * @dfs_spoof_check_failed: Indicates if the spoof check has failed. + * @dfs_spoof_test_done: Indicates if the sppof test is done. + * @dfs_seg_id: Segment ID of the radar hit channel. + * @dfs_false_radar_found: Indicates if false radar is found. + * @dfs_status_timeout_override: Used to change the timeout value of + * dfs_host_wait_timer. */ struct wlan_dfs { uint32_t dfs_debug_mask; @@ -1020,6 +1047,21 @@ struct wlan_dfs { qdf_spinlock_t dfs_nol_lock; uint16_t tx_leakage_threshold; bool dfs_use_nol_subchannel_marking; +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) + os_timer_t dfs_host_wait_timer; + uint32_t dfs_average_pri; + uint32_t dfs_average_duration; + uint32_t dfs_average_sidx; + uint8_t dfs_is_host_wait_running:1, + dfs_average_params_sent:1, + dfs_no_res_from_fw:1, + dfs_spoof_check_failed:1, + dfs_spoof_test_done:1; + uint8_t dfs_seg_id; + int dfs_false_radar_found; + struct dfs_channel dfs_radar_found_chan; + int dfs_status_timeout_override; +#endif }; /** diff --git a/umac/dfs/core/src/dfs_partial_offload_radar.h b/umac/dfs/core/src/dfs_partial_offload_radar.h index 7cc408ca5448..6a03a2809361 100644 --- a/umac/dfs/core/src/dfs_partial_offload_radar.h +++ b/umac/dfs/core/src/dfs_partial_offload_radar.h @@ -36,4 +36,91 @@ static void dfs_get_po_radars(struct wlan_dfs *dfs) { } #endif + +/** + * dfs_send_avg_params_to_fw - send avg radar parameters to FW. + * @dfs: Pointer to wlan_dfs structure. + * @params: Pointer to dfs_radar_found_params. + * + * Return: None + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +void dfs_send_avg_params_to_fw(struct wlan_dfs *dfs, + struct dfs_radar_found_params *params); +#else +static inline +void dfs_send_avg_params_to_fw(struct wlan_dfs *dfs, + struct dfs_radar_found_params *params) +{ +} +#endif + +/** + * dfs_host_wait_timer_init() - Initialize dfs host status wait timer. + * @dfs: Pointer to wlan_dfs structure. + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +void dfs_host_wait_timer_init(struct wlan_dfs *dfs); +#else +static inline void dfs_host_wait_timer_init(struct wlan_dfs *dfs) +{ +} +#endif + +/** + * dfs_set_override_status_timeout() - Change the dfs host status timeout. + * @dfs: Pointer to wlan_dfs structure. + * @status_timeout: timeout value. + * + * Return: QDF_STATUS + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +QDF_STATUS dfs_set_override_status_timeout(struct wlan_dfs *dfs, + int status_timeout); +#else +static inline QDF_STATUS dfs_set_override_status_timeout(struct wlan_dfs *dfs, + int status_timeout) +{ + return QDF_STATUS_SUCCESS; +} +#endif + +/** + * dfs_get_override_status_timeout() - Get the dfs host status timeout value. + * @dfs: Pointer to wlan_dfs structure. + * @status_timeout: Pointer to timeout value. + * + * Return: QDF_STATUS + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +QDF_STATUS dfs_get_override_status_timeout(struct wlan_dfs *dfs, + int *status_timeout); +#else +static inline +QDF_STATUS dfs_get_override_status_timeout(struct wlan_dfs *dfs, + int *status_timeout) +{ + return QDF_STATUS_SUCCESS; +} +#endif + +/** + * dfs_radarfound_action_fcc() - The dfs action on radar detection by host for + * FCC domain. + * @dfs: Pointer to wlan_dfs structure. + * @seg_id: segment id. + * @false_radar_found: Indicates if false radar is found. + * + * Return: None + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +void dfs_radarfound_action_fcc(struct wlan_dfs *dfs, uint8_t seg_id, + int false_radar_found); +#else +static inline void dfs_radarfound_action_fcc(struct wlan_dfs *dfs, + uint8_t seg_id, + int false_radar_found) +{ +} +#endif #endif /* _DFS_PARTIAL_OFFLOAD_RADAR_H_ */ diff --git a/umac/dfs/core/src/dfs_process_radar_found_ind.h b/umac/dfs/core/src/dfs_process_radar_found_ind.h index 68a6e4c87bf0..b2346fee9406 100644 --- a/umac/dfs/core/src/dfs_process_radar_found_ind.h +++ b/umac/dfs/core/src/dfs_process_radar_found_ind.h @@ -120,3 +120,15 @@ void dfs_process_radar_found_indication(struct wlan_dfs *dfs, */ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, struct radar_found_info *radar_found); + +/** + * dfs_radarfound_action_generic() - The dfs action on radar detection by host + * for domains other than FCC. + * @dfs: Pointer to wlan_dfs structure. + * @seg_id: segment id. + * @false_radar_found: Indicates detection of false radar. + * + * Return: None + */ +void dfs_radarfound_action_generic(struct wlan_dfs *dfs, + uint8_t seg_id, int false_radar_found); diff --git a/umac/dfs/core/src/filtering/dfs_partial_offload_radar.c b/umac/dfs/core/src/filtering/dfs_partial_offload_radar.c index ece6f510ceb5..37696181e041 100644 --- a/umac/dfs/core/src/filtering/dfs_partial_offload_radar.c +++ b/umac/dfs/core/src/filtering/dfs_partial_offload_radar.c @@ -26,6 +26,9 @@ #include "wlan_dfs_lmac_api.h" #include "../dfs_internal.h" #include "../dfs_partial_offload_radar.h" +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +#include "../dfs_process_radar_found_ind.h" +#endif /** * struct dfs_pulse dfs_fcc_radars - FCC radar table for Offload chipsets. @@ -425,3 +428,124 @@ void dfs_get_po_radars(struct wlan_dfs *dfs) dfs_init_radar_filters(dfs, &rinfo); } + +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +void dfs_send_avg_params_to_fw(struct wlan_dfs *dfs, + struct dfs_radar_found_params *params) +{ + tgt_dfs_send_avg_params_to_fw(dfs->dfs_pdev_obj, params); +} + +/** + * dfs_no_res_from_fw_task() - The timer function that is called if there is no + * response from fw after sending the average radar pulse parameters. + */ +static os_timer_func(dfs_no_res_from_fw_task) +{ + struct wlan_dfs *dfs = NULL; + + OS_GET_TIMER_ARG(dfs, struct wlan_dfs *); + + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return; + } + + dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "Host wait timer expired"); + + dfs->dfs_is_host_wait_running = 0; + dfs->dfs_no_res_from_fw = 1; + dfs_radarfound_action_generic(dfs, dfs->dfs_seg_id, + dfs->dfs_false_radar_found); + dfs->dfs_seg_id = 0; + dfs->dfs_false_radar_found = 0; +} + +void dfs_host_wait_timer_init(struct wlan_dfs *dfs) +{ + qdf_timer_init(NULL, + &(dfs->dfs_host_wait_timer), + dfs_no_res_from_fw_task, + (void *)(dfs), + QDF_TIMER_TYPE_WAKE_APPS); + dfs->dfs_status_timeout_override = -1; +} + +QDF_STATUS dfs_set_override_status_timeout(struct wlan_dfs *dfs, + int status_timeout) +{ + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return QDF_STATUS_E_FAILURE; + } + + dfs->dfs_status_timeout_override = status_timeout; + + dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, + "Host wait status timeout is now %s : %d", + (status_timeout == -1) ? "default" : "overridden", + status_timeout); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS dfs_get_override_status_timeout(struct wlan_dfs *dfs, + int *status_timeout) +{ + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return QDF_STATUS_E_FAILURE; + } + + *status_timeout = dfs->dfs_status_timeout_override; + + return QDF_STATUS_SUCCESS; +} + +/** + * dfs_extract_radar_found_params() - Copy the contents of average radar + * parameters to dfs_radar_found_params parameter structure. + * + * @dfs: Pointer to wlan_dfs structure which contains the average radar + * parameters. + * @params: Pointer to dfs_radar_found_params structure. + */ +static +void dfs_extract_radar_found_params(struct wlan_dfs *dfs, + struct dfs_radar_found_params *params) +{ + qdf_mem_zero(params, sizeof(*params)); + params->pri_min = dfs->dfs_average_pri; + params->pri_max = dfs->dfs_average_pri; + params->duration_min = dfs->dfs_average_duration; + params->duration_max = dfs->dfs_average_duration; + params->sidx_min = dfs->dfs_average_sidx; + params->sidx_max = dfs->dfs_average_sidx; + + /* Bangradar will not populate any of these average + * parameters as pulse is not received. If these variables + * are not resetted here, these go as radar_found params + * for bangradar if bangradar is issued after real radar. + */ + dfs->dfs_average_sidx = 0; + dfs->dfs_average_duration = 0; + dfs->dfs_average_pri = 0; +} + +void dfs_radarfound_action_fcc(struct wlan_dfs *dfs, uint8_t seg_id, + int false_radar_found) +{ + struct dfs_radar_found_params params; + + qdf_mem_copy(&dfs->dfs_radar_found_chan, dfs->dfs_curchan, + sizeof(dfs->dfs_radar_found_chan)); + dfs_extract_radar_found_params(dfs, ¶ms); + dfs_send_avg_params_to_fw(dfs, ¶ms); + dfs->dfs_is_host_wait_running = 1; + dfs->dfs_seg_id = seg_id; + dfs->dfs_false_radar_found = false_radar_found; + qdf_timer_mod(&dfs->dfs_host_wait_timer, + (dfs->dfs_status_timeout_override == + -1) ? HOST_DFS_STATUS_WAIT_TIMER_MS : + dfs->dfs_status_timeout_override); +} diff --git a/umac/dfs/core/src/filtering/dfs_process_radarevent.c b/umac/dfs/core/src/filtering/dfs_process_radarevent.c index c8d54b440b99..ff6223d2e70e 100644 --- a/umac/dfs/core/src/filtering/dfs_process_radarevent.c +++ b/umac/dfs/core/src/filtering/dfs_process_radarevent.c @@ -26,6 +26,9 @@ #include "../dfs_channel.h" #include "../dfs_internal.h" #include "../dfs_process_radar_found_ind.h" +#include "wlan_dfs_utils_api.h" +#include "wlan_dfs_lmac_api.h" +#include "../dfs_partial_offload_radar.h" #define FREQ_5500_MHZ 5500 #define FREQ_5500_MHZ 5500 @@ -440,6 +443,53 @@ void __dfs_process_radarevent(struct wlan_dfs *dfs, return; } +/** + * dfs_cal_average_radar_parameters() - Calculate the average radar parameters. + * @dfs: Pointer to wlan_dfs structure. + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +static void dfs_cal_average_radar_parameters(struct wlan_dfs *dfs) +{ + int i, count = 0; + u_int32_t total_pri = 0; + u_int32_t total_duration = 0; + u_int32_t total_sidx = 0; + + /* Calculating average PRI, Duration, SIDX from + * the 2nd pulse, ignoring the 1st pulse (radar_log[0]). + * This is because for the first pulse, the diff_ts will be + * (0 - current_ts) which will be a huge value. + * Average PRI computation will be wrong. FW returns a + * failure test result as PRI does not match their expected + * value. + */ + + for (i = 1; (i < DFS_EVENT_LOG_SIZE) && (i < dfs->dfs_event_log_count); + i++) { + total_pri += dfs->radar_log[i].diff_ts; + total_duration += dfs->radar_log[i].dur; + total_sidx += dfs->radar_log[i].sidx; + count++; + } + + if (count > 0) { + dfs->dfs_average_pri = total_pri / count; + dfs->dfs_average_duration = total_duration / count; + dfs->dfs_average_sidx = total_sidx / count; + + dfs_info(dfs, WLAN_DEBUG_DFS2, + "Avg.PRI =%u, Avg.duration =%u Avg.sidx =%u", + dfs->dfs_average_pri, + dfs->dfs_average_duration, + dfs->dfs_average_sidx); + } +} +#else +static void dfs_cal_average_radar_parameters(struct wlan_dfs *dfs) +{ +} +#endif + /** * dfs_radarfound_reset_vars() - Reset dfs variables after radar found * @dfs: Pointer to wlan_dfs structure. @@ -473,8 +523,10 @@ static inline void dfs_radarfound_reset_vars( * filter match. This can be used to collect information * on false radar detection. */ - if (dfs->dfs_event_log_on) + if (dfs->dfs_event_log_on) { + dfs_cal_average_radar_parameters(dfs); dfs_print_radar_events(dfs); + } dfs_reset_radarq(dfs); dfs_reset_alldelaylines(dfs); @@ -1196,6 +1248,30 @@ static inline void dfs_false_radarfound_reset_vars( dfs->dfs_phyerr_w53_counter = 0; } +void dfs_radarfound_action_generic(struct wlan_dfs *dfs, + uint8_t seg_id, int false_radar_found) +{ + struct radar_found_info *radar_found; + + radar_found = qdf_mem_malloc(sizeof(*radar_found)); + if (!radar_found) { + dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, + "radar_found allocation failed"); + return; + } + + qdf_mem_zero(radar_found, sizeof(*radar_found)); + radar_found->segment_id = seg_id; + radar_found->pdev_id = + wlan_objmgr_pdev_get_pdev_id(dfs->dfs_pdev_obj); + + dfs_process_radar_ind(dfs, radar_found); + qdf_mem_free(radar_found); + + if (false_radar_found) + dfs_false_radarfound_reset_vars(dfs); +} + void dfs_process_radarevent( struct wlan_dfs *dfs, struct dfs_channel *chan) @@ -1222,26 +1298,21 @@ void dfs_process_radarevent( dfsfound: if (retval) { - struct radar_found_info *radar_found; - dfs_radarfound_reset_vars(dfs, rs, chan, seg_id); - - radar_found = qdf_mem_malloc(sizeof(*radar_found)); - if (!radar_found) { - dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, - "radar_found allocation failed"); - return; + /* If Host DFS confirmation is supported, save the curchan as + * radar found chan, send radar found indication along with + * average radar parameters to FW and start the host status + * wait timer. + */ + if (utils_get_dfsdomain(dfs->dfs_pdev_obj) == DFS_FCC_DOMAIN && + lmac_is_host_dfs_check_support_enabled( + dfs->dfs_pdev_obj)) { + dfs_radarfound_action_fcc(dfs, seg_id, + false_radar_found); + } else { + dfs_radarfound_action_generic(dfs, seg_id, + false_radar_found); } - - qdf_mem_zero(radar_found, sizeof(*radar_found)); - radar_found->segment_id = seg_id; - radar_found->pdev_id = - wlan_objmgr_pdev_get_pdev_id(dfs->dfs_pdev_obj); - - dfs_process_radar_ind(dfs, radar_found); - qdf_mem_free(radar_found); } - if (false_radar_found) - dfs_false_radarfound_reset_vars(dfs); } diff --git a/umac/dfs/core/src/misc/dfs.c b/umac/dfs/core/src/misc/dfs.c index 9ef6bc5038df..a540abe9dd28 100644 --- a/umac/dfs/core/src/misc/dfs.c +++ b/umac/dfs/core/src/misc/dfs.c @@ -29,7 +29,7 @@ #include "../dfs_internal.h" #include "../dfs_filter_init.h" #include "../dfs_full_offload.h" - +#include "wlan_dfs_utils_api.h" /** * dfs_testtimer_task() - Sends CSA in the current channel. @@ -290,6 +290,10 @@ int dfs_control(struct wlan_dfs *dfs, if (dfs->dfs_debug_mask & WLAN_DEBUG_DFS3) { /* Enable debug Radar Event */ dfs->dfs_event_log_on = 1; + } else if ((utils_get_dfsdomain(dfs->dfs_pdev_obj) == + DFS_FCC_DOMAIN) && + lmac_is_host_dfs_check_support_enabled(dfs->dfs_pdev_obj)) { + dfs->dfs_event_log_on = 1; } else { dfs->dfs_event_log_on = 0; } diff --git a/umac/dfs/core/src/misc/dfs_filter_init.c b/umac/dfs/core/src/misc/dfs_filter_init.c index e03f6ad11949..ca40314949b9 100644 --- a/umac/dfs/core/src/misc/dfs_filter_init.c +++ b/umac/dfs/core/src/misc/dfs_filter_init.c @@ -28,6 +28,7 @@ #include "wlan_dfs_tgt_api.h" #include "../dfs_internal.h" #include "../dfs_filter_init.h" +#include "../dfs_partial_offload_radar.h" /* * Channel switch announcement (CSA) @@ -103,6 +104,8 @@ int dfs_main_attach(struct wlan_dfs *dfs) /*Verify : Passing NULL to qdf_timer_init().*/ dfs_main_task_timer_init(dfs); + dfs_host_wait_timer_init(dfs); + WLAN_DFSQ_LOCK_CREATE(dfs); STAILQ_INIT(&dfs->dfs_radarq); WLAN_ARQ_LOCK_CREATE(dfs); diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_public_struct.h b/umac/dfs/dispatcher/inc/wlan_dfs_public_struct.h index b8aad06ae48e..b4035331e9fe 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_public_struct.h +++ b/umac/dfs/dispatcher/inc/wlan_dfs_public_struct.h @@ -100,4 +100,22 @@ struct radar_event_info { struct dfs_user_config { bool dfs_is_phyerr_filter_offload; }; + +/** + * struct dfs_radar_found_params - radar found parameters. + * @pri_min: Minimum PRI of detected radar pulse. + * @pri_max: Max PRI of detected radar pulse. + * @duration_min: Min duration of detected pulse in us. + * @duration_max: Max duration of detected pulse in us. + * @sidx_min: Min softare index of detected radar pulse. + * @sidx_max: Max software index of detected radar pulse. + */ +struct dfs_radar_found_params { + u_int32_t pri_min; + u_int32_t pri_max; + u_int32_t duration_min; + u_int32_t duration_max; + u_int32_t sidx_min; + u_int32_t sidx_max; +}; #endif diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h b/umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h index e5d6f4a160e4..80bcca44480c 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h +++ b/umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h @@ -284,4 +284,18 @@ QDF_STATUS tgt_dfs_process_emulate_bang_radar_cmd(struct wlan_objmgr_pdev *pdev, */ QDF_STATUS tgt_dfs_set_phyerr_filter_offload(struct wlan_objmgr_pdev *pdev); #endif + +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +/** + * tgt_dfs_send_avg_params_to_fw() - send average radar parameters to fw. + * @pdev: Pointer to DFS pdev object. + * @params: Pointer to dfs radar average parameters. + * + * Return: QDF_STATUS + */ +QDF_STATUS +tgt_dfs_send_avg_params_to_fw(struct wlan_objmgr_pdev *pdev, + struct dfs_radar_found_params *params); +#endif + #endif /* _WLAN_DFS_TGT_API_H_ */ diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h b/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h index cd41d357fee3..cf85d5aa8c6c 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h +++ b/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h @@ -243,4 +243,50 @@ QDF_STATUS ucfg_dfs_get_precac_enable(struct wlan_objmgr_pdev *pdev, int *buff); QDF_STATUS ucfg_dfs_update_config(struct wlan_objmgr_psoc *psoc, struct dfs_user_config *req); #endif + +/** + * ucfg_dfs_set_override_status_timeout() - override the value of host dfs + * status wait timeout. + * @pdev: Pointer to DFS pdev object. + * @status_timeout: timeout value. + * + * Wrapper function for dfs_set_override_status_timeout(). + * This function called from outside of dfs component. + * + * Return: QDF_STATUS + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +QDF_STATUS ucfg_dfs_set_override_status_timeout(struct wlan_objmgr_pdev *pdev, + int status_timeout); +#else +static inline +QDF_STATUS ucfg_dfs_set_override_status_timeout(struct wlan_objmgr_pdev *pdev, + int status_timeout) +{ + return QDF_STATUS_SUCCESS; +} +#endif + +/** + * ucfg_dfs_get_override_status_timeout() - Get the value of host dfs status + * wait timeout. + * @pdev: Pointer to DFS pdev object. + * @status_timeout: Pointer to save the timeout value. + * + * Wrapper function for dfs_get_override_status_timeout(). + * This function called from outside of dfs component. + * + * Return: QDF_STATUS + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +QDF_STATUS ucfg_dfs_get_override_status_timeout(struct wlan_objmgr_pdev *pdev, + int *status_timeout); +#else +static inline +QDF_STATUS ucfg_dfs_get_override_status_timeout(struct wlan_objmgr_pdev *pdev, + int *status_timeout) +{ + return QDF_STATUS_SUCCESS; +} +#endif #endif /* _WLAN_DFS_UCFG_API_H_ */ diff --git a/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c b/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c index c09cfb50c8a7..561454163444 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c @@ -446,3 +446,43 @@ QDF_STATUS tgt_dfs_set_phyerr_filter_offload(struct wlan_objmgr_pdev *pdev) } qdf_export_symbol(tgt_dfs_set_phyerr_filter_offload); #endif + +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +QDF_STATUS +tgt_dfs_send_avg_params_to_fw(struct wlan_objmgr_pdev *pdev, + struct dfs_radar_found_params *params) +{ + struct wlan_objmgr_psoc *psoc; + struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops; + struct wlan_dfs *dfs; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return status; + } + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null"); + return status; + } + + dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc); + if (dfs_tx_ops && dfs_tx_ops->dfs_send_avg_radar_params_to_fw) + status = dfs_tx_ops->dfs_send_avg_radar_params_to_fw(pdev, + params); + + if (QDF_IS_STATUS_SUCCESS(status)) { + dfs->dfs_average_params_sent = 1; + dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, + "Average radar parameters sent %d", + dfs->dfs_average_params_sent); + } + + return status; +} + +qdf_export_symbol(tgt_dfs_send_avg_params_to_fw); +#endif diff --git a/umac/dfs/dispatcher/src/wlan_dfs_ucfg_api.c b/umac/dfs/dispatcher/src/wlan_dfs_ucfg_api.c index f89303347088..6e4ac9bf7f75 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_ucfg_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_ucfg_api.c @@ -25,6 +25,7 @@ #include "wlan_dfs_ucfg_api.h" #include "../../core/src/dfs.h" #include "../../core/src/dfs_zero_cac.h" +#include "../../core/src/dfs_partial_offload_radar.h" #include QDF_STATUS ucfg_dfs_is_ap_cac_timer_running(struct wlan_objmgr_pdev *pdev, @@ -125,8 +126,10 @@ QDF_STATUS ucfg_dfs_set_precac_enable(struct wlan_objmgr_pdev *pdev, struct wlan_dfs *dfs; dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); - if (!dfs) + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); return QDF_STATUS_E_FAILURE; + } dfs_set_precac_enable(dfs, value); @@ -140,8 +143,10 @@ QDF_STATUS ucfg_dfs_get_precac_enable(struct wlan_objmgr_pdev *pdev, struct wlan_dfs *dfs; dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); - if (!dfs) + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); return QDF_STATUS_E_FAILURE; + } *buff = dfs_get_precac_enable(dfs); @@ -176,3 +181,41 @@ QDF_STATUS ucfg_dfs_update_config(struct wlan_objmgr_psoc *psoc, } qdf_export_symbol(ucfg_dfs_update_config); #endif + +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +QDF_STATUS ucfg_dfs_set_override_status_timeout(struct wlan_objmgr_pdev *pdev, + int status_timeout) +{ + struct wlan_dfs *dfs; + + dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); + return QDF_STATUS_E_FAILURE; + } + + dfs_set_override_status_timeout(dfs, status_timeout); + + return QDF_STATUS_SUCCESS; +} + +qdf_export_symbol(ucfg_dfs_set_override_status_timeout); + +QDF_STATUS ucfg_dfs_get_override_status_timeout(struct wlan_objmgr_pdev *pdev, + int *status_timeout) +{ + struct wlan_dfs *dfs; + + dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); + return QDF_STATUS_E_FAILURE; + } + + dfs_get_override_status_timeout(dfs, status_timeout); + + return QDF_STATUS_SUCCESS; +} + +qdf_export_symbol(ucfg_dfs_get_override_status_timeout); +#endif From 8785b9dd692a00552f3155c899e866485959c829 Mon Sep 17 00:00:00 2001 From: Vignesh U Date: Fri, 20 Apr 2018 22:01:25 +0530 Subject: [PATCH 6/7] qcacmn: Process host DFS confirmation status from firmware Process firmware status event on radar found and take necessary actions. Change-Id: I7ddb2b1a45e97a4ea52eb9b2d718f467726aad04 CRs-Fixed: 2211883 --- umac/dfs/core/src/dfs.h | 33 +++++++ umac/dfs/core/src/dfs_partial_offload_radar.h | 59 ++++++++++- .../core/src/dfs_process_radar_found_ind.h | 12 +++ .../src/filtering/dfs_partial_offload_radar.c | 98 +++++++++++++++++++ .../core/src/filtering/dfs_process_phyerr.c | 5 + umac/dfs/core/src/misc/dfs_nol.c | 30 ++++++ .../src/misc/dfs_process_radar_found_ind.c | 6 +- umac/dfs/dispatcher/inc/wlan_dfs_lmac_api.h | 16 +++ umac/dfs/dispatcher/inc/wlan_dfs_mlme_api.h | 36 ++++++- umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h | 42 ++++++++ umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h | 9 ++ umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h | 18 ++++ .../dispatcher/src/wlan_dfs_init_deinit_api.c | 4 + umac/dfs/dispatcher/src/wlan_dfs_lmac_api.c | 17 ++++ umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c | 22 +++++ umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c | 51 ++++++++++ umac/dfs/dispatcher/src/wlan_dfs_utils_api.c | 20 ++++ 17 files changed, 473 insertions(+), 5 deletions(-) diff --git a/umac/dfs/core/src/dfs.h b/umac/dfs/core/src/dfs.h index 1f7d294b524d..4d387538d715 100644 --- a/umac/dfs/core/src/dfs.h +++ b/umac/dfs/core/src/dfs.h @@ -1118,6 +1118,24 @@ enum { WLAN_DEBUG_DFS_ALWAYS = WLAN_DEBUG_DFS_MAX }; +/** + * enum host dfs spoof check status. + * @HOST_DFS_CHECK_PASSED: Host indicates RADAR detected and the FW + * confirms it to be spoof radar to host. + * @HOST_DFS_CHECK_FAILED: Host doesn't indicate RADAR detected or spoof + * radar parameters by + * WMI_HOST_DFS_RADAR_FOUND_CMDID doesn't match. + * @HOST_DFS_STATUS_CHECK_HW_RADAR: Host indicates RADAR detected and the + * FW confirms it to be real HW radar to host. + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +enum { + HOST_DFS_STATUS_CHECK_PASSED = 0, + HOST_DFS_STATUS_CHECK_FAILED = 1, + HOST_DFS_STATUS_CHECK_HW_RADAR = 2 +}; +#endif + /** * struct dfs_phy_err - DFS phy error. * @fulltsf: 64-bit TSF as read from MAC. @@ -1617,6 +1635,21 @@ void dfs_reset_ar(struct wlan_dfs *dfs); */ void dfs_reset_arq(struct wlan_dfs *dfs); +/** + * dfs_is_radar_enabled() - check if radar detection is enabled. + * @dfs: Pointer to wlan_dfs structure. + * @ignore_dfs: if 1 then radar detection is disabled.. + */ +#if defined(WLAN_DFS_DIRECT_ATTACH) || defined(WLAN_DFS_PARTIAL_OFFLOAD) +void dfs_is_radar_enabled(struct wlan_dfs *dfs, + int *ignore_dfs); +#else +static inline void dfs_is_radar_enabled(struct wlan_dfs *dfs, + int *ignore_dfs) +{ +} +#endif + /** * dfs_process_phyerr_bb_tlv() - Parses the PHY error and populates the * dfs_phy_err struct. diff --git a/umac/dfs/core/src/dfs_partial_offload_radar.h b/umac/dfs/core/src/dfs_partial_offload_radar.h index 6a03a2809361..012f4275cb7b 100644 --- a/umac/dfs/core/src/dfs_partial_offload_radar.h +++ b/umac/dfs/core/src/dfs_partial_offload_radar.h @@ -32,7 +32,7 @@ #if defined(WLAN_DFS_PARTIAL_OFFLOAD) void dfs_get_po_radars(struct wlan_dfs *dfs); #else -static void dfs_get_po_radars(struct wlan_dfs *dfs) +static inline void dfs_get_po_radars(struct wlan_dfs *dfs) { } #endif @@ -123,4 +123,61 @@ static inline void dfs_radarfound_action_fcc(struct wlan_dfs *dfs, { } #endif + +/** + * dfs_host_wait_timer_reset() - Stop dfs host wait timer. + * @dfs: Pointer to wlan_dfs structure. + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +void dfs_host_wait_timer_reset(struct wlan_dfs *dfs); +#else +static inline void dfs_host_wait_timer_reset(struct wlan_dfs *dfs) +{ +} +#endif + +/** + * dfs_remove_spoof_channel_from_nol() - Remove the spoofed radar hit channel + * from NOL. + * @dfs: Pointer to wlan_dfs structure. + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +void dfs_remove_spoof_channel_from_nol(struct wlan_dfs *dfs); +#else +static inline void dfs_remove_spoof_channel_from_nol(struct wlan_dfs *dfs) +{ +} +#endif + +/** + * dfs_reset_spoof_test() - reset the spoof test variables. + * @dfs: Pointer to wlan_dfs structure. + * + * Return: None. + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +void dfs_reset_spoof_test(struct wlan_dfs *dfs); +#else +static inline void dfs_reset_spoof_test(struct wlan_dfs *dfs) +{ +} +#endif + +/** + * dfs_action_on_fw_radar_status_check() - The dfs action on host dfs + * confirmation by fw. + * @dfs: Pointer to wlan_dfs structure. + * @status: pointer to host dfs status. + * + * Return: None + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +void dfs_action_on_fw_radar_status_check(struct wlan_dfs *dfs, + uint32_t *status); +#else +static inline void dfs_action_on_fw_radar_status_check(struct wlan_dfs *dfs, + uint32_t *status) +{ +} +#endif #endif /* _DFS_PARTIAL_OFFLOAD_RADAR_H_ */ diff --git a/umac/dfs/core/src/dfs_process_radar_found_ind.h b/umac/dfs/core/src/dfs_process_radar_found_ind.h index b2346fee9406..d53f893984fb 100644 --- a/umac/dfs/core/src/dfs_process_radar_found_ind.h +++ b/umac/dfs/core/src/dfs_process_radar_found_ind.h @@ -132,3 +132,15 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, */ void dfs_radarfound_action_generic(struct wlan_dfs *dfs, uint8_t seg_id, int false_radar_found); + +/** + * dfs_get_bonding_channels() - Get bonding channels. + * @curchan: Pointer to dfs_channels to know width and primary channel. + * @segment_id: Segment id, useful for 80+80/160 MHz operating band. + * @channels: Pointer to save radar affected channels. + * + * Return: Number of channels. + */ +uint8_t dfs_get_bonding_channels(struct dfs_channel *curchan, + uint32_t segment_id, + uint8_t *channels); diff --git a/umac/dfs/core/src/filtering/dfs_partial_offload_radar.c b/umac/dfs/core/src/filtering/dfs_partial_offload_radar.c index 37696181e041..ba44f4955506 100644 --- a/umac/dfs/core/src/filtering/dfs_partial_offload_radar.c +++ b/umac/dfs/core/src/filtering/dfs_partial_offload_radar.c @@ -549,3 +549,101 @@ void dfs_radarfound_action_fcc(struct wlan_dfs *dfs, uint8_t seg_id, -1) ? HOST_DFS_STATUS_WAIT_TIMER_MS : dfs->dfs_status_timeout_override); } + +void dfs_host_wait_timer_reset(struct wlan_dfs *dfs) +{ + dfs->dfs_is_host_wait_running = 0; + qdf_timer_stop(&dfs->dfs_host_wait_timer); +} + +/** + * dfs_action_on_spoof_success() - DFS action on spoof test pass + * @dfs: Pointer to DFS object + */ +static void dfs_action_on_spoof_success(struct wlan_dfs *dfs) +{ + dfs->dfs_spoof_test_done = 1; + if (dfs->dfs_radar_found_chan.dfs_ch_freq == + dfs->dfs_curchan->dfs_ch_freq) { + dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, + "cac timer started for channel %d", + dfs->dfs_curchan->dfs_ch_ieee); + dfs_start_cac_timer(dfs); + } else{ + dfs_remove_spoof_channel_from_nol(dfs); + } +} + +void dfs_action_on_fw_radar_status_check(struct wlan_dfs *dfs, + uint32_t *status) +{ + struct wlan_objmgr_pdev *dfs_pdev; + int no_chans_avail = 0; + int error_flag = 0; + + dfs_host_wait_timer_reset(dfs); + dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "Host DFS status = %d", + *status); + + dfs_pdev = dfs->dfs_pdev_obj; + if (!dfs_pdev) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_pdev_obj is NULL"); + return; + } + + switch (*status) { + case HOST_DFS_STATUS_CHECK_PASSED: + if (dfs->dfs_average_params_sent) + dfs_action_on_spoof_success(dfs); + else + error_flag = 1; + break; + case HOST_DFS_STATUS_CHECK_FAILED: + dfs->dfs_spoof_check_failed = 1; + no_chans_avail = + dfs_mlme_rebuild_chan_list_with_non_dfs_channels(dfs_pdev); + dfs_mlme_restart_vaps_with_non_dfs_chan(dfs_pdev, + no_chans_avail); + break; + case HOST_DFS_STATUS_CHECK_HW_RADAR: + if (dfs->dfs_average_params_sent) { + if (dfs->dfs_radar_found_chan.dfs_ch_freq == + dfs->dfs_curchan->dfs_ch_freq) { + dfs_radarfound_action_generic( + dfs, + dfs->dfs_seg_id, + dfs->dfs_false_radar_found); + } else { + /* Else of this case, no action is needed as + * dfs_action would have been done at timer + * expiry itself. + */ + dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, + "DFS Action already taken"); + } + } else { + error_flag = 1; + } + break; + default: + dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, + "Status event mismatch:%d, Ignoring it", + *status); + } + + dfs->dfs_average_params_sent = 0; + qdf_mem_zero(&dfs->dfs_radar_found_chan, sizeof(struct dfs_channel)); + + if (error_flag == 1) { + dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, + "Received imroper response %d. Discarding it", + *status); + } +} + +void dfs_reset_spoof_test(struct wlan_dfs *dfs) +{ + dfs->dfs_spoof_test_done = 0; + dfs->dfs_spoof_check_failed = 0; +} +#endif diff --git a/umac/dfs/core/src/filtering/dfs_process_phyerr.c b/umac/dfs/core/src/filtering/dfs_process_phyerr.c index d5afc16935f0..5ea9e5454077 100644 --- a/umac/dfs/core/src/filtering/dfs_process_phyerr.c +++ b/umac/dfs/core/src/filtering/dfs_process_phyerr.c @@ -981,3 +981,8 @@ void dfs_process_phyerr_filter_offload(struct wlan_dfs *dfs, } } #endif + +void dfs_is_radar_enabled(struct wlan_dfs *dfs, int *ignore_dfs) +{ + *ignore_dfs = dfs->dfs_ignore_dfs; +} diff --git a/umac/dfs/core/src/misc/dfs_nol.c b/umac/dfs/core/src/misc/dfs_nol.c index a56c56b4110d..87b334b3092c 100644 --- a/umac/dfs/core/src/misc/dfs_nol.c +++ b/umac/dfs/core/src/misc/dfs_nol.c @@ -34,6 +34,10 @@ #include #include #include +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +#include "../dfs_process_radar_found_ind.h" +#include "../dfs_partial_offload_radar.h" +#endif /** * dfs_nol_timeout() - NOL timeout function. @@ -585,3 +589,29 @@ void dfs_clear_nolhistory(struct wlan_dfs *dfs) WLAN_CHAN_CLR_HISTORY_RADAR(c); } } + +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +void dfs_remove_spoof_channel_from_nol(struct wlan_dfs *dfs) +{ + struct dfs_nolelem *nol; + uint8_t channels[NUM_CHANNELS_160MHZ]; + int i, nchans = 0; + + nchans = dfs_get_bonding_channels(&dfs->dfs_radar_found_chan, 0, + channels); + + WLAN_DFSNOL_LOCK(dfs); + for (i = 0; i < nchans && i < NUM_CHANNELS_160MHZ; i++) { + nol = dfs->dfs_nol; + while (nol) { + if (nol->nol_freq == (uint16_t)utils_dfs_chan_to_freq( + channels[i])) { + OS_SET_TIMER(&nol->nol_timer, 0); + break; + } + nol = nol->nol_next; + } + } + WLAN_DFSNOL_UNLOCK(dfs); +} +#endif diff --git a/umac/dfs/core/src/misc/dfs_process_radar_found_ind.c b/umac/dfs/core/src/misc/dfs_process_radar_found_ind.c index af8155f6e5f3..8819305e95fd 100644 --- a/umac/dfs/core/src/misc/dfs_process_radar_found_ind.c +++ b/umac/dfs/core/src/misc/dfs_process_radar_found_ind.c @@ -366,9 +366,9 @@ static uint8_t dfs_find_radar_affected_subchans(struct wlan_dfs *dfs, * * Return: Number of channels. */ -static uint8_t dfs_get_bonding_channels(struct dfs_channel *curchan, - uint32_t segment_id, - uint8_t *channels) +uint8_t dfs_get_bonding_channels(struct dfs_channel *curchan, + uint32_t segment_id, + uint8_t *channels) { uint8_t center_chan; uint8_t nchannels = 0; diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_lmac_api.h b/umac/dfs/dispatcher/inc/wlan_dfs_lmac_api.h index d8a5ef916c57..38bbc22268e6 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_lmac_api.h +++ b/umac/dfs/dispatcher/inc/wlan_dfs_lmac_api.h @@ -116,4 +116,20 @@ uint32_t lmac_get_target_type(struct wlan_objmgr_pdev *pdev); uint32_t lmac_get_phymode_info(struct wlan_objmgr_pdev *pdev, uint32_t chan_mode); +/** + * lmac_is_host_dfs_check_support_enabled() - Check if Host DFS confirmation + * feature is supported. + * @pdev: Pointer to PDEV structure. + * + * Return: true, host dfs check supported, else false. + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +bool lmac_is_host_dfs_check_support_enabled(struct wlan_objmgr_pdev *pdev); +#else +static inline bool lmac_is_host_dfs_check_support_enabled( + struct wlan_objmgr_pdev *pdev) +{ + return false; +} +#endif #endif /* _WLAN_DFS_LMAC_API_H_ */ diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_mlme_api.h b/umac/dfs/dispatcher/inc/wlan_dfs_mlme_api.h index 750332f30a9f..ed81d676da36 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_mlme_api.h +++ b/umac/dfs/dispatcher/inc/wlan_dfs_mlme_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -221,4 +221,38 @@ int dfs_mlme_get_cac_timeout(struct wlan_objmgr_pdev *pdev, uint8_t dfs_ch_vhtop_ch_freq_seg2, uint64_t dfs_ch_flags); +/** + * dfs_mlme_rebuild_chan_list_with_non_dfs_channels() - Rebuild the channel list + * with only non DFS channels. + * @pdev: Pointer to DFS pdev object. + * + * return: On success return 1 or 0, else failure. + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +int dfs_mlme_rebuild_chan_list_with_non_dfs_channels( + struct wlan_objmgr_pdev *pdev); +#else +static inline int dfs_mlme_rebuild_chan_list_with_non_dfs_channels( + struct wlan_objmgr_pdev *pdev) +{ + return 0; +} +#endif + +/** + * dfs_mlme_restart_vaps_with_non_dfs_chan() - Restart vaps with non DFS + * channels + * @pdev: Pointer to DFS pdev object. + * @no_chans_avail: Indicates if no channel is available. + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +void dfs_mlme_restart_vaps_with_non_dfs_chan(struct wlan_objmgr_pdev *pdev, + int no_chans_avail); +#else +static inline +void dfs_mlme_restart_vaps_with_non_dfs_chan(struct wlan_objmgr_pdev *pdev, + int no_chans_avail) +{ +} +#endif #endif /* _WLAN_DFS_MLME_API_H_ */ diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h b/umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h index 80bcca44480c..04ce38338afb 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h +++ b/umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h @@ -298,4 +298,46 @@ tgt_dfs_send_avg_params_to_fw(struct wlan_objmgr_pdev *pdev, struct dfs_radar_found_params *params); #endif +/** + * tgt_dfs_action_on_status_from_fw() - trigger the action to be taken based on + * host dfs status received from fw. + * @pdev: Pointer to pdev object. + * @status: Pointer to the host dfs status received from fw. + * + * Return: QDF_STATUS + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +QDF_STATUS tgt_dfs_action_on_status_from_fw(struct wlan_objmgr_pdev *pdev, + uint32_t *status); +#else +static inline +QDF_STATUS tgt_dfs_action_on_status_from_fw(struct wlan_objmgr_pdev *pdev, + uint32_t *status) +{ + return QDF_STATUS_SUCCESS; +} +#endif + +/** + * tgt_dfs_is_radar_enabled() - checks if radar detection is enabled. + * @pdev: Pointer to pdev object. + * @ignore_dfs: Pointer to check the value. If 1, radar detection is disabled. + */ +void tgt_dfs_is_radar_enabled(struct wlan_objmgr_pdev *pdev, int *ignore_dfs); + +/** + * tgt_dfs_reset_spoof_test() - reset the dfs spoof check variables + * @pdev: Pointer to pdev object. + * + * Return: QDF_STATUS + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +QDF_STATUS tgt_dfs_reset_spoof_test(struct wlan_objmgr_pdev *pdev); +#else +static inline +QDF_STATUS tgt_dfs_reset_spoof_test(struct wlan_objmgr_pdev *pdev) +{ + return QDF_STATUS_SUCCESS; +} +#endif #endif /* _WLAN_DFS_TGT_API_H_ */ diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h b/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h index cf85d5aa8c6c..cbe70e933cbf 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h +++ b/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h @@ -52,6 +52,9 @@ * @mlme_nol_timeout_notification: NOL timeout notification. * @mlme_clist_update: Updates the channel list. * @mlme_get_cac_timeout: Gets the CAC timeout. + * @mlme_rebuild_chan_list_with_non_dfs_channel: Rebuild channels with non-dfs + * channels. + * @mlme_restart_vaps_with_non_dfs_chan: Restart vaps with non-dfs channel. */ struct dfs_to_mlme { QDF_STATUS (*pdev_component_obj_attach)(struct wlan_objmgr_pdev *pdev, @@ -128,6 +131,12 @@ struct dfs_to_mlme { uint8_t c_vhtop_ch_freq_seg2, uint64_t dfs_ch_flags, int *cac_timeout); +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) + QDF_STATUS (*mlme_rebuild_chan_list_with_non_dfs_channels) + (struct wlan_objmgr_pdev *pdev); + QDF_STATUS (*mlme_restart_vaps_with_non_dfs_chan) + (struct wlan_objmgr_pdev *pdev, int no_chans_avail); +#endif }; extern struct dfs_to_mlme global_dfs_to_mlme; diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h b/umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h index e36b7aa4b5f2..4171ab1cb5f7 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h +++ b/umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h @@ -452,4 +452,22 @@ int utils_get_dfsdomain(struct wlan_objmgr_pdev *pdev); */ uint16_t utils_dfs_get_cur_rd(struct wlan_objmgr_pdev *pdev); +/** + * utils_dfs_is_spoof_check_failed() - get spoof check status. + * @pdev: pdev ptr + * @is_spoof_check_failed: pointer containing the status. + * + * Return: QDF_STATUS. + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +QDF_STATUS utils_dfs_is_spoof_check_failed(struct wlan_objmgr_pdev *pdev, + bool *is_spoof_check_failed); +#else +static inline +QDF_STATUS utils_dfs_is_spoof_check_failed(struct wlan_objmgr_pdev *pdev, + bool *is_spoof_check_failed) +{ + return QDF_STATUS_SUCCESS; +} +#endif #endif /* _WLAN_DFS_UTILS_API_H_ */ diff --git a/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c b/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c index 449630b5a868..7203b873e96c 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c @@ -80,6 +80,10 @@ void register_dfs_callbacks(void) mlme_dfs_nol_timeout_notification; tmp_dfs_to_mlme->mlme_clist_update = mlme_dfs_clist_update; tmp_dfs_to_mlme->mlme_get_cac_timeout = mlme_dfs_get_cac_timeout; + tmp_dfs_to_mlme->mlme_rebuild_chan_list_with_non_dfs_channels = + mlme_dfs_rebuild_chan_list_with_non_dfs_channels; + tmp_dfs_to_mlme->mlme_restart_vaps_with_non_dfs_chan = + mlme_dfs_restart_vaps_with_non_dfs_chan; } #else void register_dfs_callbacks(void) diff --git a/umac/dfs/dispatcher/src/wlan_dfs_lmac_api.c b/umac/dfs/dispatcher/src/wlan_dfs_lmac_api.c index 63f78ea8c179..58b93b85b71e 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_lmac_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_lmac_api.c @@ -209,3 +209,20 @@ uint32_t lmac_get_phymode_info(struct wlan_objmgr_pdev *pdev, return mode_info; } + +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +bool lmac_is_host_dfs_check_support_enabled(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_objmgr_psoc *psoc; + struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops; + bool enabled = false; + + psoc = wlan_pdev_get_psoc(pdev); + dfs_tx_ops = &psoc->soc_cb.tx_ops.dfs_tx_ops; + + if (dfs_tx_ops->dfs_host_dfs_check_support) + dfs_tx_ops->dfs_host_dfs_check_support(pdev, &enabled); + + return enabled; +} +#endif diff --git a/umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c b/umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c index 2986ad92fe31..51bc004ead34 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c @@ -295,3 +295,25 @@ int dfs_mlme_get_cac_timeout(struct wlan_objmgr_pdev *pdev, return cac_timeout; } + +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +int dfs_mlme_rebuild_chan_list_with_non_dfs_channels( + struct wlan_objmgr_pdev *pdev) +{ + if (!global_dfs_to_mlme.mlme_rebuild_chan_list_with_non_dfs_channels) + return 1; + + return global_dfs_to_mlme.mlme_rebuild_chan_list_with_non_dfs_channels( + pdev); +} + +void dfs_mlme_restart_vaps_with_non_dfs_chan(struct wlan_objmgr_pdev *pdev, + int no_chans_avail) +{ + if (!global_dfs_to_mlme.mlme_restart_vaps_with_non_dfs_chan) + return; + + global_dfs_to_mlme.mlme_restart_vaps_with_non_dfs_chan(pdev, + no_chans_avail); +} +#endif diff --git a/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c b/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c index 561454163444..c8f9a7d1dab3 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c @@ -30,6 +30,7 @@ #include "../../core/src/dfs_zero_cac.h" #include "../../core/src/dfs_process_radar_found_ind.h" #include +#include "../../core/src/dfs_partial_offload_radar.h" struct wlan_lmac_if_dfs_tx_ops * wlan_psoc_get_dfs_txops(struct wlan_objmgr_psoc *psoc) @@ -106,6 +107,21 @@ QDF_STATUS tgt_dfs_radar_enable(struct wlan_objmgr_pdev *pdev, } qdf_export_symbol(tgt_dfs_radar_enable); +void tgt_dfs_is_radar_enabled(struct wlan_objmgr_pdev *pdev, int *ignore_dfs) +{ + struct wlan_dfs *dfs; + + dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return; + } + + dfs_is_radar_enabled(dfs, ignore_dfs); +} + +qdf_export_symbol(tgt_dfs_is_radar_enabled); + QDF_STATUS tgt_dfs_process_phyerr(struct wlan_objmgr_pdev *pdev, void *buf, uint16_t datalen, @@ -485,4 +501,39 @@ tgt_dfs_send_avg_params_to_fw(struct wlan_objmgr_pdev *pdev, } qdf_export_symbol(tgt_dfs_send_avg_params_to_fw); + +QDF_STATUS tgt_dfs_action_on_status_from_fw(struct wlan_objmgr_pdev *pdev, + uint32_t *status) +{ + struct wlan_dfs *dfs; + + dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return QDF_STATUS_E_FAILURE; + } + + dfs_action_on_fw_radar_status_check(dfs, status); + + return QDF_STATUS_SUCCESS; +} + +qdf_export_symbol(tgt_dfs_action_on_status_from_fw); + +QDF_STATUS tgt_dfs_reset_spoof_test(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_dfs *dfs; + + dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return QDF_STATUS_E_FAILURE; + } + + dfs_reset_spoof_test(dfs); + + return QDF_STATUS_SUCCESS; +} + +qdf_export_symbol(tgt_dfs_reset_spoof_test); #endif diff --git a/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c b/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c index 04fcfe2457e0..04bcd2f62910 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c @@ -889,3 +889,23 @@ uint16_t utils_dfs_get_cur_rd(struct wlan_objmgr_pdev *pdev) return cur_regdmn.regdmn_pair_id; } + +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +QDF_STATUS utils_dfs_is_spoof_check_failed(struct wlan_objmgr_pdev *pdev, + bool *is_spoof_check_failed) +{ + struct wlan_dfs *dfs; + + dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); + return QDF_STATUS_E_FAILURE; + } + + *is_spoof_check_failed = dfs->dfs_spoof_check_failed; + + return QDF_STATUS_SUCCESS; +} + +qdf_export_symbol(utils_dfs_is_spoof_check_failed); +#endif From 993a38474422b197e3dcf650f433310bf606bc06 Mon Sep 17 00:00:00 2001 From: Kiran Kumar Lokere Date: Mon, 14 May 2018 18:17:18 -0700 Subject: [PATCH 7/7] qcacmn: Define test config attribute to configure Tx beamformee Add new wifi test config command attribute to configure Tx beamformee support. Change-Id: Iddf91920c8424cb5f5681f2cc5f98d667ec1f6f4 CRs-Fixed: 2244889 --- os_if/linux/qca_vendor.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/os_if/linux/qca_vendor.h b/os_if/linux/qca_vendor.h index 9b76d144827d..ece4802dc3e6 100644 --- a/os_if/linux/qca_vendor.h +++ b/os_if/linux/qca_vendor.h @@ -5991,6 +5991,12 @@ enum qca_wlan_vendor_attr_wifi_test_config { */ QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF = 12, + /* 8-bit unsigned value to configure the tx beamformee. + * This attribute is used to configure the testbed device. + * 1 - enable, 0 - disable. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE = 13, + /* keep last */ QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_AFTER_LAST, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX =