xref: /linux/drivers/net/ethernet/rocker/rocker_ofdpa.c (revision 2ed2e359dea752e7758d29a423033031a0b96584)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * drivers/net/ethernet/rocker/rocker_ofdpa.c - Rocker switch OF-DPA-like
4  *					        implementation
5  * Copyright (c) 2014 Scott Feldman <sfeldma@gmail.com>
6  * Copyright (c) 2014-2016 Jiri Pirko <jiri@mellanox.com>
7  */
8 
9 #include <linux/kernel.h>
10 #include <linux/types.h>
11 #include <linux/spinlock.h>
12 #include <linux/hashtable.h>
13 #include <linux/crc32.h>
14 #include <linux/netdevice.h>
15 #include <linux/inetdevice.h>
16 #include <linux/if_vlan.h>
17 #include <linux/if_bridge.h>
18 #include <net/neighbour.h>
19 #include <net/switchdev.h>
20 #include <net/ip_fib.h>
21 #include <net/nexthop.h>
22 #include <net/arp.h>
23 
24 #include "rocker.h"
25 #include "rocker_tlv.h"
26 
27 struct ofdpa_flow_tbl_key {
28 	u32 priority;
29 	enum rocker_of_dpa_table_id tbl_id;
30 	union {
31 		struct {
32 			u32 in_pport;
33 			u32 in_pport_mask;
34 			enum rocker_of_dpa_table_id goto_tbl;
35 		} ig_port;
36 		struct {
37 			u32 in_pport;
38 			__be16 vlan_id;
39 			__be16 vlan_id_mask;
40 			enum rocker_of_dpa_table_id goto_tbl;
41 			bool untagged;
42 			__be16 new_vlan_id;
43 		} vlan;
44 		struct {
45 			u32 in_pport;
46 			u32 in_pport_mask;
47 			__be16 eth_type;
48 			u8 eth_dst[ETH_ALEN];
49 			u8 eth_dst_mask[ETH_ALEN];
50 			__be16 vlan_id;
51 			__be16 vlan_id_mask;
52 			enum rocker_of_dpa_table_id goto_tbl;
53 			bool copy_to_cpu;
54 		} term_mac;
55 		struct {
56 			__be16 eth_type;
57 			__be32 dst4;
58 			__be32 dst4_mask;
59 			enum rocker_of_dpa_table_id goto_tbl;
60 			u32 group_id;
61 		} ucast_routing;
62 		struct {
63 			u8 eth_dst[ETH_ALEN];
64 			u8 eth_dst_mask[ETH_ALEN];
65 			int has_eth_dst;
66 			int has_eth_dst_mask;
67 			__be16 vlan_id;
68 			u32 tunnel_id;
69 			enum rocker_of_dpa_table_id goto_tbl;
70 			u32 group_id;
71 			bool copy_to_cpu;
72 		} bridge;
73 		struct {
74 			u32 in_pport;
75 			u32 in_pport_mask;
76 			u8 eth_src[ETH_ALEN];
77 			u8 eth_src_mask[ETH_ALEN];
78 			u8 eth_dst[ETH_ALEN];
79 			u8 eth_dst_mask[ETH_ALEN];
80 			__be16 eth_type;
81 			__be16 vlan_id;
82 			__be16 vlan_id_mask;
83 			u8 ip_proto;
84 			u8 ip_proto_mask;
85 			u8 ip_tos;
86 			u8 ip_tos_mask;
87 			u32 group_id;
88 		} acl;
89 	};
90 };
91 
92 struct ofdpa_flow_tbl_entry {
93 	struct hlist_node entry;
94 	u32 cmd;
95 	u64 cookie;
96 	struct ofdpa_flow_tbl_key key;
97 	size_t key_len;
98 	u32 key_crc32; /* key */
99 	struct fib_info *fi;
100 };
101 
102 struct ofdpa_group_tbl_entry {
103 	struct hlist_node entry;
104 	u32 cmd;
105 	u32 group_id; /* key */
106 	u16 group_count;
107 	union {
108 		struct {
109 			u8 pop_vlan;
110 		} l2_interface;
111 		struct {
112 			u8 eth_src[ETH_ALEN];
113 			u8 eth_dst[ETH_ALEN];
114 			__be16 vlan_id;
115 			u32 group_id;
116 		} l2_rewrite;
117 		struct {
118 			u8 eth_src[ETH_ALEN];
119 			u8 eth_dst[ETH_ALEN];
120 			__be16 vlan_id;
121 			bool ttl_check;
122 			u32 group_id;
123 		} l3_unicast;
124 	};
125 
126 	u32 group_ids[] __counted_by(group_count);
127 };
128 
129 struct ofdpa_fdb_tbl_entry {
130 	struct hlist_node entry;
131 	u32 key_crc32; /* key */
132 	bool learned;
133 	unsigned long touched;
134 	struct ofdpa_fdb_tbl_key {
135 		struct ofdpa_port *ofdpa_port;
136 		u8 addr[ETH_ALEN];
137 		__be16 vlan_id;
138 	} key;
139 };
140 
141 struct ofdpa_internal_vlan_tbl_entry {
142 	struct hlist_node entry;
143 	int ifindex; /* key */
144 	u32 ref_count;
145 	__be16 vlan_id;
146 };
147 
148 struct ofdpa_neigh_tbl_entry {
149 	struct hlist_node entry;
150 	__be32 ip_addr; /* key */
151 	struct net_device *dev;
152 	u32 ref_count;
153 	u32 index;
154 	u8 eth_dst[ETH_ALEN];
155 	bool ttl_check;
156 };
157 
158 enum {
159 	OFDPA_CTRL_LINK_LOCAL_MCAST,
160 	OFDPA_CTRL_LOCAL_ARP,
161 	OFDPA_CTRL_IPV4_MCAST,
162 	OFDPA_CTRL_IPV6_MCAST,
163 	OFDPA_CTRL_DFLT_BRIDGING,
164 	OFDPA_CTRL_DFLT_OVS,
165 	OFDPA_CTRL_MAX,
166 };
167 
168 #define OFDPA_INTERNAL_VLAN_ID_BASE	0x0f00
169 #define OFDPA_N_INTERNAL_VLANS		255
170 #define OFDPA_VLAN_BITMAP_LEN		BITS_TO_LONGS(VLAN_N_VID)
171 #define OFDPA_INTERNAL_VLAN_BITMAP_LEN	BITS_TO_LONGS(OFDPA_N_INTERNAL_VLANS)
172 #define OFDPA_UNTAGGED_VID 0
173 
174 struct ofdpa {
175 	struct rocker *rocker;
176 	DECLARE_HASHTABLE(flow_tbl, 16);
177 	spinlock_t flow_tbl_lock;		/* for flow tbl accesses */
178 	u64 flow_tbl_next_cookie;
179 	DECLARE_HASHTABLE(group_tbl, 16);
180 	spinlock_t group_tbl_lock;		/* for group tbl accesses */
181 	struct timer_list fdb_cleanup_timer;
182 	DECLARE_HASHTABLE(fdb_tbl, 16);
183 	spinlock_t fdb_tbl_lock;		/* for fdb tbl accesses */
184 	unsigned long internal_vlan_bitmap[OFDPA_INTERNAL_VLAN_BITMAP_LEN];
185 	DECLARE_HASHTABLE(internal_vlan_tbl, 8);
186 	spinlock_t internal_vlan_tbl_lock;	/* for vlan tbl accesses */
187 	DECLARE_HASHTABLE(neigh_tbl, 16);
188 	spinlock_t neigh_tbl_lock;		/* for neigh tbl accesses */
189 	u32 neigh_tbl_next_index;
190 	unsigned long ageing_time;
191 	bool fib_aborted;
192 };
193 
194 struct ofdpa_port {
195 	struct ofdpa *ofdpa;
196 	struct rocker_port *rocker_port;
197 	struct net_device *dev;
198 	u32 pport;
199 	struct net_device *bridge_dev;
200 	__be16 internal_vlan_id;
201 	int stp_state;
202 	u32 brport_flags;
203 	unsigned long ageing_time;
204 	bool ctrls[OFDPA_CTRL_MAX];
205 	unsigned long vlan_bitmap[OFDPA_VLAN_BITMAP_LEN];
206 };
207 
208 static const u8 zero_mac[ETH_ALEN]   = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
209 static const u8 ff_mac[ETH_ALEN]     = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
210 static const u8 ll_mac[ETH_ALEN]     = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
211 static const u8 ll_mask[ETH_ALEN]    = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0 };
212 static const u8 mcast_mac[ETH_ALEN]  = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
213 static const u8 ipv4_mcast[ETH_ALEN] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };
214 static const u8 ipv4_mask[ETH_ALEN]  = { 0xff, 0xff, 0xff, 0x80, 0x00, 0x00 };
215 static const u8 ipv6_mcast[ETH_ALEN] = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 };
216 static const u8 ipv6_mask[ETH_ALEN]  = { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
217 
218 /* Rocker priority levels for flow table entries.  Higher
219  * priority match takes precedence over lower priority match.
220  */
221 
222 enum {
223 	OFDPA_PRIORITY_UNKNOWN = 0,
224 	OFDPA_PRIORITY_IG_PORT = 1,
225 	OFDPA_PRIORITY_VLAN = 1,
226 	OFDPA_PRIORITY_TERM_MAC_UCAST = 0,
227 	OFDPA_PRIORITY_TERM_MAC_MCAST = 1,
228 	OFDPA_PRIORITY_BRIDGING_VLAN_DFLT_EXACT = 1,
229 	OFDPA_PRIORITY_BRIDGING_VLAN_DFLT_WILD = 2,
230 	OFDPA_PRIORITY_BRIDGING_VLAN = 3,
231 	OFDPA_PRIORITY_BRIDGING_TENANT_DFLT_EXACT = 1,
232 	OFDPA_PRIORITY_BRIDGING_TENANT_DFLT_WILD = 2,
233 	OFDPA_PRIORITY_BRIDGING_TENANT = 3,
234 	OFDPA_PRIORITY_ACL_CTRL = 3,
235 	OFDPA_PRIORITY_ACL_NORMAL = 2,
236 	OFDPA_PRIORITY_ACL_DFLT = 1,
237 };
238 
ofdpa_vlan_id_is_internal(__be16 vlan_id)239 static bool ofdpa_vlan_id_is_internal(__be16 vlan_id)
240 {
241 	u16 start = OFDPA_INTERNAL_VLAN_ID_BASE;
242 	u16 end = 0xffe;
243 	u16 _vlan_id = ntohs(vlan_id);
244 
245 	return (_vlan_id >= start && _vlan_id <= end);
246 }
247 
ofdpa_port_vid_to_vlan(const struct ofdpa_port * ofdpa_port,u16 vid,bool * pop_vlan)248 static __be16 ofdpa_port_vid_to_vlan(const struct ofdpa_port *ofdpa_port,
249 				     u16 vid, bool *pop_vlan)
250 {
251 	__be16 vlan_id;
252 
253 	if (pop_vlan)
254 		*pop_vlan = false;
255 	vlan_id = htons(vid);
256 	if (!vlan_id) {
257 		vlan_id = ofdpa_port->internal_vlan_id;
258 		if (pop_vlan)
259 			*pop_vlan = true;
260 	}
261 
262 	return vlan_id;
263 }
264 
ofdpa_port_vlan_to_vid(const struct ofdpa_port * ofdpa_port,__be16 vlan_id)265 static u16 ofdpa_port_vlan_to_vid(const struct ofdpa_port *ofdpa_port,
266 				  __be16 vlan_id)
267 {
268 	if (ofdpa_vlan_id_is_internal(vlan_id))
269 		return 0;
270 
271 	return ntohs(vlan_id);
272 }
273 
ofdpa_port_is_slave(const struct ofdpa_port * ofdpa_port,const char * kind)274 static bool ofdpa_port_is_slave(const struct ofdpa_port *ofdpa_port,
275 				const char *kind)
276 {
277 	return ofdpa_port->bridge_dev &&
278 		!strcmp(ofdpa_port->bridge_dev->rtnl_link_ops->kind, kind);
279 }
280 
ofdpa_port_is_bridged(const struct ofdpa_port * ofdpa_port)281 static bool ofdpa_port_is_bridged(const struct ofdpa_port *ofdpa_port)
282 {
283 	return ofdpa_port_is_slave(ofdpa_port, "bridge");
284 }
285 
ofdpa_port_is_ovsed(const struct ofdpa_port * ofdpa_port)286 static bool ofdpa_port_is_ovsed(const struct ofdpa_port *ofdpa_port)
287 {
288 	return ofdpa_port_is_slave(ofdpa_port, "openvswitch");
289 }
290 
291 #define OFDPA_OP_FLAG_REMOVE		BIT(0)
292 #define OFDPA_OP_FLAG_NOWAIT		BIT(1)
293 #define OFDPA_OP_FLAG_LEARNED		BIT(2)
294 #define OFDPA_OP_FLAG_REFRESH		BIT(3)
295 
ofdpa_flags_nowait(int flags)296 static bool ofdpa_flags_nowait(int flags)
297 {
298 	return flags & OFDPA_OP_FLAG_NOWAIT;
299 }
300 
301 /*************************************************************
302  * Flow, group, FDB, internal VLAN and neigh command prepares
303  *************************************************************/
304 
305 static int
ofdpa_cmd_flow_tbl_add_ig_port(struct rocker_desc_info * desc_info,const struct ofdpa_flow_tbl_entry * entry)306 ofdpa_cmd_flow_tbl_add_ig_port(struct rocker_desc_info *desc_info,
307 			       const struct ofdpa_flow_tbl_entry *entry)
308 {
309 	if (rocker_tlv_put_u32(desc_info, ROCKER_TLV_OF_DPA_IN_PPORT,
310 			       entry->key.ig_port.in_pport))
311 		return -EMSGSIZE;
312 	if (rocker_tlv_put_u32(desc_info, ROCKER_TLV_OF_DPA_IN_PPORT_MASK,
313 			       entry->key.ig_port.in_pport_mask))
314 		return -EMSGSIZE;
315 	if (rocker_tlv_put_u16(desc_info, ROCKER_TLV_OF_DPA_GOTO_TABLE_ID,
316 			       entry->key.ig_port.goto_tbl))
317 		return -EMSGSIZE;
318 
319 	return 0;
320 }
321 
322 static int
ofdpa_cmd_flow_tbl_add_vlan(struct rocker_desc_info * desc_info,const struct ofdpa_flow_tbl_entry * entry)323 ofdpa_cmd_flow_tbl_add_vlan(struct rocker_desc_info *desc_info,
324 			    const struct ofdpa_flow_tbl_entry *entry)
325 {
326 	if (rocker_tlv_put_u32(desc_info, ROCKER_TLV_OF_DPA_IN_PPORT,
327 			       entry->key.vlan.in_pport))
328 		return -EMSGSIZE;
329 	if (rocker_tlv_put_be16(desc_info, ROCKER_TLV_OF_DPA_VLAN_ID,
330 				entry->key.vlan.vlan_id))
331 		return -EMSGSIZE;
332 	if (rocker_tlv_put_be16(desc_info, ROCKER_TLV_OF_DPA_VLAN_ID_MASK,
333 				entry->key.vlan.vlan_id_mask))
334 		return -EMSGSIZE;
335 	if (rocker_tlv_put_u16(desc_info, ROCKER_TLV_OF_DPA_GOTO_TABLE_ID,
336 			       entry->key.vlan.goto_tbl))
337 		return -EMSGSIZE;
338 	if (entry->key.vlan.untagged &&
339 	    rocker_tlv_put_be16(desc_info, ROCKER_TLV_OF_DPA_NEW_VLAN_ID,
340 				entry->key.vlan.new_vlan_id))
341 		return -EMSGSIZE;
342 
343 	return 0;
344 }
345 
346 static int
ofdpa_cmd_flow_tbl_add_term_mac(struct rocker_desc_info * desc_info,const struct ofdpa_flow_tbl_entry * entry)347 ofdpa_cmd_flow_tbl_add_term_mac(struct rocker_desc_info *desc_info,
348 				const struct ofdpa_flow_tbl_entry *entry)
349 {
350 	if (rocker_tlv_put_u32(desc_info, ROCKER_TLV_OF_DPA_IN_PPORT,
351 			       entry->key.term_mac.in_pport))
352 		return -EMSGSIZE;
353 	if (rocker_tlv_put_u32(desc_info, ROCKER_TLV_OF_DPA_IN_PPORT_MASK,
354 			       entry->key.term_mac.in_pport_mask))
355 		return -EMSGSIZE;
356 	if (rocker_tlv_put_be16(desc_info, ROCKER_TLV_OF_DPA_ETHERTYPE,
357 				entry->key.term_mac.eth_type))
358 		return -EMSGSIZE;
359 	if (rocker_tlv_put(desc_info, ROCKER_TLV_OF_DPA_DST_MAC,
360 			   ETH_ALEN, entry->key.term_mac.eth_dst))
361 		return -EMSGSIZE;
362 	if (rocker_tlv_put(desc_info, ROCKER_TLV_OF_DPA_DST_MAC_MASK,
363 			   ETH_ALEN, entry->key.term_mac.eth_dst_mask))
364 		return -EMSGSIZE;
365 	if (rocker_tlv_put_be16(desc_info, ROCKER_TLV_OF_DPA_VLAN_ID,
366 				entry->key.term_mac.vlan_id))
367 		return -EMSGSIZE;
368 	if (rocker_tlv_put_be16(desc_info, ROCKER_TLV_OF_DPA_VLAN_ID_MASK,
369 				entry->key.term_mac.vlan_id_mask))
370 		return -EMSGSIZE;
371 	if (rocker_tlv_put_u16(desc_info, ROCKER_TLV_OF_DPA_GOTO_TABLE_ID,
372 			       entry->key.term_mac.goto_tbl))
373 		return -EMSGSIZE;
374 	if (entry->key.term_mac.copy_to_cpu &&
375 	    rocker_tlv_put_u8(desc_info, ROCKER_TLV_OF_DPA_COPY_CPU_ACTION,
376 			      entry->key.term_mac.copy_to_cpu))
377 		return -EMSGSIZE;
378 
379 	return 0;
380 }
381 
382 static int
ofdpa_cmd_flow_tbl_add_ucast_routing(struct rocker_desc_info * desc_info,const struct ofdpa_flow_tbl_entry * entry)383 ofdpa_cmd_flow_tbl_add_ucast_routing(struct rocker_desc_info *desc_info,
384 				     const struct ofdpa_flow_tbl_entry *entry)
385 {
386 	if (rocker_tlv_put_be16(desc_info, ROCKER_TLV_OF_DPA_ETHERTYPE,
387 				entry->key.ucast_routing.eth_type))
388 		return -EMSGSIZE;
389 	if (rocker_tlv_put_be32(desc_info, ROCKER_TLV_OF_DPA_DST_IP,
390 				entry->key.ucast_routing.dst4))
391 		return -EMSGSIZE;
392 	if (rocker_tlv_put_be32(desc_info, ROCKER_TLV_OF_DPA_DST_IP_MASK,
393 				entry->key.ucast_routing.dst4_mask))
394 		return -EMSGSIZE;
395 	if (rocker_tlv_put_u16(desc_info, ROCKER_TLV_OF_DPA_GOTO_TABLE_ID,
396 			       entry->key.ucast_routing.goto_tbl))
397 		return -EMSGSIZE;
398 	if (rocker_tlv_put_u32(desc_info, ROCKER_TLV_OF_DPA_GROUP_ID,
399 			       entry->key.ucast_routing.group_id))
400 		return -EMSGSIZE;
401 
402 	return 0;
403 }
404 
405 static int
ofdpa_cmd_flow_tbl_add_bridge(struct rocker_desc_info * desc_info,const struct ofdpa_flow_tbl_entry * entry)406 ofdpa_cmd_flow_tbl_add_bridge(struct rocker_desc_info *desc_info,
407 			      const struct ofdpa_flow_tbl_entry *entry)
408 {
409 	if (entry->key.bridge.has_eth_dst &&
410 	    rocker_tlv_put(desc_info, ROCKER_TLV_OF_DPA_DST_MAC,
411 			   ETH_ALEN, entry->key.bridge.eth_dst))
412 		return -EMSGSIZE;
413 	if (entry->key.bridge.has_eth_dst_mask &&
414 	    rocker_tlv_put(desc_info, ROCKER_TLV_OF_DPA_DST_MAC_MASK,
415 			   ETH_ALEN, entry->key.bridge.eth_dst_mask))
416 		return -EMSGSIZE;
417 	if (entry->key.bridge.vlan_id &&
418 	    rocker_tlv_put_be16(desc_info, ROCKER_TLV_OF_DPA_VLAN_ID,
419 				entry->key.bridge.vlan_id))
420 		return -EMSGSIZE;
421 	if (entry->key.bridge.tunnel_id &&
422 	    rocker_tlv_put_u32(desc_info, ROCKER_TLV_OF_DPA_TUNNEL_ID,
423 			       entry->key.bridge.tunnel_id))
424 		return -EMSGSIZE;
425 	if (rocker_tlv_put_u16(desc_info, ROCKER_TLV_OF_DPA_GOTO_TABLE_ID,
426 			       entry->key.bridge.goto_tbl))
427 		return -EMSGSIZE;
428 	if (rocker_tlv_put_u32(desc_info, ROCKER_TLV_OF_DPA_GROUP_ID,
429 			       entry->key.bridge.group_id))
430 		return -EMSGSIZE;
431 	if (entry->key.bridge.copy_to_cpu &&
432 	    rocker_tlv_put_u8(desc_info, ROCKER_TLV_OF_DPA_COPY_CPU_ACTION,
433 			      entry->key.bridge.copy_to_cpu))
434 		return -EMSGSIZE;
435 
436 	return 0;
437 }
438 
439 static int
ofdpa_cmd_flow_tbl_add_acl(struct rocker_desc_info * desc_info,const struct ofdpa_flow_tbl_entry * entry)440 ofdpa_cmd_flow_tbl_add_acl(struct rocker_desc_info *desc_info,
441 			   const struct ofdpa_flow_tbl_entry *entry)
442 {
443 	if (rocker_tlv_put_u32(desc_info, ROCKER_TLV_OF_DPA_IN_PPORT,
444 			       entry->key.acl.in_pport))
445 		return -EMSGSIZE;
446 	if (rocker_tlv_put_u32(desc_info, ROCKER_TLV_OF_DPA_IN_PPORT_MASK,
447 			       entry->key.acl.in_pport_mask))
448 		return -EMSGSIZE;
449 	if (rocker_tlv_put(desc_info, ROCKER_TLV_OF_DPA_SRC_MAC,
450 			   ETH_ALEN, entry->key.acl.eth_src))
451 		return -EMSGSIZE;
452 	if (rocker_tlv_put(desc_info, ROCKER_TLV_OF_DPA_SRC_MAC_MASK,
453 			   ETH_ALEN, entry->key.acl.eth_src_mask))
454 		return -EMSGSIZE;
455 	if (rocker_tlv_put(desc_info, ROCKER_TLV_OF_DPA_DST_MAC,
456 			   ETH_ALEN, entry->key.acl.eth_dst))
457 		return -EMSGSIZE;
458 	if (rocker_tlv_put(desc_info, ROCKER_TLV_OF_DPA_DST_MAC_MASK,
459 			   ETH_ALEN, entry->key.acl.eth_dst_mask))
460 		return -EMSGSIZE;
461 	if (rocker_tlv_put_be16(desc_info, ROCKER_TLV_OF_DPA_ETHERTYPE,
462 				entry->key.acl.eth_type))
463 		return -EMSGSIZE;
464 	if (rocker_tlv_put_be16(desc_info, ROCKER_TLV_OF_DPA_VLAN_ID,
465 				entry->key.acl.vlan_id))
466 		return -EMSGSIZE;
467 	if (rocker_tlv_put_be16(desc_info, ROCKER_TLV_OF_DPA_VLAN_ID_MASK,
468 				entry->key.acl.vlan_id_mask))
469 		return -EMSGSIZE;
470 
471 	switch (ntohs(entry->key.acl.eth_type)) {
472 	case ETH_P_IP:
473 	case ETH_P_IPV6:
474 		if (rocker_tlv_put_u8(desc_info, ROCKER_TLV_OF_DPA_IP_PROTO,
475 				      entry->key.acl.ip_proto))
476 			return -EMSGSIZE;
477 		if (rocker_tlv_put_u8(desc_info,
478 				      ROCKER_TLV_OF_DPA_IP_PROTO_MASK,
479 				      entry->key.acl.ip_proto_mask))
480 			return -EMSGSIZE;
481 		if (rocker_tlv_put_u8(desc_info, ROCKER_TLV_OF_DPA_IP_DSCP,
482 				      entry->key.acl.ip_tos & 0x3f))
483 			return -EMSGSIZE;
484 		if (rocker_tlv_put_u8(desc_info,
485 				      ROCKER_TLV_OF_DPA_IP_DSCP_MASK,
486 				      entry->key.acl.ip_tos_mask & 0x3f))
487 			return -EMSGSIZE;
488 		if (rocker_tlv_put_u8(desc_info, ROCKER_TLV_OF_DPA_IP_ECN,
489 				      (entry->key.acl.ip_tos & 0xc0) >> 6))
490 			return -EMSGSIZE;
491 		if (rocker_tlv_put_u8(desc_info,
492 				      ROCKER_TLV_OF_DPA_IP_ECN_MASK,
493 				      (entry->key.acl.ip_tos_mask & 0xc0) >> 6))
494 			return -EMSGSIZE;
495 		break;
496 	}
497 
498 	if (entry->key.acl.group_id != ROCKER_GROUP_NONE &&
499 	    rocker_tlv_put_u32(desc_info, ROCKER_TLV_OF_DPA_GROUP_ID,
500 			       entry->key.acl.group_id))
501 		return -EMSGSIZE;
502 
503 	return 0;
504 }
505 
ofdpa_cmd_flow_tbl_add(const struct rocker_port * rocker_port,struct rocker_desc_info * desc_info,void * priv)506 static int ofdpa_cmd_flow_tbl_add(const struct rocker_port *rocker_port,
507 				  struct rocker_desc_info *desc_info,
508 				  void *priv)
509 {
510 	const struct ofdpa_flow_tbl_entry *entry = priv;
511 	struct rocker_tlv *cmd_info;
512 	int err = 0;
513 
514 	if (rocker_tlv_put_u16(desc_info, ROCKER_TLV_CMD_TYPE, entry->cmd))
515 		return -EMSGSIZE;
516 	cmd_info = rocker_tlv_nest_start(desc_info, ROCKER_TLV_CMD_INFO);
517 	if (!cmd_info)
518 		return -EMSGSIZE;
519 	if (rocker_tlv_put_u16(desc_info, ROCKER_TLV_OF_DPA_TABLE_ID,
520 			       entry->key.tbl_id))
521 		return -EMSGSIZE;
522 	if (rocker_tlv_put_u32(desc_info, ROCKER_TLV_OF_DPA_PRIORITY,
523 			       entry->key.priority))
524 		return -EMSGSIZE;
525 	if (rocker_tlv_put_u32(desc_info, ROCKER_TLV_OF_DPA_HARDTIME, 0))
526 		return -EMSGSIZE;
527 	if (rocker_tlv_put_u64(desc_info, ROCKER_TLV_OF_DPA_COOKIE,
528 			       entry->cookie))
529 		return -EMSGSIZE;
530 
531 	switch (entry->key.tbl_id) {
532 	case ROCKER_OF_DPA_TABLE_ID_INGRESS_PORT:
533 		err = ofdpa_cmd_flow_tbl_add_ig_port(desc_info, entry);
534 		break;
535 	case ROCKER_OF_DPA_TABLE_ID_VLAN:
536 		err = ofdpa_cmd_flow_tbl_add_vlan(desc_info, entry);
537 		break;
538 	case ROCKER_OF_DPA_TABLE_ID_TERMINATION_MAC:
539 		err = ofdpa_cmd_flow_tbl_add_term_mac(desc_info, entry);
540 		break;
541 	case ROCKER_OF_DPA_TABLE_ID_UNICAST_ROUTING:
542 		err = ofdpa_cmd_flow_tbl_add_ucast_routing(desc_info, entry);
543 		break;
544 	case ROCKER_OF_DPA_TABLE_ID_BRIDGING:
545 		err = ofdpa_cmd_flow_tbl_add_bridge(desc_info, entry);
546 		break;
547 	case ROCKER_OF_DPA_TABLE_ID_ACL_POLICY:
548 		err = ofdpa_cmd_flow_tbl_add_acl(desc_info, entry);
549 		break;
550 	default:
551 		err = -ENOTSUPP;
552 		break;
553 	}
554 
555 	if (err)
556 		return err;
557 
558 	rocker_tlv_nest_end(desc_info, cmd_info);
559 
560 	return 0;
561 }
562 
ofdpa_cmd_flow_tbl_del(const struct rocker_port * rocker_port,struct rocker_desc_info * desc_info,void * priv)563 static int ofdpa_cmd_flow_tbl_del(const struct rocker_port *rocker_port,
564 				  struct rocker_desc_info *desc_info,
565 				  void *priv)
566 {
567 	const struct ofdpa_flow_tbl_entry *entry = priv;
568 	struct rocker_tlv *cmd_info;
569 
570 	if (rocker_tlv_put_u16(desc_info, ROCKER_TLV_CMD_TYPE, entry->cmd))
571 		return -EMSGSIZE;
572 	cmd_info = rocker_tlv_nest_start(desc_info, ROCKER_TLV_CMD_INFO);
573 	if (!cmd_info)
574 		return -EMSGSIZE;
575 	if (rocker_tlv_put_u64(desc_info, ROCKER_TLV_OF_DPA_COOKIE,
576 			       entry->cookie))
577 		return -EMSGSIZE;
578 	rocker_tlv_nest_end(desc_info, cmd_info);
579 
580 	return 0;
581 }
582 
583 static int
ofdpa_cmd_group_tbl_add_l2_interface(struct rocker_desc_info * desc_info,struct ofdpa_group_tbl_entry * entry)584 ofdpa_cmd_group_tbl_add_l2_interface(struct rocker_desc_info *desc_info,
585 				     struct ofdpa_group_tbl_entry *entry)
586 {
587 	if (rocker_tlv_put_u32(desc_info, ROCKER_TLV_OF_DPA_OUT_PPORT,
588 			       ROCKER_GROUP_PORT_GET(entry->group_id)))
589 		return -EMSGSIZE;
590 	if (rocker_tlv_put_u8(desc_info, ROCKER_TLV_OF_DPA_POP_VLAN,
591 			      entry->l2_interface.pop_vlan))
592 		return -EMSGSIZE;
593 
594 	return 0;
595 }
596 
597 static int
ofdpa_cmd_group_tbl_add_l2_rewrite(struct rocker_desc_info * desc_info,const struct ofdpa_group_tbl_entry * entry)598 ofdpa_cmd_group_tbl_add_l2_rewrite(struct rocker_desc_info *desc_info,
599 				   const struct ofdpa_group_tbl_entry *entry)
600 {
601 	if (rocker_tlv_put_u32(desc_info, ROCKER_TLV_OF_DPA_GROUP_ID_LOWER,
602 			       entry->l2_rewrite.group_id))
603 		return -EMSGSIZE;
604 	if (!is_zero_ether_addr(entry->l2_rewrite.eth_src) &&
605 	    rocker_tlv_put(desc_info, ROCKER_TLV_OF_DPA_SRC_MAC,
606 			   ETH_ALEN, entry->l2_rewrite.eth_src))
607 		return -EMSGSIZE;
608 	if (!is_zero_ether_addr(entry->l2_rewrite.eth_dst) &&
609 	    rocker_tlv_put(desc_info, ROCKER_TLV_OF_DPA_DST_MAC,
610 			   ETH_ALEN, entry->l2_rewrite.eth_dst))
611 		return -EMSGSIZE;
612 	if (entry->l2_rewrite.vlan_id &&
613 	    rocker_tlv_put_be16(desc_info, ROCKER_TLV_OF_DPA_VLAN_ID,
614 				entry->l2_rewrite.vlan_id))
615 		return -EMSGSIZE;
616 
617 	return 0;
618 }
619 
620 static int
ofdpa_cmd_group_tbl_add_group_ids(struct rocker_desc_info * desc_info,const struct ofdpa_group_tbl_entry * entry)621 ofdpa_cmd_group_tbl_add_group_ids(struct rocker_desc_info *desc_info,
622 				  const struct ofdpa_group_tbl_entry *entry)
623 {
624 	int i;
625 	struct rocker_tlv *group_ids;
626 
627 	if (rocker_tlv_put_u16(desc_info, ROCKER_TLV_OF_DPA_GROUP_COUNT,
628 			       entry->group_count))
629 		return -EMSGSIZE;
630 
631 	group_ids = rocker_tlv_nest_start(desc_info,
632 					  ROCKER_TLV_OF_DPA_GROUP_IDS);
633 	if (!group_ids)
634 		return -EMSGSIZE;
635 
636 	for (i = 0; i < entry->group_count; i++)
637 		/* Note TLV array is 1-based */
638 		if (rocker_tlv_put_u32(desc_info, i + 1, entry->group_ids[i]))
639 			return -EMSGSIZE;
640 
641 	rocker_tlv_nest_end(desc_info, group_ids);
642 
643 	return 0;
644 }
645 
646 static int
ofdpa_cmd_group_tbl_add_l3_unicast(struct rocker_desc_info * desc_info,const struct ofdpa_group_tbl_entry * entry)647 ofdpa_cmd_group_tbl_add_l3_unicast(struct rocker_desc_info *desc_info,
648 				   const struct ofdpa_group_tbl_entry *entry)
649 {
650 	if (!is_zero_ether_addr(entry->l3_unicast.eth_src) &&
651 	    rocker_tlv_put(desc_info, ROCKER_TLV_OF_DPA_SRC_MAC,
652 			   ETH_ALEN, entry->l3_unicast.eth_src))
653 		return -EMSGSIZE;
654 	if (!is_zero_ether_addr(entry->l3_unicast.eth_dst) &&
655 	    rocker_tlv_put(desc_info, ROCKER_TLV_OF_DPA_DST_MAC,
656 			   ETH_ALEN, entry->l3_unicast.eth_dst))
657 		return -EMSGSIZE;
658 	if (entry->l3_unicast.vlan_id &&
659 	    rocker_tlv_put_be16(desc_info, ROCKER_TLV_OF_DPA_VLAN_ID,
660 				entry->l3_unicast.vlan_id))
661 		return -EMSGSIZE;
662 	if (rocker_tlv_put_u8(desc_info, ROCKER_TLV_OF_DPA_TTL_CHECK,
663 			      entry->l3_unicast.ttl_check))
664 		return -EMSGSIZE;
665 	if (rocker_tlv_put_u32(desc_info, ROCKER_TLV_OF_DPA_GROUP_ID_LOWER,
666 			       entry->l3_unicast.group_id))
667 		return -EMSGSIZE;
668 
669 	return 0;
670 }
671 
ofdpa_cmd_group_tbl_add(const struct rocker_port * rocker_port,struct rocker_desc_info * desc_info,void * priv)672 static int ofdpa_cmd_group_tbl_add(const struct rocker_port *rocker_port,
673 				   struct rocker_desc_info *desc_info,
674 				   void *priv)
675 {
676 	struct ofdpa_group_tbl_entry *entry = priv;
677 	struct rocker_tlv *cmd_info;
678 	int err = 0;
679 
680 	if (rocker_tlv_put_u16(desc_info, ROCKER_TLV_CMD_TYPE, entry->cmd))
681 		return -EMSGSIZE;
682 	cmd_info = rocker_tlv_nest_start(desc_info, ROCKER_TLV_CMD_INFO);
683 	if (!cmd_info)
684 		return -EMSGSIZE;
685 
686 	if (rocker_tlv_put_u32(desc_info, ROCKER_TLV_OF_DPA_GROUP_ID,
687 			       entry->group_id))
688 		return -EMSGSIZE;
689 
690 	switch (ROCKER_GROUP_TYPE_GET(entry->group_id)) {
691 	case ROCKER_OF_DPA_GROUP_TYPE_L2_INTERFACE:
692 		err = ofdpa_cmd_group_tbl_add_l2_interface(desc_info, entry);
693 		break;
694 	case ROCKER_OF_DPA_GROUP_TYPE_L2_REWRITE:
695 		err = ofdpa_cmd_group_tbl_add_l2_rewrite(desc_info, entry);
696 		break;
697 	case ROCKER_OF_DPA_GROUP_TYPE_L2_FLOOD:
698 	case ROCKER_OF_DPA_GROUP_TYPE_L2_MCAST:
699 		err = ofdpa_cmd_group_tbl_add_group_ids(desc_info, entry);
700 		break;
701 	case ROCKER_OF_DPA_GROUP_TYPE_L3_UCAST:
702 		err = ofdpa_cmd_group_tbl_add_l3_unicast(desc_info, entry);
703 		break;
704 	default:
705 		err = -ENOTSUPP;
706 		break;
707 	}
708 
709 	if (err)
710 		return err;
711 
712 	rocker_tlv_nest_end(desc_info, cmd_info);
713 
714 	return 0;
715 }
716 
ofdpa_cmd_group_tbl_del(const struct rocker_port * rocker_port,struct rocker_desc_info * desc_info,void * priv)717 static int ofdpa_cmd_group_tbl_del(const struct rocker_port *rocker_port,
718 				   struct rocker_desc_info *desc_info,
719 				   void *priv)
720 {
721 	const struct ofdpa_group_tbl_entry *entry = priv;
722 	struct rocker_tlv *cmd_info;
723 
724 	if (rocker_tlv_put_u16(desc_info, ROCKER_TLV_CMD_TYPE, entry->cmd))
725 		return -EMSGSIZE;
726 	cmd_info = rocker_tlv_nest_start(desc_info, ROCKER_TLV_CMD_INFO);
727 	if (!cmd_info)
728 		return -EMSGSIZE;
729 	if (rocker_tlv_put_u32(desc_info, ROCKER_TLV_OF_DPA_GROUP_ID,
730 			       entry->group_id))
731 		return -EMSGSIZE;
732 	rocker_tlv_nest_end(desc_info, cmd_info);
733 
734 	return 0;
735 }
736 
737 /***************************************************
738  * Flow, group, FDB, internal VLAN and neigh tables
739  ***************************************************/
740 
741 static struct ofdpa_flow_tbl_entry *
ofdpa_flow_tbl_find(const struct ofdpa * ofdpa,const struct ofdpa_flow_tbl_entry * match)742 ofdpa_flow_tbl_find(const struct ofdpa *ofdpa,
743 		    const struct ofdpa_flow_tbl_entry *match)
744 {
745 	struct ofdpa_flow_tbl_entry *found;
746 	size_t key_len = match->key_len ? match->key_len : sizeof(found->key);
747 
748 	hash_for_each_possible(ofdpa->flow_tbl, found,
749 			       entry, match->key_crc32) {
750 		if (memcmp(&found->key, &match->key, key_len) == 0)
751 			return found;
752 	}
753 
754 	return NULL;
755 }
756 
ofdpa_flow_tbl_add(struct ofdpa_port * ofdpa_port,int flags,struct ofdpa_flow_tbl_entry * match)757 static int ofdpa_flow_tbl_add(struct ofdpa_port *ofdpa_port,
758 			      int flags, struct ofdpa_flow_tbl_entry *match)
759 {
760 	struct ofdpa *ofdpa = ofdpa_port->ofdpa;
761 	struct ofdpa_flow_tbl_entry *found;
762 	size_t key_len = match->key_len ? match->key_len : sizeof(found->key);
763 	unsigned long lock_flags;
764 
765 	match->key_crc32 = crc32(~0, &match->key, key_len);
766 
767 	spin_lock_irqsave(&ofdpa->flow_tbl_lock, lock_flags);
768 
769 	found = ofdpa_flow_tbl_find(ofdpa, match);
770 
771 	if (found) {
772 		match->cookie = found->cookie;
773 		hash_del(&found->entry);
774 		kfree(found);
775 		found = match;
776 		found->cmd = ROCKER_TLV_CMD_TYPE_OF_DPA_FLOW_MOD;
777 	} else {
778 		found = match;
779 		found->cookie = ofdpa->flow_tbl_next_cookie++;
780 		found->cmd = ROCKER_TLV_CMD_TYPE_OF_DPA_FLOW_ADD;
781 	}
782 
783 	hash_add(ofdpa->flow_tbl, &found->entry, found->key_crc32);
784 	spin_unlock_irqrestore(&ofdpa->flow_tbl_lock, lock_flags);
785 
786 	return rocker_cmd_exec(ofdpa_port->rocker_port,
787 			       ofdpa_flags_nowait(flags),
788 			       ofdpa_cmd_flow_tbl_add,
789 			       found, NULL, NULL);
790 }
791 
ofdpa_flow_tbl_del(struct ofdpa_port * ofdpa_port,int flags,struct ofdpa_flow_tbl_entry * match)792 static int ofdpa_flow_tbl_del(struct ofdpa_port *ofdpa_port,
793 			      int flags, struct ofdpa_flow_tbl_entry *match)
794 {
795 	struct ofdpa *ofdpa = ofdpa_port->ofdpa;
796 	struct ofdpa_flow_tbl_entry *found;
797 	size_t key_len = match->key_len ? match->key_len : sizeof(found->key);
798 	unsigned long lock_flags;
799 	int err = 0;
800 
801 	match->key_crc32 = crc32(~0, &match->key, key_len);
802 
803 	spin_lock_irqsave(&ofdpa->flow_tbl_lock, lock_flags);
804 
805 	found = ofdpa_flow_tbl_find(ofdpa, match);
806 
807 	if (found) {
808 		hash_del(&found->entry);
809 		found->cmd = ROCKER_TLV_CMD_TYPE_OF_DPA_FLOW_DEL;
810 	}
811 
812 	spin_unlock_irqrestore(&ofdpa->flow_tbl_lock, lock_flags);
813 
814 	kfree(match);
815 
816 	if (found) {
817 		err = rocker_cmd_exec(ofdpa_port->rocker_port,
818 				      ofdpa_flags_nowait(flags),
819 				      ofdpa_cmd_flow_tbl_del,
820 				      found, NULL, NULL);
821 		kfree(found);
822 	}
823 
824 	return err;
825 }
826 
ofdpa_flow_tbl_do(struct ofdpa_port * ofdpa_port,int flags,struct ofdpa_flow_tbl_entry * entry)827 static int ofdpa_flow_tbl_do(struct ofdpa_port *ofdpa_port, int flags,
828 			     struct ofdpa_flow_tbl_entry *entry)
829 {
830 	if (flags & OFDPA_OP_FLAG_REMOVE)
831 		return ofdpa_flow_tbl_del(ofdpa_port, flags, entry);
832 	else
833 		return ofdpa_flow_tbl_add(ofdpa_port, flags, entry);
834 }
835 
ofdpa_flow_tbl_ig_port(struct ofdpa_port * ofdpa_port,int flags,u32 in_pport,u32 in_pport_mask,enum rocker_of_dpa_table_id goto_tbl)836 static int ofdpa_flow_tbl_ig_port(struct ofdpa_port *ofdpa_port, int flags,
837 				  u32 in_pport, u32 in_pport_mask,
838 				  enum rocker_of_dpa_table_id goto_tbl)
839 {
840 	struct ofdpa_flow_tbl_entry *entry;
841 
842 	entry = kzalloc_obj(*entry);
843 	if (!entry)
844 		return -ENOMEM;
845 
846 	entry->key.priority = OFDPA_PRIORITY_IG_PORT;
847 	entry->key.tbl_id = ROCKER_OF_DPA_TABLE_ID_INGRESS_PORT;
848 	entry->key.ig_port.in_pport = in_pport;
849 	entry->key.ig_port.in_pport_mask = in_pport_mask;
850 	entry->key.ig_port.goto_tbl = goto_tbl;
851 
852 	return ofdpa_flow_tbl_do(ofdpa_port, flags, entry);
853 }
854 
ofdpa_flow_tbl_vlan(struct ofdpa_port * ofdpa_port,int flags,u32 in_pport,__be16 vlan_id,__be16 vlan_id_mask,enum rocker_of_dpa_table_id goto_tbl,bool untagged,__be16 new_vlan_id)855 static int ofdpa_flow_tbl_vlan(struct ofdpa_port *ofdpa_port,
856 			       int flags,
857 			       u32 in_pport, __be16 vlan_id,
858 			       __be16 vlan_id_mask,
859 			       enum rocker_of_dpa_table_id goto_tbl,
860 			       bool untagged, __be16 new_vlan_id)
861 {
862 	struct ofdpa_flow_tbl_entry *entry;
863 
864 	entry = kzalloc_obj(*entry);
865 	if (!entry)
866 		return -ENOMEM;
867 
868 	entry->key.priority = OFDPA_PRIORITY_VLAN;
869 	entry->key.tbl_id = ROCKER_OF_DPA_TABLE_ID_VLAN;
870 	entry->key.vlan.in_pport = in_pport;
871 	entry->key.vlan.vlan_id = vlan_id;
872 	entry->key.vlan.vlan_id_mask = vlan_id_mask;
873 	entry->key.vlan.goto_tbl = goto_tbl;
874 
875 	entry->key.vlan.untagged = untagged;
876 	entry->key.vlan.new_vlan_id = new_vlan_id;
877 
878 	return ofdpa_flow_tbl_do(ofdpa_port, flags, entry);
879 }
880 
ofdpa_flow_tbl_term_mac(struct ofdpa_port * ofdpa_port,u32 in_pport,u32 in_pport_mask,__be16 eth_type,const u8 * eth_dst,const u8 * eth_dst_mask,__be16 vlan_id,__be16 vlan_id_mask,bool copy_to_cpu,int flags)881 static int ofdpa_flow_tbl_term_mac(struct ofdpa_port *ofdpa_port,
882 				   u32 in_pport, u32 in_pport_mask,
883 				   __be16 eth_type, const u8 *eth_dst,
884 				   const u8 *eth_dst_mask, __be16 vlan_id,
885 				   __be16 vlan_id_mask, bool copy_to_cpu,
886 				   int flags)
887 {
888 	struct ofdpa_flow_tbl_entry *entry;
889 
890 	entry = kzalloc_obj(*entry);
891 	if (!entry)
892 		return -ENOMEM;
893 
894 	if (is_multicast_ether_addr(eth_dst)) {
895 		entry->key.priority = OFDPA_PRIORITY_TERM_MAC_MCAST;
896 		entry->key.term_mac.goto_tbl =
897 			 ROCKER_OF_DPA_TABLE_ID_MULTICAST_ROUTING;
898 	} else {
899 		entry->key.priority = OFDPA_PRIORITY_TERM_MAC_UCAST;
900 		entry->key.term_mac.goto_tbl =
901 			 ROCKER_OF_DPA_TABLE_ID_UNICAST_ROUTING;
902 	}
903 
904 	entry->key.tbl_id = ROCKER_OF_DPA_TABLE_ID_TERMINATION_MAC;
905 	entry->key.term_mac.in_pport = in_pport;
906 	entry->key.term_mac.in_pport_mask = in_pport_mask;
907 	entry->key.term_mac.eth_type = eth_type;
908 	ether_addr_copy(entry->key.term_mac.eth_dst, eth_dst);
909 	ether_addr_copy(entry->key.term_mac.eth_dst_mask, eth_dst_mask);
910 	entry->key.term_mac.vlan_id = vlan_id;
911 	entry->key.term_mac.vlan_id_mask = vlan_id_mask;
912 	entry->key.term_mac.copy_to_cpu = copy_to_cpu;
913 
914 	return ofdpa_flow_tbl_do(ofdpa_port, flags, entry);
915 }
916 
ofdpa_flow_tbl_bridge(struct ofdpa_port * ofdpa_port,int flags,const u8 * eth_dst,const u8 * eth_dst_mask,__be16 vlan_id,u32 tunnel_id,enum rocker_of_dpa_table_id goto_tbl,u32 group_id,bool copy_to_cpu)917 static int ofdpa_flow_tbl_bridge(struct ofdpa_port *ofdpa_port,
918 				 int flags, const u8 *eth_dst,
919 				 const u8 *eth_dst_mask,  __be16 vlan_id,
920 				 u32 tunnel_id,
921 				 enum rocker_of_dpa_table_id goto_tbl,
922 				 u32 group_id, bool copy_to_cpu)
923 {
924 	struct ofdpa_flow_tbl_entry *entry;
925 	u32 priority;
926 	bool vlan_bridging = !!vlan_id;
927 	bool dflt = !eth_dst || eth_dst_mask;
928 	bool wild = false;
929 
930 	entry = kzalloc_obj(*entry, GFP_ATOMIC);
931 	if (!entry)
932 		return -ENOMEM;
933 
934 	entry->key.tbl_id = ROCKER_OF_DPA_TABLE_ID_BRIDGING;
935 
936 	if (eth_dst) {
937 		entry->key.bridge.has_eth_dst = 1;
938 		ether_addr_copy(entry->key.bridge.eth_dst, eth_dst);
939 	}
940 	if (eth_dst_mask) {
941 		entry->key.bridge.has_eth_dst_mask = 1;
942 		ether_addr_copy(entry->key.bridge.eth_dst_mask, eth_dst_mask);
943 		if (!ether_addr_equal(eth_dst_mask, ff_mac))
944 			wild = true;
945 	}
946 
947 	priority = OFDPA_PRIORITY_UNKNOWN;
948 	if (vlan_bridging && dflt && wild)
949 		priority = OFDPA_PRIORITY_BRIDGING_VLAN_DFLT_WILD;
950 	else if (vlan_bridging && dflt && !wild)
951 		priority = OFDPA_PRIORITY_BRIDGING_VLAN_DFLT_EXACT;
952 	else if (vlan_bridging && !dflt)
953 		priority = OFDPA_PRIORITY_BRIDGING_VLAN;
954 	else if (!vlan_bridging && dflt && wild)
955 		priority = OFDPA_PRIORITY_BRIDGING_TENANT_DFLT_WILD;
956 	else if (!vlan_bridging && dflt && !wild)
957 		priority = OFDPA_PRIORITY_BRIDGING_TENANT_DFLT_EXACT;
958 	else if (!vlan_bridging && !dflt)
959 		priority = OFDPA_PRIORITY_BRIDGING_TENANT;
960 
961 	entry->key.priority = priority;
962 	entry->key.bridge.vlan_id = vlan_id;
963 	entry->key.bridge.tunnel_id = tunnel_id;
964 	entry->key.bridge.goto_tbl = goto_tbl;
965 	entry->key.bridge.group_id = group_id;
966 	entry->key.bridge.copy_to_cpu = copy_to_cpu;
967 
968 	return ofdpa_flow_tbl_do(ofdpa_port, flags, entry);
969 }
970 
ofdpa_flow_tbl_ucast4_routing(struct ofdpa_port * ofdpa_port,__be16 eth_type,__be32 dst,__be32 dst_mask,u32 priority,enum rocker_of_dpa_table_id goto_tbl,u32 group_id,struct fib_info * fi,int flags)971 static int ofdpa_flow_tbl_ucast4_routing(struct ofdpa_port *ofdpa_port,
972 					 __be16 eth_type, __be32 dst,
973 					 __be32 dst_mask, u32 priority,
974 					 enum rocker_of_dpa_table_id goto_tbl,
975 					 u32 group_id, struct fib_info *fi,
976 					 int flags)
977 {
978 	struct ofdpa_flow_tbl_entry *entry;
979 
980 	entry = kzalloc_obj(*entry);
981 	if (!entry)
982 		return -ENOMEM;
983 
984 	entry->key.tbl_id = ROCKER_OF_DPA_TABLE_ID_UNICAST_ROUTING;
985 	entry->key.priority = priority;
986 	entry->key.ucast_routing.eth_type = eth_type;
987 	entry->key.ucast_routing.dst4 = dst;
988 	entry->key.ucast_routing.dst4_mask = dst_mask;
989 	entry->key.ucast_routing.goto_tbl = goto_tbl;
990 	entry->key.ucast_routing.group_id = group_id;
991 	entry->key_len = offsetof(struct ofdpa_flow_tbl_key,
992 				  ucast_routing.group_id);
993 	entry->fi = fi;
994 
995 	return ofdpa_flow_tbl_do(ofdpa_port, flags, entry);
996 }
997 
ofdpa_flow_tbl_acl(struct ofdpa_port * ofdpa_port,int flags,u32 in_pport,u32 in_pport_mask,const u8 * eth_src,const u8 * eth_src_mask,const u8 * eth_dst,const u8 * eth_dst_mask,__be16 eth_type,__be16 vlan_id,__be16 vlan_id_mask,u8 ip_proto,u8 ip_proto_mask,u8 ip_tos,u8 ip_tos_mask,u32 group_id)998 static int ofdpa_flow_tbl_acl(struct ofdpa_port *ofdpa_port, int flags,
999 			      u32 in_pport, u32 in_pport_mask,
1000 			      const u8 *eth_src, const u8 *eth_src_mask,
1001 			      const u8 *eth_dst, const u8 *eth_dst_mask,
1002 			      __be16 eth_type, __be16 vlan_id,
1003 			      __be16 vlan_id_mask, u8 ip_proto,
1004 			      u8 ip_proto_mask, u8 ip_tos, u8 ip_tos_mask,
1005 			      u32 group_id)
1006 {
1007 	u32 priority;
1008 	struct ofdpa_flow_tbl_entry *entry;
1009 
1010 	entry = kzalloc_obj(*entry);
1011 	if (!entry)
1012 		return -ENOMEM;
1013 
1014 	priority = OFDPA_PRIORITY_ACL_NORMAL;
1015 	if (eth_dst && eth_dst_mask) {
1016 		if (ether_addr_equal(eth_dst_mask, mcast_mac))
1017 			priority = OFDPA_PRIORITY_ACL_DFLT;
1018 		else if (is_link_local_ether_addr(eth_dst))
1019 			priority = OFDPA_PRIORITY_ACL_CTRL;
1020 	}
1021 
1022 	entry->key.priority = priority;
1023 	entry->key.tbl_id = ROCKER_OF_DPA_TABLE_ID_ACL_POLICY;
1024 	entry->key.acl.in_pport = in_pport;
1025 	entry->key.acl.in_pport_mask = in_pport_mask;
1026 
1027 	if (eth_src)
1028 		ether_addr_copy(entry->key.acl.eth_src, eth_src);
1029 	if (eth_src_mask)
1030 		ether_addr_copy(entry->key.acl.eth_src_mask, eth_src_mask);
1031 	if (eth_dst)
1032 		ether_addr_copy(entry->key.acl.eth_dst, eth_dst);
1033 	if (eth_dst_mask)
1034 		ether_addr_copy(entry->key.acl.eth_dst_mask, eth_dst_mask);
1035 
1036 	entry->key.acl.eth_type = eth_type;
1037 	entry->key.acl.vlan_id = vlan_id;
1038 	entry->key.acl.vlan_id_mask = vlan_id_mask;
1039 	entry->key.acl.ip_proto = ip_proto;
1040 	entry->key.acl.ip_proto_mask = ip_proto_mask;
1041 	entry->key.acl.ip_tos = ip_tos;
1042 	entry->key.acl.ip_tos_mask = ip_tos_mask;
1043 	entry->key.acl.group_id = group_id;
1044 
1045 	return ofdpa_flow_tbl_do(ofdpa_port, flags, entry);
1046 }
1047 
1048 static struct ofdpa_group_tbl_entry *
ofdpa_group_tbl_find(const struct ofdpa * ofdpa,const struct ofdpa_group_tbl_entry * match)1049 ofdpa_group_tbl_find(const struct ofdpa *ofdpa,
1050 		     const struct ofdpa_group_tbl_entry *match)
1051 {
1052 	struct ofdpa_group_tbl_entry *found;
1053 
1054 	hash_for_each_possible(ofdpa->group_tbl, found,
1055 			       entry, match->group_id) {
1056 		if (found->group_id == match->group_id)
1057 			return found;
1058 	}
1059 
1060 	return NULL;
1061 }
1062 
ofdpa_group_tbl_add(struct ofdpa_port * ofdpa_port,int flags,struct ofdpa_group_tbl_entry * match)1063 static int ofdpa_group_tbl_add(struct ofdpa_port *ofdpa_port, int flags,
1064 			       struct ofdpa_group_tbl_entry *match)
1065 {
1066 	struct ofdpa *ofdpa = ofdpa_port->ofdpa;
1067 	struct ofdpa_group_tbl_entry *found;
1068 	unsigned long lock_flags;
1069 
1070 	spin_lock_irqsave(&ofdpa->group_tbl_lock, lock_flags);
1071 
1072 	found = ofdpa_group_tbl_find(ofdpa, match);
1073 
1074 	if (found) {
1075 		hash_del(&found->entry);
1076 		kfree(found);
1077 		found = match;
1078 		found->cmd = ROCKER_TLV_CMD_TYPE_OF_DPA_GROUP_MOD;
1079 	} else {
1080 		found = match;
1081 		found->cmd = ROCKER_TLV_CMD_TYPE_OF_DPA_GROUP_ADD;
1082 	}
1083 
1084 	hash_add(ofdpa->group_tbl, &found->entry, found->group_id);
1085 
1086 	spin_unlock_irqrestore(&ofdpa->group_tbl_lock, lock_flags);
1087 
1088 	return rocker_cmd_exec(ofdpa_port->rocker_port,
1089 			       ofdpa_flags_nowait(flags),
1090 			       ofdpa_cmd_group_tbl_add,
1091 			       found, NULL, NULL);
1092 }
1093 
ofdpa_group_tbl_del(struct ofdpa_port * ofdpa_port,int flags,struct ofdpa_group_tbl_entry * match)1094 static int ofdpa_group_tbl_del(struct ofdpa_port *ofdpa_port, int flags,
1095 			       struct ofdpa_group_tbl_entry *match)
1096 {
1097 	struct ofdpa *ofdpa = ofdpa_port->ofdpa;
1098 	struct ofdpa_group_tbl_entry *found;
1099 	unsigned long lock_flags;
1100 	int err = 0;
1101 
1102 	spin_lock_irqsave(&ofdpa->group_tbl_lock, lock_flags);
1103 
1104 	found = ofdpa_group_tbl_find(ofdpa, match);
1105 
1106 	if (found) {
1107 		hash_del(&found->entry);
1108 		found->cmd = ROCKER_TLV_CMD_TYPE_OF_DPA_GROUP_DEL;
1109 	}
1110 
1111 	spin_unlock_irqrestore(&ofdpa->group_tbl_lock, lock_flags);
1112 
1113 	kfree(match);
1114 
1115 	if (found) {
1116 		err = rocker_cmd_exec(ofdpa_port->rocker_port,
1117 				      ofdpa_flags_nowait(flags),
1118 				      ofdpa_cmd_group_tbl_del,
1119 				      found, NULL, NULL);
1120 		kfree(found);
1121 	}
1122 
1123 	return err;
1124 }
1125 
ofdpa_group_tbl_do(struct ofdpa_port * ofdpa_port,int flags,struct ofdpa_group_tbl_entry * entry)1126 static int ofdpa_group_tbl_do(struct ofdpa_port *ofdpa_port, int flags,
1127 			      struct ofdpa_group_tbl_entry *entry)
1128 {
1129 	if (flags & OFDPA_OP_FLAG_REMOVE)
1130 		return ofdpa_group_tbl_del(ofdpa_port, flags, entry);
1131 	else
1132 		return ofdpa_group_tbl_add(ofdpa_port, flags, entry);
1133 }
1134 
ofdpa_group_l2_interface(struct ofdpa_port * ofdpa_port,int flags,__be16 vlan_id,u32 out_pport,int pop_vlan)1135 static int ofdpa_group_l2_interface(struct ofdpa_port *ofdpa_port,
1136 				    int flags, __be16 vlan_id,
1137 				    u32 out_pport, int pop_vlan)
1138 {
1139 	struct ofdpa_group_tbl_entry *entry;
1140 
1141 	entry = kzalloc_obj(*entry);
1142 	if (!entry)
1143 		return -ENOMEM;
1144 
1145 	entry->group_id = ROCKER_GROUP_L2_INTERFACE(vlan_id, out_pport);
1146 	entry->l2_interface.pop_vlan = pop_vlan;
1147 
1148 	return ofdpa_group_tbl_do(ofdpa_port, flags, entry);
1149 }
1150 
ofdpa_group_l2_fan_out(struct ofdpa_port * ofdpa_port,int flags,u8 group_count,const u32 * group_ids,u32 group_id)1151 static int ofdpa_group_l2_fan_out(struct ofdpa_port *ofdpa_port,
1152 				  int flags, u8 group_count,
1153 				  const u32 *group_ids, u32 group_id)
1154 {
1155 	struct ofdpa_group_tbl_entry *entry;
1156 
1157 	entry = kzalloc_flex(*entry, group_ids, group_count);
1158 	if (!entry)
1159 		return -ENOMEM;
1160 
1161 	entry->group_count = group_count;
1162 	entry->group_id = group_id;
1163 
1164 	memcpy(entry->group_ids, group_ids, group_count * sizeof(u32));
1165 
1166 	return ofdpa_group_tbl_do(ofdpa_port, flags, entry);
1167 }
1168 
ofdpa_group_l2_flood(struct ofdpa_port * ofdpa_port,int flags,__be16 vlan_id,u8 group_count,const u32 * group_ids,u32 group_id)1169 static int ofdpa_group_l2_flood(struct ofdpa_port *ofdpa_port,
1170 				int flags, __be16 vlan_id,
1171 				u8 group_count,	const u32 *group_ids,
1172 				u32 group_id)
1173 {
1174 	return ofdpa_group_l2_fan_out(ofdpa_port, flags,
1175 				      group_count, group_ids,
1176 				      group_id);
1177 }
1178 
ofdpa_group_l3_unicast(struct ofdpa_port * ofdpa_port,int flags,u32 index,const u8 * src_mac,const u8 * dst_mac,__be16 vlan_id,bool ttl_check,u32 pport)1179 static int ofdpa_group_l3_unicast(struct ofdpa_port *ofdpa_port, int flags,
1180 				  u32 index, const u8 *src_mac, const u8 *dst_mac,
1181 				  __be16 vlan_id, bool ttl_check, u32 pport)
1182 {
1183 	struct ofdpa_group_tbl_entry *entry;
1184 
1185 	entry = kzalloc_obj(*entry);
1186 	if (!entry)
1187 		return -ENOMEM;
1188 
1189 	entry->group_id = ROCKER_GROUP_L3_UNICAST(index);
1190 	if (src_mac)
1191 		ether_addr_copy(entry->l3_unicast.eth_src, src_mac);
1192 	if (dst_mac)
1193 		ether_addr_copy(entry->l3_unicast.eth_dst, dst_mac);
1194 	entry->l3_unicast.vlan_id = vlan_id;
1195 	entry->l3_unicast.ttl_check = ttl_check;
1196 	entry->l3_unicast.group_id = ROCKER_GROUP_L2_INTERFACE(vlan_id, pport);
1197 
1198 	return ofdpa_group_tbl_do(ofdpa_port, flags, entry);
1199 }
1200 
1201 static struct ofdpa_neigh_tbl_entry *
ofdpa_neigh_tbl_find(const struct ofdpa * ofdpa,__be32 ip_addr)1202 ofdpa_neigh_tbl_find(const struct ofdpa *ofdpa, __be32 ip_addr)
1203 {
1204 	struct ofdpa_neigh_tbl_entry *found;
1205 
1206 	hash_for_each_possible(ofdpa->neigh_tbl, found,
1207 			       entry, be32_to_cpu(ip_addr))
1208 		if (found->ip_addr == ip_addr)
1209 			return found;
1210 
1211 	return NULL;
1212 }
1213 
ofdpa_neigh_add(struct ofdpa * ofdpa,struct ofdpa_neigh_tbl_entry * entry)1214 static void ofdpa_neigh_add(struct ofdpa *ofdpa,
1215 			    struct ofdpa_neigh_tbl_entry *entry)
1216 {
1217 	entry->index = ofdpa->neigh_tbl_next_index++;
1218 	entry->ref_count++;
1219 	hash_add(ofdpa->neigh_tbl, &entry->entry,
1220 		 be32_to_cpu(entry->ip_addr));
1221 }
1222 
ofdpa_neigh_del(struct ofdpa_neigh_tbl_entry * entry)1223 static void ofdpa_neigh_del(struct ofdpa_neigh_tbl_entry *entry)
1224 {
1225 	if (--entry->ref_count == 0) {
1226 		hash_del(&entry->entry);
1227 		kfree(entry);
1228 	}
1229 }
1230 
ofdpa_neigh_update(struct ofdpa_neigh_tbl_entry * entry,const u8 * eth_dst,bool ttl_check)1231 static void ofdpa_neigh_update(struct ofdpa_neigh_tbl_entry *entry,
1232 			       const u8 *eth_dst, bool ttl_check)
1233 {
1234 	if (eth_dst) {
1235 		ether_addr_copy(entry->eth_dst, eth_dst);
1236 		entry->ttl_check = ttl_check;
1237 	} else {
1238 		entry->ref_count++;
1239 	}
1240 }
1241 
ofdpa_port_ipv4_neigh(struct ofdpa_port * ofdpa_port,int flags,__be32 ip_addr,const u8 * eth_dst)1242 static int ofdpa_port_ipv4_neigh(struct ofdpa_port *ofdpa_port,
1243 				 int flags, __be32 ip_addr, const u8 *eth_dst)
1244 {
1245 	struct ofdpa *ofdpa = ofdpa_port->ofdpa;
1246 	struct ofdpa_neigh_tbl_entry *entry;
1247 	struct ofdpa_neigh_tbl_entry *found;
1248 	unsigned long lock_flags;
1249 	__be16 eth_type = htons(ETH_P_IP);
1250 	enum rocker_of_dpa_table_id goto_tbl =
1251 			ROCKER_OF_DPA_TABLE_ID_ACL_POLICY;
1252 	u32 group_id;
1253 	u32 priority = 0;
1254 	bool adding = !(flags & OFDPA_OP_FLAG_REMOVE);
1255 	bool updating;
1256 	bool removing;
1257 	int err = 0;
1258 
1259 	entry = kzalloc_obj(*entry, GFP_ATOMIC);
1260 	if (!entry)
1261 		return -ENOMEM;
1262 
1263 	spin_lock_irqsave(&ofdpa->neigh_tbl_lock, lock_flags);
1264 
1265 	found = ofdpa_neigh_tbl_find(ofdpa, ip_addr);
1266 
1267 	updating = found && adding;
1268 	removing = found && !adding;
1269 	adding = !found && adding;
1270 
1271 	if (adding) {
1272 		entry->ip_addr = ip_addr;
1273 		entry->dev = ofdpa_port->dev;
1274 		ether_addr_copy(entry->eth_dst, eth_dst);
1275 		entry->ttl_check = true;
1276 		ofdpa_neigh_add(ofdpa, entry);
1277 	} else if (removing) {
1278 		memcpy(entry, found, sizeof(*entry));
1279 		ofdpa_neigh_del(found);
1280 	} else if (updating) {
1281 		ofdpa_neigh_update(found, eth_dst, true);
1282 		memcpy(entry, found, sizeof(*entry));
1283 	} else {
1284 		err = -ENOENT;
1285 	}
1286 
1287 	spin_unlock_irqrestore(&ofdpa->neigh_tbl_lock, lock_flags);
1288 
1289 	if (err)
1290 		goto err_out;
1291 
1292 	/* For each active neighbor, we have an L3 unicast group and
1293 	 * a /32 route to the neighbor, which uses the L3 unicast
1294 	 * group.  The L3 unicast group can also be referred to by
1295 	 * other routes' nexthops.
1296 	 */
1297 
1298 	err = ofdpa_group_l3_unicast(ofdpa_port, flags,
1299 				     entry->index,
1300 				     ofdpa_port->dev->dev_addr,
1301 				     entry->eth_dst,
1302 				     ofdpa_port->internal_vlan_id,
1303 				     entry->ttl_check,
1304 				     ofdpa_port->pport);
1305 	if (err) {
1306 		netdev_err(ofdpa_port->dev, "Error (%d) L3 unicast group index %d\n",
1307 			   err, entry->index);
1308 		goto err_out;
1309 	}
1310 
1311 	if (adding || removing) {
1312 		group_id = ROCKER_GROUP_L3_UNICAST(entry->index);
1313 		err = ofdpa_flow_tbl_ucast4_routing(ofdpa_port,
1314 						    eth_type, ip_addr,
1315 						    inet_make_mask(32),
1316 						    priority, goto_tbl,
1317 						    group_id, NULL, flags);
1318 
1319 		if (err)
1320 			netdev_err(ofdpa_port->dev, "Error (%d) /32 unicast route %pI4 group 0x%08x\n",
1321 				   err, &entry->ip_addr, group_id);
1322 	}
1323 
1324 err_out:
1325 	if (!adding)
1326 		kfree(entry);
1327 
1328 	return err;
1329 }
1330 
ofdpa_port_ipv4_resolve(struct ofdpa_port * ofdpa_port,__be32 ip_addr)1331 static int ofdpa_port_ipv4_resolve(struct ofdpa_port *ofdpa_port,
1332 				   __be32 ip_addr)
1333 {
1334 	struct net_device *dev = ofdpa_port->dev;
1335 	struct neighbour *n = __ipv4_neigh_lookup(dev, (__force u32)ip_addr);
1336 	int err = 0;
1337 
1338 	if (!n) {
1339 		n = neigh_create(&arp_tbl, &ip_addr, dev);
1340 		if (IS_ERR(n))
1341 			return PTR_ERR(n);
1342 	}
1343 
1344 	/* If the neigh is already resolved, then go ahead and
1345 	 * install the entry, otherwise start the ARP process to
1346 	 * resolve the neigh.
1347 	 */
1348 
1349 	if (n->nud_state & NUD_VALID)
1350 		err = ofdpa_port_ipv4_neigh(ofdpa_port, 0,
1351 					    ip_addr, n->ha);
1352 	else
1353 		neigh_event_send(n, NULL);
1354 
1355 	neigh_release(n);
1356 	return err;
1357 }
1358 
ofdpa_port_ipv4_nh(struct ofdpa_port * ofdpa_port,int flags,__be32 ip_addr,u32 * index)1359 static int ofdpa_port_ipv4_nh(struct ofdpa_port *ofdpa_port,
1360 			      int flags, __be32 ip_addr, u32 *index)
1361 {
1362 	struct ofdpa *ofdpa = ofdpa_port->ofdpa;
1363 	struct ofdpa_neigh_tbl_entry *entry;
1364 	struct ofdpa_neigh_tbl_entry *found;
1365 	unsigned long lock_flags;
1366 	bool adding = !(flags & OFDPA_OP_FLAG_REMOVE);
1367 	bool updating;
1368 	bool removing;
1369 	bool resolved = true;
1370 	int err = 0;
1371 
1372 	entry = kzalloc_obj(*entry);
1373 	if (!entry)
1374 		return -ENOMEM;
1375 
1376 	spin_lock_irqsave(&ofdpa->neigh_tbl_lock, lock_flags);
1377 
1378 	found = ofdpa_neigh_tbl_find(ofdpa, ip_addr);
1379 
1380 	updating = found && adding;
1381 	removing = found && !adding;
1382 	adding = !found && adding;
1383 
1384 	if (adding) {
1385 		entry->ip_addr = ip_addr;
1386 		entry->dev = ofdpa_port->dev;
1387 		ofdpa_neigh_add(ofdpa, entry);
1388 		*index = entry->index;
1389 		resolved = false;
1390 	} else if (removing) {
1391 		*index = found->index;
1392 		ofdpa_neigh_del(found);
1393 	} else if (updating) {
1394 		ofdpa_neigh_update(found, NULL, false);
1395 		resolved = !is_zero_ether_addr(found->eth_dst);
1396 		*index = found->index;
1397 	} else {
1398 		err = -ENOENT;
1399 	}
1400 
1401 	spin_unlock_irqrestore(&ofdpa->neigh_tbl_lock, lock_flags);
1402 
1403 	if (!adding)
1404 		kfree(entry);
1405 
1406 	if (err)
1407 		return err;
1408 
1409 	/* Resolved means neigh ip_addr is resolved to neigh mac. */
1410 
1411 	if (!resolved)
1412 		err = ofdpa_port_ipv4_resolve(ofdpa_port, ip_addr);
1413 
1414 	return err;
1415 }
1416 
ofdpa_port_get(const struct ofdpa * ofdpa,int port_index)1417 static struct ofdpa_port *ofdpa_port_get(const struct ofdpa *ofdpa,
1418 					 int port_index)
1419 {
1420 	struct rocker_port *rocker_port;
1421 
1422 	rocker_port = ofdpa->rocker->ports[port_index];
1423 	return rocker_port ? rocker_port->wpriv : NULL;
1424 }
1425 
ofdpa_port_vlan_flood_group(struct ofdpa_port * ofdpa_port,int flags,__be16 vlan_id)1426 static int ofdpa_port_vlan_flood_group(struct ofdpa_port *ofdpa_port,
1427 				       int flags, __be16 vlan_id)
1428 {
1429 	struct ofdpa_port *p;
1430 	const struct ofdpa *ofdpa = ofdpa_port->ofdpa;
1431 	unsigned int port_count = ofdpa->rocker->port_count;
1432 	u32 group_id = ROCKER_GROUP_L2_FLOOD(vlan_id, 0);
1433 	u32 *group_ids;
1434 	u8 group_count = 0;
1435 	int err = 0;
1436 	int i;
1437 
1438 	group_ids = kcalloc(port_count, sizeof(u32), GFP_KERNEL);
1439 	if (!group_ids)
1440 		return -ENOMEM;
1441 
1442 	/* Adjust the flood group for this VLAN.  The flood group
1443 	 * references an L2 interface group for each port in this
1444 	 * VLAN.
1445 	 */
1446 
1447 	for (i = 0; i < port_count; i++) {
1448 		p = ofdpa_port_get(ofdpa, i);
1449 		if (!p)
1450 			continue;
1451 		if (!ofdpa_port_is_bridged(p))
1452 			continue;
1453 		if (test_bit(ntohs(vlan_id), p->vlan_bitmap)) {
1454 			group_ids[group_count++] =
1455 				ROCKER_GROUP_L2_INTERFACE(vlan_id, p->pport);
1456 		}
1457 	}
1458 
1459 	/* If there are no bridged ports in this VLAN, we're done */
1460 	if (group_count == 0)
1461 		goto no_ports_in_vlan;
1462 
1463 	err = ofdpa_group_l2_flood(ofdpa_port, flags, vlan_id,
1464 				   group_count, group_ids, group_id);
1465 	if (err)
1466 		netdev_err(ofdpa_port->dev, "Error (%d) port VLAN l2 flood group\n", err);
1467 
1468 no_ports_in_vlan:
1469 	kfree(group_ids);
1470 	return err;
1471 }
1472 
ofdpa_port_vlan_l2_groups(struct ofdpa_port * ofdpa_port,int flags,__be16 vlan_id,bool pop_vlan)1473 static int ofdpa_port_vlan_l2_groups(struct ofdpa_port *ofdpa_port, int flags,
1474 				     __be16 vlan_id, bool pop_vlan)
1475 {
1476 	const struct ofdpa *ofdpa = ofdpa_port->ofdpa;
1477 	unsigned int port_count = ofdpa->rocker->port_count;
1478 	struct ofdpa_port *p;
1479 	bool adding = !(flags & OFDPA_OP_FLAG_REMOVE);
1480 	u32 out_pport;
1481 	int ref = 0;
1482 	int err;
1483 	int i;
1484 
1485 	/* An L2 interface group for this port in this VLAN, but
1486 	 * only when port STP state is LEARNING|FORWARDING.
1487 	 */
1488 
1489 	if (ofdpa_port->stp_state == BR_STATE_LEARNING ||
1490 	    ofdpa_port->stp_state == BR_STATE_FORWARDING) {
1491 		out_pport = ofdpa_port->pport;
1492 		err = ofdpa_group_l2_interface(ofdpa_port, flags,
1493 					       vlan_id, out_pport, pop_vlan);
1494 		if (err) {
1495 			netdev_err(ofdpa_port->dev, "Error (%d) port VLAN l2 group for pport %d\n",
1496 				   err, out_pport);
1497 			return err;
1498 		}
1499 	}
1500 
1501 	/* An L2 interface group for this VLAN to CPU port.
1502 	 * Add when first port joins this VLAN and destroy when
1503 	 * last port leaves this VLAN.
1504 	 */
1505 
1506 	for (i = 0; i < port_count; i++) {
1507 		p = ofdpa_port_get(ofdpa, i);
1508 		if (p && test_bit(ntohs(vlan_id), p->vlan_bitmap))
1509 			ref++;
1510 	}
1511 
1512 	if ((!adding || ref != 1) && (adding || ref != 0))
1513 		return 0;
1514 
1515 	out_pport = 0;
1516 	err = ofdpa_group_l2_interface(ofdpa_port, flags,
1517 				       vlan_id, out_pport, pop_vlan);
1518 	if (err) {
1519 		netdev_err(ofdpa_port->dev, "Error (%d) port VLAN l2 group for CPU port\n", err);
1520 		return err;
1521 	}
1522 
1523 	return 0;
1524 }
1525 
1526 static struct ofdpa_ctrl {
1527 	const u8 *eth_dst;
1528 	const u8 *eth_dst_mask;
1529 	__be16 eth_type;
1530 	bool acl;
1531 	bool bridge;
1532 	bool term;
1533 	bool copy_to_cpu;
1534 } ofdpa_ctrls[] = {
1535 	[OFDPA_CTRL_LINK_LOCAL_MCAST] = {
1536 		/* pass link local multicast pkts up to CPU for filtering */
1537 		.eth_dst = ll_mac,
1538 		.eth_dst_mask = ll_mask,
1539 		.acl = true,
1540 	},
1541 	[OFDPA_CTRL_LOCAL_ARP] = {
1542 		/* pass local ARP pkts up to CPU */
1543 		.eth_dst = zero_mac,
1544 		.eth_dst_mask = zero_mac,
1545 		.eth_type = htons(ETH_P_ARP),
1546 		.acl = true,
1547 	},
1548 	[OFDPA_CTRL_IPV4_MCAST] = {
1549 		/* pass IPv4 mcast pkts up to CPU, RFC 1112 */
1550 		.eth_dst = ipv4_mcast,
1551 		.eth_dst_mask = ipv4_mask,
1552 		.eth_type = htons(ETH_P_IP),
1553 		.term  = true,
1554 		.copy_to_cpu = true,
1555 	},
1556 	[OFDPA_CTRL_IPV6_MCAST] = {
1557 		/* pass IPv6 mcast pkts up to CPU, RFC 2464 */
1558 		.eth_dst = ipv6_mcast,
1559 		.eth_dst_mask = ipv6_mask,
1560 		.eth_type = htons(ETH_P_IPV6),
1561 		.term  = true,
1562 		.copy_to_cpu = true,
1563 	},
1564 	[OFDPA_CTRL_DFLT_BRIDGING] = {
1565 		/* flood any pkts on vlan */
1566 		.bridge = true,
1567 		.copy_to_cpu = true,
1568 	},
1569 	[OFDPA_CTRL_DFLT_OVS] = {
1570 		/* pass all pkts up to CPU */
1571 		.eth_dst = zero_mac,
1572 		.eth_dst_mask = zero_mac,
1573 		.acl = true,
1574 	},
1575 };
1576 
ofdpa_port_ctrl_vlan_acl(struct ofdpa_port * ofdpa_port,int flags,const struct ofdpa_ctrl * ctrl,__be16 vlan_id)1577 static int ofdpa_port_ctrl_vlan_acl(struct ofdpa_port *ofdpa_port, int flags,
1578 				    const struct ofdpa_ctrl *ctrl, __be16 vlan_id)
1579 {
1580 	u32 in_pport = ofdpa_port->pport;
1581 	u32 in_pport_mask = 0xffffffff;
1582 	u32 out_pport = 0;
1583 	const u8 *eth_src = NULL;
1584 	const u8 *eth_src_mask = NULL;
1585 	__be16 vlan_id_mask = htons(0xffff);
1586 	u8 ip_proto = 0;
1587 	u8 ip_proto_mask = 0;
1588 	u8 ip_tos = 0;
1589 	u8 ip_tos_mask = 0;
1590 	u32 group_id = ROCKER_GROUP_L2_INTERFACE(vlan_id, out_pport);
1591 	int err;
1592 
1593 	err = ofdpa_flow_tbl_acl(ofdpa_port, flags,
1594 				 in_pport, in_pport_mask,
1595 				 eth_src, eth_src_mask,
1596 				 ctrl->eth_dst, ctrl->eth_dst_mask,
1597 				 ctrl->eth_type,
1598 				 vlan_id, vlan_id_mask,
1599 				 ip_proto, ip_proto_mask,
1600 				 ip_tos, ip_tos_mask,
1601 				 group_id);
1602 
1603 	if (err)
1604 		netdev_err(ofdpa_port->dev, "Error (%d) ctrl ACL\n", err);
1605 
1606 	return err;
1607 }
1608 
ofdpa_port_ctrl_vlan_bridge(struct ofdpa_port * ofdpa_port,int flags,const struct ofdpa_ctrl * ctrl,__be16 vlan_id)1609 static int ofdpa_port_ctrl_vlan_bridge(struct ofdpa_port *ofdpa_port,
1610 				       int flags, const struct ofdpa_ctrl *ctrl,
1611 				       __be16 vlan_id)
1612 {
1613 	enum rocker_of_dpa_table_id goto_tbl =
1614 			ROCKER_OF_DPA_TABLE_ID_ACL_POLICY;
1615 	u32 group_id = ROCKER_GROUP_L2_FLOOD(vlan_id, 0);
1616 	u32 tunnel_id = 0;
1617 	int err;
1618 
1619 	if (!ofdpa_port_is_bridged(ofdpa_port))
1620 		return 0;
1621 
1622 	err = ofdpa_flow_tbl_bridge(ofdpa_port, flags,
1623 				    ctrl->eth_dst, ctrl->eth_dst_mask,
1624 				    vlan_id, tunnel_id,
1625 				    goto_tbl, group_id, ctrl->copy_to_cpu);
1626 
1627 	if (err)
1628 		netdev_err(ofdpa_port->dev, "Error (%d) ctrl FLOOD\n", err);
1629 
1630 	return err;
1631 }
1632 
ofdpa_port_ctrl_vlan_term(struct ofdpa_port * ofdpa_port,int flags,const struct ofdpa_ctrl * ctrl,__be16 vlan_id)1633 static int ofdpa_port_ctrl_vlan_term(struct ofdpa_port *ofdpa_port, int flags,
1634 				     const struct ofdpa_ctrl *ctrl, __be16 vlan_id)
1635 {
1636 	u32 in_pport_mask = 0xffffffff;
1637 	__be16 vlan_id_mask = htons(0xffff);
1638 	int err;
1639 
1640 	if (ntohs(vlan_id) == 0)
1641 		vlan_id = ofdpa_port->internal_vlan_id;
1642 
1643 	err = ofdpa_flow_tbl_term_mac(ofdpa_port, ofdpa_port->pport, in_pport_mask,
1644 				      ctrl->eth_type, ctrl->eth_dst,
1645 				      ctrl->eth_dst_mask, vlan_id,
1646 				      vlan_id_mask, ctrl->copy_to_cpu,
1647 				      flags);
1648 
1649 	if (err)
1650 		netdev_err(ofdpa_port->dev, "Error (%d) ctrl term\n", err);
1651 
1652 	return err;
1653 }
1654 
ofdpa_port_ctrl_vlan(struct ofdpa_port * ofdpa_port,int flags,const struct ofdpa_ctrl * ctrl,__be16 vlan_id)1655 static int ofdpa_port_ctrl_vlan(struct ofdpa_port *ofdpa_port, int flags,
1656 				const struct ofdpa_ctrl *ctrl, __be16 vlan_id)
1657 {
1658 	if (ctrl->acl)
1659 		return ofdpa_port_ctrl_vlan_acl(ofdpa_port, flags,
1660 						ctrl, vlan_id);
1661 	if (ctrl->bridge)
1662 		return ofdpa_port_ctrl_vlan_bridge(ofdpa_port, flags,
1663 						   ctrl, vlan_id);
1664 
1665 	if (ctrl->term)
1666 		return ofdpa_port_ctrl_vlan_term(ofdpa_port, flags,
1667 						 ctrl, vlan_id);
1668 
1669 	return -EOPNOTSUPP;
1670 }
1671 
ofdpa_port_ctrl_vlan_add(struct ofdpa_port * ofdpa_port,int flags,__be16 vlan_id)1672 static int ofdpa_port_ctrl_vlan_add(struct ofdpa_port *ofdpa_port, int flags,
1673 				    __be16 vlan_id)
1674 {
1675 	int err = 0;
1676 	int i;
1677 
1678 	for (i = 0; i < OFDPA_CTRL_MAX; i++) {
1679 		if (ofdpa_port->ctrls[i]) {
1680 			err = ofdpa_port_ctrl_vlan(ofdpa_port, flags,
1681 						   &ofdpa_ctrls[i], vlan_id);
1682 			if (err)
1683 				return err;
1684 		}
1685 	}
1686 
1687 	return err;
1688 }
1689 
ofdpa_port_ctrl(struct ofdpa_port * ofdpa_port,int flags,const struct ofdpa_ctrl * ctrl)1690 static int ofdpa_port_ctrl(struct ofdpa_port *ofdpa_port, int flags,
1691 			   const struct ofdpa_ctrl *ctrl)
1692 {
1693 	u16 vid;
1694 	int err = 0;
1695 
1696 	for (vid = 1; vid < VLAN_N_VID; vid++) {
1697 		if (!test_bit(vid, ofdpa_port->vlan_bitmap))
1698 			continue;
1699 		err = ofdpa_port_ctrl_vlan(ofdpa_port, flags,
1700 					   ctrl, htons(vid));
1701 		if (err)
1702 			break;
1703 	}
1704 
1705 	return err;
1706 }
1707 
ofdpa_port_vlan(struct ofdpa_port * ofdpa_port,int flags,u16 vid)1708 static int ofdpa_port_vlan(struct ofdpa_port *ofdpa_port, int flags,
1709 			   u16 vid)
1710 {
1711 	enum rocker_of_dpa_table_id goto_tbl =
1712 			ROCKER_OF_DPA_TABLE_ID_TERMINATION_MAC;
1713 	u32 in_pport = ofdpa_port->pport;
1714 	__be16 vlan_id = htons(vid);
1715 	__be16 vlan_id_mask = htons(0xffff);
1716 	__be16 internal_vlan_id;
1717 	bool untagged;
1718 	bool adding = !(flags & OFDPA_OP_FLAG_REMOVE);
1719 	int err;
1720 
1721 	internal_vlan_id = ofdpa_port_vid_to_vlan(ofdpa_port, vid, &untagged);
1722 
1723 	if (adding &&
1724 	    test_bit(ntohs(internal_vlan_id), ofdpa_port->vlan_bitmap))
1725 		return 0; /* already added */
1726 	else if (!adding &&
1727 		 !test_bit(ntohs(internal_vlan_id), ofdpa_port->vlan_bitmap))
1728 		return 0; /* already removed */
1729 
1730 	change_bit(ntohs(internal_vlan_id), ofdpa_port->vlan_bitmap);
1731 
1732 	if (adding) {
1733 		err = ofdpa_port_ctrl_vlan_add(ofdpa_port, flags,
1734 					       internal_vlan_id);
1735 		if (err) {
1736 			netdev_err(ofdpa_port->dev, "Error (%d) port ctrl vlan add\n", err);
1737 			goto err_vlan_add;
1738 		}
1739 	}
1740 
1741 	err = ofdpa_port_vlan_l2_groups(ofdpa_port, flags,
1742 					internal_vlan_id, untagged);
1743 	if (err) {
1744 		netdev_err(ofdpa_port->dev, "Error (%d) port VLAN l2 groups\n", err);
1745 		goto err_vlan_l2_groups;
1746 	}
1747 
1748 	err = ofdpa_port_vlan_flood_group(ofdpa_port, flags,
1749 					  internal_vlan_id);
1750 	if (err) {
1751 		netdev_err(ofdpa_port->dev, "Error (%d) port VLAN l2 flood group\n", err);
1752 		goto err_flood_group;
1753 	}
1754 
1755 	err = ofdpa_flow_tbl_vlan(ofdpa_port, flags,
1756 				  in_pport, vlan_id, vlan_id_mask,
1757 				  goto_tbl, untagged, internal_vlan_id);
1758 	if (err)
1759 		netdev_err(ofdpa_port->dev, "Error (%d) port VLAN table\n", err);
1760 
1761 	return 0;
1762 
1763 err_vlan_add:
1764 err_vlan_l2_groups:
1765 err_flood_group:
1766 	change_bit(ntohs(internal_vlan_id), ofdpa_port->vlan_bitmap);
1767 	return err;
1768 }
1769 
ofdpa_port_ig_tbl(struct ofdpa_port * ofdpa_port,int flags)1770 static int ofdpa_port_ig_tbl(struct ofdpa_port *ofdpa_port, int flags)
1771 {
1772 	enum rocker_of_dpa_table_id goto_tbl;
1773 	u32 in_pport;
1774 	u32 in_pport_mask;
1775 	int err;
1776 
1777 	/* Normal Ethernet Frames.  Matches pkts from any local physical
1778 	 * ports.  Goto VLAN tbl.
1779 	 */
1780 
1781 	in_pport = 0;
1782 	in_pport_mask = 0xffff0000;
1783 	goto_tbl = ROCKER_OF_DPA_TABLE_ID_VLAN;
1784 
1785 	err = ofdpa_flow_tbl_ig_port(ofdpa_port, flags,
1786 				     in_pport, in_pport_mask,
1787 				     goto_tbl);
1788 	if (err)
1789 		netdev_err(ofdpa_port->dev, "Error (%d) ingress port table entry\n", err);
1790 
1791 	return err;
1792 }
1793 
1794 struct ofdpa_fdb_learn_work {
1795 	struct work_struct work;
1796 	struct ofdpa_port *ofdpa_port;
1797 	int flags;
1798 	u8 addr[ETH_ALEN];
1799 	u16 vid;
1800 };
1801 
ofdpa_port_fdb_learn_work(struct work_struct * work)1802 static void ofdpa_port_fdb_learn_work(struct work_struct *work)
1803 {
1804 	const struct ofdpa_fdb_learn_work *lw =
1805 		container_of(work, struct ofdpa_fdb_learn_work, work);
1806 	bool removing = (lw->flags & OFDPA_OP_FLAG_REMOVE);
1807 	struct switchdev_notifier_fdb_info info = {};
1808 	enum switchdev_notifier_type event;
1809 
1810 	info.addr = lw->addr;
1811 	info.vid = lw->vid;
1812 	info.offloaded = !removing;
1813 	event = removing ? SWITCHDEV_FDB_DEL_TO_BRIDGE :
1814 			   SWITCHDEV_FDB_ADD_TO_BRIDGE;
1815 
1816 	rtnl_lock();
1817 	call_switchdev_notifiers(event, lw->ofdpa_port->dev, &info.info, NULL);
1818 	rtnl_unlock();
1819 
1820 	kfree(work);
1821 }
1822 
ofdpa_port_fdb_learn(struct ofdpa_port * ofdpa_port,int flags,const u8 * addr,__be16 vlan_id)1823 static int ofdpa_port_fdb_learn(struct ofdpa_port *ofdpa_port,
1824 				int flags, const u8 *addr, __be16 vlan_id)
1825 {
1826 	struct ofdpa_fdb_learn_work *lw;
1827 	enum rocker_of_dpa_table_id goto_tbl =
1828 			ROCKER_OF_DPA_TABLE_ID_ACL_POLICY;
1829 	u32 out_pport = ofdpa_port->pport;
1830 	u32 tunnel_id = 0;
1831 	u32 group_id = ROCKER_GROUP_NONE;
1832 	bool copy_to_cpu = false;
1833 	int err;
1834 
1835 	if (ofdpa_port_is_bridged(ofdpa_port))
1836 		group_id = ROCKER_GROUP_L2_INTERFACE(vlan_id, out_pport);
1837 
1838 	if (!(flags & OFDPA_OP_FLAG_REFRESH)) {
1839 		err = ofdpa_flow_tbl_bridge(ofdpa_port, flags, addr,
1840 					    NULL, vlan_id, tunnel_id, goto_tbl,
1841 					    group_id, copy_to_cpu);
1842 		if (err)
1843 			return err;
1844 	}
1845 
1846 	if (!ofdpa_port_is_bridged(ofdpa_port))
1847 		return 0;
1848 
1849 	if (!(flags & OFDPA_OP_FLAG_LEARNED))
1850 		return 0;
1851 
1852 	lw = kzalloc_obj(*lw, GFP_ATOMIC);
1853 	if (!lw)
1854 		return -ENOMEM;
1855 
1856 	INIT_WORK(&lw->work, ofdpa_port_fdb_learn_work);
1857 
1858 	lw->ofdpa_port = ofdpa_port;
1859 	lw->flags = flags;
1860 	ether_addr_copy(lw->addr, addr);
1861 	lw->vid = ofdpa_port_vlan_to_vid(ofdpa_port, vlan_id);
1862 
1863 	schedule_work(&lw->work);
1864 	return 0;
1865 }
1866 
1867 static struct ofdpa_fdb_tbl_entry *
ofdpa_fdb_tbl_find(const struct ofdpa * ofdpa,const struct ofdpa_fdb_tbl_entry * match)1868 ofdpa_fdb_tbl_find(const struct ofdpa *ofdpa,
1869 		   const struct ofdpa_fdb_tbl_entry *match)
1870 {
1871 	struct ofdpa_fdb_tbl_entry *found;
1872 
1873 	hash_for_each_possible(ofdpa->fdb_tbl, found, entry, match->key_crc32)
1874 		if (memcmp(&found->key, &match->key, sizeof(found->key)) == 0)
1875 			return found;
1876 
1877 	return NULL;
1878 }
1879 
ofdpa_port_fdb(struct ofdpa_port * ofdpa_port,const unsigned char * addr,__be16 vlan_id,int flags)1880 static int ofdpa_port_fdb(struct ofdpa_port *ofdpa_port,
1881 			  const unsigned char *addr,
1882 			  __be16 vlan_id, int flags)
1883 {
1884 	struct ofdpa *ofdpa = ofdpa_port->ofdpa;
1885 	struct ofdpa_fdb_tbl_entry *fdb;
1886 	struct ofdpa_fdb_tbl_entry *found;
1887 	bool removing = (flags & OFDPA_OP_FLAG_REMOVE);
1888 	unsigned long lock_flags;
1889 
1890 	fdb = kzalloc_obj(*fdb);
1891 	if (!fdb)
1892 		return -ENOMEM;
1893 
1894 	fdb->learned = (flags & OFDPA_OP_FLAG_LEARNED);
1895 	fdb->touched = jiffies;
1896 	fdb->key.ofdpa_port = ofdpa_port;
1897 	ether_addr_copy(fdb->key.addr, addr);
1898 	fdb->key.vlan_id = vlan_id;
1899 	fdb->key_crc32 = crc32(~0, &fdb->key, sizeof(fdb->key));
1900 
1901 	spin_lock_irqsave(&ofdpa->fdb_tbl_lock, lock_flags);
1902 
1903 	found = ofdpa_fdb_tbl_find(ofdpa, fdb);
1904 
1905 	if (found) {
1906 		found->touched = jiffies;
1907 		if (removing) {
1908 			kfree(fdb);
1909 			hash_del(&found->entry);
1910 		}
1911 	} else if (!removing) {
1912 		hash_add(ofdpa->fdb_tbl, &fdb->entry,
1913 			 fdb->key_crc32);
1914 	}
1915 
1916 	spin_unlock_irqrestore(&ofdpa->fdb_tbl_lock, lock_flags);
1917 
1918 	/* Check if adding and already exists, or removing and can't find */
1919 	if (!found == removing) {
1920 		kfree(fdb);
1921 		if (!found && removing)
1922 			return 0;
1923 		/* Refreshing existing to update aging timers */
1924 		flags |= OFDPA_OP_FLAG_REFRESH;
1925 	}
1926 
1927 	if (found && removing)
1928 		kfree(found);
1929 
1930 	return ofdpa_port_fdb_learn(ofdpa_port, flags, addr, vlan_id);
1931 }
1932 
ofdpa_port_fdb_flush(struct ofdpa_port * ofdpa_port,int flags)1933 static int ofdpa_port_fdb_flush(struct ofdpa_port *ofdpa_port, int flags)
1934 {
1935 	struct ofdpa *ofdpa = ofdpa_port->ofdpa;
1936 	struct ofdpa_fdb_tbl_entry *found;
1937 	unsigned long lock_flags;
1938 	struct hlist_node *tmp;
1939 	int bkt;
1940 	int err = 0;
1941 
1942 	if (ofdpa_port->stp_state == BR_STATE_LEARNING ||
1943 	    ofdpa_port->stp_state == BR_STATE_FORWARDING)
1944 		return 0;
1945 
1946 	flags |= OFDPA_OP_FLAG_NOWAIT | OFDPA_OP_FLAG_REMOVE;
1947 
1948 	spin_lock_irqsave(&ofdpa->fdb_tbl_lock, lock_flags);
1949 
1950 	hash_for_each_safe(ofdpa->fdb_tbl, bkt, tmp, found, entry) {
1951 		if (found->key.ofdpa_port != ofdpa_port)
1952 			continue;
1953 		if (!found->learned)
1954 			continue;
1955 		err = ofdpa_port_fdb_learn(ofdpa_port, flags,
1956 					   found->key.addr,
1957 					   found->key.vlan_id);
1958 		if (err)
1959 			goto err_out;
1960 		hash_del(&found->entry);
1961 	}
1962 
1963 err_out:
1964 	spin_unlock_irqrestore(&ofdpa->fdb_tbl_lock, lock_flags);
1965 
1966 	return err;
1967 }
1968 
ofdpa_fdb_cleanup(struct timer_list * t)1969 static void ofdpa_fdb_cleanup(struct timer_list *t)
1970 {
1971 	struct ofdpa *ofdpa = timer_container_of(ofdpa, t, fdb_cleanup_timer);
1972 	struct ofdpa_port *ofdpa_port;
1973 	struct ofdpa_fdb_tbl_entry *entry;
1974 	struct hlist_node *tmp;
1975 	unsigned long next_timer = jiffies + ofdpa->ageing_time;
1976 	unsigned long expires;
1977 	unsigned long lock_flags;
1978 	int flags = OFDPA_OP_FLAG_NOWAIT | OFDPA_OP_FLAG_REMOVE |
1979 		    OFDPA_OP_FLAG_LEARNED;
1980 	int bkt;
1981 
1982 	spin_lock_irqsave(&ofdpa->fdb_tbl_lock, lock_flags);
1983 
1984 	hash_for_each_safe(ofdpa->fdb_tbl, bkt, tmp, entry, entry) {
1985 		if (!entry->learned)
1986 			continue;
1987 		ofdpa_port = entry->key.ofdpa_port;
1988 		expires = entry->touched + ofdpa_port->ageing_time;
1989 		if (time_before_eq(expires, jiffies)) {
1990 			ofdpa_port_fdb_learn(ofdpa_port, flags,
1991 					     entry->key.addr,
1992 					     entry->key.vlan_id);
1993 			hash_del(&entry->entry);
1994 		} else if (time_before(expires, next_timer)) {
1995 			next_timer = expires;
1996 		}
1997 	}
1998 
1999 	spin_unlock_irqrestore(&ofdpa->fdb_tbl_lock, lock_flags);
2000 
2001 	mod_timer(&ofdpa->fdb_cleanup_timer, round_jiffies_up(next_timer));
2002 }
2003 
ofdpa_port_router_mac(struct ofdpa_port * ofdpa_port,int flags,__be16 vlan_id)2004 static int ofdpa_port_router_mac(struct ofdpa_port *ofdpa_port,
2005 				 int flags, __be16 vlan_id)
2006 {
2007 	u32 in_pport_mask = 0xffffffff;
2008 	__be16 eth_type;
2009 	const u8 *dst_mac_mask = ff_mac;
2010 	__be16 vlan_id_mask = htons(0xffff);
2011 	bool copy_to_cpu = false;
2012 	int err;
2013 
2014 	if (ntohs(vlan_id) == 0)
2015 		vlan_id = ofdpa_port->internal_vlan_id;
2016 
2017 	eth_type = htons(ETH_P_IP);
2018 	err = ofdpa_flow_tbl_term_mac(ofdpa_port, ofdpa_port->pport,
2019 				      in_pport_mask, eth_type,
2020 				      ofdpa_port->dev->dev_addr,
2021 				      dst_mac_mask, vlan_id, vlan_id_mask,
2022 				      copy_to_cpu, flags);
2023 	if (err)
2024 		return err;
2025 
2026 	eth_type = htons(ETH_P_IPV6);
2027 	err = ofdpa_flow_tbl_term_mac(ofdpa_port, ofdpa_port->pport,
2028 				      in_pport_mask, eth_type,
2029 				      ofdpa_port->dev->dev_addr,
2030 				      dst_mac_mask, vlan_id, vlan_id_mask,
2031 				      copy_to_cpu, flags);
2032 
2033 	return err;
2034 }
2035 
ofdpa_port_fwding(struct ofdpa_port * ofdpa_port,int flags)2036 static int ofdpa_port_fwding(struct ofdpa_port *ofdpa_port, int flags)
2037 {
2038 	bool pop_vlan;
2039 	u32 out_pport;
2040 	__be16 vlan_id;
2041 	u16 vid;
2042 	int err;
2043 
2044 	/* Port will be forwarding-enabled if its STP state is LEARNING
2045 	 * or FORWARDING.  Traffic from CPU can still egress, regardless of
2046 	 * port STP state.  Use L2 interface group on port VLANs as a way
2047 	 * to toggle port forwarding: if forwarding is disabled, L2
2048 	 * interface group will not exist.
2049 	 */
2050 
2051 	if (ofdpa_port->stp_state != BR_STATE_LEARNING &&
2052 	    ofdpa_port->stp_state != BR_STATE_FORWARDING)
2053 		flags |= OFDPA_OP_FLAG_REMOVE;
2054 
2055 	out_pport = ofdpa_port->pport;
2056 	for (vid = 1; vid < VLAN_N_VID; vid++) {
2057 		if (!test_bit(vid, ofdpa_port->vlan_bitmap))
2058 			continue;
2059 		vlan_id = htons(vid);
2060 		pop_vlan = ofdpa_vlan_id_is_internal(vlan_id);
2061 		err = ofdpa_group_l2_interface(ofdpa_port, flags,
2062 					       vlan_id, out_pport, pop_vlan);
2063 		if (err) {
2064 			netdev_err(ofdpa_port->dev, "Error (%d) port VLAN l2 group for pport %d\n",
2065 				   err, out_pport);
2066 			return err;
2067 		}
2068 	}
2069 
2070 	return 0;
2071 }
2072 
ofdpa_port_stp_update(struct ofdpa_port * ofdpa_port,int flags,u8 state)2073 static int ofdpa_port_stp_update(struct ofdpa_port *ofdpa_port,
2074 				 int flags, u8 state)
2075 {
2076 	bool want[OFDPA_CTRL_MAX] = { 0, };
2077 	bool prev_ctrls[OFDPA_CTRL_MAX];
2078 	u8 prev_state;
2079 	int err;
2080 	int i;
2081 
2082 	memcpy(prev_ctrls, ofdpa_port->ctrls, sizeof(prev_ctrls));
2083 	prev_state = ofdpa_port->stp_state;
2084 
2085 	if (ofdpa_port->stp_state == state)
2086 		return 0;
2087 
2088 	ofdpa_port->stp_state = state;
2089 
2090 	switch (state) {
2091 	case BR_STATE_DISABLED:
2092 		/* port is completely disabled */
2093 		break;
2094 	case BR_STATE_LISTENING:
2095 	case BR_STATE_BLOCKING:
2096 		want[OFDPA_CTRL_LINK_LOCAL_MCAST] = true;
2097 		break;
2098 	case BR_STATE_LEARNING:
2099 	case BR_STATE_FORWARDING:
2100 		if (!ofdpa_port_is_ovsed(ofdpa_port))
2101 			want[OFDPA_CTRL_LINK_LOCAL_MCAST] = true;
2102 		want[OFDPA_CTRL_IPV4_MCAST] = true;
2103 		want[OFDPA_CTRL_IPV6_MCAST] = true;
2104 		if (ofdpa_port_is_bridged(ofdpa_port))
2105 			want[OFDPA_CTRL_DFLT_BRIDGING] = true;
2106 		else if (ofdpa_port_is_ovsed(ofdpa_port))
2107 			want[OFDPA_CTRL_DFLT_OVS] = true;
2108 		else
2109 			want[OFDPA_CTRL_LOCAL_ARP] = true;
2110 		break;
2111 	}
2112 
2113 	for (i = 0; i < OFDPA_CTRL_MAX; i++) {
2114 		if (want[i] != ofdpa_port->ctrls[i]) {
2115 			int ctrl_flags = flags |
2116 					 (want[i] ? 0 : OFDPA_OP_FLAG_REMOVE);
2117 			err = ofdpa_port_ctrl(ofdpa_port, ctrl_flags,
2118 					      &ofdpa_ctrls[i]);
2119 			if (err)
2120 				goto err_port_ctrl;
2121 			ofdpa_port->ctrls[i] = want[i];
2122 		}
2123 	}
2124 
2125 	err = ofdpa_port_fdb_flush(ofdpa_port, flags);
2126 	if (err)
2127 		goto err_fdb_flush;
2128 
2129 	err = ofdpa_port_fwding(ofdpa_port, flags);
2130 	if (err)
2131 		goto err_port_fwding;
2132 
2133 	return 0;
2134 
2135 err_port_ctrl:
2136 err_fdb_flush:
2137 err_port_fwding:
2138 	memcpy(ofdpa_port->ctrls, prev_ctrls, sizeof(prev_ctrls));
2139 	ofdpa_port->stp_state = prev_state;
2140 	return err;
2141 }
2142 
ofdpa_port_fwd_enable(struct ofdpa_port * ofdpa_port,int flags)2143 static int ofdpa_port_fwd_enable(struct ofdpa_port *ofdpa_port, int flags)
2144 {
2145 	if (ofdpa_port_is_bridged(ofdpa_port))
2146 		/* bridge STP will enable port */
2147 		return 0;
2148 
2149 	/* port is not bridged, so simulate going to FORWARDING state */
2150 	return ofdpa_port_stp_update(ofdpa_port, flags,
2151 				     BR_STATE_FORWARDING);
2152 }
2153 
ofdpa_port_fwd_disable(struct ofdpa_port * ofdpa_port,int flags)2154 static int ofdpa_port_fwd_disable(struct ofdpa_port *ofdpa_port, int flags)
2155 {
2156 	if (ofdpa_port_is_bridged(ofdpa_port))
2157 		/* bridge STP will disable port */
2158 		return 0;
2159 
2160 	/* port is not bridged, so simulate going to DISABLED state */
2161 	return ofdpa_port_stp_update(ofdpa_port, flags,
2162 				     BR_STATE_DISABLED);
2163 }
2164 
ofdpa_port_vlan_add(struct ofdpa_port * ofdpa_port,u16 vid,u16 flags)2165 static int ofdpa_port_vlan_add(struct ofdpa_port *ofdpa_port,
2166 			       u16 vid, u16 flags)
2167 {
2168 	int err;
2169 
2170 	/* XXX deal with flags for PVID and untagged */
2171 
2172 	err = ofdpa_port_vlan(ofdpa_port, 0, vid);
2173 	if (err)
2174 		return err;
2175 
2176 	err = ofdpa_port_router_mac(ofdpa_port, 0, htons(vid));
2177 	if (err)
2178 		ofdpa_port_vlan(ofdpa_port,
2179 				OFDPA_OP_FLAG_REMOVE, vid);
2180 
2181 	return err;
2182 }
2183 
ofdpa_port_vlan_del(struct ofdpa_port * ofdpa_port,u16 vid,u16 flags)2184 static int ofdpa_port_vlan_del(struct ofdpa_port *ofdpa_port,
2185 			       u16 vid, u16 flags)
2186 {
2187 	int err;
2188 
2189 	err = ofdpa_port_router_mac(ofdpa_port, OFDPA_OP_FLAG_REMOVE,
2190 				    htons(vid));
2191 	if (err)
2192 		return err;
2193 
2194 	return ofdpa_port_vlan(ofdpa_port, OFDPA_OP_FLAG_REMOVE,
2195 			       vid);
2196 }
2197 
2198 static struct ofdpa_internal_vlan_tbl_entry *
ofdpa_internal_vlan_tbl_find(const struct ofdpa * ofdpa,int ifindex)2199 ofdpa_internal_vlan_tbl_find(const struct ofdpa *ofdpa, int ifindex)
2200 {
2201 	struct ofdpa_internal_vlan_tbl_entry *found;
2202 
2203 	hash_for_each_possible(ofdpa->internal_vlan_tbl, found,
2204 			       entry, ifindex) {
2205 		if (found->ifindex == ifindex)
2206 			return found;
2207 	}
2208 
2209 	return NULL;
2210 }
2211 
ofdpa_port_internal_vlan_id_get(struct ofdpa_port * ofdpa_port,int ifindex)2212 static __be16 ofdpa_port_internal_vlan_id_get(struct ofdpa_port *ofdpa_port,
2213 					      int ifindex)
2214 {
2215 	struct ofdpa *ofdpa = ofdpa_port->ofdpa;
2216 	struct ofdpa_internal_vlan_tbl_entry *entry;
2217 	struct ofdpa_internal_vlan_tbl_entry *found;
2218 	unsigned long lock_flags;
2219 	int i;
2220 
2221 	entry = kzalloc_obj(*entry);
2222 	if (!entry)
2223 		return 0;
2224 
2225 	entry->ifindex = ifindex;
2226 
2227 	spin_lock_irqsave(&ofdpa->internal_vlan_tbl_lock, lock_flags);
2228 
2229 	found = ofdpa_internal_vlan_tbl_find(ofdpa, ifindex);
2230 	if (found) {
2231 		kfree(entry);
2232 		goto found;
2233 	}
2234 
2235 	found = entry;
2236 	hash_add(ofdpa->internal_vlan_tbl, &found->entry, found->ifindex);
2237 
2238 	for (i = 0; i < OFDPA_N_INTERNAL_VLANS; i++) {
2239 		if (test_and_set_bit(i, ofdpa->internal_vlan_bitmap))
2240 			continue;
2241 		found->vlan_id = htons(OFDPA_INTERNAL_VLAN_ID_BASE + i);
2242 		goto found;
2243 	}
2244 
2245 	netdev_err(ofdpa_port->dev, "Out of internal VLAN IDs\n");
2246 
2247 found:
2248 	found->ref_count++;
2249 	spin_unlock_irqrestore(&ofdpa->internal_vlan_tbl_lock, lock_flags);
2250 
2251 	return found->vlan_id;
2252 }
2253 
ofdpa_port_fib_ipv4(struct ofdpa_port * ofdpa_port,__be32 dst,int dst_len,struct fib_info * fi,u32 tb_id,int flags)2254 static int ofdpa_port_fib_ipv4(struct ofdpa_port *ofdpa_port,  __be32 dst,
2255 			       int dst_len, struct fib_info *fi, u32 tb_id,
2256 			       int flags)
2257 {
2258 	const struct fib_nh *nh;
2259 	__be16 eth_type = htons(ETH_P_IP);
2260 	__be32 dst_mask = inet_make_mask(dst_len);
2261 	__be16 internal_vlan_id = ofdpa_port->internal_vlan_id;
2262 	u32 priority = fi->fib_priority;
2263 	enum rocker_of_dpa_table_id goto_tbl =
2264 		ROCKER_OF_DPA_TABLE_ID_ACL_POLICY;
2265 	u32 group_id;
2266 	bool nh_on_port;
2267 	bool has_gw;
2268 	u32 index;
2269 	int err;
2270 
2271 	/* XXX support ECMP */
2272 
2273 	nh = fib_info_nh(fi, 0);
2274 	nh_on_port = (nh->fib_nh_dev == ofdpa_port->dev);
2275 	has_gw = !!nh->fib_nh_gw4;
2276 
2277 	if (has_gw && nh_on_port) {
2278 		err = ofdpa_port_ipv4_nh(ofdpa_port, flags,
2279 					 nh->fib_nh_gw4, &index);
2280 		if (err)
2281 			return err;
2282 
2283 		group_id = ROCKER_GROUP_L3_UNICAST(index);
2284 	} else {
2285 		/* Send to CPU for processing */
2286 		group_id = ROCKER_GROUP_L2_INTERFACE(internal_vlan_id, 0);
2287 	}
2288 
2289 	err = ofdpa_flow_tbl_ucast4_routing(ofdpa_port, eth_type, dst,
2290 					    dst_mask, priority, goto_tbl,
2291 					    group_id, fi, flags);
2292 	if (err)
2293 		netdev_err(ofdpa_port->dev, "Error (%d) IPv4 route %pI4\n",
2294 			   err, &dst);
2295 
2296 	return err;
2297 }
2298 
2299 static void
ofdpa_port_internal_vlan_id_put(const struct ofdpa_port * ofdpa_port,int ifindex)2300 ofdpa_port_internal_vlan_id_put(const struct ofdpa_port *ofdpa_port,
2301 				int ifindex)
2302 {
2303 	struct ofdpa *ofdpa = ofdpa_port->ofdpa;
2304 	struct ofdpa_internal_vlan_tbl_entry *found;
2305 	unsigned long lock_flags;
2306 	unsigned long bit;
2307 
2308 	spin_lock_irqsave(&ofdpa->internal_vlan_tbl_lock, lock_flags);
2309 
2310 	found = ofdpa_internal_vlan_tbl_find(ofdpa, ifindex);
2311 	if (!found) {
2312 		netdev_err(ofdpa_port->dev,
2313 			   "ifindex (%d) not found in internal VLAN tbl\n",
2314 			   ifindex);
2315 		goto not_found;
2316 	}
2317 
2318 	if (--found->ref_count <= 0) {
2319 		bit = ntohs(found->vlan_id) - OFDPA_INTERNAL_VLAN_ID_BASE;
2320 		clear_bit(bit, ofdpa->internal_vlan_bitmap);
2321 		hash_del(&found->entry);
2322 		kfree(found);
2323 	}
2324 
2325 not_found:
2326 	spin_unlock_irqrestore(&ofdpa->internal_vlan_tbl_lock, lock_flags);
2327 }
2328 
2329 /**********************************
2330  * Rocker world ops implementation
2331  **********************************/
2332 
ofdpa_init(struct rocker * rocker)2333 static int ofdpa_init(struct rocker *rocker)
2334 {
2335 	struct ofdpa *ofdpa = rocker->wpriv;
2336 
2337 	ofdpa->rocker = rocker;
2338 
2339 	hash_init(ofdpa->flow_tbl);
2340 	spin_lock_init(&ofdpa->flow_tbl_lock);
2341 
2342 	hash_init(ofdpa->group_tbl);
2343 	spin_lock_init(&ofdpa->group_tbl_lock);
2344 
2345 	hash_init(ofdpa->fdb_tbl);
2346 	spin_lock_init(&ofdpa->fdb_tbl_lock);
2347 
2348 	hash_init(ofdpa->internal_vlan_tbl);
2349 	spin_lock_init(&ofdpa->internal_vlan_tbl_lock);
2350 
2351 	hash_init(ofdpa->neigh_tbl);
2352 	spin_lock_init(&ofdpa->neigh_tbl_lock);
2353 
2354 	timer_setup(&ofdpa->fdb_cleanup_timer, ofdpa_fdb_cleanup, 0);
2355 	mod_timer(&ofdpa->fdb_cleanup_timer, jiffies);
2356 
2357 	ofdpa->ageing_time = BR_DEFAULT_AGEING_TIME;
2358 
2359 	return 0;
2360 }
2361 
ofdpa_fini(struct rocker * rocker)2362 static void ofdpa_fini(struct rocker *rocker)
2363 {
2364 	struct ofdpa *ofdpa = rocker->wpriv;
2365 
2366 	unsigned long flags;
2367 	struct ofdpa_flow_tbl_entry *flow_entry;
2368 	struct ofdpa_group_tbl_entry *group_entry;
2369 	struct ofdpa_fdb_tbl_entry *fdb_entry;
2370 	struct ofdpa_internal_vlan_tbl_entry *internal_vlan_entry;
2371 	struct ofdpa_neigh_tbl_entry *neigh_entry;
2372 	struct hlist_node *tmp;
2373 	int bkt;
2374 
2375 	timer_delete_sync(&ofdpa->fdb_cleanup_timer);
2376 	flush_workqueue(rocker->rocker_owq);
2377 
2378 	spin_lock_irqsave(&ofdpa->flow_tbl_lock, flags);
2379 	hash_for_each_safe(ofdpa->flow_tbl, bkt, tmp, flow_entry, entry)
2380 		hash_del(&flow_entry->entry);
2381 	spin_unlock_irqrestore(&ofdpa->flow_tbl_lock, flags);
2382 
2383 	spin_lock_irqsave(&ofdpa->group_tbl_lock, flags);
2384 	hash_for_each_safe(ofdpa->group_tbl, bkt, tmp, group_entry, entry)
2385 		hash_del(&group_entry->entry);
2386 	spin_unlock_irqrestore(&ofdpa->group_tbl_lock, flags);
2387 
2388 	spin_lock_irqsave(&ofdpa->fdb_tbl_lock, flags);
2389 	hash_for_each_safe(ofdpa->fdb_tbl, bkt, tmp, fdb_entry, entry)
2390 		hash_del(&fdb_entry->entry);
2391 	spin_unlock_irqrestore(&ofdpa->fdb_tbl_lock, flags);
2392 
2393 	spin_lock_irqsave(&ofdpa->internal_vlan_tbl_lock, flags);
2394 	hash_for_each_safe(ofdpa->internal_vlan_tbl, bkt,
2395 			   tmp, internal_vlan_entry, entry)
2396 		hash_del(&internal_vlan_entry->entry);
2397 	spin_unlock_irqrestore(&ofdpa->internal_vlan_tbl_lock, flags);
2398 
2399 	spin_lock_irqsave(&ofdpa->neigh_tbl_lock, flags);
2400 	hash_for_each_safe(ofdpa->neigh_tbl, bkt, tmp, neigh_entry, entry)
2401 		hash_del(&neigh_entry->entry);
2402 	spin_unlock_irqrestore(&ofdpa->neigh_tbl_lock, flags);
2403 }
2404 
ofdpa_port_pre_init(struct rocker_port * rocker_port)2405 static int ofdpa_port_pre_init(struct rocker_port *rocker_port)
2406 {
2407 	struct ofdpa_port *ofdpa_port = rocker_port->wpriv;
2408 
2409 	ofdpa_port->ofdpa = rocker_port->rocker->wpriv;
2410 	ofdpa_port->rocker_port = rocker_port;
2411 	ofdpa_port->dev = rocker_port->dev;
2412 	ofdpa_port->pport = rocker_port->pport;
2413 	ofdpa_port->brport_flags = BR_LEARNING;
2414 	ofdpa_port->ageing_time = BR_DEFAULT_AGEING_TIME;
2415 	return 0;
2416 }
2417 
ofdpa_port_init(struct rocker_port * rocker_port)2418 static int ofdpa_port_init(struct rocker_port *rocker_port)
2419 {
2420 	struct ofdpa_port *ofdpa_port = rocker_port->wpriv;
2421 	int err;
2422 
2423 	rocker_port_set_learning(rocker_port,
2424 				 !!(ofdpa_port->brport_flags & BR_LEARNING));
2425 
2426 	err = ofdpa_port_ig_tbl(ofdpa_port, 0);
2427 	if (err) {
2428 		netdev_err(ofdpa_port->dev, "install ig port table failed\n");
2429 		return err;
2430 	}
2431 
2432 	ofdpa_port->internal_vlan_id =
2433 		ofdpa_port_internal_vlan_id_get(ofdpa_port,
2434 						ofdpa_port->dev->ifindex);
2435 
2436 	err = ofdpa_port_vlan_add(ofdpa_port, OFDPA_UNTAGGED_VID, 0);
2437 	if (err) {
2438 		netdev_err(ofdpa_port->dev, "install untagged VLAN failed\n");
2439 		goto err_untagged_vlan;
2440 	}
2441 	return 0;
2442 
2443 err_untagged_vlan:
2444 	ofdpa_port_ig_tbl(ofdpa_port, OFDPA_OP_FLAG_REMOVE);
2445 	return err;
2446 }
2447 
ofdpa_port_fini(struct rocker_port * rocker_port)2448 static void ofdpa_port_fini(struct rocker_port *rocker_port)
2449 {
2450 	struct ofdpa_port *ofdpa_port = rocker_port->wpriv;
2451 
2452 	ofdpa_port_ig_tbl(ofdpa_port, OFDPA_OP_FLAG_REMOVE);
2453 }
2454 
ofdpa_port_open(struct rocker_port * rocker_port)2455 static int ofdpa_port_open(struct rocker_port *rocker_port)
2456 {
2457 	struct ofdpa_port *ofdpa_port = rocker_port->wpriv;
2458 
2459 	return ofdpa_port_fwd_enable(ofdpa_port, 0);
2460 }
2461 
ofdpa_port_stop(struct rocker_port * rocker_port)2462 static void ofdpa_port_stop(struct rocker_port *rocker_port)
2463 {
2464 	struct ofdpa_port *ofdpa_port = rocker_port->wpriv;
2465 
2466 	ofdpa_port_fwd_disable(ofdpa_port, OFDPA_OP_FLAG_NOWAIT);
2467 }
2468 
ofdpa_port_attr_stp_state_set(struct rocker_port * rocker_port,u8 state)2469 static int ofdpa_port_attr_stp_state_set(struct rocker_port *rocker_port,
2470 					 u8 state)
2471 {
2472 	struct ofdpa_port *ofdpa_port = rocker_port->wpriv;
2473 
2474 	return ofdpa_port_stp_update(ofdpa_port, 0, state);
2475 }
2476 
ofdpa_port_attr_bridge_flags_set(struct rocker_port * rocker_port,unsigned long brport_flags)2477 static int ofdpa_port_attr_bridge_flags_set(struct rocker_port *rocker_port,
2478 					    unsigned long brport_flags)
2479 {
2480 	struct ofdpa_port *ofdpa_port = rocker_port->wpriv;
2481 	unsigned long orig_flags;
2482 	int err = 0;
2483 
2484 	orig_flags = ofdpa_port->brport_flags;
2485 	ofdpa_port->brport_flags = brport_flags;
2486 
2487 	if ((orig_flags ^ ofdpa_port->brport_flags) & BR_LEARNING)
2488 		err = rocker_port_set_learning(ofdpa_port->rocker_port,
2489 					       !!(ofdpa_port->brport_flags & BR_LEARNING));
2490 
2491 	return err;
2492 }
2493 
2494 static int
ofdpa_port_attr_bridge_flags_support_get(const struct rocker_port * rocker_port,unsigned long * p_brport_flags_support)2495 ofdpa_port_attr_bridge_flags_support_get(const struct rocker_port *
2496 					 rocker_port,
2497 					 unsigned long *
2498 					 p_brport_flags_support)
2499 {
2500 	*p_brport_flags_support = BR_LEARNING;
2501 	return 0;
2502 }
2503 
2504 static int
ofdpa_port_attr_bridge_ageing_time_set(struct rocker_port * rocker_port,u32 ageing_time)2505 ofdpa_port_attr_bridge_ageing_time_set(struct rocker_port *rocker_port,
2506 				       u32 ageing_time)
2507 {
2508 	struct ofdpa_port *ofdpa_port = rocker_port->wpriv;
2509 	struct ofdpa *ofdpa = ofdpa_port->ofdpa;
2510 
2511 	ofdpa_port->ageing_time = clock_t_to_jiffies(ageing_time);
2512 	if (ofdpa_port->ageing_time < ofdpa->ageing_time)
2513 		ofdpa->ageing_time = ofdpa_port->ageing_time;
2514 	mod_timer(&ofdpa_port->ofdpa->fdb_cleanup_timer, jiffies);
2515 
2516 	return 0;
2517 }
2518 
ofdpa_port_obj_vlan_add(struct rocker_port * rocker_port,const struct switchdev_obj_port_vlan * vlan)2519 static int ofdpa_port_obj_vlan_add(struct rocker_port *rocker_port,
2520 				   const struct switchdev_obj_port_vlan *vlan)
2521 {
2522 	struct ofdpa_port *ofdpa_port = rocker_port->wpriv;
2523 
2524 	return ofdpa_port_vlan_add(ofdpa_port, vlan->vid, vlan->flags);
2525 }
2526 
ofdpa_port_obj_vlan_del(struct rocker_port * rocker_port,const struct switchdev_obj_port_vlan * vlan)2527 static int ofdpa_port_obj_vlan_del(struct rocker_port *rocker_port,
2528 				   const struct switchdev_obj_port_vlan *vlan)
2529 {
2530 	struct ofdpa_port *ofdpa_port = rocker_port->wpriv;
2531 
2532 	return ofdpa_port_vlan_del(ofdpa_port, vlan->vid, vlan->flags);
2533 }
2534 
ofdpa_port_obj_fdb_add(struct rocker_port * rocker_port,u16 vid,const unsigned char * addr)2535 static int ofdpa_port_obj_fdb_add(struct rocker_port *rocker_port,
2536 				  u16 vid, const unsigned char *addr)
2537 {
2538 	struct ofdpa_port *ofdpa_port = rocker_port->wpriv;
2539 	__be16 vlan_id = ofdpa_port_vid_to_vlan(ofdpa_port, vid, NULL);
2540 
2541 	if (!ofdpa_port_is_bridged(ofdpa_port))
2542 		return -EINVAL;
2543 
2544 	return ofdpa_port_fdb(ofdpa_port, addr, vlan_id, 0);
2545 }
2546 
ofdpa_port_obj_fdb_del(struct rocker_port * rocker_port,u16 vid,const unsigned char * addr)2547 static int ofdpa_port_obj_fdb_del(struct rocker_port *rocker_port,
2548 				  u16 vid, const unsigned char *addr)
2549 {
2550 	struct ofdpa_port *ofdpa_port = rocker_port->wpriv;
2551 	__be16 vlan_id = ofdpa_port_vid_to_vlan(ofdpa_port, vid, NULL);
2552 	int flags = OFDPA_OP_FLAG_REMOVE;
2553 
2554 	if (!ofdpa_port_is_bridged(ofdpa_port))
2555 		return -EINVAL;
2556 
2557 	return ofdpa_port_fdb(ofdpa_port, addr, vlan_id, flags);
2558 }
2559 
ofdpa_port_bridge_join(struct ofdpa_port * ofdpa_port,struct net_device * bridge,struct netlink_ext_ack * extack)2560 static int ofdpa_port_bridge_join(struct ofdpa_port *ofdpa_port,
2561 				  struct net_device *bridge,
2562 				  struct netlink_ext_ack *extack)
2563 {
2564 	struct net_device *dev = ofdpa_port->dev;
2565 	int err;
2566 
2567 	/* Port is joining bridge, so the internal VLAN for the
2568 	 * port is going to change to the bridge internal VLAN.
2569 	 * Let's remove untagged VLAN (vid=0) from port and
2570 	 * re-add once internal VLAN has changed.
2571 	 */
2572 
2573 	err = ofdpa_port_vlan_del(ofdpa_port, OFDPA_UNTAGGED_VID, 0);
2574 	if (err)
2575 		return err;
2576 
2577 	ofdpa_port_internal_vlan_id_put(ofdpa_port,
2578 					ofdpa_port->dev->ifindex);
2579 	ofdpa_port->internal_vlan_id =
2580 		ofdpa_port_internal_vlan_id_get(ofdpa_port, bridge->ifindex);
2581 
2582 	ofdpa_port->bridge_dev = bridge;
2583 
2584 	err = ofdpa_port_vlan_add(ofdpa_port, OFDPA_UNTAGGED_VID, 0);
2585 	if (err)
2586 		return err;
2587 
2588 	return switchdev_bridge_port_offload(dev, dev, NULL, NULL, NULL,
2589 					     false, extack);
2590 }
2591 
ofdpa_port_bridge_leave(struct ofdpa_port * ofdpa_port)2592 static int ofdpa_port_bridge_leave(struct ofdpa_port *ofdpa_port)
2593 {
2594 	struct net_device *dev = ofdpa_port->dev;
2595 	int err;
2596 
2597 	switchdev_bridge_port_unoffload(dev, NULL, NULL, NULL);
2598 
2599 	err = ofdpa_port_vlan_del(ofdpa_port, OFDPA_UNTAGGED_VID, 0);
2600 	if (err)
2601 		return err;
2602 
2603 	ofdpa_port_internal_vlan_id_put(ofdpa_port,
2604 					ofdpa_port->bridge_dev->ifindex);
2605 	ofdpa_port->internal_vlan_id =
2606 		ofdpa_port_internal_vlan_id_get(ofdpa_port,
2607 						ofdpa_port->dev->ifindex);
2608 
2609 	ofdpa_port->bridge_dev = NULL;
2610 
2611 	err = ofdpa_port_vlan_add(ofdpa_port, OFDPA_UNTAGGED_VID, 0);
2612 	if (err)
2613 		return err;
2614 
2615 	if (ofdpa_port->dev->flags & IFF_UP)
2616 		err = ofdpa_port_fwd_enable(ofdpa_port, 0);
2617 
2618 	return err;
2619 }
2620 
ofdpa_port_ovs_changed(struct ofdpa_port * ofdpa_port,struct net_device * master)2621 static int ofdpa_port_ovs_changed(struct ofdpa_port *ofdpa_port,
2622 				  struct net_device *master)
2623 {
2624 	int err;
2625 
2626 	ofdpa_port->bridge_dev = master;
2627 
2628 	err = ofdpa_port_fwd_disable(ofdpa_port, 0);
2629 	if (err)
2630 		return err;
2631 	err = ofdpa_port_fwd_enable(ofdpa_port, 0);
2632 
2633 	return err;
2634 }
2635 
ofdpa_port_master_linked(struct rocker_port * rocker_port,struct net_device * master,struct netlink_ext_ack * extack)2636 static int ofdpa_port_master_linked(struct rocker_port *rocker_port,
2637 				    struct net_device *master,
2638 				    struct netlink_ext_ack *extack)
2639 {
2640 	struct ofdpa_port *ofdpa_port = rocker_port->wpriv;
2641 	int err = 0;
2642 
2643 	if (netif_is_bridge_master(master))
2644 		err = ofdpa_port_bridge_join(ofdpa_port, master, extack);
2645 	else if (netif_is_ovs_master(master))
2646 		err = ofdpa_port_ovs_changed(ofdpa_port, master);
2647 	return err;
2648 }
2649 
ofdpa_port_master_unlinked(struct rocker_port * rocker_port,struct net_device * master)2650 static int ofdpa_port_master_unlinked(struct rocker_port *rocker_port,
2651 				      struct net_device *master)
2652 {
2653 	struct ofdpa_port *ofdpa_port = rocker_port->wpriv;
2654 	int err = 0;
2655 
2656 	if (ofdpa_port_is_bridged(ofdpa_port))
2657 		err = ofdpa_port_bridge_leave(ofdpa_port);
2658 	else if (ofdpa_port_is_ovsed(ofdpa_port))
2659 		err = ofdpa_port_ovs_changed(ofdpa_port, NULL);
2660 	return err;
2661 }
2662 
ofdpa_port_neigh_update(struct rocker_port * rocker_port,struct neighbour * n)2663 static int ofdpa_port_neigh_update(struct rocker_port *rocker_port,
2664 				   struct neighbour *n)
2665 {
2666 	struct ofdpa_port *ofdpa_port = rocker_port->wpriv;
2667 	int flags = (n->nud_state & NUD_VALID ? 0 : OFDPA_OP_FLAG_REMOVE) |
2668 						    OFDPA_OP_FLAG_NOWAIT;
2669 	__be32 ip_addr = *(__be32 *) n->primary_key;
2670 
2671 	return ofdpa_port_ipv4_neigh(ofdpa_port, flags, ip_addr, n->ha);
2672 }
2673 
ofdpa_port_neigh_destroy(struct rocker_port * rocker_port,struct neighbour * n)2674 static int ofdpa_port_neigh_destroy(struct rocker_port *rocker_port,
2675 				    struct neighbour *n)
2676 {
2677 	struct ofdpa_port *ofdpa_port = rocker_port->wpriv;
2678 	int flags = OFDPA_OP_FLAG_REMOVE | OFDPA_OP_FLAG_NOWAIT;
2679 	__be32 ip_addr = *(__be32 *) n->primary_key;
2680 
2681 	return ofdpa_port_ipv4_neigh(ofdpa_port, flags, ip_addr, n->ha);
2682 }
2683 
ofdpa_port_ev_mac_vlan_seen(struct rocker_port * rocker_port,const unsigned char * addr,__be16 vlan_id)2684 static int ofdpa_port_ev_mac_vlan_seen(struct rocker_port *rocker_port,
2685 				       const unsigned char *addr,
2686 				       __be16 vlan_id)
2687 {
2688 	struct ofdpa_port *ofdpa_port = rocker_port->wpriv;
2689 	int flags = OFDPA_OP_FLAG_NOWAIT | OFDPA_OP_FLAG_LEARNED;
2690 
2691 	if (ofdpa_port->stp_state != BR_STATE_LEARNING &&
2692 	    ofdpa_port->stp_state != BR_STATE_FORWARDING)
2693 		return 0;
2694 
2695 	return ofdpa_port_fdb(ofdpa_port, addr, vlan_id, flags);
2696 }
2697 
ofdpa_port_dev_lower_find(struct net_device * dev,struct rocker * rocker)2698 static struct ofdpa_port *ofdpa_port_dev_lower_find(struct net_device *dev,
2699 						    struct rocker *rocker)
2700 {
2701 	struct rocker_port *rocker_port;
2702 
2703 	rocker_port = rocker_port_dev_lower_find(dev, rocker);
2704 	return rocker_port ? rocker_port->wpriv : NULL;
2705 }
2706 
ofdpa_fib4_add(struct rocker * rocker,const struct fib_entry_notifier_info * fen_info)2707 static int ofdpa_fib4_add(struct rocker *rocker,
2708 			  const struct fib_entry_notifier_info *fen_info)
2709 {
2710 	struct ofdpa *ofdpa = rocker->wpriv;
2711 	struct ofdpa_port *ofdpa_port;
2712 	struct fib_nh *nh;
2713 	int err;
2714 
2715 	if (ofdpa->fib_aborted)
2716 		return 0;
2717 	nh = fib_info_nh(fen_info->fi, 0);
2718 	ofdpa_port = ofdpa_port_dev_lower_find(nh->fib_nh_dev, rocker);
2719 	if (!ofdpa_port)
2720 		return 0;
2721 	err = ofdpa_port_fib_ipv4(ofdpa_port, htonl(fen_info->dst),
2722 				  fen_info->dst_len, fen_info->fi,
2723 				  fen_info->tb_id, 0);
2724 	if (err)
2725 		return err;
2726 	nh->fib_nh_flags |= RTNH_F_OFFLOAD;
2727 	return 0;
2728 }
2729 
ofdpa_fib4_del(struct rocker * rocker,const struct fib_entry_notifier_info * fen_info)2730 static int ofdpa_fib4_del(struct rocker *rocker,
2731 			  const struct fib_entry_notifier_info *fen_info)
2732 {
2733 	struct ofdpa *ofdpa = rocker->wpriv;
2734 	struct ofdpa_port *ofdpa_port;
2735 	struct fib_nh *nh;
2736 
2737 	if (ofdpa->fib_aborted)
2738 		return 0;
2739 	nh = fib_info_nh(fen_info->fi, 0);
2740 	ofdpa_port = ofdpa_port_dev_lower_find(nh->fib_nh_dev, rocker);
2741 	if (!ofdpa_port)
2742 		return 0;
2743 	nh->fib_nh_flags &= ~RTNH_F_OFFLOAD;
2744 	return ofdpa_port_fib_ipv4(ofdpa_port, htonl(fen_info->dst),
2745 				   fen_info->dst_len, fen_info->fi,
2746 				   fen_info->tb_id, OFDPA_OP_FLAG_REMOVE);
2747 }
2748 
ofdpa_fib4_abort(struct rocker * rocker)2749 static void ofdpa_fib4_abort(struct rocker *rocker)
2750 {
2751 	struct ofdpa *ofdpa = rocker->wpriv;
2752 	struct ofdpa_port *ofdpa_port;
2753 	struct ofdpa_flow_tbl_entry *flow_entry;
2754 	struct hlist_node *tmp;
2755 	unsigned long flags;
2756 	int bkt;
2757 
2758 	if (ofdpa->fib_aborted)
2759 		return;
2760 
2761 	spin_lock_irqsave(&ofdpa->flow_tbl_lock, flags);
2762 	hash_for_each_safe(ofdpa->flow_tbl, bkt, tmp, flow_entry, entry) {
2763 		struct fib_nh *nh;
2764 
2765 		if (flow_entry->key.tbl_id !=
2766 		    ROCKER_OF_DPA_TABLE_ID_UNICAST_ROUTING)
2767 			continue;
2768 		nh = fib_info_nh(flow_entry->fi, 0);
2769 		ofdpa_port = ofdpa_port_dev_lower_find(nh->fib_nh_dev, rocker);
2770 		if (!ofdpa_port)
2771 			continue;
2772 		nh->fib_nh_flags &= ~RTNH_F_OFFLOAD;
2773 		ofdpa_flow_tbl_del(ofdpa_port,
2774 				   OFDPA_OP_FLAG_REMOVE | OFDPA_OP_FLAG_NOWAIT,
2775 				   flow_entry);
2776 	}
2777 	spin_unlock_irqrestore(&ofdpa->flow_tbl_lock, flags);
2778 	ofdpa->fib_aborted = true;
2779 }
2780 
2781 struct rocker_world_ops rocker_ofdpa_ops = {
2782 	.kind = "ofdpa",
2783 	.priv_size = sizeof(struct ofdpa),
2784 	.port_priv_size = sizeof(struct ofdpa_port),
2785 	.mode = ROCKER_PORT_MODE_OF_DPA,
2786 	.init = ofdpa_init,
2787 	.fini = ofdpa_fini,
2788 	.port_pre_init = ofdpa_port_pre_init,
2789 	.port_init = ofdpa_port_init,
2790 	.port_fini = ofdpa_port_fini,
2791 	.port_open = ofdpa_port_open,
2792 	.port_stop = ofdpa_port_stop,
2793 	.port_attr_stp_state_set = ofdpa_port_attr_stp_state_set,
2794 	.port_attr_bridge_flags_set = ofdpa_port_attr_bridge_flags_set,
2795 	.port_attr_bridge_flags_support_get = ofdpa_port_attr_bridge_flags_support_get,
2796 	.port_attr_bridge_ageing_time_set = ofdpa_port_attr_bridge_ageing_time_set,
2797 	.port_obj_vlan_add = ofdpa_port_obj_vlan_add,
2798 	.port_obj_vlan_del = ofdpa_port_obj_vlan_del,
2799 	.port_obj_fdb_add = ofdpa_port_obj_fdb_add,
2800 	.port_obj_fdb_del = ofdpa_port_obj_fdb_del,
2801 	.port_master_linked = ofdpa_port_master_linked,
2802 	.port_master_unlinked = ofdpa_port_master_unlinked,
2803 	.port_neigh_update = ofdpa_port_neigh_update,
2804 	.port_neigh_destroy = ofdpa_port_neigh_destroy,
2805 	.port_ev_mac_vlan_seen = ofdpa_port_ev_mac_vlan_seen,
2806 	.fib4_add = ofdpa_fib4_add,
2807 	.fib4_del = ofdpa_fib4_del,
2808 	.fib4_abort = ofdpa_fib4_abort,
2809 };
2810