xref: /freebsd/sys/dev/mlx5/mlx5_fpga/mlx5fpga_sdk.c (revision 085b35bb697bd24e12ca86865914436cb7e3c76f)
1e9dcd831SSlava Shwartsman /*-
2e9dcd831SSlava Shwartsman  * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
3e9dcd831SSlava Shwartsman  *
4e9dcd831SSlava Shwartsman  * This software is available to you under a choice of one of two
5e9dcd831SSlava Shwartsman  * licenses.  You may choose to be licensed under the terms of the GNU
6e9dcd831SSlava Shwartsman  * General Public License (GPL) Version 2, available from the file
7e9dcd831SSlava Shwartsman  * COPYING in the main directory of this source tree, or the
8e9dcd831SSlava Shwartsman  * OpenIB.org BSD license below:
9e9dcd831SSlava Shwartsman  *
10e9dcd831SSlava Shwartsman  *     Redistribution and use in source and binary forms, with or
11e9dcd831SSlava Shwartsman  *     without modification, are permitted provided that the following
12e9dcd831SSlava Shwartsman  *     conditions are met:
13e9dcd831SSlava Shwartsman  *
14e9dcd831SSlava Shwartsman  *      - Redistributions of source code must retain the above
15e9dcd831SSlava Shwartsman  *        copyright notice, this list of conditions and the following
16e9dcd831SSlava Shwartsman  *        disclaimer.
17e9dcd831SSlava Shwartsman  *
18e9dcd831SSlava Shwartsman  *      - Redistributions in binary form must reproduce the above
19e9dcd831SSlava Shwartsman  *        copyright notice, this list of conditions and the following
20e9dcd831SSlava Shwartsman  *        disclaimer in the documentation and/or other materials
21e9dcd831SSlava Shwartsman  *        provided with the distribution.
22e9dcd831SSlava Shwartsman  *
23e9dcd831SSlava Shwartsman  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24e9dcd831SSlava Shwartsman  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25e9dcd831SSlava Shwartsman  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26e9dcd831SSlava Shwartsman  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27e9dcd831SSlava Shwartsman  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28e9dcd831SSlava Shwartsman  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29e9dcd831SSlava Shwartsman  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30e9dcd831SSlava Shwartsman  * SOFTWARE.
31e9dcd831SSlava Shwartsman  *
32e9dcd831SSlava Shwartsman  * $FreeBSD$
33e9dcd831SSlava Shwartsman  */
34e9dcd831SSlava Shwartsman 
35e9dcd831SSlava Shwartsman #include <linux/errno.h>
36e9dcd831SSlava Shwartsman #include <linux/err.h>
37e9dcd831SSlava Shwartsman #include <linux/completion.h>
38e9dcd831SSlava Shwartsman #include <dev/mlx5/device.h>
39e9dcd831SSlava Shwartsman #include <dev/mlx5/mlx5_fpga/core.h>
40e9dcd831SSlava Shwartsman #include <dev/mlx5/mlx5_fpga/conn.h>
41e9dcd831SSlava Shwartsman #include <dev/mlx5/mlx5_fpga/sdk.h>
42e9dcd831SSlava Shwartsman #include <dev/mlx5/mlx5_fpga/xfer.h>
43e9dcd831SSlava Shwartsman #include <dev/mlx5/mlx5_core/mlx5_core.h>
44e9dcd831SSlava Shwartsman /* #include "accel/ipsec.h" */
45e9dcd831SSlava Shwartsman 
46e9dcd831SSlava Shwartsman #define MLX5_FPGA_LOAD_TIMEOUT 25000 /* msec */
47e9dcd831SSlava Shwartsman 
48e9dcd831SSlava Shwartsman struct mem_transfer {
49e9dcd831SSlava Shwartsman 	struct mlx5_fpga_transaction t;
50e9dcd831SSlava Shwartsman 	struct completion comp;
51e9dcd831SSlava Shwartsman 	u8 status;
52e9dcd831SSlava Shwartsman };
53e9dcd831SSlava Shwartsman 
54e9dcd831SSlava Shwartsman struct mlx5_fpga_conn *
55e9dcd831SSlava Shwartsman mlx5_fpga_sbu_conn_create(struct mlx5_fpga_device *fdev,
56e9dcd831SSlava Shwartsman 			  struct mlx5_fpga_conn_attr *attr)
57e9dcd831SSlava Shwartsman {
58e9dcd831SSlava Shwartsman #ifdef NOT_YET
59e9dcd831SSlava Shwartsman 	/* XXXKIB */
60e9dcd831SSlava Shwartsman 	return mlx5_fpga_conn_create(fdev, attr, MLX5_FPGA_QPC_QP_TYPE_SANDBOX_QP);
61e9dcd831SSlava Shwartsman #else
62e9dcd831SSlava Shwartsman 	return (NULL);
63e9dcd831SSlava Shwartsman #endif
64e9dcd831SSlava Shwartsman }
65e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_sbu_conn_create);
66e9dcd831SSlava Shwartsman 
67e9dcd831SSlava Shwartsman void mlx5_fpga_sbu_conn_destroy(struct mlx5_fpga_conn *conn)
68e9dcd831SSlava Shwartsman {
69e9dcd831SSlava Shwartsman #ifdef NOT_YET
70e9dcd831SSlava Shwartsman 	/* XXXKIB */
71e9dcd831SSlava Shwartsman 	mlx5_fpga_conn_destroy(conn);
72e9dcd831SSlava Shwartsman #endif
73e9dcd831SSlava Shwartsman }
74e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_sbu_conn_destroy);
75e9dcd831SSlava Shwartsman 
76e9dcd831SSlava Shwartsman int mlx5_fpga_sbu_conn_sendmsg(struct mlx5_fpga_conn *conn,
77e9dcd831SSlava Shwartsman 			       struct mlx5_fpga_dma_buf *buf)
78e9dcd831SSlava Shwartsman {
79e9dcd831SSlava Shwartsman #ifdef NOT_YET
80e9dcd831SSlava Shwartsman 	/* XXXKIB */
81e9dcd831SSlava Shwartsman 	return mlx5_fpga_conn_send(conn, buf);
82e9dcd831SSlava Shwartsman #else
83e9dcd831SSlava Shwartsman 	return (0);
84e9dcd831SSlava Shwartsman #endif
85e9dcd831SSlava Shwartsman }
86e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_sbu_conn_sendmsg);
87e9dcd831SSlava Shwartsman 
88e9dcd831SSlava Shwartsman static void mem_complete(const struct mlx5_fpga_transaction *complete,
89e9dcd831SSlava Shwartsman 			 u8 status)
90e9dcd831SSlava Shwartsman {
91e9dcd831SSlava Shwartsman 	struct mem_transfer *xfer;
92e9dcd831SSlava Shwartsman 
93e9dcd831SSlava Shwartsman 	mlx5_fpga_dbg(complete->conn->fdev,
94e9dcd831SSlava Shwartsman 		      "transaction %p complete status %u", complete, status);
95e9dcd831SSlava Shwartsman 
96e9dcd831SSlava Shwartsman 	xfer = container_of(complete, struct mem_transfer, t);
97e9dcd831SSlava Shwartsman 	xfer->status = status;
98e9dcd831SSlava Shwartsman 	complete_all(&xfer->comp);
99e9dcd831SSlava Shwartsman }
100e9dcd831SSlava Shwartsman 
101e9dcd831SSlava Shwartsman static int mem_transaction(struct mlx5_fpga_device *fdev, size_t size, u64 addr,
102e9dcd831SSlava Shwartsman 			   void *buf, enum mlx5_fpga_direction direction)
103e9dcd831SSlava Shwartsman {
104e9dcd831SSlava Shwartsman 	int ret;
105e9dcd831SSlava Shwartsman 	struct mem_transfer xfer;
106e9dcd831SSlava Shwartsman 
107e9dcd831SSlava Shwartsman 	if (!fdev->shell_conn) {
108e9dcd831SSlava Shwartsman 		ret = -ENOTCONN;
109e9dcd831SSlava Shwartsman 		goto out;
110e9dcd831SSlava Shwartsman 	}
111e9dcd831SSlava Shwartsman 
112e9dcd831SSlava Shwartsman 	xfer.t.data = buf;
113e9dcd831SSlava Shwartsman 	xfer.t.size = size;
114e9dcd831SSlava Shwartsman 	xfer.t.addr = addr;
115e9dcd831SSlava Shwartsman 	xfer.t.conn = fdev->shell_conn;
116e9dcd831SSlava Shwartsman 	xfer.t.direction = direction;
117e9dcd831SSlava Shwartsman 	xfer.t.complete1 = mem_complete;
118e9dcd831SSlava Shwartsman 	init_completion(&xfer.comp);
119e9dcd831SSlava Shwartsman 	ret = mlx5_fpga_xfer_exec(&xfer.t);
120e9dcd831SSlava Shwartsman 	if (ret) {
121e9dcd831SSlava Shwartsman 		mlx5_fpga_dbg(fdev, "Transfer execution failed: %d\n", ret);
122e9dcd831SSlava Shwartsman 		goto out;
123e9dcd831SSlava Shwartsman 	}
124e9dcd831SSlava Shwartsman 	wait_for_completion(&xfer.comp);
125e9dcd831SSlava Shwartsman 	if (xfer.status != 0)
126e9dcd831SSlava Shwartsman 		ret = -EIO;
127e9dcd831SSlava Shwartsman 
128e9dcd831SSlava Shwartsman out:
129e9dcd831SSlava Shwartsman 	return ret;
130e9dcd831SSlava Shwartsman }
131e9dcd831SSlava Shwartsman 
132e9dcd831SSlava Shwartsman static int mlx5_fpga_mem_read_i2c(struct mlx5_fpga_device *fdev, size_t size,
133e9dcd831SSlava Shwartsman 				  u64 addr, u8 *buf)
134e9dcd831SSlava Shwartsman {
135e9dcd831SSlava Shwartsman 	size_t max_size = MLX5_FPGA_ACCESS_REG_SIZE_MAX;
136e9dcd831SSlava Shwartsman 	size_t bytes_done = 0;
137e9dcd831SSlava Shwartsman 	u8 actual_size;
138e9dcd831SSlava Shwartsman 	int err = 0;
139e9dcd831SSlava Shwartsman 
140e9dcd831SSlava Shwartsman 	if (!size)
141e9dcd831SSlava Shwartsman 		return -EINVAL;
142e9dcd831SSlava Shwartsman 
143e9dcd831SSlava Shwartsman 	if (!fdev->mdev)
144e9dcd831SSlava Shwartsman 		return -ENOTCONN;
145e9dcd831SSlava Shwartsman 
146e9dcd831SSlava Shwartsman 	while (bytes_done < size) {
147e9dcd831SSlava Shwartsman 		actual_size = min(max_size, (size - bytes_done));
148e9dcd831SSlava Shwartsman 
149e9dcd831SSlava Shwartsman 		err = mlx5_fpga_access_reg(fdev->mdev, actual_size,
150e9dcd831SSlava Shwartsman 					   addr + bytes_done,
151e9dcd831SSlava Shwartsman 					   buf + bytes_done, false);
152e9dcd831SSlava Shwartsman 		if (err) {
153e9dcd831SSlava Shwartsman 			mlx5_fpga_err(fdev, "Failed to read over I2C: %d\n",
154e9dcd831SSlava Shwartsman 				      err);
155e9dcd831SSlava Shwartsman 			break;
156e9dcd831SSlava Shwartsman 		}
157e9dcd831SSlava Shwartsman 
158e9dcd831SSlava Shwartsman 		bytes_done += actual_size;
159e9dcd831SSlava Shwartsman 	}
160e9dcd831SSlava Shwartsman 
161e9dcd831SSlava Shwartsman 	return err;
162e9dcd831SSlava Shwartsman }
163e9dcd831SSlava Shwartsman 
164e9dcd831SSlava Shwartsman static int mlx5_fpga_mem_write_i2c(struct mlx5_fpga_device *fdev, size_t size,
165e9dcd831SSlava Shwartsman 				   u64 addr, u8 *buf)
166e9dcd831SSlava Shwartsman {
167e9dcd831SSlava Shwartsman 	size_t max_size = MLX5_FPGA_ACCESS_REG_SIZE_MAX;
168e9dcd831SSlava Shwartsman 	size_t bytes_done = 0;
169e9dcd831SSlava Shwartsman 	u8 actual_size;
170e9dcd831SSlava Shwartsman 	int err = 0;
171e9dcd831SSlava Shwartsman 
172e9dcd831SSlava Shwartsman 	if (!size)
173e9dcd831SSlava Shwartsman 		return -EINVAL;
174e9dcd831SSlava Shwartsman 
175e9dcd831SSlava Shwartsman 	if (!fdev->mdev)
176e9dcd831SSlava Shwartsman 		return -ENOTCONN;
177e9dcd831SSlava Shwartsman 
178e9dcd831SSlava Shwartsman 	while (bytes_done < size) {
179e9dcd831SSlava Shwartsman 		actual_size = min(max_size, (size - bytes_done));
180e9dcd831SSlava Shwartsman 
181e9dcd831SSlava Shwartsman 		err = mlx5_fpga_access_reg(fdev->mdev, actual_size,
182e9dcd831SSlava Shwartsman 					   addr + bytes_done,
183e9dcd831SSlava Shwartsman 					   buf + bytes_done, true);
184e9dcd831SSlava Shwartsman 		if (err) {
185e9dcd831SSlava Shwartsman 			mlx5_fpga_err(fdev, "Failed to write FPGA crspace\n");
186e9dcd831SSlava Shwartsman 			break;
187e9dcd831SSlava Shwartsman 		}
188e9dcd831SSlava Shwartsman 
189e9dcd831SSlava Shwartsman 		bytes_done += actual_size;
190e9dcd831SSlava Shwartsman 	}
191e9dcd831SSlava Shwartsman 
192e9dcd831SSlava Shwartsman 	return err;
193e9dcd831SSlava Shwartsman }
194e9dcd831SSlava Shwartsman 
195e9dcd831SSlava Shwartsman int mlx5_fpga_mem_read(struct mlx5_fpga_device *fdev, size_t size, u64 addr,
196e9dcd831SSlava Shwartsman 		       void *buf, enum mlx5_fpga_access_type access_type)
197e9dcd831SSlava Shwartsman {
198e9dcd831SSlava Shwartsman 	int ret;
199e9dcd831SSlava Shwartsman 
200e9dcd831SSlava Shwartsman 	if (access_type == MLX5_FPGA_ACCESS_TYPE_DONTCARE)
201e9dcd831SSlava Shwartsman 		access_type = fdev->shell_conn ? MLX5_FPGA_ACCESS_TYPE_RDMA :
202e9dcd831SSlava Shwartsman 						 MLX5_FPGA_ACCESS_TYPE_I2C;
203e9dcd831SSlava Shwartsman 
204e9dcd831SSlava Shwartsman 	mlx5_fpga_dbg(fdev, "Reading %zu bytes at 0x%jx over %s",
205e9dcd831SSlava Shwartsman 		      size, (uintmax_t)addr, access_type ? "RDMA" : "I2C");
206e9dcd831SSlava Shwartsman 
207e9dcd831SSlava Shwartsman 	switch (access_type) {
208e9dcd831SSlava Shwartsman 	case MLX5_FPGA_ACCESS_TYPE_RDMA:
209e9dcd831SSlava Shwartsman 		ret = mem_transaction(fdev, size, addr, buf, MLX5_FPGA_READ);
210e9dcd831SSlava Shwartsman 		if (ret)
211e9dcd831SSlava Shwartsman 			return ret;
212e9dcd831SSlava Shwartsman 		break;
213e9dcd831SSlava Shwartsman 	case MLX5_FPGA_ACCESS_TYPE_I2C:
214e9dcd831SSlava Shwartsman 		ret = mlx5_fpga_mem_read_i2c(fdev, size, addr, buf);
215e9dcd831SSlava Shwartsman 		if (ret)
216e9dcd831SSlava Shwartsman 			return ret;
217e9dcd831SSlava Shwartsman 		break;
218e9dcd831SSlava Shwartsman 	default:
219e9dcd831SSlava Shwartsman 		mlx5_fpga_warn(fdev, "Unexpected read access_type %u\n",
220e9dcd831SSlava Shwartsman 			       access_type);
221e9dcd831SSlava Shwartsman 		return -EACCES;
222e9dcd831SSlava Shwartsman 	}
223e9dcd831SSlava Shwartsman 
224e9dcd831SSlava Shwartsman 	return size;
225e9dcd831SSlava Shwartsman }
226e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_mem_read);
227e9dcd831SSlava Shwartsman 
228e9dcd831SSlava Shwartsman int mlx5_fpga_mem_write(struct mlx5_fpga_device *fdev, size_t size, u64 addr,
229e9dcd831SSlava Shwartsman 			void *buf, enum mlx5_fpga_access_type access_type)
230e9dcd831SSlava Shwartsman {
231e9dcd831SSlava Shwartsman 	int ret;
232e9dcd831SSlava Shwartsman 
233e9dcd831SSlava Shwartsman 	if (access_type == MLX5_FPGA_ACCESS_TYPE_DONTCARE)
234e9dcd831SSlava Shwartsman 		access_type = fdev->shell_conn ? MLX5_FPGA_ACCESS_TYPE_RDMA :
235e9dcd831SSlava Shwartsman 						 MLX5_FPGA_ACCESS_TYPE_I2C;
236e9dcd831SSlava Shwartsman 
237e9dcd831SSlava Shwartsman 	mlx5_fpga_dbg(fdev, "Writing %zu bytes at 0x%jx over %s",
238e9dcd831SSlava Shwartsman 		      size, (uintmax_t)addr, access_type ? "RDMA" : "I2C");
239e9dcd831SSlava Shwartsman 
240e9dcd831SSlava Shwartsman 	switch (access_type) {
241e9dcd831SSlava Shwartsman 	case MLX5_FPGA_ACCESS_TYPE_RDMA:
242e9dcd831SSlava Shwartsman 		ret = mem_transaction(fdev, size, addr, buf, MLX5_FPGA_WRITE);
243e9dcd831SSlava Shwartsman 		if (ret)
244e9dcd831SSlava Shwartsman 			return ret;
245e9dcd831SSlava Shwartsman 		break;
246e9dcd831SSlava Shwartsman 	case MLX5_FPGA_ACCESS_TYPE_I2C:
247e9dcd831SSlava Shwartsman 		ret = mlx5_fpga_mem_write_i2c(fdev, size, addr, buf);
248e9dcd831SSlava Shwartsman 		if (ret)
249e9dcd831SSlava Shwartsman 			return ret;
250e9dcd831SSlava Shwartsman 		break;
251e9dcd831SSlava Shwartsman 	default:
252e9dcd831SSlava Shwartsman 		mlx5_fpga_warn(fdev, "Unexpected write access_type %u\n",
253e9dcd831SSlava Shwartsman 			       access_type);
254e9dcd831SSlava Shwartsman 		return -EACCES;
255e9dcd831SSlava Shwartsman 	}
256e9dcd831SSlava Shwartsman 
257e9dcd831SSlava Shwartsman 	return size;
258e9dcd831SSlava Shwartsman }
259e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_mem_write);
260e9dcd831SSlava Shwartsman 
261e9dcd831SSlava Shwartsman int mlx5_fpga_get_sbu_caps(struct mlx5_fpga_device *fdev, int size, void *buf)
262e9dcd831SSlava Shwartsman {
263e9dcd831SSlava Shwartsman 	return mlx5_fpga_sbu_caps(fdev->mdev, buf, size);
264e9dcd831SSlava Shwartsman }
265e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_get_sbu_caps);
266e9dcd831SSlava Shwartsman 
267e9dcd831SSlava Shwartsman u64 mlx5_fpga_ddr_size_get(struct mlx5_fpga_device *fdev)
268e9dcd831SSlava Shwartsman {
269e9dcd831SSlava Shwartsman 	return (u64)MLX5_CAP_FPGA(fdev->mdev, fpga_ddr_size) << 10;
270e9dcd831SSlava Shwartsman }
271e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_ddr_size_get);
272e9dcd831SSlava Shwartsman 
273e9dcd831SSlava Shwartsman u64 mlx5_fpga_ddr_base_get(struct mlx5_fpga_device *fdev)
274e9dcd831SSlava Shwartsman {
275e9dcd831SSlava Shwartsman 	return MLX5_CAP64_FPGA(fdev->mdev, fpga_ddr_start_addr);
276e9dcd831SSlava Shwartsman }
277e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_ddr_base_get);
278e9dcd831SSlava Shwartsman 
279e9dcd831SSlava Shwartsman void mlx5_fpga_client_data_set(struct mlx5_fpga_device *fdev,
280e9dcd831SSlava Shwartsman 			       struct mlx5_fpga_client *client, void *data)
281e9dcd831SSlava Shwartsman {
282e9dcd831SSlava Shwartsman 	struct mlx5_fpga_client_data *context;
283e9dcd831SSlava Shwartsman 
284e9dcd831SSlava Shwartsman 	list_for_each_entry(context, &fdev->client_data_list, list) {
285e9dcd831SSlava Shwartsman 		if (context->client != client)
286e9dcd831SSlava Shwartsman 			continue;
287e9dcd831SSlava Shwartsman 		context->data = data;
288e9dcd831SSlava Shwartsman 		return;
289e9dcd831SSlava Shwartsman 	}
290e9dcd831SSlava Shwartsman 
291e9dcd831SSlava Shwartsman 	mlx5_fpga_warn(fdev, "No client context found for %s\n", client->name);
292e9dcd831SSlava Shwartsman }
293e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_client_data_set);
294e9dcd831SSlava Shwartsman 
295e9dcd831SSlava Shwartsman void *mlx5_fpga_client_data_get(struct mlx5_fpga_device *fdev,
296e9dcd831SSlava Shwartsman 				struct mlx5_fpga_client *client)
297e9dcd831SSlava Shwartsman {
298e9dcd831SSlava Shwartsman 	struct mlx5_fpga_client_data *context;
299e9dcd831SSlava Shwartsman 	void *ret = NULL;
300e9dcd831SSlava Shwartsman 
301e9dcd831SSlava Shwartsman 	list_for_each_entry(context, &fdev->client_data_list, list) {
302e9dcd831SSlava Shwartsman 		if (context->client != client)
303e9dcd831SSlava Shwartsman 			continue;
304e9dcd831SSlava Shwartsman 		ret = context->data;
305e9dcd831SSlava Shwartsman 		goto out;
306e9dcd831SSlava Shwartsman 	}
307e9dcd831SSlava Shwartsman 	mlx5_fpga_warn(fdev, "No client context found for %s\n", client->name);
308e9dcd831SSlava Shwartsman 
309e9dcd831SSlava Shwartsman out:
310e9dcd831SSlava Shwartsman 	return ret;
311e9dcd831SSlava Shwartsman }
312e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_client_data_get);
313e9dcd831SSlava Shwartsman 
314e9dcd831SSlava Shwartsman void mlx5_fpga_device_query(struct mlx5_fpga_device *fdev,
315e9dcd831SSlava Shwartsman 			    struct mlx5_fpga_query *query)
316e9dcd831SSlava Shwartsman {
317e9dcd831SSlava Shwartsman 	unsigned long flags;
318e9dcd831SSlava Shwartsman 
319e9dcd831SSlava Shwartsman 	spin_lock_irqsave(&fdev->state_lock, flags);
320e9dcd831SSlava Shwartsman 	query->image_status = fdev->image_status;
321e9dcd831SSlava Shwartsman 	query->admin_image = fdev->last_admin_image;
322e9dcd831SSlava Shwartsman 	query->oper_image = fdev->last_oper_image;
323e9dcd831SSlava Shwartsman 	spin_unlock_irqrestore(&fdev->state_lock, flags);
324e9dcd831SSlava Shwartsman }
325e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_device_query);
326e9dcd831SSlava Shwartsman 
327e9dcd831SSlava Shwartsman int mlx5_fpga_device_reload(struct mlx5_fpga_device *fdev,
328e9dcd831SSlava Shwartsman 			    enum mlx5_fpga_image image)
329e9dcd831SSlava Shwartsman {
330e9dcd831SSlava Shwartsman 	struct mlx5_core_dev *mdev = fdev->mdev;
331e9dcd831SSlava Shwartsman 	unsigned long timeout;
332e9dcd831SSlava Shwartsman 	unsigned long flags;
333e9dcd831SSlava Shwartsman 	int err = 0;
334e9dcd831SSlava Shwartsman 
335e9dcd831SSlava Shwartsman 	spin_lock_irqsave(&fdev->state_lock, flags);
336e9dcd831SSlava Shwartsman 	switch (fdev->fdev_state) {
337e9dcd831SSlava Shwartsman 	case MLX5_FDEV_STATE_NONE:
338e9dcd831SSlava Shwartsman 		err = -ENODEV;
339e9dcd831SSlava Shwartsman 		break;
340e9dcd831SSlava Shwartsman 	case MLX5_FDEV_STATE_IN_PROGRESS:
341e9dcd831SSlava Shwartsman 		err = -EBUSY;
342e9dcd831SSlava Shwartsman 		break;
343e9dcd831SSlava Shwartsman 	case MLX5_FDEV_STATE_SUCCESS:
344e9dcd831SSlava Shwartsman 	case MLX5_FDEV_STATE_FAILURE:
345e9dcd831SSlava Shwartsman 		break;
346e9dcd831SSlava Shwartsman 	}
347e9dcd831SSlava Shwartsman 	spin_unlock_irqrestore(&fdev->state_lock, flags);
348e9dcd831SSlava Shwartsman 	if (err)
349e9dcd831SSlava Shwartsman 		return err;
350e9dcd831SSlava Shwartsman 
351e9dcd831SSlava Shwartsman 	mutex_lock(&mdev->intf_state_mutex);
352e9dcd831SSlava Shwartsman 	clear_bit(MLX5_INTERFACE_STATE_UP, &mdev->intf_state);
353e9dcd831SSlava Shwartsman 
354e9dcd831SSlava Shwartsman 	mlx5_unregister_device(mdev);
355e9dcd831SSlava Shwartsman 	/* XXXKIB	mlx5_accel_ipsec_cleanup(mdev); */
356e9dcd831SSlava Shwartsman 	mlx5_fpga_device_stop(mdev);
357e9dcd831SSlava Shwartsman 
358e9dcd831SSlava Shwartsman 	fdev->fdev_state = MLX5_FDEV_STATE_IN_PROGRESS;
359e9dcd831SSlava Shwartsman 	reinit_completion(&fdev->load_event);
360e9dcd831SSlava Shwartsman 
361e9dcd831SSlava Shwartsman 	if (image <= MLX5_FPGA_IMAGE_MAX) {
362e9dcd831SSlava Shwartsman 		mlx5_fpga_info(fdev, "Loading from flash\n");
363e9dcd831SSlava Shwartsman 		err = mlx5_fpga_load(mdev, image);
364e9dcd831SSlava Shwartsman 		if (err) {
365e9dcd831SSlava Shwartsman 			mlx5_fpga_err(fdev, "Failed to request load: %d\n",
366e9dcd831SSlava Shwartsman 				      err);
367e9dcd831SSlava Shwartsman 			goto out;
368e9dcd831SSlava Shwartsman 		}
369e9dcd831SSlava Shwartsman 	} else {
370e9dcd831SSlava Shwartsman 		mlx5_fpga_info(fdev, "Resetting\n");
371e9dcd831SSlava Shwartsman 		err = mlx5_fpga_ctrl_op(mdev, MLX5_FPGA_CTRL_OPERATION_RESET);
372e9dcd831SSlava Shwartsman 		if (err) {
373e9dcd831SSlava Shwartsman 			mlx5_fpga_err(fdev, "Failed to request reset: %d\n",
374e9dcd831SSlava Shwartsman 				      err);
375e9dcd831SSlava Shwartsman 			goto out;
376e9dcd831SSlava Shwartsman 		}
377e9dcd831SSlava Shwartsman 	}
378e9dcd831SSlava Shwartsman 
379e9dcd831SSlava Shwartsman 	timeout = jiffies + msecs_to_jiffies(MLX5_FPGA_LOAD_TIMEOUT);
380e9dcd831SSlava Shwartsman 	err = wait_for_completion_timeout(&fdev->load_event, timeout - jiffies);
381e9dcd831SSlava Shwartsman 	if (err < 0) {
382e9dcd831SSlava Shwartsman 		mlx5_fpga_err(fdev, "Failed waiting for FPGA load: %d\n", err);
383e9dcd831SSlava Shwartsman 		fdev->fdev_state = MLX5_FDEV_STATE_FAILURE;
384e9dcd831SSlava Shwartsman 		goto out;
385e9dcd831SSlava Shwartsman 	}
386e9dcd831SSlava Shwartsman 
387e9dcd831SSlava Shwartsman 	err = mlx5_fpga_device_start(mdev);
388e9dcd831SSlava Shwartsman 	if (err) {
389e9dcd831SSlava Shwartsman 		mlx5_core_err(mdev, "fpga device start failed %d\n", err);
390e9dcd831SSlava Shwartsman 		goto out;
391e9dcd831SSlava Shwartsman 	}
392e9dcd831SSlava Shwartsman 	/* XXXKIB err = mlx5_accel_ipsec_init(mdev); */
393e9dcd831SSlava Shwartsman 	if (err) {
394e9dcd831SSlava Shwartsman 		mlx5_core_err(mdev, "IPSec device start failed %d\n", err);
395e9dcd831SSlava Shwartsman 		goto err_fpga;
396e9dcd831SSlava Shwartsman 	}
397e9dcd831SSlava Shwartsman 
398e9dcd831SSlava Shwartsman 	err = mlx5_register_device(mdev);
399e9dcd831SSlava Shwartsman 	if (err) {
400e9dcd831SSlava Shwartsman 		mlx5_core_err(mdev, "mlx5_register_device failed %d\n", err);
401e9dcd831SSlava Shwartsman 		fdev->fdev_state = MLX5_FDEV_STATE_FAILURE;
402e9dcd831SSlava Shwartsman 		goto err_ipsec;
403e9dcd831SSlava Shwartsman 	}
404e9dcd831SSlava Shwartsman 
405e9dcd831SSlava Shwartsman 	set_bit(MLX5_INTERFACE_STATE_UP, &mdev->intf_state);
406e9dcd831SSlava Shwartsman 	goto out;
407e9dcd831SSlava Shwartsman 
408e9dcd831SSlava Shwartsman err_ipsec:
409e9dcd831SSlava Shwartsman 	/* XXXKIB mlx5_accel_ipsec_cleanup(mdev); */
410e9dcd831SSlava Shwartsman err_fpga:
411e9dcd831SSlava Shwartsman 	mlx5_fpga_device_stop(mdev);
412e9dcd831SSlava Shwartsman out:
413e9dcd831SSlava Shwartsman 	mutex_unlock(&mdev->intf_state_mutex);
414e9dcd831SSlava Shwartsman 	return err;
415e9dcd831SSlava Shwartsman }
416e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_device_reload);
417e9dcd831SSlava Shwartsman 
418e9dcd831SSlava Shwartsman int mlx5_fpga_flash_select(struct mlx5_fpga_device *fdev,
419e9dcd831SSlava Shwartsman 			   enum mlx5_fpga_image image)
420e9dcd831SSlava Shwartsman {
421e9dcd831SSlava Shwartsman 	unsigned long flags;
422e9dcd831SSlava Shwartsman 	int err;
423e9dcd831SSlava Shwartsman 
424e9dcd831SSlava Shwartsman 	spin_lock_irqsave(&fdev->state_lock, flags);
425e9dcd831SSlava Shwartsman 	switch (fdev->fdev_state) {
426e9dcd831SSlava Shwartsman 	case MLX5_FDEV_STATE_NONE:
427e9dcd831SSlava Shwartsman 		spin_unlock_irqrestore(&fdev->state_lock, flags);
428e9dcd831SSlava Shwartsman 		return -ENODEV;
429e9dcd831SSlava Shwartsman 	case MLX5_FDEV_STATE_IN_PROGRESS:
430e9dcd831SSlava Shwartsman 	case MLX5_FDEV_STATE_SUCCESS:
431e9dcd831SSlava Shwartsman 	case MLX5_FDEV_STATE_FAILURE:
432e9dcd831SSlava Shwartsman 		break;
433e9dcd831SSlava Shwartsman 	}
434e9dcd831SSlava Shwartsman 	spin_unlock_irqrestore(&fdev->state_lock, flags);
435e9dcd831SSlava Shwartsman 
436e9dcd831SSlava Shwartsman 	err = mlx5_fpga_image_select(fdev->mdev, image);
437e9dcd831SSlava Shwartsman 	if (err)
438e9dcd831SSlava Shwartsman 		mlx5_fpga_err(fdev, "Failed to select flash image: %d\n", err);
439e9dcd831SSlava Shwartsman 	else
440e9dcd831SSlava Shwartsman 		fdev->last_admin_image = image;
441e9dcd831SSlava Shwartsman 	return err;
442e9dcd831SSlava Shwartsman }
443e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_flash_select);
444e9dcd831SSlava Shwartsman 
445*085b35bbSSlava Shwartsman int mlx5_fpga_temperature(struct mlx5_fpga_device *fdev,
446*085b35bbSSlava Shwartsman 			  struct mlx5_fpga_temperature *temp)
447*085b35bbSSlava Shwartsman {
448*085b35bbSSlava Shwartsman 	return mlx5_fpga_query_mtmp(fdev->mdev, temp);
449*085b35bbSSlava Shwartsman }
450*085b35bbSSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_temperature);
451*085b35bbSSlava Shwartsman 
452e9dcd831SSlava Shwartsman struct device *mlx5_fpga_dev(struct mlx5_fpga_device *fdev)
453e9dcd831SSlava Shwartsman {
454e9dcd831SSlava Shwartsman 	return &fdev->mdev->pdev->dev;
455e9dcd831SSlava Shwartsman }
456e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_dev);
457e9dcd831SSlava Shwartsman 
458e9dcd831SSlava Shwartsman void mlx5_fpga_get_cap(struct mlx5_fpga_device *fdev, u32 *fpga_caps)
459e9dcd831SSlava Shwartsman {
460e9dcd831SSlava Shwartsman 	unsigned long flags;
461e9dcd831SSlava Shwartsman 
462e9dcd831SSlava Shwartsman 	spin_lock_irqsave(&fdev->state_lock, flags);
463e9dcd831SSlava Shwartsman 	memcpy(fpga_caps, &fdev->mdev->caps.fpga, sizeof(fdev->mdev->caps.fpga));
464e9dcd831SSlava Shwartsman 	spin_unlock_irqrestore(&fdev->state_lock, flags);
465e9dcd831SSlava Shwartsman }
466e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_get_cap);
467