1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (c) 2016 - 2018 Cavium Inc.
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"
15 #include "ecore_init_ops.h"
16 #include "ecore_init_fw_funcs.h"
17 #include "ecore_cxt.h"
19 #include "ecore_dev_api.h"
20 #include "ecore_sriov.h"
21 #include "ecore_mcp.h"
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
29 /* Doorbell-Queue constants */
30 #define DQ_RANGE_SHIFT 4
31 #define DQ_RANGE_ALIGN (1 << DQ_RANGE_SHIFT)
33 /* Searcher constants */
34 #define SRC_MIN_NUM_ELEMS 256
37 #define RGFS_MIN_NUM_ELEMS 256
38 #define TGFS_MIN_NUM_ELEMS 256
40 /* Timers constants */
42 #define TM_ALIGN (1 << TM_SHIFT)
43 #define TM_ELEM_SIZE 4
46 #define ILT_DEFAULT_HW_P_SIZE 4
48 #define ILT_PAGE_IN_BYTES(hw_p_size) (1U << ((hw_p_size) + 12))
49 #define ILT_CFG_REG(cli, reg) PSWRQ2_REG_##cli##_##reg##_RT_OFFSET
51 /* ILT entry structure */
52 #define ILT_ENTRY_PHY_ADDR_MASK 0x000FFFFFFFFFFFULL
53 #define ILT_ENTRY_PHY_ADDR_SHIFT 0
54 #define ILT_ENTRY_VALID_MASK 0x1ULL
55 #define ILT_ENTRY_VALID_SHIFT 52
56 #define ILT_ENTRY_IN_REGS 2
57 #define ILT_REG_SIZE_IN_BYTES 4
59 /* connection context union */
61 struct core_conn_context core_ctx
;
62 struct eth_conn_context eth_ctx
;
65 /* TYPE-0 task context - iSCSI, FCOE */
66 union type0_task_context
{
69 /* TYPE-1 task context - ROCE */
70 union type1_task_context
{
71 struct regpair reserved
; /* @DPDK */
79 #define CDUT_SEG_ALIGNMET 3 /* in 4k chunks */
80 #define CDUT_SEG_ALIGNMET_IN_BYTES (1 << (CDUT_SEG_ALIGNMET + 12))
82 #define CONN_CXT_SIZE(p_hwfn) \
83 ALIGNED_TYPE_SIZE(union conn_context, p_hwfn)
85 #define SRQ_CXT_SIZE (sizeof(struct regpair) * 8) /* @DPDK */
87 #define TYPE0_TASK_CXT_SIZE(p_hwfn) \
88 ALIGNED_TYPE_SIZE(union type0_task_context, p_hwfn)
90 /* Alignment is inherent to the type1_task_context structure */
91 #define TYPE1_TASK_CXT_SIZE(p_hwfn) sizeof(union type1_task_context)
93 /* PF per protocl configuration object */
94 #define TASK_SEGMENTS (NUM_TASK_PF_SEGMENTS + NUM_TASK_VF_SEGMENTS)
95 #define TASK_SEGMENT_VF (NUM_TASK_PF_SEGMENTS)
97 struct ecore_tid_seg
{
103 struct ecore_conn_type_cfg
{
106 struct ecore_tid_seg tid_seg
[TASK_SEGMENTS
];
109 /* ILT Client configuration,
110 * Per connection type (protocol) resources (cids, tis, vf cids etc.)
111 * 1 - for connection context (CDUC) and for each task context we need two
112 * values, for regular task context and for force load memory
114 #define ILT_CLI_PF_BLOCKS (1 + NUM_TASK_PF_SEGMENTS * 2)
115 #define ILT_CLI_VF_BLOCKS (1 + NUM_TASK_VF_SEGMENTS * 2)
118 #define CDUT_SEG_BLK(n) (1 + (u8)(n))
119 #define CDUT_FL_SEG_BLK(n, X) (1 + (n) + NUM_TASK_##X##_SEGMENTS)
121 struct ilt_cfg_pair
{
126 struct ecore_ilt_cli_blk
{
127 u32 total_size
; /* 0 means not active */
128 u32 real_size_in_page
;
130 u32 dynamic_line_offset
;
131 u32 dynamic_line_cnt
;
134 struct ecore_ilt_client_cfg
{
138 struct ilt_cfg_pair first
;
139 struct ilt_cfg_pair last
;
140 struct ilt_cfg_pair p_size
;
142 /* ILT client blocks for PF */
143 struct ecore_ilt_cli_blk pf_blks
[ILT_CLI_PF_BLOCKS
];
146 /* ILT client blocks for VFs */
147 struct ecore_ilt_cli_blk vf_blks
[ILT_CLI_VF_BLOCKS
];
151 #define MAP_WORD_SIZE sizeof(unsigned long)
152 #define BITS_PER_MAP_WORD (MAP_WORD_SIZE * 8)
154 struct ecore_cid_acquired_map
{
157 unsigned long *cid_map
;
160 struct ecore_src_t2
{
161 struct phys_mem_desc
*dma_mem
;
167 struct ecore_cxt_mngr
{
168 /* Per protocl configuration */
169 struct ecore_conn_type_cfg conn_cfg
[MAX_CONN_TYPES
];
171 /* computed ILT structure */
172 struct ecore_ilt_client_cfg clients
[ILT_CLI_MAX
];
174 /* Task type sizes */
175 u32 task_type_size
[NUM_TASK_TYPES
];
177 /* total number of VFs for this hwfn -
178 * ALL VFs are symmetric in terms of HW resources
183 struct ecore_cid_acquired_map acquired
[MAX_CONN_TYPES
];
184 struct ecore_cid_acquired_map
*acquired_vf
[MAX_CONN_TYPES
];
186 /* ILT shadow table */
187 struct phys_mem_desc
*ilt_shadow
;
190 /* Mutex for a dynamic ILT allocation */
194 struct ecore_src_t2 src_t2
;
196 /* The infrastructure originally was very generic and context/task
197 * oriented - per connection-type we would set how many of those
198 * are needed, and later when determining how much memory we're
199 * needing for a given block we'd iterate over all the relevant
201 * But since then we've had some additional resources, some of which
202 * require memory which is indepent of the general context/task
203 * scheme. We add those here explicitly per-feature.
206 /* total number of SRQ's for this hwfn */
209 /* Maximal number of L2 steering filters */
212 /* TODO - VF arfs filters ? */
215 static OSAL_INLINE
bool tm_cid_proto(enum protocol_type type
)
217 return type
== PROTOCOLID_TOE
;
220 static bool tm_tid_proto(enum protocol_type type
)
222 return type
== PROTOCOLID_FCOE
;
225 /* counts the iids for the CDU/CDUC ILT client configuration */
226 struct ecore_cdu_iids
{
231 static void ecore_cxt_cdu_iids(struct ecore_cxt_mngr
*p_mngr
,
232 struct ecore_cdu_iids
*iids
)
236 for (type
= 0; type
< MAX_CONN_TYPES
; type
++) {
237 iids
->pf_cids
+= p_mngr
->conn_cfg
[type
].cid_count
;
238 iids
->per_vf_cids
+= p_mngr
->conn_cfg
[type
].cids_per_vf
;
242 /* counts the iids for the Searcher block configuration */
243 struct ecore_src_iids
{
248 static void ecore_cxt_src_iids(struct ecore_cxt_mngr
*p_mngr
,
249 struct ecore_src_iids
*iids
)
253 for (i
= 0; i
< MAX_CONN_TYPES
; i
++) {
254 iids
->pf_cids
+= p_mngr
->conn_cfg
[i
].cid_count
;
255 iids
->per_vf_cids
+= p_mngr
->conn_cfg
[i
].cids_per_vf
;
258 /* Add L2 filtering filters in addition */
259 iids
->pf_cids
+= p_mngr
->arfs_count
;
262 /* counts the iids for the Timers block configuration */
263 struct ecore_tm_iids
{
265 u32 pf_tids
[NUM_TASK_PF_SEGMENTS
]; /* per segment */
271 static void ecore_cxt_tm_iids(struct ecore_hwfn
*p_hwfn
,
272 struct ecore_cxt_mngr
*p_mngr
,
273 struct ecore_tm_iids
*iids
)
275 struct ecore_conn_type_cfg
*p_cfg
;
276 bool tm_vf_required
= false;
277 bool tm_required
= false;
280 for (i
= 0; i
< MAX_CONN_TYPES
; i
++) {
281 p_cfg
= &p_mngr
->conn_cfg
[i
];
283 if (tm_cid_proto(i
) || tm_required
) {
284 if (p_cfg
->cid_count
)
287 iids
->pf_cids
+= p_cfg
->cid_count
;
290 if (tm_cid_proto(i
) || tm_vf_required
) {
291 if (p_cfg
->cids_per_vf
)
292 tm_vf_required
= true;
296 if (tm_tid_proto(i
)) {
297 struct ecore_tid_seg
*segs
= p_cfg
->tid_seg
;
299 /* for each segment there is at most one
300 * protocol for which count is not 0.
302 for (j
= 0; j
< NUM_TASK_PF_SEGMENTS
; j
++)
303 iids
->pf_tids
[j
] += segs
[j
].count
;
305 /* The last array elelment is for the VFs. As for PF
306 * segments there can be only one protocol for
307 * which this value is not 0.
309 iids
->per_vf_tids
+= segs
[NUM_TASK_PF_SEGMENTS
].count
;
313 iids
->pf_cids
= ROUNDUP(iids
->pf_cids
, TM_ALIGN
);
314 iids
->per_vf_cids
= ROUNDUP(iids
->per_vf_cids
, TM_ALIGN
);
315 iids
->per_vf_tids
= ROUNDUP(iids
->per_vf_tids
, TM_ALIGN
);
317 for (iids
->pf_tids_total
= 0, j
= 0; j
< NUM_TASK_PF_SEGMENTS
; j
++) {
318 iids
->pf_tids
[j
] = ROUNDUP(iids
->pf_tids
[j
], TM_ALIGN
);
319 iids
->pf_tids_total
+= iids
->pf_tids
[j
];
323 static void ecore_cxt_qm_iids(struct ecore_hwfn
*p_hwfn
,
324 struct ecore_qm_iids
*iids
)
326 struct ecore_cxt_mngr
*p_mngr
= p_hwfn
->p_cxt_mngr
;
327 struct ecore_tid_seg
*segs
;
328 u32 vf_cids
= 0, type
, j
;
331 for (type
= 0; type
< MAX_CONN_TYPES
; type
++) {
332 iids
->cids
+= p_mngr
->conn_cfg
[type
].cid_count
;
333 vf_cids
+= p_mngr
->conn_cfg
[type
].cids_per_vf
;
335 segs
= p_mngr
->conn_cfg
[type
].tid_seg
;
336 /* for each segment there is at most one
337 * protocol for which count is not 0.
339 for (j
= 0; j
< NUM_TASK_PF_SEGMENTS
; j
++)
340 iids
->tids
+= segs
[j
].count
;
342 /* The last array elelment is for the VFs. As for PF
343 * segments there can be only one protocol for
344 * which this value is not 0.
346 vf_tids
+= segs
[NUM_TASK_PF_SEGMENTS
].count
;
349 iids
->vf_cids
+= vf_cids
* p_mngr
->vf_count
;
350 iids
->tids
+= vf_tids
* p_mngr
->vf_count
;
352 DP_VERBOSE(p_hwfn
, ECORE_MSG_ILT
,
353 "iids: CIDS %08x vf_cids %08x tids %08x vf_tids %08x\n",
354 iids
->cids
, iids
->vf_cids
, iids
->tids
, vf_tids
);
357 static struct ecore_tid_seg
*ecore_cxt_tid_seg_info(struct ecore_hwfn
*p_hwfn
,
360 struct ecore_cxt_mngr
*p_cfg
= p_hwfn
->p_cxt_mngr
;
363 /* Find the protocol with tid count > 0 for this segment.
364 * Note: there can only be one and this is already validated.
366 for (i
= 0; i
< MAX_CONN_TYPES
; i
++) {
367 if (p_cfg
->conn_cfg
[i
].tid_seg
[seg
].count
)
368 return &p_cfg
->conn_cfg
[i
].tid_seg
[seg
];
373 static void ecore_cxt_set_srq_count(struct ecore_hwfn
*p_hwfn
, u32 num_srqs
)
375 struct ecore_cxt_mngr
*p_mgr
= p_hwfn
->p_cxt_mngr
;
377 p_mgr
->srq_count
= num_srqs
;
380 u32
ecore_cxt_get_srq_count(struct ecore_hwfn
*p_hwfn
)
382 struct ecore_cxt_mngr
*p_mgr
= p_hwfn
->p_cxt_mngr
;
384 return p_mgr
->srq_count
;
387 /* set the iids (cid/tid) count per protocol */
388 static void ecore_cxt_set_proto_cid_count(struct ecore_hwfn
*p_hwfn
,
389 enum protocol_type type
,
390 u32 cid_count
, u32 vf_cid_cnt
)
392 struct ecore_cxt_mngr
*p_mgr
= p_hwfn
->p_cxt_mngr
;
393 struct ecore_conn_type_cfg
*p_conn
= &p_mgr
->conn_cfg
[type
];
395 p_conn
->cid_count
= ROUNDUP(cid_count
, DQ_RANGE_ALIGN
);
396 p_conn
->cids_per_vf
= ROUNDUP(vf_cid_cnt
, DQ_RANGE_ALIGN
);
399 u32
ecore_cxt_get_proto_cid_count(struct ecore_hwfn
*p_hwfn
,
400 enum protocol_type type
, u32
*vf_cid
)
403 *vf_cid
= p_hwfn
->p_cxt_mngr
->conn_cfg
[type
].cids_per_vf
;
405 return p_hwfn
->p_cxt_mngr
->conn_cfg
[type
].cid_count
;
408 u32
ecore_cxt_get_proto_cid_start(struct ecore_hwfn
*p_hwfn
,
409 enum protocol_type type
)
411 return p_hwfn
->p_cxt_mngr
->acquired
[type
].start_cid
;
414 u32
ecore_cxt_get_proto_tid_count(struct ecore_hwfn
*p_hwfn
,
415 enum protocol_type type
)
420 for (i
= 0; i
< TASK_SEGMENTS
; i
++)
421 cnt
+= p_hwfn
->p_cxt_mngr
->conn_cfg
[type
].tid_seg
[i
].count
;
426 static OSAL_INLINE
void
427 ecore_cxt_set_proto_tid_count(struct ecore_hwfn
*p_hwfn
,
428 enum protocol_type proto
,
429 u8 seg
, u8 seg_type
, u32 count
, bool has_fl
)
431 struct ecore_cxt_mngr
*p_mngr
= p_hwfn
->p_cxt_mngr
;
432 struct ecore_tid_seg
*p_seg
= &p_mngr
->conn_cfg
[proto
].tid_seg
[seg
];
434 p_seg
->count
= count
;
435 p_seg
->has_fl_mem
= has_fl
;
436 p_seg
->type
= seg_type
;
439 /* the *p_line parameter must be either 0 for the first invocation or the
440 * value returned in the previous invocation.
442 static void ecore_ilt_cli_blk_fill(struct ecore_ilt_client_cfg
*p_cli
,
443 struct ecore_ilt_cli_blk
*p_blk
,
445 u32 total_size
, u32 elem_size
)
447 u32 ilt_size
= ILT_PAGE_IN_BYTES(p_cli
->p_size
.val
);
449 /* verify that it's called once for each block */
450 if (p_blk
->total_size
)
453 p_blk
->total_size
= total_size
;
454 p_blk
->real_size_in_page
= 0;
456 p_blk
->real_size_in_page
= (ilt_size
/ elem_size
) * elem_size
;
457 p_blk
->start_line
= start_line
;
460 static void ecore_ilt_cli_adv_line(struct ecore_hwfn
*p_hwfn
,
461 struct ecore_ilt_client_cfg
*p_cli
,
462 struct ecore_ilt_cli_blk
*p_blk
,
463 u32
*p_line
, enum ilt_clients client_id
)
465 if (!p_blk
->total_size
)
469 p_cli
->first
.val
= *p_line
;
471 p_cli
->active
= true;
472 *p_line
+= DIV_ROUND_UP(p_blk
->total_size
, p_blk
->real_size_in_page
);
473 p_cli
->last
.val
= *p_line
- 1;
475 DP_VERBOSE(p_hwfn
, ECORE_MSG_ILT
,
476 "ILT[Client %d] - Lines: [%08x - %08x]. Block - Size %08x"
477 " [Real %08x] Start line %d\n",
478 client_id
, p_cli
->first
.val
, p_cli
->last
.val
,
479 p_blk
->total_size
, p_blk
->real_size_in_page
,
483 static void ecore_ilt_get_dynamic_line_range(struct ecore_hwfn
*p_hwfn
,
484 enum ilt_clients ilt_client
,
485 u32
*dynamic_line_offset
,
486 u32
*dynamic_line_cnt
)
488 struct ecore_ilt_client_cfg
*p_cli
;
489 struct ecore_conn_type_cfg
*p_cfg
;
492 /* TBD MK: ILT code should be simplified once PROTO enum is changed */
494 *dynamic_line_offset
= 0;
495 *dynamic_line_cnt
= 0;
497 if (ilt_client
== ILT_CLI_CDUC
) {
498 p_cli
= &p_hwfn
->p_cxt_mngr
->clients
[ILT_CLI_CDUC
];
499 p_cfg
= &p_hwfn
->p_cxt_mngr
->conn_cfg
[PROTOCOLID_ROCE
];
501 cxts_per_p
= ILT_PAGE_IN_BYTES(p_cli
->p_size
.val
) /
502 (u32
)CONN_CXT_SIZE(p_hwfn
);
504 *dynamic_line_cnt
= p_cfg
->cid_count
/ cxts_per_p
;
508 static struct ecore_ilt_client_cfg
*
509 ecore_cxt_set_cli(struct ecore_ilt_client_cfg
*p_cli
)
511 p_cli
->active
= false;
512 p_cli
->first
.val
= 0;
517 static struct ecore_ilt_cli_blk
*
518 ecore_cxt_set_blk(struct ecore_ilt_cli_blk
*p_blk
)
520 p_blk
->total_size
= 0;
525 ecore_cxt_src_elements(struct ecore_cxt_mngr
*p_mngr
)
527 struct ecore_src_iids src_iids
;
530 OSAL_MEM_ZERO(&src_iids
, sizeof(src_iids
));
531 ecore_cxt_src_iids(p_mngr
, &src_iids
);
533 /* Both the PF and VFs searcher connections are stored in the per PF
534 * database. Thus sum the PF searcher cids and all the VFs searcher
537 elem_num
= src_iids
.pf_cids
+
538 src_iids
.per_vf_cids
* p_mngr
->vf_count
;
542 elem_num
= OSAL_MAX_T(u32
, elem_num
, SRC_MIN_NUM_ELEMS
);
543 elem_num
= OSAL_ROUNDUP_POW_OF_TWO(elem_num
);
548 enum _ecore_status_t
ecore_cxt_cfg_ilt_compute(struct ecore_hwfn
*p_hwfn
)
550 u32 curr_line
, total
, i
, task_size
, line
, total_size
, elem_size
;
551 struct ecore_cxt_mngr
*p_mngr
= p_hwfn
->p_cxt_mngr
;
552 struct ecore_ilt_client_cfg
*p_cli
;
553 struct ecore_ilt_cli_blk
*p_blk
;
554 struct ecore_cdu_iids cdu_iids
;
555 struct ecore_qm_iids qm_iids
;
556 struct ecore_tm_iids tm_iids
;
557 struct ecore_tid_seg
*p_seg
;
559 OSAL_MEM_ZERO(&qm_iids
, sizeof(qm_iids
));
560 OSAL_MEM_ZERO(&cdu_iids
, sizeof(cdu_iids
));
561 OSAL_MEM_ZERO(&tm_iids
, sizeof(tm_iids
));
563 p_mngr
->pf_start_line
= RESC_START(p_hwfn
, ECORE_ILT
);
565 DP_VERBOSE(p_hwfn
, ECORE_MSG_ILT
,
566 "hwfn [%d] - Set context mngr starting line to be 0x%08x\n",
567 p_hwfn
->my_id
, p_hwfn
->p_cxt_mngr
->pf_start_line
);
570 p_cli
= ecore_cxt_set_cli(&p_mngr
->clients
[ILT_CLI_CDUC
]);
572 curr_line
= p_mngr
->pf_start_line
;
575 p_cli
->pf_total_lines
= 0;
577 /* get the counters for the CDUC,CDUC and QM clients */
578 ecore_cxt_cdu_iids(p_mngr
, &cdu_iids
);
580 p_blk
= ecore_cxt_set_blk(&p_cli
->pf_blks
[CDUC_BLK
]);
582 total
= cdu_iids
.pf_cids
* CONN_CXT_SIZE(p_hwfn
);
584 ecore_ilt_cli_blk_fill(p_cli
, p_blk
, curr_line
,
585 total
, CONN_CXT_SIZE(p_hwfn
));
587 ecore_ilt_cli_adv_line(p_hwfn
, p_cli
, p_blk
, &curr_line
, ILT_CLI_CDUC
);
588 p_cli
->pf_total_lines
= curr_line
- p_blk
->start_line
;
590 ecore_ilt_get_dynamic_line_range(p_hwfn
, ILT_CLI_CDUC
,
591 &p_blk
->dynamic_line_offset
,
592 &p_blk
->dynamic_line_cnt
);
595 p_blk
= ecore_cxt_set_blk(&p_cli
->vf_blks
[CDUC_BLK
]);
596 total
= cdu_iids
.per_vf_cids
* CONN_CXT_SIZE(p_hwfn
);
598 ecore_ilt_cli_blk_fill(p_cli
, p_blk
, curr_line
,
599 total
, CONN_CXT_SIZE(p_hwfn
));
601 ecore_ilt_cli_adv_line(p_hwfn
, p_cli
, p_blk
, &curr_line
, ILT_CLI_CDUC
);
602 p_cli
->vf_total_lines
= curr_line
- p_blk
->start_line
;
604 for (i
= 1; i
< p_mngr
->vf_count
; i
++)
605 ecore_ilt_cli_adv_line(p_hwfn
, p_cli
, p_blk
, &curr_line
,
609 p_cli
= ecore_cxt_set_cli(&p_mngr
->clients
[ILT_CLI_CDUT
]);
610 p_cli
->first
.val
= curr_line
;
612 /* first the 'working' task memory */
613 for (i
= 0; i
< NUM_TASK_PF_SEGMENTS
; i
++) {
614 p_seg
= ecore_cxt_tid_seg_info(p_hwfn
, i
);
615 if (!p_seg
|| p_seg
->count
== 0)
618 p_blk
= ecore_cxt_set_blk(&p_cli
->pf_blks
[CDUT_SEG_BLK(i
)]);
619 total
= p_seg
->count
* p_mngr
->task_type_size
[p_seg
->type
];
620 ecore_ilt_cli_blk_fill(p_cli
, p_blk
, curr_line
, total
,
621 p_mngr
->task_type_size
[p_seg
->type
]);
623 ecore_ilt_cli_adv_line(p_hwfn
, p_cli
, p_blk
, &curr_line
,
627 /* next the 'init' task memory (forced load memory) */
628 for (i
= 0; i
< NUM_TASK_PF_SEGMENTS
; i
++) {
629 p_seg
= ecore_cxt_tid_seg_info(p_hwfn
, i
);
630 if (!p_seg
|| p_seg
->count
== 0)
634 ecore_cxt_set_blk(&p_cli
->pf_blks
[CDUT_FL_SEG_BLK(i
, PF
)]);
636 if (!p_seg
->has_fl_mem
) {
637 /* The segment is active (total size pf 'working'
638 * memory is > 0) but has no FL (forced-load, Init)
641 * 1. The total-size in the corrsponding FL block of
642 * the ILT client is set to 0 - No ILT line are
643 * provisioned and no ILT memory allocated.
645 * 2. The start-line of said block is set to the
646 * start line of the matching working memory
647 * block in the ILT client. This is later used to
648 * configure the CDU segment offset registers and
649 * results in an FL command for TIDs of this
650 * segment behaves as regular load commands
651 * (loading TIDs from the working memory).
653 line
= p_cli
->pf_blks
[CDUT_SEG_BLK(i
)].start_line
;
655 ecore_ilt_cli_blk_fill(p_cli
, p_blk
, line
, 0, 0);
658 total
= p_seg
->count
* p_mngr
->task_type_size
[p_seg
->type
];
660 ecore_ilt_cli_blk_fill(p_cli
, p_blk
,
662 p_mngr
->task_type_size
[p_seg
->type
]);
664 ecore_ilt_cli_adv_line(p_hwfn
, p_cli
, p_blk
, &curr_line
,
667 p_cli
->pf_total_lines
= curr_line
- p_cli
->first
.val
;
670 p_seg
= ecore_cxt_tid_seg_info(p_hwfn
, TASK_SEGMENT_VF
);
671 if (p_seg
&& p_seg
->count
) {
672 /* Stricly speaking we need to iterate over all VF
673 * task segment types, but a VF has only 1 segment
676 /* 'working' memory */
677 total
= p_seg
->count
* p_mngr
->task_type_size
[p_seg
->type
];
679 p_blk
= ecore_cxt_set_blk(&p_cli
->vf_blks
[CDUT_SEG_BLK(0)]);
680 ecore_ilt_cli_blk_fill(p_cli
, p_blk
,
682 p_mngr
->task_type_size
[p_seg
->type
]);
684 ecore_ilt_cli_adv_line(p_hwfn
, p_cli
, p_blk
, &curr_line
,
689 ecore_cxt_set_blk(&p_cli
->vf_blks
[CDUT_FL_SEG_BLK(0, VF
)]);
690 if (!p_seg
->has_fl_mem
) {
691 /* see comment above */
692 line
= p_cli
->vf_blks
[CDUT_SEG_BLK(0)].start_line
;
693 ecore_ilt_cli_blk_fill(p_cli
, p_blk
, line
, 0, 0);
695 task_size
= p_mngr
->task_type_size
[p_seg
->type
];
696 ecore_ilt_cli_blk_fill(p_cli
, p_blk
,
697 curr_line
, total
, task_size
);
698 ecore_ilt_cli_adv_line(p_hwfn
, p_cli
, p_blk
, &curr_line
,
701 p_cli
->vf_total_lines
= curr_line
- (p_cli
->first
.val
+
702 p_cli
->pf_total_lines
);
704 /* Now for the rest of the VFs */
705 for (i
= 1; i
< p_mngr
->vf_count
; i
++) {
706 /* don't set p_blk i.e. don't clear total_size */
707 p_blk
= &p_cli
->vf_blks
[CDUT_SEG_BLK(0)];
708 ecore_ilt_cli_adv_line(p_hwfn
, p_cli
, p_blk
, &curr_line
,
711 /* don't set p_blk i.e. don't clear total_size */
712 p_blk
= &p_cli
->vf_blks
[CDUT_FL_SEG_BLK(0, VF
)];
713 ecore_ilt_cli_adv_line(p_hwfn
, p_cli
, p_blk
, &curr_line
,
719 p_cli
= ecore_cxt_set_cli(&p_mngr
->clients
[ILT_CLI_QM
]);
720 p_blk
= ecore_cxt_set_blk(&p_cli
->pf_blks
[0]);
722 /* At this stage, after the first QM configuration, the PF PQs amount
723 * is the highest possible. Save this value at qm_info->ilt_pf_pqs to
724 * detect overflows in the future.
725 * Even though VF PQs amount can be larger than VF count, use vf_count
726 * because each VF requires only the full amount of CIDs.
728 ecore_cxt_qm_iids(p_hwfn
, &qm_iids
);
729 total
= ecore_qm_pf_mem_size(p_hwfn
, qm_iids
.cids
,
730 qm_iids
.vf_cids
, qm_iids
.tids
,
731 p_hwfn
->qm_info
.num_pqs
+ OFLD_GRP_SIZE
,
732 p_hwfn
->qm_info
.num_vf_pqs
);
734 DP_VERBOSE(p_hwfn
, ECORE_MSG_ILT
,
735 "QM ILT Info, (cids=%d, vf_cids=%d, tids=%d, num_pqs=%d,"
736 " num_vf_pqs=%d, memory_size=%d)\n",
737 qm_iids
.cids
, qm_iids
.vf_cids
, qm_iids
.tids
,
738 p_hwfn
->qm_info
.num_pqs
, p_hwfn
->qm_info
.num_vf_pqs
, total
);
740 ecore_ilt_cli_blk_fill(p_cli
, p_blk
, curr_line
, total
* 0x1000,
743 ecore_ilt_cli_adv_line(p_hwfn
, p_cli
, p_blk
, &curr_line
, ILT_CLI_QM
);
744 p_cli
->pf_total_lines
= curr_line
- p_blk
->start_line
;
747 p_cli
= ecore_cxt_set_cli(&p_mngr
->clients
[ILT_CLI_TM
]);
748 ecore_cxt_tm_iids(p_hwfn
, p_mngr
, &tm_iids
);
749 total
= tm_iids
.pf_cids
+ tm_iids
.pf_tids_total
;
751 p_blk
= ecore_cxt_set_blk(&p_cli
->pf_blks
[0]);
752 ecore_ilt_cli_blk_fill(p_cli
, p_blk
, curr_line
,
753 total
* TM_ELEM_SIZE
,
756 ecore_ilt_cli_adv_line(p_hwfn
, p_cli
, p_blk
, &curr_line
,
758 p_cli
->pf_total_lines
= curr_line
- p_blk
->start_line
;
762 total
= tm_iids
.per_vf_cids
+ tm_iids
.per_vf_tids
;
764 p_blk
= ecore_cxt_set_blk(&p_cli
->vf_blks
[0]);
765 ecore_ilt_cli_blk_fill(p_cli
, p_blk
, curr_line
,
766 total
* TM_ELEM_SIZE
, TM_ELEM_SIZE
);
768 ecore_ilt_cli_adv_line(p_hwfn
, p_cli
, p_blk
, &curr_line
,
771 p_cli
->vf_total_lines
= curr_line
- p_blk
->start_line
;
772 for (i
= 1; i
< p_mngr
->vf_count
; i
++) {
773 ecore_ilt_cli_adv_line(p_hwfn
, p_cli
, p_blk
, &curr_line
,
779 p_cli
= ecore_cxt_set_cli(&p_mngr
->clients
[ILT_CLI_SRC
]);
780 total
= ecore_cxt_src_elements(p_mngr
);
783 total_size
= total
* sizeof(struct src_ent
);
784 elem_size
= sizeof(struct src_ent
);
786 p_blk
= ecore_cxt_set_blk(&p_cli
->pf_blks
[0]);
787 ecore_ilt_cli_blk_fill(p_cli
, p_blk
, curr_line
,
788 total_size
, elem_size
);
789 ecore_ilt_cli_adv_line(p_hwfn
, p_cli
, p_blk
, &curr_line
,
791 p_cli
->pf_total_lines
= curr_line
- p_blk
->start_line
;
794 /* TSDM (SRQ CONTEXT) */
795 total
= ecore_cxt_get_srq_count(p_hwfn
);
798 p_cli
= ecore_cxt_set_cli(&p_mngr
->clients
[ILT_CLI_TSDM
]);
799 p_blk
= ecore_cxt_set_blk(&p_cli
->pf_blks
[SRQ_BLK
]);
800 ecore_ilt_cli_blk_fill(p_cli
, p_blk
, curr_line
,
801 total
* SRQ_CXT_SIZE
, SRQ_CXT_SIZE
);
803 ecore_ilt_cli_adv_line(p_hwfn
, p_cli
, p_blk
, &curr_line
,
805 p_cli
->pf_total_lines
= curr_line
- p_blk
->start_line
;
808 if (curr_line
- p_hwfn
->p_cxt_mngr
->pf_start_line
>
809 RESC_NUM(p_hwfn
, ECORE_ILT
)) {
810 DP_ERR(p_hwfn
, "too many ilt lines...#lines=%d\n",
811 curr_line
- p_hwfn
->p_cxt_mngr
->pf_start_line
);
815 return ECORE_SUCCESS
;
818 static void ecore_cxt_src_t2_free(struct ecore_hwfn
*p_hwfn
)
820 struct ecore_src_t2
*p_t2
= &p_hwfn
->p_cxt_mngr
->src_t2
;
823 if (!p_t2
|| !p_t2
->dma_mem
)
826 for (i
= 0; i
< p_t2
->num_pages
; i
++)
827 if (p_t2
->dma_mem
[i
].virt_addr
)
828 OSAL_DMA_FREE_COHERENT(p_hwfn
->p_dev
,
829 p_t2
->dma_mem
[i
].virt_addr
,
830 p_t2
->dma_mem
[i
].phys_addr
,
831 p_t2
->dma_mem
[i
].size
);
833 OSAL_FREE(p_hwfn
->p_dev
, p_t2
->dma_mem
);
834 p_t2
->dma_mem
= OSAL_NULL
;
837 static enum _ecore_status_t
838 ecore_cxt_t2_alloc_pages(struct ecore_hwfn
*p_hwfn
,
839 struct ecore_src_t2
*p_t2
,
840 u32 total_size
, u32 page_size
)
845 if (!p_t2
|| !p_t2
->dma_mem
)
848 for (i
= 0; i
< p_t2
->num_pages
; i
++) {
849 size
= OSAL_MIN_T(u32
, total_size
, page_size
);
850 p_virt
= &p_t2
->dma_mem
[i
].virt_addr
;
852 *p_virt
= OSAL_DMA_ALLOC_COHERENT(p_hwfn
->p_dev
,
853 &p_t2
->dma_mem
[i
].phys_addr
,
855 if (!p_t2
->dma_mem
[i
].virt_addr
)
858 OSAL_MEM_ZERO(*p_virt
, size
);
859 p_t2
->dma_mem
[i
].size
= size
;
863 return ECORE_SUCCESS
;
866 static enum _ecore_status_t
ecore_cxt_src_t2_alloc(struct ecore_hwfn
*p_hwfn
)
868 struct ecore_cxt_mngr
*p_mngr
= p_hwfn
->p_cxt_mngr
;
869 u32 conn_num
, total_size
, ent_per_page
, psz
, i
;
870 struct phys_mem_desc
*p_t2_last_page
;
871 struct ecore_ilt_client_cfg
*p_src
;
872 struct ecore_src_iids src_iids
;
873 struct ecore_src_t2
*p_t2
;
874 enum _ecore_status_t rc
;
876 OSAL_MEM_ZERO(&src_iids
, sizeof(src_iids
));
878 /* if the SRC ILT client is inactive - there are no connection
879 * requiring the searcer, leave.
881 p_src
= &p_hwfn
->p_cxt_mngr
->clients
[ILT_CLI_SRC
];
883 return ECORE_SUCCESS
;
885 ecore_cxt_src_iids(p_mngr
, &src_iids
);
886 conn_num
= src_iids
.pf_cids
+ src_iids
.per_vf_cids
* p_mngr
->vf_count
;
887 total_size
= conn_num
* sizeof(struct src_ent
);
889 /* use the same page size as the SRC ILT client */
890 psz
= ILT_PAGE_IN_BYTES(p_src
->p_size
.val
);
891 p_t2
= &p_mngr
->src_t2
;
892 p_t2
->num_pages
= DIV_ROUND_UP(total_size
, psz
);
895 p_t2
->dma_mem
= OSAL_ZALLOC(p_hwfn
->p_dev
, GFP_KERNEL
,
897 sizeof(struct phys_mem_desc
));
898 if (!p_t2
->dma_mem
) {
899 DP_NOTICE(p_hwfn
, false, "Failed to allocate t2 table\n");
904 rc
= ecore_cxt_t2_alloc_pages(p_hwfn
, p_t2
, total_size
, psz
);
908 /* Set the t2 pointers */
910 /* entries per page - must be a power of two */
911 ent_per_page
= psz
/ sizeof(struct src_ent
);
913 p_t2
->first_free
= (u64
)p_t2
->dma_mem
[0].phys_addr
;
915 p_t2_last_page
= &p_t2
->dma_mem
[(conn_num
- 1) / ent_per_page
];
916 p_t2
->last_free
= (u64
)p_t2_last_page
->phys_addr
+
917 ((conn_num
- 1) & (ent_per_page
- 1)) *
918 sizeof(struct src_ent
);
920 for (i
= 0; i
< p_t2
->num_pages
; i
++) {
921 u32 ent_num
= OSAL_MIN_T(u32
, ent_per_page
, conn_num
);
922 struct src_ent
*entries
= p_t2
->dma_mem
[i
].virt_addr
;
923 u64 p_ent_phys
= (u64
)p_t2
->dma_mem
[i
].phys_addr
, val
;
926 for (j
= 0; j
< ent_num
- 1; j
++) {
927 val
= p_ent_phys
+ (j
+ 1) * sizeof(struct src_ent
);
928 entries
[j
].next
= OSAL_CPU_TO_BE64(val
);
931 if (i
< p_t2
->num_pages
- 1)
932 val
= (u64
)p_t2
->dma_mem
[i
+ 1].phys_addr
;
935 entries
[j
].next
= OSAL_CPU_TO_BE64(val
);
940 return ECORE_SUCCESS
;
943 ecore_cxt_src_t2_free(p_hwfn
);
947 #define for_each_ilt_valid_client(pos, clients) \
948 for (pos = 0; pos < ILT_CLI_MAX; pos++) \
949 if (!clients[pos].active) { \
954 /* Total number of ILT lines used by this PF */
955 static u32
ecore_cxt_ilt_shadow_size(struct ecore_ilt_client_cfg
*ilt_clients
)
960 for_each_ilt_valid_client(i
, ilt_clients
)
961 size
+= (ilt_clients
[i
].last
.val
-
962 ilt_clients
[i
].first
.val
+ 1);
967 static void ecore_ilt_shadow_free(struct ecore_hwfn
*p_hwfn
)
969 struct ecore_ilt_client_cfg
*p_cli
= p_hwfn
->p_cxt_mngr
->clients
;
970 struct ecore_cxt_mngr
*p_mngr
= p_hwfn
->p_cxt_mngr
;
973 if (p_mngr
->ilt_shadow
== OSAL_NULL
)
976 ilt_size
= ecore_cxt_ilt_shadow_size(p_cli
);
978 for (i
= 0; p_mngr
->ilt_shadow
&& i
< ilt_size
; i
++) {
979 struct phys_mem_desc
*p_dma
= &p_mngr
->ilt_shadow
[i
];
981 if (p_dma
->virt_addr
)
982 OSAL_DMA_FREE_COHERENT(p_hwfn
->p_dev
,
984 p_dma
->phys_addr
, p_dma
->size
);
985 p_dma
->virt_addr
= OSAL_NULL
;
987 OSAL_FREE(p_hwfn
->p_dev
, p_mngr
->ilt_shadow
);
988 p_mngr
->ilt_shadow
= OSAL_NULL
;
991 static enum _ecore_status_t
992 ecore_ilt_blk_alloc(struct ecore_hwfn
*p_hwfn
,
993 struct ecore_ilt_cli_blk
*p_blk
,
994 enum ilt_clients ilt_client
, u32 start_line_offset
)
996 struct phys_mem_desc
*ilt_shadow
= p_hwfn
->p_cxt_mngr
->ilt_shadow
;
997 u32 lines
, line
, sz_left
, lines_to_skip
, first_skipped_line
;
999 /* Special handling for RoCE that supports dynamic allocation */
1000 if (ilt_client
== ILT_CLI_CDUT
|| ilt_client
== ILT_CLI_TSDM
)
1001 return ECORE_SUCCESS
;
1003 if (!p_blk
->total_size
)
1004 return ECORE_SUCCESS
;
1006 sz_left
= p_blk
->total_size
;
1007 lines_to_skip
= p_blk
->dynamic_line_cnt
;
1008 lines
= DIV_ROUND_UP(sz_left
, p_blk
->real_size_in_page
) - lines_to_skip
;
1009 line
= p_blk
->start_line
+ start_line_offset
-
1010 p_hwfn
->p_cxt_mngr
->pf_start_line
;
1011 first_skipped_line
= line
+ p_blk
->dynamic_line_offset
;
1018 if (lines_to_skip
&& (line
== first_skipped_line
)) {
1019 line
+= lines_to_skip
;
1023 size
= OSAL_MIN_T(u32
, sz_left
, p_blk
->real_size_in_page
);
1026 #define ILT_BLOCK_ALIGN_SIZE 0x1000
1027 p_virt
= OSAL_DMA_ALLOC_COHERENT_ALIGNED(p_hwfn
->p_dev
,
1029 ILT_BLOCK_ALIGN_SIZE
);
1032 OSAL_MEM_ZERO(p_virt
, size
);
1034 ilt_shadow
[line
].phys_addr
= p_phys
;
1035 ilt_shadow
[line
].virt_addr
= p_virt
;
1036 ilt_shadow
[line
].size
= size
;
1038 DP_VERBOSE(p_hwfn
, ECORE_MSG_ILT
,
1039 "ILT shadow: Line [%d] Physical 0x%lx"
1040 " Virtual %p Size %d\n",
1041 line
, (unsigned long)p_phys
, p_virt
, size
);
1048 return ECORE_SUCCESS
;
1051 static enum _ecore_status_t
ecore_ilt_shadow_alloc(struct ecore_hwfn
*p_hwfn
)
1053 struct ecore_cxt_mngr
*p_mngr
= p_hwfn
->p_cxt_mngr
;
1054 struct ecore_ilt_client_cfg
*clients
= p_mngr
->clients
;
1055 struct ecore_ilt_cli_blk
*p_blk
;
1057 enum _ecore_status_t rc
;
1059 size
= ecore_cxt_ilt_shadow_size(clients
);
1060 p_mngr
->ilt_shadow
= OSAL_ZALLOC(p_hwfn
->p_dev
, GFP_KERNEL
,
1061 size
* sizeof(struct phys_mem_desc
));
1063 if (!p_mngr
->ilt_shadow
) {
1064 DP_NOTICE(p_hwfn
, false, "Failed to allocate ilt shadow table\n");
1066 goto ilt_shadow_fail
;
1069 DP_VERBOSE(p_hwfn
, ECORE_MSG_ILT
,
1070 "Allocated 0x%x bytes for ilt shadow\n",
1071 (u32
)(size
* sizeof(struct phys_mem_desc
)));
1073 for_each_ilt_valid_client(i
, clients
) {
1074 for (j
= 0; j
< ILT_CLI_PF_BLOCKS
; j
++) {
1075 p_blk
= &clients
[i
].pf_blks
[j
];
1076 rc
= ecore_ilt_blk_alloc(p_hwfn
, p_blk
, i
, 0);
1077 if (rc
!= ECORE_SUCCESS
)
1078 goto ilt_shadow_fail
;
1080 for (k
= 0; k
< p_mngr
->vf_count
; k
++) {
1081 for (j
= 0; j
< ILT_CLI_VF_BLOCKS
; j
++) {
1082 u32 lines
= clients
[i
].vf_total_lines
* k
;
1084 p_blk
= &clients
[i
].vf_blks
[j
];
1085 rc
= ecore_ilt_blk_alloc(p_hwfn
, p_blk
,
1087 if (rc
!= ECORE_SUCCESS
)
1088 goto ilt_shadow_fail
;
1093 return ECORE_SUCCESS
;
1096 ecore_ilt_shadow_free(p_hwfn
);
1100 static void ecore_cid_map_free(struct ecore_hwfn
*p_hwfn
)
1102 u32 type
, vf
, max_num_vfs
= NUM_OF_VFS(p_hwfn
->p_dev
);
1103 struct ecore_cxt_mngr
*p_mngr
= p_hwfn
->p_cxt_mngr
;
1105 for (type
= 0; type
< MAX_CONN_TYPES
; type
++) {
1106 OSAL_FREE(p_hwfn
->p_dev
, p_mngr
->acquired
[type
].cid_map
);
1107 p_mngr
->acquired
[type
].cid_map
= OSAL_NULL
;
1108 p_mngr
->acquired
[type
].max_count
= 0;
1109 p_mngr
->acquired
[type
].start_cid
= 0;
1111 for (vf
= 0; vf
< max_num_vfs
; vf
++) {
1112 OSAL_FREE(p_hwfn
->p_dev
,
1113 p_mngr
->acquired_vf
[type
][vf
].cid_map
);
1114 p_mngr
->acquired_vf
[type
][vf
].cid_map
= OSAL_NULL
;
1115 p_mngr
->acquired_vf
[type
][vf
].max_count
= 0;
1116 p_mngr
->acquired_vf
[type
][vf
].start_cid
= 0;
1121 static enum _ecore_status_t
1122 __ecore_cid_map_alloc_single(struct ecore_hwfn
*p_hwfn
, u32 type
,
1123 u32 cid_start
, u32 cid_count
,
1124 struct ecore_cid_acquired_map
*p_map
)
1129 return ECORE_SUCCESS
;
1131 size
= MAP_WORD_SIZE
* DIV_ROUND_UP(cid_count
, BITS_PER_MAP_WORD
);
1132 p_map
->cid_map
= OSAL_ZALLOC(p_hwfn
->p_dev
, GFP_KERNEL
, size
);
1133 if (p_map
->cid_map
== OSAL_NULL
)
1136 p_map
->max_count
= cid_count
;
1137 p_map
->start_cid
= cid_start
;
1139 DP_VERBOSE(p_hwfn
, ECORE_MSG_CXT
,
1140 "Type %08x start: %08x count %08x\n",
1141 type
, p_map
->start_cid
, p_map
->max_count
);
1143 return ECORE_SUCCESS
;
1146 static enum _ecore_status_t
1147 ecore_cid_map_alloc_single(struct ecore_hwfn
*p_hwfn
, u32 type
, u32 start_cid
,
1150 struct ecore_cxt_mngr
*p_mngr
= p_hwfn
->p_cxt_mngr
;
1151 u32 vf
, max_num_vfs
= NUM_OF_VFS(p_hwfn
->p_dev
);
1152 struct ecore_cid_acquired_map
*p_map
;
1153 struct ecore_conn_type_cfg
*p_cfg
;
1154 enum _ecore_status_t rc
;
1156 p_cfg
= &p_mngr
->conn_cfg
[type
];
1158 /* Handle PF maps */
1159 p_map
= &p_mngr
->acquired
[type
];
1160 rc
= __ecore_cid_map_alloc_single(p_hwfn
, type
, start_cid
,
1161 p_cfg
->cid_count
, p_map
);
1162 if (rc
!= ECORE_SUCCESS
)
1165 /* Handle VF maps */
1166 for (vf
= 0; vf
< max_num_vfs
; vf
++) {
1167 p_map
= &p_mngr
->acquired_vf
[type
][vf
];
1168 rc
= __ecore_cid_map_alloc_single(p_hwfn
, type
, vf_start_cid
,
1169 p_cfg
->cids_per_vf
, p_map
);
1170 if (rc
!= ECORE_SUCCESS
)
1174 return ECORE_SUCCESS
;
1177 static enum _ecore_status_t
ecore_cid_map_alloc(struct ecore_hwfn
*p_hwfn
)
1179 struct ecore_cxt_mngr
*p_mngr
= p_hwfn
->p_cxt_mngr
;
1180 u32 start_cid
= 0, vf_start_cid
= 0;
1182 enum _ecore_status_t rc
;
1184 for (type
= 0; type
< MAX_CONN_TYPES
; type
++) {
1185 rc
= ecore_cid_map_alloc_single(p_hwfn
, type
, start_cid
,
1187 if (rc
!= ECORE_SUCCESS
)
1190 start_cid
+= p_mngr
->conn_cfg
[type
].cid_count
;
1191 vf_start_cid
+= p_mngr
->conn_cfg
[type
].cids_per_vf
;
1194 return ECORE_SUCCESS
;
1197 ecore_cid_map_free(p_hwfn
);
1201 enum _ecore_status_t
ecore_cxt_mngr_alloc(struct ecore_hwfn
*p_hwfn
)
1203 struct ecore_cid_acquired_map
*acquired_vf
;
1204 struct ecore_ilt_client_cfg
*clients
;
1205 struct ecore_cxt_mngr
*p_mngr
;
1208 p_mngr
= OSAL_ZALLOC(p_hwfn
->p_dev
, GFP_KERNEL
, sizeof(*p_mngr
));
1210 DP_NOTICE(p_hwfn
, false, "Failed to allocate `struct ecore_cxt_mngr'\n");
1214 /* Initialize ILT client registers */
1215 clients
= p_mngr
->clients
;
1216 clients
[ILT_CLI_CDUC
].first
.reg
= ILT_CFG_REG(CDUC
, FIRST_ILT
);
1217 clients
[ILT_CLI_CDUC
].last
.reg
= ILT_CFG_REG(CDUC
, LAST_ILT
);
1218 clients
[ILT_CLI_CDUC
].p_size
.reg
= ILT_CFG_REG(CDUC
, P_SIZE
);
1220 clients
[ILT_CLI_QM
].first
.reg
= ILT_CFG_REG(QM
, FIRST_ILT
);
1221 clients
[ILT_CLI_QM
].last
.reg
= ILT_CFG_REG(QM
, LAST_ILT
);
1222 clients
[ILT_CLI_QM
].p_size
.reg
= ILT_CFG_REG(QM
, P_SIZE
);
1224 clients
[ILT_CLI_TM
].first
.reg
= ILT_CFG_REG(TM
, FIRST_ILT
);
1225 clients
[ILT_CLI_TM
].last
.reg
= ILT_CFG_REG(TM
, LAST_ILT
);
1226 clients
[ILT_CLI_TM
].p_size
.reg
= ILT_CFG_REG(TM
, P_SIZE
);
1228 clients
[ILT_CLI_SRC
].first
.reg
= ILT_CFG_REG(SRC
, FIRST_ILT
);
1229 clients
[ILT_CLI_SRC
].last
.reg
= ILT_CFG_REG(SRC
, LAST_ILT
);
1230 clients
[ILT_CLI_SRC
].p_size
.reg
= ILT_CFG_REG(SRC
, P_SIZE
);
1232 clients
[ILT_CLI_CDUT
].first
.reg
= ILT_CFG_REG(CDUT
, FIRST_ILT
);
1233 clients
[ILT_CLI_CDUT
].last
.reg
= ILT_CFG_REG(CDUT
, LAST_ILT
);
1234 clients
[ILT_CLI_CDUT
].p_size
.reg
= ILT_CFG_REG(CDUT
, P_SIZE
);
1236 clients
[ILT_CLI_TSDM
].first
.reg
= ILT_CFG_REG(TSDM
, FIRST_ILT
);
1237 clients
[ILT_CLI_TSDM
].last
.reg
= ILT_CFG_REG(TSDM
, LAST_ILT
);
1238 clients
[ILT_CLI_TSDM
].p_size
.reg
= ILT_CFG_REG(TSDM
, P_SIZE
);
1240 /* default ILT page size for all clients is 64K */
1241 for (i
= 0; i
< ILT_CLI_MAX
; i
++)
1242 p_mngr
->clients
[i
].p_size
.val
= ILT_DEFAULT_HW_P_SIZE
;
1244 /* due to removal of ISCSI/FCoE files union type0_task_context
1245 * task_type_size will be 0. So hardcoded for now.
1247 p_mngr
->task_type_size
[0] = 512; /* @DPDK */
1248 p_mngr
->task_type_size
[1] = 128; /* @DPDK */
1250 if (p_hwfn
->p_dev
->p_iov_info
)
1251 p_mngr
->vf_count
= p_hwfn
->p_dev
->p_iov_info
->total_vfs
;
1253 /* Initialize the dynamic ILT allocation mutex */
1254 #ifdef CONFIG_ECORE_LOCK_ALLOC
1255 if (OSAL_MUTEX_ALLOC(p_hwfn
, &p_mngr
->mutex
)) {
1256 DP_NOTICE(p_hwfn
, false, "Failed to alloc p_mngr->mutex\n");
1260 OSAL_MUTEX_INIT(&p_mngr
->mutex
);
1262 /* Set the cxt mangr pointer prior to further allocations */
1263 p_hwfn
->p_cxt_mngr
= p_mngr
;
1265 max_num_vfs
= NUM_OF_VFS(p_hwfn
->p_dev
);
1266 for (i
= 0; i
< MAX_CONN_TYPES
; i
++) {
1267 acquired_vf
= OSAL_CALLOC(p_hwfn
->p_dev
, GFP_KERNEL
,
1268 max_num_vfs
, sizeof(*acquired_vf
));
1270 DP_NOTICE(p_hwfn
, false,
1271 "Failed to allocate an array of `struct ecore_cid_acquired_map'\n");
1275 p_mngr
->acquired_vf
[i
] = acquired_vf
;
1278 return ECORE_SUCCESS
;
1281 enum _ecore_status_t
ecore_cxt_tables_alloc(struct ecore_hwfn
*p_hwfn
)
1283 enum _ecore_status_t rc
;
1285 /* Allocate the ILT shadow table */
1286 rc
= ecore_ilt_shadow_alloc(p_hwfn
);
1288 DP_NOTICE(p_hwfn
, false, "Failed to allocate ilt memory\n");
1289 goto tables_alloc_fail
;
1292 /* Allocate the T2 table */
1293 rc
= ecore_cxt_src_t2_alloc(p_hwfn
);
1295 DP_NOTICE(p_hwfn
, false, "Failed to allocate T2 memory\n");
1296 goto tables_alloc_fail
;
1299 /* Allocate and initialize the acquired cids bitmaps */
1300 rc
= ecore_cid_map_alloc(p_hwfn
);
1302 DP_NOTICE(p_hwfn
, false, "Failed to allocate cid maps\n");
1303 goto tables_alloc_fail
;
1306 return ECORE_SUCCESS
;
1309 ecore_cxt_mngr_free(p_hwfn
);
1313 void ecore_cxt_mngr_free(struct ecore_hwfn
*p_hwfn
)
1317 if (!p_hwfn
->p_cxt_mngr
)
1320 ecore_cid_map_free(p_hwfn
);
1321 ecore_cxt_src_t2_free(p_hwfn
);
1322 ecore_ilt_shadow_free(p_hwfn
);
1323 #ifdef CONFIG_ECORE_LOCK_ALLOC
1324 OSAL_MUTEX_DEALLOC(&p_hwfn
->p_cxt_mngr
->mutex
);
1326 for (i
= 0; i
< MAX_CONN_TYPES
; i
++)
1327 OSAL_FREE(p_hwfn
->p_dev
, p_hwfn
->p_cxt_mngr
->acquired_vf
[i
]);
1328 OSAL_FREE(p_hwfn
->p_dev
, p_hwfn
->p_cxt_mngr
);
1330 p_hwfn
->p_cxt_mngr
= OSAL_NULL
;
1333 void ecore_cxt_mngr_setup(struct ecore_hwfn
*p_hwfn
)
1335 struct ecore_cxt_mngr
*p_mngr
= p_hwfn
->p_cxt_mngr
;
1336 u32 len
, max_num_vfs
= NUM_OF_VFS(p_hwfn
->p_dev
);
1337 struct ecore_cid_acquired_map
*p_map
;
1338 struct ecore_conn_type_cfg
*p_cfg
;
1341 /* Reset acquired cids */
1342 for (type
= 0; type
< MAX_CONN_TYPES
; type
++) {
1345 p_cfg
= &p_mngr
->conn_cfg
[type
];
1346 if (p_cfg
->cid_count
) {
1347 p_map
= &p_mngr
->acquired
[type
];
1348 len
= DIV_ROUND_UP(p_map
->max_count
,
1349 BITS_PER_MAP_WORD
) *
1351 OSAL_MEM_ZERO(p_map
->cid_map
, len
);
1354 if (!p_cfg
->cids_per_vf
)
1357 for (vf
= 0; vf
< max_num_vfs
; vf
++) {
1358 p_map
= &p_mngr
->acquired_vf
[type
][vf
];
1359 len
= DIV_ROUND_UP(p_map
->max_count
,
1360 BITS_PER_MAP_WORD
) *
1362 OSAL_MEM_ZERO(p_map
->cid_map
, len
);
1367 /* HW initialization helper (per Block, per phase) */
1370 #define CDUC_CXT_SIZE_SHIFT \
1371 CDU_REG_CID_ADDR_PARAMS_CONTEXT_SIZE_SHIFT
1373 #define CDUC_CXT_SIZE_MASK \
1374 (CDU_REG_CID_ADDR_PARAMS_CONTEXT_SIZE >> CDUC_CXT_SIZE_SHIFT)
1376 #define CDUC_BLOCK_WASTE_SHIFT \
1377 CDU_REG_CID_ADDR_PARAMS_BLOCK_WASTE_SHIFT
1379 #define CDUC_BLOCK_WASTE_MASK \
1380 (CDU_REG_CID_ADDR_PARAMS_BLOCK_WASTE >> CDUC_BLOCK_WASTE_SHIFT)
1382 #define CDUC_NCIB_SHIFT \
1383 CDU_REG_CID_ADDR_PARAMS_NCIB_SHIFT
1385 #define CDUC_NCIB_MASK \
1386 (CDU_REG_CID_ADDR_PARAMS_NCIB >> CDUC_NCIB_SHIFT)
1388 #define CDUT_TYPE0_CXT_SIZE_SHIFT \
1389 CDU_REG_SEGMENT0_PARAMS_T0_TID_SIZE_SHIFT
1391 #define CDUT_TYPE0_CXT_SIZE_MASK \
1392 (CDU_REG_SEGMENT0_PARAMS_T0_TID_SIZE >> \
1393 CDUT_TYPE0_CXT_SIZE_SHIFT)
1395 #define CDUT_TYPE0_BLOCK_WASTE_SHIFT \
1396 CDU_REG_SEGMENT0_PARAMS_T0_TID_BLOCK_WASTE_SHIFT
1398 #define CDUT_TYPE0_BLOCK_WASTE_MASK \
1399 (CDU_REG_SEGMENT0_PARAMS_T0_TID_BLOCK_WASTE >> \
1400 CDUT_TYPE0_BLOCK_WASTE_SHIFT)
1402 #define CDUT_TYPE0_NCIB_SHIFT \
1403 CDU_REG_SEGMENT0_PARAMS_T0_NUM_TIDS_IN_BLOCK_SHIFT
1405 #define CDUT_TYPE0_NCIB_MASK \
1406 (CDU_REG_SEGMENT0_PARAMS_T0_NUM_TIDS_IN_BLOCK >> \
1407 CDUT_TYPE0_NCIB_SHIFT)
1409 #define CDUT_TYPE1_CXT_SIZE_SHIFT \
1410 CDU_REG_SEGMENT1_PARAMS_T1_TID_SIZE_SHIFT
1412 #define CDUT_TYPE1_CXT_SIZE_MASK \
1413 (CDU_REG_SEGMENT1_PARAMS_T1_TID_SIZE >> \
1414 CDUT_TYPE1_CXT_SIZE_SHIFT)
1416 #define CDUT_TYPE1_BLOCK_WASTE_SHIFT \
1417 CDU_REG_SEGMENT1_PARAMS_T1_TID_BLOCK_WASTE_SHIFT
1419 #define CDUT_TYPE1_BLOCK_WASTE_MASK \
1420 (CDU_REG_SEGMENT1_PARAMS_T1_TID_BLOCK_WASTE >> \
1421 CDUT_TYPE1_BLOCK_WASTE_SHIFT)
1423 #define CDUT_TYPE1_NCIB_SHIFT \
1424 CDU_REG_SEGMENT1_PARAMS_T1_NUM_TIDS_IN_BLOCK_SHIFT
1426 #define CDUT_TYPE1_NCIB_MASK \
1427 (CDU_REG_SEGMENT1_PARAMS_T1_NUM_TIDS_IN_BLOCK >> \
1428 CDUT_TYPE1_NCIB_SHIFT)
1430 static void ecore_cdu_init_common(struct ecore_hwfn
*p_hwfn
)
1432 u32 page_sz
, elems_per_page
, block_waste
, cxt_size
, cdu_params
= 0;
1434 /* CDUC - connection configuration */
1435 page_sz
= p_hwfn
->p_cxt_mngr
->clients
[ILT_CLI_CDUC
].p_size
.val
;
1436 cxt_size
= CONN_CXT_SIZE(p_hwfn
);
1437 elems_per_page
= ILT_PAGE_IN_BYTES(page_sz
) / cxt_size
;
1438 block_waste
= ILT_PAGE_IN_BYTES(page_sz
) - elems_per_page
* cxt_size
;
1440 SET_FIELD(cdu_params
, CDUC_CXT_SIZE
, cxt_size
);
1441 SET_FIELD(cdu_params
, CDUC_BLOCK_WASTE
, block_waste
);
1442 SET_FIELD(cdu_params
, CDUC_NCIB
, elems_per_page
);
1443 STORE_RT_REG(p_hwfn
, CDU_REG_CID_ADDR_PARAMS_RT_OFFSET
, cdu_params
);
1445 /* CDUT - type-0 tasks configuration */
1446 page_sz
= p_hwfn
->p_cxt_mngr
->clients
[ILT_CLI_CDUT
].p_size
.val
;
1447 cxt_size
= p_hwfn
->p_cxt_mngr
->task_type_size
[0];
1448 elems_per_page
= ILT_PAGE_IN_BYTES(page_sz
) / cxt_size
;
1449 block_waste
= ILT_PAGE_IN_BYTES(page_sz
) - elems_per_page
* cxt_size
;
1451 /* cxt size and block-waste are multipes of 8 */
1453 SET_FIELD(cdu_params
, CDUT_TYPE0_CXT_SIZE
, (cxt_size
>> 3));
1454 SET_FIELD(cdu_params
, CDUT_TYPE0_BLOCK_WASTE
, (block_waste
>> 3));
1455 SET_FIELD(cdu_params
, CDUT_TYPE0_NCIB
, elems_per_page
);
1456 STORE_RT_REG(p_hwfn
, CDU_REG_SEGMENT0_PARAMS_RT_OFFSET
, cdu_params
);
1458 /* CDUT - type-1 tasks configuration */
1459 cxt_size
= p_hwfn
->p_cxt_mngr
->task_type_size
[1];
1460 elems_per_page
= ILT_PAGE_IN_BYTES(page_sz
) / cxt_size
;
1461 block_waste
= ILT_PAGE_IN_BYTES(page_sz
) - elems_per_page
* cxt_size
;
1463 /* cxt size and block-waste are multipes of 8 */
1465 SET_FIELD(cdu_params
, CDUT_TYPE1_CXT_SIZE
, (cxt_size
>> 3));
1466 SET_FIELD(cdu_params
, CDUT_TYPE1_BLOCK_WASTE
, (block_waste
>> 3));
1467 SET_FIELD(cdu_params
, CDUT_TYPE1_NCIB
, elems_per_page
);
1468 STORE_RT_REG(p_hwfn
, CDU_REG_SEGMENT1_PARAMS_RT_OFFSET
, cdu_params
);
1472 #define CDU_SEG_REG_TYPE_SHIFT CDU_SEG_TYPE_OFFSET_REG_TYPE_SHIFT
1473 #define CDU_SEG_REG_TYPE_MASK 0x1
1474 #define CDU_SEG_REG_OFFSET_SHIFT 0
1475 #define CDU_SEG_REG_OFFSET_MASK CDU_SEG_TYPE_OFFSET_REG_OFFSET_MASK
1477 static void ecore_cdu_init_pf(struct ecore_hwfn
*p_hwfn
)
1479 struct ecore_ilt_client_cfg
*p_cli
;
1480 struct ecore_tid_seg
*p_seg
;
1481 u32 cdu_seg_params
, offset
;
1484 static const u32 rt_type_offset_arr
[] = {
1485 CDU_REG_PF_SEG0_TYPE_OFFSET_RT_OFFSET
,
1486 CDU_REG_PF_SEG1_TYPE_OFFSET_RT_OFFSET
,
1487 CDU_REG_PF_SEG2_TYPE_OFFSET_RT_OFFSET
,
1488 CDU_REG_PF_SEG3_TYPE_OFFSET_RT_OFFSET
1491 static const u32 rt_type_offset_fl_arr
[] = {
1492 CDU_REG_PF_FL_SEG0_TYPE_OFFSET_RT_OFFSET
,
1493 CDU_REG_PF_FL_SEG1_TYPE_OFFSET_RT_OFFSET
,
1494 CDU_REG_PF_FL_SEG2_TYPE_OFFSET_RT_OFFSET
,
1495 CDU_REG_PF_FL_SEG3_TYPE_OFFSET_RT_OFFSET
1498 p_cli
= &p_hwfn
->p_cxt_mngr
->clients
[ILT_CLI_CDUT
];
1500 /* There are initializations only for CDUT during pf Phase */
1501 for (i
= 0; i
< NUM_TASK_PF_SEGMENTS
; i
++) {
1503 p_seg
= ecore_cxt_tid_seg_info(p_hwfn
, i
);
1507 /* Note: start_line is already adjusted for the CDU
1508 * segment register granularity, so we just need to
1509 * divide. Adjustment is implicit as we assume ILT
1510 * Page size is larger than 32K!
1512 offset
= (ILT_PAGE_IN_BYTES(p_cli
->p_size
.val
) *
1513 (p_cli
->pf_blks
[CDUT_SEG_BLK(i
)].start_line
-
1514 p_cli
->first
.val
)) / CDUT_SEG_ALIGNMET_IN_BYTES
;
1517 SET_FIELD(cdu_seg_params
, CDU_SEG_REG_TYPE
, p_seg
->type
);
1518 SET_FIELD(cdu_seg_params
, CDU_SEG_REG_OFFSET
, offset
);
1519 STORE_RT_REG(p_hwfn
, rt_type_offset_arr
[i
], cdu_seg_params
);
1521 offset
= (ILT_PAGE_IN_BYTES(p_cli
->p_size
.val
) *
1522 (p_cli
->pf_blks
[CDUT_FL_SEG_BLK(i
, PF
)].start_line
-
1523 p_cli
->first
.val
)) / CDUT_SEG_ALIGNMET_IN_BYTES
;
1526 SET_FIELD(cdu_seg_params
, CDU_SEG_REG_TYPE
, p_seg
->type
);
1527 SET_FIELD(cdu_seg_params
, CDU_SEG_REG_OFFSET
, offset
);
1528 STORE_RT_REG(p_hwfn
, rt_type_offset_fl_arr
[i
], cdu_seg_params
);
1532 void ecore_qm_init_pf(struct ecore_hwfn
*p_hwfn
, struct ecore_ptt
*p_ptt
,
1535 struct ecore_qm_info
*qm_info
= &p_hwfn
->qm_info
;
1536 struct ecore_qm_iids iids
;
1538 OSAL_MEM_ZERO(&iids
, sizeof(iids
));
1539 ecore_cxt_qm_iids(p_hwfn
, &iids
);
1540 ecore_qm_pf_rt_init(p_hwfn
, p_ptt
, p_hwfn
->rel_pf_id
,
1541 qm_info
->max_phys_tcs_per_port
,
1543 iids
.cids
, iids
.vf_cids
, iids
.tids
,
1545 qm_info
->num_pqs
- qm_info
->num_vf_pqs
,
1546 qm_info
->num_vf_pqs
,
1547 qm_info
->start_vport
,
1548 qm_info
->num_vports
, qm_info
->pf_wfq
,
1550 p_hwfn
->qm_info
.qm_pq_params
,
1551 p_hwfn
->qm_info
.qm_vport_params
);
1555 static void ecore_cm_init_pf(struct ecore_hwfn
*p_hwfn
)
1557 STORE_RT_REG(p_hwfn
, XCM_REG_CON_PHY_Q3_RT_OFFSET
,
1558 ecore_get_cm_pq_idx(p_hwfn
, PQ_FLAGS_LB
));
1562 static void ecore_dq_init_pf(struct ecore_hwfn
*p_hwfn
)
1564 struct ecore_cxt_mngr
*p_mngr
= p_hwfn
->p_cxt_mngr
;
1565 u32 dq_pf_max_cid
= 0, dq_vf_max_cid
= 0;
1567 dq_pf_max_cid
+= (p_mngr
->conn_cfg
[0].cid_count
>> DQ_RANGE_SHIFT
);
1568 STORE_RT_REG(p_hwfn
, DORQ_REG_PF_MAX_ICID_0_RT_OFFSET
, dq_pf_max_cid
);
1570 dq_vf_max_cid
+= (p_mngr
->conn_cfg
[0].cids_per_vf
>> DQ_RANGE_SHIFT
);
1571 STORE_RT_REG(p_hwfn
, DORQ_REG_VF_MAX_ICID_0_RT_OFFSET
, dq_vf_max_cid
);
1573 dq_pf_max_cid
+= (p_mngr
->conn_cfg
[1].cid_count
>> DQ_RANGE_SHIFT
);
1574 STORE_RT_REG(p_hwfn
, DORQ_REG_PF_MAX_ICID_1_RT_OFFSET
, dq_pf_max_cid
);
1576 dq_vf_max_cid
+= (p_mngr
->conn_cfg
[1].cids_per_vf
>> DQ_RANGE_SHIFT
);
1577 STORE_RT_REG(p_hwfn
, DORQ_REG_VF_MAX_ICID_1_RT_OFFSET
, dq_vf_max_cid
);
1579 dq_pf_max_cid
+= (p_mngr
->conn_cfg
[2].cid_count
>> DQ_RANGE_SHIFT
);
1580 STORE_RT_REG(p_hwfn
, DORQ_REG_PF_MAX_ICID_2_RT_OFFSET
, dq_pf_max_cid
);
1582 dq_vf_max_cid
+= (p_mngr
->conn_cfg
[2].cids_per_vf
>> DQ_RANGE_SHIFT
);
1583 STORE_RT_REG(p_hwfn
, DORQ_REG_VF_MAX_ICID_2_RT_OFFSET
, dq_vf_max_cid
);
1585 dq_pf_max_cid
+= (p_mngr
->conn_cfg
[3].cid_count
>> DQ_RANGE_SHIFT
);
1586 STORE_RT_REG(p_hwfn
, DORQ_REG_PF_MAX_ICID_3_RT_OFFSET
, dq_pf_max_cid
);
1588 dq_vf_max_cid
+= (p_mngr
->conn_cfg
[3].cids_per_vf
>> DQ_RANGE_SHIFT
);
1589 STORE_RT_REG(p_hwfn
, DORQ_REG_VF_MAX_ICID_3_RT_OFFSET
, dq_vf_max_cid
);
1591 dq_pf_max_cid
+= (p_mngr
->conn_cfg
[4].cid_count
>> DQ_RANGE_SHIFT
);
1592 STORE_RT_REG(p_hwfn
, DORQ_REG_PF_MAX_ICID_4_RT_OFFSET
, dq_pf_max_cid
);
1594 dq_vf_max_cid
+= (p_mngr
->conn_cfg
[4].cids_per_vf
>> DQ_RANGE_SHIFT
);
1595 STORE_RT_REG(p_hwfn
, DORQ_REG_VF_MAX_ICID_4_RT_OFFSET
, dq_vf_max_cid
);
1597 dq_pf_max_cid
+= (p_mngr
->conn_cfg
[5].cid_count
>> DQ_RANGE_SHIFT
);
1598 STORE_RT_REG(p_hwfn
, DORQ_REG_PF_MAX_ICID_5_RT_OFFSET
, dq_pf_max_cid
);
1600 dq_vf_max_cid
+= (p_mngr
->conn_cfg
[5].cids_per_vf
>> DQ_RANGE_SHIFT
);
1601 STORE_RT_REG(p_hwfn
, DORQ_REG_VF_MAX_ICID_5_RT_OFFSET
, dq_vf_max_cid
);
1603 /* Connection types 6 & 7 are not in use, yet they must be configured
1604 * as the highest possible connection. Not configuring them means the
1605 * defaults will be used, and with a large number of cids a bug may
1606 * occur, if the defaults will be smaller than dq_pf_max_cid /
1609 STORE_RT_REG(p_hwfn
, DORQ_REG_PF_MAX_ICID_6_RT_OFFSET
, dq_pf_max_cid
);
1610 STORE_RT_REG(p_hwfn
, DORQ_REG_VF_MAX_ICID_6_RT_OFFSET
, dq_vf_max_cid
);
1612 STORE_RT_REG(p_hwfn
, DORQ_REG_PF_MAX_ICID_7_RT_OFFSET
, dq_pf_max_cid
);
1613 STORE_RT_REG(p_hwfn
, DORQ_REG_VF_MAX_ICID_7_RT_OFFSET
, dq_vf_max_cid
);
1616 static void ecore_ilt_bounds_init(struct ecore_hwfn
*p_hwfn
)
1618 struct ecore_ilt_client_cfg
*ilt_clients
;
1621 ilt_clients
= p_hwfn
->p_cxt_mngr
->clients
;
1622 for_each_ilt_valid_client(i
, ilt_clients
) {
1623 STORE_RT_REG(p_hwfn
,
1624 ilt_clients
[i
].first
.reg
,
1625 ilt_clients
[i
].first
.val
);
1626 STORE_RT_REG(p_hwfn
,
1627 ilt_clients
[i
].last
.reg
, ilt_clients
[i
].last
.val
);
1628 STORE_RT_REG(p_hwfn
,
1629 ilt_clients
[i
].p_size
.reg
,
1630 ilt_clients
[i
].p_size
.val
);
1634 static void ecore_ilt_vf_bounds_init(struct ecore_hwfn
*p_hwfn
)
1636 struct ecore_ilt_client_cfg
*p_cli
;
1639 /* For simplicty we set the 'block' to be an ILT page */
1640 if (p_hwfn
->p_dev
->p_iov_info
) {
1641 struct ecore_hw_sriov_info
*p_iov
= p_hwfn
->p_dev
->p_iov_info
;
1643 STORE_RT_REG(p_hwfn
,
1644 PSWRQ2_REG_VF_BASE_RT_OFFSET
,
1645 p_iov
->first_vf_in_pf
);
1646 STORE_RT_REG(p_hwfn
,
1647 PSWRQ2_REG_VF_LAST_ILT_RT_OFFSET
,
1648 p_iov
->first_vf_in_pf
+ p_iov
->total_vfs
);
1651 p_cli
= &p_hwfn
->p_cxt_mngr
->clients
[ILT_CLI_CDUC
];
1652 blk_factor
= OSAL_LOG2(ILT_PAGE_IN_BYTES(p_cli
->p_size
.val
) >> 10);
1653 if (p_cli
->active
) {
1654 STORE_RT_REG(p_hwfn
,
1655 PSWRQ2_REG_CDUC_BLOCKS_FACTOR_RT_OFFSET
,
1657 STORE_RT_REG(p_hwfn
,
1658 PSWRQ2_REG_CDUC_NUMBER_OF_PF_BLOCKS_RT_OFFSET
,
1659 p_cli
->pf_total_lines
);
1660 STORE_RT_REG(p_hwfn
,
1661 PSWRQ2_REG_CDUC_VF_BLOCKS_RT_OFFSET
,
1662 p_cli
->vf_total_lines
);
1665 p_cli
= &p_hwfn
->p_cxt_mngr
->clients
[ILT_CLI_CDUT
];
1666 blk_factor
= OSAL_LOG2(ILT_PAGE_IN_BYTES(p_cli
->p_size
.val
) >> 10);
1667 if (p_cli
->active
) {
1668 STORE_RT_REG(p_hwfn
,
1669 PSWRQ2_REG_CDUT_BLOCKS_FACTOR_RT_OFFSET
,
1671 STORE_RT_REG(p_hwfn
,
1672 PSWRQ2_REG_CDUT_NUMBER_OF_PF_BLOCKS_RT_OFFSET
,
1673 p_cli
->pf_total_lines
);
1674 STORE_RT_REG(p_hwfn
,
1675 PSWRQ2_REG_CDUT_VF_BLOCKS_RT_OFFSET
,
1676 p_cli
->vf_total_lines
);
1679 p_cli
= &p_hwfn
->p_cxt_mngr
->clients
[ILT_CLI_TM
];
1680 blk_factor
= OSAL_LOG2(ILT_PAGE_IN_BYTES(p_cli
->p_size
.val
) >> 10);
1681 if (p_cli
->active
) {
1682 STORE_RT_REG(p_hwfn
,
1683 PSWRQ2_REG_TM_BLOCKS_FACTOR_RT_OFFSET
, blk_factor
);
1684 STORE_RT_REG(p_hwfn
,
1685 PSWRQ2_REG_TM_NUMBER_OF_PF_BLOCKS_RT_OFFSET
,
1686 p_cli
->pf_total_lines
);
1687 STORE_RT_REG(p_hwfn
,
1688 PSWRQ2_REG_TM_VF_BLOCKS_RT_OFFSET
,
1689 p_cli
->vf_total_lines
);
1693 /* ILT (PSWRQ2) PF */
1694 static void ecore_ilt_init_pf(struct ecore_hwfn
*p_hwfn
)
1696 struct ecore_ilt_client_cfg
*clients
;
1697 struct ecore_cxt_mngr
*p_mngr
;
1698 struct phys_mem_desc
*p_shdw
;
1699 u32 line
, rt_offst
, i
;
1701 ecore_ilt_bounds_init(p_hwfn
);
1702 ecore_ilt_vf_bounds_init(p_hwfn
);
1704 p_mngr
= p_hwfn
->p_cxt_mngr
;
1705 p_shdw
= p_mngr
->ilt_shadow
;
1706 clients
= p_hwfn
->p_cxt_mngr
->clients
;
1708 for_each_ilt_valid_client(i
, clients
) {
1709 /* Client's 1st val and RT array are absolute, ILT shadows'
1710 * lines are relative.
1712 line
= clients
[i
].first
.val
- p_mngr
->pf_start_line
;
1713 rt_offst
= PSWRQ2_REG_ILT_MEMORY_RT_OFFSET
+
1714 clients
[i
].first
.val
* ILT_ENTRY_IN_REGS
;
1716 for (; line
<= clients
[i
].last
.val
- p_mngr
->pf_start_line
;
1717 line
++, rt_offst
+= ILT_ENTRY_IN_REGS
) {
1718 u64 ilt_hw_entry
= 0;
1720 /** p_virt could be OSAL_NULL incase of dynamic
1723 if (p_shdw
[line
].virt_addr
!= OSAL_NULL
) {
1724 SET_FIELD(ilt_hw_entry
, ILT_ENTRY_VALID
, 1ULL);
1725 SET_FIELD(ilt_hw_entry
, ILT_ENTRY_PHY_ADDR
,
1726 (p_shdw
[line
].phys_addr
>> 12));
1728 DP_VERBOSE(p_hwfn
, ECORE_MSG_ILT
,
1729 "Setting RT[0x%08x] from"
1730 " ILT[0x%08x] [Client is %d] to"
1731 " Physical addr: 0x%lx\n",
1733 (unsigned long)(p_shdw
[line
].
1737 STORE_RT_REG_AGG(p_hwfn
, rt_offst
, ilt_hw_entry
);
1742 /* SRC (Searcher) PF */
1743 static void ecore_src_init_pf(struct ecore_hwfn
*p_hwfn
)
1745 struct ecore_cxt_mngr
*p_mngr
= p_hwfn
->p_cxt_mngr
;
1746 u32 rounded_conn_num
, conn_num
, conn_max
;
1747 struct ecore_src_iids src_iids
;
1749 OSAL_MEM_ZERO(&src_iids
, sizeof(src_iids
));
1750 ecore_cxt_src_iids(p_mngr
, &src_iids
);
1751 conn_num
= src_iids
.pf_cids
+ src_iids
.per_vf_cids
* p_mngr
->vf_count
;
1755 conn_max
= OSAL_MAX_T(u32
, conn_num
, SRC_MIN_NUM_ELEMS
);
1756 rounded_conn_num
= OSAL_ROUNDUP_POW_OF_TWO(conn_max
);
1758 STORE_RT_REG(p_hwfn
, SRC_REG_COUNTFREE_RT_OFFSET
, conn_num
);
1759 STORE_RT_REG(p_hwfn
, SRC_REG_NUMBER_HASH_BITS_RT_OFFSET
,
1760 OSAL_LOG2(rounded_conn_num
));
1762 STORE_RT_REG_AGG(p_hwfn
, SRC_REG_FIRSTFREE_RT_OFFSET
,
1763 p_hwfn
->p_cxt_mngr
->src_t2
.first_free
);
1764 STORE_RT_REG_AGG(p_hwfn
, SRC_REG_LASTFREE_RT_OFFSET
,
1765 p_hwfn
->p_cxt_mngr
->src_t2
.last_free
);
1766 DP_VERBOSE(p_hwfn
, ECORE_MSG_ILT
,
1767 "Configured SEARCHER for 0x%08x connections\n",
1772 #define TM_CFG_NUM_IDS_SHIFT 0
1773 #define TM_CFG_NUM_IDS_MASK 0xFFFFULL
1774 #define TM_CFG_PRE_SCAN_OFFSET_SHIFT 16
1775 #define TM_CFG_PRE_SCAN_OFFSET_MASK 0x1FFULL
1776 #define TM_CFG_PARENT_PF_SHIFT 25
1777 #define TM_CFG_PARENT_PF_MASK 0x7ULL
1779 #define TM_CFG_CID_PRE_SCAN_ROWS_SHIFT 30
1780 #define TM_CFG_CID_PRE_SCAN_ROWS_MASK 0x1FFULL
1782 #define TM_CFG_TID_OFFSET_SHIFT 30
1783 #define TM_CFG_TID_OFFSET_MASK 0x7FFFFULL
1784 #define TM_CFG_TID_PRE_SCAN_ROWS_SHIFT 49
1785 #define TM_CFG_TID_PRE_SCAN_ROWS_MASK 0x1FFULL
1787 static void ecore_tm_init_pf(struct ecore_hwfn
*p_hwfn
)
1789 struct ecore_cxt_mngr
*p_mngr
= p_hwfn
->p_cxt_mngr
;
1790 u32 active_seg_mask
= 0, tm_offset
, rt_reg
;
1791 struct ecore_tm_iids tm_iids
;
1795 OSAL_MEM_ZERO(&tm_iids
, sizeof(tm_iids
));
1796 ecore_cxt_tm_iids(p_hwfn
, p_mngr
, &tm_iids
);
1798 /* @@@TBD No pre-scan for now */
1801 SET_FIELD(cfg_word
, TM_CFG_NUM_IDS
, tm_iids
.per_vf_cids
);
1802 SET_FIELD(cfg_word
, TM_CFG_PARENT_PF
, p_hwfn
->rel_pf_id
);
1803 SET_FIELD(cfg_word
, TM_CFG_PRE_SCAN_OFFSET
, 0);
1804 SET_FIELD(cfg_word
, TM_CFG_CID_PRE_SCAN_ROWS
, 0); /* scan all */
1806 /* Note: We assume consecutive VFs for a PF */
1807 for (i
= 0; i
< p_mngr
->vf_count
; i
++) {
1808 rt_reg
= TM_REG_CONFIG_CONN_MEM_RT_OFFSET
+
1809 (sizeof(cfg_word
) / sizeof(u32
)) *
1810 (p_hwfn
->p_dev
->p_iov_info
->first_vf_in_pf
+ i
);
1811 STORE_RT_REG_AGG(p_hwfn
, rt_reg
, cfg_word
);
1815 SET_FIELD(cfg_word
, TM_CFG_NUM_IDS
, tm_iids
.pf_cids
);
1816 SET_FIELD(cfg_word
, TM_CFG_PRE_SCAN_OFFSET
, 0);
1817 SET_FIELD(cfg_word
, TM_CFG_PARENT_PF
, 0); /* n/a for PF */
1818 SET_FIELD(cfg_word
, TM_CFG_CID_PRE_SCAN_ROWS
, 0); /* scan all */
1820 rt_reg
= TM_REG_CONFIG_CONN_MEM_RT_OFFSET
+
1821 (sizeof(cfg_word
) / sizeof(u32
)) *
1822 (NUM_OF_VFS(p_hwfn
->p_dev
) + p_hwfn
->rel_pf_id
);
1823 STORE_RT_REG_AGG(p_hwfn
, rt_reg
, cfg_word
);
1826 STORE_RT_REG(p_hwfn
, TM_REG_PF_ENABLE_CONN_RT_OFFSET
,
1827 tm_iids
.pf_cids
? 0x1 : 0x0);
1829 /* @@@TBD how to enable the scan for the VFs */
1831 tm_offset
= tm_iids
.per_vf_cids
;
1833 /* Note: We assume consecutive VFs for a PF */
1834 for (i
= 0; i
< p_mngr
->vf_count
; i
++) {
1836 SET_FIELD(cfg_word
, TM_CFG_NUM_IDS
, tm_iids
.per_vf_tids
);
1837 SET_FIELD(cfg_word
, TM_CFG_PRE_SCAN_OFFSET
, 0);
1838 SET_FIELD(cfg_word
, TM_CFG_PARENT_PF
, p_hwfn
->rel_pf_id
);
1839 SET_FIELD(cfg_word
, TM_CFG_TID_OFFSET
, tm_offset
);
1840 SET_FIELD(cfg_word
, TM_CFG_TID_PRE_SCAN_ROWS
, (u64
)0);
1842 rt_reg
= TM_REG_CONFIG_TASK_MEM_RT_OFFSET
+
1843 (sizeof(cfg_word
) / sizeof(u32
)) *
1844 (p_hwfn
->p_dev
->p_iov_info
->first_vf_in_pf
+ i
);
1846 STORE_RT_REG_AGG(p_hwfn
, rt_reg
, cfg_word
);
1849 tm_offset
= tm_iids
.pf_cids
;
1850 for (i
= 0; i
< NUM_TASK_PF_SEGMENTS
; i
++) {
1852 SET_FIELD(cfg_word
, TM_CFG_NUM_IDS
, tm_iids
.pf_tids
[i
]);
1853 SET_FIELD(cfg_word
, TM_CFG_PRE_SCAN_OFFSET
, 0);
1854 SET_FIELD(cfg_word
, TM_CFG_PARENT_PF
, 0);
1855 SET_FIELD(cfg_word
, TM_CFG_TID_OFFSET
, tm_offset
);
1856 SET_FIELD(cfg_word
, TM_CFG_TID_PRE_SCAN_ROWS
, (u64
)0);
1858 rt_reg
= TM_REG_CONFIG_TASK_MEM_RT_OFFSET
+
1859 (sizeof(cfg_word
) / sizeof(u32
)) *
1860 (NUM_OF_VFS(p_hwfn
->p_dev
) +
1861 p_hwfn
->rel_pf_id
* NUM_TASK_PF_SEGMENTS
+ i
);
1863 STORE_RT_REG_AGG(p_hwfn
, rt_reg
, cfg_word
);
1864 active_seg_mask
|= (tm_iids
.pf_tids
[i
] ? (1 << i
) : 0);
1866 tm_offset
+= tm_iids
.pf_tids
[i
];
1869 STORE_RT_REG(p_hwfn
, TM_REG_PF_ENABLE_TASK_RT_OFFSET
, active_seg_mask
);
1871 /* @@@TBD how to enable the scan for the VFs */
1874 static void ecore_prs_init_pf(struct ecore_hwfn
*p_hwfn
)
1876 struct ecore_cxt_mngr
*p_mngr
= p_hwfn
->p_cxt_mngr
;
1877 struct ecore_conn_type_cfg
*p_fcoe
;
1878 struct ecore_tid_seg
*p_tid
;
1880 p_fcoe
= &p_mngr
->conn_cfg
[PROTOCOLID_FCOE
];
1882 /* If FCoE is active set the MAX OX_ID (tid) in the Parser */
1883 if (!p_fcoe
->cid_count
)
1886 p_tid
= &p_fcoe
->tid_seg
[ECORE_CXT_FCOE_TID_SEG
];
1887 STORE_RT_REG_AGG(p_hwfn
,
1888 PRS_REG_TASK_ID_MAX_INITIATOR_PF_RT_OFFSET
,
1892 void ecore_cxt_hw_init_common(struct ecore_hwfn
*p_hwfn
)
1894 /* CDU configuration */
1895 ecore_cdu_init_common(p_hwfn
);
1898 void ecore_cxt_hw_init_pf(struct ecore_hwfn
*p_hwfn
, struct ecore_ptt
*p_ptt
)
1900 ecore_qm_init_pf(p_hwfn
, p_ptt
, true);
1901 ecore_cm_init_pf(p_hwfn
);
1902 ecore_dq_init_pf(p_hwfn
);
1903 ecore_cdu_init_pf(p_hwfn
);
1904 ecore_ilt_init_pf(p_hwfn
);
1905 ecore_src_init_pf(p_hwfn
);
1906 ecore_tm_init_pf(p_hwfn
);
1907 ecore_prs_init_pf(p_hwfn
);
1910 enum _ecore_status_t
_ecore_cxt_acquire_cid(struct ecore_hwfn
*p_hwfn
,
1911 enum protocol_type type
,
1912 u32
*p_cid
, u8 vfid
)
1914 u32 rel_cid
, max_num_vfs
= NUM_OF_VFS(p_hwfn
->p_dev
);
1915 struct ecore_cxt_mngr
*p_mngr
= p_hwfn
->p_cxt_mngr
;
1916 struct ecore_cid_acquired_map
*p_map
;
1918 if (type
>= MAX_CONN_TYPES
) {
1919 DP_NOTICE(p_hwfn
, true, "Invalid protocol type %d", type
);
1923 if (vfid
>= max_num_vfs
&& vfid
!= ECORE_CXT_PF_CID
) {
1924 DP_NOTICE(p_hwfn
, true, "VF [%02x] is out of range\n", vfid
);
1928 /* Determine the right map to take this CID from */
1929 if (vfid
== ECORE_CXT_PF_CID
)
1930 p_map
= &p_mngr
->acquired
[type
];
1932 p_map
= &p_mngr
->acquired_vf
[type
][vfid
];
1934 if (p_map
->cid_map
== OSAL_NULL
) {
1935 DP_NOTICE(p_hwfn
, true, "Invalid protocol type %d", type
);
1939 rel_cid
= OSAL_FIND_FIRST_ZERO_BIT(p_map
->cid_map
,
1942 if (rel_cid
>= p_map
->max_count
) {
1943 DP_NOTICE(p_hwfn
, false, "no CID available for protocol %d\n",
1945 return ECORE_NORESOURCES
;
1948 OSAL_SET_BIT(rel_cid
, p_map
->cid_map
);
1950 *p_cid
= rel_cid
+ p_map
->start_cid
;
1952 DP_VERBOSE(p_hwfn
, ECORE_MSG_CXT
,
1953 "Acquired cid 0x%08x [rel. %08x] vfid %02x type %d\n",
1954 *p_cid
, rel_cid
, vfid
, type
);
1956 return ECORE_SUCCESS
;
1959 enum _ecore_status_t
ecore_cxt_acquire_cid(struct ecore_hwfn
*p_hwfn
,
1960 enum protocol_type type
,
1963 return _ecore_cxt_acquire_cid(p_hwfn
, type
, p_cid
, ECORE_CXT_PF_CID
);
1966 static bool ecore_cxt_test_cid_acquired(struct ecore_hwfn
*p_hwfn
,
1968 enum protocol_type
*p_type
,
1969 struct ecore_cid_acquired_map
**pp_map
)
1971 struct ecore_cxt_mngr
*p_mngr
= p_hwfn
->p_cxt_mngr
;
1974 /* Iterate over protocols and find matching cid range */
1975 for (*p_type
= 0; *p_type
< MAX_CONN_TYPES
; (*p_type
)++) {
1976 if (vfid
== ECORE_CXT_PF_CID
)
1977 *pp_map
= &p_mngr
->acquired
[*p_type
];
1979 *pp_map
= &p_mngr
->acquired_vf
[*p_type
][vfid
];
1981 if (!((*pp_map
)->cid_map
))
1983 if (cid
>= (*pp_map
)->start_cid
&&
1984 cid
< (*pp_map
)->start_cid
+ (*pp_map
)->max_count
) {
1988 if (*p_type
== MAX_CONN_TYPES
) {
1989 DP_NOTICE(p_hwfn
, true, "Invalid CID %d vfid %02x", cid
, vfid
);
1993 rel_cid
= cid
- (*pp_map
)->start_cid
;
1994 if (!OSAL_TEST_BIT(rel_cid
, (*pp_map
)->cid_map
)) {
1995 DP_NOTICE(p_hwfn
, true,
1996 "CID %d [vifd %02x] not acquired", cid
, vfid
);
2002 *p_type
= MAX_CONN_TYPES
;
2003 *pp_map
= OSAL_NULL
;
2007 void _ecore_cxt_release_cid(struct ecore_hwfn
*p_hwfn
, u32 cid
, u8 vfid
)
2009 u32 rel_cid
, max_num_vfs
= NUM_OF_VFS(p_hwfn
->p_dev
);
2010 struct ecore_cid_acquired_map
*p_map
= OSAL_NULL
;
2011 enum protocol_type type
;
2014 if (vfid
!= ECORE_CXT_PF_CID
&& vfid
> max_num_vfs
) {
2015 DP_NOTICE(p_hwfn
, true,
2016 "Trying to return incorrect CID belonging to VF %02x\n",
2021 /* Test acquired and find matching per-protocol map */
2022 b_acquired
= ecore_cxt_test_cid_acquired(p_hwfn
, cid
, vfid
,
2028 rel_cid
= cid
- p_map
->start_cid
;
2029 OSAL_CLEAR_BIT(rel_cid
, p_map
->cid_map
);
2031 DP_VERBOSE(p_hwfn
, ECORE_MSG_CXT
,
2032 "Released CID 0x%08x [rel. %08x] vfid %02x type %d\n",
2033 cid
, rel_cid
, vfid
, type
);
2036 void ecore_cxt_release_cid(struct ecore_hwfn
*p_hwfn
, u32 cid
)
2038 _ecore_cxt_release_cid(p_hwfn
, cid
, ECORE_CXT_PF_CID
);
2041 enum _ecore_status_t
ecore_cxt_get_cid_info(struct ecore_hwfn
*p_hwfn
,
2042 struct ecore_cxt_info
*p_info
)
2044 struct ecore_cxt_mngr
*p_mngr
= p_hwfn
->p_cxt_mngr
;
2045 struct ecore_cid_acquired_map
*p_map
= OSAL_NULL
;
2046 u32 conn_cxt_size
, hw_p_size
, cxts_per_p
, line
;
2047 enum protocol_type type
;
2050 /* Test acquired and find matching per-protocol map */
2051 b_acquired
= ecore_cxt_test_cid_acquired(p_hwfn
, p_info
->iid
,
2058 /* set the protocl type */
2059 p_info
->type
= type
;
2061 /* compute context virtual pointer */
2062 hw_p_size
= p_hwfn
->p_cxt_mngr
->clients
[ILT_CLI_CDUC
].p_size
.val
;
2064 conn_cxt_size
= CONN_CXT_SIZE(p_hwfn
);
2065 cxts_per_p
= ILT_PAGE_IN_BYTES(hw_p_size
) / conn_cxt_size
;
2066 line
= p_info
->iid
/ cxts_per_p
;
2068 /* Make sure context is allocated (dynamic allocation) */
2069 if (!p_mngr
->ilt_shadow
[line
].virt_addr
)
2072 p_info
->p_cxt
= (u8
*)p_mngr
->ilt_shadow
[line
].virt_addr
+
2073 p_info
->iid
% cxts_per_p
* conn_cxt_size
;
2075 DP_VERBOSE(p_hwfn
, (ECORE_MSG_ILT
| ECORE_MSG_CXT
),
2076 "Accessing ILT shadow[%d]: CXT pointer is at %p (for iid %d)\n",
2077 (p_info
->iid
/ cxts_per_p
), p_info
->p_cxt
, p_info
->iid
);
2079 return ECORE_SUCCESS
;
2082 enum _ecore_status_t
ecore_cxt_set_pf_params(struct ecore_hwfn
*p_hwfn
)
2084 /* Set the number of required CORE connections */
2085 u32 core_cids
= 1; /* SPQ */
2087 ecore_cxt_set_proto_cid_count(p_hwfn
, PROTOCOLID_CORE
, core_cids
, 0);
2089 switch (p_hwfn
->hw_info
.personality
) {
2094 struct ecore_eth_pf_params
*p_params
=
2095 &p_hwfn
->pf_params
.eth_pf_params
;
2097 if (!p_params
->num_vf_cons
)
2098 p_params
->num_vf_cons
= ETH_PF_PARAMS_VF_CONS_DEFAULT
;
2099 ecore_cxt_set_proto_cid_count(p_hwfn
, PROTOCOLID_ETH
,
2101 p_params
->num_vf_cons
);
2103 count
= p_params
->num_arfs_filters
;
2105 if (!OSAL_TEST_BIT(ECORE_MF_DISABLE_ARFS
,
2106 &p_hwfn
->p_dev
->mf_bits
))
2107 p_hwfn
->p_cxt_mngr
->arfs_count
= count
;
2115 return ECORE_SUCCESS
;
2118 /* This function is very RoCE oriented, if another protocol in the future
2119 * will want this feature we'll need to modify the function to be more generic
2121 enum _ecore_status_t
2122 ecore_cxt_dynamic_ilt_alloc(struct ecore_hwfn
*p_hwfn
,
2123 enum ecore_cxt_elem_type elem_type
,
2126 u32 reg_offset
, shadow_line
, elem_size
, hw_p_size
, elems_per_p
, line
;
2127 struct ecore_ilt_client_cfg
*p_cli
;
2128 struct ecore_ilt_cli_blk
*p_blk
;
2129 struct ecore_ptt
*p_ptt
;
2133 enum _ecore_status_t rc
= ECORE_SUCCESS
;
2135 switch (elem_type
) {
2136 case ECORE_ELEM_CXT
:
2137 p_cli
= &p_hwfn
->p_cxt_mngr
->clients
[ILT_CLI_CDUC
];
2138 elem_size
= CONN_CXT_SIZE(p_hwfn
);
2139 p_blk
= &p_cli
->pf_blks
[CDUC_BLK
];
2141 case ECORE_ELEM_SRQ
:
2142 p_cli
= &p_hwfn
->p_cxt_mngr
->clients
[ILT_CLI_TSDM
];
2143 elem_size
= SRQ_CXT_SIZE
;
2144 p_blk
= &p_cli
->pf_blks
[SRQ_BLK
];
2146 case ECORE_ELEM_TASK
:
2147 p_cli
= &p_hwfn
->p_cxt_mngr
->clients
[ILT_CLI_CDUT
];
2148 elem_size
= TYPE1_TASK_CXT_SIZE(p_hwfn
);
2149 p_blk
= &p_cli
->pf_blks
[CDUT_SEG_BLK(ECORE_CXT_ROCE_TID_SEG
)];
2152 DP_NOTICE(p_hwfn
, false,
2153 "ECORE_INVALID elem type = %d", elem_type
);
2157 /* Calculate line in ilt */
2158 hw_p_size
= p_cli
->p_size
.val
;
2159 elems_per_p
= ILT_PAGE_IN_BYTES(hw_p_size
) / elem_size
;
2160 line
= p_blk
->start_line
+ (iid
/ elems_per_p
);
2161 shadow_line
= line
- p_hwfn
->p_cxt_mngr
->pf_start_line
;
2163 /* If line is already allocated, do nothing, otherwise allocate it and
2164 * write it to the PSWRQ2 registers.
2165 * This section can be run in parallel from different contexts and thus
2166 * a mutex protection is needed.
2169 OSAL_MUTEX_ACQUIRE(&p_hwfn
->p_cxt_mngr
->mutex
);
2171 if (p_hwfn
->p_cxt_mngr
->ilt_shadow
[shadow_line
].virt_addr
)
2174 p_ptt
= ecore_ptt_acquire(p_hwfn
);
2176 DP_NOTICE(p_hwfn
, false,
2177 "ECORE_TIME_OUT on ptt acquire - dynamic allocation");
2182 p_virt
= OSAL_DMA_ALLOC_COHERENT(p_hwfn
->p_dev
,
2184 p_blk
->real_size_in_page
);
2189 OSAL_MEM_ZERO(p_virt
, p_blk
->real_size_in_page
);
2191 p_hwfn
->p_cxt_mngr
->ilt_shadow
[shadow_line
].virt_addr
= p_virt
;
2192 p_hwfn
->p_cxt_mngr
->ilt_shadow
[shadow_line
].phys_addr
= p_phys
;
2193 p_hwfn
->p_cxt_mngr
->ilt_shadow
[shadow_line
].size
=
2194 p_blk
->real_size_in_page
;
2196 /* compute absolute offset */
2197 reg_offset
= PSWRQ2_REG_ILT_MEMORY
+
2198 (line
* ILT_REG_SIZE_IN_BYTES
* ILT_ENTRY_IN_REGS
);
2201 SET_FIELD(ilt_hw_entry
, ILT_ENTRY_VALID
, 1ULL);
2202 SET_FIELD(ilt_hw_entry
,
2204 (p_hwfn
->p_cxt_mngr
->ilt_shadow
[shadow_line
].phys_addr
>> 12));
2206 /* Write via DMAE since the PSWRQ2_REG_ILT_MEMORY line is a wide-bus */
2208 ecore_dmae_host2grc(p_hwfn
, p_ptt
, (u64
)(osal_uintptr_t
)&ilt_hw_entry
,
2209 reg_offset
, sizeof(ilt_hw_entry
) / sizeof(u32
),
2210 OSAL_NULL
/* default parameters */);
2213 ecore_ptt_release(p_hwfn
, p_ptt
);
2215 OSAL_MUTEX_RELEASE(&p_hwfn
->p_cxt_mngr
->mutex
);
2220 /* This function is very RoCE oriented, if another protocol in the future
2221 * will want this feature we'll need to modify the function to be more generic
2223 static enum _ecore_status_t
2224 ecore_cxt_free_ilt_range(struct ecore_hwfn
*p_hwfn
,
2225 enum ecore_cxt_elem_type elem_type
,
2226 u32 start_iid
, u32 count
)
2228 u32 start_line
, end_line
, shadow_start_line
, shadow_end_line
;
2229 u32 reg_offset
, elem_size
, hw_p_size
, elems_per_p
;
2230 struct ecore_ilt_client_cfg
*p_cli
;
2231 struct ecore_ilt_cli_blk
*p_blk
;
2232 u32 end_iid
= start_iid
+ count
;
2233 struct ecore_ptt
*p_ptt
;
2234 u64 ilt_hw_entry
= 0;
2237 switch (elem_type
) {
2238 case ECORE_ELEM_CXT
:
2239 p_cli
= &p_hwfn
->p_cxt_mngr
->clients
[ILT_CLI_CDUC
];
2240 elem_size
= CONN_CXT_SIZE(p_hwfn
);
2241 p_blk
= &p_cli
->pf_blks
[CDUC_BLK
];
2243 case ECORE_ELEM_SRQ
:
2244 p_cli
= &p_hwfn
->p_cxt_mngr
->clients
[ILT_CLI_TSDM
];
2245 elem_size
= SRQ_CXT_SIZE
;
2246 p_blk
= &p_cli
->pf_blks
[SRQ_BLK
];
2248 case ECORE_ELEM_TASK
:
2249 p_cli
= &p_hwfn
->p_cxt_mngr
->clients
[ILT_CLI_CDUT
];
2250 elem_size
= TYPE1_TASK_CXT_SIZE(p_hwfn
);
2251 p_blk
= &p_cli
->pf_blks
[CDUT_SEG_BLK(ECORE_CXT_ROCE_TID_SEG
)];
2254 DP_NOTICE(p_hwfn
, false,
2255 "ECORE_INVALID elem type = %d", elem_type
);
2259 /* Calculate line in ilt */
2260 hw_p_size
= p_cli
->p_size
.val
;
2261 elems_per_p
= ILT_PAGE_IN_BYTES(hw_p_size
) / elem_size
;
2262 start_line
= p_blk
->start_line
+ (start_iid
/ elems_per_p
);
2263 end_line
= p_blk
->start_line
+ (end_iid
/ elems_per_p
);
2264 if (((end_iid
+ 1) / elems_per_p
) != (end_iid
/ elems_per_p
))
2267 shadow_start_line
= start_line
- p_hwfn
->p_cxt_mngr
->pf_start_line
;
2268 shadow_end_line
= end_line
- p_hwfn
->p_cxt_mngr
->pf_start_line
;
2270 p_ptt
= ecore_ptt_acquire(p_hwfn
);
2272 DP_NOTICE(p_hwfn
, false,
2273 "ECORE_TIME_OUT on ptt acquire - dynamic allocation");
2274 return ECORE_TIMEOUT
;
2277 for (i
= shadow_start_line
; i
< shadow_end_line
; i
++) {
2278 if (!p_hwfn
->p_cxt_mngr
->ilt_shadow
[i
].virt_addr
)
2281 OSAL_DMA_FREE_COHERENT(p_hwfn
->p_dev
,
2282 p_hwfn
->p_cxt_mngr
->ilt_shadow
[i
].virt_addr
,
2283 p_hwfn
->p_cxt_mngr
->ilt_shadow
[i
].phys_addr
,
2284 p_hwfn
->p_cxt_mngr
->ilt_shadow
[i
].size
);
2286 p_hwfn
->p_cxt_mngr
->ilt_shadow
[i
].virt_addr
= OSAL_NULL
;
2287 p_hwfn
->p_cxt_mngr
->ilt_shadow
[i
].phys_addr
= 0;
2288 p_hwfn
->p_cxt_mngr
->ilt_shadow
[i
].size
= 0;
2290 /* compute absolute offset */
2291 reg_offset
= PSWRQ2_REG_ILT_MEMORY
+
2292 ((start_line
++) * ILT_REG_SIZE_IN_BYTES
*
2295 /* Write via DMAE since the PSWRQ2_REG_ILT_MEMORY line is a
2298 ecore_dmae_host2grc(p_hwfn
, p_ptt
,
2299 (u64
)(osal_uintptr_t
)&ilt_hw_entry
,
2301 sizeof(ilt_hw_entry
) / sizeof(u32
),
2302 OSAL_NULL
/* default parameters */);
2305 ecore_ptt_release(p_hwfn
, p_ptt
);
2307 return ECORE_SUCCESS
;