1 /* 2 * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * 6 * Permission to use, copy, modify, and/or distribute this software for 7 * any purpose with or without fee is hereby granted, provided that the 8 * above copyright notice and this permission notice appear in all 9 * copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 12 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 13 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 14 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 15 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 16 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 17 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 18 * PERFORMANCE OF THIS SOFTWARE. 19 */ 20 21 /** 22 * DOC: target_if_dfs_partial_offload.c 23 * This file contains dfs target interface for partial offload 24 */ 25 26 #include <target_if.h> 27 #include "target_type.h" 28 #include "target_if_dfs_partial_offload.h" 29 #include "target_if_dfs.h" 30 31 QDF_STATUS target_if_dfs_reg_phyerr_events(struct wlan_objmgr_psoc *psoc) 32 { 33 /* TODO: dfs non-offload case */ 34 return QDF_STATUS_SUCCESS; 35 } 36 37 QDF_STATUS target_if_dfs_get_caps(struct wlan_objmgr_pdev *pdev, 38 struct wlan_dfs_caps *dfs_caps) 39 { 40 struct wlan_objmgr_psoc *psoc = NULL; 41 struct target_psoc_info *tgt_psoc_info; 42 43 if (!dfs_caps) { 44 target_if_err("null dfs_caps"); 45 return QDF_STATUS_E_FAILURE; 46 } 47 48 dfs_caps->wlan_dfs_combined_rssi_ok = 0; 49 dfs_caps->wlan_dfs_ext_chan_ok = 0; 50 dfs_caps->wlan_dfs_use_enhancement = 0; 51 dfs_caps->wlan_strong_signal_diversiry = 0; 52 dfs_caps->wlan_fastdiv_val = 0; 53 dfs_caps->wlan_chip_is_bb_tlv = 1; 54 dfs_caps->wlan_chip_is_over_sampled = 0; 55 dfs_caps->wlan_chip_is_ht160 = 0; 56 dfs_caps->wlan_chip_is_false_detect = 0; 57 58 psoc = wlan_pdev_get_psoc(pdev); 59 if (!psoc) { 60 target_if_err("null psoc"); 61 return QDF_STATUS_E_FAILURE; 62 } 63 64 tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc); 65 if (!tgt_psoc_info) { 66 target_if_err("null tgt_psoc_info"); 67 return QDF_STATUS_E_FAILURE; 68 } 69 70 switch (target_psoc_get_target_type(tgt_psoc_info)) { 71 case TARGET_TYPE_AR900B: 72 break; 73 74 case TARGET_TYPE_AR9888: 75 dfs_caps->wlan_chip_is_over_sampled = 1; 76 break; 77 78 case TARGET_TYPE_QCA9984: 79 case TARGET_TYPE_QCA9888: 80 dfs_caps->wlan_chip_is_ht160 = 1; 81 break; 82 default: 83 break; 84 } 85 86 return QDF_STATUS_SUCCESS; 87 } 88 89 #if defined(HOST_DFS_SPOOF_TEST) 90 QDF_STATUS target_if_dfs_send_avg_params_to_fw( 91 struct wlan_objmgr_pdev *pdev, 92 struct dfs_radar_found_params *params) 93 { 94 QDF_STATUS status; 95 wmi_unified_t wmi_handle; 96 97 if (!pdev) { 98 target_if_err("null pdev"); 99 return QDF_STATUS_E_FAILURE; 100 } 101 102 wmi_handle = get_wmi_unified_hdl_from_pdev(pdev); 103 if (!wmi_handle) { 104 target_if_err("null wmi_handle"); 105 return QDF_STATUS_E_FAILURE; 106 } 107 108 status = wmi_unified_dfs_send_avg_params_cmd(wmi_handle, 109 params); 110 if (QDF_IS_STATUS_ERROR(status)) 111 target_if_err("dfs radar found average parameters send failed: %d", 112 status); 113 114 return status; 115 } 116 117 int target_if_dfs_status_check_event_handler(ol_scn_t scn, 118 uint8_t *data, 119 uint32_t datalen) 120 { 121 struct wlan_objmgr_psoc *psoc; 122 struct wlan_objmgr_pdev *pdev; 123 struct wlan_lmac_if_dfs_rx_ops *dfs_rx_ops; 124 u_int32_t dfs_status_check; 125 wmi_unified_t wmi_hdl; 126 127 if (!scn || !data) { 128 target_if_err("scn: %pK, data: %pK", scn, data); 129 return -EINVAL; 130 } 131 132 psoc = target_if_get_psoc_from_scn_hdl(scn); 133 if (!psoc) { 134 target_if_err("null psoc"); 135 return -EINVAL; 136 } 137 138 /* Since Partial Offload chipsets have only one pdev per psoc, the first 139 * pdev from the pdev list is used. 140 */ 141 pdev = wlan_objmgr_get_pdev_by_id(psoc, 0, WLAN_DFS_ID); 142 if (!pdev) { 143 target_if_err("null pdev"); 144 return -EINVAL; 145 } 146 147 dfs_rx_ops = target_if_dfs_get_rx_ops(psoc); 148 if (!dfs_rx_ops) { 149 target_if_err("null dfs_rx_ops"); 150 wlan_objmgr_pdev_release_ref(pdev, WLAN_DFS_ID); 151 return -EINVAL; 152 } 153 154 if (!dfs_rx_ops->dfs_action_on_status) { 155 target_if_err("dfs_rx_ops->dfs_action_on_status is NULL"); 156 wlan_objmgr_pdev_release_ref(pdev, WLAN_DFS_ID); 157 return -EINVAL; 158 } 159 160 wmi_hdl = get_wmi_unified_hdl_from_pdev(pdev); 161 if (!wmi_hdl) { 162 target_if_err("wmi_hdl is NULL"); 163 wlan_objmgr_pdev_release_ref(pdev, WLAN_DFS_ID); 164 return -EINVAL; 165 } 166 167 if (wmi_extract_dfs_status_from_fw(wmi_hdl, data, &dfs_status_check) != 168 QDF_STATUS_SUCCESS) { 169 target_if_err("failed to extract status response from FW"); 170 wlan_objmgr_pdev_release_ref(pdev, WLAN_DFS_ID); 171 return -EINVAL; 172 } 173 174 if (dfs_rx_ops->dfs_action_on_status(pdev, &dfs_status_check) != 175 QDF_STATUS_SUCCESS) { 176 target_if_err("dfs action on host dfs status from FW failed"); 177 wlan_objmgr_pdev_release_ref(pdev, WLAN_DFS_ID); 178 return -EINVAL; 179 } 180 181 wlan_objmgr_pdev_release_ref(pdev, WLAN_DFS_ID); 182 183 return 0; 184 } 185 #endif 186