mirror of
https://github.com/torvalds/linux.git
synced 2026-05-24 23:22:31 +02:00
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: Yevhen Orlov <yevhen.orlov@plvision.eu> Signed-off-by: Yevhen Orlov <yevhen.orlov@plvision.eu> Signed-off-by: Oleksandr Mazur <oleksandr.mazur@plvision.eu> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
fec7c9c73f
commit
7950b214a1
|
|
@ -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);
|
||||
|
||||
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_ */
|
||||
|
|
|
|||
|
|
@ -915,6 +915,150 @@ static int prestera_netdev_event_handler(struct notifier_block *nb,
|
|||
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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user