struct mlxsw_m_port;
 
+struct mlxsw_m_line_card {
+       bool active;
+       int module_to_port[];
+};
+
 struct mlxsw_m {
        struct mlxsw_m_port **ports;
-       int *module_to_port;
        struct mlxsw_core *core;
        const struct mlxsw_bus_info *bus_info;
        u8 base_mac[ETH_ALEN];
        u8 max_ports;
+       u8 max_modules_per_slot; /* Maximum number of modules per-slot. */
+       u8 num_of_slots; /* Including the main board. */
+       struct mlxsw_m_line_card **line_cards;
 };
 
 struct mlxsw_m_port {
 
 static int
 mlxsw_m_port_module_info_get(struct mlxsw_m *mlxsw_m, u16 local_port,
-                            u8 *p_module, u8 *p_width)
+                            u8 *p_module, u8 *p_width, u8 *p_slot_index)
 {
        char pmlp_pl[MLXSW_REG_PMLP_LEN];
        int err;
                return err;
        *p_module = mlxsw_reg_pmlp_module_get(pmlp_pl, 0);
        *p_width = mlxsw_reg_pmlp_width_get(pmlp_pl);
+       *p_slot_index = mlxsw_reg_pmlp_slot_index_get(pmlp_pl, 0);
 
        return 0;
 }
        return 0;
 }
 
+static bool mlxsw_m_port_created(struct mlxsw_m *mlxsw_m, u16 local_port)
+{
+       return mlxsw_m->ports[local_port];
+}
+
 static int
 mlxsw_m_port_create(struct mlxsw_m *mlxsw_m, u16 local_port, u8 slot_index,
                    u8 module)
        mlxsw_core_port_fini(mlxsw_m->core, local_port);
 }
 
+static int*
+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,
                                   u8 *last_module)
 {
        unsigned int max_ports = mlxsw_core_max_ports(mlxsw_m->core);
-       u8 module, width;
+       u8 module, width, slot_index;
+       int *module_to_port;
        int err;
 
        /* Fill out to local port mapping array */
        err = mlxsw_m_port_module_info_get(mlxsw_m, local_port, &module,
-                                          &width);
+                                          &width, &slot_index);
        if (err)
                return err;
 
 
        if (WARN_ON_ONCE(module >= max_ports))
                return -EINVAL;
-       mlxsw_env_module_port_map(mlxsw_m->core, 0, module);
-       mlxsw_m->module_to_port[module] = ++mlxsw_m->max_ports;
+       mlxsw_env_module_port_map(mlxsw_m->core, slot_index, module);
+       module_to_port = mlxsw_m_port_mapping_get(mlxsw_m, slot_index, module);
+       *module_to_port = local_port;
 
        return 0;
 }
 static void
 mlxsw_m_port_module_unmap(struct mlxsw_m *mlxsw_m, u8 slot_index, u8 module)
 {
-       mlxsw_m->module_to_port[module] = -1;
+       int *module_to_port = mlxsw_m_port_mapping_get(mlxsw_m, slot_index,
+                                                      module);
+       *module_to_port = -1;
        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);
-       int i, err;
+       char mgpir_pl[MLXSW_REG_MGPIR_LEN];
+       u8 num_of_modules;
+       int i, j, err;
+
+       mlxsw_reg_mgpir_pack(mgpir_pl, 0);
+       err = mlxsw_reg_query(mlxsw_m->core, MLXSW_REG(mgpir), mgpir_pl);
+       if (err)
+               return err;
+
+       mlxsw_reg_mgpir_unpack(mgpir_pl, NULL, NULL, NULL, &num_of_modules,
+                              &mlxsw_m->num_of_slots);
+       /* If the system is modular, get the maximum number of modules per-slot.
+        * Otherwise, get the maximum number of modules on the main board.
+        */
+       if (mlxsw_m->num_of_slots)
+               mlxsw_m->max_modules_per_slot =
+                       mlxsw_reg_mgpir_max_modules_per_slot_get(mgpir_pl);
+       else
+               mlxsw_m->max_modules_per_slot = num_of_modules;
+       /* Add slot for main board. */
+       mlxsw_m->num_of_slots += 1;
 
        mlxsw_m->ports = kcalloc(max_ports, sizeof(*mlxsw_m->ports),
                                 GFP_KERNEL);
        if (!mlxsw_m->ports)
                return -ENOMEM;
 
-       mlxsw_m->module_to_port = kmalloc_array(max_ports, sizeof(int),
-                                               GFP_KERNEL);
-       if (!mlxsw_m->module_to_port) {
-               err = -ENOMEM;
-               goto err_module_to_port_alloc;
+       mlxsw_m->line_cards = kcalloc(mlxsw_m->num_of_slots,
+                                     sizeof(*mlxsw_m->line_cards),
+                                     GFP_KERNEL);
+       if (!mlxsw_m->line_cards)
+               goto err_kcalloc;
+
+       for (i = 0; i < mlxsw_m->num_of_slots; i++) {
+               mlxsw_m->line_cards[i] =
+                       kzalloc(struct_size(mlxsw_m->line_cards[i],
+                                           module_to_port,
+                                           mlxsw_m->max_modules_per_slot),
+                               GFP_KERNEL);
+               if (!mlxsw_m->line_cards[i])
+                       goto err_kmalloc_array;
+
+               /* Invalidate the entries of module to local port mapping array. */
+               for (j = 0; j < mlxsw_m->max_modules_per_slot; j++)
+                       mlxsw_m->line_cards[i]->module_to_port[j] = -1;
        }
 
-       /* Invalidate the entries of module to local port mapping array */
-       for (i = 0; i < max_ports; i++)
-               mlxsw_m->module_to_port[i] = -1;
-
        return 0;
 
-err_module_to_port_alloc:
+err_kmalloc_array:
+       for (i--; i >= 0; i--)
+               kfree(mlxsw_m->line_cards[i]);
+err_kcalloc:
        kfree(mlxsw_m->ports);
        return err;
 }
 
 static void mlxsw_m_linecards_fini(struct mlxsw_m *mlxsw_m)
 {
-       kfree(mlxsw_m->module_to_port);
+       int i = mlxsw_m->num_of_slots;
+
+       for (i--; i >= 0; i--)
+               kfree(mlxsw_m->line_cards[i]);
+       kfree(mlxsw_m->line_cards);
        kfree(mlxsw_m->ports);
 }
 
-static int mlxsw_m_ports_create(struct mlxsw_m *mlxsw_m)
+static void
+mlxsw_m_linecard_port_module_unmap(struct mlxsw_m *mlxsw_m, u8 slot_index)
 {
-       unsigned int max_ports = mlxsw_core_max_ports(mlxsw_m->core);
-       u8 last_module = max_ports;
        int i;
-       int err;
 
-       /* Fill out module to local port mapping array */
-       for (i = 1; i < max_ports; i++) {
-               err = mlxsw_m_port_module_map(mlxsw_m, i, &last_module);
-               if (err)
-                       goto err_module_to_port_map;
+       for (i = mlxsw_m->max_modules_per_slot - 1; i >= 0; i--) {
+               int *module_to_port;
+
+               module_to_port = mlxsw_m_port_mapping_get(mlxsw_m, slot_index, i);
+               if (*module_to_port > 0)
+                       mlxsw_m_port_module_unmap(mlxsw_m, slot_index, i);
        }
+}
 
-       /* Create port objects for each valid entry */
-       for (i = 0; i < mlxsw_m->max_ports; i++) {
-               if (mlxsw_m->module_to_port[i] > 0) {
-                       err = mlxsw_m_port_create(mlxsw_m,
-                                                 mlxsw_m->module_to_port[i],
-                                                 0, i);
+static int
+mlxsw_m_linecard_ports_create(struct mlxsw_m *mlxsw_m, u8 slot_index)
+{
+       int *module_to_port;
+       int i, err;
+
+       for (i = 0; i < mlxsw_m->max_modules_per_slot; i++) {
+               module_to_port = mlxsw_m_port_mapping_get(mlxsw_m, slot_index, i);
+               if (*module_to_port > 0) {
+                       err = mlxsw_m_port_create(mlxsw_m, *module_to_port,
+                                                 slot_index, i);
                        if (err)
-                               goto err_module_to_port_create;
+                               goto err_port_create;
+                       /* Mark slot as active */
+                       if (!mlxsw_m->line_cards[slot_index]->active)
+                               mlxsw_m->line_cards[slot_index]->active = true;
                }
        }
-
        return 0;
 
-err_module_to_port_create:
+err_port_create:
        for (i--; i >= 0; i--) {
-               if (mlxsw_m->module_to_port[i] > 0)
-                       mlxsw_m_port_remove(mlxsw_m,
-                                           mlxsw_m->module_to_port[i]);
+               module_to_port = mlxsw_m_port_mapping_get(mlxsw_m, slot_index, i);
+               if (*module_to_port > 0 &&
+                   mlxsw_m_port_created(mlxsw_m, *module_to_port)) {
+                       mlxsw_m_port_remove(mlxsw_m, *module_to_port);
+                       /* Mark slot as inactive */
+                       if (mlxsw_m->line_cards[slot_index]->active)
+                               mlxsw_m->line_cards[slot_index]->active = false;
+               }
        }
-       i = max_ports;
-err_module_to_port_map:
-       for (i--; i > 0; i--)
-               mlxsw_m_port_module_unmap(mlxsw_m, 0, i);
        return err;
 }
 
-static void mlxsw_m_ports_remove(struct mlxsw_m *mlxsw_m)
+static void
+mlxsw_m_linecard_ports_remove(struct mlxsw_m *mlxsw_m, u8 slot_index)
 {
        int i;
 
-       for (i = 0; i < mlxsw_m->max_ports; i++) {
-               if (mlxsw_m->module_to_port[i] > 0) {
-                       mlxsw_m_port_remove(mlxsw_m,
-                                           mlxsw_m->module_to_port[i]);
-                       mlxsw_m_port_module_unmap(mlxsw_m, 0, i);
+       for (i = 0; i < mlxsw_m->max_modules_per_slot; i++) {
+               int *module_to_port = mlxsw_m_port_mapping_get(mlxsw_m,
+                                                              slot_index, i);
+
+               if (*module_to_port > 0 &&
+                   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);
                }
        }
+}
 
-       kfree(mlxsw_m->module_to_port);
-       kfree(mlxsw_m->ports);
+static int mlxsw_m_ports_module_map(struct mlxsw_m *mlxsw_m)
+{
+       unsigned int max_ports = mlxsw_core_max_ports(mlxsw_m->core);
+       u8 last_module = max_ports;
+       int i, err;
+
+       for (i = 1; i < max_ports; i++) {
+               err = mlxsw_m_port_module_map(mlxsw_m, i, &last_module);
+               if (err)
+                       return err;
+       }
+
+       return 0;
+}
+
+static int mlxsw_m_ports_create(struct mlxsw_m *mlxsw_m)
+{
+       int err;
+
+       /* Fill out module to local port mapping array */
+       err = mlxsw_m_ports_module_map(mlxsw_m);
+       if (err)
+               goto err_ports_module_map;
+
+       /* Create port objects for each valid entry */
+       err = mlxsw_m_linecard_ports_create(mlxsw_m, 0);
+       if (err)
+               goto err_linecard_ports_create;
+
+       return 0;
+
+err_linecard_ports_create:
+err_ports_module_map:
+       mlxsw_m_linecard_port_module_unmap(mlxsw_m, 0);
+
+       return err;
+}
+
+static void mlxsw_m_ports_remove(struct mlxsw_m *mlxsw_m)
+{
+       mlxsw_m_linecard_ports_remove(mlxsw_m, 0);
 }
 
 static int mlxsw_m_fw_rev_validate(struct mlxsw_m *mlxsw_m)