|
@@ -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);
|
|
|
-
|
|
|
- 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(
|
|
|
+ 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(
|
|
|
struct ipa_uc_pending_event));
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
- if (!pending_event) {
|
|
|
- HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR,
|
|
|
+ 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);
|
|
|
+ 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)
|