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

Commit 3c9b922d authored by Ravit Katzav's avatar Ravit Katzav
Browse files

msm: ipa: add support for Ethernet Bridging



Add support for new IPA feature for enabling Ethernet bridging.
This includes changes in filtering or routing attributes
and header insertion.

Filtering changes includes adding filtering or routing rules
with attributes from Ethernet header such as source and
destination mac addresses.

Header insertion changes includes adding new API
for adding Processing Contexts to IPA
to allow Ethernet header insertion and processing.

Change-Id: I7fcc8146c06fc306548e67554a3c3c6c8d7cad1e
Acked-by: default avatarYaniv Lefel <ylefel@qti.qualcomm.com>
Signed-off-by: default avatarGidon Studinski <gidons@codeaurora.org>
Signed-off-by: default avatarRavit Katzav <rkatzav@codeaurora.org>
parent a223e4ce
Loading
Loading
Loading
Loading
+268 −25
Original line number Diff line number Diff line
@@ -154,6 +154,12 @@
#define IPA_IOC_NOTIFY_WAN_EMBMS_CONNECTED32 _IOWR(IPA_IOC_MAGIC, \
					IPA_IOCTL_NOTIFY_WAN_EMBMS_CONNECTED, \
					compat_uptr_t)
#define IPA_IOC_ADD_HDR_PROC_CTX32 _IOWR(IPA_IOC_MAGIC, \
				IPA_IOCTL_ADD_HDR_PROC_CTX, \
				compat_uptr_t)
#define IPA_IOC_DEL_HDR_PROC_CTX32 _IOWR(IPA_IOC_MAGIC, \
				IPA_IOCTL_DEL_HDR_PROC_CTX, \
				compat_uptr_t)

/**
 * struct ipa_ioc_nat_alloc_mem32 - nat table memory allocation
@@ -875,6 +881,65 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
			break;
		}
		break;
	case IPA_IOC_ADD_HDR_PROC_CTX:
		if (copy_from_user(header, (u8 *)arg,
			sizeof(struct ipa_ioc_add_hdr_proc_ctx))) {
			retval = -EFAULT;
			break;
		}
		pyld_sz =
		   sizeof(struct ipa_ioc_add_hdr_proc_ctx) +
		   ((struct ipa_ioc_add_hdr_proc_ctx *)header)->num_proc_ctxs *
		   sizeof(struct ipa_hdr_proc_ctx_add);
		param = kzalloc(pyld_sz, GFP_KERNEL);
		if (!param) {
			retval = -ENOMEM;
			break;
		}
		if (copy_from_user(param, (u8 *)arg, pyld_sz)) {
			retval = -EFAULT;
			break;
		}
		if (ipa_add_hdr_proc_ctx(
			(struct ipa_ioc_add_hdr_proc_ctx *)param)) {
			retval = -EFAULT;
			break;
		}
		if (copy_to_user((u8 *)arg, param, pyld_sz)) {
			retval = -EFAULT;
			break;
		}
		break;
	case IPA_IOC_DEL_HDR_PROC_CTX:
		if (copy_from_user(header, (u8 *)arg,
			sizeof(struct ipa_ioc_del_hdr_proc_ctx))) {
			retval = -EFAULT;
			break;
		}
		pyld_sz =
		   sizeof(struct ipa_ioc_del_hdr_proc_ctx) +
		   ((struct ipa_ioc_del_hdr_proc_ctx *)header)->num_hdls *
		   sizeof(struct ipa_hdr_proc_ctx_del);
		param = kzalloc(pyld_sz, GFP_KERNEL);
		if (!param) {
			retval = -ENOMEM;
			break;
		}
		if (copy_from_user(param, (u8 *)arg, pyld_sz)) {
			retval = -EFAULT;
			break;
		}
		if (ipa_del_hdr_proc_ctx(
			(struct ipa_ioc_del_hdr_proc_ctx *)param)) {
			retval = -EFAULT;
			break;
		}
		if (copy_to_user((u8 *)arg, param, pyld_sz)) {
			retval = -EFAULT;
			break;
		}
		break;

	default:        /* redundant, as cmd was checked against MAXNR */
		ipa_dec_client_disable_clks();
		return -ENOTTY;
@@ -1019,6 +1084,9 @@ static int ipa_init_smem_region(int memory_region_size,
	struct ipa_mem_buffer mem;
	int rc;

	if (memory_region_size == 0)
		return 0;

	memset(&desc, 0, sizeof(desc));
	memset(&cmd, 0, sizeof(cmd));
	memset(&mem, 0, sizeof(mem));
@@ -1084,6 +1152,14 @@ int ipa_init_q6_smem(void)
		return rc;
	}

	rc = ipa_init_smem_region(IPA_MEM_PART(modem_hdr_proc_ctx_size),
		IPA_MEM_PART(modem_hdr_proc_ctx_ofst));
	if (rc) {
		IPAERR("failed to initialize Modem proc ctx RAM memory\n");
		ipa_dec_client_disable_clks();
		return rc;
	}

	ipa_dec_client_disable_clks();

	return rc;
@@ -1450,7 +1526,7 @@ int ipa_q6_cleanup(void)
	return 0;
}

static int ipa_init_sram(void)
int _ipa_init_sram_v2(void)
{
	u32 *ipa_sram_mmio;
	unsigned long phys_addr;
@@ -1459,16 +1535,71 @@ static int ipa_init_sram(void)
	struct ipa_mem_buffer mem;
	int rc = 0;

	if (ipa_ctx->ipa_hw_type == IPA_HW_v2_5) {
		phys_addr = ipa_ctx->ipa_wrapper_base +
			ipa_ctx->ctrl->ipa_reg_base_ofst +
			IPA_SRAM_SW_FIRST_v2_5;
	} else {
	phys_addr = ipa_ctx->ipa_wrapper_base +
		ipa_ctx->ctrl->ipa_reg_base_ofst +
		IPA_SRAM_DIRECT_ACCESS_N_OFST_v2_0(
			ipa_ctx->smem_restricted_bytes / 4);

	ipa_sram_mmio = ioremap(phys_addr,
			ipa_ctx->smem_sz - ipa_ctx->smem_restricted_bytes);
	if (!ipa_sram_mmio) {
		IPAERR("fail to ioremap IPA SRAM\n");
		return -ENOMEM;
	}

#define IPA_SRAM_SET(ofst, val) (ipa_sram_mmio[(ofst - 4) / 4] = val)

	IPA_SRAM_SET(IPA_MEM_PART(v6_flt_ofst) - 4, IPA_MEM_CANARY_VAL);
	IPA_SRAM_SET(IPA_MEM_PART(v6_flt_ofst), IPA_MEM_CANARY_VAL);
	IPA_SRAM_SET(IPA_MEM_PART(v4_rt_ofst) - 4, IPA_MEM_CANARY_VAL);
	IPA_SRAM_SET(IPA_MEM_PART(v4_rt_ofst), IPA_MEM_CANARY_VAL);
	IPA_SRAM_SET(IPA_MEM_PART(v6_rt_ofst), IPA_MEM_CANARY_VAL);
	IPA_SRAM_SET(IPA_MEM_PART(modem_hdr_ofst), IPA_MEM_CANARY_VAL);
	IPA_SRAM_SET(IPA_MEM_PART(modem_ofst), IPA_MEM_CANARY_VAL);
	IPA_SRAM_SET(IPA_MEM_PART(apps_v4_flt_ofst), IPA_MEM_CANARY_VAL);
	IPA_SRAM_SET(IPA_MEM_PART(uc_info_ofst), IPA_MEM_CANARY_VAL);

	iounmap(ipa_sram_mmio);

	mem.size = IPA_STATUS_CLEAR_SIZE;
	mem.base = dma_alloc_coherent(ipa_ctx->pdev, mem.size, &mem.phys_base,
			GFP_KERNEL);
	if (!mem.base) {
		IPAERR("fail to alloc DMA buff of size %d\n", mem.size);
		return -ENOMEM;
	}
	memset(mem.base, 0, mem.size);

	cmd.size = mem.size;
	cmd.system_addr = mem.phys_base;
	cmd.local_addr = IPA_STATUS_CLEAR_OFST;
	desc.opcode = IPA_DMA_SHARED_MEM;
	desc.pyld = &cmd;
	desc.len = sizeof(struct ipa_hw_imm_cmd_dma_shared_mem);
	desc.type = IPA_IMM_CMD_DESC;

	if (ipa_send_cmd(1, &desc)) {
		IPAERR("fail to send immediate command\n");
		rc = -EFAULT;
	}

	dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base, mem.phys_base);
	return rc;
}

int _ipa_init_sram_v2_5(void)
{
	u32 *ipa_sram_mmio;
	unsigned long phys_addr;
	struct ipa_hw_imm_cmd_dma_shared_mem cmd = { 0 };
	struct ipa_desc desc = { 0 };
	struct ipa_mem_buffer mem;
	int rc = 0;

	phys_addr = ipa_ctx->ipa_wrapper_base +
			ipa_ctx->ctrl->ipa_reg_base_ofst +
			IPA_SRAM_SW_FIRST_v2_5;

	ipa_sram_mmio = ioremap(phys_addr,
		ipa_ctx->smem_sz - ipa_ctx->smem_restricted_bytes);
	if (!ipa_sram_mmio) {
@@ -1484,6 +1615,9 @@ static int ipa_init_sram(void)
	IPA_SRAM_SET(IPA_MEM_PART(v4_rt_ofst), IPA_MEM_CANARY_VAL);
	IPA_SRAM_SET(IPA_MEM_PART(v6_rt_ofst), IPA_MEM_CANARY_VAL);
	IPA_SRAM_SET(IPA_MEM_PART(modem_hdr_ofst), IPA_MEM_CANARY_VAL);
	IPA_SRAM_SET(IPA_MEM_PART(modem_hdr_proc_ctx_ofst) - 4,
							IPA_MEM_CANARY_VAL);
	IPA_SRAM_SET(IPA_MEM_PART(modem_hdr_proc_ctx_ofst), IPA_MEM_CANARY_VAL);
	IPA_SRAM_SET(IPA_MEM_PART(modem_ofst), IPA_MEM_CANARY_VAL);
	IPA_SRAM_SET(IPA_MEM_PART(apps_v4_flt_ofst), IPA_MEM_CANARY_VAL);
	IPA_SRAM_SET(IPA_MEM_PART(uc_info_ofst), IPA_MEM_CANARY_VAL);
@@ -1516,7 +1650,7 @@ static int ipa_init_sram(void)
	return rc;
}

static int ipa_init_hdr(void)
int _ipa_init_hdr_v2(void)
{
	struct ipa_desc desc = { 0 };
	struct ipa_mem_buffer mem;
@@ -1552,7 +1686,83 @@ static int ipa_init_hdr(void)
	return rc;
}

static int ipa_init_rt4(void)
int _ipa_init_hdr_v2_5(void)
{
	struct ipa_desc desc = { 0 };
	struct ipa_mem_buffer mem;
	struct ipa_hdr_init_local cmd = { 0 };
	struct ipa_hw_imm_cmd_dma_shared_mem dma_cmd = { 0 };

	mem.size = IPA_MEM_PART(modem_hdr_size) + IPA_MEM_PART(apps_hdr_size);
	mem.base = dma_alloc_coherent(ipa_ctx->pdev, mem.size, &mem.phys_base,
		GFP_KERNEL);
	if (!mem.base) {
		IPAERR("fail to alloc DMA buff of size %d\n", mem.size);
		return -ENOMEM;
	}
	memset(mem.base, 0, mem.size);

	cmd.hdr_table_src_addr = mem.phys_base;
	cmd.size_hdr_table = mem.size;
	cmd.hdr_table_dst_addr = ipa_ctx->smem_restricted_bytes +
		IPA_MEM_PART(modem_hdr_ofst);

	desc.opcode = IPA_HDR_INIT_LOCAL;
	desc.pyld = &cmd;
	desc.len = sizeof(struct ipa_hdr_init_local);
	desc.type = IPA_IMM_CMD_DESC;
	IPA_DUMP_BUFF(mem.base, mem.phys_base, mem.size);

	if (ipa_send_cmd(1, &desc)) {
		IPAERR("fail to send immediate command\n");
		dma_free_coherent(ipa_ctx->pdev,
			mem.size, mem.base,
			mem.phys_base);
		return -EFAULT;
	}

	dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base, mem.phys_base);

	mem.size = IPA_MEM_PART(modem_hdr_proc_ctx_size) +
		IPA_MEM_PART(apps_hdr_proc_ctx_size);
	mem.base = dma_alloc_coherent(ipa_ctx->pdev, mem.size, &mem.phys_base,
		GFP_KERNEL);
	if (!mem.base) {
		IPAERR("fail to alloc DMA buff of size %d\n", mem.size);
		return -ENOMEM;
	}
	memset(mem.base, 0, mem.size);
	memset(&desc, 0, sizeof(desc));

	dma_cmd.system_addr = mem.phys_base;
	dma_cmd.local_addr = ipa_ctx->smem_restricted_bytes +
		IPA_MEM_PART(modem_hdr_proc_ctx_ofst);
	dma_cmd.size = mem.size;
	desc.opcode = IPA_DMA_SHARED_MEM;
	desc.pyld = &dma_cmd;
	desc.len = sizeof(struct ipa_hw_imm_cmd_dma_shared_mem);
	desc.type = IPA_IMM_CMD_DESC;
	IPA_DUMP_BUFF(mem.base, mem.phys_base, mem.size);

	if (ipa_send_cmd(1, &desc)) {
		IPAERR("fail to send immediate command\n");
		dma_free_coherent(ipa_ctx->pdev,
			mem.size,
			mem.base,
			mem.phys_base);
		return -EFAULT;
	}

	ipa_write_reg(ipa_ctx->mmio,
		IPA_LOCAL_PKT_PROC_CNTXT_BASE_OFST,
		dma_cmd.local_addr);

	dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base, mem.phys_base);

	return 0;
}

int _ipa_init_rt4_v2(void)
{
	struct ipa_desc desc = { 0 };
	struct ipa_mem_buffer mem;
@@ -1603,7 +1813,7 @@ static int ipa_init_rt4(void)
	return rc;
}

static int ipa_init_rt6(void)
int _ipa_init_rt6_v2(void)
{
	struct ipa_desc desc = { 0 };
	struct ipa_mem_buffer mem;
@@ -1654,7 +1864,7 @@ static int ipa_init_rt6(void)
	return rc;
}

static int ipa_init_flt4(void)
int _ipa_init_flt4_v2(void)
{
	struct ipa_desc desc = { 0 };
	struct ipa_mem_buffer mem;
@@ -1703,7 +1913,7 @@ static int ipa_init_flt4(void)
	return rc;
}

static int ipa_init_flt6(void)
int _ipa_init_flt6_v2(void)
{
	struct ipa_desc desc = { 0 };
	struct ipa_mem_buffer mem;
@@ -1771,15 +1981,23 @@ static int ipa_setup_apps_pipes(void)
	}
	IPADBG("Apps to IPA cmd pipe is connected\n");

	if (ipa_ctx->ipa_hw_type == IPA_HW_v2_0 ||
		ipa_ctx->ipa_hw_type == IPA_HW_v2_5) {
		ipa_init_sram();
		ipa_init_hdr();
		ipa_init_rt4();
		ipa_init_rt6();
		ipa_init_flt4();
		ipa_init_flt6();
	}
	ipa_ctx->ctrl->ipa_init_sram();
	IPADBG("SRAM initialized\n");

	ipa_ctx->ctrl->ipa_init_hdr();
	IPADBG("HDR initialized\n");

	ipa_ctx->ctrl->ipa_init_rt4();
	IPADBG("V4 RT initialized\n");

	ipa_ctx->ctrl->ipa_init_rt6();
	IPADBG("V6 RT initialized\n");

	ipa_ctx->ctrl->ipa_init_flt4();
	IPADBG("V4 FLT initialized\n");

	ipa_ctx->ctrl->ipa_init_flt6();
	IPADBG("V6 FLT initialized\n");

	if (ipa_setup_exception_path()) {
		IPAERR(":fail to setup excp path\n");
@@ -2820,6 +3038,21 @@ static int ipa_init(const struct ipa_plat_drv_res *resource_p,
		result = -ENOMEM;
		goto fail_hdr_offset_cache;
	}
	ipa_ctx->hdr_proc_ctx_cache = kmem_cache_create("IPA HDR PROC CTX",
		sizeof(struct ipa_hdr_proc_ctx_entry), 0, 0, NULL);
	if (!ipa_ctx->hdr_proc_ctx_cache) {
		IPAERR(":ipa hdr proc ctx cache create failed\n");
		result = -ENOMEM;
		goto fail_hdr_proc_ctx_cache;
	}
	ipa_ctx->hdr_proc_ctx_offset_cache =
		kmem_cache_create("IPA HDR PROC CTX OFFSET",
		sizeof(struct ipa_hdr_proc_ctx_offset_entry), 0, 0, NULL);
	if (!ipa_ctx->hdr_proc_ctx_offset_cache) {
		IPAERR(":ipa hdr proc ctx off cache create failed\n");
		result = -ENOMEM;
		goto fail_hdr_proc_ctx_offset_cache;
	}
	ipa_ctx->rt_tbl_cache = kmem_cache_create("IPA RT TBL",
			sizeof(struct ipa_rt_tbl), 0, 0, NULL);
	if (!ipa_ctx->rt_tbl_cache) {
@@ -2875,6 +3108,12 @@ static int ipa_init(const struct ipa_plat_drv_res *resource_p,
		INIT_LIST_HEAD(&ipa_ctx->hdr_tbl.head_offset_list[i]);
		INIT_LIST_HEAD(&ipa_ctx->hdr_tbl.head_free_offset_list[i]);
	}
	INIT_LIST_HEAD(&ipa_ctx->hdr_proc_ctx_tbl.head_proc_ctx_entry_list);
	for (i = 0; i < IPA_HDR_PROC_CTX_BIN_MAX; i++) {
		INIT_LIST_HEAD(&ipa_ctx->hdr_proc_ctx_tbl.head_offset_list[i]);
		INIT_LIST_HEAD(&ipa_ctx->
				hdr_proc_ctx_tbl.head_free_offset_list[i]);
	}
	INIT_LIST_HEAD(&ipa_ctx->rt_tbl_set[IPA_IP_v4].head_rt_tbl_list);
	INIT_LIST_HEAD(&ipa_ctx->rt_tbl_set[IPA_IP_v6].head_rt_tbl_list);
	for (i = 0; i < IPA_NUM_PIPES; i++) {
@@ -3099,6 +3338,10 @@ fail_rx_pkt_wrapper_cache:
fail_tx_pkt_wrapper_cache:
	kmem_cache_destroy(ipa_ctx->rt_tbl_cache);
fail_rt_tbl_cache:
	kmem_cache_destroy(ipa_ctx->hdr_proc_ctx_offset_cache);
fail_hdr_proc_ctx_offset_cache:
	kmem_cache_destroy(ipa_ctx->hdr_proc_ctx_cache);
fail_hdr_proc_ctx_cache:
	kmem_cache_destroy(ipa_ctx->hdr_offset_cache);
fail_hdr_offset_cache:
	kmem_cache_destroy(ipa_ctx->hdr_cache);
+149 −26
Original line number Diff line number Diff line
@@ -63,11 +63,20 @@ const char *ipa_event_name[] = {
	__stringify(ECM_DISCONNECT),
};

const char *ipa_hdr_proc_type_name[] = {
	__stringify(IPA_HDR_PROC_NONE),
	__stringify(IPA_HDR_PROC_ETHII_TO_ETHII),
	__stringify(IPA_HDR_PROC_ETHII_TO_802_3),
	__stringify(IPA_HDR_PROC_802_3_TO_ETHII),
	__stringify(IPA_HDR_PROC_802_3_TO_802_3),
};

static struct dentry *dent;
static struct dentry *dfile_gen_reg;
static struct dentry *dfile_ep_reg;
static struct dentry *dfile_ep_holb;
static struct dentry *dfile_hdr;
static struct dentry *dfile_proc_ctx;
static struct dentry *dfile_ip4_rt;
static struct dentry *dfile_ip6_rt;
static struct dentry *dfile_ip4_flt;
@@ -363,33 +372,53 @@ static ssize_t ipa_read_hdr(struct file *file, char __user *ubuf, size_t count,
		loff_t *ppos)
{
	int nbytes = 0;
	int cnt = 0;
	int i = 0;
	struct ipa_hdr_entry *entry;

	mutex_lock(&ipa_ctx->lock);

	if (ipa_ctx->hdr_tbl_lcl)
		pr_err("Table resides on local memory\n");
	else
		pr_err("Table resides on system (ddr) memory\n");

	list_for_each_entry(entry, &ipa_ctx->hdr_tbl.head_hdr_entry_list,
			link) {
		nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
				   "name:%s len=%d ref=%d partial=%d lcl=%d ofst=%u ",
		if (entry->is_hdr_proc_ctx) {
			nbytes = scnprintf(
				dbg_buff,
				IPA_MAX_MSG_LEN,
				"name:%s len=%d ref=%d partial=%d "
				"phys_base=0x%pa ",
				entry->name,
				   entry->hdr_len, entry->ref_cnt,
				entry->hdr_len,
				entry->ref_cnt,
				entry->is_partial,
				&entry->phys_base);
		} else {
			nbytes = scnprintf(
				dbg_buff,
				IPA_MAX_MSG_LEN,
				"name:%s len=%d ref=%d partial=%d ofst=%u ",
				entry->name,
				entry->hdr_len,
				entry->ref_cnt,
				entry->is_partial,
				   ipa_ctx->hdr_tbl_lcl,
				entry->offset_entry->offset >> 2);
		}
		for (i = 0; i < entry->hdr_len; i++) {
			scnprintf(dbg_buff + cnt + nbytes + i * 2,
				  IPA_MAX_MSG_LEN - cnt - nbytes - i * 2,
			scnprintf(dbg_buff + nbytes + i * 2,
				  IPA_MAX_MSG_LEN - nbytes - i * 2,
				  "%02x", entry->hdr[i]);
		}
		scnprintf(dbg_buff + cnt + nbytes + entry->hdr_len * 2,
			  IPA_MAX_MSG_LEN - cnt - nbytes - entry->hdr_len * 2,
		scnprintf(dbg_buff + nbytes + entry->hdr_len * 2,
			  IPA_MAX_MSG_LEN - nbytes - entry->hdr_len * 2,
			  "\n");
		cnt += nbytes + entry->hdr_len * 2 + 1;
		pr_err("%s", dbg_buff);
	}
	mutex_unlock(&ipa_ctx->lock);

	return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
	return 0;
}

static int ipa_attrib_dump(struct ipa_rule_attrib *attrib,
@@ -489,6 +518,19 @@ static int ipa_attrib_dump(struct ipa_rule_attrib *attrib,
	if (attrib->attrib_mask & IPA_FLT_FRAGMENT)
		pr_err("frg ");

	if ((attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_ETHER_II) ||
		(attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_802_3)) {
		pr_err("src_mac_addr:%pM ", attrib->src_mac_addr);
	}

	if ((attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_ETHER_II) ||
		(attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_802_3)) {
		pr_err("dst_mac_addr:%pM ", attrib->dst_mac_addr);
	}

	if (attrib->attrib_mask & IPA_FLT_MAC_ETHER_TYPE)
		pr_err("ether_type:%x ", attrib->ether_type);

	pr_err("\n");
	return 0;
}
@@ -584,38 +626,62 @@ static ssize_t ipa_read_rt(struct file *file, char __user *ubuf, size_t count,
	struct ipa_rt_entry *entry;
	struct ipa_rt_tbl_set *set;
	enum ipa_ip_type ip = (enum ipa_ip_type)file->private_data;
	u32 hdr_ofst;
	u32 ofst;
	u32 ofst_words;

	set = &ipa_ctx->rt_tbl_set[ip];

	mutex_lock(&ipa_ctx->lock);

	if (ip ==  IPA_IP_v6) {
		if (ipa_ctx->ip6_rt_tbl_lcl)
			pr_err("Table Resides on local memory\n");
			pr_err("Table resides on local memory\n");
		else
			pr_err("Table Resides on system(ddr) memory\n");
			pr_err("Table resides on system (ddr) memory\n");
	} else if (ip == IPA_IP_v4) {
		if (ipa_ctx->ip4_rt_tbl_lcl)
			pr_err("Table Resides on local memory\n");
			pr_err("Table resides on local memory\n");
		else
			pr_err("Table Resides on system(ddr) memory\n");
			pr_err("Table resides on system (ddr) memory\n");
	}

	list_for_each_entry(tbl, &set->head_rt_tbl_list, link) {
		i = 0;
		list_for_each_entry(entry, &tbl->head_rt_rule_list, link) {
			if (entry->proc_ctx) {
				ofst = entry->proc_ctx->offset_entry->offset;
				ofst_words =
					(ofst +
					ipa_ctx->hdr_proc_ctx_tbl.start_offset)
					>> 5;

				pr_err(
					"tbl_idx:%d tbl_name:%s tbl_ref:%u "
					"rule_idx:%d dst:%d ep:%d S:%u "
					"proc_ctx[32B]:%u attrib_mask:%08x ",
					entry->tbl->idx, entry->tbl->name,
					entry->tbl->ref_cnt, i, entry->rule.dst,
					ipa_get_ep_mapping(entry->rule.dst),
					!ipa_ctx->hdr_tbl_lcl,
					ofst_words,
					entry->rule.attrib.attrib_mask);
			} else {
				if (entry->hdr)
				hdr_ofst = entry->hdr->offset_entry->offset;
					ofst = entry->hdr->offset_entry->offset;
				else
				hdr_ofst = 0;
					ofst = 0;

				pr_err(
					"tbl_idx:%d tbl_name:%s tbl_ref:%u rule_idx:%d dst:%d ep:%d S:%u hdr_ofst[words]:%u attrib_mask:%08x ",
					"tbl_idx:%d tbl_name:%s tbl_ref:%u "
					"rule_idx:%d dst:%d ep:%d S:%u "
					"hdr_ofst[words]:%u attrib_mask:%08x ",
					entry->tbl->idx, entry->tbl->name,
					entry->tbl->ref_cnt, i, entry->rule.dst,
					ipa_get_ep_mapping(entry->rule.dst),
					!ipa_ctx->hdr_tbl_lcl,
					hdr_ofst >> 2,
					ofst >> 2,
					entry->rule.attrib.attrib_mask);
			}

			ipa_attrib_dump(&entry->rule.attrib, ip);
			i++;
@@ -626,6 +692,52 @@ static ssize_t ipa_read_rt(struct file *file, char __user *ubuf, size_t count,
	return 0;
}

static ssize_t ipa_read_proc_ctx(struct file *file, char __user *ubuf,
		size_t count, loff_t *ppos)
{
	int nbytes = 0;
	struct ipa_hdr_proc_ctx_tbl *tbl;
	struct ipa_hdr_proc_ctx_entry *entry;
	u32 ofst_words;

	tbl = &ipa_ctx->hdr_proc_ctx_tbl;

	mutex_lock(&ipa_ctx->lock);

	if (ipa_ctx->hdr_proc_ctx_tbl_lcl)
		pr_info("Table resides on local memory\n");
	else
		pr_info("Table resides on system(ddr) memory\n");

	list_for_each_entry(entry, &tbl->head_proc_ctx_entry_list, link) {
		ofst_words = (entry->offset_entry->offset +
			ipa_ctx->hdr_proc_ctx_tbl.start_offset)
			>> 5;
		if (entry->hdr->is_hdr_proc_ctx) {
			nbytes += scnprintf(dbg_buff + nbytes,
				IPA_MAX_MSG_LEN - nbytes,
				"id:%u hdr_proc_type:%s proc_ctx[32B]:%u "
				"hdr_phys_base:0x%pa\n",
				entry->id,
				ipa_hdr_proc_type_name[entry->type],
				ofst_words,
				&entry->hdr->phys_base);
		} else {
			nbytes += scnprintf(dbg_buff + nbytes,
				IPA_MAX_MSG_LEN - nbytes,
				"id:%u hdr_proc_type:%s proc_ctx[32B]:%u "
				"hdr[words]:%u\n",
				entry->id,
				ipa_hdr_proc_type_name[entry->type],
				ofst_words,
				entry->hdr->offset_entry->offset >> 2);
		}
	}
	mutex_unlock(&ipa_ctx->lock);

	return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, nbytes);
}

static ssize_t ipa_read_flt(struct file *file, char __user *ubuf, size_t count,
		loff_t *ppos)
{
@@ -1323,6 +1435,10 @@ const struct file_operations ipa_rt_ops = {
	.open = ipa_open_dbg,
};

const struct file_operations ipa_proc_ctx_ops = {
	.read = ipa_read_proc_ctx,
};

const struct file_operations ipa_flt_ops = {
	.read = ipa_read_flt,
	.open = ipa_open_dbg,
@@ -1407,6 +1523,13 @@ void ipa_debugfs_init(void)
		goto fail;
	}

	dfile_proc_ctx = debugfs_create_file("proc_ctx", read_only_mode, dent,
		0, &ipa_proc_ctx_ops);
	if (!dfile_hdr || IS_ERR(dfile_hdr)) {
		IPAERR("fail to create file for debug_fs proc_ctx\n");
		goto fail;
	}

	dfile_ip4_rt = debugfs_create_file("ip4_rt", read_only_mode, dent,
			(void *)IPA_IP_v4, &ipa_rt_ops);
	if (!dfile_ip4_rt || IS_ERR(dfile_ip4_rt)) {
+649 −31

File changed.

Preview size limit exceeded, changes collapsed.

+49 −0
Original line number Diff line number Diff line
@@ -35,6 +35,12 @@
#define IPA_DMA_SHARED_MEM       (19)
#define IPA_IP_PACKET_TAG_STATUS (20)

/* Processing context TLV type */
#define IPA_PROC_CTX_TLV_TYPE_END 0
#define IPA_PROC_CTX_TLV_TYPE_HDR_ADD 1
#define IPA_PROC_CTX_TLV_TYPE_PROC_CMD 3


/**
 * struct ipa_flt_rule_hw_hdr - HW header of IPA filter rule
 * @word: filtering rule properties
@@ -72,6 +78,8 @@ struct ipa_flt_rule_hw_hdr {
 * @pipe_dest_idx: destination pipe index
 * @system: changed from local to system due to HW change
 * @hdr_offset: header offset
 * @proc_ctx: whether hdr_offset points to header table or to
 *	header processing context table
 */
struct ipa_rt_rule_hw_hdr {
	union {
@@ -82,6 +90,13 @@ struct ipa_rt_rule_hw_hdr {
			u32 system:1;
			u32 hdr_offset:10;
		} hdr;
		struct {
			u32 en_rule:16;
			u32 pipe_dest_idx:5;
			u32 system:1;
			u32 hdr_offset:9;
			u32 proc_ctx:1;
		} hdr_v2_5;
	} u;
};

@@ -163,6 +178,40 @@ struct ipa_hdr_init_system {
	u64 rsvd:32;
};

/**
 * struct ipa_hdr_proc_ctx_tlv -
 * HW structure of IPA processing context header - TLV part
 * @type: 0 - end type
 *        1 - header addition type
 *        3 - processing command type
 * @length: number of bytes after tlv
 *        for type:
 *        0 - needs to be 0
 *        1 - header addition length
 *        3 - number of 32B including type and length.
 * @value: specific value for type
 *        for type:
 *        0 - needs to be 0
 *        1 - header length
 *        3 - command ID (see IPA_HDR_UCP_* definitions)
 */
struct ipa_hdr_proc_ctx_tlv {
	u32 type:8;
	u32 length:8;
	u32 value:16;
};

/**
 * struct ipa_hdr_proc_ctx_hdr_add -
 * HW structure of IPA processing context - add header tlv
 * @tlv: IPA processing context TLV
 * @hdr_addr: processing context header address
 */
struct ipa_hdr_proc_ctx_hdr_add {
	struct ipa_hdr_proc_ctx_tlv tlv;
	u32 hdr_addr;
};

#define IPA_A5_MUX_HDR_EXCP_FLAG_IP		BIT(7)
#define IPA_A5_MUX_HDR_EXCP_FLAG_NAT		BIT(6)
#define IPA_A5_MUX_HDR_EXCP_FLAG_SW_FLT	BIT(5)
+138 −3

File changed.

Preview size limit exceeded, changes collapsed.

Loading