]> git.droids-corp.org - dpdk.git/commitdiff
raw/ifpga/base: support device tree
authorTianfei Zhang <tianfei.zhang@intel.com>
Thu, 14 Nov 2019 09:02:53 +0000 (17:02 +0800)
committerFerruh Yigit <ferruh.yigit@intel.com>
Wed, 20 Nov 2019 16:36:05 +0000 (17:36 +0100)
In PAC N3000 card, this is a BMC chip which using MAX10 FPGA
to manage the board configuration, like sensors, flash controller,
QSFP, powers. And this is a SPI bus connected between A10 FPGA and
MAX10, we can access the MAX10 registers over this SPI bus.

In BMC, there are about 19 sensors in MAX10 chip, including the FPGA
core temperature, Board temperature, board current, voltage and so on.

We use DTB (Device tree table) to describe it. This DTB file is store
in nor flash partition, which will flashed in Factory when the boards
delivery to customers. And the same time, the customers can easy to
customize the BMC configuration like change the sensors.

Add device tree support by using libfdt library in Linux distribution.
The end-user should pre-install the libfdt and libfdt-devel package
before use DPDK on PAC N3000 Card.

For Centos 7.x: sudo yum install libfdt libfdt-devel
For Ubuntu 18.04: sudo apt install libfdt-dev libfdt1

To eliminate build error, we currently do not compile raw/ifpga
and net/ipn3ke. User should install libfdt and libfdt-devel first,
modify config/common_linux, CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=n
to CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=y, modify config/common_base,
CONFIG_RTE_LIBRTE_IPN3KE_PMD=n to CONFIG_RTE_LIBRTE_IPN3KE_PMD=y.
Then this function can work.

Signed-off-by: Tianfei Zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
config/common_base
config/common_linux
drivers/meson.build
drivers/net/ipn3ke/meson.build
drivers/raw/ifpga/base/meson.build
drivers/raw/ifpga/base/opae_intel_max10.c
drivers/raw/ifpga/base/opae_intel_max10.h
drivers/raw/ifpga/meson.build
mk/rte.app.mk

index 36ab13df7f54e347ea7ffe9a0f10f87898ae5f1f..7c015f932f840c511752f72a679594ab4e34ad80 100644 (file)
@@ -347,7 +347,7 @@ CONFIG_RTE_LIBRTE_IAVF_16BYTE_RX_DESC=n
 #
 # Compile burst-oriented IPN3KE PMD driver
 #
-CONFIG_RTE_LIBRTE_IPN3KE_PMD=y
+CONFIG_RTE_LIBRTE_IPN3KE_PMD=n
 
 #
 # Compile burst-oriented Mellanox ConnectX-3 (MLX4) PMD
index a78b8c6a5f2bd31312f73972d4e6a043d49f38bb..c5cf3d66281641552ee5fd27058eb717e897f3fc 100644 (file)
@@ -73,4 +73,4 @@ CONFIG_RTE_LIBRTE_HNS3_PMD=y
 # Compile PMD for Intel FPGA raw device
 # To compile, CONFIG_RTE_EAL_VFIO should be enabled.
 #
-CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=y
+CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=n
index 823e3ef839ed927f97cd3bfae0aa50db2c08301a..b7fdfb73578de684da5afbd3d75707fb6af3f390 100644 (file)
@@ -9,12 +9,12 @@ endif
 dpdk_driver_classes = ['common',
               'bus',
               'mempool', # depends on common and bus.
-              'net',     # depends on common, bus and mempool.
+              'raw',     # depends on common and bus.
+              'net',     # depends on common, bus, mempool and raw.
               'crypto',  # depends on common, bus and mempool (net in future).
               'compress', # depends on common, bus, mempool.
               'event',   # depends on common, bus, mempool and net.
-              'baseband', # depends on common and bus.
-              'raw']     # depends on common, bus, mempool, net and event.
+              'baseband'] # depends on common and bus.
 
 disabled_drivers = get_option('disable_drivers').split(',')
 
index 74b4d7c2503c9a62cad9345b13b1bca660232121..e3c8a6768c4e927105127f8af21a0dba7bab268b 100644 (file)
@@ -8,10 +8,22 @@
 #  rte_eth_dev_destroy()
 #  rte_eth_switch_domain_free()
 #
-allow_experimental_apis = true
 
-sources += files('ipn3ke_ethdev.c',
-       'ipn3ke_representor.c',
-       'ipn3ke_tm.c',
-       'ipn3ke_flow.c')
-deps += ['bus_ifpga', 'sched']
+dep = dependency('libfdt', required: false)
+if not dep.found()
+       dep = cc.find_library('libfdt', required: false)
+endif
+if not dep.found()
+       build = false
+       reason = 'missing dependency, "libfdt"'
+endif
+
+if build
+       allow_experimental_apis = true
+
+       sources += files('ipn3ke_ethdev.c',
+               'ipn3ke_representor.c',
+               'ipn3ke_tm.c',
+               'ipn3ke_flow.c')
+       deps += ['bus_ifpga', 'sched', 'pmd_i40e', 'rawdev', 'rawdev_ifpga']
+endif
index 69f6598863bfd8728aa5fefe8f0944726d8b7652..b13e13e894527d7cf828e81df0024c5c03baebc0 100644 (file)
@@ -25,5 +25,5 @@ sources = [
 
 base_lib = static_library('ifpga_rawdev_base', sources,
        dependencies: static_rte_eal,
-       c_args: c_args)
+       c_args: cflags)
 base_objs = base_lib.extract_all_objects()
index 9ed10e282c67d14b31590f816e7222baa49fc3c0..305baba8d4c97dfb9d0f63ecf30edbadbc301199 100644 (file)
@@ -3,6 +3,7 @@
  */
 
 #include "opae_intel_max10.h"
+#include <libfdt.h>
 
 static struct intel_max10_device *g_max10;
 
@@ -26,6 +27,174 @@ int max10_reg_write(unsigned int reg, unsigned int val)
                        reg, 4, (unsigned char *)&tmp);
 }
 
+static struct max10_compatible_id max10_id_table[] = {
+       {.compatible = MAX10_PAC,},
+       {.compatible = MAX10_PAC_N3000,},
+       {.compatible = MAX10_PAC_END,}
+};
+
+static struct max10_compatible_id *max10_match_compatible(const char *fdt_root)
+{
+       struct max10_compatible_id *id = max10_id_table;
+
+       for (; strcmp(id->compatible, MAX10_PAC_END); id++) {
+               if (fdt_node_check_compatible(fdt_root, 0, id->compatible))
+                       continue;
+
+               return id;
+       }
+
+       return NULL;
+}
+
+static inline bool
+is_max10_pac_n3000(struct intel_max10_device *max10)
+{
+       return max10->id && !strcmp(max10->id->compatible,
+                       MAX10_PAC_N3000);
+}
+
+static void max10_check_capability(struct intel_max10_device *max10)
+{
+       if (!max10->fdt_root)
+               return;
+
+       if (is_max10_pac_n3000(max10)) {
+               max10->flags |= MAX10_FLAGS_NO_I2C2 |
+                               MAX10_FLAGS_NO_BMCIMG_FLASH;
+               dev_info(max10, "found %s card\n", max10->id->compatible);
+       }
+}
+
+static int altera_nor_flash_read(u32 offset,
+               void *buffer, u32 len)
+{
+       int word_len;
+       int i;
+       unsigned int *buf = (unsigned int *)buffer;
+       unsigned int value;
+       int ret;
+
+       if (!buffer || len <= 0)
+               return -ENODEV;
+
+       word_len = len/4;
+
+       for (i = 0; i < word_len; i++) {
+               ret = max10_reg_read(offset + i*4,
+                               &value);
+               if (ret)
+                       return -EBUSY;
+
+               *buf++ = value;
+       }
+
+       return 0;
+}
+
+static int enable_nor_flash(bool on)
+{
+       unsigned int val = 0;
+       int ret;
+
+       ret = max10_reg_read(RSU_REG_OFF, &val);
+       if (ret) {
+               dev_err(NULL "enabling flash error\n");
+               return ret;
+       }
+
+       if (on)
+               val |= RSU_ENABLE;
+       else
+               val &= ~RSU_ENABLE;
+
+       return max10_reg_write(RSU_REG_OFF, val);
+}
+
+static int init_max10_device_table(struct intel_max10_device *max10)
+{
+       struct max10_compatible_id *id;
+       struct fdt_header hdr;
+       char *fdt_root = NULL;
+
+       u32 dt_size, dt_addr, val;
+       int ret;
+
+       ret = max10_reg_read(DT_AVAIL_REG_OFF, &val);
+       if (ret) {
+               dev_err(max10 "cannot read DT_AVAIL_REG\n");
+               return ret;
+       }
+
+       if (!(val & DT_AVAIL)) {
+               dev_err(max10 "DT not available\n");
+               return -EINVAL;
+       }
+
+       ret = max10_reg_read(DT_BASE_ADDR_REG_OFF, &dt_addr);
+       if (ret) {
+               dev_info(max10 "cannot get base addr of device table\n");
+               return ret;
+       }
+
+       ret = enable_nor_flash(true);
+       if (ret) {
+               dev_err(max10 "fail to enable flash\n");
+               return ret;
+       }
+
+       ret = altera_nor_flash_read(dt_addr, &hdr, sizeof(hdr));
+       if (ret) {
+               dev_err(max10 "read fdt header fail\n");
+               goto done;
+       }
+
+       ret = fdt_check_header(&hdr);
+       if (ret) {
+               dev_err(max10 "check fdt header fail\n");
+               goto done;
+       }
+
+       dt_size = fdt_totalsize(&hdr);
+       if (dt_size > DFT_MAX_SIZE) {
+               dev_err(max10 "invalid device table size\n");
+               ret = -EINVAL;
+               goto done;
+       }
+
+       fdt_root = opae_malloc(dt_size);
+       if (!fdt_root) {
+               ret = -ENOMEM;
+               goto done;
+       }
+
+       ret = altera_nor_flash_read(dt_addr, fdt_root, dt_size);
+       if (ret) {
+               dev_err(max10 "cannot read device table\n");
+               goto done;
+       }
+
+       id = max10_match_compatible(fdt_root);
+       if (!id) {
+               dev_err(max10 "max10 compatible not found\n");
+               ret = -ENODEV;
+               goto done;
+       }
+
+       max10->flags |= MAX10_FLAGS_DEVICE_TABLE;
+
+       max10->id = id;
+       max10->fdt_root = fdt_root;
+
+done:
+       ret = enable_nor_flash(false);
+
+       if (ret && fdt_root)
+               opae_free(fdt_root);
+
+       return ret;
+}
+
 struct intel_max10_device *
 intel_max10_device_probe(struct altera_spi_device *spi,
                int chipselect)
@@ -49,6 +218,15 @@ intel_max10_device_probe(struct altera_spi_device *spi,
        /* set the max10 device firstly */
        g_max10 = dev;
 
+       /* init the MAX10 device table */
+       ret = init_max10_device_table(dev);
+       if (ret) {
+               dev_err(dev, "init max10 device table fail\n");
+               goto free_dev;
+       }
+
+       max10_check_capability(dev);
+
        /* read FPGA loading information */
        ret = max10_reg_read(FPGA_PAGE_INFO_OFF, &val);
        if (ret) {
@@ -60,6 +238,8 @@ intel_max10_device_probe(struct altera_spi_device *spi,
        return dev;
 
 spi_tran_fail:
+       if (dev->fdt_root)
+               opae_free(dev->fdt_root);
        spi_transaction_remove(dev->spi_tran_dev);
 free_dev:
        g_max10 = NULL;
@@ -76,6 +256,9 @@ int intel_max10_device_remove(struct intel_max10_device *dev)
        if (dev->spi_tran_dev)
                spi_transaction_remove(dev->spi_tran_dev);
 
+       if (dev->fdt_root)
+               opae_free(dev->fdt_root);
+
        g_max10 = NULL;
        opae_free(dev);
 
index 08b387e8b7d532fe22471bcf09d741f6be652252..a52b63e18e8624a566ad727c3f0a96654adbcc26 100644 (file)
@@ -8,6 +8,14 @@
 #include "opae_osdep.h"
 #include "opae_spi.h"
 
+struct max10_compatible_id {
+       char compatible[128];
+};
+
+#define MAX10_PAC      "intel,max10"
+#define MAX10_PAC_N3000        "intel,max10-pac-n3000"
+#define MAX10_PAC_END    "intel,end"
+
 /* max10 capability flags */
 #define MAX10_FLAGS_NO_I2C2            BIT(0)
 #define MAX10_FLAGS_NO_BMCIMG_FLASH    BIT(1)
@@ -20,6 +28,8 @@ struct intel_max10_device {
        unsigned int flags; /*max10 hardware capability*/
        struct altera_spi_device *spi_master;
        struct spi_transaction_dev *spi_tran_dev;
+       struct max10_compatible_id *id; /*max10 compatible*/
+       char *fdt_root;
 };
 
 /* retimer speed */
index 0ab6fd7110506e0bd822410607d6b2c3a82c4a61..69debff1fe051805befe7eb316ffa0128ac3327d 100644 (file)
@@ -3,18 +3,27 @@
 
 version = 1
 
-subdir('base')
-objs = [base_objs]
-
 dep = dependency('libfdt', required: false)
+if not dep.found()
+       dep = cc.find_library('libfdt', required: false)
+endif
 if not dep.found()
        build = false
        reason = 'missing dependency, "libfdt"'
 endif
-deps += ['rawdev', 'pci', 'bus_pci', 'kvargs',
-       'bus_vdev', 'bus_ifpga', 'net']
-sources = files('ifpga_rawdev.c')
 
-includes += include_directories('base')
+if build
+       subdir('base')
+       objs = [base_objs]
+
+       deps += ['rawdev', 'pci', 'bus_pci', 'kvargs',
+               'bus_vdev', 'bus_ifpga', 'net']
+       ext_deps += dep
 
-allow_experimental_apis = true
+       sources = files('ifpga_rawdev.c')
+
+       includes += include_directories('base')
+       includes += include_directories('../../net/ipn3ke')
+
+       allow_experimental_apis = true
+endif
index 683e3a4e336f3aa35d0641808739946b35b73479..a278552c628124579848a9705050b163ddf3f649 100644 (file)
@@ -330,7 +330,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += -lrte_rawdev_dpaa2_qdma
 endif # CONFIG_RTE_LIBRTE_FSLMC_BUS
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IFPGA_BUS)      += -lrte_bus_ifpga
 ifeq ($(CONFIG_RTE_LIBRTE_IFPGA_BUS),y)
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV)   += -lrte_rawdev_ifpga
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV)   += -lrte_rawdev_ifpga -lfdt
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD)       += -lrte_pmd_ipn3ke
 endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IOAT_RAWDEV)   += -lrte_rawdev_ioat