Skip to content

Commit

Permalink
Merge branch 'mlxsw-trap-groups-and-policers'
Browse files Browse the repository at this point in the history
Jiri Pirko says:

====================
mlxsw: traps, trap groups and policers

Nogah says:

For a packet to be sent from the HW to the cpu, it needs to be trapped.
For a trap to be activate it should be assigned to a trap group.
Those trap groups can have policers, to limit the packet rate (the max
number of packets that can be sent to the cpu in a time slot, the rest
will be discarded) or the data rate (the same, but the count is not by the
number of packets but by their total length in bytes).

This patchset rearrange the trap setting API, re-write the traps and the
trap groups list in spectrum and assign them policers.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Nov 26, 2016
2 parents eafa6ab + 9148e7c commit e5f12b3
Show file tree
Hide file tree
Showing 8 changed files with 625 additions and 408 deletions.
116 changes: 79 additions & 37 deletions drivers/net/ethernet/mellanox/mlxsw/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -572,27 +572,9 @@ static void mlxsw_emad_rx_listener_func(struct sk_buff *skb, u8 local_port,
dev_kfree_skb(skb);
}

static const struct mlxsw_rx_listener mlxsw_emad_rx_listener = {
.func = mlxsw_emad_rx_listener_func,
.local_port = MLXSW_PORT_DONT_CARE,
.trap_id = MLXSW_TRAP_ID_ETHEMAD,
};

static int mlxsw_emad_traps_set(struct mlxsw_core *mlxsw_core)
{
char htgt_pl[MLXSW_REG_HTGT_LEN];
char hpkt_pl[MLXSW_REG_HPKT_LEN];
int err;

mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_EMAD);
err = mlxsw_reg_write(mlxsw_core, MLXSW_REG(htgt), htgt_pl);
if (err)
return err;

mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_TRAP_TO_CPU,
MLXSW_TRAP_ID_ETHEMAD);
return mlxsw_reg_write(mlxsw_core, MLXSW_REG(hpkt), hpkt_pl);
}
static const struct mlxsw_listener mlxsw_emad_rx_listener =
MLXSW_RXL(mlxsw_emad_rx_listener_func, ETHEMAD, TRAP_TO_CPU, false,
EMAD, DISCARD);

static int mlxsw_emad_init(struct mlxsw_core *mlxsw_core)
{
Expand All @@ -613,42 +595,33 @@ static int mlxsw_emad_init(struct mlxsw_core *mlxsw_core)
INIT_LIST_HEAD(&mlxsw_core->emad.trans_list);
spin_lock_init(&mlxsw_core->emad.trans_list_lock);

err = mlxsw_core_rx_listener_register(mlxsw_core,
&mlxsw_emad_rx_listener,
mlxsw_core);
err = mlxsw_core_trap_register(mlxsw_core, &mlxsw_emad_rx_listener,
mlxsw_core);
if (err)
return err;

err = mlxsw_emad_traps_set(mlxsw_core);
err = mlxsw_core->driver->basic_trap_groups_set(mlxsw_core);
if (err)
goto err_emad_trap_set;

mlxsw_core->emad.use_emad = true;

return 0;

err_emad_trap_set:
mlxsw_core_rx_listener_unregister(mlxsw_core,
&mlxsw_emad_rx_listener,
mlxsw_core);
mlxsw_core_trap_unregister(mlxsw_core, &mlxsw_emad_rx_listener,
mlxsw_core);
return err;
}

static void mlxsw_emad_fini(struct mlxsw_core *mlxsw_core)
{
char hpkt_pl[MLXSW_REG_HPKT_LEN];

if (!(mlxsw_core->bus->features & MLXSW_BUS_F_TXRX))
return;

mlxsw_core->emad.use_emad = false;
mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_DISCARD,
MLXSW_TRAP_ID_ETHEMAD);
mlxsw_reg_write(mlxsw_core, MLXSW_REG(hpkt), hpkt_pl);

mlxsw_core_rx_listener_unregister(mlxsw_core,
&mlxsw_emad_rx_listener,
mlxsw_core);
mlxsw_core_trap_unregister(mlxsw_core, &mlxsw_emad_rx_listener,
mlxsw_core);
}

static struct sk_buff *mlxsw_emad_alloc(const struct mlxsw_core *mlxsw_core,
Expand Down Expand Up @@ -1392,6 +1365,75 @@ void mlxsw_core_event_listener_unregister(struct mlxsw_core *mlxsw_core,
}
EXPORT_SYMBOL(mlxsw_core_event_listener_unregister);

static int mlxsw_core_listener_register(struct mlxsw_core *mlxsw_core,
const struct mlxsw_listener *listener,
void *priv)
{
if (listener->is_event)
return mlxsw_core_event_listener_register(mlxsw_core,
&listener->u.event_listener,
priv);
else
return mlxsw_core_rx_listener_register(mlxsw_core,
&listener->u.rx_listener,
priv);
}

static void mlxsw_core_listener_unregister(struct mlxsw_core *mlxsw_core,
const struct mlxsw_listener *listener,
void *priv)
{
if (listener->is_event)
mlxsw_core_event_listener_unregister(mlxsw_core,
&listener->u.event_listener,
priv);
else
mlxsw_core_rx_listener_unregister(mlxsw_core,
&listener->u.rx_listener,
priv);
}

int mlxsw_core_trap_register(struct mlxsw_core *mlxsw_core,
const struct mlxsw_listener *listener, void *priv)
{
char hpkt_pl[MLXSW_REG_HPKT_LEN];
int err;

err = mlxsw_core_listener_register(mlxsw_core, listener, priv);
if (err)
return err;

mlxsw_reg_hpkt_pack(hpkt_pl, listener->action, listener->trap_id,
listener->trap_group, listener->is_ctrl);
err = mlxsw_reg_write(mlxsw_core, MLXSW_REG(hpkt), hpkt_pl);
if (err)
goto err_trap_set;

return 0;

err_trap_set:
mlxsw_core_listener_unregister(mlxsw_core, listener, priv);
return err;
}
EXPORT_SYMBOL(mlxsw_core_trap_register);

void mlxsw_core_trap_unregister(struct mlxsw_core *mlxsw_core,
const struct mlxsw_listener *listener,
void *priv)
{
char hpkt_pl[MLXSW_REG_HPKT_LEN];

if (!listener->is_event) {
mlxsw_reg_hpkt_pack(hpkt_pl, listener->unreg_action,
listener->trap_id, listener->trap_group,
listener->is_ctrl);
mlxsw_reg_write(mlxsw_core, MLXSW_REG(hpkt), hpkt_pl);
}

mlxsw_core_listener_unregister(mlxsw_core, listener, priv);
}
EXPORT_SYMBOL(mlxsw_core_trap_unregister);

static u64 mlxsw_core_tid_get(struct mlxsw_core *mlxsw_core)
{
return atomic64_inc_return(&mlxsw_core->emad.tid);
Expand Down
52 changes: 52 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,50 @@ struct mlxsw_event_listener {
enum mlxsw_event_trap_id trap_id;
};

struct mlxsw_listener {
u16 trap_id;
union {
struct mlxsw_rx_listener rx_listener;
struct mlxsw_event_listener event_listener;
} u;
enum mlxsw_reg_hpkt_action action;
enum mlxsw_reg_hpkt_action unreg_action;
u8 trap_group;
bool is_ctrl; /* should go via control buffer or not */
bool is_event;
};

#define MLXSW_RXL(_func, _trap_id, _action, _is_ctrl, _trap_group, \
_unreg_action) \
{ \
.trap_id = MLXSW_TRAP_ID_##_trap_id, \
.u.rx_listener = \
{ \
.func = _func, \
.local_port = MLXSW_PORT_DONT_CARE, \
.trap_id = MLXSW_TRAP_ID_##_trap_id, \
}, \
.action = MLXSW_REG_HPKT_ACTION_##_action, \
.unreg_action = MLXSW_REG_HPKT_ACTION_##_unreg_action, \
.trap_group = MLXSW_REG_HTGT_TRAP_GROUP_##_trap_group, \
.is_ctrl = _is_ctrl, \
.is_event = false, \
}

#define MLXSW_EVENTL(_func, _trap_id, _trap_group) \
{ \
.trap_id = MLXSW_TRAP_ID_##_trap_id, \
.u.event_listener = \
{ \
.func = _func, \
.trap_id = MLXSW_TRAP_ID_##_trap_id, \
}, \
.action = MLXSW_REG_HPKT_ACTION_TRAP_TO_CPU, \
.trap_group = MLXSW_REG_HTGT_TRAP_GROUP_##_trap_group, \
.is_ctrl = false, \
.is_event = true, \
}

int mlxsw_core_rx_listener_register(struct mlxsw_core *mlxsw_core,
const struct mlxsw_rx_listener *rxl,
void *priv);
Expand All @@ -104,6 +148,13 @@ void mlxsw_core_event_listener_unregister(struct mlxsw_core *mlxsw_core,
const struct mlxsw_event_listener *el,
void *priv);

int mlxsw_core_trap_register(struct mlxsw_core *mlxsw_core,
const struct mlxsw_listener *listener,
void *priv);
void mlxsw_core_trap_unregister(struct mlxsw_core *mlxsw_core,
const struct mlxsw_listener *listener,
void *priv);

typedef void mlxsw_reg_trans_cb_t(struct mlxsw_core *mlxsw_core, char *payload,
size_t payload_len, unsigned long cb_priv);

Expand Down Expand Up @@ -214,6 +265,7 @@ struct mlxsw_driver {
int (*init)(struct mlxsw_core *mlxsw_core,
const struct mlxsw_bus_info *mlxsw_bus_info);
void (*fini)(struct mlxsw_core *mlxsw_core);
int (*basic_trap_groups_set)(struct mlxsw_core *mlxsw_core);
int (*port_type_set)(struct mlxsw_core *mlxsw_core, u8 local_port,
enum devlink_port_type new_type);
int (*port_split)(struct mlxsw_core *mlxsw_core, u8 local_port,
Expand Down
Loading

0 comments on commit e5f12b3

Please sign in to comment.