1*e6550b3eSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */ 25df6d737SAbhijeet Joglekar /* 35df6d737SAbhijeet Joglekar * Copyright 2008 Cisco Systems, Inc. All rights reserved. 45df6d737SAbhijeet Joglekar * Copyright 2007 Nuova Systems, Inc. All rights reserved. 55df6d737SAbhijeet Joglekar */ 65df6d737SAbhijeet Joglekar #ifndef _VNIC_CQ_H_ 75df6d737SAbhijeet Joglekar #define _VNIC_CQ_H_ 85df6d737SAbhijeet Joglekar 95df6d737SAbhijeet Joglekar #include "cq_desc.h" 105df6d737SAbhijeet Joglekar #include "vnic_dev.h" 115df6d737SAbhijeet Joglekar 125df6d737SAbhijeet Joglekar /* 135df6d737SAbhijeet Joglekar * These defines avoid symbol clash between fnic and enic (Cisco 10G Eth 145df6d737SAbhijeet Joglekar * Driver) when both are built with CONFIG options =y 155df6d737SAbhijeet Joglekar */ 165df6d737SAbhijeet Joglekar #define vnic_cq_service fnic_cq_service 175df6d737SAbhijeet Joglekar #define vnic_cq_free fnic_cq_free 185df6d737SAbhijeet Joglekar #define vnic_cq_alloc fnic_cq_alloc 195df6d737SAbhijeet Joglekar #define vnic_cq_init fnic_cq_init 205df6d737SAbhijeet Joglekar #define vnic_cq_clean fnic_cq_clean 215df6d737SAbhijeet Joglekar 225df6d737SAbhijeet Joglekar /* Completion queue control */ 235df6d737SAbhijeet Joglekar struct vnic_cq_ctrl { 245df6d737SAbhijeet Joglekar u64 ring_base; /* 0x00 */ 255df6d737SAbhijeet Joglekar u32 ring_size; /* 0x08 */ 265df6d737SAbhijeet Joglekar u32 pad0; 275df6d737SAbhijeet Joglekar u32 flow_control_enable; /* 0x10 */ 285df6d737SAbhijeet Joglekar u32 pad1; 295df6d737SAbhijeet Joglekar u32 color_enable; /* 0x18 */ 305df6d737SAbhijeet Joglekar u32 pad2; 315df6d737SAbhijeet Joglekar u32 cq_head; /* 0x20 */ 325df6d737SAbhijeet Joglekar u32 pad3; 335df6d737SAbhijeet Joglekar u32 cq_tail; /* 0x28 */ 345df6d737SAbhijeet Joglekar u32 pad4; 355df6d737SAbhijeet Joglekar u32 cq_tail_color; /* 0x30 */ 365df6d737SAbhijeet Joglekar u32 pad5; 375df6d737SAbhijeet Joglekar u32 interrupt_enable; /* 0x38 */ 385df6d737SAbhijeet Joglekar u32 pad6; 395df6d737SAbhijeet Joglekar u32 cq_entry_enable; /* 0x40 */ 405df6d737SAbhijeet Joglekar u32 pad7; 415df6d737SAbhijeet Joglekar u32 cq_message_enable; /* 0x48 */ 425df6d737SAbhijeet Joglekar u32 pad8; 435df6d737SAbhijeet Joglekar u32 interrupt_offset; /* 0x50 */ 445df6d737SAbhijeet Joglekar u32 pad9; 455df6d737SAbhijeet Joglekar u64 cq_message_addr; /* 0x58 */ 465df6d737SAbhijeet Joglekar u32 pad10; 475df6d737SAbhijeet Joglekar }; 485df6d737SAbhijeet Joglekar 495df6d737SAbhijeet Joglekar struct vnic_cq { 505df6d737SAbhijeet Joglekar unsigned int index; 515df6d737SAbhijeet Joglekar struct vnic_dev *vdev; 525df6d737SAbhijeet Joglekar struct vnic_cq_ctrl __iomem *ctrl; /* memory-mapped */ 535df6d737SAbhijeet Joglekar struct vnic_dev_ring ring; 545df6d737SAbhijeet Joglekar unsigned int to_clean; 555df6d737SAbhijeet Joglekar unsigned int last_color; 565df6d737SAbhijeet Joglekar }; 575df6d737SAbhijeet Joglekar 585df6d737SAbhijeet Joglekar static inline unsigned int vnic_cq_service(struct vnic_cq *cq, 595df6d737SAbhijeet Joglekar unsigned int work_to_do, 605df6d737SAbhijeet Joglekar int (*q_service)(struct vnic_dev *vdev, struct cq_desc *cq_desc, 615df6d737SAbhijeet Joglekar u8 type, u16 q_number, u16 completed_index, void *opaque), 625df6d737SAbhijeet Joglekar void *opaque) 635df6d737SAbhijeet Joglekar { 645df6d737SAbhijeet Joglekar struct cq_desc *cq_desc; 655df6d737SAbhijeet Joglekar unsigned int work_done = 0; 665df6d737SAbhijeet Joglekar u16 q_number, completed_index; 675df6d737SAbhijeet Joglekar u8 type, color; 685df6d737SAbhijeet Joglekar 695df6d737SAbhijeet Joglekar cq_desc = (struct cq_desc *)((u8 *)cq->ring.descs + 705df6d737SAbhijeet Joglekar cq->ring.desc_size * cq->to_clean); 715df6d737SAbhijeet Joglekar cq_desc_dec(cq_desc, &type, &color, 725df6d737SAbhijeet Joglekar &q_number, &completed_index); 735df6d737SAbhijeet Joglekar 745df6d737SAbhijeet Joglekar while (color != cq->last_color) { 755df6d737SAbhijeet Joglekar 765df6d737SAbhijeet Joglekar if ((*q_service)(cq->vdev, cq_desc, type, 775df6d737SAbhijeet Joglekar q_number, completed_index, opaque)) 785df6d737SAbhijeet Joglekar break; 795df6d737SAbhijeet Joglekar 805df6d737SAbhijeet Joglekar cq->to_clean++; 815df6d737SAbhijeet Joglekar if (cq->to_clean == cq->ring.desc_count) { 825df6d737SAbhijeet Joglekar cq->to_clean = 0; 835df6d737SAbhijeet Joglekar cq->last_color = cq->last_color ? 0 : 1; 845df6d737SAbhijeet Joglekar } 855df6d737SAbhijeet Joglekar 865df6d737SAbhijeet Joglekar cq_desc = (struct cq_desc *)((u8 *)cq->ring.descs + 875df6d737SAbhijeet Joglekar cq->ring.desc_size * cq->to_clean); 885df6d737SAbhijeet Joglekar cq_desc_dec(cq_desc, &type, &color, 895df6d737SAbhijeet Joglekar &q_number, &completed_index); 905df6d737SAbhijeet Joglekar 915df6d737SAbhijeet Joglekar work_done++; 925df6d737SAbhijeet Joglekar if (work_done >= work_to_do) 935df6d737SAbhijeet Joglekar break; 945df6d737SAbhijeet Joglekar } 955df6d737SAbhijeet Joglekar 965df6d737SAbhijeet Joglekar return work_done; 975df6d737SAbhijeet Joglekar } 985df6d737SAbhijeet Joglekar 995df6d737SAbhijeet Joglekar void vnic_cq_free(struct vnic_cq *cq); 1005df6d737SAbhijeet Joglekar int vnic_cq_alloc(struct vnic_dev *vdev, struct vnic_cq *cq, unsigned int index, 1015df6d737SAbhijeet Joglekar unsigned int desc_count, unsigned int desc_size); 1025df6d737SAbhijeet Joglekar void vnic_cq_init(struct vnic_cq *cq, unsigned int flow_control_enable, 1035df6d737SAbhijeet Joglekar unsigned int color_enable, unsigned int cq_head, unsigned int cq_tail, 1045df6d737SAbhijeet Joglekar unsigned int cq_tail_color, unsigned int interrupt_enable, 1055df6d737SAbhijeet Joglekar unsigned int cq_entry_enable, unsigned int message_enable, 1065df6d737SAbhijeet Joglekar unsigned int interrupt_offset, u64 message_addr); 1075df6d737SAbhijeet Joglekar void vnic_cq_clean(struct vnic_cq *cq); 1085df6d737SAbhijeet Joglekar 1095df6d737SAbhijeet Joglekar #endif /* _VNIC_CQ_H_ */ 110