xref: /linux/drivers/net/ethernet/mscc/ocelot_vcap.h (revision 3c83654f246b980cc65f72f5c7b1501470082ede)
1*3c83654fSVladimir Oltean /* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
2*3c83654fSVladimir Oltean /* Microsemi Ocelot Switch driver
3*3c83654fSVladimir Oltean  * Copyright (c) 2019 Microsemi Corporation
4*3c83654fSVladimir Oltean  */
5*3c83654fSVladimir Oltean 
6*3c83654fSVladimir Oltean #ifndef _MSCC_OCELOT_ACE_H_
7*3c83654fSVladimir Oltean #define _MSCC_OCELOT_ACE_H_
8*3c83654fSVladimir Oltean 
9*3c83654fSVladimir Oltean #include "ocelot.h"
10*3c83654fSVladimir Oltean #include "ocelot_police.h"
11*3c83654fSVladimir Oltean #include <net/sch_generic.h>
12*3c83654fSVladimir Oltean #include <net/pkt_cls.h>
13*3c83654fSVladimir Oltean 
14*3c83654fSVladimir Oltean struct ocelot_ipv4 {
15*3c83654fSVladimir Oltean 	u8 addr[4];
16*3c83654fSVladimir Oltean };
17*3c83654fSVladimir Oltean 
18*3c83654fSVladimir Oltean enum ocelot_vcap_bit {
19*3c83654fSVladimir Oltean 	OCELOT_VCAP_BIT_ANY,
20*3c83654fSVladimir Oltean 	OCELOT_VCAP_BIT_0,
21*3c83654fSVladimir Oltean 	OCELOT_VCAP_BIT_1
22*3c83654fSVladimir Oltean };
23*3c83654fSVladimir Oltean 
24*3c83654fSVladimir Oltean struct ocelot_vcap_u8 {
25*3c83654fSVladimir Oltean 	u8 value[1];
26*3c83654fSVladimir Oltean 	u8 mask[1];
27*3c83654fSVladimir Oltean };
28*3c83654fSVladimir Oltean 
29*3c83654fSVladimir Oltean struct ocelot_vcap_u16 {
30*3c83654fSVladimir Oltean 	u8 value[2];
31*3c83654fSVladimir Oltean 	u8 mask[2];
32*3c83654fSVladimir Oltean };
33*3c83654fSVladimir Oltean 
34*3c83654fSVladimir Oltean struct ocelot_vcap_u24 {
35*3c83654fSVladimir Oltean 	u8 value[3];
36*3c83654fSVladimir Oltean 	u8 mask[3];
37*3c83654fSVladimir Oltean };
38*3c83654fSVladimir Oltean 
39*3c83654fSVladimir Oltean struct ocelot_vcap_u32 {
40*3c83654fSVladimir Oltean 	u8 value[4];
41*3c83654fSVladimir Oltean 	u8 mask[4];
42*3c83654fSVladimir Oltean };
43*3c83654fSVladimir Oltean 
44*3c83654fSVladimir Oltean struct ocelot_vcap_u40 {
45*3c83654fSVladimir Oltean 	u8 value[5];
46*3c83654fSVladimir Oltean 	u8 mask[5];
47*3c83654fSVladimir Oltean };
48*3c83654fSVladimir Oltean 
49*3c83654fSVladimir Oltean struct ocelot_vcap_u48 {
50*3c83654fSVladimir Oltean 	u8 value[6];
51*3c83654fSVladimir Oltean 	u8 mask[6];
52*3c83654fSVladimir Oltean };
53*3c83654fSVladimir Oltean 
54*3c83654fSVladimir Oltean struct ocelot_vcap_u64 {
55*3c83654fSVladimir Oltean 	u8 value[8];
56*3c83654fSVladimir Oltean 	u8 mask[8];
57*3c83654fSVladimir Oltean };
58*3c83654fSVladimir Oltean 
59*3c83654fSVladimir Oltean struct ocelot_vcap_u128 {
60*3c83654fSVladimir Oltean 	u8 value[16];
61*3c83654fSVladimir Oltean 	u8 mask[16];
62*3c83654fSVladimir Oltean };
63*3c83654fSVladimir Oltean 
64*3c83654fSVladimir Oltean struct ocelot_vcap_vid {
65*3c83654fSVladimir Oltean 	u16 value;
66*3c83654fSVladimir Oltean 	u16 mask;
67*3c83654fSVladimir Oltean };
68*3c83654fSVladimir Oltean 
69*3c83654fSVladimir Oltean struct ocelot_vcap_ipv4 {
70*3c83654fSVladimir Oltean 	struct ocelot_ipv4 value;
71*3c83654fSVladimir Oltean 	struct ocelot_ipv4 mask;
72*3c83654fSVladimir Oltean };
73*3c83654fSVladimir Oltean 
74*3c83654fSVladimir Oltean struct ocelot_vcap_udp_tcp {
75*3c83654fSVladimir Oltean 	u16 value;
76*3c83654fSVladimir Oltean 	u16 mask;
77*3c83654fSVladimir Oltean };
78*3c83654fSVladimir Oltean 
79*3c83654fSVladimir Oltean enum ocelot_ace_type {
80*3c83654fSVladimir Oltean 	OCELOT_ACE_TYPE_ANY,
81*3c83654fSVladimir Oltean 	OCELOT_ACE_TYPE_ETYPE,
82*3c83654fSVladimir Oltean 	OCELOT_ACE_TYPE_LLC,
83*3c83654fSVladimir Oltean 	OCELOT_ACE_TYPE_SNAP,
84*3c83654fSVladimir Oltean 	OCELOT_ACE_TYPE_ARP,
85*3c83654fSVladimir Oltean 	OCELOT_ACE_TYPE_IPV4,
86*3c83654fSVladimir Oltean 	OCELOT_ACE_TYPE_IPV6
87*3c83654fSVladimir Oltean };
88*3c83654fSVladimir Oltean 
89*3c83654fSVladimir Oltean struct ocelot_ace_vlan {
90*3c83654fSVladimir Oltean 	struct ocelot_vcap_vid vid;    /* VLAN ID (12 bit) */
91*3c83654fSVladimir Oltean 	struct ocelot_vcap_u8  pcp;    /* PCP (3 bit) */
92*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit dei;    /* DEI */
93*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit tagged; /* Tagged/untagged frame */
94*3c83654fSVladimir Oltean };
95*3c83654fSVladimir Oltean 
96*3c83654fSVladimir Oltean struct ocelot_ace_frame_etype {
97*3c83654fSVladimir Oltean 	struct ocelot_vcap_u48 dmac;
98*3c83654fSVladimir Oltean 	struct ocelot_vcap_u48 smac;
99*3c83654fSVladimir Oltean 	struct ocelot_vcap_u16 etype;
100*3c83654fSVladimir Oltean 	struct ocelot_vcap_u16 data; /* MAC data */
101*3c83654fSVladimir Oltean };
102*3c83654fSVladimir Oltean 
103*3c83654fSVladimir Oltean struct ocelot_ace_frame_llc {
104*3c83654fSVladimir Oltean 	struct ocelot_vcap_u48 dmac;
105*3c83654fSVladimir Oltean 	struct ocelot_vcap_u48 smac;
106*3c83654fSVladimir Oltean 
107*3c83654fSVladimir Oltean 	/* LLC header: DSAP at byte 0, SSAP at byte 1, Control at byte 2 */
108*3c83654fSVladimir Oltean 	struct ocelot_vcap_u32 llc;
109*3c83654fSVladimir Oltean };
110*3c83654fSVladimir Oltean 
111*3c83654fSVladimir Oltean struct ocelot_ace_frame_snap {
112*3c83654fSVladimir Oltean 	struct ocelot_vcap_u48 dmac;
113*3c83654fSVladimir Oltean 	struct ocelot_vcap_u48 smac;
114*3c83654fSVladimir Oltean 
115*3c83654fSVladimir Oltean 	/* SNAP header: Organization Code at byte 0, Type at byte 3 */
116*3c83654fSVladimir Oltean 	struct ocelot_vcap_u40 snap;
117*3c83654fSVladimir Oltean };
118*3c83654fSVladimir Oltean 
119*3c83654fSVladimir Oltean struct ocelot_ace_frame_arp {
120*3c83654fSVladimir Oltean 	struct ocelot_vcap_u48 smac;
121*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit arp;	/* Opcode ARP/RARP */
122*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit req;	/* Opcode request/reply */
123*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit unknown;    /* Opcode unknown */
124*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit smac_match; /* Sender MAC matches SMAC */
125*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit dmac_match; /* Target MAC matches DMAC */
126*3c83654fSVladimir Oltean 
127*3c83654fSVladimir Oltean 	/**< Protocol addr. length 4, hardware length 6 */
128*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit length;
129*3c83654fSVladimir Oltean 
130*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit ip;       /* Protocol address type IP */
131*3c83654fSVladimir Oltean 	enum  ocelot_vcap_bit ethernet; /* Hardware address type Ethernet */
132*3c83654fSVladimir Oltean 	struct ocelot_vcap_ipv4 sip;     /* Sender IP address */
133*3c83654fSVladimir Oltean 	struct ocelot_vcap_ipv4 dip;     /* Target IP address */
134*3c83654fSVladimir Oltean };
135*3c83654fSVladimir Oltean 
136*3c83654fSVladimir Oltean struct ocelot_ace_frame_ipv4 {
137*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit ttl;      /* TTL zero */
138*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit fragment; /* Fragment */
139*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit options;  /* Header options */
140*3c83654fSVladimir Oltean 	struct ocelot_vcap_u8 ds;
141*3c83654fSVladimir Oltean 	struct ocelot_vcap_u8 proto;      /* Protocol */
142*3c83654fSVladimir Oltean 	struct ocelot_vcap_ipv4 sip;      /* Source IP address */
143*3c83654fSVladimir Oltean 	struct ocelot_vcap_ipv4 dip;      /* Destination IP address */
144*3c83654fSVladimir Oltean 	struct ocelot_vcap_u48 data;      /* Not UDP/TCP: IP data */
145*3c83654fSVladimir Oltean 	struct ocelot_vcap_udp_tcp sport; /* UDP/TCP: Source port */
146*3c83654fSVladimir Oltean 	struct ocelot_vcap_udp_tcp dport; /* UDP/TCP: Destination port */
147*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit tcp_fin;
148*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit tcp_syn;
149*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit tcp_rst;
150*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit tcp_psh;
151*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit tcp_ack;
152*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit tcp_urg;
153*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit sip_eq_dip;     /* SIP equals DIP  */
154*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit sport_eq_dport; /* SPORT equals DPORT  */
155*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit seq_zero;       /* TCP sequence number is zero */
156*3c83654fSVladimir Oltean };
157*3c83654fSVladimir Oltean 
158*3c83654fSVladimir Oltean struct ocelot_ace_frame_ipv6 {
159*3c83654fSVladimir Oltean 	struct ocelot_vcap_u8 proto; /* IPv6 protocol */
160*3c83654fSVladimir Oltean 	struct ocelot_vcap_u128 sip; /* IPv6 source (byte 0-7 ignored) */
161*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit ttl;  /* TTL zero */
162*3c83654fSVladimir Oltean 	struct ocelot_vcap_u8 ds;
163*3c83654fSVladimir Oltean 	struct ocelot_vcap_u48 data; /* Not UDP/TCP: IP data */
164*3c83654fSVladimir Oltean 	struct ocelot_vcap_udp_tcp sport;
165*3c83654fSVladimir Oltean 	struct ocelot_vcap_udp_tcp dport;
166*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit tcp_fin;
167*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit tcp_syn;
168*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit tcp_rst;
169*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit tcp_psh;
170*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit tcp_ack;
171*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit tcp_urg;
172*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit sip_eq_dip;     /* SIP equals DIP  */
173*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit sport_eq_dport; /* SPORT equals DPORT  */
174*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit seq_zero;       /* TCP sequence number is zero */
175*3c83654fSVladimir Oltean };
176*3c83654fSVladimir Oltean 
177*3c83654fSVladimir Oltean enum ocelot_ace_action {
178*3c83654fSVladimir Oltean 	OCELOT_ACL_ACTION_DROP,
179*3c83654fSVladimir Oltean 	OCELOT_ACL_ACTION_TRAP,
180*3c83654fSVladimir Oltean 	OCELOT_ACL_ACTION_POLICE,
181*3c83654fSVladimir Oltean };
182*3c83654fSVladimir Oltean 
183*3c83654fSVladimir Oltean struct ocelot_ace_stats {
184*3c83654fSVladimir Oltean 	u64 bytes;
185*3c83654fSVladimir Oltean 	u64 pkts;
186*3c83654fSVladimir Oltean 	u64 used;
187*3c83654fSVladimir Oltean };
188*3c83654fSVladimir Oltean 
189*3c83654fSVladimir Oltean struct ocelot_ace_rule {
190*3c83654fSVladimir Oltean 	struct list_head list;
191*3c83654fSVladimir Oltean 
192*3c83654fSVladimir Oltean 	u16 prio;
193*3c83654fSVladimir Oltean 	u32 id;
194*3c83654fSVladimir Oltean 
195*3c83654fSVladimir Oltean 	enum ocelot_ace_action action;
196*3c83654fSVladimir Oltean 	struct ocelot_ace_stats stats;
197*3c83654fSVladimir Oltean 	unsigned long ingress_port_mask;
198*3c83654fSVladimir Oltean 
199*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit dmac_mc;
200*3c83654fSVladimir Oltean 	enum ocelot_vcap_bit dmac_bc;
201*3c83654fSVladimir Oltean 	struct ocelot_ace_vlan vlan;
202*3c83654fSVladimir Oltean 
203*3c83654fSVladimir Oltean 	enum ocelot_ace_type type;
204*3c83654fSVladimir Oltean 	union {
205*3c83654fSVladimir Oltean 		/* ocelot_ACE_TYPE_ANY: No specific fields */
206*3c83654fSVladimir Oltean 		struct ocelot_ace_frame_etype etype;
207*3c83654fSVladimir Oltean 		struct ocelot_ace_frame_llc llc;
208*3c83654fSVladimir Oltean 		struct ocelot_ace_frame_snap snap;
209*3c83654fSVladimir Oltean 		struct ocelot_ace_frame_arp arp;
210*3c83654fSVladimir Oltean 		struct ocelot_ace_frame_ipv4 ipv4;
211*3c83654fSVladimir Oltean 		struct ocelot_ace_frame_ipv6 ipv6;
212*3c83654fSVladimir Oltean 	} frame;
213*3c83654fSVladimir Oltean 	struct ocelot_policer pol;
214*3c83654fSVladimir Oltean 	u32 pol_ix;
215*3c83654fSVladimir Oltean };
216*3c83654fSVladimir Oltean 
217*3c83654fSVladimir Oltean int ocelot_ace_rule_offload_add(struct ocelot *ocelot,
218*3c83654fSVladimir Oltean 				struct ocelot_ace_rule *rule,
219*3c83654fSVladimir Oltean 				struct netlink_ext_ack *extack);
220*3c83654fSVladimir Oltean int ocelot_ace_rule_offload_del(struct ocelot *ocelot,
221*3c83654fSVladimir Oltean 				struct ocelot_ace_rule *rule);
222*3c83654fSVladimir Oltean int ocelot_ace_rule_stats_update(struct ocelot *ocelot,
223*3c83654fSVladimir Oltean 				 struct ocelot_ace_rule *rule);
224*3c83654fSVladimir Oltean 
225*3c83654fSVladimir Oltean int ocelot_ace_init(struct ocelot *ocelot);
226*3c83654fSVladimir Oltean 
227*3c83654fSVladimir Oltean int ocelot_setup_tc_cls_flower(struct ocelot_port_private *priv,
228*3c83654fSVladimir Oltean 			       struct flow_cls_offload *f,
229*3c83654fSVladimir Oltean 			       bool ingress);
230*3c83654fSVladimir Oltean 
231*3c83654fSVladimir Oltean #endif /* _MSCC_OCELOT_ACE_H_ */
232