| /* |
| * 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: offload lmac interface APIs for ocb |
| * |
| */ |
| |
| #include <qdf_mem.h> |
| #include <target_if.h> |
| #include <qdf_status.h> |
| #include <wmi_unified_api.h> |
| #include <wmi_unified_priv.h> |
| #include <wmi_unified_param.h> |
| #include <wlan_objmgr_psoc_obj.h> |
| #include <wlan_utility.h> |
| #include <wlan_defs.h> |
| #include <wlan_ocb_public_structs.h> |
| #include <wlan_ocb_main.h> |
| #include <target_if_ocb.h> |
| |
| /** |
| * target_if_ocb_get_rx_ops() - get target interface RX operations |
| * @pdev: pdev handle |
| * |
| * Return: fp to target interface RX operations |
| */ |
| static inline struct wlan_ocb_rx_ops * |
| target_if_ocb_get_rx_ops(struct wlan_objmgr_pdev *pdev) |
| { |
| struct ocb_pdev_obj *ocb_obj; |
| |
| ocb_obj = wlan_get_pdev_ocb_obj(pdev); |
| |
| return &ocb_obj->ocb_rxops; |
| } |
| |
| /** |
| * target_if_ocb_set_config() - send the OCB config to the FW |
| * @psoc: pointer to PSOC object |
| * @config: OCB channel configuration |
| * |
| * Return: QDF_STATUS_SUCCESS on success |
| */ |
| static QDF_STATUS target_if_ocb_set_config(struct wlan_objmgr_psoc *psoc, |
| struct ocb_config *config) |
| { |
| QDF_STATUS status; |
| |
| status = wmi_unified_ocb_set_config(get_wmi_unified_hdl_from_psoc(psoc), |
| config); |
| if (status) |
| target_if_err("Failed to set OCB config %d", status); |
| |
| return status; |
| } |
| |
| /** |
| * target_if_ocb_set_utc_time() - send the UTC time to the firmware |
| * @psoc: pointer to PSOC object |
| * @utc: pointer to the UTC time structure |
| * |
| * Return: QDF_STATUS_SUCCESS on success |
| */ |
| static QDF_STATUS target_if_ocb_set_utc_time(struct wlan_objmgr_psoc *psoc, |
| struct ocb_utc_param *utc) |
| { |
| QDF_STATUS status; |
| |
| status = wmi_unified_ocb_set_utc_time_cmd( |
| get_wmi_unified_hdl_from_psoc(psoc), utc); |
| if (status) |
| target_if_err("Failed to set OCB UTC time %d", status); |
| |
| return status; |
| } |
| |
| /** |
| * target_if_ocb_start_timing_advert() - start sending the timing |
| * advertisement frame on a channel |
| * @psoc: pointer to PSOC object |
| * @ta: pointer to the timing advertisement |
| * |
| * Return: QDF_STATUS_SUCCESS on success |
| */ |
| static QDF_STATUS |
| target_if_ocb_start_timing_advert(struct wlan_objmgr_psoc *psoc, |
| struct ocb_timing_advert_param *ta) |
| { |
| QDF_STATUS status; |
| |
| status = wmi_unified_ocb_start_timing_advert( |
| get_wmi_unified_hdl_from_psoc(psoc), ta); |
| if (status) |
| target_if_err("Failed to start OCB timing advert %d", status); |
| |
| return status; |
| } |
| |
| /** |
| * target_if_ocb_stop_timing_advert() - stop sending the timing |
| * advertisement frame on a channel |
| * @psoc: pointer to PSOC object |
| * @ta: pointer to the timing advertisement |
| * |
| * Return: QDF_STATUS_SUCCESS on success |
| */ |
| static QDF_STATUS |
| target_if_ocb_stop_timing_advert(struct wlan_objmgr_psoc *psoc, |
| struct ocb_timing_advert_param *ta) |
| { |
| QDF_STATUS status; |
| |
| status = |
| wmi_unified_ocb_stop_timing_advert( |
| get_wmi_unified_hdl_from_psoc(psoc), ta); |
| if (status) |
| target_if_err("Failed to stop OCB timing advert %d", status); |
| |
| return status; |
| } |
| |
| /** |
| * target_if_ocb_get_tsf_timer() - get tsf timer |
| * @psoc: pointer to PSOC object |
| * @request: pointer to the request |
| * |
| * Return: QDF_STATUS_SUCCESS on success |
| */ |
| static QDF_STATUS |
| target_if_ocb_get_tsf_timer(struct wlan_objmgr_psoc *psoc, |
| struct ocb_get_tsf_timer_param *request) |
| { |
| QDF_STATUS status; |
| |
| status = wmi_unified_ocb_get_tsf_timer( |
| get_wmi_unified_hdl_from_psoc(psoc), request); |
| if (status) |
| target_if_err("Failed to send get tsf timer cmd: %d", status); |
| |
| return status; |
| } |
| |
| /** |
| * target_if_dcc_get_stats() - get the DCC channel stats |
| * @psoc: pointer to PSOC object |
| * @get_stats_param: pointer to the dcc stats request |
| * |
| * Return: QDF_STATUS_SUCCESS on success |
| */ |
| static QDF_STATUS |
| target_if_dcc_get_stats(struct wlan_objmgr_psoc *psoc, |
| struct ocb_dcc_get_stats_param *get_stats_param) |
| { |
| QDF_STATUS status; |
| |
| status = wmi_unified_dcc_get_stats_cmd( |
| get_wmi_unified_hdl_from_psoc(psoc), get_stats_param); |
| if (status) |
| target_if_err("Failed to send get DCC stats cmd: %d", status); |
| |
| return status; |
| } |
| |
| /** |
| * target_if_dcc_clear_stats() - send command to clear the DCC stats |
| * @psoc: pointer to PSOC object |
| * @clear_stats_param: parameters to the command |
| * |
| * Return: QDF_STATUS_SUCCESS on success |
| */ |
| static QDF_STATUS |
| target_if_dcc_clear_stats(struct wlan_objmgr_psoc *psoc, |
| struct ocb_dcc_clear_stats_param *clear_stats_param) |
| { |
| QDF_STATUS status; |
| |
| status = wmi_unified_dcc_clear_stats( |
| get_wmi_unified_hdl_from_psoc(psoc), clear_stats_param); |
| if (status) |
| target_if_err("Failed to send clear DCC stats cmd: %d", status); |
| |
| return status; |
| } |
| |
| /** |
| * target_if_dcc_update_ndl() - command to update the NDL data |
| * @psoc: pointer to PSOC object |
| * @update_ndl_param: pointer to the request parameters |
| * |
| * Return: QDF_STATUS_SUCCESS on success |
| */ |
| static QDF_STATUS |
| target_if_dcc_update_ndl(struct wlan_objmgr_psoc *psoc, |
| struct ocb_dcc_update_ndl_param *update_ndl_param) |
| { |
| QDF_STATUS status; |
| |
| /* Send the WMI command */ |
| status = wmi_unified_dcc_update_ndl(get_wmi_unified_hdl_from_psoc(psoc), |
| update_ndl_param); |
| if (status) |
| target_if_err("Failed to send NDL update cmd: %d", status); |
| |
| return status; |
| } |
| |
| /** |
| * target_if_ocb_set_config_resp() - handler for channel config response |
| * @scn: scn handle |
| * @event_buf: pointer to the event buffer |
| * @len: length of the buffer |
| * |
| * Return: 0 on success |
| */ |
| static int |
| target_if_ocb_set_config_resp(ol_scn_t scn, uint8_t *event_buf, |
| uint32_t len) |
| { |
| int rc; |
| QDF_STATUS status; |
| uint32_t resp; |
| struct wlan_objmgr_pdev *pdev; |
| struct wlan_objmgr_psoc *psoc; |
| struct wlan_ocb_rx_ops *ocb_rx_ops; |
| |
| target_if_debug("scn:%pK, data:%pK, datalen:%d", |
| scn, event_buf, len); |
| if (!scn || !event_buf) { |
| target_if_err("scn: 0x%pK, data: 0x%pK", scn, event_buf); |
| return -EINVAL; |
| } |
| |
| psoc = target_if_get_psoc_from_scn_hdl(scn); |
| if (!psoc) { |
| target_if_err("null psoc"); |
| return -EINVAL; |
| } |
| |
| pdev = wlan_objmgr_get_pdev_by_id(psoc, 0, |
| WLAN_OCB_SB_ID); |
| if (!pdev) { |
| target_if_err("pdev is NULL"); |
| return -EINVAL; |
| } |
| |
| ocb_rx_ops = target_if_ocb_get_rx_ops(pdev); |
| if (ocb_rx_ops->ocb_set_config_status) { |
| status = wmi_extract_ocb_set_channel_config_resp( |
| get_wmi_unified_hdl_from_psoc(psoc), |
| event_buf, &resp); |
| if (QDF_IS_STATUS_ERROR(status)) { |
| target_if_err("Failed to extract config status"); |
| rc = -EINVAL; |
| goto exit; |
| } |
| status = ocb_rx_ops->ocb_set_config_status(psoc, resp); |
| if (status != QDF_STATUS_SUCCESS) { |
| target_if_err("ocb_set_config_status failed."); |
| rc = -EINVAL; |
| goto exit; |
| } |
| rc = 0; |
| } else { |
| target_if_fatal("No ocb_set_config_status callback"); |
| rc = -EINVAL; |
| } |
| exit: |
| wlan_objmgr_pdev_release_ref(pdev, WLAN_OCB_SB_ID); |
| |
| return rc; |
| }; |
| |
| /** |
| * target_if_ocb_get_tsf_timer_resp() - handler for TSF timer response |
| * @scn: scn handle |
| * @event_buf: pointer to the event buffer |
| * @len: length of the buffer |
| * |
| * Return: 0 on success |
| */ |
| static int target_if_ocb_get_tsf_timer_resp(ol_scn_t scn, |
| uint8_t *event_buf, |
| uint32_t len) |
| { |
| int rc; |
| QDF_STATUS status; |
| struct wlan_objmgr_pdev *pdev; |
| struct wlan_objmgr_psoc *psoc; |
| struct ocb_get_tsf_timer_response response; |
| struct wlan_ocb_rx_ops *ocb_rx_ops; |
| |
| target_if_debug("scn:%pK, data:%pK, datalen:%d", |
| scn, event_buf, len); |
| |
| if (!scn || !event_buf) { |
| target_if_err("scn: 0x%pK, data: 0x%pK", scn, event_buf); |
| return -EINVAL; |
| } |
| |
| psoc = target_if_get_psoc_from_scn_hdl(scn); |
| if (!psoc) { |
| target_if_err("null psoc"); |
| return -EINVAL; |
| } |
| |
| pdev = wlan_objmgr_get_pdev_by_id(psoc, 0, |
| WLAN_OCB_SB_ID); |
| if (!pdev) { |
| target_if_err("pdev is NULL"); |
| return -EINVAL; |
| } |
| |
| ocb_rx_ops = target_if_ocb_get_rx_ops(pdev); |
| if (ocb_rx_ops->ocb_tsf_timer) { |
| status = wmi_extract_ocb_tsf_timer( |
| get_wmi_unified_hdl_from_psoc(psoc), |
| event_buf, &response); |
| if (QDF_IS_STATUS_ERROR(status)) { |
| target_if_err("Failed to extract tsf timer"); |
| rc = -EINVAL; |
| goto exit; |
| } |
| status = ocb_rx_ops->ocb_tsf_timer(psoc, &response); |
| if (status != QDF_STATUS_SUCCESS) { |
| target_if_err("ocb_tsf_timer failed."); |
| rc = -EINVAL; |
| goto exit; |
| } |
| rc = 0; |
| } else { |
| target_if_fatal("No ocb_tsf_timer callback"); |
| rc = -EINVAL; |
| } |
| exit: |
| wlan_objmgr_pdev_release_ref(pdev, WLAN_OCB_SB_ID); |
| |
| return rc; |
| } |
| |
| /** |
| * target_if_dcc_update_ndl_resp() - handler for update NDL response |
| * @scn: scn handle |
| * @event_buf: pointer to the event buffer |
| * @len: length of the buffer |
| * |
| * Return: 0 on success |
| */ |
| static int target_if_dcc_update_ndl_resp(ol_scn_t scn, |
| uint8_t *event_buf, |
| uint32_t len) |
| { |
| int rc; |
| QDF_STATUS status; |
| struct wlan_objmgr_pdev *pdev; |
| struct wlan_objmgr_psoc *psoc; |
| struct ocb_dcc_update_ndl_response *resp; |
| struct wlan_ocb_rx_ops *ocb_rx_ops; |
| |
| target_if_debug("scn:%pK, data:%pK, datalen:%d", |
| scn, event_buf, len); |
| |
| if (!scn || !event_buf) { |
| target_if_err("scn: 0x%pK, data: 0x%pK", scn, event_buf); |
| return -EINVAL; |
| } |
| |
| psoc = target_if_get_psoc_from_scn_hdl(scn); |
| if (!psoc) { |
| target_if_err("null psoc"); |
| return -EINVAL; |
| } |
| pdev = wlan_objmgr_get_pdev_by_id(psoc, 0, |
| WLAN_OCB_SB_ID); |
| if (!pdev) { |
| target_if_err("pdev is NULL"); |
| return -EINVAL; |
| } |
| |
| /* Allocate and populate the response */ |
| resp = qdf_mem_malloc(sizeof(*resp)); |
| if (!resp) { |
| target_if_err("Error allocating memory for the response."); |
| rc = -ENOMEM; |
| goto exit; |
| } |
| |
| ocb_rx_ops = target_if_ocb_get_rx_ops(pdev); |
| if (ocb_rx_ops->ocb_dcc_ndl_update) { |
| status = wmi_extract_dcc_update_ndl_resp( |
| get_wmi_unified_hdl_from_psoc(psoc), |
| event_buf, resp); |
| if (QDF_IS_STATUS_ERROR(status)) { |
| target_if_err("Failed to extract ndl status"); |
| rc = -EINVAL; |
| goto exit; |
| } |
| status = ocb_rx_ops->ocb_dcc_ndl_update(psoc, resp); |
| if (status != QDF_STATUS_SUCCESS) { |
| target_if_err("dcc_ndl_update failed."); |
| rc = -EINVAL; |
| goto exit; |
| } |
| rc = 0; |
| } else { |
| target_if_fatal("No dcc_ndl_update callback"); |
| rc = -EINVAL; |
| } |
| exit: |
| wlan_objmgr_pdev_release_ref(pdev, WLAN_OCB_SB_ID); |
| if (resp) |
| qdf_mem_free(resp); |
| |
| return rc; |
| } |
| |
| /** |
| * target_if_dcc_get_stats_resp() - handler for get stats response |
| * @scn: scn handle |
| * @event_buf: pointer to the event buffer |
| * @len: length of the buffer |
| * |
| * Return: 0 on success |
| */ |
| static int target_if_dcc_get_stats_resp(ol_scn_t scn, |
| uint8_t *event_buf, |
| uint32_t len) |
| { |
| int rc; |
| QDF_STATUS status; |
| struct wlan_objmgr_pdev *pdev; |
| struct wlan_objmgr_psoc *psoc; |
| struct ocb_dcc_get_stats_response *response; |
| struct wlan_ocb_rx_ops *ocb_rx_ops; |
| |
| target_if_debug("scn:%pK, data:%pK, datalen:%d", |
| scn, event_buf, len); |
| |
| if (!scn || !event_buf) { |
| target_if_err("scn: 0x%pK, data: 0x%pK", scn, event_buf); |
| return -EINVAL; |
| } |
| |
| psoc = target_if_get_psoc_from_scn_hdl(scn); |
| if (!psoc) { |
| target_if_err("null psoc"); |
| return -EINVAL; |
| } |
| |
| pdev = wlan_objmgr_get_pdev_by_id(psoc, 0, |
| WLAN_OCB_SB_ID); |
| if (!pdev) { |
| target_if_err("pdev is NULL"); |
| return -EINVAL; |
| } |
| |
| ocb_rx_ops = target_if_ocb_get_rx_ops(pdev); |
| if (ocb_rx_ops->ocb_dcc_stats_indicate) { |
| status = wmi_extract_dcc_stats( |
| get_wmi_unified_hdl_from_psoc(psoc), |
| event_buf, &response); |
| if (!response || QDF_IS_STATUS_ERROR(status)) { |
| target_if_err("Cannot get DCC stats"); |
| rc = -ENOMEM; |
| goto exit; |
| } |
| |
| status = ocb_rx_ops->ocb_dcc_stats_indicate(psoc, |
| response, |
| true); |
| if (QDF_IS_STATUS_ERROR(status)) { |
| target_if_err("dcc_stats_indicate failed."); |
| rc = -EINVAL; |
| goto exit; |
| } |
| rc = 0; |
| } else { |
| target_if_fatal("No dcc_stats_indicate callback"); |
| rc = -EINVAL; |
| } |
| exit: |
| wlan_objmgr_pdev_release_ref(pdev, WLAN_OCB_SB_ID); |
| if (response) |
| qdf_mem_free(response); |
| |
| return rc; |
| } |
| |
| /** |
| * target_if_dcc_stats_resp() - handler for DCC stats indication event |
| * @scn: scn handle |
| * @event_buf: pointer to the event buffer |
| * @len: length of the buffer |
| * |
| * Return: 0 on success |
| */ |
| static int target_if_dcc_stats_resp(ol_scn_t scn, uint8_t *event_buf, |
| uint32_t len) |
| { |
| int rc; |
| QDF_STATUS status; |
| struct wlan_objmgr_pdev *pdev; |
| struct wlan_objmgr_psoc *psoc; |
| struct ocb_dcc_get_stats_response *response; |
| struct wlan_ocb_rx_ops *ocb_rx_ops; |
| |
| target_if_debug("scn:%pK, data:%pK, datalen:%d", |
| scn, event_buf, len); |
| |
| if (!scn || !event_buf) { |
| target_if_err("scn: 0x%pK, data: 0x%pK", scn, event_buf); |
| return -EINVAL; |
| } |
| |
| psoc = target_if_get_psoc_from_scn_hdl(scn); |
| if (!psoc) { |
| target_if_err("null psoc"); |
| return -EINVAL; |
| } |
| |
| pdev = wlan_objmgr_get_pdev_by_id(psoc, 0, |
| WLAN_OCB_SB_ID); |
| if (!pdev) { |
| target_if_err("pdev is NULL"); |
| return -EINVAL; |
| } |
| |
| ocb_rx_ops = target_if_ocb_get_rx_ops(pdev); |
| if (ocb_rx_ops->ocb_dcc_stats_indicate) { |
| status = wmi_extract_dcc_stats( |
| get_wmi_unified_hdl_from_psoc(psoc), |
| event_buf, &response); |
| if (!response || QDF_IS_STATUS_ERROR(status)) { |
| target_if_err("Cannot get DCC stats"); |
| rc = -ENOMEM; |
| goto exit; |
| } |
| status = ocb_rx_ops->ocb_dcc_stats_indicate(psoc, |
| response, |
| false); |
| if (QDF_IS_STATUS_ERROR(status)) { |
| target_if_err("dcc_stats_indicate failed."); |
| rc = -EINVAL; |
| goto exit; |
| } |
| rc = 0; |
| } else { |
| target_if_fatal("dcc_stats_indicate failed."); |
| response = NULL; |
| rc = -EINVAL; |
| } |
| exit: |
| wlan_objmgr_pdev_release_ref(pdev, WLAN_OCB_SB_ID); |
| if (response) |
| qdf_mem_free(response); |
| |
| return rc; |
| } |
| |
| QDF_STATUS target_if_ocb_register_event_handler(struct wlan_objmgr_psoc *psoc, |
| void *arg) |
| { |
| int rc; |
| |
| /* Initialize the members in WMA used by wma_ocb */ |
| rc = wmi_unified_register_event(get_wmi_unified_hdl_from_psoc(psoc), |
| wmi_ocb_set_config_resp_event_id, |
| target_if_ocb_set_config_resp); |
| if (rc) { |
| target_if_err("Failed to register OCB config resp event cb"); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| rc = wmi_unified_register_event( |
| get_wmi_unified_hdl_from_psoc(psoc), |
| wmi_ocb_get_tsf_timer_resp_event_id, |
| target_if_ocb_get_tsf_timer_resp); |
| if (rc) { |
| target_if_err("Failed to register OCB TSF resp event cb"); |
| goto unreg_set_config; |
| } |
| |
| rc = wmi_unified_register_event( |
| get_wmi_unified_hdl_from_psoc(psoc), |
| wmi_dcc_get_stats_resp_event_id, |
| target_if_dcc_get_stats_resp); |
| if (rc) { |
| target_if_err("Failed to register DCC get stats resp event cb"); |
| goto unreg_tsf_timer; |
| } |
| |
| rc = wmi_unified_register_event( |
| get_wmi_unified_hdl_from_psoc(psoc), |
| wmi_dcc_update_ndl_resp_event_id, |
| target_if_dcc_update_ndl_resp); |
| if (rc) { |
| target_if_err("Failed to register NDL update event cb"); |
| goto unreg_get_stats; |
| } |
| |
| rc = wmi_unified_register_event(get_wmi_unified_hdl_from_psoc(psoc), |
| wmi_dcc_stats_event_id, |
| target_if_dcc_stats_resp); |
| if (rc) { |
| target_if_err("Failed to register DCC stats event cb"); |
| goto unreg_ndl; |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| |
| unreg_ndl: |
| wmi_unified_unregister_event_handler( |
| get_wmi_unified_hdl_from_psoc(psoc), |
| wmi_dcc_update_ndl_resp_event_id); |
| unreg_get_stats: |
| wmi_unified_unregister_event_handler( |
| get_wmi_unified_hdl_from_psoc(psoc), |
| wmi_dcc_get_stats_resp_event_id); |
| unreg_tsf_timer: |
| wmi_unified_unregister_event_handler( |
| get_wmi_unified_hdl_from_psoc(psoc), |
| wmi_ocb_get_tsf_timer_resp_event_id); |
| unreg_set_config: |
| wmi_unified_unregister_event(get_wmi_unified_hdl_from_psoc(psoc), |
| wmi_ocb_set_config_resp_event_id); |
| |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| QDF_STATUS |
| target_if_ocb_unregister_event_handler(struct wlan_objmgr_psoc *psoc, |
| void *arg) |
| { |
| int rc; |
| |
| rc = wmi_unified_unregister_event_handler( |
| get_wmi_unified_hdl_from_psoc(psoc), |
| wmi_dcc_stats_event_id); |
| if (rc) |
| target_if_err("Failed to unregister DCC stats event cb"); |
| |
| rc = wmi_unified_unregister_event_handler( |
| get_wmi_unified_hdl_from_psoc(psoc), |
| wmi_dcc_update_ndl_resp_event_id); |
| if (rc) |
| target_if_err("Failed to unregister NDL update event cb"); |
| |
| rc = wmi_unified_unregister_event_handler( |
| get_wmi_unified_hdl_from_psoc(psoc), |
| wmi_dcc_get_stats_resp_event_id); |
| if (rc) |
| target_if_err("Failed to unregister DCC get stats resp cb"); |
| |
| rc = wmi_unified_unregister_event_handler( |
| get_wmi_unified_hdl_from_psoc(psoc), |
| wmi_ocb_get_tsf_timer_resp_event_id); |
| if (rc) |
| target_if_err("Failed to unregister OCB TSF resp event cb"); |
| |
| rc = wmi_unified_unregister_event(get_wmi_unified_hdl_from_psoc(psoc), |
| wmi_ocb_set_config_resp_event_id); |
| if (rc) |
| target_if_err("Failed to unregister OCB config resp event cb"); |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| QDF_STATUS |
| target_if_ocb_register_tx_ops(struct wlan_ocb_tx_ops *ocb_txops) |
| { |
| ocb_txops->ocb_set_config = target_if_ocb_set_config; |
| ocb_txops->ocb_set_utc_time = target_if_ocb_set_utc_time; |
| ocb_txops->ocb_start_timing_advert = target_if_ocb_start_timing_advert; |
| ocb_txops->ocb_stop_timing_advert = target_if_ocb_stop_timing_advert; |
| ocb_txops->ocb_get_tsf_timer = target_if_ocb_get_tsf_timer; |
| ocb_txops->ocb_dcc_get_stats = target_if_dcc_get_stats; |
| ocb_txops->ocb_dcc_clear_stats = target_if_dcc_clear_stats; |
| ocb_txops->ocb_dcc_update_ndl = target_if_dcc_update_ndl; |
| ocb_txops->ocb_reg_ev_handler = target_if_ocb_register_event_handler; |
| ocb_txops->ocb_unreg_ev_handler = |
| target_if_ocb_unregister_event_handler; |
| |
| return QDF_STATUS_SUCCESS; |
| } |