net/sfc/base: import libefx base
[dpdk.git] / drivers / net / sfc / base / efx_rx.c
1 /*
2  * Copyright (c) 2007-2016 Solarflare Communications Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  *    this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  *    this list of conditions and the following disclaimer in the documentation
12  *    and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  * The views and conclusions contained in the software and documentation are
27  * those of the authors and should not be interpreted as representing official
28  * policies, either expressed or implied, of the FreeBSD Project.
29  */
30
31 #include "efx.h"
32 #include "efx_impl.h"
33
34
35         __checkReturn   efx_rc_t
36 efx_rx_init(
37         __inout         efx_nic_t *enp)
38 {
39         const efx_rx_ops_t *erxop;
40         efx_rc_t rc;
41
42         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
43         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
44
45         if (!(enp->en_mod_flags & EFX_MOD_EV)) {
46                 rc = EINVAL;
47                 goto fail1;
48         }
49
50         if (enp->en_mod_flags & EFX_MOD_RX) {
51                 rc = EINVAL;
52                 goto fail2;
53         }
54
55         switch (enp->en_family) {
56
57         default:
58                 EFSYS_ASSERT(0);
59                 rc = ENOTSUP;
60                 goto fail3;
61         }
62
63         if ((rc = erxop->erxo_init(enp)) != 0)
64                 goto fail4;
65
66         enp->en_erxop = erxop;
67         enp->en_mod_flags |= EFX_MOD_RX;
68         return (0);
69
70 fail4:
71         EFSYS_PROBE(fail4);
72 fail3:
73         EFSYS_PROBE(fail3);
74 fail2:
75         EFSYS_PROBE(fail2);
76 fail1:
77         EFSYS_PROBE1(fail1, efx_rc_t, rc);
78
79         enp->en_erxop = NULL;
80         enp->en_mod_flags &= ~EFX_MOD_RX;
81         return (rc);
82 }
83
84                         void
85 efx_rx_fini(
86         __in            efx_nic_t *enp)
87 {
88         const efx_rx_ops_t *erxop = enp->en_erxop;
89
90         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
91         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
92         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
93         EFSYS_ASSERT3U(enp->en_rx_qcount, ==, 0);
94
95         erxop->erxo_fini(enp);
96
97         enp->en_erxop = NULL;
98         enp->en_mod_flags &= ~EFX_MOD_RX;
99 }
100
101                         void
102 efx_rx_qpost(
103         __in            efx_rxq_t *erp,
104         __in_ecount(n)  efsys_dma_addr_t *addrp,
105         __in            size_t size,
106         __in            unsigned int n,
107         __in            unsigned int completed,
108         __in            unsigned int added)
109 {
110         efx_nic_t *enp = erp->er_enp;
111         const efx_rx_ops_t *erxop = enp->en_erxop;
112
113         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
114
115         erxop->erxo_qpost(erp, addrp, size, n, completed, added);
116 }
117
118                         void
119 efx_rx_qpush(
120         __in            efx_rxq_t *erp,
121         __in            unsigned int added,
122         __inout         unsigned int *pushedp)
123 {
124         efx_nic_t *enp = erp->er_enp;
125         const efx_rx_ops_t *erxop = enp->en_erxop;
126
127         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
128
129         erxop->erxo_qpush(erp, added, pushedp);
130 }
131
132         __checkReturn   efx_rc_t
133 efx_rx_qflush(
134         __in            efx_rxq_t *erp)
135 {
136         efx_nic_t *enp = erp->er_enp;
137         const efx_rx_ops_t *erxop = enp->en_erxop;
138         efx_rc_t rc;
139
140         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
141
142         if ((rc = erxop->erxo_qflush(erp)) != 0)
143                 goto fail1;
144
145         return (0);
146
147 fail1:
148         EFSYS_PROBE1(fail1, efx_rc_t, rc);
149
150         return (rc);
151 }
152
153                         void
154 efx_rx_qenable(
155         __in            efx_rxq_t *erp)
156 {
157         efx_nic_t *enp = erp->er_enp;
158         const efx_rx_ops_t *erxop = enp->en_erxop;
159
160         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
161
162         erxop->erxo_qenable(erp);
163 }
164
165         __checkReturn   efx_rc_t
166 efx_rx_qcreate(
167         __in            efx_nic_t *enp,
168         __in            unsigned int index,
169         __in            unsigned int label,
170         __in            efx_rxq_type_t type,
171         __in            efsys_mem_t *esmp,
172         __in            size_t n,
173         __in            uint32_t id,
174         __in            efx_evq_t *eep,
175         __deref_out     efx_rxq_t **erpp)
176 {
177         const efx_rx_ops_t *erxop = enp->en_erxop;
178         efx_rxq_t *erp;
179         efx_rc_t rc;
180
181         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
182         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
183
184         /* Allocate an RXQ object */
185         EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_rxq_t), erp);
186
187         if (erp == NULL) {
188                 rc = ENOMEM;
189                 goto fail1;
190         }
191
192         erp->er_magic = EFX_RXQ_MAGIC;
193         erp->er_enp = enp;
194         erp->er_index = index;
195         erp->er_mask = n - 1;
196         erp->er_esmp = esmp;
197
198         if ((rc = erxop->erxo_qcreate(enp, index, label, type, esmp, n, id,
199             eep, erp)) != 0)
200                 goto fail2;
201
202         enp->en_rx_qcount++;
203         *erpp = erp;
204
205         return (0);
206
207 fail2:
208         EFSYS_PROBE(fail2);
209
210         EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_rxq_t), erp);
211 fail1:
212         EFSYS_PROBE1(fail1, efx_rc_t, rc);
213
214         return (rc);
215 }
216
217                         void
218 efx_rx_qdestroy(
219         __in            efx_rxq_t *erp)
220 {
221         efx_nic_t *enp = erp->er_enp;
222         const efx_rx_ops_t *erxop = enp->en_erxop;
223
224         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
225
226         erxop->erxo_qdestroy(erp);
227 }
228
229         __checkReturn   efx_rc_t
230 efx_pseudo_hdr_pkt_length_get(
231         __in            efx_rxq_t *erp,
232         __in            uint8_t *buffer,
233         __out           uint16_t *lengthp)
234 {
235         efx_nic_t *enp = erp->er_enp;
236         const efx_rx_ops_t *erxop = enp->en_erxop;
237
238         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
239
240         return (erxop->erxo_prefix_pktlen(enp, buffer, lengthp));
241 }
242