mlxsw: spectrum_span: Remove old SPAN API
Remove the old SPAN API now that matchall-based and flower-based mirroring were converted to use the new API. Signed-off-by: Ido Schimmel <idosch@mellanox.com> Reviewed-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
835d6b8c1a
commit
ca0892235a
|
@ -74,12 +74,8 @@ int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp)
|
||||||
span->mlxsw_sp = mlxsw_sp;
|
span->mlxsw_sp = mlxsw_sp;
|
||||||
mlxsw_sp->span = span;
|
mlxsw_sp->span = span;
|
||||||
|
|
||||||
for (i = 0; i < mlxsw_sp->span->entries_count; i++) {
|
for (i = 0; i < mlxsw_sp->span->entries_count; i++)
|
||||||
struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span->entries[i];
|
mlxsw_sp->span->entries[i].id = i;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&curr->bound_ports_list);
|
|
||||||
curr->id = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
devlink_resource_occ_get_register(devlink, MLXSW_SP_RESOURCE_SPAN,
|
devlink_resource_occ_get_register(devlink, MLXSW_SP_RESOURCE_SPAN,
|
||||||
mlxsw_sp_span_occ_get, mlxsw_sp);
|
mlxsw_sp_span_occ_get, mlxsw_sp);
|
||||||
|
@ -91,16 +87,10 @@ int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp)
|
||||||
void mlxsw_sp_span_fini(struct mlxsw_sp *mlxsw_sp)
|
void mlxsw_sp_span_fini(struct mlxsw_sp *mlxsw_sp)
|
||||||
{
|
{
|
||||||
struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
|
struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
|
||||||
int i;
|
|
||||||
|
|
||||||
cancel_work_sync(&mlxsw_sp->span->work);
|
cancel_work_sync(&mlxsw_sp->span->work);
|
||||||
devlink_resource_occ_get_unregister(devlink, MLXSW_SP_RESOURCE_SPAN);
|
devlink_resource_occ_get_unregister(devlink, MLXSW_SP_RESOURCE_SPAN);
|
||||||
|
|
||||||
for (i = 0; i < mlxsw_sp->span->entries_count; i++) {
|
|
||||||
struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span->entries[i];
|
|
||||||
|
|
||||||
WARN_ON_ONCE(!list_empty(&curr->bound_ports_list));
|
|
||||||
}
|
|
||||||
WARN_ON_ONCE(!list_empty(&mlxsw_sp->span->trigger_entries_list));
|
WARN_ON_ONCE(!list_empty(&mlxsw_sp->span->trigger_entries_list));
|
||||||
WARN_ON_ONCE(!list_empty(&mlxsw_sp->span->analyzed_ports_list));
|
WARN_ON_ONCE(!list_empty(&mlxsw_sp->span->analyzed_ports_list));
|
||||||
mutex_destroy(&mlxsw_sp->span->analyzed_ports_lock);
|
mutex_destroy(&mlxsw_sp->span->analyzed_ports_lock);
|
||||||
|
@ -862,131 +852,6 @@ void mlxsw_sp_span_speed_update_work(struct work_struct *work)
|
||||||
mutex_unlock(&mlxsw_sp->span->analyzed_ports_lock);
|
mutex_unlock(&mlxsw_sp->span->analyzed_ports_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct mlxsw_sp_span_inspected_port *
|
|
||||||
mlxsw_sp_span_entry_bound_port_find(struct mlxsw_sp_span_entry *span_entry,
|
|
||||||
enum mlxsw_sp_span_type type,
|
|
||||||
struct mlxsw_sp_port *port,
|
|
||||||
bool bind)
|
|
||||||
{
|
|
||||||
struct mlxsw_sp_span_inspected_port *p;
|
|
||||||
|
|
||||||
list_for_each_entry(p, &span_entry->bound_ports_list, list)
|
|
||||||
if (type == p->type &&
|
|
||||||
port->local_port == p->local_port &&
|
|
||||||
bind == p->bound)
|
|
||||||
return p;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
mlxsw_sp_span_inspected_port_bind(struct mlxsw_sp_port *port,
|
|
||||||
struct mlxsw_sp_span_entry *span_entry,
|
|
||||||
enum mlxsw_sp_span_type type,
|
|
||||||
bool bind)
|
|
||||||
{
|
|
||||||
struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
|
|
||||||
char mpar_pl[MLXSW_REG_MPAR_LEN];
|
|
||||||
int pa_id = span_entry->id;
|
|
||||||
|
|
||||||
/* bind the port to the SPAN entry */
|
|
||||||
mlxsw_reg_mpar_pack(mpar_pl, port->local_port,
|
|
||||||
(enum mlxsw_reg_mpar_i_e)type, bind, pa_id);
|
|
||||||
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpar), mpar_pl);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
mlxsw_sp_span_inspected_port_add(struct mlxsw_sp_port *port,
|
|
||||||
struct mlxsw_sp_span_entry *span_entry,
|
|
||||||
enum mlxsw_sp_span_type type,
|
|
||||||
bool bind)
|
|
||||||
{
|
|
||||||
struct mlxsw_sp_span_inspected_port *inspected_port;
|
|
||||||
struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
|
|
||||||
char sbib_pl[MLXSW_REG_SBIB_LEN];
|
|
||||||
int i;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
/* A given (source port, direction) can only be bound to one analyzer,
|
|
||||||
* so if a binding is requested, check for conflicts.
|
|
||||||
*/
|
|
||||||
if (bind)
|
|
||||||
for (i = 0; i < mlxsw_sp->span->entries_count; i++) {
|
|
||||||
struct mlxsw_sp_span_entry *curr =
|
|
||||||
&mlxsw_sp->span->entries[i];
|
|
||||||
|
|
||||||
if (mlxsw_sp_span_entry_bound_port_find(curr, type,
|
|
||||||
port, bind))
|
|
||||||
return -EEXIST;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if it is an egress SPAN, bind a shared buffer to it */
|
|
||||||
if (type == MLXSW_SP_SPAN_EGRESS) {
|
|
||||||
err = mlxsw_sp_span_port_buffer_update(port, port->dev->mtu);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bind) {
|
|
||||||
err = mlxsw_sp_span_inspected_port_bind(port, span_entry, type,
|
|
||||||
true);
|
|
||||||
if (err)
|
|
||||||
goto err_port_bind;
|
|
||||||
}
|
|
||||||
|
|
||||||
inspected_port = kzalloc(sizeof(*inspected_port), GFP_KERNEL);
|
|
||||||
if (!inspected_port) {
|
|
||||||
err = -ENOMEM;
|
|
||||||
goto err_inspected_port_alloc;
|
|
||||||
}
|
|
||||||
inspected_port->local_port = port->local_port;
|
|
||||||
inspected_port->type = type;
|
|
||||||
inspected_port->bound = bind;
|
|
||||||
list_add_tail(&inspected_port->list, &span_entry->bound_ports_list);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err_inspected_port_alloc:
|
|
||||||
if (bind)
|
|
||||||
mlxsw_sp_span_inspected_port_bind(port, span_entry, type,
|
|
||||||
false);
|
|
||||||
err_port_bind:
|
|
||||||
if (type == MLXSW_SP_SPAN_EGRESS) {
|
|
||||||
mlxsw_reg_sbib_pack(sbib_pl, port->local_port, 0);
|
|
||||||
mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
mlxsw_sp_span_inspected_port_del(struct mlxsw_sp_port *port,
|
|
||||||
struct mlxsw_sp_span_entry *span_entry,
|
|
||||||
enum mlxsw_sp_span_type type,
|
|
||||||
bool bind)
|
|
||||||
{
|
|
||||||
struct mlxsw_sp_span_inspected_port *inspected_port;
|
|
||||||
struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
|
|
||||||
char sbib_pl[MLXSW_REG_SBIB_LEN];
|
|
||||||
|
|
||||||
inspected_port = mlxsw_sp_span_entry_bound_port_find(span_entry, type,
|
|
||||||
port, bind);
|
|
||||||
if (!inspected_port)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (bind)
|
|
||||||
mlxsw_sp_span_inspected_port_bind(port, span_entry, type,
|
|
||||||
false);
|
|
||||||
/* remove the SBIB buffer if it was egress SPAN */
|
|
||||||
if (type == MLXSW_SP_SPAN_EGRESS) {
|
|
||||||
mlxsw_reg_sbib_pack(sbib_pl, port->local_port, 0);
|
|
||||||
mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
|
|
||||||
}
|
|
||||||
|
|
||||||
mlxsw_sp_span_entry_put(mlxsw_sp, span_entry);
|
|
||||||
|
|
||||||
list_del(&inspected_port->list);
|
|
||||||
kfree(inspected_port);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct mlxsw_sp_span_entry_ops *
|
static const struct mlxsw_sp_span_entry_ops *
|
||||||
mlxsw_sp_span_entry_ops(struct mlxsw_sp *mlxsw_sp,
|
mlxsw_sp_span_entry_ops(struct mlxsw_sp *mlxsw_sp,
|
||||||
const struct net_device *to_dev)
|
const struct net_device *to_dev)
|
||||||
|
@ -1000,57 +865,6 @@ mlxsw_sp_span_entry_ops(struct mlxsw_sp *mlxsw_sp,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mlxsw_sp_span_mirror_add(struct mlxsw_sp_port *from,
|
|
||||||
const struct net_device *to_dev,
|
|
||||||
enum mlxsw_sp_span_type type, bool bind,
|
|
||||||
int *p_span_id)
|
|
||||||
{
|
|
||||||
struct mlxsw_sp *mlxsw_sp = from->mlxsw_sp;
|
|
||||||
const struct mlxsw_sp_span_entry_ops *ops;
|
|
||||||
struct mlxsw_sp_span_parms sparms = {NULL};
|
|
||||||
struct mlxsw_sp_span_entry *span_entry;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
ops = mlxsw_sp_span_entry_ops(mlxsw_sp, to_dev);
|
|
||||||
if (!ops) {
|
|
||||||
netdev_err(to_dev, "Cannot mirror to %s", to_dev->name);
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ops->parms_set(to_dev, &sparms);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
span_entry = mlxsw_sp_span_entry_get(mlxsw_sp, to_dev, ops, sparms);
|
|
||||||
if (!span_entry)
|
|
||||||
return -ENOBUFS;
|
|
||||||
|
|
||||||
err = mlxsw_sp_span_inspected_port_add(from, span_entry, type, bind);
|
|
||||||
if (err)
|
|
||||||
goto err_port_bind;
|
|
||||||
|
|
||||||
*p_span_id = span_entry->id;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err_port_bind:
|
|
||||||
mlxsw_sp_span_entry_put(mlxsw_sp, span_entry);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mlxsw_sp_span_mirror_del(struct mlxsw_sp_port *from, int span_id,
|
|
||||||
enum mlxsw_sp_span_type type, bool bind)
|
|
||||||
{
|
|
||||||
struct mlxsw_sp_span_entry *span_entry;
|
|
||||||
|
|
||||||
span_entry = mlxsw_sp_span_entry_find_by_id(from->mlxsw_sp, span_id);
|
|
||||||
if (!span_entry) {
|
|
||||||
netdev_err(from->dev, "no span entry found\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mlxsw_sp_span_inspected_port_del(from, span_entry, type, bind);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mlxsw_sp_span_respin_work(struct work_struct *work)
|
static void mlxsw_sp_span_respin_work(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct mlxsw_sp_span *span;
|
struct mlxsw_sp_span *span;
|
||||||
|
|
|
@ -13,20 +13,6 @@
|
||||||
struct mlxsw_sp;
|
struct mlxsw_sp;
|
||||||
struct mlxsw_sp_port;
|
struct mlxsw_sp_port;
|
||||||
|
|
||||||
enum mlxsw_sp_span_type {
|
|
||||||
MLXSW_SP_SPAN_EGRESS,
|
|
||||||
MLXSW_SP_SPAN_INGRESS
|
|
||||||
};
|
|
||||||
|
|
||||||
struct mlxsw_sp_span_inspected_port {
|
|
||||||
struct list_head list;
|
|
||||||
enum mlxsw_sp_span_type type;
|
|
||||||
u8 local_port;
|
|
||||||
|
|
||||||
/* Whether this is a directly bound mirror (port-to-port) or an ACL. */
|
|
||||||
bool bound;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct mlxsw_sp_span_parms {
|
struct mlxsw_sp_span_parms {
|
||||||
struct mlxsw_sp_port *dest_port; /* NULL for unoffloaded SPAN. */
|
struct mlxsw_sp_port *dest_port; /* NULL for unoffloaded SPAN. */
|
||||||
unsigned int ttl;
|
unsigned int ttl;
|
||||||
|
@ -52,7 +38,6 @@ struct mlxsw_sp_span_entry {
|
||||||
const struct net_device *to_dev;
|
const struct net_device *to_dev;
|
||||||
const struct mlxsw_sp_span_entry_ops *ops;
|
const struct mlxsw_sp_span_entry_ops *ops;
|
||||||
struct mlxsw_sp_span_parms parms;
|
struct mlxsw_sp_span_parms parms;
|
||||||
struct list_head bound_ports_list;
|
|
||||||
refcount_t ref_count;
|
refcount_t ref_count;
|
||||||
int id;
|
int id;
|
||||||
};
|
};
|
||||||
|
@ -70,12 +55,6 @@ int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp);
|
||||||
void mlxsw_sp_span_fini(struct mlxsw_sp *mlxsw_sp);
|
void mlxsw_sp_span_fini(struct mlxsw_sp *mlxsw_sp);
|
||||||
void mlxsw_sp_span_respin(struct mlxsw_sp *mlxsw_sp);
|
void mlxsw_sp_span_respin(struct mlxsw_sp *mlxsw_sp);
|
||||||
|
|
||||||
int mlxsw_sp_span_mirror_add(struct mlxsw_sp_port *from,
|
|
||||||
const struct net_device *to_dev,
|
|
||||||
enum mlxsw_sp_span_type type,
|
|
||||||
bool bind, int *p_span_id);
|
|
||||||
void mlxsw_sp_span_mirror_del(struct mlxsw_sp_port *from, int span_id,
|
|
||||||
enum mlxsw_sp_span_type type, bool bind);
|
|
||||||
struct mlxsw_sp_span_entry *
|
struct mlxsw_sp_span_entry *
|
||||||
mlxsw_sp_span_entry_find_by_port(struct mlxsw_sp *mlxsw_sp,
|
mlxsw_sp_span_entry_find_by_port(struct mlxsw_sp *mlxsw_sp,
|
||||||
const struct net_device *to_dev);
|
const struct net_device *to_dev);
|
||||||
|
|
Loading…
Reference in New Issue