1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2 /* Copyright (c) 2015 - 2021 Intel Corporation */
10 * irdma_find_sd_index_limit - finds segment descriptor index limit
11 * @hmc_info: pointer to the HMC configuration information structure
12 * @type: type of HMC resources we're searching
13 * @idx: starting index for the object
14 * @cnt: number of objects we're trying to create
15 * @sd_idx: pointer to return index of the segment descriptor in question
16 * @sd_limit: pointer to return the maximum number of segment descriptors
18 * This function calculates the segment descriptor index and index limit
19 * for the resource defined by irdma_hmc_rsrc_type.
22 static void irdma_find_sd_index_limit(struct irdma_hmc_info
*hmc_info
, u32 type
,
23 u32 idx
, u32 cnt
, u32
*sd_idx
,
26 u64 fpm_addr
, fpm_limit
;
28 fpm_addr
= hmc_info
->hmc_obj
[(type
)].base
+
29 hmc_info
->hmc_obj
[type
].size
* idx
;
30 fpm_limit
= fpm_addr
+ hmc_info
->hmc_obj
[type
].size
* cnt
;
31 *sd_idx
= (u32
)(fpm_addr
/ IRDMA_HMC_DIRECT_BP_SIZE
);
32 *sd_limit
= (u32
)((fpm_limit
- 1) / IRDMA_HMC_DIRECT_BP_SIZE
);
37 * irdma_find_pd_index_limit - finds page descriptor index limit
38 * @hmc_info: pointer to the HMC configuration information struct
39 * @type: HMC resource type we're examining
40 * @idx: starting index for the object
41 * @cnt: number of objects we're trying to create
42 * @pd_idx: pointer to return page descriptor index
43 * @pd_limit: pointer to return page descriptor index limit
45 * Calculates the page descriptor index and index limit for the resource
46 * defined by irdma_hmc_rsrc_type.
49 static void irdma_find_pd_index_limit(struct irdma_hmc_info
*hmc_info
, u32 type
,
50 u32 idx
, u32 cnt
, u32
*pd_idx
,
53 u64 fpm_adr
, fpm_limit
;
55 fpm_adr
= hmc_info
->hmc_obj
[type
].base
+
56 hmc_info
->hmc_obj
[type
].size
* idx
;
57 fpm_limit
= fpm_adr
+ (hmc_info
)->hmc_obj
[(type
)].size
* (cnt
);
58 *pd_idx
= (u32
)(fpm_adr
/ IRDMA_HMC_PAGED_BP_SIZE
);
59 *pd_limit
= (u32
)((fpm_limit
- 1) / IRDMA_HMC_PAGED_BP_SIZE
);
64 * irdma_set_sd_entry - setup entry for sd programming
67 * @type: paged or direct sd
68 * @entry: sd entry ptr
70 static void irdma_set_sd_entry(u64 pa
, u32 idx
, enum irdma_sd_entry_type type
,
71 struct irdma_update_sd_entry
*entry
)
74 FIELD_PREP(IRDMA_PFHMC_SDDATALOW_PMSDBPCOUNT
, IRDMA_HMC_MAX_BP_COUNT
) |
75 FIELD_PREP(IRDMA_PFHMC_SDDATALOW_PMSDTYPE
,
76 type
== IRDMA_SD_TYPE_PAGED
? 0 : 1) |
77 FIELD_PREP(IRDMA_PFHMC_SDDATALOW_PMSDVALID
, 1);
79 entry
->cmd
= idx
| FIELD_PREP(IRDMA_PFHMC_SDCMD_PMSDWR
, 1) | BIT(15);
83 * irdma_clr_sd_entry - setup entry for sd clear
85 * @type: paged or direct sd
86 * @entry: sd entry ptr
88 static void irdma_clr_sd_entry(u32 idx
, enum irdma_sd_entry_type type
,
89 struct irdma_update_sd_entry
*entry
)
91 entry
->data
= FIELD_PREP(IRDMA_PFHMC_SDDATALOW_PMSDBPCOUNT
, IRDMA_HMC_MAX_BP_COUNT
) |
92 FIELD_PREP(IRDMA_PFHMC_SDDATALOW_PMSDTYPE
,
93 type
== IRDMA_SD_TYPE_PAGED
? 0 : 1);
95 entry
->cmd
= idx
| FIELD_PREP(IRDMA_PFHMC_SDCMD_PMSDWR
, 1) | BIT(15);
99 * irdma_invalidate_pf_hmc_pd - Invalidates the pd cache in the hardware for PF
100 * @dev: pointer to our device struct
101 * @sd_idx: segment descriptor index
102 * @pd_idx: page descriptor index
104 static inline void irdma_invalidate_pf_hmc_pd(struct irdma_sc_dev
*dev
, u32 sd_idx
,
107 u32 val
= FIELD_PREP(IRDMA_PFHMC_PDINV_PMSDIDX
, sd_idx
) |
108 FIELD_PREP(IRDMA_PFHMC_PDINV_PMSDPARTSEL
, 1) |
109 FIELD_PREP(IRDMA_PFHMC_PDINV_PMPDIDX
, pd_idx
);
111 writel(val
, dev
->hw_regs
[IRDMA_PFHMC_PDINV
]);
115 * irdma_hmc_sd_one - setup 1 sd entry for cqp
116 * @dev: pointer to the device structure
117 * @hmc_fn_id: hmc's function id
120 * @type: paged or direct sd
121 * @setsd: flag to set or clear sd
123 int irdma_hmc_sd_one(struct irdma_sc_dev
*dev
, u8 hmc_fn_id
, u64 pa
, u32 sd_idx
,
124 enum irdma_sd_entry_type type
, bool setsd
)
126 struct irdma_update_sds_info sdinfo
;
129 sdinfo
.hmc_fn_id
= hmc_fn_id
;
131 irdma_set_sd_entry(pa
, sd_idx
, type
, sdinfo
.entry
);
133 irdma_clr_sd_entry(sd_idx
, type
, sdinfo
.entry
);
134 return dev
->cqp
->process_cqp_sds(dev
, &sdinfo
);
138 * irdma_hmc_sd_grp - setup group of sd entries for cqp
139 * @dev: pointer to the device structure
140 * @hmc_info: pointer to the HMC configuration information struct
141 * @sd_index: sd index
142 * @sd_cnt: number of sd entries
143 * @setsd: flag to set or clear sd
145 static int irdma_hmc_sd_grp(struct irdma_sc_dev
*dev
,
146 struct irdma_hmc_info
*hmc_info
, u32 sd_index
,
147 u32 sd_cnt
, bool setsd
)
149 struct irdma_hmc_sd_entry
*sd_entry
;
150 struct irdma_update_sds_info sdinfo
= {};
155 sdinfo
.hmc_fn_id
= hmc_info
->hmc_fn_id
;
156 for (i
= sd_index
; i
< sd_index
+ sd_cnt
; i
++) {
157 sd_entry
= &hmc_info
->sd_table
.sd_entry
[i
];
158 if (!sd_entry
|| (!sd_entry
->valid
&& setsd
) ||
159 (sd_entry
->valid
&& !setsd
))
162 pa
= (sd_entry
->entry_type
== IRDMA_SD_TYPE_PAGED
) ?
163 sd_entry
->u
.pd_table
.pd_page_addr
.pa
:
164 sd_entry
->u
.bp
.addr
.pa
;
165 irdma_set_sd_entry(pa
, i
, sd_entry
->entry_type
,
166 &sdinfo
.entry
[sdinfo
.cnt
]);
168 irdma_clr_sd_entry(i
, sd_entry
->entry_type
,
169 &sdinfo
.entry
[sdinfo
.cnt
]);
172 if (sdinfo
.cnt
== IRDMA_MAX_SD_ENTRIES
) {
173 ret_code
= dev
->cqp
->process_cqp_sds(dev
, &sdinfo
);
175 ibdev_dbg(to_ibdev(dev
),
176 "HMC: sd_programming failed err=%d\n",
185 ret_code
= dev
->cqp
->process_cqp_sds(dev
, &sdinfo
);
191 * irdma_hmc_finish_add_sd_reg - program sd entries for objects
192 * @dev: pointer to the device structure
193 * @info: create obj info
195 static int irdma_hmc_finish_add_sd_reg(struct irdma_sc_dev
*dev
,
196 struct irdma_hmc_create_obj_info
*info
)
198 if (info
->start_idx
>= info
->hmc_info
->hmc_obj
[info
->rsrc_type
].cnt
)
201 if ((info
->start_idx
+ info
->count
) >
202 info
->hmc_info
->hmc_obj
[info
->rsrc_type
].cnt
)
205 if (!info
->add_sd_cnt
)
207 return irdma_hmc_sd_grp(dev
, info
->hmc_info
,
208 info
->hmc_info
->sd_indexes
[0], info
->add_sd_cnt
,
213 * irdma_sc_create_hmc_obj - allocate backing store for hmc objects
214 * @dev: pointer to the device structure
215 * @info: pointer to irdma_hmc_create_obj_info struct
217 * This will allocate memory for PDs and backing pages and populate
218 * the sd and pd entries.
220 int irdma_sc_create_hmc_obj(struct irdma_sc_dev
*dev
,
221 struct irdma_hmc_create_obj_info
*info
)
223 struct irdma_hmc_sd_entry
*sd_entry
;
225 u32 pd_idx
= 0, pd_lmt
= 0;
226 u32 pd_idx1
= 0, pd_lmt1
= 0;
228 bool pd_error
= false;
231 if (info
->start_idx
>= info
->hmc_info
->hmc_obj
[info
->rsrc_type
].cnt
)
234 if ((info
->start_idx
+ info
->count
) >
235 info
->hmc_info
->hmc_obj
[info
->rsrc_type
].cnt
) {
236 ibdev_dbg(to_ibdev(dev
),
237 "HMC: error type %u, start = %u, req cnt %u, cnt = %u\n",
238 info
->rsrc_type
, info
->start_idx
, info
->count
,
239 info
->hmc_info
->hmc_obj
[info
->rsrc_type
].cnt
);
243 irdma_find_sd_index_limit(info
->hmc_info
, info
->rsrc_type
,
244 info
->start_idx
, info
->count
, &sd_idx
,
246 if (sd_idx
>= info
->hmc_info
->sd_table
.sd_cnt
||
247 sd_lmt
> info
->hmc_info
->sd_table
.sd_cnt
) {
251 irdma_find_pd_index_limit(info
->hmc_info
, info
->rsrc_type
,
252 info
->start_idx
, info
->count
, &pd_idx
,
255 for (j
= sd_idx
; j
< sd_lmt
; j
++) {
256 ret_code
= irdma_add_sd_table_entry(dev
->hw
, info
->hmc_info
, j
,
258 IRDMA_HMC_DIRECT_BP_SIZE
);
262 sd_entry
= &info
->hmc_info
->sd_table
.sd_entry
[j
];
263 if (sd_entry
->entry_type
== IRDMA_SD_TYPE_PAGED
&&
264 (dev
->hmc_info
== info
->hmc_info
&&
265 info
->rsrc_type
!= IRDMA_HMC_IW_PBLE
)) {
266 pd_idx1
= max(pd_idx
, (j
* IRDMA_HMC_MAX_BP_COUNT
));
267 pd_lmt1
= min(pd_lmt
, (j
+ 1) * IRDMA_HMC_MAX_BP_COUNT
);
268 for (i
= pd_idx1
; i
< pd_lmt1
; i
++) {
269 /* update the pd table entry */
270 ret_code
= irdma_add_pd_table_entry(dev
,
279 while (i
&& (i
> pd_idx1
)) {
280 irdma_remove_pd_bp(dev
, info
->hmc_info
,
289 info
->hmc_info
->sd_indexes
[info
->add_sd_cnt
] = (u16
)j
;
291 sd_entry
->valid
= true;
293 return irdma_hmc_finish_add_sd_reg(dev
, info
);
296 while (j
&& (j
> sd_idx
)) {
297 sd_entry
= &info
->hmc_info
->sd_table
.sd_entry
[j
- 1];
298 switch (sd_entry
->entry_type
) {
299 case IRDMA_SD_TYPE_PAGED
:
300 pd_idx1
= max(pd_idx
, (j
- 1) * IRDMA_HMC_MAX_BP_COUNT
);
301 pd_lmt1
= min(pd_lmt
, (j
* IRDMA_HMC_MAX_BP_COUNT
));
302 for (i
= pd_idx1
; i
< pd_lmt1
; i
++)
303 irdma_prep_remove_pd_page(info
->hmc_info
, i
);
305 case IRDMA_SD_TYPE_DIRECT
:
306 irdma_prep_remove_pd_page(info
->hmc_info
, (j
- 1));
319 * irdma_finish_del_sd_reg - delete sd entries for objects
320 * @dev: pointer to the device structure
321 * @info: dele obj info
322 * @reset: true if called before reset
324 static int irdma_finish_del_sd_reg(struct irdma_sc_dev
*dev
,
325 struct irdma_hmc_del_obj_info
*info
,
328 struct irdma_hmc_sd_entry
*sd_entry
;
331 struct irdma_dma_mem
*mem
;
334 ret_code
= irdma_hmc_sd_grp(dev
, info
->hmc_info
,
335 info
->hmc_info
->sd_indexes
[0],
336 info
->del_sd_cnt
, false);
339 ibdev_dbg(to_ibdev(dev
), "HMC: error cqp sd sd_grp\n");
340 for (i
= 0; i
< info
->del_sd_cnt
; i
++) {
341 sd_idx
= info
->hmc_info
->sd_indexes
[i
];
342 sd_entry
= &info
->hmc_info
->sd_table
.sd_entry
[sd_idx
];
343 mem
= (sd_entry
->entry_type
== IRDMA_SD_TYPE_PAGED
) ?
344 &sd_entry
->u
.pd_table
.pd_page_addr
:
345 &sd_entry
->u
.bp
.addr
;
347 if (!mem
|| !mem
->va
) {
348 ibdev_dbg(to_ibdev(dev
), "HMC: error cqp sd mem\n");
350 dma_free_coherent(dev
->hw
->device
, mem
->size
, mem
->va
,
360 * irdma_sc_del_hmc_obj - remove pe hmc objects
361 * @dev: pointer to the device structure
362 * @info: pointer to irdma_hmc_del_obj_info struct
363 * @reset: true if called before reset
365 * This will de-populate the SDs and PDs. It frees
366 * the memory for PDS and backing storage. After this function is returned,
367 * caller should deallocate memory allocated previously for
368 * book-keeping information about PDs and backing storage.
370 int irdma_sc_del_hmc_obj(struct irdma_sc_dev
*dev
,
371 struct irdma_hmc_del_obj_info
*info
, bool reset
)
373 struct irdma_hmc_pd_table
*pd_table
;
375 u32 pd_idx
, pd_lmt
, rel_pd_idx
;
379 if (info
->start_idx
>= info
->hmc_info
->hmc_obj
[info
->rsrc_type
].cnt
) {
380 ibdev_dbg(to_ibdev(dev
),
381 "HMC: error start_idx[%04d] >= [type %04d].cnt[%04d]\n",
382 info
->start_idx
, info
->rsrc_type
,
383 info
->hmc_info
->hmc_obj
[info
->rsrc_type
].cnt
);
387 if ((info
->start_idx
+ info
->count
) >
388 info
->hmc_info
->hmc_obj
[info
->rsrc_type
].cnt
) {
389 ibdev_dbg(to_ibdev(dev
),
390 "HMC: error start_idx[%04d] + count %04d >= [type %04d].cnt[%04d]\n",
391 info
->start_idx
, info
->count
, info
->rsrc_type
,
392 info
->hmc_info
->hmc_obj
[info
->rsrc_type
].cnt
);
396 irdma_find_pd_index_limit(info
->hmc_info
, info
->rsrc_type
,
397 info
->start_idx
, info
->count
, &pd_idx
,
400 for (j
= pd_idx
; j
< pd_lmt
; j
++) {
401 sd_idx
= j
/ IRDMA_HMC_PD_CNT_IN_SD
;
403 if (!info
->hmc_info
->sd_table
.sd_entry
[sd_idx
].valid
)
406 if (info
->hmc_info
->sd_table
.sd_entry
[sd_idx
].entry_type
!=
410 rel_pd_idx
= j
% IRDMA_HMC_PD_CNT_IN_SD
;
411 pd_table
= &info
->hmc_info
->sd_table
.sd_entry
[sd_idx
].u
.pd_table
;
412 if (pd_table
->pd_entry
&&
413 pd_table
->pd_entry
[rel_pd_idx
].valid
) {
414 ret_code
= irdma_remove_pd_bp(dev
, info
->hmc_info
, j
);
416 ibdev_dbg(to_ibdev(dev
),
417 "HMC: remove_pd_bp error\n");
423 irdma_find_sd_index_limit(info
->hmc_info
, info
->rsrc_type
,
424 info
->start_idx
, info
->count
, &sd_idx
,
426 if (sd_idx
>= info
->hmc_info
->sd_table
.sd_cnt
||
427 sd_lmt
> info
->hmc_info
->sd_table
.sd_cnt
) {
428 ibdev_dbg(to_ibdev(dev
), "HMC: invalid sd_idx\n");
432 for (i
= sd_idx
; i
< sd_lmt
; i
++) {
433 pd_table
= &info
->hmc_info
->sd_table
.sd_entry
[i
].u
.pd_table
;
434 if (!info
->hmc_info
->sd_table
.sd_entry
[i
].valid
)
436 switch (info
->hmc_info
->sd_table
.sd_entry
[i
].entry_type
) {
437 case IRDMA_SD_TYPE_DIRECT
:
438 ret_code
= irdma_prep_remove_sd_bp(info
->hmc_info
, i
);
440 info
->hmc_info
->sd_indexes
[info
->del_sd_cnt
] =
445 case IRDMA_SD_TYPE_PAGED
:
446 ret_code
= irdma_prep_remove_pd_page(info
->hmc_info
, i
);
449 if (dev
->hmc_info
!= info
->hmc_info
&&
450 info
->rsrc_type
== IRDMA_HMC_IW_PBLE
&&
451 pd_table
->pd_entry
) {
452 kfree(pd_table
->pd_entry_virt_mem
.va
);
453 pd_table
->pd_entry
= NULL
;
455 info
->hmc_info
->sd_indexes
[info
->del_sd_cnt
] = (u16
)i
;
462 return irdma_finish_del_sd_reg(dev
, info
, reset
);
466 * irdma_add_sd_table_entry - Adds a segment descriptor to the table
467 * @hw: pointer to our hw struct
468 * @hmc_info: pointer to the HMC configuration information struct
469 * @sd_index: segment descriptor index to manipulate
470 * @type: what type of segment descriptor we're manipulating
471 * @direct_mode_sz: size to alloc in direct mode
473 int irdma_add_sd_table_entry(struct irdma_hw
*hw
,
474 struct irdma_hmc_info
*hmc_info
, u32 sd_index
,
475 enum irdma_sd_entry_type type
, u64 direct_mode_sz
)
477 struct irdma_hmc_sd_entry
*sd_entry
;
478 struct irdma_dma_mem dma_mem
;
481 sd_entry
= &hmc_info
->sd_table
.sd_entry
[sd_index
];
482 if (!sd_entry
->valid
) {
483 if (type
== IRDMA_SD_TYPE_PAGED
)
484 alloc_len
= IRDMA_HMC_PAGED_BP_SIZE
;
486 alloc_len
= direct_mode_sz
;
488 /* allocate a 4K pd page or 2M backing page */
489 dma_mem
.size
= ALIGN(alloc_len
, IRDMA_HMC_PD_BP_BUF_ALIGNMENT
);
490 dma_mem
.va
= dma_alloc_coherent(hw
->device
, dma_mem
.size
,
491 &dma_mem
.pa
, GFP_KERNEL
);
494 if (type
== IRDMA_SD_TYPE_PAGED
) {
495 struct irdma_virt_mem
*vmem
=
496 &sd_entry
->u
.pd_table
.pd_entry_virt_mem
;
498 vmem
->size
= sizeof(struct irdma_hmc_pd_entry
) * 512;
499 vmem
->va
= kzalloc(vmem
->size
, GFP_KERNEL
);
501 dma_free_coherent(hw
->device
, dma_mem
.size
,
502 dma_mem
.va
, dma_mem
.pa
);
506 sd_entry
->u
.pd_table
.pd_entry
= vmem
->va
;
508 memcpy(&sd_entry
->u
.pd_table
.pd_page_addr
, &dma_mem
,
509 sizeof(sd_entry
->u
.pd_table
.pd_page_addr
));
511 memcpy(&sd_entry
->u
.bp
.addr
, &dma_mem
,
512 sizeof(sd_entry
->u
.bp
.addr
));
514 sd_entry
->u
.bp
.sd_pd_index
= sd_index
;
517 hmc_info
->sd_table
.sd_entry
[sd_index
].entry_type
= type
;
518 hmc_info
->sd_table
.use_cnt
++;
520 if (sd_entry
->entry_type
== IRDMA_SD_TYPE_DIRECT
)
521 sd_entry
->u
.bp
.use_cnt
++;
527 * irdma_add_pd_table_entry - Adds page descriptor to the specified table
528 * @dev: pointer to our device structure
529 * @hmc_info: pointer to the HMC configuration information structure
530 * @pd_index: which page descriptor index to manipulate
531 * @rsrc_pg: if not NULL, use preallocated page instead of allocating new one.
534 * 1. Initializes the pd entry
535 * 2. Adds pd_entry in the pd_table
536 * 3. Mark the entry valid in irdma_hmc_pd_entry structure
537 * 4. Initializes the pd_entry's ref count to 1
539 * 1. The memory for pd should be pinned down, physically contiguous and
540 * aligned on 4K boundary and zeroed memory.
541 * 2. It should be 4K in size.
543 int irdma_add_pd_table_entry(struct irdma_sc_dev
*dev
,
544 struct irdma_hmc_info
*hmc_info
, u32 pd_index
,
545 struct irdma_dma_mem
*rsrc_pg
)
547 struct irdma_hmc_pd_table
*pd_table
;
548 struct irdma_hmc_pd_entry
*pd_entry
;
549 struct irdma_dma_mem mem
;
550 struct irdma_dma_mem
*page
= &mem
;
551 u32 sd_idx
, rel_pd_idx
;
555 if (pd_index
/ IRDMA_HMC_PD_CNT_IN_SD
>= hmc_info
->sd_table
.sd_cnt
)
558 sd_idx
= (pd_index
/ IRDMA_HMC_PD_CNT_IN_SD
);
559 if (hmc_info
->sd_table
.sd_entry
[sd_idx
].entry_type
!=
563 rel_pd_idx
= (pd_index
% IRDMA_HMC_PD_CNT_IN_SD
);
564 pd_table
= &hmc_info
->sd_table
.sd_entry
[sd_idx
].u
.pd_table
;
565 pd_entry
= &pd_table
->pd_entry
[rel_pd_idx
];
566 if (!pd_entry
->valid
) {
568 pd_entry
->rsrc_pg
= true;
571 page
->size
= ALIGN(IRDMA_HMC_PAGED_BP_SIZE
,
572 IRDMA_HMC_PD_BP_BUF_ALIGNMENT
);
573 page
->va
= dma_alloc_coherent(dev
->hw
->device
,
574 page
->size
, &page
->pa
,
579 pd_entry
->rsrc_pg
= false;
582 memcpy(&pd_entry
->bp
.addr
, page
, sizeof(pd_entry
->bp
.addr
));
583 pd_entry
->bp
.sd_pd_index
= pd_index
;
584 pd_entry
->bp
.entry_type
= IRDMA_SD_TYPE_PAGED
;
585 page_desc
= page
->pa
| 0x1;
586 pd_addr
= pd_table
->pd_page_addr
.va
;
587 pd_addr
+= rel_pd_idx
;
588 memcpy(pd_addr
, &page_desc
, sizeof(*pd_addr
));
589 pd_entry
->sd_index
= sd_idx
;
590 pd_entry
->valid
= true;
592 irdma_invalidate_pf_hmc_pd(dev
, sd_idx
, rel_pd_idx
);
594 pd_entry
->bp
.use_cnt
++;
600 * irdma_remove_pd_bp - remove a backing page from a page descriptor
601 * @dev: pointer to our HW structure
602 * @hmc_info: pointer to the HMC configuration information structure
603 * @idx: the page index
606 * 1. Marks the entry in pd table (for paged address mode) or in sd table
607 * (for direct address mode) invalid.
608 * 2. Write to register PMPDINV to invalidate the backing page in FV cache
609 * 3. Decrement the ref count for the pd _entry
611 * 1. Caller can deallocate the memory used by backing storage after this
614 int irdma_remove_pd_bp(struct irdma_sc_dev
*dev
,
615 struct irdma_hmc_info
*hmc_info
, u32 idx
)
617 struct irdma_hmc_pd_entry
*pd_entry
;
618 struct irdma_hmc_pd_table
*pd_table
;
619 struct irdma_hmc_sd_entry
*sd_entry
;
620 u32 sd_idx
, rel_pd_idx
;
621 struct irdma_dma_mem
*mem
;
624 sd_idx
= idx
/ IRDMA_HMC_PD_CNT_IN_SD
;
625 rel_pd_idx
= idx
% IRDMA_HMC_PD_CNT_IN_SD
;
626 if (sd_idx
>= hmc_info
->sd_table
.sd_cnt
)
629 sd_entry
= &hmc_info
->sd_table
.sd_entry
[sd_idx
];
630 if (sd_entry
->entry_type
!= IRDMA_SD_TYPE_PAGED
)
633 pd_table
= &hmc_info
->sd_table
.sd_entry
[sd_idx
].u
.pd_table
;
634 pd_entry
= &pd_table
->pd_entry
[rel_pd_idx
];
635 if (--pd_entry
->bp
.use_cnt
)
638 pd_entry
->valid
= false;
640 pd_addr
= pd_table
->pd_page_addr
.va
;
641 pd_addr
+= rel_pd_idx
;
642 memset(pd_addr
, 0, sizeof(u64
));
643 irdma_invalidate_pf_hmc_pd(dev
, sd_idx
, idx
);
645 if (!pd_entry
->rsrc_pg
) {
646 mem
= &pd_entry
->bp
.addr
;
647 if (!mem
|| !mem
->va
)
650 dma_free_coherent(dev
->hw
->device
, mem
->size
, mem
->va
,
654 if (!pd_table
->use_cnt
)
655 kfree(pd_table
->pd_entry_virt_mem
.va
);
661 * irdma_prep_remove_sd_bp - Prepares to remove a backing page from a sd entry
662 * @hmc_info: pointer to the HMC configuration information structure
663 * @idx: the page index
665 int irdma_prep_remove_sd_bp(struct irdma_hmc_info
*hmc_info
, u32 idx
)
667 struct irdma_hmc_sd_entry
*sd_entry
;
669 sd_entry
= &hmc_info
->sd_table
.sd_entry
[idx
];
670 if (--sd_entry
->u
.bp
.use_cnt
)
673 hmc_info
->sd_table
.use_cnt
--;
674 sd_entry
->valid
= false;
680 * irdma_prep_remove_pd_page - Prepares to remove a PD page from sd entry.
681 * @hmc_info: pointer to the HMC configuration information structure
682 * @idx: segment descriptor index to find the relevant page descriptor
684 int irdma_prep_remove_pd_page(struct irdma_hmc_info
*hmc_info
, u32 idx
)
686 struct irdma_hmc_sd_entry
*sd_entry
;
688 sd_entry
= &hmc_info
->sd_table
.sd_entry
[idx
];
690 if (sd_entry
->u
.pd_table
.use_cnt
)
693 sd_entry
->valid
= false;
694 hmc_info
->sd_table
.use_cnt
--;