* [U-Boot] [PATCH 1/8] armv8/fsl-lsch3: Add Freescale Debug Server driver
@ 2015-03-19 16:20 York Sun
2015-03-19 16:20 ` [U-Boot] [PATCH 2/8] fsl-ch3/README: Add description for NOR flash layout (firmware images) York Sun
` (7 more replies)
0 siblings, 8 replies; 11+ messages in thread
From: York Sun @ 2015-03-19 16:20 UTC (permalink / raw)
To: u-boot
From: Bhupesh Sharma <bhupesh.sharma@freescale.com>
The Debug Server driver is responsible for loading the Debug
server FW on the Service Processor (Cortex-A5 core) on LS2085A like
SoCs and then polling for the successful initialization of the same.
TOP MEM HIDE is adjusted to ensure the space required by Debug Server
FW is accounted for. MC uses the DDR area which is calculated as:
MC DDR region start = Top of DDR - area reserved by Debug Server FW
Signed-off-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
---
arch/arm/cpu/armv8/fsl-lsch3/cpu.c | 2 +-
arch/arm/include/asm/arch-fsl-lsch3/config.h | 10 +-
board/freescale/ls2085a/ls2085a.c | 29 +++
drivers/misc/Makefile | 1 +
drivers/misc/fsl_debug_server.c | 246 ++++++++++++++++++++++++++
drivers/net/fsl-mc/mc.c | 4 +
include/configs/ls2085a_common.h | 20 ++-
include/fsl-mc/fsl_mc.h | 1 +
include/fsl_debug_server.h | 32 ++++
9 files changed, 338 insertions(+), 7 deletions(-)
create mode 100644 drivers/misc/fsl_debug_server.c
create mode 100644 include/fsl_debug_server.h
diff --git a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c
index 4997487..618fbc2 100644
--- a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c
+++ b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c
@@ -10,6 +10,7 @@
#include <asm/armv8/mmu.h>
#include <asm/io.h>
#include <asm/arch-fsl-lsch3/immap_lsch3.h>
+#include <fsl_debug_server.h>
#include <fsl-mc/fsl_mc.h>
#include "cpu.h"
#include "mp.h"
@@ -384,7 +385,6 @@ int cpu_eth_init(bd_t *bis)
return error;
}
-
int arch_early_init_r(void)
{
int rv;
diff --git a/arch/arm/include/asm/arch-fsl-lsch3/config.h b/arch/arm/include/asm/arch-fsl-lsch3/config.h
index b140c1f..59d10bf 100644
--- a/arch/arm/include/asm/arch-fsl-lsch3/config.h
+++ b/arch/arm/include/asm/arch-fsl-lsch3/config.h
@@ -30,6 +30,15 @@
#define CONFIG_SYS_FSL_PMU_CLTBENR (CONFIG_SYS_FSL_PMU_ADDR + \
0x18A0)
+/* SP (Cortex-A5) related */
+#define CONFIG_SYS_FSL_SP_ADDR (CONFIG_SYS_IMMR + 0x00F00000)
+#define CONFIG_SYS_FSL_SP_VSG_GIC_ADDR (CONFIG_SYS_FSL_SP_ADDR)
+#define CONFIG_SYS_FSL_SP_VSG_GIC_VIGR1 (CONFIG_SYS_FSL_SP_ADDR)
+#define CONFIG_SYS_FSL_SP_VSG_GIC_VIGR2 \
+ (CONFIG_SYS_FSL_SP_ADDR + 0x0008)
+#define CONFIG_SYS_FSL_SP_LOOPBACK_DUART \
+ (CONFIG_SYS_FSL_SP_ADDR + 0x1000)
+
#define CONFIG_SYS_FSL_DCSR_DDR_ADDR 0x70012c000ULL
#define CONFIG_SYS_FSL_DCSR_DDR2_ADDR 0x70012d000ULL
#define CONFIG_SYS_FSL_DCSR_DDR3_ADDR 0x700132000ULL
@@ -88,7 +97,6 @@
#define CONFIG_MAX_MEM_MAPPED CONFIG_SYS_LS2_DDR_BLOCK1_SIZE
#define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_5_0
-
/* IFC */
#define CONFIG_SYS_FSL_IFC_LE
diff --git a/board/freescale/ls2085a/ls2085a.c b/board/freescale/ls2085a/ls2085a.c
index 519d61c..a16c2c8 100644
--- a/board/freescale/ls2085a/ls2085a.c
+++ b/board/freescale/ls2085a/ls2085a.c
@@ -12,6 +12,7 @@
#include <asm/io.h>
#include <fdt_support.h>
#include <libfdt.h>
+#include <fsl_debug_server.h>
#include <fsl-mc/fsl_mc.h>
#include <environment.h>
@@ -79,6 +80,34 @@ void reset_cpu(ulong addr)
{
}
+#if defined(CONFIG_ARCH_MISC_INIT)
+int arch_misc_init(void)
+{
+#ifdef CONFIG_FSL_DEBUG_SERVER
+ debug_server_init();
+#endif
+
+ return 0;
+}
+#endif
+
+unsigned long get_dram_size_to_hide(void)
+{
+ unsigned long dram_to_hide = 0;
+
+/* Carve the Debug Server private DRAM block from the end of DRAM */
+#ifdef CONFIG_FSL_DEBUG_SERVER
+ dram_to_hide += debug_server_get_dram_block_size();
+#endif
+
+/* Carve the MC private DRAM block from the end of DRAM */
+#ifdef CONFIG_FSL_MC_ENET
+ dram_to_hide += mc_get_dram_block_size();
+#endif
+
+ return dram_to_hide;
+}
+
int board_eth_init(bd_t *bis)
{
int error = 0;
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 6028cd4..3dd76eb 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpc.o
obj-$(CONFIG_CROS_EC_I2C) += cros_ec_i2c.o
obj-$(CONFIG_CROS_EC_SANDBOX) += cros_ec_sandbox.o
obj-$(CONFIG_CROS_EC_SPI) += cros_ec_spi.o
+obj-$(CONFIG_FSL_DEBUG_SERVER) += fsl_debug_server.o
obj-$(CONFIG_FSL_IIM) += fsl_iim.o
obj-$(CONFIG_GPIO_LED) += gpio_led.o
obj-$(CONFIG_I2C_EEPROM) += i2c_eeprom.o
diff --git a/drivers/misc/fsl_debug_server.c b/drivers/misc/fsl_debug_server.c
new file mode 100644
index 0000000..e080fe6
--- /dev/null
+++ b/drivers/misc/fsl_debug_server.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/arch-fsl-lsch3/immap_lsch3.h>
+
+#include <fsl_debug_server.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+static int debug_server_ver_info_maj, debug_server_ver_info_min;
+
+/**
+ * Copying Debug Server firmware to DDR
+ */
+static int debug_server_copy_image(const char *title, u64 image_addr,
+ u32 image_size, u64 debug_server_ram_addr)
+{
+ debug("%s copied to address %p\n", title,
+ (void *)debug_server_ram_addr);
+ memcpy((void *)debug_server_ram_addr, (void *)image_addr, image_size);
+
+ return 0;
+}
+
+/**
+ * Debug Server FIT image parser checks if the image is in FIT
+ * format, verifies integrity of the image and calculates
+ * raw image address and size values.
+ *
+ * Returns 0 if success and -1 if any of the above mentioned
+ * task fail.
+ **/
+int debug_server_parse_firmware_fit_image(const void **raw_image_addr,
+ size_t *raw_image_size)
+{
+ int format;
+ void *fit_hdr;
+ int node_offset;
+ const void *data;
+ size_t size;
+ const char *uname = "firmware";
+ char *desc;
+ char *debug_server_ver_info;
+ char *debug_server_ver_info_major, *debug_server_ver_info_minor;
+
+ /* Check if the image is in NOR flash */
+#ifdef CONFIG_SYS_DEBUG_SERVER_FW_IN_NOR
+ fit_hdr = (void *)CONFIG_SYS_DEBUG_SERVER_FW_ADDR;
+#else
+#error "CONFIG_SYS_DEBUG_SERVER_FW_IN_NOR not defined"
+#endif
+
+ /* Check if Image is in FIT format */
+ format = genimg_get_format(fit_hdr);
+ if (format != IMAGE_FORMAT_FIT) {
+ printf("Error! Not a FIT image\n");
+ goto out_error;
+ }
+
+ if (!fit_check_format(fit_hdr)) {
+ printf("Error! Bad FIT image format\n");
+ goto out_error;
+ }
+
+ node_offset = fit_image_get_node(fit_hdr, uname);
+ if (node_offset < 0) {
+ printf("Error! Can not find %s subimage\n", uname);
+ goto out_error;
+ }
+
+ /* Verify Debug Server firmware image */
+ if (!fit_image_verify(fit_hdr, node_offset)) {
+ printf("Error! Bad Debug Server firmware hash");
+ goto out_error;
+ }
+
+ if (fit_get_desc(fit_hdr, node_offset, &desc) < 0) {
+ printf("Error! Failed to get Debug Server fw description");
+ goto out_error;
+ }
+
+ debug_server_ver_info = strstr(desc, "Version");
+ debug_server_ver_info_major = strtok(debug_server_ver_info, ".");
+ debug_server_ver_info_minor = strtok(NULL, ".");
+
+ debug_server_ver_info_maj =
+ simple_strtoul(debug_server_ver_info_major, NULL, 10);
+ debug_server_ver_info_min =
+ simple_strtoul(debug_server_ver_info_minor, NULL, 10);
+
+ /* Debug server version checking */
+ if ((debug_server_ver_info_maj < DEBUG_SERVER_VER_MAJOR) ||
+ (debug_server_ver_info_min < DEBUG_SERVER_VER_MINOR)) {
+ printf("Debug server FW mismatches the min version required\n");
+ printf("Expected:%d.%d, Got %d.%d\n",
+ DEBUG_SERVER_VER_MAJOR, DEBUG_SERVER_VER_MINOR,
+ debug_server_ver_info_maj,
+ debug_server_ver_info_min);
+ goto out_error;
+ }
+
+ /* Get address and size of raw image */
+ fit_image_get_data(fit_hdr, node_offset, &data, &size);
+
+ *raw_image_addr = data;
+ *raw_image_size = size;
+
+ return 0;
+
+out_error:
+ return -1;
+}
+
+/**
+ * Return the actual size of the Debug Server private DRAM block.
+ *
+ * NOTE: For now this function always returns the minimum required size,
+ * However, in the future, the actual size may be obtained from an environment
+ * variable.
+ */
+unsigned long debug_server_get_dram_block_size(void)
+{
+ return CONFIG_SYS_DEBUG_SERVER_DRAM_BLOCK_MIN_SIZE;
+}
+
+int debug_server_init(void)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ int error, timeout = CONFIG_SYS_DEBUG_SERVER_TIMEOUT;
+ int debug_server_boot_status;
+ u64 debug_server_ram_addr, debug_server_ram_size;
+ const void *raw_image_addr;
+ size_t raw_image_size = 0;
+
+ debug("debug_server_init called\n");
+ /*
+ * The Debug Server private DRAM block was already carved@the end of
+ * DRAM by board_init_f() using CONFIG_SYS_MEM_TOP_HIDE:
+ */
+ debug_server_ram_size = debug_server_get_dram_block_size();
+ if (gd->bd->bi_dram[1].start)
+ debug_server_ram_addr =
+ gd->bd->bi_dram[1].start + gd->bd->bi_dram[1].size;
+ else
+ debug_server_ram_addr =
+ gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size;
+
+ error = debug_server_parse_firmware_fit_image(&raw_image_addr,
+ &raw_image_size);
+ if (error != 0)
+ goto out;
+
+ debug("debug server (ram addr = 0x%llx, ram size = 0x%llx)\n",
+ debug_server_ram_addr, debug_server_ram_size);
+ /*
+ * Load the Debug Server FW at the beginning of the Debug Server
+ * private DRAM block:
+ */
+ debug_server_copy_image("Debug Server Firmware",
+ (u64)raw_image_addr, raw_image_size,
+ debug_server_ram_addr);
+
+ /* flush dcache */
+ flush_dcache_range((unsigned long)debug_server_ram_addr,
+ (unsigned long)debug_server_ram_addr +
+ (unsigned long)debug_server_ram_size);
+
+ /*
+ * Tell SP that the Debug Server FW is about to be launched. Before that
+ * populate the following:
+ * 1. Write the size allocated to SP Memory region into Bits {31:16} of
+ * SCRATCHRW5.
+ * 2. Write the start address of the SP memory regions into
+ * SCRATCHRW5 (Bits {15:0}, contain most significant bits, Bits
+ * {47:32} of the SP Memory Region physical start address
+ * (SoC address)) and SCRATCHRW6 (Bits {31:0}).
+ * 3. To know the Debug Server FW boot status, set bit 0 of SCRATCHRW11
+ * to 1. The Debug Server sets this to 0 to indicate a
+ * successul boot.
+ * 4. Wakeup SP by writing 0x1F to VSG GIC reg VIGR2.
+ */
+
+ /* 512 MB */
+ out_le32(&gur->scratchrw[5 - 1],
+ (u32)((u64)debug_server_ram_addr >> 32) | (0x000D << 16));
+ out_le32(&gur->scratchrw[6 - 1],
+ ((u32)debug_server_ram_addr) & 0xFFFFFFFF);
+
+ out_le32(&gur->scratchrw[11 - 1], DEBUG_SERVER_INIT_STATUS);
+ /* Allow the changes to reflect in GUR block */
+ mb();
+
+ /*
+ * Program VGIC to raise an interrupt to SP
+ */
+ out_le32(CONFIG_SYS_FSL_SP_VSG_GIC_VIGR2, 0x1F);
+ /* Allow the changes to reflect in VIGR2 */
+ mb();
+
+ dmb();
+ debug("Polling for Debug server to launch ...\n");
+
+ while (1) {
+ debug_server_boot_status = in_le32(&gur->scratchrw[11 - 1]);
+ if (!(debug_server_boot_status & DEBUG_SERVER_INIT_STATUS_MASK))
+ break;
+
+ udelay(1); /* throttle polling */
+ if (timeout-- <= 0)
+ break;
+ }
+
+ if (timeout <= 0) {
+ printf("Debug Server FW timed out (boot status: 0x%x)\n",
+ debug_server_boot_status);
+ error = -ETIMEDOUT;
+ goto out;
+ }
+
+ if (debug_server_boot_status & DEBUG_SERVER_INIT_STATUS_MASK) {
+ printf("Debug server FW error'ed out (boot status: 0x%x)\n",
+ debug_server_boot_status);
+ error = -ENODEV;
+ goto out;
+ }
+
+ printf("Debug server booted\n");
+ printf("Detected firmware %d.%d, (boot status: 0x0%x)\n",
+ debug_server_ver_info_maj, debug_server_ver_info_min,
+ debug_server_boot_status);
+
+out:
+ if (error != 0)
+ debug_server_boot_status = -error;
+ else
+ debug_server_boot_status = 0;
+
+ return debug_server_boot_status;
+}
+
diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c
index 74b0085..76581cb 100644
--- a/drivers/net/fsl-mc/mc.c
+++ b/drivers/net/fsl-mc/mc.c
@@ -9,6 +9,7 @@
#include <fsl-mc/fsl_mc.h>
#include <fsl-mc/fsl_mc_sys.h>
#include <fsl-mc/fsl_dpmng.h>
+#include <fsl_debug_server.h>
DECLARE_GLOBAL_DATA_PTR;
static int mc_boot_status;
@@ -112,6 +113,9 @@ int mc_init(bd_t *bis)
gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size;
}
+#ifdef CONFIG_FSL_DEBUG_SERVER
+ mc_ram_addr -= debug_server_get_dram_block_size();
+#endif
/*
* Management Complex cores should be held at reset out of POR.
* U-boot should be the first software to touch MC. To be safe,
diff --git a/include/configs/ls2085a_common.h b/include/configs/ls2085a_common.h
index f80efed..c70ba70 100644
--- a/include/configs/ls2085a_common.h
+++ b/include/configs/ls2085a_common.h
@@ -19,6 +19,9 @@
#define CONFIG_ARM_ERRATA_828024
#define CONFIG_ARM_ERRATA_826974
+/* We need architecture specific misc initializations */
+#define CONFIG_ARCH_MISC_INIT
+
/* Link Definitions */
#define CONFIG_SYS_TEXT_BASE 0x30001000
@@ -206,6 +209,14 @@
#define CONFIG_SYS_CS0_FTIM2 CONFIG_SYS_NOR_FTIM2
#define CONFIG_SYS_CS0_FTIM3 CONFIG_SYS_NOR_FTIM3
+/* Debug Server firmware */
+#define CONFIG_FSL_DEBUG_SERVER
+#define CONFIG_SYS_DEBUG_SERVER_DRAM_BLOCK_MIN_SIZE (512UL * 1024 * 1024)
+#define CONFIG_SYS_DEBUG_SERVER_FW_IN_NOR
+#define CONFIG_SYS_DEBUG_SERVER_FW_ADDR 0x580C00000ULL
+/* 2 sec timeout */
+#define CONFIG_SYS_DEBUG_SERVER_TIMEOUT (2 * 1000 * 1000)
+
/* MC firmware */
#define CONFIG_FSL_MC_ENET
#define CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE (512UL * 1024 * 1024)
@@ -217,9 +228,9 @@
#define CONFIG_SYS_LS_MC_DPL_MAX_LENGTH (256 * 1024)
#define CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET 0xe00000
-/* Carve the MC private DRAM block from the end of DRAM */
-#ifdef CONFIG_FSL_MC_ENET
-#define CONFIG_SYS_MEM_TOP_HIDE mc_get_dram_block_size()
+/* Carve out a DDR region which will not be used by u-boot/Linux */
+#if defined(CONFIG_FSL_MC_ENET) || defined(CONFIG_FSL_DEBUG_SERVER)
+#define CONFIG_SYS_MEM_TOP_HIDE get_dram_size_to_hide()
#endif
/* Command line configuration */
@@ -251,7 +262,6 @@
#define CONFIG_SYS_CLK_FREQ 100000000
#define CONFIG_DDR_CLK_FREQ 133333333
-
#define CONFIG_NR_DRAM_BANKS 3
#define CONFIG_HWCONFIG
@@ -298,7 +308,7 @@
#define CONFIG_SYS_MAXARGS 64 /* max command args */
#ifndef __ASSEMBLY__
-unsigned long mc_get_dram_block_size(void);
+unsigned long get_dram_size_to_hide(void);
#endif
#endif /* __LS2_COMMON_H */
diff --git a/include/fsl-mc/fsl_mc.h b/include/fsl-mc/fsl_mc.h
index b9f089e..28d5961 100644
--- a/include/fsl-mc/fsl_mc.h
+++ b/include/fsl-mc/fsl_mc.h
@@ -56,4 +56,5 @@ struct mc_ccsr_registers {
int mc_init(bd_t *bis);
int get_mc_boot_status(void);
+unsigned long mc_get_dram_block_size(void);
#endif
diff --git a/include/fsl_debug_server.h b/include/fsl_debug_server.h
new file mode 100644
index 0000000..28d8adb
--- /dev/null
+++ b/include/fsl_debug_server.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __FSL_DBG_SERVER_H__
+#define __FSL_DBG_SERVER_H__
+
+#include <asm/io.h>
+#include <common.h>
+
+/*
+ * Define Debug Server firmware version information
+ */
+
+/* Major version number: incremented on API compatibility changes */
+#define DEBUG_SERVER_VER_MAJOR 0
+
+/* Minor version number: incremented on API additions (backward
+ * compatible); reset when major version is incremented.
+ */
+#define DEBUG_SERVER_VER_MINOR 1
+
+#define DEBUG_SERVER_INIT_STATUS (1 << 0)
+#define DEBUG_SERVER_INIT_STATUS_MASK (0x00000001)
+
+int debug_server_init(void);
+unsigned long debug_server_get_dram_block_size(void);
+
+#endif /* __FSL_DBG_SERVER_H__ */
+
--
1.7.9.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH 2/8] fsl-ch3/README: Add description for NOR flash layout (firmware images)
2015-03-19 16:20 [U-Boot] [PATCH 1/8] armv8/fsl-lsch3: Add Freescale Debug Server driver York Sun
@ 2015-03-19 16:20 ` York Sun
2015-03-19 16:20 ` [U-Boot] [PATCH 3/8] driver/fsl-mc: Add support of MC Flibs York Sun
` (6 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: York Sun @ 2015-03-19 16:20 UTC (permalink / raw)
To: u-boot
From: Bhupesh Sharma <bhupesh.sharma@freescale.com>
This patch adds description for NOR flash layout (firmware images)
in the README file for LS2085A platforms.
Signed-off-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
---
arch/arm/cpu/armv8/fsl-lsch3/README | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/arch/arm/cpu/armv8/fsl-lsch3/README b/arch/arm/cpu/armv8/fsl-lsch3/README
index cc47466..99fc39a 100644
--- a/arch/arm/cpu/armv8/fsl-lsch3/README
+++ b/arch/arm/cpu/armv8/fsl-lsch3/README
@@ -8,3 +8,28 @@ Freescale LayerScape with Chassis Generation 3
This architecture supports Freescale ARMv8 SoCs with Chassis generation 3,
for example LS2085A.
+
+Flash Layout
+============
+A typical layout of various images (including Linux and other firmware images)
+is shown below considering a 32MB NOR flash device:
+
+ -------------------------
+ | linux |
+ ------------------------- ----> 0x0120_0000
+ | Debug Server |
+ ------------------------- ----> 0x00C0_0000
+ | AIOP SW |
+ ------------------------- ----> 0x0070_0000
+ | MC FW |
+ ------------------------- ----> 0x006C_0000
+ | MC Data Path Layout |
+ ------------------------- ----> 0x0020_0000
+ | BootLoader |
+ ------------------------- ----> 0x0000_1000
+ | PBI |
+ ------------------------- ----> 0x0000_0080
+ | RCW |
+ ------------------------- ----> 0x0000_0000
+
+ 32-MB NOR flash layout
--
1.7.9.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH 3/8] driver/fsl-mc: Add support of MC Flibs
2015-03-19 16:20 [U-Boot] [PATCH 1/8] armv8/fsl-lsch3: Add Freescale Debug Server driver York Sun
2015-03-19 16:20 ` [U-Boot] [PATCH 2/8] fsl-ch3/README: Add description for NOR flash layout (firmware images) York Sun
@ 2015-03-19 16:20 ` York Sun
2015-03-19 16:20 ` [U-Boot] [PATCH 4/8] driver/ldpaa_eth: Add LDPAA Ethernet driver York Sun
` (5 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: York Sun @ 2015-03-19 16:20 UTC (permalink / raw)
To: u-boot
From: Prabhakar Kushwaha <prabhakar@freescale.com>
Freescale's Layerscape Management Complex (MC) provide support various
objects like DPRC, DPNI, DPBP and DPIO.
Where:
DPRC: Place holdes for other MC objectes like DPNI, DPBP, DPIO
DPBP: Management of buffer pool
DPIO: Used for used to QBMan portal
DPNI: Represents standard network interface
These objects are used for DPAA ethernet drivers.
Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
Signed-off-by: Lijun Pan <Lijun.Pan@freescale.com>
Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
Signed-off-by: Geoff Thorpe <Geoff.Thorpe@freescale.com>
Signed-off-by: Haiying Wang <Haiying.Wang@freescale.com>
Signed-off-by: Cristian Sovaiala <cristian.sovaiala@freescale.com>
Signed-off-by: pankaj chauhan <pankaj.chauhan@freescale.com>
Signed-off-by: Prabhakar Kushwaha <prabhakar@freescale.com>
---
arch/arm/cpu/armv8/fsl-lsch3/cpu.c | 2 +-
arch/arm/include/asm/arch-fsl-lsch3/config.h | 2 +
board/freescale/ls2085a/ls2085a.c | 1 +
drivers/net/fsl-mc/Makefile | 6 +-
drivers/net/fsl-mc/dpbp.c | 102 +++
drivers/net/fsl-mc/{ => dpio}/Makefile | 7 +-
drivers/net/fsl-mc/dpio/dpio.c | 102 +++
drivers/net/fsl-mc/dpio/qbman_portal.c | 593 ++++++++++++++
drivers/net/fsl-mc/dpio/qbman_portal.h | 157 ++++
drivers/net/fsl-mc/dpio/qbman_private.h | 169 ++++
drivers/net/fsl-mc/dpio/qbman_sys.h | 290 +++++++
drivers/net/fsl-mc/dpmng.c | 65 +-
drivers/net/fsl-mc/dpni.c | 506 ++++++++++++
drivers/net/fsl-mc/dprc.c | 283 +++++++
drivers/net/fsl-mc/fsl_dpmng_cmd.h | 32 +-
drivers/net/fsl-mc/mc.c | 230 +++++-
drivers/net/fsl-mc/mc_sys.c | 6 +-
include/fsl-mc/fsl_dpaa_fd.h | 121 +++
include/fsl-mc/fsl_dpbp.h | 143 ++++
include/fsl-mc/fsl_dpio.h | 163 ++++
include/fsl-mc/fsl_dpmng.h | 113 +--
include/fsl-mc/fsl_dpni.h | 1093 ++++++++++++++++++++++++++
include/fsl-mc/fsl_dprc.h | 659 ++++++++++++++++
include/fsl-mc/fsl_mc.h | 4 +-
include/fsl-mc/fsl_mc_cmd.h | 17 +-
include/fsl-mc/fsl_mc_private.h | 48 ++
include/fsl-mc/fsl_qbman_base.h | 87 ++
include/fsl-mc/fsl_qbman_portal.h | 175 +++++
28 files changed, 4961 insertions(+), 215 deletions(-)
create mode 100644 drivers/net/fsl-mc/dpbp.c
copy drivers/net/fsl-mc/{ => dpio}/Makefile (59%)
create mode 100644 drivers/net/fsl-mc/dpio/dpio.c
create mode 100644 drivers/net/fsl-mc/dpio/qbman_portal.c
create mode 100644 drivers/net/fsl-mc/dpio/qbman_portal.h
create mode 100644 drivers/net/fsl-mc/dpio/qbman_private.h
create mode 100644 drivers/net/fsl-mc/dpio/qbman_sys.h
create mode 100644 drivers/net/fsl-mc/dpni.c
create mode 100644 drivers/net/fsl-mc/dprc.c
create mode 100644 include/fsl-mc/fsl_dpaa_fd.h
create mode 100644 include/fsl-mc/fsl_dpbp.h
create mode 100644 include/fsl-mc/fsl_dpio.h
create mode 100644 include/fsl-mc/fsl_dpni.h
create mode 100644 include/fsl-mc/fsl_dprc.h
create mode 100644 include/fsl-mc/fsl_mc_private.h
create mode 100644 include/fsl-mc/fsl_qbman_base.h
create mode 100644 include/fsl-mc/fsl_qbman_portal.h
diff --git a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c
index 618fbc2..94fd147 100644
--- a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c
+++ b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c
@@ -380,7 +380,7 @@ int cpu_eth_init(bd_t *bis)
int error = 0;
#ifdef CONFIG_FSL_MC_ENET
- error = mc_init(bis);
+ error = fsl_mc_ldpaa_init(bis);
#endif
return error;
}
diff --git a/arch/arm/include/asm/arch-fsl-lsch3/config.h b/arch/arm/include/asm/arch-fsl-lsch3/config.h
index 59d10bf..0217582 100644
--- a/arch/arm/include/asm/arch-fsl-lsch3/config.h
+++ b/arch/arm/include/asm/arch-fsl-lsch3/config.h
@@ -8,6 +8,8 @@
#define _ASM_ARMV8_FSL_LSCH3_CONFIG_
#include <fsl_ddrc_version.h>
+
+#define CONFIG_SYS_PAGE_SIZE 0x10000
#define CONFIG_MP
#define CONFIG_SYS_FSL_OCRAM_BASE 0x18000000 /* initial RAM */
/* Link Definitions */
diff --git a/board/freescale/ls2085a/ls2085a.c b/board/freescale/ls2085a/ls2085a.c
index a16c2c8..e78c63a 100644
--- a/board/freescale/ls2085a/ls2085a.c
+++ b/board/freescale/ls2085a/ls2085a.c
@@ -164,6 +164,7 @@ int ft_board_setup(void *blob, bd_t *bd)
#ifdef CONFIG_FSL_MC_ENET
fdt_fixup_board_enet(blob);
+ fsl_mc_ldpaa_exit(bd);
#endif
return 0;
diff --git a/drivers/net/fsl-mc/Makefile b/drivers/net/fsl-mc/Makefile
index 206ac6b..7563a5f 100644
--- a/drivers/net/fsl-mc/Makefile
+++ b/drivers/net/fsl-mc/Makefile
@@ -7,4 +7,8 @@
# Layerscape MC driver
obj-y += mc.o \
mc_sys.o \
- dpmng.o
+ dpmng.o \
+ dprc.o \
+ dpbp.o \
+ dpni.o
+obj-y += dpio/
diff --git a/drivers/net/fsl-mc/dpbp.c b/drivers/net/fsl-mc/dpbp.c
new file mode 100644
index 0000000..3853e58
--- /dev/null
+++ b/drivers/net/fsl-mc/dpbp.c
@@ -0,0 +1,102 @@
+/*
+ * Freescale Layerscape MC I/O wrapper
+ *
+ * Copyright (C) 2013-2015 Freescale Semiconductor, Inc.
+ * Author: German Rivera <German.Rivera@freescale.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <fsl-mc/fsl_mc_sys.h>
+#include <fsl-mc/fsl_mc_cmd.h>
+#include <fsl-mc/fsl_dpbp.h>
+
+int dpbp_open(struct fsl_mc_io *mc_io, int dpbp_id, uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_OPEN,
+ MC_CMD_PRI_LOW, 0);
+ DPBP_CMD_OPEN(cmd, dpbp_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return err;
+}
+
+int dpbp_close(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_CLOSE, MC_CMD_PRI_HIGH,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpbp_enable(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_ENABLE, MC_CMD_PRI_LOW,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpbp_disable(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_DISABLE,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpbp_reset(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_RESET,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpbp_get_attributes(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpbp_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_ATTR,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPBP_RSP_GET_ATTRIBUTES(cmd, attr);
+
+ return 0;
+}
diff --git a/drivers/net/fsl-mc/Makefile b/drivers/net/fsl-mc/dpio/Makefile
similarity index 59%
copy from drivers/net/fsl-mc/Makefile
copy to drivers/net/fsl-mc/dpio/Makefile
index 206ac6b..1ccefc0 100644
--- a/drivers/net/fsl-mc/Makefile
+++ b/drivers/net/fsl-mc/dpio/Makefile
@@ -4,7 +4,6 @@
# SPDX-License-Identifier: GPL-2.0+
#
-# Layerscape MC driver
-obj-y += mc.o \
- mc_sys.o \
- dpmng.o
+# Layerscape MC DPIO driver
+obj-y += dpio.o \
+ qbman_portal.o
diff --git a/drivers/net/fsl-mc/dpio/dpio.c b/drivers/net/fsl-mc/dpio/dpio.c
new file mode 100644
index 0000000..b07eff7
--- /dev/null
+++ b/drivers/net/fsl-mc/dpio/dpio.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2013-2015 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <fsl-mc/fsl_mc_sys.h>
+#include <fsl-mc/fsl_mc_cmd.h>
+#include <fsl-mc/fsl_dpio.h>
+
+int dpio_open(struct fsl_mc_io *mc_io, int dpio_id, uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_OPEN,
+ MC_CMD_PRI_LOW, 0);
+ DPIO_CMD_OPEN(cmd, dpio_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return 0;
+}
+
+int dpio_close(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_CLOSE,
+ MC_CMD_PRI_HIGH, token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_enable(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_ENABLE,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_disable(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_DISABLE,
+ MC_CMD_PRI_LOW,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_reset(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_RESET,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_get_attributes(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpio_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_ATTR,
+ MC_CMD_PRI_LOW,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPIO_RSP_GET_ATTR(cmd, attr);
+
+ return 0;
+}
diff --git a/drivers/net/fsl-mc/dpio/qbman_portal.c b/drivers/net/fsl-mc/dpio/qbman_portal.c
new file mode 100644
index 0000000..dd2a7de
--- /dev/null
+++ b/drivers/net/fsl-mc/dpio/qbman_portal.c
@@ -0,0 +1,593 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "qbman_portal.h"
+
+/* QBMan portal management command codes */
+#define QBMAN_MC_ACQUIRE 0x30
+#define QBMAN_WQCHAN_CONFIGURE 0x46
+
+/* CINH register offsets */
+#define QBMAN_CINH_SWP_EQAR 0x8c0
+#define QBMAN_CINH_SWP_DCAP 0xac0
+#define QBMAN_CINH_SWP_SDQCR 0xb00
+#define QBMAN_CINH_SWP_RAR 0xcc0
+
+/* CENA register offsets */
+#define QBMAN_CENA_SWP_EQCR(n) (0x000 + ((uint32_t)(n) << 6))
+#define QBMAN_CENA_SWP_DQRR(n) (0x200 + ((uint32_t)(n) << 6))
+#define QBMAN_CENA_SWP_RCR(n) (0x400 + ((uint32_t)(n) << 6))
+#define QBMAN_CENA_SWP_CR 0x600
+#define QBMAN_CENA_SWP_RR(vb) (0x700 + ((uint32_t)(vb) >> 1))
+#define QBMAN_CENA_SWP_VDQCR 0x780
+
+/* Reverse mapping of QBMAN_CENA_SWP_DQRR() */
+#define QBMAN_IDX_FROM_DQRR(p) (((unsigned long)p & 0xff) >> 6)
+
+/*******************************/
+/* Pre-defined attribute codes */
+/*******************************/
+
+struct qb_attr_code code_generic_verb = QB_CODE(0, 0, 7);
+struct qb_attr_code code_generic_rslt = QB_CODE(0, 8, 8);
+
+/*************************/
+/* SDQCR attribute codes */
+/*************************/
+
+/* we put these here because at least some of them are required by
+ * qbman_swp_init() */
+struct qb_attr_code code_sdqcr_dct = QB_CODE(0, 24, 2);
+struct qb_attr_code code_sdqcr_fc = QB_CODE(0, 29, 1);
+struct qb_attr_code code_sdqcr_tok = QB_CODE(0, 16, 8);
+#define CODE_SDQCR_DQSRC(n) QB_CODE(0, n, 1)
+enum qbman_sdqcr_dct {
+ qbman_sdqcr_dct_null = 0,
+ qbman_sdqcr_dct_prio_ics,
+ qbman_sdqcr_dct_active_ics,
+ qbman_sdqcr_dct_active
+};
+enum qbman_sdqcr_fc {
+ qbman_sdqcr_fc_one = 0,
+ qbman_sdqcr_fc_up_to_3 = 1
+};
+
+/*********************************/
+/* Portal constructor/destructor */
+/*********************************/
+
+/* Software portals should always be in the power-on state when we initialise,
+ * due to the CCSR-based portal reset functionality that MC has. */
+struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
+{
+ int ret;
+ struct qbman_swp *p = kmalloc(sizeof(*p), GFP_KERNEL);
+
+ if (!p)
+ return NULL;
+ p->desc = d;
+#ifdef QBMAN_CHECKING
+ p->mc.check = swp_mc_can_start;
+#endif
+ p->mc.valid_bit = QB_VALID_BIT;
+ p->sdq = 0;
+ qb_attr_code_encode(&code_sdqcr_dct, &p->sdq, qbman_sdqcr_dct_prio_ics);
+ qb_attr_code_encode(&code_sdqcr_fc, &p->sdq, qbman_sdqcr_fc_up_to_3);
+ qb_attr_code_encode(&code_sdqcr_tok, &p->sdq, 0xbb);
+ p->vdq.busy = 0; /* TODO: convert to atomic_t */
+ p->vdq.valid_bit = QB_VALID_BIT;
+ p->dqrr.next_idx = 0;
+ p->dqrr.valid_bit = QB_VALID_BIT;
+ ret = qbman_swp_sys_init(&p->sys, d);
+ if (ret) {
+ free(p);
+ printf("qbman_swp_sys_init() failed %d\n", ret);
+ return NULL;
+ }
+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_SDQCR, p->sdq);
+ return p;
+}
+
+/***********************/
+/* Management commands */
+/***********************/
+
+/*
+ * Internal code common to all types of management commands.
+ */
+
+void *qbman_swp_mc_start(struct qbman_swp *p)
+{
+ void *ret;
+#ifdef QBMAN_CHECKING
+ BUG_ON(p->mc.check != swp_mc_can_start);
+#endif
+ ret = qbman_cena_write_start(&p->sys, QBMAN_CENA_SWP_CR);
+#ifdef QBMAN_CHECKING
+ if (!ret)
+ p->mc.check = swp_mc_can_submit;
+#endif
+ return ret;
+}
+
+void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, uint32_t cmd_verb)
+{
+ uint32_t *v = cmd;
+#ifdef QBMAN_CHECKING
+ BUG_ON(!p->mc.check != swp_mc_can_submit);
+#endif
+ lwsync();
+ /* TBD: "|=" is going to hurt performance. Need to move as many fields
+ * out of word zero, and for those that remain, the "OR" needs to occur
+ * at the caller side. This debug check helps to catch cases where the
+ * caller wants to OR but has forgotten to do so. */
+ BUG_ON((*v & cmd_verb) != *v);
+ *v = cmd_verb | p->mc.valid_bit;
+ qbman_cena_write_complete(&p->sys, QBMAN_CENA_SWP_CR, cmd);
+ /* TODO: add prefetch support for GPP */
+#ifdef QBMAN_CHECKING
+ p->mc.check = swp_mc_can_poll;
+#endif
+}
+
+void *qbman_swp_mc_result(struct qbman_swp *p)
+{
+ uint32_t *ret, verb;
+#ifdef QBMAN_CHECKING
+ BUG_ON(p->mc.check != swp_mc_can_poll);
+#endif
+ ret = qbman_cena_read(&p->sys, QBMAN_CENA_SWP_RR(p->mc.valid_bit));
+ /* Remove the valid-bit - command completed iff the rest is non-zero */
+ verb = ret[0] & ~QB_VALID_BIT;
+ if (!verb)
+ return NULL;
+#ifdef QBMAN_CHECKING
+ p->mc.check = swp_mc_can_start;
+#endif
+ p->mc.valid_bit ^= QB_VALID_BIT;
+ return ret;
+}
+
+/***********/
+/* Enqueue */
+/***********/
+
+/* These should be const, eventually */
+static struct qb_attr_code code_eq_cmd = QB_CODE(0, 0, 2);
+static struct qb_attr_code code_eq_orp_en = QB_CODE(0, 2, 1);
+static struct qb_attr_code code_eq_tgt_id = QB_CODE(2, 0, 24);
+/* static struct qb_attr_code code_eq_tag = QB_CODE(3, 0, 32); */
+static struct qb_attr_code code_eq_qd_en = QB_CODE(0, 4, 1);
+static struct qb_attr_code code_eq_qd_bin = QB_CODE(4, 0, 16);
+static struct qb_attr_code code_eq_qd_pri = QB_CODE(4, 16, 4);
+static struct qb_attr_code code_eq_rsp_stash = QB_CODE(5, 16, 1);
+static struct qb_attr_code code_eq_rsp_lo = QB_CODE(6, 0, 32);
+static struct qb_attr_code code_eq_rsp_hi = QB_CODE(7, 0, 32);
+
+enum qbman_eq_cmd_e {
+ /* No enqueue, primarily for plugging ORP gaps for dropped frames */
+ qbman_eq_cmd_empty,
+ /* DMA an enqueue response once complete */
+ qbman_eq_cmd_respond,
+ /* DMA an enqueue response only if the enqueue fails */
+ qbman_eq_cmd_respond_reject
+};
+
+void qbman_eq_desc_clear(struct qbman_eq_desc *d)
+{
+ memset(d, 0, sizeof(*d));
+}
+
+void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_orp_en, cl, 0);
+ qb_attr_code_encode(&code_eq_cmd, cl,
+ respond_success ? qbman_eq_cmd_respond :
+ qbman_eq_cmd_respond_reject);
+}
+
+void qbman_eq_desc_set_response(struct qbman_eq_desc *d,
+ dma_addr_t storage_phys,
+ int stash)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_rsp_lo, cl, lower32(storage_phys));
+ qb_attr_code_encode(&code_eq_rsp_hi, cl, upper32(storage_phys));
+ qb_attr_code_encode(&code_eq_rsp_stash, cl, !!stash);
+}
+
+
+void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, uint32_t qdid,
+ uint32_t qd_bin, uint32_t qd_prio)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_qd_en, cl, 1);
+ qb_attr_code_encode(&code_eq_tgt_id, cl, qdid);
+ qb_attr_code_encode(&code_eq_qd_bin, cl, qd_bin);
+ qb_attr_code_encode(&code_eq_qd_pri, cl, qd_prio);
+}
+
+#define EQAR_IDX(eqar) ((eqar) & 0x7)
+#define EQAR_VB(eqar) ((eqar) & 0x80)
+#define EQAR_SUCCESS(eqar) ((eqar) & 0x100)
+
+int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd)
+{
+ uint32_t *p;
+ const uint32_t *cl = qb_cl(d);
+ uint32_t eqar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_EQAR);
+ debug("EQAR=%08x\n", eqar);
+ if (!EQAR_SUCCESS(eqar))
+ return -EBUSY;
+ p = qbman_cena_write_start(&s->sys,
+ QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));
+ word_copy(&p[1], &cl[1], 7);
+ word_copy(&p[8], fd, sizeof(*fd) >> 2);
+ lwsync();
+ /* Set the verb byte, have to substitute in the valid-bit */
+ p[0] = cl[0] | EQAR_VB(eqar);
+ qbman_cena_write_complete(&s->sys,
+ QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)),
+ p);
+ return 0;
+}
+
+/***************************/
+/* Volatile (pull) dequeue */
+/***************************/
+
+/* These should be const, eventually */
+static struct qb_attr_code code_pull_dct = QB_CODE(0, 0, 2);
+static struct qb_attr_code code_pull_dt = QB_CODE(0, 2, 2);
+static struct qb_attr_code code_pull_rls = QB_CODE(0, 4, 1);
+static struct qb_attr_code code_pull_stash = QB_CODE(0, 5, 1);
+static struct qb_attr_code code_pull_numframes = QB_CODE(0, 8, 4);
+static struct qb_attr_code code_pull_token = QB_CODE(0, 16, 8);
+static struct qb_attr_code code_pull_dqsource = QB_CODE(1, 0, 24);
+static struct qb_attr_code code_pull_rsp_lo = QB_CODE(2, 0, 32);
+static struct qb_attr_code code_pull_rsp_hi = QB_CODE(3, 0, 32);
+
+enum qb_pull_dt_e {
+ qb_pull_dt_channel,
+ qb_pull_dt_workqueue,
+ qb_pull_dt_framequeue
+};
+
+void qbman_pull_desc_clear(struct qbman_pull_desc *d)
+{
+ memset(d, 0, sizeof(*d));
+}
+
+void qbman_pull_desc_set_storage(struct qbman_pull_desc *d,
+ struct ldpaa_dq *storage,
+ dma_addr_t storage_phys,
+ int stash)
+{
+ uint32_t *cl = qb_cl(d);
+
+ /* Squiggle the pointer 'storage' into the extra 2 words of the
+ * descriptor (which aren't copied to the hw command) */
+ *(void **)&cl[4] = storage;
+ if (!storage) {
+ qb_attr_code_encode(&code_pull_rls, cl, 0);
+ return;
+ }
+ qb_attr_code_encode(&code_pull_rls, cl, 1);
+ qb_attr_code_encode(&code_pull_stash, cl, !!stash);
+ qb_attr_code_encode(&code_pull_rsp_lo, cl, lower32(storage_phys));
+ qb_attr_code_encode(&code_pull_rsp_hi, cl, upper32(storage_phys));
+}
+
+void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d, uint8_t numframes)
+{
+ uint32_t *cl = qb_cl(d);
+
+ BUG_ON(!numframes || (numframes > 16));
+ qb_attr_code_encode(&code_pull_numframes, cl,
+ (uint32_t)(numframes - 1));
+}
+
+void qbman_pull_desc_set_token(struct qbman_pull_desc *d, uint8_t token)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_pull_token, cl, token);
+}
+
+void qbman_pull_desc_set_fq(struct qbman_pull_desc *d, uint32_t fqid)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_pull_dct, cl, 1);
+ qb_attr_code_encode(&code_pull_dt, cl, qb_pull_dt_framequeue);
+ qb_attr_code_encode(&code_pull_dqsource, cl, fqid);
+}
+
+int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d)
+{
+ uint32_t *p;
+ uint32_t *cl = qb_cl(d);
+
+ /* TODO: convert to atomic_t */
+ if (s->vdq.busy)
+ return -EBUSY;
+ s->vdq.busy = 1;
+ s->vdq.storage = *(void **)&cl[4];
+ s->vdq.token = qb_attr_code_decode(&code_pull_token, cl);
+ p = qbman_cena_write_start(&s->sys, QBMAN_CENA_SWP_VDQCR);
+ word_copy(&p[1], &cl[1], 3);
+ lwsync();
+ /* Set the verb byte, have to substitute in the valid-bit */
+ p[0] = cl[0] | s->vdq.valid_bit;
+ s->vdq.valid_bit ^= QB_VALID_BIT;
+ qbman_cena_write_complete(&s->sys, QBMAN_CENA_SWP_VDQCR, p);
+ return 0;
+}
+
+/****************/
+/* Polling DQRR */
+/****************/
+
+static struct qb_attr_code code_dqrr_verb = QB_CODE(0, 0, 8);
+static struct qb_attr_code code_dqrr_response = QB_CODE(0, 0, 7);
+static struct qb_attr_code code_dqrr_stat = QB_CODE(0, 8, 8);
+
+#define QBMAN_DQRR_RESPONSE_DQ 0x60
+#define QBMAN_DQRR_RESPONSE_FQRN 0x21
+#define QBMAN_DQRR_RESPONSE_FQRNI 0x22
+#define QBMAN_DQRR_RESPONSE_FQPN 0x24
+#define QBMAN_DQRR_RESPONSE_FQDAN 0x25
+#define QBMAN_DQRR_RESPONSE_CDAN 0x26
+#define QBMAN_DQRR_RESPONSE_CSCN_MEM 0x27
+#define QBMAN_DQRR_RESPONSE_CGCU 0x28
+#define QBMAN_DQRR_RESPONSE_BPSCN 0x29
+#define QBMAN_DQRR_RESPONSE_CSCN_WQ 0x2a
+
+
+/* NULL return if there are no unconsumed DQRR entries. Returns a DQRR entry
+ * only once, so repeated calls can return a sequence of DQRR entries, without
+ * requiring they be consumed immediately or in any particular order. */
+const struct ldpaa_dq *qbman_swp_dqrr_next(struct qbman_swp *s)
+{
+ uint32_t verb;
+ uint32_t response_verb;
+ const struct ldpaa_dq *dq = qbman_cena_read(&s->sys,
+ QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
+ const uint32_t *p = qb_cl(dq);
+
+ verb = qb_attr_code_decode(&code_dqrr_verb, p);
+ /* If the valid-bit isn't of the expected polarity, nothing there */
+ if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit) {
+ qbman_cena_invalidate_prefetch(&s->sys,
+ QBMAN_CENA_SWP_DQRR(
+ s->dqrr.next_idx));
+ return NULL;
+ }
+ /* There's something there. Move "next_idx" attention to the next ring
+ * entry (and prefetch it) before returning what we found. */
+ s->dqrr.next_idx++;
+ s->dqrr.next_idx &= 3; /* Wrap around at 4 */
+ /* TODO: it's possible to do all this without conditionals, optimise it
+ * later. */
+ if (!s->dqrr.next_idx)
+ s->dqrr.valid_bit ^= QB_VALID_BIT;
+ /* VDQCR "no longer busy" hook - if VDQCR shows "busy" and this is a
+ * VDQCR result, mark it as non-busy. */
+ if (s->vdq.busy) {
+ uint32_t flags = ldpaa_dq_flags(dq);
+
+ response_verb = qb_attr_code_decode(&code_dqrr_response, &verb);
+ if ((response_verb == QBMAN_DQRR_RESPONSE_DQ) &&
+ (flags & LDPAA_DQ_STAT_VOLATILE))
+ s->vdq.busy = 0;
+ }
+ qbman_cena_invalidate_prefetch(&s->sys,
+ QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
+ return dq;
+}
+
+/* Consume DQRR entries previously returned from qbman_swp_dqrr_next(). */
+void qbman_swp_dqrr_consume(struct qbman_swp *s, const struct ldpaa_dq *dq)
+{
+ qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_DCAP, QBMAN_IDX_FROM_DQRR(dq));
+}
+
+/*********************************/
+/* Polling user-provided storage */
+/*********************************/
+
+void qbman_dq_entry_set_oldtoken(struct ldpaa_dq *dq,
+ unsigned int num_entries,
+ uint8_t oldtoken)
+{
+ memset(dq, oldtoken, num_entries * sizeof(*dq));
+}
+
+int qbman_dq_entry_has_newtoken(struct qbman_swp *s,
+ const struct ldpaa_dq *dq,
+ uint8_t newtoken)
+{
+ /* To avoid converting the little-endian DQ entry to host-endian prior
+ * to us knowing whether there is a valid entry or not (and run the
+ * risk of corrupting the incoming hardware LE write), we detect in
+ * hardware endianness rather than host. This means we need a different
+ * "code" depending on whether we are BE or LE in software, which is
+ * where DQRR_TOK_OFFSET comes in... */
+ static struct qb_attr_code code_dqrr_tok_detect =
+ QB_CODE(0, DQRR_TOK_OFFSET, 8);
+ /* The user trying to poll for a result treats "dq" as const. It is
+ * however the same address that was provided to us non-const in the
+ * first place, for directing hardware DMA to. So we can cast away the
+ * const because it is mutable from our perspective. */
+ uint32_t *p = qb_cl((struct ldpaa_dq *)dq);
+ uint32_t token;
+
+ token = qb_attr_code_decode(&code_dqrr_tok_detect, &p[1]);
+ if (token != newtoken)
+ return 0;
+
+ /* Only now do we convert from hardware to host endianness. Also, as we
+ * are returning success, the user has promised not to call us again, so
+ * there's no risk of us converting the endianness twice... */
+ make_le32_n(p, 16);
+
+ /* VDQCR "no longer busy" hook - not quite the same as DQRR, because the
+ * fact "VDQCR" shows busy doesn't mean that the result we're looking at
+ * is from the same command. Eg. we may be looking at our 10th dequeue
+ * result from our first VDQCR command, yet the second dequeue command
+ * could have been kicked off already, after seeing the 1st result. Ie.
+ * the result we're looking at is not necessarily proof that we can
+ * reset "busy". We instead base the decision on whether the current
+ * result is sitting at the first 'storage' location of the busy
+ * command. */
+ if (s->vdq.busy && (s->vdq.storage == dq))
+ s->vdq.busy = 0;
+ return 1;
+}
+
+/********************************/
+/* Categorising dequeue entries */
+/********************************/
+
+static inline int __qbman_dq_entry_is_x(const struct ldpaa_dq *dq, uint32_t x)
+{
+ const uint32_t *p = qb_cl(dq);
+ uint32_t response_verb = qb_attr_code_decode(&code_dqrr_response, p);
+
+ return response_verb == x;
+}
+
+int qbman_dq_entry_is_DQ(const struct ldpaa_dq *dq)
+{
+ return __qbman_dq_entry_is_x(dq, QBMAN_DQRR_RESPONSE_DQ);
+}
+
+/*********************************/
+/* Parsing frame dequeue results */
+/*********************************/
+
+/* These APIs assume qbman_dq_entry_is_DQ() is TRUE */
+
+uint32_t ldpaa_dq_flags(const struct ldpaa_dq *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return qb_attr_code_decode(&code_dqrr_stat, p);
+}
+
+const struct dpaa_fd *ldpaa_dq_fd(const struct ldpaa_dq *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return (const struct dpaa_fd *)&p[8];
+}
+
+/******************/
+/* Buffer release */
+/******************/
+
+/* These should be const, eventually */
+/* static struct qb_attr_code code_release_num = QB_CODE(0, 0, 3); */
+static struct qb_attr_code code_release_set_me = QB_CODE(0, 5, 1);
+static struct qb_attr_code code_release_bpid = QB_CODE(0, 16, 16);
+
+void qbman_release_desc_clear(struct qbman_release_desc *d)
+{
+ uint32_t *cl;
+
+ memset(d, 0, sizeof(*d));
+ cl = qb_cl(d);
+ qb_attr_code_encode(&code_release_set_me, cl, 1);
+}
+
+void qbman_release_desc_set_bpid(struct qbman_release_desc *d, uint32_t bpid)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_release_bpid, cl, bpid);
+}
+
+#define RAR_IDX(rar) ((rar) & 0x7)
+#define RAR_VB(rar) ((rar) & 0x80)
+#define RAR_SUCCESS(rar) ((rar) & 0x100)
+
+int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d,
+ const uint64_t *buffers, unsigned int num_buffers)
+{
+ uint32_t *p;
+ const uint32_t *cl = qb_cl(d);
+ uint32_t rar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_RAR);
+ debug("RAR=%08x\n", rar);
+ if (!RAR_SUCCESS(rar))
+ return -EBUSY;
+ BUG_ON(!num_buffers || (num_buffers > 7));
+ /* Start the release command */
+ p = qbman_cena_write_start(&s->sys,
+ QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));
+ /* Copy the caller's buffer pointers to the command */
+ u64_to_le32_copy(&p[2], buffers, num_buffers);
+ lwsync();
+ /* Set the verb byte, have to substitute in the valid-bit and the number
+ * of buffers. */
+ p[0] = cl[0] | RAR_VB(rar) | num_buffers;
+ qbman_cena_write_complete(&s->sys,
+ QBMAN_CENA_SWP_RCR(RAR_IDX(rar)),
+ p);
+ return 0;
+}
+
+/*******************/
+/* Buffer acquires */
+/*******************/
+
+/* These should be const, eventually */
+static struct qb_attr_code code_acquire_bpid = QB_CODE(0, 16, 16);
+static struct qb_attr_code code_acquire_num = QB_CODE(1, 0, 3);
+static struct qb_attr_code code_acquire_r_num = QB_CODE(1, 0, 3);
+
+int qbman_swp_acquire(struct qbman_swp *s, uint32_t bpid, uint64_t *buffers,
+ unsigned int num_buffers)
+{
+ uint32_t *p;
+ uint32_t verb, rslt, num;
+
+ BUG_ON(!num_buffers || (num_buffers > 7));
+
+ /* Start the management command */
+ p = qbman_swp_mc_start(s);
+
+ if (!p)
+ return -EBUSY;
+
+ /* Encode the caller-provided attributes */
+ qb_attr_code_encode(&code_acquire_bpid, p, bpid);
+ qb_attr_code_encode(&code_acquire_num, p, num_buffers);
+
+ /* Complete the management command */
+ p = qbman_swp_mc_complete(s, p, p[0] | QBMAN_MC_ACQUIRE);
+
+ /* Decode the outcome */
+ verb = qb_attr_code_decode(&code_generic_verb, p);
+ rslt = qb_attr_code_decode(&code_generic_rslt, p);
+ num = qb_attr_code_decode(&code_acquire_r_num, p);
+ BUG_ON(verb != QBMAN_MC_ACQUIRE);
+
+ /* Determine success or failure */
+ if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
+ printf("Acquire buffers from BPID 0x%x failed, code=0x%02x\n",
+ bpid, rslt);
+ return -EIO;
+ }
+ BUG_ON(num > num_buffers);
+ /* Copy the acquired buffers to the caller's array */
+ u64_from_le32_copy(buffers, &p[2], num);
+ return (int)num;
+}
diff --git a/drivers/net/fsl-mc/dpio/qbman_portal.h b/drivers/net/fsl-mc/dpio/qbman_portal.h
new file mode 100644
index 0000000..bb67c3b
--- /dev/null
+++ b/drivers/net/fsl-mc/dpio/qbman_portal.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "qbman_private.h"
+#include <fsl-mc/fsl_qbman_portal.h>
+#include <fsl-mc/fsl_dpaa_fd.h>
+
+/* All QBMan command and result structures use this "valid bit" encoding */
+#define QB_VALID_BIT ((uint32_t)0x80)
+
+/* Management command result codes */
+#define QBMAN_MC_RSLT_OK 0xf0
+
+/* --------------------- */
+/* portal data structure */
+/* --------------------- */
+
+struct qbman_swp {
+ const struct qbman_swp_desc *desc;
+ /* The qbman_sys (ie. arch/OS-specific) support code can put anything it
+ * needs in here. */
+ struct qbman_swp_sys sys;
+ /* Management commands */
+ struct {
+#ifdef QBMAN_CHECKING
+ enum swp_mc_check {
+ swp_mc_can_start, /* call __qbman_swp_mc_start() */
+ swp_mc_can_submit, /* call __qbman_swp_mc_submit() */
+ swp_mc_can_poll, /* call __qbman_swp_mc_result() */
+ } check;
+#endif
+ uint32_t valid_bit; /* 0x00 or 0x80 */
+ } mc;
+ /* Push dequeues */
+ uint32_t sdq;
+ /* Volatile dequeues */
+ struct {
+ /* VDQCR supports a "1 deep pipeline", meaning that if you know
+ * the last-submitted command is already executing in the
+ * hardware (as evidenced by at least 1 valid dequeue result),
+ * you can write another dequeue command to the register, the
+ * hardware will start executing it as soon as the
+ * already-executing command terminates. (This minimises latency
+ * and stalls.) With that in mind, this "busy" variable refers
+ * to whether or not a command can be submitted, not whether or
+ * not a previously-submitted command is still executing. In
+ * other words, once proof is seen that the previously-submitted
+ * command is executing, "vdq" is no longer "busy". TODO:
+ * convert this to "atomic_t" so that it is thread-safe (without
+ * locking). */
+ int busy;
+ uint32_t valid_bit; /* 0x00 or 0x80 */
+ /* We need to determine when vdq is no longer busy. This depends
+ * on whether the "busy" (last-submitted) dequeue command is
+ * targetting DQRR or main-memory, and detected is based on the
+ * presence of the dequeue command's "token" showing up in
+ * dequeue entries in DQRR or main-memory (respectively). Debug
+ * builds will, when submitting vdq commands, verify that the
+ * dequeue result location is not already equal to the command's
+ * token value. */
+ struct ldpaa_dq *storage; /* NULL if DQRR */
+ uint32_t token;
+ } vdq;
+ /* DQRR */
+ struct {
+ uint32_t next_idx;
+ uint32_t valid_bit;
+ } dqrr;
+};
+
+/* -------------------------- */
+/* portal management commands */
+/* -------------------------- */
+
+/* Different management commands all use this common base layer of code to issue
+ * commands and poll for results. The first function returns a pointer to where
+ * the caller should fill in their MC command (though they should ignore the
+ * verb byte), the second function commits merges in the caller-supplied command
+ * verb (which should not include the valid-bit) and submits the command to
+ * hardware, and the third function checks for a completed response (returns
+ * non-NULL if only if the response is complete). */
+void *qbman_swp_mc_start(struct qbman_swp *p);
+void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, uint32_t cmd_verb);
+void *qbman_swp_mc_result(struct qbman_swp *p);
+
+/* Wraps up submit + poll-for-result */
+static inline void *qbman_swp_mc_complete(struct qbman_swp *swp, void *cmd,
+ uint32_t cmd_verb)
+{
+ int loopvar;
+
+ qbman_swp_mc_submit(swp, cmd, cmd_verb);
+ DBG_POLL_START(loopvar);
+ do {
+ DBG_POLL_CHECK(loopvar);
+ cmd = qbman_swp_mc_result(swp);
+ } while (!cmd);
+ return cmd;
+}
+
+/* ------------ */
+/* qb_attr_code */
+/* ------------ */
+
+/* This struct locates a sub-field within a QBMan portal (CENA) cacheline which
+ * is either serving as a configuration command or a query result. The
+ * representation is inherently little-endian, as the indexing of the words is
+ * itself little-endian in nature and layerscape is little endian for anything
+ * that crosses a word boundary too (64-bit fields are the obvious examples).
+ */
+struct qb_attr_code {
+ unsigned int word; /* which uint32_t[] array member encodes the field */
+ unsigned int lsoffset; /* encoding offset from ls-bit */
+ unsigned int width; /* encoding width. (bool must be 1.) */
+};
+
+/* Macros to define codes */
+#define QB_CODE(a, b, c) { a, b, c}
+
+/* decode a field from a cacheline */
+static inline uint32_t qb_attr_code_decode(const struct qb_attr_code *code,
+ const uint32_t *cacheline)
+{
+ return d32_uint32_t(code->lsoffset, code->width, cacheline[code->word]);
+}
+
+/* encode a field to a cacheline */
+static inline void qb_attr_code_encode(const struct qb_attr_code *code,
+ uint32_t *cacheline, uint32_t val)
+{
+ cacheline[code->word] =
+ r32_uint32_t(code->lsoffset, code->width, cacheline[code->word])
+ | e32_uint32_t(code->lsoffset, code->width, val);
+}
+
+/* ---------------------- */
+/* Descriptors/cachelines */
+/* ---------------------- */
+
+/* To avoid needless dynamic allocation, the driver API often gives the caller
+ * a "descriptor" type that the caller can instantiate however they like.
+ * Ultimately though, it is just a cacheline of binary storage (or something
+ * smaller when it is known that the descriptor doesn't need all 64 bytes) for
+ * holding pre-formatted pieces of harware commands. The performance-critical
+ * code can then copy these descriptors directly into hardware command
+ * registers more efficiently than trying to construct/format commands
+ * on-the-fly. The API user sees the descriptor as an array of 32-bit words in
+ * order for the compiler to know its size, but the internal details are not
+ * exposed. The following macro is used within the driver for converting *any*
+ * descriptor pointer to a usable array pointer. The use of a macro (instead of
+ * an inline) is necessary to work with different descriptor types and to work
+ * correctly with const and non-const inputs (and similarly-qualified outputs).
+ */
+#define qb_cl(d) (&(d)->dont_manipulate_directly[0])
diff --git a/drivers/net/fsl-mc/dpio/qbman_private.h b/drivers/net/fsl-mc/dpio/qbman_private.h
new file mode 100644
index 0000000..2d2556b
--- /dev/null
+++ b/drivers/net/fsl-mc/dpio/qbman_private.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/* Perform extra checking */
+#include <common.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <linux/types.h>
+#include <linux/compat.h>
+#include <malloc.h>
+#include <fsl-mc/fsl_qbman_base.h>
+
+#define QBMAN_CHECKING
+
+/* Any time there is a register interface which we poll on, this provides a
+ * "break after x iterations" scheme for it. It's handy for debugging, eg.
+ * where you don't want millions of lines of log output from a polling loop
+ * that won't, because such things tend to drown out the earlier log output
+ * that might explain what caused the problem. (NB: put ";" after each macro!)
+ * TODO: we should probably remove this once we're done sanitising the
+ * simulator...
+ */
+#define DBG_POLL_START(loopvar) (loopvar = 10)
+#define DBG_POLL_CHECK(loopvar) \
+ do {if (!(loopvar--)) BUG_ON(NULL == "DBG_POLL_CHECK"); } while (0)
+
+/* For CCSR or portal-CINH registers that contain fields at arbitrary offsets
+ * and widths, these macro-generated encode/decode/isolate/remove inlines can
+ * be used.
+ *
+ * Eg. to "d"ecode a 14-bit field out of a register (into a "uint16_t" type),
+ * where the field is located 3 bits "up" from the least-significant bit of the
+ * register (ie. the field location within the 32-bit register corresponds to a
+ * mask of 0x0001fff8), you would do;
+ * uint16_t field = d32_uint16_t(3, 14, reg_value);
+ *
+ * Or to "e"ncode a 1-bit boolean value (input type is "int", zero is FALSE,
+ * non-zero is TRUE, so must convert all non-zero inputs to 1, hence the "!!"
+ * operator) into a register at bit location 0x00080000 (19 bits "in" from the
+ * LS bit), do;
+ * reg_value |= e32_int(19, 1, !!field);
+ *
+ * If you wish to read-modify-write a register, such that you leave the 14-bit
+ * field as-is but have all other fields set to zero, then "i"solate the 14-bit
+ * value using;
+ * reg_value = i32_uint16_t(3, 14, reg_value);
+ *
+ * Alternatively, you could "r"emove the 1-bit boolean field (setting it to
+ * zero) but leaving all other fields as-is;
+ * reg_val = r32_int(19, 1, reg_value);
+ *
+ */
+#define MAKE_MASK32(width) (width == 32 ? 0xffffffff : \
+ (uint32_t)((1 << width) - 1))
+#define DECLARE_CODEC32(t) \
+static inline uint32_t e32_##t(uint32_t lsoffset, uint32_t width, t val) \
+{ \
+ BUG_ON(width > (sizeof(t) * 8)); \
+ return ((uint32_t)val & MAKE_MASK32(width)) << lsoffset; \
+} \
+static inline t d32_##t(uint32_t lsoffset, uint32_t width, uint32_t val) \
+{ \
+ BUG_ON(width > (sizeof(t) * 8)); \
+ return (t)((val >> lsoffset) & MAKE_MASK32(width)); \
+} \
+static inline uint32_t i32_##t(uint32_t lsoffset, uint32_t width, \
+ uint32_t val) \
+{ \
+ BUG_ON(width > (sizeof(t) * 8)); \
+ return e32_##t(lsoffset, width, d32_##t(lsoffset, width, val)); \
+} \
+static inline uint32_t r32_##t(uint32_t lsoffset, uint32_t width, \
+ uint32_t val) \
+{ \
+ BUG_ON(width > (sizeof(t) * 8)); \
+ return ~(MAKE_MASK32(width) << lsoffset) & val; \
+}
+DECLARE_CODEC32(uint32_t)
+DECLARE_CODEC32(uint16_t)
+DECLARE_CODEC32(uint8_t)
+DECLARE_CODEC32(int)
+
+ /*********************/
+ /* Debugging assists */
+ /*********************/
+
+static inline void __hexdump(unsigned long start, unsigned long end,
+ unsigned long p, size_t sz, const unsigned char *c)
+{
+ while (start < end) {
+ unsigned int pos = 0;
+ char buf[64];
+ int nl = 0;
+
+ pos += sprintf(buf + pos, "%08lx: ", start);
+ do {
+ if ((start < p) || (start >= (p + sz)))
+ pos += sprintf(buf + pos, "..");
+ else
+ pos += sprintf(buf + pos, "%02x", *(c++));
+ if (!(++start & 15)) {
+ buf[pos++] = '\n';
+ nl = 1;
+ } else {
+ nl = 0;
+ if (!(start & 1))
+ buf[pos++] = ' ';
+ if (!(start & 3))
+ buf[pos++] = ' ';
+ }
+ } while (start & 15);
+ if (!nl)
+ buf[pos++] = '\n';
+ buf[pos] = '\0';
+ debug("%s", buf);
+ }
+}
+static inline void hexdump(const void *ptr, size_t sz)
+{
+ unsigned long p = (unsigned long)ptr;
+ unsigned long start = p & ~(unsigned long)15;
+ unsigned long end = (p + sz + 15) & ~(unsigned long)15;
+ const unsigned char *c = ptr;
+
+ __hexdump(start, end, p, sz, c);
+}
+
+#if defined(__BIG_ENDIAN)
+#define DQRR_TOK_OFFSET 0
+#else
+#define DQRR_TOK_OFFSET 24
+#endif
+
+/* Similarly-named functions */
+#define upper32(a) upper_32_bits(a)
+#define lower32(a) lower_32_bits(a)
+
+ /****************/
+ /* arch assists */
+ /****************/
+
+static inline void dcbz(void *ptr)
+{
+ uint32_t *p = ptr;
+ BUG_ON((unsigned long)ptr & 63);
+ p[0] = 0;
+ p[1] = 0;
+ p[2] = 0;
+ p[3] = 0;
+ p[4] = 0;
+ p[5] = 0;
+ p[6] = 0;
+ p[7] = 0;
+ p[8] = 0;
+ p[9] = 0;
+ p[10] = 0;
+ p[11] = 0;
+ p[12] = 0;
+ p[13] = 0;
+ p[14] = 0;
+ p[15] = 0;
+}
+
+#define lwsync()
+
+#include "qbman_sys.h"
diff --git a/drivers/net/fsl-mc/dpio/qbman_sys.h b/drivers/net/fsl-mc/dpio/qbman_sys.h
new file mode 100644
index 0000000..235d641
--- /dev/null
+++ b/drivers/net/fsl-mc/dpio/qbman_sys.h
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/* qbman_sys_decl.h and qbman_sys.h are the two platform-specific files in the
+ * driver. They are only included via qbman_private.h, which is itself a
+ * platform-independent file and is included by all the other driver source.
+ *
+ * qbman_sys_decl.h is included prior to all other declarations and logic, and
+ * it exists to provide compatibility with any linux interfaces our
+ * single-source driver code is dependent on (eg. kmalloc). Ie. this file
+ * provides linux compatibility.
+ *
+ * This qbman_sys.h header, on the other hand, is included *after* any common
+ * and platform-neutral declarations and logic in qbman_private.h, and exists to
+ * implement any platform-specific logic of the qbman driver itself. Ie. it is
+ * *not* to provide linux compatibility.
+ */
+
+/* Trace the 3 different classes of read/write access to QBMan. #undef as
+ * required. */
+#undef QBMAN_CCSR_TRACE
+#undef QBMAN_CINH_TRACE
+#undef QBMAN_CENA_TRACE
+
+/* Temporarily define this to get around the fact that cache enabled mapping is
+ * not working right now. Will remove this after uboot could map the cache
+ * enabled portal memory.
+ */
+#define QBMAN_CINH_ONLY
+
+static inline void word_copy(void *d, const void *s, unsigned int cnt)
+{
+ uint32_t *dd = d;
+ const uint32_t *ss = s;
+
+ while (cnt--)
+ *(dd++) = *(ss++);
+}
+
+/* Currently, the CENA support code expects each 32-bit word to be written in
+ * host order, and these are converted to hardware (little-endian) order on
+ * command submission. However, 64-bit quantities are must be written (and read)
+ * as two 32-bit words with the least-significant word first, irrespective of
+ * host endianness. */
+static inline void u64_to_le32_copy(void *d, const uint64_t *s,
+ unsigned int cnt)
+{
+ uint32_t *dd = d;
+ const uint32_t *ss = (const uint32_t *)s;
+
+ while (cnt--) {
+ /* TBD: the toolchain was choking on the use of 64-bit types up
+ * until recently so this works entirely with 32-bit variables.
+ * When 64-bit types become usable again, investigate better
+ * ways of doing this. */
+#if defined(__BIG_ENDIAN)
+ *(dd++) = ss[1];
+ *(dd++) = ss[0];
+ ss += 2;
+#else
+ *(dd++) = *(ss++);
+ *(dd++) = *(ss++);
+#endif
+ }
+}
+static inline void u64_from_le32_copy(uint64_t *d, const void *s,
+ unsigned int cnt)
+{
+ const uint32_t *ss = s;
+ uint32_t *dd = (uint32_t *)d;
+
+ while (cnt--) {
+#if defined(__BIG_ENDIAN)
+ dd[1] = *(ss++);
+ dd[0] = *(ss++);
+ dd += 2;
+#else
+ *(dd++) = *(ss++);
+ *(dd++) = *(ss++);
+#endif
+ }
+}
+
+/* Convert a host-native 32bit value into little endian */
+#if defined(__BIG_ENDIAN)
+static inline uint32_t make_le32(uint32_t val)
+{
+ return ((val & 0xff) << 24) | ((val & 0xff00) << 8) |
+ ((val & 0xff0000) >> 8) | ((val & 0xff000000) >> 24);
+}
+#else
+#define make_le32(val) (val)
+#endif
+static inline void make_le32_n(uint32_t *val, unsigned int num)
+{
+ while (num--) {
+ *val = make_le32(*val);
+ val++;
+ }
+}
+
+ /******************/
+ /* Portal access */
+ /******************/
+struct qbman_swp_sys {
+ /* On GPP, the sys support for qbman_swp is here. The CENA region isi
+ * not an mmap() of the real portal registers, but an allocated
+ * place-holder, because the actual writes/reads to/from the portal are
+ * marshalled from these allocated areas using QBMan's "MC access
+ * registers". CINH accesses are atomic so there's no need for a
+ * place-holder. */
+ void *cena;
+ void __iomem *addr_cena;
+ void __iomem *addr_cinh;
+};
+
+/* P_OFFSET is (ACCESS_CMD,0,12) - offset within the portal
+ * C is (ACCESS_CMD,12,1) - is inhibited? (0==CENA, 1==CINH)
+ * SWP_IDX is (ACCESS_CMD,16,10) - Software portal index
+ * P is (ACCESS_CMD,28,1) - (0==special portal, 1==any portal)
+ * T is (ACCESS_CMD,29,1) - Command type (0==READ, 1==WRITE)
+ * E is (ACCESS_CMD,31,1) - Command execute (1 to issue, poll for 0==complete)
+ */
+
+static inline void qbman_cinh_write(struct qbman_swp_sys *s, uint32_t offset,
+ uint32_t val)
+{
+ __raw_writel(val, s->addr_cinh + offset);
+#ifdef QBMAN_CINH_TRACE
+ pr_info("qbman_cinh_write(%p:0x%03x) 0x%08x\n",
+ s->addr_cinh, offset, val);
+#endif
+}
+
+static inline uint32_t qbman_cinh_read(struct qbman_swp_sys *s, uint32_t offset)
+{
+ uint32_t reg = __raw_readl(s->addr_cinh + offset);
+
+#ifdef QBMAN_CINH_TRACE
+ pr_info("qbman_cinh_read(%p:0x%03x) 0x%08x\n",
+ s->addr_cinh, offset, reg);
+#endif
+ return reg;
+}
+
+static inline void *qbman_cena_write_start(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+ void *shadow = s->cena + offset;
+
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_write_start(%p:0x%03x) %p\n",
+ s->addr_cena, offset, shadow);
+#endif
+ BUG_ON(offset & 63);
+ dcbz(shadow);
+ return shadow;
+}
+
+static inline void qbman_cena_write_complete(struct qbman_swp_sys *s,
+ uint32_t offset, void *cmd)
+{
+ const uint32_t *shadow = cmd;
+ int loop;
+
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_write_complete(%p:0x%03x) %p\n",
+ s->addr_cena, offset, shadow);
+ hexdump(cmd, 64);
+#endif
+ for (loop = 15; loop >= 0; loop--)
+#ifdef QBMAN_CINH_ONLY
+ __raw_writel(shadow[loop], s->addr_cinh +
+ offset + loop * 4);
+#else
+ __raw_writel(shadow[loop], s->addr_cena +
+ offset + loop * 4);
+#endif
+}
+
+static inline void *qbman_cena_read(struct qbman_swp_sys *s, uint32_t offset)
+{
+ uint32_t *shadow = s->cena + offset;
+ unsigned int loop;
+
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_read(%p:0x%03x) %p\n",
+ s->addr_cena, offset, shadow);
+#endif
+
+ for (loop = 0; loop < 16; loop++)
+#ifdef QBMAN_CINH_ONLY
+ shadow[loop] = __raw_readl(s->addr_cinh + offset
+ + loop * 4);
+#else
+ shadow[loop] = __raw_readl(s->addr_cena + offset
+ + loop * 4);
+#endif
+#ifdef QBMAN_CENA_TRACE
+ hexdump(shadow, 64);
+#endif
+ return shadow;
+}
+
+static inline void qbman_cena_invalidate_prefetch(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+}
+
+ /******************/
+ /* Portal support */
+ /******************/
+
+/* The SWP_CFG portal register is special, in that it is used by the
+ * platform-specific code rather than the platform-independent code in
+ * qbman_portal.c. So use of it is declared locally here. */
+#define QBMAN_CINH_SWP_CFG 0xd00
+
+/* For MC portal use, we always configure with
+ * DQRR_MF is (SWP_CFG,20,3) - DQRR max fill (<- 0x4)
+ * EST is (SWP_CFG,16,3) - EQCR_CI stashing threshold (<- 0x0)
+ * RPM is (SWP_CFG,12,2) - RCR production notification mode (<- 0x3)
+ * DCM is (SWP_CFG,10,2) - DQRR consumption notification mode (<- 0x2)
+ * EPM is (SWP_CFG,8,2) - EQCR production notification mode (<- 0x3)
+ * SD is (SWP_CFG,5,1) - memory stashing drop enable (<- FALSE)
+ * SP is (SWP_CFG,4,1) - memory stashing priority (<- TRUE)
+ * SE is (SWP_CFG,3,1) - memory stashing enable (<- 0x0)
+ * DP is (SWP_CFG,2,1) - dequeue stashing priority (<- TRUE)
+ * DE is (SWP_CFG,1,1) - dequeue stashing enable (<- 0x0)
+ * EP is (SWP_CFG,0,1) - EQCR_CI stashing priority (<- FALSE)
+ */
+static inline uint32_t qbman_set_swp_cfg(uint8_t max_fill, uint8_t wn,
+ uint8_t est, uint8_t rpm, uint8_t dcm,
+ uint8_t epm, int sd, int sp, int se,
+ int dp, int de, int ep)
+{
+ uint32_t reg;
+
+ reg = e32_uint8_t(20, 3, max_fill) | e32_uint8_t(16, 3, est) |
+ e32_uint8_t(12, 2, rpm) | e32_uint8_t(10, 2, dcm) |
+ e32_uint8_t(8, 2, epm) | e32_int(5, 1, sd) |
+ e32_int(4, 1, sp) | e32_int(3, 1, se) | e32_int(2, 1, dp) |
+ e32_int(1, 1, de) | e32_int(0, 1, ep) | e32_uint8_t(14, 1, wn);
+ return reg;
+}
+
+static inline int qbman_swp_sys_init(struct qbman_swp_sys *s,
+ const struct qbman_swp_desc *d)
+{
+ uint32_t reg;
+
+ s->addr_cena = d->cena_bar;
+ s->addr_cinh = d->cinh_bar;
+ s->cena = (void *)valloc(CONFIG_SYS_PAGE_SIZE);
+ memset((void *)s->cena, 0x00, CONFIG_SYS_PAGE_SIZE);
+ if (!s->cena) {
+ printf("Could not allocate page for cena shadow\n");
+ return -1;
+ }
+
+#ifdef QBMAN_CHECKING
+ /* We should never be asked to initialise for a portal that isn't in
+ * the power-on state. (Ie. don't forget to reset portals when they are
+ * decommissioned!)
+ */
+ reg = qbman_cinh_read(s, QBMAN_CINH_SWP_CFG);
+ BUG_ON(reg);
+#endif
+#ifdef QBMAN_CINH_ONLY
+ reg = qbman_set_swp_cfg(4, 1, 0, 3, 2, 3, 0, 1, 0, 1, 0, 0);
+#else
+ reg = qbman_set_swp_cfg(4, 0, 0, 3, 2, 3, 0, 1, 0, 1, 0, 0);
+#endif
+ qbman_cinh_write(s, QBMAN_CINH_SWP_CFG, reg);
+ reg = qbman_cinh_read(s, QBMAN_CINH_SWP_CFG);
+ if (!reg) {
+ printf("The portal is not enabled!\n");
+ free(s->cena);
+ return -1;
+ }
+ return 0;
+}
+
+static inline void qbman_swp_sys_finish(struct qbman_swp_sys *s)
+{
+ free((void *)s->cena);
+}
diff --git a/drivers/net/fsl-mc/dpmng.c b/drivers/net/fsl-mc/dpmng.c
index cc14c7b..01ee112 100644
--- a/drivers/net/fsl-mc/dpmng.c
+++ b/drivers/net/fsl-mc/dpmng.c
@@ -1,4 +1,4 @@
-/* Copyright 2014 Freescale Semiconductor Inc.
+/* Copyright 2013-2015 Freescale Semiconductor Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -26,66 +26,3 @@ int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info)
return 0;
}
-
-int dpmng_reset_aiop(struct fsl_mc_io *mc_io, int container_id,
- int aiop_tile_id)
-{
- struct mc_command cmd = { 0 };
-
- /* prepare command */
- cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RESET_AIOP,
- MC_CMD_PRI_LOW, 0);
- DPMNG_CMD_RESET_AIOP(cmd, container_id, aiop_tile_id);
-
- /* send command to mc*/
- return mc_send_command(mc_io, &cmd);
-}
-
-int dpmng_load_aiop(struct fsl_mc_io *mc_io,
- int container_id,
- int aiop_tile_id,
- uint64_t img_iova,
- uint32_t img_size)
-{
- struct mc_command cmd = { 0 };
-
- /* prepare command */
- cmd.header = mc_encode_cmd_header(DPMNG_CMDID_LOAD_AIOP,
- MC_CMD_PRI_LOW,
- 0);
- DPMNG_CMD_LOAD_AIOP(cmd, container_id, aiop_tile_id, img_size,
- img_iova);
-
- /* send command to mc*/
- return mc_send_command(mc_io, &cmd);
-}
-
-int dpmng_run_aiop(struct fsl_mc_io *mc_io,
- int container_id,
- int aiop_tile_id,
- const struct dpmng_aiop_run_cfg *cfg)
-{
- struct mc_command cmd = { 0 };
-
- /* prepare command */
- cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RUN_AIOP,
- MC_CMD_PRI_LOW,
- 0);
- DPMNG_CMD_RUN_AIOP(cmd, container_id, aiop_tile_id, cfg);
-
- /* send command to mc*/
- return mc_send_command(mc_io, &cmd);
-}
-
-int dpmng_reset_mc_portal(struct fsl_mc_io *mc_io)
-{
- struct mc_command cmd = { 0 };
-
- /* prepare command */
- cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RESET_MC_PORTAL,
- MC_CMD_PRI_LOW,
- 0);
-
- /* send command to mc*/
- return mc_send_command(mc_io, &cmd);
-}
diff --git a/drivers/net/fsl-mc/dpni.c b/drivers/net/fsl-mc/dpni.c
new file mode 100644
index 0000000..b384401
--- /dev/null
+++ b/drivers/net/fsl-mc/dpni.c
@@ -0,0 +1,506 @@
+/*
+ * Copyright (C) 2013-2015 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <fsl-mc/fsl_mc_sys.h>
+#include <fsl-mc/fsl_mc_cmd.h>
+#include <fsl-mc/fsl_dpni.h>
+
+int dpni_open(struct fsl_mc_io *mc_io, int dpni_id, uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_OPEN,
+ MC_CMD_PRI_LOW, 0);
+ DPNI_CMD_OPEN(cmd, dpni_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return 0;
+}
+
+int dpni_close(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLOSE,
+ MC_CMD_PRI_HIGH, token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_pools(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dpni_pools_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_POOLS,
+ MC_CMD_PRI_LOW,
+ token);
+ DPNI_CMD_SET_POOLS(cmd, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_enable(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_disable(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_DISABLE,
+ MC_CMD_PRI_LOW,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_reset(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_attributes(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpni_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_ATTR,
+ MC_CMD_PRI_LOW,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_ATTR(cmd, attr);
+
+ return 0;
+}
+
+int dpni_get_rx_buffer_layout(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_RX_BUFFER_LAYOUT,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_RX_BUFFER_LAYOUT(cmd, layout);
+
+ return 0;
+}
+
+int dpni_set_rx_buffer_layout(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_BUFFER_LAYOUT,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_SET_RX_BUFFER_LAYOUT(cmd, layout);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_tx_buffer_layout(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TX_BUFFER_LAYOUT,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_TX_BUFFER_LAYOUT(cmd, layout);
+
+ return 0;
+}
+
+int dpni_set_tx_buffer_layout(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_BUFFER_LAYOUT,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_SET_TX_BUFFER_LAYOUT(cmd, layout);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_tx_conf_buffer_layout(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TX_CONF_BUFFER_LAYOUT,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_TX_CONF_BUFFER_LAYOUT(cmd, layout);
+
+ return 0;
+}
+
+int dpni_set_tx_conf_buffer_layout(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_CONF_BUFFER_LAYOUT,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_SET_TX_CONF_BUFFER_LAYOUT(cmd, layout);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_qdid(struct fsl_mc_io *mc_io, uint16_t token, uint16_t *qdid)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QDID,
+ MC_CMD_PRI_LOW,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_QDID(cmd, *qdid);
+
+ return 0;
+}
+
+int dpni_get_tx_data_offset(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ uint16_t *data_offset)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TX_DATA_OFFSET,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_TX_DATA_OFFSET(cmd, *data_offset);
+
+ return 0;
+}
+
+int dpni_get_counter(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ enum dpni_counter counter,
+ uint64_t *value)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_COUNTER,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_GET_COUNTER(cmd, counter);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_COUNTER(cmd, *value);
+
+ return 0;
+}
+
+int dpni_set_counter(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ enum dpni_counter counter,
+ uint64_t value)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_COUNTER,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_SET_COUNTER(cmd, counter, value);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_link_cfg(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpni_link_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_LINK_CFG,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_SET_LINK_CFG(cmd, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_link_state(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpni_link_state *state)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_STATE,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_LINK_STATE(cmd, state);
+
+ return 0;
+}
+
+
+int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const uint8_t mac_addr[6])
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_PRIM_MAC,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_SET_PRIMARY_MAC_ADDR(cmd, mac_addr);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ uint8_t mac_addr[6])
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PRIM_MAC,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_PRIMARY_MAC_ADDR(cmd, mac_addr);
+
+ return 0;
+}
+
+int dpni_add_mac_addr(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const uint8_t mac_addr[6])
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_MAC_ADDR,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_ADD_MAC_ADDR(cmd, mac_addr);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_remove_mac_addr(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const uint8_t mac_addr[6])
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_MAC_ADDR,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_REMOVE_MAC_ADDR(cmd, mac_addr);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_tx_flow(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ uint16_t *flow_id,
+ const struct dpni_tx_flow_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_FLOW,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_SET_TX_FLOW(cmd, *flow_id, cfg);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_SET_TX_FLOW(cmd, *flow_id);
+
+ return 0;
+}
+
+int dpni_get_tx_flow(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ uint16_t flow_id,
+ struct dpni_tx_flow_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TX_FLOW,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_GET_TX_FLOW(cmd, flow_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_TX_FLOW(cmd, attr);
+
+ return 0;
+}
+
+int dpni_set_rx_flow(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ uint8_t tc_id,
+ uint16_t flow_id,
+ const struct dpni_queue_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_FLOW,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_SET_RX_FLOW(cmd, tc_id, flow_id, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_rx_flow(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ uint8_t tc_id,
+ uint16_t flow_id,
+ struct dpni_queue_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_RX_FLOW,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_GET_RX_FLOW(cmd, tc_id, flow_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_RX_FLOW(cmd, attr);
+
+ return 0;
+}
diff --git a/drivers/net/fsl-mc/dprc.c b/drivers/net/fsl-mc/dprc.c
new file mode 100644
index 0000000..d481200
--- /dev/null
+++ b/drivers/net/fsl-mc/dprc.c
@@ -0,0 +1,283 @@
+/*
+ * Freescale Layerscape MC I/O wrapper
+ *
+ * Copyright (C) 2013-2015 Freescale Semiconductor, Inc.
+ * Author: German Rivera <German.Rivera@freescale.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <fsl-mc/fsl_mc_sys.h>
+#include <fsl-mc/fsl_mc_cmd.h>
+#include <fsl-mc/fsl_dprc.h>
+
+int dprc_get_container_id(struct fsl_mc_io *mc_io, int *container_id)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONT_ID,
+ MC_CMD_PRI_LOW, 0);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPRC_RSP_GET_CONTAINER_ID(cmd, *container_id);
+
+ return 0;
+}
+
+int dprc_open(struct fsl_mc_io *mc_io, int container_id, uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_OPEN, MC_CMD_PRI_LOW,
+ 0);
+ DPRC_CMD_OPEN(cmd, container_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return 0;
+}
+
+int dprc_close(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_CLOSE, MC_CMD_PRI_HIGH,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dprc_reset_container(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ int child_container_id)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_RESET_CONT,
+ MC_CMD_PRI_LOW, token);
+ DPRC_CMD_RESET_CONTAINER(cmd, child_container_id);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dprc_get_attributes(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dprc_attributes *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_ATTR,
+ MC_CMD_PRI_LOW,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPRC_RSP_GET_ATTRIBUTES(cmd, attr);
+
+ return 0;
+}
+
+int dprc_get_obj_count(struct fsl_mc_io *mc_io, uint16_t token, int *obj_count)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_COUNT,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPRC_RSP_GET_OBJ_COUNT(cmd, *obj_count);
+
+ return 0;
+}
+
+int dprc_get_obj(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ int obj_index,
+ struct dprc_obj_desc *obj_desc)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ,
+ MC_CMD_PRI_LOW,
+ token);
+ DPRC_CMD_GET_OBJ(cmd, obj_index);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPRC_RSP_GET_OBJ(cmd, obj_desc);
+
+ return 0;
+}
+
+int dprc_get_res_count(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ char *type,
+ int *res_count)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ *res_count = 0;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_RES_COUNT,
+ MC_CMD_PRI_LOW, token);
+ DPRC_CMD_GET_RES_COUNT(cmd, type);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPRC_RSP_GET_RES_COUNT(cmd, *res_count);
+
+ return 0;
+}
+
+int dprc_get_res_ids(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ char *type,
+ struct dprc_res_ids_range_desc *range_desc)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_RES_IDS,
+ MC_CMD_PRI_LOW, token);
+ DPRC_CMD_GET_RES_IDS(cmd, range_desc, type);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPRC_RSP_GET_RES_IDS(cmd, range_desc);
+
+ return 0;
+}
+
+int dprc_get_obj_region(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ char *obj_type,
+ int obj_id,
+ uint8_t region_index,
+ struct dprc_region_desc *region_desc)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_REG,
+ MC_CMD_PRI_LOW, token);
+ DPRC_CMD_GET_OBJ_REGION(cmd, obj_type, obj_id, region_index);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPRC_RSP_GET_OBJ_REGION(cmd, region_desc);
+
+ return 0;
+}
+
+int dprc_connect(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dprc_endpoint *endpoint1,
+ const struct dprc_endpoint *endpoint2)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_CONNECT,
+ MC_CMD_PRI_LOW,
+ token);
+ DPRC_CMD_CONNECT(cmd, endpoint1, endpoint2);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dprc_disconnect(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dprc_endpoint *endpoint)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_DISCONNECT,
+ MC_CMD_PRI_LOW,
+ token);
+ DPRC_CMD_DISCONNECT(cmd, endpoint);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dprc_get_connection(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dprc_endpoint *endpoint1,
+ struct dprc_endpoint *endpoint2,
+ int *state)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONNECTION,
+ MC_CMD_PRI_LOW,
+ token);
+ DPRC_CMD_GET_CONNECTION(cmd, endpoint1);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPRC_RSP_GET_CONNECTION(cmd, endpoint2, *state);
+
+ return 0;
+}
diff --git a/drivers/net/fsl-mc/fsl_dpmng_cmd.h b/drivers/net/fsl-mc/fsl_dpmng_cmd.h
index c9fe021..33f84f3 100644
--- a/drivers/net/fsl-mc/fsl_dpmng_cmd.h
+++ b/drivers/net/fsl-mc/fsl_dpmng_cmd.h
@@ -1,4 +1,4 @@
-/* Copyright 2014 Freescale Semiconductor Inc.
+/* Copyright 2013-2015 Freescale Semiconductor Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -7,10 +7,6 @@
/* Command IDs */
#define DPMNG_CMDID_GET_VERSION 0x831
-#define DPMNG_CMDID_RESET_AIOP 0x832
-#define DPMNG_CMDID_LOAD_AIOP 0x833
-#define DPMNG_CMDID_RUN_AIOP 0x834
-#define DPMNG_CMDID_RESET_MC_PORTAL 0x835
/* cmd, param, offset, width, type, arg_name */
#define DPMNG_RSP_GET_VERSION(cmd, mc_ver_info) \
@@ -20,30 +16,4 @@ do { \
MC_RSP_OP(cmd, 1, 0, 32, uint32_t, mc_ver_info->minor); \
} while (0)
-/* cmd, param, offset, width, type, arg_name */
-#define DPMNG_CMD_RESET_AIOP(cmd, container_id, aiop_tile_id) \
-do { \
- MC_CMD_OP(cmd, 0, 0, 32, int, aiop_tile_id); \
- MC_CMD_OP(cmd, 0, 32, 32, int, container_id); \
-} while (0)
-
-/* cmd, param, offset, width, type, arg_name */
-#define DPMNG_CMD_LOAD_AIOP(cmd, container_id, aiop_tile_id, img_size, \
- img_iova) \
-do { \
- MC_CMD_OP(cmd, 0, 0, 32, int, aiop_tile_id); \
- MC_CMD_OP(cmd, 0, 32, 32, int, container_id); \
- MC_CMD_OP(cmd, 1, 0, 32, uint32_t, img_size); \
- MC_CMD_OP(cmd, 2, 0, 64, uint64_t, img_iova); \
-} while (0)
-
-/* cmd, param, offset, width, type, arg_name */
-#define DPMNG_CMD_RUN_AIOP(cmd, container_id, aiop_tile_id, cfg) \
-do { \
- MC_CMD_OP(cmd, 0, 0, 32, int, aiop_tile_id); \
- MC_CMD_OP(cmd, 0, 32, 32, int, container_id); \
- MC_CMD_OP(cmd, 1, 0, 32, uint32_t, cfg->cores_mask); \
- MC_CMD_OP(cmd, 2, 0, 64, uint64_t, cfg->options); \
-} while (0)
-
#endif /* __FSL_DPMNG_CMD_H */
diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c
index 76581cb..e29ee3d 100644
--- a/drivers/net/fsl-mc/mc.c
+++ b/drivers/net/fsl-mc/mc.c
@@ -8,11 +8,20 @@
#include <asm/io.h>
#include <fsl-mc/fsl_mc.h>
#include <fsl-mc/fsl_mc_sys.h>
+#include <fsl-mc/fsl_mc_private.h>
#include <fsl-mc/fsl_dpmng.h>
#include <fsl_debug_server.h>
+#include <fsl-mc/fsl_dprc.h>
+#include <fsl-mc/fsl_dpio.h>
+#include <fsl-mc/fsl_qbman_portal.h>
DECLARE_GLOBAL_DATA_PTR;
static int mc_boot_status;
+struct fsl_mc_io *dflt_mc_io = NULL;
+uint16_t dflt_dprc_handle = 0;
+struct fsl_dpbp_obj *dflt_dpbp = NULL;
+struct fsl_dpio_obj *dflt_dpio = NULL;
+uint16_t dflt_dpio_handle = NULL;
/**
* Copying MC firmware or DPL image to DDR
@@ -84,10 +93,11 @@ int parse_mc_firmware_fit_image(const void **raw_image_addr,
return 0;
}
-int mc_init(bd_t *bis)
+int mc_init(void)
{
int error = 0;
int timeout = 200000;
+ int portal_id = 0;
struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR;
u64 mc_ram_addr;
u64 mc_dpl_offset;
@@ -97,8 +107,6 @@ int mc_init(bd_t *bis)
int dpl_size;
const void *raw_image_addr;
size_t raw_image_size = 0;
- struct fsl_mc_io mc_io;
- int portal_id;
struct mc_version mc_ver_info;
/*
@@ -263,13 +271,20 @@ int mc_init(bd_t *bis)
portal_id = 0;
/*
- * Check that the MC firmware is responding portal commands:
+ * Initialize the global default MC portal
+ * And check that the MC firmware is responding portal commands:
*/
- mc_io.mmio_regs = SOC_MC_PORTAL_ADDR(portal_id);
+ dflt_mc_io = (struct fsl_mc_io *)malloc(sizeof(struct fsl_mc_io));
+ if (!dflt_mc_io) {
+ printf(" No memory: malloc() failed\n");
+ return -ENOMEM;
+ }
+
+ dflt_mc_io->mmio_regs = SOC_MC_PORTAL_ADDR(portal_id);
debug("Checking access to MC portal of root DPRC container (portal_id %d, portal physical addr %p)\n",
- portal_id, mc_io.mmio_regs);
+ portal_id, dflt_mc_io->mmio_regs);
- error = mc_get_version(&mc_io, &mc_ver_info);
+ error = mc_get_version(dflt_mc_io, &mc_ver_info);
if (error != 0) {
printf("fsl-mc: ERROR: Firmware version check failed (error: %d)\n",
error);
@@ -312,3 +327,204 @@ unsigned long mc_get_dram_block_size(void)
{
return CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE;
}
+
+int dpio_init(struct dprc_obj_desc obj_desc)
+{
+ struct qbman_swp_desc p_des;
+ struct dpio_attr attr;
+ int err = 0;
+
+ dflt_dpio = (struct fsl_dpio_obj *)malloc(sizeof(struct fsl_dpio_obj));
+ if (!dflt_dpio) {
+ printf(" No memory: malloc() failed\n");
+ return -ENOMEM;
+ }
+
+ dflt_dpio->dpio_id = obj_desc.id;
+
+ err = dpio_open(dflt_mc_io, obj_desc.id, &dflt_dpio_handle);
+ if (err) {
+ printf("dpio_open() failed\n");
+ goto err_open;
+ }
+
+ err = dpio_get_attributes(dflt_mc_io, dflt_dpio_handle, &attr);
+ if (err) {
+ printf("dpio_get_attributes() failed %d\n", err);
+ goto err_get_attr;
+ }
+
+ err = dpio_enable(dflt_mc_io, dflt_dpio_handle);
+ if (err) {
+ printf("dpio_enable() failed %d\n", err);
+ goto err_get_enable;
+ }
+ debug("ce_paddr=0x%llx, ci_paddr=0x%llx, portalid=%d, prios=%d\n",
+ attr.qbman_portal_ce_paddr,
+ attr.qbman_portal_ci_paddr,
+ attr.qbman_portal_id,
+ attr.num_priorities);
+
+ p_des.cena_bar = (void *)attr.qbman_portal_ce_paddr;
+ p_des.cinh_bar = (void *)attr.qbman_portal_ci_paddr;
+
+ dflt_dpio->sw_portal = qbman_swp_init(&p_des);
+ if (dflt_dpio->sw_portal == NULL) {
+ printf("qbman_swp_init() failed\n");
+ goto err_get_swp_init;
+ }
+ return 0;
+
+err_get_swp_init:
+err_get_enable:
+ dpio_disable(dflt_mc_io, dflt_dpio_handle);
+err_get_attr:
+ dpio_close(dflt_mc_io, dflt_dpio_handle);
+err_open:
+ free(dflt_dpio);
+ return err;
+}
+
+int dpbp_init(struct dprc_obj_desc obj_desc)
+{
+ dflt_dpbp = (struct fsl_dpbp_obj *)malloc(sizeof(struct fsl_dpbp_obj));
+ if (!dflt_dpbp) {
+ printf(" No memory: malloc() failed\n");
+ return -ENOMEM;
+ }
+ dflt_dpbp->dpbp_attr.id = obj_desc.id;
+
+ return 0;
+}
+
+int dprc_init_container_obj(struct dprc_obj_desc obj_desc)
+{
+ int error = 0;
+ if (!strcmp(obj_desc.type, "dpbp")) {
+ if (!dflt_dpbp) {
+ error = dpbp_init(obj_desc);
+ if (error < 0)
+ printf("dpbp_init failed\n");
+ }
+ } else if (!strcmp(obj_desc.type, "dpio")) {
+ if (!dflt_dpio) {
+ error = dpio_init(obj_desc);
+ if (error < 0)
+ printf("dpio_init failed\n");
+ }
+ }
+
+ return error;
+}
+
+int dprc_scan_container_obj(uint16_t dprc_handle, char *obj_type, int i)
+{
+ int error = 0;
+ struct dprc_obj_desc obj_desc;
+
+ memset((void *)&obj_desc, 0x00, sizeof(struct dprc_obj_desc));
+
+ error = dprc_get_obj(dflt_mc_io, dprc_handle,
+ i, &obj_desc);
+ if (error < 0) {
+ printf("dprc_get_obj(i=%d) failed: %d\n",
+ i, error);
+ return error;
+ }
+
+ if (!strcmp(obj_desc.type, obj_type)) {
+ debug("Discovered object: type %s, id %d, req %s\n",
+ obj_desc.type, obj_desc.id, obj_type);
+
+ error = dprc_init_container_obj(obj_desc);
+ if (error < 0) {
+ printf("dprc_init_container_obj(i=%d) failed: %d\n",
+ i, error);
+ return error;
+ }
+ }
+
+ return error;
+}
+
+int fsl_mc_ldpaa_init(bd_t *bis)
+{
+ int i, error = 0;
+ int dprc_opened = 0, container_id;
+ int num_child_objects = 0;
+
+ error = mc_init();
+
+ error = dprc_get_container_id(dflt_mc_io, &container_id);
+ if (error < 0) {
+ printf("dprc_get_container_id() failed: %d\n", error);
+ goto error;
+ }
+
+ debug("fsl-mc: Container id=0x%x\n", container_id);
+
+ error = dprc_open(dflt_mc_io, container_id, &dflt_dprc_handle);
+ if (error < 0) {
+ printf("dprc_open() failed: %d\n", error);
+ goto error;
+ }
+ dprc_opened = true;
+
+ error = dprc_get_obj_count(dflt_mc_io,
+ dflt_dprc_handle,
+ &num_child_objects);
+ if (error < 0) {
+ printf("dprc_get_obj_count() failed: %d\n", error);
+ goto error;
+ }
+ debug("Total child in container %d = %d\n", container_id,
+ num_child_objects);
+
+ if (num_child_objects != 0) {
+ /*
+ * Discover objects currently in the DPRC container in the MC:
+ */
+ for (i = 0; i < num_child_objects; i++)
+ error = dprc_scan_container_obj(dflt_dprc_handle,
+ "dpbp", i);
+
+ for (i = 0; i < num_child_objects; i++)
+ error = dprc_scan_container_obj(dflt_dprc_handle,
+ "dpio", i);
+
+ for (i = 0; i < num_child_objects; i++)
+ error = dprc_scan_container_obj(dflt_dprc_handle,
+ "dpni", i);
+ }
+error:
+ if (dprc_opened)
+ dprc_close(dflt_mc_io, dflt_dprc_handle);
+
+ return error;
+}
+
+void fsl_mc_ldpaa_exit(bd_t *bis)
+{
+ int err;
+
+
+ err = dpio_disable(dflt_mc_io, dflt_dpio_handle);
+ if (err < 0) {
+ printf("dpio_disable() failed: %d\n", err);
+ return;
+ }
+ err = dpio_reset(dflt_mc_io, dflt_dpio_handle);
+ if (err < 0) {
+ printf("dpio_reset() failed: %d\n", err);
+ return;
+ }
+ err = dpio_close(dflt_mc_io, dflt_dpio_handle);
+ if (err < 0) {
+ printf("dpio_close() failed: %d\n", err);
+ return;
+ }
+
+ free(dflt_dpio);
+ free(dflt_dpbp);
+ free(dflt_mc_io);
+}
diff --git a/drivers/net/fsl-mc/mc_sys.c b/drivers/net/fsl-mc/mc_sys.c
index 7c8e003..3fc1f98 100644
--- a/drivers/net/fsl-mc/mc_sys.c
+++ b/drivers/net/fsl-mc/mc_sys.c
@@ -1,7 +1,7 @@
/*
* Freescale Layerscape MC I/O wrapper
*
- * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Copyright (C) 2013-2015 Freescale Semiconductor, Inc.
* Author: German Rivera <German.Rivera@freescale.com>
*
* SPDX-License-Identifier: GPL-2.0+
@@ -32,7 +32,7 @@ int mc_send_command(struct fsl_mc_io *mc_io,
struct mc_command *cmd)
{
enum mc_cmd_status status;
- int timeout = 2000;
+ int timeout = 6000;
mc_write_command(mc_io->mmio_regs, cmd);
@@ -52,7 +52,7 @@ int mc_send_command(struct fsl_mc_io *mc_io,
if (status != MC_CMD_STATUS_OK) {
printf("Error: MC command failed (portal: %p, obj handle: %#x, command: %#x, status: %#x)\n",
mc_io->mmio_regs,
- (unsigned int)MC_CMD_HDR_READ_AUTHID(cmd->header),
+ (unsigned int)MC_CMD_HDR_READ_TOKEN(cmd->header),
(unsigned int)MC_CMD_HDR_READ_CMDID(cmd->header),
(unsigned int)status);
diff --git a/include/fsl-mc/fsl_dpaa_fd.h b/include/fsl-mc/fsl_dpaa_fd.h
new file mode 100644
index 0000000..6d0ffa8
--- /dev/null
+++ b/include/fsl-mc/fsl_dpaa_fd.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef __FSL_DPAA_FD_H
+#define __FSL_DPAA_FD_H
+
+/* Place-holder for FDs, we represent it via the simplest form that we need for
+ * now. Different overlays may be needed to support different options, etc. (It
+ * is impractical to define One True Struct, because the resulting encoding
+ * routines (lots of read-modify-writes) would be worst-case performance whether
+ * or not circumstances required them.) */
+struct dpaa_fd {
+ union {
+ u32 words[8];
+ struct dpaa_fd_simple {
+ u32 addr_lo;
+ u32 addr_hi;
+ u32 len;
+ /* offset in the MS 16 bits, BPID in the LS 16 bits */
+ u32 bpid_offset;
+ u32 frc; /* frame context */
+ /* "err", "va", "cbmt", "asal", [...] */
+ u32 ctrl;
+ /* flow context */
+ u32 flc_lo;
+ u32 flc_hi;
+ } simple;
+ };
+};
+
+enum dpaa_fd_format {
+ dpaa_fd_single = 0,
+ dpaa_fd_list,
+ dpaa_fd_sg
+};
+
+static inline u64 ldpaa_fd_get_addr(const struct dpaa_fd *fd)
+{
+ return (u64)((((uint64_t)fd->simple.addr_hi) << 32)
+ + fd->simple.addr_lo);
+}
+
+static inline void ldpaa_fd_set_addr(struct dpaa_fd *fd, u64 addr)
+{
+ fd->simple.addr_hi = upper_32_bits(addr);
+ fd->simple.addr_lo = lower_32_bits(addr);
+}
+
+static inline u32 ldpaa_fd_get_len(const struct dpaa_fd *fd)
+{
+ return fd->simple.len;
+}
+
+static inline void ldpaa_fd_set_len(struct dpaa_fd *fd, u32 len)
+{
+ fd->simple.len = len;
+}
+
+static inline uint16_t ldpaa_fd_get_offset(const struct dpaa_fd *fd)
+{
+ return (uint16_t)(fd->simple.bpid_offset >> 16) & 0x0FFF;
+}
+
+static inline void ldpaa_fd_set_offset(struct dpaa_fd *fd, uint16_t offset)
+{
+ fd->simple.bpid_offset &= 0xF000FFFF;
+ fd->simple.bpid_offset |= (u32)offset << 16;
+}
+
+static inline uint16_t ldpaa_fd_get_bpid(const struct dpaa_fd *fd)
+{
+ return (uint16_t)(fd->simple.bpid_offset & 0xFFFF);
+}
+
+static inline void ldpaa_fd_set_bpid(struct dpaa_fd *fd, uint16_t bpid)
+{
+ fd->simple.bpid_offset &= 0xFFFF0000;
+ fd->simple.bpid_offset |= (u32)bpid;
+}
+
+/* When frames are dequeued, the FDs show up inside "dequeue" result structures
+ * (if at all, not all dequeue results contain valid FDs). This structure type
+ * is intentionally defined without internal detail, and the only reason it
+ * isn't declared opaquely (without size) is to allow the user to provide
+ * suitably-sized (and aligned) memory for these entries. */
+struct ldpaa_dq {
+ uint32_t dont_manipulate_directly[16];
+};
+
+/* Parsing frame dequeue results */
+#define LDPAA_DQ_STAT_FQEMPTY 0x80
+#define LDPAA_DQ_STAT_HELDACTIVE 0x40
+#define LDPAA_DQ_STAT_FORCEELIGIBLE 0x20
+#define LDPAA_DQ_STAT_VALIDFRAME 0x10
+#define LDPAA_DQ_STAT_ODPVALID 0x04
+#define LDPAA_DQ_STAT_VOLATILE 0x02
+#define LDPAA_DQ_STAT_EXPIRED 0x01
+uint32_t ldpaa_dq_flags(const struct ldpaa_dq *);
+static inline int ldpaa_dq_is_pull(const struct ldpaa_dq *dq)
+{
+ return (int)(ldpaa_dq_flags(dq) & LDPAA_DQ_STAT_VOLATILE);
+}
+static inline int ldpaa_dq_is_pull_complete(
+ const struct ldpaa_dq *dq)
+{
+ return (int)(ldpaa_dq_flags(dq) & LDPAA_DQ_STAT_EXPIRED);
+}
+/* seqnum/odpid are valid only if VALIDFRAME and ODPVALID flags are TRUE */
+uint16_t ldpaa_dq_seqnum(const struct ldpaa_dq *);
+uint16_t ldpaa_dq_odpid(const struct ldpaa_dq *);
+uint32_t ldpaa_dq_fqid(const struct ldpaa_dq *);
+uint32_t ldpaa_dq_byte_count(const struct ldpaa_dq *);
+uint32_t ldpaa_dq_frame_count(const struct ldpaa_dq *);
+uint32_t ldpaa_dq_fqd_ctx_hi(const struct ldpaa_dq *);
+uint32_t ldpaa_dq_fqd_ctx_lo(const struct ldpaa_dq *);
+/* get the Frame Descriptor */
+const struct dpaa_fd *ldpaa_dq_fd(const struct ldpaa_dq *);
+
+#endif /* __FSL_DPAA_FD_H */
diff --git a/include/fsl-mc/fsl_dpbp.h b/include/fsl-mc/fsl_dpbp.h
new file mode 100644
index 0000000..7f0075c
--- /dev/null
+++ b/include/fsl-mc/fsl_dpbp.h
@@ -0,0 +1,143 @@
+/*
+ * Freescale Layerscape MC I/O wrapper
+ *
+ * Copyright (C) 2013-2015 Freescale Semiconductor, Inc.
+ * Author: German Rivera <German.Rivera@freescale.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+/*!
+ * @file fsl_dpbp.h
+ * @brief Data Path Buffer Pool API
+ */
+#ifndef __FSL_DPBP_H
+#define __FSL_DPBP_H
+
+/* DPBP Version */
+#define DPBP_VER_MAJOR 2
+#define DPBP_VER_MINOR 0
+
+/* Command IDs */
+#define DPBP_CMDID_CLOSE 0x800
+#define DPBP_CMDID_OPEN 0x804
+
+#define DPBP_CMDID_ENABLE 0x002
+#define DPBP_CMDID_DISABLE 0x003
+#define DPBP_CMDID_GET_ATTR 0x004
+#define DPBP_CMDID_RESET 0x005
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPBP_CMD_OPEN(cmd, dpbp_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpbp_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPBP_RSP_GET_ATTRIBUTES(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, attr->bpid); \
+ MC_RSP_OP(cmd, 0, 32, 32, int, attr->id);\
+ MC_RSP_OP(cmd, 1, 0, 16, uint16_t, attr->version.major);\
+ MC_RSP_OP(cmd, 1, 16, 16, uint16_t, attr->version.minor);\
+} while (0)
+
+/* Data Path Buffer Pool API
+ * Contains initialization APIs and runtime control APIs for DPBP
+ */
+
+struct fsl_mc_io;
+
+/**
+ * dpbp_open() - Open a control session for the specified object.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dpbp_id: DPBP unique ID
+ * @token: Returned token; use in subsequent API calls
+ *
+ * This function can be used to open a control session for an
+ * already created object; an object may have been declared in
+ * the DPL or by calling the dpbp_create function.
+ * This function returns a unique authentication token,
+ * associated with the specific object ID and the specific MC
+ * portal; this token must be used in all subsequent commands for
+ * this specific object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_open(struct fsl_mc_io *mc_io, int dpbp_id, uint16_t *token);
+
+/**
+ * dpbp_close() - Close the control session of the object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPBP object
+ *
+ * After this function is called, no further operations are
+ * allowed on the object without opening a new control session.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_close(struct fsl_mc_io *mc_io, uint16_t token);
+
+/**
+ * dpbp_enable() - Enable the DPBP.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPBP object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+
+int dpbp_enable(struct fsl_mc_io *mc_io, uint16_t token);
+
+/**
+ * dpbp_disable() - Disable the DPBP.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPBP object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_disable(struct fsl_mc_io *mc_io, uint16_t token);
+
+/**
+ * dpbp_reset() - Reset the DPBP, returns the object to initial state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPBP object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_reset(struct fsl_mc_io *mc_io, uint16_t token);
+
+/**
+ * struct dpbp_attr - Structure representing DPBP attributes
+ * @id: DPBP object ID
+ * @version: DPBP version
+ * @bpid: Hardware buffer pool ID; should be used as an argument in
+ * acquire/release operations on buffers
+ */
+struct dpbp_attr {
+ int id;
+ /**
+ * struct version - Structure representing DPBP version
+ * @major: DPBP major version
+ * @minor: DPBP minor version
+ */
+ struct {
+ uint16_t major;
+ uint16_t minor;
+ } version;
+ uint16_t bpid;
+};
+
+
+/**
+ * dpbp_get_attributes - Retrieve DPBP attributes.
+ *
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPBP object
+ * @attr: Returned object's attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_get_attributes(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpbp_attr *attr);
+
+/** @} */
+
+#endif /* __FSL_DPBP_H */
diff --git a/include/fsl-mc/fsl_dpio.h b/include/fsl-mc/fsl_dpio.h
new file mode 100644
index 0000000..e84b419
--- /dev/null
+++ b/include/fsl-mc/fsl_dpio.h
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2013-2015 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _FSL_DPIO_H
+#define _FSL_DPIO_H
+
+/* DPIO Version */
+#define DPIO_VER_MAJOR 2
+#define DPIO_VER_MINOR 1
+
+/* Command IDs */
+#define DPIO_CMDID_CLOSE 0x800
+#define DPIO_CMDID_OPEN 0x803
+
+#define DPIO_CMDID_ENABLE 0x002
+#define DPIO_CMDID_DISABLE 0x003
+#define DPIO_CMDID_GET_ATTR 0x004
+#define DPIO_CMDID_RESET 0x005
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_CMD_OPEN(cmd, dpio_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpio_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_RSP_GET_ATTR(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, int, attr->id);\
+ MC_RSP_OP(cmd, 0, 32, 16, uint16_t, attr->qbman_portal_id);\
+ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, attr->num_priorities);\
+ MC_RSP_OP(cmd, 0, 56, 4, enum dpio_channel_mode, attr->channel_mode);\
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, attr->qbman_portal_ce_paddr);\
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, attr->qbman_portal_ci_paddr);\
+ MC_RSP_OP(cmd, 3, 0, 16, uint16_t, attr->version.major);\
+ MC_RSP_OP(cmd, 3, 16, 16, uint16_t, attr->version.minor);\
+} while (0)
+
+/* Data Path I/O Portal API
+ * Contains initialization APIs and runtime control APIs for DPIO
+ */
+
+struct fsl_mc_io;
+/**
+ * dpio_open() - Open a control session for the specified object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dpio_id: DPIO unique ID
+ * @token: Returned token; use in subsequent API calls
+ *
+ * This function can be used to open a control session for an
+ * already created object; an object may have been declared in
+ * the DPL or by calling the dpio_create() function.
+ * This function returns a unique authentication token,
+ * associated with the specific object ID and the specific MC
+ * portal; this token must be used in all subsequent commands for
+ * this specific object.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_open(struct fsl_mc_io *mc_io, int dpio_id, uint16_t *token);
+
+/**
+ * dpio_open() - Open a control session for the specified object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dpio_id: DPIO unique ID
+ * @token: Returned token; use in subsequent API calls
+ *
+ * This function can be used to open a control session for an
+ * already created object; an object may have been declared in
+ * the DPL or by calling the dpio_create() function.
+ * This function returns a unique authentication token,
+ * associated with the specific object ID and the specific MC
+ * portal; this token must be used in all subsequent commands for
+ * this specific object.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_close(struct fsl_mc_io *mc_io, uint16_t token);
+
+/**
+ * enum dpio_channel_mode - DPIO notification channel mode
+ * @DPIO_NO_CHANNEL: No support for notification channel
+ * @DPIO_LOCAL_CHANNEL: Notifications on data availability can be received by a
+ * dedicated channel in the DPIO; user should point the queue's
+ * destination in the relevant interface to this DPIO
+ */
+enum dpio_channel_mode {
+ DPIO_NO_CHANNEL = 0,
+ DPIO_LOCAL_CHANNEL = 1,
+};
+
+/**
+ * dpio_enable() - Enable the DPIO, allow I/O portal operations.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPIO object
+ *
+ * Return: '0' on Success; Error code otherwise
+ */
+int dpio_enable(struct fsl_mc_io *mc_io, uint16_t token);
+
+/**
+ * dpio_disable() - Disable the DPIO, stop any I/O portal operation.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPIO object
+ *
+ * Return: '0' on Success; Error code otherwise
+ */
+int dpio_disable(struct fsl_mc_io *mc_io, uint16_t token);
+
+/**
+ * dpio_reset() - Reset the DPIO, returns the object to initial state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPIO object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_reset(struct fsl_mc_io *mc_io, uint16_t token);
+
+/**
+ * struct dpio_attr - Structure representing DPIO attributes
+ * @id: DPIO object ID
+ * @version: DPIO version
+ * @qbman_portal_ce_paddr: Physical address of the software portal
+ * cache-enabled area
+ * @qbman_portal_ci_paddr: Physical address of the software portal
+ * cache-inhibited area
+ * @qbman_portal_id: Software portal ID
+ * @channel_mode: Notification channel mode
+ * @num_priorities: Number of priorities for the notification channel (1-8);
+ * relevant only if 'channel_mode = DPIO_LOCAL_CHANNEL'
+ */
+struct dpio_attr {
+ int id;
+ /**
+ * struct version - DPIO version
+ * @major: DPIO major version
+ * @minor: DPIO minor version
+ */
+ struct {
+ uint16_t major;
+ uint16_t minor;
+ } version;
+ uint64_t qbman_portal_ce_paddr;
+ uint64_t qbman_portal_ci_paddr;
+ uint16_t qbman_portal_id;
+ enum dpio_channel_mode channel_mode;
+ uint8_t num_priorities;
+};
+
+/**
+ * dpio_get_attributes() - Retrieve DPIO attributes
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPIO object
+ * @attr: Returned object's attributes
+ *
+ * Return: '0' on Success; Error code otherwise
+ */
+int dpio_get_attributes(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpio_attr *attr);
+
+#endif /* _FSL_DPIO_H */
diff --git a/include/fsl-mc/fsl_dpmng.h b/include/fsl-mc/fsl_dpmng.h
index c2e1ddd..986e7c8 100644
--- a/include/fsl-mc/fsl_dpmng.h
+++ b/include/fsl-mc/fsl_dpmng.h
@@ -1,121 +1,44 @@
-/* Copyright 2014 Freescale Semiconductor Inc.
+/* Copyright 2013-2015 Freescale Semiconductor Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
-/*!
- * @file fsl_dpmng.h
- * @brief Management Complex General API
- */
-
#ifndef __FSL_DPMNG_H
#define __FSL_DPMNG_H
-/*!
- * @Group grp_dpmng Management Complex General API
- *
- * @brief Contains general API for the Management Complex firmware
- * @{
+/* Management Complex General API
+ * Contains general API for the Management Complex firmware
*/
struct fsl_mc_io;
/**
- * @brief Management Complex firmware version information
+ * Management Complex firmware version information
*/
-#define MC_VER_MAJOR 4
+#define MC_VER_MAJOR 6
#define MC_VER_MINOR 0
+/**
+ * struct mc_versoin
+ * @major: Major version number: incremented on API compatibility changes
+ * @minor: Minor version number: incremented on API additions (that are
+ * backward compatible); reset when major version is incremented
+ * @revision: Internal revision number: incremented on implementation changes
+ * and/or bug fixes that have no impact on API
+ */
struct mc_version {
uint32_t major;
- /*!< Major version number: incremented on API compatibility changes */
uint32_t minor;
- /*!< Minor version number: incremented on API additions (that are
- * backward compatible); reset when major version is incremented
- */
uint32_t revision;
- /*!< Internal revision number: incremented on implementation changes
- * and/or bug fixes that have no impact on API
- */
};
/**
- * @brief Retrieves the Management Complex firmware version information
- *
- * @param[in] mc_io Pointer to opaque I/O object
- * @param[out] mc_ver_info Pointer to version information structure
+ * mc_get_version() - Retrieves the Management Complex firmware
+ * version information
+ * @mc_io: Pointer to opaque I/O object
+ * @mc_ver_info: Returned version information structure
*
- * @returns '0' on Success; Error code otherwise.
+ * Return: '0' on Success; Error code otherwise.
*/
int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info);
-/**
- * @brief Resets an AIOP tile
- *
- * @param[in] mc_io Pointer to opaque I/O object
- * @param[in] container_id AIOP container ID
- * @param[in] aiop_tile_id AIOP tile ID to reset
- *
- * @returns '0' on Success; Error code otherwise.
- */
-int dpmng_reset_aiop(struct fsl_mc_io *mc_io,
- int container_id,
- int aiop_tile_id);
-
-/**
- * @brief Loads an image to AIOP tile
- *
- * @param[in] mc_io Pointer to opaque I/O object
- * @param[in] container_id AIOP container ID
- * @param[in] aiop_tile_id AIOP tile ID to reset
- * @param[in] img_iova I/O virtual address of AIOP ELF image
- * @param[in] img_size Size of AIOP ELF image in memory (in bytes)
- *
- * @returns '0' on Success; Error code otherwise.
- */
-int dpmng_load_aiop(struct fsl_mc_io *mc_io,
- int container_id,
- int aiop_tile_id,
- uint64_t img_iova,
- uint32_t img_size);
-
-/**
- * @brief AIOP run configuration
- */
-struct dpmng_aiop_run_cfg {
- uint32_t cores_mask;
- /*!< Mask of AIOP cores to run (core 0 in most significant bit) */
- uint64_t options;
- /*!< Execution options (currently none defined) */
-};
-
-/**
- * @brief Starts AIOP tile execution
- *
- * @param[in] mc_io Pointer to MC portal's I/O object
- * @param[in] container_id AIOP container ID
- * @param[in] aiop_tile_id AIOP tile ID to reset
- * @param[in] cfg AIOP run configuration
- *
- * @returns '0' on Success; Error code otherwise.
- */
-int dpmng_run_aiop(struct fsl_mc_io *mc_io,
- int container_id,
- int aiop_tile_id,
- const struct dpmng_aiop_run_cfg *cfg);
-
-/**
- * @brief Resets MC portal
- *
- * This function closes all object handles (tokens) that are currently
- * open in the MC portal on which the command is submitted. This allows
- * cleanup of stale handles that belong to non-functional user processes.
- *
- * @param[in] mc_io Pointer to MC portal's I/O object
- *
- * @returns '0' on Success; Error code otherwise.
- */
-int dpmng_reset_mc_portal(struct fsl_mc_io *mc_io);
-
-/** @} */
-
#endif /* __FSL_DPMNG_H */
diff --git a/include/fsl-mc/fsl_dpni.h b/include/fsl-mc/fsl_dpni.h
new file mode 100644
index 0000000..67c087d
--- /dev/null
+++ b/include/fsl-mc/fsl_dpni.h
@@ -0,0 +1,1093 @@
+/*
+ * Copyright (C) 2013-2015 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef _FSL_DPNI_H
+#define _FSL_DPNI_H
+
+/* DPNI Version */
+#define DPNI_VER_MAJOR 4
+#define DPNI_VER_MINOR 0
+
+/* Command IDs */
+#define DPNI_CMDID_OPEN 0x801
+#define DPNI_CMDID_CLOSE 0x800
+
+#define DPNI_CMDID_ENABLE 0x002
+#define DPNI_CMDID_DISABLE 0x003
+#define DPNI_CMDID_GET_ATTR 0x004
+#define DPNI_CMDID_RESET 0x005
+
+#define DPNI_CMDID_SET_POOLS 0x200
+#define DPNI_CMDID_GET_RX_BUFFER_LAYOUT 0x201
+#define DPNI_CMDID_SET_RX_BUFFER_LAYOUT 0x202
+#define DPNI_CMDID_GET_TX_BUFFER_LAYOUT 0x203
+#define DPNI_CMDID_SET_TX_BUFFER_LAYOUT 0x204
+#define DPNI_CMDID_SET_TX_CONF_BUFFER_LAYOUT 0x205
+#define DPNI_CMDID_GET_TX_CONF_BUFFER_LAYOUT 0x206
+
+#define DPNI_CMDID_GET_QDID 0x210
+#define DPNI_CMDID_GET_TX_DATA_OFFSET 0x212
+#define DPNI_CMDID_GET_COUNTER 0x213
+#define DPNI_CMDID_SET_COUNTER 0x214
+#define DPNI_CMDID_GET_LINK_STATE 0x215
+#define DPNI_CMDID_SET_LINK_CFG 0x21A
+
+#define DPNI_CMDID_SET_PRIM_MAC 0x224
+#define DPNI_CMDID_GET_PRIM_MAC 0x225
+#define DPNI_CMDID_ADD_MAC_ADDR 0x226
+#define DPNI_CMDID_REMOVE_MAC_ADDR 0x227
+
+#define DPNI_CMDID_SET_TX_FLOW 0x236
+#define DPNI_CMDID_GET_TX_FLOW 0x237
+#define DPNI_CMDID_SET_RX_FLOW 0x238
+#define DPNI_CMDID_GET_RX_FLOW 0x239
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_OPEN(cmd, dpni_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpni_id)
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_POOLS(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, cfg->num_dpbp); \
+ MC_CMD_OP(cmd, 0, 32, 32, int, cfg->pools[0].dpbp_id); \
+ MC_CMD_OP(cmd, 4, 32, 16, uint16_t, cfg->pools[0].buffer_size);\
+ MC_CMD_OP(cmd, 1, 0, 32, int, cfg->pools[1].dpbp_id); \
+ MC_CMD_OP(cmd, 4, 48, 16, uint16_t, cfg->pools[1].buffer_size);\
+ MC_CMD_OP(cmd, 1, 32, 32, int, cfg->pools[2].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 0, 16, uint16_t, cfg->pools[2].buffer_size);\
+ MC_CMD_OP(cmd, 2, 0, 32, int, cfg->pools[3].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 16, 16, uint16_t, cfg->pools[3].buffer_size);\
+ MC_CMD_OP(cmd, 2, 32, 32, int, cfg->pools[4].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 32, 16, uint16_t, cfg->pools[4].buffer_size);\
+ MC_CMD_OP(cmd, 3, 0, 32, int, cfg->pools[5].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 48, 16, uint16_t, cfg->pools[5].buffer_size);\
+ MC_CMD_OP(cmd, 3, 32, 32, int, cfg->pools[6].dpbp_id); \
+ MC_CMD_OP(cmd, 6, 0, 16, uint16_t, cfg->pools[6].buffer_size);\
+ MC_CMD_OP(cmd, 4, 0, 32, int, cfg->pools[7].dpbp_id); \
+ MC_CMD_OP(cmd, 6, 16, 16, uint16_t, cfg->pools[7].buffer_size);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_ATTR(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, int, attr->id);\
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, attr->max_tcs); \
+ MC_RSP_OP(cmd, 0, 40, 8, uint8_t, attr->max_senders); \
+ MC_RSP_OP(cmd, 0, 48, 8, enum net_prot, attr->start_hdr); \
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, attr->options); \
+ MC_RSP_OP(cmd, 2, 0, 8, uint8_t, attr->max_unicast_filters); \
+ MC_RSP_OP(cmd, 2, 8, 8, uint8_t, attr->max_multicast_filters);\
+ MC_RSP_OP(cmd, 2, 16, 8, uint8_t, attr->max_vlan_filters); \
+ MC_RSP_OP(cmd, 2, 24, 8, uint8_t, attr->max_qos_entries); \
+ MC_RSP_OP(cmd, 2, 32, 8, uint8_t, attr->max_qos_key_size); \
+ MC_RSP_OP(cmd, 2, 40, 8, uint8_t, attr->max_dist_key_size); \
+ MC_RSP_OP(cmd, 3, 0, 8, uint8_t, attr->max_dist_per_tc[0]); \
+ MC_RSP_OP(cmd, 3, 8, 8, uint8_t, attr->max_dist_per_tc[1]); \
+ MC_RSP_OP(cmd, 3, 16, 8, uint8_t, attr->max_dist_per_tc[2]); \
+ MC_RSP_OP(cmd, 3, 24, 8, uint8_t, attr->max_dist_per_tc[3]); \
+ MC_RSP_OP(cmd, 3, 32, 8, uint8_t, attr->max_dist_per_tc[4]); \
+ MC_RSP_OP(cmd, 3, 40, 8, uint8_t, attr->max_dist_per_tc[5]); \
+ MC_RSP_OP(cmd, 3, 48, 8, uint8_t, attr->max_dist_per_tc[6]); \
+ MC_RSP_OP(cmd, 3, 56, 8, uint8_t, attr->max_dist_per_tc[7]); \
+ MC_RSP_OP(cmd, 4, 0, 16, uint16_t, \
+ attr->ipr_cfg.max_reass_frm_size); \
+ MC_RSP_OP(cmd, 4, 16, 16, uint16_t, \
+ attr->ipr_cfg.min_frag_size_ipv4); \
+ MC_RSP_OP(cmd, 4, 32, 16, uint16_t, \
+ attr->ipr_cfg.min_frag_size_ipv6); \
+ MC_RSP_OP(cmd, 5, 0, 16, uint16_t, \
+ attr->ipr_cfg.max_open_frames_ipv4); \
+ MC_RSP_OP(cmd, 5, 16, 16, uint16_t, \
+ attr->ipr_cfg.max_open_frames_ipv6); \
+ MC_RSP_OP(cmd, 5, 32, 16, uint16_t, attr->version.major);\
+ MC_RSP_OP(cmd, 5, 48, 16, uint16_t, attr->version.minor);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_RX_BUFFER_LAYOUT(cmd, layout) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, layout->private_data_size); \
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, layout->data_align); \
+ MC_RSP_OP(cmd, 1, 0, 1, int, layout->pass_timestamp); \
+ MC_RSP_OP(cmd, 1, 1, 1, int, layout->pass_parser_result); \
+ MC_RSP_OP(cmd, 1, 2, 1, int, layout->pass_frame_status); \
+ MC_RSP_OP(cmd, 1, 16, 16, uint16_t, layout->data_head_room); \
+ MC_RSP_OP(cmd, 1, 32, 16, uint16_t, layout->data_tail_room); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_RX_BUFFER_LAYOUT(cmd, layout) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 16, uint16_t, layout->private_data_size); \
+ MC_CMD_OP(cmd, 0, 16, 16, uint16_t, layout->data_align); \
+ MC_CMD_OP(cmd, 0, 32, 32, uint32_t, layout->options); \
+ MC_CMD_OP(cmd, 1, 0, 1, int, layout->pass_timestamp); \
+ MC_CMD_OP(cmd, 1, 1, 1, int, layout->pass_parser_result); \
+ MC_CMD_OP(cmd, 1, 2, 1, int, layout->pass_frame_status); \
+ MC_CMD_OP(cmd, 1, 16, 16, uint16_t, layout->data_head_room); \
+ MC_CMD_OP(cmd, 1, 32, 16, uint16_t, layout->data_tail_room); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_TX_BUFFER_LAYOUT(cmd, layout) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, layout->private_data_size); \
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, layout->data_align); \
+ MC_RSP_OP(cmd, 1, 0, 1, int, layout->pass_timestamp); \
+ MC_RSP_OP(cmd, 1, 1, 1, int, layout->pass_parser_result); \
+ MC_RSP_OP(cmd, 1, 2, 1, int, layout->pass_frame_status); \
+ MC_RSP_OP(cmd, 1, 16, 16, uint16_t, layout->data_head_room); \
+ MC_RSP_OP(cmd, 1, 32, 16, uint16_t, layout->data_tail_room); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_TX_BUFFER_LAYOUT(cmd, layout) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 16, uint16_t, layout->private_data_size); \
+ MC_CMD_OP(cmd, 0, 16, 16, uint16_t, layout->data_align); \
+ MC_CMD_OP(cmd, 0, 32, 32, uint32_t, layout->options); \
+ MC_CMD_OP(cmd, 1, 0, 1, int, layout->pass_timestamp); \
+ MC_CMD_OP(cmd, 1, 1, 1, int, layout->pass_parser_result); \
+ MC_CMD_OP(cmd, 1, 2, 1, int, layout->pass_frame_status); \
+ MC_CMD_OP(cmd, 1, 16, 16, uint16_t, layout->data_head_room); \
+ MC_CMD_OP(cmd, 1, 32, 16, uint16_t, layout->data_tail_room); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_TX_CONF_BUFFER_LAYOUT(cmd, layout) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, layout->private_data_size); \
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, layout->data_align); \
+ MC_RSP_OP(cmd, 1, 0, 1, int, layout->pass_timestamp); \
+ MC_RSP_OP(cmd, 1, 1, 1, int, layout->pass_parser_result); \
+ MC_RSP_OP(cmd, 1, 2, 1, int, layout->pass_frame_status); \
+ MC_RSP_OP(cmd, 1, 16, 16, uint16_t, layout->data_head_room); \
+ MC_RSP_OP(cmd, 1, 32, 16, uint16_t, layout->data_tail_room); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_TX_CONF_BUFFER_LAYOUT(cmd, layout) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 16, uint16_t, layout->private_data_size); \
+ MC_CMD_OP(cmd, 0, 16, 16, uint16_t, layout->data_align); \
+ MC_CMD_OP(cmd, 0, 32, 32, uint32_t, layout->options); \
+ MC_CMD_OP(cmd, 1, 0, 1, int, layout->pass_timestamp); \
+ MC_CMD_OP(cmd, 1, 1, 1, int, layout->pass_parser_result); \
+ MC_CMD_OP(cmd, 1, 2, 1, int, layout->pass_frame_status); \
+ MC_CMD_OP(cmd, 1, 16, 16, uint16_t, layout->data_head_room); \
+ MC_CMD_OP(cmd, 1, 32, 16, uint16_t, layout->data_tail_room); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_QDID(cmd, qdid) \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, qdid)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_TX_DATA_OFFSET(cmd, data_offset) \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, data_offset)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_GET_COUNTER(cmd, counter) \
+ MC_CMD_OP(cmd, 0, 0, 16, enum dpni_counter, counter)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_COUNTER(cmd, value) \
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, value)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_COUNTER(cmd, counter, value) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 16, enum dpni_counter, counter); \
+ MC_CMD_OP(cmd, 1, 0, 64, uint64_t, value); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_LINK_CFG(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 1, 0, 64, uint64_t, cfg->rate);\
+ MC_CMD_OP(cmd, 2, 0, 64, uint64_t, cfg->options);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_LINK_STATE(cmd, state) \
+do { \
+ MC_RSP_OP(cmd, 0, 32, 1, int, state->up);\
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, state->rate);\
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, state->options);\
+} while (0)
+
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_PRIMARY_MAC_ADDR(cmd, mac_addr) \
+do { \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \
+ MC_CMD_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \
+ MC_CMD_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_PRIMARY_MAC_ADDR(cmd, mac_addr) \
+do { \
+ MC_RSP_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \
+ MC_RSP_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \
+ MC_RSP_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \
+ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \
+ MC_RSP_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_ADD_MAC_ADDR(cmd, mac_addr) \
+do { \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \
+ MC_CMD_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \
+ MC_CMD_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_REMOVE_MAC_ADDR(cmd, mac_addr) \
+do { \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \
+ MC_CMD_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \
+ MC_CMD_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_TX_FLOW(cmd, flow_id, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, int, \
+ cfg->conf_err_cfg.queue_cfg.dest_cfg.dest_id);\
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, \
+ cfg->conf_err_cfg.queue_cfg.dest_cfg.priority);\
+ MC_CMD_OP(cmd, 0, 40, 2, enum dpni_dest, \
+ cfg->conf_err_cfg.queue_cfg.dest_cfg.dest_type);\
+ MC_CMD_OP(cmd, 0, 42, 1, int, cfg->conf_err_cfg.errors_only);\
+ MC_CMD_OP(cmd, 0, 43, 1, int, cfg->l3_chksum_gen);\
+ MC_CMD_OP(cmd, 0, 44, 1, int, cfg->l4_chksum_gen);\
+ MC_CMD_OP(cmd, 0, 45, 1, int, \
+ cfg->conf_err_cfg.use_default_queue);\
+ MC_CMD_OP(cmd, 0, 48, 16, uint16_t, flow_id);\
+ MC_CMD_OP(cmd, 1, 0, 64, uint64_t, \
+ cfg->conf_err_cfg.queue_cfg.user_ctx);\
+ MC_CMD_OP(cmd, 2, 0, 32, uint32_t, cfg->options);\
+ MC_CMD_OP(cmd, 2, 32, 32, uint32_t, \
+ cfg->conf_err_cfg.queue_cfg.options);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_SET_TX_FLOW(cmd, flow_id) \
+ MC_RSP_OP(cmd, 0, 48, 16, uint16_t, flow_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_GET_TX_FLOW(cmd, flow_id) \
+ MC_CMD_OP(cmd, 0, 48, 16, uint16_t, flow_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_TX_FLOW(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, int, \
+ attr->conf_err_attr.queue_attr.dest_cfg.dest_id);\
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, \
+ attr->conf_err_attr.queue_attr.dest_cfg.priority);\
+ MC_RSP_OP(cmd, 0, 40, 2, enum dpni_dest, \
+ attr->conf_err_attr.queue_attr.dest_cfg.dest_type);\
+ MC_RSP_OP(cmd, 0, 42, 1, int, attr->conf_err_attr.errors_only);\
+ MC_RSP_OP(cmd, 0, 43, 1, int, attr->l3_chksum_gen);\
+ MC_RSP_OP(cmd, 0, 44, 1, int, attr->l4_chksum_gen);\
+ MC_RSP_OP(cmd, 0, 45, 1, int, \
+ attr->conf_err_attr.use_default_queue);\
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, \
+ attr->conf_err_attr.queue_attr.user_ctx);\
+ MC_RSP_OP(cmd, 2, 32, 32, uint32_t, \
+ attr->conf_err_attr.queue_attr.fqid);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_RX_FLOW(cmd, tc_id, flow_id, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, int, cfg->dest_cfg.dest_id); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, cfg->dest_cfg.priority);\
+ MC_CMD_OP(cmd, 0, 40, 2, enum dpni_dest, cfg->dest_cfg.dest_type);\
+ MC_CMD_OP(cmd, 0, 48, 16, uint16_t, flow_id); \
+ MC_CMD_OP(cmd, 1, 0, 64, uint64_t, cfg->user_ctx); \
+ MC_CMD_OP(cmd, 2, 16, 8, uint8_t, tc_id); \
+ MC_CMD_OP(cmd, 2, 32, 32, uint32_t, cfg->options); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_GET_RX_FLOW(cmd, tc_id, flow_id) \
+do { \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, tc_id); \
+ MC_CMD_OP(cmd, 0, 48, 16, uint16_t, flow_id); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_RX_FLOW(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, int, attr->dest_cfg.dest_id); \
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, attr->dest_cfg.priority);\
+ MC_RSP_OP(cmd, 0, 40, 2, enum dpni_dest, attr->dest_cfg.dest_type); \
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, attr->user_ctx); \
+ MC_RSP_OP(cmd, 2, 32, 32, uint32_t, attr->fqid); \
+} while (0)
+
+enum net_prot {
+ NET_PROT_NONE = 0,
+ NET_PROT_PAYLOAD,
+ NET_PROT_ETH,
+ NET_PROT_VLAN,
+ NET_PROT_IPV4,
+ NET_PROT_IPV6,
+ NET_PROT_IP,
+ NET_PROT_TCP,
+ NET_PROT_UDP,
+ NET_PROT_UDP_LITE,
+ NET_PROT_IPHC,
+ NET_PROT_SCTP,
+ NET_PROT_SCTP_CHUNK_DATA,
+ NET_PROT_PPPOE,
+ NET_PROT_PPP,
+ NET_PROT_PPPMUX,
+ NET_PROT_PPPMUX_SUBFRM,
+ NET_PROT_L2TPV2,
+ NET_PROT_L2TPV3_CTRL,
+ NET_PROT_L2TPV3_SESS,
+ NET_PROT_LLC,
+ NET_PROT_LLC_SNAP,
+ NET_PROT_NLPID,
+ NET_PROT_SNAP,
+ NET_PROT_MPLS,
+ NET_PROT_IPSEC_AH,
+ NET_PROT_IPSEC_ESP,
+ NET_PROT_UDP_ENC_ESP, /* RFC 3948 */
+ NET_PROT_MACSEC,
+ NET_PROT_GRE,
+ NET_PROT_MINENCAP,
+ NET_PROT_DCCP,
+ NET_PROT_ICMP,
+ NET_PROT_IGMP,
+ NET_PROT_ARP,
+ NET_PROT_CAPWAP_DATA,
+ NET_PROT_CAPWAP_CTRL,
+ NET_PROT_RFC2684,
+ NET_PROT_ICMPV6,
+ NET_PROT_FCOE,
+ NET_PROT_FIP,
+ NET_PROT_ISCSI,
+ NET_PROT_GTP,
+ NET_PROT_USER_DEFINED_L2,
+ NET_PROT_USER_DEFINED_L3,
+ NET_PROT_USER_DEFINED_L4,
+ NET_PROT_USER_DEFINED_L5,
+ NET_PROT_USER_DEFINED_SHIM1,
+ NET_PROT_USER_DEFINED_SHIM2,
+
+ NET_PROT_DUMMY_LAST
+};
+
+/* Data Path Network Interface API
+ * Contains initialization APIs and runtime control APIs for DPNI
+ */
+
+struct fsl_mc_io;
+
+/* General DPNI macros */
+
+/* Maximum number of traffic classes */
+#define DPNI_MAX_TC 8
+/* Maximum number of buffer pools per DPNI */
+#define DPNI_MAX_DPBP 8
+
+/* All traffic classes considered; see dpni_set_rx_flow() */
+#define DPNI_ALL_TCS (uint8_t)(-1)
+/* All flows within traffic class considered; see dpni_set_rx_flow() */
+#define DPNI_ALL_TC_FLOWS (uint16_t)(-1)
+/* Generate new flow ID; see dpni_set_tx_flow() */
+#define DPNI_NEW_FLOW_ID (uint16_t)(-1)
+
+/**
+ * dpni_open() - Open a control session for the specified object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dpni_id: DPNI unique ID
+ * @token: Returned token; use in subsequent API calls
+ *
+ * This function can be used to open a control session for an
+ * already created object; an object may have been declared in
+ * the DPL or by calling the dpni_create() function.
+ * This function returns a unique authentication token,
+ * associated with the specific object ID and the specific MC
+ * portal; this token must be used in all subsequent commands for
+ * this specific object.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_open(struct fsl_mc_io *mc_io, int dpni_id, uint16_t *token);
+
+/**
+ * dpni_close() - Close the control session of the object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ *
+ * After this function is called, no further operations are
+ * allowed on the object without opening a new control session.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_close(struct fsl_mc_io *mc_io, uint16_t token);
+
+/**
+ * struct dpni_ipr_cfg - Structure representing IP reassembly configuration
+ * @max_reass_frm_size: Maximum size of the reassembled frame
+ * @min_frag_size_ipv4: Minimum fragment size of IPv4 fragments
+ * @min_frag_size_ipv6: Minimum fragment size of IPv6 fragments
+ * @max_open_frames_ipv4: Maximum concurrent IPv4 packets in reassembly process
+ * @max_open_frames_ipv6: Maximum concurrent IPv6 packets in reassembly process
+ */
+struct dpni_ipr_cfg {
+ uint16_t max_reass_frm_size;
+ uint16_t min_frag_size_ipv4;
+ uint16_t min_frag_size_ipv6;
+ uint16_t max_open_frames_ipv4;
+ uint16_t max_open_frames_ipv6;
+};
+
+/**
+ * struct dpni_pools_cfg - Structure representing buffer pools configuration
+ * @num_dpbp: Number of DPBPs
+ * @pools: Array of buffer pools parameters; The number of valid entries
+ * must match 'num_dpbp' value
+ */
+struct dpni_pools_cfg {
+ uint8_t num_dpbp;
+ /**
+ * struct pools - Buffer pools parameters
+ * @dpbp_id: DPBP object ID
+ * @buffer_size: Buffer size
+ */
+ struct {
+ int dpbp_id;
+ uint16_t buffer_size;
+ } pools[DPNI_MAX_DPBP];
+};
+
+/**
+ * dpni_set_pools() - Set buffer pools configuration
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @cfg: Buffer pools configuration
+ *
+ * mandatory for DPNI operation
+ * warning:Allowed only when DPNI is disabled
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_pools(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dpni_pools_cfg *cfg);
+
+/**
+ * dpni_enable() - Enable the DPNI, allow sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_enable(struct fsl_mc_io *mc_io, uint16_t token);
+
+/**
+ * dpni_disable() - Disable the DPNI, stop sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_disable(struct fsl_mc_io *mc_io, uint16_t token);
+
+
+/**
+ * @dpni_reset() - Reset the DPNI, returns the object to initial state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_reset(struct fsl_mc_io *mc_io, uint16_t token);
+
+/**
+ * struct dpni_attr - Structure representing DPNI attributes
+ * @id: DPNI object ID
+ * @version: DPNI version
+ * @start_hdr: Indicates the packet starting header for parsing
+ * @options: Mask of available options; reflects the value as was given in
+ * object's creation
+ * @max_senders: Maximum number of different senders; used as the number
+ * of dedicated Tx flows;
+ * @max_tcs: Maximum number of traffic classes (for both Tx and Rx)
+ * @max_dist_per_tc: Maximum distribution size per Rx traffic class;
+ * Set to the required value minus 1
+ * @max_unicast_filters: Maximum number of unicast filters
+ * @max_multicast_filters: Maximum number of multicast filters
+ * @max_vlan_filters: Maximum number of VLAN filters
+ * @max_qos_entries: if 'max_tcs > 1', declares the maximum entries in QoS table
+ * @max_qos_key_size: Maximum key size for the QoS look-up
+ * @max_dist_key_size: Maximum key size for the distribution look-up
+ * @ipr_cfg: IP reassembly configuration
+ */
+struct dpni_attr {
+ int id;
+ /**
+ * struct version - DPNI version
+ * @major: DPNI major version
+ * @minor: DPNI minor version
+ */
+ struct {
+ uint16_t major;
+ uint16_t minor;
+ } version;
+ enum net_prot start_hdr;
+ uint64_t options;
+ uint8_t max_senders;
+ uint8_t max_tcs;
+ uint8_t max_dist_per_tc[DPNI_MAX_TC];
+ uint8_t max_unicast_filters;
+ uint8_t max_multicast_filters;
+ uint8_t max_vlan_filters;
+ uint8_t max_qos_entries;
+ uint8_t max_qos_key_size;
+ uint8_t max_dist_key_size;
+ struct dpni_ipr_cfg ipr_cfg;
+};
+/**
+ * dpni_get_attributes() - Retrieve DPNI attributes.
+ * @mc_io: Pointer to MC portal's I/O objec
+ * @token: Token of DPNI object
+ * @attr: Returned object's attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_attributes(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpni_attr *attr);
+
+/* DPNI buffer layout modification options */
+
+/* Select to modify the time-stamp setting */
+#define DPNI_BUF_LAYOUT_OPT_TIMESTAMP 0x00000001
+/* Select to modify the parser-result setting; not applicable for Tx */
+#define DPNI_BUF_LAYOUT_OPT_PARSER_RESULT 0x00000002
+/* Select to modify the frame-status setting */
+#define DPNI_BUF_LAYOUT_OPT_FRAME_STATUS 0x00000004
+/* Select to modify the private-data-size setting */
+#define DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE 0x00000008
+/* Select to modify the data-alignment setting */
+#define DPNI_BUF_LAYOUT_OPT_DATA_ALIGN 0x00000010
+/* Select to modify the data-head-room setting */
+#define DPNI_BUF_LAYOUT_OPT_DATA_HEAD_ROOM 0x00000020
+/*!< Select to modify the data-tail-room setting */
+#define DPNI_BUF_LAYOUT_OPT_DATA_TAIL_ROOM 0x00000040
+
+/**
+ * struct dpni_buffer_layout - Structure representing DPNI buffer layout
+ * @options: Flags representing the suggested modifications to the buffer
+ * layout; Use any combination of 'DPNI_BUF_LAYOUT_OPT_<X>' flags
+ * @pass_timestamp: Pass timestamp value
+ * @pass_parser_result: Pass parser results
+ * @pass_frame_status: Pass frame status
+ * @private_data_size: Size kept for private data (in bytes)
+ * @data_align: Data alignment
+ * @data_head_room: Data head room
+ * @data_tail_room: Data tail room
+ */
+struct dpni_buffer_layout {
+ uint32_t options;
+ int pass_timestamp;
+ int pass_parser_result;
+ int pass_frame_status;
+ uint16_t private_data_size;
+ uint16_t data_align;
+ uint16_t data_head_room;
+ uint16_t data_tail_room;
+};
+
+/**
+ * dpni_get_rx_buffer_layout() - Retrieve Rx buffer layout attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @layout: Returns buffer layout attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_rx_buffer_layout(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpni_buffer_layout *layout);
+/**
+ * dpni_set_rx_buffer_layout() - Set Rx buffer layout configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @layout: Buffer layout configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_set_rx_buffer_layout(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dpni_buffer_layout *layout);
+
+/**
+ * dpni_get_tx_buffer_layout() - Retrieve Tx buffer layout attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @layout: Returns buffer layout attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_tx_buffer_layout(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpni_buffer_layout *layout);
+
+/**
+ * @brief Set Tx buffer layout configuration.
+ *
+ * @param[in] mc_io Pointer to MC portal's I/O object
+ * @param[in] token Token of DPNI object
+ * @param[in] layout Buffer layout configuration
+ *
+ * @returns '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_set_tx_buffer_layout(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dpni_buffer_layout *layout);
+/**
+ * dpni_get_tx_conf_buffer_layout() - Retrieve Tx confirmation buffer layout
+ * attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @layout: Returns buffer layout attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_tx_conf_buffer_layout(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpni_buffer_layout *layout);
+/**
+ * dpni_set_tx_conf_buffer_layout() - Set Tx confirmation buffer layout
+ * configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @layout: Buffer layout configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_set_tx_conf_buffer_layout(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dpni_buffer_layout *layout);
+/**
+ * dpni_get_spid() - Get the AIOP storage profile ID associated with the DPNI
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @spid: Returned aiop storage-profile ID
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Only relevant for DPNI that belongs to AIOP container.
+ */
+int dpni_get_qdid(struct fsl_mc_io *mc_io, uint16_t token, uint16_t *qdid);
+
+/**
+ * dpni_get_tx_data_offset() - Get the Tx data offset (from start of buffer)
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @data_offset: Tx data offset (from start of buffer)
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_tx_data_offset(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ uint16_t *data_offset);
+
+/**
+ * enum dpni_counter - DPNI counter types
+ * @DPNI_CNT_ING_FRAME: Counts ingress frames
+ * @DPNI_CNT_ING_BYTE: Counts ingress bytes
+ * @DPNI_CNT_ING_FRAME_DROP: Counts ingress frames dropped due to explicit
+ * 'drop' setting
+ * @DPNI_CNT_ING_FRAME_DISCARD: Counts ingress frames discarded due to errors
+ * @DPNI_CNT_ING_MCAST_FRAME: Counts ingress multicast frames
+ * @DPNI_CNT_ING_MCAST_BYTE: Counts ingress multicast bytes
+ * @DPNI_CNT_ING_BCAST_FRAME: Counts ingress broadcast frames
+ * @DPNI_CNT_ING_BCAST_BYTES: Counts ingress broadcast bytes
+ * @DPNI_CNT_EGR_FRAME: Counts egress frames
+ * @DPNI_CNT_EGR_BYTE: Counts egress bytes
+ * @DPNI_CNT_EGR_FRAME_DISCARD: Counts egress frames discarded due to errors
+ */
+enum dpni_counter {
+ DPNI_CNT_ING_FRAME = 0x0,
+ DPNI_CNT_ING_BYTE = 0x1,
+ DPNI_CNT_ING_FRAME_DROP = 0x2,
+ DPNI_CNT_ING_FRAME_DISCARD = 0x3,
+ DPNI_CNT_ING_MCAST_FRAME = 0x4,
+ DPNI_CNT_ING_MCAST_BYTE = 0x5,
+ DPNI_CNT_ING_BCAST_FRAME = 0x6,
+ DPNI_CNT_ING_BCAST_BYTES = 0x7,
+ DPNI_CNT_EGR_FRAME = 0x8,
+ DPNI_CNT_EGR_BYTE = 0x9,
+ DPNI_CNT_EGR_FRAME_DISCARD = 0xa
+};
+
+/**
+ * dpni_get_counter() - Read a specific DPNI counter
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @counter: The requested counter
+ * @value: Returned counter's current value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_counter(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ enum dpni_counter counter,
+ uint64_t *value);
+
+/**
+ * dpni_set_counter() - Set (or clear) a specific DPNI counter
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @counter: The requested counter
+ * @value: New counter value; typically pass '0' for resetting
+ * the counter.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_counter(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ enum dpni_counter counter,
+ uint64_t value);
+/**
+ * struct - Structure representing DPNI link configuration
+ * @rate: Rate
+ * @options: Mask of available options; use 'DPNI_LINK_OPT_<X>' values
+ */
+struct dpni_link_cfg {
+ uint64_t rate;
+ uint64_t options;
+};
+
+/**
+ * dpni_set_link_cfg() - set the link configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @cfg: Link configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_link_cfg(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpni_link_cfg *cfg);
+
+/**
+ * struct dpni_link_state - Structure representing DPNI link state
+ * @rate: Rate
+ * @options: Mask of available options; use 'DPNI_LINK_OPT_<X>' values
+ * @up: Link state; '0' for down, '1' for up
+ */
+struct dpni_link_state {
+ uint64_t rate;
+ uint64_t options;
+ int up;
+};
+
+/**
+ * dpni_get_link_state() - Return the link state (either up or down)
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @state: Returned link state;
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_link_state(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpni_link_state *state);
+
+/**
+ * dpni_set_primary_mac_addr() - Set the primary MAC address
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @mac_addr: MAC address to set as primary address
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const uint8_t mac_addr[6]);
+/**
+ * dpni_get_primary_mac_addr() - Get the primary MAC address
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @mac_addr: Returned MAC address
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ uint8_t mac_addr[6]);
+/**
+ * dpni_add_mac_addr() - Add MAC address filter
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @mac_addr: MAC address to add
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_add_mac_addr(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const uint8_t mac_addr[6]);
+
+/**
+ * dpni_remove_mac_addr() - Remove MAC address filter
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @mac_addr: MAC address to remove
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_remove_mac_addr(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const uint8_t mac_addr[6]);
+
+/**
+ * enum dpni_dest - DPNI destination types
+ * DPNI_DEST_NONE: Unassigned destination; The queue is set in parked mode and
+ * does not generate FQDAN notifications; user is expected to
+ * dequeue from the queue based on polling or other user-defined
+ * method
+ * @DPNI_DEST_DPIO: The queue is set in schedule mode and generates FQDAN
+ * notifications to the specified DPIO; user is expected to dequeue
+ * from the queue only after notification is received
+ * @DPNI_DEST_DPCON: The queue is set in schedule mode and does not generate
+ * FQDAN notifications, but is connected to the specified DPCON
+ * object; user is expected to dequeue from the DPCON channel
+ */
+enum dpni_dest {
+ DPNI_DEST_NONE = 0,
+ DPNI_DEST_DPIO = 1,
+ DPNI_DEST_DPCON = 2
+};
+
+/**
+ * struct dpni_dest_cfg - Structure representing DPNI destination parameters
+ * @dest_type: Destination type
+ * @dest_id: Either DPIO ID or DPCON ID, depending on the destination type
+ * @priority: Priority selection within the DPIO or DPCON channel; valid values
+ * are 0-1 or 0-7, depending on the number of priorities in that
+ * channel; not relevant for 'DPNI_DEST_NONE' option
+ */
+struct dpni_dest_cfg {
+ enum dpni_dest dest_type;
+ int dest_id;
+ uint8_t priority;
+};
+
+/* DPNI queue modification options */
+
+/* Select to modify the user's context associated with the queue */
+#define DPNI_QUEUE_OPT_USER_CTX 0x00000001
+/* Select to modify the queue's destination */
+#define DPNI_QUEUE_OPT_DEST 0x00000002
+
+/**
+ * struct dpni_queue_cfg - Structure representing queue configuration
+ * @options: Flags representing the suggested modifications to the queue;
+ * Use any combination of 'DPNI_QUEUE_OPT_<X>' flags
+ * @user_ctx: User context value provided in the frame descriptor of each
+ * dequeued frame; valid only if 'DPNI_QUEUE_OPT_USER_CTX'
+ * is contained in 'options'
+ * @dest_cfg: Queue destination parameters;
+ * valid only if 'DPNI_QUEUE_OPT_DEST' is contained in 'options'
+ */
+struct dpni_queue_cfg {
+ uint32_t options;
+ uint64_t user_ctx;
+ struct dpni_dest_cfg dest_cfg;
+};
+
+/**
+ * struct dpni_queue_attr - Structure representing queue attributes
+ * @user_ctx: User context value provided in the frame descriptor of each
+ * dequeued frame
+ * @dest_cfg: Queue destination configuration
+ * @fqid: Virtual fqid value to be used for dequeue operations
+ */
+struct dpni_queue_attr {
+ uint64_t user_ctx;
+ struct dpni_dest_cfg dest_cfg;
+ uint32_t fqid;
+};
+
+/* DPNI Tx flow modification options */
+
+/* Select to modify the settings for dedicate Tx confirmation/error */
+#define DPNI_TX_FLOW_OPT_TX_CONF_ERROR 0x00000001
+/*!< Select to modify the Tx confirmation and/or error setting */
+#define DPNI_TX_FLOW_OPT_ONLY_TX_ERROR 0x00000002
+/*!< Select to modify the queue configuration */
+#define DPNI_TX_FLOW_OPT_QUEUE 0x00000004
+/*!< Select to modify the L3 checksum generation setting */
+#define DPNI_TX_FLOW_OPT_L3_CHKSUM_GEN 0x00000010
+/*!< Select to modify the L4 checksum generation setting */
+#define DPNI_TX_FLOW_OPT_L4_CHKSUM_GEN 0x00000020
+
+/**
+ * struct dpni_tx_flow_cfg - Structure representing Tx flow configuration
+ * @options: Flags representing the suggested modifications to the Tx flow;
+ * Use any combination 'DPNI_TX_FLOW_OPT_<X>' flags
+ * @conf_err_cfg: Tx confirmation and error configuration; these settings are
+ * ignored if 'DPNI_OPT_PRIVATE_TX_CONF_ERROR_DISABLED' was set at
+ * DPNI creation
+ * @l3_chksum_gen: Set to '1' to enable L3 checksum generation; '0' to disable;
+ * valid only if 'DPNI_TX_FLOW_OPT_L3_CHKSUM_GEN' is contained in
+ * 'options'
+ * @l4_chksum_gen: Set to '1' to enable L4 checksum generation; '0' to disable;
+ * valid only if 'DPNI_TX_FLOW_OPT_L4_CHKSUM_GEN' is contained in
+ * 'options'
+ */
+struct dpni_tx_flow_cfg {
+ uint32_t options;
+ /**
+ * struct cnf_err_cfg - Tx confirmation and error configuration
+ * @use_default_queue: Set to '1' to use the common (default) Tx
+ * confirmation and error queue; Set to '0' to use the
+ * private Tx confirmation and error queue; valid only if
+ * 'DPNI_TX_FLOW_OPT_TX_CONF_ERROR' is contained in
+ * 'options'
+ * @errors_only: Set to '1' to report back only error frames;
+ * Set to '0' to confirm transmission/error for all
+ * transmitted frames;
+ * valid only if 'DPNI_TX_FLOW_OPT_ONLY_TX_ERROR' is
+ * contained in 'options' and 'use_default_queue = 0';
+ * @queue_cfg: Queue configuration; valid only if
+ * 'DPNI_TX_FLOW_OPT_QUEUE' is contained in 'options'
+ */
+ struct {
+ int use_default_queue;
+ int errors_only;
+ struct dpni_queue_cfg queue_cfg;
+ } conf_err_cfg;
+ int l3_chksum_gen;
+ int l4_chksum_gen;
+};
+
+/**
+ * dpni_set_tx_flow() - Set Tx flow configuration
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @flow_id: Provides (or returns) the sender's flow ID;
+ * for each new sender set (*flow_id) to
+ * 'DPNI_NEW_FLOW_ID' to generate a new flow_id;
+ * this ID should be used as the QDBIN argument
+ * in enqueue operations
+ * @cfg: Tx flow configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_tx_flow(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ uint16_t *flow_id,
+ const struct dpni_tx_flow_cfg *cfg);
+
+/**
+ * struct dpni_tx_flow_attr - Structure representing Tx flow attributes
+ * @conf_err_attr: Tx confirmation and error attributes
+ * @l3_chksum_gen: '1' if L3 checksum generation is enabled; '0' if disabled
+ * @l4_chksum_gen: '1' if L4 checksum generation is enabled; '0' if disabled
+ */
+struct dpni_tx_flow_attr {
+ /**
+ * struct conf_err_attr - Tx confirmation and error attributes
+ * @use_default_queue: '1' if using common (default) Tx confirmation and
+ * error queue;
+ * '0' if using private Tx confirmation and error
+ * queue
+ * @errors_only: '1' if only error frames are reported back; '0' if all
+ * transmitted frames are confirmed
+ * @queue_attr: Queue attributes
+ */
+ struct {
+ int use_default_queue;
+ int errors_only;
+ struct dpni_queue_attr queue_attr;
+ } conf_err_attr;
+ int l3_chksum_gen;
+ int l4_chksum_gen;
+};
+
+/**
+ * dpni_get_tx_flow() - Get Tx flow attributes
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @flow_id: The sender's flow ID, as returned by the
+ * dpni_set_tx_flow() function
+ * @attr: Returned Tx flow attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_tx_flow(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ uint16_t flow_id,
+ struct dpni_tx_flow_attr *attr);
+
+/**
+ * dpni_set_rx_flow() - Set Rx flow configuration
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @tc_id: Traffic class selection (0-7);
+ * use 'DPNI_ALL_TCS' to set all TCs and all flows
+ * @flow_id Rx flow id within the traffic class; use
+ * 'DPNI_ALL_TC_FLOWS' to set all flows within
+ * this tc_id; ignored if tc_id is set to
+ * 'DPNI_ALL_TCS';
+ * @cfg: Rx flow configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_rx_flow(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ uint8_t tc_id,
+ uint16_t flow_id,
+ const struct dpni_queue_cfg *cfg);
+
+/**
+ * dpni_get_rx_flow() - Get Rx flow attributes
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @tc_id: Traffic class selection (0-7)
+ * @flow_id: Rx flow id within the traffic class
+ * @attr: Returned Rx flow attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_rx_flow(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ uint8_t tc_id,
+ uint16_t flow_id,
+ struct dpni_queue_attr *attr);
+
+#endif /* _FSL_DPNI_H */
diff --git a/include/fsl-mc/fsl_dprc.h b/include/fsl-mc/fsl_dprc.h
new file mode 100644
index 0000000..f837e89
--- /dev/null
+++ b/include/fsl-mc/fsl_dprc.h
@@ -0,0 +1,659 @@
+/*
+ * Freescale Layerscape MC I/O wrapper
+ *
+ * Copyright (C) 2013-2015 Freescale Semiconductor, Inc.
+ * Author: German Rivera <German.Rivera@freescale.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef _FSL_DPRC_H
+#define _FSL_DPRC_H
+
+/* DPRC Version */
+#define DPRC_VER_MAJOR 2
+#define DPRC_VER_MINOR 0
+
+/* Command IDs */
+#define DPRC_CMDID_CLOSE 0x800
+#define DPRC_CMDID_OPEN 0x805
+
+#define DPRC_CMDID_GET_ATTR 0x004
+#define DPRC_CMDID_RESET_CONT 0x005
+
+#define DPRC_CMDID_GET_CONT_ID 0x830
+#define DPRC_CMDID_GET_OBJ_COUNT 0x159
+#define DPRC_CMDID_GET_OBJ 0x15A
+#define DPRC_CMDID_GET_RES_COUNT 0x15B
+#define DPRC_CMDID_GET_RES_IDS 0x15C
+#define DPRC_CMDID_GET_OBJ_REG 0x15E
+
+#define DPRC_CMDID_CONNECT 0x167
+#define DPRC_CMDID_DISCONNECT 0x168
+#define DPRC_CMDID_GET_CONNECTION 0x16C
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_RSP_GET_CONTAINER_ID(cmd, container_id) \
+ MC_RSP_OP(cmd, 0, 0, 32, int, container_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_CMD_OPEN(cmd, container_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, container_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_CMD_RESET_CONTAINER(cmd, child_container_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, child_container_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_RSP_GET_ATTRIBUTES(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, int, attr->container_id); \
+ MC_RSP_OP(cmd, 0, 32, 16, uint16_t, attr->icid); \
+ MC_RSP_OP(cmd, 1, 0, 32, uint32_t, attr->options);\
+ MC_RSP_OP(cmd, 1, 32, 32, int, attr->portal_id); \
+ MC_RSP_OP(cmd, 2, 0, 16, uint16_t, attr->version.major);\
+ MC_RSP_OP(cmd, 2, 16, 16, uint16_t, attr->version.minor);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_RSP_GET_OBJ_COUNT(cmd, obj_count) \
+ MC_RSP_OP(cmd, 0, 32, 32, int, obj_count)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_CMD_GET_OBJ(cmd, obj_index) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, obj_index)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_RSP_GET_OBJ(cmd, obj_desc) \
+do { \
+ MC_RSP_OP(cmd, 0, 32, 32, int, obj_desc->id); \
+ MC_RSP_OP(cmd, 1, 0, 16, uint16_t, obj_desc->vendor); \
+ MC_RSP_OP(cmd, 1, 16, 8, uint8_t, obj_desc->irq_count); \
+ MC_RSP_OP(cmd, 1, 24, 8, uint8_t, obj_desc->region_count); \
+ MC_RSP_OP(cmd, 1, 32, 32, uint32_t, obj_desc->state);\
+ MC_RSP_OP(cmd, 2, 0, 16, uint16_t, obj_desc->ver_major);\
+ MC_RSP_OP(cmd, 2, 16, 16, uint16_t, obj_desc->ver_minor);\
+ MC_RSP_OP(cmd, 3, 0, 8, char, obj_desc->type[0]);\
+ MC_RSP_OP(cmd, 3, 8, 8, char, obj_desc->type[1]);\
+ MC_RSP_OP(cmd, 3, 16, 8, char, obj_desc->type[2]);\
+ MC_RSP_OP(cmd, 3, 24, 8, char, obj_desc->type[3]);\
+ MC_RSP_OP(cmd, 3, 32, 8, char, obj_desc->type[4]);\
+ MC_RSP_OP(cmd, 3, 40, 8, char, obj_desc->type[5]);\
+ MC_RSP_OP(cmd, 3, 48, 8, char, obj_desc->type[6]);\
+ MC_RSP_OP(cmd, 3, 56, 8, char, obj_desc->type[7]);\
+ MC_RSP_OP(cmd, 4, 0, 8, char, obj_desc->type[8]);\
+ MC_RSP_OP(cmd, 4, 8, 8, char, obj_desc->type[9]);\
+ MC_RSP_OP(cmd, 4, 16, 8, char, obj_desc->type[10]);\
+ MC_RSP_OP(cmd, 4, 24, 8, char, obj_desc->type[11]);\
+ MC_RSP_OP(cmd, 4, 32, 8, char, obj_desc->type[12]);\
+ MC_RSP_OP(cmd, 4, 40, 8, char, obj_desc->type[13]);\
+ MC_RSP_OP(cmd, 4, 48, 8, char, obj_desc->type[14]);\
+ MC_RSP_OP(cmd, 4, 56, 8, char, obj_desc->type[15]);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_CMD_GET_RES_COUNT(cmd, type) \
+do { \
+ MC_CMD_OP(cmd, 1, 0, 8, char, type[0]);\
+ MC_CMD_OP(cmd, 1, 8, 8, char, type[1]);\
+ MC_CMD_OP(cmd, 1, 16, 8, char, type[2]);\
+ MC_CMD_OP(cmd, 1, 24, 8, char, type[3]);\
+ MC_CMD_OP(cmd, 1, 32, 8, char, type[4]);\
+ MC_CMD_OP(cmd, 1, 40, 8, char, type[5]);\
+ MC_CMD_OP(cmd, 1, 48, 8, char, type[6]);\
+ MC_CMD_OP(cmd, 1, 56, 8, char, type[7]);\
+ MC_CMD_OP(cmd, 2, 0, 8, char, type[8]);\
+ MC_CMD_OP(cmd, 2, 8, 8, char, type[9]);\
+ MC_CMD_OP(cmd, 2, 16, 8, char, type[10]);\
+ MC_CMD_OP(cmd, 2, 24, 8, char, type[11]);\
+ MC_CMD_OP(cmd, 2, 32, 8, char, type[12]);\
+ MC_CMD_OP(cmd, 2, 40, 8, char, type[13]);\
+ MC_CMD_OP(cmd, 2, 48, 8, char, type[14]);\
+ MC_CMD_OP(cmd, 2, 56, 8, char, type[15]);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_RSP_GET_RES_COUNT(cmd, res_count) \
+ MC_RSP_OP(cmd, 0, 0, 32, int, res_count)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_CMD_GET_RES_IDS(cmd, range_desc, type) \
+do { \
+ MC_CMD_OP(cmd, 0, 42, 7, enum dprc_iter_status, \
+ range_desc->iter_status); \
+ MC_CMD_OP(cmd, 1, 0, 32, int, range_desc->base_id); \
+ MC_CMD_OP(cmd, 1, 32, 32, int, range_desc->last_id);\
+ MC_CMD_OP(cmd, 2, 0, 8, char, type[0]);\
+ MC_CMD_OP(cmd, 2, 8, 8, char, type[1]);\
+ MC_CMD_OP(cmd, 2, 16, 8, char, type[2]);\
+ MC_CMD_OP(cmd, 2, 24, 8, char, type[3]);\
+ MC_CMD_OP(cmd, 2, 32, 8, char, type[4]);\
+ MC_CMD_OP(cmd, 2, 40, 8, char, type[5]);\
+ MC_CMD_OP(cmd, 2, 48, 8, char, type[6]);\
+ MC_CMD_OP(cmd, 2, 56, 8, char, type[7]);\
+ MC_CMD_OP(cmd, 3, 0, 8, char, type[8]);\
+ MC_CMD_OP(cmd, 3, 8, 8, char, type[9]);\
+ MC_CMD_OP(cmd, 3, 16, 8, char, type[10]);\
+ MC_CMD_OP(cmd, 3, 24, 8, char, type[11]);\
+ MC_CMD_OP(cmd, 3, 32, 8, char, type[12]);\
+ MC_CMD_OP(cmd, 3, 40, 8, char, type[13]);\
+ MC_CMD_OP(cmd, 3, 48, 8, char, type[14]);\
+ MC_CMD_OP(cmd, 3, 56, 8, char, type[15]);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_RSP_GET_RES_IDS(cmd, range_desc) \
+do { \
+ MC_RSP_OP(cmd, 0, 42, 7, enum dprc_iter_status, \
+ range_desc->iter_status);\
+ MC_RSP_OP(cmd, 1, 0, 32, int, range_desc->base_id); \
+ MC_RSP_OP(cmd, 1, 32, 32, int, range_desc->last_id);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_CMD_GET_OBJ_REGION(cmd, obj_type, obj_id, region_index) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, int, obj_id); \
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, region_index);\
+ MC_CMD_OP(cmd, 3, 0, 8, char, obj_type[0]);\
+ MC_CMD_OP(cmd, 3, 8, 8, char, obj_type[1]);\
+ MC_CMD_OP(cmd, 3, 16, 8, char, obj_type[2]);\
+ MC_CMD_OP(cmd, 3, 24, 8, char, obj_type[3]);\
+ MC_CMD_OP(cmd, 3, 32, 8, char, obj_type[4]);\
+ MC_CMD_OP(cmd, 3, 40, 8, char, obj_type[5]);\
+ MC_CMD_OP(cmd, 3, 48, 8, char, obj_type[6]);\
+ MC_CMD_OP(cmd, 3, 56, 8, char, obj_type[7]);\
+ MC_CMD_OP(cmd, 4, 0, 8, char, obj_type[8]);\
+ MC_CMD_OP(cmd, 4, 8, 8, char, obj_type[9]);\
+ MC_CMD_OP(cmd, 4, 16, 8, char, obj_type[10]);\
+ MC_CMD_OP(cmd, 4, 24, 8, char, obj_type[11]);\
+ MC_CMD_OP(cmd, 4, 32, 8, char, obj_type[12]);\
+ MC_CMD_OP(cmd, 4, 40, 8, char, obj_type[13]);\
+ MC_CMD_OP(cmd, 4, 48, 8, char, obj_type[14]);\
+ MC_CMD_OP(cmd, 4, 56, 8, char, obj_type[15]);\
+} while (0)
+
+/* param, offset, width, type, arg_name */
+#define DPRC_RSP_GET_OBJ_REGION(cmd, region_desc) \
+do { \
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, region_desc->base_paddr);\
+ MC_RSP_OP(cmd, 2, 0, 32, uint32_t, region_desc->size); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_CMD_CONNECT(cmd, endpoint1, endpoint2) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, int, endpoint1->id); \
+ MC_CMD_OP(cmd, 0, 32, 32, int, endpoint1->interface_id); \
+ MC_CMD_OP(cmd, 1, 0, 32, int, endpoint2->id); \
+ MC_CMD_OP(cmd, 1, 32, 32, int, endpoint2->interface_id); \
+ MC_CMD_OP(cmd, 2, 0, 8, char, endpoint1->type[0]); \
+ MC_CMD_OP(cmd, 2, 8, 8, char, endpoint1->type[1]); \
+ MC_CMD_OP(cmd, 2, 16, 8, char, endpoint1->type[2]); \
+ MC_CMD_OP(cmd, 2, 24, 8, char, endpoint1->type[3]); \
+ MC_CMD_OP(cmd, 2, 32, 8, char, endpoint1->type[4]); \
+ MC_CMD_OP(cmd, 2, 40, 8, char, endpoint1->type[5]); \
+ MC_CMD_OP(cmd, 2, 48, 8, char, endpoint1->type[6]); \
+ MC_CMD_OP(cmd, 2, 56, 8, char, endpoint1->type[7]); \
+ MC_CMD_OP(cmd, 3, 0, 8, char, endpoint1->type[8]); \
+ MC_CMD_OP(cmd, 3, 8, 8, char, endpoint1->type[9]); \
+ MC_CMD_OP(cmd, 3, 16, 8, char, endpoint1->type[10]); \
+ MC_CMD_OP(cmd, 3, 24, 8, char, endpoint1->type[11]); \
+ MC_CMD_OP(cmd, 3, 32, 8, char, endpoint1->type[12]); \
+ MC_CMD_OP(cmd, 3, 40, 8, char, endpoint1->type[13]); \
+ MC_CMD_OP(cmd, 3, 48, 8, char, endpoint1->type[14]); \
+ MC_CMD_OP(cmd, 3, 56, 8, char, endpoint1->type[15]); \
+ MC_CMD_OP(cmd, 5, 0, 8, char, endpoint2->type[0]); \
+ MC_CMD_OP(cmd, 5, 8, 8, char, endpoint2->type[1]); \
+ MC_CMD_OP(cmd, 5, 16, 8, char, endpoint2->type[2]); \
+ MC_CMD_OP(cmd, 5, 24, 8, char, endpoint2->type[3]); \
+ MC_CMD_OP(cmd, 5, 32, 8, char, endpoint2->type[4]); \
+ MC_CMD_OP(cmd, 5, 40, 8, char, endpoint2->type[5]); \
+ MC_CMD_OP(cmd, 5, 48, 8, char, endpoint2->type[6]); \
+ MC_CMD_OP(cmd, 5, 56, 8, char, endpoint2->type[7]); \
+ MC_CMD_OP(cmd, 6, 0, 8, char, endpoint2->type[8]); \
+ MC_CMD_OP(cmd, 6, 8, 8, char, endpoint2->type[9]); \
+ MC_CMD_OP(cmd, 6, 16, 8, char, endpoint2->type[10]); \
+ MC_CMD_OP(cmd, 6, 24, 8, char, endpoint2->type[11]); \
+ MC_CMD_OP(cmd, 6, 32, 8, char, endpoint2->type[12]); \
+ MC_CMD_OP(cmd, 6, 40, 8, char, endpoint2->type[13]); \
+ MC_CMD_OP(cmd, 6, 48, 8, char, endpoint2->type[14]); \
+ MC_CMD_OP(cmd, 6, 56, 8, char, endpoint2->type[15]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_CMD_DISCONNECT(cmd, endpoint) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, int, endpoint->id); \
+ MC_CMD_OP(cmd, 0, 32, 32, int, endpoint->interface_id); \
+ MC_CMD_OP(cmd, 1, 0, 8, char, endpoint->type[0]); \
+ MC_CMD_OP(cmd, 1, 8, 8, char, endpoint->type[1]); \
+ MC_CMD_OP(cmd, 1, 16, 8, char, endpoint->type[2]); \
+ MC_CMD_OP(cmd, 1, 24, 8, char, endpoint->type[3]); \
+ MC_CMD_OP(cmd, 1, 32, 8, char, endpoint->type[4]); \
+ MC_CMD_OP(cmd, 1, 40, 8, char, endpoint->type[5]); \
+ MC_CMD_OP(cmd, 1, 48, 8, char, endpoint->type[6]); \
+ MC_CMD_OP(cmd, 1, 56, 8, char, endpoint->type[7]); \
+ MC_CMD_OP(cmd, 2, 0, 8, char, endpoint->type[8]); \
+ MC_CMD_OP(cmd, 2, 8, 8, char, endpoint->type[9]); \
+ MC_CMD_OP(cmd, 2, 16, 8, char, endpoint->type[10]); \
+ MC_CMD_OP(cmd, 2, 24, 8, char, endpoint->type[11]); \
+ MC_CMD_OP(cmd, 2, 32, 8, char, endpoint->type[12]); \
+ MC_CMD_OP(cmd, 2, 40, 8, char, endpoint->type[13]); \
+ MC_CMD_OP(cmd, 2, 48, 8, char, endpoint->type[14]); \
+ MC_CMD_OP(cmd, 2, 56, 8, char, endpoint->type[15]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_CMD_GET_CONNECTION(cmd, endpoint1) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, int, endpoint1->id); \
+ MC_CMD_OP(cmd, 0, 32, 32, int, endpoint1->interface_id); \
+ MC_CMD_OP(cmd, 1, 0, 8, char, endpoint1->type[0]); \
+ MC_CMD_OP(cmd, 1, 8, 8, char, endpoint1->type[1]); \
+ MC_CMD_OP(cmd, 1, 16, 8, char, endpoint1->type[2]); \
+ MC_CMD_OP(cmd, 1, 24, 8, char, endpoint1->type[3]); \
+ MC_CMD_OP(cmd, 1, 32, 8, char, endpoint1->type[4]); \
+ MC_CMD_OP(cmd, 1, 40, 8, char, endpoint1->type[5]); \
+ MC_CMD_OP(cmd, 1, 48, 8, char, endpoint1->type[6]); \
+ MC_CMD_OP(cmd, 1, 56, 8, char, endpoint1->type[7]); \
+ MC_CMD_OP(cmd, 2, 0, 8, char, endpoint1->type[8]); \
+ MC_CMD_OP(cmd, 2, 8, 8, char, endpoint1->type[9]); \
+ MC_CMD_OP(cmd, 2, 16, 8, char, endpoint1->type[10]); \
+ MC_CMD_OP(cmd, 2, 24, 8, char, endpoint1->type[11]); \
+ MC_CMD_OP(cmd, 2, 32, 8, char, endpoint1->type[12]); \
+ MC_CMD_OP(cmd, 2, 40, 8, char, endpoint1->type[13]); \
+ MC_CMD_OP(cmd, 2, 48, 8, char, endpoint1->type[14]); \
+ MC_CMD_OP(cmd, 2, 56, 8, char, endpoint1->type[15]); \
+} while (0)
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_RSP_GET_CONNECTION(cmd, endpoint2, state) \
+do { \
+ MC_RSP_OP(cmd, 3, 0, 32, int, endpoint2->id); \
+ MC_RSP_OP(cmd, 3, 32, 32, int, endpoint2->interface_id); \
+ MC_RSP_OP(cmd, 4, 0, 8, char, endpoint2->type[0]); \
+ MC_RSP_OP(cmd, 4, 8, 8, char, endpoint2->type[1]); \
+ MC_RSP_OP(cmd, 4, 16, 8, char, endpoint2->type[2]); \
+ MC_RSP_OP(cmd, 4, 24, 8, char, endpoint2->type[3]); \
+ MC_RSP_OP(cmd, 4, 32, 8, char, endpoint2->type[4]); \
+ MC_RSP_OP(cmd, 4, 40, 8, char, endpoint2->type[5]); \
+ MC_RSP_OP(cmd, 4, 48, 8, char, endpoint2->type[6]); \
+ MC_RSP_OP(cmd, 4, 56, 8, char, endpoint2->type[7]); \
+ MC_RSP_OP(cmd, 5, 0, 8, char, endpoint2->type[8]); \
+ MC_RSP_OP(cmd, 5, 8, 8, char, endpoint2->type[9]); \
+ MC_RSP_OP(cmd, 5, 16, 8, char, endpoint2->type[10]); \
+ MC_RSP_OP(cmd, 5, 24, 8, char, endpoint2->type[11]); \
+ MC_RSP_OP(cmd, 5, 32, 8, char, endpoint2->type[12]); \
+ MC_RSP_OP(cmd, 5, 40, 8, char, endpoint2->type[13]); \
+ MC_RSP_OP(cmd, 5, 48, 8, char, endpoint2->type[14]); \
+ MC_RSP_OP(cmd, 5, 56, 8, char, endpoint2->type[15]); \
+ MC_RSP_OP(cmd, 6, 0, 32, int, state); \
+} while (0)
+
+/* Data Path Resource Container API
+ * Contains DPRC API for managing and querying DPAA resources
+ */
+struct fsl_mc_io;
+
+/**
+ * Set this value as the icid value in dprc_cfg structure when creating a
+ * container, in case the ICID is not selected by the user and should be
+ * allocated by the DPRC from the pool of ICIDs.
+ */
+#define DPRC_GET_ICID_FROM_POOL (uint16_t)(~(0))
+
+/**
+ * Set this value as the portal_id value in dprc_cfg structure when creating a
+ * container, in case the portal ID is not specifically selected by the
+ * user and should be allocated by the DPRC from the pool of portal ids.
+ */
+#define DPRC_GET_PORTAL_ID_FROM_POOL (int)(~(0))
+
+/**
+ * dprc_get_container_id() - Get container ID associated with a given portal.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @container_id: Requested container ID
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dprc_get_container_id(struct fsl_mc_io *mc_io, int *container_id);
+
+/**
+ * dprc_open() - Open DPRC object for use
+ * @mc_io: Pointer to MC portal's I/O object
+ * @container_id: Container ID to open
+ * @token: Returned token of DPRC object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Required before any operation on the object.
+ */
+int dprc_open(struct fsl_mc_io *mc_io, int container_id, uint16_t *token);
+
+/**
+ * dprc_close() - Close the control session of the object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPRC object
+ *
+ * After this function is called, no further operations are
+ * allowed on the object without opening a new control session.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dprc_close(struct fsl_mc_io *mc_io, uint16_t token);
+
+/**
+ * Container general options
+ *
+ * These options may be selected at container creation by the container creator
+ * and can be retrieved using dprc_get_attributes()
+ */
+
+/* Spawn Policy Option allowed - Indicates that the new container is allowed
+ * to spawn and have its own child containers.
+ */
+#define DPRC_CFG_OPT_SPAWN_ALLOWED 0x00000001
+
+/* General Container allocation policy - Indicates that the new container is
+ * allowed to allocate requested resources from its parent container; if not
+ * set, the container is only allowed to use resources in its own pools; Note
+ * that this is a container's global policy, but the parent container may
+ * override it and set specific quota per resource type.
+ */
+#define DPRC_CFG_OPT_ALLOC_ALLOWED 0x00000002
+
+/* Object initialization allowed - software context associated with this
+ * container is allowed to invoke object initialization operations.
+ */
+#define DPRC_CFG_OPT_OBJ_CREATE_ALLOWED 0x00000004
+
+/* Topology change allowed - software context associated with this
+ * container is allowed to invoke topology operations, such as attach/detach
+ * of network objects.
+ */
+#define DPRC_CFG_OPT_TOPOLOGY_CHANGES_ALLOWED 0x00000008
+
+/* IOMMU bypass - indicates whether objects of this container are permitted
+ * to bypass the IOMMU.
+ */
+#define DPRC_CFG_OPT_IOMMU_BYPASS 0x00000010
+
+/* AIOP - Indicates that container belongs to AIOP. */
+#define DPRC_CFG_OPT_AIOP 0x00000020
+
+/**
+ * struct dprc_cfg - Container configuration options
+ * @icid: Container's ICID; if set to 'DPRC_GET_ICID_FROM_POOL', a free
+ * ICID value is allocated by the DPRC
+ * @portal_id: Portal ID; if set to 'DPRC_GET_PORTAL_ID_FROM_POOL', a free
+ * portal ID is allocated by the DPRC
+ * @options: Combination of 'DPRC_CFG_OPT_<X>' options
+ */
+struct dprc_cfg {
+ uint16_t icid;
+ int portal_id;
+ uint64_t options;
+};
+
+/**
+ * dprc_reset_container - Reset child container.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPRC object
+ * @child_container_id: ID of the container to reset
+ *
+ * In case a software context crashes or becomes non-responsive, the parent
+ * may wish to reset its resources container before the software context is
+ * restarted.
+ *
+ * This routine informs all objects assigned to the child container that the
+ * container is being reset, so they may perform any cleanup operations that are
+ * needed. All objects handles that were owned by the child container shall be
+ * closed.
+ *
+ * Note that such request may be submitted even if the child software context
+ * has not crashed, but the resulting object cleanup operations will not be
+ * aware of that.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dprc_reset_container(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ int child_container_id);
+
+/**
+ * struct dprc_attributes - Container attributes
+ * @container_id: Container's ID
+ * @icid: Container's ICID
+ * @portal_id: Container's portal ID
+ * @options: Container's options as set at container's creation
+ * @version: DPRC version
+ */
+struct dprc_attributes {
+ int container_id;
+ uint16_t icid;
+ int portal_id;
+ uint64_t options;
+ /**
+ * struct version - DPRC version
+ * @major: DPRC major version
+ * @minor: DPRC minor version
+ */
+ struct {
+ uint16_t major;
+ uint16_t minor;
+ } version;
+};
+
+/**
+ * dprc_get_attributes() - Obtains container attributes
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPRC object
+ * @attributes Returned container attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dprc_get_attributes(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dprc_attributes *attributes);
+
+/**
+ * dprc_get_obj_count() - Obtains the number of objects in the DPRC
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPRC object
+ * @obj_count: Number of objects assigned to the DPRC
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dprc_get_obj_count(struct fsl_mc_io *mc_io, uint16_t token, int *obj_count);
+
+/* Objects Attributes Flags */
+
+/* Opened state - Indicates that an object is open by at least one owner */
+#define DPRC_OBJ_STATE_OPEN 0x00000001
+/* Plugged state - Indicates that the object is plugged */
+#define DPRC_OBJ_STATE_PLUGGED 0x00000002
+
+/**
+ * struct dprc_obj_desc - Object descriptor, returned from dprc_get_obj()
+ * @type: Type of object: NULL terminated string
+ * @id: ID of logical object resource
+ * @vendor: Object vendor identifier
+ * @ver_major: Major version number
+ * @ver_minor: Minor version number
+ * @irq_count: Number of interrupts supported by the object
+ * @region_count: Number of mappable regions supported by the object
+ * @state: Object state: combination of DPRC_OBJ_STATE_ states
+ */
+struct dprc_obj_desc {
+ char type[16];
+ int id;
+ uint16_t vendor;
+ uint16_t ver_major;
+ uint16_t ver_minor;
+ uint8_t irq_count;
+ uint8_t region_count;
+ uint32_t state;
+};
+
+/**
+ * dprc_get_obj() - Get general information on an object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPRC object
+ * @obj_index: Index of the object to be queried (< obj_count)
+ * @obj_desc: Returns the requested object descriptor
+ *
+ * The object descriptors are retrieved one by one by incrementing
+ * obj_index up to (not including) the value of obj_count returned
+ * from dprc_get_obj_count(). dprc_get_obj_count() must
+ * be called prior to dprc_get_obj().
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dprc_get_obj(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ int obj_index,
+ struct dprc_obj_desc *obj_desc);
+
+/**
+ * dprc_get_res_count() - Obtains the number of free resources that are assigned
+ * to this container, by pool type
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPRC object
+ * @type: pool type
+ * @res_count: Returned number of free resources of the given
+ * resource type that are assigned to this DPRC
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dprc_get_res_count(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ char *type,
+ int *res_count);
+
+/**
+ * enum dprc_iter_status - Iteration status
+ * @DPRC_ITER_STATUS_FIRST: Perform first iteration
+ * @DPRC_ITER_STATUS_MORE: Indicates more/next iteration is needed
+ * @DPRC_ITER_STATUS_LAST: Indicates last iteration
+ */
+enum dprc_iter_status {
+ DPRC_ITER_STATUS_FIRST = 0,
+ DPRC_ITER_STATUS_MORE = 1,
+ DPRC_ITER_STATUS_LAST = 2
+};
+
+/**
+ * struct dprc_res_ids_range_desc - Resource ID range descriptor
+ * @base_id: Base resource ID of this range
+ * @last_id: Last resource ID of this range
+ * @iter_status: Iteration status - should be set to DPRC_ITER_STATUS_FIRST at
+ * first iteration; while the returned marker is DPRC_ITER_STATUS_MORE,
+ * additional iterations are needed, until the returned marker is
+ * DPRC_ITER_STATUS_LAST
+ */
+struct dprc_res_ids_range_desc {
+ int base_id;
+ int last_id;
+ enum dprc_iter_status iter_status;
+};
+
+/**
+ * dprc_get_res_ids() - Obtains IDs of free resources in the container
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPRC object
+ * @type: pool type
+ * @range_desc: range descriptor
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dprc_get_res_ids(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ char *type,
+ struct dprc_res_ids_range_desc *range_desc);
+
+/**
+ * struct dprc_region_desc - Mappable region descriptor
+ * @base_paddr: Region base physical address
+ * @size: Region size (in bytes)
+ */
+struct dprc_region_desc {
+ uint64_t base_paddr;
+ uint32_t size;
+};
+
+/**
+ * dprc_get_obj_region() - Get region information for a specified object.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPRC object
+ * @obj_type; Object type as returned in dprc_get_obj()
+ * @obj_id: Unique object instance as returned in dprc_get_obj()
+ * @region_index: The specific region to query
+ * @region_desc: Returns the requested region descriptor
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dprc_get_obj_region(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ char *obj_type,
+ int obj_id,
+ uint8_t region_index,
+ struct dprc_region_desc *region_desc);
+/**
+ * struct dprc_endpoint - Endpoint description for link connect/disconnect
+ * operations
+ * @type: Endpoint object type: NULL terminated string
+ * @id: Endpoint object ID
+ * @interface_id: Interface ID; should be set for endpoints with multiple
+ * interfaces ("dpsw", "dpdmux"); for others, always set to 0
+ */
+struct dprc_endpoint {
+ char type[16];
+ int id;
+ int interface_id;
+};
+
+/**
+ * dprc_connect() - Connect two endpoints to create a network link between them
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPRC object
+ * @endpoint1: Endpoint 1 configuration parameters
+ * @endpoint2: Endpoint 2 configuration parameters
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dprc_connect(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dprc_endpoint *endpoint1,
+ const struct dprc_endpoint *endpoint2);
+
+/**
+ * dprc_disconnect() - Disconnect one endpoint to remove its network connection
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPRC object
+ * @endpoint: Endpoint configuration parameters
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dprc_disconnect(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dprc_endpoint *endpoint);
+
+/**
+* dprc_get_connection() - Get connected endpoint and link status if connection
+* exists.
+* @mc_io Pointer to MC portal's I/O object
+* @token Token of DPRC object
+* @endpoint1 Endpoint 1 configuration parameters
+* @endpoint2 Returned endpoint 2 configuration parameters
+* @state: Returned link state: 1 - link is up, 0 - link is down
+*
+* Return: '0' on Success; -ENAVAIL if connection does not exist.
+*/
+int dprc_get_connection(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dprc_endpoint *endpoint1,
+ struct dprc_endpoint *endpoint2,
+ int *state);
+
+#endif /* _FSL_DPRC_H */
diff --git a/include/fsl-mc/fsl_mc.h b/include/fsl-mc/fsl_mc.h
index 28d5961..ec24415 100644
--- a/include/fsl-mc/fsl_mc.h
+++ b/include/fsl-mc/fsl_mc.h
@@ -53,8 +53,8 @@ struct mc_ccsr_registers {
u32 reg_error[];
};
-int mc_init(bd_t *bis);
-
int get_mc_boot_status(void);
unsigned long mc_get_dram_block_size(void);
+int fsl_mc_ldpaa_init(bd_t *bis);
+void fsl_mc_ldpaa_exit(bd_t *bis);
#endif
diff --git a/include/fsl-mc/fsl_mc_cmd.h b/include/fsl-mc/fsl_mc_cmd.h
index e7fcb5b..cb39c39 100644
--- a/include/fsl-mc/fsl_mc_cmd.h
+++ b/include/fsl-mc/fsl_mc_cmd.h
@@ -1,4 +1,4 @@
-/* Copyright 2014 Freescale Semiconductor Inc.
+/* Copyright 2013-2015 Freescale Semiconductor Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -41,9 +41,9 @@ enum mc_cmd_status {
#define MC_CMD_HDR_CMDID_O 52 /* Command ID field offset */
#define MC_CMD_HDR_CMDID_S 12 /* Command ID field size */
-#define MC_CMD_HDR_AUTHID_O 38 /* Authentication ID field offset */
-#define MC_CMD_HDR_AUTHID_S 10 /* Authentication ID field size */
#define MC_CMD_HDR_STATUS_O 16 /* Status field offset */
+#define MC_CMD_HDR_TOKEN_O 38 /* Token field offset */
+#define MC_CMD_HDR_TOKEN_S 10 /* Token field size */
#define MC_CMD_HDR_STATUS_S 8 /* Status field size*/
#define MC_CMD_HDR_PRI_O 15 /* Priority field offset */
#define MC_CMD_HDR_PRI_S 1 /* Priority field size */
@@ -52,12 +52,15 @@ enum mc_cmd_status {
((enum mc_cmd_status)u64_dec((_hdr), \
MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S))
-#define MC_CMD_HDR_READ_AUTHID(_hdr) \
- ((uint16_t)u64_dec((_hdr), MC_CMD_HDR_AUTHID_O, MC_CMD_HDR_AUTHID_S))
+#define MC_CMD_HDR_READ_TOKEN(_hdr) \
+ ((uint16_t)u64_dec((_hdr), MC_CMD_HDR_TOKEN_O, MC_CMD_HDR_TOKEN_S))
#define MC_CMD_PRI_LOW 0 /*!< Low Priority command indication */
#define MC_CMD_PRI_HIGH 1 /*!< High Priority command indication */
+#define MC_EXT_OP(_ext, _param, _offset, _width, _type, _arg) \
+ ((_ext)[_param] |= u64_enc((_offset), (_width), _arg))
+
#define MC_CMD_OP(_cmd, _param, _offset, _width, _type, _arg) \
((_cmd).params[_param] |= u64_enc((_offset), (_width), _arg))
@@ -66,12 +69,12 @@ enum mc_cmd_status {
static inline uint64_t mc_encode_cmd_header(uint16_t cmd_id,
uint8_t priority,
- uint16_t auth_id)
+ uint16_t token)
{
uint64_t hdr;
hdr = u64_enc(MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S, cmd_id);
- hdr |= u64_enc(MC_CMD_HDR_AUTHID_O, MC_CMD_HDR_AUTHID_S, auth_id);
+ hdr |= u64_enc(MC_CMD_HDR_TOKEN_O, MC_CMD_HDR_TOKEN_S, token);
hdr |= u64_enc(MC_CMD_HDR_PRI_O, MC_CMD_HDR_PRI_S, priority);
hdr |= u64_enc(MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S,
MC_CMD_STATUS_READY);
diff --git a/include/fsl-mc/fsl_mc_private.h b/include/fsl-mc/fsl_mc_private.h
new file mode 100644
index 0000000..cf4b079
--- /dev/null
+++ b/include/fsl-mc/fsl_mc_private.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _FSL_MC_PRIVATE_H_
+#define _FSL_MC_PRIVATE_H_
+
+#include <errno.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <linux/compat.h>
+#include <linux/types.h>
+#include <linux/stringify.h>
+
+#include <fsl-mc/fsl_mc_sys.h>
+#include <fsl-mc/fsl_mc_cmd.h>
+#include <fsl-mc/fsl_dpbp.h>
+
+extern struct fsl_mc_io *dflt_mc_io;
+
+/**
+ * struct dpbp_node - DPBP strucuture
+ * @uint16_t handle: DPBP object handle
+ * @int dpbp_id: DPBP id
+ */
+struct fsl_dpbp_obj {
+ uint16_t dpbp_handle;
+ struct dpbp_attr dpbp_attr;
+};
+
+extern struct fsl_dpbp_obj *dflt_dpbp;
+
+/**
+ * struct fsl_dpio_obj - DPIO strucuture
+ * @int dpio_id: DPIO id
+ * @struct qbman_swp *sw_portal: SW portal object
+ */
+struct fsl_dpio_obj {
+ int dpio_id;
+ struct qbman_swp *sw_portal; /** SW portal object */
+};
+
+extern struct fsl_dpio_obj *dflt_dpio;
+
+int mc_init(void);
+#endif /* _FSL_MC_PRIVATE_H_ */
diff --git a/include/fsl-mc/fsl_qbman_base.h b/include/fsl-mc/fsl_qbman_base.h
new file mode 100644
index 0000000..c92cbe1
--- /dev/null
+++ b/include/fsl-mc/fsl_qbman_base.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _FSL_QBMAN_BASE_H
+#define _FSL_QBMAN_BASE_H
+
+/* Descriptor for a QBMan instance on the SoC. On partitions/targets that do not
+ * control this QBMan instance, these values may simply be place-holders. The
+ * idea is simply that we be able to distinguish between them, eg. so that SWP
+ * descriptors can identify which QBMan instance they belong to. */
+struct qbman_block_desc {
+ void *ccsr_reg_bar; /* CCSR register map */
+ int irq_rerr; /* Recoverable error interrupt line */
+ int irq_nrerr; /* Non-recoverable error interrupt line */
+};
+
+/* Descriptor for a QBMan software portal, expressed in terms that make sense to
+ * the user context. Ie. on MC, this information is likely to be true-physical,
+ * and instantiated statically at compile-time. On GPP, this information is
+ * likely to be obtained via "discovery" over a partition's "layerscape bus"
+ * (ie. in response to a MC portal command), and would take into account any
+ * virtualisation of the GPP user's address space and/or interrupt numbering. */
+struct qbman_swp_desc {
+ const struct qbman_block_desc *block; /* The QBMan instance */
+ void *cena_bar; /* Cache-enabled portal register map */
+ void *cinh_bar; /* Cache-inhibited portal register map */
+};
+
+/* Driver object for managing a QBMan portal */
+struct qbman_swp;
+
+/* Place-holder for FDs, we represent it via the simplest form that we need for
+ * now. Different overlays may be needed to support different options, etc. (It
+ * is impractical to define One True Struct, because the resulting encoding
+ * routines (lots of read-modify-writes) would be worst-case performance whether
+ * or not circumstances required them.)
+ *
+ * Note, as with all data-structures exchanged between software and hardware (be
+ * they located in the portal register map or DMA'd to and from main-memory),
+ * the driver ensures that the caller of the driver API sees the data-structures
+ * in host-endianness. "struct qbman_fd" is no exception. The 32-bit words
+ * contained within this structure are represented in host-endianness, even if
+ * hardware always treats them as little-endian. As such, if any of these fields
+ * are interpreted in a binary (rather than numerical) fashion by hardware
+ * blocks (eg. accelerators), then the user should be careful. We illustrate
+ * with an example;
+ *
+ * Suppose the desired behaviour of an accelerator is controlled by the "frc"
+ * field of the FDs that are sent to it. Suppose also that the behaviour desired
+ * by the user corresponds to an "frc" value which is expressed as the literal
+ * sequence of bytes 0xfe, 0xed, 0xab, and 0xba. So "frc" should be the 32-bit
+ * value in which 0xfe is the first byte and 0xba is the last byte, and as
+ * hardware is little-endian, this amounts to a 32-bit "value" of 0xbaabedfe. If
+ * the software is little-endian also, this can simply be achieved by setting
+ * frc=0xbaabedfe. On the other hand, if software is big-endian, it should set
+ * frc=0xfeedabba! The best away of avoiding trouble with this sort of thing is
+ * to treat the 32-bit words as numerical values, in which the offset of a field
+ * from the beginning of the first byte (as required or generated by hardware)
+ * is numerically encoded by a left-shift (ie. by raising the field to a
+ * corresponding power of 2). Ie. in the current example, software could set
+ * "frc" in the following way, and it would work correctly on both little-endian
+ * and big-endian operation;
+ * fd.frc = (0xfe << 0) | (0xed << 8) | (0xab << 16) | (0xba << 24);
+ */
+struct qbman_fd {
+ union {
+ uint32_t words[8];
+ struct qbman_fd_simple {
+ uint32_t addr_lo;
+ uint32_t addr_hi;
+ uint32_t len;
+ /* offset in the MS 16 bits, BPID in the LS 16 bits */
+ uint32_t bpid_offset;
+ uint32_t frc; /* frame context */
+ /* "err", "va", "cbmt", "asal", [...] */
+ uint32_t ctrl;
+ /* flow context */
+ uint32_t flc_lo;
+ uint32_t flc_hi;
+ } simple;
+ };
+};
+
+#endif /* !_FSL_QBMAN_BASE_H */
diff --git a/include/fsl-mc/fsl_qbman_portal.h b/include/fsl-mc/fsl_qbman_portal.h
new file mode 100644
index 0000000..2aadad8
--- /dev/null
+++ b/include/fsl-mc/fsl_qbman_portal.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _FSL_QBMAN_PORTAL_H
+#define _FSL_QBMAN_PORTAL_H
+
+#include <fsl-mc/fsl_qbman_base.h>
+
+/* Create and destroy a functional object representing the given QBMan portal
+ * descriptor. */
+struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *);
+
+ /************/
+ /* Dequeues */
+ /************/
+
+/* See the QBMan driver API documentation for details on the enqueue
+ * mechanisms. NB: the use of a 'ldpaa_' prefix for this type is because it is
+ * primarily used by the "DPIO" layer that sits above (and hides) the QBMan
+ * driver. The structure is defined in the DPIO interface, but to avoid circular
+ * dependencies we just pre/re-declare it here opaquely. */
+struct ldpaa_dq;
+
+
+/* ------------------- */
+/* Pull-mode dequeuing */
+/* ------------------- */
+
+struct qbman_pull_desc {
+ uint32_t dont_manipulate_directly[6];
+};
+
+/* Clear the contents of a descriptor to default/starting state. */
+void qbman_pull_desc_clear(struct qbman_pull_desc *);
+/* If not called, or if called with 'storage' as NULL, the result pull dequeues
+ * will produce results to DQRR. If 'storage' is non-NULL, then results are
+ * produced to the given memory location (using the physical/DMA address which
+ * the caller provides in 'storage_phys'), and 'stash' controls whether or not
+ * those writes to main-memory express a cache-warming attribute. */
+void qbman_pull_desc_set_storage(struct qbman_pull_desc *,
+ struct ldpaa_dq *storage,
+ dma_addr_t storage_phys,
+ int stash);
+/* numframes must be between 1 and 16, inclusive */
+void qbman_pull_desc_set_numframes(struct qbman_pull_desc *, uint8_t numframes);
+/* token is the value that shows up in the dequeue results that can be used to
+ * detect when the results have been published, and is not really used when
+ * dequeue results go to DQRR. The easiest technique is to zero result "storage"
+ * before issuing a pull dequeue, and use any non-zero 'token' value. */
+void qbman_pull_desc_set_token(struct qbman_pull_desc *, uint8_t token);
+/* Exactly one of the following descriptor "actions" should be set. (Calling any
+ * one of these will replace the effect of any prior call to one of these.)
+ * - pull dequeue from the given frame queue (FQ)
+ * - pull dequeue from any FQ in the given work queue (WQ)
+ * - pull dequeue from any FQ in any WQ in the given channel
+ */
+void qbman_pull_desc_set_fq(struct qbman_pull_desc *, uint32_t fqid);
+
+/* Issue the pull dequeue command */
+int qbman_swp_pull(struct qbman_swp *, struct qbman_pull_desc *);
+
+/* -------------------------------- */
+/* Polling DQRR for dequeue results */
+/* -------------------------------- */
+
+/* NULL return if there are no unconsumed DQRR entries. Returns a DQRR entry
+ * only once, so repeated calls can return a sequence of DQRR entries, without
+ * requiring they be consumed immediately or in any particular order. */
+const struct ldpaa_dq *qbman_swp_dqrr_next(struct qbman_swp *);
+/* Consume DQRR entries previously returned from qbman_swp_dqrr_next(). */
+void qbman_swp_dqrr_consume(struct qbman_swp *, const struct ldpaa_dq *);
+
+/* ------------------------------------------------- */
+/* Polling user-provided storage for dequeue results */
+/* ------------------------------------------------- */
+
+/* Only used for user-provided storage of dequeue results, not DQRR. Prior to
+ * being used, the storage must set "oldtoken", so that the driver notices when
+ * hardware has filled it in with results using a "newtoken". NB, for efficiency
+ * purposes, the driver will perform any required endianness conversion to
+ * ensure that the user's dequeue result storage is in host-endian format
+ * (whether or not that is the same as the little-endian format that hardware
+ * DMA'd to the user's storage). As such, once the user has called
+ * qbman_dq_entry_has_newtoken() and been returned a valid dequeue result, they
+ * should not call it again on the same memory location (except of course if
+ * another dequeue command has been executed to produce a new result to that
+ * location).
+ */
+void qbman_dq_entry_set_oldtoken(struct ldpaa_dq *,
+ unsigned int num_entries,
+ uint8_t oldtoken);
+int qbman_dq_entry_has_newtoken(struct qbman_swp *,
+ const struct ldpaa_dq *,
+ uint8_t newtoken);
+
+/* -------------------------------------------------------- */
+/* Parsing dequeue entries (DQRR and user-provided storage) */
+/* -------------------------------------------------------- */
+
+/* DQRR entries may contain non-dequeue results, ie. notifications */
+int qbman_dq_entry_is_DQ(const struct ldpaa_dq *);
+
+ /************/
+ /* Enqueues */
+ /************/
+
+struct qbman_eq_desc {
+ uint32_t dont_manipulate_directly[8];
+};
+
+
+/* Clear the contents of a descriptor to default/starting state. */
+void qbman_eq_desc_clear(struct qbman_eq_desc *);
+/* Exactly one of the following descriptor "actions" should be set. (Calling
+ * any one of these will replace the effect of any prior call to one of these.)
+ * - enqueue without order-restoration
+ * - enqueue with order-restoration
+ * - fill a hole in the order-restoration sequence, without any enqueue
+ * - advance NESN (Next Expected Sequence Number), without any enqueue
+ * 'respond_success' indicates whether an enqueue response should be DMA'd
+ * after success (otherwise a response is DMA'd only after failure).
+ * 'incomplete' indicates that other fragments of the same 'seqnum' are yet to
+ * be enqueued.
+ */
+void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *, int respond_success);
+void qbman_eq_desc_set_response(struct qbman_eq_desc *,
+ dma_addr_t storage_phys,
+ int stash);
+/* token is the value that shows up in an enqueue response that can be used to
+ * detect when the results have been published. The easiest technique is to zero
+ * result "storage" before issuing an enqueue, and use any non-zero 'token'
+ * value. */
+void qbman_eq_desc_set_token(struct qbman_eq_desc *, uint8_t token);
+/* Exactly one of the following descriptor "targets" should be set. (Calling any
+ * one of these will replace the effect of any prior call to one of these.)
+ * - enqueue to a frame queue
+ * - enqueue to a queuing destination
+ * Note, that none of these will have any affect if the "action" type has been
+ * set to "orp_hole" or "orp_nesn".
+ */
+void qbman_eq_desc_set_fq(struct qbman_eq_desc *, uint32_t fqid);
+void qbman_eq_desc_set_qd(struct qbman_eq_desc *, uint32_t qdid,
+ uint32_t qd_bin, uint32_t qd_prio);
+
+/* Issue an enqueue command. ('fd' should only be NULL if the "action" of the
+ * descriptor is "orp_hole" or "orp_nesn".) */
+int qbman_swp_enqueue(struct qbman_swp *, const struct qbman_eq_desc *,
+ const struct qbman_fd *fd);
+
+ /*******************/
+ /* Buffer releases */
+ /*******************/
+
+struct qbman_release_desc {
+ uint32_t dont_manipulate_directly[1];
+};
+
+/* Clear the contents of a descriptor to default/starting state. */
+void qbman_release_desc_clear(struct qbman_release_desc *);
+/* Set the ID of the buffer pool to release to */
+void qbman_release_desc_set_bpid(struct qbman_release_desc *, uint32_t bpid);
+/* Issue a release command. 'num_buffers' must be less than 8. */
+int qbman_swp_release(struct qbman_swp *, const struct qbman_release_desc *,
+ const uint64_t *buffers, unsigned int num_buffers);
+
+ /*******************/
+ /* Buffer acquires */
+ /*******************/
+
+int qbman_swp_acquire(struct qbman_swp *, uint32_t bpid, uint64_t *buffers,
+ unsigned int num_buffers);
+#endif /* !_FSL_QBMAN_PORTAL_H */
--
1.7.9.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH 4/8] driver/ldpaa_eth: Add LDPAA Ethernet driver
2015-03-19 16:20 [U-Boot] [PATCH 1/8] armv8/fsl-lsch3: Add Freescale Debug Server driver York Sun
2015-03-19 16:20 ` [U-Boot] [PATCH 2/8] fsl-ch3/README: Add description for NOR flash layout (firmware images) York Sun
2015-03-19 16:20 ` [U-Boot] [PATCH 3/8] driver/fsl-mc: Add support of MC Flibs York Sun
@ 2015-03-19 16:20 ` York Sun
2015-03-19 16:20 ` [U-Boot] [PATCH 5/8] board/ls2085_common: Increase malloc length York Sun
` (4 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: York Sun @ 2015-03-19 16:20 UTC (permalink / raw)
To: u-boot
From: Prabhakar Kushwaha <prabhakar@freescale.com>
LDPAA Ethernet driver is a freescale's new ethernet driver based on
Layerscape architecture.
Every ethernet driver controls on DPNI object. Where all DPNIs share
one common DPBP and DPIO object to support Rx and Tx flows.
Signed-off-by: Prabhakar Kushwaha <prabhakar@freescale.com>
CC: Cristian Sovaiala <cristian.sovaiala@freescale.com>
CC: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
CC: J. German Rivera <German.Rivera@freescale.com>
---
arch/arm/include/asm/arch-fsl-lsch3/config.h | 6 +
drivers/net/Makefile | 1 +
drivers/net/fsl-mc/mc.c | 16 +-
drivers/net/{fsl-mc/dpio => ldpaa_eth}/Makefile | 5 +-
drivers/net/ldpaa_eth/ldpaa_eth.c | 695 +++++++++++++++++++++++
drivers/net/ldpaa_eth/ldpaa_eth.h | 153 +++++
include/fsl-mc/fsl_mc_private.h | 2 +
7 files changed, 872 insertions(+), 6 deletions(-)
copy drivers/net/{fsl-mc/dpio => ldpaa_eth}/Makefile (59%)
create mode 100644 drivers/net/ldpaa_eth/ldpaa_eth.c
create mode 100644 drivers/net/ldpaa_eth/ldpaa_eth.h
diff --git a/arch/arm/include/asm/arch-fsl-lsch3/config.h b/arch/arm/include/asm/arch-fsl-lsch3/config.h
index 0217582..1d2a7fa 100644
--- a/arch/arm/include/asm/arch-fsl-lsch3/config.h
+++ b/arch/arm/include/asm/arch-fsl-lsch3/config.h
@@ -10,6 +10,12 @@
#include <fsl_ddrc_version.h>
#define CONFIG_SYS_PAGE_SIZE 0x10000
+
+#ifndef L1_CACHE_BYTES
+#define L1_CACHE_SHIFT 6
+#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
+#endif
+
#define CONFIG_MP
#define CONFIG_SYS_FSL_OCRAM_BASE 0x18000000 /* initial RAM */
/* Link Definitions */
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index b8b0803..5497934 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -65,4 +65,5 @@ obj-$(CONFIG_XILINX_LL_TEMAC) += xilinx_ll_temac.o xilinx_ll_temac_mdio.o \
xilinx_ll_temac_fifo.o xilinx_ll_temac_sdma.o
obj-$(CONFIG_ZYNQ_GEM) += zynq_gem.o
obj-$(CONFIG_FSL_MC_ENET) += fsl-mc/
+obj-$(CONFIG_FSL_MC_ENET) += ldpaa_eth/
obj-$(CONFIG_VSC9953) += vsc9953.o
diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c
index e29ee3d..2a2b0af 100644
--- a/drivers/net/fsl-mc/mc.c
+++ b/drivers/net/fsl-mc/mc.c
@@ -397,9 +397,10 @@ int dpbp_init(struct dprc_obj_desc obj_desc)
return 0;
}
-int dprc_init_container_obj(struct dprc_obj_desc obj_desc)
+int dprc_init_container_obj(struct dprc_obj_desc obj_desc, uint16_t dprc_handle)
{
- int error = 0;
+ int error = 0, state = 0;
+ struct dprc_endpoint dpni_endpoint, dpmac_endpoint;
if (!strcmp(obj_desc.type, "dpbp")) {
if (!dflt_dpbp) {
error = dpbp_init(obj_desc);
@@ -412,6 +413,15 @@ int dprc_init_container_obj(struct dprc_obj_desc obj_desc)
if (error < 0)
printf("dpio_init failed\n");
}
+ } else if (!strcmp(obj_desc.type, "dpni")) {
+ strcpy(dpni_endpoint.type, obj_desc.type);
+ dpni_endpoint.id = obj_desc.id;
+ error = dprc_get_connection(dflt_mc_io, dprc_handle,
+ &dpni_endpoint, &dpmac_endpoint, &state);
+ if (!strcmp(dpmac_endpoint.type, "dpmac"))
+ error = ldpaa_eth_init(obj_desc);
+ if (error < 0)
+ printf("ldpaa_eth_init failed\n");
}
return error;
@@ -436,7 +446,7 @@ int dprc_scan_container_obj(uint16_t dprc_handle, char *obj_type, int i)
debug("Discovered object: type %s, id %d, req %s\n",
obj_desc.type, obj_desc.id, obj_type);
- error = dprc_init_container_obj(obj_desc);
+ error = dprc_init_container_obj(obj_desc, dprc_handle);
if (error < 0) {
printf("dprc_init_container_obj(i=%d) failed: %d\n",
i, error);
diff --git a/drivers/net/fsl-mc/dpio/Makefile b/drivers/net/ldpaa_eth/Makefile
similarity index 59%
copy from drivers/net/fsl-mc/dpio/Makefile
copy to drivers/net/ldpaa_eth/Makefile
index 1ccefc0..3b1a60b 100644
--- a/drivers/net/fsl-mc/dpio/Makefile
+++ b/drivers/net/ldpaa_eth/Makefile
@@ -4,6 +4,5 @@
# SPDX-License-Identifier: GPL-2.0+
#
-# Layerscape MC DPIO driver
-obj-y += dpio.o \
- qbman_portal.o
+# Layerscape LDPAA driver
+obj-y += ldpaa_eth.o
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c
new file mode 100644
index 0000000..b79942f
--- /dev/null
+++ b/drivers/net/ldpaa_eth/ldpaa_eth.c
@@ -0,0 +1,695 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/types.h>
+#include <malloc.h>
+#include <net.h>
+#include <hwconfig.h>
+#include <phy.h>
+#include <linux/compat.h>
+
+#include "ldpaa_eth.h"
+
+static int init_phy(struct eth_device *dev)
+{
+ /*TODO for external PHY */
+
+ return 0;
+}
+
+static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv,
+ const struct dpaa_fd *fd)
+{
+ u64 fd_addr;
+ uint16_t fd_offset;
+ uint32_t fd_length;
+ struct ldpaa_fas *fas;
+ uint32_t status, err;
+ struct qbman_release_desc releasedesc;
+ struct qbman_swp *swp = dflt_dpio->sw_portal;
+
+ invalidate_dcache_all();
+
+ fd_addr = ldpaa_fd_get_addr(fd);
+ fd_offset = ldpaa_fd_get_offset(fd);
+ fd_length = ldpaa_fd_get_len(fd);
+
+ debug("Rx frame:data addr=0x%p size=0x%x\n", (u64 *)fd_addr, fd_length);
+
+ if (fd->simple.frc & LDPAA_FD_FRC_FASV) {
+ /* Read the frame annotation status word and check for errors */
+ fas = (struct ldpaa_fas *)
+ ((uint8_t *)(fd_addr) +
+ priv->buf_layout.private_data_size);
+ status = le32_to_cpu(fas->status);
+ if (status & LDPAA_ETH_RX_ERR_MASK) {
+ printf("Rx frame error(s): 0x%08x\n",
+ status & LDPAA_ETH_RX_ERR_MASK);
+ goto error;
+ } else if (status & LDPAA_ETH_RX_UNSUPP_MASK) {
+ printf("Unsupported feature in bitmask: 0x%08x\n",
+ status & LDPAA_ETH_RX_UNSUPP_MASK);
+ goto error;
+ }
+ }
+
+ debug("Rx frame: To Upper layer\n");
+ NetReceive((uint8_t *)(fd_addr) + fd_offset, fd_length);
+
+error:
+ qbman_release_desc_clear(&releasedesc);
+ qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
+ do {
+ /* Release buffer into the QBMAN */
+ err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1);
+ } while (err == -EBUSY);
+ return;
+}
+
+static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev)
+{
+ struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv;
+ const struct ldpaa_dq *dq;
+ const struct dpaa_fd *fd;
+ int i = 5, err = 0, status;
+ static struct qbman_pull_desc pulldesc;
+ struct qbman_swp *swp = dflt_dpio->sw_portal;
+
+ qbman_pull_desc_clear(&pulldesc);
+ qbman_pull_desc_set_numframes(&pulldesc, 1);
+ qbman_pull_desc_set_fq(&pulldesc, priv->rx_dflt_fqid);
+
+ while (--i) {
+ err = qbman_swp_pull(swp, &pulldesc);
+ if (err < 0) {
+ printf("Dequeue frames error:0x%08x\n", err);
+ continue;
+ }
+
+ dq = qbman_swp_dqrr_next(swp);
+ if (dq) {
+ /* Check for valid frame. If not sent a consume
+ * confirmation to QBMAN otherwise give it to NADK
+ * application and then send consume confirmation to
+ * QBMAN.
+ */
+ status = (uint8_t)ldpaa_dq_flags(dq);
+ if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) {
+ debug("Dequeue RX frames:");
+ debug("No frame delivered\n");
+
+ qbman_swp_dqrr_consume(swp, dq);
+ break;
+ }
+
+ fd = ldpaa_dq_fd(dq);
+
+ /* Obtain FD and process it */
+ ldpaa_eth_rx(priv, fd);
+ qbman_swp_dqrr_consume(swp, dq);
+ break;
+ }
+ }
+
+ return err;
+}
+
+static void ldpaa_eth_tx_conf(struct ldpaa_eth_priv *priv,
+ const struct dpaa_fd *fd)
+{
+ uint64_t fd_addr;
+ struct ldpaa_fas *fas;
+ uint32_t status, err;
+ struct qbman_release_desc releasedesc;
+ struct qbman_swp *swp = dflt_dpio->sw_portal;
+
+ invalidate_dcache_all();
+ fd_addr = ldpaa_fd_get_addr(fd);
+
+
+ debug("TX Conf frame:data addr=0x%p\n", (u64 *)fd_addr);
+
+ /* Check the status from the Frame Annotation */
+ if (fd->simple.frc & LDPAA_FD_FRC_FASV) {
+ fas = (struct ldpaa_fas *)
+ ((uint8_t *)(fd_addr) +
+ priv->buf_layout.private_data_size);
+ status = le32_to_cpu(fas->status);
+ if (status & LDPAA_ETH_TXCONF_ERR_MASK) {
+ printf("TxConf frame error(s): 0x%08x\n",
+ status & LDPAA_ETH_TXCONF_ERR_MASK);
+ }
+ }
+
+ qbman_release_desc_clear(&releasedesc);
+ qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
+ do {
+ /* Release buffer into the QBMAN */
+ err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1);
+ } while (err == -EBUSY);
+}
+
+static int ldpaa_eth_pull_dequeue_tx_conf(struct ldpaa_eth_priv *priv)
+{
+ const struct ldpaa_dq *dq;
+ const struct dpaa_fd *fd;
+ int err = 0;
+ int i = 5, status;
+ static struct qbman_pull_desc pulldesc;
+ struct qbman_swp *swp = dflt_dpio->sw_portal;
+
+ qbman_pull_desc_clear(&pulldesc);
+ qbman_pull_desc_set_numframes(&pulldesc, 1);
+ qbman_pull_desc_set_fq(&pulldesc, priv->tx_conf_fqid);
+
+ while (--i) {
+ err = qbman_swp_pull(swp, &pulldesc);
+ if (err < 0) {
+ printf("Dequeue TX conf frames error:0x%08x\n", err);
+ continue;
+ }
+
+ dq = qbman_swp_dqrr_next(swp);
+ if (dq) {
+ /* Check for valid frame. If not sent a consume
+ * confirmation to QBMAN otherwise give it to NADK
+ * application and then send consume confirmation to
+ * QBMAN.
+ */
+ status = (uint8_t)ldpaa_dq_flags(dq);
+ if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) {
+ debug("Dequeue TX conf frames:");
+ debug("No frame is delivered\n");
+
+ qbman_swp_dqrr_consume(swp, dq);
+ break;
+ }
+ fd = ldpaa_dq_fd(dq);
+
+ ldpaa_eth_tx_conf(priv, fd);
+ qbman_swp_dqrr_consume(swp, dq);
+ break;
+ }
+ }
+
+ return err;
+}
+
+static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len)
+{
+ struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
+ struct dpaa_fd fd;
+ u64 buffer_start;
+ int data_offset, err;
+ struct qbman_swp *swp = dflt_dpio->sw_portal;
+ struct qbman_eq_desc ed;
+
+ /* Setup the FD fields */
+ memset(&fd, 0, sizeof(fd));
+
+ data_offset = priv->tx_data_offset;
+
+ do {
+ err = qbman_swp_acquire(dflt_dpio->sw_portal,
+ dflt_dpbp->dpbp_attr.bpid,
+ &buffer_start, 1);
+ } while (err == -EBUSY);
+
+ if (err < 0) {
+ printf("qbman_swp_acquire() failed\n");
+ return -ENOMEM;
+ }
+
+ debug("TX data: malloc buffer start=0x%p\n", (u64 *)buffer_start);
+
+ memcpy(((uint8_t *)(buffer_start) + data_offset), buf, len);
+
+ flush_dcache_range(buffer_start, LDPAA_ETH_RX_BUFFER_SIZE);
+
+ ldpaa_fd_set_addr(&fd, (u64)buffer_start);
+ ldpaa_fd_set_offset(&fd, (uint16_t)(data_offset));
+ ldpaa_fd_set_bpid(&fd, dflt_dpbp->dpbp_attr.bpid);
+ ldpaa_fd_set_len(&fd, len);
+
+ fd.simple.ctrl = LDPAA_FD_CTRL_ASAL | LDPAA_FD_CTRL_PTA |
+ LDPAA_FD_CTRL_PTV1;
+
+ qbman_eq_desc_clear(&ed);
+ qbman_eq_desc_set_no_orp(&ed, 0);
+ qbman_eq_desc_set_qd(&ed, priv->tx_qdid, priv->tx_flow_id, 0);
+ err = qbman_swp_enqueue(swp, &ed, (const struct qbman_fd *)(&fd));
+ if (err < 0)
+ printf("error enqueueing Tx frame\n");
+
+ mdelay(1);
+
+ err = ldpaa_eth_pull_dequeue_tx_conf(priv);
+ if (err < 0)
+ printf("error Tx Conf frame\n");
+
+ return err;
+}
+
+static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
+{
+ struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
+ struct dpni_queue_attr rx_queue_attr;
+ struct dpni_tx_flow_attr tx_flow_attr;
+ uint8_t mac_addr[6];
+ int err;
+
+ if (net_dev->state == ETH_STATE_ACTIVE)
+ return 0;
+
+ /* DPNI initialization */
+ err = ldpaa_dpni_setup(priv);
+ if (err < 0)
+ goto err_dpni_setup;
+
+ err = ldpaa_dpbp_setup();
+ if (err < 0)
+ goto err_dpbp_setup;
+
+ /* DPNI binding DPBP */
+ err = ldpaa_dpni_bind(priv);
+ if (err)
+ goto err_bind;
+
+ err = dpni_get_primary_mac_addr(dflt_mc_io, priv->dpni_handle,
+ mac_addr);
+ if (err) {
+ printf("dpni_get_primary_mac_addr() failed\n");
+ return err;
+ }
+
+ memcpy(net_dev->enetaddr, mac_addr, 0x6);
+
+ /* setup the MAC address */
+ if (net_dev->enetaddr[0] & 0x01) {
+ printf("%s: MacAddress is multcast address\n", __func__);
+ return 1;
+ }
+
+#ifdef CONFIG_PHYLIB
+ /* TODO Check this path */
+ ret = phy_startup(priv->phydev);
+ if (ret) {
+ printf("%s: Could not initialize\n", priv->phydev->dev->name);
+ return ret;
+ }
+#else
+ priv->phydev->speed = SPEED_1000;
+ priv->phydev->link = 1;
+ priv->phydev->duplex = DUPLEX_FULL;
+#endif
+
+ err = dpni_enable(dflt_mc_io, priv->dpni_handle);
+ if (err < 0) {
+ printf("dpni_enable() failed\n");
+ return err;
+ }
+
+ /* TODO: support multiple Rx flows */
+ err = dpni_get_rx_flow(dflt_mc_io, priv->dpni_handle, 0, 0,
+ &rx_queue_attr);
+ if (err) {
+ printf("dpni_get_rx_flow() failed\n");
+ goto err_rx_flow;
+ }
+
+ priv->rx_dflt_fqid = rx_queue_attr.fqid;
+
+ err = dpni_get_qdid(dflt_mc_io, priv->dpni_handle, &priv->tx_qdid);
+ if (err) {
+ printf("dpni_get_qdid() failed\n");
+ goto err_qdid;
+ }
+
+ err = dpni_get_tx_flow(dflt_mc_io, priv->dpni_handle, priv->tx_flow_id,
+ &tx_flow_attr);
+ if (err) {
+ printf("dpni_get_tx_flow() failed\n");
+ goto err_tx_flow;
+ }
+
+ priv->tx_conf_fqid = tx_flow_attr.conf_err_attr.queue_attr.fqid;
+
+ if (!priv->phydev->link)
+ printf("%s: No link.\n", priv->phydev->dev->name);
+
+ return priv->phydev->link ? 0 : -1;
+
+err_tx_flow:
+err_qdid:
+err_rx_flow:
+ dpni_disable(dflt_mc_io, priv->dpni_handle);
+err_bind:
+ ldpaa_dpbp_free();
+err_dpbp_setup:
+ dpni_close(dflt_mc_io, priv->dpni_handle);
+err_dpni_setup:
+ return err;
+}
+
+static void ldpaa_eth_stop(struct eth_device *net_dev)
+{
+ struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
+ int err = 0;
+
+ if (net_dev->state == ETH_STATE_PASSIVE)
+ return;
+ /* Stop Tx and Rx traffic */
+ err = dpni_disable(dflt_mc_io, priv->dpni_handle);
+ if (err < 0)
+ printf("dpni_disable() failed\n");
+
+#ifdef CONFIG_PHYLIB
+ phy_shutdown(priv->phydev);
+#endif
+
+ ldpaa_dpbp_free();
+ dpni_reset(dflt_mc_io, priv->dpni_handle);
+ dpni_close(dflt_mc_io, priv->dpni_handle);
+}
+
+static void ldpaa_dpbp_drain_cnt(int count)
+{
+ uint64_t buf_array[7];
+ void *addr;
+ int ret, i;
+
+ BUG_ON(count > 7);
+
+ do {
+ ret = qbman_swp_acquire(dflt_dpio->sw_portal,
+ dflt_dpbp->dpbp_attr.bpid,
+ buf_array, count);
+ if (ret < 0) {
+ printf("qbman_swp_acquire() failed\n");
+ return;
+ }
+ for (i = 0; i < ret; i++) {
+ addr = (void *)buf_array[i];
+ debug("Free: buffer addr =0x%p\n", addr);
+ free(addr);
+ }
+ } while (ret);
+}
+
+static void ldpaa_dpbp_drain(void)
+{
+ int i;
+ for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7)
+ ldpaa_dpbp_drain_cnt(7);
+}
+
+static int ldpaa_bp_add_7(uint16_t bpid)
+{
+ uint64_t buf_array[7];
+ u8 *addr;
+ int i;
+ struct qbman_release_desc rd;
+
+ for (i = 0; i < 7; i++) {
+ addr = memalign(L1_CACHE_BYTES, LDPAA_ETH_RX_BUFFER_SIZE);
+ if (!addr) {
+ printf("addr allocation failed\n");
+ goto err_alloc;
+ }
+ memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE);
+
+ buf_array[i] = (uint64_t)addr;
+ debug("Release: buffer addr =0x%p\n", addr);
+ }
+
+release_bufs:
+ /* In case the portal is busy, retry until successful.
+ * This function is guaranteed to succeed in a reasonable amount
+ * of time.
+ */
+
+ do {
+ mdelay(1);
+ qbman_release_desc_clear(&rd);
+ qbman_release_desc_set_bpid(&rd, bpid);
+ } while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i));
+
+ return i;
+
+err_alloc:
+ if (i)
+ goto release_bufs;
+
+ return 0;
+}
+
+static int ldpaa_dpbp_seed(uint16_t bpid)
+{
+ int i;
+ int count;
+
+ for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) {
+ count = ldpaa_bp_add_7(bpid);
+ if (count < 7)
+ printf("Buffer Seed= %d\n", count);
+ }
+
+ return 0;
+}
+
+static int ldpaa_dpbp_setup(void)
+{
+ int err;
+
+ err = dpbp_open(dflt_mc_io, dflt_dpbp->dpbp_attr.id,
+ &dflt_dpbp->dpbp_handle);
+ if (err) {
+ printf("dpbp_open() failed\n");
+ goto err_open;
+ }
+
+ err = dpbp_enable(dflt_mc_io, dflt_dpbp->dpbp_handle);
+ if (err) {
+ printf("dpbp_enable() failed\n");
+ goto err_enable;
+ }
+
+ err = dpbp_get_attributes(dflt_mc_io, dflt_dpbp->dpbp_handle,
+ &dflt_dpbp->dpbp_attr);
+ if (err) {
+ printf("dpbp_get_attributes() failed\n");
+ goto err_get_attr;
+ }
+
+ err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid);
+ if (err) {
+ printf("Buffer seeding failed for DPBP %d (bpid=%d)\n",
+ dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid);
+ goto err_seed;
+ }
+
+ return 0;
+
+err_seed:
+err_get_attr:
+ dpbp_disable(dflt_mc_io, dflt_dpbp->dpbp_handle);
+err_enable:
+ dpbp_close(dflt_mc_io, dflt_dpbp->dpbp_handle);
+err_open:
+ return err;
+}
+
+static void ldpaa_dpbp_free(void)
+{
+ ldpaa_dpbp_drain();
+ dpbp_disable(dflt_mc_io, dflt_dpbp->dpbp_handle);
+ dpbp_reset(dflt_mc_io, dflt_dpbp->dpbp_handle);
+ dpbp_close(dflt_mc_io, dflt_dpbp->dpbp_handle);
+}
+
+static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv)
+{
+ int err;
+
+ /* and get a handle for the DPNI this interface is associate with */
+ err = dpni_open(dflt_mc_io, priv->dpni_id, &priv->dpni_handle);
+ if (err) {
+ printf("dpni_open() failed\n");
+ goto err_open;
+ }
+
+ err = dpni_get_attributes(dflt_mc_io, priv->dpni_handle,
+ &priv->dpni_attrs);
+ if (err) {
+ printf("dpni_get_attributes() failed (err=%d)\n", err);
+ goto err_get_attr;
+ }
+
+ /* Configure our buffers' layout */
+ priv->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT |
+ DPNI_BUF_LAYOUT_OPT_FRAME_STATUS |
+ DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE;
+ priv->buf_layout.pass_parser_result = true;
+ priv->buf_layout.pass_frame_status = true;
+ priv->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE;
+ /* ...rx, ... */
+ err = dpni_set_rx_buffer_layout(dflt_mc_io, priv->dpni_handle,
+ &priv->buf_layout);
+ if (err) {
+ printf("dpni_set_rx_buffer_layout() failed");
+ goto err_buf_layout;
+ }
+
+ /* ... tx, ... */
+ priv->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PARSER_RESULT;
+ err = dpni_set_tx_buffer_layout(dflt_mc_io, priv->dpni_handle,
+ &priv->buf_layout);
+ if (err) {
+ printf("dpni_set_tx_buffer_layout() failed");
+ goto err_buf_layout;
+ }
+
+ /* ... tx-confirm. */
+ priv->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE;
+ err = dpni_set_tx_conf_buffer_layout(dflt_mc_io, priv->dpni_handle,
+ &priv->buf_layout);
+ if (err) {
+ printf("dpni_set_tx_conf_buffer_layout() failed");
+ goto err_buf_layout;
+ }
+
+ /* Now that we've set our tx buffer layout, retrieve the minimum
+ * required tx data offset.
+ */
+ err = dpni_get_tx_data_offset(dflt_mc_io, priv->dpni_handle,
+ &priv->tx_data_offset);
+ if (err) {
+ printf("dpni_get_tx_data_offset() failed\n");
+ goto err_data_offset;
+ }
+
+ /* Warn in case TX data offset is not multiple of 64 bytes. */
+ WARN_ON(priv->tx_data_offset % 64);
+
+ /* Accomodate SWA space. */
+ priv->tx_data_offset += LDPAA_ETH_SWA_SIZE;
+ debug("priv->tx_data_offset=%d\n", priv->tx_data_offset);
+
+ return 0;
+
+err_data_offset:
+err_buf_layout:
+err_get_attr:
+ dpni_close(dflt_mc_io, priv->dpni_handle);
+err_open:
+ return err;
+}
+
+static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv)
+{
+ struct dpni_pools_cfg pools_params;
+ struct dpni_tx_flow_cfg dflt_tx_flow;
+ int err = 0;
+
+ pools_params.num_dpbp = 1;
+ pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id;
+ pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE;
+ err = dpni_set_pools(dflt_mc_io, priv->dpni_handle, &pools_params);
+ if (err) {
+ printf("dpni_set_pools() failed\n");
+ return err;
+ }
+
+ priv->tx_flow_id = DPNI_NEW_FLOW_ID;
+ memset(&dflt_tx_flow, 0, sizeof(dflt_tx_flow));
+
+ err = dpni_set_tx_flow(dflt_mc_io, priv->dpni_handle,
+ &priv->tx_flow_id, &dflt_tx_flow);
+ if (err) {
+ printf("dpni_set_tx_flow() failed\n");
+ return err;
+ }
+
+ return 0;
+}
+
+static int ldpaa_eth_netdev_init(struct eth_device *net_dev)
+{
+ int err;
+ struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
+
+ if (priv->type == LDPAA_ETH_1G_E)
+ sprintf(net_dev->name, "DTSEC%d", priv->dpni_id);
+ else
+ sprintf(net_dev->name, "TGEC%d", priv->dpni_id);
+
+ net_dev->iobase = 0;
+ net_dev->init = ldpaa_eth_open;
+ net_dev->halt = ldpaa_eth_stop;
+ net_dev->send = ldpaa_eth_tx;
+ net_dev->recv = ldpaa_eth_pull_dequeue_rx;
+/*
+ TODO: PHY MDIO information
+ priv->bus = info->bus;
+ priv->phyaddr = info->phy_addr;
+ priv->enet_if = info->enet_if;
+*/
+
+ if (init_phy(net_dev))
+ return 0;
+
+ err = eth_register(net_dev);
+ if (err < 0) {
+ printf("eth_register() = %d\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+int ldpaa_eth_init(struct dprc_obj_desc obj_desc)
+{
+ struct eth_device *net_dev = NULL;
+ struct ldpaa_eth_priv *priv = NULL;
+ int err = 0;
+
+
+ /* Net device */
+ net_dev = (struct eth_device *)malloc(sizeof(struct eth_device));
+ if (!net_dev) {
+ printf("eth_device malloc() failed\n");
+ return -ENOMEM;
+ }
+ memset(net_dev, 0, sizeof(struct eth_device));
+
+ /* alloc the ldpaa ethernet private struct */
+ priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv));
+ if (!priv) {
+ printf("ldpaa_eth_priv malloc() failed\n");
+ return -ENOMEM;
+ }
+ memset(priv, 0, sizeof(struct ldpaa_eth_priv));
+
+ net_dev->priv = (void *)priv;
+ priv->net_dev = (struct eth_device *)net_dev;
+ priv->dpni_id = obj_desc.id;
+
+ err = ldpaa_eth_netdev_init(net_dev);
+ if (err)
+ goto err_netdev_init;
+
+ debug("ldpaa ethernet: Probed interface %s\n", net_dev->name);
+ return 0;
+
+err_netdev_init:
+ free(priv);
+ net_dev->priv = NULL;
+ free(net_dev);
+
+ return err;
+}
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.h b/drivers/net/ldpaa_eth/ldpaa_eth.h
new file mode 100644
index 0000000..c7760ef
--- /dev/null
+++ b/drivers/net/ldpaa_eth/ldpaa_eth.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __LDPAA_ETH_H
+#define __LDPAA_ETH_H
+
+#include <linux/netdevice.h>
+#include <fsl-mc/fsl_mc.h>
+#include <fsl-mc/fsl_dpaa_fd.h>
+#include <fsl-mc/fsl_dprc.h>
+#include <fsl-mc/fsl_dpni.h>
+#include <fsl-mc/fsl_dpbp.h>
+#include <fsl-mc/fsl_dpio.h>
+#include <fsl-mc/fsl_qbman_portal.h>
+#include <fsl-mc/fsl_mc_private.h>
+
+
+enum ldpaa_eth_type {
+ LDPAA_ETH_1G_E,
+ LDPAA_ETH_10G_E,
+};
+
+/* Arbitrary values for now, but we'll need to tune */
+#define LDPAA_ETH_NUM_BUFS (2 * 7)
+#define LDPAA_ETH_REFILL_THRESH (LDPAA_ETH_NUM_BUFS/2)
+#define LDPAA_ETH_RX_BUFFER_SIZE 2048
+
+/* Hardware requires alignment for ingress/egress buffer addresses
+ * and ingress buffer lengths.
+ */
+#define LDPAA_ETH_BUF_ALIGN 64
+
+/* So far we're only accomodating a skb backpointer in the frame's
+ * software annotation, but the hardware options are either 0 or 64.
+ */
+#define LDPAA_ETH_SWA_SIZE 64
+
+/* Annotation valid bits in FD FRC */
+#define LDPAA_FD_FRC_FASV 0x8000
+#define LDPAA_FD_FRC_FAEADV 0x4000
+#define LDPAA_FD_FRC_FAPRV 0x2000
+#define LDPAA_FD_FRC_FAIADV 0x1000
+#define LDPAA_FD_FRC_FASWOV 0x0800
+#define LDPAA_FD_FRC_FAICFDV 0x0400
+
+/* Annotation bits in FD CTRL */
+#define LDPAA_FD_CTRL_ASAL 0x00020000 /* ASAL = 128 */
+#define LDPAA_FD_CTRL_PTA 0x00800000
+#define LDPAA_FD_CTRL_PTV1 0x00400000
+
+/* TODO: we may want to move this and other WRIOP related defines
+ * to a separate header
+ */
+/* Frame annotation status */
+struct ldpaa_fas {
+ u8 reserved;
+ u8 ppid;
+ __le16 ifpid;
+ __le32 status;
+} __packed;
+
+/* Debug frame, otherwise supposed to be discarded */
+#define LDPAA_ETH_FAS_DISC 0x80000000
+/* MACSEC frame */
+#define LDPAA_ETH_FAS_MS 0x40000000
+#define LDPAA_ETH_FAS_PTP 0x08000000
+/* Ethernet multicast frame */
+#define LDPAA_ETH_FAS_MC 0x04000000
+/* Ethernet broadcast frame */
+#define LDPAA_ETH_FAS_BC 0x02000000
+#define LDPAA_ETH_FAS_KSE 0x00040000
+#define LDPAA_ETH_FAS_EOFHE 0x00020000
+#define LDPAA_ETH_FAS_MNLE 0x00010000
+#define LDPAA_ETH_FAS_TIDE 0x00008000
+#define LDPAA_ETH_FAS_PIEE 0x00004000
+/* Frame length error */
+#define LDPAA_ETH_FAS_FLE 0x00002000
+/* Frame physical error; our favourite pastime */
+#define LDPAA_ETH_FAS_FPE 0x00001000
+#define LDPAA_ETH_FAS_PTE 0x00000080
+#define LDPAA_ETH_FAS_ISP 0x00000040
+#define LDPAA_ETH_FAS_PHE 0x00000020
+#define LDPAA_ETH_FAS_BLE 0x00000010
+/* L3 csum validation performed */
+#define LDPAA_ETH_FAS_L3CV 0x00000008
+/* L3 csum error */
+#define LDPAA_ETH_FAS_L3CE 0x00000004
+/* L4 csum validation performed */
+#define LDPAA_ETH_FAS_L4CV 0x00000002
+/* L4 csum error */
+#define LDPAA_ETH_FAS_L4CE 0x00000001
+/* These bits always signal errors */
+#define LDPAA_ETH_RX_ERR_MASK (LDPAA_ETH_FAS_DISC | \
+ LDPAA_ETH_FAS_KSE | \
+ LDPAA_ETH_FAS_EOFHE | \
+ LDPAA_ETH_FAS_MNLE | \
+ LDPAA_ETH_FAS_TIDE | \
+ LDPAA_ETH_FAS_PIEE | \
+ LDPAA_ETH_FAS_FLE | \
+ LDPAA_ETH_FAS_FPE | \
+ LDPAA_ETH_FAS_PTE | \
+ LDPAA_ETH_FAS_ISP | \
+ LDPAA_ETH_FAS_PHE | \
+ LDPAA_ETH_FAS_BLE | \
+ LDPAA_ETH_FAS_L3CE | \
+ LDPAA_ETH_FAS_L4CE)
+/* Unsupported features in the ingress */
+#define LDPAA_ETH_RX_UNSUPP_MASK LDPAA_ETH_FAS_MS
+/* TODO trim down the bitmask; not all of them apply to Tx-confirm */
+#define LDPAA_ETH_TXCONF_ERR_MASK (LDPAA_ETH_FAS_KSE | \
+ LDPAA_ETH_FAS_EOFHE | \
+ LDPAA_ETH_FAS_MNLE | \
+ LDPAA_ETH_FAS_TIDE)
+
+struct ldpaa_eth_priv {
+ struct eth_device *net_dev;
+ int dpni_id;
+ uint16_t dpni_handle;
+ struct dpni_attr dpni_attrs;
+ /* Insofar as the MC is concerned, we're using one layout on all 3 types
+ * of buffers (Rx, Tx, Tx-Conf).
+ */
+ struct dpni_buffer_layout buf_layout;
+ uint16_t tx_data_offset;
+
+ uint32_t rx_dflt_fqid;
+ uint16_t tx_qdid;
+ uint32_t tx_conf_fqid;
+ uint16_t tx_flow_id;
+
+ enum ldpaa_eth_type type; /* 1G or 10G ethernet */
+ phy_interface_t enet_if;
+ struct mii_dev *bus;
+ struct phy_device *phydev;
+ int phyaddr;
+
+};
+
+extern struct fsl_mc_io *dflt_mc_io;
+extern struct fsl_dpbp_obj *dflt_dpbp;
+extern struct fsl_dpio_obj *dflt_dpio;
+
+static void ldpaa_dpbp_drain_cnt(int count);
+static void ldpaa_dpbp_drain(void);
+static int ldpaa_dpbp_seed(uint16_t bpid);
+static void ldpaa_dpbp_free(void);
+static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv);
+static int ldpaa_dpbp_setup(void);
+static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv);
+#endif /* __LDPAA_H */
diff --git a/include/fsl-mc/fsl_mc_private.h b/include/fsl-mc/fsl_mc_private.h
index cf4b079..9f06978 100644
--- a/include/fsl-mc/fsl_mc_private.h
+++ b/include/fsl-mc/fsl_mc_private.h
@@ -16,6 +16,7 @@
#include <fsl-mc/fsl_mc_sys.h>
#include <fsl-mc/fsl_mc_cmd.h>
+#include <fsl-mc/fsl_dprc.h>
#include <fsl-mc/fsl_dpbp.h>
extern struct fsl_mc_io *dflt_mc_io;
@@ -45,4 +46,5 @@ struct fsl_dpio_obj {
extern struct fsl_dpio_obj *dflt_dpio;
int mc_init(void);
+int ldpaa_eth_init(struct dprc_obj_desc obj_desc);
#endif /* _FSL_MC_PRIVATE_H_ */
--
1.7.9.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH 5/8] board/ls2085_common: Increase malloc length
2015-03-19 16:20 [U-Boot] [PATCH 1/8] armv8/fsl-lsch3: Add Freescale Debug Server driver York Sun
` (2 preceding siblings ...)
2015-03-19 16:20 ` [U-Boot] [PATCH 4/8] driver/ldpaa_eth: Add LDPAA Ethernet driver York Sun
@ 2015-03-19 16:20 ` York Sun
2015-03-19 16:20 ` [U-Boot] [PATCH 6/8] driver/fsl_ifc: Add support to finalize CS1, CS3 address binding York Sun
` (3 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: York Sun @ 2015-03-19 16:20 UTC (permalink / raw)
To: u-boot
From: Prabhakar Kushwaha <prabhakar@freescale.com>
Increase malloc length for more than 2M.
Signed-off-by: Prabhakar Kushwaha <prabhakar@freescale.com>
Change-Id: Id3b87453be03c97467ab58c841274fb5ea0883f2
Reviewed-on: http://git.am.freescale.net:8181/26580
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
---
include/configs/ls2085a_common.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/configs/ls2085a_common.h b/include/configs/ls2085a_common.h
index c70ba70..eb7b9b2 100644
--- a/include/configs/ls2085a_common.h
+++ b/include/configs/ls2085a_common.h
@@ -78,7 +78,7 @@
#define COUNTER_FREQUENCY 12000000 /* 12MHz */
/* Size of malloc() pool */
-#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 128 * 1024)
+#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 2048 * 1024)
/* I2C */
#define CONFIG_CMD_I2C
--
1.7.9.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH 6/8] driver/fsl_ifc: Add support to finalize CS1, CS3 address binding
2015-03-19 16:20 [U-Boot] [PATCH 1/8] armv8/fsl-lsch3: Add Freescale Debug Server driver York Sun
` (3 preceding siblings ...)
2015-03-19 16:20 ` [U-Boot] [PATCH 5/8] board/ls2085_common: Increase malloc length York Sun
@ 2015-03-19 16:20 ` York Sun
2015-03-19 16:20 ` [U-Boot] [PATCH 7/8] nand/fsl_ifc: Increase eccstat[] for IFC 2.0 York Sun
` (2 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: York Sun @ 2015-03-19 16:20 UTC (permalink / raw)
To: u-boot
From: Prabhakar Kushwaha <prabhakar@freescale.com>
For fsl-lsch3, IFC is binded with address within 32-bit at fist.
After u-boot relocates to DDR, CS1, CS3 can be binded to higher
address to support large space.
Signed-off-by: Prabhakar Kushwaha <prabhakar@freescale.com>
Signed-off-by: York Sun <yorksun@freescale.com>
---
drivers/misc/fsl_ifc.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/misc/fsl_ifc.c b/drivers/misc/fsl_ifc.c
index 3902e9f..45d299c 100644
--- a/drivers/misc/fsl_ifc.c
+++ b/drivers/misc/fsl_ifc.c
@@ -168,4 +168,13 @@ void init_final_memctl_regs(void)
#ifdef CONFIG_SYS_CSPR0_FINAL
set_ifc_cspr(IFC_CS0, CONFIG_SYS_CSPR0_FINAL);
#endif
+#ifdef CONFIG_SYS_CSPR1_FINAL
+ set_ifc_cspr(IFC_CS1, CONFIG_SYS_CSPR1_FINAL);
+#endif
+#ifdef CONFIG_SYS_AMASK1_FINAL
+ set_ifc_amask(IFC_CS1, CONFIG_SYS_AMASK1_FINAL);
+#endif
+#ifdef CONFIG_SYS_CSPR3_FINAL
+ set_ifc_cspr(IFC_CS3, CONFIG_SYS_CSPR3_FINAL);
+#endif
}
--
1.7.9.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH 7/8] nand/fsl_ifc: Increase eccstat[] for IFC 2.0
2015-03-19 16:20 [U-Boot] [PATCH 1/8] armv8/fsl-lsch3: Add Freescale Debug Server driver York Sun
` (4 preceding siblings ...)
2015-03-19 16:20 ` [U-Boot] [PATCH 6/8] driver/fsl_ifc: Add support to finalize CS1, CS3 address binding York Sun
@ 2015-03-19 16:20 ` York Sun
2015-03-19 16:20 ` [U-Boot] [PATCH 8/8] driver/i2c/mxc: Add I2C3 and I2C4 for LS2085A York Sun
2015-04-23 23:36 ` [U-Boot] [PATCH 1/8] armv8/fsl-lsch3: Add Freescale Debug Server driver York Sun
7 siblings, 0 replies; 11+ messages in thread
From: York Sun @ 2015-03-19 16:20 UTC (permalink / raw)
To: u-boot
From: Scott Wood <scottwood@freescale.com>
IFC 2.0 doubled the SRAM size, which means double the number of
ECCSTAT registers. Fix the resulting array overflow.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
drivers/mtd/nand/fsl_ifc_nand.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index b283eae..16266fa 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -292,7 +292,7 @@ static int fsl_ifc_run_command(struct mtd_info *mtd)
struct fsl_ifc *ifc = ctrl->regs;
u32 timeo = (CONFIG_SYS_HZ * 10) / 1000;
u32 time_start;
- u32 eccstat[4] = {0};
+ u32 eccstat[8] = {0};
int i;
/* set the chip select for NAND Transaction */
@@ -325,8 +325,15 @@ static int fsl_ifc_run_command(struct mtd_info *mtd)
int sector = bufnum * chip->ecc.steps;
int sector_end = sector + chip->ecc.steps - 1;
- for (i = sector / 4; i <= sector_end / 4; i++)
+ for (i = sector / 4; i <= sector_end / 4; i++) {
+ if (i >= ARRAY_SIZE(eccstat)) {
+ printf("%s: eccstat too small for %d\n",
+ __func__, i);
+ return -EIO;
+ }
+
eccstat[i] = ifc_in32(&ifc->ifc_nand.nand_eccstat[i]);
+ }
for (i = sector; i <= sector_end; i++) {
errors = check_read_ecc(mtd, ctrl, eccstat, i);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH 8/8] driver/i2c/mxc: Add I2C3 and I2C4 for LS2085A
2015-03-19 16:20 [U-Boot] [PATCH 1/8] armv8/fsl-lsch3: Add Freescale Debug Server driver York Sun
` (5 preceding siblings ...)
2015-03-19 16:20 ` [U-Boot] [PATCH 7/8] nand/fsl_ifc: Increase eccstat[] for IFC 2.0 York Sun
@ 2015-03-19 16:20 ` York Sun
2015-03-20 5:31 ` Heiko Schocher
2015-04-23 23:36 ` [U-Boot] [PATCH 1/8] armv8/fsl-lsch3: Add Freescale Debug Server driver York Sun
7 siblings, 1 reply; 11+ messages in thread
From: York Sun @ 2015-03-19 16:20 UTC (permalink / raw)
To: u-boot
LS2085A uses mxc I2C driver and has four I2C buses.
Signed-off-by: York Sun <yorksun@freescale.com>
CC: Heiko Schocher <hs@denx.de>
---
drivers/i2c/mxc_i2c.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index fc5ee35..02a173e 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -114,6 +114,9 @@ static u16 i2c_clk_div[50][2] = {
#ifndef CONFIG_SYS_MXC_I2C3_SPEED
#define CONFIG_SYS_MXC_I2C3_SPEED 100000
#endif
+#ifndef CONFIG_SYS_MXC_I2C4_SPEED
+#define CONFIG_SYS_MXC_I2C4_SPEED 100000
+#endif
#ifndef CONFIG_SYS_MXC_I2C1_SLAVE
#define CONFIG_SYS_MXC_I2C1_SLAVE 0
@@ -124,6 +127,9 @@ static u16 i2c_clk_div[50][2] = {
#ifndef CONFIG_SYS_MXC_I2C3_SLAVE
#define CONFIG_SYS_MXC_I2C3_SLAVE 0
#endif
+#ifndef CONFIG_SYS_MXC_I2C4_SLAVE
+#define CONFIG_SYS_MXC_I2C4_SLAVE 0
+#endif
/*
@@ -545,10 +551,18 @@ U_BOOT_I2C_ADAP_COMPLETE(mxc1, mxc_i2c_init, mxc_i2c_probe,
CONFIG_SYS_MXC_I2C2_SLAVE, 1)
#if defined(CONFIG_MX31) || defined(CONFIG_MX35) ||\
defined(CONFIG_MX51) || defined(CONFIG_MX53) ||\
- defined(CONFIG_MX6) || defined(CONFIG_LS102XA)
+ defined(CONFIG_MX6) || defined(CONFIG_LS102XA) ||\
+ defined(CONFIG_LS2085A)
U_BOOT_I2C_ADAP_COMPLETE(mxc2, mxc_i2c_init, mxc_i2c_probe,
mxc_i2c_read, mxc_i2c_write,
mxc_i2c_set_bus_speed,
CONFIG_SYS_MXC_I2C3_SPEED,
CONFIG_SYS_MXC_I2C3_SLAVE, 2)
#endif
+#ifdef CONFIG_LS2085A
+U_BOOT_I2C_ADAP_COMPLETE(mxc3, mxc_i2c_init, mxc_i2c_probe,
+ mxc_i2c_read, mxc_i2c_write,
+ mxc_i2c_set_bus_speed,
+ CONFIG_SYS_MXC_I2C4_SPEED,
+ CONFIG_SYS_MXC_I2C4_SLAVE, 3)
+#endif
--
1.7.9.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH 8/8] driver/i2c/mxc: Add I2C3 and I2C4 for LS2085A
2015-03-19 16:20 ` [U-Boot] [PATCH 8/8] driver/i2c/mxc: Add I2C3 and I2C4 for LS2085A York Sun
@ 2015-03-20 5:31 ` Heiko Schocher
2015-03-20 16:09 ` York Sun
0 siblings, 1 reply; 11+ messages in thread
From: Heiko Schocher @ 2015-03-20 5:31 UTC (permalink / raw)
To: u-boot
Hello Yrok,
Am 19.03.2015 17:20, schrieb York Sun:
> LS2085A uses mxc I2C driver and has four I2C buses.
>
> Signed-off-by: York Sun <yorksun@freescale.com>
> CC: Heiko Schocher <hs@denx.de>
> ---
> drivers/i2c/mxc_i2c.c | 16 +++++++++++++++-
> 1 file changed, 15 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
> index fc5ee35..02a173e 100644
> --- a/drivers/i2c/mxc_i2c.c
> +++ b/drivers/i2c/mxc_i2c.c
> @@ -114,6 +114,9 @@ static u16 i2c_clk_div[50][2] = {
> #ifndef CONFIG_SYS_MXC_I2C3_SPEED
> #define CONFIG_SYS_MXC_I2C3_SPEED 100000
> #endif
> +#ifndef CONFIG_SYS_MXC_I2C4_SPEED
> +#define CONFIG_SYS_MXC_I2C4_SPEED 100000
> +#endif
>
> #ifndef CONFIG_SYS_MXC_I2C1_SLAVE
> #define CONFIG_SYS_MXC_I2C1_SLAVE 0
> @@ -124,6 +127,9 @@ static u16 i2c_clk_div[50][2] = {
> #ifndef CONFIG_SYS_MXC_I2C3_SLAVE
> #define CONFIG_SYS_MXC_I2C3_SLAVE 0
> #endif
> +#ifndef CONFIG_SYS_MXC_I2C4_SLAVE
> +#define CONFIG_SYS_MXC_I2C4_SLAVE 0
> +#endif
>
>
> /*
> @@ -545,10 +551,18 @@ U_BOOT_I2C_ADAP_COMPLETE(mxc1, mxc_i2c_init, mxc_i2c_probe,
> CONFIG_SYS_MXC_I2C2_SLAVE, 1)
> #if defined(CONFIG_MX31) || defined(CONFIG_MX35) ||\
> defined(CONFIG_MX51) || defined(CONFIG_MX53) ||\
> - defined(CONFIG_MX6) || defined(CONFIG_LS102XA)
> + defined(CONFIG_MX6) || defined(CONFIG_LS102XA) ||\
> + defined(CONFIG_LS2085A)
> U_BOOT_I2C_ADAP_COMPLETE(mxc2, mxc_i2c_init, mxc_i2c_probe,
> mxc_i2c_read, mxc_i2c_write,
> mxc_i2c_set_bus_speed,
> CONFIG_SYS_MXC_I2C3_SPEED,
> CONFIG_SYS_MXC_I2C3_SLAVE, 2)
> #endif
> +#ifdef CONFIG_LS2085A
> +U_BOOT_I2C_ADAP_COMPLETE(mxc3, mxc_i2c_init, mxc_i2c_probe,
> + mxc_i2c_read, mxc_i2c_write,
> + mxc_i2c_set_bus_speed,
> + CONFIG_SYS_MXC_I2C4_SPEED,
> + CONFIG_SYS_MXC_I2C4_SLAVE, 3)
> +#endif
Dummy question ... CONFIG_LS2085A (and CONFIG_LS102XA) are
board spezific defines, right?
If so, I do not want them in driver specific code... because
every board which uses this driver has to add here more defines.
Could you introduce a SoC or at least a driver specific define
here? Maybe CONFIG_SYS_I2C_MXC_I2C4 if no SoC specific code
is possible ...
Thanks!
bye,
Heiko
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
^ permalink raw reply [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH 8/8] driver/i2c/mxc: Add I2C3 and I2C4 for LS2085A
2015-03-20 5:31 ` Heiko Schocher
@ 2015-03-20 16:09 ` York Sun
0 siblings, 0 replies; 11+ messages in thread
From: York Sun @ 2015-03-20 16:09 UTC (permalink / raw)
To: u-boot
On 03/19/2015 10:31 PM, Heiko Schocher wrote:
> Hello Yrok,
>
> Am 19.03.2015 17:20, schrieb York Sun:
>> LS2085A uses mxc I2C driver and has four I2C buses.
>>
>> Signed-off-by: York Sun <yorksun@freescale.com>
>> CC: Heiko Schocher <hs@denx.de>
>> ---
>> drivers/i2c/mxc_i2c.c | 16 +++++++++++++++-
>> 1 file changed, 15 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
>> index fc5ee35..02a173e 100644
>> --- a/drivers/i2c/mxc_i2c.c
>> +++ b/drivers/i2c/mxc_i2c.c
>> @@ -114,6 +114,9 @@ static u16 i2c_clk_div[50][2] = {
>> #ifndef CONFIG_SYS_MXC_I2C3_SPEED
>> #define CONFIG_SYS_MXC_I2C3_SPEED 100000
>> #endif
>> +#ifndef CONFIG_SYS_MXC_I2C4_SPEED
>> +#define CONFIG_SYS_MXC_I2C4_SPEED 100000
>> +#endif
>>
>> #ifndef CONFIG_SYS_MXC_I2C1_SLAVE
>> #define CONFIG_SYS_MXC_I2C1_SLAVE 0
>> @@ -124,6 +127,9 @@ static u16 i2c_clk_div[50][2] = {
>> #ifndef CONFIG_SYS_MXC_I2C3_SLAVE
>> #define CONFIG_SYS_MXC_I2C3_SLAVE 0
>> #endif
>> +#ifndef CONFIG_SYS_MXC_I2C4_SLAVE
>> +#define CONFIG_SYS_MXC_I2C4_SLAVE 0
>> +#endif
>>
>>
>> /*
>> @@ -545,10 +551,18 @@ U_BOOT_I2C_ADAP_COMPLETE(mxc1, mxc_i2c_init, mxc_i2c_probe,
>> CONFIG_SYS_MXC_I2C2_SLAVE, 1)
>> #if defined(CONFIG_MX31) || defined(CONFIG_MX35) ||\
>> defined(CONFIG_MX51) || defined(CONFIG_MX53) ||\
>> - defined(CONFIG_MX6) || defined(CONFIG_LS102XA)
>> + defined(CONFIG_MX6) || defined(CONFIG_LS102XA) ||\
>> + defined(CONFIG_LS2085A)
>> U_BOOT_I2C_ADAP_COMPLETE(mxc2, mxc_i2c_init, mxc_i2c_probe,
>> mxc_i2c_read, mxc_i2c_write,
>> mxc_i2c_set_bus_speed,
>> CONFIG_SYS_MXC_I2C3_SPEED,
>> CONFIG_SYS_MXC_I2C3_SLAVE, 2)
>> #endif
>> +#ifdef CONFIG_LS2085A
>> +U_BOOT_I2C_ADAP_COMPLETE(mxc3, mxc_i2c_init, mxc_i2c_probe,
>> + mxc_i2c_read, mxc_i2c_write,
>> + mxc_i2c_set_bus_speed,
>> + CONFIG_SYS_MXC_I2C4_SPEED,
>> + CONFIG_SYS_MXC_I2C4_SLAVE, 3)
>> +#endif
>
> Dummy question ... CONFIG_LS2085A (and CONFIG_LS102XA) are
> board spezific defines, right?
>
> If so, I do not want them in driver specific code... because
> every board which uses this driver has to add here more defines.
>
> Could you introduce a SoC or at least a driver specific define
> here? Maybe CONFIG_SYS_I2C_MXC_I2C4 if no SoC specific code
> is possible ...
>
Agree. Will fix in next version. Thanks.
York
^ permalink raw reply [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH 1/8] armv8/fsl-lsch3: Add Freescale Debug Server driver
2015-03-19 16:20 [U-Boot] [PATCH 1/8] armv8/fsl-lsch3: Add Freescale Debug Server driver York Sun
` (6 preceding siblings ...)
2015-03-19 16:20 ` [U-Boot] [PATCH 8/8] driver/i2c/mxc: Add I2C3 and I2C4 for LS2085A York Sun
@ 2015-04-23 23:36 ` York Sun
7 siblings, 0 replies; 11+ messages in thread
From: York Sun @ 2015-04-23 23:36 UTC (permalink / raw)
To: u-boot
On 03/19/2015 09:20 AM, York Sun wrote:
> From: Bhupesh Sharma <bhupesh.sharma@freescale.com>
>
> The Debug Server driver is responsible for loading the Debug
> server FW on the Service Processor (Cortex-A5 core) on LS2085A like
> SoCs and then polling for the successful initialization of the same.
> TOP MEM HIDE is adjusted to ensure the space required by Debug Server
> FW is accounted for. MC uses the DDR area which is calculated as:
>
> MC DDR region start = Top of DDR - area reserved by Debug Server FW
>
> Signed-off-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
> ---
This set is to fsl-qoriq master, awaiting upstream.
[U-Boot,1/8] armv8/fsl-lsch3: Add Freescale Debug Server driver
[U-Boot,2/8] fsl-ch3/README: Add description for NOR flash layout (firmware images)
[U-Boot,3/8] driver/fsl-mc: Add support of MC Flibs
[U-Boot,4/8] driver/ldpaa_eth: Add LDPAA Ethernet driver
[U-Boot,5/8] board/ls2085_common: Increase malloc length
[U-Boot,6/8] driver/fsl_ifc: Add support to finalize CS1, CS3 address binding
[U-Boot,7/8] nand/fsl_ifc: Increase eccstat[] for IFC 2.0
[U-Boot,v2,8/8] driver/i2c/mxc: Enable I2C bus 3 and 4
York
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2015-04-23 23:36 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-03-19 16:20 [U-Boot] [PATCH 1/8] armv8/fsl-lsch3: Add Freescale Debug Server driver York Sun
2015-03-19 16:20 ` [U-Boot] [PATCH 2/8] fsl-ch3/README: Add description for NOR flash layout (firmware images) York Sun
2015-03-19 16:20 ` [U-Boot] [PATCH 3/8] driver/fsl-mc: Add support of MC Flibs York Sun
2015-03-19 16:20 ` [U-Boot] [PATCH 4/8] driver/ldpaa_eth: Add LDPAA Ethernet driver York Sun
2015-03-19 16:20 ` [U-Boot] [PATCH 5/8] board/ls2085_common: Increase malloc length York Sun
2015-03-19 16:20 ` [U-Boot] [PATCH 6/8] driver/fsl_ifc: Add support to finalize CS1, CS3 address binding York Sun
2015-03-19 16:20 ` [U-Boot] [PATCH 7/8] nand/fsl_ifc: Increase eccstat[] for IFC 2.0 York Sun
2015-03-19 16:20 ` [U-Boot] [PATCH 8/8] driver/i2c/mxc: Add I2C3 and I2C4 for LS2085A York Sun
2015-03-20 5:31 ` Heiko Schocher
2015-03-20 16:09 ` York Sun
2015-04-23 23:36 ` [U-Boot] [PATCH 1/8] armv8/fsl-lsch3: Add Freescale Debug Server driver York Sun
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox