2 * Copyright 2008 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * These defines avoid symbol clash between fnic and enic (Cisco 10G Eth
26 * Driver) when both are built with CONFIG options =y
28 #define vnic_cq_service fnic_cq_service
29 #define vnic_cq_free fnic_cq_free
30 #define vnic_cq_alloc fnic_cq_alloc
31 #define vnic_cq_init fnic_cq_init
32 #define vnic_cq_clean fnic_cq_clean
34 /* Completion queue control */
36 u64 ring_base
; /* 0x00 */
37 u32 ring_size
; /* 0x08 */
39 u32 flow_control_enable
; /* 0x10 */
41 u32 color_enable
; /* 0x18 */
43 u32 cq_head
; /* 0x20 */
45 u32 cq_tail
; /* 0x28 */
47 u32 cq_tail_color
; /* 0x30 */
49 u32 interrupt_enable
; /* 0x38 */
51 u32 cq_entry_enable
; /* 0x40 */
53 u32 cq_message_enable
; /* 0x48 */
55 u32 interrupt_offset
; /* 0x50 */
57 u64 cq_message_addr
; /* 0x58 */
63 struct vnic_dev
*vdev
;
64 struct vnic_cq_ctrl __iomem
*ctrl
; /* memory-mapped */
65 struct vnic_dev_ring ring
;
66 unsigned int to_clean
;
67 unsigned int last_color
;
70 static inline unsigned int vnic_cq_service(struct vnic_cq
*cq
,
71 unsigned int work_to_do
,
72 int (*q_service
)(struct vnic_dev
*vdev
, struct cq_desc
*cq_desc
,
73 u8 type
, u16 q_number
, u16 completed_index
, void *opaque
),
76 struct cq_desc
*cq_desc
;
77 unsigned int work_done
= 0;
78 u16 q_number
, completed_index
;
81 cq_desc
= (struct cq_desc
*)((u8
*)cq
->ring
.descs
+
82 cq
->ring
.desc_size
* cq
->to_clean
);
83 cq_desc_dec(cq_desc
, &type
, &color
,
84 &q_number
, &completed_index
);
86 while (color
!= cq
->last_color
) {
88 if ((*q_service
)(cq
->vdev
, cq_desc
, type
,
89 q_number
, completed_index
, opaque
))
93 if (cq
->to_clean
== cq
->ring
.desc_count
) {
95 cq
->last_color
= cq
->last_color
? 0 : 1;
98 cq_desc
= (struct cq_desc
*)((u8
*)cq
->ring
.descs
+
99 cq
->ring
.desc_size
* cq
->to_clean
);
100 cq_desc_dec(cq_desc
, &type
, &color
,
101 &q_number
, &completed_index
);
104 if (work_done
>= work_to_do
)
111 void vnic_cq_free(struct vnic_cq
*cq
);
112 int vnic_cq_alloc(struct vnic_dev
*vdev
, struct vnic_cq
*cq
, unsigned int index
,
113 unsigned int desc_count
, unsigned int desc_size
);
114 void vnic_cq_init(struct vnic_cq
*cq
, unsigned int flow_control_enable
,
115 unsigned int color_enable
, unsigned int cq_head
, unsigned int cq_tail
,
116 unsigned int cq_tail_color
, unsigned int interrupt_enable
,
117 unsigned int cq_entry_enable
, unsigned int message_enable
,
118 unsigned int interrupt_offset
, u64 message_addr
);
119 void vnic_cq_clean(struct vnic_cq
*cq
);
121 #endif /* _VNIC_CQ_H_ */