mlxsw_m
mlxsw_m->bus_info->fw_rev.subminor);
strscpy(drvinfo->bus_info, mlxsw_m->bus_info->device_name,
struct mlxsw_core *core = mlxsw_m_port->mlxsw_m->core;
struct mlxsw_core *core = mlxsw_m_port->mlxsw_m->core;
struct mlxsw_core *core = mlxsw_m_port->mlxsw_m->core;
struct mlxsw_core *core = mlxsw_m_port->mlxsw_m->core;
struct mlxsw_core *core = mlxsw_m_port->mlxsw_m->core;
struct mlxsw_core *core = mlxsw_m_port->mlxsw_m->core;
struct mlxsw_core *core = mlxsw_m_port->mlxsw_m->core;
mlxsw_m_port_module_info_get(struct mlxsw_m *mlxsw_m, u16 local_port,
err = mlxsw_reg_query(mlxsw_m->core, MLXSW_REG(pmlp), pmlp_pl);
struct mlxsw_m *mlxsw_m = mlxsw_m_port->mlxsw_m;
err = mlxsw_reg_query(mlxsw_m->core, MLXSW_REG(ppad), ppad_pl);
static bool mlxsw_m_port_created(struct mlxsw_m *mlxsw_m, u16 local_port)
return mlxsw_m->ports[local_port];
mlxsw_m_port_create(struct mlxsw_m *mlxsw_m, u16 local_port, u8 slot_index,
err = mlxsw_core_port_init(mlxsw_m->core, local_port, slot_index,
0, mlxsw_m->base_mac,
sizeof(mlxsw_m->base_mac));
dev_err(mlxsw_m->bus_info->dev, "Port %d: Failed to init core port\n",
SET_NETDEV_DEV(dev, mlxsw_m->bus_info->dev);
dev_net_set(dev, mlxsw_core_net(mlxsw_m->core));
mlxsw_core_port_netdev_link(mlxsw_m->core, local_port,
mlxsw_m_port->mlxsw_m = mlxsw_m;
mlxsw_m->max_modules_per_slot : 0;
dev_err(mlxsw_m->bus_info->dev, "Port %d: Unable to get port mac address\n",
mlxsw_m->ports[local_port] = mlxsw_m_port;
dev_err(mlxsw_m->bus_info->dev, "Port %d: Failed to register netdev\n",
mlxsw_m->ports[local_port] = NULL;
mlxsw_core_port_fini(mlxsw_m->core, local_port);
static void mlxsw_m_port_remove(struct mlxsw_m *mlxsw_m, u16 local_port)
struct mlxsw_m_port *mlxsw_m_port = mlxsw_m->ports[local_port];
mlxsw_m->ports[local_port] = NULL;
mlxsw_core_port_fini(mlxsw_m->core, local_port);
mlxsw_m_port_mapping_get(struct mlxsw_m *mlxsw_m, u8 slot_index, u8 module)
return &mlxsw_m->line_cards[slot_index]->module_to_port[module];
static int mlxsw_m_port_module_map(struct mlxsw_m *mlxsw_m, u16 local_port,
unsigned int max_ports = mlxsw_core_max_ports(mlxsw_m->core);
err = mlxsw_m_port_module_info_get(mlxsw_m, local_port, &module,
if (mlxsw_m->line_cards[slot_index]->active)
mlxsw_env_module_port_map(mlxsw_m->core, slot_index, module);
module_to_port = mlxsw_m_port_mapping_get(mlxsw_m, slot_index, module);
mlxsw_m_port_module_unmap(struct mlxsw_m *mlxsw_m, u8 slot_index, u8 module)
int *module_to_port = mlxsw_m_port_mapping_get(mlxsw_m, slot_index,
mlxsw_env_module_port_unmap(mlxsw_m->core, slot_index, module);
static int mlxsw_m_linecards_init(struct mlxsw_m *mlxsw_m)
unsigned int max_ports = mlxsw_core_max_ports(mlxsw_m->core);
err = mlxsw_reg_query(mlxsw_m->core, MLXSW_REG(mgpir), mgpir_pl);
&mlxsw_m->num_of_slots);
if (mlxsw_m->num_of_slots)
mlxsw_m->max_modules_per_slot =
mlxsw_m->max_modules_per_slot = num_of_modules;
mlxsw_m->num_of_slots += 1;
mlxsw_m->ports = kzalloc_objs(*mlxsw_m->ports, max_ports);
if (!mlxsw_m->ports)
mlxsw_m->line_cards = kzalloc_objs(*mlxsw_m->line_cards,
mlxsw_m->num_of_slots);
if (!mlxsw_m->line_cards) {
for (i = 0; i < mlxsw_m->num_of_slots; i++) {
mlxsw_m->line_cards[i] =
kzalloc_flex(*mlxsw_m->line_cards[i], module_to_port,
mlxsw_m->max_modules_per_slot);
if (!mlxsw_m->line_cards[i]) {
for (j = 0; j < mlxsw_m->max_modules_per_slot; j++)
mlxsw_m->line_cards[i]->module_to_port[j] = -1;
kfree(mlxsw_m->line_cards[i]);
kfree(mlxsw_m->line_cards);
kfree(mlxsw_m->ports);
static void mlxsw_m_linecards_fini(struct mlxsw_m *mlxsw_m)
int i = mlxsw_m->num_of_slots;
kfree(mlxsw_m->line_cards[i]);
kfree(mlxsw_m->line_cards);
kfree(mlxsw_m->ports);
mlxsw_m_linecard_port_module_unmap(struct mlxsw_m *mlxsw_m, u8 slot_index)
for (i = mlxsw_m->max_modules_per_slot - 1; i >= 0; i--) {
module_to_port = mlxsw_m_port_mapping_get(mlxsw_m, slot_index, i);
mlxsw_m_port_module_unmap(mlxsw_m, slot_index, i);
struct mlxsw_m *mlxsw_m;
mlxsw_m_linecard_ports_create(struct mlxsw_m *mlxsw_m, u8 slot_index)
for (i = 0; i < mlxsw_m->max_modules_per_slot; i++) {
module_to_port = mlxsw_m_port_mapping_get(mlxsw_m, slot_index, i);
err = mlxsw_m_port_create(mlxsw_m, *module_to_port,
if (!mlxsw_m->line_cards[slot_index]->active)
mlxsw_m->line_cards[slot_index]->active = true;
module_to_port = mlxsw_m_port_mapping_get(mlxsw_m, slot_index, i);
mlxsw_m_port_created(mlxsw_m, *module_to_port)) {
mlxsw_m_port_remove(mlxsw_m, *module_to_port);
if (mlxsw_m->line_cards[slot_index]->active)
mlxsw_m->line_cards[slot_index]->active = false;
mlxsw_m_linecard_ports_remove(struct mlxsw_m *mlxsw_m, u8 slot_index)
for (i = 0; i < mlxsw_m->max_modules_per_slot; i++) {
int *module_to_port = mlxsw_m_port_mapping_get(mlxsw_m,
mlxsw_m_port_created(mlxsw_m, *module_to_port)) {
mlxsw_m_port_remove(mlxsw_m, *module_to_port);
mlxsw_m_port_module_unmap(mlxsw_m, slot_index, i);
static int mlxsw_m_ports_module_map(struct mlxsw_m *mlxsw_m)
unsigned int max_ports = mlxsw_core_max_ports(mlxsw_m->core);
err = mlxsw_m_port_module_map(mlxsw_m, i, &last_module);
static int mlxsw_m_ports_create(struct mlxsw_m *mlxsw_m)
static int mlxsw_m_base_mac_get(struct mlxsw_m *mlxsw_m)
err = mlxsw_m_ports_module_map(mlxsw_m);
err = mlxsw_m_linecard_ports_create(mlxsw_m, 0);
mlxsw_m_linecard_port_module_unmap(mlxsw_m, 0);
static void mlxsw_m_ports_remove(struct mlxsw_m *mlxsw_m)
mlxsw_m_linecard_ports_remove(mlxsw_m, 0);
struct mlxsw_m *mlxsw_m = mlxsw_core_driver_priv(mlxsw_core);
linecard = mlxsw_m->line_cards[linecard_priv->slot_index];
mlxsw_m_linecard_ports_remove(mlxsw_m, linecard_priv->slot_index);
static int mlxsw_m_fw_rev_validate(struct mlxsw_m *mlxsw_m)
const struct mlxsw_fw_rev *rev = &mlxsw_m->bus_info->fw_rev;
err = mlxsw_reg_query(mlxsw_m->core, MLXSW_REG(spad), spad_pl);
dev_err(mlxsw_m->bus_info->dev, "The firmware version %d.%d.%d is incompatible with the driver (required >= %d.%d.%d)\n",
struct mlxsw_m *mlxsw_m = priv;
linecard = mlxsw_m->line_cards[slot_index];
err = mlxsw_m_ports_module_map(mlxsw_m);
err = mlxsw_m_linecard_ports_create(mlxsw_m, slot_index);
mlxsw_reg_spad_base_mac_memcpy_from(spad_pl, mlxsw_m->base_mac);
dev_err(mlxsw_m->bus_info->dev, "Failed to create port for line card at slot %d\n",
mlxsw_m_linecard_port_module_unmap(mlxsw_m, slot_index);
struct mlxsw_m *mlxsw_m = priv;
linecard = mlxsw_m->line_cards[slot_index];
mlxsw_m_linecard_ports_remove(mlxsw_m, slot_index);
struct mlxsw_m *mlxsw_m = mlxsw_core_driver_priv(mlxsw_core);
mlxsw_m->core = mlxsw_core;
mlxsw_m->bus_info = mlxsw_bus_info;
err = mlxsw_m_fw_rev_validate(mlxsw_m);
err = mlxsw_m_base_mac_get(mlxsw_m);
dev_err(mlxsw_m->bus_info->dev, "Failed to get base mac\n");
err = mlxsw_m_linecards_init(mlxsw_m);
dev_err(mlxsw_m->bus_info->dev, "Failed to create line cards\n");
&mlxsw_m_event_ops, mlxsw_m);
dev_err(mlxsw_m->bus_info->dev, "Failed to register line cards operations\n");
err = mlxsw_m_ports_create(mlxsw_m);
dev_err(mlxsw_m->bus_info->dev, "Failed to create ports\n");
struct mlxsw_m *mlxsw_m = mlxsw_m_port->mlxsw_m;
&mlxsw_m_event_ops, mlxsw_m);
mlxsw_m_linecards_fini(mlxsw_m);
struct mlxsw_m *mlxsw_m = mlxsw_core_driver_priv(mlxsw_core);
mlxsw_m_ports_remove(mlxsw_m);
&mlxsw_m_event_ops, mlxsw_m);
return mlxsw_env_module_port_up(mlxsw_m->core, 0,
mlxsw_m_linecards_fini(mlxsw_m);
.priv_size = sizeof(struct mlxsw_m),
struct mlxsw_m *mlxsw_m = mlxsw_m_port->mlxsw_m;
mlxsw_env_module_port_down(mlxsw_m->core, 0, mlxsw_m_port->module);
struct mlxsw_m *mlxsw_m = mlxsw_m_port->mlxsw_m;
strscpy(drvinfo->driver, mlxsw_m->bus_info->device_kind,
mlxsw_m->bus_info->fw_rev.major,
mlxsw_m->bus_info->fw_rev.minor,