Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * RSS and Classifier definitions for Marvell PPv2 Network Controller
0004  *
0005  * Copyright (C) 2014 Marvell
0006  *
0007  * Marcin Wojtas <mw@semihalf.com>
0008  */
0009 
0010 #ifndef _MVPP2_CLS_H_
0011 #define _MVPP2_CLS_H_
0012 
0013 #include "mvpp2.h"
0014 #include "mvpp2_prs.h"
0015 
0016 /* Classifier constants */
0017 #define MVPP2_CLS_FLOWS_TBL_SIZE    512
0018 #define MVPP2_CLS_FLOWS_TBL_DATA_WORDS  3
0019 #define MVPP2_CLS_LKP_TBL_SIZE      64
0020 #define MVPP2_CLS_RX_QUEUES     256
0021 
0022 /* Classifier flow constants */
0023 
0024 #define MVPP2_FLOW_N_FIELDS     4
0025 
0026 enum mvpp2_cls_engine {
0027     MVPP22_CLS_ENGINE_C2 = 1,
0028     MVPP22_CLS_ENGINE_C3A,
0029     MVPP22_CLS_ENGINE_C3B,
0030     MVPP22_CLS_ENGINE_C4,
0031     MVPP22_CLS_ENGINE_C3HA = 6,
0032     MVPP22_CLS_ENGINE_C3HB = 7,
0033 };
0034 
0035 #define MVPP22_CLS_HEK_OPT_MAC_DA   BIT(0)
0036 #define MVPP22_CLS_HEK_OPT_VLAN_PRI BIT(1)
0037 #define MVPP22_CLS_HEK_OPT_VLAN     BIT(2)
0038 #define MVPP22_CLS_HEK_OPT_L3_PROTO BIT(3)
0039 #define MVPP22_CLS_HEK_OPT_IP4SA    BIT(4)
0040 #define MVPP22_CLS_HEK_OPT_IP4DA    BIT(5)
0041 #define MVPP22_CLS_HEK_OPT_IP6SA    BIT(6)
0042 #define MVPP22_CLS_HEK_OPT_IP6DA    BIT(7)
0043 #define MVPP22_CLS_HEK_OPT_L4SIP    BIT(8)
0044 #define MVPP22_CLS_HEK_OPT_L4DIP    BIT(9)
0045 #define MVPP22_CLS_HEK_N_FIELDS     10
0046 
0047 #define MVPP22_CLS_HEK_L4_OPTS  (MVPP22_CLS_HEK_OPT_L4SIP | \
0048                  MVPP22_CLS_HEK_OPT_L4DIP)
0049 
0050 #define MVPP22_CLS_HEK_IP4_2T   (MVPP22_CLS_HEK_OPT_IP4SA | \
0051                  MVPP22_CLS_HEK_OPT_IP4DA)
0052 
0053 #define MVPP22_CLS_HEK_IP6_2T   (MVPP22_CLS_HEK_OPT_IP6SA | \
0054                  MVPP22_CLS_HEK_OPT_IP6DA)
0055 
0056 /* The fifth tuple in "5T" is the L4_Info field */
0057 #define MVPP22_CLS_HEK_IP4_5T   (MVPP22_CLS_HEK_IP4_2T | \
0058                  MVPP22_CLS_HEK_L4_OPTS)
0059 
0060 #define MVPP22_CLS_HEK_IP6_5T   (MVPP22_CLS_HEK_IP6_2T | \
0061                  MVPP22_CLS_HEK_L4_OPTS)
0062 
0063 #define MVPP22_CLS_HEK_TAGGED   (MVPP22_CLS_HEK_OPT_VLAN | \
0064                  MVPP22_CLS_HEK_OPT_VLAN_PRI)
0065 
0066 enum mvpp2_cls_field_id {
0067     MVPP22_CLS_FIELD_MAC_DA = 0x03,
0068     MVPP22_CLS_FIELD_VLAN_PRI = 0x05,
0069     MVPP22_CLS_FIELD_VLAN = 0x06,
0070     MVPP22_CLS_FIELD_L3_PROTO = 0x0f,
0071     MVPP22_CLS_FIELD_IP4SA = 0x10,
0072     MVPP22_CLS_FIELD_IP4DA = 0x11,
0073     MVPP22_CLS_FIELD_IP6SA = 0x17,
0074     MVPP22_CLS_FIELD_IP6DA = 0x1a,
0075     MVPP22_CLS_FIELD_L4SIP = 0x1d,
0076     MVPP22_CLS_FIELD_L4DIP = 0x1e,
0077 };
0078 
0079 /* Classifier C2 engine constants */
0080 #define MVPP22_CLS_C2_TCAM_EN(data)     ((data) << 16)
0081 
0082 enum mvpp22_cls_c2_action {
0083     MVPP22_C2_NO_UPD = 0,
0084     MVPP22_C2_NO_UPD_LOCK,
0085     MVPP22_C2_UPD,
0086     MVPP22_C2_UPD_LOCK,
0087 };
0088 
0089 enum mvpp22_cls_c2_fwd_action {
0090     MVPP22_C2_FWD_NO_UPD = 0,
0091     MVPP22_C2_FWD_NO_UPD_LOCK,
0092     MVPP22_C2_FWD_SW,
0093     MVPP22_C2_FWD_SW_LOCK,
0094     MVPP22_C2_FWD_HW,
0095     MVPP22_C2_FWD_HW_LOCK,
0096     MVPP22_C2_FWD_HW_LOW_LAT,
0097     MVPP22_C2_FWD_HW_LOW_LAT_LOCK,
0098 };
0099 
0100 enum mvpp22_cls_c2_color_action {
0101     MVPP22_C2_COL_NO_UPD = 0,
0102     MVPP22_C2_COL_NO_UPD_LOCK,
0103     MVPP22_C2_COL_GREEN,
0104     MVPP22_C2_COL_GREEN_LOCK,
0105     MVPP22_C2_COL_YELLOW,
0106     MVPP22_C2_COL_YELLOW_LOCK,
0107     MVPP22_C2_COL_RED,      /* Drop */
0108     MVPP22_C2_COL_RED_LOCK,     /* Drop */
0109 };
0110 
0111 #define MVPP2_CLS_C2_TCAM_WORDS         5
0112 #define MVPP2_CLS_C2_ATTR_WORDS         5
0113 
0114 struct mvpp2_cls_c2_entry {
0115     u32 index;
0116     /* TCAM lookup key */
0117     u32 tcam[MVPP2_CLS_C2_TCAM_WORDS];
0118     /* Actions to perform upon TCAM match */
0119     u32 act;
0120     /* Attributes relative to the actions to perform */
0121     u32 attr[MVPP2_CLS_C2_ATTR_WORDS];
0122     /* Entry validity */
0123     u8 valid;
0124 };
0125 
0126 #define MVPP22_FLOW_ETHER_BIT   BIT(0)
0127 #define MVPP22_FLOW_IP4_BIT BIT(1)
0128 #define MVPP22_FLOW_IP6_BIT BIT(2)
0129 #define MVPP22_FLOW_TCP_BIT BIT(3)
0130 #define MVPP22_FLOW_UDP_BIT BIT(4)
0131 
0132 #define MVPP22_FLOW_TCP4    (MVPP22_FLOW_ETHER_BIT | MVPP22_FLOW_IP4_BIT | MVPP22_FLOW_TCP_BIT)
0133 #define MVPP22_FLOW_TCP6    (MVPP22_FLOW_ETHER_BIT | MVPP22_FLOW_IP6_BIT | MVPP22_FLOW_TCP_BIT)
0134 #define MVPP22_FLOW_UDP4    (MVPP22_FLOW_ETHER_BIT | MVPP22_FLOW_IP4_BIT | MVPP22_FLOW_UDP_BIT)
0135 #define MVPP22_FLOW_UDP6    (MVPP22_FLOW_ETHER_BIT | MVPP22_FLOW_IP6_BIT | MVPP22_FLOW_UDP_BIT)
0136 #define MVPP22_FLOW_IP4     (MVPP22_FLOW_ETHER_BIT | MVPP22_FLOW_IP4_BIT)
0137 #define MVPP22_FLOW_IP6     (MVPP22_FLOW_ETHER_BIT | MVPP22_FLOW_IP6_BIT)
0138 #define MVPP22_FLOW_ETHERNET    (MVPP22_FLOW_ETHER_BIT)
0139 
0140 /* Classifier C2 engine entries */
0141 #define MVPP22_CLS_C2_N_ENTRIES     256
0142 
0143 /* Number of per-port dedicated entries in the C2 TCAM */
0144 #define MVPP22_CLS_C2_PORT_N_FLOWS  MVPP2_N_RFS_ENTRIES_PER_FLOW
0145 
0146 /* Each port has one range per flow type + one entry controlling the global RSS
0147  * setting and the default rx queue
0148  */
0149 #define MVPP22_CLS_C2_PORT_RANGE    (MVPP22_CLS_C2_PORT_N_FLOWS + 1)
0150 #define MVPP22_CLS_C2_PORT_FIRST(p) ((p) * MVPP22_CLS_C2_PORT_RANGE)
0151 #define MVPP22_CLS_C2_RSS_ENTRY(p)  (MVPP22_CLS_C2_PORT_FIRST((p) + 1) - 1)
0152 
0153 #define MVPP22_CLS_C2_PORT_FLOW_FIRST(p)    (MVPP22_CLS_C2_PORT_FIRST(p))
0154 
0155 #define MVPP22_CLS_C2_RFS_LOC(p, loc)   (MVPP22_CLS_C2_PORT_FLOW_FIRST(p) + (loc))
0156 
0157 /* Packet flow ID */
0158 enum mvpp2_prs_flow {
0159     MVPP2_FL_START = 8,
0160     MVPP2_FL_IP4_TCP_NF_UNTAG = MVPP2_FL_START,
0161     MVPP2_FL_IP4_UDP_NF_UNTAG,
0162     MVPP2_FL_IP4_TCP_NF_TAG,
0163     MVPP2_FL_IP4_UDP_NF_TAG,
0164     MVPP2_FL_IP6_TCP_NF_UNTAG,
0165     MVPP2_FL_IP6_UDP_NF_UNTAG,
0166     MVPP2_FL_IP6_TCP_NF_TAG,
0167     MVPP2_FL_IP6_UDP_NF_TAG,
0168     MVPP2_FL_IP4_TCP_FRAG_UNTAG,
0169     MVPP2_FL_IP4_UDP_FRAG_UNTAG,
0170     MVPP2_FL_IP4_TCP_FRAG_TAG,
0171     MVPP2_FL_IP4_UDP_FRAG_TAG,
0172     MVPP2_FL_IP6_TCP_FRAG_UNTAG,
0173     MVPP2_FL_IP6_UDP_FRAG_UNTAG,
0174     MVPP2_FL_IP6_TCP_FRAG_TAG,
0175     MVPP2_FL_IP6_UDP_FRAG_TAG,
0176     MVPP2_FL_IP4_UNTAG, /* non-TCP, non-UDP, same for below */
0177     MVPP2_FL_IP4_TAG,
0178     MVPP2_FL_IP6_UNTAG,
0179     MVPP2_FL_IP6_TAG,
0180     MVPP2_FL_NON_IP_UNTAG,
0181     MVPP2_FL_NON_IP_TAG,
0182     MVPP2_FL_LAST,
0183 };
0184 
0185 /* LU Type defined for all engines, and specified in the flow table */
0186 #define MVPP2_CLS_LU_TYPE_MASK          0x3f
0187 
0188 enum mvpp2_cls_lu_type {
0189     /* rule->loc is used as a lu-type for the entries 0 - 62. */
0190     MVPP22_CLS_LU_TYPE_ALL = 63,
0191 };
0192 
0193 #define MVPP2_N_FLOWS       (MVPP2_FL_LAST - MVPP2_FL_START)
0194 
0195 struct mvpp2_cls_flow {
0196     /* The L2-L4 traffic flow type */
0197     int flow_type;
0198 
0199     /* The first id in the flow table for this flow */
0200     u16 flow_id;
0201 
0202     /* The supported HEK fields for this flow */
0203     u16 supported_hash_opts;
0204 
0205     /* The Header Parser result_info that matches this flow */
0206     struct mvpp2_prs_result_info prs_ri;
0207 };
0208 
0209 #define MVPP2_CLS_FLT_ENTRIES_PER_FLOW      (MVPP2_MAX_PORTS + 1 + 16)
0210 #define MVPP2_CLS_FLT_FIRST(id)         (((id) - MVPP2_FL_START) * \
0211                          MVPP2_CLS_FLT_ENTRIES_PER_FLOW)
0212 
0213 #define MVPP2_CLS_FLT_C2_RFS(port, id, rfs_n)   (MVPP2_CLS_FLT_FIRST(id) + \
0214                          ((port) * MVPP2_MAX_PORTS) + \
0215                          (rfs_n))
0216 
0217 #define MVPP2_CLS_FLT_C2_RSS_ENTRY(id)      (MVPP2_CLS_FLT_C2_RFS(MVPP2_MAX_PORTS, id, 0))
0218 #define MVPP2_CLS_FLT_HASH_ENTRY(port, id)  (MVPP2_CLS_FLT_C2_RSS_ENTRY(id) + 1 + (port))
0219 #define MVPP2_CLS_FLT_LAST(id)          (MVPP2_CLS_FLT_FIRST(id) + \
0220                          MVPP2_CLS_FLT_ENTRIES_PER_FLOW - 1)
0221 
0222 /* Iterate on each classifier flow id. Sets 'i' to be the index of the first
0223  * entry in the cls_flows table for each different flow_id.
0224  * This relies on entries having the same flow_id in the cls_flows table being
0225  * contiguous.
0226  */
0227 #define for_each_cls_flow_id(i)                           \
0228     for ((i) = 0; (i) < MVPP2_N_PRS_FLOWS; (i)++)                 \
0229         if ((i) > 0 &&                            \
0230             cls_flows[(i)].flow_id == cls_flows[(i) - 1].flow_id)       \
0231             continue;                         \
0232         else
0233 
0234 /* Iterate on each classifier flow that has a given flow_type. Sets 'i' to be
0235  * the index of the first entry in the cls_flow table for each different flow_id
0236  * that has the given flow_type. This allows to operate on all flows that
0237  * matches a given ethtool flow type.
0238  */
0239 #define for_each_cls_flow_id_with_type(i, type)                   \
0240     for_each_cls_flow_id((i))                         \
0241         if (cls_flows[(i)].flow_type != (type))               \
0242             continue;                         \
0243         else
0244 
0245 #define for_each_cls_flow_id_containing_type(i, type)                 \
0246     for_each_cls_flow_id((i))                         \
0247         if ((cls_flows[(i)].flow_type & (type)) != (type))        \
0248             continue;                         \
0249         else
0250 
0251 struct mvpp2_cls_flow_entry {
0252     u32 index;
0253     u32 data[MVPP2_CLS_FLOWS_TBL_DATA_WORDS];
0254 };
0255 
0256 struct mvpp2_cls_lookup_entry {
0257     u32 lkpid;
0258     u32 way;
0259     u32 data;
0260 };
0261 
0262 int mvpp22_port_rss_init(struct mvpp2_port *port);
0263 
0264 int mvpp22_port_rss_enable(struct mvpp2_port *port);
0265 int mvpp22_port_rss_disable(struct mvpp2_port *port);
0266 
0267 int mvpp22_port_rss_ctx_create(struct mvpp2_port *port, u32 *rss_ctx);
0268 int mvpp22_port_rss_ctx_delete(struct mvpp2_port *port, u32 rss_ctx);
0269 
0270 int mvpp22_port_rss_ctx_indir_set(struct mvpp2_port *port, u32 rss_ctx,
0271                   const u32 *indir);
0272 int mvpp22_port_rss_ctx_indir_get(struct mvpp2_port *port, u32 rss_ctx,
0273                   u32 *indir);
0274 
0275 int mvpp2_ethtool_rxfh_get(struct mvpp2_port *port, struct ethtool_rxnfc *info);
0276 int mvpp2_ethtool_rxfh_set(struct mvpp2_port *port, struct ethtool_rxnfc *info);
0277 
0278 void mvpp2_cls_init(struct mvpp2 *priv);
0279 
0280 void mvpp2_cls_port_config(struct mvpp2_port *port);
0281 
0282 void mvpp2_cls_oversize_rxq_set(struct mvpp2_port *port);
0283 
0284 int mvpp2_cls_flow_eng_get(struct mvpp2_cls_flow_entry *fe);
0285 
0286 u16 mvpp2_flow_get_hek_fields(struct mvpp2_cls_flow_entry *fe);
0287 
0288 const struct mvpp2_cls_flow *mvpp2_cls_flow_get(int flow);
0289 
0290 u32 mvpp2_cls_flow_hits(struct mvpp2 *priv, int index);
0291 
0292 void mvpp2_cls_flow_read(struct mvpp2 *priv, int index,
0293              struct mvpp2_cls_flow_entry *fe);
0294 
0295 u32 mvpp2_cls_lookup_hits(struct mvpp2 *priv, int index);
0296 
0297 void mvpp2_cls_lookup_read(struct mvpp2 *priv, int lkpid, int way,
0298                struct mvpp2_cls_lookup_entry *le);
0299 
0300 u32 mvpp2_cls_c2_hit_count(struct mvpp2 *priv, int c2_index);
0301 
0302 void mvpp2_cls_c2_read(struct mvpp2 *priv, int index,
0303                struct mvpp2_cls_c2_entry *c2);
0304 
0305 int mvpp2_ethtool_cls_rule_get(struct mvpp2_port *port,
0306                    struct ethtool_rxnfc *rxnfc);
0307 
0308 int mvpp2_ethtool_cls_rule_ins(struct mvpp2_port *port,
0309                    struct ethtool_rxnfc *info);
0310 
0311 int mvpp2_ethtool_cls_rule_del(struct mvpp2_port *port,
0312                    struct ethtool_rxnfc *info);
0313 
0314 #endif