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