114b24e2bSVaishali Kulkarni /*
214b24e2bSVaishali Kulkarni * CDDL HEADER START
314b24e2bSVaishali Kulkarni *
414b24e2bSVaishali Kulkarni * The contents of this file are subject to the terms of the
514b24e2bSVaishali Kulkarni * Common Development and Distribution License, v.1,  (the "License").
614b24e2bSVaishali Kulkarni * You may not use this file except in compliance with the License.
714b24e2bSVaishali Kulkarni *
814b24e2bSVaishali Kulkarni * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
914b24e2bSVaishali Kulkarni * or http://opensource.org/licenses/CDDL-1.0.
1014b24e2bSVaishali Kulkarni * See the License for the specific language governing permissions
1114b24e2bSVaishali Kulkarni * and limitations under the License.
1214b24e2bSVaishali Kulkarni *
1314b24e2bSVaishali Kulkarni * When distributing Covered Code, include this CDDL HEADER in each
1414b24e2bSVaishali Kulkarni * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1514b24e2bSVaishali Kulkarni * If applicable, add the following below this CDDL HEADER, with the
1614b24e2bSVaishali Kulkarni * fields enclosed by brackets "[]" replaced with your own identifying
1714b24e2bSVaishali Kulkarni * information: Portions Copyright [yyyy] [name of copyright owner]
1814b24e2bSVaishali Kulkarni *
1914b24e2bSVaishali Kulkarni * CDDL HEADER END
2014b24e2bSVaishali Kulkarni */
2114b24e2bSVaishali Kulkarni 
2214b24e2bSVaishali Kulkarni /*
2314b24e2bSVaishali Kulkarni * Copyright 2014-2017 Cavium, Inc.
2414b24e2bSVaishali Kulkarni * The contents of this file are subject to the terms of the Common Development
2514b24e2bSVaishali Kulkarni * and Distribution License, v.1,  (the "License").
2614b24e2bSVaishali Kulkarni 
2714b24e2bSVaishali Kulkarni * You may not use this file except in compliance with the License.
2814b24e2bSVaishali Kulkarni 
2914b24e2bSVaishali Kulkarni * You can obtain a copy of the License at available
3014b24e2bSVaishali Kulkarni * at http://opensource.org/licenses/CDDL-1.0
3114b24e2bSVaishali Kulkarni 
3214b24e2bSVaishali Kulkarni * See the License for the specific language governing permissions and
3314b24e2bSVaishali Kulkarni * limitations under the License.
3414b24e2bSVaishali Kulkarni */
3514b24e2bSVaishali Kulkarni 
3614b24e2bSVaishali Kulkarni #include "bcm_osal.h"
3714b24e2bSVaishali Kulkarni #include "reg_addr.h"
3814b24e2bSVaishali Kulkarni #include "common_hsi.h"
3914b24e2bSVaishali Kulkarni #include "ecore_hsi_common.h"
4014b24e2bSVaishali Kulkarni #include "ecore_hsi_eth.h"
4114b24e2bSVaishali Kulkarni #include "tcp_common.h"
4214b24e2bSVaishali Kulkarni #include "ecore_hsi_iscsi.h"
4314b24e2bSVaishali Kulkarni #include "ecore_hsi_fcoe.h"
4414b24e2bSVaishali Kulkarni #include "ecore_hsi_roce.h"
4514b24e2bSVaishali Kulkarni #include "ecore_hsi_iwarp.h"
4614b24e2bSVaishali Kulkarni #include "ecore_rt_defs.h"
4714b24e2bSVaishali Kulkarni #include "ecore_status.h"
4814b24e2bSVaishali Kulkarni #include "ecore.h"
4914b24e2bSVaishali Kulkarni #include "ecore_init_ops.h"
5014b24e2bSVaishali Kulkarni #include "ecore_init_fw_funcs.h"
5114b24e2bSVaishali Kulkarni #include "ecore_cxt.h"
5214b24e2bSVaishali Kulkarni #include "ecore_hw.h"
5314b24e2bSVaishali Kulkarni #include "ecore_dev_api.h"
5414b24e2bSVaishali Kulkarni #include "ecore_sriov.h"
5514b24e2bSVaishali Kulkarni #include "ecore_roce.h"
5614b24e2bSVaishali Kulkarni #include "ecore_mcp.h"
5714b24e2bSVaishali Kulkarni 
5814b24e2bSVaishali Kulkarni /* Max number of connection types in HW (DQ/CDU etc.) */
5914b24e2bSVaishali Kulkarni #define MAX_CONN_TYPES		PROTOCOLID_COMMON
6014b24e2bSVaishali Kulkarni #define NUM_TASK_TYPES		2
6114b24e2bSVaishali Kulkarni #define NUM_TASK_PF_SEGMENTS	4
6214b24e2bSVaishali Kulkarni #define NUM_TASK_VF_SEGMENTS	1
6314b24e2bSVaishali Kulkarni 
6414b24e2bSVaishali Kulkarni /* Doorbell-Queue constants */
6514b24e2bSVaishali Kulkarni #define DQ_RANGE_SHIFT	4
6614b24e2bSVaishali Kulkarni #define DQ_RANGE_ALIGN	(1 << DQ_RANGE_SHIFT)
6714b24e2bSVaishali Kulkarni 
6814b24e2bSVaishali Kulkarni /* Searcher constants */
6914b24e2bSVaishali Kulkarni #define SRC_MIN_NUM_ELEMS 256
7014b24e2bSVaishali Kulkarni 
7114b24e2bSVaishali Kulkarni /* Timers constants */
7214b24e2bSVaishali Kulkarni #define TM_SHIFT	7
7314b24e2bSVaishali Kulkarni #define TM_ALIGN	(1 << TM_SHIFT)
7414b24e2bSVaishali Kulkarni #define TM_ELEM_SIZE	4
7514b24e2bSVaishali Kulkarni 
7614b24e2bSVaishali Kulkarni /* ILT constants */
7714b24e2bSVaishali Kulkarni /* If for some reason, HW P size is modified to be less than 32K,
7814b24e2bSVaishali Kulkarni  * special handling needs to be made for CDU initialization
7914b24e2bSVaishali Kulkarni  */
8014b24e2bSVaishali Kulkarni #ifdef CONFIG_ECORE_ROCE
8114b24e2bSVaishali Kulkarni /* For RoCE we configure to 64K to cover for RoCE max tasks 256K purpose. Can be
8214b24e2bSVaishali Kulkarni  * optimized with resource management scheme
8314b24e2bSVaishali Kulkarni  */
8414b24e2bSVaishali Kulkarni #define ILT_DEFAULT_HW_P_SIZE	4
8514b24e2bSVaishali Kulkarni #else
8614b24e2bSVaishali Kulkarni #define ILT_DEFAULT_HW_P_SIZE	3
8714b24e2bSVaishali Kulkarni #endif
8814b24e2bSVaishali Kulkarni 
8914b24e2bSVaishali Kulkarni #define ILT_PAGE_IN_BYTES(hw_p_size)	(1U << ((hw_p_size) + 12))
9014b24e2bSVaishali Kulkarni #define ILT_CFG_REG(cli, reg)		PSWRQ2_REG_##cli##_##reg##_RT_OFFSET
9114b24e2bSVaishali Kulkarni 
9214b24e2bSVaishali Kulkarni /* ILT entry structure */
9314b24e2bSVaishali Kulkarni #define ILT_ENTRY_PHY_ADDR_MASK		0x000FFFFFFFFFFFULL
9414b24e2bSVaishali Kulkarni #define ILT_ENTRY_PHY_ADDR_SHIFT	0
9514b24e2bSVaishali Kulkarni #define ILT_ENTRY_VALID_MASK		0x1ULL
9614b24e2bSVaishali Kulkarni #define ILT_ENTRY_VALID_SHIFT		52
9714b24e2bSVaishali Kulkarni #define ILT_ENTRY_IN_REGS		2
9814b24e2bSVaishali Kulkarni #define ILT_REG_SIZE_IN_BYTES		4
9914b24e2bSVaishali Kulkarni 
10014b24e2bSVaishali Kulkarni /* connection context union */
10114b24e2bSVaishali Kulkarni union conn_context {
10214b24e2bSVaishali Kulkarni 	struct core_conn_context  core_ctx;
10314b24e2bSVaishali Kulkarni 	struct eth_conn_context	  eth_ctx;
10414b24e2bSVaishali Kulkarni 	struct iscsi_conn_context iscsi_ctx;
10514b24e2bSVaishali Kulkarni 	struct fcoe_conn_context  fcoe_ctx;
10614b24e2bSVaishali Kulkarni 	struct roce_conn_context  roce_ctx;
10714b24e2bSVaishali Kulkarni };
10814b24e2bSVaishali Kulkarni 
10914b24e2bSVaishali Kulkarni /* TYPE-0 task context - iSCSI, FCOE */
11014b24e2bSVaishali Kulkarni union type0_task_context {
11114b24e2bSVaishali Kulkarni 	struct iscsi_task_context iscsi_ctx;
11214b24e2bSVaishali Kulkarni 	struct fcoe_task_context  fcoe_ctx;
11314b24e2bSVaishali Kulkarni };
11414b24e2bSVaishali Kulkarni 
11514b24e2bSVaishali Kulkarni /* TYPE-1 task context - ROCE */
11614b24e2bSVaishali Kulkarni union type1_task_context {
11714b24e2bSVaishali Kulkarni 	struct rdma_task_context roce_ctx;
11814b24e2bSVaishali Kulkarni };
11914b24e2bSVaishali Kulkarni 
12014b24e2bSVaishali Kulkarni struct src_ent {
12114b24e2bSVaishali Kulkarni 	u8  opaque[56];
12214b24e2bSVaishali Kulkarni 	u64 next;
12314b24e2bSVaishali Kulkarni };
12414b24e2bSVaishali Kulkarni 
12514b24e2bSVaishali Kulkarni #define CDUT_SEG_ALIGNMET 3 /* in 4k chunks */
12614b24e2bSVaishali Kulkarni #define CDUT_SEG_ALIGNMET_IN_BYTES (1 << (CDUT_SEG_ALIGNMET + 12))
12714b24e2bSVaishali Kulkarni 
12814b24e2bSVaishali Kulkarni #define CONN_CXT_SIZE(p_hwfn) \
12914b24e2bSVaishali Kulkarni 	ALIGNED_TYPE_SIZE(union conn_context, p_hwfn)
13014b24e2bSVaishali Kulkarni 
13114b24e2bSVaishali Kulkarni #define SRQ_CXT_SIZE (sizeof(struct rdma_srq_context))
13214b24e2bSVaishali Kulkarni 
13314b24e2bSVaishali Kulkarni #define TYPE0_TASK_CXT_SIZE(p_hwfn) \
13414b24e2bSVaishali Kulkarni 	ALIGNED_TYPE_SIZE(union type0_task_context, p_hwfn)
13514b24e2bSVaishali Kulkarni 
13614b24e2bSVaishali Kulkarni /* Alignment is inherent to the type1_task_context structure */
13714b24e2bSVaishali Kulkarni #define TYPE1_TASK_CXT_SIZE(p_hwfn) sizeof(union type1_task_context)
13814b24e2bSVaishali Kulkarni 
13914b24e2bSVaishali Kulkarni /* PF per protocl configuration object */
14014b24e2bSVaishali Kulkarni #define TASK_SEGMENTS   (NUM_TASK_PF_SEGMENTS + NUM_TASK_VF_SEGMENTS)
14114b24e2bSVaishali Kulkarni #define TASK_SEGMENT_VF (NUM_TASK_PF_SEGMENTS)
14214b24e2bSVaishali Kulkarni 
14314b24e2bSVaishali Kulkarni struct ecore_tid_seg {
14414b24e2bSVaishali Kulkarni 	u32	count;
14514b24e2bSVaishali Kulkarni 	u8	type;
14614b24e2bSVaishali Kulkarni 	bool	has_fl_mem;
14714b24e2bSVaishali Kulkarni };
14814b24e2bSVaishali Kulkarni 
14914b24e2bSVaishali Kulkarni struct ecore_conn_type_cfg {
15014b24e2bSVaishali Kulkarni 	u32			cid_count;
15114b24e2bSVaishali Kulkarni 	u32			cids_per_vf;
15214b24e2bSVaishali Kulkarni 	struct ecore_tid_seg	tid_seg[TASK_SEGMENTS];
15314b24e2bSVaishali Kulkarni };
15414b24e2bSVaishali Kulkarni 
15514b24e2bSVaishali Kulkarni /* ILT Client configuration,
15614b24e2bSVaishali Kulkarni  * Per connection type (protocol) resources (cids, tis, vf cids etc.)
15714b24e2bSVaishali Kulkarni  * 1 - for connection context (CDUC) and for each task context we need two
15814b24e2bSVaishali Kulkarni  * values, for regular task context and for force load memory
15914b24e2bSVaishali Kulkarni  */
16014b24e2bSVaishali Kulkarni #define ILT_CLI_PF_BLOCKS	(1 + NUM_TASK_PF_SEGMENTS * 2)
16114b24e2bSVaishali Kulkarni #define ILT_CLI_VF_BLOCKS	(1 + NUM_TASK_VF_SEGMENTS * 2)
16214b24e2bSVaishali Kulkarni #define CDUC_BLK		(0)
16314b24e2bSVaishali Kulkarni #define SRQ_BLK			(0)
16414b24e2bSVaishali Kulkarni #define CDUT_SEG_BLK(n)		(1 + (u8)(n))
16514b24e2bSVaishali Kulkarni #define CDUT_FL_SEG_BLK(n, X)	(1 + (n) + NUM_TASK_##X##_SEGMENTS)
16614b24e2bSVaishali Kulkarni 
16714b24e2bSVaishali Kulkarni enum ilt_clients {
16814b24e2bSVaishali Kulkarni 	ILT_CLI_CDUC,
16914b24e2bSVaishali Kulkarni 	ILT_CLI_CDUT,
17014b24e2bSVaishali Kulkarni 	ILT_CLI_QM,
17114b24e2bSVaishali Kulkarni 	ILT_CLI_TM,
17214b24e2bSVaishali Kulkarni 	ILT_CLI_SRC,
17314b24e2bSVaishali Kulkarni 	ILT_CLI_TSDM,
17414b24e2bSVaishali Kulkarni 	ILT_CLI_MAX
17514b24e2bSVaishali Kulkarni };
17614b24e2bSVaishali Kulkarni 
17714b24e2bSVaishali Kulkarni struct ilt_cfg_pair {
17814b24e2bSVaishali Kulkarni 	u32 reg;
17914b24e2bSVaishali Kulkarni 	u32 val;
18014b24e2bSVaishali Kulkarni };
18114b24e2bSVaishali Kulkarni 
18214b24e2bSVaishali Kulkarni struct ecore_ilt_cli_blk {
18314b24e2bSVaishali Kulkarni 	u32 total_size; /* 0 means not active */
18414b24e2bSVaishali Kulkarni 	u32 real_size_in_page;
18514b24e2bSVaishali Kulkarni 	u32 start_line;
18614b24e2bSVaishali Kulkarni 	u32 dynamic_line_cnt;
18714b24e2bSVaishali Kulkarni };
18814b24e2bSVaishali Kulkarni 
18914b24e2bSVaishali Kulkarni struct ecore_ilt_client_cfg {
19014b24e2bSVaishali Kulkarni 	bool				active;
19114b24e2bSVaishali Kulkarni 
19214b24e2bSVaishali Kulkarni 	/* ILT boundaries */
19314b24e2bSVaishali Kulkarni 	struct ilt_cfg_pair		first;
19414b24e2bSVaishali Kulkarni 	struct ilt_cfg_pair		last;
19514b24e2bSVaishali Kulkarni 	struct ilt_cfg_pair		p_size;
19614b24e2bSVaishali Kulkarni 
19714b24e2bSVaishali Kulkarni 	/* ILT client blocks for PF */
19814b24e2bSVaishali Kulkarni 	struct ecore_ilt_cli_blk	pf_blks[ILT_CLI_PF_BLOCKS];
19914b24e2bSVaishali Kulkarni 	u32				pf_total_lines;
20014b24e2bSVaishali Kulkarni 
20114b24e2bSVaishali Kulkarni 	/* ILT client blocks for VFs */
20214b24e2bSVaishali Kulkarni 	struct ecore_ilt_cli_blk	vf_blks[ILT_CLI_VF_BLOCKS];
20314b24e2bSVaishali Kulkarni 	u32				vf_total_lines;
20414b24e2bSVaishali Kulkarni };
20514b24e2bSVaishali Kulkarni 
20614b24e2bSVaishali Kulkarni /* Per Path -
20714b24e2bSVaishali Kulkarni  *      ILT shadow table
20814b24e2bSVaishali Kulkarni  *      Protocol acquired CID lists
20914b24e2bSVaishali Kulkarni  *      PF start line in ILT
21014b24e2bSVaishali Kulkarni  */
21114b24e2bSVaishali Kulkarni struct ecore_dma_mem {
21214b24e2bSVaishali Kulkarni 	dma_addr_t	p_phys;
21314b24e2bSVaishali Kulkarni 	void		*p_virt;
21414b24e2bSVaishali Kulkarni 	osal_size_t	size;
21514b24e2bSVaishali Kulkarni };
21614b24e2bSVaishali Kulkarni 
21714b24e2bSVaishali Kulkarni #define MAP_WORD_SIZE		sizeof(unsigned long)
21814b24e2bSVaishali Kulkarni #define BITS_PER_MAP_WORD	(MAP_WORD_SIZE * 8)
21914b24e2bSVaishali Kulkarni 
22014b24e2bSVaishali Kulkarni struct ecore_cid_acquired_map {
22114b24e2bSVaishali Kulkarni 	u32		start_cid;
22214b24e2bSVaishali Kulkarni 	u32		max_count;
22314b24e2bSVaishali Kulkarni 	unsigned long	*cid_map;
22414b24e2bSVaishali Kulkarni };
22514b24e2bSVaishali Kulkarni 
22614b24e2bSVaishali Kulkarni struct ecore_cxt_mngr {
22714b24e2bSVaishali Kulkarni 	/* Per protocl configuration */
22814b24e2bSVaishali Kulkarni 	struct ecore_conn_type_cfg	conn_cfg[MAX_CONN_TYPES];
22914b24e2bSVaishali Kulkarni 
23014b24e2bSVaishali Kulkarni 	/* computed ILT structure */
23114b24e2bSVaishali Kulkarni 	struct ecore_ilt_client_cfg	clients[ILT_CLI_MAX];
23214b24e2bSVaishali Kulkarni 
23314b24e2bSVaishali Kulkarni 	/* Task type sizes */
23414b24e2bSVaishali Kulkarni 	u32				task_type_size[NUM_TASK_TYPES];
23514b24e2bSVaishali Kulkarni 
23614b24e2bSVaishali Kulkarni 	/* total number of VFs for this hwfn -
23714b24e2bSVaishali Kulkarni 	 * ALL VFs are symmetric in terms of HW resources
23814b24e2bSVaishali Kulkarni 	 */
23914b24e2bSVaishali Kulkarni 	u32				vf_count;
24014b24e2bSVaishali Kulkarni 
24114b24e2bSVaishali Kulkarni 	/* Acquired CIDs */
24214b24e2bSVaishali Kulkarni 	struct ecore_cid_acquired_map acquired[MAX_CONN_TYPES];
24314b24e2bSVaishali Kulkarni 	/* TBD - do we want this allocated to reserve space? */
24414b24e2bSVaishali Kulkarni 	struct ecore_cid_acquired_map acquired_vf[MAX_CONN_TYPES][COMMON_MAX_NUM_VFS];
24514b24e2bSVaishali Kulkarni 
24614b24e2bSVaishali Kulkarni 	/* ILT shadow table */
24714b24e2bSVaishali Kulkarni 	struct ecore_dma_mem		*ilt_shadow;
24814b24e2bSVaishali Kulkarni 	u32				pf_start_line;
24914b24e2bSVaishali Kulkarni 
25014b24e2bSVaishali Kulkarni 	/* Mutex for a dynamic ILT allocation */
25114b24e2bSVaishali Kulkarni 	osal_mutex_t			mutex;
25214b24e2bSVaishali Kulkarni 
25314b24e2bSVaishali Kulkarni 	/* SRC T2 */
25414b24e2bSVaishali Kulkarni 	struct ecore_dma_mem		*t2;
25514b24e2bSVaishali Kulkarni 	u32				t2_num_pages;
25614b24e2bSVaishali Kulkarni 	u64				first_free;
25714b24e2bSVaishali Kulkarni 	u64				last_free;
25814b24e2bSVaishali Kulkarni 
25914b24e2bSVaishali Kulkarni 	/* The infrastructure originally was very generic and context/task
26014b24e2bSVaishali Kulkarni 	 * oriented - per connection-type we would set how many of those
26114b24e2bSVaishali Kulkarni 	 * are needed, and later when determining how much memory we're
26214b24e2bSVaishali Kulkarni 	 * needing for a given block we'd iterate over all the relevant
26314b24e2bSVaishali Kulkarni 	 * connection-types.
26414b24e2bSVaishali Kulkarni 	 * But since then we've had some additional resources, some of which
26514b24e2bSVaishali Kulkarni 	 * require memory which is indepent of the general context/task
26614b24e2bSVaishali Kulkarni 	 * scheme. We add those here explicitly per-feature.
26714b24e2bSVaishali Kulkarni 	 */
26814b24e2bSVaishali Kulkarni 
26914b24e2bSVaishali Kulkarni 	/* total number of SRQ's for this hwfn */
27014b24e2bSVaishali Kulkarni 	u32				srq_count;
27114b24e2bSVaishali Kulkarni 
27214b24e2bSVaishali Kulkarni 	/* Maximal number of L2 steering filters */
27314b24e2bSVaishali Kulkarni 	u32				arfs_count;
27414b24e2bSVaishali Kulkarni 
27514b24e2bSVaishali Kulkarni 	/* TODO - VF arfs filters ? */
27614b24e2bSVaishali Kulkarni };
27714b24e2bSVaishali Kulkarni 
27814b24e2bSVaishali Kulkarni /* check if resources/configuration is required according to protocol type */
src_proto(struct ecore_hwfn * p_hwfn,enum protocol_type type)27914b24e2bSVaishali Kulkarni static bool src_proto(struct ecore_hwfn *p_hwfn,
28014b24e2bSVaishali Kulkarni 		      enum protocol_type type)
28114b24e2bSVaishali Kulkarni {
28214b24e2bSVaishali Kulkarni 	return	type == PROTOCOLID_ISCSI	||
28314b24e2bSVaishali Kulkarni 		type == PROTOCOLID_FCOE		||
28414b24e2bSVaishali Kulkarni 		type == PROTOCOLID_TOE		||
28514b24e2bSVaishali Kulkarni 		type == PROTOCOLID_IWARP;
28614b24e2bSVaishali Kulkarni }
28714b24e2bSVaishali Kulkarni 
tm_cid_proto(enum protocol_type type)28814b24e2bSVaishali Kulkarni static bool tm_cid_proto(enum protocol_type type)
28914b24e2bSVaishali Kulkarni {
29014b24e2bSVaishali Kulkarni 	return type == PROTOCOLID_ISCSI ||
29114b24e2bSVaishali Kulkarni 	       type == PROTOCOLID_FCOE  ||
29214b24e2bSVaishali Kulkarni 	       type == PROTOCOLID_ROCE  ||
29314b24e2bSVaishali Kulkarni 	       type == PROTOCOLID_IWARP;
29414b24e2bSVaishali Kulkarni }
29514b24e2bSVaishali Kulkarni 
tm_tid_proto(enum protocol_type type)29614b24e2bSVaishali Kulkarni static bool tm_tid_proto(enum protocol_type type)
29714b24e2bSVaishali Kulkarni {
29814b24e2bSVaishali Kulkarni 	return type == PROTOCOLID_FCOE;
29914b24e2bSVaishali Kulkarni }
30014b24e2bSVaishali Kulkarni 
30114b24e2bSVaishali Kulkarni /* counts the iids for the CDU/CDUC ILT client configuration */
30214b24e2bSVaishali Kulkarni struct ecore_cdu_iids {
30314b24e2bSVaishali Kulkarni 	u32 pf_cids;
30414b24e2bSVaishali Kulkarni 	u32 per_vf_cids;
30514b24e2bSVaishali Kulkarni };
30614b24e2bSVaishali Kulkarni 
ecore_cxt_cdu_iids(struct ecore_cxt_mngr * p_mngr,struct ecore_cdu_iids * iids)30714b24e2bSVaishali Kulkarni static void ecore_cxt_cdu_iids(struct ecore_cxt_mngr   *p_mngr,
30814b24e2bSVaishali Kulkarni 			       struct ecore_cdu_iids	*iids)
30914b24e2bSVaishali Kulkarni {
31014b24e2bSVaishali Kulkarni 	u32 type;
31114b24e2bSVaishali Kulkarni 
31214b24e2bSVaishali Kulkarni 	for (type = 0; type < MAX_CONN_TYPES; type++) {
31314b24e2bSVaishali Kulkarni 		iids->pf_cids += p_mngr->conn_cfg[type].cid_count;
31414b24e2bSVaishali Kulkarni 		iids->per_vf_cids += p_mngr->conn_cfg[type].cids_per_vf;
31514b24e2bSVaishali Kulkarni 	}
31614b24e2bSVaishali Kulkarni }
31714b24e2bSVaishali Kulkarni 
31814b24e2bSVaishali Kulkarni /* counts the iids for the Searcher block configuration */
31914b24e2bSVaishali Kulkarni struct ecore_src_iids {
32014b24e2bSVaishali Kulkarni 	u32			pf_cids;
32114b24e2bSVaishali Kulkarni 	u32			per_vf_cids;
32214b24e2bSVaishali Kulkarni };
32314b24e2bSVaishali Kulkarni 
ecore_cxt_src_iids(struct ecore_hwfn * p_hwfn,struct ecore_cxt_mngr * p_mngr,struct ecore_src_iids * iids)32414b24e2bSVaishali Kulkarni static void ecore_cxt_src_iids(struct ecore_hwfn *p_hwfn,
32514b24e2bSVaishali Kulkarni 			       struct ecore_cxt_mngr *p_mngr,
32614b24e2bSVaishali Kulkarni 			       struct ecore_src_iids *iids)
32714b24e2bSVaishali Kulkarni {
32814b24e2bSVaishali Kulkarni 	u32 i;
32914b24e2bSVaishali Kulkarni 
33014b24e2bSVaishali Kulkarni 	for (i = 0; i < MAX_CONN_TYPES; i++) {
33114b24e2bSVaishali Kulkarni 		if (!src_proto(p_hwfn, i))
33214b24e2bSVaishali Kulkarni 			continue;
33314b24e2bSVaishali Kulkarni 
33414b24e2bSVaishali Kulkarni 		iids->pf_cids += p_mngr->conn_cfg[i].cid_count;
33514b24e2bSVaishali Kulkarni 		iids->per_vf_cids += p_mngr->conn_cfg[i].cids_per_vf;
33614b24e2bSVaishali Kulkarni 	}
33714b24e2bSVaishali Kulkarni 
33814b24e2bSVaishali Kulkarni 	/* Add L2 filtering filters in addition */
33914b24e2bSVaishali Kulkarni 	iids->pf_cids += p_mngr->arfs_count;
34014b24e2bSVaishali Kulkarni }
34114b24e2bSVaishali Kulkarni 
34214b24e2bSVaishali Kulkarni /* counts the iids for the Timers block configuration */
34314b24e2bSVaishali Kulkarni struct ecore_tm_iids {
34414b24e2bSVaishali Kulkarni 	u32 pf_cids;
34514b24e2bSVaishali Kulkarni 	u32 pf_tids[NUM_TASK_PF_SEGMENTS]; /* per segment */
34614b24e2bSVaishali Kulkarni 	u32 pf_tids_total;
34714b24e2bSVaishali Kulkarni 	u32 per_vf_cids;
34814b24e2bSVaishali Kulkarni 	u32 per_vf_tids;
34914b24e2bSVaishali Kulkarni };
35014b24e2bSVaishali Kulkarni 
ecore_cxt_tm_iids(struct ecore_hwfn * p_hwfn,struct ecore_cxt_mngr * p_mngr,struct ecore_tm_iids * iids)35114b24e2bSVaishali Kulkarni static void ecore_cxt_tm_iids(struct ecore_hwfn *p_hwfn,
35214b24e2bSVaishali Kulkarni 			      struct ecore_cxt_mngr *p_mngr,
35314b24e2bSVaishali Kulkarni 			      struct ecore_tm_iids *iids)
35414b24e2bSVaishali Kulkarni {
35514b24e2bSVaishali Kulkarni 	bool tm_vf_required = false;
35614b24e2bSVaishali Kulkarni 	bool tm_required = false;
35714b24e2bSVaishali Kulkarni 	int i, j;
35814b24e2bSVaishali Kulkarni 
35914b24e2bSVaishali Kulkarni 	/* Timers is a special case -> we don't count how many cids require
36014b24e2bSVaishali Kulkarni 	 * timers but what's the max cid that will be used by the timer block.
36114b24e2bSVaishali Kulkarni 	 * therefore we traverse in reverse order, and once we hit a protocol
36214b24e2bSVaishali Kulkarni 	 * that requires the timers memory, we'll sum all the protocols up
36314b24e2bSVaishali Kulkarni 	 * to that one.
36414b24e2bSVaishali Kulkarni 	 */
36514b24e2bSVaishali Kulkarni 	for (i = MAX_CONN_TYPES - 1; i >= 0; i--) {
36614b24e2bSVaishali Kulkarni 		struct ecore_conn_type_cfg *p_cfg = &p_mngr->conn_cfg[i];
36714b24e2bSVaishali Kulkarni 
36814b24e2bSVaishali Kulkarni 		if (tm_cid_proto(i) || tm_required) {
36914b24e2bSVaishali Kulkarni 			if (p_cfg->cid_count)
37014b24e2bSVaishali Kulkarni 				tm_required = true;
37114b24e2bSVaishali Kulkarni 
37214b24e2bSVaishali Kulkarni 			iids->pf_cids += p_cfg->cid_count;
37314b24e2bSVaishali Kulkarni 		}
37414b24e2bSVaishali Kulkarni 
37514b24e2bSVaishali Kulkarni 		if (tm_cid_proto(i) || tm_vf_required) {
37614b24e2bSVaishali Kulkarni 			if (p_cfg->cids_per_vf)
37714b24e2bSVaishali Kulkarni 				tm_vf_required = true;
37814b24e2bSVaishali Kulkarni 
37914b24e2bSVaishali Kulkarni 			iids->per_vf_cids += p_cfg->cids_per_vf;
38014b24e2bSVaishali Kulkarni 		}
38114b24e2bSVaishali Kulkarni 
38214b24e2bSVaishali Kulkarni 		if (tm_tid_proto(i)) {
38314b24e2bSVaishali Kulkarni 			struct ecore_tid_seg *segs = p_cfg->tid_seg;
38414b24e2bSVaishali Kulkarni 
38514b24e2bSVaishali Kulkarni 			/* for each segment there is at most one
38614b24e2bSVaishali Kulkarni 			 * protocol for which count is not 0.
38714b24e2bSVaishali Kulkarni 			 */
38814b24e2bSVaishali Kulkarni 			for (j = 0; j < NUM_TASK_PF_SEGMENTS; j++)
38914b24e2bSVaishali Kulkarni 				iids->pf_tids[j] += segs[j].count;
39014b24e2bSVaishali Kulkarni 
39114b24e2bSVaishali Kulkarni 			/* The last array elelment is for the VFs. As for PF
39214b24e2bSVaishali Kulkarni 			 * segments there can be only one protocol for
39314b24e2bSVaishali Kulkarni 			 * which this value is not 0.
39414b24e2bSVaishali Kulkarni 			 */
39514b24e2bSVaishali Kulkarni 			iids->per_vf_tids += segs[NUM_TASK_PF_SEGMENTS].count;
39614b24e2bSVaishali Kulkarni 		}
39714b24e2bSVaishali Kulkarni 	}
39814b24e2bSVaishali Kulkarni 
39914b24e2bSVaishali Kulkarni 	iids->pf_cids = ROUNDUP(iids->pf_cids, TM_ALIGN);
40014b24e2bSVaishali Kulkarni 	iids->per_vf_cids = ROUNDUP(iids->per_vf_cids, TM_ALIGN);
40114b24e2bSVaishali Kulkarni 	iids->per_vf_tids = ROUNDUP(iids->per_vf_tids, TM_ALIGN);
40214b24e2bSVaishali Kulkarni 
40314b24e2bSVaishali Kulkarni 	for (iids->pf_tids_total = 0, j = 0; j < NUM_TASK_PF_SEGMENTS; j++) {
40414b24e2bSVaishali Kulkarni 		iids->pf_tids[j] = ROUNDUP(iids->pf_tids[j], TM_ALIGN);
40514b24e2bSVaishali Kulkarni 		iids->pf_tids_total += iids->pf_tids[j];
40614b24e2bSVaishali Kulkarni 	}
40714b24e2bSVaishali Kulkarni }
40814b24e2bSVaishali Kulkarni 
ecore_cxt_qm_iids(struct ecore_hwfn * p_hwfn,struct ecore_qm_iids * iids)40914b24e2bSVaishali Kulkarni static void ecore_cxt_qm_iids(struct ecore_hwfn *p_hwfn,
41014b24e2bSVaishali Kulkarni 			      struct ecore_qm_iids *iids)
41114b24e2bSVaishali Kulkarni {
41214b24e2bSVaishali Kulkarni 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
41314b24e2bSVaishali Kulkarni 	struct ecore_tid_seg *segs;
41414b24e2bSVaishali Kulkarni 	u32 vf_cids = 0, type, j;
41514b24e2bSVaishali Kulkarni 	u32 vf_tids = 0;
41614b24e2bSVaishali Kulkarni 
41714b24e2bSVaishali Kulkarni 	for (type = 0; type < MAX_CONN_TYPES; type++) {
41814b24e2bSVaishali Kulkarni 		iids->cids += p_mngr->conn_cfg[type].cid_count;
41914b24e2bSVaishali Kulkarni 		vf_cids += p_mngr->conn_cfg[type].cids_per_vf;
42014b24e2bSVaishali Kulkarni 
42114b24e2bSVaishali Kulkarni 		segs = p_mngr->conn_cfg[type].tid_seg;
42214b24e2bSVaishali Kulkarni 		/* for each segment there is at most one
42314b24e2bSVaishali Kulkarni 		 * protocol for which count is not 0.
42414b24e2bSVaishali Kulkarni 		 */
42514b24e2bSVaishali Kulkarni 		for (j = 0; j < NUM_TASK_PF_SEGMENTS; j++)
42614b24e2bSVaishali Kulkarni 			iids->tids += segs[j].count;
42714b24e2bSVaishali Kulkarni 
42814b24e2bSVaishali Kulkarni 		/* The last array elelment is for the VFs. As for PF
42914b24e2bSVaishali Kulkarni 		 * segments there can be only one protocol for
43014b24e2bSVaishali Kulkarni 		 * which this value is not 0.
43114b24e2bSVaishali Kulkarni 		 */
43214b24e2bSVaishali Kulkarni 		vf_tids += segs[NUM_TASK_PF_SEGMENTS].count;
43314b24e2bSVaishali Kulkarni 	}
43414b24e2bSVaishali Kulkarni 
43514b24e2bSVaishali Kulkarni 	iids->vf_cids += vf_cids * p_mngr->vf_count;
43614b24e2bSVaishali Kulkarni 	iids->tids += vf_tids * p_mngr->vf_count;
43714b24e2bSVaishali Kulkarni 
43814b24e2bSVaishali Kulkarni 	DP_VERBOSE(p_hwfn, ECORE_MSG_ILT,
43914b24e2bSVaishali Kulkarni 		   "iids: CIDS %08x vf_cids %08x tids %08x vf_tids %08x\n",
44014b24e2bSVaishali Kulkarni 		   iids->cids, iids->vf_cids, iids->tids, vf_tids);
44114b24e2bSVaishali Kulkarni }
44214b24e2bSVaishali Kulkarni 
ecore_cxt_tid_seg_info(struct ecore_hwfn * p_hwfn,u32 seg)44314b24e2bSVaishali Kulkarni static struct ecore_tid_seg *ecore_cxt_tid_seg_info(struct ecore_hwfn   *p_hwfn,
44414b24e2bSVaishali Kulkarni 						    u32			seg)
44514b24e2bSVaishali Kulkarni {
44614b24e2bSVaishali Kulkarni 	struct ecore_cxt_mngr *p_cfg = p_hwfn->p_cxt_mngr;
44714b24e2bSVaishali Kulkarni 	u32 i;
44814b24e2bSVaishali Kulkarni 
44914b24e2bSVaishali Kulkarni 	/* Find the protocol with tid count > 0 for this segment.
45014b24e2bSVaishali Kulkarni 	   Note: there can only be one and this is already validated.
45114b24e2bSVaishali Kulkarni 	 */
45214b24e2bSVaishali Kulkarni 	for (i = 0; i < MAX_CONN_TYPES; i++) {
45314b24e2bSVaishali Kulkarni 		if (p_cfg->conn_cfg[i].tid_seg[seg].count)
45414b24e2bSVaishali Kulkarni 			return &p_cfg->conn_cfg[i].tid_seg[seg];
45514b24e2bSVaishali Kulkarni 	}
45614b24e2bSVaishali Kulkarni 	return OSAL_NULL;
45714b24e2bSVaishali Kulkarni }
45814b24e2bSVaishali Kulkarni 
45914b24e2bSVaishali Kulkarni /* set the iids (cid/tid) count per protocol */
ecore_cxt_set_proto_cid_count(struct ecore_hwfn * p_hwfn,enum protocol_type type,u32 cid_count,u32 vf_cid_cnt)46014b24e2bSVaishali Kulkarni static void ecore_cxt_set_proto_cid_count(struct ecore_hwfn *p_hwfn,
46114b24e2bSVaishali Kulkarni 					  enum protocol_type type,
46214b24e2bSVaishali Kulkarni 					  u32 cid_count, u32 vf_cid_cnt)
46314b24e2bSVaishali Kulkarni {
46414b24e2bSVaishali Kulkarni 	struct ecore_cxt_mngr *p_mgr = p_hwfn->p_cxt_mngr;
46514b24e2bSVaishali Kulkarni 	struct ecore_conn_type_cfg *p_conn = &p_mgr->conn_cfg[type];
46614b24e2bSVaishali Kulkarni 
46714b24e2bSVaishali Kulkarni 	p_conn->cid_count = ROUNDUP(cid_count, DQ_RANGE_ALIGN);
46814b24e2bSVaishali Kulkarni 	p_conn->cids_per_vf = ROUNDUP(vf_cid_cnt, DQ_RANGE_ALIGN);
46914b24e2bSVaishali Kulkarni 
47014b24e2bSVaishali Kulkarni 	if (type == PROTOCOLID_ROCE) {
47114b24e2bSVaishali Kulkarni 		u32 page_sz = p_mgr->clients[ILT_CLI_CDUC].p_size.val;
47214b24e2bSVaishali Kulkarni 		u32 cxt_size = CONN_CXT_SIZE(p_hwfn);
47314b24e2bSVaishali Kulkarni 		u32 elems_per_page = ILT_PAGE_IN_BYTES(page_sz) / cxt_size;
47414b24e2bSVaishali Kulkarni 		u32 align = elems_per_page * DQ_RANGE_ALIGN;
47514b24e2bSVaishali Kulkarni 
47614b24e2bSVaishali Kulkarni 		p_conn->cid_count = ROUNDUP(p_conn->cid_count, align);
47714b24e2bSVaishali Kulkarni 	}
47814b24e2bSVaishali Kulkarni }
47914b24e2bSVaishali Kulkarni 
ecore_cxt_get_proto_cid_count(struct ecore_hwfn * p_hwfn,enum protocol_type type,u32 * vf_cid)48014b24e2bSVaishali Kulkarni u32 ecore_cxt_get_proto_cid_count(struct ecore_hwfn	*p_hwfn,
48114b24e2bSVaishali Kulkarni 				  enum protocol_type	type,
48214b24e2bSVaishali Kulkarni 				  u32			*vf_cid)
48314b24e2bSVaishali Kulkarni {
48414b24e2bSVaishali Kulkarni 	if (vf_cid)
48514b24e2bSVaishali Kulkarni 		*vf_cid = p_hwfn->p_cxt_mngr->conn_cfg[type].cids_per_vf;
48614b24e2bSVaishali Kulkarni 
48714b24e2bSVaishali Kulkarni 	return p_hwfn->p_cxt_mngr->conn_cfg[type].cid_count;
48814b24e2bSVaishali Kulkarni }
48914b24e2bSVaishali Kulkarni 
ecore_cxt_get_proto_cid_start(struct ecore_hwfn * p_hwfn,enum protocol_type type)49014b24e2bSVaishali Kulkarni u32 ecore_cxt_get_proto_cid_start(struct ecore_hwfn	*p_hwfn,
49114b24e2bSVaishali Kulkarni 				  enum protocol_type	type)
49214b24e2bSVaishali Kulkarni {
49314b24e2bSVaishali Kulkarni 	return p_hwfn->p_cxt_mngr->acquired[type].start_cid;
49414b24e2bSVaishali Kulkarni }
49514b24e2bSVaishali Kulkarni 
ecore_cxt_get_proto_tid_count(struct ecore_hwfn * p_hwfn,enum protocol_type type)49614b24e2bSVaishali Kulkarni u32 ecore_cxt_get_proto_tid_count(struct ecore_hwfn *p_hwfn,
49714b24e2bSVaishali Kulkarni 				  enum protocol_type type)
49814b24e2bSVaishali Kulkarni {
49914b24e2bSVaishali Kulkarni 	u32 cnt = 0;
50014b24e2bSVaishali Kulkarni 	int i;
50114b24e2bSVaishali Kulkarni 
50214b24e2bSVaishali Kulkarni 	for (i = 0; i < TASK_SEGMENTS; i++)
50314b24e2bSVaishali Kulkarni 		cnt += p_hwfn->p_cxt_mngr->conn_cfg[type].tid_seg[i].count;
50414b24e2bSVaishali Kulkarni 
50514b24e2bSVaishali Kulkarni 	return cnt;
50614b24e2bSVaishali Kulkarni }
50714b24e2bSVaishali Kulkarni 
ecore_cxt_set_proto_tid_count(struct ecore_hwfn * p_hwfn,enum protocol_type proto,u8 seg,u8 seg_type,u32 count,bool has_fl)50814b24e2bSVaishali Kulkarni static void ecore_cxt_set_proto_tid_count(struct ecore_hwfn *p_hwfn,
50914b24e2bSVaishali Kulkarni 					  enum protocol_type proto,
51014b24e2bSVaishali Kulkarni 					  u8 seg,
51114b24e2bSVaishali Kulkarni 					  u8 seg_type,
51214b24e2bSVaishali Kulkarni 					  u32 count,
51314b24e2bSVaishali Kulkarni 					  bool has_fl)
51414b24e2bSVaishali Kulkarni {
51514b24e2bSVaishali Kulkarni 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
51614b24e2bSVaishali Kulkarni 	struct ecore_tid_seg *p_seg = &p_mngr->conn_cfg[proto].tid_seg[seg];
51714b24e2bSVaishali Kulkarni 
51814b24e2bSVaishali Kulkarni 	p_seg->count = count;
51914b24e2bSVaishali Kulkarni 	p_seg->has_fl_mem = has_fl;
52014b24e2bSVaishali Kulkarni 	p_seg->type = seg_type;
52114b24e2bSVaishali Kulkarni }
52214b24e2bSVaishali Kulkarni 
52314b24e2bSVaishali Kulkarni /* the *p_line parameter must be either 0 for the first invocation or the
52414b24e2bSVaishali Kulkarni    value returned in the previous invocation.
52514b24e2bSVaishali Kulkarni  */
ecore_ilt_cli_blk_fill(struct ecore_ilt_client_cfg * p_cli,struct ecore_ilt_cli_blk * p_blk,u32 start_line,u32 total_size,u32 elem_size)52614b24e2bSVaishali Kulkarni static void ecore_ilt_cli_blk_fill(struct ecore_ilt_client_cfg	*p_cli,
52714b24e2bSVaishali Kulkarni 				   struct ecore_ilt_cli_blk	*p_blk,
52814b24e2bSVaishali Kulkarni 				   u32				start_line,
52914b24e2bSVaishali Kulkarni 				   u32				total_size,
53014b24e2bSVaishali Kulkarni 				   u32				elem_size)
53114b24e2bSVaishali Kulkarni {
53214b24e2bSVaishali Kulkarni 	u32 ilt_size = ILT_PAGE_IN_BYTES(p_cli->p_size.val);
53314b24e2bSVaishali Kulkarni 
53414b24e2bSVaishali Kulkarni 	/* verify that it's called once for each block */
53514b24e2bSVaishali Kulkarni 	if (p_blk->total_size)
53614b24e2bSVaishali Kulkarni 		return;
53714b24e2bSVaishali Kulkarni 
53814b24e2bSVaishali Kulkarni 	p_blk->total_size = total_size;
53914b24e2bSVaishali Kulkarni 	p_blk->real_size_in_page = 0;
54014b24e2bSVaishali Kulkarni 	if (elem_size)
54114b24e2bSVaishali Kulkarni 		p_blk->real_size_in_page = (ilt_size / elem_size) * elem_size;
54214b24e2bSVaishali Kulkarni 	p_blk->start_line = start_line;
54314b24e2bSVaishali Kulkarni }
54414b24e2bSVaishali Kulkarni 
ecore_ilt_cli_adv_line(struct ecore_hwfn * p_hwfn,struct ecore_ilt_client_cfg * p_cli,struct ecore_ilt_cli_blk * p_blk,u32 * p_line,enum ilt_clients client_id)54514b24e2bSVaishali Kulkarni static void ecore_ilt_cli_adv_line(struct ecore_hwfn		*p_hwfn,
54614b24e2bSVaishali Kulkarni 				    struct ecore_ilt_client_cfg	*p_cli,
54714b24e2bSVaishali Kulkarni 				    struct ecore_ilt_cli_blk	*p_blk,
54814b24e2bSVaishali Kulkarni 				    u32				*p_line,
54914b24e2bSVaishali Kulkarni 				    enum ilt_clients		client_id)
55014b24e2bSVaishali Kulkarni {
55114b24e2bSVaishali Kulkarni 	if (!p_blk->total_size)
55214b24e2bSVaishali Kulkarni 		return;
55314b24e2bSVaishali Kulkarni 
55414b24e2bSVaishali Kulkarni 	if (!p_cli->active)
55514b24e2bSVaishali Kulkarni 		p_cli->first.val = *p_line;
55614b24e2bSVaishali Kulkarni 
55714b24e2bSVaishali Kulkarni 	p_cli->active = true;
55814b24e2bSVaishali Kulkarni 	*p_line += DIV_ROUND_UP(p_blk->total_size, p_blk->real_size_in_page);
55914b24e2bSVaishali Kulkarni 	p_cli->last.val = *p_line-1;
56014b24e2bSVaishali Kulkarni 
56114b24e2bSVaishali Kulkarni 	DP_VERBOSE(p_hwfn, ECORE_MSG_ILT,
56214b24e2bSVaishali Kulkarni 		   "ILT[Client %d] - Lines: [%08x - %08x]. Block - Size %08x [Real %08x] Start line %d\n",
56314b24e2bSVaishali Kulkarni 		   client_id, p_cli->first.val, p_cli->last.val,
56414b24e2bSVaishali Kulkarni 		   p_blk->total_size, p_blk->real_size_in_page,
56514b24e2bSVaishali Kulkarni 		   p_blk->start_line);
56614b24e2bSVaishali Kulkarni }
56714b24e2bSVaishali Kulkarni 
ecore_ilt_get_dynamic_line_cnt(struct ecore_hwfn * p_hwfn,enum ilt_clients ilt_client)56814b24e2bSVaishali Kulkarni static u32 ecore_ilt_get_dynamic_line_cnt(struct ecore_hwfn *p_hwfn,
56914b24e2bSVaishali Kulkarni 					  enum ilt_clients ilt_client)
57014b24e2bSVaishali Kulkarni {
57114b24e2bSVaishali Kulkarni 	u32 cid_count = p_hwfn->p_cxt_mngr->conn_cfg[PROTOCOLID_ROCE].cid_count;
57214b24e2bSVaishali Kulkarni 	struct ecore_ilt_client_cfg *p_cli;
57314b24e2bSVaishali Kulkarni 	u32 lines_to_skip = 0;
57414b24e2bSVaishali Kulkarni 	u32 cxts_per_p;
57514b24e2bSVaishali Kulkarni 
57614b24e2bSVaishali Kulkarni 	/* TBD MK: ILT code should be simplified once PROTO enum is changed */
57714b24e2bSVaishali Kulkarni 
57814b24e2bSVaishali Kulkarni 	if (ilt_client == ILT_CLI_CDUC) {
57914b24e2bSVaishali Kulkarni 		p_cli = &p_hwfn->p_cxt_mngr->clients[ILT_CLI_CDUC];
58014b24e2bSVaishali Kulkarni 
58114b24e2bSVaishali Kulkarni 		cxts_per_p = ILT_PAGE_IN_BYTES(p_cli->p_size.val) /
58214b24e2bSVaishali Kulkarni 			     (u32)CONN_CXT_SIZE(p_hwfn);
58314b24e2bSVaishali Kulkarni 
58414b24e2bSVaishali Kulkarni 		lines_to_skip = cid_count / cxts_per_p;
58514b24e2bSVaishali Kulkarni 	}
58614b24e2bSVaishali Kulkarni 
58714b24e2bSVaishali Kulkarni 	return lines_to_skip;
58814b24e2bSVaishali Kulkarni }
58914b24e2bSVaishali Kulkarni 
59014b24e2bSVaishali Kulkarni static struct ecore_ilt_client_cfg *
ecore_cxt_set_cli(struct ecore_ilt_client_cfg * p_cli)59114b24e2bSVaishali Kulkarni ecore_cxt_set_cli(struct ecore_ilt_client_cfg *p_cli)
59214b24e2bSVaishali Kulkarni {
59314b24e2bSVaishali Kulkarni 	p_cli->active = false;
59414b24e2bSVaishali Kulkarni 	p_cli->first.val = 0;
59514b24e2bSVaishali Kulkarni 	p_cli->last.val = 0;
59614b24e2bSVaishali Kulkarni 	return p_cli;
59714b24e2bSVaishali Kulkarni }
59814b24e2bSVaishali Kulkarni 
59914b24e2bSVaishali Kulkarni static struct ecore_ilt_cli_blk *
ecore_cxt_set_blk(struct ecore_ilt_cli_blk * p_blk)60014b24e2bSVaishali Kulkarni ecore_cxt_set_blk(struct ecore_ilt_cli_blk *p_blk)
60114b24e2bSVaishali Kulkarni {
60214b24e2bSVaishali Kulkarni 	p_blk->total_size = 0;
60314b24e2bSVaishali Kulkarni 	return p_blk;
60414b24e2bSVaishali Kulkarni }
60514b24e2bSVaishali Kulkarni 
ecore_cxt_cfg_ilt_compute(struct ecore_hwfn * p_hwfn,u32 * line_count)60614b24e2bSVaishali Kulkarni enum _ecore_status_t ecore_cxt_cfg_ilt_compute(struct ecore_hwfn *p_hwfn,
60714b24e2bSVaishali Kulkarni 					       u32 *line_count)
60814b24e2bSVaishali Kulkarni {
60914b24e2bSVaishali Kulkarni 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
61014b24e2bSVaishali Kulkarni 	u32 curr_line, total, i, task_size, line;
61114b24e2bSVaishali Kulkarni 	struct ecore_ilt_client_cfg *p_cli;
61214b24e2bSVaishali Kulkarni 	struct ecore_ilt_cli_blk *p_blk;
61314b24e2bSVaishali Kulkarni 	struct ecore_cdu_iids cdu_iids;
61414b24e2bSVaishali Kulkarni 	struct ecore_src_iids src_iids;
61514b24e2bSVaishali Kulkarni 	struct ecore_qm_iids qm_iids;
61614b24e2bSVaishali Kulkarni 	struct ecore_tm_iids tm_iids;
61714b24e2bSVaishali Kulkarni 	struct ecore_tid_seg *p_seg;
61814b24e2bSVaishali Kulkarni 
61914b24e2bSVaishali Kulkarni 	OSAL_MEM_ZERO(&qm_iids, sizeof(qm_iids));
62014b24e2bSVaishali Kulkarni 	OSAL_MEM_ZERO(&cdu_iids, sizeof(cdu_iids));
62114b24e2bSVaishali Kulkarni 	OSAL_MEM_ZERO(&src_iids, sizeof(src_iids));
62214b24e2bSVaishali Kulkarni 	OSAL_MEM_ZERO(&tm_iids, sizeof(tm_iids));
62314b24e2bSVaishali Kulkarni 
62414b24e2bSVaishali Kulkarni 	p_mngr->pf_start_line = RESC_START(p_hwfn, ECORE_ILT);
62514b24e2bSVaishali Kulkarni 
62614b24e2bSVaishali Kulkarni 	DP_VERBOSE(p_hwfn, ECORE_MSG_ILT,
62714b24e2bSVaishali Kulkarni 		   "hwfn [%d] - Set context manager starting line to be 0x%08x\n",
62814b24e2bSVaishali Kulkarni 		   p_hwfn->my_id, p_hwfn->p_cxt_mngr->pf_start_line);
62914b24e2bSVaishali Kulkarni 
63014b24e2bSVaishali Kulkarni 	/* CDUC */
63114b24e2bSVaishali Kulkarni 	p_cli = ecore_cxt_set_cli(&p_mngr->clients[ILT_CLI_CDUC]);
63214b24e2bSVaishali Kulkarni 
63314b24e2bSVaishali Kulkarni 	curr_line = p_mngr->pf_start_line;
63414b24e2bSVaishali Kulkarni 
63514b24e2bSVaishali Kulkarni 	/* CDUC PF */
63614b24e2bSVaishali Kulkarni 	p_cli->pf_total_lines = 0;
63714b24e2bSVaishali Kulkarni 
63814b24e2bSVaishali Kulkarni 	/* get the counters for the CDUC,CDUC and QM clients  */
63914b24e2bSVaishali Kulkarni 	ecore_cxt_cdu_iids(p_mngr, &cdu_iids);
64014b24e2bSVaishali Kulkarni 
64114b24e2bSVaishali Kulkarni 	p_blk = ecore_cxt_set_blk(&p_cli->pf_blks[CDUC_BLK]);
64214b24e2bSVaishali Kulkarni 
64314b24e2bSVaishali Kulkarni 	total = cdu_iids.pf_cids * CONN_CXT_SIZE(p_hwfn);
64414b24e2bSVaishali Kulkarni 
64514b24e2bSVaishali Kulkarni 	ecore_ilt_cli_blk_fill(p_cli, p_blk, curr_line,
64614b24e2bSVaishali Kulkarni 			       total, CONN_CXT_SIZE(p_hwfn));
64714b24e2bSVaishali Kulkarni 
64814b24e2bSVaishali Kulkarni 	ecore_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line, ILT_CLI_CDUC);
64914b24e2bSVaishali Kulkarni 	p_cli->pf_total_lines = curr_line - p_blk->start_line;
65014b24e2bSVaishali Kulkarni 
65114b24e2bSVaishali Kulkarni 	p_blk->dynamic_line_cnt = ecore_ilt_get_dynamic_line_cnt(p_hwfn,
65214b24e2bSVaishali Kulkarni 								 ILT_CLI_CDUC);
65314b24e2bSVaishali Kulkarni 
65414b24e2bSVaishali Kulkarni 	/* CDUC VF */
65514b24e2bSVaishali Kulkarni 	p_blk = ecore_cxt_set_blk(&p_cli->vf_blks[CDUC_BLK]);
65614b24e2bSVaishali Kulkarni 	total = cdu_iids.per_vf_cids * CONN_CXT_SIZE(p_hwfn);
65714b24e2bSVaishali Kulkarni 
65814b24e2bSVaishali Kulkarni 	ecore_ilt_cli_blk_fill(p_cli, p_blk, curr_line,
65914b24e2bSVaishali Kulkarni 			       total, CONN_CXT_SIZE(p_hwfn));
66014b24e2bSVaishali Kulkarni 
66114b24e2bSVaishali Kulkarni 	ecore_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line, ILT_CLI_CDUC);
66214b24e2bSVaishali Kulkarni 	p_cli->vf_total_lines = curr_line - p_blk->start_line;
66314b24e2bSVaishali Kulkarni 
66414b24e2bSVaishali Kulkarni 	for (i = 1; i < p_mngr->vf_count; i++)
66514b24e2bSVaishali Kulkarni 		ecore_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line,
66614b24e2bSVaishali Kulkarni 				       ILT_CLI_CDUC);
66714b24e2bSVaishali Kulkarni 
66814b24e2bSVaishali Kulkarni 	/* CDUT PF */
66914b24e2bSVaishali Kulkarni 	p_cli = ecore_cxt_set_cli(&p_mngr->clients[ILT_CLI_CDUT]);
67014b24e2bSVaishali Kulkarni 	p_cli->first.val = curr_line;
67114b24e2bSVaishali Kulkarni 
67214b24e2bSVaishali Kulkarni 	/* first the 'working' task memory */
67314b24e2bSVaishali Kulkarni 	for (i = 0; i < NUM_TASK_PF_SEGMENTS; i++) {
67414b24e2bSVaishali Kulkarni 		p_seg = ecore_cxt_tid_seg_info(p_hwfn, i);
67514b24e2bSVaishali Kulkarni 		if (!p_seg || p_seg->count == 0)
67614b24e2bSVaishali Kulkarni 			continue;
67714b24e2bSVaishali Kulkarni 
67814b24e2bSVaishali Kulkarni 		p_blk = ecore_cxt_set_blk(&p_cli->pf_blks[CDUT_SEG_BLK(i)]);
67914b24e2bSVaishali Kulkarni 		total = p_seg->count * p_mngr->task_type_size[p_seg->type];
68014b24e2bSVaishali Kulkarni 		ecore_ilt_cli_blk_fill(p_cli, p_blk, curr_line, total,
68114b24e2bSVaishali Kulkarni 				       p_mngr->task_type_size[p_seg->type]);
68214b24e2bSVaishali Kulkarni 
68314b24e2bSVaishali Kulkarni 		ecore_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line,
68414b24e2bSVaishali Kulkarni 				       ILT_CLI_CDUT);
68514b24e2bSVaishali Kulkarni 	}
68614b24e2bSVaishali Kulkarni 
68714b24e2bSVaishali Kulkarni 	/* next the 'init' task memory (forced load memory) */
68814b24e2bSVaishali Kulkarni 	for (i = 0; i < NUM_TASK_PF_SEGMENTS; i++) {
68914b24e2bSVaishali Kulkarni 		p_seg = ecore_cxt_tid_seg_info(p_hwfn, i);
69014b24e2bSVaishali Kulkarni 		if (!p_seg || p_seg->count == 0)
69114b24e2bSVaishali Kulkarni 			continue;
69214b24e2bSVaishali Kulkarni 
69314b24e2bSVaishali Kulkarni 		p_blk = ecore_cxt_set_blk(
69414b24e2bSVaishali Kulkarni 				&p_cli->pf_blks[CDUT_FL_SEG_BLK(i, PF)]);
69514b24e2bSVaishali Kulkarni 
69614b24e2bSVaishali Kulkarni 		if (!p_seg->has_fl_mem) {
69714b24e2bSVaishali Kulkarni 			/* The segment is active (total size pf 'working'
69814b24e2bSVaishali Kulkarni 			 * memory is > 0) but has no FL (forced-load, Init)
69914b24e2bSVaishali Kulkarni 			 * memory. Thus:
70014b24e2bSVaishali Kulkarni 			 *
70114b24e2bSVaishali Kulkarni 			 * 1.   The total-size in the corrsponding FL block of
70214b24e2bSVaishali Kulkarni 			 *      the ILT client is set to 0 - No ILT line are
70314b24e2bSVaishali Kulkarni 			 *      provisioned and no ILT memory allocated.
70414b24e2bSVaishali Kulkarni 			 *
70514b24e2bSVaishali Kulkarni 			 * 2.   The start-line of said block is set to the
70614b24e2bSVaishali Kulkarni 			 *      start line of the matching working memory
70714b24e2bSVaishali Kulkarni 			 *      block in the ILT client. This is later used to
70814b24e2bSVaishali Kulkarni 			 *      configure the CDU segment offset registers and
70914b24e2bSVaishali Kulkarni 			 *      results in an FL command for TIDs of this
71014b24e2bSVaishali Kulkarni 			 *      segement behaves as regular load commands
71114b24e2bSVaishali Kulkarni 			 *      (loading TIDs from the working memory).
71214b24e2bSVaishali Kulkarni 			 */
71314b24e2bSVaishali Kulkarni 			line = p_cli->pf_blks[CDUT_SEG_BLK(i)].start_line;
71414b24e2bSVaishali Kulkarni 
71514b24e2bSVaishali Kulkarni 			ecore_ilt_cli_blk_fill(p_cli, p_blk, line, 0, 0);
71614b24e2bSVaishali Kulkarni 			continue;
71714b24e2bSVaishali Kulkarni 		}
71814b24e2bSVaishali Kulkarni 		total = p_seg->count * p_mngr->task_type_size[p_seg->type];
71914b24e2bSVaishali Kulkarni 
72014b24e2bSVaishali Kulkarni 		ecore_ilt_cli_blk_fill(p_cli, p_blk,
72114b24e2bSVaishali Kulkarni 				       curr_line, total,
72214b24e2bSVaishali Kulkarni 				       p_mngr->task_type_size[p_seg->type]);
72314b24e2bSVaishali Kulkarni 
72414b24e2bSVaishali Kulkarni 		ecore_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line,
72514b24e2bSVaishali Kulkarni 				       ILT_CLI_CDUT);
72614b24e2bSVaishali Kulkarni 	}
72714b24e2bSVaishali Kulkarni 	p_cli->pf_total_lines = curr_line - p_cli->pf_blks[0].start_line;
72814b24e2bSVaishali Kulkarni 
72914b24e2bSVaishali Kulkarni 	/* CDUT VF */
73014b24e2bSVaishali Kulkarni 	p_seg = ecore_cxt_tid_seg_info(p_hwfn, TASK_SEGMENT_VF);
73114b24e2bSVaishali Kulkarni 	if (p_seg && p_seg->count) {
73214b24e2bSVaishali Kulkarni 		/* Stricly speaking we need to iterate over all VF
73314b24e2bSVaishali Kulkarni 		 * task segment types, but a VF has only 1 segment
73414b24e2bSVaishali Kulkarni 		 */
73514b24e2bSVaishali Kulkarni 
73614b24e2bSVaishali Kulkarni 		/* 'working' memory */
73714b24e2bSVaishali Kulkarni 		total = p_seg->count * p_mngr->task_type_size[p_seg->type];
73814b24e2bSVaishali Kulkarni 
73914b24e2bSVaishali Kulkarni 		p_blk = ecore_cxt_set_blk(&p_cli->vf_blks[CDUT_SEG_BLK(0)]);
74014b24e2bSVaishali Kulkarni 		ecore_ilt_cli_blk_fill(p_cli, p_blk,
74114b24e2bSVaishali Kulkarni 				       curr_line, total,
74214b24e2bSVaishali Kulkarni 				       p_mngr->task_type_size[p_seg->type]);
74314b24e2bSVaishali Kulkarni 
74414b24e2bSVaishali Kulkarni 		ecore_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line,
74514b24e2bSVaishali Kulkarni 				       ILT_CLI_CDUT);
74614b24e2bSVaishali Kulkarni 
74714b24e2bSVaishali Kulkarni 		/* 'init' memory */
74814b24e2bSVaishali Kulkarni 		p_blk = ecore_cxt_set_blk(
74914b24e2bSVaishali Kulkarni 				&p_cli->vf_blks[CDUT_FL_SEG_BLK(0, VF)]);
75014b24e2bSVaishali Kulkarni 		if (!p_seg->has_fl_mem) {
75114b24e2bSVaishali Kulkarni 			/* see comment above */
75214b24e2bSVaishali Kulkarni 			line = p_cli->vf_blks[CDUT_SEG_BLK(0)].start_line;
75314b24e2bSVaishali Kulkarni 			ecore_ilt_cli_blk_fill(p_cli, p_blk, line, 0, 0);
75414b24e2bSVaishali Kulkarni 		} else {
75514b24e2bSVaishali Kulkarni 			task_size = p_mngr->task_type_size[p_seg->type];
75614b24e2bSVaishali Kulkarni 			ecore_ilt_cli_blk_fill(p_cli, p_blk,
75714b24e2bSVaishali Kulkarni 					       curr_line, total,
75814b24e2bSVaishali Kulkarni 					       task_size);
75914b24e2bSVaishali Kulkarni 			ecore_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line,
76014b24e2bSVaishali Kulkarni 					       ILT_CLI_CDUT);
76114b24e2bSVaishali Kulkarni 		}
76214b24e2bSVaishali Kulkarni 		p_cli->vf_total_lines = curr_line -
76314b24e2bSVaishali Kulkarni 					p_cli->vf_blks[0].start_line;
76414b24e2bSVaishali Kulkarni 
76514b24e2bSVaishali Kulkarni 		/* Now for the rest of the VFs */
76614b24e2bSVaishali Kulkarni 		for (i = 1; i < p_mngr->vf_count; i++) {
76714b24e2bSVaishali Kulkarni 			/* don't set p_blk i.e. don't clear total_size */
76814b24e2bSVaishali Kulkarni 			p_blk = &p_cli->vf_blks[CDUT_SEG_BLK(0)];
76914b24e2bSVaishali Kulkarni 			ecore_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line,
77014b24e2bSVaishali Kulkarni 					       ILT_CLI_CDUT);
77114b24e2bSVaishali Kulkarni 
77214b24e2bSVaishali Kulkarni 			/* don't set p_blk i.e. don't clear total_size */
77314b24e2bSVaishali Kulkarni 			p_blk = &p_cli->vf_blks[CDUT_FL_SEG_BLK(0, VF)];
77414b24e2bSVaishali Kulkarni 			ecore_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line,
77514b24e2bSVaishali Kulkarni 					       ILT_CLI_CDUT);
77614b24e2bSVaishali Kulkarni 		}