net/ark: stub PMD for Atomic Rules Arkville
[dpdk.git] / drivers / net / ark / ark_ethdev.c
1 /*-
2  * BSD LICENSE
3  *
4  * Copyright (c) 2015-2017 Atomic Rules LLC
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 copyright holder 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 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 <unistd.h>
35 #include <sys/stat.h>
36 #include <dlfcn.h>
37
38 #include <rte_ethdev_pci.h>
39 #include <rte_kvargs.h>
40
41 #include "ark_global.h"
42 #include "ark_logs.h"
43 #include "ark_ethdev.h"
44
45 /*  Internal prototypes */
46 static int eth_ark_check_args(struct ark_adapter *ark, const char *params);
47 static int eth_ark_dev_init(struct rte_eth_dev *dev);
48 static int eth_ark_dev_uninit(struct rte_eth_dev *eth_dev);
49 static int eth_ark_dev_configure(struct rte_eth_dev *dev);
50 static void eth_ark_dev_info_get(struct rte_eth_dev *dev,
51                                  struct rte_eth_dev_info *dev_info);
52
53 /*
54  * The packet generator is a functional block used to generate packet
55  * patterns for testing.  It is not intended for nominal use.
56  */
57 #define ARK_PKTGEN_ARG "Pkt_gen"
58
59 /*
60  * The packet checker is a functional block used to verify packet
61  * patterns for testing.  It is not intended for nominal use.
62  */
63 #define ARK_PKTCHKR_ARG "Pkt_chkr"
64
65 /*
66  * The packet director is used to select the internal ingress and
67  * egress packets paths during testing.  It is not intended for
68  * nominal use.
69  */
70 #define ARK_PKTDIR_ARG "Pkt_dir"
71
72 /* Devinfo configurations */
73 #define ARK_RX_MAX_QUEUE (4096 * 4)
74 #define ARK_RX_MIN_QUEUE (512)
75 #define ARK_RX_MAX_PKT_LEN ((16 * 1024) - 128)
76 #define ARK_RX_MIN_BUFSIZE (1024)
77
78 #define ARK_TX_MAX_QUEUE (4096 * 4)
79 #define ARK_TX_MIN_QUEUE (256)
80
81 static const char * const valid_arguments[] = {
82         ARK_PKTGEN_ARG,
83         ARK_PKTCHKR_ARG,
84         ARK_PKTDIR_ARG,
85         NULL
86 };
87
88 static const struct rte_pci_id pci_id_ark_map[] = {
89         {RTE_PCI_DEVICE(0x1d6c, 0x100d)},
90         {RTE_PCI_DEVICE(0x1d6c, 0x100e)},
91         {.vendor_id = 0, /* sentinel */ },
92 };
93
94 static int
95 eth_ark_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
96                 struct rte_pci_device *pci_dev)
97 {
98         struct rte_eth_dev *eth_dev;
99         int ret;
100
101         eth_dev = rte_eth_dev_pci_allocate(pci_dev, sizeof(struct ark_adapter));
102
103         if (eth_dev == NULL)
104                 return -ENOMEM;
105
106         ret = eth_ark_dev_init(eth_dev);
107         if (ret)
108                 rte_eth_dev_pci_release(eth_dev);
109
110         return ret;
111 }
112
113 static int
114 eth_ark_pci_remove(struct rte_pci_device *pci_dev)
115 {
116         return rte_eth_dev_pci_generic_remove(pci_dev, eth_ark_dev_uninit);
117 }
118
119 static struct rte_pci_driver rte_ark_pmd = {
120         .id_table = pci_id_ark_map,
121         .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
122         .probe = eth_ark_pci_probe,
123         .remove = eth_ark_pci_remove,
124 };
125
126 static const struct eth_dev_ops ark_eth_dev_ops = {
127         .dev_configure = eth_ark_dev_configure,
128         .dev_infos_get = eth_ark_dev_info_get,
129 };
130
131 static int
132 eth_ark_dev_init(struct rte_eth_dev *dev)
133 {
134         struct ark_adapter *ark =
135                 (struct ark_adapter *)dev->data->dev_private;
136         struct rte_pci_device *pci_dev;
137         int ret = -1;
138
139         ark->eth_dev = dev;
140
141         PMD_FUNC_LOG(DEBUG, "\n");
142
143         pci_dev = ARK_DEV_TO_PCI(dev);
144         rte_eth_copy_pci_info(dev, pci_dev);
145
146         ark->bar0 = (uint8_t *)pci_dev->mem_resource[0].addr;
147         ark->a_bar = (uint8_t *)pci_dev->mem_resource[2].addr;
148
149         dev->dev_ops = &ark_eth_dev_ops;
150         dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
151
152         if (pci_dev->device.devargs)
153                 ret = eth_ark_check_args(ark, pci_dev->device.devargs->args);
154         else
155                 PMD_DRV_LOG(INFO, "No Device args found\n");
156
157         return ret;
158 }
159
160 static int
161 eth_ark_dev_uninit(struct rte_eth_dev *dev)
162 {
163         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
164                 return 0;
165
166         dev->dev_ops = NULL;
167         dev->rx_pkt_burst = NULL;
168         dev->tx_pkt_burst = NULL;
169         return 0;
170 }
171
172 static int
173 eth_ark_dev_configure(struct rte_eth_dev *dev __rte_unused)
174 {
175         PMD_FUNC_LOG(DEBUG, "\n");
176         return 0;
177 }
178
179 static void
180 eth_ark_dev_info_get(struct rte_eth_dev *dev,
181                      struct rte_eth_dev_info *dev_info)
182 {
183         dev_info->max_rx_pktlen = ARK_RX_MAX_PKT_LEN;
184         dev_info->min_rx_bufsize = ARK_RX_MIN_BUFSIZE;
185
186         dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
187                 .nb_max = ARK_RX_MAX_QUEUE,
188                 .nb_min = ARK_RX_MIN_QUEUE,
189                 .nb_align = ARK_RX_MIN_QUEUE}; /* power of 2 */
190
191         dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
192                 .nb_max = ARK_TX_MAX_QUEUE,
193                 .nb_min = ARK_TX_MIN_QUEUE,
194                 .nb_align = ARK_TX_MIN_QUEUE}; /* power of 2 */
195
196         /* ARK PMD supports all line rates, how do we indicate that here ?? */
197         dev_info->speed_capa = (ETH_LINK_SPEED_1G |
198                                 ETH_LINK_SPEED_10G |
199                                 ETH_LINK_SPEED_25G |
200                                 ETH_LINK_SPEED_40G |
201                                 ETH_LINK_SPEED_50G |
202                                 ETH_LINK_SPEED_100G);
203         dev_info->pci_dev = ARK_DEV_TO_PCI(dev);
204 }
205
206 static inline int
207 process_pktdir_arg(const char *key, const char *value,
208                    void *extra_args)
209 {
210         PMD_FUNC_LOG(DEBUG, "key = %s, value = %s\n",
211                     key, value);
212         struct ark_adapter *ark =
213                 (struct ark_adapter *)extra_args;
214
215         ark->pkt_dir_v = strtol(value, NULL, 16);
216         PMD_FUNC_LOG(DEBUG, "pkt_dir_v = 0x%x\n", ark->pkt_dir_v);
217         return 0;
218 }
219
220 static inline int
221 process_file_args(const char *key, const char *value, void *extra_args)
222 {
223         PMD_FUNC_LOG(DEBUG, "key = %s, value = %s\n",
224                     key, value);
225         char *args = (char *)extra_args;
226
227         /* Open the configuration file */
228         FILE *file = fopen(value, "r");
229         char line[ARK_MAX_ARG_LEN];
230         int  size = 0;
231         int first = 1;
232
233         while (fgets(line, sizeof(line), file)) {
234                 size += strlen(line);
235                 if (size >= ARK_MAX_ARG_LEN) {
236                         PMD_DRV_LOG(ERR, "Unable to parse file %s args, "
237                                     "parameter list is too long\n", value);
238                         fclose(file);
239                         return -1;
240                 }
241                 if (first) {
242                         strncpy(args, line, ARK_MAX_ARG_LEN);
243                         first = 0;
244                 } else {
245                         strncat(args, line, ARK_MAX_ARG_LEN);
246                 }
247         }
248         PMD_FUNC_LOG(DEBUG, "file = %s\n", args);
249         fclose(file);
250         return 0;
251 }
252
253 static int
254 eth_ark_check_args(struct ark_adapter *ark, const char *params)
255 {
256         struct rte_kvargs *kvlist;
257         unsigned int k_idx;
258         struct rte_kvargs_pair *pair = NULL;
259
260         kvlist = rte_kvargs_parse(params, valid_arguments);
261         if (kvlist == NULL)
262                 return 0;
263
264         ark->pkt_gen_args[0] = 0;
265         ark->pkt_chkr_args[0] = 0;
266
267         for (k_idx = 0; k_idx < kvlist->count; k_idx++) {
268                 pair = &kvlist->pairs[k_idx];
269                 PMD_FUNC_LOG(DEBUG, "**** Arg passed to PMD = %s:%s\n",
270                              pair->key,
271                              pair->value);
272         }
273
274         if (rte_kvargs_process(kvlist,
275                                ARK_PKTDIR_ARG,
276                                &process_pktdir_arg,
277                                ark) != 0) {
278                 PMD_DRV_LOG(ERR, "Unable to parse arg %s\n", ARK_PKTDIR_ARG);
279                 return -1;
280         }
281
282         if (rte_kvargs_process(kvlist,
283                                ARK_PKTGEN_ARG,
284                                &process_file_args,
285                                ark->pkt_gen_args) != 0) {
286                 PMD_DRV_LOG(ERR, "Unable to parse arg %s\n", ARK_PKTGEN_ARG);
287                 return -1;
288         }
289
290         if (rte_kvargs_process(kvlist,
291                                ARK_PKTCHKR_ARG,
292                                &process_file_args,
293                                ark->pkt_chkr_args) != 0) {
294                 PMD_DRV_LOG(ERR, "Unable to parse arg %s\n", ARK_PKTCHKR_ARG);
295                 return -1;
296         }
297
298         PMD_DRV_LOG(INFO, "packet director set to 0x%x\n", ark->pkt_dir_v);
299
300         return 0;
301 }
302
303 RTE_PMD_REGISTER_PCI(net_ark, rte_ark_pmd);
304 RTE_PMD_REGISTER_KMOD_DEP(net_ark, "* igb_uio | uio_pci_generic ");
305 RTE_PMD_REGISTER_PCI_TABLE(net_ark, pci_id_ark_map);
306 RTE_PMD_REGISTER_PARAM_STRING(net_ark,
307                               ARK_PKTGEN_ARG "=<filename> "
308                               ARK_PKTCHKR_ARG "=<filename> "
309                               ARK_PKTDIR_ARG "=<bitmap>");