Просмотр исходного кода

qcacld-3.0: Block modem graceful shutdown during stop modules

In the case the interface timer gets expired and stop modules is called
in that context and modem graceful shutdown occurs at the same time,
there arises a situation in which there is a mismatch in the FW and
driver state. This results in the rx ring buffers being freed by the
host while FW still tries to access those buffers.

To avoid this assert situation, block the modem shutdown while the host
is performing stop modules. During stop modules, host will send pdev
suspend which will suspend all activity from FW. This can then clear the
path for the modem graceful shutdown.

Change-Id: I8ecae86bb90be7e97eb274946270eb57ca107332
CRs-Fixed: 2392815
Sourav Mohapatra 6 лет назад
Родитель
Сommit
698d6f6638
1 измененных файлов с 17 добавлено и 0 удалено
  1. 17 0
      core/hdd/src/wlan_hdd_main.c

+ 17 - 0
core/hdd/src/wlan_hdd_main.c

@@ -9276,6 +9276,19 @@ void hdd_psoc_idle_timer_stop(struct hdd_context *hdd_ctx)
 	hdd_debug("Stopped psoc idle timer");
 }
 
+/*
+ * enum hdd_block_shutdown - Control if driver allows modem shutdown
+ * @HDD_UNBLOCK_MODEM_SHUTDOWN: Unblock shutdown
+ * @HDD_BLOCK_MODEM_SHUTDOWN: Block shutdown
+ *
+ * On calling pld_block_shutdown API with the given values, modem
+ * graceful shutdown is blocked/unblocked.
+ */
+enum hdd_block_shutdown {
+	HDD_UNBLOCK_MODEM_SHUTDOWN,
+	HDD_BLOCK_MODEM_SHUTDOWN,
+};
+
 /**
  * hdd_psoc_idle_shutdown() - perform an idle shutdown on the given psoc
  * @hdd_ctx: the hdd context which should be shutdown
@@ -9299,6 +9312,8 @@ static void hdd_psoc_idle_shutdown(struct hdd_context *hdd_ctx)
 		hdd_info("psoc busy, abort idle shutdown; errno:%d", errno);
 		goto exit;
 	}
+	/* Block the modem graceful shutdown till stop modules is completed */
+	pld_block_shutdown(hdd_ctx->parent_dev, HDD_BLOCK_MODEM_SHUTDOWN);
 
 	osif_psoc_sync_wait_for_ops(psoc_sync);
 
@@ -9306,6 +9321,8 @@ static void hdd_psoc_idle_shutdown(struct hdd_context *hdd_ctx)
 
 	osif_psoc_sync_trans_stop(psoc_sync);
 
+	pld_block_shutdown(hdd_ctx->parent_dev, HDD_UNBLOCK_MODEM_SHUTDOWN);
+
 exit:
 	hdd_exit();
 }