X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fnfp%2Fnfp_net_pmd.h;h=3c5e1868a451ce4fc0eced7c0243bc1472880771;hb=7f8e73201dae6e605df6a9cdc24d9004b2590424;hp=d7e38d4fd9a18485712fc7f22b3ea498a20468ed;hpb=c4171b520b3fc84913aa5c22490167f5c47a2d80;p=dpdk.git diff --git a/drivers/net/nfp/nfp_net_pmd.h b/drivers/net/nfp/nfp_net_pmd.h index d7e38d4fd9..3c5e1868a4 100644 --- a/drivers/net/nfp/nfp_net_pmd.h +++ b/drivers/net/nfp/nfp_net_pmd.h @@ -1,32 +1,6 @@ -/* - * Copyright (c) 2014, 2015 Netronome Systems, Inc. +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2014-2018 Netronome Systems, Inc. * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ /* @@ -34,7 +8,7 @@ * * @file dpdk/pmd/nfp_net_pmd.h * - * Netronome NFP_NET PDM driver + * Netronome NFP_NET PMD driver */ #ifndef _NFP_NET_PMD_H_ @@ -49,20 +23,14 @@ /* Forward declaration */ struct nfp_net_adapter; -/* - * The maximum number of descriptors is limited by design as - * DPDK uses uint16_t variables for these values - */ -#define NFP_NET_MAX_TX_DESC (32 * 1024) -#define NFP_NET_MIN_TX_DESC 64 - -#define NFP_NET_MAX_RX_DESC (32 * 1024) -#define NFP_NET_MIN_RX_DESC 64 +#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) @@ -73,6 +41,12 @@ struct nfp_net_adapter; #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 @@ -121,277 +95,69 @@ struct nfp_net_adapter; #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 -static inline uint8_t nn_readb(volatile const void *addr) -{ - return rte_read8(addr); -} +/* nfp_qcp_ptr - Read or Write Pointer of a queue */ +enum nfp_qcp_ptr { + NFP_QCP_READ_PTR = 0, + NFP_QCP_WRITE_PTR +}; -static inline void nn_writeb(uint8_t val, volatile void *addr) -{ - rte_write8(val, addr); -} +struct nfp_pf_dev { + /* Backpointer to associated pci device */ + struct rte_pci_device *pci_dev; -static inline uint32_t nn_readl(volatile const void *addr) -{ - return rte_read32(addr); -} + /* Array of physical ports belonging to this PF */ + struct nfp_net_hw *ports[NFP_MAX_PHYPORTS]; -static inline void nn_writel(uint32_t val, volatile void *addr) -{ - rte_write32(val, addr); -} + /* Current values for control */ + uint32_t ctrl; -static inline void nn_writew(uint16_t val, volatile void *addr) -{ - rte_write16(val, addr); -} + uint8_t *ctrl_bar; + uint8_t *tx_bar; + uint8_t *rx_bar; -static inline uint64_t nn_readq(volatile void *addr) -{ - const volatile uint32_t *p = addr; - uint32_t low, high; + uint8_t *qcp_cfg; + rte_spinlock_t reconfig_lock; - high = nn_readl((volatile const void *)(p + 1)); - low = nn_readl((volatile const void *)p); + 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 - return low + ((uint64_t)high << 32); -} + struct nfp_cpp *cpp; + struct nfp_cpp_area *ctrl_area; + struct nfp_cpp_area *hwqueues_area; + struct nfp_cpp_area *msix_area; -static inline void nn_writeq(uint64_t val, volatile void *addr) -{ - nn_writel(val >> 32, (volatile char *)addr + 4); - nn_writel(val, addr); -} + uint8_t *hw_queues; + uint8_t total_phyports; + bool multiport; -/* TX descriptor format */ -#define PCIE_DESC_TX_EOP (1 << 7) -#define PCIE_DESC_TX_OFFSET_MASK (0x7f) - -/* Flags in the host TX descriptor */ -#define PCIE_DESC_TX_CSUM (1 << 7) -#define PCIE_DESC_TX_IP4_CSUM (1 << 6) -#define PCIE_DESC_TX_TCP_CSUM (1 << 5) -#define PCIE_DESC_TX_UDP_CSUM (1 << 4) -#define PCIE_DESC_TX_VLAN (1 << 3) -#define PCIE_DESC_TX_LSO (1 << 2) -#define PCIE_DESC_TX_ENCAP_NONE (0) -#define PCIE_DESC_TX_ENCAP_VXLAN (1 << 1) -#define PCIE_DESC_TX_ENCAP_GRE (1 << 0) - -struct nfp_net_tx_desc { - union { - struct { - uint8_t dma_addr_hi; /* High bits of host buf address */ - __le16 dma_len; /* Length to DMA for this desc */ - uint8_t offset_eop; /* Offset in buf where pkt starts + - * highest bit is eop flag. - */ - __le32 dma_addr_lo; /* Low 32bit of host buf addr */ - - __le16 lso; /* MSS to be used for LSO */ - uint8_t l4_offset; /* LSO, where the L4 data starts */ - uint8_t flags; /* TX Flags, see @PCIE_DESC_TX_* */ - - __le16 vlan; /* VLAN tag to add if indicated */ - __le16 data_len; /* Length of frame + meta data */ - } __attribute__((__packed__)); - __le32 vals[4]; - }; -}; + union eth_table_entry *eth_table; -struct nfp_net_txq { - struct nfp_net_hw *hw; /* Backpointer to nfp_net structure */ - - /* - * Queue information: @qidx is the queue index from Linux's - * perspective. @tx_qcidx is the index of the Queue - * Controller Peripheral queue relative to the TX queue BAR. - * @cnt is the size of the queue in number of - * descriptors. @qcp_q is a pointer to the base of the queue - * structure on the NFP - */ - uint8_t *qcp_q; - - /* - * Read and Write pointers. @wr_p and @rd_p are host side pointer, - * they are free running and have little relation to the QCP pointers * - * @qcp_rd_p is a local copy queue controller peripheral read pointer - */ - - uint32_t wr_p; - uint32_t rd_p; - - uint32_t tx_count; - - uint32_t tx_free_thresh; - - /* - * For each descriptor keep a reference to the mbuff and - * DMA address used until completion is signalled. - */ - struct { - struct rte_mbuf *mbuf; - } *txbufs; - - /* - * Information about the host side queue location. @txds is - * the virtual address for the queue, @dma is the DMA address - * of the queue and @size is the size in bytes for the queue - * (needed for free) - */ - struct nfp_net_tx_desc *txds; - - /* - * At this point 48 bytes have been used for all the fields in the - * TX critical path. We have room for 8 bytes and still all placed - * in a cache line. We are not using the threshold values below nor - * the txq_flags but if we need to, we can add the most used in the - * remaining bytes. - */ - uint32_t tx_rs_thresh; /* not used by now. Future? */ - uint32_t tx_pthresh; /* not used by now. Future? */ - uint32_t tx_hthresh; /* not used by now. Future? */ - uint32_t tx_wthresh; /* not used by now. Future? */ - uint32_t txq_flags; /* not used by now. Future? */ - uint8_t port_id; - int qidx; - int tx_qcidx; - __le64 dma; -} __attribute__ ((__aligned__(64))); - -/* RX and freelist descriptor format */ -#define PCIE_DESC_RX_DD (1 << 7) -#define PCIE_DESC_RX_META_LEN_MASK (0x7f) - -/* Flags in the RX descriptor */ -#define PCIE_DESC_RX_RSS (1 << 15) -#define PCIE_DESC_RX_I_IP4_CSUM (1 << 14) -#define PCIE_DESC_RX_I_IP4_CSUM_OK (1 << 13) -#define PCIE_DESC_RX_I_TCP_CSUM (1 << 12) -#define PCIE_DESC_RX_I_TCP_CSUM_OK (1 << 11) -#define PCIE_DESC_RX_I_UDP_CSUM (1 << 10) -#define PCIE_DESC_RX_I_UDP_CSUM_OK (1 << 9) -#define PCIE_DESC_RX_SPARE (1 << 8) -#define PCIE_DESC_RX_EOP (1 << 7) -#define PCIE_DESC_RX_IP4_CSUM (1 << 6) -#define PCIE_DESC_RX_IP4_CSUM_OK (1 << 5) -#define PCIE_DESC_RX_TCP_CSUM (1 << 4) -#define PCIE_DESC_RX_TCP_CSUM_OK (1 << 3) -#define PCIE_DESC_RX_UDP_CSUM (1 << 2) -#define PCIE_DESC_RX_UDP_CSUM_OK (1 << 1) -#define PCIE_DESC_RX_VLAN (1 << 0) - -struct nfp_net_rx_desc { - union { - /* Freelist descriptor */ - struct { - uint8_t dma_addr_hi; - __le16 spare; - uint8_t dd; - - __le32 dma_addr_lo; - } __attribute__((__packed__)) fld; - - /* RX descriptor */ - struct { - __le16 data_len; - uint8_t reserved; - uint8_t meta_len_dd; - - __le16 flags; - __le16 vlan; - } __attribute__((__packed__)) rxd; - - __le32 vals[2]; - }; + struct nfp_hwinfo *hwinfo; + struct nfp_rtsym_table *sym_tbl; + uint32_t nfp_cpp_service_id; }; -struct nfp_net_rx_buff { - struct rte_mbuf *mbuf; -}; +struct nfp_net_hw { + /* Backpointer to the PF this port belongs to */ + struct nfp_pf_dev *pf_dev; -struct nfp_net_rxq { - struct nfp_net_hw *hw; /* Backpointer to nfp_net structure */ - - /* - * @qcp_fl and @qcp_rx are pointers to the base addresses of the - * freelist and RX queue controller peripheral queue structures on the - * NFP - */ - uint8_t *qcp_fl; - uint8_t *qcp_rx; - - /* - * Read and Write pointers. @wr_p and @rd_p are host side - * pointer, they are free running and have little relation to - * the QCP pointers. @wr_p is where the driver adds new - * freelist descriptors and @rd_p is where the driver start - * reading descriptors for newly arrive packets from. - */ - uint32_t rd_p; - - /* - * For each buffer placed on the freelist, record the - * associated SKB - */ - struct nfp_net_rx_buff *rxbufs; - - /* - * Information about the host side queue location. @rxds is - * the virtual address for the queue - */ - struct nfp_net_rx_desc *rxds; - - /* - * The mempool is created by the user specifying a mbuf size. - * We save here the reference of the mempool needed in the RX - * path and the mbuf size for checking received packets can be - * safely copied to the mbuf using the NFP_NET_RX_OFFSET - */ - struct rte_mempool *mem_pool; - uint16_t mbuf_size; - - /* - * Next two fields are used for giving more free descriptors - * to the NFP - */ - uint16_t rx_free_thresh; - uint16_t nb_rx_hold; - - /* the size of the queue in number of descriptors */ - uint16_t rx_count; - - /* - * Fields above this point fit in a single cache line and are all used - * in the RX critical path. Fields below this point are just used - * during queue configuration or not used at all (yet) - */ - - /* referencing dev->data->port_id */ - uint16_t port_id; - - uint8_t crc_len; /* Not used by now */ - uint8_t drop_en; /* Not used by now */ - - /* DMA address of the queue */ - __le64 dma; - - /* - * Queue information: @qidx is the queue index from Linux's - * perspective. @fl_qcidx is the index of the Queue - * Controller peripheral queue relative to the RX queue BAR - * used for the freelist and @rx_qcidx is the Queue Controller - * Peripheral index for the RX queue. - */ - int qidx; - int fl_qcidx; - int rx_qcidx; -} __attribute__ ((__aligned__(64))); + /* Backpointer to the eth_dev of this port*/ + struct rte_eth_dev *eth_dev; -struct nfp_net_hw { /* Info from the firmware */ uint32_t ver; uint32_t cap; @@ -425,33 +191,211 @@ struct nfp_net_hw { #endif #endif - uint8_t mac_addr[ETHER_ADDR_LEN]; + uint8_t mac_addr[RTE_ETHER_ADDR_LEN]; /* Records starting point for counters */ struct rte_eth_stats eth_stats_base; -#ifdef NFP_NET_LIBNFP struct nfp_cpp *cpp; struct nfp_cpp_area *ctrl_area; - struct nfp_cpp_area *tx_area; - struct nfp_cpp_area *rx_area; + struct nfp_cpp_area *hwqueues_area; struct nfp_cpp_area *msix_area; -#endif + uint8_t *hw_queues; - uint8_t is_pf; - uint8_t pf_port_idx; - uint8_t pf_multiport_enabled; - nspu_desc_t *nspu_desc; - nfpu_desc_t *nfpu_desc; + /* 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: