summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c')
-rwxr-xr-xdrivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c2908
1 files changed, 2908 insertions, 0 deletions
diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c
new file mode 100755
index 0000000..31f654b
--- /dev/null
+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c
@@ -0,0 +1,2908 @@
+/*
+ * Copyright 2008-2012 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ @File lnxwrp_fm.c
+ @Author Shlomi Gridish
+ @Description FM Linux wrapper functions.
+*/
+
+#include <linux/version.h>
+#include <linux/slab.h>
+#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
+#define MODVERSIONS
+#endif
+#ifdef MODVERSIONS
+#include <config/modversions.h>
+#endif /* MODVERSIONS */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/clk.h>
+#include <asm/uaccess.h>
+#include <asm/errno.h>
+#ifndef CONFIG_FMAN_ARM
+#include <sysdev/fsl_soc.h>
+#include <linux/fsl/guts.h>
+#include <linux/fsl/svr.h>
+#endif
+#include <linux/stat.h> /* For file access mask */
+#include <linux/skbuff.h>
+#include <linux/proc_fs.h>
+
+/* NetCommSw Headers --------------- */
+#include "std_ext.h"
+#include "error_ext.h"
+#include "sprint_ext.h"
+#include "debug_ext.h"
+#include "sys_io_ext.h"
+
+#include "fm_ioctls.h"
+
+#include "lnxwrp_fm.h"
+#include "lnxwrp_resources.h"
+#include "lnxwrp_sysfs_fm.h"
+#include "lnxwrp_sysfs_fm_port.h"
+#include "lnxwrp_exp_sym.h"
+#include "fm_common.h"
+#include "../../sdk_fman/Peripherals/FM/fm.h"
+#define __ERR_MODULE__ MODULE_FM
+
+extern struct device_node *GetFmPortAdvArgsDevTreeNode (struct device_node *fm_node,
+ e_FmPortType portType,
+ uint8_t portId);
+
+#define PROC_PRINT(args...) offset += sprintf(buf+offset,args)
+
+#define ADD_ADV_CONFIG_NO_RET(_func, _param) \
+ do { \
+ if (i<max){ \
+ p_Entry = &p_Entrys[i]; \
+ p_Entry->p_Function = _func; \
+ _param \
+ i++; \
+ } \
+ else \
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE,\
+ ("Number of advanced-configuration entries exceeded"));\
+ } while (0)
+
+/* Bootarg used to override the Kconfig FSL_FM_MAX_FRAME_SIZE value */
+#define FSL_FM_MAX_FRM_BOOTARG "fsl_fm_max_frm"
+
+/* Bootarg used to override FSL_FM_RX_EXTRA_HEADROOM Kconfig value */
+#define FSL_FM_RX_EXTRA_HEADROOM_BOOTARG "fsl_fm_rx_extra_headroom"
+
+/* Minimum and maximum value for the fsl_fm_rx_extra_headroom bootarg */
+#define FSL_FM_RX_EXTRA_HEADROOM_MIN 16
+#define FSL_FM_RX_EXTRA_HEADROOM_MAX 384
+
+#define FSL_FM_PAUSE_TIME_ENABLE 0xf000
+#define FSL_FM_PAUSE_TIME_DISABLE 0
+#define FSL_FM_PAUSE_THRESH_DEFAULT 0
+
+/*
+ * Max frame size, across all interfaces.
+ * Configurable from Kconfig or bootargs, to avoid allocating
+ * oversized (socket) buffers when not using jumbo frames.
+ * Must be large enough to accommodate the network MTU, but small enough
+ * to avoid wasting skb memory.
+ *
+ * Could be overridden once, at boot-time, via the
+ * fm_set_max_frm() callback.
+ */
+int fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
+
+/*
+ * Extra headroom for Rx buffers.
+ * FMan is instructed to allocate, on the Rx path, this amount of
+ * space at the beginning of a data buffer, beside the DPA private
+ * data area and the IC fields.
+ * Does not impact Tx buffer layout.
+ *
+ * Configurable from Kconfig or bootargs. Zero by default, it's needed
+ * on particular forwarding scenarios that add extra headers to the
+ * forwarded frame.
+ */
+int fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
+
+#ifdef CONFIG_FMAN_PFC
+static int fsl_fm_pfc_quanta[] = {
+ CONFIG_FMAN_PFC_QUANTA_0,
+ CONFIG_FMAN_PFC_QUANTA_1,
+ CONFIG_FMAN_PFC_QUANTA_2,
+ CONFIG_FMAN_PFC_QUANTA_3
+};
+#endif
+
+static t_LnxWrpFm lnxWrpFm;
+
+int fm_get_max_frm()
+{
+ return fsl_fm_max_frm;
+}
+EXPORT_SYMBOL(fm_get_max_frm);
+
+int fm_get_rx_extra_headroom()
+{
+ return ALIGN(fsl_fm_rx_extra_headroom, 16);
+}
+EXPORT_SYMBOL(fm_get_rx_extra_headroom);
+
+static int __init fm_set_max_frm(char *str)
+{
+ int ret = 0;
+
+ ret = get_option(&str, &fsl_fm_max_frm);
+ if (ret != 1) {
+ /*
+ * This will only work if CONFIG_EARLY_PRINTK is compiled in,
+ * and something like "earlyprintk=serial,uart0,115200" is
+ * specified in the bootargs
+ */
+ printk(KERN_WARNING "No suitable %s=<int> prop in bootargs; "
+ "will use the default FSL_FM_MAX_FRAME_SIZE (%d) "
+ "from Kconfig.\n", FSL_FM_MAX_FRM_BOOTARG,
+ CONFIG_FSL_FM_MAX_FRAME_SIZE);
+
+ fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
+ return 1;
+ }
+
+ /* Don't allow invalid bootargs; fallback to the Kconfig value */
+ if (fsl_fm_max_frm < 64 || fsl_fm_max_frm > 9600) {
+ printk(KERN_WARNING "Invalid %s=%d in bootargs, valid range is "
+ "64-9600. Falling back to the FSL_FM_MAX_FRAME_SIZE (%d) "
+ "from Kconfig.\n",
+ FSL_FM_MAX_FRM_BOOTARG, fsl_fm_max_frm,
+ CONFIG_FSL_FM_MAX_FRAME_SIZE);
+
+ fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
+ return 1;
+ }
+
+ printk(KERN_INFO "Using fsl_fm_max_frm=%d from bootargs\n",
+ fsl_fm_max_frm);
+ return 0;
+}
+early_param(FSL_FM_MAX_FRM_BOOTARG, fm_set_max_frm);
+
+static int __init fm_set_rx_extra_headroom(char *str)
+{
+ int ret;
+
+ ret = get_option(&str, &fsl_fm_rx_extra_headroom);
+
+ if (ret != 1) {
+ printk(KERN_WARNING "No suitable %s=<int> prop in bootargs; "
+ "will use the default FSL_FM_RX_EXTRA_HEADROOM (%d) "
+ "from Kconfig.\n", FSL_FM_RX_EXTRA_HEADROOM_BOOTARG,
+ CONFIG_FSL_FM_RX_EXTRA_HEADROOM);
+ fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
+
+ return 1;
+ }
+
+ if (fsl_fm_rx_extra_headroom < FSL_FM_RX_EXTRA_HEADROOM_MIN ||
+ fsl_fm_rx_extra_headroom > FSL_FM_RX_EXTRA_HEADROOM_MAX) {
+ printk(KERN_WARNING "Invalid value for %s=%d prop in "
+ "bootargs; will use the default "
+ "FSL_FM_RX_EXTRA_HEADROOM (%d) from Kconfig.\n",
+ FSL_FM_RX_EXTRA_HEADROOM_BOOTARG,
+ fsl_fm_rx_extra_headroom,
+ CONFIG_FSL_FM_RX_EXTRA_HEADROOM);
+ fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
+ }
+
+ printk(KERN_INFO "Using fsl_fm_rx_extra_headroom=%d from bootargs\n",
+ fsl_fm_rx_extra_headroom);
+
+ return 0;
+}
+early_param(FSL_FM_RX_EXTRA_HEADROOM_BOOTARG, fm_set_rx_extra_headroom);
+
+static irqreturn_t fm_irq(int irq, void *_dev)
+{
+ t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)_dev;
+#ifdef CONFIG_PM_SLEEP
+ t_Fm *p_Fm = (t_Fm*)p_LnxWrpFmDev->h_Dev;
+#endif
+ if (!p_LnxWrpFmDev || !p_LnxWrpFmDev->h_Dev)
+ return IRQ_NONE;
+
+#ifdef CONFIG_PM_SLEEP
+ if (fman_get_normal_pending(p_Fm->p_FmFpmRegs) & INTR_EN_WAKEUP)
+ {
+ pm_wakeup_event(p_LnxWrpFmDev->dev, 200);
+ }
+#endif
+ FM_EventIsr(p_LnxWrpFmDev->h_Dev);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t fm_err_irq(int irq, void *_dev)
+{
+ t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)_dev;
+
+ if (!p_LnxWrpFmDev || !p_LnxWrpFmDev->h_Dev)
+ return IRQ_NONE;
+
+ if (FM_ErrorIsr(p_LnxWrpFmDev->h_Dev) == E_OK)
+ return IRQ_HANDLED;
+
+ return IRQ_NONE;
+}
+
+/* used to protect FMD/LLD from concurrent calls in functions fm_mutex_lock / fm_mutex_unlock */
+static struct mutex lnxwrp_mutex;
+
+static t_LnxWrpFmDev * CreateFmDev(uint8_t id)
+{
+ t_LnxWrpFmDev *p_LnxWrpFmDev;
+ int j;
+
+ p_LnxWrpFmDev = (t_LnxWrpFmDev *)XX_Malloc(sizeof(t_LnxWrpFmDev));
+ if (!p_LnxWrpFmDev)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
+ return NULL;
+ }
+
+ memset(p_LnxWrpFmDev, 0, sizeof(t_LnxWrpFmDev));
+ p_LnxWrpFmDev->fmDevSettings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
+ memset(p_LnxWrpFmDev->fmDevSettings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
+ p_LnxWrpFmDev->fmPcdDevSettings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
+ memset(p_LnxWrpFmDev->fmPcdDevSettings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
+ p_LnxWrpFmDev->hcPort.settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
+ memset(p_LnxWrpFmDev->hcPort.settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
+ for (j=0; j<FM_MAX_NUM_OF_RX_PORTS; j++)
+ {
+ p_LnxWrpFmDev->rxPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
+ memset(p_LnxWrpFmDev->rxPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
+ }
+ for (j=0; j<FM_MAX_NUM_OF_TX_PORTS; j++)
+ {
+ p_LnxWrpFmDev->txPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
+ memset(p_LnxWrpFmDev->txPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
+ }
+ for (j=0; j<FM_MAX_NUM_OF_OH_PORTS-1; j++)
+ {
+ p_LnxWrpFmDev->opPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
+ memset(p_LnxWrpFmDev->opPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
+ }
+
+ return p_LnxWrpFmDev;
+}
+
+static void DestroyFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
+{
+ int j;
+
+ for (j=0; j<FM_MAX_NUM_OF_OH_PORTS-1; j++)
+ if (p_LnxWrpFmDev->opPorts[j].settings.advConfig)
+ XX_Free(p_LnxWrpFmDev->opPorts[j].settings.advConfig);
+ for (j=0; j<FM_MAX_NUM_OF_TX_PORTS; j++)
+ if (p_LnxWrpFmDev->txPorts[j].settings.advConfig)
+ XX_Free(p_LnxWrpFmDev->txPorts[j].settings.advConfig);
+ for (j=0; j<FM_MAX_NUM_OF_RX_PORTS; j++)
+ if (p_LnxWrpFmDev->rxPorts[j].settings.advConfig)
+ XX_Free(p_LnxWrpFmDev->rxPorts[j].settings.advConfig);
+ if (p_LnxWrpFmDev->hcPort.settings.advConfig)
+ XX_Free(p_LnxWrpFmDev->hcPort.settings.advConfig);
+ if (p_LnxWrpFmDev->fmPcdDevSettings.advConfig)
+ XX_Free(p_LnxWrpFmDev->fmPcdDevSettings.advConfig);
+ if (p_LnxWrpFmDev->fmDevSettings.advConfig)
+ XX_Free(p_LnxWrpFmDev->fmDevSettings.advConfig);
+
+ XX_Free(p_LnxWrpFmDev);
+}
+
+static t_Error FillRestFmInfo(t_LnxWrpFmDev *p_LnxWrpFmDev)
+{
+#define FM_BMI_PPIDS_OFFSET 0x00080304
+#define FM_DMA_PLR_OFFSET 0x000c2060
+#define FM_FPM_IP_REV_1_OFFSET 0x000c30c4
+#define DMA_HIGH_LIODN_MASK 0x0FFF0000
+#define DMA_LOW_LIODN_MASK 0x00000FFF
+#define DMA_LIODN_SHIFT 16
+
+typedef _Packed struct {
+ uint32_t plr[32];
+} _PackedType t_Plr;
+
+typedef _Packed struct {
+ volatile uint32_t fmbm_ppid[63];
+} _PackedType t_Ppids;
+
+ t_Plr *p_Plr;
+ t_Ppids *p_Ppids;
+ int i,j;
+ uint32_t fmRev;
+
+ static const uint8_t phys1GRxPortId[] = {0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf};
+ static const uint8_t phys10GRxPortId[] = {0x10,0x11};
+#if (DPAA_VERSION >= 11)
+ static const uint8_t physOhPortId[] = {/* 0x1, */0x2,0x3,0x4,0x5,0x6,0x7};
+#else
+ static const uint8_t physOhPortId[] = {0x1,0x2,0x3,0x4,0x5,0x6,0x7};
+#endif
+ static const uint8_t phys1GTxPortId[] = {0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f};
+ static const uint8_t phys10GTxPortId[] = {0x30,0x31};
+
+ fmRev = (uint32_t)(*((volatile uint32_t *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_FPM_IP_REV_1_OFFSET)));
+ fmRev &= 0xffff;
+
+ p_Plr = (t_Plr *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_DMA_PLR_OFFSET);
+#ifdef MODULE
+ for (i=0;i<FM_MAX_NUM_OF_PARTITIONS/2;i++)
+ p_Plr->plr[i] = 0;
+#endif /* MODULE */
+
+ for (i=0; i<FM_MAX_NUM_OF_PARTITIONS; i++)
+ {
+ uint16_t liodnBase = (uint16_t)((i%2) ?
+ (p_Plr->plr[i/2] & DMA_LOW_LIODN_MASK) :
+ ((p_Plr->plr[i/2] & DMA_HIGH_LIODN_MASK) >> DMA_LIODN_SHIFT));
+#ifdef FM_PARTITION_ARRAY
+ /* TODO: this was .liodnPerPartition[i] = liodnBase; is the index meaning the same? */
+ p_LnxWrpFmDev->fmDevSettings.param.liodnBasePerPort[i] = liodnBase;
+#endif /* FM_PARTITION_ARRAY */
+
+ if ((i >= phys1GRxPortId[0]) &&
+ (i <= phys1GRxPortId[FM_MAX_NUM_OF_1G_RX_PORTS-1]))
+ {
+ for (j=0; j<ARRAY_SIZE(phys1GRxPortId); j++)
+ if (phys1GRxPortId[j] == i)
+ break;
+ ASSERT_COND(j<ARRAY_SIZE(phys1GRxPortId));
+ p_LnxWrpFmDev->rxPorts[j].settings.param.liodnBase = liodnBase;
+ }
+ else if (FM_MAX_NUM_OF_10G_RX_PORTS &&
+ (i >= phys10GRxPortId[0]) &&
+ (i <= phys10GRxPortId[FM_MAX_NUM_OF_10G_RX_PORTS-1]))
+ {
+ for (j=0; j<ARRAY_SIZE(phys10GRxPortId); j++)
+ if (phys10GRxPortId[j] == i)
+ break;
+ ASSERT_COND(j<ARRAY_SIZE(phys10GRxPortId));
+ p_LnxWrpFmDev->rxPorts[FM_MAX_NUM_OF_1G_RX_PORTS+j].settings.param.liodnBase = liodnBase;
+ }
+ else if ((i >= physOhPortId[0]) &&
+ (i <= physOhPortId[FM_MAX_NUM_OF_OH_PORTS-1]))
+ {
+ for (j=0; j<ARRAY_SIZE(physOhPortId); j++)
+ if (physOhPortId[j] == i)
+ break;
+ ASSERT_COND(j<ARRAY_SIZE(physOhPortId));
+ if (j == 0)
+ p_LnxWrpFmDev->hcPort.settings.param.liodnBase = liodnBase;
+ else
+ p_LnxWrpFmDev->opPorts[j - 1].settings.param.liodnBase = liodnBase;
+ }
+ else if ((i >= phys1GTxPortId[0]) &&
+ (i <= phys1GTxPortId[FM_MAX_NUM_OF_1G_TX_PORTS-1]))
+ {
+ for (j=0; j<ARRAY_SIZE(phys1GTxPortId); j++)
+ if (phys1GTxPortId[j] == i)
+ break;
+ ASSERT_COND(j<ARRAY_SIZE(phys1GTxPortId));
+ p_LnxWrpFmDev->txPorts[j].settings.param.liodnBase = liodnBase;
+ }
+ else if (FM_MAX_NUM_OF_10G_TX_PORTS &&
+ (i >= phys10GTxPortId[0]) &&
+ (i <= phys10GTxPortId[FM_MAX_NUM_OF_10G_TX_PORTS-1]))
+ {
+ for (j=0; j<ARRAY_SIZE(phys10GTxPortId); j++)
+ if (phys10GTxPortId[j] == i)
+ break;
+ ASSERT_COND(j<ARRAY_SIZE(phys10GTxPortId));
+ p_LnxWrpFmDev->txPorts[FM_MAX_NUM_OF_1G_TX_PORTS+j].settings.param.liodnBase = liodnBase;
+ }
+ }
+
+ p_Ppids = (t_Ppids *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_BMI_PPIDS_OFFSET);
+
+ for (i=0; i<FM_MAX_NUM_OF_1G_RX_PORTS; i++)
+ p_LnxWrpFmDev->rxPorts[i].settings.param.specificParams.rxParams.liodnOffset =
+ p_Ppids->fmbm_ppid[phys1GRxPortId[i]-1];
+
+ for (i=0; i<FM_MAX_NUM_OF_10G_RX_PORTS; i++)
+ p_LnxWrpFmDev->rxPorts[FM_MAX_NUM_OF_1G_RX_PORTS+i].settings.param.specificParams.rxParams.liodnOffset =
+ p_Ppids->fmbm_ppid[phys10GRxPortId[i]-1];
+
+ return E_OK;
+}
+
+/* Structure that defines QE firmware binary files.
+ *
+ * See Documentation/powerpc/qe_firmware.txt for a description of these
+ * fields.
+ */
+struct qe_firmware {
+ struct qe_header {
+ __be32 length; /* Length of the entire structure, in bytes */
+ u8 magic[3]; /* Set to { 'Q', 'E', 'F' } */
+ u8 version; /* Version of this layout. First ver is '1' */
+ } header;
+ u8 id[62]; /* Null-terminated identifier string */
+ u8 split; /* 0 = shared I-RAM, 1 = split I-RAM */
+ u8 count; /* Number of microcode[] structures */
+ struct {
+ __be16 model; /* The SOC model */
+ u8 major; /* The SOC revision major */
+ u8 minor; /* The SOC revision minor */
+ } __attribute__ ((packed)) soc;
+ u8 padding[4]; /* Reserved, for alignment */
+ __be64 extended_modes; /* Extended modes */
+ __be32 vtraps[8]; /* Virtual trap addresses */
+ u8 reserved[4]; /* Reserved, for future expansion */
+ struct qe_microcode {
+ u8 id[32]; /* Null-terminated identifier */
+ __be32 traps[16]; /* Trap addresses, 0 == ignore */
+ __be32 eccr; /* The value for the ECCR register */
+ __be32 iram_offset; /* Offset into I-RAM for the code */
+ __be32 count; /* Number of 32-bit words of the code */
+ __be32 code_offset; /* Offset of the actual microcode */
+ u8 major; /* The microcode version major */
+ u8 minor; /* The microcode version minor */
+ u8 revision; /* The microcode version revision */
+ u8 padding; /* Reserved, for alignment */
+ u8 reserved[4]; /* Reserved, for future expansion */
+ } __attribute__ ((packed)) microcode[1];
+ /* All microcode binaries should be located here */
+ /* CRC32 should be located here, after the microcode binaries */
+} __attribute__ ((packed));
+
+
+/**
+ * FindFmanMicrocode - find the Fman microcode
+ *
+ * This function returns a pointer to the QE Firmware blob that holds
+ * the Fman microcode. We use the QE Firmware structure because Fman microcode
+ * is similar to QE microcode, so there's no point in defining a new layout.
+ *
+ * Current versions of U-Boot embed the Fman firmware into the device tree,
+ * so we check for that first. Each Fman node in the device tree contains a
+ * node or a pointer to node that holds the firmware. Technically, we should
+ * be fetching the firmware node for the current Fman, but we don't have that
+ * information any more, so we assume that there is only one firmware node in
+ * the device tree, and that all Fmen use the same firmware.
+ */
+static const struct qe_firmware *FindFmanMicrocode(void)
+{
+ static const struct qe_firmware *P4080_UCPatch;
+ struct device_node *np;
+
+ if (P4080_UCPatch)
+ return P4080_UCPatch;
+
+ /* The firmware should be inside the device tree. */
+ np = of_find_compatible_node(NULL, NULL, "fsl,fman-firmware");
+ if (np) {
+ P4080_UCPatch = of_get_property(np, "fsl,firmware", NULL);
+ of_node_put(np);
+ if (P4080_UCPatch)
+ return P4080_UCPatch;
+ else
+ REPORT_ERROR(WARNING, E_NOT_FOUND, ("firmware node is incomplete"));
+ }
+
+ /* Returning NULL here forces the reuse of the IRAM content */
+ return NULL;
+}
+#define SVR_SECURITY_MASK 0x00080000
+#define SVR_PERSONALITY_MASK 0x0000FF00
+#define SVR_VER_IGNORE_MASK (SVR_SECURITY_MASK | SVR_PERSONALITY_MASK)
+#define SVR_B4860_REV1_VALUE 0x86800010
+#define SVR_B4860_REV2_VALUE 0x86800020
+#define SVR_T4240_VALUE 0x82400000
+#define SVR_T4120_VALUE 0x82400100
+#define SVR_T4160_VALUE 0x82410000
+#define SVR_T4080_VALUE 0x82410200
+#define SVR_T4_DEVICE_ID 0x82400000
+#define SVR_DEVICE_ID_MASK 0xFFF00000
+
+#define OF_DEV_ID_NUM 2 /* one used, another one zeroed */
+
+/* searches for a subnode with the given name/compatible */
+static bool HasFmPcdOfNode(struct device_node *fm_node,
+ struct of_device_id *ids,
+ const char *name,
+ const char *compatible)
+{
+ struct device_node *dev_node;
+ bool ret = false;
+
+ memset(ids, 0, OF_DEV_ID_NUM*sizeof(struct of_device_id));
+ if (WARN_ON(strlen(name) >= sizeof(ids[0].name)))
+ return false;
+ strcpy(ids[0].name, name);
+ if (WARN_ON(strlen(compatible) >= sizeof(ids[0].compatible)))
+ return false;
+ strcpy(ids[0].compatible, compatible);
+ for_each_child_of_node(fm_node, dev_node)
+ if (of_match_node(ids, dev_node) != NULL)
+ ret = true;
+ return ret;
+}
+
+static t_LnxWrpFmDev * ReadFmDevTreeNode (struct platform_device *of_dev)
+{
+ t_LnxWrpFmDev *p_LnxWrpFmDev;
+ struct device_node *fm_node, *dev_node;
+ struct of_device_id ids[OF_DEV_ID_NUM];
+ struct resource res;
+ struct clk *clk;
+ u32 clk_rate;
+ const uint32_t *uint32_prop;
+ int _errno=0, lenp;
+ uint32_t tmp_prop;
+
+ fm_node = of_node_get(of_dev->dev.of_node);
+
+ uint32_prop = (uint32_t *)of_get_property(fm_node, "cell-index", &lenp);
+ if (unlikely(uint32_prop == NULL)) {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_get_property(%s, cell-index) failed", fm_node->full_name));
+ return NULL;
+ }
+ tmp_prop = be32_to_cpu(*uint32_prop);
+
+ if (WARN_ON(lenp != sizeof(uint32_t)))
+ return NULL;
+
+ if (tmp_prop > INTG_MAX_NUM_OF_FM) {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
+ return NULL;
+ }
+ p_LnxWrpFmDev = CreateFmDev(tmp_prop);
+ if (!p_LnxWrpFmDev) {
+ REPORT_ERROR(MAJOR, E_NULL_POINTER, NO_MSG);
+ return NULL;
+ }
+ p_LnxWrpFmDev->dev = &of_dev->dev;
+ p_LnxWrpFmDev->id = tmp_prop;
+
+ /* Get the FM interrupt */
+ p_LnxWrpFmDev->irq = of_irq_to_resource(fm_node, 0, NULL);
+ if (unlikely(p_LnxWrpFmDev->irq == /*NO_IRQ*/0)) {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_irq_to_resource() = %d", NO_IRQ));
+ DestroyFmDev(p_LnxWrpFmDev);
+ return NULL;
+ }
+
+ /* Get the FM error interrupt */
+ p_LnxWrpFmDev->err_irq = of_irq_to_resource(fm_node, 1, NULL);
+
+ if (unlikely(p_LnxWrpFmDev->err_irq == /*NO_IRQ*/0)) {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_irq_to_resource() = %d", NO_IRQ));
+ DestroyFmDev(p_LnxWrpFmDev);
+ return NULL;
+ }
+
+ /* Get the FM address */
+ _errno = of_address_to_resource(fm_node, 0, &res);
+ if (unlikely(_errno < 0)) {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
+ DestroyFmDev(p_LnxWrpFmDev);
+ return NULL;
+ }
+
+
+ p_LnxWrpFmDev->fmBaseAddr = 0;
+ p_LnxWrpFmDev->fmPhysBaseAddr = res.start;
+ p_LnxWrpFmDev->fmMemSize = res.end + 1 - res.start;
+
+ clk = of_clk_get(fm_node, 0);
+ if (IS_ERR(clk)) {
+ dev_err(&of_dev->dev, "%s: Failed to get FM clock structure\n",
+ __func__);
+ of_node_put(fm_node);
+ DestroyFmDev(p_LnxWrpFmDev);
+ return NULL;
+ }
+
+ clk_rate = clk_get_rate(clk);
+ if (!clk_rate) {
+ dev_err(&of_dev->dev, "%s: Failed to determine FM clock rate\n",
+ __func__);
+ of_node_put(fm_node);
+ DestroyFmDev(p_LnxWrpFmDev);
+ return NULL;
+ }
+
+ p_LnxWrpFmDev->fmDevSettings.param.fmClkFreq = DIV_ROUND_UP(clk_rate, 1000000); /* In MHz, rounded */
+ /* Get the MURAM base address and size */
+ memset(ids, 0, sizeof(ids));
+ if (WARN_ON(strlen("muram") >= sizeof(ids[0].name)))
+ return NULL;
+ strcpy(ids[0].name, "muram");
+ if (WARN_ON(strlen("fsl,fman-muram") >= sizeof(ids[0].compatible)))
+ return NULL;
+ strcpy(ids[0].compatible, "fsl,fman-muram");
+ for_each_child_of_node(fm_node, dev_node) {
+ if (likely(of_match_node(ids, dev_node) != NULL)) {
+ _errno = of_address_to_resource(dev_node, 0, &res);
+ if (unlikely(_errno < 0)) {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
+ DestroyFmDev(p_LnxWrpFmDev);
+ return NULL;
+ }
+
+ p_LnxWrpFmDev->fmMuramBaseAddr = 0;
+ p_LnxWrpFmDev->fmMuramPhysBaseAddr = res.start;
+ p_LnxWrpFmDev->fmMuramMemSize = res.end + 1 - res.start;
+
+#ifndef CONFIG_FMAN_ARM
+ {
+ uint32_t svr;
+ svr = mfspr(SPRN_SVR);
+
+ if ((svr & ~SVR_VER_IGNORE_MASK) >= SVR_B4860_REV2_VALUE)
+ p_LnxWrpFmDev->fmMuramMemSize = 0x80000;
+ }
+#endif
+ }
+ }
+
+ /* Get the RTC base address and size */
+ memset(ids, 0, sizeof(ids));
+ if (WARN_ON(strlen("ptp-timer") >= sizeof(ids[0].name)))
+ return NULL;
+ strcpy(ids[0].name, "ptp-timer");
+ if (WARN_ON(strlen("fsl,fman-rtc") >= sizeof(ids[0].compatible)))
+ return NULL;
+ strcpy(ids[0].compatible, "fsl,fman-rtc");
+ for_each_child_of_node(fm_node, dev_node) {
+ if (likely(of_match_node(ids, dev_node) != NULL)) {
+ _errno = of_address_to_resource(dev_node, 0, &res);
+ if (unlikely(_errno < 0)) {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
+ DestroyFmDev(p_LnxWrpFmDev);
+ return NULL;
+ }
+
+ p_LnxWrpFmDev->fmRtcBaseAddr = 0;
+ p_LnxWrpFmDev->fmRtcPhysBaseAddr = res.start;
+ p_LnxWrpFmDev->fmRtcMemSize = res.end + 1 - res.start;
+ }
+ }
+
+#if (DPAA_VERSION >= 11)
+ /* Get the VSP base address */
+ for_each_child_of_node(fm_node, dev_node) {
+ if (of_device_is_compatible(dev_node, "fsl,fman-vsps")) {
+ _errno = of_address_to_resource(dev_node, 0, &res);
+ if (unlikely(_errno < 0)) {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
+ DestroyFmDev(p_LnxWrpFmDev);
+ return NULL;
+ }
+ p_LnxWrpFmDev->fmVspBaseAddr = 0;
+ p_LnxWrpFmDev->fmVspPhysBaseAddr = res.start;
+ p_LnxWrpFmDev->fmVspMemSize = res.end + 1 - res.start;
+ }
+ }
+#endif
+
+ /* Get all PCD nodes */
+ p_LnxWrpFmDev->prsActive = HasFmPcdOfNode(fm_node, ids, "parser", "fsl,fman-parser");
+ p_LnxWrpFmDev->kgActive = HasFmPcdOfNode(fm_node, ids, "keygen", "fsl,fman-keygen");
+ p_LnxWrpFmDev->ccActive = HasFmPcdOfNode(fm_node, ids, "cc", "fsl,fman-cc");
+ p_LnxWrpFmDev->plcrActive = HasFmPcdOfNode(fm_node, ids, "policer", "fsl,fman-policer");
+
+ if (p_LnxWrpFmDev->prsActive || p_LnxWrpFmDev->kgActive ||
+ p_LnxWrpFmDev->ccActive || p_LnxWrpFmDev->plcrActive)
+ p_LnxWrpFmDev->pcdActive = TRUE;
+
+ if (p_LnxWrpFmDev->pcdActive)
+ {
+ const char *str_prop = (char *)of_get_property(fm_node, "fsl,default-pcd", &lenp);
+ if (str_prop) {
+ if (strncmp(str_prop, "3-tuple", strlen("3-tuple")) == 0)
+ p_LnxWrpFmDev->defPcd = e_FM_PCD_3_TUPLE;
+ }
+ else
+ p_LnxWrpFmDev->defPcd = e_NO_PCD;
+ }
+
+ of_node_put(fm_node);
+
+ p_LnxWrpFmDev->hcCh =
+ qman_affine_channel(cpumask_first(qman_affine_cpus()));
+
+ p_LnxWrpFmDev->active = TRUE;
+
+ return p_LnxWrpFmDev;
+}
+
+struct device_node *GetFmAdvArgsDevTreeNode (uint8_t fmIndx)
+{
+ struct device_node *dev_node;
+ const uint32_t *uint32_prop;
+ int lenp;
+ uint32_t tmp_prop;
+
+ for_each_compatible_node(dev_node, NULL, "fsl,fman-extended-args") {
+ uint32_prop = (uint32_t *)of_get_property(dev_node, "cell-index", &lenp);
+ if (unlikely(uint32_prop == NULL)) {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE,
+ ("of_get_property(%s, cell-index) failed",
+ dev_node->full_name));
+ return NULL;
+ }
+ tmp_prop = be32_to_cpu(*uint32_prop);
+ if (WARN_ON(lenp != sizeof(uint32_t)))
+ return NULL;
+ if (tmp_prop > INTG_MAX_NUM_OF_FM) {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
+ return NULL;
+ }
+ if (fmIndx == tmp_prop)
+ return dev_node;
+ }
+
+ return NULL;
+}
+
+static t_Error CheckNConfigFmAdvArgs (t_LnxWrpFmDev *p_LnxWrpFmDev)
+{
+ struct device_node *dev_node;
+ t_Error err = E_INVALID_VALUE;
+ const uint32_t *uint32_prop;
+ const char *str_prop;
+ int lenp;
+ uint32_t tmp_prop;
+
+ dev_node = GetFmAdvArgsDevTreeNode(p_LnxWrpFmDev->id);
+ if (!dev_node) /* no advance parameters for FMan */
+ return E_OK;
+
+ str_prop = (char *)of_get_property(dev_node, "dma-aid-mode", &lenp);
+ if (str_prop) {
+ if (strcmp(str_prop, "port") == 0)
+ err = FM_ConfigDmaAidMode(p_LnxWrpFmDev->h_Dev, e_FM_DMA_AID_OUT_PORT_ID);
+ else if (strcmp(str_prop, "tnum") == 0)
+ err = FM_ConfigDmaAidMode(p_LnxWrpFmDev->h_Dev, e_FM_DMA_AID_OUT_TNUM);
+
+ if (err != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ uint32_prop = (uint32_t *)of_get_property(dev_node,
+ "total-fifo-size", &lenp);
+ if (uint32_prop) {
+ tmp_prop = be32_to_cpu(*uint32_prop);
+ if (WARN_ON(lenp != sizeof(uint32_t)))
+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
+
+ if (FM_ConfigTotalFifoSize(p_LnxWrpFmDev->h_Dev,
+ tmp_prop) != E_OK)
+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
+ }
+
+ uint32_prop = (uint32_t *)of_get_property(dev_node, "tnum-aging-period",
+ &lenp);
+ if (uint32_prop) {
+ tmp_prop = be32_to_cpu(*uint32_prop);
+ if (WARN_ON(lenp != sizeof(uint32_t)))
+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
+
+ err = FM_ConfigTnumAgingPeriod(p_LnxWrpFmDev->h_Dev,
+ (uint16_t)tmp_prop/*tnumAgingPeriod*/);
+
+ if (err != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ of_node_put(dev_node);
+
+ return E_OK;
+}
+
+static void LnxwrpFmDevExceptionsCb(t_Handle h_App, e_FmExceptions exception)
+{
+ t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)h_App;
+
+ ASSERT_COND(p_LnxWrpFmDev);
+
+ DBG(INFO, ("got fm exception %d", exception));
+
+ /* do nothing */
+ UNUSED(exception);
+}
+
+static void LnxwrpFmDevBusErrorCb(t_Handle h_App,
+ e_FmPortType portType,
+ uint8_t portId,
+ uint64_t addr,
+ uint8_t tnum,
+ uint16_t liodn)
+{
+ t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)h_App;
+
+ ASSERT_COND(p_LnxWrpFmDev);
+
+ /* do nothing */
+ UNUSED(portType);UNUSED(portId);UNUSED(addr);UNUSED(tnum);UNUSED(liodn);
+}
+
+static t_Error ConfigureFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
+{
+ struct resource *dev_res;
+ int _errno;
+
+ if (!p_LnxWrpFmDev->active)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM not configured!!!"));
+
+#ifndef MODULE
+ _errno = can_request_irq(p_LnxWrpFmDev->irq, 0);
+ if (unlikely(_errno < 0))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("can_request_irq() = %d", _errno));
+#endif
+ _errno = devm_request_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->irq, fm_irq, 0, "fman", p_LnxWrpFmDev);
+ if (unlikely(_errno < 0))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_irq(%d) = %d", p_LnxWrpFmDev->irq, _errno));
+
+ enable_irq_wake(p_LnxWrpFmDev->irq);
+
+ if (p_LnxWrpFmDev->err_irq != 0) {
+#ifndef MODULE
+ _errno = can_request_irq(p_LnxWrpFmDev->err_irq, 0);
+ if (unlikely(_errno < 0))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("can_request_irq() = %d", _errno));
+#endif
+ _errno = devm_request_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->err_irq, fm_err_irq, IRQF_SHARED, "fman-err", p_LnxWrpFmDev);
+ if (unlikely(_errno < 0))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_irq(%d) = %d", p_LnxWrpFmDev->err_irq, _errno));
+
+ enable_irq_wake(p_LnxWrpFmDev->err_irq);
+ }
+
+ p_LnxWrpFmDev->res = devm_request_mem_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize, "fman");
+ if (unlikely(p_LnxWrpFmDev->res == NULL))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_mem_region() failed"));
+
+ p_LnxWrpFmDev->fmBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize));
+ if (unlikely(p_LnxWrpFmDev->fmBaseAddr == 0))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
+
+ if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmBaseAddr, (uint64_t)p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize) != E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM memory map"));
+
+ dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize, "fman-muram");
+ if (unlikely(dev_res == NULL))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
+
+ p_LnxWrpFmDev->fmMuramBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize));
+ if (unlikely(p_LnxWrpFmDev->fmMuramBaseAddr == 0))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
+
+ if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmMuramBaseAddr, (uint64_t)p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize) != E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM MURAM memory map"));
+
+ if (p_LnxWrpFmDev->fmRtcPhysBaseAddr)
+ {
+ dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize, "fman-rtc");
+ if (unlikely(dev_res == NULL))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
+
+ p_LnxWrpFmDev->fmRtcBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize));
+ if (unlikely(p_LnxWrpFmDev->fmRtcBaseAddr == 0))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
+
+ if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmRtcBaseAddr, (uint64_t)p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize) != E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC memory map"));
+ }
+
+#if (DPAA_VERSION >= 11)
+ if (p_LnxWrpFmDev->fmVspPhysBaseAddr) {
+ dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmVspPhysBaseAddr, p_LnxWrpFmDev->fmVspMemSize, "fman-vsp");
+ if (unlikely(dev_res == NULL))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
+
+ p_LnxWrpFmDev->fmVspBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmVspPhysBaseAddr, p_LnxWrpFmDev->fmVspMemSize));
+ if (unlikely(p_LnxWrpFmDev->fmVspBaseAddr == 0))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
+ }
+#endif
+
+ p_LnxWrpFmDev->fmDevSettings.param.baseAddr = p_LnxWrpFmDev->fmBaseAddr;
+ p_LnxWrpFmDev->fmDevSettings.param.fmId = p_LnxWrpFmDev->id;
+ p_LnxWrpFmDev->fmDevSettings.param.irq = NO_IRQ;
+ p_LnxWrpFmDev->fmDevSettings.param.errIrq = NO_IRQ;
+ p_LnxWrpFmDev->fmDevSettings.param.f_Exception = LnxwrpFmDevExceptionsCb;
+ p_LnxWrpFmDev->fmDevSettings.param.f_BusError = LnxwrpFmDevBusErrorCb;
+ p_LnxWrpFmDev->fmDevSettings.param.h_App = p_LnxWrpFmDev;
+
+ return FillRestFmInfo(p_LnxWrpFmDev);
+}
+
+#ifndef CONFIG_FMAN_ARM
+/*
+ * Table for matching compatible strings, for device tree
+ * guts node, for QorIQ SOCs.
+ * "fsl,qoriq-device-config-2.0" corresponds to T4 & B4
+ * SOCs. For the older SOCs "fsl,qoriq-device-config-1.0"
+ * string would be used.
+*/
+static const struct of_device_id guts_device_ids[] = {
+ { .compatible = "fsl,qoriq-device-config-1.0", },
+ { .compatible = "fsl,qoriq-device-config-2.0", },
+ {}
+};
+
+static unsigned int get_rcwsr(int regnum)
+{
+ struct ccsr_guts __iomem *guts_regs = NULL;
+ struct device_node *guts_node;
+
+ guts_node = of_find_matching_node(NULL, guts_device_ids);
+ if (!guts_node) {
+ pr_err("could not find GUTS node\n");
+ return 0;
+ }
+ guts_regs = of_iomap(guts_node, 0);
+ of_node_put(guts_node);
+ if (!guts_regs) {
+ pr_err("ioremap of GUTS node failed\n");
+ return 0;
+ }
+
+ return ioread32be(&guts_regs->rcwsr[regnum]);
+}
+
+#define FMAN1_ALL_MACS_MASK 0xFCC00000
+#define FMAN2_ALL_MACS_MASK 0x000FCC00
+
+/**
+ * @Function ResetOnInitErrata_A007273
+ *
+ * @Description Workaround for Errata A-007273
+ * This workaround is required to avoid a FMan hang during reset on initialization.
+ * Enable all MACs in guts.devdisr2 register,
+ * then perform a regular FMan reset and then restore MACs to their original state.
+ *
+ * @Param[in] h_Fm - FM module descriptor
+ *
+ * @Return None.
+ */
+void ResetOnInitErrata_A007273(t_Handle h_Fm)
+{
+ struct ccsr_guts __iomem *guts_regs = NULL;
+ struct device_node *guts_node;
+ u32 devdisr2, enableMacs;
+
+ /* Get guts registers */
+ guts_node = of_find_matching_node(NULL, guts_device_ids);
+ if (!guts_node) {
+ pr_err("could not find GUTS node\n");
+ return;
+ }
+ guts_regs = of_iomap(guts_node, 0);
+ of_node_put(guts_node);
+ if (!guts_regs) {
+ pr_err("ioremap of GUTS node failed\n");
+ return;
+ }
+
+ /* Read current state */
+ devdisr2 = ioread32be(&guts_regs->devdisr2);
+
+ if (FmGetId(h_Fm) == 0)
+ enableMacs = devdisr2 & ~FMAN1_ALL_MACS_MASK;
+ else
+ enableMacs = devdisr2 & ~FMAN2_ALL_MACS_MASK;
+
+ /* Enable all MACs */
+ iowrite32be(enableMacs, &guts_regs->devdisr2);
+
+ /* Perform standard FMan reset */
+ FmReset(h_Fm);
+
+ /* Restore devdisr2 value */
+ iowrite32be(devdisr2, &guts_regs->devdisr2);
+
+ iounmap(guts_regs);
+}
+#endif
+
+static t_Error InitFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
+{
+ const struct qe_firmware *fw;
+
+ if (!p_LnxWrpFmDev->active)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM not configured!!!"));
+
+ if ((p_LnxWrpFmDev->h_MuramDev = FM_MURAM_ConfigAndInit(p_LnxWrpFmDev->fmMuramBaseAddr, p_LnxWrpFmDev->fmMuramMemSize)) == NULL)
+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-MURAM!"));
+
+ /* Loading the fman-controller code */
+ fw = FindFmanMicrocode();
+
+ if (!fw) {
+ /* this forces the reuse of the current IRAM content */
+ p_LnxWrpFmDev->fmDevSettings.param.firmware.size = 0;
+ p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code = NULL;
+ } else {
+ p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code =
+ (void *) fw + be32_to_cpu(fw->microcode[0].code_offset);
+ p_LnxWrpFmDev->fmDevSettings.param.firmware.size =
+ sizeof(u32) * be32_to_cpu(fw->microcode[0].count);
+ DBG(INFO, ("Loading fman-controller code version %d.%d.%d",
+ fw->microcode[0].major,
+ fw->microcode[0].minor,
+ fw->microcode[0].revision));
+ }
+
+#ifdef CONFIG_FMAN_ARM
+ { /* endianness adjustments: byteswap the ucode retrieved from the f/w blob */
+ int i;
+ int usz = p_LnxWrpFmDev->fmDevSettings.param.firmware.size;
+ void * p_Code = p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code;
+ u32 *dest = kzalloc(usz, GFP_KERNEL);
+
+ if (p_Code && dest)
+ for(i=0; i < usz / 4; ++i)
+ dest[i] = be32_to_cpu(((u32 *)p_Code)[i]);
+
+ p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code = dest;
+ }
+#endif
+
+ p_LnxWrpFmDev->fmDevSettings.param.h_FmMuram = p_LnxWrpFmDev->h_MuramDev;
+
+#if (DPAA_VERSION >= 11)
+ if (p_LnxWrpFmDev->fmVspBaseAddr) {
+ p_LnxWrpFmDev->fmDevSettings.param.vspBaseAddr = p_LnxWrpFmDev->fmVspBaseAddr;
+ p_LnxWrpFmDev->fmDevSettings.param.partVSPBase = 0;
+ p_LnxWrpFmDev->fmDevSettings.param.partNumOfVSPs = FM_VSP_MAX_NUM_OF_ENTRIES;
+ }
+#endif
+
+#ifdef CONFIG_FMAN_ARM
+ p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio = 1;
+#else
+ if(p_LnxWrpFmDev->fmDevSettings.param.fmId == 0)
+ p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio =
+ !!(get_rcwsr(4) & 0x2); /* RCW[FM_MAC_RAT0] */
+ else
+ p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio =
+ !!(get_rcwsr(4) & 0x1); /* RCW[FM_MAC_RAT1] */
+
+ {
+ /* T4 Devices ClkRatio is always 1 regardless of RCW[FM_MAC_RAT1] */
+ uint32_t svr;
+ svr = mfspr(SPRN_SVR);
+
+ if ((svr & SVR_DEVICE_ID_MASK) == SVR_T4_DEVICE_ID)
+ p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio = 1;
+ }
+#endif /* CONFIG_FMAN_ARM */
+
+ if ((p_LnxWrpFmDev->h_Dev = FM_Config(&p_LnxWrpFmDev->fmDevSettings.param)) == NULL)
+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM"));
+
+
+ if (FM_ConfigResetOnInit(p_LnxWrpFmDev->h_Dev, TRUE) != E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
+
+#ifndef CONFIG_FMAN_ARM
+#ifdef FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273
+ if (FM_ConfigResetOnInitOverrideCallback(p_LnxWrpFmDev->h_Dev, ResetOnInitErrata_A007273) != E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
+#endif /* FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273 */
+#endif /* CONFIG_FMAN_ARM */
+
+#ifdef CONFIG_FMAN_P1023
+ if (FM_ConfigDmaAidOverride(p_LnxWrpFmDev->h_Dev, TRUE) != E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
+#endif
+
+
+ CheckNConfigFmAdvArgs(p_LnxWrpFmDev);
+
+ if (FM_Init(p_LnxWrpFmDev->h_Dev) != E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
+
+ /* TODO: Why we mask these interrupts? */
+ if (p_LnxWrpFmDev->err_irq == 0) {
+ FM_SetException(p_LnxWrpFmDev->h_Dev, e_FM_EX_DMA_BUS_ERROR,FALSE);
+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_READ_ECC,FALSE);
+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_SYSTEM_WRITE_ECC,FALSE);
+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_FM_WRITE_ECC,FALSE);
+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_SINGLE_PORT_ECC, FALSE);
+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_STALL_ON_TASKS , FALSE);
+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_SINGLE_ECC, FALSE);
+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_DOUBLE_ECC,FALSE);
+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_SINGLE_ECC, FALSE);
+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_DOUBLE_ECC,FALSE);
+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,FALSE);
+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_LIST_RAM_ECC,FALSE);
+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_STORAGE_PROFILE_ECC, FALSE);
+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_STATISTICS_RAM_ECC, FALSE);
+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_DISPATCH_RAM_ECC, FALSE);
+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_IRAM_ECC,FALSE);
+ /* TODO: FmDisableRamsEcc assert for ramsEccOwners.
+ * FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_MURAM_ECC,FALSE);*/
+ }
+
+ if (p_LnxWrpFmDev->fmRtcBaseAddr)
+ {
+ t_FmRtcParams fmRtcParam;
+
+ memset(&fmRtcParam, 0, sizeof(fmRtcParam));
+ fmRtcParam.h_App = p_LnxWrpFmDev;
+ fmRtcParam.h_Fm = p_LnxWrpFmDev->h_Dev;
+ fmRtcParam.baseAddress = p_LnxWrpFmDev->fmRtcBaseAddr;
+
+ if(!(p_LnxWrpFmDev->h_RtcDev = FM_RTC_Config(&fmRtcParam)))
+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-RTC"));
+
+ if (FM_RTC_ConfigPeriod(p_LnxWrpFmDev->h_RtcDev, DPA_PTP_NOMINAL_FREQ_PERIOD_NS) != E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC"));
+
+ if (FM_RTC_Init(p_LnxWrpFmDev->h_RtcDev) != E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC"));
+ }
+
+ return E_OK;
+}
+
+/* TODO: to be moved back here */
+extern void FreeFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev);
+
+static void FreeFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
+{
+ if (!p_LnxWrpFmDev->active)
+ return;
+
+ FreeFmPcdDev(p_LnxWrpFmDev);
+
+ if (p_LnxWrpFmDev->h_RtcDev)
+ FM_RTC_Free(p_LnxWrpFmDev->h_RtcDev);
+
+ if (p_LnxWrpFmDev->h_Dev)
+ FM_Free(p_LnxWrpFmDev->h_Dev);
+
+ if (p_LnxWrpFmDev->h_MuramDev)
+ FM_MURAM_Free(p_LnxWrpFmDev->h_MuramDev);
+
+ if (p_LnxWrpFmDev->fmRtcBaseAddr)
+ {
+ SYS_UnregisterIoMap(p_LnxWrpFmDev->fmRtcBaseAddr);
+ devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmRtcBaseAddr));
+ __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize);
+ }
+ SYS_UnregisterIoMap(p_LnxWrpFmDev->fmMuramBaseAddr);
+ devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmMuramBaseAddr));
+ __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize);
+ SYS_UnregisterIoMap(p_LnxWrpFmDev->fmBaseAddr);
+ devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr));
+ devm_release_mem_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize);
+ if (p_LnxWrpFmDev->err_irq != 0) {
+ devm_free_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->err_irq, p_LnxWrpFmDev);
+ }
+
+ devm_free_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->irq, p_LnxWrpFmDev);
+}
+
+/* FMan character device file operations */
+extern struct file_operations fm_fops;
+
+static int /*__devinit*/ fm_probe(struct platform_device *of_dev)
+{
+ t_LnxWrpFmDev *p_LnxWrpFmDev;
+
+ if ((p_LnxWrpFmDev = ReadFmDevTreeNode(of_dev)) == NULL)
+ return -EIO;
+ if (ConfigureFmDev(p_LnxWrpFmDev) != E_OK)
+ return -EIO;
+ if (InitFmDev(p_LnxWrpFmDev) != E_OK)
+ return -EIO;
+
+ /* IOCTL ABI checking */
+ LnxWrpPCDIOCTLEnumChecking();
+ LnxWrpPCDIOCTLTypeChecking();
+
+ Sprint (p_LnxWrpFmDev->name, "%s%d", DEV_FM_NAME, p_LnxWrpFmDev->id);
+
+ /* Register to the /dev for IOCTL API */
+ /* Register dynamically a new major number for the character device: */
+ if ((p_LnxWrpFmDev->major = register_chrdev(0, p_LnxWrpFmDev->name, &fm_fops)) <= 0) {
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Failed to allocate a major number for device \"%s\"", p_LnxWrpFmDev->name));
+ return -EIO;
+ }
+
+ /* Creating classes for FM */
+ DBG(TRACE ,("class_create fm_class"));
+ p_LnxWrpFmDev->fm_class = class_create(THIS_MODULE, p_LnxWrpFmDev->name);
+ if (IS_ERR(p_LnxWrpFmDev->fm_class)) {
+ unregister_chrdev(p_LnxWrpFmDev->major, p_LnxWrpFmDev->name);
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("class_create error fm_class"));
+ return -EIO;
+ }
+
+ device_create(p_LnxWrpFmDev->fm_class, NULL, MKDEV(p_LnxWrpFmDev->major, DEV_FM_MINOR_BASE), NULL,
+ "fm%d", p_LnxWrpFmDev->id);
+ device_create(p_LnxWrpFmDev->fm_class, NULL, MKDEV(p_LnxWrpFmDev->major, DEV_FM_PCD_MINOR_BASE), NULL,
+ "fm%d-pcd", p_LnxWrpFmDev->id);
+ dev_set_drvdata(p_LnxWrpFmDev->dev, p_LnxWrpFmDev);
+
+ /* create sysfs entries for stats and regs */
+ if ( fm_sysfs_create(p_LnxWrpFmDev->dev) !=0 )
+ {
+ FreeFmDev(p_LnxWrpFmDev);
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Unable to create sysfs entry - fm!!!"));
+ return -EIO;
+ }
+
+#ifdef CONFIG_PM
+ device_set_wakeup_capable(p_LnxWrpFmDev->dev, true);
+#endif
+
+ DBG(TRACE, ("FM%d probed", p_LnxWrpFmDev->id));
+
+ return 0;
+}
+
+static int fm_remove(struct platform_device *of_dev)
+{
+ t_LnxWrpFmDev *p_LnxWrpFmDev;
+ struct device *dev;
+
+ dev = &of_dev->dev;
+ p_LnxWrpFmDev = dev_get_drvdata(dev);
+
+ fm_sysfs_destroy(dev);
+
+ DBG(TRACE, ("destroy fm_class"));
+ device_destroy(p_LnxWrpFmDev->fm_class, MKDEV(p_LnxWrpFmDev->major, DEV_FM_MINOR_BASE));
+ device_destroy(p_LnxWrpFmDev->fm_class, MKDEV(p_LnxWrpFmDev->major, DEV_FM_PCD_MINOR_BASE));
+ class_destroy(p_LnxWrpFmDev->fm_class);
+
+ /* Destroy chardev */
+ unregister_chrdev(p_LnxWrpFmDev->major, p_LnxWrpFmDev->name);
+
+ FreeFmDev(p_LnxWrpFmDev);
+
+ DestroyFmDev(p_LnxWrpFmDev);
+
+ dev_set_drvdata(dev, NULL);
+
+ return 0;
+}
+
+static const struct of_device_id fm_match[] = {
+ {
+ .compatible = "fsl,fman"
+ },
+ {}
+};
+#ifndef MODULE
+MODULE_DEVICE_TABLE(of, fm_match);
+#endif /* !MODULE */
+
+#ifdef CONFIG_PM
+
+#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C
+#define SCFG_FMCLKDPSLPCR_DS_VAL 0x48402000
+#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000
+
+struct device *g_fm_dev;
+
+static int fm_soc_suspend(struct device *dev)
+{
+ int err = 0;
+ uint32_t *fmclk;
+ t_LnxWrpFmDev *p_LnxWrpFmDev = dev_get_drvdata(get_device(dev));
+ g_fm_dev = dev;
+ fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
+ WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL);
+ if (p_LnxWrpFmDev->h_DsarRxPort)
+ {
+#ifdef CONFIG_FSL_QORIQ_PM
+ device_set_wakeup_enable(p_LnxWrpFmDev->dev, 1);
+#endif
+ err = FM_PORT_EnterDsarFinal(p_LnxWrpFmDev->h_DsarRxPort,
+ p_LnxWrpFmDev->h_DsarTxPort);
+ }
+ return err;
+}
+
+static int fm_soc_resume(struct device *dev)
+{
+ t_LnxWrpFmDev *p_LnxWrpFmDev = dev_get_drvdata(get_device(dev));
+ uint32_t *fmclk;
+ fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
+ WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_NORMAL_VAL);
+ if (p_LnxWrpFmDev->h_DsarRxPort)
+ {
+#ifdef CONFIG_FSL_QORIQ_PM
+ device_set_wakeup_enable(p_LnxWrpFmDev->dev, 0);
+#endif
+ FM_PORT_ExitDsar(p_LnxWrpFmDev->h_DsarRxPort,
+ p_LnxWrpFmDev->h_DsarTxPort);
+ p_LnxWrpFmDev->h_DsarRxPort = 0;
+ p_LnxWrpFmDev->h_DsarTxPort = 0;
+ }
+ return 0;
+}
+
+static const struct dev_pm_ops fm_pm_ops = {
+ .suspend = fm_soc_suspend,
+ .resume = fm_soc_resume,
+};
+
+#define FM_PM_OPS (&fm_pm_ops)
+
+#else /* CONFIG_PM */
+
+#define FM_PM_OPS NULL
+
+#endif /* CONFIG_PM */
+
+static struct platform_driver fm_driver = {
+ .driver = {
+ .name = "fsl-fman",
+ .of_match_table = fm_match,
+ .owner = THIS_MODULE,
+ .pm = FM_PM_OPS,
+ },
+ .probe = fm_probe,
+ .remove = fm_remove
+};
+
+t_Handle LNXWRP_FM_Init(void)
+{
+ memset(&lnxWrpFm, 0, sizeof(lnxWrpFm));
+ mutex_init(&lnxwrp_mutex);
+
+ /* Register to the DTB for basic FM API */
+ platform_driver_register(&fm_driver);
+
+ return &lnxWrpFm;
+}
+
+t_Error LNXWRP_FM_Free(t_Handle h_LnxWrpFm)
+{
+ platform_driver_unregister(&fm_driver);
+ mutex_destroy(&lnxwrp_mutex);
+
+ return E_OK;
+}
+
+
+struct fm * fm_bind(struct device *fm_dev)
+{
+ return (struct fm *)(dev_get_drvdata(get_device(fm_dev)));
+}
+EXPORT_SYMBOL(fm_bind);
+
+void fm_unbind(struct fm *fm)
+{
+ t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
+
+ put_device(p_LnxWrpFmDev->dev);
+}
+EXPORT_SYMBOL(fm_unbind);
+
+struct resource * fm_get_mem_region(struct fm *fm)
+{
+ t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
+
+ return p_LnxWrpFmDev->res;
+}
+EXPORT_SYMBOL(fm_get_mem_region);
+
+void * fm_get_handle(struct fm *fm)
+{
+ t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
+
+ return (void *)p_LnxWrpFmDev->h_Dev;
+}
+EXPORT_SYMBOL(fm_get_handle);
+
+void * fm_get_rtc_handle(struct fm *fm)
+{
+ t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
+
+ return (void *)p_LnxWrpFmDev->h_RtcDev;
+}
+EXPORT_SYMBOL(fm_get_rtc_handle);
+
+struct fm_port * fm_port_bind (struct device *fm_port_dev)
+{
+ return (struct fm_port *)(dev_get_drvdata(get_device(fm_port_dev)));
+}
+EXPORT_SYMBOL(fm_port_bind);
+
+void fm_port_unbind(struct fm_port *port)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
+
+ put_device(p_LnxWrpFmPortDev->dev);
+}
+EXPORT_SYMBOL(fm_port_unbind);
+
+void *fm_port_get_handle(const struct fm_port *port)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
+
+ return (void *)p_LnxWrpFmPortDev->h_Dev;
+}
+EXPORT_SYMBOL(fm_port_get_handle);
+
+u64 *fm_port_get_buffer_time_stamp(const struct fm_port *port,
+ const void *data)
+{
+ return FM_PORT_GetBufferTimeStamp(fm_port_get_handle(port),
+ (void *)data);
+}
+EXPORT_SYMBOL(fm_port_get_buffer_time_stamp);
+
+void fm_port_get_base_addr(const struct fm_port *port, uint64_t *base_addr)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
+
+ *base_addr = p_LnxWrpFmPortDev->settings.param.baseAddr;
+}
+EXPORT_SYMBOL(fm_port_get_base_addr);
+
+void fm_port_pcd_bind (struct fm_port *port, struct fm_port_pcd_param *params)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
+
+ p_LnxWrpFmPortDev->pcd_owner_params.cba = params->cba;
+ p_LnxWrpFmPortDev->pcd_owner_params.cbf = params->cbf;
+ p_LnxWrpFmPortDev->pcd_owner_params.dev = params->dev;
+}
+EXPORT_SYMBOL(fm_port_pcd_bind);
+
+void fm_port_get_buff_layout_ext_params(struct fm_port *port, struct fm_port_params *params)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
+ struct device_node *fm_node, *port_node;
+ const uint32_t *uint32_prop;
+ int lenp;
+
+ params->data_align = 0;
+ params->manip_extra_space = 0;
+
+ fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
+ if (!fm_node) /* no advance parameters for FMan */
+ return;
+
+ port_node = GetFmPortAdvArgsDevTreeNode(fm_node,
+ p_LnxWrpFmPortDev->settings.param.portType,
+ p_LnxWrpFmPortDev->settings.param.portId);
+ if (!port_node) /* no advance parameters for FMan-Port */
+ return;
+
+ uint32_prop = (uint32_t *)of_get_property(port_node, "buffer-layout", &lenp);
+ if (uint32_prop) {
+ if (WARN_ON(lenp != sizeof(uint32_t)*2))
+ return;
+
+ params->manip_extra_space = (uint8_t)be32_to_cpu(uint32_prop[0]);
+ params->data_align = (uint16_t)be32_to_cpu(uint32_prop[1]);
+ }
+
+ of_node_put(port_node);
+ of_node_put(fm_node);
+}
+EXPORT_SYMBOL(fm_port_get_buff_layout_ext_params);
+
+uint16_t fm_get_tx_port_channel(struct fm_port *port)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
+
+ return p_LnxWrpFmPortDev->txCh;
+}
+EXPORT_SYMBOL(fm_get_tx_port_channel);
+
+int fm_port_enable (struct fm_port *port)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
+ t_Error err = FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
+
+ return GET_ERROR_TYPE(err);
+}
+EXPORT_SYMBOL(fm_port_enable);
+
+int fm_port_disable(struct fm_port *port)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
+ t_Error err = FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
+
+ return GET_ERROR_TYPE(err);
+}
+EXPORT_SYMBOL(fm_port_disable);
+
+int fm_port_set_rate_limit(struct fm_port *port,
+ uint16_t max_burst_size,
+ uint32_t rate_limit)
+{
+ t_FmPortRateLimit param;
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
+ int err = 0;
+
+ param.maxBurstSize = max_burst_size;
+ param.rateLimit = rate_limit;
+ param.rateLimitDivider = 0;
+
+ err = FM_PORT_SetRateLimit(p_LnxWrpFmPortDev->h_Dev, &param);
+ return err;
+}
+EXPORT_SYMBOL(fm_port_set_rate_limit);
+
+int fm_port_del_rate_limit(struct fm_port *port)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
+
+ FM_PORT_DeleteRateLimit(p_LnxWrpFmPortDev->h_Dev);
+ return 0;
+}
+EXPORT_SYMBOL(fm_port_del_rate_limit);
+
+void FM_PORT_Dsar_DumpRegs(void);
+int ar_showmem(struct file *file, const char __user *buffer,
+ unsigned long count, void *data)
+{
+ FM_PORT_Dsar_DumpRegs();
+ return 2;
+}
+
+struct auto_res_tables_sizes *fm_port_get_autores_maxsize(
+ struct fm_port *port)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
+ return &p_LnxWrpFmPortDev->dsar_table_sizes;
+}
+EXPORT_SYMBOL(fm_port_get_autores_maxsize);
+
+int fm_port_enter_autores_for_deepsleep(struct fm_port *port,
+ struct auto_res_port_params *params)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
+ t_LnxWrpFmDev* p_LnxWrpFmDev = (t_LnxWrpFmDev*)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
+ p_LnxWrpFmDev->h_DsarRxPort = p_LnxWrpFmPortDev->h_Dev;
+ p_LnxWrpFmDev->h_DsarTxPort = params->h_FmPortTx;
+
+ /*Register other under /proc/autoresponse */
+ if (WARN_ON(sizeof(t_FmPortDsarParams) != sizeof(struct auto_res_port_params)))
+ return -EFAULT;
+
+ FM_PORT_EnterDsar(p_LnxWrpFmPortDev->h_Dev, (t_FmPortDsarParams*)params);
+ return 0;
+}
+EXPORT_SYMBOL(fm_port_enter_autores_for_deepsleep);
+
+void fm_port_exit_auto_res_for_deep_sleep(struct fm_port *port_rx,
+ struct fm_port *port_tx)
+{
+}
+EXPORT_SYMBOL(fm_port_exit_auto_res_for_deep_sleep);
+
+int fm_port_get_autores_stats(struct fm_port *port,
+ struct auto_res_port_stats *stats)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
+ if (WARN_ON(sizeof(t_FmPortDsarStats) != sizeof(struct auto_res_port_stats)))
+ return -EFAULT;
+ return FM_PORT_GetDsarStats(p_LnxWrpFmPortDev->h_Dev, (t_FmPortDsarStats*)stats);
+}
+EXPORT_SYMBOL(fm_port_get_autores_stats);
+
+int fm_port_suspend(struct fm_port *port)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
+ if (!FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev))
+ return FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
+ else
+ return 0;
+}
+EXPORT_SYMBOL(fm_port_suspend);
+
+int fm_port_resume(struct fm_port *port)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
+ if (!FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev))
+ return FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
+ else
+ return 0;
+}
+EXPORT_SYMBOL(fm_port_resume);
+
+bool fm_port_is_in_auto_res_mode(struct fm_port *port)
+{
+ return FM_PORT_IsInDsar(port);
+}
+EXPORT_SYMBOL(fm_port_is_in_auto_res_mode);
+
+#ifdef CONFIG_FMAN_PFC
+int fm_port_set_pfc_priorities_mapping_to_qman_wq(struct fm_port *port,
+ uint8_t prio, uint8_t wq)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
+ int err;
+ int _errno;
+
+ err = FM_PORT_SetPfcPrioritiesMappingToQmanWQ(p_LnxWrpFmPortDev->h_Dev,
+ prio, wq);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_PORT_SetPfcPrioritiesMappingToQmanWQ() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_port_set_pfc_priorities_mapping_to_qman_wq);
+#endif
+
+int fm_mac_set_exception(struct fm_mac_dev *fm_mac_dev,
+ e_FmMacExceptions exception, bool enable)
+{
+ int err;
+ int _errno;
+
+ err = FM_MAC_SetException(fm_mac_dev, exception, enable);
+
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MAC_SetException() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_mac_set_exception);
+
+int fm_mac_free(struct fm_mac_dev *fm_mac_dev)
+{
+ int err;
+ int _error;
+
+ err = FM_MAC_Free(fm_mac_dev);
+ _error = -GET_ERROR_TYPE(err);
+
+ if (unlikely(_error < 0))
+ pr_err("FM_MAC_Free() = 0x%08x\n", err);
+
+ return _error;
+}
+EXPORT_SYMBOL(fm_mac_free);
+
+struct fm_mac_dev *fm_mac_config(t_FmMacParams *params)
+{
+ struct fm_mac_dev *fm_mac_dev;
+
+ fm_mac_dev = FM_MAC_Config(params);
+ if (unlikely(fm_mac_dev == NULL))
+ pr_err("FM_MAC_Config() failed\n");
+
+ return fm_mac_dev;
+}
+EXPORT_SYMBOL(fm_mac_config);
+
+int fm_mac_config_max_frame_length(struct fm_mac_dev *fm_mac_dev,
+ int len)
+{
+ int err;
+ int _errno;
+
+ err = FM_MAC_ConfigMaxFrameLength(fm_mac_dev, len);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MAC_ConfigMaxFrameLength() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_mac_config_max_frame_length);
+
+int fm_mac_config_pad_and_crc(struct fm_mac_dev *fm_mac_dev, bool enable)
+{
+ int err;
+ int _errno;
+
+ err = FM_MAC_ConfigPadAndCrc(fm_mac_dev, enable);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MAC_ConfigPadAndCrc() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_mac_config_pad_and_crc);
+
+int fm_mac_config_half_duplex(struct fm_mac_dev *fm_mac_dev, bool enable)
+{
+ int err;
+ int _errno;
+
+ err = FM_MAC_ConfigHalfDuplex(fm_mac_dev, enable);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MAC_ConfigHalfDuplex() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_mac_config_half_duplex);
+
+int fm_mac_config_reset_on_init(struct fm_mac_dev *fm_mac_dev, bool enable)
+{
+ int err;
+ int _errno;
+
+ err = FM_MAC_ConfigResetOnInit(fm_mac_dev, enable);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MAC_ConfigResetOnInit() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_mac_config_reset_on_init);
+
+int fm_mac_init(struct fm_mac_dev *fm_mac_dev)
+{
+ int err;
+ int _errno;
+
+ err = FM_MAC_Init(fm_mac_dev);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MAC_Init() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_mac_init);
+
+int fm_mac_get_version(struct fm_mac_dev *fm_mac_dev, uint32_t *version)
+{
+ int err;
+ int _errno;
+
+ err = FM_MAC_GetVesrion(fm_mac_dev, version);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MAC_GetVesrion() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_mac_get_version);
+
+int fm_mac_enable(struct fm_mac_dev *fm_mac_dev)
+{
+ int _errno;
+ t_Error err;
+
+ err = FM_MAC_Enable(fm_mac_dev, e_COMM_MODE_RX_AND_TX);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MAC_Enable() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_mac_enable);
+
+int fm_mac_disable(struct fm_mac_dev *fm_mac_dev)
+{
+ int _errno;
+ t_Error err;
+
+ err = FM_MAC_Disable(fm_mac_dev, e_COMM_MODE_RX_AND_TX);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MAC_Disable() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_mac_disable);
+
+int fm_mac_resume(struct fm_mac_dev *fm_mac_dev)
+{
+ int _errno;
+ t_Error err;
+
+ err = FM_MAC_Resume(fm_mac_dev);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MAC_Resume() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_mac_resume);
+
+int fm_mac_set_promiscuous(struct fm_mac_dev *fm_mac_dev,
+ bool enable)
+{
+ int _errno;
+ t_Error err;
+
+ err = FM_MAC_SetPromiscuous(fm_mac_dev, enable);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MAC_SetPromiscuous() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_mac_set_promiscuous);
+
+int fm_mac_remove_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
+ t_EnetAddr *mac_addr)
+{
+ int _errno;
+ t_Error err;
+
+ err = FM_MAC_RemoveHashMacAddr(fm_mac_dev, mac_addr);
+ _errno = -GET_ERROR_TYPE(err);
+ if (_errno < 0) {
+ pr_err("FM_MAC_RemoveHashMacAddr() = 0x%08x\n", err);
+ return _errno;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(fm_mac_remove_hash_mac_addr);
+
+int fm_mac_add_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
+ t_EnetAddr *mac_addr)
+{
+ int _errno;
+ t_Error err;
+
+ err = FM_MAC_AddHashMacAddr(fm_mac_dev, mac_addr);
+ _errno = -GET_ERROR_TYPE(err);
+ if (_errno < 0) {
+ pr_err("FM_MAC_AddHashMacAddr() = 0x%08x\n", err);
+ return _errno;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(fm_mac_add_hash_mac_addr);
+
+int fm_mac_modify_mac_addr(struct fm_mac_dev *fm_mac_dev,
+ uint8_t *addr)
+{
+ int _errno;
+ t_Error err;
+
+ err = FM_MAC_ModifyMacAddr(fm_mac_dev, (t_EnetAddr *)addr);
+ _errno = -GET_ERROR_TYPE(err);
+ if (_errno < 0)
+ pr_err("FM_MAC_ModifyMacAddr() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_mac_modify_mac_addr);
+
+int fm_mac_adjust_link(struct fm_mac_dev *fm_mac_dev,
+ bool link, int speed, bool duplex)
+{
+ int _errno;
+ t_Error err;
+
+ if (!link) {
+#if (DPAA_VERSION < 11)
+ FM_MAC_RestartAutoneg(fm_mac_dev);
+#endif
+ return 0;
+ }
+
+ err = FM_MAC_AdjustLink(fm_mac_dev, speed, duplex);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MAC_AdjustLink() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_mac_adjust_link);
+
+int fm_mac_enable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev)
+{
+ int _errno;
+ t_Error err;
+
+ err = FM_MAC_Enable1588TimeStamp(fm_mac_dev);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MAC_Enable1588TimeStamp() = 0x%08x\n", err);
+ return _errno;
+}
+EXPORT_SYMBOL(fm_mac_enable_1588_time_stamp);
+
+int fm_mac_disable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev)
+{
+ int _errno;
+ t_Error err;
+
+ err = FM_MAC_Disable1588TimeStamp(fm_mac_dev);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MAC_Disable1588TimeStamp() = 0x%08x\n", err);
+ return _errno;
+}
+EXPORT_SYMBOL(fm_mac_disable_1588_time_stamp);
+
+int fm_mac_set_rx_pause_frames(
+ struct fm_mac_dev *fm_mac_dev, bool en)
+{
+ int _errno;
+ t_Error err;
+
+ /* if rx pause is enabled, do NOT ignore pause frames */
+ err = FM_MAC_SetRxIgnorePauseFrames(fm_mac_dev, !en);
+
+ _errno = -GET_ERROR_TYPE(err);
+ if (_errno < 0)
+ pr_err("FM_MAC_SetRxIgnorePauseFrames() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_mac_set_rx_pause_frames);
+
+#ifdef CONFIG_FMAN_PFC
+int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
+ bool en)
+{
+ int _errno, i;
+ t_Error err;
+
+ if (en)
+ for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
+ err = FM_MAC_SetTxPauseFrames(fm_mac_dev,
+ i, fsl_fm_pfc_quanta[i],
+ FSL_FM_PAUSE_THRESH_DEFAULT);
+ _errno = -GET_ERROR_TYPE(err);
+ if (_errno < 0) {
+ pr_err("FM_MAC_SetTxPauseFrames() = 0x%08x\n", err);
+ return _errno;
+ }
+ }
+ else
+ for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
+ err = FM_MAC_SetTxPauseFrames(fm_mac_dev,
+ i, FSL_FM_PAUSE_TIME_DISABLE,
+ FSL_FM_PAUSE_THRESH_DEFAULT);
+ _errno = -GET_ERROR_TYPE(err);
+ if (_errno < 0) {
+ pr_err("FM_MAC_SetTxPauseFrames() = 0x%08x\n", err);
+ return _errno;
+ }
+ }
+
+ return _errno;
+}
+#else
+int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
+ bool en)
+{
+ int _errno;
+ t_Error err;
+
+ if (en)
+ err = FM_MAC_SetTxAutoPauseFrames(fm_mac_dev,
+ FSL_FM_PAUSE_TIME_ENABLE);
+ else
+ err = FM_MAC_SetTxAutoPauseFrames(fm_mac_dev,
+ FSL_FM_PAUSE_TIME_DISABLE);
+
+ _errno = -GET_ERROR_TYPE(err);
+ if (_errno < 0)
+ pr_err("FM_MAC_SetTxAutoPauseFrames() = 0x%08x\n", err);
+
+ return _errno;
+}
+#endif
+EXPORT_SYMBOL(fm_mac_set_tx_pause_frames);
+
+int fm_rtc_enable(struct fm *fm_dev)
+{
+ int _errno;
+ t_Error err;
+
+ err = FM_RTC_Enable(fm_get_rtc_handle(fm_dev), 0);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_RTC_Enable = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_rtc_enable);
+
+int fm_rtc_disable(struct fm *fm_dev)
+{
+ int _errno;
+ t_Error err;
+
+ err = FM_RTC_Disable(fm_get_rtc_handle(fm_dev));
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_RTC_Disable = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_rtc_disable);
+
+int fm_rtc_get_cnt(struct fm *fm_dev, uint64_t *ts)
+{
+ int _errno;
+ t_Error err;
+
+ err = FM_RTC_GetCurrentTime(fm_get_rtc_handle(fm_dev), ts);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_RTC_GetCurrentTime = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_rtc_get_cnt);
+
+int fm_rtc_set_cnt(struct fm *fm_dev, uint64_t ts)
+{
+ int _errno;
+ t_Error err;
+
+ err = FM_RTC_SetCurrentTime(fm_get_rtc_handle(fm_dev), ts);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_RTC_SetCurrentTime = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_rtc_set_cnt);
+
+int fm_rtc_get_drift(struct fm *fm_dev, uint32_t *drift)
+{
+ int _errno;
+ t_Error err;
+
+ err = FM_RTC_GetFreqCompensation(fm_get_rtc_handle(fm_dev),
+ drift);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_RTC_GetFreqCompensation = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_rtc_get_drift);
+
+int fm_rtc_set_drift(struct fm *fm_dev, uint32_t drift)
+{
+ int _errno;
+ t_Error err;
+
+ err = FM_RTC_SetFreqCompensation(fm_get_rtc_handle(fm_dev),
+ drift);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_RTC_SetFreqCompensation = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_rtc_set_drift);
+
+int fm_rtc_set_alarm(struct fm *fm_dev, uint32_t id,
+ uint64_t time)
+{
+ t_FmRtcAlarmParams alarm;
+ int _errno;
+ t_Error err;
+
+ alarm.alarmId = id;
+ alarm.alarmTime = time;
+ alarm.f_AlarmCallback = NULL;
+ err = FM_RTC_SetAlarm(fm_get_rtc_handle(fm_dev),
+ &alarm);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_RTC_SetAlarm = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_rtc_set_alarm);
+
+int fm_rtc_set_fiper(struct fm *fm_dev, uint32_t id,
+ uint64_t fiper)
+{
+ t_FmRtcPeriodicPulseParams pp;
+ int _errno;
+ t_Error err;
+
+ pp.periodicPulseId = id;
+ pp.periodicPulsePeriod = fiper;
+ pp.f_PeriodicPulseCallback = NULL;
+ err = FM_RTC_SetPeriodicPulse(fm_get_rtc_handle(fm_dev), &pp);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_RTC_SetPeriodicPulse = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_rtc_set_fiper);
+
+#ifdef CONFIG_PTP_1588_CLOCK_DPAA
+int fm_rtc_enable_interrupt(struct fm *fm_dev, uint32_t events)
+{
+ int _errno;
+ t_Error err;
+
+ err = FM_RTC_EnableInterrupt(fm_get_rtc_handle(fm_dev),
+ events);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_RTC_EnableInterrupt = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_rtc_enable_interrupt);
+
+int fm_rtc_disable_interrupt(struct fm *fm_dev, uint32_t events)
+{
+ int _errno;
+ t_Error err;
+
+ err = FM_RTC_DisableInterrupt(fm_get_rtc_handle(fm_dev),
+ events);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_RTC_DisableInterrupt = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_rtc_disable_interrupt);
+#endif
+
+int fm_mac_set_wol(struct fm_port *port, struct fm_mac_dev *fm_mac_dev, bool en)
+{
+ int _errno;
+ t_Error err;
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
+
+ /* Do not set WoL on AR ports */
+ if (FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev)) {
+ printk(KERN_WARNING "Port is AutoResponse enabled! WoL will not be set on this port!\n");
+ return 0;
+ }
+
+ err = FM_MAC_SetWakeOnLan(fm_mac_dev, en);
+
+ _errno = -GET_ERROR_TYPE(err);
+ if (_errno < 0)
+ pr_err("FM_MAC_SetWakeOnLan() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_mac_set_wol);
+
+void fm_mutex_lock(void)
+{
+ mutex_lock(&lnxwrp_mutex);
+}
+EXPORT_SYMBOL(fm_mutex_lock);
+
+void fm_mutex_unlock(void)
+{
+ mutex_unlock(&lnxwrp_mutex);
+}
+EXPORT_SYMBOL(fm_mutex_unlock);
+
+/*Macsec wrapper functions*/
+struct fm_macsec_dev *fm_macsec_config(struct fm_macsec_params *fm_params)
+{
+ struct fm_macsec_dev *fm_macsec_dev;
+
+ fm_macsec_dev = FM_MACSEC_Config((t_FmMacsecParams *)fm_params);
+ if (unlikely(fm_macsec_dev == NULL))
+ pr_err("FM_MACSEC_Config() failed\n");
+
+ return fm_macsec_dev;
+}
+EXPORT_SYMBOL(fm_macsec_config);
+
+int fm_macsec_init(struct fm_macsec_dev *fm_macsec_dev)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_Init(fm_macsec_dev);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_Init() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_init);
+
+int fm_macsec_free(struct fm_macsec_dev *fm_macsec_dev)
+{
+ int err;
+ int _error;
+
+ err = FM_MACSEC_Free(fm_macsec_dev);
+ _error = -GET_ERROR_TYPE(err);
+
+ if (unlikely(_error < 0))
+ pr_err("FM_MACSEC_Free() = 0x%08x\n", err);
+
+ return _error;
+}
+EXPORT_SYMBOL(fm_macsec_free);
+
+int fm_macsec_config_unknown_sci_frame_treatment(struct fm_macsec_dev
+ *fm_macsec_dev,
+ fm_macsec_unknown_sci_frame_treatment treat_mode)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_ConfigUnknownSciFrameTreatment(fm_macsec_dev,
+ treat_mode);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_ConfigUnknownSciFrameTreatmen() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_config_unknown_sci_frame_treatment);
+
+int fm_macsec_config_invalid_tags_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
+ bool deliver_uncontrolled)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_ConfigInvalidTagsFrameTreatment(fm_macsec_dev,
+ deliver_uncontrolled);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MAC_ConfigMaxFrameLength() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_config_invalid_tags_frame_treatment);
+
+int fm_macsec_config_kay_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
+ bool discard_uncontrolled)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(fm_macsec_dev,
+ discard_uncontrolled);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatmen() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_config_kay_frame_treatment);
+
+int fm_macsec_config_untag_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
+ fm_macsec_untag_frame_treatment treat_mode)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_ConfigUntagFrameTreatment(fm_macsec_dev, treat_mode);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_ConfigUntagFrameTreatment() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_config_untag_frame_treatment);
+
+int fm_macsec_config_pn_exhaustion_threshold(struct fm_macsec_dev *fm_macsec_dev,
+ uint32_t pn_exh_thr)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_ConfigPnExhaustionThreshold(fm_macsec_dev, pn_exh_thr);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_ConfigPnExhaustionThreshold() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_config_pn_exhaustion_threshold);
+
+int fm_macsec_config_keys_unreadable(struct fm_macsec_dev *fm_macsec_dev)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_ConfigKeysUnreadable(fm_macsec_dev);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_ConfigKeysUnreadable() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_config_keys_unreadable);
+
+int fm_macsec_config_sectag_without_sci(struct fm_macsec_dev *fm_macsec_dev)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_ConfigSectagWithoutSCI(fm_macsec_dev);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_ConfigSectagWithoutSCI() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_config_sectag_without_sci);
+
+int fm_macsec_config_exception(struct fm_macsec_dev *fm_macsec_dev,
+ fm_macsec_exception exception, bool enable)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_ConfigException(fm_macsec_dev, exception, enable);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_ConfigException() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_config_exception);
+
+int fm_macsec_get_revision(struct fm_macsec_dev *fm_macsec_dev,
+ int *macsec_revision)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_GetRevision(fm_macsec_dev, macsec_revision);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_GetRevision() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_get_revision);
+
+int fm_macsec_enable(struct fm_macsec_dev *fm_macsec_dev)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_Enable(fm_macsec_dev);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_Enable() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_enable);
+
+int fm_macsec_disable(struct fm_macsec_dev *fm_macsec_dev)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_Disable(fm_macsec_dev);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_Disable() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_disable);
+
+int fm_macsec_set_exception(struct fm_macsec_dev *fm_macsec_dev,
+ fm_macsec_exception exception, bool enable)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SetException(fm_macsec_dev, exception, enable);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SetException() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_set_exception);
+
+/* Macsec SECY wrapper API */
+struct fm_macsec_secy_dev *fm_macsec_secy_config(struct fm_macsec_secy_params *secy_params)
+{
+ struct fm_macsec_secy_dev *fm_macsec_secy;
+
+ fm_macsec_secy = FM_MACSEC_SECY_Config((t_FmMacsecSecYParams *)secy_params);
+ if (unlikely(fm_macsec_secy < 0))
+ pr_err("FM_MACSEC_SECY_Config() failed\n");
+
+ return fm_macsec_secy;
+}
+EXPORT_SYMBOL(fm_macsec_secy_config);
+
+int fm_macsec_secy_init(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SECY_Init(fm_macsec_secy_dev);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SECY_Init() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_secy_init);
+
+int fm_macsec_secy_free(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SECY_Free(fm_macsec_secy_dev);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SECY_Free() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_secy_free);
+
+int fm_macsec_secy_config_sci_insertion_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
+ fm_macsec_sci_insertion_mode sci_insertion_mode)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SECY_ConfigSciInsertionMode(fm_macsec_secy_dev,
+ sci_insertion_mode);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SECY_ConfigSciInsertionMode() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_secy_config_sci_insertion_mode);
+
+int fm_macsec_secy_config_protect_frames(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
+ bool protect_frames)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SECY_ConfigProtectFrames(fm_macsec_secy_dev,
+ protect_frames);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SECY_ConfigProtectFrames() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_secy_config_protect_frames);
+
+int fm_macsec_secy_config_replay_window(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
+ bool replay_protect, uint32_t replay_window)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SECY_ConfigReplayWindow(fm_macsec_secy_dev,
+ replay_protect, replay_window);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SECY_ConfigReplayWindow() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_secy_config_replay_window);
+
+int fm_macsec_secy_config_validation_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
+ fm_macsec_valid_frame_behavior validate_frames)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SECY_ConfigValidationMode(fm_macsec_secy_dev,
+ validate_frames);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SECY_ConfigValidationMode() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_secy_config_validation_mode);
+
+int fm_macsec_secy_config_confidentiality(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
+ bool confidentiality_enable,
+ uint32_t confidentiality_offset)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SECY_ConfigConfidentiality(fm_macsec_secy_dev,
+ confidentiality_enable,
+ confidentiality_offset);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SECY_ConfigConfidentiality() = 0x%08x\n",
+ err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_secy_config_confidentiality);
+
+int fm_macsec_secy_config_point_to_point(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SECY_ConfigPointToPoint(fm_macsec_secy_dev);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SECY_ConfigPointToPoint() = 0x%08x\n",
+ err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_secy_config_point_to_point);
+
+int fm_macsec_secy_config_exception(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
+ fm_macsec_secy_exception exception,
+ bool enable)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SECY_ConfigException(fm_macsec_secy_dev, exception,
+ enable);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SECY_ConfigException() = 0x%08x\n",
+ err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_secy_config_exception);
+
+int fm_macsec_secy_config_event(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
+ fm_macsec_secy_event event,
+ bool enable)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SECY_ConfigEvent(fm_macsec_secy_dev, event, enable);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SECY_ConfigEvent() = 0x%08x\n",
+ err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_secy_config_event);
+
+struct rx_sc_dev *fm_macsec_secy_create_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
+ struct fm_macsec_secy_sc_params *params)
+{
+ struct rx_sc_dev *rx_sc_dev;
+
+ rx_sc_dev = FM_MACSEC_SECY_CreateRxSc(fm_macsec_secy_dev, (t_FmMacsecSecYSCParams *)params);
+ if (unlikely(rx_sc_dev == NULL))
+ pr_err("FM_MACSEC_SECY_CreateRxSc() failed\n");
+
+ return rx_sc_dev;
+}
+EXPORT_SYMBOL(fm_macsec_secy_create_rxsc);
+
+int fm_macsec_secy_delete_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
+ struct rx_sc_dev *sc)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SECY_DeleteRxSc(fm_macsec_secy_dev, sc);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SECY_DeleteRxSc() = 0x%08x\n",
+ err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_secy_delete_rxsc);
+
+int fm_macsec_secy_create_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
+ struct rx_sc_dev *sc, macsec_an_t an,
+ uint32_t lowest_pn, macsec_sa_key_t key)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SECY_CreateRxSa(fm_macsec_secy_dev, sc, an,
+ lowest_pn, key);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SECY_CreateRxSa() = 0x%08x\n",
+ err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_secy_create_rx_sa);
+
+int fm_macsec_secy_delete_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
+ struct rx_sc_dev *sc, macsec_an_t an)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SECY_DeleteRxSa(fm_macsec_secy_dev, sc, an);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SECY_DeleteRxSa() = 0x%08x\n",
+ err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_secy_delete_rx_sa);
+
+int fm_macsec_secy_rxsa_enable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
+ struct rx_sc_dev *sc,
+ macsec_an_t an)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SECY_RxSaEnableReceive(fm_macsec_secy_dev, sc, an);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SECY_RxSaEnableReceive() = 0x%08x\n",
+ err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_secy_rxsa_enable_receive);
+
+int fm_macsec_secy_rxsa_disable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
+ struct rx_sc_dev *sc,
+ macsec_an_t an)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SECY_RxSaDisableReceive(fm_macsec_secy_dev, sc, an);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SECY_RxSaDisableReceive() = 0x%08x\n",
+ err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_secy_rxsa_disable_receive);
+
+int fm_macsec_secy_rxsa_update_next_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
+ struct rx_sc_dev *sc,
+ macsec_an_t an, uint32_t updt_next_pn)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SECY_RxSaUpdateNextPn(fm_macsec_secy_dev, sc, an,
+ updt_next_pn);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SECY_RxSaUpdateNextPn() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_secy_rxsa_update_next_pn);
+
+int fm_macsec_secy_rxsa_update_lowest_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
+ struct rx_sc_dev *sc,
+ macsec_an_t an, uint32_t updt_lowest_pn)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SECY_RxSaUpdateLowestPn(fm_macsec_secy_dev, sc, an,
+ updt_lowest_pn);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SECY_RxSaUpdateLowestPn() = 0x%08x\n",
+ err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_secy_rxsa_update_lowest_pn);
+
+int fm_macsec_secy_rxsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
+ struct rx_sc_dev *sc,
+ macsec_an_t an, macsec_sa_key_t key)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SECY_RxSaModifyKey(fm_macsec_secy_dev, sc, an, key);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SECY_RxSaModifyKey() = 0x%08x\n",
+ err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_secy_rxsa_modify_key);
+
+int fm_macsec_secy_create_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
+ macsec_an_t an, macsec_sa_key_t key)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SECY_CreateTxSa(fm_macsec_secy_dev, an, key);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SECY_CreateTxSa() = 0x%08x\n",
+ err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_secy_create_tx_sa);
+
+int fm_macsec_secy_delete_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
+ macsec_an_t an)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SECY_DeleteTxSa(fm_macsec_secy_dev, an);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SECY_DeleteTxSa() = 0x%08x\n",
+ err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_secy_delete_tx_sa);
+
+int fm_macsec_secy_txsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
+ macsec_an_t next_active_an,
+ macsec_sa_key_t key)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SECY_TxSaModifyKey(fm_macsec_secy_dev, next_active_an,
+ key);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SECY_TxSaModifyKey() = 0x%08x\n",
+ err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_secy_txsa_modify_key);
+
+int fm_macsec_secy_txsa_set_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
+ macsec_an_t an)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SECY_TxSaSetActive(fm_macsec_secy_dev, an);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SECY_TxSaSetActive() = 0x%08x\n",
+ err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_secy_txsa_set_active);
+
+int fm_macsec_secy_txsa_get_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
+ macsec_an_t *p_an)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SECY_TxSaGetActive(fm_macsec_secy_dev, p_an);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SECY_TxSaGetActive() = 0x%08x\n",
+ err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_secy_txsa_get_active);
+
+int fm_macsec_secy_get_rxsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
+ struct rx_sc_dev *sc, uint32_t *sc_phys_id)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SECY_GetRxScPhysId(fm_macsec_secy_dev, sc, sc_phys_id);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SECY_GetRxScPhysId() = 0x%08x\n",
+ err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_secy_get_rxsc_phys_id);
+
+int fm_macsec_secy_get_txsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
+ uint32_t *sc_phys_id)
+{
+ int err;
+ int _errno;
+
+ err = FM_MACSEC_SECY_GetTxScPhysId(fm_macsec_secy_dev, sc_phys_id);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_MACSEC_SECY_GetTxScPhysId() = 0x%08x\n",
+ err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_macsec_secy_get_txsc_phys_id);
+
+static t_Handle h_FmLnxWrp;
+
+static int __init __cold fm_load (void)
+{
+ if ((h_FmLnxWrp = LNXWRP_FM_Init()) == NULL)
+ {
+ printk("Failed to init FM wrapper!\n");
+ return -ENODEV;
+ }
+
+ printk(KERN_CRIT "Freescale FM module," \
+ " FMD API version %d.%d.%d\n",
+ FMD_API_VERSION_MAJOR,
+ FMD_API_VERSION_MINOR,
+ FMD_API_VERSION_RESPIN);
+ return 0;
+}
+
+static void __exit __cold fm_unload (void)
+{
+ if (h_FmLnxWrp)
+ LNXWRP_FM_Free(h_FmLnxWrp);
+}
+
+module_init (fm_load);
+module_exit (fm_unload);