scsi: megaraid_sas: Add support for 64bit consistent DMA

The latest MegaRAID Firmware (for Invader series) has support for 64bit
DMA for both streaming and consistent DMA buffers.  All Ventura series
controller FW always support 64 bit consistent DMA.  Also, on a few
architectures 32bit DMA is not supported.

Current driver always prefers 32bit for consistent DMA and 64bit for
streaming DMA.  This behavior was unintentional and carried forwarded
from legacy controller FW. Need to enhance the driver to support 64bit
consistent DMA buffers based on the firmware capability.

Below is the DMA setting strategy in driver with this patch.  For
Ventura series, always try to set 64bit DMA mask. If it fails fall back
to 32bit DMA mask.  For Invader series and earlier generation
controllers, first try to set to 32bit consistent DMA mask irrespective
of FW capability. This is needed to ensure firmware downgrades do not
break. If 32bit DMA setting fails, check FW capability and try seting to
64bit DMA mask.

There are certain restrictions in the hardware for having all sense
buffers and all reply descriptors to be in the same 4GB memory region.
This limitation is h/w dependent and can not be changed in firmware.
This limitation needs to be taken care in driver while allocating the
buffers.  There was a discussion regarding this - find details at below
link.  https://www.spinics.net/lists/linux-scsi/msg108251.html

Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
Signed-off-by: Shivasharan S <shivasharan.srikanteshwara@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 85ef841..b34fc68 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 */