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