1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /* Copyright (c) 2018 Mellanox Technologies. All rights reserved */
3 
4 #include <linux/if_bridge.h>
5 #include <linux/list.h>
6 #include <net/arp.h>
7 #include <net/gre.h>
8 #include <net/lag.h>
9 #include <net/ndisc.h>
10 #include <net/ip6_tunnel.h>
11 
12 #include "spectrum.h"
13 #include "spectrum_ipip.h"
14 #include "spectrum_span.h"
15 #include "spectrum_switchdev.h"
16 
17 static u64 mlxsw_sp_span_occ_get(void *priv)
18 {
19 	const struct mlxsw_sp *mlxsw_sp = priv;
20 	u64 occ = 0;
21 	int i;
22 
23 	for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
24 		if (mlxsw_sp->span.entries[i].ref_count)
25 			occ++;
26 	}
27 
28 	return occ;
29 }
30 
31 int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp)
32 {
33 	struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
34 	int i;
35 
36 	if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_SPAN))
37 		return -EIO;
38 
39 	mlxsw_sp->span.entries_count = MLXSW_CORE_RES_GET(mlxsw_sp->core,
40 							  MAX_SPAN);
41 	mlxsw_sp->span.entries = kcalloc(mlxsw_sp->span.entries_count,
42 					 sizeof(struct mlxsw_sp_span_entry),
43 					 GFP_KERNEL);
44 	if (!mlxsw_sp->span.entries)
45 		return -ENOMEM;
46 
47 	for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
48 		struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i];
49 
50 		INIT_LIST_HEAD(&curr->bound_ports_list);
51 		curr->id = i;
52 	}
53 
54 	devlink_resource_occ_get_register(devlink, MLXSW_SP_RESOURCE_SPAN,
55 					  mlxsw_sp_span_occ_get, mlxsw_sp);
56 
57 	return 0;
58 }
59 
60 void mlxsw_sp_span_fini(struct mlxsw_sp *mlxsw_sp)
61 {
62 	struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
63 	int i;
64 
65 	devlink_resource_occ_get_unregister(devlink, MLXSW_SP_RESOURCE_SPAN);
66 
67 	for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
68 		struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i];
69 
70 		WARN_ON_ONCE(!list_empty(&curr->bound_ports_list));
71 	}
72 	kfree(mlxsw_sp->span.entries);
73 }
74 
75 static int
76 mlxsw_sp_span_entry_phys_parms(const struct net_device *to_dev,
77 			       struct mlxsw_sp_span_parms *sparmsp)
78 {
79 	sparmsp->dest_port = netdev_priv(to_dev);
80 	return 0;
81 }
82 
83 static int
84 mlxsw_sp_span_entry_phys_configure(struct mlxsw_sp_span_entry *span_entry,
85 				   struct mlxsw_sp_span_parms sparms)
86 {
87 	struct mlxsw_sp_port *dest_port = sparms.dest_port;
88 	struct mlxsw_sp *mlxsw_sp = dest_port->mlxsw_sp;
89 	u8 local_port = dest_port->local_port;
90 	char mpat_pl[MLXSW_REG_MPAT_LEN];
91 	int pa_id = span_entry->id;
92 
93 	/* Create a new port analayzer entry for local_port. */
94 	mlxsw_reg_mpat_pack(mpat_pl, pa_id, local_port, true,
95 			    MLXSW_REG_MPAT_SPAN_TYPE_LOCAL_ETH);
96 
97 	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpat), mpat_pl);
98 }
99 
100 static void
101 mlxsw_sp_span_entry_deconfigure_common(struct mlxsw_sp_span_entry *span_entry,
102 				       enum mlxsw_reg_mpat_span_type span_type)
103 {
104 	struct mlxsw_sp_port *dest_port = span_entry->parms.dest_port;
105 	struct mlxsw_sp *mlxsw_sp = dest_port->mlxsw_sp;
106 	u8 local_port = dest_port->local_port;
107 	char mpat_pl[MLXSW_REG_MPAT_LEN];
108 	int pa_id = span_entry->id;
109 
110 	mlxsw_reg_mpat_pack(mpat_pl, pa_id, local_port, false, span_type);
111 	mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpat), mpat_pl);
112 }
113 
114 static void
115 mlxsw_sp_span_entry_phys_deconfigure(struct mlxsw_sp_span_entry *span_entry)
116 {
117 	mlxsw_sp_span_entry_deconfigure_common(span_entry,
118 					    MLXSW_REG_MPAT_SPAN_TYPE_LOCAL_ETH);
119 }
120 
121 static const
122 struct mlxsw_sp_span_entry_ops mlxsw_sp_span_entry_ops_phys = {
123 	.can_handle = mlxsw_sp_port_dev_check,
124 	.parms = mlxsw_sp_span_entry_phys_parms,
125 	.configure = mlxsw_sp_span_entry_phys_configure,
126 	.deconfigure = mlxsw_sp_span_entry_phys_deconfigure,
127 };
128 
129 static int mlxsw_sp_span_dmac(struct neigh_table *tbl,
130 			      const void *pkey,
131 			      struct net_device *dev,
132 			      unsigned char dmac[ETH_ALEN])
133 {
134 	struct neighbour *neigh = neigh_lookup(tbl, pkey, dev);
135 	int err = 0;
136 
137 	if (!neigh) {
138 		neigh = neigh_create(tbl, pkey, dev);
139 		if (IS_ERR(neigh))
140 			return PTR_ERR(neigh);
141 	}
142 
143 	neigh_event_send(neigh, NULL);
144 
145 	read_lock_bh(&neigh->lock);
146 	if ((neigh->nud_state & NUD_VALID) && !neigh->dead)
147 		memcpy(dmac, neigh->ha, ETH_ALEN);
148 	else
149 		err = -ENOENT;
150 	read_unlock_bh(&neigh->lock);
151 
152 	neigh_release(neigh);
153 	return err;
154 }
155 
156 static int
157 mlxsw_sp_span_entry_unoffloadable(struct mlxsw_sp_span_parms *sparmsp)
158 {
159 	sparmsp->dest_port = NULL;
160 	return 0;
161 }
162 
163 static struct net_device *
164 mlxsw_sp_span_entry_bridge_8021q(const struct net_device *br_dev,
165 				 unsigned char *dmac,
166 				 u16 *p_vid)
167 {
168 	struct bridge_vlan_info vinfo;
169 	struct net_device *edev;
170 	u16 vid = *p_vid;
171 
172 	if (!vid && WARN_ON(br_vlan_get_pvid(br_dev, &vid)))
173 		return NULL;
174 	if (!vid ||
175 	    br_vlan_get_info(br_dev, vid, &vinfo) ||
176 	    !(vinfo.flags & BRIDGE_VLAN_INFO_BRENTRY))
177 		return NULL;
178 
179 	edev = br_fdb_find_port(br_dev, dmac, vid);
180 	if (!edev)
181 		return NULL;
182 
183 	if (br_vlan_get_info(edev, vid, &vinfo))
184 		return NULL;
185 	if (vinfo.flags & BRIDGE_VLAN_INFO_UNTAGGED)
186 		*p_vid = 0;
187 	else
188 		*p_vid = vid;
189 	return edev;
190 }
191 
192 static struct net_device *
193 mlxsw_sp_span_entry_bridge_8021d(const struct net_device *br_dev,
194 				 unsigned char *dmac)
195 {
196 	return br_fdb_find_port(br_dev, dmac, 0);
197 }
198 
199 static struct net_device *
200 mlxsw_sp_span_entry_bridge(const struct net_device *br_dev,
201 			   unsigned char dmac[ETH_ALEN],
202 			   u16 *p_vid)
203 {
204 	struct mlxsw_sp_bridge_port *bridge_port;
205 	enum mlxsw_reg_spms_state spms_state;
206 	struct net_device *dev = NULL;
207 	struct mlxsw_sp_port *port;
208 	u8 stp_state;
209 
210 	if (br_vlan_enabled(br_dev))
211 		dev = mlxsw_sp_span_entry_bridge_8021q(br_dev, dmac, p_vid);
212 	else if (!*p_vid)
213 		dev = mlxsw_sp_span_entry_bridge_8021d(br_dev, dmac);
214 	if (!dev)
215 		return NULL;
216 
217 	port = mlxsw_sp_port_dev_lower_find(dev);
218 	if (!port)
219 		return NULL;
220 
221 	bridge_port = mlxsw_sp_bridge_port_find(port->mlxsw_sp->bridge, dev);
222 	if (!bridge_port)
223 		return NULL;
224 
225 	stp_state = mlxsw_sp_bridge_port_stp_state(bridge_port);
226 	spms_state = mlxsw_sp_stp_spms_state(stp_state);
227 	if (spms_state != MLXSW_REG_SPMS_STATE_FORWARDING)
228 		return NULL;
229 
230 	return dev;
231 }
232 
233 static struct net_device *
234 mlxsw_sp_span_entry_vlan(const struct net_device *vlan_dev,
235 			 u16 *p_vid)
236 {
237 	*p_vid = vlan_dev_vlan_id(vlan_dev);
238 	return vlan_dev_real_dev(vlan_dev);
239 }
240 
241 static struct net_device *
242 mlxsw_sp_span_entry_lag(struct net_device *lag_dev)
243 {
244 	struct net_device *dev;
245 	struct list_head *iter;
246 
247 	netdev_for_each_lower_dev(lag_dev, dev, iter)
248 		if (netif_carrier_ok(dev) &&
249 		    net_lag_port_dev_txable(dev) &&
250 		    mlxsw_sp_port_dev_check(dev))
251 			return dev;
252 
253 	return NULL;
254 }
255 
256 static __maybe_unused int
257 mlxsw_sp_span_entry_tunnel_parms_common(struct net_device *edev,
258 					union mlxsw_sp_l3addr saddr,
259 					union mlxsw_sp_l3addr daddr,
260 					union mlxsw_sp_l3addr gw,
261 					__u8 ttl,
262 					struct neigh_table *tbl,
263 					struct mlxsw_sp_span_parms *sparmsp)
264 {
265 	unsigned char dmac[ETH_ALEN];
266 	u16 vid = 0;
267 
268 	if (mlxsw_sp_l3addr_is_zero(gw))
269 		gw = daddr;
270 
271 	if (!edev || mlxsw_sp_span_dmac(tbl, &gw, edev, dmac))
272 		goto unoffloadable;
273 
274 	if (is_vlan_dev(edev))
275 		edev = mlxsw_sp_span_entry_vlan(edev, &vid);
276 
277 	if (netif_is_bridge_master(edev)) {
278 		edev = mlxsw_sp_span_entry_bridge(edev, dmac, &vid);
279 		if (!edev)
280 			goto unoffloadable;
281 	}
282 
283 	if (is_vlan_dev(edev)) {
284 		if (vid || !(edev->flags & IFF_UP))
285 			goto unoffloadable;
286 		edev = mlxsw_sp_span_entry_vlan(edev, &vid);
287 	}
288 
289 	if (netif_is_lag_master(edev)) {
290 		if (!(edev->flags & IFF_UP))
291 			goto unoffloadable;
292 		edev = mlxsw_sp_span_entry_lag(edev);
293 		if (!edev)
294 			goto unoffloadable;
295 	}
296 
297 	if (!mlxsw_sp_port_dev_check(edev))
298 		goto unoffloadable;
299 
300 	sparmsp->dest_port = netdev_priv(edev);
301 	sparmsp->ttl = ttl;
302 	memcpy(sparmsp->dmac, dmac, ETH_ALEN);
303 	memcpy(sparmsp->smac, edev->dev_addr, ETH_ALEN);
304 	sparmsp->saddr = saddr;
305 	sparmsp->daddr = daddr;
306 	sparmsp->vid = vid;
307 	return 0;
308 
309 unoffloadable:
310 	return mlxsw_sp_span_entry_unoffloadable(sparmsp);
311 }
312 
313 #if IS_ENABLED(CONFIG_NET_IPGRE)
314 static struct net_device *
315 mlxsw_sp_span_gretap4_route(const struct net_device *to_dev,
316 			    __be32 *saddrp, __be32 *daddrp)
317 {
318 	struct ip_tunnel *tun = netdev_priv(to_dev);
319 	struct net_device *dev = NULL;
320 	struct ip_tunnel_parm parms;
321 	struct rtable *rt = NULL;
322 	struct flowi4 fl4;
323 
324 	/* We assume "dev" stays valid after rt is put. */
325 	ASSERT_RTNL();
326 
327 	parms = mlxsw_sp_ipip_netdev_parms4(to_dev);
328 	ip_tunnel_init_flow(&fl4, parms.iph.protocol, *daddrp, *saddrp,
329 			    0, 0, parms.link, tun->fwmark, 0);
330 
331 	rt = ip_route_output_key(tun->net, &fl4);
332 	if (IS_ERR(rt))
333 		return NULL;
334 
335 	if (rt->rt_type != RTN_UNICAST)
336 		goto out;
337 
338 	dev = rt->dst.dev;
339 	*saddrp = fl4.saddr;
340 	if (rt->rt_gw_family == AF_INET)
341 		*daddrp = rt->rt_gw4;
342 	/* can not offload if route has an IPv6 gateway */
343 	else if (rt->rt_gw_family == AF_INET6)
344 		dev = NULL;
345 
346 out:
347 	ip_rt_put(rt);
348 	return dev;
349 }
350 
351 static int
352 mlxsw_sp_span_entry_gretap4_parms(const struct net_device *to_dev,
353 				  struct mlxsw_sp_span_parms *sparmsp)
354 {
355 	struct ip_tunnel_parm tparm = mlxsw_sp_ipip_netdev_parms4(to_dev);
356 	union mlxsw_sp_l3addr saddr = { .addr4 = tparm.iph.saddr };
357 	union mlxsw_sp_l3addr daddr = { .addr4 = tparm.iph.daddr };
358 	bool inherit_tos = tparm.iph.tos & 0x1;
359 	bool inherit_ttl = !tparm.iph.ttl;
360 	union mlxsw_sp_l3addr gw = daddr;
361 	struct net_device *l3edev;
362 
363 	if (!(to_dev->flags & IFF_UP) ||
364 	    /* Reject tunnels with GRE keys, checksums, etc. */
365 	    tparm.i_flags || tparm.o_flags ||
366 	    /* Require a fixed TTL and a TOS copied from the mirrored packet. */
367 	    inherit_ttl || !inherit_tos ||
368 	    /* A destination address may not be "any". */
369 	    mlxsw_sp_l3addr_is_zero(daddr))
370 		return mlxsw_sp_span_entry_unoffloadable(sparmsp);
371 
372 	l3edev = mlxsw_sp_span_gretap4_route(to_dev, &saddr.addr4, &gw.addr4);
373 	return mlxsw_sp_span_entry_tunnel_parms_common(l3edev, saddr, daddr, gw,
374 						       tparm.iph.ttl,
375 						       &arp_tbl, sparmsp);
376 }
377 
378 static int
379 mlxsw_sp_span_entry_gretap4_configure(struct mlxsw_sp_span_entry *span_entry,
380 				      struct mlxsw_sp_span_parms sparms)
381 {
382 	struct mlxsw_sp_port *dest_port = sparms.dest_port;
383 	struct mlxsw_sp *mlxsw_sp = dest_port->mlxsw_sp;
384 	u8 local_port = dest_port->local_port;
385 	char mpat_pl[MLXSW_REG_MPAT_LEN];
386 	int pa_id = span_entry->id;
387 
388 	/* Create a new port analayzer entry for local_port. */
389 	mlxsw_reg_mpat_pack(mpat_pl, pa_id, local_port, true,
390 			    MLXSW_REG_MPAT_SPAN_TYPE_REMOTE_ETH_L3);
391 	mlxsw_reg_mpat_eth_rspan_pack(mpat_pl, sparms.vid);
392 	mlxsw_reg_mpat_eth_rspan_l2_pack(mpat_pl,
393 				    MLXSW_REG_MPAT_ETH_RSPAN_VERSION_NO_HEADER,
394 				    sparms.dmac, !!sparms.vid);
395 	mlxsw_reg_mpat_eth_rspan_l3_ipv4_pack(mpat_pl,
396 					      sparms.ttl, sparms.smac,
397 					      be32_to_cpu(sparms.saddr.addr4),
398 					      be32_to_cpu(sparms.daddr.addr4));
399 
400 	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpat), mpat_pl);
401 }
402 
403 static void
404 mlxsw_sp_span_entry_gretap4_deconfigure(struct mlxsw_sp_span_entry *span_entry)
405 {
406 	mlxsw_sp_span_entry_deconfigure_common(span_entry,
407 					MLXSW_REG_MPAT_SPAN_TYPE_REMOTE_ETH_L3);
408 }
409 
410 static const struct mlxsw_sp_span_entry_ops mlxsw_sp_span_entry_ops_gretap4 = {
411 	.can_handle = netif_is_gretap,
412 	.parms = mlxsw_sp_span_entry_gretap4_parms,
413 	.configure = mlxsw_sp_span_entry_gretap4_configure,
414 	.deconfigure = mlxsw_sp_span_entry_gretap4_deconfigure,
415 };
416 #endif
417 
418 #if IS_ENABLED(CONFIG_IPV6_GRE)
419 static struct net_device *
420 mlxsw_sp_span_gretap6_route(const struct net_device *to_dev,
421 			    struct in6_addr *saddrp,
422 			    struct in6_addr *daddrp)
423 {
424 	struct ip6_tnl *t = netdev_priv(to_dev);
425 	struct flowi6 fl6 = t->fl.u.ip6;
426 	struct net_device *dev = NULL;
427 	struct dst_entry *dst;
428 	struct rt6_info *rt6;
429 
430 	/* We assume "dev" stays valid after dst is released. */
431 	ASSERT_RTNL();
432 
433 	fl6.flowi6_mark = t->parms.fwmark;
434 	if (!ip6_tnl_xmit_ctl(t, &fl6.saddr, &fl6.daddr))
435 		return NULL;
436 
437 	dst = ip6_route_output(t->net, NULL, &fl6);
438 	if (!dst || dst->error)
439 		goto out;
440 
441 	rt6 = container_of(dst, struct rt6_info, dst);
442 
443 	dev = dst->dev;
444 	*saddrp = fl6.saddr;
445 	*daddrp = rt6->rt6i_gateway;
446 
447 out:
448 	dst_release(dst);
449 	return dev;
450 }
451 
452 static int
453 mlxsw_sp_span_entry_gretap6_parms(const struct net_device *to_dev,
454 				  struct mlxsw_sp_span_parms *sparmsp)
455 {
456 	struct __ip6_tnl_parm tparm = mlxsw_sp_ipip_netdev_parms6(to_dev);
457 	bool inherit_tos = tparm.flags & IP6_TNL_F_USE_ORIG_TCLASS;
458 	union mlxsw_sp_l3addr saddr = { .addr6 = tparm.laddr };
459 	union mlxsw_sp_l3addr daddr = { .addr6 = tparm.raddr };
460 	bool inherit_ttl = !tparm.hop_limit;
461 	union mlxsw_sp_l3addr gw = daddr;
462 	struct net_device *l3edev;
463 
464 	if (!(to_dev->flags & IFF_UP) ||
465 	    /* Reject tunnels with GRE keys, checksums, etc. */
466 	    tparm.i_flags || tparm.o_flags ||
467 	    /* Require a fixed TTL and a TOS copied from the mirrored packet. */
468 	    inherit_ttl || !inherit_tos ||
469 	    /* A destination address may not be "any". */
470 	    mlxsw_sp_l3addr_is_zero(daddr))
471 		return mlxsw_sp_span_entry_unoffloadable(sparmsp);
472 
473 	l3edev = mlxsw_sp_span_gretap6_route(to_dev, &saddr.addr6, &gw.addr6);
474 	return mlxsw_sp_span_entry_tunnel_parms_common(l3edev, saddr, daddr, gw,
475 						       tparm.hop_limit,
476 						       &nd_tbl, sparmsp);
477 }
478 
479 static int
480 mlxsw_sp_span_entry_gretap6_configure(struct mlxsw_sp_span_entry *span_entry,
481 				      struct mlxsw_sp_span_parms sparms)
482 {
483 	struct mlxsw_sp_port *dest_port = sparms.dest_port;
484 	struct mlxsw_sp *mlxsw_sp = dest_port->mlxsw_sp;
485 	u8 local_port = dest_port->local_port;
486 	char mpat_pl[MLXSW_REG_MPAT_LEN];
487 	int pa_id = span_entry->id;
488 
489 	/* Create a new port analayzer entry for local_port. */
490 	mlxsw_reg_mpat_pack(mpat_pl, pa_id, local_port, true,
491 			    MLXSW_REG_MPAT_SPAN_TYPE_REMOTE_ETH_L3);
492 	mlxsw_reg_mpat_eth_rspan_pack(mpat_pl, sparms.vid);
493 	mlxsw_reg_mpat_eth_rspan_l2_pack(mpat_pl,
494 				    MLXSW_REG_MPAT_ETH_RSPAN_VERSION_NO_HEADER,
495 				    sparms.dmac, !!sparms.vid);
496 	mlxsw_reg_mpat_eth_rspan_l3_ipv6_pack(mpat_pl, sparms.ttl, sparms.smac,
497 					      sparms.saddr.addr6,
498 					      sparms.daddr.addr6);
499 
500 	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpat), mpat_pl);
501 }
502 
503 static void
504 mlxsw_sp_span_entry_gretap6_deconfigure(struct mlxsw_sp_span_entry *span_entry)
505 {
506 	mlxsw_sp_span_entry_deconfigure_common(span_entry,
507 					MLXSW_REG_MPAT_SPAN_TYPE_REMOTE_ETH_L3);
508 }
509 
510 static const
511 struct mlxsw_sp_span_entry_ops mlxsw_sp_span_entry_ops_gretap6 = {
512 	.can_handle = netif_is_ip6gretap,
513 	.parms = mlxsw_sp_span_entry_gretap6_parms,
514 	.configure = mlxsw_sp_span_entry_gretap6_configure,
515 	.deconfigure = mlxsw_sp_span_entry_gretap6_deconfigure,
516 };
517 #endif
518 
519 static bool
520 mlxsw_sp_span_vlan_can_handle(const struct net_device *dev)
521 {
522 	return is_vlan_dev(dev) &&
523 	       mlxsw_sp_port_dev_check(vlan_dev_real_dev(dev));
524 }
525 
526 static int
527 mlxsw_sp_span_entry_vlan_parms(const struct net_device *to_dev,
528 			       struct mlxsw_sp_span_parms *sparmsp)
529 {
530 	struct net_device *real_dev;
531 	u16 vid;
532 
533 	if (!(to_dev->flags & IFF_UP))
534 		return mlxsw_sp_span_entry_unoffloadable(sparmsp);
535 
536 	real_dev = mlxsw_sp_span_entry_vlan(to_dev, &vid);
537 	sparmsp->dest_port = netdev_priv(real_dev);
538 	sparmsp->vid = vid;
539 	return 0;
540 }
541 
542 static int
543 mlxsw_sp_span_entry_vlan_configure(struct mlxsw_sp_span_entry *span_entry,
544 				   struct mlxsw_sp_span_parms sparms)
545 {
546 	struct mlxsw_sp_port *dest_port = sparms.dest_port;
547 	struct mlxsw_sp *mlxsw_sp = dest_port->mlxsw_sp;
548 	u8 local_port = dest_port->local_port;
549 	char mpat_pl[MLXSW_REG_MPAT_LEN];
550 	int pa_id = span_entry->id;
551 
552 	mlxsw_reg_mpat_pack(mpat_pl, pa_id, local_port, true,
553 			    MLXSW_REG_MPAT_SPAN_TYPE_REMOTE_ETH);
554 	mlxsw_reg_mpat_eth_rspan_pack(mpat_pl, sparms.vid);
555 
556 	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpat), mpat_pl);
557 }
558 
559 static void
560 mlxsw_sp_span_entry_vlan_deconfigure(struct mlxsw_sp_span_entry *span_entry)
561 {
562 	mlxsw_sp_span_entry_deconfigure_common(span_entry,
563 					MLXSW_REG_MPAT_SPAN_TYPE_REMOTE_ETH);
564 }
565 
566 static const
567 struct mlxsw_sp_span_entry_ops mlxsw_sp_span_entry_ops_vlan = {
568 	.can_handle = mlxsw_sp_span_vlan_can_handle,
569 	.parms = mlxsw_sp_span_entry_vlan_parms,
570 	.configure = mlxsw_sp_span_entry_vlan_configure,
571 	.deconfigure = mlxsw_sp_span_entry_vlan_deconfigure,
572 };
573 
574 static const
575 struct mlxsw_sp_span_entry_ops *const mlxsw_sp_span_entry_types[] = {
576 	&mlxsw_sp_span_entry_ops_phys,
577 #if IS_ENABLED(CONFIG_NET_IPGRE)
578 	&mlxsw_sp_span_entry_ops_gretap4,
579 #endif
580 #if IS_ENABLED(CONFIG_IPV6_GRE)
581 	&mlxsw_sp_span_entry_ops_gretap6,
582 #endif
583 	&mlxsw_sp_span_entry_ops_vlan,
584 };
585 
586 static int
587 mlxsw_sp_span_entry_nop_parms(const struct net_device *to_dev,
588 			      struct mlxsw_sp_span_parms *sparmsp)
589 {
590 	return mlxsw_sp_span_entry_unoffloadable(sparmsp);
591 }
592 
593 static int
594 mlxsw_sp_span_entry_nop_configure(struct mlxsw_sp_span_entry *span_entry,
595 				  struct mlxsw_sp_span_parms sparms)
596 {
597 	return 0;
598 }
599 
600 static void
601 mlxsw_sp_span_entry_nop_deconfigure(struct mlxsw_sp_span_entry *span_entry)
602 {
603 }
604 
605 static const struct mlxsw_sp_span_entry_ops mlxsw_sp_span_entry_ops_nop = {
606 	.parms = mlxsw_sp_span_entry_nop_parms,
607 	.configure = mlxsw_sp_span_entry_nop_configure,
608 	.deconfigure = mlxsw_sp_span_entry_nop_deconfigure,
609 };
610 
611 static void
612 mlxsw_sp_span_entry_configure(struct mlxsw_sp *mlxsw_sp,
613 			      struct mlxsw_sp_span_entry *span_entry,
614 			      struct mlxsw_sp_span_parms sparms)
615 {
616 	if (sparms.dest_port) {
617 		if (sparms.dest_port->mlxsw_sp != mlxsw_sp) {
618 			netdev_err(span_entry->to_dev, "Cannot mirror to %s, which belongs to a different mlxsw instance",
619 				   sparms.dest_port->dev->name);
620 			sparms.dest_port = NULL;
621 		} else if (span_entry->ops->configure(span_entry, sparms)) {
622 			netdev_err(span_entry->to_dev, "Failed to offload mirror to %s",
623 				   sparms.dest_port->dev->name);
624 			sparms.dest_port = NULL;
625 		}
626 	}
627 
628 	span_entry->parms = sparms;
629 }
630 
631 static void
632 mlxsw_sp_span_entry_deconfigure(struct mlxsw_sp_span_entry *span_entry)
633 {
634 	if (span_entry->parms.dest_port)
635 		span_entry->ops->deconfigure(span_entry);
636 }
637 
638 static struct mlxsw_sp_span_entry *
639 mlxsw_sp_span_entry_create(struct mlxsw_sp *mlxsw_sp,
640 			   const struct net_device *to_dev,
641 			   const struct mlxsw_sp_span_entry_ops *ops,
642 			   struct mlxsw_sp_span_parms sparms)
643 {
644 	struct mlxsw_sp_span_entry *span_entry = NULL;
645 	int i;
646 
647 	/* find a free entry to use */
648 	for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
649 		if (!mlxsw_sp->span.entries[i].ref_count) {
650 			span_entry = &mlxsw_sp->span.entries[i];
651 			break;
652 		}
653 	}
654 	if (!span_entry)
655 		return NULL;
656 
657 	span_entry->ops = ops;
658 	span_entry->ref_count = 1;
659 	span_entry->to_dev = to_dev;
660 	mlxsw_sp_span_entry_configure(mlxsw_sp, span_entry, sparms);
661 
662 	return span_entry;
663 }
664 
665 static void mlxsw_sp_span_entry_destroy(struct mlxsw_sp_span_entry *span_entry)
666 {
667 	mlxsw_sp_span_entry_deconfigure(span_entry);
668 }
669 
670 struct mlxsw_sp_span_entry *
671 mlxsw_sp_span_entry_find_by_port(struct mlxsw_sp *mlxsw_sp,
672 				 const struct net_device *to_dev)
673 {
674 	int i;
675 
676 	for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
677 		struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i];
678 
679 		if (curr->ref_count && curr->to_dev == to_dev)
680 			return curr;
681 	}
682 	return NULL;
683 }
684 
685 void mlxsw_sp_span_entry_invalidate(struct mlxsw_sp *mlxsw_sp,
686 				    struct mlxsw_sp_span_entry *span_entry)
687 {
688 	mlxsw_sp_span_entry_deconfigure(span_entry);
689 	span_entry->ops = &mlxsw_sp_span_entry_ops_nop;
690 }
691 
692 static struct mlxsw_sp_span_entry *
693 mlxsw_sp_span_entry_find_by_id(struct mlxsw_sp *mlxsw_sp, int span_id)
694 {
695 	int i;
696 
697 	for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
698 		struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i];
699 
700 		if (curr->ref_count && curr->id == span_id)
701 			return curr;
702 	}
703 	return NULL;
704 }
705 
706 static struct mlxsw_sp_span_entry *
707 mlxsw_sp_span_entry_get(struct mlxsw_sp *mlxsw_sp,
708 			const struct net_device *to_dev,
709 			const struct mlxsw_sp_span_entry_ops *ops,
710 			struct mlxsw_sp_span_parms sparms)
711 {
712 	struct mlxsw_sp_span_entry *span_entry;
713 
714 	span_entry = mlxsw_sp_span_entry_find_by_port(mlxsw_sp, to_dev);
715 	if (span_entry) {
716 		/* Already exists, just take a reference */
717 		span_entry->ref_count++;
718 		return span_entry;
719 	}
720 
721 	return mlxsw_sp_span_entry_create(mlxsw_sp, to_dev, ops, sparms);
722 }
723 
724 static int mlxsw_sp_span_entry_put(struct mlxsw_sp *mlxsw_sp,
725 				   struct mlxsw_sp_span_entry *span_entry)
726 {
727 	WARN_ON(!span_entry->ref_count);
728 	if (--span_entry->ref_count == 0)
729 		mlxsw_sp_span_entry_destroy(span_entry);
730 	return 0;
731 }
732 
733 static bool mlxsw_sp_span_is_egress_mirror(struct mlxsw_sp_port *port)
734 {
735 	struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
736 	struct mlxsw_sp_span_inspected_port *p;
737 	int i;
738 
739 	for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
740 		struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i];
741 
742 		list_for_each_entry(p, &curr->bound_ports_list, list)
743 			if (p->local_port == port->local_port &&
744 			    p->type == MLXSW_SP_SPAN_EGRESS)
745 				return true;
746 	}
747 
748 	return false;
749 }
750 
751 static int mlxsw_sp_span_mtu_to_buffsize(const struct mlxsw_sp *mlxsw_sp,
752 					 int mtu)
753 {
754 	return mlxsw_sp_bytes_cells(mlxsw_sp, mtu * 5 / 2) + 1;
755 }
756 
757 int mlxsw_sp_span_port_mtu_update(struct mlxsw_sp_port *port, u16 mtu)
758 {
759 	struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
760 	char sbib_pl[MLXSW_REG_SBIB_LEN];
761 	int err;
762 
763 	/* If port is egress mirrored, the shared buffer size should be
764 	 * updated according to the mtu value
765 	 */
766 	if (mlxsw_sp_span_is_egress_mirror(port)) {
767 		u32 buffsize = mlxsw_sp_span_mtu_to_buffsize(mlxsw_sp, mtu);
768 
769 		mlxsw_reg_sbib_pack(sbib_pl, port->local_port, buffsize);
770 		err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
771 		if (err) {
772 			netdev_err(port->dev, "Could not update shared buffer for mirroring\n");
773 			return err;
774 		}
775 	}
776 
777 	return 0;
778 }
779 
780 static struct mlxsw_sp_span_inspected_port *
781 mlxsw_sp_span_entry_bound_port_find(struct mlxsw_sp_span_entry *span_entry,
782 				    enum mlxsw_sp_span_type type,
783 				    struct mlxsw_sp_port *port,
784 				    bool bind)
785 {
786 	struct mlxsw_sp_span_inspected_port *p;
787 
788 	list_for_each_entry(p, &span_entry->bound_ports_list, list)
789 		if (type == p->type &&
790 		    port->local_port == p->local_port &&
791 		    bind == p->bound)
792 			return p;
793 	return NULL;
794 }
795 
796 static int
797 mlxsw_sp_span_inspected_port_bind(struct mlxsw_sp_port *port,
798 				  struct mlxsw_sp_span_entry *span_entry,
799 				  enum mlxsw_sp_span_type type,
800 				  bool bind)
801 {
802 	struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
803 	char mpar_pl[MLXSW_REG_MPAR_LEN];
804 	int pa_id = span_entry->id;
805 
806 	/* bind the port to the SPAN entry */
807 	mlxsw_reg_mpar_pack(mpar_pl, port->local_port,
808 			    (enum mlxsw_reg_mpar_i_e)type, bind, pa_id);
809 	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpar), mpar_pl);
810 }
811 
812 static int
813 mlxsw_sp_span_inspected_port_add(struct mlxsw_sp_port *port,
814 				 struct mlxsw_sp_span_entry *span_entry,
815 				 enum mlxsw_sp_span_type type,
816 				 bool bind)
817 {
818 	struct mlxsw_sp_span_inspected_port *inspected_port;
819 	struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
820 	char sbib_pl[MLXSW_REG_SBIB_LEN];
821 	int i;
822 	int err;
823 
824 	/* A given (source port, direction) can only be bound to one analyzer,
825 	 * so if a binding is requested, check for conflicts.
826 	 */
827 	if (bind)
828 		for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
829 			struct mlxsw_sp_span_entry *curr =
830 				&mlxsw_sp->span.entries[i];
831 
832 			if (mlxsw_sp_span_entry_bound_port_find(curr, type,
833 								port, bind))
834 				return -EEXIST;
835 		}
836 
837 	/* if it is an egress SPAN, bind a shared buffer to it */
838 	if (type == MLXSW_SP_SPAN_EGRESS) {
839 		u32 buffsize = mlxsw_sp_span_mtu_to_buffsize(mlxsw_sp,
840 							     port->dev->mtu);
841 
842 		mlxsw_reg_sbib_pack(sbib_pl, port->local_port, buffsize);
843 		err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
844 		if (err) {
845 			netdev_err(port->dev, "Could not create shared buffer for mirroring\n");
846 			return err;
847 		}
848 	}
849 
850 	if (bind) {
851 		err = mlxsw_sp_span_inspected_port_bind(port, span_entry, type,
852 							true);
853 		if (err)
854 			goto err_port_bind;
855 	}
856 
857 	inspected_port = kzalloc(sizeof(*inspected_port), GFP_KERNEL);
858 	if (!inspected_port) {
859 		err = -ENOMEM;
860 		goto err_inspected_port_alloc;
861 	}
862 	inspected_port->local_port = port->local_port;
863 	inspected_port->type = type;
864 	inspected_port->bound = bind;
865 	list_add_tail(&inspected_port->list, &span_entry->bound_ports_list);
866 
867 	return 0;
868 
869 err_inspected_port_alloc:
870 	if (bind)
871 		mlxsw_sp_span_inspected_port_bind(port, span_entry, type,
872 						  false);
873 err_port_bind:
874 	if (type == MLXSW_SP_SPAN_EGRESS) {
875 		mlxsw_reg_sbib_pack(sbib_pl, port->local_port, 0);
876 		mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
877 	}
878 	return err;
879 }
880 
881 static void
882 mlxsw_sp_span_inspected_port_del(struct mlxsw_sp_port *port,
883 				 struct mlxsw_sp_span_entry *span_entry,
884 				 enum mlxsw_sp_span_type type,
885 				 bool bind)
886 {
887 	struct mlxsw_sp_span_inspected_port *inspected_port;
888 	struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
889 	char sbib_pl[MLXSW_REG_SBIB_LEN];
890 
891 	inspected_port = mlxsw_sp_span_entry_bound_port_find(span_entry, type,
892 							     port, bind);
893 	if (!inspected_port)
894 		return;
895 
896 	if (bind)
897 		mlxsw_sp_span_inspected_port_bind(port, span_entry, type,
898 						  false);
899 	/* remove the SBIB buffer if it was egress SPAN */
900 	if (type == MLXSW_SP_SPAN_EGRESS) {
901 		mlxsw_reg_sbib_pack(sbib_pl, port->local_port, 0);
902 		mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
903 	}
904 
905 	mlxsw_sp_span_entry_put(mlxsw_sp, span_entry);
906 
907 	list_del(&inspected_port->list);
908 	kfree(inspected_port);
909 }
910 
911 static const struct mlxsw_sp_span_entry_ops *
912 mlxsw_sp_span_entry_ops(struct mlxsw_sp *mlxsw_sp,
913 			const struct net_device *to_dev)
914 {
915 	size_t i;
916 
917 	for (i = 0; i < ARRAY_SIZE(mlxsw_sp_span_entry_types); ++i)
918 		if (mlxsw_sp_span_entry_types[i]->can_handle(to_dev))
919 			return mlxsw_sp_span_entry_types[i];
920 
921 	return NULL;
922 }
923 
924 int mlxsw_sp_span_mirror_add(struct mlxsw_sp_port *from,
925 			     const struct net_device *to_dev,
926 			     enum mlxsw_sp_span_type type, bool bind,
927 			     int *p_span_id)
928 {
929 	struct mlxsw_sp *mlxsw_sp = from->mlxsw_sp;
930 	const struct mlxsw_sp_span_entry_ops *ops;
931 	struct mlxsw_sp_span_parms sparms = {NULL};
932 	struct mlxsw_sp_span_entry *span_entry;
933 	int err;
934 
935 	ops = mlxsw_sp_span_entry_ops(mlxsw_sp, to_dev);
936 	if (!ops) {
937 		netdev_err(to_dev, "Cannot mirror to %s", to_dev->name);
938 		return -EOPNOTSUPP;
939 	}
940 
941 	err = ops->parms(to_dev, &sparms);
942 	if (err)
943 		return err;
944 
945 	span_entry = mlxsw_sp_span_entry_get(mlxsw_sp, to_dev, ops, sparms);
946 	if (!span_entry)
947 		return -ENOBUFS;
948 
949 	netdev_dbg(from->dev, "Adding inspected port to SPAN entry %d\n",
950 		   span_entry->id);
951 
952 	err = mlxsw_sp_span_inspected_port_add(from, span_entry, type, bind);
953 	if (err)
954 		goto err_port_bind;
955 
956 	*p_span_id = span_entry->id;
957 	return 0;
958 
959 err_port_bind:
960 	mlxsw_sp_span_entry_put(mlxsw_sp, span_entry);
961 	return err;
962 }
963 
964 void mlxsw_sp_span_mirror_del(struct mlxsw_sp_port *from, int span_id,
965 			      enum mlxsw_sp_span_type type, bool bind)
966 {
967 	struct mlxsw_sp_span_entry *span_entry;
968 
969 	span_entry = mlxsw_sp_span_entry_find_by_id(from->mlxsw_sp, span_id);
970 	if (!span_entry) {
971 		netdev_err(from->dev, "no span entry found\n");
972 		return;
973 	}
974 
975 	netdev_dbg(from->dev, "removing inspected port from SPAN entry %d\n",
976 		   span_entry->id);
977 	mlxsw_sp_span_inspected_port_del(from, span_entry, type, bind);
978 }
979 
980 void mlxsw_sp_span_respin(struct mlxsw_sp *mlxsw_sp)
981 {
982 	int i;
983 	int err;
984 
985 	ASSERT_RTNL();
986 	for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
987 		struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span.entries[i];
988 		struct mlxsw_sp_span_parms sparms = {NULL};
989 
990 		if (!curr->ref_count)
991 			continue;
992 
993 		err = curr->ops->parms(curr->to_dev, &sparms);
994 		if (err)
995 			continue;
996 
997 		if (memcmp(&sparms, &curr->parms, sizeof(sparms))) {
998 			mlxsw_sp_span_entry_deconfigure(curr);
999 			mlxsw_sp_span_entry_configure(mlxsw_sp, curr, sparms);
1000 		}
1001 	}
1002 }
1003