Commit 5c8d39c9 authored by Arkadi Sharshevsky's avatar Arkadi Sharshevsky Committed by David S. Miller

mlxsw: spectrum: Extend and export SPAN API

Extend SPAN API for ACL case. In case of ACL triggering the MPAR register
shouldn't be configured. This patch also export those helpers for
ACL usage.
Signed-off-by: default avatarArkadi Sharshevsky <arkadis@mellanox.com>
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent db0553b2
...@@ -568,7 +568,7 @@ static void mlxsw_sp_span_entry_destroy(struct mlxsw_sp *mlxsw_sp, ...@@ -568,7 +568,7 @@ static void mlxsw_sp_span_entry_destroy(struct mlxsw_sp *mlxsw_sp,
span_entry->used = false; span_entry->used = false;
} }
static struct mlxsw_sp_span_entry * struct mlxsw_sp_span_entry *
mlxsw_sp_span_entry_find(struct mlxsw_sp *mlxsw_sp, u8 local_port) mlxsw_sp_span_entry_find(struct mlxsw_sp *mlxsw_sp, u8 local_port)
{ {
int i; int i;
...@@ -669,13 +669,28 @@ mlxsw_sp_span_entry_bound_port_find(struct mlxsw_sp_port *port, ...@@ -669,13 +669,28 @@ mlxsw_sp_span_entry_bound_port_find(struct mlxsw_sp_port *port,
static int static int
mlxsw_sp_span_inspected_port_bind(struct mlxsw_sp_port *port, mlxsw_sp_span_inspected_port_bind(struct mlxsw_sp_port *port,
struct mlxsw_sp_span_entry *span_entry, struct mlxsw_sp_span_entry *span_entry,
enum mlxsw_sp_span_type type) enum mlxsw_sp_span_type type,
bool bind)
{ {
struct mlxsw_sp_span_inspected_port *inspected_port;
struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp; struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
char mpar_pl[MLXSW_REG_MPAR_LEN]; char mpar_pl[MLXSW_REG_MPAR_LEN];
char sbib_pl[MLXSW_REG_SBIB_LEN];
int pa_id = span_entry->id; 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 err; int err;
/* if it is an egress SPAN, bind a shared buffer to it */ /* if it is an egress SPAN, bind a shared buffer to it */
...@@ -691,12 +706,12 @@ mlxsw_sp_span_inspected_port_bind(struct mlxsw_sp_port *port, ...@@ -691,12 +706,12 @@ mlxsw_sp_span_inspected_port_bind(struct mlxsw_sp_port *port,
} }
} }
/* bind the port to the SPAN entry */ if (bind) {
mlxsw_reg_mpar_pack(mpar_pl, port->local_port, err = mlxsw_sp_span_inspected_port_bind(port, span_entry, type,
(enum mlxsw_reg_mpar_i_e) type, true, pa_id); true);
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpar), mpar_pl); if (err)
if (err) goto err_port_bind;
goto err_mpar_reg_write; }
inspected_port = kzalloc(sizeof(*inspected_port), GFP_KERNEL); inspected_port = kzalloc(sizeof(*inspected_port), GFP_KERNEL);
if (!inspected_port) { if (!inspected_port) {
...@@ -709,8 +724,11 @@ mlxsw_sp_span_inspected_port_bind(struct mlxsw_sp_port *port, ...@@ -709,8 +724,11 @@ mlxsw_sp_span_inspected_port_bind(struct mlxsw_sp_port *port,
return 0; return 0;
err_mpar_reg_write:
err_inspected_port_alloc: 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) { if (type == MLXSW_SP_SPAN_EGRESS) {
mlxsw_reg_sbib_pack(sbib_pl, port->local_port, 0); mlxsw_reg_sbib_pack(sbib_pl, port->local_port, 0);
mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl); mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
...@@ -719,25 +737,22 @@ mlxsw_sp_span_inspected_port_bind(struct mlxsw_sp_port *port, ...@@ -719,25 +737,22 @@ mlxsw_sp_span_inspected_port_bind(struct mlxsw_sp_port *port,
} }
static void static void
mlxsw_sp_span_inspected_port_unbind(struct mlxsw_sp_port *port, mlxsw_sp_span_inspected_port_del(struct mlxsw_sp_port *port,
struct mlxsw_sp_span_entry *span_entry, struct mlxsw_sp_span_entry *span_entry,
enum mlxsw_sp_span_type type) enum mlxsw_sp_span_type type,
bool bind)
{ {
struct mlxsw_sp_span_inspected_port *inspected_port; struct mlxsw_sp_span_inspected_port *inspected_port;
struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp; struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
char mpar_pl[MLXSW_REG_MPAR_LEN];
char sbib_pl[MLXSW_REG_SBIB_LEN]; char sbib_pl[MLXSW_REG_SBIB_LEN];
int pa_id = span_entry->id;
inspected_port = mlxsw_sp_span_entry_bound_port_find(port, span_entry); inspected_port = mlxsw_sp_span_entry_bound_port_find(port, span_entry);
if (!inspected_port) if (!inspected_port)
return; return;
/* remove the inspected port */ if (bind)
mlxsw_reg_mpar_pack(mpar_pl, port->local_port, mlxsw_sp_span_inspected_port_bind(port, span_entry, type,
(enum mlxsw_reg_mpar_i_e) type, false, pa_id); false);
mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpar), mpar_pl);
/* remove the SBIB buffer if it was egress SPAN */ /* remove the SBIB buffer if it was egress SPAN */
if (type == MLXSW_SP_SPAN_EGRESS) { if (type == MLXSW_SP_SPAN_EGRESS) {
mlxsw_reg_sbib_pack(sbib_pl, port->local_port, 0); mlxsw_reg_sbib_pack(sbib_pl, port->local_port, 0);
...@@ -750,9 +765,9 @@ mlxsw_sp_span_inspected_port_unbind(struct mlxsw_sp_port *port, ...@@ -750,9 +765,9 @@ mlxsw_sp_span_inspected_port_unbind(struct mlxsw_sp_port *port,
kfree(inspected_port); kfree(inspected_port);
} }
static int mlxsw_sp_span_mirror_add(struct mlxsw_sp_port *from, int mlxsw_sp_span_mirror_add(struct mlxsw_sp_port *from,
struct mlxsw_sp_port *to, struct mlxsw_sp_port *to,
enum mlxsw_sp_span_type type) enum mlxsw_sp_span_type type, bool bind)
{ {
struct mlxsw_sp *mlxsw_sp = from->mlxsw_sp; struct mlxsw_sp *mlxsw_sp = from->mlxsw_sp;
struct mlxsw_sp_span_entry *span_entry; struct mlxsw_sp_span_entry *span_entry;
...@@ -765,7 +780,7 @@ static int mlxsw_sp_span_mirror_add(struct mlxsw_sp_port *from, ...@@ -765,7 +780,7 @@ static int mlxsw_sp_span_mirror_add(struct mlxsw_sp_port *from,
netdev_dbg(from->dev, "Adding inspected port to SPAN entry %d\n", netdev_dbg(from->dev, "Adding inspected port to SPAN entry %d\n",
span_entry->id); span_entry->id);
err = mlxsw_sp_span_inspected_port_bind(from, span_entry, type); err = mlxsw_sp_span_inspected_port_add(from, span_entry, type, bind);
if (err) if (err)
goto err_port_bind; goto err_port_bind;
...@@ -776,9 +791,8 @@ static int mlxsw_sp_span_mirror_add(struct mlxsw_sp_port *from, ...@@ -776,9 +791,8 @@ static int mlxsw_sp_span_mirror_add(struct mlxsw_sp_port *from,
return err; return err;
} }
static void mlxsw_sp_span_mirror_remove(struct mlxsw_sp_port *from, void mlxsw_sp_span_mirror_del(struct mlxsw_sp_port *from, u8 destination_port,
u8 destination_port, enum mlxsw_sp_span_type type, bool bind)
enum mlxsw_sp_span_type type)
{ {
struct mlxsw_sp_span_entry *span_entry; struct mlxsw_sp_span_entry *span_entry;
...@@ -791,7 +805,7 @@ static void mlxsw_sp_span_mirror_remove(struct mlxsw_sp_port *from, ...@@ -791,7 +805,7 @@ static void mlxsw_sp_span_mirror_remove(struct mlxsw_sp_port *from,
netdev_dbg(from->dev, "removing inspected port from SPAN entry %d\n", netdev_dbg(from->dev, "removing inspected port from SPAN entry %d\n",
span_entry->id); span_entry->id);
mlxsw_sp_span_inspected_port_unbind(from, span_entry, type); mlxsw_sp_span_inspected_port_del(from, span_entry, type, bind);
} }
static int mlxsw_sp_port_sample_set(struct mlxsw_sp_port *mlxsw_sp_port, static int mlxsw_sp_port_sample_set(struct mlxsw_sp_port *mlxsw_sp_port,
...@@ -1582,7 +1596,8 @@ mlxsw_sp_port_add_cls_matchall_mirror(struct mlxsw_sp_port *mlxsw_sp_port, ...@@ -1582,7 +1596,8 @@ mlxsw_sp_port_add_cls_matchall_mirror(struct mlxsw_sp_port *mlxsw_sp_port,
mirror->to_local_port = to_port->local_port; mirror->to_local_port = to_port->local_port;
mirror->ingress = ingress; mirror->ingress = ingress;
span_type = ingress ? MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS; span_type = ingress ? MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS;
return mlxsw_sp_span_mirror_add(mlxsw_sp_port, to_port, span_type); return mlxsw_sp_span_mirror_add(mlxsw_sp_port, to_port, span_type,
true);
} }
static void static void
...@@ -1593,8 +1608,8 @@ mlxsw_sp_port_del_cls_matchall_mirror(struct mlxsw_sp_port *mlxsw_sp_port, ...@@ -1593,8 +1608,8 @@ mlxsw_sp_port_del_cls_matchall_mirror(struct mlxsw_sp_port *mlxsw_sp_port,
span_type = mirror->ingress ? span_type = mirror->ingress ?
MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS; MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS;
mlxsw_sp_span_mirror_remove(mlxsw_sp_port, mirror->to_local_port, mlxsw_sp_span_mirror_del(mlxsw_sp_port, mirror->to_local_port,
span_type); span_type, true);
} }
static int static int
......
...@@ -396,6 +396,16 @@ struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find(struct net_device *dev); ...@@ -396,6 +396,16 @@ struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find(struct net_device *dev);
struct mlxsw_sp_port *mlxsw_sp_port_lower_dev_hold(struct net_device *dev); struct mlxsw_sp_port *mlxsw_sp_port_lower_dev_hold(struct net_device *dev);
void mlxsw_sp_port_dev_put(struct mlxsw_sp_port *mlxsw_sp_port); void mlxsw_sp_port_dev_put(struct mlxsw_sp_port *mlxsw_sp_port);
struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find_rcu(struct net_device *dev); struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find_rcu(struct net_device *dev);
int mlxsw_sp_span_mirror_add(struct mlxsw_sp_port *from,
struct mlxsw_sp_port *to,
enum mlxsw_sp_span_type type,
bool bind);
void mlxsw_sp_span_mirror_del(struct mlxsw_sp_port *from,
u8 destination_port,
enum mlxsw_sp_span_type type,
bool bind);
struct mlxsw_sp_span_entry *
mlxsw_sp_span_entry_find(struct mlxsw_sp *mlxsw_sp, u8 local_port);
/* spectrum_dcb.c */ /* spectrum_dcb.c */
#ifdef CONFIG_MLXSW_SPECTRUM_DCB #ifdef CONFIG_MLXSW_SPECTRUM_DCB
......
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