Commit 7950b214 authored by Oleksandr Mazur's avatar Oleksandr Mazur Committed by David S. Miller

net: marvell: prestera: define and implement MDB / flood domain API for...

net: marvell: prestera: define and implement MDB / flood domain API for entries creation and deletion

Define and implement prestera API calls for managing MDB and
  flood domain (ports) entries (create / delete / find calls).
Co-developed-by: default avatarYevhen Orlov <yevhen.orlov@plvision.eu>
Signed-off-by: default avatarYevhen Orlov <yevhen.orlov@plvision.eu>
Signed-off-by: default avatarOleksandr Mazur <oleksandr.mazur@plvision.eu>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent fec7c9c7
...@@ -369,4 +369,23 @@ struct prestera_lag *prestera_lag_by_id(struct prestera_switch *sw, u16 id); ...@@ -369,4 +369,23 @@ struct prestera_lag *prestera_lag_by_id(struct prestera_switch *sw, u16 id);
u16 prestera_port_lag_id(const struct prestera_port *port); 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_ */ #endif /* _PRESTERA_H_ */
...@@ -915,6 +915,150 @@ static int prestera_netdev_event_handler(struct notifier_block *nb, ...@@ -915,6 +915,150 @@ static int prestera_netdev_event_handler(struct notifier_block *nb,
return notifier_from_errno(err); 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) static int prestera_netdev_event_handler_register(struct prestera_switch *sw)
{ {
sw->netdev_nb.notifier_call = prestera_netdev_event_handler; sw->netdev_nb.notifier_call = prestera_netdev_event_handler;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment