xref: /freebsd-src/sys/dev/mlx5/mlx5_fpga_tools/mlx5fpga_tools_char.c (revision 95ee2897e98f5d444f26ed2334cc7c439f9c16c6)
1d50c55f1SSlava Shwartsman /*-
2d50c55f1SSlava Shwartsman  * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
3d50c55f1SSlava Shwartsman  *
4d50c55f1SSlava Shwartsman  * This software is available to you under a choice of one of two
5d50c55f1SSlava Shwartsman  * licenses.  You may choose to be licensed under the terms of the GNU
6d50c55f1SSlava Shwartsman  * General Public License (GPL) Version 2, available from the file
7d50c55f1SSlava Shwartsman  * COPYING in the main directory of this source tree, or the
8d50c55f1SSlava Shwartsman  * OpenIB.org BSD license below:
9d50c55f1SSlava Shwartsman  *
10d50c55f1SSlava Shwartsman  *     Redistribution and use in source and binary forms, with or
11d50c55f1SSlava Shwartsman  *     without modification, are permitted provided that the following
12d50c55f1SSlava Shwartsman  *     conditions are met:
13d50c55f1SSlava Shwartsman  *
14d50c55f1SSlava Shwartsman  *      - Redistributions of source code must retain the above
15d50c55f1SSlava Shwartsman  *        copyright notice, this list of conditions and the following
16d50c55f1SSlava Shwartsman  *        disclaimer.
17d50c55f1SSlava Shwartsman  *
18d50c55f1SSlava Shwartsman  *      - Redistributions in binary form must reproduce the above
19d50c55f1SSlava Shwartsman  *        copyright notice, this list of conditions and the following
20d50c55f1SSlava Shwartsman  *        disclaimer in the documentation and/or other materials
21d50c55f1SSlava Shwartsman  *        provided with the distribution.
22d50c55f1SSlava Shwartsman  *
23d50c55f1SSlava Shwartsman  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24d50c55f1SSlava Shwartsman  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25d50c55f1SSlava Shwartsman  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26d50c55f1SSlava Shwartsman  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27d50c55f1SSlava Shwartsman  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28d50c55f1SSlava Shwartsman  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29d50c55f1SSlava Shwartsman  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30d50c55f1SSlava Shwartsman  * SOFTWARE.
31d50c55f1SSlava Shwartsman  */
32d50c55f1SSlava Shwartsman 
33d50c55f1SSlava Shwartsman #include <sys/param.h>
34d50c55f1SSlava Shwartsman #include <sys/systm.h>
35d50c55f1SSlava Shwartsman #include <sys/conf.h>
36d50c55f1SSlava Shwartsman #include <dev/mlx5/mlx5io.h>
37d50c55f1SSlava Shwartsman #include <dev/mlx5/mlx5_fpga_tools/tools_char.h>
38d50c55f1SSlava Shwartsman 
39d50c55f1SSlava Shwartsman #define CHUNK_SIZE (128 * 1024)
40d50c55f1SSlava Shwartsman 
41d50c55f1SSlava Shwartsman struct tools_context {
42d50c55f1SSlava Shwartsman 	struct mlx5_fpga_tools_dev *tdev;
43d50c55f1SSlava Shwartsman 	enum mlx5_fpga_access_type access_type;
44d50c55f1SSlava Shwartsman };
45d50c55f1SSlava Shwartsman 
46d50c55f1SSlava Shwartsman static void
tools_char_ctx_dtor(void * data)47d50c55f1SSlava Shwartsman tools_char_ctx_dtor(void *data)
48d50c55f1SSlava Shwartsman {
49d50c55f1SSlava Shwartsman 
50d50c55f1SSlava Shwartsman 	free(data, M_DEVBUF);
51d50c55f1SSlava Shwartsman }
52d50c55f1SSlava Shwartsman 
53d50c55f1SSlava Shwartsman static int
tools_char_open(struct cdev * dev,int oflags,int devtype,struct thread * td)54d50c55f1SSlava Shwartsman tools_char_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
55d50c55f1SSlava Shwartsman {
56d50c55f1SSlava Shwartsman 	struct tools_context *context;
57d50c55f1SSlava Shwartsman 
58d50c55f1SSlava Shwartsman 	context = malloc(sizeof(*context), M_DEVBUF, M_WAITOK);
59d50c55f1SSlava Shwartsman 	context->tdev = dev->si_drv1;
60d50c55f1SSlava Shwartsman 	context->access_type = MLX5_FPGA_ACCESS_TYPE_DONTCARE;
61d50c55f1SSlava Shwartsman 	devfs_set_cdevpriv(context, tools_char_ctx_dtor);
62d50c55f1SSlava Shwartsman 	return (0);
63d50c55f1SSlava Shwartsman }
64d50c55f1SSlava Shwartsman 
65d50c55f1SSlava Shwartsman static int
mem_read(struct mlx5_fpga_tools_dev * tdev,void * buf,size_t count,u64 address,enum mlx5_fpga_access_type access_type,size_t * retcnt)66d50c55f1SSlava Shwartsman mem_read(struct mlx5_fpga_tools_dev *tdev, void *buf, size_t count,
67d50c55f1SSlava Shwartsman     u64 address, enum mlx5_fpga_access_type access_type, size_t *retcnt)
68d50c55f1SSlava Shwartsman {
69d50c55f1SSlava Shwartsman 	int ret;
70d50c55f1SSlava Shwartsman 
71d50c55f1SSlava Shwartsman 	ret = sx_xlock_sig(&tdev->lock);
72d50c55f1SSlava Shwartsman 	if (ret != 0)
73d50c55f1SSlava Shwartsman 		return (ret);
74d50c55f1SSlava Shwartsman 	ret = mlx5_fpga_mem_read(tdev->fdev, count, address, buf, access_type);
75d50c55f1SSlava Shwartsman 	sx_xunlock(&tdev->lock);
76d50c55f1SSlava Shwartsman 	if (ret < 0) {
77d50c55f1SSlava Shwartsman 		dev_dbg(mlx5_fpga_dev(tdev->fdev),
78d50c55f1SSlava Shwartsman 			"Failed to read %zu bytes at address 0x%jx: %d\n",
79d50c55f1SSlava Shwartsman 			count, (uintmax_t)address, ret);
80d50c55f1SSlava Shwartsman 		return (-ret);
81d50c55f1SSlava Shwartsman 	}
82d50c55f1SSlava Shwartsman 	*retcnt = ret;
83d50c55f1SSlava Shwartsman 	return (0);
84d50c55f1SSlava Shwartsman }
85d50c55f1SSlava Shwartsman 
86d50c55f1SSlava Shwartsman static int
mem_write(struct mlx5_fpga_tools_dev * tdev,void * buf,size_t count,u64 address,enum mlx5_fpga_access_type access_type,size_t * retcnt)87d50c55f1SSlava Shwartsman mem_write(struct mlx5_fpga_tools_dev *tdev, void *buf, size_t count,
88d50c55f1SSlava Shwartsman     u64 address, enum mlx5_fpga_access_type access_type, size_t *retcnt)
89d50c55f1SSlava Shwartsman {
90d50c55f1SSlava Shwartsman 	int ret;
91d50c55f1SSlava Shwartsman 
92d50c55f1SSlava Shwartsman 	ret = sx_xlock_sig(&tdev->lock);
93d50c55f1SSlava Shwartsman 	if (ret != 0)
94d50c55f1SSlava Shwartsman 		return (ret);
95d50c55f1SSlava Shwartsman 	ret = mlx5_fpga_mem_write(tdev->fdev, count, address, buf, access_type);
96d50c55f1SSlava Shwartsman 	sx_xunlock(&tdev->lock);
97d50c55f1SSlava Shwartsman 	if (ret < 0) {
98d50c55f1SSlava Shwartsman 		dev_dbg(mlx5_fpga_dev(tdev->fdev),
99d50c55f1SSlava Shwartsman 			"Failed to write %zu bytes at address 0x%jx: %d\n",
100d50c55f1SSlava Shwartsman 			count, (uintmax_t)address, ret);
101d50c55f1SSlava Shwartsman 		return (-ret);
102d50c55f1SSlava Shwartsman 	}
103d50c55f1SSlava Shwartsman 	*retcnt = ret;
104d50c55f1SSlava Shwartsman 	return (0);
105d50c55f1SSlava Shwartsman }
106d50c55f1SSlava Shwartsman 
107d50c55f1SSlava Shwartsman static void
tools_char_llseek(struct tools_context * context,struct uio * uio,ssize_t * len)108d50c55f1SSlava Shwartsman tools_char_llseek(struct tools_context *context, struct uio *uio, ssize_t *len)
109d50c55f1SSlava Shwartsman {
110d50c55f1SSlava Shwartsman 	uint64_t fbase, fsize;
111d50c55f1SSlava Shwartsman 	size_t llen;
112d50c55f1SSlava Shwartsman 
113d50c55f1SSlava Shwartsman 	llen = uio->uio_resid;
114d50c55f1SSlava Shwartsman 	if (llen < 1) {
115d50c55f1SSlava Shwartsman 		*len = 0;
116d50c55f1SSlava Shwartsman 		return;
117d50c55f1SSlava Shwartsman 	}
118d50c55f1SSlava Shwartsman 	if (llen > CHUNK_SIZE)
119d50c55f1SSlava Shwartsman 		llen = CHUNK_SIZE;
120d50c55f1SSlava Shwartsman 	fbase = mlx5_fpga_ddr_base_get(context->tdev->fdev);
121d50c55f1SSlava Shwartsman 	fsize = mlx5_fpga_ddr_size_get(context->tdev->fdev);
122d50c55f1SSlava Shwartsman 	if (uio->uio_offset > fbase)
123d50c55f1SSlava Shwartsman 		*len = 0;
124d50c55f1SSlava Shwartsman 	else if (uio->uio_offset + *len > fbase + fsize)
125d50c55f1SSlava Shwartsman 		*len = fbase + fsize - uio->uio_offset;
126d50c55f1SSlava Shwartsman 	else
127d50c55f1SSlava Shwartsman 		*len = llen;
128d50c55f1SSlava Shwartsman }
129d50c55f1SSlava Shwartsman 
130d50c55f1SSlava Shwartsman static int
tools_char_read(struct cdev * dev,struct uio * uio,int ioflag)131d50c55f1SSlava Shwartsman tools_char_read(struct cdev *dev, struct uio *uio, int ioflag)
132d50c55f1SSlava Shwartsman {
133d50c55f1SSlava Shwartsman 	struct tools_context *context;
134d50c55f1SSlava Shwartsman 	void *kbuf;
135d50c55f1SSlava Shwartsman 	size_t len, len1;
136d50c55f1SSlava Shwartsman 	int ret;
137d50c55f1SSlava Shwartsman 
138d50c55f1SSlava Shwartsman 	ret = devfs_get_cdevpriv((void **)&context);
139d50c55f1SSlava Shwartsman 	if (ret != 0)
140d50c55f1SSlava Shwartsman 		return (ret);
141d50c55f1SSlava Shwartsman 	dev_dbg(mlx5_fpga_dev(context->tdev->fdev),
142d50c55f1SSlava Shwartsman 	    "tools char device reading %zu bytes at 0x%jx\n", uio->uio_resid,
143d50c55f1SSlava Shwartsman 	     (uintmax_t)uio->uio_offset);
144d50c55f1SSlava Shwartsman 
145d50c55f1SSlava Shwartsman 	tools_char_llseek(context, uio, &len);
146d50c55f1SSlava Shwartsman 	if (len == 0)
147d50c55f1SSlava Shwartsman 		return (0);
148d50c55f1SSlava Shwartsman 
149d50c55f1SSlava Shwartsman 	kbuf = malloc(len, M_DEVBUF, M_WAITOK);
150d50c55f1SSlava Shwartsman 	ret = mem_read(context->tdev, kbuf, len, uio->uio_offset,
151d50c55f1SSlava Shwartsman 	    context->access_type, &len1);
152d50c55f1SSlava Shwartsman 	if (ret == 0)
153d50c55f1SSlava Shwartsman 		ret = uiomove(kbuf, len1, uio);
154d50c55f1SSlava Shwartsman 	free(kbuf, M_DEVBUF);
155d50c55f1SSlava Shwartsman 	return (ret);
156d50c55f1SSlava Shwartsman }
157d50c55f1SSlava Shwartsman 
158d50c55f1SSlava Shwartsman static int
tools_char_write(struct cdev * dev,struct uio * uio,int ioflag)159d50c55f1SSlava Shwartsman tools_char_write(struct cdev *dev, struct uio *uio, int ioflag)
160d50c55f1SSlava Shwartsman {
161d50c55f1SSlava Shwartsman 	struct tools_context *context;
162d50c55f1SSlava Shwartsman 	void *kbuf;
163d50c55f1SSlava Shwartsman 	off_t of;
164d50c55f1SSlava Shwartsman 	size_t len, len1;
165d50c55f1SSlava Shwartsman 	int ret;
166d50c55f1SSlava Shwartsman 
167d50c55f1SSlava Shwartsman 	ret = devfs_get_cdevpriv((void **)&context);
168d50c55f1SSlava Shwartsman 	if (ret != 0)
169d50c55f1SSlava Shwartsman 		return (ret);
170d50c55f1SSlava Shwartsman 	dev_dbg(mlx5_fpga_dev(context->tdev->fdev),
171d50c55f1SSlava Shwartsman 	    "tools char device reading %zu bytes at 0x%jx\n", uio->uio_resid,
172d50c55f1SSlava Shwartsman 	    (uintmax_t)uio->uio_offset);
173d50c55f1SSlava Shwartsman 
174d50c55f1SSlava Shwartsman 	tools_char_llseek(context, uio, &len);
175d50c55f1SSlava Shwartsman 	if (len == 0)
176d50c55f1SSlava Shwartsman 		return (0);
177d50c55f1SSlava Shwartsman 
178d50c55f1SSlava Shwartsman 	kbuf = malloc(len, M_DEVBUF, M_WAITOK);
179d50c55f1SSlava Shwartsman 	len1 = uio->uio_resid;
180d50c55f1SSlava Shwartsman 	of = uio->uio_offset;
181d50c55f1SSlava Shwartsman 
182d50c55f1SSlava Shwartsman 	ret = uiomove(kbuf, len, uio);
183d50c55f1SSlava Shwartsman 	if (ret == 0) {
184d50c55f1SSlava Shwartsman 		len1 -= uio->uio_resid;
185d50c55f1SSlava Shwartsman 		ret = mem_write(context->tdev, kbuf, len, of,
186d50c55f1SSlava Shwartsman 		    context->access_type, &len1);
187d50c55f1SSlava Shwartsman 	}
188d50c55f1SSlava Shwartsman 	free(kbuf, M_DEVBUF);
189d50c55f1SSlava Shwartsman 	return (ret);
190d50c55f1SSlava Shwartsman }
191d50c55f1SSlava Shwartsman 
192d50c55f1SSlava Shwartsman CTASSERT(MLX5_FPGA_CAP_ARR_SZ == MLX5_ST_SZ_DW(fpga_cap));
193d50c55f1SSlava Shwartsman 
194d50c55f1SSlava Shwartsman static int
tools_char_ioctl(struct cdev * dev,u_long cmd,caddr_t data,int fflag,struct thread * td)195d50c55f1SSlava Shwartsman tools_char_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
196d50c55f1SSlava Shwartsman     struct thread *td)
197d50c55f1SSlava Shwartsman {
198d50c55f1SSlava Shwartsman 	struct tools_context *context;
199d50c55f1SSlava Shwartsman 	struct mlx5_fpga_device *fdev;
200d50c55f1SSlava Shwartsman 	struct mlx5_fpga_query query;
201085b35bbSSlava Shwartsman 	struct mlx5_fpga_temperature *temperature;
202d82f1c13SSlava Shwartsman 	enum mlx5_fpga_connect *connect;
203d50c55f1SSlava Shwartsman 	u32 fpga_cap[MLX5_ST_SZ_DW(fpga_cap)] = {0};
204d50c55f1SSlava Shwartsman 	int arg, err;
205d50c55f1SSlava Shwartsman 
206d50c55f1SSlava Shwartsman 	err = devfs_get_cdevpriv((void **)&context);
207d50c55f1SSlava Shwartsman 	if (err != 0)
208d50c55f1SSlava Shwartsman 		return (err);
209d50c55f1SSlava Shwartsman 	fdev = context->tdev->fdev;
210d50c55f1SSlava Shwartsman 	if (fdev == NULL)
211d50c55f1SSlava Shwartsman 		return (ENXIO);
212d50c55f1SSlava Shwartsman 
213d50c55f1SSlava Shwartsman 	switch (cmd) {
214d50c55f1SSlava Shwartsman 	case MLX5_FPGA_ACCESS_TYPE:
215d50c55f1SSlava Shwartsman 		arg = *(int *)data;
216d50c55f1SSlava Shwartsman 		if (arg > MLX5_FPGA_ACCESS_TYPE_MAX) {
217d50c55f1SSlava Shwartsman 			dev_err(mlx5_fpga_dev(fdev),
218d50c55f1SSlava Shwartsman 			    "unknown access type %u\n", arg);
219d50c55f1SSlava Shwartsman 			err = EINVAL;
220d50c55f1SSlava Shwartsman 			break;
221d50c55f1SSlava Shwartsman 		}
222d50c55f1SSlava Shwartsman 		context->access_type = arg;
223d50c55f1SSlava Shwartsman 		break;
224d50c55f1SSlava Shwartsman 	case MLX5_FPGA_LOAD:
225d50c55f1SSlava Shwartsman 		arg = *(int *)data;
226*c322dbafSHans Petter Selasky 		if (arg > MLX5_FPGA_IMAGE_FACTORY) {
227d50c55f1SSlava Shwartsman 			dev_err(mlx5_fpga_dev(fdev),
228d50c55f1SSlava Shwartsman 				"unknown image type %u\n", arg);
229d50c55f1SSlava Shwartsman 			err = EINVAL;
230d50c55f1SSlava Shwartsman 			break;
231d50c55f1SSlava Shwartsman 		}
232d50c55f1SSlava Shwartsman 		err = mlx5_fpga_device_reload(fdev, arg);
233d50c55f1SSlava Shwartsman 		break;
234d50c55f1SSlava Shwartsman 	case MLX5_FPGA_RESET:
235*c322dbafSHans Petter Selasky 		err = mlx5_fpga_device_reload(fdev, MLX5_FPGA_IMAGE_RESET);
236*c322dbafSHans Petter Selasky 		break;
237*c322dbafSHans Petter Selasky 	case MLX5_FPGA_RELOAD:
238*c322dbafSHans Petter Selasky 		err = mlx5_fpga_device_reload(fdev, MLX5_FPGA_IMAGE_RELOAD);
239d50c55f1SSlava Shwartsman 		break;
240d50c55f1SSlava Shwartsman 	case MLX5_FPGA_IMAGE_SEL:
241d50c55f1SSlava Shwartsman 		arg = *(int *)data;
242*c322dbafSHans Petter Selasky 		if (arg > MLX5_FPGA_IMAGE_FACTORY) {
243d50c55f1SSlava Shwartsman 			dev_err(mlx5_fpga_dev(fdev),
244d50c55f1SSlava Shwartsman 			    "unknown image type %u\n", arg);
245d50c55f1SSlava Shwartsman 			err = EINVAL;
246d50c55f1SSlava Shwartsman 			break;
247d50c55f1SSlava Shwartsman 		}
248d50c55f1SSlava Shwartsman 		err = mlx5_fpga_flash_select(fdev, arg);
249d50c55f1SSlava Shwartsman 		break;
250d50c55f1SSlava Shwartsman 	case MLX5_FPGA_QUERY:
251d50c55f1SSlava Shwartsman 		mlx5_fpga_device_query(fdev, &query);
252d50c55f1SSlava Shwartsman 		bcopy(&query, data, sizeof(query));
253d50c55f1SSlava Shwartsman 		err = 0;
254d50c55f1SSlava Shwartsman 		break;
255d50c55f1SSlava Shwartsman 	case MLX5_FPGA_CAP:
256d50c55f1SSlava Shwartsman 		mlx5_fpga_get_cap(fdev, fpga_cap);
257d50c55f1SSlava Shwartsman 		bcopy(&fpga_cap, data, sizeof(fpga_cap));
258d50c55f1SSlava Shwartsman 		err = 0;
259d50c55f1SSlava Shwartsman 		break;
260085b35bbSSlava Shwartsman 	case MLX5_FPGA_TEMPERATURE:
261085b35bbSSlava Shwartsman 		temperature = (struct mlx5_fpga_temperature *)data;
262085b35bbSSlava Shwartsman 		mlx5_fpga_temperature(fdev, temperature);
263085b35bbSSlava Shwartsman 		err = 0; /* XXXKIB */
264085b35bbSSlava Shwartsman 		break;
265d82f1c13SSlava Shwartsman 	case MLX5_FPGA_CONNECT:
266d82f1c13SSlava Shwartsman 		connect = (enum mlx5_fpga_connect *)data;
267d82f1c13SSlava Shwartsman 		mlx5_fpga_connectdisconnect(fdev, connect);
268d82f1c13SSlava Shwartsman 		err = 0; /* XXXKIB */
269d82f1c13SSlava Shwartsman  		break;
270d50c55f1SSlava Shwartsman 	default:
271d50c55f1SSlava Shwartsman 		dev_err(mlx5_fpga_dev(fdev),
272d50c55f1SSlava Shwartsman 			"unknown ioctl command %#08lx\n", cmd);
273d50c55f1SSlava Shwartsman 		err = ENOTTY;
274d50c55f1SSlava Shwartsman 	}
275d50c55f1SSlava Shwartsman 	return (err);
276d50c55f1SSlava Shwartsman }
277d50c55f1SSlava Shwartsman 
278d50c55f1SSlava Shwartsman static struct cdevsw mlx5_tools_char_cdevsw = {
279d50c55f1SSlava Shwartsman 	.d_version =	D_VERSION,
280d50c55f1SSlava Shwartsman 	.d_name =	"mlx5_tools_char",
281d50c55f1SSlava Shwartsman 	.d_open =	tools_char_open,
282d50c55f1SSlava Shwartsman 	.d_read =	tools_char_read,
283d50c55f1SSlava Shwartsman 	.d_write =	tools_char_write,
284d50c55f1SSlava Shwartsman 	.d_ioctl =	tools_char_ioctl,
285d50c55f1SSlava Shwartsman };
286d50c55f1SSlava Shwartsman 
287d50c55f1SSlava Shwartsman int
mlx5_fpga_tools_char_add_one(struct mlx5_fpga_tools_dev * tdev)288d50c55f1SSlava Shwartsman mlx5_fpga_tools_char_add_one(struct mlx5_fpga_tools_dev *tdev)
289d50c55f1SSlava Shwartsman {
290d50c55f1SSlava Shwartsman 	struct make_dev_args mda;
291d50c55f1SSlava Shwartsman 	struct cdev *cd;
292d50c55f1SSlava Shwartsman 	device_t bdev;
293d50c55f1SSlava Shwartsman 	int ret;
294d50c55f1SSlava Shwartsman 
295d50c55f1SSlava Shwartsman 	make_dev_args_init(&mda);
296d50c55f1SSlava Shwartsman 	mda.mda_flags = MAKEDEV_WAITOK | MAKEDEV_CHECKNAME;
297d50c55f1SSlava Shwartsman 	mda.mda_devsw = &mlx5_tools_char_cdevsw;
298d50c55f1SSlava Shwartsman 	mda.mda_uid = UID_ROOT;
299d50c55f1SSlava Shwartsman 	mda.mda_gid = GID_OPERATOR;
300d50c55f1SSlava Shwartsman 	mda.mda_mode = 0660;
301d50c55f1SSlava Shwartsman 	mda.mda_si_drv1 = tdev;
302d50c55f1SSlava Shwartsman 	bdev = mlx5_fpga_dev(tdev->fdev)->bsddev;
303d50c55f1SSlava Shwartsman 	ret = make_dev_s(&mda, &cd,
304d50c55f1SSlava Shwartsman 	    "%04x:%02x:%02x.%x" MLX5_FPGA_TOOLS_NAME_SUFFIX,
305d50c55f1SSlava Shwartsman 	    pci_get_domain(bdev), pci_get_bus(bdev), pci_get_slot(bdev),
306d50c55f1SSlava Shwartsman 	    pci_get_function(bdev));
307d50c55f1SSlava Shwartsman 	if (ret != 0) {
308d50c55f1SSlava Shwartsman 		tdev->char_device = NULL;
309d50c55f1SSlava Shwartsman 		dev_err(mlx5_fpga_dev(tdev->fdev),
310d50c55f1SSlava Shwartsman 		    "Failed to create a char device: %d\n", ret);
311d50c55f1SSlava Shwartsman 		return (-ret);
312d50c55f1SSlava Shwartsman 	}
313d50c55f1SSlava Shwartsman 	tdev->char_device = cd;
314d50c55f1SSlava Shwartsman 
315d50c55f1SSlava Shwartsman 	dev_dbg(mlx5_fpga_dev(tdev->fdev), "tools char device %s created\n",
316d50c55f1SSlava Shwartsman 	    cd->si_name);
317d50c55f1SSlava Shwartsman 	return (0);
318d50c55f1SSlava Shwartsman }
319d50c55f1SSlava Shwartsman 
mlx5_fpga_tools_char_remove_one(struct mlx5_fpga_tools_dev * tdev)320d50c55f1SSlava Shwartsman void mlx5_fpga_tools_char_remove_one(struct mlx5_fpga_tools_dev *tdev)
321d50c55f1SSlava Shwartsman {
322d50c55f1SSlava Shwartsman 
323d50c55f1SSlava Shwartsman 	dev_err(mlx5_fpga_dev(tdev->fdev), "tools char device %s destroyed\n",
324d50c55f1SSlava Shwartsman 	    ((struct cdev *)(tdev->char_device))->si_name);
325d50c55f1SSlava Shwartsman 	destroy_dev((struct cdev *)(tdev->char_device));
326d50c55f1SSlava Shwartsman }
327d50c55f1SSlava Shwartsman 
328d50c55f1SSlava Shwartsman int
mlx5_fpga_tools_char_init(void)329d50c55f1SSlava Shwartsman mlx5_fpga_tools_char_init(void)
330d50c55f1SSlava Shwartsman {
331d50c55f1SSlava Shwartsman 
332d50c55f1SSlava Shwartsman 	return (0);
333d50c55f1SSlava Shwartsman }
334d50c55f1SSlava Shwartsman 
335d50c55f1SSlava Shwartsman void
mlx5_fpga_tools_char_deinit(void)336d50c55f1SSlava Shwartsman mlx5_fpga_tools_char_deinit(void)
337d50c55f1SSlava Shwartsman {
338d50c55f1SSlava Shwartsman }
339