/* 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 Application Programming Interface. */ #ifndef __FSL_DPA_CLASSIFIER_H #define __FSL_DPA_CLASSIFIER_H /* DPA offloading layer includes */ #include "fsl_dpa_offload.h" /* General definitions */ /* Maximum number of VLAN tags supported by the insert header manipulation */ #define DPA_CLS_HM_MAX_VLANs 6 /* Maximum number of MPLS labels supported by the insert header manipulation */ #define DPA_CLS_HM_MAX_MPLS_LABELS 6 /* Standard size of the DSCP-to-VPri mapping table */ #define DPA_CLS_HM_DSCP_TO_VLAN_TABLE_SIZE 32 /* Number of entries in the DSCP-to-VPri mapping table */ #define DPA_CLS_HM_DSCP_TO_VPRI_TABLE_SIZE 64 /* API functions, definitions and enums */ /* Table API */ /* DPA Classifier Table Types */ enum dpa_cls_tbl_type { DPA_CLS_TBL_HASH = 0, /* HASH table */ DPA_CLS_TBL_INDEXED, /* Indexed table */ DPA_CLS_TBL_EXACT_MATCH /* Exact match table */ }; /* DPA Classifier Table Action Types */ enum dpa_cls_tbl_action_type { /* Unspecified action */ DPA_CLS_TBL_ACTION_NONE = 0, /* Drop frame */ DPA_CLS_TBL_ACTION_DROP, /* Send frame into a frame queue (enqueue) */ DPA_CLS_TBL_ACTION_ENQ, /* Go to another table and re-classify the packet */ DPA_CLS_TBL_ACTION_NEXT_TABLE, /* Send frames to a multicast group */ DPA_CLS_TBL_ACTION_MCAST }; /* DPA Classifier Table Entry Modification Types */ enum dpa_cls_tbl_modify_type { /* * Modify the entry key. This modification is supported only on exact * match tables. */ DPA_CLS_TBL_MODIFY_KEY = 0, /* Modify the entry action */ DPA_CLS_TBL_MODIFY_ACTION, /* * Modify the entry key and action. This modification is supported only * on exact match tables. */ DPA_CLS_TBL_MODIFY_KEY_AND_ACTION }; /* DPA Classifier Table Entry Management Types */ enum dpa_cls_tbl_entry_mgmt { /* * Manage entries by key (shadow table). The shadow table consumes more * RAM, but allows the user to do software lookups and refer to the * table entries by their key as well as by their reference (Id) */ DPA_CLS_TBL_MANAGE_BY_KEY = 0, /* * Manage entries by reference only (no shadow table). Saves memory and * speeds up runtime operations, but the user cannot do software * lookups and can only refer to the entries by their reference (Id) */ DPA_CLS_TBL_MANAGE_BY_REF, }; /* DPA Classifier HASH table parameters */ struct dpa_cls_tbl_hash_params { /* Number of sets (buckets) of the HASH table */ unsigned int num_sets; /* Number of ways of the HASH table (capability to resolve conflicts) */ unsigned int max_ways; /* HASH offset */ unsigned int hash_offs; /* Key size in bytes */ uint8_t key_size; }; /* DPA Classifier indexed table parameters */ struct dpa_cls_tbl_indexed_params { unsigned int entries_cnt; /* Number of entries in the table */ }; /* DPA Classifier exact match table parameters */ struct dpa_cls_tbl_exact_match_params { /* Number of entries in the table */ unsigned int entries_cnt; /* Key size in bytes */ uint8_t key_size; /* Use priorities for each entry in table if nonzero */ bool use_priorities; }; /* DPA Classifier table parameters */ struct dpa_cls_tbl_params { /* * Handle of the initial FM Cc node for this table * * This Cc node must be connected to a Cc tree. */ void *cc_node; /* * Handle to a FMan distribution to send frames to instead of * enqueuing frames. If this handle is provided (not NULL) the enqueue * action will only select the frame queue, but it will NOT actually * enqueue the frame to the selected frame queue. Instead it will send * the frame to the indicated distribution for further processing. */ void *distribution; /* * Handle to a FMan classification to send frames after distribution */ void *classification; /* The type of the DPA Classifier table */ enum dpa_cls_tbl_type type; /* Table entry management mechanism for runtime */ enum dpa_cls_tbl_entry_mgmt entry_mgmt; union { /* Parameters for HASH table */ struct dpa_cls_tbl_hash_params hash_params; /* Parameters for indexed table */ struct dpa_cls_tbl_indexed_params indexed_params; /* Parameters for exact match table */ struct dpa_cls_tbl_exact_match_params exact_match_params; }; /* * Number of entries in the table which are pre-filled from the * skeleton. The assumption is always that these entries are the first * entries in the table and with the highest priority. */ unsigned int prefilled_entries; }; /* Policer parameters */ struct dpa_cls_tbl_policer_params { /* [True] if the default policer parameters will be overridden */ bool modify_policer_params; /* [True] if this policer profile is shared between ports; relevant * only if [modify_policer_params] is set to [true]. */ bool shared_profile; /* * This parameter should indicate the policer profile offset within the * port's policer profiles or from the SHARED window; relevant only if * [modify_policer_params] is set to [true]. */ unsigned int new_rel_profile_id; }; /* Enqueue action parameters */ struct dpa_cls_tbl_enq_action_desc { /* * Override the frame queue Id from KeyGen and use the one * specified in this enqueue action descriptor if set to true */ bool override_fqid; /* * Id of the frame queue where to send the frames in case of * rule hit. */ uint32_t new_fqid; /* * Pointer to the policer parameters. If NULL, no policing is * applied during the enqueue. */ struct dpa_cls_tbl_policer_params *policer_params; /* * Descriptor of the header manipulation chain to use with this * entry. */ int hmd; /* * New virtual storage profile Id. This parameter is mandatory when * [override_fqid] is set to [true] and the port has virtual storage * profiles defined. Otherwise it is not used. */ uint8_t new_rel_vsp_id; }; /* Action parameters to route to a new classifier table */ struct dpa_cls_tbl_next_table_desc { /* * Descriptor of the next DPA Classifier table to continue * classification with */ int next_td; /* * Descriptor of the header manipulation chain to use before sending * the frames to the next table. */ int hmd; }; struct dpa_cls_tbl_mcast_group_desc { /* * Descriptor of the multicast group to use with a specific table entry. */ int grpd; /* * Descriptor of the header manipulation chain that will be performed * before sending the frames to the multicast group */ int hmd; }; /* DPA Classifier action descriptor */ struct dpa_cls_tbl_action { /* * Action type specifier. Drop action doesn't require any * further parameters */ enum dpa_cls_tbl_action_type type; /* Enable statistics for this entry if nonzero */ bool enable_statistics; union { /* Specific parameters for enqueue action */ struct dpa_cls_tbl_enq_action_desc enq_params; /* * Specific parameters for sending the frames to a new * classifier table */ struct dpa_cls_tbl_next_table_desc next_table_params; /* * Specific parameters for sending the frame to a multicast * group */ struct dpa_cls_tbl_mcast_group_desc mcast_params; }; }; /* DPA Classifier entry modification parameters */ struct dpa_cls_tbl_entry_mod_params { /* The type of modification */ enum dpa_cls_tbl_modify_type type; /* * The new key parameters to replace the existing key * parameters of the entry. Ignored for modify types which * do not refer to the key. */ struct dpa_offload_lookup_key *key; /* * The new action parameters to replace the existing action * parameters of the entry. Ignored for modify types which * do not refer to the action. */ struct dpa_cls_tbl_action *action; }; /* DPA Classifier table entry statistics */ struct dpa_cls_tbl_entry_stats { /* The total number of packets that have hit the entry */ uint32_t pkts; /* The total number of bytes that have hit the entry */ uint32_t bytes; }; /* * Creates and initializes a DPA Classifier table using a FMan * coarse classification node. Depending on the type of table, * this call can result in MURAM allocation. * * Once the DPA Classifier takes control of a FMan Cc node, all * its management must be performed through this API. If * applications use different APIs to modify the Cc node's * properties in the same time while the DPA Classifier has * ownership of the node, unpredictable behavior and data * inconsistency can occur. */ int dpa_classif_table_create(const struct dpa_cls_tbl_params *params, int *td); /* * Releases all resources associated with a DPA Classifier table * and destroys it. */ int dpa_classif_table_free(int td); /* Modifies the action taken in case of lookup miss condition. */ int dpa_classif_table_modify_miss_action(int td, const struct dpa_cls_tbl_action *miss_action); /* * Adds an entry (classification rule) in the specified DPA * Classifier table. If the MURAM for the table was pre-allocated, * this operation doesn't consume MURAM. * * The hardware currently doesn't support longest prefix match on * the exact match tables. If there are more entries in the * table that match the lookup (e.g. because of their mask) the * first one will always be returned by the hardware lookup. * * The priority parameter is meaningful only if [td] is an exact match table * with priority per entries. The priority value of the entry influences the * position of the entry in the table relative to the other entries. Entries * with lower priority values go to the top of the table. Priority values can * be negative. If two entries with the same priority are inserted in the * table, they will be positioned one after the other in the table, and the * older one first. */ int dpa_classif_table_insert_entry(int td, const struct dpa_offload_lookup_key *key, const struct dpa_cls_tbl_action *action, int priority, int *entry_id); /* * Modifies an entry in the specified DPA Classifier table. The * entry is identified by the lookup key. This function never * allocates new MURAM space. */ int dpa_classif_table_modify_entry_by_key(int td, const struct dpa_offload_lookup_key *key, const struct dpa_cls_tbl_entry_mod_params *mod_params); /* * Modifies an entry in the specified DPA Classifier table. The * entry is identified by its ref (Id). This function never * allocates new MURAM space. */ int dpa_classif_table_modify_entry_by_ref(int td, int entry_id, const struct dpa_cls_tbl_entry_mod_params *mod_params); /* * Removes an entry in the specified DPA Classifier table. The * entry is identified by the lookup key. If the MURAM for the * table was pre-allocated, this function doesn't free up any * MURAM space. */ int dpa_classif_table_delete_entry_by_key(int td, const struct dpa_offload_lookup_key *key); /* * Removes an entry in the specified DPA Classifier table. The * entry is identified by its ref (Id). If the MURAM for the * table was pre-allocated, this function doesn't free up any * MURAM space. */ int dpa_classif_table_delete_entry_by_ref(int td, int entry_id); /* * Performs a lookup in the specified table for an entry specified * by a key. If successful (i.e. the entry exists in that table) * the action descriptor for that entry is returned. * * Table lookup works only if entry management by key is selected * for the DPA Classifier table. * * This is not a hardware accelerated lookup. This lookup is * performed by the DPA Classifier in its internal shadow tables. * It is recommended to use this function with consideration. */ int dpa_classif_table_lookup_by_key(int td, const struct dpa_offload_lookup_key *key, struct dpa_cls_tbl_action *action); /* * Performs a lookup in the specified table for an entry specified * by its ref (Id). The action descriptor for that entry is * returned. * * Table lookup works only if entry management by key is selected * for the DPA Classifier table. */ int dpa_classif_table_lookup_by_ref(int td, int entry_id, struct dpa_cls_tbl_action *action); /* * Removes all the entries in a DPA Classifier Table. After this * operation is completed the entries cannot be recovered. */ int dpa_classif_table_flush(int td); /* * Returns the statistics for a specified entry in a specified * table. The entry is identified by the lookup key. */ int dpa_classif_table_get_entry_stats_by_key(int td, const struct dpa_offload_lookup_key *key, struct dpa_cls_tbl_entry_stats *stats); /* * Returns the statistics for a specified entry in a specified * table. The entry is identified by its ref (pointer). */ int dpa_classif_table_get_entry_stats_by_ref(int td, int entry_id, struct dpa_cls_tbl_entry_stats *stats); /* Returns the miss statistics for the specified table. */ int dpa_classif_table_get_miss_stats(int td, struct dpa_cls_tbl_entry_stats *stats); /* Returns the parameters of a classifier table. */ int dpa_classif_table_get_params(int td, struct dpa_cls_tbl_params *params); /* Header Manipulation API */ /* Supported protocols for NAT header manipulations */ enum dpa_cls_hm_nat_proto { DPA_CLS_NAT_PROTO_UDP, DPA_CLS_NAT_PROTO_TCP, DPA_CLS_NAT_PROTO_ICMP, DPA_CLS_NAT_PROTO_LAST_ENTRY }; /* NAT operation type */ enum dpa_cls_hm_nat_type { /* Traditional NAT */ DPA_CLS_HM_NAT_TYPE_TRADITIONAL, /* NAT w/ protocol translation */ DPA_CLS_HM_NAT_TYPE_NAT_PT, DPA_CLS_HM_NAT_TYPE_LAST_ENTRY }; /* * Flag values indicating the possible fields to be updated with the * NAT header manipulation */ enum dpa_cls_hm_nat_flags { DPA_CLS_HM_NAT_UPDATE_SIP = 0x01, DPA_CLS_HM_NAT_UPDATE_DIP = 0x02, DPA_CLS_HM_NAT_UPDATE_SPORT = 0x04, DPA_CLS_HM_NAT_UPDATE_DPORT = 0x08 }; /* Type of protocol translation for NAT */ enum dpa_cls_hm_nat_pt_type { DPA_CLS_HM_NAT_PT_IPv6_TO_IPv4, DPA_CLS_HM_NAT_PT_IPv4_TO_IPv6 }; /* * Flag values indicating which attributes of the NAT header manipulation to * modify */ enum dpa_cls_hm_nat_modify_flags { DPA_CLS_HM_NAT_MOD_FLAGS = 0x01, DPA_CLS_HM_NAT_MOD_SIP = 0x02, DPA_CLS_HM_NAT_MOD_DIP = 0x04, DPA_CLS_HM_NAT_MOD_SPORT = 0x08, DPA_CLS_HM_NAT_MOD_DPORT = 0x10, DPA_CLS_HM_NAT_MOD_IP_HDR = 0x20 }; /* NAT header manipulation low level driver resources */ struct dpa_cls_hm_nat_resources { /* * Handle to a header manipulation node which may combine a local * IPv4/IPv6 update header manipulation with an IP protocol replace. * This is a FMan driver header manipulation node handle and it is * mandatory for the import to succeed. */ void *l3_update_node; /* * Handle to the local TCP/UDP update header manipulation node. This is * a FMan driver header manipulation node handle and it is optional * (can be NULL in case no L4 header updates are necessary for this NAT * flow). */ void *l4_update_node; }; /* Traditional NAT parameters */ struct dpa_cls_hm_traditional_nat_params { /* New source IP address */ struct dpa_offload_ip_address sip; /* New destination IP address */ struct dpa_offload_ip_address dip; }; /* NAT-PT parameters */ struct dpa_cls_hm_nat_pt_params { /* * Specifies the protocol replacement for NAT-PT: either IPv4-to-IPv6 * or IPv6-to-IPv4 */ enum dpa_cls_hm_nat_pt_type type; union { /* New IPv4 header data to replace IPv6 with */ struct ipv4_header ipv4; /* New IPv6 header data to replace IPv4 with */ struct ipv6_header ipv6; } new_header; }; /* Definition of a NAT related header manipulation */ struct dpa_cls_hm_nat_params { /* * NAT operation flags specify which fields in the packet should be * updated. This is a combination of the values in the * dpa_cls_hm_nat_flags enum. */ int flags; /* Protocol to perform NAT for */ enum dpa_cls_hm_nat_proto proto; /* Selects the flavor of NAT to configure */ enum dpa_cls_hm_nat_type type; union { /* * Traditional NAT header manipulation parameters. Used only * when traditional NAT is selected using the [type] attribute. */ struct dpa_cls_hm_traditional_nat_params nat; /* * NAT-PT header manipulation parameters. Used only when NAT-PT * is selected using the [type] attribute. */ struct dpa_cls_hm_nat_pt_params nat_pt; }; /* * New L4 protocol source port number; used when selected using the * flags attribute. */ uint16_t sport; /* * New L4 protocol destination port number; used only when selected * using the flags attribute */ uint16_t dport; /* * Handle to the low level driver PCD to use when creating the header * manipulation object. */ void *fm_pcd; /* * Request re-parsing of the packet headers after this NAT. */ bool reparse; }; /* Output interface type for forwarding */ enum dpa_cls_hm_out_if_type { DPA_CLS_HM_IF_TYPE_ETHERNET, DPA_CLS_HM_IF_TYPE_PPPoE, DPA_CLS_HM_IF_TYPE_PPP, DPA_CLS_HM_IF_TYPE_LAST_ENTRY }; /* * Flag values indicating which forwarding header manipulation attributes to * modify */ enum dpa_cls_hm_fwd_modify_flags { DPA_CLS_HM_FWD_MOD_ETH_MACSA = 0x01, DPA_CLS_HM_FWD_MOD_ETH_MACDA = 0x02, DPA_CLS_HM_FWD_MOD_PPPoE_HEADER = 0x04, DPA_CLS_HM_FWD_MOD_PPP_PID = 0x08, DPA_CLS_HM_FWD_MOD_IP_FRAG_MTU = 0x10, DPA_CLS_HM_FWD_MOD_IP_FRAG_SCRATCH_BPID = 0x20, DPA_CLS_HM_FWD_MOD_IP_FRAG_DF_ACTION = 0x40 }; enum dpa_cls_hm_frag_df_action { DPA_CLS_HM_DF_ACTION_FRAG_ANYWAY, DPA_CLS_HM_DF_ACTION_DONT_FRAG, DPA_CLS_HM_DF_ACTION_DROP }; /* IP fragmentation parameters */ struct dpa_cls_hm_ip_frag_params { /* Maximum Transfer Unit. Use zero to disable IP fragmentation. */ uint16_t mtu; /* * Scratch buffer pool ID. This is necessary for the IP fragmentation * on FMan v2 devices only. On FMan v3 or newer devices this parameter * is ignored. It is also ignored if IP fragmentation is disabled. */ uint8_t scratch_bpid; /* Specifies how to deal with packets with DF flag on */ enum dpa_cls_hm_frag_df_action df_action; }; struct dpa_cls_hm_fwd_l2_param { /* New Ethernet destination MAC address to update the L2 header */ uint8_t macda[ETH_ALEN]; /* New Ethernet source MAC address to update the L2 header */ uint8_t macsa[ETH_ALEN]; }; /* Forwarding header manipulation parameters for a PPPoE output interface */ struct dpa_cls_hm_fwd_pppoe_param { /* L2 header update parameters */ struct dpa_cls_hm_fwd_l2_param l2; /* * PPPoE header to be inserted in the packets. The PPPoE payload length * field is updated automatically (you can set it to zero). */ struct pppoe_header pppoe_header; }; /* Forwarding header manipulation parameters for a PPP output interface */ struct dpa_cls_hm_fwd_ppp_param { /* PPP PID value to use in the PPP header to be inserted */ uint16_t ppp_pid; }; /* Forwarding header manipulation low level driver resources */ struct dpa_cls_hm_fwd_resources { /* * Handle to the forwarding header manipulation node. * * In case of an Ethernet or a PPPoE output interface this is a local * header replace header manipulation node (for Ethernet MAC addresses). * * In case of a PPP output interface this is a protocol specific header * removal node (for Ethernet and VLAN tags) combined with an internal * header insert. * * This is a FMan driver header manipulation node handle and it is * mandatory for the import to succeed. */ void *fwd_node; /* * Handle to the PPPoE specific node. This is an internal protocol * specific insert PPPoE header manipulation node. This is a FMan driver * header manipulation node handle and it is optional (can be NULL in * case the output interface type is not PPPoE). */ void *pppoe_node; /* * Handle to the IP fragmentation node. This is a FMan driver header * manipulation node handle and it is optional (can be NULL in case no * IP fragmentation is enabled for this IP forwarding flow). */ void *ip_frag_node; }; /* Forwarding header manipulation parameters */ struct dpa_cls_hm_fwd_params { /* * Output interface type. Based on this selection the DPA Classifier * decides which header manipulations are needed to perform forwarding. */ enum dpa_cls_hm_out_if_type out_if_type; union { /* Necessary parameters for an Ethernet output interface */ struct dpa_cls_hm_fwd_l2_param eth; /* Necessary parameters for a PPPoE output interface */ struct dpa_cls_hm_fwd_pppoe_param pppoe; /* Necessary parameters for a PPP output interface */ struct dpa_cls_hm_fwd_ppp_param ppp; }; /* Parameters related to optional IP fragmentation */ struct dpa_cls_hm_ip_frag_params ip_frag_params; /* * Handle to the low level driver PCD to use when creating the header * manipulation object. */ void *fm_pcd; /* * Request re-parsing of the packet headers after this forwarding * header manipulation. */ bool reparse; }; /* Types of the remove header manipulation operations */ enum dpa_cls_hm_remove_type { DPA_CLS_HM_REMOVE_ETHERNET, /* removes ETH and all QTags */ DPA_CLS_HM_REMOVE_PPPoE, /* removes ETH, all QTags and PPPoE */ DPA_CLS_HM_REMOVE_PPP, DPA_CLS_HM_REMOVE_CUSTOM, /* General remove */ DPA_CLS_HM_REMOVE_LAST_ENTRY }; /* * Flag values indicating which attributes of the remove header manipulation * to modify */ enum dpa_cls_hm_remove_modify_flags { DPA_CLS_HM_RM_MOD_TYPE = 0x01, DPA_CLS_HM_RM_MOD_CUSTOM_OFFSET = 0x02, DPA_CLS_HM_RM_MOD_CUSTOM_SIZE = 0x04 }; /* General (custom) remove header manipulation parameters */ struct dpa_cls_hm_custom_rm_params { /* * Offset in bytes, relative to the start of the packet, to start * removing data from */ uint8_t offset; /* The size in bytes of the section to remove */ uint8_t size; }; /* Ingress remove header manipulation low level driver resources */ struct dpa_cls_hm_remove_resources { /* * Handle to either a header removal node or a protocol specific header * removal node (for Ethernet and all VLAN tags). This is a FMan driver * header manipulation node handle and it is mandatory for the import * to succeed. */ void *remove_node; }; /* Ingress (remove) header manipulation parameters */ struct dpa_cls_hm_remove_params { /* * Selects the type of the remove header manipulation operation to * perform. Protocol specific header removals don't need any further * parameters. */ enum dpa_cls_hm_remove_type type; /* * Parameters for the custom remove header manipulation. If [type] is * anything else than "custom remove", these parameters are ignored */ struct dpa_cls_hm_custom_rm_params custom; /* * Handle to the low level driver PCD to use when creating the header * manipulation object. */ void *fm_pcd; /* * Request re-parsing of the packet headers after this header remove. */ bool reparse; }; /* Types of insert header manipulation operations */ enum dpa_cls_hm_insert_type { DPA_CLS_HM_INSERT_ETHERNET, /* Insert Ethernet + QTags */ DPA_CLS_HM_INSERT_PPPoE, /* Insert PPPoE, ETH and QTags */ DPA_CLS_HM_INSERT_PPP, DPA_CLS_HM_INSERT_CUSTOM, /* General insert */ DPA_CLS_HM_INSERT_LAST_ENTRY }; /* * Flag values indicating which attributes of the insert header manipulation * to modify */ enum dpa_cls_hm_insert_modify_flags { /* Ethernet and PPPoE insert group */ DPA_CLS_HM_INS_MOD_ETH_HEADER = 0x01, DPA_CLS_HM_INS_MOD_QTAGS = 0x02, DPA_CLS_HM_INS_MOD_PPPoE_HEADER = 0x04, /* PPP insert group */ DPA_CLS_HM_INS_MOD_PPP_PID = 0x08, /* Custom insert group */ DPA_CLS_HM_INS_MOD_CUSTOM_OFFSET = 0x10, DPA_CLS_HM_INS_MOD_CUSTOM_DATA = 0x20 }; /* General insert parameters */ struct dpa_cls_hm_custom_ins_params { /* * Offset in bytes relative to the start of the frame to insert new * header at. */ uint8_t offset; /* The size in bytes of the header to insert */ uint8_t size; /* * The data buffer containing the header to insert. This buffer must be * at least [size] bytes long */ const uint8_t *data; }; /* Egress insert header manipulation low level driver resources */ struct dpa_cls_hm_insert_resources { /* * Handle to either an internal header insert or an internal protocol * specific header insert node. This is a FMan driver header * manipulation node handle and it is mandatory for the import to * succeed. */ void *insert_node; }; /* Ethernet header insert params */ struct dpa_cls_hm_eth_ins_params { /* Ethernet header to insert */ struct ethhdr eth_header; /* * Number of VLAN tags to insert. If zero, no VLAN tags will be inserted * in the packet */ unsigned int num_tags; /* * Relevant only if [num_tags] is not zero. Contains an array with the * data of the VLAN QTags to insert */ struct vlan_header qtag[DPA_CLS_HM_MAX_VLANs]; }; /* PPPoE header insert params */ struct dpa_cls_hm_pppoe_ins_params { /* * Parameters of the Ethernet header to insert together with PPPoE * header */ struct dpa_cls_hm_eth_ins_params eth; /* PPPoE header to insert */ struct pppoe_header pppoe_header; }; /* Ethernet header insert params */ struct dpa_cls_hm_insert_params { /* Specifies the type of insert header manipulation */ enum dpa_cls_hm_insert_type type; union { /* * Ethernet header insert parameters if type is "insert * Ethernet" */ struct dpa_cls_hm_eth_ins_params eth; /* PPPoE header insert parameters if type is "insert PPPoE" */ struct dpa_cls_hm_pppoe_ins_params pppoe; /* * PPP PID value to use in the PPP header if type is "insert * PPP" */ uint16_t ppp_pid; /* * Custom insert header manipulation operation parameters. * These are relevant only if a custom insert header * manipulation operation is selected. */ struct dpa_cls_hm_custom_ins_params custom; }; /* * Handle to the low level driver PCD to use when creating the header * manipulation object. */ void *fm_pcd; /* * Request re-parsing of the packet headers after this header insert. */ bool reparse; }; /* Update header manipulation op flags */ enum dpa_cls_hm_update_op_flags { DPA_CLS_HM_UPDATE_NONE = 0, DPA_CLS_HM_UPDATE_IPv4_UPDATE = 0x01, DPA_CLS_HM_UPDATE_IPv6_UPDATE = 0x02, DPA_CLS_HM_UPDATE_UDP_TCP_UPDATE = 0x04, DPA_CLS_HM_REPLACE_IPv4_BY_IPv6 = 0x08, DPA_CLS_HM_REPLACE_IPv6_BY_IPv4 = 0x10 }; /* Update header manipulation field flags */ enum dpa_cls_hm_l3_field_flags { DPA_CLS_HM_IP_UPDATE_IPSA = 0x01, DPA_CLS_HM_IP_UPDATE_IPDA = 0x02, DPA_CLS_HM_IP_UPDATE_TOS_TC = 0x04, DPA_CLS_HM_IP_UPDATE_ID = 0x08, DPA_CLS_HM_IP_UPDATE_TTL_HOPL_DECREMENT = 0x10 }; /* L4 header update field flags */ enum dpa_cls_hm_l4_field_flags { DPA_CLS_HM_L4_UPDATE_SPORT = 0x01, DPA_CLS_HM_L4_UPDATE_DPORT = 0x02, DPA_CLS_HM_L4_UPDATE_CALCULATE_CKSUM = 0x04 }; /* * Flag values indicating which attributes of the update header manipulation * to modify */ enum dpa_cls_hm_update_modify_flags { DPA_CLS_HM_UPDATE_MOD_IPHDR = 0x0001, /* L3 protocol flags group */ DPA_CLS_HM_UPDATE_MOD_SIP = 0x0002, DPA_CLS_HM_UPDATE_MOD_DIP = 0x0004, DPA_CLS_HM_UPDATE_MOD_TOS_TC = 0x0008, DPA_CLS_HM_UPDATE_MOD_IP_ID = 0x0010, DPA_CLS_HM_UPDATE_MOD_L3_FLAGS = 0x0020, /* L4 protocol flags group */ DPA_CLS_HM_UPDATE_MOD_SPORT = 0x0040, DPA_CLS_HM_UPDATE_MOD_DPORT = 0x0080, DPA_CLS_HM_UPDATE_MOD_L4_FLAGS = 0x0100, DPA_CLS_HM_UPDATE_MOD_IP_FRAG_MTU = 0x0200, DPA_CLS_HM_UPDATE_MOD_IP_FRAG_SCRATCH_BPID = 0x0400, DPA_CLS_HM_UPDATE_MOD_IP_FRAG_DF_ACTION = 0x0800 }; /* L3 protocols field update parameters */ struct dpa_cls_hm_l3_update_params { /* New source IP address */ struct dpa_offload_ip_address ipsa; /* New destination IP address */ struct dpa_offload_ip_address ipda; /* New TOS (for IPv4) or Traffic Class (for IPv6) */ uint8_t tos_tc; /* * Initial IPv4 ID. This is used only if op_flags selected IPv4 update */ uint16_t initial_id; /* * A combination of flags designating the header fields to replace. The * available options are defined in the dpa_cls_hm_l3_field_flags enum */ int field_flags; }; /* L4 protocols field update parameters */ struct dpa_cls_hm_l4_update_params { uint16_t sport; /* new L4 source port value */ uint16_t dport; /* new L4 destination port value */ /* * A combination of flags designating the header fields to replace. The * available options are defined in the dpa_cls_hm_l4_field_flags enum */ int field_flags; }; /* Egress update header manipulation low level driver resources */ struct dpa_cls_hm_update_resources { /* * Handle to a header manipulation node with different header * manipulations enabled, depending on the options selected in the * parameters: local IPv4/IPv6 update header manipulation, a local * TCP/UDP update header manipulation and an internal IP header replace. * This is a FMan driver header manipulation node handle and it is * optional (can be NULL in case no L3 or L4 field updates or header * replace features are enabled for this flow) */ void *update_node; /* * Handle to the IP fragmentation node. This is a FMan driver header * manipulation node handle and it is optional (can be NULL in case no * IP fragmentation is enabled for this flow). */ void *ip_frag_node; }; /* Egress update header manipulation parameters */ struct dpa_cls_hm_update_params { /* * Flags defining the header manipulation operations to perform. They * are a combination of the flags defined in the * dpa_cls_hm_update_op_flags enum. */ int op_flags; union { /* * IPv4 header data. This header is used for IPv6 to IPv4 header * replace. */ struct ipv4_header new_ipv4_hdr; /* * IPv6 header data. This header is used for IPv4 to IPv6 * header replace. */ struct ipv6_header new_ipv6_hdr; } replace; union { /* * L3 protocol field values. This data is used for L3 protocol * header updates */ struct dpa_cls_hm_l3_update_params l3; /* * L4 protocol field values. This data is used for L4 protocol * header updates. */ struct dpa_cls_hm_l4_update_params l4; } update; /* * IP fragmentation parameters. This is an optional operation and can * be disabled. */ struct dpa_cls_hm_ip_frag_params ip_frag_params; /* * Handle to the low level driver PCD to use when creating the header * manipulation object. */ void *fm_pcd; /* * Request re-parsing of the packet headers after this header update. */ bool reparse; }; /* VLAN specific header manipulation operation types */ enum dpa_cls_hm_vlan_type { DPA_CLS_HM_VLAN_INGRESS, DPA_CLS_HM_VLAN_EGRESS, DPA_CLS_HM_VLAN_LAST_ENTRY }; /* Types of supported VLAN update operations */ enum dpa_cls_hm_vlan_update_type { DPA_CLS_HM_VLAN_UPDATE_NONE, DPA_CLS_HM_VLAN_UPDATE_VPri, /* manual VPri update */ DPA_CLS_HM_VLAN_UPDATE_VPri_BY_DSCP, DPA_CLS_HM_VLAN_UPDATE_LAST_ENTRY }; /* VLAN QTag identifier */ enum dpa_cls_hm_vlan_count { DPA_CLS_HM_VLAN_CNT_NONE, DPA_CLS_HM_VLAN_CNT_1QTAG, /* outer QTag */ DPA_CLS_HM_VLAN_CNT_2QTAGS, /* outer most 2 QTags */ DPA_CLS_HM_VLAN_CNT_3QTAGS, /* outer most 3 QTags */ DPA_CLS_HM_VLAN_CNT_4QTAGS, /* outer most 4 QTags */ DPA_CLS_HM_VLAN_CNT_5QTAGS, /* outer most 5 QTags */ DPA_CLS_HM_VLAN_CNT_6QTAGS, /* outer most 6 QTags */ DPA_CLS_HM_VLAN_CNT_ALL_QTAGS, DPA_CLS_HM_VLAN_CNT_LAST_ENTRY }; /* * Flag values indicating which attributes of the VLAN specific header * manipulation to modify */ enum dpa_cls_hm_vlan_modify_flags { /* This flag cannot be combined with any other flags */ DPA_CLS_HM_VLAN_MOD_INGRESS_NUM_QTAGS = 0x01, DPA_CLS_HM_VLAN_MOD_EGRESS_QTAGS = 0x02, DPA_CLS_HM_VLAN_MOD_EGRESS_UPDATE_OP = 0x04, DPA_CLS_HM_VLAN_MOD_EGRESS_VPRI = 0x08, DPA_CLS_HM_VLAN_MOD_EGRESS_DSCP_TO_VPRI_ARRAY = 0x10 }; /* Ingress VLAN specific header manipulation parameters */ struct dpa_cls_hm_ingress_vlan_params { /* Number of VLAN tags to remove */ enum dpa_cls_hm_vlan_count num_tags; }; /* Egress VLAN specific header manipulation parameters */ struct dpa_cls_hm_egress_vlan_params { enum dpa_cls_hm_vlan_update_type update_op; /* * Number of VLAN tags to insert. If zero, no VLAN tags will be * inserted in the packet. */ unsigned int num_tags; /* * Relevant only if [num_tags] is not zero. Contains an array with the * data of the VLAN tags to insert. */ struct vlan_header qtag[DPA_CLS_HM_MAX_VLANs]; union { /* * New VPri field value if [update_flag] selects manual VPri * update. */ uint8_t vpri; /* * DSCP-to-VPri mapping table to use for VPri field update if * [update_flag] selects VPri update by mapping to DSCP. */ uint8_t dscp_to_vpri[DPA_CLS_HM_DSCP_TO_VPRI_TABLE_SIZE]; } update; }; /* VLAN specific header manipulation low level resources */ struct dpa_cls_hm_vlan_resources { /* * Handle to a header manipulation node with different operations * depending on the selected type of VLAN specific header manipulation. * * In case of VLAN ingress header manipulation this is a VLAN protocol * specific removal node. * * In case of VLAN egress header manipulation this is a header * manipulation node which may combine an internal header insert (in * case there are VLANs to insert) with a protocol specific VLAN update * operation. * * This is a FMan driver header manipulation node handle and it is * mandatory for the import to succeed. */ void *vlan_node; }; /* VLAN specific header manipulation parameters */ struct dpa_cls_hm_vlan_params { /* Selects the type of the VLAN specific header manipulation */ enum dpa_cls_hm_vlan_type type; union { /* Parameters for ingress VLAN header manipulations */ struct dpa_cls_hm_ingress_vlan_params ingress; /* Parameters for egress VLAN header manipulations */ struct dpa_cls_hm_egress_vlan_params egress; }; /* * Handle to the low level driver PCD to use when creating the header * manipulation object. */ void *fm_pcd; /* * Request re-parsing of the packet headers after this VLAN header * update. */ bool reparse; }; /* MPLS specific header manipulation operation types */ enum dpa_cls_hm_mpls_type { DPA_CLS_HM_MPLS_INSERT_LABELS, DPA_CLS_HM_MPLS_REMOVE_ALL_LABELS, DPA_CLS_HM_MPLS_LAST_ENTRY }; /* * Flag values indicating which attributes of the MPLS specific header * manipulation to modify */ enum dpa_cls_hm_mpls_modify_flags { DPA_CLS_HM_MPLS_MOD_NUM_LABELS = 0x01, DPA_CLS_HM_MPLS_MOD_HDR_ARRAY = 0x02, }; /* MPLS specific header manipulation low level driver resources */ struct dpa_cls_hm_mpls_resources { /* * Handle to the protocol specific header insert (MPLS) or to the * protocol specific header removal (MPLS) node. This is a FMan driver * header manipulation node handle and it is mandatory for the import * to succeed. */ void *ins_rm_node; }; /* MPLS specific header manipulation parameters */ struct dpa_cls_hm_mpls_params { /* Specifies the type of header manipulation */ enum dpa_cls_hm_mpls_type type; /* * Stores the MPLS labels to insert if the operation type is "insert * MPLS labels" */ struct mpls_header mpls_hdr[DPA_CLS_HM_MAX_MPLS_LABELS]; /* * Number of MPLS labels to insert. This is relevant only if the * operation type is "insert MPLS labels" */ unsigned int num_labels; /* * Handle to the low level driver PCD to use when creating the header * manipulation object. */ void *fm_pcd; /* * Request re-parsing of the packet headers after this MPLS header * update. */ bool reparse; }; /* * Creates or imports a NAT type header manipulation object. If the function is * successful it returns at the [hmd] location the descriptor of the created * header manipulation object. * * If the [res] parameter is provided, the function will import the low level * driver resources specified therein rather than create them. In this case the * [fm_pcd] handle in the parameters structure is not used and can be provided * as NULL. When working in this mode the function doesn't allocate MURAM. */ int dpa_classif_set_nat_hm(const struct dpa_cls_hm_nat_params *nat_params, int next_hmd, int *hmd, bool chain_head, const struct dpa_cls_hm_nat_resources *res); /* * Modify the parameters of an existing NAT header manipulation. * * [modify_flags] is a combination of flags indicating which header manipulation * attributes to modify (and hence indicating which of the attributes in the * [new_nat_params] data structure are valid). Select the flag values from the * dpa_cls_hm_nat_modify_flags enum and combine them using the "or" logical * operand. */ int dpa_classif_modify_nat_hm(int hmd, const struct dpa_cls_hm_nat_params *new_nat_params, int modify_flags); /* * Creates or imports a forwarding type header manipulation object. DPA * Classifier takes into account an Ethernet/IP frame to start with and, * depending on the selection of output interface type, it decides what header * manipulations are necessary. * * If the [res] parameter is provided, the function will import the low level * driver resources specified therein rather than create them. In this case the * [fm_pcd] handle in the parameters structure is not used and can be provided * as NULL. When working in this mode the function doesn't allocate MURAM. */ int dpa_classif_set_fwd_hm(const struct dpa_cls_hm_fwd_params *fwd_params, int next_hmd, int *hmd, bool chain_head, const struct dpa_cls_hm_fwd_resources *res); /* * Modify the parameters of an existing forwarding type header manipulation. * * [modify_flags] is a combination of flags indicating which header manipulation * attributes to modify (and hence indicating which of the attributes in the * [new_fwd_params] data structure are valid). Select the flag values from the * dpa_cls_hm_fwd_modify_flags enum and combine them using the "or" logical * operand. */ int dpa_classif_modify_fwd_hm(int hmd, const struct dpa_cls_hm_fwd_params *new_fwd_params, int modify_flags); /* Creates or imports a remove type header manipulation object. * * If the [res] parameter is provided, the function will import the low level * driver resources specified therein rather than create them. In this case the * [fm_pcd] handle in the parameters structure is not used and can be provided * as NULL. When working in this mode the function doesn't allocate MURAM. */ int dpa_classif_set_remove_hm(const struct dpa_cls_hm_remove_params *remove_params, int next_hmd, int *hmd, bool chain_head, const struct dpa_cls_hm_remove_resources *res); /* * Modify the parameters of an existing remove type header manipulation. * * [modify_flags] is a combination of flags indicating which header manipulation * attributes to modify (and hence indicating which of the attributes in the * [new_remove_params] data structure are valid). Select the flag values from * the dpa_cls_hm_remove_modify_flags enum and combine them using the "or" * logical operand. */ int dpa_classif_modify_remove_hm(int hmd, const struct dpa_cls_hm_remove_params *new_remove_params, int modify_flags); /* * Creates or imports an insert type header manipulation object. * * If the [res] parameter is provided, the function will import the low level * driver resources specified therein rather than create them. In this case the * [fm_pcd] handle in the parameters structure is not used and can be provided * as NULL. When working in this mode the function doesn't allocate MURAM. */ int dpa_classif_set_insert_hm(const struct dpa_cls_hm_insert_params *insert_params, int next_hmd, int *hmd, bool chain_head, const struct dpa_cls_hm_insert_resources *res); /* * Modify the parameters of an existing insert header manipulation. * * [modify_flags] is a combination of flags indicating which header manipulation * attributes to modify (and hence indicating which of the attributes in the * [new_insert_params] data structure are valid). Select the flag values from * the dpa_cls_hm_insert_modify_flags enum and combine them using the "or" * logical operand. */ int dpa_classif_modify_insert_hm(int hmd, const struct dpa_cls_hm_insert_params *new_insert_params, int modify_flags); /* * Creates or imports an update type header manipulation object. * * If the [res] parameter is provided, the function will import the low level * driver resources specified therein rather than create them. In this case the * [fm_pcd] handle in the parameters structure is not used and can be provided * as NULL. When working in this mode the function doesn't allocate MURAM. */ int dpa_classif_set_update_hm(const struct dpa_cls_hm_update_params *update_params, int next_hmd, int *hmd, bool chain_head, const struct dpa_cls_hm_update_resources *res); /* * Modify the parameters of an existing update header manipulation. * * [modify_flags] is a combination of flags indicating which header manipulation * attributes to modify (and hence indicating which of the attributes in the * [new_update_params] data structure are valid). Select the flag values from * the dpa_cls_hm_update_modify_flags enum and combine them using the "or" * logical operand. */ int dpa_classif_modify_update_hm(int hmd, const struct dpa_cls_hm_update_params *new_update_params, int modify_flags); /* * Creates or imports a VLAN specific header manipulation (either ingress or * egress) object. * * If the [res] parameter is provided, the function will import the low level * driver resources specified therein rather than create them. In this case the * [fm_pcd] handle in the parameters structure is not used and can be provided * as NULL. When working in this mode the function doesn't allocate MURAM. */ int dpa_classif_set_vlan_hm(const struct dpa_cls_hm_vlan_params *vlan_params, int next_hmd, int *hmd, bool chain_head, const struct dpa_cls_hm_vlan_resources *res); /* * Modify the parameters of an existing VLAN specific header manipulation. * * [modify_flags] is a combination of flags indicating which header manipulation * attributes to modify (and hence indicating which of the attributes in the * [new_vlan_params] data structure are valid). Select the flag values from the * dpa_cls_hm_vlan_modify_flags enum and combine them using the "or" logical * operand. */ int dpa_classif_modify_vlan_hm(int hmd, const struct dpa_cls_hm_vlan_params *new_vlan_params, int modify_flags); /* * Creates or imports a MPLS specific header manipulation object. * * If the [res] parameter is provided, the function will import the low level * driver resources specified therein rather than create them. In this case the * [fm_pcd] handle in the parameters structure is not used and can be provided * as NULL. When working in this mode the function doesn't allocate MURAM. */ int dpa_classif_set_mpls_hm(const struct dpa_cls_hm_mpls_params *mpls_params, int next_hmd, int *hmd, bool chain_head, const struct dpa_cls_hm_mpls_resources *res); /* * Modify the parameters of an existing MPLS specific header manipulation. * * [modify_flags] is a combination of flags indicating which header manipulation * attributes to modify (and hence indicating which of the attributes in the * [new_mpls_params] data structure are valid). Select the flag values from the * dpa_cls_hm_mpls_modify_flags enum and combine them using the "or" logical * operand. */ int dpa_classif_modify_mpls_hm(int hmd, const struct dpa_cls_hm_mpls_params *new_mpls_params, int modify_flags); /* * Releases a header manipulation object and frees up all related resources * allocated for it. The header manipulation operations must be removed in the * reverse order they were created in (i.e. starting with the header * manipulation chain head and working towards the tail). */ int dpa_classif_free_hm(int hmd); /* * Multicast API */ /* * Multicast group parameters */ struct dpa_cls_mcast_group_params { /* * Maximum number of members in group */ uint8_t max_members; /* * Handle of the FM PCD that owns the Cc node that will * point to the group */ void *fm_pcd; /* * Member parameters. A group must have at least * one member */ struct dpa_cls_tbl_enq_action_desc first_member_params; /* * Number of members that already exist in the imported group */ unsigned int prefilled_members; /* * External distribution handle. When provided, replicated frames * are not enqueued to members' frame queues. They are sent to this * distribution. */ void *distribution; /* * Handle to a FMan classification to send frames after distribution */ void *classification; }; /* Multicast group external resource */ struct dpa_cls_mcast_group_resources { /* * Multicast group handle used when importing an external group node */ void *group_node; }; /* * Creates a multicast group with one member */ int dpa_classif_mcast_create_group( const struct dpa_cls_mcast_group_params *group_params, int *grpd, const struct dpa_cls_mcast_group_resources *res); /* * Adds a new member to a multicast group */ int dpa_classif_mcast_add_member(int grpd, const struct dpa_cls_tbl_enq_action_desc *member_params, int *md); /* * Removes a member from a multicast group */ int dpa_classif_mcast_remove_member(int grpd, int md); /* * Removes an existing group */ int dpa_classif_mcast_free_group(int grpd); #endif /* __FSL_DPA_CLASSIFIER_H */