diff options
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/cmd.h | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/i2c.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 101 |
3 files changed, 59 insertions, 54 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/cmd.h b/drivers/net/ethernet/mellanox/mlxsw/cmd.h index 56e19b0d2f8f..a1b48421648a 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/cmd.h +++ b/drivers/net/ethernet/mellanox/mlxsw/cmd.h @@ -1132,12 +1132,12 @@ static inline int mlxsw_cmd_sw2hw_eq(struct mlxsw_core *mlxsw_core, */ MLXSW_ITEM32(cmd_mbox, sw2hw_eq, int_msix, 0x00, 24, 1); -/* cmd_mbox_sw2hw_eq_int_oi +/* cmd_mbox_sw2hw_eq_oi * When set, overrun ignore is enabled. */ MLXSW_ITEM32(cmd_mbox, sw2hw_eq, oi, 0x00, 12, 1); -/* cmd_mbox_sw2hw_eq_int_st +/* cmd_mbox_sw2hw_eq_st * Event delivery state machine * 0x0 - FIRED * 0x1 - ARMED (Request for Notification) @@ -1146,19 +1146,19 @@ MLXSW_ITEM32(cmd_mbox, sw2hw_eq, oi, 0x00, 12, 1); */ MLXSW_ITEM32(cmd_mbox, sw2hw_eq, st, 0x00, 8, 2); -/* cmd_mbox_sw2hw_eq_int_log_eq_size +/* cmd_mbox_sw2hw_eq_log_eq_size * Log (base 2) of the EQ size (in entries). */ MLXSW_ITEM32(cmd_mbox, sw2hw_eq, log_eq_size, 0x00, 0, 4); -/* cmd_mbox_sw2hw_eq_int_producer_counter +/* cmd_mbox_sw2hw_eq_producer_counter * Producer Counter. The counter is incremented for each EQE that is written * by the HW to the EQ. * Maintained by HW (valid for the QUERY_EQ command only) */ MLXSW_ITEM32(cmd_mbox, sw2hw_eq, producer_counter, 0x04, 0, 16); -/* cmd_mbox_sw2hw_eq_int_pa +/* cmd_mbox_sw2hw_eq_pa * Physical Address. */ MLXSW_ITEM64_INDEXED(cmd_mbox, sw2hw_eq, pa, 0x10, 11, 53, 0x08, 0x00, true); diff --git a/drivers/net/ethernet/mellanox/mlxsw/i2c.c b/drivers/net/ethernet/mellanox/mlxsw/i2c.c index e50c8db2602a..12c3a4449120 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/i2c.c +++ b/drivers/net/ethernet/mellanox/mlxsw/i2c.c @@ -338,7 +338,7 @@ mlxsw_i2c_write(struct device *dev, size_t in_mbox_size, u8 *in_mbox, int num, return -EIO; } - return err > 0 ? 0 : err; + return 0; } /* Routine executes I2C command. */ diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index 46c53a042e6b..d0e803f4f775 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c @@ -1161,8 +1161,8 @@ static int mlxsw_sp_port_get_phys_port_name(struct net_device *dev, char *name, } static struct mlxsw_sp_port_mall_tc_entry * -mlxsw_sp_port_mirror_entry_find(struct mlxsw_sp_port *port, - unsigned long cookie) { +mlxsw_sp_port_mall_tc_entry_find(struct mlxsw_sp_port *port, + unsigned long cookie) { struct mlxsw_sp_port_mall_tc_entry *mall_tc_entry; list_for_each_entry(mall_tc_entry, &port->mall_tc_list, list) @@ -1174,17 +1174,15 @@ mlxsw_sp_port_mirror_entry_find(struct mlxsw_sp_port *port, static int mlxsw_sp_port_add_cls_matchall_mirror(struct mlxsw_sp_port *mlxsw_sp_port, - struct tc_cls_matchall_offload *cls, + struct mlxsw_sp_port_mall_mirror_tc_entry *mirror, const struct tc_action *a, bool ingress) { - struct mlxsw_sp_port_mall_tc_entry *mall_tc_entry; struct net *net = dev_net(mlxsw_sp_port->dev); enum mlxsw_sp_span_type span_type; struct mlxsw_sp_port *to_port; struct net_device *to_dev; int ifindex; - int err; ifindex = tcf_mirred_ifindex(a); to_dev = __dev_get_by_index(net, ifindex); @@ -1195,30 +1193,28 @@ mlxsw_sp_port_add_cls_matchall_mirror(struct mlxsw_sp_port *mlxsw_sp_port, if (!mlxsw_sp_port_dev_check(to_dev)) { netdev_err(mlxsw_sp_port->dev, "Cannot mirror to a non-spectrum port"); - return -ENOTSUPP; + return -EOPNOTSUPP; } to_port = netdev_priv(to_dev); - mall_tc_entry = kzalloc(sizeof(*mall_tc_entry), GFP_KERNEL); - if (!mall_tc_entry) - return -ENOMEM; - - mall_tc_entry->cookie = cls->cookie; - mall_tc_entry->type = MLXSW_SP_PORT_MALL_MIRROR; - mall_tc_entry->mirror.to_local_port = to_port->local_port; - mall_tc_entry->mirror.ingress = ingress; - list_add_tail(&mall_tc_entry->list, &mlxsw_sp_port->mall_tc_list); - + mirror->to_local_port = to_port->local_port; + mirror->ingress = ingress; span_type = ingress ? MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS; - err = mlxsw_sp_span_mirror_add(mlxsw_sp_port, to_port, span_type); - if (err) - goto err_mirror_add; - return 0; + return mlxsw_sp_span_mirror_add(mlxsw_sp_port, to_port, span_type); +} -err_mirror_add: - list_del(&mall_tc_entry->list); - kfree(mall_tc_entry); - return err; +static void +mlxsw_sp_port_del_cls_matchall_mirror(struct mlxsw_sp_port *mlxsw_sp_port, + struct mlxsw_sp_port_mall_mirror_tc_entry *mirror) +{ + struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; + enum mlxsw_sp_span_type span_type; + struct mlxsw_sp_port *to_port; + + to_port = mlxsw_sp->ports[mirror->to_local_port]; + span_type = mirror->ingress ? + MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS; + mlxsw_sp_span_mirror_remove(mlxsw_sp_port, to_port, span_type); } static int mlxsw_sp_port_add_cls_matchall(struct mlxsw_sp_port *mlxsw_sp_port, @@ -1226,59 +1222,68 @@ static int mlxsw_sp_port_add_cls_matchall(struct mlxsw_sp_port *mlxsw_sp_port, struct tc_cls_matchall_offload *cls, bool ingress) { + struct mlxsw_sp_port_mall_tc_entry *mall_tc_entry; const struct tc_action *a; LIST_HEAD(actions); int err; if (!tc_single_action(cls->exts)) { netdev_err(mlxsw_sp_port->dev, "only singular actions are supported\n"); - return -ENOTSUPP; + return -EOPNOTSUPP; } + mall_tc_entry = kzalloc(sizeof(*mall_tc_entry), GFP_KERNEL); + if (!mall_tc_entry) + return -ENOMEM; + mall_tc_entry->cookie = cls->cookie; + tcf_exts_to_list(cls->exts, &actions); - list_for_each_entry(a, &actions, list) { - if (!is_tcf_mirred_egress_mirror(a) || - protocol != htons(ETH_P_ALL)) { - return -ENOTSUPP; - } + a = list_first_entry(&actions, struct tc_action, list); - err = mlxsw_sp_port_add_cls_matchall_mirror(mlxsw_sp_port, cls, - a, ingress); - if (err) - return err; + if (is_tcf_mirred_egress_mirror(a) && protocol == htons(ETH_P_ALL)) { + struct mlxsw_sp_port_mall_mirror_tc_entry *mirror; + + mall_tc_entry->type = MLXSW_SP_PORT_MALL_MIRROR; + mirror = &mall_tc_entry->mirror; + err = mlxsw_sp_port_add_cls_matchall_mirror(mlxsw_sp_port, + mirror, a, ingress); + } else { + err = -EOPNOTSUPP; } + if (err) + goto err_add_action; + + list_add_tail(&mall_tc_entry->list, &mlxsw_sp_port->mall_tc_list); return 0; + +err_add_action: + kfree(mall_tc_entry); + return err; } static void mlxsw_sp_port_del_cls_matchall(struct mlxsw_sp_port *mlxsw_sp_port, struct tc_cls_matchall_offload *cls) { - struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; struct mlxsw_sp_port_mall_tc_entry *mall_tc_entry; - enum mlxsw_sp_span_type span_type; - struct mlxsw_sp_port *to_port; - mall_tc_entry = mlxsw_sp_port_mirror_entry_find(mlxsw_sp_port, - cls->cookie); + mall_tc_entry = mlxsw_sp_port_mall_tc_entry_find(mlxsw_sp_port, + cls->cookie); if (!mall_tc_entry) { netdev_dbg(mlxsw_sp_port->dev, "tc entry not found on port\n"); return; } + list_del(&mall_tc_entry->list); switch (mall_tc_entry->type) { case MLXSW_SP_PORT_MALL_MIRROR: - to_port = mlxsw_sp->ports[mall_tc_entry->mirror.to_local_port]; - span_type = mall_tc_entry->mirror.ingress ? - MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS; - - mlxsw_sp_span_mirror_remove(mlxsw_sp_port, to_port, span_type); + mlxsw_sp_port_del_cls_matchall_mirror(mlxsw_sp_port, + &mall_tc_entry->mirror); break; default: WARN_ON(1); } - list_del(&mall_tc_entry->list); kfree(mall_tc_entry); } @@ -1304,7 +1309,7 @@ static int mlxsw_sp_setup_tc(struct net_device *dev, u32 handle, } } - return -ENOTSUPP; + return -EOPNOTSUPP; } static const struct net_device_ops mlxsw_sp_port_netdev_ops = { @@ -1647,7 +1652,7 @@ mlxsw_sp_get_hw_stats_by_group(struct mlxsw_sp_port_hw_stats **p_hw_stats, break; default: WARN_ON(1); - return -ENOTSUPP; + return -EOPNOTSUPP; } return 0; } @@ -2426,8 +2431,8 @@ static void __mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port) mlxsw_sp_port_dcb_fini(mlxsw_sp_port); mlxsw_sp_port_swid_set(mlxsw_sp_port, MLXSW_PORT_SWID_DISABLED_PORT); mlxsw_sp_port_module_unmap(mlxsw_sp, mlxsw_sp_port->local_port); - free_percpu(mlxsw_sp_port->pcpu_stats); kfree(mlxsw_sp_port->hw_stats.cache); + free_percpu(mlxsw_sp_port->pcpu_stats); kfree(mlxsw_sp_port->untagged_vlans); kfree(mlxsw_sp_port->active_vlans); WARN_ON_ONCE(!list_empty(&mlxsw_sp_port->vports_list)); |