net/octeontx: add device configure
[dpdk.git] / drivers / net / octeontx / octeontx_ethdev.c
1 /*
2  *   BSD LICENSE
3  *
4  *   Copyright (C) Cavium Inc. 2017. All rights reserved.
5  *
6  *   Redistribution and use in source and binary forms, with or without
7  *   modification, are permitted provided that the following conditions
8  *   are met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above copyright
13  *       notice, this list of conditions and the following disclaimer in
14  *       the documentation and/or other materials provided with the
15  *       distribution.
16  *     * Neither the name of Cavium networks nor the names of its
17  *       contributors may be used to endorse or promote products derived
18  *       from this software without specific prior written permission.
19  *
20  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 #include <stdio.h>
33 #include <stdarg.h>
34 #include <stdbool.h>
35 #include <stdint.h>
36 #include <string.h>
37 #include <unistd.h>
38
39 #include <rte_alarm.h>
40 #include <rte_branch_prediction.h>
41 #include <rte_debug.h>
42 #include <rte_devargs.h>
43 #include <rte_dev.h>
44 #include <rte_kvargs.h>
45 #include <rte_malloc.h>
46 #include <rte_prefetch.h>
47 #include <rte_vdev.h>
48
49 #include "octeontx_ethdev.h"
50 #include "octeontx_logs.h"
51
52 struct octeontx_vdev_init_params {
53         uint8_t nr_port;
54 };
55
56 /* Parse integer from integer argument */
57 static int
58 parse_integer_arg(const char *key __rte_unused,
59                 const char *value, void *extra_args)
60 {
61         int *i = (int *)extra_args;
62
63         *i = atoi(value);
64         if (*i < 0) {
65                 octeontx_log_err("argument has to be positive.");
66                 return -1;
67         }
68
69         return 0;
70 }
71
72 static int
73 octeontx_parse_vdev_init_params(struct octeontx_vdev_init_params *params,
74                                 struct rte_vdev_device *dev)
75 {
76         struct rte_kvargs *kvlist = NULL;
77         int ret = 0;
78
79         static const char * const octeontx_vdev_valid_params[] = {
80                 OCTEONTX_VDEV_NR_PORT_ARG,
81                 NULL
82         };
83
84         const char *input_args = rte_vdev_device_args(dev);
85         if (params == NULL)
86                 return -EINVAL;
87
88
89         if (input_args) {
90                 kvlist = rte_kvargs_parse(input_args,
91                                 octeontx_vdev_valid_params);
92                 if (kvlist == NULL)
93                         return -1;
94
95                 ret = rte_kvargs_process(kvlist,
96                                         OCTEONTX_VDEV_NR_PORT_ARG,
97                                         &parse_integer_arg,
98                                         &params->nr_port);
99                 if (ret < 0)
100                         goto free_kvlist;
101         }
102
103 free_kvlist:
104         rte_kvargs_free(kvlist);
105         return ret;
106 }
107
108 static int
109 octeontx_port_open(struct octeontx_nic *nic)
110 {
111         octeontx_mbox_bgx_port_conf_t bgx_port_conf;
112         int res;
113
114         res = 0;
115
116         PMD_INIT_FUNC_TRACE();
117
118         res = octeontx_bgx_port_open(nic->port_id, &bgx_port_conf);
119         if (res < 0) {
120                 octeontx_log_err("failed to open port %d", res);
121                 return res;
122         }
123
124         nic->node = bgx_port_conf.node;
125         nic->port_ena = bgx_port_conf.enable;
126         nic->base_ichan = bgx_port_conf.base_chan;
127         nic->base_ochan = bgx_port_conf.base_chan;
128         nic->num_ichans = bgx_port_conf.num_chans;
129         nic->num_ochans = bgx_port_conf.num_chans;
130         nic->mtu = bgx_port_conf.mtu;
131         nic->bpen = bgx_port_conf.bpen;
132         nic->fcs_strip = bgx_port_conf.fcs_strip;
133         nic->bcast_mode = bgx_port_conf.bcast_mode;
134         nic->mcast_mode = bgx_port_conf.mcast_mode;
135         nic->speed      = bgx_port_conf.mode;
136
137         memcpy(&nic->mac_addr[0], &bgx_port_conf.macaddr[0], ETHER_ADDR_LEN);
138
139         octeontx_log_dbg("port opened %d", nic->port_id);
140         return res;
141 }
142
143 static void
144 octeontx_port_close(struct octeontx_nic *nic)
145 {
146         PMD_INIT_FUNC_TRACE();
147
148         octeontx_bgx_port_close(nic->port_id);
149         octeontx_log_dbg("port closed %d", nic->port_id);
150 }
151
152 static inline void
153 devconf_set_default_sane_values(struct rte_event_dev_config *dev_conf,
154                                 struct rte_event_dev_info *info)
155 {
156         memset(dev_conf, 0, sizeof(struct rte_event_dev_config));
157         dev_conf->dequeue_timeout_ns = info->min_dequeue_timeout_ns;
158
159         dev_conf->nb_event_ports = info->max_event_ports;
160         dev_conf->nb_event_queues = info->max_event_queues;
161
162         dev_conf->nb_event_queue_flows = info->max_event_queue_flows;
163         dev_conf->nb_event_port_dequeue_depth =
164                         info->max_event_port_dequeue_depth;
165         dev_conf->nb_event_port_enqueue_depth =
166                         info->max_event_port_enqueue_depth;
167         dev_conf->nb_event_port_enqueue_depth =
168                         info->max_event_port_enqueue_depth;
169         dev_conf->nb_events_limit =
170                         info->max_num_events;
171 }
172
173 static int
174 octeontx_dev_configure(struct rte_eth_dev *dev)
175 {
176         struct rte_eth_dev_data *data = dev->data;
177         struct rte_eth_conf *conf = &data->dev_conf;
178         struct rte_eth_rxmode *rxmode = &conf->rxmode;
179         struct rte_eth_txmode *txmode = &conf->txmode;
180         struct octeontx_nic *nic = octeontx_pmd_priv(dev);
181         int ret;
182
183         PMD_INIT_FUNC_TRACE();
184         RTE_SET_USED(conf);
185
186         if (!rte_eal_has_hugepages()) {
187                 octeontx_log_err("huge page is not configured");
188                 return -EINVAL;
189         }
190
191         if (txmode->mq_mode) {
192                 octeontx_log_err("tx mq_mode DCB or VMDq not supported");
193                 return -EINVAL;
194         }
195
196         if (rxmode->mq_mode != ETH_MQ_RX_NONE &&
197                 rxmode->mq_mode != ETH_MQ_RX_RSS) {
198                 octeontx_log_err("unsupported rx qmode %d", rxmode->mq_mode);
199                 return -EINVAL;
200         }
201
202         if (!rxmode->hw_strip_crc) {
203                 PMD_INIT_LOG(NOTICE, "can't disable hw crc strip");
204                 rxmode->hw_strip_crc = 1;
205         }
206
207         if (rxmode->hw_ip_checksum) {
208                 PMD_INIT_LOG(NOTICE, "rxcksum not supported");
209                 rxmode->hw_ip_checksum = 0;
210         }
211
212         if (rxmode->split_hdr_size) {
213                 octeontx_log_err("rxmode does not support split header");
214                 return -EINVAL;
215         }
216
217         if (rxmode->hw_vlan_filter) {
218                 octeontx_log_err("VLAN filter not supported");
219                 return -EINVAL;
220         }
221
222         if (rxmode->hw_vlan_extend) {
223                 octeontx_log_err("VLAN extended not supported");
224                 return -EINVAL;
225         }
226
227         if (rxmode->enable_lro) {
228                 octeontx_log_err("LRO not supported");
229                 return -EINVAL;
230         }
231
232         if (conf->link_speeds & ETH_LINK_SPEED_FIXED) {
233                 octeontx_log_err("setting link speed/duplex not supported");
234                 return -EINVAL;
235         }
236
237         if (conf->dcb_capability_en) {
238                 octeontx_log_err("DCB enable not supported");
239                 return -EINVAL;
240         }
241
242         if (conf->fdir_conf.mode != RTE_FDIR_MODE_NONE) {
243                 octeontx_log_err("flow director not supported");
244                 return -EINVAL;
245         }
246
247         nic->num_tx_queues = dev->data->nb_tx_queues;
248
249         ret = octeontx_pko_channel_open(nic->port_id * PKO_VF_NUM_DQ,
250                                         nic->num_tx_queues,
251                                         nic->base_ochan);
252         if (ret) {
253                 octeontx_log_err("failed to open channel %d no-of-txq %d",
254                            nic->base_ochan, nic->num_tx_queues);
255                 return -EFAULT;
256         }
257
258         nic->pki.classifier_enable = false;
259         nic->pki.hash_enable = true;
260         nic->pki.initialized = false;
261
262         return 0;
263 }
264
265 /* Initialize and register driver with DPDK Application */
266 static const struct eth_dev_ops octeontx_dev_ops = {
267         .dev_configure           = octeontx_dev_configure,
268 };
269
270 /* Create Ethdev interface per BGX LMAC ports */
271 static int
272 octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev,
273                         int socket_id)
274 {
275         int res;
276         char octtx_name[OCTEONTX_MAX_NAME_LEN];
277         struct octeontx_nic *nic = NULL;
278         struct rte_eth_dev *eth_dev = NULL;
279         struct rte_eth_dev_data *data = NULL;
280         const char *name = rte_vdev_device_name(dev);
281
282         PMD_INIT_FUNC_TRACE();
283
284         sprintf(octtx_name, "%s_%d", name, port);
285         if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
286                 eth_dev = rte_eth_dev_attach_secondary(octtx_name);
287                 if (eth_dev == NULL)
288                         return -ENODEV;
289
290                 return 0;
291         }
292
293         data = rte_zmalloc_socket(octtx_name, sizeof(*data), 0, socket_id);
294         if (data == NULL) {
295                 octeontx_log_err("failed to allocate devdata");
296                 res = -ENOMEM;
297                 goto err;
298         }
299
300         nic = rte_zmalloc_socket(octtx_name, sizeof(*nic), 0, socket_id);
301         if (nic == NULL) {
302                 octeontx_log_err("failed to allocate nic structure");
303                 res = -ENOMEM;
304                 goto err;
305         }
306
307         nic->port_id = port;
308         nic->evdev = evdev;
309
310         res = octeontx_port_open(nic);
311         if (res < 0)
312                 goto err;
313
314         /* Rx side port configuration */
315         res = octeontx_pki_port_open(port);
316         if (res != 0) {
317                 octeontx_log_err("failed to open PKI port %d", port);
318                 res = -ENODEV;
319                 goto err;
320         }
321
322         /* Reserve an ethdev entry */
323         eth_dev = rte_eth_dev_allocate(octtx_name);
324         if (eth_dev == NULL) {
325                 octeontx_log_err("failed to allocate rte_eth_dev");
326                 res = -ENOMEM;
327                 goto err;
328         }
329
330         eth_dev->device = &dev->device;
331         eth_dev->intr_handle = NULL;
332         eth_dev->data->kdrv = RTE_KDRV_NONE;
333         eth_dev->data->numa_node = dev->device.numa_node;
334
335         rte_memcpy(data, (eth_dev)->data, sizeof(*data));
336         data->dev_private = nic;
337
338         data->port_id = eth_dev->data->port_id;
339         snprintf(data->name, sizeof(data->name), "%s", eth_dev->data->name);
340
341         nic->ev_queues = 1;
342         nic->ev_ports = 1;
343
344         data->dev_link.link_status = ETH_LINK_DOWN;
345         data->dev_started = 0;
346         data->promiscuous = 0;
347         data->all_multicast = 0;
348         data->scattered_rx = 0;
349
350         data->mac_addrs = rte_zmalloc_socket(octtx_name, ETHER_ADDR_LEN, 0,
351                                                         socket_id);
352         if (data->mac_addrs == NULL) {
353                 octeontx_log_err("failed to allocate memory for mac_addrs");
354                 res = -ENOMEM;
355                 goto err;
356         }
357
358         eth_dev->data = data;
359         eth_dev->dev_ops = &octeontx_dev_ops;
360
361         /* Finally save ethdev pointer to the NIC structure */
362         nic->dev = eth_dev;
363
364         if (nic->port_id != data->port_id) {
365                 octeontx_log_err("eth_dev->port_id (%d) is diff to orig (%d)",
366                                 data->port_id, nic->port_id);
367                 res = -EINVAL;
368                 goto err;
369         }
370
371         /* Update port_id mac to eth_dev */
372         memcpy(data->mac_addrs, nic->mac_addr, ETHER_ADDR_LEN);
373
374         PMD_INIT_LOG(DEBUG, "ethdev info: ");
375         PMD_INIT_LOG(DEBUG, "port %d, port_ena %d ochan %d num_ochan %d tx_q %d",
376                                 nic->port_id, nic->port_ena,
377                                 nic->base_ochan, nic->num_ochans,
378                                 nic->num_tx_queues);
379         PMD_INIT_LOG(DEBUG, "speed %d mtu %d", nic->speed, nic->mtu);
380
381         return data->port_id;
382
383 err:
384         if (port)
385                 octeontx_port_close(nic);
386
387         if (eth_dev != NULL) {
388                 rte_free(eth_dev->data->mac_addrs);
389                 rte_free(data);
390                 rte_free(nic);
391                 rte_eth_dev_release_port(eth_dev);
392         }
393
394         return res;
395 }
396
397 /* Un initialize octeontx device */
398 static int
399 octeontx_remove(struct rte_vdev_device *dev)
400 {
401         char octtx_name[OCTEONTX_MAX_NAME_LEN];
402         struct rte_eth_dev *eth_dev = NULL;
403         struct octeontx_nic *nic = NULL;
404         int i;
405
406         if (dev == NULL)
407                 return -EINVAL;
408
409         for (i = 0; i < OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT; i++) {
410                 sprintf(octtx_name, "eth_octeontx_%d", i);
411
412                 /* reserve an ethdev entry */
413                 eth_dev = rte_eth_dev_allocated(octtx_name);
414                 if (eth_dev == NULL)
415                         return -ENODEV;
416
417                 nic = octeontx_pmd_priv(eth_dev);
418                 rte_event_dev_stop(nic->evdev);
419                 PMD_INIT_LOG(INFO, "Closing octeontx device %s", octtx_name);
420
421                 rte_free(eth_dev->data->mac_addrs);
422                 rte_free(eth_dev->data->dev_private);
423                 rte_free(eth_dev->data);
424                 rte_eth_dev_release_port(eth_dev);
425                 rte_event_dev_close(nic->evdev);
426         }
427
428         /* Free FC resource */
429         octeontx_pko_fc_free();
430
431         return 0;
432 }
433
434 /* Initialize octeontx device */
435 static int
436 octeontx_probe(struct rte_vdev_device *dev)
437 {
438         const char *dev_name;
439         static int probe_once;
440         uint8_t socket_id, qlist;
441         int tx_vfcnt, port_id, evdev, qnum, pnum, res, i;
442         struct rte_event_dev_config dev_conf;
443         const char *eventdev_name = "event_octeontx";
444         struct rte_event_dev_info info;
445
446         struct octeontx_vdev_init_params init_params = {
447                 OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT
448         };
449
450         dev_name = rte_vdev_device_name(dev);
451         res = octeontx_parse_vdev_init_params(&init_params, dev);
452         if (res < 0)
453                 return -EINVAL;
454
455         if (init_params.nr_port > OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT) {
456                 octeontx_log_err("nr_port (%d) > max (%d)", init_params.nr_port,
457                                 OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT);
458                 return -ENOTSUP;
459         }
460
461         PMD_INIT_LOG(DEBUG, "initializing %s pmd", dev_name);
462
463         socket_id = rte_socket_id();
464
465         tx_vfcnt = octeontx_pko_vf_count();
466
467         if (tx_vfcnt < init_params.nr_port) {
468                 octeontx_log_err("not enough PKO (%d) for port number (%d)",
469                                 tx_vfcnt, init_params.nr_port);
470                 return -EINVAL;
471         }
472         evdev = rte_event_dev_get_dev_id(eventdev_name);
473         if (evdev < 0) {
474                 octeontx_log_err("eventdev %s not found", eventdev_name);
475                 return -ENODEV;
476         }
477
478         res = rte_event_dev_info_get(evdev, &info);
479         if (res < 0) {
480                 octeontx_log_err("failed to eventdev info %d", res);
481                 return -EINVAL;
482         }
483
484         PMD_INIT_LOG(DEBUG, "max_queue %d max_port %d",
485                         info.max_event_queues, info.max_event_ports);
486
487         if (octeontx_pko_init_fc(tx_vfcnt))
488                 return -ENOMEM;
489
490         devconf_set_default_sane_values(&dev_conf, &info);
491         res = rte_event_dev_configure(evdev, &dev_conf);
492         if (res < 0)
493                 goto parse_error;
494
495         rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_PORT_COUNT,
496                         (uint32_t *)&pnum);
497         rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_QUEUE_COUNT,
498                         (uint32_t *)&qnum);
499         if (pnum < qnum) {
500                 octeontx_log_err("too few event ports (%d) for event_q(%d)",
501                                 pnum, qnum);
502                 res = -EINVAL;
503                 goto parse_error;
504         }
505         if (pnum > qnum) {
506                 /*
507                  * We don't poll on event ports
508                  * that do not have any queues assigned.
509                  */
510                 pnum = qnum;
511                 PMD_INIT_LOG(INFO,
512                         "reducing number of active event ports to %d", pnum);
513         }
514         for (i = 0; i < qnum; i++) {
515                 res = rte_event_queue_setup(evdev, i, NULL);
516                 if (res < 0) {
517                         octeontx_log_err("failed to setup event_q(%d): res %d",
518                                         i, res);
519                         goto parse_error;
520                 }
521         }
522
523         for (i = 0; i < pnum; i++) {
524                 res = rte_event_port_setup(evdev, i, NULL);
525                 if (res < 0) {
526                         res = -ENODEV;
527                         octeontx_log_err("failed to setup ev port(%d) res=%d",
528                                                 i, res);
529                         goto parse_error;
530                 }
531                 /* Link one queue to one event port */
532                 qlist = i;
533                 res = rte_event_port_link(evdev, i, &qlist, NULL, 1);
534                 if (res < 0) {
535                         res = -ENODEV;
536                         octeontx_log_err("failed to link port (%d): res=%d",
537                                         i, res);
538                         goto parse_error;
539                 }
540         }
541
542         /* Create ethdev interface */
543         for (i = 0; i < init_params.nr_port; i++) {
544                 port_id = octeontx_create(dev, i, evdev, socket_id);
545                 if (port_id < 0) {
546                         octeontx_log_err("failed to create device %s",
547                                         dev_name);
548                         res = -ENODEV;
549                         goto parse_error;
550                 }
551
552                 PMD_INIT_LOG(INFO, "created ethdev %s for port %d", dev_name,
553                                         port_id);
554         }
555
556         if (probe_once) {
557                 octeontx_log_err("interface %s not supported", dev_name);
558                 octeontx_remove(dev);
559                 res = -ENOTSUP;
560                 goto parse_error;
561         }
562         probe_once = 1;
563
564         return 0;
565
566 parse_error:
567         octeontx_pko_fc_free();
568         return res;
569 }
570
571 static struct rte_vdev_driver octeontx_pmd_drv = {
572         .probe = octeontx_probe,
573         .remove = octeontx_remove,
574 };
575
576 RTE_PMD_REGISTER_VDEV(OCTEONTX_PMD, octeontx_pmd_drv);
577 RTE_PMD_REGISTER_ALIAS(OCTEONTX_PMD, eth_octeontx);
578 RTE_PMD_REGISTER_PARAM_STRING(OCTEONTX_PMD, "nr_port=<int> ");