net/liquidio: add APIs to allocate and free SC buffer pool
[dpdk.git] / drivers / net / liquidio / lio_rxtx.c
1 /*
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2017 Cavium, Inc.. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Cavium, Inc. nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <rte_ethdev.h>
35 #include <rte_cycles.h>
36 #include <rte_malloc.h>
37
38 #include "lio_logs.h"
39 #include "lio_struct.h"
40 #include "lio_ethdev.h"
41 #include "lio_rxtx.h"
42
43 static void
44 lio_dma_zone_free(struct lio_device *lio_dev, const struct rte_memzone *mz)
45 {
46         const struct rte_memzone *mz_tmp;
47         int ret = 0;
48
49         if (mz == NULL) {
50                 lio_dev_err(lio_dev, "Memzone NULL\n");
51                 return;
52         }
53
54         mz_tmp = rte_memzone_lookup(mz->name);
55         if (mz_tmp == NULL) {
56                 lio_dev_err(lio_dev, "Memzone %s Not Found\n", mz->name);
57                 return;
58         }
59
60         ret = rte_memzone_free(mz);
61         if (ret)
62                 lio_dev_err(lio_dev, "Memzone free Failed ret %d\n", ret);
63 }
64
65 /**
66  *  lio_init_instr_queue()
67  *  @param lio_dev      - pointer to the lio device structure.
68  *  @param txpciq       - queue to be initialized.
69  *
70  *  Called at driver init time for each input queue. iq_conf has the
71  *  configuration parameters for the queue.
72  *
73  *  @return  Success: 0 Failure: -1
74  */
75 static int
76 lio_init_instr_queue(struct lio_device *lio_dev,
77                      union octeon_txpciq txpciq,
78                      uint32_t num_descs, unsigned int socket_id)
79 {
80         uint32_t iq_no = (uint32_t)txpciq.s.q_no;
81         struct lio_instr_queue *iq;
82         uint32_t instr_type;
83         uint32_t q_size;
84
85         instr_type = LIO_IQ_INSTR_TYPE(lio_dev);
86
87         q_size = instr_type * num_descs;
88         iq = lio_dev->instr_queue[iq_no];
89         iq->iq_mz = rte_eth_dma_zone_reserve(lio_dev->eth_dev,
90                                              "instr_queue", iq_no, q_size,
91                                              RTE_CACHE_LINE_SIZE,
92                                              socket_id);
93         if (iq->iq_mz == NULL) {
94                 lio_dev_err(lio_dev, "Cannot allocate memory for instr queue %d\n",
95                             iq_no);
96                 return -1;
97         }
98
99         iq->base_addr_dma = iq->iq_mz->phys_addr;
100         iq->base_addr = (uint8_t *)iq->iq_mz->addr;
101
102         iq->max_count = num_descs;
103
104         /* Initialize a list to holds requests that have been posted to Octeon
105          * but has yet to be fetched by octeon
106          */
107         iq->request_list = rte_zmalloc_socket("request_list",
108                                               sizeof(*iq->request_list) *
109                                                         num_descs,
110                                               RTE_CACHE_LINE_SIZE,
111                                               socket_id);
112         if (iq->request_list == NULL) {
113                 lio_dev_err(lio_dev, "Alloc failed for IQ[%d] nr free list\n",
114                             iq_no);
115                 lio_dma_zone_free(lio_dev, iq->iq_mz);
116                 return -1;
117         }
118
119         lio_dev_dbg(lio_dev, "IQ[%d]: base: %p basedma: %lx count: %d\n",
120                     iq_no, iq->base_addr, (unsigned long)iq->base_addr_dma,
121                     iq->max_count);
122
123         iq->lio_dev = lio_dev;
124         iq->txpciq.txpciq64 = txpciq.txpciq64;
125         iq->fill_cnt = 0;
126         iq->host_write_index = 0;
127         iq->lio_read_index = 0;
128         iq->flush_index = 0;
129
130         rte_atomic64_set(&iq->instr_pending, 0);
131
132         /* Initialize the spinlock for this instruction queue */
133         rte_spinlock_init(&iq->lock);
134         rte_spinlock_init(&iq->post_lock);
135
136         rte_atomic64_clear(&iq->iq_flush_running);
137
138         lio_dev->io_qmask.iq |= (1ULL << iq_no);
139
140         /* Set the 32B/64B mode for each input queue */
141         lio_dev->io_qmask.iq64B |= ((instr_type == 64) << iq_no);
142         iq->iqcmd_64B = (instr_type == 64);
143
144         lio_dev->fn_list.setup_iq_regs(lio_dev, iq_no);
145
146         return 0;
147 }
148
149 int
150 lio_setup_instr_queue0(struct lio_device *lio_dev)
151 {
152         union octeon_txpciq txpciq;
153         uint32_t num_descs = 0;
154         uint32_t iq_no = 0;
155
156         num_descs = LIO_NUM_DEF_TX_DESCS_CFG(lio_dev);
157
158         lio_dev->num_iqs = 0;
159
160         lio_dev->instr_queue[0] = rte_zmalloc(NULL,
161                                         sizeof(struct lio_instr_queue), 0);
162         if (lio_dev->instr_queue[0] == NULL)
163                 return -ENOMEM;
164
165         lio_dev->instr_queue[0]->q_index = 0;
166         lio_dev->instr_queue[0]->app_ctx = (void *)(size_t)0;
167         txpciq.txpciq64 = 0;
168         txpciq.s.q_no = iq_no;
169         txpciq.s.pkind = lio_dev->pfvf_hsword.pkind;
170         txpciq.s.use_qpg = 0;
171         txpciq.s.qpg = 0;
172         if (lio_init_instr_queue(lio_dev, txpciq, num_descs, SOCKET_ID_ANY)) {
173                 rte_free(lio_dev->instr_queue[0]);
174                 lio_dev->instr_queue[0] = NULL;
175                 return -1;
176         }
177
178         lio_dev->num_iqs++;
179
180         return 0;
181 }
182
183 /**
184  *  lio_delete_instr_queue()
185  *  @param lio_dev      - pointer to the lio device structure.
186  *  @param iq_no        - queue to be deleted.
187  *
188  *  Called at driver unload time for each input queue. Deletes all
189  *  allocated resources for the input queue.
190  */
191 static void
192 lio_delete_instr_queue(struct lio_device *lio_dev, uint32_t iq_no)
193 {
194         struct lio_instr_queue *iq = lio_dev->instr_queue[iq_no];
195
196         rte_free(iq->request_list);
197         iq->request_list = NULL;
198         lio_dma_zone_free(lio_dev, iq->iq_mz);
199 }
200
201 void
202 lio_free_instr_queue0(struct lio_device *lio_dev)
203 {
204         lio_delete_instr_queue(lio_dev, 0);
205         rte_free(lio_dev->instr_queue[0]);
206         lio_dev->instr_queue[0] = NULL;
207         lio_dev->num_iqs--;
208 }
209
210 int
211 lio_setup_sc_buffer_pool(struct lio_device *lio_dev)
212 {
213         char sc_pool_name[RTE_MEMPOOL_NAMESIZE];
214         uint16_t buf_size;
215
216         buf_size = LIO_SOFT_COMMAND_BUFFER_SIZE + RTE_PKTMBUF_HEADROOM;
217         snprintf(sc_pool_name, sizeof(sc_pool_name),
218                  "lio_sc_pool_%u", lio_dev->port_id);
219         lio_dev->sc_buf_pool = rte_pktmbuf_pool_create(sc_pool_name,
220                                                 LIO_MAX_SOFT_COMMAND_BUFFERS,
221                                                 0, 0, buf_size, SOCKET_ID_ANY);
222         return 0;
223 }
224
225 void
226 lio_free_sc_buffer_pool(struct lio_device *lio_dev)
227 {
228         rte_mempool_free(lio_dev->sc_buf_pool);
229 }