18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci/* Authors: Bernard Metzler <bmt@zurich.ibm.com> */
48c2ecf20Sopenharmony_ci/* Copyright (c) 2008-2019, IBM Corporation */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#ifndef _SIW_MEM_H
78c2ecf20Sopenharmony_ci#define _SIW_MEM_H
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_cistruct siw_umem *siw_umem_get(u64 start, u64 len, bool writable);
108c2ecf20Sopenharmony_civoid siw_umem_release(struct siw_umem *umem, bool dirty);
118c2ecf20Sopenharmony_cistruct siw_pbl *siw_pbl_alloc(u32 num_buf);
128c2ecf20Sopenharmony_cidma_addr_t siw_pbl_get_buffer(struct siw_pbl *pbl, u64 off, int *len, int *idx);
138c2ecf20Sopenharmony_cistruct siw_mem *siw_mem_id2obj(struct siw_device *sdev, int stag_index);
148c2ecf20Sopenharmony_ciint siw_mem_add(struct siw_device *sdev, struct siw_mem *m);
158c2ecf20Sopenharmony_ciint siw_invalidate_stag(struct ib_pd *pd, u32 stag);
168c2ecf20Sopenharmony_ciint siw_check_mem(struct ib_pd *pd, struct siw_mem *mem, u64 addr,
178c2ecf20Sopenharmony_ci		  enum ib_access_flags perms, int len);
188c2ecf20Sopenharmony_ciint siw_check_sge(struct ib_pd *pd, struct siw_sge *sge,
198c2ecf20Sopenharmony_ci		  struct siw_mem *mem[], enum ib_access_flags perms,
208c2ecf20Sopenharmony_ci		  u32 off, int len);
218c2ecf20Sopenharmony_civoid siw_wqe_put_mem(struct siw_wqe *wqe, enum siw_opcode op);
228c2ecf20Sopenharmony_ciint siw_mr_add_mem(struct siw_mr *mr, struct ib_pd *pd, void *mem_obj,
238c2ecf20Sopenharmony_ci		   u64 start, u64 len, int rights);
248c2ecf20Sopenharmony_civoid siw_mr_drop_mem(struct siw_mr *mr);
258c2ecf20Sopenharmony_civoid siw_free_mem(struct kref *ref);
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_cistatic inline void siw_mem_put(struct siw_mem *mem)
288c2ecf20Sopenharmony_ci{
298c2ecf20Sopenharmony_ci	kref_put(&mem->ref, siw_free_mem);
308c2ecf20Sopenharmony_ci}
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_cistatic inline struct siw_mr *siw_mem2mr(struct siw_mem *m)
338c2ecf20Sopenharmony_ci{
348c2ecf20Sopenharmony_ci	return container_of(m, struct siw_mr, mem);
358c2ecf20Sopenharmony_ci}
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_cistatic inline void siw_unref_mem_sgl(struct siw_mem **mem, unsigned int num_sge)
388c2ecf20Sopenharmony_ci{
398c2ecf20Sopenharmony_ci	while (num_sge) {
408c2ecf20Sopenharmony_ci		if (*mem == NULL)
418c2ecf20Sopenharmony_ci			break;
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci		siw_mem_put(*mem);
448c2ecf20Sopenharmony_ci		*mem = NULL;
458c2ecf20Sopenharmony_ci		mem++;
468c2ecf20Sopenharmony_ci		num_sge--;
478c2ecf20Sopenharmony_ci	}
488c2ecf20Sopenharmony_ci}
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci#define CHUNK_SHIFT 9 /* sets number of pages per chunk */
518c2ecf20Sopenharmony_ci#define PAGES_PER_CHUNK (_AC(1, UL) << CHUNK_SHIFT)
528c2ecf20Sopenharmony_ci#define CHUNK_MASK (~(PAGES_PER_CHUNK - 1))
538c2ecf20Sopenharmony_ci#define PAGE_CHUNK_SIZE (PAGES_PER_CHUNK * sizeof(struct page *))
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci/*
568c2ecf20Sopenharmony_ci * siw_get_upage()
578c2ecf20Sopenharmony_ci *
588c2ecf20Sopenharmony_ci * Get page pointer for address on given umem.
598c2ecf20Sopenharmony_ci *
608c2ecf20Sopenharmony_ci * @umem: two dimensional list of page pointers
618c2ecf20Sopenharmony_ci * @addr: user virtual address
628c2ecf20Sopenharmony_ci */
638c2ecf20Sopenharmony_cistatic inline struct page *siw_get_upage(struct siw_umem *umem, u64 addr)
648c2ecf20Sopenharmony_ci{
658c2ecf20Sopenharmony_ci	unsigned int page_idx = (addr - umem->fp_addr) >> PAGE_SHIFT,
668c2ecf20Sopenharmony_ci		     chunk_idx = page_idx >> CHUNK_SHIFT,
678c2ecf20Sopenharmony_ci		     page_in_chunk = page_idx & ~CHUNK_MASK;
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci	if (likely(page_idx < umem->num_pages))
708c2ecf20Sopenharmony_ci		return umem->page_chunk[chunk_idx].plist[page_in_chunk];
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci	return NULL;
738c2ecf20Sopenharmony_ci}
748c2ecf20Sopenharmony_ci#endif
75