From 41a58394a7a47705745e0a88791fde7fe0ef4b98 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Mon, 13 Mar 2017 20:17:34 +0800 Subject: [PATCH] qcacmn: WMI changes for P2P component Update WMI layer to adopt to converged P2P component. Change-Id: Ia031476f7ee6071d2e15010fc3f7c998df9995dd CRs-Fixed: 2011217 --- target_if/p2p/src/target_if_p2p.c | 120 +++++++++++--- wmi/inc/wmi_unified_api.h | 18 ++ wmi/inc/wmi_unified_priv.h | 20 +++ wmi/src/wmi_unified_api.c | 101 +++++++++++ wmi/src/wmi_unified_tlv.c | 267 ++++++++++++++++++++++++++++++ 5 files changed, 502 insertions(+), 24 deletions(-) diff --git a/target_if/p2p/src/target_if_p2p.c b/target_if/p2p/src/target_if_p2p.c index 9df8498ec2..dee2c8c0ec 100644 --- a/target_if/p2p/src/target_if_p2p.c +++ b/target_if/p2p/src/target_if_p2p.c @@ -33,9 +33,9 @@ target_if_psoc_get_p2p_rx_ops(struct wlan_objmgr_psoc *psoc) /** * target_p2p_lo_event_handler() - WMI callback for lo stop event - * @scn: + * @scn: pointer to scn * @event_buf: event buffer - * @len: buffer length + * @len: buffer length * * This function gets called from WMI when triggered wmi event * wmi_p2p_lo_stop_event_id. @@ -52,7 +52,7 @@ static int target_p2p_lo_event_handler(ol_scn_t scn, uint8_t *data, struct wlan_lmac_if_p2p_rx_ops *p2p_rx_ops; QDF_STATUS status = QDF_STATUS_E_FAILURE; - target_if_info("scn:%p, data:%p, datalen:%d", scn, data, datalen); + target_if_debug("scn:%p, data:%p, datalen:%d", scn, data, datalen); if (!scn || !data) { target_if_err("scn: 0x%p, data: 0x%p", scn, data); @@ -77,7 +77,12 @@ static int target_p2p_lo_event_handler(ol_scn_t scn, uint8_t *data, return -ENOMEM; } - /*TODO, extract wmi lo stop event */ + if (wmi_extract_p2p_lo_stop_ev_param(wmi_handle, data, + event_info)) { + target_if_err("Failed to extract wmi p2p lo stop event"); + qdf_mem_free(event_info); + return -EINVAL; + } p2p_rx_ops = target_if_psoc_get_p2p_rx_ops(psoc); if (p2p_rx_ops->lo_ev_handler) { @@ -91,9 +96,9 @@ static int target_p2p_lo_event_handler(ol_scn_t scn, uint8_t *data, /** * target_p2p_noa_event_handler() - WMI callback for noa event - * @scn: + * @scn: pointer to scn * @event_buf: event buffer - * @len: buffer length + * @len: buffer length * * This function gets called from WMI when triggered WMI event * wmi_p2p_noa_event_id. @@ -110,7 +115,7 @@ static int target_p2p_noa_event_handler(ol_scn_t scn, uint8_t *data, struct wlan_lmac_if_p2p_rx_ops *p2p_rx_ops; QDF_STATUS status = QDF_STATUS_E_FAILURE; - target_if_info("scn:%p, data:%p, datalen:%d", scn, data, datalen); + target_if_debug("scn:%p, data:%p, datalen:%d", scn, data, datalen); if (!scn || !data) { target_if_err("scn: 0x%p, data: 0x%p", scn, data); @@ -131,11 +136,16 @@ static int target_p2p_noa_event_handler(ol_scn_t scn, uint8_t *data, event_info = qdf_mem_malloc(sizeof(*event_info)); if (!event_info) { - target_if_err("Failed to allocate p2p noa information"); + target_if_err("failed to allocate p2p noa information"); return -ENOMEM; } - /*TODO, extract wmi noa event */ + if (wmi_extract_p2p_noa_ev_param(wmi_handle, data, + event_info)) { + target_if_err("failed to extract wmi p2p noa event"); + qdf_mem_free(event_info); + return -EINVAL; + } p2p_rx_ops = target_if_psoc_get_p2p_rx_ops(psoc); if (p2p_rx_ops->noa_ev_handler) { @@ -153,7 +163,7 @@ QDF_STATUS target_if_p2p_register_lo_event_handler( int status; wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); - target_if_info("psoc:%p, arg:%p", psoc, arg); + target_if_debug("psoc:%p, arg:%p", psoc, arg); if (!wmi_handle) { target_if_err("Invalid wmi handle"); @@ -161,10 +171,11 @@ QDF_STATUS target_if_p2p_register_lo_event_handler( } status = wmi_unified_register_event_handler(wmi_handle, - wmi_p2p_lo_stop_event_id, target_p2p_lo_event_handler, + WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID, + target_p2p_lo_event_handler, WMI_RX_UMAC_CTX); - target_if_info("wmi register lo event handle, status:%d", + target_if_debug("wmi register lo event handle, status:%d", status); return status == 0 ? QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE; @@ -176,7 +187,7 @@ QDF_STATUS target_if_p2p_register_noa_event_handler( int status; wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); - target_if_info("psoc:%p, arg:%p", psoc, arg); + target_if_debug("psoc:%p, arg:%p", psoc, arg); if (!wmi_handle) { target_if_err("Invalid wmi handle"); @@ -184,10 +195,10 @@ QDF_STATUS target_if_p2p_register_noa_event_handler( } status = wmi_unified_register_event_handler(wmi_handle, - wmi_p2p_noa_event_id, target_p2p_noa_event_handler, + WMI_P2P_NOA_EVENTID, target_p2p_noa_event_handler, WMI_RX_UMAC_CTX); - target_if_info("wmi register noa event handle, status:%d", + target_if_debug("wmi register noa event handle, status:%d", status); return status == 0 ? QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE; @@ -199,7 +210,7 @@ QDF_STATUS target_if_p2p_unregister_lo_event_handler( int status; wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); - target_if_info("psoc:%p, arg:%p", psoc, arg); + target_if_debug("psoc:%p, arg:%p", psoc, arg); if (!wmi_handle) { target_if_err("Invalid wmi handle"); @@ -207,9 +218,9 @@ QDF_STATUS target_if_p2p_unregister_lo_event_handler( } status = wmi_unified_unregister_event_handler(wmi_handle, - wmi_p2p_lo_stop_event_id); + WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID); - target_if_info("wmi unregister lo event handle, status:%d", + target_if_debug("wmi unregister lo event handle, status:%d", status); return status == 0 ? QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE; @@ -221,7 +232,7 @@ QDF_STATUS target_if_p2p_unregister_noa_event_handler( int status; wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); - target_if_info("psoc:%p, arg:%p", psoc, arg); + target_if_debug("psoc:%p, arg:%p", psoc, arg); if (!wmi_handle) { target_if_err("Invalid wmi handle"); @@ -229,9 +240,9 @@ QDF_STATUS target_if_p2p_unregister_noa_event_handler( } status = wmi_unified_unregister_event_handler(wmi_handle, - wmi_p2p_noa_event_id); + WMI_P2P_NOA_EVENTID); - target_if_info("wmi unregister noa event handle, status:%d", + target_if_debug("wmi unregister noa event handle, status:%d", status); return status == 0 ? QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE; @@ -240,19 +251,80 @@ QDF_STATUS target_if_p2p_unregister_noa_event_handler( QDF_STATUS target_if_p2p_set_ps(struct wlan_objmgr_psoc *psoc, struct p2p_ps_config *ps_config) { - return QDF_STATUS_SUCCESS; + struct p2p_ps_params cmd; + QDF_STATUS status; + wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); + + target_if_debug("psoc:%p, vdev_id:%d, opp_ps:%d", psoc, + ps_config->vdev_id, ps_config->opp_ps); + + if (!wmi_handle) { + target_if_err("Invalid wmi handle"); + return QDF_STATUS_E_INVAL; + } + + if (!ps_config) { + target_if_err("ps config parameters is null"); + return QDF_STATUS_E_INVAL; + } + + cmd.opp_ps = ps_config->opp_ps; + cmd.ctwindow = ps_config->ct_window; + cmd.count = ps_config->count; + cmd.duration = ps_config->duration; + cmd.interval = ps_config->interval; + cmd.single_noa_duration = ps_config->single_noa_duration; + cmd.ps_selection = ps_config->ps_selection; + cmd.session_id = ps_config->vdev_id; + + if (ps_config->opp_ps) + status = wmi_unified_set_p2pgo_oppps_req(wmi_handle, + &cmd); + else + status = wmi_unified_set_p2pgo_noa_req_cmd(wmi_handle, + &cmd); + + if (status != QDF_STATUS_SUCCESS) + target_if_err("Failed to send set uapsd param, %d", + status); + + return status; } QDF_STATUS target_if_p2p_lo_start(struct wlan_objmgr_psoc *psoc, struct p2p_lo_start *lo_start) { - return QDF_STATUS_SUCCESS; + wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); + + target_if_debug("psoc:%p, vdev_id:%d", psoc, lo_start->vdev_id); + + if (!wmi_handle) { + target_if_err("Invalid wmi handle"); + return QDF_STATUS_E_INVAL; + } + + if (!lo_start) { + target_if_err("lo start parameters is null"); + return QDF_STATUS_E_INVAL; + } + + return wmi_unified_p2p_lo_start_cmd(wmi_handle, lo_start); } QDF_STATUS target_if_p2p_lo_stop(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id) { - return QDF_STATUS_SUCCESS; + wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); + + target_if_debug("psoc:%p, vdev_id:%d", psoc, vdev_id); + + if (!wmi_handle) { + target_if_err("Invalid wmi handle"); + return QDF_STATUS_E_INVAL; + } + + return wmi_unified_p2p_lo_stop_cmd(wmi_handle, + (uint8_t)vdev_id); } void target_if_p2p_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) diff --git a/wmi/inc/wmi_unified_api.h b/wmi/inc/wmi_unified_api.h index e44f5160d8..4fd9b981d4 100644 --- a/wmi/inc/wmi_unified_api.h +++ b/wmi/inc/wmi_unified_api.h @@ -46,6 +46,9 @@ #ifdef WLAN_PMO_ENABLE #include "wmi_unified_pmo_api.h" #endif +#ifdef CONVERGED_P2P_ENABLE +#include "wlan_p2p_public_struct.h" +#endif typedef qdf_nbuf_t wmi_buf_t; #define wmi_buf_data(_buf) qdf_nbuf_data(_buf) @@ -471,6 +474,13 @@ QDF_STATUS wmi_unified_set_p2pgo_oppps_req(void *wmi_hdl, QDF_STATUS wmi_unified_set_p2pgo_noa_req_cmd(void *wmi_hdl, struct p2p_ps_params *noa); +#ifdef CONVERGED_P2P_ENABLE +QDF_STATUS wmi_unified_p2p_lo_start_cmd(void *wmi_hdl, + struct p2p_lo_start *param); + +QDF_STATUS wmi_unified_p2p_lo_stop_cmd(void *wmi_hdl, uint8_t vdev_id); +#endif + QDF_STATUS wmi_unified_set_smps_params(void *wmi_hdl, uint8_t vdev_id, int value); @@ -1236,6 +1246,14 @@ QDF_STATUS wmi_extract_swba_tim_info(void *wmi_hdl, void *evt_buf, QDF_STATUS wmi_extract_swba_noa_info(void *wmi_hdl, void *evt_buf, uint32_t idx, wmi_host_p2p_noa_info *p2p_desc); +#ifdef CONVERGED_P2P_ENABLE +QDF_STATUS wmi_extract_p2p_lo_stop_ev_param(void *wmi_hdl, + void *evt_buf, struct p2p_lo_event *param); + +QDF_STATUS wmi_extract_p2p_noa_ev_param(void *wmi_hdl, + void *evt_buf, struct p2p_noa_info *param); +#endif + QDF_STATUS wmi_extract_peer_sta_ps_statechange_ev(void *wmi_hdl, void *evt_buf, wmi_host_peer_sta_ps_statechange_event *ev); diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index a748b8c588..760e7ee1f2 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -37,6 +37,10 @@ #include "qdf_atomic.h" #include "wlan_objmgr_psoc_service_ready_api.h" +#ifdef CONVERGED_P2P_ENABLE +#include +#endif + #define WMI_UNIFIED_MAX_EVENT 0x100 #ifdef CONFIG_MCL #define WMI_MAX_CMDS 256 @@ -300,6 +304,14 @@ QDF_STATUS (*send_set_p2pgo_oppps_req_cmd)(wmi_unified_t wmi_handle, QDF_STATUS (*send_set_p2pgo_noa_req_cmd)(wmi_unified_t wmi_handle, struct p2p_ps_params *noa); +#ifdef CONVERGED_P2P_ENABLE +QDF_STATUS (*send_p2p_lo_start_cmd)(wmi_unified_t wmi_handle, + struct p2p_lo_start *param); + +QDF_STATUS (*send_p2p_lo_stop_cmd)(wmi_unified_t wmi_handle, + uint8_t vdev_id); +#endif + QDF_STATUS (*send_set_smps_params_cmd)(wmi_unified_t wmi_handle, uint8_t vdev_id, int value); @@ -1095,6 +1107,14 @@ QDF_STATUS (*extract_swba_tim_info)(wmi_unified_t wmi_handle, void *evt_buf, QDF_STATUS (*extract_swba_noa_info)(wmi_unified_t wmi_handle, void *evt_buf, uint32_t idx, wmi_host_p2p_noa_info *p2p_desc); +#ifdef CONVERGED_P2P_ENABLE +QDF_STATUS (*extract_p2p_lo_stop_ev_param)(wmi_unified_t wmi_handle, + void *evt_buf, struct p2p_lo_event *param); + +QDF_STATUS (*extract_p2p_noa_ev_param)(wmi_unified_t wmi_handle, + void *evt_buf, struct p2p_noa_info *param); +#endif + QDF_STATUS (*extract_peer_sta_ps_statechange_ev)(wmi_unified_t wmi_handle, void *evt_buf, wmi_host_peer_sta_ps_statechange_event *ev); diff --git a/wmi/src/wmi_unified_api.c b/wmi/src/wmi_unified_api.c index bf9db91aa5..27650940ba 100644 --- a/wmi/src/wmi_unified_api.c +++ b/wmi/src/wmi_unified_api.c @@ -932,6 +932,55 @@ QDF_STATUS wmi_unified_set_p2pgo_noa_req_cmd(void *wmi_hdl, return QDF_STATUS_E_FAILURE; } +#ifdef CONVERGED_P2P_ENABLE +/** + * wmi_unified_p2p_lo_start_cmd() - send p2p lo start request to fw + * @wmi_hdl: wmi handle + * @param: p2p listen offload start parameters + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_p2p_lo_start_cmd(void *wmi_hdl, + struct p2p_lo_start *param) +{ + wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl; + + if (!wmi_handle) { + WMI_LOGE("wmi handle is null"); + return QDF_STATUS_E_INVAL; + } + + if (wmi_handle->ops->send_p2p_lo_start_cmd) + return wmi_handle->ops->send_p2p_lo_start_cmd(wmi_handle, + param); + + return QDF_STATUS_E_FAILURE; +} + +/** + * wmi_unified_p2p_lo_stop_cmd() - send p2p lo stop request to fw + * @wmi_hdl: wmi handle + * @vdev_id: vdev id + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_p2p_lo_stop_cmd(void *wmi_hdl, uint8_t vdev_id) +{ + wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl; + + if (!wmi_handle) { + WMI_LOGE("wmi handle is null"); + return QDF_STATUS_E_INVAL; + } + + if (wmi_handle->ops->send_p2p_lo_start_cmd) + return wmi_handle->ops->send_p2p_lo_stop_cmd(wmi_handle, + vdev_id); + + return QDF_STATUS_E_FAILURE; +} +#endif /* End of CONVERGED_P2P_ENABLE */ + /** * wmi_get_temperature() - get pdev temperature req * @wmi_hdl: wmi handle @@ -5461,6 +5510,58 @@ QDF_STATUS wmi_extract_swba_noa_info(void *wmi_hdl, void *evt_buf, return QDF_STATUS_E_FAILURE; } +#ifdef CONVERGED_P2P_ENABLE +/** + * wmi_extract_p2p_lo_stop_ev_param() - extract p2p lo stop param from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @param: Pointer to hold listen offload stop param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_extract_p2p_lo_stop_ev_param(void *wmi_hdl, void *evt_buf, + struct p2p_lo_event *param) +{ + wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl; + + if (!wmi_handle) { + WMI_LOGE("wmi handle is null"); + return QDF_STATUS_E_INVAL; + } + + if (wmi_handle->ops->extract_p2p_lo_stop_ev_param) + return wmi_handle->ops->extract_p2p_lo_stop_ev_param( + wmi_handle, evt_buf, param); + + return QDF_STATUS_E_FAILURE; +} + +/** + * wmi_extract_p2p_noa_ev_param() - extract p2p noa param from event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @param: Pointer to hold p2p noa param + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_extract_p2p_noa_ev_param(void *wmi_hdl, void *evt_buf, + struct p2p_noa_info *param) +{ + wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl; + + if (!wmi_handle) { + WMI_LOGE("wmi handle is null"); + return QDF_STATUS_E_INVAL; + } + + if (wmi_handle->ops->extract_p2p_noa_ev_param) + return wmi_handle->ops->extract_p2p_noa_ev_param( + wmi_handle, evt_buf, param); + + return QDF_STATUS_E_FAILURE; +} +#endif + /** * wmi_extract_peer_sta_ps_statechange_ev() - extract peer sta ps state * from event diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 0a1221e696..3178c3e8b2 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -31,6 +31,9 @@ #include "wmi_unified_priv.h" #include "wmi_version_whitelist.h" +#ifdef CONVERGED_P2P_ENABLE +#include "wlan_p2p_public_struct.h" +#endif /* copy_vdev_create_pdev_id() - copy pdev from host params to target command * buffer. @@ -2739,6 +2742,149 @@ end: return status; } +#ifdef CONVERGED_P2P_ENABLE +/** + * send_p2p_lo_start_cmd_tlv() - send p2p lo start request to fw + * @wmi_handle: wmi handle + * @param: p2p listen offload start parameters + * + * Return: QDF status + */ +static QDF_STATUS send_p2p_lo_start_cmd_tlv(wmi_unified_t wmi_handle, + struct p2p_lo_start *param) +{ + wmi_buf_t buf; + wmi_p2p_lo_start_cmd_fixed_param *cmd; + int32_t len = sizeof(*cmd); + uint8_t *buf_ptr; + QDF_STATUS status; + int device_types_len_aligned; + int probe_resp_len_aligned; + + if (!param) { + WMI_LOGE("lo start param is null"); + return QDF_STATUS_E_INVAL; + } + + WMI_LOGD("%s: vdev_id:%d", __func__, param->vdev_id); + + device_types_len_aligned = + qdf_roundup(param->dev_types_len, + sizeof(A_UINT32)); + probe_resp_len_aligned = + qdf_roundup(param->probe_resp_len, + sizeof(A_UINT32)); + + len += 2 * WMI_TLV_HDR_SIZE + device_types_len_aligned + + probe_resp_len_aligned; + + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) { + WMI_LOGE("%s: Failed to allocate memory for p2p lo start", + __func__); + return QDF_STATUS_E_NOMEM; + } + + cmd = (wmi_p2p_lo_start_cmd_fixed_param *)wmi_buf_data(buf); + buf_ptr = (uint8_t *) wmi_buf_data(buf); + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_p2p_lo_start_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_p2p_lo_start_cmd_fixed_param)); + + cmd->vdev_id = param->vdev_id; + cmd->ctl_flags = param->ctl_flags; + cmd->channel = param->freq; + cmd->period = param->period; + cmd->interval = param->interval; + cmd->count = param->count; + cmd->device_types_len = param->dev_types_len; + cmd->prob_resp_len = param->probe_resp_len; + + buf_ptr += sizeof(wmi_p2p_lo_start_cmd_fixed_param); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, + device_types_len_aligned); + buf_ptr += WMI_TLV_HDR_SIZE; + qdf_mem_copy(buf_ptr, param->device_types, + param->dev_types_len); + + buf_ptr += device_types_len_aligned; + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, + probe_resp_len_aligned); + buf_ptr += WMI_TLV_HDR_SIZE; + qdf_mem_copy(buf_ptr, param->probe_resp_tmplt, + param->probe_resp_len); + + WMI_LOGD("%s: Sending WMI_P2P_LO_START command, channel=%d, period=%d, interval=%d, count=%d", __func__, + cmd->channel, cmd->period, cmd->interval, cmd->count); + + status = wmi_unified_cmd_send(wmi_handle, + buf, len, + WMI_P2P_LISTEN_OFFLOAD_START_CMDID); + if (status != QDF_STATUS_SUCCESS) { + WMI_LOGE("%s: Failed to send p2p lo start: %d", + __func__, status); + wmi_buf_free(buf); + return status; + } + + WMI_LOGD("%s: Successfully sent WMI_P2P_LO_START", __func__); + + return QDF_STATUS_SUCCESS; +} + +/** + * send_p2p_lo_stop_cmd_tlv() - send p2p lo stop request to fw + * @wmi_handle: wmi handle + * @param: p2p listen offload stop parameters + * + * Return: QDF status + */ +static QDF_STATUS send_p2p_lo_stop_cmd_tlv(wmi_unified_t wmi_handle, + uint8_t vdev_id) +{ + wmi_buf_t buf; + wmi_p2p_lo_stop_cmd_fixed_param *cmd; + int32_t len; + QDF_STATUS status; + + WMI_LOGD("%s: vdev_id:%d", __func__, vdev_id); + + len = sizeof(*cmd); + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) { + qdf_print("%s: Failed to allocate memory for p2p lo stop", + __func__); + return QDF_STATUS_E_NOMEM; + } + cmd = (wmi_p2p_lo_stop_cmd_fixed_param *)wmi_buf_data(buf); + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_p2p_lo_stop_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_p2p_lo_stop_cmd_fixed_param)); + + cmd->vdev_id = vdev_id; + + WMI_LOGD("%s: Sending WMI_P2P_LO_STOP command", __func__); + + status = wmi_unified_cmd_send(wmi_handle, + buf, len, + WMI_P2P_LISTEN_OFFLOAD_STOP_CMDID); + if (status != QDF_STATUS_SUCCESS) { + WMI_LOGE("%s: Failed to send p2p lo stop: %d", + __func__, status); + wmi_buf_free(buf); + return status; + } + + WMI_LOGD("%s: Successfully sent WMI_P2P_LO_STOP", __func__); + + return QDF_STATUS_SUCCESS; +} +#endif /* End of CONVERGED_P2P_ENABLE */ + /** * send_get_temperature_cmd_tlv() - get pdev temperature req * @wmi_handle: wmi handle @@ -14659,6 +14805,118 @@ static QDF_STATUS extract_swba_noa_info_tlv(wmi_unified_t wmi_handle, return QDF_STATUS_SUCCESS; } +#ifdef CONVERGED_P2P_ENABLE +/** + * extract_p2p_noa_ev_param_tlv() - extract p2p noa information from event + * @wmi_handle: wmi handle + * @param evt_buf: pointer to event buffer + * @param param: Pointer to hold p2p noa info + * + * Return: QDF_STATUS_SUCCESS for success or error code + */ +static QDF_STATUS extract_p2p_noa_ev_param_tlv( + wmi_unified_t wmi_handle, void *evt_buf, + struct p2p_noa_info *param) +{ + WMI_P2P_NOA_EVENTID_param_tlvs *param_tlvs; + wmi_p2p_noa_event_fixed_param *fixed_param; + uint8_t i; + wmi_p2p_noa_info *wmi_noa_info; + uint8_t *buf_ptr; + uint32_t descriptors; + + param_tlvs = (WMI_P2P_NOA_EVENTID_param_tlvs *) evt_buf; + if (!param_tlvs) { + WMI_LOGE("%s: Invalid P2P NoA event buffer", __func__); + return QDF_STATUS_E_INVAL; + } + + if (!param) { + WMI_LOGE("noa information param is null"); + return QDF_STATUS_E_INVAL; + } + + fixed_param = param_tlvs->fixed_param; + buf_ptr = (uint8_t *) fixed_param; + buf_ptr += sizeof(wmi_p2p_noa_event_fixed_param); + wmi_noa_info = (wmi_p2p_noa_info *) (buf_ptr); + + if (!WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(wmi_noa_info)) { + WMI_LOGE("%s: noa attr is not modified", __func__); + return QDF_STATUS_E_INVAL; + } + + param->vdev_id = fixed_param->vdev_id; + param->index = + (uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(wmi_noa_info); + param->opps_ps = + (uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(wmi_noa_info); + param->ct_window = + (uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(wmi_noa_info); + descriptors = WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(wmi_noa_info); + param->num_desc = (uint8_t) descriptors; + + WMI_LOGD("%s:index %u, opps_ps %u, ct_window %u, num_descriptors = %u", __func__, + param->index, param->opps_ps, param->ct_window, + param->num_desc); + for (i = 0; i < param->num_desc; i++) { + param->noa_desc[i].type_count = + (uint8_t) wmi_noa_info->noa_descriptors[i]. + type_count; + param->noa_desc[i].duration = + wmi_noa_info->noa_descriptors[i].duration; + param->noa_desc[i].interval = + wmi_noa_info->noa_descriptors[i].interval; + param->noa_desc[i].start_time = + wmi_noa_info->noa_descriptors[i].start_time; + WMI_LOGD("%s:NoA descriptor[%d] type_count %u, duration %u, interval %u, start_time = %u", + __func__, i, param->noa_desc[i].type_count, + param->noa_desc[i].duration, + param->noa_desc[i].interval, + param->noa_desc[i].start_time); + } + + return QDF_STATUS_SUCCESS; +} + +/** + * extract_p2p_lo_stop_ev_param_tlv() - extract p2p lo stop + * information from event + * @wmi_handle: wmi handle + * @param evt_buf: pointer to event buffer + * @param param: Pointer to hold p2p lo stop event information + * + * Return: QDF_STATUS_SUCCESS for success or error code + */ +static QDF_STATUS extract_p2p_lo_stop_ev_param_tlv( + wmi_unified_t wmi_handle, void *evt_buf, + struct p2p_lo_event *param) +{ + WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *param_tlvs; + wmi_p2p_lo_stopped_event_fixed_param *lo_param; + + param_tlvs = (WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *) + evt_buf; + if (!param_tlvs) { + WMI_LOGE("%s: Invalid P2P lo stop event buffer", __func__); + return QDF_STATUS_E_INVAL; + } + + if (!param) { + WMI_LOGE("lo stop event param is null"); + return QDF_STATUS_E_INVAL; + } + + lo_param = param_tlvs->fixed_param; + param->vdev_id = lo_param->vdev_id; + param->reason_code = lo_param->reason; + WMI_LOGD("%s: vdev_id:%d, reason:%d", __func__, + param->vdev_id, param->reason_code); + + return QDF_STATUS_SUCCESS; +} +#endif /* End of CONVERGED_P2P_ENABLE */ + /** * extract_peer_sta_kickout_ev_tlv() - extract peer sta kickout event * @wmi_handle: wmi handle @@ -15809,6 +16067,10 @@ struct wmi_ops tlv_ops = { .send_get_temperature_cmd = send_get_temperature_cmd_tlv, .send_set_p2pgo_oppps_req_cmd = send_set_p2pgo_oppps_req_cmd_tlv, .send_set_p2pgo_noa_req_cmd = send_set_p2pgo_noa_req_cmd_tlv, +#ifdef CONVERGED_P2P_ENABLE + .send_p2p_lo_start_cmd = send_p2p_lo_start_cmd_tlv, + .send_p2p_lo_stop_cmd = send_p2p_lo_stop_cmd_tlv, +#endif .send_set_smps_params_cmd = send_set_smps_params_cmd_tlv, .send_set_mimops_cmd = send_set_mimops_cmd_tlv, .send_ocb_set_utc_time_cmd = send_ocb_set_utc_time_cmd_tlv, @@ -16039,6 +16301,11 @@ struct wmi_ops tlv_ops = { .extract_swba_vdev_map = extract_swba_vdev_map_tlv, .extract_swba_tim_info = extract_swba_tim_info_tlv, .extract_swba_noa_info = extract_swba_noa_info_tlv, +#ifdef CONVERGED_P2P_ENABLE + .extract_p2p_noa_ev_param = extract_p2p_noa_ev_param_tlv, + .extract_p2p_lo_stop_ev_param = + extract_p2p_lo_stop_ev_param_tlv, +#endif .extract_peer_sta_kickout_ev = extract_peer_sta_kickout_ev_tlv, .extract_all_stats_count = extract_all_stats_counts_tlv, .extract_pdev_stats = extract_pdev_stats_tlv,