1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /* Copyright 2014 Cisco Systems, Inc. All rights reserved. */
10 /* Completion queue control */
12 u64 ring_base
; /* 0x00 */
13 u32 ring_size
; /* 0x08 */
15 u32 flow_control_enable
; /* 0x10 */
17 u32 color_enable
; /* 0x18 */
19 u32 cq_head
; /* 0x20 */
21 u32 cq_tail
; /* 0x28 */
23 u32 cq_tail_color
; /* 0x30 */
25 u32 interrupt_enable
; /* 0x38 */
27 u32 cq_entry_enable
; /* 0x40 */
29 u32 cq_message_enable
; /* 0x48 */
31 u32 interrupt_offset
; /* 0x50 */
33 u64 cq_message_addr
; /* 0x58 */
39 struct vnic_dev
*vdev
;
40 struct vnic_cq_ctrl __iomem
*ctrl
; /* memory-mapped */
41 struct vnic_dev_ring ring
;
42 unsigned int to_clean
;
43 unsigned int last_color
;
46 static inline unsigned int svnic_cq_service(struct vnic_cq
*cq
,
47 unsigned int work_to_do
,
48 int (*q_service
)(struct vnic_dev
*vdev
, struct cq_desc
*cq_desc
,
49 u8 type
, u16 q_number
, u16 completed_index
, void *opaque
),
52 struct cq_desc
*cq_desc
;
53 unsigned int work_done
= 0;
54 u16 q_number
, completed_index
;
57 cq_desc
= (struct cq_desc
*)((u8
*)cq
->ring
.descs
+
58 cq
->ring
.desc_size
* cq
->to_clean
);
59 cq_desc_dec(cq_desc
, &type
, &color
,
60 &q_number
, &completed_index
);
62 while (color
!= cq
->last_color
) {
64 if ((*q_service
)(cq
->vdev
, cq_desc
, type
,
65 q_number
, completed_index
, opaque
))
69 if (cq
->to_clean
== cq
->ring
.desc_count
) {
71 cq
->last_color
= cq
->last_color
? 0 : 1;
74 cq_desc
= (struct cq_desc
*)((u8
*)cq
->ring
.descs
+
75 cq
->ring
.desc_size
* cq
->to_clean
);
76 cq_desc_dec(cq_desc
, &type
, &color
,
77 &q_number
, &completed_index
);
80 if (work_done
>= work_to_do
)
87 void svnic_cq_free(struct vnic_cq
*cq
);
88 int svnic_cq_alloc(struct vnic_dev
*vdev
, struct vnic_cq
*cq
,
89 unsigned int index
, unsigned int desc_count
, unsigned int desc_size
);
90 void svnic_cq_init(struct vnic_cq
*cq
, unsigned int flow_control_enable
,
91 unsigned int color_enable
, unsigned int cq_head
, unsigned int cq_tail
,
92 unsigned int cq_tail_color
, unsigned int interrupt_enable
,
93 unsigned int cq_entry_enable
, unsigned int message_enable
,
94 unsigned int interrupt_offset
, u64 message_addr
);
95 void svnic_cq_clean(struct vnic_cq
*cq
);
96 #endif /* _VNIC_CQ_H_ */