xref: /OK3568_Linux_fs/kernel/drivers/net/ethernet/mscc/ocelot_vcap.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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