123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629 |
- /*
- * Copyright (c) 2018 The Linux Foundation. All rights reserved.
- *
- * Permission to use, copy, modify, and/or distribute this software for
- * any purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
- * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
- /**
- * DOC: This file contains ocb north bound interface definitions
- */
- #include <scheduler_api.h>
- #include <wlan_defs.h>
- #include <wlan_reg_services_api.h>
- #include <wlan_objmgr_psoc_obj.h>
- #include <wlan_objmgr_global_obj.h>
- #include <wlan_ocb_public_structs.h>
- #include <wlan_ocb_ucfg_api.h>
- #include <wlan_ocb_tgt_api.h>
- #include <wlan_lmac_if_def.h>
- #include "wlan_ocb_main.h"
- /**
- * wlan_ocb_get_tx_ops() - get target interface tx operations
- * @pdev: pdev handle
- *
- * Return: fp to target interface operations
- */
- static struct wlan_ocb_tx_ops *
- wlan_ocb_get_tx_ops(struct wlan_objmgr_pdev *pdev)
- {
- struct ocb_pdev_obj *ocb_obj;
- ocb_obj = wlan_get_pdev_ocb_obj(pdev);
- if (!ocb_obj) {
- ocb_err("failed to get OCB pdev object");
- return NULL;
- }
- return &ocb_obj->ocb_txops;
- }
- QDF_STATUS ucfg_ocb_init(void)
- {
- QDF_STATUS status;
- ocb_notice("ocb module dispatcher init");
- status = wlan_objmgr_register_pdev_create_handler(WLAN_UMAC_COMP_OCB,
- ocb_pdev_obj_create_notification, NULL);
- if (QDF_IS_STATUS_ERROR(status)) {
- ocb_err("Failed to register pdev create handler for ocb");
- return status;
- }
- status = wlan_objmgr_register_pdev_destroy_handler(WLAN_UMAC_COMP_OCB,
- ocb_pdev_obj_destroy_notification, NULL);
- if (QDF_IS_STATUS_ERROR(status)) {
- ocb_err("Failed to register pdev destroy handler for ocb");
- goto fail_delete_pdev;
- }
- return status;
- fail_delete_pdev:
- wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_OCB,
- ocb_pdev_obj_create_notification, NULL);
- return status;
- }
- QDF_STATUS ucfg_ocb_deinit(void)
- {
- QDF_STATUS status;
- ocb_notice("ocb module dispatcher deinit");
- status = wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_OCB,
- ocb_pdev_obj_destroy_notification, NULL);
- if (QDF_IS_STATUS_ERROR(status))
- ocb_err("Failed to unregister pdev destroy handler");
- status = wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_OCB,
- ocb_pdev_obj_create_notification, NULL);
- if (QDF_IS_STATUS_ERROR(status))
- ocb_err("Failed to unregister pdev create handler");
- return status;
- }
- QDF_STATUS ocb_psoc_enable(struct wlan_objmgr_psoc *psoc)
- {
- struct wlan_objmgr_pdev *pdev;
- pdev = wlan_objmgr_get_pdev_by_id(psoc, 0,
- WLAN_OCB_NB_ID);
- if (!pdev) {
- ocb_err("Failed to get pdev handle");
- return QDF_STATUS_E_FAILURE;
- }
- tgt_ocb_register_ev_handler(pdev);
- wlan_objmgr_pdev_release_ref(pdev, WLAN_OCB_NB_ID);
- return QDF_STATUS_SUCCESS;
- }
- QDF_STATUS ocb_psoc_disable(struct wlan_objmgr_psoc *psoc)
- {
- struct wlan_objmgr_pdev *pdev;
- pdev = wlan_objmgr_get_pdev_by_id(psoc, 0,
- WLAN_OCB_NB_ID);
- if (!pdev) {
- ocb_err("Failed to get pdev handle");
- return QDF_STATUS_E_FAILURE;
- }
- tgt_ocb_unregister_ev_handler(pdev);
- wlan_objmgr_pdev_release_ref(pdev, WLAN_OCB_NB_ID);
- return QDF_STATUS_SUCCESS;
- }
- QDF_STATUS ucfg_ocb_set_txrx_handle(struct wlan_objmgr_psoc *psoc,
- void *txrx_handle)
- {
- struct wlan_objmgr_pdev *pdev;
- struct ocb_pdev_obj *ocb_obj;
- pdev = wlan_objmgr_get_pdev_by_id(psoc, 0,
- WLAN_OCB_NB_ID);
- if (!pdev) {
- ocb_err("Failed to get pdev handle");
- return QDF_STATUS_E_FAILURE;
- }
- ocb_obj = wlan_get_pdev_ocb_obj(pdev);
- wlan_objmgr_pdev_release_ref(pdev, WLAN_OCB_NB_ID);
- if (!ocb_obj) {
- ocb_err("OCB object is NULL");
- return QDF_STATUS_E_FAILURE;
- }
- ocb_obj->dp_pdev = txrx_handle;
- return QDF_STATUS_SUCCESS;
- }
- QDF_STATUS ucfg_ocb_update_dp_handle(struct wlan_objmgr_psoc *psoc,
- void *dp_soc)
- {
- struct wlan_objmgr_pdev *pdev;
- struct ocb_pdev_obj *ocb_obj;
- pdev = wlan_objmgr_get_pdev_by_id(psoc, 0,
- WLAN_OCB_NB_ID);
- if (!pdev) {
- ocb_err("Failed to get pdev handle");
- return QDF_STATUS_E_FAILURE;
- }
- ocb_obj = wlan_get_pdev_ocb_obj(pdev);
- wlan_objmgr_pdev_release_ref(pdev, WLAN_OCB_NB_ID);
- if (!ocb_obj) {
- ocb_err("OCB object is NULL");
- return QDF_STATUS_E_FAILURE;
- }
- ocb_obj->dp_soc = dp_soc;
- return QDF_STATUS_SUCCESS;
- }
- QDF_STATUS ucfg_ocb_config_channel(struct wlan_objmgr_pdev *pdev)
- {
- QDF_STATUS status;
- struct ocb_config *config;
- struct ocb_pdev_obj *ocb_obj;
- struct wlan_objmgr_psoc *psoc;
- struct wlan_ocb_tx_ops *tx_ops;
- ocb_obj = wlan_get_pdev_ocb_obj(pdev);
- if (!ocb_obj || !ocb_obj->channel_config) {
- ocb_alert("The request could not be found");
- return QDF_STATUS_E_FAILURE;
- }
- config = ocb_obj->channel_config;
- ocb_debug("Set config to vdev%d", config->vdev_id);
- psoc = wlan_pdev_get_psoc(pdev);
- if (!psoc) {
- ocb_err("Null pointer for psoc");
- return QDF_STATUS_E_INVAL;
- }
- tx_ops = wlan_ocb_get_tx_ops(pdev);
- if (tx_ops && tx_ops->ocb_set_config)
- status = tx_ops->ocb_set_config(psoc, ocb_obj->channel_config);
- else
- status = QDF_STATUS_E_IO;
- if (QDF_IS_STATUS_SUCCESS(status)) {
- ocb_debug("Set channel cmd is sent to southbound");
- } else {
- ocb_err("Failed to set channel config to southbound");
- if (ocb_obj->channel_config) {
- /*
- * On success case, backup parameters will be released
- * after channel info is synced to DP
- */
- ocb_info("release the backed config parameters");
- qdf_mem_free(ocb_obj->channel_config);
- ocb_obj->channel_config = NULL;
- }
- }
- return status;
- }
- QDF_STATUS ucfg_ocb_set_channel_config(struct wlan_objmgr_vdev *vdev,
- struct ocb_config *config,
- ocb_sync_callback set_config_cb,
- void *arg)
- {
- QDF_STATUS status;
- enum wlan_vdev_state state;
- uint32_t i;
- struct wlan_objmgr_pdev *pdev;
- struct wlan_objmgr_psoc *psoc;
- struct wlan_ocb_tx_ops *tx_ops;
- struct ocb_pdev_obj *ocb_obj;
- struct ocb_callbacks *ocb_cbs;
- pdev = wlan_vdev_get_pdev(vdev);
- if (!pdev) {
- ocb_err("Null pointer for pdev");
- return QDF_STATUS_E_INVAL;
- }
- ocb_obj = wlan_get_pdev_ocb_obj(pdev);
- if (!ocb_obj) {
- ocb_alert("Failed to get OCB vdev object");
- return QDF_STATUS_E_IO;
- }
- if (!config) {
- ocb_err("Invalid config input");
- return QDF_STATUS_E_FAILURE;
- }
- for (i = 0; i < config->channel_count; i++) {
- if (WLAN_REG_CHAN_TO_BAND(wlan_reg_freq_to_chan(pdev,
- config->channels[i].chan_freq))
- == BAND_2G)
- config->channels[i].ch_mode = MODE_11G;
- else
- config->channels[i].ch_mode = MODE_11A;
- }
- /*
- * backup the new configuration,
- * it will be released after target's response
- */
- ocb_obj->channel_config = ocb_copy_config(config);
- if (!ocb_obj->channel_config) {
- ocb_err("Failed to backup config");
- return QDF_STATUS_E_NOMEM;
- }
- ocb_cbs = &ocb_obj->ocb_cbs;
- ocb_cbs->ocb_set_config_callback = set_config_cb;
- ocb_cbs->ocb_set_config_context = arg;
- state = wlan_vdev_mlme_get_state(vdev);
- if (state != WLAN_VDEV_S_RUN) {
- /* Vdev is not started, start it */
- ocb_debug("OCB vdev%d is not up", config->vdev_id);
- status = ocb_vdev_start(ocb_obj);
- } else {
- psoc = wlan_vdev_get_psoc(vdev);
- tx_ops = wlan_ocb_get_tx_ops(pdev);
- if (tx_ops && tx_ops->ocb_set_config)
- status = tx_ops->ocb_set_config(psoc, config);
- else
- status = QDF_STATUS_E_IO;
- ocb_debug("Set config to vdev%d", config->vdev_id);
- if (QDF_IS_STATUS_SUCCESS(status))
- ocb_debug("Set channel cmd is sent to southbound");
- else
- ocb_err("Failed to set channel config to southbound");
- }
- if (QDF_IS_STATUS_ERROR(status) && ocb_obj->channel_config) {
- /*
- * On success case, backup parameters will be released
- * after channel info is synced to DP
- */
- ocb_info("release the backed config parameters");
- qdf_mem_free(ocb_obj->channel_config);
- ocb_obj->channel_config = NULL;
- }
- return status;
- }
- QDF_STATUS ucfg_ocb_set_utc_time(struct wlan_objmgr_vdev *vdev,
- struct ocb_utc_param *utc)
- {
- QDF_STATUS status;
- struct wlan_objmgr_psoc *psoc;
- struct wlan_objmgr_pdev *pdev;
- struct wlan_ocb_tx_ops *tx_ops;
- psoc = wlan_vdev_get_psoc(vdev);
- pdev = wlan_vdev_get_pdev(vdev);
- if (!psoc || !pdev) {
- ocb_err("Null pointer for psoc/pdev");
- return QDF_STATUS_E_INVAL;
- }
- tx_ops = wlan_ocb_get_tx_ops(pdev);
- if (!tx_ops) {
- ocb_alert("tx_ops is null");
- return QDF_STATUS_E_IO;
- }
- if (!tx_ops->ocb_set_utc_time) {
- ocb_alert("ocb_set_utc_time is null");
- return QDF_STATUS_E_IO;
- }
- status = tx_ops->ocb_set_utc_time(psoc, utc);
- if (QDF_IS_STATUS_ERROR(status))
- ocb_err("Failed to set UTC time to southbound");
- else
- ocb_debug("UTC time is sent to southbound");
- return status;
- }
- QDF_STATUS ucfg_ocb_start_timing_advert(struct wlan_objmgr_vdev *vdev,
- struct ocb_timing_advert_param *ta)
- {
- QDF_STATUS status;
- struct wlan_objmgr_psoc *psoc;
- struct wlan_objmgr_pdev *pdev;
- struct wlan_ocb_tx_ops *tx_ops;
- psoc = wlan_vdev_get_psoc(vdev);
- pdev = wlan_vdev_get_pdev(vdev);
- if (!psoc || !pdev) {
- ocb_err("Null pointer for psoc/pdev");
- return QDF_STATUS_E_INVAL;
- }
- tx_ops = wlan_ocb_get_tx_ops(pdev);
- if (!tx_ops) {
- ocb_alert("tx_ops is null");
- return QDF_STATUS_E_IO;
- }
- if (!tx_ops->ocb_start_timing_advert) {
- ocb_alert("ocb_start_timing_advert is null");
- return QDF_STATUS_E_IO;
- }
- status = tx_ops->ocb_start_timing_advert(psoc, ta);
- if (QDF_IS_STATUS_ERROR(status))
- ocb_err("Failed to sent start timing advert to southbound");
- else
- ocb_debug("Start timing advert is sent to southbound");
- return status;
- }
- QDF_STATUS ucfg_ocb_stop_timing_advert(struct wlan_objmgr_vdev *vdev,
- struct ocb_timing_advert_param *ta)
- {
- QDF_STATUS status;
- struct wlan_objmgr_psoc *psoc;
- struct wlan_objmgr_pdev *pdev;
- struct wlan_ocb_tx_ops *tx_ops;
- psoc = wlan_vdev_get_psoc(vdev);
- pdev = wlan_vdev_get_pdev(vdev);
- if (!psoc || !pdev) {
- ocb_err("Null pointer for psoc/pdev");
- return QDF_STATUS_E_INVAL;
- }
- tx_ops = wlan_ocb_get_tx_ops(pdev);
- if (!tx_ops) {
- ocb_alert("tx_ops is null");
- return QDF_STATUS_E_IO;
- }
- if (!tx_ops->ocb_stop_timing_advert) {
- ocb_alert("ocb_stop_timing_advert is null");
- return QDF_STATUS_E_IO;
- }
- status = tx_ops->ocb_stop_timing_advert(psoc, ta);
- if (QDF_IS_STATUS_ERROR(status))
- ocb_err("Failed to sent start timing advert to southbound");
- else
- ocb_debug("Start timing advert is sent to southbound");
- return status;
- }
- QDF_STATUS ucfg_ocb_get_tsf_timer(struct wlan_objmgr_vdev *vdev,
- struct ocb_get_tsf_timer_param *req,
- ocb_sync_callback get_tsf_cb,
- void *arg)
- {
- QDF_STATUS status;
- struct wlan_objmgr_psoc *psoc;
- struct ocb_get_tsf_timer_param request;
- struct wlan_ocb_tx_ops *tx_ops;
- struct ocb_callbacks *ocb_cbs;
- struct wlan_objmgr_pdev *pdev;
- pdev = wlan_vdev_get_pdev(vdev);
- if (!pdev) {
- ocb_err("Null pointer for pdev");
- return QDF_STATUS_E_INVAL;
- }
- tx_ops = wlan_ocb_get_tx_ops(pdev);
- if (!tx_ops) {
- ocb_alert("tx_ops is null");
- return QDF_STATUS_E_IO;
- }
- if (!tx_ops->ocb_get_tsf_timer) {
- ocb_alert("ocb_get_tsf_timer is null");
- return QDF_STATUS_E_IO;
- }
- ocb_cbs = wlan_ocb_get_callbacks(pdev);
- ocb_cbs->ocb_get_tsf_timer_context = arg;
- ocb_cbs->ocb_get_tsf_timer_callback = get_tsf_cb;
- request.vdev_id = req->vdev_id;
- psoc = wlan_vdev_get_psoc(vdev);
- if (!psoc) {
- ocb_err("Null pointer for psoc");
- return QDF_STATUS_E_INVAL;
- }
- status = tx_ops->ocb_get_tsf_timer(psoc, &request);
- if (QDF_IS_STATUS_ERROR(status))
- ocb_err("Failed to sent get tsf timer to southbound");
- else
- ocb_debug("Get tsf timer is sent to southbound");
- return status;
- }
- QDF_STATUS ucfg_ocb_dcc_get_stats(struct wlan_objmgr_vdev *vdev,
- struct ocb_dcc_get_stats_param *request,
- ocb_sync_callback dcc_get_stats_cb,
- void *arg)
- {
- QDF_STATUS status;
- struct wlan_objmgr_psoc *psoc;
- struct wlan_objmgr_pdev *pdev;
- struct ocb_callbacks *ocb_cbs;
- struct wlan_ocb_tx_ops *tx_ops;
- pdev = wlan_vdev_get_pdev(vdev);
- if (!pdev) {
- ocb_err("Null pointer for pdev");
- return QDF_STATUS_E_INVAL;
- }
- ocb_cbs = wlan_ocb_get_callbacks(pdev);
- ocb_cbs->ocb_dcc_get_stats_context = arg;
- ocb_cbs->ocb_dcc_get_stats_callback = dcc_get_stats_cb;
- tx_ops = wlan_ocb_get_tx_ops(pdev);
- if (!tx_ops) {
- ocb_alert("tx_ops is null");
- return QDF_STATUS_E_IO;
- }
- if (!tx_ops->ocb_dcc_get_stats) {
- ocb_alert("ocb_dcc_get_stats is null");
- return QDF_STATUS_E_IO;
- }
- psoc = wlan_vdev_get_psoc(vdev);
- if (!psoc) {
- ocb_err("Null pointer for psoc");
- return QDF_STATUS_E_INVAL;
- }
- status = tx_ops->ocb_dcc_get_stats(psoc, request);
- if (QDF_IS_STATUS_ERROR(status))
- ocb_err("Failed to sent get dcc stats to southbound");
- else
- ocb_debug("Get dcc stats is sent to southbound");
- return status;
- }
- QDF_STATUS ucfg_ocb_dcc_clear_stats(struct wlan_objmgr_vdev *vdev,
- uint16_t vdev_id,
- uint32_t bitmap)
- {
- QDF_STATUS status;
- struct wlan_objmgr_psoc *psoc;
- struct wlan_objmgr_pdev *pdev;
- struct wlan_ocb_tx_ops *tx_ops;
- struct ocb_dcc_clear_stats_param clear_stats_param;
- pdev = wlan_vdev_get_pdev(vdev);
- if (!pdev) {
- ocb_err("Null pointer for pdev");
- return QDF_STATUS_E_INVAL;
- }
- tx_ops = wlan_ocb_get_tx_ops(pdev);
- if (!tx_ops) {
- ocb_alert("tx_ops is null");
- return QDF_STATUS_E_IO;
- }
- if (!tx_ops->ocb_dcc_clear_stats) {
- ocb_alert("ocb_dcc_clear_stats is null");
- return QDF_STATUS_E_IO;
- }
- clear_stats_param.vdev_id = vdev_id;
- clear_stats_param.dcc_stats_bitmap = bitmap;
- psoc = wlan_vdev_get_psoc(vdev);
- if (!psoc) {
- ocb_err("Null pointer for psoc");
- return QDF_STATUS_E_INVAL;
- }
- status = tx_ops->ocb_dcc_clear_stats(psoc, &clear_stats_param);
- if (QDF_IS_STATUS_ERROR(status))
- ocb_err("Failed to sent clear dcc stats to southbound");
- else
- ocb_debug("clear dcc stats is sent to southbound");
- return status;
- }
- QDF_STATUS ucfg_ocb_dcc_update_ndl(struct wlan_objmgr_vdev *vdev,
- struct ocb_dcc_update_ndl_param *request,
- ocb_sync_callback dcc_update_ndl_cb,
- void *arg)
- {
- QDF_STATUS status;
- struct wlan_objmgr_psoc *psoc;
- struct ocb_callbacks *ocb_cbs;
- struct wlan_objmgr_pdev *pdev;
- struct wlan_ocb_tx_ops *tx_ops;
- pdev = wlan_vdev_get_pdev(vdev);
- if (!pdev) {
- ocb_err("Null pointer for pdev");
- return QDF_STATUS_E_INVAL;
- }
- ocb_cbs = wlan_ocb_get_callbacks(pdev);
- ocb_cbs->ocb_dcc_update_ndl_context = arg;
- ocb_cbs->ocb_dcc_update_ndl_callback = dcc_update_ndl_cb;
- tx_ops = wlan_ocb_get_tx_ops(pdev);
- if (!tx_ops) {
- ocb_alert("tx_ops is null");
- return QDF_STATUS_E_IO;
- }
- if (!tx_ops->ocb_dcc_update_ndl) {
- ocb_alert("dcc_update_ndl is null");
- return QDF_STATUS_E_IO;
- }
- psoc = wlan_vdev_get_psoc(vdev);
- if (!psoc) {
- ocb_err("Null pointer for psoc");
- return QDF_STATUS_E_INVAL;
- }
- status = tx_ops->ocb_dcc_update_ndl(psoc, request);
- if (QDF_IS_STATUS_ERROR(status))
- ocb_err("Failed to sent update ndl to southbound");
- else
- ocb_debug("Update ndl is sent to southbound");
- return status;
- }
- QDF_STATUS ucfg_ocb_register_for_dcc_stats_event(struct wlan_objmgr_pdev *pdev,
- void *ctx, ocb_sync_callback dcc_stats_cb)
- {
- struct ocb_callbacks *ocb_cbs;
- if (!pdev) {
- ocb_err("Null pointer for pdev");
- return QDF_STATUS_E_INVAL;
- }
- ocb_cbs = wlan_ocb_get_callbacks(pdev);
- if (!ocb_cbs) {
- ocb_err("Failed to register dcc stats callback");
- return QDF_STATUS_E_FAILURE;
- }
- ocb_cbs->ocb_dcc_stats_event_context = ctx;
- ocb_cbs->ocb_dcc_stats_event_callback = dcc_stats_cb;
- return QDF_STATUS_SUCCESS;
- }
- QDF_STATUS ucfg_ocb_register_vdev_start(struct wlan_objmgr_pdev *pdev,
- QDF_STATUS (*ocb_start)(struct ocb_config *))
- {
- struct ocb_callbacks *ocb_cbs;
- if (!pdev) {
- ocb_err("Null pointer for pdev");
- return QDF_STATUS_E_INVAL;
- }
- ocb_cbs = wlan_ocb_get_callbacks(pdev);
- if (!ocb_cbs) {
- ocb_err("Failed to register dcc stats callback");
- return QDF_STATUS_E_FAILURE;
- }
- ocb_cbs->start_ocb_vdev = ocb_start;
- return QDF_STATUS_SUCCESS;
- }
|