u16 prestera_port_lag_id(const struct prestera_port *port);
 
+struct prestera_mdb_entry *
+prestera_mdb_entry_create(struct prestera_switch *sw,
+                         const unsigned char *addr, u16 vid);
+void prestera_mdb_entry_destroy(struct prestera_mdb_entry *mdb_entry);
+
+struct prestera_flood_domain *
+prestera_flood_domain_create(struct prestera_switch *sw);
+void prestera_flood_domain_destroy(struct prestera_flood_domain *flood_domain);
+
+int
+prestera_flood_domain_port_create(struct prestera_flood_domain *flood_domain,
+                                 struct net_device *dev,
+                                 u16 vid);
+void
+prestera_flood_domain_port_destroy(struct prestera_flood_domain_port *port);
+struct prestera_flood_domain_port *
+prestera_flood_domain_port_find(struct prestera_flood_domain *flood_domain,
+                               struct net_device *dev, u16 vid);
+
 #endif /* _PRESTERA_H_ */
 
        return notifier_from_errno(err);
 }
 
+struct prestera_mdb_entry *
+prestera_mdb_entry_create(struct prestera_switch *sw,
+                         const unsigned char *addr, u16 vid)
+{
+       struct prestera_flood_domain *flood_domain;
+       struct prestera_mdb_entry *mdb_entry;
+
+       mdb_entry = kzalloc(sizeof(*mdb_entry), GFP_KERNEL);
+       if (!mdb_entry)
+               goto err_mdb_alloc;
+
+       flood_domain = prestera_flood_domain_create(sw);
+       if (!flood_domain)
+               goto err_flood_domain_create;
+
+       mdb_entry->sw = sw;
+       mdb_entry->vid = vid;
+       mdb_entry->flood_domain = flood_domain;
+       ether_addr_copy(mdb_entry->addr, addr);
+
+       if (prestera_hw_mdb_create(mdb_entry))
+               goto err_mdb_hw_create;
+
+       return mdb_entry;
+
+err_mdb_hw_create:
+       prestera_flood_domain_destroy(flood_domain);
+err_flood_domain_create:
+       kfree(mdb_entry);
+err_mdb_alloc:
+       return NULL;
+}
+
+void prestera_mdb_entry_destroy(struct prestera_mdb_entry *mdb_entry)
+{
+       prestera_hw_mdb_destroy(mdb_entry);
+       prestera_flood_domain_destroy(mdb_entry->flood_domain);
+       kfree(mdb_entry);
+}
+
+struct prestera_flood_domain *
+prestera_flood_domain_create(struct prestera_switch *sw)
+{
+       struct prestera_flood_domain *domain;
+
+       domain = kzalloc(sizeof(*domain), GFP_KERNEL);
+       if (!domain)
+               return NULL;
+
+       domain->sw = sw;
+
+       if (prestera_hw_flood_domain_create(domain)) {
+               kfree(domain);
+               return NULL;
+       }
+
+       INIT_LIST_HEAD(&domain->flood_domain_port_list);
+
+       return domain;
+}
+
+void prestera_flood_domain_destroy(struct prestera_flood_domain *flood_domain)
+{
+       WARN_ON(!list_empty(&flood_domain->flood_domain_port_list));
+       WARN_ON_ONCE(prestera_hw_flood_domain_destroy(flood_domain));
+       kfree(flood_domain);
+}
+
+int
+prestera_flood_domain_port_create(struct prestera_flood_domain *flood_domain,
+                                 struct net_device *dev,
+                                 u16 vid)
+{
+       struct prestera_flood_domain_port *flood_domain_port;
+       bool is_first_port_in_list = false;
+       int err;
+
+       flood_domain_port = kzalloc(sizeof(*flood_domain_port), GFP_KERNEL);
+       if (!flood_domain_port) {
+               err = -ENOMEM;
+               goto err_port_alloc;
+       }
+
+       flood_domain_port->vid = vid;
+
+       if (list_empty(&flood_domain->flood_domain_port_list))
+               is_first_port_in_list = true;
+
+       list_add(&flood_domain_port->flood_domain_port_node,
+                &flood_domain->flood_domain_port_list);
+
+       flood_domain_port->flood_domain = flood_domain;
+       flood_domain_port->dev = dev;
+
+       if (!is_first_port_in_list) {
+               err = prestera_hw_flood_domain_ports_reset(flood_domain);
+               if (err)
+                       goto err_prestera_mdb_port_create_hw;
+       }
+
+       err = prestera_hw_flood_domain_ports_set(flood_domain);
+       if (err)
+               goto err_prestera_mdb_port_create_hw;
+
+       return 0;
+
+err_prestera_mdb_port_create_hw:
+       list_del(&flood_domain_port->flood_domain_port_node);
+       kfree(flood_domain_port);
+err_port_alloc:
+       return err;
+}
+
+void
+prestera_flood_domain_port_destroy(struct prestera_flood_domain_port *port)
+{
+       struct prestera_flood_domain *flood_domain = port->flood_domain;
+
+       list_del(&port->flood_domain_port_node);
+
+       WARN_ON_ONCE(prestera_hw_flood_domain_ports_reset(flood_domain));
+
+       if (!list_empty(&flood_domain->flood_domain_port_list))
+               WARN_ON_ONCE(prestera_hw_flood_domain_ports_set(flood_domain));
+
+       kfree(port);
+}
+
+struct prestera_flood_domain_port *
+prestera_flood_domain_port_find(struct prestera_flood_domain *flood_domain,
+                               struct net_device *dev, u16 vid)
+{
+       struct prestera_flood_domain_port *flood_domain_port;
+
+       list_for_each_entry(flood_domain_port,
+                           &flood_domain->flood_domain_port_list,
+                           flood_domain_port_node)
+               if (flood_domain_port->dev == dev &&
+                   vid == flood_domain_port->vid)
+                       return flood_domain_port;
+
+       return NULL;
+}
+
 static int prestera_netdev_event_handler_register(struct prestera_switch *sw)
 {
        sw->netdev_nb.notifier_call = prestera_netdev_event_handler;