Commit 53da9325 authored by David S. Miller's avatar David S. Miller

Merge branch 'mlxsw-Cosmetic-fixes'

Jiri Pirko says:

====================
mlxsw: Cosmetic fixes

This is a set of mainly action/trap related cosmetic fixes.
No functional changes.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 2045e158 df647027
......@@ -1457,14 +1457,12 @@ static bool __is_rx_listener_equal(const struct mlxsw_rx_listener *rxl_a,
static struct mlxsw_rx_listener_item *
__find_rx_listener_item(struct mlxsw_core *mlxsw_core,
const struct mlxsw_rx_listener *rxl,
void *priv)
const struct mlxsw_rx_listener *rxl)
{
struct mlxsw_rx_listener_item *rxl_item;
list_for_each_entry(rxl_item, &mlxsw_core->rx_listener_list, list) {
if (__is_rx_listener_equal(&rxl_item->rxl, rxl) &&
rxl_item->priv == priv)
if (__is_rx_listener_equal(&rxl_item->rxl, rxl))
return rxl_item;
}
return NULL;
......@@ -1476,7 +1474,7 @@ int mlxsw_core_rx_listener_register(struct mlxsw_core *mlxsw_core,
{
struct mlxsw_rx_listener_item *rxl_item;
rxl_item = __find_rx_listener_item(mlxsw_core, rxl, priv);
rxl_item = __find_rx_listener_item(mlxsw_core, rxl);
if (rxl_item)
return -EEXIST;
rxl_item = kmalloc(sizeof(*rxl_item), GFP_KERNEL);
......@@ -1491,12 +1489,11 @@ int mlxsw_core_rx_listener_register(struct mlxsw_core *mlxsw_core,
EXPORT_SYMBOL(mlxsw_core_rx_listener_register);
void mlxsw_core_rx_listener_unregister(struct mlxsw_core *mlxsw_core,
const struct mlxsw_rx_listener *rxl,
void *priv)
const struct mlxsw_rx_listener *rxl)
{
struct mlxsw_rx_listener_item *rxl_item;
rxl_item = __find_rx_listener_item(mlxsw_core, rxl, priv);
rxl_item = __find_rx_listener_item(mlxsw_core, rxl);
if (!rxl_item)
return;
list_del_rcu(&rxl_item->list);
......@@ -1534,14 +1531,12 @@ static bool __is_event_listener_equal(const struct mlxsw_event_listener *el_a,
static struct mlxsw_event_listener_item *
__find_event_listener_item(struct mlxsw_core *mlxsw_core,
const struct mlxsw_event_listener *el,
void *priv)
const struct mlxsw_event_listener *el)
{
struct mlxsw_event_listener_item *el_item;
list_for_each_entry(el_item, &mlxsw_core->event_listener_list, list) {
if (__is_event_listener_equal(&el_item->el, el) &&
el_item->priv == priv)
if (__is_event_listener_equal(&el_item->el, el))
return el_item;
}
return NULL;
......@@ -1559,7 +1554,7 @@ int mlxsw_core_event_listener_register(struct mlxsw_core *mlxsw_core,
.trap_id = el->trap_id,
};
el_item = __find_event_listener_item(mlxsw_core, el, priv);
el_item = __find_event_listener_item(mlxsw_core, el);
if (el_item)
return -EEXIST;
el_item = kmalloc(sizeof(*el_item), GFP_KERNEL);
......@@ -1586,8 +1581,7 @@ int mlxsw_core_event_listener_register(struct mlxsw_core *mlxsw_core,
EXPORT_SYMBOL(mlxsw_core_event_listener_register);
void mlxsw_core_event_listener_unregister(struct mlxsw_core *mlxsw_core,
const struct mlxsw_event_listener *el,
void *priv)
const struct mlxsw_event_listener *el)
{
struct mlxsw_event_listener_item *el_item;
const struct mlxsw_rx_listener rxl = {
......@@ -1596,10 +1590,10 @@ void mlxsw_core_event_listener_unregister(struct mlxsw_core *mlxsw_core,
.trap_id = el->trap_id,
};
el_item = __find_event_listener_item(mlxsw_core, el, priv);
el_item = __find_event_listener_item(mlxsw_core, el);
if (!el_item)
return;
mlxsw_core_rx_listener_unregister(mlxsw_core, &rxl, el_item);
mlxsw_core_rx_listener_unregister(mlxsw_core, &rxl);
list_del(&el_item->list);
kfree(el_item);
}
......@@ -1611,11 +1605,11 @@ static int mlxsw_core_listener_register(struct mlxsw_core *mlxsw_core,
{
if (listener->is_event)
return mlxsw_core_event_listener_register(mlxsw_core,
&listener->u.event_listener,
&listener->event_listener,
priv);
else
return mlxsw_core_rx_listener_register(mlxsw_core,
&listener->u.rx_listener,
&listener->rx_listener,
priv);
}
......@@ -1625,12 +1619,10 @@ static void mlxsw_core_listener_unregister(struct mlxsw_core *mlxsw_core,
{
if (listener->is_event)
mlxsw_core_event_listener_unregister(mlxsw_core,
&listener->u.event_listener,
priv);
&listener->event_listener);
else
mlxsw_core_rx_listener_unregister(mlxsw_core,
&listener->u.rx_listener,
priv);
&listener->rx_listener);
}
int mlxsw_core_trap_register(struct mlxsw_core *mlxsw_core,
......
......@@ -62,7 +62,6 @@ struct mlxsw_rx_listener {
void (*func)(struct sk_buff *skb, u8 local_port, void *priv);
u8 local_port;
u16 trap_id;
enum mlxsw_reg_hpkt_action action;
};
struct mlxsw_event_listener {
......@@ -76,19 +75,19 @@ struct mlxsw_listener {
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;
u8 is_ctrl:1, /* should go via control buffer or not */
is_event:1;
};
#define MLXSW_RXL(_func, _trap_id, _action, _is_ctrl, _trap_group, \
_unreg_action) \
{ \
.trap_id = MLXSW_TRAP_ID_##_trap_id, \
.u.rx_listener = \
.rx_listener = \
{ \
.func = _func, \
.local_port = MLXSW_PORT_DONT_CARE, \
......@@ -98,20 +97,18 @@ struct mlxsw_listener {
.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 = \
.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, \
}
......@@ -119,15 +116,13 @@ int mlxsw_core_rx_listener_register(struct mlxsw_core *mlxsw_core,
const struct mlxsw_rx_listener *rxl,
void *priv);
void mlxsw_core_rx_listener_unregister(struct mlxsw_core *mlxsw_core,
const struct mlxsw_rx_listener *rxl,
void *priv);
const struct mlxsw_rx_listener *rxl);
int mlxsw_core_event_listener_register(struct mlxsw_core *mlxsw_core,
const struct mlxsw_event_listener *el,
void *priv);
void mlxsw_core_event_listener_unregister(struct mlxsw_core *mlxsw_core,
const struct mlxsw_event_listener *el,
void *priv);
const struct mlxsw_event_listener *el);
int mlxsw_core_trap_register(struct mlxsw_core *mlxsw_core,
const struct mlxsw_listener *listener,
......
......@@ -747,97 +747,94 @@ int mlxsw_afa_block_append_vlan_modify(struct mlxsw_afa_block *block,
}
EXPORT_SYMBOL(mlxsw_afa_block_append_vlan_modify);
/* Trap / Discard Action
* ---------------------
* The Trap / Discard action enables trapping / mirroring packets to the CPU
/* Trap Action
* -----------
* The Trap action enables trapping / mirroring packets to the CPU
* as well as discarding packets.
* The ACL Trap / Discard separates the forward/discard control from CPU
* trap control. In addition, the Trap / Discard action enables activating
* SPAN (port mirroring).
*/
#define MLXSW_AFA_TRAPDISC_CODE 0x03
#define MLXSW_AFA_TRAPDISC_SIZE 1
#define MLXSW_AFA_TRAP_CODE 0x03
#define MLXSW_AFA_TRAP_SIZE 1
enum mlxsw_afa_trapdisc_trap_action {
MLXSW_AFA_TRAPDISC_TRAP_ACTION_NOP = 0,
MLXSW_AFA_TRAPDISC_TRAP_ACTION_TRAP = 2,
enum mlxsw_afa_trap_trap_action {
MLXSW_AFA_TRAP_TRAP_ACTION_NOP = 0,
MLXSW_AFA_TRAP_TRAP_ACTION_TRAP = 2,
};
/* afa_trapdisc_trap_action
/* afa_trap_trap_action
* Trap Action.
*/
MLXSW_ITEM32(afa, trapdisc, trap_action, 0x00, 24, 4);
MLXSW_ITEM32(afa, trap, trap_action, 0x00, 24, 4);
enum mlxsw_afa_trapdisc_forward_action {
MLXSW_AFA_TRAPDISC_FORWARD_ACTION_FORWARD = 1,
MLXSW_AFA_TRAPDISC_FORWARD_ACTION_DISCARD = 3,
enum mlxsw_afa_trap_forward_action {
MLXSW_AFA_TRAP_FORWARD_ACTION_FORWARD = 1,
MLXSW_AFA_TRAP_FORWARD_ACTION_DISCARD = 3,
};
/* afa_trapdisc_forward_action
/* afa_trap_forward_action
* Forward Action.
*/
MLXSW_ITEM32(afa, trapdisc, forward_action, 0x00, 0, 4);
MLXSW_ITEM32(afa, trap, forward_action, 0x00, 0, 4);
/* afa_trapdisc_trap_id
/* afa_trap_trap_id
* Trap ID to configure.
*/
MLXSW_ITEM32(afa, trapdisc, trap_id, 0x04, 0, 9);
MLXSW_ITEM32(afa, trap, trap_id, 0x04, 0, 9);
/* afa_trapdisc_mirror_agent
/* afa_trap_mirror_agent
* Mirror agent.
*/
MLXSW_ITEM32(afa, trapdisc, mirror_agent, 0x08, 29, 3);
MLXSW_ITEM32(afa, trap, mirror_agent, 0x08, 29, 3);
/* afa_trapdisc_mirror_enable
/* afa_trap_mirror_enable
* Mirror enable.
*/
MLXSW_ITEM32(afa, trapdisc, mirror_enable, 0x08, 24, 1);
MLXSW_ITEM32(afa, trap, mirror_enable, 0x08, 24, 1);
static inline void
mlxsw_afa_trapdisc_pack(char *payload,
enum mlxsw_afa_trapdisc_trap_action trap_action,
enum mlxsw_afa_trapdisc_forward_action forward_action,
mlxsw_afa_trap_pack(char *payload,
enum mlxsw_afa_trap_trap_action trap_action,
enum mlxsw_afa_trap_forward_action forward_action,
u16 trap_id)
{
mlxsw_afa_trapdisc_trap_action_set(payload, trap_action);
mlxsw_afa_trapdisc_forward_action_set(payload, forward_action);
mlxsw_afa_trapdisc_trap_id_set(payload, trap_id);
mlxsw_afa_trap_trap_action_set(payload, trap_action);
mlxsw_afa_trap_forward_action_set(payload, forward_action);
mlxsw_afa_trap_trap_id_set(payload, trap_id);
}
static inline void
mlxsw_afa_trapdisc_mirror_pack(char *payload, bool mirror_enable,
mlxsw_afa_trap_mirror_pack(char *payload, bool mirror_enable,
u8 mirror_agent)
{
mlxsw_afa_trapdisc_mirror_enable_set(payload, mirror_enable);
mlxsw_afa_trapdisc_mirror_agent_set(payload, mirror_agent);
mlxsw_afa_trap_mirror_enable_set(payload, mirror_enable);
mlxsw_afa_trap_mirror_agent_set(payload, mirror_agent);
}
int mlxsw_afa_block_append_drop(struct mlxsw_afa_block *block)
{
char *act = mlxsw_afa_block_append_action(block,
MLXSW_AFA_TRAPDISC_CODE,
MLXSW_AFA_TRAPDISC_SIZE);
char *act = mlxsw_afa_block_append_action(block, MLXSW_AFA_TRAP_CODE,
MLXSW_AFA_TRAP_SIZE);
if (IS_ERR(act))
return PTR_ERR(act);
mlxsw_afa_trapdisc_pack(act, MLXSW_AFA_TRAPDISC_TRAP_ACTION_NOP,
MLXSW_AFA_TRAPDISC_FORWARD_ACTION_DISCARD, 0);
mlxsw_afa_trap_pack(act, MLXSW_AFA_TRAP_TRAP_ACTION_NOP,
MLXSW_AFA_TRAP_FORWARD_ACTION_DISCARD, 0);
return 0;
}
EXPORT_SYMBOL(mlxsw_afa_block_append_drop);
int mlxsw_afa_block_append_trap(struct mlxsw_afa_block *block, u16 trap_id)
{
char *act = mlxsw_afa_block_append_action(block,
MLXSW_AFA_TRAPDISC_CODE,
MLXSW_AFA_TRAPDISC_SIZE);
char *act = mlxsw_afa_block_append_action(block, MLXSW_AFA_TRAP_CODE,
MLXSW_AFA_TRAP_SIZE);
if (IS_ERR(act))
return PTR_ERR(act);
mlxsw_afa_trapdisc_pack(act, MLXSW_AFA_TRAPDISC_TRAP_ACTION_TRAP,
MLXSW_AFA_TRAPDISC_FORWARD_ACTION_DISCARD,
trap_id);
mlxsw_afa_trap_pack(act, MLXSW_AFA_TRAP_TRAP_ACTION_TRAP,
MLXSW_AFA_TRAP_FORWARD_ACTION_DISCARD, trap_id);
return 0;
}
EXPORT_SYMBOL(mlxsw_afa_block_append_trap);
......@@ -845,15 +842,13 @@ EXPORT_SYMBOL(mlxsw_afa_block_append_trap);
int mlxsw_afa_block_append_trap_and_forward(struct mlxsw_afa_block *block,
u16 trap_id)
{
char *act = mlxsw_afa_block_append_action(block,
MLXSW_AFA_TRAPDISC_CODE,
MLXSW_AFA_TRAPDISC_SIZE);
char *act = mlxsw_afa_block_append_action(block, MLXSW_AFA_TRAP_CODE,
MLXSW_AFA_TRAP_SIZE);
if (IS_ERR(act))
return PTR_ERR(act);
mlxsw_afa_trapdisc_pack(act, MLXSW_AFA_TRAPDISC_TRAP_ACTION_TRAP,
MLXSW_AFA_TRAPDISC_FORWARD_ACTION_FORWARD,
trap_id);
mlxsw_afa_trap_pack(act, MLXSW_AFA_TRAP_TRAP_ACTION_TRAP,
MLXSW_AFA_TRAP_FORWARD_ACTION_FORWARD, trap_id);
return 0;
}
EXPORT_SYMBOL(mlxsw_afa_block_append_trap_and_forward);
......@@ -920,13 +915,13 @@ mlxsw_afa_block_append_allocated_mirror(struct mlxsw_afa_block *block,
u8 mirror_agent)
{
char *act = mlxsw_afa_block_append_action(block,
MLXSW_AFA_TRAPDISC_CODE,
MLXSW_AFA_TRAPDISC_SIZE);
MLXSW_AFA_TRAP_CODE,
MLXSW_AFA_TRAP_SIZE);
if (IS_ERR(act))
return PTR_ERR(act);
mlxsw_afa_trapdisc_pack(act, MLXSW_AFA_TRAPDISC_TRAP_ACTION_NOP,
MLXSW_AFA_TRAPDISC_FORWARD_ACTION_FORWARD, 0);
mlxsw_afa_trapdisc_mirror_pack(act, true, mirror_agent);
mlxsw_afa_trap_pack(act, MLXSW_AFA_TRAP_TRAP_ACTION_NOP,
MLXSW_AFA_TRAP_FORWARD_ACTION_FORWARD, 0);
mlxsw_afa_trap_mirror_pack(act, true, mirror_agent);
return 0;
}
......
......@@ -25,8 +25,6 @@
#define MLXSW_PCI_CIR_CTRL_STATUS_SHIFT 24
#define MLXSW_PCI_CIR_TIMEOUT_MSECS 1000
#define MLXSW_PCI_SW_RESET 0xF0010
#define MLXSW_PCI_SW_RESET_RST_BIT BIT(0)
#define MLXSW_PCI_SW_RESET_TIMEOUT_MSECS 900000
#define MLXSW_PCI_SW_RESET_WAIT_MSECS 100
#define MLXSW_PCI_FW_READY 0xA1844
......
......@@ -670,10 +670,11 @@ struct mlxsw_sp_acl_block {
struct mlxsw_afk *mlxsw_sp_acl_afk(struct mlxsw_sp_acl *acl);
struct mlxsw_sp *mlxsw_sp_acl_block_mlxsw_sp(struct mlxsw_sp_acl_block *block);
unsigned int mlxsw_sp_acl_block_rule_count(struct mlxsw_sp_acl_block *block);
unsigned int
mlxsw_sp_acl_block_rule_count(const struct mlxsw_sp_acl_block *block);
void mlxsw_sp_acl_block_disable_inc(struct mlxsw_sp_acl_block *block);
void mlxsw_sp_acl_block_disable_dec(struct mlxsw_sp_acl_block *block);
bool mlxsw_sp_acl_block_disabled(struct mlxsw_sp_acl_block *block);
bool mlxsw_sp_acl_block_disabled(const struct mlxsw_sp_acl_block *block);
struct mlxsw_sp_acl_block *mlxsw_sp_acl_block_create(struct mlxsw_sp *mlxsw_sp,
struct net *net);
void mlxsw_sp_acl_block_destroy(struct mlxsw_sp_acl_block *block);
......@@ -686,7 +687,7 @@ int mlxsw_sp_acl_block_unbind(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_block *block,
struct mlxsw_sp_port *mlxsw_sp_port,
bool ingress);
bool mlxsw_sp_acl_block_is_egress_bound(struct mlxsw_sp_acl_block *block);
bool mlxsw_sp_acl_block_is_egress_bound(const struct mlxsw_sp_acl_block *block);
struct mlxsw_sp_acl_ruleset *
mlxsw_sp_acl_ruleset_lookup(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_block *block, u32 chain_index,
......
......@@ -99,7 +99,8 @@ struct mlxsw_sp *mlxsw_sp_acl_block_mlxsw_sp(struct mlxsw_sp_acl_block *block)
return block->mlxsw_sp;
}
unsigned int mlxsw_sp_acl_block_rule_count(struct mlxsw_sp_acl_block *block)
unsigned int
mlxsw_sp_acl_block_rule_count(const struct mlxsw_sp_acl_block *block)
{
return block ? block->rule_count : 0;
}
......@@ -116,12 +117,12 @@ void mlxsw_sp_acl_block_disable_dec(struct mlxsw_sp_acl_block *block)
block->disable_count--;
}
bool mlxsw_sp_acl_block_disabled(struct mlxsw_sp_acl_block *block)
bool mlxsw_sp_acl_block_disabled(const struct mlxsw_sp_acl_block *block)
{
return block->disable_count;
}
bool mlxsw_sp_acl_block_is_egress_bound(struct mlxsw_sp_acl_block *block)
bool mlxsw_sp_acl_block_is_egress_bound(const struct mlxsw_sp_acl_block *block)
{
struct mlxsw_sp_acl_block_binding *binding;
......@@ -163,7 +164,8 @@ mlxsw_sp_acl_ruleset_unbind(struct mlxsw_sp *mlxsw_sp,
binding->mlxsw_sp_port, binding->ingress);
}
static bool mlxsw_sp_acl_ruleset_block_bound(struct mlxsw_sp_acl_block *block)
static bool
mlxsw_sp_acl_ruleset_block_bound(const struct mlxsw_sp_acl_block *block)
{
return block->ruleset_zero;
}
......
......@@ -25,10 +25,81 @@ enum {
#define MLXSW_SP_TRAP_METADATA DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT
static int mlxsw_sp_rx_listener(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
u8 local_port,
struct mlxsw_sp_port *mlxsw_sp_port)
{
struct mlxsw_sp_port_pcpu_stats *pcpu_stats;
if (unlikely(!mlxsw_sp_port)) {
dev_warn_ratelimited(mlxsw_sp->bus_info->dev, "Port %d: skb received for non-existent port\n",
local_port);
kfree_skb(skb);
return -EINVAL;
}
skb->dev = mlxsw_sp_port->dev;
pcpu_stats = this_cpu_ptr(mlxsw_sp_port->pcpu_stats);
u64_stats_update_begin(&pcpu_stats->syncp);
pcpu_stats->rx_packets++;
pcpu_stats->rx_bytes += skb->len;
u64_stats_update_end(&pcpu_stats->syncp);
skb->protocol = eth_type_trans(skb, skb->dev);
return 0;
}
static void mlxsw_sp_rx_drop_listener(struct sk_buff *skb, u8 local_port,
void *priv);
void *trap_ctx)
{
struct devlink_port *in_devlink_port;
struct mlxsw_sp_port *mlxsw_sp_port;
struct mlxsw_sp *mlxsw_sp;
struct devlink *devlink;
int err;
mlxsw_sp = devlink_trap_ctx_priv(trap_ctx);
mlxsw_sp_port = mlxsw_sp->ports[local_port];
err = mlxsw_sp_rx_listener(mlxsw_sp, skb, local_port, mlxsw_sp_port);
if (err)
return;
devlink = priv_to_devlink(mlxsw_sp->core);
in_devlink_port = mlxsw_core_port_devlink_port_get(mlxsw_sp->core,
local_port);
skb_push(skb, ETH_HLEN);
devlink_trap_report(devlink, skb, trap_ctx, in_devlink_port);
consume_skb(skb);
}
static void mlxsw_sp_rx_exception_listener(struct sk_buff *skb, u8 local_port,
void *trap_ctx);
void *trap_ctx)
{
struct devlink_port *in_devlink_port;
struct mlxsw_sp_port *mlxsw_sp_port;
struct mlxsw_sp *mlxsw_sp;
struct devlink *devlink;
int err;
mlxsw_sp = devlink_trap_ctx_priv(trap_ctx);
mlxsw_sp_port = mlxsw_sp->ports[local_port];
err = mlxsw_sp_rx_listener(mlxsw_sp, skb, local_port, mlxsw_sp_port);
if (err)
return;
devlink = priv_to_devlink(mlxsw_sp->core);
in_devlink_port = mlxsw_core_port_devlink_port_get(mlxsw_sp->core,
local_port);
skb_push(skb, ETH_HLEN);
devlink_trap_report(devlink, skb, trap_ctx, in_devlink_port);
skb_pull(skb, ETH_HLEN);
skb->offload_fwd_mark = 1;
netif_receive_skb(skb);
}
#define MLXSW_SP_TRAP_DROP(_id, _group_id) \
DEVLINK_TRAP_GENERIC(DROP, DROP, _id, \
......@@ -54,7 +125,7 @@ static void mlxsw_sp_rx_exception_listener(struct sk_buff *skb, u8 local_port,
MLXSW_RXL(mlxsw_sp_rx_exception_listener, _id, \
_action, false, SP_##_group_id, DISCARD)
static struct devlink_trap mlxsw_sp_traps_arr[] = {
static const struct devlink_trap mlxsw_sp_traps_arr[] = {
MLXSW_SP_TRAP_DROP(SMAC_MC, L2_DROPS),
MLXSW_SP_TRAP_DROP(VLAN_TAG_MISMATCH, L2_DROPS),
MLXSW_SP_TRAP_DROP(INGRESS_VLAN_FILTER, L2_DROPS),
......@@ -85,7 +156,7 @@ static struct devlink_trap mlxsw_sp_traps_arr[] = {
MLXSW_SP_TRAP_DROP(OVERLAY_SMAC_MC, TUNNEL_DROPS),
};
static struct mlxsw_listener mlxsw_sp_listeners_arr[] = {
static const struct mlxsw_listener mlxsw_sp_listeners_arr[] = {
MLXSW_SP_RXL_DISCARD(ING_PACKET_SMAC_MC, L2_DISCARDS),
MLXSW_SP_RXL_DISCARD(ING_SWITCH_VTAG_ALLOW, L2_DISCARDS),
MLXSW_SP_RXL_DISCARD(ING_SWITCH_VLAN, L2_DISCARDS),
......@@ -130,7 +201,7 @@ static struct mlxsw_listener mlxsw_sp_listeners_arr[] = {
* be mapped to the same devlink trap. Order is according to
* 'mlxsw_sp_listeners_arr'.
*/
static u16 mlxsw_sp_listener_devlink_map[] = {
static const u16 mlxsw_sp_listener_devlink_map[] = {
DEVLINK_TRAP_GENERIC_ID_SMAC_MC,
DEVLINK_TRAP_GENERIC_ID_VLAN_TAG_MISMATCH,
DEVLINK_TRAP_GENERIC_ID_INGRESS_VLAN_FILTER,
......@@ -166,81 +237,25 @@ static u16 mlxsw_sp_listener_devlink_map[] = {
DEVLINK_TRAP_GENERIC_ID_OVERLAY_SMAC_MC,
};
static int mlxsw_sp_rx_listener(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
u8 local_port,
struct mlxsw_sp_port *mlxsw_sp_port)
{
struct mlxsw_sp_port_pcpu_stats *pcpu_stats;
if (unlikely(!mlxsw_sp_port)) {
dev_warn_ratelimited(mlxsw_sp->bus_info->dev, "Port %d: skb received for non-existent port\n",
local_port);
kfree_skb(skb);
return -EINVAL;
}
skb->dev = mlxsw_sp_port->dev;
pcpu_stats = this_cpu_ptr(mlxsw_sp_port->pcpu_stats);
u64_stats_update_begin(&pcpu_stats->syncp);
pcpu_stats->rx_packets++;
pcpu_stats->rx_bytes += skb->len;
u64_stats_update_end(&pcpu_stats->syncp);
skb->protocol = eth_type_trans(skb, skb->dev);
return 0;
}
static void mlxsw_sp_rx_drop_listener(struct sk_buff *skb, u8 local_port,
void *trap_ctx)
{
struct devlink_port *in_devlink_port;
struct mlxsw_sp_port *mlxsw_sp_port;
struct mlxsw_sp *mlxsw_sp;
struct devlink *devlink;
mlxsw_sp = devlink_trap_ctx_priv(trap_ctx);
mlxsw_sp_port = mlxsw_sp->ports[local_port];
if (mlxsw_sp_rx_listener(mlxsw_sp, skb, local_port, mlxsw_sp_port))
return;
devlink = priv_to_devlink(mlxsw_sp->core);
in_devlink_port = mlxsw_core_port_devlink_port_get(mlxsw_sp->core,
local_port);
skb_push(skb, ETH_HLEN);
devlink_trap_report(devlink, skb, trap_ctx, in_devlink_port);
consume_skb(skb);
}
#define MLXSW_SP_DISCARD_POLICER_ID (MLXSW_REG_HTGT_TRAP_GROUP_MAX + 1)
static void mlxsw_sp_rx_exception_listener(struct sk_buff *skb, u8 local_port,
void *trap_ctx)
static int mlxsw_sp_trap_cpu_policers_set(struct mlxsw_sp *mlxsw_sp)
{
struct devlink_port *in_devlink_port;
struct mlxsw_sp_port *mlxsw_sp_port;
struct mlxsw_sp *mlxsw_sp;
struct devlink *devlink;
mlxsw_sp = devlink_trap_ctx_priv(trap_ctx);
mlxsw_sp_port = mlxsw_sp->ports[local_port];
if (mlxsw_sp_rx_listener(mlxsw_sp, skb, local_port, mlxsw_sp_port))
return;
char qpcr_pl[MLXSW_REG_QPCR_LEN];
devlink = priv_to_devlink(mlxsw_sp->core);
in_devlink_port = mlxsw_core_port_devlink_port_get(mlxsw_sp->core,
local_port);
skb_push(skb, ETH_HLEN);
devlink_trap_report(devlink, skb, trap_ctx, in_devlink_port);
skb_pull(skb, ETH_HLEN);
skb->offload_fwd_mark = 1;
netif_receive_skb(skb);
mlxsw_reg_qpcr_pack(qpcr_pl, MLXSW_SP_DISCARD_POLICER_ID,
MLXSW_REG_QPCR_IR_UNITS_M, false, 10 * 1024, 7);
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qpcr), qpcr_pl);
}
int mlxsw_sp_devlink_traps_init(struct mlxsw_sp *mlxsw_sp)
{
struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
int err;
err = mlxsw_sp_trap_cpu_policers_set(mlxsw_sp);
if (err)
return err;
if (WARN_ON(ARRAY_SIZE(mlxsw_sp_listener_devlink_map) !=
ARRAY_SIZE(mlxsw_sp_listeners_arr)))
......@@ -265,7 +280,7 @@ int mlxsw_sp_trap_init(struct mlxsw_core *mlxsw_core,
int i;
for (i = 0; i < ARRAY_SIZE(mlxsw_sp_listener_devlink_map); i++) {
struct mlxsw_listener *listener;
const struct mlxsw_listener *listener;
int err;
if (mlxsw_sp_listener_devlink_map[i] != trap->id)
......@@ -286,7 +301,7 @@ void mlxsw_sp_trap_fini(struct mlxsw_core *mlxsw_core,
int i;
for (i = 0; i < ARRAY_SIZE(mlxsw_sp_listener_devlink_map); i++) {
struct mlxsw_listener *listener;
const struct mlxsw_listener *listener;
if (mlxsw_sp_listener_devlink_map[i] != trap->id)
continue;
......@@ -303,8 +318,8 @@ int mlxsw_sp_trap_action_set(struct mlxsw_core *mlxsw_core,
int i;
for (i = 0; i < ARRAY_SIZE(mlxsw_sp_listener_devlink_map); i++) {
const struct mlxsw_listener *listener;
enum mlxsw_reg_hpkt_action hw_action;
struct mlxsw_listener *listener;
int err;
if (mlxsw_sp_listener_devlink_map[i] != trap->id)
......@@ -331,40 +346,7 @@ int mlxsw_sp_trap_action_set(struct mlxsw_core *mlxsw_core,
return 0;
}
#define MLXSW_SP_DISCARD_POLICER_ID (MLXSW_REG_HTGT_TRAP_GROUP_MAX + 1)
static int
mlxsw_sp_trap_group_policer_init(struct mlxsw_sp *mlxsw_sp,
const struct devlink_trap_group *group)
{
enum mlxsw_reg_qpcr_ir_units ir_units;
char qpcr_pl[MLXSW_REG_QPCR_LEN];
u16 policer_id;
u8 burst_size;
bool is_bytes;
u32 rate;
switch (group->id) {
case DEVLINK_TRAP_GROUP_GENERIC_ID_L2_DROPS: /* fall through */
case DEVLINK_TRAP_GROUP_GENERIC_ID_L3_DROPS: /* fall through */
case DEVLINK_TRAP_GROUP_GENERIC_ID_TUNNEL_DROPS:
policer_id = MLXSW_SP_DISCARD_POLICER_ID;
ir_units = MLXSW_REG_QPCR_IR_UNITS_M;
is_bytes = false;
rate = 10 * 1024; /* 10Kpps */
burst_size = 7;
break;
default:
return -EINVAL;
}
mlxsw_reg_qpcr_pack(qpcr_pl, policer_id, ir_units, is_bytes, rate,
burst_size);
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qpcr), qpcr_pl);
}
static int
__mlxsw_sp_trap_group_init(struct mlxsw_sp *mlxsw_sp,
int mlxsw_sp_trap_group_init(struct mlxsw_core *mlxsw_core,
const struct devlink_trap_group *group)
{
char htgt_pl[MLXSW_REG_HTGT_LEN];
......@@ -395,22 +377,5 @@ __mlxsw_sp_trap_group_init(struct mlxsw_sp *mlxsw_sp,
}
mlxsw_reg_htgt_pack(htgt_pl, group_id, policer_id, priority, tc);
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(htgt), htgt_pl);
}
int mlxsw_sp_trap_group_init(struct mlxsw_core *mlxsw_core,
const struct devlink_trap_group *group)
{
struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
int err;
err = mlxsw_sp_trap_group_policer_init(mlxsw_sp, group);
if (err)
return err;
err = __mlxsw_sp_trap_group_init(mlxsw_sp, group);
if (err)
return err;
return 0;
return mlxsw_reg_write(mlxsw_core, MLXSW_REG(htgt), htgt_pl);
}
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