1*4882a593Smuzhiyun /* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ 2*4882a593Smuzhiyun /* Microsemi Ocelot Switch driver 3*4882a593Smuzhiyun * Copyright (c) 2019 Microsemi Corporation 4*4882a593Smuzhiyun */ 5*4882a593Smuzhiyun 6*4882a593Smuzhiyun #ifndef _MSCC_OCELOT_VCAP_H_ 7*4882a593Smuzhiyun #define _MSCC_OCELOT_VCAP_H_ 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun #include "ocelot.h" 10*4882a593Smuzhiyun #include "ocelot_police.h" 11*4882a593Smuzhiyun #include <net/sch_generic.h> 12*4882a593Smuzhiyun #include <net/pkt_cls.h> 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun #define OCELOT_POLICER_DISCARD 0x17f 15*4882a593Smuzhiyun 16*4882a593Smuzhiyun struct ocelot_ipv4 { 17*4882a593Smuzhiyun u8 addr[4]; 18*4882a593Smuzhiyun }; 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun enum ocelot_vcap_bit { 21*4882a593Smuzhiyun OCELOT_VCAP_BIT_ANY, 22*4882a593Smuzhiyun OCELOT_VCAP_BIT_0, 23*4882a593Smuzhiyun OCELOT_VCAP_BIT_1 24*4882a593Smuzhiyun }; 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun struct ocelot_vcap_u8 { 27*4882a593Smuzhiyun u8 value[1]; 28*4882a593Smuzhiyun u8 mask[1]; 29*4882a593Smuzhiyun }; 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun struct ocelot_vcap_u16 { 32*4882a593Smuzhiyun u8 value[2]; 33*4882a593Smuzhiyun u8 mask[2]; 34*4882a593Smuzhiyun }; 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun struct ocelot_vcap_u24 { 37*4882a593Smuzhiyun u8 value[3]; 38*4882a593Smuzhiyun u8 mask[3]; 39*4882a593Smuzhiyun }; 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun struct ocelot_vcap_u32 { 42*4882a593Smuzhiyun u8 value[4]; 43*4882a593Smuzhiyun u8 mask[4]; 44*4882a593Smuzhiyun }; 45*4882a593Smuzhiyun 46*4882a593Smuzhiyun struct ocelot_vcap_u40 { 47*4882a593Smuzhiyun u8 value[5]; 48*4882a593Smuzhiyun u8 mask[5]; 49*4882a593Smuzhiyun }; 50*4882a593Smuzhiyun 51*4882a593Smuzhiyun struct ocelot_vcap_u48 { 52*4882a593Smuzhiyun u8 value[6]; 53*4882a593Smuzhiyun u8 mask[6]; 54*4882a593Smuzhiyun }; 55*4882a593Smuzhiyun 56*4882a593Smuzhiyun struct ocelot_vcap_u64 { 57*4882a593Smuzhiyun u8 value[8]; 58*4882a593Smuzhiyun u8 mask[8]; 59*4882a593Smuzhiyun }; 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun struct ocelot_vcap_u128 { 62*4882a593Smuzhiyun u8 value[16]; 63*4882a593Smuzhiyun u8 mask[16]; 64*4882a593Smuzhiyun }; 65*4882a593Smuzhiyun 66*4882a593Smuzhiyun struct ocelot_vcap_vid { 67*4882a593Smuzhiyun u16 value; 68*4882a593Smuzhiyun u16 mask; 69*4882a593Smuzhiyun }; 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun struct ocelot_vcap_ipv4 { 72*4882a593Smuzhiyun struct ocelot_ipv4 value; 73*4882a593Smuzhiyun struct ocelot_ipv4 mask; 74*4882a593Smuzhiyun }; 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun struct ocelot_vcap_udp_tcp { 77*4882a593Smuzhiyun u16 value; 78*4882a593Smuzhiyun u16 mask; 79*4882a593Smuzhiyun }; 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun struct ocelot_vcap_port { 82*4882a593Smuzhiyun u8 value; 83*4882a593Smuzhiyun u8 mask; 84*4882a593Smuzhiyun }; 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun enum ocelot_vcap_key_type { 87*4882a593Smuzhiyun OCELOT_VCAP_KEY_ANY, 88*4882a593Smuzhiyun OCELOT_VCAP_KEY_ETYPE, 89*4882a593Smuzhiyun OCELOT_VCAP_KEY_LLC, 90*4882a593Smuzhiyun OCELOT_VCAP_KEY_SNAP, 91*4882a593Smuzhiyun OCELOT_VCAP_KEY_ARP, 92*4882a593Smuzhiyun OCELOT_VCAP_KEY_IPV4, 93*4882a593Smuzhiyun OCELOT_VCAP_KEY_IPV6 94*4882a593Smuzhiyun }; 95*4882a593Smuzhiyun 96*4882a593Smuzhiyun struct ocelot_vcap_key_vlan { 97*4882a593Smuzhiyun struct ocelot_vcap_vid vid; /* VLAN ID (12 bit) */ 98*4882a593Smuzhiyun struct ocelot_vcap_u8 pcp; /* PCP (3 bit) */ 99*4882a593Smuzhiyun enum ocelot_vcap_bit dei; /* DEI */ 100*4882a593Smuzhiyun enum ocelot_vcap_bit tagged; /* Tagged/untagged frame */ 101*4882a593Smuzhiyun }; 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun struct ocelot_vcap_key_etype { 104*4882a593Smuzhiyun struct ocelot_vcap_u48 dmac; 105*4882a593Smuzhiyun struct ocelot_vcap_u48 smac; 106*4882a593Smuzhiyun struct ocelot_vcap_u16 etype; 107*4882a593Smuzhiyun struct ocelot_vcap_u16 data; /* MAC data */ 108*4882a593Smuzhiyun }; 109*4882a593Smuzhiyun 110*4882a593Smuzhiyun struct ocelot_vcap_key_llc { 111*4882a593Smuzhiyun struct ocelot_vcap_u48 dmac; 112*4882a593Smuzhiyun struct ocelot_vcap_u48 smac; 113*4882a593Smuzhiyun 114*4882a593Smuzhiyun /* LLC header: DSAP at byte 0, SSAP at byte 1, Control at byte 2 */ 115*4882a593Smuzhiyun struct ocelot_vcap_u32 llc; 116*4882a593Smuzhiyun }; 117*4882a593Smuzhiyun 118*4882a593Smuzhiyun struct ocelot_vcap_key_snap { 119*4882a593Smuzhiyun struct ocelot_vcap_u48 dmac; 120*4882a593Smuzhiyun struct ocelot_vcap_u48 smac; 121*4882a593Smuzhiyun 122*4882a593Smuzhiyun /* SNAP header: Organization Code at byte 0, Type at byte 3 */ 123*4882a593Smuzhiyun struct ocelot_vcap_u40 snap; 124*4882a593Smuzhiyun }; 125*4882a593Smuzhiyun 126*4882a593Smuzhiyun struct ocelot_vcap_key_arp { 127*4882a593Smuzhiyun struct ocelot_vcap_u48 smac; 128*4882a593Smuzhiyun enum ocelot_vcap_bit arp; /* Opcode ARP/RARP */ 129*4882a593Smuzhiyun enum ocelot_vcap_bit req; /* Opcode request/reply */ 130*4882a593Smuzhiyun enum ocelot_vcap_bit unknown; /* Opcode unknown */ 131*4882a593Smuzhiyun enum ocelot_vcap_bit smac_match; /* Sender MAC matches SMAC */ 132*4882a593Smuzhiyun enum ocelot_vcap_bit dmac_match; /* Target MAC matches DMAC */ 133*4882a593Smuzhiyun 134*4882a593Smuzhiyun /**< Protocol addr. length 4, hardware length 6 */ 135*4882a593Smuzhiyun enum ocelot_vcap_bit length; 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun enum ocelot_vcap_bit ip; /* Protocol address type IP */ 138*4882a593Smuzhiyun enum ocelot_vcap_bit ethernet; /* Hardware address type Ethernet */ 139*4882a593Smuzhiyun struct ocelot_vcap_ipv4 sip; /* Sender IP address */ 140*4882a593Smuzhiyun struct ocelot_vcap_ipv4 dip; /* Target IP address */ 141*4882a593Smuzhiyun }; 142*4882a593Smuzhiyun 143*4882a593Smuzhiyun struct ocelot_vcap_key_ipv4 { 144*4882a593Smuzhiyun enum ocelot_vcap_bit ttl; /* TTL zero */ 145*4882a593Smuzhiyun enum ocelot_vcap_bit fragment; /* Fragment */ 146*4882a593Smuzhiyun enum ocelot_vcap_bit options; /* Header options */ 147*4882a593Smuzhiyun struct ocelot_vcap_u8 ds; 148*4882a593Smuzhiyun struct ocelot_vcap_u8 proto; /* Protocol */ 149*4882a593Smuzhiyun struct ocelot_vcap_ipv4 sip; /* Source IP address */ 150*4882a593Smuzhiyun struct ocelot_vcap_ipv4 dip; /* Destination IP address */ 151*4882a593Smuzhiyun struct ocelot_vcap_u48 data; /* Not UDP/TCP: IP data */ 152*4882a593Smuzhiyun struct ocelot_vcap_udp_tcp sport; /* UDP/TCP: Source port */ 153*4882a593Smuzhiyun struct ocelot_vcap_udp_tcp dport; /* UDP/TCP: Destination port */ 154*4882a593Smuzhiyun enum ocelot_vcap_bit tcp_fin; 155*4882a593Smuzhiyun enum ocelot_vcap_bit tcp_syn; 156*4882a593Smuzhiyun enum ocelot_vcap_bit tcp_rst; 157*4882a593Smuzhiyun enum ocelot_vcap_bit tcp_psh; 158*4882a593Smuzhiyun enum ocelot_vcap_bit tcp_ack; 159*4882a593Smuzhiyun enum ocelot_vcap_bit tcp_urg; 160*4882a593Smuzhiyun enum ocelot_vcap_bit sip_eq_dip; /* SIP equals DIP */ 161*4882a593Smuzhiyun enum ocelot_vcap_bit sport_eq_dport; /* SPORT equals DPORT */ 162*4882a593Smuzhiyun enum ocelot_vcap_bit seq_zero; /* TCP sequence number is zero */ 163*4882a593Smuzhiyun }; 164*4882a593Smuzhiyun 165*4882a593Smuzhiyun struct ocelot_vcap_key_ipv6 { 166*4882a593Smuzhiyun struct ocelot_vcap_u8 proto; /* IPv6 protocol */ 167*4882a593Smuzhiyun struct ocelot_vcap_u128 sip; /* IPv6 source (byte 0-7 ignored) */ 168*4882a593Smuzhiyun struct ocelot_vcap_u128 dip; /* IPv6 destination (byte 0-7 ignored) */ 169*4882a593Smuzhiyun enum ocelot_vcap_bit ttl; /* TTL zero */ 170*4882a593Smuzhiyun struct ocelot_vcap_u8 ds; 171*4882a593Smuzhiyun struct ocelot_vcap_u48 data; /* Not UDP/TCP: IP data */ 172*4882a593Smuzhiyun struct ocelot_vcap_udp_tcp sport; 173*4882a593Smuzhiyun struct ocelot_vcap_udp_tcp dport; 174*4882a593Smuzhiyun enum ocelot_vcap_bit tcp_fin; 175*4882a593Smuzhiyun enum ocelot_vcap_bit tcp_syn; 176*4882a593Smuzhiyun enum ocelot_vcap_bit tcp_rst; 177*4882a593Smuzhiyun enum ocelot_vcap_bit tcp_psh; 178*4882a593Smuzhiyun enum ocelot_vcap_bit tcp_ack; 179*4882a593Smuzhiyun enum ocelot_vcap_bit tcp_urg; 180*4882a593Smuzhiyun enum ocelot_vcap_bit sip_eq_dip; /* SIP equals DIP */ 181*4882a593Smuzhiyun enum ocelot_vcap_bit sport_eq_dport; /* SPORT equals DPORT */ 182*4882a593Smuzhiyun enum ocelot_vcap_bit seq_zero; /* TCP sequence number is zero */ 183*4882a593Smuzhiyun }; 184*4882a593Smuzhiyun 185*4882a593Smuzhiyun enum ocelot_mask_mode { 186*4882a593Smuzhiyun OCELOT_MASK_MODE_NONE, 187*4882a593Smuzhiyun OCELOT_MASK_MODE_PERMIT_DENY, 188*4882a593Smuzhiyun OCELOT_MASK_MODE_POLICY, 189*4882a593Smuzhiyun OCELOT_MASK_MODE_REDIRECT, 190*4882a593Smuzhiyun }; 191*4882a593Smuzhiyun 192*4882a593Smuzhiyun enum ocelot_es0_tag { 193*4882a593Smuzhiyun OCELOT_NO_ES0_TAG, 194*4882a593Smuzhiyun OCELOT_ES0_TAG, 195*4882a593Smuzhiyun OCELOT_FORCE_PORT_TAG, 196*4882a593Smuzhiyun OCELOT_FORCE_UNTAG, 197*4882a593Smuzhiyun }; 198*4882a593Smuzhiyun 199*4882a593Smuzhiyun enum ocelot_tag_tpid_sel { 200*4882a593Smuzhiyun OCELOT_TAG_TPID_SEL_8021Q, 201*4882a593Smuzhiyun OCELOT_TAG_TPID_SEL_8021AD, 202*4882a593Smuzhiyun }; 203*4882a593Smuzhiyun 204*4882a593Smuzhiyun struct ocelot_vcap_action { 205*4882a593Smuzhiyun union { 206*4882a593Smuzhiyun /* VCAP ES0 */ 207*4882a593Smuzhiyun struct { 208*4882a593Smuzhiyun enum ocelot_es0_tag push_outer_tag; 209*4882a593Smuzhiyun enum ocelot_es0_tag push_inner_tag; 210*4882a593Smuzhiyun enum ocelot_tag_tpid_sel tag_a_tpid_sel; 211*4882a593Smuzhiyun int tag_a_vid_sel; 212*4882a593Smuzhiyun int tag_a_pcp_sel; 213*4882a593Smuzhiyun u16 vid_a_val; 214*4882a593Smuzhiyun u8 pcp_a_val; 215*4882a593Smuzhiyun u8 dei_a_val; 216*4882a593Smuzhiyun enum ocelot_tag_tpid_sel tag_b_tpid_sel; 217*4882a593Smuzhiyun int tag_b_vid_sel; 218*4882a593Smuzhiyun int tag_b_pcp_sel; 219*4882a593Smuzhiyun u16 vid_b_val; 220*4882a593Smuzhiyun u8 pcp_b_val; 221*4882a593Smuzhiyun u8 dei_b_val; 222*4882a593Smuzhiyun }; 223*4882a593Smuzhiyun 224*4882a593Smuzhiyun /* VCAP IS1 */ 225*4882a593Smuzhiyun struct { 226*4882a593Smuzhiyun bool vid_replace_ena; 227*4882a593Smuzhiyun u16 vid; 228*4882a593Smuzhiyun bool vlan_pop_cnt_ena; 229*4882a593Smuzhiyun int vlan_pop_cnt; 230*4882a593Smuzhiyun bool pcp_dei_ena; 231*4882a593Smuzhiyun u8 pcp; 232*4882a593Smuzhiyun u8 dei; 233*4882a593Smuzhiyun bool qos_ena; 234*4882a593Smuzhiyun u8 qos_val; 235*4882a593Smuzhiyun u8 pag_override_mask; 236*4882a593Smuzhiyun u8 pag_val; 237*4882a593Smuzhiyun }; 238*4882a593Smuzhiyun 239*4882a593Smuzhiyun /* VCAP IS2 */ 240*4882a593Smuzhiyun struct { 241*4882a593Smuzhiyun bool cpu_copy_ena; 242*4882a593Smuzhiyun u8 cpu_qu_num; 243*4882a593Smuzhiyun enum ocelot_mask_mode mask_mode; 244*4882a593Smuzhiyun unsigned long port_mask; 245*4882a593Smuzhiyun bool police_ena; 246*4882a593Smuzhiyun struct ocelot_policer pol; 247*4882a593Smuzhiyun u32 pol_ix; 248*4882a593Smuzhiyun }; 249*4882a593Smuzhiyun }; 250*4882a593Smuzhiyun }; 251*4882a593Smuzhiyun 252*4882a593Smuzhiyun struct ocelot_vcap_stats { 253*4882a593Smuzhiyun u64 bytes; 254*4882a593Smuzhiyun u64 pkts; 255*4882a593Smuzhiyun u64 used; 256*4882a593Smuzhiyun }; 257*4882a593Smuzhiyun 258*4882a593Smuzhiyun enum ocelot_vcap_filter_type { 259*4882a593Smuzhiyun OCELOT_VCAP_FILTER_DUMMY, 260*4882a593Smuzhiyun OCELOT_VCAP_FILTER_PAG, 261*4882a593Smuzhiyun OCELOT_VCAP_FILTER_OFFLOAD, 262*4882a593Smuzhiyun }; 263*4882a593Smuzhiyun 264*4882a593Smuzhiyun struct ocelot_vcap_filter { 265*4882a593Smuzhiyun struct list_head list; 266*4882a593Smuzhiyun 267*4882a593Smuzhiyun enum ocelot_vcap_filter_type type; 268*4882a593Smuzhiyun int block_id; 269*4882a593Smuzhiyun int goto_target; 270*4882a593Smuzhiyun int lookup; 271*4882a593Smuzhiyun u8 pag; 272*4882a593Smuzhiyun u16 prio; 273*4882a593Smuzhiyun u32 id; 274*4882a593Smuzhiyun 275*4882a593Smuzhiyun struct ocelot_vcap_action action; 276*4882a593Smuzhiyun struct ocelot_vcap_stats stats; 277*4882a593Smuzhiyun /* For VCAP IS1 and IS2 */ 278*4882a593Smuzhiyun unsigned long ingress_port_mask; 279*4882a593Smuzhiyun /* For VCAP ES0 */ 280*4882a593Smuzhiyun struct ocelot_vcap_port ingress_port; 281*4882a593Smuzhiyun struct ocelot_vcap_port egress_port; 282*4882a593Smuzhiyun 283*4882a593Smuzhiyun enum ocelot_vcap_bit dmac_mc; 284*4882a593Smuzhiyun enum ocelot_vcap_bit dmac_bc; 285*4882a593Smuzhiyun struct ocelot_vcap_key_vlan vlan; 286*4882a593Smuzhiyun 287*4882a593Smuzhiyun enum ocelot_vcap_key_type key_type; 288*4882a593Smuzhiyun union { 289*4882a593Smuzhiyun /* OCELOT_VCAP_KEY_ANY: No specific fields */ 290*4882a593Smuzhiyun struct ocelot_vcap_key_etype etype; 291*4882a593Smuzhiyun struct ocelot_vcap_key_llc llc; 292*4882a593Smuzhiyun struct ocelot_vcap_key_snap snap; 293*4882a593Smuzhiyun struct ocelot_vcap_key_arp arp; 294*4882a593Smuzhiyun struct ocelot_vcap_key_ipv4 ipv4; 295*4882a593Smuzhiyun struct ocelot_vcap_key_ipv6 ipv6; 296*4882a593Smuzhiyun } key; 297*4882a593Smuzhiyun }; 298*4882a593Smuzhiyun 299*4882a593Smuzhiyun int ocelot_vcap_filter_add(struct ocelot *ocelot, 300*4882a593Smuzhiyun struct ocelot_vcap_filter *rule, 301*4882a593Smuzhiyun struct netlink_ext_ack *extack); 302*4882a593Smuzhiyun int ocelot_vcap_filter_del(struct ocelot *ocelot, 303*4882a593Smuzhiyun struct ocelot_vcap_filter *rule); 304*4882a593Smuzhiyun int ocelot_vcap_filter_stats_update(struct ocelot *ocelot, 305*4882a593Smuzhiyun struct ocelot_vcap_filter *rule); 306*4882a593Smuzhiyun struct ocelot_vcap_filter * 307*4882a593Smuzhiyun ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, int id); 308*4882a593Smuzhiyun 309*4882a593Smuzhiyun void ocelot_detect_vcap_constants(struct ocelot *ocelot); 310*4882a593Smuzhiyun int ocelot_vcap_init(struct ocelot *ocelot); 311*4882a593Smuzhiyun 312*4882a593Smuzhiyun int ocelot_setup_tc_cls_flower(struct ocelot_port_private *priv, 313*4882a593Smuzhiyun struct flow_cls_offload *f, 314*4882a593Smuzhiyun bool ingress); 315*4882a593Smuzhiyun 316*4882a593Smuzhiyun #endif /* _MSCC_OCELOT_VCAP_H_ */ 317