xref: /freebsd/sys/dev/enic/cq_desc.h (revision 0acab8b3d1336d4db73a9946ef76b4bcd0b0aabe)
1*9c067b84SDoug Ambrisko /* SPDX-License-Identifier: BSD-3-Clause
2*9c067b84SDoug Ambrisko  * Copyright 2008-2017 Cisco Systems, Inc.  All rights reserved.
3*9c067b84SDoug Ambrisko  * Copyright 2007 Nuova Systems, Inc.  All rights reserved.
4*9c067b84SDoug Ambrisko  */
5*9c067b84SDoug Ambrisko 
6*9c067b84SDoug Ambrisko #ifndef _CQ_DESC_H_
7*9c067b84SDoug Ambrisko #define _CQ_DESC_H_
8*9c067b84SDoug Ambrisko 
9*9c067b84SDoug Ambrisko /*
10*9c067b84SDoug Ambrisko  * Completion queue descriptor types
11*9c067b84SDoug Ambrisko  */
12*9c067b84SDoug Ambrisko enum cq_desc_types {
13*9c067b84SDoug Ambrisko 	CQ_DESC_TYPE_WQ_ENET = 0,
14*9c067b84SDoug Ambrisko 	CQ_DESC_TYPE_DESC_COPY = 1,
15*9c067b84SDoug Ambrisko 	CQ_DESC_TYPE_WQ_EXCH = 2,
16*9c067b84SDoug Ambrisko 	CQ_DESC_TYPE_RQ_ENET = 3,
17*9c067b84SDoug Ambrisko 	CQ_DESC_TYPE_RQ_FCP = 4,
18*9c067b84SDoug Ambrisko 	CQ_DESC_TYPE_IOMMU_MISS = 5,
19*9c067b84SDoug Ambrisko 	CQ_DESC_TYPE_SGL = 6,
20*9c067b84SDoug Ambrisko 	CQ_DESC_TYPE_CLASSIFIER = 7,
21*9c067b84SDoug Ambrisko 	CQ_DESC_TYPE_TEST = 127,
22*9c067b84SDoug Ambrisko };
23*9c067b84SDoug Ambrisko 
24*9c067b84SDoug Ambrisko /* Completion queue descriptor: 16B
25*9c067b84SDoug Ambrisko  *
26*9c067b84SDoug Ambrisko  * All completion queues have this basic layout.  The
27*9c067b84SDoug Ambrisko  * type_specfic area is unique for each completion
28*9c067b84SDoug Ambrisko  * queue type.
29*9c067b84SDoug Ambrisko  */
30*9c067b84SDoug Ambrisko struct cq_desc {
31*9c067b84SDoug Ambrisko 	__le16 completed_index;
32*9c067b84SDoug Ambrisko 	__le16 q_number;
33*9c067b84SDoug Ambrisko 	u8 type_specfic[11];
34*9c067b84SDoug Ambrisko 	u8 type_color;
35*9c067b84SDoug Ambrisko };
36*9c067b84SDoug Ambrisko 
37*9c067b84SDoug Ambrisko #define CQ_DESC_TYPE_BITS        4
38*9c067b84SDoug Ambrisko #define CQ_DESC_TYPE_MASK        ((1 << CQ_DESC_TYPE_BITS) - 1)
39*9c067b84SDoug Ambrisko #define CQ_DESC_COLOR_MASK       1
40*9c067b84SDoug Ambrisko #define CQ_DESC_COLOR_SHIFT      7
41*9c067b84SDoug Ambrisko #define CQ_DESC_COLOR_MASK_NOSHIFT 0x80
42*9c067b84SDoug Ambrisko #define CQ_DESC_Q_NUM_BITS       10
43*9c067b84SDoug Ambrisko #define CQ_DESC_Q_NUM_MASK       ((1 << CQ_DESC_Q_NUM_BITS) - 1)
44*9c067b84SDoug Ambrisko #define CQ_DESC_COMP_NDX_BITS    12
45*9c067b84SDoug Ambrisko #define CQ_DESC_COMP_NDX_MASK    ((1 << CQ_DESC_COMP_NDX_BITS) - 1)
46*9c067b84SDoug Ambrisko 
cq_desc_enc(struct cq_desc * desc,const u8 type,const u8 color,const u16 q_number,const u16 completed_index)47*9c067b84SDoug Ambrisko static inline void cq_desc_enc(struct cq_desc *desc,
48*9c067b84SDoug Ambrisko 	const u8 type, const u8 color, const u16 q_number,
49*9c067b84SDoug Ambrisko 	const u16 completed_index)
50*9c067b84SDoug Ambrisko {
51*9c067b84SDoug Ambrisko 	desc->type_color = (type & CQ_DESC_TYPE_MASK) |
52*9c067b84SDoug Ambrisko 		((color & CQ_DESC_COLOR_MASK) << CQ_DESC_COLOR_SHIFT);
53*9c067b84SDoug Ambrisko 	desc->q_number = cpu_to_le16(q_number & CQ_DESC_Q_NUM_MASK);
54*9c067b84SDoug Ambrisko 	desc->completed_index = cpu_to_le16(completed_index &
55*9c067b84SDoug Ambrisko 		CQ_DESC_COMP_NDX_MASK);
56*9c067b84SDoug Ambrisko }
57*9c067b84SDoug Ambrisko 
cq_desc_dec(const struct cq_desc * desc_arg,u8 * type,u8 * color,u16 * q_number,u16 * completed_index)58*9c067b84SDoug Ambrisko static inline void cq_desc_dec(const struct cq_desc *desc_arg,
59*9c067b84SDoug Ambrisko 	u8 *type, u8 *color, u16 *q_number, u16 *completed_index)
60*9c067b84SDoug Ambrisko {
61*9c067b84SDoug Ambrisko 	const struct cq_desc *desc = desc_arg;
62*9c067b84SDoug Ambrisko 	const u8 type_color = desc->type_color;
63*9c067b84SDoug Ambrisko 
64*9c067b84SDoug Ambrisko 	*color = (type_color >> CQ_DESC_COLOR_SHIFT) & CQ_DESC_COLOR_MASK;
65*9c067b84SDoug Ambrisko 
66*9c067b84SDoug Ambrisko 	/*
67*9c067b84SDoug Ambrisko 	 * Make sure color bit is read from desc *before* other fields
68*9c067b84SDoug Ambrisko 	 * are read from desc.  Hardware guarantees color bit is last
69*9c067b84SDoug Ambrisko 	 * bit (byte) written.  Adding the rmb() prevents the compiler
70*9c067b84SDoug Ambrisko 	 * and/or CPU from reordering the reads which would potentially
71*9c067b84SDoug Ambrisko 	 * result in reading stale values.
72*9c067b84SDoug Ambrisko 	 */
73*9c067b84SDoug Ambrisko 
74*9c067b84SDoug Ambrisko 	rmb();
75*9c067b84SDoug Ambrisko 
76*9c067b84SDoug Ambrisko 	*type = type_color & CQ_DESC_TYPE_MASK;
77*9c067b84SDoug Ambrisko 	*q_number = le16_to_cpu(desc->q_number) & CQ_DESC_Q_NUM_MASK;
78*9c067b84SDoug Ambrisko 	*completed_index = le16_to_cpu(desc->completed_index) &
79*9c067b84SDoug Ambrisko 		CQ_DESC_COMP_NDX_MASK;
80*9c067b84SDoug Ambrisko }
81*9c067b84SDoug Ambrisko 
82*9c067b84SDoug Ambrisko #endif /* _CQ_DESC_H_ */
83