diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 1de4f0a34f72..dee992d3e994 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -18550,14 +18550,7 @@ int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy, adapter->sta_info[i]. sta_mac.bytes, QDF_MAC_ADDR_SIZE); - if (hdd_ipa_uc_is_enabled(hdd_ctx)) { - hdd_ipa_wlan_evt(adapter, - adapter-> - sta_info[i]. - sta_id, - HDD_IPA_CLIENT_DISCONNECT, - mac); - } + hdd_debug("Delete STA with MAC::" MAC_ADDRESS_STR, MAC_ADDR_ARRAY(mac)); @@ -18598,11 +18591,6 @@ int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy, return -ENOENT; } - if (hdd_ipa_uc_is_enabled(hdd_ctx)) { - hdd_ipa_wlan_evt(adapter, staId, - HDD_IPA_CLIENT_DISCONNECT, mac); - } - if (adapter->sta_info[staId].is_deauth_in_progress == true) { hdd_debug("Skip DEL STA as deauth is in progress::" diff --git a/core/hdd/src/wlan_hdd_ipa.c b/core/hdd/src/wlan_hdd_ipa.c index fb0754340c71..912e8260c7f4 100644 --- a/core/hdd/src/wlan_hdd_ipa.c +++ b/core/hdd/src/wlan_hdd_ipa.c @@ -309,6 +309,7 @@ struct ipa_uc_pending_event { qdf_ipa_wlan_event_t type; uint8_t sta_id; uint8_t mac_addr[QDF_MAC_ADDR_SIZE]; + bool is_loading; }; /** @@ -550,7 +551,8 @@ static void hdd_ipa_wdi_meter_notifier_cb(void); static void hdd_ipa_msg_free_fn(void *buff, uint32_t len, uint32_t type); static void hdd_ipa_cleanup_iface(struct hdd_ipa_iface_context *iface_context); -static void hdd_ipa_uc_proc_pending_event(struct hdd_ipa_priv *hdd_ipa); +static void hdd_ipa_uc_proc_pending_event(struct hdd_ipa_priv *hdd_ipa, + bool is_loading); #if ((defined(QCA_WIFI_3_0) && defined(CONFIG_IPA3)) || \ defined(IPA_CLIENT_IS_MHI_CONS)) @@ -2692,7 +2694,7 @@ static void hdd_ipa_uc_op_cb(struct op_msg_type *op_msg, void *usr_ctxt) hdd_ipa_send_mcc_scc_msg(hdd_ctx, hdd_ctx->mcc_mode); } - hdd_ipa_uc_proc_pending_event(hdd_ipa); + hdd_ipa_uc_proc_pending_event(hdd_ipa, true); if (hdd_ipa->pending_cons_req) ipa_rm_notify_completion( IPA_RM_RESOURCE_GRANTED, @@ -2709,13 +2711,13 @@ static void hdd_ipa_uc_op_cb(struct op_msg_type *op_msg, void *usr_ctxt) * Async return success from FW * Disable/suspend all the PIPEs */ + hdd_ipa->resource_unloading = false; + complete(&hdd_ipa->ipa_resource_comp); hdd_ipa_uc_disable_pipes(hdd_ipa); if (hdd_ipa_is_rm_enabled(hdd_ipa->hdd_ctx)) ipa_rm_release_resource( IPA_RM_RESOURCE_WLAN_PROD); - hdd_ipa->resource_unloading = false; - complete(&hdd_ipa->ipa_resource_comp); - hdd_ipa_uc_proc_pending_event(hdd_ipa); + hdd_ipa_uc_proc_pending_event(hdd_ipa, false); hdd_ipa->pending_cons_req = false; } qdf_mutex_release(&hdd_ipa->ipa_lock); @@ -3121,6 +3123,12 @@ QDF_STATUS hdd_ipa_uc_ol_init(struct hdd_context *hdd_ctx) status = QDF_STATUS_E_FAILURE; goto fail_return; } + + for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) { + hdd_ipa->vdev_to_iface[i] = CSR_ROAM_SESSION_MAX; + hdd_ipa->vdev_offload_enabled[i] = false; + } + if (cdp_ipa_get_resource(soc, (struct cdp_pdev *)pdev)) { HDD_IPA_LOG(QDF_TRACE_LEVEL_FATAL, "IPA UC resource alloc fail"); @@ -3153,7 +3161,7 @@ QDF_STATUS hdd_ipa_uc_ol_init(struct hdd_context *hdd_ctx) for (i = 0; i < HDD_IPA_UC_OPCODE_MAX; i++) { hdd_ipa_init_uc_op_work(&hdd_ipa->uc_op_work[i].work, - hdd_ipa_uc_fw_op_event_handler); + hdd_ipa_uc_fw_op_event_handler); hdd_ipa->uc_op_work[i].msg = NULL; } @@ -3209,7 +3217,9 @@ int hdd_ipa_uc_ol_deinit(struct hdd_context *hdd_ctx) } } + qdf_mutex_acquire(&hdd_ipa->ipa_lock); hdd_ipa_cleanup_pending_event(hdd_ipa); + qdf_mutex_release(&hdd_ipa->ipa_lock); HDD_IPA_LOG(QDF_TRACE_LEVEL_INFO, "exit: ret=%d", ret); return ret; @@ -3471,6 +3481,7 @@ static int __hdd_ipa_uc_ssr_deinit(void) hdd_ipa_cleanup_iface(iface_context); } hdd_ipa->num_iface = 0; + /* After SSR, wlan driver reloads FW again. But we need to protect * IPA submodule during SSR transient state. So deinit basic IPA * UC host side to be in sync with reloaded FW during SSR @@ -3546,10 +3557,6 @@ static int __hdd_ipa_uc_ssr_reinit(struct hdd_context *hdd_ctx) iface_context->iface_id = i; iface_context->adapter = NULL; } - for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) { - hdd_ipa->vdev_to_iface[i] = CSR_ROAM_SESSION_MAX; - hdd_ipa->vdev_offload_enabled[i] = false; - } if (hdd_ipa_uc_is_enabled(hdd_ipa->hdd_ctx)) { hdd_ipa->resource_loading = false; @@ -5369,42 +5376,42 @@ static int __hdd_ipa_wlan_evt(struct hdd_adapter *adapter, uint8_t sta_id, hdd_ipa->resource_loading ? "load" : "unload"); - if (hdd_ipa->resource_loading) { - qdf_mutex_acquire(&hdd_ipa->ipa_lock); + qdf_mutex_acquire(&hdd_ipa->ipa_lock); - pending_event_count = - qdf_list_size(&hdd_ipa->pending_event); - if (pending_event_count >= - HDD_IPA_MAX_PENDING_EVENT_COUNT) { - hdd_debug( - "Reached max pending event count"); - qdf_list_remove_front( - &hdd_ipa->pending_event, - (qdf_list_node_t **)&pending_event); - } else { - pending_event = - (struct ipa_uc_pending_event *) - qdf_mem_malloc(sizeof( + pending_event_count = + qdf_list_size(&hdd_ipa->pending_event); + if (pending_event_count >= + HDD_IPA_MAX_PENDING_EVENT_COUNT) { + hdd_debug("Reached max pending event count"); + qdf_list_remove_front( + &hdd_ipa->pending_event, + (qdf_list_node_t **)&pending_event); + } else { + pending_event = + (struct ipa_uc_pending_event *) + qdf_mem_malloc(sizeof( struct ipa_uc_pending_event)); - } - - if (!pending_event) { - HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR, - "Pending event memory alloc fail"); - qdf_mutex_release(&hdd_ipa->ipa_lock); - return -ENOMEM; - } - - pending_event->adapter = adapter; - pending_event->sta_id = sta_id; - pending_event->type = type; - qdf_mem_copy(pending_event->mac_addr, - mac_addr, QDF_MAC_ADDR_SIZE); - qdf_list_insert_back(&hdd_ipa->pending_event, - &pending_event->node); - - qdf_mutex_release(&hdd_ipa->ipa_lock); } + + if (!pending_event) { + HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR, + "Pending event memory alloc fail"); + qdf_mutex_release(&hdd_ipa->ipa_lock); + return -ENOMEM; + } + + pending_event->adapter = adapter; + pending_event->sta_id = sta_id; + pending_event->type = type; + pending_event->is_loading = + hdd_ipa->resource_loading; + qdf_mem_copy(pending_event->mac_addr, + mac_addr, QDF_MAC_ADDR_SIZE); + qdf_list_insert_back(&hdd_ipa->pending_event, + &pending_event->node); + + qdf_mutex_release(&hdd_ipa->ipa_lock); + return 0; } HDD_IPA_LOG(QDF_TRACE_LEVEL_INFO, @@ -5796,11 +5803,12 @@ int hdd_ipa_wlan_evt(struct hdd_adapter *adapter, uint8_t sta_id, /** * hdd_ipa_uc_proc_pending_event() - Process IPA uC pending events * @hdd_ipa: Global HDD IPA context + * @is_loading: Indicate if invoked during loading * * Return: None */ static void -hdd_ipa_uc_proc_pending_event(struct hdd_ipa_priv *hdd_ipa) +hdd_ipa_uc_proc_pending_event(struct hdd_ipa_priv *hdd_ipa, bool is_loading) { unsigned int pending_event_count; struct ipa_uc_pending_event *pending_event = NULL; @@ -5817,10 +5825,11 @@ hdd_ipa_uc_proc_pending_event(struct hdd_ipa_priv *hdd_ipa) qdf_list_remove_front(&hdd_ipa->pending_event, (qdf_list_node_t **)&pending_event); while (pending_event != NULL) { - __hdd_ipa_wlan_evt(pending_event->adapter, - pending_event->sta_id, - pending_event->type, - pending_event->mac_addr); + if (pending_event->is_loading == is_loading) + __hdd_ipa_wlan_evt(pending_event->adapter, + pending_event->sta_id, + pending_event->type, + pending_event->mac_addr); qdf_mem_free(pending_event); pending_event = NULL; qdf_list_remove_front(&hdd_ipa->pending_event, @@ -5899,10 +5908,6 @@ static QDF_STATUS __hdd_ipa_init(struct hdd_context *hdd_ctx) iface_context->adapter = NULL; qdf_spinlock_create(&iface_context->interface_lock); } - for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) { - hdd_ipa->vdev_to_iface[i] = CSR_ROAM_SESSION_MAX; - hdd_ipa->vdev_offload_enabled[i] = false; - } INIT_WORK(&hdd_ipa->pm_work, hdd_ipa_pm_flush); qdf_spinlock_create(&hdd_ipa->pm_lock); @@ -5941,12 +5946,6 @@ static QDF_STATUS __hdd_ipa_init(struct hdd_context *hdd_ctx) } if (hdd_ipa_uc_register_uc_ready(hdd_ipa)) goto fail_create_sys_pipe; - - for (i = 0; i < HDD_IPA_UC_OPCODE_MAX; i++) { - hdd_ipa_init_uc_op_work(&hdd_ipa->uc_op_work[i].work, - hdd_ipa_uc_fw_op_event_handler); - hdd_ipa->uc_op_work[i].msg = NULL; - } } else { ret = hdd_ipa_setup_sys_pipe(hdd_ipa); if (ret)