1*5df6d737SAbhijeet Joglekar /* 2*5df6d737SAbhijeet Joglekar * Copyright 2008 Cisco Systems, Inc. All rights reserved. 3*5df6d737SAbhijeet Joglekar * Copyright 2007 Nuova Systems, Inc. All rights reserved. 4*5df6d737SAbhijeet Joglekar * 5*5df6d737SAbhijeet Joglekar * This program is free software; you may redistribute it and/or modify 6*5df6d737SAbhijeet Joglekar * it under the terms of the GNU General Public License as published by 7*5df6d737SAbhijeet Joglekar * the Free Software Foundation; version 2 of the License. 8*5df6d737SAbhijeet Joglekar * 9*5df6d737SAbhijeet Joglekar * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 10*5df6d737SAbhijeet Joglekar * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 11*5df6d737SAbhijeet Joglekar * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 12*5df6d737SAbhijeet Joglekar * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 13*5df6d737SAbhijeet Joglekar * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 14*5df6d737SAbhijeet Joglekar * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 15*5df6d737SAbhijeet Joglekar * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 16*5df6d737SAbhijeet Joglekar * SOFTWARE. 17*5df6d737SAbhijeet Joglekar */ 18*5df6d737SAbhijeet Joglekar #ifndef _VNIC_CQ_H_ 19*5df6d737SAbhijeet Joglekar #define _VNIC_CQ_H_ 20*5df6d737SAbhijeet Joglekar 21*5df6d737SAbhijeet Joglekar #include "cq_desc.h" 22*5df6d737SAbhijeet Joglekar #include "vnic_dev.h" 23*5df6d737SAbhijeet Joglekar 24*5df6d737SAbhijeet Joglekar /* 25*5df6d737SAbhijeet Joglekar * These defines avoid symbol clash between fnic and enic (Cisco 10G Eth 26*5df6d737SAbhijeet Joglekar * Driver) when both are built with CONFIG options =y 27*5df6d737SAbhijeet Joglekar */ 28*5df6d737SAbhijeet Joglekar #define vnic_cq_service fnic_cq_service 29*5df6d737SAbhijeet Joglekar #define vnic_cq_free fnic_cq_free 30*5df6d737SAbhijeet Joglekar #define vnic_cq_alloc fnic_cq_alloc 31*5df6d737SAbhijeet Joglekar #define vnic_cq_init fnic_cq_init 32*5df6d737SAbhijeet Joglekar #define vnic_cq_clean fnic_cq_clean 33*5df6d737SAbhijeet Joglekar 34*5df6d737SAbhijeet Joglekar /* Completion queue control */ 35*5df6d737SAbhijeet Joglekar struct vnic_cq_ctrl { 36*5df6d737SAbhijeet Joglekar u64 ring_base; /* 0x00 */ 37*5df6d737SAbhijeet Joglekar u32 ring_size; /* 0x08 */ 38*5df6d737SAbhijeet Joglekar u32 pad0; 39*5df6d737SAbhijeet Joglekar u32 flow_control_enable; /* 0x10 */ 40*5df6d737SAbhijeet Joglekar u32 pad1; 41*5df6d737SAbhijeet Joglekar u32 color_enable; /* 0x18 */ 42*5df6d737SAbhijeet Joglekar u32 pad2; 43*5df6d737SAbhijeet Joglekar u32 cq_head; /* 0x20 */ 44*5df6d737SAbhijeet Joglekar u32 pad3; 45*5df6d737SAbhijeet Joglekar u32 cq_tail; /* 0x28 */ 46*5df6d737SAbhijeet Joglekar u32 pad4; 47*5df6d737SAbhijeet Joglekar u32 cq_tail_color; /* 0x30 */ 48*5df6d737SAbhijeet Joglekar u32 pad5; 49*5df6d737SAbhijeet Joglekar u32 interrupt_enable; /* 0x38 */ 50*5df6d737SAbhijeet Joglekar u32 pad6; 51*5df6d737SAbhijeet Joglekar u32 cq_entry_enable; /* 0x40 */ 52*5df6d737SAbhijeet Joglekar u32 pad7; 53*5df6d737SAbhijeet Joglekar u32 cq_message_enable; /* 0x48 */ 54*5df6d737SAbhijeet Joglekar u32 pad8; 55*5df6d737SAbhijeet Joglekar u32 interrupt_offset; /* 0x50 */ 56*5df6d737SAbhijeet Joglekar u32 pad9; 57*5df6d737SAbhijeet Joglekar u64 cq_message_addr; /* 0x58 */ 58*5df6d737SAbhijeet Joglekar u32 pad10; 59*5df6d737SAbhijeet Joglekar }; 60*5df6d737SAbhijeet Joglekar 61*5df6d737SAbhijeet Joglekar struct vnic_cq { 62*5df6d737SAbhijeet Joglekar unsigned int index; 63*5df6d737SAbhijeet Joglekar struct vnic_dev *vdev; 64*5df6d737SAbhijeet Joglekar struct vnic_cq_ctrl __iomem *ctrl; /* memory-mapped */ 65*5df6d737SAbhijeet Joglekar struct vnic_dev_ring ring; 66*5df6d737SAbhijeet Joglekar unsigned int to_clean; 67*5df6d737SAbhijeet Joglekar unsigned int last_color; 68*5df6d737SAbhijeet Joglekar }; 69*5df6d737SAbhijeet Joglekar 70*5df6d737SAbhijeet Joglekar static inline unsigned int vnic_cq_service(struct vnic_cq *cq, 71*5df6d737SAbhijeet Joglekar unsigned int work_to_do, 72*5df6d737SAbhijeet Joglekar int (*q_service)(struct vnic_dev *vdev, struct cq_desc *cq_desc, 73*5df6d737SAbhijeet Joglekar u8 type, u16 q_number, u16 completed_index, void *opaque), 74*5df6d737SAbhijeet Joglekar void *opaque) 75*5df6d737SAbhijeet Joglekar { 76*5df6d737SAbhijeet Joglekar struct cq_desc *cq_desc; 77*5df6d737SAbhijeet Joglekar unsigned int work_done = 0; 78*5df6d737SAbhijeet Joglekar u16 q_number, completed_index; 79*5df6d737SAbhijeet Joglekar u8 type, color; 80*5df6d737SAbhijeet Joglekar 81*5df6d737SAbhijeet Joglekar cq_desc = (struct cq_desc *)((u8 *)cq->ring.descs + 82*5df6d737SAbhijeet Joglekar cq->ring.desc_size * cq->to_clean); 83*5df6d737SAbhijeet Joglekar cq_desc_dec(cq_desc, &type, &color, 84*5df6d737SAbhijeet Joglekar &q_number, &completed_index); 85*5df6d737SAbhijeet Joglekar 86*5df6d737SAbhijeet Joglekar while (color != cq->last_color) { 87*5df6d737SAbhijeet Joglekar 88*5df6d737SAbhijeet Joglekar if ((*q_service)(cq->vdev, cq_desc, type, 89*5df6d737SAbhijeet Joglekar q_number, completed_index, opaque)) 90*5df6d737SAbhijeet Joglekar break; 91*5df6d737SAbhijeet Joglekar 92*5df6d737SAbhijeet Joglekar cq->to_clean++; 93*5df6d737SAbhijeet Joglekar if (cq->to_clean == cq->ring.desc_count) { 94*5df6d737SAbhijeet Joglekar cq->to_clean = 0; 95*5df6d737SAbhijeet Joglekar cq->last_color = cq->last_color ? 0 : 1; 96*5df6d737SAbhijeet Joglekar } 97*5df6d737SAbhijeet Joglekar 98*5df6d737SAbhijeet Joglekar cq_desc = (struct cq_desc *)((u8 *)cq->ring.descs + 99*5df6d737SAbhijeet Joglekar cq->ring.desc_size * cq->to_clean); 100*5df6d737SAbhijeet Joglekar cq_desc_dec(cq_desc, &type, &color, 101*5df6d737SAbhijeet Joglekar &q_number, &completed_index); 102*5df6d737SAbhijeet Joglekar 103*5df6d737SAbhijeet Joglekar work_done++; 104*5df6d737SAbhijeet Joglekar if (work_done >= work_to_do) 105*5df6d737SAbhijeet Joglekar break; 106*5df6d737SAbhijeet Joglekar } 107*5df6d737SAbhijeet Joglekar 108*5df6d737SAbhijeet Joglekar return work_done; 109*5df6d737SAbhijeet Joglekar } 110*5df6d737SAbhijeet Joglekar 111*5df6d737SAbhijeet Joglekar void vnic_cq_free(struct vnic_cq *cq); 112*5df6d737SAbhijeet Joglekar int vnic_cq_alloc(struct vnic_dev *vdev, struct vnic_cq *cq, unsigned int index, 113*5df6d737SAbhijeet Joglekar unsigned int desc_count, unsigned int desc_size); 114*5df6d737SAbhijeet Joglekar void vnic_cq_init(struct vnic_cq *cq, unsigned int flow_control_enable, 115*5df6d737SAbhijeet Joglekar unsigned int color_enable, unsigned int cq_head, unsigned int cq_tail, 116*5df6d737SAbhijeet Joglekar unsigned int cq_tail_color, unsigned int interrupt_enable, 117*5df6d737SAbhijeet Joglekar unsigned int cq_entry_enable, unsigned int message_enable, 118*5df6d737SAbhijeet Joglekar unsigned int interrupt_offset, u64 message_addr); 119*5df6d737SAbhijeet Joglekar void vnic_cq_clean(struct vnic_cq *cq); 120*5df6d737SAbhijeet Joglekar 121*5df6d737SAbhijeet Joglekar #endif /* _VNIC_CQ_H_ */ 122