__func__, __LINE__);
                return -1;
        }
+       instance->balanced_mode = false;
+       instance->low_latency_index_start = 0;
        return 0;
 }
 
 static void megasas_setup_reply_map(struct megasas_instance *instance)
 {
        const struct cpumask *mask;
-       unsigned int queue, cpu;
+       unsigned int queue, cpu, low_latency_index_start;
 
-       for (queue = 0; queue < instance->msix_vectors; queue++) {
+       low_latency_index_start = instance->low_latency_index_start;
+
+       for (queue = low_latency_index_start; queue < instance->msix_vectors; queue++) {
                mask = pci_irq_get_affinity(instance->pdev, queue);
                if (!mask)
                        goto fallback;
        return;
 
 fallback:
-       for_each_possible_cpu(cpu)
-               instance->reply_map[cpu] = cpu % instance->msix_vectors;
+       queue = low_latency_index_start;
+       for_each_possible_cpu(cpu) {
+               instance->reply_map[cpu] = queue;
+               if (queue == (instance->msix_vectors - 1))
+                       queue = low_latency_index_start;
+               else
+                       queue++;
+       }
 }
 
 /**
 
        return SUCCESS;
 }
+
+static int
+__megasas_alloc_irq_vectors(struct megasas_instance *instance)
+{
+       int i, irq_flags;
+       struct irq_affinity desc = { .pre_vectors = instance->low_latency_index_start };
+       struct irq_affinity *descp = &desc;
+
+       irq_flags = PCI_IRQ_MSIX;
+
+       if (instance->smp_affinity_enable)
+               irq_flags |= PCI_IRQ_AFFINITY;
+       else
+               descp = NULL;
+
+       i = pci_alloc_irq_vectors_affinity(instance->pdev,
+               instance->low_latency_index_start,
+               instance->msix_vectors, irq_flags, descp);
+
+       return i;
+}
+
+/**
+ * megasas_alloc_irq_vectors - Allocate IRQ vectors/enable MSI-x vectors
+ * @instance:                  Adapter soft state
+ * return:                     void
+ */
+static void
+megasas_alloc_irq_vectors(struct megasas_instance *instance)
+{
+       int i;
+       unsigned int num_msix_req;
+
+       i = __megasas_alloc_irq_vectors(instance);
+
+       if (instance->balanced_mode && (i != instance->msix_vectors)) {
+               if (instance->msix_vectors)
+                       pci_free_irq_vectors(instance->pdev);
+               /* Disable Balanced IOPS mode and try realloc vectors */
+               instance->balanced_mode = false;
+               instance->low_latency_index_start = 1;
+               num_msix_req = num_online_cpus() + instance->low_latency_index_start;
+
+               instance->msix_vectors = min(num_msix_req,
+                               instance->msix_vectors);
+
+               i = __megasas_alloc_irq_vectors(instance);
+
+       }
+
+       dev_info(&instance->pdev->dev,
+               "requested/available msix %d/%d\n", instance->msix_vectors, i);
+
+       if (i > 0)
+               instance->msix_vectors = i;
+       else
+               instance->msix_vectors = 0;
+
+}
+
 /**
  * megasas_init_fw -   Initializes the FW
  * @instance:          Adapter soft state
        int i, j, loop;
        struct IOV_111 *iovPtr;
        struct fusion_context *fusion;
+       bool intr_coalescing;
+       unsigned int num_msix_req;
 
        fusion = instance->ctrl_context;
 
        msix_enable = (instance->instancet->read_fw_status_reg(instance) &
                       0x4000000) >> 0x1a;
        if (msix_enable && !msix_disable) {
-               int irq_flags = PCI_IRQ_MSIX;
 
                scratch_pad_1 = megasas_readl
                        (instance, &instance->reg_set->outbound_scratch_pad_1);
                } else /* MFI adapters */
                        instance->msix_vectors = 1;
 
-               /* Don't bother allocating more MSI-X vectors than cpus */
-               instance->msix_vectors = min(instance->msix_vectors,
-                                            (unsigned int)num_online_cpus());
-               if (instance->smp_affinity_enable)
-                       irq_flags |= PCI_IRQ_AFFINITY;
-               i = pci_alloc_irq_vectors(instance->pdev, 1,
-                                         instance->msix_vectors, irq_flags);
-               if (i > 0) {
-                       instance->msix_vectors = i;
-               } else {
-                       instance->msix_vectors = 0;
+
+               /*
+                * For Aero (if some conditions are met), driver will configure a
+                * few additional reply queues with interrupt coalescing enabled.
+                * These queues with interrupt coalescing enabled are called
+                * High IOPS queues and rest of reply queues (based on number of
+                * logical CPUs) are termed as Low latency queues.
+                *
+                * Total Number of reply queues = High IOPS queues + low latency queues
+                *
+                * For rest of fusion adapters, 1 additional reply queue will be
+                * reserved for management commands, rest of reply queues
+                * (based on number of logical CPUs) will be used for IOs and
+                * referenced as IO queues.
+                * Total Number of reply queues = 1 + IO queues
+                *
+                * MFI adapters supports single MSI-x so single reply queue
+                * will be used for IO and management commands.
+                */
+
+               intr_coalescing = (scratch_pad_1 & MR_INTR_COALESCING_SUPPORT_OFFSET) ?
+                                                               true : false;
+               if (intr_coalescing &&
+                       (num_online_cpus() >= MR_HIGH_IOPS_QUEUE_COUNT) &&
+                       (instance->msix_vectors == MEGASAS_MAX_MSIX_QUEUES))
+                       instance->balanced_mode = true;
+               else
+                       instance->balanced_mode = false;
+
+               if (instance->balanced_mode)
+                       instance->low_latency_index_start =
+                               MR_HIGH_IOPS_QUEUE_COUNT;
+               else
+                       instance->low_latency_index_start = 1;
+
+               num_msix_req = num_online_cpus() + instance->low_latency_index_start;
+
+               instance->msix_vectors = min(num_msix_req,
+                               instance->msix_vectors);
+
+               megasas_alloc_irq_vectors(instance);
+               if (!instance->msix_vectors)
                        instance->msix_load_balance = false;
-               }
        }
        /*
         * MSI-X host index 0 is common for all adapter.