Commit | Line | Data |
---|---|---|
94990b49 AK |
1 | /* |
2 | * Copyright (c) 2017, Mellanox Technologies. All rights reserved. | |
3 | * | |
4 | * This software is available to you under a choice of one of two | |
5 | * licenses. You may choose to be licensed under the terms of the GNU | |
6 | * General Public License (GPL) Version 2, available from the file | |
7 | * COPYING in the main directory of this source tree, or the | |
8 | * OpenIB.org BSD license below: | |
9 | * | |
10 | * Redistribution and use in source and binary forms, with or | |
11 | * without modification, are permitted provided that the following | |
12 | * conditions are met: | |
13 | * | |
14 | * - Redistributions of source code must retain the above | |
15 | * copyright notice, this list of conditions and the following | |
16 | * disclaimer. | |
17 | * | |
18 | * - Redistributions in binary form must reproduce the above | |
19 | * copyright notice, this list of conditions and the following | |
20 | * disclaimer in the documentation and/or other materials | |
21 | * provided with the distribution. | |
22 | * | |
23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |
27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |
28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
30 | * SOFTWARE. | |
31 | */ | |
32 | ||
33 | #include "cmd.h" | |
34 | ||
4d4fb5dc YC |
35 | int mlx5_cmd_dump_fill_mkey(struct mlx5_core_dev *dev, u32 *mkey) |
36 | { | |
37 | u32 out[MLX5_ST_SZ_DW(query_special_contexts_out)] = {0}; | |
38 | u32 in[MLX5_ST_SZ_DW(query_special_contexts_in)] = {0}; | |
39 | int err; | |
40 | ||
41 | MLX5_SET(query_special_contexts_in, in, opcode, | |
42 | MLX5_CMD_OP_QUERY_SPECIAL_CONTEXTS); | |
43 | err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); | |
44 | if (!err) | |
45 | *mkey = MLX5_GET(query_special_contexts_out, out, | |
46 | dump_fill_mkey); | |
47 | return err; | |
48 | } | |
49 | ||
94990b49 AK |
50 | int mlx5_cmd_null_mkey(struct mlx5_core_dev *dev, u32 *null_mkey) |
51 | { | |
52 | u32 out[MLX5_ST_SZ_DW(query_special_contexts_out)] = {}; | |
53 | u32 in[MLX5_ST_SZ_DW(query_special_contexts_in)] = {}; | |
54 | int err; | |
55 | ||
56 | MLX5_SET(query_special_contexts_in, in, opcode, | |
57 | MLX5_CMD_OP_QUERY_SPECIAL_CONTEXTS); | |
58 | err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); | |
59 | if (!err) | |
60 | *null_mkey = MLX5_GET(query_special_contexts_out, out, | |
61 | null_mkey); | |
62 | return err; | |
63 | } | |
e1f24a79 | 64 | |
4a2da0b8 PP |
65 | int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point, |
66 | void *out, int out_size) | |
67 | { | |
68 | u32 in[MLX5_ST_SZ_DW(query_cong_params_in)] = { }; | |
69 | ||
70 | MLX5_SET(query_cong_params_in, in, opcode, | |
71 | MLX5_CMD_OP_QUERY_CONG_PARAMS); | |
72 | MLX5_SET(query_cong_params_in, in, cong_protocol, cong_point); | |
73 | ||
74 | return mlx5_cmd_exec(dev, in, sizeof(in), out, out_size); | |
75 | } | |
76 | ||
77 | int mlx5_cmd_modify_cong_params(struct mlx5_core_dev *dev, | |
78 | void *in, int in_size) | |
79 | { | |
80 | u32 out[MLX5_ST_SZ_DW(modify_cong_params_out)] = { }; | |
81 | ||
82 | return mlx5_cmd_exec(dev, in, in_size, out, sizeof(out)); | |
83 | } | |
24da0016 AL |
84 | |
85 | int mlx5_cmd_alloc_memic(struct mlx5_memic *memic, phys_addr_t *addr, | |
86 | u64 length, u32 alignment) | |
87 | { | |
88 | struct mlx5_core_dev *dev = memic->dev; | |
89 | u64 num_memic_hw_pages = MLX5_CAP_DEV_MEM(dev, memic_bar_size) | |
90 | >> PAGE_SHIFT; | |
91 | u64 hw_start_addr = MLX5_CAP64_DEV_MEM(dev, memic_bar_start_addr); | |
92 | u32 max_alignment = MLX5_CAP_DEV_MEM(dev, log_max_memic_addr_alignment); | |
93 | u32 num_pages = DIV_ROUND_UP(length, PAGE_SIZE); | |
94 | u32 out[MLX5_ST_SZ_DW(alloc_memic_out)] = {}; | |
95 | u32 in[MLX5_ST_SZ_DW(alloc_memic_in)] = {}; | |
96 | u32 mlx5_alignment; | |
97 | u64 page_idx = 0; | |
98 | int ret = 0; | |
99 | ||
100 | if (!length || (length & MLX5_MEMIC_ALLOC_SIZE_MASK)) | |
101 | return -EINVAL; | |
102 | ||
103 | /* mlx5 device sets alignment as 64*2^driver_value | |
104 | * so normalizing is needed. | |
105 | */ | |
106 | mlx5_alignment = (alignment < MLX5_MEMIC_BASE_ALIGN) ? 0 : | |
107 | alignment - MLX5_MEMIC_BASE_ALIGN; | |
108 | if (mlx5_alignment > max_alignment) | |
109 | return -EINVAL; | |
110 | ||
111 | MLX5_SET(alloc_memic_in, in, opcode, MLX5_CMD_OP_ALLOC_MEMIC); | |
112 | MLX5_SET(alloc_memic_in, in, range_size, num_pages * PAGE_SIZE); | |
113 | MLX5_SET(alloc_memic_in, in, memic_size, length); | |
114 | MLX5_SET(alloc_memic_in, in, log_memic_addr_alignment, | |
115 | mlx5_alignment); | |
116 | ||
cdbd0d2b | 117 | while (page_idx < num_memic_hw_pages) { |
24da0016 AL |
118 | spin_lock(&memic->memic_lock); |
119 | page_idx = bitmap_find_next_zero_area(memic->memic_alloc_pages, | |
120 | num_memic_hw_pages, | |
121 | page_idx, | |
122 | num_pages, 0); | |
123 | ||
cdbd0d2b | 124 | if (page_idx < num_memic_hw_pages) |
24da0016 AL |
125 | bitmap_set(memic->memic_alloc_pages, |
126 | page_idx, num_pages); | |
24da0016 AL |
127 | |
128 | spin_unlock(&memic->memic_lock); | |
129 | ||
cdbd0d2b AL |
130 | if (page_idx >= num_memic_hw_pages) |
131 | break; | |
24da0016 AL |
132 | |
133 | MLX5_SET64(alloc_memic_in, in, range_start_addr, | |
134 | hw_start_addr + (page_idx * PAGE_SIZE)); | |
135 | ||
136 | ret = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); | |
137 | if (ret) { | |
138 | spin_lock(&memic->memic_lock); | |
139 | bitmap_clear(memic->memic_alloc_pages, | |
140 | page_idx, num_pages); | |
141 | spin_unlock(&memic->memic_lock); | |
142 | ||
143 | if (ret == -EAGAIN) { | |
144 | page_idx++; | |
145 | continue; | |
146 | } | |
147 | ||
148 | return ret; | |
149 | } | |
150 | ||
151 | *addr = pci_resource_start(dev->pdev, 0) + | |
152 | MLX5_GET64(alloc_memic_out, out, memic_start_addr); | |
153 | ||
cdbd0d2b AL |
154 | return 0; |
155 | } | |
24da0016 | 156 | |
cdbd0d2b | 157 | return -ENOMEM; |
24da0016 AL |
158 | } |
159 | ||
160 | int mlx5_cmd_dealloc_memic(struct mlx5_memic *memic, u64 addr, u64 length) | |
161 | { | |
162 | struct mlx5_core_dev *dev = memic->dev; | |
163 | u64 hw_start_addr = MLX5_CAP64_DEV_MEM(dev, memic_bar_start_addr); | |
164 | u32 num_pages = DIV_ROUND_UP(length, PAGE_SIZE); | |
165 | u32 out[MLX5_ST_SZ_DW(dealloc_memic_out)] = {0}; | |
166 | u32 in[MLX5_ST_SZ_DW(dealloc_memic_in)] = {0}; | |
167 | u64 start_page_idx; | |
168 | int err; | |
169 | ||
170 | addr -= pci_resource_start(dev->pdev, 0); | |
171 | start_page_idx = (addr - hw_start_addr) >> PAGE_SHIFT; | |
172 | ||
173 | MLX5_SET(dealloc_memic_in, in, opcode, MLX5_CMD_OP_DEALLOC_MEMIC); | |
174 | MLX5_SET64(dealloc_memic_in, in, memic_start_addr, addr); | |
175 | MLX5_SET(dealloc_memic_in, in, memic_size, length); | |
176 | ||
177 | err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); | |
178 | ||
179 | if (!err) { | |
180 | spin_lock(&memic->memic_lock); | |
181 | bitmap_clear(memic->memic_alloc_pages, | |
182 | start_page_idx, num_pages); | |
183 | spin_unlock(&memic->memic_lock); | |
184 | } | |
185 | ||
186 | return err; | |
187 | } |