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

Commit b17f2416 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "icnss: Map memory regions passed by firmware"

parents bca8938b 59931688
Loading
Loading
Loading
Loading
+44 −38
Original line number Diff line number Diff line
@@ -325,8 +325,9 @@ static struct icnss_priv {
	u32 pwr_pin_result;
	u32 phy_io_pin_result;
	u32 rf_pin_result;
	uint32_t nr_mem_region;
	struct icnss_mem_region_info
		icnss_mem_region[QMI_WLFW_MAX_NUM_MEMORY_REGIONS_V01];
		mem_region[QMI_WLFW_MAX_NUM_MEMORY_REGIONS_V01];
	struct dentry *root_dentry;
	spinlock_t on_off_lock;
	struct icnss_stats stats;
@@ -964,7 +965,7 @@ int icnss_power_off(struct device *dev)
}
EXPORT_SYMBOL(icnss_power_off);

static int icnss_map_msa_permissions(struct icnss_priv *priv, u32 index)
static int icnss_map_msa_permissions(struct icnss_mem_region_info *mem_region)
{
	int ret = 0;
	phys_addr_t addr;
@@ -977,10 +978,10 @@ static int icnss_map_msa_permissions(struct icnss_priv *priv, u32 index)
	int source_nelems = sizeof(source_vmlist)/sizeof(u32);
	int dest_nelems = 0;

	addr = priv->icnss_mem_region[index].reg_addr;
	size = priv->icnss_mem_region[index].size;
	addr = mem_region->reg_addr;
	size = mem_region->size;

	if (!priv->icnss_mem_region[index].secure_flag) {
	if (!mem_region->secure_flag) {
		dest_vmids[2] = VMID_WLAN_CE;
		dest_nelems = 3;
	} else {
@@ -990,19 +991,20 @@ static int icnss_map_msa_permissions(struct icnss_priv *priv, u32 index)
	ret = hyp_assign_phys(addr, size, source_vmlist, source_nelems,
			      dest_vmids, dest_perms, dest_nelems);
	if (ret) {
		icnss_pr_err("Region %u hyp_assign_phys failed IPA=%pa size=%u err=%d\n",
			     index, &addr, size, ret);
		icnss_pr_err("Hyperviser map failed for PA=%pa size=%u err=%d\n",
			     &addr, size, ret);
		goto out;
	}
	icnss_pr_dbg("Hypervisor map for region %u: source=%x, dest_nelems=%d, dest[0]=%x, dest[1]=%x, dest[2]=%x\n",
		     index, source_vmlist[0], dest_nelems,
		     dest_vmids[0], dest_vmids[1], dest_vmids[2]);

	icnss_pr_dbg("Hypervisor map for source=%x, dest_nelems=%d, dest[0]=%x, dest[1]=%x, dest[2]=%x\n",
		     source_vmlist[0], dest_nelems, dest_vmids[0],
		     dest_vmids[1], dest_vmids[2]);
out:
	return ret;

}

static int icnss_unmap_msa_permissions(struct icnss_priv *priv, u32 index)
static int icnss_unmap_msa_permissions(struct icnss_mem_region_info *mem_region)
{
	int ret = 0;
	phys_addr_t addr;
@@ -1013,9 +1015,10 @@ static int icnss_unmap_msa_permissions(struct icnss_priv *priv, u32 index)
	int source_nelems = 0;
	int dest_nelems = sizeof(dest_vmids)/sizeof(u32);

	addr = priv->icnss_mem_region[index].reg_addr;
	size = priv->icnss_mem_region[index].size;
	if (!priv->icnss_mem_region[index].secure_flag) {
	addr = mem_region->reg_addr;
	size = mem_region->size;

	if (!mem_region->secure_flag) {
		source_vmlist[2] = VMID_WLAN_CE;
		source_nelems = 3;
	} else {
@@ -1026,14 +1029,13 @@ static int icnss_unmap_msa_permissions(struct icnss_priv *priv, u32 index)
	ret = hyp_assign_phys(addr, size, source_vmlist, source_nelems,
			      dest_vmids, dest_perms, dest_nelems);
	if (ret) {
		icnss_pr_err("Region %u hyp_assign_phys failed IPA=%pa size=%u err=%d\n",
			     index, &addr, size, ret);
		icnss_pr_err("Hyperviser unmap failed for PA=%pa size=%u err=%d\n",
			     &addr, size, ret);
		goto out;
	}
	icnss_pr_dbg("hypervisor unmap for region %u, source_nelems=%d, source[0]=%x, source[1]=%x, source[2]=%x, dest=%x\n",
		     index, source_nelems,
		     source_vmlist[0], source_vmlist[1], source_vmlist[2],
		     dest_vmids[0]);
	icnss_pr_dbg("Hypervisor unmap for source_nelems=%d, source[0]=%x, source[1]=%x, source[2]=%x, dest=%x\n",
		     source_nelems, source_vmlist[0], source_vmlist[1],
		     source_vmlist[2], dest_vmids[0]);
out:
	return ret;
}
@@ -1041,34 +1043,37 @@ out:
static int icnss_setup_msa_permissions(struct icnss_priv *priv)
{
	int ret;
	int i;

	if (test_bit(ICNSS_MSA0_ASSIGNED, &priv->state))
		return 0;

	ret = icnss_map_msa_permissions(priv, 0);
	if (ret)
		return ret;
	for (i = 0; i < priv->nr_mem_region; i++) {

	ret = icnss_map_msa_permissions(priv, 1);
		ret = icnss_map_msa_permissions(&priv->mem_region[i]);
		if (ret)
		goto err_map_msa;
			goto err_unmap;
	}

	set_bit(ICNSS_MSA0_ASSIGNED, &priv->state);

	return ret;
	return 0;

err_map_msa:
	icnss_unmap_msa_permissions(priv, 0);
err_unmap:
	for (i--; i >= 0; i--)
		icnss_unmap_msa_permissions(&priv->mem_region[i]);
	return ret;
}

static void icnss_remove_msa_permissions(struct icnss_priv *priv)
{
	int i;

	if (!test_bit(ICNSS_MSA0_ASSIGNED, &priv->state))
		return;

	icnss_unmap_msa_permissions(priv, 0);
	icnss_unmap_msa_permissions(priv, 1);
	for (i = 0; i < priv->nr_mem_region; i++)
		icnss_unmap_msa_permissions(&priv->mem_region[i]);

	clear_bit(ICNSS_MSA0_ASSIGNED, &priv->state);
}
@@ -1119,7 +1124,7 @@ static int wlfw_msa_mem_info_send_sync_msg(void)
	icnss_pr_dbg("Receive mem_region_info_len: %d\n",
		     resp.mem_region_info_len);

	if (resp.mem_region_info_len > 2) {
	if (resp.mem_region_info_len > QMI_WLFW_MAX_NUM_MEMORY_REGIONS_V01) {
		icnss_pr_err("Invalid memory region length received: %d\n",
			     resp.mem_region_info_len);
		ret = -EINVAL;
@@ -1127,17 +1132,18 @@ static int wlfw_msa_mem_info_send_sync_msg(void)
	}

	penv->stats.msa_info_resp++;
	penv->nr_mem_region = resp.mem_region_info_len;
	for (i = 0; i < resp.mem_region_info_len; i++) {
		penv->icnss_mem_region[i].reg_addr =
		penv->mem_region[i].reg_addr =
			resp.mem_region_info[i].region_addr;
		penv->icnss_mem_region[i].size =
		penv->mem_region[i].size =
			resp.mem_region_info[i].size;
		penv->icnss_mem_region[i].secure_flag =
		penv->mem_region[i].secure_flag =
			resp.mem_region_info[i].secure_flag;
		icnss_pr_dbg("Memory Region: %d Addr: 0x%llx Size: 0x%x Flag: 0x%08x\n",
			 i, penv->icnss_mem_region[i].reg_addr,
			 penv->icnss_mem_region[i].size,
			 penv->icnss_mem_region[i].secure_flag);
			     i, penv->mem_region[i].reg_addr,
			     penv->mem_region[i].size,
			     penv->mem_region[i].secure_flag);
	}

	return 0;