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