1 /* 2 * Copyright (c) 2016-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 #include "qdf_mem.h" 21 #include <qdf_module.h> 22 #include "wlan_lmac_if_def.h" 23 #include "wlan_lmac_if_api.h" 24 #include "wlan_mgmt_txrx_tgt_api.h" 25 #include "wlan_scan_tgt_api.h" 26 #include <wlan_reg_services_api.h> 27 #include <wlan_reg_ucfg_api.h> 28 #ifdef WLAN_ATF_ENABLE 29 #include "wlan_atf_tgt_api.h" 30 #endif 31 #ifdef WLAN_SA_API_ENABLE 32 #include "wlan_sa_api_tgt_api.h" 33 #endif 34 #ifdef WIFI_POS_CONVERGED 35 #include "target_if_wifi_pos.h" 36 #endif /* WIFI_POS_CONVERGED */ 37 #ifdef WLAN_FEATURE_NAN_CONVERGENCE 38 #include "target_if_nan.h" 39 #endif /* WLAN_FEATURE_NAN_CONVERGENCE */ 40 #include "wlan_reg_tgt_api.h" 41 #ifdef CONVERGED_P2P_ENABLE 42 #include "wlan_p2p_tgt_api.h" 43 #endif 44 #ifdef CONVERGED_TDLS_ENABLE 45 #include "wlan_tdls_tgt_api.h" 46 #endif 47 48 #ifdef WLAN_CONV_CRYPTO_SUPPORTED 49 #include "wlan_crypto_global_api.h" 50 #endif 51 #ifdef DFS_COMPONENT_ENABLE 52 #include <wlan_dfs_tgt_api.h> 53 #include <wlan_dfs_utils_api.h> 54 #endif 55 56 #ifdef WLAN_SUPPORT_GREEN_AP 57 #include <wlan_green_ap_api.h> 58 #include <wlan_green_ap_ucfg_api.h> 59 #endif 60 #include <wlan_ftm_ucfg_api.h> 61 62 #ifdef WLAN_SUPPORT_FILS 63 #include <wlan_fd_tgt_api.h> 64 #endif 65 66 #ifdef QCA_SUPPORT_CP_STATS 67 #include <wlan_cp_stats_tgt_api.h> 68 #include <target_if_cp_stats.h> 69 #endif /* QCA_SUPPORT_CP_STATS */ 70 71 /* Function pointer for OL/WMA specific UMAC tx_ops 72 * registration. 73 */ 74 QDF_STATUS (*wlan_lmac_if_umac_tx_ops_register) 75 (struct wlan_lmac_if_tx_ops *tx_ops); 76 qdf_export_symbol(wlan_lmac_if_umac_tx_ops_register); 77 78 #ifdef QCA_SUPPORT_CP_STATS 79 /** 80 * wlan_lmac_if_cp_stats_rx_ops_register() - API to register cp stats Rx Ops 81 * @rx_ops: pointer to lmac rx ops 82 * 83 * This API will be used to register function pointers for FW events 84 * 85 * Return: void 86 */ 87 static void 88 wlan_lmac_if_cp_stats_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) 89 { 90 target_if_cp_stats_register_rx_ops(rx_ops); 91 } 92 #else 93 static void 94 wlan_lmac_if_cp_stats_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) 95 { 96 } 97 #endif /* QCA_SUPPORT_CP_STATS */ 98 99 #ifdef WLAN_ATF_ENABLE 100 /** 101 * wlan_lmac_if_atf_rx_ops_register() - Function to register ATF RX ops. 102 */ 103 static void 104 wlan_lmac_if_atf_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) 105 { 106 struct wlan_lmac_if_atf_rx_ops *atf_rx_ops = &rx_ops->atf_rx_ops; 107 108 /* ATF rx ops */ 109 atf_rx_ops->atf_get_atf_commit = tgt_atf_get_atf_commit; 110 atf_rx_ops->atf_get_fmcap = tgt_atf_get_fmcap; 111 atf_rx_ops->atf_get_obss_scale = tgt_atf_get_obss_scale; 112 atf_rx_ops->atf_get_mode = tgt_atf_get_mode; 113 atf_rx_ops->atf_get_msdu_desc = tgt_atf_get_msdu_desc; 114 atf_rx_ops->atf_get_max_vdevs = tgt_atf_get_max_vdevs; 115 atf_rx_ops->atf_get_peers = tgt_atf_get_peers; 116 atf_rx_ops->atf_get_tput_based = tgt_atf_get_tput_based; 117 atf_rx_ops->atf_get_logging = tgt_atf_get_logging; 118 atf_rx_ops->atf_get_txbuf_share = tgt_atf_get_txbuf_share; 119 atf_rx_ops->atf_get_txbuf_max = tgt_atf_get_txbuf_max; 120 atf_rx_ops->atf_get_txbuf_min = tgt_atf_get_txbuf_min; 121 atf_rx_ops->atf_get_ssidgroup = tgt_atf_get_ssidgroup; 122 atf_rx_ops->atf_get_tx_block_count = tgt_atf_get_tx_block_count; 123 atf_rx_ops->atf_get_peer_blk_txtraffic = tgt_atf_get_peer_blk_txtraffic; 124 atf_rx_ops->atf_get_vdev_blk_txtraffic = tgt_atf_get_vdev_blk_txtraffic; 125 atf_rx_ops->atf_get_sched = tgt_atf_get_sched; 126 atf_rx_ops->atf_get_tx_tokens = tgt_atf_get_tx_tokens; 127 atf_rx_ops->atf_get_shadow_tx_tokens = tgt_atf_get_shadow_tx_tokens; 128 atf_rx_ops->atf_get_shadow_alloted_tx_tokens = 129 tgt_atf_get_shadow_alloted_tx_tokens; 130 atf_rx_ops->atf_get_txtokens_common = tgt_atf_get_txtokens_common; 131 atf_rx_ops->atf_get_peer_stats = tgt_atf_get_peer_stats; 132 atf_rx_ops->atf_get_token_allocated = tgt_atf_get_token_allocated; 133 atf_rx_ops->atf_get_token_utilized = tgt_atf_get_token_utilized; 134 135 atf_rx_ops->atf_set_sched = tgt_atf_set_sched; 136 atf_rx_ops->atf_set_fmcap = tgt_atf_set_fmcap; 137 atf_rx_ops->atf_set_obss_scale = tgt_atf_set_obss_scale; 138 atf_rx_ops->atf_set_mode = tgt_atf_set_mode; 139 atf_rx_ops->atf_set_msdu_desc = tgt_atf_set_msdu_desc; 140 atf_rx_ops->atf_set_max_vdevs = tgt_atf_set_max_vdevs; 141 atf_rx_ops->atf_set_peers = tgt_atf_set_peers; 142 atf_rx_ops->atf_set_peer_stats = tgt_atf_set_peer_stats; 143 atf_rx_ops->atf_set_vdev_blk_txtraffic = tgt_atf_set_vdev_blk_txtraffic; 144 atf_rx_ops->atf_set_peer_blk_txtraffic = tgt_atf_set_peer_blk_txtraffic; 145 atf_rx_ops->atf_set_tx_block_count = tgt_atf_set_tx_block_count; 146 atf_rx_ops->atf_set_token_allocated = tgt_atf_set_token_allocated; 147 atf_rx_ops->atf_set_token_utilized = tgt_atf_set_token_utilized; 148 } 149 #else 150 static void 151 wlan_lmac_if_atf_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) 152 { 153 } 154 #endif 155 156 #ifdef WLAN_SUPPORT_FILS 157 static void 158 wlan_lmac_if_fd_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) 159 { 160 struct wlan_lmac_if_fd_rx_ops *fd_rx_ops = &rx_ops->fd_rx_ops; 161 162 fd_rx_ops->fd_is_fils_enable = tgt_fd_is_fils_enable; 163 fd_rx_ops->fd_alloc = tgt_fd_alloc; 164 fd_rx_ops->fd_stop = tgt_fd_stop; 165 fd_rx_ops->fd_free = tgt_fd_free; 166 fd_rx_ops->fd_get_valid_fd_period = tgt_fd_get_valid_fd_period; 167 fd_rx_ops->fd_swfda_handler = tgt_fd_swfda_handler; 168 } 169 #else 170 static void 171 wlan_lmac_if_fd_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) 172 { 173 } 174 #endif 175 176 #ifdef WLAN_SA_API_ENABLE 177 /** 178 * wlan_lmac_if_sa_api_rx_ops_register() - Function to register SA_API RX ops. 179 */ 180 static void 181 wlan_lmac_if_sa_api_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) 182 { 183 struct wlan_lmac_if_sa_api_rx_ops *sa_api_rx_ops = &rx_ops->sa_api_rx_ops; 184 185 /* SA API rx ops */ 186 sa_api_rx_ops->sa_api_get_sa_supported = tgt_sa_api_get_sa_supported; 187 sa_api_rx_ops->sa_api_get_validate_sw = tgt_sa_api_get_validate_sw; 188 sa_api_rx_ops->sa_api_enable_sa = tgt_sa_api_enable_sa; 189 sa_api_rx_ops->sa_api_get_sa_enable = tgt_sa_api_get_sa_enable; 190 191 sa_api_rx_ops->sa_api_peer_assoc_hanldler = tgt_sa_api_peer_assoc_hanldler; 192 sa_api_rx_ops->sa_api_update_tx_feedback = tgt_sa_api_update_tx_feedback; 193 sa_api_rx_ops->sa_api_update_rx_feedback = tgt_sa_api_update_rx_feedback; 194 195 sa_api_rx_ops->sa_api_ucfg_set_param = tgt_sa_api_ucfg_set_param; 196 sa_api_rx_ops->sa_api_ucfg_get_param = tgt_sa_api_ucfg_get_param; 197 198 sa_api_rx_ops->sa_api_is_tx_feedback_enabled = tgt_sa_api_is_tx_feedback_enabled; 199 sa_api_rx_ops->sa_api_is_rx_feedback_enabled = tgt_sa_api_is_rx_feedback_enabled; 200 201 sa_api_rx_ops->sa_api_convert_rate_2g = tgt_sa_api_convert_rate_2g; 202 sa_api_rx_ops->sa_api_convert_rate_5g = tgt_sa_api_convert_rate_5g; 203 sa_api_rx_ops->sa_api_get_sa_mode = tgt_sa_api_get_sa_mode; 204 205 sa_api_rx_ops->sa_api_get_beacon_txantenna = tgt_sa_api_get_beacon_txantenna; 206 sa_api_rx_ops->sa_api_cwm_action = tgt_sa_api_cwm_action; 207 } 208 #else 209 static void 210 wlan_lmac_if_sa_api_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) 211 { 212 } 213 #endif 214 215 216 #ifdef WLAN_CONV_CRYPTO_SUPPORTED 217 static void 218 wlan_lmac_if_crypto_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) 219 { 220 wlan_crypto_register_crypto_rx_ops(&rx_ops->crypto_rx_ops); 221 } 222 #else 223 static void 224 wlan_lmac_if_crypto_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) 225 { 226 } 227 #endif 228 229 #ifdef WIFI_POS_CONVERGED 230 static void wlan_lmac_if_umac_rx_ops_register_wifi_pos( 231 struct wlan_lmac_if_rx_ops *rx_ops) 232 { 233 target_if_wifi_pos_register_rx_ops(rx_ops); 234 } 235 #else 236 static void wlan_lmac_if_umac_rx_ops_register_wifi_pos( 237 struct wlan_lmac_if_rx_ops *rx_ops) 238 { 239 } 240 #endif /* WIFI_POS_CONVERGED */ 241 242 #ifdef WLAN_FEATURE_NAN_CONVERGENCE 243 static void wlan_lmac_if_register_nan_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops) 244 { 245 target_if_nan_register_rx_ops(rx_ops); 246 } 247 #else 248 static void wlan_lmac_if_register_nan_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops) 249 { 250 } 251 #endif /* WLAN_FEATURE_NAN_CONVERGENCE */ 252 253 static void wlan_lmac_if_umac_reg_rx_ops_register( 254 struct wlan_lmac_if_rx_ops *rx_ops) 255 { 256 rx_ops->reg_rx_ops.master_list_handler = 257 tgt_reg_process_master_chan_list; 258 259 rx_ops->reg_rx_ops.reg_11d_new_cc_handler = 260 tgt_reg_process_11d_new_country; 261 262 rx_ops->reg_rx_ops.reg_set_regdb_offloaded = 263 tgt_reg_set_regdb_offloaded; 264 265 rx_ops->reg_rx_ops.reg_set_11d_offloaded = 266 tgt_reg_set_11d_offloaded; 267 268 rx_ops->reg_rx_ops.get_dfs_region = 269 wlan_reg_get_dfs_region; 270 271 rx_ops->reg_rx_ops.reg_ch_avoid_event_handler = 272 tgt_reg_process_ch_avoid_event; 273 274 rx_ops->reg_rx_ops.reg_freq_to_chan = 275 wlan_reg_freq_to_chan; 276 277 rx_ops->reg_rx_ops.reg_set_chan_144 = 278 ucfg_reg_modify_chan_144; 279 280 rx_ops->reg_rx_ops.reg_get_chan_144 = 281 ucfg_reg_get_en_chan_144; 282 283 rx_ops->reg_rx_ops.reg_program_default_cc = 284 ucfg_reg_program_default_cc; 285 286 rx_ops->reg_rx_ops.reg_get_current_regdomain = 287 wlan_reg_get_curr_regdomain; 288 } 289 290 #ifdef CONVERGED_P2P_ENABLE 291 static void wlan_lmac_if_umac_rx_ops_register_p2p( 292 struct wlan_lmac_if_rx_ops *rx_ops) 293 { 294 rx_ops->p2p.lo_ev_handler = tgt_p2p_lo_event_cb; 295 rx_ops->p2p.noa_ev_handler = tgt_p2p_noa_event_cb; 296 } 297 #else 298 static void wlan_lmac_if_umac_rx_ops_register_p2p( 299 struct wlan_lmac_if_rx_ops *rx_ops) 300 { 301 } 302 #endif 303 304 #ifdef DFS_COMPONENT_ENABLE 305 static QDF_STATUS 306 wlan_lmac_if_umac_dfs_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) 307 { 308 struct wlan_lmac_if_dfs_rx_ops *dfs_rx_ops; 309 310 dfs_rx_ops = &rx_ops->dfs_rx_ops; 311 312 dfs_rx_ops->dfs_get_radars = tgt_dfs_get_radars; 313 dfs_rx_ops->dfs_process_phyerr = tgt_dfs_process_phyerr; 314 dfs_rx_ops->dfs_destroy_object = tgt_dfs_destroy_object; 315 dfs_rx_ops->dfs_radar_enable = tgt_dfs_radar_enable; 316 dfs_rx_ops->dfs_control = tgt_dfs_control; 317 dfs_rx_ops->dfs_is_precac_timer_running = 318 tgt_dfs_is_precac_timer_running; 319 dfs_rx_ops->dfs_find_vht80_chan_for_precac = 320 tgt_dfs_find_vht80_chan_for_precac; 321 dfs_rx_ops->dfs_cancel_precac_timer = utils_dfs_cancel_precac_timer; 322 dfs_rx_ops->dfs_override_precac_timeout = 323 ucfg_dfs_override_precac_timeout; 324 dfs_rx_ops->dfs_set_precac_enable = ucfg_dfs_set_precac_enable; 325 dfs_rx_ops->dfs_get_precac_enable = ucfg_dfs_get_precac_enable; 326 dfs_rx_ops->dfs_get_override_precac_timeout = 327 ucfg_dfs_get_override_precac_timeout; 328 dfs_rx_ops->dfs_set_current_channel = tgt_dfs_set_current_channel; 329 dfs_rx_ops->dfs_process_radar_ind = tgt_dfs_process_radar_ind; 330 dfs_rx_ops->dfs_dfs_cac_complete_ind = tgt_dfs_cac_complete; 331 dfs_rx_ops->dfs_stop = tgt_dfs_stop; 332 dfs_rx_ops->dfs_process_phyerr_filter_offload = 333 tgt_dfs_process_phyerr_filter_offload; 334 dfs_rx_ops->dfs_is_phyerr_filter_offload = 335 tgt_dfs_is_phyerr_filter_offload; 336 337 return QDF_STATUS_SUCCESS; 338 } 339 #else 340 static QDF_STATUS 341 wlan_lmac_if_umac_dfs_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) 342 { 343 return QDF_STATUS_SUCCESS; 344 } 345 #endif 346 347 #ifdef CONVERGED_TDLS_ENABLE 348 static QDF_STATUS 349 wlan_lmac_if_umac_tdls_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) 350 { 351 rx_ops->tdls_rx_ops.tdls_ev_handler = tgt_tdls_event_handler; 352 353 return QDF_STATUS_SUCCESS; 354 } 355 #else 356 static QDF_STATUS 357 wlan_lmac_if_umac_tdls_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) 358 { 359 return QDF_STATUS_SUCCESS; 360 } 361 #endif 362 363 #ifdef WLAN_SUPPORT_GREEN_AP 364 static QDF_STATUS 365 wlan_lmac_if_umac_green_ap_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) 366 { 367 rx_ops->green_ap_rx_ops.is_ps_enabled = wlan_green_ap_is_ps_enabled; 368 rx_ops->green_ap_rx_ops.is_dbg_print_enabled = 369 ucfg_green_ap_get_debug_prints; 370 rx_ops->green_ap_rx_ops.ps_set = ucfg_green_ap_set_ps_config; 371 rx_ops->green_ap_rx_ops.ps_get = ucfg_green_ap_get_ps_config; 372 rx_ops->green_ap_rx_ops.suspend_handle = wlan_green_ap_suspend_handle; 373 374 return QDF_STATUS_SUCCESS; 375 } 376 #else 377 static QDF_STATUS 378 wlan_lmac_if_umac_green_ap_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) 379 { 380 return QDF_STATUS_SUCCESS; 381 } 382 #endif 383 384 static QDF_STATUS 385 wlan_lmac_if_umac_ftm_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) 386 { 387 struct wlan_lmac_if_ftm_rx_ops *ftm_rx_ops; 388 389 ftm_rx_ops = &rx_ops->ftm_rx_ops; 390 391 ftm_rx_ops->ftm_ev_handler = wlan_ftm_process_utf_event; 392 393 return QDF_STATUS_SUCCESS; 394 } 395 396 /** 397 * wlan_lmac_if_umac_rx_ops_register() - UMAC rx handler register 398 * @rx_ops: Pointer to rx_ops structure to be populated 399 * 400 * Register umac RX callabacks which will be called by DA/OL/WMA/WMI 401 * 402 * Return: QDF_STATUS_SUCCESS - in case of success 403 */ 404 QDF_STATUS 405 wlan_lmac_if_umac_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) 406 { 407 /* Component specific public api's to be called to register 408 * respective callbacks 409 * Ex: rx_ops->fp = function; 410 */ 411 struct wlan_lmac_if_mgmt_txrx_rx_ops *mgmt_txrx_rx_ops; 412 413 if (!rx_ops) { 414 qdf_print("%s: lmac if rx ops pointer is NULL", __func__); 415 return QDF_STATUS_E_INVAL; 416 } 417 418 /* mgmt txrx rx ops */ 419 mgmt_txrx_rx_ops = &rx_ops->mgmt_txrx_rx_ops; 420 421 mgmt_txrx_rx_ops->mgmt_tx_completion_handler = 422 tgt_mgmt_txrx_tx_completion_handler; 423 mgmt_txrx_rx_ops->mgmt_rx_frame_handler = 424 tgt_mgmt_txrx_rx_frame_handler; 425 mgmt_txrx_rx_ops->mgmt_txrx_get_nbuf_from_desc_id = 426 tgt_mgmt_txrx_get_nbuf_from_desc_id; 427 mgmt_txrx_rx_ops->mgmt_txrx_get_peer_from_desc_id = 428 tgt_mgmt_txrx_get_peer_from_desc_id; 429 mgmt_txrx_rx_ops->mgmt_txrx_get_vdev_id_from_desc_id = 430 tgt_mgmt_txrx_get_vdev_id_from_desc_id; 431 mgmt_txrx_rx_ops->mgmt_txrx_get_free_desc_pool_count = 432 tgt_mgmt_txrx_get_free_desc_pool_count; 433 434 /* scan rx ops */ 435 rx_ops->scan.scan_ev_handler = tgt_scan_event_handler; 436 rx_ops->scan.scan_set_max_active_scans = tgt_scan_set_max_active_scans; 437 438 wlan_lmac_if_atf_rx_ops_register(rx_ops); 439 440 wlan_lmac_if_cp_stats_rx_ops_register(rx_ops); 441 442 wlan_lmac_if_sa_api_rx_ops_register(rx_ops); 443 444 wlan_lmac_if_crypto_rx_ops_register(rx_ops); 445 /* wifi_pos rx ops */ 446 wlan_lmac_if_umac_rx_ops_register_wifi_pos(rx_ops); 447 448 /* tdls rx ops */ 449 wlan_lmac_if_umac_tdls_rx_ops_register(rx_ops); 450 451 wlan_lmac_if_register_nan_rx_ops(rx_ops); 452 453 wlan_lmac_if_umac_reg_rx_ops_register(rx_ops); 454 455 /* p2p rx ops */ 456 wlan_lmac_if_umac_rx_ops_register_p2p(rx_ops); 457 458 /* DFS rx_ops */ 459 wlan_lmac_if_umac_dfs_rx_ops_register(rx_ops); 460 461 wlan_lmac_if_umac_green_ap_rx_ops_register(rx_ops); 462 463 /* FTM rx_ops */ 464 wlan_lmac_if_umac_ftm_rx_ops_register(rx_ops); 465 466 /* FILS Discovery */ 467 wlan_lmac_if_fd_rx_ops_register(rx_ops); 468 469 return QDF_STATUS_SUCCESS; 470 } 471 472 /** 473 * wlan_lmac_if_set_umac_txops_registration_cb() - tx registration 474 * callback assignment 475 * @dev_type: Dev type can be either Direct attach or Offload 476 * @handler: handler to be called for LMAC tx ops registration 477 * 478 * API to assign appropriate tx registration callback handler based on the 479 * device type(Offload or Direct attach) 480 * 481 * Return: QDF_STATUS_SUCCESS - in case of success 482 */ 483 QDF_STATUS wlan_lmac_if_set_umac_txops_registration_cb(QDF_STATUS (*handler) 484 (struct wlan_lmac_if_tx_ops *)) 485 { 486 wlan_lmac_if_umac_tx_ops_register = handler; 487 return QDF_STATUS_SUCCESS; 488 } 489 qdf_export_symbol(wlan_lmac_if_set_umac_txops_registration_cb); 490 491