net/hns3: extract common code to its own file
[dpdk.git] / drivers / net / hns3 / hns3_common.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2021 HiSilicon Limited
3  */
4
5 #include <rte_kvargs.h>
6
7 #include "hns3_logs.h"
8 #include "hns3_common.h"
9
10 static int
11 hns3_parse_io_hint_func(const char *key, const char *value, void *extra_args)
12 {
13         uint32_t hint = HNS3_IO_FUNC_HINT_NONE;
14
15         RTE_SET_USED(key);
16
17         if (strcmp(value, "vec") == 0)
18                 hint = HNS3_IO_FUNC_HINT_VEC;
19         else if (strcmp(value, "sve") == 0)
20                 hint = HNS3_IO_FUNC_HINT_SVE;
21         else if (strcmp(value, "simple") == 0)
22                 hint = HNS3_IO_FUNC_HINT_SIMPLE;
23         else if (strcmp(value, "common") == 0)
24                 hint = HNS3_IO_FUNC_HINT_COMMON;
25
26         /* If the hint is valid then update output parameters */
27         if (hint != HNS3_IO_FUNC_HINT_NONE)
28                 *(uint32_t *)extra_args = hint;
29
30         return 0;
31 }
32
33 static const char *
34 hns3_get_io_hint_func_name(uint32_t hint)
35 {
36         switch (hint) {
37         case HNS3_IO_FUNC_HINT_VEC:
38                 return "vec";
39         case HNS3_IO_FUNC_HINT_SVE:
40                 return "sve";
41         case HNS3_IO_FUNC_HINT_SIMPLE:
42                 return "simple";
43         case HNS3_IO_FUNC_HINT_COMMON:
44                 return "common";
45         default:
46                 return "none";
47         }
48 }
49
50 static int
51 hns3_parse_dev_caps_mask(const char *key, const char *value, void *extra_args)
52 {
53         uint64_t val;
54
55         RTE_SET_USED(key);
56
57         val = strtoull(value, NULL, 16);
58         *(uint64_t *)extra_args = val;
59
60         return 0;
61 }
62
63 static int
64 hns3_parse_mbx_time_limit(const char *key, const char *value, void *extra_args)
65 {
66         uint32_t val;
67
68         RTE_SET_USED(key);
69
70         val = strtoul(value, NULL, 10);
71         if (val > HNS3_MBX_DEF_TIME_LIMIT_MS && val <= UINT16_MAX)
72                 *(uint16_t *)extra_args = val;
73
74         return 0;
75 }
76
77 void
78 hns3_parse_devargs(struct rte_eth_dev *dev)
79 {
80         uint16_t mbx_time_limit_ms = HNS3_MBX_DEF_TIME_LIMIT_MS;
81         struct hns3_adapter *hns = dev->data->dev_private;
82         uint32_t rx_func_hint = HNS3_IO_FUNC_HINT_NONE;
83         uint32_t tx_func_hint = HNS3_IO_FUNC_HINT_NONE;
84         struct hns3_hw *hw = &hns->hw;
85         uint64_t dev_caps_mask = 0;
86         struct rte_kvargs *kvlist;
87
88         if (dev->device->devargs == NULL)
89                 return;
90
91         kvlist = rte_kvargs_parse(dev->device->devargs->args, NULL);
92         if (!kvlist)
93                 return;
94
95         (void)rte_kvargs_process(kvlist, HNS3_DEVARG_RX_FUNC_HINT,
96                            &hns3_parse_io_hint_func, &rx_func_hint);
97         (void)rte_kvargs_process(kvlist, HNS3_DEVARG_TX_FUNC_HINT,
98                            &hns3_parse_io_hint_func, &tx_func_hint);
99         (void)rte_kvargs_process(kvlist, HNS3_DEVARG_DEV_CAPS_MASK,
100                            &hns3_parse_dev_caps_mask, &dev_caps_mask);
101         (void)rte_kvargs_process(kvlist, HNS3_DEVARG_MBX_TIME_LIMIT_MS,
102                            &hns3_parse_mbx_time_limit, &mbx_time_limit_ms);
103
104         rte_kvargs_free(kvlist);
105
106         if (rx_func_hint != HNS3_IO_FUNC_HINT_NONE)
107                 hns3_warn(hw, "parsed %s = %s.", HNS3_DEVARG_RX_FUNC_HINT,
108                           hns3_get_io_hint_func_name(rx_func_hint));
109         hns->rx_func_hint = rx_func_hint;
110         if (tx_func_hint != HNS3_IO_FUNC_HINT_NONE)
111                 hns3_warn(hw, "parsed %s = %s.", HNS3_DEVARG_TX_FUNC_HINT,
112                           hns3_get_io_hint_func_name(tx_func_hint));
113         hns->tx_func_hint = tx_func_hint;
114
115         if (dev_caps_mask != 0)
116                 hns3_warn(hw, "parsed %s = 0x%" PRIx64 ".",
117                           HNS3_DEVARG_DEV_CAPS_MASK, dev_caps_mask);
118         hns->dev_caps_mask = dev_caps_mask;
119 }
120
121 void
122 hns3_clock_gettime(struct timeval *tv)
123 {
124 #ifdef CLOCK_MONOTONIC_RAW /* Defined in glibc bits/time.h */
125 #define CLOCK_TYPE CLOCK_MONOTONIC_RAW
126 #else
127 #define CLOCK_TYPE CLOCK_MONOTONIC
128 #endif
129 #define NSEC_TO_USEC_DIV 1000
130
131         struct timespec spec;
132         (void)clock_gettime(CLOCK_TYPE, &spec);
133
134         tv->tv_sec = spec.tv_sec;
135         tv->tv_usec = spec.tv_nsec / NSEC_TO_USEC_DIV;
136 }
137
138 uint64_t
139 hns3_clock_calctime_ms(struct timeval *tv)
140 {
141         return (uint64_t)tv->tv_sec * MSEC_PER_SEC +
142                 tv->tv_usec / USEC_PER_MSEC;
143 }
144
145 uint64_t
146 hns3_clock_gettime_ms(void)
147 {
148         struct timeval tv;
149
150         hns3_clock_gettime(&tv);
151         return hns3_clock_calctime_ms(&tv);
152 }
153
154 void hns3_ether_format_addr(char *buf, uint16_t size,
155                             const struct rte_ether_addr *ether_addr)
156 {
157         snprintf(buf, size, "%02X:**:**:**:%02X:%02X",
158                 ether_addr->addr_bytes[0],
159                 ether_addr->addr_bytes[4],
160                 ether_addr->addr_bytes[5]);
161 }
162
163 static int
164 hns3_set_mc_addr_chk_param(struct hns3_hw *hw,
165                            struct rte_ether_addr *mc_addr_set,
166                            uint32_t nb_mc_addr)
167 {
168         struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
169         char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
170         struct rte_ether_addr *addr;
171         uint16_t mac_addrs_capa;
172         uint32_t i;
173         uint32_t j;
174
175         if (nb_mc_addr > HNS3_MC_MACADDR_NUM) {
176                 hns3_err(hw, "failed to set mc mac addr, nb_mc_addr(%u) "
177                          "invalid. valid range: 0~%d",
178                          nb_mc_addr, HNS3_MC_MACADDR_NUM);
179                 return -EINVAL;
180         }
181
182         /* Check if input mac addresses are valid */
183         for (i = 0; i < nb_mc_addr; i++) {
184                 addr = &mc_addr_set[i];
185                 if (!rte_is_multicast_ether_addr(addr)) {
186                         hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
187                                               addr);
188                         hns3_err(hw,
189                                  "failed to set mc mac addr, addr(%s) invalid.",
190                                  mac_str);
191                         return -EINVAL;
192                 }
193
194                 /* Check if there are duplicate addresses */
195                 for (j = i + 1; j < nb_mc_addr; j++) {
196                         if (rte_is_same_ether_addr(addr, &mc_addr_set[j])) {
197                                 hns3_ether_format_addr(mac_str,
198                                                       RTE_ETHER_ADDR_FMT_SIZE,
199                                                       addr);
200                                 hns3_err(hw, "failed to set mc mac addr, "
201                                          "addrs invalid. two same addrs(%s).",
202                                          mac_str);
203                                 return -EINVAL;
204                         }
205                 }
206
207                 /*
208                  * Check if there are duplicate addresses between mac_addrs
209                  * and mc_addr_set
210                  */
211                 mac_addrs_capa = hns->is_vf ? HNS3_VF_UC_MACADDR_NUM :
212                                               HNS3_UC_MACADDR_NUM;
213                 for (j = 0; j < mac_addrs_capa; j++) {
214                         if (rte_is_same_ether_addr(addr,
215                                                    &hw->data->mac_addrs[j])) {
216                                 hns3_ether_format_addr(mac_str,
217                                                        RTE_ETHER_ADDR_FMT_SIZE,
218                                                        addr);
219                                 hns3_err(hw, "failed to set mc mac addr, "
220                                          "addrs invalid. addrs(%s) has already "
221                                          "configured in mac_addr add API",
222                                          mac_str);
223                                 return -EINVAL;
224                         }
225                 }
226         }
227
228         return 0;
229 }
230
231 int
232 hns3_set_mc_mac_addr_list(struct rte_eth_dev *dev,
233                           struct rte_ether_addr *mc_addr_set,
234                           uint32_t nb_mc_addr)
235 {
236         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
237         struct rte_ether_addr *addr;
238         int cur_addr_num;
239         int set_addr_num;
240         int num;
241         int ret;
242         int i;
243
244         /* Check if input parameters are valid */
245         ret = hns3_set_mc_addr_chk_param(hw, mc_addr_set, nb_mc_addr);
246         if (ret)
247                 return ret;
248
249         rte_spinlock_lock(&hw->lock);
250         cur_addr_num = hw->mc_addrs_num;
251         for (i = 0; i < cur_addr_num; i++) {
252                 num = cur_addr_num - i - 1;
253                 addr = &hw->mc_addrs[num];
254                 ret = hw->ops.del_mc_mac_addr(hw, addr);
255                 if (ret) {
256                         rte_spinlock_unlock(&hw->lock);
257                         return ret;
258                 }
259
260                 hw->mc_addrs_num--;
261         }
262
263         set_addr_num = (int)nb_mc_addr;
264         for (i = 0; i < set_addr_num; i++) {
265                 addr = &mc_addr_set[i];
266                 ret = hw->ops.add_mc_mac_addr(hw, addr);
267                 if (ret) {
268                         rte_spinlock_unlock(&hw->lock);
269                         return ret;
270                 }
271
272                 rte_ether_addr_copy(addr, &hw->mc_addrs[hw->mc_addrs_num]);
273                 hw->mc_addrs_num++;
274         }
275         rte_spinlock_unlock(&hw->lock);
276
277         return 0;
278 }
279
280 int
281 hns3_configure_all_mc_mac_addr(struct hns3_adapter *hns, bool del)
282 {
283         char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
284         struct hns3_hw *hw = &hns->hw;
285         struct rte_ether_addr *addr;
286         int ret = 0;
287         int i;
288
289         for (i = 0; i < hw->mc_addrs_num; i++) {
290                 addr = &hw->mc_addrs[i];
291                 if (!rte_is_multicast_ether_addr(addr))
292                         continue;
293                 if (del)
294                         ret = hw->ops.del_mc_mac_addr(hw, addr);
295                 else
296                         ret = hw->ops.add_mc_mac_addr(hw, addr);
297                 if (ret) {
298                         hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
299                                               addr);
300                         hns3_dbg(hw, "failed to %s mc mac addr: %s ret = %d",
301                                  del ? "Remove" : "Restore", mac_str, ret);
302                 }
303         }
304         return ret;
305 }
306
307 int
308 hns3_configure_all_mac_addr(struct hns3_adapter *hns, bool del)
309 {
310         char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
311         struct hns3_hw *hw = &hns->hw;
312         struct hns3_hw_ops *ops = &hw->ops;
313         struct rte_ether_addr *addr;
314         uint16_t mac_addrs_capa;
315         int ret = 0;
316         int i;
317
318         mac_addrs_capa =
319                 hns->is_vf ? HNS3_VF_UC_MACADDR_NUM : HNS3_UC_MACADDR_NUM;
320         for (i = 0; i < mac_addrs_capa; i++) {
321                 addr = &hw->data->mac_addrs[i];
322                 if (rte_is_zero_ether_addr(addr))
323                         continue;
324                 if (rte_is_multicast_ether_addr(addr))
325                         ret = del ? ops->del_mc_mac_addr(hw, addr) :
326                               ops->add_mc_mac_addr(hw, addr);
327                 else
328                         ret = del ? ops->del_uc_mac_addr(hw, addr) :
329                               ops->add_uc_mac_addr(hw, addr);
330
331                 if (ret) {
332                         hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
333                                                addr);
334                         hns3_err(hw, "failed to %s mac addr(%s) index:%d ret = %d.",
335                                  del ? "remove" : "restore", mac_str, i, ret);
336                 }
337         }
338
339         return ret;
340 }
341
342 static bool
343 hns3_find_duplicate_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mc_addr)
344 {
345         char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
346         struct rte_ether_addr *addr;
347         int i;
348
349         for (i = 0; i < hw->mc_addrs_num; i++) {
350                 addr = &hw->mc_addrs[i];
351                 /* Check if there are duplicate addresses in mc_addrs[] */
352                 if (rte_is_same_ether_addr(addr, mc_addr)) {
353                         hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
354                                                addr);
355                         hns3_err(hw, "failed to add mc mac addr, same addrs"
356                                  "(%s) is added by the set_mc_mac_addr_list "
357                                  "API", mac_str);
358                         return true;
359                 }
360         }
361
362         return false;
363 }
364
365 int
366 hns3_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
367                   __rte_unused uint32_t idx, __rte_unused uint32_t pool)
368 {
369         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
370         char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
371         int ret;
372
373         rte_spinlock_lock(&hw->lock);
374
375         /*
376          * In hns3 network engine adding UC and MC mac address with different
377          * commands with firmware. We need to determine whether the input
378          * address is a UC or a MC address to call different commands.
379          * By the way, it is recommended calling the API function named
380          * rte_eth_dev_set_mc_addr_list to set the MC mac address, because
381          * using the rte_eth_dev_mac_addr_add API function to set MC mac address
382          * may affect the specifications of UC mac addresses.
383          */
384         if (rte_is_multicast_ether_addr(mac_addr)) {
385                 if (hns3_find_duplicate_mc_addr(hw, mac_addr)) {
386                         rte_spinlock_unlock(&hw->lock);
387                         return -EINVAL;
388                 }
389                 ret = hw->ops.add_mc_mac_addr(hw, mac_addr);
390         } else {
391                 ret = hw->ops.add_uc_mac_addr(hw, mac_addr);
392         }
393         rte_spinlock_unlock(&hw->lock);
394         if (ret) {
395                 hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
396                                       mac_addr);
397                 hns3_err(hw, "failed to add mac addr(%s), ret = %d", mac_str,
398                          ret);
399         }
400
401         return ret;
402 }
403
404 void
405 hns3_remove_mac_addr(struct rte_eth_dev *dev, uint32_t idx)
406 {
407         struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
408         /* index will be checked by upper level rte interface */
409         struct rte_ether_addr *mac_addr = &dev->data->mac_addrs[idx];
410         char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
411         int ret;
412
413         rte_spinlock_lock(&hw->lock);
414
415         if (rte_is_multicast_ether_addr(mac_addr))
416                 ret = hw->ops.del_mc_mac_addr(hw, mac_addr);
417         else
418                 ret = hw->ops.del_uc_mac_addr(hw, mac_addr);
419         rte_spinlock_unlock(&hw->lock);
420         if (ret) {
421                 hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
422                                       mac_addr);
423                 hns3_err(hw, "failed to remove mac addr(%s), ret = %d", mac_str,
424                          ret);
425         }
426 }