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
33e9dcd831SSlava Shwartsman #include <linux/errno.h>
34e9dcd831SSlava Shwartsman #include <linux/err.h>
35e9dcd831SSlava Shwartsman #include <linux/completion.h>
36e9dcd831SSlava Shwartsman #include <dev/mlx5/device.h>
37e9dcd831SSlava Shwartsman #include <dev/mlx5/mlx5_fpga/core.h>
38e9dcd831SSlava Shwartsman #include <dev/mlx5/mlx5_fpga/conn.h>
39e9dcd831SSlava Shwartsman #include <dev/mlx5/mlx5_fpga/sdk.h>
40e9dcd831SSlava Shwartsman #include <dev/mlx5/mlx5_fpga/xfer.h>
41e9dcd831SSlava Shwartsman #include <dev/mlx5/mlx5_core/mlx5_core.h>
42e9dcd831SSlava Shwartsman /* #include "accel/ipsec.h" */
43e9dcd831SSlava Shwartsman
44e9dcd831SSlava Shwartsman #define MLX5_FPGA_LOAD_TIMEOUT 25000 /* msec */
45e9dcd831SSlava Shwartsman
46e9dcd831SSlava Shwartsman struct mem_transfer {
47e9dcd831SSlava Shwartsman struct mlx5_fpga_transaction t;
48e9dcd831SSlava Shwartsman struct completion comp;
49e9dcd831SSlava Shwartsman u8 status;
50e9dcd831SSlava Shwartsman };
51e9dcd831SSlava Shwartsman
52e9dcd831SSlava Shwartsman struct mlx5_fpga_conn *
mlx5_fpga_sbu_conn_create(struct mlx5_fpga_device * fdev,struct mlx5_fpga_conn_attr * attr)53e9dcd831SSlava Shwartsman mlx5_fpga_sbu_conn_create(struct mlx5_fpga_device *fdev,
54e9dcd831SSlava Shwartsman struct mlx5_fpga_conn_attr *attr)
55e9dcd831SSlava Shwartsman {
56e9dcd831SSlava Shwartsman #ifdef NOT_YET
57e9dcd831SSlava Shwartsman /* XXXKIB */
58e9dcd831SSlava Shwartsman return mlx5_fpga_conn_create(fdev, attr, MLX5_FPGA_QPC_QP_TYPE_SANDBOX_QP);
59e9dcd831SSlava Shwartsman #else
60e9dcd831SSlava Shwartsman return (NULL);
61e9dcd831SSlava Shwartsman #endif
62e9dcd831SSlava Shwartsman }
63e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_sbu_conn_create);
64e9dcd831SSlava Shwartsman
mlx5_fpga_sbu_conn_destroy(struct mlx5_fpga_conn * conn)65e9dcd831SSlava Shwartsman void mlx5_fpga_sbu_conn_destroy(struct mlx5_fpga_conn *conn)
66e9dcd831SSlava Shwartsman {
67e9dcd831SSlava Shwartsman #ifdef NOT_YET
68e9dcd831SSlava Shwartsman /* XXXKIB */
69e9dcd831SSlava Shwartsman mlx5_fpga_conn_destroy(conn);
70e9dcd831SSlava Shwartsman #endif
71e9dcd831SSlava Shwartsman }
72e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_sbu_conn_destroy);
73e9dcd831SSlava Shwartsman
mlx5_fpga_sbu_conn_sendmsg(struct mlx5_fpga_conn * conn,struct mlx5_fpga_dma_buf * buf)74e9dcd831SSlava Shwartsman int mlx5_fpga_sbu_conn_sendmsg(struct mlx5_fpga_conn *conn,
75e9dcd831SSlava Shwartsman struct mlx5_fpga_dma_buf *buf)
76e9dcd831SSlava Shwartsman {
77e9dcd831SSlava Shwartsman #ifdef NOT_YET
78e9dcd831SSlava Shwartsman /* XXXKIB */
79e9dcd831SSlava Shwartsman return mlx5_fpga_conn_send(conn, buf);
80e9dcd831SSlava Shwartsman #else
81e9dcd831SSlava Shwartsman return (0);
82e9dcd831SSlava Shwartsman #endif
83e9dcd831SSlava Shwartsman }
84e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_sbu_conn_sendmsg);
85e9dcd831SSlava Shwartsman
mem_complete(const struct mlx5_fpga_transaction * complete,u8 status)86e9dcd831SSlava Shwartsman static void mem_complete(const struct mlx5_fpga_transaction *complete,
87e9dcd831SSlava Shwartsman u8 status)
88e9dcd831SSlava Shwartsman {
89e9dcd831SSlava Shwartsman struct mem_transfer *xfer;
90e9dcd831SSlava Shwartsman
91e9dcd831SSlava Shwartsman mlx5_fpga_dbg(complete->conn->fdev,
92e9dcd831SSlava Shwartsman "transaction %p complete status %u", complete, status);
93e9dcd831SSlava Shwartsman
94e9dcd831SSlava Shwartsman xfer = container_of(complete, struct mem_transfer, t);
95e9dcd831SSlava Shwartsman xfer->status = status;
96e9dcd831SSlava Shwartsman complete_all(&xfer->comp);
97e9dcd831SSlava Shwartsman }
98e9dcd831SSlava Shwartsman
mem_transaction(struct mlx5_fpga_device * fdev,size_t size,u64 addr,void * buf,enum mlx5_fpga_direction direction)99e9dcd831SSlava Shwartsman static int mem_transaction(struct mlx5_fpga_device *fdev, size_t size, u64 addr,
100e9dcd831SSlava Shwartsman void *buf, enum mlx5_fpga_direction direction)
101e9dcd831SSlava Shwartsman {
102e9dcd831SSlava Shwartsman int ret;
103e9dcd831SSlava Shwartsman struct mem_transfer xfer;
104e9dcd831SSlava Shwartsman
105e9dcd831SSlava Shwartsman if (!fdev->shell_conn) {
106e9dcd831SSlava Shwartsman ret = -ENOTCONN;
107e9dcd831SSlava Shwartsman goto out;
108e9dcd831SSlava Shwartsman }
109e9dcd831SSlava Shwartsman
110e9dcd831SSlava Shwartsman xfer.t.data = buf;
111e9dcd831SSlava Shwartsman xfer.t.size = size;
112e9dcd831SSlava Shwartsman xfer.t.addr = addr;
113e9dcd831SSlava Shwartsman xfer.t.conn = fdev->shell_conn;
114e9dcd831SSlava Shwartsman xfer.t.direction = direction;
115e9dcd831SSlava Shwartsman xfer.t.complete1 = mem_complete;
116e9dcd831SSlava Shwartsman init_completion(&xfer.comp);
117e9dcd831SSlava Shwartsman ret = mlx5_fpga_xfer_exec(&xfer.t);
118e9dcd831SSlava Shwartsman if (ret) {
119e9dcd831SSlava Shwartsman mlx5_fpga_dbg(fdev, "Transfer execution failed: %d\n", ret);
120e9dcd831SSlava Shwartsman goto out;
121e9dcd831SSlava Shwartsman }
122e9dcd831SSlava Shwartsman wait_for_completion(&xfer.comp);
123e9dcd831SSlava Shwartsman if (xfer.status != 0)
124e9dcd831SSlava Shwartsman ret = -EIO;
125e9dcd831SSlava Shwartsman
126e9dcd831SSlava Shwartsman out:
127e9dcd831SSlava Shwartsman return ret;
128e9dcd831SSlava Shwartsman }
129e9dcd831SSlava Shwartsman
mlx5_fpga_mem_read_i2c(struct mlx5_fpga_device * fdev,size_t size,u64 addr,u8 * buf)130e9dcd831SSlava Shwartsman static int mlx5_fpga_mem_read_i2c(struct mlx5_fpga_device *fdev, size_t size,
131e9dcd831SSlava Shwartsman u64 addr, u8 *buf)
132e9dcd831SSlava Shwartsman {
133e9dcd831SSlava Shwartsman size_t max_size = MLX5_FPGA_ACCESS_REG_SIZE_MAX;
134e9dcd831SSlava Shwartsman size_t bytes_done = 0;
135e9dcd831SSlava Shwartsman u8 actual_size;
136e9dcd831SSlava Shwartsman int err = 0;
137e9dcd831SSlava Shwartsman
138e9dcd831SSlava Shwartsman if (!size)
139e9dcd831SSlava Shwartsman return -EINVAL;
140e9dcd831SSlava Shwartsman
141e9dcd831SSlava Shwartsman if (!fdev->mdev)
142e9dcd831SSlava Shwartsman return -ENOTCONN;
143e9dcd831SSlava Shwartsman
144e9dcd831SSlava Shwartsman while (bytes_done < size) {
145e9dcd831SSlava Shwartsman actual_size = min(max_size, (size - bytes_done));
146e9dcd831SSlava Shwartsman
147e9dcd831SSlava Shwartsman err = mlx5_fpga_access_reg(fdev->mdev, actual_size,
148e9dcd831SSlava Shwartsman addr + bytes_done,
149e9dcd831SSlava Shwartsman buf + bytes_done, false);
150e9dcd831SSlava Shwartsman if (err) {
151e9dcd831SSlava Shwartsman mlx5_fpga_err(fdev, "Failed to read over I2C: %d\n",
152e9dcd831SSlava Shwartsman err);
153e9dcd831SSlava Shwartsman break;
154e9dcd831SSlava Shwartsman }
155e9dcd831SSlava Shwartsman
156e9dcd831SSlava Shwartsman bytes_done += actual_size;
157e9dcd831SSlava Shwartsman }
158e9dcd831SSlava Shwartsman
159e9dcd831SSlava Shwartsman return err;
160e9dcd831SSlava Shwartsman }
161e9dcd831SSlava Shwartsman
mlx5_fpga_mem_write_i2c(struct mlx5_fpga_device * fdev,size_t size,u64 addr,u8 * buf)162e9dcd831SSlava Shwartsman static int mlx5_fpga_mem_write_i2c(struct mlx5_fpga_device *fdev, size_t size,
163e9dcd831SSlava Shwartsman u64 addr, u8 *buf)
164e9dcd831SSlava Shwartsman {
165e9dcd831SSlava Shwartsman size_t max_size = MLX5_FPGA_ACCESS_REG_SIZE_MAX;
166e9dcd831SSlava Shwartsman size_t bytes_done = 0;
167e9dcd831SSlava Shwartsman u8 actual_size;
168e9dcd831SSlava Shwartsman int err = 0;
169e9dcd831SSlava Shwartsman
170e9dcd831SSlava Shwartsman if (!size)
171e9dcd831SSlava Shwartsman return -EINVAL;
172e9dcd831SSlava Shwartsman
173e9dcd831SSlava Shwartsman if (!fdev->mdev)
174e9dcd831SSlava Shwartsman return -ENOTCONN;
175e9dcd831SSlava Shwartsman
176e9dcd831SSlava Shwartsman while (bytes_done < size) {
177e9dcd831SSlava Shwartsman actual_size = min(max_size, (size - bytes_done));
178e9dcd831SSlava Shwartsman
179e9dcd831SSlava Shwartsman err = mlx5_fpga_access_reg(fdev->mdev, actual_size,
180e9dcd831SSlava Shwartsman addr + bytes_done,
181e9dcd831SSlava Shwartsman buf + bytes_done, true);
182e9dcd831SSlava Shwartsman if (err) {
183e9dcd831SSlava Shwartsman mlx5_fpga_err(fdev, "Failed to write FPGA crspace\n");
184e9dcd831SSlava Shwartsman break;
185e9dcd831SSlava Shwartsman }
186e9dcd831SSlava Shwartsman
187e9dcd831SSlava Shwartsman bytes_done += actual_size;
188e9dcd831SSlava Shwartsman }
189e9dcd831SSlava Shwartsman
190e9dcd831SSlava Shwartsman return err;
191e9dcd831SSlava Shwartsman }
192e9dcd831SSlava Shwartsman
mlx5_fpga_mem_read(struct mlx5_fpga_device * fdev,size_t size,u64 addr,void * buf,enum mlx5_fpga_access_type access_type)193e9dcd831SSlava Shwartsman int mlx5_fpga_mem_read(struct mlx5_fpga_device *fdev, size_t size, u64 addr,
194e9dcd831SSlava Shwartsman void *buf, enum mlx5_fpga_access_type access_type)
195e9dcd831SSlava Shwartsman {
196e9dcd831SSlava Shwartsman int ret;
197e9dcd831SSlava Shwartsman
198e9dcd831SSlava Shwartsman if (access_type == MLX5_FPGA_ACCESS_TYPE_DONTCARE)
199e9dcd831SSlava Shwartsman access_type = fdev->shell_conn ? MLX5_FPGA_ACCESS_TYPE_RDMA :
200e9dcd831SSlava Shwartsman MLX5_FPGA_ACCESS_TYPE_I2C;
201e9dcd831SSlava Shwartsman
202e9dcd831SSlava Shwartsman mlx5_fpga_dbg(fdev, "Reading %zu bytes at 0x%jx over %s",
203e9dcd831SSlava Shwartsman size, (uintmax_t)addr, access_type ? "RDMA" : "I2C");
204e9dcd831SSlava Shwartsman
205e9dcd831SSlava Shwartsman switch (access_type) {
206e9dcd831SSlava Shwartsman case MLX5_FPGA_ACCESS_TYPE_RDMA:
207e9dcd831SSlava Shwartsman ret = mem_transaction(fdev, size, addr, buf, MLX5_FPGA_READ);
208e9dcd831SSlava Shwartsman if (ret)
209e9dcd831SSlava Shwartsman return ret;
210e9dcd831SSlava Shwartsman break;
211e9dcd831SSlava Shwartsman case MLX5_FPGA_ACCESS_TYPE_I2C:
212e9dcd831SSlava Shwartsman ret = mlx5_fpga_mem_read_i2c(fdev, size, addr, buf);
213e9dcd831SSlava Shwartsman if (ret)
214e9dcd831SSlava Shwartsman return ret;
215e9dcd831SSlava Shwartsman break;
216e9dcd831SSlava Shwartsman default:
217e9dcd831SSlava Shwartsman mlx5_fpga_warn(fdev, "Unexpected read access_type %u\n",
218e9dcd831SSlava Shwartsman access_type);
219e9dcd831SSlava Shwartsman return -EACCES;
220e9dcd831SSlava Shwartsman }
221e9dcd831SSlava Shwartsman
222e9dcd831SSlava Shwartsman return size;
223e9dcd831SSlava Shwartsman }
224e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_mem_read);
225e9dcd831SSlava Shwartsman
mlx5_fpga_mem_write(struct mlx5_fpga_device * fdev,size_t size,u64 addr,void * buf,enum mlx5_fpga_access_type access_type)226e9dcd831SSlava Shwartsman int mlx5_fpga_mem_write(struct mlx5_fpga_device *fdev, size_t size, u64 addr,
227e9dcd831SSlava Shwartsman void *buf, enum mlx5_fpga_access_type access_type)
228e9dcd831SSlava Shwartsman {
229e9dcd831SSlava Shwartsman int ret;
230e9dcd831SSlava Shwartsman
231e9dcd831SSlava Shwartsman if (access_type == MLX5_FPGA_ACCESS_TYPE_DONTCARE)
232e9dcd831SSlava Shwartsman access_type = fdev->shell_conn ? MLX5_FPGA_ACCESS_TYPE_RDMA :
233e9dcd831SSlava Shwartsman MLX5_FPGA_ACCESS_TYPE_I2C;
234e9dcd831SSlava Shwartsman
235e9dcd831SSlava Shwartsman mlx5_fpga_dbg(fdev, "Writing %zu bytes at 0x%jx over %s",
236e9dcd831SSlava Shwartsman size, (uintmax_t)addr, access_type ? "RDMA" : "I2C");
237e9dcd831SSlava Shwartsman
238e9dcd831SSlava Shwartsman switch (access_type) {
239e9dcd831SSlava Shwartsman case MLX5_FPGA_ACCESS_TYPE_RDMA:
240e9dcd831SSlava Shwartsman ret = mem_transaction(fdev, size, addr, buf, MLX5_FPGA_WRITE);
241e9dcd831SSlava Shwartsman if (ret)
242e9dcd831SSlava Shwartsman return ret;
243e9dcd831SSlava Shwartsman break;
244e9dcd831SSlava Shwartsman case MLX5_FPGA_ACCESS_TYPE_I2C:
245e9dcd831SSlava Shwartsman ret = mlx5_fpga_mem_write_i2c(fdev, size, addr, buf);
246e9dcd831SSlava Shwartsman if (ret)
247e9dcd831SSlava Shwartsman return ret;
248e9dcd831SSlava Shwartsman break;
249e9dcd831SSlava Shwartsman default:
250e9dcd831SSlava Shwartsman mlx5_fpga_warn(fdev, "Unexpected write access_type %u\n",
251e9dcd831SSlava Shwartsman access_type);
252e9dcd831SSlava Shwartsman return -EACCES;
253e9dcd831SSlava Shwartsman }
254e9dcd831SSlava Shwartsman
255e9dcd831SSlava Shwartsman return size;
256e9dcd831SSlava Shwartsman }
257e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_mem_write);
258e9dcd831SSlava Shwartsman
mlx5_fpga_get_sbu_caps(struct mlx5_fpga_device * fdev,int size,void * buf)259e9dcd831SSlava Shwartsman int mlx5_fpga_get_sbu_caps(struct mlx5_fpga_device *fdev, int size, void *buf)
260e9dcd831SSlava Shwartsman {
261e9dcd831SSlava Shwartsman return mlx5_fpga_sbu_caps(fdev->mdev, buf, size);
262e9dcd831SSlava Shwartsman }
263e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_get_sbu_caps);
264e9dcd831SSlava Shwartsman
mlx5_fpga_ddr_size_get(struct mlx5_fpga_device * fdev)265e9dcd831SSlava Shwartsman u64 mlx5_fpga_ddr_size_get(struct mlx5_fpga_device *fdev)
266e9dcd831SSlava Shwartsman {
267e9dcd831SSlava Shwartsman return (u64)MLX5_CAP_FPGA(fdev->mdev, fpga_ddr_size) << 10;
268e9dcd831SSlava Shwartsman }
269e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_ddr_size_get);
270e9dcd831SSlava Shwartsman
mlx5_fpga_ddr_base_get(struct mlx5_fpga_device * fdev)271e9dcd831SSlava Shwartsman u64 mlx5_fpga_ddr_base_get(struct mlx5_fpga_device *fdev)
272e9dcd831SSlava Shwartsman {
273e9dcd831SSlava Shwartsman return MLX5_CAP64_FPGA(fdev->mdev, fpga_ddr_start_addr);
274e9dcd831SSlava Shwartsman }
275e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_ddr_base_get);
276e9dcd831SSlava Shwartsman
mlx5_fpga_client_data_set(struct mlx5_fpga_device * fdev,struct mlx5_fpga_client * client,void * data)277e9dcd831SSlava Shwartsman void mlx5_fpga_client_data_set(struct mlx5_fpga_device *fdev,
278e9dcd831SSlava Shwartsman struct mlx5_fpga_client *client, void *data)
279e9dcd831SSlava Shwartsman {
280e9dcd831SSlava Shwartsman struct mlx5_fpga_client_data *context;
281e9dcd831SSlava Shwartsman
282e9dcd831SSlava Shwartsman list_for_each_entry(context, &fdev->client_data_list, list) {
283e9dcd831SSlava Shwartsman if (context->client != client)
284e9dcd831SSlava Shwartsman continue;
285e9dcd831SSlava Shwartsman context->data = data;
286e9dcd831SSlava Shwartsman return;
287e9dcd831SSlava Shwartsman }
288e9dcd831SSlava Shwartsman
289e9dcd831SSlava Shwartsman mlx5_fpga_warn(fdev, "No client context found for %s\n", client->name);
290e9dcd831SSlava Shwartsman }
291e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_client_data_set);
292e9dcd831SSlava Shwartsman
mlx5_fpga_client_data_get(struct mlx5_fpga_device * fdev,struct mlx5_fpga_client * client)293e9dcd831SSlava Shwartsman void *mlx5_fpga_client_data_get(struct mlx5_fpga_device *fdev,
294e9dcd831SSlava Shwartsman struct mlx5_fpga_client *client)
295e9dcd831SSlava Shwartsman {
296e9dcd831SSlava Shwartsman struct mlx5_fpga_client_data *context;
297e9dcd831SSlava Shwartsman void *ret = NULL;
298e9dcd831SSlava Shwartsman
299e9dcd831SSlava Shwartsman list_for_each_entry(context, &fdev->client_data_list, list) {
300e9dcd831SSlava Shwartsman if (context->client != client)
301e9dcd831SSlava Shwartsman continue;
302e9dcd831SSlava Shwartsman ret = context->data;
303e9dcd831SSlava Shwartsman goto out;
304e9dcd831SSlava Shwartsman }
305e9dcd831SSlava Shwartsman mlx5_fpga_warn(fdev, "No client context found for %s\n", client->name);
306e9dcd831SSlava Shwartsman
307e9dcd831SSlava Shwartsman out:
308e9dcd831SSlava Shwartsman return ret;
309e9dcd831SSlava Shwartsman }
310e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_client_data_get);
311e9dcd831SSlava Shwartsman
mlx5_fpga_device_query(struct mlx5_fpga_device * fdev,struct mlx5_fpga_query * query)312e9dcd831SSlava Shwartsman void mlx5_fpga_device_query(struct mlx5_fpga_device *fdev,
313e9dcd831SSlava Shwartsman struct mlx5_fpga_query *query)
314e9dcd831SSlava Shwartsman {
315e9dcd831SSlava Shwartsman unsigned long flags;
316e9dcd831SSlava Shwartsman
317e9dcd831SSlava Shwartsman spin_lock_irqsave(&fdev->state_lock, flags);
318e9dcd831SSlava Shwartsman query->image_status = fdev->image_status;
319e9dcd831SSlava Shwartsman query->admin_image = fdev->last_admin_image;
320e9dcd831SSlava Shwartsman query->oper_image = fdev->last_oper_image;
321e9dcd831SSlava Shwartsman spin_unlock_irqrestore(&fdev->state_lock, flags);
322e9dcd831SSlava Shwartsman }
323e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_device_query);
324e9dcd831SSlava Shwartsman
mlx5_fpga_device_reload_cmd(struct mlx5_fpga_device * fdev)325*c322dbafSHans Petter Selasky static int mlx5_fpga_device_reload_cmd(struct mlx5_fpga_device *fdev)
326*c322dbafSHans Petter Selasky {
327*c322dbafSHans Petter Selasky struct mlx5_core_dev *mdev = fdev->mdev;
328*c322dbafSHans Petter Selasky unsigned long timeout;
329*c322dbafSHans Petter Selasky unsigned long flags;
330*c322dbafSHans Petter Selasky int err = 0;
331*c322dbafSHans Petter Selasky
332*c322dbafSHans Petter Selasky mlx5_fpga_info(fdev, "mlx5/fpga - reload started\n");
333*c322dbafSHans Petter Selasky fdev->fdev_state = MLX5_FDEV_STATE_IN_PROGRESS;
334*c322dbafSHans Petter Selasky reinit_completion(&fdev->load_event);
335*c322dbafSHans Petter Selasky err = mlx5_fpga_ctrl_op(mdev, MLX5_FPGA_CTRL_OPERATION_RELOAD);
336*c322dbafSHans Petter Selasky if (err) {
337*c322dbafSHans Petter Selasky mlx5_fpga_err(fdev, "Failed to request reload: %d\n",
338*c322dbafSHans Petter Selasky err);
339*c322dbafSHans Petter Selasky goto out;
340*c322dbafSHans Petter Selasky }
341*c322dbafSHans Petter Selasky timeout = jiffies + msecs_to_jiffies(MLX5_FPGA_LOAD_TIMEOUT);
342*c322dbafSHans Petter Selasky err = wait_for_completion_timeout(&fdev->load_event,
343*c322dbafSHans Petter Selasky timeout - jiffies);
344*c322dbafSHans Petter Selasky if (err < 0) {
345*c322dbafSHans Petter Selasky mlx5_fpga_err(fdev, "Failed waiting for reload: %d\n", err);
346*c322dbafSHans Petter Selasky fdev->fdev_state = MLX5_FDEV_STATE_FAILURE;
347*c322dbafSHans Petter Selasky goto out;
348*c322dbafSHans Petter Selasky }
349*c322dbafSHans Petter Selasky /* Check device loaded successful */
350*c322dbafSHans Petter Selasky err = mlx5_fpga_device_start(mdev);
351*c322dbafSHans Petter Selasky if (err) {
352*c322dbafSHans Petter Selasky mlx5_fpga_err(fdev, "Failed load check for reload: %d\n", err);
353*c322dbafSHans Petter Selasky fdev->fdev_state = MLX5_FDEV_STATE_FAILURE;
354*c322dbafSHans Petter Selasky goto out;
355*c322dbafSHans Petter Selasky }
356*c322dbafSHans Petter Selasky spin_lock_irqsave(&fdev->state_lock, flags);
357*c322dbafSHans Petter Selasky fdev->fdev_state = MLX5_FDEV_STATE_SUCCESS;
358*c322dbafSHans Petter Selasky spin_unlock_irqrestore(&fdev->state_lock, flags);
359*c322dbafSHans Petter Selasky mlx5_fpga_info(fdev, "mlx5/fpga - reload ended\n");
360*c322dbafSHans Petter Selasky out:
361*c322dbafSHans Petter Selasky return err;
362*c322dbafSHans Petter Selasky }
363*c322dbafSHans Petter Selasky
mlx5_fpga_device_reload(struct mlx5_fpga_device * fdev,enum mlx5_fpga_image image)364e9dcd831SSlava Shwartsman int mlx5_fpga_device_reload(struct mlx5_fpga_device *fdev,
365e9dcd831SSlava Shwartsman enum mlx5_fpga_image image)
366e9dcd831SSlava Shwartsman {
367e9dcd831SSlava Shwartsman struct mlx5_core_dev *mdev = fdev->mdev;
368e9dcd831SSlava Shwartsman unsigned long timeout;
369e9dcd831SSlava Shwartsman unsigned long flags;
370e9dcd831SSlava Shwartsman int err = 0;
371e9dcd831SSlava Shwartsman
372e9dcd831SSlava Shwartsman spin_lock_irqsave(&fdev->state_lock, flags);
373e9dcd831SSlava Shwartsman switch (fdev->fdev_state) {
374e9dcd831SSlava Shwartsman case MLX5_FDEV_STATE_NONE:
375e9dcd831SSlava Shwartsman err = -ENODEV;
376e9dcd831SSlava Shwartsman break;
377e9dcd831SSlava Shwartsman case MLX5_FDEV_STATE_IN_PROGRESS:
378e9dcd831SSlava Shwartsman err = -EBUSY;
379e9dcd831SSlava Shwartsman break;
380e9dcd831SSlava Shwartsman case MLX5_FDEV_STATE_SUCCESS:
381e9dcd831SSlava Shwartsman case MLX5_FDEV_STATE_FAILURE:
382d82f1c13SSlava Shwartsman case MLX5_FDEV_STATE_DISCONNECTED:
383e9dcd831SSlava Shwartsman break;
384e9dcd831SSlava Shwartsman }
385e9dcd831SSlava Shwartsman spin_unlock_irqrestore(&fdev->state_lock, flags);
386e9dcd831SSlava Shwartsman if (err)
387e9dcd831SSlava Shwartsman return err;
388e9dcd831SSlava Shwartsman
389e9dcd831SSlava Shwartsman mutex_lock(&mdev->intf_state_mutex);
390*c322dbafSHans Petter Selasky
391*c322dbafSHans Petter Selasky if (image == MLX5_FPGA_IMAGE_RELOAD) {
392*c322dbafSHans Petter Selasky err = mlx5_fpga_device_reload_cmd(fdev);
393*c322dbafSHans Petter Selasky goto out;
394*c322dbafSHans Petter Selasky }
395*c322dbafSHans Petter Selasky
396e9dcd831SSlava Shwartsman clear_bit(MLX5_INTERFACE_STATE_UP, &mdev->intf_state);
397e9dcd831SSlava Shwartsman
398e9dcd831SSlava Shwartsman mlx5_unregister_device(mdev);
399e9dcd831SSlava Shwartsman /* XXXKIB mlx5_accel_ipsec_cleanup(mdev); */
400e9dcd831SSlava Shwartsman mlx5_fpga_device_stop(mdev);
401e9dcd831SSlava Shwartsman
402e9dcd831SSlava Shwartsman fdev->fdev_state = MLX5_FDEV_STATE_IN_PROGRESS;
403e9dcd831SSlava Shwartsman reinit_completion(&fdev->load_event);
404e9dcd831SSlava Shwartsman
405*c322dbafSHans Petter Selasky if (image <= MLX5_FPGA_IMAGE_FACTORY) {
406e9dcd831SSlava Shwartsman mlx5_fpga_info(fdev, "Loading from flash\n");
407e9dcd831SSlava Shwartsman err = mlx5_fpga_load(mdev, image);
408e9dcd831SSlava Shwartsman if (err) {
409e9dcd831SSlava Shwartsman mlx5_fpga_err(fdev, "Failed to request load: %d\n",
410e9dcd831SSlava Shwartsman err);
411e9dcd831SSlava Shwartsman goto out;
412e9dcd831SSlava Shwartsman }
413*c322dbafSHans Petter Selasky } else if (image == MLX5_FPGA_IMAGE_RESET) {
414e9dcd831SSlava Shwartsman mlx5_fpga_info(fdev, "Resetting\n");
415e9dcd831SSlava Shwartsman err = mlx5_fpga_ctrl_op(mdev, MLX5_FPGA_CTRL_OPERATION_RESET);
416e9dcd831SSlava Shwartsman if (err) {
417e9dcd831SSlava Shwartsman mlx5_fpga_err(fdev, "Failed to request reset: %d\n",
418e9dcd831SSlava Shwartsman err);
419e9dcd831SSlava Shwartsman goto out;
420e9dcd831SSlava Shwartsman }
421*c322dbafSHans Petter Selasky } else {
422*c322dbafSHans Petter Selasky mlx5_fpga_err(fdev, "Unknown command: %d\n",
423*c322dbafSHans Petter Selasky image);
424*c322dbafSHans Petter Selasky goto out;
425e9dcd831SSlava Shwartsman }
426e9dcd831SSlava Shwartsman
427e9dcd831SSlava Shwartsman timeout = jiffies + msecs_to_jiffies(MLX5_FPGA_LOAD_TIMEOUT);
428e9dcd831SSlava Shwartsman err = wait_for_completion_timeout(&fdev->load_event, timeout - jiffies);
429e9dcd831SSlava Shwartsman if (err < 0) {
430e9dcd831SSlava Shwartsman mlx5_fpga_err(fdev, "Failed waiting for FPGA load: %d\n", err);
431e9dcd831SSlava Shwartsman fdev->fdev_state = MLX5_FDEV_STATE_FAILURE;
432e9dcd831SSlava Shwartsman goto out;
433e9dcd831SSlava Shwartsman }
434e9dcd831SSlava Shwartsman
435e9dcd831SSlava Shwartsman err = mlx5_fpga_device_start(mdev);
436e9dcd831SSlava Shwartsman if (err) {
437e9dcd831SSlava Shwartsman mlx5_core_err(mdev, "fpga device start failed %d\n", err);
438e9dcd831SSlava Shwartsman goto out;
439e9dcd831SSlava Shwartsman }
440e9dcd831SSlava Shwartsman /* XXXKIB err = mlx5_accel_ipsec_init(mdev); */
441e9dcd831SSlava Shwartsman if (err) {
442e9dcd831SSlava Shwartsman mlx5_core_err(mdev, "IPSec device start failed %d\n", err);
443e9dcd831SSlava Shwartsman goto err_fpga;
444e9dcd831SSlava Shwartsman }
445e9dcd831SSlava Shwartsman
446e9dcd831SSlava Shwartsman err = mlx5_register_device(mdev);
447e9dcd831SSlava Shwartsman if (err) {
448e9dcd831SSlava Shwartsman mlx5_core_err(mdev, "mlx5_register_device failed %d\n", err);
449e9dcd831SSlava Shwartsman fdev->fdev_state = MLX5_FDEV_STATE_FAILURE;
450e9dcd831SSlava Shwartsman goto err_ipsec;
451e9dcd831SSlava Shwartsman }
452e9dcd831SSlava Shwartsman
453e9dcd831SSlava Shwartsman set_bit(MLX5_INTERFACE_STATE_UP, &mdev->intf_state);
454e9dcd831SSlava Shwartsman goto out;
455e9dcd831SSlava Shwartsman
456e9dcd831SSlava Shwartsman err_ipsec:
457e9dcd831SSlava Shwartsman /* XXXKIB mlx5_accel_ipsec_cleanup(mdev); */
458e9dcd831SSlava Shwartsman err_fpga:
459e9dcd831SSlava Shwartsman mlx5_fpga_device_stop(mdev);
460e9dcd831SSlava Shwartsman out:
461e9dcd831SSlava Shwartsman mutex_unlock(&mdev->intf_state_mutex);
462e9dcd831SSlava Shwartsman return err;
463e9dcd831SSlava Shwartsman }
464e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_device_reload);
465e9dcd831SSlava Shwartsman
mlx5_fpga_flash_select(struct mlx5_fpga_device * fdev,enum mlx5_fpga_image image)466e9dcd831SSlava Shwartsman int mlx5_fpga_flash_select(struct mlx5_fpga_device *fdev,
467e9dcd831SSlava Shwartsman enum mlx5_fpga_image image)
468e9dcd831SSlava Shwartsman {
469e9dcd831SSlava Shwartsman unsigned long flags;
470e9dcd831SSlava Shwartsman int err;
471e9dcd831SSlava Shwartsman
472e9dcd831SSlava Shwartsman spin_lock_irqsave(&fdev->state_lock, flags);
473e9dcd831SSlava Shwartsman switch (fdev->fdev_state) {
474e9dcd831SSlava Shwartsman case MLX5_FDEV_STATE_NONE:
475e9dcd831SSlava Shwartsman spin_unlock_irqrestore(&fdev->state_lock, flags);
476e9dcd831SSlava Shwartsman return -ENODEV;
477d82f1c13SSlava Shwartsman case MLX5_FDEV_STATE_DISCONNECTED:
478e9dcd831SSlava Shwartsman case MLX5_FDEV_STATE_IN_PROGRESS:
479e9dcd831SSlava Shwartsman case MLX5_FDEV_STATE_SUCCESS:
480e9dcd831SSlava Shwartsman case MLX5_FDEV_STATE_FAILURE:
481e9dcd831SSlava Shwartsman break;
482e9dcd831SSlava Shwartsman }
483e9dcd831SSlava Shwartsman spin_unlock_irqrestore(&fdev->state_lock, flags);
484e9dcd831SSlava Shwartsman
485e9dcd831SSlava Shwartsman err = mlx5_fpga_image_select(fdev->mdev, image);
486e9dcd831SSlava Shwartsman if (err)
487e9dcd831SSlava Shwartsman mlx5_fpga_err(fdev, "Failed to select flash image: %d\n", err);
488e9dcd831SSlava Shwartsman else
489e9dcd831SSlava Shwartsman fdev->last_admin_image = image;
490e9dcd831SSlava Shwartsman return err;
491e9dcd831SSlava Shwartsman }
492e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_flash_select);
493e9dcd831SSlava Shwartsman
mlx5_fpga_connectdisconnect(struct mlx5_fpga_device * fdev,enum mlx5_fpga_connect * connect)494d82f1c13SSlava Shwartsman int mlx5_fpga_connectdisconnect(struct mlx5_fpga_device *fdev,
495d82f1c13SSlava Shwartsman enum mlx5_fpga_connect *connect)
496d82f1c13SSlava Shwartsman {
497d82f1c13SSlava Shwartsman unsigned long flags;
498d82f1c13SSlava Shwartsman int err;
499d82f1c13SSlava Shwartsman
500d82f1c13SSlava Shwartsman spin_lock_irqsave(&fdev->state_lock, flags);
501d82f1c13SSlava Shwartsman switch (fdev->fdev_state) {
502d82f1c13SSlava Shwartsman case MLX5_FDEV_STATE_NONE:
503d82f1c13SSlava Shwartsman spin_unlock_irqrestore(&fdev->state_lock, flags);
504d82f1c13SSlava Shwartsman return -ENODEV;
505d82f1c13SSlava Shwartsman case MLX5_FDEV_STATE_IN_PROGRESS:
506d82f1c13SSlava Shwartsman case MLX5_FDEV_STATE_SUCCESS:
507d82f1c13SSlava Shwartsman case MLX5_FDEV_STATE_FAILURE:
508d82f1c13SSlava Shwartsman case MLX5_FDEV_STATE_DISCONNECTED:
509d82f1c13SSlava Shwartsman break;
510d82f1c13SSlava Shwartsman }
511d82f1c13SSlava Shwartsman spin_unlock_irqrestore(&fdev->state_lock, flags);
512d82f1c13SSlava Shwartsman
513d82f1c13SSlava Shwartsman err = mlx5_fpga_ctrl_connect(fdev->mdev, connect);
514d82f1c13SSlava Shwartsman if (err)
515d82f1c13SSlava Shwartsman mlx5_fpga_err(fdev, "Failed to connect/disconnect: %d\n", err);
516d82f1c13SSlava Shwartsman return err;
517d82f1c13SSlava Shwartsman }
518d82f1c13SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_connectdisconnect);
519d82f1c13SSlava Shwartsman
mlx5_fpga_temperature(struct mlx5_fpga_device * fdev,struct mlx5_fpga_temperature * temp)520085b35bbSSlava Shwartsman int mlx5_fpga_temperature(struct mlx5_fpga_device *fdev,
521085b35bbSSlava Shwartsman struct mlx5_fpga_temperature *temp)
522085b35bbSSlava Shwartsman {
523085b35bbSSlava Shwartsman return mlx5_fpga_query_mtmp(fdev->mdev, temp);
524085b35bbSSlava Shwartsman }
525085b35bbSSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_temperature);
526085b35bbSSlava Shwartsman
mlx5_fpga_dev(struct mlx5_fpga_device * fdev)527e9dcd831SSlava Shwartsman struct device *mlx5_fpga_dev(struct mlx5_fpga_device *fdev)
528e9dcd831SSlava Shwartsman {
529e9dcd831SSlava Shwartsman return &fdev->mdev->pdev->dev;
530e9dcd831SSlava Shwartsman }
531e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_dev);
532e9dcd831SSlava Shwartsman
mlx5_fpga_get_cap(struct mlx5_fpga_device * fdev,u32 * fpga_caps)533e9dcd831SSlava Shwartsman void mlx5_fpga_get_cap(struct mlx5_fpga_device *fdev, u32 *fpga_caps)
534e9dcd831SSlava Shwartsman {
535e9dcd831SSlava Shwartsman unsigned long flags;
536e9dcd831SSlava Shwartsman
537e9dcd831SSlava Shwartsman spin_lock_irqsave(&fdev->state_lock, flags);
538e9dcd831SSlava Shwartsman memcpy(fpga_caps, &fdev->mdev->caps.fpga, sizeof(fdev->mdev->caps.fpga));
539e9dcd831SSlava Shwartsman spin_unlock_irqrestore(&fdev->state_lock, flags);
540e9dcd831SSlava Shwartsman }
541e9dcd831SSlava Shwartsman EXPORT_SYMBOL(mlx5_fpga_get_cap);
542