xref: /freebsd/sys/dev/enic/vnic_rq.c (revision 9c067b84)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2008-2017 Cisco Systems, Inc.  All rights reserved.
3  * Copyright 2007 Nuova Systems, Inc.  All rights reserved.
4  */
5 
6 #include "enic.h"
7 #include "vnic_dev.h"
8 #include "vnic_rq.h"
9 
vnic_rq_init_start(struct vnic_rq * rq,unsigned int cq_index,unsigned int fetch_index,unsigned int posted_index,unsigned int error_interrupt_enable,unsigned int error_interrupt_offset)10 void vnic_rq_init_start(struct vnic_rq *rq, unsigned int cq_index,
11     unsigned int fetch_index, unsigned int posted_index,
12     unsigned int error_interrupt_enable,
13     unsigned int error_interrupt_offset)
14 {
15 	u64 paddr;
16 	unsigned int count = rq->ring.desc_count;
17 
18 	paddr = (u64)rq->ring.base_addr | VNIC_PADDR_TARGET;
19 	ENIC_BUS_WRITE_8(rq->ctrl, RX_RING_BASE, paddr);
20 	ENIC_BUS_WRITE_4(rq->ctrl, RX_RING_SIZE, count);
21 	ENIC_BUS_WRITE_4(rq->ctrl, RX_CQ_INDEX, cq_index);
22 	ENIC_BUS_WRITE_4(rq->ctrl, RX_ERROR_INTR_ENABLE, error_interrupt_enable);
23 	ENIC_BUS_WRITE_4(rq->ctrl, RX_ERROR_INTR_OFFSET, error_interrupt_offset);
24 	ENIC_BUS_WRITE_4(rq->ctrl, RX_ERROR_STATUS, 0);
25 	ENIC_BUS_WRITE_4(rq->ctrl, RX_FETCH_INDEX, fetch_index);
26 	ENIC_BUS_WRITE_4(rq->ctrl, RX_POSTED_INDEX, posted_index);
27 }
28 
vnic_rq_init(struct vnic_rq * rq,unsigned int cq_index,unsigned int error_interrupt_enable,unsigned int error_interrupt_offset)29 void vnic_rq_init(struct vnic_rq *rq, unsigned int cq_index,
30     unsigned int error_interrupt_enable,
31     unsigned int error_interrupt_offset)
32 {
33 	u32 fetch_index = 0;
34 
35 	/* Use current fetch_index as the ring starting point */
36 	fetch_index = ENIC_BUS_READ_4(rq->ctrl, RX_FETCH_INDEX);
37 
38 	if (fetch_index == 0xFFFFFFFF) { /* check for hardware gone  */
39 		/* Hardware surprise removal: reset fetch_index */
40 		fetch_index = 0;
41 	}
42 
43 	vnic_rq_init_start(rq, cq_index,
44 		fetch_index, fetch_index,
45 		error_interrupt_enable,
46 		error_interrupt_offset);
47 	rq->rxst_idx = 0;
48 	rq->tot_pkts = 0;
49 }
50 
vnic_rq_error_status(struct vnic_rq * rq)51 unsigned int vnic_rq_error_status(struct vnic_rq *rq)
52 {
53 	return ENIC_BUS_READ_4(rq->ctrl, RX_ERROR_STATUS);
54 }
55 
vnic_rq_enable(struct vnic_rq * rq)56 void vnic_rq_enable(struct vnic_rq *rq)
57 {
58 	ENIC_BUS_WRITE_4(rq->ctrl, RX_ENABLE, 1);
59 }
60 
vnic_rq_disable(struct vnic_rq * rq)61 int vnic_rq_disable(struct vnic_rq *rq)
62 {
63 	unsigned int wait;
64 
65 	ENIC_BUS_WRITE_4(rq->ctrl, RX_ENABLE, 0);
66 
67 	/* Wait for HW to ACK disable request */
68 	for (wait = 0; wait < 1000; wait++) {
69 		if (!(ENIC_BUS_READ_4(rq->ctrl, RX_RUNNING)))
70 			return 0;
71 		udelay(10);
72 	}
73 
74 	pr_err("Failed to disable RQ[%d]\n", rq->index);
75 
76 	return -ETIMEDOUT;
77 }
78 
vnic_rq_clean(struct vnic_rq * rq)79 void vnic_rq_clean(struct vnic_rq *rq)
80 {
81 	u32 fetch_index;
82 	unsigned int count = rq->ring.desc_count;
83 
84 	rq->ring.desc_avail = count - 1;
85 	rq->rx_nb_hold = 0;
86 
87 	/* Use current fetch_index as the ring starting point */
88 	fetch_index = ENIC_BUS_READ_4(rq->ctrl, RX_FETCH_INDEX);
89 	if (fetch_index == 0xFFFFFFFF) { /* check for hardware gone  */
90 		/* Hardware surprise removal: reset fetch_index */
91 		fetch_index = 0;
92 	}
93 
94 	ENIC_BUS_WRITE_4(rq->ctrl, RX_POSTED_INDEX, fetch_index);
95 
96 	vnic_dev_clear_desc_ring(&rq->ring);
97 }
98