diff --git a/components/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h b/components/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h index b0fd778a93e1..0cf54d33580b 100644 --- a/components/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h +++ b/components/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h @@ -29,6 +29,14 @@ #include "wlan_cmn.h" #include "qdf_event.h" +#ifdef WLAN_SUPPORT_TWT + +#include +/* Max TWT sessions per peer (supported by fw) */ +#define TWT_PEER_MAX_SESSIONS 1 + +#endif /* WLAN_SUPPORT_TWT */ + #define MAX_NUM_CHAINS 2 #define MAX_MIB_STATS 1 @@ -300,6 +308,7 @@ struct peer_extd_stats { * @peer_macaddr: mac address * @extd_stats: Pointer to peer extended stats * @adv_stats: Pointer to peer adv (extd2) stats + * @twt_param: Pointer to peer twt session parameters */ struct peer_mc_cp_stats { uint32_t tx_rate; @@ -308,6 +317,9 @@ struct peer_mc_cp_stats { uint8_t peer_macaddr[QDF_MAC_ADDR_SIZE]; struct peer_extd_stats *extd_stats; struct peer_adv_mc_cp_stats *adv_stats; +#ifdef WLAN_SUPPORT_TWT + struct wmi_host_twt_session_stats_info twt_param[TWT_PEER_MAX_SESSIONS]; +#endif }; /** diff --git a/components/cp_stats/dispatcher/inc/wlan_cp_stats_mc_ucfg_api.h b/components/cp_stats/dispatcher/inc/wlan_cp_stats_mc_ucfg_api.h index 9420168ce09d..177a1a820011 100644 --- a/components/cp_stats/dispatcher/inc/wlan_cp_stats_mc_ucfg_api.h +++ b/components/cp_stats/dispatcher/inc/wlan_cp_stats_mc_ucfg_api.h @@ -31,6 +31,37 @@ #include #include +#ifdef WLAN_SUPPORT_TWT + +#include +#include "../../core/src/wlan_cp_stats_defs.h" +#include + +/* Max TWT sessions supported */ +#define TWT_PSOC_MAX_SESSIONS TWT_PEER_MAX_SESSIONS + +/* Valid dialog_id 0 to (0xFF - 1) */ +#define TWT_MAX_DIALOG_ID (0xFF - 1) + +/* dialog_id used to get all peer's twt session parameters */ +#define TWT_GET_ALL_PEER_PARAMS_DIALOG_ID (0xFF) + +/** + * ucfg_twt_get_peer_session_params() - Retrieves peer twt session parameters + * corresponding to a peer by using mac_addr and dialog id + * If dialog_id is TWT_GET_ALL_PEER_PARAMS_DIALOG_ID retrieves twt session + * parameters of all peers with valid twt session + * @psoc_obj: psoc object + * @params: array pointer to store peer twt session parameters, should contain + * mac_addr and dialog id of a peer for which twt session stats to be retrieved + * + * Return: QDF_STATUS_SUCCESS upon success, else qdf error values + */ +QDF_STATUS +ucfg_twt_get_peer_session_params(struct wlan_objmgr_psoc *psoc_obj, + struct wmi_host_twt_session_stats_info *param); +#endif /* WLAN_SUPPORT_TWT */ + struct psoc_cp_stats; struct vdev_cp_stats; diff --git a/components/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c b/components/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c index d5cbaef3a4b2..f669c8a4c7f3 100644 --- a/components/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c +++ b/components/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c @@ -28,12 +28,258 @@ #include #include #include "../../core/src/wlan_cp_stats_defs.h" -#include "../../core/src/wlan_cp_stats_defs.h" #include "../../core/src/wlan_cp_stats_cmn_api_i.h" #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD #include #endif +#ifdef WLAN_SUPPORT_TWT + +/** + * ucfg_twt_get_peer_session_param_by_dlg_id() - Finds a Peer twt session with + * dialog id matching with input dialog id. If a match is found copies + * the twt session parameters + * @mc_stats: pointer to peer specific stats + * @input_dialog_id: input dialog id + * @dest_param: Pointer to copy twt session parameters when a peer with + * given dialog id is found + * + * Return: true if stats are copied for a peer with given dialog, else false + */ +static bool +ucfg_twt_get_peer_session_param_by_dlg_id(struct peer_mc_cp_stats *mc_stats, + uint32_t input_dialog_id, + struct wmi_host_twt_session_stats_info + *dest_param) +{ + struct wmi_host_twt_session_stats_info *src_param; + uint32_t event_type; + int i; + + if (!mc_stats || !dest_param) + return false; + + for (i = 0; i < TWT_PEER_MAX_SESSIONS; i++) { + event_type = mc_stats->twt_param[i].event_type; + + src_param = &mc_stats->twt_param[i]; + if ((!event_type) || (src_param->dialog_id != input_dialog_id)) + continue; + + if ((event_type == HOST_TWT_SESSION_SETUP) || + (event_type == HOST_TWT_SESSION_UPDATE)) { + qdf_mem_copy(dest_param, src_param, sizeof(*src_param)); + return true; + } + } + + return false; +} + +/** + * ucfg_twt_get_single_peer_session_params()- Extracts twt session parameters + * corresponding to a peer given by dialog_id + * @psoc_obj: psoc object + * @mac_addr: mac addr of peer + * @dialog_id: dialog id of peer for which twt session params to be retrieved + * @params: pointer to store peer twt session parameters + * + * Return: Retuns QDF_STATUS_SUCCESS upon success, else qdf error values + */ +static QDF_STATUS +ucfg_twt_get_single_peer_session_params(struct wlan_objmgr_psoc *psoc_obj, + uint8_t *mac_addr, uint32_t dialog_id, + struct wmi_host_twt_session_stats_info + *params) +{ + struct wlan_objmgr_peer *peer; + struct peer_cp_stats *peer_cp_stats_priv; + struct peer_mc_cp_stats *peer_mc_stats; + QDF_STATUS qdf_status = QDF_STATUS_E_INVAL; + + if (!psoc_obj || !params) + return qdf_status; + + peer = wlan_objmgr_get_peer_by_mac(psoc_obj, mac_addr, + WLAN_CP_STATS_ID); + if (!peer) + return qdf_status; + + peer_cp_stats_priv = wlan_cp_stats_get_peer_stats_obj(peer); + if (!peer_cp_stats_priv) { + wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID); + return qdf_status; + } + + wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv); + peer_mc_stats = peer_cp_stats_priv->peer_stats; + + if (ucfg_twt_get_peer_session_param_by_dlg_id(peer_mc_stats, + dialog_id, params)) { + qdf_status = QDF_STATUS_SUCCESS; + } else { + qdf_err("No TWT session for " QDF_MAC_ADDR_STR " dialog_id %d", + QDF_MAC_ADDR_ARRAY(mac_addr), dialog_id); + } + + wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv); + wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID); + + return qdf_status; +} + +/** + * ucfg_twt_get_peer_session_param() - Obtains twt session parameters of + * a peer if twt session is valid + * @mc_cp_stats: pointer to peer specific stats + * @param: Pointer to copy twt session parameters + * @num_twt_sessions: Pointer holding total number of valid twt sessions + * + * Return: QDF_STATUS success if valid twt session parameters are obtained + * else other qdf error values + */ +static QDF_STATUS +ucfg_twt_get_peer_session_param(struct peer_mc_cp_stats *mc_cp_stats, + struct wmi_host_twt_session_stats_info *params, + int *num_twt_sessions) +{ + struct wmi_host_twt_session_stats_info *twt_params; + QDF_STATUS qdf_status = QDF_STATUS_E_INVAL; + uint32_t event_type; + int i; + + if (!mc_cp_stats || !params) + return qdf_status; + + for (i = 0; i < TWT_PEER_MAX_SESSIONS; i++) { + twt_params = &mc_cp_stats->twt_param[i]; + event_type = mc_cp_stats->twt_param[i].event_type; + + /* Check twt session is established */ + if ((event_type == HOST_TWT_SESSION_SETUP) || + (event_type == HOST_TWT_SESSION_UPDATE)) { + qdf_mem_copy(¶ms[*num_twt_sessions], twt_params, + sizeof(*twt_params)); + qdf_status = QDF_STATUS_SUCCESS; + *num_twt_sessions += 1; + if (*num_twt_sessions >= TWT_PSOC_MAX_SESSIONS) + break; + } + } + return qdf_status; +} + +/** + * ucfg_twt_get_all_peer_session_params()- Retrieves twt session parameters + * of all peers with valid twt session + * @psoc_obj: psoc object + * @params: array of pointer to store peer twt session parameters + * + * Return: Retuns QDF_STATUS_SUCCESS upon success, else qdf error values + */ +static QDF_STATUS +ucfg_twt_get_all_peer_session_params(struct wlan_objmgr_psoc *psoc_obj, + struct wmi_host_twt_session_stats_info + *params) +{ + struct wlan_objmgr_psoc_objmgr *psoc_objmgr; + struct wlan_objmgr_peer *peer_obj; + struct wlan_peer_list *peer_list; + struct peer_cp_stats *cp_stats_peer_obj; + struct peer_mc_cp_stats *mc_cp_stats; + struct peer_cp_stats *peer_cp_stat_prv; + QDF_STATUS qdf_status = QDF_STATUS_E_INVAL; + qdf_list_t *obj_list; + int i, num_sessions = 0; + + /* psoc obj lock should be taken before peer list lock */ + wlan_psoc_obj_lock(psoc_obj); + psoc_objmgr = &psoc_obj->soc_objmgr; + /* List is empty, return */ + if (!psoc_objmgr->wlan_peer_count) { + wlan_psoc_obj_unlock(psoc_obj); + return qdf_status; + } + + peer_list = &psoc_objmgr->peer_list; + qdf_spin_lock_bh(&peer_list->peer_list_lock); + + /* Iterate through peer_list to find a peer with valid twt sessions */ + for (i = 0; i < WLAN_PEER_HASHSIZE; i++) { + obj_list = &peer_list->peer_hash[i]; + peer_obj = wlan_psoc_peer_list_peek_head(obj_list); + while (peer_obj) { + cp_stats_peer_obj = + wlan_objmgr_peer_get_comp_private_obj + (peer_obj, WLAN_UMAC_COMP_CP_STATS); + + mc_cp_stats = NULL; + if (cp_stats_peer_obj) + mc_cp_stats = cp_stats_peer_obj->peer_stats; + + peer_cp_stat_prv = + wlan_cp_stats_get_peer_stats_obj(peer_obj); + + if (peer_cp_stat_prv && mc_cp_stats) { + wlan_cp_stats_peer_obj_lock(peer_cp_stat_prv); + ucfg_twt_get_peer_session_param(mc_cp_stats, + params, + &num_sessions); + wlan_cp_stats_peer_obj_unlock(peer_cp_stat_prv); + } + + if (num_sessions >= TWT_PSOC_MAX_SESSIONS) + goto done; + /* Get next peer */ + peer_obj = wlan_peer_get_next_peer_of_psoc(obj_list, + peer_obj); + } + } + +done: + /* If atleast one peer with valid twt session is found return success */ + if (num_sessions) + qdf_status = QDF_STATUS_SUCCESS; + else + qdf_err("Unable to find a peer with twt session established"); + + qdf_spin_unlock_bh(&peer_list->peer_list_lock); + wlan_psoc_obj_unlock(psoc_obj); + return qdf_status; +} + +QDF_STATUS +ucfg_twt_get_peer_session_params(struct wlan_objmgr_psoc *psoc_obj, + struct wmi_host_twt_session_stats_info *params) +{ + uint8_t *mac_addr; + uint32_t dialog_id; + + if (!psoc_obj || !params) + return QDF_STATUS_E_INVAL; + + mac_addr = params[0].peer_mac; + dialog_id = params[0].dialog_id; + + /* + * Currently twt_get_params nl cmd is sending only dialog_id(STA) and + * mac_addr is being filled by driver in STA peer case. When + * twt_get_params adds support for mac_addr and dialog_id of STA/SAP, + * we need handle unicast/multicast macaddr in + * ucfg_twt_get_all_peer_session_params for all active twt sessions + */ + if (dialog_id <= TWT_MAX_DIALOG_ID) + return ucfg_twt_get_single_peer_session_params(psoc_obj, + mac_addr, + dialog_id, + params); + else if (dialog_id == TWT_GET_ALL_PEER_PARAMS_DIALOG_ID) + return ucfg_twt_get_all_peer_session_params(psoc_obj, params); + + return QDF_STATUS_E_INVAL; +} +#endif /* WLAN_SUPPORT_TWT */ + QDF_STATUS wlan_cp_stats_psoc_cs_init(struct psoc_cp_stats *psoc_cs) { psoc_cs->obj_stats = qdf_mem_malloc(sizeof(struct psoc_mc_cp_stats)); diff --git a/components/target_if/cp_stats/src/target_if_mc_cp_stats.c b/components/target_if/cp_stats/src/target_if_mc_cp_stats.c index df7787513308..90aa692ac18f 100644 --- a/components/target_if/cp_stats/src/target_if_mc_cp_stats.c +++ b/components/target_if/cp_stats/src/target_if_mc_cp_stats.c @@ -40,6 +40,274 @@ #include #include +#ifdef WLAN_SUPPORT_TWT + +#include +#include + +/** + * target_if_twt_fill_peer_twt_session_params() - Fills peer twt session + * parameter obtained from firmware into mc_cp_stats of peer + * @mc_cp_stats: Pointer to Peer mc_cp stats + * @twt_params: twt session parameters to be copied + * + * Return: None + */ +static void target_if_twt_fill_peer_twt_session_params +( + struct peer_mc_cp_stats *mc_cp_stats, + struct wmi_host_twt_session_stats_info *twt_params +) +{ + uint32_t event_type; + int i = 0; + + if (!mc_cp_stats || !twt_params) + return; + + if ((twt_params->event_type == HOST_TWT_SESSION_UPDATE) || + (twt_params->event_type == HOST_TWT_SESSION_TEARDOWN)) { + /* Update for a existing session, find by dialog_id */ + for (i = 0; i < TWT_PEER_MAX_SESSIONS; i++) { + if (mc_cp_stats->twt_param[i].dialog_id != + twt_params->dialog_id) + continue; + qdf_mem_copy(&mc_cp_stats->twt_param[i], twt_params, + sizeof(*twt_params)); + return; + } + } else if (twt_params->event_type == HOST_TWT_SESSION_SETUP) { + /* New session, fill in any existing invalid session */ + for (i = 0; i < TWT_PEER_MAX_SESSIONS; i++) { + event_type = mc_cp_stats->twt_param[i].event_type; + if ((event_type != HOST_TWT_SESSION_SETUP) && + (event_type != HOST_TWT_SESSION_UPDATE)) { + qdf_mem_copy(&mc_cp_stats->twt_param[i], + twt_params, + sizeof(*twt_params)); + return; + } + } + } + + target_if_err("Unable to save twt session params with dialog id %d", + twt_params->dialog_id); +} + +/** + * target_if_obtain_mc_cp_stat_obj() - Retrieves peer mc cp stats object + * @peer_obj: peer object + * + * Return: mc cp stats object on success or NULL + */ +static struct peer_mc_cp_stats * +target_if_obtain_mc_cp_stat_obj(struct wlan_objmgr_peer *peer_obj) +{ + struct peer_cp_stats *cp_stats_peer_obj; + struct peer_mc_cp_stats *mc_cp_stats; + + cp_stats_peer_obj = wlan_objmgr_peer_get_comp_private_obj + (peer_obj, WLAN_UMAC_COMP_CP_STATS); + if (!cp_stats_peer_obj) { + target_if_err("cp peer stats obj err"); + return NULL; + } + + mc_cp_stats = cp_stats_peer_obj->peer_stats; + if (!mc_cp_stats) { + target_if_err("mc stats obj err"); + return NULL; + } + return mc_cp_stats; +} + +/** + * target_if_twt_session_params_event_handler() - Handles twt session stats + * event from firmware and store the per peer twt session parameters in + * mc_cp_stats + * @scn: scn handle + * @evt_buf: data buffer for event + * @evt_data_len: data length of event + * + * Return: 0 on success, else error values + */ +static int target_if_twt_session_params_event_handler(ol_scn_t scn, + uint8_t *evt_buf, + uint32_t evt_data_len) +{ + struct wlan_objmgr_psoc *psoc_obj; + struct wlan_objmgr_peer *peer_obj; + struct wmi_unified *wmi_hdl; + struct wmi_host_twt_session_stats_info twt_params; + struct wmi_twt_session_stats_event_param params = {0}; + struct peer_mc_cp_stats *mc_cp_stats; + struct peer_cp_stats *peer_cp_stats_priv; + uint32_t expected_len; + int i; + QDF_STATUS status; + + if (!scn || !evt_buf) { + target_if_err("scn: 0x%pK, evt_buf: 0x%pK", scn, evt_buf); + return -EINVAL; + } + + psoc_obj = target_if_get_psoc_from_scn_hdl(scn); + if (!psoc_obj) { + target_if_err("psoc object is null!"); + return -EINVAL; + } + + wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc_obj); + if (!wmi_hdl) { + target_if_err("wmi_handle is null!"); + return -EINVAL; + } + + status = wmi_extract_twt_session_stats_event(wmi_hdl, evt_buf, ¶ms); + if (QDF_IS_STATUS_ERROR(status)) { + target_if_err("Could not extract twt session stats event"); + return qdf_status_to_os_return(status); + } + + if (params.num_sessions > TWT_PEER_MAX_SESSIONS) { + target_if_err("no of twt sessions exceeded the max supported"); + return -EINVAL; + } + + expected_len = (sizeof(wmi_pdev_twt_session_stats_event_fixed_param) + + WMI_TLV_HDR_SIZE + (params.num_sessions * + sizeof(wmi_twt_session_stats_info))); + + if (evt_data_len < expected_len) { + target_if_err("Got invalid len of data from FW %d expected %d", + evt_data_len, expected_len); + return -EINVAL; + } + + for (i = 0; i < params.num_sessions; i++) { + status = wmi_extract_twt_session_stats_data(wmi_hdl, evt_buf, + ¶ms, + &twt_params, i); + if (QDF_IS_STATUS_ERROR(status)) { + target_if_err("Unable to extract twt params for idx %d", + i); + return -EINVAL; + } + + peer_obj = wlan_objmgr_get_peer_by_mac(psoc_obj, + twt_params.peer_mac, + WLAN_CP_STATS_ID); + if (!peer_obj) { + target_if_err("peer obj not found for " + QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_ARRAY(twt_params.peer_mac)); + continue; + } + + peer_cp_stats_priv = wlan_cp_stats_get_peer_stats_obj(peer_obj); + if (!peer_cp_stats_priv) { + target_if_err("peer_cp_stats_priv is null"); + continue; + } + + mc_cp_stats = target_if_obtain_mc_cp_stat_obj(peer_obj); + if (!mc_cp_stats) { + target_if_err("Unable to retrieve mc cp stats obj for " + QDF_MAC_ADDR_STR, + QDF_MAC_ADDR_ARRAY(twt_params.peer_mac)); + wlan_objmgr_peer_release_ref(peer_obj, + WLAN_CP_STATS_ID); + continue; + } + + wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv); + target_if_twt_fill_peer_twt_session_params(mc_cp_stats, + &twt_params); + wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv); + + wlan_objmgr_peer_release_ref(peer_obj, WLAN_CP_STATS_ID); + } + return 0; +} + +/** + * target_if_twt_session_params_unregister_evt_hdlr() - Unregister the + * event handler registered for wmi event wmi_twt_session_stats_event_id + * @psoc: psoc object + * + * Return: QDF_STATUS_SUCCESS on success or QDF error values on failure + */ +static QDF_STATUS +target_if_twt_session_params_unregister_evt_hdlr(struct wlan_objmgr_psoc *psoc) +{ + struct wmi_unified *wmi_handle; + + if (!psoc) { + target_if_err("psoc obj in null!"); + return QDF_STATUS_E_NULL_VALUE; + } + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("wmi_handle is null!"); + return QDF_STATUS_E_INVAL; + } + + wmi_unified_unregister_event_handler(wmi_handle, + wmi_twt_session_stats_event_id); + + return QDF_STATUS_SUCCESS; +} + +/** + * target_if_twt_session_params_register_evt_hdlr() - Register a event + * handler with wmi layer for wmi event wmi_twt_session_stats_event_id + * @psoc: psoc object + * + * Return: QDF_STATUS_SUCCESS on success or QDF error values on failure + */ +static QDF_STATUS +target_if_twt_session_params_register_evt_hdlr(struct wlan_objmgr_psoc *psoc) +{ + int ret_val; + struct wmi_unified *wmi_handle; + + if (!psoc) { + target_if_err("psoc obj in null!"); + return QDF_STATUS_E_NULL_VALUE; + } + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("wmi_handle is null!"); + return QDF_STATUS_E_INVAL; + } + + ret_val = wmi_unified_register_event_handler( + wmi_handle, + wmi_twt_session_stats_event_id, + target_if_twt_session_params_event_handler, + WMI_RX_WORK_CTX); + + if (ret_val) + target_if_err("Failed to register twt session stats event cb"); + + return qdf_status_from_os_return(ret_val); +} +#else +static QDF_STATUS +target_if_twt_session_params_register_evt_hdlr(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS +target_if_twt_session_params_unregister_evt_hdlr(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} +#endif /* WLAN_SUPPORT_TWT */ + #ifdef WLAN_FEATURE_MIB_STATS static void target_if_cp_stats_free_mib_stats(struct stats_event *ev) { @@ -725,6 +993,48 @@ static QDF_STATUS target_if_cp_stats_send_stats_req( ¶m); } +/** + * target_if_cp_stats_unregister_handlers() - Un-registers wmi event handlers + * of control plane stats & twt session stats info + * @psoc: PSOC object + * + * Return: QDF_STATUS_SUCCESS on success or QDF error values on failure + */ +static QDF_STATUS +target_if_cp_stats_unregister_handlers(struct wlan_objmgr_psoc *psoc) +{ + QDF_STATUS qdf_status; + + qdf_status = target_if_twt_session_params_unregister_evt_hdlr(psoc); + if (qdf_status == QDF_STATUS_SUCCESS) + qdf_status = target_if_cp_stats_unregister_event_handler(psoc); + + return qdf_status; +} + +/** + * target_if_cp_stats_register_handlers() - Registers wmi event handlers for + * control plane stats & twt session stats info + * @psoc: PSOC object + * + * Return: QDF_STATUS_SUCCESS on success or QDF error values on failure + */ +static QDF_STATUS +target_if_cp_stats_register_handlers(struct wlan_objmgr_psoc *psoc) +{ + QDF_STATUS qdf_status; + + qdf_status = target_if_cp_stats_register_event_handler(psoc); + if (qdf_status != QDF_STATUS_SUCCESS) + return qdf_status; + + qdf_status = target_if_twt_session_params_register_evt_hdlr(psoc); + if (qdf_status != QDF_STATUS_SUCCESS) + target_if_cp_stats_unregister_event_handler(psoc); + + return qdf_status; +} + QDF_STATUS target_if_cp_stats_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) { @@ -742,9 +1052,9 @@ target_if_cp_stats_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) } cp_stats_tx_ops->cp_stats_attach = - target_if_cp_stats_register_event_handler; + target_if_cp_stats_register_handlers; cp_stats_tx_ops->cp_stats_detach = - target_if_cp_stats_unregister_event_handler; + target_if_cp_stats_unregister_handlers; cp_stats_tx_ops->inc_wake_lock_stats = target_if_cp_stats_inc_wake_lock_stats; cp_stats_tx_ops->send_req_stats = target_if_cp_stats_send_stats_req;