Commit 107a60dd authored by Shivasharan S's avatar Shivasharan S Committed by Martin K. Petersen

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.htmlSigned-off-by: default avatarKashyap Desai <kashyap.desai@broadcom.com>
Signed-off-by: default avatarShivasharan S <shivasharan.srikanteshwara@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 2dba66bf
......@@ -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 */
This diff is collapsed.
This diff is collapsed.
......@@ -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];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment