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