1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2021 HiSilicon Limited
5 #include <rte_kvargs.h>
8 #include "hns3_common.h"
11 hns3_parse_io_hint_func(const char *key, const char *value, void *extra_args)
13 uint32_t hint = HNS3_IO_FUNC_HINT_NONE;
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;
26 /* If the hint is valid then update output parameters */
27 if (hint != HNS3_IO_FUNC_HINT_NONE)
28 *(uint32_t *)extra_args = hint;
34 hns3_get_io_hint_func_name(uint32_t hint)
37 case HNS3_IO_FUNC_HINT_VEC:
39 case HNS3_IO_FUNC_HINT_SVE:
41 case HNS3_IO_FUNC_HINT_SIMPLE:
43 case HNS3_IO_FUNC_HINT_COMMON:
51 hns3_parse_dev_caps_mask(const char *key, const char *value, void *extra_args)
57 val = strtoull(value, NULL, HNS3_CONVERT_TO_HEXADECIMAL);
58 *(uint64_t *)extra_args = val;
64 hns3_parse_mbx_time_limit(const char *key, const char *value, void *extra_args)
70 val = strtoul(value, NULL, HNS3_CONVERT_TO_DECIMAL);
71 if (val > HNS3_MBX_DEF_TIME_LIMIT_MS && val <= UINT16_MAX)
72 *(uint16_t *)extra_args = val;
78 hns3_parse_devargs(struct rte_eth_dev *dev)
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;
88 if (dev->device->devargs == NULL)
91 kvlist = rte_kvargs_parse(dev->device->devargs->args, NULL);
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);
104 rte_kvargs_free(kvlist);
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;
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;
122 hns3_clock_gettime(struct timeval *tv)
124 #ifdef CLOCK_MONOTONIC_RAW /* Defined in glibc bits/time.h */
125 #define CLOCK_TYPE CLOCK_MONOTONIC_RAW
127 #define CLOCK_TYPE CLOCK_MONOTONIC
129 #define NSEC_TO_USEC_DIV 1000
131 struct timespec spec;
132 (void)clock_gettime(CLOCK_TYPE, &spec);
134 tv->tv_sec = spec.tv_sec;
135 tv->tv_usec = spec.tv_nsec / NSEC_TO_USEC_DIV;
139 hns3_clock_calctime_ms(struct timeval *tv)
141 return (uint64_t)tv->tv_sec * MSEC_PER_SEC +
142 tv->tv_usec / USEC_PER_MSEC;
146 hns3_clock_gettime_ms(void)
150 hns3_clock_gettime(&tv);
151 return hns3_clock_calctime_ms(&tv);
154 void hns3_ether_format_addr(char *buf, uint16_t size,
155 const struct rte_ether_addr *ether_addr)
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]);
164 hns3_set_mc_addr_chk_param(struct hns3_hw *hw,
165 struct rte_ether_addr *mc_addr_set,
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;
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);
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,
189 "failed to set mc mac addr, addr(%s) invalid.",
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,
200 hns3_err(hw, "failed to set mc mac addr, "
201 "addrs invalid. two same addrs(%s).",
208 * Check if there are duplicate addresses between mac_addrs
211 mac_addrs_capa = hns->is_vf ? HNS3_VF_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,
219 hns3_err(hw, "failed to set mc mac addr, "
220 "addrs invalid. addrs(%s) has already "
221 "configured in mac_addr add API",
232 hns3_set_mc_mac_addr_list(struct rte_eth_dev *dev,
233 struct rte_ether_addr *mc_addr_set,
236 struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
237 struct rte_ether_addr *addr;
244 /* Check if input parameters are valid */
245 ret = hns3_set_mc_addr_chk_param(hw, mc_addr_set, nb_mc_addr);
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);
256 rte_spinlock_unlock(&hw->lock);
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);
268 rte_spinlock_unlock(&hw->lock);
272 rte_ether_addr_copy(addr, &hw->mc_addrs[hw->mc_addrs_num]);
275 rte_spinlock_unlock(&hw->lock);
281 hns3_configure_all_mc_mac_addr(struct hns3_adapter *hns, bool del)
283 char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
284 struct hns3_hw *hw = &hns->hw;
285 struct rte_ether_addr *addr;
289 for (i = 0; i < hw->mc_addrs_num; i++) {
290 addr = &hw->mc_addrs[i];
291 if (!rte_is_multicast_ether_addr(addr))
294 ret = hw->ops.del_mc_mac_addr(hw, addr);
296 ret = hw->ops.add_mc_mac_addr(hw, addr);
298 hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
300 hns3_dbg(hw, "failed to %s mc mac addr: %s ret = %d",
301 del ? "Remove" : "Restore", mac_str, ret);
308 hns3_configure_all_mac_addr(struct hns3_adapter *hns, bool del)
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;
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))
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);
328 ret = del ? ops->del_uc_mac_addr(hw, addr) :
329 ops->add_uc_mac_addr(hw, addr);
332 hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
334 hns3_err(hw, "failed to %s mac addr(%s) index:%d ret = %d.",
335 del ? "remove" : "restore", mac_str, i, ret);
343 hns3_find_duplicate_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mc_addr)
345 char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
346 struct rte_ether_addr *addr;
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,
355 hns3_err(hw, "failed to add mc mac addr, same addrs"
356 "(%s) is added by the set_mc_mac_addr_list "
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)
369 struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
370 char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
373 rte_spinlock_lock(&hw->lock);
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.
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);
389 ret = hw->ops.add_mc_mac_addr(hw, mac_addr);
391 ret = hw->ops.add_uc_mac_addr(hw, mac_addr);
393 rte_spinlock_unlock(&hw->lock);
395 hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
397 hns3_err(hw, "failed to add mac addr(%s), ret = %d", mac_str,
405 hns3_remove_mac_addr(struct rte_eth_dev *dev, uint32_t idx)
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];
413 rte_spinlock_lock(&hw->lock);
415 if (rte_is_multicast_ether_addr(mac_addr))
416 ret = hw->ops.del_mc_mac_addr(hw, mac_addr);
418 ret = hw->ops.del_uc_mac_addr(hw, mac_addr);
419 rte_spinlock_unlock(&hw->lock);
421 hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
423 hns3_err(hw, "failed to remove mac addr(%s), ret = %d", mac_str,