1/*
2 * Copyright (c) 2016 Hisilicon Limited.
3 * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses.  You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 *     Redistribution and use in source and binary forms, with or
12 *     without modification, are permitted provided that the following
13 *     conditions are met:
14 *
15 *      - Redistributions of source code must retain the above
16 *        copyright notice, this list of conditions and the following
17 *        disclaimer.
18 *
19 *      - Redistributions in binary form must reproduce the above
20 *        copyright notice, this list of conditions and the following
21 *        disclaimer in the documentation and/or other materials
22 *        provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33
34#ifndef _HNS_ROCE_HEM_H
35#define _HNS_ROCE_HEM_H
36
37#define HEM_HOP_STEP_DIRECT 0xff
38
39enum {
40	/* MAP HEM(Hardware Entry Memory) */
41	HEM_TYPE_QPC = 0,
42	HEM_TYPE_MTPT,
43	HEM_TYPE_CQC,
44	HEM_TYPE_SRQC,
45	HEM_TYPE_SCCC,
46	HEM_TYPE_QPC_TIMER,
47	HEM_TYPE_CQC_TIMER,
48	HEM_TYPE_GMV,
49
50	 /* UNMAP HEM */
51	HEM_TYPE_MTT,
52	HEM_TYPE_CQE,
53	HEM_TYPE_SRQWQE,
54	HEM_TYPE_IDX,
55	HEM_TYPE_IRRL,
56	HEM_TYPE_TRRL,
57};
58
59#define check_whether_bt_num_3(type, hop_num) \
60	(type < HEM_TYPE_MTT && hop_num == 2)
61
62#define check_whether_bt_num_2(type, hop_num) \
63	((type < HEM_TYPE_MTT && hop_num == 1) || \
64	(type >= HEM_TYPE_MTT && hop_num == 2))
65
66#define check_whether_bt_num_1(type, hop_num) \
67	((type < HEM_TYPE_MTT && hop_num == HNS_ROCE_HOP_NUM_0) || \
68	(type >= HEM_TYPE_MTT && hop_num == 1) || \
69	(type >= HEM_TYPE_MTT && hop_num == HNS_ROCE_HOP_NUM_0))
70
71struct hns_roce_hem {
72	void *buf;
73	dma_addr_t dma;
74	unsigned long size;
75	refcount_t refcount;
76};
77
78struct hns_roce_hem_mhop {
79	u32	hop_num;
80	u32	buf_chunk_size;
81	u32	bt_chunk_size;
82	u32	ba_l0_num;
83	u32	l0_idx; /* level 0 base address table index */
84	u32	l1_idx; /* level 1 base address table index */
85	u32	l2_idx; /* level 2 base address table index */
86};
87
88void hns_roce_free_hem(struct hns_roce_dev *hr_dev, struct hns_roce_hem *hem);
89int hns_roce_table_get(struct hns_roce_dev *hr_dev,
90		       struct hns_roce_hem_table *table, unsigned long obj);
91void hns_roce_table_put(struct hns_roce_dev *hr_dev,
92			struct hns_roce_hem_table *table, unsigned long obj);
93void *hns_roce_table_find(struct hns_roce_dev *hr_dev,
94			  struct hns_roce_hem_table *table, unsigned long obj,
95			  dma_addr_t *dma_handle);
96int hns_roce_init_hem_table(struct hns_roce_dev *hr_dev,
97			    struct hns_roce_hem_table *table, u32 type,
98			    unsigned long obj_size, unsigned long nobj);
99void hns_roce_cleanup_hem_table(struct hns_roce_dev *hr_dev,
100				struct hns_roce_hem_table *table);
101void hns_roce_cleanup_hem(struct hns_roce_dev *hr_dev);
102int hns_roce_calc_hem_mhop(struct hns_roce_dev *hr_dev,
103			   struct hns_roce_hem_table *table, unsigned long *obj,
104			   struct hns_roce_hem_mhop *mhop);
105bool hns_roce_check_whether_mhop(struct hns_roce_dev *hr_dev, u32 type);
106
107void hns_roce_hem_list_init(struct hns_roce_hem_list *hem_list);
108int hns_roce_hem_list_calc_root_ba(const struct hns_roce_buf_region *regions,
109				   int region_cnt, int unit);
110int hns_roce_hem_list_request(struct hns_roce_dev *hr_dev,
111			      struct hns_roce_hem_list *hem_list,
112			      const struct hns_roce_buf_region *regions,
113			      int region_cnt, unsigned int bt_pg_shift);
114void hns_roce_hem_list_release(struct hns_roce_dev *hr_dev,
115			       struct hns_roce_hem_list *hem_list);
116void *hns_roce_hem_list_find_mtt(struct hns_roce_dev *hr_dev,
117				 struct hns_roce_hem_list *hem_list,
118				 int offset, int *mtt_cnt);
119
120#endif /* _HNS_ROCE_HEM_H */
121