New upstream version 18.02
[deb_dpdk.git] / drivers / net / enic / base / vnic_wq.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_wq.h"
8
9 static inline
10 int vnic_wq_get_ctrl(struct vnic_dev *vdev, struct vnic_wq *wq,
11                                 unsigned int index, enum vnic_res_type res_type)
12 {
13         wq->ctrl = vnic_dev_get_res(vdev, res_type, index);
14         if (!wq->ctrl)
15                 return -EINVAL;
16         return 0;
17 }
18
19 static inline
20 int vnic_wq_alloc_ring(struct vnic_dev *vdev, struct vnic_wq *wq,
21                                 unsigned int desc_count, unsigned int desc_size)
22 {
23         char res_name[NAME_MAX];
24         static int instance;
25
26         snprintf(res_name, sizeof(res_name), "%d-wq-%u", instance++, wq->index);
27         return vnic_dev_alloc_desc_ring(vdev, &wq->ring, desc_count, desc_size,
28                 wq->socket_id, res_name);
29 }
30
31 static int vnic_wq_alloc_bufs(struct vnic_wq *wq)
32 {
33         unsigned int count = wq->ring.desc_count;
34        /* Allocate the mbuf ring */
35         wq->bufs = (struct vnic_wq_buf *)rte_zmalloc_socket("wq->bufs",
36                     sizeof(struct vnic_wq_buf) * count,
37                     RTE_CACHE_LINE_SIZE, wq->socket_id);
38         wq->head_idx = 0;
39         wq->tail_idx = 0;
40         if (wq->bufs == NULL)
41                 return -ENOMEM;
42         return 0;
43 }
44
45 void vnic_wq_free(struct vnic_wq *wq)
46 {
47         struct vnic_dev *vdev;
48
49         vdev = wq->vdev;
50
51         vnic_dev_free_desc_ring(vdev, &wq->ring);
52
53         rte_free(wq->bufs);
54         wq->ctrl = NULL;
55 }
56
57
58 int vnic_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq, unsigned int index,
59         unsigned int desc_count, unsigned int desc_size)
60 {
61         int err;
62
63         wq->index = index;
64         wq->vdev = vdev;
65
66         err = vnic_wq_get_ctrl(vdev, wq, index, RES_TYPE_WQ);
67         if (err) {
68                 pr_err("Failed to hook WQ[%d] resource, err %d\n", index, err);
69                 return err;
70         }
71
72         vnic_wq_disable(wq);
73
74         err = vnic_wq_alloc_ring(vdev, wq, desc_count, desc_size);
75         if (err)
76                 return err;
77
78         err = vnic_wq_alloc_bufs(wq);
79         if (err) {
80                 vnic_wq_free(wq);
81                 return err;
82         }
83
84         return 0;
85 }
86
87 void vnic_wq_init_start(struct vnic_wq *wq, unsigned int cq_index,
88         unsigned int fetch_index, unsigned int posted_index,
89         unsigned int error_interrupt_enable,
90         unsigned int error_interrupt_offset)
91 {
92         u64 paddr;
93         unsigned int count = wq->ring.desc_count;
94
95         paddr = (u64)wq->ring.base_addr | VNIC_PADDR_TARGET;
96         writeq(paddr, &wq->ctrl->ring_base);
97         iowrite32(count, &wq->ctrl->ring_size);
98         iowrite32(fetch_index, &wq->ctrl->fetch_index);
99         iowrite32(posted_index, &wq->ctrl->posted_index);
100         iowrite32(cq_index, &wq->ctrl->cq_index);
101         iowrite32(error_interrupt_enable, &wq->ctrl->error_interrupt_enable);
102         iowrite32(error_interrupt_offset, &wq->ctrl->error_interrupt_offset);
103         iowrite32(0, &wq->ctrl->error_status);
104
105         wq->head_idx = fetch_index;
106         wq->tail_idx = wq->head_idx;
107 }
108
109 void vnic_wq_init(struct vnic_wq *wq, unsigned int cq_index,
110         unsigned int error_interrupt_enable,
111         unsigned int error_interrupt_offset)
112 {
113         vnic_wq_init_start(wq, cq_index, 0, 0,
114                 error_interrupt_enable,
115                 error_interrupt_offset);
116         wq->last_completed_index = 0;
117 }
118
119 unsigned int vnic_wq_error_status(struct vnic_wq *wq)
120 {
121         return ioread32(&wq->ctrl->error_status);
122 }
123
124 void vnic_wq_enable(struct vnic_wq *wq)
125 {
126         iowrite32(1, &wq->ctrl->enable);
127 }
128
129 int vnic_wq_disable(struct vnic_wq *wq)
130 {
131         unsigned int wait;
132
133         iowrite32(0, &wq->ctrl->enable);
134
135         /* Wait for HW to ACK disable request */
136         for (wait = 0; wait < 1000; wait++) {
137                 if (!(ioread32(&wq->ctrl->running)))
138                         return 0;
139                 udelay(10);
140         }
141
142         pr_err("Failed to disable WQ[%d]\n", wq->index);
143
144         return -ETIMEDOUT;
145 }
146
147 void vnic_wq_clean(struct vnic_wq *wq,
148                    void (*buf_clean)(struct vnic_wq_buf *buf))
149 {
150         struct vnic_wq_buf *buf;
151         unsigned int  to_clean = wq->tail_idx;
152
153         buf = &wq->bufs[to_clean];
154
155         while (vnic_wq_desc_used(wq) > 0) {
156
157                 (*buf_clean)(buf);
158                 to_clean = buf_idx_incr(wq->ring.desc_count, to_clean);
159
160                 buf = &wq->bufs[to_clean];
161                 wq->ring.desc_avail++;
162         }
163
164         wq->head_idx = 0;
165         wq->tail_idx = 0;
166         wq->last_completed_index = 0;
167         *((uint32_t *)wq->cqmsg_rz->addr) = 0;
168
169         iowrite32(0, &wq->ctrl->fetch_index);
170         iowrite32(0, &wq->ctrl->posted_index);
171         iowrite32(0, &wq->ctrl->error_status);
172
173         vnic_dev_clear_desc_ring(&wq->ring);
174 }