Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
   1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2/* Copyright (c) 2019-2020 Marvell International Ltd. All rights reserved */
   3
   4#include <linux/if_bridge.h>
   5#include <linux/if_vlan.h>
   6#include <linux/kernel.h>
   7#include <linux/module.h>
   8#include <linux/notifier.h>
   9#include <net/netevent.h>
  10#include <net/switchdev.h>
  11
  12#include "prestera.h"
  13#include "prestera_hw.h"
  14#include "prestera_switchdev.h"
  15
  16#define PRESTERA_VID_ALL (0xffff)
  17
  18#define PRESTERA_DEFAULT_AGEING_TIME_MS 300000
  19#define PRESTERA_MAX_AGEING_TIME_MS 1000000000
  20#define PRESTERA_MIN_AGEING_TIME_MS 32000
  21
  22struct prestera_fdb_event_work {
  23	struct work_struct work;
  24	struct switchdev_notifier_fdb_info fdb_info;
  25	struct net_device *dev;
  26	unsigned long event;
  27};
  28
  29struct prestera_switchdev {
  30	struct prestera_switch *sw;
  31	struct list_head bridge_list;
  32	bool bridge_8021q_exists;
  33	struct notifier_block swdev_nb_blk;
  34	struct notifier_block swdev_nb;
  35};
  36
  37struct prestera_bridge {
  38	struct list_head head;
  39	struct net_device *dev;
  40	struct prestera_switchdev *swdev;
  41	struct list_head port_list;
  42	struct list_head br_mdb_entry_list;
  43	bool mrouter_exist;
  44	bool vlan_enabled;
  45	bool multicast_enabled;
  46	u16 bridge_id;
  47};
  48
  49struct prestera_bridge_port {
  50	struct list_head head;
  51	struct net_device *dev;
  52	struct prestera_bridge *bridge;
  53	struct list_head vlan_list;
  54	struct list_head br_mdb_port_list;
  55	refcount_t ref_count;
  56	unsigned long flags;
  57	bool mrouter;
  58	u8 stp_state;
  59};
  60
  61struct prestera_bridge_vlan {
  62	struct list_head head;
  63	struct list_head port_vlan_list;
  64	u16 vid;
  65};
  66
  67struct prestera_port_vlan {
  68	struct list_head br_vlan_head;
  69	struct list_head port_head;
  70	struct prestera_port *port;
  71	struct prestera_bridge_port *br_port;
  72	u16 vid;
  73};
  74
  75struct prestera_br_mdb_port {
  76	struct prestera_bridge_port *br_port;
  77	struct list_head br_mdb_port_node;
  78};
  79
  80/* Software representation of MDB table. */
  81struct prestera_br_mdb_entry {
  82	struct prestera_bridge *bridge;
  83	struct prestera_mdb_entry *mdb;
  84	struct list_head br_mdb_port_list;
  85	struct list_head br_mdb_entry_node;
  86	bool enabled;
  87};
  88
  89static struct workqueue_struct *swdev_wq;
  90
  91static void prestera_bridge_port_put(struct prestera_bridge_port *br_port);
  92
  93static int prestera_port_vid_stp_set(struct prestera_port *port, u16 vid,
  94				     u8 state);
  95
  96static struct prestera_bridge *
  97prestera_bridge_find(const struct prestera_switch *sw,
  98		     const struct net_device *br_dev)
  99{
 100	struct prestera_bridge *bridge;
 101
 102	list_for_each_entry(bridge, &sw->swdev->bridge_list, head)
 103		if (bridge->dev == br_dev)
 104			return bridge;
 105
 106	return NULL;
 107}
 108
 109static struct prestera_bridge_port *
 110__prestera_bridge_port_find(const struct prestera_bridge *bridge,
 111			    const struct net_device *brport_dev)
 112{
 113	struct prestera_bridge_port *br_port;
 114
 115	list_for_each_entry(br_port, &bridge->port_list, head)
 116		if (br_port->dev == brport_dev)
 117			return br_port;
 118
 119	return NULL;
 120}
 121
 122static struct prestera_bridge_port *
 123prestera_bridge_port_find(struct prestera_switch *sw,
 124			  struct net_device *brport_dev)
 125{
 126	struct net_device *br_dev = netdev_master_upper_dev_get(brport_dev);
 127	struct prestera_bridge *bridge;
 128
 129	if (!br_dev)
 130		return NULL;
 131
 132	bridge = prestera_bridge_find(sw, br_dev);
 133	if (!bridge)
 134		return NULL;
 135
 136	return __prestera_bridge_port_find(bridge, brport_dev);
 137}
 138
 139static void
 140prestera_br_port_flags_reset(struct prestera_bridge_port *br_port,
 141			     struct prestera_port *port)
 142{
 143	prestera_port_uc_flood_set(port, false);
 144	prestera_port_mc_flood_set(port, false);
 145	prestera_port_learning_set(port, false);
 146	prestera_port_br_locked_set(port, false);
 147}
 148
 149static int prestera_br_port_flags_set(struct prestera_bridge_port *br_port,
 150				      struct prestera_port *port)
 151{
 152	int err;
 153
 154	err = prestera_port_uc_flood_set(port, br_port->flags & BR_FLOOD);
 155	if (err)
 156		goto err_out;
 157
 158	err = prestera_port_mc_flood_set(port, br_port->flags & BR_MCAST_FLOOD);
 159	if (err)
 160		goto err_out;
 161
 162	err = prestera_port_learning_set(port, br_port->flags & BR_LEARNING);
 163	if (err)
 164		goto err_out;
 165
 166	err = prestera_port_br_locked_set(port,
 167					  br_port->flags & BR_PORT_LOCKED);
 168	if (err)
 169		goto err_out;
 170
 171	return 0;
 172
 173err_out:
 174	prestera_br_port_flags_reset(br_port, port);
 175	return err;
 176}
 177
 178static struct prestera_bridge_vlan *
 179prestera_bridge_vlan_create(struct prestera_bridge_port *br_port, u16 vid)
 180{
 181	struct prestera_bridge_vlan *br_vlan;
 182
 183	br_vlan = kzalloc(sizeof(*br_vlan), GFP_KERNEL);
 184	if (!br_vlan)
 185		return NULL;
 186
 187	INIT_LIST_HEAD(&br_vlan->port_vlan_list);
 188	br_vlan->vid = vid;
 189	list_add(&br_vlan->head, &br_port->vlan_list);
 190
 191	return br_vlan;
 192}
 193
 194static void prestera_bridge_vlan_destroy(struct prestera_bridge_vlan *br_vlan)
 195{
 196	list_del(&br_vlan->head);
 197	WARN_ON(!list_empty(&br_vlan->port_vlan_list));
 198	kfree(br_vlan);
 199}
 200
 201static struct prestera_bridge_vlan *
 202prestera_bridge_vlan_by_vid(struct prestera_bridge_port *br_port, u16 vid)
 203{
 204	struct prestera_bridge_vlan *br_vlan;
 205
 206	list_for_each_entry(br_vlan, &br_port->vlan_list, head) {
 207		if (br_vlan->vid == vid)
 208			return br_vlan;
 209	}
 210
 211	return NULL;
 212}
 213
 214static int prestera_bridge_vlan_port_count(struct prestera_bridge *bridge,
 215					   u16 vid)
 216{
 217	struct prestera_bridge_port *br_port;
 218	struct prestera_bridge_vlan *br_vlan;
 219	int count = 0;
 220
 221	list_for_each_entry(br_port, &bridge->port_list, head) {
 222		list_for_each_entry(br_vlan, &br_port->vlan_list, head) {
 223			if (br_vlan->vid == vid) {
 224				count += 1;
 225				break;
 226			}
 227		}
 228	}
 229
 230	return count;
 231}
 232
 233static void prestera_bridge_vlan_put(struct prestera_bridge_vlan *br_vlan)
 234{
 235	if (list_empty(&br_vlan->port_vlan_list))
 236		prestera_bridge_vlan_destroy(br_vlan);
 237}
 238
 239static struct prestera_port_vlan *
 240prestera_port_vlan_by_vid(struct prestera_port *port, u16 vid)
 241{
 242	struct prestera_port_vlan *port_vlan;
 243
 244	list_for_each_entry(port_vlan, &port->vlans_list, port_head) {
 245		if (port_vlan->vid == vid)
 246			return port_vlan;
 247	}
 248
 249	return NULL;
 250}
 251
 252static struct prestera_port_vlan *
 253prestera_port_vlan_create(struct prestera_port *port, u16 vid, bool untagged)
 254{
 255	struct prestera_port_vlan *port_vlan;
 256	int err;
 257
 258	port_vlan = prestera_port_vlan_by_vid(port, vid);
 259	if (port_vlan)
 260		return ERR_PTR(-EEXIST);
 261
 262	err = prestera_hw_vlan_port_set(port, vid, true, untagged);
 263	if (err)
 264		return ERR_PTR(err);
 265
 266	port_vlan = kzalloc(sizeof(*port_vlan), GFP_KERNEL);
 267	if (!port_vlan) {
 268		err = -ENOMEM;
 269		goto err_port_vlan_alloc;
 270	}
 271
 272	port_vlan->port = port;
 273	port_vlan->vid = vid;
 274
 275	list_add(&port_vlan->port_head, &port->vlans_list);
 276
 277	return port_vlan;
 278
 279err_port_vlan_alloc:
 280	prestera_hw_vlan_port_set(port, vid, false, false);
 281	return ERR_PTR(err);
 282}
 283
 284static int prestera_fdb_add(struct prestera_port *port,
 285			    const unsigned char *mac, u16 vid, bool dynamic)
 286{
 287	if (prestera_port_is_lag_member(port))
 288		return prestera_hw_lag_fdb_add(port->sw, prestera_port_lag_id(port),
 289					      mac, vid, dynamic);
 290
 291	return prestera_hw_fdb_add(port, mac, vid, dynamic);
 292}
 293
 294static int prestera_fdb_del(struct prestera_port *port,
 295			    const unsigned char *mac, u16 vid)
 296{
 297	if (prestera_port_is_lag_member(port))
 298		return prestera_hw_lag_fdb_del(port->sw, prestera_port_lag_id(port),
 299					      mac, vid);
 300	else
 301		return prestera_hw_fdb_del(port, mac, vid);
 302}
 303
 304static int prestera_fdb_flush_port_vlan(struct prestera_port *port, u16 vid,
 305					u32 mode)
 306{
 307	if (prestera_port_is_lag_member(port))
 308		return prestera_hw_fdb_flush_lag_vlan(port->sw, prestera_port_lag_id(port),
 309						      vid, mode);
 310	else
 311		return prestera_hw_fdb_flush_port_vlan(port, vid, mode);
 312}
 313
 314static int prestera_fdb_flush_port(struct prestera_port *port, u32 mode)
 315{
 316	if (prestera_port_is_lag_member(port))
 317		return prestera_hw_fdb_flush_lag(port->sw, prestera_port_lag_id(port),
 318						 mode);
 319	else
 320		return prestera_hw_fdb_flush_port(port, mode);
 321}
 322
 323static void
 324prestera_mdb_port_del(struct prestera_mdb_entry *mdb,
 325		      struct net_device *orig_dev)
 326{
 327	struct prestera_flood_domain *fl_domain = mdb->flood_domain;
 328	struct prestera_flood_domain_port *flood_domain_port;
 329
 330	flood_domain_port = prestera_flood_domain_port_find(fl_domain,
 331							    orig_dev,
 332							    mdb->vid);
 333	if (flood_domain_port)
 334		prestera_flood_domain_port_destroy(flood_domain_port);
 335}
 336
 337static void
 338prestera_br_mdb_entry_put(struct prestera_br_mdb_entry *br_mdb)
 339{
 340	struct prestera_bridge_port *br_port;
 341
 342	if (list_empty(&br_mdb->br_mdb_port_list)) {
 343		list_for_each_entry(br_port, &br_mdb->bridge->port_list, head)
 344			prestera_mdb_port_del(br_mdb->mdb, br_port->dev);
 345
 346		prestera_mdb_entry_destroy(br_mdb->mdb);
 347		list_del(&br_mdb->br_mdb_entry_node);
 348		kfree(br_mdb);
 349	}
 350}
 351
 352static void
 353prestera_br_mdb_port_del(struct prestera_br_mdb_entry *br_mdb,
 354			 struct prestera_bridge_port *br_port)
 355{
 356	struct prestera_br_mdb_port *br_mdb_port, *tmp;
 357
 358	list_for_each_entry_safe(br_mdb_port, tmp, &br_mdb->br_mdb_port_list,
 359				 br_mdb_port_node) {
 360		if (br_mdb_port->br_port == br_port) {
 361			list_del(&br_mdb_port->br_mdb_port_node);
 362			kfree(br_mdb_port);
 363		}
 364	}
 365}
 366
 367static void
 368prestera_mdb_flush_bridge_port(struct prestera_bridge_port *br_port)
 369{
 370	struct prestera_br_mdb_port *br_mdb_port, *tmp_port;
 371	struct prestera_br_mdb_entry *br_mdb, *br_mdb_tmp;
 372	struct prestera_bridge *br_dev = br_port->bridge;
 373
 374	list_for_each_entry_safe(br_mdb, br_mdb_tmp, &br_dev->br_mdb_entry_list,
 375				 br_mdb_entry_node) {
 376		list_for_each_entry_safe(br_mdb_port, tmp_port,
 377					 &br_mdb->br_mdb_port_list,
 378					 br_mdb_port_node) {
 379			prestera_mdb_port_del(br_mdb->mdb,
 380					      br_mdb_port->br_port->dev);
 381			prestera_br_mdb_port_del(br_mdb,  br_mdb_port->br_port);
 382		}
 383		prestera_br_mdb_entry_put(br_mdb);
 384	}
 385}
 386
 387static void
 388prestera_port_vlan_bridge_leave(struct prestera_port_vlan *port_vlan)
 389{
 390	u32 fdb_flush_mode = PRESTERA_FDB_FLUSH_MODE_DYNAMIC;
 391	struct prestera_port *port = port_vlan->port;
 392	struct prestera_bridge_vlan *br_vlan;
 393	struct prestera_bridge_port *br_port;
 394	bool last_port, last_vlan;
 395	u16 vid = port_vlan->vid;
 396	int port_count;
 397
 398	br_port = port_vlan->br_port;
 399	port_count = prestera_bridge_vlan_port_count(br_port->bridge, vid);
 400	br_vlan = prestera_bridge_vlan_by_vid(br_port, vid);
 401
 402	last_vlan = list_is_singular(&br_port->vlan_list);
 403	last_port = port_count == 1;
 404
 405	if (last_vlan)
 406		prestera_fdb_flush_port(port, fdb_flush_mode);
 407	else if (last_port)
 408		prestera_hw_fdb_flush_vlan(port->sw, vid, fdb_flush_mode);
 409	else
 410		prestera_fdb_flush_port_vlan(port, vid, fdb_flush_mode);
 411
 412	prestera_mdb_flush_bridge_port(br_port);
 413
 414	list_del(&port_vlan->br_vlan_head);
 415	prestera_bridge_vlan_put(br_vlan);
 416	prestera_bridge_port_put(br_port);
 417	port_vlan->br_port = NULL;
 418}
 419
 420static void prestera_port_vlan_destroy(struct prestera_port_vlan *port_vlan)
 421{
 422	struct prestera_port *port = port_vlan->port;
 423	u16 vid = port_vlan->vid;
 424
 425	if (port_vlan->br_port)
 426		prestera_port_vlan_bridge_leave(port_vlan);
 427
 428	prestera_hw_vlan_port_set(port, vid, false, false);
 429	list_del(&port_vlan->port_head);
 430	kfree(port_vlan);
 431}
 432
 433static struct prestera_bridge *
 434prestera_bridge_create(struct prestera_switchdev *swdev, struct net_device *dev)
 435{
 436	bool vlan_enabled = br_vlan_enabled(dev);
 437	struct prestera_bridge *bridge;
 438	u16 bridge_id;
 439	int err;
 440
 441	if (vlan_enabled && swdev->bridge_8021q_exists) {
 442		netdev_err(dev, "Only one VLAN-aware bridge is supported\n");
 443		return ERR_PTR(-EINVAL);
 444	}
 445
 446	bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
 447	if (!bridge)
 448		return ERR_PTR(-ENOMEM);
 449
 450	if (vlan_enabled) {
 451		swdev->bridge_8021q_exists = true;
 452	} else {
 453		err = prestera_hw_bridge_create(swdev->sw, &bridge_id);
 454		if (err) {
 455			kfree(bridge);
 456			return ERR_PTR(err);
 457		}
 458
 459		bridge->bridge_id = bridge_id;
 460	}
 461
 462	bridge->vlan_enabled = vlan_enabled;
 463	bridge->swdev = swdev;
 464	bridge->dev = dev;
 465	bridge->multicast_enabled = br_multicast_enabled(dev);
 466
 467	INIT_LIST_HEAD(&bridge->port_list);
 468	INIT_LIST_HEAD(&bridge->br_mdb_entry_list);
 469
 470	list_add(&bridge->head, &swdev->bridge_list);
 471
 472	return bridge;
 473}
 474
 475static void prestera_bridge_destroy(struct prestera_bridge *bridge)
 476{
 477	struct prestera_switchdev *swdev = bridge->swdev;
 478
 479	list_del(&bridge->head);
 480
 481	if (bridge->vlan_enabled)
 482		swdev->bridge_8021q_exists = false;
 483	else
 484		prestera_hw_bridge_delete(swdev->sw, bridge->bridge_id);
 485
 486	WARN_ON(!list_empty(&bridge->br_mdb_entry_list));
 487	WARN_ON(!list_empty(&bridge->port_list));
 488	kfree(bridge);
 489}
 490
 491static void prestera_bridge_put(struct prestera_bridge *bridge)
 492{
 493	if (list_empty(&bridge->port_list))
 494		prestera_bridge_destroy(bridge);
 495}
 496
 497static
 498struct prestera_bridge *prestera_bridge_by_dev(struct prestera_switchdev *swdev,
 499					       const struct net_device *dev)
 500{
 501	struct prestera_bridge *bridge;
 502
 503	list_for_each_entry(bridge, &swdev->bridge_list, head)
 504		if (bridge->dev == dev)
 505			return bridge;
 506
 507	return NULL;
 508}
 509
 510static struct prestera_bridge_port *
 511__prestera_bridge_port_by_dev(struct prestera_bridge *bridge,
 512			      struct net_device *dev)
 513{
 514	struct prestera_bridge_port *br_port;
 515
 516	list_for_each_entry(br_port, &bridge->port_list, head) {
 517		if (br_port->dev == dev)
 518			return br_port;
 519	}
 520
 521	return NULL;
 522}
 523
 524static int prestera_match_upper_bridge_dev(struct net_device *dev,
 525					   struct netdev_nested_priv *priv)
 526{
 527	if (netif_is_bridge_master(dev))
 528		priv->data = dev;
 529
 530	return 0;
 531}
 532
 533static struct net_device *prestera_get_upper_bridge_dev(struct net_device *dev)
 534{
 535	struct netdev_nested_priv priv = { };
 536
 537	netdev_walk_all_upper_dev_rcu(dev, prestera_match_upper_bridge_dev,
 538				      &priv);
 539	return priv.data;
 540}
 541
 542static struct prestera_bridge_port *
 543prestera_bridge_port_by_dev(struct prestera_switchdev *swdev,
 544			    struct net_device *dev)
 545{
 546	struct net_device *br_dev = prestera_get_upper_bridge_dev(dev);
 547	struct prestera_bridge *bridge;
 548
 549	if (!br_dev)
 550		return NULL;
 551
 552	bridge = prestera_bridge_by_dev(swdev, br_dev);
 553	if (!bridge)
 554		return NULL;
 555
 556	return __prestera_bridge_port_by_dev(bridge, dev);
 557}
 558
 559static struct prestera_bridge_port *
 560prestera_bridge_port_create(struct prestera_bridge *bridge,
 561			    struct net_device *dev)
 562{
 563	struct prestera_bridge_port *br_port;
 564
 565	br_port = kzalloc(sizeof(*br_port), GFP_KERNEL);
 566	if (!br_port)
 567		return NULL;
 568
 569	br_port->flags = BR_LEARNING | BR_FLOOD | BR_LEARNING_SYNC |
 570				BR_MCAST_FLOOD;
 571	br_port->stp_state = BR_STATE_DISABLED;
 572	refcount_set(&br_port->ref_count, 1);
 573	br_port->bridge = bridge;
 574	br_port->dev = dev;
 575
 576	INIT_LIST_HEAD(&br_port->vlan_list);
 577	list_add(&br_port->head, &bridge->port_list);
 578	INIT_LIST_HEAD(&br_port->br_mdb_port_list);
 579
 580	return br_port;
 581}
 582
 583static void
 584prestera_bridge_port_destroy(struct prestera_bridge_port *br_port)
 585{
 586	list_del(&br_port->head);
 587	WARN_ON(!list_empty(&br_port->vlan_list));
 588	WARN_ON(!list_empty(&br_port->br_mdb_port_list));
 589	kfree(br_port);
 590}
 591
 592static void prestera_bridge_port_get(struct prestera_bridge_port *br_port)
 593{
 594	refcount_inc(&br_port->ref_count);
 595}
 596
 597static void prestera_bridge_port_put(struct prestera_bridge_port *br_port)
 598{
 599	struct prestera_bridge *bridge = br_port->bridge;
 600
 601	if (refcount_dec_and_test(&br_port->ref_count)) {
 602		prestera_bridge_port_destroy(br_port);
 603		prestera_bridge_put(bridge);
 604	}
 605}
 606
 607static struct prestera_bridge_port *
 608prestera_bridge_port_add(struct prestera_bridge *bridge, struct net_device *dev)
 609{
 610	struct prestera_bridge_port *br_port;
 611
 612	br_port = __prestera_bridge_port_by_dev(bridge, dev);
 613	if (br_port) {
 614		prestera_bridge_port_get(br_port);
 615		return br_port;
 616	}
 617
 618	br_port = prestera_bridge_port_create(bridge, dev);
 619	if (!br_port)
 620		return ERR_PTR(-ENOMEM);
 621
 622	return br_port;
 623}
 624
 625static int
 626prestera_bridge_1d_port_join(struct prestera_bridge_port *br_port)
 627{
 628	struct prestera_port *port = netdev_priv(br_port->dev);
 629	struct prestera_bridge *bridge = br_port->bridge;
 630	int err;
 631
 632	err = prestera_hw_bridge_port_add(port, bridge->bridge_id);
 633	if (err)
 634		return err;
 635
 636	err = prestera_br_port_flags_set(br_port, port);
 637	if (err)
 638		goto err_flags2port_set;
 639
 640	return 0;
 641
 642err_flags2port_set:
 643	prestera_hw_bridge_port_delete(port, bridge->bridge_id);
 644
 645	return err;
 646}
 647
 648int prestera_bridge_port_join(struct net_device *br_dev,
 649			      struct prestera_port *port,
 650			      struct netlink_ext_ack *extack)
 651{
 652	struct prestera_switchdev *swdev = port->sw->swdev;
 653	struct prestera_bridge_port *br_port;
 654	struct prestera_bridge *bridge;
 655	int err;
 656
 657	bridge = prestera_bridge_by_dev(swdev, br_dev);
 658	if (!bridge) {
 659		bridge = prestera_bridge_create(swdev, br_dev);
 660		if (IS_ERR(bridge))
 661			return PTR_ERR(bridge);
 662	}
 663
 664	br_port = prestera_bridge_port_add(bridge, port->dev);
 665	if (IS_ERR(br_port)) {
 666		prestera_bridge_put(bridge);
 667		return PTR_ERR(br_port);
 668	}
 669
 670	err = switchdev_bridge_port_offload(br_port->dev, port->dev, NULL,
 671					    NULL, NULL, false, extack);
 672	if (err)
 673		goto err_switchdev_offload;
 674
 675	if (bridge->vlan_enabled)
 676		return 0;
 677
 678	err = prestera_bridge_1d_port_join(br_port);
 679	if (err)
 680		goto err_port_join;
 681
 682	return 0;
 683
 684err_port_join:
 685	switchdev_bridge_port_unoffload(br_port->dev, NULL, NULL, NULL);
 686err_switchdev_offload:
 687	prestera_bridge_port_put(br_port);
 688	return err;
 689}
 690
 691static void prestera_bridge_1q_port_leave(struct prestera_bridge_port *br_port)
 692{
 693	struct prestera_port *port = netdev_priv(br_port->dev);
 694
 695	prestera_hw_fdb_flush_port(port, PRESTERA_FDB_FLUSH_MODE_ALL);
 696	prestera_port_pvid_set(port, PRESTERA_DEFAULT_VID);
 697}
 698
 699static void prestera_bridge_1d_port_leave(struct prestera_bridge_port *br_port)
 700{
 701	struct prestera_port *port = netdev_priv(br_port->dev);
 702
 703	prestera_hw_fdb_flush_port(port, PRESTERA_FDB_FLUSH_MODE_ALL);
 704	prestera_hw_bridge_port_delete(port, br_port->bridge->bridge_id);
 705}
 706
 707static int prestera_port_vid_stp_set(struct prestera_port *port, u16 vid,
 708				     u8 state)
 709{
 710	u8 hw_state = state;
 711
 712	switch (state) {
 713	case BR_STATE_DISABLED:
 714		hw_state = PRESTERA_STP_DISABLED;
 715		break;
 716
 717	case BR_STATE_BLOCKING:
 718	case BR_STATE_LISTENING:
 719		hw_state = PRESTERA_STP_BLOCK_LISTEN;
 720		break;
 721
 722	case BR_STATE_LEARNING:
 723		hw_state = PRESTERA_STP_LEARN;
 724		break;
 725
 726	case BR_STATE_FORWARDING:
 727		hw_state = PRESTERA_STP_FORWARD;
 728		break;
 729
 730	default:
 731		return -EINVAL;
 732	}
 733
 734	return prestera_hw_vlan_port_stp_set(port, vid, hw_state);
 735}
 736
 737void prestera_bridge_port_leave(struct net_device *br_dev,
 738				struct prestera_port *port)
 739{
 740	struct prestera_switchdev *swdev = port->sw->swdev;
 741	struct prestera_bridge_port *br_port;
 742	struct prestera_bridge *bridge;
 743
 744	bridge = prestera_bridge_by_dev(swdev, br_dev);
 745	if (!bridge)
 746		return;
 747
 748	br_port = __prestera_bridge_port_by_dev(bridge, port->dev);
 749	if (!br_port)
 750		return;
 751
 752	bridge = br_port->bridge;
 753
 754	if (bridge->vlan_enabled)
 755		prestera_bridge_1q_port_leave(br_port);
 756	else
 757		prestera_bridge_1d_port_leave(br_port);
 758
 759	switchdev_bridge_port_unoffload(br_port->dev, NULL, NULL, NULL);
 760
 761	prestera_mdb_flush_bridge_port(br_port);
 762
 763	prestera_br_port_flags_reset(br_port, port);
 764	prestera_port_vid_stp_set(port, PRESTERA_VID_ALL, BR_STATE_FORWARDING);
 765	prestera_bridge_port_put(br_port);
 766}
 767
 768static int prestera_port_attr_br_flags_set(struct prestera_port *port,
 769					   struct net_device *dev,
 770					   struct switchdev_brport_flags flags)
 771{
 772	struct prestera_bridge_port *br_port;
 773
 774	br_port = prestera_bridge_port_by_dev(port->sw->swdev, dev);
 775	if (!br_port)
 776		return 0;
 777
 778	br_port->flags &= ~flags.mask;
 779	br_port->flags |= flags.val & flags.mask;
 780	return prestera_br_port_flags_set(br_port, port);
 781}
 782
 783static int prestera_port_attr_br_ageing_set(struct prestera_port *port,
 784					    unsigned long ageing_clock_t)
 785{
 786	unsigned long ageing_jiffies = clock_t_to_jiffies(ageing_clock_t);
 787	u32 ageing_time_ms = jiffies_to_msecs(ageing_jiffies);
 788	struct prestera_switch *sw = port->sw;
 789
 790	if (ageing_time_ms < PRESTERA_MIN_AGEING_TIME_MS ||
 791	    ageing_time_ms > PRESTERA_MAX_AGEING_TIME_MS)
 792		return -ERANGE;
 793
 794	return prestera_hw_switch_ageing_set(sw, ageing_time_ms);
 795}
 796
 797static int prestera_port_attr_br_vlan_set(struct prestera_port *port,
 798					  struct net_device *dev,
 799					  bool vlan_enabled)
 800{
 801	struct prestera_switch *sw = port->sw;
 802	struct prestera_bridge *bridge;
 803
 804	bridge = prestera_bridge_by_dev(sw->swdev, dev);
 805	if (WARN_ON(!bridge))
 806		return -EINVAL;
 807
 808	if (bridge->vlan_enabled == vlan_enabled)
 809		return 0;
 810
 811	netdev_err(bridge->dev, "VLAN filtering can't be changed for existing bridge\n");
 812
 813	return -EINVAL;
 814}
 815
 816static int prestera_port_bridge_vlan_stp_set(struct prestera_port *port,
 817					     struct prestera_bridge_vlan *br_vlan,
 818					     u8 state)
 819{
 820	struct prestera_port_vlan *port_vlan;
 821
 822	list_for_each_entry(port_vlan, &br_vlan->port_vlan_list, br_vlan_head) {
 823		if (port_vlan->port != port)
 824			continue;
 825
 826		return prestera_port_vid_stp_set(port, br_vlan->vid, state);
 827	}
 828
 829	return 0;
 830}
 831
 832static int prestera_port_attr_stp_state_set(struct prestera_port *port,
 833					    struct net_device *dev,
 834					    u8 state)
 835{
 836	struct prestera_bridge_port *br_port;
 837	struct prestera_bridge_vlan *br_vlan;
 838	int err;
 839	u16 vid;
 840
 841	br_port = prestera_bridge_port_by_dev(port->sw->swdev, dev);
 842	if (!br_port)
 843		return 0;
 844
 845	if (!br_port->bridge->vlan_enabled) {
 846		vid = br_port->bridge->bridge_id;
 847		err = prestera_port_vid_stp_set(port, vid, state);
 848		if (err)
 849			goto err_port_stp_set;
 850	} else {
 851		list_for_each_entry(br_vlan, &br_port->vlan_list, head) {
 852			err = prestera_port_bridge_vlan_stp_set(port, br_vlan,
 853								state);
 854			if (err)
 855				goto err_port_vlan_stp_set;
 856		}
 857	}
 858
 859	br_port->stp_state = state;
 860
 861	return 0;
 862
 863err_port_vlan_stp_set:
 864	list_for_each_entry_continue_reverse(br_vlan, &br_port->vlan_list, head)
 865		prestera_port_bridge_vlan_stp_set(port, br_vlan, br_port->stp_state);
 866	return err;
 867
 868err_port_stp_set:
 869	prestera_port_vid_stp_set(port, vid, br_port->stp_state);
 870
 871	return err;
 872}
 873
 874static int
 875prestera_br_port_lag_mdb_mc_enable_sync(struct prestera_bridge_port *br_port,
 876					bool enabled)
 877{
 878	struct prestera_port *pr_port;
 879	struct prestera_switch *sw;
 880	u16 lag_id;
 881	int err;
 882
 883	pr_port = prestera_port_dev_lower_find(br_port->dev);
 884	if (!pr_port)
 885		return 0;
 886
 887	sw = pr_port->sw;
 888	err = prestera_lag_id(sw, br_port->dev, &lag_id);
 889	if (err)
 890		return err;
 891
 892	list_for_each_entry(pr_port, &sw->port_list, list) {
 893		if (pr_port->lag->lag_id == lag_id) {
 894			err = prestera_port_mc_flood_set(pr_port, enabled);
 895			if (err)
 896				return err;
 897		}
 898	}
 899
 900	return 0;
 901}
 902
 903static int prestera_br_mdb_mc_enable_sync(struct prestera_bridge *br_dev)
 904{
 905	struct prestera_bridge_port *br_port;
 906	struct prestera_port *port;
 907	bool enabled;
 908	int err;
 909
 910	/* if mrouter exists:
 911	 *  - make sure every mrouter receives unreg mcast traffic;
 912	 * if mrouter doesn't exists:
 913	 *  - make sure every port receives unreg mcast traffic;
 914	 */
 915	list_for_each_entry(br_port, &br_dev->port_list, head) {
 916		if (br_dev->multicast_enabled && br_dev->mrouter_exist)
 917			enabled = br_port->mrouter;
 918		else
 919			enabled = br_port->flags & BR_MCAST_FLOOD;
 920
 921		if (netif_is_lag_master(br_port->dev)) {
 922			err = prestera_br_port_lag_mdb_mc_enable_sync(br_port,
 923								      enabled);
 924			if (err)
 925				return err;
 926			continue;
 927		}
 928
 929		port = prestera_port_dev_lower_find(br_port->dev);
 930		if (!port)
 931			continue;
 932
 933		err = prestera_port_mc_flood_set(port, enabled);
 934		if (err)
 935			return err;
 936	}
 937
 938	return 0;
 939}
 940
 941static bool
 942prestera_br_mdb_port_is_member(struct prestera_br_mdb_entry *br_mdb,
 943			       struct net_device *orig_dev)
 944{
 945	struct prestera_br_mdb_port *tmp_port;
 946
 947	list_for_each_entry(tmp_port, &br_mdb->br_mdb_port_list,
 948			    br_mdb_port_node)
 949		if (tmp_port->br_port->dev == orig_dev)
 950			return true;
 951
 952	return false;
 953}
 954
 955static int
 956prestera_mdb_port_add(struct prestera_mdb_entry *mdb,
 957		      struct net_device *orig_dev,
 958		      const unsigned char addr[ETH_ALEN], u16 vid)
 959{
 960	struct prestera_flood_domain *flood_domain = mdb->flood_domain;
 961	int err;
 962
 963	if (!prestera_flood_domain_port_find(flood_domain,
 964					     orig_dev, vid)) {
 965		err = prestera_flood_domain_port_create(flood_domain, orig_dev,
 966							vid);
 967		if (err)
 968			return err;
 969	}
 970
 971	return 0;
 972}
 973
 974/* Sync bridge mdb (software table) with HW table (if MC is enabled). */
 975static int prestera_br_mdb_sync(struct prestera_bridge *br_dev)
 976{
 977	struct prestera_br_mdb_port *br_mdb_port;
 978	struct prestera_bridge_port *br_port;
 979	struct prestera_br_mdb_entry *br_mdb;
 980	struct prestera_mdb_entry *mdb;
 981	struct prestera_port *pr_port;
 982	int err = 0;
 983
 984	if (!br_dev->multicast_enabled)
 985		return 0;
 986
 987	list_for_each_entry(br_mdb, &br_dev->br_mdb_entry_list,
 988			    br_mdb_entry_node) {
 989		mdb = br_mdb->mdb;
 990		/* Make sure every port that explicitly been added to the mdb
 991		 * joins the specified group.
 992		 */
 993		list_for_each_entry(br_mdb_port, &br_mdb->br_mdb_port_list,
 994				    br_mdb_port_node) {
 995			br_port = br_mdb_port->br_port;
 996			pr_port = prestera_port_dev_lower_find(br_port->dev);
 997
 998			/* Match only mdb and br_mdb ports that belong to the
 999			 * same broadcast domain.
1000			 */
1001			if (br_dev->vlan_enabled &&
1002			    !prestera_port_vlan_by_vid(pr_port,
1003						       mdb->vid))
1004				continue;
1005
1006			/* If port is not in MDB or there's no Mrouter
1007			 * clear HW mdb.
1008			 */
1009			if (prestera_br_mdb_port_is_member(br_mdb,
1010							   br_mdb_port->br_port->dev) &&
1011							   br_dev->mrouter_exist)
1012				err = prestera_mdb_port_add(mdb, br_port->dev,
1013							    mdb->addr,
1014							    mdb->vid);
1015			else
1016				prestera_mdb_port_del(mdb, br_port->dev);
1017
1018			if (err)
1019				return err;
1020		}
1021
1022		/* Make sure that every mrouter port joins every MC group int
1023		 * broadcast domain. If it's not an mrouter - it should leave
1024		 */
1025		list_for_each_entry(br_port, &br_dev->port_list, head) {
1026			pr_port = prestera_port_dev_lower_find(br_port->dev);
1027
1028			/* Make sure mrouter woudln't receive traffci from
1029			 * another broadcast domain (e.g. from a vlan, which
1030			 * mrouter port is not a member of).
1031			 */
1032			if (br_dev->vlan_enabled &&
1033			    !prestera_port_vlan_by_vid(pr_port,
1034						       mdb->vid))
1035				continue;
1036
1037			if (br_port->mrouter) {
1038				err = prestera_mdb_port_add(mdb, br_port->dev,
1039							    mdb->addr,
1040							    mdb->vid);
1041				if (err)
1042					return err;
1043			} else if (!br_port->mrouter &&
1044				   !prestera_br_mdb_port_is_member
1045				   (br_mdb, br_port->dev)) {
1046				prestera_mdb_port_del(mdb, br_port->dev);
1047			}
1048		}
1049	}
1050
1051	return 0;
1052}
1053
1054static int
1055prestera_mdb_enable_set(struct prestera_br_mdb_entry *br_mdb, bool enable)
1056{
1057	int err;
1058
1059	if (enable != br_mdb->enabled) {
1060		if (enable)
1061			err = prestera_hw_mdb_create(br_mdb->mdb);
1062		else
1063			err = prestera_hw_mdb_destroy(br_mdb->mdb);
1064
1065		if (err)
1066			return err;
1067
1068		br_mdb->enabled = enable;
1069	}
1070
1071	return 0;
1072}
1073
1074static int
1075prestera_br_mdb_enable_set(struct prestera_bridge *br_dev, bool enable)
1076{
1077	struct prestera_br_mdb_entry *br_mdb;
1078	int err;
1079
1080	list_for_each_entry(br_mdb, &br_dev->br_mdb_entry_list,
1081			    br_mdb_entry_node) {
1082		err = prestera_mdb_enable_set(br_mdb, enable);
1083		if (err)
1084			return err;
1085	}
1086
1087	return 0;
1088}
1089
1090static int prestera_port_attr_br_mc_disabled_set(struct prestera_port *port,
1091						 struct net_device *orig_dev,
1092						 bool mc_disabled)
1093{
1094	struct prestera_switch *sw = port->sw;
1095	struct prestera_bridge *br_dev;
1096
1097	br_dev = prestera_bridge_find(sw, orig_dev);
1098	if (!br_dev)
1099		return 0;
1100
1101	br_dev->multicast_enabled = !mc_disabled;
1102
1103	/* There's no point in enabling mdb back if router is missing. */
1104	WARN_ON(prestera_br_mdb_enable_set(br_dev, br_dev->multicast_enabled &&
1105					   br_dev->mrouter_exist));
1106
1107	WARN_ON(prestera_br_mdb_sync(br_dev));
1108
1109	WARN_ON(prestera_br_mdb_mc_enable_sync(br_dev));
1110
1111	return 0;
1112}
1113
1114static bool
1115prestera_bridge_mdb_mc_mrouter_exists(struct prestera_bridge *br_dev)
1116{
1117	struct prestera_bridge_port *br_port;
1118
1119	list_for_each_entry(br_port, &br_dev->port_list, head)
1120		if (br_port->mrouter)
1121			return true;
1122
1123	return false;
1124}
1125
1126static int
1127prestera_port_attr_mrouter_set(struct prestera_port *port,
1128			       struct net_device *orig_dev,
1129			       bool is_port_mrouter)
1130{
1131	struct prestera_bridge_port *br_port;
1132	struct prestera_bridge *br_dev;
1133
1134	br_port = prestera_bridge_port_find(port->sw, orig_dev);
1135	if (!br_port)
1136		return 0;
1137
1138	br_dev = br_port->bridge;
1139	br_port->mrouter = is_port_mrouter;
1140
1141	br_dev->mrouter_exist = prestera_bridge_mdb_mc_mrouter_exists(br_dev);
1142
1143	/* Enable MDB processing if both mrouter exists and mc is enabled.
1144	 * In case if MC enabled, but there is no mrouter, device would flood
1145	 * all multicast traffic (even if MDB table is not empty) with the use
1146	 * of bridge's flood capabilities (without the use of flood_domain).
1147	 */
1148	WARN_ON(prestera_br_mdb_enable_set(br_dev, br_dev->multicast_enabled &&
1149					   br_dev->mrouter_exist));
1150
1151	WARN_ON(prestera_br_mdb_sync(br_dev));
1152
1153	WARN_ON(prestera_br_mdb_mc_enable_sync(br_dev));
1154
1155	return 0;
1156}
1157
1158static int prestera_port_obj_attr_set(struct net_device *dev, const void *ctx,
1159				      const struct switchdev_attr *attr,
1160				      struct netlink_ext_ack *extack)
1161{
1162	struct prestera_port *port = netdev_priv(dev);
1163	int err = 0;
1164
1165	switch (attr->id) {
1166	case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
1167		err = prestera_port_attr_stp_state_set(port, attr->orig_dev,
1168						       attr->u.stp_state);
1169		break;
1170	case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS:
1171		if (attr->u.brport_flags.mask &
1172		    ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_PORT_LOCKED))
1173			err = -EINVAL;
1174		break;
1175	case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
1176		err = prestera_port_attr_br_flags_set(port, attr->orig_dev,
1177						      attr->u.brport_flags);
1178		break;
1179	case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
1180		err = prestera_port_attr_br_ageing_set(port,
1181						       attr->u.ageing_time);
1182		break;
1183	case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING:
1184		err = prestera_port_attr_br_vlan_set(port, attr->orig_dev,
1185						     attr->u.vlan_filtering);
1186		break;
1187	case SWITCHDEV_ATTR_ID_PORT_MROUTER:
1188		err = prestera_port_attr_mrouter_set(port, attr->orig_dev,
1189						     attr->u.mrouter);
1190		break;
1191	case SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED:
1192		err = prestera_port_attr_br_mc_disabled_set(port, attr->orig_dev,
1193							    attr->u.mc_disabled);
1194		break;
1195	default:
1196		err = -EOPNOTSUPP;
1197	}
1198
1199	return err;
1200}
1201
1202static void
1203prestera_fdb_offload_notify(struct prestera_port *port,
1204			    struct switchdev_notifier_fdb_info *info)
1205{
1206	struct switchdev_notifier_fdb_info send_info = {};
1207
1208	send_info.addr = info->addr;
1209	send_info.vid = info->vid;
1210	send_info.offloaded = true;
1211
1212	call_switchdev_notifiers(SWITCHDEV_FDB_OFFLOADED, port->dev,
1213				 &send_info.info, NULL);
1214}
1215
1216static int prestera_port_fdb_set(struct prestera_port *port,
1217				 struct switchdev_notifier_fdb_info *fdb_info,
1218				 bool adding)
1219{
1220	struct prestera_switch *sw = port->sw;
1221	struct prestera_bridge_port *br_port;
1222	struct prestera_bridge *bridge;
1223	int err;
1224	u16 vid;
1225
1226	br_port = prestera_bridge_port_by_dev(sw->swdev, port->dev);
1227	if (!br_port)
1228		return -EINVAL;
1229
1230	bridge = br_port->bridge;
1231
1232	if (bridge->vlan_enabled)
1233		vid = fdb_info->vid;
1234	else
1235		vid = bridge->bridge_id;
1236
1237	if (adding)
1238		err = prestera_fdb_add(port, fdb_info->addr, vid, false);
1239	else
1240		err = prestera_fdb_del(port, fdb_info->addr, vid);
1241
1242	return err;
1243}
1244
1245static void prestera_fdb_event_work(struct work_struct *work)
1246{
1247	struct switchdev_notifier_fdb_info *fdb_info;
1248	struct prestera_fdb_event_work *swdev_work;
1249	struct prestera_port *port;
1250	struct net_device *dev;
1251	int err;
1252
1253	swdev_work = container_of(work, struct prestera_fdb_event_work, work);
1254	dev = swdev_work->dev;
1255
1256	rtnl_lock();
1257
1258	port = prestera_port_dev_lower_find(dev);
1259	if (!port)
1260		goto out_unlock;
1261
1262	switch (swdev_work->event) {
1263	case SWITCHDEV_FDB_ADD_TO_DEVICE:
1264		fdb_info = &swdev_work->fdb_info;
1265		if (!fdb_info->added_by_user || fdb_info->is_local)
1266			break;
1267
1268		err = prestera_port_fdb_set(port, fdb_info, true);
1269		if (err)
1270			break;
1271
1272		prestera_fdb_offload_notify(port, fdb_info);
1273		break;
1274
1275	case SWITCHDEV_FDB_DEL_TO_DEVICE:
1276		fdb_info = &swdev_work->fdb_info;
1277		prestera_port_fdb_set(port, fdb_info, false);
1278		break;
1279	}
1280
1281out_unlock:
1282	rtnl_unlock();
1283
1284	kfree(swdev_work->fdb_info.addr);
1285	kfree(swdev_work);
1286	dev_put(dev);
1287}
1288
1289static int prestera_switchdev_event(struct notifier_block *unused,
1290				    unsigned long event, void *ptr)
1291{
1292	struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
1293	struct switchdev_notifier_fdb_info *fdb_info;
1294	struct switchdev_notifier_info *info = ptr;
1295	struct prestera_fdb_event_work *swdev_work;
1296	struct net_device *upper;
1297	int err;
1298
1299	if (event == SWITCHDEV_PORT_ATTR_SET) {
1300		err = switchdev_handle_port_attr_set(dev, ptr,
1301						     prestera_netdev_check,
1302						     prestera_port_obj_attr_set);
1303		return notifier_from_errno(err);
1304	}
1305
1306	if (!prestera_netdev_check(dev))
1307		return NOTIFY_DONE;
1308
1309	upper = netdev_master_upper_dev_get_rcu(dev);
1310	if (!upper)
1311		return NOTIFY_DONE;
1312
1313	if (!netif_is_bridge_master(upper))
1314		return NOTIFY_DONE;
1315
1316	swdev_work = kzalloc(sizeof(*swdev_work), GFP_ATOMIC);
1317	if (!swdev_work)
1318		return NOTIFY_BAD;
1319
1320	swdev_work->event = event;
1321	swdev_work->dev = dev;
1322
1323	switch (event) {
1324	case SWITCHDEV_FDB_ADD_TO_DEVICE:
1325	case SWITCHDEV_FDB_DEL_TO_DEVICE:
1326		fdb_info = container_of(info,
1327					struct switchdev_notifier_fdb_info,
1328					info);
1329
1330		INIT_WORK(&swdev_work->work, prestera_fdb_event_work);
1331		memcpy(&swdev_work->fdb_info, ptr,
1332		       sizeof(swdev_work->fdb_info));
1333
1334		swdev_work->fdb_info.addr = kzalloc(ETH_ALEN, GFP_ATOMIC);
1335		if (!swdev_work->fdb_info.addr)
1336			goto out_bad;
1337
1338		ether_addr_copy((u8 *)swdev_work->fdb_info.addr,
1339				fdb_info->addr);
1340		dev_hold(dev);
1341		break;
1342
1343	default:
1344		kfree(swdev_work);
1345		return NOTIFY_DONE;
1346	}
1347
1348	queue_work(swdev_wq, &swdev_work->work);
1349	return NOTIFY_DONE;
1350
1351out_bad:
1352	kfree(swdev_work);
1353	return NOTIFY_BAD;
1354}
1355
1356static int
1357prestera_port_vlan_bridge_join(struct prestera_port_vlan *port_vlan,
1358			       struct prestera_bridge_port *br_port)
1359{
1360	struct prestera_port *port = port_vlan->port;
1361	struct prestera_bridge_vlan *br_vlan;
1362	u16 vid = port_vlan->vid;
1363	int err;
1364
1365	if (port_vlan->br_port)
1366		return 0;
1367
1368	err = prestera_br_port_flags_set(br_port, port);
1369	if (err)
1370		goto err_flags2port_set;
1371
1372	err = prestera_port_vid_stp_set(port, vid, br_port->stp_state);
1373	if (err)
1374		goto err_port_vid_stp_set;
1375
1376	br_vlan = prestera_bridge_vlan_by_vid(br_port, vid);
1377	if (!br_vlan) {
1378		br_vlan = prestera_bridge_vlan_create(br_port, vid);
1379		if (!br_vlan) {
1380			err = -ENOMEM;
1381			goto err_bridge_vlan_get;
1382		}
1383	}
1384
1385	list_add(&port_vlan->br_vlan_head, &br_vlan->port_vlan_list);
1386
1387	prestera_bridge_port_get(br_port);
1388	port_vlan->br_port = br_port;
1389
1390	return 0;
1391
1392err_bridge_vlan_get:
1393	prestera_port_vid_stp_set(port, vid, BR_STATE_FORWARDING);
1394err_port_vid_stp_set:
1395	prestera_br_port_flags_reset(br_port, port);
1396err_flags2port_set:
1397	return err;
1398}
1399
1400static int
1401prestera_bridge_port_vlan_add(struct prestera_port *port,
1402			      struct prestera_bridge_port *br_port,
1403			      u16 vid, bool is_untagged, bool is_pvid,
1404			      struct netlink_ext_ack *extack)
1405{
1406	struct prestera_port_vlan *port_vlan;
1407	u16 old_pvid = port->pvid;
1408	u16 pvid;
1409	int err;
1410
1411	if (is_pvid)
1412		pvid = vid;
1413	else
1414		pvid = port->pvid == vid ? 0 : port->pvid;
1415
1416	port_vlan = prestera_port_vlan_by_vid(port, vid);
1417	if (port_vlan && port_vlan->br_port != br_port)
1418		return -EEXIST;
1419
1420	if (!port_vlan) {
1421		port_vlan = prestera_port_vlan_create(port, vid, is_untagged);
1422		if (IS_ERR(port_vlan))
1423			return PTR_ERR(port_vlan);
1424	} else {
1425		err = prestera_hw_vlan_port_set(port, vid, true, is_untagged);
1426		if (err)
1427			goto err_port_vlan_set;
1428	}
1429
1430	err = prestera_port_pvid_set(port, pvid);
1431	if (err)
1432		goto err_port_pvid_set;
1433
1434	err = prestera_port_vlan_bridge_join(port_vlan, br_port);
1435	if (err)
1436		goto err_port_vlan_bridge_join;
1437
1438	return 0;
1439
1440err_port_vlan_bridge_join:
1441	prestera_port_pvid_set(port, old_pvid);
1442err_port_pvid_set:
1443	prestera_hw_vlan_port_set(port, vid, false, false);
1444err_port_vlan_set:
1445	prestera_port_vlan_destroy(port_vlan);
1446
1447	return err;
1448}
1449
1450static void
1451prestera_bridge_port_vlan_del(struct prestera_port *port,
1452			      struct prestera_bridge_port *br_port, u16 vid)
1453{
1454	u16 pvid = port->pvid == vid ? 0 : port->pvid;
1455	struct prestera_port_vlan *port_vlan;
1456
1457	port_vlan = prestera_port_vlan_by_vid(port, vid);
1458	if (WARN_ON(!port_vlan))
1459		return;
1460
1461	prestera_port_vlan_bridge_leave(port_vlan);
1462	prestera_port_pvid_set(port, pvid);
1463	prestera_port_vlan_destroy(port_vlan);
1464}
1465
1466static int prestera_port_vlans_add(struct prestera_port *port,
1467				   const struct switchdev_obj_port_vlan *vlan,
1468				   struct netlink_ext_ack *extack)
1469{
1470	bool flag_untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
1471	bool flag_pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
1472	struct net_device *orig_dev = vlan->obj.orig_dev;
1473	struct prestera_bridge_port *br_port;
1474	struct prestera_switch *sw = port->sw;
1475	struct prestera_bridge *bridge;
1476
1477	if (netif_is_bridge_master(orig_dev))
1478		return 0;
1479
1480	br_port = prestera_bridge_port_by_dev(sw->swdev, port->dev);
1481	if (WARN_ON(!br_port))
1482		return -EINVAL;
1483
1484	bridge = br_port->bridge;
1485	if (!bridge->vlan_enabled)
1486		return 0;
1487
1488	return prestera_bridge_port_vlan_add(port, br_port,
1489					     vlan->vid, flag_untagged,
1490					     flag_pvid, extack);
1491}
1492
1493static struct prestera_br_mdb_entry *
1494prestera_br_mdb_entry_create(struct prestera_switch *sw,
1495			     struct prestera_bridge *br_dev,
1496			     const unsigned char *addr, u16 vid)
1497{
1498	struct prestera_br_mdb_entry *br_mdb_entry;
1499	struct prestera_mdb_entry *mdb_entry;
1500
1501	br_mdb_entry = kzalloc(sizeof(*br_mdb_entry), GFP_KERNEL);
1502	if (!br_mdb_entry)
1503		return NULL;
1504
1505	mdb_entry = prestera_mdb_entry_create(sw, addr, vid);
1506	if (!mdb_entry)
1507		goto err_mdb_alloc;
1508
1509	br_mdb_entry->mdb = mdb_entry;
1510	br_mdb_entry->bridge = br_dev;
1511	br_mdb_entry->enabled = true;
1512	INIT_LIST_HEAD(&br_mdb_entry->br_mdb_port_list);
1513
1514	list_add(&br_mdb_entry->br_mdb_entry_node, &br_dev->br_mdb_entry_list);
1515
1516	return br_mdb_entry;
1517
1518err_mdb_alloc:
1519	kfree(br_mdb_entry);
1520	return NULL;
1521}
1522
1523static int prestera_br_mdb_port_add(struct prestera_br_mdb_entry *br_mdb,
1524				    struct prestera_bridge_port *br_port)
1525{
1526	struct prestera_br_mdb_port *br_mdb_port;
1527
1528	list_for_each_entry(br_mdb_port, &br_mdb->br_mdb_port_list,
1529			    br_mdb_port_node)
1530		if (br_mdb_port->br_port == br_port)
1531			return 0;
1532
1533	br_mdb_port = kzalloc(sizeof(*br_mdb_port), GFP_KERNEL);
1534	if (!br_mdb_port)
1535		return -ENOMEM;
1536
1537	br_mdb_port->br_port = br_port;
1538	list_add(&br_mdb_port->br_mdb_port_node,
1539		 &br_mdb->br_mdb_port_list);
1540
1541	return 0;
1542}
1543
1544static struct prestera_br_mdb_entry *
1545prestera_br_mdb_entry_find(struct prestera_bridge *br_dev,
1546			   const unsigned char *addr, u16 vid)
1547{
1548	struct prestera_br_mdb_entry *br_mdb;
1549
1550	list_for_each_entry(br_mdb, &br_dev->br_mdb_entry_list,
1551			    br_mdb_entry_node)
1552		if (ether_addr_equal(&br_mdb->mdb->addr[0], addr) &&
1553		    vid == br_mdb->mdb->vid)
1554			return br_mdb;
1555
1556	return NULL;
1557}
1558
1559static struct prestera_br_mdb_entry *
1560prestera_br_mdb_entry_get(struct prestera_switch *sw,
1561			  struct prestera_bridge *br_dev,
1562			  const unsigned char *addr, u16 vid)
1563{
1564	struct prestera_br_mdb_entry *br_mdb;
1565
1566	br_mdb = prestera_br_mdb_entry_find(br_dev, addr, vid);
1567	if (br_mdb)
1568		return br_mdb;
1569
1570	return prestera_br_mdb_entry_create(sw, br_dev, addr, vid);
1571}
1572
1573static int
1574prestera_mdb_port_addr_obj_add(const struct switchdev_obj_port_mdb *mdb)
1575{
1576	struct prestera_br_mdb_entry *br_mdb;
1577	struct prestera_bridge_port *br_port;
1578	struct prestera_bridge *br_dev;
1579	struct prestera_switch *sw;
1580	struct prestera_port *port;
1581	int err;
1582
1583	sw = prestera_switch_get(mdb->obj.orig_dev);
1584	port = prestera_port_dev_lower_find(mdb->obj.orig_dev);
1585
1586	br_port = prestera_bridge_port_find(sw, mdb->obj.orig_dev);
1587	if (!br_port)
1588		return 0;
1589
1590	br_dev = br_port->bridge;
1591
1592	if (mdb->vid && !prestera_port_vlan_by_vid(port, mdb->vid))
1593		return 0;
1594
1595	if (mdb->vid)
1596		br_mdb = prestera_br_mdb_entry_get(sw, br_dev, &mdb->addr[0],
1597						   mdb->vid);
1598	else
1599		br_mdb = prestera_br_mdb_entry_get(sw, br_dev, &mdb->addr[0],
1600						   br_dev->bridge_id);
1601
1602	if (!br_mdb)
1603		return -ENOMEM;
1604
1605	/* Make sure newly allocated MDB entry gets disabled if either MC is
1606	 * disabled, or the mrouter does not exist.
1607	 */
1608	WARN_ON(prestera_mdb_enable_set(br_mdb, br_dev->multicast_enabled &&
1609					br_dev->mrouter_exist));
1610
1611	err = prestera_br_mdb_port_add(br_mdb, br_port);
1612	if (err) {
1613		prestera_br_mdb_entry_put(br_mdb);
1614		return err;
1615	}
1616
1617	err = prestera_br_mdb_sync(br_dev);
1618	if (err)
1619		return err;
1620
1621	return 0;
1622}
1623
1624static int prestera_port_obj_add(struct net_device *dev, const void *ctx,
1625				 const struct switchdev_obj *obj,
1626				 struct netlink_ext_ack *extack)
1627{
1628	struct prestera_port *port = netdev_priv(dev);
1629	const struct switchdev_obj_port_vlan *vlan;
1630	const struct switchdev_obj_port_mdb *mdb;
1631	int err = 0;
1632
1633	switch (obj->id) {
1634	case SWITCHDEV_OBJ_ID_PORT_VLAN:
1635		vlan = SWITCHDEV_OBJ_PORT_VLAN(obj);
1636		return prestera_port_vlans_add(port, vlan, extack);
1637	case SWITCHDEV_OBJ_ID_PORT_MDB:
1638		mdb = SWITCHDEV_OBJ_PORT_MDB(obj);
1639		err = prestera_mdb_port_addr_obj_add(mdb);
1640		break;
1641	case SWITCHDEV_OBJ_ID_HOST_MDB:
1642		fallthrough;
1643	default:
1644		err = -EOPNOTSUPP;
1645		break;
1646	}
1647
1648	return err;
1649}
1650
1651static int prestera_port_vlans_del(struct prestera_port *port,
1652				   const struct switchdev_obj_port_vlan *vlan)
1653{
1654	struct net_device *orig_dev = vlan->obj.orig_dev;
1655	struct prestera_bridge_port *br_port;
1656	struct prestera_switch *sw = port->sw;
1657
1658	if (netif_is_bridge_master(orig_dev))
1659		return -EOPNOTSUPP;
1660
1661	br_port = prestera_bridge_port_by_dev(sw->swdev, port->dev);
1662	if (WARN_ON(!br_port))
1663		return -EINVAL;
1664
1665	if (!br_port->bridge->vlan_enabled)
1666		return 0;
1667
1668	prestera_bridge_port_vlan_del(port, br_port, vlan->vid);
1669
1670	return 0;
1671}
1672
1673static int
1674prestera_mdb_port_addr_obj_del(struct prestera_port *port,
1675			       const struct switchdev_obj_port_mdb *mdb)
1676{
1677	struct prestera_br_mdb_entry *br_mdb;
1678	struct prestera_bridge_port *br_port;
1679	struct prestera_bridge *br_dev;
1680	int err;
1681
1682	/* Bridge port no longer exists - and so does this MDB entry */
1683	br_port = prestera_bridge_port_find(port->sw, mdb->obj.orig_dev);
1684	if (!br_port)
1685		return 0;
1686
1687	/* Removing MDB with non-existing VLAN - not supported; */
1688	if (mdb->vid && !prestera_port_vlan_by_vid(port, mdb->vid))
1689		return 0;
1690
1691	br_dev = br_port->bridge;
1692
1693	if (br_port->bridge->vlan_enabled)
1694		br_mdb = prestera_br_mdb_entry_find(br_dev, &mdb->addr[0],
1695						    mdb->vid);
1696	else
1697		br_mdb = prestera_br_mdb_entry_find(br_dev, &mdb->addr[0],
1698						    br_port->bridge->bridge_id);
1699
1700	if (!br_mdb)
1701		return 0;
1702
1703	/* Since there might be a situation that this port was the last in the
1704	 * MDB group, we have to both remove this port from software and HW MDB,
1705	 * sync MDB table, and then destroy software MDB (if needed).
1706	 */
1707	prestera_br_mdb_port_del(br_mdb, br_port);
1708
1709	prestera_br_mdb_entry_put(br_mdb);
1710
1711	err = prestera_br_mdb_sync(br_dev);
1712	if (err)
1713		return err;
1714
1715	return 0;
1716}
1717
1718static int prestera_port_obj_del(struct net_device *dev, const void *ctx,
1719				 const struct switchdev_obj *obj)
1720{
1721	struct prestera_port *port = netdev_priv(dev);
1722	const struct switchdev_obj_port_mdb *mdb;
1723	int err = 0;
1724
1725	switch (obj->id) {
1726	case SWITCHDEV_OBJ_ID_PORT_VLAN:
1727		return prestera_port_vlans_del(port, SWITCHDEV_OBJ_PORT_VLAN(obj));
1728	case SWITCHDEV_OBJ_ID_PORT_MDB:
1729		mdb = SWITCHDEV_OBJ_PORT_MDB(obj);
1730		err = prestera_mdb_port_addr_obj_del(port, mdb);
1731		break;
1732	default:
1733		err = -EOPNOTSUPP;
1734		break;
1735	}
1736
1737	return err;
1738}
1739
1740static int prestera_switchdev_blk_event(struct notifier_block *unused,
1741					unsigned long event, void *ptr)
1742{
1743	struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
1744	int err;
1745
1746	switch (event) {
1747	case SWITCHDEV_PORT_OBJ_ADD:
1748		err = switchdev_handle_port_obj_add(dev, ptr,
1749						    prestera_netdev_check,
1750						    prestera_port_obj_add);
1751		break;
1752	case SWITCHDEV_PORT_OBJ_DEL:
1753		err = switchdev_handle_port_obj_del(dev, ptr,
1754						    prestera_netdev_check,
1755						    prestera_port_obj_del);
1756		break;
1757	case SWITCHDEV_PORT_ATTR_SET:
1758		err = switchdev_handle_port_attr_set(dev, ptr,
1759						     prestera_netdev_check,
1760						     prestera_port_obj_attr_set);
1761		break;
1762	default:
1763		return NOTIFY_DONE;
1764	}
1765
1766	return notifier_from_errno(err);
1767}
1768
1769static void prestera_fdb_event(struct prestera_switch *sw,
1770			       struct prestera_event *evt, void *arg)
1771{
1772	struct switchdev_notifier_fdb_info info = {};
1773	struct net_device *dev = NULL;
1774	struct prestera_port *port;
1775	struct prestera_lag *lag;
1776
1777	switch (evt->fdb_evt.type) {
1778	case PRESTERA_FDB_ENTRY_TYPE_REG_PORT:
1779		port = prestera_find_port(sw, evt->fdb_evt.dest.port_id);
1780		if (port)
1781			dev = port->dev;
1782		break;
1783	case PRESTERA_FDB_ENTRY_TYPE_LAG:
1784		lag = prestera_lag_by_id(sw, evt->fdb_evt.dest.lag_id);
1785		if (lag)
1786			dev = lag->dev;
1787		break;
1788	default:
1789		return;
1790	}
1791
1792	if (!dev)
1793		return;
1794
1795	info.addr = evt->fdb_evt.data.mac;
1796	info.vid = evt->fdb_evt.vid;
1797	info.offloaded = true;
1798
1799	rtnl_lock();
1800
1801	switch (evt->id) {
1802	case PRESTERA_FDB_EVENT_LEARNED:
1803		call_switchdev_notifiers(SWITCHDEV_FDB_ADD_TO_BRIDGE,
1804					 dev, &info.info, NULL);
1805		break;
1806	case PRESTERA_FDB_EVENT_AGED:
1807		call_switchdev_notifiers(SWITCHDEV_FDB_DEL_TO_BRIDGE,
1808					 dev, &info.info, NULL);
1809		break;
1810	}
1811
1812	rtnl_unlock();
1813}
1814
1815static int prestera_fdb_init(struct prestera_switch *sw)
1816{
1817	int err;
1818
1819	err = prestera_hw_event_handler_register(sw, PRESTERA_EVENT_TYPE_FDB,
1820						 prestera_fdb_event, NULL);
1821	if (err)
1822		return err;
1823
1824	err = prestera_hw_switch_ageing_set(sw, PRESTERA_DEFAULT_AGEING_TIME_MS);
1825	if (err)
1826		goto err_ageing_set;
1827
1828	return 0;
1829
1830err_ageing_set:
1831	prestera_hw_event_handler_unregister(sw, PRESTERA_EVENT_TYPE_FDB,
1832					     prestera_fdb_event);
1833	return err;
1834}
1835
1836static void prestera_fdb_fini(struct prestera_switch *sw)
1837{
1838	prestera_hw_event_handler_unregister(sw, PRESTERA_EVENT_TYPE_FDB,
1839					     prestera_fdb_event);
1840}
1841
1842static int prestera_switchdev_handler_init(struct prestera_switchdev *swdev)
1843{
1844	int err;
1845
1846	swdev->swdev_nb.notifier_call = prestera_switchdev_event;
1847	err = register_switchdev_notifier(&swdev->swdev_nb);
1848	if (err)
1849		goto err_register_swdev_notifier;
1850
1851	swdev->swdev_nb_blk.notifier_call = prestera_switchdev_blk_event;
1852	err = register_switchdev_blocking_notifier(&swdev->swdev_nb_blk);
1853	if (err)
1854		goto err_register_blk_swdev_notifier;
1855
1856	return 0;
1857
1858err_register_blk_swdev_notifier:
1859	unregister_switchdev_notifier(&swdev->swdev_nb);
1860err_register_swdev_notifier:
1861	destroy_workqueue(swdev_wq);
1862	return err;
1863}
1864
1865static void prestera_switchdev_handler_fini(struct prestera_switchdev *swdev)
1866{
1867	unregister_switchdev_blocking_notifier(&swdev->swdev_nb_blk);
1868	unregister_switchdev_notifier(&swdev->swdev_nb);
1869}
1870
1871int prestera_switchdev_init(struct prestera_switch *sw)
1872{
1873	struct prestera_switchdev *swdev;
1874	int err;
1875
1876	swdev = kzalloc(sizeof(*swdev), GFP_KERNEL);
1877	if (!swdev)
1878		return -ENOMEM;
1879
1880	sw->swdev = swdev;
1881	swdev->sw = sw;
1882
1883	INIT_LIST_HEAD(&swdev->bridge_list);
1884
1885	swdev_wq = alloc_ordered_workqueue("%s_ordered", 0, "prestera_br");
1886	if (!swdev_wq) {
1887		err = -ENOMEM;
1888		goto err_alloc_wq;
1889	}
1890
1891	err = prestera_switchdev_handler_init(swdev);
1892	if (err)
1893		goto err_swdev_init;
1894
1895	err = prestera_fdb_init(sw);
1896	if (err)
1897		goto err_fdb_init;
1898
1899	return 0;
1900
1901err_fdb_init:
1902err_swdev_init:
1903	destroy_workqueue(swdev_wq);
1904err_alloc_wq:
1905	kfree(swdev);
1906
1907	return err;
1908}
1909
1910void prestera_switchdev_fini(struct prestera_switch *sw)
1911{
1912	struct prestera_switchdev *swdev = sw->swdev;
1913
1914	prestera_fdb_fini(sw);
1915	prestera_switchdev_handler_fini(swdev);
1916	destroy_workqueue(swdev_wq);
1917	kfree(swdev);
1918}