net/hns3: extract common code to its own file
[dpdk.git] / drivers / net / hns3 / hns3_ethdev.c
index 88abbb8..2ddd295 100644 (file)
@@ -6,9 +6,9 @@
 #include <rte_bus_pci.h>
 #include <ethdev_pci.h>
 #include <rte_pci.h>
-#include <rte_kvargs.h>
 
 #include "hns3_ethdev.h"
+#include "hns3_common.h"
 #include "hns3_logs.h"
 #include "hns3_rxtx.h"
 #include "hns3_intr.h"
@@ -105,14 +105,6 @@ static int hns3_do_stop(struct hns3_adapter *hns);
 static int hns3_check_port_speed(struct hns3_hw *hw, uint32_t link_speeds);
 static int hns3_cfg_mac_mode(struct hns3_hw *hw, bool enable);
 
-void hns3_ether_format_addr(char *buf, uint16_t size,
-                           const struct rte_ether_addr *ether_addr)
-{
-       snprintf(buf, size, "%02X:**:**:**:%02X:%02X",
-               ether_addr->addr_bytes[0],
-               ether_addr->addr_bytes[4],
-               ether_addr->addr_bytes[5]);
-}
 
 static void
 hns3_pf_disable_irq0(struct hns3_hw *hw)
@@ -1609,68 +1601,6 @@ hns3_add_uc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
        return ret;
 }
 
-static bool
-hns3_find_duplicate_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mc_addr)
-{
-       char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
-       struct rte_ether_addr *addr;
-       int i;
-
-       for (i = 0; i < hw->mc_addrs_num; i++) {
-               addr = &hw->mc_addrs[i];
-               /* Check if there are duplicate addresses in mc_addrs[] */
-               if (rte_is_same_ether_addr(addr, mc_addr)) {
-                       hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
-                                              addr);
-                       hns3_err(hw, "failed to add mc mac addr, same addrs"
-                                "(%s) is added by the set_mc_mac_addr_list "
-                                "API", mac_str);
-                       return true;
-               }
-       }
-
-       return false;
-}
-
-int
-hns3_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
-                 __rte_unused uint32_t idx, __rte_unused uint32_t pool)
-{
-       struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
-       int ret;
-
-       rte_spinlock_lock(&hw->lock);
-
-       /*
-        * In hns3 network engine adding UC and MC mac address with different
-        * commands with firmware. We need to determine whether the input
-        * address is a UC or a MC address to call different commands.
-        * By the way, it is recommended calling the API function named
-        * rte_eth_dev_set_mc_addr_list to set the MC mac address, because
-        * using the rte_eth_dev_mac_addr_add API function to set MC mac address
-        * may affect the specifications of UC mac addresses.
-        */
-       if (rte_is_multicast_ether_addr(mac_addr)) {
-               if (hns3_find_duplicate_mc_addr(hw, mac_addr)) {
-                       rte_spinlock_unlock(&hw->lock);
-                       return -EINVAL;
-               }
-               ret = hw->ops.add_mc_mac_addr(hw, mac_addr);
-       } else {
-               ret = hw->ops.add_uc_mac_addr(hw, mac_addr);
-       }
-       rte_spinlock_unlock(&hw->lock);
-       if (ret) {
-               hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
-                                     mac_addr);
-               hns3_err(hw, "failed to add mac addr(%s), ret = %d", mac_str,
-                        ret);
-       }
-
-       return ret;
-}
-
 static int
 hns3_remove_uc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
 {
@@ -1699,30 +1629,6 @@ hns3_remove_uc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
        return ret;
 }
 
-void
-hns3_remove_mac_addr(struct rte_eth_dev *dev, uint32_t idx)
-{
-       struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       /* index will be checked by upper level rte interface */
-       struct rte_ether_addr *mac_addr = &dev->data->mac_addrs[idx];
-       char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
-       int ret;
-
-       rte_spinlock_lock(&hw->lock);
-
-       if (rte_is_multicast_ether_addr(mac_addr))
-               ret = hw->ops.del_mc_mac_addr(hw, mac_addr);
-       else
-               ret = hw->ops.del_uc_mac_addr(hw, mac_addr);
-       rte_spinlock_unlock(&hw->lock);
-       if (ret) {
-               hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
-                                     mac_addr);
-               hns3_err(hw, "failed to remove mac addr(%s), ret = %d", mac_str,
-                        ret);
-       }
-}
-
 static int
 hns3_set_default_mac_addr(struct rte_eth_dev *dev,
                          struct rte_ether_addr *mac_addr)
@@ -1787,41 +1693,6 @@ err_add_uc_addr:
        return ret;
 }
 
-int
-hns3_configure_all_mac_addr(struct hns3_adapter *hns, bool del)
-{
-       char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
-       struct hns3_hw *hw = &hns->hw;
-       struct hns3_hw_ops *ops = &hw->ops;
-       struct rte_ether_addr *addr;
-       uint16_t mac_addrs_capa;
-       int ret = 0;
-       int i;
-
-       mac_addrs_capa =
-               hns->is_vf ? HNS3_VF_UC_MACADDR_NUM : HNS3_UC_MACADDR_NUM;
-       for (i = 0; i < mac_addrs_capa; i++) {
-               addr = &hw->data->mac_addrs[i];
-               if (rte_is_zero_ether_addr(addr))
-                       continue;
-               if (rte_is_multicast_ether_addr(addr))
-                       ret = del ? ops->del_mc_mac_addr(hw, addr) :
-                             ops->add_mc_mac_addr(hw, addr);
-               else
-                       ret = del ? ops->del_uc_mac_addr(hw, addr) :
-                             ops->add_uc_mac_addr(hw, addr);
-
-               if (ret) {
-                       hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
-                                              addr);
-                       hns3_err(hw, "failed to %s mac addr(%s) index:%d ret = %d.",
-                                del ? "remove" : "restore", mac_str, i, ret);
-               }
-       }
-
-       return ret;
-}
-
 static void
 hns3_update_desc_vfid(struct hns3_cmd_desc *desc, uint8_t vfid, bool clr)
 {
@@ -1947,150 +1818,6 @@ hns3_remove_mc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
        return ret;
 }
 
-static int
-hns3_set_mc_addr_chk_param(struct hns3_hw *hw,
-                          struct rte_ether_addr *mc_addr_set,
-                          uint32_t nb_mc_addr)
-{
-       struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
-       char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
-       struct rte_ether_addr *addr;
-       uint16_t mac_addrs_capa;
-       uint32_t i;
-       uint32_t j;
-
-       if (nb_mc_addr > HNS3_MC_MACADDR_NUM) {
-               hns3_err(hw, "failed to set mc mac addr, nb_mc_addr(%u) "
-                        "invalid. valid range: 0~%d",
-                        nb_mc_addr, HNS3_MC_MACADDR_NUM);
-               return -EINVAL;
-       }
-
-       /* Check if input mac addresses are valid */
-       for (i = 0; i < nb_mc_addr; i++) {
-               addr = &mc_addr_set[i];
-               if (!rte_is_multicast_ether_addr(addr)) {
-                       hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
-                                             addr);
-                       hns3_err(hw,
-                                "failed to set mc mac addr, addr(%s) invalid.",
-                                mac_str);
-                       return -EINVAL;
-               }
-
-               /* Check if there are duplicate addresses */
-               for (j = i + 1; j < nb_mc_addr; j++) {
-                       if (rte_is_same_ether_addr(addr, &mc_addr_set[j])) {
-                               hns3_ether_format_addr(mac_str,
-                                                     RTE_ETHER_ADDR_FMT_SIZE,
-                                                     addr);
-                               hns3_err(hw, "failed to set mc mac addr, "
-                                        "addrs invalid. two same addrs(%s).",
-                                        mac_str);
-                               return -EINVAL;
-                       }
-               }
-
-               /*
-                * Check if there are duplicate addresses between mac_addrs
-                * and mc_addr_set
-                */
-               mac_addrs_capa = hns->is_vf ? HNS3_VF_UC_MACADDR_NUM :
-                                             HNS3_UC_MACADDR_NUM;
-               for (j = 0; j < mac_addrs_capa; j++) {
-                       if (rte_is_same_ether_addr(addr,
-                                                  &hw->data->mac_addrs[j])) {
-                               hns3_ether_format_addr(mac_str,
-                                                      RTE_ETHER_ADDR_FMT_SIZE,
-                                                      addr);
-                               hns3_err(hw, "failed to set mc mac addr, "
-                                        "addrs invalid. addrs(%s) has already "
-                                        "configured in mac_addr add API",
-                                        mac_str);
-                               return -EINVAL;
-                       }
-               }
-       }
-
-       return 0;
-}
-
-int
-hns3_set_mc_mac_addr_list(struct rte_eth_dev *dev,
-                         struct rte_ether_addr *mc_addr_set,
-                         uint32_t nb_mc_addr)
-{
-       struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       struct rte_ether_addr *addr;
-       int cur_addr_num;
-       int set_addr_num;
-       int num;
-       int ret;
-       int i;
-
-       /* Check if input parameters are valid */
-       ret = hns3_set_mc_addr_chk_param(hw, mc_addr_set, nb_mc_addr);
-       if (ret)
-               return ret;
-
-       rte_spinlock_lock(&hw->lock);
-       cur_addr_num = hw->mc_addrs_num;
-       for (i = 0; i < cur_addr_num; i++) {
-               num = cur_addr_num - i - 1;
-               addr = &hw->mc_addrs[num];
-               ret = hw->ops.del_mc_mac_addr(hw, addr);
-               if (ret) {
-                       rte_spinlock_unlock(&hw->lock);
-                       return ret;
-               }
-
-               hw->mc_addrs_num--;
-       }
-
-       set_addr_num = (int)nb_mc_addr;
-       for (i = 0; i < set_addr_num; i++) {
-               addr = &mc_addr_set[i];
-               ret = hw->ops.add_mc_mac_addr(hw, addr);
-               if (ret) {
-                       rte_spinlock_unlock(&hw->lock);
-                       return ret;
-               }
-
-               rte_ether_addr_copy(addr, &hw->mc_addrs[hw->mc_addrs_num]);
-               hw->mc_addrs_num++;
-       }
-       rte_spinlock_unlock(&hw->lock);
-
-       return 0;
-}
-
-int
-hns3_configure_all_mc_mac_addr(struct hns3_adapter *hns, bool del)
-{
-       char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
-       struct hns3_hw *hw = &hns->hw;
-       struct rte_ether_addr *addr;
-       int ret = 0;
-       int i;
-
-       for (i = 0; i < hw->mc_addrs_num; i++) {
-               addr = &hw->mc_addrs[i];
-               if (!rte_is_multicast_ether_addr(addr))
-                       continue;
-               if (del)
-                       ret = hw->ops.del_mc_mac_addr(hw, addr);
-               else
-                       ret = hw->ops.add_mc_mac_addr(hw, addr);
-               if (ret) {
-                       hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
-                                             addr);
-                       hns3_dbg(hw, "failed to %s mc mac addr: %s ret = %d",
-                                del ? "Remove" : "Restore", mac_str, ret);
-               }
-       }
-       return ret;
-}
-
 static int
 hns3_check_mq_mode(struct rte_eth_dev *dev)
 {
@@ -2104,7 +1831,7 @@ hns3_check_mq_mode(struct rte_eth_dev *dev)
        int max_tc = 0;
        int i;
 
-       if ((rx_mq_mode & RTE_ETH_MQ_RX_VMDQ_FLAG) ||
+       if (((uint32_t)rx_mq_mode & RTE_ETH_MQ_RX_VMDQ_FLAG) ||
            (tx_mq_mode == RTE_ETH_MQ_TX_VMDQ_DCB ||
             tx_mq_mode == RTE_ETH_MQ_TX_VMDQ_ONLY)) {
                hns3_err(hw, "VMDQ is not supported, rx_mq_mode = %d, tx_mq_mode = %d.",
@@ -2114,7 +1841,7 @@ hns3_check_mq_mode(struct rte_eth_dev *dev)
 
        dcb_rx_conf = &dev->data->dev_conf.rx_adv_conf.dcb_rx_conf;
        dcb_tx_conf = &dev->data->dev_conf.tx_adv_conf.dcb_tx_conf;
-       if (rx_mq_mode & RTE_ETH_MQ_RX_DCB_FLAG) {
+       if ((uint32_t)rx_mq_mode & RTE_ETH_MQ_RX_DCB_FLAG) {
                if (dcb_rx_conf->nb_tcs > pf->tc_max) {
                        hns3_err(hw, "nb_tcs(%u) > max_tc(%u) driver supported.",
                                 dcb_rx_conf->nb_tcs, pf->tc_max);
@@ -5851,8 +5578,7 @@ hns3_dev_close(struct rte_eth_dev *eth_dev)
        int ret = 0;
 
        if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
-               __atomic_fetch_sub(&hw->secondary_cnt, 1, __ATOMIC_RELAXED);
-               hns3_mp_uninit();
+               hns3_mp_uninit(eth_dev);
                return 0;
        }
 
@@ -5869,7 +5595,7 @@ hns3_dev_close(struct rte_eth_dev *eth_dev)
        hns3_uninit_pf(eth_dev);
        hns3_free_all_queues(eth_dev);
        rte_free(hw->reset.wait_data);
-       hns3_mp_uninit();
+       hns3_mp_uninit(eth_dev);
        hns3_warn(hw, "Close port %u finished", hw->data->port_id);
 
        return ret;
@@ -7112,161 +6838,6 @@ hns3_get_module_info(struct rte_eth_dev *dev,
        return 0;
 }
 
-void
-hns3_clock_gettime(struct timeval *tv)
-{
-#ifdef CLOCK_MONOTONIC_RAW /* Defined in glibc bits/time.h */
-#define CLOCK_TYPE CLOCK_MONOTONIC_RAW
-#else
-#define CLOCK_TYPE CLOCK_MONOTONIC
-#endif
-#define NSEC_TO_USEC_DIV 1000
-
-       struct timespec spec;
-       (void)clock_gettime(CLOCK_TYPE, &spec);
-
-       tv->tv_sec = spec.tv_sec;
-       tv->tv_usec = spec.tv_nsec / NSEC_TO_USEC_DIV;
-}
-
-uint64_t
-hns3_clock_calctime_ms(struct timeval *tv)
-{
-       return (uint64_t)tv->tv_sec * MSEC_PER_SEC +
-               tv->tv_usec / USEC_PER_MSEC;
-}
-
-uint64_t
-hns3_clock_gettime_ms(void)
-{
-       struct timeval tv;
-
-       hns3_clock_gettime(&tv);
-       return hns3_clock_calctime_ms(&tv);
-}
-
-static int
-hns3_parse_io_hint_func(const char *key, const char *value, void *extra_args)
-{
-       uint32_t hint = HNS3_IO_FUNC_HINT_NONE;
-
-       RTE_SET_USED(key);
-
-       if (strcmp(value, "vec") == 0)
-               hint = HNS3_IO_FUNC_HINT_VEC;
-       else if (strcmp(value, "sve") == 0)
-               hint = HNS3_IO_FUNC_HINT_SVE;
-       else if (strcmp(value, "simple") == 0)
-               hint = HNS3_IO_FUNC_HINT_SIMPLE;
-       else if (strcmp(value, "common") == 0)
-               hint = HNS3_IO_FUNC_HINT_COMMON;
-
-       /* If the hint is valid then update output parameters */
-       if (hint != HNS3_IO_FUNC_HINT_NONE)
-               *(uint32_t *)extra_args = hint;
-
-       return 0;
-}
-
-static const char *
-hns3_get_io_hint_func_name(uint32_t hint)
-{
-       switch (hint) {
-       case HNS3_IO_FUNC_HINT_VEC:
-               return "vec";
-       case HNS3_IO_FUNC_HINT_SVE:
-               return "sve";
-       case HNS3_IO_FUNC_HINT_SIMPLE:
-               return "simple";
-       case HNS3_IO_FUNC_HINT_COMMON:
-               return "common";
-       default:
-               return "none";
-       }
-}
-
-static int
-hns3_parse_dev_caps_mask(const char *key, const char *value, void *extra_args)
-{
-       uint64_t val;
-
-       RTE_SET_USED(key);
-
-       val = strtoull(value, NULL, 16);
-       *(uint64_t *)extra_args = val;
-
-       return 0;
-}
-
-static int
-hns3_parse_mbx_time_limit(const char *key, const char *value, void *extra_args)
-{
-       uint32_t val;
-
-       RTE_SET_USED(key);
-
-       val = strtoul(value, NULL, 10);
-
-       /*
-        * 500ms is empirical value in process of mailbox communication. If
-        * the delay value is set to one lower thanthe empirical value, mailbox
-        * communication may fail.
-        */
-       if (val > HNS3_MBX_DEF_TIME_LIMIT_MS && val <= UINT16_MAX)
-               *(uint16_t *)extra_args = val;
-
-       return 0;
-}
-
-void
-hns3_parse_devargs(struct rte_eth_dev *dev)
-{
-       uint16_t mbx_time_limit_ms = HNS3_MBX_DEF_TIME_LIMIT_MS;
-       struct hns3_adapter *hns = dev->data->dev_private;
-       uint32_t rx_func_hint = HNS3_IO_FUNC_HINT_NONE;
-       uint32_t tx_func_hint = HNS3_IO_FUNC_HINT_NONE;
-       struct hns3_hw *hw = &hns->hw;
-       uint64_t dev_caps_mask = 0;
-       struct rte_kvargs *kvlist;
-
-       if (dev->device->devargs == NULL)
-               return;
-
-       kvlist = rte_kvargs_parse(dev->device->devargs->args, NULL);
-       if (!kvlist)
-               return;
-
-       (void)rte_kvargs_process(kvlist, HNS3_DEVARG_RX_FUNC_HINT,
-                          &hns3_parse_io_hint_func, &rx_func_hint);
-       (void)rte_kvargs_process(kvlist, HNS3_DEVARG_TX_FUNC_HINT,
-                          &hns3_parse_io_hint_func, &tx_func_hint);
-       (void)rte_kvargs_process(kvlist, HNS3_DEVARG_DEV_CAPS_MASK,
-                          &hns3_parse_dev_caps_mask, &dev_caps_mask);
-       (void)rte_kvargs_process(kvlist, HNS3_DEVARG_MBX_TIME_LIMIT_MS,
-                          &hns3_parse_mbx_time_limit, &mbx_time_limit_ms);
-
-       rte_kvargs_free(kvlist);
-
-       if (rx_func_hint != HNS3_IO_FUNC_HINT_NONE)
-               hns3_warn(hw, "parsed %s = %s.", HNS3_DEVARG_RX_FUNC_HINT,
-                         hns3_get_io_hint_func_name(rx_func_hint));
-       hns->rx_func_hint = rx_func_hint;
-       if (tx_func_hint != HNS3_IO_FUNC_HINT_NONE)
-               hns3_warn(hw, "parsed %s = %s.", HNS3_DEVARG_TX_FUNC_HINT,
-                         hns3_get_io_hint_func_name(tx_func_hint));
-       hns->tx_func_hint = tx_func_hint;
-
-       if (dev_caps_mask != 0)
-               hns3_warn(hw, "parsed %s = 0x%" PRIx64 ".",
-                         HNS3_DEVARG_DEV_CAPS_MASK, dev_caps_mask);
-       hns->dev_caps_mask = dev_caps_mask;
-
-       if (mbx_time_limit_ms != HNS3_MBX_DEF_TIME_LIMIT_MS)
-               hns3_warn(hw, "parsed %s = %u.", HNS3_DEVARG_MBX_TIME_LIMIT_MS,
-                               mbx_time_limit_ms);
-       hns->mbx_time_limit_ms = mbx_time_limit_ms;
-}
-
 static const struct eth_dev_ops hns3_eth_dev_ops = {
        .dev_configure      = hns3_dev_configure,
        .dev_start          = hns3_dev_start,
@@ -7373,28 +6944,15 @@ hns3_dev_init(struct rte_eth_dev *eth_dev)
        hns3_set_rxtx_function(eth_dev);
        eth_dev->dev_ops = &hns3_eth_dev_ops;
        eth_dev->rx_queue_count = hns3_rx_queue_count;
+       ret = hns3_mp_init(eth_dev);
+       if (ret)
+               goto err_mp_init;
+
        if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
-               ret = hns3_mp_init_secondary();
-               if (ret) {
-                       PMD_INIT_LOG(ERR, "Failed to init for secondary "
-                                    "process, ret = %d", ret);
-                       goto err_mp_init_secondary;
-               }
-               __atomic_fetch_add(&hw->secondary_cnt, 1, __ATOMIC_RELAXED);
-               process_data.eth_dev_cnt++;
                hns3_tx_push_init(eth_dev);
                return 0;
        }
 
-       ret = hns3_mp_init_primary();
-       if (ret) {
-               PMD_INIT_LOG(ERR,
-                            "Failed to init for primary process, ret = %d",
-                            ret);
-               goto err_mp_init_primary;
-       }
-       process_data.eth_dev_cnt++;
-
        hw->adapter_state = HNS3_NIC_UNINITIALIZED;
        hns->is_vf = false;
        hw->data = eth_dev->data;
@@ -7464,10 +7022,9 @@ err_init_pf:
        rte_free(hw->reset.wait_data);
 
 err_init_reset:
-       hns3_mp_uninit();
+       hns3_mp_uninit(eth_dev);
 
-err_mp_init_primary:
-err_mp_init_secondary:
+err_mp_init:
        eth_dev->dev_ops = NULL;
        eth_dev->rx_pkt_burst = NULL;
        eth_dev->rx_descriptor_status = NULL;
@@ -7486,8 +7043,7 @@ hns3_dev_uninit(struct rte_eth_dev *eth_dev)
        PMD_INIT_FUNC_TRACE();
 
        if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
-               __atomic_fetch_sub(&hw->secondary_cnt, 1, __ATOMIC_RELAXED);
-               hns3_mp_uninit();
+               hns3_mp_uninit(eth_dev);
                return 0;
        }