xref: /linux/drivers/net/ethernet/cisco/enic/vnic_cq.h (revision e5451c8f8330e03ad3cfa16048b4daf961af434f)
101f2e4eaSScott Feldman /*
229046f9bSVasanthy Kolluri  * Copyright 2008-2010 Cisco Systems, Inc.  All rights reserved.
301f2e4eaSScott Feldman  * Copyright 2007 Nuova Systems, Inc.  All rights reserved.
401f2e4eaSScott Feldman  *
501f2e4eaSScott Feldman  * This program is free software; you may redistribute it and/or modify
601f2e4eaSScott Feldman  * it under the terms of the GNU General Public License as published by
701f2e4eaSScott Feldman  * the Free Software Foundation; version 2 of the License.
801f2e4eaSScott Feldman  *
901f2e4eaSScott Feldman  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1001f2e4eaSScott Feldman  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1101f2e4eaSScott Feldman  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1201f2e4eaSScott Feldman  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
1301f2e4eaSScott Feldman  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
1401f2e4eaSScott Feldman  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1501f2e4eaSScott Feldman  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1601f2e4eaSScott Feldman  * SOFTWARE.
1701f2e4eaSScott Feldman  *
1801f2e4eaSScott Feldman  */
1901f2e4eaSScott Feldman 
2001f2e4eaSScott Feldman #ifndef _VNIC_CQ_H_
2101f2e4eaSScott Feldman #define _VNIC_CQ_H_
2201f2e4eaSScott Feldman 
2301f2e4eaSScott Feldman #include "cq_desc.h"
2401f2e4eaSScott Feldman #include "vnic_dev.h"
2501f2e4eaSScott Feldman 
2601f2e4eaSScott Feldman /* Completion queue control */
2701f2e4eaSScott Feldman struct vnic_cq_ctrl {
2801f2e4eaSScott Feldman 	u64 ring_base;			/* 0x00 */
2901f2e4eaSScott Feldman 	u32 ring_size;			/* 0x08 */
3001f2e4eaSScott Feldman 	u32 pad0;
3101f2e4eaSScott Feldman 	u32 flow_control_enable;	/* 0x10 */
3201f2e4eaSScott Feldman 	u32 pad1;
3301f2e4eaSScott Feldman 	u32 color_enable;		/* 0x18 */
3401f2e4eaSScott Feldman 	u32 pad2;
3501f2e4eaSScott Feldman 	u32 cq_head;			/* 0x20 */
3601f2e4eaSScott Feldman 	u32 pad3;
3701f2e4eaSScott Feldman 	u32 cq_tail;			/* 0x28 */
3801f2e4eaSScott Feldman 	u32 pad4;
3901f2e4eaSScott Feldman 	u32 cq_tail_color;		/* 0x30 */
4001f2e4eaSScott Feldman 	u32 pad5;
4101f2e4eaSScott Feldman 	u32 interrupt_enable;		/* 0x38 */
4201f2e4eaSScott Feldman 	u32 pad6;
4301f2e4eaSScott Feldman 	u32 cq_entry_enable;		/* 0x40 */
4401f2e4eaSScott Feldman 	u32 pad7;
4501f2e4eaSScott Feldman 	u32 cq_message_enable;		/* 0x48 */
4601f2e4eaSScott Feldman 	u32 pad8;
4701f2e4eaSScott Feldman 	u32 interrupt_offset;		/* 0x50 */
4801f2e4eaSScott Feldman 	u32 pad9;
4901f2e4eaSScott Feldman 	u64 cq_message_addr;		/* 0x58 */
5001f2e4eaSScott Feldman 	u32 pad10;
5101f2e4eaSScott Feldman };
5201f2e4eaSScott Feldman 
53*7c2ce6e6SSujith Sankar struct vnic_rx_bytes_counter {
54*7c2ce6e6SSujith Sankar 	unsigned int small_pkt_bytes_cnt;
55*7c2ce6e6SSujith Sankar 	unsigned int large_pkt_bytes_cnt;
56*7c2ce6e6SSujith Sankar };
57*7c2ce6e6SSujith Sankar 
5801f2e4eaSScott Feldman struct vnic_cq {
5901f2e4eaSScott Feldman 	unsigned int index;
6001f2e4eaSScott Feldman 	struct vnic_dev *vdev;
6101f2e4eaSScott Feldman 	struct vnic_cq_ctrl __iomem *ctrl;              /* memory-mapped */
6201f2e4eaSScott Feldman 	struct vnic_dev_ring ring;
6301f2e4eaSScott Feldman 	unsigned int to_clean;
6401f2e4eaSScott Feldman 	unsigned int last_color;
657d260ec2SVasanthy Kolluri 	unsigned int interrupt_offset;
66*7c2ce6e6SSujith Sankar 	struct vnic_rx_bytes_counter pkt_size_counter;
67*7c2ce6e6SSujith Sankar 	unsigned int cur_rx_coal_timeval;
68*7c2ce6e6SSujith Sankar 	unsigned int tobe_rx_coal_timeval;
69*7c2ce6e6SSujith Sankar 	ktime_t prev_ts;
7001f2e4eaSScott Feldman };
7101f2e4eaSScott Feldman 
7201f2e4eaSScott Feldman static inline unsigned int vnic_cq_service(struct vnic_cq *cq,
7301f2e4eaSScott Feldman 	unsigned int work_to_do,
7401f2e4eaSScott Feldman 	int (*q_service)(struct vnic_dev *vdev, struct cq_desc *cq_desc,
7501f2e4eaSScott Feldman 	u8 type, u16 q_number, u16 completed_index, void *opaque),
7601f2e4eaSScott Feldman 	void *opaque)
7701f2e4eaSScott Feldman {
7801f2e4eaSScott Feldman 	struct cq_desc *cq_desc;
7901f2e4eaSScott Feldman 	unsigned int work_done = 0;
8001f2e4eaSScott Feldman 	u16 q_number, completed_index;
8101f2e4eaSScott Feldman 	u8 type, color;
8201f2e4eaSScott Feldman 
8301f2e4eaSScott Feldman 	cq_desc = (struct cq_desc *)((u8 *)cq->ring.descs +
8401f2e4eaSScott Feldman 		cq->ring.desc_size * cq->to_clean);
8501f2e4eaSScott Feldman 	cq_desc_dec(cq_desc, &type, &color,
8601f2e4eaSScott Feldman 		&q_number, &completed_index);
8701f2e4eaSScott Feldman 
8801f2e4eaSScott Feldman 	while (color != cq->last_color) {
8901f2e4eaSScott Feldman 
9001f2e4eaSScott Feldman 		if ((*q_service)(cq->vdev, cq_desc, type,
9101f2e4eaSScott Feldman 			q_number, completed_index, opaque))
9201f2e4eaSScott Feldman 			break;
9301f2e4eaSScott Feldman 
9401f2e4eaSScott Feldman 		cq->to_clean++;
9501f2e4eaSScott Feldman 		if (cq->to_clean == cq->ring.desc_count) {
9601f2e4eaSScott Feldman 			cq->to_clean = 0;
9701f2e4eaSScott Feldman 			cq->last_color = cq->last_color ? 0 : 1;
9801f2e4eaSScott Feldman 		}
9901f2e4eaSScott Feldman 
10001f2e4eaSScott Feldman 		cq_desc = (struct cq_desc *)((u8 *)cq->ring.descs +
10101f2e4eaSScott Feldman 			cq->ring.desc_size * cq->to_clean);
10201f2e4eaSScott Feldman 		cq_desc_dec(cq_desc, &type, &color,
10301f2e4eaSScott Feldman 			&q_number, &completed_index);
10401f2e4eaSScott Feldman 
10501f2e4eaSScott Feldman 		work_done++;
10601f2e4eaSScott Feldman 		if (work_done >= work_to_do)
10701f2e4eaSScott Feldman 			break;
10801f2e4eaSScott Feldman 	}
10901f2e4eaSScott Feldman 
11001f2e4eaSScott Feldman 	return work_done;
11101f2e4eaSScott Feldman }
11201f2e4eaSScott Feldman 
11301f2e4eaSScott Feldman void vnic_cq_free(struct vnic_cq *cq);
11401f2e4eaSScott Feldman int vnic_cq_alloc(struct vnic_dev *vdev, struct vnic_cq *cq, unsigned int index,
11501f2e4eaSScott Feldman 	unsigned int desc_count, unsigned int desc_size);
11601f2e4eaSScott Feldman void vnic_cq_init(struct vnic_cq *cq, unsigned int flow_control_enable,
11701f2e4eaSScott Feldman 	unsigned int color_enable, unsigned int cq_head, unsigned int cq_tail,
11801f2e4eaSScott Feldman 	unsigned int cq_tail_color, unsigned int interrupt_enable,
11901f2e4eaSScott Feldman 	unsigned int cq_entry_enable, unsigned int message_enable,
12001f2e4eaSScott Feldman 	unsigned int interrupt_offset, u64 message_addr);
12101f2e4eaSScott Feldman void vnic_cq_clean(struct vnic_cq *cq);
12201f2e4eaSScott Feldman 
12301f2e4eaSScott Feldman #endif /* _VNIC_CQ_H_ */
124