Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9bda10d7 authored by Govind Singh's avatar Govind Singh Committed by Gerrit - the friendly Code Review server
Browse files

qcacmn: Free mem leak in qmi bypass mode

QMI bypass mode uses 2mb of of mem region for
fw uses. Current implementation does not free this
memory region when qmi bypass mode in enabled.
Free mem leak in qmi bypass mode.

Change-Id: Ie11aa9f20f93183e0b999cd6578aea4b231f8d8b
parent 47ca2101
Loading
Loading
Loading
Loading
+64 −17
Original line number Diff line number Diff line
@@ -3389,7 +3389,6 @@ void hif_unconfig_ce(struct hif_softc *hif_sc)
 */
static void hif_post_static_buf_to_target(struct hif_softc *scn)
{
	void *target_va;
	phys_addr_t target_pa;
	struct ce_info *ce_info_ptr;
	uint32_t msi_data_start;
@@ -3398,15 +3397,19 @@ static void hif_post_static_buf_to_target(struct hif_softc *scn)
	uint32_t i = 0;
	int ret;

	target_va = qdf_mem_alloc_consistent(scn->qdf_dev,
	scn->vaddr_qmi_bypass =
			(uint32_t *)qdf_mem_alloc_consistent(scn->qdf_dev,
							     scn->qdf_dev->dev,
					     FW_SHARED_MEM +
					     sizeof(struct ce_info),
							     FW_SHARED_MEM,
							     &target_pa);
	if (!target_va)
	if (!scn->vaddr_qmi_bypass) {
		hif_err("Memory allocation failed could not post target buf");
		return;
	}

	ce_info_ptr = (struct ce_info *)target_va;
	scn->paddr_qmi_bypass = target_pa;

	ce_info_ptr = (struct ce_info *)scn->vaddr_qmi_bypass;

	if (scn->vaddr_rri_on_ddr) {
		ce_info_ptr->rri_over_ddr_low_paddr  =
@@ -3430,7 +3433,26 @@ static void hif_post_static_buf_to_target(struct hif_softc *scn)
	}

	hif_write32_mb(scn, scn->mem + BYPASS_QMI_TEMP_REGISTER, target_pa);
	hif_info("target va %pK target pa %pa", target_va, &target_pa);
	hif_info("target va %pK target pa %pa", scn->vaddr_qmi_bypass,
		 &target_pa);
}

/**
 * hif_cleanup_static_buf_to_target() -  clean up static buffer to WLAN FW
 * @scn: pointer to HIF structure
 *
 *
 * Return: void
 */
void hif_cleanup_static_buf_to_target(struct hif_softc *scn)
{
	void *target_va = scn->vaddr_qmi_bypass;
	phys_addr_t target_pa = scn->paddr_qmi_bypass;

	qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev,
				FW_SHARED_MEM, target_va,
				target_pa, 0);
	hif_write32_mb(scn, scn->mem + BYPASS_QMI_TEMP_REGISTER, 0);
}
#else
/**
@@ -3443,17 +3465,38 @@ static void hif_post_static_buf_to_target(struct hif_softc *scn)
 */
static void hif_post_static_buf_to_target(struct hif_softc *scn)
{
	void *target_va;
	phys_addr_t target_pa;
	qdf_dma_addr_t target_pa;

	target_va = qdf_mem_alloc_consistent(scn->qdf_dev, scn->qdf_dev->dev,
				FW_SHARED_MEM, &target_pa);
	if (!target_va) {
		HIF_TRACE("Memory allocation failed could not post target buf");
	scn->vaddr_qmi_bypass =
			(uint32_t *)qdf_mem_alloc_consistent(scn->qdf_dev,
							     scn->qdf_dev->dev,
							     FW_SHARED_MEM,
							     &target_pa);
	if (!scn->vaddr_qmi_bypass) {
		hif_err("Memory allocation failed could not post target buf");
		return;
	}

	scn->paddr_qmi_bypass = target_pa;
	hif_write32_mb(scn, scn->mem + BYPASS_QMI_TEMP_REGISTER, target_pa);
	HIF_TRACE("target va %pK target pa %pa", target_va, &target_pa);
}

/**
 * hif_cleanup_static_buf_to_target() -  clean up static buffer to WLAN FW
 * @scn: pointer to HIF structure
 *
 *
 * Return: void
 */
void hif_cleanup_static_buf_to_target(struct hif_softc *scn)
{
	void *target_va = scn->vaddr_qmi_bypass;
	phys_addr_t target_pa = scn->paddr_qmi_bypass;

	qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev,
				FW_SHARED_MEM, target_va,
				target_pa, 0);
	hif_write32_mb(snc, scn->mem + BYPASS_QMI_TEMP_REGISTER, 0);
}
#endif

@@ -3461,6 +3504,10 @@ static void hif_post_static_buf_to_target(struct hif_softc *scn)
static inline void hif_post_static_buf_to_target(struct hif_softc *scn)
{
}

void hif_cleanup_static_buf_to_target(struct hif_softc *scn)
{
}
#endif

static int hif_srng_sleep_state_adjust(struct hif_softc *scn, bool sleep_ok,
+1 −0
Original line number Diff line number Diff line
@@ -704,6 +704,7 @@ void hif_close(struct hif_opaque_softc *hif_ctx)
	}

	hif_uninit_rri_on_ddr(scn);
	hif_cleanup_static_buf_to_target(scn);
	hif_cpuhp_unregister(scn);

	hif_bus_close(scn);
+5 −0
Original line number Diff line number Diff line
@@ -201,6 +201,10 @@ struct hif_softc {
	atomic_t link_suspended;
	uint32_t *vaddr_rri_on_ddr;
	qdf_dma_addr_t paddr_rri_on_ddr;
#ifdef CONFIG_BYPASS_QMI
	uint32_t *vaddr_qmi_bypass;
	qdf_dma_addr_t paddr_qmi_bypass;
#endif
	int linkstate_vote;
	bool fastpath_mode_on;
	atomic_t tasklet_from_intr;
@@ -449,4 +453,5 @@ void hif_uninit_rri_on_ddr(struct hif_softc *scn);
static inline
void hif_uninit_rri_on_ddr(struct hif_softc *scn) {}
#endif
void hif_cleanup_static_buf_to_target(struct hif_softc *scn);
#endif /* __HIF_MAIN_H__ */