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

Commit 43287066 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: ipa3: V6 CT mmap fix"

parents c5ac9792 a6499d64
Loading
Loading
Loading
Loading
+115 −61
Original line number Diff line number Diff line
/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -130,25 +130,14 @@ static int ipa3_nat_ipv6ct_mmap(
		(struct ipa3_nat_ipv6ct_common_mem *) filp->private_data;
	unsigned long vsize = vma->vm_end - vma->vm_start;
	struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_AP);

	struct ipa3_nat_mem          *nm_ptr = (struct ipa3_nat_mem *) dev;
	struct ipa3_nat_mem          *nm_ptr;
	struct ipa3_nat_mem_loc_data *mld_ptr;
	enum ipa3_nat_mem_in          nmi;

	int result = 0;

	nmi = nm_ptr->last_alloc_loc;

	IPADBG("In\n");

	if (!IPA_VALID_NAT_MEM_IN(nmi)) {
		IPAERR_RL("Bad ipa3_nat_mem_in type\n");
		result = -EPERM;
		goto bail;
	}

	mld_ptr = &nm_ptr->mem_loc[nmi];

	if (!dev->is_dev_init) {
		IPAERR("Attempt to mmap %s before dev init\n",
			   dev->name);
@@ -158,8 +147,34 @@ static int ipa3_nat_ipv6ct_mmap(

	mutex_lock(&dev->lock);

	/*
	 * Check if no smmu or non dma coherent
	 */
	if (!cb->valid || !is_device_dma_coherent(cb->dev)) {

		IPADBG("Either smmu valid=%u and/or DMA coherent=%u false\n",
			   cb->valid, is_device_dma_coherent(cb->dev));

		vma->vm_page_prot =
			pgprot_noncached(vma->vm_page_prot);
	}

	if (dev->is_nat_mem) {

		nm_ptr = (struct ipa3_nat_mem *) dev;
		nmi    = nm_ptr->last_alloc_loc;

		if (!IPA_VALID_NAT_MEM_IN(nmi)) {
			IPAERR_RL("Bad ipa3_nat_mem_in type\n");
			result = -EPERM;
			goto unlock;
		}

		mld_ptr = &nm_ptr->mem_loc[nmi];

		if (!mld_ptr->vaddr) {
		IPAERR_RL("Attempt to mmap %s before the memory allocation\n",
			IPAERR_RL(
			 "Attempt to mmap %s before the memory allocation\n",
			 dev->name);
			result = -EPERM;
			goto unlock;
@@ -173,33 +188,24 @@ static int ipa3_nat_ipv6ct_mmap(
		}

		if (nmi == IPA_NAT_MEM_IN_SRAM) {
		if (dev->phys_mem_size == 0 || dev->phys_mem_size > vsize) {
			IPAERR_RL("%s err vsize(0x%X) phys_mem_size(0x%X)\n",
			if (dev->phys_mem_size == 0 ||
				dev->phys_mem_size > vsize) {
				IPAERR_RL(
				 "%s err vsize(0x%X) phys_mem_size(0x%X)\n",
				 dev->name, vsize, dev->phys_mem_size);
				result = -EINVAL;
				goto unlock;
			}
		}

	/*
	 * Check if no smmu or non dma coherent
	 */
	if (!cb->valid || !is_device_dma_coherent(cb->dev)) {

		IPADBG("Either smmu valid=%u and/or DMA coherent=%u false\n",
			   cb->valid, is_device_dma_coherent(cb->dev));

		vma->vm_page_prot =
			pgprot_noncached(vma->vm_page_prot);
	}

		mld_ptr->base_address = NULL;

	IPADBG("Mapping %s\n", ipa3_nat_mem_in_as_str(nmi));
		IPADBG("Mapping V4 NAT: %s\n",
			   ipa3_nat_mem_in_as_str(nmi));

		if (nmi == IPA_NAT_MEM_IN_DDR) {

		IPADBG("map sz=0x%zx into vma size=0x%08x\n",
			IPADBG("map sz=0x%zx -> vma size=0x%08x\n",
				   mld_ptr->table_alloc_size,
				   vsize);

@@ -212,13 +218,15 @@ static int ipa3_nat_ipv6ct_mmap(
					mld_ptr->table_alloc_size);

			if (result) {
			IPAERR("dma_mmap_coherent failed. Err:%d\n", result);
				IPAERR(
				 "dma_mmap_coherent failed. Err:%d\n",
				 result);
				goto unlock;
			}

			mld_ptr->base_address = mld_ptr->vaddr;
	} else {
		if (nmi == IPA_NAT_MEM_IN_SRAM) {

		} else { /* nmi == IPA_NAT_MEM_IN_SRAM */

			IPADBG("map phys_mem_size(0x%08X) -> vma sz(0x%08X)\n",
				   dev->phys_mem_size, vsize);
@@ -236,10 +244,53 @@ static int ipa3_nat_ipv6ct_mmap(

			mld_ptr->base_address = mld_ptr->vaddr;
		}
	}

		mld_ptr->is_mapped = true;

	} else { /* dev->is_ipv6ct_mem */

		if (!dev->vaddr) {
			IPAERR_RL(
			 "Attempt to mmap %s before the memory allocation\n",
			 dev->name);
			result = -EPERM;
			goto unlock;
		}

		if (dev->is_mapped) {
			IPAERR("%s already mapped, only 1 mapping supported\n",
				   dev->name);
			result = -EINVAL;
			goto unlock;
		}

		dev->base_address = NULL;

		IPADBG("Mapping V6 CT: %s\n",
			   ipa3_nat_mem_in_as_str(IPA_NAT_MEM_IN_DDR));

		IPADBG("map sz=0x%zx -> vma size=0x%08x\n",
			   dev->table_alloc_size,
			   vsize);

		result =
			dma_mmap_coherent(
				ipa3_ctx->pdev,
				vma,
				dev->vaddr,
				dev->dma_handle,
				dev->table_alloc_size);

		if (result) {
			IPAERR("dma_mmap_coherent failed. Err:%d\n", result);
			goto unlock;
		}

		dev->base_address = dev->vaddr;

		dev->is_mapped = true;
	}

	vma->vm_ops = &ipa3_nat_ipv6ct_remap_vm_ops;

unlock:
@@ -542,7 +593,8 @@ static int ipa3_nat_ipv6ct_allocate_mem(
			/*
			 * CAN fit in SRAM, hence we'll use SRAM...
			 */
			IPADBG("V4 NAT will reside in: %s\n",
			IPADBG("V4 NAT with size 0x%08X will reside in: %s\n",
				   table_alloc->size,
				   ipa3_nat_mem_in_as_str(IPA_NAT_MEM_IN_SRAM));

			if (nm_ptr->sram_in_use) {
@@ -584,7 +636,8 @@ static int ipa3_nat_ipv6ct_allocate_mem(
			/*
			 * CAN NOT fit in SRAM, hence we'll allocate DDR...
			 */
			IPADBG("V4 NAT will reside in: %s\n",
			IPADBG("V4 NAT with size 0x%08X will reside in: %s\n",
				   table_alloc->size,
				   ipa3_nat_mem_in_as_str(IPA_NAT_MEM_IN_DDR));

			if (nm_ptr->ddr_in_use) {
@@ -616,11 +669,12 @@ static int ipa3_nat_ipv6ct_allocate_mem(
	} else {
		if (nat_type == IPAHAL_NAT_IPV6CT) {

			dev->table_alloc_size = table_alloc->size;

			IPADBG("V6 NAT will reside in: %s\n",
			IPADBG("V6 CT with size 0x%08X will reside in: %s\n",
				   table_alloc->size,
				   ipa3_nat_mem_in_as_str(IPA_NAT_MEM_IN_DDR));

			dev->table_alloc_size = table_alloc->size;

			dev->vaddr =
				dma_alloc_coherent(
					ipa3_ctx->pdev,