summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/freescale/sdk_fman/src/wrapper
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/freescale/sdk_fman/src/wrapper')
-rw-r--r--drivers/net/ethernet/freescale/sdk_fman/src/wrapper/Makefile19
-rw-r--r--drivers/net/ethernet/freescale/sdk_fman/src/wrapper/fman_test.c1665
-rwxr-xr-xdrivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c2939
-rw-r--r--drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.h294
-rw-r--r--drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c1506
-rw-r--r--drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c4869
-rw-r--r--drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c1299
-rw-r--r--drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h765
-rw-r--r--drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources.h121
-rw-r--r--drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.c191
-rw-r--r--drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.h144
-rw-r--r--drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.make28
-rw-r--r--drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c60
-rw-r--r--drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h52
-rw-r--r--drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c1858
-rw-r--r--drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h136
-rw-r--r--drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c1268
-rw-r--r--drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h56
18 files changed, 17270 insertions, 0 deletions
diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/Makefile b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/Makefile
new file mode 100644
index 000000000000..62713d626dfa
--- /dev/null
+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/Makefile
@@ -0,0 +1,19 @@
+#
+# Makefile for the Freescale Ethernet controllers
+#
+ccflags-y += -DVERSION=\"\"
+#
+#Include netcomm SW specific definitions
+include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
+
+NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
+
+ccflags-y += -I$(NCSW_FM_INC)
+ccflags-y += -I$(NET_DPA)
+
+obj-y += fsl-ncsw-PFM.o
+obj-$(CONFIG_FSL_SDK_FMAN_TEST) += fman_test.o
+
+fsl-ncsw-PFM-objs := lnxwrp_fm.o lnxwrp_fm_port.o lnxwrp_ioctls_fm.o \
+ lnxwrp_sysfs.o lnxwrp_sysfs_fm.o lnxwrp_sysfs_fm_port.o
+obj-$(CONFIG_COMPAT) += lnxwrp_ioctls_fm_compat.o
diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/fman_test.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/fman_test.c
new file mode 100644
index 000000000000..270d07b8829d
--- /dev/null
+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/fman_test.c
@@ -0,0 +1,1665 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of 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 fman_test.c
+ @Authors Pistirica Sorin Andrei
+ @Description FM Linux test environment
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/of_platform.h>
+#include <linux/ip.h>
+#include <linux/compat.h>
+#include <linux/uaccess.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/fsl_qman.h>
+#include <linux/fsl_bman.h>
+
+/* private headers */
+#include "fm_ext.h"
+#include "lnxwrp_fsl_fman.h"
+#include "fm_port_ext.h"
+#if (DPAA_VERSION == 11)
+#include "../../Peripherals/FM/MAC/memac.h"
+#endif
+#include "fm_test_ioctls.h"
+#include "fsl_fman_test.h"
+
+#include "dpaa_eth.h"
+#include "dpaa_eth_common.h"
+
+#define FMT_FRM_WATERMARK 0xdeadbeefdeadbeeaLL
+
+struct fmt_frame_s {
+ ioc_fmt_buff_desc_t buff;
+ struct list_head list;
+};
+
+struct fmt_fqs_s {
+ struct qman_fq fq_base;
+ bool init;
+ struct fmt_port_s *fmt_port_priv;
+};
+
+struct fmt_port_pcd_s {
+ int num_queues;
+ struct fmt_fqs_s *fmt_pcd_fqs;
+ uint32_t fqid_base;
+};
+
+/* char dev structure: fm test port */
+struct fmt_port_s {
+ bool valid;
+ uint8_t id;
+ ioc_fmt_port_type port_type;
+ ioc_diag_mode diag;
+ bool compat_test_type;
+
+ /* fm ports */
+ /* ! for oh ports p_tx_fm_port_dev == p_rx_fm_port_dev &&
+ * p_tx_port == p_rx_port */
+ /* t_LnxWrpFmPortDev */
+ struct fm_port *p_tx_port;
+ /* t_LnxWrpFmPortDev->h_Dev: t_FmPort */
+ void *p_tx_fm_port_dev;
+ /* t_LnxWrpFmPortDev */
+ struct fm_port *p_rx_port;
+ /* t_LnxWrpFmPortDev->h_Dev: t_FmPort */
+ void *p_rx_fm_port_dev;
+
+ void *p_mac_dev;
+ uint64_t fm_phys_base_addr;
+
+ /* read/write queue manipulation */
+ spinlock_t rx_q_lock;
+ struct list_head rx_q;
+
+ /* tx queuee for injecting traffic */
+ int num_of_tx_fqs;
+ struct fmt_fqs_s p_tx_fqs[FMAN_TEST_MAX_TX_FQS];
+
+ /* pcd private queues manipulation */
+ struct fmt_port_pcd_s fmt_port_pcd;
+
+ /* debugging stuff */
+
+#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
+ atomic_t enqueue_to_qman_frm;
+ atomic_t enqueue_to_rxq;
+ atomic_t dequeue_from_rxq;
+ atomic_t not_enqueue_to_rxq_wrong_frm;
+#endif
+
+};
+
+/* The devices. */
+struct fmt_s {
+ int major;
+ struct fmt_port_s ports[IOC_FMT_MAX_NUM_OF_PORTS];
+ struct class *fmt_class;
+};
+
+/* fm test structure */
+static struct fmt_s fm_test;
+
+#if (DPAA_VERSION == 11)
+struct mac_priv_s {
+ t_Handle mac;
+};
+#endif
+
+#define DTSEC_BASE_ADDR 0x000e0000
+#define DTSEC_MEM_RANGE 0x00002000
+#define MAC_1G_MACCFG1 0x00000100
+#define MAC_1G_LOOP_MASK 0x00000100
+static int set_1gmac_loopback(
+ struct fmt_port_s *fmt_port,
+ bool en)
+{
+#if (DPAA_VERSION <= 10)
+ uint32_t dtsec_idx = fmt_port->id; /* dtsec for which port */
+ uint32_t dtsec_idx_off = dtsec_idx * DTSEC_MEM_RANGE;
+ phys_addr_t maccfg1_hw;
+ void *maccfg1_map;
+ uint32_t maccfg1_val;
+
+ /* compute the maccfg1 register address */
+ maccfg1_hw = fmt_port->fm_phys_base_addr +
+ (phys_addr_t)(DTSEC_BASE_ADDR +
+ dtsec_idx_off +
+ MAC_1G_MACCFG1);
+
+ /* map register */
+ maccfg1_map = ioremap(maccfg1_hw, sizeof(u32));
+
+ /* set register */
+ maccfg1_val = in_be32(maccfg1_map);
+ if (en)
+ maccfg1_val |= MAC_1G_LOOP_MASK;
+ else
+ maccfg1_val &= ~MAC_1G_LOOP_MASK;
+ out_be32(maccfg1_map, maccfg1_val);
+
+ /* unmap register */
+ iounmap(maccfg1_map);
+#else
+ struct mac_device *mac_dev;
+ struct mac_priv_s *priv;
+ t_Memac *p_memac;
+
+ if (!fmt_port)
+ return -EINVAL;
+
+ mac_dev = (struct mac_device *)fmt_port->p_mac_dev;
+
+ if (!mac_dev)
+ return -EINVAL;
+
+ priv = macdev_priv(mac_dev);
+
+ if (!priv)
+ return -EINVAL;
+
+ p_memac = priv->mac;
+
+ if (!p_memac)
+ return -EINVAL;
+
+ memac_set_loopback(p_memac->p_MemMap, en);
+#endif
+ return 0;
+}
+
+/* TODO: re-write this function */
+static int set_10gmac_int_loopback(
+ struct fmt_port_s *fmt_port,
+ bool en)
+{
+#ifndef FM_10G_MAC_NO_CTRL_LOOPBACK
+#define FM_10GMAC0_OFFSET 0x000f0000
+#define FM_10GMAC_CMD_CONF_CTRL_OFFSET 0x8
+#define CMD_CFG_LOOPBACK_EN 0x00000400
+
+ uint64_t base_addr, reg_addr;
+ uint32_t tmp_val;
+
+ base_addr = fmt_port->fm_phys_base_addr + (FM_10GMAC0_OFFSET +
+ ((fmt_port->id-FM_MAX_NUM_OF_1G_RX_PORTS)*0x2000));
+
+ base_addr = PTR_TO_UINT(ioremap(base_addr, 0x1000));
+
+ reg_addr = base_addr + FM_10GMAC_CMD_CONF_CTRL_OFFSET;
+ tmp_val = GET_UINT32(*((uint32_t *)UINT_TO_PTR(reg_addr)));
+ if (en)
+ tmp_val |= CMD_CFG_LOOPBACK_EN;
+ else
+ tmp_val &= ~CMD_CFG_LOOPBACK_EN;
+ WRITE_UINT32(*((uint32_t *)UINT_TO_PTR(reg_addr)), tmp_val);
+
+ iounmap(UINT_TO_PTR(base_addr));
+
+ return 0;
+#else
+ _fmt_err("TGEC don't have internal-loopback.\n");
+ return -EPERM;
+#endif
+}
+
+static int set_mac_int_loopback(struct fmt_port_s *fmt_port, bool en)
+{
+ int _err = 0;
+
+ switch (fmt_port->port_type) {
+
+ case e_IOC_FMT_PORT_T_RXTX:
+ /* 1G port */
+ if (fmt_port->id < FM_MAX_NUM_OF_1G_RX_PORTS)
+ _err = set_1gmac_loopback(fmt_port, en);
+ /* 10g port */
+ else if ((fmt_port->id >= FM_MAX_NUM_OF_1G_RX_PORTS) &&
+ (fmt_port->id < FM_MAX_NUM_OF_1G_RX_PORTS +
+ FM_MAX_NUM_OF_10G_RX_PORTS)) {
+
+ _err = set_10gmac_int_loopback(fmt_port, en);
+ } else
+ _err = -EINVAL;
+ break;
+ /* op port does not have MAC (loopback mode) */
+ case e_IOC_FMT_PORT_T_OP:
+
+ _err = 0;
+ break;
+ default:
+
+ _err = -EPERM;
+ break;
+ }
+
+ return _err;
+}
+
+static void enqueue_fmt_frame(
+ struct fmt_port_s *fmt_port,
+ struct fmt_frame_s *p_fmt_frame)
+{
+ spinlock_t *rx_q_lock = NULL;
+
+ rx_q_lock = &fmt_port->rx_q_lock;
+
+ spin_lock(rx_q_lock);
+ list_add_tail(&p_fmt_frame->list, &fmt_port->rx_q);
+ spin_unlock(rx_q_lock);
+
+#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
+ atomic_inc(&fmt_port->enqueue_to_rxq);
+#endif
+}
+
+static struct fmt_frame_s *dequeue_fmt_frame(
+ struct fmt_port_s *fmt_port)
+{
+ struct fmt_frame_s *p_fmt_frame = NULL;
+ spinlock_t *rx_q_lock = NULL;
+
+ rx_q_lock = &fmt_port->rx_q_lock;
+
+ spin_lock(rx_q_lock);
+
+#define list_last_entry(ptr, type, member) list_entry((ptr)->prev, type, member)
+
+ if (!list_empty(&fmt_port->rx_q)) {
+ p_fmt_frame = list_last_entry(&fmt_port->rx_q,
+ struct fmt_frame_s,
+ list);
+ list_del(&p_fmt_frame->list);
+
+#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
+ atomic_inc(&fmt_port->dequeue_from_rxq);
+#endif
+ }
+
+ spin_unlock(rx_q_lock);
+
+ return p_fmt_frame;
+}
+
+/* eth-dev -to- fmt port association */
+struct fmt_port_s *match_dpa_to_fmt_port(
+ struct dpa_priv_s *dpa_priv) {
+ struct mac_device *mac_dev = dpa_priv->mac_dev;
+ struct fm_port *fm_port = (struct fm_port *) mac_dev;
+ struct fmt_port_s *fmt_port = NULL;
+ int i;
+
+ _fmt_dbgr("calling...\n");
+
+ /* find the FM-test-port object */
+ for (i = 0; i < IOC_FMT_MAX_NUM_OF_PORTS; i++)
+ if ((fm_test.ports[i].p_mac_dev &&
+ mac_dev == fm_test.ports[i].p_mac_dev) ||
+ fm_port == fm_test.ports[i].p_tx_port) {
+
+ fmt_port = &fm_test.ports[i];
+ break;
+ }
+
+ _fmt_dbgr("called\n");
+ return fmt_port;
+}
+
+void dump_frame(
+ uint8_t *buffer,
+ uint32_t size)
+{
+#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
+ unsigned int i;
+
+ for (i = 0; i < size; i++) {
+ if (i%16 == 0)
+ printk(KERN_DEBUG "\n");
+ printk(KERN_DEBUG "%2x ", *(buffer+i));
+ }
+#endif
+ return;
+}
+
+bool test_and_steal_frame(struct fmt_port_s *fmt_port,
+ uint32_t fqid,
+ uint8_t *buffer,
+ uint32_t size)
+{
+ struct fmt_frame_s *p_fmt_frame = NULL;
+ bool test_and_steal_frame_frame;
+ uint32_t data_offset;
+ uint32_t i;
+
+ _fmt_dbgr("calling...\n");
+
+ if (!fmt_port || !fmt_port->p_rx_fm_port_dev)
+ return false;
+
+ /* check watermark */
+ test_and_steal_frame_frame = false;
+ for (i = 0; i < size; i++) {
+ uint64_t temp = *((uint64_t *)(buffer + i));
+
+ if (temp == (uint64_t) FMT_FRM_WATERMARK) {
+ _fmt_dbgr("watermark found!\n");
+ test_and_steal_frame_frame = true;
+ break;
+ }
+ }
+
+ if (!test_and_steal_frame_frame) {
+#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
+ atomic_inc(&fmt_port->not_enqueue_to_rxq_wrong_frm);
+#endif
+ _fmt_dbgr("NOT watermark found!\n");
+ return false;
+ }
+
+ /* do not enqueue the tx conf/err frames */
+ if ((fqid == FMT_TX_CONF_Q) || (fqid == FMT_TX_ERR_Q))
+ goto _test_and_steal_frame_return_true;
+
+ _fmt_dbgr("on port %d got FMUC frame\n", fmt_port->id);
+ data_offset = FM_PORT_GetBufferDataOffset(
+ fmt_port->p_rx_fm_port_dev);
+
+ p_fmt_frame = kmalloc(sizeof(struct fmt_frame_s), GFP_KERNEL);
+
+ /* dump frame... no more space left on device */
+ if (p_fmt_frame == NULL) {
+ _fmt_err("no space left on device!\n");
+ goto _test_and_steal_frame_return_true;
+ }
+
+ memset(p_fmt_frame, 0, sizeof(struct fmt_frame_s));
+ p_fmt_frame->buff.p_data = kmalloc(size * sizeof(uint8_t), GFP_KERNEL);
+
+ /* No more space left on device*/
+ if (p_fmt_frame->buff.p_data == NULL) {
+ _fmt_err("no space left on device!\n");
+ kfree(p_fmt_frame);
+ goto _test_and_steal_frame_return_true;
+ }
+
+ p_fmt_frame->buff.size = size-data_offset;
+ p_fmt_frame->buff.qid = fqid;
+
+ memcpy(p_fmt_frame->buff.p_data,
+ (uint8_t *)PTR_MOVE(buffer, data_offset),
+ p_fmt_frame->buff.size);
+
+ memcpy(p_fmt_frame->buff.buff_context.fm_prs_res,
+ FM_PORT_GetBufferPrsResult(fmt_port->p_rx_fm_port_dev,
+ (char *)buffer),
+ 32);
+
+ /* enqueue frame - this frame will go to us */
+ enqueue_fmt_frame(fmt_port, p_fmt_frame);
+
+_test_and_steal_frame_return_true:
+ return true;
+}
+
+static int fmt_fq_release(const struct qm_fd *fd)
+{
+ struct dpa_bp *_dpa_bp;
+ struct bm_buffer _bmb;
+
+ if (fd->format == qm_fd_contig) {
+ _dpa_bp = dpa_bpid2pool(fd->bpid);
+ BUG_ON(IS_ERR(_dpa_bp));
+
+ _bmb.hi = fd->addr_hi;
+ _bmb.lo = fd->addr_lo;
+
+ while (bman_release(_dpa_bp->pool, &_bmb, 1, 0))
+ cpu_relax();
+
+ } else {
+ _fmt_err("frame not supported !\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/* sync it w/ dpaa_eth.c: DPA_BP_HEAD */
+#define DPA_BP_HEADROOM (DPA_TX_PRIV_DATA_SIZE + \
+ fm_get_rx_extra_headroom() + \
+ DPA_PARSE_RESULTS_SIZE + \
+ DPA_HASH_RESULTS_SIZE)
+#define MAC_HEADER_LENGTH 14
+#define L2_AND_HEADROOM_OFF ((DPA_BP_HEADROOM) + (MAC_HEADER_LENGTH))
+
+/* dpa ingress hooks definition */
+enum dpaa_eth_hook_result fmt_rx_default_hook(
+ struct sk_buff *skb,
+ struct net_device *net_dev,
+ u32 fqid)
+{
+ struct dpa_priv_s *dpa_priv = NULL;
+ struct fmt_port_s *fmt_port = NULL;
+ uint8_t *buffer;
+ uint32_t buffer_len;
+
+ _fmt_dbgr("calling...\n");
+
+ dpa_priv = netdev_priv(net_dev);
+ fmt_port = match_dpa_to_fmt_port(dpa_priv);
+
+ /* conversion from skb to fd:
+ * skb cames processed for L3, so we need to go back for
+ * layer 2 offset */
+ buffer = (uint8_t *)(skb->data - ((int)L2_AND_HEADROOM_OFF));
+ buffer_len = skb->len + ((int)L2_AND_HEADROOM_OFF);
+
+ /* if is not out frame let dpa to handle it */
+ if (test_and_steal_frame(fmt_port,
+ FMT_RX_DFLT_Q,
+ buffer,
+ buffer_len))
+ goto _fmt_rx_default_hook_stolen;
+
+ _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
+ return DPAA_ETH_CONTINUE;
+
+_fmt_rx_default_hook_stolen:
+ dev_kfree_skb(skb);
+
+ _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
+ return DPAA_ETH_STOLEN;
+}
+
+enum dpaa_eth_hook_result fmt_rx_error_hook(
+ struct net_device *net_dev,
+ const struct qm_fd *fd,
+ u32 fqid)
+{
+ struct dpa_priv_s *dpa_priv = NULL;
+ struct dpa_bp *dpa_bp = NULL;
+ struct fmt_port_s *fmt_port = NULL;
+ void *fd_virt_addr = NULL;
+ dma_addr_t addr = qm_fd_addr(fd);
+
+ _fmt_dbgr("calling...\n");
+
+ dpa_priv = netdev_priv(net_dev);
+ fmt_port = match_dpa_to_fmt_port(dpa_priv);
+
+ /* dpaa doesn't do this... we have to do it here */
+ dpa_bp = dpa_bpid2pool(fd->bpid);
+ dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
+
+ fd_virt_addr = phys_to_virt(addr);
+ /* if is not out frame let dpa to handle it */
+ if (test_and_steal_frame(fmt_port,
+ FMT_RX_ERR_Q,
+ fd_virt_addr,
+ fd->length20 + fd->offset)) {
+ goto _fmt_rx_error_hook_stolen;
+ }
+
+ _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
+ return DPAA_ETH_CONTINUE;
+
+_fmt_rx_error_hook_stolen:
+ /* the frame data doesn't matter,
+ * so, no mapping is needed */
+ fmt_fq_release(fd);
+
+ _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
+ return DPAA_ETH_STOLEN;
+}
+
+enum dpaa_eth_hook_result fmt_tx_confirm_hook(
+ struct net_device *net_dev,
+ const struct qm_fd *fd,
+ u32 fqid)
+{
+ struct dpa_priv_s *dpa_priv = NULL;
+ struct fmt_port_s *fmt_port = NULL;
+ dma_addr_t addr = qm_fd_addr(fd);
+ void *fd_virt_addr = NULL;
+ uint32_t fd_len = 0;
+
+ _fmt_dbgr("calling...\n");
+
+ dpa_priv = netdev_priv(net_dev);
+ fmt_port = match_dpa_to_fmt_port(dpa_priv);
+
+ fd_virt_addr = phys_to_virt(addr);
+ fd_len = fd->length20 + fd->offset;
+
+ if (fd_len > fm_get_max_frm()) {
+ _fmt_err("tx confirm bad frame size: %u!\n", fd_len);
+ goto _fmt_tx_confirm_hook_continue;
+ }
+
+ if (test_and_steal_frame(fmt_port,
+ FMT_TX_CONF_Q,
+ fd_virt_addr,
+ fd_len))
+ goto _fmt_tx_confirm_hook_stolen;
+
+_fmt_tx_confirm_hook_continue:
+ _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
+ return DPAA_ETH_CONTINUE;
+
+_fmt_tx_confirm_hook_stolen:
+ kfree(fd_virt_addr);
+
+ _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
+ return DPAA_ETH_STOLEN;
+}
+
+enum dpaa_eth_hook_result fmt_tx_confirm_error_hook(
+ struct net_device *net_dev,
+ const struct qm_fd *fd,
+ u32 fqid)
+{
+ struct dpa_priv_s *dpa_priv = NULL;
+ struct fmt_port_s *fmt_port = NULL;
+ dma_addr_t addr = qm_fd_addr(fd);
+ void *fd_virt_addr = NULL;
+ uint32_t fd_len = 0;
+
+ _fmt_dbgr("calling...\n");
+
+ dpa_priv = netdev_priv(net_dev);
+ fmt_port = match_dpa_to_fmt_port(dpa_priv);
+
+ fd_virt_addr = phys_to_virt(addr);
+ fd_len = fd->length20 + fd->offset;
+
+ if (fd_len > fm_get_max_frm()) {
+ _fmt_err("tx confirm err bad frame size: %u !\n", fd_len);
+ goto _priv_ingress_tx_err_continue;
+ }
+
+ if (test_and_steal_frame(fmt_port, FMT_TX_ERR_Q, fd_virt_addr, fd_len))
+ goto _priv_ingress_tx_err_stolen;
+
+_priv_ingress_tx_err_continue:
+ _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
+ return DPAA_ETH_CONTINUE;
+
+_priv_ingress_tx_err_stolen:
+ kfree(fd_virt_addr);
+
+ _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
+ return DPAA_ETH_STOLEN;
+}
+
+/* egress callbacks definition */
+enum qman_cb_dqrr_result fmt_egress_dqrr(
+ struct qman_portal *portal,
+ struct qman_fq *fq,
+ const struct qm_dqrr_entry *dqrr)
+{
+ /* this callback should never be called */
+ BUG();
+ return qman_cb_dqrr_consume;
+}
+
+static void fmt_egress_error_dqrr(
+ struct qman_portal *p,
+ struct qman_fq *fq,
+ const struct qm_mr_entry *msg)
+{
+ uint8_t *fd_virt_addr = NULL;
+
+ /* tx failure, on the ern callback - release buffer */
+ fd_virt_addr = (uint8_t *)phys_to_virt(qm_fd_addr(&msg->ern.fd));
+ kfree(fd_virt_addr);
+
+ return;
+}
+
+static const struct qman_fq fmt_egress_fq = {
+ .cb = { .dqrr = fmt_egress_dqrr,
+ .ern = fmt_egress_error_dqrr,
+ .fqs = NULL}
+};
+
+int fmt_fq_alloc(
+ struct fmt_fqs_s *fmt_fqs,
+ const struct qman_fq *qman_fq,
+ uint32_t fqid, uint32_t flags,
+ uint16_t channel, uint8_t wq)
+{
+ int _errno = 0;
+
+ _fmt_dbg("calling...\n");
+
+ fmt_fqs->fq_base = *qman_fq;
+
+ if (fqid == 0) {
+ flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
+ flags &= ~QMAN_FQ_FLAG_NO_MODIFY;
+ } else
+ flags &= ~QMAN_FQ_FLAG_DYNAMIC_FQID;
+
+ fmt_fqs->init = !(flags & QMAN_FQ_FLAG_NO_MODIFY);
+
+ _errno = qman_create_fq(fqid, flags, &fmt_fqs->fq_base);
+ if (_errno < 0) {
+ _fmt_err("frame queues create failed.\n");
+ return -EINVAL;
+ }
+
+ if (fmt_fqs->init) {
+ struct qm_mcc_initfq initfq;
+
+ initfq.we_mask = QM_INITFQ_WE_DESTWQ;
+ initfq.fqd.dest.channel = channel;
+ initfq.fqd.dest.wq = wq;
+
+ _errno = qman_init_fq(&fmt_fqs->fq_base,
+ QMAN_INITFQ_FLAG_SCHED,
+ &initfq);
+ if (_errno < 0) {
+ _fmt_err("frame queues init erorr.\n");
+ qman_destroy_fq(&fmt_fqs->fq_base, 0);
+ return -EINVAL;
+ }
+ }
+
+ _fmt_dbg("called.\n");
+ return 0;
+}
+
+static int fmt_fq_free(struct fmt_fqs_s *fmt_fq)
+{
+ int _err = 0;
+
+ _fmt_dbg("calling...\n");
+
+ if (fmt_fq->init) {
+ _err = qman_retire_fq(&fmt_fq->fq_base, NULL);
+ if (unlikely(_err < 0))
+ _fmt_err("qman_retire_fq(%u) = %d\n",
+ qman_fq_fqid(&fmt_fq->fq_base), _err);
+
+ _err = qman_oos_fq(&fmt_fq->fq_base);
+ if (unlikely(_err < 0))
+ _fmt_err("qman_oos_fq(%u) = %d\n",
+ qman_fq_fqid(&fmt_fq->fq_base), _err);
+ }
+
+ qman_destroy_fq(&fmt_fq->fq_base, 0);
+
+ _fmt_dbg("called.\n");
+ return _err;
+}
+
+/* private pcd dqrr calbacks */
+static enum qman_cb_dqrr_result fmt_pcd_dqrr(
+ struct qman_portal *portal,
+ struct qman_fq *fq,
+ const struct qm_dqrr_entry *dq)
+{
+ struct dpa_bp *dpa_bp = NULL;
+ dma_addr_t addr = qm_fd_addr(&dq->fd);
+ uint8_t *fd_virt_addr = NULL;
+ struct fmt_port_s *fmt_port;
+ struct fmt_port_pcd_s *fmt_port_pcd;
+ uint32_t relative_fqid = 0;
+ uint32_t fd_len = 0;
+
+ _fmt_dbgr("calling...\n");
+
+ /* upcast - from pcd_alloc_fq */
+ fmt_port = ((struct fmt_fqs_s *)fq)->fmt_port_priv;
+ if (!fmt_port) {
+ _fmt_err(" wrong fmt port -to- fq match.\n");
+ goto _fmt_pcd_dqrr_return;
+ }
+ fmt_port_pcd = &fmt_port->fmt_port_pcd;
+
+ relative_fqid = dq->fqid - fmt_port_pcd->fqid_base;
+ _fmt_dbgr("pcd dqrr got frame on relative fq:%u@base:%u\n",
+ relative_fqid, fmt_port_pcd->fqid_base);
+
+ fd_len = dq->fd.length20 + dq->fd.offset;
+
+ if (fd_len > fm_get_max_frm()) {
+ _fmt_err("pcd dqrr wrong frame size: %u (%u:%u)!\n",
+ fd_len, dq->fd.length20, dq->fd.offset);
+ goto _fmt_pcd_dqrr_return;
+ }
+
+ dpa_bp = dpa_bpid2pool(dq->fd.bpid);
+ dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
+
+ fd_virt_addr = phys_to_virt(addr);
+ if (!test_and_steal_frame(fmt_port, relative_fqid, fd_virt_addr,
+ fd_len)) {
+
+#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
+ atomic_inc(&fmt_port->not_enqueue_to_rxq_wrong_frm);
+#endif
+ _fmt_wrn("pcd dqrr unrecognized frame@fqid: %u,"
+ " frame len: %u (dropped).\n",
+ dq->fqid, dq->fd.length20);
+ dump_frame(fd_virt_addr, fd_len);
+ }
+
+_fmt_pcd_dqrr_return:
+ /* no need to map again here */
+ fmt_fq_release(&dq->fd);
+
+ _fmt_dbgr("calle.\n");
+ return qman_cb_dqrr_consume;
+}
+
+static void fmt_pcd_err_dqrr(
+ struct qman_portal *qm,
+ struct qman_fq *fq,
+ const struct qm_mr_entry *msg)
+{
+ _fmt_err("this callback should never be called.\n");
+ BUG();
+ return;
+}
+
+static void fmt_pcd_fqs_dqrr(
+ struct qman_portal *qm,
+ struct qman_fq *fq,
+ const struct qm_mr_entry *msg)
+{
+ _fmt_dbg(" fq state(0x%x)@fqid(%u.\n", msg->fq.fqs, msg->fq.fqid);
+ return;
+}
+
+/* private pcd queue template */
+static const struct qman_fq pcd_fq = {
+ .cb = { .dqrr = fmt_pcd_dqrr,
+ .ern = fmt_pcd_err_dqrr,
+ .fqs = fmt_pcd_fqs_dqrr}
+};
+
+/* defined as weak in dpaa driver. */
+/* ! parameters come from IOCTL call - US */
+int dpa_alloc_pcd_fqids(
+ struct device *dev,
+ uint32_t num, uint8_t alignment,
+ uint32_t *base_fqid)
+{
+ int _err = 0, i;
+ struct net_device *net_dev = NULL;
+ struct dpa_priv_s *dpa_priv = NULL;
+ struct fmt_port_pcd_s *fmt_port_pcd = NULL;
+ struct fmt_fqs_s *fmt_fqs = NULL;
+ struct fmt_port_s *fmt_port = NULL;
+ int num_allocated = 0;
+
+ _fmt_dbg("calling...\n");
+
+ net_dev = (typeof(net_dev))dev_get_drvdata(dev);
+ dpa_priv = (typeof(dpa_priv))netdev_priv(net_dev);
+
+ if (!netif_msg_probe(dpa_priv)) {
+ _fmt_err("dpa not probe.\n");
+ _err = -ENODEV;
+ goto _pcd_alloc_fqs_err;
+ }
+
+ fmt_port = match_dpa_to_fmt_port(dpa_priv);
+ if (!fmt_port) {
+ _fmt_err("fmt port not found.");
+ _err = -EINVAL;
+ goto _pcd_alloc_fqs_err;
+ }
+
+ fmt_port_pcd = &fmt_port->fmt_port_pcd;
+
+ num_allocated = qman_alloc_fqid_range(base_fqid, num, alignment, 0);
+
+ if ((num_allocated <= 0) ||
+ (num_allocated < num) ||
+ (alignment && (*base_fqid) % alignment)) {
+ *base_fqid = 0;
+ _fmt_err("Failed to alloc pcd fqs rang.\n");
+ _err = -EINVAL;
+ goto _pcd_alloc_fqs_err;
+ }
+
+ _fmt_dbg("wanted %d fqs(align %d), got %d fqids@%u.\n",
+ num, alignment, num_allocated, *base_fqid);
+
+ /* alloc pcd queues */
+ fmt_port_pcd->fmt_pcd_fqs = kmalloc(num_allocated *
+ sizeof(struct fmt_fqs_s),
+ GFP_KERNEL);
+ fmt_port_pcd->num_queues = num_allocated;
+ fmt_port_pcd->fqid_base = *base_fqid;
+ fmt_fqs = fmt_port_pcd->fmt_pcd_fqs;
+
+ /* alloc the pcd queues */
+ for (i = 0; i < num_allocated; i++, fmt_fqs++) {
+ _err = fmt_fq_alloc(
+ fmt_fqs,
+ &pcd_fq,
+ (*base_fqid) + i, QMAN_FQ_FLAG_NO_ENQUEUE,
+ dpa_priv->channel, 7);
+
+ if (_err < 0)
+ goto _pcd_alloc_fqs_err;
+
+ /* upcast to identify from where the frames came from */
+ fmt_fqs->fmt_port_priv = fmt_port;
+ }
+
+ _fmt_dbg("called.\n");
+ return _err;
+_pcd_alloc_fqs_err:
+ if (num_allocated > 0)
+ qman_release_fqid_range(*base_fqid, num_allocated);
+ /*TODO: free fmt_pcd_fqs if are any */
+
+ _fmt_dbg("called(_err:%d).\n", _err);
+ return _err;
+}
+
+/* defined as weak in dpaa driver. */
+int dpa_free_pcd_fqids(
+ struct device *dev,
+ uint32_t base_fqid)
+{
+
+ int _err = 0, i;
+ struct net_device *net_dev = NULL;
+ struct dpa_priv_s *dpa_priv = NULL;
+ struct fmt_port_pcd_s *fmt_port_pcd = NULL;
+ struct fmt_fqs_s *fmt_fqs = NULL;
+ struct fmt_port_s *fmt_port = NULL;
+ int num_allocated = 0;
+
+ _fmt_dbg("calling...\n");
+
+ net_dev = (typeof(net_dev))dev_get_drvdata(dev);
+ dpa_priv = (typeof(dpa_priv))netdev_priv(net_dev);
+
+ if (!netif_msg_probe(dpa_priv)) {
+ _fmt_err("dpa not probe.\n");
+ _err = -ENODEV;
+ goto _pcd_free_fqs_err;
+ }
+
+ fmt_port = match_dpa_to_fmt_port(dpa_priv);
+ if (!fmt_port) {
+ _fmt_err("fmt port not found.");
+ _err = -EINVAL;
+ goto _pcd_free_fqs_err;
+ }
+
+ fmt_port_pcd = &fmt_port->fmt_port_pcd;
+ num_allocated = fmt_port_pcd->num_queues;
+ fmt_fqs = fmt_port_pcd->fmt_pcd_fqs;
+
+ for (i = 0; i < num_allocated; i++, fmt_fqs++)
+ fmt_fq_free(fmt_fqs);
+
+ qman_release_fqid_range(base_fqid,num_allocated);
+
+ kfree(fmt_port_pcd->fmt_pcd_fqs);
+ memset(fmt_port_pcd, 0, sizeof(*fmt_port_pcd));
+
+ /* debugging stuff */
+#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
+ _fmt_dbg(" portid: %u.\n", fmt_port->id);
+ _fmt_dbg(" frames enqueue to qman: %u.\n",
+ atomic_read(&fmt_port->enqueue_to_qman_frm));
+ _fmt_dbg(" frames enqueue to rxq: %u.\n",
+ atomic_read(&fmt_port->enqueue_to_rxq));
+ _fmt_dbg(" frames dequeue from rxq: %u.\n",
+ atomic_read(&fmt_port->dequeue_from_rxq));
+ _fmt_dbg(" frames not enqueue to rxq - wrong frm: %u.\n",
+ atomic_read(&fmt_port->not_enqueue_to_rxq_wrong_frm));
+ atomic_set(&fmt_port->enqueue_to_qman_frm, 0);
+ atomic_set(&fmt_port->enqueue_to_rxq, 0);
+ atomic_set(&fmt_port->dequeue_from_rxq, 0);
+ atomic_set(&fmt_port->not_enqueue_to_rxq_wrong_frm, 0);
+#endif
+ return 0;
+
+_pcd_free_fqs_err:
+ return _err;
+}
+
+static int fmt_port_init(
+ struct fmt_port_s *fmt_port,
+ ioc_fmt_port_param_t *p_Params)
+{
+ struct device_node *fm_node, *fm_port_node;
+ const uint32_t *uint32_prop;
+ int _errno = 0, lenp = 0, i;
+ static struct of_device_id fm_node_of_match[] = {
+ { .compatible = "fsl,fman", },
+ { /* end of list */ },
+ };
+
+ _fmt_dbg("calling...\n");
+
+ /* init send/receive tu US list */
+ INIT_LIST_HEAD(&fmt_port->rx_q);
+
+ /* check parameters */
+ if (p_Params->num_tx_queues > FMAN_TEST_MAX_TX_FQS ||
+ p_Params->fm_port_id > IOC_FMT_MAX_NUM_OF_PORTS) {
+ _fmt_dbg("wrong test parameters.\n");
+ return -EINVAL;
+ }
+
+ /* set port parameters */
+ fmt_port->num_of_tx_fqs = p_Params->num_tx_queues;
+ fmt_port->id = p_Params->fm_port_id;
+ fmt_port->port_type = p_Params->fm_port_type;
+ fmt_port->diag = e_IOC_DIAG_MODE_NONE;
+
+ /* init debugging stuff */
+#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
+ atomic_set(&fmt_port->enqueue_to_qman_frm, 0);
+ atomic_set(&fmt_port->enqueue_to_rxq, 0);
+ atomic_set(&fmt_port->dequeue_from_rxq, 0);
+ atomic_set(&fmt_port->not_enqueue_to_rxq_wrong_frm, 0);
+#endif
+
+ /* TODO: This should be done at probe time not at runtime
+ * very ugly function */
+ /* fill fmt port properties from dts */
+ for_each_matching_node(fm_node, fm_node_of_match) {
+
+ uint32_prop = (uint32_t *)of_get_property(fm_node,
+ "cell-index", &lenp);
+ if (unlikely(uint32_prop == NULL)) {
+ _fmt_wrn("of_get_property(%s, cell-index) invalid",
+ fm_node->full_name);
+ return -EINVAL;
+ }
+ if (WARN_ON(lenp != sizeof(uint32_t))) {
+ _fmt_wrn("of_get_property(%s, cell-index) invalid",
+ fm_node->full_name);
+ return -EINVAL;
+ }
+
+ if (*uint32_prop == p_Params->fm_id) {
+ struct resource res;
+
+ /* Get the FM address */
+ _errno = of_address_to_resource(fm_node, 0, &res);
+ if (unlikely(_errno < 0)) {
+ _fmt_wrn("of_address_to_resource() = %u.\n", _errno);
+ return -EINVAL;
+ }
+
+ fmt_port->fm_phys_base_addr = res.start;
+
+ for_each_child_of_node(fm_node, fm_port_node) {
+ struct platform_device *of_dev;
+
+ if (!of_device_is_available(fm_port_node))
+ continue;
+
+ uint32_prop = (uint32_t *)of_get_property(
+ fm_port_node,
+ "cell-index",
+ &lenp);
+ if (uint32_prop == NULL)
+ continue;
+
+ if (of_device_is_compatible(fm_port_node,
+ "fsl,fman-port-oh") &&
+ (fmt_port->port_type == e_IOC_FMT_PORT_T_OP)) {
+
+ if (*uint32_prop == fmt_port->id) {
+ of_dev = of_find_device_by_node(fm_port_node);
+ if (unlikely(of_dev == NULL)) {
+ _fmt_wrn("fm id invalid\n");
+ return -EINVAL;
+ }
+
+ fmt_port->p_tx_port =
+ fm_port_bind(&of_dev->dev);
+ fmt_port->p_tx_fm_port_dev =
+ (void *)fm_port_get_handle(
+ fmt_port->p_tx_port);
+ fmt_port->p_rx_port =
+ fmt_port->p_tx_port;
+ fmt_port->p_rx_fm_port_dev =
+ fmt_port->p_tx_fm_port_dev;
+ fmt_port->p_mac_dev = NULL;
+ break;
+ }
+ } else if ((*uint32_prop == fmt_port->id) &&
+ fmt_port->port_type == e_IOC_FMT_PORT_T_RXTX) {
+
+ of_dev = of_find_device_by_node(fm_port_node);
+ if (unlikely(of_dev == NULL)) {
+ _fmt_wrn("dtb fm id invalid value");
+ return -EINVAL;
+ }
+
+ if (of_device_is_compatible(fm_port_node,
+ "fsl,fman-port-1g-tx")) {
+ fmt_port->p_tx_port =
+ fm_port_bind(&of_dev->dev);
+ fmt_port->p_tx_fm_port_dev = (void *)
+ fm_port_get_handle(
+ fmt_port->p_tx_port);
+ } else if (of_device_is_compatible(fm_port_node,
+ "fsl,fman-port-1g-rx")) {
+ fmt_port->p_rx_port =
+ fm_port_bind(&of_dev->dev);
+ fmt_port->p_rx_fm_port_dev = (void *)
+ fm_port_get_handle(
+ fmt_port->p_rx_port);
+ } else if (of_device_is_compatible(fm_port_node,
+ "fsl,fman-1g-mac") ||
+ of_device_is_compatible(fm_port_node,
+ "fsl,fman-memac"))
+ fmt_port->p_mac_dev =
+ (typeof(fmt_port->p_mac_dev))
+ dev_get_drvdata(&of_dev->dev);
+ else
+ continue;
+
+ if (fmt_port->p_tx_fm_port_dev &&
+ fmt_port->p_rx_fm_port_dev && fmt_port->p_mac_dev)
+ break;
+ } else if (((*uint32_prop + FM_MAX_NUM_OF_1G_RX_PORTS) ==
+ fmt_port->id) &&
+ fmt_port->port_type == e_IOC_FMT_PORT_T_RXTX) {
+
+ of_dev = of_find_device_by_node(fm_port_node);
+ if (unlikely(of_dev == NULL)) {
+ _fmt_wrn("dtb fm id invalid value\n");
+ return -EINVAL;
+ }
+
+ if (of_device_is_compatible(fm_port_node,
+ "fsl,fman-port-10g-tx")) {
+ fmt_port->p_tx_port =
+ fm_port_bind(&of_dev->dev);
+ fmt_port->p_tx_fm_port_dev = (void *)
+ fm_port_get_handle(
+ fmt_port->p_tx_port);
+ } else if (of_device_is_compatible(fm_port_node,
+ "fsl,fman-port-10g-rx")) {
+ fmt_port->p_rx_port =
+ fm_port_bind(&of_dev->dev);
+ fmt_port->p_rx_fm_port_dev = (void *)
+ fm_port_get_handle(
+ fmt_port->p_rx_port);
+ } else if (of_device_is_compatible(fm_port_node,
+ "fsl,fman-10g-mac") ||
+ of_device_is_compatible(fm_port_node,
+ "fsl,fman-memac"))
+ fmt_port->p_mac_dev =
+ (typeof(fmt_port->p_mac_dev))
+ dev_get_drvdata(&of_dev->dev);
+ else
+ continue;
+
+ if (fmt_port->p_tx_fm_port_dev &&
+ fmt_port->p_rx_fm_port_dev && fmt_port->p_mac_dev)
+ break;
+ }
+ } /* for_each_child */
+ }
+ } /* for each matching node */
+
+ if (fmt_port->p_tx_fm_port_dev == 0 ||
+ fmt_port->p_rx_fm_port_dev == 0) {
+
+ _fmt_err("bad fm port pointers.\n");
+ return -EINVAL;
+ }
+
+ _fmt_dbg("alloc %u tx queues.\n", fmt_port->num_of_tx_fqs);
+
+ /* init fman test egress dynamic frame queues */
+ for (i = 0; i < fmt_port->num_of_tx_fqs; i++) {
+ int _errno;
+ _errno = fmt_fq_alloc(
+ &fmt_port->p_tx_fqs[i],
+ &fmt_egress_fq,
+ 0,
+ QMAN_FQ_FLAG_TO_DCPORTAL,
+ fm_get_tx_port_channel(fmt_port->p_tx_port),
+ i);
+
+ if (_errno < 0) {
+ _fmt_err("tx queues allocation failed.\n");
+ /* TODO: memory leak here if 1 queue is allocated and
+ * next queues are failing ... */
+ return -EINVAL;
+ }
+ }
+
+ /* port is valid and ready to use. */
+ fmt_port->valid = TRUE;
+
+ _fmt_dbg("called.\n");
+ return 0;
+}
+
+/* fm test chardev functions */
+static int fmt_open(struct inode *inode, struct file *file)
+{
+ unsigned int minor = iminor(inode);
+
+ _fmt_dbg("calling...\n");
+
+ if (file->private_data != NULL)
+ return 0;
+
+ /* The minor represent the port number.
+ * Set the port structure accordingly, thus all the operations
+ * will be done on this port. */
+ if ((minor >= DEV_FM_TEST_PORTS_MINOR_BASE) &&
+ (minor < DEV_FM_TEST_MAX_MINORS))
+ file->private_data = &fm_test.ports[minor];
+ else
+ return -ENXIO;
+
+ _fmt_dbg("called.\n");
+ return 0;
+}
+
+static int fmt_close(struct inode *inode, struct file *file)
+{
+ struct fmt_port_s *fmt_port = NULL;
+ struct fmt_frame_s *fmt_frame = NULL;
+
+ int err = 0;
+
+ _fmt_dbg("calling...\n");
+
+ fmt_port = file->private_data;
+ if (!fmt_port)
+ return -ENODEV;
+
+ /* Close the current test port by invalidating it. */
+ fmt_port->valid = FALSE;
+
+ /* clean the fmt port queue */
+ while ((fmt_frame = dequeue_fmt_frame(fmt_port)) != NULL) {
+ if (fmt_frame && fmt_frame->buff.p_data){
+ kfree(fmt_frame->buff.p_data);
+ kfree(fmt_frame);
+ }
+ }
+
+ /* !!! the qman queues are cleaning from fm_ioctl...
+ * - very ugly */
+
+ _fmt_dbg("called.\n");
+ return err;
+}
+
+static int fmt_ioctls(unsigned int minor,
+ struct file *file,
+ unsigned int cmd,
+ unsigned long arg,
+ bool compat)
+{
+ struct fmt_port_s *fmt_port = NULL;
+
+ _fmt_dbg("IOCTL minor:%u "
+ " arg:0x%08lx ioctl cmd (0x%08x):(0x%02x:0x%02x.\n",
+ minor, arg, cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
+
+ fmt_port = file->private_data;
+ if (!fmt_port) {
+ _fmt_err("invalid fmt port.\n");
+ return -ENODEV;
+ }
+
+ /* set test type properly */
+ if (compat)
+ fmt_port->compat_test_type = true;
+ else
+ fmt_port->compat_test_type = false;
+
+ switch (cmd) {
+ case FMT_PORT_IOC_INIT:
+ {
+ ioc_fmt_port_param_t param;
+
+ if (fmt_port->valid) {
+ _fmt_wrn("port is already initialized.\n");
+ return -EFAULT;
+ }
+#if defined(CONFIG_COMPAT)
+ if (compat) {
+ if (copy_from_user(&param,
+ (ioc_fmt_port_param_t *)compat_ptr(arg),
+ sizeof(ioc_fmt_port_param_t)))
+
+ return -EFAULT;
+ } else
+#endif
+ {
+ if (copy_from_user(&param,
+ (ioc_fmt_port_param_t *) arg,
+ sizeof(ioc_fmt_port_param_t)))
+
+ return -EFAULT;
+ }
+
+ return fmt_port_init(fmt_port, &param);
+ }
+
+ case FMT_PORT_IOC_SET_DIAG_MODE:
+ if (get_user(fmt_port->diag, (ioc_diag_mode *)arg))
+ return -EFAULT;
+
+ if (fmt_port->diag == e_IOC_DIAG_MODE_CTRL_LOOPBACK)
+ return set_mac_int_loopback(fmt_port, TRUE);
+ else
+ return set_mac_int_loopback(fmt_port, FALSE);
+ break;
+
+ case FMT_PORT_IOC_SET_DPAECHO_MODE:
+ case FMT_PORT_IOC_SET_IP_HEADER_MANIP:
+ default:
+ _fmt_wrn("ioctl unimplemented minor:%u@ioctl"
+ " cmd:0x%08x(type:0x%02x, nr:0x%02x.\n",
+ minor, cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_COMPAT
+static long fmt_compat_ioctl(
+ struct file *file,
+ unsigned int cmd,
+ unsigned long arg)
+{
+ unsigned int minor = iminor(file->f_path.dentry->d_inode);
+
+ _fmt_dbg("calling...\n");
+ return fmt_ioctls(minor, file, cmd, arg, true);
+}
+#endif
+
+static long fmt_ioctl(
+ struct file *file,
+ unsigned int cmd,
+ unsigned long arg)
+{
+ unsigned int minor = iminor(file->f_path.dentry->d_inode);
+ unsigned int res;
+
+ _fmt_dbg("calling...\n");
+
+ fm_mutex_lock();
+ res = fmt_ioctls(minor, file, cmd, arg, false);
+ fm_mutex_unlock();
+
+ _fmt_dbg("called.\n");
+
+ return res;
+}
+
+#ifdef CONFIG_COMPAT
+void copy_compat_test_frame_buffer(
+ ioc_fmt_buff_desc_t *buff,
+ ioc_fmt_compat_buff_desc_t *compat_buff)
+{
+ compat_buff->qid = buff->qid;
+ compat_buff->p_data = ptr_to_compat(buff->p_data);
+ compat_buff->size = buff->size;
+ compat_buff->status = buff->status;
+
+ compat_buff->buff_context.p_user_priv =
+ ptr_to_compat(buff->buff_context.p_user_priv);
+ memcpy(compat_buff->buff_context.fm_prs_res,
+ buff->buff_context.fm_prs_res,
+ FM_PRS_MAX * sizeof(uint8_t));
+ memcpy(compat_buff->buff_context.fm_time_stamp,
+ buff->buff_context.fm_time_stamp,
+ FM_TIME_STAMP_MAX * sizeof(uint8_t));
+}
+#endif
+
+ssize_t fmt_read(
+ struct file *file,
+ char __user *buf,
+ size_t size,
+ loff_t *ppos)
+{
+ struct fmt_port_s *fmt_port = NULL;
+ struct fmt_frame_s *p_fmt_frame = NULL;
+ ssize_t cnt = 0;
+
+ fmt_port = file->private_data;
+ if (!fmt_port || !fmt_port->valid) {
+ _fmt_err("fmt port not valid!\n");
+ return -ENODEV;
+ }
+
+ p_fmt_frame = dequeue_fmt_frame(fmt_port);
+ if (p_fmt_frame == NULL)
+ return 0;
+
+ _fmt_dbgr("calling...\n");
+
+#ifdef CONFIG_COMPAT
+ if (fmt_port->compat_test_type){
+ cnt = sizeof(ioc_fmt_compat_buff_desc_t);
+ }
+ else
+#endif
+ {
+ cnt = sizeof(ioc_fmt_buff_desc_t);
+ }
+
+ if (size < cnt) {
+ _fmt_err("illegal buffer-size!\n");
+ cnt = 0;
+ goto _fmt_read_return;
+ }
+
+ /* Copy structure */
+#ifdef CONFIG_COMPAT
+ if (fmt_port->compat_test_type) {
+ {
+ ioc_fmt_compat_buff_desc_t compat_buff;
+ copy_compat_test_frame_buffer(&p_fmt_frame->buff,
+ &compat_buff);
+
+ if (copy_to_user(buf, &compat_buff, cnt)) {
+ _fmt_err("copy_to_user failed!\n");
+ goto _fmt_read_return;
+ }
+ }
+
+ ((ioc_fmt_compat_buff_desc_t *)buf)->p_data =
+ ptr_to_compat(buf+sizeof(ioc_fmt_compat_buff_desc_t));
+ cnt += MIN(p_fmt_frame->buff.size, size-cnt);
+ } else
+#endif
+ {
+ if (copy_to_user(buf, &p_fmt_frame->buff, cnt)) {
+ _fmt_err("copy_to_user failed!\n");
+ goto _fmt_read_return;
+ }
+
+ ((ioc_fmt_buff_desc_t *)buf)->p_data =
+ buf + sizeof(ioc_fmt_buff_desc_t);
+ cnt += MIN(p_fmt_frame->buff.size, size-cnt);
+ }
+
+ if (size < cnt) {
+ _fmt_err("illegal buffer-size!\n");
+ goto _fmt_read_return;
+ }
+
+ /* copy frame */
+#ifdef CONFIG_COMPAT
+ if (fmt_port->compat_test_type) {
+ if (copy_to_user(buf+sizeof(ioc_fmt_compat_buff_desc_t),
+ p_fmt_frame->buff.p_data, cnt)) {
+ _fmt_err("copy_to_user failed!\n");
+ goto _fmt_read_return;
+ }
+ } else
+#endif
+ {
+ if (copy_to_user(buf+sizeof(ioc_fmt_buff_desc_t),
+ p_fmt_frame->buff.p_data, cnt)) {
+ _fmt_err("copy_to_user failed!\n");
+ goto _fmt_read_return;
+ }
+ }
+
+_fmt_read_return:
+ kfree(p_fmt_frame->buff.p_data);
+ kfree(p_fmt_frame);
+
+ _fmt_dbgr("called.\n");
+ return cnt;
+}
+
+ssize_t fmt_write(
+ struct file *file,
+ const char __user *buf,
+ size_t size,
+ loff_t *ppos)
+{
+ struct fmt_port_s *fmt_port = NULL;
+ ioc_fmt_buff_desc_t buff_desc;
+#ifdef CONFIG_COMPAT
+ ioc_fmt_compat_buff_desc_t buff_desc_compat;
+#endif
+ uint8_t *p_data = NULL;
+ uint32_t data_offset;
+ int _errno;
+ t_DpaaFD fd;
+
+ _fmt_dbgr("calling...\n");
+
+ fmt_port = file->private_data;
+ if (!fmt_port || !fmt_port->valid) {
+ _fmt_err("fmt port not valid.\n");
+ return -EINVAL;
+ }
+
+ /* If Compat (32B UserSpace - 64B KernelSpace) */
+#ifdef CONFIG_COMPAT
+ if (fmt_port->compat_test_type) {
+ if (size < sizeof(ioc_fmt_compat_buff_desc_t)) {
+ _fmt_err("invalid buff_desc size.\n");
+ return -EFAULT;
+ }
+
+ if (copy_from_user(&buff_desc_compat, buf,
+ sizeof(ioc_fmt_compat_buff_desc_t)))
+ return -EFAULT;
+
+ buff_desc.qid = buff_desc_compat.qid;
+ buff_desc.p_data = compat_ptr(buff_desc_compat.p_data);
+ buff_desc.size = buff_desc_compat.size;
+ buff_desc.status = buff_desc_compat.status;
+
+ buff_desc.buff_context.p_user_priv =
+ compat_ptr(buff_desc_compat.buff_context.p_user_priv);
+ memcpy(buff_desc.buff_context.fm_prs_res,
+ buff_desc_compat.buff_context.fm_prs_res,
+ FM_PRS_MAX * sizeof(uint8_t));
+ memcpy(buff_desc.buff_context.fm_time_stamp,
+ buff_desc_compat.buff_context.fm_time_stamp,
+ FM_TIME_STAMP_MAX * sizeof(uint8_t));
+ } else
+#endif
+ {
+ if (size < sizeof(ioc_fmt_buff_desc_t)) {
+ _fmt_err("invalid buff_desc size.\n");
+ return -EFAULT;
+ }
+
+ if (copy_from_user(&buff_desc, (ioc_fmt_buff_desc_t *)buf,
+ sizeof(ioc_fmt_buff_desc_t)))
+ return -EFAULT;
+ }
+
+ data_offset = FM_PORT_GetBufferDataOffset(fmt_port->p_tx_fm_port_dev);
+ p_data = kmalloc(buff_desc.size+data_offset, GFP_KERNEL);
+ if (!p_data)
+ return -ENOMEM;
+
+ /* If Compat (32UserSpace - 64KernelSpace) the buff_desc.p_data is ok */
+ if (copy_from_user((uint8_t *)PTR_MOVE(p_data, data_offset),
+ buff_desc.p_data,
+ buff_desc.size)) {
+ kfree(p_data);
+ return -EFAULT;
+ }
+
+ /* TODO: dma_map_single here (cannot access the bpool struct) */
+
+ /* prepare fd */
+ memset(&fd, 0, sizeof(fd));
+ DPAA_FD_SET_ADDR(&fd, p_data);
+ DPAA_FD_SET_OFFSET(&fd, data_offset);
+ DPAA_FD_SET_LENGTH(&fd, buff_desc.size);
+
+ _errno = qman_enqueue(&fmt_port->p_tx_fqs[buff_desc.qid].fq_base,
+ (struct qm_fd *)&fd, 0);
+ if (_errno) {
+ buff_desc.status = (uint32_t)_errno;
+ if (copy_to_user((ioc_fmt_buff_desc_t *)buf, &buff_desc,
+ sizeof(ioc_fmt_buff_desc_t))) {
+ kfree(p_data);
+ return -EFAULT;
+ }
+ }
+
+ /* for debugging */
+#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
+ atomic_inc(&fmt_port->enqueue_to_qman_frm);
+#endif
+ _fmt_dbgr("called.\n");
+ return buff_desc.size;
+}
+
+/* fm test character device definition */
+static const struct file_operations fmt_fops =
+{
+ .owner = THIS_MODULE,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = fmt_compat_ioctl,
+#endif
+ .unlocked_ioctl = fmt_ioctl,
+ .open = fmt_open,
+ .release = fmt_close,
+ .read = fmt_read,
+ .write = fmt_write,
+};
+
+static int fmt_init(void)
+{
+ int id;
+
+ _fmt_dbg("calling...\n");
+
+ /* Register to the /dev for IOCTL API */
+ /* Register dynamically a new major number for the character device: */
+ fm_test.major = register_chrdev(0, DEV_FM_TEST_NAME, &fmt_fops);
+ if (fm_test.major <= 0) {
+ _fmt_wrn("Failed to allocate major number for device %s.\n",
+ DEV_FM_TEST_NAME);
+ return -ENODEV;
+ }
+
+ /* Creating class for FMan_test */
+ fm_test.fmt_class = class_create(THIS_MODULE, DEV_FM_TEST_NAME);
+ if (IS_ERR(fm_test.fmt_class)) {
+ unregister_chrdev(fm_test.major, DEV_FM_TEST_NAME);
+ _fmt_wrn("Error creating %s class.\n", DEV_FM_TEST_NAME);
+ return -ENODEV;
+ }
+
+ for (id = 0; id < IOC_FMT_MAX_NUM_OF_PORTS; id++)
+ if (NULL == device_create(fm_test.fmt_class, NULL,
+ MKDEV(fm_test.major,
+ DEV_FM_TEST_PORTS_MINOR_BASE + id), NULL,
+ DEV_FM_TEST_NAME "%d", id)) {
+
+ _fmt_err("Error creating %s device.\n",
+ DEV_FM_TEST_NAME);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static void fmt_free(void)
+{
+ int id;
+
+ for (id = 0; id < IOC_FMT_MAX_NUM_OF_PORTS; id++)
+ device_destroy(fm_test.fmt_class, MKDEV(fm_test.major,
+ DEV_FM_TEST_PORTS_MINOR_BASE + id));
+ class_destroy(fm_test.fmt_class);
+}
+
+static int __init __cold fmt_load(void)
+{
+ struct dpaa_eth_hooks_s priv_dpaa_eth_hooks;
+
+ /* set dpaa hooks for default queues */
+ memset(&priv_dpaa_eth_hooks, 0, sizeof(priv_dpaa_eth_hooks));
+ priv_dpaa_eth_hooks.rx_default = fmt_rx_default_hook;
+ priv_dpaa_eth_hooks.rx_error = fmt_rx_error_hook;
+ priv_dpaa_eth_hooks.tx_confirm = fmt_tx_confirm_hook;
+ priv_dpaa_eth_hooks.tx_error = fmt_tx_confirm_error_hook;
+
+ fsl_dpaa_eth_set_hooks(&priv_dpaa_eth_hooks);
+
+ /* initialize the fman test environment */
+ if (fmt_init() < 0) {
+ _fmt_err("Failed to init FM-test modul.\n");
+ fmt_free();
+ return -ENODEV;
+ }
+
+ _fmt_inf("FSL FM test module loaded.\n");
+
+ return 0;
+}
+
+static void __exit __cold fmt_unload(void)
+{
+ fmt_free();
+ _fmt_inf("FSL FM test module unloaded.\n");
+}
+
+module_init(fmt_load);
+module_exit(fmt_unload);
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 000000000000..3fa99df195ac
--- /dev/null
+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c
@@ -0,0 +1,2939 @@
+/*
+ * Copyright 2008-2012 Freescale Semiconductor Inc.
+ * Copyright 2019 NXP
+ *
+ * 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>
+#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;
+
+#ifdef FM_ERRATUM_A050385
+static bool fm_has_err_a050385;
+#endif
+
+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);
+
+#ifdef FM_ERRATUM_A050385
+bool fm_has_errata_a050385(void)
+{
+ return fm_has_err_a050385;
+}
+EXPORT_SYMBOL(fm_has_errata_a050385);
+#endif
+
+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
+ }
+ }
+
+#ifdef CONFIG_FSL_SDK_FMAN_RTC_API
+ /* 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-ptp-timer") >= sizeof(ids[0].compatible)))
+ return NULL;
+ strcpy(ids[0].compatible, "fsl,fman-ptp-timer");
+ 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;
+ }
+ }
+#endif
+
+#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;
+ }
+
+#ifdef FM_ERRATUM_A050385
+ fm_has_err_a050385 = of_property_read_bool(fm_node, "fsl,erratum-a050385");
+#endif
+
+ 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, IRQF_SHARED, "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"));
+
+#ifdef CONFIG_FSL_SDK_FMAN_RTC_API
+ if (p_LnxWrpFmDev->fmRtcPhysBaseAddr)
+ {
+ dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize, "fman-ptp-timer");
+ 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"));
+ }
+#endif
+
+#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);*/
+ }
+
+#ifdef CONFIG_FSL_SDK_FMAN_RTC_API
+ 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"));
+ }
+#endif
+
+ 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);
+
+#ifdef CONFIG_FSL_SDK_FMAN_RTC_API
+ if (p_LnxWrpFmDev->h_RtcDev)
+ FM_RTC_Free(p_LnxWrpFmDev->h_RtcDev);
+#endif
+
+ if (p_LnxWrpFmDev->h_Dev)
+ FM_Free(p_LnxWrpFmDev->h_Dev);
+
+ if (p_LnxWrpFmDev->h_MuramDev)
+ FM_MURAM_Free(p_LnxWrpFmDev->h_MuramDev);
+
+#ifdef CONFIG_FSL_SDK_FMAN_RTC_API
+ 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);
+ }
+#endif
+ 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) {
+ FreeFmDev(p_LnxWrpFmDev);
+ return -EIO;
+ }
+ if (InitFmDev(p_LnxWrpFmDev) != E_OK) {
+ FreeFmDev(p_LnxWrpFmDev);
+ 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) {
+ FreeFmDev(p_LnxWrpFmDev);
+ 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);
+ FreeFmDev(p_LnxWrpFmDev);
+ 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 */
+
+#if defined CONFIG_PM && (defined CONFIG_PPC || defined CONFIG_PPC64)
+
+#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 && (CONFIG_PPC || CONFIG_PPC64) */
+
+#define FM_PM_OPS NULL
+
+#endif /* CONFIG_PM && (CONFIG_PPC || CONFIG_PPC64) */
+
+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);
+
+#ifdef CONFIG_FSL_SDK_FMAN_RTC_API
+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);
+#endif
+
+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);
+
+#ifdef CONFIG_FSL_SDK_FMAN_RTC_API
+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
+#endif /* CONFIG_FSL_SDK_FMAN_RTC_API */
+
+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_INFO "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);
diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.h b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.h
new file mode 100644
index 000000000000..098325635d23
--- /dev/null
+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.h
@@ -0,0 +1,294 @@
+/*
+ * 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.h
+
+ @Author Shlomi Gridish
+
+ @Description FM Linux wrapper functions.
+
+*/
+
+#ifndef __LNXWRP_FM_H__
+#define __LNXWRP_FM_H__
+
+#include <linux/fsl_qman.h> /* struct qman_fq */
+
+#include "std_ext.h"
+#include "error_ext.h"
+#include "list_ext.h"
+
+#include "lnxwrp_fm_ext.h"
+
+#define FM_MAX_NUM_OF_ADV_SETTINGS 10
+
+#define LNXWRP_FM_NUM_OF_SHARED_PROFILES 16
+
+#if defined(CONFIG_FMAN_DISABLE_OH_TO_REUSE_RESOURCES)
+#define FM_10G_OPENDMA_MIN_TRESHOLD 8 /* 10g minimum treshold if only HC is enabled and no OH port enabled */
+#define FM_OPENDMA_RX_TX_RAPORT 2 /* RX = 2*TX */
+#else
+#define FM_10G_OPENDMA_MIN_TRESHOLD 7 /* 10g minimum treshold if 7 OH ports are enabled */
+#define FM_OPENDMA_RX_TX_RAPORT 1 /* RX = TX */
+#endif
+#define FM_DEFAULT_TX10G_OPENDMA 8 /* default TX 10g open dmas */
+#define FM_DEFAULT_RX10G_OPENDMA 8 /* default RX 10g open dmas */
+
+#define FRAG_MANIP_SPACE 128
+#define FRAG_DATA_ALIGN 64
+
+#ifndef CONFIG_FSL_FM_MAX_FRAME_SIZE
+#define CONFIG_FSL_FM_MAX_FRAME_SIZE 0
+#endif
+
+#ifndef CONFIG_FSL_FM_RX_EXTRA_HEADROOM
+#define CONFIG_FSL_FM_RX_EXTRA_HEADROOM 16
+#endif
+
+typedef enum {
+ e_NO_PCD = 0,
+ e_FM_PCD_3_TUPLE
+} e_LnxWrpFmPortPcdDefUseCase;
+
+
+typedef struct t_FmTestFq {
+ struct qman_fq fq_base;
+ t_Handle h_Arg;
+} t_FmTestFq;
+
+typedef struct {
+ uint8_t id; /* sw port id, see SW_PORT_ID_TO_HW_PORT_ID() in fm_common.h */
+ int minor;
+ char name[20];
+ bool active;
+ uint64_t phys_baseAddr;
+ uint64_t baseAddr; /* Port's *virtual* address */
+ uint32_t memSize;
+ t_WrpFmPortDevSettings settings;
+ t_FmExtPools opExtPools;
+ uint8_t totalNumOfSchemes;
+ uint8_t schemesBase;
+ uint8_t numOfSchemesUsed;
+ uint32_t pcdBaseQ;
+ uint16_t pcdNumOfQs;
+ struct fm_port_pcd_param pcd_owner_params;
+ e_LnxWrpFmPortPcdDefUseCase defPcd;
+ t_Handle h_DefNetEnv;
+ t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES];
+ t_FmBufferPrefixContent buffPrefixContent;
+ t_Handle h_Dev;
+ t_Handle h_DfltVsp;
+ t_Handle h_LnxWrpFmDev;
+ uint16_t txCh;
+ struct device *dev;
+ struct device_attribute *dev_attr_stats;
+ struct device_attribute *dev_attr_regs;
+ struct device_attribute *dev_attr_bmi_regs;
+ struct device_attribute *dev_attr_qmi_regs;
+#if (DPAA_VERSION >= 11)
+ struct device_attribute *dev_attr_ipv4_opt;
+#endif
+ struct device_attribute *dev_attr_dsar_regs;
+ struct device_attribute *dev_attr_dsar_mem;
+ struct auto_res_tables_sizes dsar_table_sizes;
+} t_LnxWrpFmPortDev;
+
+typedef struct {
+ uint8_t id;
+ bool active;
+ uint64_t baseAddr;
+ uint32_t memSize;
+ t_WrpFmMacDevSettings settings;
+ t_Handle h_Dev;
+ t_Handle h_LnxWrpFmDev;
+} t_LnxWrpFmMacDev;
+
+/* information about all active ports for an FMan.
+ * !Some ports may be disabled by u-boot, thus will not be available */
+struct fm_active_ports {
+ uint32_t num_oh_ports;
+ uint32_t num_tx_ports;
+ uint32_t num_rx_ports;
+ uint32_t num_tx25_ports;
+ uint32_t num_rx25_ports;
+ uint32_t num_tx10_ports;
+ uint32_t num_rx10_ports;
+};
+
+/* FMan resources precalculated at fm probe based
+ * on available FMan port. */
+struct fm_resource_settings {
+ /* buffers - fifo sizes */
+ uint32_t tx1g_num_buffers;
+ uint32_t rx1g_num_buffers;
+ uint32_t tx2g5_num_buffers; /* Not supported yet by LLD */
+ uint32_t rx2g5_num_buffers; /* Not supported yet by LLD */
+ uint32_t tx10g_num_buffers;
+ uint32_t rx10g_num_buffers;
+ uint32_t oh_num_buffers;
+ uint32_t shared_ext_buffers;
+
+ /* open DMAs */
+ uint32_t tx_1g_dmas;
+ uint32_t rx_1g_dmas;
+ uint32_t tx_2g5_dmas; /* Not supported yet by LLD */
+ uint32_t rx_2g5_dmas; /* Not supported yet by LLD */
+ uint32_t tx_10g_dmas;
+ uint32_t rx_10g_dmas;
+ uint32_t oh_dmas;
+ uint32_t shared_ext_open_dma;
+
+ /* Tnums */
+ uint32_t tx_1g_tnums;
+ uint32_t rx_1g_tnums;
+ uint32_t tx_2g5_tnums; /* Not supported yet by LLD */
+ uint32_t rx_2g5_tnums; /* Not supported yet by LLD */
+ uint32_t tx_10g_tnums;
+ uint32_t rx_10g_tnums;
+ uint32_t oh_tnums;
+ uint32_t shared_ext_tnums;
+};
+
+typedef struct {
+ uint8_t id;
+ char name[10];
+ bool active;
+ bool pcdActive;
+ bool prsActive;
+ bool kgActive;
+ bool ccActive;
+ bool plcrActive;
+ e_LnxWrpFmPortPcdDefUseCase defPcd;
+ uint32_t usedSchemes;
+ uint8_t totalNumOfSharedSchemes;
+ uint8_t sharedSchemesBase;
+ uint8_t numOfSchemesUsed;
+ uint8_t defNetEnvId;
+ uint64_t fmPhysBaseAddr;
+ uint64_t fmBaseAddr;
+ uint32_t fmMemSize;
+ uint64_t fmMuramPhysBaseAddr;
+ uint64_t fmMuramBaseAddr;
+ uint32_t fmMuramMemSize;
+ uint64_t fmRtcPhysBaseAddr;
+ uint64_t fmRtcBaseAddr;
+ uint32_t fmRtcMemSize;
+ uint64_t fmVspPhysBaseAddr;
+ uint64_t fmVspBaseAddr;
+ uint32_t fmVspMemSize;
+ int irq;
+ int err_irq;
+ t_WrpFmDevSettings fmDevSettings;
+ t_WrpFmPcdDevSettings fmPcdDevSettings;
+ t_Handle h_Dev;
+ uint16_t hcCh;
+
+ t_Handle h_MuramDev;
+ t_Handle h_PcdDev;
+ t_Handle h_RtcDev;
+
+ t_Handle h_DsarRxPort;
+ t_Handle h_DsarTxPort;
+
+ t_LnxWrpFmPortDev hcPort;
+ t_LnxWrpFmPortDev opPorts[FM_MAX_NUM_OF_OH_PORTS-1];
+ t_LnxWrpFmPortDev rxPorts[FM_MAX_NUM_OF_RX_PORTS];
+ t_LnxWrpFmPortDev txPorts[FM_MAX_NUM_OF_TX_PORTS];
+ t_LnxWrpFmMacDev macs[FM_MAX_NUM_OF_MACS];
+ struct fm_active_ports fm_active_ports_info;
+ struct fm_resource_settings fm_resource_settings_info;
+
+ struct device *dev;
+ struct resource *res;
+ int major;
+ struct class *fm_class;
+ struct device_attribute *dev_attr_stats;
+ struct device_attribute *dev_attr_regs;
+ struct device_attribute *dev_attr_risc_load;
+
+ struct device_attribute *dev_pcd_attr_stats;
+ struct device_attribute *dev_plcr_attr_regs;
+ struct device_attribute *dev_prs_attr_regs;
+ struct device_attribute *dev_fm_fpm_attr_regs;
+ struct device_attribute *dev_fm_kg_attr_regs;
+ struct device_attribute *dev_fm_kg_pe_attr_regs;
+ struct device_attribute *dev_attr_muram_free_size;
+ struct device_attribute *dev_attr_fm_ctrl_code_ver;
+
+
+ struct qman_fq *hc_tx_conf_fq, *hc_tx_err_fq, *hc_tx_fq;
+} t_LnxWrpFmDev;
+
+typedef struct {
+ t_LnxWrpFmDev *p_FmDevs[INTG_MAX_NUM_OF_FM];
+} t_LnxWrpFm;
+#define LNXWRP_FM_OBJECT(ptr) LIST_OBJECT(ptr, t_LnxWrpFm, fms[((t_LnxWrpFmDev *)ptr)->id])
+
+
+t_Error LnxwrpFmIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat);
+t_Error LnxwrpFmPortIOCTL(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev, unsigned int cmd, unsigned long arg, bool compat);
+
+
+#if 0
+static __inline__ t_Error AllocSchemesForPort(t_LnxWrpFmDev *p_LnxWrpFmDev, uint8_t numSchemes, uint8_t *p_BaseSchemeNum)
+{
+ uint32_t schemeMask;
+ uint8_t i;
+
+ if (!numSchemes)
+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
+
+ schemeMask = 0x80000000;
+ *p_BaseSchemeNum = 0xff;
+
+ for (i=0; schemeMask && numSchemes; schemeMask>>=1, i++)
+ if ((p_LnxWrpFmDev->usedSchemes & schemeMask) == 0)
+ {
+ p_LnxWrpFmDev->usedSchemes |= schemeMask;
+ numSchemes--;
+ if (*p_BaseSchemeNum==0xff)
+ *p_BaseSchemeNum = i;
+ }
+ else if (*p_BaseSchemeNum!=0xff)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Fragmentation on schemes array!!!"));
+
+ if (numSchemes)
+ RETURN_ERROR(MINOR, E_FULL, ("schemes!!!"));
+ return E_OK;
+}
+#endif
+
+void LnxWrpPCDIOCTLTypeChecking(void);
+void LnxWrpPCDIOCTLEnumChecking(void);
+
+#endif /* __LNXWRP_FM_H__ */
diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c
new file mode 100644
index 000000000000..13b422334067
--- /dev/null
+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c
@@ -0,0 +1,1506 @@
+/*
+ * 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_port.c
+
+ @Description FMD wrapper - FMan port functions.
+
+*/
+
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/cdev.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#ifndef CONFIG_FMAN_ARM
+#include <linux/fsl/svr.h>
+#endif
+#include <linux/io.h>
+
+#include "sprint_ext.h"
+#include "fm_common.h"
+#include "lnxwrp_fsl_fman.h"
+#include "fm_port_ext.h"
+#if (DPAA_VERSION >= 11)
+#include "fm_vsp_ext.h"
+#endif /* DPAA_VERSION >= 11 */
+#include "fm_ioctls.h"
+#include "lnxwrp_resources.h"
+#include "lnxwrp_sysfs_fm_port.h"
+
+#define __ERR_MODULE__ MODULE_FM
+
+extern struct device_node *GetFmAdvArgsDevTreeNode (uint8_t fmIndx);
+
+/* TODO: duplicated, see lnxwrp_fm.c */
+#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)
+
+#ifndef CONFIG_FMAN_ARM
+#define IS_T1023_T1024 (SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1024 || \
+ SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1023)
+#endif
+
+static volatile int hcFrmRcv/* = 0 */;
+static spinlock_t lock;
+
+static enum qman_cb_dqrr_result qm_tx_conf_dqrr_cb(struct qman_portal *portal,
+ struct qman_fq *fq,
+ const struct qm_dqrr_entry
+ *dq)
+{
+ t_LnxWrpFmDev *p_LnxWrpFmDev = ((t_FmTestFq *) fq)->h_Arg;
+ unsigned long flags;
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+{
+ /* extract the HC frame address */
+ uint32_t *hcf_va = XX_PhysToVirt(qm_fd_addr((struct qm_fd *)&dq->fd));
+ int hcf_l = ((struct qm_fd *)&dq->fd)->length20;
+ int i;
+
+ /* 32b byteswap of all data in the HC Frame */
+ for(i = 0; i < hcf_l / 4; ++i)
+ hcf_va[i] =
+ ___constant_swab32(hcf_va[i]);
+}
+#endif
+ FM_PCD_HcTxConf(p_LnxWrpFmDev->h_PcdDev, (t_DpaaFD *)&dq->fd);
+ spin_lock_irqsave(&lock, flags);
+ hcFrmRcv--;
+ spin_unlock_irqrestore(&lock, flags);
+
+ return qman_cb_dqrr_consume;
+}
+
+static enum qman_cb_dqrr_result qm_tx_dqrr_cb(struct qman_portal *portal,
+ struct qman_fq *fq,
+ const struct qm_dqrr_entry *dq)
+{
+ WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
+ __func__);
+ return qman_cb_dqrr_consume;
+}
+
+static void qm_err_cb(struct qman_portal *portal,
+ struct qman_fq *fq, const struct qm_mr_entry *msg)
+{
+ WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
+ __func__);
+}
+
+static struct qman_fq *FqAlloc(t_LnxWrpFmDev * p_LnxWrpFmDev,
+ uint32_t fqid,
+ uint32_t flags, uint16_t channel, uint8_t wq)
+{
+ int _errno;
+ struct qman_fq *fq = NULL;
+ t_FmTestFq *p_FmtFq;
+ struct qm_mcc_initfq initfq;
+
+ p_FmtFq = (t_FmTestFq *) XX_Malloc(sizeof(t_FmTestFq));
+ if (!p_FmtFq) {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FQ obj!!!"));
+ return NULL;
+ }
+
+ p_FmtFq->fq_base.cb.dqrr = ((flags & QMAN_FQ_FLAG_NO_ENQUEUE)
+ ? qm_tx_conf_dqrr_cb
+ : qm_tx_dqrr_cb);
+ p_FmtFq->fq_base.cb.ern = qm_err_cb;
+ /* p_FmtFq->fq_base.cb.fqs = qm_err_cb; */
+ /* qm_err_cb wrongly called when the FQ is parked */
+ p_FmtFq->fq_base.cb.fqs = NULL;
+ p_FmtFq->h_Arg = (t_Handle) p_LnxWrpFmDev;
+ if (fqid == 0) {
+ flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
+ flags &= ~QMAN_FQ_FLAG_NO_MODIFY;
+ } else {
+ flags &= ~QMAN_FQ_FLAG_DYNAMIC_FQID;
+ }
+
+ if (qman_create_fq(fqid, flags, &p_FmtFq->fq_base)) {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FQ obj - qman_new_fq!!!"));
+ XX_Free(p_FmtFq);
+ return NULL;
+ }
+ fq = &p_FmtFq->fq_base;
+
+ if (!(flags & QMAN_FQ_FLAG_NO_MODIFY)) {
+ initfq.we_mask = QM_INITFQ_WE_DESTWQ;
+ initfq.fqd.dest.channel = channel;
+ initfq.fqd.dest.wq = wq;
+
+ _errno = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &initfq);
+ if (unlikely(_errno < 0)) {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY,
+ ("FQ obj - qman_init_fq!!!"));
+ qman_destroy_fq(fq, 0);
+ XX_Free(p_FmtFq);
+ return NULL;
+ }
+ }
+
+ DBG(TRACE,
+ ("fqid %d, flags 0x%08x, channel %d, wq %d", qman_fq_fqid(fq),
+ flags, channel, wq));
+
+ return fq;
+}
+
+static void FqFree(struct qman_fq *fq)
+{
+ int _errno;
+
+ _errno = qman_retire_fq(fq, NULL);
+ if (unlikely(_errno < 0))
+ printk(KERN_WARNING "qman_retire_fq(%u) = %d\n", qman_fq_fqid(fq), _errno);
+
+ _errno = qman_oos_fq(fq);
+ if (unlikely(_errno < 0))
+ printk(KERN_WARNING "qman_oos_fq(%u) = %d\n", qman_fq_fqid(fq), _errno);
+
+ qman_destroy_fq(fq, 0);
+ XX_Free((t_FmTestFq *) fq);
+}
+
+static t_Error QmEnqueueCB(t_Handle h_Arg, void *p_Fd)
+{
+ t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_Arg;
+ int _errno, timeout = 1000000;
+ unsigned long flags;
+
+ ASSERT_COND(p_LnxWrpFmDev);
+
+ spin_lock_irqsave(&lock, flags);
+ hcFrmRcv++;
+ spin_unlock_irqrestore(&lock, flags);
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+{
+ /* extract the HC frame address */
+ uint32_t *hcf_va = XX_PhysToVirt(qm_fd_addr((struct qm_fd *) p_Fd));
+ int hcf_l = ((struct qm_fd *)p_Fd)->length20;
+ int i;
+
+ /* 32b byteswap of all data in the HC Frame */
+ for(i = 0; i < hcf_l / 4; ++i)
+ hcf_va[i] =
+ ___constant_swab32(hcf_va[i]);
+}
+#endif
+
+ _errno = qman_enqueue(p_LnxWrpFmDev->hc_tx_fq, (struct qm_fd *) p_Fd,
+ 0);
+ if (_errno)
+ RETURN_ERROR(MINOR, E_INVALID_STATE,
+ ("qman_enqueue() failed"));
+
+ while (hcFrmRcv && --timeout) {
+ udelay(1);
+ cpu_relax();
+ }
+ if (timeout == 0) {
+ dump_stack();
+ RETURN_ERROR(MINOR, E_WRITE_FAILED,
+ ("timeout waiting for Tx confirmation"));
+ return E_WRITE_FAILED;
+ }
+
+ return E_OK;
+}
+
+static t_LnxWrpFmPortDev *ReadFmPortDevTreeNode(struct platform_device
+ *of_dev)
+{
+ t_LnxWrpFmDev *p_LnxWrpFmDev;
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
+ struct device_node *fm_node, *port_node;
+ struct resource res;
+ const uint32_t *uint32_prop;
+ int _errno = 0, lenp;
+ uint32_t tmp_prop;
+
+#ifdef CONFIG_FMAN_P1023
+ static unsigned char have_oh_port/* = 0 */;
+#endif
+
+ port_node = of_node_get(of_dev->dev.of_node);
+
+ /* Get the FM node */
+ fm_node = of_get_parent(port_node);
+ if (unlikely(fm_node == NULL)) {
+ REPORT_ERROR(MAJOR, E_NO_DEVICE,
+ ("of_get_parent() = %d", _errno));
+ return NULL;
+ }
+
+ p_LnxWrpFmDev =
+ dev_get_drvdata(&of_find_device_by_node(fm_node)->dev);
+ of_node_put(fm_node);
+
+ /* if fm_probe() failed, no point in going further with port probing */
+ if (p_LnxWrpFmDev == NULL)
+ return NULL;
+
+ uint32_prop =
+ (uint32_t *) of_get_property(port_node, "cell-index", &lenp);
+ if (unlikely(uint32_prop == NULL)) {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE,
+ ("of_get_property(%s, cell-index) failed",
+ port_node->full_name));
+ return NULL;
+ }
+ tmp_prop = be32_to_cpu(*uint32_prop);
+ if (WARN_ON(lenp != sizeof(uint32_t)))
+ return NULL;
+ if (of_device_is_compatible(port_node, "fsl,fman-port-oh") ||
+ of_device_is_compatible(port_node, "fsl,fman-v2-port-oh") ||
+ of_device_is_compatible(port_node, "fsl,fman-v3-port-oh")) {
+#ifndef CONFIG_FMAN_ARM
+#ifdef CONFIG_FMAN_P3040_P4080_P5020
+ /* On PPC FMan v2, OH ports start from cell-index 0x1 */
+ tmp_prop -= 0x1;
+#else
+ /* On PPC FMan v3 (Low and High), OH ports start from
+ * cell-index 0x2
+ */
+ tmp_prop -= 0x2;
+#endif // CONFIG_FMAN_P3040_P4080_P5020
+#endif // CONFIG_FMAN_ARM
+
+ if (unlikely(tmp_prop >= FM_MAX_NUM_OF_OH_PORTS)) {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE,
+ ("of_get_property(%s, cell-index) failed",
+ port_node->full_name));
+ return NULL;
+ }
+
+#ifdef CONFIG_FMAN_P1023
+ /* Beware, this can be done when there is only
+ one FMan to be initialized */
+ if (!have_oh_port) {
+ have_oh_port = 1; /* first OP/HC port
+ is used for host command */
+#else
+ /* Here it is hardcoded the use of the OH port 1
+ (with cell-index 0) */
+ if (tmp_prop == 0) {
+#endif
+ p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
+ p_LnxWrpFmPortDev->id = 0;
+ /*
+ p_LnxWrpFmPortDev->id = *uint32_prop-1;
+ p_LnxWrpFmPortDev->id = *uint32_prop;
+ */
+ p_LnxWrpFmPortDev->settings.param.portType =
+ e_FM_PORT_TYPE_OH_HOST_COMMAND;
+ } else {
+ p_LnxWrpFmPortDev =
+ &p_LnxWrpFmDev->opPorts[tmp_prop - 1];
+ p_LnxWrpFmPortDev->id = tmp_prop- 1;
+ p_LnxWrpFmPortDev->settings.param.portType =
+ e_FM_PORT_TYPE_OH_OFFLINE_PARSING;
+ }
+ p_LnxWrpFmPortDev->settings.param.portId = tmp_prop;
+
+ uint32_prop =
+ (uint32_t *) of_get_property(port_node,
+ "fsl,qman-channel-id",
+ &lenp);
+ if (uint32_prop == NULL) {
+ /*
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("missing fsl,qman-channel-id"));
+ */
+ XX_Print("FM warning: missing fsl,qman-channel-id"
+ " for OH port.\n");
+ return NULL;
+ }
+ tmp_prop = be32_to_cpu(*uint32_prop);
+ if (WARN_ON(lenp != sizeof(uint32_t)))
+ return NULL;
+ p_LnxWrpFmPortDev->txCh = tmp_prop;
+
+ p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
+ qmChannel = p_LnxWrpFmPortDev->txCh;
+ } else if (of_device_is_compatible(port_node, "fsl,fman-port-1g-tx")) {
+ tmp_prop -= 0x28;
+ if (unlikely(tmp_prop >= FM_MAX_NUM_OF_1G_TX_PORTS)) {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE,
+ ("of_get_property(%s, cell-index) failed",
+ port_node->full_name));
+ return NULL;
+ }
+ p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[tmp_prop];
+
+ p_LnxWrpFmPortDev->id = tmp_prop;
+ p_LnxWrpFmPortDev->settings.param.portId =
+ p_LnxWrpFmPortDev->id;
+ p_LnxWrpFmPortDev->settings.param.portType = e_FM_PORT_TYPE_TX;
+
+ uint32_prop = (uint32_t *) of_get_property(port_node,
+ "fsl,qman-channel-id", &lenp);
+ if (uint32_prop == NULL) {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE,
+ ("missing fsl,qman-channel-id"));
+ return NULL;
+ }
+ tmp_prop = be32_to_cpu(*uint32_prop);
+ if (WARN_ON(lenp != sizeof(uint32_t)))
+ return NULL;
+ p_LnxWrpFmPortDev->txCh = tmp_prop;
+ p_LnxWrpFmPortDev->
+ settings.param.specificParams.nonRxParams.qmChannel =
+ p_LnxWrpFmPortDev->txCh;
+ } else if (of_device_is_compatible(port_node, "fsl,fman-port-10g-tx")) {
+#ifndef CONFIG_FMAN_ARM
+ /* On T102x, the 10G TX port IDs start from 0x28 */
+ if (IS_T1023_T1024)
+ tmp_prop -= 0x28;
+ else
+#endif
+ tmp_prop -= 0x30;
+
+ if (unlikely(tmp_prop>= FM_MAX_NUM_OF_10G_TX_PORTS)) {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE,
+ ("of_get_property(%s, cell-index) failed",
+ port_node->full_name));
+ return NULL;
+ }
+ p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[tmp_prop +
+ FM_MAX_NUM_OF_1G_TX_PORTS];
+#ifndef CONFIG_FMAN_ARM
+ if (IS_T1023_T1024)
+ p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[tmp_prop];
+#endif
+
+ p_LnxWrpFmPortDev->id = tmp_prop;
+ p_LnxWrpFmPortDev->settings.param.portId =
+ p_LnxWrpFmPortDev->id;
+ p_LnxWrpFmPortDev->settings.param.portType =
+ e_FM_PORT_TYPE_TX_10G;
+ uint32_prop = (uint32_t *) of_get_property(port_node,
+ "fsl,qman-channel-id", &lenp);
+ if (uint32_prop == NULL) {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE,
+ ("missing fsl,qman-channel-id"));
+ return NULL;
+ }
+ tmp_prop = be32_to_cpu(*uint32_prop);
+ if (WARN_ON(lenp != sizeof(uint32_t)))
+ return NULL;
+ p_LnxWrpFmPortDev->txCh = tmp_prop;
+ p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
+ qmChannel = p_LnxWrpFmPortDev->txCh;
+ } else if (of_device_is_compatible(port_node, "fsl,fman-port-1g-rx")) {
+ tmp_prop -= 0x08;
+ if (unlikely(tmp_prop >= FM_MAX_NUM_OF_1G_RX_PORTS)) {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE,
+ ("of_get_property(%s, cell-index) failed",
+ port_node->full_name));
+ return NULL;
+ }
+ p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[tmp_prop];
+
+ p_LnxWrpFmPortDev->id = tmp_prop;
+ p_LnxWrpFmPortDev->settings.param.portId =
+ p_LnxWrpFmPortDev->id;
+ p_LnxWrpFmPortDev->settings.param.portType = e_FM_PORT_TYPE_RX;
+ if (p_LnxWrpFmDev->pcdActive)
+ p_LnxWrpFmPortDev->defPcd = p_LnxWrpFmDev->defPcd;
+ } else if (of_device_is_compatible(port_node, "fsl,fman-port-10g-rx")) {
+#ifndef CONFIG_FMAN_ARM
+ /* On T102x, the 10G RX port IDs start from 0x08 */
+ if (IS_T1023_T1024)
+ tmp_prop -= 0x8;
+ else
+#endif
+ tmp_prop -= 0x10;
+
+ if (unlikely(tmp_prop >= FM_MAX_NUM_OF_10G_RX_PORTS)) {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE,
+ ("of_get_property(%s, cell-index) failed",
+ port_node->full_name));
+ return NULL;
+ }
+ p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[tmp_prop +
+ FM_MAX_NUM_OF_1G_RX_PORTS];
+
+#ifndef CONFIG_FMAN_ARM
+ if (IS_T1023_T1024)
+ p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[tmp_prop];
+#endif
+
+ p_LnxWrpFmPortDev->id = tmp_prop;
+ p_LnxWrpFmPortDev->settings.param.portId =
+ p_LnxWrpFmPortDev->id;
+ p_LnxWrpFmPortDev->settings.param.portType =
+ e_FM_PORT_TYPE_RX_10G;
+ if (p_LnxWrpFmDev->pcdActive)
+ p_LnxWrpFmPortDev->defPcd = p_LnxWrpFmDev->defPcd;
+ } else {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal port type"));
+ return NULL;
+ }
+
+ _errno = of_address_to_resource(port_node, 0, &res);
+ if (unlikely(_errno < 0)) {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE,
+ ("of_address_to_resource() = %d", _errno));
+ return NULL;
+ }
+
+ p_LnxWrpFmPortDev->dev = &of_dev->dev;
+ p_LnxWrpFmPortDev->baseAddr = 0;
+ p_LnxWrpFmPortDev->phys_baseAddr = res.start;
+ p_LnxWrpFmPortDev->memSize = res.end + 1 - res.start;
+ p_LnxWrpFmPortDev->settings.param.h_Fm = p_LnxWrpFmDev->h_Dev;
+ p_LnxWrpFmPortDev->h_LnxWrpFmDev = (t_Handle) p_LnxWrpFmDev;
+
+ of_node_put(port_node);
+
+ p_LnxWrpFmPortDev->active = TRUE;
+
+#if defined(CONFIG_FMAN_DISABLE_OH_TO_REUSE_RESOURCES)
+ /* for performance mode no OH port available. */
+ if (p_LnxWrpFmPortDev->settings.param.portType ==
+ e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
+ p_LnxWrpFmPortDev->active = FALSE;
+#endif
+
+ return p_LnxWrpFmPortDev;
+}
+
+struct device_node * GetFmPortAdvArgsDevTreeNode (struct device_node *fm_node,
+ e_FmPortType portType,
+ uint8_t portId)
+{
+ struct device_node *port_node;
+ const uint32_t *uint32_prop;
+ int lenp;
+ char *portTypeString;
+ uint32_t tmp_prop;
+
+ switch(portType) {
+ case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
+ portTypeString = "fsl,fman-port-op-extended-args";
+ break;
+ case e_FM_PORT_TYPE_TX:
+ portTypeString = "fsl,fman-port-1g-tx-extended-args";
+ break;
+ case e_FM_PORT_TYPE_TX_10G:
+ portTypeString = "fsl,fman-port-10g-tx-extended-args";
+ break;
+ case e_FM_PORT_TYPE_RX:
+ portTypeString = "fsl,fman-port-1g-rx-extended-args";
+ break;
+ case e_FM_PORT_TYPE_RX_10G:
+ portTypeString = "fsl,fman-port-10g-rx-extended-args";
+ break;
+ default:
+ return NULL;
+ }
+
+ for_each_child_of_node(fm_node, port_node) {
+ uint32_prop = (uint32_t *)of_get_property(port_node, "cell-index", &lenp);
+ if (unlikely(uint32_prop == NULL)) {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE,
+ ("of_get_property(%s, cell-index) failed",
+ port_node->full_name));
+ return NULL;
+ }
+ tmp_prop = be32_to_cpu(*uint32_prop);
+ if (WARN_ON(lenp != sizeof(uint32_t)))
+ return NULL;
+ if ((portId == tmp_prop) &&
+ (of_device_is_compatible(port_node, portTypeString))) {
+ return port_node;
+ }
+ }
+
+ return NULL;
+}
+
+static t_Error CheckNConfigFmPortAdvArgs (t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
+{
+ struct device_node *fm_node, *port_node;
+ t_Error err;
+ t_FmPortRsrc portRsrc;
+ const uint32_t *uint32_prop;
+ /*const char *str_prop;*/
+ int lenp;
+#ifdef CONFIG_FMAN_PFC
+ uint8_t i, id, num_pools;
+ t_FmBufPoolDepletion poolDepletion;
+
+ if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX ||
+ p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G) {
+ memset(&poolDepletion, 0, sizeof(t_FmBufPoolDepletion));
+ poolDepletion.singlePoolModeEnable = true;
+ num_pools = p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
+ extBufPools.numOfPoolsUsed;
+ for (i = 0; i < num_pools; i++) {
+ id = p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
+ extBufPools.extBufPool[i].id;
+ poolDepletion.poolsToConsiderForSingleMode[id] = true;
+ }
+
+ for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++)
+ poolDepletion.pfcPrioritiesEn[i] = true;
+
+ err = FM_PORT_ConfigPoolDepletion(p_LnxWrpFmPortDev->h_Dev,
+ &poolDepletion);
+ if (err != E_OK)
+ RETURN_ERROR(MAJOR, err, ("FM_PORT_ConfigPoolDepletion() failed"));
+ }
+#endif
+
+ fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
+ if (!fm_node) /* no advance parameters for FMan */
+ return E_OK;
+
+ 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 E_OK;
+
+ uint32_prop = (uint32_t *)of_get_property(port_node, "num-tnums", &lenp);
+ if (uint32_prop) {
+ if (WARN_ON(lenp != sizeof(uint32_t)*2))
+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
+
+ portRsrc.num = be32_to_cpu(uint32_prop[0]);
+ portRsrc.extra = be32_to_cpu(uint32_prop[1]);
+
+ if ((err = FM_PORT_ConfigNumOfTasks(p_LnxWrpFmPortDev->h_Dev,
+ &portRsrc)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ uint32_prop = (uint32_t *)of_get_property(port_node, "num-dmas", &lenp);
+ if (uint32_prop) {
+ if (WARN_ON(lenp != sizeof(uint32_t)*2))
+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
+
+ portRsrc.num = be32_to_cpu(uint32_prop[0]);
+ portRsrc.extra = be32_to_cpu(uint32_prop[1]);
+
+ if ((err = FM_PORT_ConfigNumOfOpenDmas(p_LnxWrpFmPortDev->h_Dev,
+ &portRsrc)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ uint32_prop = (uint32_t *)of_get_property(port_node, "fifo-size", &lenp);
+ if (uint32_prop) {
+ if (WARN_ON(lenp != sizeof(uint32_t)*2))
+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
+
+ portRsrc.num = be32_to_cpu(uint32_prop[0]);
+ portRsrc.extra = be32_to_cpu(uint32_prop[1]);
+
+ if ((err = FM_PORT_ConfigSizeOfFifo(p_LnxWrpFmPortDev->h_Dev,
+ &portRsrc)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ uint32_prop = (uint32_t *)of_get_property(port_node, "errors-to-discard", &lenp);
+ if (uint32_prop) {
+ if (WARN_ON(lenp != sizeof(uint32_t)))
+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
+ if ((err = FM_PORT_ConfigErrorsToDiscard(p_LnxWrpFmPortDev->h_Dev,
+ be32_to_cpu(uint32_prop[0]))) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ uint32_prop = (uint32_t *)of_get_property(port_node, "ar-tables-sizes",
+ &lenp);
+ if (uint32_prop) {
+
+ if (WARN_ON(lenp != sizeof(uint32_t)*8))
+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
+ if (WARN_ON(p_LnxWrpFmPortDev->settings.param.portType !=
+ e_FM_PORT_TYPE_RX) &&
+ (p_LnxWrpFmPortDev->settings.param.portType !=
+ e_FM_PORT_TYPE_RX_10G))
+ RETURN_ERROR(MINOR, E_INVALID_VALUE,
+ ("Auto Response is an Rx port atribute."));
+
+ memset(&p_LnxWrpFmPortDev->dsar_table_sizes, 0, sizeof(struct auto_res_tables_sizes));
+
+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_arp_entries =
+ (uint16_t)be32_to_cpu(uint32_prop[0]);
+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_echo_ipv4_entries =
+ (uint16_t)be32_to_cpu(uint32_prop[1]);
+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_ndp_entries =
+ (uint16_t)be32_to_cpu(uint32_prop[2]);
+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_echo_ipv6_entries =
+ (uint16_t)be32_to_cpu(uint32_prop[3]);
+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_ipv4_entries =
+ (uint16_t)be32_to_cpu(uint32_prop[4]);
+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_ipv6_entries =
+ (uint16_t)be32_to_cpu(uint32_prop[5]);
+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_oid_entries =
+ (uint16_t)be32_to_cpu(uint32_prop[6]);
+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_char =
+ (uint16_t)be32_to_cpu(uint32_prop[7]);
+
+ uint32_prop = (uint32_t *)of_get_property(port_node,
+ "ar-filters-sizes", &lenp);
+ if (uint32_prop) {
+ if (WARN_ON(lenp != sizeof(uint32_t)*3))
+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
+
+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_ip_prot_filtering =
+ (uint16_t)be32_to_cpu(uint32_prop[0]);
+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_tcp_port_filtering =
+ (uint16_t)be32_to_cpu(uint32_prop[1]);
+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_udp_port_filtering =
+ (uint16_t)be32_to_cpu(uint32_prop[2]);
+ }
+
+ if ((err = FM_PORT_ConfigDsarSupport(p_LnxWrpFmPortDev->h_Dev,
+ (t_FmPortDsarTablesSizes*)&p_LnxWrpFmPortDev->dsar_table_sizes)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ of_node_put(port_node);
+ of_node_put(fm_node);
+
+ return E_OK;
+}
+
+static t_Error CheckNSetFmPortAdvArgs (t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
+{
+ struct device_node *fm_node, *port_node;
+ t_Error err;
+ const uint32_t *uint32_prop;
+ /*const char *str_prop;*/
+ int lenp;
+
+ fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
+ if (!fm_node) /* no advance parameters for FMan */
+ return E_OK;
+
+ 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 E_OK;
+
+#if (DPAA_VERSION >= 11)
+ uint32_prop = (uint32_t *)of_get_property(port_node, "vsp-window", &lenp);
+ if (uint32_prop) {
+ t_FmPortVSPAllocParams portVSPAllocParams;
+ t_FmVspParams fmVspParams;
+ t_LnxWrpFmDev *p_LnxWrpFmDev;
+ uint8_t portId;
+
+ p_LnxWrpFmDev = ((t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev);
+
+ if (WARN_ON(lenp != sizeof(uint32_t)*2))
+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
+
+ if ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_TX) ||
+ (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_TX_10G) ||
+ ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
+ p_LnxWrpFmPortDev->settings.frag_enabled))
+ return E_OK;
+
+ memset(&portVSPAllocParams, 0, sizeof(portVSPAllocParams));
+ memset(&fmVspParams, 0, sizeof(fmVspParams));
+
+ portVSPAllocParams.numOfProfiles = (uint8_t)be32_to_cpu(uint32_prop[0]);
+ portVSPAllocParams.dfltRelativeId = (uint8_t)be32_to_cpu(uint32_prop[1]);
+ fmVspParams.h_Fm = p_LnxWrpFmDev->h_Dev;
+
+ fmVspParams.portParams.portType = p_LnxWrpFmPortDev->settings.param.portType;
+ fmVspParams.portParams.portId = p_LnxWrpFmPortDev->settings.param.portId;
+ fmVspParams.relativeProfileId = portVSPAllocParams.dfltRelativeId;
+
+ if (p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
+ {
+ portId = fmVspParams.portParams.portId;
+ if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G){
+#ifndef CONFIG_FMAN_ARM
+ if (!(IS_T1023_T1024))
+#endif
+ portId += FM_MAX_NUM_OF_1G_RX_PORTS;
+ }
+ portVSPAllocParams.h_FmTxPort =
+ p_LnxWrpFmDev->txPorts[portId].h_Dev;
+ fmVspParams.liodnOffset =
+ p_LnxWrpFmDev->rxPorts[portId].settings.param.specificParams.rxParams.liodnOffset;
+ memcpy(&fmVspParams.extBufPools,
+ &p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.extBufPools,
+ sizeof(t_FmExtPools));
+ }
+ else
+ {
+ memcpy(&fmVspParams.extBufPools,
+ &p_LnxWrpFmPortDev->opExtPools,
+ sizeof(t_FmExtPools));
+ }
+
+ if ((err = FM_PORT_VSPAlloc(p_LnxWrpFmPortDev->h_Dev,
+ &portVSPAllocParams)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ /* We're initializing only the default VSP that are being used by the Linux-Ethernet-driver */
+ if ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
+ !p_LnxWrpFmPortDev->opExtPools.numOfPoolsUsed)
+ return E_OK;
+
+ p_LnxWrpFmPortDev->h_DfltVsp = FM_VSP_Config(&fmVspParams);
+ if (!p_LnxWrpFmPortDev->h_DfltVsp)
+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("default-VSP for port!"));
+
+ if ((err = FM_VSP_ConfigBufferPrefixContent(p_LnxWrpFmPortDev->h_DfltVsp,
+ &p_LnxWrpFmPortDev->buffPrefixContent)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ if ((err = FM_VSP_Init(p_LnxWrpFmPortDev->h_DfltVsp)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+#else
+UNUSED(err); UNUSED(uint32_prop); UNUSED(lenp);
+#endif /* (DPAA_VERSION >= 11) */
+
+ of_node_put(port_node);
+ of_node_put(fm_node);
+
+ return E_OK;
+}
+
+static t_Error ConfigureFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
+{
+ t_LnxWrpFmDev *p_LnxWrpFmDev =
+ (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
+ struct resource *dev_res;
+
+ if (!p_LnxWrpFmPortDev->active)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE,
+ ("FM port not configured!!!"));
+
+ dev_res =
+ __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res,
+ p_LnxWrpFmPortDev->phys_baseAddr,
+ p_LnxWrpFmPortDev->memSize,
+ "fman-port-hc");
+ if (unlikely(dev_res == NULL))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE,
+ ("__devm_request_region() failed"));
+ p_LnxWrpFmPortDev->baseAddr =
+ PTR_TO_UINT(devm_ioremap
+ (p_LnxWrpFmDev->dev,
+ p_LnxWrpFmPortDev->phys_baseAddr,
+ p_LnxWrpFmPortDev->memSize));
+ if (unlikely(p_LnxWrpFmPortDev->baseAddr == 0))
+ REPORT_ERROR(MAJOR, E_INVALID_STATE,
+ ("devm_ioremap() failed"));
+
+ p_LnxWrpFmPortDev->settings.param.baseAddr =
+ p_LnxWrpFmPortDev->baseAddr;
+
+ return E_OK;
+}
+
+static t_Error InitFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
+{
+#define MY_ADV_CONFIG_CHECK_END \
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION,\
+ ("Advanced configuration routine"));\
+ if (errCode != E_OK)\
+ RETURN_ERROR(MAJOR, errCode, NO_MSG);\
+ }
+
+ int i = 0;
+
+ if (!p_LnxWrpFmPortDev->active || p_LnxWrpFmPortDev->h_Dev)
+ return E_INVALID_STATE;
+
+ p_LnxWrpFmPortDev->h_Dev =
+ FM_PORT_Config(&p_LnxWrpFmPortDev->settings.param);
+ if (p_LnxWrpFmPortDev->h_Dev == NULL)
+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-port"));
+
+#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
+ if ((p_LnxWrpFmPortDev->settings.param.portType ==
+ e_FM_PORT_TYPE_TX_10G)
+ || (p_LnxWrpFmPortDev->settings.param.portType ==
+ e_FM_PORT_TYPE_TX)) {
+ t_Error errCode = E_OK;
+ errCode =
+ FM_PORT_ConfigDeqHighPriority(p_LnxWrpFmPortDev->h_Dev,
+ TRUE);
+ if (errCode != E_OK)
+ RETURN_ERROR(MAJOR, errCode, NO_MSG);
+ errCode =
+ FM_PORT_ConfigDeqPrefetchOption(p_LnxWrpFmPortDev->h_Dev,
+ e_FM_PORT_DEQ_FULL_PREFETCH);
+ if (errCode
+ != E_OK)
+ RETURN_ERROR(MAJOR, errCode, NO_MSG);
+ }
+#endif /* !FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
+
+#ifndef CONFIG_FMAN_ARM
+#ifdef FM_BCB_ERRATA_BMI_SW001
+/* Configure BCB workaround on Rx ports, only for B4860 rev1 */
+#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
+
+ if ((p_LnxWrpFmPortDev->settings.param.portType ==
+ e_FM_PORT_TYPE_RX_10G) ||
+ (p_LnxWrpFmPortDev->settings.param.portType ==
+ e_FM_PORT_TYPE_RX)) {
+ unsigned int svr;
+
+ svr = mfspr(SPRN_SVR);
+
+ if ((svr & ~SVR_VER_IGNORE_MASK) == SVR_B4860_REV1_VALUE)
+ FM_PORT_ConfigBCBWorkaround(p_LnxWrpFmPortDev->h_Dev);
+ }
+#endif /* FM_BCB_ERRATA_BMI_SW001 */
+#endif /* CONFIG_FMAN_ARM */
+/* Call the driver's advanced configuration routines, if requested:
+ Compare the function pointer of each entry to the available routines,
+ and invoke the matching routine with proper casting of arguments. */
+ while (p_LnxWrpFmPortDev->settings.advConfig[i].p_Function
+ && (i < FM_MAX_NUM_OF_ADV_SETTINGS)) {
+
+/* TODO: Change this MACRO */
+ ADV_CONFIG_CHECK_START(
+ &(p_LnxWrpFmPortDev->settings.advConfig[i]))
+
+ ADV_CONFIG_CHECK(p_LnxWrpFmPortDev->h_Dev,
+ FM_PORT_ConfigBufferPrefixContent,
+ NCSW_PARAMS(1,
+ (t_FmBufferPrefixContent *)))
+
+ if ((p_LnxWrpFmPortDev->settings.param.portType ==
+ e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
+ (p_LnxWrpFmPortDev->settings.frag_enabled == TRUE)) {
+
+ ADV_CONFIG_CHECK(p_LnxWrpFmPortDev->h_Dev,
+ FM_PORT_ConfigExtBufPools,
+ NCSW_PARAMS(1, (t_FmExtPools *)))
+
+ /* this define contains an else */
+ MY_ADV_CONFIG_CHECK_END
+ }
+
+ /* Advance to next advanced configuration entry */
+ i++;
+ }
+
+
+ if ((p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_TX) &&
+ (p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_TX_10G)) {
+ if (FM_PORT_ConfigErrorsToDiscard(p_LnxWrpFmPortDev->h_Dev, (FM_PORT_FRM_ERR_IPRE |
+ FM_PORT_FRM_ERR_IPR_NCSP |
+ FM_PORT_FRM_ERR_CLS_DISCARD)) !=E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+ }
+
+ if (CheckNConfigFmPortAdvArgs(p_LnxWrpFmPortDev) != E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+
+ if (FM_PORT_Init(p_LnxWrpFmPortDev->h_Dev) != E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+
+ if (CheckNSetFmPortAdvArgs(p_LnxWrpFmPortDev) != E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+
+/* FMan Fifo sizes behind the scene":
+ * Using the following formulae (*), under a set of simplifying assumptions (.):
+ * . all ports are configured in Normal Mode (rather than Independent Mode)
+ * . the DPAA Eth driver allocates buffers of size:
+ * . MAXFRM + NET_IP_ALIGN + DPA_PRIV_DATA_SIZE + DPA_PARSE_RESULTS_SIZE
+ * + DPA_HASH_RESULTS_SIZE, i.e.:
+ * MAXFRM + 2 + 16 + sizeof(t_FmPrsResult) + 16, i.e.:
+ * MAXFRM + 66
+ * . excessive buffer pools not accounted for
+ *
+ * * for Rx ports on P4080:
+ * . IFSZ = ceil(max(FMBM_EBMPI[PBS]) / 256) * 256 + 7 * 256
+ * . no internal frame offset (FMBM_RIM[FOF] == 0) - otherwise,
+ * add up to 256 to the above
+ *
+ * * for Rx ports on P1023:
+ * . IFSZ = ceil(second_largest(FMBM_EBMPI[PBS] / 256)) * 256 + 7 * 256,
+ * if at least 2 bpools are configured
+ * . IFSZ = 8 * 256, if only a single bpool is configured
+ *
+ * * for Tx ports:
+ * . IFSZ = ceil(frame_size / 256) * 256 + 3 * 256
+ * + FMBM_TFP[DPDE] * 256, i.e.:
+ * IFSZ = ceil(MAXFRM / 256) * 256 + 3 x 256 + FMBM_TFP[DPDE] * 256
+ *
+ * * for OH ports on P4080:
+ * . IFSZ = ceil(frame_size / 256) * 256 + 1 * 256 + FMBM_PP[MXT] * 256
+ * * for OH ports on P1023:
+ * . IFSZ = ceil(frame_size / 256) * 256 + 3 * 256 + FMBM_TFP[DPDE] * 256
+ * * for both P4080 and P1023:
+ * . (conservative decisions, assuming that BMI must bring the entire
+ * frame, not only the frame header)
+ * . no internal frame offset (FMBM_OIM[FOF] == 0) - otherwise,
+ * add up to 256 to the above
+ *
+ * . for P4080/P5020/P3041/P2040, DPDE is:
+ * > 0 or 1, for 1Gb ports, HW default: 0
+ * > 2..7 (recommended: 3..7) for 10Gb ports, HW default: 3
+ * . for P1023, DPDE should be 1
+ *
+ * . for P1023, MXT is in range (0..31)
+ * . for P4080, MXT is in range (0..63)
+ *
+ */
+#if 0
+ if ((p_LnxWrpFmPortDev->defPcd != e_NO_PCD) &&
+ (InitFmPort3TupleDefPcd(p_LnxWrpFmPortDev) != E_OK))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+#endif
+ return E_OK;
+}
+
+void fm_set_rx_port_params(struct fm_port *port,
+ struct fm_port_params *params)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) port;
+ int i;
+
+ p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.errFqid =
+ params->errq;
+ p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.dfltFqid =
+ params->defq;
+ p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.extBufPools.
+ numOfPoolsUsed = params->num_pools;
+ for (i = 0; i < params->num_pools; i++) {
+ p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
+ extBufPools.extBufPool[i].id =
+ params->pool_param[i].id;
+ p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
+ extBufPools.extBufPool[i].size =
+ params->pool_param[i].size;
+ }
+
+ p_LnxWrpFmPortDev->buffPrefixContent.privDataSize =
+ params->priv_data_size;
+ p_LnxWrpFmPortDev->buffPrefixContent.passPrsResult =
+ params->parse_results;
+ p_LnxWrpFmPortDev->buffPrefixContent.passHashResult =
+ params->hash_results;
+ p_LnxWrpFmPortDev->buffPrefixContent.passTimeStamp =
+ params->time_stamp;
+ p_LnxWrpFmPortDev->buffPrefixContent.dataAlign =
+ params->data_align;
+ p_LnxWrpFmPortDev->buffPrefixContent.manipExtraSpace =
+ params->manip_extra_space;
+
+ ADD_ADV_CONFIG_START(p_LnxWrpFmPortDev->settings.advConfig,
+ FM_MAX_NUM_OF_ADV_SETTINGS)
+
+ ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigBufferPrefixContent,
+ ARGS(1,
+ (&p_LnxWrpFmPortDev->
+ buffPrefixContent)));
+
+ ADD_ADV_CONFIG_END InitFmPortDev(p_LnxWrpFmPortDev);
+}
+EXPORT_SYMBOL(fm_set_rx_port_params);
+
+/* this function is called from oh_probe as well, thus it contains oh port
+ * specific parameters (make sure everything is checked) */
+void fm_set_tx_port_params(struct fm_port *port,
+ struct fm_port_params *params)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) port;
+
+ p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.errFqid =
+ params->errq;
+ p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
+ dfltFqid = params->defq;
+
+ p_LnxWrpFmPortDev->buffPrefixContent.privDataSize =
+ params->priv_data_size;
+ p_LnxWrpFmPortDev->buffPrefixContent.passPrsResult =
+ params->parse_results;
+ p_LnxWrpFmPortDev->buffPrefixContent.passHashResult =
+ params->hash_results;
+ p_LnxWrpFmPortDev->buffPrefixContent.passTimeStamp =
+ params->time_stamp;
+ p_LnxWrpFmPortDev->settings.frag_enabled =
+ params->frag_enable;
+ p_LnxWrpFmPortDev->buffPrefixContent.dataAlign =
+ params->data_align;
+ p_LnxWrpFmPortDev->buffPrefixContent.manipExtraSpace =
+ params->manip_extra_space;
+
+ ADD_ADV_CONFIG_START(p_LnxWrpFmPortDev->settings.advConfig,
+ FM_MAX_NUM_OF_ADV_SETTINGS)
+
+ ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigBufferPrefixContent,
+ ARGS(1,
+ (&p_LnxWrpFmPortDev->
+ buffPrefixContent)));
+
+ /* oh port specific parameter (for fragmentation only) */
+ if ((p_LnxWrpFmPortDev->settings.param.portType ==
+ e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
+ params->num_pools) {
+ int i;
+
+ p_LnxWrpFmPortDev->opExtPools.numOfPoolsUsed = params->num_pools;
+ for (i = 0; i < params->num_pools; i++) {
+ p_LnxWrpFmPortDev->opExtPools.extBufPool[i].id = params->pool_param[i].id;
+ p_LnxWrpFmPortDev->opExtPools.extBufPool[i].size = params->pool_param[i].size;
+ }
+
+ if (p_LnxWrpFmPortDev->settings.frag_enabled)
+ ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigExtBufPools,
+ ARGS(1, (&p_LnxWrpFmPortDev->opExtPools)));
+ }
+
+ ADD_ADV_CONFIG_END InitFmPortDev(p_LnxWrpFmPortDev);
+}
+EXPORT_SYMBOL(fm_set_tx_port_params);
+
+void fm_mac_set_handle(t_Handle h_lnx_wrp_fm_dev,
+ t_Handle h_fm_mac,
+ int mac_id)
+{
+ t_LnxWrpFmDev *p_lnx_wrp_fm_dev = (t_LnxWrpFmDev *)h_lnx_wrp_fm_dev;
+
+ p_lnx_wrp_fm_dev->macs[mac_id].h_Dev = h_fm_mac;
+ p_lnx_wrp_fm_dev->macs[mac_id].h_LnxWrpFmDev = h_lnx_wrp_fm_dev;
+}
+EXPORT_SYMBOL(fm_mac_set_handle);
+
+static void LnxwrpFmPcdDevExceptionsCb(t_Handle h_App,
+ e_FmPcdExceptions exception)
+{
+ t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_App;
+
+ ASSERT_COND(p_LnxWrpFmDev);
+
+ DBG(INFO, ("got fm-pcd exception %d", exception));
+
+ /* do nothing */
+ UNUSED(exception);
+}
+
+static void LnxwrpFmPcdDevIndexedExceptionsCb(t_Handle h_App,
+ e_FmPcdExceptions exception,
+ uint16_t index)
+{
+ t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_App;
+
+ ASSERT_COND(p_LnxWrpFmDev);
+
+ DBG(INFO,
+ ("got fm-pcd-indexed exception %d, indx %d", exception, index));
+
+ /* do nothing */
+ UNUSED(exception);
+ UNUSED(index);
+}
+
+static t_Error InitFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
+{
+ spin_lock_init(&lock);
+
+ if (p_LnxWrpFmDev->pcdActive) {
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
+ t_FmPcdParams fmPcdParams;
+ t_Error err;
+
+ memset(&fmPcdParams, 0, sizeof(fmPcdParams));
+ fmPcdParams.h_Fm = p_LnxWrpFmDev->h_Dev;
+ fmPcdParams.prsSupport = p_LnxWrpFmDev->prsActive;
+ fmPcdParams.kgSupport = p_LnxWrpFmDev->kgActive;
+ fmPcdParams.plcrSupport = p_LnxWrpFmDev->plcrActive;
+ fmPcdParams.ccSupport = p_LnxWrpFmDev->ccActive;
+ fmPcdParams.numOfSchemes = FM_PCD_KG_NUM_OF_SCHEMES;
+
+#ifndef CONFIG_GUEST_PARTITION
+ fmPcdParams.f_Exception = LnxwrpFmPcdDevExceptionsCb;
+ if (fmPcdParams.kgSupport)
+ fmPcdParams.f_ExceptionId =
+ LnxwrpFmPcdDevIndexedExceptionsCb;
+ fmPcdParams.h_App = p_LnxWrpFmDev;
+#endif /* !CONFIG_GUEST_PARTITION */
+
+#ifdef CONFIG_MULTI_PARTITION_SUPPORT
+ fmPcdParams.numOfSchemes = 0;
+ fmPcdParams.numOfClsPlanEntries = 0;
+ fmPcdParams.partitionId = 0;
+#endif /* CONFIG_MULTI_PARTITION_SUPPORT */
+ fmPcdParams.useHostCommand = TRUE;
+
+ p_LnxWrpFmDev->hc_tx_fq =
+ FqAlloc(p_LnxWrpFmDev,
+ 0,
+ QMAN_FQ_FLAG_TO_DCPORTAL,
+ p_LnxWrpFmPortDev->txCh, 0);
+ if (!p_LnxWrpFmDev->hc_tx_fq)
+ RETURN_ERROR(MAJOR, E_NULL_POINTER,
+ ("Frame queue allocation failed..."));
+
+ p_LnxWrpFmDev->hc_tx_conf_fq =
+ FqAlloc(p_LnxWrpFmDev,
+ 0,
+ QMAN_FQ_FLAG_NO_ENQUEUE,
+ p_LnxWrpFmDev->hcCh, 1);
+ if (!p_LnxWrpFmDev->hc_tx_conf_fq)
+ RETURN_ERROR(MAJOR, E_NULL_POINTER,
+ ("Frame queue allocation failed..."));
+
+ p_LnxWrpFmDev->hc_tx_err_fq =
+ FqAlloc(p_LnxWrpFmDev,
+ 0,
+ QMAN_FQ_FLAG_NO_ENQUEUE,
+ p_LnxWrpFmDev->hcCh, 2);
+ if (!p_LnxWrpFmDev->hc_tx_err_fq)
+ RETURN_ERROR(MAJOR, E_NULL_POINTER,
+ ("Frame queue allocation failed..."));
+
+ fmPcdParams.hc.portBaseAddr = p_LnxWrpFmPortDev->baseAddr;
+ fmPcdParams.hc.portId =
+ p_LnxWrpFmPortDev->settings.param.portId;
+ fmPcdParams.hc.liodnBase =
+ p_LnxWrpFmPortDev->settings.param.liodnBase;
+ fmPcdParams.hc.errFqid =
+ qman_fq_fqid(p_LnxWrpFmDev->hc_tx_err_fq);
+ fmPcdParams.hc.confFqid =
+ qman_fq_fqid(p_LnxWrpFmDev->hc_tx_conf_fq);
+ fmPcdParams.hc.qmChannel = p_LnxWrpFmPortDev->txCh;
+ fmPcdParams.hc.f_QmEnqueue = QmEnqueueCB;
+ fmPcdParams.hc.h_QmArg = (t_Handle) p_LnxWrpFmDev;
+
+ p_LnxWrpFmDev->h_PcdDev = FM_PCD_Config(&fmPcdParams);
+ if (!p_LnxWrpFmDev->h_PcdDev)
+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM PCD!"));
+
+ err =
+ FM_PCD_ConfigPlcrNumOfSharedProfiles(p_LnxWrpFmDev->h_PcdDev,
+ LNXWRP_FM_NUM_OF_SHARED_PROFILES);
+ if (err != E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ err = FM_PCD_Init(p_LnxWrpFmDev->h_PcdDev);
+ if (err != E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ if (p_LnxWrpFmDev->err_irq == 0) {
+ FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
+ e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC,
+ FALSE);
+ FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
+ e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW,
+ FALSE);
+ FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
+ e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR,
+ FALSE);
+ FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
+ e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC,
+ FALSE);
+ FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
+ e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC,
+ FALSE);
+ FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
+ e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE,
+ FALSE);
+ FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
+ e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE,
+ FALSE);
+ FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
+ e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC,
+ FALSE);
+ }
+ }
+
+ return E_OK;
+}
+
+void FreeFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
+{
+
+ if (p_LnxWrpFmDev->h_PcdDev)
+ FM_PCD_Free(p_LnxWrpFmDev->h_PcdDev);
+
+ if (p_LnxWrpFmDev->hc_tx_err_fq)
+ FqFree(p_LnxWrpFmDev->hc_tx_err_fq);
+
+ if (p_LnxWrpFmDev->hc_tx_conf_fq)
+ FqFree(p_LnxWrpFmDev->hc_tx_conf_fq);
+
+ if (p_LnxWrpFmDev->hc_tx_fq)
+ FqFree(p_LnxWrpFmDev->hc_tx_fq);
+}
+
+static void FreeFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
+{
+ t_LnxWrpFmDev *p_LnxWrpFmDev =
+ (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
+
+ if (!p_LnxWrpFmPortDev->active)
+ return;
+
+ if (p_LnxWrpFmPortDev->h_Dev)
+ FM_PORT_Free(p_LnxWrpFmPortDev->h_Dev);
+
+ devm_iounmap(p_LnxWrpFmDev->dev,
+ UINT_TO_PTR(p_LnxWrpFmPortDev->baseAddr));
+ __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res,
+ p_LnxWrpFmPortDev->phys_baseAddr,
+ p_LnxWrpFmPortDev->memSize);
+}
+
+static int /*__devinit*/ fm_port_probe(struct platform_device *of_dev)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
+ t_LnxWrpFmDev *p_LnxWrpFmDev;
+ struct device *dev;
+
+ dev = &of_dev->dev;
+
+ p_LnxWrpFmPortDev = ReadFmPortDevTreeNode(of_dev);
+ if (p_LnxWrpFmPortDev == NULL)
+ return -EIO;
+ /* Port can be inactive, thus will not be probed:
+ - in performance mode, OH ports are disabled
+ ...
+ */
+ if (!p_LnxWrpFmPortDev->active)
+ return 0;
+
+ if (ConfigureFmPortDev(p_LnxWrpFmPortDev) != E_OK)
+ return -EIO;
+
+ dev_set_drvdata(dev, p_LnxWrpFmPortDev);
+
+ if (p_LnxWrpFmPortDev->settings.param.portType ==
+ e_FM_PORT_TYPE_OH_HOST_COMMAND)
+ InitFmPcdDev((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev);
+
+ p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
+
+ if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX) {
+ Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
+ p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
+ p_LnxWrpFmPortDev->minor =
+ p_LnxWrpFmPortDev->id + DEV_FM_RX_PORTS_MINOR_BASE;
+ } else if (p_LnxWrpFmPortDev->settings.param.portType ==
+ e_FM_PORT_TYPE_RX_10G) {
+ Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
+ p_LnxWrpFmDev->name,
+ p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_RX_PORTS);
+ p_LnxWrpFmPortDev->minor =
+ p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_RX_PORTS +
+ DEV_FM_RX_PORTS_MINOR_BASE;
+#ifndef CONFIG_FMAN_ARM
+ if (IS_T1023_T1024) {
+ Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
+ p_LnxWrpFmDev->name,
+ p_LnxWrpFmPortDev->id);
+ p_LnxWrpFmPortDev->minor =
+ p_LnxWrpFmPortDev->id +
+ DEV_FM_RX_PORTS_MINOR_BASE;
+ }
+#endif
+ } else if (p_LnxWrpFmPortDev->settings.param.portType ==
+ e_FM_PORT_TYPE_TX) {
+ Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
+ p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
+ p_LnxWrpFmPortDev->minor =
+ p_LnxWrpFmPortDev->id + DEV_FM_TX_PORTS_MINOR_BASE;
+ } else if (p_LnxWrpFmPortDev->settings.param.portType ==
+ e_FM_PORT_TYPE_TX_10G) {
+ Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
+ p_LnxWrpFmDev->name,
+ p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_TX_PORTS);
+ p_LnxWrpFmPortDev->minor =
+ p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_TX_PORTS +
+ DEV_FM_TX_PORTS_MINOR_BASE;
+#ifndef CONFIG_FMAN_ARM
+ if (IS_T1023_T1024) {
+ Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
+ p_LnxWrpFmDev->name,
+ p_LnxWrpFmPortDev->id);
+ p_LnxWrpFmPortDev->minor =
+ p_LnxWrpFmPortDev->id +
+ DEV_FM_TX_PORTS_MINOR_BASE;
+ }
+#endif
+ } else if (p_LnxWrpFmPortDev->settings.param.portType ==
+ e_FM_PORT_TYPE_OH_HOST_COMMAND) {
+ Sprint(p_LnxWrpFmPortDev->name, "%s-port-oh%d",
+ p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
+ p_LnxWrpFmPortDev->minor =
+ p_LnxWrpFmPortDev->id + DEV_FM_OH_PORTS_MINOR_BASE;
+ } else if (p_LnxWrpFmPortDev->settings.param.portType ==
+ e_FM_PORT_TYPE_OH_OFFLINE_PARSING) {
+ Sprint(p_LnxWrpFmPortDev->name, "%s-port-oh%d",
+ p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id + 1);
+ p_LnxWrpFmPortDev->minor =
+ p_LnxWrpFmPortDev->id + 1 +
+ DEV_FM_OH_PORTS_MINOR_BASE;
+ }
+
+ device_create(p_LnxWrpFmDev->fm_class, NULL,
+ MKDEV(p_LnxWrpFmDev->major, p_LnxWrpFmPortDev->minor),
+ NULL, p_LnxWrpFmPortDev->name);
+
+ /* create sysfs entries for stats and regs */
+
+ if (fm_port_sysfs_create(dev) != 0) {
+ FreeFmPortDev(p_LnxWrpFmPortDev);
+ REPORT_ERROR(MAJOR, E_INVALID_STATE,
+ ("Unable to create sys entry - fm port!!!"));
+ return -EIO;
+ }
+
+#ifdef FM_TX_INVALID_ECC_ERRATA_10GMAC_A009
+ FM_DisableRamsEcc(p_LnxWrpFmDev->h_Dev);
+#endif /* FM_TX_INVALID_ECC_ERRATA_10GMAC_A009 */
+
+ DBG(TRACE, ("%s probed", p_LnxWrpFmPortDev->name));
+
+ return 0;
+}
+
+static int fm_port_remove(struct platform_device *of_dev)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
+ t_LnxWrpFmDev *p_LnxWrpFmDev;
+ struct device *dev;
+
+ dev = &of_dev->dev;
+ p_LnxWrpFmPortDev = dev_get_drvdata(dev);
+
+ fm_port_sysfs_destroy(dev);
+
+ p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
+ device_destroy(p_LnxWrpFmDev->fm_class,
+ MKDEV(p_LnxWrpFmDev->major, p_LnxWrpFmPortDev->minor));
+
+ FreeFmPortDev(p_LnxWrpFmPortDev);
+
+ dev_set_drvdata(dev, NULL);
+
+ return 0;
+}
+
+static const struct of_device_id fm_port_match[] = {
+ {
+ .compatible = "fsl,fman-port-oh"},
+ {
+ .compatible = "fsl,fman-v2-port-oh"},
+ {
+ .compatible = "fsl,fman-v3-port-oh"},
+ {
+ .compatible = "fsl,fman-port-1g-rx"},
+ {
+ .compatible = "fsl,fman-port-10g-rx"},
+ {
+ .compatible = "fsl,fman-port-1g-tx"},
+ {
+ .compatible = "fsl,fman-port-10g-tx"},
+ {}
+};
+
+#ifndef MODULE
+MODULE_DEVICE_TABLE(of, fm_port_match);
+#endif /* !MODULE */
+
+static struct platform_driver fm_port_driver = {
+
+ .driver = {
+ .name = "fsl-fman-port",
+ .of_match_table = fm_port_match,
+ .owner = THIS_MODULE,
+ },
+ .probe = fm_port_probe,
+ .remove = fm_port_remove
+};
+
+
+t_Error LNXWRP_FM_Port_Init(void)
+{
+ /* Register to the DTB for basic FM port API */
+ if (platform_driver_register(&fm_port_driver))
+ return E_NO_DEVICE;
+
+ return E_OK;
+}
+
+void LNXWRP_FM_Port_Free(void)
+{
+ platform_driver_unregister(&fm_port_driver);
+}
+
+static int __init __cold fm_port_load(void)
+{
+ if (LNXWRP_FM_Port_Init() != E_OK) {
+ printk(KERN_ERR "Failed to init FM Ports wrapper!\n");
+ return -ENODEV;
+ }
+
+ printk(KERN_INFO "Freescale FM Ports module\n");
+
+ return 0;
+}
+
+static void __exit __cold fm_port_unload(void)
+{
+ LNXWRP_FM_Port_Free();
+}
+
+module_init(fm_port_load);
+module_exit(fm_port_unload);
diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c
new file mode 100644
index 000000000000..13900e28fc67
--- /dev/null
+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c
@@ -0,0 +1,4869 @@
+/*
+ * Copyright 2008-2012 Freescale Semiconductor Inc.
+ * Copyright 2021 NXP
+ *
+ * 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_ioctls_fm.c
+ @Author Shlomi Gridish
+ @Description FM Linux wrapper functions.
+*/
+
+/* Linux Headers ------------------- */
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.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/uaccess.h>
+#include <asm/errno.h>
+#ifndef CONFIG_FMAN_ARM
+#include <sysdev/fsl_soc.h>
+#include <linux/fsl/svr.h>
+#endif
+
+#if defined(CONFIG_COMPAT)
+#include <linux/compat.h>
+#endif
+
+#include "part_ext.h"
+#include "fm_ioctls.h"
+#include "fm_pcd_ioctls.h"
+#include "fm_port_ioctls.h"
+#include "fm_vsp_ext.h"
+
+#ifndef CONFIG_FMAN_ARM
+#define IS_T1023_T1024 (SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1024 || \
+ SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1023)
+#endif
+
+#define __ERR_MODULE__ MODULE_FM
+
+#if defined(CONFIG_COMPAT)
+#include "lnxwrp_ioctls_fm_compat.h"
+#endif
+
+#include "lnxwrp_fm.h"
+
+#define CMP_IOC_DEFINE(def) (IOC_##def != def)
+
+/* fm_pcd_ioctls.h === fm_pcd_ext.h assertions */
+#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(FM_PCD_PRS_NUM_OF_HDRS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_GENERIC_REGS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_EXTRACT_MASKS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_DEFAULT_GROUPS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(FM_PCD_PRS_NUM_OF_LABELS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(FM_PCD_SW_PRS_SIZE)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if DPAA_VERSION >= 11
+#if CMP_IOC_DEFINE(FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES)
+#error Error: please synchronize IOC_ defines!
+#endif
+#endif
+
+#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_TREES)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_GROUPS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_UNITS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_KEYS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(FM_PCD_MAX_SIZE_OF_KEY)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(FM_PCD_LAST_KEY_INDEX)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+/* net_ioctls.h === net_ext.h assertions */
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_PID)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_COMPRESSED)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPoE_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPMUX_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ETH_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPv4_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPv6_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ICMP_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IGMP_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_TCP_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SCTP_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_DCCP_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_UDP_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPHC_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv2_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_VLAN_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_LLC_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_NLPID_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SNAP_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS)
+#warning Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ARP_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_RFC2684_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_GRE_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MINENCAP_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MACSEC_ALL_FIELDS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+/* fm_ioctls.h === fm_ext.h assertions */
+#if CMP_IOC_DEFINE(FM_MAX_NUM_OF_VALID_PORTS)
+#error Error: please synchronize IOC_ defines!
+#endif
+
+void LnxWrpPCDIOCTLTypeChecking(void)
+{
+ /* fm_ext.h == fm_ioctls.h */
+ ASSERT_COND(sizeof(ioc_fm_port_bandwidth_params) == sizeof(t_FmPortsBandwidthParams));
+ ASSERT_COND(sizeof(ioc_fm_revision_info_t) == sizeof(t_FmRevisionInfo));
+
+ /* fm_pcd_ext.h == fm_pcd_ioctls.h */
+ /*ioc_fm_pcd_counters_params_t : NOT USED */
+ /*ioc_fm_pcd_exception_params_t : private */
+#if (DPAA_VERSION >= 11)
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_capwap_params_t) == sizeof(t_FmPcdManipFragCapwapParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_capwap_params_t) == sizeof(t_FmPcdManipReassemCapwapParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t) == sizeof(t_FmPcdManipHdrInsrtByHdrParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_ip_params_t) == sizeof(t_FmPcdManipHdrInsrtIpParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_t) == sizeof(t_FmPcdManipHdrInsrt));
+ ASSERT_COND(sizeof(ioc_fm_manip_hdr_info_t) == sizeof(t_FmManipHdrInfo));
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t) == sizeof(t_FmPcdManipHdrRmvByHdrParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_capwap_params_t) == sizeof(t_FmPcdManipSpecialOffloadCapwapParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_capwap_stats_t) == sizeof(t_FmPcdManipFragCapwapStats));
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_capwap_stats_t) == sizeof(t_FmPcdManipReassemCapwapStats));
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_params_t) == sizeof(t_FmPcdManipFragParams));
+#endif /* (DPAA_VERSION >= 11) */
+
+ ASSERT_COND(sizeof(ioc_fm_pcd_prs_label_params_t) == sizeof(t_FmPcdPrsLabelParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_prs_sw_params_t) == sizeof(t_FmPcdPrsSwParams));
+ /*ioc_fm_pcd_kg_dflt_value_params_t : private */
+ ASSERT_COND(sizeof(ioc_fm_pcd_hdr_protocol_opt_u) == sizeof(u_FmPcdHdrProtocolOpt));
+ ASSERT_COND(sizeof(ioc_fm_pcd_fields_u) == sizeof(t_FmPcdFields));
+ ASSERT_COND(sizeof(ioc_fm_pcd_from_hdr_t) == sizeof(t_FmPcdFromHdr));
+ ASSERT_COND(sizeof(ioc_fm_pcd_from_field_t) == sizeof(t_FmPcdFromField));
+ ASSERT_COND(sizeof(ioc_fm_pcd_distinction_unit_t) == sizeof(t_FmPcdDistinctionUnit));
+
+#if defined(CONFIG_ARM64)
+ /* different alignment */
+ ASSERT_COND(sizeof(ioc_fm_pcd_net_env_params_t) == sizeof(t_FmPcdNetEnvParams) + sizeof(void *) + 4);
+#else
+#if !defined(CONFIG_COMPAT)
+ /* different alignment */
+ ASSERT_COND(sizeof(ioc_fm_pcd_net_env_params_t) == sizeof(t_FmPcdNetEnvParams) + sizeof(void *));
+#endif
+#endif
+ ASSERT_COND(sizeof(ioc_fm_pcd_extract_entry_t) == sizeof(t_FmPcdExtractEntry));
+ ASSERT_COND(sizeof(ioc_fm_pcd_kg_extract_mask_t) == sizeof(t_FmPcdKgExtractMask));
+ ASSERT_COND(sizeof(ioc_fm_pcd_kg_extract_dflt_t) == sizeof(t_FmPcdKgExtractDflt));
+ ASSERT_COND(sizeof(ioc_fm_pcd_kg_key_extract_and_hash_params_t) == sizeof(t_FmPcdKgKeyExtractAndHashParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_kg_extracted_or_params_t) == sizeof(t_FmPcdKgExtractedOrParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_counter_t) == sizeof(t_FmPcdKgSchemeCounter));
+ ASSERT_COND(sizeof(ioc_fm_pcd_kg_plcr_profile_t) == sizeof(t_FmPcdKgPlcrProfile));
+#if (DPAA_VERSION >= 11)
+ ASSERT_COND(sizeof(ioc_fm_pcd_kg_storage_profile_t) == sizeof(t_FmPcdKgStorageProfile));
+#endif
+ ASSERT_COND(sizeof(ioc_fm_pcd_kg_cc_t) == sizeof(t_FmPcdKgCc));
+#if !defined(CONFIG_COMPAT)
+ /* different alignment */
+ ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_params_t) == sizeof(t_FmPcdKgSchemeParams) + sizeof(void *));
+#endif
+ ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_cc_params_t) == sizeof(t_FmPcdCcNextCcParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_plcr_params_t) == sizeof(t_FmPcdCcNextPlcrParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_enqueue_params_t) == sizeof(t_FmPcdCcNextEnqueueParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_kg_params_t) == sizeof(t_FmPcdCcNextKgParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_engine_params_t) == sizeof(t_FmPcdCcNextEngineParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_cc_key_params_t) == sizeof(t_FmPcdCcKeyParams));
+ ASSERT_COND(sizeof(ioc_keys_params_t) == sizeof(t_KeysParams));
+#if !defined(CONFIG_COMPAT)
+ /* different alignment */
+ ASSERT_COND(sizeof(ioc_fm_pcd_cc_node_params_t) == sizeof(t_FmPcdCcNodeParams) + sizeof(void *));
+ ASSERT_COND(sizeof(ioc_fm_pcd_hash_table_params_t) == sizeof(t_FmPcdHashTableParams) + sizeof(void *));
+#endif
+ ASSERT_COND(sizeof(ioc_fm_pcd_cc_grp_params_t) == sizeof(t_FmPcdCcGrpParams));
+#if !defined(CONFIG_COMPAT)
+ /* different alignment */
+ ASSERT_COND(sizeof(ioc_fm_pcd_cc_tree_params_t) == sizeof(t_FmPcdCcTreeParams) + sizeof(void *));
+#endif
+ ASSERT_COND(sizeof(ioc_fm_pcd_plcr_byte_rate_mode_param_t) == sizeof(t_FmPcdPlcrByteRateModeParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t) == sizeof(t_FmPcdPlcrNonPassthroughAlgParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_plcr_next_engine_params_u) == sizeof(u_FmPcdPlcrNextEngineParams));
+ /*ioc_fm_pcd_port_params_t : private */
+ ASSERT_COND(sizeof(ioc_fm_pcd_plcr_profile_params_t) == sizeof(t_FmPcdPlcrProfileParams) + sizeof(void *));
+ /*ioc_fm_pcd_cc_tree_modify_next_engine_params_t : private */
+
+#ifdef FM_CAPWAP_SUPPORT
+#error TODO: unsupported feature
+/*
+ ASSERT_COND(sizeof(TODO) == sizeof(t_FmPcdManipHdrInsrtByTemplateParams));
+ ASSERT_COND(sizeof(TODO) == sizeof(t_CapwapFragmentationParams));
+ ASSERT_COND(sizeof(TODO) == sizeof(t_CapwapReassemblyParams));
+*/
+#endif
+
+ /*ioc_fm_pcd_cc_node_modify_next_engine_params_t : private */
+ /*ioc_fm_pcd_cc_node_remove_key_params_t : private */
+ /*ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t : private */
+ /*ioc_fm_pcd_cc_node_modify_key_params_t : private */
+ /*ioc_fm_manip_hdr_info_t : private */
+ /*ioc_fm_pcd_hash_table_set_t : private */
+
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_ip_params_t) == sizeof(t_FmPcdManipFragIpParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_ip_params_t) == sizeof(t_FmPcdManipReassemIpParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_ipsec_params_t) == sizeof(t_FmPcdManipSpecialOffloadIPSecParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_params_t) == sizeof(t_FmPcdManipSpecialOffloadParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_generic_params_t) == sizeof(t_FmPcdManipHdrRmvGenericParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_generic_params_t) == sizeof(t_FmPcdManipHdrInsrtGenericParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_params_t) == sizeof(t_FmPcdManipHdrInsrtParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_params_t) == sizeof(t_FmPcdManipHdrRmvParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_params_t) == sizeof(t_FmPcdManipHdrParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_params_t) == sizeof(t_FmPcdManipFragParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_params_t) == sizeof(t_FmPcdManipReassemParams));
+#if !defined(CONFIG_COMPAT)
+ /* different alignment */
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_params_t) == sizeof(t_FmPcdManipParams) + sizeof(void *));
+#endif
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_ip_stats_t) == sizeof(t_FmPcdManipReassemIpStats));
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_ip_stats_t) == sizeof(t_FmPcdManipFragIpStats));
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_stats_t) == sizeof(t_FmPcdManipReassemStats));
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_stats_t) == sizeof(t_FmPcdManipFragStats));
+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_stats_t) == sizeof(t_FmPcdManipStats));
+#if DPAA_VERSION >= 11
+ ASSERT_COND(sizeof(ioc_fm_pcd_frm_replic_group_params_t) == sizeof(t_FmPcdFrmReplicGroupParams) + sizeof(void *));
+#endif
+
+ /* fm_port_ext.h == fm_port_ioctls.h */
+ ASSERT_COND(sizeof(ioc_fm_port_rate_limit_t) == sizeof(t_FmPortRateLimit));
+ ASSERT_COND(sizeof(ioc_fm_port_pcd_params_t) == sizeof(t_FmPortPcdParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_select_t) == sizeof(t_FmPcdKgSchemeSelect));
+ ASSERT_COND(sizeof(ioc_fm_pcd_port_schemes_params_t) == sizeof(t_FmPcdPortSchemesParams));
+ ASSERT_COND(sizeof(ioc_fm_pcd_prs_start_t) == sizeof(t_FmPcdPrsStart));
+
+ return;
+}
+
+#define ASSERT_IOC_NET_ENUM(def) ASSERT_COND((unsigned long)e_IOC_NET_##def == (unsigned long)def)
+
+void LnxWrpPCDIOCTLEnumChecking(void)
+{
+ /* net_ext.h == net_ioctls.h : sampling checks */
+ ASSERT_IOC_NET_ENUM(HEADER_TYPE_MACSEC);
+ ASSERT_IOC_NET_ENUM(HEADER_TYPE_PPP);
+ ASSERT_IOC_NET_ENUM(MAX_HEADER_TYPE_COUNT);
+
+ /* fm_ext.h == fm_ioctls.h */
+ ASSERT_COND((unsigned long)e_IOC_FM_PORT_TYPE_DUMMY == (unsigned long)e_FM_PORT_TYPE_DUMMY);
+ ASSERT_COND((unsigned long)e_IOC_EX_MURAM_ECC == (unsigned long)e_FM_EX_MURAM_ECC);
+ ASSERT_COND((unsigned long)e_IOC_FM_COUNTERS_DEQ_CONFIRM == (unsigned long)e_FM_COUNTERS_DEQ_CONFIRM);
+
+ /* fm_pcd_ext.h == fm_pcd_ioctls.h */
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES == (unsigned long)e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES);
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_PRS_EXCEPTION_SINGLE_ECC == (unsigned long)e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC);
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_PRS == (unsigned long)e_FM_PCD_PRS);
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_EXTRACT_FULL_FIELD == (unsigned long)e_FM_PCD_EXTRACT_FULL_FIELD);
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_EXTRACT_FROM_FLOW_ID == (unsigned long)e_FM_PCD_EXTRACT_FROM_FLOW_ID);
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO == (unsigned long)e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO);
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_DFLT_ILLEGAL == (unsigned long)e_FM_PCD_KG_DFLT_ILLEGAL);
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_GENERIC_NOT_FROM_DATA == (unsigned long)e_FM_PCD_KG_GENERIC_NOT_FROM_DATA);
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_HDR_INDEX_LAST == (unsigned long)e_FM_PCD_HDR_INDEX_LAST);
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_SHARED == (unsigned long)e_FM_PCD_PLCR_SHARED);
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_RFC_4115 == (unsigned long)e_FM_PCD_PLCR_RFC_4115);
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_COLOR_AWARE == (unsigned long)e_FM_PCD_PLCR_COLOR_AWARE);
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_OVERRIDE == (unsigned long)e_FM_PCD_PLCR_OVERRIDE);
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_FULL_FRM_LEN == (unsigned long)e_FM_PCD_PLCR_FULL_FRM_LEN);
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN == (unsigned long)e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN);
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_PACKET_MODE == (unsigned long)e_FM_PCD_PLCR_PACKET_MODE);
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_DROP_FRAME == (unsigned long)e_FM_PCD_DROP_FRAME);
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER == (unsigned long)e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER);
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP == (unsigned long)e_FM_PCD_ACTION_INDEXED_LOOKUP);
+ ASSERT_COND((unsigned long)e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR == (unsigned long)e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR);
+#if !defined(FM_CAPWAP_SUPPORT)
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_INSRT_GENERIC == (unsigned long)e_FM_PCD_MANIP_INSRT_GENERIC);
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_RMV_GENERIC == (unsigned long)e_FM_PCD_MANIP_RMV_GENERIC);
+#else
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE == (unsigned long)e_FM_PCD_MANIP_INSRT_BY_TEMPLATE);
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_RMV_BY_HDR == (unsigned long)e_FM_PCD_MANIP_RMV_BY_HDR);
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_RMV_BY_HDR_FROM_START == (unsigned long)e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START);
+#endif
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG == (unsigned long)e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG);
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH == (unsigned long)e_FM_PCD_MANIP_EIGHT_WAYS_HASH);
+
+#ifdef FM_CAPWAP_SUPPORT
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_STATS_PER_FLOWID == (unsigned long)e_FM_PCD_STATS_PER_FLOWID);
+#endif
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD == (unsigned long)e_FM_PCD_MANIP_SPECIAL_OFFLOAD);
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_CC_STATS_MODE_FRAME == (unsigned long)e_FM_PCD_CC_STATS_MODE_FRAME);
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG == (unsigned long)e_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG);
+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC == (unsigned long)e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC);
+
+ /* fm_port_ext.h == fm_port_ioctls.h */
+#if !defined(FM_CAPWAP_SUPPORT)
+ ASSERT_COND((unsigned long)e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR == (unsigned long)e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR);
+#else
+ ASSERT_COND((unsigned long)e_IOC_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR == (unsigned long)e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR);
+#endif
+ ASSERT_COND((unsigned long)e_IOC_FM_PORT_COUNTERS_DEQ_CONFIRM == (unsigned long)e_FM_PORT_COUNTERS_DEQ_CONFIRM);
+ ASSERT_COND((unsigned long)e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8 == (unsigned long)e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8);
+
+ return;
+}
+
+static t_Error LnxwrpFmPcdIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat)
+{
+ t_Error err = E_OK;
+
+/*
+Status: PCD API to fmlib (file: drivers/net/dpa/NetCommSw/inc/Peripherals/fm_pcd_ext.h):
+
+ FM_PCD_PrsLoadSw
+ FM_PCD_SetAdvancedOffloadSupport
+ FM_PCD_Enable
+ FM_PCD_Disable
+ FM_PCD_ForceIntr
+ FM_PCD_AllowHcUsage
+ FM_PCD_SetException
+ FM_PCD_KgSetAdditionalDataAfterParsing
+ FM_PCD_KgSetDfltValue
+ FM_PCD_NetEnvCharacteristicsSet
+ FM_PCD_NetEnvCharacteristicsDelete
+ FM_PCD_KgSchemeSet
+ FM_PCD_KgSchemeDelete
+ FM_PCD_MatchTableSet
+ FM_PCD_MatchTableDelete
+ FM_PCD_CcRootBuild
+ FM_PCD_CcRootDelete
+ FM_PCD_PlcrProfileSet
+ FM_PCD_PlcrProfileDelete
+ FM_PCD_CcRootModifyNextEngine
+ FM_PCD_MatchTableModifyNextEngine
+ FM_PCD_MatchTableModifyMissNextEngine
+ FM_PCD_MatchTableRemoveKey
+ FM_PCD_MatchTableAddKey
+ FM_PCD_MatchTableModifyKeyAndNextEngine
+ FM_PCD_HashTableSet
+ FM_PCD_HashTableDelete
+ FM_PCD_HashTableAddKey
+ FM_PCD_HashTableRemoveKey
+ FM_PCD_MatchTableModifyKey
+ FM_PCD_ManipNodeReplace
+ FM_PCD_ManipNodeSet
+ FM_PCD_ManipNodeDelete
+
+Status: not exported, should be thru sysfs
+ FM_PCD_KgSchemeGetCounter
+ FM_PCD_KgSchemeSetCounter
+ FM_PCD_PlcrProfileGetCounter
+ FM_PCD_PlcrProfileSetCounter
+
+Status: not exported
+ FM_PCD_MatchTableFindNRemoveKey
+ FM_PCD_MatchTableFindNModifyNextEngine
+ FM_PCD_MatchTableFindNModifyKeyAndNextEngine
+ FM_PCD_MatchTableFindNModifyKey
+ FM_PCD_MatchTableGetIndexedHashBucket
+ FM_PCD_MatchTableGetNextEngine
+ FM_PCD_MatchTableGetKeyCounter
+
+Status: not exported, would be nice to have
+ FM_PCD_HashTableModifyNextEngine
+ FM_PCD_HashTableModifyMissNextEngine
+ FM_PCD_HashTableGetMissNextEngine
+ FM_PCD_ManipGetStatistics
+
+Status: not exported
+#if DPAA_VERSION >= 11
+
+ FM_VSP_GetStatistics -- it's not available yet
+#endif
+
+Status: feature not supported
+#ifdef FM_CAPWAP_SUPPORT
+#error unsupported feature
+ FM_PCD_StatisticsSetNode
+#endif
+
+ */
+ _fm_ioctl_dbg("cmd:0x%08x(type:0x%02x, nr:%u).\n",
+ cmd, _IOC_TYPE(cmd), _IOC_NR(cmd) - 20);
+
+ switch (cmd)
+ {
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_PRS_LOAD_SW_COMPAT:
+#endif
+ case FM_PCD_IOC_PRS_LOAD_SW:
+ {
+ ioc_fm_pcd_prs_sw_params_t *param;
+ uint8_t *p_code;
+
+ param = (ioc_fm_pcd_prs_sw_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_prs_sw_params_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(param, 0, sizeof(ioc_fm_pcd_prs_sw_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_prs_sw_params_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_prs_sw_params_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_prs_sw_params_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_prs_sw_params_t));
+ if (copy_from_user(compat_param,
+ (ioc_compat_fm_pcd_prs_sw_params_t *) compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_prs_sw_params_t)))
+ {
+ XX_Free(compat_param);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ compat_fm_pcd_prs_sw(compat_param, param, COMPAT_US_TO_K);
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_pcd_prs_sw_params_t *)arg,
+ sizeof(ioc_fm_pcd_prs_sw_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ if (!param->p_code || !param->size)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ p_code = (uint8_t *) XX_Malloc(param->size);
+ if (!p_code)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(p_code, 0, param->size);
+ if (copy_from_user(p_code, param->p_code, param->size))
+ {
+ XX_Free(p_code);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ param->p_code = p_code;
+
+ err = FM_PCD_PrsLoadSw(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdPrsSwParams*)param);
+
+ XX_Free(p_code);
+ XX_Free(param);
+ break;
+ }
+
+ case FM_PCD_IOC_SET_ADVANCED_OFFLOAD_SUPPORT:
+ err = FM_PCD_SetAdvancedOffloadSupport(p_LnxWrpFmDev->h_PcdDev);
+ break;
+
+ case FM_PCD_IOC_ENABLE:
+ err = FM_PCD_Enable(p_LnxWrpFmDev->h_PcdDev);
+ break;
+
+ case FM_PCD_IOC_DISABLE:
+ err = FM_PCD_Disable(p_LnxWrpFmDev->h_PcdDev);
+ break;
+
+ case FM_PCD_IOC_FORCE_INTR:
+ {
+ int exception;
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ if (get_user(exception, (int *) compat_ptr(arg)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ else
+#endif
+ {
+ if (get_user(exception, (int *)arg))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ err = FM_PCD_ForceIntr(p_LnxWrpFmDev->h_PcdDev, (e_FmPcdExceptions)exception);
+ break;
+ }
+
+ case FM_PCD_IOC_ALLOW_HC_USAGE:
+ {
+ uint8_t allow_hc;
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ if (get_user(allow_hc, (uint8_t *) compat_ptr(arg)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ else
+#endif
+ {
+ if (get_user(allow_hc, (uint8_t *)arg))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ err = FM_PCD_AllowHcUsage(p_LnxWrpFmDev->h_PcdDev, allow_hc);
+ break;
+ }
+
+ case FM_PCD_IOC_SET_EXCEPTION:
+ {
+ ioc_fm_pcd_exception_params_t *param;
+
+ param = (ioc_fm_pcd_exception_params_t *) XX_Malloc(
+ sizeof(ioc_fm_pcd_exception_params_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(param, 0, sizeof(ioc_fm_pcd_exception_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ if (copy_from_user(param, (ioc_fm_pcd_exception_params_t *)compat_ptr(arg),
+ sizeof(ioc_fm_pcd_exception_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_pcd_exception_params_t *)arg,
+ sizeof(ioc_fm_pcd_exception_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ err = FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev, param->exception, param->enable);
+
+ XX_Free(param);
+ break;
+ }
+
+ case FM_PCD_IOC_KG_SET_ADDITIONAL_DATA_AFTER_PARSING:
+ {
+ uint8_t payloadOffset;
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ if (get_user(payloadOffset, (uint8_t*) compat_ptr(arg)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ else
+#endif
+ {
+ if (get_user(payloadOffset, (uint8_t*) arg))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ err = FM_PCD_KgSetAdditionalDataAfterParsing(p_LnxWrpFmDev->h_PcdDev, payloadOffset);
+ break;
+ }
+
+ case FM_PCD_IOC_KG_SET_DFLT_VALUE:
+ {
+ ioc_fm_pcd_kg_dflt_value_params_t *param;
+
+ param = (ioc_fm_pcd_kg_dflt_value_params_t *) XX_Malloc(
+ sizeof(ioc_fm_pcd_kg_dflt_value_params_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(param, 0, sizeof(ioc_fm_pcd_kg_dflt_value_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ if (copy_from_user(param, (ioc_fm_pcd_kg_dflt_value_params_t *)compat_ptr(arg),
+ sizeof(ioc_fm_pcd_kg_dflt_value_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_pcd_kg_dflt_value_params_t *)arg,
+ sizeof(ioc_fm_pcd_kg_dflt_value_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ err = FM_PCD_KgSetDfltValue(p_LnxWrpFmDev->h_PcdDev, param->valueId, param->value);
+
+ XX_Free(param);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET_COMPAT:
+#endif
+ case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET:
+ {
+ ioc_fm_pcd_net_env_params_t *param;
+
+ param = (ioc_fm_pcd_net_env_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_net_env_params_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(param, 0, sizeof(ioc_fm_pcd_net_env_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_net_env_params_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_net_env_params_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_net_env_params_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_net_env_params_t));
+ if (copy_from_user(compat_param, (ioc_compat_fm_pcd_net_env_params_t *) compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_net_env_params_t)))
+ {
+ XX_Free(compat_param);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ compat_copy_fm_pcd_net_env(compat_param, param, COMPAT_US_TO_K);
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_pcd_net_env_params_t *) arg,
+ sizeof(ioc_fm_pcd_net_env_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ param->id = FM_PCD_NetEnvCharacteristicsSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdNetEnvParams*)param);
+
+ if (!param->id)
+ {
+ XX_Free(param);
+ err = E_INVALID_VALUE;
+ /* Since the LLD has no errno-style error reporting,
+ we're left here with no other option than to report
+ a generic E_INVALID_VALUE */
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_net_env_params_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_net_env_params_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_net_env_params_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_net_env_params_t));
+ compat_copy_fm_pcd_net_env(compat_param, param, COMPAT_K_TO_US);
+
+ if (copy_to_user((ioc_compat_fm_pcd_net_env_params_t *) compat_ptr(arg),
+ compat_param,
+ sizeof(ioc_compat_fm_pcd_net_env_params_t)))
+ err = E_READ_FAILED;
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_to_user((ioc_fm_pcd_net_env_params_t *)arg,
+ param,
+ sizeof(ioc_fm_pcd_net_env_params_t)))
+ err = E_READ_FAILED;
+ }
+
+ XX_Free(param);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT:
+#endif
+ case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE:
+ {
+ ioc_fm_obj_t id;
+
+ memset(&id, 0 , sizeof(ioc_fm_obj_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_obj_t compat_id;
+
+ if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ compat_obj_delete(&compat_id, &id);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ err = FM_PCD_NetEnvCharacteristicsDelete(id.obj);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_KG_SCHEME_SET_COMPAT:
+#endif
+ case FM_PCD_IOC_KG_SCHEME_SET:
+ {
+ ioc_fm_pcd_kg_scheme_params_t *param;
+
+ param = (ioc_fm_pcd_kg_scheme_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_kg_scheme_params_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_kg_scheme_params_t *compat_param = NULL;
+
+ compat_param = (ioc_compat_fm_pcd_kg_scheme_params_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
+
+ if (copy_from_user(compat_param, (ioc_compat_fm_pcd_kg_scheme_params_t *) compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_kg_scheme_params_t)))
+ {
+ XX_Free(compat_param);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ compat_copy_fm_pcd_kg_scheme(compat_param, param, COMPAT_US_TO_K);
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_params_t *)arg,
+ sizeof(ioc_fm_pcd_kg_scheme_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ param->id = FM_PCD_KgSchemeSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdKgSchemeParams*)param);
+
+ if (!param->id)
+ {
+ XX_Free(param);
+ err = E_INVALID_VALUE;
+ /* Since the LLD has no errno-style error reporting,
+ we're left here with no other option than to report
+ a generic E_INVALID_VALUE */
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_kg_scheme_params_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_kg_scheme_params_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
+ compat_copy_fm_pcd_kg_scheme(compat_param, param, COMPAT_K_TO_US);
+ if (copy_to_user((ioc_compat_fm_pcd_kg_scheme_params_t *)compat_ptr(arg),
+ compat_param,
+ sizeof(ioc_compat_fm_pcd_kg_scheme_params_t)))
+ err = E_READ_FAILED;
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_to_user((ioc_fm_pcd_kg_scheme_params_t *)arg,
+ param,
+ sizeof(ioc_fm_pcd_kg_scheme_params_t)))
+ err = E_READ_FAILED;
+ }
+
+ XX_Free(param);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_KG_SCHEME_GET_CNTR_COMPAT:
+#endif
+ case FM_PCD_IOC_KG_SCHEME_GET_CNTR:
+ {
+ ioc_fm_pcd_kg_scheme_spc_t *param;
+
+ param = (ioc_fm_pcd_kg_scheme_spc_t *) XX_Malloc(sizeof(ioc_fm_pcd_kg_scheme_spc_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_spc_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param = NULL;
+
+ compat_param = (ioc_compat_fm_pcd_kg_scheme_spc_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
+
+ if (copy_from_user(compat_param, (ioc_compat_fm_pcd_kg_scheme_spc_t *) compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t)))
+ {
+ XX_Free(compat_param);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ compat_copy_fm_pcd_kg_scheme_spc(compat_param, param, COMPAT_US_TO_K);
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_spc_t *)arg,
+ sizeof(ioc_fm_pcd_kg_scheme_spc_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ param->val = FM_PCD_KgSchemeGetCounter((t_Handle)param->id);
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_kg_scheme_spc_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
+ compat_copy_fm_pcd_kg_scheme_spc(compat_param, param, COMPAT_K_TO_US);
+ if (copy_to_user((ioc_compat_fm_pcd_kg_scheme_spc_t *)compat_ptr(arg),
+ compat_param,
+ sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t)))
+ err = E_READ_FAILED;
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_to_user((ioc_fm_pcd_kg_scheme_spc_t *)arg,
+ param,
+ sizeof(ioc_fm_pcd_kg_scheme_spc_t)))
+ err = E_READ_FAILED;
+ }
+
+ XX_Free(param);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT:
+#endif
+ case FM_PCD_IOC_KG_SCHEME_DELETE:
+ {
+ ioc_fm_obj_t id;
+
+ memset(&id, 0 , sizeof(ioc_fm_obj_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_obj_t compat_id;
+
+ if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ compat_obj_delete(&compat_id, &id);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ err = FM_PCD_KgSchemeDelete(id.obj);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_MATCH_TABLE_SET_COMPAT:
+#endif
+ case FM_PCD_IOC_MATCH_TABLE_SET:
+ {
+ ioc_fm_pcd_cc_node_params_t *param;
+ uint8_t *keys;
+ uint8_t *masks;
+ int i,k;
+
+ param = (ioc_fm_pcd_cc_node_params_t *) XX_Malloc(
+ sizeof(ioc_fm_pcd_cc_node_params_t) +
+ 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(param, 0, sizeof(ioc_fm_pcd_cc_node_params_t) +
+ 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
+
+ keys = (uint8_t *) (param + 1);
+ masks = keys + IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY;
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_cc_node_params_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_cc_node_params_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
+ 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
+ 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
+
+ if (copy_from_user(compat_param,
+ (ioc_compat_fm_pcd_cc_node_params_t *)compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_cc_node_params_t)))
+ {
+ XX_Free(compat_param);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ compat_copy_fm_pcd_cc_node(compat_param, param, COMPAT_US_TO_K);
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_pcd_cc_node_params_t *)arg, sizeof(ioc_fm_pcd_cc_node_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ ASSERT_COND(param->keys_params.num_of_keys <= IOC_FM_PCD_MAX_NUM_OF_KEYS);
+ ASSERT_COND(param->keys_params.key_size <= IOC_FM_PCD_MAX_SIZE_OF_KEY);
+
+ /* support for indexed lookup */
+ if( !(param->extract_cc_params.type == e_IOC_FM_PCD_EXTRACT_NON_HDR &&
+ param->extract_cc_params.extract_params.extract_non_hdr.src == e_IOC_FM_PCD_EXTRACT_FROM_HASH &&
+ param->extract_cc_params.extract_params.extract_non_hdr.action == e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP))
+ {
+ for (i=0, k=0;
+ i < param->keys_params.num_of_keys;
+ i++, k += IOC_FM_PCD_MAX_SIZE_OF_KEY)
+ {
+ if (param->keys_params.key_params[i].p_key &&
+ param->keys_params.key_size)
+ {
+ if (copy_from_user(&keys[k],
+ param->keys_params.key_params[i].p_key,
+ param->keys_params.key_size))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ param->keys_params.key_params[i].p_key = &keys[k];
+ }
+
+ if (param->keys_params.key_params[i].p_mask)
+ {
+ if (copy_from_user(&masks[k],
+ param->keys_params.key_params[i].p_mask,
+ param->keys_params.key_size))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ param->keys_params.key_params[i].p_mask = &masks[k];
+ }
+ }
+ }
+
+ param->id = FM_PCD_MatchTableSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdCcNodeParams*)param);
+
+ if (!param->id) {
+ XX_Free(param);
+ err = E_INVALID_VALUE;
+ /* Since the LLD has no errno-style error reporting,
+ we're left here with no other option than to report
+ a generic E_INVALID_VALUE */
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_cc_node_params_t *compat_param;
+ compat_param = (ioc_compat_fm_pcd_cc_node_params_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
+ 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
+ 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
+ compat_copy_fm_pcd_cc_node(compat_param, param, COMPAT_K_TO_US);
+
+ if (copy_to_user((ioc_compat_fm_pcd_cc_node_params_t *)compat_ptr(arg),
+ compat_param,
+ sizeof(ioc_compat_fm_pcd_cc_node_params_t)))
+ err = E_READ_FAILED;
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_to_user((ioc_fm_pcd_cc_node_params_t *)arg,
+ param,
+ sizeof(ioc_fm_pcd_cc_node_params_t)))
+ err = E_READ_FAILED;
+ }
+
+ XX_Free(param);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT:
+#endif
+ case FM_PCD_IOC_MATCH_TABLE_DELETE:
+ {
+ ioc_fm_obj_t id;
+
+ memset(&id, 0 , sizeof(ioc_fm_obj_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_obj_t compat_id;
+
+ if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ compat_obj_delete(&compat_id, &id);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ err = FM_PCD_MatchTableDelete(id.obj);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_CC_ROOT_BUILD_COMPAT:
+#endif
+ case FM_PCD_IOC_CC_ROOT_BUILD:
+ {
+ ioc_fm_pcd_cc_tree_params_t *param;
+
+ param = (ioc_fm_pcd_cc_tree_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_cc_tree_params_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(param, 0, sizeof(ioc_fm_pcd_cc_tree_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_cc_tree_params_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_cc_tree_params_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
+ if (copy_from_user(compat_param,
+ (ioc_compat_fm_pcd_cc_tree_params_t *)compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_cc_tree_params_t)))
+ {
+ XX_Free(compat_param);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ compat_copy_fm_pcd_cc_tree(compat_param, param, COMPAT_US_TO_K);
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_pcd_cc_tree_params_t *)arg,
+ sizeof(ioc_fm_pcd_cc_tree_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ param->id = FM_PCD_CcRootBuild(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdCcTreeParams*)param);
+
+ if (!param->id) {
+ XX_Free(param);
+ err = E_INVALID_VALUE;
+ /* Since the LLD has no errno-style error reporting,
+ we're left here with no other option than to report
+ a generic E_INVALID_VALUE */
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_cc_tree_params_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_cc_tree_params_t *) XX_Malloc(sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
+
+ compat_copy_fm_pcd_cc_tree(compat_param, param, COMPAT_K_TO_US);
+
+ if (copy_to_user((ioc_compat_fm_pcd_cc_tree_params_t *)compat_ptr(arg),
+ compat_param,
+ sizeof(ioc_compat_fm_pcd_cc_tree_params_t)))
+ err = E_READ_FAILED;
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_to_user((ioc_fm_pcd_cc_tree_params_t *)arg,
+ param,
+ sizeof(ioc_fm_pcd_cc_tree_params_t)))
+ err = E_READ_FAILED;
+ }
+
+ XX_Free(param);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_CC_ROOT_DELETE_COMPAT:
+#endif
+ case FM_PCD_IOC_CC_ROOT_DELETE:
+ {
+ ioc_fm_obj_t id;
+
+ memset(&id, 0 , sizeof(ioc_fm_obj_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_obj_t compat_id;
+
+ if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ compat_obj_delete(&compat_id, &id);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ err = FM_PCD_CcRootDelete(id.obj);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_PLCR_PROFILE_SET_COMPAT:
+#endif
+ case FM_PCD_IOC_PLCR_PROFILE_SET:
+ {
+ ioc_fm_pcd_plcr_profile_params_t *param;
+
+ param = (ioc_fm_pcd_plcr_profile_params_t *) XX_Malloc(
+ sizeof(ioc_fm_pcd_plcr_profile_params_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(param, 0, sizeof(ioc_fm_pcd_plcr_profile_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_plcr_profile_params_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_plcr_profile_params_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
+ if (copy_from_user(compat_param, (
+ ioc_compat_fm_pcd_plcr_profile_params_t *)compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_plcr_profile_params_t)))
+ {
+ XX_Free(compat_param);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ compat_copy_fm_pcd_plcr_profile(compat_param, param, COMPAT_US_TO_K);
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_pcd_plcr_profile_params_t *)arg,
+ sizeof(ioc_fm_pcd_plcr_profile_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ if (!param->modify &&
+ (((t_FmPcdPlcrProfileParams*)param)->id.newParams.profileType != e_FM_PCD_PLCR_SHARED))
+ {
+ t_Handle h_Port;
+ ioc_fm_pcd_port_params_t *port_params;
+
+ port_params = (ioc_fm_pcd_port_params_t*) XX_Malloc(sizeof(ioc_fm_pcd_port_params_t));
+ if (!port_params)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(port_params, 0, sizeof(ioc_fm_pcd_port_params_t));
+ if (copy_from_user(port_params, (ioc_fm_pcd_port_params_t*)((t_FmPcdPlcrProfileParams*)param)->id.newParams.h_FmPort,
+ sizeof(ioc_fm_pcd_port_params_t)))
+ {
+ XX_Free(port_params);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ switch(port_params->port_type)
+ {
+ case (e_IOC_FM_PORT_TYPE_RX):
+ if (port_params->port_id < FM_MAX_NUM_OF_1G_RX_PORTS) {
+ h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id].h_Dev;
+ break;
+ }
+ goto invalid_port_id;
+
+ case (e_IOC_FM_PORT_TYPE_RX_10G):
+ if (port_params->port_id < FM_MAX_NUM_OF_10G_RX_PORTS) {
+#ifndef CONFIG_FMAN_ARM
+ if (IS_T1023_T1024) {
+ h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id].h_Dev;
+ } else {
+#else
+ {
+#endif
+ h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id + FM_MAX_NUM_OF_1G_RX_PORTS].h_Dev;
+ }
+ break;
+ }
+ goto invalid_port_id;
+
+ case (e_IOC_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ if (port_params->port_id && port_params->port_id < FM_MAX_NUM_OF_OH_PORTS) {
+ h_Port = p_LnxWrpFmDev->opPorts[port_params->port_id - 1].h_Dev;
+ break;
+ }
+ goto invalid_port_id;
+
+ default:
+invalid_port_id:
+ XX_Free(port_params);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
+ }
+
+ ((t_FmPcdPlcrProfileParams*)param)->id.newParams.h_FmPort = h_Port;
+ XX_Free(port_params);
+ }
+
+ param->id = FM_PCD_PlcrProfileSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdPlcrProfileParams*)param);
+
+ if (!param->id) {
+ XX_Free(param);
+ err = E_INVALID_VALUE;
+ /* Since the LLD has no errno-style error reporting,
+ we're left here with no other option than to report
+ a generic E_INVALID_VALUE */
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_plcr_profile_params_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_plcr_profile_params_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
+ compat_copy_fm_pcd_plcr_profile(compat_param, param, COMPAT_K_TO_US);
+ if (copy_to_user((ioc_compat_fm_pcd_plcr_profile_params_t *) compat_ptr(arg),
+ compat_param,
+ sizeof(ioc_compat_fm_pcd_plcr_profile_params_t)))
+ err = E_READ_FAILED;
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_to_user((ioc_fm_pcd_plcr_profile_params_t *)arg,
+ param,
+ sizeof(ioc_fm_pcd_plcr_profile_params_t)))
+ err = E_READ_FAILED;
+ }
+
+ XX_Free(param);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT:
+#endif
+ case FM_PCD_IOC_PLCR_PROFILE_DELETE:
+ {
+ ioc_fm_obj_t id;
+
+ memset(&id, 0 , sizeof(ioc_fm_obj_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_obj_t compat_id;
+
+ if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ compat_obj_delete(&compat_id, &id);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ err = FM_PCD_PlcrProfileDelete(id.obj);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE_COMPAT:
+#endif
+ case FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE:
+ {
+ ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param;
+
+ param = (ioc_fm_pcd_cc_tree_modify_next_engine_params_t *) XX_Malloc(
+ sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(param, 0, sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t));
+ if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *) compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t)))
+ {
+ XX_Free(compat_param);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ compat_fm_pcd_cc_tree_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_pcd_cc_tree_modify_next_engine_params_t *)arg,
+ sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ err = FM_PCD_CcRootModifyNextEngine(param->id,
+ param->grp_indx,
+ param->indx,
+ (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
+
+ XX_Free(param);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE_COMPAT:
+#endif
+ case FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE:
+ {
+ ioc_fm_pcd_cc_node_modify_next_engine_params_t *param;
+
+ param = (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
+ sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
+ if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t)))
+ {
+ XX_Free(compat_param);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ compat_copy_fm_pcd_cc_node_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_next_engine_params_t *)arg,
+ sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ err = FM_PCD_MatchTableModifyNextEngine(param->id,
+ param->key_indx,
+ (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
+
+ XX_Free(param);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE_COMPAT:
+#endif
+ case FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE:
+ {
+ ioc_fm_pcd_cc_node_modify_next_engine_params_t *param;
+
+ param = (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
+ sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
+ if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t)))
+ {
+ XX_Free(compat_param);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ compat_copy_fm_pcd_cc_node_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) arg,
+ sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ err = FM_PCD_MatchTableModifyMissNextEngine(param->id,
+ (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
+
+ XX_Free(param);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY_COMPAT:
+#endif
+ case FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY:
+ {
+ ioc_fm_pcd_cc_node_remove_key_params_t *param;
+
+ param = (ioc_fm_pcd_cc_node_remove_key_params_t *) XX_Malloc(
+ sizeof(ioc_fm_pcd_cc_node_remove_key_params_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(param, 0, sizeof(ioc_fm_pcd_cc_node_remove_key_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_cc_node_remove_key_params_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_cc_node_remove_key_params_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t));
+ if (copy_from_user(compat_param,
+ (ioc_compat_fm_pcd_cc_node_remove_key_params_t *)compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t)))
+ {
+ XX_Free(compat_param);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ param->id = compat_ptr(compat_param->id);
+ param->key_indx = compat_param->key_indx;
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_pcd_cc_node_remove_key_params_t *) arg,
+ sizeof(ioc_fm_pcd_cc_node_remove_key_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ err = FM_PCD_MatchTableRemoveKey(param->id, param->key_indx);
+
+ XX_Free(param);
+ break;
+ }
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_MATCH_TABLE_ADD_KEY_COMPAT:
+#endif
+ case FM_PCD_IOC_MATCH_TABLE_ADD_KEY:
+ {
+ ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param;
+
+ param = (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
+ sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
+ if (copy_from_user(compat_param,
+ (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
+ {
+ XX_Free(compat_param);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(compat_param, param, COMPAT_US_TO_K);
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)arg,
+ sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ if (param->key_size)
+ {
+ int size = 0;
+
+ if (param->key_params.p_key) size += param->key_size;
+ if (param->key_params.p_mask) size += param->key_size;
+
+ if (size)
+ {
+ uint8_t *p_tmp;
+
+ p_tmp = (uint8_t*) XX_Malloc(size);
+ if (!p_tmp)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
+ }
+
+ if (param->key_params.p_key)
+ {
+ if (copy_from_user(p_tmp, param->key_params.p_key, param->key_size))
+ {
+ XX_Free(p_tmp);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ param->key_params.p_key = p_tmp;
+ }
+
+ if (param->key_params.p_mask)
+ {
+ p_tmp += param->key_size;
+ if (copy_from_user(p_tmp, param->key_params.p_mask, param->key_size))
+ {
+ XX_Free(p_tmp - param->key_size);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ param->key_params.p_mask = p_tmp;
+ }
+ }
+ }
+
+ err = FM_PCD_MatchTableAddKey(
+ param->id,
+ param->key_indx,
+ param->key_size,
+ (t_FmPcdCcKeyParams*)&param->key_params);
+
+ if (param->key_params.p_key)
+ XX_Free(param->key_params.p_key);
+ XX_Free(param);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT:
+#endif
+ case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE:
+ {
+ ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param;
+
+ param = (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
+ sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
+ if (copy_from_user(compat_param,
+ (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
+ {
+ XX_Free(compat_param);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(compat_param, param, COMPAT_US_TO_K);
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)arg,
+ sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ err = FM_PCD_MatchTableModifyKeyAndNextEngine(param->id,
+ param->key_indx,
+ param->key_size,
+ (t_FmPcdCcKeyParams*)(&param->key_params));
+
+ XX_Free(param);
+ break;
+ }
+
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT_COMPAT:
+#endif
+ case FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT:
+ {
+ ioc_fm_pcd_cc_tbl_get_stats_t param;
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
+ if (!compat_param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
+ if (copy_from_user(compat_param,
+ (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
+ {
+ XX_Free(compat_param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
+ sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+
+ err = FM_PCD_MatchTableGetKeyStatistics((t_Handle) param.id,
+ param.key_index,
+ (t_FmPcdCcKeyStatistics *) &param.statistics);
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
+ if (!compat_param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
+ compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
+ if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
+ compat_param,
+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
+ XX_Free(compat_param);
+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
+ }
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
+ &param,
+ sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
+ }
+
+ break;
+ }
+
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT_COMPAT:
+#endif
+ case FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT:
+ {
+ ioc_fm_pcd_cc_tbl_get_stats_t param;
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
+ if (!compat_param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
+ if (copy_from_user(compat_param,
+ (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
+ {
+ XX_Free(compat_param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
+ sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+
+ err = FM_PCD_MatchTableGetMissStatistics((t_Handle) param.id,
+ (t_FmPcdCcKeyStatistics *) &param.statistics);
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
+ if (!compat_param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
+ compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
+ if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
+ compat_param,
+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
+ XX_Free(compat_param);
+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
+ }
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
+ &param,
+ sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
+ }
+
+ break;
+ }
+
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT_COMPAT:
+#endif
+ case FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT:
+ {
+ ioc_fm_pcd_cc_tbl_get_stats_t param;
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
+ if (!compat_param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
+ if (copy_from_user(compat_param,
+ (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
+ {
+ XX_Free(compat_param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
+ sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+
+ err = FM_PCD_HashTableGetMissStatistics((t_Handle) param.id,
+ (t_FmPcdCcKeyStatistics *) &param.statistics);
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
+ if (!compat_param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
+ compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
+ if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
+ compat_param,
+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
+ XX_Free(compat_param);
+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
+ }
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
+ &param,
+ sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
+ }
+
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_HASH_TABLE_SET_COMPAT:
+#endif
+ case FM_PCD_IOC_HASH_TABLE_SET:
+ {
+ ioc_fm_pcd_hash_table_params_t *param;
+
+ param = (ioc_fm_pcd_hash_table_params_t*) XX_Malloc(
+ sizeof(ioc_fm_pcd_hash_table_params_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(param, 0, sizeof(ioc_fm_pcd_hash_table_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_hash_table_params_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_hash_table_params_t*) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_hash_table_params_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_params_t));
+ if (copy_from_user(compat_param,
+ (ioc_compat_fm_pcd_hash_table_params_t*)compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_hash_table_params_t)))
+ {
+ XX_Free(compat_param);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ compat_copy_fm_pcd_hash_table(compat_param, param, COMPAT_US_TO_K);
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_pcd_hash_table_params_t *)arg,
+ sizeof(ioc_fm_pcd_hash_table_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ param->id = FM_PCD_HashTableSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdHashTableParams *) param);
+
+ if (!param->id)
+ {
+ XX_Free(param);
+ err = E_INVALID_VALUE;
+ /* Since the LLD has no errno-style error reporting,
+ we're left here with no other option than to report
+ a generic E_INVALID_VALUE */
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_hash_table_params_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_hash_table_params_t*) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_hash_table_params_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_params_t));
+ compat_copy_fm_pcd_hash_table(compat_param, param, COMPAT_K_TO_US);
+ if (copy_to_user((ioc_compat_fm_pcd_hash_table_params_t*) compat_ptr(arg),
+ compat_param,
+ sizeof(ioc_compat_fm_pcd_hash_table_params_t)))
+ err = E_READ_FAILED;
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_to_user((ioc_fm_pcd_hash_table_params_t *)arg,
+ param,
+ sizeof(ioc_fm_pcd_hash_table_params_t)))
+ err = E_READ_FAILED;
+ }
+
+ XX_Free(param);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_HASH_TABLE_DELETE_COMPAT:
+#endif
+ case FM_PCD_IOC_HASH_TABLE_DELETE:
+ {
+ ioc_fm_obj_t id;
+
+ memset(&id, 0, sizeof(ioc_fm_obj_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_obj_t compat_id;
+
+ if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ id.obj = compat_pcd_id2ptr(compat_id.obj);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ err = FM_PCD_HashTableDelete(id.obj);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_HASH_TABLE_ADD_KEY_COMPAT:
+#endif
+ case FM_PCD_IOC_HASH_TABLE_ADD_KEY:
+ {
+ ioc_fm_pcd_hash_table_add_key_params_t *param = NULL;
+
+ param = (ioc_fm_pcd_hash_table_add_key_params_t*) XX_Malloc(
+ sizeof(ioc_fm_pcd_hash_table_add_key_params_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(param, 0, sizeof(ioc_fm_pcd_hash_table_add_key_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_hash_table_add_key_params_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_hash_table_add_key_params_t*) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t));
+ if (copy_from_user(compat_param,
+ (ioc_compat_fm_pcd_hash_table_add_key_params_t*) compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t)))
+ {
+ XX_Free(compat_param);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ if (compat_param->key_size)
+ {
+ param->p_hash_tbl = compat_pcd_id2ptr(compat_param->p_hash_tbl);
+ param->key_size = compat_param->key_size;
+
+ compat_copy_fm_pcd_cc_key(&compat_param->key_params, &param->key_params, COMPAT_US_TO_K);
+ }
+ else
+ {
+ XX_Free(compat_param);
+ XX_Free(param);
+ err = E_INVALID_VALUE;
+ break;
+ }
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_pcd_hash_table_add_key_params_t*) arg,
+ sizeof(ioc_fm_pcd_hash_table_add_key_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ if (param->key_size)
+ {
+ int size = 0;
+
+ if (param->key_params.p_key) size += param->key_size;
+ if (param->key_params.p_mask) size += param->key_size;
+
+ if (size)
+ {
+ uint8_t *p_tmp;
+
+ p_tmp = (uint8_t*) XX_Malloc(size);
+ if (!p_tmp)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
+ }
+
+ if (param->key_params.p_key)
+ {
+ if (copy_from_user(p_tmp, param->key_params.p_key, param->key_size))
+ {
+ XX_Free(p_tmp);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ param->key_params.p_key = p_tmp;
+ }
+
+ if (param->key_params.p_mask)
+ {
+ p_tmp += param->key_size;
+ if (copy_from_user(p_tmp, param->key_params.p_mask, param->key_size))
+ {
+ XX_Free(p_tmp - param->key_size);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ param->key_params.p_mask = p_tmp;
+ }
+ }
+ }
+
+ err = FM_PCD_HashTableAddKey(
+ param->p_hash_tbl,
+ param->key_size,
+ (t_FmPcdCcKeyParams*)&param->key_params);
+
+ if (param->key_params.p_key)
+ XX_Free(param->key_params.p_key);
+ XX_Free(param);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_HASH_TABLE_REMOVE_KEY_COMPAT:
+#endif
+ case FM_PCD_IOC_HASH_TABLE_REMOVE_KEY:
+ {
+ ioc_fm_pcd_hash_table_remove_key_params_t *param = NULL;
+
+ param = (ioc_fm_pcd_hash_table_remove_key_params_t*) XX_Malloc(
+ sizeof(ioc_fm_pcd_hash_table_remove_key_params_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(param, 0, sizeof(ioc_fm_pcd_hash_table_remove_key_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_hash_table_remove_key_params_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_hash_table_remove_key_params_t*) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t));
+ if (copy_from_user(compat_param,
+ (ioc_compat_fm_pcd_hash_table_remove_key_params_t*) compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t)))
+ {
+ XX_Free(compat_param);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ param->p_hash_tbl = compat_pcd_id2ptr(compat_param->p_hash_tbl);
+ param->key_size = compat_param->key_size;
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_pcd_hash_table_remove_key_params_t*)arg,
+ sizeof(ioc_fm_pcd_hash_table_remove_key_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ if (param->key_size)
+ {
+ uint8_t *p_key;
+
+ p_key = (uint8_t*) XX_Malloc(param->key_size);
+ if (!p_key)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ if (param->p_key && copy_from_user(p_key, param->p_key, param->key_size))
+ {
+ XX_Free(p_key);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ param->p_key = p_key;
+ }
+
+ err = FM_PCD_HashTableRemoveKey(
+ param->p_hash_tbl,
+ param->key_size,
+ param->p_key);
+
+ if (param->p_key)
+ XX_Free(param->p_key);
+ XX_Free(param);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_COMPAT:
+#endif
+ case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY:
+ {
+ ioc_fm_pcd_cc_node_modify_key_params_t *param;
+
+ param = (ioc_fm_pcd_cc_node_modify_key_params_t *) XX_Malloc(
+ sizeof(ioc_fm_pcd_cc_node_modify_key_params_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_params_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t));
+ if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_key_params_t *)compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t)))
+ {
+ XX_Free(compat_param);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ compat_copy_fm_pcd_cc_node_modify_key(compat_param, param, COMPAT_US_TO_K);
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_params_t *)arg,
+ sizeof(ioc_fm_pcd_cc_node_modify_key_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ if (param->key_size)
+ {
+ int size = 0;
+
+ if (param->p_key) size += param->key_size;
+ if (param->p_mask) size += param->key_size;
+
+ if (size)
+ {
+ uint8_t *p_tmp;
+
+ p_tmp = (uint8_t*) XX_Malloc(size);
+ if (!p_tmp)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
+ }
+
+ if (param->p_key)
+ {
+ if (copy_from_user(p_tmp, param->p_key, param->key_size))
+ {
+ XX_Free(p_tmp);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ param->p_key = p_tmp;
+ }
+
+ if (param->p_mask)
+ {
+ p_tmp += param->key_size;
+ if (copy_from_user(p_tmp, param->p_mask, param->key_size))
+ {
+ XX_Free(p_tmp - param->key_size);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ param->p_mask = p_tmp;
+ }
+ }
+ }
+
+ err = FM_PCD_MatchTableModifyKey(param->id,
+ param->key_indx,
+ param->key_size,
+ param->p_key,
+ param->p_mask);
+
+ if (param->p_key)
+ XX_Free(param->p_key);
+ else if (param->p_mask)
+ XX_Free(param->p_mask);
+ XX_Free(param);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_MANIP_NODE_SET_COMPAT:
+#endif
+ case FM_PCD_IOC_MANIP_NODE_SET:
+ {
+ ioc_fm_pcd_manip_params_t *param;
+ uint8_t *p_data = NULL;
+ uint8_t size;
+
+ param = (ioc_fm_pcd_manip_params_t *) XX_Malloc(
+ sizeof(ioc_fm_pcd_manip_params_t));
+
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(param, 0, sizeof(ioc_fm_pcd_manip_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_manip_params_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_manip_params_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_manip_params_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_params_t));
+ if (copy_from_user(compat_param,
+ (ioc_compat_fm_pcd_manip_params_t *) compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_manip_params_t)))
+ {
+ XX_Free(compat_param);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ compat_fm_pcd_manip_set_node(compat_param, param, COMPAT_US_TO_K);
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_pcd_manip_params_t *)arg,
+ sizeof(ioc_fm_pcd_manip_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ if (param->type == e_IOC_FM_PCD_MANIP_HDR)
+ {
+ size = param->u.hdr.insrt_params.u.generic.size;
+ p_data = (uint8_t *) XX_Malloc(size);
+ if (!p_data )
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, NO_MSG);
+ }
+
+ if (param->u.hdr.insrt_params.u.generic.p_data &&
+ copy_from_user(p_data,
+ param->u.hdr.insrt_params.u.generic.p_data, size))
+ {
+ XX_Free(p_data);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ param->u.hdr.insrt_params.u.generic.p_data = p_data;
+ }
+
+ if (param->id)
+ {
+ /* Security Hole: the user can pass any piece of garbage
+ in 'param->id', and that will go straight through to the LLD,
+ no checks being done by the wrapper! */
+ err = FM_PCD_ManipNodeReplace(
+ (t_Handle) param->id,
+ (t_FmPcdManipParams*) param);
+ if (err)
+ {
+ if (p_data)
+ XX_Free(p_data);
+ XX_Free(param);
+ break;
+ }
+ }
+ else
+ {
+ param->id = FM_PCD_ManipNodeSet(
+ p_LnxWrpFmDev->h_PcdDev,
+ (t_FmPcdManipParams*) param);
+ if (!param->id)
+ {
+ if (p_data)
+ XX_Free(p_data);
+ XX_Free(param);
+ err = E_INVALID_VALUE;
+ /* Since the LLD has no errno-style error reporting,
+ we're left here with no other option than to report
+ a generic E_INVALID_VALUE */
+ break;
+ }
+ }
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_manip_params_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_manip_params_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_manip_params_t));
+ if (!compat_param)
+ {
+ if (p_data)
+ XX_Free(p_data);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_params_t));
+
+ compat_fm_pcd_manip_set_node(compat_param, param, COMPAT_K_TO_US);
+
+ if (copy_to_user((ioc_compat_fm_pcd_manip_params_t *) compat_ptr(arg),
+ compat_param,
+ sizeof(ioc_compat_fm_pcd_manip_params_t)))
+ err = E_READ_FAILED;
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_to_user((ioc_fm_pcd_manip_params_t *)arg,
+ param, sizeof(ioc_fm_pcd_manip_params_t)))
+ err = E_READ_FAILED;
+ }
+
+ if (p_data)
+ XX_Free(p_data);
+ XX_Free(param);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT:
+#endif
+ case FM_PCD_IOC_MANIP_NODE_DELETE:
+ {
+ ioc_fm_obj_t id;
+
+ memset(&id, 0, sizeof(ioc_fm_obj_t));
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_obj_t compat_id;
+
+ if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ compat_obj_delete(&compat_id, &id);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ err = FM_PCD_ManipNodeDelete(id.obj);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_MANIP_GET_STATS_COMPAT:
+#endif
+ case FM_PCD_IOC_MANIP_GET_STATS:
+ {
+ ioc_fm_pcd_manip_get_stats_t param;
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_manip_get_stats_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_manip_get_stats_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
+ if (!compat_param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
+ if (copy_from_user(compat_param,
+ (ioc_compat_fm_pcd_manip_get_stats_t *)compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_manip_get_stats_t)))
+ {
+ XX_Free(compat_param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ compat_copy_fm_pcd_manip_get_stats(compat_param, &param, COMPAT_US_TO_K);
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(&param, (ioc_fm_pcd_manip_get_stats_t *)arg,
+ sizeof(ioc_fm_pcd_manip_get_stats_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ err = FM_PCD_ManipGetStatistics((t_Handle) param.id,
+ (t_FmPcdManipStats*) &param.stats);
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_manip_get_stats_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_manip_get_stats_t*) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
+ if (!compat_param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
+ compat_copy_fm_pcd_manip_get_stats(compat_param, &param, COMPAT_K_TO_US);
+ if (copy_to_user((ioc_compat_fm_pcd_manip_get_stats_t*) compat_ptr(arg),
+ compat_param,
+ sizeof(ioc_compat_fm_pcd_manip_get_stats_t))){
+ XX_Free(compat_param);
+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
+ }
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ if (copy_to_user((ioc_fm_pcd_manip_get_stats_t *)arg,
+ &param,
+ sizeof(ioc_fm_pcd_manip_get_stats_t)))
+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
+
+ break;
+ }
+
+#if (DPAA_VERSION >= 11)
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_FRM_REPLIC_GROUP_SET_COMPAT:
+#endif
+ case FM_PCD_IOC_FRM_REPLIC_GROUP_SET:
+ {
+ ioc_fm_pcd_frm_replic_group_params_t *param;
+
+ param = (ioc_fm_pcd_frm_replic_group_params_t *) XX_Malloc(
+ sizeof(ioc_fm_pcd_frm_replic_group_params_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(param, 0, sizeof(ioc_fm_pcd_frm_replic_group_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_frm_replic_group_params_t
+ *compat_param;
+
+ compat_param =
+ (ioc_compat_fm_pcd_frm_replic_group_params_t *)
+ XX_Malloc(sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY,
+ ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
+ if (copy_from_user(compat_param,
+ (ioc_compat_fm_pcd_frm_replic_group_params_t *)
+ compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t))) {
+ XX_Free(compat_param);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
+ }
+
+ compat_copy_fm_pcd_frm_replic_group_params(compat_param,
+ param, COMPAT_US_TO_K);
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param,
+ (ioc_fm_pcd_frm_replic_group_params_t *)arg,
+ sizeof(ioc_fm_pcd_frm_replic_group_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
+ }
+ }
+
+ param->id = FM_PCD_FrmReplicSetGroup(p_LnxWrpFmDev->h_PcdDev,
+ (t_FmPcdFrmReplicGroupParams*)param);
+
+ if (!param->id) {
+ XX_Free(param);
+ err = E_INVALID_VALUE;
+ /*
+ * Since the LLD has no errno-style error reporting,
+ * we're left here with no other option than to report
+ * a generic E_INVALID_VALUE
+ */
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_frm_replic_group_params_t
+ *compat_param;
+
+ compat_param =
+ (ioc_compat_fm_pcd_frm_replic_group_params_t *)
+ XX_Malloc(sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY,
+ ("IOCTL FM PCD"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
+ compat_copy_fm_pcd_frm_replic_group_params(compat_param,
+ param, COMPAT_K_TO_US);
+ if (copy_to_user(
+ (ioc_compat_fm_pcd_frm_replic_group_params_t *)
+ compat_ptr(arg),
+ compat_param,
+ sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t)))
+ err = E_WRITE_FAILED;
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_to_user(
+ (ioc_fm_pcd_frm_replic_group_params_t *)arg,
+ param,
+ sizeof(ioc_fm_pcd_frm_replic_group_params_t)))
+ err = E_WRITE_FAILED;
+ }
+
+ XX_Free(param);
+ break;
+ }
+ break;
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE_COMPAT:
+#endif
+ case FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE:
+ {
+ ioc_fm_obj_t id;
+
+ memset(&id, 0, sizeof(ioc_fm_obj_t));
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_obj_t compat_id;
+
+ if (copy_from_user(&compat_id,
+ (ioc_compat_fm_obj_t *) compat_ptr(arg),
+ sizeof(ioc_compat_fm_obj_t)))
+ break;
+ compat_obj_delete(&compat_id, &id);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
+ sizeof(ioc_fm_obj_t)))
+ break;
+ }
+
+ return FM_PCD_FrmReplicDeleteGroup(id.obj);
+ }
+ break;
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD_COMPAT:
+#endif
+ case FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD:
+ {
+ ioc_fm_pcd_frm_replic_member_params_t param;
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_frm_replic_member_params_t compat_param;
+
+ if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ compat_copy_fm_pcd_frm_replic_member_params(&compat_param, &param, COMPAT_US_TO_K);
+ }
+ else
+#endif
+ if (copy_from_user(&param, (void *)arg, sizeof(param)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ return FM_PCD_FrmReplicAddMember(param.member.h_replic_group,
+ param.member.member_index,
+ (t_FmPcdCcNextEngineParams*)&param.next_engine_params);
+ }
+ break;
+
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE_COMPAT:
+#endif
+ case FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE:
+ {
+ ioc_fm_pcd_frm_replic_member_t param;
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_frm_replic_member_t compat_param;
+
+ if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ compat_copy_fm_pcd_frm_replic_member(&compat_param, &param, COMPAT_US_TO_K);
+ }
+ else
+#endif
+ if (copy_from_user(&param, (void *)arg, sizeof(param)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ return FM_PCD_FrmReplicRemoveMember(param.h_replic_group, param.member_index);
+ }
+ break;
+
+#if defined(CONFIG_COMPAT)
+ case FM_IOC_VSP_CONFIG_COMPAT:
+#endif
+ case FM_IOC_VSP_CONFIG:
+ {
+ ioc_fm_vsp_params_t param;
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_vsp_params_t compat_param;
+
+ if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ compat_copy_fm_vsp_params(&compat_param, &param, COMPAT_US_TO_K);
+ }
+ else
+#endif
+ if (copy_from_user(&param, (void *)arg, sizeof(param)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ {
+ uint8_t portId = param.port_params.port_id;
+ param.liodn_offset =
+ p_LnxWrpFmDev->rxPorts[portId].settings.param.specificParams.rxParams.liodnOffset;
+ }
+ param.p_fm = p_LnxWrpFmDev->h_Dev;
+ param.id = FM_VSP_Config((t_FmVspParams *)&param);
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_vsp_params_t compat_param;
+
+ memset(&compat_param, 0, sizeof(compat_param));
+ compat_copy_fm_vsp_params(&compat_param, &param, COMPAT_K_TO_US);
+
+ if (copy_to_user(compat_ptr(arg), &compat_param, sizeof(compat_param)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ else
+#endif
+ if (copy_to_user((void *)arg, &param, sizeof(param)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_IOC_VSP_INIT_COMPAT:
+#endif
+ case FM_IOC_VSP_INIT:
+ {
+ ioc_fm_obj_t id;
+
+ memset(&id, 0, sizeof(ioc_fm_obj_t));
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_obj_t compat_id;
+
+ if (copy_from_user(&compat_id,
+ (ioc_compat_fm_obj_t *) compat_ptr(arg),
+ sizeof(ioc_compat_fm_obj_t)))
+ break;
+ id.obj = compat_pcd_id2ptr(compat_id.obj);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
+ sizeof(ioc_fm_obj_t)))
+ break;
+ }
+
+ return FM_VSP_Init(id.obj);
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_IOC_VSP_FREE_COMPAT:
+#endif
+ case FM_IOC_VSP_FREE:
+ {
+ ioc_fm_obj_t id;
+
+ memset(&id, 0, sizeof(ioc_fm_obj_t));
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_obj_t compat_id;
+
+ if (copy_from_user(&compat_id,
+ (ioc_compat_fm_obj_t *) compat_ptr(arg),
+ sizeof(ioc_compat_fm_obj_t)))
+ break;
+ compat_obj_delete(&compat_id, &id);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
+ sizeof(ioc_fm_obj_t)))
+ break;
+ }
+
+ return FM_VSP_Free(id.obj);
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_IOC_VSP_CONFIG_POOL_DEPLETION_COMPAT:
+#endif
+ case FM_IOC_VSP_CONFIG_POOL_DEPLETION:
+ {
+ ioc_fm_buf_pool_depletion_params_t param;
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_buf_pool_depletion_params_t compat_param;
+
+ if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ compat_copy_fm_buf_pool_depletion_params(&compat_param, &param, COMPAT_US_TO_K);
+ }
+ else
+#endif
+ if (copy_from_user(&param, (void *)arg, sizeof(param)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ if (FM_VSP_ConfigPoolDepletion(param.p_fm_vsp,
+ (t_FmBufPoolDepletion *)&param.fm_buf_pool_depletion))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ break;
+ }
+
+
+#if defined(CONFIG_COMPAT)
+ case FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT_COMPAT:
+#endif
+ case FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT:
+ {
+ ioc_fm_buffer_prefix_content_params_t param;
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_buffer_prefix_content_params_t compat_param;
+
+ if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ compat_copy_fm_buffer_prefix_content_params(&compat_param, &param, COMPAT_US_TO_K);
+ }
+ else
+#endif
+ if (copy_from_user(&param, (void *)arg, sizeof(param)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ if (FM_VSP_ConfigBufferPrefixContent(param.p_fm_vsp,
+ (t_FmBufferPrefixContent *)&param.fm_buffer_prefix_content))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_IOC_VSP_CONFIG_NO_SG_COMPAT:
+#endif
+ case FM_IOC_VSP_CONFIG_NO_SG:
+ {
+ ioc_fm_vsp_config_no_sg_params_t param;
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_vsp_config_no_sg_params_t compat_param;
+
+ if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ compat_copy_fm_vsp_config_no_sg_params(&compat_param, &param, COMPAT_US_TO_K);
+ }
+ else
+#endif
+ if (copy_from_user(&param, (void *)arg, sizeof(param)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ if (FM_VSP_ConfigNoScatherGather(param.p_fm_vsp, param.no_sg))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_IOC_VSP_GET_BUFFER_PRS_RESULT_COMPAT:
+#endif
+ case FM_IOC_VSP_GET_BUFFER_PRS_RESULT:
+ {
+ ioc_fm_vsp_prs_result_params_t param;
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_vsp_prs_result_params_t compat_param;
+
+ if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ compat_copy_fm_vsp_prs_result_params(&compat_param, &param, COMPAT_US_TO_K);
+ }
+ else
+#endif
+ if (copy_from_user(&param, (void *)arg, sizeof(param)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ /* this call just adds the parse results offset to p_data */
+ param.p_data = FM_VSP_GetBufferPrsResult(param.p_fm_vsp, param.p_data);
+
+ if (!param.p_data)
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_vsp_prs_result_params_t compat_param;
+
+ memset(&compat_param, 0, sizeof(compat_param));
+ compat_copy_fm_vsp_prs_result_params(&compat_param, &param, COMPAT_K_TO_US);
+
+ if (copy_to_user(compat_ptr(arg), &compat_param, sizeof(compat_param)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ else
+#endif
+ if (copy_to_user((void *)arg, &param, sizeof(param)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ break;
+ }
+#endif /* (DPAA_VERSION >= 11) */
+
+#ifdef FM_CAPWAP_SUPPORT
+#warning "feature not supported!"
+#if defined(CONFIG_COMPAT)
+ case FM_PCD_IOC_STATISTICS_SET_NODE_COMPAT:
+#endif
+ case FM_PCD_IOC_STATISTICS_SET_NODE:
+ {
+/* ioc_fm_pcd_stats_params_t param;
+ ...
+ param->id = FM_PCD_StatisticsSetNode(p_LnxWrpFmDev->h_PcdDev,
+ (t_FmPcdStatsParams *)&param);
+*/
+ err = E_NOT_SUPPORTED;
+ break;
+ }
+#endif /* FM_CAPWAP_SUPPORT */
+
+ default:
+ RETURN_ERROR(MINOR, E_INVALID_SELECTION,
+ ("invalid ioctl: cmd:0x%08x(type:0x%02x, nr: %d.\n",
+ cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)));
+ }
+
+ if (err)
+ RETURN_ERROR(MINOR, err, ("IOCTL FM PCD"));
+
+ return E_OK;
+}
+
+void FM_Get_Api_Version(ioc_fm_api_version_t *p_version)
+{
+ p_version->version.major = FMD_API_VERSION_MAJOR;
+ p_version->version.minor = FMD_API_VERSION_MINOR;
+ p_version->version.respin = FMD_API_VERSION_RESPIN;
+ p_version->version.reserved = 0;
+}
+
+t_Error LnxwrpFmIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat)
+{
+ t_Error err = E_OK;
+
+ switch (cmd)
+ {
+ case FM_IOC_SET_PORTS_BANDWIDTH:
+ {
+ ioc_fm_port_bandwidth_params *param;
+
+ param = (ioc_fm_port_bandwidth_params*) XX_Malloc(sizeof(ioc_fm_port_bandwidth_params));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(param, 0, sizeof(ioc_fm_port_bandwidth_params));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ if (copy_from_user(param, (ioc_fm_port_bandwidth_params*)compat_ptr(arg), sizeof(ioc_fm_port_bandwidth_params)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_port_bandwidth_params*)arg, sizeof(ioc_fm_port_bandwidth_params)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ err = FM_SetPortsBandwidth(p_LnxWrpFmDev->h_Dev, (t_FmPortsBandwidthParams*) param);
+
+ XX_Free(param);
+ break;
+ }
+
+ case FM_IOC_GET_REVISION:
+ {
+ ioc_fm_revision_info_t *param;
+
+ param = (ioc_fm_revision_info_t *) XX_Malloc(sizeof(ioc_fm_revision_info_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ FM_GetRevision(p_LnxWrpFmDev->h_Dev, (t_FmRevisionInfo*)param);
+ /* This one never returns anything other than E_OK */
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ if (copy_to_user((ioc_fm_revision_info_t *)compat_ptr(arg),
+ param,
+ sizeof(ioc_fm_revision_info_t))){
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
+ }
+ }
+ else
+#endif
+ {
+ if (copy_to_user((ioc_fm_revision_info_t *)arg,
+ param,
+ sizeof(ioc_fm_revision_info_t))){
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
+ }
+ }
+ XX_Free(param);
+ break;
+ }
+
+ case FM_IOC_SET_COUNTER:
+ {
+ ioc_fm_counters_params_t *param;
+
+ param = (ioc_fm_counters_params_t *) XX_Malloc(sizeof(ioc_fm_counters_params_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(param, 0, sizeof(ioc_fm_counters_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ if (copy_from_user(param, (ioc_fm_counters_params_t *)compat_ptr(arg), sizeof(ioc_fm_counters_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_counters_params_t *)arg, sizeof(ioc_fm_counters_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ err = FM_ModifyCounter(p_LnxWrpFmDev->h_Dev, param->cnt, param->val);
+
+ XX_Free(param);
+ break;
+ }
+
+ case FM_IOC_GET_COUNTER:
+ {
+ ioc_fm_counters_params_t *param;
+
+ param = (ioc_fm_counters_params_t *) XX_Malloc(sizeof(ioc_fm_counters_params_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
+
+ memset(param, 0, sizeof(ioc_fm_counters_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ if (copy_from_user(param, (ioc_fm_counters_params_t *)compat_ptr(arg), sizeof(ioc_fm_counters_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_counters_params_t *)arg, sizeof(ioc_fm_counters_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ param->val = FM_GetCounter(p_LnxWrpFmDev->h_Dev, param->cnt);
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ if (copy_to_user((ioc_fm_counters_params_t *)compat_ptr(arg), param, sizeof(ioc_fm_counters_params_t)))
+ err = E_READ_FAILED;
+ }
+ else
+#endif
+ {
+ if (copy_to_user((ioc_fm_counters_params_t *)arg, param, sizeof(ioc_fm_counters_params_t)))
+ err = E_READ_FAILED;
+ }
+
+ XX_Free(param);
+ break;
+ }
+
+ case FM_IOC_FORCE_INTR:
+ {
+ ioc_fm_exceptions param;
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ if (get_user(param, (ioc_fm_exceptions*) compat_ptr(arg)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ else
+#endif
+ {
+ if (get_user(param, (ioc_fm_exceptions*)arg))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ err = FM_ForceIntr(p_LnxWrpFmDev->h_Dev, (e_FmExceptions)param);
+ break;
+ }
+
+ case FM_IOC_GET_API_VERSION:
+ {
+ ioc_fm_api_version_t version;
+
+ FM_Get_Api_Version(&version);
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ if (copy_to_user(
+ (ioc_fm_api_version_t *)compat_ptr(arg),
+ &version, sizeof(version)))
+ err = E_READ_FAILED;
+ }
+ else
+#endif
+ {
+ if (copy_to_user((ioc_fm_api_version_t *)arg,
+ &version, sizeof(version)))
+ err = E_READ_FAILED;
+ }
+ }
+ break;
+
+ case FM_IOC_CTRL_MON_START:
+ {
+ FM_CtrlMonStart(p_LnxWrpFmDev->h_Dev);
+ }
+ break;
+
+ case FM_IOC_CTRL_MON_STOP:
+ {
+ FM_CtrlMonStop(p_LnxWrpFmDev->h_Dev);
+ }
+ break;
+
+#if defined(CONFIG_COMPAT)
+ case FM_IOC_CTRL_MON_GET_COUNTERS_COMPAT:
+#endif
+ case FM_IOC_CTRL_MON_GET_COUNTERS:
+ {
+ ioc_fm_ctrl_mon_counters_params_t param;
+ t_FmCtrlMon mon;
+
+#if defined(CONFIG_COMPAT)
+ ioc_compat_fm_ctrl_mon_counters_params_t compat_param;
+
+ if (compat)
+ {
+ if (copy_from_user(&compat_param, (void *)compat_ptr(arg),
+ sizeof(compat_param)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ param.fm_ctrl_index = compat_param.fm_ctrl_index;
+ param.p_mon = (fm_ctrl_mon_t *)compat_ptr(compat_param.p_mon);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(&param, (void *)arg, sizeof(ioc_fm_ctrl_mon_counters_params_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ if (FM_CtrlMonGetCounters(p_LnxWrpFmDev->h_Dev, param.fm_ctrl_index, &mon))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ if (copy_to_user(param.p_mon, &mon, sizeof(t_FmCtrlMon)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ break;
+
+ default:
+ return LnxwrpFmPcdIOCTL(p_LnxWrpFmDev, cmd, arg, compat);
+ }
+
+ if (err)
+ RETURN_ERROR(MINOR, E_INVALID_OPERATION, ("IOCTL FM"));
+
+ return E_OK;
+}
+
+t_Error LnxwrpFmPortIOCTL(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev, unsigned int cmd, unsigned long arg, bool compat)
+{
+ t_Error err = E_OK;
+
+ _fm_ioctl_dbg("cmd:0x%08x(type:0x%02x, nr:%u).\n",
+ cmd, _IOC_TYPE(cmd), _IOC_NR(cmd) - 70);
+
+ switch (cmd)
+ {
+ case FM_PORT_IOC_DISABLE:
+ FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
+ /* deliberately ignoring error codes here */
+ return E_OK;
+
+ case FM_PORT_IOC_ENABLE:
+ FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
+ /* deliberately ignoring error codes here */
+ return E_OK;
+
+ case FM_PORT_IOC_SET_ERRORS_ROUTE:
+ {
+ ioc_fm_port_frame_err_select_t errs;
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ if (get_user(errs, (ioc_fm_port_frame_err_select_t*)compat_ptr(arg)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ else
+#endif
+ {
+ if (get_user(errs, (ioc_fm_port_frame_err_select_t*)arg))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ err = FM_PORT_SetErrorsRoute(p_LnxWrpFmPortDev->h_Dev, (fmPortFrameErrSelect_t)errs);
+ break;
+ }
+
+ case FM_PORT_IOC_SET_RATE_LIMIT:
+ {
+ ioc_fm_port_rate_limit_t *param;
+
+ param = (ioc_fm_port_rate_limit_t *) XX_Malloc(sizeof(ioc_fm_port_rate_limit_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
+
+ memset(param, 0, sizeof(ioc_fm_port_rate_limit_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ if (copy_from_user(param, (ioc_fm_port_rate_limit_t *)compat_ptr(arg), sizeof(ioc_fm_port_rate_limit_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_port_rate_limit_t *)arg, sizeof(ioc_fm_port_rate_limit_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ err = FM_PORT_SetRateLimit(p_LnxWrpFmPortDev->h_Dev, (t_FmPortRateLimit *)param);
+
+ XX_Free(param);
+ break;
+ }
+
+ case FM_PORT_IOC_REMOVE_RATE_LIMIT:
+ FM_PORT_DeleteRateLimit(p_LnxWrpFmPortDev->h_Dev);
+ /* deliberately ignoring error codes here */
+ return E_OK;
+
+ case FM_PORT_IOC_ALLOC_PCD_FQIDS:
+ {
+ ioc_fm_port_pcd_fqids_params_t *param;
+
+ if (!p_LnxWrpFmPortDev->pcd_owner_params.cba)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("No one to listen on this PCD!!!"));
+
+ param = (ioc_fm_port_pcd_fqids_params_t *) XX_Malloc(sizeof(ioc_fm_port_pcd_fqids_params_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
+
+ memset(param, 0, sizeof(ioc_fm_port_pcd_fqids_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ if (copy_from_user(param, (ioc_fm_port_pcd_fqids_params_t *)compat_ptr(arg),
+ sizeof(ioc_fm_port_pcd_fqids_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_port_pcd_fqids_params_t *)arg,
+ sizeof(ioc_fm_port_pcd_fqids_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ if (p_LnxWrpFmPortDev->pcd_owner_params.cba(p_LnxWrpFmPortDev->pcd_owner_params.dev,
+ param->num_fqids,
+ param->alignment,
+ &param->base_fqid))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("can't allocate fqids for PCD!!!"));
+ }
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ if (copy_to_user((ioc_fm_port_pcd_fqids_params_t *)compat_ptr(arg),
+ param, sizeof(ioc_fm_port_pcd_fqids_params_t)))
+ err = E_READ_FAILED;
+ }
+ else
+#endif
+ {
+ if (copy_to_user((ioc_fm_port_pcd_fqids_params_t *)arg,
+ param, sizeof(ioc_fm_port_pcd_fqids_params_t)))
+ err = E_READ_FAILED;
+ }
+
+ XX_Free(param);
+ break;
+ }
+
+ case FM_PORT_IOC_FREE_PCD_FQIDS:
+ {
+ uint32_t base_fqid;
+
+ if (!p_LnxWrpFmPortDev->pcd_owner_params.cbf)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("No one to listen on this PCD!!!"));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ if (get_user(base_fqid, (uint32_t*) compat_ptr(arg)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ else
+#endif
+ {
+ if (get_user(base_fqid, (uint32_t*)arg))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ if (p_LnxWrpFmPortDev->pcd_owner_params.cbf(p_LnxWrpFmPortDev->pcd_owner_params.dev, base_fqid))
+ err = E_WRITE_FAILED;
+
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PORT_IOC_SET_PCD_COMPAT:
+#endif
+ case FM_PORT_IOC_SET_PCD:
+ {
+ ioc_fm_port_pcd_params_t *port_pcd_params;
+ ioc_fm_port_pcd_prs_params_t *port_pcd_prs_params;
+ ioc_fm_port_pcd_cc_params_t *port_pcd_cc_params;
+ ioc_fm_port_pcd_kg_params_t *port_pcd_kg_params;
+ ioc_fm_port_pcd_plcr_params_t *port_pcd_plcr_params;
+
+ port_pcd_params = (ioc_fm_port_pcd_params_t *) XX_Malloc(
+ sizeof(ioc_fm_port_pcd_params_t) +
+ sizeof(ioc_fm_port_pcd_prs_params_t) +
+ sizeof(ioc_fm_port_pcd_cc_params_t) +
+ sizeof(ioc_fm_port_pcd_kg_params_t) +
+ sizeof(ioc_fm_port_pcd_plcr_params_t));
+ if (!port_pcd_params)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
+
+ memset(port_pcd_params, 0,
+ sizeof(ioc_fm_port_pcd_params_t) +
+ sizeof(ioc_fm_port_pcd_prs_params_t) +
+ sizeof(ioc_fm_port_pcd_cc_params_t) +
+ sizeof(ioc_fm_port_pcd_kg_params_t) +
+ sizeof(ioc_fm_port_pcd_plcr_params_t));
+
+ port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (port_pcd_params + 1);
+ port_pcd_cc_params = (ioc_fm_port_pcd_cc_params_t *) (port_pcd_prs_params + 1);
+ port_pcd_kg_params = (ioc_fm_port_pcd_kg_params_t *) (port_pcd_cc_params + 1);
+ port_pcd_plcr_params = (ioc_fm_port_pcd_plcr_params_t *) (port_pcd_kg_params + 1);
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_port_pcd_params_t *compat_port_pcd_params;
+ ioc_fm_port_pcd_prs_params_t *same_port_pcd_prs_params;
+ ioc_compat_fm_port_pcd_cc_params_t *compat_port_pcd_cc_params;
+ ioc_compat_fm_port_pcd_kg_params_t *compat_port_pcd_kg_params;
+ ioc_compat_fm_port_pcd_plcr_params_t *compat_port_pcd_plcr_params;
+
+ compat_port_pcd_params = (ioc_compat_fm_port_pcd_params_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_port_pcd_params_t) +
+ sizeof(ioc_fm_port_pcd_prs_params_t) +
+ sizeof(ioc_compat_fm_port_pcd_cc_params_t) +
+ sizeof(ioc_compat_fm_port_pcd_kg_params_t) +
+ sizeof(ioc_compat_fm_port_pcd_plcr_params_t));
+ if (!compat_port_pcd_params)
+ {
+ XX_Free(port_pcd_params);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
+ }
+
+ memset(compat_port_pcd_params, 0,
+ sizeof(ioc_compat_fm_port_pcd_params_t) +
+ sizeof(ioc_fm_port_pcd_prs_params_t) +
+ sizeof(ioc_compat_fm_port_pcd_cc_params_t) +
+ sizeof(ioc_compat_fm_port_pcd_kg_params_t) +
+ sizeof(ioc_compat_fm_port_pcd_plcr_params_t));
+ same_port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (compat_port_pcd_params + 1);
+ compat_port_pcd_cc_params = (ioc_compat_fm_port_pcd_cc_params_t *) (same_port_pcd_prs_params + 1);
+ compat_port_pcd_kg_params = (ioc_compat_fm_port_pcd_kg_params_t *) (compat_port_pcd_cc_params + 1);
+ compat_port_pcd_plcr_params = (ioc_compat_fm_port_pcd_plcr_params_t *) (compat_port_pcd_kg_params + 1);
+
+ if (copy_from_user(compat_port_pcd_params,
+ (ioc_compat_fm_port_pcd_params_t*) compat_ptr(arg),
+ sizeof(ioc_compat_fm_port_pcd_params_t)))
+ err = E_WRITE_FAILED;
+
+ while (!err) /* pseudo-while */
+ {
+ /* set pointers from where to copy from: */
+ port_pcd_params->p_prs_params = compat_ptr(compat_port_pcd_params->p_prs_params); /* same structure */
+ port_pcd_params->p_cc_params = compat_ptr(compat_port_pcd_params->p_cc_params);
+ port_pcd_params->p_kg_params = compat_ptr(compat_port_pcd_params->p_kg_params);
+ port_pcd_params->p_plcr_params = compat_ptr(compat_port_pcd_params->p_plcr_params);
+ port_pcd_params->p_ip_reassembly_manip = compat_ptr(compat_port_pcd_params->p_ip_reassembly_manip);
+#if (DPAA_VERSION >= 11)
+ port_pcd_params->p_capwap_reassembly_manip = compat_ptr(compat_port_pcd_params->p_capwap_reassembly_manip);
+#endif
+ /* the prs member is the same, no compat structure...memcpy only */
+ if (port_pcd_params->p_prs_params)
+ {
+ if (copy_from_user(same_port_pcd_prs_params,
+ port_pcd_params->p_prs_params,
+ sizeof(ioc_fm_port_pcd_prs_params_t)))
+ {
+ err = E_WRITE_FAILED;
+ break; /* from pseudo-while */
+ }
+
+ memcpy(port_pcd_prs_params, same_port_pcd_prs_params, sizeof(ioc_fm_port_pcd_prs_params_t));
+ port_pcd_params->p_prs_params = port_pcd_prs_params;
+ }
+
+ if (port_pcd_params->p_cc_params)
+ {
+ if (copy_from_user(compat_port_pcd_cc_params,
+ port_pcd_params->p_cc_params,
+ sizeof(ioc_compat_fm_port_pcd_cc_params_t)))
+ {
+ err = E_WRITE_FAILED;
+ break; /* from pseudo-while */
+ }
+
+ port_pcd_params->p_cc_params = port_pcd_cc_params;
+ }
+
+ if (port_pcd_params->p_kg_params)
+ {
+ if (copy_from_user(compat_port_pcd_kg_params,
+ port_pcd_params->p_kg_params,
+ sizeof(ioc_compat_fm_port_pcd_kg_params_t)))
+ {
+ err = E_WRITE_FAILED;
+ break; /* from pseudo-while */
+ }
+
+ port_pcd_params->p_kg_params = port_pcd_kg_params;
+ }
+
+ if (port_pcd_params->p_plcr_params)
+ {
+ if (copy_from_user(compat_port_pcd_plcr_params,
+ port_pcd_params->p_plcr_params,
+ sizeof(ioc_compat_fm_port_pcd_plcr_params_t)))
+ {
+ err = E_WRITE_FAILED;
+ break; /* from pseudo-while */
+ }
+
+ port_pcd_params->p_plcr_params = port_pcd_plcr_params;
+ }
+
+ break; /* pseudo-while: always run once! */
+ }
+
+ if (!err)
+ compat_copy_fm_port_pcd(compat_port_pcd_params, port_pcd_params, COMPAT_US_TO_K);
+
+ XX_Free(compat_port_pcd_params);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(port_pcd_params,
+ (ioc_fm_port_pcd_params_t*) arg,
+ sizeof(ioc_fm_port_pcd_params_t)))
+ err = E_WRITE_FAILED;
+
+ while (!err) /* pseudo-while */
+ {
+ if (port_pcd_params->p_prs_params)
+ {
+ if (copy_from_user(port_pcd_prs_params,
+ port_pcd_params->p_prs_params,
+ sizeof(ioc_fm_port_pcd_prs_params_t)))
+ {
+ err = E_WRITE_FAILED;
+ break; /* from pseudo-while */
+ }
+
+ port_pcd_params->p_prs_params = port_pcd_prs_params;
+ }
+
+ if (port_pcd_params->p_cc_params)
+ {
+ if (copy_from_user(port_pcd_cc_params,
+ port_pcd_params->p_cc_params,
+ sizeof(ioc_fm_port_pcd_cc_params_t)))
+ {
+ err = E_WRITE_FAILED;
+ break; /* from pseudo-while */
+ }
+
+ port_pcd_params->p_cc_params = port_pcd_cc_params;
+ }
+
+ if (port_pcd_params->p_kg_params)
+ {
+ if (copy_from_user(port_pcd_kg_params,
+ port_pcd_params->p_kg_params,
+ sizeof(ioc_fm_port_pcd_kg_params_t)))
+ {
+ err = E_WRITE_FAILED;
+ break; /* from pseudo-while */
+ }
+
+ port_pcd_params->p_kg_params = port_pcd_kg_params;
+ }
+
+ if (port_pcd_params->p_plcr_params)
+ {
+ if (copy_from_user(port_pcd_plcr_params,
+ port_pcd_params->p_plcr_params,
+ sizeof(ioc_fm_port_pcd_plcr_params_t)))
+ {
+ err = E_WRITE_FAILED;
+ break; /* from pseudo-while */
+ }
+
+ port_pcd_params->p_plcr_params = port_pcd_plcr_params;
+ }
+
+ break; /* pseudo-while: always run once! */
+ }
+ }
+
+ if (!err)
+ err = FM_PORT_SetPCD(p_LnxWrpFmPortDev->h_Dev, (t_FmPortPcdParams*) port_pcd_params);
+
+ XX_Free(port_pcd_params);
+ break;
+ }
+
+ case FM_PORT_IOC_DELETE_PCD:
+ err = FM_PORT_DeletePCD(p_LnxWrpFmPortDev->h_Dev);
+ break;
+
+#if defined(CONFIG_COMPAT)
+ case FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME_COMPAT:
+#endif
+ case FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME:
+ {
+ ioc_fm_pcd_kg_scheme_select_t *param;
+
+ param = (ioc_fm_pcd_kg_scheme_select_t *) XX_Malloc(
+ sizeof(ioc_fm_pcd_kg_scheme_select_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
+
+ memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_select_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_kg_scheme_select_t *compat_param;
+
+ compat_param = (ioc_compat_fm_pcd_kg_scheme_select_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_pcd_kg_scheme_select_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_select_t));
+ if (copy_from_user(compat_param,
+ (ioc_compat_fm_pcd_kg_scheme_select_t *) compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_kg_scheme_select_t)))
+ {
+ XX_Free(compat_param);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ compat_copy_fm_pcd_kg_scheme_select(compat_param, param, COMPAT_US_TO_K);
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_select_t *)arg,
+ sizeof(ioc_fm_pcd_kg_scheme_select_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ err = FM_PORT_PcdKgModifyInitialScheme(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdKgSchemeSelect *)param);
+
+ XX_Free(param);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE_COMPAT:
+#endif
+ case FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE:
+ {
+ ioc_fm_obj_t id;
+
+ memset(&id, 0 , sizeof(ioc_fm_obj_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_obj_t compat_id;
+
+ if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ id.obj = compat_ptr(compat_id.obj);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ err = FM_PORT_PcdPlcrModifyInitialProfile(p_LnxWrpFmPortDev->h_Dev, id.obj);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PORT_IOC_PCD_KG_BIND_SCHEMES_COMPAT:
+#endif
+ case FM_PORT_IOC_PCD_KG_BIND_SCHEMES:
+ {
+ ioc_fm_pcd_port_schemes_params_t *param;
+
+ param = (ioc_fm_pcd_port_schemes_params_t *) XX_Malloc(
+ sizeof(ioc_fm_pcd_port_schemes_params_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
+
+ memset(param, 0 , sizeof(ioc_fm_pcd_port_schemes_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_port_schemes_params_t compat_param;
+
+ if (copy_from_user(&compat_param,
+ (ioc_compat_fm_pcd_port_schemes_params_t *) compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_port_schemes_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ compat_copy_fm_pcd_kg_schemes_params(&compat_param, param, COMPAT_US_TO_K);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_pcd_port_schemes_params_t *) arg,
+ sizeof(ioc_fm_pcd_port_schemes_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ err = FM_PORT_PcdKgBindSchemes(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdPortSchemesParams *)param);
+
+ XX_Free(param);
+ break;
+ }
+
+#if defined(CONFIG_COMPAT)
+ case FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES_COMPAT:
+#endif
+ case FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES:
+ {
+ ioc_fm_pcd_port_schemes_params_t *param;
+
+ param = (ioc_fm_pcd_port_schemes_params_t *) XX_Malloc(
+ sizeof(ioc_fm_pcd_port_schemes_params_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
+
+ memset(param, 0 , sizeof(ioc_fm_pcd_port_schemes_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_pcd_port_schemes_params_t compat_param;
+
+ if (copy_from_user(&compat_param,
+ (ioc_compat_fm_pcd_port_schemes_params_t *) compat_ptr(arg),
+ sizeof(ioc_compat_fm_pcd_port_schemes_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ compat_copy_fm_pcd_kg_schemes_params(&compat_param, param, COMPAT_US_TO_K);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_pcd_port_schemes_params_t *) arg,
+ sizeof(ioc_fm_pcd_port_schemes_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ err = FM_PORT_PcdKgUnbindSchemes(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdPortSchemesParams *)param);
+
+ XX_Free(param);
+ break;
+ }
+
+ case FM_PORT_IOC_PCD_PLCR_ALLOC_PROFILES:
+ {
+ uint16_t num;
+ if (get_user(num, (uint16_t*) arg))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ err = FM_PORT_PcdPlcrAllocProfiles(p_LnxWrpFmPortDev->h_Dev, num);
+ break;
+ }
+
+ case FM_PORT_IOC_PCD_PLCR_FREE_PROFILES:
+ err = FM_PORT_PcdPlcrFreeProfiles(p_LnxWrpFmPortDev->h_Dev);
+ break;
+
+ case FM_PORT_IOC_DETACH_PCD:
+ err = FM_PORT_DetachPCD(p_LnxWrpFmPortDev->h_Dev);
+ break;
+
+ case FM_PORT_IOC_ATTACH_PCD:
+ err = FM_PORT_AttachPCD(p_LnxWrpFmPortDev->h_Dev);
+ break;
+
+#if defined(CONFIG_COMPAT)
+ case FM_PORT_IOC_PCD_CC_MODIFY_TREE_COMPAT:
+#endif
+ case FM_PORT_IOC_PCD_CC_MODIFY_TREE:
+ {
+ ioc_fm_obj_t id;
+
+ memset(&id, 0 , sizeof(ioc_fm_obj_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_obj_t compat_id;
+
+ if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ compat_copy_fm_port_pcd_modify_tree(&compat_id, &id, COMPAT_US_TO_K);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ err = FM_PORT_PcdCcModifyTree(p_LnxWrpFmPortDev->h_Dev, id.obj);
+ break;
+ }
+
+ case FM_PORT_IOC_ADD_CONGESTION_GRPS:
+ case FM_PORT_IOC_REMOVE_CONGESTION_GRPS:
+ {
+ ioc_fm_port_congestion_groups_t *param;
+
+ param = (ioc_fm_port_congestion_groups_t*) XX_Malloc(sizeof(ioc_fm_port_congestion_groups_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
+
+ memset(param, 0, sizeof(ioc_fm_port_congestion_groups_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ if (copy_from_user(param, (t_FmPortCongestionGrps*) compat_ptr(arg),
+ sizeof(t_FmPortCongestionGrps)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+ else
+#endif /* CONFIG_COMPAT */
+ {
+ if (copy_from_user(param, (t_FmPortCongestionGrps*) arg,
+ sizeof(t_FmPortCongestionGrps)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ err = (cmd == FM_PORT_IOC_ADD_CONGESTION_GRPS)
+ ? FM_PORT_AddCongestionGrps(p_LnxWrpFmPortDev->h_Dev, (t_FmPortCongestionGrps*) param)
+ : FM_PORT_RemoveCongestionGrps(p_LnxWrpFmPortDev->h_Dev, (t_FmPortCongestionGrps*) param)
+ ;
+
+ XX_Free(param);
+ break;
+ }
+
+ case FM_PORT_IOC_ADD_RX_HASH_MAC_ADDR:
+ case FM_PORT_IOC_REMOVE_RX_HASH_MAC_ADDR:
+ {
+ ioc_fm_port_mac_addr_params_t *param;
+
+ param = (ioc_fm_port_mac_addr_params_t*) XX_Malloc(
+ sizeof(ioc_fm_port_mac_addr_params_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
+
+ memset(param, 0, sizeof(ioc_fm_port_mac_addr_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ if (copy_from_user(param, (ioc_fm_port_mac_addr_params_t*) compat_ptr(arg),
+ sizeof(ioc_fm_port_mac_addr_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+ else
+#endif /* CONFIG_COMPAT */
+ {
+ if (copy_from_user(param, (ioc_fm_port_mac_addr_params_t*) arg,
+ sizeof(ioc_fm_port_mac_addr_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ if (p_LnxWrpFmPortDev->pcd_owner_params.dev)
+ {
+ int id = -1;
+
+ switch(p_LnxWrpFmPortDev->settings.param.portType)
+ {
+ case e_FM_PORT_TYPE_RX:
+ case e_FM_PORT_TYPE_TX:
+ id = p_LnxWrpFmPortDev->id;
+ break;
+ case e_FM_PORT_TYPE_RX_10G:
+ case e_FM_PORT_TYPE_TX_10G:
+ id = p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_MACS;
+ break;
+ default:
+ err = E_NOT_AVAILABLE;
+ REPORT_ERROR(MINOR, err, ("Attempt to add/remove hash MAC addr. to/from MAC-less port!"));
+ }
+ if (id >= 0)
+ {
+ t_LnxWrpFmDev *fm = (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
+ t_Handle mac_handle = fm->macs[id].h_Dev;
+
+ err = (cmd == FM_PORT_IOC_ADD_RX_HASH_MAC_ADDR)
+ ? FM_MAC_AddHashMacAddr(mac_handle, (t_EnetAddr*) param)
+ : FM_MAC_RemoveHashMacAddr(mac_handle, (t_EnetAddr*) param);
+ }
+ }
+ else
+ {
+ err = E_NOT_AVAILABLE;
+ REPORT_ERROR(MINOR, err, ("Port not initialized or other error!?!?"));
+ }
+
+ XX_Free(param);
+ break;
+ }
+
+ case FM_PORT_IOC_SET_TX_PAUSE_FRAMES:
+ {
+ t_LnxWrpFmDev *p_LnxWrpFmDev =
+ (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
+ ioc_fm_port_tx_pause_frames_params_t param;
+ int mac_id = p_LnxWrpFmPortDev->id;
+
+ if(&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev)
+ mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */
+
+ if (copy_from_user(&param, (ioc_fm_port_tx_pause_frames_params_t *)arg,
+ sizeof(ioc_fm_port_tx_pause_frames_params_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ if (p_LnxWrpFmDev && p_LnxWrpFmDev->macs[mac_id].h_Dev)
+ {
+ FM_MAC_SetTxPauseFrames(p_LnxWrpFmDev->macs[mac_id].h_Dev,
+ param.priority,
+ param.pause_time,
+ param.thresh_time);
+ }
+ else
+ {
+ err = E_NOT_AVAILABLE;
+ REPORT_ERROR(MINOR, err, ("Port not initialized or other error!"));
+ }
+
+ break;
+ }
+
+ case FM_PORT_IOC_CONFIG_BUFFER_PREFIX_CONTENT:
+ {
+ ioc_fm_buffer_prefix_content_t *param;
+
+ param = (ioc_fm_buffer_prefix_content_t*) XX_Malloc(sizeof(ioc_fm_buffer_prefix_content_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
+
+ memset(param, 0, sizeof(ioc_fm_buffer_prefix_content_t));
+
+ if (copy_from_user(param, (ioc_fm_buffer_prefix_content_t*) arg,
+ sizeof(ioc_fm_buffer_prefix_content_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ if (FM_PORT_ConfigBufferPrefixContent(p_LnxWrpFmPortDev->h_Dev,
+ (t_FmBufferPrefixContent *)param))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ XX_Free(param);
+ break;
+ }
+
+#if (DPAA_VERSION >= 11)
+#if defined(CONFIG_COMPAT)
+ case FM_PORT_IOC_VSP_ALLOC_COMPAT:
+#endif
+ case FM_PORT_IOC_VSP_ALLOC:
+ {
+ ioc_fm_port_vsp_alloc_params_t *param;
+ t_LnxWrpFmDev *p_LnxWrpFmDev;
+ t_LnxWrpFmPortDev *p_LnxWrpFmTxPortDev;
+
+ param = (ioc_fm_port_vsp_alloc_params_t *) XX_Malloc(
+ sizeof(ioc_fm_port_vsp_alloc_params_t));
+ if (!param)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
+
+ memset(param, 0, sizeof(ioc_fm_port_vsp_alloc_params_t));
+
+#if defined(CONFIG_COMPAT)
+ if (compat)
+ {
+ ioc_compat_fm_port_vsp_alloc_params_t *compat_param;
+
+ compat_param = (ioc_compat_fm_port_vsp_alloc_params_t *) XX_Malloc(
+ sizeof(ioc_compat_fm_port_vsp_alloc_params_t));
+ if (!compat_param)
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
+ }
+
+ memset(compat_param, 0, sizeof(ioc_compat_fm_port_vsp_alloc_params_t));
+ if (copy_from_user(compat_param,
+ (ioc_compat_fm_port_vsp_alloc_params_t *) compat_ptr(arg),
+ sizeof(ioc_compat_fm_port_vsp_alloc_params_t)))
+ {
+ XX_Free(compat_param);
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ compat_copy_fm_port_vsp_alloc_params(compat_param, param, COMPAT_US_TO_K);
+
+ XX_Free(compat_param);
+ }
+ else
+#endif
+ {
+ if (copy_from_user(param, (ioc_fm_port_vsp_alloc_params_t *)arg,
+ sizeof(ioc_fm_port_vsp_alloc_params_t)))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+ }
+
+ /* Userspace may not have the Tx port t_handle when issuing the IOCTL */
+ if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX ||
+ p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G)
+ {
+ /* Determine the Tx port t_Handle from the Rx port id */
+ p_LnxWrpFmDev = p_LnxWrpFmPortDev->h_LnxWrpFmDev;
+ p_LnxWrpFmTxPortDev = &p_LnxWrpFmDev->txPorts[p_LnxWrpFmPortDev->id];
+ param->p_fm_tx_port = p_LnxWrpFmTxPortDev->h_Dev;
+ }
+
+ if (FM_PORT_VSPAlloc(p_LnxWrpFmPortDev->h_Dev, (t_FmPortVSPAllocParams *)param))
+ {
+ XX_Free(param);
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+ }
+
+ XX_Free(param);
+ break;
+ }
+#endif /* (DPAA_VERSION >= 11) */
+
+ case FM_PORT_IOC_GET_MAC_STATISTICS:
+ {
+ t_LnxWrpFmDev *p_LnxWrpFmDev =
+ (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
+ ioc_fm_port_mac_statistics_t param;
+ int mac_id = p_LnxWrpFmPortDev->id;
+
+ if (!p_LnxWrpFmDev)
+ RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
+
+ if (&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev &&
+ &p_LnxWrpFmDev->rxPorts[mac_id] != p_LnxWrpFmPortDev)
+ mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */
+
+ if (!p_LnxWrpFmDev->macs[mac_id].h_Dev)
+ RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
+
+ if (FM_MAC_GetStatistics(p_LnxWrpFmDev->macs[mac_id].h_Dev,
+ (t_FmMacStatistics *)&param))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ if (copy_to_user((ioc_fm_port_mac_statistics_t *)arg, &param,
+ sizeof(ioc_fm_port_mac_statistics_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ break;
+ }
+
+ case FM_PORT_IOC_GET_MAC_FRAME_SIZE_COUNTERS:
+ {
+ t_LnxWrpFmDev *p_LnxWrpFmDev =
+ (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
+ ioc_fm_port_mac_frame_size_counters_t param;
+ t_FmMacFrameSizeCounters frameSizeCounters;
+ int mac_id = p_LnxWrpFmPortDev->id;
+
+ if (!p_LnxWrpFmDev)
+ RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
+
+ if (&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev &&
+ &p_LnxWrpFmDev->rxPorts[mac_id] != p_LnxWrpFmPortDev)
+ mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */
+
+ if (!p_LnxWrpFmDev->macs[mac_id].h_Dev)
+ RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
+
+ if (copy_from_user(&param, (ioc_fm_port_mac_frame_size_counters_t *)arg,
+ sizeof(ioc_fm_port_mac_frame_size_counters_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ if (FM_MAC_GetFrameSizeCounters(p_LnxWrpFmDev->macs[mac_id].h_Dev,
+ &frameSizeCounters, param.type))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ param.count_pkts_64 = frameSizeCounters.count_pkts_64;
+ param.count_pkts_65_to_127 = frameSizeCounters.count_pkts_65_to_127;
+ param.count_pkts_128_to_255 = frameSizeCounters.count_pkts_128_to_255;
+ param.count_pkts_256_to_511 = frameSizeCounters.count_pkts_256_to_511;
+ param.count_pkts_512_to_1023 = frameSizeCounters.count_pkts_512_to_1023;
+ param.count_pkts_1024_to_1518 = frameSizeCounters.count_pkts_1024_to_1518;
+ param.count_pkts_1519_to_1522 = frameSizeCounters.count_pkts_1519_to_1522;
+
+ if (copy_to_user((ioc_fm_port_mac_frame_size_counters_t *)arg, &param,
+ sizeof(ioc_fm_port_mac_frame_size_counters_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ break;
+ }
+
+ case FM_PORT_IOC_GET_BMI_COUNTERS:
+ {
+ t_LnxWrpFmDev *p_LnxWrpFmDev =
+ (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
+ ioc_fm_port_bmi_stats_t param;
+
+ if (!p_LnxWrpFmDev)
+ RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
+
+ if (FM_PORT_GetBmiCounters(p_LnxWrpFmPortDev->h_Dev,
+ (t_FmPortBmiStats *)&param))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ if (copy_to_user((ioc_fm_port_bmi_stats_t *)arg, &param,
+ sizeof(ioc_fm_port_bmi_stats_t)))
+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
+
+ break;
+ }
+
+ default:
+ RETURN_ERROR(MINOR, E_INVALID_SELECTION,
+ ("invalid ioctl: cmd:0x%08x(type:0x%02x, nr:0x%02x.\n",
+ cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)));
+ }
+
+ if (err)
+ RETURN_ERROR(MINOR, E_INVALID_OPERATION, ("IOCTL FM PORT"));
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+/* API routines for the FM Linux Device */
+/*****************************************************************************/
+
+static int fm_open(struct inode *inode, struct file *file)
+{
+ t_LnxWrpFmDev *p_LnxWrpFmDev = NULL;
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = NULL;
+ unsigned int major = imajor(inode);
+ unsigned int minor = iminor(inode);
+ struct device_node *fm_node;
+ static struct of_device_id fm_node_of_match[] = {
+ { .compatible = "fsl,fman", },
+ { /* end of list */ },
+ };
+
+ DBG(TRACE, ("Opening minor - %d - ", minor));
+
+ if (file->private_data != NULL)
+ return 0;
+
+ /* Get all the FM nodes */
+ for_each_matching_node(fm_node, fm_node_of_match) {
+ struct platform_device *of_dev;
+
+ of_dev = of_find_device_by_node(fm_node);
+ if (unlikely(of_dev == NULL)) {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
+ return -ENXIO;
+ }
+
+ p_LnxWrpFmDev = (t_LnxWrpFmDev *)fm_bind(&of_dev->dev);
+ if (p_LnxWrpFmDev->major == major)
+ break;
+ fm_unbind((struct fm *)p_LnxWrpFmDev);
+ p_LnxWrpFmDev = NULL;
+ }
+
+ if (!p_LnxWrpFmDev)
+ return -ENODEV;
+
+ if (minor == DEV_FM_MINOR_BASE)
+ file->private_data = p_LnxWrpFmDev;
+ else if (minor == DEV_FM_PCD_MINOR_BASE)
+ file->private_data = p_LnxWrpFmDev;
+ else {
+ if (minor == DEV_FM_OH_PORTS_MINOR_BASE)
+ p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
+ else if ((minor > DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE))
+ p_LnxWrpFmPortDev = &p_LnxWrpFmDev->opPorts[minor-DEV_FM_OH_PORTS_MINOR_BASE-1];
+ else if ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE))
+ p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[minor-DEV_FM_RX_PORTS_MINOR_BASE];
+ else if ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS))
+ p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[minor-DEV_FM_TX_PORTS_MINOR_BASE];
+ else
+ return -EINVAL;
+
+ /* if trying to open port, check if it initialized */
+ if (!p_LnxWrpFmPortDev->h_Dev)
+ return -ENODEV;
+
+ p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)fm_port_bind(p_LnxWrpFmPortDev->dev);
+ file->private_data = p_LnxWrpFmPortDev;
+ fm_unbind((struct fm *)p_LnxWrpFmDev);
+ }
+
+ if (file->private_data == NULL)
+ return -ENXIO;
+
+ return 0;
+}
+
+static int fm_close(struct inode *inode, struct file *file)
+{
+ t_LnxWrpFmDev *p_LnxWrpFmDev;
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
+ unsigned int minor = iminor(inode);
+ int err = 0;
+
+ DBG(TRACE, ("Closing minor - %d - ", minor));
+
+ if ((minor == DEV_FM_MINOR_BASE) ||
+ (minor == DEV_FM_PCD_MINOR_BASE))
+ {
+ p_LnxWrpFmDev = (t_LnxWrpFmDev*)file->private_data;
+ if (!p_LnxWrpFmDev)
+ return -ENODEV;
+ fm_unbind((struct fm *)p_LnxWrpFmDev);
+ }
+ else if (((minor >= DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE)) ||
+ ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE)) ||
+ ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS)))
+ {
+ p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)file->private_data;
+ if (!p_LnxWrpFmPortDev)
+ return -ENODEV;
+ fm_port_unbind((struct fm_port *)p_LnxWrpFmPortDev);
+ }
+
+ return err;
+}
+
+static int fm_ioctls(unsigned int minor, struct file *file, unsigned int cmd, unsigned long arg, bool compat)
+{
+ DBG(TRACE, ("IOCTL minor - %u, cmd - 0x%08x, arg - 0x%08lx \n", minor, cmd, arg));
+
+ if ((minor == DEV_FM_MINOR_BASE) ||
+ (minor == DEV_FM_PCD_MINOR_BASE))
+ {
+ t_LnxWrpFmDev *p_LnxWrpFmDev = ((t_LnxWrpFmDev*)file->private_data);
+ if (!p_LnxWrpFmDev)
+ return -ENODEV;
+ if (LnxwrpFmIOCTL(p_LnxWrpFmDev, cmd, arg, compat))
+ return -EFAULT;
+ }
+ else if (((minor >= DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE)) ||
+ ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE)) ||
+ ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS)))
+ {
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = ((t_LnxWrpFmPortDev*)file->private_data);
+ if (!p_LnxWrpFmPortDev)
+ return -ENODEV;
+ if (LnxwrpFmPortIOCTL(p_LnxWrpFmPortDev, cmd, arg, compat))
+ return -EFAULT;
+ }
+ else
+ {
+ REPORT_ERROR(MINOR, E_INVALID_VALUE, ("minor"));
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_COMPAT
+static long fm_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ unsigned int minor = iminor(file->f_path.dentry->d_inode);
+ long res;
+
+ fm_mutex_lock();
+ res = fm_ioctls(minor, file, cmd, arg, true);
+ fm_mutex_unlock();
+
+ return res;
+}
+#endif
+
+static long fm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ unsigned int minor = iminor(file->f_path.dentry->d_inode);
+ long res;
+
+ fm_mutex_lock();
+ res = fm_ioctls(minor, file, cmd, arg, false);
+ fm_mutex_unlock();
+
+ return res;
+}
+
+/* Globals for FM character device */
+struct file_operations fm_fops =
+{
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = fm_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = fm_compat_ioctl,
+#endif
+ .open = fm_open,
+ .release = fm_close,
+};
diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c
new file mode 100644
index 000000000000..515f4d04538c
--- /dev/null
+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c
@@ -0,0 +1,1299 @@
+/*
+ * 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_compat_ioctls.c
+
+ @Description FM PCD compat functions
+
+*/
+
+#if !defined(CONFIG_COMPAT)
+#error "missing COMPAT layer..."
+#endif
+
+
+#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 <asm/uaccess.h>
+#include <asm/errno.h>
+#ifndef CONFIG_FMAN_ARM
+#include <sysdev/fsl_soc.h>
+#endif
+
+#include "part_ext.h"
+#include "fm_ioctls.h"
+#include "fm_pcd_ioctls.h"
+#include "fm_port_ioctls.h"
+#include "lnxwrp_ioctls_fm_compat.h"
+
+#if defined(FM_COMPAT_DBG)
+static void hex_dump(void * p_addr, unsigned int size)
+{
+ int i;
+
+ for(i=0; i<size; i+=16)
+ {
+ printk("%p: 0x%08x 0x%08x 0x%08x 0x%08x\n", p_addr + i,
+ *(unsigned int *)(p_addr + i),
+ *(unsigned int *)(p_addr + i + 4),
+ *(unsigned int *)(p_addr + i + 8),
+ *(unsigned int *)(p_addr + i +12)
+ );
+ }
+}
+#endif
+
+/* maping kernel pointers w/ UserSpace id's { */
+struct map_node {
+ void *ptr;
+ u8 node_type;
+};
+
+static struct map_node compat_ptr2id_array[COMPAT_PTR2ID_ARRAY_MAX] = {{NULL},{FM_MAP_TYPE_UNSPEC}};
+
+void compat_del_ptr2id(void *p, enum fm_map_node_type node_type)
+{
+ compat_uptr_t k;
+
+ _fm_cpt_dbg(COMPAT_GENERIC, "delete (%p)\n", p);
+
+ for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
+ if(compat_ptr2id_array[k].ptr == p){
+ compat_ptr2id_array[k].ptr = NULL;
+ compat_ptr2id_array[k].node_type = FM_MAP_TYPE_UNSPEC;
+ }
+}
+EXPORT_SYMBOL(compat_del_ptr2id);
+
+compat_uptr_t compat_add_ptr2id(void *p, enum fm_map_node_type node_type)
+{
+ compat_uptr_t k;
+
+ _fm_cpt_dbg(COMPAT_GENERIC, " (%p) do ->\n", p);
+
+ if(!p)
+ return 0;
+
+ for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
+ if(compat_ptr2id_array[k].ptr == NULL)
+ {
+ compat_ptr2id_array[k].ptr = p;
+ compat_ptr2id_array[k].node_type = node_type;
+ _fm_cpt_dbg(COMPAT_GENERIC, "0x%08x \n", k | COMPAT_PTR2ID_WATERMARK);
+ return k | COMPAT_PTR2ID_WATERMARK;
+ }
+
+ printk(KERN_WARNING "FMan map list full! No more PCD space on kernel!\n");
+ return 0;
+}
+EXPORT_SYMBOL(compat_add_ptr2id);
+
+compat_uptr_t compat_get_ptr2id(void *p, enum fm_map_node_type node_type)
+{
+ compat_uptr_t k;
+
+ _fm_cpt_dbg(COMPAT_GENERIC, " (%p) get -> \n", p);
+
+ for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
+ if(compat_ptr2id_array[k].ptr == p &&
+ compat_ptr2id_array[k].node_type == node_type) {
+
+ _fm_cpt_dbg(COMPAT_GENERIC, "0x%08x\n", k | COMPAT_PTR2ID_WATERMARK);
+ return k | COMPAT_PTR2ID_WATERMARK;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(compat_get_ptr2id);
+
+void *compat_get_id2ptr(compat_uptr_t comp, enum fm_map_node_type node_type)
+{
+
+ _fm_cpt_dbg(COMPAT_GENERIC, " (0x%08x) get -> \n", comp);
+
+ if((COMPAT_PTR2ID_WM_MASK & comp) != COMPAT_PTR2ID_WATERMARK) {
+ _fm_cpt_dbg(COMPAT_GENERIC, "Error, invalid watermark (0x%08x)!\n\n", comp);
+ dump_stack();
+ return compat_ptr(comp);
+ }
+
+ comp &= ~COMPAT_PTR2ID_WM_MASK;
+
+ if(((0 < comp) && (comp < COMPAT_PTR2ID_ARRAY_MAX) && (compat_ptr2id_array[comp].ptr != NULL)
+ && compat_ptr2id_array[comp].node_type == node_type)) {
+ _fm_cpt_dbg(COMPAT_GENERIC, "%p\n", compat_ptr2id_array[comp].ptr);
+ return compat_ptr2id_array[comp].ptr;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(compat_get_id2ptr);
+/* } maping kernel pointers w/ UserSpace id's */
+
+void compat_obj_delete(
+ ioc_compat_fm_obj_t *compat_id,
+ ioc_fm_obj_t *id)
+{
+ id->obj = compat_pcd_id2ptr(compat_id->obj);
+ compat_del_ptr2id(id->obj, FM_MAP_TYPE_PCD_NODE);
+}
+
+static inline void compat_copy_fm_pcd_plcr_next_engine(
+ ioc_compat_fm_pcd_plcr_next_engine_params_u *compat_param,
+ ioc_fm_pcd_plcr_next_engine_params_u *param,
+ ioc_fm_pcd_engine next_engine,
+ uint8_t compat)
+{
+ _fm_cpt_dbg (compat, " {->...\n");
+
+ switch (next_engine)
+ {
+ case e_IOC_FM_PCD_PLCR:
+ if (compat == COMPAT_US_TO_K)
+ param->p_profile = compat_pcd_id2ptr(compat_param->p_profile);
+ else
+ compat_param->p_profile = compat_pcd_ptr2id(param->p_profile);
+ break;
+ case e_IOC_FM_PCD_KG:
+ if (compat == COMPAT_US_TO_K)
+ param->p_direct_scheme = compat_pcd_id2ptr(compat_param->p_direct_scheme);
+ else
+ compat_param->p_direct_scheme = compat_pcd_ptr2id(param->p_direct_scheme);
+ break;
+ default:
+ if (compat == COMPAT_US_TO_K)
+ param->action = compat_param->action;
+ else
+ compat_param->action = param->action;
+ break;
+ }
+
+ _fm_cpt_dbg (compat, " ...->}\n");
+}
+
+void compat_copy_fm_pcd_plcr_profile(
+ ioc_compat_fm_pcd_plcr_profile_params_t *compat_param,
+ ioc_fm_pcd_plcr_profile_params_t *param,
+ uint8_t compat)
+{
+ _fm_cpt_dbg (compat, " {->...\n");
+
+ if (compat == COMPAT_US_TO_K)
+ {
+ param->modify = compat_param->modify;
+
+ /* profile_select */
+ if (!compat_param->modify)
+ {
+ param->profile_select.new_params.profile_type =
+ compat_param->profile_select.new_params.profile_type;
+ param->profile_select.new_params.p_fm_port =
+ compat_ptr(compat_param->profile_select.new_params.p_fm_port);
+ param->profile_select.new_params.relative_profile_id =
+ compat_param->profile_select.new_params.relative_profile_id;
+ }
+ else
+ param->profile_select.p_profile =
+ compat_pcd_id2ptr(compat_param->profile_select.p_profile);
+
+ param->alg_selection = compat_param->alg_selection;
+ param->color_mode = compat_param->color_mode;
+
+ /* both parameters in the union has the same size, so memcpy works */
+ memcpy(&param->color, &compat_param->color, sizeof(param->color));
+
+ memcpy(&param->non_passthrough_alg_param,
+ &compat_param->non_passthrough_alg_param,
+ sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t));
+
+ param->next_engine_on_green = compat_param->next_engine_on_green;
+ param->next_engine_on_yellow = compat_param->next_engine_on_yellow;
+ param->next_engine_on_red = compat_param->next_engine_on_red;
+
+ param->trap_profile_on_flow_A = compat_param->trap_profile_on_flow_A;
+ param->trap_profile_on_flow_B = compat_param->trap_profile_on_flow_B;
+ param->trap_profile_on_flow_C = compat_param->trap_profile_on_flow_C;
+ }
+ else
+ {
+ compat_param->modify = param->modify;
+
+ /* profile_select */
+ if (!param->modify)
+ {
+ compat_param->profile_select.new_params.profile_type =
+ param->profile_select.new_params.profile_type;
+ compat_param->profile_select.new_params.p_fm_port =
+ ptr_to_compat(param->profile_select.new_params.p_fm_port);
+ compat_param->profile_select.new_params.relative_profile_id =
+ param->profile_select.new_params.relative_profile_id;
+ }
+ else
+ compat_param->profile_select.p_profile =
+ compat_pcd_ptr2id(param->profile_select.p_profile);
+
+ compat_param->alg_selection = param->alg_selection;
+ compat_param->color_mode = param->color_mode;
+
+ /* both parameters in the union has the same size, so memcpy works */
+ memcpy(&compat_param->color, &param->color, sizeof(compat_param->color));
+
+ memcpy(&compat_param->non_passthrough_alg_param,
+ &param->non_passthrough_alg_param,
+ sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t));
+
+ compat_param->next_engine_on_green = param->next_engine_on_green;
+ compat_param->next_engine_on_yellow = param->next_engine_on_yellow;
+ compat_param->next_engine_on_red = param->next_engine_on_red;
+
+ compat_param->trap_profile_on_flow_A = param->trap_profile_on_flow_A;
+ compat_param->trap_profile_on_flow_B = param->trap_profile_on_flow_B;
+ compat_param->trap_profile_on_flow_C = param->trap_profile_on_flow_C;
+
+ compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
+ }
+
+ compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_green,
+ &param->params_on_green, param->next_engine_on_green, compat);
+
+ compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_yellow,
+ &param->params_on_yellow, param->next_engine_on_yellow, compat);
+
+ compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_red,
+ &param->params_on_red, param->next_engine_on_red, compat);
+
+ _fm_cpt_dbg (compat, " ...->}\n");
+}
+
+static inline void compat_copy_fm_pcd_cc_next_kg(
+ ioc_compat_fm_pcd_cc_next_kg_params_t *compat_param,
+ ioc_fm_pcd_cc_next_kg_params_t *param,
+ uint8_t compat)
+{
+ _fm_cpt_dbg (compat, " {->...\n");
+
+ if (compat == COMPAT_US_TO_K)
+ {
+ param->new_fqid = compat_param->new_fqid;
+ param->override_fqid = compat_param->override_fqid;
+#if DPAA_VERSION >= 11
+ param->new_relative_storage_profile_id = compat_param->new_relative_storage_profile_id;
+#endif
+ param->p_direct_scheme = compat_pcd_id2ptr(compat_param->p_direct_scheme);
+ }
+ else
+ {
+ compat_param->new_fqid = param->new_fqid;
+ compat_param->override_fqid = param->override_fqid;
+#if DPAA_VERSION >= 11
+ compat_param->new_relative_storage_profile_id = param->new_relative_storage_profile_id;
+#endif
+ compat_param->p_direct_scheme = compat_pcd_ptr2id(param->p_direct_scheme);
+ }
+
+ _fm_cpt_dbg (compat, " ...->}\n");
+}
+
+static inline void compat_copy_fm_pcd_cc_next_cc(
+ ioc_compat_fm_pcd_cc_next_cc_params_t *compat_param,
+ ioc_fm_pcd_cc_next_cc_params_t *param,
+ uint8_t compat)
+{
+ _fm_cpt_dbg (compat, " {->...\n");
+
+ if (compat == COMPAT_US_TO_K)
+ param->cc_node_id = compat_pcd_id2ptr(compat_param->cc_node_id);
+ else
+ compat_param->cc_node_id = compat_pcd_ptr2id(param->cc_node_id);
+
+ _fm_cpt_dbg (compat, " ...->}\n");
+}
+
+static inline void compat_copy_fm_pcd_cc_next_engine(
+ ioc_compat_fm_pcd_cc_next_engine_params_t *compat_param,
+ ioc_fm_pcd_cc_next_engine_params_t *param,
+ uint8_t compat)
+{
+ _fm_cpt_dbg (compat, " {->...\n");
+
+ if (compat == COMPAT_US_TO_K)
+ {
+ param->next_engine = compat_param->next_engine;
+ if (param->next_engine != e_IOC_FM_PCD_INVALID )
+ _fm_cpt_dbg(compat, " param->next_engine = %i \n", param->next_engine);
+
+ switch (param->next_engine)
+ {
+#if DPAA_VERSION >= 11
+ case e_IOC_FM_PCD_FR:
+ param->params.fr_params.frm_replic_id = compat_pcd_id2ptr(compat_param->params.fr_params.frm_replic_id);
+ break;
+#endif /* DPAA_VERSION >= 11 */
+ case e_IOC_FM_PCD_CC:
+ param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
+ compat_copy_fm_pcd_cc_next_cc(&compat_param->params.cc_params, &param->params.cc_params, compat);
+ break;
+ case e_IOC_FM_PCD_KG:
+ param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
+ compat_copy_fm_pcd_cc_next_kg(&compat_param->params.kg_params, &param->params.kg_params, compat);
+ break;
+ case e_IOC_FM_PCD_DONE:
+ case e_IOC_FM_PCD_PLCR:
+ param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
+ fallthrough;
+ default:
+ memcpy(&param->params, &compat_param->params, sizeof(param->params));
+ }
+ param->statistics_en = compat_param->statistics_en;
+ }
+ else
+ {
+ compat_param->next_engine = param->next_engine;
+
+ switch (compat_param->next_engine)
+ {
+#if DPAA_VERSION >= 11
+ case e_IOC_FM_PCD_FR:
+ compat_param->params.fr_params.frm_replic_id = compat_pcd_ptr2id(param->params.fr_params.frm_replic_id);
+ break;
+#endif /* DPAA_VERSION >= 11 */
+ case e_IOC_FM_PCD_CC:
+ compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
+ compat_copy_fm_pcd_cc_next_cc(&compat_param->params.cc_params, &param->params.cc_params, compat);
+ break;
+ case e_IOC_FM_PCD_KG:
+ compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
+ compat_copy_fm_pcd_cc_next_kg(&compat_param->params.kg_params, &param->params.kg_params, compat);
+ break;
+ case e_IOC_FM_PCD_DONE:
+ case e_IOC_FM_PCD_PLCR:
+ compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
+ fallthrough;
+ default:
+ memcpy(&compat_param->params, &param->params, sizeof(compat_param->params));
+ }
+ compat_param->statistics_en = param->statistics_en;
+ }
+
+ _fm_cpt_dbg (compat, " ...->}\n");
+}
+
+void compat_copy_fm_pcd_cc_key(
+ ioc_compat_fm_pcd_cc_key_params_t *compat_param,
+ ioc_fm_pcd_cc_key_params_t *param,
+ uint8_t compat)
+{
+ if (compat == COMPAT_US_TO_K)
+ {
+ param->p_key = compat_ptr(compat_param->p_key);
+ param->p_mask = compat_ptr(compat_param->p_mask);
+ }
+ else
+ {
+ compat_param->p_key = ptr_to_compat(param->p_key);
+ compat_param->p_mask = ptr_to_compat(param->p_mask);
+ }
+
+ compat_copy_fm_pcd_cc_next_engine(
+ &compat_param->cc_next_engine_params,
+ &param->cc_next_engine_params,
+ compat);
+}
+
+void compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(
+ ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param,
+ ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param,
+ uint8_t compat)
+{
+ if (compat == COMPAT_US_TO_K)
+ {
+ param->id = compat_pcd_id2ptr(compat_param->id);
+ param->key_indx = compat_param->key_indx;
+ param->key_size = compat_param->key_size;
+ compat_copy_fm_pcd_cc_key(
+ &compat_param->key_params,
+ &param->key_params,
+ compat);
+ }
+ else
+ {
+ compat_param->id = compat_pcd_ptr2id(param->id);
+ compat_param->key_indx = param->key_indx;
+ compat_param->key_size = param->key_size;
+ compat_copy_fm_pcd_cc_key(
+ &compat_param->key_params,
+ &param->key_params,
+ compat);
+ }
+}
+
+void compat_copy_fm_pcd_cc_node_modify_next_engine(
+ ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param,
+ ioc_fm_pcd_cc_node_modify_next_engine_params_t *param,
+ uint8_t compat)
+{
+ if (compat == COMPAT_US_TO_K)
+ {
+ param->id = compat_pcd_id2ptr(compat_param->id);
+ param->key_indx = compat_param->key_indx;
+ param->key_size = compat_param->key_size;
+ }
+ else
+ {
+ compat_param->id = compat_pcd_ptr2id(param->id);
+ compat_param->key_indx = param->key_indx;
+ compat_param->key_size = param->key_size;
+ }
+
+ compat_copy_fm_pcd_cc_next_engine(
+ &compat_param->cc_next_engine_params,
+ &param->cc_next_engine_params,
+ compat);
+}
+
+void compat_fm_pcd_cc_tree_modify_next_engine(
+ ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param,
+ ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param,
+ uint8_t compat)
+{
+ if (compat == COMPAT_US_TO_K)
+ {
+ param->id = compat_pcd_id2ptr(compat_param->id);
+ param->grp_indx = compat_param->grp_indx;
+ param->indx = compat_param->indx;
+ }
+ else
+ {
+ compat_param->id = compat_pcd_ptr2id(param->id);
+ compat_param->grp_indx = param->grp_indx;
+ compat_param->indx = param->indx;
+ }
+
+ compat_copy_fm_pcd_cc_next_engine(
+ &compat_param->cc_next_engine_params,
+ &param->cc_next_engine_params,
+ compat);
+}
+
+void compat_copy_fm_pcd_hash_table(
+ ioc_compat_fm_pcd_hash_table_params_t *compat_param,
+ ioc_fm_pcd_hash_table_params_t *param,
+ uint8_t compat)
+{
+ if (compat == COMPAT_US_TO_K)
+ {
+ param->max_num_of_keys = compat_param->max_num_of_keys;
+ param->statistics_mode = compat_param->statistics_mode;
+ param->kg_hash_shift = compat_param->kg_hash_shift;
+ param->hash_res_mask = compat_param->hash_res_mask;
+ param->hash_shift = compat_param->hash_shift;
+ param->match_key_size = compat_param->match_key_size;
+ param->id = compat_pcd_id2ptr(compat_param->id);
+ }
+ else
+ {
+ compat_param->max_num_of_keys = param->max_num_of_keys;
+ compat_param->statistics_mode = param->statistics_mode;
+ compat_param->kg_hash_shift = param->kg_hash_shift;
+ compat_param->hash_res_mask = param->hash_res_mask;
+ compat_param->hash_shift = param->hash_shift;
+ compat_param->match_key_size = param->match_key_size;
+
+ compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
+ }
+
+ compat_copy_fm_pcd_cc_next_engine(
+ &compat_param->cc_next_engine_params_for_miss,
+ &param->cc_next_engine_params_for_miss,
+ compat);
+}
+
+void compat_copy_fm_pcd_cc_grp(
+ ioc_compat_fm_pcd_cc_grp_params_t *compat_param,
+ ioc_fm_pcd_cc_grp_params_t *param,
+ uint8_t compat)
+{
+ int k;
+
+ _fm_cpt_dbg (compat, " {->...\n");
+
+ if (compat == COMPAT_US_TO_K)
+ {
+ param->num_of_distinction_units = compat_param->num_of_distinction_units;
+ memcpy(param->unit_ids, compat_param->unit_ids, IOC_FM_PCD_MAX_NUM_OF_CC_UNITS);
+ }
+ else
+ {
+ compat_param->num_of_distinction_units = param->num_of_distinction_units;
+ memcpy(compat_param->unit_ids, param->unit_ids, IOC_FM_PCD_MAX_NUM_OF_CC_UNITS);
+ }
+
+ for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP; k++)
+ compat_copy_fm_pcd_cc_next_engine(
+ &compat_param->next_engine_per_entries_in_grp[k],
+ &param->next_engine_per_entries_in_grp[k],
+ compat);
+
+ _fm_cpt_dbg (compat, " ...->}\n");
+}
+
+void compat_copy_fm_pcd_cc_tree(
+ ioc_compat_fm_pcd_cc_tree_params_t *compat_param,
+ ioc_fm_pcd_cc_tree_params_t *param,
+ uint8_t compat)
+{
+ int k;
+ _fm_cpt_dbg (compat, " {->...\n");
+
+ if (compat == COMPAT_US_TO_K)
+ {
+ param->net_env_id = compat_pcd_id2ptr(compat_param->net_env_id);
+ param->num_of_groups = compat_param->num_of_groups;
+ }
+ else
+ {
+ compat_param->net_env_id = compat_pcd_ptr2id(param->net_env_id);
+ compat_param->num_of_groups = param->num_of_groups;
+
+ compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
+ }
+
+ for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS; k++)
+ compat_copy_fm_pcd_cc_grp(
+ &compat_param->fm_pcd_cc_group_params[k],
+ &param->fm_pcd_cc_group_params[k],
+ compat);
+
+ _fm_cpt_dbg (compat, " ...->}\n");
+}
+
+void compat_fm_pcd_prs_sw(
+ ioc_compat_fm_pcd_prs_sw_params_t *compat_param,
+ ioc_fm_pcd_prs_sw_params_t *param,
+ uint8_t compat)
+{
+ if (compat == COMPAT_US_TO_K)
+ {
+ param->override = compat_param->override;
+ param->size = compat_param->size;
+ param->base = compat_param->base;
+ param->p_code = compat_ptr(compat_param->p_code);
+ memcpy(param->sw_prs_data_params,compat_param->sw_prs_data_params,IOC_FM_PCD_PRS_NUM_OF_HDRS*sizeof(uint32_t));
+ param->num_of_labels = compat_param->num_of_labels;
+ memcpy(param->labels_table,compat_param->labels_table,IOC_FM_PCD_PRS_NUM_OF_LABELS*sizeof(ioc_fm_pcd_prs_label_params_t));
+ }
+}
+
+void compat_copy_fm_pcd_kg_scheme(
+ ioc_compat_fm_pcd_kg_scheme_params_t *compat_param,
+ ioc_fm_pcd_kg_scheme_params_t *param,
+ uint8_t compat)
+{
+ _fm_cpt_dbg(compat," {->...\n");
+
+ if (compat == COMPAT_US_TO_K)
+ {
+ param->modify = compat_param->modify;
+
+ /* scm_id */
+ if (compat_param->modify)
+ {
+ param->scm_id.scheme_id = compat_pcd_id2ptr(compat_param->scm_id.scheme_id);
+ _fm_cpt_dbg(compat," param->scm_id.scheme_id = %p \n", param->scm_id.scheme_id);
+ }
+ else
+ param->scm_id.relative_scheme_id = compat_param->scm_id.relative_scheme_id;
+
+ param->always_direct = compat_param->always_direct;
+ /* net_env_params */
+ param->net_env_params.net_env_id = compat_pcd_id2ptr(compat_param->net_env_params.net_env_id);
+ param->net_env_params.num_of_distinction_units = compat_param->net_env_params.num_of_distinction_units;
+ memcpy(param->net_env_params.unit_ids,
+ compat_param->net_env_params.unit_ids,
+ IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
+
+ param->use_hash = compat_param->use_hash;
+ memcpy(&param->key_extract_and_hash_params,
+ &compat_param->key_extract_and_hash_params,
+ sizeof(ioc_fm_pcd_kg_key_extract_and_hash_params_t));
+ param->bypass_fqid_generation = compat_param->bypass_fqid_generation;
+ param->base_fqid = compat_param->base_fqid;
+#if DPAA_VERSION >= 11
+ param->override_storage_profile =
+ compat_param->override_storage_profile;
+ param->storage_profile = compat_param->storage_profile;
+#endif
+ param->num_of_used_extracted_ors = compat_param->num_of_used_extracted_ors;
+ memcpy(param->extracted_ors,
+ compat_param->extracted_ors,
+ IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS * sizeof(ioc_fm_pcd_kg_extracted_or_params_t));
+ param->next_engine = compat_param->next_engine;
+
+ /* kg_next_engine_params */
+ if (param->next_engine == e_IOC_FM_PCD_CC)
+ {
+ param->kg_next_engine_params.cc.tree_id = compat_pcd_id2ptr(compat_param->kg_next_engine_params.cc.tree_id);
+ param->kg_next_engine_params.cc.grp_id = compat_param->kg_next_engine_params.cc.grp_id;
+ param->kg_next_engine_params.cc.plcr_next = compat_param->kg_next_engine_params.cc.plcr_next;
+ param->kg_next_engine_params.cc.bypass_plcr_profile_generation
+ = compat_param->kg_next_engine_params.cc.bypass_plcr_profile_generation;
+ memcpy(&param->kg_next_engine_params.cc.plcr_profile,
+ &compat_param->kg_next_engine_params.cc.plcr_profile,
+ sizeof(ioc_fm_pcd_kg_plcr_profile_t));
+ }
+ else
+ memcpy(&param->kg_next_engine_params,
+ &compat_param->kg_next_engine_params,
+ sizeof(param->kg_next_engine_params));
+
+ memcpy(&param->scheme_counter,
+ &compat_param->scheme_counter,
+ sizeof(ioc_fm_pcd_kg_scheme_counter_t));
+ }
+ else
+ {
+ compat_param->modify = param->modify;
+
+ /* scm_id */
+ if (param->modify)
+ compat_param->scm_id.scheme_id = compat_pcd_ptr2id(param->scm_id.scheme_id);
+ else
+ compat_param->scm_id.relative_scheme_id = param->scm_id.relative_scheme_id;
+
+ compat_param->always_direct = param->always_direct;
+
+ /* net_env_params */
+ compat_param->net_env_params.net_env_id = compat_pcd_ptr2id(param->net_env_params.net_env_id);
+ compat_param->net_env_params.num_of_distinction_units = param->net_env_params.num_of_distinction_units;
+ memcpy(compat_param->net_env_params.unit_ids, param->net_env_params.unit_ids, IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
+
+ compat_param->use_hash = param->use_hash;
+ memcpy(&compat_param->key_extract_and_hash_params, &param->key_extract_and_hash_params, sizeof(ioc_fm_pcd_kg_key_extract_and_hash_params_t));
+ compat_param->bypass_fqid_generation = param->bypass_fqid_generation;
+ compat_param->base_fqid = param->base_fqid;
+#if DPAA_VERSION >= 11
+ compat_param->override_storage_profile =
+ param->override_storage_profile;
+ compat_param->storage_profile = param->storage_profile;
+#endif
+ compat_param->num_of_used_extracted_ors = param->num_of_used_extracted_ors;
+ memcpy(compat_param->extracted_ors, param->extracted_ors, IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS * sizeof(ioc_fm_pcd_kg_extracted_or_params_t));
+ compat_param->next_engine = param->next_engine;
+
+ /* kg_next_engine_params */
+ if (compat_param->next_engine == e_IOC_FM_PCD_CC)
+ {
+ compat_param->kg_next_engine_params.cc.tree_id = compat_pcd_ptr2id(param->kg_next_engine_params.cc.tree_id);
+ compat_param->kg_next_engine_params.cc.grp_id = param->kg_next_engine_params.cc.grp_id;
+ compat_param->kg_next_engine_params.cc.plcr_next = param->kg_next_engine_params.cc.plcr_next;
+ compat_param->kg_next_engine_params.cc.bypass_plcr_profile_generation
+ = param->kg_next_engine_params.cc.bypass_plcr_profile_generation;
+ memcpy(&compat_param->kg_next_engine_params.cc.plcr_profile,
+ &param->kg_next_engine_params.cc.plcr_profile,
+ sizeof(ioc_fm_pcd_kg_plcr_profile_t));
+ }
+ else
+ memcpy(&param->kg_next_engine_params, &compat_param->kg_next_engine_params, sizeof(compat_param->kg_next_engine_params));
+
+ memcpy(&compat_param->scheme_counter, &param->scheme_counter, sizeof(ioc_fm_pcd_kg_scheme_counter_t));
+
+ compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
+ }
+
+ _fm_cpt_dbg(compat," ...->}\n");
+}
+
+void compat_copy_fm_pcd_kg_scheme_spc(
+ ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param,
+ ioc_fm_pcd_kg_scheme_spc_t *param,
+ uint8_t compat)
+{
+ if (compat == COMPAT_US_TO_K)
+ {
+ param->id = compat_pcd_id2ptr(compat_param->id);
+ param->val = compat_param->val;
+ } else {
+ compat_param->id = compat_pcd_ptr2id(param->id);
+ compat_param->val = param->val;
+ }
+}
+
+
+void compat_copy_fm_pcd_kg_scheme_select(
+ ioc_compat_fm_pcd_kg_scheme_select_t *compat_param,
+ ioc_fm_pcd_kg_scheme_select_t *param,
+ uint8_t compat)
+{
+ if (compat == COMPAT_US_TO_K)
+ {
+ param->direct = compat_param->direct;
+ if (param->direct)
+ param->scheme_id = compat_pcd_id2ptr(compat_param->scheme_id);
+ }
+}
+
+void compat_copy_fm_pcd_kg_schemes_params(
+ ioc_compat_fm_pcd_port_schemes_params_t *compat_param,
+ ioc_fm_pcd_port_schemes_params_t *param,
+ uint8_t compat)
+{
+ int k;
+
+ if (compat == COMPAT_US_TO_K) {
+ param->num_of_schemes = compat_param->num_of_schemes;
+ for(k=0; k < compat_param->num_of_schemes; k++)
+ param->scheme_ids[k] = compat_pcd_id2ptr(compat_param->scheme_ids[k]);
+ }
+}
+
+void compat_copy_fm_port_pcd_cc(
+ ioc_compat_fm_port_pcd_cc_params_t *compat_cc_params ,
+ ioc_fm_port_pcd_cc_params_t *p_cc_params,
+ uint8_t compat)
+{
+ if (compat == COMPAT_US_TO_K){
+ p_cc_params->cc_tree_id = compat_pcd_id2ptr(compat_cc_params->cc_tree_id);
+ }
+}
+
+void compat_copy_fm_port_pcd_kg(
+ ioc_compat_fm_port_pcd_kg_params_t *compat_param,
+ ioc_fm_port_pcd_kg_params_t *param,
+ uint8_t compat)
+{
+ if (compat == COMPAT_US_TO_K){
+ uint8_t k;
+
+ param->num_of_schemes = compat_param->num_of_schemes;
+ for(k=0; k<compat_param->num_of_schemes; k++)
+ param->scheme_ids[k] = compat_pcd_id2ptr(compat_param->scheme_ids[k]);
+
+ param->direct_scheme = compat_param->direct_scheme;
+ if (param->direct_scheme)
+ param->direct_scheme_id = compat_pcd_id2ptr(compat_param->direct_scheme_id);
+ }
+}
+
+void compat_copy_fm_port_pcd(
+ ioc_compat_fm_port_pcd_params_t *compat_param,
+ ioc_fm_port_pcd_params_t *param,
+ uint8_t compat)
+{
+ if (compat == COMPAT_US_TO_K)
+ {
+ ioc_fm_port_pcd_prs_params_t *same_port_pcd_prs_params;
+ ioc_compat_fm_port_pcd_cc_params_t *compat_port_pcd_cc_params;
+ ioc_compat_fm_port_pcd_kg_params_t *compat_port_pcd_kg_params;
+ ioc_compat_fm_port_pcd_plcr_params_t *compat_port_pcd_plcr_params;
+
+ same_port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (compat_param + 1);
+ compat_port_pcd_cc_params = (ioc_compat_fm_port_pcd_cc_params_t *) (same_port_pcd_prs_params + 1);
+ compat_port_pcd_kg_params = (ioc_compat_fm_port_pcd_kg_params_t *) (compat_port_pcd_cc_params + 1);
+ compat_port_pcd_plcr_params = (ioc_compat_fm_port_pcd_plcr_params_t *) (compat_port_pcd_kg_params + 1);
+
+ _fm_cpt_dbg(compat,"\n param->p_prs_params=%p \n", param->p_prs_params);
+ _fm_cpt_dbg(compat," param->p_cc_params=%p \n", param->p_cc_params);
+ _fm_cpt_dbg(compat," param->p_kg_params=%p \n", param->p_kg_params);
+ _fm_cpt_dbg(compat," param->p_plcr_params=%p \n", param->p_plcr_params);
+ _fm_cpt_dbg(compat," param->p_ip_reassembly_manip=%p \n", param->p_ip_reassembly_manip);
+#if (DPAA_VERSION >= 11)
+ _fm_cpt_dbg(compat," param->p_capwap_reassembly_manip=%p \n", param->p_capwap_reassembly_manip);
+#endif
+ param->pcd_support = compat_param->pcd_support;
+ param->net_env_id = compat_pcd_id2ptr(compat_param->net_env_id);
+
+ if (param->p_cc_params)
+ compat_copy_fm_port_pcd_cc(compat_port_pcd_cc_params, param->p_cc_params, COMPAT_US_TO_K);
+ if (param->p_kg_params)
+ compat_copy_fm_port_pcd_kg(compat_port_pcd_kg_params, param->p_kg_params, COMPAT_US_TO_K);
+ if (param->p_plcr_params)
+ param->p_plcr_params->plcr_profile_id = compat_pcd_id2ptr(compat_port_pcd_plcr_params->plcr_profile_id);
+ param->p_ip_reassembly_manip = compat_pcd_id2ptr(compat_param->p_ip_reassembly_manip);
+#if (DPAA_VERSION >= 11)
+ param->p_capwap_reassembly_manip = compat_pcd_id2ptr(compat_param->p_capwap_reassembly_manip);
+#endif
+ }
+}
+
+void compat_copy_fm_port_pcd_modify_tree(
+ ioc_compat_fm_obj_t *compat_id,
+ ioc_fm_obj_t *id,
+ uint8_t compat)
+{
+ if (compat == COMPAT_US_TO_K)
+ id->obj = compat_pcd_id2ptr(compat_id->obj);
+}
+
+#if (DPAA_VERSION >= 11)
+void compat_copy_fm_port_vsp_alloc_params(
+ ioc_compat_fm_port_vsp_alloc_params_t *compat_param,
+ ioc_fm_port_vsp_alloc_params_t *param,
+ uint8_t compat)
+{
+ if (compat == COMPAT_US_TO_K)
+ {
+ _fm_cpt_dbg(compat," param->p_fm_tx_port=%p \n", param->p_fm_tx_port);
+
+ param->dflt_relative_id = compat_param->dflt_relative_id;
+ param->num_of_profiles = compat_param->num_of_profiles;
+ param->p_fm_tx_port = compat_pcd_id2ptr(compat_param->p_fm_tx_port);
+ }
+}
+#endif /* (DPAA_VERSION >= 11) */
+
+void compat_copy_fm_pcd_cc_tbl_get_stats(
+ ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param,
+ ioc_fm_pcd_cc_tbl_get_stats_t *param,
+ uint8_t compat)
+{
+ if (compat == COMPAT_US_TO_K)
+ {
+ param->id = compat_pcd_id2ptr(compat_param->id);
+ param->key_index = compat_param->key_index;
+ memcpy(&param->statistics, &compat_param->statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t));
+ } else {
+ compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
+ compat_param->key_index = param->key_index;
+ memcpy(&compat_param->statistics, &param->statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t));
+ }
+}
+
+
+void compat_copy_fm_pcd_net_env(
+ ioc_compat_fm_pcd_net_env_params_t *compat_param,
+ ioc_fm_pcd_net_env_params_t *param,
+ uint8_t compat)
+{
+ if (compat == COMPAT_US_TO_K)
+ {
+ param->num_of_distinction_units = compat_param->num_of_distinction_units;
+ memcpy(param->units, compat_param->units, sizeof(ioc_fm_pcd_distinction_unit_t)*IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
+ param->id = NULL; /* to avoid passing garbage to the kernel */
+ }
+ else
+ {
+ compat_param->num_of_distinction_units = param->num_of_distinction_units;
+ memcpy(compat_param->units, param->units, sizeof(ioc_fm_pcd_distinction_unit_t)*IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
+
+ compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
+ }
+}
+
+void compat_copy_fm_pcd_cc_node_modify_key(
+ ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param,
+ ioc_fm_pcd_cc_node_modify_key_params_t *param,
+ uint8_t compat)
+{
+ if (compat == COMPAT_US_TO_K)
+ {
+ param->key_indx = compat_param->key_indx;
+ param->key_size = compat_param->key_size;
+ param->p_key = (uint8_t *)compat_ptr(compat_param->p_key);
+ _fm_cpt_dbg(compat," param->p_key = %p \n", param->p_key);
+ param->p_mask = (uint8_t *)compat_ptr(compat_param->p_mask);
+ _fm_cpt_dbg(compat," param->p_mask = %p\n", param->p_mask);
+ param->id = compat_pcd_id2ptr(compat_param->id);
+ _fm_cpt_dbg(compat," param->id = %p \n", param->id);
+ }
+ else
+ {
+ compat_param->key_indx = param->key_indx;
+ compat_param->key_size = param->key_size;
+ compat_param->p_key = ptr_to_compat((void *)param->p_key);
+ compat_param->p_mask = ptr_to_compat((void *)param->p_mask);
+
+ compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
+ }
+}
+
+void compat_copy_keys(
+ ioc_compat_keys_params_t *compat_param,
+ ioc_keys_params_t *param,
+ uint8_t compat)
+{
+ int k = 0;
+
+ _fm_cpt_dbg(compat," {->...\n");
+
+ if (compat == COMPAT_US_TO_K) {
+ param->max_num_of_keys = compat_param->max_num_of_keys;
+ param->mask_support = compat_param->mask_support;
+ param->statistics_mode = compat_param->statistics_mode;
+ param->num_of_keys = compat_param->num_of_keys;
+ param->key_size = compat_param->key_size;
+#if (DPAA_VERSION >= 11)
+ memcpy(&param->frame_length_ranges,
+ &compat_param->frame_length_ranges,
+ sizeof(param->frame_length_ranges[0]) *
+ IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR);
+#endif /* (DPAA_VERSION >= 11) */
+ }
+ else {
+ compat_param->max_num_of_keys = param->max_num_of_keys;
+ compat_param->mask_support = param->mask_support;
+ compat_param->statistics_mode = param->statistics_mode;
+ compat_param->num_of_keys = param->num_of_keys;
+ compat_param->key_size = param->key_size;
+#if (DPAA_VERSION >= 11)
+ memcpy(&compat_param->frame_length_ranges,
+ &param->frame_length_ranges,
+ sizeof(compat_param->frame_length_ranges[0]) *
+ IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR);
+#endif /* (DPAA_VERSION >= 11) */
+ }
+
+ for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_KEYS; k++)
+ compat_copy_fm_pcd_cc_key(
+ &compat_param->key_params[k],
+ &param->key_params[k],
+ compat);
+
+ compat_copy_fm_pcd_cc_next_engine(
+ &compat_param->cc_next_engine_params_for_miss,
+ &param->cc_next_engine_params_for_miss,
+ compat);
+
+ _fm_cpt_dbg(compat," ...->}\n");
+}
+
+void compat_copy_fm_pcd_cc_node(
+ ioc_compat_fm_pcd_cc_node_params_t *compat_param,
+ ioc_fm_pcd_cc_node_params_t *param,
+ uint8_t compat)
+{
+ _fm_cpt_dbg(compat," {->...\n");
+
+ if (compat == COMPAT_US_TO_K)
+ memcpy(&param->extract_cc_params, &compat_param->extract_cc_params, sizeof(ioc_fm_pcd_extract_entry_t));
+
+ else
+ {
+ compat_copy_keys(&compat_param->keys_params, &param->keys_params, compat);
+
+ compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
+ _fm_cpt_dbg(compat," param->id = %p \n", param->id);
+ }
+
+ compat_copy_keys(&compat_param->keys_params, &param->keys_params, compat);
+
+ _fm_cpt_dbg(compat," ...->}\n");
+}
+
+void compat_fm_pcd_manip_set_node(
+ ioc_compat_fm_pcd_manip_params_t *compat_param,
+ ioc_fm_pcd_manip_params_t *param,
+ uint8_t compat)
+{
+ if (compat == COMPAT_US_TO_K) {
+ param->type = compat_param->type;
+ switch (param->type) {
+ case e_IOC_FM_PCD_MANIP_HDR:
+ param->u.hdr.rmv = compat_param->u.hdr.rmv;
+ memcpy(&param->u.hdr.rmv_params,
+ &compat_param->u.hdr.rmv_params,
+ sizeof(param->u.hdr.rmv_params));
+
+ param->u.hdr.insrt = compat_param->u.hdr.insrt;
+ param->u.hdr.insrt_params.type =
+ compat_param->u.hdr.insrt_params.type;
+ switch (compat_param->u.hdr.insrt_params.type)
+ {
+ case e_IOC_FM_PCD_MANIP_INSRT_GENERIC:
+ param->u.hdr.insrt_params.u.generic.offset =
+ compat_param->u.hdr.insrt_params.u.generic.offset;
+ param->u.hdr.insrt_params.u.generic.size =
+ compat_param->u.hdr.insrt_params.u.generic.size;
+ param->u.hdr.insrt_params.u.generic.replace =
+ compat_param->u.hdr.insrt_params.u.generic.replace;
+ param->u.hdr.insrt_params.u.generic.p_data =
+ compat_ptr(compat_param->u.hdr.insrt_params.u.generic.p_data);
+ break;
+ case e_IOC_FM_PCD_MANIP_INSRT_BY_HDR:
+ param->u.hdr.insrt_params.u.by_hdr.type =
+ compat_param->u.hdr.insrt_params.u.by_hdr.type;
+ param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.specific_l2 =
+ compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.specific_l2;
+ param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.update =
+ compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.update;
+ param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.size =
+ compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.size;
+ param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.p_data =
+ compat_ptr(compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.p_data);
+ break;
+ default:
+ _fm_cpt_err("Unsupported type: %d", compat_param->u.hdr.insrt_params.type);
+ }
+
+ param->u.hdr.field_update = compat_param->u.hdr.field_update;
+ memcpy(&param->u.hdr.field_update_params,
+ &compat_param->u.hdr.field_update_params,
+ sizeof(param->u.hdr.field_update_params));
+
+ param->u.hdr.custom = compat_param->u.hdr.custom;
+ memcpy(&param->u.hdr.custom_params,
+ &compat_param->u.hdr.custom_params,
+ sizeof(param->u.hdr.custom_params));
+
+ param->u.hdr.dont_parse_after_manip =
+ compat_param->u.hdr.dont_parse_after_manip;
+ break;
+ case e_IOC_FM_PCD_MANIP_REASSEM:
+ memcpy(&param->u.reassem, &compat_param->u.reassem, sizeof(param->u.reassem));
+ break;
+ case e_IOC_FM_PCD_MANIP_FRAG:
+ memcpy(&param->u.frag, &compat_param->u.frag, sizeof(param->u.frag));
+ break;
+ case e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD:
+ memcpy(&param->u.special_offload,
+ &compat_param->u.special_offload,
+ sizeof(param->u.special_offload));
+ break;
+ }
+
+ param->p_next_manip = compat_pcd_id2ptr(compat_param->p_next_manip);
+ param->id = compat_pcd_id2ptr(compat_param->id);
+ }
+ else {
+ compat_param->type = param->type;
+ memcpy(&compat_param->u, &param->u, sizeof(compat_param->u));
+
+ if (param->type == e_IOC_FM_PCD_MANIP_HDR &&
+ param->u.hdr.insrt_params.type == e_IOC_FM_PCD_MANIP_INSRT_GENERIC)
+ compat_param->u.hdr.insrt_params.u.generic.p_data =
+ ptr_to_compat(param->u.hdr.insrt_params.u.generic.p_data);
+
+ compat_param->p_next_manip = compat_pcd_ptr2id(param->id);
+ /* ... should be one that was added previously by the very call to
+ compat_add_ptr2id() below: */
+ compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
+ }
+}
+
+void compat_copy_fm_pcd_manip_get_stats(
+ ioc_compat_fm_pcd_manip_get_stats_t *compat_param,
+ ioc_fm_pcd_manip_get_stats_t *param,
+ uint8_t compat)
+{
+ _fm_cpt_dbg (compat, " {->...\n");
+
+ if (compat == COMPAT_US_TO_K)
+ {
+ param->id = compat_pcd_id2ptr(compat_param->id);
+ memcpy(&param->stats, &compat_param->stats,
+ sizeof(ioc_fm_pcd_manip_stats_t));
+ }
+ else
+ {
+ compat_param->id = compat_add_ptr2id(param->id,
+ FM_MAP_TYPE_PCD_NODE);
+ memcpy(&compat_param->stats, &param->stats,
+ sizeof(ioc_fm_pcd_manip_stats_t));
+ }
+
+ _fm_cpt_dbg (compat, " ...->}\n");
+}
+
+#if (DPAA_VERSION >= 11)
+void compat_copy_fm_pcd_frm_replic_group_params(
+ ioc_compat_fm_pcd_frm_replic_group_params_t *compat_param,
+ ioc_fm_pcd_frm_replic_group_params_t *param,
+ uint8_t compat)
+{
+ int k;
+
+ _fm_cpt_dbg (compat, " {->...\n");
+
+ if (compat == COMPAT_US_TO_K)
+ {
+ param->max_num_of_entries = compat_param->max_num_of_entries;
+ param->num_of_entries = compat_param->num_of_entries;
+ param->id = compat_pcd_id2ptr(compat_param->id);
+ }
+ else
+ {
+ compat_param->max_num_of_entries = param->max_num_of_entries;
+ compat_param->num_of_entries = param->num_of_entries;
+ compat_param->id = compat_add_ptr2id(param->id,
+ FM_MAP_TYPE_PCD_NODE);
+ }
+
+ for (k=0; k < IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES; k++)
+ compat_copy_fm_pcd_cc_next_engine(
+ &compat_param->next_engine_params[k],
+ &param->next_engine_params[k],
+ compat);
+
+ _fm_cpt_dbg (compat, " ...->}\n");
+}
+
+void compat_copy_fm_pcd_frm_replic_member(
+ ioc_compat_fm_pcd_frm_replic_member_t *compat_param,
+ ioc_fm_pcd_frm_replic_member_t *param,
+ uint8_t compat)
+{
+ _fm_cpt_dbg (compat, " {->...\n");
+
+ if (compat == COMPAT_US_TO_K)
+ {
+ param->h_replic_group = compat_pcd_id2ptr(compat_param->h_replic_group);
+ param->member_index = compat_param->member_index;
+ }
+
+ _fm_cpt_dbg (compat, " ...->}\n");
+}
+
+void compat_copy_fm_pcd_frm_replic_member_params(
+ ioc_compat_fm_pcd_frm_replic_member_params_t *compat_param,
+ ioc_fm_pcd_frm_replic_member_params_t *param,
+ uint8_t compat)
+{
+ _fm_cpt_dbg (compat, " {->...\n");
+
+ compat_copy_fm_pcd_frm_replic_member(&compat_param->member,
+ &param->member, compat);
+
+ compat_copy_fm_pcd_cc_next_engine(&compat_param->next_engine_params,
+ &param->next_engine_params, compat);
+
+ _fm_cpt_dbg (compat, " ...->}\n");
+}
+
+void compat_copy_fm_vsp_params(
+ ioc_compat_fm_vsp_params_t *compat_param,
+ ioc_fm_vsp_params_t *param,
+ uint8_t compat)
+{
+ _fm_cpt_dbg (compat, " {->...\n");
+
+ if (compat == COMPAT_US_TO_K)
+ {
+ memcpy(&param->ext_buf_pools, &compat_param->ext_buf_pools, sizeof(ioc_fm_ext_pools));
+ param->liodn_offset = compat_param->liodn_offset;
+ param->port_params.port_id = compat_param->port_params.port_id;
+ param->port_params.port_type = compat_param->port_params.port_type;
+ param->relative_profile_id = compat_param->relative_profile_id;
+ }
+ else
+ {
+ memcpy(&compat_param->ext_buf_pools, &param->ext_buf_pools, sizeof(ioc_fm_ext_pools));
+ compat_param->liodn_offset = param->liodn_offset;
+ compat_param->port_params.port_id = param->port_params.port_id;
+ compat_param->port_params.port_type = param->port_params.port_type;
+ compat_param->relative_profile_id = param->relative_profile_id;
+ compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
+ }
+
+ _fm_cpt_dbg (compat, " ...->}\n");
+}
+
+void compat_copy_fm_buf_pool_depletion_params(
+ ioc_compat_fm_buf_pool_depletion_params_t *compat_param,
+ ioc_fm_buf_pool_depletion_params_t *param,
+ uint8_t compat)
+{
+ _fm_cpt_dbg (compat, " {->...\n");
+
+ if (compat == COMPAT_US_TO_K)
+ {
+ param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
+ memcpy(&param->fm_buf_pool_depletion,
+ &compat_param->fm_buf_pool_depletion,
+ sizeof(ioc_fm_buf_pool_depletion_t));
+ }
+
+ _fm_cpt_dbg (compat, " ...->}\n");
+}
+
+void compat_copy_fm_buffer_prefix_content_params(
+ ioc_compat_fm_buffer_prefix_content_params_t *compat_param,
+ ioc_fm_buffer_prefix_content_params_t *param,
+ uint8_t compat)
+{
+ _fm_cpt_dbg (compat, " {->...\n");
+
+ if (compat == COMPAT_US_TO_K)
+ {
+ param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
+ memcpy(&param->fm_buffer_prefix_content,
+ &compat_param->fm_buffer_prefix_content,
+ sizeof(ioc_fm_buffer_prefix_content_t));
+ }
+
+ _fm_cpt_dbg (compat, " ...->}\n");
+}
+
+void compat_copy_fm_vsp_config_no_sg_params(
+ ioc_compat_fm_vsp_config_no_sg_params_t *compat_param,
+ ioc_fm_vsp_config_no_sg_params_t *param,
+ uint8_t compat)
+{
+ _fm_cpt_dbg (compat, " {->...\n");
+
+ if (compat == COMPAT_US_TO_K)
+ {
+ param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
+ param->no_sg = compat_param->no_sg;
+ }
+
+ _fm_cpt_dbg (compat, " ...->}\n");
+}
+
+void compat_copy_fm_vsp_prs_result_params(
+ ioc_compat_fm_vsp_prs_result_params_t *compat_param,
+ ioc_fm_vsp_prs_result_params_t *param,
+ uint8_t compat)
+{
+ _fm_cpt_dbg (compat, " {->...\n");
+
+ if (compat == COMPAT_US_TO_K)
+ {
+ param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
+ /* p_data is an user-space pointer that needs to remain unmodified */
+ param->p_data = (void *)(unsigned long long)compat_param->p_data;
+ }
+ else
+ {
+ compat_param->p_fm_vsp = compat_pcd_ptr2id(param->p_fm_vsp);
+ /* p_data is an user-space pointer that needs to remain unmodified */
+ compat_param->p_data = (compat_uptr_t)((unsigned long long)param->p_data & 0xFFFFFFFF);
+ }
+
+ _fm_cpt_dbg (compat, " ...->}\n");
+}
+#endif /* (DPAA_VERSION >= 11) */
diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h
new file mode 100644
index 000000000000..fe60a55c8f78
--- /dev/null
+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h
@@ -0,0 +1,765 @@
+/*
+ * 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_ioctls_fm_compat.h
+
+ @Description FM PCD compat structures definition.
+
+*/
+
+#ifndef __FM_COMPAT_IOCTLS_H
+#define __FM_COMPAT_IOCTLS_H
+
+#include <linux/compat.h>
+
+#define COMPAT_K_TO_US 0 /* copy from Kernel to User */
+#define COMPAT_US_TO_K 1 /* copy from User to Kernel */
+#define COMPAT_GENERIC 2
+
+#define COMPAT_COPY_K2US(dest, src, type) compat_copy_##type(src, dest, 0)
+#define COMPAT_COPY_US2K(dest, src, type) compat_copy_##type(dest, src, 1)
+
+/* mapping kernel pointers w/ UserSpace id's { */
+/* Because compat_ptr(ptr_to_compat(X)) != X, this way we cannot exchange pointers
+ back and forth (US - KS). compat_ptr is a cast and pointers are broken. */
+#define COMPAT_PTR2ID_ARRAY_MAX (512+1) /* first location is not used */
+#define COMPAT_PTR2ID_WATERMARK 0xface0000
+#define COMPAT_PTR2ID_WM_MASK 0xffff0000
+
+/* define it for debug trace */
+/*#define FM_COMPAT_DBG*/
+
+#define _fm_cpt_prk(stage, format, arg...) \
+ printk(stage "fm_cpt (cpu:%u): " format, raw_smp_processor_id(), ##arg)
+
+#define _fm_cpt_inf(format, arg...) _fm_cpt_prk(KERN_INFO, format, ##arg)
+#define _fm_cpt_wrn(format, arg...) _fm_cpt_prk(KERN_WARNING, format, ##arg)
+#define _fm_cpt_err(format, arg...) _fm_cpt_prk(KERN_ERR, format, ##arg)
+
+/* used for compat IOCTL debugging */
+#if defined(FM_COMPAT_DBG)
+ #define _fm_cpt_dbg(from, format, arg...) \
+ do{ \
+ if (from == COMPAT_US_TO_K) \
+ printk("fm_cpt to KS [%s:%u](cpu:%u) - " format, \
+ __func__, __LINE__, raw_smp_processor_id(), ##arg); \
+ else if (from == COMPAT_K_TO_US) \
+ printk("fm_cpt to US [%s:%u](cpu:%u) - " format, \
+ __func__, __LINE__, raw_smp_processor_id(), ##arg); \
+ else \
+ printk("fm_cpt [%s:%u](cpu:%u) - " format, \
+ __func__, __LINE__, raw_smp_processor_id(), ##arg); \
+ }while(0)
+#else
+# define _fm_cpt_dbg(arg...)
+#endif
+
+/*TODO: per FMan module:
+ *
+ * Parser: FM_MAP_TYPE_PARSER_NODE,
+ * Kg: FM_MAP_TYPE_KG_NODE,
+ * Policer: FM_MAP_TYPE_POLICER_NODE
+ * Manip: FM_MAP_TYPE_MANIP_NODE
+ **/
+enum fm_map_node_type {
+ FM_MAP_TYPE_UNSPEC = 0,
+ FM_MAP_TYPE_PCD_NODE,
+
+ /* add types here, update the policy */
+
+ __FM_MAP_TYPE_AFTER_LAST,
+ FM_MAP_TYPE_MAX = __FM_MAP_TYPE_AFTER_LAST - 1
+};
+
+void compat_del_ptr2id(void *p, enum fm_map_node_type);
+compat_uptr_t compat_add_ptr2id(void *p, enum fm_map_node_type);
+compat_uptr_t compat_get_ptr2id(void *p, enum fm_map_node_type);
+void *compat_get_id2ptr(compat_uptr_t comp, enum fm_map_node_type);
+
+static inline compat_uptr_t compat_pcd_ptr2id(void *ptr) {
+ return (ptr)? compat_get_ptr2id(ptr, FM_MAP_TYPE_PCD_NODE)
+ : (compat_uptr_t) 0;
+}
+
+static inline void *compat_pcd_id2ptr(compat_uptr_t id) {
+ return (id) ? compat_get_id2ptr(id, FM_MAP_TYPE_PCD_NODE)
+ : NULL;
+}
+
+/* other similar inlines may be added as new nodes are added
+ to enum fm_map_node_type above... */
+/* } mapping kernel pointers w/ UserSpace id's */
+
+/* pcd compat structures { */
+typedef struct ioc_compat_fm_pcd_cc_node_remove_key_params_t {
+ compat_uptr_t id;
+ uint16_t key_indx;
+} ioc_compat_fm_pcd_cc_node_remove_key_params_t;
+
+typedef union ioc_compat_fm_pcd_plcr_next_engine_params_u {
+ ioc_fm_pcd_done_action action;
+ compat_uptr_t p_profile;
+ compat_uptr_t p_direct_scheme;
+} ioc_compat_fm_pcd_plcr_next_engine_params_u;
+
+typedef struct ioc_compat_fm_pcd_plcr_profile_params_t {
+ bool modify;
+ union {
+ struct {
+ ioc_fm_pcd_profile_type_selection profile_type;
+ compat_uptr_t p_fm_port;
+ uint16_t relative_profile_id;
+ } new_params;
+ compat_uptr_t p_profile;
+ } profile_select;
+ ioc_fm_pcd_plcr_algorithm_selection alg_selection;
+ ioc_fm_pcd_plcr_color_mode color_mode;
+
+ union {
+ ioc_fm_pcd_plcr_color dflt_color;
+ ioc_fm_pcd_plcr_color override;
+ } color;
+
+ ioc_fm_pcd_plcr_non_passthrough_alg_param_t non_passthrough_alg_param;
+
+ ioc_fm_pcd_engine next_engine_on_green;
+ ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_green;
+
+ ioc_fm_pcd_engine next_engine_on_yellow;
+ ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_yellow;
+
+ ioc_fm_pcd_engine next_engine_on_red;
+ ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_red;
+
+ bool trap_profile_on_flow_A;
+ bool trap_profile_on_flow_B;
+ bool trap_profile_on_flow_C;
+ compat_uptr_t id;
+} ioc_compat_fm_pcd_plcr_profile_params_t;
+
+typedef struct ioc_compat_fm_obj_t {
+ compat_uptr_t obj;
+} ioc_compat_fm_obj_t;
+
+typedef struct ioc_compat_fm_pcd_kg_scheme_select_t {
+ bool direct;
+ compat_uptr_t scheme_id;
+} ioc_compat_fm_pcd_kg_scheme_select_t;
+
+typedef struct ioc_compat_fm_pcd_port_schemes_params_t {
+ uint8_t num_of_schemes;
+ compat_uptr_t scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
+} ioc_compat_fm_pcd_port_schemes_params_t;
+
+#if (DPAA_VERSION >= 11)
+typedef struct ioc_compat_fm_port_vsp_alloc_params_t {
+ uint8_t num_of_profiles; /**< Number of Virtual Storage Profiles */
+ uint8_t dflt_relative_id; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port
+ The same default Virtual-Storage-Profile-id will be for coupled Tx port
+ if relevant function called for Rx port */
+ compat_uptr_t p_fm_tx_port; /**< Handle to coupled Tx Port; not relevant for OP port. */
+}ioc_compat_fm_port_vsp_alloc_params_t;
+#endif /* (DPAA_VERSION >= 11) */
+
+typedef struct ioc_compat_fm_pcd_net_env_params_t {
+ uint8_t num_of_distinction_units;
+ ioc_fm_pcd_distinction_unit_t units[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /* same structure*/
+ compat_uptr_t id;
+} ioc_compat_fm_pcd_net_env_params_t;
+
+typedef struct ioc_compat_fm_pcd_prs_sw_params_t {
+ bool override;
+ uint32_t size;
+ uint16_t base;
+ compat_uptr_t p_code;
+ uint32_t sw_prs_data_params[IOC_FM_PCD_PRS_NUM_OF_HDRS];
+ uint8_t num_of_labels;
+ ioc_fm_pcd_prs_label_params_t labels_table[IOC_FM_PCD_PRS_NUM_OF_LABELS];
+} ioc_compat_fm_pcd_prs_sw_params_t;
+
+typedef struct ioc_compat_fm_pcd_cc_next_kg_params_t {
+ bool override_fqid;
+ uint32_t new_fqid;
+#if DPAA_VERSION >= 11
+ uint8_t new_relative_storage_profile_id;
+#endif
+ compat_uptr_t p_direct_scheme;
+} ioc_compat_fm_pcd_cc_next_kg_params_t;
+
+typedef struct ioc_compat_fm_pcd_cc_next_cc_params_t {
+ compat_uptr_t cc_node_id;
+} ioc_compat_fm_pcd_cc_next_cc_params_t;
+
+#if DPAA_VERSION >= 11
+typedef struct ioc_compat_fm_pcd_cc_next_fr_params_t {
+ compat_uptr_t frm_replic_id;
+} ioc_compat_fm_pcd_cc_next_fr_params_t;
+#endif /* DPAA_VERSION >= 11 */
+
+typedef struct ioc_compat_fm_pcd_cc_next_engine_params_t {
+ ioc_fm_pcd_engine next_engine;
+ union {
+ ioc_compat_fm_pcd_cc_next_cc_params_t cc_params; /**< compat structure*/
+ ioc_fm_pcd_cc_next_plcr_params_t plcr_params; /**< same structure*/
+ ioc_fm_pcd_cc_next_enqueue_params_t enqueue_params; /**< same structure*/
+ ioc_compat_fm_pcd_cc_next_kg_params_t kg_params; /**< compat structure*/
+#if DPAA_VERSION >= 11
+ ioc_compat_fm_pcd_cc_next_fr_params_t fr_params; /**< compat structure*/
+#endif /* DPAA_VERSION >= 11 */
+ } params;
+ compat_uptr_t manip_id;
+ bool statistics_en;
+} ioc_compat_fm_pcd_cc_next_engine_params_t;
+
+typedef struct ioc_compat_fm_pcd_cc_grp_params_t {
+ uint8_t num_of_distinction_units;
+ uint8_t unit_ids [IOC_FM_PCD_MAX_NUM_OF_CC_UNITS];
+ ioc_compat_fm_pcd_cc_next_engine_params_t next_engine_per_entries_in_grp[IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP];
+} ioc_compat_fm_pcd_cc_grp_params_t;
+
+typedef struct ioc_compat_fm_pcd_cc_tree_params_t {
+ compat_uptr_t net_env_id;
+ uint8_t num_of_groups;
+ ioc_compat_fm_pcd_cc_grp_params_t fm_pcd_cc_group_params [IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS];
+ compat_uptr_t id;
+} ioc_compat_fm_pcd_cc_tree_params_t;
+
+typedef struct ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t {
+ compat_uptr_t id;
+ uint8_t grp_indx;
+ uint8_t indx;
+ ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
+} ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t;
+
+typedef struct ioc_compat_fm_pcd_cc_key_params_t {
+ compat_uptr_t p_key;
+ compat_uptr_t p_mask;
+ ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params; /**< compat structure*/
+} ioc_compat_fm_pcd_cc_key_params_t;
+
+typedef struct ioc_compat_keys_params_t {
+ uint16_t max_num_of_keys;
+ bool mask_support;
+ ioc_fm_pcd_cc_stats_mode statistics_mode;
+#if (DPAA_VERSION >= 11)
+ uint16_t frame_length_ranges[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
+#endif /* (DPAA_VERSION >= 11) */
+ uint16_t num_of_keys;
+ uint8_t key_size;
+ ioc_compat_fm_pcd_cc_key_params_t key_params[IOC_FM_PCD_MAX_NUM_OF_KEYS]; /**< compat structure*/
+ ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss; /**< compat structure*/
+} ioc_compat_keys_params_t;
+
+typedef struct ioc_compat_fm_pcd_cc_node_params_t {
+ ioc_fm_pcd_extract_entry_t extract_cc_params; /**< same structure*/
+ ioc_compat_keys_params_t keys_params; /**< compat structure*/
+ compat_uptr_t id;
+} ioc_compat_fm_pcd_cc_node_params_t;
+
+/**************************************************************************//**
+ @Description Parameters for defining a hash table
+*//***************************************************************************/
+typedef struct ioc_compat_fm_pcd_hash_table_params_t {
+ uint16_t max_num_of_keys;
+ ioc_fm_pcd_cc_stats_mode statistics_mode;
+ uint8_t kg_hash_shift;
+ uint16_t hash_res_mask;
+ uint8_t hash_shift;
+ uint8_t match_key_size;
+ ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss;
+ compat_uptr_t id;
+} ioc_compat_fm_pcd_hash_table_params_t;
+
+typedef struct ioc_compat_fm_pcd_hash_table_add_key_params_t {
+ compat_uptr_t p_hash_tbl;
+ uint8_t key_size;
+ ioc_compat_fm_pcd_cc_key_params_t key_params;
+} ioc_compat_fm_pcd_hash_table_add_key_params_t;
+
+typedef struct ioc_compat_fm_pcd_cc_node_modify_key_params_t {
+ compat_uptr_t id;
+ uint16_t key_indx;
+ uint8_t key_size;
+ compat_uptr_t p_key;
+ compat_uptr_t p_mask;
+} ioc_compat_fm_pcd_cc_node_modify_key_params_t;
+
+typedef struct ioc_compat_fm_pcd_hash_table_remove_key_params_t {
+ compat_uptr_t p_hash_tbl;
+ uint8_t key_size;
+ compat_uptr_t p_key;
+} ioc_compat_fm_pcd_hash_table_remove_key_params_t;
+
+typedef struct ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t {
+ compat_uptr_t id;
+ uint16_t key_indx;
+ uint8_t key_size;
+ ioc_compat_fm_pcd_cc_key_params_t key_params;
+} ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t;
+
+typedef struct ioc_compat_fm_port_pcd_plcr_params_t {
+ compat_uptr_t plcr_profile_id;
+} ioc_compat_fm_port_pcd_plcr_params_t;
+
+typedef struct ioc_compat_fm_port_pcd_cc_params_t {
+ compat_uptr_t cc_tree_id;
+} ioc_compat_fm_port_pcd_cc_params_t;
+
+typedef struct ioc_compat_fm_port_pcd_kg_params_t {
+ uint8_t num_of_schemes;
+ compat_uptr_t scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
+ bool direct_scheme;
+ compat_uptr_t direct_scheme_id;
+} ioc_compat_fm_port_pcd_kg_params_t;
+
+typedef struct ioc_compat_fm_port_pcd_params_t {
+ ioc_fm_port_pcd_support pcd_support;
+ compat_uptr_t net_env_id;
+ compat_uptr_t p_prs_params;
+ compat_uptr_t p_cc_params;
+ compat_uptr_t p_kg_params;
+ compat_uptr_t p_plcr_params;
+ compat_uptr_t p_ip_reassembly_manip;
+#if DPAA_VERSION >= 11
+ compat_uptr_t p_capwap_reassembly_manip;
+#endif
+} ioc_compat_fm_port_pcd_params_t;
+
+typedef struct ioc_compat_fm_pcd_kg_cc_t {
+ compat_uptr_t tree_id;
+ uint8_t grp_id;
+ bool plcr_next;
+ bool bypass_plcr_profile_generation;
+ ioc_fm_pcd_kg_plcr_profile_t plcr_profile;
+} ioc_compat_fm_pcd_kg_cc_t;
+
+typedef struct ioc_compat_fm_pcd_kg_scheme_params_t {
+ bool modify;
+ union {
+ uint8_t relative_scheme_id;
+ compat_uptr_t scheme_id;
+ } scm_id;
+ bool always_direct;
+ struct {
+ compat_uptr_t net_env_id;
+ uint8_t num_of_distinction_units;
+ uint8_t unit_ids[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
+ } net_env_params;
+ bool use_hash;
+ ioc_fm_pcd_kg_key_extract_and_hash_params_t key_extract_and_hash_params;
+ bool bypass_fqid_generation;
+ uint32_t base_fqid;
+ uint8_t num_of_used_extracted_ors;
+ ioc_fm_pcd_kg_extracted_or_params_t extracted_ors[IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS];
+#if DPAA_VERSION >= 11
+ bool override_storage_profile;
+ ioc_fm_pcd_kg_storage_profile_t storage_profile;
+#endif /* DPAA_VERSION >= 11 */
+ ioc_fm_pcd_engine next_engine;
+ union{
+ ioc_fm_pcd_done_action done_action;
+ ioc_fm_pcd_kg_plcr_profile_t plcr_profile;
+ ioc_compat_fm_pcd_kg_cc_t cc;
+ } kg_next_engine_params;
+ ioc_fm_pcd_kg_scheme_counter_t scheme_counter;
+ compat_uptr_t id;
+} ioc_compat_fm_pcd_kg_scheme_params_t;
+
+typedef struct ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t {
+ compat_uptr_t id;
+ uint16_t key_indx;
+ uint8_t key_size;
+ ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
+} ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t;
+
+typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t {
+ uint8_t offset;
+ uint8_t size;
+ bool replace;
+ compat_uptr_t p_data;
+} ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t;
+
+typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t {
+ ioc_fm_pcd_manip_hdr_insrt_specific_l2 specific_l2;
+ bool update;
+ uint8_t size;
+ compat_uptr_t p_data;
+} ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t;
+
+typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_t {
+ uint8_t size; /**< size of inserted section */
+ compat_uptr_t p_data; /**< data to be inserted */
+} ioc_compat_fm_pcd_manip_hdr_insrt_t;
+
+#if (DPAA_VERSION >= 11)
+typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t {
+ bool calc_l4_checksum; /**< Calculate L4 checksum. */
+ ioc_fm_pcd_manip_hdr_qos_mapping_mode mapping_mode; /**< TODO */
+ uint8_t last_pid_offset; /**< the offset of the last Protocol within
+ the inserted header */
+ uint16_t id; /**< 16 bit New IP ID */
+ bool dont_frag_overwrite;
+ /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte.
+ * This byte is configured to be overwritten when RPD is set. */
+ uint8_t last_dst_offset;
+ /**< IPv6 only. if routing extension exist, user should set the offset of the destination address
+ * in order to calculate UDP checksum pseudo header;
+ * Otherwise set it to '0'. */
+ ioc_compat_fm_pcd_manip_hdr_insrt_t insrt; /**< size and data to be inserted. */
+} ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t;
+#endif /* (DPAA_VERSION >= 11) */
+
+typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t {
+ ioc_fm_pcd_manip_hdr_insrt_by_hdr_type type;
+ union {
+ ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t specific_l2_params;
+#if (DPAA_VERSION >= 11)
+ ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t ip_params;
+ ioc_compat_fm_pcd_manip_hdr_insrt_t insrt;
+#endif /* (DPAA_VERSION >= 11) */
+ } u;
+} ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t;
+
+typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_params_t {
+ ioc_fm_pcd_manip_hdr_insrt_type type;
+ union {
+ ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t by_hdr;
+ ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t generic;
+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
+#error "FM_CAPWAP_SUPPORT feature not supported!"
+ ioc_fm_pcd_manip_hdr_insrt_by_template_params_t by_template;
+#endif /* FM_CAPWAP_SUPPORT */
+ } u;
+} ioc_compat_fm_pcd_manip_hdr_insrt_params_t;
+
+typedef struct ioc_compat_fm_pcd_manip_hdr_params_t {
+ bool rmv;
+ ioc_fm_pcd_manip_hdr_rmv_params_t rmv_params;
+ bool insrt;
+ ioc_compat_fm_pcd_manip_hdr_insrt_params_t insrt_params;
+ bool field_update;
+ ioc_fm_pcd_manip_hdr_field_update_params_t field_update_params;
+ bool custom;
+ ioc_fm_pcd_manip_hdr_custom_params_t custom_params;
+ bool dont_parse_after_manip;
+} ioc_compat_fm_pcd_manip_hdr_params_t;
+
+typedef struct ioc_compat_fm_pcd_manip_special_offload_ipsec_params_t {
+ bool decryption;
+ bool ecn_copy;
+ bool dscp_copy;
+ bool variable_ip_hdr_len;
+ bool variable_ip_version;
+ uint8_t outer_ip_hdr_len;
+ uint16_t arw_size;
+ compat_uptr_t arw_addr;
+} ioc_compat_fm_pcd_manip_special_offload_ipsec_params_t;
+
+typedef struct ioc_compat_fm_pcd_manip_special_offload_params_t {
+ ioc_fm_pcd_manip_special_offload_type type;
+ union {
+ ioc_compat_fm_pcd_manip_special_offload_ipsec_params_t ipsec;
+#if (DPAA_VERSION >= 11)
+ ioc_fm_pcd_manip_special_offload_capwap_params_t capwap;
+#endif /* (DPAA_VERSION >= 11) */
+ } u;
+} ioc_compat_fm_pcd_manip_special_offload_params_t;
+
+typedef struct ioc_compat_fm_pcd_manip_params_t {
+ ioc_fm_pcd_manip_type type;
+ union {
+ ioc_compat_fm_pcd_manip_hdr_params_t hdr;
+ ioc_fm_pcd_manip_reassem_params_t reassem;
+ ioc_fm_pcd_manip_frag_params_t frag;
+ ioc_compat_fm_pcd_manip_special_offload_params_t special_offload;
+ } u;
+ compat_uptr_t p_next_manip;
+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
+#error "FM_CAPWAP_SUPPORT feature not supported!"
+ bool frag_or_reasm;
+ ioc_fm_pcd_manip_frag_or_reasm_params_t frag_or_reasm_params;
+#endif /* FM_CAPWAP_SUPPORT */
+ compat_uptr_t id;
+} ioc_compat_fm_pcd_manip_params_t;
+
+typedef struct ioc_compat_fm_pcd_manip_get_stats_t {
+ compat_uptr_t id;
+ ioc_fm_pcd_manip_stats_t stats;
+} ioc_compat_fm_pcd_manip_get_stats_t;
+
+#if (DPAA_VERSION >= 11)
+typedef struct ioc_compat_fm_pcd_frm_replic_group_params_t {
+ uint8_t max_num_of_entries;
+ uint8_t num_of_entries;
+ ioc_compat_fm_pcd_cc_next_engine_params_t
+ next_engine_params[IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES];
+ compat_uptr_t id;
+} ioc_compat_fm_pcd_frm_replic_group_params_t;
+
+typedef struct ioc_compat_fm_pcd_frm_replic_member_t {
+ compat_uptr_t h_replic_group;
+ uint16_t member_index;
+} ioc_compat_fm_pcd_frm_replic_member_t;
+
+typedef struct ioc_compat_fm_pcd_frm_replic_member_params_t {
+ ioc_compat_fm_pcd_frm_replic_member_t member;
+ ioc_compat_fm_pcd_cc_next_engine_params_t next_engine_params;
+} ioc_compat_fm_pcd_frm_replic_member_params_t;
+
+typedef struct ioc_compat_fm_vsp_params_t {
+ compat_uptr_t p_fm; /**< A handle to the FM object this VSP related to */
+ ioc_fm_ext_pools ext_buf_pools; /**< Which external buffer pools are used
+ (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes.
+ parameter associated with Rx / OP port */
+ uint16_t liodn_offset; /**< VSP's LIODN offset */
+ struct {
+ ioc_fm_port_type port_type; /**< Port type */
+ uint8_t port_id; /**< Port Id - relative to type */
+ } port_params;
+ uint8_t relative_profile_id; /**< VSP Id - relative to VSP's range
+ defined in relevant FM object */
+ compat_uptr_t id; /**< return value */
+} ioc_compat_fm_vsp_params_t;
+
+typedef struct ioc_compat_fm_buf_pool_depletion_params_t {
+ compat_uptr_t p_fm_vsp;
+ ioc_fm_buf_pool_depletion_t fm_buf_pool_depletion;
+} ioc_compat_fm_buf_pool_depletion_params_t;
+
+typedef struct ioc_compat_fm_buffer_prefix_content_params_t {
+ compat_uptr_t p_fm_vsp;
+ ioc_fm_buffer_prefix_content_t fm_buffer_prefix_content;
+} ioc_compat_fm_buffer_prefix_content_params_t;
+
+typedef struct ioc_compat_fm_vsp_config_no_sg_params_t {
+ compat_uptr_t p_fm_vsp;
+ bool no_sg;
+} ioc_compat_fm_vsp_config_no_sg_params_t;
+
+typedef struct ioc_compat_fm_vsp_prs_result_params_t {
+ compat_uptr_t p_fm_vsp;
+ compat_uptr_t p_data;
+} ioc_compat_fm_vsp_prs_result_params_t;
+
+#endif /* (DPAA_VERSION >= 11) */
+typedef struct ioc_compat_fm_pcd_kg_scheme_spc_t {
+ uint32_t val;
+ compat_uptr_t id;
+} ioc_compat_fm_pcd_kg_scheme_spc_t;
+
+typedef struct ioc_compat_fm_ctrl_mon_counters_params_t {
+ uint8_t fm_ctrl_index;
+ compat_uptr_t p_mon;
+} ioc_compat_fm_ctrl_mon_counters_params_t;
+
+typedef struct ioc_compat_fm_pcd_cc_tbl_get_stats_t {
+ compat_uptr_t id;
+ uint16_t key_index;
+ ioc_fm_pcd_cc_key_statistics_t statistics;
+} ioc_compat_fm_pcd_cc_tbl_get_stats_t;
+
+
+/* } pcd compat structures */
+
+void compat_obj_delete(
+ ioc_compat_fm_obj_t *compat_id,
+ ioc_fm_obj_t *id);
+
+/* pcd compat functions { */
+void compat_copy_fm_pcd_plcr_profile(
+ ioc_compat_fm_pcd_plcr_profile_params_t *compat_param,
+ ioc_fm_pcd_plcr_profile_params_t *param,
+ uint8_t compat);
+
+void compat_copy_fm_pcd_cc_key(
+ ioc_compat_fm_pcd_cc_key_params_t *compat_param,
+ ioc_fm_pcd_cc_key_params_t *param,
+ uint8_t compat);
+
+void compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(
+ ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param,
+ ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param,
+ uint8_t compat);
+
+void compat_copy_fm_pcd_cc_node_modify_next_engine(
+ ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param,
+ ioc_fm_pcd_cc_node_modify_next_engine_params_t *param,
+ uint8_t compat);
+
+void compat_fm_pcd_cc_tree_modify_next_engine(
+ ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param,
+ ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param,
+ uint8_t compat);
+
+void compat_copy_fm_pcd_hash_table(
+ ioc_compat_fm_pcd_hash_table_params_t *compat_param,
+ ioc_fm_pcd_hash_table_params_t *param,
+ uint8_t compat);
+
+void compat_copy_fm_pcd_cc_grp(
+ ioc_compat_fm_pcd_cc_grp_params_t *compat_param,
+ ioc_fm_pcd_cc_grp_params_t *param,
+ uint8_t compat);
+
+void compat_copy_fm_pcd_cc_tree(
+ ioc_compat_fm_pcd_cc_tree_params_t *compat_param,
+ ioc_fm_pcd_cc_tree_params_t *param,
+ uint8_t compat);
+
+void compat_copy_fm_pcd_cc_tbl_get_stats(
+ ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param,
+ ioc_fm_pcd_cc_tbl_get_stats_t *param,
+ uint8_t compat);
+
+void compat_fm_pcd_prs_sw(
+ ioc_compat_fm_pcd_prs_sw_params_t *compat_param,
+ ioc_fm_pcd_prs_sw_params_t *param,
+ uint8_t compat);
+
+void compat_copy_fm_pcd_kg_scheme(
+ ioc_compat_fm_pcd_kg_scheme_params_t *compat_param,
+ ioc_fm_pcd_kg_scheme_params_t *param,
+ uint8_t compat);
+
+void compat_copy_fm_pcd_kg_scheme_select(
+ ioc_compat_fm_pcd_kg_scheme_select_t *compat_param,
+ ioc_fm_pcd_kg_scheme_select_t *param,
+ uint8_t compat);
+
+void compat_copy_fm_pcd_kg_schemes_params(
+ ioc_compat_fm_pcd_port_schemes_params_t *compat_param,
+ ioc_fm_pcd_port_schemes_params_t *param,
+ uint8_t compat);
+
+void compat_copy_fm_port_pcd_kg(
+ ioc_compat_fm_port_pcd_kg_params_t *compat_param,
+ ioc_fm_port_pcd_kg_params_t *param,
+ uint8_t compat);
+
+void compat_copy_fm_port_pcd(
+ ioc_compat_fm_port_pcd_params_t *compat_param,
+ ioc_fm_port_pcd_params_t *param,
+ uint8_t compat);
+
+#if (DPAA_VERSION >= 11)
+void compat_copy_fm_port_vsp_alloc_params(
+ ioc_compat_fm_port_vsp_alloc_params_t *compat_param,
+ ioc_fm_port_vsp_alloc_params_t *param,
+ uint8_t compat);
+#endif /* (DPAA_VERSION >= 11) */
+
+void compat_copy_fm_pcd_net_env(
+ ioc_compat_fm_pcd_net_env_params_t *compat_param,
+ ioc_fm_pcd_net_env_params_t *param,
+ uint8_t compat);
+
+void compat_copy_fm_pcd_cc_node_modify_key(
+ ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param,
+ ioc_fm_pcd_cc_node_modify_key_params_t *param,
+ uint8_t compat);
+
+void compat_copy_keys(
+ ioc_compat_keys_params_t *compat_param,
+ ioc_keys_params_t *param,
+ uint8_t compat);
+
+void compat_copy_fm_pcd_cc_node(
+ ioc_compat_fm_pcd_cc_node_params_t *compat_param,
+ ioc_fm_pcd_cc_node_params_t *param,
+ uint8_t compat);
+
+void compat_fm_pcd_manip_set_node(
+ ioc_compat_fm_pcd_manip_params_t *compat_param,
+ ioc_fm_pcd_manip_params_t *param,
+ uint8_t compat);
+
+void compat_copy_fm_pcd_manip_get_stats(
+ ioc_compat_fm_pcd_manip_get_stats_t *compat_param,
+ ioc_fm_pcd_manip_get_stats_t *param,
+ uint8_t compat);
+
+void compat_copy_fm_port_pcd_modify_tree(
+ ioc_compat_fm_obj_t *compat_id,
+ ioc_fm_obj_t *id,
+ uint8_t compat);
+
+#if (DPAA_VERSION >= 11)
+void compat_copy_fm_pcd_frm_replic_group_params(
+ ioc_compat_fm_pcd_frm_replic_group_params_t *compat_param,
+ ioc_fm_pcd_frm_replic_group_params_t *param,
+ uint8_t compat);
+
+void compat_copy_fm_pcd_frm_replic_member(
+ ioc_compat_fm_pcd_frm_replic_member_t *compat_param,
+ ioc_fm_pcd_frm_replic_member_t *param,
+ uint8_t compat);
+
+void compat_copy_fm_pcd_frm_replic_member_params(
+ ioc_compat_fm_pcd_frm_replic_member_params_t *compat_param,
+ ioc_fm_pcd_frm_replic_member_params_t *param,
+ uint8_t compat);
+
+void compat_copy_fm_vsp_params(
+ ioc_compat_fm_vsp_params_t *compat_param,
+ ioc_fm_vsp_params_t *param,
+ uint8_t compat);
+
+void compat_copy_fm_buf_pool_depletion_params(
+ ioc_compat_fm_buf_pool_depletion_params_t *compat_param,
+ ioc_fm_buf_pool_depletion_params_t *param,
+ uint8_t compat);
+
+void compat_copy_fm_buffer_prefix_content_params(
+ ioc_compat_fm_buffer_prefix_content_params_t *compat_param,
+ ioc_fm_buffer_prefix_content_params_t *param,
+ uint8_t compat);
+
+void compat_copy_fm_vsp_config_no_sg_params(
+ ioc_compat_fm_vsp_config_no_sg_params_t *compat_param,
+ ioc_fm_vsp_config_no_sg_params_t *param,
+ uint8_t compat);
+
+void compat_copy_fm_vsp_prs_result_params(
+ ioc_compat_fm_vsp_prs_result_params_t *compat_param,
+ ioc_fm_vsp_prs_result_params_t *param,
+ uint8_t compat);
+
+#endif /* (DPAA_VERSION >= 11) */
+
+void compat_copy_fm_pcd_kg_scheme_spc(
+ ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param,
+ ioc_fm_pcd_kg_scheme_spc_t *param,
+ uint8_t compat);
+
+/* } pcd compat functions */
+#endif
diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources.h b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources.h
new file mode 100644
index 000000000000..1b72e1d5bca6
--- /dev/null
+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources.h
@@ -0,0 +1,121 @@
+/*
+ * 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_resources.h
+
+ @Description FMD wrapper resource allocation functions.
+
+*/
+
+#ifndef LNXWRP_RESOURCES_H_
+#define LNXWRP_RESOURCES_H_
+
+#if !defined(FMAN_RESOURCES_UNIT_TEST)
+#include "lnxwrp_fm.h"
+#else
+#include "lnxwrp_resources_ut.h"
+#endif
+
+#define ROUND(X) ((2*(X)+1)/2)
+#define CEIL(X) ((X)+1)
+/* #define ROUND_DIV(X, Y) (((X)+(Y)/2)/(Y)) */
+#define ROUND_DIV(X, Y) ((2*(X)+(Y))/(2*(Y)))
+#define CEIL_DIV(X, Y) (((X)+(Y)-1)/(Y))
+
+/* used for resource calculus */
+#define DPDE_1G 2 /* DQDP 1g - from LLD:
+ DEFAULT_PORT_txFifoDeqPipelineDepth_1G */
+#define DPDE_10G 8 /* DQDP 10g - from LLD:
+ DEFAULT_PORT_txFifoDeqPipelineDepth_10G */
+
+int fm_set_active_fman_ports(struct platform_device *of_dev,
+ t_LnxWrpFmDev *p_LnxWrpFmDev);
+
+/* Calculate the fifosize based on MURAM allocation, number of ports, dpde
+ * value and s/g software support (! Kernel does not suport s/g).
+ *
+ * Algorithm summary:
+ * - Calculate the the minimum fifosize required for every type of port
+ * (TX,RX for 1G, 2.5G and 10G).
+ * - Set TX the minimum fifosize required.
+ * - Distribute the remaining buffers (after all TX were set) to RX ports
+ * based on:
+ * 1G RX = Remaining_buffers * 1/(1+2.5+10)
+ * 2.5G RX = Remaining_buffers * 2.5/(1+2.5+10)
+ * 10G RX = Remaining_buffers * 10/(1+2.5+10)
+ * - if the RX is smaller than the minimum required, then set the minimum
+ * required
+ * - In the end distribuite the leftovers if there are any (due to
+ * unprecise calculus) or if over allocation cat some buffers from all RX
+ * ports w/o pass over minimum required treshold, but if there must be
+ * pass the treshold in order to cat the over allocation ,then this
+ * configuration can not be set - KERN_ALERT.
+*/
+int fm_precalculate_fifosizes(t_LnxWrpFmDev *p_LnxWrpFmDev,
+ int muram_fifo_size);
+
+#if !defined(FMAN_RESOURCES_UNIT_TEST)
+int fm_config_precalculate_fifosize(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
+#endif
+
+/* Compute FMan open DMA based on total number of open DMAs and
+ * number of available fman ports.
+ *
+ * By default 10g ports are set to input parameters. The other ports
+ * tries to keep the proportion rx=2tx open dmas or tresholds.
+ *
+ * If leftovers, then those will be set as shared.
+ *
+ * If after computing overflow appears, then it decrements open dma
+ * for all ports w/o cross the tresholds. If the tresholds are meet
+ * and is still overflow, then it returns error.
+*/
+int fm_precalculate_open_dma(t_LnxWrpFmDev *p_LnxWrpFmDev,
+ int max_fm_open_dma,
+ int default_tx_10g_dmas,
+ int default_rx_10g_dmas,
+ int min_tx_10g_treshold, int min_rx_10g_treshold);
+
+#if !defined(FMAN_RESOURCES_UNIT_TEST)
+int fm_config_precalculate_open_dma(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
+#endif
+
+/* Compute FMan tnums based on available tnums and number of ports.
+ * Set defaults (minim tresholds) and then distribute leftovers.*/
+int fm_precalculate_tnums(t_LnxWrpFmDev *p_LnxWrpFmDev, int max_fm_tnums);
+
+#if !defined(FMAN_RESOURCES_UNIT_TEST)
+int fm_config_precalculate_tnums(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
+#endif
+
+#endif /* LNXWRP_RESOURCES_H_ */
diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.c
new file mode 100644
index 000000000000..6c06a5a677f1
--- /dev/null
+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.c
@@ -0,0 +1,191 @@
+/* Copyright (c) 2012 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of 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.
+ */
+
+#include "lnxwrp_resources.h"
+#include "lnxwrp_resources_ut.h"
+
+#define KILOBYTE 0x400 /* 1024 */
+
+typedef enum e_board_type {
+ e_p3041,
+ e_p4080,
+ e_p5020,
+ e_p1023
+} e_board_type;
+
+uint8_t board_type;
+uint32_t muram_size = 0;
+uint32_t dmas_num = 0;
+uint32_t task_num = 0;
+uint32_t frame_size = 0;
+uint32_t oh_num = 0;
+uint32_t num_ports_1g = 0;
+uint32_t num_ports_10g = 0;
+uint32_t num_ports_2g5 = 0;
+uint32_t fsl_fman_phy_maxfrm = 0;
+uint32_t dpa_rx_extra_headroom = 0;
+
+void show_help(void){
+ printf(" help: \n");
+ printf(" -b <board_type> -f <max_fram_size(mtu)> -o <num_oh_ports> -g1"
+ " <num_1g_ports> -g10 <num_10g_ports> -g25 <num_2g5_ports>\n");
+ printf(" Maxim num of DMAS availbale: P3/P4/P5:32 , P1023:16 \n");
+ printf(" Maxim num of TNUMs availbale: P3/P4/P5:128, P1023:32 \n");
+ printf(" Muram size: P3/P4/P5:160K, P1023:64K \n");
+ printf(" Number of ports:\n");
+ printf(" P3/P5: 5p 1g, 1p 10g, 7p oh \n");
+ printf(" P4 : 4p 1g, 1p 10g, 7p oh \n");
+ printf(" P1 : 2p 1g, 0p 10g, 4p oh \n");
+ printf(" MTU: Default:1522, Jumbo:9600 \n");
+}
+
+int fm_set_param(t_LnxWrpFmDev *p_LnxWrpFmDev) {
+ struct fm_active_ports *fm_active_ports_info = NULL;
+ fm_active_ports_info = &p_LnxWrpFmDev->fm_active_ports_info;
+
+ switch(board_type){
+ case e_p3041:
+ case e_p5020:
+ muram_size = 160*KILOBYTE;
+ dmas_num = 32;
+ task_num = 128;
+ if ((num_ports_1g+num_ports_2g5) > 5 || num_ports_10g > 1 || oh_num > 7)
+ goto err_fm_set_param;
+ break;
+ case e_p4080:
+ muram_size = 160*KILOBYTE;
+ dmas_num = 32;
+ task_num = 128;
+ if ((num_ports_1g+num_ports_2g5) > 4 || num_ports_10g > 1 || oh_num > 7)
+ goto err_fm_set_param;
+ break;
+ case e_p1023:
+ muram_size = 64*KILOBYTE;
+ dmas_num = 16;
+ task_num = 128;
+ if ((num_ports_1g+num_ports_2g5) > 2 || oh_num > 4)
+ goto err_fm_set_param;
+ break;
+ default:
+ goto err_fm_set_param;
+ break;
+ }
+
+ p_LnxWrpFmDev->id = 0;
+ fsl_fman_phy_maxfrm = frame_size;
+ dpa_rx_extra_headroom = 0; /* ATTENTION: can be != 0 */
+ fm_active_ports_info->num_oh_ports = oh_num;
+ fm_active_ports_info->num_tx_ports = num_ports_1g;
+ fm_active_ports_info->num_rx_ports = num_ports_1g;
+ fm_active_ports_info->num_tx25_ports = num_ports_2g5;
+ fm_active_ports_info->num_rx25_ports = num_ports_2g5;
+ fm_active_ports_info->num_tx10_ports = num_ports_10g;
+ fm_active_ports_info->num_rx10_ports = num_ports_10g;
+
+ return 0;
+
+err_fm_set_param:
+ printf(" ERR: To many ports!!! \n");
+ return -1;
+}
+
+int main (int argc, char *argv[]){
+ t_LnxWrpFmDev LnxWrpFmDev;
+ t_LnxWrpFmDev *p_LnxWrpFmDev = &LnxWrpFmDev;
+ int tokens_cnt = 1;
+
+ char *token = NULL;
+
+ while(tokens_cnt < argc)
+ {
+ token = argv[tokens_cnt++];
+ if (strcmp(token, "-b") == 0){
+ if(strcmp(argv[tokens_cnt],"p3") == 0)
+ board_type = e_p3041;
+ else if(strcmp(argv[tokens_cnt],"p4") == 0)
+ board_type = e_p4080;
+ else if(strcmp(argv[tokens_cnt],"p5") == 0)
+ board_type = e_p5020;
+ else if(strcmp(argv[tokens_cnt],"p1") == 0)
+ board_type = e_p1023;
+ else
+ show_help();
+ tokens_cnt++;
+ }
+ else if(strcmp(token, "-d") == 0){
+ dmas_num = atoi(argv[tokens_cnt++]);
+ }
+ else if(strcmp(token, "-t") == 0)
+ task_num = atoi(argv[tokens_cnt++]);
+ else if(strcmp(token, "-f") == 0)
+ frame_size = atoi(argv[tokens_cnt++]);
+ else if(strcmp(token, "-o") == 0)
+ oh_num = atoi(argv[tokens_cnt++]);
+ else if(strcmp(token, "-g1") == 0)
+ num_ports_1g = atoi(argv[tokens_cnt++]);
+ else if(strcmp(token, "-g10") == 0)
+ num_ports_10g = atoi(argv[tokens_cnt++]);
+ else if(strcmp(token, "-g25") == 0)
+ num_ports_2g5 = atoi(argv[tokens_cnt++]);
+ else {
+ show_help();
+ return -1;
+ }
+ }
+
+ if(fm_set_param(p_LnxWrpFmDev) < 0){
+ show_help();
+ return -1;
+ }
+
+ if(fm_precalculate_fifosizes(
+ p_LnxWrpFmDev,
+ 128*KILOBYTE)
+ != 0)
+ return -1;
+ if(fm_precalculate_open_dma(
+ p_LnxWrpFmDev,
+ dmas_num, /* max open dmas:dpaa_integration_ext.h */
+ FM_DEFAULT_TX10G_OPENDMA, /* default TX 10g open dmas */
+ FM_DEFAULT_RX10G_OPENDMA, /* default RX 10g open dmas */
+ FM_10G_OPENDMA_MIN_TRESHOLD,/* TX 10g minimum treshold */
+ FM_10G_OPENDMA_MIN_TRESHOLD)/* RX 10g minimum treshold */
+ != 0)
+ return -1;
+ if(fm_precalculate_tnums(
+ p_LnxWrpFmDev,
+ task_num) /* max TNUMS: dpa integration file. */
+ != 0)
+ return -1;
+
+ return 0;
+}
diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.h b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.h
new file mode 100644
index 000000000000..063946eb9ef8
--- /dev/null
+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.h
@@ -0,0 +1,144 @@
+/* Copyright (c) 2012 Freescale Semiconductor, Inc
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of 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.
+ */
+
+#ifndef FM_RESS_TEST_H_
+#define FM_RESS_TEST_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define _Packed
+#define _PackedType __attribute__ ((packed))
+#define MAX(x, y) (((x) > (y)) ? (x) : (y))
+#define MIN(x, y) (((x) < (y)) ? (x) : (y))
+#define KERN_ALERT ""
+#define KERN_INFO ""
+#define ASSERT_COND assert
+#define printk printf
+#define NET_IP_ALIGN 0
+#define FM_FIFO_ALLOCATION_OLD_ALG
+
+#if defined(CONFIG_FMAN_DISABLE_OH_AND_DISTRIBUTE_RESOURCES)
+#define FM_10G_OPENDMA_MIN_TRESHOLD 8 /* 10g minimum treshold if only HC is enabled and no OH port enabled */
+#define FM_OPENDMA_RX_TX_RAPORT 2 /* RX = 2*TX */
+#else
+#define FM_10G_OPENDMA_MIN_TRESHOLD 7 /* 10g minimum treshold if 7 OH ports are enabled */
+#define FM_OPENDMA_RX_TX_RAPORT 1 /* RX = TX */
+#endif
+#define FM_DEFAULT_TX10G_OPENDMA 8 /* default TX 10g open dmas */
+#define FM_DEFAULT_RX10G_OPENDMA 8 /* default RX 10g open dmas */
+
+/* information about all active ports for an FMan.
+ * !Some ports may be disabled by u-boot, thus will not be available */
+struct fm_active_ports {
+ uint32_t num_oh_ports;
+ uint32_t num_tx_ports;
+ uint32_t num_rx_ports;
+ uint32_t num_tx25_ports;
+ uint32_t num_rx25_ports;
+ uint32_t num_tx10_ports;
+ uint32_t num_rx10_ports;
+};
+
+/* FMan resources precalculated at fm probe based
+ * on available FMan port. */
+struct fm_resource_settings {
+ /* buffers - fifo sizes */
+ uint32_t tx1g_num_buffers;
+ uint32_t rx1g_num_buffers;
+ uint32_t tx2g5_num_buffers; /* Not supported yet by LLD */
+ uint32_t rx2g5_num_buffers; /* Not supported yet by LLD */
+ uint32_t tx10g_num_buffers;
+ uint32_t rx10g_num_buffers;
+ uint32_t oh_num_buffers;
+ uint32_t shared_ext_buffers;
+
+
+ /* open DMAs */
+ uint32_t tx_1g_dmas;
+ uint32_t rx_1g_dmas;
+ uint32_t tx_2g5_dmas; /* Not supported yet by LLD */
+ uint32_t rx_2g5_dmas; /* Not supported yet by LLD */
+ uint32_t tx_10g_dmas;
+ uint32_t rx_10g_dmas;
+ uint32_t oh_dmas;
+ uint32_t shared_ext_open_dma;
+
+ /* Tnums */
+ uint32_t tx_1g_tnums;
+ uint32_t rx_1g_tnums;
+ uint32_t tx_2g5_tnums; /* Not supported yet by LLD */
+ uint32_t rx_2g5_tnums; /* Not supported yet by LLD */
+ uint32_t tx_10g_tnums;
+ uint32_t rx_10g_tnums;
+ uint32_t oh_tnums;
+ uint32_t shared_ext_tnums;
+};
+
+typedef struct {
+ uint8_t id;
+ struct fm_active_ports fm_active_ports_info;
+ struct fm_resource_settings fm_resource_settings_info;
+} t_LnxWrpFmDev;
+
+typedef struct {
+ uint8_t id;
+} t_LnxWrpFmPortDev;
+
+typedef _Packed struct t_FmPrsResult {
+ volatile uint8_t lpid; /**< Logical port id */
+ volatile uint8_t shimr; /**< Shim header result */
+ volatile uint16_t l2r; /**< Layer 2 result */
+ volatile uint16_t l3r; /**< Layer 3 result */
+ volatile uint8_t l4r; /**< Layer 4 result */
+ volatile uint8_t cplan; /**< Classification plan id */
+ volatile uint16_t nxthdr; /**< Next Header */
+ volatile uint16_t cksum; /**< Checksum */
+ volatile uint32_t lcv; /**< LCV */
+ volatile uint8_t shim_off[3]; /**< Shim offset */
+ volatile uint8_t eth_off; /**< ETH offset */
+ volatile uint8_t llc_snap_off; /**< LLC_SNAP offset */
+ volatile uint8_t vlan_off[2]; /**< VLAN offset */
+ volatile uint8_t etype_off; /**< ETYPE offset */
+ volatile uint8_t pppoe_off; /**< PPP offset */
+ volatile uint8_t mpls_off[2]; /**< MPLS offset */
+ volatile uint8_t ip_off[2]; /**< IP offset */
+ volatile uint8_t gre_off; /**< GRE offset */
+ volatile uint8_t l4_off; /**< Layer 4 offset */
+ volatile uint8_t nxthdr_off; /**< Parser end point */
+} _PackedType t_FmPrsResult;
+
+#endif
diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.make b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.make
new file mode 100644
index 000000000000..58009cd8a91e
--- /dev/null
+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.make
@@ -0,0 +1,28 @@
+CC=gcc
+
+LNXWRP_RESS_UT=lnxwrp_resources_ut
+OBJ=lnxwrp_resources
+
+INC_PATH=
+LIB_PATH=
+
+INC=$(addprefix -I,$(INC_PATH))
+LIB=$(addprefix -L,$(LIB_PATH))
+
+CFLAGS= -gdwarf-2 -g -O0 -Wall
+XFLAGS= -DFMAN_RESOURCES_UNIT_TEST
+
+all: $(LNXWRP_RESS_UT)
+
+$(LNXWRP_RESS_UT):$(addsuffix .o,$(OBJ)) $(LNXWRP_RESS_UT).o
+ $(CC) -o $(LNXWRP_RESS_UT) $(LNXWRP_RESS_UT).o $(addsuffix .o,$(OBJ))
+
+%.o: %.c
+ @(echo " (CC) $@")
+ @($(CC) $(INC) $(CFLAGS) $(XFLAGS) -o $(@) -c $<)
+
+.PHONY: clean
+
+clean:
+ rm -f *.o
+ rm -f $(LNXWRP_RESS_UT)
diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c
new file mode 100644
index 000000000000..813771bfdac7
--- /dev/null
+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c
@@ -0,0 +1,60 @@
+/*
+ * 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_sysfs.c
+
+ @Description FM wrapper sysfs related functions.
+
+*/
+
+#include <linux/types.h>
+#include "lnxwrp_sysfs.h"
+
+uint8_t fm_find_statistic_counter_by_name(const char *attr_name,
+ const struct sysfs_stats_t *sysfs_stats,
+ uint8_t *offset)
+{
+ int i = 0;
+
+ while (sysfs_stats[i].stat_name != NULL) {
+ if (strcmp(sysfs_stats[i].stat_name, attr_name) == 0) {
+ if (offset != NULL)
+ *offset = i;
+ return sysfs_stats[i].stat_counter;
+ }
+
+ i++;
+ }
+ WARN(1, "FMD: Should never get here!");
+ return 0;
+}
diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h
new file mode 100644
index 000000000000..e6ac4934af18
--- /dev/null
+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+#ifndef LNXWRP_SYSFS_H_
+#define LNXWRP_SYSFS_H_
+
+/* Linux Headers ------------------- */
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/sysfs.h>
+
+struct sysfs_stats_t {
+ const char *stat_name;
+ uint8_t stat_counter;
+};
+
+uint8_t fm_find_statistic_counter_by_name(const char *attr_name,
+ const struct sysfs_stats_t *sysfs_stats,
+ uint8_t *offset);
+
+#endif /* LNXWRP_SYSFS_H_ */
diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c
new file mode 100644
index 000000000000..844c8bd5e15f
--- /dev/null
+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c
@@ -0,0 +1,1858 @@
+/*
+ * 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.
+ */
+
+#include "lnxwrp_sysfs.h"
+#include "lnxwrp_sysfs_fm.h"
+#include "lnxwrp_fm.h"
+
+#include "../../sdk_fman/Peripherals/FM/inc/fm_common.h"
+#include "../../sdk_fman/Peripherals/FM/Pcd/fm_pcd.h"
+#include "../../sdk_fman/Peripherals/FM/Pcd/fm_kg.h"
+#include "../../sdk_fman/Peripherals/FM/Pcd/fm_plcr.h"
+
+#if defined(__ERR_MODULE__)
+#undef __ERR_MODULE__
+#endif
+
+#include "../../sdk_fman/Peripherals/FM/fm.h"
+#include <linux/delay.h>
+
+
+static int fm_get_counter(void *h_fm, e_FmCounters cnt_e, uint32_t *cnt_val);
+
+enum fm_dma_match_stats {
+ FM_DMA_COUNTERS_CMQ_NOT_EMPTY,
+ FM_DMA_COUNTERS_BUS_ERROR,
+ FM_DMA_COUNTERS_READ_BUF_ECC_ERROR,
+ FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR,
+ FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR
+};
+
+static const struct sysfs_stats_t fm_sysfs_stats[] = {
+ /* FM statistics */
+ {
+ .stat_name = "enq_total_frame",
+ .stat_counter = e_FM_COUNTERS_ENQ_TOTAL_FRAME,
+ },
+ {
+ .stat_name = "deq_total_frame",
+ .stat_counter = e_FM_COUNTERS_DEQ_TOTAL_FRAME,
+ },
+ {
+ .stat_name = "deq_0",
+ .stat_counter = e_FM_COUNTERS_DEQ_0,
+ },
+ {
+ .stat_name = "deq_1",
+ .stat_counter = e_FM_COUNTERS_DEQ_1,
+ },
+ {
+ .stat_name = "deq_2",
+ .stat_counter = e_FM_COUNTERS_DEQ_2,
+ },
+ {
+ .stat_name = "deq_3",
+ .stat_counter = e_FM_COUNTERS_DEQ_3,
+ },
+ {
+ .stat_name = "deq_from_default",
+ .stat_counter = e_FM_COUNTERS_DEQ_FROM_DEFAULT,
+ },
+ {
+ .stat_name = "deq_from_context",
+ .stat_counter = e_FM_COUNTERS_DEQ_FROM_CONTEXT,
+ },
+ {
+ .stat_name = "deq_from_fd",
+ .stat_counter = e_FM_COUNTERS_DEQ_FROM_FD,
+ },
+ {
+ .stat_name = "deq_confirm",
+ .stat_counter = e_FM_COUNTERS_DEQ_CONFIRM,
+ },
+ /* FM:DMA statistics */
+ {
+ .stat_name = "cmq_not_empty",
+ .stat_counter = FM_DMA_COUNTERS_CMQ_NOT_EMPTY,
+ },
+ {
+ .stat_name = "bus_error",
+ .stat_counter = FM_DMA_COUNTERS_BUS_ERROR,
+ },
+ {
+ .stat_name = "read_buf_ecc_error",
+ .stat_counter = FM_DMA_COUNTERS_READ_BUF_ECC_ERROR,
+ },
+ {
+ .stat_name = "write_buf_ecc_sys_error",
+ .stat_counter = FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR,
+ },
+ {
+ .stat_name = "write_buf_ecc_fm_error",
+ .stat_counter = FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR,
+ },
+ /* FM:PCD statistics */
+ {
+ .stat_name = "pcd_kg_total",
+ .stat_counter = e_FM_PCD_KG_COUNTERS_TOTAL,
+ },
+ {
+ .stat_name = "pcd_plcr_yellow",
+ .stat_counter = e_FM_PCD_PLCR_COUNTERS_YELLOW,
+ },
+ {
+ .stat_name = "pcd_plcr_red",
+ .stat_counter = e_FM_PCD_PLCR_COUNTERS_RED,
+ },
+ {
+ .stat_name = "pcd_plcr_recolored_to_red",
+ .stat_counter = e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED,
+ },
+ {
+ .stat_name = "pcd_plcr_recolored_to_yellow",
+ .stat_counter = e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW,
+ },
+ {
+ .stat_name = "pcd_plcr_total",
+ .stat_counter = e_FM_PCD_PLCR_COUNTERS_TOTAL,
+ },
+ {
+ .stat_name = "pcd_plcr_length_mismatch",
+ .stat_counter = e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH,
+ },
+ {
+ .stat_name = "pcd_prs_parse_dispatch",
+ .stat_counter = e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH,
+ },
+ {
+ .stat_name = "pcd_prs_l2_parse_result_returned",
+ .stat_counter = e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED,
+ },
+ {
+ .stat_name = "pcd_prs_l3_parse_result_returned",
+ .stat_counter = e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED,
+ },
+ {
+ .stat_name = "pcd_prs_l4_parse_result_returned",
+ .stat_counter = e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED,
+ },
+ {
+ .stat_name = "pcd_prs_shim_parse_result_returned",
+ .stat_counter = e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED,
+ },
+ {
+ .stat_name = "pcd_prs_l2_parse_result_returned_with_err",
+ .stat_counter =
+ e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR,
+ },
+ {
+ .stat_name = "pcd_prs_l3_parse_result_returned_with_err",
+ .stat_counter =
+ e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR,
+ },
+ {
+ .stat_name = "pcd_prs_l4_parse_result_returned_with_err",
+ .stat_counter =
+ e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR,
+ },
+ {
+ .stat_name = "pcd_prs_shim_parse_result_returned_with_err",
+ .stat_counter =
+ e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR,
+ },
+ {
+ .stat_name = "pcd_prs_soft_prs_cycles",
+ .stat_counter = e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES,
+ },
+ {
+ .stat_name = "pcd_prs_soft_prs_stall_cycles",
+ .stat_counter = e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES,
+ },
+ {
+ .stat_name = "pcd_prs_hard_prs_cycle_incl_stall_cycles",
+ .stat_counter =
+ e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES,
+ },
+ {
+ .stat_name = "pcd_prs_muram_read_cycles",
+ .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES,
+ },
+ {
+ .stat_name = "pcd_prs_muram_read_stall_cycles",
+ .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES,
+ },
+ {
+ .stat_name = "pcd_prs_muram_write_cycles",
+ .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES,
+ },
+ {
+ .stat_name = "pcd_prs_muram_write_stall_cycles",
+ .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES,
+ },
+ {
+ .stat_name = "pcd_prs_fpm_command_stall_cycles",
+ .stat_counter = e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES,
+ },
+ {}
+};
+
+
+static ssize_t show_fm_risc_load(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
+ unsigned long flags;
+ int m =0;
+ int err =0;
+ unsigned n = 0;
+ t_FmCtrlMon util;
+ uint8_t i =0 ;
+
+ if (attr == NULL || buf == NULL || dev == NULL)
+ return -EINVAL;
+
+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
+ if (WARN_ON(p_wrp_fm_dev == NULL))
+ return -EINVAL;
+
+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
+ return -EIO;
+
+ local_irq_save(flags);
+
+ /* Calculate risc load */
+ FM_CtrlMonStart(p_wrp_fm_dev->h_Dev);
+ msleep(1000);
+ FM_CtrlMonStop(p_wrp_fm_dev->h_Dev);
+
+ for (i = 0; i < FM_NUM_OF_CTRL; i++) {
+ err |= FM_CtrlMonGetCounters(p_wrp_fm_dev->h_Dev, i, &util);
+ m = snprintf(&buf[n],PAGE_SIZE,"\tRisc%u: util-%u%%, efficiency-%u%%\n",
+ i, util.percentCnt[0], util.percentCnt[1]);
+ n=m+n;
+ }
+
+ local_irq_restore(flags);
+
+ return n;
+}
+
+/* Fm stats and regs dumps via sysfs */
+static ssize_t show_fm_dma_stats(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
+ t_FmDmaStatus dma_status;
+ unsigned long flags = 0;
+ unsigned n = 0;
+ uint8_t counter_value = 0, counter = 0;
+
+ if (attr == NULL || buf == NULL || dev == NULL)
+ return -EINVAL;
+
+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
+ if (WARN_ON(p_wrp_fm_dev == NULL))
+ return -EINVAL;
+
+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
+ return -EIO;
+
+ counter = fm_find_statistic_counter_by_name(
+ attr->attr.name,
+ fm_sysfs_stats, NULL);
+
+ local_irq_save(flags);
+
+ memset(&dma_status, 0, sizeof(dma_status));
+ FM_GetDmaStatus(p_wrp_fm_dev->h_Dev, &dma_status);
+
+ switch (counter) {
+ case FM_DMA_COUNTERS_CMQ_NOT_EMPTY:
+ counter_value = dma_status.cmqNotEmpty;
+ break;
+ case FM_DMA_COUNTERS_BUS_ERROR:
+ counter_value = dma_status.busError;
+ break;
+ case FM_DMA_COUNTERS_READ_BUF_ECC_ERROR:
+ counter_value = dma_status.readBufEccError;
+ break;
+ case FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR:
+ counter_value = dma_status.writeBufEccSysError;
+ break;
+ case FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR:
+ counter_value = dma_status.writeBufEccFmError;
+ break;
+ default:
+ WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
+ __func__);
+ break;
+ };
+
+ n = snprintf(buf, PAGE_SIZE, "\tFM %u counter: %c\n",
+ p_wrp_fm_dev->id, counter_value ? 'T' : 'F');
+
+ local_irq_restore(flags);
+
+ return n;
+}
+
+static ssize_t show_fm_stats(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
+ unsigned long flags = 0;
+ unsigned n = 0, cnt_e = 0;
+ uint32_t cnt_val;
+ int err;
+
+ if (attr == NULL || buf == NULL || dev == NULL)
+ return -EINVAL;
+
+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
+ if (WARN_ON(p_wrp_fm_dev == NULL))
+ return -EINVAL;
+
+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
+ return -EIO;
+
+ cnt_e = fm_find_statistic_counter_by_name(
+ attr->attr.name,
+ fm_sysfs_stats, NULL);
+
+ err = fm_get_counter(p_wrp_fm_dev->h_Dev,
+ (e_FmCounters) cnt_e, &cnt_val);
+
+ if (err)
+ return err;
+
+ local_irq_save(flags);
+
+ n = snprintf(buf, PAGE_SIZE, "\tFM %d counter: %d\n",
+ p_wrp_fm_dev->id, cnt_val);
+
+ local_irq_restore(flags);
+
+ return n;
+}
+
+static ssize_t show_fm_muram_free_sz(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
+ unsigned long flags = 0;
+ unsigned n = 0;
+ uint64_t muram_free_size = 0;
+
+ if (attr == NULL || buf == NULL || dev == NULL)
+ return -EINVAL;
+
+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
+ if (WARN_ON(p_wrp_fm_dev == NULL))
+ return -EINVAL;
+
+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
+ return -EIO;
+
+ muram_free_size = FM_MURAM_GetFreeMemSize(p_wrp_fm_dev->h_MuramDev);
+
+ local_irq_save(flags);
+
+ n = snprintf(buf, PAGE_SIZE, "\tFM %d muram_free_size: %lld\n",
+ p_wrp_fm_dev->id, muram_free_size);
+
+ local_irq_restore(flags);
+
+ return n;
+}
+
+static ssize_t show_fm_ctrl_code_ver(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
+ unsigned long flags = 0;
+ unsigned n = 0;
+ t_FmCtrlCodeRevisionInfo rv_info;
+
+ if (attr == NULL || buf == NULL || dev == NULL)
+ return -EINVAL;
+
+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
+ if (WARN_ON(p_wrp_fm_dev == NULL))
+ return -EINVAL;
+
+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
+ return -EIO;
+
+ FM_GetFmanCtrlCodeRevision((t_Fm *)p_wrp_fm_dev->h_Dev, &rv_info);
+
+ local_irq_save(flags);
+
+ FM_DMP_LN(buf, n, "- FM %d ctrl code pkg info:\n", p_wrp_fm_dev->id);
+ FM_DMP_LN(buf, n, "Package rev: %d\n", rv_info.packageRev);
+ FM_DMP_LN(buf, n, "major rev: %d\n", rv_info.majorRev);
+ FM_DMP_LN(buf, n, "minor rev: %d\n", rv_info.minorRev);
+
+ local_irq_restore(flags);
+
+ return n;
+}
+
+static ssize_t show_fm_pcd_stats(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
+ unsigned long flags = 0;
+ unsigned n = 0, counter = 0;
+
+ if (attr == NULL || buf == NULL || dev == NULL)
+ return -EINVAL;
+
+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
+ if (WARN_ON(p_wrp_fm_dev == NULL))
+ return -EINVAL;
+
+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev ||
+ !p_wrp_fm_dev->h_PcdDev)
+ return -EIO;
+
+ counter = fm_find_statistic_counter_by_name(
+ attr->attr.name,
+ fm_sysfs_stats, NULL);
+
+ local_irq_save(flags);
+
+ n = snprintf(buf, PAGE_SIZE, "\tFM %d counter: %d\n",
+ p_wrp_fm_dev->id,
+ FM_PCD_GetCounter(p_wrp_fm_dev->h_PcdDev,
+ (e_FmPcdCounters) counter));
+
+ local_irq_restore(flags);
+
+ return n;
+}
+
+static ssize_t show_fm_tnum_dbg(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long flags;
+ unsigned n = 0;
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
+#endif
+
+ if (attr == NULL || buf == NULL || dev == NULL)
+ return -EINVAL;
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+
+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
+ if (WARN_ON(p_wrp_fm_dev == NULL))
+ return -EINVAL;
+
+ local_irq_save(flags);
+
+ if (!p_wrp_fm_dev->active)
+ return -EIO;
+ else {
+ int tn_s;
+
+ if (!sscanf(attr->attr.name, "tnum_dbg_%d", &tn_s))
+ return -EINVAL;
+
+ n = fm_dump_tnum_dbg(p_wrp_fm_dev->h_Dev,
+ tn_s, tn_s + 15, buf, n);
+ }
+ local_irq_restore(flags);
+#else
+
+ local_irq_save(flags);
+ n = snprintf(buf, PAGE_SIZE,
+ "Debug level is too low to dump registers!!!\n");
+ local_irq_restore(flags);
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+ return n;
+}
+
+static ssize_t show_fm_cls_plan(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long flags;
+ unsigned n = 0;
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
+#endif
+
+ if (attr == NULL || buf == NULL || dev == NULL)
+ return -EINVAL;
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
+ if (WARN_ON(p_wrp_fm_dev == NULL))
+ return -EINVAL;
+
+ local_irq_save(flags);
+
+ n = snprintf(buf, PAGE_SIZE, "\n FM-KG classification plan dump.\n");
+
+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
+ return -EIO;
+ else {
+ int cpn;
+
+ if (!sscanf(attr->attr.name, "cls_plan_%d", &cpn))
+ return -EINVAL;
+
+ n = fm_dump_cls_plan(p_wrp_fm_dev->h_PcdDev, cpn, buf, n);
+ }
+ local_irq_restore(flags);
+#else
+ local_irq_save(flags);
+ n = snprintf(buf, PAGE_SIZE,
+ "Debug level is too low to dump registers!!!\n");
+ local_irq_restore(flags);
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+ return n;
+}
+
+static ssize_t show_fm_profiles(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long flags;
+ unsigned n = 0;
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
+#endif
+
+ if (attr == NULL || buf == NULL || dev == NULL)
+ return -EINVAL;
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+
+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
+ if (WARN_ON(p_wrp_fm_dev == NULL))
+ return -EINVAL;
+
+ local_irq_save(flags);
+
+ n = snprintf(buf, PAGE_SIZE, "FM policer profile dump.\n");
+
+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
+ return -EIO;
+ else {
+ int pn;
+
+ if (!sscanf(attr->attr.name, "profile_%d", &pn))
+ return -EINVAL;
+
+ n = fm_profile_dump_regs(p_wrp_fm_dev->h_PcdDev, pn, buf, n);
+ }
+ local_irq_restore(flags);
+#else
+ local_irq_save(flags);
+ n = snprintf(buf, PAGE_SIZE,
+ "Debug level is too low to dump registers!!!\n");
+ local_irq_restore(flags);
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+ return n;
+}
+
+static ssize_t show_fm_schemes(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long flags;
+ unsigned n = 0;
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
+#endif
+
+ if (attr == NULL || buf == NULL || dev == NULL)
+ return -EINVAL;
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+
+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
+ if (WARN_ON(p_wrp_fm_dev == NULL))
+ return -EINVAL;
+
+ local_irq_save(flags);
+
+ n = snprintf(buf, PAGE_SIZE, "FM-KG driver schemes dump.\n");
+
+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
+ return -EIO;
+ else {
+ int sn;
+
+ if (!sscanf(attr->attr.name, "scheme_%d", &sn))
+ return -EINVAL;
+
+ n = fm_dump_scheme(p_wrp_fm_dev->h_PcdDev, sn, buf, n);
+ }
+ local_irq_restore(flags);
+#else
+
+ local_irq_save(flags);
+ n = snprintf(buf, PAGE_SIZE,
+ "Debug level is too low to dump registers!!!\n");
+ local_irq_restore(flags);
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+ return n;
+}
+
+/* FM */
+static DEVICE_ATTR(enq_total_frame, S_IRUGO, show_fm_stats, NULL);
+static DEVICE_ATTR(deq_total_frame, S_IRUGO, show_fm_stats, NULL);
+static DEVICE_ATTR(fm_risc_load_val, S_IRUGO, show_fm_risc_load, NULL);
+static DEVICE_ATTR(deq_0, S_IRUGO, show_fm_stats, NULL);
+static DEVICE_ATTR(deq_1, S_IRUGO, show_fm_stats, NULL);
+static DEVICE_ATTR(deq_2, S_IRUGO, show_fm_stats, NULL);
+static DEVICE_ATTR(deq_3, S_IRUGO, show_fm_stats, NULL);
+static DEVICE_ATTR(deq_from_default, S_IRUGO, show_fm_stats, NULL);
+static DEVICE_ATTR(deq_from_context, S_IRUGO, show_fm_stats, NULL);
+static DEVICE_ATTR(deq_from_fd, S_IRUGO, show_fm_stats, NULL);
+static DEVICE_ATTR(deq_confirm, S_IRUGO, show_fm_stats, NULL);
+/* FM:DMA */
+static DEVICE_ATTR(cmq_not_empty, S_IRUGO, show_fm_dma_stats, NULL);
+static DEVICE_ATTR(bus_error, S_IRUGO, show_fm_dma_stats, NULL);
+static DEVICE_ATTR(read_buf_ecc_error, S_IRUGO, show_fm_dma_stats, NULL);
+static DEVICE_ATTR(write_buf_ecc_sys_error, S_IRUGO, show_fm_dma_stats, NULL);
+static DEVICE_ATTR(write_buf_ecc_fm_error, S_IRUGO, show_fm_dma_stats, NULL);
+/* FM:PCD */
+static DEVICE_ATTR(pcd_kg_total, S_IRUGO, show_fm_pcd_stats, NULL);
+static DEVICE_ATTR(pcd_plcr_yellow, S_IRUGO, show_fm_pcd_stats, NULL);
+static DEVICE_ATTR(pcd_plcr_red, S_IRUGO, show_fm_pcd_stats, NULL);
+static DEVICE_ATTR(pcd_plcr_recolored_to_red, S_IRUGO, show_fm_pcd_stats,
+ NULL);
+static DEVICE_ATTR(pcd_plcr_recolored_to_yellow, S_IRUGO, show_fm_pcd_stats,
+ NULL);
+static DEVICE_ATTR(pcd_plcr_total, S_IRUGO, show_fm_pcd_stats, NULL);
+static DEVICE_ATTR(pcd_plcr_length_mismatch, S_IRUGO, show_fm_pcd_stats,
+ NULL);
+static DEVICE_ATTR(pcd_prs_parse_dispatch, S_IRUGO, show_fm_pcd_stats, NULL);
+static DEVICE_ATTR(pcd_prs_l2_parse_result_returned, S_IRUGO,
+ show_fm_pcd_stats, NULL);
+static DEVICE_ATTR(pcd_prs_l3_parse_result_returned, S_IRUGO,
+ show_fm_pcd_stats, NULL);
+static DEVICE_ATTR(pcd_prs_l4_parse_result_returned, S_IRUGO,
+ show_fm_pcd_stats, NULL);
+static DEVICE_ATTR(pcd_prs_shim_parse_result_returned, S_IRUGO,
+ show_fm_pcd_stats, NULL);
+static DEVICE_ATTR(pcd_prs_l2_parse_result_returned_with_err, S_IRUGO,
+ show_fm_pcd_stats, NULL);
+static DEVICE_ATTR(pcd_prs_l3_parse_result_returned_with_err, S_IRUGO,
+ show_fm_pcd_stats, NULL);
+static DEVICE_ATTR(pcd_prs_l4_parse_result_returned_with_err, S_IRUGO,
+ show_fm_pcd_stats, NULL);
+static DEVICE_ATTR(pcd_prs_shim_parse_result_returned_with_err, S_IRUGO,
+ show_fm_pcd_stats, NULL);
+static DEVICE_ATTR(pcd_prs_soft_prs_cycles, S_IRUGO, show_fm_pcd_stats, NULL);
+static DEVICE_ATTR(pcd_prs_soft_prs_stall_cycles, S_IRUGO, show_fm_pcd_stats,
+ NULL);
+static DEVICE_ATTR(pcd_prs_hard_prs_cycle_incl_stall_cycles, S_IRUGO,
+ show_fm_pcd_stats, NULL);
+static DEVICE_ATTR(pcd_prs_muram_read_cycles, S_IRUGO, show_fm_pcd_stats,
+ NULL);
+static DEVICE_ATTR(pcd_prs_muram_read_stall_cycles, S_IRUGO,
+ show_fm_pcd_stats, NULL);
+static DEVICE_ATTR(pcd_prs_muram_write_cycles, S_IRUGO, show_fm_pcd_stats,
+ NULL);
+static DEVICE_ATTR(pcd_prs_muram_write_stall_cycles, S_IRUGO,
+ show_fm_pcd_stats, NULL);
+static DEVICE_ATTR(pcd_prs_fpm_command_stall_cycles, S_IRUGO,
+ show_fm_pcd_stats, NULL);
+
+static DEVICE_ATTR(tnum_dbg_0, S_IRUGO, show_fm_tnum_dbg, NULL);
+static DEVICE_ATTR(tnum_dbg_16, S_IRUGO, show_fm_tnum_dbg, NULL);
+static DEVICE_ATTR(tnum_dbg_32, S_IRUGO, show_fm_tnum_dbg, NULL);
+static DEVICE_ATTR(tnum_dbg_48, S_IRUGO, show_fm_tnum_dbg, NULL);
+static DEVICE_ATTR(tnum_dbg_64, S_IRUGO, show_fm_tnum_dbg, NULL);
+static DEVICE_ATTR(tnum_dbg_80, S_IRUGO, show_fm_tnum_dbg, NULL);
+static DEVICE_ATTR(tnum_dbg_96, S_IRUGO, show_fm_tnum_dbg, NULL);
+static DEVICE_ATTR(tnum_dbg_112, S_IRUGO, show_fm_tnum_dbg, NULL);
+
+static DEVICE_ATTR(cls_plan_0, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_1, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_2, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_3, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_4, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_5, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_6, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_7, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_8, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_9, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_10, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_11, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_12, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_13, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_14, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_15, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_16, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_17, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_18, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_19, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_20, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_21, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_22, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_23, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_24, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_25, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_26, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_27, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_28, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_29, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_30, S_IRUGO, show_fm_cls_plan, NULL);
+static DEVICE_ATTR(cls_plan_31, S_IRUGO, show_fm_cls_plan, NULL);
+
+static DEVICE_ATTR(profile_0, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_1, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_2, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_3, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_4, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_5, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_6, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_7, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_8, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_9, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_10, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_11, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_12, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_13, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_14, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_15, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_16, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_17, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_18, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_19, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_20, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_21, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_22, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_23, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_24, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_25, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_26, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_27, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_28, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_29, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_30, S_IRUGO, show_fm_profiles, NULL);
+static DEVICE_ATTR(profile_31, S_IRUGO, show_fm_profiles, NULL);
+
+static DEVICE_ATTR(scheme_0, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_1, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_2, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_3, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_4, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_5, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_6, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_7, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_8, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_9, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_10, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_11, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_12, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_13, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_14, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_15, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_16, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_17, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_18, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_19, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_20, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_21, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_22, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_23, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_24, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_25, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_26, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_27, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_28, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_29, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_30, S_IRUGO, show_fm_schemes, NULL);
+static DEVICE_ATTR(scheme_31, S_IRUGO, show_fm_schemes, NULL);
+
+
+static struct attribute *fm_dev_stats_attributes[] = {
+ &dev_attr_enq_total_frame.attr,
+ &dev_attr_deq_total_frame.attr,
+ &dev_attr_deq_0.attr,
+ &dev_attr_deq_1.attr,
+ &dev_attr_deq_2.attr,
+ &dev_attr_deq_3.attr,
+ &dev_attr_deq_from_default.attr,
+ &dev_attr_deq_from_context.attr,
+ &dev_attr_deq_from_fd.attr,
+ &dev_attr_deq_confirm.attr,
+ &dev_attr_cmq_not_empty.attr,
+ &dev_attr_bus_error.attr,
+ &dev_attr_read_buf_ecc_error.attr,
+ &dev_attr_write_buf_ecc_sys_error.attr,
+ &dev_attr_write_buf_ecc_fm_error.attr,
+ &dev_attr_pcd_kg_total.attr,
+ &dev_attr_pcd_plcr_yellow.attr,
+ &dev_attr_pcd_plcr_red.attr,
+ &dev_attr_pcd_plcr_recolored_to_red.attr,
+ &dev_attr_pcd_plcr_recolored_to_yellow.attr,
+ &dev_attr_pcd_plcr_total.attr,
+ &dev_attr_pcd_plcr_length_mismatch.attr,
+ &dev_attr_pcd_prs_parse_dispatch.attr,
+ &dev_attr_pcd_prs_l2_parse_result_returned.attr,
+ &dev_attr_pcd_prs_l3_parse_result_returned.attr,
+ &dev_attr_pcd_prs_l4_parse_result_returned.attr,
+ &dev_attr_pcd_prs_shim_parse_result_returned.attr,
+ &dev_attr_pcd_prs_l2_parse_result_returned_with_err.attr,
+ &dev_attr_pcd_prs_l3_parse_result_returned_with_err.attr,
+ &dev_attr_pcd_prs_l4_parse_result_returned_with_err.attr,
+ &dev_attr_pcd_prs_shim_parse_result_returned_with_err.attr,
+ &dev_attr_pcd_prs_soft_prs_cycles.attr,
+ &dev_attr_pcd_prs_soft_prs_stall_cycles.attr,
+ &dev_attr_pcd_prs_hard_prs_cycle_incl_stall_cycles.attr,
+ &dev_attr_pcd_prs_muram_read_cycles.attr,
+ &dev_attr_pcd_prs_muram_read_stall_cycles.attr,
+ &dev_attr_pcd_prs_muram_write_cycles.attr,
+ &dev_attr_pcd_prs_muram_write_stall_cycles.attr,
+ &dev_attr_pcd_prs_fpm_command_stall_cycles.attr,
+ NULL
+};
+
+static struct attribute *fm_dev_tnums_dbg_attributes[] = {
+ &dev_attr_tnum_dbg_0.attr,
+ &dev_attr_tnum_dbg_16.attr,
+ &dev_attr_tnum_dbg_32.attr,
+ &dev_attr_tnum_dbg_48.attr,
+ &dev_attr_tnum_dbg_64.attr,
+ &dev_attr_tnum_dbg_80.attr,
+ &dev_attr_tnum_dbg_96.attr,
+ &dev_attr_tnum_dbg_112.attr,
+ NULL
+};
+
+static struct attribute *fm_dev_cls_plans_attributes[] = {
+ &dev_attr_cls_plan_0.attr,
+ &dev_attr_cls_plan_1.attr,
+ &dev_attr_cls_plan_2.attr,
+ &dev_attr_cls_plan_3.attr,
+ &dev_attr_cls_plan_4.attr,
+ &dev_attr_cls_plan_5.attr,
+ &dev_attr_cls_plan_6.attr,
+ &dev_attr_cls_plan_7.attr,
+ &dev_attr_cls_plan_8.attr,
+ &dev_attr_cls_plan_9.attr,
+ &dev_attr_cls_plan_10.attr,
+ &dev_attr_cls_plan_11.attr,
+ &dev_attr_cls_plan_12.attr,
+ &dev_attr_cls_plan_13.attr,
+ &dev_attr_cls_plan_14.attr,
+ &dev_attr_cls_plan_15.attr,
+ &dev_attr_cls_plan_16.attr,
+ &dev_attr_cls_plan_17.attr,
+ &dev_attr_cls_plan_18.attr,
+ &dev_attr_cls_plan_19.attr,
+ &dev_attr_cls_plan_20.attr,
+ &dev_attr_cls_plan_21.attr,
+ &dev_attr_cls_plan_22.attr,
+ &dev_attr_cls_plan_23.attr,
+ &dev_attr_cls_plan_24.attr,
+ &dev_attr_cls_plan_25.attr,
+ &dev_attr_cls_plan_26.attr,
+ &dev_attr_cls_plan_27.attr,
+ &dev_attr_cls_plan_28.attr,
+ &dev_attr_cls_plan_29.attr,
+ &dev_attr_cls_plan_30.attr,
+ &dev_attr_cls_plan_31.attr,
+ NULL
+};
+
+static struct attribute *fm_dev_profiles_attributes[] = {
+ &dev_attr_profile_0.attr,
+ &dev_attr_profile_1.attr,
+ &dev_attr_profile_2.attr,
+ &dev_attr_profile_3.attr,
+ &dev_attr_profile_4.attr,
+ &dev_attr_profile_5.attr,
+ &dev_attr_profile_6.attr,
+ &dev_attr_profile_7.attr,
+ &dev_attr_profile_8.attr,
+ &dev_attr_profile_9.attr,
+ &dev_attr_profile_10.attr,
+ &dev_attr_profile_11.attr,
+ &dev_attr_profile_12.attr,
+ &dev_attr_profile_13.attr,
+ &dev_attr_profile_14.attr,
+ &dev_attr_profile_15.attr,
+ &dev_attr_profile_16.attr,
+ &dev_attr_profile_17.attr,
+ &dev_attr_profile_18.attr,
+ &dev_attr_profile_19.attr,
+ &dev_attr_profile_20.attr,
+ &dev_attr_profile_21.attr,
+ &dev_attr_profile_22.attr,
+ &dev_attr_profile_23.attr,
+ &dev_attr_profile_24.attr,
+ &dev_attr_profile_25.attr,
+ &dev_attr_profile_26.attr,
+ &dev_attr_profile_27.attr,
+ &dev_attr_profile_28.attr,
+ &dev_attr_profile_29.attr,
+ &dev_attr_profile_30.attr,
+ &dev_attr_profile_31.attr,
+ NULL
+};
+
+static struct attribute *fm_dev_schemes_attributes[] = {
+ &dev_attr_scheme_0.attr,
+ &dev_attr_scheme_1.attr,
+ &dev_attr_scheme_2.attr,
+ &dev_attr_scheme_3.attr,
+ &dev_attr_scheme_4.attr,
+ &dev_attr_scheme_5.attr,
+ &dev_attr_scheme_6.attr,
+ &dev_attr_scheme_7.attr,
+ &dev_attr_scheme_8.attr,
+ &dev_attr_scheme_9.attr,
+ &dev_attr_scheme_10.attr,
+ &dev_attr_scheme_11.attr,
+ &dev_attr_scheme_12.attr,
+ &dev_attr_scheme_13.attr,
+ &dev_attr_scheme_14.attr,
+ &dev_attr_scheme_15.attr,
+ &dev_attr_scheme_16.attr,
+ &dev_attr_scheme_17.attr,
+ &dev_attr_scheme_18.attr,
+ &dev_attr_scheme_19.attr,
+ &dev_attr_scheme_20.attr,
+ &dev_attr_scheme_21.attr,
+ &dev_attr_scheme_22.attr,
+ &dev_attr_scheme_23.attr,
+ &dev_attr_scheme_24.attr,
+ &dev_attr_scheme_25.attr,
+ &dev_attr_scheme_26.attr,
+ &dev_attr_scheme_27.attr,
+ &dev_attr_scheme_28.attr,
+ &dev_attr_scheme_29.attr,
+ &dev_attr_scheme_30.attr,
+ &dev_attr_scheme_31.attr,
+ NULL
+};
+
+static const struct attribute_group fm_dev_stats_attr_grp = {
+ .name = "statistics",
+ .attrs = fm_dev_stats_attributes
+};
+
+static const struct attribute_group fm_dev_tnums_dbg_attr_grp = {
+ .name = "tnums_dbg",
+ .attrs = fm_dev_tnums_dbg_attributes
+};
+
+static const struct attribute_group fm_dev_cls_plans_attr_grp = {
+ .name = "cls_plans",
+ .attrs = fm_dev_cls_plans_attributes
+};
+
+static const struct attribute_group fm_dev_schemes_attr_grp = {
+ .name = "schemes",
+ .attrs = fm_dev_schemes_attributes
+};
+
+static const struct attribute_group fm_dev_profiles_attr_grp = {
+ .name = "profiles",
+ .attrs = fm_dev_profiles_attributes
+};
+
+static ssize_t show_fm_regs(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long flags;
+ unsigned n = 0;
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
+#endif
+ if (attr == NULL || buf == NULL || dev == NULL)
+ return -EINVAL;
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+
+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
+ if (WARN_ON(p_wrp_fm_dev == NULL))
+ return -EINVAL;
+
+ local_irq_save(flags);
+
+ n = snprintf(buf, PAGE_SIZE, "FM driver registers dump.\n");
+
+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
+ return -EIO;
+ else
+ n = fm_dump_regs(p_wrp_fm_dev->h_Dev, buf, n);
+
+ local_irq_restore(flags);
+#else
+
+ local_irq_save(flags);
+ n = snprintf(buf, PAGE_SIZE,
+ "Debug level is too low to dump registers!!!\n");
+ local_irq_restore(flags);
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+ return n;
+}
+
+static ssize_t show_fm_kg_pe_regs(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long flags;
+ unsigned n = 0;
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
+#endif
+
+ if (attr == NULL || buf == NULL || dev == NULL)
+ return -EINVAL;
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+
+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
+ if (WARN_ON(p_wrp_fm_dev == NULL))
+ return -EINVAL;
+
+ local_irq_save(flags);
+
+ n = snprintf(buf, PAGE_SIZE,
+ "\n FM-KG Port Partition Config registers dump.\n");
+
+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
+ return -EIO;
+ else
+ n = fm_kg_pe_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
+
+ local_irq_restore(flags);
+#else
+
+ local_irq_save(flags);
+ n = snprintf(buf, PAGE_SIZE,
+ "Debug level is too low to dump registers!!!\n");
+ local_irq_restore(flags);
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+ return n;
+}
+
+static ssize_t show_fm_kg_regs(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long flags;
+ unsigned n = 0;
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
+#endif
+
+ if (attr == NULL || buf == NULL || dev == NULL)
+ return -EINVAL;
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+
+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
+ if (WARN_ON(p_wrp_fm_dev == NULL))
+ return -EINVAL;
+
+ local_irq_save(flags);
+
+ n = snprintf(buf, PAGE_SIZE, "FM-KG registers dump.\n");
+
+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
+ return -EIO;
+ else
+ n = fm_kg_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
+
+ local_irq_restore(flags);
+#else
+
+ local_irq_save(flags);
+ n = snprintf(buf, PAGE_SIZE,
+ "Debug level is too low to dump registers!!!\n");
+ local_irq_restore(flags);
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+ return n;
+}
+
+
+static ssize_t show_fm_fpm_regs(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long flags;
+ unsigned n = 0;
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
+#endif
+
+ if (attr == NULL || buf == NULL || dev == NULL)
+ return -EINVAL;
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+
+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
+ if (WARN_ON(p_wrp_fm_dev == NULL))
+ return -EINVAL;
+
+ local_irq_save(flags);
+
+ n = snprintf(buf, PAGE_SIZE, "FM-FPM registers dump.\n");
+
+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
+ return -EIO;
+ else
+ n = fm_fpm_dump_regs(p_wrp_fm_dev->h_Dev, buf, n);
+
+ local_irq_restore(flags);
+#else
+
+ local_irq_save(flags);
+ n = snprintf(buf, PAGE_SIZE,
+ "Debug level is too low to dump registers!!!\n");
+ local_irq_restore(flags);
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+ return n;
+}
+
+static ssize_t show_prs_regs(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long flags;
+ unsigned n = 0;
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
+#endif
+
+ if (attr == NULL || buf == NULL || dev == NULL)
+ return -EINVAL;
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
+ if (WARN_ON(p_wrp_fm_dev == NULL))
+ return -EINVAL;
+
+ local_irq_save(flags);
+ n = snprintf(buf, PAGE_SIZE, "FM Policer registers dump.\n");
+
+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
+ return -EIO;
+ else
+ n = fm_prs_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
+
+ local_irq_restore(flags);
+#else
+
+ local_irq_save(flags);
+ n = snprintf(buf, PAGE_SIZE,
+ "Debug level is too low to dump registers!!!\n");
+ local_irq_restore(flags);
+
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+ return n;
+}
+
+static ssize_t show_plcr_regs(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long flags;
+ unsigned n = 0;
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
+#endif
+
+ if (attr == NULL || buf == NULL || dev == NULL)
+ return -EINVAL;
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
+ if (WARN_ON(p_wrp_fm_dev == NULL))
+ return -EINVAL;
+
+ local_irq_save(flags);
+ n = snprintf(buf, PAGE_SIZE, "FM Policer registers dump.\n");
+
+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
+ return -EIO;
+ else
+ n = fm_plcr_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
+
+ local_irq_restore(flags);
+#else
+
+ local_irq_save(flags);
+ n = snprintf(buf, PAGE_SIZE,
+ "Debug level is too low to dump registers!!!\n");
+ local_irq_restore(flags);
+
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+ return n;
+}
+
+static DEVICE_ATTR(fm_regs, S_IRUGO, show_fm_regs, NULL);
+static DEVICE_ATTR(fm_fpm_regs, S_IRUGO, show_fm_fpm_regs, NULL);
+static DEVICE_ATTR(fm_kg_regs, S_IRUGO, show_fm_kg_regs, NULL);
+static DEVICE_ATTR(fm_kg_pe_regs, S_IRUGO, show_fm_kg_pe_regs, NULL);
+static DEVICE_ATTR(fm_plcr_regs, S_IRUGO, show_plcr_regs, NULL);
+static DEVICE_ATTR(fm_prs_regs, S_IRUGO, show_prs_regs, NULL);
+static DEVICE_ATTR(fm_muram_free_size, S_IRUGO, show_fm_muram_free_sz, NULL);
+static DEVICE_ATTR(fm_ctrl_code_ver, S_IRUGO, show_fm_ctrl_code_ver, NULL);
+
+int fm_sysfs_create(struct device *dev)
+{
+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
+
+ if (dev == NULL)
+ return -EIO;
+
+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
+
+ /* store to remove them when module is disabled */
+ p_wrp_fm_dev->dev_attr_regs = &dev_attr_fm_regs;
+ p_wrp_fm_dev->dev_attr_risc_load = &dev_attr_fm_risc_load_val;
+ p_wrp_fm_dev->dev_fm_fpm_attr_regs = &dev_attr_fm_fpm_regs;
+ p_wrp_fm_dev->dev_fm_kg_attr_regs = &dev_attr_fm_kg_regs;
+ p_wrp_fm_dev->dev_fm_kg_pe_attr_regs = &dev_attr_fm_kg_pe_regs;
+ p_wrp_fm_dev->dev_plcr_attr_regs = &dev_attr_fm_plcr_regs;
+ p_wrp_fm_dev->dev_prs_attr_regs = &dev_attr_fm_prs_regs;
+ p_wrp_fm_dev->dev_attr_muram_free_size = &dev_attr_fm_muram_free_size;
+ p_wrp_fm_dev->dev_attr_fm_ctrl_code_ver = &dev_attr_fm_ctrl_code_ver;
+
+ /* Create sysfs statistics group for FM module */
+ if (sysfs_create_group(&dev->kobj, &fm_dev_stats_attr_grp) != 0)
+ return -EIO;
+
+ if (sysfs_create_group(&dev->kobj, &fm_dev_schemes_attr_grp) != 0)
+ return -EIO;
+
+ if (sysfs_create_group(&dev->kobj, &fm_dev_profiles_attr_grp) != 0)
+ return -EIO;
+
+ if (sysfs_create_group(&dev->kobj, &fm_dev_tnums_dbg_attr_grp) != 0)
+ return -EIO;
+
+ if (sysfs_create_group(&dev->kobj, &fm_dev_cls_plans_attr_grp) != 0)
+ return -EIO;
+
+ /* Registers dump entry - in future will be moved to debugfs */
+ if (device_create_file(dev, &dev_attr_fm_regs) != 0)
+ return -EIO;
+
+ if (device_create_file(dev, &dev_attr_fm_risc_load_val) != 0)
+ return -EIO;
+
+ if (device_create_file(dev, &dev_attr_fm_fpm_regs) != 0)
+ return -EIO;
+
+ if (device_create_file(dev, &dev_attr_fm_kg_regs) != 0)
+ return -EIO;
+
+ if (device_create_file(dev, &dev_attr_fm_kg_pe_regs) != 0)
+ return -EIO;
+
+ if (device_create_file(dev, &dev_attr_fm_plcr_regs) != 0)
+ return -EIO;
+
+ if (device_create_file(dev, &dev_attr_fm_prs_regs) != 0)
+ return -EIO;
+
+ /* muram free size */
+ if (device_create_file(dev, &dev_attr_fm_muram_free_size) != 0)
+ return -EIO;
+
+ /* fm ctrl code version */
+ if (device_create_file(dev, &dev_attr_fm_ctrl_code_ver) != 0)
+ return -EIO;
+
+ return 0;
+}
+
+void fm_sysfs_destroy(struct device *dev)
+{
+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
+
+ if (WARN_ON(dev == NULL))
+ return;
+
+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
+ if (WARN_ON(p_wrp_fm_dev == NULL))
+ return;
+
+ sysfs_remove_group(&dev->kobj, &fm_dev_stats_attr_grp);
+ sysfs_remove_group(&dev->kobj, &fm_dev_schemes_attr_grp);
+ sysfs_remove_group(&dev->kobj, &fm_dev_profiles_attr_grp);
+ sysfs_remove_group(&dev->kobj, &fm_dev_cls_plans_attr_grp);
+ sysfs_remove_group(&dev->kobj, &fm_dev_tnums_dbg_attr_grp);
+ device_remove_file(dev, p_wrp_fm_dev->dev_attr_regs);
+ device_remove_file(dev, p_wrp_fm_dev->dev_fm_fpm_attr_regs);
+ device_remove_file(dev, p_wrp_fm_dev->dev_fm_kg_attr_regs);
+ device_remove_file(dev, p_wrp_fm_dev->dev_fm_kg_pe_attr_regs);
+ device_remove_file(dev, p_wrp_fm_dev->dev_plcr_attr_regs);
+ device_remove_file(dev, p_wrp_fm_dev->dev_prs_attr_regs);
+ device_remove_file(dev, p_wrp_fm_dev->dev_attr_muram_free_size);
+ device_remove_file(dev, p_wrp_fm_dev->dev_attr_fm_ctrl_code_ver);
+}
+
+int fm_dump_regs(void *h_fm, char *buf, int nn)
+{
+ t_Fm *p_Fm = (t_Fm *)h_fm;
+ uint8_t i = 0;
+ int n = nn;
+
+ FM_DMP_SUBTITLE(buf, n, "\n");
+
+ FM_DMP_TITLE(buf, n, p_Fm->p_FmDmaRegs, "FM-DMA Regs");
+
+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmsr);
+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmemsr);
+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmmr);
+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtr);
+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmhy);
+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmsetr);
+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtah);
+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtal);
+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtcid);
+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmra);
+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmrd);
+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmwcr);
+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmebcr);
+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmdcr);
+
+ FM_DMP_TITLE(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr, "fmdmplr");
+
+ for (i = 0; i < FM_MAX_NUM_OF_HW_PORT_IDS / 2 ; ++i)
+ FM_DMP_MEM_32(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr[i]);
+
+ FM_DMP_TITLE(buf, n, p_Fm->p_FmBmiRegs, "FM-BMI COMMON Regs");
+ FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_init);
+ FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_cfg1);
+ FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_cfg2);
+ FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_ievr);
+ FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_ier);
+
+ FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_arb, "fmbm_arb");
+ for (i = 0; i < 8 ; ++i)
+ FM_DMP_MEM_32(buf, n, &p_Fm->p_FmBmiRegs->fmbm_arb[i]);
+
+ FM_DMP_TITLE(buf, n, p_Fm->p_FmQmiRegs, "FM-QMI COMMON Regs");
+ FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_gc);
+ FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eie);
+ FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eien);
+ FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eif);
+ FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_ie);
+ FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_ien);
+ FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_if);
+ FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_gs);
+ FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_etfc);
+
+ return n;
+}
+
+int fm_dump_tnum_dbg(void *h_fm, int tn_s, int tn_e, char *buf, int nn)
+{
+ t_Fm *p_Fm = (t_Fm *)h_fm;
+ uint8_t i, j = 0;
+ int n = nn;
+
+ FM_DMP_TITLE(buf, n, NULL, "Tnums and Tnum dbg regs %d - %d",
+ tn_s, tn_e);
+
+ iowrite32be(tn_s << 24, &p_Fm->p_FmFpmRegs->fmfp_dra);
+
+ mb();
+
+ for (j = tn_s; j <= tn_e; j++) {
+ FM_DMP_LN(buf, n, "> fmfp_ts[%d]\n", j);
+ FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ts[j]);
+ FM_DMP_V32(buf, n, p_Fm->p_FmFpmRegs, fmfp_dra);
+ FM_DMP_LN(buf, n, "> fmfp_drd[0-3]\n");
+
+ for (i = 0; i < 4 ; ++i)
+ FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_drd[i]);
+
+ FM_DMP_LN(buf, n, "\n");
+
+ }
+
+ return n;
+}
+
+int fm_dump_cls_plan(void *h_fm_pcd, int cpn, char *buf, int nn)
+{
+ t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
+ int i = 0;
+ uint32_t tmp;
+ unsigned long i_flg;
+ int n = nn;
+ u_FmPcdKgIndirectAccessRegs *idac;
+ spinlock_t *p_lk;
+
+ p_lk = (spinlock_t *)p_pcd->p_FmPcdKg->h_HwSpinlock;
+ idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
+
+ spin_lock_irqsave(p_lk, i_flg);
+
+ /* Read ClsPlan Block Action Regs */
+ tmp = (uint32_t)(FM_KG_KGAR_GO |
+ FM_KG_KGAR_READ |
+ FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
+ DUMMY_PORT_ID |
+ ((uint32_t)cpn << FM_PCD_KG_KGAR_NUM_SHIFT) |
+ FM_PCD_KG_KGAR_WSEL_MASK);
+
+ if (fman_kg_write_ar_wait(p_pcd->p_FmPcdKg->p_FmPcdKgRegs, tmp)) {
+ FM_DMP_LN(buf, nn, "Keygen scheme access violation");
+ spin_unlock_irqrestore(p_lk, i_flg);
+ return nn;
+ }
+ FM_DMP_TITLE(buf, n, &idac->clsPlanRegs,
+ "ClsPlan %d Indirect Access Regs", cpn);
+
+ for (i = 0; i < 8; i++)
+ FM_DMP_MEM_32(buf, n, &idac->clsPlanRegs.kgcpe[i]);
+
+ spin_unlock_irqrestore(p_lk, i_flg);
+
+ return n;
+}
+
+int fm_profile_dump_regs(void *h_fm_pcd, int ppn, char *buf, int nn)
+{
+ t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
+ t_FmPcdPlcrProfileRegs *p_prof_regs;
+ t_FmPcdPlcrRegs *p_plcr_regs;
+ t_FmPcdPlcr *p_plcr;
+ uint32_t tmp;
+ unsigned long i_flg;
+ int n = nn;
+ int toc = 10;
+ spinlock_t *p_lk;
+
+ p_plcr = p_pcd->p_FmPcdPlcr;
+ p_prof_regs = &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs;
+ p_plcr_regs = p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
+
+ p_lk = (spinlock_t *)((t_FmPcdPlcr *)p_plcr)->h_HwSpinlock;
+
+ FM_DMP_SUBTITLE(buf, n, "\n");
+ FM_DMP_TITLE(buf, n, p_plcr_regs, "FM-PCD policer-profile regs");
+
+ tmp = (uint32_t)(FM_PCD_PLCR_PAR_GO |
+ FM_PCD_PLCR_PAR_R |
+ ((uint32_t)ppn << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
+ FM_PCD_PLCR_PAR_PWSEL_MASK);
+
+ spin_lock_irqsave(p_lk, i_flg);
+
+ iowrite32be(tmp, &p_plcr_regs->fmpl_par);
+
+ mb();
+
+ /* wait for the porfile regs to be present */
+ do {
+ --toc;
+ udelay(10);
+ if (!toc) {
+ /* looks like PLCR_PAR_GO refuses to clear */
+ spin_unlock_irqrestore(p_lk, i_flg);
+ FM_DMP_LN(buf, n, "Profile regs not accessible -");
+ FM_DMP_LN(buf, n, " check profile init process\n");
+ return n;
+ }
+ } while ((ioread32be(&p_plcr_regs->fmpl_par) & FM_PCD_PLCR_PAR_GO));
+
+ FM_DMP_TITLE(buf, n, p_prof_regs, "Profile %d regs", ppn);
+
+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_pemode);
+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_pegnia);
+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_peynia);
+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_pernia);
+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_pecir);
+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_pecbs);
+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepepir_eir);
+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepbs_ebs);
+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_pelts);
+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_pects);
+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepts_ets);
+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_pegpc);
+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_peypc);
+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_perpc);
+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_perypc);
+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_perrpc);
+
+ spin_unlock_irqrestore(p_lk, i_flg);
+
+ return n;
+}
+
+int fm_dump_scheme(void *h_fm_pcd, int scnum, char *buf, int nn)
+{
+ t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
+ uint32_t tmp_ar;
+ unsigned long i_flg;
+ int i, n = nn;
+ spinlock_t *p_lk;
+ u_FmPcdKgIndirectAccessRegs *idac;
+
+ idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
+ p_lk = (spinlock_t *)p_pcd->p_FmPcdKg->h_HwSpinlock;
+
+ spin_lock_irqsave(p_lk, i_flg);
+
+ tmp_ar = FmPcdKgBuildReadSchemeActionReg((uint8_t)scnum);
+ if (fman_kg_write_ar_wait(p_pcd->p_FmPcdKg->p_FmPcdKgRegs, tmp_ar)) {
+ FM_DMP_LN(buf, nn,
+ "Keygen scheme access violation or no such scheme");
+ spin_unlock_irqrestore(p_lk, i_flg);
+ return nn;
+ }
+
+ FM_DMP_TITLE(buf, n, &idac->schemeRegs,
+ "Scheme %d Indirect Access Regs", scnum);
+
+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_mode);
+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ekfc);
+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ekdv);
+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_bmch);
+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_bmcl);
+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_fqb);
+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_hc);
+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ppc);
+
+ FM_DMP_TITLE(buf, n, &idac->schemeRegs.kgse_gec, "kgse_gec");
+
+ for (i = 0; i < FM_KG_NUM_OF_GENERIC_REGS; i++)
+ FM_DMP_MEM_32(buf, n, &idac->schemeRegs.kgse_gec[i]);
+
+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_spc);
+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_dv0);
+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_dv1);
+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ccbs);
+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_mv);
+
+ FM_DMP_SUBTITLE(buf, n, "\n");
+
+ spin_unlock_irqrestore(p_lk, i_flg);
+
+ return n;
+}
+
+int fm_kg_pe_dump_regs(void *h_fm_pcd, char *buf, int nn)
+{
+ t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
+ int i = 0;
+ uint8_t prt_id = 0;
+ uint32_t tmp_ar;
+ unsigned long i_flg;
+ int n = nn;
+ u_FmPcdKgIndirectAccessRegs *idac;
+ t_FmPcdKg *p_kg;
+ spinlock_t *p_lk;
+
+ p_kg = p_pcd->p_FmPcdKg;
+ idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
+ p_lk = (spinlock_t *)p_kg->h_HwSpinlock;
+
+ spin_lock_irqsave(p_lk, i_flg);
+
+ FM_DMP_SUBTITLE(buf, n, "\n");
+
+ for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++) {
+ SW_PORT_INDX_TO_HW_PORT_ID(prt_id, i);
+
+ tmp_ar = FmPcdKgBuildReadPortSchemeBindActionReg(prt_id);
+
+ if (fman_kg_write_ar_wait(p_kg->p_FmPcdKgRegs, tmp_ar)) {
+ FM_DMP_LN(buf, nn, "Keygen scheme access violation");
+ spin_unlock_irqrestore(p_lk, i_flg);
+ return nn;
+ }
+ FM_DMP_TITLE(buf, n, &idac->portRegs, "Port %d regs", prt_id);
+ FM_DMP_V32(buf, n, &idac->portRegs, fmkg_pe_sp);
+ FM_DMP_V32(buf, n, &idac->portRegs, fmkg_pe_cpp);
+ }
+
+ FM_DMP_SUBTITLE(buf, n, "\n");
+
+ spin_unlock_irqrestore(p_lk, i_flg);
+
+ return n;
+}
+
+int fm_kg_dump_regs(void *h_fm_pcd, char *buf, int nn)
+{
+ t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
+ int n = nn;
+
+ FM_DMP_SUBTITLE(buf, n, "\n");
+ FM_DMP_TITLE(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs,
+ "FmPcdKgRegs Regs");
+
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gcr);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_eer);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_eeer);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_seer);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_seeer);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gsr);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_tpc);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_serc);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_fdor);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gdv0r);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gdv1r);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_feer);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_ar);
+
+ FM_DMP_SUBTITLE(buf, n, "\n");
+
+ return n;
+}
+
+
+int fm_fpm_dump_regs(void *h_fm, char *buf, int nn)
+{
+ t_Fm *p_fm = (t_Fm *)h_fm;
+ uint8_t i;
+ int n = nn;
+
+ FM_DMP_SUBTITLE(buf, n, "\n");
+
+ FM_DMP_TITLE(buf, n, p_fm->p_FmFpmRegs, "FM-FPM Regs");
+
+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tnc);
+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_prc);
+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_brkc);
+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_mxd);
+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_dist1);
+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_dist2);
+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_epi);
+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rie);
+
+ FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_fcev, "fmfp_fcev");
+ for (i = 0; i < 4; ++i)
+ FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_fcev[i]);
+
+ FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_cee, "fmfp_cee");
+ for (i = 0; i < 4; ++i)
+ FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_cee[i]);
+
+ FM_DMP_SUBTITLE(buf, n, "\n");
+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsc1);
+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsc2);
+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsp);
+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsf);
+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rcr);
+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_extc);
+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ext1);
+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ext2);
+
+ FM_DMP_SUBTITLE(buf, n, "\n");
+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_ip_rev_1);
+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_ip_rev_2);
+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rstc);
+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_cld);
+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_npi);
+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ee);
+
+ FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_cev, "fmfp_cev");
+ for (i = 0; i < 4; ++i)
+ FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_cev[i]);
+
+ FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_ps, "fmfp_ps");
+ for (i = 0; i < 64; ++i)
+ FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_ps[i]);
+
+ return n;
+}
+
+int fm_prs_dump_regs(void *h_fm_pcd, char *buf, int nn)
+{
+ t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
+ int n = nn;
+
+ FM_DMP_SUBTITLE(buf, n, "\n");
+
+ FM_DMP_TITLE(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs,
+ "FM-PCD parser regs");
+
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_rpclim);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_rpimac);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, pmeec);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pevr);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pever);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_perr);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_perer);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_ppsc);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pds);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l2rrs);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l3rrs);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l4rrs);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_srrs);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l2rres);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l3rres);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l4rres);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_srres);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_spcs);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_spscs);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_hxscs);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mrcs);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mwcs);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mrscs);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mwscs);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_fcscs);
+
+ return n;
+}
+
+int fm_plcr_dump_regs(void *h_fm_pcd, char *buf, int nn)
+{
+ t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
+ int i = 0;
+ int n = nn;
+
+ FM_DMP_SUBTITLE(buf, n, "\n");
+
+ FM_DMP_TITLE(buf, n,
+ p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,
+ "FM policer regs");
+
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_gcr);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_gsr);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_evr);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ier);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ifr);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eevr);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eier);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eifr);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rpcnt);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ypcnt);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rrpcnt);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rypcnt);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_tpcnt);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_flmcnt);
+
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_serc);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_upcr);
+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_dpmr);
+
+ FM_DMP_TITLE(buf, n,
+ &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr,
+ "fmpl_pmr");
+
+ for (i = 0; i < 63; ++i)
+ FM_DMP_MEM_32(buf, n,
+ &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr[i]);
+
+ return n;
+}
+
+int fm_get_counter(void *h_fm, e_FmCounters cnt_e, uint32_t *cnt_val)
+{
+ t_Fm *p_fm = (t_Fm *)h_fm;
+
+ /* When applicable (when there is an "enable counters" bit),
+ check that counters are enabled */
+
+ switch (cnt_e) {
+ case (e_FM_COUNTERS_DEQ_1):
+ case (e_FM_COUNTERS_DEQ_2):
+ fallthrough;
+ case (e_FM_COUNTERS_DEQ_3):
+ if (p_fm->p_FmStateStruct->revInfo.majorRev >= 6)
+ return -EINVAL; /* counter not available */
+
+ fallthrough;
+ case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
+ case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
+ case (e_FM_COUNTERS_DEQ_0):
+ case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
+ case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
+ case (e_FM_COUNTERS_DEQ_FROM_FD):
+ fallthrough;
+ case (e_FM_COUNTERS_DEQ_CONFIRM):
+ if (!(ioread32be(&p_fm->p_FmQmiRegs->fmqm_gc) &
+ QMI_CFG_EN_COUNTERS))
+ return -EINVAL; /* Requested counter not available */
+ break;
+ default:
+ break;
+ }
+
+ switch (cnt_e) {
+ case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
+ *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_etfc);
+ return 0;
+ case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
+ *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dtfc);
+ return 0;
+ case (e_FM_COUNTERS_DEQ_0):
+ *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc0);
+ return 0;
+ case (e_FM_COUNTERS_DEQ_1):
+ *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc1);
+ return 0;
+ case (e_FM_COUNTERS_DEQ_2):
+ *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc2);
+ return 0;
+ case (e_FM_COUNTERS_DEQ_3):
+ *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc3);
+ return 0;
+ case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
+ *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dfdc);
+ return 0;
+ case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
+ *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dfcc);
+ return 0;
+ case (e_FM_COUNTERS_DEQ_FROM_FD):
+ *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dffc);
+ return 0;
+ case (e_FM_COUNTERS_DEQ_CONFIRM):
+ *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dcc);
+ return 0;
+ }
+ /* should never get here */
+ return -EINVAL; /* counter not available */
+}
diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h
new file mode 100644
index 000000000000..3d56c94aecea
--- /dev/null
+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+
+#ifndef LNXWRP_SYSFS_FM_H_
+#define LNXWRP_SYSFS_FM_H_
+
+#include "lnxwrp_sysfs.h"
+
+int fm_sysfs_create(struct device *dev);
+void fm_sysfs_destroy(struct device *dev);
+int fm_dump_regs(void *h_dev, char *buf, int nn);
+int fm_fpm_dump_regs(void *h_dev, char *buf, int nn);
+int fm_kg_dump_regs(void *h_pcd, char *buf, int nn);
+int fm_kg_pe_dump_regs(void *h_pcd, char *buf, int nn);
+int fm_dump_scheme(void *h_pcd, int scnum, char *buf, int nn);
+int fm_dump_tnum_dbg(void *h_fm, int tn_s, int tn_e, char *buf, int nn);
+int fm_dump_cls_plan(void *h_pcd, int cpn, char *buf, int nn);
+int fm_plcr_dump_regs(void *h_pcd, char *buf, int nn);
+int fm_prs_dump_regs(void *h_pcd, char *buf, int nn);
+int fm_profile_dump_regs(void *h_pcd, int ppnum, char *buf, int nn);
+
+#define FM_DMP_PGSZ_ERR { \
+ snprintf(&buf[PAGE_SIZE - 80], 70, \
+ "\n Err: current sysfs buffer reached PAGE_SIZE\n");\
+ n = PAGE_SIZE - 2; \
+ }
+
+#define FM_DMP_LN(buf, n, ...) \
+ do { \
+ int k, m = n; \
+ m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
+ if (k < 0 || m > PAGE_SIZE - 90) \
+ FM_DMP_PGSZ_ERR \
+ n = m; \
+ } while (0)
+
+#define FM_DMP_TITLE(buf, n, addr, ...) \
+ do { \
+ int k, m = n; \
+ m += k = snprintf(&buf[m], PAGE_SIZE - m, "\n"); \
+ if (k < 0 || m > PAGE_SIZE - 90) \
+ FM_DMP_PGSZ_ERR \
+ m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
+ if (k < 0 || m > PAGE_SIZE - 90) \
+ FM_DMP_PGSZ_ERR \
+ if (addr) { \
+ phys_addr_t pa; \
+ pa = virt_to_phys(addr); \
+ m += k = \
+ snprintf(&buf[m], PAGE_SIZE - m, " (0x%lX)", \
+ (long unsigned int)(pa)); \
+ if (k < 0 || m > PAGE_SIZE - 90) \
+ FM_DMP_PGSZ_ERR \
+ } \
+ m += k = snprintf(&buf[m], PAGE_SIZE - m, \
+ "\n----------------------------------------\n\n"); \
+ if (k < 0 || m > PAGE_SIZE - 90) \
+ FM_DMP_PGSZ_ERR \
+ n = m; \
+ } while (0)
+
+#define FM_DMP_SUBTITLE(buf, n, ...) \
+ do { \
+ int k, m = n; \
+ m += k = snprintf(&buf[m], PAGE_SIZE - m, "------- "); \
+ if (k < 0 || m > PAGE_SIZE - 90) \
+ FM_DMP_PGSZ_ERR \
+ m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
+ if (k < 0 || m > PAGE_SIZE - 90) \
+ FM_DMP_PGSZ_ERR \
+ m += k = snprintf(&buf[m], PAGE_SIZE - m, "\n"); \
+ if (k < 0 || m > PAGE_SIZE - 90) \
+ FM_DMP_PGSZ_ERR \
+ n = m; \
+ } while (0)
+
+#define FM_DMP_MEM_32(buf, n, addr) \
+ { \
+ uint32_t val; \
+ phys_addr_t pa; \
+ int k, m = n; \
+ pa = virt_to_phys(addr); \
+ val = ioread32be((addr)); \
+ do { \
+ m += k = snprintf(&buf[m], \
+ PAGE_SIZE - m, "0x%010llX: 0x%08x\n", \
+ (unsigned long long)pa, val); \
+ if (k < 0 || m > PAGE_SIZE - 90) \
+ FM_DMP_PGSZ_ERR \
+ n += k; \
+ } while (0) ;\
+ }
+
+#define FM_DMP_V32(buf, n, st, phrase) \
+ do { \
+ int k, m = n; \
+ phys_addr_t pa = virt_to_phys(&((st)->phrase)); \
+ k = snprintf(&buf[m], PAGE_SIZE - m, \
+ "0x%010llX: 0x%08x%8s\t%s\n", (unsigned long long) pa, \
+ ioread32be((uint32_t *)&((st)->phrase)), "", #phrase); \
+ if (k < 0 || m > PAGE_SIZE - 90) \
+ FM_DMP_PGSZ_ERR \
+ n += k; \
+ } while (0)
+
+#endif /* LNXWRP_SYSFS_FM_H_ */
diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c
new file mode 100644
index 000000000000..db8e824c71e7
--- /dev/null
+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c
@@ -0,0 +1,1268 @@
+/*
+ * 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.
+ */
+
+#include "lnxwrp_sysfs.h"
+#include "lnxwrp_fm.h"
+#include "debug_ext.h"
+#include "lnxwrp_sysfs_fm_port.h"
+#include "lnxwrp_sysfs_fm.h"
+
+#include "../../sdk_fman/Peripherals/FM/Port/fm_port.h"
+#include "../../sdk_fman/Peripherals/FM/Port/fm_port_dsar.h"
+
+#if defined(__ERR_MODULE__)
+#undef __ERR_MODULE__
+#endif
+
+#include "../../sdk_fman/Peripherals/FM/fm.h"
+
+static const struct sysfs_stats_t portSysfsStats[] = {
+ /* RX/TX/OH common statistics */
+ {
+ .stat_name = "port_frame",
+ .stat_counter = e_FM_PORT_COUNTERS_FRAME,
+ },
+ {
+ .stat_name = "port_discard_frame",
+ .stat_counter = e_FM_PORT_COUNTERS_DISCARD_FRAME,
+ },
+ {
+ .stat_name = "port_dealloc_buf",
+ .stat_counter = e_FM_PORT_COUNTERS_DEALLOC_BUF,
+ },
+ {
+ .stat_name = "port_enq_total",
+ .stat_counter = e_FM_PORT_COUNTERS_ENQ_TOTAL,
+ },
+ /* TX/OH */
+ {
+ .stat_name = "port_length_err",
+ .stat_counter = e_FM_PORT_COUNTERS_LENGTH_ERR,
+ },
+ {
+ .stat_name = "port_unsupprted_format",
+ .stat_counter = e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT,
+ },
+ {
+ .stat_name = "port_deq_total",
+ .stat_counter = e_FM_PORT_COUNTERS_DEQ_TOTAL,
+ },
+ {
+ .stat_name = "port_deq_from_default",
+ .stat_counter = e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT,
+ },
+ {
+ .stat_name = "port_deq_confirm",
+ .stat_counter = e_FM_PORT_COUNTERS_DEQ_CONFIRM,
+ },
+ /* RX/OH */
+ {
+ .stat_name = "port_rx_bad_frame",
+ .stat_counter = e_FM_PORT_COUNTERS_RX_BAD_FRAME,
+ },
+ {
+ .stat_name = "port_rx_large_frame",
+ .stat_counter = e_FM_PORT_COUNTERS_RX_LARGE_FRAME,
+ },
+ {
+ .stat_name = "port_rx_out_of_buffers_discard",
+ .stat_counter = e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD,
+ },
+ {
+ .stat_name = "port_rx_filter_frame",
+ .stat_counter = e_FM_PORT_COUNTERS_RX_FILTER_FRAME,
+ },
+ /* TODO: Particular statistics for OH ports */
+ {}
+};
+
+static ssize_t show_fm_port_stats(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
+ t_LnxWrpFmDev *p_LnxWrpFmDev;
+ unsigned long flags;
+ int n = 0;
+ uint8_t counter = 0;
+
+ if (attr == NULL || buf == NULL || dev == NULL)
+ return -EINVAL;
+
+ p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
+ if (WARN_ON(p_LnxWrpFmPortDev == NULL))
+ return -EINVAL;
+
+ p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
+ if (WARN_ON(p_LnxWrpFmDev == NULL))
+ return -EINVAL;
+
+ if (!p_LnxWrpFmDev->active || !p_LnxWrpFmDev->h_Dev)
+ return -EIO;
+
+ if (!p_LnxWrpFmPortDev->h_Dev) {
+ n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
+ return n;
+ }
+
+ counter = fm_find_statistic_counter_by_name(
+ attr->attr.name,
+ portSysfsStats, NULL);
+
+ if (counter == e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR) {
+ uint32_t fmRev = 0;
+ fmRev = 0xffff &
+ ioread32(UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr +
+ 0x000c30c4));
+
+ if (fmRev == 0x0100) {
+ local_irq_save(flags);
+ n = snprintf(buf, PAGE_SIZE,
+ "counter not available for revision 1\n");
+ local_irq_restore(flags);
+ }
+ return n;
+ }
+
+ local_irq_save(flags);
+ n = snprintf(buf, PAGE_SIZE, "\t%s counter: %u\n",
+ p_LnxWrpFmPortDev->name,
+ FM_PORT_GetCounter(p_LnxWrpFmPortDev->h_Dev,
+ (e_FmPortCounters) counter));
+ local_irq_restore(flags);
+
+ return n;
+}
+
+/* FM PORT RX/TX/OH statistics */
+static DEVICE_ATTR(port_frame, S_IRUGO, show_fm_port_stats, NULL);
+static DEVICE_ATTR(port_discard_frame, S_IRUGO, show_fm_port_stats, NULL);
+static DEVICE_ATTR(port_dealloc_buf, S_IRUGO, show_fm_port_stats, NULL);
+static DEVICE_ATTR(port_enq_total, S_IRUGO, show_fm_port_stats, NULL);
+/* FM PORT TX/OH statistics */
+static DEVICE_ATTR(port_length_err, S_IRUGO, show_fm_port_stats, NULL);
+static DEVICE_ATTR(port_unsupprted_format, S_IRUGO, show_fm_port_stats, NULL);
+static DEVICE_ATTR(port_deq_total, S_IRUGO, show_fm_port_stats, NULL);
+static DEVICE_ATTR(port_deq_from_default, S_IRUGO, show_fm_port_stats, NULL);
+static DEVICE_ATTR(port_deq_confirm, S_IRUGO, show_fm_port_stats, NULL);
+/* FM PORT RX/OH statistics */
+static DEVICE_ATTR(port_rx_bad_frame, S_IRUGO, show_fm_port_stats, NULL);
+static DEVICE_ATTR(port_rx_large_frame, S_IRUGO, show_fm_port_stats, NULL);
+static DEVICE_ATTR(port_rx_out_of_buffers_discard, S_IRUGO,
+ show_fm_port_stats, NULL);
+static DEVICE_ATTR(port_rx_filter_frame, S_IRUGO, show_fm_port_stats, NULL);
+
+/* FM PORT TX statistics */
+static struct attribute *fm_tx_port_dev_stats_attributes[] = {
+ &dev_attr_port_frame.attr,
+ &dev_attr_port_discard_frame.attr,
+ &dev_attr_port_dealloc_buf.attr,
+ &dev_attr_port_enq_total.attr,
+ &dev_attr_port_length_err.attr,
+ &dev_attr_port_unsupprted_format.attr,
+ &dev_attr_port_deq_total.attr,
+ &dev_attr_port_deq_from_default.attr,
+ &dev_attr_port_deq_confirm.attr,
+ NULL
+};
+
+static const struct attribute_group fm_tx_port_dev_stats_attr_grp = {
+ .name = "statistics",
+ .attrs = fm_tx_port_dev_stats_attributes
+};
+
+/* FM PORT RX statistics */
+static struct attribute *fm_rx_port_dev_stats_attributes[] = {
+ &dev_attr_port_frame.attr,
+ &dev_attr_port_discard_frame.attr,
+ &dev_attr_port_dealloc_buf.attr,
+ &dev_attr_port_enq_total.attr,
+ &dev_attr_port_rx_bad_frame.attr,
+ &dev_attr_port_rx_large_frame.attr,
+ &dev_attr_port_rx_out_of_buffers_discard.attr,
+ &dev_attr_port_rx_filter_frame.attr,
+ NULL
+};
+
+static const struct attribute_group fm_rx_port_dev_stats_attr_grp = {
+ .name = "statistics",
+ .attrs = fm_rx_port_dev_stats_attributes
+};
+
+/* TODO: add particular OH ports statistics */
+static struct attribute *fm_oh_port_dev_stats_attributes[] = {
+ &dev_attr_port_frame.attr,
+ &dev_attr_port_discard_frame.attr,
+ &dev_attr_port_dealloc_buf.attr,
+ &dev_attr_port_enq_total.attr,
+ /*TX*/ &dev_attr_port_length_err.attr,
+ &dev_attr_port_unsupprted_format.attr,
+ &dev_attr_port_deq_total.attr,
+ &dev_attr_port_deq_from_default.attr,
+ &dev_attr_port_deq_confirm.attr,
+ /* &dev_attr_port_rx_bad_frame.attr, */
+ /* &dev_attr_port_rx_large_frame.attr, */
+ &dev_attr_port_rx_out_of_buffers_discard.attr,
+ /*&dev_attr_port_rx_filter_frame.attr, */
+ NULL
+};
+
+static const struct attribute_group fm_oh_port_dev_stats_attr_grp = {
+ .name = "statistics",
+ .attrs = fm_oh_port_dev_stats_attributes
+};
+
+static ssize_t show_fm_port_regs(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long flags;
+ unsigned n = 0;
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
+#endif
+ if (attr == NULL || buf == NULL || dev == NULL)
+ return -EINVAL;
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ p_LnxWrpFmPortDev =
+ (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
+
+
+ local_irq_save(flags);
+
+ if (!p_LnxWrpFmPortDev->h_Dev) {
+ n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
+ return n;
+ } else {
+ n = snprintf(buf, PAGE_SIZE,
+ "FM port driver registers dump.\n");
+ n = fm_port_dump_regs(p_LnxWrpFmPortDev->h_Dev, buf, n);
+ }
+
+ local_irq_restore(flags);
+
+ return n;
+#else
+
+ local_irq_save(flags);
+ n = snprintf(buf, PAGE_SIZE,
+ "Debug level is too low to dump registers!!!\n");
+ local_irq_restore(flags);
+
+ return n;
+#endif
+}
+static int fm_port_dsar_dump_mem(void *h_dev, char *buf, int nn)
+{
+ t_FmPort *p_FmPort;
+ t_Fm *p_Fm;
+ uint8_t hardwarePortId;
+ uint32_t *param_page;
+ t_ArCommonDesc *ArCommonDescPtr;
+ uint32_t *mem;
+ int i, n = nn;
+
+ p_FmPort = (t_FmPort *)h_dev;
+ hardwarePortId = p_FmPort->hardwarePortId;
+ p_Fm = (t_Fm *)p_FmPort->h_Fm;
+
+ if (!FM_PORT_IsInDsar(p_FmPort))
+ {
+ FM_DMP_LN(buf, n, "port %u is not a DSAR port\n",
+ hardwarePortId);
+ return n;
+ }
+ FM_DMP_LN(buf, n, "port %u DSAR mem\n", hardwarePortId);
+ FM_DMP_LN(buf, n, "========================\n");
+
+ /* do I need request_mem_region here? */
+ param_page = ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr), 4);
+ ArCommonDescPtr = (t_ArCommonDesc*)(ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(param_page), 300*4)); /* this should be changed*/
+ mem = (uint32_t*)ArCommonDescPtr;
+ for (i = 0; i < 300; i+=4)
+ FM_DMP_LN(buf, n, "%08x: %08x %08x %08x %08x\n", i*4, mem[i], mem[i + 1], mem[i + 2], mem[i + 3]);
+ iounmap(ArCommonDescPtr);
+ iounmap(param_page);
+ return n;
+}
+
+static int fm_port_dsar_dump_regs(void *h_dev, char *buf, int nn)
+{
+ t_FmPort *p_FmPort;
+ t_Fm *p_Fm;
+ uint8_t hardwarePortId;
+ uint32_t *param_page;
+ t_ArCommonDesc *ArCommonDescPtr;
+ int i, n = nn;
+
+ p_FmPort = (t_FmPort *)h_dev;
+ hardwarePortId = p_FmPort->hardwarePortId;
+ p_Fm = (t_Fm *)p_FmPort->h_Fm;
+
+ if (!FM_PORT_IsInDsar(p_FmPort))
+ {
+ FM_DMP_LN(buf, n, "port %u is not a DSAR port\n",
+ hardwarePortId);
+ return n;
+ }
+ FM_DMP_LN(buf, n, "port %u DSAR information\n", hardwarePortId);
+ FM_DMP_LN(buf, n, "========================\n");
+
+ /* do I need request_mem_region here? */
+ param_page = ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr), 4);
+ ArCommonDescPtr = (t_ArCommonDesc*)(ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(param_page), sizeof(t_ArCommonDesc))); /* this should be changed*/
+ FM_DMP_LN(buf, n, "Tx port: 0x%x\n", ArCommonDescPtr->arTxPort);
+ FM_DMP_LN(buf, n, "Active HPNIA: 0x%08x\n", ArCommonDescPtr->activeHPNIA);
+ FM_DMP_LN(buf, n, "Snmp port: 0x%x\n", ArCommonDescPtr->snmpPort);
+ FM_DMP_LN(buf, n, "MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", ArCommonDescPtr->macStationAddr[0],
+ ArCommonDescPtr->macStationAddr[1], ArCommonDescPtr->macStationAddr[2],
+ ArCommonDescPtr->macStationAddr[3], ArCommonDescPtr->macStationAddr[4],
+ ArCommonDescPtr->macStationAddr[5]);
+ FM_DMP_LN(buf, n, "filterControl: 0x%02x\n", ArCommonDescPtr->filterControl);
+ FM_DMP_LN(buf, n, "tcpControlPass: 0x%04x\n", ArCommonDescPtr->tcpControlPass);
+ FM_DMP_LN(buf, n, "ipProtocolTblSize: 0x%x\n", ArCommonDescPtr->ipProtocolTblSize);
+ FM_DMP_LN(buf, n, "udpPortTblSize: 0x%x\n", ArCommonDescPtr->udpPortTblSize);
+ FM_DMP_LN(buf, n, "tcpPortTblSize: 0x%x\n", ArCommonDescPtr->tcpPortTblSize);
+ if (ArCommonDescPtr->p_ArStats)
+ {
+ t_ArStatistics *arStatistics = (t_ArStatistics*)
+ ioremap(ioread32be(&ArCommonDescPtr->p_ArStats) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ sizeof (t_ArStatistics));
+ FM_DMP_LN(buf, n, "\nDSAR statistics\n");
+ FM_DMP_LN(buf, n, "DSAR_Discarded: 0x%x\n", arStatistics->dsarDiscarded);
+ FM_DMP_LN(buf, n, "DSAR_Err_Discarded: 0x%x\n", arStatistics->dsarErrDiscarded);
+ FM_DMP_LN(buf, n, "DSAR_Frag_Discarded: 0x%x\n", arStatistics->dsarFragDiscarded);
+ FM_DMP_LN(buf, n, "DSAR_Tunnel_Discarded: 0x%x\n", arStatistics->dsarTunnelDiscarded);
+ FM_DMP_LN(buf, n, "DSAR_ARP_Discarded: 0x%x\n", arStatistics->dsarArpDiscarded);
+ FM_DMP_LN(buf, n, "DSAR_IP_Discarded: 0x%x\n", arStatistics->dsarIpDiscarded);
+ FM_DMP_LN(buf, n, "DSAR_TCP_Discarded: 0x%x\n", arStatistics->dsarTcpDiscarded);
+ FM_DMP_LN(buf, n, "DSAR_UDP_Discarded: 0x%x\n", arStatistics->dsarUdpDiscarded);
+ FM_DMP_LN(buf, n, "DSAR_ICMPv6_Checksum_Err: 0x%x\n", arStatistics->dsarIcmpV6ChecksumErr);
+ FM_DMP_LN(buf, n, "DSAR_ICMPv6_Other_Type: 0x%x\n", arStatistics->dsarIcmpV6OtherType);
+ FM_DMP_LN(buf, n, "DSAR_ICMPv4_Other_Type: 0x%x\n", arStatistics->dsarIcmpV4OtherType);
+
+ iounmap(arStatistics);
+ }
+ if (ArCommonDescPtr->p_ArpDescriptor)
+ {
+ t_DsarArpDescriptor* ArpDescriptor = (t_DsarArpDescriptor*)
+ ioremap(ioread32be(&ArCommonDescPtr->p_ArpDescriptor) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ sizeof (t_DsarArpDescriptor));
+ FM_DMP_LN(buf, n, "\nARP\n");
+ FM_DMP_LN(buf, n, "===\n");
+ FM_DMP_LN(buf, n, "control bits 0x%04x\n", ArpDescriptor->control);
+ if (ArpDescriptor->numOfBindings)
+ {
+ char ip_str[100];
+ t_DsarArpBindingEntry* bindings = ioremap(
+ ioread32be(&ArpDescriptor->p_Bindings) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ ArpDescriptor->numOfBindings *
+ sizeof(t_DsarArpBindingEntry));
+ uint8_t* ip_addr = (uint8_t*)&bindings->ipv4Addr;
+ FM_DMP_LN(buf, n, " ip vlan id\n");
+ for (i = 0; i < ArpDescriptor->numOfBindings; i++)
+ {
+ n += snprintf(ip_str, 100, "%d.%d.%d.%d",
+ ip_addr[0], ip_addr[1],
+ ip_addr[2], ip_addr[3]);
+ FM_DMP_LN(buf, n, "%-15s 0x%x\n",
+ ip_str, bindings->vlanId);
+ }
+ iounmap(bindings);
+ }
+ if (ArpDescriptor->p_Statistics)
+ {
+ t_DsarArpStatistics* arpStats = ioremap(
+ ioread32be(&ArpDescriptor->p_Statistics) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ sizeof(t_DsarArpStatistics));
+ FM_DMP_LN(buf, n, "statistics\n");
+ FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", arpStats->invalCnt);
+ FM_DMP_LN(buf, n, "ECHO_CNT: 0x%x\n", arpStats->echoCnt);
+ FM_DMP_LN(buf, n, "CD_CNT: 0x%x\n", arpStats->cdCnt);
+ FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", arpStats->arCnt);
+ FM_DMP_LN(buf, n, "RATM_CNT: 0x%x\n", arpStats->ratmCnt);
+ FM_DMP_LN(buf, n, "UKOP_CNT: 0x%x\n", arpStats->ukopCnt);
+ FM_DMP_LN(buf, n, "NMTP_CNT: 0x%x\n", arpStats->nmtpCnt);
+ FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", arpStats->nmVlanCnt);
+ iounmap(arpStats);
+ }
+
+ iounmap(ArpDescriptor);
+ }
+ if (ArCommonDescPtr->p_IcmpV4Descriptor)
+ {
+ t_DsarIcmpV4Descriptor* ICMPV4Descriptor =
+ (t_DsarIcmpV4Descriptor*)ioremap(ioread32be(
+ &ArCommonDescPtr->p_IcmpV4Descriptor) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ sizeof (t_DsarIcmpV4Descriptor));
+ FM_DMP_LN(buf, n, "\nEcho ICMPv4\n");
+ FM_DMP_LN(buf, n, "===========\n");
+ FM_DMP_LN(buf, n, "control bits 0x%04x\n", ICMPV4Descriptor->control);
+ if (ICMPV4Descriptor->numOfBindings)
+ {
+ char ip_str[100];
+ t_DsarArpBindingEntry* bindings = ioremap(
+ ioread32be(&ICMPV4Descriptor->p_Bindings) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ ICMPV4Descriptor->numOfBindings *
+ sizeof(t_DsarArpBindingEntry));
+ uint8_t* ip_addr = (uint8_t*)&bindings->ipv4Addr;
+ FM_DMP_LN(buf, n, " ip vlan id\n");
+ for (i = 0; i < ICMPV4Descriptor->numOfBindings; i++)
+ {
+ n += snprintf(ip_str, 100, "%d.%d.%d.%d",
+ ip_addr[0], ip_addr[1],
+ ip_addr[2], ip_addr[3]);
+ FM_DMP_LN(buf, n, "%-15s 0x%x\n",
+ ip_str, bindings->vlanId);
+ }
+ iounmap(bindings);
+ }
+ if (ICMPV4Descriptor->p_Statistics)
+ {
+ t_DsarIcmpV4Statistics* icmpv4Stats = ioremap(
+ ioread32be(&ICMPV4Descriptor->p_Statistics) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ sizeof(t_DsarIcmpV4Statistics));
+ FM_DMP_LN(buf, n, "statistics\n");
+ FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", icmpv4Stats->invalCnt);
+ FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", icmpv4Stats->nmVlanCnt);
+ FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", icmpv4Stats->nmIpCnt);
+ FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", icmpv4Stats->arCnt);
+ FM_DMP_LN(buf, n, "CSERR_CNT: 0x%x\n", icmpv4Stats->cserrCnt);
+ iounmap(icmpv4Stats);
+ }
+ iounmap(ICMPV4Descriptor);
+ }
+ if (ArCommonDescPtr->p_NdDescriptor)
+ {
+ t_DsarNdDescriptor *NDDescriptor =
+ (t_DsarNdDescriptor*)ioremap(ioread32be(
+ &ArCommonDescPtr->p_NdDescriptor) + p_FmPort->
+ fmMuramPhysBaseAddr, sizeof (t_DsarNdDescriptor));
+ FM_DMP_LN(buf, n, "\nNDP\n");
+ FM_DMP_LN(buf, n, "===\n");
+ FM_DMP_LN(buf, n, "control bits 0x%04x\n", NDDescriptor->control);
+ FM_DMP_LN(buf, n, "solicited address 0x%08x\n", NDDescriptor->solicitedAddr);
+ if (NDDescriptor->numOfBindings)
+ {
+ char ip_str[100];
+ t_DsarIcmpV6BindingEntry* bindings = ioremap(
+ ioread32be(&NDDescriptor->p_Bindings) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ NDDescriptor->numOfBindings *
+ sizeof(t_DsarIcmpV6BindingEntry));
+ uint16_t* ip_addr = (uint16_t*)&bindings->ipv6Addr;
+ FM_DMP_LN(buf, n, " ip vlan id\n");
+ for (i = 0; i < NDDescriptor->numOfBindings; i++)
+ {
+ n += snprintf(ip_str, 100,
+ "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
+ ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3],
+ ip_addr[4], ip_addr[5], ip_addr[6], ip_addr[7]);
+ FM_DMP_LN(buf, n, "%s 0x%x\n", ip_str, bindings->vlanId);
+ }
+ iounmap(bindings);
+ }
+ if (NDDescriptor->p_Statistics)
+ {
+ t_NdStatistics* ndStats = ioremap(
+ ioread32be(&NDDescriptor->p_Statistics) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ sizeof(t_NdStatistics));
+ FM_DMP_LN(buf, n, "statistics\n");
+ FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", ndStats->invalCnt);
+ FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", ndStats->nmVlanCnt);
+ FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", ndStats->nmIpCnt);
+ FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", ndStats->arCnt);
+ FM_DMP_LN(buf, n, "USADVERT_CNT: 0x%x\n", ndStats->usadvertCnt);
+ FM_DMP_LN(buf, n, "NMMCAST_CNT: 0x%x\n", ndStats->nmmcastCnt);
+ FM_DMP_LN(buf, n, "NSLLA_CNT: 0x%x\n", ndStats->nsllaCnt);
+ iounmap(ndStats);
+ }
+ iounmap(NDDescriptor);
+ }
+ if (ArCommonDescPtr->p_IcmpV6Descriptor)
+ {
+ t_DsarIcmpV6Descriptor *ICMPV6Descriptor =
+ (t_DsarIcmpV6Descriptor*)ioremap(ioread32be(
+ &ArCommonDescPtr->p_IcmpV6Descriptor) + p_FmPort->
+ fmMuramPhysBaseAddr, sizeof (t_DsarIcmpV6Descriptor));
+ FM_DMP_LN(buf, n, "\nEcho ICMPv6\n");
+ FM_DMP_LN(buf, n, "===========\n");
+ FM_DMP_LN(buf, n, "control bits 0x%04x\n", ICMPV6Descriptor->control);
+ if (ICMPV6Descriptor->numOfBindings)
+ {
+ char ip_str[100];
+ t_DsarIcmpV6BindingEntry* bindings = ioremap(
+ ioread32be(&ICMPV6Descriptor->p_Bindings) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ ICMPV6Descriptor->numOfBindings *
+ sizeof(t_DsarIcmpV6BindingEntry));
+ uint16_t* ip_addr = (uint16_t*)&bindings->ipv6Addr;
+ FM_DMP_LN(buf, n, " ip vlan id\n");
+ for (i = 0; i < ICMPV6Descriptor->numOfBindings; i++)
+ {
+ n += snprintf(ip_str, 100,
+ "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
+ ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3],
+ ip_addr[4], ip_addr[5], ip_addr[6], ip_addr[7]);
+ FM_DMP_LN(buf, n, "%s 0x%x\n", ip_str, bindings->vlanId);
+ }
+ iounmap(bindings);
+ }
+ if (ICMPV6Descriptor->p_Statistics)
+ {
+ t_DsarIcmpV6Statistics* icmpv6Stats = ioremap(
+ ioread32be(&ICMPV6Descriptor->p_Statistics) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ sizeof(t_DsarIcmpV6Statistics));
+ FM_DMP_LN(buf, n, "statistics\n");
+ FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", icmpv6Stats->invalCnt);
+ FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", icmpv6Stats->nmVlanCnt);
+ FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", icmpv6Stats->nmIpCnt);
+ FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", icmpv6Stats->arCnt);
+ iounmap(icmpv6Stats);
+ }
+ iounmap(ICMPV6Descriptor);
+ }
+ if (ArCommonDescPtr->p_SnmpDescriptor)
+ {
+ t_DsarSnmpDescriptor *SnmpDescriptor =
+ (t_DsarSnmpDescriptor*)ioremap(ioread32be(
+ &ArCommonDescPtr->p_SnmpDescriptor) + p_FmPort->
+ fmMuramPhysBaseAddr, sizeof (t_DsarSnmpDescriptor));
+ FM_DMP_LN(buf, n, "\nSNMP\n");
+ FM_DMP_LN(buf, n, "===========\n");
+ FM_DMP_LN(buf, n, "control bits 0x%04x\n", SnmpDescriptor->control);
+ FM_DMP_LN(buf, n, "max message length 0x%04x\n", SnmpDescriptor->maxSnmpMsgLength);
+ if (SnmpDescriptor->numOfIpv4Addresses)
+ {
+ char ip_str[100];
+ t_DsarSnmpIpv4AddrTblEntry* addrs = ioremap(
+ ioread32be(&SnmpDescriptor->p_Ipv4AddrTbl) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ SnmpDescriptor->numOfIpv4Addresses *
+ sizeof(t_DsarSnmpIpv4AddrTblEntry));
+ uint8_t* ip_addr = (uint8_t*)&addrs->ipv4Addr;
+ FM_DMP_LN(buf, n, " ip vlan id\n");
+ for (i = 0; i < SnmpDescriptor->numOfIpv4Addresses; i++)
+ {
+ n += snprintf(ip_str, 100, "%d.%d.%d.%d",
+ ip_addr[0], ip_addr[1],
+ ip_addr[2], ip_addr[3]);
+ FM_DMP_LN(buf, n, "%-15s 0x%x\n", ip_str, addrs->vlanId);
+ }
+ iounmap(addrs);
+ }
+ if (SnmpDescriptor->p_Statistics)
+ {
+ t_DsarSnmpStatistics* snmpStats = ioremap(
+ ioread32be(&SnmpDescriptor->p_Statistics) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ sizeof(t_DsarSnmpStatistics));
+ FM_DMP_LN(buf, n, "statistics\n");
+ FM_DMP_LN(buf, n, "snmpErrCnt: 0x%x\n", snmpStats->snmpErrCnt);
+ FM_DMP_LN(buf, n, "snmpCommunityErrCnt: 0x%x\n", snmpStats->snmpCommunityErrCnt);
+ FM_DMP_LN(buf, n, "snmpTotalDiscardCnt: 0x%x\n", snmpStats->snmpTotalDiscardCnt);
+ FM_DMP_LN(buf, n, "snmpGetReqCnt: 0x%x\n", snmpStats->snmpGetReqCnt);
+ FM_DMP_LN(buf, n, "snmpGetNextReqCnt: 0x%x\n", snmpStats->snmpGetNextReqCnt);
+ iounmap(snmpStats);
+ }
+ iounmap(SnmpDescriptor);
+ }
+ iounmap(ArCommonDescPtr);
+ iounmap(param_page);
+ return n;
+}
+
+static ssize_t show_fm_port_dsar_mem(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long flags;
+ unsigned n = 0;
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
+#endif
+ if (attr == NULL || buf == NULL || dev == NULL)
+ return -EINVAL;
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ p_LnxWrpFmPortDev =
+ (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
+
+ local_irq_save(flags);
+
+ if (!p_LnxWrpFmPortDev->h_Dev) {
+ n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
+ return n;
+ } else {
+ n = snprintf(buf, PAGE_SIZE,
+ "FM port driver registers dump.\n");
+ n = fm_port_dsar_dump_mem(p_LnxWrpFmPortDev->h_Dev, buf, n);
+ }
+
+ local_irq_restore(flags);
+
+ return n;
+#else
+
+ local_irq_save(flags);
+ n = snprintf(buf, PAGE_SIZE,
+ "Debug level is too low to dump registers!!!\n");
+ local_irq_restore(flags);
+
+ return n;
+#endif
+}
+
+static ssize_t show_fm_port_dsar_regs(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long flags;
+ unsigned n = 0;
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
+#endif
+ if (attr == NULL || buf == NULL || dev == NULL)
+ return -EINVAL;
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ p_LnxWrpFmPortDev =
+ (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
+
+ local_irq_save(flags);
+
+ if (!p_LnxWrpFmPortDev->h_Dev) {
+ n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
+ return n;
+ } else {
+ n = snprintf(buf, PAGE_SIZE,
+ "FM port driver registers dump.\n");
+ n = fm_port_dsar_dump_regs(p_LnxWrpFmPortDev->h_Dev, buf, n);
+ }
+
+ local_irq_restore(flags);
+
+ return n;
+#else
+
+ local_irq_save(flags);
+ n = snprintf(buf, PAGE_SIZE,
+ "Debug level is too low to dump registers!!!\n");
+ local_irq_restore(flags);
+
+ return n;
+#endif
+}
+
+#if (DPAA_VERSION >= 11)
+static ssize_t show_fm_port_ipv4_options(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long flags;
+ unsigned n = 0;
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
+#endif
+
+ if (attr == NULL || buf == NULL || dev == NULL)
+ return -EINVAL;
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ p_LnxWrpFmPortDev =
+ (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
+
+ local_irq_save(flags);
+
+ if (!p_LnxWrpFmPortDev->h_Dev) {
+ n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
+ return n;
+ } else if (((t_FmPort *)p_LnxWrpFmPortDev->h_Dev)->p_ParamsPage
+ == NULL) {
+ n = snprintf(buf, PAGE_SIZE,
+ "\tPort: FMan-controller params page not set\n");
+ return n;
+ } else {
+ n = snprintf(buf, PAGE_SIZE,
+ "Counter for fragmented pkt with IP header options\n");
+ n = fm_port_dump_ipv4_opt(p_LnxWrpFmPortDev->h_Dev, buf, n);
+ }
+
+ local_irq_restore(flags);
+
+ return n;
+#else
+
+ local_irq_save(flags);
+ n = snprintf(buf, PAGE_SIZE,
+ "Debug level is too low to dump registers!!!\n");
+ local_irq_restore(flags);
+
+ return n;
+#endif
+}
+
+#endif
+
+static ssize_t show_fm_port_bmi_regs(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long flags;
+ unsigned n = 0;
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
+#endif
+
+ if (attr == NULL || buf == NULL || dev == NULL)
+ return -EINVAL;
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ p_LnxWrpFmPortDev =
+ (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
+
+ local_irq_save(flags);
+
+ if (!p_LnxWrpFmPortDev->h_Dev) {
+ n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
+ return n;
+ } else {
+ n = snprintf(buf, PAGE_SIZE,
+ "FM port driver registers dump.\n");
+ n = fm_port_dump_regs_bmi(p_LnxWrpFmPortDev->h_Dev, buf, n);
+ }
+
+ local_irq_restore(flags);
+
+ return n;
+#else
+
+ local_irq_save(flags);
+ n = snprintf(buf, PAGE_SIZE,
+ "Debug level is too low to dump registers!!!\n");
+ local_irq_restore(flags);
+
+ return n;
+#endif
+}
+
+static ssize_t show_fm_port_qmi_regs(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long flags;
+ unsigned n = 0;
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
+#endif
+
+ if (attr == NULL || buf == NULL || dev == NULL)
+ return -EINVAL;
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ p_LnxWrpFmPortDev =
+ (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
+
+ local_irq_save(flags);
+
+ if (!p_LnxWrpFmPortDev->h_Dev) {
+ n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
+ return n;
+ } else {
+ n = snprintf(buf, PAGE_SIZE,
+ "FM port driver registers dump.\n");
+ n = fm_port_dump_regs_qmi(p_LnxWrpFmPortDev->h_Dev, buf, n);
+ }
+
+ local_irq_restore(flags);
+
+ return n;
+#else
+
+ local_irq_save(flags);
+ n = snprintf(buf, PAGE_SIZE,
+ "Debug level is too low to dump registers!!!\n");
+ local_irq_restore(flags);
+
+ return n;
+#endif
+}
+
+static DEVICE_ATTR(fm_port_regs, S_IRUGO | S_IRUSR, show_fm_port_regs, NULL);
+static DEVICE_ATTR(fm_port_qmi_regs, S_IRUGO | S_IRUSR, show_fm_port_qmi_regs, NULL);
+static DEVICE_ATTR(fm_port_bmi_regs, S_IRUGO | S_IRUSR, show_fm_port_bmi_regs, NULL);
+#if (DPAA_VERSION >= 11)
+static DEVICE_ATTR(fm_port_ipv4_opt, S_IRUGO | S_IRUSR, show_fm_port_ipv4_options, NULL);
+#endif
+static DEVICE_ATTR(fm_port_dsar_regs, S_IRUGO | S_IRUSR, show_fm_port_dsar_regs, NULL);
+static DEVICE_ATTR(fm_port_dsar_mem, S_IRUGO | S_IRUSR, show_fm_port_dsar_mem, NULL);
+
+int fm_port_sysfs_create(struct device *dev)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
+
+ if (dev == NULL)
+ return -EINVAL;
+
+ p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
+ if (WARN_ON(p_LnxWrpFmPortDev == NULL))
+ return -EINVAL;
+
+ /* store to remove them when module is disabled */
+ p_LnxWrpFmPortDev->dev_attr_regs = &dev_attr_fm_port_regs;
+ p_LnxWrpFmPortDev->dev_attr_qmi_regs = &dev_attr_fm_port_qmi_regs;
+ p_LnxWrpFmPortDev->dev_attr_bmi_regs = &dev_attr_fm_port_bmi_regs;
+#if (DPAA_VERSION >= 11)
+ p_LnxWrpFmPortDev->dev_attr_ipv4_opt = &dev_attr_fm_port_ipv4_opt;
+#endif
+ p_LnxWrpFmPortDev->dev_attr_dsar_regs = &dev_attr_fm_port_dsar_regs;
+ p_LnxWrpFmPortDev->dev_attr_dsar_mem = &dev_attr_fm_port_dsar_mem;
+ /* Registers dump entry - in future will be moved to debugfs */
+ if (device_create_file(dev, &dev_attr_fm_port_regs) != 0)
+ return -EIO;
+ if (device_create_file(dev, &dev_attr_fm_port_qmi_regs) != 0)
+ return -EIO;
+ if (device_create_file(dev, &dev_attr_fm_port_bmi_regs) != 0)
+ return -EIO;
+#if (DPAA_VERSION >= 11)
+ if (device_create_file(dev, &dev_attr_fm_port_ipv4_opt) != 0)
+ return -EIO;
+#endif
+ if (device_create_file(dev, &dev_attr_fm_port_dsar_regs) != 0)
+ return -EIO;
+ if (device_create_file(dev, &dev_attr_fm_port_dsar_mem) != 0)
+ return -EIO;
+
+ /* FM Ports statistics */
+ switch (p_LnxWrpFmPortDev->settings.param.portType) {
+ case e_FM_PORT_TYPE_TX:
+ case e_FM_PORT_TYPE_TX_10G:
+ if (sysfs_create_group
+ (&dev->kobj, &fm_tx_port_dev_stats_attr_grp) != 0)
+ return -EIO;
+ break;
+ case e_FM_PORT_TYPE_RX:
+ case e_FM_PORT_TYPE_RX_10G:
+ if (sysfs_create_group
+ (&dev->kobj, &fm_rx_port_dev_stats_attr_grp) != 0)
+ return -EIO;
+ break;
+ case e_FM_PORT_TYPE_DUMMY:
+ case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
+ if (sysfs_create_group
+ (&dev->kobj, &fm_oh_port_dev_stats_attr_grp) != 0)
+ return -EIO;
+ break;
+ default:
+ WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
+ __func__);
+ return -EINVAL;
+ break;
+ };
+
+ return 0;
+}
+
+void fm_port_sysfs_destroy(struct device *dev)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = NULL;
+
+ /* this function has never been tested !!! */
+
+ if (WARN_ON(dev == NULL))
+ return;
+
+ p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
+ if (WARN_ON(p_LnxWrpFmPortDev == NULL))
+ return;
+
+ /* The name attribute will be freed also by these 2 functions? */
+ switch (p_LnxWrpFmPortDev->settings.param.portType) {
+ case e_FM_PORT_TYPE_TX:
+ case e_FM_PORT_TYPE_TX_10G:
+ sysfs_remove_group(&dev->kobj, &fm_tx_port_dev_stats_attr_grp);
+ break;
+ case e_FM_PORT_TYPE_RX:
+ case e_FM_PORT_TYPE_RX_10G:
+ sysfs_remove_group(&dev->kobj, &fm_rx_port_dev_stats_attr_grp);
+ break;
+ case e_FM_PORT_TYPE_DUMMY:
+ case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
+ sysfs_remove_group(&dev->kobj, &fm_oh_port_dev_stats_attr_grp);
+ break;
+ default:
+ WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
+ __func__);
+ break;
+ };
+
+ device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_regs);
+ device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_qmi_regs);
+ device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_bmi_regs);
+#if (DPAA_VERSION >= 11)
+ device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_ipv4_opt);
+#endif
+ device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_dsar_regs);
+ device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_dsar_mem);
+}
+
+
+int fm_port_dump_regs(void *h_dev, char *buf, int nn)
+{
+ t_FmPort *p_FmPort;
+ t_Fm *p_Fm;
+ uint8_t hardwarePortId;
+ int n = nn;
+
+ p_FmPort = (t_FmPort *)h_dev;
+ hardwarePortId = p_FmPort->hardwarePortId;
+ p_Fm = (t_Fm *)p_FmPort->h_Fm;
+
+ FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId - 1],
+ "fmbm_pp for port %u", hardwarePortId);
+ FM_DMP_MEM_32(buf, n,
+ &p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId - 1]);
+
+ FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId - 1],
+ "fmbm_pfs for port %u", hardwarePortId);
+ FM_DMP_MEM_32(buf, n,
+ &p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId - 1]);
+
+ FM_DMP_TITLE(buf, n,
+ &p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId - 1],
+ "fmbm_spliodn for port %u", hardwarePortId);
+ FM_DMP_MEM_32(buf, n,
+ &p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId - 1]);
+
+ FM_DMP_TITLE(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId],
+ "fmfp_psfor port %u", hardwarePortId);
+ FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId]);
+
+ FM_DMP_TITLE(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId / 2],
+ "fmdmplrfor port %u", hardwarePortId);
+ FM_DMP_MEM_32(buf, n,
+ &p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId / 2]);
+ return n;
+}
+
+#if (DPAA_VERSION >= 11)
+
+int fm_port_dump_ipv4_opt(void *h_dev, char *buf, int nn)
+{
+ t_FmPort *p_FmPort;
+ int n = nn;
+
+ p_FmPort = (t_FmPort *)h_dev;
+
+ FM_DMP_V32(buf, n, p_FmPort->p_ParamsPage, ipfOptionsCounter);
+
+ FM_DMP_SUBTITLE(buf, n, "\n");
+
+ return n;
+}
+#endif
+
+int fm_port_dump_regs_bmi(void *h_dev, char *buf, int nn)
+{
+ t_FmPort *p_FmPort;
+ u_FmPortBmiRegs *p_bmi;
+
+ char arr[20];
+ uint8_t flag;
+ int i = 0;
+ int n = nn;
+
+ p_FmPort = (t_FmPort *)h_dev;
+ p_bmi = p_FmPort->p_FmPortBmiRegs;
+
+ memset(arr, 0, sizeof(arr));
+ switch (p_FmPort->portType) {
+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ strcpy(arr, "OFFLINE-PARSING");
+ flag = 0;
+ break;
+ case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
+ strcpy(arr, "HOST-COMMAND");
+ flag = 0;
+ break;
+ case (e_FM_PORT_TYPE_RX):
+ strcpy(arr, "RX");
+ flag = 1;
+ break;
+ case (e_FM_PORT_TYPE_RX_10G):
+ strcpy(arr, "RX-10G");
+ flag = 1;
+ break;
+ case (e_FM_PORT_TYPE_TX):
+ strcpy(arr, "TX");
+ flag = 2;
+ break;
+ case (e_FM_PORT_TYPE_TX_10G):
+ strcpy(arr, "TX-10G");
+ flag = 2;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ FM_DMP_TITLE(buf, n, NULL,
+ "FMan-Port (%s #%d) registers:",
+ arr, p_FmPort->portId);
+
+ FM_DMP_TITLE(buf, n, p_bmi, "Bmi Port Regs");
+
+ switch (flag) {
+ case (0):
+ FM_DMP_SUBTITLE(buf, n, "\n");
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocfg);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ost);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oda);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oicp);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofdne);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofne);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofca);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofpne);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opso);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opp);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_occb);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oim);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofp);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofed);
+
+ FM_DMP_TITLE(buf, n,
+ &(p_bmi->ohPortBmiRegs.fmbm_oprai), "fmbm_oprai");
+ for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; ++i) {
+ FM_DMP_MEM_32(buf, n,
+ &(p_bmi->ohPortBmiRegs.fmbm_oprai[i]));
+ }
+ FM_DMP_SUBTITLE(buf, n, "\n");
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofqid);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oefqid);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofsdm);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofsem);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofene);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_orlmts);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_orlmt);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocmne);
+ {
+#ifndef FM_NO_OP_OBSERVED_POOLS
+ if (p_FmPort->fmRevInfo.majorRev == 4) {
+ FM_DMP_TITLE(buf, n,
+ &p_bmi->ohPortBmiRegs.fmbm_oebmpi,
+ "fmbm_oebmpi");
+
+ for (i = 0; i < FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS; ++i) {
+ FM_DMP_MEM_32(buf, n,
+ &(p_bmi->ohPortBmiRegs.fmbm_oebmpi[i]));
+ }
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocgm);
+ }
+#endif /* !FM_NO_OP_OBSERVED_POOLS */
+ }
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ostc);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofrc);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofdc);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofledc);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofufdc);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_offc);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofwdc);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofldec);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opc);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opcp);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_occn);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_otuc);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oduc);
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofuc);
+ FM_DMP_TITLE(buf, n, &(p_bmi->ohPortBmiRegs.fmbm_odcfg),
+ "fmbm_odcfg");
+ for (i = 0; i < 3; ++i) {
+ FM_DMP_MEM_32(buf, n,
+ &(p_bmi->ohPortBmiRegs.fmbm_odcfg[i]));
+ }
+ FM_DMP_SUBTITLE(buf, n, "\n");
+
+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ogpr);
+ break;
+ case (1):
+ FM_DMP_SUBTITLE(buf, n, "\n");
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rcfg);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rst);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rda);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfp);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_reth);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfed);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_ricp);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rebm);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfne);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfca);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfpne);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpso);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpp);
+ FM_DMP_TITLE(buf, n, &(p_bmi->rxPortBmiRegs.fmbm_rprai),
+ "fmbm_rprai");
+ for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; ++i) {
+ FM_DMP_MEM_32(buf, n,
+ &(p_bmi->rxPortBmiRegs.fmbm_rprai[i]));
+ }
+ FM_DMP_SUBTITLE(buf, n, "\n");
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfqid);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_refqid);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfsdm);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfsem);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfene);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rcmne);
+ FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_ebmpi,
+ "fmbm_ebmpi");
+ for (i = 0; i < FM_PORT_MAX_NUM_OF_EXT_POOLS; ++i) {
+ FM_DMP_MEM_32(buf, n,
+ &(p_bmi->rxPortBmiRegs.fmbm_ebmpi[i]));
+ }
+ FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_acnt,
+ "fmbm_acnt");
+ for (i = 0; i < FM_PORT_MAX_NUM_OF_EXT_POOLS; ++i) {
+ FM_DMP_MEM_32(buf, n,
+ &(p_bmi->rxPortBmiRegs.fmbm_acnt[i]));
+ }
+ FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_rcgm,
+ "fmbm_rcgm");
+ for (i = 0; i < FM_PORT_NUM_OF_CONGESTION_GRPS / 32; ++i) {
+ FM_DMP_MEM_32(buf, n,
+ &(p_bmi->rxPortBmiRegs.fmbm_rcgm[i]));
+ }
+
+ FM_DMP_SUBTITLE(buf, n, "\n");
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rmpd);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rstc);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfrc);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfbc);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rlfc);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rffc);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfcd);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfldec);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rodc);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpc);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpcp);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rccn);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rtuc);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rrquc);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rduc);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfuc);
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpac);
+ FM_DMP_TITLE(buf, n, &(p_bmi->rxPortBmiRegs.fmbm_rdcfg),
+ "fmbm_rdcfg");
+ for (i = 0; i < 3; ++i) {
+ FM_DMP_MEM_32(buf, n,
+ &(p_bmi->rxPortBmiRegs.fmbm_rdcfg[i]));
+ }
+ FM_DMP_SUBTITLE(buf, n, "\n");
+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rgpr);
+ break;
+ case (2):
+ FM_DMP_SUBTITLE(buf, n, "\n");
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcfg);
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tst);
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tda);
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfp);
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfed);
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ticp);
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfdne);
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfca);
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcfqid);
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfeqid);
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfene);
+#if (DPAA_VERSION >= 11)
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfne);
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcmne);
+#endif /* (DPAA_VERSION >= 11) */
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_trlmts);
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_trlmt);
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tstc);
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfrc);
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfdc);
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfledc);
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfufdc);
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tpc);
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tpcp);
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tccn);
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ttuc);
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ttcquc);
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tduc);
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfuc);
+ FM_DMP_TITLE(buf, n, &(p_bmi->txPortBmiRegs.fmbm_tdcfg),
+ "fmbm_tdcfg");
+ for (i = 0; i < 3 ; ++i) {
+ FM_DMP_MEM_32(buf, n,
+ &(p_bmi->txPortBmiRegs.fmbm_tdcfg[i]));
+ }
+ FM_DMP_SUBTITLE(buf, n, "\n");
+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tgpr);
+ break;
+ }
+
+ FM_DMP_SUBTITLE(buf, n, "\n");
+
+ return n;
+}
+
+int fm_port_dump_regs_qmi(void *h_dev, char *buf, int nn)
+{
+ t_FmPort *p_FmPort;
+ int n = nn;
+
+ p_FmPort = (t_FmPort *)h_dev;
+
+ FM_DMP_TITLE(buf, n, p_FmPort->p_FmPortQmiRegs, "Qmi Port Regs");
+
+ FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnc);
+ FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pns);
+ FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnts);
+ FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnen);
+ FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnetfc);
+ FM_DMP_V32(buf, n,
+ &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndn);
+ FM_DMP_V32(buf, n,
+ &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndc);
+ FM_DMP_V32(buf, n,
+ &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndtfc);
+ FM_DMP_V32(buf, n,
+ &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndfdc);
+ FM_DMP_V32(buf, n,
+ &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndcc);
+
+ FM_DMP_SUBTITLE(buf, n, "\n");
+
+ return n;
+}
+
diff --git a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h
new file mode 100644
index 000000000000..1e7636f47fc4
--- /dev/null
+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h
@@ -0,0 +1,56 @@
+/*
+ * 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_sysfs_fm_port.h
+
+ @Description FM port sysfs functions.
+
+*/
+
+#ifndef LNXWRP_SYSFS_FM_PORT_H_
+#define LNXWRP_SYSFS_FM_PORT_H_
+
+#include "lnxwrp_sysfs.h"
+
+int fm_port_sysfs_create(struct device *dev);
+void fm_port_sysfs_destroy(struct device *dev);
+
+int fm_port_dump_regs(void *h_dev, char *buf, int n);
+int fm_port_dump_regs_bmi(void *h_dev, char *buf, int n);
+int fm_port_dump_regs_qmi(void *h_dev, char *buf, int n);
+
+#if (DPAA_VERSION >= 11)
+int fm_port_dump_ipv4_opt(void *h_dev, char *buf, int n);
+#endif
+
+#endif /* LNXWRP_SYSFS_FM_PORT_H_ */