13c83654fSVladimir Oltean /* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ 23c83654fSVladimir Oltean /* Microsemi Ocelot Switch driver 33c83654fSVladimir Oltean * Copyright (c) 2019 Microsemi Corporation 43c83654fSVladimir Oltean */ 53c83654fSVladimir Oltean 6aae4e500SVladimir Oltean #ifndef _MSCC_OCELOT_VCAP_H_ 7aae4e500SVladimir Oltean #define _MSCC_OCELOT_VCAP_H_ 83c83654fSVladimir Oltean 93c83654fSVladimir Oltean #include "ocelot.h" 103c83654fSVladimir Oltean #include "ocelot_police.h" 113c83654fSVladimir Oltean #include <net/sch_generic.h> 123c83654fSVladimir Oltean #include <net/pkt_cls.h> 133c83654fSVladimir Oltean 143c83654fSVladimir Oltean struct ocelot_ipv4 { 153c83654fSVladimir Oltean u8 addr[4]; 163c83654fSVladimir Oltean }; 173c83654fSVladimir Oltean 183c83654fSVladimir Oltean enum ocelot_vcap_bit { 193c83654fSVladimir Oltean OCELOT_VCAP_BIT_ANY, 203c83654fSVladimir Oltean OCELOT_VCAP_BIT_0, 213c83654fSVladimir Oltean OCELOT_VCAP_BIT_1 223c83654fSVladimir Oltean }; 233c83654fSVladimir Oltean 243c83654fSVladimir Oltean struct ocelot_vcap_u8 { 253c83654fSVladimir Oltean u8 value[1]; 263c83654fSVladimir Oltean u8 mask[1]; 273c83654fSVladimir Oltean }; 283c83654fSVladimir Oltean 293c83654fSVladimir Oltean struct ocelot_vcap_u16 { 303c83654fSVladimir Oltean u8 value[2]; 313c83654fSVladimir Oltean u8 mask[2]; 323c83654fSVladimir Oltean }; 333c83654fSVladimir Oltean 343c83654fSVladimir Oltean struct ocelot_vcap_u24 { 353c83654fSVladimir Oltean u8 value[3]; 363c83654fSVladimir Oltean u8 mask[3]; 373c83654fSVladimir Oltean }; 383c83654fSVladimir Oltean 393c83654fSVladimir Oltean struct ocelot_vcap_u32 { 403c83654fSVladimir Oltean u8 value[4]; 413c83654fSVladimir Oltean u8 mask[4]; 423c83654fSVladimir Oltean }; 433c83654fSVladimir Oltean 443c83654fSVladimir Oltean struct ocelot_vcap_u40 { 453c83654fSVladimir Oltean u8 value[5]; 463c83654fSVladimir Oltean u8 mask[5]; 473c83654fSVladimir Oltean }; 483c83654fSVladimir Oltean 493c83654fSVladimir Oltean struct ocelot_vcap_u48 { 503c83654fSVladimir Oltean u8 value[6]; 513c83654fSVladimir Oltean u8 mask[6]; 523c83654fSVladimir Oltean }; 533c83654fSVladimir Oltean 543c83654fSVladimir Oltean struct ocelot_vcap_u64 { 553c83654fSVladimir Oltean u8 value[8]; 563c83654fSVladimir Oltean u8 mask[8]; 573c83654fSVladimir Oltean }; 583c83654fSVladimir Oltean 593c83654fSVladimir Oltean struct ocelot_vcap_u128 { 603c83654fSVladimir Oltean u8 value[16]; 613c83654fSVladimir Oltean u8 mask[16]; 623c83654fSVladimir Oltean }; 633c83654fSVladimir Oltean 643c83654fSVladimir Oltean struct ocelot_vcap_vid { 653c83654fSVladimir Oltean u16 value; 663c83654fSVladimir Oltean u16 mask; 673c83654fSVladimir Oltean }; 683c83654fSVladimir Oltean 693c83654fSVladimir Oltean struct ocelot_vcap_ipv4 { 703c83654fSVladimir Oltean struct ocelot_ipv4 value; 713c83654fSVladimir Oltean struct ocelot_ipv4 mask; 723c83654fSVladimir Oltean }; 733c83654fSVladimir Oltean 743c83654fSVladimir Oltean struct ocelot_vcap_udp_tcp { 753c83654fSVladimir Oltean u16 value; 763c83654fSVladimir Oltean u16 mask; 773c83654fSVladimir Oltean }; 783c83654fSVladimir Oltean 79aae4e500SVladimir Oltean enum ocelot_vcap_key_type { 80aae4e500SVladimir Oltean OCELOT_VCAP_KEY_ANY, 81aae4e500SVladimir Oltean OCELOT_VCAP_KEY_ETYPE, 82aae4e500SVladimir Oltean OCELOT_VCAP_KEY_LLC, 83aae4e500SVladimir Oltean OCELOT_VCAP_KEY_SNAP, 84aae4e500SVladimir Oltean OCELOT_VCAP_KEY_ARP, 85aae4e500SVladimir Oltean OCELOT_VCAP_KEY_IPV4, 86aae4e500SVladimir Oltean OCELOT_VCAP_KEY_IPV6 873c83654fSVladimir Oltean }; 883c83654fSVladimir Oltean 89aae4e500SVladimir Oltean struct ocelot_vcap_key_vlan { 903c83654fSVladimir Oltean struct ocelot_vcap_vid vid; /* VLAN ID (12 bit) */ 913c83654fSVladimir Oltean struct ocelot_vcap_u8 pcp; /* PCP (3 bit) */ 923c83654fSVladimir Oltean enum ocelot_vcap_bit dei; /* DEI */ 933c83654fSVladimir Oltean enum ocelot_vcap_bit tagged; /* Tagged/untagged frame */ 943c83654fSVladimir Oltean }; 953c83654fSVladimir Oltean 96aae4e500SVladimir Oltean struct ocelot_vcap_key_etype { 973c83654fSVladimir Oltean struct ocelot_vcap_u48 dmac; 983c83654fSVladimir Oltean struct ocelot_vcap_u48 smac; 993c83654fSVladimir Oltean struct ocelot_vcap_u16 etype; 1003c83654fSVladimir Oltean struct ocelot_vcap_u16 data; /* MAC data */ 1013c83654fSVladimir Oltean }; 1023c83654fSVladimir Oltean 103aae4e500SVladimir Oltean struct ocelot_vcap_key_llc { 1043c83654fSVladimir Oltean struct ocelot_vcap_u48 dmac; 1053c83654fSVladimir Oltean struct ocelot_vcap_u48 smac; 1063c83654fSVladimir Oltean 1073c83654fSVladimir Oltean /* LLC header: DSAP at byte 0, SSAP at byte 1, Control at byte 2 */ 1083c83654fSVladimir Oltean struct ocelot_vcap_u32 llc; 1093c83654fSVladimir Oltean }; 1103c83654fSVladimir Oltean 111aae4e500SVladimir Oltean struct ocelot_vcap_key_snap { 1123c83654fSVladimir Oltean struct ocelot_vcap_u48 dmac; 1133c83654fSVladimir Oltean struct ocelot_vcap_u48 smac; 1143c83654fSVladimir Oltean 1153c83654fSVladimir Oltean /* SNAP header: Organization Code at byte 0, Type at byte 3 */ 1163c83654fSVladimir Oltean struct ocelot_vcap_u40 snap; 1173c83654fSVladimir Oltean }; 1183c83654fSVladimir Oltean 119aae4e500SVladimir Oltean struct ocelot_vcap_key_arp { 1203c83654fSVladimir Oltean struct ocelot_vcap_u48 smac; 1213c83654fSVladimir Oltean enum ocelot_vcap_bit arp; /* Opcode ARP/RARP */ 1223c83654fSVladimir Oltean enum ocelot_vcap_bit req; /* Opcode request/reply */ 1233c83654fSVladimir Oltean enum ocelot_vcap_bit unknown; /* Opcode unknown */ 1243c83654fSVladimir Oltean enum ocelot_vcap_bit smac_match; /* Sender MAC matches SMAC */ 1253c83654fSVladimir Oltean enum ocelot_vcap_bit dmac_match; /* Target MAC matches DMAC */ 1263c83654fSVladimir Oltean 1273c83654fSVladimir Oltean /**< Protocol addr. length 4, hardware length 6 */ 1283c83654fSVladimir Oltean enum ocelot_vcap_bit length; 1293c83654fSVladimir Oltean 1303c83654fSVladimir Oltean enum ocelot_vcap_bit ip; /* Protocol address type IP */ 1313c83654fSVladimir Oltean enum ocelot_vcap_bit ethernet; /* Hardware address type Ethernet */ 1323c83654fSVladimir Oltean struct ocelot_vcap_ipv4 sip; /* Sender IP address */ 1333c83654fSVladimir Oltean struct ocelot_vcap_ipv4 dip; /* Target IP address */ 1343c83654fSVladimir Oltean }; 1353c83654fSVladimir Oltean 136aae4e500SVladimir Oltean struct ocelot_vcap_key_ipv4 { 1373c83654fSVladimir Oltean enum ocelot_vcap_bit ttl; /* TTL zero */ 1383c83654fSVladimir Oltean enum ocelot_vcap_bit fragment; /* Fragment */ 1393c83654fSVladimir Oltean enum ocelot_vcap_bit options; /* Header options */ 1403c83654fSVladimir Oltean struct ocelot_vcap_u8 ds; 1413c83654fSVladimir Oltean struct ocelot_vcap_u8 proto; /* Protocol */ 1423c83654fSVladimir Oltean struct ocelot_vcap_ipv4 sip; /* Source IP address */ 1433c83654fSVladimir Oltean struct ocelot_vcap_ipv4 dip; /* Destination IP address */ 1443c83654fSVladimir Oltean struct ocelot_vcap_u48 data; /* Not UDP/TCP: IP data */ 1453c83654fSVladimir Oltean struct ocelot_vcap_udp_tcp sport; /* UDP/TCP: Source port */ 1463c83654fSVladimir Oltean struct ocelot_vcap_udp_tcp dport; /* UDP/TCP: Destination port */ 1473c83654fSVladimir Oltean enum ocelot_vcap_bit tcp_fin; 1483c83654fSVladimir Oltean enum ocelot_vcap_bit tcp_syn; 1493c83654fSVladimir Oltean enum ocelot_vcap_bit tcp_rst; 1503c83654fSVladimir Oltean enum ocelot_vcap_bit tcp_psh; 1513c83654fSVladimir Oltean enum ocelot_vcap_bit tcp_ack; 1523c83654fSVladimir Oltean enum ocelot_vcap_bit tcp_urg; 1533c83654fSVladimir Oltean enum ocelot_vcap_bit sip_eq_dip; /* SIP equals DIP */ 1543c83654fSVladimir Oltean enum ocelot_vcap_bit sport_eq_dport; /* SPORT equals DPORT */ 1553c83654fSVladimir Oltean enum ocelot_vcap_bit seq_zero; /* TCP sequence number is zero */ 1563c83654fSVladimir Oltean }; 1573c83654fSVladimir Oltean 158aae4e500SVladimir Oltean struct ocelot_vcap_key_ipv6 { 1593c83654fSVladimir Oltean struct ocelot_vcap_u8 proto; /* IPv6 protocol */ 1603c83654fSVladimir Oltean struct ocelot_vcap_u128 sip; /* IPv6 source (byte 0-7 ignored) */ 1613c83654fSVladimir Oltean enum ocelot_vcap_bit ttl; /* TTL zero */ 1623c83654fSVladimir Oltean struct ocelot_vcap_u8 ds; 1633c83654fSVladimir Oltean struct ocelot_vcap_u48 data; /* Not UDP/TCP: IP data */ 1643c83654fSVladimir Oltean struct ocelot_vcap_udp_tcp sport; 1653c83654fSVladimir Oltean struct ocelot_vcap_udp_tcp dport; 1663c83654fSVladimir Oltean enum ocelot_vcap_bit tcp_fin; 1673c83654fSVladimir Oltean enum ocelot_vcap_bit tcp_syn; 1683c83654fSVladimir Oltean enum ocelot_vcap_bit tcp_rst; 1693c83654fSVladimir Oltean enum ocelot_vcap_bit tcp_psh; 1703c83654fSVladimir Oltean enum ocelot_vcap_bit tcp_ack; 1713c83654fSVladimir Oltean enum ocelot_vcap_bit tcp_urg; 1723c83654fSVladimir Oltean enum ocelot_vcap_bit sip_eq_dip; /* SIP equals DIP */ 1733c83654fSVladimir Oltean enum ocelot_vcap_bit sport_eq_dport; /* SPORT equals DPORT */ 1743c83654fSVladimir Oltean enum ocelot_vcap_bit seq_zero; /* TCP sequence number is zero */ 1753c83654fSVladimir Oltean }; 1763c83654fSVladimir Oltean 177aae4e500SVladimir Oltean enum ocelot_vcap_action { 178aae4e500SVladimir Oltean OCELOT_VCAP_ACTION_DROP, 179aae4e500SVladimir Oltean OCELOT_VCAP_ACTION_TRAP, 180aae4e500SVladimir Oltean OCELOT_VCAP_ACTION_POLICE, 1813c83654fSVladimir Oltean }; 1823c83654fSVladimir Oltean 183aae4e500SVladimir Oltean struct ocelot_vcap_stats { 1843c83654fSVladimir Oltean u64 bytes; 1853c83654fSVladimir Oltean u64 pkts; 1863c83654fSVladimir Oltean u64 used; 1873c83654fSVladimir Oltean }; 1883c83654fSVladimir Oltean 189aae4e500SVladimir Oltean struct ocelot_vcap_filter { 1903c83654fSVladimir Oltean struct list_head list; 1913c83654fSVladimir Oltean 1923c83654fSVladimir Oltean u16 prio; 1933c83654fSVladimir Oltean u32 id; 1943c83654fSVladimir Oltean 195aae4e500SVladimir Oltean enum ocelot_vcap_action action; 196aae4e500SVladimir Oltean struct ocelot_vcap_stats stats; 1973c83654fSVladimir Oltean unsigned long ingress_port_mask; 1983c83654fSVladimir Oltean 1993c83654fSVladimir Oltean enum ocelot_vcap_bit dmac_mc; 2003c83654fSVladimir Oltean enum ocelot_vcap_bit dmac_bc; 201aae4e500SVladimir Oltean struct ocelot_vcap_key_vlan vlan; 2023c83654fSVladimir Oltean 203aae4e500SVladimir Oltean enum ocelot_vcap_key_type key_type; 2043c83654fSVladimir Oltean union { 205aae4e500SVladimir Oltean /* OCELOT_VCAP_KEY_ANY: No specific fields */ 206aae4e500SVladimir Oltean struct ocelot_vcap_key_etype etype; 207aae4e500SVladimir Oltean struct ocelot_vcap_key_llc llc; 208aae4e500SVladimir Oltean struct ocelot_vcap_key_snap snap; 209aae4e500SVladimir Oltean struct ocelot_vcap_key_arp arp; 210aae4e500SVladimir Oltean struct ocelot_vcap_key_ipv4 ipv4; 211aae4e500SVladimir Oltean struct ocelot_vcap_key_ipv6 ipv6; 212aae4e500SVladimir Oltean } key; 2133c83654fSVladimir Oltean struct ocelot_policer pol; 2143c83654fSVladimir Oltean u32 pol_ix; 2153c83654fSVladimir Oltean }; 2163c83654fSVladimir Oltean 217aae4e500SVladimir Oltean int ocelot_vcap_filter_add(struct ocelot *ocelot, 218aae4e500SVladimir Oltean struct ocelot_vcap_filter *rule, 2193c83654fSVladimir Oltean struct netlink_ext_ack *extack); 220aae4e500SVladimir Oltean int ocelot_vcap_filter_del(struct ocelot *ocelot, 221aae4e500SVladimir Oltean struct ocelot_vcap_filter *rule); 222aae4e500SVladimir Oltean int ocelot_vcap_filter_stats_update(struct ocelot *ocelot, 223aae4e500SVladimir Oltean struct ocelot_vcap_filter *rule); 2243c83654fSVladimir Oltean 225*20968054SVladimir Oltean void ocelot_detect_vcap_constants(struct ocelot *ocelot); 226aae4e500SVladimir Oltean int ocelot_vcap_init(struct ocelot *ocelot); 2273c83654fSVladimir Oltean 2283c83654fSVladimir Oltean int ocelot_setup_tc_cls_flower(struct ocelot_port_private *priv, 2293c83654fSVladimir Oltean struct flow_cls_offload *f, 2303c83654fSVladimir Oltean bool ingress); 2313c83654fSVladimir Oltean 232aae4e500SVladimir Oltean #endif /* _MSCC_OCELOT_VCAP_H_ */ 233