This is to prepare for firmwares with multiple ibufs and obufs.
Ibufs and obufs are the modules in FPGA firmware implementing
the Ethernet port.
There is one ibuf+obuf per Ethernet port.
The cards and firmwares allow one physical port to be one Ethernet
port or split into more Ethernet ports, e.g. one 100GE physical
port can be one Ethernet port of 100GE or split into ten Ethernet
ports of 10GE.
All DMA queues in the device are shared between all Ethernet ports.
Offsets of ibufs and obufs are defined in array.
Functions which operate on ibufs and obufs iterate over this array.
Signed-off-by: Matej Vido <vido@cesnet.cz>
# 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
#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
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)
struct rte_eth_link *dev_link = &dev->data->dev_link;
struct pmd_internals *internals = (struct pmd_internals *)
dev->data->dev_private;
- const volatile struct szedata2_ibuf *ibuf = SZEDATA2_PCI_RESOURCE_PTR(
- internals->pci_rsc, SZEDATA2_IBUF_BASE_OFF,
- const volatile struct szedata2_ibuf *);
+ const volatile struct szedata2_ibuf *ibuf;
+ uint32_t i;
+ bool link_is_up = false;
- switch (get_link_speed(ibuf)) {
+ switch (get_link_speed(internals)) {
case SZEDATA2_LINK_SPEED_10G:
link.link_speed = ETH_SPEED_NUM_10G;
break;
/* szedata2 uses only full duplex */
link.link_duplex = ETH_LINK_FULL_DUPLEX;
- link.link_status = (ibuf_is_enabled(ibuf) &&
- 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;
{
struct pmd_internals *internals = (struct pmd_internals *)
dev->data->dev_private;
- volatile struct szedata2_ibuf *ibuf = SZEDATA2_PCI_RESOURCE_PTR(
- internals->pci_rsc, SZEDATA2_IBUF_BASE_OFF,
- volatile struct szedata2_ibuf *);
- volatile struct szedata2_obuf *obuf = SZEDATA2_PCI_RESOURCE_PTR(
- internals->pci_rsc, SZEDATA2_OBUF_BASE_OFF,
- volatile struct szedata2_obuf *);
-
- ibuf_enable(ibuf);
- 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;
}
{
struct pmd_internals *internals = (struct pmd_internals *)
dev->data->dev_private;
- volatile struct szedata2_ibuf *ibuf = SZEDATA2_PCI_RESOURCE_PTR(
- internals->pci_rsc, SZEDATA2_IBUF_BASE_OFF,
- volatile struct szedata2_ibuf *);
- volatile struct szedata2_obuf *obuf = SZEDATA2_PCI_RESOURCE_PTR(
- internals->pci_rsc, SZEDATA2_OBUF_BASE_OFF,
- volatile struct szedata2_obuf *);
-
- ibuf_disable(ibuf);
- 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;
}
{
struct pmd_internals *internals = (struct pmd_internals *)
dev->data->dev_private;
- volatile struct szedata2_ibuf *ibuf = SZEDATA2_PCI_RESOURCE_PTR(
- internals->pci_rsc, SZEDATA2_IBUF_BASE_OFF,
- volatile struct szedata2_ibuf *);
- 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
{
struct pmd_internals *internals = (struct pmd_internals *)
dev->data->dev_private;
- volatile struct szedata2_ibuf *ibuf = SZEDATA2_PCI_RESOURCE_PTR(
- internals->pci_rsc, SZEDATA2_IBUF_BASE_OFF,
- volatile struct szedata2_ibuf *);
- 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
{
struct pmd_internals *internals = (struct pmd_internals *)
dev->data->dev_private;
- volatile struct szedata2_ibuf *ibuf = SZEDATA2_PCI_RESOURCE_PTR(
- internals->pci_rsc, SZEDATA2_IBUF_BASE_OFF,
- volatile struct szedata2_ibuf *);
- 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
{
struct pmd_internals *internals = (struct pmd_internals *)
dev->data->dev_private;
- volatile struct szedata2_ibuf *ibuf = SZEDATA2_PCI_RESOURCE_PTR(
- internals->pci_rsc, SZEDATA2_IBUF_BASE_OFF,
- volatile struct szedata2_ibuf *);
- 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 = {
rte_write32(rte_cpu_to_le_32(value), addr);
}
-#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,
&obuf->obuf_en);
}
-/*
- * 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
-get_link_speed(const volatile struct szedata2_ibuf *ibuf)
-{
- 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;
- }
-}
-
-/*
- * 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
-
-/*
- * IBUF offset from the beginning of PCI resource address space.
- */
-#define SZEDATA2_IBUF_BASE_OFF 0x8000
-/*
- * Size of IBUF.
- */
-#define SZEDATA2_IBUF_SIZE 0x200
-
-/*
- * OBUF offset from the beginning of PCI resource address space.
- */
-#define SZEDATA2_OBUF_BASE_OFF 0x9000
-/*
- * Size of OBUF.
- */
-#define SZEDATA2_OBUF_SIZE 0x100
-
-#else
-#error "RTE_LIBRTE_PMD_SZEDATA2_AS has wrong value, see comments in config file"
-#endif
-
#endif
--- /dev/null
+/*-
+ * 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.
+ * 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_SZEDATA2_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
+
+const uint32_t szedata2_ibuf_base_table[] = {
+ 0x8000
+};
+const uint32_t szedata2_obuf_base_table[] = {
+ 0x9000
+};
+
+#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);
--- /dev/null
+/*-
+ * 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 <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;
+
+/**
+ * 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)))
+
+/**
+ * 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 *);
+}
+
+#endif /* _SZEDATA2_IOBUF_H_ */