From 950deb641d97786ac2345e344c5c335810ed1294 Mon Sep 17 00:00:00 2001 From: Pragaspathi Thilagaraj Date: Fri, 23 Oct 2020 19:03:39 +0530 Subject: [PATCH] qcacld-3.0: Add support for peer create confirmation event Firmware sends peer create confirmation to detect duplicate peer on other vdev. If the status field in the wmi_peer_create_conf_event_fixed_param is 0, peer creation is successful. Add support to handle the peer create confirmation command for sta mode. For roaming scenario, the peer will be internally created by the firmware, so bail out after creating object manager peer/datapath peer without sending the peer create command similar as the current implementation. For SAP/P2P Go mode the legacy peer create path will be used. Proceed to do post linkstate change if status is success, else do vdev stop and indicate failure to upper layers Change-Id: I0abbd70dd509f2b9afa8d4d7db1774e289d1e021 CRs-Fixed: 2747870 --- .../mlme/dispatcher/inc/wlan_mlme_api.h | 9 - .../dispatcher/inc/wlan_mlme_public_struct.h | 2 - .../mlme/dispatcher/src/wlan_mlme_api.c | 12 - core/mac/inc/sir_api.h | 2 + core/mac/src/include/sir_params.h | 2 + .../src/pe/lim/lim_process_mlm_req_messages.c | 36 +-- core/mac/src/pe/lim/lim_types.h | 16 ++ .../src/sys/legacy/src/utils/src/mac_trace.c | 2 + core/wma/inc/wma.h | 16 +- core/wma/inc/wma_internal.h | 16 +- core/wma/inc/wma_types.h | 3 +- core/wma/src/wma_dev_if.c | 235 ++++++++++++++++-- core/wma/src/wma_main.c | 12 +- core/wma/src/wma_scan_roam.c | 4 +- 14 files changed, 279 insertions(+), 88 deletions(-) diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h index 6f733aaf1a..0ee18479cc 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_api.h @@ -823,15 +823,6 @@ QDF_STATUS wlan_mlme_get_bigtk_support(struct wlan_objmgr_psoc *psoc, */ bool wlan_mlme_get_host_scan_abort_support(struct wlan_objmgr_psoc *psoc); -/** - * wlan_mlme_get_peer_create_conf_support - Get if the firmware supports - * peer create confirm event - * @psoc: PSOC object pointer - * - * Return: True if capability is supported, else False - */ -bool wlan_mlme_get_peer_create_conf_support(struct wlan_objmgr_psoc *psoc); - /** * wlan_mlme_get_dual_sta_roam_support - Get support for dual sta roaming * feature diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index 6fb06f46a8..c7ec17b323 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -1272,7 +1272,6 @@ struct wlan_mlme_ratemask { * @bigtk_support: Whether BIGTK is supported or not * @stop_all_host_scan_support: Target capability that indicates if the target * supports stop all host scan request type. - * @peer_create_conf_support: Peer create confirmation command support * @dual_sta_roam_fw_support: Firmware support for dual sta roaming feature * @sae_connect_retries: sae connect retry bitmask * @wls_6ghz_capable: wifi location service(WLS) is 6ghz capable @@ -1315,7 +1314,6 @@ struct wlan_mlme_generic { uint8_t dfs_chan_ageout_time; bool bigtk_support; bool stop_all_host_scan_support; - bool peer_create_conf_support; bool dual_sta_roam_fw_support; uint32_t sae_connect_retries; bool wls_6ghz_capable; diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c index 8256c6c023..efc3da0ba1 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_api.c @@ -472,8 +472,6 @@ wlan_mlme_update_cfg_with_tgt_caps(struct wlan_objmgr_psoc *psoc, mlme_obj->cfg.gen.bigtk_support = tgt_caps->bigtk_support; mlme_obj->cfg.gen.stop_all_host_scan_support = tgt_caps->stop_all_host_scan_support; - mlme_obj->cfg.gen.peer_create_conf_support = - tgt_caps->peer_create_conf_support; mlme_obj->cfg.gen.dual_sta_roam_fw_support = tgt_caps->dual_sta_roam_fw_support; @@ -2097,16 +2095,6 @@ bool wlan_mlme_get_host_scan_abort_support(struct wlan_objmgr_psoc *psoc) return mlme_obj->cfg.gen.stop_all_host_scan_support; } -bool wlan_mlme_get_peer_create_conf_support(struct wlan_objmgr_psoc *psoc) -{ - struct wlan_mlme_psoc_ext_obj *mlme_obj = mlme_get_psoc_ext_obj(psoc); - - if (!mlme_obj) - return false; - - return mlme_obj->cfg.gen.peer_create_conf_support; -} - bool wlan_mlme_get_dual_sta_roam_support(struct wlan_objmgr_psoc *psoc) { struct wlan_mlme_psoc_ext_obj *mlme_obj = mlme_get_psoc_ext_obj(psoc); diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 2fe8470c1c..11edd1506d 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -81,9 +81,11 @@ typedef uint8_t tSirVersionString[SIR_VERSION_STRING_LEN]; #ifdef FEATURE_RUNTIME_PM /* Add extra PMO_RESUME_TIMEOUT for runtime PM resume timeout */ +#define SIR_PEER_CREATE_RESPONSE_TIMEOUT (4000 + PMO_RESUME_TIMEOUT) #define SIR_DELETE_STA_TIMEOUT (4000 + PMO_RESUME_TIMEOUT) #define SIR_VDEV_PLCY_MGR_TIMEOUT (2000 + PMO_RESUME_TIMEOUT) #else +#define SIR_PEER_CREATE_RESPONSE_TIMEOUT (4000) #define SIR_DELETE_STA_TIMEOUT (4000) /* 4 seconds */ #define SIR_VDEV_PLCY_MGR_TIMEOUT (2000) #endif diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h index dc29c7f8c7..ad42606244 100644 --- a/core/mac/src/include/sir_params.h +++ b/core/mac/src/include/sir_params.h @@ -663,6 +663,8 @@ enum halmsgtype { SIR_HAL_TWT_DEL_DIALOG_REQUEST = (SIR_HAL_ITC_MSG_TYPES_BEGIN + 418), SIR_HAL_TWT_PAUSE_DIALOG_REQUEST = (SIR_HAL_ITC_MSG_TYPES_BEGIN + 419), SIR_HAL_TWT_RESUME_DIALOG_REQUEST = (SIR_HAL_ITC_MSG_TYPES_BEGIN + 420), + SIR_HAL_PEER_CREATE_REQ = (SIR_HAL_ITC_MSG_TYPES_BEGIN + 421), + SIR_HAL_MSG_TYPES_END = (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF), }; diff --git a/core/mac/src/pe/lim/lim_process_mlm_req_messages.c b/core/mac/src/pe/lim/lim_process_mlm_req_messages.c index 62dfcfdb6f..60d28d279d 100644 --- a/core/mac/src/pe/lim/lim_process_mlm_req_messages.c +++ b/core/mac/src/pe/lim/lim_process_mlm_req_messages.c @@ -325,33 +325,21 @@ end: lim_send_start_bss_confirm(mac_ctx, &mlm_start_cnf); } -/** - * lim_post_join_set_link_state_callback()- registered callback to perform post - * peer creation operations - * - * @mac: pointer to global mac structure - * @callback_arg: registered callback argument - * @status: peer creation status - * - * this is registered callback function during association to perform - * post peer creation operation based on the peer creation status - * - * Return: none - */ -static void lim_post_join_set_link_state_callback( - struct mac_context *mac, - struct pe_session *session_entry, QDF_STATUS status) +void +lim_post_join_set_link_state_callback(struct mac_context *mac, uint32_t vdev_id, + QDF_STATUS status) { tLimMlmJoinCnf mlm_join_cnf; + struct pe_session *session_entry; + session_entry = pe_find_session_by_vdev_id(mac, vdev_id); if (!session_entry) { - pe_err("sessionId is NULL"); + pe_err("vdev_id:%d PE session is NULL", vdev_id); return; } if (QDF_IS_STATUS_ERROR(status)) { - pe_err("failed to find pe session for session id:%d", - session_entry->peSessionId); + pe_err("vdev%d: Failed to create peer", session_entry->vdev_id); goto failure; } @@ -359,8 +347,7 @@ static void lim_post_join_set_link_state_callback( * store the channel switch session_entry in the lim * global variable */ - session_entry->channelChangeReasonCode = - LIM_SWITCH_CHANNEL_JOIN; + session_entry->channelChangeReasonCode = LIM_SWITCH_CHANNEL_JOIN; session_entry->pLimMlmReassocRetryReq = NULL; lim_send_switch_chnl_params(mac, session_entry); @@ -395,18 +382,13 @@ static void lim_process_mlm_post_join_suspend_link(struct mac_context *mac_ctx, struct pe_session *session) { - QDF_STATUS status; - lim_deactivate_and_change_timer(mac_ctx, eLIM_JOIN_FAIL_TIMER); /* assign appropriate sessionId to the timer object */ mac_ctx->lim.lim_timers.gLimJoinFailureTimer.sessionId = session->peSessionId; - status = wma_add_bss_peer_sta(session->vdev_id, session->bssId); - lim_post_join_set_link_state_callback(mac_ctx, session, status); - - return; + wma_add_bss_peer_sta(session->vdev_id, session->bssId); } /** diff --git a/core/mac/src/pe/lim/lim_types.h b/core/mac/src/pe/lim/lim_types.h index fed50a994e..a5266d1329 100644 --- a/core/mac/src/pe/lim/lim_types.h +++ b/core/mac/src/pe/lim/lim_types.h @@ -1367,6 +1367,22 @@ void lim_process_mlm_start_req(struct mac_context *mac_ctx, void lim_process_mlm_join_req(struct mac_context *mac_ctx, tLimMlmJoinReq *mlm_join_req); +/** + * lim_post_join_set_link_state_callback()- registered callback to perform post + * peer creation operations + * @mac: pointer to global mac structure + * @callback_arg: registered callback argument + * @status: peer creation status + * + * This is registered callback function during association to perform + * post peer creation operation based on the peer creation status + * + * Return: none + */ +void +lim_post_join_set_link_state_callback(struct mac_context *mac, uint32_t vdev_id, + QDF_STATUS status); + /* * lim_process_mlm_deauth_req() - This function is called to process * MLM_DEAUTH_REQ message from SME diff --git a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c index 406e64f6ce..4be80b5f40 100644 --- a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c +++ b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c @@ -39,6 +39,7 @@ #include "qdf_mem.h" #include "qdf_trace.h" #include "wma_if.h" +#include "wma.h" /** * mac_trace_get_neighbour_roam_state() - Get the neighbor roam state @@ -607,6 +608,7 @@ uint8_t *mac_trace_get_wma_msg_string(uint16_t wma_msg) CASE_RETURN_STRING(WMA_GET_RCPI_REQ); CASE_RETURN_STRING(WMA_SET_DBS_SCAN_SEL_CONF_PARAMS); CASE_RETURN_STRING(WMA_GET_ROAM_SCAN_STATS); + CASE_RETURN_STRING(WMA_PEER_CREATE_RESPONSE); #ifdef FW_THERMAL_THROTTLE_SUPPORT CASE_RETURN_STRING(WMA_SET_THERMAL_THROTTLE_CFG); CASE_RETURN_STRING(WMA_SET_THERMAL_MGMT); diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index b031717e5f..61fb0ef7d7 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -166,6 +166,9 @@ #define WMA_PDEV_SET_HW_MODE_RESP 0x06 #define WMA_PDEV_MAC_CFG_RESP 0x07 +#define WMA_PEER_CREATE_RESPONSE 0x08 +#define WMA_PEER_CREATE_RESPONSE_TIMEOUT SIR_PEER_CREATE_RESPONSE_TIMEOUT + /* FW response timeout values in milli seconds */ #define WMA_VDEV_PLCY_MGR_TIMEOUT SIR_VDEV_PLCY_MGR_TIMEOUT #define WMA_VDEV_HW_MODE_REQUEST_TIMEOUT WMA_VDEV_PLCY_MGR_TIMEOUT @@ -1641,7 +1644,18 @@ void wma_process_set_pdev_vht_ie_req(tp_wma_handle wma, QDF_STATUS wma_remove_peer(tp_wma_handle wma, uint8_t *mac_addr, uint8_t vdev_id, bool no_fw_peer_delete); -QDF_STATUS wma_create_peer(tp_wma_handle wma, uint8_t peer_addr[6], +/** + * wma_create_peer() - Call wma_add_peer() to send peer create command to fw + * and setup cdp peer + * @wma: wma handle + * @peer_addr: peer mac address + * @peer_type: peer type + * @vdev_id: vdev id + * + * Return: QDF_STATUS + */ +QDF_STATUS wma_create_peer(tp_wma_handle wma, + uint8_t peer_addr[QDF_MAC_ADDR_SIZE], u_int32_t peer_type, u_int8_t vdev_id); QDF_STATUS wma_peer_unmap_conf_cb(uint8_t vdev_id, diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index 9553f54d20..936a6db91b 100644 --- a/core/wma/inc/wma_internal.h +++ b/core/wma/inc/wma_internal.h @@ -630,10 +630,6 @@ QDF_STATUS wma_remove_peer(tp_wma_handle wma, uint8_t *mac_addr, QDF_STATUS wma_peer_unmap_conf_send(tp_wma_handle wma, struct send_peer_unmap_conf_params *msg); -QDF_STATUS wma_create_peer(tp_wma_handle wma, - uint8_t peer_addr[QDF_MAC_ADDR_SIZE], - uint32_t peer_type, uint8_t vdev_id); - /** * wma_send_del_bss_response() - send delete bss resp * @wma: wma handle @@ -1377,6 +1373,18 @@ QDF_STATUS wma_process_set_ie_info(tp_wma_handle wma, int wma_peer_assoc_conf_handler(void *handle, uint8_t *cmd_param_info, uint32_t len); +/** + * wma_peer_create_confirm_handler - Handle peer create confirmation + * result + * @handle: wma_handle + * @evt_param_info: event data + * @len: event length + * + * Return: 0 on success. Error value on failure + */ +int wma_peer_create_confirm_handler(void *handle, uint8_t *evt_param_info, + uint32_t len); + int wma_peer_delete_handler(void *handle, uint8_t *cmd_param_info, uint32_t len); void wma_remove_req(tp_wma_handle wma, uint8_t vdev_id, diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h index d9fc392019..5aa3061228 100644 --- a/core/wma/inc/wma_types.h +++ b/core/wma/inc/wma_types.h @@ -108,7 +108,6 @@ /* WMA Messages */ - enum wmamsgtype { WMA_MSG_TYPES_BEGIN = SIR_HAL_MSG_TYPES_BEGIN, WMA_ITC_MSG_TYPES_BEGIN = SIR_HAL_ITC_MSG_TYPES_BEGIN, @@ -155,7 +154,6 @@ enum wmamsgtype { WMA_TIMER_TRAFFIC_ACTIVITY_REQ = SIR_HAL_TIMER_TRAFFIC_ACTIVITY_REQ, WMA_TIMER_ADC_RSSI_STATS = SIR_HAL_TIMER_ADC_RSSI_STATS, WMA_TIMER_TRAFFIC_STATS_IND = SIR_HAL_TRAFFIC_STATS_IND, - #ifdef WLAN_FEATURE_11W WMA_EXCLUDE_UNENCRYPTED_IND = SIR_HAL_EXCLUDE_UNENCRYPTED_IND, #endif @@ -440,6 +438,7 @@ enum wmamsgtype { WMA_TWT_DEL_DIALOG_REQUEST = SIR_HAL_TWT_DEL_DIALOG_REQUEST, WMA_TWT_PAUSE_DIALOG_REQUEST = SIR_HAL_TWT_PAUSE_DIALOG_REQUEST, WMA_TWT_RESUME_DIALOG_REQUEST = SIR_HAL_TWT_RESUME_DIALOG_REQUEST, + WMA_PEER_CREATE_REQ = SIR_HAL_PEER_CREATE_REQ, }; #define WMA_DATA_STALL_TRIGGER 6 diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 7bb2cae978..592f6f0f0b 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -1761,7 +1761,21 @@ static struct wlan_objmgr_peer *wma_create_objmgr_peer(tp_wma_handle wma, } /** - * wma_create_peer() - send peer create command to fw + * wma_increment_peer_count() - Increment the vdev peer + * count + * @wma: wma handle + * @vdev_id: vdev id + * + * Return: None + */ +static void +wma_increment_peer_count(tp_wma_handle wma, uint8_t vdev_id) +{ + wma->interfaces[vdev_id].peer_count++; +} + +/** + * wma_add_peer() - send peer create command to fw * @wma: wma handle * @peer_addr: peer mac addr * @peer_type: peer type @@ -1769,12 +1783,12 @@ static struct wlan_objmgr_peer *wma_create_objmgr_peer(tp_wma_handle wma, * * Return: QDF status */ -QDF_STATUS wma_create_peer(tp_wma_handle wma, - uint8_t peer_addr[QDF_MAC_ADDR_SIZE], - uint32_t peer_type, uint8_t vdev_id) +static +QDF_STATUS wma_add_peer(tp_wma_handle wma, + uint8_t peer_addr[QDF_MAC_ADDR_SIZE], + uint32_t peer_type, uint8_t vdev_id) { struct peer_create_params param = {0}; - uint8_t *mac_addr_raw; void *dp_soc = cds_get_context(QDF_MODULE_ID_SOC); struct wlan_objmgr_psoc *psoc = wma->psoc; target_resource_config *wlan_res_cfg; @@ -1792,25 +1806,25 @@ QDF_STATUS wma_create_peer(tp_wma_handle wma, return QDF_STATUS_E_INVAL; } - if (++wma->interfaces[vdev_id].peer_count > + if (wma->interfaces[vdev_id].peer_count >= wlan_res_cfg->num_peers) { wma_err("the peer count exceeds the limit %d", - wma->interfaces[vdev_id].peer_count - 1); - goto err; + wma->interfaces[vdev_id].peer_count); + return QDF_STATUS_E_FAILURE; } if (!dp_soc) - goto err; + return QDF_STATUS_E_FAILURE; if (qdf_is_macaddr_group((struct qdf_mac_addr *)peer_addr) || qdf_is_macaddr_zero((struct qdf_mac_addr *)peer_addr)) { wma_err("Invalid peer address received reject it"); - goto err; + return QDF_STATUS_E_FAILURE; } obj_peer = wma_create_objmgr_peer(wma, vdev_id, peer_addr, peer_type); if (!obj_peer) - goto err; + return QDF_STATUS_E_FAILURE; /* The peer object should be created before sending the WMI peer * create command to firmware. This is to prevent a race condition @@ -1822,7 +1836,7 @@ QDF_STATUS wma_create_peer(tp_wma_handle wma, wma_err("Unable to attach peer "QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(peer_addr)); wlan_objmgr_peer_obj_delete(obj_peer); - goto err; + return QDF_STATUS_E_FAILURE; } if (peer_type == WMI_PEER_TYPE_TDLS) @@ -1831,8 +1845,7 @@ QDF_STATUS wma_create_peer(tp_wma_handle wma, if (MLME_IS_ROAM_SYNCH_IN_PROGRESS(wma->psoc, vdev_id)) { wma_debug("LFR3: Created peer "QDF_MAC_ADDR_FMT" vdev_id %d, peer_count %d", QDF_MAC_ADDR_REF(peer_addr), vdev_id, - wma->interfaces[vdev_id].peer_count); - cdp_peer_setup(dp_soc, vdev_id, peer_addr); + wma->interfaces[vdev_id].peer_count + 1); return QDF_STATUS_SUCCESS; } param.peer_addr = peer_addr; @@ -1851,27 +1864,106 @@ QDF_STATUS wma_create_peer(tp_wma_handle wma, dp_soc, vdev_id, peer_addr, 1 << CDP_PEER_DO_NOT_START_UNMAP_TIMER); wlan_objmgr_peer_obj_delete(obj_peer); - goto err; + + return QDF_STATUS_E_FAILURE; } wma_debug("Created peer peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d, peer_count - %d", QDF_MAC_ADDR_REF(peer_addr), vdev_id, - wma->interfaces[vdev_id].peer_count); + wma->interfaces[vdev_id].peer_count + 1); wlan_roam_debug_log(vdev_id, DEBUG_PEER_CREATE_SEND, DEBUG_INVALID_PEER_ID, peer_addr, NULL, 0, 0); - cdp_peer_setup(dp_soc, vdev_id, peer_addr); - - mac_addr_raw = cdp_get_vdev_mac_addr(dp_soc, vdev_id); - if (!mac_addr_raw) { - wma_err("peer mac addr is NULL"); - return QDF_STATUS_E_FAULT; - } return QDF_STATUS_SUCCESS; -err: - wma->interfaces[vdev_id].peer_count--; - return QDF_STATUS_E_FAILURE; +} + +QDF_STATUS wma_create_peer(tp_wma_handle wma, + uint8_t peer_addr[QDF_MAC_ADDR_SIZE], + uint32_t peer_type, uint8_t vdev_id) +{ + void *dp_soc = cds_get_context(QDF_MODULE_ID_SOC); + QDF_STATUS status; + + if (!dp_soc) + return QDF_STATUS_E_FAILURE; + + status = wma_add_peer(wma, peer_addr, peer_type, vdev_id); + if (QDF_IS_STATUS_ERROR(status)) + return status; + + wma_increment_peer_count(wma, vdev_id); + cdp_peer_setup(dp_soc, vdev_id, peer_addr); + + return QDF_STATUS_SUCCESS; +} + +/** + * wma_create_sta_mode_bss_peer() - send peer create command to fw + * and start peer create response timer + * @wma: wma handle + * @peer_addr: peer mac address + * @peer_type: peer type + * @vdev_id: vdev id + * + * Return: QDF_STATUS + */ +static QDF_STATUS +wma_create_sta_mode_bss_peer(tp_wma_handle wma, + uint8_t peer_addr[QDF_MAC_ADDR_SIZE], + uint32_t peer_type, uint8_t vdev_id) +{ + struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE); + struct wma_target_req *msg = NULL; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + bool is_tgt_peer_conf_supported = false; + + if (!mac) { + wma_err("vdev%d: Mac context is null", vdev_id); + return status; + } + + /* + * If fw doesn't advertise peer create confirm event support, + * use the legacy peer create API + */ + is_tgt_peer_conf_supported = + wlan_psoc_nif_fw_ext_cap_get(wma->psoc, + WLAN_SOC_F_PEER_CREATE_RESP); + if (!is_tgt_peer_conf_supported) { + status = wma_create_peer(wma, peer_addr, peer_type, vdev_id); + goto end; + } + + wma_acquire_wakelock(&wma->wmi_cmd_rsp_wake_lock, + WMA_PEER_CREATE_RESPONSE_TIMEOUT); + + status = wma_add_peer(wma, peer_addr, peer_type, vdev_id); + if (QDF_IS_STATUS_ERROR(status)) { + wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock); + goto end; + } + + wma_increment_peer_count(wma, vdev_id); + + msg = wma_fill_hold_req(wma, vdev_id, WMA_PEER_CREATE_REQ, + WMA_PEER_CREATE_RESPONSE, (void *)peer_addr, + WMA_PEER_CREATE_RESPONSE_TIMEOUT); + if (!msg) { + wma_err("vdev:%d failed to fill peer create req", vdev_id); + wma_remove_req(wma, vdev_id, WMA_PEER_CREATE_RESPONSE); + wma_remove_peer(wma, peer_addr, vdev_id, false); + wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock); + status = QDF_STATUS_E_FAILURE; + goto end; + } + + return status; + +end: + lim_post_join_set_link_state_callback(mac, vdev_id, status); + + return status; } /** @@ -2827,6 +2919,78 @@ free_req_msg: return status; } +int wma_peer_create_confirm_handler(void *handle, uint8_t *evt_param_info, + uint32_t len) +{ + tp_wma_handle wma = (tp_wma_handle)handle; + wmi_peer_create_conf_event_fixed_param *peer_create_rsp; + WMI_PEER_CREATE_CONF_EVENTID_param_tlvs *param_buf; + struct wma_target_req *req_msg = NULL; + struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE); + void *dp_soc = cds_get_context(QDF_MODULE_ID_SOC); + struct qdf_mac_addr peer_mac; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + int ret = -EINVAL; + + param_buf = (WMI_PEER_CREATE_CONF_EVENTID_param_tlvs *)evt_param_info; + if (!param_buf) { + wma_err("Invalid peer create conf evt buffer"); + return -EINVAL; + } + + peer_create_rsp = param_buf->fixed_param; + + WMI_MAC_ADDR_TO_CHAR_ARRAY(&peer_create_rsp->peer_macaddr, + peer_mac.bytes); + if (qdf_is_macaddr_zero(&peer_mac) || + qdf_is_macaddr_broadcast(&peer_mac) || + qdf_is_macaddr_group(&peer_mac)) { + wma_err("Invalid bssid"); + return -EINVAL; + } + + wma_debug("vdev:%d Peer create confirm for bssid: " QDF_MAC_ADDR_FMT, + peer_create_rsp->vdev_id, QDF_MAC_ADDR_REF(peer_mac.bytes)); + req_msg = wma_find_remove_req_msgtype(wma, peer_create_rsp->vdev_id, + WMA_PEER_CREATE_REQ); + if (!req_msg) { + wma_err("vdev:%d Failed to lookup peer create request message", + peer_create_rsp->vdev_id); + return -EINVAL; + } + + wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock); + + qdf_mc_timer_stop(&req_msg->event_timeout); + qdf_mc_timer_destroy(&req_msg->event_timeout); + qdf_mem_free(req_msg); + + if (!peer_create_rsp->status) { + if (!dp_soc) { + wma_err("DP SOC context is NULL"); + goto fail; + } + + cdp_peer_setup(dp_soc, peer_create_rsp->vdev_id, + peer_mac.bytes); + + status = QDF_STATUS_SUCCESS; + ret = 0; + } + +fail: + if (QDF_IS_STATUS_ERROR(status)) + wma_remove_peer(wma, peer_mac.bytes, peer_create_rsp->vdev_id, + (peer_create_rsp->status > 0) ? true : false); + + if (mac) + lim_post_join_set_link_state_callback(mac, + peer_create_rsp->vdev_id, + status); + + return ret; +} + /** * wma_peer_delete_handler() - peer delete response handler * @handle: wma handle @@ -2937,6 +3101,7 @@ void wma_hold_req_timer(void *data) { tp_wma_handle wma; struct wma_target_req *tgt_req = (struct wma_target_req *)data; + struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE); QDF_STATUS status; wma = cds_get_context(QDF_MODULE_ID_WMA); @@ -3062,6 +3227,21 @@ void wma_hold_req_timer(void *data) resp->status = SET_HW_MODE_STATUS_ECANCELED; wma_send_msg_high_priority(wma, SIR_HAL_PDEV_MAC_CFG_RESP, resp, 0); + } else if ((tgt_req->msg_type == WMA_PEER_CREATE_REQ) && + (tgt_req->type == WMA_PEER_CREATE_RESPONSE)) { + if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) + wma_trigger_recovery_assert_on_fw_timeout( + WMA_PEER_CREATE_RESPONSE, + WMA_PEER_CREATE_RESPONSE_TIMEOUT); + + wma_remove_peer(wma, (uint8_t *)tgt_req->user_data, + tgt_req->vdev_id, false); + if (!mac) + goto timer_destroy; + + lim_post_join_set_link_state_callback(mac, tgt_req->vdev_id, + QDF_STATUS_E_FAILURE); + } else { wma_err("Unhandled timeout for msg_type:%d and type:%d", tgt_req->msg_type, tgt_req->type); @@ -4988,7 +5168,8 @@ QDF_STATUS wma_add_bss_peer_sta(uint8_t vdev_id, uint8_t *bssid) if (!wma) goto err; - status = wma_create_peer(wma, bssid, WMI_PEER_TYPE_DEFAULT, vdev_id); + status = wma_create_sta_mode_bss_peer(wma, bssid, WMI_PEER_TYPE_DEFAULT, + vdev_id); err: return status; } diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index da873ee793..1cd92c362b 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -3317,6 +3317,10 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, wmi_peer_assoc_conf_event_id, wma_peer_assoc_conf_handler, WMA_RX_SERIALIZER_CTX); + wmi_unified_register_event_handler(wma_handle->wmi_handle, + wmi_peer_create_conf_event_id, + wma_peer_create_confirm_handler, + WMA_RX_SERIALIZER_CTX); wmi_unified_register_event_handler(wma_handle->wmi_handle, wmi_peer_delete_response_event_id, wma_peer_delete_handler, @@ -5378,9 +5382,6 @@ static void wma_update_mlme_related_tgt_caps(struct wlan_objmgr_psoc *psoc, mlme_tgt_cfg.stop_all_host_scan_support = wmi_service_enabled(wmi_handle, wmi_service_host_scan_stop_vdev_all); - mlme_tgt_cfg.peer_create_conf_support = - wmi_service_enabled(wmi_handle, - wmi_service_peer_create_conf); mlme_tgt_cfg.dual_sta_roam_fw_support = wmi_service_enabled(wmi_handle, wmi_service_dual_sta_roam_support); @@ -5472,6 +5473,11 @@ static int wma_update_hdd_cfg(tp_wma_handle wma_handle) } wma_update_mlme_related_tgt_caps(wma_handle->psoc, wmi_handle); + + if (wmi_service_enabled(wmi_handle, wmi_service_peer_create_conf)) + wlan_psoc_nif_fw_ext_cap_set(wma_handle->psoc, + WLAN_SOC_F_PEER_CREATE_RESP); + qdf_mem_zero(&tgt_cfg, sizeof(struct wma_tgt_cfg)); tgt_cfg.sub_20_support = wma_handle->sub_20_support; diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index c4edcc4ae1..297ea0547a 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -1118,7 +1118,9 @@ wma_roam_update_vdev(tp_wma_handle wma, wma_delete_sta(wma, del_sta_params); wma_delete_bss(wma, vdev_id); - wma_add_bss_peer_sta(vdev_id, roam_synch_ind_ptr->bssid.bytes); + wma_create_peer(wma, roam_synch_ind_ptr->bssid.bytes, + WMI_PEER_TYPE_DEFAULT, vdev_id); + /* Update new peer's uc cipher */ wma_update_roamed_peer_unicast_cipher(wma, uc_cipher, cipher_cap, roam_synch_ind_ptr->bssid.bytes);