1 /* 2 * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2022 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 * DOC: target_if_wifi_pos_tx_ops.c 22 * This file defines the functions pertinent to wifi positioning component's 23 * target if layer TX operations. 24 */ 25 #include "wifi_pos_utils_pub.h" 26 27 #include "wmi_unified_api.h" 28 #include "wlan_lmac_if_def.h" 29 #include "target_if_wifi_pos.h" 30 #include "target_if_wifi_pos_tx_ops.h" 31 #include "wifi_pos_utils_i.h" 32 #include "wifi_pos_api.h" 33 #include "wifi_pos_pasn_api.h" 34 #include "target_if.h" 35 36 /** 37 * target_if_wifi_pos_oem_data_req() - start OEM data request to target 38 * @psoc: pointer to psoc object mgr 39 * @req: start request params 40 * 41 * Return: QDF_STATUS 42 */ 43 static QDF_STATUS 44 target_if_wifi_pos_oem_data_req(struct wlan_objmgr_pdev *pdev, 45 struct oem_data_req *req) 46 { 47 QDF_STATUS status; 48 wmi_unified_t wmi_hdl = get_wmi_unified_hdl_from_pdev(pdev); 49 50 target_if_debug("Send oem data req to target"); 51 52 if (!req || !req->data) { 53 target_if_err("oem_data_req is null"); 54 return QDF_STATUS_E_INVAL; 55 } 56 57 if (!wmi_hdl) { 58 target_if_err("WMA closed, can't send oem data req cmd"); 59 return QDF_STATUS_E_INVAL; 60 } 61 62 status = wmi_unified_start_oem_data_cmd(wmi_hdl, req->data_len, 63 req->data); 64 65 if (!QDF_IS_STATUS_SUCCESS(status)) 66 target_if_err("wmi cmd send failed"); 67 68 return status; 69 } 70 71 #if !defined(CNSS_GENL) && defined(WLAN_RTT_MEASUREMENT_NOTIFICATION) 72 static QDF_STATUS 73 target_if_wifi_pos_parse_measreq_chan_info(struct wlan_objmgr_pdev *pdev, 74 uint32_t data_len, uint8_t *data, 75 struct rtt_channel_info *chinfo) 76 { 77 QDF_STATUS status; 78 wmi_unified_t wmi_hdl = get_wmi_unified_hdl_from_pdev(pdev); 79 80 if (!data) { 81 target_if_err("data is null"); 82 return QDF_STATUS_E_INVAL; 83 } 84 85 if (!wmi_hdl) { 86 target_if_err("wmi_hdl is null"); 87 return QDF_STATUS_E_INVAL; 88 } 89 90 status = wmi_unified_extract_measreq_chan_info(wmi_hdl, data_len, data, 91 chinfo); 92 if (!QDF_IS_STATUS_SUCCESS(status)) 93 target_if_err("wmi_unified_extract_measreq_chan_info failed"); 94 95 return status; 96 } 97 #else 98 static inline QDF_STATUS 99 target_if_wifi_pos_parse_measreq_chan_info(struct wlan_objmgr_pdev *pdev, 100 uint32_t data_len, uint8_t *data, 101 struct rtt_channel_info *chinfo) 102 { 103 return QDF_STATUS_E_NOSUPPORT; 104 } 105 #endif /* WLAN_RTT_MEASUREMENT_NOTIFICATION */ 106 107 #ifdef WLAN_FEATURE_RTT_11AZ_SUPPORT 108 static QDF_STATUS 109 target_if_wifi_pos_send_rtt_pasn_auth_status(struct wlan_objmgr_psoc *psoc, 110 struct wlan_pasn_auth_status *data) 111 { 112 QDF_STATUS status; 113 wmi_unified_t wmi = GET_WMI_HDL_FROM_PSOC(psoc); 114 115 if (!psoc || !wmi) { 116 target_if_err("%s is null", !psoc ? "psoc" : "wmi_handle"); 117 return QDF_STATUS_E_INVAL; 118 } 119 120 status = wmi_send_rtt_pasn_auth_status_cmd(wmi, data); 121 if (QDF_IS_STATUS_ERROR(status)) 122 target_if_err("send pasn auth status cmd failed"); 123 124 return status; 125 } 126 127 static QDF_STATUS 128 target_if_wifi_pos_send_rtt_pasn_deauth(struct wlan_objmgr_psoc *psoc, 129 struct qdf_mac_addr *peer_mac) 130 { 131 QDF_STATUS status; 132 wmi_unified_t wmi = GET_WMI_HDL_FROM_PSOC(psoc); 133 134 if (!psoc || !wmi) { 135 target_if_err("%s is null", !psoc ? "psoc" : "wmi_handle"); 136 return QDF_STATUS_E_INVAL; 137 } 138 139 status = wmi_send_rtt_pasn_deauth_cmd(wmi, peer_mac); 140 if (QDF_IS_STATUS_ERROR(status)) 141 target_if_err("send pasn deauth cmd failed"); 142 143 return status; 144 } 145 146 static void target_if_wifi_pos_register_11az_ops( 147 struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops) 148 { 149 tx_ops->send_rtt_pasn_auth_status = 150 target_if_wifi_pos_send_rtt_pasn_auth_status; 151 tx_ops->send_rtt_pasn_deauth = target_if_wifi_pos_send_rtt_pasn_deauth; 152 } 153 #else 154 static inline 155 void target_if_wifi_pos_register_11az_ops( 156 struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops) 157 {} 158 #endif 159 160 #ifdef WIFI_POS_CONVERGED 161 #ifdef WLAN_FEATURE_RTT_11AZ_SUPPORT 162 static QDF_STATUS 163 target_if_wifi_pos_register_11az_events(struct wlan_objmgr_psoc *psoc) 164 { 165 QDF_STATUS status = QDF_STATUS_SUCCESS; 166 167 status = wmi_unified_register_event_handler( 168 get_wmi_unified_hdl_from_psoc(psoc), 169 wmi_rtt_pasn_peer_create_req_eventid, 170 target_if_wifi_pos_pasn_peer_create_ev_handler, 171 WMI_RX_SERIALIZER_CTX); 172 if (QDF_IS_STATUS_ERROR(status)) { 173 target_if_err("register pasn peer create event_handler failed"); 174 return QDF_STATUS_E_INVAL; 175 } 176 177 status = wmi_unified_register_event_handler( 178 get_wmi_unified_hdl_from_psoc(psoc), 179 wmi_rtt_pasn_peer_delete_eventid, 180 target_if_wifi_pos_pasn_peer_delete_ev_handler, 181 WMI_RX_SERIALIZER_CTX); 182 if (QDF_IS_STATUS_ERROR(status)) { 183 target_if_err("register pasn peer delete event_handler failed"); 184 return status; 185 } 186 187 return status; 188 } 189 190 static void 191 target_if_wifi_pos_unregister_11az_events(struct wlan_objmgr_psoc *psoc) 192 { 193 if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) { 194 target_if_err("psoc or psoc->tgt_if_handle is null"); 195 return; 196 } 197 198 wmi_unified_unregister_event_handler( 199 get_wmi_unified_hdl_from_psoc(psoc), 200 wmi_rtt_pasn_peer_create_req_eventid); 201 202 wmi_unified_unregister_event_handler( 203 get_wmi_unified_hdl_from_psoc(psoc), 204 wmi_rtt_pasn_peer_delete_eventid); 205 } 206 #else 207 static QDF_STATUS 208 target_if_wifi_pos_register_11az_events(struct wlan_objmgr_psoc *psoc) 209 { 210 return QDF_STATUS_SUCCESS; 211 } 212 213 static void 214 target_if_wifi_pos_unregister_11az_events(struct wlan_objmgr_psoc *psoc) 215 {} 216 #endif /* WLAN_FEATURE_RTT_11AZ_SUPPORT */ 217 218 static 219 QDF_STATUS target_if_wifi_pos_register_events(struct wlan_objmgr_psoc *psoc) 220 { 221 QDF_STATUS ret; 222 223 if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) { 224 target_if_err("psoc or psoc->tgt_if_handle is null"); 225 return QDF_STATUS_E_INVAL; 226 } 227 228 /* wmi_oem_response_event_id is not defined for legacy targets. 229 * So do not check for error for this event. 230 */ 231 wmi_unified_register_event_handler( 232 get_wmi_unified_hdl_from_psoc(psoc), 233 wmi_oem_response_event_id, 234 target_if_wifi_pos_oem_rsp_ev_handler, 235 WMI_RX_WORK_CTX); 236 237 ret = wmi_unified_register_event_handler( 238 get_wmi_unified_hdl_from_psoc(psoc), 239 wmi_oem_cap_event_id, 240 wifi_pos_oem_cap_ev_handler, 241 WMI_RX_WORK_CTX); 242 if (QDF_IS_STATUS_ERROR(ret)) { 243 target_if_err("register_event_handler failed: err %d", ret); 244 return QDF_STATUS_E_INVAL; 245 } 246 247 ret = wmi_unified_register_event_handler( 248 get_wmi_unified_hdl_from_psoc(psoc), 249 wmi_oem_meas_report_event_id, 250 wifi_pos_oem_meas_rpt_ev_handler, 251 WMI_RX_WORK_CTX); 252 if (QDF_IS_STATUS_ERROR(ret)) { 253 target_if_err("register_event_handler failed: err %d", ret); 254 return QDF_STATUS_E_INVAL; 255 } 256 257 ret = wmi_unified_register_event_handler( 258 get_wmi_unified_hdl_from_psoc(psoc), 259 wmi_oem_report_event_id, 260 wifi_pos_oem_err_rpt_ev_handler, 261 WMI_RX_WORK_CTX); 262 if (QDF_IS_STATUS_ERROR(ret)) { 263 target_if_err("register_event_handler failed: err %d", ret); 264 return QDF_STATUS_E_INVAL; 265 } 266 267 target_if_wifi_pos_register_11az_events(psoc); 268 269 return QDF_STATUS_SUCCESS; 270 } 271 272 static 273 QDF_STATUS target_if_wifi_pos_deregister_events(struct wlan_objmgr_psoc *psoc) 274 { 275 if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) { 276 target_if_err("psoc or psoc->tgt_if_handle is null"); 277 return QDF_STATUS_E_INVAL; 278 } 279 280 wmi_unified_unregister_event_handler( 281 get_wmi_unified_hdl_from_psoc(psoc), 282 wmi_oem_response_event_id); 283 wmi_unified_unregister_event_handler( 284 get_wmi_unified_hdl_from_psoc(psoc), 285 wmi_oem_cap_event_id); 286 wmi_unified_unregister_event_handler( 287 get_wmi_unified_hdl_from_psoc(psoc), 288 wmi_oem_meas_report_event_id); 289 wmi_unified_unregister_event_handler( 290 get_wmi_unified_hdl_from_psoc(psoc), 291 wmi_oem_report_event_id); 292 target_if_wifi_pos_unregister_11az_events(psoc); 293 294 return QDF_STATUS_SUCCESS; 295 } 296 297 void target_if_wifi_pos_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) 298 { 299 struct wlan_lmac_if_wifi_pos_tx_ops *wifi_pos_tx_ops; 300 301 wifi_pos_tx_ops = &tx_ops->wifi_pos_tx_ops; 302 wifi_pos_tx_ops->wifi_pos_register_events = 303 target_if_wifi_pos_register_events; 304 wifi_pos_tx_ops->wifi_pos_deregister_events = 305 target_if_wifi_pos_deregister_events; 306 wifi_pos_tx_ops->data_req_tx = target_if_wifi_pos_oem_data_req; 307 wifi_pos_tx_ops->wifi_pos_convert_pdev_id_host_to_target = 308 target_if_wifi_pos_convert_pdev_id_host_to_target; 309 wifi_pos_tx_ops->wifi_pos_convert_pdev_id_target_to_host = 310 target_if_wifi_pos_convert_pdev_id_target_to_host; 311 wifi_pos_tx_ops->wifi_pos_get_vht_ch_width = 312 target_if_wifi_pos_get_vht_ch_width; 313 wifi_pos_tx_ops->data_req_tx = target_if_wifi_pos_oem_data_req; 314 wifi_pos_tx_ops->wifi_pos_parse_measreq_chan_info = 315 target_if_wifi_pos_parse_measreq_chan_info; 316 wifi_pos_tx_ops->wifi_pos_vdev_delete_all_ranging_peers_cb = 317 wifi_pos_vdev_delete_all_ranging_peers; 318 319 target_if_wifi_pos_register_11az_ops(wifi_pos_tx_ops); 320 } 321 #endif 322