summaryrefslogtreecommitdiff
path: root/drivers/staging/fsl_dpa_offload
diff options
context:
space:
mode:
authorMarian Chereji <marian.chereji@freescale.com>2013-04-19 14:18:07 (GMT)
committerFleming Andrew-AFLEMING <AFLEMING@freescale.com>2013-04-30 16:00:05 (GMT)
commitb50c338b5ee3529e92cc9bd76b48e2a0bdf84b13 (patch)
treedb35142eaaa658a1ba80b640673977a956caf449 /drivers/staging/fsl_dpa_offload
parentbd89c40ffa9cc51449eb5beac6c515046d94ac75 (diff)
downloadlinux-fsl-qoriq-b50c338b5ee3529e92cc9bd76b48e2a0bdf84b13.tar.xz
dpa_offload: Add packet classification component wrapper
The wrapper component allows the packet classification offloading driver's API to be accessible from user space via ioctl sys calls. Signed-off-by: Marian Chereji <marian.chereji@freescale.com> Signed-off-by: Radu Bulie <radu.bulie@freescale.com> Change-Id: I33110048b995205c7f9ef0f40753f9060789dd18 Reviewed-on: http://git.am.freescale.net:8181/2234 Reviewed-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com> Tested-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com>
Diffstat (limited to 'drivers/staging/fsl_dpa_offload')
-rw-r--r--drivers/staging/fsl_dpa_offload/dpa_classifier_ioctl.h848
-rw-r--r--drivers/staging/fsl_dpa_offload/dpa_offload_module.c102
-rw-r--r--drivers/staging/fsl_dpa_offload/dpa_offload_module.h46
-rw-r--r--drivers/staging/fsl_dpa_offload/wrp_dpa_classifier.c3123
-rw-r--r--drivers/staging/fsl_dpa_offload/wrp_dpa_classifier.h86
5 files changed, 4205 insertions, 0 deletions
diff --git a/drivers/staging/fsl_dpa_offload/dpa_classifier_ioctl.h b/drivers/staging/fsl_dpa_offload/dpa_classifier_ioctl.h
new file mode 100644
index 0000000..4aab2d7
--- /dev/null
+++ b/drivers/staging/fsl_dpa_offload/dpa_classifier_ioctl.h
@@ -0,0 +1,848 @@
+
+/* 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.
+ */
+
+/*
+ * DPA Classifier Wrapper Application Programming Interface
+ */
+
+#ifndef __DPA_CLASSIFIER_IOCTL_H
+#define __DPA_CLASSIFIER_IOCTL_H
+
+
+/* Other includes */
+#include "linux/ioctl.h"
+#include <linux/compat.h>
+
+
+#define DPA_CLS_IOC_MAGIC 0xbe
+
+
+struct ioc_dpa_cls_tbl_params {
+ struct dpa_cls_tbl_params table_params;
+ int td;
+};
+
+struct ioc_dpa_cls_tbl_miss_action {
+ int td;
+ struct dpa_cls_tbl_action miss_action;
+};
+
+struct ioc_dpa_cls_tbl_entry_params {
+ int td;
+ struct dpa_offload_lookup_key key;
+ struct dpa_cls_tbl_action action;
+ int priority;
+ int entry_id;
+};
+
+struct ioc_dpa_cls_tbl_entry_mod_by_key {
+ int td;
+ struct dpa_offload_lookup_key key;
+ struct dpa_cls_tbl_entry_mod_params mod_params;
+};
+
+struct ioc_dpa_cls_tbl_entry_mod_by_ref {
+ int td;
+ int entry_id;
+ struct dpa_cls_tbl_entry_mod_params mod_params;
+};
+
+struct ioc_dpa_cls_tbl_entry_by_key {
+ int td;
+ struct dpa_offload_lookup_key key;
+};
+
+struct ioc_dpa_cls_tbl_entry_by_ref {
+ int td;
+ int entry_id;
+};
+
+struct ioc_dpa_cls_tbl_lookup_by_key {
+ int td;
+ struct dpa_offload_lookup_key key;
+ struct dpa_cls_tbl_action action;
+};
+
+struct ioc_dpa_cls_tbl_lookup_by_ref {
+ int td;
+ int entry_id;
+ struct dpa_cls_tbl_action action;
+};
+
+struct ioc_dpa_cls_tbl_entry_stats_by_key {
+ int td;
+ struct dpa_offload_lookup_key key;
+ struct dpa_cls_tbl_entry_stats stats;
+};
+
+struct ioc_dpa_cls_tbl_entry_stats_by_ref {
+ int td;
+ int entry_id;
+ struct dpa_cls_tbl_entry_stats stats;
+};
+
+struct ioc_dpa_cls_hm_remove_params {
+ struct dpa_cls_hm_remove_params rm_params;
+ int next_hmd;
+ int hmd;
+ struct dpa_cls_hm_remove_resources res;
+ bool chain_head;
+ int modify_flags;
+};
+
+struct ioc_dpa_cls_hm_insert_params {
+ struct dpa_cls_hm_insert_params ins_params;
+ int next_hmd;
+ int hmd;
+ struct dpa_cls_hm_insert_resources res;
+ bool chain_head;
+ int modify_flags;
+};
+
+struct ioc_dpa_cls_hm_vlan_params {
+ struct dpa_cls_hm_vlan_params vlan_params;
+ int next_hmd;
+ int hmd;
+ struct dpa_cls_hm_vlan_resources res;
+ bool chain_head;
+ int modify_flags;
+};
+
+struct ioc_dpa_cls_hm_nat_params {
+ struct dpa_cls_hm_nat_params nat_params;
+ int next_hmd;
+ int hmd;
+ struct dpa_cls_hm_nat_resources res;
+ bool chain_head;
+ int modify_flags;
+};
+
+struct ioc_dpa_cls_hm_update_params {
+ struct dpa_cls_hm_update_params update_params;
+ int next_hmd;
+ int hmd;
+ struct dpa_cls_hm_update_resources res;
+ bool chain_head;
+ int modify_flags;
+};
+
+struct ioc_dpa_cls_hm_fwd_params {
+ struct dpa_cls_hm_fwd_params fwd_params;
+ int next_hmd;
+ int hmd;
+ struct dpa_cls_hm_fwd_resources res;
+ bool chain_head;
+ int modify_flags;
+};
+
+struct ioc_dpa_cls_hm_mpls_params {
+ struct dpa_cls_hm_mpls_params mpls_params;
+ int next_hmd;
+ int hmd;
+ struct dpa_cls_hm_mpls_resources res;
+ bool chain_head;
+ int modify_flags;
+};
+
+struct ioc_dpa_cls_mcast_group_params {
+ struct dpa_cls_mcast_group_params mcast_grp_params;
+ int grpd;
+};
+
+struct ioc_dpa_cls_mcast_import_params {
+ void *group;
+ int grpd;
+};
+
+struct ioc_dpa_cls_mcast_member_params {
+ int grpd;
+ struct dpa_cls_tbl_enq_action_desc member_params;
+ int md;
+};
+
+struct ioc_dpa_cls_mcast_remove_params {
+ int grpd;
+ int md;
+};
+
+
+#ifdef CONFIG_COMPAT
+
+struct dpa_cls_compat_tbl_params {
+ compat_uptr_t fm_pcd;
+ compat_uptr_t cc_node;
+ compat_uptr_t distribution;
+ compat_uptr_t classification;
+ enum dpa_cls_tbl_type type;
+ enum dpa_cls_tbl_entry_mgmt entry_mgmt;
+ union {
+ struct dpa_cls_tbl_hash_params hash_params;
+ struct dpa_cls_tbl_indexed_params indexed_params;
+ struct dpa_cls_tbl_exact_match_params exact_match_params;
+ };
+ unsigned int prefilled_entries;
+};
+
+struct compat_ioc_dpa_cls_tbl_params {
+ struct dpa_cls_compat_tbl_params table_params;
+ int td;
+};
+
+struct dpa_cls_compat_tbl_enq_action_desc {
+ bool override_fqid;
+ uint32_t new_fqid;
+ compat_uptr_t policer_params;
+ int hmd;
+ uint8_t new_rel_vsp_id;
+};
+
+struct dpa_cls_compat_tbl_action {
+ enum dpa_cls_tbl_action_type type;
+ bool enable_statistics;
+ union {
+ struct dpa_cls_compat_tbl_enq_action_desc enq_params;
+ struct dpa_cls_tbl_next_table_desc next_table_params;
+ struct dpa_cls_tbl_mcast_group_desc mcast_params;
+ };
+};
+
+struct compat_ioc_dpa_cls_tbl_miss_action {
+ int td;
+ struct dpa_cls_compat_tbl_action miss_action;
+};
+
+struct compat_ioc_dpa_offld_lookup_key {
+ compat_uptr_t byte;
+ compat_uptr_t mask;
+ uint8_t size;
+};
+
+struct compat_ioc_dpa_cls_tbl_entry_by_key {
+ int td;
+ struct compat_ioc_dpa_offld_lookup_key key;
+};
+
+struct compat_ioc_dpa_cls_tbl_entry_stats_by_key {
+ int td;
+ struct compat_ioc_dpa_offld_lookup_key key;
+ struct dpa_cls_tbl_entry_stats stats;
+};
+
+struct compat_ioc_dpa_cls_tbl_entry_params {
+ int td;
+ struct compat_ioc_dpa_offld_lookup_key key;
+ struct dpa_cls_compat_tbl_action action;
+ int priority;
+ int entry_id;
+};
+
+struct dpa_cls_compat_tbl_entry_mod_params {
+ enum dpa_cls_tbl_modify_type type;
+ compat_uptr_t key;
+ compat_uptr_t action;
+};
+
+struct compat_ioc_dpa_cls_tbl_entry_mod_by_key {
+ int td;
+ struct compat_ioc_dpa_offld_lookup_key key;
+ struct dpa_cls_compat_tbl_entry_mod_params mod_params;
+};
+
+struct compat_ioc_dpa_cls_tbl_entry_mod_by_ref {
+ int td;
+ int entry_id;
+ struct dpa_cls_compat_tbl_entry_mod_params mod_params;
+};
+
+struct compat_ioc_dpa_cls_tbl_lookup_by_key {
+ int td;
+ struct compat_ioc_dpa_offld_lookup_key key;
+ struct dpa_cls_compat_tbl_action action;
+};
+
+struct compat_ioc_dpa_cls_tbl_lookup_by_ref {
+ int td;
+ int entry_id;
+ struct dpa_cls_compat_tbl_action action;
+};
+
+struct dpa_cls_compat_hm_remove_resources {
+ compat_uptr_t remove_node;
+};
+
+struct dpa_cls_compat_hm_remove_params {
+ enum dpa_cls_hm_remove_type type;
+ struct dpa_cls_hm_custom_rm_params custom;
+ compat_uptr_t fm_pcd;
+};
+
+struct compat_ioc_dpa_cls_hm_remove_params {
+ struct dpa_cls_compat_hm_remove_params rm_params;
+ int next_hmd;
+ int hmd;
+ struct dpa_cls_compat_hm_remove_resources res;
+ bool chain_head;
+ int modify_flags;
+};
+
+struct dpa_cls_compat_hm_insert_resources {
+ compat_uptr_t insert_node;
+};
+
+struct dpa_cls_compat_hm_custom_ins_params {
+ uint8_t offset;
+ uint8_t size;
+ compat_uptr_t data;
+};
+
+struct dpa_cls_compat_hm_insert_params {
+ enum dpa_cls_hm_insert_type type;
+ union {
+ struct dpa_cls_hm_eth_ins_params eth;
+ struct dpa_cls_hm_pppoe_ins_params pppoe;
+ uint16_t ppp_pid;
+ struct dpa_cls_compat_hm_custom_ins_params custom;
+ };
+ compat_uptr_t fm_pcd;
+};
+
+struct compat_ioc_dpa_cls_hm_insert_params {
+ struct dpa_cls_compat_hm_insert_params ins_params;
+ int next_hmd;
+ int hmd;
+ struct dpa_cls_compat_hm_insert_resources res;
+ bool chain_head;
+ int modify_flags;
+};
+
+struct dpa_cls_compat_hm_vlan_params {
+ enum dpa_cls_hm_vlan_type type;
+ union {
+ struct dpa_cls_hm_ingress_vlan_params ingress;
+ struct dpa_cls_hm_egress_vlan_params egress;
+ };
+ compat_uptr_t fm_pcd;
+};
+
+struct dpa_cls_compat_hm_vlan_resources {
+ compat_uptr_t vlan_node;
+};
+
+struct compat_ioc_dpa_cls_hm_vlan_params {
+ struct dpa_cls_compat_hm_vlan_params vlan_params;
+ int next_hmd;
+ int hmd;
+ struct dpa_cls_compat_hm_vlan_resources res;
+ bool chain_head;
+ int modify_flags;
+};
+
+struct compat_ipv4_header {
+ struct iphdr header;
+ compat_uptr_t options;
+ unsigned int options_size;
+};
+
+struct dpa_cls_compat_hm_nat_pt_params {
+ enum dpa_cls_hm_nat_pt_type type;
+
+ union {
+ struct compat_ipv4_header ipv4;
+ struct ipv6_header ipv6;
+ } new_header;
+};
+
+struct dpa_cls_compat_hm_nat_params {
+ int flags;
+ enum dpa_cls_hm_nat_proto proto;
+ enum dpa_cls_hm_nat_type type;
+ union {
+ struct dpa_cls_hm_traditional_nat_params nat;
+ struct dpa_cls_compat_hm_nat_pt_params nat_pt;
+ };
+ uint16_t sport;
+ uint16_t dport;
+ compat_uptr_t fm_pcd;
+};
+
+struct dpa_cls_compat_hm_nat_resources {
+ compat_uptr_t l3_update_node;
+ compat_uptr_t l4_update_node;
+};
+
+struct compat_ioc_dpa_cls_hm_nat_params {
+ struct dpa_cls_compat_hm_nat_params nat_params;
+ int next_hmd;
+ int hmd;
+ struct dpa_cls_compat_hm_nat_resources res;
+ bool chain_head;
+ int modify_flags;
+};
+
+struct dpa_cls_compat_hm_update_params {
+ int op_flags;
+ union {
+ struct compat_ipv4_header new_ipv4_hdr;
+ struct ipv6_header new_ipv6_hdr;
+ } replace;
+ union {
+ struct dpa_cls_hm_l3_update_params l3;
+ struct dpa_cls_hm_l4_update_params l4;
+ } update;
+ struct dpa_cls_hm_ip_frag_params ip_frag_params;
+ compat_uptr_t fm_pcd;
+};
+
+struct dpa_cls_compat_hm_update_resources {
+ compat_uptr_t update_node;
+ compat_uptr_t ip_frag_node;
+
+};
+
+struct compat_ioc_dpa_cls_hm_update_params {
+ struct dpa_cls_compat_hm_update_params update_params;
+ int next_hmd;
+ int hmd;
+ struct dpa_cls_compat_hm_update_resources res;
+ bool chain_head;
+ int modify_flags;
+};
+
+struct dpa_cls_compat_hm_fwd_params {
+ enum dpa_cls_hm_out_if_type out_if_type;
+ union {
+ struct dpa_cls_hm_fwd_l2_param eth;
+ struct dpa_cls_hm_fwd_pppoe_param pppoe;
+ struct dpa_cls_hm_fwd_ppp_param ppp;
+ };
+ struct dpa_cls_hm_ip_frag_params ip_frag_params;
+ compat_uptr_t fm_pcd;
+};
+
+struct dpa_cls_compat_hm_fwd_resources {
+ compat_uptr_t fwd_node;
+ compat_uptr_t pppoe_node;
+ compat_uptr_t ip_frag_node;
+};
+
+struct compat_ioc_dpa_cls_hm_fwd_params {
+ struct dpa_cls_compat_hm_fwd_params fwd_params;
+ int next_hmd;
+ int hmd;
+ struct dpa_cls_compat_hm_fwd_resources res;
+ bool chain_head;
+ int modify_flags;
+};
+
+struct dpa_cls_compat_hm_mpls_params {
+ enum dpa_cls_hm_mpls_type type;
+ struct mpls_header mpls_hdr[DPA_CLS_HM_MAX_MPLS_LABELS];
+ unsigned int num_labels;
+ compat_uptr_t fm_pcd;
+};
+
+struct dpa_cls_compat_hm_mpls_resources {
+ compat_uptr_t ins_rm_node;
+};
+
+struct compat_ioc_dpa_cls_hm_mpls_params {
+ struct dpa_cls_compat_hm_mpls_params mpls_params;
+ int next_hmd;
+ int hmd;
+ struct dpa_cls_compat_hm_mpls_resources res;
+ bool chain_head;
+ int modify_flags;
+};
+
+struct dpa_cls_compat_mcast_group_params {
+ uint8_t max_members;
+ compat_uptr_t fm_pcd;
+ struct dpa_cls_compat_tbl_enq_action_desc first_member_params;
+ unsigned int prefilled_members;
+ compat_uptr_t group;
+ compat_uptr_t distribution;
+ compat_uptr_t classification;
+};
+
+struct compat_ioc_dpa_cls_mcast_group_params {
+ struct dpa_cls_compat_mcast_group_params mcast_grp_params;
+ int grpd;
+};
+
+struct compat_ioc_dpa_cls_mcast_member_params {
+ int grpd;
+ struct dpa_cls_compat_tbl_enq_action_desc member_params;
+ int md;
+};
+
+int dpa_cls_tbl_entry_params_compatcpy(
+ struct ioc_dpa_cls_tbl_entry_params *kparam,
+ const struct compat_ioc_dpa_cls_tbl_entry_params *uparam);
+
+int dpa_cls_tbl_params_compatcpy(
+ struct ioc_dpa_cls_tbl_params *kparam,
+ const struct compat_ioc_dpa_cls_tbl_params *uparam);
+
+int dpa_cls_tbl_params_rcompatcpy(
+ struct compat_ioc_dpa_cls_tbl_params *uparam,
+ const struct ioc_dpa_cls_tbl_params *kparam);
+
+int dpa_cls_tbl_miss_action_params_compatcpy(
+ struct ioc_dpa_cls_tbl_miss_action *kparam,
+ const struct compat_ioc_dpa_cls_tbl_miss_action *uparam);
+
+int dpa_cls_tbl_action_params_compatcpy(
+ struct dpa_cls_tbl_action *kparam,
+ const struct dpa_cls_compat_tbl_action *uparam);
+
+int dpa_cls_tbl_action_params_rcompatcpy(
+ struct dpa_cls_compat_tbl_action *uparam,
+ const struct dpa_cls_tbl_action *kparam);
+
+int dpa_cls_tbl_entry_mod_by_key_params_compatcpy(
+ struct ioc_dpa_cls_tbl_entry_mod_by_key *kparam,
+ const struct compat_ioc_dpa_cls_tbl_entry_mod_by_key *uparam);
+
+int dpa_cls_tbl_entry_mod_by_ref_params_compatcpy(
+ struct ioc_dpa_cls_tbl_entry_mod_by_ref *kparam,
+ const struct compat_ioc_dpa_cls_tbl_entry_mod_by_ref *uparam);
+
+int dpa_cls_tbl_entry_mod_params_compatcpy(
+ struct dpa_cls_tbl_entry_mod_params *kparam,
+ const struct dpa_cls_compat_tbl_entry_mod_params *uparam);
+
+int dpa_cls_tbl_entry_by_key_params_compatcpy(
+ struct ioc_dpa_cls_tbl_entry_by_key *kparam,
+ const struct compat_ioc_dpa_cls_tbl_entry_by_key *uparam);
+
+int dpa_cls_tbl_lookup_by_key_params_compatcpy(
+ struct ioc_dpa_cls_tbl_lookup_by_key *kparam,
+ const struct compat_ioc_dpa_cls_tbl_lookup_by_key *uparam);
+
+int dpa_cls_tbl_lookup_by_ref_params_compatcpy(
+ struct ioc_dpa_cls_tbl_lookup_by_ref *kparam,
+ const struct compat_ioc_dpa_cls_tbl_lookup_by_ref *uparam);
+
+int dpa_cls_tbl_entry_stats_by_key_params_compatcpy(
+ struct ioc_dpa_cls_tbl_entry_stats_by_key *kparam,
+ const struct compat_ioc_dpa_cls_tbl_entry_stats_by_key *uparam);
+
+int dpa_lookup_key_params_compatcpy(
+ struct dpa_offload_lookup_key *kparam,
+ const struct compat_ioc_dpa_offld_lookup_key *uparam);
+
+int dpa_cls_hm_remove_params_compatcpy(
+ struct ioc_dpa_cls_hm_remove_params *kparam,
+ const struct compat_ioc_dpa_cls_hm_remove_params *uparam);
+
+int dpa_cls_hm_insert_params_compatcpy(
+ struct ioc_dpa_cls_hm_insert_params *kparam,
+ const struct compat_ioc_dpa_cls_hm_insert_params *uparam);
+
+int dpa_cls_hm_vlan_params_compatcpy(
+ struct ioc_dpa_cls_hm_vlan_params *kparam,
+ const struct compat_ioc_dpa_cls_hm_vlan_params *uparam);
+
+int dpa_cls_hm_nat_params_compatcpy(
+ struct ioc_dpa_cls_hm_nat_params *kparam,
+ const struct compat_ioc_dpa_cls_hm_nat_params *uparam);
+
+int dpa_cls_hm_update_params_compatcpy(
+ struct ioc_dpa_cls_hm_update_params *kparam,
+ const struct compat_ioc_dpa_cls_hm_update_params *uparam);
+
+int dpa_cls_hm_fwd_params_compatcpy(
+ struct ioc_dpa_cls_hm_fwd_params *kparam,
+ const struct compat_ioc_dpa_cls_hm_fwd_params *uparam);
+
+int dpa_cls_hm_mpls_params_compatcpy(
+ struct ioc_dpa_cls_hm_mpls_params *kparam,
+ const struct compat_ioc_dpa_cls_hm_mpls_params *uparam);
+
+int dpa_cls_mcast_group_params_compatcpy(
+ struct ioc_dpa_cls_mcast_group_params *kparam,
+ const struct compat_ioc_dpa_cls_mcast_group_params *uparam);
+
+int dpa_cls_mcast_member_params_compatcpy(
+ struct ioc_dpa_cls_mcast_member_params *kparam,
+ const struct compat_ioc_dpa_cls_mcast_member_params *uparam);
+#endif /* CONFIG_COMPAT */
+
+
+#define DPA_CLS_IOC_TBL_CREATE \
+ _IOWR(DPA_CLS_IOC_MAGIC, 0, struct ioc_dpa_cls_tbl_params)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_TBL_CREATE \
+ _IOWR(DPA_CLS_IOC_MAGIC, 0, struct compat_ioc_dpa_cls_tbl_params)
+#endif /* CONFIG_COMPAT */
+
+#define DPA_CLS_IOC_TBL_FREE \
+ _IOW(DPA_CLS_IOC_MAGIC, 1, int)
+
+#define DPA_CLS_IOC_TBL_MODIFY_MISS_ACTION \
+ _IOW(DPA_CLS_IOC_MAGIC, 2, struct ioc_dpa_cls_tbl_miss_action)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_TBL_MODIFY_MISS_ACTION \
+ _IOW(DPA_CLS_IOC_MAGIC, 2, struct compat_ioc_dpa_cls_tbl_miss_action)
+#endif /* CONFIG_COMPAT */
+
+#define DPA_CLS_IOC_TBL_INSERT_ENTRY \
+ _IOWR(DPA_CLS_IOC_MAGIC, 3, struct ioc_dpa_cls_tbl_entry_params)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_TBL_INSERT_ENTRY \
+ _IOWR(DPA_CLS_IOC_MAGIC, 3, struct compat_ioc_dpa_cls_tbl_entry_params)
+#endif /* CONFIG_COMPAT */
+
+#define DPA_CLS_IOC_TBL_MODIFY_ENTRY_BY_KEY \
+ _IOW(DPA_CLS_IOC_MAGIC, 4, struct ioc_dpa_cls_tbl_entry_mod_by_key)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_TBL_MODIFY_ENTRY_BY_KEY \
+ _IOW(DPA_CLS_IOC_MAGIC, 4, \
+ struct compat_ioc_dpa_cls_tbl_entry_mod_by_key)
+#endif /* CONFIG_COMPAT */
+
+#define DPA_CLS_IOC_TBL_MODIFY_ENTRY_BY_REF \
+ _IOW(DPA_CLS_IOC_MAGIC, 5, struct ioc_dpa_cls_tbl_entry_mod_by_ref)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_TBL_MODIFY_ENTRY_BY_REF \
+ _IOW(DPA_CLS_IOC_MAGIC, 5, \
+ struct compat_ioc_dpa_cls_tbl_entry_mod_by_ref)
+#endif /* CONFIG_COMPAT */
+
+#define DPA_CLS_IOC_TBL_DELETE_ENTRY_BY_KEY \
+ _IOW(DPA_CLS_IOC_MAGIC, 6, struct ioc_dpa_cls_tbl_entry_by_key)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_TBL_DELETE_ENTRY_BY_KEY \
+ _IOW(DPA_CLS_IOC_MAGIC, 6, \
+ struct compat_ioc_dpa_cls_tbl_entry_by_key)
+#endif /* CONFIG_COMPAT */
+
+#define DPA_CLS_IOC_TBL_DELETE_ENTRY_BY_REF \
+ _IOW(DPA_CLS_IOC_MAGIC, 7, struct ioc_dpa_cls_tbl_entry_by_ref)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_TBL_DELETE_ENTRY_BY_REF \
+ _IOW(DPA_CLS_IOC_MAGIC, 7, \
+ struct compat_ioc_dpa_cls_tbl_entry_by_ref)
+#endif /* CONFIG_COMPAT */
+
+#define DPA_CLS_IOC_TBL_LOOKUP_BY_KEY \
+ _IOR(DPA_CLS_IOC_MAGIC, 8, struct ioc_dpa_cls_tbl_lookup_by_key)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_TBL_LOOKUP_BY_KEY \
+ _IOR(DPA_CLS_IOC_MAGIC, 8, struct compat_ioc_dpa_cls_tbl_lookup_by_key)
+#endif /* CONFIG_COMPAT */
+
+#define DPA_CLS_IOC_TBL_LOOKUP_BY_REF \
+ _IOR(DPA_CLS_IOC_MAGIC, 9, struct ioc_dpa_cls_tbl_lookup_by_ref)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_TBL_LOOKUP_BY_REF \
+ _IOR(DPA_CLS_IOC_MAGIC, 9, struct compat_ioc_dpa_cls_tbl_lookup_by_ref)
+#endif /* CONFIG_COMPAT */
+
+#define DPA_CLS_IOC_TBL_FLUSH \
+ _IOW(DPA_CLS_IOC_MAGIC, 10, int)
+
+#define DPA_CLS_IOC_TBL_GET_STATS_BY_KEY \
+ _IOR(DPA_CLS_IOC_MAGIC, 11, struct ioc_dpa_cls_tbl_entry_stats_by_key)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_TBL_GET_STATS_BY_KEY \
+ _IOR(DPA_CLS_IOC_MAGIC, 11, \
+ struct compat_ioc_dpa_cls_tbl_entry_stats_by_key)
+#endif /* CONFIG_COMPAT */
+
+#define DPA_CLS_IOC_TBL_GET_STATS_BY_REF \
+ _IOR(DPA_CLS_IOC_MAGIC, 12, struct ioc_dpa_cls_tbl_entry_stats_by_ref)
+
+#define DPA_CLS_IOC_TBL_GET_PARAMS \
+ _IOWR(DPA_CLS_IOC_MAGIC, 15, struct ioc_dpa_cls_tbl_params)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_TBL_GET_PARAMS \
+ _IOWR(DPA_CLS_IOC_MAGIC, 15, struct compat_ioc_dpa_cls_tbl_params)
+#endif /* CONFIG_COMPAT */
+
+#define DPA_CLS_IOC_SET_REMOVE_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 16, struct ioc_dpa_cls_hm_remove_params)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_SET_REMOVE_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 16, \
+ struct compat_ioc_dpa_cls_hm_remove_params)
+#endif /* CONFIG_COMPAT */
+
+#define DPA_CLS_IOC_MODIFY_REMOVE_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 17, struct ioc_dpa_cls_hm_remove_params)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_MODIFY_REMOVE_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 17, \
+ struct compat_ioc_dpa_cls_hm_remove_params)
+#endif /* CONFIG_COMPAT */
+
+#define DPA_CLS_IOC_SET_INSERT_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 18, struct ioc_dpa_cls_hm_insert_params)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_SET_INSERT_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 18, \
+ struct compat_ioc_dpa_cls_hm_insert_params)
+#endif /* CONFIG_COMPAT */
+
+#define DPA_CLS_IOC_MODIFY_INSERT_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 19, struct ioc_dpa_cls_hm_insert_params)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_MODIFY_INSERT_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 19, \
+ struct compat_ioc_dpa_cls_hm_insert_params)
+#endif /* CONFIG_COMPAT */
+
+#define DPA_CLS_IOC_SET_VLAN_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 20, struct ioc_dpa_cls_hm_vlan_params)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_SET_VLAN_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 20, struct compat_ioc_dpa_cls_hm_vlan_params)
+#endif /* CONFIG_COMPAT */
+
+#define DPA_CLS_IOC_MODIFY_VLAN_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 21, struct ioc_dpa_cls_hm_vlan_params)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_MODIFY_VLAN_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 21, struct compat_ioc_dpa_cls_hm_vlan_params)
+#endif /* CONFIG_COMPAT */
+
+
+#define DPA_CLS_IOC_SET_NAT_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 22, struct ioc_dpa_cls_hm_nat_params)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_SET_NAT_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 22, struct compat_ioc_dpa_cls_hm_nat_params)
+#endif /* CONFIG_COMPAT */
+
+#define DPA_CLS_IOC_MODIFY_NAT_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 23, struct ioc_dpa_cls_hm_nat_params)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_MODIFY_NAT_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 23, struct compat_ioc_dpa_cls_hm_nat_params)
+#endif /* CONFIG_COMPAT */
+
+#define DPA_CLS_IOC_SET_UPDATE_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 24, struct ioc_dpa_cls_hm_update_params)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_SET_UPDATE_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 24, struct compat_ioc_dpa_cls_hm_update_params)
+#endif /* CONFIG_COMPAT */
+
+#define DPA_CLS_IOC_MODIFY_UPDATE_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 25, struct ioc_dpa_cls_hm_update_params)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_MODIFY_UPDATE_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 25, struct compat_ioc_dpa_cls_hm_update_params)
+#endif /* CONFIG_COMPAT */
+
+#define DPA_CLS_IOC_SET_FWD_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 26, struct ioc_dpa_cls_hm_fwd_params)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_SET_FWD_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 26, struct compat_ioc_dpa_cls_hm_fwd_params)
+#endif /* CONFIG_COMPAT */
+
+#define DPA_CLS_IOC_MODIFY_FWD_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 27, struct ioc_dpa_cls_hm_fwd_params)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_MODIFY_FWD_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 27, struct compat_ioc_dpa_cls_hm_fwd_params)
+#endif /* CONFIG_COMPAT */
+
+#define DPA_CLS_IOC_SET_MPLS_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 28, struct ioc_dpa_cls_hm_mpls_params)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_SET_MPLS_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 28, struct compat_ioc_dpa_cls_hm_mpls_params)
+#endif
+
+#define DPA_CLS_IOC_MODIFY_MPLS_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 29, struct ioc_dpa_cls_hm_mpls_params)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_MODIFY_MPLS_HM \
+ _IOWR(DPA_CLS_IOC_MAGIC, 29, struct compat_ioc_dpa_cls_hm_mpls_params)
+#endif
+
+#define DPA_CLS_IOC_FREE_HM \
+ _IOR(DPA_CLS_IOC_MAGIC, 30, int)
+
+#define DPA_CLS_IOC_MCAST_CREATE_GROUP \
+ _IOWR(DPA_CLS_IOC_MAGIC, 31, struct ioc_dpa_cls_mcast_group_params)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_MCAST_CREATE_GROUP \
+ _IOWR(DPA_CLS_IOC_MAGIC, 31, \
+ struct compat_ioc_dpa_cls_mcast_group_params)
+#endif
+
+#define DPA_CLS_IOC_MCAST_ADD_MEMBER \
+ _IOWR(DPA_CLS_IOC_MAGIC, 32, struct ioc_dpa_cls_mcast_member_params)
+
+#ifdef CONFIG_COMPAT
+#define DPA_CLS_IOC_COMPAT_MCAST_ADD_MEMBER \
+ _IOWR(DPA_CLS_IOC_MAGIC, 32, \
+ struct compat_ioc_dpa_cls_mcast_member_params)
+#endif
+
+#define DPA_CLS_IOC_MCAST_REMOVE_MEMBER \
+ _IOWR(DPA_CLS_IOC_MAGIC, 33, struct ioc_dpa_cls_mcast_remove_params)
+
+#define DPA_CLS_IOC_MCAST_FREE_GROUP \
+ _IOWR(DPA_CLS_IOC_MAGIC, 34, int)
+
+
+#endif /* __DPA_CLASSIFIER_IOCTL_H */
diff --git a/drivers/staging/fsl_dpa_offload/dpa_offload_module.c b/drivers/staging/fsl_dpa_offload/dpa_offload_module.c
new file mode 100644
index 0000000..aaf6693
--- /dev/null
+++ b/drivers/staging/fsl_dpa_offload/dpa_offload_module.c
@@ -0,0 +1,102 @@
+/* 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.
+ */
+
+/*
+ * DPA Offloading driver implementation
+ */
+
+#include <linux/module.h>
+
+#include "dpa_offload_module.h"
+#include "wrp_dpa_classifier.h"
+#include "wrp_dpa_ipsec.h"
+#include "wrp_dpa_stats.h"
+
+static int __init dpa_offload_drv_init(void)
+{
+ int err;
+
+ /* Initialize DPA Classifier wrapper to listen to [ioctl] calls */
+ err = wrp_dpa_classif_init();
+ if (err == 0)
+ printk(KERN_INFO"DPA Classifier Driver initialized.\n");
+ else {
+ printk(KERN_ERR"DPA Classifier Driver failed to initialize.\n");
+ return err;
+ }
+
+ /* Initialize DPA IPSec wrapper to listen to [ioctl] calls */
+ err = wrp_dpa_ipsec_init();
+ if (err == 0)
+ printk(KERN_INFO"DPA IPSec Driver initialized.\n");
+ else {
+ printk(KERN_ERR"DPA IPSec Driver failed to initialize.\n");
+ return err;
+ }
+
+ /* Initialize DPA Stats wrapper to listen to [ioctl] calls */
+ err = wrp_dpa_stats_init();
+ if (err == 0)
+ printk(KERN_INFO"DPA Stats Driver initialized.\n");
+ else {
+ printk(KERN_ERR"DPA Stats Driver failed to initialize.\n");
+ return err;
+ }
+ return err;
+}
+module_init(dpa_offload_drv_init);
+
+static void __exit dpa_offload_drv_exit(void)
+{
+ /* Shut down DPA Classifier wrapper */
+ if (wrp_dpa_classif_exit() < 0)
+ printk(KERN_ERR"DPA Classifier Driver failed to unload.\n");
+ else
+ printk(KERN_INFO"DPA Classifier Driver unloaded.\n");
+
+ /* Shut down DPA IPSec wrapper */
+ if (wrp_dpa_ipsec_exit() < 0)
+ printk(KERN_ERR"DPA IPSec Driver failed to unload.\n");
+ else
+ printk(KERN_INFO"INFO: DPA IPSec Driver unloaded.\n");
+
+ /* Shut down DPA Stats wrapper */
+ if (wrp_dpa_stats_exit() < 0)
+ printk(KERN_ERR"DPA Stats Driver failed to unload.\n");
+ else
+ printk(KERN_INFO"INFO: DPA Stats Driver unloaded.\n");
+}
+module_exit(dpa_offload_drv_exit);
+
+MODULE_AUTHOR("Freescale, <freescale.com>");
+MODULE_DESCRIPTION("DPA Offloading Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/staging/fsl_dpa_offload/dpa_offload_module.h b/drivers/staging/fsl_dpa_offload/dpa_offload_module.h
new file mode 100644
index 0000000..e4f3ad1
--- /dev/null
+++ b/drivers/staging/fsl_dpa_offload/dpa_offload_module.h
@@ -0,0 +1,46 @@
+/* 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.
+ */
+
+/*
+ * DPA Offloading driver internal interface
+ */
+
+#ifndef __DPA_OFFLOAD_DRIVER_H
+#define __DPA_OFFLOAD_DRIVER_H
+
+#define DRV_VERSION "1.0"
+
+static int __init dpa_offload_drv_init(void);
+
+static void __exit dpa_offload_drv_exit(void);
+
+
+#endif /* __DPA_OFFLOAD_DRIVER_H */
diff --git a/drivers/staging/fsl_dpa_offload/wrp_dpa_classifier.c b/drivers/staging/fsl_dpa_offload/wrp_dpa_classifier.c
new file mode 100644
index 0000000..aa2017a
--- /dev/null
+++ b/drivers/staging/fsl_dpa_offload/wrp_dpa_classifier.c
@@ -0,0 +1,3123 @@
+
+/* 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.
+ */
+
+/*
+ * DPA Classifier Wrapper implementation.
+ */
+
+/* DPA offloading layer includes */
+#include <linux/fsl_dpa_classifier.h>
+#include "wrp_dpa_classifier.h"
+#include "dpa_classifier_ioctl.h"
+
+/* Other includes */
+#include <linux/uaccess.h>
+#include <linux/fdtable.h>
+#include <linux/export.h>
+#include "lnxwrp_fm.h"
+#include "fm_pcd_ioctls.h"
+#include "fm_port_ioctls.h"
+#ifdef CONFIG_COMPAT
+#include "lnxwrp_ioctls_fm_compat.h"
+#endif /* CONFIG_COMPAT */
+
+
+#define COPY_KEY_PARAMS \
+do { \
+ if ((kparam.key.size <= 0) || \
+ (kparam.key.size > DPA_OFFLD_MAXENTRYKEYSIZE)) { \
+ pr_err("ERROR: %s, %s (%d): Invalid lookup key size " \
+ "(%d bytes).\n", __FILE__, __func__, __LINE__, \
+ kparam.key.size); \
+ return -EINVAL; \
+ } \
+ \
+ if (copy_from_user(key_buf, kparam.key.byte, \
+ kparam.key.size)) { \
+ pr_err("ERROR: %s, %s (%d): Read failed: lookup " \
+ "key.\n", __FILE__, __func__, __LINE__); \
+ return -EBUSY; \
+ } \
+ kparam.key.byte = key_buf; \
+ \
+ if (kparam.key.mask) { \
+ if (copy_from_user(mask_buf, kparam.key.mask, \
+ kparam.key.size)) { \
+ pr_err("ERROR: %s, %s (%d): Read failed: " \
+ "key mask.\n", __FILE__, __func__, \
+ __LINE__); \
+ return -EBUSY; \
+ } \
+ \
+ kparam.key.mask = mask_buf; \
+ } \
+} while (0)
+
+#define COPY_NEW_KEY_PARAMS \
+do { \
+ if (kparam.mod_params.key) { \
+ if (copy_from_user(&new_key, \
+ kparam.mod_params.key, \
+ sizeof(struct dpa_offload_lookup_key))) { \
+ pr_err("ERROR: %s, %s (%d): Read failed: " \
+ "new lookup key.\n", __FILE__, \
+ __func__, __LINE__); \
+ return -EBUSY; \
+ } \
+ kparam.mod_params.key = &new_key; \
+ \
+ if ((kparam.mod_params.key->size <= 0) || \
+ (kparam.mod_params.key->size > \
+ DPA_OFFLD_MAXENTRYKEYSIZE)) { \
+ pr_err("ERROR: %s, %s (%d): Invalid new lookup " \
+ "key size (%d bytes).\n", __FILE__, \
+ __func__, __LINE__, \
+ kparam.mod_params.key->size); \
+ return -EINVAL; \
+ } \
+ \
+ if (kparam.mod_params.key->byte) { \
+ if (copy_from_user(new_key_buf, \
+ kparam.mod_params.key->byte, \
+ kparam.mod_params.key->size)) { \
+ pr_err("ERROR: %s, %s (%d): Read " \
+ "failed: new lookup key data.\n", \
+ __FILE__, __func__, __LINE__); \
+ return -EBUSY; \
+ } \
+ kparam.mod_params.key->byte = new_key_buf; \
+ } \
+ if (kparam.mod_params.key->mask) { \
+ if (copy_from_user(new_mask_buf, \
+ kparam.mod_params.key->mask, \
+ kparam.mod_params.key->size)) { \
+ pr_err("ERROR: %s, %s (%d): Read " \
+ "failed: new key mask.\n", \
+ __FILE__, __func__, __LINE__); \
+ return -EBUSY; \
+ } \
+ kparam.mod_params.key->mask = new_mask_buf; \
+ } \
+ } \
+} while (0)
+
+#ifdef DPA_CLASSIFIER_WRP_DEBUG
+#define dpa_cls_wrp_dbg(message) printk message
+#else
+#define dpa_cls_wrp_dbg(message)
+#endif /* DPA_CLASSIFIER_DEBUG */
+
+
+static long do_ioctl_table_create(unsigned long args, bool compat_mode);
+
+static long do_ioctl_table_modify_miss_action(unsigned long args,
+ bool compat_mode);
+
+static long do_ioctl_table_insert_entry(unsigned long args, bool compat_mode);
+
+static long do_ioctl_table_modify_entry_by_key(unsigned long args,
+ bool compat_mode);
+
+static long do_ioctl_table_modify_entry_by_ref(unsigned long args,
+ bool compat_mode);
+
+static long do_ioctl_table_lookup_by_key(unsigned long args, bool compat_mode);
+
+static long do_ioctl_table_lookup_by_ref(unsigned long args, bool compat_mode);
+
+static long do_ioctl_table_delete_entry_by_key(unsigned long args,
+ bool compat_mode);
+
+static long do_ioctl_table_get_stats_by_key(unsigned long args,
+ bool compat_mode);
+
+static long do_ioctl_set_remove_hm(unsigned long args,
+ bool compat_mode);
+
+static long do_ioctl_modify_remove_hm(unsigned long args,
+ bool compat_mode);
+
+static long do_ioctl_set_insert_hm(unsigned long args,
+ bool compat_mode);
+
+static long do_ioctl_modify_insert_hm(unsigned long args,
+ bool compat_mode);
+
+static long do_ioctl_set_vlan_hm(unsigned long args, bool compat_mode);
+
+static long do_ioctl_modify_vlan_hm(unsigned long args, bool compat_mode);
+
+static long do_ioctl_set_nat_hm(unsigned long args, bool compat_mode);
+
+static long do_ioctl_modify_nat_hm(unsigned long args, bool compat_mode);
+
+static long do_ioctl_set_update_hm(unsigned long args, bool compat_mode);
+
+static long do_ioctl_modify_update_hm(unsigned long args, bool compat_mode);
+
+static long do_ioctl_set_fwd_hm(unsigned long args, bool compat_mode);
+
+static long do_ioctl_modify_fwd_hm(unsigned long args, bool compat_mode);
+
+static long do_ioctl_set_mpls_hm(unsigned long args, bool compat_mode);
+
+static long do_ioctl_modify_mpls_hm(unsigned long args, bool compat_mode);
+
+static long do_ioctl_mcast_create_group(unsigned long args, bool compat_mode);
+
+static long do_ioctl_mcast_add_member(unsigned long args, bool compat_mode);
+
+void *translate_fm_pcd_handle(void *fm_pcd);
+
+static const struct file_operations dpa_classif_fops = {
+ .owner = THIS_MODULE,
+ .open = wrp_dpa_classif_open,
+ .read = wrp_dpa_classif_read,
+ .write = wrp_dpa_classif_write,
+ .unlocked_ioctl = wrp_dpa_classif_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = wrp_dpa_classif_compat_ioctl,
+#endif /* CONFIG_COMPAT */
+ .release = wrp_dpa_classif_release
+};
+
+static int dpa_cls_cdev_major = -1;
+
+
+int wrp_dpa_classif_init(void)
+{
+ /* Cannot initialize the wrapper twice */
+ if (dpa_cls_cdev_major >= 0)
+ return 0;
+
+ dpa_cls_cdev_major = register_chrdev(
+ 0,
+ WRP_DPA_CLS_CDEVNAME,
+ &dpa_classif_fops);
+ if (dpa_cls_cdev_major < 0) {
+ pr_err("ERROR: %s, %s (%d): Could not register DPA Classifier "
+ "Control Device.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+
+int wrp_dpa_classif_exit(void)
+{
+ if (dpa_cls_cdev_major < 0)
+ return 0;
+
+ unregister_chrdev(dpa_cls_cdev_major, WRP_DPA_CLS_CDEVNAME);
+
+ dpa_cls_cdev_major = -1;
+
+ return 0;
+}
+
+
+int wrp_dpa_classif_open(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+
+int wrp_dpa_classif_release(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+
+ssize_t wrp_dpa_classif_read(
+ struct file *filp,
+ char __user *buf,
+ size_t len,
+ loff_t *offp)
+{
+ return 0;
+}
+
+
+ssize_t wrp_dpa_classif_write(
+ struct file *filp,
+ const char __user *buf,
+ size_t len,
+ loff_t *offp)
+{
+ return 0;
+}
+
+
+#ifdef CONFIG_COMPAT
+long wrp_dpa_classif_compat_ioctl(
+ struct file *filp,
+ unsigned int cmd,
+ unsigned long args)
+{
+ return wrp_dpa_classif_do_ioctl(filp, cmd, args, true);
+}
+#endif /* CONFIG_COMPAT */
+
+
+long wrp_dpa_classif_ioctl(
+ struct file *filp,
+ unsigned int cmd,
+ unsigned long args)
+{
+ return wrp_dpa_classif_do_ioctl(filp, cmd, args, false);
+}
+
+
+long wrp_dpa_classif_do_ioctl(
+ struct file *filp,
+ unsigned int cmd,
+ unsigned long args,
+ bool compat_mode)
+{
+ long ret = 0;
+
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) --> Processing ioctl "
+ "cmd=0x%x\n", __func__, __LINE__, cmd));
+
+ switch (cmd) {
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_TBL_CREATE:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_TBL_CREATE:
+ ret = do_ioctl_table_create(args, compat_mode);
+ break;
+
+ case DPA_CLS_IOC_TBL_FREE:
+ ret = dpa_classif_table_free((int)args);
+ break;
+
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_TBL_MODIFY_MISS_ACTION:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_TBL_MODIFY_MISS_ACTION:
+ ret = do_ioctl_table_modify_miss_action(args, compat_mode);
+ break;
+
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_TBL_INSERT_ENTRY:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_TBL_INSERT_ENTRY:
+ ret = do_ioctl_table_insert_entry(args, compat_mode);
+ break;
+
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_TBL_MODIFY_ENTRY_BY_KEY:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_TBL_MODIFY_ENTRY_BY_KEY:
+ ret = do_ioctl_table_modify_entry_by_key(args, compat_mode);
+ break;
+
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_TBL_MODIFY_ENTRY_BY_REF:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_TBL_MODIFY_ENTRY_BY_REF:
+ ret = do_ioctl_table_modify_entry_by_ref(args, compat_mode);
+ break;
+
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_TBL_DELETE_ENTRY_BY_KEY:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_TBL_DELETE_ENTRY_BY_KEY:
+ ret = do_ioctl_table_delete_entry_by_key(args, compat_mode);
+ break;
+
+ case DPA_CLS_IOC_TBL_DELETE_ENTRY_BY_REF:
+ {
+ struct ioc_dpa_cls_tbl_entry_by_ref param;
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d): "
+ "delete_entry_by_ref\n", __func__, __LINE__));
+
+ /* Prepare arguments */
+ if (copy_from_user(&param, (void *) args, sizeof(param))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: "
+ "dpa_classif_table_delete_entry_by_ref user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ /* Call function */
+ ret = dpa_classif_table_delete_entry_by_ref(param.td,
+ param.entry_id);
+
+ break;
+ }
+
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_TBL_LOOKUP_BY_KEY:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_TBL_LOOKUP_BY_KEY:
+ ret = do_ioctl_table_lookup_by_key(args, compat_mode);
+ break;
+
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_TBL_LOOKUP_BY_REF:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_TBL_LOOKUP_BY_REF:
+ ret = do_ioctl_table_lookup_by_ref(args, compat_mode);
+ break;
+
+ case DPA_CLS_IOC_TBL_FLUSH:
+ ret = dpa_classif_table_flush((int)args);
+ break;
+
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_TBL_GET_STATS_BY_KEY:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_TBL_GET_STATS_BY_KEY:
+ ret = do_ioctl_table_get_stats_by_key(args, compat_mode);
+ break;
+
+ case DPA_CLS_IOC_TBL_GET_STATS_BY_REF:
+ {
+ struct ioc_dpa_cls_tbl_entry_stats_by_ref param;
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d): "
+ "get_stats_by_ref\n", __func__, __LINE__));
+
+ /* Prepare arguments */
+ if (copy_from_user(&param, (void *) args, sizeof(param))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: "
+ "dpa_classif_table_get_entry_stats_by_ref user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ /* Call function */
+ ret = dpa_classif_table_get_entry_stats_by_ref(param.td,
+ param.entry_id,
+ &param.stats);
+ if (ret < 0)
+ return ret;
+
+ /* Return results to user space */
+ if (copy_to_user((void *) args, &param, sizeof(param))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: "
+ "dpa_classif_table_get_entry_stats_by_ref "
+ "result.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ break;
+ }
+
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_TBL_GET_PARAMS:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_TBL_GET_PARAMS:
+ {
+ struct ioc_dpa_cls_tbl_params kparam;
+#ifdef CONFIG_COMPAT
+ struct compat_ioc_dpa_cls_tbl_params uparam;
+
+ /* Prepare arguments */
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args,
+ sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: "
+ "dpa_classif_table_lookup_by_key user "
+ "space args.\n", __FILE__, __func__,
+ __LINE__);
+ return -EBUSY;
+ }
+
+ /* Transfer the data into the kernel space params: */
+ kparam.td = uparam.td;
+ } else
+#endif /* CONFIG_COMPAT */
+ /* Prepare arguments */
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: "
+ "dpa_classif_table_lookup_by_key user space "
+ "args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d): "
+ "table_get_params\n", __func__, __LINE__));
+
+ /* Call function */
+ ret = dpa_classif_table_get_params(kparam.td,
+ &kparam.table_params);
+ if (ret < 0)
+ return ret;
+
+#ifdef CONFIG_COMPAT
+ if (compat_mode) {
+ ret = dpa_cls_tbl_params_rcompatcpy(&uparam, &kparam);
+ if (ret < 0)
+ return ret;
+
+ if (copy_to_user((void *) args, &uparam, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: "
+ "dpa_classif_table_get_params result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+ } else
+#endif /* CONFIG_COMPAT */
+ /* Return results to user space */
+ if (copy_to_user((void *) args, &kparam, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: "
+ "dpa_classif_table_get_params result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ break;
+ }
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_SET_REMOVE_HM:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_SET_REMOVE_HM:
+ ret = do_ioctl_set_remove_hm(args, compat_mode);
+ break;
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_MODIFY_REMOVE_HM:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_MODIFY_REMOVE_HM:
+ ret = do_ioctl_modify_remove_hm(args, compat_mode);
+ break;
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_SET_INSERT_HM:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_SET_INSERT_HM:
+ ret = do_ioctl_set_insert_hm(args, compat_mode);
+ break;
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_MODIFY_INSERT_HM:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_MODIFY_INSERT_HM:
+ ret = do_ioctl_modify_insert_hm(args, compat_mode);
+ break;
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_SET_VLAN_HM:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_SET_VLAN_HM:
+ ret = do_ioctl_set_vlan_hm(args, compat_mode);
+ break;
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_MODIFY_VLAN_HM:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_MODIFY_VLAN_HM:
+ ret = do_ioctl_modify_vlan_hm(args, compat_mode);
+ break;
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_SET_NAT_HM:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_SET_NAT_HM:
+ ret = do_ioctl_set_nat_hm(args, compat_mode);
+ break;
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_MODIFY_NAT_HM:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_MODIFY_NAT_HM:
+ ret = do_ioctl_modify_nat_hm(args, compat_mode);
+ break;
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_SET_UPDATE_HM:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_SET_UPDATE_HM:
+ ret = do_ioctl_set_update_hm(args, compat_mode);
+ break;
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_MODIFY_UPDATE_HM:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_MODIFY_UPDATE_HM:
+ ret = do_ioctl_modify_update_hm(args, compat_mode);
+ break;
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_SET_FWD_HM:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_SET_FWD_HM:
+ ret = do_ioctl_set_fwd_hm(args, compat_mode);
+ break;
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_MODIFY_FWD_HM:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_MODIFY_FWD_HM:
+ ret = do_ioctl_modify_fwd_hm(args, compat_mode);
+ break;
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_SET_MPLS_HM:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_SET_MPLS_HM:
+ ret = do_ioctl_set_mpls_hm(args, compat_mode);
+ break;
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_MODIFY_MPLS_HM:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_MODIFY_MPLS_HM:
+ ret = do_ioctl_modify_mpls_hm(args, compat_mode);
+ break;
+ case DPA_CLS_IOC_FREE_HM:
+ ret = dpa_classif_free_hm((int)args);
+ break;
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_MCAST_CREATE_GROUP:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_MCAST_CREATE_GROUP:
+ ret = do_ioctl_mcast_create_group(args, compat_mode);
+ break;
+#ifdef CONFIG_COMPAT
+ case DPA_CLS_IOC_COMPAT_MCAST_ADD_MEMBER:
+#endif /* CONFIG_COMPAT */
+ case DPA_CLS_IOC_MCAST_ADD_MEMBER:
+ ret = do_ioctl_mcast_add_member(args, compat_mode);
+ break;
+ case DPA_CLS_IOC_MCAST_REMOVE_MEMBER: {
+ struct ioc_dpa_cls_mcast_remove_params params;
+ int sz;
+ sz = sizeof(struct ioc_dpa_cls_mcast_remove_params);
+ if (copy_from_user(&params,
+ (struct ioc_dpa_cls_mcast_remove_params *)args,
+ sz)) {
+ pr_err("ERROR: %s, %s (%d):Could not copy parameters\n",
+ __FILE__, __func__, __LINE__);
+ return -EINVAL;
+ }
+#if (DPAA_VERSION >= 11)
+ ret = dpa_classif_mcast_remove_member(params.grpd,
+ params.md);
+#else
+ pr_err("ERROR: %s, %s (%d): Multicast not supported on this"
+ "platform.\n", __FILE__, __func__, __LINE__);
+ ret = -EINVAL;
+ return ret;
+#endif
+ break;
+ }
+ case DPA_CLS_IOC_MCAST_FREE_GROUP: {
+ int grpd;
+ if (copy_from_user(&grpd, (int *)args, sizeof(int))) {
+ pr_err("ERROR: %s, %s (%d):Could not copy parameters\n",
+ __FILE__, __func__, __LINE__);
+ return -EINVAL;
+ }
+#if (DPAA_VERSION >= 11)
+ ret = dpa_classif_mcast_free_group(grpd);
+ if (ret < 0)
+ return ret;
+#else
+ pr_err("ERROR: %s, %s (%d): Multicast not supported on this"
+ "platform.\n", __FILE__, __func__, __LINE__);
+ ret = -EINVAL;
+ return ret;
+#endif
+ break;
+ }
+ default:
+ pr_err("ERROR: %s, %s (%d): DPA Classifier ioctl command "
+ "(0x%x) not suppoted", __FILE__, __func__, __LINE__,
+ cmd);
+ return -EINVAL;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d): Done <--\n", __func__,
+ __LINE__));
+
+ return ret;
+}
+
+static long do_ioctl_table_create(unsigned long args, bool compat_mode)
+{
+ long ret = 0;
+ struct ioc_dpa_cls_tbl_params kparam;
+#ifdef CONFIG_COMPAT
+ struct compat_ioc_dpa_cls_tbl_params uparam;
+
+ /* Prepare arguments */
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user space "
+ "args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ memset(&kparam, 0, sizeof(struct ioc_dpa_cls_tbl_params));
+ /* Transfer the data into the kernel space params: */
+ ret = dpa_cls_tbl_params_compatcpy(&kparam, &uparam);
+ if (ret < 0)
+ return ret;
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user space "
+ "args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) -->\n", __func__,
+ __LINE__));
+
+ /* Call function */
+ ret = dpa_classif_table_create(&kparam.table_params,
+ &kparam.td);
+ if (ret < 0)
+ return ret;
+
+ /* Return results to user space */
+#ifdef CONFIG_COMPAT
+ if (compat_mode) {
+ uparam.td = kparam.td;
+ if (copy_to_user((void *) args, &uparam, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_to_user((void *) args, &kparam, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) <--\n", __func__,
+ __LINE__));
+
+ return ret;
+}
+
+static long do_ioctl_set_remove_hm(unsigned long args, bool compat_mode)
+{
+ long ret = 0;
+ struct ioc_dpa_cls_hm_remove_params kparam;
+ struct dpa_cls_hm_remove_resources *p_res = NULL;
+#ifdef CONFIG_COMPAT
+ struct compat_ioc_dpa_cls_hm_remove_params uparam;
+
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user space "
+ "args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ /* Transfer the data into the kernel space params: */
+ ret = dpa_cls_hm_remove_params_compatcpy(&kparam, &uparam);
+ if (ret < 0)
+ return ret;
+
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user space "
+ "args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) -->\n", __func__,
+ __LINE__));
+
+ if (kparam.res.remove_node)
+ p_res = &kparam.res;
+
+ /* Translate FM_PCD file descriptor */
+ if (!p_res) {
+ kparam.rm_params.fm_pcd =
+ translate_fm_pcd_handle(kparam.rm_params.fm_pcd);
+ if (!kparam.rm_params.fm_pcd)
+ return -EINVAL;
+ }
+
+ ret = dpa_classif_set_remove_hm(&kparam.rm_params, kparam.next_hmd,
+ &kparam.hmd, kparam.chain_head,
+ p_res);
+ if (ret < 0)
+ return ret;
+
+ /* Return results to user space */
+#ifdef CONFIG_COMPAT
+ if (compat_mode) {
+ uparam.hmd = kparam.hmd;
+ if (copy_to_user((void *) args, &uparam, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_to_user((void *) args, &kparam, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) <--\n", __func__,
+ __LINE__));
+
+ return ret;
+}
+
+static long do_ioctl_modify_remove_hm(unsigned long args, bool compat_mode)
+{
+ struct ioc_dpa_cls_hm_remove_params kparam;
+#ifdef CONFIG_COMPAT
+ long ret = 0;
+ struct compat_ioc_dpa_cls_hm_remove_params uparam;
+
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ /* Transfer the data into the kernel space params: */
+ ret = dpa_cls_hm_remove_params_compatcpy(&kparam, &uparam);
+ if (ret < 0)
+ return ret;
+
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d)\n", __func__,
+ __LINE__));
+
+ return dpa_classif_modify_remove_hm(kparam.hmd, &kparam.rm_params,
+ kparam.modify_flags);
+}
+
+static long do_ioctl_set_insert_hm(unsigned long args, bool compat_mode)
+{
+ long ret = 0;
+ struct ioc_dpa_cls_hm_insert_params kparam;
+ struct dpa_cls_hm_insert_resources *p_res = NULL;
+ uint8_t *data = NULL;
+ uint8_t sz;
+#ifdef CONFIG_COMPAT
+ struct compat_ioc_dpa_cls_hm_insert_params uparam;
+
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ /* Transfer the data into the kernel space params: */
+ ret = dpa_cls_hm_insert_params_compatcpy(&kparam, &uparam);
+ if (ret < 0)
+ return ret;
+
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: space args.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) -->\n", __func__,
+ __LINE__));
+
+ if (kparam.res.insert_node)
+ p_res = &kparam.res;
+
+ /* Translate FM_PCD file descriptor */
+ if (!p_res) {
+ kparam.ins_params.fm_pcd =
+ translate_fm_pcd_handle(kparam.ins_params.fm_pcd);
+ if (!kparam.ins_params.fm_pcd)
+ return -EINVAL;
+ }
+
+ if (kparam.ins_params.type == DPA_CLS_HM_INSERT_CUSTOM) {
+ sz = kparam.ins_params.custom.size;
+ data = kzalloc(sz * sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ pr_err("ERROR: %s, %s (%d): Failed to allocate memory "
+ "for data param for DPA_CLS_HM_INSERT_CUSTOM"
+ " parameter type.\n",
+ __FILE__, __func__, __LINE__);
+ return -ENOMEM;
+ }
+
+ copy_from_user(data, kparam.ins_params.custom.data, sz);
+ kparam.ins_params.custom.data = data;
+ }
+
+ ret = dpa_classif_set_insert_hm(&kparam.ins_params, kparam.next_hmd,
+ &kparam.hmd, kparam.chain_head,
+ p_res);
+ kfree(data);
+ if (ret < 0)
+ return ret;
+
+#ifdef CONFIG_COMPAT
+ if (compat_mode) {
+ uparam.hmd = kparam.hmd;
+ if (copy_to_user((void *) args, &uparam, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_to_user((void *) args, &kparam, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) <--\n", __func__,
+ __LINE__));
+
+ return ret;
+}
+
+static long do_ioctl_modify_insert_hm(unsigned long args, bool compat_mode)
+{
+ long ret = 0;
+ struct ioc_dpa_cls_hm_insert_params kparam;
+ uint8_t *data = NULL;
+ uint8_t sz;
+#ifdef CONFIG_COMPAT
+ struct compat_ioc_dpa_cls_hm_insert_params uparam;
+
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ /* Transfer the data into the kernel space params: */
+ ret = dpa_cls_hm_insert_params_compatcpy(&kparam, &uparam);
+ if (ret < 0)
+ return ret;
+
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user space "
+ "args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) -->\n", __func__,
+ __LINE__));
+
+ if (kparam.ins_params.type == DPA_CLS_HM_INSERT_CUSTOM) {
+ sz = kparam.ins_params.custom.size;
+ data = kzalloc(sz * sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ pr_err("ERROR: %s, %s (%d): Failed to allocate memory "
+ "for data param for DPA_CLS_HM_INSERT_CUSTOM "
+ "parameter type.\n",
+ __FILE__, __func__, __LINE__);
+ return -ENOMEM;
+ }
+
+ copy_from_user(data, kparam.ins_params.custom.data, sz);
+ kparam.ins_params.custom.data = data;
+ }
+
+ ret = dpa_classif_modify_insert_hm(kparam.hmd, &kparam.ins_params,
+ kparam.modify_flags);
+ kfree(data);
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) <--\n", __func__,
+ __LINE__));
+
+ return ret;
+}
+
+static long do_ioctl_set_vlan_hm(unsigned long args, bool compat_mode)
+{
+ long ret = 0;
+ struct ioc_dpa_cls_hm_vlan_params kparam;
+ struct dpa_cls_hm_vlan_resources *p_res = NULL;
+#ifdef CONFIG_COMPAT
+ struct compat_ioc_dpa_cls_hm_vlan_params uparam;
+
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ /* Transfer the data into the kernel space params: */
+ ret = dpa_cls_hm_vlan_params_compatcpy(&kparam, &uparam);
+ if (ret < 0)
+ return ret;
+
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user space "
+ "args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) -->\n", __func__,
+ __LINE__));
+
+ if (kparam.res.vlan_node)
+ p_res = &kparam.res;
+
+ /* Translate FM_PCD file descriptor */
+ if (!p_res) {
+ kparam.vlan_params.fm_pcd =
+ translate_fm_pcd_handle(kparam.vlan_params.fm_pcd);
+ if (!kparam.vlan_params.fm_pcd)
+ return -EINVAL;
+ }
+
+ ret = dpa_classif_set_vlan_hm(&kparam.vlan_params, kparam.next_hmd,
+ &kparam.hmd, kparam.chain_head,
+ p_res);
+ if (ret < 0)
+ return ret;
+
+#ifdef CONFIG_COMPAT
+ if (compat_mode) {
+ uparam.hmd = kparam.hmd;
+ if (copy_to_user((void *) args, &uparam, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_to_user((void *) args, &kparam, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) <--\n", __func__,
+ __LINE__));
+
+ return ret;
+
+}
+
+static long do_ioctl_modify_vlan_hm(unsigned long args, bool compat_mode)
+{
+ struct ioc_dpa_cls_hm_vlan_params kparam;
+#ifdef CONFIG_COMPAT
+ long ret = 0;
+ struct compat_ioc_dpa_cls_hm_vlan_params uparam;
+
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ /* Transfer the data into the kernel space params: */
+ ret = dpa_cls_hm_vlan_params_compatcpy(&kparam, &uparam);
+ if (ret < 0)
+ return ret;
+
+ } else
+#endif
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user space args.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d)\n", __func__,
+ __LINE__));
+
+ return dpa_classif_modify_vlan_hm(kparam.hmd, &kparam.vlan_params,
+ kparam.modify_flags);
+}
+
+static long do_ioctl_set_nat_hm(unsigned long args, bool compat_mode)
+{
+ long ret = 0;
+ struct ioc_dpa_cls_hm_nat_params kparam;
+ struct dpa_cls_hm_nat_resources *p_res = NULL;
+ int type;
+ unsigned int sz;
+ uint8_t *options = NULL;
+#ifdef CONFIG_COMPAT
+ struct compat_ioc_dpa_cls_hm_nat_params uparam;
+
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ /* Transfer the data into the kernel space params: */
+ ret = dpa_cls_hm_nat_params_compatcpy(&kparam, &uparam);
+ if (ret < 0)
+ return ret;
+
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user space "
+ "args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) -->\n", __func__,
+ __LINE__));
+
+ if (kparam.res.l3_update_node || kparam.res.l4_update_node)
+ p_res = &kparam.res;
+
+ /* Translate FM_PCD file descriptor */
+ if (!p_res) {
+ kparam.nat_params.fm_pcd =
+ translate_fm_pcd_handle(kparam.nat_params.fm_pcd);
+ if (!kparam.nat_params.fm_pcd)
+ return -EINVAL;
+ }
+
+ if (kparam.nat_params.type == DPA_CLS_HM_NAT_TYPE_NAT_PT) {
+ type = kparam.nat_params.nat_pt.type;
+ if (type == DPA_CLS_HM_NAT_PT_IPv6_TO_IPv4) {
+ sz = kparam.nat_params.nat_pt.new_header.ipv4.
+ options_size;
+ options = kzalloc(sz * sizeof(*options), GFP_KERNEL);
+ if (!options) {
+ pr_err("ERROR: %s, %s (%d): Failed to allocate"
+ " memory for options param for"
+ " DPA_CLS_HM_NAT_TYPE_NAT_PT parameter"
+ " type.\n", __FILE__, __func__,
+ __LINE__);
+ return -ENOMEM;
+ }
+ copy_from_user(options,
+ kparam.nat_params.nat_pt.new_header.
+ ipv4.options, sz);
+ kparam.nat_params.nat_pt.new_header.ipv4.options =
+ options;
+ }
+ }
+
+ ret = dpa_classif_set_nat_hm(&kparam.nat_params, kparam.next_hmd,
+ &kparam.hmd, kparam.chain_head,
+ p_res);
+ kfree(options);
+ if (ret < 0)
+ return ret;
+
+#ifdef CONFIG_COMPAT
+ if (compat_mode) {
+ uparam.hmd = kparam.hmd;
+ if (copy_to_user((void *) args, &uparam, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_to_user((void *) args, &kparam, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) <--\n", __func__,
+ __LINE__));
+
+ return ret;
+}
+
+static long do_ioctl_modify_nat_hm(unsigned long args, bool compat_mode)
+{
+ struct ioc_dpa_cls_hm_nat_params kparam;
+ uint8_t *options = NULL;
+ long ret = 0;
+ int type;
+ unsigned int sz;
+#ifdef CONFIG_COMPAT
+ struct compat_ioc_dpa_cls_hm_nat_params uparam;
+
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ /* Transfer the data into the kernel space params: */
+ ret = dpa_cls_hm_nat_params_compatcpy(&kparam, &uparam);
+ if (ret < 0)
+ return ret;
+
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user space "
+ "args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ if (kparam.nat_params.type == DPA_CLS_HM_NAT_TYPE_NAT_PT) {
+ type = kparam.nat_params.nat_pt.type;
+ if (type == DPA_CLS_HM_NAT_PT_IPv6_TO_IPv4) {
+ sz = kparam.nat_params.nat_pt.new_header.ipv4.
+ options_size;
+ options = kzalloc(sz * sizeof(*options), GFP_KERNEL);
+ if (!options) {
+ pr_err("ERROR: %s, %s (%d): Failed to allocate"
+ " memory for options param for"
+ " DPA_CLS_HM_NAT_TYPE_NAT_PT parameter"
+ " type.\n", __FILE__, __func__,
+ __LINE__);
+ return -ENOMEM;
+ }
+ copy_from_user(options,
+ kparam.nat_params.nat_pt.new_header.
+ ipv4.options, sz);
+ kparam.nat_params.nat_pt.new_header.ipv4.options =
+ options;
+ }
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d)\n", __func__,
+ __LINE__));
+
+ ret = dpa_classif_modify_nat_hm(kparam.hmd, &kparam.nat_params,
+ kparam.modify_flags);
+ kfree(options);
+
+ return ret;
+}
+
+static long do_ioctl_set_update_hm(unsigned long args, bool compat_mode)
+{
+ long ret = 0;
+ struct ioc_dpa_cls_hm_update_params kparam;
+ struct dpa_cls_hm_update_resources *p_res = NULL;
+ unsigned int sz;
+ uint8_t *options = NULL;
+#ifdef CONFIG_COMPAT
+ struct compat_ioc_dpa_cls_hm_update_params uparam;
+
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ /* Transfer the data into the kernel space params: */
+ ret = dpa_cls_hm_update_params_compatcpy(&kparam, &uparam);
+ if (ret < 0)
+ return ret;
+
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user space "
+ "args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) -->\n", __func__,
+ __LINE__));
+
+ if (kparam.res.ip_frag_node || kparam.res.update_node)
+ p_res = &kparam.res;
+
+ /* Translate FM_PCD file descriptor */
+ if (!p_res) {
+ kparam.update_params.fm_pcd =
+ translate_fm_pcd_handle(kparam.update_params.fm_pcd);
+ if (!kparam.update_params.fm_pcd)
+ return -EINVAL;
+ }
+
+ if (kparam.update_params.op_flags == DPA_CLS_HM_REPLACE_IPv6_BY_IPv4) {
+ sz = kparam.update_params.replace.new_ipv4_hdr.options_size;
+ options = kzalloc(sz * sizeof(*options), GFP_KERNEL);
+ if (!options) {
+ pr_err("ERROR: %s, %s (%d): Failed to allocate memory "
+ "for options param for"
+ " DPA_CLS_HM_REPLACE_IPv6_BY_IPv4"
+ " parameter type.\n", __FILE__, __func__,
+ __LINE__);
+ return -ENOMEM;
+ }
+
+ copy_from_user(options,
+ kparam.update_params.replace.new_ipv4_hdr.
+ options, sz);
+ kparam.update_params.replace.new_ipv4_hdr.options = options;
+ }
+
+ ret = dpa_classif_set_update_hm(&kparam.update_params, kparam.next_hmd,
+ &kparam.hmd, kparam.chain_head,
+ p_res);
+ kfree(options);
+ if (ret < 0)
+ return ret;
+
+#ifdef CONFIG_COMPAT
+ if (compat_mode) {
+ uparam.hmd = kparam.hmd;
+ if (copy_to_user((void *) args, &uparam, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_to_user((void *) args, &kparam, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) <--\n", __func__,
+ __LINE__));
+
+ return ret;
+}
+
+static long do_ioctl_modify_update_hm(unsigned long args, bool compat_mode)
+{
+ struct ioc_dpa_cls_hm_update_params kparam;
+ uint8_t *options = NULL;
+ long ret = 0;
+ unsigned int sz;
+#ifdef CONFIG_COMPAT
+ struct compat_ioc_dpa_cls_hm_update_params uparam;
+
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ /* Transfer the data into the kernel space params: */
+ ret = dpa_cls_hm_update_params_compatcpy(&kparam, &uparam);
+ if (ret < 0)
+ return ret;
+
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d)\n", __func__,
+ __LINE__));
+
+ if (kparam.update_params.op_flags == DPA_CLS_HM_REPLACE_IPv6_BY_IPv4) {
+ sz = kparam.update_params.replace.new_ipv4_hdr.options_size;
+ options = kzalloc(sz * sizeof(*options), GFP_KERNEL);
+ if (!options) {
+ pr_err("ERROR: %s, %s (%d): Failed to allocate memory "
+ "for options param for"
+ " DPA_CLS_HM_REPLACE_IPv6_BY_IPv4"
+ " parameter type.\n", __FILE__, __func__,
+ __LINE__);
+ return -ENOMEM;
+ }
+
+ copy_from_user(options,
+ kparam.update_params.replace.new_ipv4_hdr.
+ options, sz);
+ kparam.update_params.replace.new_ipv4_hdr.options = options;
+ }
+
+ ret = dpa_classif_modify_update_hm(kparam.hmd, &kparam.update_params,
+ kparam.modify_flags);
+
+ kfree(options);
+
+ return ret;
+}
+
+static long do_ioctl_set_fwd_hm(unsigned long args, bool compat_mode)
+{
+ long ret = 0;
+ struct ioc_dpa_cls_hm_fwd_params kparam;
+ struct dpa_cls_hm_fwd_resources *p_res = NULL;
+#ifdef CONFIG_COMPAT
+ struct compat_ioc_dpa_cls_hm_fwd_params uparam;
+
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ /* Transfer the data into the kernel space params: */
+ ret = dpa_cls_hm_fwd_params_compatcpy(&kparam, &uparam);
+ if (ret < 0)
+ return ret;
+
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user space "
+ "args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) -->\n", __func__,
+ __LINE__));
+
+ if (kparam.res.ip_frag_node || kparam.res.fwd_node ||
+ kparam.res.pppoe_node)
+ p_res = &kparam.res;
+
+ /* Translate FM_PCD file descriptor */
+ if (!p_res) {
+ kparam.fwd_params.fm_pcd =
+ translate_fm_pcd_handle(kparam.fwd_params.fm_pcd);
+ if (!kparam.fwd_params.fm_pcd)
+ return -EINVAL;
+ }
+
+ ret = dpa_classif_set_fwd_hm(&kparam.fwd_params, kparam.next_hmd,
+ &kparam.hmd, kparam.chain_head,
+ p_res);
+ if (ret < 0)
+ return ret;
+
+#ifdef CONFIG_COMPAT
+ if (compat_mode) {
+ uparam.hmd = kparam.hmd;
+ if (copy_to_user((void *) args, &uparam, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_to_user((void *) args, &kparam, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) <--\n", __func__,
+ __LINE__));
+
+ return ret;
+}
+
+static long do_ioctl_modify_fwd_hm(unsigned long args, bool compat_mode)
+{
+ struct ioc_dpa_cls_hm_fwd_params kparam;
+#ifdef CONFIG_COMPAT
+ long ret = 0;
+ struct compat_ioc_dpa_cls_hm_fwd_params uparam;
+
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ /* Transfer the data into the kernel space params: */
+ ret = dpa_cls_hm_fwd_params_compatcpy(&kparam, &uparam);
+ if (ret < 0)
+ return ret;
+
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user space "
+ "args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d)\n", __func__,
+ __LINE__));
+
+ return dpa_classif_modify_fwd_hm(kparam.hmd, &kparam.fwd_params,
+ kparam.modify_flags);
+}
+
+static long do_ioctl_set_mpls_hm(unsigned long args, bool compat_mode)
+{
+ long ret = 0;
+ struct ioc_dpa_cls_hm_mpls_params kparam;
+ struct dpa_cls_hm_mpls_resources *p_res = NULL;
+#ifdef CONFIG_COMPAT
+ struct compat_ioc_dpa_cls_hm_mpls_params uparam;
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ /* Transfer the data into the kernel space params: */
+ ret = dpa_cls_hm_mpls_params_compatcpy(&kparam, &uparam);
+ if (ret < 0)
+ return ret;
+
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user space "
+ "args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) -->\n", __func__,
+ __LINE__));
+
+ if (kparam.res.ins_rm_node)
+ p_res = &kparam.res;
+
+ /* Translate FM_PCD file descriptor */
+ if (!p_res) {
+ kparam.mpls_params.fm_pcd =
+ translate_fm_pcd_handle(kparam.mpls_params.fm_pcd);
+ if (!kparam.mpls_params.fm_pcd)
+ return -EINVAL;
+ }
+
+ ret = dpa_classif_set_mpls_hm(&kparam.mpls_params, kparam.next_hmd,
+ &kparam.hmd, kparam.chain_head,
+ p_res);
+ if (ret < 0)
+ return ret;
+
+#ifdef CONFIG_COMPAT
+ if (compat_mode) {
+ uparam.hmd = kparam.hmd;
+ if (copy_to_user((void *) args, &uparam, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_to_user((void *) args, &kparam, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) <--\n", __func__,
+ __LINE__));
+
+ return ret;
+}
+
+static long do_ioctl_modify_mpls_hm(unsigned long args, bool compat_mode)
+{
+ struct ioc_dpa_cls_hm_mpls_params kparam;
+#ifdef CONFIG_COMPAT
+ long ret = 0;
+ struct compat_ioc_dpa_cls_hm_mpls_params uparam;
+
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ /* Transfer the data into the kernel space params: */
+ ret = dpa_cls_hm_mpls_params_compatcpy(&kparam, &uparam);
+ if (ret < 0)
+ return ret;
+
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user space "
+ "args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d)\n", __func__,
+ __LINE__));
+
+ return dpa_classif_modify_mpls_hm(kparam.hmd, &kparam.mpls_params,
+ kparam.modify_flags);
+}
+
+static long do_ioctl_mcast_create_group(unsigned long args, bool compat_mode)
+{
+ long ret = 0;
+ struct ioc_dpa_cls_mcast_group_params kparam;
+ struct dpa_cls_tbl_policer_params policer_params;
+#ifdef CONFIG_COMPAT
+ struct compat_ioc_dpa_cls_mcast_group_params uparam;
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ kparam.mcast_grp_params.first_member_params.policer_params =
+ &policer_params;
+ /*
+ * Transfer the data into the kernel space params:
+ */
+ ret = dpa_cls_mcast_group_params_compatcpy(&kparam, &uparam);
+ if (ret < 0)
+ return ret;
+
+ } else
+#endif /* CONFIG_COMPAT */
+ {
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user space "
+ "args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ if (kparam.mcast_grp_params.first_member_params.
+ policer_params) {
+ if (copy_from_user(&policer_params,
+ kparam.mcast_grp_params.
+ first_member_params.policer_params,
+ sizeof(policer_params))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: "
+ "policer params.\n", __FILE__, __func__,
+ __LINE__);
+ return -EBUSY;
+ }
+ kparam.mcast_grp_params.first_member_params.
+ policer_params =
+ &policer_params;
+ }
+ }
+ /*
+ * Translate FM_PCD file descriptor
+ */
+ if (!kparam.mcast_grp_params.group) {
+ kparam.mcast_grp_params.fm_pcd =
+ translate_fm_pcd_handle(kparam.
+ mcast_grp_params.fm_pcd);
+ if (!kparam.mcast_grp_params.fm_pcd)
+ return -EINVAL;
+ }
+
+#if (DPAA_VERSION >= 11)
+ ret = dpa_classif_mcast_create_group(&kparam.mcast_grp_params,
+ &kparam.grpd);
+#else
+ pr_err("ERROR: %s, %s (%d): Multicast not supported on this"
+ "platform.\n", __FILE__, __func__, __LINE__);
+ return -EINVAL;
+#endif
+
+ if (ret < 0)
+ return ret;
+
+#ifdef CONFIG_COMPAT
+ if (compat_mode) {
+ uparam.grpd = kparam.grpd;
+ if (copy_to_user((void *) args, &uparam, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_to_user((void *) args, &kparam, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) <--\n", __func__,
+ __LINE__));
+
+ return ret;
+}
+
+static long do_ioctl_mcast_add_member(unsigned long args, bool compat_mode)
+{
+ long ret = 0;
+ struct ioc_dpa_cls_mcast_member_params kparam;
+ struct dpa_cls_tbl_policer_params policer_params;
+#ifdef CONFIG_COMPAT
+ struct compat_ioc_dpa_cls_mcast_member_params uparam;
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ kparam.member_params.policer_params = &policer_params;
+ /*
+ * Transfer the data into the kernel space params:
+ */
+ ret = dpa_cls_mcast_member_params_compatcpy(&kparam, &uparam);
+ if (ret < 0)
+ return ret;
+
+ } else
+#endif /* CONFIG_COMPAT */
+ {
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user space "
+ "args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ if (kparam.member_params.policer_params) {
+ if (copy_from_user(&policer_params,
+ kparam.member_params.policer_params,
+ sizeof(policer_params))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: "
+ "policer params.\n", __FILE__, __func__,
+ __LINE__);
+ return -EBUSY;
+ }
+
+ kparam.member_params.policer_params = &policer_params;
+ }
+ }
+#if (DPAA_VERSION >= 11)
+ ret = dpa_classif_mcast_add_member(kparam.grpd, &kparam.member_params,
+ &kparam.md);
+ if (ret < 0)
+ return ret;
+#else
+ pr_err("ERROR: %s, %s (%d): Multicast not supported on this"
+ "platform.\n", __FILE__, __func__, __LINE__);
+ return -EINVAL;
+#endif
+
+#ifdef CONFIG_COMPAT
+ if (compat_mode) {
+ uparam.md = kparam.md;
+ if (copy_to_user((void *) args, &uparam, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_to_user((void *) args, &kparam, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) <--\n", __func__,
+ __LINE__));
+
+ return ret;
+}
+
+
+static long do_ioctl_table_modify_miss_action(unsigned long args,
+ bool compat_mode)
+{
+ struct ioc_dpa_cls_tbl_miss_action kparam;
+ struct dpa_cls_tbl_policer_params policer_params;
+#ifdef CONFIG_COMPAT
+ long ret = 0;
+ struct compat_ioc_dpa_cls_tbl_miss_action uparam;
+
+ /* Prepare arguments */
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ kparam.miss_action.enq_params.policer_params = &policer_params;
+ /* Transfer the data into the kernel space params: */
+ ret = dpa_cls_tbl_miss_action_params_compatcpy(&kparam,
+ &uparam);
+ if (ret < 0)
+ return ret;
+ } else
+#endif /* CONFIG_COMPAT */
+ {
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ if (kparam.miss_action.enq_params.policer_params) {
+ if (copy_from_user(&policer_params,
+ kparam.miss_action.enq_params.policer_params,
+ sizeof(policer_params))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: "
+ "policer params.\n", __FILE__, __func__,
+ __LINE__);
+ return -EBUSY;
+ }
+
+ kparam.miss_action.enq_params.policer_params =
+ &policer_params;
+ }
+ }
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d)\n", __func__,
+ __LINE__));
+
+ /* Call function */
+ return dpa_classif_table_modify_miss_action(kparam.td,
+ &kparam.miss_action);
+}
+
+static long do_ioctl_table_insert_entry(unsigned long args, bool compat_mode)
+{
+ long ret = 0;
+ struct ioc_dpa_cls_tbl_entry_params kparam;
+ struct dpa_cls_tbl_policer_params policer_params;
+ uint8_t key_buf[DPA_OFFLD_MAXENTRYKEYSIZE];
+ uint8_t mask_buf[DPA_OFFLD_MAXENTRYKEYSIZE];
+#ifdef CONFIG_COMPAT
+ struct compat_ioc_dpa_cls_tbl_entry_params uparam;
+
+ /* Prepare arguments */
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user space "
+ "args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ kparam.key.byte = key_buf;
+ kparam.key.mask = mask_buf;
+ kparam.key.size = DPA_OFFLD_MAXENTRYKEYSIZE;
+
+ kparam.action.enq_params.policer_params = &policer_params;
+
+ /* Transfer the data into the kernel space params: */
+ ret = dpa_cls_tbl_entry_params_compatcpy(&kparam, &uparam);
+ if (ret < 0)
+ return ret;
+ } else
+#endif /* CONFIG_COMPAT */
+ {
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user space "
+ "args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ COPY_KEY_PARAMS;
+
+ /* Check if we need to copy also the policer params */
+ if ((kparam.action.type == DPA_CLS_TBL_ACTION_ENQ) &&
+ (kparam.action.enq_params.policer_params)) {
+ if (copy_from_user(&policer_params,
+ kparam.action.enq_params.policer_params,
+ sizeof(policer_params))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: "
+ "policer params.\n", __FILE__, __func__,
+ __LINE__);
+ return -EBUSY;
+ }
+ kparam.action.enq_params.policer_params = &policer_params;
+ }
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) -->\n", __func__,
+ __LINE__));
+
+ /* Call function */
+ ret = dpa_classif_table_insert_entry(kparam.td,
+ &kparam.key,
+ &kparam.action,
+ kparam.priority,
+ &kparam.entry_id);
+ if (ret < 0)
+ return ret;
+
+ /* In case of success return results to user space */
+#ifdef CONFIG_COMPAT
+ if (compat_mode) {
+ uparam.entry_id = kparam.entry_id;
+
+ if (copy_to_user((void *) args, &uparam, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_to_user((void *) args, &kparam, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) <--\n", __func__,
+ __LINE__));
+
+ return ret;
+}
+
+static long do_ioctl_table_modify_entry_by_key(unsigned long args,
+ bool compat_mode)
+{
+ struct ioc_dpa_cls_tbl_entry_mod_by_key kparam;
+ struct dpa_offload_lookup_key new_key;
+ struct dpa_cls_tbl_action action;
+ struct dpa_cls_tbl_policer_params policer_params;
+ uint8_t key_buf[DPA_OFFLD_MAXENTRYKEYSIZE];
+ uint8_t new_key_buf[DPA_OFFLD_MAXENTRYKEYSIZE];
+ uint8_t mask_buf[DPA_OFFLD_MAXENTRYKEYSIZE];
+ uint8_t new_mask_buf[DPA_OFFLD_MAXENTRYKEYSIZE];
+#ifdef CONFIG_COMPAT
+ long ret = 0;
+ struct compat_ioc_dpa_cls_tbl_entry_mod_by_key uparam;
+
+ /* Prepare arguments */
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ kparam.key.byte = key_buf;
+ kparam.key.mask = mask_buf;
+ kparam.key.size = DPA_OFFLD_MAXENTRYKEYSIZE;
+
+ new_key.byte = new_key_buf;
+ new_key.mask = new_mask_buf;
+ new_key.size = DPA_OFFLD_MAXENTRYKEYSIZE;
+
+ kparam.mod_params.key = &new_key;
+ kparam.mod_params.action = &action;
+ kparam.mod_params.action->enq_params.policer_params =
+ &policer_params;
+
+ /* Transfer the data into the kernel space params: */
+ ret = dpa_cls_tbl_entry_mod_by_key_params_compatcpy(&kparam,
+ &uparam);
+ if (ret < 0)
+ return ret;
+ } else
+#endif /* CONFIG_COMPAT */
+ {
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ COPY_KEY_PARAMS;
+
+ /* Check if we need to copy the new key */
+ COPY_NEW_KEY_PARAMS;
+
+ if (kparam.mod_params.action) {
+ if (copy_from_user(&action,
+ kparam.mod_params.action,
+ sizeof(struct dpa_cls_tbl_action))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: "
+ "new action params.\n", __FILE__,
+ __func__, __LINE__);
+ return -EBUSY;
+ }
+ kparam.mod_params.action = &action;
+
+ /* Check if we need to copy policer params */
+ if ((kparam.mod_params.action->type ==
+ DPA_CLS_TBL_ACTION_ENQ) &&
+ (kparam.mod_params.action->enq_params.
+ policer_params)) {
+ if (copy_from_user(&policer_params,
+ kparam.mod_params.
+ action->enq_params.
+ policer_params,
+ sizeof(policer_params))) {
+ pr_err("ERROR: %s, %s (%d): Read "
+ "failed: new policer params.\n", __FILE__,
+ __func__, __LINE__);
+ return -EBUSY;
+ }
+ kparam.mod_params.action->enq_params.
+ policer_params =
+ &policer_params;
+ }
+ }
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d)\n", __func__,
+ __LINE__));
+
+ /* Call function */
+ return dpa_classif_table_modify_entry_by_key(kparam.td,
+ &kparam.key,
+ &kparam.mod_params);
+
+}
+
+static long do_ioctl_table_modify_entry_by_ref(unsigned long args,
+ bool compat_mode)
+{
+ struct ioc_dpa_cls_tbl_entry_mod_by_ref kparam;
+ struct dpa_offload_lookup_key new_key;
+ struct dpa_cls_tbl_action action;
+ struct dpa_cls_tbl_policer_params policer_params;
+ uint8_t new_key_buf[DPA_OFFLD_MAXENTRYKEYSIZE];
+ uint8_t new_mask_buf[DPA_OFFLD_MAXENTRYKEYSIZE];
+#ifdef CONFIG_COMPAT
+ long ret = 0;
+ struct compat_ioc_dpa_cls_tbl_entry_mod_by_ref uparam;
+
+ /* Prepare arguments */
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ new_key.byte = new_key_buf;
+ new_key.mask = new_mask_buf;
+ new_key.size = DPA_OFFLD_MAXENTRYKEYSIZE;
+
+ memset(&kparam, 0,
+ sizeof(struct ioc_dpa_cls_tbl_entry_mod_by_ref));
+ kparam.mod_params.key = &new_key;
+ kparam.mod_params.action = &action;
+ kparam.mod_params.action->enq_params.policer_params =
+ &policer_params;
+
+ /* Transfer the data into the kernel space params: */
+ ret = dpa_cls_tbl_entry_mod_by_ref_params_compatcpy(&kparam,
+ &uparam);
+ if (ret < 0)
+ return ret;
+ } else
+#endif /* CONFIG_COMPAT */
+ {
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ /* Check if we need to copy the new key */
+ COPY_NEW_KEY_PARAMS;
+
+ if (kparam.mod_params.action) {
+ if (copy_from_user(&action,
+ kparam.mod_params.action,
+ sizeof(struct dpa_cls_tbl_action))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: "
+ "new action params.\n", __FILE__,
+ __func__, __LINE__);
+ return -EBUSY;
+ }
+ kparam.mod_params.action = &action;
+
+ /* Check if we need to copy policer params */
+ if ((kparam.mod_params.action->type ==
+ DPA_CLS_TBL_ACTION_ENQ) &&
+ (kparam.mod_params.action->enq_params.
+ policer_params)) {
+ if (copy_from_user(&policer_params,
+ kparam.mod_params.
+ action->enq_params.
+ policer_params,
+ sizeof(policer_params))) {
+ pr_err("ERROR: %s, %s (%d): Read "
+ "failed: new policer params.\n", __FILE__,
+ __func__, __LINE__);
+ return -EBUSY;
+ }
+ kparam.mod_params.action->enq_params.
+ policer_params =
+ &policer_params;
+ }
+ }
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d)\n", __func__,
+ __LINE__));
+
+ /* Call function */
+ return dpa_classif_table_modify_entry_by_ref(kparam.td,
+ kparam.entry_id,
+ &kparam.mod_params);
+}
+
+static long do_ioctl_table_lookup_by_key(unsigned long args, bool compat_mode)
+{
+ long ret = 0;
+ struct ioc_dpa_cls_tbl_lookup_by_key kparam;
+ uint8_t key_buf[DPA_OFFLD_MAXENTRYKEYSIZE];
+ uint8_t mask_buf[DPA_OFFLD_MAXENTRYKEYSIZE];
+#ifdef CONFIG_COMPAT
+ struct compat_ioc_dpa_cls_tbl_lookup_by_key uparam;
+
+ /* Prepare arguments */
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user space "
+ "args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ kparam.key.byte = key_buf;
+ kparam.key.mask = mask_buf;
+ kparam.key.size = DPA_OFFLD_MAXENTRYKEYSIZE;
+
+ /* Transfer the data into the kernel space params: */
+ ret = dpa_cls_tbl_lookup_by_key_params_compatcpy(&kparam,
+ &uparam);
+ if (ret < 0)
+ return ret;
+ } else
+#endif /* CONFIG_COMPAT */
+ {
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user space "
+ "args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ COPY_KEY_PARAMS;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) -->\n", __func__,
+ __LINE__));
+
+ /* Call function */
+ ret = dpa_classif_table_lookup_by_key(kparam.td,
+ &kparam.key,
+ &kparam.action);
+ if (ret < 0)
+ return ret;
+
+ /* Return results to user space */
+#ifdef CONFIG_COMPAT
+ if (compat_mode) {
+ ret = dpa_cls_tbl_action_params_rcompatcpy(&uparam.action,
+ &kparam.action);
+ if (ret < 0)
+ return ret;
+
+ if (copy_to_user((void *) args, &uparam, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_to_user((void *) args, &kparam, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) <--\n", __func__,
+ __LINE__));
+
+ return ret;
+}
+
+static long do_ioctl_table_lookup_by_ref(unsigned long args, bool compat_mode)
+{
+ long ret = 0;
+ struct ioc_dpa_cls_tbl_lookup_by_ref kparam;
+#ifdef CONFIG_COMPAT
+ struct compat_ioc_dpa_cls_tbl_lookup_by_ref uparam;
+
+ /* Prepare arguments */
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user space "
+ "args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ /* Transfer the data into the kernel space params: */
+ ret = dpa_cls_tbl_lookup_by_ref_params_compatcpy(&kparam,
+ &uparam);
+ if (ret < 0)
+ return ret;
+ } else
+#endif /* CONFIG_COMPAT */
+ /* Prepare arguments */
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user space "
+ "args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) -->\n", __func__,
+ __LINE__));
+
+ /* Call function */
+ ret = dpa_classif_table_lookup_by_ref(kparam.td,
+ kparam.entry_id,
+ &kparam.action);
+ if (ret < 0)
+ return ret;
+
+ /* Return results to user space */
+#ifdef CONFIG_COMPAT
+ if (compat_mode) {
+ ret = dpa_cls_tbl_action_params_rcompatcpy(&uparam.action,
+ &kparam.action);
+ if (ret < 0)
+ return ret;
+
+ if (copy_to_user((void *)args, &uparam, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_to_user((void *) args, &kparam, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) <--\n", __func__,
+ __LINE__));
+
+ return ret;
+}
+
+static long do_ioctl_table_delete_entry_by_key(unsigned long args,
+ bool compat_mode)
+{
+ struct ioc_dpa_cls_tbl_entry_by_key kparam;
+ uint8_t key_buf[DPA_OFFLD_MAXENTRYKEYSIZE];
+ uint8_t mask_buf[DPA_OFFLD_MAXENTRYKEYSIZE];
+#ifdef CONFIG_COMPAT
+ long ret = 0;
+ struct compat_ioc_dpa_cls_tbl_entry_by_key uparam;
+
+ /* Prepare arguments */
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ kparam.key.byte = key_buf;
+ kparam.key.mask = mask_buf;
+ kparam.key.size = DPA_OFFLD_MAXENTRYKEYSIZE;
+
+ /* Transfer the data into the kernel space params: */
+ ret = dpa_cls_tbl_entry_by_key_params_compatcpy(&kparam,
+ &uparam);
+ if (ret < 0)
+ return ret;
+ } else
+#endif /* CONFIG_COMPAT */
+ {
+ /* Prepare arguments */
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ COPY_KEY_PARAMS;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d)\n", __func__,
+ __LINE__));
+
+ /* Call function */
+ return dpa_classif_table_delete_entry_by_key(kparam.td,
+ &kparam.key);
+}
+
+static long do_ioctl_table_get_stats_by_key(unsigned long args,
+ bool compat_mode)
+{
+ long ret = 0;
+ struct ioc_dpa_cls_tbl_entry_stats_by_key kparam;
+ uint8_t key_buf[DPA_OFFLD_MAXENTRYKEYSIZE];
+ uint8_t mask_buf[DPA_OFFLD_MAXENTRYKEYSIZE];
+#ifdef CONFIG_COMPAT
+ struct compat_ioc_dpa_cls_tbl_entry_stats_by_key uparam;
+
+ /* Prepare arguments */
+ if (compat_mode) {
+ if (copy_from_user(&uparam, (void *) args, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user "
+ "space args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ kparam.key.byte = key_buf;
+ kparam.key.mask = mask_buf;
+ kparam.key.size = DPA_OFFLD_MAXENTRYKEYSIZE;
+
+ /* Transfer the data into the kernel space params: */
+ ret = dpa_cls_tbl_entry_stats_by_key_params_compatcpy(&kparam,
+ &uparam);
+ if (ret < 0)
+ return ret;
+ } else
+#endif /* CONFIG_COMPAT */
+ {
+ /* Prepare arguments */
+ if (copy_from_user(&kparam, (void *) args, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: user space "
+ "args.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ COPY_KEY_PARAMS;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) -->\n", __func__,
+ __LINE__));
+
+ /* Call function */
+ ret = dpa_classif_table_get_entry_stats_by_key(kparam.td,
+ &kparam.key,
+ &kparam.stats);
+ if (ret < 0)
+ return ret;
+
+ /* Return results to user space */
+#ifdef CONFIG_COMPAT
+ if (compat_mode) {
+ memcpy(&uparam.stats, &kparam.stats,
+ sizeof(struct dpa_cls_tbl_entry_stats));
+
+ if (copy_to_user((void *) args, &uparam, sizeof(uparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+ } else
+#endif /* CONFIG_COMPAT */
+ if (copy_to_user((void *) args, &kparam, sizeof(kparam))) {
+ pr_err("ERROR: %s, %s (%d): Write failed: result.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ dpa_cls_wrp_dbg(("DEBUG: classifier_wrp %s (%d) <--\n", __func__,
+ __LINE__));
+
+ return ret;
+}
+
+void *translate_fm_pcd_handle(void *fm_pcd)
+{
+ struct file *fm_pcd_file;
+ t_LnxWrpFmDev *fm_wrapper_dev;
+
+ fm_pcd_file = fcheck((unsigned long)fm_pcd);
+ if (!fm_pcd_file) {
+ pr_err("ERROR: %s, %s (%d): Could not translate PCD handle "
+ "fm_pcd=0x%p.\n", __FILE__, __func__, __LINE__, fm_pcd);
+ return NULL;
+ }
+ fm_wrapper_dev = (t_LnxWrpFmDev *)fm_pcd_file->private_data;
+ BUG_ON(!fm_wrapper_dev);
+ BUG_ON(!fm_wrapper_dev->h_PcdDev);
+
+ return (void *)fm_wrapper_dev->h_PcdDev;
+}
+
+#ifdef CONFIG_COMPAT
+
+int dpa_cls_tbl_entry_by_key_params_compatcpy(
+ struct ioc_dpa_cls_tbl_entry_by_key *kparam,
+ const struct compat_ioc_dpa_cls_tbl_entry_by_key *uparam)
+{
+ kparam->td = uparam->td;
+ return dpa_lookup_key_params_compatcpy(&kparam->key, &uparam->key);
+}
+
+int dpa_cls_tbl_entry_stats_by_key_params_compatcpy(
+ struct ioc_dpa_cls_tbl_entry_stats_by_key *kparam,
+ const struct compat_ioc_dpa_cls_tbl_entry_stats_by_key *uparam)
+{
+ int err = 0;
+
+ kparam->td = uparam->td;
+
+ err = dpa_lookup_key_params_compatcpy(&kparam->key, &uparam->key);
+ if (err < 0)
+ return err;
+
+ memcpy(&kparam->stats,
+ &uparam->stats,
+ sizeof(struct dpa_cls_tbl_entry_stats));
+
+ return 0;
+}
+
+int dpa_lookup_key_params_compatcpy(
+ struct dpa_offload_lookup_key *kparam,
+ const struct compat_ioc_dpa_offld_lookup_key *uparam)
+{
+ BUG_ON(!uparam->byte);
+ BUG_ON(!kparam->byte);
+ BUG_ON(kparam->size < uparam->size);
+ BUG_ON(uparam->size <= 0);
+
+ kparam->size = uparam->size;
+ if (copy_from_user(kparam->byte, compat_ptr(uparam->byte),
+ uparam->size)) {
+ pr_err("ERROR: %s, %s (%d): Read failed: lookup key.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ if (compat_ptr(uparam->mask)) {
+ BUG_ON(!kparam->mask);
+ if (copy_from_user(kparam->mask, compat_ptr(uparam->mask),
+ uparam->size)) {
+ pr_err("ERROR: %s, %s (%d): Read failed: key mask.\n",
+ __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+ } else
+ kparam->mask = NULL;
+
+ return 0;
+}
+
+int dpa_cls_tbl_entry_params_compatcpy(
+ struct ioc_dpa_cls_tbl_entry_params *kparam,
+ const struct compat_ioc_dpa_cls_tbl_entry_params *uparam)
+{
+ int err;
+
+ kparam->td = uparam->td;
+ kparam->priority = uparam->priority;
+ kparam->entry_id = uparam->entry_id;
+
+ err = dpa_lookup_key_params_compatcpy(&kparam->key, &uparam->key);
+ if (err < 0)
+ return err;
+
+ return dpa_cls_tbl_action_params_compatcpy(&kparam->action,
+ &uparam->action);
+}
+
+int dpa_cls_tbl_action_params_compatcpy(
+ struct dpa_cls_tbl_action *kparam,
+ const struct dpa_cls_compat_tbl_action *uparam)
+{
+ kparam->type = uparam->type;
+ kparam->enable_statistics = uparam->enable_statistics;
+
+ switch (uparam->type) {
+ case DPA_CLS_TBL_ACTION_ENQ:
+ kparam->enq_params.override_fqid =
+ uparam->enq_params.override_fqid;
+ kparam->enq_params.new_fqid =
+ uparam->enq_params.new_fqid;
+ kparam->enq_params.hmd = uparam->enq_params.hmd;
+ kparam->enq_params.new_rel_vsp_id =
+ uparam->enq_params.new_rel_vsp_id;
+ if (compat_ptr(uparam->enq_params.policer_params)) {
+ BUG_ON(!kparam->enq_params.policer_params);
+ if (copy_from_user(kparam->enq_params.policer_params,
+ compat_ptr(uparam->enq_params.policer_params),
+ sizeof(struct dpa_cls_tbl_policer_params))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: "
+ "policer params.\n", __FILE__, __func__,
+ __LINE__);
+ return -EBUSY;
+ }
+ } else
+ kparam->enq_params.policer_params = NULL;
+ break;
+ case DPA_CLS_TBL_ACTION_NEXT_TABLE:
+ kparam->next_table_params.next_td =
+ uparam->next_table_params.next_td;
+ break;
+ case DPA_CLS_TBL_ACTION_MCAST:
+ kparam->mcast_params.grpd = uparam->mcast_params.grpd;
+ kparam->mcast_params.hmd = uparam->mcast_params.hmd;
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+int dpa_cls_tbl_action_params_rcompatcpy(
+ struct dpa_cls_compat_tbl_action *uparam,
+ const struct dpa_cls_tbl_action *kparam)
+{
+ uparam->type = kparam->type;
+ uparam->enable_statistics = kparam->enable_statistics;
+
+ switch (kparam->type) {
+ case DPA_CLS_TBL_ACTION_ENQ:
+ uparam->enq_params.override_fqid =
+ kparam->enq_params.override_fqid;
+ uparam->enq_params.new_fqid =
+ kparam->enq_params.new_fqid;
+ uparam->enq_params.hmd = kparam->enq_params.hmd;
+
+ /*
+ * Policer params structure address has no meaning in user
+ * space
+ */
+ uparam->enq_params.policer_params = 0;
+
+ break;
+ case DPA_CLS_TBL_ACTION_NEXT_TABLE:
+ uparam->next_table_params.next_td =
+ kparam->next_table_params.next_td;
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+int dpa_cls_tbl_params_compatcpy(
+ struct ioc_dpa_cls_tbl_params *kparam,
+ const struct compat_ioc_dpa_cls_tbl_params *uparam)
+{
+ kparam->table_params.cc_node = compat_get_id2ptr(
+ uparam->table_params.cc_node,
+ FM_MAP_TYPE_PCD_NODE);
+ if (compat_ptr(uparam->table_params.distribution))
+ kparam->table_params.distribution = compat_get_id2ptr(
+ uparam->table_params.distribution,
+ FM_MAP_TYPE_PCD_NODE);
+ if (compat_ptr(uparam->table_params.classification))
+ kparam->table_params.classification = compat_get_id2ptr(
+ uparam->table_params.classification,
+ FM_MAP_TYPE_PCD_NODE);
+
+ kparam->table_params.type = uparam->table_params.type;
+ kparam->table_params.entry_mgmt = uparam->table_params.entry_mgmt;
+ kparam->table_params.prefilled_entries =
+ uparam->table_params.prefilled_entries;
+
+ switch (uparam->table_params.type) {
+ case DPA_CLS_TBL_INDEXED:
+ memcpy(&kparam->table_params.indexed_params,
+ &uparam->table_params.indexed_params,
+ sizeof(struct dpa_cls_tbl_indexed_params));
+ break;
+ case DPA_CLS_TBL_HASH:
+ memcpy(&kparam->table_params.hash_params,
+ &uparam->table_params.hash_params,
+ sizeof(struct dpa_cls_tbl_hash_params));
+
+ break;
+ case DPA_CLS_TBL_EXACT_MATCH:
+ memcpy(&kparam->table_params.exact_match_params,
+ &uparam->table_params.exact_match_params,
+ sizeof(struct dpa_cls_tbl_exact_match_params));
+
+ break;
+ }
+
+ return 0;
+}
+
+int dpa_cls_tbl_params_rcompatcpy(
+ struct compat_ioc_dpa_cls_tbl_params *uparam,
+ const struct ioc_dpa_cls_tbl_params *kparam)
+{
+ uparam->table_params.cc_node = compat_get_ptr2id(
+ kparam->table_params.cc_node,
+ FM_MAP_TYPE_PCD_NODE);
+ if (kparam->table_params.distribution)
+ uparam->table_params.distribution = compat_get_ptr2id(
+ kparam->table_params.distribution,
+ FM_MAP_TYPE_PCD_NODE);
+ if (kparam->table_params.classification)
+ uparam->table_params.classification = compat_get_ptr2id(
+ kparam->table_params.classification,
+ FM_MAP_TYPE_PCD_NODE);
+
+ uparam->table_params.type = kparam->table_params.type;
+ uparam->table_params.entry_mgmt = kparam->table_params.entry_mgmt;
+ uparam->table_params.prefilled_entries =
+ kparam->table_params.prefilled_entries;
+
+ switch (kparam->table_params.type) {
+ case DPA_CLS_TBL_INDEXED:
+ memcpy(&uparam->table_params.indexed_params,
+ &kparam->table_params.indexed_params,
+ sizeof(struct dpa_cls_tbl_indexed_params));
+ break;
+ case DPA_CLS_TBL_HASH:
+ memcpy(&uparam->table_params.hash_params,
+ &kparam->table_params.hash_params,
+ sizeof(struct dpa_cls_tbl_hash_params));
+
+ break;
+ case DPA_CLS_TBL_EXACT_MATCH:
+ memcpy(&uparam->table_params.exact_match_params,
+ &kparam->table_params.exact_match_params,
+ sizeof(struct dpa_cls_tbl_exact_match_params));
+
+ break;
+ }
+
+ return 0;
+}
+
+int dpa_cls_tbl_miss_action_params_compatcpy(
+ struct ioc_dpa_cls_tbl_miss_action *kparam,
+ const struct compat_ioc_dpa_cls_tbl_miss_action *uparam)
+{
+ kparam->td = uparam->td;
+
+ return dpa_cls_tbl_action_params_compatcpy(&kparam->miss_action,
+ &uparam->miss_action);
+}
+
+int dpa_cls_tbl_entry_mod_by_key_params_compatcpy(
+ struct ioc_dpa_cls_tbl_entry_mod_by_key *kparam,
+ const struct compat_ioc_dpa_cls_tbl_entry_mod_by_key *uparam)
+{
+ int err;
+
+ kparam->td = uparam->td;
+
+ err = dpa_lookup_key_params_compatcpy(&kparam->key, &uparam->key);
+ if (err < 0)
+ return err;
+
+ return dpa_cls_tbl_entry_mod_params_compatcpy(&kparam->mod_params,
+ &uparam->mod_params);
+}
+
+int dpa_cls_tbl_entry_mod_params_compatcpy(
+ struct dpa_cls_tbl_entry_mod_params *kparam,
+ const struct dpa_cls_compat_tbl_entry_mod_params *uparam)
+{
+ int err = 0;
+
+ kparam->type = uparam->type;
+
+ if (compat_ptr(uparam->key)) {
+ struct compat_ioc_dpa_offld_lookup_key key;
+
+ BUG_ON(!kparam->key);
+ if (copy_from_user(&key, compat_ptr(uparam->key),
+ sizeof(struct compat_ioc_dpa_offld_lookup_key))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: New key "
+ "parameters.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ err = dpa_lookup_key_params_compatcpy(kparam->key, &key);
+ } else
+ kparam->key = NULL;
+
+ if (err < 0)
+ return err;
+
+ if (compat_ptr(uparam->action)) {
+ struct dpa_cls_compat_tbl_action action;
+
+ BUG_ON(!kparam->action);
+
+ if (copy_from_user(&action, compat_ptr(uparam->action),
+ sizeof(struct dpa_cls_compat_tbl_action))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: New action "
+ "parameters.\n", __FILE__, __func__, __LINE__);
+ return -EBUSY;
+ }
+
+ err = dpa_cls_tbl_action_params_compatcpy(kparam->action,
+ &action);
+ } else
+ kparam->action = NULL;
+
+ return err;
+}
+
+int dpa_cls_tbl_entry_mod_by_ref_params_compatcpy(
+ struct ioc_dpa_cls_tbl_entry_mod_by_ref *kparam,
+ const struct compat_ioc_dpa_cls_tbl_entry_mod_by_ref *uparam)
+{
+ kparam->td = uparam->td;
+ kparam->entry_id = uparam->entry_id;
+
+ return dpa_cls_tbl_entry_mod_params_compatcpy(&kparam->mod_params,
+ &uparam->mod_params);
+}
+
+int dpa_cls_tbl_lookup_by_key_params_compatcpy(
+ struct ioc_dpa_cls_tbl_lookup_by_key *kparam,
+ const struct compat_ioc_dpa_cls_tbl_lookup_by_key *uparam)
+{
+ kparam->td = uparam->td;
+
+ return dpa_lookup_key_params_compatcpy(&kparam->key, &uparam->key);
+}
+
+int dpa_cls_tbl_lookup_by_ref_params_compatcpy(
+ struct ioc_dpa_cls_tbl_lookup_by_ref *kparam,
+ const struct compat_ioc_dpa_cls_tbl_lookup_by_ref *uparam)
+{
+ kparam->td = uparam->td;
+ kparam->entry_id = uparam->entry_id;
+
+ return 0;
+}
+
+int dpa_cls_hm_remove_params_compatcpy(
+ struct ioc_dpa_cls_hm_remove_params *kparam,
+ const struct compat_ioc_dpa_cls_hm_remove_params *uparam)
+{
+ kparam->rm_params.type = uparam->rm_params.type;
+ memcpy(&kparam->rm_params.custom, &uparam->rm_params.custom,
+ sizeof(struct dpa_cls_hm_custom_rm_params));
+
+ kparam->rm_params.fm_pcd = compat_ptr(uparam->rm_params.fm_pcd);
+ kparam->next_hmd = uparam->next_hmd;
+ kparam->hmd = uparam->hmd;
+
+ if (uparam->res.remove_node)
+ kparam->res.remove_node = compat_get_id2ptr(
+ uparam->res.remove_node,
+ FM_MAP_TYPE_PCD_NODE);
+ else
+ kparam->res.remove_node = NULL;
+
+ kparam->chain_head = uparam->chain_head;
+ kparam->modify_flags = uparam->modify_flags;
+
+ return 0;
+}
+
+int dpa_cls_hm_insert_params_compatcpy(
+ struct ioc_dpa_cls_hm_insert_params *kparam,
+ const struct compat_ioc_dpa_cls_hm_insert_params *uparam)
+{
+ int type;
+
+ kparam->ins_params.type = uparam->ins_params.type;
+
+ type = kparam->ins_params.type;
+ switch (type) {
+ case DPA_CLS_HM_INSERT_CUSTOM:
+ kparam->ins_params.custom.offset = uparam->ins_params.
+ custom.offset;
+ kparam->ins_params.custom.size = uparam->ins_params.
+ custom.size;
+ kparam->ins_params.custom.data = compat_ptr(uparam->ins_params.
+ custom.data);
+ break;
+ case DPA_CLS_HM_INSERT_ETHERNET:
+ memcpy(&kparam->ins_params.eth, &uparam->ins_params.eth,
+ sizeof(struct dpa_cls_hm_eth_ins_params));
+ break;
+ case DPA_CLS_HM_INSERT_PPPoE:
+ memcpy(&kparam->ins_params.pppoe, &uparam->ins_params.pppoe,
+ sizeof(struct dpa_cls_hm_pppoe_ins_params));
+ break;
+ case DPA_CLS_HM_INSERT_PPP:
+ kparam->ins_params.ppp_pid = uparam->ins_params.ppp_pid;
+ break;
+ default:
+ break;
+ }
+
+ kparam->ins_params.fm_pcd = compat_ptr(uparam->ins_params.fm_pcd);
+ kparam->next_hmd = uparam->next_hmd;
+ kparam->hmd = uparam->hmd;
+ if (uparam->res.insert_node)
+ kparam->res.insert_node = compat_get_id2ptr(
+ uparam->res.insert_node,
+ FM_MAP_TYPE_PCD_NODE);
+ else
+ kparam->res.insert_node = NULL;
+
+ kparam->chain_head = uparam->chain_head;
+ kparam->modify_flags = uparam->modify_flags;
+
+ return 0;
+}
+
+int dpa_cls_hm_vlan_params_compatcpy(
+ struct ioc_dpa_cls_hm_vlan_params *kparam,
+ const struct compat_ioc_dpa_cls_hm_vlan_params *uparam)
+{
+ int type;
+
+ kparam->vlan_params.type = uparam->vlan_params.type;
+ type = kparam->vlan_params.type;
+ switch (type) {
+ case DPA_CLS_HM_VLAN_INGRESS:
+ memcpy(&kparam->vlan_params.ingress,
+ &uparam->vlan_params.ingress,
+ sizeof(struct dpa_cls_hm_ingress_vlan_params));
+ break;
+ case DPA_CLS_HM_VLAN_EGRESS:
+ memcpy(&kparam->vlan_params.egress,
+ &uparam->vlan_params.egress,
+ sizeof(struct dpa_cls_hm_egress_vlan_params));
+ break;
+ default:
+ break;
+ }
+
+ kparam->vlan_params.fm_pcd = compat_ptr(uparam->vlan_params.fm_pcd);
+ kparam->next_hmd = uparam->next_hmd;
+ kparam->hmd = uparam->hmd;
+
+ if (uparam->res.vlan_node)
+ kparam->res.vlan_node = compat_get_id2ptr(
+ uparam->res.vlan_node,
+ FM_MAP_TYPE_PCD_NODE);
+ else
+ kparam->res.vlan_node = NULL;
+
+ kparam->chain_head = uparam->chain_head;
+ kparam->modify_flags = uparam->modify_flags;
+
+ return 0;
+}
+
+int dpa_cls_hm_nat_params_compatcpy(
+ struct ioc_dpa_cls_hm_nat_params *kparam,
+ const struct compat_ioc_dpa_cls_hm_nat_params *uparam)
+{
+ int type;
+ kparam->nat_params.flags = uparam->nat_params.flags;
+ kparam->nat_params.proto = uparam->nat_params.proto;
+ kparam->nat_params.type = uparam->nat_params.type;
+
+ if (kparam->nat_params.type == DPA_CLS_HM_NAT_TYPE_NAT_PT) {
+ kparam->nat_params.nat_pt.type = uparam->nat_params.nat_pt.type;
+ type = kparam->nat_params.nat_pt.type;
+ switch (type) {
+ case DPA_CLS_HM_NAT_PT_IPv6_TO_IPv4:
+ kparam->nat_params.nat_pt.new_header.ipv4.options_size =
+ uparam->nat_params.nat_pt.new_header.ipv4.options_size;
+ kparam->nat_params.nat_pt.new_header.ipv4.options =
+ compat_ptr(uparam->nat_params.nat_pt.new_header.ipv4.
+ options);
+ memcpy(&kparam->nat_params.nat_pt.new_header.ipv4.
+ header, &uparam->nat_params.nat_pt.new_header.
+ ipv4.header, sizeof(struct iphdr));
+ break;
+ case DPA_CLS_HM_NAT_PT_IPv4_TO_IPv6:
+ memcpy(&kparam->nat_params.nat_pt.new_header.ipv6,
+ &uparam->nat_params.nat_pt.new_header.ipv6,
+ sizeof(struct ipv6_header));
+ break;
+ default:
+ break;
+ }
+ } else if (kparam->nat_params.type == DPA_CLS_HM_NAT_TYPE_TRADITIONAL)
+ memcpy(&kparam->nat_params.nat, &uparam->nat_params.nat,
+ sizeof(struct dpa_cls_hm_traditional_nat_params));
+
+ kparam->nat_params.fm_pcd = compat_ptr(uparam->nat_params.fm_pcd);
+ kparam->nat_params.sport = uparam->nat_params.sport;
+ kparam->nat_params.dport = uparam->nat_params.dport;
+ kparam->next_hmd = uparam->next_hmd;
+ kparam->hmd = uparam->hmd;
+
+ if (uparam->res.l3_update_node)
+ kparam->res.l3_update_node = compat_get_id2ptr(
+ uparam->res.l3_update_node,
+ FM_MAP_TYPE_PCD_NODE);
+ else
+ kparam->res.l3_update_node = NULL;
+
+ if (uparam->res.l4_update_node)
+ kparam->res.l4_update_node = compat_get_id2ptr(
+ uparam->res.l4_update_node,
+ FM_MAP_TYPE_PCD_NODE);
+ else
+ kparam->res.l4_update_node = NULL;
+
+ kparam->chain_head = uparam->chain_head;
+ kparam->modify_flags = uparam->modify_flags;
+
+ return 0;
+}
+
+int dpa_cls_hm_update_params_compatcpy(
+ struct ioc_dpa_cls_hm_update_params *kparam,
+ const struct compat_ioc_dpa_cls_hm_update_params *uparam)
+{
+ int op_flags;
+
+ kparam->update_params.op_flags = uparam->update_params.op_flags;
+ op_flags = kparam->update_params.op_flags;
+ memcpy(&kparam->update_params.update, &uparam->update_params.update,
+ sizeof(kparam->update_params.update));
+ memcpy(&kparam->update_params.ip_frag_params,
+ &uparam->update_params.ip_frag_params,
+ sizeof(kparam->update_params.ip_frag_params));
+
+ switch (op_flags) {
+ case DPA_CLS_HM_REPLACE_IPv4_BY_IPv6:
+ memcpy(&kparam->update_params.replace.new_ipv6_hdr,
+ &uparam->update_params.replace.new_ipv6_hdr,
+ sizeof(struct ipv6_header));
+ break;
+ case DPA_CLS_HM_REPLACE_IPv6_BY_IPv4:
+ kparam->update_params.replace.new_ipv4_hdr.options_size =
+ uparam->update_params.replace.new_ipv4_hdr.options_size;
+ kparam->update_params.replace.new_ipv4_hdr.options =
+ compat_ptr(uparam->update_params.replace.new_ipv4_hdr.
+ options);
+ memcpy(&kparam->update_params.replace.new_ipv4_hdr.header,
+ &uparam->update_params.replace.new_ipv4_hdr.header,
+ sizeof(struct iphdr));
+ break;
+ default:
+ break;
+ }
+
+
+ kparam->update_params.fm_pcd = compat_ptr(uparam->update_params.fm_pcd);
+ kparam->next_hmd = uparam->next_hmd;
+ kparam->hmd = uparam->hmd;
+
+ if (uparam->res.update_node)
+ kparam->res.update_node = compat_get_id2ptr(
+ uparam->res.update_node,
+ FM_MAP_TYPE_PCD_NODE);
+ else
+ kparam->res.update_node = NULL;
+
+ if (uparam->res.ip_frag_node)
+ kparam->res.ip_frag_node = compat_get_id2ptr(
+ uparam->res.ip_frag_node,
+ FM_MAP_TYPE_PCD_NODE);
+ else
+ kparam->res.ip_frag_node = NULL;
+
+ kparam->chain_head = uparam->chain_head;
+ kparam->modify_flags = uparam->modify_flags;
+
+ return 0;
+}
+
+int dpa_cls_hm_fwd_params_compatcpy(
+ struct ioc_dpa_cls_hm_fwd_params *kparam,
+ const struct compat_ioc_dpa_cls_hm_fwd_params *uparam)
+{
+ int type;
+
+ kparam->fwd_params.out_if_type = uparam->fwd_params.out_if_type;
+ kparam->fwd_params.fm_pcd = compat_ptr(uparam->fwd_params.fm_pcd);
+
+ type = kparam->fwd_params.out_if_type;
+ switch (type) {
+ case DPA_CLS_HM_IF_TYPE_ETHERNET:
+ memcpy(&kparam->fwd_params.eth, &uparam->fwd_params.eth,
+ sizeof(struct dpa_cls_hm_fwd_l2_param));
+ break;
+ case DPA_CLS_HM_IF_TYPE_PPPoE:
+ memcpy(&kparam->fwd_params.pppoe, &uparam->fwd_params.pppoe,
+ sizeof(struct dpa_cls_hm_fwd_pppoe_param));
+ break;
+ case DPA_CLS_HM_IF_TYPE_PPP:
+ memcpy(&kparam->fwd_params.ppp, &uparam->fwd_params.ppp,
+ sizeof(struct dpa_cls_hm_fwd_ppp_param));
+ break;
+ default:
+ break;
+ }
+
+ memcpy(&kparam->fwd_params.ip_frag_params,
+ &uparam->fwd_params.ip_frag_params,
+ sizeof(struct dpa_cls_hm_ip_frag_params));
+
+ kparam->next_hmd = uparam->next_hmd;
+ kparam->hmd = uparam->hmd;
+
+ if (uparam->res.fwd_node)
+ kparam->res.fwd_node = compat_get_id2ptr(uparam->res.fwd_node,
+ FM_MAP_TYPE_PCD_NODE);
+ else
+ kparam->res.fwd_node = NULL;
+
+ if (uparam->res.pppoe_node)
+ kparam->res.pppoe_node = compat_get_id2ptr(
+ uparam->res.pppoe_node,
+ FM_MAP_TYPE_PCD_NODE);
+ else
+ kparam->res.pppoe_node = NULL;
+
+ if (uparam->res.ip_frag_node)
+ kparam->res.ip_frag_node = compat_get_id2ptr(
+ uparam->res.ip_frag_node,
+ FM_MAP_TYPE_PCD_NODE);
+ else
+ kparam->res.ip_frag_node = NULL;
+
+ kparam->chain_head = uparam->chain_head;
+ kparam->modify_flags = uparam->modify_flags;
+
+ return 0;
+}
+
+int dpa_cls_hm_mpls_params_compatcpy(
+ struct ioc_dpa_cls_hm_mpls_params *kparam,
+ const struct compat_ioc_dpa_cls_hm_mpls_params *uparam)
+{
+ kparam->mpls_params.type = uparam->mpls_params.type;
+ memcpy(kparam->mpls_params.mpls_hdr, uparam->mpls_params.mpls_hdr,
+ sizeof(struct mpls_header) * DPA_CLS_HM_MAX_MPLS_LABELS);
+ kparam->mpls_params.num_labels = uparam->mpls_params.num_labels;
+ kparam->mpls_params.fm_pcd = compat_ptr(uparam->mpls_params.fm_pcd);
+ kparam->next_hmd = uparam->next_hmd;
+ kparam->hmd = uparam->hmd;
+
+ if (uparam->res.ins_rm_node)
+ kparam->res.ins_rm_node = compat_get_id2ptr(
+ uparam->res.ins_rm_node,
+ FM_MAP_TYPE_PCD_NODE);
+ else
+ kparam->res.ins_rm_node = NULL;
+
+ kparam->chain_head = uparam->chain_head;
+ kparam->modify_flags = uparam->modify_flags;
+
+ return 0;
+}
+
+int dpa_cls_mcast_group_params_compatcpy(
+ struct ioc_dpa_cls_mcast_group_params *kparam,
+ const struct compat_ioc_dpa_cls_mcast_group_params *uparam)
+{
+ kparam->mcast_grp_params.max_members =
+ uparam->mcast_grp_params.max_members;
+ kparam->mcast_grp_params.fm_pcd = compat_ptr(uparam->mcast_grp_params.
+ fm_pcd);
+ kparam->mcast_grp_params.first_member_params.override_fqid =
+ uparam->mcast_grp_params.first_member_params.override_fqid;
+ kparam->mcast_grp_params.first_member_params.new_fqid =
+ uparam->mcast_grp_params.first_member_params.new_fqid;
+ kparam->mcast_grp_params.first_member_params.new_rel_vsp_id =
+ uparam->mcast_grp_params.first_member_params.new_rel_vsp_id;
+ if (compat_ptr(uparam->mcast_grp_params.first_member_params.
+ policer_params)) {
+ if (copy_from_user(kparam->mcast_grp_params.first_member_params.
+ policer_params,
+ compat_ptr(uparam->mcast_grp_params.first_member_params.
+ policer_params),
+ sizeof(struct dpa_cls_tbl_policer_params))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: "
+ "policer params.\n", __FILE__, __func__,
+ __LINE__);
+ return -EBUSY;
+ }
+ } else
+ kparam->mcast_grp_params.first_member_params.policer_params =
+ NULL;
+
+ kparam->mcast_grp_params.first_member_params.hmd =
+ uparam->mcast_grp_params.first_member_params.hmd;
+ kparam->mcast_grp_params.prefilled_members =
+ uparam->mcast_grp_params.prefilled_members;
+
+ if (uparam->mcast_grp_params.group)
+ kparam->mcast_grp_params.group = compat_get_id2ptr(
+ uparam->mcast_grp_params.group,
+ FM_MAP_TYPE_PCD_NODE);
+ else
+ kparam->mcast_grp_params.group = NULL;
+
+ if (compat_ptr(uparam->mcast_grp_params.distribution))
+ kparam->mcast_grp_params.distribution = compat_get_id2ptr(
+ uparam->mcast_grp_params.distribution,
+ FM_MAP_TYPE_PCD_NODE);
+ else
+ kparam->mcast_grp_params.distribution = NULL;
+
+ if (compat_ptr(uparam->mcast_grp_params.classification))
+ kparam->mcast_grp_params.classification = compat_get_id2ptr(
+ uparam->mcast_grp_params.classification,
+ FM_MAP_TYPE_PCD_NODE);
+ else
+ kparam->mcast_grp_params.classification = NULL;
+
+ return 0;
+}
+
+int dpa_cls_mcast_member_params_compatcpy(
+ struct ioc_dpa_cls_mcast_member_params *kparam,
+ const struct compat_ioc_dpa_cls_mcast_member_params *uparam)
+{
+ kparam->grpd = uparam->grpd;
+ kparam->member_params.hmd = uparam->member_params.hmd;
+ kparam->member_params.new_fqid = uparam->member_params.new_fqid;
+ kparam->member_params.override_fqid =
+ uparam->member_params.override_fqid;
+ kparam->member_params.new_rel_vsp_id =
+ uparam->member_params.new_rel_vsp_id;
+ if (compat_ptr(uparam->member_params.policer_params)) {
+ if (copy_from_user(kparam->member_params.policer_params,
+ compat_ptr(uparam->member_params.policer_params),
+ sizeof(struct dpa_cls_tbl_policer_params))) {
+ pr_err("ERROR: %s, %s (%d): Read failed: "
+ "policer params.\n", __FILE__, __func__,
+ __LINE__);
+ return -EBUSY;
+ }
+ } else
+ kparam->member_params.policer_params = NULL;
+
+ return 0;
+}
+
+#endif /* CONFIG_COMPAT */
diff --git a/drivers/staging/fsl_dpa_offload/wrp_dpa_classifier.h b/drivers/staging/fsl_dpa_offload/wrp_dpa_classifier.h
new file mode 100644
index 0000000..411a332
--- /dev/null
+++ b/drivers/staging/fsl_dpa_offload/wrp_dpa_classifier.h
@@ -0,0 +1,86 @@
+
+/* 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.
+ */
+
+/*
+ * Internal DPA Classifier Wrapper Application Programming Interface
+ */
+
+#ifndef __WRP_DPA_CLASSIFIER_H
+#define __WRP_DPA_CLASSIFIER_H
+
+
+/* Other includes */
+#include "linux/fs.h"
+
+
+#define WRP_DPA_CLS_CDEVNAME "dpa_classifier"
+
+
+int wrp_dpa_classif_init(void);
+
+int wrp_dpa_classif_exit(void);
+
+int wrp_dpa_classif_open(struct inode *inode, struct file *filp);
+
+int wrp_dpa_classif_release(struct inode *inode, struct file *filp);
+
+ssize_t wrp_dpa_classif_read(
+ struct file *filp,
+ char __user *buf,
+ size_t len,
+ loff_t *offp);
+
+ssize_t wrp_dpa_classif_write(
+ struct file *filp,
+ const char __user *buf,
+ size_t len,
+ loff_t *offp);
+
+long wrp_dpa_classif_ioctl(
+ struct file *filp,
+ unsigned int cmd,
+ unsigned long args);
+
+long wrp_dpa_classif_do_ioctl(
+ struct file *filp,
+ unsigned int cmd,
+ unsigned long args,
+ bool compat_mode);
+
+#ifdef CONFIG_COMPAT
+long wrp_dpa_classif_compat_ioctl(
+ struct file *filp,
+ unsigned int cmd,
+ unsigned long args);
+#endif
+
+#endif /* __WRP_DPA_CLASSIFIER_H */