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

Commit 3a0820ab authored by Bojun Pan's avatar Bojun Pan Committed by Gerrit - the friendly Code Review server
Browse files

msm: ipa3: IPA SW counter support for FnR stats



Add support for SW counter set on FnR stats.

Change-Id: Iec55a9dd8671337dcfefc11255c8bcf79df44a31
Signed-off-by: default avatarBojun Pan <bojunp@codeaurora.org>
parent 4a2c0fae
Loading
Loading
Loading
Loading
+111 −0
Original line number Diff line number Diff line
@@ -1084,6 +1084,117 @@ int ipa_get_flt_rt_stats(struct ipa_ioc_flt_rt_query *query)
	return __ipa_get_flt_rt_stats(query);
}


static int __ipa_set_flt_rt_stats(int index, struct ipa_flt_rt_stats stats)
{
	int ret;
	int smem_ofst;
	struct ipahal_stats_get_offset_flt_rt_v4_5 *get_offset;
	struct ipahal_stats_offset offset = { 0 };
	struct ipahal_imm_cmd_dma_shared_mem cmd = { 0 };
	struct ipahal_imm_cmd_pyld *cmd_pyld;
	struct ipa_mem_buffer mem;
	struct ipa3_desc desc = { 0 };

	get_offset = kzalloc(sizeof(*get_offset), GFP_KERNEL);
	if (!get_offset) {
		IPADBG("no mem\n");
		return -ENOMEM;
	}

	smem_ofst = IPA_MEM_PART(stats_fnr_ofst);

	get_offset->start_id = index;
	get_offset->end_id = index;

	ret = ipahal_stats_get_offset(IPAHAL_HW_STATS_FNR, get_offset,
		&offset);
	if (ret) {
		IPAERR("failed to get offset from hal %d\n", ret);
		goto free_offset;
	}

	IPADBG("offset = %d size = %d\n", offset.offset, offset.size);

	if (offset.size == 0) {
		ret = 0;
		goto free_offset;
	}

	mem.size = offset.size;
	mem.base = dma_alloc_coherent(ipa3_ctx->pdev,
		mem.size,
		&mem.phys_base,
		GFP_KERNEL);
	if (!mem.base) {
		IPAERR("fail to alloc DMA memory\n");
		goto free_offset;
	}
	ipahal_set_flt_rt_sw_stats(mem.base, stats);

	cmd.is_read = false;
	cmd.skip_pipeline_clear = false;
	cmd.pipeline_clear_options = IPAHAL_HPS_CLEAR;
	cmd.size = mem.size;
	cmd.system_addr = mem.phys_base;
	cmd.local_addr = ipa3_ctx->smem_restricted_bytes +
		smem_ofst + offset.offset;
	cmd_pyld = ipahal_construct_imm_cmd(
		IPA_IMM_CMD_DMA_SHARED_MEM, &cmd, false);
	if (!cmd_pyld) {
		IPAERR("failed to construct dma_shared_mem imm cmd\n");
		ret = -ENOMEM;
		goto free_dma_mem;
	}
	desc.opcode = cmd_pyld->opcode;
	desc.pyld = cmd_pyld->data;
	desc.len = cmd_pyld->len;
	desc.type = IPA_IMM_CMD_DESC;

	ret = ipa3_send_cmd(1, &desc);
	if (ret) {
		IPAERR("failed to send immediate command (error %d)\n", ret);
		goto destroy_imm;
	}

	ret = 0;

destroy_imm:
	ipahal_destroy_imm_cmd(cmd_pyld);
free_dma_mem:
	dma_free_coherent(ipa3_ctx->pdev, mem.size, mem.base, mem.phys_base);
free_offset:
	kfree(get_offset);
	return ret;
}

int ipa_set_flt_rt_stats(int index, struct ipa_flt_rt_stats stats)
{
	if (!ipa3_ctx->hw_stats.enabled) {
		IPAERR("hw_stats is not enabled\n");
		return 0;
	}

	if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_5) {
		IPAERR("FnR stats not supported in %d hw_type\n",
			ipa3_ctx->ipa_hw_type);
		return 0;
	}

	if (index > IPA_MAX_FLT_RT_CNT_INDEX) {
		IPAERR("index %d out of range\n", index);
		return -EINVAL;
	}

	if (index <= IPA_FLT_RT_HW_COUNTER) {
		IPAERR("index %d invalid, only support sw counter set\n",
			index);
		return -EINVAL;
	}

	return __ipa_set_flt_rt_stats(index, stats);
}

int ipa_init_drop_stats(u32 pipe_bitmask)
{
	struct ipahal_stats_init_pyld *pyld;
+2 −0
Original line number Diff line number Diff line
@@ -2816,6 +2816,8 @@ int ipa_reset_all_teth_stats(void);

int ipa_get_flt_rt_stats(struct ipa_ioc_flt_rt_query *query);

int ipa_set_flt_rt_stats(int index, struct ipa_flt_rt_stats stats);

u32 ipa3_get_num_pipes(void);
struct ipa_smmu_cb_ctx *ipa3_get_smmu_ctx(enum ipa_smmu_cb_type);
struct iommu_domain *ipa3_get_smmu_domain(void);
+12 −0
Original line number Diff line number Diff line
@@ -620,3 +620,15 @@ int ipahal_parse_stats(enum ipahal_hw_stats_type type, void *init_params,
	return ipahal_hw_stats_objs[ipahal_ctx->hw_type][type].parse_stats(
		init_params, raw_stats, parsed_stats);
}

void ipahal_set_flt_rt_sw_stats(void *raw_stats,
	struct ipa_flt_rt_stats sw_stats)
{
	struct ipahal_stats_flt_rt_v4_5_hw *raw_hw =
		(struct ipahal_stats_flt_rt_v4_5_hw *)raw_stats;

	IPAHAL_DBG_LOW("\n");
	raw_hw->num_bytes = sw_stats.num_bytes;
	raw_hw->num_packets_hash = sw_stats.num_pkts_hash;
	raw_hw->num_packets = sw_stats.num_pkts;
}
+10 −0
Original line number Diff line number Diff line
@@ -260,4 +260,14 @@ int ipahal_parse_stats(enum ipahal_hw_stats_type type, void *init_params,
	void *raw_stats, void *parsed_stats);


/*
 * ipahal_set_flt_rt_sw_stats - set sw counter stats for FnR
 * @raw_stats: stats write to IPA SRAM
 * @sw_stats: FnR sw stats to be written
 *
 * Return: None
 */
void ipahal_set_flt_rt_sw_stats(void *raw_stats,
	struct ipa_flt_rt_stats sw_stats);

#endif /* _IPAHAL_HW_STATS_H_ */
+73 −0
Original line number Diff line number Diff line
@@ -663,6 +663,71 @@ static int ipa_test_hw_stats_query_FnR_clean(void *priv)
	return ret;
}


static int ipa_test_hw_stats_query_sw_stats(void *priv)
{
	int ret, i, start = 0;
	struct ipa_ioc_flt_rt_query *query;
	int pyld_size = 0;

	query = kzalloc(sizeof(struct ipa_ioc_flt_rt_query), GFP_KERNEL);
	if (!query)
		return -ENOMEM;
	pyld_size = IPA_MAX_FLT_RT_CNT_INDEX *
		sizeof(struct ipa_flt_rt_stats);
	query->stats = (uint64_t)kzalloc(pyld_size, GFP_KERNEL);
	if (!query->stats) {
		kfree(query);
		return -ENOMEM;
	}

	/* query all together */
	IPA_UT_INFO("========query all SW counters========\n");
	query->start_id = IPA_FLT_RT_HW_COUNTER + 1;
	query->end_id = IPA_MAX_FLT_RT_CNT_INDEX;
	ipa_get_flt_rt_stats(query);
	start = 0;
	for (i = IPA_FLT_RT_HW_COUNTER + 1;
		i <= IPA_MAX_FLT_RT_CNT_INDEX; i++) {
		IPA_UT_INFO(
			"counter %u pkt_cnt %u bytes cnt %llu\n",
			i, ((struct ipa_flt_rt_stats *)
			query->stats)[start].num_pkts,
			((struct ipa_flt_rt_stats *)
			query->stats)[start].num_bytes);
		start++;
	}
	IPA_UT_INFO("================ done ============\n");

	ret = 0;
	kfree((void *)(query->stats));
	kfree(query);
	return ret;
}

static int ipa_test_hw_stats_set_sw_stats(void *priv)
{
	int ret = 0, i, start = 0;
	struct ipa_flt_rt_stats stats;

	/* set sw counters */
	IPA_UT_INFO("========set all SW counters========\n");
	for (i = IPA_FLT_RT_HW_COUNTER + 1;
		i <= IPA_MAX_FLT_RT_CNT_INDEX; i++) {
		stats.num_bytes = start;
		stats.num_pkts_hash = start + 10;
		stats.num_pkts = start + 100;
		IPA_UT_INFO(
			"set counter %u pkt_cnt %u bytes cnt %llu\n",
			i, stats.num_pkts, stats.num_bytes);
		ipa_set_flt_rt_stats(i, stats);
		start++;
	}
	IPA_UT_INFO("================ done ============\n");

	return ret;
}

/* Suite definition block */
IPA_UT_DEFINE_SUITE_START(hw_stats, "HW stats test",
	ipa_test_hw_stats_suite_setup, ipa_test_hw_stats_suite_teardown)
@@ -685,4 +750,12 @@ IPA_UT_DEFINE_SUITE_START(hw_stats, "HW stats test",
		ipa_test_hw_stats_query_FnR_clean, false,
		IPA_HW_v4_5, IPA_HW_MAX),

	IPA_UT_ADD_TEST(query_sw_stats, "Query SW stats",
		ipa_test_hw_stats_query_sw_stats, false,
		IPA_HW_v4_5, IPA_HW_MAX),

	IPA_UT_ADD_TEST(set_sw_stats, "Set SW stats to dummy values",
		ipa_test_hw_stats_set_sw_stats, false,
		IPA_HW_v4_5, IPA_HW_MAX),

} IPA_UT_DEFINE_SUITE_END(hw_stats);