Commit 07e0e046 authored by David S. Miller's avatar David S. Miller

Merge branch 'mlxsw-small-driver-update'

Jiri Pirko says:

====================
mlxsw: small driver update

This patchset contains various small "non-net" fixes and enhancements.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents f89d21b9 e915ac68
...@@ -1132,12 +1132,12 @@ static inline int mlxsw_cmd_sw2hw_eq(struct mlxsw_core *mlxsw_core, ...@@ -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); 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. * When set, overrun ignore is enabled.
*/ */
MLXSW_ITEM32(cmd_mbox, sw2hw_eq, oi, 0x00, 12, 1); 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 * Event delivery state machine
* 0x0 - FIRED * 0x0 - FIRED
* 0x1 - ARMED (Request for Notification) * 0x1 - ARMED (Request for Notification)
...@@ -1146,19 +1146,19 @@ MLXSW_ITEM32(cmd_mbox, sw2hw_eq, oi, 0x00, 12, 1); ...@@ -1146,19 +1146,19 @@ MLXSW_ITEM32(cmd_mbox, sw2hw_eq, oi, 0x00, 12, 1);
*/ */
MLXSW_ITEM32(cmd_mbox, sw2hw_eq, st, 0x00, 8, 2); 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). * Log (base 2) of the EQ size (in entries).
*/ */
MLXSW_ITEM32(cmd_mbox, sw2hw_eq, log_eq_size, 0x00, 0, 4); 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 * Producer Counter. The counter is incremented for each EQE that is written
* by the HW to the EQ. * by the HW to the EQ.
* Maintained by HW (valid for the QUERY_EQ command only) * Maintained by HW (valid for the QUERY_EQ command only)
*/ */
MLXSW_ITEM32(cmd_mbox, sw2hw_eq, producer_counter, 0x04, 0, 16); MLXSW_ITEM32(cmd_mbox, sw2hw_eq, producer_counter, 0x04, 0, 16);
/* cmd_mbox_sw2hw_eq_int_pa /* cmd_mbox_sw2hw_eq_pa
* Physical Address. * Physical Address.
*/ */
MLXSW_ITEM64_INDEXED(cmd_mbox, sw2hw_eq, pa, 0x10, 11, 53, 0x08, 0x00, true); MLXSW_ITEM64_INDEXED(cmd_mbox, sw2hw_eq, pa, 0x10, 11, 53, 0x08, 0x00, true);
......
...@@ -338,7 +338,7 @@ mlxsw_i2c_write(struct device *dev, size_t in_mbox_size, u8 *in_mbox, int num, ...@@ -338,7 +338,7 @@ mlxsw_i2c_write(struct device *dev, size_t in_mbox_size, u8 *in_mbox, int num,
return -EIO; return -EIO;
} }
return err > 0 ? 0 : err; return 0;
} }
/* Routine executes I2C command. */ /* Routine executes I2C command. */
......
...@@ -1161,8 +1161,8 @@ static int mlxsw_sp_port_get_phys_port_name(struct net_device *dev, char *name, ...@@ -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 * static struct mlxsw_sp_port_mall_tc_entry *
mlxsw_sp_port_mirror_entry_find(struct mlxsw_sp_port *port, mlxsw_sp_port_mall_tc_entry_find(struct mlxsw_sp_port *port,
unsigned long cookie) { unsigned long cookie) {
struct mlxsw_sp_port_mall_tc_entry *mall_tc_entry; struct mlxsw_sp_port_mall_tc_entry *mall_tc_entry;
list_for_each_entry(mall_tc_entry, &port->mall_tc_list, list) 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, ...@@ -1174,17 +1174,15 @@ mlxsw_sp_port_mirror_entry_find(struct mlxsw_sp_port *port,
static int static int
mlxsw_sp_port_add_cls_matchall_mirror(struct mlxsw_sp_port *mlxsw_sp_port, 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, const struct tc_action *a,
bool ingress) bool ingress)
{ {
struct mlxsw_sp_port_mall_tc_entry *mall_tc_entry;
struct net *net = dev_net(mlxsw_sp_port->dev); struct net *net = dev_net(mlxsw_sp_port->dev);
enum mlxsw_sp_span_type span_type; enum mlxsw_sp_span_type span_type;
struct mlxsw_sp_port *to_port; struct mlxsw_sp_port *to_port;
struct net_device *to_dev; struct net_device *to_dev;
int ifindex; int ifindex;
int err;
ifindex = tcf_mirred_ifindex(a); ifindex = tcf_mirred_ifindex(a);
to_dev = __dev_get_by_index(net, ifindex); 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, ...@@ -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)) { if (!mlxsw_sp_port_dev_check(to_dev)) {
netdev_err(mlxsw_sp_port->dev, "Cannot mirror to a non-spectrum port"); netdev_err(mlxsw_sp_port->dev, "Cannot mirror to a non-spectrum port");
return -ENOTSUPP; return -EOPNOTSUPP;
} }
to_port = netdev_priv(to_dev); to_port = netdev_priv(to_dev);
mall_tc_entry = kzalloc(sizeof(*mall_tc_entry), GFP_KERNEL); mirror->to_local_port = to_port->local_port;
if (!mall_tc_entry) mirror->ingress = ingress;
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);
span_type = ingress ? MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS; span_type = ingress ? MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS;
err = 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);
if (err) }
goto err_mirror_add;
return 0;
err_mirror_add: static void
list_del(&mall_tc_entry->list); mlxsw_sp_port_del_cls_matchall_mirror(struct mlxsw_sp_port *mlxsw_sp_port,
kfree(mall_tc_entry); struct mlxsw_sp_port_mall_mirror_tc_entry *mirror)
return err; {
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, 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, ...@@ -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, struct tc_cls_matchall_offload *cls,
bool ingress) bool ingress)
{ {
struct mlxsw_sp_port_mall_tc_entry *mall_tc_entry;
const struct tc_action *a; const struct tc_action *a;
LIST_HEAD(actions); LIST_HEAD(actions);
int err; int err;
if (!tc_single_action(cls->exts)) { if (!tc_single_action(cls->exts)) {
netdev_err(mlxsw_sp_port->dev, "only singular actions are supported\n"); 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); tcf_exts_to_list(cls->exts, &actions);
list_for_each_entry(a, &actions, list) { a = list_first_entry(&actions, struct tc_action, list);
if (!is_tcf_mirred_egress_mirror(a) ||
protocol != htons(ETH_P_ALL)) {
return -ENOTSUPP;
}
err = mlxsw_sp_port_add_cls_matchall_mirror(mlxsw_sp_port, cls, if (is_tcf_mirred_egress_mirror(a) && protocol == htons(ETH_P_ALL)) {
a, ingress); struct mlxsw_sp_port_mall_mirror_tc_entry *mirror;
if (err)
return err; 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; 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, static void mlxsw_sp_port_del_cls_matchall(struct mlxsw_sp_port *mlxsw_sp_port,
struct tc_cls_matchall_offload *cls) 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; 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, mall_tc_entry = mlxsw_sp_port_mall_tc_entry_find(mlxsw_sp_port,
cls->cookie); cls->cookie);
if (!mall_tc_entry) { if (!mall_tc_entry) {
netdev_dbg(mlxsw_sp_port->dev, "tc entry not found on port\n"); netdev_dbg(mlxsw_sp_port->dev, "tc entry not found on port\n");
return; return;
} }
list_del(&mall_tc_entry->list);
switch (mall_tc_entry->type) { switch (mall_tc_entry->type) {
case MLXSW_SP_PORT_MALL_MIRROR: case MLXSW_SP_PORT_MALL_MIRROR:
to_port = mlxsw_sp->ports[mall_tc_entry->mirror.to_local_port]; mlxsw_sp_port_del_cls_matchall_mirror(mlxsw_sp_port,
span_type = mall_tc_entry->mirror.ingress ? &mall_tc_entry->mirror);
MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS;
mlxsw_sp_span_mirror_remove(mlxsw_sp_port, to_port, span_type);
break; break;
default: default:
WARN_ON(1); WARN_ON(1);
} }
list_del(&mall_tc_entry->list);
kfree(mall_tc_entry); kfree(mall_tc_entry);
} }
...@@ -1304,7 +1309,7 @@ static int mlxsw_sp_setup_tc(struct net_device *dev, u32 handle, ...@@ -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 = { 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, ...@@ -1647,7 +1652,7 @@ mlxsw_sp_get_hw_stats_by_group(struct mlxsw_sp_port_hw_stats **p_hw_stats,
break; break;
default: default:
WARN_ON(1); WARN_ON(1);
return -ENOTSUPP; return -EOPNOTSUPP;
} }
return 0; return 0;
} }
...@@ -2426,8 +2431,8 @@ static void __mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port) ...@@ -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_dcb_fini(mlxsw_sp_port);
mlxsw_sp_port_swid_set(mlxsw_sp_port, MLXSW_PORT_SWID_DISABLED_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); 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); kfree(mlxsw_sp_port->hw_stats.cache);
free_percpu(mlxsw_sp_port->pcpu_stats);
kfree(mlxsw_sp_port->untagged_vlans); kfree(mlxsw_sp_port->untagged_vlans);
kfree(mlxsw_sp_port->active_vlans); kfree(mlxsw_sp_port->active_vlans);
WARN_ON_ONCE(!list_empty(&mlxsw_sp_port->vports_list)); WARN_ON_ONCE(!list_empty(&mlxsw_sp_port->vports_list));
......
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