diff options
Diffstat (limited to 'drivers/net/szedata2')
-rw-r--r-- | drivers/net/szedata2/Makefile | 1 | ||||
-rw-r--r-- | drivers/net/szedata2/rte_eth_szedata2.c | 128 | ||||
-rw-r--r-- | drivers/net/szedata2/rte_eth_szedata2.h | 344 | ||||
-rw-r--r-- | drivers/net/szedata2/szedata2_iobuf.c | 203 | ||||
-rw-r--r-- | drivers/net/szedata2/szedata2_iobuf.h | 356 |
5 files changed, 650 insertions, 382 deletions
diff --git a/drivers/net/szedata2/Makefile b/drivers/net/szedata2/Makefile index 836c3b2a..0e96b922 100644 --- a/drivers/net/szedata2/Makefile +++ b/drivers/net/szedata2/Makefile @@ -48,6 +48,7 @@ LIBABIVER := 1 # all source are stored in SRCS-y # SRCS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += rte_eth_szedata2.c +SRCS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += szedata2_iobuf.c # # Export include files diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c index 54212b71..9c0d57cc 100644 --- a/drivers/net/szedata2/rte_eth_szedata2.c +++ b/drivers/net/szedata2/rte_eth_szedata2.c @@ -53,6 +53,7 @@ #include <rte_atomic.h> #include "rte_eth_szedata2.h" +#include "szedata2_iobuf.h" #define RTE_ETH_SZEDATA2_MAX_RX_QUEUES 32 #define RTE_ETH_SZEDATA2_MAX_TX_QUEUES 32 @@ -64,7 +65,6 @@ #define RTE_SZE2_PACKET_HEADER_SIZE_ALIGNED 8 #define RTE_SZEDATA2_DRIVER_NAME net_szedata2 -#define RTE_SZEDATA2_PCI_DRIVER_NAME "rte_szedata2_pmd" #define SZEDATA2_DEV_PATH_FMT "/dev/szedataII%u" @@ -1032,7 +1032,7 @@ eth_dev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) { struct pmd_internals *internals = dev->data->dev_private; - dev_info->pci_dev = RTE_DEV_TO_PCI(dev->device); + dev_info->pci_dev = RTE_ETH_DEV_TO_PCI(dev); dev_info->if_index = 0; dev_info->max_mac_addrs = 1; dev_info->max_rx_pktlen = (uint32_t)-1; @@ -1140,6 +1140,33 @@ eth_dev_close(struct rte_eth_dev *dev) dev->data->nb_tx_queues = 0; } +/** + * Function takes value from first IBUF status register. + * Values in IBUF and OBUF should be same. + * + * @param internals + * Pointer to device private structure. + * @return + * Link speed constant. + */ +static inline enum szedata2_link_speed +get_link_speed(const struct pmd_internals *internals) +{ + const volatile struct szedata2_ibuf *ibuf = + ibuf_ptr_by_index(internals->pci_rsc, 0); + uint32_t speed = (szedata2_read32(&ibuf->ibuf_st) & 0x70) >> 4; + switch (speed) { + case 0x03: + return SZEDATA2_LINK_SPEED_10G; + case 0x04: + return SZEDATA2_LINK_SPEED_40G; + case 0x05: + return SZEDATA2_LINK_SPEED_100G; + default: + return SZEDATA2_LINK_SPEED_DEFAULT; + } +} + static int eth_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused) @@ -1149,11 +1176,11 @@ eth_link_update(struct rte_eth_dev *dev, struct rte_eth_link *dev_link = &dev->data->dev_link; struct pmd_internals *internals = (struct pmd_internals *) dev->data->dev_private; - volatile struct szedata2_cgmii_ibuf *ibuf = SZEDATA2_PCI_RESOURCE_PTR( - internals->pci_rsc, SZEDATA2_CGMII_IBUF_BASE_OFF, - volatile struct szedata2_cgmii_ibuf *); + const volatile struct szedata2_ibuf *ibuf; + uint32_t i; + bool link_is_up = false; - switch (cgmii_link_speed(ibuf)) { + switch (get_link_speed(internals)) { case SZEDATA2_LINK_SPEED_10G: link.link_speed = ETH_SPEED_NUM_10G; break; @@ -1171,8 +1198,19 @@ eth_link_update(struct rte_eth_dev *dev, /* szedata2 uses only full duplex */ link.link_duplex = ETH_LINK_FULL_DUPLEX; - link.link_status = (cgmii_ibuf_is_enabled(ibuf) && - cgmii_ibuf_is_link_up(ibuf)) ? ETH_LINK_UP : ETH_LINK_DOWN; + for (i = 0; i < szedata2_ibuf_count; i++) { + ibuf = ibuf_ptr_by_index(internals->pci_rsc, i); + /* + * Link is considered up if at least one ibuf is enabled + * and up. + */ + if (ibuf_is_enabled(ibuf) && ibuf_is_link_up(ibuf)) { + link_is_up = true; + break; + } + } + + link.link_status = (link_is_up) ? ETH_LINK_UP : ETH_LINK_DOWN; link.link_autoneg = ETH_LINK_SPEED_FIXED; @@ -1187,15 +1225,12 @@ eth_dev_set_link_up(struct rte_eth_dev *dev) { struct pmd_internals *internals = (struct pmd_internals *) dev->data->dev_private; - volatile struct szedata2_cgmii_ibuf *ibuf = SZEDATA2_PCI_RESOURCE_PTR( - internals->pci_rsc, SZEDATA2_CGMII_IBUF_BASE_OFF, - volatile struct szedata2_cgmii_ibuf *); - volatile struct szedata2_cgmii_obuf *obuf = SZEDATA2_PCI_RESOURCE_PTR( - internals->pci_rsc, SZEDATA2_CGMII_OBUF_BASE_OFF, - volatile struct szedata2_cgmii_obuf *); - - cgmii_ibuf_enable(ibuf); - cgmii_obuf_enable(obuf); + uint32_t i; + + for (i = 0; i < szedata2_ibuf_count; i++) + ibuf_enable(ibuf_ptr_by_index(internals->pci_rsc, i)); + for (i = 0; i < szedata2_obuf_count; i++) + obuf_enable(obuf_ptr_by_index(internals->pci_rsc, i)); return 0; } @@ -1204,15 +1239,12 @@ eth_dev_set_link_down(struct rte_eth_dev *dev) { struct pmd_internals *internals = (struct pmd_internals *) dev->data->dev_private; - volatile struct szedata2_cgmii_ibuf *ibuf = SZEDATA2_PCI_RESOURCE_PTR( - internals->pci_rsc, SZEDATA2_CGMII_IBUF_BASE_OFF, - volatile struct szedata2_cgmii_ibuf *); - volatile struct szedata2_cgmii_obuf *obuf = SZEDATA2_PCI_RESOURCE_PTR( - internals->pci_rsc, SZEDATA2_CGMII_OBUF_BASE_OFF, - volatile struct szedata2_cgmii_obuf *); - - cgmii_ibuf_disable(ibuf); - cgmii_obuf_disable(obuf); + uint32_t i; + + for (i = 0; i < szedata2_ibuf_count; i++) + ibuf_disable(ibuf_ptr_by_index(internals->pci_rsc, i)); + for (i = 0; i < szedata2_obuf_count; i++) + obuf_disable(obuf_ptr_by_index(internals->pci_rsc, i)); return 0; } @@ -1292,10 +1324,12 @@ eth_promiscuous_enable(struct rte_eth_dev *dev) { struct pmd_internals *internals = (struct pmd_internals *) dev->data->dev_private; - volatile struct szedata2_cgmii_ibuf *ibuf = SZEDATA2_PCI_RESOURCE_PTR( - internals->pci_rsc, SZEDATA2_CGMII_IBUF_BASE_OFF, - volatile struct szedata2_cgmii_ibuf *); - cgmii_ibuf_mac_mode_write(ibuf, SZEDATA2_MAC_CHMODE_PROMISC); + uint32_t i; + + for (i = 0; i < szedata2_ibuf_count; i++) { + ibuf_mac_mode_write(ibuf_ptr_by_index(internals->pci_rsc, i), + SZEDATA2_MAC_CHMODE_PROMISC); + } } static void @@ -1303,10 +1337,12 @@ eth_promiscuous_disable(struct rte_eth_dev *dev) { struct pmd_internals *internals = (struct pmd_internals *) dev->data->dev_private; - volatile struct szedata2_cgmii_ibuf *ibuf = SZEDATA2_PCI_RESOURCE_PTR( - internals->pci_rsc, SZEDATA2_CGMII_IBUF_BASE_OFF, - volatile struct szedata2_cgmii_ibuf *); - cgmii_ibuf_mac_mode_write(ibuf, SZEDATA2_MAC_CHMODE_ONLY_VALID); + uint32_t i; + + for (i = 0; i < szedata2_ibuf_count; i++) { + ibuf_mac_mode_write(ibuf_ptr_by_index(internals->pci_rsc, i), + SZEDATA2_MAC_CHMODE_ONLY_VALID); + } } static void @@ -1314,10 +1350,12 @@ eth_allmulticast_enable(struct rte_eth_dev *dev) { struct pmd_internals *internals = (struct pmd_internals *) dev->data->dev_private; - volatile struct szedata2_cgmii_ibuf *ibuf = SZEDATA2_PCI_RESOURCE_PTR( - internals->pci_rsc, SZEDATA2_CGMII_IBUF_BASE_OFF, - volatile struct szedata2_cgmii_ibuf *); - cgmii_ibuf_mac_mode_write(ibuf, SZEDATA2_MAC_CHMODE_ALL_MULTICAST); + uint32_t i; + + for (i = 0; i < szedata2_ibuf_count; i++) { + ibuf_mac_mode_write(ibuf_ptr_by_index(internals->pci_rsc, i), + SZEDATA2_MAC_CHMODE_ALL_MULTICAST); + } } static void @@ -1325,10 +1363,12 @@ eth_allmulticast_disable(struct rte_eth_dev *dev) { struct pmd_internals *internals = (struct pmd_internals *) dev->data->dev_private; - volatile struct szedata2_cgmii_ibuf *ibuf = SZEDATA2_PCI_RESOURCE_PTR( - internals->pci_rsc, SZEDATA2_CGMII_IBUF_BASE_OFF, - volatile struct szedata2_cgmii_ibuf *); - cgmii_ibuf_mac_mode_write(ibuf, SZEDATA2_MAC_CHMODE_ONLY_VALID); + uint32_t i; + + for (i = 0; i < szedata2_ibuf_count; i++) { + ibuf_mac_mode_write(ibuf_ptr_by_index(internals->pci_rsc, i), + SZEDATA2_MAC_CHMODE_ONLY_VALID); + } } static const struct eth_dev_ops ops = { @@ -1431,7 +1471,7 @@ rte_szedata2_eth_dev_init(struct rte_eth_dev *dev) struct szedata *szedata_temp; int ret; uint32_t szedata2_index; - struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device); + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); struct rte_pci_addr *pci_addr = &pci_dev->addr; struct rte_mem_resource *pci_rsc = &pci_dev->mem_resource[PCI_RESOURCE_NUMBER]; @@ -1554,7 +1594,7 @@ rte_szedata2_eth_dev_init(struct rte_eth_dev *dev) static int rte_szedata2_eth_dev_uninit(struct rte_eth_dev *dev) { - struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device); + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); struct rte_pci_addr *pci_addr = &pci_dev->addr; rte_free(dev->data->mac_addrs); diff --git a/drivers/net/szedata2/rte_eth_szedata2.h b/drivers/net/szedata2/rte_eth_szedata2.h index afe8a383..f25d4c59 100644 --- a/drivers/net/szedata2/rte_eth_szedata2.h +++ b/drivers/net/szedata2/rte_eth_szedata2.h @@ -34,9 +34,11 @@ #ifndef RTE_PMD_SZEDATA2_H_ #define RTE_PMD_SZEDATA2_H_ -#include <stdbool.h> +#include <stdint.h> -#include <rte_byteorder.h> +#include <libsze2.h> + +#include <rte_common.h> /* PCI Vendor ID */ #define PCI_VENDOR_ID_NETCOPE 0x1b26 @@ -58,7 +60,7 @@ * Round 'what' to the nearest larger (or equal) multiple of '8' * (szedata2 packet is aligned to 8 bytes) */ -#define RTE_SZE2_ALIGN8(what) (((what) + ((8) - 1)) & (~((8) - 1))) +#define RTE_SZE2_ALIGN8(what) RTE_ALIGN(what, 8) /*! main handle structure */ struct szedata { @@ -113,338 +115,4 @@ struct szedata { int numa_node; }; -/* - * @return Byte from PCI resource at offset "offset". - */ -static inline uint8_t -pci_resource_read8(struct rte_mem_resource *rsc, uint32_t offset) -{ - return *((uint8_t *)((uint8_t *)rsc->addr + offset)); -} - -/* - * @return Two bytes from PCI resource starting at offset "offset". - */ -static inline uint16_t -pci_resource_read16(struct rte_mem_resource *rsc, uint32_t offset) -{ - return rte_le_to_cpu_16(*((uint16_t *)((uint8_t *)rsc->addr + - offset))); -} - -/* - * @return Four bytes from PCI resource starting at offset "offset". - */ -static inline uint32_t -pci_resource_read32(struct rte_mem_resource *rsc, uint32_t offset) -{ - return rte_le_to_cpu_32(*((uint32_t *)((uint8_t *)rsc->addr + - offset))); -} - -/* - * @return Eight bytes from PCI resource starting at offset "offset". - */ -static inline uint64_t -pci_resource_read64(struct rte_mem_resource *rsc, uint32_t offset) -{ - return rte_le_to_cpu_64(*((uint64_t *)((uint8_t *)rsc->addr + - offset))); -} - -/* - * Write one byte to PCI resource address space at offset "offset". - */ -static inline void -pci_resource_write8(struct rte_mem_resource *rsc, uint32_t offset, uint8_t val) -{ - *((uint8_t *)((uint8_t *)rsc->addr + offset)) = val; -} - -/* - * Write two bytes to PCI resource address space at offset "offset". - */ -static inline void -pci_resource_write16(struct rte_mem_resource *rsc, uint32_t offset, - uint16_t val) -{ - *((uint16_t *)((uint8_t *)rsc->addr + offset)) = rte_cpu_to_le_16(val); -} - -/* - * Write four bytes to PCI resource address space at offset "offset". - */ -static inline void -pci_resource_write32(struct rte_mem_resource *rsc, uint32_t offset, - uint32_t val) -{ - *((uint32_t *)((uint8_t *)rsc->addr + offset)) = rte_cpu_to_le_32(val); -} - -/* - * Write eight bytes to PCI resource address space at offset "offset". - */ -static inline void -pci_resource_write64(struct rte_mem_resource *rsc, uint32_t offset, - uint64_t val) -{ - *((uint64_t *)((uint8_t *)rsc->addr + offset)) = rte_cpu_to_le_64(val); -} - -#define SZEDATA2_PCI_RESOURCE_PTR(rsc, offset, type) \ - ((type)(((uint8_t *)(rsc)->addr) + (offset))) - -enum szedata2_link_speed { - SZEDATA2_LINK_SPEED_DEFAULT = 0, - SZEDATA2_LINK_SPEED_10G, - SZEDATA2_LINK_SPEED_40G, - SZEDATA2_LINK_SPEED_100G, -}; - -enum szedata2_mac_check_mode { - SZEDATA2_MAC_CHMODE_PROMISC = 0x0, - SZEDATA2_MAC_CHMODE_ONLY_VALID = 0x1, - SZEDATA2_MAC_CHMODE_ALL_BROADCAST = 0x2, - SZEDATA2_MAC_CHMODE_ALL_MULTICAST = 0x3, -}; - -/* - * Structure describes CGMII IBUF address space - */ -struct szedata2_cgmii_ibuf { - /** Total Received Frames Counter low part */ - uint32_t trfcl; - /** Correct Frames Counter low part */ - uint32_t cfcl; - /** Discarded Frames Counter low part */ - uint32_t dfcl; - /** Counter of frames discarded due to buffer overflow low part */ - uint32_t bodfcl; - /** Total Received Frames Counter high part */ - uint32_t trfch; - /** Correct Frames Counter high part */ - uint32_t cfch; - /** Discarded Frames Counter high part */ - uint32_t dfch; - /** Counter of frames discarded due to buffer overflow high part */ - uint32_t bodfch; - /** IBUF enable register */ - uint32_t ibuf_en; - /** Error mask register */ - uint32_t err_mask; - /** IBUF status register */ - uint32_t ibuf_st; - /** IBUF command register */ - uint32_t ibuf_cmd; - /** Minimum frame length allowed */ - uint32_t mfla; - /** Frame MTU */ - uint32_t mtu; - /** MAC address check mode */ - uint32_t mac_chmode; - /** Octets Received OK Counter low part */ - uint32_t orocl; - /** Octets Received OK Counter high part */ - uint32_t oroch; -} __rte_packed; - -/* Offset of CGMII IBUF memory for MAC addresses */ -#define SZEDATA2_CGMII_IBUF_MAC_MEM_OFF 0x80 - -/* - * @return - * true if IBUF is enabled - * false if IBUF is disabled - */ -static inline bool -cgmii_ibuf_is_enabled(volatile struct szedata2_cgmii_ibuf *ibuf) -{ - return ((rte_le_to_cpu_32(ibuf->ibuf_en) & 0x1) != 0) ? true : false; -} - -/* - * Enables IBUF. - */ -static inline void -cgmii_ibuf_enable(volatile struct szedata2_cgmii_ibuf *ibuf) -{ - ibuf->ibuf_en = - rte_cpu_to_le_32(rte_le_to_cpu_32(ibuf->ibuf_en) | 0x1); -} - -/* - * Disables IBUF. - */ -static inline void -cgmii_ibuf_disable(volatile struct szedata2_cgmii_ibuf *ibuf) -{ - ibuf->ibuf_en = - rte_cpu_to_le_32(rte_le_to_cpu_32(ibuf->ibuf_en) & ~0x1); -} - -/* - * @return - * true if ibuf link is up - * false if ibuf link is down - */ -static inline bool -cgmii_ibuf_is_link_up(volatile struct szedata2_cgmii_ibuf *ibuf) -{ - return ((rte_le_to_cpu_32(ibuf->ibuf_st) & 0x80) != 0) ? true : false; -} - -/* - * @return - * MAC address check mode - */ -static inline enum szedata2_mac_check_mode -cgmii_ibuf_mac_mode_read(volatile struct szedata2_cgmii_ibuf *ibuf) -{ - switch (rte_le_to_cpu_32(ibuf->mac_chmode) & 0x3) { - case 0x0: - return SZEDATA2_MAC_CHMODE_PROMISC; - case 0x1: - return SZEDATA2_MAC_CHMODE_ONLY_VALID; - case 0x2: - return SZEDATA2_MAC_CHMODE_ALL_BROADCAST; - case 0x3: - return SZEDATA2_MAC_CHMODE_ALL_MULTICAST; - default: - return SZEDATA2_MAC_CHMODE_PROMISC; - } -} - -/* - * Writes "mode" in MAC address check mode register. - */ -static inline void -cgmii_ibuf_mac_mode_write(volatile struct szedata2_cgmii_ibuf *ibuf, - enum szedata2_mac_check_mode mode) -{ - ibuf->mac_chmode = rte_cpu_to_le_32( - (rte_le_to_cpu_32(ibuf->mac_chmode) & ~0x3) | mode); -} - -/* - * Structure describes CGMII OBUF address space - */ -struct szedata2_cgmii_obuf { - /** Total Sent Frames Counter low part */ - uint32_t tsfcl; - /** Octets Sent Counter low part */ - uint32_t oscl; - /** Total Discarded Frames Counter low part */ - uint32_t tdfcl; - /** reserved */ - uint32_t reserved1; - /** Total Sent Frames Counter high part */ - uint32_t tsfch; - /** Octets Sent Counter high part */ - uint32_t osch; - /** Total Discarded Frames Counter high part */ - uint32_t tdfch; - /** reserved */ - uint32_t reserved2; - /** OBUF enable register */ - uint32_t obuf_en; - /** reserved */ - uint64_t reserved3; - /** OBUF control register */ - uint32_t ctrl; - /** OBUF status register */ - uint32_t obuf_st; -} __rte_packed; - -/* - * @return - * true if OBUF is enabled - * false if OBUF is disabled - */ -static inline bool -cgmii_obuf_is_enabled(volatile struct szedata2_cgmii_obuf *obuf) -{ - return ((rte_le_to_cpu_32(obuf->obuf_en) & 0x1) != 0) ? true : false; -} - -/* - * Enables OBUF. - */ -static inline void -cgmii_obuf_enable(volatile struct szedata2_cgmii_obuf *obuf) -{ - obuf->obuf_en = - rte_cpu_to_le_32(rte_le_to_cpu_32(obuf->obuf_en) | 0x1); -} - -/* - * Disables OBUF. - */ -static inline void -cgmii_obuf_disable(volatile struct szedata2_cgmii_obuf *obuf) -{ - obuf->obuf_en = - rte_cpu_to_le_32(rte_le_to_cpu_32(obuf->obuf_en) & ~0x1); -} - -/* - * Function takes value from IBUF status register. Values in IBUF and OBUF - * should be same. - * - * @return Link speed constant. - */ -static inline enum szedata2_link_speed -cgmii_link_speed(volatile struct szedata2_cgmii_ibuf *ibuf) -{ - uint32_t speed = (rte_le_to_cpu_32(ibuf->ibuf_st) & 0x70) >> 4; - switch (speed) { - case 0x03: - return SZEDATA2_LINK_SPEED_10G; - case 0x04: - return SZEDATA2_LINK_SPEED_40G; - case 0x05: - return SZEDATA2_LINK_SPEED_100G; - default: - return SZEDATA2_LINK_SPEED_DEFAULT; - } -} - -/* - * IBUFs and OBUFs can generally be located at different offsets in different - * firmwares. - * This part defines base offsets of IBUFs and OBUFs through various firmwares. - * Currently one firmware type is supported. - * Type of firmware is set through configuration option - * CONFIG_RTE_LIBRTE_PMD_SZEDATA_AS. - * Possible values are: - * 0 - for firmwares: - * NIC_100G1_LR4 - * HANIC_100G1_LR4 - * HANIC_100G1_SR10 - */ -#if !defined(RTE_LIBRTE_PMD_SZEDATA2_AS) -#error "RTE_LIBRTE_PMD_SZEDATA2_AS has to be defined" -#elif RTE_LIBRTE_PMD_SZEDATA2_AS == 0 - -/* - * CGMII IBUF offset from the beginning of PCI resource address space. - */ -#define SZEDATA2_CGMII_IBUF_BASE_OFF 0x8000 -/* - * Size of CGMII IBUF. - */ -#define SZEDATA2_CGMII_IBUF_SIZE 0x200 - -/* - * GCMII OBUF offset from the beginning of PCI resource address space. - */ -#define SZEDATA2_CGMII_OBUF_BASE_OFF 0x9000 -/* - * Size of CGMII OBUF. - */ -#define SZEDATA2_CGMII_OBUF_SIZE 0x100 - -#else -#error "RTE_LIBRTE_PMD_SZEDATA2_AS has wrong value, see comments in config file" -#endif - -#endif +#endif /* RTE_PMD_SZEDATA2_H_ */ diff --git a/drivers/net/szedata2/szedata2_iobuf.c b/drivers/net/szedata2/szedata2_iobuf.c new file mode 100644 index 00000000..3b9a71fe --- /dev/null +++ b/drivers/net/szedata2/szedata2_iobuf.c @@ -0,0 +1,203 @@ +/*- + * BSD LICENSE + * + * Copyright (c) 2017 CESNET + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of CESNET 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 + * OWNER 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. + */ + +#include <stdint.h> + +#include <rte_common.h> + +#include "szedata2_iobuf.h" + +/* + * IBUFs and OBUFs can generally be located at different offsets in different + * firmwares (modes). + * This part defines base offsets of IBUFs and OBUFs for various cards + * and firmwares (modes). + * Type of firmware (mode) is set through configuration option + * CONFIG_RTE_LIBRTE_PMD_SZEDATA2_AS. + * Possible values are: + * 0 - for cards (modes): + * NFB-100G1 (100G1) + * + * 1 - for cards (modes): + * NFB-100G2Q (100G1) + * + * 2 - for cards (modes): + * NFB-40G2 (40G2) + * NFB-100G2C (100G2) + * NFB-100G2Q (40G2) + * + * 3 - for cards (modes): + * NFB-40G2 (10G8) + * NFB-100G2Q (10G8) + * + * 4 - for cards (modes): + * NFB-100G1 (10G10) + * + * 5 - for experimental firmwares and future use + */ +#if !defined(RTE_LIBRTE_PMD_SZEDATA2_AS) +#error "RTE_LIBRTE_PMD_SZEDATA2_AS has to be defined" +#elif RTE_LIBRTE_PMD_SZEDATA2_AS == 0 + +/* + * Cards (modes): + * NFB-100G1 (100G1) + */ + +const uint32_t szedata2_ibuf_base_table[] = { + 0x8000 +}; +const uint32_t szedata2_obuf_base_table[] = { + 0x9000 +}; + +#elif RTE_LIBRTE_PMD_SZEDATA2_AS == 1 + +/* + * Cards (modes): + * NFB-100G2Q (100G1) + */ + +const uint32_t szedata2_ibuf_base_table[] = { + 0x8800 +}; +const uint32_t szedata2_obuf_base_table[] = { + 0x9800 +}; + +#elif RTE_LIBRTE_PMD_SZEDATA2_AS == 2 + +/* + * Cards (modes): + * NFB-40G2 (40G2) + * NFB-100G2C (100G2) + * NFB-100G2Q (40G2) + */ + +const uint32_t szedata2_ibuf_base_table[] = { + 0x8000, + 0x8800 +}; +const uint32_t szedata2_obuf_base_table[] = { + 0x9000, + 0x9800 +}; + +#elif RTE_LIBRTE_PMD_SZEDATA2_AS == 3 + +/* + * Cards (modes): + * NFB-40G2 (10G8) + * NFB-100G2Q (10G8) + */ + +const uint32_t szedata2_ibuf_base_table[] = { + 0x8000, + 0x8200, + 0x8400, + 0x8600, + 0x8800, + 0x8A00, + 0x8C00, + 0x8E00 +}; +const uint32_t szedata2_obuf_base_table[] = { + 0x9000, + 0x9200, + 0x9400, + 0x9600, + 0x9800, + 0x9A00, + 0x9C00, + 0x9E00 +}; + +#elif RTE_LIBRTE_PMD_SZEDATA2_AS == 4 + +/* + * Cards (modes): + * NFB-100G1 (10G10) + */ + +const uint32_t szedata2_ibuf_base_table[] = { + 0x8000, + 0x8200, + 0x8400, + 0x8600, + 0x8800, + 0x8A00, + 0x8C00, + 0x8E00, + 0x9000, + 0x9200 +}; +const uint32_t szedata2_obuf_base_table[] = { + 0xA000, + 0xA200, + 0xA400, + 0xA600, + 0xA800, + 0xAA00, + 0xAC00, + 0xAE00, + 0xB000, + 0xB200 +}; + +#elif RTE_LIBRTE_PMD_SZEDATA2_AS == 5 + +/* + * Future use and experimental firmwares. + */ + +const uint32_t szedata2_ibuf_base_table[] = { + 0x8000, + 0x8200, + 0x8400, + 0x8600, + 0x8800 +}; +const uint32_t szedata2_obuf_base_table[] = { + 0x9000, + 0x9200, + 0x9400, + 0x9600, + 0x9800 +}; + +#else +#error "RTE_LIBRTE_PMD_SZEDATA2_AS has wrong value, see comments in config file" +#endif + +const uint32_t szedata2_ibuf_count = RTE_DIM(szedata2_ibuf_base_table); +const uint32_t szedata2_obuf_count = RTE_DIM(szedata2_obuf_base_table); diff --git a/drivers/net/szedata2/szedata2_iobuf.h b/drivers/net/szedata2/szedata2_iobuf.h new file mode 100644 index 00000000..f1ccb3b2 --- /dev/null +++ b/drivers/net/szedata2/szedata2_iobuf.h @@ -0,0 +1,356 @@ +/*- + * BSD LICENSE + * + * Copyright (c) 2017 CESNET + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of CESNET 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 + * OWNER 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. + */ + +#ifndef _SZEDATA2_IOBUF_H_ +#define _SZEDATA2_IOBUF_H_ + +#include <stdint.h> +#include <stdbool.h> + +#include <rte_byteorder.h> +#include <rte_io.h> +#include <rte_dev.h> + +/* IBUF offsets from the beginning of the PCI resource address space. */ +extern const uint32_t szedata2_ibuf_base_table[]; +extern const uint32_t szedata2_ibuf_count; + +/* OBUF offsets from the beginning of the PCI resource address space. */ +extern const uint32_t szedata2_obuf_base_table[]; +extern const uint32_t szedata2_obuf_count; + +enum szedata2_link_speed { + SZEDATA2_LINK_SPEED_DEFAULT = 0, + SZEDATA2_LINK_SPEED_10G, + SZEDATA2_LINK_SPEED_40G, + SZEDATA2_LINK_SPEED_100G, +}; + +enum szedata2_mac_check_mode { + SZEDATA2_MAC_CHMODE_PROMISC = 0x0, + SZEDATA2_MAC_CHMODE_ONLY_VALID = 0x1, + SZEDATA2_MAC_CHMODE_ALL_BROADCAST = 0x2, + SZEDATA2_MAC_CHMODE_ALL_MULTICAST = 0x3, +}; + +/** + * Macro takes pointer to pci resource structure (rsc) + * and returns pointer to mapped resource memory at + * specified offset (offset) typecast to the type (type). + */ +#define SZEDATA2_PCI_RESOURCE_PTR(rsc, offset, type) \ + ((type)(((uint8_t *)(rsc)->addr) + (offset))) + +/** + * Maximum possible number of MAC addresses (limited by IBUF status + * register value MAC_COUNT which has 5 bits). + */ +#define SZEDATA2_IBUF_MAX_MAC_COUNT 32 + +/** + * Structure describes IBUF address space. + */ +struct szedata2_ibuf { + /** Total Received Frames Counter low part */ + uint32_t trfcl; /**< 0x00 */ + /** Correct Frames Counter low part */ + uint32_t cfcl; /**< 0x04 */ + /** Discarded Frames Counter low part */ + uint32_t dfcl; /**< 0x08 */ + /** Counter of frames discarded due to buffer overflow low part */ + uint32_t bodfcl; /**< 0x0C */ + /** Total Received Frames Counter high part */ + uint32_t trfch; /**< 0x10 */ + /** Correct Frames Counter high part */ + uint32_t cfch; /**< 0x14 */ + /** Discarded Frames Counter high part */ + uint32_t dfch; /**< 0x18 */ + /** Counter of frames discarded due to buffer overflow high part */ + uint32_t bodfch; /**< 0x1C */ + /** IBUF enable register */ + uint32_t ibuf_en; /**< 0x20 */ + /** Error mask register */ + uint32_t err_mask; /**< 0x24 */ + /** IBUF status register */ + uint32_t ibuf_st; /**< 0x28 */ + /** IBUF command register */ + uint32_t ibuf_cmd; /**< 0x2C */ + /** Minimum frame length allowed */ + uint32_t mfla; /**< 0x30 */ + /** Frame MTU */ + uint32_t mtu; /**< 0x34 */ + /** MAC address check mode */ + uint32_t mac_chmode; /**< 0x38 */ + /** Octets Received OK Counter low part */ + uint32_t orocl; /**< 0x3C */ + /** Octets Received OK Counter high part */ + uint32_t oroch; /**< 0x40 */ + /** reserved */ + uint8_t reserved[60]; /**< 0x4C */ + /** IBUF memory for MAC addresses */ + uint32_t mac_mem[2 * SZEDATA2_IBUF_MAX_MAC_COUNT]; /**< 0x80 */ +} __rte_packed; + +/** + * Structure describes OBUF address space. + */ +struct szedata2_obuf { + /** Total Sent Frames Counter low part */ + uint32_t tsfcl; /**< 0x00 */ + /** Octets Sent Counter low part */ + uint32_t oscl; /**< 0x04 */ + /** Total Discarded Frames Counter low part */ + uint32_t tdfcl; /**< 0x08 */ + /** reserved */ + uint32_t reserved1; /**< 0x0C */ + /** Total Sent Frames Counter high part */ + uint32_t tsfch; /**< 0x10 */ + /** Octets Sent Counter high part */ + uint32_t osch; /**< 0x14 */ + /** Total Discarded Frames Counter high part */ + uint32_t tdfch; /**< 0x18 */ + /** reserved */ + uint32_t reserved2; /**< 0x1C */ + /** OBUF enable register */ + uint32_t obuf_en; /**< 0x20 */ + /** reserved */ + uint64_t reserved3; /**< 0x24 */ + /** OBUF control register */ + uint32_t ctrl; /**< 0x2C */ + /** OBUF status register */ + uint32_t obuf_st; /**< 0x30 */ +} __rte_packed; + +/** + * Wrapper for reading 4 bytes from device memory in correct endianness. + * + * @param addr + * Address for reading. + * @return + * 4 B value. + */ +static inline uint32_t +szedata2_read32(const volatile void *addr) +{ + return rte_le_to_cpu_32(rte_read32(addr)); +} + +/** + * Wrapper for writing 4 bytes to device memory in correct endianness. + * + * @param value + * Value to write. + * @param addr + * Address for writing. + */ +static inline void +szedata2_write32(uint32_t value, volatile void *addr) +{ + rte_write32(rte_cpu_to_le_32(value), addr); +} + +/** + * Get pointer to IBUF structure according to specified index. + * + * @param rsc + * Pointer to base address of memory resource. + * @param index + * Index of IBUF. + * @return + * Pointer to IBUF structure. + */ +static inline struct szedata2_ibuf * +ibuf_ptr_by_index(struct rte_mem_resource *rsc, uint32_t index) +{ + if (index >= szedata2_ibuf_count) + index = szedata2_ibuf_count - 1; + return SZEDATA2_PCI_RESOURCE_PTR(rsc, szedata2_ibuf_base_table[index], + struct szedata2_ibuf *); +} + +/** + * Get pointer to OBUF structure according to specified idnex. + * + * @param rsc + * Pointer to base address of memory resource. + * @param index + * Index of OBUF. + * @return + * Pointer to OBUF structure. + */ +static inline struct szedata2_obuf * +obuf_ptr_by_index(struct rte_mem_resource *rsc, uint32_t index) +{ + if (index >= szedata2_obuf_count) + index = szedata2_obuf_count - 1; + return SZEDATA2_PCI_RESOURCE_PTR(rsc, szedata2_obuf_base_table[index], + struct szedata2_obuf *); +} + +/** + * Checks if IBUF is enabled. + * + * @param ibuf + * Pointer to IBUF structure. + * @return + * true if IBUF is enabled. + * false if IBUF is disabled. + */ +static inline bool +ibuf_is_enabled(const volatile struct szedata2_ibuf *ibuf) +{ + return ((szedata2_read32(&ibuf->ibuf_en) & 0x1) != 0) ? true : false; +} + +/** + * Enables IBUF. + * + * @param ibuf + * Pointer to IBUF structure. + */ +static inline void +ibuf_enable(volatile struct szedata2_ibuf *ibuf) +{ + szedata2_write32(szedata2_read32(&ibuf->ibuf_en) | 0x1, &ibuf->ibuf_en); +} + +/** + * Disables IBUF. + * + * @param ibuf + * Pointer to IBUF structure. + */ +static inline void +ibuf_disable(volatile struct szedata2_ibuf *ibuf) +{ + szedata2_write32(szedata2_read32(&ibuf->ibuf_en) & ~0x1, + &ibuf->ibuf_en); +} + +/** + * Checks if link is up. + * + * @param ibuf + * Pointer to IBUF structure. + * @return + * true if ibuf link is up. + * false if ibuf link is down. + */ +static inline bool +ibuf_is_link_up(const volatile struct szedata2_ibuf *ibuf) +{ + return ((szedata2_read32(&ibuf->ibuf_st) & 0x80) != 0) ? true : false; +} + +/** + * Get current MAC address check mode from IBUF. + * + * @param ibuf + * Pointer to IBUF structure. + * @return + * MAC address check mode constant. + */ +static inline enum szedata2_mac_check_mode +ibuf_mac_mode_read(const volatile struct szedata2_ibuf *ibuf) +{ + switch (szedata2_read32(&ibuf->mac_chmode) & 0x3) { + case 0x0: + return SZEDATA2_MAC_CHMODE_PROMISC; + case 0x1: + return SZEDATA2_MAC_CHMODE_ONLY_VALID; + case 0x2: + return SZEDATA2_MAC_CHMODE_ALL_BROADCAST; + case 0x3: + return SZEDATA2_MAC_CHMODE_ALL_MULTICAST; + default: + return SZEDATA2_MAC_CHMODE_PROMISC; + } +} + +/** + * Writes mode in MAC address check mode register in IBUF. + * + * @param ibuf + * Pointer to IBUF structure. + * @param mode + * MAC address check mode to set. + */ +static inline void +ibuf_mac_mode_write(volatile struct szedata2_ibuf *ibuf, + enum szedata2_mac_check_mode mode) +{ + szedata2_write32((szedata2_read32(&ibuf->mac_chmode) & ~0x3) | mode, + &ibuf->mac_chmode); +} + +/** + * Checks if obuf is enabled. + * + * @param obuf + * Pointer to OBUF structure. + * @return + * true if OBUF is enabled. + * false if OBUF is disabled. + */ +static inline bool +obuf_is_enabled(const volatile struct szedata2_obuf *obuf) +{ + return ((szedata2_read32(&obuf->obuf_en) & 0x1) != 0) ? true : false; +} + +/** + * Enables OBUF. + * + * @param obuf + * Pointer to OBUF structure. + */ +static inline void +obuf_enable(volatile struct szedata2_obuf *obuf) +{ + szedata2_write32(szedata2_read32(&obuf->obuf_en) | 0x1, &obuf->obuf_en); +} + +/** + * Disables OBUF. + * + * @param obuf + * Pointer to OBUF structure. + */ +static inline void +obuf_disable(volatile struct szedata2_obuf *obuf) +{ + szedata2_write32(szedata2_read32(&obuf->obuf_en) & ~0x1, + &obuf->obuf_en); +} + +#endif /* _SZEDATA2_IOBUF_H_ */ |