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