Jelajahi Sumber

qcacld-3.0: Collect ramdump before kernel panic

FW dumps is not getting collected during kernel panic handler.
Hence move ramdump collection before kernel panic.

CRs-Fixed: 2362637
Change-Id: Id9f1dfefe1560affff6c4ecfca1b8fdba3eb0928
Yuanyuan Liu 6 tahun lalu
induk
melakukan
3ab5531e6d
4 mengubah file dengan 45 tambahan dan 6 penghapusan
  1. 11 6
      core/cds/src/cds_api.c
  2. 1 0
      core/pld/inc/pld_common.h
  3. 24 0
      core/pld/src/pld_common.c
  4. 9 0
      core/pld/src/pld_pcie.h

+ 11 - 6
core/cds/src/cds_api.c

@@ -1753,6 +1753,7 @@ static void cds_trigger_recovery_handler(const char *func, const uint32_t line)
 	QDF_STATUS status;
 	qdf_runtime_lock_t rtl;
 	qdf_device_t qdf;
+	int ret = 0;
 
 	/* NOTE! This code path is delicate! Think very carefully before
 	 * modifying the content or order of the following. Please review any
@@ -1774,6 +1775,16 @@ static void cds_trigger_recovery_handler(const char *func, const uint32_t line)
 		return;
 	}
 
+	qdf = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
+	if (!qdf) {
+		cds_err("Qdf context is null");
+		return;
+	}
+
+	ret = pld_collect_rddm(qdf->dev);
+	if (ret < 0)
+		QDF_DEBUG_PANIC("Fail to collect FW ramdump %d", ret);
+
 	/* if *wlan* recovery is disabled, crash here for debugging */
 	if (!cds_is_self_recovery_enabled()) {
 		QDF_DEBUG_PANIC("WLAN recovery is not enabled (via %s:%d)",
@@ -1787,12 +1798,6 @@ static void cds_trigger_recovery_handler(const char *func, const uint32_t line)
 		return;
 	}
 
-	qdf = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
-	if (!qdf) {
-		cds_err("Qdf context is null");
-		return;
-	}
-
 	status = qdf_runtime_lock_init(&rtl);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		cds_err("qdf_runtime_lock_init failed, status: %d", status);

+ 1 - 0
core/pld/inc/pld_common.h

@@ -603,6 +603,7 @@ int pld_is_qmi_disable(struct device *dev);
 int pld_is_fw_down(struct device *dev);
 void pld_block_shutdown(struct device *dev, bool status);
 int pld_force_assert_target(struct device *dev);
+int pld_collect_rddm(struct device *dev);
 bool pld_is_fw_dump_skipped(struct device *dev);
 
 /**

+ 24 - 0
core/pld/src/pld_common.c

@@ -1669,6 +1669,30 @@ int pld_force_assert_target(struct device *dev)
 	}
 }
 
+/**
+ * pld_collect_rddm() - Collect ramdump before FW assert.
+ * This can used to collect ramdump before FW assert.
+ * @dev: device
+ *
+ *  Return: 0 if ramdump is collected successfully
+ *          Non zero failure code for errors
+ */
+int pld_collect_rddm(struct device *dev)
+{
+	enum pld_bus_type type = pld_get_bus_type(dev);
+
+	switch (type) {
+	case PLD_BUS_TYPE_PCIE:
+		return pld_pcie_collect_rddm(dev);
+	case PLD_BUS_TYPE_SNOC:
+	case PLD_BUS_TYPE_SDIO:
+		return 0;
+	default:
+		pr_err("Invalid device type %d\n", type);
+		return -EINVAL;
+	}
+}
+
 /**
  * pld_is_fw_dump_skipped() - get fw dump skipped status.
  *  The subsys ssr status help the driver to decide whether to skip

+ 9 - 0
core/pld/src/pld_pcie.h

@@ -284,6 +284,11 @@ static inline int pld_pcie_force_assert_target(struct device *dev)
 	return -EINVAL;
 }
 
+static inline int pld_pcie_collect_rddm(struct device *dev)
+{
+	return 0;
+}
+
 static inline int pld_pcie_get_user_msi_assignment(struct device *dev,
 						   char *user_name,
 						   int *num_vectors,
@@ -319,6 +324,10 @@ void pld_pcie_schedule_recovery_work(struct device *dev,
 				     enum pld_recovery_reason reason);
 void pld_pcie_device_self_recovery(struct device *dev,
 				   enum pld_recovery_reason reason);
+static inline int pld_pcie_collect_rddm(struct device *dev)
+{
+	return cnss_force_collect_rddm(dev);
+}
 
 static inline void *pld_pcie_smmu_get_mapping(struct device *dev)
 {