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

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

Merge "msm: ipa3: Move IPA headers building to IPAHAL"

parents c72d4465 a7f6f3fa
Loading
Loading
Loading
Loading
+10 −57
Original line number Diff line number Diff line
@@ -22,12 +22,6 @@ static const u32 ipa_hdr_proc_ctx_bin_sz[IPA_HDR_PROC_CTX_BIN_MAX] = { 32, 64};
#define HDR_PROC_TYPE_IS_VALID(type) \
	((type) >= 0 && (type) < IPA_HDR_PROC_MAX)

/* uCP command numbers */
#define IPA_HDR_UCP_802_3_TO_802_3 6
#define IPA_HDR_UCP_802_3_TO_ETHII 7
#define IPA_HDR_UCP_ETHII_TO_802_3 8
#define IPA_HDR_UCP_ETHII_TO_ETHII 9

/**
 * ipa3_generate_hdr_hw_tbl() - generates the headers table
 * @mem:	[out] buffer to put the header table
@@ -60,8 +54,8 @@ static int ipa3_generate_hdr_hw_tbl(struct ipa3_mem_buffer *mem)
			continue;
		IPADBG_LOW("hdr of len %d ofst=%d\n", entry->hdr_len,
				entry->offset_entry->offset);
		memcpy(mem->base + entry->offset_entry->offset, entry->hdr,
				entry->hdr_len);
		ipahal_cp_hdr_to_hw_buff(mem->base, entry->offset_entry->offset,
				entry->hdr, entry->hdr_len);
	}

	return 0;
@@ -77,52 +71,13 @@ static void ipa3_hdr_proc_ctx_to_hw_format(struct ipa3_mem_buffer *mem,
			link) {
		IPADBG_LOW("processing type %d ofst=%d\n",
			entry->type, entry->offset_entry->offset);
		if (entry->type == IPA_HDR_PROC_NONE) {
			struct ipa3_hdr_proc_ctx_add_hdr_seq *ctx;

			ctx = (struct ipa3_hdr_proc_ctx_add_hdr_seq *)
				(mem->base + entry->offset_entry->offset);
			ctx->hdr_add.tlv.type = IPA_PROC_CTX_TLV_TYPE_HDR_ADD;
			ctx->hdr_add.tlv.length = 1;
			ctx->hdr_add.tlv.value = entry->hdr->hdr_len;
			ctx->hdr_add.hdr_addr = (entry->hdr->is_hdr_proc_ctx) ?
				entry->hdr->phys_base :
				hdr_base_addr +
				entry->hdr->offset_entry->offset;
			IPADBG_LOW("header address 0x%x\n",
				ctx->hdr_add.hdr_addr);
			ctx->end.type = IPA_PROC_CTX_TLV_TYPE_END;
			ctx->end.length = 0;
			ctx->end.value = 0;
		} else {
			struct ipa3_hdr_proc_ctx_add_hdr_cmd_seq *ctx;

			ctx = (struct ipa3_hdr_proc_ctx_add_hdr_cmd_seq *)
				(mem->base + entry->offset_entry->offset);
			ctx->hdr_add.tlv.type = IPA_PROC_CTX_TLV_TYPE_HDR_ADD;
			ctx->hdr_add.tlv.length = 1;
			ctx->hdr_add.tlv.value = entry->hdr->hdr_len;
			ctx->hdr_add.hdr_addr = (entry->hdr->is_hdr_proc_ctx) ?
				entry->hdr->phys_base :
				hdr_base_addr +
				entry->hdr->offset_entry->offset;
			IPADBG_LOW("header address 0x%x\n",
				ctx->hdr_add.hdr_addr);
			ctx->cmd.type = IPA_PROC_CTX_TLV_TYPE_PROC_CMD;
			ctx->cmd.length = 0;
			if (entry->type == IPA_HDR_PROC_ETHII_TO_ETHII)
				ctx->cmd.value = IPA_HDR_UCP_ETHII_TO_ETHII;
			else if (entry->type == IPA_HDR_PROC_ETHII_TO_802_3)
				ctx->cmd.value = IPA_HDR_UCP_ETHII_TO_802_3;
			else if (entry->type == IPA_HDR_PROC_802_3_TO_ETHII)
				ctx->cmd.value = IPA_HDR_UCP_802_3_TO_ETHII;
			else if (entry->type == IPA_HDR_PROC_802_3_TO_802_3)
				ctx->cmd.value = IPA_HDR_UCP_802_3_TO_802_3;
			IPADBG_LOW("command id %d\n", ctx->cmd.value);
			ctx->end.type = IPA_PROC_CTX_TLV_TYPE_END;
			ctx->end.length = 0;
			ctx->end.value = 0;
		}
		ipahal_cp_proc_ctx_to_hw_buff(entry->type, mem->base,
				entry->offset_entry->offset,
				entry->hdr->hdr_len,
				entry->hdr->is_hdr_proc_ctx,
				entry->hdr->phys_base,
				hdr_base_addr,
				entry->hdr->offset_entry->offset);
	}
}

@@ -395,9 +350,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
		hdr_entry->ref_cnt++;
	entry->cookie = IPA_COOKIE;

	needed_len = (proc_ctx->type == IPA_HDR_PROC_NONE) ?
			sizeof(struct ipa3_hdr_proc_ctx_add_hdr_seq) :
			sizeof(struct ipa3_hdr_proc_ctx_add_hdr_cmd_seq);
	needed_len = ipahal_get_proc_ctx_needed_len(proc_ctx->type);

	if (needed_len <= ipa_hdr_proc_ctx_bin_sz[IPA_HDR_PROC_CTX_BIN0]) {
		bin = IPA_HDR_PROC_CTX_BIN0;
+0 −39
Original line number Diff line number Diff line
@@ -16,11 +16,6 @@

/* This header defines various HW related data types */

/* 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

#define IPA_RULE_ID_INVALID 0x3FF

/**
@@ -94,40 +89,6 @@ struct ipa3_rt_rule_hw_hdr {
	} u;
};

/**
 * struct ipa3_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 ipa3_hdr_proc_ctx_tlv {
	u32 type:8;
	u32 length:8;
	u32 value:16;
};

/**
 * struct ipa3_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 ipa3_hdr_proc_ctx_hdr_add {
	struct ipa3_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)
+0 −24
Original line number Diff line number Diff line
@@ -395,30 +395,6 @@ struct ipa3_hdr_proc_ctx_offset_entry {
	u32 bin;
};

/**
 * struct ipa3_hdr_proc_ctx_add_hdr_seq -
 * IPA processing context header - add header sequence
 * @hdr_add: add header command
 * @end: tlv end command (cmd.type must be 0)
 */
struct ipa3_hdr_proc_ctx_add_hdr_seq {
	struct ipa3_hdr_proc_ctx_hdr_add hdr_add;
	struct ipa3_hdr_proc_ctx_tlv end;
};

/**
 * struct ipa3_hdr_proc_ctx_add_hdr_cmd_seq -
 * IPA processing context header - process command sequence
 * @hdr_add: add header command
 * @cmd: tlv processing command (cmd.type must be 3)
 * @end: tlv end command (cmd.type must be 0)
 */
struct ipa3_hdr_proc_ctx_add_hdr_cmd_seq {
	struct ipa3_hdr_proc_ctx_hdr_add hdr_add;
	struct ipa3_hdr_proc_ctx_tlv cmd;
	struct ipa3_hdr_proc_ctx_tlv end;
};

/**
 struct ipa3_hdr_proc_ctx_entry - IPA processing context header table entry
 * @link: entry's link in global header table entries list
+219 −0
Original line number Diff line number Diff line
@@ -1018,6 +1018,223 @@ static void ipahal_debugfs_init(void) {}
static void ipahal_debugfs_remove(void) {}
#endif /* CONFIG_DEBUG_FS */

/*
 * ipahal_cp_hdr_to_hw_buff_v3() - copy header to hardware buffer according to
 * base address and offset given.
 * @base: dma base address
 * @offset: offset from base address where the data will be copied
 * @hdr: the header to be copied
 * @hdr_len: the length of the header
 */
static void ipahal_cp_hdr_to_hw_buff_v3(void *const base, u32 offset,
		u8 *const hdr, u32 hdr_len)
{
	memcpy(base + offset, hdr, hdr_len);
}

/*
 * ipahal_cp_proc_ctx_to_hw_buff_v3() - copy processing context to
 * base address and offset given.
 * @type: header processing context type (no processing context,
 *	IPA_HDR_PROC_ETHII_TO_ETHII etc.)
 * @base: dma base address
 * @offset: offset from base address where the data will be copied
 * @hdr_len: the length of the header
 * @is_hdr_proc_ctx: header is located in phys_base (true) or hdr_base_addr
 * @phys_base: memory location in DDR
 * @hdr_base_addr: base address in table
 * @hdr_offset_entry: offset from hdr_base_addr in table
 */
static void ipahal_cp_proc_ctx_to_hw_buff_v3(enum ipa_hdr_proc_type type,
		void *const base, u32 offset,
		u32 hdr_len, bool is_hdr_proc_ctx,
		dma_addr_t phys_base, u32 hdr_base_addr,
		u32 hdr_offset_entry){
	if (type == IPA_HDR_PROC_NONE) {
		struct ipa_hw_hdr_proc_ctx_add_hdr_seq *ctx;

		ctx = (struct ipa_hw_hdr_proc_ctx_add_hdr_seq *)
			(base + offset);
		ctx->hdr_add.tlv.type = IPA_PROC_CTX_TLV_TYPE_HDR_ADD;
		ctx->hdr_add.tlv.length = 1;
		ctx->hdr_add.tlv.value = hdr_len;
		ctx->hdr_add.hdr_addr = is_hdr_proc_ctx ? phys_base :
			hdr_base_addr + hdr_offset_entry;
		IPAHAL_DBG("header address 0x%x\n",
			ctx->hdr_add.hdr_addr);
		ctx->end.type = IPA_PROC_CTX_TLV_TYPE_END;
		ctx->end.length = 0;
		ctx->end.value = 0;
	} else {
		struct ipa_hw_hdr_proc_ctx_add_hdr_cmd_seq *ctx;

		ctx = (struct ipa_hw_hdr_proc_ctx_add_hdr_cmd_seq *)
			(base + offset);
		ctx->hdr_add.tlv.type = IPA_PROC_CTX_TLV_TYPE_HDR_ADD;
		ctx->hdr_add.tlv.length = 1;
		ctx->hdr_add.tlv.value = hdr_len;
		ctx->hdr_add.hdr_addr = is_hdr_proc_ctx ? phys_base :
			hdr_base_addr + hdr_offset_entry;
		IPAHAL_DBG("header address 0x%x\n",
			ctx->hdr_add.hdr_addr);
		ctx->cmd.type = IPA_PROC_CTX_TLV_TYPE_PROC_CMD;
		ctx->cmd.length = 0;
		switch (type) {
		case IPA_HDR_PROC_ETHII_TO_ETHII:
			ctx->cmd.value = IPA_HDR_UCP_ETHII_TO_ETHII;
		break;
		case IPA_HDR_PROC_ETHII_TO_802_3:
			ctx->cmd.value = IPA_HDR_UCP_ETHII_TO_802_3;
		break;
		case IPA_HDR_PROC_802_3_TO_ETHII:
			ctx->cmd.value = IPA_HDR_UCP_802_3_TO_ETHII;
		break;
		case IPA_HDR_PROC_802_3_TO_802_3:
			ctx->cmd.value = IPA_HDR_UCP_802_3_TO_802_3;
		break;
		default:
			IPAHAL_ERR("unknown ipa_hdr_proc_type %d", type);
			BUG();
		}
		IPAHAL_DBG("command id %d\n", ctx->cmd.value);
		ctx->end.type = IPA_PROC_CTX_TLV_TYPE_END;
		ctx->end.length = 0;
		ctx->end.value = 0;
	}
}

/*
 * ipahal_get_proc_ctx_needed_len_v3() - calculates the needed length for
 * addition of header processing context according to the type of processing
 * context.
 * @type: header processing context type (no processing context,
 *	IPA_HDR_PROC_ETHII_TO_ETHII etc.)
 */
static int ipahal_get_proc_ctx_needed_len_v3(enum ipa_hdr_proc_type type)
{
	return (type == IPA_HDR_PROC_NONE) ?
			sizeof(struct ipa_hw_hdr_proc_ctx_add_hdr_seq) :
			sizeof(struct ipa_hw_hdr_proc_ctx_add_hdr_cmd_seq);
}

/*
 * struct ipahal_hdr_funcs - headers handling functions for specific IPA
 * version
 * @ipahal_cp_hdr_to_hw_buff - copy function for regular headers
 */
struct ipahal_hdr_funcs {
	void (*ipahal_cp_hdr_to_hw_buff)(void *const base, u32 offset,
			u8 *const hdr, u32 hdr_len);

	void (*ipahal_cp_proc_ctx_to_hw_buff)(enum ipa_hdr_proc_type type,
			void *const base, u32 offset, u32 hdr_len,
			bool is_hdr_proc_ctx, dma_addr_t phys_base,
			u32 hdr_base_addr, u32 hdr_offset_entry);

	int (*ipahal_get_proc_ctx_needed_len)(enum ipa_hdr_proc_type type);
};

static struct ipahal_hdr_funcs hdr_funcs;

static void ipahal_hdr_init(enum ipa_hw_type ipa_hw_type)
{

	IPAHAL_DBG("Entry - HW_TYPE=%d\n", ipa_hw_type);

	/*
	 * once there are changes in HW and need to use different case, insert
	 * new case for the new h/w. put the default always for the latest HW
	 * and make sure all previous supported versions have their cases.
	 */
	switch (ipa_hw_type) {
	case IPA_HW_v3_0:
	default:
		hdr_funcs.ipahal_cp_hdr_to_hw_buff =
				ipahal_cp_hdr_to_hw_buff_v3;
		hdr_funcs.ipahal_cp_proc_ctx_to_hw_buff =
				ipahal_cp_proc_ctx_to_hw_buff_v3;
		hdr_funcs.ipahal_get_proc_ctx_needed_len =
				ipahal_get_proc_ctx_needed_len_v3;
	}
	IPAHAL_DBG("Exit\n");
}

/*
 * ipahal_cp_hdr_to_hw_buff() - copy header to hardware buffer according to
 * base address and offset given.
 * @base: dma base address
 * @offset: offset from base address where the data will be copied
 * @hdr: the header to be copied
 * @hdr_len: the length of the header
 */
void ipahal_cp_hdr_to_hw_buff(void *base, u32 offset, u8 *const hdr,
		u32 hdr_len)
{
	IPAHAL_DBG_LOW("Entry\n");
	IPAHAL_DBG("base %p, offset %d, hdr %p, hdr_len %d\n", base,
			offset, hdr, hdr_len);
	BUG_ON(!base || !hdr_len || !hdr);

	hdr_funcs.ipahal_cp_hdr_to_hw_buff(base, offset, hdr, hdr_len);

	IPAHAL_DBG_LOW("Exit\n");
}

/*
 * ipahal_cp_proc_ctx_to_hw_buff() - copy processing context to
 * base address and offset given.
 * @type: type of header processing context
 * @base: dma base address
 * @offset: offset from base address where the data will be copied
 * @hdr_len: the length of the header
 * @is_hdr_proc_ctx: header is located in phys_base (true) or hdr_base_addr
 * @phys_base: memory location in DDR
 * @hdr_base_addr: base address in table
 * @hdr_offset_entry: offset from hdr_base_addr in table
 */
void ipahal_cp_proc_ctx_to_hw_buff(enum ipa_hdr_proc_type type,
		void *const base, u32 offset, u32 hdr_len,
		bool is_hdr_proc_ctx, dma_addr_t phys_base,
		u32 hdr_base_addr, u32 hdr_offset_entry)
{
	IPAHAL_DBG_LOW("entry\n");
	IPAHAL_DBG(
		"type %d, base %p, offset %d, hdr_len %d, is_hdr_proc_ctx %d, hdr_base_addr %d, hdr_offset_entry %d\n"
			, type, base, offset, hdr_len, is_hdr_proc_ctx,
			hdr_base_addr, hdr_offset_entry);

	BUG_ON(!base ||
		!hdr_len ||
		(!phys_base && !hdr_base_addr) ||
		!hdr_base_addr);

	hdr_funcs.ipahal_cp_proc_ctx_to_hw_buff(type, base, offset,
			hdr_len, is_hdr_proc_ctx, phys_base,
			hdr_base_addr, hdr_offset_entry);

	IPAHAL_DBG_LOW("Exit\n");
}

/*
 * ipahal_get_proc_ctx_needed_len() - calculates the needed length for
 * addition of header processing context according to the type of processing
 * context
 * @type: header processing context type (no processing context,
 *	IPA_HDR_PROC_ETHII_TO_ETHII etc.)
 */
int ipahal_get_proc_ctx_needed_len(enum ipa_hdr_proc_type type)
{
	int res;

	IPAHAL_DBG("entry\n");

	res = hdr_funcs.ipahal_get_proc_ctx_needed_len(type);

	IPAHAL_DBG("Exit\n");

	return res;
}

int ipahal_init(enum ipa_hw_type ipa_hw_type, void __iomem *base)
{
	int result;
@@ -1065,6 +1282,8 @@ int ipahal_init(enum ipa_hw_type ipa_hw_type, void __iomem *base)
		goto bail_free_ctx;
	}

	ipahal_hdr_init(ipa_hw_type);

	ipahal_debugfs_init();

	return 0;
+35 −0
Original line number Diff line number Diff line
@@ -597,6 +597,41 @@ void ipahal_pkt_status_parse(const void *unparsed_status,
const char *ipahal_pkt_status_exception_str(
	enum ipahal_pkt_status_exception exception);

/*
 * ipahal_cp_hdr_to_hw_buff() - copy header to hardware buffer according to
 * base address and offset given.
 * @base: dma base address
 * @offset: offset from base address where the data will be copied
 * @hdr: the header to be copied
 * @hdr_len: the length of the header
 */
void ipahal_cp_hdr_to_hw_buff(void *base, u32 offset, u8 *hdr, u32 hdr_len);

/*
 * ipahal_cp_proc_ctx_to_hw_buff() - copy processing context to
 * base address and offset given.
 * @type: type of header processing context
 * @base: dma base address
 * @offset: offset from base address where the data will be copied
 * @hdr_len: the length of the header
 * @is_hdr_proc_ctx: header is located in phys_base (true) or hdr_base_addr
 * @phys_base: memory location in DDR
 * @hdr_base_addr: base address in table
 * @hdr_offset_entry: offset from hdr_base_addr in table
 */
void ipahal_cp_proc_ctx_to_hw_buff(enum ipa_hdr_proc_type type,
		void *base, u32 offset, u32 hdr_len,
		bool is_hdr_proc_ctx, dma_addr_t phys_base,
		u32 hdr_base_addr, u32 hdr_offset_entry);

/*
 * ipahal_get_proc_ctx_needed_len() - calculates the needed length for addition
 * of header processing context according to the type of processing context
 * @type: header processing context type (no processing context,
 *	IPA_HDR_PROC_ETHII_TO_ETHII etc.)
 */
int ipahal_get_proc_ctx_needed_len(enum ipa_hdr_proc_type type);

int ipahal_init(enum ipa_hw_type ipa_hw_type, void __iomem *base);
void ipahal_destroy(void);

Loading