From: Heinrich Kuhn Date: Thu, 29 Jul 2021 13:47:11 +0000 (+0200) Subject: net/nfp: rename files for consistency X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=8d7a59f171a2bb765ad45cee3f67df45e7e71f7e;p=dpdk.git net/nfp: rename files for consistency Rename the nfp_net.c file to nfp_common as it now contains functions common to VF and PF functionality. Rename the header file too to be consistent. Also remove the "net" naming from the _ctrl and _logs files for consistency across the PMD. Signed-off-by: Heinrich Kuhn Signed-off-by: Simon Horman --- diff --git a/drivers/net/nfp/meson.build b/drivers/net/nfp/meson.build index ab64d0cac3..810f02ae5b 100644 --- a/drivers/net/nfp/meson.build +++ b/drivers/net/nfp/meson.build @@ -18,7 +18,7 @@ sources = files( 'nfpcore/nfp_mutex.c', 'nfpcore/nfp_nsp_eth.c', 'nfpcore/nfp_hwinfo.c', - 'nfp_net.c', + 'nfp_common.c', 'nfp_rxtx.c', 'nfp_cpp_bridge.c', 'nfp_ethdev_vf.c', diff --git a/drivers/net/nfp/nfp_common.c b/drivers/net/nfp/nfp_common.c new file mode 100644 index 0000000000..1b4bc33593 --- /dev/null +++ b/drivers/net/nfp/nfp_common.c @@ -0,0 +1,1322 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2014-2018 Netronome Systems, Inc. + * All rights reserved. + * + * Small portions derived from code Copyright(c) 2010-2015 Intel Corporation. + */ + +/* + * vim:shiftwidth=8:noexpandtab + * + * @file dpdk/pmd/nfp_common.c + * + * Netronome vNIC DPDK Poll-Mode Driver: Common files + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nfpcore/nfp_cpp.h" +#include "nfpcore/nfp_nffw.h" +#include "nfpcore/nfp_hwinfo.h" +#include "nfpcore/nfp_mip.h" +#include "nfpcore/nfp_rtsym.h" +#include "nfpcore/nfp_nsp.h" + +#include "nfp_common.h" +#include "nfp_rxtx.h" +#include "nfp_logs.h" +#include "nfp_ctrl.h" +#include "nfp_cpp_bridge.h" + +#include +#include +#include +#include +#include +#include +#include + +static int +__nfp_net_reconfig(struct nfp_net_hw *hw, uint32_t update) +{ + int cnt; + uint32_t new; + struct timespec wait; + + PMD_DRV_LOG(DEBUG, "Writing to the configuration queue (%p)...", + hw->qcp_cfg); + + if (hw->qcp_cfg == NULL) + rte_panic("Bad configuration queue pointer\n"); + + nfp_qcp_ptr_add(hw->qcp_cfg, NFP_QCP_WRITE_PTR, 1); + + wait.tv_sec = 0; + wait.tv_nsec = 1000000; + + PMD_DRV_LOG(DEBUG, "Polling for update ack..."); + + /* Poll update field, waiting for NFP to ack the config */ + for (cnt = 0; ; cnt++) { + new = nn_cfg_readl(hw, NFP_NET_CFG_UPDATE); + if (new == 0) + break; + if (new & NFP_NET_CFG_UPDATE_ERR) { + PMD_INIT_LOG(ERR, "Reconfig error: 0x%08x", new); + return -1; + } + if (cnt >= NFP_NET_POLL_TIMEOUT) { + PMD_INIT_LOG(ERR, "Reconfig timeout for 0x%08x after" + " %dms", update, cnt); + rte_panic("Exiting\n"); + } + nanosleep(&wait, 0); /* waiting for a 1ms */ + } + PMD_DRV_LOG(DEBUG, "Ack DONE"); + return 0; +} + +/* + * Reconfigure the NIC + * @nn: device to reconfigure + * @ctrl: The value for the ctrl field in the BAR config + * @update: The value for the update field in the BAR config + * + * Write the update word to the BAR and ping the reconfig queue. Then poll + * until the firmware has acknowledged the update by zeroing the update word. + */ +int +nfp_net_reconfig(struct nfp_net_hw *hw, uint32_t ctrl, uint32_t update) +{ + uint32_t err; + + PMD_DRV_LOG(DEBUG, "nfp_net_reconfig: ctrl=%08x update=%08x", + ctrl, update); + + rte_spinlock_lock(&hw->reconfig_lock); + + nn_cfg_writel(hw, NFP_NET_CFG_CTRL, ctrl); + nn_cfg_writel(hw, NFP_NET_CFG_UPDATE, update); + + rte_wmb(); + + err = __nfp_net_reconfig(hw, update); + + rte_spinlock_unlock(&hw->reconfig_lock); + + if (!err) + return 0; + + /* + * Reconfig errors imply situations where they can be handled. + * Otherwise, rte_panic is called inside __nfp_net_reconfig + */ + PMD_INIT_LOG(ERR, "Error nfp_net reconfig for ctrl: %x update: %x", + ctrl, update); + return -EIO; +} + +/* + * Configure an Ethernet device. This function must be invoked first + * before any other function in the Ethernet API. This function can + * also be re-invoked when a device is in the stopped state. + */ +int +nfp_net_configure(struct rte_eth_dev *dev) +{ + struct rte_eth_conf *dev_conf; + struct rte_eth_rxmode *rxmode; + struct rte_eth_txmode *txmode; + struct nfp_net_hw *hw; + + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + /* + * A DPDK app sends info about how many queues to use and how + * those queues need to be configured. This is used by the + * DPDK core and it makes sure no more queues than those + * advertised by the driver are requested. This function is + * called after that internal process + */ + + PMD_INIT_LOG(DEBUG, "Configure"); + + dev_conf = &dev->data->dev_conf; + rxmode = &dev_conf->rxmode; + txmode = &dev_conf->txmode; + + if (rxmode->mq_mode & ETH_MQ_RX_RSS_FLAG) + rxmode->offloads |= DEV_RX_OFFLOAD_RSS_HASH; + + /* Checking TX mode */ + if (txmode->mq_mode) { + PMD_INIT_LOG(INFO, "TX mq_mode DCB and VMDq not supported"); + return -EINVAL; + } + + /* Checking RX mode */ + if (rxmode->mq_mode & ETH_MQ_RX_RSS && + !(hw->cap & NFP_NET_CFG_CTRL_RSS)) { + PMD_INIT_LOG(INFO, "RSS not supported"); + return -EINVAL; + } + + return 0; +} + +void +nfp_net_enable_queues(struct rte_eth_dev *dev) +{ + struct nfp_net_hw *hw; + uint64_t enabled_queues = 0; + int i; + + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + /* Enabling the required TX queues in the device */ + for (i = 0; i < dev->data->nb_tx_queues; i++) + enabled_queues |= (1 << i); + + nn_cfg_writeq(hw, NFP_NET_CFG_TXRS_ENABLE, enabled_queues); + + enabled_queues = 0; + + /* Enabling the required RX queues in the device */ + for (i = 0; i < dev->data->nb_rx_queues; i++) + enabled_queues |= (1 << i); + + nn_cfg_writeq(hw, NFP_NET_CFG_RXRS_ENABLE, enabled_queues); +} + +void +nfp_net_disable_queues(struct rte_eth_dev *dev) +{ + struct nfp_net_hw *hw; + uint32_t new_ctrl, update = 0; + + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + nn_cfg_writeq(hw, NFP_NET_CFG_TXRS_ENABLE, 0); + nn_cfg_writeq(hw, NFP_NET_CFG_RXRS_ENABLE, 0); + + new_ctrl = hw->ctrl & ~NFP_NET_CFG_CTRL_ENABLE; + update = NFP_NET_CFG_UPDATE_GEN | NFP_NET_CFG_UPDATE_RING | + NFP_NET_CFG_UPDATE_MSIX; + + if (hw->cap & NFP_NET_CFG_CTRL_RINGCFG) + new_ctrl &= ~NFP_NET_CFG_CTRL_RINGCFG; + + /* If an error when reconfig we avoid to change hw state */ + if (nfp_net_reconfig(hw, new_ctrl, update) < 0) + return; + + hw->ctrl = new_ctrl; +} + +void +nfp_net_params_setup(struct nfp_net_hw *hw) +{ + nn_cfg_writel(hw, NFP_NET_CFG_MTU, hw->mtu); + nn_cfg_writel(hw, NFP_NET_CFG_FLBUFSZ, hw->flbufsz); +} + +void +nfp_net_cfg_queue_setup(struct nfp_net_hw *hw) +{ + hw->qcp_cfg = hw->tx_bar + NFP_QCP_QUEUE_ADDR_SZ; +} + +#define ETH_ADDR_LEN 6 + +void +nfp_eth_copy_mac(uint8_t *dst, const uint8_t *src) +{ + int i; + + for (i = 0; i < ETH_ADDR_LEN; i++) + dst[i] = src[i]; +} + +void +nfp_net_write_mac(struct nfp_net_hw *hw, uint8_t *mac) +{ + uint32_t mac0 = *(uint32_t *)mac; + uint16_t mac1; + + nn_writel(rte_cpu_to_be_32(mac0), hw->ctrl_bar + NFP_NET_CFG_MACADDR); + + mac += 4; + mac1 = *(uint16_t *)mac; + nn_writew(rte_cpu_to_be_16(mac1), + hw->ctrl_bar + NFP_NET_CFG_MACADDR + 6); +} + +int +nfp_set_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr) +{ + struct nfp_net_hw *hw; + uint32_t update, ctrl; + + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + if ((hw->ctrl & NFP_NET_CFG_CTRL_ENABLE) && + !(hw->cap & NFP_NET_CFG_CTRL_LIVE_ADDR)) { + PMD_INIT_LOG(INFO, "MAC address unable to change when" + " port enabled"); + return -EBUSY; + } + + if ((hw->ctrl & NFP_NET_CFG_CTRL_ENABLE) && + !(hw->cap & NFP_NET_CFG_CTRL_LIVE_ADDR)) + return -EBUSY; + + /* Writing new MAC to the specific port BAR address */ + nfp_net_write_mac(hw, (uint8_t *)mac_addr); + + /* Signal the NIC about the change */ + update = NFP_NET_CFG_UPDATE_MACADDR; + ctrl = hw->ctrl; + if ((hw->ctrl & NFP_NET_CFG_CTRL_ENABLE) && + (hw->cap & NFP_NET_CFG_CTRL_LIVE_ADDR)) + ctrl |= NFP_NET_CFG_CTRL_LIVE_ADDR; + if (nfp_net_reconfig(hw, ctrl, update) < 0) { + PMD_INIT_LOG(INFO, "MAC address update failed"); + return -EIO; + } + return 0; +} + +int +nfp_configure_rx_interrupt(struct rte_eth_dev *dev, + struct rte_intr_handle *intr_handle) +{ + struct nfp_net_hw *hw; + int i; + + if (!intr_handle->intr_vec) { + intr_handle->intr_vec = + rte_zmalloc("intr_vec", + dev->data->nb_rx_queues * sizeof(int), 0); + if (!intr_handle->intr_vec) { + PMD_INIT_LOG(ERR, "Failed to allocate %d rx_queues" + " intr_vec", dev->data->nb_rx_queues); + return -ENOMEM; + } + } + + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + if (intr_handle->type == RTE_INTR_HANDLE_UIO) { + PMD_INIT_LOG(INFO, "VF: enabling RX interrupt with UIO"); + /* UIO just supports one queue and no LSC*/ + nn_cfg_writeb(hw, NFP_NET_CFG_RXR_VEC(0), 0); + intr_handle->intr_vec[0] = 0; + } else { + PMD_INIT_LOG(INFO, "VF: enabling RX interrupt with VFIO"); + for (i = 0; i < dev->data->nb_rx_queues; i++) { + /* + * The first msix vector is reserved for non + * efd interrupts + */ + nn_cfg_writeb(hw, NFP_NET_CFG_RXR_VEC(i), i + 1); + intr_handle->intr_vec[i] = i + 1; + PMD_INIT_LOG(DEBUG, "intr_vec[%d]= %d", i, + intr_handle->intr_vec[i]); + } + } + + /* Avoiding TX interrupts */ + hw->ctrl |= NFP_NET_CFG_CTRL_MSIX_TX_OFF; + return 0; +} + +uint32_t +nfp_check_offloads(struct rte_eth_dev *dev) +{ + struct nfp_net_hw *hw; + struct rte_eth_conf *dev_conf; + struct rte_eth_rxmode *rxmode; + struct rte_eth_txmode *txmode; + uint32_t ctrl = 0; + + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + dev_conf = &dev->data->dev_conf; + rxmode = &dev_conf->rxmode; + txmode = &dev_conf->txmode; + + if (rxmode->offloads & DEV_RX_OFFLOAD_IPV4_CKSUM) { + if (hw->cap & NFP_NET_CFG_CTRL_RXCSUM) + ctrl |= NFP_NET_CFG_CTRL_RXCSUM; + } + + if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP) { + if (hw->cap & NFP_NET_CFG_CTRL_RXVLAN) + ctrl |= NFP_NET_CFG_CTRL_RXVLAN; + } + + if (rxmode->offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) + hw->mtu = rxmode->max_rx_pkt_len; + + if (txmode->offloads & DEV_TX_OFFLOAD_VLAN_INSERT) + ctrl |= NFP_NET_CFG_CTRL_TXVLAN; + + /* L2 broadcast */ + if (hw->cap & NFP_NET_CFG_CTRL_L2BC) + ctrl |= NFP_NET_CFG_CTRL_L2BC; + + /* L2 multicast */ + if (hw->cap & NFP_NET_CFG_CTRL_L2MC) + ctrl |= NFP_NET_CFG_CTRL_L2MC; + + /* TX checksum offload */ + if (txmode->offloads & DEV_TX_OFFLOAD_IPV4_CKSUM || + txmode->offloads & DEV_TX_OFFLOAD_UDP_CKSUM || + txmode->offloads & DEV_TX_OFFLOAD_TCP_CKSUM) + ctrl |= NFP_NET_CFG_CTRL_TXCSUM; + + /* LSO offload */ + if (txmode->offloads & DEV_TX_OFFLOAD_TCP_TSO) { + if (hw->cap & NFP_NET_CFG_CTRL_LSO) + ctrl |= NFP_NET_CFG_CTRL_LSO; + else + ctrl |= NFP_NET_CFG_CTRL_LSO2; + } + + /* RX gather */ + if (txmode->offloads & DEV_TX_OFFLOAD_MULTI_SEGS) + ctrl |= NFP_NET_CFG_CTRL_GATHER; + + return ctrl; +} + +int +nfp_net_promisc_enable(struct rte_eth_dev *dev) +{ + uint32_t new_ctrl, update = 0; + struct nfp_net_hw *hw; + int ret; + + PMD_DRV_LOG(DEBUG, "Promiscuous mode enable"); + + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + if (!(hw->cap & NFP_NET_CFG_CTRL_PROMISC)) { + PMD_INIT_LOG(INFO, "Promiscuous mode not supported"); + return -ENOTSUP; + } + + if (hw->ctrl & NFP_NET_CFG_CTRL_PROMISC) { + PMD_DRV_LOG(INFO, "Promiscuous mode already enabled"); + return 0; + } + + new_ctrl = hw->ctrl | NFP_NET_CFG_CTRL_PROMISC; + update = NFP_NET_CFG_UPDATE_GEN; + + /* + * DPDK sets promiscuous mode on just after this call assuming + * it can not fail ... + */ + ret = nfp_net_reconfig(hw, new_ctrl, update); + if (ret < 0) + return ret; + + hw->ctrl = new_ctrl; + + return 0; +} + +int +nfp_net_promisc_disable(struct rte_eth_dev *dev) +{ + uint32_t new_ctrl, update = 0; + struct nfp_net_hw *hw; + int ret; + + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + if ((hw->ctrl & NFP_NET_CFG_CTRL_PROMISC) == 0) { + PMD_DRV_LOG(INFO, "Promiscuous mode already disabled"); + return 0; + } + + new_ctrl = hw->ctrl & ~NFP_NET_CFG_CTRL_PROMISC; + update = NFP_NET_CFG_UPDATE_GEN; + + /* + * DPDK sets promiscuous mode off just before this call + * assuming it can not fail ... + */ + ret = nfp_net_reconfig(hw, new_ctrl, update); + if (ret < 0) + return ret; + + hw->ctrl = new_ctrl; + + return 0; +} + +/* + * return 0 means link status changed, -1 means not changed + * + * Wait to complete is needed as it can take up to 9 seconds to get the Link + * status. + */ +int +nfp_net_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete) +{ + struct nfp_net_hw *hw; + struct rte_eth_link link; + uint32_t nn_link_status; + int ret; + + static const uint32_t ls_to_ethtool[] = { + [NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED] = ETH_SPEED_NUM_NONE, + [NFP_NET_CFG_STS_LINK_RATE_UNKNOWN] = ETH_SPEED_NUM_NONE, + [NFP_NET_CFG_STS_LINK_RATE_1G] = ETH_SPEED_NUM_1G, + [NFP_NET_CFG_STS_LINK_RATE_10G] = ETH_SPEED_NUM_10G, + [NFP_NET_CFG_STS_LINK_RATE_25G] = ETH_SPEED_NUM_25G, + [NFP_NET_CFG_STS_LINK_RATE_40G] = ETH_SPEED_NUM_40G, + [NFP_NET_CFG_STS_LINK_RATE_50G] = ETH_SPEED_NUM_50G, + [NFP_NET_CFG_STS_LINK_RATE_100G] = ETH_SPEED_NUM_100G, + }; + + PMD_DRV_LOG(DEBUG, "Link update"); + + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + nn_link_status = nn_cfg_readl(hw, NFP_NET_CFG_STS); + + memset(&link, 0, sizeof(struct rte_eth_link)); + + if (nn_link_status & NFP_NET_CFG_STS_LINK) + link.link_status = ETH_LINK_UP; + + link.link_duplex = ETH_LINK_FULL_DUPLEX; + + nn_link_status = (nn_link_status >> NFP_NET_CFG_STS_LINK_RATE_SHIFT) & + NFP_NET_CFG_STS_LINK_RATE_MASK; + + if (nn_link_status >= RTE_DIM(ls_to_ethtool)) + link.link_speed = ETH_SPEED_NUM_NONE; + else + link.link_speed = ls_to_ethtool[nn_link_status]; + + ret = rte_eth_linkstatus_set(dev, &link); + if (ret == 0) { + if (link.link_status) + PMD_DRV_LOG(INFO, "NIC Link is Up"); + else + PMD_DRV_LOG(INFO, "NIC Link is Down"); + } + return ret; +} + +int +nfp_net_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) +{ + int i; + struct nfp_net_hw *hw; + struct rte_eth_stats nfp_dev_stats; + + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + /* RTE_ETHDEV_QUEUE_STAT_CNTRS default value is 16 */ + + memset(&nfp_dev_stats, 0, sizeof(nfp_dev_stats)); + + /* reading per RX ring stats */ + for (i = 0; i < dev->data->nb_rx_queues; i++) { + if (i == RTE_ETHDEV_QUEUE_STAT_CNTRS) + break; + + nfp_dev_stats.q_ipackets[i] = + nn_cfg_readq(hw, NFP_NET_CFG_RXR_STATS(i)); + + nfp_dev_stats.q_ipackets[i] -= + hw->eth_stats_base.q_ipackets[i]; + + nfp_dev_stats.q_ibytes[i] = + nn_cfg_readq(hw, NFP_NET_CFG_RXR_STATS(i) + 0x8); + + nfp_dev_stats.q_ibytes[i] -= + hw->eth_stats_base.q_ibytes[i]; + } + + /* reading per TX ring stats */ + for (i = 0; i < dev->data->nb_tx_queues; i++) { + if (i == RTE_ETHDEV_QUEUE_STAT_CNTRS) + break; + + nfp_dev_stats.q_opackets[i] = + nn_cfg_readq(hw, NFP_NET_CFG_TXR_STATS(i)); + + nfp_dev_stats.q_opackets[i] -= + hw->eth_stats_base.q_opackets[i]; + + nfp_dev_stats.q_obytes[i] = + nn_cfg_readq(hw, NFP_NET_CFG_TXR_STATS(i) + 0x8); + + nfp_dev_stats.q_obytes[i] -= + hw->eth_stats_base.q_obytes[i]; + } + + nfp_dev_stats.ipackets = + nn_cfg_readq(hw, NFP_NET_CFG_STATS_RX_FRAMES); + + nfp_dev_stats.ipackets -= hw->eth_stats_base.ipackets; + + nfp_dev_stats.ibytes = + nn_cfg_readq(hw, NFP_NET_CFG_STATS_RX_OCTETS); + + nfp_dev_stats.ibytes -= hw->eth_stats_base.ibytes; + + nfp_dev_stats.opackets = + nn_cfg_readq(hw, NFP_NET_CFG_STATS_TX_FRAMES); + + nfp_dev_stats.opackets -= hw->eth_stats_base.opackets; + + nfp_dev_stats.obytes = + nn_cfg_readq(hw, NFP_NET_CFG_STATS_TX_OCTETS); + + nfp_dev_stats.obytes -= hw->eth_stats_base.obytes; + + /* reading general device stats */ + nfp_dev_stats.ierrors = + nn_cfg_readq(hw, NFP_NET_CFG_STATS_RX_ERRORS); + + nfp_dev_stats.ierrors -= hw->eth_stats_base.ierrors; + + nfp_dev_stats.oerrors = + nn_cfg_readq(hw, NFP_NET_CFG_STATS_TX_ERRORS); + + nfp_dev_stats.oerrors -= hw->eth_stats_base.oerrors; + + /* RX ring mbuf allocation failures */ + nfp_dev_stats.rx_nombuf = dev->data->rx_mbuf_alloc_failed; + + nfp_dev_stats.imissed = + nn_cfg_readq(hw, NFP_NET_CFG_STATS_RX_DISCARDS); + + nfp_dev_stats.imissed -= hw->eth_stats_base.imissed; + + if (stats) { + memcpy(stats, &nfp_dev_stats, sizeof(*stats)); + return 0; + } + return -EINVAL; +} + +int +nfp_net_stats_reset(struct rte_eth_dev *dev) +{ + int i; + struct nfp_net_hw *hw; + + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + /* + * hw->eth_stats_base records the per counter starting point. + * Lets update it now + */ + + /* reading per RX ring stats */ + for (i = 0; i < dev->data->nb_rx_queues; i++) { + if (i == RTE_ETHDEV_QUEUE_STAT_CNTRS) + break; + + hw->eth_stats_base.q_ipackets[i] = + nn_cfg_readq(hw, NFP_NET_CFG_RXR_STATS(i)); + + hw->eth_stats_base.q_ibytes[i] = + nn_cfg_readq(hw, NFP_NET_CFG_RXR_STATS(i) + 0x8); + } + + /* reading per TX ring stats */ + for (i = 0; i < dev->data->nb_tx_queues; i++) { + if (i == RTE_ETHDEV_QUEUE_STAT_CNTRS) + break; + + hw->eth_stats_base.q_opackets[i] = + nn_cfg_readq(hw, NFP_NET_CFG_TXR_STATS(i)); + + hw->eth_stats_base.q_obytes[i] = + nn_cfg_readq(hw, NFP_NET_CFG_TXR_STATS(i) + 0x8); + } + + hw->eth_stats_base.ipackets = + nn_cfg_readq(hw, NFP_NET_CFG_STATS_RX_FRAMES); + + hw->eth_stats_base.ibytes = + nn_cfg_readq(hw, NFP_NET_CFG_STATS_RX_OCTETS); + + hw->eth_stats_base.opackets = + nn_cfg_readq(hw, NFP_NET_CFG_STATS_TX_FRAMES); + + hw->eth_stats_base.obytes = + nn_cfg_readq(hw, NFP_NET_CFG_STATS_TX_OCTETS); + + /* reading general device stats */ + hw->eth_stats_base.ierrors = + nn_cfg_readq(hw, NFP_NET_CFG_STATS_RX_ERRORS); + + hw->eth_stats_base.oerrors = + nn_cfg_readq(hw, NFP_NET_CFG_STATS_TX_ERRORS); + + /* RX ring mbuf allocation failures */ + dev->data->rx_mbuf_alloc_failed = 0; + + hw->eth_stats_base.imissed = + nn_cfg_readq(hw, NFP_NET_CFG_STATS_RX_DISCARDS); + + return 0; +} + +int +nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) +{ + struct nfp_net_hw *hw; + + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + dev_info->max_rx_queues = (uint16_t)hw->max_rx_queues; + dev_info->max_tx_queues = (uint16_t)hw->max_tx_queues; + dev_info->min_rx_bufsize = RTE_ETHER_MIN_MTU; + dev_info->max_rx_pktlen = hw->max_mtu; + /* Next should change when PF support is implemented */ + dev_info->max_mac_addrs = 1; + + if (hw->cap & NFP_NET_CFG_CTRL_RXVLAN) + dev_info->rx_offload_capa = DEV_RX_OFFLOAD_VLAN_STRIP; + + if (hw->cap & NFP_NET_CFG_CTRL_RXCSUM) + dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_IPV4_CKSUM | + DEV_RX_OFFLOAD_UDP_CKSUM | + DEV_RX_OFFLOAD_TCP_CKSUM; + + if (hw->cap & NFP_NET_CFG_CTRL_TXVLAN) + dev_info->tx_offload_capa = DEV_TX_OFFLOAD_VLAN_INSERT; + + if (hw->cap & NFP_NET_CFG_CTRL_TXCSUM) + dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_IPV4_CKSUM | + DEV_TX_OFFLOAD_UDP_CKSUM | + DEV_TX_OFFLOAD_TCP_CKSUM; + + if (hw->cap & NFP_NET_CFG_CTRL_LSO_ANY) + dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_TCP_TSO; + + if (hw->cap & NFP_NET_CFG_CTRL_GATHER) + dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_MULTI_SEGS; + + dev_info->default_rxconf = (struct rte_eth_rxconf) { + .rx_thresh = { + .pthresh = DEFAULT_RX_PTHRESH, + .hthresh = DEFAULT_RX_HTHRESH, + .wthresh = DEFAULT_RX_WTHRESH, + }, + .rx_free_thresh = DEFAULT_RX_FREE_THRESH, + .rx_drop_en = 0, + }; + + dev_info->default_txconf = (struct rte_eth_txconf) { + .tx_thresh = { + .pthresh = DEFAULT_TX_PTHRESH, + .hthresh = DEFAULT_TX_HTHRESH, + .wthresh = DEFAULT_TX_WTHRESH, + }, + .tx_free_thresh = DEFAULT_TX_FREE_THRESH, + .tx_rs_thresh = DEFAULT_TX_RSBIT_THRESH, + }; + + dev_info->rx_desc_lim = (struct rte_eth_desc_lim) { + .nb_max = NFP_NET_MAX_RX_DESC, + .nb_min = NFP_NET_MIN_RX_DESC, + .nb_align = NFP_ALIGN_RING_DESC, + }; + + dev_info->tx_desc_lim = (struct rte_eth_desc_lim) { + .nb_max = NFP_NET_MAX_TX_DESC, + .nb_min = NFP_NET_MIN_TX_DESC, + .nb_align = NFP_ALIGN_RING_DESC, + .nb_seg_max = NFP_TX_MAX_SEG, + .nb_mtu_seg_max = NFP_TX_MAX_MTU_SEG, + }; + + /* All NFP devices support jumbo frames */ + dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_JUMBO_FRAME; + + if (hw->cap & NFP_NET_CFG_CTRL_RSS) { + dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_RSS_HASH; + + dev_info->flow_type_rss_offloads = ETH_RSS_IPV4 | + ETH_RSS_NONFRAG_IPV4_TCP | + ETH_RSS_NONFRAG_IPV4_UDP | + ETH_RSS_IPV6 | + ETH_RSS_NONFRAG_IPV6_TCP | + ETH_RSS_NONFRAG_IPV6_UDP; + + dev_info->reta_size = NFP_NET_CFG_RSS_ITBL_SZ; + dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ; + } + + dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G | + ETH_LINK_SPEED_25G | ETH_LINK_SPEED_40G | + ETH_LINK_SPEED_50G | ETH_LINK_SPEED_100G; + + return 0; +} + +const uint32_t * +nfp_net_supported_ptypes_get(struct rte_eth_dev *dev) +{ + static const uint32_t ptypes[] = { + /* refers to nfp_net_set_hash() */ + RTE_PTYPE_INNER_L3_IPV4, + RTE_PTYPE_INNER_L3_IPV6, + RTE_PTYPE_INNER_L3_IPV6_EXT, + RTE_PTYPE_INNER_L4_MASK, + RTE_PTYPE_UNKNOWN + }; + + if (dev->rx_pkt_burst == nfp_net_recv_pkts) + return ptypes; + return NULL; +} + +int +nfp_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id) +{ + struct rte_pci_device *pci_dev; + struct nfp_net_hw *hw; + int base = 0; + + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + pci_dev = RTE_ETH_DEV_TO_PCI(dev); + + if (pci_dev->intr_handle.type != RTE_INTR_HANDLE_UIO) + base = 1; + + /* Make sure all updates are written before un-masking */ + rte_wmb(); + nn_cfg_writeb(hw, NFP_NET_CFG_ICR(base + queue_id), + NFP_NET_CFG_ICR_UNMASKED); + return 0; +} + +int +nfp_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id) +{ + struct rte_pci_device *pci_dev; + struct nfp_net_hw *hw; + int base = 0; + + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + pci_dev = RTE_ETH_DEV_TO_PCI(dev); + + if (pci_dev->intr_handle.type != RTE_INTR_HANDLE_UIO) + base = 1; + + /* Make sure all updates are written before un-masking */ + rte_wmb(); + nn_cfg_writeb(hw, NFP_NET_CFG_ICR(base + queue_id), 0x1); + return 0; +} + +static void +nfp_net_dev_link_status_print(struct rte_eth_dev *dev) +{ + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); + struct rte_eth_link link; + + rte_eth_linkstatus_get(dev, &link); + if (link.link_status) + PMD_DRV_LOG(INFO, "Port %d: Link Up - speed %u Mbps - %s", + dev->data->port_id, link.link_speed, + link.link_duplex == ETH_LINK_FULL_DUPLEX + ? "full-duplex" : "half-duplex"); + else + PMD_DRV_LOG(INFO, " Port %d: Link Down", + dev->data->port_id); + + PMD_DRV_LOG(INFO, "PCI Address: " PCI_PRI_FMT, + pci_dev->addr.domain, pci_dev->addr.bus, + pci_dev->addr.devid, pci_dev->addr.function); +} + +/* Interrupt configuration and handling */ + +/* + * nfp_net_irq_unmask - Unmask an interrupt + * + * If MSI-X auto-masking is enabled clear the mask bit, otherwise + * clear the ICR for the entry. + */ +static void +nfp_net_irq_unmask(struct rte_eth_dev *dev) +{ + struct nfp_net_hw *hw; + struct rte_pci_device *pci_dev; + + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + pci_dev = RTE_ETH_DEV_TO_PCI(dev); + + if (hw->ctrl & NFP_NET_CFG_CTRL_MSIXAUTO) { + /* If MSI-X auto-masking is used, clear the entry */ + rte_wmb(); + rte_intr_ack(&pci_dev->intr_handle); + } else { + /* Make sure all updates are written before un-masking */ + rte_wmb(); + nn_cfg_writeb(hw, NFP_NET_CFG_ICR(NFP_NET_IRQ_LSC_IDX), + NFP_NET_CFG_ICR_UNMASKED); + } +} + +/* + * Interrupt handler which shall be registered for alarm callback for delayed + * handling specific interrupt to wait for the stable nic state. As the NIC + * interrupt state is not stable for nfp after link is just down, it needs + * to wait 4 seconds to get the stable status. + * + * @param handle Pointer to interrupt handle. + * @param param The address of parameter (struct rte_eth_dev *) + * + * @return void + */ +static void +nfp_net_dev_interrupt_delayed_handler(void *param) +{ + struct rte_eth_dev *dev = (struct rte_eth_dev *)param; + + nfp_net_link_update(dev, 0); + rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL); + + nfp_net_dev_link_status_print(dev); + + /* Unmasking */ + nfp_net_irq_unmask(dev); +} + +void +nfp_net_dev_interrupt_handler(void *param) +{ + int64_t timeout; + struct rte_eth_link link; + struct rte_eth_dev *dev = (struct rte_eth_dev *)param; + + PMD_DRV_LOG(DEBUG, "We got a LSC interrupt!!!"); + + rte_eth_linkstatus_get(dev, &link); + + nfp_net_link_update(dev, 0); + + /* likely to up */ + if (!link.link_status) { + /* handle it 1 sec later, wait it being stable */ + timeout = NFP_NET_LINK_UP_CHECK_TIMEOUT; + /* likely to down */ + } else { + /* handle it 4 sec later, wait it being stable */ + timeout = NFP_NET_LINK_DOWN_CHECK_TIMEOUT; + } + + if (rte_eal_alarm_set(timeout * 1000, + nfp_net_dev_interrupt_delayed_handler, + (void *)dev) < 0) { + PMD_INIT_LOG(ERR, "Error setting alarm"); + /* Unmasking */ + nfp_net_irq_unmask(dev); + } +} + +int +nfp_net_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) +{ + struct nfp_net_hw *hw; + + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + /* check that mtu is within the allowed range */ + if (mtu < RTE_ETHER_MIN_MTU || (uint32_t)mtu > hw->max_mtu) + return -EINVAL; + + /* mtu setting is forbidden if port is started */ + if (dev->data->dev_started) { + PMD_DRV_LOG(ERR, "port %d must be stopped before configuration", + dev->data->port_id); + return -EBUSY; + } + + /* switch to jumbo mode if needed */ + if ((uint32_t)mtu > RTE_ETHER_MTU) + dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME; + else + dev->data->dev_conf.rxmode.offloads &= ~DEV_RX_OFFLOAD_JUMBO_FRAME; + + /* update max frame size */ + dev->data->dev_conf.rxmode.max_rx_pkt_len = (uint32_t)mtu; + + /* writing to configuration space */ + nn_cfg_writel(hw, NFP_NET_CFG_MTU, (uint32_t)mtu); + + hw->mtu = mtu; + + return 0; +} + +int +nfp_net_vlan_offload_set(struct rte_eth_dev *dev, int mask) +{ + uint32_t new_ctrl, update; + struct nfp_net_hw *hw; + int ret; + + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + new_ctrl = 0; + + /* Enable vlan strip if it is not configured yet */ + if ((mask & ETH_VLAN_STRIP_OFFLOAD) && + !(hw->ctrl & NFP_NET_CFG_CTRL_RXVLAN)) + new_ctrl = hw->ctrl | NFP_NET_CFG_CTRL_RXVLAN; + + /* Disable vlan strip just if it is configured */ + if (!(mask & ETH_VLAN_STRIP_OFFLOAD) && + (hw->ctrl & NFP_NET_CFG_CTRL_RXVLAN)) + new_ctrl = hw->ctrl & ~NFP_NET_CFG_CTRL_RXVLAN; + + if (new_ctrl == 0) + return 0; + + update = NFP_NET_CFG_UPDATE_GEN; + + ret = nfp_net_reconfig(hw, new_ctrl, update); + if (!ret) + hw->ctrl = new_ctrl; + + return ret; +} + +static int +nfp_net_rss_reta_write(struct rte_eth_dev *dev, + struct rte_eth_rss_reta_entry64 *reta_conf, + uint16_t reta_size) +{ + uint32_t reta, mask; + int i, j; + int idx, shift; + struct nfp_net_hw *hw = + NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + if (reta_size != NFP_NET_CFG_RSS_ITBL_SZ) { + PMD_DRV_LOG(ERR, "The size of hash lookup table configured " + "(%d) doesn't match the number hardware can supported " + "(%d)", reta_size, NFP_NET_CFG_RSS_ITBL_SZ); + return -EINVAL; + } + + /* + * Update Redirection Table. There are 128 8bit-entries which can be + * manage as 32 32bit-entries + */ + for (i = 0; i < reta_size; i += 4) { + /* Handling 4 RSS entries per loop */ + idx = i / RTE_RETA_GROUP_SIZE; + shift = i % RTE_RETA_GROUP_SIZE; + mask = (uint8_t)((reta_conf[idx].mask >> shift) & 0xF); + + if (!mask) + continue; + + reta = 0; + /* If all 4 entries were set, don't need read RETA register */ + if (mask != 0xF) + reta = nn_cfg_readl(hw, NFP_NET_CFG_RSS_ITBL + i); + + for (j = 0; j < 4; j++) { + if (!(mask & (0x1 << j))) + continue; + if (mask != 0xF) + /* Clearing the entry bits */ + reta &= ~(0xFF << (8 * j)); + reta |= reta_conf[idx].reta[shift + j] << (8 * j); + } + nn_cfg_writel(hw, NFP_NET_CFG_RSS_ITBL + (idx * 64) + shift, + reta); + } + return 0; +} + +/* Update Redirection Table(RETA) of Receive Side Scaling of Ethernet device */ +int +nfp_net_reta_update(struct rte_eth_dev *dev, + struct rte_eth_rss_reta_entry64 *reta_conf, + uint16_t reta_size) +{ + struct nfp_net_hw *hw = + NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + uint32_t update; + int ret; + + if (!(hw->ctrl & NFP_NET_CFG_CTRL_RSS)) + return -EINVAL; + + ret = nfp_net_rss_reta_write(dev, reta_conf, reta_size); + if (ret != 0) + return ret; + + update = NFP_NET_CFG_UPDATE_RSS; + + if (nfp_net_reconfig(hw, hw->ctrl, update) < 0) + return -EIO; + + return 0; +} + + /* Query Redirection Table(RETA) of Receive Side Scaling of Ethernet device. */ +int +nfp_net_reta_query(struct rte_eth_dev *dev, + struct rte_eth_rss_reta_entry64 *reta_conf, + uint16_t reta_size) +{ + uint8_t i, j, mask; + int idx, shift; + uint32_t reta; + struct nfp_net_hw *hw; + + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + if (!(hw->ctrl & NFP_NET_CFG_CTRL_RSS)) + return -EINVAL; + + if (reta_size != NFP_NET_CFG_RSS_ITBL_SZ) { + PMD_DRV_LOG(ERR, "The size of hash lookup table configured " + "(%d) doesn't match the number hardware can supported " + "(%d)", reta_size, NFP_NET_CFG_RSS_ITBL_SZ); + return -EINVAL; + } + + /* + * Reading Redirection Table. There are 128 8bit-entries which can be + * manage as 32 32bit-entries + */ + for (i = 0; i < reta_size; i += 4) { + /* Handling 4 RSS entries per loop */ + idx = i / RTE_RETA_GROUP_SIZE; + shift = i % RTE_RETA_GROUP_SIZE; + mask = (uint8_t)((reta_conf[idx].mask >> shift) & 0xF); + + if (!mask) + continue; + + reta = nn_cfg_readl(hw, NFP_NET_CFG_RSS_ITBL + (idx * 64) + + shift); + for (j = 0; j < 4; j++) { + if (!(mask & (0x1 << j))) + continue; + reta_conf[idx].reta[shift + j] = + (uint8_t)((reta >> (8 * j)) & 0xF); + } + } + return 0; +} + +static int +nfp_net_rss_hash_write(struct rte_eth_dev *dev, + struct rte_eth_rss_conf *rss_conf) +{ + struct nfp_net_hw *hw; + uint64_t rss_hf; + uint32_t cfg_rss_ctrl = 0; + uint8_t key; + int i; + + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + /* Writing the key byte a byte */ + for (i = 0; i < rss_conf->rss_key_len; i++) { + memcpy(&key, &rss_conf->rss_key[i], 1); + nn_cfg_writeb(hw, NFP_NET_CFG_RSS_KEY + i, key); + } + + rss_hf = rss_conf->rss_hf; + + if (rss_hf & ETH_RSS_IPV4) + cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV4; + + if (rss_hf & ETH_RSS_NONFRAG_IPV4_TCP) + cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV4_TCP; + + if (rss_hf & ETH_RSS_NONFRAG_IPV4_UDP) + cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV4_UDP; + + if (rss_hf & ETH_RSS_IPV6) + cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV6; + + if (rss_hf & ETH_RSS_NONFRAG_IPV6_TCP) + cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV6_TCP; + + if (rss_hf & ETH_RSS_NONFRAG_IPV6_UDP) + cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV6_UDP; + + cfg_rss_ctrl |= NFP_NET_CFG_RSS_MASK; + cfg_rss_ctrl |= NFP_NET_CFG_RSS_TOEPLITZ; + + /* configuring where to apply the RSS hash */ + nn_cfg_writel(hw, NFP_NET_CFG_RSS_CTRL, cfg_rss_ctrl); + + /* Writing the key size */ + nn_cfg_writeb(hw, NFP_NET_CFG_RSS_KEY_SZ, rss_conf->rss_key_len); + + return 0; +} + +int +nfp_net_rss_hash_update(struct rte_eth_dev *dev, + struct rte_eth_rss_conf *rss_conf) +{ + uint32_t update; + uint64_t rss_hf; + struct nfp_net_hw *hw; + + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + rss_hf = rss_conf->rss_hf; + + /* Checking if RSS is enabled */ + if (!(hw->ctrl & NFP_NET_CFG_CTRL_RSS)) { + if (rss_hf != 0) { /* Enable RSS? */ + PMD_DRV_LOG(ERR, "RSS unsupported"); + return -EINVAL; + } + return 0; /* Nothing to do */ + } + + if (rss_conf->rss_key_len > NFP_NET_CFG_RSS_KEY_SZ) { + PMD_DRV_LOG(ERR, "hash key too long"); + return -EINVAL; + } + + nfp_net_rss_hash_write(dev, rss_conf); + + update = NFP_NET_CFG_UPDATE_RSS; + + if (nfp_net_reconfig(hw, hw->ctrl, update) < 0) + return -EIO; + + return 0; +} + +int +nfp_net_rss_hash_conf_get(struct rte_eth_dev *dev, + struct rte_eth_rss_conf *rss_conf) +{ + uint64_t rss_hf; + uint32_t cfg_rss_ctrl; + uint8_t key; + int i; + struct nfp_net_hw *hw; + + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + if (!(hw->ctrl & NFP_NET_CFG_CTRL_RSS)) + return -EINVAL; + + rss_hf = rss_conf->rss_hf; + cfg_rss_ctrl = nn_cfg_readl(hw, NFP_NET_CFG_RSS_CTRL); + + if (cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV4) + rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_NONFRAG_IPV4_UDP; + + if (cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV4_TCP) + rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP; + + if (cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV6_TCP) + rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP; + + if (cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV4_UDP) + rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP; + + if (cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV6_UDP) + rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP; + + if (cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV6) + rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_NONFRAG_IPV6_UDP; + + /* Propagate current RSS hash functions to caller */ + rss_conf->rss_hf = rss_hf; + + /* Reading the key size */ + rss_conf->rss_key_len = nn_cfg_readl(hw, NFP_NET_CFG_RSS_KEY_SZ); + + /* Reading the key byte a byte */ + for (i = 0; i < rss_conf->rss_key_len; i++) { + key = nn_cfg_readb(hw, NFP_NET_CFG_RSS_KEY + i); + memcpy(&rss_conf->rss_key[i], &key, 1); + } + + return 0; +} + +int +nfp_net_rss_config_default(struct rte_eth_dev *dev) +{ + struct rte_eth_conf *dev_conf; + struct rte_eth_rss_conf rss_conf; + struct rte_eth_rss_reta_entry64 nfp_reta_conf[2]; + uint16_t rx_queues = dev->data->nb_rx_queues; + uint16_t queue; + int i, j, ret; + + PMD_DRV_LOG(INFO, "setting default RSS conf for %u queues", + rx_queues); + + nfp_reta_conf[0].mask = ~0x0; + nfp_reta_conf[1].mask = ~0x0; + + queue = 0; + for (i = 0; i < 0x40; i += 8) { + for (j = i; j < (i + 8); j++) { + nfp_reta_conf[0].reta[j] = queue; + nfp_reta_conf[1].reta[j] = queue++; + queue %= rx_queues; + } + } + ret = nfp_net_rss_reta_write(dev, nfp_reta_conf, 0x80); + if (ret != 0) + return ret; + + dev_conf = &dev->data->dev_conf; + if (!dev_conf) { + PMD_DRV_LOG(INFO, "wrong rss conf"); + return -EINVAL; + } + rss_conf = dev_conf->rx_adv_conf.rss_conf; + + ret = nfp_net_rss_hash_write(dev, &rss_conf); + + return ret; +} + +RTE_LOG_REGISTER_SUFFIX(nfp_logtype_init, init, NOTICE); +RTE_LOG_REGISTER_SUFFIX(nfp_logtype_driver, driver, NOTICE); +/* + * Local variables: + * c-file-style: "Linux" + * indent-tabs-mode: t + * End: + */ diff --git a/drivers/net/nfp/nfp_common.h b/drivers/net/nfp/nfp_common.h new file mode 100644 index 0000000000..1fbf3d7cd6 --- /dev/null +++ b/drivers/net/nfp/nfp_common.h @@ -0,0 +1,405 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2014-2018 Netronome Systems, Inc. + * All rights reserved. + */ + +/* + * vim:shiftwidth=8:noexpandtab + * + * @file dpdk/pmd/nfp_net_pmd.h + * + * Netronome NFP_NET PMD driver + */ + +#ifndef _NFP_COMMON_H_ +#define _NFP_COMMON_H_ + +#define NFP_NET_PMD_VERSION "0.1" +#define PCI_VENDOR_ID_NETRONOME 0x19ee +#define PCI_DEVICE_ID_NFP4000_PF_NIC 0x4000 +#define PCI_DEVICE_ID_NFP6000_PF_NIC 0x6000 +#define PCI_DEVICE_ID_NFP6000_VF_NIC 0x6003 + +/* Forward declaration */ +struct nfp_net_adapter; + +#define NFP_TX_MAX_SEG UINT8_MAX +#define NFP_TX_MAX_MTU_SEG 8 + +/* Bar allocation */ +#define NFP_NET_CRTL_BAR 0 +#define NFP_NET_TX_BAR 2 +#define NFP_NET_RX_BAR 2 +#define NFP_QCP_QUEUE_AREA_SZ 0x80000 + +/* Macros for accessing the Queue Controller Peripheral 'CSRs' */ +#define NFP_QCP_QUEUE_OFF(_x) ((_x) * 0x800) +#define NFP_QCP_QUEUE_ADD_RPTR 0x0000 +#define NFP_QCP_QUEUE_ADD_WPTR 0x0004 +#define NFP_QCP_QUEUE_STS_LO 0x0008 +#define NFP_QCP_QUEUE_STS_LO_READPTR_mask (0x3ffff) +#define NFP_QCP_QUEUE_STS_HI 0x000c +#define NFP_QCP_QUEUE_STS_HI_WRITEPTR_mask (0x3ffff) + +/* The offset of the queue controller queues in the PCIe Target */ +#define NFP_PCIE_QUEUE(_q) (0x80000 + (NFP_QCP_QUEUE_ADDR_SZ * ((_q) & 0xff))) + +/* Maximum value which can be added to a queue with one transaction */ +#define NFP_QCP_MAX_ADD 0x7f + +/* Interrupt definitions */ +#define NFP_NET_IRQ_LSC_IDX 0 + +/* Default values for RX/TX configuration */ +#define DEFAULT_RX_FREE_THRESH 32 +#define DEFAULT_RX_PTHRESH 8 +#define DEFAULT_RX_HTHRESH 8 +#define DEFAULT_RX_WTHRESH 0 + +#define DEFAULT_TX_RS_THRESH 32 +#define DEFAULT_TX_FREE_THRESH 32 +#define DEFAULT_TX_PTHRESH 32 +#define DEFAULT_TX_HTHRESH 0 +#define DEFAULT_TX_WTHRESH 0 +#define DEFAULT_TX_RSBIT_THRESH 32 + +/* Alignment for dma zones */ +#define NFP_MEMZONE_ALIGN 128 + +/* + * This is used by the reconfig protocol. It sets the maximum time waiting in + * milliseconds before a reconfig timeout happens. + */ +#define NFP_NET_POLL_TIMEOUT 5000 + +#define NFP_QCP_QUEUE_ADDR_SZ (0x800) + +#define NFP_NET_LINK_DOWN_CHECK_TIMEOUT 4000 /* ms */ +#define NFP_NET_LINK_UP_CHECK_TIMEOUT 1000 /* ms */ + +/* Version number helper defines */ +#define NFD_CFG_CLASS_VER_msk 0xff +#define NFD_CFG_CLASS_VER_shf 24 +#define NFD_CFG_CLASS_VER(x) (((x) & 0xff) << 24) +#define NFD_CFG_CLASS_VER_of(x) (((x) >> 24) & 0xff) +#define NFD_CFG_CLASS_TYPE_msk 0xff +#define NFD_CFG_CLASS_TYPE_shf 16 +#define NFD_CFG_CLASS_TYPE(x) (((x) & 0xff) << 16) +#define NFD_CFG_CLASS_TYPE_of(x) (((x) >> 16) & 0xff) +#define NFD_CFG_MAJOR_VERSION_msk 0xff +#define NFD_CFG_MAJOR_VERSION_shf 8 +#define NFD_CFG_MAJOR_VERSION(x) (((x) & 0xff) << 8) +#define NFD_CFG_MAJOR_VERSION_of(x) (((x) >> 8) & 0xff) +#define NFD_CFG_MINOR_VERSION_msk 0xff +#define NFD_CFG_MINOR_VERSION_shf 0 +#define NFD_CFG_MINOR_VERSION(x) (((x) & 0xff) << 0) +#define NFD_CFG_MINOR_VERSION_of(x) (((x) >> 0) & 0xff) + +/* Number of supported physical ports */ +#define NFP_MAX_PHYPORTS 12 + +#include +#include + +/* nfp_qcp_ptr - Read or Write Pointer of a queue */ +enum nfp_qcp_ptr { + NFP_QCP_READ_PTR = 0, + NFP_QCP_WRITE_PTR +}; + +struct nfp_pf_dev { + /* Backpointer to associated pci device */ + struct rte_pci_device *pci_dev; + + /* Array of physical ports belonging to this PF */ + struct nfp_net_hw *ports[NFP_MAX_PHYPORTS]; + + /* Current values for control */ + uint32_t ctrl; + + uint8_t *ctrl_bar; + uint8_t *tx_bar; + uint8_t *rx_bar; + + uint8_t *qcp_cfg; + rte_spinlock_t reconfig_lock; + + uint16_t flbufsz; + uint16_t device_id; + uint16_t vendor_id; + uint16_t subsystem_device_id; + uint16_t subsystem_vendor_id; +#if defined(DSTQ_SELECTION) +#if DSTQ_SELECTION + uint16_t device_function; +#endif +#endif + + struct nfp_cpp *cpp; + struct nfp_cpp_area *ctrl_area; + struct nfp_cpp_area *hwqueues_area; + struct nfp_cpp_area *msix_area; + + uint8_t *hw_queues; + uint8_t total_phyports; + bool multiport; + + union eth_table_entry *eth_table; + + struct nfp_hwinfo *hwinfo; + struct nfp_rtsym_table *sym_tbl; + uint32_t nfp_cpp_service_id; +}; + +struct nfp_net_hw { + /* Backpointer to the PF this port belongs to */ + struct nfp_pf_dev *pf_dev; + + /* Backpointer to the eth_dev of this port*/ + struct rte_eth_dev *eth_dev; + + /* Info from the firmware */ + uint32_t ver; + uint32_t cap; + uint32_t max_mtu; + uint32_t mtu; + uint32_t rx_offset; + + /* Current values for control */ + uint32_t ctrl; + + uint8_t *ctrl_bar; + uint8_t *tx_bar; + uint8_t *rx_bar; + + int stride_rx; + int stride_tx; + + uint8_t *qcp_cfg; + rte_spinlock_t reconfig_lock; + + uint32_t max_tx_queues; + uint32_t max_rx_queues; + uint16_t flbufsz; + uint16_t device_id; + uint16_t vendor_id; + uint16_t subsystem_device_id; + uint16_t subsystem_vendor_id; +#if defined(DSTQ_SELECTION) +#if DSTQ_SELECTION + uint16_t device_function; +#endif +#endif + + uint8_t mac_addr[RTE_ETHER_ADDR_LEN]; + + /* Records starting point for counters */ + struct rte_eth_stats eth_stats_base; + + struct nfp_cpp *cpp; + struct nfp_cpp_area *ctrl_area; + struct nfp_cpp_area *hwqueues_area; + struct nfp_cpp_area *msix_area; + + uint8_t *hw_queues; + /* Sequential physical port number */ + uint8_t idx; + /* Internal port number as seen from NFP */ + uint8_t nfp_idx; + bool is_phyport; + + union eth_table_entry *eth_table; + + uint32_t nfp_cpp_service_id; +}; + +struct nfp_net_adapter { + struct nfp_net_hw hw; +}; + +static inline uint8_t nn_readb(volatile const void *addr) +{ + return rte_read8(addr); +} + +static inline void nn_writeb(uint8_t val, volatile void *addr) +{ + rte_write8(val, addr); +} + +static inline uint32_t nn_readl(volatile const void *addr) +{ + return rte_read32(addr); +} + +static inline void nn_writel(uint32_t val, volatile void *addr) +{ + rte_write32(val, addr); +} + +static inline void nn_writew(uint16_t val, volatile void *addr) +{ + rte_write16(val, addr); +} + +static inline uint64_t nn_readq(volatile void *addr) +{ + const volatile uint32_t *p = addr; + uint32_t low, high; + + high = nn_readl((volatile const void *)(p + 1)); + low = nn_readl((volatile const void *)p); + + return low + ((uint64_t)high << 32); +} + +static inline void nn_writeq(uint64_t val, volatile void *addr) +{ + nn_writel(val >> 32, (volatile char *)addr + 4); + nn_writel(val, addr); +} + +/* + * Functions to read/write from/to Config BAR + * Performs any endian conversion necessary. + */ +static inline uint8_t +nn_cfg_readb(struct nfp_net_hw *hw, int off) +{ + return nn_readb(hw->ctrl_bar + off); +} + +static inline void +nn_cfg_writeb(struct nfp_net_hw *hw, int off, uint8_t val) +{ + nn_writeb(val, hw->ctrl_bar + off); +} + +static inline uint32_t +nn_cfg_readl(struct nfp_net_hw *hw, int off) +{ + return rte_le_to_cpu_32(nn_readl(hw->ctrl_bar + off)); +} + +static inline void +nn_cfg_writel(struct nfp_net_hw *hw, int off, uint32_t val) +{ + nn_writel(rte_cpu_to_le_32(val), hw->ctrl_bar + off); +} + +static inline uint64_t +nn_cfg_readq(struct nfp_net_hw *hw, int off) +{ + return rte_le_to_cpu_64(nn_readq(hw->ctrl_bar + off)); +} + +static inline void +nn_cfg_writeq(struct nfp_net_hw *hw, int off, uint64_t val) +{ + nn_writeq(rte_cpu_to_le_64(val), hw->ctrl_bar + off); +} + +/* + * nfp_qcp_ptr_add - Add the value to the selected pointer of a queue + * @q: Base address for queue structure + * @ptr: Add to the Read or Write pointer + * @val: Value to add to the queue pointer + * + * If @val is greater than @NFP_QCP_MAX_ADD multiple writes are performed. + */ +static inline void +nfp_qcp_ptr_add(uint8_t *q, enum nfp_qcp_ptr ptr, uint32_t val) +{ + uint32_t off; + + if (ptr == NFP_QCP_READ_PTR) + off = NFP_QCP_QUEUE_ADD_RPTR; + else + off = NFP_QCP_QUEUE_ADD_WPTR; + + while (val > NFP_QCP_MAX_ADD) { + nn_writel(rte_cpu_to_le_32(NFP_QCP_MAX_ADD), q + off); + val -= NFP_QCP_MAX_ADD; +} + +nn_writel(rte_cpu_to_le_32(val), q + off); +} + +/* + * nfp_qcp_read - Read the current Read/Write pointer value for a queue + * @q: Base address for queue structure + * @ptr: Read or Write pointer + */ +static inline uint32_t +nfp_qcp_read(uint8_t *q, enum nfp_qcp_ptr ptr) +{ + uint32_t off; + uint32_t val; + + if (ptr == NFP_QCP_READ_PTR) + off = NFP_QCP_QUEUE_STS_LO; + else + off = NFP_QCP_QUEUE_STS_HI; + + val = rte_cpu_to_le_32(nn_readl(q + off)); + + if (ptr == NFP_QCP_READ_PTR) + return val & NFP_QCP_QUEUE_STS_LO_READPTR_mask; + else + return val & NFP_QCP_QUEUE_STS_HI_WRITEPTR_mask; +} + +/* Prototypes for common NFP functions */ +int nfp_net_reconfig(struct nfp_net_hw *hw, uint32_t ctrl, uint32_t update); +int nfp_net_configure(struct rte_eth_dev *dev); +void nfp_net_enable_queues(struct rte_eth_dev *dev); +void nfp_net_disable_queues(struct rte_eth_dev *dev); +void nfp_net_params_setup(struct nfp_net_hw *hw); +void nfp_eth_copy_mac(uint8_t *dst, const uint8_t *src); +void nfp_net_write_mac(struct nfp_net_hw *hw, uint8_t *mac); +int nfp_set_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr); +int nfp_configure_rx_interrupt(struct rte_eth_dev *dev, + struct rte_intr_handle *intr_handle); +uint32_t nfp_check_offloads(struct rte_eth_dev *dev); +int nfp_net_promisc_enable(struct rte_eth_dev *dev); +int nfp_net_promisc_disable(struct rte_eth_dev *dev); +int nfp_net_link_update(struct rte_eth_dev *dev, + __rte_unused int wait_to_complete); +int nfp_net_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats); +int nfp_net_stats_reset(struct rte_eth_dev *dev); +int nfp_net_infos_get(struct rte_eth_dev *dev, + struct rte_eth_dev_info *dev_info); +const uint32_t *nfp_net_supported_ptypes_get(struct rte_eth_dev *dev); +int nfp_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id); +int nfp_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id); +void nfp_net_params_setup(struct nfp_net_hw *hw); +void nfp_net_cfg_queue_setup(struct nfp_net_hw *hw); +void nfp_eth_copy_mac(uint8_t *dst, const uint8_t *src); +void nfp_net_dev_interrupt_handler(void *param); +int nfp_net_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu); +int nfp_net_vlan_offload_set(struct rte_eth_dev *dev, int mask); +int nfp_net_reta_update(struct rte_eth_dev *dev, + struct rte_eth_rss_reta_entry64 *reta_conf, + uint16_t reta_size); +int nfp_net_reta_query(struct rte_eth_dev *dev, + struct rte_eth_rss_reta_entry64 *reta_conf, + uint16_t reta_size); +int nfp_net_rss_hash_update(struct rte_eth_dev *dev, + struct rte_eth_rss_conf *rss_conf); +int nfp_net_rss_hash_conf_get(struct rte_eth_dev *dev, + struct rte_eth_rss_conf *rss_conf); +int nfp_net_rss_config_default(struct rte_eth_dev *dev); + +#define NFP_NET_DEV_PRIVATE_TO_HW(adapter)\ + (&((struct nfp_net_adapter *)adapter)->hw) + +#define NFP_NET_DEV_PRIVATE_TO_PF(dev_priv)\ + (((struct nfp_net_hw *)dev_priv)->pf_dev) + +#endif /* _NFP_COMMON_H_ */ +/* + * Local variables: + * c-file-style: "Linux" + * indent-tabs-mode: t + * End: + */ diff --git a/drivers/net/nfp/nfp_cpp_bridge.c b/drivers/net/nfp/nfp_cpp_bridge.c index d916793338..74a0eacb3f 100644 --- a/drivers/net/nfp/nfp_cpp_bridge.c +++ b/drivers/net/nfp/nfp_cpp_bridge.c @@ -19,7 +19,7 @@ #include "nfpcore/nfp_mip.h" #include "nfpcore/nfp_nsp.h" -#include "nfp_net_logs.h" +#include "nfp_logs.h" #include "nfp_cpp_bridge.h" #include diff --git a/drivers/net/nfp/nfp_ctrl.h b/drivers/net/nfp/nfp_ctrl.h new file mode 100644 index 0000000000..4dd62ef194 --- /dev/null +++ b/drivers/net/nfp/nfp_ctrl.h @@ -0,0 +1,326 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2014, 2015 Netronome Systems, Inc. + * All rights reserved. + */ + +/* + * vim:shiftwidth=8:noexpandtab + * + * Netronome network device driver: Control BAR layout + */ +#ifndef _NFP_CTRL_H_ +#define _NFP_CTRL_H_ + +/* + * Configuration BAR size. + * + * The configuration BAR is 8K in size, but on the NFP6000, due to + * THB-350, 32k needs to be reserved. + */ +#ifdef __NFP_IS_6000 +#define NFP_NET_CFG_BAR_SZ (32 * 1024) +#else +#define NFP_NET_CFG_BAR_SZ (8 * 1024) +#endif + +/* Offset in Freelist buffer where packet starts on RX */ +#define NFP_NET_RX_OFFSET 32 + +/* working with metadata api (NFD version > 3.0) */ +#define NFP_NET_META_FIELD_SIZE 4 +#define NFP_NET_META_FIELD_MASK ((1 << NFP_NET_META_FIELD_SIZE) - 1) + +/* Prepend field types */ +#define NFP_NET_META_HASH 1 /* next field carries hash type */ + +/* Hash type pre-pended when a RSS hash was computed */ +#define NFP_NET_RSS_NONE 0 +#define NFP_NET_RSS_IPV4 1 +#define NFP_NET_RSS_IPV6 2 +#define NFP_NET_RSS_IPV6_EX 3 +#define NFP_NET_RSS_IPV4_TCP 4 +#define NFP_NET_RSS_IPV6_TCP 5 +#define NFP_NET_RSS_IPV6_EX_TCP 6 +#define NFP_NET_RSS_IPV4_UDP 7 +#define NFP_NET_RSS_IPV6_UDP 8 +#define NFP_NET_RSS_IPV6_EX_UDP 9 + +/* + * @NFP_NET_TXR_MAX: Maximum number of TX rings + * @NFP_NET_TXR_MASK: Mask for TX rings + * @NFP_NET_RXR_MAX: Maximum number of RX rings + * @NFP_NET_RXR_MASK: Mask for RX rings + */ +#define NFP_NET_TXR_MAX 64 +#define NFP_NET_TXR_MASK (NFP_NET_TXR_MAX - 1) +#define NFP_NET_RXR_MAX 64 +#define NFP_NET_RXR_MASK (NFP_NET_RXR_MAX - 1) + +/* + * Read/Write config words (0x0000 - 0x002c) + * @NFP_NET_CFG_CTRL: Global control + * @NFP_NET_CFG_UPDATE: Indicate which fields are updated + * @NFP_NET_CFG_TXRS_ENABLE: Bitmask of enabled TX rings + * @NFP_NET_CFG_RXRS_ENABLE: Bitmask of enabled RX rings + * @NFP_NET_CFG_MTU: Set MTU size + * @NFP_NET_CFG_FLBUFSZ: Set freelist buffer size (must be larger than MTU) + * @NFP_NET_CFG_EXN: MSI-X table entry for exceptions + * @NFP_NET_CFG_LSC: MSI-X table entry for link state changes + * @NFP_NET_CFG_MACADDR: MAC address + * + * TODO: + * - define Error details in UPDATE + */ +#define NFP_NET_CFG_CTRL 0x0000 +#define NFP_NET_CFG_CTRL_ENABLE (0x1 << 0) /* Global enable */ +#define NFP_NET_CFG_CTRL_PROMISC (0x1 << 1) /* Enable Promisc mode */ +#define NFP_NET_CFG_CTRL_L2BC (0x1 << 2) /* Allow L2 Broadcast */ +#define NFP_NET_CFG_CTRL_L2MC (0x1 << 3) /* Allow L2 Multicast */ +#define NFP_NET_CFG_CTRL_RXCSUM (0x1 << 4) /* Enable RX Checksum */ +#define NFP_NET_CFG_CTRL_TXCSUM (0x1 << 5) /* Enable TX Checksum */ +#define NFP_NET_CFG_CTRL_RXVLAN (0x1 << 6) /* Enable VLAN strip */ +#define NFP_NET_CFG_CTRL_TXVLAN (0x1 << 7) /* Enable VLAN insert */ +#define NFP_NET_CFG_CTRL_SCATTER (0x1 << 8) /* Scatter DMA */ +#define NFP_NET_CFG_CTRL_GATHER (0x1 << 9) /* Gather DMA */ +#define NFP_NET_CFG_CTRL_LSO (0x1 << 10) /* LSO/TSO */ +#define NFP_NET_CFG_CTRL_RINGCFG (0x1 << 16) /* Ring runtime changes */ +#define NFP_NET_CFG_CTRL_RSS (0x1 << 17) /* RSS */ +#define NFP_NET_CFG_CTRL_IRQMOD (0x1 << 18) /* Interrupt moderation */ +#define NFP_NET_CFG_CTRL_RINGPRIO (0x1 << 19) /* Ring priorities */ +#define NFP_NET_CFG_CTRL_MSIXAUTO (0x1 << 20) /* MSI-X auto-masking */ +#define NFP_NET_CFG_CTRL_TXRWB (0x1 << 21) /* Write-back of TX ring*/ +#define NFP_NET_CFG_CTRL_L2SWITCH (0x1 << 22) /* L2 Switch */ +#define NFP_NET_CFG_CTRL_L2SWITCH_LOCAL (0x1 << 23) /* Switch to local */ +#define NFP_NET_CFG_CTRL_VXLAN (0x1 << 24) /* Enable VXLAN */ +#define NFP_NET_CFG_CTRL_NVGRE (0x1 << 25) /* Enable NVGRE */ +#define NFP_NET_CFG_CTRL_MSIX_TX_OFF (0x1 << 26) /* Disable MSIX for TX */ +#define NFP_NET_CFG_CTRL_LSO2 (0x1 << 28) /* LSO/TSO (version 2) */ +#define NFP_NET_CFG_CTRL_RSS2 (0x1 << 29) /* RSS (version 2) */ +#define NFP_NET_CFG_CTRL_LIVE_ADDR (0x1U << 31)/* live MAC addr change */ +#define NFP_NET_CFG_UPDATE 0x0004 +#define NFP_NET_CFG_UPDATE_GEN (0x1 << 0) /* General update */ +#define NFP_NET_CFG_UPDATE_RING (0x1 << 1) /* Ring config change */ +#define NFP_NET_CFG_UPDATE_RSS (0x1 << 2) /* RSS config change */ +#define NFP_NET_CFG_UPDATE_TXRPRIO (0x1 << 3) /* TX Ring prio change */ +#define NFP_NET_CFG_UPDATE_RXRPRIO (0x1 << 4) /* RX Ring prio change */ +#define NFP_NET_CFG_UPDATE_MSIX (0x1 << 5) /* MSI-X change */ +#define NFP_NET_CFG_UPDATE_L2SWITCH (0x1 << 6) /* Switch changes */ +#define NFP_NET_CFG_UPDATE_RESET (0x1 << 7) /* Update due to FLR */ +#define NFP_NET_CFG_UPDATE_IRQMOD (0x1 << 8) /* IRQ mod change */ +#define NFP_NET_CFG_UPDATE_VXLAN (0x1 << 9) /* VXLAN port change */ +#define NFP_NET_CFG_UPDATE_MACADDR (0x1 << 11) /* MAC address change */ +#define NFP_NET_CFG_UPDATE_ERR (0x1U << 31) /* A error occurred */ +#define NFP_NET_CFG_TXRS_ENABLE 0x0008 +#define NFP_NET_CFG_RXRS_ENABLE 0x0010 +#define NFP_NET_CFG_MTU 0x0018 +#define NFP_NET_CFG_FLBUFSZ 0x001c +#define NFP_NET_CFG_EXN 0x001f +#define NFP_NET_CFG_LSC 0x0020 +#define NFP_NET_CFG_MACADDR 0x0024 + +#define NFP_NET_CFG_CTRL_LSO_ANY (NFP_NET_CFG_CTRL_LSO | NFP_NET_CFG_CTRL_LSO2) + +/* + * Read-only words (0x0030 - 0x0050): + * @NFP_NET_CFG_VERSION: Firmware version number + * @NFP_NET_CFG_STS: Status + * @NFP_NET_CFG_CAP: Capabilities (same bits as @NFP_NET_CFG_CTRL) + * @NFP_NET_MAX_TXRINGS: Maximum number of TX rings + * @NFP_NET_MAX_RXRINGS: Maximum number of RX rings + * @NFP_NET_MAX_MTU: Maximum support MTU + * @NFP_NET_CFG_START_TXQ: Start Queue Control Queue to use for TX (PF only) + * @NFP_NET_CFG_START_RXQ: Start Queue Control Queue to use for RX (PF only) + * + * TODO: + * - define more STS bits + */ +#define NFP_NET_CFG_VERSION 0x0030 +#define NFP_NET_CFG_VERSION_RESERVED_MASK (0xff << 24) +#define NFP_NET_CFG_VERSION_CLASS_MASK (0xff << 16) +#define NFP_NET_CFG_VERSION_CLASS(x) (((x) & 0xff) << 16) +#define NFP_NET_CFG_VERSION_CLASS_GENERIC 0 +#define NFP_NET_CFG_VERSION_MAJOR_MASK (0xff << 8) +#define NFP_NET_CFG_VERSION_MAJOR(x) (((x) & 0xff) << 8) +#define NFP_NET_CFG_VERSION_MINOR_MASK (0xff << 0) +#define NFP_NET_CFG_VERSION_MINOR(x) (((x) & 0xff) << 0) +#define NFP_NET_CFG_STS 0x0034 +#define NFP_NET_CFG_STS_LINK (0x1 << 0) /* Link up or down */ +/* Link rate */ +#define NFP_NET_CFG_STS_LINK_RATE_SHIFT 1 +#define NFP_NET_CFG_STS_LINK_RATE_MASK 0xF +#define NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED 0 +#define NFP_NET_CFG_STS_LINK_RATE_UNKNOWN 1 +#define NFP_NET_CFG_STS_LINK_RATE_1G 2 +#define NFP_NET_CFG_STS_LINK_RATE_10G 3 +#define NFP_NET_CFG_STS_LINK_RATE_25G 4 +#define NFP_NET_CFG_STS_LINK_RATE_40G 5 +#define NFP_NET_CFG_STS_LINK_RATE_50G 6 +#define NFP_NET_CFG_STS_LINK_RATE_100G 7 +#define NFP_NET_CFG_CAP 0x0038 +#define NFP_NET_CFG_MAX_TXRINGS 0x003c +#define NFP_NET_CFG_MAX_RXRINGS 0x0040 +#define NFP_NET_CFG_MAX_MTU 0x0044 +/* Next two words are being used by VFs for solving THB350 issue */ +#define NFP_NET_CFG_START_TXQ 0x0048 +#define NFP_NET_CFG_START_RXQ 0x004c + +/* + * NFP-3200 workaround (0x0050 - 0x0058) + * @NFP_NET_CFG_SPARE_ADDR: DMA address for ME code to use (e.g. YDS-155 fix) + */ +#define NFP_NET_CFG_SPARE_ADDR 0x0050 +/** + * NFP6000/NFP4000 - Prepend configuration + */ +#define NFP_NET_CFG_RX_OFFSET 0x0050 +#define NFP_NET_CFG_RX_OFFSET_DYNAMIC 0 /* Prepend mode */ + +/** + * Reuse spare address to contain the offset from the start of + * the host buffer where the first byte of the received frame + * will land. Any metadata will come prior to that offset. If the + * value in this field is 0, it means that that the metadata will + * always land starting at the first byte of the host buffer and + * packet data will immediately follow the metadata. As always, + * the RX descriptor indicates the presence or absence of metadata + * along with the length thereof. + */ +#define NFP_NET_CFG_RX_OFFSET_ADDR 0x0050 + +#define NFP_NET_CFG_VXLAN_PORT 0x0060 +#define NFP_NET_CFG_VXLAN_SZ 0x0008 + +/* Offload definitions */ +#define NFP_NET_N_VXLAN_PORTS (NFP_NET_CFG_VXLAN_SZ / sizeof(uint16_t)) + +/** + * 64B reserved for future use (0x0080 - 0x00c0) + */ +#define NFP_NET_CFG_RESERVED 0x0080 +#define NFP_NET_CFG_RESERVED_SZ 0x0040 + +/* + * RSS configuration (0x0100 - 0x01ac): + * Used only when NFP_NET_CFG_CTRL_RSS is enabled + * @NFP_NET_CFG_RSS_CFG: RSS configuration word + * @NFP_NET_CFG_RSS_KEY: RSS "secret" key + * @NFP_NET_CFG_RSS_ITBL: RSS indirection table + */ +#define NFP_NET_CFG_RSS_BASE 0x0100 +#define NFP_NET_CFG_RSS_CTRL NFP_NET_CFG_RSS_BASE +#define NFP_NET_CFG_RSS_MASK (0x7f) +#define NFP_NET_CFG_RSS_MASK_of(_x) ((_x) & 0x7f) +#define NFP_NET_CFG_RSS_IPV4 (1 << 8) /* RSS for IPv4 */ +#define NFP_NET_CFG_RSS_IPV6 (1 << 9) /* RSS for IPv6 */ +#define NFP_NET_CFG_RSS_IPV4_TCP (1 << 10) /* RSS for IPv4/TCP */ +#define NFP_NET_CFG_RSS_IPV4_UDP (1 << 11) /* RSS for IPv4/UDP */ +#define NFP_NET_CFG_RSS_IPV6_TCP (1 << 12) /* RSS for IPv6/TCP */ +#define NFP_NET_CFG_RSS_IPV6_UDP (1 << 13) /* RSS for IPv6/UDP */ +#define NFP_NET_CFG_RSS_TOEPLITZ (1 << 24) /* Use Toeplitz hash */ +#define NFP_NET_CFG_RSS_KEY (NFP_NET_CFG_RSS_BASE + 0x4) +#define NFP_NET_CFG_RSS_KEY_SZ 0x28 +#define NFP_NET_CFG_RSS_ITBL (NFP_NET_CFG_RSS_BASE + 0x4 + \ + NFP_NET_CFG_RSS_KEY_SZ) +#define NFP_NET_CFG_RSS_ITBL_SZ 0x80 + +/* + * TX ring configuration (0x200 - 0x800) + * @NFP_NET_CFG_TXR_BASE: Base offset for TX ring configuration + * @NFP_NET_CFG_TXR_ADDR: Per TX ring DMA address (8B entries) + * @NFP_NET_CFG_TXR_WB_ADDR: Per TX ring write back DMA address (8B entries) + * @NFP_NET_CFG_TXR_SZ: Per TX ring ring size (1B entries) + * @NFP_NET_CFG_TXR_VEC: Per TX ring MSI-X table entry (1B entries) + * @NFP_NET_CFG_TXR_PRIO: Per TX ring priority (1B entries) + * @NFP_NET_CFG_TXR_IRQ_MOD: Per TX ring interrupt moderation (4B entries) + */ +#define NFP_NET_CFG_TXR_BASE 0x0200 +#define NFP_NET_CFG_TXR_ADDR(_x) (NFP_NET_CFG_TXR_BASE + ((_x) * 0x8)) +#define NFP_NET_CFG_TXR_WB_ADDR(_x) (NFP_NET_CFG_TXR_BASE + 0x200 + \ + ((_x) * 0x8)) +#define NFP_NET_CFG_TXR_SZ(_x) (NFP_NET_CFG_TXR_BASE + 0x400 + (_x)) +#define NFP_NET_CFG_TXR_VEC(_x) (NFP_NET_CFG_TXR_BASE + 0x440 + (_x)) +#define NFP_NET_CFG_TXR_PRIO(_x) (NFP_NET_CFG_TXR_BASE + 0x480 + (_x)) +#define NFP_NET_CFG_TXR_IRQ_MOD(_x) (NFP_NET_CFG_TXR_BASE + 0x500 + \ + ((_x) * 0x4)) + +/* + * RX ring configuration (0x0800 - 0x0c00) + * @NFP_NET_CFG_RXR_BASE: Base offset for RX ring configuration + * @NFP_NET_CFG_RXR_ADDR: Per TX ring DMA address (8B entries) + * @NFP_NET_CFG_RXR_SZ: Per TX ring ring size (1B entries) + * @NFP_NET_CFG_RXR_VEC: Per TX ring MSI-X table entry (1B entries) + * @NFP_NET_CFG_RXR_PRIO: Per TX ring priority (1B entries) + * @NFP_NET_CFG_RXR_IRQ_MOD: Per TX ring interrupt moderation (4B entries) + */ +#define NFP_NET_CFG_RXR_BASE 0x0800 +#define NFP_NET_CFG_RXR_ADDR(_x) (NFP_NET_CFG_RXR_BASE + ((_x) * 0x8)) +#define NFP_NET_CFG_RXR_SZ(_x) (NFP_NET_CFG_RXR_BASE + 0x200 + (_x)) +#define NFP_NET_CFG_RXR_VEC(_x) (NFP_NET_CFG_RXR_BASE + 0x240 + (_x)) +#define NFP_NET_CFG_RXR_PRIO(_x) (NFP_NET_CFG_RXR_BASE + 0x280 + (_x)) +#define NFP_NET_CFG_RXR_IRQ_MOD(_x) (NFP_NET_CFG_RXR_BASE + 0x300 + \ + ((_x) * 0x4)) + +/* + * Interrupt Control/Cause registers (0x0c00 - 0x0d00) + * These registers are only used when MSI-X auto-masking is not + * enabled (@NFP_NET_CFG_CTRL_MSIXAUTO not set). The array is index + * by MSI-X entry and are 1B in size. If an entry is zero, the + * corresponding entry is enabled. If the FW generates an interrupt, + * it writes a cause into the corresponding field. This also masks + * the MSI-X entry and the host driver must clear the register to + * re-enable the interrupt. + */ +#define NFP_NET_CFG_ICR_BASE 0x0c00 +#define NFP_NET_CFG_ICR(_x) (NFP_NET_CFG_ICR_BASE + (_x)) +#define NFP_NET_CFG_ICR_UNMASKED 0x0 +#define NFP_NET_CFG_ICR_RXTX 0x1 +#define NFP_NET_CFG_ICR_LSC 0x2 + +/* + * General device stats (0x0d00 - 0x0d90) + * all counters are 64bit. + */ +#define NFP_NET_CFG_STATS_BASE 0x0d00 +#define NFP_NET_CFG_STATS_RX_DISCARDS (NFP_NET_CFG_STATS_BASE + 0x00) +#define NFP_NET_CFG_STATS_RX_ERRORS (NFP_NET_CFG_STATS_BASE + 0x08) +#define NFP_NET_CFG_STATS_RX_OCTETS (NFP_NET_CFG_STATS_BASE + 0x10) +#define NFP_NET_CFG_STATS_RX_UC_OCTETS (NFP_NET_CFG_STATS_BASE + 0x18) +#define NFP_NET_CFG_STATS_RX_MC_OCTETS (NFP_NET_CFG_STATS_BASE + 0x20) +#define NFP_NET_CFG_STATS_RX_BC_OCTETS (NFP_NET_CFG_STATS_BASE + 0x28) +#define NFP_NET_CFG_STATS_RX_FRAMES (NFP_NET_CFG_STATS_BASE + 0x30) +#define NFP_NET_CFG_STATS_RX_MC_FRAMES (NFP_NET_CFG_STATS_BASE + 0x38) +#define NFP_NET_CFG_STATS_RX_BC_FRAMES (NFP_NET_CFG_STATS_BASE + 0x40) + +#define NFP_NET_CFG_STATS_TX_DISCARDS (NFP_NET_CFG_STATS_BASE + 0x48) +#define NFP_NET_CFG_STATS_TX_ERRORS (NFP_NET_CFG_STATS_BASE + 0x50) +#define NFP_NET_CFG_STATS_TX_OCTETS (NFP_NET_CFG_STATS_BASE + 0x58) +#define NFP_NET_CFG_STATS_TX_UC_OCTETS (NFP_NET_CFG_STATS_BASE + 0x60) +#define NFP_NET_CFG_STATS_TX_MC_OCTETS (NFP_NET_CFG_STATS_BASE + 0x68) +#define NFP_NET_CFG_STATS_TX_BC_OCTETS (NFP_NET_CFG_STATS_BASE + 0x70) +#define NFP_NET_CFG_STATS_TX_FRAMES (NFP_NET_CFG_STATS_BASE + 0x78) +#define NFP_NET_CFG_STATS_TX_MC_FRAMES (NFP_NET_CFG_STATS_BASE + 0x80) +#define NFP_NET_CFG_STATS_TX_BC_FRAMES (NFP_NET_CFG_STATS_BASE + 0x88) + +/* + * Per ring stats (0x1000 - 0x1800) + * options, 64bit per entry + * @NFP_NET_CFG_TXR_STATS: TX ring statistics (Packet and Byte count) + * @NFP_NET_CFG_RXR_STATS: RX ring statistics (Packet and Byte count) + */ +#define NFP_NET_CFG_TXR_STATS_BASE 0x1000 +#define NFP_NET_CFG_TXR_STATS(_x) (NFP_NET_CFG_TXR_STATS_BASE + \ + ((_x) * 0x10)) +#define NFP_NET_CFG_RXR_STATS_BASE 0x1400 +#define NFP_NET_CFG_RXR_STATS(_x) (NFP_NET_CFG_RXR_STATS_BASE + \ + ((_x) * 0x10)) + +/* PF multiport offset */ +#define NFP_PF_CSR_SLICE_SIZE (32 * 1024) + +#endif /* _NFP_CTRL_H_ */ +/* + * Local variables: + * c-file-style: "Linux" + * indent-tabs-mode: t + * End: + */ diff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c index 8b6e641eeb..534a38c14f 100644 --- a/drivers/net/nfp/nfp_ethdev.c +++ b/drivers/net/nfp/nfp_ethdev.c @@ -31,10 +31,10 @@ #include "nfpcore/nfp_rtsym.h" #include "nfpcore/nfp_nsp.h" -#include "nfp_net_pmd.h" +#include "nfp_common.h" #include "nfp_rxtx.h" -#include "nfp_net_logs.h" -#include "nfp_net_ctrl.h" +#include "nfp_logs.h" +#include "nfp_ctrl.h" #include "nfp_cpp_bridge.h" diff --git a/drivers/net/nfp/nfp_ethdev_vf.c b/drivers/net/nfp/nfp_ethdev_vf.c index 223142c0ed..b697b55865 100644 --- a/drivers/net/nfp/nfp_ethdev_vf.c +++ b/drivers/net/nfp/nfp_ethdev_vf.c @@ -16,10 +16,10 @@ #include "nfpcore/nfp_mip.h" #include "nfpcore/nfp_rtsym.h" -#include "nfp_net_pmd.h" +#include "nfp_common.h" #include "nfp_rxtx.h" -#include "nfp_net_logs.h" -#include "nfp_net_ctrl.h" +#include "nfp_logs.h" +#include "nfp_ctrl.h" static void nfp_netvf_read_mac(struct nfp_net_hw *hw); static int nfp_netvf_start(struct rte_eth_dev *dev); diff --git a/drivers/net/nfp/nfp_logs.h b/drivers/net/nfp/nfp_logs.h new file mode 100644 index 0000000000..cc49a1583e --- /dev/null +++ b/drivers/net/nfp/nfp_logs.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2014, 2015 Netronome Systems, Inc. + * All rights reserved. + */ + +#ifndef _NFP_LOGS_H_ +#define _NFP_LOGS_H_ + +#include + +extern int nfp_logtype_init; +#define PMD_INIT_LOG(level, fmt, args...) \ + rte_log(RTE_LOG_ ## level, nfp_logtype_init, \ + "%s(): " fmt "\n", __func__, ## args) +#define PMD_INIT_FUNC_TRACE() PMD_INIT_LOG(DEBUG, " >>") + +#ifdef RTE_LIBRTE_NFP_NET_DEBUG_RX +#define PMD_RX_LOG(level, fmt, args...) \ + RTE_LOG(level, PMD, "%s() rx: " fmt "\n", __func__, ## args) +#else +#define PMD_RX_LOG(level, fmt, args...) do { } while (0) +#endif + +#ifdef RTE_LIBRTE_NFP_NET_DEBUG_TX +#define PMD_TX_LOG(level, fmt, args...) \ + RTE_LOG(level, PMD, "%s() tx: " fmt "\n", __func__, ## args) +#define ASSERT(x) if (!(x)) rte_panic("NFP_NET: x") +#else +#define PMD_TX_LOG(level, fmt, args...) do { } while (0) +#define ASSERT(x) do { } while (0) +#endif + +#define PMD_CPP_LOG(level, fmt, args...) do { } while (0) + +extern int nfp_logtype_driver; +#define PMD_DRV_LOG(level, fmt, args...) \ + rte_log(RTE_LOG_ ## level, nfp_logtype_driver, \ + "%s(): " fmt "\n", __func__, ## args) + +#endif /* _NFP_LOGS_H_ */ diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c deleted file mode 100644 index 04288a3376..0000000000 --- a/drivers/net/nfp/nfp_net.c +++ /dev/null @@ -1,1322 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright (c) 2014-2018 Netronome Systems, Inc. - * All rights reserved. - * - * Small portions derived from code Copyright(c) 2010-2015 Intel Corporation. - */ - -/* - * vim:shiftwidth=8:noexpandtab - * - * @file dpdk/pmd/nfp_net.c - * - * Netronome vNIC DPDK Poll-Mode Driver: Main entry point - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "nfpcore/nfp_cpp.h" -#include "nfpcore/nfp_nffw.h" -#include "nfpcore/nfp_hwinfo.h" -#include "nfpcore/nfp_mip.h" -#include "nfpcore/nfp_rtsym.h" -#include "nfpcore/nfp_nsp.h" - -#include "nfp_common.h" -#include "nfp_rxtx.h" -#include "nfp_logs.h" -#include "nfp_ctrl.h" -#include "nfp_cpp_bridge.h" - -#include -#include -#include -#include -#include -#include -#include - -static int -__nfp_net_reconfig(struct nfp_net_hw *hw, uint32_t update) -{ - int cnt; - uint32_t new; - struct timespec wait; - - PMD_DRV_LOG(DEBUG, "Writing to the configuration queue (%p)...", - hw->qcp_cfg); - - if (hw->qcp_cfg == NULL) - rte_panic("Bad configuration queue pointer\n"); - - nfp_qcp_ptr_add(hw->qcp_cfg, NFP_QCP_WRITE_PTR, 1); - - wait.tv_sec = 0; - wait.tv_nsec = 1000000; - - PMD_DRV_LOG(DEBUG, "Polling for update ack..."); - - /* Poll update field, waiting for NFP to ack the config */ - for (cnt = 0; ; cnt++) { - new = nn_cfg_readl(hw, NFP_NET_CFG_UPDATE); - if (new == 0) - break; - if (new & NFP_NET_CFG_UPDATE_ERR) { - PMD_INIT_LOG(ERR, "Reconfig error: 0x%08x", new); - return -1; - } - if (cnt >= NFP_NET_POLL_TIMEOUT) { - PMD_INIT_LOG(ERR, "Reconfig timeout for 0x%08x after" - " %dms", update, cnt); - rte_panic("Exiting\n"); - } - nanosleep(&wait, 0); /* waiting for a 1ms */ - } - PMD_DRV_LOG(DEBUG, "Ack DONE"); - return 0; -} - -/* - * Reconfigure the NIC - * @nn: device to reconfigure - * @ctrl: The value for the ctrl field in the BAR config - * @update: The value for the update field in the BAR config - * - * Write the update word to the BAR and ping the reconfig queue. Then poll - * until the firmware has acknowledged the update by zeroing the update word. - */ -int -nfp_net_reconfig(struct nfp_net_hw *hw, uint32_t ctrl, uint32_t update) -{ - uint32_t err; - - PMD_DRV_LOG(DEBUG, "nfp_net_reconfig: ctrl=%08x update=%08x", - ctrl, update); - - rte_spinlock_lock(&hw->reconfig_lock); - - nn_cfg_writel(hw, NFP_NET_CFG_CTRL, ctrl); - nn_cfg_writel(hw, NFP_NET_CFG_UPDATE, update); - - rte_wmb(); - - err = __nfp_net_reconfig(hw, update); - - rte_spinlock_unlock(&hw->reconfig_lock); - - if (!err) - return 0; - - /* - * Reconfig errors imply situations where they can be handled. - * Otherwise, rte_panic is called inside __nfp_net_reconfig - */ - PMD_INIT_LOG(ERR, "Error nfp_net reconfig for ctrl: %x update: %x", - ctrl, update); - return -EIO; -} - -/* - * Configure an Ethernet device. This function must be invoked first - * before any other function in the Ethernet API. This function can - * also be re-invoked when a device is in the stopped state. - */ -int -nfp_net_configure(struct rte_eth_dev *dev) -{ - struct rte_eth_conf *dev_conf; - struct rte_eth_rxmode *rxmode; - struct rte_eth_txmode *txmode; - struct nfp_net_hw *hw; - - hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); - - /* - * A DPDK app sends info about how many queues to use and how - * those queues need to be configured. This is used by the - * DPDK core and it makes sure no more queues than those - * advertised by the driver are requested. This function is - * called after that internal process - */ - - PMD_INIT_LOG(DEBUG, "Configure"); - - dev_conf = &dev->data->dev_conf; - rxmode = &dev_conf->rxmode; - txmode = &dev_conf->txmode; - - if (rxmode->mq_mode & ETH_MQ_RX_RSS_FLAG) - rxmode->offloads |= DEV_RX_OFFLOAD_RSS_HASH; - - /* Checking TX mode */ - if (txmode->mq_mode) { - PMD_INIT_LOG(INFO, "TX mq_mode DCB and VMDq not supported"); - return -EINVAL; - } - - /* Checking RX mode */ - if (rxmode->mq_mode & ETH_MQ_RX_RSS && - !(hw->cap & NFP_NET_CFG_CTRL_RSS)) { - PMD_INIT_LOG(INFO, "RSS not supported"); - return -EINVAL; - } - - return 0; -} - -void -nfp_net_enable_queues(struct rte_eth_dev *dev) -{ - struct nfp_net_hw *hw; - uint64_t enabled_queues = 0; - int i; - - hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); - - /* Enabling the required TX queues in the device */ - for (i = 0; i < dev->data->nb_tx_queues; i++) - enabled_queues |= (1 << i); - - nn_cfg_writeq(hw, NFP_NET_CFG_TXRS_ENABLE, enabled_queues); - - enabled_queues = 0; - - /* Enabling the required RX queues in the device */ - for (i = 0; i < dev->data->nb_rx_queues; i++) - enabled_queues |= (1 << i); - - nn_cfg_writeq(hw, NFP_NET_CFG_RXRS_ENABLE, enabled_queues); -} - -void -nfp_net_disable_queues(struct rte_eth_dev *dev) -{ - struct nfp_net_hw *hw; - uint32_t new_ctrl, update = 0; - - hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); - - nn_cfg_writeq(hw, NFP_NET_CFG_TXRS_ENABLE, 0); - nn_cfg_writeq(hw, NFP_NET_CFG_RXRS_ENABLE, 0); - - new_ctrl = hw->ctrl & ~NFP_NET_CFG_CTRL_ENABLE; - update = NFP_NET_CFG_UPDATE_GEN | NFP_NET_CFG_UPDATE_RING | - NFP_NET_CFG_UPDATE_MSIX; - - if (hw->cap & NFP_NET_CFG_CTRL_RINGCFG) - new_ctrl &= ~NFP_NET_CFG_CTRL_RINGCFG; - - /* If an error when reconfig we avoid to change hw state */ - if (nfp_net_reconfig(hw, new_ctrl, update) < 0) - return; - - hw->ctrl = new_ctrl; -} - -void -nfp_net_params_setup(struct nfp_net_hw *hw) -{ - nn_cfg_writel(hw, NFP_NET_CFG_MTU, hw->mtu); - nn_cfg_writel(hw, NFP_NET_CFG_FLBUFSZ, hw->flbufsz); -} - -void -nfp_net_cfg_queue_setup(struct nfp_net_hw *hw) -{ - hw->qcp_cfg = hw->tx_bar + NFP_QCP_QUEUE_ADDR_SZ; -} - -#define ETH_ADDR_LEN 6 - -void -nfp_eth_copy_mac(uint8_t *dst, const uint8_t *src) -{ - int i; - - for (i = 0; i < ETH_ADDR_LEN; i++) - dst[i] = src[i]; -} - -void -nfp_net_write_mac(struct nfp_net_hw *hw, uint8_t *mac) -{ - uint32_t mac0 = *(uint32_t *)mac; - uint16_t mac1; - - nn_writel(rte_cpu_to_be_32(mac0), hw->ctrl_bar + NFP_NET_CFG_MACADDR); - - mac += 4; - mac1 = *(uint16_t *)mac; - nn_writew(rte_cpu_to_be_16(mac1), - hw->ctrl_bar + NFP_NET_CFG_MACADDR + 6); -} - -int -nfp_set_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr) -{ - struct nfp_net_hw *hw; - uint32_t update, ctrl; - - hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); - if ((hw->ctrl & NFP_NET_CFG_CTRL_ENABLE) && - !(hw->cap & NFP_NET_CFG_CTRL_LIVE_ADDR)) { - PMD_INIT_LOG(INFO, "MAC address unable to change when" - " port enabled"); - return -EBUSY; - } - - if ((hw->ctrl & NFP_NET_CFG_CTRL_ENABLE) && - !(hw->cap & NFP_NET_CFG_CTRL_LIVE_ADDR)) - return -EBUSY; - - /* Writing new MAC to the specific port BAR address */ - nfp_net_write_mac(hw, (uint8_t *)mac_addr); - - /* Signal the NIC about the change */ - update = NFP_NET_CFG_UPDATE_MACADDR; - ctrl = hw->ctrl; - if ((hw->ctrl & NFP_NET_CFG_CTRL_ENABLE) && - (hw->cap & NFP_NET_CFG_CTRL_LIVE_ADDR)) - ctrl |= NFP_NET_CFG_CTRL_LIVE_ADDR; - if (nfp_net_reconfig(hw, ctrl, update) < 0) { - PMD_INIT_LOG(INFO, "MAC address update failed"); - return -EIO; - } - return 0; -} - -int -nfp_configure_rx_interrupt(struct rte_eth_dev *dev, - struct rte_intr_handle *intr_handle) -{ - struct nfp_net_hw *hw; - int i; - - if (!intr_handle->intr_vec) { - intr_handle->intr_vec = - rte_zmalloc("intr_vec", - dev->data->nb_rx_queues * sizeof(int), 0); - if (!intr_handle->intr_vec) { - PMD_INIT_LOG(ERR, "Failed to allocate %d rx_queues" - " intr_vec", dev->data->nb_rx_queues); - return -ENOMEM; - } - } - - hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); - - if (intr_handle->type == RTE_INTR_HANDLE_UIO) { - PMD_INIT_LOG(INFO, "VF: enabling RX interrupt with UIO"); - /* UIO just supports one queue and no LSC*/ - nn_cfg_writeb(hw, NFP_NET_CFG_RXR_VEC(0), 0); - intr_handle->intr_vec[0] = 0; - } else { - PMD_INIT_LOG(INFO, "VF: enabling RX interrupt with VFIO"); - for (i = 0; i < dev->data->nb_rx_queues; i++) { - /* - * The first msix vector is reserved for non - * efd interrupts - */ - nn_cfg_writeb(hw, NFP_NET_CFG_RXR_VEC(i), i + 1); - intr_handle->intr_vec[i] = i + 1; - PMD_INIT_LOG(DEBUG, "intr_vec[%d]= %d", i, - intr_handle->intr_vec[i]); - } - } - - /* Avoiding TX interrupts */ - hw->ctrl |= NFP_NET_CFG_CTRL_MSIX_TX_OFF; - return 0; -} - -uint32_t -nfp_check_offloads(struct rte_eth_dev *dev) -{ - struct nfp_net_hw *hw; - struct rte_eth_conf *dev_conf; - struct rte_eth_rxmode *rxmode; - struct rte_eth_txmode *txmode; - uint32_t ctrl = 0; - - hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); - - dev_conf = &dev->data->dev_conf; - rxmode = &dev_conf->rxmode; - txmode = &dev_conf->txmode; - - if (rxmode->offloads & DEV_RX_OFFLOAD_IPV4_CKSUM) { - if (hw->cap & NFP_NET_CFG_CTRL_RXCSUM) - ctrl |= NFP_NET_CFG_CTRL_RXCSUM; - } - - if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP) { - if (hw->cap & NFP_NET_CFG_CTRL_RXVLAN) - ctrl |= NFP_NET_CFG_CTRL_RXVLAN; - } - - if (rxmode->offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) - hw->mtu = rxmode->max_rx_pkt_len; - - if (txmode->offloads & DEV_TX_OFFLOAD_VLAN_INSERT) - ctrl |= NFP_NET_CFG_CTRL_TXVLAN; - - /* L2 broadcast */ - if (hw->cap & NFP_NET_CFG_CTRL_L2BC) - ctrl |= NFP_NET_CFG_CTRL_L2BC; - - /* L2 multicast */ - if (hw->cap & NFP_NET_CFG_CTRL_L2MC) - ctrl |= NFP_NET_CFG_CTRL_L2MC; - - /* TX checksum offload */ - if (txmode->offloads & DEV_TX_OFFLOAD_IPV4_CKSUM || - txmode->offloads & DEV_TX_OFFLOAD_UDP_CKSUM || - txmode->offloads & DEV_TX_OFFLOAD_TCP_CKSUM) - ctrl |= NFP_NET_CFG_CTRL_TXCSUM; - - /* LSO offload */ - if (txmode->offloads & DEV_TX_OFFLOAD_TCP_TSO) { - if (hw->cap & NFP_NET_CFG_CTRL_LSO) - ctrl |= NFP_NET_CFG_CTRL_LSO; - else - ctrl |= NFP_NET_CFG_CTRL_LSO2; - } - - /* RX gather */ - if (txmode->offloads & DEV_TX_OFFLOAD_MULTI_SEGS) - ctrl |= NFP_NET_CFG_CTRL_GATHER; - - return ctrl; -} - -int -nfp_net_promisc_enable(struct rte_eth_dev *dev) -{ - uint32_t new_ctrl, update = 0; - struct nfp_net_hw *hw; - int ret; - - PMD_DRV_LOG(DEBUG, "Promiscuous mode enable"); - - hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); - - if (!(hw->cap & NFP_NET_CFG_CTRL_PROMISC)) { - PMD_INIT_LOG(INFO, "Promiscuous mode not supported"); - return -ENOTSUP; - } - - if (hw->ctrl & NFP_NET_CFG_CTRL_PROMISC) { - PMD_DRV_LOG(INFO, "Promiscuous mode already enabled"); - return 0; - } - - new_ctrl = hw->ctrl | NFP_NET_CFG_CTRL_PROMISC; - update = NFP_NET_CFG_UPDATE_GEN; - - /* - * DPDK sets promiscuous mode on just after this call assuming - * it can not fail ... - */ - ret = nfp_net_reconfig(hw, new_ctrl, update); - if (ret < 0) - return ret; - - hw->ctrl = new_ctrl; - - return 0; -} - -int -nfp_net_promisc_disable(struct rte_eth_dev *dev) -{ - uint32_t new_ctrl, update = 0; - struct nfp_net_hw *hw; - int ret; - - hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); - - if ((hw->ctrl & NFP_NET_CFG_CTRL_PROMISC) == 0) { - PMD_DRV_LOG(INFO, "Promiscuous mode already disabled"); - return 0; - } - - new_ctrl = hw->ctrl & ~NFP_NET_CFG_CTRL_PROMISC; - update = NFP_NET_CFG_UPDATE_GEN; - - /* - * DPDK sets promiscuous mode off just before this call - * assuming it can not fail ... - */ - ret = nfp_net_reconfig(hw, new_ctrl, update); - if (ret < 0) - return ret; - - hw->ctrl = new_ctrl; - - return 0; -} - -/* - * return 0 means link status changed, -1 means not changed - * - * Wait to complete is needed as it can take up to 9 seconds to get the Link - * status. - */ -int -nfp_net_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete) -{ - struct nfp_net_hw *hw; - struct rte_eth_link link; - uint32_t nn_link_status; - int ret; - - static const uint32_t ls_to_ethtool[] = { - [NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED] = ETH_SPEED_NUM_NONE, - [NFP_NET_CFG_STS_LINK_RATE_UNKNOWN] = ETH_SPEED_NUM_NONE, - [NFP_NET_CFG_STS_LINK_RATE_1G] = ETH_SPEED_NUM_1G, - [NFP_NET_CFG_STS_LINK_RATE_10G] = ETH_SPEED_NUM_10G, - [NFP_NET_CFG_STS_LINK_RATE_25G] = ETH_SPEED_NUM_25G, - [NFP_NET_CFG_STS_LINK_RATE_40G] = ETH_SPEED_NUM_40G, - [NFP_NET_CFG_STS_LINK_RATE_50G] = ETH_SPEED_NUM_50G, - [NFP_NET_CFG_STS_LINK_RATE_100G] = ETH_SPEED_NUM_100G, - }; - - PMD_DRV_LOG(DEBUG, "Link update"); - - hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); - - nn_link_status = nn_cfg_readl(hw, NFP_NET_CFG_STS); - - memset(&link, 0, sizeof(struct rte_eth_link)); - - if (nn_link_status & NFP_NET_CFG_STS_LINK) - link.link_status = ETH_LINK_UP; - - link.link_duplex = ETH_LINK_FULL_DUPLEX; - - nn_link_status = (nn_link_status >> NFP_NET_CFG_STS_LINK_RATE_SHIFT) & - NFP_NET_CFG_STS_LINK_RATE_MASK; - - if (nn_link_status >= RTE_DIM(ls_to_ethtool)) - link.link_speed = ETH_SPEED_NUM_NONE; - else - link.link_speed = ls_to_ethtool[nn_link_status]; - - ret = rte_eth_linkstatus_set(dev, &link); - if (ret == 0) { - if (link.link_status) - PMD_DRV_LOG(INFO, "NIC Link is Up"); - else - PMD_DRV_LOG(INFO, "NIC Link is Down"); - } - return ret; -} - -int -nfp_net_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) -{ - int i; - struct nfp_net_hw *hw; - struct rte_eth_stats nfp_dev_stats; - - hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); - - /* RTE_ETHDEV_QUEUE_STAT_CNTRS default value is 16 */ - - memset(&nfp_dev_stats, 0, sizeof(nfp_dev_stats)); - - /* reading per RX ring stats */ - for (i = 0; i < dev->data->nb_rx_queues; i++) { - if (i == RTE_ETHDEV_QUEUE_STAT_CNTRS) - break; - - nfp_dev_stats.q_ipackets[i] = - nn_cfg_readq(hw, NFP_NET_CFG_RXR_STATS(i)); - - nfp_dev_stats.q_ipackets[i] -= - hw->eth_stats_base.q_ipackets[i]; - - nfp_dev_stats.q_ibytes[i] = - nn_cfg_readq(hw, NFP_NET_CFG_RXR_STATS(i) + 0x8); - - nfp_dev_stats.q_ibytes[i] -= - hw->eth_stats_base.q_ibytes[i]; - } - - /* reading per TX ring stats */ - for (i = 0; i < dev->data->nb_tx_queues; i++) { - if (i == RTE_ETHDEV_QUEUE_STAT_CNTRS) - break; - - nfp_dev_stats.q_opackets[i] = - nn_cfg_readq(hw, NFP_NET_CFG_TXR_STATS(i)); - - nfp_dev_stats.q_opackets[i] -= - hw->eth_stats_base.q_opackets[i]; - - nfp_dev_stats.q_obytes[i] = - nn_cfg_readq(hw, NFP_NET_CFG_TXR_STATS(i) + 0x8); - - nfp_dev_stats.q_obytes[i] -= - hw->eth_stats_base.q_obytes[i]; - } - - nfp_dev_stats.ipackets = - nn_cfg_readq(hw, NFP_NET_CFG_STATS_RX_FRAMES); - - nfp_dev_stats.ipackets -= hw->eth_stats_base.ipackets; - - nfp_dev_stats.ibytes = - nn_cfg_readq(hw, NFP_NET_CFG_STATS_RX_OCTETS); - - nfp_dev_stats.ibytes -= hw->eth_stats_base.ibytes; - - nfp_dev_stats.opackets = - nn_cfg_readq(hw, NFP_NET_CFG_STATS_TX_FRAMES); - - nfp_dev_stats.opackets -= hw->eth_stats_base.opackets; - - nfp_dev_stats.obytes = - nn_cfg_readq(hw, NFP_NET_CFG_STATS_TX_OCTETS); - - nfp_dev_stats.obytes -= hw->eth_stats_base.obytes; - - /* reading general device stats */ - nfp_dev_stats.ierrors = - nn_cfg_readq(hw, NFP_NET_CFG_STATS_RX_ERRORS); - - nfp_dev_stats.ierrors -= hw->eth_stats_base.ierrors; - - nfp_dev_stats.oerrors = - nn_cfg_readq(hw, NFP_NET_CFG_STATS_TX_ERRORS); - - nfp_dev_stats.oerrors -= hw->eth_stats_base.oerrors; - - /* RX ring mbuf allocation failures */ - nfp_dev_stats.rx_nombuf = dev->data->rx_mbuf_alloc_failed; - - nfp_dev_stats.imissed = - nn_cfg_readq(hw, NFP_NET_CFG_STATS_RX_DISCARDS); - - nfp_dev_stats.imissed -= hw->eth_stats_base.imissed; - - if (stats) { - memcpy(stats, &nfp_dev_stats, sizeof(*stats)); - return 0; - } - return -EINVAL; -} - -int -nfp_net_stats_reset(struct rte_eth_dev *dev) -{ - int i; - struct nfp_net_hw *hw; - - hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); - - /* - * hw->eth_stats_base records the per counter starting point. - * Lets update it now - */ - - /* reading per RX ring stats */ - for (i = 0; i < dev->data->nb_rx_queues; i++) { - if (i == RTE_ETHDEV_QUEUE_STAT_CNTRS) - break; - - hw->eth_stats_base.q_ipackets[i] = - nn_cfg_readq(hw, NFP_NET_CFG_RXR_STATS(i)); - - hw->eth_stats_base.q_ibytes[i] = - nn_cfg_readq(hw, NFP_NET_CFG_RXR_STATS(i) + 0x8); - } - - /* reading per TX ring stats */ - for (i = 0; i < dev->data->nb_tx_queues; i++) { - if (i == RTE_ETHDEV_QUEUE_STAT_CNTRS) - break; - - hw->eth_stats_base.q_opackets[i] = - nn_cfg_readq(hw, NFP_NET_CFG_TXR_STATS(i)); - - hw->eth_stats_base.q_obytes[i] = - nn_cfg_readq(hw, NFP_NET_CFG_TXR_STATS(i) + 0x8); - } - - hw->eth_stats_base.ipackets = - nn_cfg_readq(hw, NFP_NET_CFG_STATS_RX_FRAMES); - - hw->eth_stats_base.ibytes = - nn_cfg_readq(hw, NFP_NET_CFG_STATS_RX_OCTETS); - - hw->eth_stats_base.opackets = - nn_cfg_readq(hw, NFP_NET_CFG_STATS_TX_FRAMES); - - hw->eth_stats_base.obytes = - nn_cfg_readq(hw, NFP_NET_CFG_STATS_TX_OCTETS); - - /* reading general device stats */ - hw->eth_stats_base.ierrors = - nn_cfg_readq(hw, NFP_NET_CFG_STATS_RX_ERRORS); - - hw->eth_stats_base.oerrors = - nn_cfg_readq(hw, NFP_NET_CFG_STATS_TX_ERRORS); - - /* RX ring mbuf allocation failures */ - dev->data->rx_mbuf_alloc_failed = 0; - - hw->eth_stats_base.imissed = - nn_cfg_readq(hw, NFP_NET_CFG_STATS_RX_DISCARDS); - - return 0; -} - -int -nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) -{ - struct nfp_net_hw *hw; - - hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); - - dev_info->max_rx_queues = (uint16_t)hw->max_rx_queues; - dev_info->max_tx_queues = (uint16_t)hw->max_tx_queues; - dev_info->min_rx_bufsize = RTE_ETHER_MIN_MTU; - dev_info->max_rx_pktlen = hw->max_mtu; - /* Next should change when PF support is implemented */ - dev_info->max_mac_addrs = 1; - - if (hw->cap & NFP_NET_CFG_CTRL_RXVLAN) - dev_info->rx_offload_capa = DEV_RX_OFFLOAD_VLAN_STRIP; - - if (hw->cap & NFP_NET_CFG_CTRL_RXCSUM) - dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_IPV4_CKSUM | - DEV_RX_OFFLOAD_UDP_CKSUM | - DEV_RX_OFFLOAD_TCP_CKSUM; - - if (hw->cap & NFP_NET_CFG_CTRL_TXVLAN) - dev_info->tx_offload_capa = DEV_TX_OFFLOAD_VLAN_INSERT; - - if (hw->cap & NFP_NET_CFG_CTRL_TXCSUM) - dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_IPV4_CKSUM | - DEV_TX_OFFLOAD_UDP_CKSUM | - DEV_TX_OFFLOAD_TCP_CKSUM; - - if (hw->cap & NFP_NET_CFG_CTRL_LSO_ANY) - dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_TCP_TSO; - - if (hw->cap & NFP_NET_CFG_CTRL_GATHER) - dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_MULTI_SEGS; - - dev_info->default_rxconf = (struct rte_eth_rxconf) { - .rx_thresh = { - .pthresh = DEFAULT_RX_PTHRESH, - .hthresh = DEFAULT_RX_HTHRESH, - .wthresh = DEFAULT_RX_WTHRESH, - }, - .rx_free_thresh = DEFAULT_RX_FREE_THRESH, - .rx_drop_en = 0, - }; - - dev_info->default_txconf = (struct rte_eth_txconf) { - .tx_thresh = { - .pthresh = DEFAULT_TX_PTHRESH, - .hthresh = DEFAULT_TX_HTHRESH, - .wthresh = DEFAULT_TX_WTHRESH, - }, - .tx_free_thresh = DEFAULT_TX_FREE_THRESH, - .tx_rs_thresh = DEFAULT_TX_RSBIT_THRESH, - }; - - dev_info->rx_desc_lim = (struct rte_eth_desc_lim) { - .nb_max = NFP_NET_MAX_RX_DESC, - .nb_min = NFP_NET_MIN_RX_DESC, - .nb_align = NFP_ALIGN_RING_DESC, - }; - - dev_info->tx_desc_lim = (struct rte_eth_desc_lim) { - .nb_max = NFP_NET_MAX_TX_DESC, - .nb_min = NFP_NET_MIN_TX_DESC, - .nb_align = NFP_ALIGN_RING_DESC, - .nb_seg_max = NFP_TX_MAX_SEG, - .nb_mtu_seg_max = NFP_TX_MAX_MTU_SEG, - }; - - /* All NFP devices support jumbo frames */ - dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_JUMBO_FRAME; - - if (hw->cap & NFP_NET_CFG_CTRL_RSS) { - dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_RSS_HASH; - - dev_info->flow_type_rss_offloads = ETH_RSS_IPV4 | - ETH_RSS_NONFRAG_IPV4_TCP | - ETH_RSS_NONFRAG_IPV4_UDP | - ETH_RSS_IPV6 | - ETH_RSS_NONFRAG_IPV6_TCP | - ETH_RSS_NONFRAG_IPV6_UDP; - - dev_info->reta_size = NFP_NET_CFG_RSS_ITBL_SZ; - dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ; - } - - dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G | - ETH_LINK_SPEED_25G | ETH_LINK_SPEED_40G | - ETH_LINK_SPEED_50G | ETH_LINK_SPEED_100G; - - return 0; -} - -const uint32_t * -nfp_net_supported_ptypes_get(struct rte_eth_dev *dev) -{ - static const uint32_t ptypes[] = { - /* refers to nfp_net_set_hash() */ - RTE_PTYPE_INNER_L3_IPV4, - RTE_PTYPE_INNER_L3_IPV6, - RTE_PTYPE_INNER_L3_IPV6_EXT, - RTE_PTYPE_INNER_L4_MASK, - RTE_PTYPE_UNKNOWN - }; - - if (dev->rx_pkt_burst == nfp_net_recv_pkts) - return ptypes; - return NULL; -} - -int -nfp_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id) -{ - struct rte_pci_device *pci_dev; - struct nfp_net_hw *hw; - int base = 0; - - hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); - pci_dev = RTE_ETH_DEV_TO_PCI(dev); - - if (pci_dev->intr_handle.type != RTE_INTR_HANDLE_UIO) - base = 1; - - /* Make sure all updates are written before un-masking */ - rte_wmb(); - nn_cfg_writeb(hw, NFP_NET_CFG_ICR(base + queue_id), - NFP_NET_CFG_ICR_UNMASKED); - return 0; -} - -int -nfp_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id) -{ - struct rte_pci_device *pci_dev; - struct nfp_net_hw *hw; - int base = 0; - - hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); - pci_dev = RTE_ETH_DEV_TO_PCI(dev); - - if (pci_dev->intr_handle.type != RTE_INTR_HANDLE_UIO) - base = 1; - - /* Make sure all updates are written before un-masking */ - rte_wmb(); - nn_cfg_writeb(hw, NFP_NET_CFG_ICR(base + queue_id), 0x1); - return 0; -} - -static void -nfp_net_dev_link_status_print(struct rte_eth_dev *dev) -{ - struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); - struct rte_eth_link link; - - rte_eth_linkstatus_get(dev, &link); - if (link.link_status) - PMD_DRV_LOG(INFO, "Port %d: Link Up - speed %u Mbps - %s", - dev->data->port_id, link.link_speed, - link.link_duplex == ETH_LINK_FULL_DUPLEX - ? "full-duplex" : "half-duplex"); - else - PMD_DRV_LOG(INFO, " Port %d: Link Down", - dev->data->port_id); - - PMD_DRV_LOG(INFO, "PCI Address: " PCI_PRI_FMT, - pci_dev->addr.domain, pci_dev->addr.bus, - pci_dev->addr.devid, pci_dev->addr.function); -} - -/* Interrupt configuration and handling */ - -/* - * nfp_net_irq_unmask - Unmask an interrupt - * - * If MSI-X auto-masking is enabled clear the mask bit, otherwise - * clear the ICR for the entry. - */ -static void -nfp_net_irq_unmask(struct rte_eth_dev *dev) -{ - struct nfp_net_hw *hw; - struct rte_pci_device *pci_dev; - - hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); - pci_dev = RTE_ETH_DEV_TO_PCI(dev); - - if (hw->ctrl & NFP_NET_CFG_CTRL_MSIXAUTO) { - /* If MSI-X auto-masking is used, clear the entry */ - rte_wmb(); - rte_intr_ack(&pci_dev->intr_handle); - } else { - /* Make sure all updates are written before un-masking */ - rte_wmb(); - nn_cfg_writeb(hw, NFP_NET_CFG_ICR(NFP_NET_IRQ_LSC_IDX), - NFP_NET_CFG_ICR_UNMASKED); - } -} - -/* - * Interrupt handler which shall be registered for alarm callback for delayed - * handling specific interrupt to wait for the stable nic state. As the NIC - * interrupt state is not stable for nfp after link is just down, it needs - * to wait 4 seconds to get the stable status. - * - * @param handle Pointer to interrupt handle. - * @param param The address of parameter (struct rte_eth_dev *) - * - * @return void - */ -static void -nfp_net_dev_interrupt_delayed_handler(void *param) -{ - struct rte_eth_dev *dev = (struct rte_eth_dev *)param; - - nfp_net_link_update(dev, 0); - rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL); - - nfp_net_dev_link_status_print(dev); - - /* Unmasking */ - nfp_net_irq_unmask(dev); -} - -void -nfp_net_dev_interrupt_handler(void *param) -{ - int64_t timeout; - struct rte_eth_link link; - struct rte_eth_dev *dev = (struct rte_eth_dev *)param; - - PMD_DRV_LOG(DEBUG, "We got a LSC interrupt!!!"); - - rte_eth_linkstatus_get(dev, &link); - - nfp_net_link_update(dev, 0); - - /* likely to up */ - if (!link.link_status) { - /* handle it 1 sec later, wait it being stable */ - timeout = NFP_NET_LINK_UP_CHECK_TIMEOUT; - /* likely to down */ - } else { - /* handle it 4 sec later, wait it being stable */ - timeout = NFP_NET_LINK_DOWN_CHECK_TIMEOUT; - } - - if (rte_eal_alarm_set(timeout * 1000, - nfp_net_dev_interrupt_delayed_handler, - (void *)dev) < 0) { - PMD_INIT_LOG(ERR, "Error setting alarm"); - /* Unmasking */ - nfp_net_irq_unmask(dev); - } -} - -int -nfp_net_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) -{ - struct nfp_net_hw *hw; - - hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); - - /* check that mtu is within the allowed range */ - if (mtu < RTE_ETHER_MIN_MTU || (uint32_t)mtu > hw->max_mtu) - return -EINVAL; - - /* mtu setting is forbidden if port is started */ - if (dev->data->dev_started) { - PMD_DRV_LOG(ERR, "port %d must be stopped before configuration", - dev->data->port_id); - return -EBUSY; - } - - /* switch to jumbo mode if needed */ - if ((uint32_t)mtu > RTE_ETHER_MTU) - dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME; - else - dev->data->dev_conf.rxmode.offloads &= ~DEV_RX_OFFLOAD_JUMBO_FRAME; - - /* update max frame size */ - dev->data->dev_conf.rxmode.max_rx_pkt_len = (uint32_t)mtu; - - /* writing to configuration space */ - nn_cfg_writel(hw, NFP_NET_CFG_MTU, (uint32_t)mtu); - - hw->mtu = mtu; - - return 0; -} - -int -nfp_net_vlan_offload_set(struct rte_eth_dev *dev, int mask) -{ - uint32_t new_ctrl, update; - struct nfp_net_hw *hw; - int ret; - - hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); - new_ctrl = 0; - - /* Enable vlan strip if it is not configured yet */ - if ((mask & ETH_VLAN_STRIP_OFFLOAD) && - !(hw->ctrl & NFP_NET_CFG_CTRL_RXVLAN)) - new_ctrl = hw->ctrl | NFP_NET_CFG_CTRL_RXVLAN; - - /* Disable vlan strip just if it is configured */ - if (!(mask & ETH_VLAN_STRIP_OFFLOAD) && - (hw->ctrl & NFP_NET_CFG_CTRL_RXVLAN)) - new_ctrl = hw->ctrl & ~NFP_NET_CFG_CTRL_RXVLAN; - - if (new_ctrl == 0) - return 0; - - update = NFP_NET_CFG_UPDATE_GEN; - - ret = nfp_net_reconfig(hw, new_ctrl, update); - if (!ret) - hw->ctrl = new_ctrl; - - return ret; -} - -static int -nfp_net_rss_reta_write(struct rte_eth_dev *dev, - struct rte_eth_rss_reta_entry64 *reta_conf, - uint16_t reta_size) -{ - uint32_t reta, mask; - int i, j; - int idx, shift; - struct nfp_net_hw *hw = - NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); - - if (reta_size != NFP_NET_CFG_RSS_ITBL_SZ) { - PMD_DRV_LOG(ERR, "The size of hash lookup table configured " - "(%d) doesn't match the number hardware can supported " - "(%d)", reta_size, NFP_NET_CFG_RSS_ITBL_SZ); - return -EINVAL; - } - - /* - * Update Redirection Table. There are 128 8bit-entries which can be - * manage as 32 32bit-entries - */ - for (i = 0; i < reta_size; i += 4) { - /* Handling 4 RSS entries per loop */ - idx = i / RTE_RETA_GROUP_SIZE; - shift = i % RTE_RETA_GROUP_SIZE; - mask = (uint8_t)((reta_conf[idx].mask >> shift) & 0xF); - - if (!mask) - continue; - - reta = 0; - /* If all 4 entries were set, don't need read RETA register */ - if (mask != 0xF) - reta = nn_cfg_readl(hw, NFP_NET_CFG_RSS_ITBL + i); - - for (j = 0; j < 4; j++) { - if (!(mask & (0x1 << j))) - continue; - if (mask != 0xF) - /* Clearing the entry bits */ - reta &= ~(0xFF << (8 * j)); - reta |= reta_conf[idx].reta[shift + j] << (8 * j); - } - nn_cfg_writel(hw, NFP_NET_CFG_RSS_ITBL + (idx * 64) + shift, - reta); - } - return 0; -} - -/* Update Redirection Table(RETA) of Receive Side Scaling of Ethernet device */ -int -nfp_net_reta_update(struct rte_eth_dev *dev, - struct rte_eth_rss_reta_entry64 *reta_conf, - uint16_t reta_size) -{ - struct nfp_net_hw *hw = - NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); - uint32_t update; - int ret; - - if (!(hw->ctrl & NFP_NET_CFG_CTRL_RSS)) - return -EINVAL; - - ret = nfp_net_rss_reta_write(dev, reta_conf, reta_size); - if (ret != 0) - return ret; - - update = NFP_NET_CFG_UPDATE_RSS; - - if (nfp_net_reconfig(hw, hw->ctrl, update) < 0) - return -EIO; - - return 0; -} - - /* Query Redirection Table(RETA) of Receive Side Scaling of Ethernet device. */ -int -nfp_net_reta_query(struct rte_eth_dev *dev, - struct rte_eth_rss_reta_entry64 *reta_conf, - uint16_t reta_size) -{ - uint8_t i, j, mask; - int idx, shift; - uint32_t reta; - struct nfp_net_hw *hw; - - hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); - - if (!(hw->ctrl & NFP_NET_CFG_CTRL_RSS)) - return -EINVAL; - - if (reta_size != NFP_NET_CFG_RSS_ITBL_SZ) { - PMD_DRV_LOG(ERR, "The size of hash lookup table configured " - "(%d) doesn't match the number hardware can supported " - "(%d)", reta_size, NFP_NET_CFG_RSS_ITBL_SZ); - return -EINVAL; - } - - /* - * Reading Redirection Table. There are 128 8bit-entries which can be - * manage as 32 32bit-entries - */ - for (i = 0; i < reta_size; i += 4) { - /* Handling 4 RSS entries per loop */ - idx = i / RTE_RETA_GROUP_SIZE; - shift = i % RTE_RETA_GROUP_SIZE; - mask = (uint8_t)((reta_conf[idx].mask >> shift) & 0xF); - - if (!mask) - continue; - - reta = nn_cfg_readl(hw, NFP_NET_CFG_RSS_ITBL + (idx * 64) + - shift); - for (j = 0; j < 4; j++) { - if (!(mask & (0x1 << j))) - continue; - reta_conf[idx].reta[shift + j] = - (uint8_t)((reta >> (8 * j)) & 0xF); - } - } - return 0; -} - -static int -nfp_net_rss_hash_write(struct rte_eth_dev *dev, - struct rte_eth_rss_conf *rss_conf) -{ - struct nfp_net_hw *hw; - uint64_t rss_hf; - uint32_t cfg_rss_ctrl = 0; - uint8_t key; - int i; - - hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); - - /* Writing the key byte a byte */ - for (i = 0; i < rss_conf->rss_key_len; i++) { - memcpy(&key, &rss_conf->rss_key[i], 1); - nn_cfg_writeb(hw, NFP_NET_CFG_RSS_KEY + i, key); - } - - rss_hf = rss_conf->rss_hf; - - if (rss_hf & ETH_RSS_IPV4) - cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV4; - - if (rss_hf & ETH_RSS_NONFRAG_IPV4_TCP) - cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV4_TCP; - - if (rss_hf & ETH_RSS_NONFRAG_IPV4_UDP) - cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV4_UDP; - - if (rss_hf & ETH_RSS_IPV6) - cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV6; - - if (rss_hf & ETH_RSS_NONFRAG_IPV6_TCP) - cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV6_TCP; - - if (rss_hf & ETH_RSS_NONFRAG_IPV6_UDP) - cfg_rss_ctrl |= NFP_NET_CFG_RSS_IPV6_UDP; - - cfg_rss_ctrl |= NFP_NET_CFG_RSS_MASK; - cfg_rss_ctrl |= NFP_NET_CFG_RSS_TOEPLITZ; - - /* configuring where to apply the RSS hash */ - nn_cfg_writel(hw, NFP_NET_CFG_RSS_CTRL, cfg_rss_ctrl); - - /* Writing the key size */ - nn_cfg_writeb(hw, NFP_NET_CFG_RSS_KEY_SZ, rss_conf->rss_key_len); - - return 0; -} - -int -nfp_net_rss_hash_update(struct rte_eth_dev *dev, - struct rte_eth_rss_conf *rss_conf) -{ - uint32_t update; - uint64_t rss_hf; - struct nfp_net_hw *hw; - - hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); - - rss_hf = rss_conf->rss_hf; - - /* Checking if RSS is enabled */ - if (!(hw->ctrl & NFP_NET_CFG_CTRL_RSS)) { - if (rss_hf != 0) { /* Enable RSS? */ - PMD_DRV_LOG(ERR, "RSS unsupported"); - return -EINVAL; - } - return 0; /* Nothing to do */ - } - - if (rss_conf->rss_key_len > NFP_NET_CFG_RSS_KEY_SZ) { - PMD_DRV_LOG(ERR, "hash key too long"); - return -EINVAL; - } - - nfp_net_rss_hash_write(dev, rss_conf); - - update = NFP_NET_CFG_UPDATE_RSS; - - if (nfp_net_reconfig(hw, hw->ctrl, update) < 0) - return -EIO; - - return 0; -} - -int -nfp_net_rss_hash_conf_get(struct rte_eth_dev *dev, - struct rte_eth_rss_conf *rss_conf) -{ - uint64_t rss_hf; - uint32_t cfg_rss_ctrl; - uint8_t key; - int i; - struct nfp_net_hw *hw; - - hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); - - if (!(hw->ctrl & NFP_NET_CFG_CTRL_RSS)) - return -EINVAL; - - rss_hf = rss_conf->rss_hf; - cfg_rss_ctrl = nn_cfg_readl(hw, NFP_NET_CFG_RSS_CTRL); - - if (cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV4) - rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_NONFRAG_IPV4_UDP; - - if (cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV4_TCP) - rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP; - - if (cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV6_TCP) - rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP; - - if (cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV4_UDP) - rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP; - - if (cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV6_UDP) - rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP; - - if (cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV6) - rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_NONFRAG_IPV6_UDP; - - /* Propagate current RSS hash functions to caller */ - rss_conf->rss_hf = rss_hf; - - /* Reading the key size */ - rss_conf->rss_key_len = nn_cfg_readl(hw, NFP_NET_CFG_RSS_KEY_SZ); - - /* Reading the key byte a byte */ - for (i = 0; i < rss_conf->rss_key_len; i++) { - key = nn_cfg_readb(hw, NFP_NET_CFG_RSS_KEY + i); - memcpy(&rss_conf->rss_key[i], &key, 1); - } - - return 0; -} - -int -nfp_net_rss_config_default(struct rte_eth_dev *dev) -{ - struct rte_eth_conf *dev_conf; - struct rte_eth_rss_conf rss_conf; - struct rte_eth_rss_reta_entry64 nfp_reta_conf[2]; - uint16_t rx_queues = dev->data->nb_rx_queues; - uint16_t queue; - int i, j, ret; - - PMD_DRV_LOG(INFO, "setting default RSS conf for %u queues", - rx_queues); - - nfp_reta_conf[0].mask = ~0x0; - nfp_reta_conf[1].mask = ~0x0; - - queue = 0; - for (i = 0; i < 0x40; i += 8) { - for (j = i; j < (i + 8); j++) { - nfp_reta_conf[0].reta[j] = queue; - nfp_reta_conf[1].reta[j] = queue++; - queue %= rx_queues; - } - } - ret = nfp_net_rss_reta_write(dev, nfp_reta_conf, 0x80); - if (ret != 0) - return ret; - - dev_conf = &dev->data->dev_conf; - if (!dev_conf) { - PMD_DRV_LOG(INFO, "wrong rss conf"); - return -EINVAL; - } - rss_conf = dev_conf->rx_adv_conf.rss_conf; - - ret = nfp_net_rss_hash_write(dev, &rss_conf); - - return ret; -} - -RTE_LOG_REGISTER_SUFFIX(nfp_logtype_init, init, NOTICE); -RTE_LOG_REGISTER_SUFFIX(nfp_logtype_driver, driver, NOTICE); -/* - * Local variables: - * c-file-style: "Linux" - * indent-tabs-mode: t - * End: - */ diff --git a/drivers/net/nfp/nfp_net_ctrl.h b/drivers/net/nfp/nfp_net_ctrl.h deleted file mode 100644 index 4f26ccf483..0000000000 --- a/drivers/net/nfp/nfp_net_ctrl.h +++ /dev/null @@ -1,326 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright (c) 2014, 2015 Netronome Systems, Inc. - * All rights reserved. - */ - -/* - * vim:shiftwidth=8:noexpandtab - * - * Netronome network device driver: Control BAR layout - */ -#ifndef _NFP_NET_CTRL_H_ -#define _NFP_NET_CTRL_H_ - -/* - * Configuration BAR size. - * - * The configuration BAR is 8K in size, but on the NFP6000, due to - * THB-350, 32k needs to be reserved. - */ -#ifdef __NFP_IS_6000 -#define NFP_NET_CFG_BAR_SZ (32 * 1024) -#else -#define NFP_NET_CFG_BAR_SZ (8 * 1024) -#endif - -/* Offset in Freelist buffer where packet starts on RX */ -#define NFP_NET_RX_OFFSET 32 - -/* working with metadata api (NFD version > 3.0) */ -#define NFP_NET_META_FIELD_SIZE 4 -#define NFP_NET_META_FIELD_MASK ((1 << NFP_NET_META_FIELD_SIZE) - 1) - -/* Prepend field types */ -#define NFP_NET_META_HASH 1 /* next field carries hash type */ - -/* Hash type pre-pended when a RSS hash was computed */ -#define NFP_NET_RSS_NONE 0 -#define NFP_NET_RSS_IPV4 1 -#define NFP_NET_RSS_IPV6 2 -#define NFP_NET_RSS_IPV6_EX 3 -#define NFP_NET_RSS_IPV4_TCP 4 -#define NFP_NET_RSS_IPV6_TCP 5 -#define NFP_NET_RSS_IPV6_EX_TCP 6 -#define NFP_NET_RSS_IPV4_UDP 7 -#define NFP_NET_RSS_IPV6_UDP 8 -#define NFP_NET_RSS_IPV6_EX_UDP 9 - -/* - * @NFP_NET_TXR_MAX: Maximum number of TX rings - * @NFP_NET_TXR_MASK: Mask for TX rings - * @NFP_NET_RXR_MAX: Maximum number of RX rings - * @NFP_NET_RXR_MASK: Mask for RX rings - */ -#define NFP_NET_TXR_MAX 64 -#define NFP_NET_TXR_MASK (NFP_NET_TXR_MAX - 1) -#define NFP_NET_RXR_MAX 64 -#define NFP_NET_RXR_MASK (NFP_NET_RXR_MAX - 1) - -/* - * Read/Write config words (0x0000 - 0x002c) - * @NFP_NET_CFG_CTRL: Global control - * @NFP_NET_CFG_UPDATE: Indicate which fields are updated - * @NFP_NET_CFG_TXRS_ENABLE: Bitmask of enabled TX rings - * @NFP_NET_CFG_RXRS_ENABLE: Bitmask of enabled RX rings - * @NFP_NET_CFG_MTU: Set MTU size - * @NFP_NET_CFG_FLBUFSZ: Set freelist buffer size (must be larger than MTU) - * @NFP_NET_CFG_EXN: MSI-X table entry for exceptions - * @NFP_NET_CFG_LSC: MSI-X table entry for link state changes - * @NFP_NET_CFG_MACADDR: MAC address - * - * TODO: - * - define Error details in UPDATE - */ -#define NFP_NET_CFG_CTRL 0x0000 -#define NFP_NET_CFG_CTRL_ENABLE (0x1 << 0) /* Global enable */ -#define NFP_NET_CFG_CTRL_PROMISC (0x1 << 1) /* Enable Promisc mode */ -#define NFP_NET_CFG_CTRL_L2BC (0x1 << 2) /* Allow L2 Broadcast */ -#define NFP_NET_CFG_CTRL_L2MC (0x1 << 3) /* Allow L2 Multicast */ -#define NFP_NET_CFG_CTRL_RXCSUM (0x1 << 4) /* Enable RX Checksum */ -#define NFP_NET_CFG_CTRL_TXCSUM (0x1 << 5) /* Enable TX Checksum */ -#define NFP_NET_CFG_CTRL_RXVLAN (0x1 << 6) /* Enable VLAN strip */ -#define NFP_NET_CFG_CTRL_TXVLAN (0x1 << 7) /* Enable VLAN insert */ -#define NFP_NET_CFG_CTRL_SCATTER (0x1 << 8) /* Scatter DMA */ -#define NFP_NET_CFG_CTRL_GATHER (0x1 << 9) /* Gather DMA */ -#define NFP_NET_CFG_CTRL_LSO (0x1 << 10) /* LSO/TSO */ -#define NFP_NET_CFG_CTRL_RINGCFG (0x1 << 16) /* Ring runtime changes */ -#define NFP_NET_CFG_CTRL_RSS (0x1 << 17) /* RSS */ -#define NFP_NET_CFG_CTRL_IRQMOD (0x1 << 18) /* Interrupt moderation */ -#define NFP_NET_CFG_CTRL_RINGPRIO (0x1 << 19) /* Ring priorities */ -#define NFP_NET_CFG_CTRL_MSIXAUTO (0x1 << 20) /* MSI-X auto-masking */ -#define NFP_NET_CFG_CTRL_TXRWB (0x1 << 21) /* Write-back of TX ring*/ -#define NFP_NET_CFG_CTRL_L2SWITCH (0x1 << 22) /* L2 Switch */ -#define NFP_NET_CFG_CTRL_L2SWITCH_LOCAL (0x1 << 23) /* Switch to local */ -#define NFP_NET_CFG_CTRL_VXLAN (0x1 << 24) /* Enable VXLAN */ -#define NFP_NET_CFG_CTRL_NVGRE (0x1 << 25) /* Enable NVGRE */ -#define NFP_NET_CFG_CTRL_MSIX_TX_OFF (0x1 << 26) /* Disable MSIX for TX */ -#define NFP_NET_CFG_CTRL_LSO2 (0x1 << 28) /* LSO/TSO (version 2) */ -#define NFP_NET_CFG_CTRL_RSS2 (0x1 << 29) /* RSS (version 2) */ -#define NFP_NET_CFG_CTRL_LIVE_ADDR (0x1U << 31)/* live MAC addr change */ -#define NFP_NET_CFG_UPDATE 0x0004 -#define NFP_NET_CFG_UPDATE_GEN (0x1 << 0) /* General update */ -#define NFP_NET_CFG_UPDATE_RING (0x1 << 1) /* Ring config change */ -#define NFP_NET_CFG_UPDATE_RSS (0x1 << 2) /* RSS config change */ -#define NFP_NET_CFG_UPDATE_TXRPRIO (0x1 << 3) /* TX Ring prio change */ -#define NFP_NET_CFG_UPDATE_RXRPRIO (0x1 << 4) /* RX Ring prio change */ -#define NFP_NET_CFG_UPDATE_MSIX (0x1 << 5) /* MSI-X change */ -#define NFP_NET_CFG_UPDATE_L2SWITCH (0x1 << 6) /* Switch changes */ -#define NFP_NET_CFG_UPDATE_RESET (0x1 << 7) /* Update due to FLR */ -#define NFP_NET_CFG_UPDATE_IRQMOD (0x1 << 8) /* IRQ mod change */ -#define NFP_NET_CFG_UPDATE_VXLAN (0x1 << 9) /* VXLAN port change */ -#define NFP_NET_CFG_UPDATE_MACADDR (0x1 << 11) /* MAC address change */ -#define NFP_NET_CFG_UPDATE_ERR (0x1U << 31) /* A error occurred */ -#define NFP_NET_CFG_TXRS_ENABLE 0x0008 -#define NFP_NET_CFG_RXRS_ENABLE 0x0010 -#define NFP_NET_CFG_MTU 0x0018 -#define NFP_NET_CFG_FLBUFSZ 0x001c -#define NFP_NET_CFG_EXN 0x001f -#define NFP_NET_CFG_LSC 0x0020 -#define NFP_NET_CFG_MACADDR 0x0024 - -#define NFP_NET_CFG_CTRL_LSO_ANY (NFP_NET_CFG_CTRL_LSO | NFP_NET_CFG_CTRL_LSO2) - -/* - * Read-only words (0x0030 - 0x0050): - * @NFP_NET_CFG_VERSION: Firmware version number - * @NFP_NET_CFG_STS: Status - * @NFP_NET_CFG_CAP: Capabilities (same bits as @NFP_NET_CFG_CTRL) - * @NFP_NET_MAX_TXRINGS: Maximum number of TX rings - * @NFP_NET_MAX_RXRINGS: Maximum number of RX rings - * @NFP_NET_MAX_MTU: Maximum support MTU - * @NFP_NET_CFG_START_TXQ: Start Queue Control Queue to use for TX (PF only) - * @NFP_NET_CFG_START_RXQ: Start Queue Control Queue to use for RX (PF only) - * - * TODO: - * - define more STS bits - */ -#define NFP_NET_CFG_VERSION 0x0030 -#define NFP_NET_CFG_VERSION_RESERVED_MASK (0xff << 24) -#define NFP_NET_CFG_VERSION_CLASS_MASK (0xff << 16) -#define NFP_NET_CFG_VERSION_CLASS(x) (((x) & 0xff) << 16) -#define NFP_NET_CFG_VERSION_CLASS_GENERIC 0 -#define NFP_NET_CFG_VERSION_MAJOR_MASK (0xff << 8) -#define NFP_NET_CFG_VERSION_MAJOR(x) (((x) & 0xff) << 8) -#define NFP_NET_CFG_VERSION_MINOR_MASK (0xff << 0) -#define NFP_NET_CFG_VERSION_MINOR(x) (((x) & 0xff) << 0) -#define NFP_NET_CFG_STS 0x0034 -#define NFP_NET_CFG_STS_LINK (0x1 << 0) /* Link up or down */ -/* Link rate */ -#define NFP_NET_CFG_STS_LINK_RATE_SHIFT 1 -#define NFP_NET_CFG_STS_LINK_RATE_MASK 0xF -#define NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED 0 -#define NFP_NET_CFG_STS_LINK_RATE_UNKNOWN 1 -#define NFP_NET_CFG_STS_LINK_RATE_1G 2 -#define NFP_NET_CFG_STS_LINK_RATE_10G 3 -#define NFP_NET_CFG_STS_LINK_RATE_25G 4 -#define NFP_NET_CFG_STS_LINK_RATE_40G 5 -#define NFP_NET_CFG_STS_LINK_RATE_50G 6 -#define NFP_NET_CFG_STS_LINK_RATE_100G 7 -#define NFP_NET_CFG_CAP 0x0038 -#define NFP_NET_CFG_MAX_TXRINGS 0x003c -#define NFP_NET_CFG_MAX_RXRINGS 0x0040 -#define NFP_NET_CFG_MAX_MTU 0x0044 -/* Next two words are being used by VFs for solving THB350 issue */ -#define NFP_NET_CFG_START_TXQ 0x0048 -#define NFP_NET_CFG_START_RXQ 0x004c - -/* - * NFP-3200 workaround (0x0050 - 0x0058) - * @NFP_NET_CFG_SPARE_ADDR: DMA address for ME code to use (e.g. YDS-155 fix) - */ -#define NFP_NET_CFG_SPARE_ADDR 0x0050 -/** - * NFP6000/NFP4000 - Prepend configuration - */ -#define NFP_NET_CFG_RX_OFFSET 0x0050 -#define NFP_NET_CFG_RX_OFFSET_DYNAMIC 0 /* Prepend mode */ - -/** - * Reuse spare address to contain the offset from the start of - * the host buffer where the first byte of the received frame - * will land. Any metadata will come prior to that offset. If the - * value in this field is 0, it means that that the metadata will - * always land starting at the first byte of the host buffer and - * packet data will immediately follow the metadata. As always, - * the RX descriptor indicates the presence or absence of metadata - * along with the length thereof. - */ -#define NFP_NET_CFG_RX_OFFSET_ADDR 0x0050 - -#define NFP_NET_CFG_VXLAN_PORT 0x0060 -#define NFP_NET_CFG_VXLAN_SZ 0x0008 - -/* Offload definitions */ -#define NFP_NET_N_VXLAN_PORTS (NFP_NET_CFG_VXLAN_SZ / sizeof(uint16_t)) - -/** - * 64B reserved for future use (0x0080 - 0x00c0) - */ -#define NFP_NET_CFG_RESERVED 0x0080 -#define NFP_NET_CFG_RESERVED_SZ 0x0040 - -/* - * RSS configuration (0x0100 - 0x01ac): - * Used only when NFP_NET_CFG_CTRL_RSS is enabled - * @NFP_NET_CFG_RSS_CFG: RSS configuration word - * @NFP_NET_CFG_RSS_KEY: RSS "secret" key - * @NFP_NET_CFG_RSS_ITBL: RSS indirection table - */ -#define NFP_NET_CFG_RSS_BASE 0x0100 -#define NFP_NET_CFG_RSS_CTRL NFP_NET_CFG_RSS_BASE -#define NFP_NET_CFG_RSS_MASK (0x7f) -#define NFP_NET_CFG_RSS_MASK_of(_x) ((_x) & 0x7f) -#define NFP_NET_CFG_RSS_IPV4 (1 << 8) /* RSS for IPv4 */ -#define NFP_NET_CFG_RSS_IPV6 (1 << 9) /* RSS for IPv6 */ -#define NFP_NET_CFG_RSS_IPV4_TCP (1 << 10) /* RSS for IPv4/TCP */ -#define NFP_NET_CFG_RSS_IPV4_UDP (1 << 11) /* RSS for IPv4/UDP */ -#define NFP_NET_CFG_RSS_IPV6_TCP (1 << 12) /* RSS for IPv6/TCP */ -#define NFP_NET_CFG_RSS_IPV6_UDP (1 << 13) /* RSS for IPv6/UDP */ -#define NFP_NET_CFG_RSS_TOEPLITZ (1 << 24) /* Use Toeplitz hash */ -#define NFP_NET_CFG_RSS_KEY (NFP_NET_CFG_RSS_BASE + 0x4) -#define NFP_NET_CFG_RSS_KEY_SZ 0x28 -#define NFP_NET_CFG_RSS_ITBL (NFP_NET_CFG_RSS_BASE + 0x4 + \ - NFP_NET_CFG_RSS_KEY_SZ) -#define NFP_NET_CFG_RSS_ITBL_SZ 0x80 - -/* - * TX ring configuration (0x200 - 0x800) - * @NFP_NET_CFG_TXR_BASE: Base offset for TX ring configuration - * @NFP_NET_CFG_TXR_ADDR: Per TX ring DMA address (8B entries) - * @NFP_NET_CFG_TXR_WB_ADDR: Per TX ring write back DMA address (8B entries) - * @NFP_NET_CFG_TXR_SZ: Per TX ring ring size (1B entries) - * @NFP_NET_CFG_TXR_VEC: Per TX ring MSI-X table entry (1B entries) - * @NFP_NET_CFG_TXR_PRIO: Per TX ring priority (1B entries) - * @NFP_NET_CFG_TXR_IRQ_MOD: Per TX ring interrupt moderation (4B entries) - */ -#define NFP_NET_CFG_TXR_BASE 0x0200 -#define NFP_NET_CFG_TXR_ADDR(_x) (NFP_NET_CFG_TXR_BASE + ((_x) * 0x8)) -#define NFP_NET_CFG_TXR_WB_ADDR(_x) (NFP_NET_CFG_TXR_BASE + 0x200 + \ - ((_x) * 0x8)) -#define NFP_NET_CFG_TXR_SZ(_x) (NFP_NET_CFG_TXR_BASE + 0x400 + (_x)) -#define NFP_NET_CFG_TXR_VEC(_x) (NFP_NET_CFG_TXR_BASE + 0x440 + (_x)) -#define NFP_NET_CFG_TXR_PRIO(_x) (NFP_NET_CFG_TXR_BASE + 0x480 + (_x)) -#define NFP_NET_CFG_TXR_IRQ_MOD(_x) (NFP_NET_CFG_TXR_BASE + 0x500 + \ - ((_x) * 0x4)) - -/* - * RX ring configuration (0x0800 - 0x0c00) - * @NFP_NET_CFG_RXR_BASE: Base offset for RX ring configuration - * @NFP_NET_CFG_RXR_ADDR: Per TX ring DMA address (8B entries) - * @NFP_NET_CFG_RXR_SZ: Per TX ring ring size (1B entries) - * @NFP_NET_CFG_RXR_VEC: Per TX ring MSI-X table entry (1B entries) - * @NFP_NET_CFG_RXR_PRIO: Per TX ring priority (1B entries) - * @NFP_NET_CFG_RXR_IRQ_MOD: Per TX ring interrupt moderation (4B entries) - */ -#define NFP_NET_CFG_RXR_BASE 0x0800 -#define NFP_NET_CFG_RXR_ADDR(_x) (NFP_NET_CFG_RXR_BASE + ((_x) * 0x8)) -#define NFP_NET_CFG_RXR_SZ(_x) (NFP_NET_CFG_RXR_BASE + 0x200 + (_x)) -#define NFP_NET_CFG_RXR_VEC(_x) (NFP_NET_CFG_RXR_BASE + 0x240 + (_x)) -#define NFP_NET_CFG_RXR_PRIO(_x) (NFP_NET_CFG_RXR_BASE + 0x280 + (_x)) -#define NFP_NET_CFG_RXR_IRQ_MOD(_x) (NFP_NET_CFG_RXR_BASE + 0x300 + \ - ((_x) * 0x4)) - -/* - * Interrupt Control/Cause registers (0x0c00 - 0x0d00) - * These registers are only used when MSI-X auto-masking is not - * enabled (@NFP_NET_CFG_CTRL_MSIXAUTO not set). The array is index - * by MSI-X entry and are 1B in size. If an entry is zero, the - * corresponding entry is enabled. If the FW generates an interrupt, - * it writes a cause into the corresponding field. This also masks - * the MSI-X entry and the host driver must clear the register to - * re-enable the interrupt. - */ -#define NFP_NET_CFG_ICR_BASE 0x0c00 -#define NFP_NET_CFG_ICR(_x) (NFP_NET_CFG_ICR_BASE + (_x)) -#define NFP_NET_CFG_ICR_UNMASKED 0x0 -#define NFP_NET_CFG_ICR_RXTX 0x1 -#define NFP_NET_CFG_ICR_LSC 0x2 - -/* - * General device stats (0x0d00 - 0x0d90) - * all counters are 64bit. - */ -#define NFP_NET_CFG_STATS_BASE 0x0d00 -#define NFP_NET_CFG_STATS_RX_DISCARDS (NFP_NET_CFG_STATS_BASE + 0x00) -#define NFP_NET_CFG_STATS_RX_ERRORS (NFP_NET_CFG_STATS_BASE + 0x08) -#define NFP_NET_CFG_STATS_RX_OCTETS (NFP_NET_CFG_STATS_BASE + 0x10) -#define NFP_NET_CFG_STATS_RX_UC_OCTETS (NFP_NET_CFG_STATS_BASE + 0x18) -#define NFP_NET_CFG_STATS_RX_MC_OCTETS (NFP_NET_CFG_STATS_BASE + 0x20) -#define NFP_NET_CFG_STATS_RX_BC_OCTETS (NFP_NET_CFG_STATS_BASE + 0x28) -#define NFP_NET_CFG_STATS_RX_FRAMES (NFP_NET_CFG_STATS_BASE + 0x30) -#define NFP_NET_CFG_STATS_RX_MC_FRAMES (NFP_NET_CFG_STATS_BASE + 0x38) -#define NFP_NET_CFG_STATS_RX_BC_FRAMES (NFP_NET_CFG_STATS_BASE + 0x40) - -#define NFP_NET_CFG_STATS_TX_DISCARDS (NFP_NET_CFG_STATS_BASE + 0x48) -#define NFP_NET_CFG_STATS_TX_ERRORS (NFP_NET_CFG_STATS_BASE + 0x50) -#define NFP_NET_CFG_STATS_TX_OCTETS (NFP_NET_CFG_STATS_BASE + 0x58) -#define NFP_NET_CFG_STATS_TX_UC_OCTETS (NFP_NET_CFG_STATS_BASE + 0x60) -#define NFP_NET_CFG_STATS_TX_MC_OCTETS (NFP_NET_CFG_STATS_BASE + 0x68) -#define NFP_NET_CFG_STATS_TX_BC_OCTETS (NFP_NET_CFG_STATS_BASE + 0x70) -#define NFP_NET_CFG_STATS_TX_FRAMES (NFP_NET_CFG_STATS_BASE + 0x78) -#define NFP_NET_CFG_STATS_TX_MC_FRAMES (NFP_NET_CFG_STATS_BASE + 0x80) -#define NFP_NET_CFG_STATS_TX_BC_FRAMES (NFP_NET_CFG_STATS_BASE + 0x88) - -/* - * Per ring stats (0x1000 - 0x1800) - * options, 64bit per entry - * @NFP_NET_CFG_TXR_STATS: TX ring statistics (Packet and Byte count) - * @NFP_NET_CFG_RXR_STATS: RX ring statistics (Packet and Byte count) - */ -#define NFP_NET_CFG_TXR_STATS_BASE 0x1000 -#define NFP_NET_CFG_TXR_STATS(_x) (NFP_NET_CFG_TXR_STATS_BASE + \ - ((_x) * 0x10)) -#define NFP_NET_CFG_RXR_STATS_BASE 0x1400 -#define NFP_NET_CFG_RXR_STATS(_x) (NFP_NET_CFG_RXR_STATS_BASE + \ - ((_x) * 0x10)) - -/* PF multiport offset */ -#define NFP_PF_CSR_SLICE_SIZE (32 * 1024) - -#endif /* _NFP_NET_CTRL_H_ */ -/* - * Local variables: - * c-file-style: "Linux" - * indent-tabs-mode: t - * End: - */ diff --git a/drivers/net/nfp/nfp_net_logs.h b/drivers/net/nfp/nfp_net_logs.h deleted file mode 100644 index 76cc94cb65..0000000000 --- a/drivers/net/nfp/nfp_net_logs.h +++ /dev/null @@ -1,40 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright (c) 2014, 2015 Netronome Systems, Inc. - * All rights reserved. - */ - -#ifndef _NFP_NET_LOGS_H_ -#define _NFP_NET_LOGS_H_ - -#include - -extern int nfp_logtype_init; -#define PMD_INIT_LOG(level, fmt, args...) \ - rte_log(RTE_LOG_ ## level, nfp_logtype_init, \ - "%s(): " fmt "\n", __func__, ## args) -#define PMD_INIT_FUNC_TRACE() PMD_INIT_LOG(DEBUG, " >>") - -#ifdef RTE_LIBRTE_NFP_NET_DEBUG_RX -#define PMD_RX_LOG(level, fmt, args...) \ - RTE_LOG(level, PMD, "%s() rx: " fmt "\n", __func__, ## args) -#else -#define PMD_RX_LOG(level, fmt, args...) do { } while (0) -#endif - -#ifdef RTE_LIBRTE_NFP_NET_DEBUG_TX -#define PMD_TX_LOG(level, fmt, args...) \ - RTE_LOG(level, PMD, "%s() tx: " fmt "\n", __func__, ## args) -#define ASSERT(x) if (!(x)) rte_panic("NFP_NET: x") -#else -#define PMD_TX_LOG(level, fmt, args...) do { } while (0) -#define ASSERT(x) do { } while (0) -#endif - -#define PMD_CPP_LOG(level, fmt, args...) do { } while (0) - -extern int nfp_logtype_driver; -#define PMD_DRV_LOG(level, fmt, args...) \ - rte_log(RTE_LOG_ ## level, nfp_logtype_driver, \ - "%s(): " fmt "\n", __func__, ## args) - -#endif /* _NFP_NET_LOGS_H_ */ diff --git a/drivers/net/nfp/nfp_net_pmd.h b/drivers/net/nfp/nfp_net_pmd.h deleted file mode 100644 index 3c5e1868a4..0000000000 --- a/drivers/net/nfp/nfp_net_pmd.h +++ /dev/null @@ -1,405 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright (c) 2014-2018 Netronome Systems, Inc. - * All rights reserved. - */ - -/* - * vim:shiftwidth=8:noexpandtab - * - * @file dpdk/pmd/nfp_net_pmd.h - * - * Netronome NFP_NET PMD driver - */ - -#ifndef _NFP_NET_PMD_H_ -#define _NFP_NET_PMD_H_ - -#define NFP_NET_PMD_VERSION "0.1" -#define PCI_VENDOR_ID_NETRONOME 0x19ee -#define PCI_DEVICE_ID_NFP4000_PF_NIC 0x4000 -#define PCI_DEVICE_ID_NFP6000_PF_NIC 0x6000 -#define PCI_DEVICE_ID_NFP6000_VF_NIC 0x6003 - -/* Forward declaration */ -struct nfp_net_adapter; - -#define NFP_TX_MAX_SEG UINT8_MAX -#define NFP_TX_MAX_MTU_SEG 8 - -/* Bar allocation */ -#define NFP_NET_CRTL_BAR 0 -#define NFP_NET_TX_BAR 2 -#define NFP_NET_RX_BAR 2 -#define NFP_QCP_QUEUE_AREA_SZ 0x80000 - -/* Macros for accessing the Queue Controller Peripheral 'CSRs' */ -#define NFP_QCP_QUEUE_OFF(_x) ((_x) * 0x800) -#define NFP_QCP_QUEUE_ADD_RPTR 0x0000 -#define NFP_QCP_QUEUE_ADD_WPTR 0x0004 -#define NFP_QCP_QUEUE_STS_LO 0x0008 -#define NFP_QCP_QUEUE_STS_LO_READPTR_mask (0x3ffff) -#define NFP_QCP_QUEUE_STS_HI 0x000c -#define NFP_QCP_QUEUE_STS_HI_WRITEPTR_mask (0x3ffff) - -/* The offset of the queue controller queues in the PCIe Target */ -#define NFP_PCIE_QUEUE(_q) (0x80000 + (NFP_QCP_QUEUE_ADDR_SZ * ((_q) & 0xff))) - -/* Maximum value which can be added to a queue with one transaction */ -#define NFP_QCP_MAX_ADD 0x7f - -/* Interrupt definitions */ -#define NFP_NET_IRQ_LSC_IDX 0 - -/* Default values for RX/TX configuration */ -#define DEFAULT_RX_FREE_THRESH 32 -#define DEFAULT_RX_PTHRESH 8 -#define DEFAULT_RX_HTHRESH 8 -#define DEFAULT_RX_WTHRESH 0 - -#define DEFAULT_TX_RS_THRESH 32 -#define DEFAULT_TX_FREE_THRESH 32 -#define DEFAULT_TX_PTHRESH 32 -#define DEFAULT_TX_HTHRESH 0 -#define DEFAULT_TX_WTHRESH 0 -#define DEFAULT_TX_RSBIT_THRESH 32 - -/* Alignment for dma zones */ -#define NFP_MEMZONE_ALIGN 128 - -/* - * This is used by the reconfig protocol. It sets the maximum time waiting in - * milliseconds before a reconfig timeout happens. - */ -#define NFP_NET_POLL_TIMEOUT 5000 - -#define NFP_QCP_QUEUE_ADDR_SZ (0x800) - -#define NFP_NET_LINK_DOWN_CHECK_TIMEOUT 4000 /* ms */ -#define NFP_NET_LINK_UP_CHECK_TIMEOUT 1000 /* ms */ - -/* Version number helper defines */ -#define NFD_CFG_CLASS_VER_msk 0xff -#define NFD_CFG_CLASS_VER_shf 24 -#define NFD_CFG_CLASS_VER(x) (((x) & 0xff) << 24) -#define NFD_CFG_CLASS_VER_of(x) (((x) >> 24) & 0xff) -#define NFD_CFG_CLASS_TYPE_msk 0xff -#define NFD_CFG_CLASS_TYPE_shf 16 -#define NFD_CFG_CLASS_TYPE(x) (((x) & 0xff) << 16) -#define NFD_CFG_CLASS_TYPE_of(x) (((x) >> 16) & 0xff) -#define NFD_CFG_MAJOR_VERSION_msk 0xff -#define NFD_CFG_MAJOR_VERSION_shf 8 -#define NFD_CFG_MAJOR_VERSION(x) (((x) & 0xff) << 8) -#define NFD_CFG_MAJOR_VERSION_of(x) (((x) >> 8) & 0xff) -#define NFD_CFG_MINOR_VERSION_msk 0xff -#define NFD_CFG_MINOR_VERSION_shf 0 -#define NFD_CFG_MINOR_VERSION(x) (((x) & 0xff) << 0) -#define NFD_CFG_MINOR_VERSION_of(x) (((x) >> 0) & 0xff) - -/* Number of supported physical ports */ -#define NFP_MAX_PHYPORTS 12 - -#include -#include - -/* nfp_qcp_ptr - Read or Write Pointer of a queue */ -enum nfp_qcp_ptr { - NFP_QCP_READ_PTR = 0, - NFP_QCP_WRITE_PTR -}; - -struct nfp_pf_dev { - /* Backpointer to associated pci device */ - struct rte_pci_device *pci_dev; - - /* Array of physical ports belonging to this PF */ - struct nfp_net_hw *ports[NFP_MAX_PHYPORTS]; - - /* Current values for control */ - uint32_t ctrl; - - uint8_t *ctrl_bar; - uint8_t *tx_bar; - uint8_t *rx_bar; - - uint8_t *qcp_cfg; - rte_spinlock_t reconfig_lock; - - uint16_t flbufsz; - uint16_t device_id; - uint16_t vendor_id; - uint16_t subsystem_device_id; - uint16_t subsystem_vendor_id; -#if defined(DSTQ_SELECTION) -#if DSTQ_SELECTION - uint16_t device_function; -#endif -#endif - - struct nfp_cpp *cpp; - struct nfp_cpp_area *ctrl_area; - struct nfp_cpp_area *hwqueues_area; - struct nfp_cpp_area *msix_area; - - uint8_t *hw_queues; - uint8_t total_phyports; - bool multiport; - - union eth_table_entry *eth_table; - - struct nfp_hwinfo *hwinfo; - struct nfp_rtsym_table *sym_tbl; - uint32_t nfp_cpp_service_id; -}; - -struct nfp_net_hw { - /* Backpointer to the PF this port belongs to */ - struct nfp_pf_dev *pf_dev; - - /* Backpointer to the eth_dev of this port*/ - struct rte_eth_dev *eth_dev; - - /* Info from the firmware */ - uint32_t ver; - uint32_t cap; - uint32_t max_mtu; - uint32_t mtu; - uint32_t rx_offset; - - /* Current values for control */ - uint32_t ctrl; - - uint8_t *ctrl_bar; - uint8_t *tx_bar; - uint8_t *rx_bar; - - int stride_rx; - int stride_tx; - - uint8_t *qcp_cfg; - rte_spinlock_t reconfig_lock; - - uint32_t max_tx_queues; - uint32_t max_rx_queues; - uint16_t flbufsz; - uint16_t device_id; - uint16_t vendor_id; - uint16_t subsystem_device_id; - uint16_t subsystem_vendor_id; -#if defined(DSTQ_SELECTION) -#if DSTQ_SELECTION - uint16_t device_function; -#endif -#endif - - uint8_t mac_addr[RTE_ETHER_ADDR_LEN]; - - /* Records starting point for counters */ - struct rte_eth_stats eth_stats_base; - - struct nfp_cpp *cpp; - struct nfp_cpp_area *ctrl_area; - struct nfp_cpp_area *hwqueues_area; - struct nfp_cpp_area *msix_area; - - uint8_t *hw_queues; - /* Sequential physical port number */ - uint8_t idx; - /* Internal port number as seen from NFP */ - uint8_t nfp_idx; - bool is_phyport; - - union eth_table_entry *eth_table; - - uint32_t nfp_cpp_service_id; -}; - -struct nfp_net_adapter { - struct nfp_net_hw hw; -}; - -static inline uint8_t nn_readb(volatile const void *addr) -{ - return rte_read8(addr); -} - -static inline void nn_writeb(uint8_t val, volatile void *addr) -{ - rte_write8(val, addr); -} - -static inline uint32_t nn_readl(volatile const void *addr) -{ - return rte_read32(addr); -} - -static inline void nn_writel(uint32_t val, volatile void *addr) -{ - rte_write32(val, addr); -} - -static inline void nn_writew(uint16_t val, volatile void *addr) -{ - rte_write16(val, addr); -} - -static inline uint64_t nn_readq(volatile void *addr) -{ - const volatile uint32_t *p = addr; - uint32_t low, high; - - high = nn_readl((volatile const void *)(p + 1)); - low = nn_readl((volatile const void *)p); - - return low + ((uint64_t)high << 32); -} - -static inline void nn_writeq(uint64_t val, volatile void *addr) -{ - nn_writel(val >> 32, (volatile char *)addr + 4); - nn_writel(val, addr); -} - -/* - * Functions to read/write from/to Config BAR - * Performs any endian conversion necessary. - */ -static inline uint8_t -nn_cfg_readb(struct nfp_net_hw *hw, int off) -{ - return nn_readb(hw->ctrl_bar + off); -} - -static inline void -nn_cfg_writeb(struct nfp_net_hw *hw, int off, uint8_t val) -{ - nn_writeb(val, hw->ctrl_bar + off); -} - -static inline uint32_t -nn_cfg_readl(struct nfp_net_hw *hw, int off) -{ - return rte_le_to_cpu_32(nn_readl(hw->ctrl_bar + off)); -} - -static inline void -nn_cfg_writel(struct nfp_net_hw *hw, int off, uint32_t val) -{ - nn_writel(rte_cpu_to_le_32(val), hw->ctrl_bar + off); -} - -static inline uint64_t -nn_cfg_readq(struct nfp_net_hw *hw, int off) -{ - return rte_le_to_cpu_64(nn_readq(hw->ctrl_bar + off)); -} - -static inline void -nn_cfg_writeq(struct nfp_net_hw *hw, int off, uint64_t val) -{ - nn_writeq(rte_cpu_to_le_64(val), hw->ctrl_bar + off); -} - -/* - * nfp_qcp_ptr_add - Add the value to the selected pointer of a queue - * @q: Base address for queue structure - * @ptr: Add to the Read or Write pointer - * @val: Value to add to the queue pointer - * - * If @val is greater than @NFP_QCP_MAX_ADD multiple writes are performed. - */ -static inline void -nfp_qcp_ptr_add(uint8_t *q, enum nfp_qcp_ptr ptr, uint32_t val) -{ - uint32_t off; - - if (ptr == NFP_QCP_READ_PTR) - off = NFP_QCP_QUEUE_ADD_RPTR; - else - off = NFP_QCP_QUEUE_ADD_WPTR; - - while (val > NFP_QCP_MAX_ADD) { - nn_writel(rte_cpu_to_le_32(NFP_QCP_MAX_ADD), q + off); - val -= NFP_QCP_MAX_ADD; -} - -nn_writel(rte_cpu_to_le_32(val), q + off); -} - -/* - * nfp_qcp_read - Read the current Read/Write pointer value for a queue - * @q: Base address for queue structure - * @ptr: Read or Write pointer - */ -static inline uint32_t -nfp_qcp_read(uint8_t *q, enum nfp_qcp_ptr ptr) -{ - uint32_t off; - uint32_t val; - - if (ptr == NFP_QCP_READ_PTR) - off = NFP_QCP_QUEUE_STS_LO; - else - off = NFP_QCP_QUEUE_STS_HI; - - val = rte_cpu_to_le_32(nn_readl(q + off)); - - if (ptr == NFP_QCP_READ_PTR) - return val & NFP_QCP_QUEUE_STS_LO_READPTR_mask; - else - return val & NFP_QCP_QUEUE_STS_HI_WRITEPTR_mask; -} - -/* Prototypes for common NFP functions */ -int nfp_net_reconfig(struct nfp_net_hw *hw, uint32_t ctrl, uint32_t update); -int nfp_net_configure(struct rte_eth_dev *dev); -void nfp_net_enable_queues(struct rte_eth_dev *dev); -void nfp_net_disable_queues(struct rte_eth_dev *dev); -void nfp_net_params_setup(struct nfp_net_hw *hw); -void nfp_eth_copy_mac(uint8_t *dst, const uint8_t *src); -void nfp_net_write_mac(struct nfp_net_hw *hw, uint8_t *mac); -int nfp_set_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr); -int nfp_configure_rx_interrupt(struct rte_eth_dev *dev, - struct rte_intr_handle *intr_handle); -uint32_t nfp_check_offloads(struct rte_eth_dev *dev); -int nfp_net_promisc_enable(struct rte_eth_dev *dev); -int nfp_net_promisc_disable(struct rte_eth_dev *dev); -int nfp_net_link_update(struct rte_eth_dev *dev, - __rte_unused int wait_to_complete); -int nfp_net_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats); -int nfp_net_stats_reset(struct rte_eth_dev *dev); -int nfp_net_infos_get(struct rte_eth_dev *dev, - struct rte_eth_dev_info *dev_info); -const uint32_t *nfp_net_supported_ptypes_get(struct rte_eth_dev *dev); -int nfp_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id); -int nfp_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id); -void nfp_net_params_setup(struct nfp_net_hw *hw); -void nfp_net_cfg_queue_setup(struct nfp_net_hw *hw); -void nfp_eth_copy_mac(uint8_t *dst, const uint8_t *src); -void nfp_net_dev_interrupt_handler(void *param); -int nfp_net_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu); -int nfp_net_vlan_offload_set(struct rte_eth_dev *dev, int mask); -int nfp_net_reta_update(struct rte_eth_dev *dev, - struct rte_eth_rss_reta_entry64 *reta_conf, - uint16_t reta_size); -int nfp_net_reta_query(struct rte_eth_dev *dev, - struct rte_eth_rss_reta_entry64 *reta_conf, - uint16_t reta_size); -int nfp_net_rss_hash_update(struct rte_eth_dev *dev, - struct rte_eth_rss_conf *rss_conf); -int nfp_net_rss_hash_conf_get(struct rte_eth_dev *dev, - struct rte_eth_rss_conf *rss_conf); -int nfp_net_rss_config_default(struct rte_eth_dev *dev); - -#define NFP_NET_DEV_PRIVATE_TO_HW(adapter)\ - (&((struct nfp_net_adapter *)adapter)->hw) - -#define NFP_NET_DEV_PRIVATE_TO_PF(dev_priv)\ - (((struct nfp_net_hw *)dev_priv)->pf_dev) - -#endif /* _NFP_NET_PMD_H_ */ -/* - * Local variables: - * c-file-style: "Linux" - * indent-tabs-mode: t - * End: - */ diff --git a/drivers/net/nfp/nfp_rxtx.c b/drivers/net/nfp/nfp_rxtx.c index 9ee9e5c9a3..1402c5f84a 100644 --- a/drivers/net/nfp/nfp_rxtx.c +++ b/drivers/net/nfp/nfp_rxtx.c @@ -16,10 +16,10 @@ #include #include -#include "nfp_net_pmd.h" +#include "nfp_common.h" #include "nfp_rxtx.h" -#include "nfp_net_logs.h" -#include "nfp_net_ctrl.h" +#include "nfp_logs.h" +#include "nfp_ctrl.h" /* Prototypes */ static int nfp_net_rx_fill_freelist(struct nfp_net_rxq *rxq);