#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"
static int hns3_update_link_info(struct rte_eth_dev *eth_dev);
static bool hns3_update_link_status(struct hns3_hw *hw);
-static int hns3_add_mc_addr(struct hns3_hw *hw,
- struct rte_ether_addr *mac_addr);
-static int hns3_remove_mc_addr(struct hns3_hw *hw,
- struct rte_ether_addr *mac_addr);
+static int hns3_add_mc_mac_addr(struct hns3_hw *hw,
+ struct rte_ether_addr *mac_addr);
+static int hns3_remove_mc_mac_addr(struct hns3_hw *hw,
+ struct rte_ether_addr *mac_addr);
static int hns3_restore_fec(struct hns3_hw *hw);
static int hns3_query_dev_fec_info(struct hns3_hw *hw);
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)
}
static int
-hns3_add_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
+hns3_add_uc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
{
struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
struct hns3_mac_vlan_tbl_entry_cmd req;
}
static int
-hns3_add_mc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
-{
- char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
- struct rte_ether_addr *addr;
- int ret;
- int i;
-
- for (i = 0; i < hw->mc_addrs_num; i++) {
- addr = &hw->mc_addrs[i];
- /* Check if there are duplicate addresses */
- if (rte_is_same_ether_addr(addr, mac_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 -EINVAL;
- }
- }
-
- ret = hns3_add_mc_addr(hw, mac_addr);
- if (ret) {
- hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
- mac_addr);
- hns3_err(hw, "failed to add mc mac addr(%s), ret = %d",
- mac_str, ret);
- }
- return ret;
-}
-
-static int
-hns3_remove_mc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
-{
- char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
- int ret;
-
- ret = hns3_remove_mc_addr(hw, mac_addr);
- if (ret) {
- hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
- mac_addr);
- hns3_err(hw, "failed to remove mc mac addr(%s), ret = %d",
- mac_str, ret);
- }
- return ret;
-}
-
-static 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))
- ret = hns3_add_mc_addr_common(hw, mac_addr);
- else
- ret = hns3_add_uc_addr_common(hw, mac_addr);
-
- if (ret) {
- rte_spinlock_unlock(&hw->lock);
- 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;
- }
-
- rte_spinlock_unlock(&hw->lock);
-
- return ret;
-}
-
-static int
-hns3_remove_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
+hns3_remove_uc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
{
struct hns3_mac_vlan_tbl_entry_cmd req;
char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
return ret;
}
-static 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 = hns3_remove_mc_addr_common(hw, mac_addr);
- else
- ret = hns3_remove_uc_addr_common(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)
rte_spinlock_lock(&hw->lock);
oaddr = (struct rte_ether_addr *)hw->mac.mac_addr;
- ret = hns3_remove_uc_addr_common(hw, oaddr);
+ ret = hw->ops.del_uc_mac_addr(hw, oaddr);
if (ret) {
hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
oaddr);
return ret;
}
- ret = hns3_add_uc_addr_common(hw, mac_addr);
+ ret = hw->ops.add_uc_mac_addr(hw, mac_addr);
if (ret) {
hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
mac_addr);
return 0;
err_pause_addr_cfg:
- ret_val = hns3_remove_uc_addr_common(hw, mac_addr);
+ ret_val = hw->ops.del_uc_mac_addr(hw, mac_addr);
if (ret_val) {
hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
mac_addr);
}
err_add_uc_addr:
- ret_val = hns3_add_uc_addr_common(hw, oaddr);
+ ret_val = hw->ops.add_uc_mac_addr(hw, oaddr);
if (ret_val) {
hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, oaddr);
hns3_warn(hw, "Failed to restore old uc mac addr(%s): %d",
return ret;
}
-static 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 rte_ether_addr *addr;
- int err = 0;
- int ret;
- int i;
-
- for (i = 0; i < HNS3_UC_MACADDR_NUM; i++) {
- addr = &hw->data->mac_addrs[i];
- if (rte_is_zero_ether_addr(addr))
- continue;
- if (rte_is_multicast_ether_addr(addr))
- ret = del ? hns3_remove_mc_addr(hw, addr) :
- hns3_add_mc_addr(hw, addr);
- else
- ret = del ? hns3_remove_uc_addr_common(hw, addr) :
- hns3_add_uc_addr_common(hw, addr);
-
- if (ret) {
- err = 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 err;
-}
-
static void
hns3_update_desc_vfid(struct hns3_cmd_desc *desc, uint8_t vfid, bool clr)
{
}
static int
-hns3_add_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
+hns3_add_mc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
{
struct hns3_cmd_desc desc[HNS3_MC_MAC_VLAN_OPS_DESC_NUM];
struct hns3_mac_vlan_tbl_entry_cmd req;
}
static int
-hns3_remove_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
+hns3_remove_mc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
{
struct hns3_mac_vlan_tbl_entry_cmd req;
struct hns3_cmd_desc desc[3];
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)
-{
- char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
- struct rte_ether_addr *addr;
- 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
- */
- for (j = 0; j < HNS3_UC_MACADDR_NUM; 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;
-}
-
-static void
-hns3_set_mc_addr_calc_addr(struct hns3_hw *hw,
- struct rte_ether_addr *mc_addr_set,
- int mc_addr_num,
- struct rte_ether_addr *reserved_addr_list,
- int *reserved_addr_num,
- struct rte_ether_addr *add_addr_list,
- int *add_addr_num,
- struct rte_ether_addr *rm_addr_list,
- int *rm_addr_num)
-{
- struct rte_ether_addr *addr;
- int current_addr_num;
- int reserved_num = 0;
- int add_num = 0;
- int rm_num = 0;
- int num;
- int i;
- int j;
- bool same_addr;
-
- /* Calculate the mc mac address list that should be removed */
- current_addr_num = hw->mc_addrs_num;
- for (i = 0; i < current_addr_num; i++) {
- addr = &hw->mc_addrs[i];
- same_addr = false;
- for (j = 0; j < mc_addr_num; j++) {
- if (rte_is_same_ether_addr(addr, &mc_addr_set[j])) {
- same_addr = true;
- break;
- }
- }
-
- if (!same_addr) {
- rte_ether_addr_copy(addr, &rm_addr_list[rm_num]);
- rm_num++;
- } else {
- rte_ether_addr_copy(addr,
- &reserved_addr_list[reserved_num]);
- reserved_num++;
- }
- }
-
- /* Calculate the mc mac address list that should be added */
- for (i = 0; i < mc_addr_num; i++) {
- addr = &mc_addr_set[i];
- same_addr = false;
- for (j = 0; j < current_addr_num; j++) {
- if (rte_is_same_ether_addr(addr, &hw->mc_addrs[j])) {
- same_addr = true;
- break;
- }
- }
-
- if (!same_addr) {
- rte_ether_addr_copy(addr, &add_addr_list[add_num]);
- add_num++;
- }
- }
-
- /* Reorder the mc mac address list maintained by driver */
- for (i = 0; i < reserved_num; i++)
- rte_ether_addr_copy(&reserved_addr_list[i], &hw->mc_addrs[i]);
-
- for (i = 0; i < rm_num; i++) {
- num = reserved_num + i;
- rte_ether_addr_copy(&rm_addr_list[i], &hw->mc_addrs[num]);
- }
-
- *reserved_addr_num = reserved_num;
- *add_addr_num = add_num;
- *rm_addr_num = rm_num;
-}
-
-static 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 reserved_addr_list[HNS3_MC_MACADDR_NUM];
- struct rte_ether_addr add_addr_list[HNS3_MC_MACADDR_NUM];
- struct rte_ether_addr rm_addr_list[HNS3_MC_MACADDR_NUM];
- struct rte_ether_addr *addr;
- int reserved_addr_num;
- int add_addr_num;
- int rm_addr_num;
- int mc_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);
-
- /*
- * Calculate the mc mac address lists those should be removed and be
- * added, Reorder the mc mac address list maintained by driver.
- */
- mc_addr_num = (int)nb_mc_addr;
- hns3_set_mc_addr_calc_addr(hw, mc_addr_set, mc_addr_num,
- reserved_addr_list, &reserved_addr_num,
- add_addr_list, &add_addr_num,
- rm_addr_list, &rm_addr_num);
-
- /* Remove mc mac addresses */
- for (i = 0; i < rm_addr_num; i++) {
- num = rm_addr_num - i - 1;
- addr = &rm_addr_list[num];
- ret = hns3_remove_mc_addr(hw, addr);
- if (ret) {
- rte_spinlock_unlock(&hw->lock);
- return ret;
- }
- hw->mc_addrs_num--;
- }
-
- /* Add mc mac addresses */
- for (i = 0; i < add_addr_num; i++) {
- addr = &add_addr_list[i];
- ret = hns3_add_mc_addr(hw, addr);
- if (ret) {
- rte_spinlock_unlock(&hw->lock);
- return ret;
- }
-
- num = reserved_addr_num + i;
- rte_ether_addr_copy(addr, &hw->mc_addrs[num]);
- hw->mc_addrs_num++;
- }
- rte_spinlock_unlock(&hw->lock);
-
- return 0;
-}
-
-static 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 err = 0;
- int ret;
- 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 = hns3_remove_mc_addr(hw, addr);
- else
- ret = hns3_add_mc_addr(hw, addr);
- if (ret) {
- err = ret;
- hns3_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
- addr);
- hns3_dbg(hw, "%s mc mac addr: %s failed for pf: ret = %d",
- del ? "Remove" : "Restore", mac_str, ret);
- }
- }
- return err;
-}
-
static int
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.",
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);
if (hns3_dev_get_support(hw, INDEP_TXRX))
info->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP |
RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP;
+ info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP;
if (hns3_dev_get_support(hw, PTP))
info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_TIMESTAMP;
hns3_config_all_msix_error(hw, true);
- ret = rte_intr_callback_register(&pci_dev->intr_handle,
+ ret = rte_intr_callback_register(pci_dev->intr_handle,
hns3_interrupt_handler,
eth_dev);
if (ret) {
goto err_get_config;
/* Enable interrupt */
- rte_intr_enable(&pci_dev->intr_handle);
+ rte_intr_enable(pci_dev->intr_handle);
hns3_pf_enable_irq0(hw);
/* Get configuration */
hns3_tqp_stats_uninit(hw);
err_get_config:
hns3_pf_disable_irq0(hw);
- rte_intr_disable(&pci_dev->intr_handle);
- hns3_intr_unregister(&pci_dev->intr_handle, hns3_interrupt_handler,
+ rte_intr_disable(pci_dev->intr_handle);
+ hns3_intr_unregister(pci_dev->intr_handle, hns3_interrupt_handler,
eth_dev);
err_intr_callback_register:
err_cmd_init:
hns3_tqp_stats_uninit(hw);
hns3_config_mac_tnl_int(hw, false);
hns3_pf_disable_irq0(hw);
- rte_intr_disable(&pci_dev->intr_handle);
- hns3_intr_unregister(&pci_dev->intr_handle, hns3_interrupt_handler,
+ rte_intr_disable(pci_dev->intr_handle);
+ hns3_intr_unregister(pci_dev->intr_handle, hns3_interrupt_handler,
eth_dev);
hns3_config_all_msix_error(hw, false);
hns3_cmd_uninit(hw);
hns3_map_rx_interrupt(struct rte_eth_dev *dev)
{
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
- struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint16_t base = RTE_INTR_VEC_ZERO_OFFSET;
uint16_t vec = RTE_INTR_VEC_ZERO_OFFSET;
if (rte_intr_efd_enable(intr_handle, intr_vector))
return -EINVAL;
- if (intr_handle->intr_vec == NULL) {
- intr_handle->intr_vec =
- rte_zmalloc("intr_vec",
- hw->used_rx_queues * sizeof(int), 0);
- if (intr_handle->intr_vec == NULL) {
- hns3_err(hw, "failed to allocate %u rx_queues intr_vec",
- hw->used_rx_queues);
- ret = -ENOMEM;
- goto alloc_intr_vec_error;
- }
+ /* Allocate vector list */
+ if (rte_intr_vec_list_alloc(intr_handle, "intr_vec",
+ hw->used_rx_queues)) {
+ hns3_err(hw, "failed to allocate %u rx_queues intr_vec",
+ hw->used_rx_queues);
+ ret = -ENOMEM;
+ goto alloc_intr_vec_error;
}
if (rte_intr_allow_others(intr_handle)) {
HNS3_RING_TYPE_RX, q_id);
if (ret)
goto bind_vector_error;
- intr_handle->intr_vec[q_id] = vec;
+
+ if (rte_intr_vec_list_index_set(intr_handle, q_id, vec))
+ goto bind_vector_error;
/*
* If there are not enough efds (e.g. not enough interrupt),
* remaining queues will be bond to the last interrupt.
*/
- if (vec < base + intr_handle->nb_efd - 1)
+ if (vec < base + rte_intr_nb_efd_get(intr_handle) - 1)
vec++;
}
rte_intr_enable(intr_handle);
return 0;
bind_vector_error:
- rte_free(intr_handle->intr_vec);
- intr_handle->intr_vec = NULL;
+ rte_intr_vec_list_free(intr_handle);
alloc_intr_vec_error:
rte_intr_efd_disable(intr_handle);
return ret;
{
struct rte_eth_dev *dev = &rte_eth_devices[hw->data->port_id];
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
- struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
uint16_t q_id;
int ret;
if (rte_intr_dp_is_en(intr_handle)) {
for (q_id = 0; q_id < hw->used_rx_queues; q_id++) {
ret = hns3_bind_ring_with_vector(hw,
- intr_handle->intr_vec[q_id], true,
- HNS3_RING_TYPE_RX, q_id);
+ rte_intr_vec_list_index_get(intr_handle,
+ q_id),
+ true, HNS3_RING_TYPE_RX, q_id);
if (ret)
return ret;
}
hns3_unmap_rx_interrupt(struct rte_eth_dev *dev)
{
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
- struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
struct hns3_adapter *hns = dev->data->dev_private;
struct hns3_hw *hw = &hns->hw;
uint8_t base = RTE_INTR_VEC_ZERO_OFFSET;
(void)hns3_bind_ring_with_vector(hw, vec, false,
HNS3_RING_TYPE_RX,
q_id);
- if (vec < base + intr_handle->nb_efd - 1)
+ if (vec < base + rte_intr_nb_efd_get(intr_handle)
+ - 1)
vec++;
}
}
/* Clean datapath event and queue/vec mapping */
rte_intr_efd_disable(intr_handle);
- if (intr_handle->intr_vec) {
- rte_free(intr_handle->intr_vec);
- intr_handle->intr_vec = NULL;
- }
+ rte_intr_vec_list_free(intr_handle);
}
static int
struct hns3_hw *hw = &hns->hw;
int ret = 0;
- if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
+ hns3_mp_uninit(eth_dev);
return 0;
+ }
if (hw->adapter_state == HNS3_NIC_STARTED)
ret = hns3_dev_stop(eth_dev);
hns3_uninit_pf(eth_dev);
hns3_free_all_queues(eth_dev);
rte_free(hw->reset.wait_data);
- hns3_mp_uninit_primary();
+ hns3_mp_uninit(eth_dev);
hns3_warn(hw, "Close port %u finished", hw->data->port_id);
return ret;
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,
.start_service = hns3_start_service,
};
+static void
+hns3_init_hw_ops(struct hns3_hw *hw)
+{
+ hw->ops.add_mc_mac_addr = hns3_add_mc_mac_addr;
+ hw->ops.del_mc_mac_addr = hns3_remove_mc_mac_addr;
+ hw->ops.add_uc_mac_addr = hns3_add_uc_mac_addr;
+ hw->ops.del_uc_mac_addr = hns3_remove_uc_mac_addr;
+}
+
static int
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;
- }
- hw->secondary_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;
- }
-
hw->adapter_state = HNS3_NIC_UNINITIALIZED;
hns->is_vf = false;
hw->data = eth_dev->data;
goto err_init_reset;
hw->reset.ops = &hns3_reset_ops;
+ hns3_init_hw_ops(hw);
ret = hns3_init_pf(eth_dev);
if (ret) {
PMD_INIT_LOG(ERR, "Failed to init pf: %d", ret);
rte_free(hw->reset.wait_data);
err_init_reset:
- hns3_mp_uninit_primary();
+ 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;
PMD_INIT_FUNC_TRACE();
- if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
+ hns3_mp_uninit(eth_dev);
return 0;
+ }
if (hw->adapter_state < HNS3_NIC_CLOSING)
hns3_dev_close(eth_dev);