1 /* 2 * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 /** 18 * DOC: Implements MLME global APIs 19 */ 20 21 #include <wlan_objmgr_cmn.h> 22 #include <include/wlan_mlme_cmn.h> 23 #include <include/wlan_pdev_mlme.h> 24 #include <include/wlan_vdev_mlme.h> 25 #include <include/wlan_mlme_cmn.h> 26 #include <wlan_psoc_mlme_main.h> 27 #include <wlan_pdev_mlme_main.h> 28 #include <wlan_vdev_mlme_main.h> 29 30 struct mlme_ext_ops *glbl_ops; 31 mlme_get_global_ops_cb glbl_ops_cb; 32 33 #ifdef FEATURE_CM_ENABLE 34 struct mlme_cm_ops *glbl_cm_ops; 35 osif_cm_get_global_ops_cb glbl_cm_ops_cb; 36 37 static void mlme_cm_ops_init(void) 38 { 39 if (glbl_cm_ops_cb) 40 glbl_cm_ops = glbl_cm_ops_cb(); 41 } 42 43 static void mlme_cm_ops_deinit(void) 44 { 45 if (glbl_cm_ops_cb) 46 glbl_cm_ops = NULL; 47 } 48 #else 49 static inline void mlme_cm_ops_init(void) 50 { 51 } 52 53 static inline void mlme_cm_ops_deinit(void) 54 { 55 } 56 #endif 57 58 QDF_STATUS wlan_cmn_mlme_init(void) 59 { 60 QDF_STATUS status; 61 62 status = wlan_psoc_mlme_init(); 63 if (status != QDF_STATUS_SUCCESS) 64 return status; 65 66 status = wlan_pdev_mlme_init(); 67 if (status != QDF_STATUS_SUCCESS) 68 return status; 69 70 status = wlan_vdev_mlme_init(); 71 if (status != QDF_STATUS_SUCCESS) 72 return status; 73 74 if (glbl_ops_cb) 75 glbl_ops = glbl_ops_cb(); 76 77 mlme_cm_ops_init(); 78 79 return QDF_STATUS_SUCCESS; 80 } 81 82 QDF_STATUS wlan_cmn_mlme_deinit(void) 83 { 84 QDF_STATUS status; 85 86 status = wlan_vdev_mlme_deinit(); 87 if (status != QDF_STATUS_SUCCESS) 88 return status; 89 90 status = wlan_pdev_mlme_deinit(); 91 if (status != QDF_STATUS_SUCCESS) 92 return status; 93 94 status = wlan_psoc_mlme_deinit(); 95 if (status != QDF_STATUS_SUCCESS) 96 return status; 97 98 mlme_cm_ops_deinit(); 99 100 return QDF_STATUS_SUCCESS; 101 } 102 103 QDF_STATUS mlme_psoc_ops_ext_hdl_create(struct psoc_mlme_obj *psoc_mlme) 104 { 105 QDF_STATUS ret = QDF_STATUS_SUCCESS; 106 107 if (glbl_ops && glbl_ops->mlme_psoc_ext_hdl_create) 108 ret = glbl_ops->mlme_psoc_ext_hdl_create(psoc_mlme); 109 110 return ret; 111 } 112 113 QDF_STATUS mlme_psoc_ops_ext_hdl_destroy(struct psoc_mlme_obj *psoc_mlme) 114 { 115 QDF_STATUS ret = QDF_STATUS_SUCCESS; 116 117 if (glbl_ops && glbl_ops->mlme_psoc_ext_hdl_destroy) 118 ret = glbl_ops->mlme_psoc_ext_hdl_destroy(psoc_mlme); 119 120 return ret; 121 } 122 123 QDF_STATUS mlme_pdev_ops_ext_hdl_create(struct pdev_mlme_obj *pdev_mlme) 124 { 125 QDF_STATUS ret = QDF_STATUS_SUCCESS; 126 127 if (glbl_ops && glbl_ops->mlme_pdev_ext_hdl_create) 128 ret = glbl_ops->mlme_pdev_ext_hdl_create(pdev_mlme); 129 130 return ret; 131 } 132 133 QDF_STATUS mlme_pdev_ops_ext_hdl_destroy(struct pdev_mlme_obj *pdev_mlme) 134 { 135 QDF_STATUS ret = QDF_STATUS_SUCCESS; 136 137 if (glbl_ops && glbl_ops->mlme_pdev_ext_hdl_destroy) 138 ret = glbl_ops->mlme_pdev_ext_hdl_destroy(pdev_mlme); 139 140 return ret; 141 } 142 143 QDF_STATUS mlme_vdev_ops_ext_hdl_create(struct vdev_mlme_obj *vdev_mlme) 144 { 145 QDF_STATUS ret = QDF_STATUS_SUCCESS; 146 147 if (glbl_ops && glbl_ops->mlme_vdev_ext_hdl_create) 148 ret = glbl_ops->mlme_vdev_ext_hdl_create(vdev_mlme); 149 150 return ret; 151 } 152 153 QDF_STATUS mlme_vdev_ops_ext_hdl_post_create(struct vdev_mlme_obj *vdev_mlme) 154 { 155 QDF_STATUS ret = QDF_STATUS_SUCCESS; 156 157 if (glbl_ops && glbl_ops->mlme_vdev_ext_hdl_post_create) 158 ret = glbl_ops->mlme_vdev_ext_hdl_post_create(vdev_mlme); 159 160 return ret; 161 } 162 163 QDF_STATUS mlme_vdev_ops_ext_hdl_destroy(struct vdev_mlme_obj *vdev_mlme) 164 { 165 QDF_STATUS ret = QDF_STATUS_SUCCESS; 166 167 if (glbl_ops && glbl_ops->mlme_vdev_ext_hdl_destroy) 168 ret = glbl_ops->mlme_vdev_ext_hdl_destroy(vdev_mlme); 169 170 return ret; 171 } 172 173 QDF_STATUS mlme_vdev_ops_start_fw_send(struct wlan_objmgr_vdev *vdev, 174 uint8_t restart) 175 { 176 QDF_STATUS ret = QDF_STATUS_SUCCESS; 177 178 if (glbl_ops && glbl_ops->mlme_vdev_start_fw_send) 179 ret = glbl_ops->mlme_vdev_start_fw_send(vdev, restart); 180 181 return ret; 182 } 183 184 QDF_STATUS mlme_vdev_ops_multivdev_restart_fw_cmd_send( 185 struct wlan_objmgr_pdev *pdev) 186 { 187 QDF_STATUS ret = QDF_STATUS_SUCCESS; 188 189 if (glbl_ops && glbl_ops->mlme_multivdev_restart_fw_send) 190 ret = glbl_ops->mlme_multivdev_restart_fw_send(pdev); 191 192 return ret; 193 } 194 195 QDF_STATUS mlme_vdev_ops_stop_fw_send(struct wlan_objmgr_vdev *vdev) 196 { 197 QDF_STATUS ret = QDF_STATUS_SUCCESS; 198 199 if (glbl_ops && glbl_ops->mlme_vdev_stop_fw_send) 200 ret = glbl_ops->mlme_vdev_stop_fw_send(vdev); 201 202 return ret; 203 } 204 205 QDF_STATUS mlme_vdev_ops_down_fw_send(struct wlan_objmgr_vdev *vdev) 206 { 207 QDF_STATUS ret = QDF_STATUS_SUCCESS; 208 209 if (glbl_ops && glbl_ops->mlme_vdev_down_fw_send) 210 ret = glbl_ops->mlme_vdev_down_fw_send(vdev); 211 212 return ret; 213 } 214 215 QDF_STATUS mlme_vdev_enqueue_exp_ser_cmd(struct vdev_mlme_obj *vdev_mlme, 216 uint8_t cmd_type) 217 { 218 QDF_STATUS ret = QDF_STATUS_SUCCESS; 219 220 if (glbl_ops && glbl_ops->mlme_vdev_enqueue_exp_cmd) 221 ret = glbl_ops->mlme_vdev_enqueue_exp_cmd(vdev_mlme, cmd_type); 222 223 return ret; 224 } 225 226 QDF_STATUS mlme_vdev_ops_ext_hdl_delete_rsp(struct wlan_objmgr_psoc *psoc, 227 struct vdev_delete_response *rsp) 228 { 229 QDF_STATUS ret = QDF_STATUS_SUCCESS; 230 231 if ((glbl_ops) && glbl_ops->mlme_vdev_ext_delete_rsp) 232 ret = glbl_ops->mlme_vdev_ext_delete_rsp(psoc, rsp); 233 234 return ret; 235 } 236 237 QDF_STATUS mlme_vdev_ops_ext_hdl_multivdev_restart_resp( 238 struct wlan_objmgr_psoc *psoc, 239 struct multi_vdev_restart_resp *resp) 240 { 241 QDF_STATUS ret = QDF_STATUS_SUCCESS; 242 243 if ((glbl_ops) && glbl_ops->mlme_multi_vdev_restart_resp) 244 ret = glbl_ops->mlme_multi_vdev_restart_resp(psoc, resp); 245 246 return ret; 247 } 248 249 #ifdef FEATURE_CM_ENABLE 250 QDF_STATUS mlme_cm_connect_start_ind(struct wlan_objmgr_vdev *vdev, 251 struct wlan_cm_connect_req *req) 252 { 253 QDF_STATUS ret = QDF_STATUS_SUCCESS; 254 255 if ((glbl_ops) && glbl_ops->mlme_cm_ext_connect_start_ind_cb) 256 ret = glbl_ops->mlme_cm_ext_connect_start_ind_cb(vdev, req); 257 258 return ret; 259 } 260 261 QDF_STATUS mlme_cm_bss_select_ind(struct wlan_objmgr_vdev *vdev, 262 struct wlan_cm_vdev_connect_req *req) 263 { 264 QDF_STATUS ret = QDF_STATUS_E_NOSUPPORT; 265 266 if ((glbl_ops) && glbl_ops->mlme_cm_ext_bss_select_ind_cb) 267 ret = glbl_ops->mlme_cm_ext_bss_select_ind_cb(vdev, req); 268 269 return ret; 270 } 271 272 QDF_STATUS mlme_cm_bss_peer_create_req(struct wlan_objmgr_vdev *vdev, 273 struct qdf_mac_addr *peer_mac) 274 { 275 QDF_STATUS ret = QDF_STATUS_SUCCESS; 276 277 if ((glbl_ops) && glbl_ops->mlme_cm_ext_bss_peer_create_req_cb) 278 ret = glbl_ops->mlme_cm_ext_bss_peer_create_req_cb(vdev, 279 peer_mac); 280 281 return ret; 282 } 283 284 QDF_STATUS mlme_cm_connect_req(struct wlan_objmgr_vdev *vdev, 285 struct wlan_cm_vdev_connect_req *req) 286 { 287 QDF_STATUS ret = QDF_STATUS_SUCCESS; 288 289 if ((glbl_ops) && glbl_ops->mlme_cm_ext_connect_req_cb) 290 ret = glbl_ops->mlme_cm_ext_connect_req_cb(vdev, req); 291 292 return ret; 293 } 294 295 QDF_STATUS mlme_cm_connect_complete_ind(struct wlan_objmgr_vdev *vdev, 296 struct wlan_cm_connect_resp *rsp) 297 { 298 QDF_STATUS ret = QDF_STATUS_SUCCESS; 299 300 if ((glbl_ops) && glbl_ops->mlme_cm_ext_connect_complete_ind_cb) 301 ret = glbl_ops->mlme_cm_ext_connect_complete_ind_cb(vdev, rsp); 302 303 return ret; 304 } 305 306 QDF_STATUS mlme_cm_disconnect_start_ind(struct wlan_objmgr_vdev *vdev, 307 struct wlan_cm_disconnect_req *req) 308 { 309 QDF_STATUS ret = QDF_STATUS_SUCCESS; 310 311 if ((glbl_ops) && glbl_ops->mlme_cm_ext_disconnect_start_ind_cb) 312 ret = glbl_ops->mlme_cm_ext_disconnect_start_ind_cb(vdev, req); 313 314 return ret; 315 } 316 317 QDF_STATUS mlme_cm_disconnect_req(struct wlan_objmgr_vdev *vdev, 318 struct wlan_cm_vdev_discon_req *req) 319 { 320 QDF_STATUS ret = QDF_STATUS_SUCCESS; 321 322 if ((glbl_ops) && glbl_ops->mlme_cm_ext_disconnect_req_cb) 323 ret = glbl_ops->mlme_cm_ext_disconnect_req_cb(vdev, req); 324 325 return ret; 326 } 327 328 QDF_STATUS mlme_cm_bss_peer_delete_req(struct wlan_objmgr_vdev *vdev) 329 { 330 QDF_STATUS ret = QDF_STATUS_SUCCESS; 331 332 if ((glbl_ops) && glbl_ops->mlme_cm_ext_bss_peer_delete_req_cb) 333 ret = glbl_ops->mlme_cm_ext_bss_peer_delete_req_cb(vdev); 334 335 return ret; 336 } 337 338 QDF_STATUS mlme_cm_disconnect_complete_ind(struct wlan_objmgr_vdev *vdev, 339 struct wlan_cm_discon_rsp *rsp) 340 { 341 QDF_STATUS ret = QDF_STATUS_SUCCESS; 342 343 if ((glbl_ops) && glbl_ops->mlme_cm_ext_disconnect_complete_ind_cb) 344 ret = glbl_ops->mlme_cm_ext_disconnect_complete_ind_cb(vdev, 345 rsp); 346 347 return ret; 348 } 349 350 QDF_STATUS mlme_cm_vdev_down_req(struct wlan_objmgr_vdev *vdev) 351 { 352 QDF_STATUS ret = QDF_STATUS_SUCCESS; 353 354 if ((glbl_ops) && glbl_ops->mlme_cm_ext_vdev_down_req_cb) 355 ret = glbl_ops->mlme_cm_ext_vdev_down_req_cb(vdev); 356 return ret; 357 } 358 359 QDF_STATUS mlme_cm_osif_connect_complete(struct wlan_objmgr_vdev *vdev, 360 struct wlan_cm_connect_resp *rsp) 361 { 362 QDF_STATUS ret = QDF_STATUS_SUCCESS; 363 364 if (glbl_cm_ops && glbl_cm_ops->mlme_cm_connect_complete_cb) 365 ret = glbl_cm_ops->mlme_cm_connect_complete_cb(vdev, rsp); 366 367 return ret; 368 } 369 370 QDF_STATUS 371 mlme_cm_osif_failed_candidate_ind(struct wlan_objmgr_vdev *vdev, 372 struct wlan_cm_connect_resp *rsp) 373 { 374 QDF_STATUS ret = QDF_STATUS_SUCCESS; 375 376 if (glbl_cm_ops && 377 glbl_cm_ops->mlme_cm_failed_candidate_cb) 378 ret = glbl_cm_ops->mlme_cm_failed_candidate_cb(vdev, rsp); 379 380 return ret; 381 } 382 383 QDF_STATUS mlme_cm_osif_update_id_and_src(struct wlan_objmgr_vdev *vdev, 384 enum wlan_cm_source source, 385 wlan_cm_id cm_id) 386 { 387 QDF_STATUS ret = QDF_STATUS_SUCCESS; 388 389 if (glbl_cm_ops && 390 glbl_cm_ops->mlme_cm_update_id_and_src_cb) 391 ret = glbl_cm_ops->mlme_cm_update_id_and_src_cb(vdev, source, 392 cm_id); 393 394 return ret; 395 } 396 397 QDF_STATUS mlme_cm_osif_disconnect_complete(struct wlan_objmgr_vdev *vdev, 398 struct wlan_cm_discon_rsp *rsp) 399 { 400 QDF_STATUS ret = QDF_STATUS_SUCCESS; 401 402 if (glbl_cm_ops && 403 glbl_cm_ops->mlme_cm_disconnect_complete_cb) 404 ret = glbl_cm_ops->mlme_cm_disconnect_complete_cb(vdev, rsp); 405 406 return ret; 407 } 408 409 QDF_STATUS mlme_cm_osif_disconnect_start_ind(struct wlan_objmgr_vdev *vdev) 410 { 411 QDF_STATUS ret = QDF_STATUS_SUCCESS; 412 413 if (glbl_cm_ops && 414 glbl_cm_ops->mlme_cm_disconnect_start_cb) 415 ret = glbl_cm_ops->mlme_cm_disconnect_start_cb(vdev); 416 417 return ret; 418 } 419 420 void mlme_set_osif_cm_cb(osif_cm_get_global_ops_cb osif_cm_ops) 421 { 422 glbl_cm_ops_cb = osif_cm_ops; 423 } 424 #endif 425 426 void mlme_set_ops_register_cb(mlme_get_global_ops_cb ops_cb) 427 { 428 glbl_ops_cb = ops_cb; 429 } 430