diff options
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlxsw/core.c')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/core.c | 143 |
1 files changed, 97 insertions, 46 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c index 866b9357939b..b13e0f8d232a 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core.c @@ -177,17 +177,6 @@ void *mlxsw_core_driver_priv(struct mlxsw_core *mlxsw_core) } EXPORT_SYMBOL(mlxsw_core_driver_priv); -bool mlxsw_core_res_query_enabled(const struct mlxsw_core *mlxsw_core) -{ - return mlxsw_core->driver->res_query_enabled; -} -EXPORT_SYMBOL(mlxsw_core_res_query_enabled); - -bool mlxsw_core_temp_warn_enabled(const struct mlxsw_core *mlxsw_core) -{ - return mlxsw_core->driver->temp_warn_enabled; -} - bool mlxsw_core_fw_rev_minor_subminor_validate(const struct mlxsw_fw_rev *rev, const struct mlxsw_fw_rev *req_rev) @@ -212,6 +201,32 @@ struct mlxsw_event_listener_item { void *priv; }; +static const u8 mlxsw_core_trap_groups[] = { + MLXSW_REG_HTGT_TRAP_GROUP_EMAD, + MLXSW_REG_HTGT_TRAP_GROUP_CORE_EVENT, +}; + +static int mlxsw_core_trap_groups_set(struct mlxsw_core *mlxsw_core) +{ + char htgt_pl[MLXSW_REG_HTGT_LEN]; + int err; + int i; + + if (!(mlxsw_core->bus->features & MLXSW_BUS_F_TXRX)) + return 0; + + for (i = 0; i < ARRAY_SIZE(mlxsw_core_trap_groups); i++) { + mlxsw_reg_htgt_pack(htgt_pl, mlxsw_core_trap_groups[i], + MLXSW_REG_HTGT_INVALID_POLICER, + MLXSW_REG_HTGT_DEFAULT_PRIORITY, + MLXSW_REG_HTGT_DEFAULT_TC); + err = mlxsw_reg_write(mlxsw_core, MLXSW_REG(htgt), htgt_pl); + if (err) + return err; + } + return 0; +} + /****************** * EMAD processing ******************/ @@ -777,16 +792,10 @@ static int mlxsw_emad_init(struct mlxsw_core *mlxsw_core) if (err) goto err_trap_register; - 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_trap_unregister(mlxsw_core, &mlxsw_emad_rx_listener, - mlxsw_core); err_trap_register: destroy_workqueue(mlxsw_core->emad_wq); return err; @@ -1208,36 +1217,37 @@ static void mlxsw_core_fw_params_unregister(struct mlxsw_core *mlxsw_core) ARRAY_SIZE(mlxsw_core_fw_devlink_params)); } +static void *__dl_port(struct devlink_port *devlink_port) +{ + return container_of(devlink_port, struct mlxsw_core_port, devlink_port); +} + static int mlxsw_devlink_port_split(struct devlink *devlink, - unsigned int port_index, + struct devlink_port *port, unsigned int count, struct netlink_ext_ack *extack) { + struct mlxsw_core_port *mlxsw_core_port = __dl_port(port); struct mlxsw_core *mlxsw_core = devlink_priv(devlink); - if (port_index >= mlxsw_core->max_ports) { - NL_SET_ERR_MSG_MOD(extack, "Port index exceeds maximum number of ports"); - return -EINVAL; - } if (!mlxsw_core->driver->port_split) return -EOPNOTSUPP; - return mlxsw_core->driver->port_split(mlxsw_core, port_index, count, - extack); + return mlxsw_core->driver->port_split(mlxsw_core, + mlxsw_core_port->local_port, + count, extack); } static int mlxsw_devlink_port_unsplit(struct devlink *devlink, - unsigned int port_index, + struct devlink_port *port, struct netlink_ext_ack *extack) { + struct mlxsw_core_port *mlxsw_core_port = __dl_port(port); struct mlxsw_core *mlxsw_core = devlink_priv(devlink); - if (port_index >= mlxsw_core->max_ports) { - NL_SET_ERR_MSG_MOD(extack, "Port index exceeds maximum number of ports"); - return -EINVAL; - } if (!mlxsw_core->driver->port_unsplit) return -EOPNOTSUPP; - return mlxsw_core->driver->port_unsplit(mlxsw_core, port_index, + return mlxsw_core->driver->port_unsplit(mlxsw_core, + mlxsw_core_port->local_port, extack); } @@ -1271,11 +1281,6 @@ mlxsw_devlink_sb_pool_set(struct devlink *devlink, extack); } -static void *__dl_port(struct devlink_port *devlink_port) -{ - return container_of(devlink_port, struct mlxsw_core_port, devlink_port); -} - static int mlxsw_devlink_port_type_set(struct devlink_port *devlink_port, enum devlink_port_type port_type) { @@ -1706,7 +1711,7 @@ static void mlxsw_core_health_listener_func(const struct mlxsw_reg_info *reg, } static const struct mlxsw_listener mlxsw_core_health_listener = - MLXSW_EVENTL(mlxsw_core_health_listener_func, MFDE, MFDE); + MLXSW_CORE_EVENTL(mlxsw_core_health_listener_func, MFDE); static int mlxsw_core_health_fw_fatal_dump_fatal_cause(const char *mfde_pl, @@ -2019,7 +2024,7 @@ static int mlxsw_core_health_init(struct mlxsw_core *mlxsw_core) struct devlink_health_reporter *fw_fatal; int err; - if (!mlxsw_core->driver->fw_fatal_enabled) + if (!(mlxsw_core->bus->features & MLXSW_BUS_F_TXRX)) return 0; fw_fatal = devlink_health_reporter_create(devlink, &mlxsw_core_health_fw_fatal_ops, @@ -2049,7 +2054,7 @@ err_trap_register: static void mlxsw_core_health_fini(struct mlxsw_core *mlxsw_core) { - if (!mlxsw_core->driver->fw_fatal_enabled) + if (!(mlxsw_core->bus->features & MLXSW_BUS_F_TXRX)) return; mlxsw_core_health_fw_fatal_config(mlxsw_core, false); @@ -2069,7 +2074,6 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, const char *device_kind = mlxsw_bus_info->device_kind; struct mlxsw_core *mlxsw_core; struct mlxsw_driver *mlxsw_driver; - struct mlxsw_res *res; size_t alloc_size; int err; @@ -2095,8 +2099,8 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, mlxsw_core->bus_priv = bus_priv; mlxsw_core->bus_info = mlxsw_bus_info; - res = mlxsw_driver->res_query_enabled ? &mlxsw_core->res : NULL; - err = mlxsw_bus->init(bus_priv, mlxsw_core, mlxsw_driver->profile, res); + err = mlxsw_bus->init(bus_priv, mlxsw_core, mlxsw_driver->profile, + &mlxsw_core->res); if (err) goto err_bus_init; @@ -2122,6 +2126,10 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, } } + err = mlxsw_core_trap_groups_set(mlxsw_core); + if (err) + goto err_trap_groups_set; + err = mlxsw_emad_init(mlxsw_core); if (err) goto err_emad_init; @@ -2181,6 +2189,7 @@ err_fw_rev_validate: err_register_params: mlxsw_emad_fini(mlxsw_core); err_emad_init: +err_trap_groups_set: kfree(mlxsw_core->lag.mapping); err_alloc_lag_mapping: mlxsw_ports_fini(mlxsw_core, reload); @@ -2500,6 +2509,9 @@ int mlxsw_core_trap_register(struct mlxsw_core *mlxsw_core, char hpkt_pl[MLXSW_REG_HPKT_LEN]; int err; + if (!(mlxsw_core->bus->features & MLXSW_BUS_F_TXRX)) + return 0; + err = mlxsw_core_listener_register(mlxsw_core, listener, priv, listener->enabled_on_register); if (err) @@ -2529,6 +2541,9 @@ void mlxsw_core_trap_unregister(struct mlxsw_core *mlxsw_core, { char hpkt_pl[MLXSW_REG_HPKT_LEN]; + if (!(mlxsw_core->bus->features & MLXSW_BUS_F_TXRX)) + return; + if (!listener->is_event) { mlxsw_reg_hpkt_pack(hpkt_pl, listener->dis_action, listener->trap_id, listener->dis_trap_group, @@ -2540,6 +2555,45 @@ void mlxsw_core_trap_unregister(struct mlxsw_core *mlxsw_core, } EXPORT_SYMBOL(mlxsw_core_trap_unregister); +int mlxsw_core_traps_register(struct mlxsw_core *mlxsw_core, + const struct mlxsw_listener *listeners, + size_t listeners_count, void *priv) +{ + int i, err; + + for (i = 0; i < listeners_count; i++) { + err = mlxsw_core_trap_register(mlxsw_core, + &listeners[i], + priv); + if (err) + goto err_listener_register; + } + return 0; + +err_listener_register: + for (i--; i >= 0; i--) { + mlxsw_core_trap_unregister(mlxsw_core, + &listeners[i], + priv); + } + return err; +} +EXPORT_SYMBOL(mlxsw_core_traps_register); + +void mlxsw_core_traps_unregister(struct mlxsw_core *mlxsw_core, + const struct mlxsw_listener *listeners, + size_t listeners_count, void *priv) +{ + int i; + + for (i = 0; i < listeners_count; i++) { + mlxsw_core_trap_unregister(mlxsw_core, + &listeners[i], + priv); + } +} +EXPORT_SYMBOL(mlxsw_core_traps_unregister); + int mlxsw_core_trap_state_set(struct mlxsw_core *mlxsw_core, const struct mlxsw_listener *listener, bool enabled) @@ -2925,7 +2979,7 @@ static int __mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u16 local_port, attrs.switch_id.id_len = switch_id_len; mlxsw_core_port->local_port = local_port; devlink_port_attrs_set(devlink_port, &attrs); - err = devlink_port_register(devlink, devlink_port, local_port); + err = devl_port_register(devlink, devlink_port, local_port); if (err) memset(mlxsw_core_port, 0, sizeof(*mlxsw_core_port)); return err; @@ -2937,7 +2991,7 @@ static void __mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u16 local_port &mlxsw_core->ports[local_port]; struct devlink_port *devlink_port = &mlxsw_core_port->devlink_port; - devlink_port_unregister(devlink_port); + devl_port_unregister(devlink_port); memset(mlxsw_core_port, 0, sizeof(*mlxsw_core_port)); } @@ -3181,9 +3235,6 @@ int mlxsw_core_resources_query(struct mlxsw_core *mlxsw_core, char *mbox, u16 id; int err; - if (!res) - return 0; - mlxsw_cmd_mbox_zero(mbox); for (index = 0; index < MLXSW_CMD_QUERY_RESOURCES_MAX_QUERIES; |