xref: /linux/drivers/net/ethernet/mscc/ocelot_vcap.h (revision ea9d1f30b128c2bc5f429b3bd822b45ac9bf5114)
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 
14*ea9d1f30SVladimir Oltean #define OCELOT_POLICER_DISCARD 0x17f
15*ea9d1f30SVladimir Oltean 
163c83654fSVladimir Oltean struct ocelot_ipv4 {
173c83654fSVladimir Oltean 	u8 addr[4];
183c83654fSVladimir Oltean };
193c83654fSVladimir Oltean 
203c83654fSVladimir Oltean enum ocelot_vcap_bit {
213c83654fSVladimir Oltean 	OCELOT_VCAP_BIT_ANY,
223c83654fSVladimir Oltean 	OCELOT_VCAP_BIT_0,
233c83654fSVladimir Oltean 	OCELOT_VCAP_BIT_1
243c83654fSVladimir Oltean };
253c83654fSVladimir Oltean 
263c83654fSVladimir Oltean struct ocelot_vcap_u8 {
273c83654fSVladimir Oltean 	u8 value[1];
283c83654fSVladimir Oltean 	u8 mask[1];
293c83654fSVladimir Oltean };
303c83654fSVladimir Oltean 
313c83654fSVladimir Oltean struct ocelot_vcap_u16 {
323c83654fSVladimir Oltean 	u8 value[2];
333c83654fSVladimir Oltean 	u8 mask[2];
343c83654fSVladimir Oltean };
353c83654fSVladimir Oltean 
363c83654fSVladimir Oltean struct ocelot_vcap_u24 {
373c83654fSVladimir Oltean 	u8 value[3];
383c83654fSVladimir Oltean 	u8 mask[3];
393c83654fSVladimir Oltean };
403c83654fSVladimir Oltean 
413c83654fSVladimir Oltean struct ocelot_vcap_u32 {
423c83654fSVladimir Oltean 	u8 value[4];
433c83654fSVladimir Oltean 	u8 mask[4];
443c83654fSVladimir Oltean };
453c83654fSVladimir Oltean 
463c83654fSVladimir Oltean struct ocelot_vcap_u40 {
473c83654fSVladimir Oltean 	u8 value[5];
483c83654fSVladimir Oltean 	u8 mask[5];
493c83654fSVladimir Oltean };
503c83654fSVladimir Oltean 
513c83654fSVladimir Oltean struct ocelot_vcap_u48 {
523c83654fSVladimir Oltean 	u8 value[6];
533c83654fSVladimir Oltean 	u8 mask[6];
543c83654fSVladimir Oltean };
553c83654fSVladimir Oltean 
563c83654fSVladimir Oltean struct ocelot_vcap_u64 {
573c83654fSVladimir Oltean 	u8 value[8];
583c83654fSVladimir Oltean 	u8 mask[8];
593c83654fSVladimir Oltean };
603c83654fSVladimir Oltean 
613c83654fSVladimir Oltean struct ocelot_vcap_u128 {
623c83654fSVladimir Oltean 	u8 value[16];
633c83654fSVladimir Oltean 	u8 mask[16];
643c83654fSVladimir Oltean };
653c83654fSVladimir Oltean 
663c83654fSVladimir Oltean struct ocelot_vcap_vid {
673c83654fSVladimir Oltean 	u16 value;
683c83654fSVladimir Oltean 	u16 mask;
693c83654fSVladimir Oltean };
703c83654fSVladimir Oltean 
713c83654fSVladimir Oltean struct ocelot_vcap_ipv4 {
723c83654fSVladimir Oltean 	struct ocelot_ipv4 value;
733c83654fSVladimir Oltean 	struct ocelot_ipv4 mask;
743c83654fSVladimir Oltean };
753c83654fSVladimir Oltean 
763c83654fSVladimir Oltean struct ocelot_vcap_udp_tcp {
773c83654fSVladimir Oltean 	u16 value;
783c83654fSVladimir Oltean 	u16 mask;
793c83654fSVladimir Oltean };
803c83654fSVladimir Oltean 
81aae4e500SVladimir Oltean enum ocelot_vcap_key_type {
82aae4e500SVladimir Oltean 	OCELOT_VCAP_KEY_ANY,
83aae4e500SVladimir Oltean 	OCELOT_VCAP_KEY_ETYPE,
84aae4e500SVladimir Oltean 	OCELOT_VCAP_KEY_LLC,
85aae4e500SVladimir Oltean 	OCELOT_VCAP_KEY_SNAP,
86aae4e500SVladimir Oltean 	OCELOT_VCAP_KEY_ARP,
87aae4e500SVladimir Oltean 	OCELOT_VCAP_KEY_IPV4,
88aae4e500SVladimir Oltean 	OCELOT_VCAP_KEY_IPV6
893c83654fSVladimir Oltean };
903c83654fSVladimir Oltean 
91aae4e500SVladimir Oltean struct ocelot_vcap_key_vlan {
923c83654fSVladimir Oltean 	struct ocelot_vcap_vid vid;    /* VLAN ID (12 bit) */
933c83654fSVladimir Oltean 	struct ocelot_vcap_u8  pcp;    /* PCP (3 bit) */
943c83654fSVladimir Oltean 	enum ocelot_vcap_bit dei;    /* DEI */
953c83654fSVladimir Oltean 	enum ocelot_vcap_bit tagged; /* Tagged/untagged frame */
963c83654fSVladimir Oltean };
973c83654fSVladimir Oltean 
98aae4e500SVladimir Oltean struct ocelot_vcap_key_etype {
993c83654fSVladimir Oltean 	struct ocelot_vcap_u48 dmac;
1003c83654fSVladimir Oltean 	struct ocelot_vcap_u48 smac;
1013c83654fSVladimir Oltean 	struct ocelot_vcap_u16 etype;
1023c83654fSVladimir Oltean 	struct ocelot_vcap_u16 data; /* MAC data */
1033c83654fSVladimir Oltean };
1043c83654fSVladimir Oltean 
105aae4e500SVladimir Oltean struct ocelot_vcap_key_llc {
1063c83654fSVladimir Oltean 	struct ocelot_vcap_u48 dmac;
1073c83654fSVladimir Oltean 	struct ocelot_vcap_u48 smac;
1083c83654fSVladimir Oltean 
1093c83654fSVladimir Oltean 	/* LLC header: DSAP at byte 0, SSAP at byte 1, Control at byte 2 */
1103c83654fSVladimir Oltean 	struct ocelot_vcap_u32 llc;
1113c83654fSVladimir Oltean };
1123c83654fSVladimir Oltean 
113aae4e500SVladimir Oltean struct ocelot_vcap_key_snap {
1143c83654fSVladimir Oltean 	struct ocelot_vcap_u48 dmac;
1153c83654fSVladimir Oltean 	struct ocelot_vcap_u48 smac;
1163c83654fSVladimir Oltean 
1173c83654fSVladimir Oltean 	/* SNAP header: Organization Code at byte 0, Type at byte 3 */
1183c83654fSVladimir Oltean 	struct ocelot_vcap_u40 snap;
1193c83654fSVladimir Oltean };
1203c83654fSVladimir Oltean 
121aae4e500SVladimir Oltean struct ocelot_vcap_key_arp {
1223c83654fSVladimir Oltean 	struct ocelot_vcap_u48 smac;
1233c83654fSVladimir Oltean 	enum ocelot_vcap_bit arp;	/* Opcode ARP/RARP */
1243c83654fSVladimir Oltean 	enum ocelot_vcap_bit req;	/* Opcode request/reply */
1253c83654fSVladimir Oltean 	enum ocelot_vcap_bit unknown;    /* Opcode unknown */
1263c83654fSVladimir Oltean 	enum ocelot_vcap_bit smac_match; /* Sender MAC matches SMAC */
1273c83654fSVladimir Oltean 	enum ocelot_vcap_bit dmac_match; /* Target MAC matches DMAC */
1283c83654fSVladimir Oltean 
1293c83654fSVladimir Oltean 	/**< Protocol addr. length 4, hardware length 6 */
1303c83654fSVladimir Oltean 	enum ocelot_vcap_bit length;
1313c83654fSVladimir Oltean 
1323c83654fSVladimir Oltean 	enum ocelot_vcap_bit ip;       /* Protocol address type IP */
1333c83654fSVladimir Oltean 	enum  ocelot_vcap_bit ethernet; /* Hardware address type Ethernet */
1343c83654fSVladimir Oltean 	struct ocelot_vcap_ipv4 sip;     /* Sender IP address */
1353c83654fSVladimir Oltean 	struct ocelot_vcap_ipv4 dip;     /* Target IP address */
1363c83654fSVladimir Oltean };
1373c83654fSVladimir Oltean 
138aae4e500SVladimir Oltean struct ocelot_vcap_key_ipv4 {
1393c83654fSVladimir Oltean 	enum ocelot_vcap_bit ttl;      /* TTL zero */
1403c83654fSVladimir Oltean 	enum ocelot_vcap_bit fragment; /* Fragment */
1413c83654fSVladimir Oltean 	enum ocelot_vcap_bit options;  /* Header options */
1423c83654fSVladimir Oltean 	struct ocelot_vcap_u8 ds;
1433c83654fSVladimir Oltean 	struct ocelot_vcap_u8 proto;      /* Protocol */
1443c83654fSVladimir Oltean 	struct ocelot_vcap_ipv4 sip;      /* Source IP address */
1453c83654fSVladimir Oltean 	struct ocelot_vcap_ipv4 dip;      /* Destination IP address */
1463c83654fSVladimir Oltean 	struct ocelot_vcap_u48 data;      /* Not UDP/TCP: IP data */
1473c83654fSVladimir Oltean 	struct ocelot_vcap_udp_tcp sport; /* UDP/TCP: Source port */
1483c83654fSVladimir Oltean 	struct ocelot_vcap_udp_tcp dport; /* UDP/TCP: Destination port */
1493c83654fSVladimir Oltean 	enum ocelot_vcap_bit tcp_fin;
1503c83654fSVladimir Oltean 	enum ocelot_vcap_bit tcp_syn;
1513c83654fSVladimir Oltean 	enum ocelot_vcap_bit tcp_rst;
1523c83654fSVladimir Oltean 	enum ocelot_vcap_bit tcp_psh;
1533c83654fSVladimir Oltean 	enum ocelot_vcap_bit tcp_ack;
1543c83654fSVladimir Oltean 	enum ocelot_vcap_bit tcp_urg;
1553c83654fSVladimir Oltean 	enum ocelot_vcap_bit sip_eq_dip;     /* SIP equals DIP  */
1563c83654fSVladimir Oltean 	enum ocelot_vcap_bit sport_eq_dport; /* SPORT equals DPORT  */
1573c83654fSVladimir Oltean 	enum ocelot_vcap_bit seq_zero;       /* TCP sequence number is zero */
1583c83654fSVladimir Oltean };
1593c83654fSVladimir Oltean 
160aae4e500SVladimir Oltean struct ocelot_vcap_key_ipv6 {
1613c83654fSVladimir Oltean 	struct ocelot_vcap_u8 proto; /* IPv6 protocol */
1623c83654fSVladimir Oltean 	struct ocelot_vcap_u128 sip; /* IPv6 source (byte 0-7 ignored) */
1633c83654fSVladimir Oltean 	enum ocelot_vcap_bit ttl;  /* TTL zero */
1643c83654fSVladimir Oltean 	struct ocelot_vcap_u8 ds;
1653c83654fSVladimir Oltean 	struct ocelot_vcap_u48 data; /* Not UDP/TCP: IP data */
1663c83654fSVladimir Oltean 	struct ocelot_vcap_udp_tcp sport;
1673c83654fSVladimir Oltean 	struct ocelot_vcap_udp_tcp dport;
1683c83654fSVladimir Oltean 	enum ocelot_vcap_bit tcp_fin;
1693c83654fSVladimir Oltean 	enum ocelot_vcap_bit tcp_syn;
1703c83654fSVladimir Oltean 	enum ocelot_vcap_bit tcp_rst;
1713c83654fSVladimir Oltean 	enum ocelot_vcap_bit tcp_psh;
1723c83654fSVladimir Oltean 	enum ocelot_vcap_bit tcp_ack;
1733c83654fSVladimir Oltean 	enum ocelot_vcap_bit tcp_urg;
1743c83654fSVladimir Oltean 	enum ocelot_vcap_bit sip_eq_dip;     /* SIP equals DIP  */
1753c83654fSVladimir Oltean 	enum ocelot_vcap_bit sport_eq_dport; /* SPORT equals DPORT  */
1763c83654fSVladimir Oltean 	enum ocelot_vcap_bit seq_zero;       /* TCP sequence number is zero */
1773c83654fSVladimir Oltean };
1783c83654fSVladimir Oltean 
179*ea9d1f30SVladimir Oltean enum ocelot_mask_mode {
180*ea9d1f30SVladimir Oltean 	OCELOT_MASK_MODE_NONE,
181*ea9d1f30SVladimir Oltean 	OCELOT_MASK_MODE_PERMIT_DENY,
182*ea9d1f30SVladimir Oltean 	OCELOT_MASK_MODE_POLICY,
183*ea9d1f30SVladimir Oltean 	OCELOT_MASK_MODE_REDIRECT,
184*ea9d1f30SVladimir Oltean };
185*ea9d1f30SVladimir Oltean 
186*ea9d1f30SVladimir Oltean struct ocelot_vcap_action {
187*ea9d1f30SVladimir Oltean 	union {
188*ea9d1f30SVladimir Oltean 		/* VCAP IS2 */
189*ea9d1f30SVladimir Oltean 		struct {
190*ea9d1f30SVladimir Oltean 			bool cpu_copy_ena;
191*ea9d1f30SVladimir Oltean 			u8 cpu_qu_num;
192*ea9d1f30SVladimir Oltean 			enum ocelot_mask_mode mask_mode;
193*ea9d1f30SVladimir Oltean 			unsigned long port_mask;
194*ea9d1f30SVladimir Oltean 			bool police_ena;
195*ea9d1f30SVladimir Oltean 			struct ocelot_policer pol;
196*ea9d1f30SVladimir Oltean 			u32 pol_ix;
197*ea9d1f30SVladimir Oltean 		};
198*ea9d1f30SVladimir Oltean 	};
1993c83654fSVladimir Oltean };
2003c83654fSVladimir Oltean 
201aae4e500SVladimir Oltean struct ocelot_vcap_stats {
2023c83654fSVladimir Oltean 	u64 bytes;
2033c83654fSVladimir Oltean 	u64 pkts;
2043c83654fSVladimir Oltean 	u64 used;
2053c83654fSVladimir Oltean };
2063c83654fSVladimir Oltean 
207aae4e500SVladimir Oltean struct ocelot_vcap_filter {
2083c83654fSVladimir Oltean 	struct list_head list;
2093c83654fSVladimir Oltean 
2103c83654fSVladimir Oltean 	u16 prio;
2113c83654fSVladimir Oltean 	u32 id;
2123c83654fSVladimir Oltean 
213*ea9d1f30SVladimir Oltean 	struct ocelot_vcap_action action;
214aae4e500SVladimir Oltean 	struct ocelot_vcap_stats stats;
2153c83654fSVladimir Oltean 	unsigned long ingress_port_mask;
2163c83654fSVladimir Oltean 
2173c83654fSVladimir Oltean 	enum ocelot_vcap_bit dmac_mc;
2183c83654fSVladimir Oltean 	enum ocelot_vcap_bit dmac_bc;
219aae4e500SVladimir Oltean 	struct ocelot_vcap_key_vlan vlan;
2203c83654fSVladimir Oltean 
221aae4e500SVladimir Oltean 	enum ocelot_vcap_key_type key_type;
2223c83654fSVladimir Oltean 	union {
223aae4e500SVladimir Oltean 		/* OCELOT_VCAP_KEY_ANY: No specific fields */
224aae4e500SVladimir Oltean 		struct ocelot_vcap_key_etype etype;
225aae4e500SVladimir Oltean 		struct ocelot_vcap_key_llc llc;
226aae4e500SVladimir Oltean 		struct ocelot_vcap_key_snap snap;
227aae4e500SVladimir Oltean 		struct ocelot_vcap_key_arp arp;
228aae4e500SVladimir Oltean 		struct ocelot_vcap_key_ipv4 ipv4;
229aae4e500SVladimir Oltean 		struct ocelot_vcap_key_ipv6 ipv6;
230aae4e500SVladimir Oltean 	} key;
2313c83654fSVladimir Oltean };
2323c83654fSVladimir Oltean 
233aae4e500SVladimir Oltean int ocelot_vcap_filter_add(struct ocelot *ocelot,
234aae4e500SVladimir Oltean 			   struct ocelot_vcap_filter *rule,
2353c83654fSVladimir Oltean 			   struct netlink_ext_ack *extack);
236aae4e500SVladimir Oltean int ocelot_vcap_filter_del(struct ocelot *ocelot,
237aae4e500SVladimir Oltean 			   struct ocelot_vcap_filter *rule);
238aae4e500SVladimir Oltean int ocelot_vcap_filter_stats_update(struct ocelot *ocelot,
239aae4e500SVladimir Oltean 				    struct ocelot_vcap_filter *rule);
240085f5b91SVladimir Oltean struct ocelot_vcap_filter *
241085f5b91SVladimir Oltean ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, int id);
2423c83654fSVladimir Oltean 
24320968054SVladimir Oltean void ocelot_detect_vcap_constants(struct ocelot *ocelot);
244aae4e500SVladimir Oltean int ocelot_vcap_init(struct ocelot *ocelot);
2453c83654fSVladimir Oltean 
2463c83654fSVladimir Oltean int ocelot_setup_tc_cls_flower(struct ocelot_port_private *priv,
2473c83654fSVladimir Oltean 			       struct flow_cls_offload *f,
2483c83654fSVladimir Oltean 			       bool ingress);
2493c83654fSVladimir Oltean 
250aae4e500SVladimir Oltean #endif /* _MSCC_OCELOT_VCAP_H_ */
251