diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 85ef8415640cb10a9e6e3bd4ab3c13f21550efc9..b34fc68c14c94f870b291323d7ae37b5d4dd0b89 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1508,6 +1508,8 @@ enum FW_BOOT_CONTEXT {
 
 #define MR_CAN_HANDLE_SYNC_CACHE_OFFSET		0X01000000
 
+#define MR_CAN_HANDLE_64_BIT_DMA_OFFSET		(1 << 25)
+
 enum MR_ADAPTER_TYPE {
 	MFI_SERIES = 1,
 	THUNDERBOLT_SERIES = 2,
@@ -1628,7 +1630,8 @@ union megasas_sgl_frame {
 typedef union _MFI_CAPABILITIES {
 	struct {
 #if   defined(__BIG_ENDIAN_BITFIELD)
-	u32     reserved:19;
+	u32     reserved:18;
+	u32     support_64bit_mode:1;
 	u32 support_pd_map_target_id:1;
 	u32     support_qd_throttling:1;
 	u32     support_fp_rlbypass:1;
@@ -1656,7 +1659,8 @@ typedef union _MFI_CAPABILITIES {
 	u32     support_fp_rlbypass:1;
 	u32     support_qd_throttling:1;
 	u32	support_pd_map_target_id:1;
-	u32     reserved:19;
+	u32     support_64bit_mode:1;
+	u32     reserved:18;
 #endif
 	} mfi_capabilities;
 	__le32		reg;
@@ -2264,6 +2268,7 @@ struct megasas_instance {
 	u8  r1_ldio_hint_default;
 	u32 nvme_page_size;
 	u8 adapter_type;
+	bool consistent_mask_64bit;
 };
 struct MR_LD_VF_MAP {
 	u32 size;
@@ -2510,4 +2515,7 @@ int megasas_reset_target_fusion(struct scsi_cmnd *scmd);
 u32 mega_mod64(u64 dividend, u32 divisor);
 int megasas_alloc_fusion_context(struct megasas_instance *instance);
 void megasas_free_fusion_context(struct megasas_instance *instance);
+void megasas_set_dma_settings(struct megasas_instance *instance,
+			      struct megasas_dcmd_frame *dcmd,
+			      dma_addr_t dma_addr, u32 dma_len);
 #endif				/*LSI_MEGARAID_SAS_H */
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index 7e40ff6725e9ec326ac1ffb0e3ac33f43d99d604..f14d7cb05280e7a800388e20eff7733b6453e4bf 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -207,7 +207,7 @@ void megasas_fusion_ocr_wq(struct work_struct *work);
 static int megasas_get_ld_vf_affiliation(struct megasas_instance *instance,
 					 int initial);
 static int
-megasas_set_dma_mask(struct pci_dev *pdev);
+megasas_set_dma_mask(struct megasas_instance *instance);
 static int
 megasas_alloc_ctrl_mem(struct megasas_instance *instance);
 static inline void
@@ -219,6 +219,31 @@ megasas_free_ctrl_dma_buffers(struct megasas_instance *instance);
 static inline void
 megasas_init_ctrl_params(struct megasas_instance *instance);
 
+/**
+ * megasas_set_dma_settings -	Populate DMA address, length and flags for DCMDs
+ * @instance:			Adapter soft state
+ * @dcmd:			DCMD frame inside MFI command
+ * @dma_addr:			DMA address of buffer to be passed to FW
+ * @dma_len:			Length of DMA buffer to be passed to FW
+ * @return:			void
+ */
+void megasas_set_dma_settings(struct megasas_instance *instance,
+			      struct megasas_dcmd_frame *dcmd,
+			      dma_addr_t dma_addr, u32 dma_len)
+{
+	if (instance->consistent_mask_64bit) {
+		dcmd->sgl.sge64[0].phys_addr = cpu_to_le64(dma_addr);
+		dcmd->sgl.sge64[0].length = cpu_to_le32(dma_len);
+		dcmd->flags = cpu_to_le16(dcmd->flags | MFI_FRAME_SGL64);
+
+	} else {
+		dcmd->sgl.sge32[0].phys_addr =
+				cpu_to_le32(lower_32_bits(dma_addr));
+		dcmd->sgl.sge32[0].length = cpu_to_le32(dma_len);
+		dcmd->flags = cpu_to_le16(dcmd->flags);
+	}
+}
+
 void
 megasas_issue_dcmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
 {
@@ -2501,8 +2526,9 @@ int megasas_sriov_start_heartbeat(struct megasas_instance *instance,
 	dcmd->pad_0 = 0;
 	dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_CTRL_HB_HOST_MEM));
 	dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_SHARED_HOST_MEM_ALLOC);
-	dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(instance->hb_host_mem_h);
-	dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct MR_CTRL_HB_HOST_MEM));
+
+	megasas_set_dma_settings(instance, dcmd, instance->hb_host_mem_h,
+				 sizeof(struct MR_CTRL_HB_HOST_MEM));
 
 	dev_warn(&instance->pdev->dev, "SR-IOV: Starting heartbeat for scsi%d\n",
 	       instance->host->host_no);
@@ -4155,13 +4181,14 @@ megasas_get_pd_info(struct megasas_instance *instance, struct scsi_device *sdev)
 	dcmd->cmd = MFI_CMD_DCMD;
 	dcmd->cmd_status = 0xFF;
 	dcmd->sge_count = 1;
-	dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
+	dcmd->flags = MFI_FRAME_DIR_READ;
 	dcmd->timeout = 0;
 	dcmd->pad_0 = 0;
 	dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_PD_INFO));
 	dcmd->opcode = cpu_to_le32(MR_DCMD_PD_GET_INFO);
-	dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(instance->pd_info_h);
-	dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct MR_PD_INFO));
+
+	megasas_set_dma_settings(instance, dcmd, instance->pd_info_h,
+				 sizeof(struct MR_PD_INFO));
 
 	if ((instance->adapter_type != MFI_SERIES) &&
 	    !instance->mask_interrupts)
@@ -4247,13 +4274,14 @@ megasas_get_pd_list(struct megasas_instance *instance)
 	dcmd->cmd = MFI_CMD_DCMD;
 	dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
 	dcmd->sge_count = 1;
-	dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
+	dcmd->flags = MFI_FRAME_DIR_READ;
 	dcmd->timeout = 0;
 	dcmd->pad_0 = 0;
 	dcmd->data_xfer_len = cpu_to_le32(MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST));
 	dcmd->opcode = cpu_to_le32(MR_DCMD_PD_LIST_QUERY);
-	dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(ci_h);
-	dcmd->sgl.sge32[0].length = cpu_to_le32(MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST));
+
+	megasas_set_dma_settings(instance, dcmd, instance->pd_list_buf_h,
+				 (MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST)));
 
 	if ((instance->adapter_type != MFI_SERIES) &&
 	    !instance->mask_interrupts)
@@ -4369,14 +4397,15 @@ megasas_get_ld_list(struct megasas_instance *instance)
 	dcmd->cmd = MFI_CMD_DCMD;
 	dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
 	dcmd->sge_count = 1;
-	dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
+	dcmd->flags = MFI_FRAME_DIR_READ;
 	dcmd->timeout = 0;
 	dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_LD_LIST));
 	dcmd->opcode = cpu_to_le32(MR_DCMD_LD_GET_LIST);
-	dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(ci_h);
-	dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct MR_LD_LIST));
 	dcmd->pad_0  = 0;
 
+	megasas_set_dma_settings(instance, dcmd, ci_h,
+				 sizeof(struct MR_LD_LIST));
+
 	if ((instance->adapter_type != MFI_SERIES) &&
 	    !instance->mask_interrupts)
 		ret = megasas_issue_blocked_cmd(instance, cmd,
@@ -4480,14 +4509,15 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type)
 	dcmd->cmd = MFI_CMD_DCMD;
 	dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
 	dcmd->sge_count = 1;
-	dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
+	dcmd->flags = MFI_FRAME_DIR_READ;
 	dcmd->timeout = 0;
 	dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_LD_TARGETID_LIST));
 	dcmd->opcode = cpu_to_le32(MR_DCMD_LD_LIST_QUERY);
-	dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(ci_h);
-	dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct MR_LD_TARGETID_LIST));
 	dcmd->pad_0  = 0;
 
+	megasas_set_dma_settings(instance, dcmd, ci_h,
+				 sizeof(struct MR_LD_TARGETID_LIST));
+
 	if ((instance->adapter_type != MFI_SERIES) &&
 	    !instance->mask_interrupts)
 		ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS);
@@ -4641,15 +4671,16 @@ megasas_get_ctrl_info(struct megasas_instance *instance)
 	dcmd->cmd = MFI_CMD_DCMD;
 	dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
 	dcmd->sge_count = 1;
-	dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
+	dcmd->flags = MFI_FRAME_DIR_READ;
 	dcmd->timeout = 0;
 	dcmd->pad_0 = 0;
 	dcmd->data_xfer_len = cpu_to_le32(sizeof(struct megasas_ctrl_info));
 	dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_GET_INFO);
-	dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(ci_h);
-	dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct megasas_ctrl_info));
 	dcmd->mbox.b[0] = 1;
 
+	megasas_set_dma_settings(instance, dcmd, ci_h,
+				 sizeof(struct megasas_ctrl_info));
+
 	if ((instance->adapter_type != MFI_SERIES) &&
 	    !instance->mask_interrupts)
 		ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS);
@@ -4758,13 +4789,14 @@ int megasas_set_crash_dump_params(struct megasas_instance *instance,
 	dcmd->cmd = MFI_CMD_DCMD;
 	dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
 	dcmd->sge_count = 1;
-	dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_NONE);
+	dcmd->flags = MFI_FRAME_DIR_NONE;
 	dcmd->timeout = 0;
 	dcmd->pad_0 = 0;
 	dcmd->data_xfer_len = cpu_to_le32(CRASH_DMA_BUF_SIZE);
 	dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_SET_CRASH_DUMP_PARAMS);
-	dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(instance->crash_dump_h);
-	dcmd->sgl.sge32[0].length = cpu_to_le32(CRASH_DMA_BUF_SIZE);
+
+	megasas_set_dma_settings(instance, dcmd, instance->crash_dump_h,
+				 CRASH_DMA_BUF_SIZE);
 
 	if ((instance->adapter_type != MFI_SERIES) &&
 	    !instance->mask_interrupts)
@@ -5197,7 +5229,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
 
 	megasas_init_ctrl_params(instance);
 
-	if (megasas_set_dma_mask(instance->pdev))
+	if (megasas_set_dma_mask(instance))
 		goto fail_ready_state;
 
 	if (megasas_alloc_ctrl_mem(instance))
@@ -5580,13 +5612,14 @@ megasas_get_seq_num(struct megasas_instance *instance,
 	dcmd->cmd = MFI_CMD_DCMD;
 	dcmd->cmd_status = 0x0;
 	dcmd->sge_count = 1;
-	dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
+	dcmd->flags = MFI_FRAME_DIR_READ;
 	dcmd->timeout = 0;
 	dcmd->pad_0 = 0;
 	dcmd->data_xfer_len = cpu_to_le32(sizeof(struct megasas_evt_log_info));
 	dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_EVENT_GET_INFO);
-	dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(el_info_h);
-	dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct megasas_evt_log_info));
+
+	megasas_set_dma_settings(instance, dcmd, el_info_h,
+				 sizeof(struct megasas_evt_log_info));
 
 	if (megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS) ==
 		DCMD_SUCCESS) {
@@ -5711,7 +5744,7 @@ megasas_register_aen(struct megasas_instance *instance, u32 seq_num,
 	dcmd->cmd = MFI_CMD_DCMD;
 	dcmd->cmd_status = 0x0;
 	dcmd->sge_count = 1;
-	dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
+	dcmd->flags = MFI_FRAME_DIR_READ;
 	dcmd->timeout = 0;
 	dcmd->pad_0 = 0;
 	dcmd->data_xfer_len = cpu_to_le32(sizeof(struct megasas_evt_detail));
@@ -5719,8 +5752,9 @@ megasas_register_aen(struct megasas_instance *instance, u32 seq_num,
 	dcmd->mbox.w[0] = cpu_to_le32(seq_num);
 	instance->last_seq_num = seq_num;
 	dcmd->mbox.w[1] = cpu_to_le32(curr_aen.word);
-	dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(instance->evt_detail_h);
-	dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct megasas_evt_detail));
+
+	megasas_set_dma_settings(instance, dcmd, instance->evt_detail_h,
+				 sizeof(struct megasas_evt_detail));
 
 	if (instance->aen_cmd != NULL) {
 		megasas_return_cmd(instance, cmd);
@@ -5787,16 +5821,15 @@ megasas_get_target_prop(struct megasas_instance *instance,
 	dcmd->cmd = MFI_CMD_DCMD;
 	dcmd->cmd_status = 0xFF;
 	dcmd->sge_count = 1;
-	dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
+	dcmd->flags = MFI_FRAME_DIR_READ;
 	dcmd->timeout = 0;
 	dcmd->pad_0 = 0;
 	dcmd->data_xfer_len =
 		cpu_to_le32(sizeof(struct MR_TARGET_PROPERTIES));
 	dcmd->opcode = cpu_to_le32(MR_DCMD_DRV_GET_TARGET_PROP);
-	dcmd->sgl.sge32[0].phys_addr =
-		cpu_to_le32(instance->tgt_prop_h);
-	dcmd->sgl.sge32[0].length =
-		cpu_to_le32(sizeof(struct MR_TARGET_PROPERTIES));
+
+	megasas_set_dma_settings(instance, dcmd, instance->tgt_prop_h,
+				 sizeof(struct MR_TARGET_PROPERTIES));
 
 	if ((instance->adapter_type != MFI_SERIES) &&
 	    !instance->mask_interrupts)
@@ -5924,40 +5957,73 @@ static int megasas_io_attach(struct megasas_instance *instance)
 	return 0;
 }
 
+/**
+ * megasas_set_dma_mask -	Set DMA mask for supported controllers
+ *
+ * @instance:		Adapter soft state
+ * Description:
+ *
+ * For Ventura, driver/FW will operate in 64bit DMA addresses.
+ *
+ * For invader-
+ *	By default, driver/FW will operate in 32bit DMA addresses
+ *	for consistent DMA mapping but if 32 bit consistent
+ *	DMA mask fails, driver will try with 64 bit consistent
+ *	mask provided FW is true 64bit DMA capable
+ *
+ * For older controllers(Thunderbolt and MFI based adapters)-
+ *	driver/FW will operate in 32 bit consistent DMA addresses.
+ */
 static int
-megasas_set_dma_mask(struct pci_dev *pdev)
+megasas_set_dma_mask(struct megasas_instance *instance)
 {
-	/*
-	 * All our controllers are capable of performing 64-bit DMA
-	 */
+	u64 consistent_mask;
+	struct pci_dev *pdev;
+	u32 scratch_pad_2;
+
+	pdev = instance->pdev;
+	consistent_mask = (instance->adapter_type == VENTURA_SERIES) ?
+				DMA_BIT_MASK(64) : DMA_BIT_MASK(32);
+
 	if (IS_DMA64) {
-		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) {
+		if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) &&
+		    dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)))
+			goto fail_set_dma_mask;
+
+		if ((*pdev->dev.dma_mask == DMA_BIT_MASK(64)) &&
+		    (dma_set_coherent_mask(&pdev->dev, consistent_mask) &&
+		     dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)))) {
+			/*
+			 * If 32 bit DMA mask fails, then try for 64 bit mask
+			 * for FW capable of handling 64 bit DMA.
+			 */
+			scratch_pad_2 = readl
+				(&instance->reg_set->outbound_scratch_pad_2);
 
-			if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)
+			if (!(scratch_pad_2 & MR_CAN_HANDLE_64_BIT_DMA_OFFSET))
+				goto fail_set_dma_mask;
+			else if (dma_set_mask_and_coherent(&pdev->dev,
+							   DMA_BIT_MASK(64)))
 				goto fail_set_dma_mask;
 		}
-	} else {
-		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)
-			goto fail_set_dma_mask;
-	}
-	/*
-	 * Ensure that all data structures are allocated in 32-bit
-	 * memory.
-	 */
-	if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) {
-		/* Try 32bit DMA mask and 32 bit Consistent dma mask */
-		if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
-			&& !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))
-			dev_info(&pdev->dev, "set 32bit DMA mask"
-				"and 32 bit consistent mask\n");
-		else
-			goto fail_set_dma_mask;
-	}
+	} else if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)))
+		goto fail_set_dma_mask;
+
+	if (pdev->dev.coherent_dma_mask == DMA_BIT_MASK(32))
+		instance->consistent_mask_64bit = false;
+	else
+		instance->consistent_mask_64bit = true;
+
+	dev_info(&pdev->dev, "%s bit DMA mask and %s bit consistent mask\n",
+		 ((*pdev->dev.dma_mask == DMA_BIT_MASK(64)) ? "64" : "32"),
+		 (instance->consistent_mask_64bit ? "64" : "32"));
 
 	return 0;
 
 fail_set_dma_mask:
-	return 1;
+	dev_err(&pdev->dev, "Failed to set DMA mask\n");
+	return -1;
+
 }
 
 /*
@@ -6632,7 +6698,13 @@ megasas_resume(struct pci_dev *pdev)
 
 	pci_set_master(pdev);
 
-	if (megasas_set_dma_mask(pdev))
+	/*
+	 * We expect the FW state to be READY
+	 */
+	if (megasas_transition_to_ready(instance, 0))
+		goto fail_ready_state;
+
+	if (megasas_set_dma_mask(instance))
 		goto fail_set_dma_mask;
 
 	/*
@@ -6641,12 +6713,6 @@ megasas_resume(struct pci_dev *pdev)
 
 	atomic_set(&instance->fw_outstanding, 0);
 
-	/*
-	 * We expect the FW state to be READY
-	 */
-	if (megasas_transition_to_ready(instance, 0))
-		goto fail_ready_state;
-
 	/* Now re-enable MSI-X */
 	if (instance->msix_vectors) {
 		irq_flags = PCI_IRQ_MSIX;
@@ -6713,9 +6779,9 @@ megasas_resume(struct pci_dev *pdev)
 	megasas_free_ctrl_mem(instance);
 	scsi_host_put(host);
 
+fail_reenable_msix:
 fail_set_dma_mask:
 fail_ready_state:
-fail_reenable_msix:
 
 	pci_disable_device(pdev);
 
@@ -7013,7 +7079,8 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
 		      struct megasas_iocpacket __user * user_ioc,
 		      struct megasas_iocpacket *ioc)
 {
-	struct megasas_sge32 *kern_sge32;
+	struct megasas_sge64 *kern_sge64 = NULL;
+	struct megasas_sge32 *kern_sge32 = NULL;
 	struct megasas_cmd *cmd;
 	void *kbuff_arr[MAX_IOCTL_SGE];
 	dma_addr_t buf_handle = 0;
@@ -7053,8 +7120,14 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
 	memcpy(cmd->frame, ioc->frame.raw, 2 * MEGAMFI_FRAME_SIZE);
 	cmd->frame->hdr.context = cpu_to_le32(cmd->index);
 	cmd->frame->hdr.pad_0 = 0;
-	cmd->frame->hdr.flags &= cpu_to_le16(~(MFI_FRAME_IEEE |
-					       MFI_FRAME_SGL64 |
+
+	cmd->frame->hdr.flags &= (~MFI_FRAME_IEEE);
+
+	if (instance->consistent_mask_64bit)
+		cmd->frame->hdr.flags |= cpu_to_le16((MFI_FRAME_SGL64 |
+				       MFI_FRAME_SENSE64));
+	else
+		cmd->frame->hdr.flags &= cpu_to_le16(~(MFI_FRAME_SGL64 |
 					       MFI_FRAME_SENSE64));
 
 	if (cmd->frame->hdr.cmd == MFI_CMD_DCMD)
@@ -7081,8 +7154,12 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
 	 * kernel buffers in SGLs. The location of SGL is embedded in the
 	 * struct iocpacket itself.
 	 */
-	kern_sge32 = (struct megasas_sge32 *)
-	    ((unsigned long)cmd->frame + ioc->sgl_off);
+	if (instance->consistent_mask_64bit)
+		kern_sge64 = (struct megasas_sge64 *)
+			((unsigned long)cmd->frame + ioc->sgl_off);
+	else
+		kern_sge32 = (struct megasas_sge32 *)
+			((unsigned long)cmd->frame + ioc->sgl_off);
 
 	/*
 	 * For each user buffer, create a mirror buffer and copy in
@@ -7105,8 +7182,13 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
 		 * We don't change the dma_coherent_mask, so
 		 * pci_alloc_consistent only returns 32bit addresses
 		 */
-		kern_sge32[i].phys_addr = cpu_to_le32(buf_handle);
-		kern_sge32[i].length = cpu_to_le32(ioc->sgl[i].iov_len);
+		if (instance->consistent_mask_64bit) {
+			kern_sge64[i].phys_addr = cpu_to_le64(buf_handle);
+			kern_sge64[i].length = cpu_to_le32(ioc->sgl[i].iov_len);
+		} else {
+			kern_sge32[i].phys_addr = cpu_to_le32(buf_handle);
+			kern_sge32[i].length = cpu_to_le32(ioc->sgl[i].iov_len);
+		}
 
 		/*
 		 * We created a kernel buffer corresponding to the
@@ -7129,7 +7211,10 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
 
 		sense_ptr =
 		(unsigned long *) ((unsigned long)cmd->frame + ioc->sense_off);
-		*sense_ptr = cpu_to_le32(sense_handle);
+		if (instance->consistent_mask_64bit)
+			*sense_ptr = cpu_to_le64(sense_handle);
+		else
+			*sense_ptr = cpu_to_le32(sense_handle);
 	}
 
 	/*
@@ -7202,10 +7287,16 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
 
 	for (i = 0; i < ioc->sge_count; i++) {
 		if (kbuff_arr[i]) {
-			dma_free_coherent(&instance->pdev->dev,
-					  le32_to_cpu(kern_sge32[i].length),
-					  kbuff_arr[i],
-					  le32_to_cpu(kern_sge32[i].phys_addr));
+			if (instance->consistent_mask_64bit)
+				dma_free_coherent(&instance->pdev->dev,
+					le32_to_cpu(kern_sge64[i].length),
+					kbuff_arr[i],
+					le64_to_cpu(kern_sge64[i].phys_addr));
+			else
+				dma_free_coherent(&instance->pdev->dev,
+					le32_to_cpu(kern_sge32[i].length),
+					kbuff_arr[i],
+					le32_to_cpu(kern_sge32[i].phys_addr));
 			kbuff_arr[i] = NULL;
 		}
 	}
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 745da54c11aac2a7782dd068f32cc3babc3dc81b..ad162fed389cf622335511f9bbb96f9cacda4834 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -99,7 +99,34 @@ static void megasas_free_reply_fusion(struct megasas_instance *instance);
 static inline
 void megasas_configure_queue_sizes(struct megasas_instance *instance);
 
+/**
+ * megasas_check_same_4gb_region -	check if allocation
+ *					crosses same 4GB boundary or not
+ * @instance -				adapter's soft instance
+ * start_addr -			start address of DMA allocation
+ * size -				size of allocation in bytes
+ * return -				true : allocation does not cross same
+ *					4GB boundary
+ *					false: allocation crosses same
+ *					4GB boundary
+ */
+static inline bool megasas_check_same_4gb_region
+	(struct megasas_instance *instance, dma_addr_t start_addr, size_t size)
+{
+	dma_addr_t end_addr;
+
+	end_addr = start_addr + size;
 
+	if (upper_32_bits(start_addr) != upper_32_bits(end_addr)) {
+		dev_err(&instance->pdev->dev,
+			"Failed to get same 4GB boundary: start_addr: 0x%llx end_addr: 0x%llx\n",
+			(unsigned long long)start_addr,
+			(unsigned long long)end_addr);
+		return false;
+	}
+
+	return true;
+}
 
 /**
  * megasas_enable_intr_fusion -	Enables interrupts
@@ -294,17 +321,23 @@ megasas_free_cmds_fusion(struct megasas_instance *instance)
 	struct fusion_context *fusion = instance->ctrl_context;
 	struct megasas_cmd_fusion *cmd;
 
-	/* SG, Sense */
-	for (i = 0; i < instance->max_mpt_cmds; i++) {
-		cmd = fusion->cmd_list[i];
-		if (cmd) {
-			if (cmd->sg_frame)
-				dma_pool_free(fusion->sg_dma_pool, cmd->sg_frame,
-				      cmd->sg_frame_phys_addr);
-			if (cmd->sense)
-				dma_pool_free(fusion->sense_dma_pool, cmd->sense,
-				      cmd->sense_phys_addr);
+	if (fusion->sense)
+		dma_pool_free(fusion->sense_dma_pool, fusion->sense,
+			      fusion->sense_phys_addr);
+
+	/* SG */
+	if (fusion->cmd_list) {
+		for (i = 0; i < instance->max_mpt_cmds; i++) {
+			cmd = fusion->cmd_list[i];
+			if (cmd) {
+				if (cmd->sg_frame)
+					dma_pool_free(fusion->sg_dma_pool,
+						      cmd->sg_frame,
+						      cmd->sg_frame_phys_addr);
+			}
+			kfree(cmd);
 		}
+		kfree(fusion->cmd_list);
 	}
 
 	if (fusion->sg_dma_pool) {
@@ -336,13 +369,6 @@ megasas_free_cmds_fusion(struct megasas_instance *instance)
 		dma_pool_destroy(fusion->io_request_frames_pool);
 		fusion->io_request_frames_pool = NULL;
 	}
-
-
-	/* cmd_list */
-	for (i = 0; i < instance->max_mpt_cmds; i++)
-		kfree(fusion->cmd_list[i]);
-
-	kfree(fusion->cmd_list);
 }
 
 /**
@@ -356,10 +382,12 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance)
 	u16 max_cmd;
 	struct fusion_context *fusion;
 	struct megasas_cmd_fusion *cmd;
+	int sense_sz;
+	u32 offset;
 
 	fusion = instance->ctrl_context;
 	max_cmd = instance->max_fw_cmds;
-
+	sense_sz = instance->max_mpt_cmds * SCSI_SENSE_BUFFERSIZE;
 
 	fusion->sg_dma_pool =
 			dma_pool_create("mr_sg", &instance->pdev->dev,
@@ -368,7 +396,7 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance)
 	/* SCSI_SENSE_BUFFERSIZE  = 96 bytes */
 	fusion->sense_dma_pool =
 			dma_pool_create("mr_sense", &instance->pdev->dev,
-				SCSI_SENSE_BUFFERSIZE, 64, 0);
+				sense_sz, 64, 0);
 
 	if (!fusion->sense_dma_pool || !fusion->sg_dma_pool) {
 		dev_err(&instance->pdev->dev,
@@ -376,6 +404,51 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance)
 		return -ENOMEM;
 	}
 
+	fusion->sense = dma_pool_alloc(fusion->sense_dma_pool,
+				       GFP_KERNEL, &fusion->sense_phys_addr);
+	if (!fusion->sense) {
+		dev_err(&instance->pdev->dev,
+			"failed from %s %d\n",  __func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	/* sense buffer, request frame and reply desc pool requires to be in
+	 * same 4 gb region. Below function will check this.
+	 * In case of failure, new pci pool will be created with updated
+	 * alignment.
+	 * Older allocation and pool will be destroyed.
+	 * Alignment will be used such a way that next allocation if success,
+	 * will always meet same 4gb region requirement.
+	 * Actual requirement is not alignment, but we need start and end of
+	 * DMA address must have same upper 32 bit address.
+	 */
+
+	if (!megasas_check_same_4gb_region(instance, fusion->sense_phys_addr,
+					   sense_sz)) {
+		dma_pool_free(fusion->sense_dma_pool, fusion->sense,
+			      fusion->sense_phys_addr);
+		fusion->sense = NULL;
+		dma_pool_destroy(fusion->sense_dma_pool);
+
+		fusion->sense_dma_pool =
+			dma_pool_create("mr_sense_align", &instance->pdev->dev,
+					sense_sz, roundup_pow_of_two(sense_sz),
+					0);
+		if (!fusion->sense_dma_pool) {
+			dev_err(&instance->pdev->dev,
+				"Failed from %s %d\n",  __func__, __LINE__);
+			return -ENOMEM;
+		}
+		fusion->sense = dma_pool_alloc(fusion->sense_dma_pool,
+					       GFP_KERNEL,
+					       &fusion->sense_phys_addr);
+		if (!fusion->sense) {
+			dev_err(&instance->pdev->dev,
+				"failed from %s %d\n",  __func__, __LINE__);
+			return -ENOMEM;
+		}
+	}
+
 	/*
 	 * Allocate and attach a frame to each of the commands in cmd_list
 	 */
@@ -384,9 +457,11 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance)
 		cmd->sg_frame = dma_pool_alloc(fusion->sg_dma_pool,
 					GFP_KERNEL, &cmd->sg_frame_phys_addr);
 
-		cmd->sense = dma_pool_alloc(fusion->sense_dma_pool,
-					GFP_KERNEL, &cmd->sense_phys_addr);
-		if (!cmd->sg_frame || !cmd->sense) {
+		offset = SCSI_SENSE_BUFFERSIZE * i;
+		cmd->sense = (u8 *)fusion->sense + offset;
+		cmd->sense_phys_addr = fusion->sense_phys_addr + offset;
+
+		if (!cmd->sg_frame) {
 			dev_err(&instance->pdev->dev,
 				"Failed from %s %d\n",  __func__, __LINE__);
 			return -ENOMEM;
@@ -396,13 +471,10 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance)
 	/* create sense buffer for the raid 1/10 fp */
 	for (i = max_cmd; i < instance->max_mpt_cmds; i++) {
 		cmd = fusion->cmd_list[i];
-		cmd->sense = dma_pool_alloc(fusion->sense_dma_pool,
-			GFP_KERNEL, &cmd->sense_phys_addr);
-		if (!cmd->sense) {
-			dev_err(&instance->pdev->dev,
-				"Failed from %s %d\n",  __func__, __LINE__);
-			return -ENOMEM;
-		}
+		offset = SCSI_SENSE_BUFFERSIZE * i;
+		cmd->sense = (u8 *)fusion->sense + offset;
+		cmd->sense_phys_addr = fusion->sense_phys_addr + offset;
+
 	}
 
 	return 0;
@@ -481,6 +553,40 @@ megasas_alloc_request_fusion(struct megasas_instance *instance)
 		}
 	}
 
+	if (!megasas_check_same_4gb_region(instance,
+					   fusion->io_request_frames_phys,
+					   fusion->io_frames_alloc_sz)) {
+		dma_pool_free(fusion->io_request_frames_pool,
+			      fusion->io_request_frames,
+			      fusion->io_request_frames_phys);
+		fusion->io_request_frames = NULL;
+		dma_pool_destroy(fusion->io_request_frames_pool);
+
+		fusion->io_request_frames_pool =
+			dma_pool_create("mr_ioreq_align",
+					&instance->pdev->dev,
+					fusion->io_frames_alloc_sz,
+					roundup_pow_of_two(fusion->io_frames_alloc_sz),
+					0);
+
+		if (!fusion->io_request_frames_pool) {
+			dev_err(&instance->pdev->dev,
+				"Failed from %s %d\n",  __func__, __LINE__);
+			return -ENOMEM;
+		}
+
+		fusion->io_request_frames =
+			dma_pool_alloc(fusion->io_request_frames_pool,
+				       GFP_KERNEL,
+				       &fusion->io_request_frames_phys);
+
+		if (!fusion->io_request_frames) {
+			dev_err(&instance->pdev->dev,
+				"Failed from %s %d\n",  __func__, __LINE__);
+			return -ENOMEM;
+		}
+	}
+
 	fusion->req_frames_desc =
 		dma_alloc_coherent(&instance->pdev->dev,
 				   fusion->request_alloc_sz,
@@ -521,6 +627,41 @@ megasas_alloc_reply_fusion(struct megasas_instance *instance)
 			"Failed from %s %d\n",  __func__, __LINE__);
 		return -ENOMEM;
 	}
+
+	if (!megasas_check_same_4gb_region(instance,
+					   fusion->reply_frames_desc_phys[0],
+					   (fusion->reply_alloc_sz * count))) {
+		dma_pool_free(fusion->reply_frames_desc_pool,
+			      fusion->reply_frames_desc[0],
+			      fusion->reply_frames_desc_phys[0]);
+		fusion->reply_frames_desc[0] = NULL;
+		dma_pool_destroy(fusion->reply_frames_desc_pool);
+
+		fusion->reply_frames_desc_pool =
+			dma_pool_create("mr_reply_align",
+					&instance->pdev->dev,
+					fusion->reply_alloc_sz * count,
+					roundup_pow_of_two(fusion->reply_alloc_sz * count),
+					0);
+
+		if (!fusion->reply_frames_desc_pool) {
+			dev_err(&instance->pdev->dev,
+				"Failed from %s %d\n",  __func__, __LINE__);
+			return -ENOMEM;
+		}
+
+		fusion->reply_frames_desc[0] =
+			dma_pool_alloc(fusion->reply_frames_desc_pool,
+				       GFP_KERNEL,
+				       &fusion->reply_frames_desc_phys[0]);
+
+		if (!fusion->reply_frames_desc[0]) {
+			dev_err(&instance->pdev->dev,
+				"Failed from %s %d\n",  __func__, __LINE__);
+			return -ENOMEM;
+		}
+	}
+
 	reply_desc = fusion->reply_frames_desc[0];
 	for (i = 0; i < fusion->reply_q_depth * count; i++, reply_desc++)
 		reply_desc->Words = cpu_to_le64(ULLONG_MAX);
@@ -539,52 +680,124 @@ megasas_alloc_reply_fusion(struct megasas_instance *instance)
 int
 megasas_alloc_rdpq_fusion(struct megasas_instance *instance)
 {
-	int i, j, count;
+	int i, j, k, msix_count;
 	struct fusion_context *fusion;
 	union MPI2_REPLY_DESCRIPTORS_UNION *reply_desc;
+	union MPI2_REPLY_DESCRIPTORS_UNION *rdpq_chunk_virt[RDPQ_MAX_CHUNK_COUNT];
+	dma_addr_t rdpq_chunk_phys[RDPQ_MAX_CHUNK_COUNT];
+	u8 dma_alloc_count, abs_index;
+	u32 chunk_size, array_size, offset;
 
 	fusion = instance->ctrl_context;
+	chunk_size = fusion->reply_alloc_sz * RDPQ_MAX_INDEX_IN_ONE_CHUNK;
+	array_size = sizeof(struct MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY) *
+		     MAX_MSIX_QUEUES_FUSION;
 
-	fusion->rdpq_virt = pci_alloc_consistent(instance->pdev,
-				sizeof(struct MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY) * MAX_MSIX_QUEUES_FUSION,
-				&fusion->rdpq_phys);
+	fusion->rdpq_virt = pci_alloc_consistent(instance->pdev, array_size,
+						 &fusion->rdpq_phys);
 	if (!fusion->rdpq_virt) {
 		dev_err(&instance->pdev->dev,
 			"Failed from %s %d\n",  __func__, __LINE__);
 		return -ENOMEM;
 	}
 
-	memset(fusion->rdpq_virt, 0,
-			sizeof(struct MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY) * MAX_MSIX_QUEUES_FUSION);
-	count = instance->msix_vectors > 0 ? instance->msix_vectors : 1;
+	memset(fusion->rdpq_virt, 0, array_size);
+	msix_count = instance->msix_vectors > 0 ? instance->msix_vectors : 1;
+
 	fusion->reply_frames_desc_pool = dma_pool_create("mr_rdpq",
 							 &instance->pdev->dev,
-							 fusion->reply_alloc_sz,
-							 16, 0);
-
-	if (!fusion->reply_frames_desc_pool) {
+							 chunk_size, 16, 0);
+	fusion->reply_frames_desc_pool_align =
+				dma_pool_create("mr_rdpq_align",
+						&instance->pdev->dev,
+						chunk_size,
+						roundup_pow_of_two(chunk_size),
+						0);
+
+	if (!fusion->reply_frames_desc_pool ||
+	    !fusion->reply_frames_desc_pool_align) {
 		dev_err(&instance->pdev->dev,
 			"Failed from %s %d\n",  __func__, __LINE__);
 		return -ENOMEM;
 	}
 
-	for (i = 0; i < count; i++) {
-		fusion->reply_frames_desc[i] =
-				dma_pool_alloc(fusion->reply_frames_desc_pool,
-					GFP_KERNEL, &fusion->reply_frames_desc_phys[i]);
-		if (!fusion->reply_frames_desc[i]) {
+/*
+ * For INVADER_SERIES each set of 8 reply queues(0-7, 8-15, ..) and
+ * VENTURA_SERIES each set of 16 reply queues(0-15, 16-31, ..) should be
+ * within 4GB boundary and also reply queues in a set must have same
+ * upper 32-bits in their memory address. so here driver is allocating the
+ * DMA'able memory for reply queues according. Driver uses limitation of
+ * VENTURA_SERIES to manage INVADER_SERIES as well.
+ */
+	dma_alloc_count = DIV_ROUND_UP(msix_count, RDPQ_MAX_INDEX_IN_ONE_CHUNK);
+
+	for (i = 0; i < dma_alloc_count; i++) {
+		rdpq_chunk_virt[i] =
+			dma_pool_alloc(fusion->reply_frames_desc_pool,
+				       GFP_KERNEL, &rdpq_chunk_phys[i]);
+		if (!rdpq_chunk_virt[i]) {
 			dev_err(&instance->pdev->dev,
 				"Failed from %s %d\n",  __func__, __LINE__);
 			return -ENOMEM;
 		}
+		/* reply desc pool requires to be in same 4 gb region.
+		 * Below function will check this.
+		 * In case of failure, new pci pool will be created with updated
+		 * alignment.
+		 * For RDPQ buffers, driver always allocate two separate pci pool.
+		 * Alignment will be used such a way that next allocation if
+		 * success, will always meet same 4gb region requirement.
+		 * rdpq_tracker keep track of each buffer's physical,
+		 * virtual address and pci pool descriptor. It will help driver
+		 * while freeing the resources.
+		 *
+		 */
+		if (!megasas_check_same_4gb_region(instance, rdpq_chunk_phys[i],
+						   chunk_size)) {
+			dma_pool_free(fusion->reply_frames_desc_pool,
+				      rdpq_chunk_virt[i],
+				      rdpq_chunk_phys[i]);
+
+			rdpq_chunk_virt[i] =
+				dma_pool_alloc(fusion->reply_frames_desc_pool_align,
+					       GFP_KERNEL, &rdpq_chunk_phys[i]);
+			if (!rdpq_chunk_virt[i]) {
+				dev_err(&instance->pdev->dev,
+					"Failed from %s %d\n",
+					__func__, __LINE__);
+				return -ENOMEM;
+			}
+			fusion->rdpq_tracker[i].dma_pool_ptr =
+					fusion->reply_frames_desc_pool_align;
+		} else {
+			fusion->rdpq_tracker[i].dma_pool_ptr =
+					fusion->reply_frames_desc_pool;
+		}
 
-		fusion->rdpq_virt[i].RDPQBaseAddress =
-			cpu_to_le64(fusion->reply_frames_desc_phys[i]);
+		fusion->rdpq_tracker[i].pool_entry_phys = rdpq_chunk_phys[i];
+		fusion->rdpq_tracker[i].pool_entry_virt = rdpq_chunk_virt[i];
+	}
 
-		reply_desc = fusion->reply_frames_desc[i];
-		for (j = 0; j < fusion->reply_q_depth; j++, reply_desc++)
-			reply_desc->Words = cpu_to_le64(ULLONG_MAX);
+	for (k = 0; k < dma_alloc_count; k++) {
+		for (i = 0; i < RDPQ_MAX_INDEX_IN_ONE_CHUNK; i++) {
+			abs_index = (k * RDPQ_MAX_INDEX_IN_ONE_CHUNK) + i;
+
+			if (abs_index == msix_count)
+				break;
+			offset = fusion->reply_alloc_sz * i;
+			fusion->rdpq_virt[abs_index].RDPQBaseAddress =
+					cpu_to_le64(rdpq_chunk_phys[k] + offset);
+			fusion->reply_frames_desc_phys[abs_index] =
+					rdpq_chunk_phys[k] + offset;
+			fusion->reply_frames_desc[abs_index] =
+					(union MPI2_REPLY_DESCRIPTORS_UNION *)((u8 *)rdpq_chunk_virt[k] + offset);
+
+			reply_desc = fusion->reply_frames_desc[abs_index];
+			for (j = 0; j < fusion->reply_q_depth; j++, reply_desc++)
+				reply_desc->Words = ULLONG_MAX;
+		}
 	}
+
 	return 0;
 }
 
@@ -596,15 +809,18 @@ megasas_free_rdpq_fusion(struct megasas_instance *instance) {
 
 	fusion = instance->ctrl_context;
 
-	for (i = 0; i < MAX_MSIX_QUEUES_FUSION; i++) {
-		if (fusion->reply_frames_desc[i])
-			dma_pool_free(fusion->reply_frames_desc_pool,
-				fusion->reply_frames_desc[i],
-				fusion->reply_frames_desc_phys[i]);
+	for (i = 0; i < RDPQ_MAX_CHUNK_COUNT; i++) {
+		if (fusion->rdpq_tracker[i].pool_entry_virt)
+			dma_pool_free(fusion->rdpq_tracker[i].dma_pool_ptr,
+				      fusion->rdpq_tracker[i].pool_entry_virt,
+				      fusion->rdpq_tracker[i].pool_entry_phys);
+
 	}
 
 	if (fusion->reply_frames_desc_pool)
 		dma_pool_destroy(fusion->reply_frames_desc_pool);
+	if (fusion->reply_frames_desc_pool_align)
+		dma_pool_destroy(fusion->reply_frames_desc_pool_align);
 
 	if (fusion->rdpq_virt)
 		pci_free_consistent(instance->pdev,
@@ -771,6 +987,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
 	u32 scratch_pad_2;
 	unsigned long flags;
 	struct timeval tv;
+	bool cur_fw_64bit_dma_capable;
 
 	fusion = instance->ctrl_context;
 
@@ -784,6 +1001,19 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
 
 	cur_rdpq_mode = (scratch_pad_2 & MR_RDPQ_MODE_OFFSET) ? 1 : 0;
 
+	if (instance->adapter_type == INVADER_SERIES) {
+		cur_fw_64bit_dma_capable =
+			(scratch_pad_2 & MR_CAN_HANDLE_64_BIT_DMA_OFFSET) ? true : false;
+
+		if (instance->consistent_mask_64bit && !cur_fw_64bit_dma_capable) {
+			dev_err(&instance->pdev->dev, "Driver was operating on 64bit "
+				"DMA mask, but upcoming FW does not support 64bit DMA mask\n");
+			megaraid_sas_kill_hba(instance);
+			ret = 1;
+			goto fail_fw_init;
+		}
+	}
+
 	if (instance->is_rdpq && !cur_rdpq_mode) {
 		dev_err(&instance->pdev->dev, "Firmware downgrade *NOT SUPPORTED*"
 			" from RDPQ mode to non RDPQ mode\n");
@@ -811,6 +1041,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
 	IOCInitMessage->MsgFlags = instance->is_rdpq ?
 			MPI2_IOCINIT_MSGFLAG_RDPQ_ARRAY_MODE : 0;
 	IOCInitMessage->SystemRequestFrameBaseAddress = cpu_to_le64(fusion->io_request_frames_phys);
+	IOCInitMessage->SenseBufferAddressHigh = cpu_to_le32(upper_32_bits(fusion->sense_phys_addr));
 	IOCInitMessage->HostMSIxVectors = instance->msix_vectors;
 	IOCInitMessage->HostPageSize = MR_DEFAULT_NVME_PAGE_SHIFT;
 
@@ -852,6 +1083,10 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
 
 	drv_ops->mfi_capabilities.support_qd_throttling = 1;
 	drv_ops->mfi_capabilities.support_pd_map_target_id = 1;
+
+	if (instance->consistent_mask_64bit)
+		drv_ops->mfi_capabilities.support_64bit_mode = 1;
+
 	/* Convert capability to LE32 */
 	cpu_to_le32s((u32 *)&init_frame->driver_operations.mfi_capabilities);
 
@@ -861,8 +1096,8 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
 			strlen(sys_info) > 64 ? 64 : strlen(sys_info));
 		instance->system_info_buf->systemIdLength =
 			strlen(sys_info) > 64 ? 64 : strlen(sys_info);
-		init_frame->system_info_lo = instance->system_info_h;
-		init_frame->system_info_hi = 0;
+		init_frame->system_info_lo = cpu_to_le32(lower_32_bits(instance->system_info_h));
+		init_frame->system_info_hi = cpu_to_le32(upper_32_bits(instance->system_info_h));
 	}
 
 	init_frame->queue_info_new_phys_addr_hi =
@@ -953,6 +1188,15 @@ megasas_sync_pd_seq_num(struct megasas_instance *instance, bool pend) {
 
 	memset(pd_sync, 0, pd_seq_map_sz);
 	memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
+
+	if (pend) {
+		dcmd->mbox.b[0] = MEGASAS_DCMD_MBOX_PEND_FLAG;
+		dcmd->flags = MFI_FRAME_DIR_WRITE;
+		instance->jbod_seq_cmd = cmd;
+	} else {
+		dcmd->flags = MFI_FRAME_DIR_READ;
+	}
+
 	dcmd->cmd = MFI_CMD_DCMD;
 	dcmd->cmd_status = 0xFF;
 	dcmd->sge_count = 1;
@@ -960,19 +1204,14 @@ megasas_sync_pd_seq_num(struct megasas_instance *instance, bool pend) {
 	dcmd->pad_0 = 0;
 	dcmd->data_xfer_len = cpu_to_le32(pd_seq_map_sz);
 	dcmd->opcode = cpu_to_le32(MR_DCMD_SYSTEM_PD_MAP_GET_INFO);
-	dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(pd_seq_h);
-	dcmd->sgl.sge32[0].length = cpu_to_le32(pd_seq_map_sz);
+
+	megasas_set_dma_settings(instance, dcmd, pd_seq_h, pd_seq_map_sz);
 
 	if (pend) {
-		dcmd->mbox.b[0] = MEGASAS_DCMD_MBOX_PEND_FLAG;
-		dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_WRITE);
-		instance->jbod_seq_cmd = cmd;
 		instance->instancet->issue_dcmd(instance, cmd);
 		return 0;
 	}
 
-	dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
-
 	/* Below code is only for non pended DCMD */
 	if (!instance->mask_interrupts)
 		ret = megasas_issue_blocked_cmd(instance, cmd,
@@ -1055,13 +1294,13 @@ megasas_get_ld_map_info(struct megasas_instance *instance)
 	dcmd->cmd = MFI_CMD_DCMD;
 	dcmd->cmd_status = 0xFF;
 	dcmd->sge_count = 1;
-	dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
+	dcmd->flags = MFI_FRAME_DIR_READ;
 	dcmd->timeout = 0;
 	dcmd->pad_0 = 0;
 	dcmd->data_xfer_len = cpu_to_le32(size_map_info);
 	dcmd->opcode = cpu_to_le32(MR_DCMD_LD_MAP_GET_INFO);
-	dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(ci_h);
-	dcmd->sgl.sge32[0].length = cpu_to_le32(size_map_info);
+
+	megasas_set_dma_settings(instance, dcmd, ci_h, size_map_info);
 
 	if (!instance->mask_interrupts)
 		ret = megasas_issue_blocked_cmd(instance, cmd,
@@ -1159,15 +1398,15 @@ megasas_sync_map_info(struct megasas_instance *instance)
 	dcmd->cmd = MFI_CMD_DCMD;
 	dcmd->cmd_status = 0xFF;
 	dcmd->sge_count = 1;
-	dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_WRITE);
+	dcmd->flags = MFI_FRAME_DIR_WRITE;
 	dcmd->timeout = 0;
 	dcmd->pad_0 = 0;
 	dcmd->data_xfer_len = cpu_to_le32(size_map_info);
 	dcmd->mbox.b[0] = num_lds;
 	dcmd->mbox.b[1] = MEGASAS_DCMD_MBOX_PEND_FLAG;
 	dcmd->opcode = cpu_to_le32(MR_DCMD_LD_MAP_GET_INFO);
-	dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(ci_h);
-	dcmd->sgl.sge32[0].length = cpu_to_le32(size_map_info);
+
+	megasas_set_dma_settings(instance, dcmd, ci_h, size_map_info);
 
 	instance->map_update_cmd = cmd;
 
@@ -2872,7 +3111,8 @@ megasas_build_io_fusion(struct megasas_instance *instance,
 	io_request->SGLOffset0 =
 		offsetof(struct MPI2_RAID_SCSI_IO_REQUEST, SGL) / 4;
 
-	io_request->SenseBufferLowAddress = cpu_to_le32(cmd->sense_phys_addr);
+	io_request->SenseBufferLowAddress =
+		cpu_to_le32(lower_32_bits(cmd->sense_phys_addr));
 	io_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE;
 
 	cmd->scmd = scp;
@@ -2913,7 +3153,7 @@ void megasas_prepare_secondRaid1_IO(struct megasas_instance *instance,
 	       (fusion->max_sge_in_main_msg * sizeof(union MPI2_SGE_IO_UNION)));
 	/*sense buffer is different for r1 command*/
 	r1_cmd->io_request->SenseBufferLowAddress =
-			cpu_to_le32(r1_cmd->sense_phys_addr);
+			cpu_to_le32(lower_32_bits(r1_cmd->sense_phys_addr));
 	r1_cmd->scmd = cmd->scmd;
 	req_desc2 = megasas_get_request_descriptor(instance,
 						   (r1_cmd->index - 1));
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h
index 4e229d72dfb0346fb3dc6879f93e73ab216f9b26..1814d79cb98d3096d07bea2fd3d2e9691bca7a48 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h
@@ -51,6 +51,8 @@
 #define HOST_DIAG_RESET_ADAPTER			    0x4
 #define MEGASAS_FUSION_MAX_RESET_TRIES		    3
 #define MAX_MSIX_QUEUES_FUSION			    128
+#define RDPQ_MAX_INDEX_IN_ONE_CHUNK		    16
+#define RDPQ_MAX_CHUNK_COUNT (MAX_MSIX_QUEUES_FUSION / RDPQ_MAX_INDEX_IN_ONE_CHUNK)
 
 /* Invader defines */
 #define MPI2_TYPE_CUDA				    0x2
@@ -1266,6 +1268,12 @@ struct MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY {
 	u32 Reserved2;
 };
 
+struct rdpq_alloc_detail {
+	struct dma_pool *dma_pool_ptr;
+	dma_addr_t	pool_entry_phys;
+	union MPI2_REPLY_DESCRIPTORS_UNION *pool_entry_virt;
+};
+
 struct fusion_context {
 	struct megasas_cmd_fusion **cmd_list;
 	dma_addr_t req_frames_desc_phys;
@@ -1278,9 +1286,14 @@ struct fusion_context {
 	struct dma_pool *sg_dma_pool;
 	struct dma_pool *sense_dma_pool;
 
+	u8 *sense;
+	dma_addr_t sense_phys_addr;
+
 	dma_addr_t reply_frames_desc_phys[MAX_MSIX_QUEUES_FUSION];
 	union MPI2_REPLY_DESCRIPTORS_UNION *reply_frames_desc[MAX_MSIX_QUEUES_FUSION];
+	struct rdpq_alloc_detail rdpq_tracker[RDPQ_MAX_CHUNK_COUNT];
 	struct dma_pool *reply_frames_desc_pool;
+	struct dma_pool *reply_frames_desc_pool_align;
 
 	u16 last_reply_idx[MAX_MSIX_QUEUES_FUSION];