}
 EXPORT_SYMBOL(mlxsw_core_port_devlink_port_get);
 
+int mlxsw_core_module_max_width(struct mlxsw_core *mlxsw_core, u8 module)
+{
+       enum mlxsw_reg_pmtm_module_type module_type;
+       char pmtm_pl[MLXSW_REG_PMTM_LEN];
+       int err;
+
+       mlxsw_reg_pmtm_pack(pmtm_pl, module);
+       err = mlxsw_reg_query(mlxsw_core, MLXSW_REG(pmtm), pmtm_pl);
+       if (err)
+               return err;
+       mlxsw_reg_pmtm_unpack(pmtm_pl, &module_type);
+
+       /* Here we need to get the module width according to the module type. */
+
+       switch (module_type) {
+       case MLXSW_REG_PMTM_MODULE_TYPE_BP_4X: /* fall through */
+       case MLXSW_REG_PMTM_MODULE_TYPE_BP_QSFP:
+               return 4;
+       case MLXSW_REG_PMTM_MODULE_TYPE_BP_2X:
+               return 2;
+       case MLXSW_REG_PMTM_MODULE_TYPE_BP_SFP: /* fall through */
+       case MLXSW_REG_PMTM_MODULE_TYPE_BP_1X:
+               return 1;
+       default:
+               return -EINVAL;
+       }
+}
+EXPORT_SYMBOL(mlxsw_core_module_max_width);
+
 static void mlxsw_core_buf_dump_dbg(struct mlxsw_core *mlxsw_core,
                                    const char *buf, size_t size)
 {
 
        return err;
 }
 
-static u8 mlxsw_sp_cluster_base_port_get(u8 local_port)
+static u8 mlxsw_sp_cluster_base_port_get(u8 local_port, unsigned int max_width)
 {
-       u8 offset = (local_port - 1) % MLXSW_SP_PORTS_PER_CLUSTER_MAX;
+       u8 offset = (local_port - 1) % max_width;
 
        return local_port - offset;
 }
 
 static int mlxsw_sp_port_split_create(struct mlxsw_sp *mlxsw_sp, u8 base_port,
-                                     u8 module, unsigned int count, u8 offset)
+                                     u8 module, unsigned int count, u8 offset,
+                                     unsigned int max_width)
 {
-       u8 width = MLXSW_PORT_MODULE_MAX_WIDTH / count;
+       u8 width = max_width / count;
        int err, i;
 
        for (i = 0; i < count; i++) {
 }
 
 static void mlxsw_sp_port_unsplit_create(struct mlxsw_sp *mlxsw_sp,
-                                        u8 base_port, unsigned int count)
+                                        u8 base_port, unsigned int count,
+                                        unsigned int max_width)
 {
-       u8 local_port, module, width = MLXSW_PORT_MODULE_MAX_WIDTH;
+       u8 local_port, module, width = max_width;
        int i;
 
        /* Split by four means we need to re-create two ports, otherwise
        struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
        u8 local_ports_in_1x, local_ports_in_2x, offset;
        struct mlxsw_sp_port *mlxsw_sp_port;
-       u8 module, cur_width, base_port;
+       u8 module, base_port;
+       int max_width;
        int i;
        int err;
 
        }
 
        module = mlxsw_sp_port->mapping.module;
-       cur_width = mlxsw_sp_port->mapping.width;
+
+       max_width = mlxsw_core_module_max_width(mlxsw_core,
+                                               mlxsw_sp_port->mapping.module);
+       if (max_width < 0) {
+               netdev_err(mlxsw_sp_port->dev, "Cannot get max width of port module\n");
+               NL_SET_ERR_MSG_MOD(extack, "Cannot get max width of port module");
+               return max_width;
+       }
 
        if (count != 2 && count != 4) {
                netdev_err(mlxsw_sp_port->dev, "Port can only be split into 2 or 4 ports\n");
                return -EINVAL;
        }
 
-       if (cur_width != MLXSW_PORT_MODULE_MAX_WIDTH) {
+       /* Split port with non-max module width cannot be split. */
+       if (mlxsw_sp_port->mapping.width != max_width) {
                netdev_err(mlxsw_sp_port->dev, "Port cannot be split further\n");
                NL_SET_ERR_MSG_MOD(extack, "Port cannot be split further");
                return -EINVAL;
                }
        } else {
                offset = local_ports_in_1x;
-               base_port = mlxsw_sp_cluster_base_port_get(local_port);
+               base_port = mlxsw_sp_cluster_base_port_get(local_port,
+                                                          max_width);
                if (mlxsw_sp->ports[base_port + 1] ||
                    mlxsw_sp->ports[base_port + 3]) {
                        netdev_err(mlxsw_sp_port->dev, "Invalid split configuration\n");
                        mlxsw_sp_port_remove(mlxsw_sp, base_port + i * offset);
 
        err = mlxsw_sp_port_split_create(mlxsw_sp, base_port, module, count,
-                                        offset);
+                                        offset, max_width);
        if (err) {
                dev_err(mlxsw_sp->bus_info->dev, "Failed to create split ports\n");
                goto err_port_split_create;
        return 0;
 
 err_port_split_create:
-       mlxsw_sp_port_unsplit_create(mlxsw_sp, base_port, count);
+       mlxsw_sp_port_unsplit_create(mlxsw_sp, base_port, count, max_width);
        return err;
 }
 
        struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
        u8 local_ports_in_1x, local_ports_in_2x, offset;
        struct mlxsw_sp_port *mlxsw_sp_port;
-       u8 cur_width, base_port;
        unsigned int count;
+       int max_width;
+       u8 base_port;
        int i;
 
        if (!MLXSW_CORE_RES_VALID(mlxsw_core, LOCAL_PORTS_IN_1X) ||
                return -EINVAL;
        }
 
-       cur_width = mlxsw_sp_port->mapping.width;
-       count = cur_width == 1 ? 4 : 2;
+       max_width = mlxsw_core_module_max_width(mlxsw_core,
+                                               mlxsw_sp_port->mapping.module);
+       if (max_width < 0) {
+               netdev_err(mlxsw_sp_port->dev, "Cannot get max width of port module\n");
+               NL_SET_ERR_MSG_MOD(extack, "Cannot get max width of port module");
+               return max_width;
+       }
+
+       count = max_width / mlxsw_sp_port->mapping.width;
 
        if (count == 2)
                offset = local_ports_in_2x;
        else
                offset = local_ports_in_1x;
 
-       base_port = mlxsw_sp_cluster_base_port_get(local_port);
+       base_port = mlxsw_sp_cluster_base_port_get(local_port, max_width);
 
        /* Determine which ports to remove. */
        if (count == 2 && local_port >= base_port + 2)
                if (mlxsw_sp_port_created(mlxsw_sp, base_port + i * offset))
                        mlxsw_sp_port_remove(mlxsw_sp, base_port + i * offset);
 
-       mlxsw_sp_port_unsplit_create(mlxsw_sp, base_port, count);
+       mlxsw_sp_port_unsplit_create(mlxsw_sp, base_port, count, max_width);
 
        return 0;
 }