xref: /f-stack/dpdk/drivers/net/qede/base/ecore_cxt.c (revision 8850115b)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2016 - 2018 Cavium Inc.
3  * All rights reserved.
4  * www.cavium.com
5  */
6 
7 #include "bcm_osal.h"
8 #include "reg_addr.h"
9 #include "common_hsi.h"
10 #include "ecore_hsi_common.h"
11 #include "ecore_hsi_eth.h"
12 #include "ecore_rt_defs.h"
13 #include "ecore_status.h"
14 #include "ecore.h"
15 #include "ecore_init_ops.h"
16 #include "ecore_init_fw_funcs.h"
17 #include "ecore_cxt.h"
18 #include "ecore_hw.h"
19 #include "ecore_dev_api.h"
20 #include "ecore_sriov.h"
21 #include "ecore_mcp.h"
22 
23 /* Max number of connection types in HW (DQ/CDU etc.) */
24 #define MAX_CONN_TYPES		PROTOCOLID_COMMON
25 #define NUM_TASK_TYPES		2
26 #define NUM_TASK_PF_SEGMENTS	4
27 #define NUM_TASK_VF_SEGMENTS	1
28 
29 /* Doorbell-Queue constants */
30 #define DQ_RANGE_SHIFT	4
31 #define DQ_RANGE_ALIGN	(1 << DQ_RANGE_SHIFT)
32 
33 /* Searcher constants */
34 #define SRC_MIN_NUM_ELEMS 256
35 
36 /* Timers constants */
37 #define TM_SHIFT	7
38 #define TM_ALIGN	(1 << TM_SHIFT)
39 #define TM_ELEM_SIZE	4
40 
41 /* ILT constants */
42 #define ILT_DEFAULT_HW_P_SIZE	4
43 
44 #define ILT_PAGE_IN_BYTES(hw_p_size)	(1U << ((hw_p_size) + 12))
45 #define ILT_CFG_REG(cli, reg)		PSWRQ2_REG_##cli##_##reg##_RT_OFFSET
46 
47 /* ILT entry structure */
48 #define ILT_ENTRY_PHY_ADDR_MASK		0x000FFFFFFFFFFFULL
49 #define ILT_ENTRY_PHY_ADDR_SHIFT	0
50 #define ILT_ENTRY_VALID_MASK		0x1ULL
51 #define ILT_ENTRY_VALID_SHIFT		52
52 #define ILT_ENTRY_IN_REGS		2
53 #define ILT_REG_SIZE_IN_BYTES		4
54 
55 /* connection context union */
56 union conn_context {
57 	struct e4_core_conn_context core_ctx;
58 	struct e4_eth_conn_context eth_ctx;
59 };
60 
61 /* TYPE-0 task context - iSCSI, FCOE */
62 union type0_task_context {
63 };
64 
65 /* TYPE-1 task context - ROCE */
66 union type1_task_context {
67 	struct regpair reserved; /* @DPDK */
68 };
69 
70 struct src_ent {
71 	u8 opaque[56];
72 	u64 next;
73 };
74 
75 #define CDUT_SEG_ALIGNMET 3	/* in 4k chunks */
76 #define CDUT_SEG_ALIGNMET_IN_BYTES (1 << (CDUT_SEG_ALIGNMET + 12))
77 
78 #define CONN_CXT_SIZE(p_hwfn) \
79 	ALIGNED_TYPE_SIZE(union conn_context, p_hwfn)
80 
81 #define SRQ_CXT_SIZE (sizeof(struct regpair) * 8) /* @DPDK */
82 
83 #define TYPE0_TASK_CXT_SIZE(p_hwfn) \
84 	ALIGNED_TYPE_SIZE(union type0_task_context, p_hwfn)
85 
86 /* Alignment is inherent to the type1_task_context structure */
87 #define TYPE1_TASK_CXT_SIZE(p_hwfn) sizeof(union type1_task_context)
88 
89 /* PF per protocl configuration object */
90 #define TASK_SEGMENTS   (NUM_TASK_PF_SEGMENTS + NUM_TASK_VF_SEGMENTS)
91 #define TASK_SEGMENT_VF (NUM_TASK_PF_SEGMENTS)
92 
93 struct ecore_tid_seg {
94 	u32 count;
95 	u8 type;
96 	bool has_fl_mem;
97 };
98 
99 struct ecore_conn_type_cfg {
100 	u32 cid_count;
101 	u32 cids_per_vf;
102 	struct ecore_tid_seg tid_seg[TASK_SEGMENTS];
103 };
104 
105 /* ILT Client configuration,
106  * Per connection type (protocol) resources (cids, tis, vf cids etc.)
107  * 1 - for connection context (CDUC) and for each task context we need two
108  * values, for regular task context and for force load memory
109  */
110 #define ILT_CLI_PF_BLOCKS	(1 + NUM_TASK_PF_SEGMENTS * 2)
111 #define ILT_CLI_VF_BLOCKS	(1 + NUM_TASK_VF_SEGMENTS * 2)
112 #define CDUC_BLK		(0)
113 #define SRQ_BLK			(0)
114 #define CDUT_SEG_BLK(n)		(1 + (u8)(n))
115 #define CDUT_FL_SEG_BLK(n, X)	(1 + (n) + NUM_TASK_##X##_SEGMENTS)
116 
117 enum ilt_clients {
118 	ILT_CLI_CDUC,
119 	ILT_CLI_CDUT,
120 	ILT_CLI_QM,
121 	ILT_CLI_TM,
122 	ILT_CLI_SRC,
123 	ILT_CLI_TSDM,
124 	ILT_CLI_MAX
125 };
126 
127 struct ilt_cfg_pair {
128 	u32 reg;
129 	u32 val;
130 };
131 
132 struct ecore_ilt_cli_blk {
133 	u32 total_size;		/* 0 means not active */
134 	u32 real_size_in_page;
135 	u32 start_line;
136 	u32 dynamic_line_cnt;
137 };
138 
139 struct ecore_ilt_client_cfg {
140 	bool active;
141 
142 	/* ILT boundaries */
143 	struct ilt_cfg_pair first;
144 	struct ilt_cfg_pair last;
145 	struct ilt_cfg_pair p_size;
146 
147 	/* ILT client blocks for PF */
148 	struct ecore_ilt_cli_blk pf_blks[ILT_CLI_PF_BLOCKS];
149 	u32 pf_total_lines;
150 
151 	/* ILT client blocks for VFs */
152 	struct ecore_ilt_cli_blk vf_blks[ILT_CLI_VF_BLOCKS];
153 	u32 vf_total_lines;
154 };
155 
156 /* Per Path -
157  *      ILT shadow table
158  *      Protocol acquired CID lists
159  *      PF start line in ILT
160  */
161 struct ecore_dma_mem {
162 	dma_addr_t p_phys;
163 	void *p_virt;
164 	osal_size_t size;
165 };
166 
167 #define MAP_WORD_SIZE		sizeof(unsigned long)
168 #define BITS_PER_MAP_WORD	(MAP_WORD_SIZE * 8)
169 
170 struct ecore_cid_acquired_map {
171 	u32 start_cid;
172 	u32 max_count;
173 	unsigned long *cid_map;
174 };
175 
176 struct ecore_cxt_mngr {
177 	/* Per protocl configuration */
178 	struct ecore_conn_type_cfg conn_cfg[MAX_CONN_TYPES];
179 
180 	/* computed ILT structure */
181 	struct ecore_ilt_client_cfg clients[ILT_CLI_MAX];
182 
183 	/* Task type sizes */
184 	u32 task_type_size[NUM_TASK_TYPES];
185 
186 	/* total number of VFs for this hwfn -
187 	 * ALL VFs are symmetric in terms of HW resources
188 	 */
189 	u32 vf_count;
190 
191 	/* Acquired CIDs */
192 	struct ecore_cid_acquired_map acquired[MAX_CONN_TYPES];
193 	/* TBD - do we want this allocated to reserve space? */
194 	struct ecore_cid_acquired_map
195 		acquired_vf[MAX_CONN_TYPES][COMMON_MAX_NUM_VFS];
196 
197 	/* ILT  shadow table */
198 	struct ecore_dma_mem *ilt_shadow;
199 	u32 pf_start_line;
200 
201 	/* Mutex for a dynamic ILT allocation */
202 	osal_mutex_t mutex;
203 
204 	/* SRC T2 */
205 	struct ecore_dma_mem *t2;
206 	u32 t2_num_pages;
207 	u64 first_free;
208 	u64 last_free;
209 
210 	/* The infrastructure originally was very generic and context/task
211 	 * oriented - per connection-type we would set how many of those
212 	 * are needed, and later when determining how much memory we're
213 	 * needing for a given block we'd iterate over all the relevant
214 	 * connection-types.
215 	 * But since then we've had some additional resources, some of which
216 	 * require memory which is indepent of the general context/task
217 	 * scheme. We add those here explicitly per-feature.
218 	 */
219 
220 	/* total number of SRQ's for this hwfn */
221 	u32				srq_count;
222 
223 	/* Maximal number of L2 steering filters */
224 	u32				arfs_count;
225 
226 	/* TODO - VF arfs filters ? */
227 };
228 
229 static OSAL_INLINE bool tm_cid_proto(enum protocol_type type)
230 {
231 	return type == PROTOCOLID_TOE;
232 }
233 
234 static bool tm_tid_proto(enum protocol_type type)
235 {
236 	return type == PROTOCOLID_FCOE;
237 }
238 
239 /* counts the iids for the CDU/CDUC ILT client configuration */
240 struct ecore_cdu_iids {
241 	u32 pf_cids;
242 	u32 per_vf_cids;
243 };
244 
245 static void ecore_cxt_cdu_iids(struct ecore_cxt_mngr *p_mngr,
246 			       struct ecore_cdu_iids *iids)
247 {
248 	u32 type;
249 
250 	for (type = 0; type < MAX_CONN_TYPES; type++) {
251 		iids->pf_cids += p_mngr->conn_cfg[type].cid_count;
252 		iids->per_vf_cids += p_mngr->conn_cfg[type].cids_per_vf;
253 	}
254 }
255 
256 /* counts the iids for the Searcher block configuration */
257 struct ecore_src_iids {
258 	u32 pf_cids;
259 	u32 per_vf_cids;
260 };
261 
262 static void ecore_cxt_src_iids(struct ecore_cxt_mngr *p_mngr,
263 			       struct ecore_src_iids *iids)
264 {
265 	u32 i;
266 
267 	for (i = 0; i < MAX_CONN_TYPES; i++) {
268 		iids->pf_cids += p_mngr->conn_cfg[i].cid_count;
269 		iids->per_vf_cids += p_mngr->conn_cfg[i].cids_per_vf;
270 	}
271 
272 	/* Add L2 filtering filters in addition */
273 	iids->pf_cids += p_mngr->arfs_count;
274 }
275 
276 /* counts the iids for the Timers block configuration */
277 struct ecore_tm_iids {
278 	u32 pf_cids;
279 	u32 pf_tids[NUM_TASK_PF_SEGMENTS];	/* per segment */
280 	u32 pf_tids_total;
281 	u32 per_vf_cids;
282 	u32 per_vf_tids;
283 };
284 
285 static void ecore_cxt_tm_iids(struct ecore_cxt_mngr *p_mngr,
286 			      struct ecore_tm_iids *iids)
287 {
288 	bool tm_vf_required = false;
289 	bool tm_required = false;
290 	u32 i, j;
291 
292 	for (i = 0; i < MAX_CONN_TYPES; i++) {
293 		struct ecore_conn_type_cfg *p_cfg = &p_mngr->conn_cfg[i];
294 
295 		if (tm_cid_proto(i) || tm_required) {
296 			if (p_cfg->cid_count)
297 				tm_required = true;
298 
299 			iids->pf_cids += p_cfg->cid_count;
300 		}
301 
302 		if (tm_cid_proto(i) || tm_vf_required) {
303 			if (p_cfg->cids_per_vf)
304 				tm_vf_required = true;
305 
306 		}
307 
308 		if (tm_tid_proto(i)) {
309 			struct ecore_tid_seg *segs = p_cfg->tid_seg;
310 
311 			/* for each segment there is at most one
312 			 * protocol for which count is not 0.
313 			 */
314 			for (j = 0; j < NUM_TASK_PF_SEGMENTS; j++)
315 				iids->pf_tids[j] += segs[j].count;
316 
317 			/* The last array elelment is for the VFs. As for PF
318 			 * segments there can be only one protocol for
319 			 * which this value is not 0.
320 			 */
321 			iids->per_vf_tids += segs[NUM_TASK_PF_SEGMENTS].count;
322 		}
323 	}
324 
325 	iids->pf_cids = ROUNDUP(iids->pf_cids, TM_ALIGN);
326 	iids->per_vf_cids = ROUNDUP(iids->per_vf_cids, TM_ALIGN);
327 	iids->per_vf_tids = ROUNDUP(iids->per_vf_tids, TM_ALIGN);
328 
329 	for (iids->pf_tids_total = 0, j = 0; j < NUM_TASK_PF_SEGMENTS; j++) {
330 		iids->pf_tids[j] = ROUNDUP(iids->pf_tids[j], TM_ALIGN);
331 		iids->pf_tids_total += iids->pf_tids[j];
332 	}
333 }
334 
335 static void ecore_cxt_qm_iids(struct ecore_hwfn *p_hwfn,
336 			      struct ecore_qm_iids *iids)
337 {
338 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
339 	struct ecore_tid_seg *segs;
340 	u32 vf_cids = 0, type, j;
341 	u32 vf_tids = 0;
342 
343 	for (type = 0; type < MAX_CONN_TYPES; type++) {
344 		iids->cids += p_mngr->conn_cfg[type].cid_count;
345 		vf_cids += p_mngr->conn_cfg[type].cids_per_vf;
346 
347 		segs = p_mngr->conn_cfg[type].tid_seg;
348 		/* for each segment there is at most one
349 		 * protocol for which count is not 0.
350 		 */
351 		for (j = 0; j < NUM_TASK_PF_SEGMENTS; j++)
352 			iids->tids += segs[j].count;
353 
354 		/* The last array elelment is for the VFs. As for PF
355 		 * segments there can be only one protocol for
356 		 * which this value is not 0.
357 		 */
358 		vf_tids += segs[NUM_TASK_PF_SEGMENTS].count;
359 	}
360 
361 	iids->vf_cids += vf_cids * p_mngr->vf_count;
362 	iids->tids += vf_tids * p_mngr->vf_count;
363 
364 	DP_VERBOSE(p_hwfn, ECORE_MSG_ILT,
365 		   "iids: CIDS %08x vf_cids %08x tids %08x vf_tids %08x\n",
366 		   iids->cids, iids->vf_cids, iids->tids, vf_tids);
367 }
368 
369 static struct ecore_tid_seg *ecore_cxt_tid_seg_info(struct ecore_hwfn *p_hwfn,
370 						    u32 seg)
371 {
372 	struct ecore_cxt_mngr *p_cfg = p_hwfn->p_cxt_mngr;
373 	u32 i;
374 
375 	/* Find the protocol with tid count > 0 for this segment.
376 	 * Note: there can only be one and this is already validated.
377 	 */
378 	for (i = 0; i < MAX_CONN_TYPES; i++) {
379 		if (p_cfg->conn_cfg[i].tid_seg[seg].count)
380 			return &p_cfg->conn_cfg[i].tid_seg[seg];
381 	}
382 	return OSAL_NULL;
383 }
384 
385 static void ecore_cxt_set_srq_count(struct ecore_hwfn *p_hwfn, u32 num_srqs)
386 {
387 	struct ecore_cxt_mngr *p_mgr = p_hwfn->p_cxt_mngr;
388 
389 	p_mgr->srq_count = num_srqs;
390 }
391 
392 u32 ecore_cxt_get_srq_count(struct ecore_hwfn *p_hwfn)
393 {
394 	struct ecore_cxt_mngr *p_mgr = p_hwfn->p_cxt_mngr;
395 
396 	return p_mgr->srq_count;
397 }
398 
399 /* set the iids (cid/tid) count per protocol */
400 static void ecore_cxt_set_proto_cid_count(struct ecore_hwfn *p_hwfn,
401 				   enum protocol_type type,
402 				   u32 cid_count, u32 vf_cid_cnt)
403 {
404 	struct ecore_cxt_mngr *p_mgr = p_hwfn->p_cxt_mngr;
405 	struct ecore_conn_type_cfg *p_conn = &p_mgr->conn_cfg[type];
406 
407 	p_conn->cid_count = ROUNDUP(cid_count, DQ_RANGE_ALIGN);
408 	p_conn->cids_per_vf = ROUNDUP(vf_cid_cnt, DQ_RANGE_ALIGN);
409 }
410 
411 u32 ecore_cxt_get_proto_cid_count(struct ecore_hwfn *p_hwfn,
412 				  enum protocol_type type, u32 *vf_cid)
413 {
414 	if (vf_cid)
415 		*vf_cid = p_hwfn->p_cxt_mngr->conn_cfg[type].cids_per_vf;
416 
417 	return p_hwfn->p_cxt_mngr->conn_cfg[type].cid_count;
418 }
419 
420 u32 ecore_cxt_get_proto_cid_start(struct ecore_hwfn *p_hwfn,
421 				  enum protocol_type type)
422 {
423 	return p_hwfn->p_cxt_mngr->acquired[type].start_cid;
424 }
425 
426 u32 ecore_cxt_get_proto_tid_count(struct ecore_hwfn *p_hwfn,
427 					 enum protocol_type type)
428 {
429 	u32 cnt = 0;
430 	int i;
431 
432 	for (i = 0; i < TASK_SEGMENTS; i++)
433 		cnt += p_hwfn->p_cxt_mngr->conn_cfg[type].tid_seg[i].count;
434 
435 	return cnt;
436 }
437 
438 static OSAL_INLINE void
439 ecore_cxt_set_proto_tid_count(struct ecore_hwfn *p_hwfn,
440 			      enum protocol_type proto,
441 			      u8 seg, u8 seg_type, u32 count, bool has_fl)
442 {
443 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
444 	struct ecore_tid_seg *p_seg = &p_mngr->conn_cfg[proto].tid_seg[seg];
445 
446 	p_seg->count = count;
447 	p_seg->has_fl_mem = has_fl;
448 	p_seg->type = seg_type;
449 }
450 
451 /* the *p_line parameter must be either 0 for the first invocation or the
452  * value returned in the previous invocation.
453  */
454 static void ecore_ilt_cli_blk_fill(struct ecore_ilt_client_cfg *p_cli,
455 				   struct ecore_ilt_cli_blk *p_blk,
456 				   u32 start_line,
457 				   u32 total_size, u32 elem_size)
458 {
459 	u32 ilt_size = ILT_PAGE_IN_BYTES(p_cli->p_size.val);
460 
461 	/* verify that it's called once for each block */
462 	if (p_blk->total_size)
463 		return;
464 
465 	p_blk->total_size = total_size;
466 	p_blk->real_size_in_page = 0;
467 	if (elem_size)
468 		p_blk->real_size_in_page = (ilt_size / elem_size) * elem_size;
469 	p_blk->start_line = start_line;
470 }
471 
472 static void ecore_ilt_cli_adv_line(struct ecore_hwfn *p_hwfn,
473 				   struct ecore_ilt_client_cfg *p_cli,
474 				   struct ecore_ilt_cli_blk *p_blk,
475 				   u32 *p_line, enum ilt_clients client_id)
476 {
477 	if (!p_blk->total_size)
478 		return;
479 
480 	if (!p_cli->active)
481 		p_cli->first.val = *p_line;
482 
483 	p_cli->active = true;
484 	*p_line += DIV_ROUND_UP(p_blk->total_size, p_blk->real_size_in_page);
485 	p_cli->last.val = *p_line - 1;
486 
487 	DP_VERBOSE(p_hwfn, ECORE_MSG_ILT,
488 		   "ILT[Client %d] - Lines: [%08x - %08x]. Block - Size %08x"
489 		   " [Real %08x] Start line %d\n",
490 		   client_id, p_cli->first.val, p_cli->last.val,
491 		   p_blk->total_size, p_blk->real_size_in_page,
492 		   p_blk->start_line);
493 }
494 
495 static u32 ecore_ilt_get_dynamic_line_cnt(struct ecore_hwfn *p_hwfn,
496 					  enum ilt_clients ilt_client)
497 {
498 	u32 cid_count = p_hwfn->p_cxt_mngr->conn_cfg[PROTOCOLID_ROCE].cid_count;
499 	struct ecore_ilt_client_cfg *p_cli;
500 	u32 lines_to_skip = 0;
501 	u32 cxts_per_p;
502 
503 	/* TBD MK: ILT code should be simplified once PROTO enum is changed */
504 
505 	if (ilt_client == ILT_CLI_CDUC) {
506 		p_cli = &p_hwfn->p_cxt_mngr->clients[ILT_CLI_CDUC];
507 
508 		cxts_per_p = ILT_PAGE_IN_BYTES(p_cli->p_size.val) /
509 		    (u32)CONN_CXT_SIZE(p_hwfn);
510 
511 		lines_to_skip = cid_count / cxts_per_p;
512 	}
513 
514 	return lines_to_skip;
515 }
516 
517 enum _ecore_status_t ecore_cxt_cfg_ilt_compute(struct ecore_hwfn *p_hwfn)
518 {
519 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
520 	u32 curr_line, total, i, task_size, line;
521 	struct ecore_ilt_client_cfg *p_cli;
522 	struct ecore_ilt_cli_blk *p_blk;
523 	struct ecore_cdu_iids cdu_iids;
524 	struct ecore_src_iids src_iids;
525 	struct ecore_qm_iids qm_iids;
526 	struct ecore_tm_iids tm_iids;
527 	struct ecore_tid_seg *p_seg;
528 
529 	OSAL_MEM_ZERO(&qm_iids, sizeof(qm_iids));
530 	OSAL_MEM_ZERO(&cdu_iids, sizeof(cdu_iids));
531 	OSAL_MEM_ZERO(&src_iids, sizeof(src_iids));
532 	OSAL_MEM_ZERO(&tm_iids, sizeof(tm_iids));
533 
534 	p_mngr->pf_start_line = RESC_START(p_hwfn, ECORE_ILT);
535 
536 	DP_VERBOSE(p_hwfn, ECORE_MSG_ILT,
537 		   "hwfn [%d] - Set context mngr starting line to be 0x%08x\n",
538 		   p_hwfn->my_id, p_hwfn->p_cxt_mngr->pf_start_line);
539 
540 	/* CDUC */
541 	p_cli = &p_mngr->clients[ILT_CLI_CDUC];
542 
543 	curr_line = p_mngr->pf_start_line;
544 
545 	/* CDUC PF */
546 	p_cli->pf_total_lines = 0;
547 
548 	/* get the counters for the CDUC,CDUC and QM clients  */
549 	ecore_cxt_cdu_iids(p_mngr, &cdu_iids);
550 
551 	p_blk = &p_cli->pf_blks[CDUC_BLK];
552 
553 	total = cdu_iids.pf_cids * CONN_CXT_SIZE(p_hwfn);
554 
555 	ecore_ilt_cli_blk_fill(p_cli, p_blk, curr_line,
556 			       total, CONN_CXT_SIZE(p_hwfn));
557 
558 	ecore_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line, ILT_CLI_CDUC);
559 	p_cli->pf_total_lines = curr_line - p_blk->start_line;
560 
561 	p_blk->dynamic_line_cnt = ecore_ilt_get_dynamic_line_cnt(p_hwfn,
562 								 ILT_CLI_CDUC);
563 
564 	/* CDUC VF */
565 	p_blk = &p_cli->vf_blks[CDUC_BLK];
566 	total = cdu_iids.per_vf_cids * CONN_CXT_SIZE(p_hwfn);
567 
568 	ecore_ilt_cli_blk_fill(p_cli, p_blk, curr_line,
569 			       total, CONN_CXT_SIZE(p_hwfn));
570 
571 	ecore_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line, ILT_CLI_CDUC);
572 	p_cli->vf_total_lines = curr_line - p_blk->start_line;
573 
574 	for (i = 1; i < p_mngr->vf_count; i++)
575 		ecore_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line,
576 				       ILT_CLI_CDUC);
577 
578 	/* CDUT PF */
579 	p_cli = &p_mngr->clients[ILT_CLI_CDUT];
580 	p_cli->first.val = curr_line;
581 
582 	/* first the 'working' task memory */
583 	for (i = 0; i < NUM_TASK_PF_SEGMENTS; i++) {
584 		p_seg = ecore_cxt_tid_seg_info(p_hwfn, i);
585 		if (!p_seg || p_seg->count == 0)
586 			continue;
587 
588 		p_blk = &p_cli->pf_blks[CDUT_SEG_BLK(i)];
589 		total = p_seg->count * p_mngr->task_type_size[p_seg->type];
590 		ecore_ilt_cli_blk_fill(p_cli, p_blk, curr_line, total,
591 				       p_mngr->task_type_size[p_seg->type]);
592 
593 		ecore_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line,
594 				       ILT_CLI_CDUT);
595 	}
596 
597 	/* next the 'init' task memory (forced load memory) */
598 	for (i = 0; i < NUM_TASK_PF_SEGMENTS; i++) {
599 		p_seg = ecore_cxt_tid_seg_info(p_hwfn, i);
600 		if (!p_seg || p_seg->count == 0)
601 			continue;
602 
603 		p_blk = &p_cli->pf_blks[CDUT_FL_SEG_BLK(i, PF)];
604 
605 		if (!p_seg->has_fl_mem) {
606 			/* The segment is active (total size pf 'working'
607 			 * memory is > 0) but has no FL (forced-load, Init)
608 			 * memory. Thus:
609 			 *
610 			 * 1.   The total-size in the corrsponding FL block of
611 			 *      the ILT client is set to 0 - No ILT line are
612 			 *      provisioned and no ILT memory allocated.
613 			 *
614 			 * 2.   The start-line of said block is set to the
615 			 *      start line of the matching working memory
616 			 *      block in the ILT client. This is later used to
617 			 *      configure the CDU segment offset registers and
618 			 *      results in an FL command for TIDs of this
619 			 *      segment behaves as regular load commands
620 			 *      (loading TIDs from the working memory).
621 			 */
622 			line = p_cli->pf_blks[CDUT_SEG_BLK(i)].start_line;
623 
624 			ecore_ilt_cli_blk_fill(p_cli, p_blk, line, 0, 0);
625 			continue;
626 		}
627 		total = p_seg->count * p_mngr->task_type_size[p_seg->type];
628 
629 		ecore_ilt_cli_blk_fill(p_cli, p_blk,
630 				       curr_line, total,
631 				       p_mngr->task_type_size[p_seg->type]);
632 
633 		ecore_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line,
634 				       ILT_CLI_CDUT);
635 	}
636 	p_cli->pf_total_lines = curr_line - p_cli->pf_blks[0].start_line;
637 
638 	/* CDUT VF */
639 	p_seg = ecore_cxt_tid_seg_info(p_hwfn, TASK_SEGMENT_VF);
640 	if (p_seg && p_seg->count) {
641 		/* Stricly speaking we need to iterate over all VF
642 		 * task segment types, but a VF has only 1 segment
643 		 */
644 
645 		/* 'working' memory */
646 		total = p_seg->count * p_mngr->task_type_size[p_seg->type];
647 
648 		p_blk = &p_cli->vf_blks[CDUT_SEG_BLK(0)];
649 		ecore_ilt_cli_blk_fill(p_cli, p_blk,
650 				       curr_line, total,
651 				       p_mngr->task_type_size[p_seg->type]);
652 
653 		ecore_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line,
654 				       ILT_CLI_CDUT);
655 
656 		/* 'init' memory */
657 		p_blk = &p_cli->vf_blks[CDUT_FL_SEG_BLK(0, VF)];
658 		if (!p_seg->has_fl_mem) {
659 			/* see comment above */
660 			line = p_cli->vf_blks[CDUT_SEG_BLK(0)].start_line;
661 			ecore_ilt_cli_blk_fill(p_cli, p_blk, line, 0, 0);
662 		} else {
663 			task_size = p_mngr->task_type_size[p_seg->type];
664 			ecore_ilt_cli_blk_fill(p_cli, p_blk,
665 					       curr_line, total, task_size);
666 			ecore_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line,
667 					       ILT_CLI_CDUT);
668 		}
669 		p_cli->vf_total_lines = curr_line -
670 		    p_cli->vf_blks[0].start_line;
671 
672 		/* Now for the rest of the VFs */
673 		for (i = 1; i < p_mngr->vf_count; i++) {
674 			p_blk = &p_cli->vf_blks[CDUT_SEG_BLK(0)];
675 			ecore_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line,
676 					       ILT_CLI_CDUT);
677 
678 			p_blk = &p_cli->vf_blks[CDUT_FL_SEG_BLK(0, VF)];
679 			ecore_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line,
680 					       ILT_CLI_CDUT);
681 		}
682 	}
683 
684 	/* QM */
685 	p_cli = &p_mngr->clients[ILT_CLI_QM];
686 	p_blk = &p_cli->pf_blks[0];
687 
688 	ecore_cxt_qm_iids(p_hwfn, &qm_iids);
689 	total = ecore_qm_pf_mem_size(qm_iids.cids,
690 				     qm_iids.vf_cids, qm_iids.tids,
691 				     p_hwfn->qm_info.num_pqs,
692 				     p_hwfn->qm_info.num_vf_pqs);
693 
694 	DP_VERBOSE(p_hwfn, ECORE_MSG_ILT,
695 		   "QM ILT Info, (cids=%d, vf_cids=%d, tids=%d, num_pqs=%d,"
696 		   " num_vf_pqs=%d, memory_size=%d)\n",
697 		   qm_iids.cids, qm_iids.vf_cids, qm_iids.tids,
698 		   p_hwfn->qm_info.num_pqs, p_hwfn->qm_info.num_vf_pqs, total);
699 
700 	ecore_ilt_cli_blk_fill(p_cli, p_blk, curr_line, total * 0x1000,
701 			       QM_PQ_ELEMENT_SIZE);
702 
703 	ecore_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line, ILT_CLI_QM);
704 	p_cli->pf_total_lines = curr_line - p_blk->start_line;
705 
706 	/* SRC */
707 	p_cli = &p_mngr->clients[ILT_CLI_SRC];
708 	ecore_cxt_src_iids(p_mngr, &src_iids);
709 
710 	/* Both the PF and VFs searcher connections are stored in the per PF
711 	 * database. Thus sum the PF searcher cids and all the VFs searcher
712 	 * cids.
713 	 */
714 	total = src_iids.pf_cids + src_iids.per_vf_cids * p_mngr->vf_count;
715 	if (total) {
716 		u32 local_max = OSAL_MAX_T(u32, total,
717 					   SRC_MIN_NUM_ELEMS);
718 
719 		total = OSAL_ROUNDUP_POW_OF_TWO(local_max);
720 
721 		p_blk = &p_cli->pf_blks[0];
722 		ecore_ilt_cli_blk_fill(p_cli, p_blk, curr_line,
723 				       total * sizeof(struct src_ent),
724 				       sizeof(struct src_ent));
725 
726 		ecore_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line,
727 				       ILT_CLI_SRC);
728 		p_cli->pf_total_lines = curr_line - p_blk->start_line;
729 	}
730 
731 	/* TM PF */
732 	p_cli = &p_mngr->clients[ILT_CLI_TM];
733 	ecore_cxt_tm_iids(p_mngr, &tm_iids);
734 	total = tm_iids.pf_cids + tm_iids.pf_tids_total;
735 	if (total) {
736 		p_blk = &p_cli->pf_blks[0];
737 		ecore_ilt_cli_blk_fill(p_cli, p_blk, curr_line,
738 				       total * TM_ELEM_SIZE, TM_ELEM_SIZE);
739 
740 		ecore_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line,
741 				       ILT_CLI_TM);
742 		p_cli->pf_total_lines = curr_line - p_blk->start_line;
743 	}
744 
745 	/* TM VF */
746 	total = tm_iids.per_vf_cids + tm_iids.per_vf_tids;
747 	if (total) {
748 		p_blk = &p_cli->vf_blks[0];
749 		ecore_ilt_cli_blk_fill(p_cli, p_blk, curr_line,
750 				       total * TM_ELEM_SIZE, TM_ELEM_SIZE);
751 
752 		ecore_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line,
753 				       ILT_CLI_TM);
754 
755 		p_cli->vf_total_lines = curr_line - p_blk->start_line;
756 		for (i = 1; i < p_mngr->vf_count; i++) {
757 			ecore_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line,
758 					       ILT_CLI_TM);
759 		}
760 	}
761 
762 	/* TSDM (SRQ CONTEXT) */
763 	total = ecore_cxt_get_srq_count(p_hwfn);
764 
765 	if (total) {
766 		p_cli = &p_mngr->clients[ILT_CLI_TSDM];
767 		p_blk = &p_cli->pf_blks[SRQ_BLK];
768 		ecore_ilt_cli_blk_fill(p_cli, p_blk, curr_line,
769 				       total * SRQ_CXT_SIZE, SRQ_CXT_SIZE);
770 
771 		ecore_ilt_cli_adv_line(p_hwfn, p_cli, p_blk, &curr_line,
772 				       ILT_CLI_TSDM);
773 		p_cli->pf_total_lines = curr_line - p_blk->start_line;
774 	}
775 
776 	if (curr_line - p_hwfn->p_cxt_mngr->pf_start_line >
777 	    RESC_NUM(p_hwfn, ECORE_ILT)) {
778 		DP_ERR(p_hwfn, "too many ilt lines...#lines=%d\n",
779 		       curr_line - p_hwfn->p_cxt_mngr->pf_start_line);
780 		return ECORE_INVAL;
781 	}
782 
783 	return ECORE_SUCCESS;
784 }
785 
786 static void ecore_cxt_src_t2_free(struct ecore_hwfn *p_hwfn)
787 {
788 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
789 	u32 i;
790 
791 	if (!p_mngr->t2)
792 		return;
793 
794 	for (i = 0; i < p_mngr->t2_num_pages; i++)
795 		if (p_mngr->t2[i].p_virt)
796 			OSAL_DMA_FREE_COHERENT(p_hwfn->p_dev,
797 					       p_mngr->t2[i].p_virt,
798 					       p_mngr->t2[i].p_phys,
799 					       p_mngr->t2[i].size);
800 
801 	OSAL_FREE(p_hwfn->p_dev, p_mngr->t2);
802 }
803 
804 static enum _ecore_status_t ecore_cxt_src_t2_alloc(struct ecore_hwfn *p_hwfn)
805 {
806 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
807 	u32 conn_num, total_size, ent_per_page, psz, i;
808 	struct ecore_ilt_client_cfg *p_src;
809 	struct ecore_src_iids src_iids;
810 	struct ecore_dma_mem *p_t2;
811 	enum _ecore_status_t rc;
812 
813 	OSAL_MEM_ZERO(&src_iids, sizeof(src_iids));
814 
815 	/* if the SRC ILT client is inactive - there are no connection
816 	 * requiring the searcer, leave.
817 	 */
818 	p_src = &p_hwfn->p_cxt_mngr->clients[ILT_CLI_SRC];
819 	if (!p_src->active)
820 		return ECORE_SUCCESS;
821 
822 	ecore_cxt_src_iids(p_mngr, &src_iids);
823 	conn_num = src_iids.pf_cids + src_iids.per_vf_cids * p_mngr->vf_count;
824 	total_size = conn_num * sizeof(struct src_ent);
825 
826 	/* use the same page size as the SRC ILT client */
827 	psz = ILT_PAGE_IN_BYTES(p_src->p_size.val);
828 	p_mngr->t2_num_pages = DIV_ROUND_UP(total_size, psz);
829 
830 	/* allocate t2 */
831 	p_mngr->t2 = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL,
832 				 p_mngr->t2_num_pages *
833 				 sizeof(struct ecore_dma_mem));
834 	if (!p_mngr->t2) {
835 		DP_NOTICE(p_hwfn, false, "Failed to allocate t2 table\n");
836 		rc = ECORE_NOMEM;
837 		goto t2_fail;
838 	}
839 
840 	/* allocate t2 pages */
841 	for (i = 0; i < p_mngr->t2_num_pages; i++) {
842 		u32 size = OSAL_MIN_T(u32, total_size, psz);
843 		void **p_virt = &p_mngr->t2[i].p_virt;
844 
845 		*p_virt = OSAL_DMA_ALLOC_COHERENT(p_hwfn->p_dev,
846 						  &p_mngr->t2[i].p_phys, size);
847 		if (!p_mngr->t2[i].p_virt) {
848 			rc = ECORE_NOMEM;
849 			goto t2_fail;
850 		}
851 		OSAL_MEM_ZERO(*p_virt, size);
852 		p_mngr->t2[i].size = size;
853 		total_size -= size;
854 	}
855 
856 	/* Set the t2 pointers */
857 
858 	/* entries per page - must be a power of two */
859 	ent_per_page = psz / sizeof(struct src_ent);
860 
861 	p_mngr->first_free = (u64)p_mngr->t2[0].p_phys;
862 
863 	p_t2 = &p_mngr->t2[(conn_num - 1) / ent_per_page];
864 	p_mngr->last_free = (u64)p_t2->p_phys +
865 	    ((conn_num - 1) & (ent_per_page - 1)) * sizeof(struct src_ent);
866 
867 	for (i = 0; i < p_mngr->t2_num_pages; i++) {
868 		u32 ent_num = OSAL_MIN_T(u32, ent_per_page, conn_num);
869 		struct src_ent *entries = p_mngr->t2[i].p_virt;
870 		u64 p_ent_phys = (u64)p_mngr->t2[i].p_phys, val;
871 		u32 j;
872 
873 		for (j = 0; j < ent_num - 1; j++) {
874 			val = p_ent_phys + (j + 1) * sizeof(struct src_ent);
875 			entries[j].next = OSAL_CPU_TO_BE64(val);
876 		}
877 
878 		if (i < p_mngr->t2_num_pages - 1)
879 			val = (u64)p_mngr->t2[i + 1].p_phys;
880 		else
881 			val = 0;
882 		entries[j].next = OSAL_CPU_TO_BE64(val);
883 
884 		conn_num -= ent_num;
885 	}
886 
887 	return ECORE_SUCCESS;
888 
889 t2_fail:
890 	ecore_cxt_src_t2_free(p_hwfn);
891 	return rc;
892 }
893 
894 #define for_each_ilt_valid_client(pos, clients)		\
895 	for (pos = 0; pos < ILT_CLI_MAX; pos++)		\
896 		if (!clients[pos].active) {		\
897 			continue;			\
898 		} else					\
899 
900 
901 /* Total number of ILT lines used by this PF */
902 static u32 ecore_cxt_ilt_shadow_size(struct ecore_ilt_client_cfg *ilt_clients)
903 {
904 	u32 size = 0;
905 	u32 i;
906 
907 	for_each_ilt_valid_client(i, ilt_clients)
908 		size += (ilt_clients[i].last.val -
909 			 ilt_clients[i].first.val + 1);
910 
911 	return size;
912 }
913 
914 static void ecore_ilt_shadow_free(struct ecore_hwfn *p_hwfn)
915 {
916 	struct ecore_ilt_client_cfg *p_cli = p_hwfn->p_cxt_mngr->clients;
917 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
918 	u32 ilt_size, i;
919 
920 	if (p_mngr->ilt_shadow == OSAL_NULL)
921 		return;
922 
923 	ilt_size = ecore_cxt_ilt_shadow_size(p_cli);
924 
925 	for (i = 0; p_mngr->ilt_shadow && i < ilt_size; i++) {
926 		struct ecore_dma_mem *p_dma = &p_mngr->ilt_shadow[i];
927 
928 		if (p_dma->p_virt)
929 			OSAL_DMA_FREE_COHERENT(p_hwfn->p_dev,
930 					       p_dma->p_virt,
931 					       p_dma->p_phys, p_dma->size);
932 		p_dma->p_virt = OSAL_NULL;
933 	}
934 	OSAL_FREE(p_hwfn->p_dev, p_mngr->ilt_shadow);
935 	p_mngr->ilt_shadow = OSAL_NULL;
936 }
937 
938 static enum _ecore_status_t
939 ecore_ilt_blk_alloc(struct ecore_hwfn *p_hwfn,
940 		    struct ecore_ilt_cli_blk *p_blk,
941 		    enum ilt_clients ilt_client, u32 start_line_offset)
942 {
943 	struct ecore_dma_mem *ilt_shadow = p_hwfn->p_cxt_mngr->ilt_shadow;
944 	u32 lines, line, sz_left, lines_to_skip = 0;
945 
946 	/* Special handling for RoCE that supports dynamic allocation */
947 	if (ilt_client == ILT_CLI_CDUT || ilt_client == ILT_CLI_TSDM)
948 		return ECORE_SUCCESS;
949 
950 	lines_to_skip = p_blk->dynamic_line_cnt;
951 
952 	if (!p_blk->total_size)
953 		return ECORE_SUCCESS;
954 
955 	sz_left = p_blk->total_size;
956 	lines = DIV_ROUND_UP(sz_left, p_blk->real_size_in_page) - lines_to_skip;
957 	line = p_blk->start_line + start_line_offset -
958 	    p_hwfn->p_cxt_mngr->pf_start_line + lines_to_skip;
959 
960 	for (; lines; lines--) {
961 		dma_addr_t p_phys;
962 		void *p_virt;
963 		u32 size;
964 
965 		size = OSAL_MIN_T(u32, sz_left, p_blk->real_size_in_page);
966 
967 /* @DPDK */
968 #define ILT_BLOCK_ALIGN_SIZE 0x1000
969 		p_virt = OSAL_DMA_ALLOC_COHERENT_ALIGNED(p_hwfn->p_dev,
970 							 &p_phys, size,
971 							 ILT_BLOCK_ALIGN_SIZE);
972 		if (!p_virt)
973 			return ECORE_NOMEM;
974 		OSAL_MEM_ZERO(p_virt, size);
975 
976 		ilt_shadow[line].p_phys = p_phys;
977 		ilt_shadow[line].p_virt = p_virt;
978 		ilt_shadow[line].size = size;
979 
980 		DP_VERBOSE(p_hwfn, ECORE_MSG_ILT,
981 			   "ILT shadow: Line [%d] Physical 0x%lx"
982 			   " Virtual %p Size %d\n",
983 			   line, (unsigned long)p_phys, p_virt, size);
984 
985 		sz_left -= size;
986 		line++;
987 	}
988 
989 	return ECORE_SUCCESS;
990 }
991 
992 static enum _ecore_status_t ecore_ilt_shadow_alloc(struct ecore_hwfn *p_hwfn)
993 {
994 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
995 	struct ecore_ilt_client_cfg *clients = p_mngr->clients;
996 	struct ecore_ilt_cli_blk *p_blk;
997 	u32 size, i, j, k;
998 	enum _ecore_status_t rc;
999 
1000 	size = ecore_cxt_ilt_shadow_size(clients);
1001 	p_mngr->ilt_shadow = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL,
1002 					 size * sizeof(struct ecore_dma_mem));
1003 
1004 	if (!p_mngr->ilt_shadow) {
1005 		DP_NOTICE(p_hwfn, false, "Failed to allocate ilt shadow table\n");
1006 		rc = ECORE_NOMEM;
1007 		goto ilt_shadow_fail;
1008 	}
1009 
1010 	DP_VERBOSE(p_hwfn, ECORE_MSG_ILT,
1011 		   "Allocated 0x%x bytes for ilt shadow\n",
1012 		   (u32)(size * sizeof(struct ecore_dma_mem)));
1013 
1014 	for_each_ilt_valid_client(i, clients) {
1015 		for (j = 0; j < ILT_CLI_PF_BLOCKS; j++) {
1016 			p_blk = &clients[i].pf_blks[j];
1017 			rc = ecore_ilt_blk_alloc(p_hwfn, p_blk, i, 0);
1018 			if (rc != ECORE_SUCCESS)
1019 				goto ilt_shadow_fail;
1020 		}
1021 		for (k = 0; k < p_mngr->vf_count; k++) {
1022 			for (j = 0; j < ILT_CLI_VF_BLOCKS; j++) {
1023 				u32 lines = clients[i].vf_total_lines * k;
1024 
1025 				p_blk = &clients[i].vf_blks[j];
1026 				rc = ecore_ilt_blk_alloc(p_hwfn, p_blk,
1027 							 i, lines);
1028 				if (rc != ECORE_SUCCESS)
1029 					goto ilt_shadow_fail;
1030 			}
1031 		}
1032 	}
1033 
1034 	return ECORE_SUCCESS;
1035 
1036 ilt_shadow_fail:
1037 	ecore_ilt_shadow_free(p_hwfn);
1038 	return rc;
1039 }
1040 
1041 static void ecore_cid_map_free(struct ecore_hwfn *p_hwfn)
1042 {
1043 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
1044 	u32 type, vf;
1045 
1046 	for (type = 0; type < MAX_CONN_TYPES; type++) {
1047 		OSAL_FREE(p_hwfn->p_dev, p_mngr->acquired[type].cid_map);
1048 		p_mngr->acquired[type].cid_map = OSAL_NULL;
1049 		p_mngr->acquired[type].max_count = 0;
1050 		p_mngr->acquired[type].start_cid = 0;
1051 
1052 		for (vf = 0; vf < COMMON_MAX_NUM_VFS; vf++) {
1053 			OSAL_FREE(p_hwfn->p_dev,
1054 				  p_mngr->acquired_vf[type][vf].cid_map);
1055 			p_mngr->acquired_vf[type][vf].cid_map = OSAL_NULL;
1056 			p_mngr->acquired_vf[type][vf].max_count = 0;
1057 			p_mngr->acquired_vf[type][vf].start_cid = 0;
1058 		}
1059 	}
1060 }
1061 
1062 static enum _ecore_status_t
1063 ecore_cid_map_alloc_single(struct ecore_hwfn *p_hwfn, u32 type,
1064 			   u32 cid_start, u32 cid_count,
1065 			   struct ecore_cid_acquired_map *p_map)
1066 {
1067 	u32 size;
1068 
1069 	if (!cid_count)
1070 		return ECORE_SUCCESS;
1071 
1072 	size = MAP_WORD_SIZE * DIV_ROUND_UP(cid_count, BITS_PER_MAP_WORD);
1073 	p_map->cid_map = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL, size);
1074 	if (p_map->cid_map == OSAL_NULL)
1075 		return ECORE_NOMEM;
1076 
1077 	p_map->max_count = cid_count;
1078 	p_map->start_cid = cid_start;
1079 
1080 	DP_VERBOSE(p_hwfn, ECORE_MSG_CXT,
1081 		   "Type %08x start: %08x count %08x\n",
1082 		   type, p_map->start_cid, p_map->max_count);
1083 
1084 	return ECORE_SUCCESS;
1085 }
1086 
1087 static enum _ecore_status_t ecore_cid_map_alloc(struct ecore_hwfn *p_hwfn)
1088 {
1089 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
1090 	u32 start_cid = 0, vf_start_cid = 0;
1091 	u32 type, vf;
1092 
1093 	for (type = 0; type < MAX_CONN_TYPES; type++) {
1094 		struct ecore_conn_type_cfg *p_cfg = &p_mngr->conn_cfg[type];
1095 		struct ecore_cid_acquired_map *p_map;
1096 
1097 		/* Handle PF maps */
1098 		p_map = &p_mngr->acquired[type];
1099 		if (ecore_cid_map_alloc_single(p_hwfn, type, start_cid,
1100 					       p_cfg->cid_count, p_map))
1101 			goto cid_map_fail;
1102 
1103 		/* Handle VF maps */
1104 		for (vf = 0; vf < COMMON_MAX_NUM_VFS; vf++) {
1105 			p_map = &p_mngr->acquired_vf[type][vf];
1106 			if (ecore_cid_map_alloc_single(p_hwfn, type,
1107 						       vf_start_cid,
1108 						       p_cfg->cids_per_vf,
1109 						       p_map))
1110 				goto cid_map_fail;
1111 		}
1112 
1113 		start_cid += p_cfg->cid_count;
1114 		vf_start_cid += p_cfg->cids_per_vf;
1115 	}
1116 
1117 	return ECORE_SUCCESS;
1118 
1119 cid_map_fail:
1120 	ecore_cid_map_free(p_hwfn);
1121 	return ECORE_NOMEM;
1122 }
1123 
1124 enum _ecore_status_t ecore_cxt_mngr_alloc(struct ecore_hwfn *p_hwfn)
1125 {
1126 	struct ecore_ilt_client_cfg *clients;
1127 	struct ecore_cxt_mngr *p_mngr;
1128 	u32 i;
1129 
1130 	p_mngr = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL, sizeof(*p_mngr));
1131 	if (!p_mngr) {
1132 		DP_NOTICE(p_hwfn, false, "Failed to allocate `struct ecore_cxt_mngr'\n");
1133 		return ECORE_NOMEM;
1134 	}
1135 
1136 	/* Set the cxt mangr pointer prior to further allocations */
1137 	p_hwfn->p_cxt_mngr = p_mngr;
1138 
1139 	/* Initialize ILT client registers */
1140 	clients = p_mngr->clients;
1141 	clients[ILT_CLI_CDUC].first.reg = ILT_CFG_REG(CDUC, FIRST_ILT);
1142 	clients[ILT_CLI_CDUC].last.reg  = ILT_CFG_REG(CDUC, LAST_ILT);
1143 	clients[ILT_CLI_CDUC].p_size.reg = ILT_CFG_REG(CDUC, P_SIZE);
1144 
1145 	clients[ILT_CLI_QM].first.reg   = ILT_CFG_REG(QM, FIRST_ILT);
1146 	clients[ILT_CLI_QM].last.reg    = ILT_CFG_REG(QM, LAST_ILT);
1147 	clients[ILT_CLI_QM].p_size.reg  = ILT_CFG_REG(QM, P_SIZE);
1148 
1149 	clients[ILT_CLI_TM].first.reg   = ILT_CFG_REG(TM, FIRST_ILT);
1150 	clients[ILT_CLI_TM].last.reg    = ILT_CFG_REG(TM, LAST_ILT);
1151 	clients[ILT_CLI_TM].p_size.reg  = ILT_CFG_REG(TM, P_SIZE);
1152 
1153 	clients[ILT_CLI_SRC].first.reg  = ILT_CFG_REG(SRC, FIRST_ILT);
1154 	clients[ILT_CLI_SRC].last.reg   = ILT_CFG_REG(SRC, LAST_ILT);
1155 	clients[ILT_CLI_SRC].p_size.reg = ILT_CFG_REG(SRC, P_SIZE);
1156 
1157 	clients[ILT_CLI_CDUT].first.reg = ILT_CFG_REG(CDUT, FIRST_ILT);
1158 	clients[ILT_CLI_CDUT].last.reg  = ILT_CFG_REG(CDUT, LAST_ILT);
1159 	clients[ILT_CLI_CDUT].p_size.reg = ILT_CFG_REG(CDUT, P_SIZE);
1160 
1161 	clients[ILT_CLI_TSDM].first.reg = ILT_CFG_REG(TSDM, FIRST_ILT);
1162 	clients[ILT_CLI_TSDM].last.reg  = ILT_CFG_REG(TSDM, LAST_ILT);
1163 	clients[ILT_CLI_TSDM].p_size.reg = ILT_CFG_REG(TSDM, P_SIZE);
1164 
1165 	/* default ILT page size for all clients is 64K */
1166 	for (i = 0; i < ILT_CLI_MAX; i++)
1167 		p_mngr->clients[i].p_size.val = ILT_DEFAULT_HW_P_SIZE;
1168 
1169 	/* due to removal of ISCSI/FCoE files union type0_task_context
1170 	 * task_type_size will be 0. So hardcoded for now.
1171 	 */
1172 	p_mngr->task_type_size[0] = 512; /* @DPDK */
1173 	p_mngr->task_type_size[1] = 128; /* @DPDK */
1174 
1175 	if (p_hwfn->p_dev->p_iov_info)
1176 		p_mngr->vf_count = p_hwfn->p_dev->p_iov_info->total_vfs;
1177 
1178 	/* Initialize the dynamic ILT allocation mutex */
1179 #ifdef CONFIG_ECORE_LOCK_ALLOC
1180 	if (OSAL_MUTEX_ALLOC(p_hwfn, &p_mngr->mutex)) {
1181 		DP_NOTICE(p_hwfn, false, "Failed to alloc p_mngr->mutex\n");
1182 		return ECORE_NOMEM;
1183 	}
1184 #endif
1185 	OSAL_MUTEX_INIT(&p_mngr->mutex);
1186 
1187 	return ECORE_SUCCESS;
1188 }
1189 
1190 enum _ecore_status_t ecore_cxt_tables_alloc(struct ecore_hwfn *p_hwfn)
1191 {
1192 	enum _ecore_status_t rc;
1193 
1194 	/* Allocate the ILT shadow table */
1195 	rc = ecore_ilt_shadow_alloc(p_hwfn);
1196 	if (rc) {
1197 		DP_NOTICE(p_hwfn, false, "Failed to allocate ilt memory\n");
1198 		goto tables_alloc_fail;
1199 	}
1200 
1201 	/* Allocate the T2  table */
1202 	rc = ecore_cxt_src_t2_alloc(p_hwfn);
1203 	if (rc) {
1204 		DP_NOTICE(p_hwfn, false, "Failed to allocate T2 memory\n");
1205 		goto tables_alloc_fail;
1206 	}
1207 
1208 	/* Allocate and initialize the acquired cids bitmaps */
1209 	rc = ecore_cid_map_alloc(p_hwfn);
1210 	if (rc) {
1211 		DP_NOTICE(p_hwfn, false, "Failed to allocate cid maps\n");
1212 		goto tables_alloc_fail;
1213 	}
1214 
1215 	return ECORE_SUCCESS;
1216 
1217 tables_alloc_fail:
1218 	ecore_cxt_mngr_free(p_hwfn);
1219 	return rc;
1220 }
1221 
1222 void ecore_cxt_mngr_free(struct ecore_hwfn *p_hwfn)
1223 {
1224 	if (!p_hwfn->p_cxt_mngr)
1225 		return;
1226 
1227 	ecore_cid_map_free(p_hwfn);
1228 	ecore_cxt_src_t2_free(p_hwfn);
1229 	ecore_ilt_shadow_free(p_hwfn);
1230 #ifdef CONFIG_ECORE_LOCK_ALLOC
1231 	OSAL_MUTEX_DEALLOC(&p_hwfn->p_cxt_mngr->mutex);
1232 #endif
1233 	OSAL_FREE(p_hwfn->p_dev, p_hwfn->p_cxt_mngr);
1234 }
1235 
1236 void ecore_cxt_mngr_setup(struct ecore_hwfn *p_hwfn)
1237 {
1238 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
1239 	struct ecore_cid_acquired_map *p_map;
1240 	struct ecore_conn_type_cfg *p_cfg;
1241 	int type;
1242 	u32 len;
1243 
1244 	/* Reset acquired cids */
1245 	for (type = 0; type < MAX_CONN_TYPES; type++) {
1246 		u32 vf;
1247 
1248 		p_cfg = &p_mngr->conn_cfg[type];
1249 		if (p_cfg->cid_count) {
1250 			p_map = &p_mngr->acquired[type];
1251 			len = DIV_ROUND_UP(p_map->max_count,
1252 					   BITS_PER_MAP_WORD) *
1253 			      MAP_WORD_SIZE;
1254 			OSAL_MEM_ZERO(p_map->cid_map, len);
1255 		}
1256 
1257 		if (!p_cfg->cids_per_vf)
1258 			continue;
1259 
1260 		for (vf = 0; vf < COMMON_MAX_NUM_VFS; vf++) {
1261 			p_map = &p_mngr->acquired_vf[type][vf];
1262 			len = DIV_ROUND_UP(p_map->max_count,
1263 					   BITS_PER_MAP_WORD) *
1264 			      MAP_WORD_SIZE;
1265 			OSAL_MEM_ZERO(p_map->cid_map, len);
1266 		}
1267 	}
1268 }
1269 
1270 /* HW initialization helper (per Block, per phase) */
1271 
1272 /* CDU Common */
1273 #define CDUC_CXT_SIZE_SHIFT						\
1274 	CDU_REG_CID_ADDR_PARAMS_CONTEXT_SIZE_SHIFT
1275 
1276 #define CDUC_CXT_SIZE_MASK						\
1277 	(CDU_REG_CID_ADDR_PARAMS_CONTEXT_SIZE >> CDUC_CXT_SIZE_SHIFT)
1278 
1279 #define CDUC_BLOCK_WASTE_SHIFT						\
1280 	CDU_REG_CID_ADDR_PARAMS_BLOCK_WASTE_SHIFT
1281 
1282 #define CDUC_BLOCK_WASTE_MASK						\
1283 	(CDU_REG_CID_ADDR_PARAMS_BLOCK_WASTE >> CDUC_BLOCK_WASTE_SHIFT)
1284 
1285 #define CDUC_NCIB_SHIFT							\
1286 	CDU_REG_CID_ADDR_PARAMS_NCIB_SHIFT
1287 
1288 #define CDUC_NCIB_MASK							\
1289 	(CDU_REG_CID_ADDR_PARAMS_NCIB >> CDUC_NCIB_SHIFT)
1290 
1291 #define CDUT_TYPE0_CXT_SIZE_SHIFT					\
1292 	CDU_REG_SEGMENT0_PARAMS_T0_TID_SIZE_SHIFT
1293 
1294 #define CDUT_TYPE0_CXT_SIZE_MASK					\
1295 	(CDU_REG_SEGMENT0_PARAMS_T0_TID_SIZE >>				\
1296 	CDUT_TYPE0_CXT_SIZE_SHIFT)
1297 
1298 #define CDUT_TYPE0_BLOCK_WASTE_SHIFT					\
1299 	CDU_REG_SEGMENT0_PARAMS_T0_TID_BLOCK_WASTE_SHIFT
1300 
1301 #define CDUT_TYPE0_BLOCK_WASTE_MASK					\
1302 	(CDU_REG_SEGMENT0_PARAMS_T0_TID_BLOCK_WASTE >>			\
1303 	CDUT_TYPE0_BLOCK_WASTE_SHIFT)
1304 
1305 #define CDUT_TYPE0_NCIB_SHIFT						\
1306 	CDU_REG_SEGMENT0_PARAMS_T0_NUM_TIDS_IN_BLOCK_SHIFT
1307 
1308 #define CDUT_TYPE0_NCIB_MASK						\
1309 	(CDU_REG_SEGMENT0_PARAMS_T0_NUM_TIDS_IN_BLOCK >>		\
1310 	CDUT_TYPE0_NCIB_SHIFT)
1311 
1312 #define CDUT_TYPE1_CXT_SIZE_SHIFT					\
1313 	CDU_REG_SEGMENT1_PARAMS_T1_TID_SIZE_SHIFT
1314 
1315 #define CDUT_TYPE1_CXT_SIZE_MASK					\
1316 	(CDU_REG_SEGMENT1_PARAMS_T1_TID_SIZE >>				\
1317 	CDUT_TYPE1_CXT_SIZE_SHIFT)
1318 
1319 #define CDUT_TYPE1_BLOCK_WASTE_SHIFT					\
1320 	CDU_REG_SEGMENT1_PARAMS_T1_TID_BLOCK_WASTE_SHIFT
1321 
1322 #define CDUT_TYPE1_BLOCK_WASTE_MASK					\
1323 	(CDU_REG_SEGMENT1_PARAMS_T1_TID_BLOCK_WASTE >>			\
1324 	CDUT_TYPE1_BLOCK_WASTE_SHIFT)
1325 
1326 #define CDUT_TYPE1_NCIB_SHIFT						\
1327 	CDU_REG_SEGMENT1_PARAMS_T1_NUM_TIDS_IN_BLOCK_SHIFT
1328 
1329 #define CDUT_TYPE1_NCIB_MASK						\
1330 	(CDU_REG_SEGMENT1_PARAMS_T1_NUM_TIDS_IN_BLOCK >>		\
1331 	CDUT_TYPE1_NCIB_SHIFT)
1332 
1333 static void ecore_cdu_init_common(struct ecore_hwfn *p_hwfn)
1334 {
1335 	u32 page_sz, elems_per_page, block_waste, cxt_size, cdu_params = 0;
1336 
1337 	/* CDUC - connection configuration */
1338 	page_sz = p_hwfn->p_cxt_mngr->clients[ILT_CLI_CDUC].p_size.val;
1339 	cxt_size = CONN_CXT_SIZE(p_hwfn);
1340 	elems_per_page = ILT_PAGE_IN_BYTES(page_sz) / cxt_size;
1341 	block_waste = ILT_PAGE_IN_BYTES(page_sz) - elems_per_page * cxt_size;
1342 
1343 	SET_FIELD(cdu_params, CDUC_CXT_SIZE, cxt_size);
1344 	SET_FIELD(cdu_params, CDUC_BLOCK_WASTE, block_waste);
1345 	SET_FIELD(cdu_params, CDUC_NCIB, elems_per_page);
1346 	STORE_RT_REG(p_hwfn, CDU_REG_CID_ADDR_PARAMS_RT_OFFSET, cdu_params);
1347 
1348 	/* CDUT - type-0 tasks configuration */
1349 	page_sz = p_hwfn->p_cxt_mngr->clients[ILT_CLI_CDUT].p_size.val;
1350 	cxt_size = p_hwfn->p_cxt_mngr->task_type_size[0];
1351 	elems_per_page = ILT_PAGE_IN_BYTES(page_sz) / cxt_size;
1352 	block_waste = ILT_PAGE_IN_BYTES(page_sz) - elems_per_page * cxt_size;
1353 
1354 	/* cxt size and block-waste are multipes of 8 */
1355 	cdu_params = 0;
1356 	SET_FIELD(cdu_params, CDUT_TYPE0_CXT_SIZE, (cxt_size >> 3));
1357 	SET_FIELD(cdu_params, CDUT_TYPE0_BLOCK_WASTE, (block_waste >> 3));
1358 	SET_FIELD(cdu_params, CDUT_TYPE0_NCIB, elems_per_page);
1359 	STORE_RT_REG(p_hwfn, CDU_REG_SEGMENT0_PARAMS_RT_OFFSET, cdu_params);
1360 
1361 	/* CDUT - type-1 tasks configuration */
1362 	cxt_size = p_hwfn->p_cxt_mngr->task_type_size[1];
1363 	elems_per_page = ILT_PAGE_IN_BYTES(page_sz) / cxt_size;
1364 	block_waste = ILT_PAGE_IN_BYTES(page_sz) - elems_per_page * cxt_size;
1365 
1366 	/* cxt size and block-waste are multipes of 8 */
1367 	cdu_params = 0;
1368 	SET_FIELD(cdu_params, CDUT_TYPE1_CXT_SIZE, (cxt_size >> 3));
1369 	SET_FIELD(cdu_params, CDUT_TYPE1_BLOCK_WASTE, (block_waste >> 3));
1370 	SET_FIELD(cdu_params, CDUT_TYPE1_NCIB, elems_per_page);
1371 	STORE_RT_REG(p_hwfn, CDU_REG_SEGMENT1_PARAMS_RT_OFFSET, cdu_params);
1372 }
1373 
1374 /* CDU PF */
1375 #define CDU_SEG_REG_TYPE_SHIFT		CDU_SEG_TYPE_OFFSET_REG_TYPE_SHIFT
1376 #define CDU_SEG_REG_TYPE_MASK		0x1
1377 #define CDU_SEG_REG_OFFSET_SHIFT	0
1378 #define CDU_SEG_REG_OFFSET_MASK		CDU_SEG_TYPE_OFFSET_REG_OFFSET_MASK
1379 
1380 static void ecore_cdu_init_pf(struct ecore_hwfn *p_hwfn)
1381 {
1382 	struct ecore_ilt_client_cfg *p_cli;
1383 	struct ecore_tid_seg *p_seg;
1384 	u32 cdu_seg_params, offset;
1385 	int i;
1386 
1387 	static const u32 rt_type_offset_arr[] = {
1388 		CDU_REG_PF_SEG0_TYPE_OFFSET_RT_OFFSET,
1389 		CDU_REG_PF_SEG1_TYPE_OFFSET_RT_OFFSET,
1390 		CDU_REG_PF_SEG2_TYPE_OFFSET_RT_OFFSET,
1391 		CDU_REG_PF_SEG3_TYPE_OFFSET_RT_OFFSET
1392 	};
1393 
1394 	static const u32 rt_type_offset_fl_arr[] = {
1395 		CDU_REG_PF_FL_SEG0_TYPE_OFFSET_RT_OFFSET,
1396 		CDU_REG_PF_FL_SEG1_TYPE_OFFSET_RT_OFFSET,
1397 		CDU_REG_PF_FL_SEG2_TYPE_OFFSET_RT_OFFSET,
1398 		CDU_REG_PF_FL_SEG3_TYPE_OFFSET_RT_OFFSET
1399 	};
1400 
1401 	p_cli = &p_hwfn->p_cxt_mngr->clients[ILT_CLI_CDUT];
1402 
1403 	/* There are initializations only for CDUT during pf Phase */
1404 	for (i = 0; i < NUM_TASK_PF_SEGMENTS; i++) {
1405 		/* Segment 0 */
1406 		p_seg = ecore_cxt_tid_seg_info(p_hwfn, i);
1407 		if (!p_seg)
1408 			continue;
1409 
1410 		/* Note: start_line is already adjusted for the CDU
1411 		 * segment register granularity, so we just need to
1412 		 * divide. Adjustment is implicit as we assume ILT
1413 		 * Page size is larger than 32K!
1414 		 */
1415 		offset = (ILT_PAGE_IN_BYTES(p_cli->p_size.val) *
1416 			  (p_cli->pf_blks[CDUT_SEG_BLK(i)].start_line -
1417 			   p_cli->first.val)) / CDUT_SEG_ALIGNMET_IN_BYTES;
1418 
1419 		cdu_seg_params = 0;
1420 		SET_FIELD(cdu_seg_params, CDU_SEG_REG_TYPE, p_seg->type);
1421 		SET_FIELD(cdu_seg_params, CDU_SEG_REG_OFFSET, offset);
1422 		STORE_RT_REG(p_hwfn, rt_type_offset_arr[i], cdu_seg_params);
1423 
1424 		offset = (ILT_PAGE_IN_BYTES(p_cli->p_size.val) *
1425 			  (p_cli->pf_blks[CDUT_FL_SEG_BLK(i, PF)].start_line -
1426 			   p_cli->first.val)) / CDUT_SEG_ALIGNMET_IN_BYTES;
1427 
1428 		cdu_seg_params = 0;
1429 		SET_FIELD(cdu_seg_params, CDU_SEG_REG_TYPE, p_seg->type);
1430 		SET_FIELD(cdu_seg_params, CDU_SEG_REG_OFFSET, offset);
1431 		STORE_RT_REG(p_hwfn, rt_type_offset_fl_arr[i], cdu_seg_params);
1432 	}
1433 }
1434 
1435 void ecore_qm_init_pf(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
1436 		      bool is_pf_loading)
1437 {
1438 	struct ecore_qm_info *qm_info = &p_hwfn->qm_info;
1439 	struct ecore_mcp_link_state *p_link;
1440 	struct ecore_qm_iids iids;
1441 
1442 	OSAL_MEM_ZERO(&iids, sizeof(iids));
1443 	ecore_cxt_qm_iids(p_hwfn, &iids);
1444 
1445 	p_link = &ECORE_LEADING_HWFN(p_hwfn->p_dev)->mcp_info->link_output;
1446 
1447 	ecore_qm_pf_rt_init(p_hwfn, p_ptt, p_hwfn->rel_pf_id,
1448 			    qm_info->max_phys_tcs_per_port,
1449 			    is_pf_loading,
1450 			    iids.cids, iids.vf_cids, iids.tids,
1451 			    qm_info->start_pq,
1452 			    qm_info->num_pqs - qm_info->num_vf_pqs,
1453 			    qm_info->num_vf_pqs,
1454 			    qm_info->start_vport,
1455 			    qm_info->num_vports, qm_info->pf_wfq,
1456 			    qm_info->pf_rl, p_link->speed,
1457 			    p_hwfn->qm_info.qm_pq_params,
1458 			    p_hwfn->qm_info.qm_vport_params);
1459 }
1460 
1461 /* CM PF */
1462 static void ecore_cm_init_pf(struct ecore_hwfn *p_hwfn)
1463 {
1464 	STORE_RT_REG(p_hwfn, XCM_REG_CON_PHY_Q3_RT_OFFSET,
1465 		     ecore_get_cm_pq_idx(p_hwfn, PQ_FLAGS_LB));
1466 }
1467 
1468 /* DQ PF */
1469 static void ecore_dq_init_pf(struct ecore_hwfn *p_hwfn)
1470 {
1471 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
1472 	u32 dq_pf_max_cid = 0, dq_vf_max_cid = 0;
1473 
1474 	dq_pf_max_cid += (p_mngr->conn_cfg[0].cid_count >> DQ_RANGE_SHIFT);
1475 	STORE_RT_REG(p_hwfn, DORQ_REG_PF_MAX_ICID_0_RT_OFFSET, dq_pf_max_cid);
1476 
1477 	dq_vf_max_cid += (p_mngr->conn_cfg[0].cids_per_vf >> DQ_RANGE_SHIFT);
1478 	STORE_RT_REG(p_hwfn, DORQ_REG_VF_MAX_ICID_0_RT_OFFSET, dq_vf_max_cid);
1479 
1480 	dq_pf_max_cid += (p_mngr->conn_cfg[1].cid_count >> DQ_RANGE_SHIFT);
1481 	STORE_RT_REG(p_hwfn, DORQ_REG_PF_MAX_ICID_1_RT_OFFSET, dq_pf_max_cid);
1482 
1483 	dq_vf_max_cid += (p_mngr->conn_cfg[1].cids_per_vf >> DQ_RANGE_SHIFT);
1484 	STORE_RT_REG(p_hwfn, DORQ_REG_VF_MAX_ICID_1_RT_OFFSET, dq_vf_max_cid);
1485 
1486 	dq_pf_max_cid += (p_mngr->conn_cfg[2].cid_count >> DQ_RANGE_SHIFT);
1487 	STORE_RT_REG(p_hwfn, DORQ_REG_PF_MAX_ICID_2_RT_OFFSET, dq_pf_max_cid);
1488 
1489 	dq_vf_max_cid += (p_mngr->conn_cfg[2].cids_per_vf >> DQ_RANGE_SHIFT);
1490 	STORE_RT_REG(p_hwfn, DORQ_REG_VF_MAX_ICID_2_RT_OFFSET, dq_vf_max_cid);
1491 
1492 	dq_pf_max_cid += (p_mngr->conn_cfg[3].cid_count >> DQ_RANGE_SHIFT);
1493 	STORE_RT_REG(p_hwfn, DORQ_REG_PF_MAX_ICID_3_RT_OFFSET, dq_pf_max_cid);
1494 
1495 	dq_vf_max_cid += (p_mngr->conn_cfg[3].cids_per_vf >> DQ_RANGE_SHIFT);
1496 	STORE_RT_REG(p_hwfn, DORQ_REG_VF_MAX_ICID_3_RT_OFFSET, dq_vf_max_cid);
1497 
1498 	dq_pf_max_cid += (p_mngr->conn_cfg[4].cid_count >> DQ_RANGE_SHIFT);
1499 	STORE_RT_REG(p_hwfn, DORQ_REG_PF_MAX_ICID_4_RT_OFFSET, dq_pf_max_cid);
1500 
1501 	dq_vf_max_cid += (p_mngr->conn_cfg[4].cids_per_vf >> DQ_RANGE_SHIFT);
1502 	STORE_RT_REG(p_hwfn, DORQ_REG_VF_MAX_ICID_4_RT_OFFSET, dq_vf_max_cid);
1503 
1504 	dq_pf_max_cid += (p_mngr->conn_cfg[5].cid_count >> DQ_RANGE_SHIFT);
1505 	STORE_RT_REG(p_hwfn, DORQ_REG_PF_MAX_ICID_5_RT_OFFSET, dq_pf_max_cid);
1506 
1507 	dq_vf_max_cid += (p_mngr->conn_cfg[5].cids_per_vf >> DQ_RANGE_SHIFT);
1508 	STORE_RT_REG(p_hwfn, DORQ_REG_VF_MAX_ICID_5_RT_OFFSET, dq_vf_max_cid);
1509 
1510 	/* Connection types 6 & 7 are not in use, yet they must be configured
1511 	 * as the highest possible connection. Not configuring them means the
1512 	 * defaults will be  used, and with a large number of cids a bug may
1513 	 * occur, if the defaults will be smaller than dq_pf_max_cid /
1514 	 * dq_vf_max_cid.
1515 	 */
1516 	STORE_RT_REG(p_hwfn, DORQ_REG_PF_MAX_ICID_6_RT_OFFSET, dq_pf_max_cid);
1517 	STORE_RT_REG(p_hwfn, DORQ_REG_VF_MAX_ICID_6_RT_OFFSET, dq_vf_max_cid);
1518 
1519 	STORE_RT_REG(p_hwfn, DORQ_REG_PF_MAX_ICID_7_RT_OFFSET, dq_pf_max_cid);
1520 	STORE_RT_REG(p_hwfn, DORQ_REG_VF_MAX_ICID_7_RT_OFFSET, dq_vf_max_cid);
1521 }
1522 
1523 static void ecore_ilt_bounds_init(struct ecore_hwfn *p_hwfn)
1524 {
1525 	struct ecore_ilt_client_cfg *ilt_clients;
1526 	int i;
1527 
1528 	ilt_clients = p_hwfn->p_cxt_mngr->clients;
1529 	for_each_ilt_valid_client(i, ilt_clients) {
1530 		STORE_RT_REG(p_hwfn,
1531 			     ilt_clients[i].first.reg,
1532 			     ilt_clients[i].first.val);
1533 		STORE_RT_REG(p_hwfn,
1534 			     ilt_clients[i].last.reg, ilt_clients[i].last.val);
1535 		STORE_RT_REG(p_hwfn,
1536 			     ilt_clients[i].p_size.reg,
1537 			     ilt_clients[i].p_size.val);
1538 	}
1539 }
1540 
1541 static void ecore_ilt_vf_bounds_init(struct ecore_hwfn *p_hwfn)
1542 {
1543 	struct ecore_ilt_client_cfg *p_cli;
1544 	u32 blk_factor;
1545 
1546 	/* For simplicty  we set the 'block' to be an ILT page */
1547 	if (p_hwfn->p_dev->p_iov_info) {
1548 		struct ecore_hw_sriov_info *p_iov = p_hwfn->p_dev->p_iov_info;
1549 
1550 		STORE_RT_REG(p_hwfn,
1551 			     PSWRQ2_REG_VF_BASE_RT_OFFSET,
1552 			     p_iov->first_vf_in_pf);
1553 		STORE_RT_REG(p_hwfn,
1554 			     PSWRQ2_REG_VF_LAST_ILT_RT_OFFSET,
1555 			     p_iov->first_vf_in_pf + p_iov->total_vfs);
1556 	}
1557 
1558 	p_cli = &p_hwfn->p_cxt_mngr->clients[ILT_CLI_CDUC];
1559 	blk_factor = OSAL_LOG2(ILT_PAGE_IN_BYTES(p_cli->p_size.val) >> 10);
1560 	if (p_cli->active) {
1561 		STORE_RT_REG(p_hwfn,
1562 			     PSWRQ2_REG_CDUC_BLOCKS_FACTOR_RT_OFFSET,
1563 			     blk_factor);
1564 		STORE_RT_REG(p_hwfn,
1565 			     PSWRQ2_REG_CDUC_NUMBER_OF_PF_BLOCKS_RT_OFFSET,
1566 			     p_cli->pf_total_lines);
1567 		STORE_RT_REG(p_hwfn,
1568 			     PSWRQ2_REG_CDUC_VF_BLOCKS_RT_OFFSET,
1569 			     p_cli->vf_total_lines);
1570 	}
1571 
1572 	p_cli = &p_hwfn->p_cxt_mngr->clients[ILT_CLI_CDUT];
1573 	blk_factor = OSAL_LOG2(ILT_PAGE_IN_BYTES(p_cli->p_size.val) >> 10);
1574 	if (p_cli->active) {
1575 		STORE_RT_REG(p_hwfn,
1576 			     PSWRQ2_REG_CDUT_BLOCKS_FACTOR_RT_OFFSET,
1577 			     blk_factor);
1578 		STORE_RT_REG(p_hwfn,
1579 			     PSWRQ2_REG_CDUT_NUMBER_OF_PF_BLOCKS_RT_OFFSET,
1580 			     p_cli->pf_total_lines);
1581 		STORE_RT_REG(p_hwfn,
1582 			     PSWRQ2_REG_CDUT_VF_BLOCKS_RT_OFFSET,
1583 			     p_cli->vf_total_lines);
1584 	}
1585 
1586 	p_cli = &p_hwfn->p_cxt_mngr->clients[ILT_CLI_TM];
1587 	blk_factor = OSAL_LOG2(ILT_PAGE_IN_BYTES(p_cli->p_size.val) >> 10);
1588 	if (p_cli->active) {
1589 		STORE_RT_REG(p_hwfn,
1590 			     PSWRQ2_REG_TM_BLOCKS_FACTOR_RT_OFFSET, blk_factor);
1591 		STORE_RT_REG(p_hwfn,
1592 			     PSWRQ2_REG_TM_NUMBER_OF_PF_BLOCKS_RT_OFFSET,
1593 			     p_cli->pf_total_lines);
1594 		STORE_RT_REG(p_hwfn,
1595 			     PSWRQ2_REG_TM_VF_BLOCKS_RT_OFFSET,
1596 			     p_cli->vf_total_lines);
1597 	}
1598 }
1599 
1600 /* ILT (PSWRQ2) PF */
1601 static void ecore_ilt_init_pf(struct ecore_hwfn *p_hwfn)
1602 {
1603 	struct ecore_ilt_client_cfg *clients;
1604 	struct ecore_cxt_mngr *p_mngr;
1605 	struct ecore_dma_mem *p_shdw;
1606 	u32 line, rt_offst, i;
1607 
1608 	ecore_ilt_bounds_init(p_hwfn);
1609 	ecore_ilt_vf_bounds_init(p_hwfn);
1610 
1611 	p_mngr = p_hwfn->p_cxt_mngr;
1612 	p_shdw = p_mngr->ilt_shadow;
1613 	clients = p_hwfn->p_cxt_mngr->clients;
1614 
1615 	for_each_ilt_valid_client(i, clients) {
1616 		/* Client's 1st val and RT array are absolute, ILT shadows'
1617 		 * lines are relative.
1618 		 */
1619 		line = clients[i].first.val - p_mngr->pf_start_line;
1620 		rt_offst = PSWRQ2_REG_ILT_MEMORY_RT_OFFSET +
1621 		    clients[i].first.val * ILT_ENTRY_IN_REGS;
1622 
1623 		for (; line <= clients[i].last.val - p_mngr->pf_start_line;
1624 		     line++, rt_offst += ILT_ENTRY_IN_REGS) {
1625 			u64 ilt_hw_entry = 0;
1626 
1627 			/** p_virt could be OSAL_NULL incase of dynamic
1628 			 *  allocation
1629 			 */
1630 			if (p_shdw[line].p_virt != OSAL_NULL) {
1631 				SET_FIELD(ilt_hw_entry, ILT_ENTRY_VALID, 1ULL);
1632 				SET_FIELD(ilt_hw_entry, ILT_ENTRY_PHY_ADDR,
1633 					  (p_shdw[line].p_phys >> 12));
1634 
1635 				DP_VERBOSE(p_hwfn, ECORE_MSG_ILT,
1636 					"Setting RT[0x%08x] from"
1637 					" ILT[0x%08x] [Client is %d] to"
1638 					" Physical addr: 0x%lx\n",
1639 					rt_offst, line, i,
1640 					(unsigned long)(p_shdw[line].
1641 							p_phys >> 12));
1642 			}
1643 
1644 			STORE_RT_REG_AGG(p_hwfn, rt_offst, ilt_hw_entry);
1645 		}
1646 	}
1647 }
1648 
1649 /* SRC (Searcher) PF */
1650 static void ecore_src_init_pf(struct ecore_hwfn *p_hwfn)
1651 {
1652 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
1653 	u32 rounded_conn_num, conn_num, conn_max;
1654 	struct ecore_src_iids src_iids;
1655 
1656 	OSAL_MEM_ZERO(&src_iids, sizeof(src_iids));
1657 	ecore_cxt_src_iids(p_mngr, &src_iids);
1658 	conn_num = src_iids.pf_cids + src_iids.per_vf_cids * p_mngr->vf_count;
1659 	if (!conn_num)
1660 		return;
1661 
1662 	conn_max = OSAL_MAX_T(u32, conn_num, SRC_MIN_NUM_ELEMS);
1663 	rounded_conn_num = OSAL_ROUNDUP_POW_OF_TWO(conn_max);
1664 
1665 	STORE_RT_REG(p_hwfn, SRC_REG_COUNTFREE_RT_OFFSET, conn_num);
1666 	STORE_RT_REG(p_hwfn, SRC_REG_NUMBER_HASH_BITS_RT_OFFSET,
1667 		     OSAL_LOG2(rounded_conn_num));
1668 
1669 	STORE_RT_REG_AGG(p_hwfn, SRC_REG_FIRSTFREE_RT_OFFSET,
1670 			 p_hwfn->p_cxt_mngr->first_free);
1671 	STORE_RT_REG_AGG(p_hwfn, SRC_REG_LASTFREE_RT_OFFSET,
1672 			 p_hwfn->p_cxt_mngr->last_free);
1673 	DP_VERBOSE(p_hwfn, ECORE_MSG_ILT,
1674 		   "Configured SEARCHER for 0x%08x connections\n",
1675 		   conn_num);
1676 }
1677 
1678 /* Timers PF */
1679 #define TM_CFG_NUM_IDS_SHIFT		0
1680 #define TM_CFG_NUM_IDS_MASK		0xFFFFULL
1681 #define TM_CFG_PRE_SCAN_OFFSET_SHIFT	16
1682 #define TM_CFG_PRE_SCAN_OFFSET_MASK	0x1FFULL
1683 #define TM_CFG_PARENT_PF_SHIFT		25
1684 #define TM_CFG_PARENT_PF_MASK		0x7ULL
1685 
1686 #define TM_CFG_CID_PRE_SCAN_ROWS_SHIFT	30
1687 #define TM_CFG_CID_PRE_SCAN_ROWS_MASK	0x1FFULL
1688 
1689 #define TM_CFG_TID_OFFSET_SHIFT		30
1690 #define TM_CFG_TID_OFFSET_MASK		0x7FFFFULL
1691 #define TM_CFG_TID_PRE_SCAN_ROWS_SHIFT	49
1692 #define TM_CFG_TID_PRE_SCAN_ROWS_MASK	0x1FFULL
1693 
1694 static void ecore_tm_init_pf(struct ecore_hwfn *p_hwfn)
1695 {
1696 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
1697 	u32 active_seg_mask = 0, tm_offset, rt_reg;
1698 	struct ecore_tm_iids tm_iids;
1699 	u64 cfg_word;
1700 	u8 i;
1701 
1702 	OSAL_MEM_ZERO(&tm_iids, sizeof(tm_iids));
1703 	ecore_cxt_tm_iids(p_mngr, &tm_iids);
1704 
1705 	/* @@@TBD No pre-scan for now */
1706 
1707 	/* Note: We assume consecutive VFs for a PF */
1708 	for (i = 0; i < p_mngr->vf_count; i++) {
1709 		cfg_word = 0;
1710 		SET_FIELD(cfg_word, TM_CFG_NUM_IDS, tm_iids.per_vf_cids);
1711 		SET_FIELD(cfg_word, TM_CFG_PRE_SCAN_OFFSET, 0);
1712 		SET_FIELD(cfg_word, TM_CFG_PARENT_PF, p_hwfn->rel_pf_id);
1713 		SET_FIELD(cfg_word, TM_CFG_CID_PRE_SCAN_ROWS, 0); /* scan all */
1714 
1715 		rt_reg = TM_REG_CONFIG_CONN_MEM_RT_OFFSET +
1716 		    (sizeof(cfg_word) / sizeof(u32)) *
1717 		    (p_hwfn->p_dev->p_iov_info->first_vf_in_pf + i);
1718 		STORE_RT_REG_AGG(p_hwfn, rt_reg, cfg_word);
1719 	}
1720 
1721 	cfg_word = 0;
1722 	SET_FIELD(cfg_word, TM_CFG_NUM_IDS, tm_iids.pf_cids);
1723 	SET_FIELD(cfg_word, TM_CFG_PRE_SCAN_OFFSET, 0);
1724 	SET_FIELD(cfg_word, TM_CFG_PARENT_PF, 0);	/* n/a for PF */
1725 	SET_FIELD(cfg_word, TM_CFG_CID_PRE_SCAN_ROWS, 0); /* scan all   */
1726 
1727 	rt_reg = TM_REG_CONFIG_CONN_MEM_RT_OFFSET +
1728 	    (sizeof(cfg_word) / sizeof(u32)) *
1729 	    (NUM_OF_VFS(p_hwfn->p_dev) + p_hwfn->rel_pf_id);
1730 	STORE_RT_REG_AGG(p_hwfn, rt_reg, cfg_word);
1731 
1732 	/* enale scan */
1733 	STORE_RT_REG(p_hwfn, TM_REG_PF_ENABLE_CONN_RT_OFFSET,
1734 		     tm_iids.pf_cids ? 0x1 : 0x0);
1735 
1736 	/* @@@TBD how to enable the scan for the VFs */
1737 
1738 	tm_offset = tm_iids.per_vf_cids;
1739 
1740 	/* Note: We assume consecutive VFs for a PF */
1741 	for (i = 0; i < p_mngr->vf_count; i++) {
1742 		cfg_word = 0;
1743 		SET_FIELD(cfg_word, TM_CFG_NUM_IDS, tm_iids.per_vf_tids);
1744 		SET_FIELD(cfg_word, TM_CFG_PRE_SCAN_OFFSET, 0);
1745 		SET_FIELD(cfg_word, TM_CFG_PARENT_PF, p_hwfn->rel_pf_id);
1746 		SET_FIELD(cfg_word, TM_CFG_TID_OFFSET, tm_offset);
1747 		SET_FIELD(cfg_word, TM_CFG_TID_PRE_SCAN_ROWS, (u64)0);
1748 
1749 		rt_reg = TM_REG_CONFIG_TASK_MEM_RT_OFFSET +
1750 		    (sizeof(cfg_word) / sizeof(u32)) *
1751 		    (p_hwfn->p_dev->p_iov_info->first_vf_in_pf + i);
1752 
1753 		STORE_RT_REG_AGG(p_hwfn, rt_reg, cfg_word);
1754 	}
1755 
1756 	tm_offset = tm_iids.pf_cids;
1757 	for (i = 0; i < NUM_TASK_PF_SEGMENTS; i++) {
1758 		cfg_word = 0;
1759 		SET_FIELD(cfg_word, TM_CFG_NUM_IDS, tm_iids.pf_tids[i]);
1760 		SET_FIELD(cfg_word, TM_CFG_PRE_SCAN_OFFSET, 0);
1761 		SET_FIELD(cfg_word, TM_CFG_PARENT_PF, 0);
1762 		SET_FIELD(cfg_word, TM_CFG_TID_OFFSET, tm_offset);
1763 		SET_FIELD(cfg_word, TM_CFG_TID_PRE_SCAN_ROWS, (u64)0);
1764 
1765 		rt_reg = TM_REG_CONFIG_TASK_MEM_RT_OFFSET +
1766 		    (sizeof(cfg_word) / sizeof(u32)) *
1767 		    (NUM_OF_VFS(p_hwfn->p_dev) +
1768 		     p_hwfn->rel_pf_id * NUM_TASK_PF_SEGMENTS + i);
1769 
1770 		STORE_RT_REG_AGG(p_hwfn, rt_reg, cfg_word);
1771 		active_seg_mask |= (tm_iids.pf_tids[i] ? (1 << i) : 0);
1772 
1773 		tm_offset += tm_iids.pf_tids[i];
1774 	}
1775 
1776 	STORE_RT_REG(p_hwfn, TM_REG_PF_ENABLE_TASK_RT_OFFSET, active_seg_mask);
1777 
1778 	/* @@@TBD how to enable the scan for the VFs */
1779 }
1780 
1781 static void ecore_prs_init_pf(struct ecore_hwfn *p_hwfn)
1782 {
1783 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
1784 	struct ecore_conn_type_cfg *p_fcoe;
1785 	struct ecore_tid_seg *p_tid;
1786 
1787 	p_fcoe = &p_mngr->conn_cfg[PROTOCOLID_FCOE];
1788 
1789 	/* If FCoE is active set the MAX OX_ID (tid) in the Parser */
1790 	if (!p_fcoe->cid_count)
1791 		return;
1792 
1793 	p_tid = &p_fcoe->tid_seg[ECORE_CXT_FCOE_TID_SEG];
1794 	STORE_RT_REG_AGG(p_hwfn,
1795 			PRS_REG_TASK_ID_MAX_INITIATOR_PF_RT_OFFSET,
1796 			p_tid->count);
1797 }
1798 
1799 void ecore_cxt_hw_init_common(struct ecore_hwfn *p_hwfn)
1800 {
1801 	/* CDU configuration */
1802 	ecore_cdu_init_common(p_hwfn);
1803 }
1804 
1805 void ecore_cxt_hw_init_pf(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt)
1806 {
1807 	ecore_qm_init_pf(p_hwfn, p_ptt, true);
1808 	ecore_cm_init_pf(p_hwfn);
1809 	ecore_dq_init_pf(p_hwfn);
1810 	ecore_cdu_init_pf(p_hwfn);
1811 	ecore_ilt_init_pf(p_hwfn);
1812 	ecore_src_init_pf(p_hwfn);
1813 	ecore_tm_init_pf(p_hwfn);
1814 	ecore_prs_init_pf(p_hwfn);
1815 }
1816 
1817 enum _ecore_status_t _ecore_cxt_acquire_cid(struct ecore_hwfn *p_hwfn,
1818 					    enum protocol_type type,
1819 					    u32 *p_cid, u8 vfid)
1820 {
1821 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
1822 	struct ecore_cid_acquired_map *p_map;
1823 	u32 rel_cid;
1824 
1825 	if (type >= MAX_CONN_TYPES) {
1826 		DP_NOTICE(p_hwfn, true, "Invalid protocol type %d", type);
1827 		return ECORE_INVAL;
1828 	}
1829 
1830 	if (vfid >= COMMON_MAX_NUM_VFS && vfid != ECORE_CXT_PF_CID) {
1831 		DP_NOTICE(p_hwfn, true, "VF [%02x] is out of range\n", vfid);
1832 		return ECORE_INVAL;
1833 	}
1834 
1835 	/* Determine the right map to take this CID from */
1836 	if (vfid == ECORE_CXT_PF_CID)
1837 		p_map = &p_mngr->acquired[type];
1838 	else
1839 		p_map = &p_mngr->acquired_vf[type][vfid];
1840 
1841 	if (p_map->cid_map == OSAL_NULL) {
1842 		DP_NOTICE(p_hwfn, true, "Invalid protocol type %d", type);
1843 		return ECORE_INVAL;
1844 	}
1845 
1846 	rel_cid = OSAL_FIND_FIRST_ZERO_BIT(p_map->cid_map,
1847 					   p_map->max_count);
1848 
1849 	if (rel_cid >= p_map->max_count) {
1850 		DP_NOTICE(p_hwfn, false, "no CID available for protocol %d\n",
1851 			  type);
1852 		return ECORE_NORESOURCES;
1853 	}
1854 
1855 	OSAL_SET_BIT(rel_cid, p_map->cid_map);
1856 
1857 	*p_cid = rel_cid + p_map->start_cid;
1858 
1859 	DP_VERBOSE(p_hwfn, ECORE_MSG_CXT,
1860 		   "Acquired cid 0x%08x [rel. %08x] vfid %02x type %d\n",
1861 		   *p_cid, rel_cid, vfid, type);
1862 
1863 	return ECORE_SUCCESS;
1864 }
1865 
1866 enum _ecore_status_t ecore_cxt_acquire_cid(struct ecore_hwfn *p_hwfn,
1867 					   enum protocol_type type,
1868 					   u32 *p_cid)
1869 {
1870 	return _ecore_cxt_acquire_cid(p_hwfn, type, p_cid, ECORE_CXT_PF_CID);
1871 }
1872 
1873 static bool ecore_cxt_test_cid_acquired(struct ecore_hwfn *p_hwfn,
1874 					u32 cid, u8 vfid,
1875 					enum protocol_type *p_type,
1876 					struct ecore_cid_acquired_map **pp_map)
1877 {
1878 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
1879 	u32 rel_cid;
1880 
1881 	/* Iterate over protocols and find matching cid range */
1882 	for (*p_type = 0; *p_type < MAX_CONN_TYPES; (*p_type)++) {
1883 		if (vfid == ECORE_CXT_PF_CID)
1884 			*pp_map = &p_mngr->acquired[*p_type];
1885 		else
1886 			*pp_map = &p_mngr->acquired_vf[*p_type][vfid];
1887 
1888 		if (!((*pp_map)->cid_map))
1889 			continue;
1890 		if (cid >= (*pp_map)->start_cid &&
1891 		    cid < (*pp_map)->start_cid + (*pp_map)->max_count) {
1892 			break;
1893 		}
1894 	}
1895 	if (*p_type == MAX_CONN_TYPES) {
1896 		DP_NOTICE(p_hwfn, true, "Invalid CID %d vfid %02x", cid, vfid);
1897 		goto fail;
1898 	}
1899 
1900 	rel_cid = cid - (*pp_map)->start_cid;
1901 	if (!OSAL_TEST_BIT(rel_cid, (*pp_map)->cid_map)) {
1902 		DP_NOTICE(p_hwfn, true,
1903 			  "CID %d [vifd %02x] not acquired", cid, vfid);
1904 		goto fail;
1905 	}
1906 
1907 	return true;
1908 fail:
1909 	*p_type = MAX_CONN_TYPES;
1910 	*pp_map = OSAL_NULL;
1911 	return false;
1912 }
1913 
1914 void _ecore_cxt_release_cid(struct ecore_hwfn *p_hwfn, u32 cid, u8 vfid)
1915 {
1916 	struct ecore_cid_acquired_map *p_map = OSAL_NULL;
1917 	enum protocol_type type;
1918 	bool b_acquired;
1919 	u32 rel_cid;
1920 
1921 	if (vfid != ECORE_CXT_PF_CID && vfid > COMMON_MAX_NUM_VFS) {
1922 		DP_NOTICE(p_hwfn, true,
1923 			  "Trying to return incorrect CID belonging to VF %02x\n",
1924 			  vfid);
1925 		return;
1926 	}
1927 
1928 	/* Test acquired and find matching per-protocol map */
1929 	b_acquired = ecore_cxt_test_cid_acquired(p_hwfn, cid, vfid,
1930 						 &type, &p_map);
1931 
1932 	if (!b_acquired)
1933 		return;
1934 
1935 	rel_cid = cid - p_map->start_cid;
1936 	OSAL_CLEAR_BIT(rel_cid, p_map->cid_map);
1937 
1938 	DP_VERBOSE(p_hwfn, ECORE_MSG_CXT,
1939 		   "Released CID 0x%08x [rel. %08x] vfid %02x type %d\n",
1940 		   cid, rel_cid, vfid, type);
1941 }
1942 
1943 void ecore_cxt_release_cid(struct ecore_hwfn *p_hwfn, u32 cid)
1944 {
1945 	_ecore_cxt_release_cid(p_hwfn, cid, ECORE_CXT_PF_CID);
1946 }
1947 
1948 enum _ecore_status_t ecore_cxt_get_cid_info(struct ecore_hwfn *p_hwfn,
1949 					    struct ecore_cxt_info *p_info)
1950 {
1951 	struct ecore_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
1952 	struct ecore_cid_acquired_map *p_map = OSAL_NULL;
1953 	u32 conn_cxt_size, hw_p_size, cxts_per_p, line;
1954 	enum protocol_type type;
1955 	bool b_acquired;
1956 
1957 	/* Test acquired and find matching per-protocol map */
1958 	b_acquired = ecore_cxt_test_cid_acquired(p_hwfn, p_info->iid,
1959 						 ECORE_CXT_PF_CID,
1960 						 &type, &p_map);
1961 
1962 	if (!b_acquired)
1963 		return ECORE_INVAL;
1964 
1965 	/* set the protocl type */
1966 	p_info->type = type;
1967 
1968 	/* compute context virtual pointer */
1969 	hw_p_size = p_hwfn->p_cxt_mngr->clients[ILT_CLI_CDUC].p_size.val;
1970 
1971 	conn_cxt_size = CONN_CXT_SIZE(p_hwfn);
1972 	cxts_per_p = ILT_PAGE_IN_BYTES(hw_p_size) / conn_cxt_size;
1973 	line = p_info->iid / cxts_per_p;
1974 
1975 	/* Make sure context is allocated (dynamic allocation) */
1976 	if (!p_mngr->ilt_shadow[line].p_virt)
1977 		return ECORE_INVAL;
1978 
1979 	p_info->p_cxt = (u8 *)p_mngr->ilt_shadow[line].p_virt +
1980 	    p_info->iid % cxts_per_p * conn_cxt_size;
1981 
1982 	DP_VERBOSE(p_hwfn, (ECORE_MSG_ILT | ECORE_MSG_CXT),
1983 		"Accessing ILT shadow[%d]: CXT pointer is at %p (for iid %d)\n",
1984 		(p_info->iid / cxts_per_p), p_info->p_cxt, p_info->iid);
1985 
1986 	return ECORE_SUCCESS;
1987 }
1988 
1989 enum _ecore_status_t ecore_cxt_set_pf_params(struct ecore_hwfn *p_hwfn)
1990 {
1991 	/* Set the number of required CORE connections */
1992 	u32 core_cids = 1;	/* SPQ */
1993 
1994 	ecore_cxt_set_proto_cid_count(p_hwfn, PROTOCOLID_CORE, core_cids, 0);
1995 
1996 	switch (p_hwfn->hw_info.personality) {
1997 	case ECORE_PCI_ETH:
1998 		{
1999 		u32 count = 0;
2000 
2001 		struct ecore_eth_pf_params *p_params =
2002 			    &p_hwfn->pf_params.eth_pf_params;
2003 
2004 		if (!p_params->num_vf_cons)
2005 			p_params->num_vf_cons = ETH_PF_PARAMS_VF_CONS_DEFAULT;
2006 		ecore_cxt_set_proto_cid_count(p_hwfn, PROTOCOLID_ETH,
2007 					      p_params->num_cons,
2008 					      p_params->num_vf_cons);
2009 
2010 		count = p_params->num_arfs_filters;
2011 
2012 		if (!OSAL_TEST_BIT(ECORE_MF_DISABLE_ARFS,
2013 				   &p_hwfn->p_dev->mf_bits))
2014 			p_hwfn->p_cxt_mngr->arfs_count = count;
2015 
2016 		break;
2017 		}
2018 	default:
2019 		return ECORE_INVAL;
2020 	}
2021 
2022 	return ECORE_SUCCESS;
2023 }
2024 
2025 /* This function is very RoCE oriented, if another protocol in the future
2026  * will want this feature we'll need to modify the function to be more generic
2027  */
2028 enum _ecore_status_t
2029 ecore_cxt_dynamic_ilt_alloc(struct ecore_hwfn *p_hwfn,
2030 			    enum ecore_cxt_elem_type elem_type,
2031 			    u32 iid)
2032 {
2033 	u32 reg_offset, shadow_line, elem_size, hw_p_size, elems_per_p, line;
2034 	struct ecore_ilt_client_cfg *p_cli;
2035 	struct ecore_ilt_cli_blk *p_blk;
2036 	struct ecore_ptt *p_ptt;
2037 	dma_addr_t p_phys;
2038 	u64 ilt_hw_entry;
2039 	void *p_virt;
2040 	enum _ecore_status_t rc = ECORE_SUCCESS;
2041 
2042 	switch (elem_type) {
2043 	case ECORE_ELEM_CXT:
2044 		p_cli = &p_hwfn->p_cxt_mngr->clients[ILT_CLI_CDUC];
2045 		elem_size = CONN_CXT_SIZE(p_hwfn);
2046 		p_blk = &p_cli->pf_blks[CDUC_BLK];
2047 		break;
2048 	case ECORE_ELEM_SRQ:
2049 		p_cli = &p_hwfn->p_cxt_mngr->clients[ILT_CLI_TSDM];
2050 		elem_size = SRQ_CXT_SIZE;
2051 		p_blk = &p_cli->pf_blks[SRQ_BLK];
2052 		break;
2053 	case ECORE_ELEM_TASK:
2054 		p_cli = &p_hwfn->p_cxt_mngr->clients[ILT_CLI_CDUT];
2055 		elem_size = TYPE1_TASK_CXT_SIZE(p_hwfn);
2056 		p_blk = &p_cli->pf_blks[CDUT_SEG_BLK(ECORE_CXT_ROCE_TID_SEG)];
2057 		break;
2058 	default:
2059 		DP_NOTICE(p_hwfn, false,
2060 			  "ECORE_INVALID elem type = %d", elem_type);
2061 		return ECORE_INVAL;
2062 	}
2063 
2064 	/* Calculate line in ilt */
2065 	hw_p_size = p_cli->p_size.val;
2066 	elems_per_p = ILT_PAGE_IN_BYTES(hw_p_size) / elem_size;
2067 	line = p_blk->start_line + (iid / elems_per_p);
2068 	shadow_line = line - p_hwfn->p_cxt_mngr->pf_start_line;
2069 
2070 	/* If line is already allocated, do nothing, otherwise allocate it and
2071 	 * write it to the PSWRQ2 registers.
2072 	 * This section can be run in parallel from different contexts and thus
2073 	 * a mutex protection is needed.
2074 	 */
2075 
2076 	OSAL_MUTEX_ACQUIRE(&p_hwfn->p_cxt_mngr->mutex);
2077 
2078 	if (p_hwfn->p_cxt_mngr->ilt_shadow[shadow_line].p_virt)
2079 		goto out0;
2080 
2081 	p_ptt = ecore_ptt_acquire(p_hwfn);
2082 	if (!p_ptt) {
2083 		DP_NOTICE(p_hwfn, false,
2084 			  "ECORE_TIME_OUT on ptt acquire - dynamic allocation");
2085 		rc = ECORE_TIMEOUT;
2086 		goto out0;
2087 	}
2088 
2089 	p_virt = OSAL_DMA_ALLOC_COHERENT(p_hwfn->p_dev,
2090 					 &p_phys,
2091 					 p_blk->real_size_in_page);
2092 	if (!p_virt) {
2093 		rc = ECORE_NOMEM;
2094 		goto out1;
2095 	}
2096 	OSAL_MEM_ZERO(p_virt, p_blk->real_size_in_page);
2097 
2098 	p_hwfn->p_cxt_mngr->ilt_shadow[shadow_line].p_virt = p_virt;
2099 	p_hwfn->p_cxt_mngr->ilt_shadow[shadow_line].p_phys = p_phys;
2100 	p_hwfn->p_cxt_mngr->ilt_shadow[shadow_line].size =
2101 		p_blk->real_size_in_page;
2102 
2103 	/* compute absolute offset */
2104 	reg_offset = PSWRQ2_REG_ILT_MEMORY +
2105 		     (line * ILT_REG_SIZE_IN_BYTES * ILT_ENTRY_IN_REGS);
2106 
2107 	ilt_hw_entry = 0;
2108 	SET_FIELD(ilt_hw_entry, ILT_ENTRY_VALID, 1ULL);
2109 	SET_FIELD(ilt_hw_entry,
2110 		  ILT_ENTRY_PHY_ADDR,
2111 		  (p_hwfn->p_cxt_mngr->ilt_shadow[shadow_line].p_phys >> 12));
2112 
2113 /* Write via DMAE since the PSWRQ2_REG_ILT_MEMORY line is a wide-bus */
2114 
2115 	ecore_dmae_host2grc(p_hwfn, p_ptt, (u64)(osal_uintptr_t)&ilt_hw_entry,
2116 			    reg_offset, sizeof(ilt_hw_entry) / sizeof(u32),
2117 			    OSAL_NULL /* default parameters */);
2118 
2119 	if (elem_type == ECORE_ELEM_CXT) {
2120 		u32 last_cid_allocated = (1 + (iid / elems_per_p)) *
2121 					 elems_per_p;
2122 
2123 		/* Update the relevant register in the parser */
2124 		ecore_wr(p_hwfn, p_ptt, PRS_REG_ROCE_DEST_QP_MAX_PF,
2125 			 last_cid_allocated - 1);
2126 
2127 		if (!p_hwfn->b_rdma_enabled_in_prs) {
2128 			/* Enable RoCE search */
2129 			ecore_wr(p_hwfn, p_ptt, p_hwfn->rdma_prs_search_reg, 1);
2130 			p_hwfn->b_rdma_enabled_in_prs = true;
2131 		}
2132 	}
2133 
2134 out1:
2135 	ecore_ptt_release(p_hwfn, p_ptt);
2136 out0:
2137 	OSAL_MUTEX_RELEASE(&p_hwfn->p_cxt_mngr->mutex);
2138 
2139 	return rc;
2140 }
2141 
2142 /* This function is very RoCE oriented, if another protocol in the future
2143  * will want this feature we'll need to modify the function to be more generic
2144  */
2145 static enum _ecore_status_t
2146 ecore_cxt_free_ilt_range(struct ecore_hwfn *p_hwfn,
2147 			 enum ecore_cxt_elem_type elem_type,
2148 			 u32 start_iid, u32 count)
2149 {
2150 	u32 start_line, end_line, shadow_start_line, shadow_end_line;
2151 	u32 reg_offset, elem_size, hw_p_size, elems_per_p;
2152 	struct ecore_ilt_client_cfg *p_cli;
2153 	struct ecore_ilt_cli_blk *p_blk;
2154 	u32 end_iid = start_iid + count;
2155 	struct ecore_ptt *p_ptt;
2156 	u64 ilt_hw_entry = 0;
2157 	u32 i;
2158 
2159 	switch (elem_type) {
2160 	case ECORE_ELEM_CXT:
2161 		p_cli = &p_hwfn->p_cxt_mngr->clients[ILT_CLI_CDUC];
2162 		elem_size = CONN_CXT_SIZE(p_hwfn);
2163 		p_blk = &p_cli->pf_blks[CDUC_BLK];
2164 		break;
2165 	case ECORE_ELEM_SRQ:
2166 		p_cli = &p_hwfn->p_cxt_mngr->clients[ILT_CLI_TSDM];
2167 		elem_size = SRQ_CXT_SIZE;
2168 		p_blk = &p_cli->pf_blks[SRQ_BLK];
2169 		break;
2170 	case ECORE_ELEM_TASK:
2171 		p_cli = &p_hwfn->p_cxt_mngr->clients[ILT_CLI_CDUT];
2172 		elem_size = TYPE1_TASK_CXT_SIZE(p_hwfn);
2173 		p_blk = &p_cli->pf_blks[CDUT_SEG_BLK(ECORE_CXT_ROCE_TID_SEG)];
2174 		break;
2175 	default:
2176 		DP_NOTICE(p_hwfn, false,
2177 			  "ECORE_INVALID elem type = %d", elem_type);
2178 		return ECORE_INVAL;
2179 	}
2180 
2181 	/* Calculate line in ilt */
2182 	hw_p_size = p_cli->p_size.val;
2183 	elems_per_p = ILT_PAGE_IN_BYTES(hw_p_size) / elem_size;
2184 	start_line = p_blk->start_line + (start_iid / elems_per_p);
2185 	end_line = p_blk->start_line + (end_iid / elems_per_p);
2186 	if (((end_iid + 1) / elems_per_p) != (end_iid / elems_per_p))
2187 		end_line--;
2188 
2189 	shadow_start_line = start_line - p_hwfn->p_cxt_mngr->pf_start_line;
2190 	shadow_end_line = end_line - p_hwfn->p_cxt_mngr->pf_start_line;
2191 
2192 	p_ptt = ecore_ptt_acquire(p_hwfn);
2193 	if (!p_ptt) {
2194 		DP_NOTICE(p_hwfn, false,
2195 			  "ECORE_TIME_OUT on ptt acquire - dynamic allocation");
2196 		return ECORE_TIMEOUT;
2197 	}
2198 
2199 	for (i = shadow_start_line; i < shadow_end_line; i++) {
2200 		if (!p_hwfn->p_cxt_mngr->ilt_shadow[i].p_virt)
2201 			continue;
2202 
2203 		OSAL_DMA_FREE_COHERENT(p_hwfn->p_dev,
2204 				       p_hwfn->p_cxt_mngr->ilt_shadow[i].p_virt,
2205 				       p_hwfn->p_cxt_mngr->ilt_shadow[i].p_phys,
2206 				       p_hwfn->p_cxt_mngr->ilt_shadow[i].size);
2207 
2208 		p_hwfn->p_cxt_mngr->ilt_shadow[i].p_virt = OSAL_NULL;
2209 		p_hwfn->p_cxt_mngr->ilt_shadow[i].p_phys = 0;
2210 		p_hwfn->p_cxt_mngr->ilt_shadow[i].size = 0;
2211 
2212 		/* compute absolute offset */
2213 		reg_offset = PSWRQ2_REG_ILT_MEMORY +
2214 		    ((start_line++) * ILT_REG_SIZE_IN_BYTES *
2215 		     ILT_ENTRY_IN_REGS);
2216 
2217 		/* Write via DMAE since the PSWRQ2_REG_ILT_MEMORY line is a
2218 		 * wide-bus.
2219 		 */
2220 		ecore_dmae_host2grc(p_hwfn, p_ptt,
2221 				    (u64)(osal_uintptr_t)&ilt_hw_entry,
2222 				    reg_offset,
2223 				    sizeof(ilt_hw_entry) / sizeof(u32),
2224 				    OSAL_NULL /* default parameters */);
2225 	}
2226 
2227 	ecore_ptt_release(p_hwfn, p_ptt);
2228 
2229 	return ECORE_SUCCESS;
2230 }
2231