aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/mscc/ocelot_vcap.h
blob: 0dfbfc011b2e4cd8ea606d802f5b06b56a1e4070 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
/* Microsemi Ocelot Switch driver
 * Copyright (c) 2019 Microsemi Corporation
 */

#ifndef _MSCC_OCELOT_VCAP_H_
#define _MSCC_OCELOT_VCAP_H_

#include "ocelot.h"
#include "ocelot_police.h"
#include <net/sch_generic.h>
#include <net/pkt_cls.h>

struct ocelot_ipv4 {
	u8 addr[4];
};

enum ocelot_vcap_bit {
	OCELOT_VCAP_BIT_ANY,
	OCELOT_VCAP_BIT_0,
	OCELOT_VCAP_BIT_1
};

struct ocelot_vcap_u8 {
	u8 value[1];
	u8 mask[1];
};

struct ocelot_vcap_u16 {
	u8 value[2];
	u8 mask[2];
};

struct ocelot_vcap_u24 {
	u8 value[3];
	u8 mask[3];
};

struct ocelot_vcap_u32 {
	u8 value[4];
	u8 mask[4];
};

struct ocelot_vcap_u40 {
	u8 value[5];
	u8 mask[5];
};

struct ocelot_vcap_u48 {
	u8 value[6];
	u8 mask[6];
};

struct ocelot_vcap_u64 {
	u8 value[8];
	u8 mask[8];
};

struct ocelot_vcap_u128 {
	u8 value[16];
	u8 mask[16];
};

struct ocelot_vcap_vid {
	u16 value;
	u16 mask;
};

struct ocelot_vcap_ipv4 {
	struct ocelot_ipv4 value;
	struct ocelot_ipv4 mask;
};

struct ocelot_vcap_udp_tcp {
	u16 value;
	u16 mask;
};

enum ocelot_vcap_key_type {
	OCELOT_VCAP_KEY_ANY,
	OCELOT_VCAP_KEY_ETYPE,
	OCELOT_VCAP_KEY_LLC,
	OCELOT_VCAP_KEY_SNAP,
	OCELOT_VCAP_KEY_ARP,
	OCELOT_VCAP_KEY_IPV4,
	OCELOT_VCAP_KEY_IPV6
};

struct ocelot_vcap_key_vlan {
	struct ocelot_vcap_vid vid;    /* VLAN ID (12 bit) */
	struct ocelot_vcap_u8  pcp;    /* PCP (3 bit) */
	enum ocelot_vcap_bit dei;    /* DEI */
	enum ocelot_vcap_bit tagged; /* Tagged/untagged frame */
};

struct ocelot_vcap_key_etype {
	struct ocelot_vcap_u48 dmac;
	struct ocelot_vcap_u48 smac;
	struct ocelot_vcap_u16 etype;
	struct ocelot_vcap_u16 data; /* MAC data */
};

struct ocelot_vcap_key_llc {
	struct ocelot_vcap_u48 dmac;
	struct ocelot_vcap_u48 smac;

	/* LLC header: DSAP at byte 0, SSAP at byte 1, Control at byte 2 */
	struct ocelot_vcap_u32 llc;
};

struct ocelot_vcap_key_snap {
	struct ocelot_vcap_u48 dmac;
	struct ocelot_vcap_u48 smac;

	/* SNAP header: Organization Code at byte 0, Type at byte 3 */
	struct ocelot_vcap_u40 snap;
};

struct ocelot_vcap_key_arp {
	struct ocelot_vcap_u48 smac;
	enum ocelot_vcap_bit arp;	/* Opcode ARP/RARP */
	enum ocelot_vcap_bit req;	/* Opcode request/reply */
	enum ocelot_vcap_bit unknown;    /* Opcode unknown */
	enum ocelot_vcap_bit smac_match; /* Sender MAC matches SMAC */
	enum ocelot_vcap_bit dmac_match; /* Target MAC matches DMAC */

	/**< Protocol addr. length 4, hardware length 6 */
	enum ocelot_vcap_bit length;

	enum ocelot_vcap_bit ip;       /* Protocol address type IP */
	enum  ocelot_vcap_bit ethernet; /* Hardware address type Ethernet */
	struct ocelot_vcap_ipv4 sip;     /* Sender IP address */
	struct ocelot_vcap_ipv4 dip;     /* Target IP address */
};

struct ocelot_vcap_key_ipv4 {
	enum ocelot_vcap_bit ttl;      /* TTL zero */
	enum ocelot_vcap_bit fragment; /* Fragment */
	enum ocelot_vcap_bit options;  /* Header options */
	struct ocelot_vcap_u8 ds;
	struct ocelot_vcap_u8 proto;      /* Protocol */
	struct ocelot_vcap_ipv4 sip;      /* Source IP address */
	struct ocelot_vcap_ipv4 dip;      /* Destination IP address */
	struct ocelot_vcap_u48 data;      /* Not UDP/TCP: IP data */
	struct ocelot_vcap_udp_tcp sport; /* UDP/TCP: Source port */
	struct ocelot_vcap_udp_tcp dport; /* UDP/TCP: Destination port */
	enum ocelot_vcap_bit tcp_fin;
	enum ocelot_vcap_bit tcp_syn;
	enum ocelot_vcap_bit tcp_rst;
	enum ocelot_vcap_bit tcp_psh;
	enum ocelot_vcap_bit tcp_ack;
	enum ocelot_vcap_bit tcp_urg;
	enum ocelot_vcap_bit sip_eq_dip;     /* SIP equals DIP  */
	enum ocelot_vcap_bit sport_eq_dport; /* SPORT equals DPORT  */
	enum ocelot_vcap_bit seq_zero;       /* TCP sequence number is zero */
};

struct ocelot_vcap_key_ipv6 {
	struct ocelot_vcap_u8 proto; /* IPv6 protocol */
	struct ocelot_vcap_u128 sip; /* IPv6 source (byte 0-7 ignored) */
	enum ocelot_vcap_bit ttl;  /* TTL zero */
	struct ocelot_vcap_u8 ds;
	struct ocelot_vcap_u48 data; /* Not UDP/TCP: IP data */
	struct ocelot_vcap_udp_tcp sport;
	struct ocelot_vcap_udp_tcp dport;
	enum ocelot_vcap_bit tcp_fin;
	enum ocelot_vcap_bit tcp_syn;
	enum ocelot_vcap_bit tcp_rst;
	enum ocelot_vcap_bit tcp_psh;
	enum ocelot_vcap_bit tcp_ack;
	enum ocelot_vcap_bit tcp_urg;
	enum ocelot_vcap_bit sip_eq_dip;     /* SIP equals DIP  */
	enum ocelot_vcap_bit sport_eq_dport; /* SPORT equals DPORT  */
	enum ocelot_vcap_bit seq_zero;       /* TCP sequence number is zero */
};

enum ocelot_vcap_action {
	OCELOT_VCAP_ACTION_DROP,
	OCELOT_VCAP_ACTION_TRAP,
	OCELOT_VCAP_ACTION_POLICE,
};

struct ocelot_vcap_stats {
	u64 bytes;
	u64 pkts;
	u64 used;
};

struct ocelot_vcap_filter {
	struct list_head list;

	u16 prio;
	u32 id;

	enum ocelot_vcap_action action;
	struct ocelot_vcap_stats stats;
	unsigned long ingress_port_mask;

	enum ocelot_vcap_bit dmac_mc;
	enum ocelot_vcap_bit dmac_bc;
	struct ocelot_vcap_key_vlan vlan;

	enum ocelot_vcap_key_type key_type;
	union {
		/* OCELOT_VCAP_KEY_ANY: No specific fields */
		struct ocelot_vcap_key_etype etype;
		struct ocelot_vcap_key_llc llc;
		struct ocelot_vcap_key_snap snap;
		struct ocelot_vcap_key_arp arp;
		struct ocelot_vcap_key_ipv4 ipv4;
		struct ocelot_vcap_key_ipv6 ipv6;
	} key;
	struct ocelot_policer pol;
	u32 pol_ix;
};

int ocelot_vcap_filter_add(struct ocelot *ocelot,
			   struct ocelot_vcap_filter *rule,
			   struct netlink_ext_ack *extack);
int ocelot_vcap_filter_del(struct ocelot *ocelot,
			   struct ocelot_vcap_filter *rule);
int ocelot_vcap_filter_stats_update(struct ocelot *ocelot,
				    struct ocelot_vcap_filter *rule);

int ocelot_vcap_init(struct ocelot *ocelot);

int ocelot_setup_tc_cls_flower(struct ocelot_port_private *priv,
			       struct flow_cls_offload *f,
			       bool ingress);

#endif /* _MSCC_OCELOT_VCAP_H_ */