New upstream version 18.02
[deb_dpdk.git] / drivers / net / enic / base / vnic_rq.c
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 "vnic_dev.h"
7 #include "vnic_rq.h"
8
9 void vnic_rq_free(struct vnic_rq *rq)
10 {
11         struct vnic_dev *vdev;
12
13         vdev = rq->vdev;
14
15         vnic_dev_free_desc_ring(vdev, &rq->ring);
16
17         rq->ctrl = NULL;
18 }
19
20 int vnic_rq_alloc(struct vnic_dev *vdev, struct vnic_rq *rq, unsigned int index,
21         unsigned int desc_count, unsigned int desc_size)
22 {
23         int rc;
24         char res_name[NAME_MAX];
25         static int instance;
26
27         rq->index = index;
28         rq->vdev = vdev;
29
30         rq->ctrl = vnic_dev_get_res(vdev, RES_TYPE_RQ, index);
31         if (!rq->ctrl) {
32                 pr_err("Failed to hook RQ[%u] resource\n", index);
33                 return -EINVAL;
34         }
35
36         vnic_rq_disable(rq);
37
38         snprintf(res_name, sizeof(res_name), "%d-rq-%u", instance++, index);
39         rc = vnic_dev_alloc_desc_ring(vdev, &rq->ring, desc_count, desc_size,
40                 rq->socket_id, res_name);
41         return rc;
42 }
43
44 void vnic_rq_init_start(struct vnic_rq *rq, unsigned int cq_index,
45         unsigned int fetch_index, unsigned int posted_index,
46         unsigned int error_interrupt_enable,
47         unsigned int error_interrupt_offset)
48 {
49         u64 paddr;
50         unsigned int count = rq->ring.desc_count;
51
52         paddr = (u64)rq->ring.base_addr | VNIC_PADDR_TARGET;
53         writeq(paddr, &rq->ctrl->ring_base);
54         iowrite32(count, &rq->ctrl->ring_size);
55         iowrite32(cq_index, &rq->ctrl->cq_index);
56         iowrite32(error_interrupt_enable, &rq->ctrl->error_interrupt_enable);
57         iowrite32(error_interrupt_offset, &rq->ctrl->error_interrupt_offset);
58         iowrite32(0, &rq->ctrl->error_status);
59         iowrite32(fetch_index, &rq->ctrl->fetch_index);
60         iowrite32(posted_index, &rq->ctrl->posted_index);
61         if (rq->data_queue_enable)
62                 iowrite32(((1 << 10) | rq->data_queue_idx),
63                           &rq->ctrl->data_ring);
64         else
65                 iowrite32(0, &rq->ctrl->data_ring);
66 }
67
68 void vnic_rq_init(struct vnic_rq *rq, unsigned int cq_index,
69         unsigned int error_interrupt_enable,
70         unsigned int error_interrupt_offset)
71 {
72         u32 fetch_index = 0;
73
74         /* Use current fetch_index as the ring starting point */
75         fetch_index = ioread32(&rq->ctrl->fetch_index);
76
77         if (fetch_index == 0xFFFFFFFF) { /* check for hardware gone  */
78                 /* Hardware surprise removal: reset fetch_index */
79                 fetch_index = 0;
80         }
81
82         vnic_rq_init_start(rq, cq_index,
83                 fetch_index, fetch_index,
84                 error_interrupt_enable,
85                 error_interrupt_offset);
86         rq->rxst_idx = 0;
87         rq->tot_pkts = 0;
88         rq->pkt_first_seg = NULL;
89         rq->pkt_last_seg = NULL;
90 }
91
92 unsigned int vnic_rq_error_status(struct vnic_rq *rq)
93 {
94         return ioread32(&rq->ctrl->error_status);
95 }
96
97 void vnic_rq_enable(struct vnic_rq *rq)
98 {
99         iowrite32(1, &rq->ctrl->enable);
100 }
101
102 int vnic_rq_disable(struct vnic_rq *rq)
103 {
104         unsigned int wait;
105
106         iowrite32(0, &rq->ctrl->enable);
107
108         /* Wait for HW to ACK disable request */
109         for (wait = 0; wait < 1000; wait++) {
110                 if (!(ioread32(&rq->ctrl->running)))
111                         return 0;
112                 udelay(10);
113         }
114
115         pr_err("Failed to disable RQ[%d]\n", rq->index);
116
117         return -ETIMEDOUT;
118 }
119
120 void vnic_rq_clean(struct vnic_rq *rq,
121         void (*buf_clean)(struct rte_mbuf **buf))
122 {
123         struct rte_mbuf **buf;
124         u32 fetch_index, i;
125         unsigned int count = rq->ring.desc_count;
126
127         buf = &rq->mbuf_ring[0];
128
129         for (i = 0; i < count; i++) {
130                 (*buf_clean)(buf);
131                 buf++;
132         }
133         rq->ring.desc_avail = count - 1;
134         rq->rx_nb_hold = 0;
135
136         /* Use current fetch_index as the ring starting point */
137         fetch_index = ioread32(&rq->ctrl->fetch_index);
138
139         if (fetch_index == 0xFFFFFFFF) { /* check for hardware gone  */
140                 /* Hardware surprise removal: reset fetch_index */
141                 fetch_index = 0;
142         }
143
144         iowrite32(fetch_index, &rq->ctrl->posted_index);
145
146         vnic_dev_clear_desc_ring(&rq->ring);
147 }