doc: add Meson coding style to contributors guide
[dpdk.git] / lib / librte_ethdev / ethdev_private.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 GaĆ«tan Rivet
3  */
4
5 #include "rte_ethdev.h"
6 #include "ethdev_driver.h"
7 #include "ethdev_private.h"
8
9 uint16_t
10 eth_dev_to_id(const struct rte_eth_dev *dev)
11 {
12         if (dev == NULL)
13                 return RTE_MAX_ETHPORTS;
14         return dev - rte_eth_devices;
15 }
16
17 struct rte_eth_dev *
18 eth_find_device(const struct rte_eth_dev *start, rte_eth_cmp_t cmp,
19                 const void *data)
20 {
21         struct rte_eth_dev *edev;
22         ptrdiff_t idx;
23
24         /* Avoid Undefined Behaviour */
25         if (start != NULL &&
26             (start < &rte_eth_devices[0] ||
27              start > &rte_eth_devices[RTE_MAX_ETHPORTS]))
28                 return NULL;
29         if (start != NULL)
30                 idx = eth_dev_to_id(start) + 1;
31         else
32                 idx = 0;
33         for (; idx < RTE_MAX_ETHPORTS; idx++) {
34                 edev = &rte_eth_devices[idx];
35                 if (cmp(edev, data) == 0)
36                         return edev;
37         }
38         return NULL;
39 }
40
41 /* Put new value into list. */
42 static int
43 rte_eth_devargs_enlist(uint16_t *list, uint16_t *len_list,
44                        const uint16_t max_list, uint16_t val)
45 {
46         uint16_t i;
47
48         for (i = 0; i < *len_list; i++) {
49                 if (list[i] == val)
50                         return 0;
51         }
52         if (*len_list >= max_list)
53                 return -1;
54         list[(*len_list)++] = val;
55         return 0;
56 }
57
58 /* Parse and enlist a range expression of "min-max" or a single value. */
59 static char *
60 rte_eth_devargs_process_range(char *str, uint16_t *list, uint16_t *len_list,
61         const uint16_t max_list)
62 {
63         uint16_t lo, hi, val;
64         int result, n = 0;
65         char *pos = str;
66
67         result = sscanf(str, "%hu%n-%hu%n", &lo, &n, &hi, &n);
68         if (result == 1) {
69                 if (rte_eth_devargs_enlist(list, len_list, max_list, lo) != 0)
70                         return NULL;
71         } else if (result == 2) {
72                 if (lo > hi)
73                         return NULL;
74                 for (val = lo; val <= hi; val++) {
75                         if (rte_eth_devargs_enlist(list, len_list, max_list,
76                                                    val) != 0)
77                                 return NULL;
78                 }
79         } else
80                 return NULL;
81         return pos + n;
82 }
83
84 /*
85  * Parse list of values separated by ",".
86  * Each value could be a range [min-max] or single number.
87  * Examples:
88  *  2               - single
89  *  [1,2,3]         - single list
90  *  [1,3-5,7,9-11]  - list with singles and ranges
91  */
92 static char *
93 rte_eth_devargs_process_list(char *str, uint16_t *list, uint16_t *len_list,
94         const uint16_t max_list)
95 {
96         char *pos = str;
97
98         if (*pos == '[')
99                 pos++;
100         while (1) {
101                 pos = rte_eth_devargs_process_range(pos, list, len_list,
102                                                     max_list);
103                 if (pos == NULL)
104                         return NULL;
105                 if (*pos != ',') /* end of list */
106                         break;
107                 pos++;
108         }
109         if (*str == '[' && *pos != ']')
110                 return NULL;
111         if (*pos == ']')
112                 pos++;
113         return pos;
114 }
115
116 /*
117  * Parse representor ports from a single value or lists.
118  *
119  * Representor format:
120  *   #: range or single number of VF representor - legacy
121  *   [[c#]pf#]vf#: VF port representor/s
122  *   [[c#]pf#]sf#: SF port representor/s
123  *   [c#]pf#:      PF port representor/s
124  *
125  * Examples of #:
126  *  2               - single
127  *  [1,2,3]         - single list
128  *  [1,3-5,7,9-11]  - list with singles and ranges
129  */
130 int
131 rte_eth_devargs_parse_representor_ports(char *str, void *data)
132 {
133         struct rte_eth_devargs *eth_da = data;
134
135         if (str[0] == 'c') {
136                 str += 1;
137                 str = rte_eth_devargs_process_list(str, eth_da->mh_controllers,
138                                 &eth_da->nb_mh_controllers,
139                                 RTE_DIM(eth_da->mh_controllers));
140                 if (str == NULL)
141                         goto done;
142         }
143         if (str[0] == 'p' && str[1] == 'f') {
144                 eth_da->type = RTE_ETH_REPRESENTOR_PF;
145                 str += 2;
146                 str = rte_eth_devargs_process_list(str, eth_da->ports,
147                                 &eth_da->nb_ports, RTE_DIM(eth_da->ports));
148                 if (str == NULL || str[0] == '\0')
149                         goto done;
150         } else if (eth_da->nb_mh_controllers > 0) {
151                 /* 'c' must followed by 'pf'. */
152                 str = NULL;
153                 goto done;
154         }
155         if (str[0] == 'v' && str[1] == 'f') {
156                 eth_da->type = RTE_ETH_REPRESENTOR_VF;
157                 str += 2;
158         } else if (str[0] == 's' && str[1] == 'f') {
159                 eth_da->type = RTE_ETH_REPRESENTOR_SF;
160                 str += 2;
161         } else {
162                 /* 'pf' must followed by 'vf' or 'sf'. */
163                 if (eth_da->type == RTE_ETH_REPRESENTOR_PF) {
164                         str = NULL;
165                         goto done;
166                 }
167                 eth_da->type = RTE_ETH_REPRESENTOR_VF;
168         }
169         str = rte_eth_devargs_process_list(str, eth_da->representor_ports,
170                 &eth_da->nb_representor_ports,
171                 RTE_DIM(eth_da->representor_ports));
172 done:
173         if (str == NULL)
174                 RTE_LOG(ERR, EAL, "wrong representor format: %s\n", str);
175         return str == NULL ? -1 : 0;
176 }