1 /* 2 * Copyright (c) 2017-2018, 2020 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. 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 * This file defines the important dispatcher APIs pertinent to 22 * wifi positioning. 23 */ 24 #include <wlan_lmac_if_def.h> 25 #include "wifi_pos_utils_i.h" 26 #include "wifi_pos_api.h" 27 #include "wifi_pos_ucfg_i.h" 28 #include "wlan_ptt_sock_svc.h" 29 #ifndef CNSS_GENL 30 #include <wlan_objmgr_psoc_obj.h> 31 #include "wifi_pos_main_i.h" 32 #endif 33 34 #ifndef CNSS_GENL 35 QDF_STATUS ucfg_wifi_psoc_get_pdev_id_by_dev_name( 36 char *dev_name, uint8_t *pdev_id, 37 struct wlan_objmgr_psoc **psoc) 38 { 39 struct wlan_objmgr_psoc *tmp_psoc = wifi_pos_get_psoc(); 40 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc_obj; 41 42 if (!tmp_psoc) { 43 wifi_pos_err("psoc is null"); 44 return QDF_STATUS_E_NULL_VALUE; 45 } 46 47 wifi_pos_psoc_obj = wifi_pos_get_psoc_priv_obj(tmp_psoc); 48 if (!wifi_pos_psoc_obj) { 49 wifi_pos_err("wifi_pos_psoc_obj is null"); 50 return QDF_STATUS_E_NULL_VALUE; 51 } 52 53 if (!wifi_pos_psoc_obj->wifi_pos_get_pdev_id_by_dev_name) { 54 wifi_pos_err("wifi_pos_get_pdev_id_by_dev_name is null"); 55 return QDF_STATUS_E_NULL_VALUE; 56 } 57 58 return wifi_pos_psoc_obj->wifi_pos_get_pdev_id_by_dev_name( 59 dev_name, pdev_id, psoc); 60 } 61 62 #ifdef WLAN_RTT_MEASUREMENT_NOTIFICATION 63 QDF_STATUS ucfg_wifi_pos_measurement_request_notification( 64 struct wlan_objmgr_pdev *pdev, 65 struct wifi_pos_req_msg *req) 66 { 67 struct wlan_objmgr_psoc *psoc = wifi_pos_get_psoc(); 68 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc_obj; 69 struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops; 70 struct rtt_channel_info chinfo = {0}; 71 72 if (!psoc) { 73 wifi_pos_err("psoc is null"); 74 return QDF_STATUS_E_NULL_VALUE; 75 } 76 77 wifi_pos_psoc_obj = wifi_pos_get_psoc_priv_obj(psoc); 78 if (!wifi_pos_psoc_obj) { 79 wifi_pos_err("wifi_pos_psoc_obj is null"); 80 return QDF_STATUS_E_NULL_VALUE; 81 } 82 83 if (!wifi_pos_psoc_obj->wifi_pos_measurement_request_notification) { 84 wifi_pos_debug("wifi_pos_measurement_request_notification is not registered"); 85 return QDF_STATUS_SUCCESS; 86 } 87 88 tx_ops = wifi_pos_get_tx_ops(psoc); 89 if (!tx_ops) { 90 wifi_pos_err("tx_ops null"); 91 return QDF_STATUS_E_NULL_VALUE; 92 } 93 94 if (!tx_ops->wifi_pos_parse_measreq_chan_info) { 95 wifi_pos_err("wifi_pos_parse_measreq_chan_info is null"); 96 return QDF_STATUS_E_NULL_VALUE; 97 } 98 99 tx_ops->wifi_pos_parse_measreq_chan_info(pdev, req->buf_len, req->buf, 100 &chinfo); 101 if (!chinfo.freq) { 102 wifi_pos_debug("Not a measurement request buffer, proceed"); 103 return QDF_STATUS_SUCCESS; 104 } 105 106 return wifi_pos_psoc_obj->wifi_pos_measurement_request_notification( 107 pdev, &chinfo); 108 } 109 #endif /* WLAN_RTT_MEASUREMENT_NOTIFICATION */ 110 #endif 111 112 QDF_STATUS ucfg_wifi_pos_process_req(struct wlan_objmgr_psoc *psoc, 113 struct wifi_pos_req_msg *req, 114 wifi_pos_send_rsp_handler send_rsp_cb) 115 { 116 uint8_t err; 117 uint32_t app_pid; 118 bool is_app_registered; 119 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc_obj; 120 121 wifi_pos_debug("enter"); 122 123 wifi_pos_psoc_obj = wifi_pos_get_psoc_priv_obj(wifi_pos_get_psoc()); 124 if (!wifi_pos_psoc_obj) { 125 wifi_pos_err("wifi_pos_psoc_obj is null"); 126 return QDF_STATUS_E_NULL_VALUE; 127 } 128 129 qdf_spin_lock_bh(&wifi_pos_psoc_obj->wifi_pos_lock); 130 wifi_pos_psoc_obj->wifi_pos_send_rsp = send_rsp_cb; 131 is_app_registered = wifi_pos_psoc_obj->is_app_registered; 132 app_pid = wifi_pos_psoc_obj->app_pid; 133 wifi_pos_psoc_obj->rsp_version = req->rsp_version; 134 qdf_spin_unlock_bh(&wifi_pos_psoc_obj->wifi_pos_lock); 135 136 if (!wifi_pos_psoc_obj->wifi_pos_req_handler) { 137 wifi_pos_err("wifi_pos_psoc_obj->wifi_pos_req_handler is null"); 138 err = OEM_ERR_NULL_CONTEXT; 139 send_rsp_cb(psoc, app_pid, WIFI_POS_CMD_ERROR, sizeof(err), 140 &err); 141 return QDF_STATUS_E_NULL_VALUE; 142 } 143 144 if (req->msg_type != WIFI_POS_CMD_REGISTRATION && 145 (!is_app_registered || app_pid != req->pid)) { 146 wifi_pos_err("requesting app is not registered, app_registered: %d, requesting pid: %d, stored pid: %d", 147 is_app_registered, req->pid, app_pid); 148 err = OEM_ERR_APP_NOT_REGISTERED; 149 send_rsp_cb(psoc, app_pid, WIFI_POS_CMD_ERROR, sizeof(err), 150 &err); 151 return QDF_STATUS_E_INVAL; 152 } 153 154 return wifi_pos_psoc_obj->wifi_pos_req_handler(psoc, req); 155 } 156 157 158 uint32_t ucfg_wifi_pos_get_ftm_cap(struct wlan_objmgr_psoc *psoc) 159 { 160 uint32_t val = 0; 161 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 162 wifi_pos_get_psoc_priv_obj(psoc); 163 164 if (!wifi_pos_psoc) { 165 wifi_pos_alert("unable to get wifi_pos psoc obj"); 166 return val; 167 } 168 169 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 170 val = wifi_pos_psoc->fine_time_meas_cap; 171 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 172 173 return val; 174 } 175 176 void ucfg_wifi_pos_set_ftm_cap(struct wlan_objmgr_psoc *psoc, uint32_t val) 177 { 178 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 179 wifi_pos_get_psoc_priv_obj(psoc); 180 181 if (!wifi_pos_psoc) { 182 wifi_pos_alert("unable to get wifi_pos psoc obj"); 183 return; 184 } 185 186 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 187 wifi_pos_psoc->fine_time_meas_cap = val; 188 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 189 } 190 191 void ucfg_wifi_pos_set_oem_6g_supported(struct wlan_objmgr_psoc *psoc, 192 bool val) 193 { 194 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 195 wifi_pos_get_psoc_priv_obj(psoc); 196 if (!wifi_pos_psoc) { 197 wifi_pos_alert("unable to get wifi_pos psoc obj"); 198 return; 199 } 200 201 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 202 wifi_pos_psoc->oem_6g_support_disable = val; 203 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 204 } 205 206 bool ucfg_wifi_pos_is_nl_rsp(struct wlan_objmgr_psoc *psoc) 207 { 208 uint32_t val = 0; 209 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 210 wifi_pos_get_psoc_priv_obj(psoc); 211 212 if (!wifi_pos_psoc) { 213 wifi_pos_alert("unable to get wifi_pos psoc obj"); 214 return false; 215 } 216 217 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 218 val = wifi_pos_psoc->rsp_version; 219 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 220 221 if (val == WIFI_POS_RSP_V2_NL) 222 return true; 223 else 224 return false; 225 226 } 227 228