* [[PATCH v1] 1/8] net/rnp: add skeleton
2023-08-01 6:43 [[PATCH v1] 0/8] *** SUBJECT HERE *** Wenbo Cao
@ 2023-08-01 6:43 ` Wenbo Cao
2023-08-01 6:43 ` [[PATCH v1] 2/8] net/rnp: add ethdev probe and remove Wenbo Cao
` (5 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Wenbo Cao @ 2023-08-01 6:43 UTC (permalink / raw)
To: Thomas Monjalon, caowenbo; +Cc: dev
Add Basic PMD library and doc build infrastructure
Update maintainers file to claim responsibility.
Signed-off-by: Wenbo Cao <caowenbo@mucse.com>
---
MAINTAINERS | 6 +++++
doc/guides/nics/features/rnp.ini | 8 ++++++
doc/guides/nics/index.rst | 1 +
doc/guides/nics/rnp.rst | 43 ++++++++++++++++++++++++++++++++
drivers/net/meson.build | 1 +
drivers/net/rnp/meson.build | 12 +++++++++
drivers/net/rnp/rnp_ethdev.c | 3 +++
7 files changed, 74 insertions(+)
create mode 100644 doc/guides/nics/features/rnp.ini
create mode 100644 doc/guides/nics/rnp.rst
create mode 100644 drivers/net/rnp/meson.build
create mode 100644 drivers/net/rnp/rnp_ethdev.c
diff --git a/MAINTAINERS b/MAINTAINERS
index a5219926ab..36f4867cf8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -955,6 +955,12 @@ F: drivers/net/qede/
F: doc/guides/nics/qede.rst
F: doc/guides/nics/features/qede*.ini
+Mucse rnp
+M: caowenbo@mucse.com
+F: drivers/net/rnp
+F: doc/guides/nics/rnp.rst
+F: doc/guides/nics/features/rnp.ini
+
Solarflare sfc_efx
M: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
F: drivers/common/sfc_efx/
diff --git a/doc/guides/nics/features/rnp.ini b/doc/guides/nics/features/rnp.ini
new file mode 100644
index 0000000000..2ad04ee330
--- /dev/null
+++ b/doc/guides/nics/features/rnp.ini
@@ -0,0 +1,8 @@
+;
+; Supported features of the 'rnp' network poll mode driver.
+;
+; Refer to default.ini for the full list of available PMD features.
+;
+[Features]
+Linux = Y
+x86-64 = Y
diff --git a/doc/guides/nics/index.rst b/doc/guides/nics/index.rst
index 5c9d1edf5e..cc89d3154a 100644
--- a/doc/guides/nics/index.rst
+++ b/doc/guides/nics/index.rst
@@ -61,6 +61,7 @@ Network Interface Controller Drivers
pcap_ring
pfe
qede
+ rnp
sfc_efx
softnic
tap
diff --git a/doc/guides/nics/rnp.rst b/doc/guides/nics/rnp.rst
new file mode 100644
index 0000000000..8785972fd9
--- /dev/null
+++ b/doc/guides/nics/rnp.rst
@@ -0,0 +1,43 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2023 Mucse IC Design Ltd.
+
+RNP Poll Mode driver
+==========================
+
+The RNP ETHDEV PMD (**librte_net_rnp**) provides poll mode ethdev
+driver support for the inbuilt network device found in the **Mucse RNP**
+
+Prerequisites
+-------------
+More information can be found at `Mucse, Official Website
+<https://mucse.com/productDetail>`_.
+
+Supported RNP SoCs
+------------------------
+
+- N10
+
+Driver compilation and testing
+------------------------------
+
+Refer to the document :ref:`compiling and testing a PMD for a NIC <pmd_build_and_test>`
+for details.
+
+#. Running testpmd:
+
+ Follow instructions available in the document
+ :ref:`compiling and testing a PMD for a NIC <pmd_build_and_test>`
+ to run testpmd.
+
+Limitations or Known issues
+-----------
+Build with ICC is not supported yet.
+CRC stripping
+~~~~~~~~~~~~
+The RNP SoC family NICs strip the CRC for every packets coming into the
+host interface irrespective of the offload configuration.
+When You Want To Disable CRC_OFFLOAD The Feature Will Influence The RxCksum Offload
+VLAN Strip
+~~~~~~~~~~~~~~~~~~
+For VLAN Strip RNP Just Support CVLAN(0x8100) Type If The Vlan Type Is SVLAN(0X88a8)
+VLAN Filter Or Strip Will Not Effert For This Packet It Will Bypass To The Host.
diff --git a/drivers/net/meson.build b/drivers/net/meson.build
index b1df17ce8c..8bdbf05857 100644
--- a/drivers/net/meson.build
+++ b/drivers/net/meson.build
@@ -56,6 +56,7 @@ drivers = [
'ring',
'sfc',
'softnic',
+ 'rnp',
'tap',
'thunderx',
'txgbe',
diff --git a/drivers/net/rnp/meson.build b/drivers/net/rnp/meson.build
new file mode 100644
index 0000000000..0c38d39347
--- /dev/null
+++ b/drivers/net/rnp/meson.build
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(C) 2023 Mucse IC Design Ltd.
+#
+if is_windows
+ build = false
+ reason = 'not supported on Windows'
+ subdir_done()
+endif
+
+sources = files(
+ 'rnp_ethdev.c',
+)
diff --git a/drivers/net/rnp/rnp_ethdev.c b/drivers/net/rnp/rnp_ethdev.c
new file mode 100644
index 0000000000..9ce3c0b497
--- /dev/null
+++ b/drivers/net/rnp/rnp_ethdev.c
@@ -0,0 +1,3 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Mucse IC Design Ltd.
+ */
--
2.27.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [[PATCH v1] 2/8] net/rnp: add ethdev probe and remove
2023-08-01 6:43 [[PATCH v1] 0/8] *** SUBJECT HERE *** Wenbo Cao
2023-08-01 6:43 ` [[PATCH v1] 1/8] net/rnp: add skeleton Wenbo Cao
@ 2023-08-01 6:43 ` Wenbo Cao
2023-08-01 6:43 ` [[PATCH v1] 3/8] net/rnp: add device init and uninit Wenbo Cao
` (4 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Wenbo Cao @ 2023-08-01 6:43 UTC (permalink / raw)
To: caowenbo, Anatoly Burakov; +Cc: dev
Add basic PCIe ethdev probe and remove.
Signed-off-by: Wenbo Cao <caowenbo@mucse.com>
---
drivers/net/rnp/rnp.h | 13 ++++++
drivers/net/rnp/rnp_ethdev.c | 83 ++++++++++++++++++++++++++++++++++++
2 files changed, 96 insertions(+)
create mode 100644 drivers/net/rnp/rnp.h
diff --git a/drivers/net/rnp/rnp.h b/drivers/net/rnp/rnp.h
new file mode 100644
index 0000000000..76d281cc0a
--- /dev/null
+++ b/drivers/net/rnp/rnp.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Mucse IC Design Ltd.
+ */
+#ifndef __RNP_H__
+#define __RNP_H__
+
+#define PCI_VENDOR_ID_MUCSE (0x8848)
+#define RNP_DEV_ID_N10G (0x1000)
+
+struct rnp_eth_port {
+} __rte_cache_aligned;
+
+#endif /* __RNP_H__ */
diff --git a/drivers/net/rnp/rnp_ethdev.c b/drivers/net/rnp/rnp_ethdev.c
index 9ce3c0b497..5951c2b311 100644
--- a/drivers/net/rnp/rnp_ethdev.c
+++ b/drivers/net/rnp/rnp_ethdev.c
@@ -1,3 +1,86 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(C) 2023 Mucse IC Design Ltd.
*/
+
+#include <ethdev_pci.h>
+#include <rte_io.h>
+#include <rte_malloc.h>
+
+#include "rnp.h"
+
+static int
+rnp_eth_dev_init(struct rte_eth_dev *eth_dev)
+{
+ RTE_SET_USED(eth_dev);
+
+ return -ENODEV;
+}
+
+static int
+rnp_eth_dev_uninit(struct rte_eth_dev *eth_dev)
+{
+ RTE_SET_USED(eth_dev);
+
+ return -ENODEV;
+}
+
+static int
+rnp_pci_remove(struct rte_pci_device *pci_dev)
+{
+ struct rte_eth_dev *eth_dev;
+ int rc;
+
+ eth_dev = rte_eth_dev_allocated(pci_dev->device.name);
+
+ if (eth_dev) {
+ /* Cleanup eth dev */
+ rc = rte_eth_dev_pci_generic_remove(pci_dev,
+ rnp_eth_dev_uninit);
+ if (rc)
+ return rc;
+ }
+ /* Nothing to be done for secondary processes */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return 0;
+
+ return 0;
+}
+
+static int
+rnp_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
+{
+ int rc;
+
+ RTE_SET_USED(pci_drv);
+
+ rc = rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct rnp_eth_port),
+ rnp_eth_dev_init);
+
+ /* On error on secondary, recheck if port exists in primary or
+ * in mid of detach state.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY && rc)
+ if (!rte_eth_dev_allocated(pci_dev->device.name))
+ return 0;
+ return rc;
+}
+
+static const struct rte_pci_id pci_id_rnp_map[] = {
+ {
+ RTE_PCI_DEVICE(PCI_VENDOR_ID_MUCSE, RNP_DEV_ID_N10G)
+ },
+ {
+ .vendor_id = 0,
+ },
+};
+
+static struct rte_pci_driver rte_rnp_pmd = {
+ .id_table = pci_id_rnp_map,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
+ .probe = rnp_pci_probe,
+ .remove = rnp_pci_remove,
+};
+
+RTE_PMD_REGISTER_PCI(net_rnp, rte_rnp_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(net_rnp, pci_id_rnp_map);
+RTE_PMD_REGISTER_KMOD_DEP(net_txgbe, "igb_uio | uio_pci_generic");
--
2.27.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [[PATCH v1] 3/8] net/rnp: add device init and uninit
2023-08-01 6:43 [[PATCH v1] 0/8] *** SUBJECT HERE *** Wenbo Cao
2023-08-01 6:43 ` [[PATCH v1] 1/8] net/rnp: add skeleton Wenbo Cao
2023-08-01 6:43 ` [[PATCH v1] 2/8] net/rnp: add ethdev probe and remove Wenbo Cao
@ 2023-08-01 6:43 ` Wenbo Cao
2023-08-01 15:20 ` Stephen Hemminger
2023-08-01 6:43 ` [[PATCH v1] 4/8] net/rnp: add mbx basic api feature Wenbo Cao
` (3 subsequent siblings)
6 siblings, 1 reply; 11+ messages in thread
From: Wenbo Cao @ 2023-08-01 6:43 UTC (permalink / raw)
To: caowenbo, Anatoly Burakov; +Cc: dev
Add basic init and uninit function
Signed-off-by: Wenbo Cao <caowenbo@mucse.com>
---
drivers/net/rnp/base/rnp_hw.h | 18 ++++
drivers/net/rnp/meson.build | 1 +
drivers/net/rnp/rnp.h | 25 +++++
drivers/net/rnp/rnp_ethdev.c | 197 +++++++++++++++++++++++++++++++++-
drivers/net/rnp/rnp_logs.h | 34 ++++++
drivers/net/rnp/rnp_osdep.h | 30 ++++++
6 files changed, 300 insertions(+), 5 deletions(-)
create mode 100644 drivers/net/rnp/base/rnp_hw.h
create mode 100644 drivers/net/rnp/rnp_logs.h
create mode 100644 drivers/net/rnp/rnp_osdep.h
diff --git a/drivers/net/rnp/base/rnp_hw.h b/drivers/net/rnp/base/rnp_hw.h
new file mode 100644
index 0000000000..543011a64c
--- /dev/null
+++ b/drivers/net/rnp/base/rnp_hw.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Mucse IC Design Ltd.
+ */
+#ifndef __RNP_HW_H__
+#define __RNP_HW_H__
+
+struct rnp_hw {
+ void *back;
+ char *iobar0;
+ uint32_t iobar0_len;
+ char *iobar4;
+ uint32_t iobar4_len;
+
+ uint16_t device_id;
+ uint16_t vendor_id;
+} __rte_cache_aligned;
+
+#endif /* __RNP_H__*/
diff --git a/drivers/net/rnp/meson.build b/drivers/net/rnp/meson.build
index 0c38d39347..36a1f7148d 100644
--- a/drivers/net/rnp/meson.build
+++ b/drivers/net/rnp/meson.build
@@ -10,3 +10,4 @@ endif
sources = files(
'rnp_ethdev.c',
)
+includes += include_directories('base')
diff --git a/drivers/net/rnp/rnp.h b/drivers/net/rnp/rnp.h
index 76d281cc0a..ea9d138673 100644
--- a/drivers/net/rnp/rnp.h
+++ b/drivers/net/rnp/rnp.h
@@ -4,10 +4,35 @@
#ifndef __RNP_H__
#define __RNP_H__
+#include "base/rnp_hw.h"
+
#define PCI_VENDOR_ID_MUCSE (0x8848)
#define RNP_DEV_ID_N10G (0x1000)
+#define RNP_MAX_PORT_OF_PF (4)
+#define RNP_CFG_BAR (4)
+#define RNP_PF_INFO_BAR (0)
struct rnp_eth_port {
+ void *adapt;
+ struct rte_eth_dev *eth_dev;
+} __rte_cache_aligned;
+
+struct rnp_share_ops {
} __rte_cache_aligned;
+struct rnp_eth_adapter {
+ struct rnp_hw hw;
+ struct rte_pci_device *pdev;
+ struct rte_eth_dev *eth_dev; /* master eth_dev */
+ struct rnp_eth_port *ports[RNP_MAX_PORT_OF_PF];
+ struct rnp_share_ops *share_priv;
+
+ uint8_t num_ports; /* Cur Pf Has physical Port Num */
+} __rte_cache_aligned;
+
+#define RNP_DEV_TO_PORT(eth_dev) \
+ (((struct rnp_eth_port *)((eth_dev)->data->dev_private)))
+#define RNP_DEV_TO_ADAPTER(eth_dev) \
+ ((struct rnp_eth_adapter *)(RNP_DEV_TO_PORT(eth_dev)->adapt))
+
#endif /* __RNP_H__ */
diff --git a/drivers/net/rnp/rnp_ethdev.c b/drivers/net/rnp/rnp_ethdev.c
index 5951c2b311..18fd169166 100644
--- a/drivers/net/rnp/rnp_ethdev.c
+++ b/drivers/net/rnp/rnp_ethdev.c
@@ -5,23 +5,199 @@
#include <ethdev_pci.h>
#include <rte_io.h>
#include <rte_malloc.h>
+#include <ethdev_driver.h>
#include "rnp.h"
+#include "rnp_logs.h"
static int
-rnp_eth_dev_init(struct rte_eth_dev *eth_dev)
+rnp_mac_rx_disable(struct rte_eth_dev *dev)
{
- RTE_SET_USED(eth_dev);
+ RTE_SET_USED(dev);
- return -ENODEV;
+ return 0;
+}
+
+static int
+rnp_mac_tx_disable(struct rte_eth_dev *dev)
+{
+ RTE_SET_USED(dev);
+
+ return 0;
+}
+
+static int rnp_dev_close(struct rte_eth_dev *dev)
+{
+ RTE_SET_USED(dev);
+
+ return 0;
+}
+
+/* Features supported by this driver */
+static const struct eth_dev_ops rnp_eth_dev_ops = {
+};
+
+static int
+rnp_init_port_resource(struct rnp_eth_adapter *adapter,
+ struct rte_eth_dev *dev,
+ char *name,
+ uint8_t p_id)
+{
+ struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
+
+ port->eth_dev = dev;
+ adapter->ports[p_id] = port;
+ dev->dev_ops = &rnp_eth_dev_ops;
+ RTE_SET_USED(name);
+
+ return 0;
+}
+
+static struct rte_eth_dev *
+rnp_alloc_eth_port(struct rte_pci_device *master_pci, char *name)
+{
+ struct rnp_eth_port *port;
+ struct rte_eth_dev *eth_dev;
+
+ eth_dev = rte_eth_dev_allocate(name);
+ if (!eth_dev) {
+ RNP_PMD_DRV_LOG(ERR, "Could not allocate "
+ "eth_dev for %s\n", name);
+ return NULL;
+ }
+ port = rte_zmalloc_socket(name,
+ sizeof(*port),
+ RTE_CACHE_LINE_SIZE,
+ master_pci->device.numa_node);
+ if (!port) {
+ RNP_PMD_DRV_LOG(ERR, "Could not allocate "
+ "rnp_eth_port for %s\n", name);
+ return NULL;
+ }
+ eth_dev->data->dev_private = port;
+ eth_dev->process_private = calloc(1, sizeof(struct rnp_share_ops));
+ if (!eth_dev->process_private) {
+ RNP_PMD_DRV_LOG(ERR, "Could not calloc "
+ "for Process_priv\n");
+ goto fail_calloc;
+ }
+ return eth_dev;
+fail_calloc:
+ rte_free(port);
+ rte_eth_dev_release_port(eth_dev);
+
+ return NULL;
+}
+
+static int
+rnp_eth_dev_init(struct rte_eth_dev *dev)
+{
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+ struct rnp_eth_adapter *adapter = NULL;
+ char name[RTE_ETH_NAME_MAX_LEN] = " ";
+ struct rnp_eth_port *port = NULL;
+ struct rte_eth_dev *eth_dev;
+ struct rnp_hw *hw = NULL;
+ int32_t p_id;
+ int ret;
+
+ PMD_INIT_FUNC_TRACE();
+
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return 0;
+ memset(name, 0, sizeof(name));
+ snprintf(name, sizeof(name), "rnp_adapter_%d", dev->data->port_id);
+ adapter = rte_zmalloc(name, sizeof(struct rnp_eth_adapter), 0);
+ if (!adapter) {
+ RNP_PMD_DRV_LOG(ERR, "zmalloc for adapter failed\n");
+ return -ENOMEM;
+ }
+ hw = &adapter->hw;
+ adapter->pdev = pci_dev;
+ adapter->eth_dev = dev;
+ adapter->num_ports = 1;
+ hw->back = (void *)adapter;
+ hw->iobar4 = (char *)pci_dev->mem_resource[RNP_CFG_BAR].addr;
+ hw->iobar0 = (char *)pci_dev->mem_resource[RNP_PF_INFO_BAR].addr;
+ hw->iobar4_len = pci_dev->mem_resource[RNP_CFG_BAR].len;
+ hw->iobar0_len = pci_dev->mem_resource[RNP_PF_INFO_BAR].len;
+ hw->device_id = pci_dev->id.device_id;
+ hw->vendor_id = pci_dev->id.vendor_id;
+ hw->device_id = pci_dev->id.device_id;
+ for (p_id = 0; p_id < adapter->num_ports; p_id++) {
+ /* port 0 resource has been alloced When Probe */
+ if (!p_id) {
+ eth_dev = dev;
+ } else {
+ snprintf(name, sizeof(name), "%s_%d",
+ adapter->pdev->device.name,
+ p_id);
+ eth_dev = rnp_alloc_eth_port(pci_dev, name);
+ if (eth_dev)
+ rte_memcpy(eth_dev->process_private,
+ adapter->share_priv,
+ sizeof(*adapter->share_priv));
+ if (!eth_dev) {
+ ret = -ENOMEM;
+ goto eth_alloc_error;
+ }
+ }
+ ret = rnp_init_port_resource(adapter, eth_dev, name, p_id);
+ if (ret)
+ goto init_failed;
+
+ rnp_mac_rx_disable(eth_dev);
+ rnp_mac_tx_disable(eth_dev);
+ }
+
+ return 0;
+eth_alloc_error:
+init_failed:
+ for (p_id = 0; p_id < adapter->num_ports; p_id++) {
+ port = adapter->ports[p_id];
+ if (!port)
+ continue;
+ if (port->eth_dev) {
+ rnp_dev_close(port->eth_dev);
+ rte_eth_dev_release_port(port->eth_dev);
+ if (port->eth_dev->process_private)
+ free(port->eth_dev->process_private);
+ }
+ rte_free(port);
+ }
+ rte_free(adapter);
+
+ return 0;
}
static int
rnp_eth_dev_uninit(struct rte_eth_dev *eth_dev)
{
- RTE_SET_USED(eth_dev);
+ struct rnp_eth_adapter *adapter = RNP_DEV_TO_ADAPTER(eth_dev);
+ struct rnp_eth_port *port = NULL;
+ uint8_t p_id;
+
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return 0;
- return -ENODEV;
+ if (adapter->eth_dev != eth_dev) {
+ RNP_PMD_DRV_LOG(ERR, "Input Argument ethdev "
+ "Isn't Master Ethdev\n");
+ return -EINVAL;
+ }
+ for (p_id = 0; p_id < adapter->num_ports; p_id++) {
+ port = adapter->ports[p_id];
+ if (!port)
+ continue;
+ if (port->eth_dev) {
+ rnp_dev_close(port->eth_dev);
+ /* Just Relase Not Master Port Alloced By PMD */
+ if (p_id)
+ rte_eth_dev_release_port(port->eth_dev);
+ }
+ }
+
+ return 0;
}
static int
@@ -84,3 +260,14 @@ static struct rte_pci_driver rte_rnp_pmd = {
RTE_PMD_REGISTER_PCI(net_rnp, rte_rnp_pmd);
RTE_PMD_REGISTER_PCI_TABLE(net_rnp, pci_id_rnp_map);
RTE_PMD_REGISTER_KMOD_DEP(net_txgbe, "igb_uio | uio_pci_generic");
+
+RTE_LOG_REGISTER_SUFFIX(rnp_init_logtype, init, NOTICE);
+RTE_LOG_REGISTER_SUFFIX(rnp_drv_logtype, driver, NOTICE);
+
+#ifdef RTE_LIBRTE_RNP_DEBUG_RX
+ RTE_LOG_REGISTER_SUFFIX(rnp_rx_logtype, rx, DEBUG);
+#endif
+
+#ifdef RTE_LIBRTE_RNP_DEBUG_TX
+ RTE_LOG_REGISTER_SUFFIX(rnp_tx_logtype, tx, DEBUG);
+#endif
diff --git a/drivers/net/rnp/rnp_logs.h b/drivers/net/rnp/rnp_logs.h
new file mode 100644
index 0000000000..1b3ee33745
--- /dev/null
+++ b/drivers/net/rnp/rnp_logs.h
@@ -0,0 +1,34 @@
+#ifndef __RNP_LOGS_H__
+#define __RNP_LOGS_H__
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Mucse IC Design Ltd.
+ */
+extern int rnp_init_logtype;
+
+#define RNP_PMD_INIT_LOG(level, fmt, args...) \
+ rte_log(RTE_LOG_##level, rnp_init_logtype, \
+ "%s() " fmt, __func__, ##args)
+#define PMD_INIT_FUNC_TRACE() RNP_PMD_INIT_LOG(DEBUG, " >>")
+extern int rnp_drv_logtype;
+#define RNP_PMD_DRV_LOG(level, fmt, args...) \
+ rte_log(RTE_LOG_##level, rnp_drv_logtype, \
+ "%s() " fmt, __func__, ##args)
+#ifdef RTE_LIBRTE_RNP_DEBUG_RX
+extern int rnp_rx_logtype;
+#define RNP_PMD_RX_LOG(level, fmt, args...) \
+ rte_log(RTE_LOG_ ## level, rnp_rx_logtype, \
+ "%s(): " fmt "\n", __func__, ##args)
+#else
+#define RNP_PMD_RX_LOG(level, fmt, args...) do { } while (0)
+#endif
+
+#ifdef RTE_LIBRTE_RNP_DEBUG_TX
+extern int rnp_tx_logtype;
+#define PMD_TX_LOG(level, fmt, args...) \
+ rte_log(RTE_LOG_ ## level, rnp_tx_logtype, \
+ "%s(): " fmt "\n", __func__, ##args)
+#else
+#define PMD_TX_LOG(level, fmt, args...) do { } while (0)
+#endif
+
+#endif /* __RNP_LOGS_H__ */
diff --git a/drivers/net/rnp/rnp_osdep.h b/drivers/net/rnp/rnp_osdep.h
new file mode 100644
index 0000000000..5685dd2404
--- /dev/null
+++ b/drivers/net/rnp/rnp_osdep.h
@@ -0,0 +1,30 @@
+#ifndef __RNP_OSDEP_H__
+#define __RNP_OSDEP_H__
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Mucse IC Design Ltd.
+ */
+#include <stdint.h>
+
+#include <rte_byteorder.h>
+
+#define __iomem
+#define _RING_(off) ((off) + 0x000000)
+#define _DMA_(off) ((off))
+#define _GLB_(off) ((off) + 0x000000)
+#define _NIC_(off) ((off) + 0x000000)
+#define _ETH_(off) ((off))
+#define _MAC_(off) ((off))
+#define BIT(n) (1UL << (n))
+#define BIT64(n) (1ULL << (n))
+#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
+#define GENMASK(h, l) \
+ (((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+typedef int32_t s32;
+typedef int16_t s16;
+typedef int8_t s8;
+#endif /* __RNP_OSDEP_H__ */
--
2.27.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [[PATCH v1] 3/8] net/rnp: add device init and uninit
2023-08-01 6:43 ` [[PATCH v1] 3/8] net/rnp: add device init and uninit Wenbo Cao
@ 2023-08-01 15:20 ` Stephen Hemminger
2023-08-02 2:23 ` 11
0 siblings, 1 reply; 11+ messages in thread
From: Stephen Hemminger @ 2023-08-01 15:20 UTC (permalink / raw)
To: Wenbo Cao; +Cc: Anatoly Burakov, dev
On Tue, 1 Aug 2023 06:43:41 +0000
Wenbo Cao <caowenbo@mucse.com> wrote:
> + return 0;
> +eth_alloc_error:
> +init_failed:
Why have two labels for same place, to later patches insert code here?
^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: [[PATCH v1] 3/8] net/rnp: add device init and uninit
2023-08-01 15:20 ` Stephen Hemminger
@ 2023-08-02 2:23 ` 11
0 siblings, 0 replies; 11+ messages in thread
From: 11 @ 2023-08-02 2:23 UTC (permalink / raw)
To: 'Stephen Hemminger'; +Cc: 'Anatoly Burakov', dev
Hi Stephen,
Why have two labels for same place, to later patches insert code here?
For this question the new code in rnp_init_port_resource
Will zmalloc dev->data->mac_addrs and dev->data->hash_mac_addrs
So I wish to free the zmalloc mem when init port resource failed
Regards wenbo
-----Original Message-----
From: Stephen Hemminger <stephen@networkplumber.org>
Sent: 2023年8月1日 23:21
To: Wenbo Cao <caowenbo@mucse.com>
Cc: Anatoly Burakov <anatoly.burakov@intel.com>; dev@dpdk.org
Subject: Re: [[PATCH v1] 3/8] net/rnp: add device init and uninit
On Tue, 1 Aug 2023 06:43:41 +0000
Wenbo Cao <caowenbo@mucse.com> wrote:
> + return 0;
> +eth_alloc_error:
> +init_failed:
Why have two labels for same place, to later patches insert code here?
^ permalink raw reply [flat|nested] 11+ messages in thread
* [[PATCH v1] 4/8] net/rnp: add mbx basic api feature
2023-08-01 6:43 [[PATCH v1] 0/8] *** SUBJECT HERE *** Wenbo Cao
` (2 preceding siblings ...)
2023-08-01 6:43 ` [[PATCH v1] 3/8] net/rnp: add device init and uninit Wenbo Cao
@ 2023-08-01 6:43 ` Wenbo Cao
2023-08-01 6:43 ` [[PATCH v1] 5/8] net/rnp add reset code for Chip Init process Wenbo Cao
` (2 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Wenbo Cao @ 2023-08-01 6:43 UTC (permalink / raw)
To: caowenbo; +Cc: dev
mbx base code is for communicate with the firmware
Signed-off-by: Wenbo Cao <caowenbo@mucse.com>
---
drivers/net/rnp/base/rnp_hw.h | 107 ++++++-
drivers/net/rnp/meson.build | 1 +
drivers/net/rnp/rnp.h | 35 +++
drivers/net/rnp/rnp_ethdev.c | 68 +++++
drivers/net/rnp/rnp_logs.h | 9 +
drivers/net/rnp/rnp_mbx.c | 522 ++++++++++++++++++++++++++++++++++
drivers/net/rnp/rnp_mbx.h | 138 +++++++++
drivers/net/rnp/rnp_mbx_fw.h | 22 ++
8 files changed, 901 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/rnp/rnp_mbx.c
create mode 100644 drivers/net/rnp/rnp_mbx.h
create mode 100644 drivers/net/rnp/rnp_mbx_fw.h
diff --git a/drivers/net/rnp/base/rnp_hw.h b/drivers/net/rnp/base/rnp_hw.h
index 543011a64c..da3659bd67 100644
--- a/drivers/net/rnp/base/rnp_hw.h
+++ b/drivers/net/rnp/base/rnp_hw.h
@@ -4,15 +4,120 @@
#ifndef __RNP_HW_H__
#define __RNP_HW_H__
+#include <rte_io.h>
+#include <ethdev_driver.h>
+
+#include "rnp_osdep.h"
+
+static inline unsigned int rnp_rd_reg(volatile void *addr)
+{
+ unsigned int v = rte_read32(addr);
+
+ return v;
+}
+
+static inline void rnp_wr_reg(volatile void *reg, int val)
+{
+ rte_write32_relaxed((val), (reg));
+}
+
+#define mbx_rd32(hw, reg) rnp_rd_reg((hw)->iobar4 + (reg))
+#define mbx_wr32(hw, reg, val) rnp_wr_reg((hw)->iobar4 + (reg), (val))
+
+struct rnp_hw;
+/* Mbx Operate info */
+enum MBX_ID {
+ MBX_PF = 0,
+ MBX_VF,
+ MBX_CM3CPU,
+ MBX_FW = MBX_CM3CPU,
+ MBX_VFCNT
+};
+struct rnp_mbx_api {
+ void (*init_mbx)(struct rnp_hw *hw);
+ int32_t (*read)(struct rnp_hw *hw,
+ uint32_t *msg,
+ uint16_t size,
+ enum MBX_ID);
+ int32_t (*write)(struct rnp_hw *hw,
+ uint32_t *msg,
+ uint16_t size,
+ enum MBX_ID);
+ int32_t (*read_posted)(struct rte_eth_dev *dev,
+ uint32_t *msg,
+ uint16_t size,
+ enum MBX_ID);
+ int32_t (*write_posted)(struct rte_eth_dev *dev,
+ uint32_t *msg,
+ uint16_t size,
+ enum MBX_ID);
+ int32_t (*check_for_msg)(struct rnp_hw *hw, enum MBX_ID);
+ int32_t (*check_for_ack)(struct rnp_hw *hw, enum MBX_ID);
+ int32_t (*check_for_rst)(struct rnp_hw *hw, enum MBX_ID);
+ int32_t (*configure)(struct rnp_hw *hw, int nr_vec, bool enable);
+};
+
+struct rnp_mbx_stats {
+ u32 msgs_tx;
+ u32 msgs_rx;
+
+ u32 acks;
+ u32 reqs;
+ u32 rsts;
+};
+
+struct rnp_mbx_info {
+ struct rnp_mbx_api ops;
+ uint32_t usec_delay; /* retry interval delay time */
+ uint32_t timeout; /* retry ops timeout limit */
+ uint16_t size; /* data buffer size*/
+ uint16_t vf_num; /* Virtual Function num */
+ uint16_t pf_num; /* Physical Function num */
+ uint16_t sriov_st; /* Sriov state */
+ bool irq_enabled;
+ union {
+ struct {
+ unsigned short pf_req;
+ unsigned short pf_ack;
+ };
+ struct {
+ unsigned short cpu_req;
+ unsigned short cpu_ack;
+ };
+ };
+ unsigned short vf_req[64];
+ unsigned short vf_ack[64];
+
+ struct rnp_mbx_stats stats;
+
+ rte_atomic16_t state;
+} __rte_cache_aligned;
+
+#define RNP_MAX_HW_PORT_PERR_PF (4)
struct rnp_hw {
void *back;
char *iobar0;
uint32_t iobar0_len;
char *iobar4;
uint32_t iobar4_len;
+ char *link_sync;
+ char *dma_base;
+ char *eth_base;
+ char *veb_base;
+ char *mac_base[RNP_MAX_HW_PORT_PERR_PF];
+ char *msix_base;
+ /* === dma == */
+ char *dma_axi_en;
+ char *dma_axi_st;
uint16_t device_id;
uint16_t vendor_id;
-} __rte_cache_aligned;
+ uint16_t function;
+ uint16_t pf_vf_num;
+ uint16_t max_vfs;
+ void *cookie_pool;
+ char cookie_p_name[RTE_MEMZONE_NAMESIZE];
+ struct rnp_mbx_info mbx;
+} __rte_cache_aligned;
#endif /* __RNP_H__*/
diff --git a/drivers/net/rnp/meson.build b/drivers/net/rnp/meson.build
index 36a1f7148d..38dbee5ca4 100644
--- a/drivers/net/rnp/meson.build
+++ b/drivers/net/rnp/meson.build
@@ -9,5 +9,6 @@ endif
sources = files(
'rnp_ethdev.c',
+ 'rnp_mbx.c',
)
includes += include_directories('base')
diff --git a/drivers/net/rnp/rnp.h b/drivers/net/rnp/rnp.h
index ea9d138673..a8999ddc47 100644
--- a/drivers/net/rnp/rnp.h
+++ b/drivers/net/rnp/rnp.h
@@ -3,6 +3,7 @@
*/
#ifndef __RNP_H__
#define __RNP_H__
+#include <rte_log.h>
#include "base/rnp_hw.h"
@@ -14,14 +15,17 @@
struct rnp_eth_port {
void *adapt;
+ struct rnp_hw *hw;
struct rte_eth_dev *eth_dev;
} __rte_cache_aligned;
struct rnp_share_ops {
+ struct rnp_mbx_api mbx_api;
} __rte_cache_aligned;
struct rnp_eth_adapter {
struct rnp_hw hw;
+ uint16_t max_vfs;
struct rte_pci_device *pdev;
struct rte_eth_dev *eth_dev; /* master eth_dev */
struct rnp_eth_port *ports[RNP_MAX_PORT_OF_PF];
@@ -34,5 +38,36 @@ struct rnp_eth_adapter {
(((struct rnp_eth_port *)((eth_dev)->data->dev_private)))
#define RNP_DEV_TO_ADAPTER(eth_dev) \
((struct rnp_eth_adapter *)(RNP_DEV_TO_PORT(eth_dev)->adapt))
+#define RNP_DEV_TO_HW(eth_dev) \
+ (&((struct rnp_eth_adapter *)(RNP_DEV_TO_PORT((eth_dev))->adapt))->hw)
+#define RNP_DEV_PP_PRIV_TO_MBX_OPS(dev) \
+ (&((struct rnp_share_ops *)(dev)->process_private)->mbx_api)
+#define RNP_DEV_TO_MBX_OPS(dev) RNP_DEV_PP_PRIV_TO_MBX_OPS(dev)
+static inline void rnp_reg_offset_init(struct rnp_hw *hw)
+{
+ uint16_t i;
+
+ if (hw->device_id == RNP_DEV_ID_N10G && hw->mbx.pf_num) {
+ hw->iobar4 += 0x100000;
+ hw->msix_base = hw->iobar4 + 0xa0000;
+ hw->msix_base += 0x200;
+ } else {
+ hw->msix_base = hw->iobar4 + 0xa0000;
+ }
+ /* === dma status/config====== */
+ hw->link_sync = hw->iobar4 + 0x000c;
+ hw->dma_axi_en = hw->iobar4 + 0x0010;
+ hw->dma_axi_st = hw->iobar4 + 0x0014;
+
+ if (hw->mbx.pf_num)
+ hw->msix_base += 0x200;
+ /* === queue registers === */
+ hw->dma_base = hw->iobar4 + 0x08000;
+ hw->veb_base = hw->iobar4 + 0x0;
+ hw->eth_base = hw->iobar4 + 0x10000;
+ /* mac */
+ for (i = 0; i < RNP_MAX_HW_PORT_PERR_PF; i++)
+ hw->mac_base[i] = hw->iobar4 + 0x60000 + 0x10000 * i;
+}
#endif /* __RNP_H__ */
diff --git a/drivers/net/rnp/rnp_ethdev.c b/drivers/net/rnp/rnp_ethdev.c
index 18fd169166..4747a41423 100644
--- a/drivers/net/rnp/rnp_ethdev.c
+++ b/drivers/net/rnp/rnp_ethdev.c
@@ -8,8 +8,10 @@
#include <ethdev_driver.h>
#include "rnp.h"
+#include "rnp_mbx.h"
#include "rnp_logs.h"
+extern struct rnp_mbx_api rnp_mbx_pf_ops;
static int
rnp_mac_rx_disable(struct rte_eth_dev *dev)
{
@@ -89,6 +91,59 @@ rnp_alloc_eth_port(struct rte_pci_device *master_pci, char *name)
return NULL;
}
+static void rnp_get_nic_attr(struct rnp_eth_adapter *adapter)
+{
+ RTE_SET_USED(adapter);
+}
+
+static int
+rnp_process_resource_init(struct rte_eth_dev *eth_dev)
+{
+ struct rnp_share_ops *share_priv;
+
+ /* allocate process_private memory this must can't
+ * belone to the dpdk mem resource manager
+ * such as from rte_malloc or rte_dma_zone..
+ */
+ /* use the process_prive point to resolve secondary process
+ * use point-func. This point is per process will be safe to cover.
+ * This will cause secondary process core-dump because of IPC
+ * Secondary will call primary process point func virt-address
+ * secondary process don't alloc user/pmd to alloc or free
+ * the memory of dpdk-mem resource it will cause hugepage
+ * mem exception
+ * be careful for secondary Process to use the share-mem of
+ * point correlation
+ */
+ share_priv = calloc(1, sizeof(*share_priv));
+ if (!share_priv) {
+ PMD_DRV_LOG(ERR, "calloc share_priv failed");
+ return -ENOMEM;
+ }
+
+ eth_dev->process_private = share_priv;
+ adapter->share_priv = share_priv;
+
+ return 0;
+}
+
+static void
+rnp_common_ops_init(struct rnp_eth_adapter *adapter)
+{
+ struct rnp_share_ops *share_priv;
+
+ share_priv = adapter->share_priv;
+ share_priv->mbx_api = rnp_mbx_pf_ops;
+}
+
+static int
+rnp_special_ops_init(struct rte_eth_dev *eth_dev)
+{
+ RTE_SET_USED(eth_dev);
+
+ return 0;
+}
+
static int
rnp_eth_dev_init(struct rte_eth_dev *dev)
{
@@ -124,6 +179,19 @@ rnp_eth_dev_init(struct rte_eth_dev *dev)
hw->device_id = pci_dev->id.device_id;
hw->vendor_id = pci_dev->id.vendor_id;
hw->device_id = pci_dev->id.device_id;
+ adapter->max_vfs = pci_dev->max_vfs;
+ ret = rnp_process_resource_init(dev, adapter);
+ if (ret) {
+ PMD_DRV_LOG(ERR, "share prive resource init failed");
+ return ret;
+ }
+ rnp_common_ops_init(adapter);
+ rnp_get_nic_attr(adapter);
+ /* We need Use Device Id To Change The Resource Mode */
+ rnp_special_ops_init(dev);
+ port->adapt = adapter;
+ port->hw = hw;
+ rnp_init_mbx_ops_pf(hw);
for (p_id = 0; p_id < adapter->num_ports; p_id++) {
/* port 0 resource has been alloced When Probe */
if (!p_id) {
diff --git a/drivers/net/rnp/rnp_logs.h b/drivers/net/rnp/rnp_logs.h
index 1b3ee33745..f1648aabb5 100644
--- a/drivers/net/rnp/rnp_logs.h
+++ b/drivers/net/rnp/rnp_logs.h
@@ -13,6 +13,15 @@ extern int rnp_drv_logtype;
#define RNP_PMD_DRV_LOG(level, fmt, args...) \
rte_log(RTE_LOG_##level, rnp_drv_logtype, \
"%s() " fmt, __func__, ##args)
+#define PMD_DRV_LOG_RAW(level, fmt, args...) \
+ rte_log(RTE_LOG_ ## level, rnp_drv_logtype, "%s(): " fmt, \
+ __func__, ## args)
+#define PMD_DRV_LOG(level, fmt, args...) \
+ PMD_DRV_LOG_RAW(level, fmt "\n", ## args)
+
+#define RNP_PMD_LOG(level, fmt, args...) \
+ rte_log(RTE_LOG_##level, rnp_drv_logtype, \
+ "rnp_net: (%d) " fmt, __LINE__, ##args)
#ifdef RTE_LIBRTE_RNP_DEBUG_RX
extern int rnp_rx_logtype;
#define RNP_PMD_RX_LOG(level, fmt, args...) \
diff --git a/drivers/net/rnp/rnp_mbx.c b/drivers/net/rnp/rnp_mbx.c
new file mode 100644
index 0000000000..0f1c0a5b74
--- /dev/null
+++ b/drivers/net/rnp/rnp_mbx.c
@@ -0,0 +1,522 @@
+#include <rte_cycles.h>
+#include <rte_log.h>
+
+#include "rnp.h"
+#include "rnp_hw.h"
+#include "rnp_mbx.h"
+#include "rnp_mbx_fw.h"
+#include "rnp_logs.h"
+
+#define RNP_MAX_VF_FUNCTIONS (64)
+/* == VEC == */
+#define VF2PF_MBOX_VEC(VF) (0xa5100 + 4 * (VF))
+#define CPU2PF_MBOX_VEC (0xa5300)
+
+/* == PF <--> VF mailbox ==== */
+#define SHARE_MEM_BYTES (64) /* 64bytes */
+/* for PF1 rtl will remap 6000 to 0xb000 */
+#define PF_VF_SHM(vf) ((0xa6000) + (64 * (vf)))
+#define PF2VF_COUNTER(vf) (PF_VF_SHM(vf) + 0)
+#define VF2PF_COUNTER(vf) (PF_VF_SHM(vf) + 4)
+#define PF_VF_SHM_DATA(vf) (PF_VF_SHM(vf) + 8)
+#define PF2VF_MBOX_CTRL(vf) ((0xa7100) + (4 * (vf)))
+#define PF_VF_MBOX_MASK_LO ((0xa7200))
+#define PF_VF_MBOX_MASK_HI ((0xa7300))
+
+/* === CPU <--> PF === */
+#define CPU_PF_SHM (0xaa000)
+#define CPU2PF_COUNTER (CPU_PF_SHM + 0)
+#define PF2CPU_COUNTER (CPU_PF_SHM + 4)
+#define CPU_PF_SHM_DATA (CPU_PF_SHM + 8)
+#define PF2CPU_MBOX_CTRL (0xaa100)
+#define CPU_PF_MBOX_MASK (0xaa300)
+
+/* === CPU <--> VF === */
+#define CPU_VF_SHM(vf) (0xa8000 + (64 * (vf)))
+#define CPU2VF_COUNTER(vf) (CPU_VF_SHM(vf) + 0)
+#define VF2CPU_COUNTER(vf) (CPU_VF_SHM(vf) + 4)
+#define CPU_VF_SHM_DATA(vf) (CPU_VF_SHM(vf) + 8)
+#define VF2CPU_MBOX_CTRL(vf) (0xa9000 + 64 * (vf))
+#define CPU_VF_MBOX_MASK_LO(vf) (0xa9200 + 64 * (vf))
+#define CPU_VF_MBOX_MASK_HI(vf) (0xa9300 + 64 * (vf))
+
+#define MBOX_CTRL_REQ (1 << 0) /* WO */
+/* VF:WR, PF:RO */
+#define MBOX_CTRL_PF_HOLD_SHM (1 << 3) /* VF:RO, PF:WR */
+
+#define MBOX_IRQ_EN (0)
+#define MBOX_IRQ_DISABLE (1)
+
+/****************************PF MBX OPS************************************/
+static inline u16 rnp_mbx_get_req(struct rnp_hw *hw, int reg)
+{
+ rte_mb();
+ return mbx_rd32(hw, reg) & 0xffff;
+}
+
+static inline u16 rnp_mbx_get_ack(struct rnp_hw *hw, int reg)
+{
+ rte_mb();
+ return (mbx_rd32(hw, reg) >> 16) & 0xffff;
+}
+
+static inline void rnp_mbx_inc_pf_req(struct rnp_hw *hw, enum MBX_ID mbx_id)
+{
+ int reg = (mbx_id == MBX_CM3CPU) ?
+ PF2CPU_COUNTER : PF2VF_COUNTER(mbx_id);
+ u32 v = mbx_rd32(hw, reg);
+ u16 req;
+
+ req = (v & 0xffff);
+ req++;
+ v &= ~(0x0000ffff);
+ v |= req;
+
+ rte_mb();
+ mbx_wr32(hw, reg, v);
+
+ /* update stats */
+ /* hw->mbx.stats.msgs_tx++; */
+}
+
+static inline void rnp_mbx_inc_pf_ack(struct rnp_hw *hw, enum MBX_ID mbx_id)
+{
+ int reg = (mbx_id == MBX_CM3CPU) ?
+ PF2CPU_COUNTER : PF2VF_COUNTER(mbx_id);
+ u32 v = mbx_rd32(hw, reg);
+ u16 ack;
+
+ ack = (v >> 16) & 0xffff;
+ ack++;
+ v &= ~(0xffff0000);
+ v |= (ack << 16);
+
+ rte_mb();
+ mbx_wr32(hw, reg, v);
+
+ /* update stats */
+ /* hw->mbx.stats.msgs_rx++; */
+}
+
+/**
+ * rnp_poll_for_msg - Wait for message notification
+ * @hw: pointer to the HW structure
+ * @mbx_id: id of mailbox to write
+ *
+ * returns SUCCESS if it successfully received a message notification
+ **/
+static int32_t rnp_poll_for_msg(struct rte_eth_dev *dev, enum MBX_ID mbx_id)
+{
+ struct rnp_mbx_api *ops = RNP_DEV_TO_MBX_OPS(dev);
+ struct rnp_hw *hw = RNP_DEV_TO_HW(dev);
+ struct rnp_mbx_info *mbx = &hw->mbx;
+ int countdown = mbx->timeout;
+
+ if (!countdown || !ops->check_for_msg)
+ goto out;
+
+ while (countdown && ops->check_for_msg(hw, mbx_id)) {
+ countdown--;
+ if (!countdown)
+ break;
+ rte_delay_us_block(mbx->usec_delay);
+ }
+
+out:
+ return countdown ? 0 : -ETIME;
+}
+
+/**
+ * rnp_poll_for_ack - Wait for message acknowledgment
+ * @hw: pointer to the HW structure
+ * @mbx_id: id of mailbox to write
+ *
+ * returns SUCCESS if it successfully received a message acknowledgment
+ **/
+static int32_t rnp_poll_for_ack(struct rte_eth_dev *dev, enum MBX_ID mbx_id)
+{
+ struct rnp_mbx_api *ops = RNP_DEV_TO_MBX_OPS(dev);
+ struct rnp_hw *hw = RNP_DEV_TO_HW(dev);
+ struct rnp_mbx_info *mbx = &hw->mbx;
+ int countdown = mbx->timeout;
+
+ if (!countdown || !ops->check_for_ack)
+ goto out;
+
+ while (countdown && ops->check_for_ack(hw, mbx_id)) {
+ countdown--;
+ if (!countdown)
+ break;
+ rte_delay_us_block(mbx->usec_delay);
+ }
+
+out:
+ return countdown ? 0 : -ETIME;
+}
+
+/**
+ * rnp_read_posted_mbx - Wait for message notification and receive message
+ * @hw: pointer to the HW structure
+ * @msg: The message buffer
+ * @size: Length of buffer
+ * @mbx_id: id of mailbox to write
+ *
+ * returns SUCCESS if it successfully received a message notification and
+ * copied it into the receive buffer.
+ **/
+static int32_t
+rnp_read_posted_mbx_pf(struct rte_eth_dev *dev, u32 *msg, u16 size,
+ enum MBX_ID mbx_id)
+{
+ struct rnp_mbx_api *ops = RNP_DEV_TO_MBX_OPS(dev);
+ struct rnp_hw *hw = RNP_DEV_TO_HW(dev);
+ struct rnp_mbx_info *mbx = &hw->mbx;
+ int countdown = mbx->timeout;
+ int32_t ret_val = -ETIME;
+
+ if (!ops->read || !countdown)
+ return -EOPNOTSUPP;
+
+ ret_val = rnp_poll_for_msg(dev, mbx_id);
+
+ /* if ack received read message, otherwise we timed out */
+ if (!ret_val)
+ return ops->read(hw, msg, size, mbx_id);
+ return ret_val;
+}
+
+/**
+ * rnp_write_posted_mbx - Write a message to the mailbox, wait for ack
+ * @hw: pointer to the HW structure
+ * @msg: The message buffer
+ * @size: Length of buffer
+ * @mbx_id: id of mailbox to write
+ *
+ * returns SUCCESS if it successfully copied message into the buffer and
+ * received an ack to that message within delay * timeout period
+ **/
+static int32_t
+rnp_write_posted_mbx_pf(struct rte_eth_dev *dev, u32 *msg, u16 size,
+ enum MBX_ID mbx_id)
+{
+ struct rnp_mbx_api *ops = RNP_DEV_TO_MBX_OPS(dev);
+ struct rnp_hw *hw = RNP_DEV_TO_HW(dev);
+ struct rnp_mbx_info *mbx = &hw->mbx;
+ int32_t ret_val = -ETIME;
+
+ /* exit if either we can't write or there isn't a defined timeout */
+ if (!ops->write || !mbx->timeout)
+ goto out;
+
+ /* send msg and hold buffer lock */
+ if (ops->write)
+ ret_val = ops->write(hw, msg, size, mbx_id);
+
+ /* if msg sent wait until we receive an ack */
+ if (!ret_val)
+ ret_val = rnp_poll_for_ack(dev, mbx_id);
+out:
+ return ret_val;
+}
+
+/**
+ * rnp_check_for_msg_pf - checks to see if the VF has sent mail
+ * @hw: pointer to the HW structure
+ * @vf_number: the VF index
+ *
+ * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
+ **/
+static int32_t rnp_check_for_msg_pf(struct rnp_hw *hw, enum MBX_ID mbx_id)
+{
+ int32_t ret_val = -ETIME;
+
+ if (mbx_id == MBX_CM3CPU) {
+ if (rnp_mbx_get_req(hw, CPU2PF_COUNTER) != hw->mbx.cpu_req) {
+ ret_val = 0;
+ /* hw->mbx.stats.reqs++; */
+ }
+ } else {
+ if (rnp_mbx_get_req(hw, VF2PF_COUNTER(mbx_id)) !=
+ hw->mbx.vf_req[mbx_id]) {
+ ret_val = 0;
+ /* hw->mbx.stats.reqs++; */
+ }
+ }
+
+ return ret_val;
+}
+
+/**
+ * rnp_check_for_ack_pf - checks to see if the VF has ACKed
+ * @hw: pointer to the HW structure
+ * @vf_number: the VF index
+ *
+ * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
+ **/
+static int32_t rnp_check_for_ack_pf(struct rnp_hw *hw, enum MBX_ID mbx_id)
+{
+ int32_t ret_val = -ETIME;
+
+ if (mbx_id == MBX_CM3CPU) {
+ if (rnp_mbx_get_ack(hw, CPU2PF_COUNTER) != hw->mbx.cpu_ack) {
+ ret_val = 0;
+ /* hw->mbx.stats.acks++; */
+ }
+ } else {
+ if (rnp_mbx_get_ack(hw, VF2PF_COUNTER(mbx_id)) != hw->mbx.vf_ack[mbx_id]) {
+ ret_val = 0;
+ /* hw->mbx.stats.acks++; */
+ }
+ }
+
+ return ret_val;
+}
+
+/**
+ * rnp_obtain_mbx_lock_pf - obtain mailbox lock
+ * @hw: pointer to the HW structure
+ * @mbx_id: the VF index or CPU
+ *
+ * return SUCCESS if we obtained the mailbox lock
+ **/
+static int32_t rnp_obtain_mbx_lock_pf(struct rnp_hw *hw, enum MBX_ID mbx_id)
+{
+ int32_t ret_val = -ETIME;
+ int try_cnt = 5000; /* 500ms */
+ u32 CTRL_REG = (mbx_id == MBX_CM3CPU) ?
+ PF2CPU_MBOX_CTRL : PF2VF_MBOX_CTRL(mbx_id);
+
+ while (try_cnt-- > 0) {
+ /* Take ownership of the buffer */
+ mbx_wr32(hw, CTRL_REG, MBOX_CTRL_PF_HOLD_SHM);
+
+ /* reserve mailbox for cm3 use */
+ if (mbx_rd32(hw, CTRL_REG) & MBOX_CTRL_PF_HOLD_SHM)
+ return 0;
+ rte_delay_us_block(100);
+ }
+
+ RNP_PMD_LOG(WARNING, "%s: failed to get:%d lock\n",
+ __func__, mbx_id);
+ return ret_val;
+}
+
+/**
+ * rnp_write_mbx_pf - Places a message in the mailbox
+ * @hw: pointer to the HW structure
+ * @msg: The message buffer
+ * @size: Length of buffer
+ * @mbx_id: the VF index
+ *
+ * returns SUCCESS if it successfully copied message into the buffer
+ **/
+static int32_t rnp_write_mbx_pf(struct rnp_hw *hw, u32 *msg,
+ u16 size, enum MBX_ID mbx_id)
+{
+ u32 DATA_REG = (mbx_id == MBX_CM3CPU) ?
+ CPU_PF_SHM_DATA : PF_VF_SHM_DATA(mbx_id);
+ u32 CTRL_REG = (mbx_id == MBX_CM3CPU) ?
+ PF2CPU_MBOX_CTRL : PF2VF_MBOX_CTRL(mbx_id);
+ int32_t ret_val = 0;
+ u32 stat __rte_unused;
+ u16 i;
+
+ if (size > RNP_VFMAILBOX_SIZE) {
+ RNP_PMD_LOG(ERR, "%s: size:%d should <%d\n", __func__,
+ size, RNP_VFMAILBOX_SIZE);
+ return -EINVAL;
+ }
+
+ /* lock the mailbox to prevent pf/vf/cpu race condition */
+ ret_val = rnp_obtain_mbx_lock_pf(hw, mbx_id);
+ if (ret_val) {
+ RNP_PMD_LOG(WARNING, "PF[%d] Can't Get Mbx-Lock Try Again\n",
+ hw->function);
+ return ret_val;
+ }
+
+ /* copy the caller specified message to the mailbox memory buffer */
+ for (i = 0; i < size; i++) {
+#ifdef MBX_WR_DEBUG
+ mbx_pwr32(hw, DATA_REG + i * 4, msg[i]);
+#else
+ mbx_wr32(hw, DATA_REG + i * 4, msg[i]);
+#endif
+ }
+
+ /* flush msg and acks as we are overwriting the message buffer */
+ if (mbx_id == MBX_CM3CPU)
+ hw->mbx.cpu_ack = rnp_mbx_get_ack(hw, CPU2PF_COUNTER);
+ else
+ hw->mbx.vf_ack[mbx_id] = rnp_mbx_get_ack(hw, VF2PF_COUNTER(mbx_id));
+
+ rnp_mbx_inc_pf_req(hw, mbx_id);
+ rte_mb();
+
+ rte_delay_us(300);
+
+ /* Interrupt VF/CM3 to tell it a message
+ * has been sent and release buffer
+ */
+ mbx_wr32(hw, CTRL_REG, MBOX_CTRL_REQ);
+
+ return 0;
+}
+
+/**
+ * rnp_read_mbx_pf - Read a message from the mailbox
+ * @hw: pointer to the HW structure
+ * @msg: The message buffer
+ * @size: Length of buffer
+ * @vf_number: the VF index
+ *
+ * This function copies a message from the mailbox buffer to the caller's
+ * memory buffer. The presumption is that the caller knows that there was
+ * a message due to a VF/CPU request so no polling for message is needed.
+ **/
+static int32_t rnp_read_mbx_pf(struct rnp_hw *hw, u32 *msg,
+ u16 size, enum MBX_ID mbx_id)
+{
+ u32 BUF_REG = (mbx_id == MBX_CM3CPU) ?
+ CPU_PF_SHM_DATA : PF_VF_SHM_DATA(mbx_id);
+ u32 CTRL_REG = (mbx_id == MBX_CM3CPU) ?
+ PF2CPU_MBOX_CTRL : PF2VF_MBOX_CTRL(mbx_id);
+ int32_t ret_val = -EIO;
+ u32 stat __rte_unused, i;
+ if (size > RNP_VFMAILBOX_SIZE) {
+ RNP_PMD_LOG(ERR, "%s: size:%d should <%d\n", __func__,
+ size, RNP_VFMAILBOX_SIZE);
+ return -EINVAL;
+ }
+ /* lock the mailbox to prevent pf/vf race condition */
+ ret_val = rnp_obtain_mbx_lock_pf(hw, mbx_id);
+ if (ret_val)
+ goto out_no_read;
+
+ /* copy the message from the mailbox memory buffer */
+ for (i = 0; i < size; i++) {
+#ifdef MBX_RD_DEBUG
+ msg[i] = mbx_prd32(hw, BUF_REG + 4 * i);
+#else
+ msg[i] = mbx_rd32(hw, BUF_REG + 4 * i);
+#endif
+ }
+ mbx_wr32(hw, BUF_REG, 0);
+
+ /* update req. used by rnpvf_check_for_msg_vf */
+ if (mbx_id == MBX_CM3CPU)
+ hw->mbx.cpu_req = rnp_mbx_get_req(hw, CPU2PF_COUNTER);
+ else
+ hw->mbx.vf_req[mbx_id] = rnp_mbx_get_req(hw, VF2PF_COUNTER(mbx_id));
+
+ /* this ack maybe too earier? */
+ /* Acknowledge receipt and release mailbox, then we're done */
+ rnp_mbx_inc_pf_ack(hw, mbx_id);
+
+ rte_mb();
+
+ /* free ownership of the buffer */
+ mbx_wr32(hw, CTRL_REG, 0);
+
+out_no_read:
+
+ return ret_val;
+}
+
+static void rnp_mbx_reset_pf(struct rnp_hw *hw)
+{
+ int v;
+
+ /* reset pf->cm3 status */
+ v = mbx_rd32(hw, CPU2PF_COUNTER);
+ hw->mbx.cpu_req = v & 0xffff;
+ hw->mbx.cpu_ack = (v >> 16) & 0xffff;
+ /* release pf->cm3 buffer lock */
+ mbx_wr32(hw, PF2CPU_MBOX_CTRL, 0);
+
+ rte_mb();
+ /* enable irq to fw */
+ mbx_wr32(hw, CPU_PF_MBOX_MASK, 0);
+}
+
+static int get_pfvfnum(struct rnp_hw *hw)
+{
+ uint32_t addr_mask;
+ uint32_t offset;
+ uint32_t val;
+#define RNP_PF_NUM_REG (0x75f000)
+#define RNP_PFVF_SHIFT (4)
+#define RNP_PF_SHIFT (6)
+#define RNP_PF_BIT_MASK BIT(6)
+ addr_mask = hw->iobar0_len - 1;
+ offset = RNP_PF_NUM_REG & addr_mask;
+ val = rnp_rd_reg(hw->iobar0 + offset);
+
+ return val >> RNP_PFVF_SHIFT;
+}
+
+struct rnp_mbx_api rnp_mbx_pf_ops = {
+ .read = rnp_read_mbx_pf,
+ .write = rnp_write_mbx_pf,
+ .read_posted = rnp_read_posted_mbx_pf,
+ .write_posted = rnp_write_posted_mbx_pf,
+ .check_for_msg = rnp_check_for_msg_pf,
+ .check_for_ack = rnp_check_for_ack_pf,
+};
+
+void *rnp_memzone_reserve(const char *name, unsigned int size)
+{
+#define NO_FLAGS 0
+ const struct rte_memzone *mz = NULL;
+
+ if (name) {
+ if (size) {
+ mz = rte_memzone_reserve(name, size,
+ rte_socket_id(), NO_FLAGS);
+ if (mz)
+ memset(mz->addr, 0, size);
+ } else {
+ mz = rte_memzone_lookup(name);
+ }
+ return mz ? mz->addr : NULL;
+ }
+ return NULL;
+}
+
+void rnp_init_mbx_ops_pf(struct rnp_hw *hw)
+{
+ struct rnp_eth_adapter *adapter = hw->back;
+ struct rnp_mbx_info *mbx = &hw->mbx;
+ struct mbx_req_cookie *cookie;
+ uint32_t vf_isolat_off;
+
+ mbx->size = RNP_VFMAILBOX_SIZE;
+ mbx->usec_delay = RNP_MBX_DELAY_US;
+ mbx->timeout = (RNP_MBX_TIMEOUT_SECONDS * 1000 * 1000) /
+ mbx->usec_delay;
+ if (hw->device_id == RNP_DEV_ID_N10G) {
+ vf_isolat_off = RNP_VF_ISOLATE_CTRL &
+ (hw->iobar0_len - 1);
+ rnp_wr_reg(hw->iobar0 + vf_isolat_off, 0);
+ }
+ mbx->sriov_st = 0;
+ hw->pf_vf_num = get_pfvfnum(hw);
+ mbx->vf_num = UINT16_MAX;
+ mbx->pf_num = (hw->pf_vf_num & RNP_PF_BIT_MASK) >> RNP_PF_SHIFT;
+ hw->function = mbx->pf_num;
+ /* Retrieving and storing the HW base address of device */
+ rnp_reg_offset_init(hw);
+ snprintf(hw->cookie_p_name, RTE_MEMZONE_NAMESIZE, "mbx_req_cookie%d_%d",
+ hw->function, adapter->eth_dev->data->port_id);
+ hw->cookie_pool = rnp_memzone_reserve(hw->cookie_p_name,
+ sizeof(struct mbx_req_cookie));
+
+ cookie = (struct mbx_req_cookie *)hw->cookie_pool;
+ if (cookie) {
+ cookie->timeout_ms = 1000;
+ cookie->magic = COOKIE_MAGIC;
+ cookie->priv_len = RNP_MAX_SHARE_MEM;
+ }
+
+ rnp_mbx_reset_pf(hw);
+}
diff --git a/drivers/net/rnp/rnp_mbx.h b/drivers/net/rnp/rnp_mbx.h
new file mode 100644
index 0000000000..ee020b5fbc
--- /dev/null
+++ b/drivers/net/rnp/rnp_mbx.h
@@ -0,0 +1,138 @@
+#ifndef __TSRN10_MBX_H__
+#define __TSRN10_MBX_H__
+
+#define VF_NUM_MASK_TEMP (0xff0)
+#define VF_NUM_OFF (4)
+#define RNP_VF_NUM (0x75f000)
+#define RNP_VF_NB_MASK (0x3f)
+#define RNP_PF_NB_MASK (0x40)
+#define RNP_VF_ISOLATE_CTRL (0x7982fc)
+#define RNP_IS_SRIOV BIT(7)
+#define RNP_SRIOV_ST_SHIFT (24)
+#define RNP_VF_DEFAULT_PORT (0)
+
+/* Mbx Ctrl state */
+#define RNP_VFMAILBOX_SIZE (14) /* 16 32 bit words - 64 bytes */
+#define TSRN10_VFMBX_SIZE (RNP_VFMAILBOX_SIZE)
+#define RNP_VT_MSGTYPE_ACK (0x80000000)
+
+#define RNP_VT_MSGTYPE_NACK (0x40000000)
+/* Messages below or'd with * this are the NACK */
+#define RNP_VT_MSGTYPE_CTS (0x20000000)
+/* Indicates that VF is still
+ *clear to send requests
+ */
+#define RNP_VT_MSGINFO_SHIFT (16)
+
+#define RNP_VT_MSGINFO_MASK (0xFF << RNP_VT_MSGINFO_SHIFT)
+/* The mailbox memory size is 64 bytes accessed by 32-bit registers */
+#define RNP_VLVF_VIEN (0x80000000) /* filter is valid */
+#define RNP_VLVF_ENTRIES (64)
+#define RNP_VLVF_VLANID_MASK (0x00000FFF)
+/* Every VF own 64 bytes mem for communitate accessed by 32-bit */
+
+#define RNP_VF_RESET (0x01) /* VF requests reset */
+#define RNP_VF_SET_MAC_ADDR (0x02) /* VF requests PF to set MAC addr */
+#define RNP_VF_SET_MULTICAST (0x03) /* VF requests PF to set MC addr */
+#define RNP_VF_SET_VLAN (0x04) /* VF requests PF to set VLAN */
+
+#define RNP_VF_SET_LPE (0x05) /* VF requests PF to set VMOLR.LPE */
+#define RNP_VF_SET_MACVLAN (0x06) /* VF requests PF for unicast filter */
+#define RNP_VF_GET_MACVLAN (0x07) /* VF requests mac */
+#define RNP_VF_API_NEGOTIATE (0x08) /* negotiate API version */
+#define RNP_VF_GET_QUEUES (0x09) /* get queue configuration */
+#define RNP_VF_GET_LINK (0x10) /* get link status */
+
+#define RNP_VF_SET_VLAN_STRIP (0x0a) /* VF Requests PF to set VLAN STRIP */
+#define RNP_VF_REG_RD (0x0b) /* VF Read Reg */
+#define RNP_VF_GET_MAX_MTU (0x0c) /* VF Get Max Mtu */
+#define RNP_VF_SET_MTU (0x0d) /* VF Set Mtu */
+#define RNP_VF_GET_FW (0x0e) /* VF Get Firmware Version */
+
+#define RNP_PF_VFNUM_MASK GENMASK(26, 21)
+
+#define RNP_PF_SET_FCS (0x10) /* PF set fcs status */
+#define RNP_PF_SET_PAUSE (0x11) /* PF set pause status */
+#define RNP_PF_SET_FT_PADDING (0x12) /* PF set ft padding status */
+#define RNP_PF_SET_VLAN_FILTER (0x13) /* PF set ntuple status */
+#define RNP_PF_SET_VLAN (0x14)
+#define RNP_PF_SET_LINK (0x15)
+#define RNP_PF_SET_SPEED_40G BIT(8)
+#define RNP_PF_SET_SPEED_10G BIT(7)
+#define RNP_PF_SET_SPEED_1G BIT(5)
+#define RNP_PF_SET_SPEED_100M BIT(3)
+
+#define RNP_PF_SET_MTU (0x16)
+#define RNP_PF_SET_RESET (0x17)
+#define RNP_PF_LINK_UP BIT(31)
+#define RNP_PF_SPEED_MASK GENMASK(15, 0)
+
+/* Define mailbox register bits */
+#define RNP_PF_REMOVE (0x0f)
+
+/* Mailbox API ID VF Request */
+/* length of permanent address message returned from PF */
+#define RNP_VF_PERMADDR_MSG_LEN (11)
+#define RNP_VF_TX_QUEUES (1) /* number of Tx queues supported */
+#define RNP_VF_RX_QUEUES (2) /* number of Rx queues supported */
+#define RNP_VF_TRANS_VLAN (3) /* Indication of port vlan */
+#define RNP_VF_DEF_QUEUE (4) /* Default queue offset */
+/* word in permanent address message with the current multicast type */
+#define RNP_VF_VLAN_WORD (5)
+#define RNP_VF_PHY_TYPE_WORD (6)
+#define RNP_VF_FW_VERSION_WORD (7)
+#define RNP_VF_LINK_STATUS_WORD (8)
+#define RNP_VF_AXI_MHZ (9)
+#define RNP_VF_RNP_VF_FEATURE (10)
+#define RNP_VF_RNP_VF_FILTER_EN BIT(0)
+
+#define RNP_LINK_SPEED_UNKNOWN 0
+#define RNP_LINK_SPEED_10_FULL BIT(2)
+#define RNP_LINK_SPEED_100_FULL BIT(3)
+#define RNP_LINK_SPEED_1GB_FULL BIT(4)
+#define RNP_LINK_SPEED_10GB_FULL BIT(5)
+#define RNP_LINK_SPEED_40GB_FULL BIT(6)
+#define RNP_LINK_SPEED_25GB_FULL BIT(7)
+#define RNP_LINK_SPEED_50GB_FULL BIT(8)
+#define RNP_LINK_SPEED_100GB_FULL BIT(9)
+#define RNP_LINK_SPEED_10_HALF BIT(10)
+#define RNP_LINK_SPEED_100_HALF BIT(11)
+#define RNP_LINK_SPEED_1GB_HALF BIT(12)
+
+/* Mailbox API ID PF Request */
+#define RNP_VF_MC_TYPE_WORD (3)
+#define RNP_VF_DMA_VERSION_WORD (4)
+/* Get Queue write-back reference value */
+#define RNP_PF_CONTROL_PRING_MSG (0x0100) /* PF control message */
+
+#define TSRN10_MBX_VECTOR_ID (0)
+#define TSRN10_PF2VF_MBX_VEC_CTR(n) (0xa5000 + 0x4 * (n))
+
+#define RNP_VF_INIT_TIMEOUT (200) /* Number of retries to clear RSTI */
+#define RNP_VF_MBX_INIT_TIMEOUT (2000) /* number of retries on mailbox */
+
+#define MBOX_CTRL_REQ (1 << 0) /* WO */
+#define MBOX_CTRL_VF_HOLD_SHM (1 << 2) /* VF:WR, PF:RO */
+#define VF_NUM_MASK 0x3f
+#define VFNUM(num) ((num) & VF_NUM_MASK)
+
+#define PF_VF_SHM(vf) \
+ ((0xa6000) + (64 * (vf))) /* for PF1 rtl will remap 6000 to 0xb000 */
+#define PF2VF_COUNTER(vf) (PF_VF_SHM(vf) + 0)
+#define VF2PF_COUNTER(vf) (PF_VF_SHM(vf) + 4)
+#define PF_VF_SHM_DATA(vf) (PF_VF_SHM(vf) + 8)
+#define VF2PF_MBOX_CTRL(vf) ((0xa7000) + (4 * (vf)))
+
+/* Error Codes */
+#define RNP_ERR_INVALID_MAC_ADDR (-1)
+#define RNP_ERR_MBX (-100)
+
+#define RNP_MBX_DELAY_US (100) /* Delay us for Retry */
+/* Max Retry Time */
+#define RNP_MBX_TIMEOUT_SECONDS (2) /* Max Retry Time 2s */
+#define RNP_ARRAY_OPCODE_OFFSET (0)
+#define RNP_ARRAY_CTRL_OFFSET (1)
+
+void rnp_init_mbx_ops_pf(struct rnp_hw *hw);
+void *rnp_memzone_reserve(const char *name, unsigned int size);
+#endif
diff --git a/drivers/net/rnp/rnp_mbx_fw.h b/drivers/net/rnp/rnp_mbx_fw.h
new file mode 100644
index 0000000000..439090b5a3
--- /dev/null
+++ b/drivers/net/rnp/rnp_mbx_fw.h
@@ -0,0 +1,22 @@
+#ifndef __RNP_MBX_FW_H__
+#define __RNP_MBX_FW_H__
+
+struct mbx_fw_cmd_reply;
+typedef void (*cookie_cb)(struct mbx_fw_cmd_reply *reply, void *priv);
+#define RNP_MAX_SHARE_MEM (8 * 8)
+struct mbx_req_cookie {
+ int magic;
+#define COOKIE_MAGIC 0xCE
+ cookie_cb cb;
+ int timeout_ms;
+ int errcode;
+
+ /* wait_queue_head_t wait; */
+ volatile int done;
+ int priv_len;
+ char priv[RNP_MAX_SHARE_MEM];
+};
+struct mbx_fw_cmd_reply {
+} __rte_cache_aligned;
+
+#endif /* __RNP_MBX_FW_H__*/
--
2.27.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [[PATCH v1] 5/8] net/rnp add reset code for Chip Init process
2023-08-01 6:43 [[PATCH v1] 0/8] *** SUBJECT HERE *** Wenbo Cao
` (3 preceding siblings ...)
2023-08-01 6:43 ` [[PATCH v1] 4/8] net/rnp: add mbx basic api feature Wenbo Cao
@ 2023-08-01 6:43 ` Wenbo Cao
2023-08-01 6:43 ` [[PATCH v1] 6/8] net/rnp add port info resource init Wenbo Cao
2023-08-01 6:43 ` [[PATCH v1] 7/8] net/rnp add devargs runtime parsing functions Wenbo Cao
6 siblings, 0 replies; 11+ messages in thread
From: Wenbo Cao @ 2023-08-01 6:43 UTC (permalink / raw)
To: caowenbo; +Cc: dev
we must get the shape info of nic from Firmware for
reset. so the related codes is first get firmware info
and then reset the chip
Signed-off-by: Wenbo Cao <caowenbo@mucse.com>
---
drivers/net/rnp/base/rnp_api.c | 24 +++
drivers/net/rnp/base/rnp_api.h | 7 +
drivers/net/rnp/base/rnp_cfg.h | 7 +
drivers/net/rnp/base/rnp_dma_regs.h | 73 ++++++++
drivers/net/rnp/base/rnp_eth_regs.h | 124 +++++++++++++
drivers/net/rnp/base/rnp_hw.h | 46 +++++
drivers/net/rnp/meson.build | 3 +
drivers/net/rnp/rnp.h | 28 ++-
drivers/net/rnp/rnp_ethdev.c | 99 +++++++++-
drivers/net/rnp/rnp_mbx_fw.c | 272 ++++++++++++++++++++++++++++
drivers/net/rnp/rnp_mbx_fw.h | 163 ++++++++++++++++-
11 files changed, 840 insertions(+), 6 deletions(-)
create mode 100644 drivers/net/rnp/base/rnp_api.c
create mode 100644 drivers/net/rnp/base/rnp_api.h
create mode 100644 drivers/net/rnp/base/rnp_cfg.h
create mode 100644 drivers/net/rnp/base/rnp_dma_regs.h
create mode 100644 drivers/net/rnp/base/rnp_eth_regs.h
create mode 100644 drivers/net/rnp/rnp_mbx_fw.c
diff --git a/drivers/net/rnp/base/rnp_api.c b/drivers/net/rnp/base/rnp_api.c
new file mode 100644
index 0000000000..f3044e595e
--- /dev/null
+++ b/drivers/net/rnp/base/rnp_api.c
@@ -0,0 +1,24 @@
+#include "rnp.h"
+#include "rnp_api.h"
+
+int
+rnp_init_hw(struct rte_eth_dev *dev)
+{
+ struct rnp_mac_api *ops = RNP_DEV_TO_MAC_OPS(dev);
+ struct rnp_hw *hw = RNP_DEV_TO_HW(dev);
+
+ if (ops->init_hw)
+ return ops->init_hw(hw);
+ return -EOPNOTSUPP;
+}
+
+int
+rnp_reset_hw(struct rte_eth_dev *dev, struct rnp_hw *hw)
+{
+ struct rnp_mac_api *ops = RNP_DEV_TO_MAC_OPS(dev);
+
+ if (ops->reset_hw)
+ return ops->reset_hw(hw);
+ return -EOPNOTSUPP;
+}
+
diff --git a/drivers/net/rnp/base/rnp_api.h b/drivers/net/rnp/base/rnp_api.h
new file mode 100644
index 0000000000..df574dab77
--- /dev/null
+++ b/drivers/net/rnp/base/rnp_api.h
@@ -0,0 +1,7 @@
+#ifndef __RNP_API_H__
+#define __RNP_API_H__
+int
+rnp_init_hw(struct rte_eth_dev *dev);
+int
+rnp_reset_hw(struct rte_eth_dev *dev, struct rnp_hw *hw);
+#endif /* __RNP_API_H__ */
diff --git a/drivers/net/rnp/base/rnp_cfg.h b/drivers/net/rnp/base/rnp_cfg.h
new file mode 100644
index 0000000000..90f25268ad
--- /dev/null
+++ b/drivers/net/rnp/base/rnp_cfg.h
@@ -0,0 +1,7 @@
+#ifndef __RNP_CFG_H__
+#define __RNP_CFG_H__
+#include "rnp_osdep.h"
+
+#define RNP_NIC_RESET _NIC_(0x0010)
+#define RNP_TX_QINQ_WORKAROUND _NIC_(0x801c)
+#endif /* __RNP_CFG_H__ */
diff --git a/drivers/net/rnp/base/rnp_dma_regs.h b/drivers/net/rnp/base/rnp_dma_regs.h
new file mode 100644
index 0000000000..bfe87e534d
--- /dev/null
+++ b/drivers/net/rnp/base/rnp_dma_regs.h
@@ -0,0 +1,73 @@
+#ifndef __RNP_REGS_H__
+#define __RNP_REGS_H__
+
+#include "rnp_osdep.h"
+
+/* mac address offset */
+#define RNP_DMA_CTRL (0x4)
+#define RNP_VEB_BYPASS_EN BIT(4)
+#define RNP_DMA_MEM_CFG_LE (0 << 5)
+#define TSNR10_DMA_MEM_CFG_BE (1 << 5)
+#define RNP_DMA_SCATTER_MEM_SHIFT (16)
+
+#define RNP_FIRMWARE_SYNC (0xc)
+#define RNP_FIRMWARE_SYNC_MASK GENMASK(31, 16)
+#define RNP_FIRMWARE_SYNC_MAGIC (0xa5a40000)
+#define RNP_DRIVER_REMOVE (0x5a000000)
+/* 1BIT <-> 16 bytes Dma Addr Size*/
+#define RNP_DMA_SCATTER_MEM_MASK GENMASK(31, 16)
+#define RNP_DMA_TX_MAP_MODE_SHIFT (12)
+#define RNP_DMA_TX_MAP_MODE_MASK GENMASK(15, 12)
+#define RNP_DMA_RX_MEM_PAD_EN BIT(8)
+/* === queue register ===== */
+/* enable */
+#define RNP_DMA_RXQ_START(qid) _RING_(0x0010 + 0x100 * (qid))
+#define RNP_DMA_RXQ_READY(qid) _RING_(0x0014 + 0x100 * (qid))
+#define RNP_DMA_TXQ_START(qid) _RING_(0x0018 + 0x100 * (qid))
+#define RNP_DMA_TXQ_READY(qid) _RING_(0x001c + 0x100 * (qid))
+
+#define RNP_DMA_INT_STAT(qid) _RING_(0x0020 + 0x100 * (qid))
+#define RNP_DMA_INT_MASK(qid) _RING_(0x0024 + 0x100 * (qid))
+#define RNP_TX_INT_MASK BIT(1)
+#define RNP_RX_INT_MASK BIT(0)
+#define RNP_DMA_INT_CLER(qid) _RING_(0x0028 + 0x100 * (qid))
+
+/* rx-queue */
+#define RNP_DMA_RXQ_BASE_ADDR_HI(qid) _RING_(0x0030 + 0x100 * (qid))
+#define RNP_DMA_RXQ_BASE_ADDR_LO(qid) _RING_(0x0034 + 0x100 * (qid))
+#define RNP_DMA_RXQ_LEN(qid) _RING_(0x0038 + 0x100 * (qid))
+#define RNP_DMA_RXQ_HEAD(qid) _RING_(0x003c + 0x100 * (qid))
+#define RNP_DMA_RXQ_TAIL(qid) _RING_(0x0040 + 0x100 * (qid))
+#define RNP_DMA_RXQ_DESC_FETCH_CTRL(qid) _RING_(0x0044 + 0x100 * (qid))
+#define RNP_DMA_RXQ_INT_DELAY_TIMER(qid) _RING_(0x0048 + 0x100 * (qid))
+#define RNP_DMA_RXQ_INT_DELAY_PKTCNT(qidx) _RING_(0x004c + 0x100 * (qid))
+#define RNP_DMA_RXQ_RX_PRI_LVL(qid) _RING_(0x0050 + 0x100 * (qid))
+#define RNP_DMA_RXQ_DROP_TIMEOUT_TH(qid) _RING_(0x0054 + 0x100 * (qid))
+/* tx-queue */
+#define RNP_DMA_TXQ_BASE_ADDR_HI(qid) _RING_(0x0060 + 0x100 * (qid))
+#define RNP_DMA_TXQ_BASE_ADDR_LO(qid) _RING_(0x0064 + 0x100 * (qid))
+#define RNP_DMA_TXQ_LEN(qid) _RING_(0x0068 + 0x100 * (qid))
+#define RNP_DMA_TXQ_HEAD(qid) _RING_(0x006c + 0x100 * (qid))
+#define RNP_DMA_TXQ_TAIL(qid) _RING_(0x0070 + 0x100 * (qid))
+#define RNP_DMA_TXQ_DESC_FETCH_CTRL(qid) _RING_(0x0074 + 0x100 * (qid))
+#define RNP_DMA_TXQ_INT_DELAY_TIMER(qid) _RING_(0x0078 + 0x100 * (qid))
+#define RNP_DMA_TXQ_INT_DELAY_PKTCNT(qid) _RING_(0x007c + 0x100 * (qid))
+
+#define RNP_DMA_TXQ_PRI_LVL(qid) _RING_(0x0080 + 0x100 * (qid))
+#define RNP_DMA_TXQ_RATE_CTRL_TH(qid) _RING_(0x0084 + 0x100 * (qid))
+#define RNP_DMA_TXQ_RATE_CTRL_TM(qid) _RING_(0x0088 + 0x100 * (qid))
+
+/* VEB Table Register */
+#define RNP_VBE_MAC_LO(port, nr) _RING_(0x00a0 + (4 * (port)) + \
+ (0x100 * (nr)))
+#define RNP_VBE_MAC_HI(port, nr) _RING_(0x00b0 + (4 * (port)) + \
+ (0x100 * (nr)))
+#define RNP_VEB_VID_CFG(port, nr) _RING_(0x00c0 + (4 * (port)) + \
+ (0x100 * (nr)))
+#define RNP_VEB_VF_RING(port, nr) _RING_(0x00d0 + (4 * (port)) + \
+ (0x100 * (nr)))
+#define RNP_MAX_VEB_TB (64)
+#define RNP_VEB_RING_CFG_OFFSET (8)
+#define RNP_VEB_SWITCH_VF_EN BIT(7)
+#define MAX_VEB_TABLES_NUM (4)
+#endif /* RNP_DMA_REGS_H_ */
diff --git a/drivers/net/rnp/base/rnp_eth_regs.h b/drivers/net/rnp/base/rnp_eth_regs.h
new file mode 100644
index 0000000000..88e8e1e552
--- /dev/null
+++ b/drivers/net/rnp/base/rnp_eth_regs.h
@@ -0,0 +1,124 @@
+#ifndef _RNP_ETH_REGS_H_
+#define _RNP_ETH_REGS_H_
+
+#include "rnp_osdep.h"
+
+/* PTP 1588 TM Offload */
+#define RNP_ETH_PTP_TX_STATUS(n) _ETH_(0x0400 + ((n) * 0x14))
+#define RNP_ETH_PTP_TX_HTIMES(n) _ETH_(0x0404 + ((n) * 0x14))
+#define RNP_ETH_PTP_TX_LTIMES(n) _ETH_(0x0408 + ((n) * 0x14))
+#define RNP_ETH_PTP_TX_TS_ST(n) _ETH_(0x040c + ((n) * 0x14))
+#define RNP_ETH_PTP_TX_CLEAR(n) _ETH_(0x0410 + ((n) * 0x14))
+
+#define RNP_ETH_ENGINE_BYPASS _ETH_(0x8000)
+#define RNP_EN_TUNNEL_VXLAN_PARSE _ETH_(0x8004)
+#define RNP_ETH_MAC_LOOPBACK _ETH_(0x8008)
+#define RNP_ETH_FIFO_CTRL _ETH_(0x800c)
+#define RNP_ETH_FOUR_FIFO BIT(0)
+#define RNP_ETH_TWO_FIFO BIT(1)
+#define RNP_ETH_ONE_FIFO BIT(2)
+#define RNP_FIFO_CFG_EN (0x1221)
+#define RNP_ETH_VXLAN_PORT_CTRL _ETH_(0x8010)
+#define RNP_ETH_VXLAN_DEF_PORT (4789)
+#define RNP_HOST_FILTER_EN _ETH_(0x801c)
+#define RNP_HW_SCTP_CKSUM_CTRL _ETH_(0x8038)
+#define RNP_HW_CHECK_ERR_CTRL _ETH_(0x8060)
+#define RNP_HW_ERR_HDR_LEN BIT(0)
+#define RNP_HW_ERR_PKTLEN BIT(1)
+#define RNP_HW_L3_CKSUM_ERR BIT(2)
+#define RNP_HW_L4_CKSUM_ERR BIT(3)
+#define RNP_HW_SCTP_CKSUM_ERR BIT(4)
+#define RNP_HW_INNER_L3_CKSUM_ERR BIT(5)
+#define RNP_HW_INNER_L4_CKSUM_ERR BIT(6)
+#define RNP_HW_CKSUM_ERR_MASK GENMASK(6, 2)
+#define RNP_HW_CHECK_ERR_MASK GENMASK(6, 0)
+#define RNP_HW_ERR_RX_ALL_MASK GENMASK(1, 0)
+
+#define RNP_REDIR_CTRL _ETH_(0x8030)
+#define RNP_VLAN_Q_STRIP_CTRL(n) _ETH_(0x8040 + 0x4 * ((n) / 32))
+/* This Just VLAN Master Switch */
+#define RNP_VLAN_TUNNEL_STRIP_EN _ETH_(0x8050)
+#define RNP_VLAN_TUNNEL_STRIP_MODE _ETH_(0x8054)
+#define RNP_VLAN_TUNNEL_STRIP_OUTER (0)
+#define RNP_VLAN_TUNNEL_STRIP_INNER (1)
+#define RNP_RSS_INNER_CTRL _ETH_(0x805c)
+#define RNP_INNER_RSS_EN (1)
+
+#define RNP_ETH_DEFAULT_RX_RING _ETH_(0x806c)
+#define RNP_RX_FC_HI_WATER(n) _ETH_(0x80c0 + ((n) * 0x8))
+#define RNP_RX_FC_LO_WATER(n) _ETH_(0x80c4 + ((n) * 0x8))
+
+#define RNP_RX_FIFO_FULL_THRETH(n) _ETH_(0x8070 + ((n) * 0x8))
+#define RNP_RX_WORKAROUND_VAL _ETH_(0x7ff)
+#define RNP_RX_DEFAULT_VAL _ETH_(0x270)
+
+#define RNP_MIN_FRAME_CTRL _ETH_(0x80f0)
+#define RNP_MAX_FRAME_CTRL _ETH_(0x80f4)
+
+#define RNP_RX_FC_ENABLE _ETH_(0x8520)
+#define RNP_RING_FC_EN(n) _ETH_(0x8524 + 0x4 * ((n) / 32))
+#define RNP_RING_FC_THRESH(n) _ETH_(0x8a00 + 0x4 * (n))
+
+/* Mac Host Filter */
+#define RNP_MAC_FCTRL _ETH_(0x9110)
+#define RNP_MAC_FCTRL_MPE BIT(8) /* Multicast Promiscuous En */
+#define RNP_MAC_FCTRL_UPE BIT(9) /* Unicast Promiscuous En */
+#define RNP_MAC_FCTRL_BAM BIT(10) /* Broadcast Accept Mode */
+#define RNP_MAC_FCTRL_BYPASS (RNP_MAC_FCTRL_MPE | \
+ RNP_MAC_FCTRL_UPE | \
+ RNP_MAC_FCTRL_BAM)
+/* MC UC Mac Hash Filter Ctrl */
+#define RNP_MAC_MCSTCTRL _ETH_(0x9114)
+#define RNP_MAC_HASH_MASK GENMASK(11, 0)
+#define RNP_MAC_MULTICASE_TBL_EN BIT(2)
+#define RNP_MAC_UNICASE_TBL_EN BIT(3)
+#define RNP_UC_HASH_TB(n) _ETH_(0xA800 + ((n) * 0x4))
+#define RNP_MC_HASH_TB(n) _ETH_(0xAC00 + ((n) * 0x4))
+
+#define RNP_VLAN_FILTER_CTRL _ETH_(0x9118)
+#define RNP_L2TYPE_FILTER_CTRL (RNP_VLAN_FILTER_CTRL)
+#define RNP_L2TYPE_FILTER_EN BIT(31)
+#define RNP_VLAN_FILTER_EN BIT(30)
+
+#define RNP_FC_PAUSE_FWD_ACT _ETH_(0x9280)
+#define RNP_FC_PAUSE_DROP BIT(31)
+#define RNP_FC_PAUSE_PASS (0)
+#define RNP_FC_PAUSE_TYPE _ETH_(0x9284)
+#define RNP_FC_PAUSE_POLICY_EN BIT(31)
+#define RNP_PAUSE_TYPE _ETH_(0x8808)
+
+#define RNP_INPUT_USE_CTRL _ETH_(0x91d0)
+#define RNP_INPUT_VALID_MASK (0xf)
+#define RNP_INPUT_POLICY(n) _ETH_(0x91e0 + ((n) * 0x4))
+/* RSS */
+#define RNP_RSS_MRQC_ADDR _ETH_(0x92a0)
+#define RNP_SRIOV_CTRL RNP_RSS_MRQC_ADDR
+#define RNP_SRIOV_ENABLE BIT(3)
+
+#define RNP_RSS_REDIR_TB(mac, idx) _ETH_(0xe000 + \
+ ((mac) * 0x200) + ((idx) * 0x4))
+#define RNP_RSS_KEY_TABLE(idx) _ETH_(0x92d0 + ((idx) * 0x4))
+/*=======================================================================
+ *HOST_MAC_ADDRESS_FILTER
+ *=======================================================================
+ */
+#define RNP_RAL_BASE_ADDR(vf_id) _ETH_(0xA000 + 0x04 * (vf_id))
+#define RNP_RAH_BASE_ADDR(vf_id) _ETH_(0xA400 + 0x04 * (vf_id))
+#define RNP_MAC_FILTER_EN BIT(31)
+
+/* ETH Statistic */
+#define RNP_ETH_RXTRANS_DROP(p_id) _ETH_((0x8904) + ((p_id) * (0x40)))
+#define RNP_ETH_RXTRANS_CAT_ERR(p_id) _ETH_((0x8928) + ((p_id) * (0x40)))
+#define RNP_ETH_TXTM_DROP _ETH_(0X0470)
+
+#define RNP_VFTA_BASE_ADDR _ETH_(0xB000)
+#define RNP_VFTA_HASH_TABLE(id) (RNP_VFTA_BASE_ADDR + 0x4 * (id))
+#define RNP_ETYPE_BASE_ADDR _ETH_(0xB300)
+#define RNP_MPSAR_BASE_ADDR(vf_id) _ETH_(0xB400 + 0x04 * (vf_id))
+#define RNP_PFVLVF_BASE_ADDR _ETH_(0xB600)
+#define RNP_PFVLVFB_BASE_ADDR _ETH_(0xB700)
+#define RNP_TUNNEL_PFVLVF_BASE_ADDR _ETH_(0xB800)
+#define RNP_TUNNEL_PFVLVFB_BASE_ADDR _ETH_(0xB900)
+
+#define RNP_TC_PORT_MAP_TB(port) _ETH_(0xe840 + 0x04 * (port))
+#endif /* RNP_ETH_REGS_H_ */
diff --git a/drivers/net/rnp/base/rnp_hw.h b/drivers/net/rnp/base/rnp_hw.h
index da3659bd67..03381ab6d0 100644
--- a/drivers/net/rnp/base/rnp_hw.h
+++ b/drivers/net/rnp/base/rnp_hw.h
@@ -8,6 +8,9 @@
#include <ethdev_driver.h>
#include "rnp_osdep.h"
+#include "rnp_dma_regs.h"
+#include "rnp_eth_regs.h"
+#include "rnp_cfg.h"
static inline unsigned int rnp_rd_reg(volatile void *addr)
{
@@ -24,6 +27,9 @@ static inline void rnp_wr_reg(volatile void *reg, int val)
#define mbx_rd32(hw, reg) rnp_rd_reg((hw)->iobar4 + (reg))
#define mbx_wr32(hw, reg, val) rnp_wr_reg((hw)->iobar4 + (reg), (val))
+#define rnp_eth_rd(hw, off) rnp_rd_reg((char *)(hw)->eth_base + (off))
+#define rnp_eth_wr(hw, off, val) \
+ rnp_wr_reg((char *)(hw)->eth_base + (off), val)
struct rnp_hw;
/* Mbx Operate info */
enum MBX_ID {
@@ -93,6 +99,17 @@ struct rnp_mbx_info {
rte_atomic16_t state;
} __rte_cache_aligned;
+struct rnp_mac_api {
+ int32_t (*init_hw)(struct rnp_hw *hw);
+ int32_t (*reset_hw)(struct rnp_hw *hw);
+};
+
+struct rnp_mac_info {
+ uint8_t assign_addr[RTE_ETHER_ADDR_LEN];
+ uint8_t set_addr[RTE_ETHER_ADDR_LEN];
+ struct rnp_mac_api ops;
+} __rte_cache_aligned;
+
#define RNP_MAX_HW_PORT_PERR_PF (4)
struct rnp_hw {
void *back;
@@ -105,8 +122,10 @@ struct rnp_hw {
char *eth_base;
char *veb_base;
char *mac_base[RNP_MAX_HW_PORT_PERR_PF];
+ char *comm_reg_base;
char *msix_base;
/* === dma == */
+ char *dev_version;
char *dma_axi_en;
char *dma_axi_st;
@@ -114,10 +133,37 @@ struct rnp_hw {
uint16_t vendor_id;
uint16_t function;
uint16_t pf_vf_num;
+ int pfvfnum;
uint16_t max_vfs;
+
+ bool ncsi_en;
+ uint8_t ncsi_rar_entries;
+
+ int sgmii_phy_id;
+ int is_sgmii;
+ u16 phy_type;
+ uint8_t force_10g_1g_speed_ablity;
+ uint8_t force_speed_stat;
+#define FORCE_SPEED_STAT_DISABLED (0)
+#define FORCE_SPEED_STAT_1G (1)
+#define FORCE_SPEED_STAT_10G (2)
+ uint32_t speed;
+ unsigned int axi_mhz;
+
+ int fw_version; /* Primary FW Version */
+ uint32_t fw_uid; /* Subclass Fw Version */
+
+ int nic_mode;
+ unsigned char lane_mask;
+ int lane_of_port[4];
+ char phy_port_ids[4]; /* port id: for lane0~3: value: 0 ~ 7 */
+ uint8_t max_port_num; /* Max Port Num This PF Have */
+
void *cookie_pool;
char cookie_p_name[RTE_MEMZONE_NAMESIZE];
+ struct rnp_mac_info mac;
struct rnp_mbx_info mbx;
+ rte_spinlock_t fw_lock;
} __rte_cache_aligned;
#endif /* __RNP_H__*/
diff --git a/drivers/net/rnp/meson.build b/drivers/net/rnp/meson.build
index 38dbee5ca4..c52566c357 100644
--- a/drivers/net/rnp/meson.build
+++ b/drivers/net/rnp/meson.build
@@ -10,5 +10,8 @@ endif
sources = files(
'rnp_ethdev.c',
'rnp_mbx.c',
+ 'rnp_mbx_fw.c',
+ 'base/rnp_api.c',
)
+
includes += include_directories('base')
diff --git a/drivers/net/rnp/rnp.h b/drivers/net/rnp/rnp.h
index a8999ddc47..70685e48a6 100644
--- a/drivers/net/rnp/rnp.h
+++ b/drivers/net/rnp/rnp.h
@@ -13,6 +13,20 @@
#define RNP_CFG_BAR (4)
#define RNP_PF_INFO_BAR (0)
+enum rnp_resource_share_m {
+ RNP_SHARE_CORPORATE = 0,
+ RNP_SHARE_INDEPEND,
+};
+/*
+ * Structure to store private data for each driver instance (for each port).
+ */
+enum rnp_work_mode {
+ RNP_SINGLE_40G = 0,
+ RNP_SINGLE_10G = 1,
+ RNP_DUAL_10G = 2,
+ RNP_QUAD_10G = 3,
+};
+
struct rnp_eth_port {
void *adapt;
struct rnp_hw *hw;
@@ -21,9 +35,12 @@ struct rnp_eth_port {
struct rnp_share_ops {
struct rnp_mbx_api mbx_api;
+ struct rnp_mac_api mac_api;
} __rte_cache_aligned;
struct rnp_eth_adapter {
+ enum rnp_work_mode mode;
+ enum rnp_resource_share_m s_mode; /* Port Resource Share Policy */
struct rnp_hw hw;
uint16_t max_vfs;
struct rte_pci_device *pdev;
@@ -31,7 +48,9 @@ struct rnp_eth_adapter {
struct rnp_eth_port *ports[RNP_MAX_PORT_OF_PF];
struct rnp_share_ops *share_priv;
+ int max_link_speed;
uint8_t num_ports; /* Cur Pf Has physical Port Num */
+ uint8_t lane_mask;
} __rte_cache_aligned;
#define RNP_DEV_TO_PORT(eth_dev) \
@@ -40,8 +59,13 @@ struct rnp_eth_adapter {
((struct rnp_eth_adapter *)(RNP_DEV_TO_PORT(eth_dev)->adapt))
#define RNP_DEV_TO_HW(eth_dev) \
(&((struct rnp_eth_adapter *)(RNP_DEV_TO_PORT((eth_dev))->adapt))->hw)
+#define RNP_HW_TO_ADAPTER(hw) \
+ ((struct rnp_eth_adapter *)((hw)->back))
#define RNP_DEV_PP_PRIV_TO_MBX_OPS(dev) \
(&((struct rnp_share_ops *)(dev)->process_private)->mbx_api)
+#define RNP_DEV_PP_PRIV_TO_MAC_OPS(dev) \
+ (&((struct rnp_share_ops *)(dev)->process_private)->mac_api)
+#define RNP_DEV_TO_MAC_OPS(dev) RNP_DEV_PP_PRIV_TO_MAC_OPS(dev)
#define RNP_DEV_TO_MBX_OPS(dev) RNP_DEV_PP_PRIV_TO_MBX_OPS(dev)
static inline void rnp_reg_offset_init(struct rnp_hw *hw)
@@ -56,10 +80,10 @@ static inline void rnp_reg_offset_init(struct rnp_hw *hw)
hw->msix_base = hw->iobar4 + 0xa0000;
}
/* === dma status/config====== */
+ hw->dev_version = hw->iobar4 + 0x0000;
hw->link_sync = hw->iobar4 + 0x000c;
hw->dma_axi_en = hw->iobar4 + 0x0010;
hw->dma_axi_st = hw->iobar4 + 0x0014;
-
if (hw->mbx.pf_num)
hw->msix_base += 0x200;
/* === queue registers === */
@@ -69,5 +93,7 @@ static inline void rnp_reg_offset_init(struct rnp_hw *hw)
/* mac */
for (i = 0; i < RNP_MAX_HW_PORT_PERR_PF; i++)
hw->mac_base[i] = hw->iobar4 + 0x60000 + 0x10000 * i;
+ /* === top reg === */
+ hw->comm_reg_base = hw->iobar4 + 0x30000;
}
#endif /* __RNP_H__ */
diff --git a/drivers/net/rnp/rnp_ethdev.c b/drivers/net/rnp/rnp_ethdev.c
index 4747a41423..b4287d8a3e 100644
--- a/drivers/net/rnp/rnp_ethdev.c
+++ b/drivers/net/rnp/rnp_ethdev.c
@@ -9,6 +9,8 @@
#include "rnp.h"
#include "rnp_mbx.h"
+#include "base/rnp_api.h"
+#include "rnp_mbx_fw.h"
#include "rnp_logs.h"
extern struct rnp_mbx_api rnp_mbx_pf_ops;
@@ -93,7 +95,30 @@ rnp_alloc_eth_port(struct rte_pci_device *master_pci, char *name)
static void rnp_get_nic_attr(struct rnp_eth_adapter *adapter)
{
- RTE_SET_USED(adapter);
+ struct rnp_hw *hw = &adapter->hw;
+ int lane_mask = 0, err, mode = 0;
+
+ rnp_mbx_link_event_enable(adapter->eth_dev, false);
+
+ err = rnp_mbx_get_capability(adapter->eth_dev, &lane_mask, &mode);
+ if (err < 0 || !lane_mask) {
+ PMD_DRV_LOG(ERR, "%s: mbx_get_capability error! errcode=%d\n",
+ __func__, hw->speed);
+ return;
+ }
+
+ adapter->num_ports = __builtin_popcount(lane_mask);
+ adapter->max_link_speed = hw->speed;
+ adapter->lane_mask = lane_mask;
+ adapter->mode = hw->nic_mode;
+
+ PMD_DRV_LOG(INFO, "max link speed:%d lane_mask:0x%x nic-mode:0x%x\n",
+ (int)adapter->max_link_speed,
+ (int)adapter->num_ports, adapter->mode);
+ if (adapter->num_ports && adapter->num_ports == 1)
+ adapter->s_mode = RNP_SHARE_CORPORATE;
+ else
+ adapter->s_mode = RNP_SHARE_INDEPEND;
}
static int
@@ -120,13 +145,78 @@ rnp_process_resource_init(struct rte_eth_dev *eth_dev)
PMD_DRV_LOG(ERR, "calloc share_priv failed");
return -ENOMEM;
}
-
+ memset(share_priv, 0, sizeof(*share_priv));
eth_dev->process_private = share_priv;
- adapter->share_priv = share_priv;
return 0;
}
+static int32_t rnp_reset_hw_pf(struct rnp_hw *hw)
+{
+ struct rnp_eth_adapter *adapter = hw->back;
+
+ rnp_wr_reg(hw->comm_reg_base + RNP_NIC_RESET, 0);
+ rte_wmb();
+ rnp_wr_reg(hw->comm_reg_base + RNP_NIC_RESET, 1);
+
+ rnp_mbx_fw_reset_phy(adapter->eth_dev);
+
+ PMD_DRV_LOG(INFO, "PF[%d] reset nic finish\n",
+ hw->function);
+ return 0;
+}
+
+static int32_t rnp_init_hw_pf(struct rnp_hw *hw)
+{
+ struct rnp_eth_adapter *adapter = RNP_HW_TO_ADAPTER(hw);
+ uint32_t version;
+ uint32_t reg;
+
+ PMD_INIT_FUNC_TRACE();
+ version = rnp_rd_reg(hw->dev_version);
+ PMD_DRV_LOG(INFO, "NIC HW Version:0x%.2x\n", version);
+
+ /* Disable Rx/Tx Dma */
+ rnp_wr_reg(hw->dma_axi_en, false);
+ /* Check Dma Chanle Status */
+ while (rnp_rd_reg(hw->dma_axi_st) == 0)
+ ;
+
+ /* Reset Nic All Hardware */
+ if (rnp_reset_hw(adapter->eth_dev, hw))
+ return -EPERM;
+
+ /* Rx Proto Offload No-BYPASS */
+ rnp_eth_wr(hw, RNP_ETH_ENGINE_BYPASS, false);
+ /* Enable Flow Filter Engine */
+ rnp_eth_wr(hw, RNP_HOST_FILTER_EN, true);
+ /* Enable VXLAN Parse */
+ rnp_eth_wr(hw, RNP_EN_TUNNEL_VXLAN_PARSE, true);
+ /* Enabled REDIR ACTION */
+ rnp_eth_wr(hw, RNP_REDIR_CTRL, true);
+
+ /* Setup Scatter DMA Mem Size */
+ reg = ((RTE_ETHER_MAX_LEN / 16) << RNP_DMA_SCATTER_MEM_SHIFT);
+ rnp_wr_reg(hw->iobar4 + RNP_DMA_CTRL, reg);
+#ifdef PHYTIUM_SUPPORT
+#define RNP_DMA_PADDING (1 << 8)
+ reg = rnp_rd_reg(hw->iobar4 + RNP_DMA_CTRL);
+ reg |= RNP_DMA_PADDING;
+ rnp_wr_reg(hw->iobar4 + RNP_DMA_CTRL, reg);
+#endif
+ /* Enable Rx/Tx Dma */
+ rnp_wr_reg(hw->dma_axi_en, 0b1111);
+
+ rnp_wr_reg(hw->comm_reg_base + RNP_TX_QINQ_WORKAROUND, 1);
+
+ return 0;
+}
+
+struct rnp_mac_api rnp_mac_ops = {
+ .reset_hw = rnp_reset_hw_pf,
+ .init_hw = rnp_init_hw_pf
+};
+
static void
rnp_common_ops_init(struct rnp_eth_adapter *adapter)
{
@@ -180,11 +270,12 @@ rnp_eth_dev_init(struct rte_eth_dev *dev)
hw->vendor_id = pci_dev->id.vendor_id;
hw->device_id = pci_dev->id.device_id;
adapter->max_vfs = pci_dev->max_vfs;
- ret = rnp_process_resource_init(dev, adapter);
+ ret = rnp_process_resource_init(dev);
if (ret) {
PMD_DRV_LOG(ERR, "share prive resource init failed");
return ret;
}
+ adapter->share_priv = dev->process_private;
rnp_common_ops_init(adapter);
rnp_get_nic_attr(adapter);
/* We need Use Device Id To Change The Resource Mode */
diff --git a/drivers/net/rnp/rnp_mbx_fw.c b/drivers/net/rnp/rnp_mbx_fw.c
new file mode 100644
index 0000000000..5ac8b6608f
--- /dev/null
+++ b/drivers/net/rnp/rnp_mbx_fw.c
@@ -0,0 +1,272 @@
+#include <linux/wait.h>
+#include <stdio.h>
+
+#include <rte_version.h>
+#include <ethdev_pci.h>
+#include <rte_malloc.h>
+#include <rte_alarm.h>
+
+#include "rnp.h"
+#include "rnp_mbx.h"
+#include "rnp_mbx_fw.h"
+#include "rnp_logs.h"
+
+static int
+rnp_fw_send_cmd_wait(struct rte_eth_dev *dev, struct mbx_fw_cmd_req *req,
+ struct mbx_fw_cmd_reply *reply)
+{
+ struct rnp_mbx_api *ops = RNP_DEV_TO_MBX_OPS(dev);
+ struct rnp_hw *hw = RNP_DEV_TO_HW(dev);
+ int err;
+
+ rte_spinlock_lock(&hw->fw_lock);
+
+ err = ops->write_posted(dev, (u32 *)req,
+ (req->datalen + MBX_REQ_HDR_LEN) / 4, MBX_FW);
+ if (err) {
+ RNP_PMD_LOG(ERR, "%s: write_posted failed! err:0x%x\n",
+ __func__, err);
+ rte_spinlock_unlock(&hw->fw_lock);
+ return err;
+ }
+
+ err = ops->read_posted(dev, (u32 *)reply, sizeof(*reply) / 4, MBX_FW);
+ rte_spinlock_unlock(&hw->fw_lock);
+ if (err) {
+ RNP_PMD_LOG(ERR,
+ "%s: read_posted failed! err:0x%x. "
+ "req-op:0x%x\n",
+ __func__,
+ err,
+ req->opcode);
+ goto err_quit;
+ }
+
+ if (reply->error_code) {
+ RNP_PMD_LOG(ERR,
+ "%s: reply err:0x%x. req-op:0x%x\n",
+ __func__,
+ reply->error_code,
+ req->opcode);
+ err = -reply->error_code;
+ goto err_quit;
+ }
+
+ return 0;
+err_quit:
+ RNP_PMD_LOG(ERR,
+ "%s:PF[%d]: req:%08x_%08x_%08x_%08x "
+ "reply:%08x_%08x_%08x_%08x\n",
+ __func__,
+ hw->function,
+ ((int *)req)[0],
+ ((int *)req)[1],
+ ((int *)req)[2],
+ ((int *)req)[3],
+ ((int *)reply)[0],
+ ((int *)reply)[1],
+ ((int *)reply)[2],
+ ((int *)reply)[3]);
+
+ return err;
+}
+
+static int rnp_mbx_fw_post_req(struct rte_eth_dev *dev,
+ struct mbx_fw_cmd_req *req,
+ struct mbx_req_cookie *cookie)
+{
+ struct rnp_mbx_api *ops = RNP_DEV_TO_MBX_OPS(dev);
+ struct rnp_hw *hw = RNP_DEV_TO_HW(dev);
+ int err = 0;
+ int timeout_cnt;
+#define WAIT_MS 10
+
+ cookie->done = 0;
+
+ rte_spinlock_lock(&hw->fw_lock);
+
+ /* down_interruptible(&pf_cpu_lock); */
+ err = ops->write(hw, (u32 *)req,
+ (req->datalen + MBX_REQ_HDR_LEN) / 4, MBX_FW);
+ if (err) {
+ RNP_PMD_LOG(ERR, "rnp_write_mbx failed!\n");
+ goto quit;
+ }
+
+ timeout_cnt = cookie->timeout_ms / WAIT_MS;
+ while (timeout_cnt > 0) {
+ rte_delay_ms(WAIT_MS);
+ timeout_cnt--;
+ if (cookie->done)
+ break;
+ }
+
+quit:
+ rte_spinlock_unlock(&hw->fw_lock);
+ return err;
+}
+
+static int rnp_fw_get_capablity(struct rte_eth_dev *dev,
+ struct phy_abilities *abil)
+{
+ struct mbx_fw_cmd_reply reply;
+ struct mbx_fw_cmd_req req;
+ int err;
+
+ memset(&req, 0, sizeof(req));
+ memset(&reply, 0, sizeof(reply));
+
+ build_phy_abalities_req(&req, &req);
+
+ err = rnp_fw_send_cmd_wait(dev, &req, &reply);
+ if (err)
+ return err;
+
+ memcpy(abil, &reply.phy_abilities, sizeof(*abil));
+
+ return 0;
+}
+
+#define RNP_MBX_API_MAX_RETRY (10)
+int rnp_mbx_get_capability(struct rte_eth_dev *dev,
+ int *lane_mask,
+ int *nic_mode)
+{
+ struct rnp_hw *hw = RNP_DEV_TO_HW(dev);
+ struct phy_abilities ablity;
+ uint16_t temp_lmask;
+ uint16_t lane_bit = 0;
+ uint16_t retry = 0;
+ int lane_cnt = 0;
+ uint8_t lane_idx;
+ int err = -EIO;
+ uint8_t idx;
+
+ memset(&ablity, 0, sizeof(ablity));
+
+ /* enable CM3CPU to PF MBX IRQ */
+ do {
+ err = rnp_fw_get_capablity(dev, &ablity);
+ if (retry > RNP_MBX_API_MAX_RETRY)
+ break;
+ retry++;
+ } while (err);
+ if (!err) {
+ hw->lane_mask = ablity.lane_mask;
+ hw->nic_mode = ablity.nic_mode;
+ hw->pfvfnum = ablity.pfnum;
+ hw->fw_version = ablity.fw_version;
+ hw->axi_mhz = ablity.axi_mhz;
+ hw->fw_uid = ablity.fw_uid;
+ if (ablity.phy_type == PHY_TYPE_SGMII) {
+ hw->is_sgmii = 1;
+ hw->sgmii_phy_id = ablity.phy_id;
+ }
+
+ if (ablity.ext_ablity != 0xffffffff && ablity.e.valid) {
+ hw->ncsi_en = (ablity.e.ncsi_en == 1);
+ hw->ncsi_rar_entries = 1;
+ }
+
+ if (hw->nic_mode == RNP_SINGLE_10G &&
+ hw->fw_version >= 0x00050201 &&
+ ablity.speed == RTE_ETH_SPEED_NUM_10G) {
+ hw->force_speed_stat = FORCE_SPEED_STAT_DISABLED;
+ hw->force_10g_1g_speed_ablity = 1;
+ }
+
+ if (lane_mask)
+ *lane_mask = hw->lane_mask;
+ if (nic_mode)
+ *nic_mode = hw->nic_mode;
+
+ lane_cnt = __builtin_popcount(hw->lane_mask);
+ temp_lmask = hw->lane_mask;
+ for (idx = 0; idx < lane_cnt; idx++) {
+ hw->phy_port_ids[idx] = ablity.port_ids[idx];
+ lane_bit = ffs(temp_lmask) - 1;
+ lane_idx = ablity.port_ids[idx] % lane_cnt;
+ hw->lane_of_port[lane_idx] = lane_bit;
+ temp_lmask &= ~BIT(lane_bit);
+ }
+ hw->max_port_num = lane_cnt;
+ }
+
+ RNP_PMD_LOG(INFO,
+ "%s: nic-mode:%d lane_cnt:%d lane_mask:0x%x "
+ "pfvfnum:0x%x, fw_version:0x%08x, ports:%d-%d-%d-%d ncsi:en:%d\n",
+ __func__,
+ hw->nic_mode,
+ lane_cnt,
+ hw->lane_mask,
+ hw->pfvfnum,
+ ablity.fw_version,
+ ablity.port_ids[0],
+ ablity.port_ids[1],
+ ablity.port_ids[2],
+ ablity.port_ids[3],
+ hw->ncsi_en);
+
+ if (lane_cnt <= 0 || lane_cnt > 4)
+ return -EIO;
+
+ return err;
+}
+
+int rnp_mbx_link_event_enable(struct rte_eth_dev *dev, int enable)
+{
+ struct rnp_mbx_api *ops = RNP_DEV_TO_MBX_OPS(dev);
+ struct rnp_hw *hw = RNP_DEV_TO_HW(dev);
+ struct mbx_fw_cmd_reply reply;
+ struct mbx_fw_cmd_req req;
+ int err, v;
+
+ memset(&req, 0, sizeof(req));
+ memset(&reply, 0, sizeof(reply));
+
+ rte_spinlock_lock(&hw->fw_lock);
+ if (enable) {
+ v = rnp_rd_reg(hw->link_sync);
+ v &= ~RNP_FIRMWARE_SYNC_MASK;
+ v |= RNP_FIRMWARE_SYNC_MAGIC;
+ rnp_wr_reg(hw->link_sync, v);
+ } else {
+ rnp_wr_reg(hw->link_sync, 0);
+ }
+ rte_spinlock_unlock(&hw->fw_lock);
+
+ build_link_set_event_mask(&req, BIT(EVT_LINK_UP),
+ (enable & 1) << EVT_LINK_UP, &req);
+
+ rte_spinlock_lock(&hw->fw_lock);
+ err = ops->write_posted(dev, (u32 *)&req,
+ (req.datalen + MBX_REQ_HDR_LEN) / 4, MBX_FW);
+ rte_spinlock_unlock(&hw->fw_lock);
+
+ rte_delay_ms(200);
+
+ return err;
+}
+
+int rnp_mbx_fw_reset_phy(struct rte_eth_dev *dev)
+{
+ struct rnp_hw *hw = RNP_DEV_TO_HW(dev);
+ struct mbx_fw_cmd_reply reply;
+ struct mbx_req_cookie *cookie;
+ struct mbx_fw_cmd_req req;
+
+ memset(&req, 0, sizeof(req));
+ memset(&reply, 0, sizeof(reply));
+
+ if (hw->mbx.irq_enabled) {
+ cookie = rnp_memzone_reserve(hw->cookie_p_name, 0);
+ if (!cookie)
+ return -ENOMEM;
+ memset(cookie->priv, 0, cookie->priv_len);
+ build_reset_phy_req(&req, cookie);
+ return rnp_mbx_fw_post_req(dev, &req, cookie);
+ }
+ build_reset_phy_req(&req, &req);
+
+ return rnp_fw_send_cmd_wait(dev, &req, &reply);
+}
diff --git a/drivers/net/rnp/rnp_mbx_fw.h b/drivers/net/rnp/rnp_mbx_fw.h
index 439090b5a3..3651e32fcc 100644
--- a/drivers/net/rnp/rnp_mbx_fw.h
+++ b/drivers/net/rnp/rnp_mbx_fw.h
@@ -16,7 +16,168 @@ struct mbx_req_cookie {
int priv_len;
char priv[RNP_MAX_SHARE_MEM];
};
+enum GENERIC_CMD {
+ /* link configuration admin commands */
+ GET_PHY_ABALITY = 0x0601,
+ RESET_PHY = 0x0603,
+ SET_EVENT_MASK = 0x0613,
+};
+
+enum link_event_mask {
+ EVT_LINK_UP = 1,
+ EVT_NO_MEDIA = 2,
+ EVT_LINK_FAULT = 3,
+ EVT_PHY_TEMP_ALARM = 4,
+ EVT_EXCESSIVE_ERRORS = 5,
+ EVT_SIGNAL_DETECT = 6,
+ EVT_AUTO_NEGOTIATION_DONE = 7,
+ EVT_MODULE_QUALIFICATION_FAILD = 8,
+ EVT_PORT_TX_SUSPEND = 9,
+};
+
+enum pma_type {
+ PHY_TYPE_NONE = 0,
+ PHY_TYPE_1G_BASE_KX,
+ PHY_TYPE_SGMII,
+ PHY_TYPE_10G_BASE_KR,
+ PHY_TYPE_25G_BASE_KR,
+ PHY_TYPE_40G_BASE_KR4,
+ PHY_TYPE_10G_BASE_SR,
+ PHY_TYPE_40G_BASE_SR4,
+ PHY_TYPE_40G_BASE_CR4,
+ PHY_TYPE_40G_BASE_LR4,
+ PHY_TYPE_10G_BASE_LR,
+ PHY_TYPE_10G_BASE_ER,
+};
+
+struct phy_abilities {
+ unsigned char link_stat;
+ unsigned char lane_mask;
+
+ int speed;
+ short phy_type;
+ short nic_mode;
+ short pfnum;
+ unsigned int fw_version;
+ unsigned int axi_mhz;
+ uint8_t port_ids[4];
+ uint32_t fw_uid;
+ uint32_t phy_id;
+
+ int wol_status;
+
+ union {
+ unsigned int ext_ablity;
+ struct {
+ unsigned int valid : 1;
+ unsigned int wol_en : 1;
+ unsigned int pci_preset_runtime_en : 1;
+ unsigned int smbus_en : 1;
+ unsigned int ncsi_en : 1;
+ unsigned int rpu_en : 1;
+ unsigned int v2 : 1;
+ unsigned int pxe_en : 1;
+ unsigned int mctp_en : 1;
+ } e;
+ };
+} __rte_packed __rte_aligned(4);
+
+/* firmware -> driver */
struct mbx_fw_cmd_reply {
-} __rte_cache_aligned;
+ /* fw must set: DD, CMP, Error(if error), copy value */
+ unsigned short flags;
+ /* from command: LB,RD,VFC,BUF,SI,EI,FE */
+ unsigned short opcode; /* 2-3: copy from req */
+ unsigned short error_code; /* 4-5: 0 if no error */
+ unsigned short datalen; /* 6-7: */
+ union {
+ struct {
+ unsigned int cookie_lo; /* 8-11: */
+ unsigned int cookie_hi; /* 12-15: */
+ };
+ void *cookie;
+ };
+ /* ===== data ==== [16-64] */
+ union {
+ struct phy_abilities phy_abilities;
+ };
+} __rte_packed __rte_aligned(4);
+
+#define MBX_REQ_HDR_LEN 24
+/* driver -> firmware */
+struct mbx_fw_cmd_req {
+ unsigned short flags; /* 0-1 */
+ unsigned short opcode; /* 2-3 enum LINK_ADM_CMD */
+ unsigned short datalen; /* 4-5 */
+ unsigned short ret_value; /* 6-7 */
+ union {
+ struct {
+ unsigned int cookie_lo; /* 8-11 */
+ unsigned int cookie_hi; /* 12-15 */
+ };
+ void *cookie;
+ };
+ unsigned int reply_lo; /* 16-19 5dw */
+ unsigned int reply_hi; /* 20-23 */
+ /* === data === [24-64] 7dw */
+ union {
+ struct {
+ int requestor;
+#define REQUEST_BY_DPDK 0xa1
+#define REQUEST_BY_DRV 0xa2
+#define REQUEST_BY_PXE 0xa3
+ } get_phy_ablity;
+
+ struct {
+ unsigned short enable_stat;
+ unsigned short event_mask; /* enum link_event_mask */
+ } stat_event_mask;
+ };
+} __rte_packed __rte_aligned(4);
+
+static inline void
+build_phy_abalities_req(struct mbx_fw_cmd_req *req, void *cookie)
+{
+ req->flags = 0;
+ req->opcode = GET_PHY_ABALITY;
+ req->datalen = 0;
+ req->reply_lo = 0;
+ req->reply_hi = 0;
+ req->cookie = cookie;
+}
+
+/* enum link_event_mask or */
+static inline void
+build_link_set_event_mask(struct mbx_fw_cmd_req *req,
+ unsigned short event_mask,
+ unsigned short enable,
+ void *cookie)
+{
+ req->flags = 0;
+ req->opcode = SET_EVENT_MASK;
+ req->datalen = sizeof(req->stat_event_mask);
+ req->cookie = cookie;
+ req->reply_lo = 0;
+ req->reply_hi = 0;
+ req->stat_event_mask.event_mask = event_mask;
+ req->stat_event_mask.enable_stat = enable;
+}
+
+static inline void
+build_reset_phy_req(struct mbx_fw_cmd_req *req,
+ void *cookie)
+{
+ req->flags = 0;
+ req->opcode = RESET_PHY;
+ req->datalen = 0;
+ req->reply_lo = 0;
+ req->reply_hi = 0;
+ req->cookie = cookie;
+}
+int rnp_mbx_get_capability(struct rte_eth_dev *dev,
+ int *lane_mask,
+ int *nic_mode);
+int rnp_mbx_link_event_enable(struct rte_eth_dev *dev, int enable);
+int rnp_mbx_fw_reset_phy(struct rte_eth_dev *dev);
#endif /* __RNP_MBX_FW_H__*/
--
2.27.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [[PATCH v1] 6/8] net/rnp add port info resource init
2023-08-01 6:43 [[PATCH v1] 0/8] *** SUBJECT HERE *** Wenbo Cao
` (4 preceding siblings ...)
2023-08-01 6:43 ` [[PATCH v1] 5/8] net/rnp add reset code for Chip Init process Wenbo Cao
@ 2023-08-01 6:43 ` Wenbo Cao
2023-08-01 6:43 ` [[PATCH v1] 7/8] net/rnp add devargs runtime parsing functions Wenbo Cao
6 siblings, 0 replies; 11+ messages in thread
From: Wenbo Cao @ 2023-08-01 6:43 UTC (permalink / raw)
To: caowenbo; +Cc: dev
Add Api For FW Mac Info, Port Resoucre info init Code
For Different Shape Of Nic
Signed-off-by: Wenbo Cao <caowenbo@mucse.com>
---
drivers/net/rnp/base/rnp_api.c | 47 +++++++
drivers/net/rnp/base/rnp_api.h | 10 ++
drivers/net/rnp/base/rnp_hw.h | 19 +++
drivers/net/rnp/meson.build | 1 +
drivers/net/rnp/rnp.h | 88 +++++++++++++
drivers/net/rnp/rnp_ethdev.c | 224 +++++++++++++++++++++++++++++++--
drivers/net/rnp/rnp_mbx_fw.c | 112 +++++++++++++++++
drivers/net/rnp/rnp_mbx_fw.h | 115 +++++++++++++++++
drivers/net/rnp/rnp_rxtx.c | 83 ++++++++++++
drivers/net/rnp/rnp_rxtx.h | 14 +++
10 files changed, 706 insertions(+), 7 deletions(-)
create mode 100644 drivers/net/rnp/rnp_rxtx.c
create mode 100644 drivers/net/rnp/rnp_rxtx.h
diff --git a/drivers/net/rnp/base/rnp_api.c b/drivers/net/rnp/base/rnp_api.c
index f3044e595e..f2ab0ea270 100644
--- a/drivers/net/rnp/base/rnp_api.c
+++ b/drivers/net/rnp/base/rnp_api.c
@@ -22,3 +22,50 @@ rnp_reset_hw(struct rte_eth_dev *dev, struct rnp_hw *hw)
return -EOPNOTSUPP;
}
+int
+rnp_get_mac_addr(struct rte_eth_dev *dev, uint8_t *macaddr)
+{
+ struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
+ struct rnp_mac_api *ops = RNP_DEV_TO_MAC_OPS(dev);
+
+ if (!macaddr)
+ return -EINVAL;
+ if (ops->get_mac_addr)
+ return ops->get_mac_addr(port, port->attr.nr_lane, macaddr);
+ return -EOPNOTSUPP;
+}
+
+int
+rnp_set_default_mac(struct rte_eth_dev *dev, uint8_t *mac_addr)
+{
+ struct rnp_mac_api *ops = RNP_DEV_TO_MAC_OPS(dev);
+ struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
+
+ if (ops->set_default_mac)
+ return ops->set_default_mac(port, mac_addr);
+ return -EOPNOTSUPP;
+}
+
+int
+rnp_set_rafb(struct rte_eth_dev *dev, uint8_t *addr,
+ uint8_t vm_pool, uint8_t index)
+{
+ struct rnp_mac_api *ops = RNP_DEV_TO_MAC_OPS(dev);
+ struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
+
+ if (ops->set_rafb)
+ return ops->set_rafb(port, addr, vm_pool, index);
+ return -EOPNOTSUPP;
+}
+
+int
+rnp_clear_rafb(struct rte_eth_dev *dev,
+ uint8_t vm_pool, uint8_t index)
+{
+ struct rnp_mac_api *ops = RNP_DEV_TO_MAC_OPS(dev);
+ struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
+
+ if (ops->clear_rafb)
+ return ops->clear_rafb(port, vm_pool, index);
+ return -EOPNOTSUPP;
+}
diff --git a/drivers/net/rnp/base/rnp_api.h b/drivers/net/rnp/base/rnp_api.h
index df574dab77..b998b11237 100644
--- a/drivers/net/rnp/base/rnp_api.h
+++ b/drivers/net/rnp/base/rnp_api.h
@@ -4,4 +4,14 @@ int
rnp_init_hw(struct rte_eth_dev *dev);
int
rnp_reset_hw(struct rte_eth_dev *dev, struct rnp_hw *hw);
+int
+rnp_get_mac_addr(struct rte_eth_dev *dev, uint8_t *macaddr);
+int
+rnp_set_default_mac(struct rte_eth_dev *dev, uint8_t *mac_addr);
+int
+rnp_set_rafb(struct rte_eth_dev *dev, uint8_t *addr,
+ uint8_t vm_pool, uint8_t index);
+int
+rnp_clear_rafb(struct rte_eth_dev *dev,
+ uint8_t vm_pool, uint8_t index);
#endif /* __RNP_API_H__ */
diff --git a/drivers/net/rnp/base/rnp_hw.h b/drivers/net/rnp/base/rnp_hw.h
index 03381ab6d0..7b7584959e 100644
--- a/drivers/net/rnp/base/rnp_hw.h
+++ b/drivers/net/rnp/base/rnp_hw.h
@@ -30,6 +30,11 @@ static inline void rnp_wr_reg(volatile void *reg, int val)
#define rnp_eth_rd(hw, off) rnp_rd_reg((char *)(hw)->eth_base + (off))
#define rnp_eth_wr(hw, off, val) \
rnp_wr_reg((char *)(hw)->eth_base + (off), val)
+/* ================== reg-rw == */
+#define RNP_MACADDR_UPDATE_LO(hw, hw_idx, val) \
+ rnp_eth_wr(hw, RNP_RAL_BASE_ADDR(hw_idx), val)
+#define RNP_MACADDR_UPDATE_HI(hw, hw_idx, val) \
+ rnp_eth_wr(hw, RNP_RAH_BASE_ADDR(hw_idx), val)
struct rnp_hw;
/* Mbx Operate info */
enum MBX_ID {
@@ -99,9 +104,23 @@ struct rnp_mbx_info {
rte_atomic16_t state;
} __rte_cache_aligned;
+struct rnp_eth_port;
struct rnp_mac_api {
int32_t (*init_hw)(struct rnp_hw *hw);
int32_t (*reset_hw)(struct rnp_hw *hw);
+ /* MAC Address */
+ int32_t (*get_mac_addr)(struct rnp_eth_port *port,
+ uint8_t lane,
+ uint8_t *macaddr);
+ int32_t (*set_default_mac)(struct rnp_eth_port *port, uint8_t *mac);
+ /* Receive Address Filter Table */
+ int32_t (*set_rafb)(struct rnp_eth_port *port,
+ uint8_t *mac,
+ uint8_t vm_pool,
+ uint8_t index);
+ int32_t (*clear_rafb)(struct rnp_eth_port *port,
+ uint8_t vm_pool,
+ uint8_t index);
};
struct rnp_mac_info {
diff --git a/drivers/net/rnp/meson.build b/drivers/net/rnp/meson.build
index c52566c357..7d63460c45 100644
--- a/drivers/net/rnp/meson.build
+++ b/drivers/net/rnp/meson.build
@@ -11,6 +11,7 @@ sources = files(
'rnp_ethdev.c',
'rnp_mbx.c',
'rnp_mbx_fw.c',
+ 'rnp_rxtx.c',
'base/rnp_api.c',
)
diff --git a/drivers/net/rnp/rnp.h b/drivers/net/rnp/rnp.h
index 70685e48a6..892dbc47f4 100644
--- a/drivers/net/rnp/rnp.h
+++ b/drivers/net/rnp/rnp.h
@@ -9,14 +9,90 @@
#define PCI_VENDOR_ID_MUCSE (0x8848)
#define RNP_DEV_ID_N10G (0x1000)
+#define RNP_DEV_ID_N400L_X4 (0x1021)
#define RNP_MAX_PORT_OF_PF (4)
#define RNP_CFG_BAR (4)
#define RNP_PF_INFO_BAR (0)
+/* Peer Port Own Indepent Resource */
+#define RNP_PORT_MAX_MACADDR (32)
+#define RNP_PORT_MAX_UC_MAC_SIZE (256)
+#define RNP_PORT_MAX_VLAN_HASH (12)
+#define RNP_PORT_MAX_UC_HASH_TB (8)
+
+/* Hardware Resource info */
+#define RNP_MAX_RX_QUEUE_NUM (128)
+#define RNP_MAX_TX_QUEUE_NUM (128)
+#define RNP_N400_MAX_RX_QUEUE_NUM (8)
+#define RNP_N400_MAX_TX_QUEUE_NUM (8)
+#define RNP_MAX_HASH_KEY_SIZE (10)
+#define RNP_MAX_MAC_ADDRS (128)
+#define RNP_MAX_SUPPORT_VF_NUM (64)
+#define RNP_MAX_VFTA_SIZE (128)
+#define RNP_MAX_TC_SUPPORT (4)
+
+#define RNP_MAX_UC_MAC_SIZE (4096) /* Max Num of Unicast MAC addr */
+#define RNP_MAX_UC_HASH_TB (128)
+#define RNP_MAX_MC_MAC_SIZE (4096) /* Max Num of Multicast MAC addr */
+#define RNP_MAC_MC_HASH_TB (128)
+#define RNP_MAX_VLAN_HASH_TB_SIZE (4096)
+
+#define RNP_MAX_UC_HASH_TABLE (128)
+#define RNP_MAC_MC_HASH_TABLE (128)
+#define RNP_UTA_BIT_SHIFT (5)
+
enum rnp_resource_share_m {
RNP_SHARE_CORPORATE = 0,
RNP_SHARE_INDEPEND,
};
+
+/* media type */
+enum rnp_media_type {
+ RNP_MEDIA_TYPE_UNKNOWN,
+ RNP_MEDIA_TYPE_FIBER,
+ RNP_MEDIA_TYPE_COPPER,
+ RNP_MEDIA_TYPE_BACKPLANE,
+ RNP_MEDIA_TYPE_NONE,
+};
+
+struct rnp_phy_meta {
+ uint16_t phy_type;
+ uint32_t speed_cap;
+ uint32_t supported_link;
+ uint16_t link_duplex;
+ uint16_t link_autoneg;
+ uint8_t media_type;
+ bool is_sgmii;
+ bool is_backplane;
+ bool fec;
+ uint32_t phy_identifier;
+};
+
+struct rnp_port_attr {
+ uint16_t max_mac_addrs; /* Max Support Mac Address */
+ uint16_t uc_hash_tb_size; /* Unicast Hash Table Size */
+ uint16_t max_uc_mac_hash; /* Max Num of hash MAC addr for UC */
+ uint16_t mc_hash_tb_size; /* Multicast Hash Table Size */
+ uint16_t max_mc_mac_hash; /* Max Num Of Hash Mac addr For MC */
+ uint16_t max_vlan_hash; /* Max Num Of Hash For Vlan ID*/
+ uint32_t hash_table_shift;
+ uint16_t rte_pid; /* Dpdk Manage Port Sequence Id */
+ uint8_t max_rx_queues; /* Belong To This Port Rxq Resource */
+ uint8_t max_tx_queues; /* Belong To This Port Rxq Resource */
+ uint8_t queue_ring_base;
+ uint8_t port_offset; /* Use For Redir Table Dma Ring Offset Of Port */
+ union {
+ uint8_t nr_lane; /* phy lane of This PF:0~3 */
+ uint8_t nr_port; /* phy lane of This PF:0~3 */
+ };
+ struct rnp_phy_meta phy_meta;
+ bool link_ready;
+ bool pre_link;
+ uint32_t speed;
+ uint16_t max_rx_pktlen; /* Current Port Max Support Packet Len */
+ uint16_t max_mtu;
+};
+
/*
* Structure to store private data for each driver instance (for each port).
*/
@@ -29,8 +105,16 @@ enum rnp_work_mode {
struct rnp_eth_port {
void *adapt;
+ uint8_t mac_addr[RTE_ETHER_ADDR_LEN];
struct rnp_hw *hw;
struct rte_eth_dev *eth_dev;
+ struct rnp_port_attr attr;
+ /* Recvice Mac Address Record Table */
+ uint8_t mac_use_tb[RNP_MAX_MAC_ADDRS];
+ uint8_t use_num_mac;
+ bool port_stopped;
+ bool port_closed;
+ enum rnp_resource_share_m s_mode; /* Port Resource Independ */
} __rte_cache_aligned;
struct rnp_share_ops {
@@ -61,6 +145,10 @@ struct rnp_eth_adapter {
(&((struct rnp_eth_adapter *)(RNP_DEV_TO_PORT((eth_dev))->adapt))->hw)
#define RNP_HW_TO_ADAPTER(hw) \
((struct rnp_eth_adapter *)((hw)->back))
+#define RNP_PORT_TO_HW(port) \
+ (&(((struct rnp_eth_adapter *)(port)->adapt)->hw))
+#define RNP_PORT_TO_ADAPTER(port) \
+ ((struct rnp_eth_adapter *)((port)->adapt))
#define RNP_DEV_PP_PRIV_TO_MBX_OPS(dev) \
(&((struct rnp_share_ops *)(dev)->process_private)->mbx_api)
#define RNP_DEV_PP_PRIV_TO_MAC_OPS(dev) \
diff --git a/drivers/net/rnp/rnp_ethdev.c b/drivers/net/rnp/rnp_ethdev.c
index b4287d8a3e..22b9ffd685 100644
--- a/drivers/net/rnp/rnp_ethdev.c
+++ b/drivers/net/rnp/rnp_ethdev.c
@@ -11,6 +11,7 @@
#include "rnp_mbx.h"
#include "base/rnp_api.h"
#include "rnp_mbx_fw.h"
+#include "rnp_rxtx.h"
#include "rnp_logs.h"
extern struct rnp_mbx_api rnp_mbx_pf_ops;
@@ -41,6 +42,62 @@ static int rnp_dev_close(struct rte_eth_dev *dev)
static const struct eth_dev_ops rnp_eth_dev_ops = {
};
+static void
+rnp_setup_port_attr(struct rnp_eth_port *port,
+ struct rte_eth_dev *dev,
+ uint8_t num_ports,
+ uint8_t p_id)
+{
+ struct rnp_port_attr *attr = &port->attr;
+ struct rnp_hw *hw = RNP_DEV_TO_HW(dev);
+ uint32_t lane_bit;
+
+ if (port->s_mode == RNP_SHARE_INDEPEND) {
+ attr->max_mac_addrs = RNP_PORT_MAX_MACADDR;
+ attr->max_uc_mac_hash = RNP_PORT_MAX_UC_MAC_SIZE;
+ attr->uc_hash_tb_size = RNP_PORT_MAX_UC_HASH_TB;
+ attr->max_mc_mac_hash = RNP_PORT_MAX_MACADDR;
+ attr->max_vlan_hash = RNP_PORT_MAX_VLAN_HASH;
+ attr->hash_table_shift = 26 - (attr->max_uc_mac_hash >> 7);
+ } else {
+ attr->max_mac_addrs = RNP_MAX_MAC_ADDRS / num_ports;
+ attr->max_uc_mac_hash = RNP_MAX_UC_MAC_SIZE / num_ports;
+ attr->uc_hash_tb_size = RNP_MAX_UC_HASH_TB;
+ attr->max_mc_mac_hash = RNP_MAX_MC_MAC_SIZE / num_ports;
+ attr->mc_hash_tb_size = RNP_MAC_MC_HASH_TB;
+ attr->max_vlan_hash = RNP_MAX_VLAN_HASH_TB_SIZE / num_ports;
+ attr->hash_table_shift = RNP_UTA_BIT_SHIFT;
+ }
+ if (hw->ncsi_en)
+ attr->uc_hash_tb_size -= hw->ncsi_rar_entries;
+ if (hw->device_id == RNP_DEV_ID_N400L_X4) {
+ attr->max_rx_queues = RNP_N400_MAX_RX_QUEUE_NUM;
+ attr->max_tx_queues = RNP_N400_MAX_TX_QUEUE_NUM;
+ } else {
+ attr->max_rx_queues = RNP_MAX_RX_QUEUE_NUM / num_ports;
+ attr->max_tx_queues = RNP_MAX_TX_QUEUE_NUM / num_ports;
+ }
+
+ attr->rte_pid = dev->data->port_id;
+ lane_bit = hw->phy_port_ids[p_id] & (hw->max_port_num - 1);
+
+ attr->nr_port = lane_bit;
+ attr->port_offset = rnp_eth_rd(hw, RNP_TC_PORT_MAP_TB(attr->nr_port));
+
+ rnp_mbx_get_lane_stat(dev);
+
+ PMD_DRV_LOG(INFO, "PF[%d] SW-ETH-PORT[%d]<->PHY_LANE[%d]\n",
+ hw->function, p_id, lane_bit);
+}
+
+static void
+rnp_init_filter_setup(struct rnp_eth_port *port,
+ uint8_t num_ports)
+{
+ RTE_SET_USED(port);
+ RTE_SET_USED(num_ports);
+}
+
static int
rnp_init_port_resource(struct rnp_eth_adapter *adapter,
struct rte_eth_dev *dev,
@@ -48,11 +105,53 @@ rnp_init_port_resource(struct rnp_eth_adapter *adapter,
uint8_t p_id)
{
struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
+ struct rte_pci_device *pci_dev = adapter->pdev;
+ struct rnp_hw *hw = &adapter->hw;
+ port->adapt = adapter;
+ port->s_mode = adapter->s_mode;
+ port->port_stopped = 1;
+ port->hw = hw;
port->eth_dev = dev;
- adapter->ports[p_id] = port;
+
+ dev->device = &pci_dev->device;
+ rte_eth_copy_pci_info(dev, pci_dev);
dev->dev_ops = &rnp_eth_dev_ops;
- RTE_SET_USED(name);
+ dev->rx_queue_count = rnp_dev_rx_queue_count;
+ dev->rx_descriptor_status = rnp_dev_rx_descriptor_status;
+ dev->tx_descriptor_status = rnp_dev_tx_descriptor_status;
+ dev->rx_pkt_burst = rnp_recv_pkts;
+ dev->tx_pkt_burst = rnp_xmit_pkts;
+ dev->tx_pkt_prepare = rnp_prep_pkts;
+
+ rnp_setup_port_attr(port, dev, adapter->num_ports, p_id);
+ rnp_init_filter_setup(port, adapter->num_ports);
+ rnp_get_mac_addr(dev, port->mac_addr);
+ dev->data->mac_addrs = rte_zmalloc(name, sizeof(struct rte_ether_addr) *
+ port->attr.max_mac_addrs, 0);
+ if (!dev->data->mac_addrs) {
+ RNP_PMD_DRV_LOG(ERR, "Memory allocation "
+ "for MAC failed! Exiting.\n");
+ return -ENOMEM;
+ }
+ /* Allocate memory for storing hash filter MAC addresses */
+ dev->data->hash_mac_addrs = rte_zmalloc(name,
+ RTE_ETHER_ADDR_LEN * port->attr.max_uc_mac_hash, 0);
+ if (dev->data->hash_mac_addrs == NULL) {
+ RNP_PMD_INIT_LOG(ERR, "Failed to allocate %d bytes "
+ "needed to store MAC addresses",
+ RTE_ETHER_ADDR_LEN * port->attr.max_uc_mac_hash);
+ return -ENOMEM;
+ }
+
+ rnp_set_default_mac(dev, port->mac_addr);
+ rte_ether_addr_copy((const struct rte_ether_addr *)port->mac_addr,
+ dev->data->mac_addrs);
+ /* MTU */
+ dev->data->mtu = RTE_ETHER_MAX_LEN -
+ RTE_ETHER_HDR_LEN - RTE_ETHER_CRC_LEN;
+ adapter->ports[p_id] = port;
+ rte_eth_dev_probing_finish(dev);
return 0;
}
@@ -212,9 +311,116 @@ static int32_t rnp_init_hw_pf(struct rnp_hw *hw)
return 0;
}
+static void
+rnp_mac_res_take_in(struct rnp_eth_port *port,
+ uint8_t index)
+{
+ if (!port->mac_use_tb[index]) {
+ port->mac_use_tb[index] = true;
+ port->use_num_mac++;
+ }
+}
+
+static void
+rnp_mac_res_remove(struct rnp_eth_port *port,
+ uint8_t index)
+{
+ if (port->mac_use_tb[index]) {
+ port->mac_use_tb[index] = false;
+ port->use_num_mac--;
+ }
+}
+
+static int32_t rnp_set_mac_addr_pf(struct rnp_eth_port *port,
+ uint8_t *mac, uint8_t vm_pool,
+ uint8_t index)
+{
+ struct rnp_hw *hw = RNP_PORT_TO_HW(port);
+ struct rnp_port_attr *attr = &port->attr;
+ uint8_t hw_idx;
+ uint32_t value;
+
+ if (port->use_num_mac > port->attr.max_mac_addrs ||
+ index > port->attr.max_mac_addrs)
+ return -ENOMEM;
+
+ if (vm_pool != UINT8_MAX)
+ hw_idx = (attr->nr_port * attr->max_mac_addrs) + vm_pool + index;
+ else
+ hw_idx = (attr->nr_port * attr->max_mac_addrs) + index;
+
+ rnp_mac_res_take_in(port, hw_idx);
+
+ value = (mac[0] << 8) | mac[1];
+ value |= RNP_MAC_FILTER_EN;
+ RNP_MACADDR_UPDATE_HI(hw, hw_idx, value);
+
+ value = (mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5];
+ RNP_MACADDR_UPDATE_LO(hw, hw_idx, value);
+
+ return 0;
+}
+
+static void
+rnp_remove_mac_from_hw(struct rnp_eth_port *port,
+ uint8_t vm_pool, uint8_t index)
+{
+ struct rnp_hw *hw = RNP_PORT_TO_HW(port);
+ struct rnp_port_attr *attr = &port->attr;
+ uint16_t hw_idx;
+
+ if (vm_pool != UINT8_MAX)
+ hw_idx = (attr->nr_port * attr->max_mac_addrs) + vm_pool + index;
+ else
+ hw_idx = (attr->nr_port * attr->max_mac_addrs) + index;
+
+ rnp_mac_res_remove(port, hw_idx);
+
+ rnp_eth_wr(hw, RNP_RAL_BASE_ADDR(hw_idx), 0);
+ rnp_eth_wr(hw, RNP_RAH_BASE_ADDR(hw_idx), 0);
+}
+
+static int32_t
+rnp_clear_mac_addr_pf(struct rnp_eth_port *port,
+ uint8_t vm_pool, uint8_t index)
+{
+ rnp_remove_mac_from_hw(port, vm_pool, index);
+
+ return 0;
+}
+
+static int32_t rnp_get_mac_addr_pf(struct rnp_eth_port *port,
+ uint8_t lane,
+ uint8_t *macaddr)
+{
+ struct rnp_hw *hw = RNP_DEV_TO_HW(port->eth_dev);
+
+ return rnp_fw_get_macaddr(port->eth_dev, hw->pf_vf_num, macaddr, lane);
+}
+
+static int32_t
+rnp_set_default_mac_pf(struct rnp_eth_port *port,
+ uint8_t *mac)
+{
+ struct rnp_eth_adapter *adap = RNP_PORT_TO_ADAPTER(port);
+ uint16_t max_vfs;
+
+ if (port->s_mode == RNP_SHARE_INDEPEND)
+ return rnp_set_rafb(port->eth_dev, (uint8_t *)mac,
+ UINT8_MAX, 0);
+
+ max_vfs = adap->max_vfs;
+
+ return rnp_set_rafb(port->eth_dev, mac, max_vfs, 0);
+}
+
struct rnp_mac_api rnp_mac_ops = {
.reset_hw = rnp_reset_hw_pf,
- .init_hw = rnp_init_hw_pf
+ .init_hw = rnp_init_hw_pf,
+ .get_mac_addr = rnp_get_mac_addr_pf,
+ .set_default_mac = rnp_set_default_mac_pf,
+ .set_rafb = rnp_set_mac_addr_pf,
+ .clear_rafb = rnp_clear_mac_addr_pf
};
static void
@@ -229,7 +435,11 @@ rnp_common_ops_init(struct rnp_eth_adapter *adapter)
static int
rnp_special_ops_init(struct rte_eth_dev *eth_dev)
{
- RTE_SET_USED(eth_dev);
+ struct rnp_eth_adapter *adapter = RNP_DEV_TO_ADAPTER(eth_dev);
+ struct rnp_share_ops *share_priv;
+
+ share_priv = adapter->share_priv;
+ share_priv->mac_api = rnp_mac_ops;
return 0;
}
@@ -238,9 +448,9 @@ static int
rnp_eth_dev_init(struct rte_eth_dev *dev)
{
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+ struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
struct rnp_eth_adapter *adapter = NULL;
char name[RTE_ETH_NAME_MAX_LEN] = " ";
- struct rnp_eth_port *port = NULL;
struct rte_eth_dev *eth_dev;
struct rnp_hw *hw = NULL;
int32_t p_id;
@@ -276,13 +486,13 @@ rnp_eth_dev_init(struct rte_eth_dev *dev)
return ret;
}
adapter->share_priv = dev->process_private;
+ port->adapt = adapter;
rnp_common_ops_init(adapter);
+ rnp_init_mbx_ops_pf(hw);
rnp_get_nic_attr(adapter);
/* We need Use Device Id To Change The Resource Mode */
rnp_special_ops_init(dev);
- port->adapt = adapter;
port->hw = hw;
- rnp_init_mbx_ops_pf(hw);
for (p_id = 0; p_id < adapter->num_ports; p_id++) {
/* port 0 resource has been alloced When Probe */
if (!p_id) {
diff --git a/drivers/net/rnp/rnp_mbx_fw.c b/drivers/net/rnp/rnp_mbx_fw.c
index 5ac8b6608f..4901c98a75 100644
--- a/drivers/net/rnp/rnp_mbx_fw.c
+++ b/drivers/net/rnp/rnp_mbx_fw.c
@@ -270,3 +270,115 @@ int rnp_mbx_fw_reset_phy(struct rte_eth_dev *dev)
return rnp_fw_send_cmd_wait(dev, &req, &reply);
}
+
+int
+rnp_fw_get_macaddr(struct rte_eth_dev *dev,
+ int pfvfnum,
+ u8 *mac_addr,
+ int nr_lane)
+{
+ struct rnp_hw *hw = RNP_DEV_TO_HW(dev);
+ struct mbx_req_cookie *cookie;
+ struct mbx_fw_cmd_reply reply;
+ struct mbx_fw_cmd_req req;
+ struct mac_addr *mac;
+ int err;
+
+ memset(&req, 0, sizeof(req));
+ memset(&reply, 0, sizeof(reply));
+
+ if (!mac_addr)
+ return -EINVAL;
+
+ if (hw->mbx.irq_enabled) {
+ cookie = rnp_memzone_reserve(hw->cookie_p_name, 0);
+ if (!cookie)
+ return -ENOMEM;
+ memset(cookie->priv, 0, cookie->priv_len);
+ mac = (struct mac_addr *)cookie->priv;
+ build_get_macaddress_req(&req, 1 << nr_lane, pfvfnum, cookie);
+ err = rnp_mbx_fw_post_req(dev, &req, cookie);
+ if (err)
+ goto quit;
+
+ if ((1 << nr_lane) & mac->lanes) {
+ memcpy(mac_addr, mac->addrs[nr_lane].mac, 6);
+ err = 0;
+ } else {
+ err = -ENODATA;
+ }
+quit:
+ return err;
+ }
+ build_get_macaddress_req(&req, 1 << nr_lane, pfvfnum, &req);
+ err = rnp_fw_send_cmd_wait(dev, &req, &reply);
+ if (err) {
+ RNP_PMD_LOG(ERR, "%s: failed. err:%d\n", __func__, err);
+ return err;
+ }
+
+ if ((1 << nr_lane) & reply.mac_addr.lanes) {
+ memcpy(mac_addr, reply.mac_addr.addrs[nr_lane].mac, 6);
+ return 0;
+ }
+
+ return -ENODATA;
+}
+
+int rnp_mbx_get_lane_stat(struct rte_eth_dev *dev)
+{
+ struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
+ struct rnp_phy_meta *phy_meta = &port->attr.phy_meta;
+ struct rnp_hw *hw = RNP_DEV_TO_HW(dev);
+ struct lane_stat_data *lane_stat;
+ int nr_lane = port->attr.nr_lane;
+ struct mbx_req_cookie *cookie;
+ struct mbx_fw_cmd_reply reply;
+ struct mbx_fw_cmd_req req;
+ int err = 0;
+
+ memset(&req, 0, sizeof(req));
+
+ if (hw->mbx.irq_enabled) {
+ cookie = rnp_memzone_reserve(hw->cookie_p_name, 0);
+
+ if (!cookie)
+ return -ENOMEM;
+ memset(cookie->priv, 0, cookie->priv_len);
+ lane_stat = (struct lane_stat_data *)cookie->priv;
+ build_get_lane_status_req(&req, nr_lane, cookie);
+ err = rnp_mbx_fw_post_req(dev, &req, cookie);
+ if (err)
+ goto quit;
+ } else {
+ memset(&reply, 0, sizeof(reply));
+ build_get_lane_status_req(&req, nr_lane, &req);
+ err = rnp_fw_send_cmd_wait(dev, &req, &reply);
+ if (err)
+ goto quit;
+ lane_stat = (struct lane_stat_data *)reply.data;
+ }
+
+ phy_meta->supported_link = lane_stat->supported_link;
+ phy_meta->is_backplane = lane_stat->is_backplane;
+ phy_meta->phy_identifier = lane_stat->phy_addr;
+ phy_meta->link_autoneg = lane_stat->autoneg;
+ phy_meta->link_duplex = lane_stat->duplex;
+ phy_meta->phy_type = lane_stat->phy_type;
+ phy_meta->is_sgmii = lane_stat->is_sgmii;
+ phy_meta->fec = lane_stat->fec;
+
+ if (phy_meta->is_sgmii) {
+ phy_meta->media_type = RNP_MEDIA_TYPE_COPPER;
+ phy_meta->supported_link |=
+ RNP_SPEED_CAP_100M_HALF | RNP_SPEED_CAP_10M_HALF;
+ } else if (phy_meta->is_backplane) {
+ phy_meta->media_type = RNP_MEDIA_TYPE_BACKPLANE;
+ } else {
+ phy_meta->media_type = RNP_MEDIA_TYPE_FIBER;
+ }
+
+ return 0;
+quit:
+ return err;
+}
diff --git a/drivers/net/rnp/rnp_mbx_fw.h b/drivers/net/rnp/rnp_mbx_fw.h
index 3651e32fcc..49ab79888f 100644
--- a/drivers/net/rnp/rnp_mbx_fw.h
+++ b/drivers/net/rnp/rnp_mbx_fw.h
@@ -19,7 +19,9 @@ struct mbx_req_cookie {
enum GENERIC_CMD {
/* link configuration admin commands */
GET_PHY_ABALITY = 0x0601,
+ GET_MAC_ADDRES = 0x0602,
RESET_PHY = 0x0603,
+ GET_LANE_STATUS = 0x0610,
SET_EVENT_MASK = 0x0613,
};
@@ -82,6 +84,61 @@ struct phy_abilities {
};
} __rte_packed __rte_aligned(4);
+#define RNP_SPEED_CAP_UNKNOWN (0)
+#define RNP_SPEED_CAP_10M_FULL BIT(2)
+#define RNP_SPEED_CAP_100M_FULL BIT(3)
+#define RNP_SPEED_CAP_1GB_FULL BIT(4)
+#define RNP_SPEED_CAP_10GB_FULL BIT(5)
+#define RNP_SPEED_CAP_40GB_FULL BIT(6)
+#define RNP_SPEED_CAP_25GB_FULL BIT(7)
+#define RNP_SPEED_CAP_50GB_FULL BIT(8)
+#define RNP_SPEED_CAP_100GB_FULL BIT(9)
+#define RNP_SPEED_CAP_10M_HALF BIT(10)
+#define RNP_SPEED_CAP_100M_HALF BIT(11)
+#define RNP_SPEED_CAP_1GB_HALF BIT(12)
+
+struct lane_stat_data {
+ u8 nr_lane; /* 0-3 cur port correspond with hw lane */
+ u8 pci_gen : 4; /* nic cur pci speed genX: 1,2,3 */
+ u8 pci_lanes : 4; /* nic cur pci x1 x2 x4 x8 x16 */
+ u8 pma_type;
+ u8 phy_type; /* interface media type */
+
+ u16 linkup : 1; /* cur port link state */
+ u16 duplex : 1; /* duplex state only RJ45 valid */
+ u16 autoneg : 1; /* autoneg state */
+ u16 fec : 1; /* fec state */
+ u16 rev_an : 1;
+ u16 link_traing : 1; /* link-traing state */
+ u16 media_availble : 1;
+ u16 is_sgmii : 1; /* 1: Twisted Pair 0: FIBRE */
+ u16 link_fault : 4;
+#define LINK_LINK_FAULT BIT(0)
+#define LINK_TX_FAULT BIT(1)
+#define LINK_RX_FAULT BIT(2)
+#define LINK_REMOTE_FAULT BIT(3)
+ u16 is_backplane : 1; /* 1: Backplane Mode */
+ union {
+ u8 phy_addr; /* Phy MDIO address */
+ struct {
+ u8 mod_abs : 1;
+ u8 fault : 1;
+ u8 tx_dis : 1;
+ u8 los : 1;
+ } sfp;
+ };
+ u8 sfp_connector;
+ u32 speed; /* Current Speed Value */
+
+ u32 si_main;
+ u32 si_pre;
+ u32 si_post;
+ u32 si_tx_boost;
+ u32 supported_link; /* Cur nic Support Link cap */
+ u32 phy_id;
+ u32 advertised_link; /* autoneg mode advertised cap */
+} __rte_packed __rte_aligned(4);
+
/* firmware -> driver */
struct mbx_fw_cmd_reply {
/* fw must set: DD, CMP, Error(if error), copy value */
@@ -99,6 +156,19 @@ struct mbx_fw_cmd_reply {
};
/* ===== data ==== [16-64] */
union {
+ char data[0];
+
+ struct mac_addr {
+ int lanes;
+ struct _addr {
+ /* for macaddr:01:02:03:04:05:06
+ * mac-hi=0x01020304 mac-lo=0x05060000
+ */
+ unsigned char mac[8];
+ } addrs[4];
+ } mac_addr;
+
+ struct lane_stat_data lanestat;
struct phy_abilities phy_abilities;
};
} __rte_packed __rte_aligned(4);
@@ -128,10 +198,19 @@ struct mbx_fw_cmd_req {
#define REQUEST_BY_PXE 0xa3
} get_phy_ablity;
+ struct {
+ int lane_mask;
+ int pfvf_num;
+ } get_mac_addr;
+
struct {
unsigned short enable_stat;
unsigned short event_mask; /* enum link_event_mask */
} stat_event_mask;
+
+ struct {
+ int nr_lane;
+ } get_lane_st;
};
} __rte_packed __rte_aligned(4);
@@ -146,6 +225,23 @@ build_phy_abalities_req(struct mbx_fw_cmd_req *req, void *cookie)
req->cookie = cookie;
}
+static inline void
+build_get_macaddress_req(struct mbx_fw_cmd_req *req,
+ int lane_mask,
+ int pfvfnum,
+ void *cookie)
+{
+ req->flags = 0;
+ req->opcode = GET_MAC_ADDRES;
+ req->datalen = sizeof(req->get_mac_addr);
+ req->cookie = cookie;
+ req->reply_lo = 0;
+ req->reply_hi = 0;
+
+ req->get_mac_addr.lane_mask = lane_mask;
+ req->get_mac_addr.pfvf_num = pfvfnum;
+}
+
/* enum link_event_mask or */
static inline void
build_link_set_event_mask(struct mbx_fw_cmd_req *req,
@@ -175,9 +271,28 @@ build_reset_phy_req(struct mbx_fw_cmd_req *req,
req->cookie = cookie;
}
+static inline void
+build_get_lane_status_req(struct mbx_fw_cmd_req *req,
+ int nr_lane, void *cookie)
+{
+ req->flags = 0;
+ req->opcode = GET_LANE_STATUS;
+ req->datalen = sizeof(req->get_lane_st);
+ req->cookie = cookie;
+ req->reply_lo = 0;
+ req->reply_hi = 0;
+ req->get_lane_st.nr_lane = nr_lane;
+}
+
int rnp_mbx_get_capability(struct rte_eth_dev *dev,
int *lane_mask,
int *nic_mode);
int rnp_mbx_link_event_enable(struct rte_eth_dev *dev, int enable);
int rnp_mbx_fw_reset_phy(struct rte_eth_dev *dev);
+int
+rnp_fw_get_macaddr(struct rte_eth_dev *dev,
+ int pfvfnum,
+ u8 *mac_addr,
+ int nr_lane);
+int rnp_mbx_get_lane_stat(struct rte_eth_dev *dev);
#endif /* __RNP_MBX_FW_H__*/
diff --git a/drivers/net/rnp/rnp_rxtx.c b/drivers/net/rnp/rnp_rxtx.c
new file mode 100644
index 0000000000..679c0649a7
--- /dev/null
+++ b/drivers/net/rnp/rnp_rxtx.c
@@ -0,0 +1,83 @@
+#include <stdbool.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+
+#include <rte_version.h>
+#include <rte_ether.h>
+#include <rte_cycles.h>
+#include <rte_ethdev.h>
+#include <rte_malloc.h>
+#include <rte_memzone.h>
+#include <rte_vxlan.h>
+#include <rte_gre.h>
+#ifdef RTE_ARCH_ARM64
+#include <rte_cpuflags_64.h>
+#elif defined(RTE_ARCH_ARM)
+#include <rte_cpuflags_32.h>
+#endif
+
+#include "base/rnp_hw.h"
+#include "rnp.h"
+#include "rnp_rxtx.h"
+#include "rnp_logs.h"
+
+int
+rnp_dev_rx_descriptor_status(void *rx_queue, uint16_t offset)
+{
+ RTE_SET_USED(rx_queue);
+ RTE_SET_USED(offset);
+
+ return 0;
+}
+
+int
+rnp_dev_tx_descriptor_status(void *tx_queue, uint16_t offset)
+{
+ RTE_SET_USED(tx_queue);
+ RTE_SET_USED(offset);
+
+ return 0;
+}
+
+uint32_t
+rnp_dev_rx_queue_count(void *rx_queue)
+{
+ RTE_SET_USED(rx_queue);
+
+ return 0;
+}
+
+__rte_always_inline uint16_t
+rnp_recv_pkts(void *_rxq,
+ struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
+{
+ RTE_SET_USED(_rxq);
+ RTE_SET_USED(rx_pkts);
+ RTE_SET_USED(nb_pkts);
+
+ return 0;
+}
+
+__rte_always_inline uint16_t
+rnp_xmit_pkts(void *_txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
+{
+ RTE_SET_USED(_txq);
+ RTE_SET_USED(tx_pkts);
+ RTE_SET_USED(nb_pkts);
+
+ return 0;
+}
+
+uint16_t rnp_prep_pkts(void *tx_queue,
+ struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts)
+{
+ RTE_SET_USED(tx_queue);
+ RTE_SET_USED(tx_pkts);
+ RTE_SET_USED(nb_pkts);
+
+ return 0;
+}
diff --git a/drivers/net/rnp/rnp_rxtx.h b/drivers/net/rnp/rnp_rxtx.h
new file mode 100644
index 0000000000..0352971fcb
--- /dev/null
+++ b/drivers/net/rnp/rnp_rxtx.h
@@ -0,0 +1,14 @@
+#ifndef __RNP_RXTX_H__
+#define __RNP_RXTX_H__
+
+uint32_t rnp_dev_rx_queue_count(void *rx_queue);
+int rnp_dev_rx_descriptor_status(void *rx_queue, uint16_t offset);
+int rnp_dev_tx_descriptor_status(void *tx_queue, uint16_t offset);
+uint16_t
+rnp_recv_pkts(void *_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
+uint16_t
+rnp_xmit_pkts(void *_txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts);
+uint16_t rnp_prep_pkts(void *tx_queue,
+ struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts);
+#endif /* __RNP_RXTX_H__ */
--
2.27.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [[PATCH v1] 7/8] net/rnp add devargs runtime parsing functions
2023-08-01 6:43 [[PATCH v1] 0/8] *** SUBJECT HERE *** Wenbo Cao
` (5 preceding siblings ...)
2023-08-01 6:43 ` [[PATCH v1] 6/8] net/rnp add port info resource init Wenbo Cao
@ 2023-08-01 6:43 ` Wenbo Cao
6 siblings, 0 replies; 11+ messages in thread
From: Wenbo Cao @ 2023-08-01 6:43 UTC (permalink / raw)
To: caowenbo; +Cc: dev
add various runtime devargs command line options
supported by this driver.
Signed-off-by: Wenbo Cao <caowenbo@mucse.com>
---
drivers/net/rnp/rnp.h | 22 +++++
drivers/net/rnp/rnp_ethdev.c | 164 +++++++++++++++++++++++++++++++++++
drivers/net/rnp/rnp_mbx_fw.c | 164 +++++++++++++++++++++++++++++++++++
drivers/net/rnp/rnp_mbx_fw.h | 69 +++++++++++++++
4 files changed, 419 insertions(+)
diff --git a/drivers/net/rnp/rnp.h b/drivers/net/rnp/rnp.h
index 892dbc47f4..029e8a2776 100644
--- a/drivers/net/rnp/rnp.h
+++ b/drivers/net/rnp/rnp.h
@@ -107,6 +107,8 @@ struct rnp_eth_port {
void *adapt;
uint8_t mac_addr[RTE_ETHER_ADDR_LEN];
struct rnp_hw *hw;
+ uint8_t rx_func_sec; /* force set io rx_func */
+ uint8_t tx_func_sec; /* force set io tx func */
struct rte_eth_dev *eth_dev;
struct rnp_port_attr attr;
/* Recvice Mac Address Record Table */
@@ -122,6 +124,13 @@ struct rnp_share_ops {
struct rnp_mac_api mac_api;
} __rte_cache_aligned;
+enum {
+ RNP_IO_FUNC_USE_NONE = 0,
+ RNP_IO_FUNC_USE_VEC,
+ RNP_IO_FUNC_USE_SIMPLE,
+ RNP_IO_FUNC_USE_COMMON,
+};
+
struct rnp_eth_adapter {
enum rnp_work_mode mode;
enum rnp_resource_share_m s_mode; /* Port Resource Share Policy */
@@ -135,6 +144,19 @@ struct rnp_eth_adapter {
int max_link_speed;
uint8_t num_ports; /* Cur Pf Has physical Port Num */
uint8_t lane_mask;
+
+ uint8_t rx_func_sec; /* force set io rx_func */
+ uint8_t tx_func_sec; /* force set io tx func*/
+ /*fw-update*/
+ bool do_fw_update;
+ char *fw_path;
+
+ bool loopback_en;
+ bool fw_sfp_10g_1g_auto_det;
+ int fw_force_speed_1g;
+#define FOCE_SPEED_1G_NOT_SET (-1)
+#define FOCE_SPEED_1G_DISABLED (0)
+#define FOCE_SPEED_1G_ENABLED (1)
} __rte_cache_aligned;
#define RNP_DEV_TO_PORT(eth_dev) \
diff --git a/drivers/net/rnp/rnp_ethdev.c b/drivers/net/rnp/rnp_ethdev.c
index 22b9ffd685..fbcfc4f661 100644
--- a/drivers/net/rnp/rnp_ethdev.c
+++ b/drivers/net/rnp/rnp_ethdev.c
@@ -6,6 +6,7 @@
#include <rte_io.h>
#include <rte_malloc.h>
#include <ethdev_driver.h>
+#include <rte_kvargs.h>
#include "rnp.h"
#include "rnp_mbx.h"
@@ -14,6 +15,13 @@
#include "rnp_rxtx.h"
#include "rnp_logs.h"
+#define RNP_HW_MAC_LOOPBACK_ARG "hw_loopback"
+#define RNP_FW_UPDATE "fw_update"
+#define RNP_RX_FUNC_SELECT "rx_func_sec"
+#define RNP_TX_FUNC_SELECT "tx_func_sec"
+#define RNP_FW_4X10G_10G_1G_DET "fw_4x10g_10g_1g_auto_det"
+#define RNP_FW_FORCE_SPEED_1G "fw_force_1g_speed"
+
extern struct rnp_mbx_api rnp_mbx_pf_ops;
static int
rnp_mac_rx_disable(struct rte_eth_dev *dev)
@@ -109,6 +117,8 @@ rnp_init_port_resource(struct rnp_eth_adapter *adapter,
struct rnp_hw *hw = &adapter->hw;
port->adapt = adapter;
+ port->rx_func_sec = adapter->rx_func_sec;
+ port->tx_func_sec = adapter->tx_func_sec;
port->s_mode = adapter->s_mode;
port->port_stopped = 1;
port->hw = hw;
@@ -444,6 +454,152 @@ rnp_special_ops_init(struct rte_eth_dev *eth_dev)
return 0;
}
+static const char *const rnp_valid_arguments[] = {
+ RNP_HW_MAC_LOOPBACK_ARG,
+ RNP_FW_UPDATE,
+ RNP_RX_FUNC_SELECT,
+ RNP_TX_FUNC_SELECT,
+ RNP_FW_4X10G_10G_1G_DET,
+ RNP_FW_FORCE_SPEED_1G,
+ NULL
+};
+
+static int
+rnp_parse_handle_devarg(const char *key, const char *value,
+ void *extra_args)
+{
+ struct rnp_eth_adapter *adapter = NULL;
+
+ if (value == NULL || extra_args == NULL)
+ return -EINVAL;
+
+ if (strcmp(key, RNP_HW_MAC_LOOPBACK_ARG) == 0) {
+ uint16_t *n = extra_args;
+ *n = (uint16_t)strtoul(value, NULL, 10);
+ if (*n == USHRT_MAX && errno == ERANGE)
+ return -1;
+ } else if (strcmp(key, RNP_FW_UPDATE) == 0) {
+ adapter = (struct rnp_eth_adapter *)extra_args;
+ adapter->do_fw_update = true;
+ adapter->fw_path = strdup(value);
+ } else if (strcmp(key, RNP_FW_4X10G_10G_1G_DET) == 0) {
+ adapter = (struct rnp_eth_adapter *)extra_args;
+ if (adapter->num_ports == 2 && adapter->hw.speed == 10 * 1000) {
+ adapter->fw_sfp_10g_1g_auto_det =
+ (strcmp(value, "on") == 0) ? true : false;
+ } else {
+ adapter->fw_sfp_10g_1g_auto_det = false;
+ }
+ } else if (strcmp(key, RNP_FW_FORCE_SPEED_1G) == 0) {
+ adapter = (struct rnp_eth_adapter *)extra_args;
+ if (adapter->num_ports == 2) {
+ if (strcmp(value, "on") == 0)
+ adapter->fw_force_speed_1g = FOCE_SPEED_1G_ENABLED;
+ else if (strcmp(value, "off") == 0)
+ adapter->fw_force_speed_1g = FOCE_SPEED_1G_DISABLED;
+ }
+ } else {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+rnp_parse_io_select_func(const char *key, const char *value, void *extra_args)
+{
+ uint8_t select = RNP_IO_FUNC_USE_NONE;
+
+ RTE_SET_USED(key);
+
+ if (strcmp(value, "vec") == 0)
+ select = RNP_IO_FUNC_USE_VEC;
+ else if (strcmp(value, "simple") == 0)
+ select = RNP_IO_FUNC_USE_SIMPLE;
+ else if (strcmp(value, "common") == 0)
+ select = RNP_IO_FUNC_USE_COMMON;
+
+ *(uint8_t *)extra_args = select;
+
+ return 0;
+}
+
+static int
+rnp_parse_devargs(struct rnp_eth_adapter *adapter,
+ struct rte_devargs *devargs)
+{
+ uint8_t rx_io_func = RNP_IO_FUNC_USE_NONE;
+ uint8_t tx_io_func = RNP_IO_FUNC_USE_NONE;
+ struct rte_kvargs *kvlist;
+ bool loopback_en = false;
+ int ret = 0;
+
+ adapter->do_fw_update = false;
+ adapter->fw_sfp_10g_1g_auto_det = false;
+ adapter->fw_force_speed_1g = FOCE_SPEED_1G_NOT_SET;
+
+ if (!devargs)
+ goto def;
+
+ kvlist = rte_kvargs_parse(devargs->args, rnp_valid_arguments);
+ if (kvlist == NULL)
+ goto def;
+
+ if (rte_kvargs_count(kvlist, RNP_HW_MAC_LOOPBACK_ARG) == 1)
+ ret = rte_kvargs_process(kvlist, RNP_HW_MAC_LOOPBACK_ARG,
+ &rnp_parse_handle_devarg, &loopback_en);
+
+ if (rte_kvargs_count(kvlist, RNP_FW_4X10G_10G_1G_DET) == 1)
+ ret = rte_kvargs_process(kvlist,
+ RNP_FW_4X10G_10G_1G_DET,
+ &rnp_parse_handle_devarg,
+ adapter);
+
+ if (rte_kvargs_count(kvlist, RNP_FW_FORCE_SPEED_1G) == 1)
+ ret = rte_kvargs_process(kvlist,
+ RNP_FW_FORCE_SPEED_1G,
+ &rnp_parse_handle_devarg,
+ adapter);
+
+ if (rte_kvargs_count(kvlist, RNP_FW_UPDATE) == 1)
+ ret = rte_kvargs_process(kvlist, RNP_FW_UPDATE,
+ &rnp_parse_handle_devarg, adapter);
+ if (rte_kvargs_count(kvlist, RNP_RX_FUNC_SELECT) == 1)
+ ret = rte_kvargs_process(kvlist, RNP_RX_FUNC_SELECT,
+ &rnp_parse_io_select_func, &rx_io_func);
+ if (rte_kvargs_count(kvlist, RNP_TX_FUNC_SELECT) == 1)
+ ret = rte_kvargs_process(kvlist, RNP_TX_FUNC_SELECT,
+ &rnp_parse_io_select_func, &tx_io_func);
+ rte_kvargs_free(kvlist);
+def:
+ adapter->loopback_en = loopback_en;
+ adapter->rx_func_sec = rx_io_func;
+ adapter->tx_func_sec = tx_io_func;
+
+ return ret;
+}
+
+static int rnp_post_handle(struct rnp_eth_adapter *adapter)
+{
+ bool on = false;
+
+ if (!adapter->eth_dev)
+ return -ENOMEM;
+ if (adapter->do_fw_update && adapter->fw_path) {
+ rnp_fw_update(adapter);
+ adapter->do_fw_update = 0;
+ }
+
+ if (adapter->fw_sfp_10g_1g_auto_det)
+ return rnp_hw_set_fw_10g_1g_auto_detch(adapter->eth_dev, 1);
+
+ on = (adapter->fw_force_speed_1g == FOCE_SPEED_1G_ENABLED) ? 1 : 0;
+ if (adapter->fw_force_speed_1g != FOCE_SPEED_1G_NOT_SET)
+ return rnp_hw_set_fw_force_speed_1g(adapter->eth_dev, on);
+
+ return 0;
+}
+
static int
rnp_eth_dev_init(struct rte_eth_dev *dev)
{
@@ -493,6 +649,11 @@ rnp_eth_dev_init(struct rte_eth_dev *dev)
/* We need Use Device Id To Change The Resource Mode */
rnp_special_ops_init(dev);
port->hw = hw;
+ ret = rnp_parse_devargs(adapter, pci_dev->device.devargs);
+ if (ret) {
+ PMD_DRV_LOG(ERR, "parse_devargs failed");
+ return ret;
+ }
for (p_id = 0; p_id < adapter->num_ports; p_id++) {
/* port 0 resource has been alloced When Probe */
if (!p_id) {
@@ -519,6 +680,9 @@ rnp_eth_dev_init(struct rte_eth_dev *dev)
rnp_mac_tx_disable(eth_dev);
}
+ ret = rnp_post_handle(adapter);
+ if (ret)
+ goto init_failed;
return 0;
eth_alloc_error:
init_failed:
diff --git a/drivers/net/rnp/rnp_mbx_fw.c b/drivers/net/rnp/rnp_mbx_fw.c
index 4901c98a75..eda1389364 100644
--- a/drivers/net/rnp/rnp_mbx_fw.c
+++ b/drivers/net/rnp/rnp_mbx_fw.c
@@ -106,6 +106,27 @@ static int rnp_mbx_fw_post_req(struct rte_eth_dev *dev,
return err;
}
+static int
+rnp_mbx_write_posted_locked(struct rte_eth_dev *dev, struct mbx_fw_cmd_req *req)
+{
+ struct rnp_mbx_api *ops = RNP_DEV_TO_MBX_OPS(dev);
+ struct rnp_hw *hw = RNP_DEV_TO_HW(dev);
+ int err = 0;
+
+ rte_spinlock_lock(&hw->fw_lock);
+
+ err = ops->write_posted(dev, (u32 *)req,
+ (req->datalen + MBX_REQ_HDR_LEN) / 4, MBX_FW);
+ if (err) {
+ RNP_PMD_LOG(ERR, "%s failed!\n", __func__);
+ goto quit;
+ }
+
+quit:
+ rte_spinlock_unlock(&hw->fw_lock);
+ return err;
+}
+
static int rnp_fw_get_capablity(struct rte_eth_dev *dev,
struct phy_abilities *abil)
{
@@ -382,3 +403,146 @@ int rnp_mbx_get_lane_stat(struct rte_eth_dev *dev)
quit:
return err;
}
+
+static int rnp_maintain_req(struct rte_eth_dev *dev,
+ int cmd,
+ int arg0,
+ int req_data_bytes,
+ int reply_bytes,
+ phys_addr_t dma_phy_addr)
+{
+ struct rnp_hw *hw = RNP_DEV_TO_HW(dev);
+ struct mbx_req_cookie *cookie = NULL;
+ struct mbx_fw_cmd_req req;
+ int err;
+
+ if (!hw->mbx.irq_enabled)
+ return -EIO;
+ cookie = rnp_memzone_reserve(hw->cookie_p_name, 0);
+ if (!cookie)
+ return -ENOMEM;
+ memset(&req, 0, sizeof(req));
+ cookie->timeout_ms = 60 * 1000; /* 60s */
+
+ build_maintain_req(&req,
+ cookie,
+ cmd,
+ arg0,
+ req_data_bytes,
+ reply_bytes,
+ dma_phy_addr & 0xffffffff,
+ (dma_phy_addr >> 32) & 0xffffffff);
+
+ err = rnp_mbx_fw_post_req(dev, &req, cookie);
+
+ return (err) ? -EIO : 0;
+}
+
+int rnp_fw_update(struct rnp_eth_adapter *adapter)
+{
+ const struct rte_memzone *rz = NULL;
+ struct maintain_req *mt;
+ FILE *file;
+ int fsz;
+#define MAX_FW_BIN_SZ (552 * 1024)
+#define FW_256KB (256 * 1024)
+
+ RNP_PMD_LOG(INFO, "%s: %s\n", __func__, adapter->fw_path);
+
+ file = fopen(adapter->fw_path, "rb");
+ if (!file) {
+ RNP_PMD_LOG(ERR,
+ "RNP: [%s] %s can't open for read\n",
+ __func__,
+ adapter->fw_path);
+ return -ENOENT;
+ }
+ /* get dma */
+ rz = rte_memzone_reserve("fw_update", MAX_FW_BIN_SZ, SOCKET_ID_ANY, 4);
+ if (rz == NULL) {
+ RNP_PMD_LOG(ERR, "RNP: [%s] not memory:%d\n", __func__,
+ MAX_FW_BIN_SZ);
+ return -EFBIG;
+ }
+ memset(rz->addr, 0xff, rz->len);
+ mt = (struct maintain_req *)rz->addr;
+
+ /* read data */
+ fsz = fread(mt->data, 1, rz->len, file);
+ if (fsz <= 0) {
+ RNP_PMD_LOG(INFO, "RNP: [%s] read failed! err:%d\n",
+ __func__, fsz);
+ return -EIO;
+ }
+ fclose(file);
+
+ if (fsz > ((256 + 4) * 1024)) {
+ printf("fw length:%d is two big. not supported!\n", fsz);
+ return -EINVAL;
+ }
+ RNP_PMD_LOG(NOTICE, "RNP: fw update ...\n");
+ fflush(stdout);
+
+ /* ==== update fw */
+ mt->magic = MAINTAIN_MAGIC;
+ mt->cmd = MT_WRITE_FLASH;
+ mt->arg0 = 1;
+ mt->req_data_bytes = (fsz > FW_256KB) ? FW_256KB : fsz;
+ mt->reply_bytes = 0;
+
+ if (rnp_maintain_req(adapter->eth_dev, mt->cmd, mt->arg0,
+ mt->req_data_bytes, mt->reply_bytes, rz->iova))
+ RNP_PMD_LOG(ERR, "maintain request failed!\n");
+ else
+ RNP_PMD_LOG(INFO, "maintail request done!\n");
+
+ /* ==== update cfg */
+ if (fsz > FW_256KB) {
+ mt->magic = MAINTAIN_MAGIC;
+ mt->cmd = MT_WRITE_FLASH;
+ mt->arg0 = 2;
+ mt->req_data_bytes = 4096;
+ mt->reply_bytes = 0;
+ memcpy(mt->data, mt->data + FW_256KB, mt->req_data_bytes);
+
+ if (rnp_maintain_req(adapter->eth_dev,
+ mt->cmd, mt->arg0, mt->req_data_bytes,
+ mt->reply_bytes, rz->iova))
+ RNP_PMD_LOG(ERR, "maintain request failed!\n");
+ else
+ RNP_PMD_LOG(INFO, "maintail request done!\n");
+ }
+
+ RNP_PMD_LOG(NOTICE, "done\n");
+ fflush(stdout);
+
+ rte_memzone_free(rz);
+
+ exit(0);
+
+ return 0;
+}
+
+static int rnp_mbx_set_dump(struct rte_eth_dev *dev, int flag)
+{
+ struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
+ struct mbx_fw_cmd_req req;
+ int err;
+
+ memset(&req, 0, sizeof(req));
+ build_set_dump(&req, port->attr.nr_lane, flag);
+
+ err = rnp_mbx_write_posted_locked(dev, &req);
+
+ return err;
+}
+
+int rnp_hw_set_fw_10g_1g_auto_detch(struct rte_eth_dev *dev, int enable)
+{
+ return rnp_mbx_set_dump(dev, 0x01140000 | (enable & 1));
+}
+
+int rnp_hw_set_fw_force_speed_1g(struct rte_eth_dev *dev, int enable)
+{
+ return rnp_mbx_set_dump(dev, 0x01150000 | (enable & 1));
+}
diff --git a/drivers/net/rnp/rnp_mbx_fw.h b/drivers/net/rnp/rnp_mbx_fw.h
index 49ab79888f..cc45a572cc 100644
--- a/drivers/net/rnp/rnp_mbx_fw.h
+++ b/drivers/net/rnp/rnp_mbx_fw.h
@@ -16,6 +16,17 @@ struct mbx_req_cookie {
int priv_len;
char priv[RNP_MAX_SHARE_MEM];
};
+struct maintain_req {
+ int magic;
+#define MAINTAIN_MAGIC 0xa6a7a8a9
+
+ int cmd;
+ int arg0;
+ int req_data_bytes;
+ int reply_bytes;
+ char data[0];
+} __rte_packed;
+
enum GENERIC_CMD {
/* link configuration admin commands */
GET_PHY_ABALITY = 0x0601,
@@ -23,6 +34,9 @@ enum GENERIC_CMD {
RESET_PHY = 0x0603,
GET_LANE_STATUS = 0x0610,
SET_EVENT_MASK = 0x0613,
+ /* fw update */
+ FW_MAINTAIN = 0x0701,
+ SET_DUMP = 0x0a10,
};
enum link_event_mask {
@@ -211,6 +225,21 @@ struct mbx_fw_cmd_req {
struct {
int nr_lane;
} get_lane_st;
+
+ struct {
+ int cmd;
+#define MT_WRITE_FLASH 1
+ int arg0;
+ int req_bytes;
+ int reply_bytes;
+ int ddr_lo;
+ int ddr_hi;
+ } maintain;
+
+ struct {
+ int flag;
+ int nr_lane;
+ } set_dump;
};
} __rte_packed __rte_aligned(4);
@@ -284,6 +313,43 @@ build_get_lane_status_req(struct mbx_fw_cmd_req *req,
req->get_lane_st.nr_lane = nr_lane;
}
+static inline void
+build_maintain_req(struct mbx_fw_cmd_req *req,
+ void *cookie,
+ int cmd,
+ int arg0,
+ int req_bytes,
+ int reply_bytes,
+ u32 dma_phy_lo,
+ u32 dma_phy_hi)
+{
+ req->flags = 0;
+ req->opcode = FW_MAINTAIN;
+ req->datalen = sizeof(req->maintain);
+ req->cookie = cookie;
+ req->reply_lo = 0;
+ req->reply_hi = 0;
+ req->maintain.cmd = cmd;
+ req->maintain.arg0 = arg0;
+ req->maintain.req_bytes = req_bytes;
+ req->maintain.reply_bytes = reply_bytes;
+ req->maintain.ddr_lo = dma_phy_lo;
+ req->maintain.ddr_hi = dma_phy_hi;
+}
+
+static inline void
+build_set_dump(struct mbx_fw_cmd_req *req, int nr_lane, int flag)
+{
+ req->flags = 0;
+ req->opcode = SET_DUMP;
+ req->datalen = sizeof(req->set_dump);
+ req->cookie = NULL;
+ req->reply_lo = 0;
+ req->reply_hi = 0;
+ req->set_dump.flag = flag;
+ req->set_dump.nr_lane = nr_lane;
+}
+
int rnp_mbx_get_capability(struct rte_eth_dev *dev,
int *lane_mask,
int *nic_mode);
@@ -295,4 +361,7 @@ rnp_fw_get_macaddr(struct rte_eth_dev *dev,
u8 *mac_addr,
int nr_lane);
int rnp_mbx_get_lane_stat(struct rte_eth_dev *dev);
+int rnp_fw_update(struct rnp_eth_adapter *adapter);
+int rnp_hw_set_fw_10g_1g_auto_detch(struct rte_eth_dev *dev, int enable);
+int rnp_hw_set_fw_force_speed_1g(struct rte_eth_dev *dev, int enable);
#endif /* __RNP_MBX_FW_H__*/
--
2.27.0
^ permalink raw reply [flat|nested] 11+ messages in thread