xref: /freebsd/sys/dev/mlx5/mlx5_fpga/mlx5fpga_trans.c (revision 95ee2897e98f5d444f26ed2334cc7c439f9c16c6)
1*e9dcd831SSlava Shwartsman /*-
2*e9dcd831SSlava Shwartsman  * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
3*e9dcd831SSlava Shwartsman  *
4*e9dcd831SSlava Shwartsman  * This software is available to you under a choice of one of two
5*e9dcd831SSlava Shwartsman  * licenses.  You may choose to be licensed under the terms of the GNU
6*e9dcd831SSlava Shwartsman  * General Public License (GPL) Version 2, available from the file
7*e9dcd831SSlava Shwartsman  * COPYING in the main directory of this source tree, or the
8*e9dcd831SSlava Shwartsman  * OpenIB.org BSD license below:
9*e9dcd831SSlava Shwartsman  *
10*e9dcd831SSlava Shwartsman  *     Redistribution and use in source and binary forms, with or
11*e9dcd831SSlava Shwartsman  *     without modification, are permitted provided that the following
12*e9dcd831SSlava Shwartsman  *     conditions are met:
13*e9dcd831SSlava Shwartsman  *
14*e9dcd831SSlava Shwartsman  *      - Redistributions of source code must retain the above
15*e9dcd831SSlava Shwartsman  *        copyright notice, this list of conditions and the following
16*e9dcd831SSlava Shwartsman  *        disclaimer.
17*e9dcd831SSlava Shwartsman  *
18*e9dcd831SSlava Shwartsman  *      - Redistributions in binary form must reproduce the above
19*e9dcd831SSlava Shwartsman  *        copyright notice, this list of conditions and the following
20*e9dcd831SSlava Shwartsman  *        disclaimer in the documentation and/or other materials
21*e9dcd831SSlava Shwartsman  *        provided with the distribution.
22*e9dcd831SSlava Shwartsman  *
23*e9dcd831SSlava Shwartsman  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24*e9dcd831SSlava Shwartsman  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25*e9dcd831SSlava Shwartsman  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26*e9dcd831SSlava Shwartsman  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27*e9dcd831SSlava Shwartsman  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28*e9dcd831SSlava Shwartsman  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29*e9dcd831SSlava Shwartsman  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30*e9dcd831SSlava Shwartsman  * SOFTWARE.
31*e9dcd831SSlava Shwartsman  */
32*e9dcd831SSlava Shwartsman 
33*e9dcd831SSlava Shwartsman #include <dev/mlx5/mlx5_fpga/trans.h>
34*e9dcd831SSlava Shwartsman #include <dev/mlx5/mlx5_fpga/conn.h>
35*e9dcd831SSlava Shwartsman 
36*e9dcd831SSlava Shwartsman enum mlx5_fpga_transaction_state {
37*e9dcd831SSlava Shwartsman 	TRANS_STATE_NONE,
38*e9dcd831SSlava Shwartsman 	TRANS_STATE_SEND,
39*e9dcd831SSlava Shwartsman 	TRANS_STATE_WAIT,
40*e9dcd831SSlava Shwartsman 	TRANS_STATE_COMPLETE,
41*e9dcd831SSlava Shwartsman };
42*e9dcd831SSlava Shwartsman 
43*e9dcd831SSlava Shwartsman struct mlx5_fpga_trans_priv {
44*e9dcd831SSlava Shwartsman 	const struct mlx5_fpga_transaction *user_trans;
45*e9dcd831SSlava Shwartsman 	u8 tid;
46*e9dcd831SSlava Shwartsman 	enum mlx5_fpga_transaction_state state;
47*e9dcd831SSlava Shwartsman 	u8 status;
48*e9dcd831SSlava Shwartsman 	u32 header[MLX5_ST_SZ_DW(fpga_shell_qp_packet)];
49*e9dcd831SSlava Shwartsman 	struct mlx5_fpga_dma_buf buf;
50*e9dcd831SSlava Shwartsman 	struct list_head list_item;
51*e9dcd831SSlava Shwartsman };
52*e9dcd831SSlava Shwartsman 
53*e9dcd831SSlava Shwartsman struct mlx5_fpga_trans_device_state {
54*e9dcd831SSlava Shwartsman 	spinlock_t lock; /* Protects all members of this struct */
55*e9dcd831SSlava Shwartsman 	struct list_head free_queue;
56*e9dcd831SSlava Shwartsman 	struct mlx5_fpga_trans_priv transactions[MLX5_FPGA_TID_COUNT];
57*e9dcd831SSlava Shwartsman };
58*e9dcd831SSlava Shwartsman 
find_tid(struct mlx5_fpga_device * fdev,u8 tid)59*e9dcd831SSlava Shwartsman static struct mlx5_fpga_trans_priv *find_tid(struct mlx5_fpga_device *fdev,
60*e9dcd831SSlava Shwartsman 					     u8 tid)
61*e9dcd831SSlava Shwartsman {
62*e9dcd831SSlava Shwartsman 	if (tid >= MLX5_FPGA_TID_COUNT) {
63*e9dcd831SSlava Shwartsman 		mlx5_fpga_warn(fdev, "Unexpected transaction ID %u\n", tid);
64*e9dcd831SSlava Shwartsman 		return NULL;
65*e9dcd831SSlava Shwartsman 	}
66*e9dcd831SSlava Shwartsman 	return &fdev->trans->transactions[tid];
67*e9dcd831SSlava Shwartsman }
68*e9dcd831SSlava Shwartsman 
alloc_tid(struct mlx5_fpga_device * fdev)69*e9dcd831SSlava Shwartsman static struct mlx5_fpga_trans_priv *alloc_tid(struct mlx5_fpga_device *fdev)
70*e9dcd831SSlava Shwartsman {
71*e9dcd831SSlava Shwartsman 	struct mlx5_fpga_trans_priv *ret;
72*e9dcd831SSlava Shwartsman 	unsigned long flags;
73*e9dcd831SSlava Shwartsman 
74*e9dcd831SSlava Shwartsman 	spin_lock_irqsave(&fdev->trans->lock, flags);
75*e9dcd831SSlava Shwartsman 
76*e9dcd831SSlava Shwartsman 	if (list_empty(&fdev->trans->free_queue)) {
77*e9dcd831SSlava Shwartsman 		mlx5_fpga_dbg(fdev, "No free transaction ID available\n");
78*e9dcd831SSlava Shwartsman 		ret = NULL;
79*e9dcd831SSlava Shwartsman 		goto out;
80*e9dcd831SSlava Shwartsman 	}
81*e9dcd831SSlava Shwartsman 
82*e9dcd831SSlava Shwartsman 	ret = list_first_entry(&fdev->trans->free_queue,
83*e9dcd831SSlava Shwartsman 			       struct mlx5_fpga_trans_priv, list_item);
84*e9dcd831SSlava Shwartsman 	list_del(&ret->list_item);
85*e9dcd831SSlava Shwartsman 
86*e9dcd831SSlava Shwartsman 	ret->state = TRANS_STATE_NONE;
87*e9dcd831SSlava Shwartsman out:
88*e9dcd831SSlava Shwartsman 	spin_unlock_irqrestore(&fdev->trans->lock, flags);
89*e9dcd831SSlava Shwartsman 	return ret;
90*e9dcd831SSlava Shwartsman }
91*e9dcd831SSlava Shwartsman 
free_tid(struct mlx5_fpga_device * fdev,struct mlx5_fpga_trans_priv * trans_priv)92*e9dcd831SSlava Shwartsman static void free_tid(struct mlx5_fpga_device *fdev,
93*e9dcd831SSlava Shwartsman 		     struct mlx5_fpga_trans_priv *trans_priv)
94*e9dcd831SSlava Shwartsman {
95*e9dcd831SSlava Shwartsman 	unsigned long flags;
96*e9dcd831SSlava Shwartsman 
97*e9dcd831SSlava Shwartsman 	spin_lock_irqsave(&fdev->trans->lock, flags);
98*e9dcd831SSlava Shwartsman 	list_add_tail(&trans_priv->list_item, &fdev->trans->free_queue);
99*e9dcd831SSlava Shwartsman 	spin_unlock_irqrestore(&fdev->trans->lock, flags);
100*e9dcd831SSlava Shwartsman }
101*e9dcd831SSlava Shwartsman 
trans_complete(struct mlx5_fpga_device * fdev,struct mlx5_fpga_trans_priv * trans_priv,u8 status)102*e9dcd831SSlava Shwartsman static void trans_complete(struct mlx5_fpga_device *fdev,
103*e9dcd831SSlava Shwartsman 			   struct mlx5_fpga_trans_priv *trans_priv, u8 status)
104*e9dcd831SSlava Shwartsman {
105*e9dcd831SSlava Shwartsman 	const struct mlx5_fpga_transaction *user_trans;
106*e9dcd831SSlava Shwartsman 	unsigned long flags;
107*e9dcd831SSlava Shwartsman 
108*e9dcd831SSlava Shwartsman 	mlx5_fpga_dbg(fdev, "Transaction %u is complete with status %u\n",
109*e9dcd831SSlava Shwartsman 		      trans_priv->tid, status);
110*e9dcd831SSlava Shwartsman 
111*e9dcd831SSlava Shwartsman 	spin_lock_irqsave(&fdev->trans->lock, flags);
112*e9dcd831SSlava Shwartsman 	trans_priv->state = TRANS_STATE_COMPLETE;
113*e9dcd831SSlava Shwartsman 	trans_priv->status = status;
114*e9dcd831SSlava Shwartsman 	spin_unlock_irqrestore(&fdev->trans->lock, flags);
115*e9dcd831SSlava Shwartsman 
116*e9dcd831SSlava Shwartsman 	user_trans = trans_priv->user_trans;
117*e9dcd831SSlava Shwartsman 	free_tid(fdev, trans_priv);
118*e9dcd831SSlava Shwartsman 
119*e9dcd831SSlava Shwartsman 	if (user_trans->complete1)
120*e9dcd831SSlava Shwartsman 		user_trans->complete1(user_trans, status);
121*e9dcd831SSlava Shwartsman }
122*e9dcd831SSlava Shwartsman 
trans_send_complete(struct mlx5_fpga_conn * conn,struct mlx5_fpga_device * fdev,struct mlx5_fpga_dma_buf * buf,u8 status)123*e9dcd831SSlava Shwartsman static void trans_send_complete(struct mlx5_fpga_conn *conn,
124*e9dcd831SSlava Shwartsman 				struct mlx5_fpga_device *fdev,
125*e9dcd831SSlava Shwartsman 				struct mlx5_fpga_dma_buf *buf, u8 status)
126*e9dcd831SSlava Shwartsman {
127*e9dcd831SSlava Shwartsman 	unsigned long flags;
128*e9dcd831SSlava Shwartsman 	struct mlx5_fpga_trans_priv *trans_priv;
129*e9dcd831SSlava Shwartsman 
130*e9dcd831SSlava Shwartsman 	trans_priv = container_of(buf, struct mlx5_fpga_trans_priv, buf);
131*e9dcd831SSlava Shwartsman 	mlx5_fpga_dbg(fdev, "send complete tid %u. Status: %u\n",
132*e9dcd831SSlava Shwartsman 		      trans_priv->tid, status);
133*e9dcd831SSlava Shwartsman 	if (status) {
134*e9dcd831SSlava Shwartsman 		trans_complete(fdev, trans_priv, status);
135*e9dcd831SSlava Shwartsman 		return;
136*e9dcd831SSlava Shwartsman 	}
137*e9dcd831SSlava Shwartsman 
138*e9dcd831SSlava Shwartsman 	spin_lock_irqsave(&fdev->trans->lock, flags);
139*e9dcd831SSlava Shwartsman 	if (trans_priv->state == TRANS_STATE_SEND)
140*e9dcd831SSlava Shwartsman 		trans_priv->state = TRANS_STATE_WAIT;
141*e9dcd831SSlava Shwartsman 	spin_unlock_irqrestore(&fdev->trans->lock, flags);
142*e9dcd831SSlava Shwartsman }
143*e9dcd831SSlava Shwartsman 
trans_validate(struct mlx5_fpga_device * fdev,u64 addr,size_t size)144*e9dcd831SSlava Shwartsman static int trans_validate(struct mlx5_fpga_device *fdev, u64 addr, size_t size)
145*e9dcd831SSlava Shwartsman {
146*e9dcd831SSlava Shwartsman 	if (size > MLX5_FPGA_TRANSACTION_MAX_SIZE) {
147*e9dcd831SSlava Shwartsman 		mlx5_fpga_warn(fdev, "Cannot access %zu bytes at once. Max is %u\n",
148*e9dcd831SSlava Shwartsman 			       size, MLX5_FPGA_TRANSACTION_MAX_SIZE);
149*e9dcd831SSlava Shwartsman 		return -EINVAL;
150*e9dcd831SSlava Shwartsman 	}
151*e9dcd831SSlava Shwartsman 	if (size & MLX5_FPGA_TRANSACTION_SEND_ALIGN_BITS) {
152*e9dcd831SSlava Shwartsman 		mlx5_fpga_warn(fdev, "Cannot access %zu bytes. Must be full dwords\n",
153*e9dcd831SSlava Shwartsman 			       size);
154*e9dcd831SSlava Shwartsman 		return -EINVAL;
155*e9dcd831SSlava Shwartsman 	}
156*e9dcd831SSlava Shwartsman 	if (size < 1) {
157*e9dcd831SSlava Shwartsman 		mlx5_fpga_warn(fdev, "Cannot access %zu bytes. Empty transaction not allowed\n",
158*e9dcd831SSlava Shwartsman 			       size);
159*e9dcd831SSlava Shwartsman 		return -EINVAL;
160*e9dcd831SSlava Shwartsman 	}
161*e9dcd831SSlava Shwartsman 	if (addr & MLX5_FPGA_TRANSACTION_SEND_ALIGN_BITS) {
162*e9dcd831SSlava Shwartsman 		mlx5_fpga_warn(fdev, "Cannot access %zu bytes at unaligned address %jx\n",
163*e9dcd831SSlava Shwartsman 			       size, (uintmax_t)addr);
164*e9dcd831SSlava Shwartsman 		return -EINVAL;
165*e9dcd831SSlava Shwartsman 	}
166*e9dcd831SSlava Shwartsman 	if ((addr >> MLX5_FPGA_TRANSACTION_SEND_PAGE_BITS) !=
167*e9dcd831SSlava Shwartsman 	    ((addr + size - 1) >> MLX5_FPGA_TRANSACTION_SEND_PAGE_BITS)) {
168*e9dcd831SSlava Shwartsman 		mlx5_fpga_warn(fdev, "Cannot access %zu bytes at address %jx. Crosses page boundary\n",
169*e9dcd831SSlava Shwartsman 			       size, (uintmax_t)addr);
170*e9dcd831SSlava Shwartsman 		return -EINVAL;
171*e9dcd831SSlava Shwartsman 	}
172*e9dcd831SSlava Shwartsman 	if (addr < mlx5_fpga_ddr_base_get(fdev)) {
173*e9dcd831SSlava Shwartsman 		if (size != sizeof(u32)) {
174*e9dcd831SSlava Shwartsman 			mlx5_fpga_warn(fdev, "Cannot access %zu bytes at cr-space address %jx. Must access a single dword\n",
175*e9dcd831SSlava Shwartsman 				       size, (uintmax_t)addr);
176*e9dcd831SSlava Shwartsman 			return -EINVAL;
177*e9dcd831SSlava Shwartsman 		}
178*e9dcd831SSlava Shwartsman 	}
179*e9dcd831SSlava Shwartsman 	return 0;
180*e9dcd831SSlava Shwartsman }
181*e9dcd831SSlava Shwartsman 
mlx5_fpga_trans_exec(const struct mlx5_fpga_transaction * trans)182*e9dcd831SSlava Shwartsman int mlx5_fpga_trans_exec(const struct mlx5_fpga_transaction *trans)
183*e9dcd831SSlava Shwartsman {
184*e9dcd831SSlava Shwartsman 	struct mlx5_fpga_conn *conn = trans->conn;
185*e9dcd831SSlava Shwartsman 	struct mlx5_fpga_trans_priv *trans_priv;
186*e9dcd831SSlava Shwartsman 	u32 *header;
187*e9dcd831SSlava Shwartsman 	int err;
188*e9dcd831SSlava Shwartsman 
189*e9dcd831SSlava Shwartsman 	if (!trans->complete1) {
190*e9dcd831SSlava Shwartsman 		mlx5_fpga_warn(conn->fdev, "Transaction must have a completion callback\n");
191*e9dcd831SSlava Shwartsman 		err = -EINVAL;
192*e9dcd831SSlava Shwartsman 		goto out;
193*e9dcd831SSlava Shwartsman 	}
194*e9dcd831SSlava Shwartsman 
195*e9dcd831SSlava Shwartsman 	err = trans_validate(conn->fdev, trans->addr, trans->size);
196*e9dcd831SSlava Shwartsman 	if (err)
197*e9dcd831SSlava Shwartsman 		goto out;
198*e9dcd831SSlava Shwartsman 
199*e9dcd831SSlava Shwartsman 	trans_priv = alloc_tid(conn->fdev);
200*e9dcd831SSlava Shwartsman 	if (!trans_priv) {
201*e9dcd831SSlava Shwartsman 		err = -EBUSY;
202*e9dcd831SSlava Shwartsman 		goto out;
203*e9dcd831SSlava Shwartsman 	}
204*e9dcd831SSlava Shwartsman 	trans_priv->user_trans = trans;
205*e9dcd831SSlava Shwartsman 	header = trans_priv->header;
206*e9dcd831SSlava Shwartsman 
207*e9dcd831SSlava Shwartsman 	memset(header, 0, sizeof(trans_priv->header));
208*e9dcd831SSlava Shwartsman 	memset(&trans_priv->buf, 0, sizeof(trans_priv->buf));
209*e9dcd831SSlava Shwartsman 	MLX5_SET(fpga_shell_qp_packet, header, type,
210*e9dcd831SSlava Shwartsman 		 (trans->direction == MLX5_FPGA_WRITE) ?
211*e9dcd831SSlava Shwartsman 		 MLX5_FPGA_SHELL_QP_PACKET_TYPE_DDR_WRITE :
212*e9dcd831SSlava Shwartsman 		 MLX5_FPGA_SHELL_QP_PACKET_TYPE_DDR_READ);
213*e9dcd831SSlava Shwartsman 	MLX5_SET(fpga_shell_qp_packet, header, tid, trans_priv->tid);
214*e9dcd831SSlava Shwartsman 	MLX5_SET(fpga_shell_qp_packet, header, len, trans->size);
215*e9dcd831SSlava Shwartsman 	MLX5_SET64(fpga_shell_qp_packet, header, address, trans->addr);
216*e9dcd831SSlava Shwartsman 
217*e9dcd831SSlava Shwartsman 	trans_priv->buf.sg[0].data = header;
218*e9dcd831SSlava Shwartsman 	trans_priv->buf.sg[0].size = sizeof(trans_priv->header);
219*e9dcd831SSlava Shwartsman 	if (trans->direction == MLX5_FPGA_WRITE) {
220*e9dcd831SSlava Shwartsman 		trans_priv->buf.sg[1].data = trans->data;
221*e9dcd831SSlava Shwartsman 		trans_priv->buf.sg[1].size = trans->size;
222*e9dcd831SSlava Shwartsman 	}
223*e9dcd831SSlava Shwartsman 
224*e9dcd831SSlava Shwartsman 	trans_priv->buf.complete = trans_send_complete;
225*e9dcd831SSlava Shwartsman 	trans_priv->state = TRANS_STATE_SEND;
226*e9dcd831SSlava Shwartsman 
227*e9dcd831SSlava Shwartsman #ifdef NOT_YET
228*e9dcd831SSlava Shwartsman 	/* XXXKIB */
229*e9dcd831SSlava Shwartsman 	err = mlx5_fpga_conn_send(conn->fdev->shell_conn, &trans_priv->buf);
230*e9dcd831SSlava Shwartsman #else
231*e9dcd831SSlava Shwartsman 	err = 0;
232*e9dcd831SSlava Shwartsman #endif
233*e9dcd831SSlava Shwartsman 	if (err)
234*e9dcd831SSlava Shwartsman 		goto out_buf_tid;
235*e9dcd831SSlava Shwartsman 	goto out;
236*e9dcd831SSlava Shwartsman 
237*e9dcd831SSlava Shwartsman out_buf_tid:
238*e9dcd831SSlava Shwartsman 	free_tid(conn->fdev, trans_priv);
239*e9dcd831SSlava Shwartsman out:
240*e9dcd831SSlava Shwartsman 	return err;
241*e9dcd831SSlava Shwartsman }
242*e9dcd831SSlava Shwartsman 
mlx5_fpga_trans_recv(void * cb_arg,struct mlx5_fpga_dma_buf * buf)243*e9dcd831SSlava Shwartsman void mlx5_fpga_trans_recv(void *cb_arg, struct mlx5_fpga_dma_buf *buf)
244*e9dcd831SSlava Shwartsman {
245*e9dcd831SSlava Shwartsman 	struct mlx5_fpga_device *fdev = cb_arg;
246*e9dcd831SSlava Shwartsman 	struct mlx5_fpga_trans_priv *trans_priv;
247*e9dcd831SSlava Shwartsman 	size_t payload_len;
248*e9dcd831SSlava Shwartsman 	u8 status = 0;
249*e9dcd831SSlava Shwartsman 	u8 tid, type;
250*e9dcd831SSlava Shwartsman 
251*e9dcd831SSlava Shwartsman 	mlx5_fpga_dbg(fdev, "Rx QP message on core conn; %u bytes\n",
252*e9dcd831SSlava Shwartsman 		      buf->sg[0].size);
253*e9dcd831SSlava Shwartsman 
254*e9dcd831SSlava Shwartsman 	if (buf->sg[0].size < MLX5_ST_SZ_BYTES(fpga_shell_qp_packet)) {
255*e9dcd831SSlava Shwartsman 		mlx5_fpga_warn(fdev, "Short message %u bytes from device\n",
256*e9dcd831SSlava Shwartsman 			       buf->sg[0].size);
257*e9dcd831SSlava Shwartsman 		goto out;
258*e9dcd831SSlava Shwartsman 	}
259*e9dcd831SSlava Shwartsman 	payload_len = buf->sg[0].size - MLX5_ST_SZ_BYTES(fpga_shell_qp_packet);
260*e9dcd831SSlava Shwartsman 
261*e9dcd831SSlava Shwartsman 	tid = MLX5_GET(fpga_shell_qp_packet, buf->sg[0].data, tid);
262*e9dcd831SSlava Shwartsman 	trans_priv = find_tid(fdev, tid);
263*e9dcd831SSlava Shwartsman 	if (!trans_priv)
264*e9dcd831SSlava Shwartsman 		goto out;
265*e9dcd831SSlava Shwartsman 
266*e9dcd831SSlava Shwartsman 	type = MLX5_GET(fpga_shell_qp_packet, buf->sg[0].data, type);
267*e9dcd831SSlava Shwartsman 	switch (type) {
268*e9dcd831SSlava Shwartsman 	case MLX5_FPGA_SHELL_QP_PACKET_TYPE_DDR_READ_RESPONSE:
269*e9dcd831SSlava Shwartsman 		if (trans_priv->user_trans->direction != MLX5_FPGA_READ) {
270*e9dcd831SSlava Shwartsman 			mlx5_fpga_warn(fdev, "Wrong answer type %u to a %u transaction\n",
271*e9dcd831SSlava Shwartsman 				       type, trans_priv->user_trans->direction);
272*e9dcd831SSlava Shwartsman 			status = -EIO;
273*e9dcd831SSlava Shwartsman 			goto complete;
274*e9dcd831SSlava Shwartsman 		}
275*e9dcd831SSlava Shwartsman 		if (payload_len != trans_priv->user_trans->size) {
276*e9dcd831SSlava Shwartsman 			mlx5_fpga_warn(fdev, "Incorrect transaction payload length %zu expected %zu\n",
277*e9dcd831SSlava Shwartsman 				       payload_len,
278*e9dcd831SSlava Shwartsman 				       trans_priv->user_trans->size);
279*e9dcd831SSlava Shwartsman 			goto complete;
280*e9dcd831SSlava Shwartsman 		}
281*e9dcd831SSlava Shwartsman 		memcpy(trans_priv->user_trans->data,
282*e9dcd831SSlava Shwartsman 		       MLX5_ADDR_OF(fpga_shell_qp_packet, buf->sg[0].data,
283*e9dcd831SSlava Shwartsman 				    data), payload_len);
284*e9dcd831SSlava Shwartsman 		break;
285*e9dcd831SSlava Shwartsman 	case MLX5_FPGA_SHELL_QP_PACKET_TYPE_DDR_WRITE_RESPONSE:
286*e9dcd831SSlava Shwartsman 		if (trans_priv->user_trans->direction != MLX5_FPGA_WRITE) {
287*e9dcd831SSlava Shwartsman 			mlx5_fpga_warn(fdev, "Wrong answer type %u to a %u transaction\n",
288*e9dcd831SSlava Shwartsman 				       type, trans_priv->user_trans->direction);
289*e9dcd831SSlava Shwartsman 			status = -EIO;
290*e9dcd831SSlava Shwartsman 			goto complete;
291*e9dcd831SSlava Shwartsman 		}
292*e9dcd831SSlava Shwartsman 		break;
293*e9dcd831SSlava Shwartsman 	default:
294*e9dcd831SSlava Shwartsman 		mlx5_fpga_warn(fdev, "Unexpected message type %u len %u from device\n",
295*e9dcd831SSlava Shwartsman 			       type, buf->sg[0].size);
296*e9dcd831SSlava Shwartsman 		status = -EIO;
297*e9dcd831SSlava Shwartsman 		goto complete;
298*e9dcd831SSlava Shwartsman 	}
299*e9dcd831SSlava Shwartsman 
300*e9dcd831SSlava Shwartsman complete:
301*e9dcd831SSlava Shwartsman 	trans_complete(fdev, trans_priv, status);
302*e9dcd831SSlava Shwartsman out:
303*e9dcd831SSlava Shwartsman 	return;
304*e9dcd831SSlava Shwartsman }
305*e9dcd831SSlava Shwartsman 
mlx5_fpga_trans_device_init(struct mlx5_fpga_device * fdev)306*e9dcd831SSlava Shwartsman int mlx5_fpga_trans_device_init(struct mlx5_fpga_device *fdev)
307*e9dcd831SSlava Shwartsman {
308*e9dcd831SSlava Shwartsman 	int ret = 0;
309*e9dcd831SSlava Shwartsman 	int tid;
310*e9dcd831SSlava Shwartsman 
311*e9dcd831SSlava Shwartsman 	fdev->trans = kzalloc(sizeof(*fdev->trans), GFP_KERNEL);
312*e9dcd831SSlava Shwartsman 	if (!fdev->trans) {
313*e9dcd831SSlava Shwartsman 		ret = -ENOMEM;
314*e9dcd831SSlava Shwartsman 		goto out;
315*e9dcd831SSlava Shwartsman 	}
316*e9dcd831SSlava Shwartsman 
317*e9dcd831SSlava Shwartsman 	INIT_LIST_HEAD(&fdev->trans->free_queue);
318*e9dcd831SSlava Shwartsman 	for (tid = 0; tid < ARRAY_SIZE(fdev->trans->transactions); tid++) {
319*e9dcd831SSlava Shwartsman 		fdev->trans->transactions[tid].tid = tid;
320*e9dcd831SSlava Shwartsman 		list_add_tail(&fdev->trans->transactions[tid].list_item,
321*e9dcd831SSlava Shwartsman 			      &fdev->trans->free_queue);
322*e9dcd831SSlava Shwartsman 	}
323*e9dcd831SSlava Shwartsman 
324*e9dcd831SSlava Shwartsman 	spin_lock_init(&fdev->trans->lock);
325*e9dcd831SSlava Shwartsman 
326*e9dcd831SSlava Shwartsman out:
327*e9dcd831SSlava Shwartsman 	return ret;
328*e9dcd831SSlava Shwartsman }
329*e9dcd831SSlava Shwartsman 
mlx5_fpga_trans_device_cleanup(struct mlx5_fpga_device * fdev)330*e9dcd831SSlava Shwartsman void mlx5_fpga_trans_device_cleanup(struct mlx5_fpga_device *fdev)
331*e9dcd831SSlava Shwartsman {
332*e9dcd831SSlava Shwartsman 	kfree(fdev->trans);
333*e9dcd831SSlava Shwartsman }
334