Commit d889344e authored by Sasikumar Chandrasekaran's avatar Sasikumar Chandrasekaran Committed by Martin K. Petersen

scsi: megaraid_sas: Dynamic Raid Map Changes for SAS3.5 Generic Megaraid Controllers

SAS3.5 Generic Megaraid Controllers FW will support new dynamic RaidMap to have different
sizes for different number of supported VDs.
Signed-off-by: default avatarSasikumar Chandrasekaran <sasikumar.pc@broadcom.com>
Reviewed-by: default avatarTomas Henzl <thenzl@redhat.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 69c337c0
......@@ -1434,6 +1434,12 @@ enum FW_BOOT_CONTEXT {
#define MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT 14
#define MR_MAX_MSIX_REG_ARRAY 16
#define MR_RDPQ_MODE_OFFSET 0X00800000
#define MR_MAX_RAID_MAP_SIZE_OFFSET_SHIFT 16
#define MR_MAX_RAID_MAP_SIZE_MASK 0x1FF
#define MR_MIN_MAP_SIZE 0x10000
/* 64k */
#define MR_CAN_HANDLE_SYNC_CACHE_OFFSET 0X01000000
/*
......@@ -2151,6 +2157,7 @@ struct megasas_instance {
bool fw_sync_cache_support;
bool is_ventura;
bool msix_combined;
u16 max_raid_mapsize;
};
struct MR_LD_VF_MAP {
u32 size;
......
......@@ -4424,8 +4424,7 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type)
static void megasas_update_ext_vd_details(struct megasas_instance *instance)
{
struct fusion_context *fusion;
u32 old_map_sz;
u32 new_map_sz;
u32 ventura_map_sz = 0;
fusion = instance->ctrl_context;
/* For MFI based controllers return dummy success */
......@@ -4455,21 +4454,38 @@ static void megasas_update_ext_vd_details(struct megasas_instance *instance)
instance->supportmax256vd ? "Extended VD(240 VD)firmware" :
"Legacy(64 VD) firmware");
old_map_sz = sizeof(struct MR_FW_RAID_MAP) +
(sizeof(struct MR_LD_SPAN_MAP) *
(instance->fw_supported_vd_count - 1));
new_map_sz = sizeof(struct MR_FW_RAID_MAP_EXT);
fusion->drv_map_sz = sizeof(struct MR_DRV_RAID_MAP) +
(sizeof(struct MR_LD_SPAN_MAP) *
(instance->drv_supported_vd_count - 1));
fusion->max_map_sz = max(old_map_sz, new_map_sz);
if (instance->max_raid_mapsize) {
ventura_map_sz = instance->max_raid_mapsize *
MR_MIN_MAP_SIZE; /* 64k */
fusion->current_map_sz = ventura_map_sz;
fusion->max_map_sz = ventura_map_sz;
} else {
fusion->old_map_sz = sizeof(struct MR_FW_RAID_MAP) +
(sizeof(struct MR_LD_SPAN_MAP) *
(instance->fw_supported_vd_count - 1));
fusion->new_map_sz = sizeof(struct MR_FW_RAID_MAP_EXT);
fusion->max_map_sz =
max(fusion->old_map_sz, fusion->new_map_sz);
if (instance->supportmax256vd)
fusion->current_map_sz = new_map_sz;
else
fusion->current_map_sz = old_map_sz;
if (instance->supportmax256vd)
fusion->current_map_sz = fusion->new_map_sz;
else
fusion->current_map_sz = fusion->old_map_sz;
}
/* irrespective of FW raid maps, driver raid map is constant */
fusion->drv_map_sz = sizeof(struct MR_DRV_RAID_MAP_ALL);
#if VD_EXT_DEBUG
dev_info(&instance->pdev->dev, "instance->max_raid_mapsize 0x%x\n ",
instance->max_raid_mapsize);
dev_info(&instance->pdev->dev, "new_map_sz = 0x%x, old_map_sz = 0x%x\n",
fusion->new_map_sz, fusion->old_map_sz);
dev_info(&instance->pdev->dev, "ventura_map_sz = 0x%x, current_map_sz = 0x%x\n",
ventura_map_sz, fusion->current_map_sz);
dev_info(&instance->pdev->dev, "fusion->drv_map_sz =0x%x, size of driver raid map 0x%lx\n",
fusion->drv_map_sz, sizeof(struct MR_DRV_RAID_MAP_ALL));
#endif
}
/**
......@@ -4996,7 +5012,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
{
u32 max_sectors_1;
u32 max_sectors_2;
u32 tmp_sectors, msix_enable, scratch_pad_2;
u32 tmp_sectors, msix_enable, scratch_pad_2, scratch_pad_3;
resource_size_t base_addr;
struct megasas_register_set __iomem *reg_set;
struct megasas_ctrl_info *ctrl_info = NULL;
......@@ -5072,7 +5088,17 @@ static int megasas_init_fw(struct megasas_instance *instance)
goto fail_ready_state;
}
if (instance->is_ventura) {
scratch_pad_3 =
readl(&instance->reg_set->outbound_scratch_pad_3);
#if VD_EXT_DEBUG
dev_info(&instance->pdev->dev, "scratch_pad3 0x%x\n",
scratch_pad_3);
#endif
instance->max_raid_mapsize = ((scratch_pad_3 >>
MR_MAX_RAID_MAP_SIZE_OFFSET_SHIFT) &
MR_MAX_RAID_MAP_SIZE_MASK);
}
/* Check if MSI-X is supported while in ready state */
msix_enable = (instance->instancet->read_fw_status_reg(reg_set) &
......
This diff is collapsed.
This diff is collapsed.
......@@ -59,6 +59,8 @@
#define MR_RL_FLAGS_GRANT_DESTINATION_CPU1 0x10
#define MR_RL_FLAGS_GRANT_DESTINATION_CUDA 0x80
#define MR_RL_FLAGS_SEQ_NUM_ENABLE 0x8
#define MR_RL_WRITE_THROUGH_MODE 0x00
#define MR_RL_WRITE_BACK_MODE 0x01
/* T10 PI defines */
#define MR_PROT_INFO_TYPE_CONTROLLER 0x8
......@@ -81,6 +83,11 @@
enum MR_RAID_FLAGS_IO_SUB_TYPE {
MR_RAID_FLAGS_IO_SUB_TYPE_NONE = 0,
MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD = 1,
MR_RAID_FLAGS_IO_SUB_TYPE_RMW_DATA = 2,
MR_RAID_FLAGS_IO_SUB_TYPE_RMW_P = 3,
MR_RAID_FLAGS_IO_SUB_TYPE_RMW_Q = 4,
MR_RAID_FLAGS_IO_SUB_TYPE_CACHE_BYPASS = 6,
MR_RAID_FLAGS_IO_SUB_TYPE_LDIO_BW_LIMIT = 7
};
/*
......@@ -109,29 +116,29 @@ enum MR_FUSION_ADAPTER_TYPE {
struct RAID_CONTEXT {
#if defined(__BIG_ENDIAN_BITFIELD)
u8 nseg:4;
u8 Type:4;
u8 nseg:4;
u8 type:4;
#else
u8 Type:4;
u8 nseg:4;
u8 type:4;
u8 nseg:4;
#endif
u8 resvd0;
__le16 timeoutValue;
u8 regLockFlags;
u8 resvd1;
__le16 VirtualDiskTgtId;
__le64 regLockRowLBA;
__le32 regLockLength;
__le16 nextLMId;
u8 exStatus;
u8 status;
u8 RAIDFlags;
u8 numSGE;
__le16 configSeqNum;
u8 spanArm;
u8 priority;
u8 numSGEExt;
u8 resvd2;
u8 resvd0;
__le16 timeout_value;
u8 reg_lock_flags;
u8 resvd1;
__le16 virtual_disk_tgt_id;
__le64 reg_lock_row_lba;
__le32 reg_lock_length;
__le16 next_lmid;
u8 ex_status;
u8 status;
u8 raid_flags;
u8 num_sge;
__le16 config_seq_num;
u8 span_arm;
u8 priority;
u8 num_sge_ext;
u8 resvd2;
};
/*
......@@ -187,7 +194,7 @@ struct RAID_CONTEXT_G35 {
} smid;
u8 ex_status; /* 0x16 : OUT */
u8 status; /* 0x17 status */
u8 RAIDFlags; /* 0x18 resvd[7:6], ioSubType[5:4],
u8 raid_flags; /* 0x18 resvd[7:6], ioSubType[5:4],
* resvd[3:1], preferredCpu[0]
*/
u8 span_arm; /* 0x1C span[7:5], arm[4:0] */
......@@ -672,14 +679,17 @@ struct MPI2_IOC_INIT_REQUEST {
#define MAX_RAIDMAP_ROW_SIZE (MAX_ROW_SIZE)
#define MAX_LOGICAL_DRIVES 64
#define MAX_LOGICAL_DRIVES_EXT 256
#define MAX_LOGICAL_DRIVES_DYN 512
#define MAX_RAIDMAP_LOGICAL_DRIVES (MAX_LOGICAL_DRIVES)
#define MAX_RAIDMAP_VIEWS (MAX_LOGICAL_DRIVES)
#define MAX_ARRAYS 128
#define MAX_RAIDMAP_ARRAYS (MAX_ARRAYS)
#define MAX_ARRAYS_EXT 256
#define MAX_API_ARRAYS_EXT (MAX_ARRAYS_EXT)
#define MAX_API_ARRAYS_DYN 512
#define MAX_PHYSICAL_DEVICES 256
#define MAX_RAIDMAP_PHYSICAL_DEVICES (MAX_PHYSICAL_DEVICES)
#define MAX_RAIDMAP_PHYSICAL_DEVICES_DYN 512
#define MR_DCMD_LD_MAP_GET_INFO 0x0300e101
#define MR_DCMD_SYSTEM_PD_MAP_GET_INFO 0x0200e102
#define MR_DCMD_CTRL_SHARED_HOST_MEM_ALLOC 0x010e8485 /* SR-IOV HB alloc*/
......@@ -726,12 +736,56 @@ struct MR_SPAN_BLOCK_INFO {
struct MR_SPAN_INFO block_span_info;
};
#define MR_RAID_CTX_CPUSEL_0 0
#define MR_RAID_CTX_CPUSEL_1 1
#define MR_RAID_CTX_CPUSEL_2 2
#define MR_RAID_CTX_CPUSEL_3 3
#define MR_RAID_CTX_CPUSEL_FCFS 0xF
struct MR_CPU_AFFINITY_MASK {
union {
struct {
#ifndef MFI_BIG_ENDIAN
u8 hw_path:1;
u8 cpu0:1;
u8 cpu1:1;
u8 cpu2:1;
u8 cpu3:1;
u8 reserved:3;
#else
u8 reserved:3;
u8 cpu3:1;
u8 cpu2:1;
u8 cpu1:1;
u8 cpu0:1;
u8 hw_path:1;
#endif
};
u8 core_mask;
};
};
struct MR_IO_AFFINITY {
union {
struct {
struct MR_CPU_AFFINITY_MASK pdRead;
struct MR_CPU_AFFINITY_MASK pdWrite;
struct MR_CPU_AFFINITY_MASK ldRead;
struct MR_CPU_AFFINITY_MASK ldWrite;
};
u32 word;
};
u8 maxCores; /* Total cores + HW Path in ROC */
u8 reserved[3];
};
struct MR_LD_RAID {
struct {
#if defined(__BIG_ENDIAN_BITFIELD)
u32 reserved4:3;
u32 fp_cache_bypass_capable:1;
u32 fp_rmw_capable:1;
u32 reserved4:2;
u32 fp_cache_bypass_capable:1;
u32 fp_rmw_capable:1;
u32 disable_coalescing:1;
u32 fpBypassRegionLock:1;
u32 tmCapable:1;
u32 fpNonRWCapable:1;
......@@ -759,9 +813,10 @@ struct MR_LD_RAID {
u32 fpNonRWCapable:1;
u32 tmCapable:1;
u32 fpBypassRegionLock:1;
u32 fp_rmw_capable:1;
u32 fp_cache_bypass_capable:1;
u32 reserved4:3;
u32 disable_coalescing:1;
u32 fp_rmw_capable:1;
u32 fp_cache_bypass_capable:1;
u32 reserved4:2;
#endif
} capability;
__le32 reserved6;
......@@ -788,7 +843,36 @@ struct MR_LD_RAID {
u8 LUN[8]; /* 0x24 8 byte LUN field used for SCSI IO's */
u8 fpIoTimeoutForLd;/*0x2C timeout value used by driver in FP IO*/
u8 reserved3[0x80-0x2D]; /* 0x2D */
/* Ox2D This LD accept priority boost of this type */
u8 ld_accept_priority_type;
u8 reserved2[2]; /* 0x2E - 0x2F */
/* 0x30 - 0x33, Logical block size for the LD */
u32 logical_block_length;
struct {
#ifndef MFI_BIG_ENDIAN
/* 0x34, P_I_EXPONENT from READ CAPACITY 16 */
u32 ld_pi_exp:4;
/* 0x34, LOGICAL BLOCKS PER PHYSICAL
* BLOCK EXPONENT from READ CAPACITY 16
*/
u32 ld_logical_block_exp:4;
u32 reserved1:24; /* 0x34 */
#else
u32 reserved1:24; /* 0x34 */
/* 0x34, LOGICAL BLOCKS PER PHYSICAL
* BLOCK EXPONENT from READ CAPACITY 16
*/
u32 ld_logical_block_exp:4;
/* 0x34, P_I_EXPONENT from READ CAPACITY 16 */
u32 ld_pi_exp:4;
#endif
}; /* 0x34 - 0x37 */
/* 0x38 - 0x3f, This will determine which
* core will process LD IO and PD IO.
*/
struct MR_IO_AFFINITY cpuAffinity;
/* Bit definiations are specified by MR_IO_AFFINITY */
u8 reserved3[0x80-0x40]; /* 0x40 - 0x7f */
};
struct MR_LD_SPAN_MAP {
......@@ -846,6 +930,91 @@ struct MR_LD_TARGET_SYNC {
__le16 seqNum;
};
/*
* RAID Map descriptor Types.
* Each element should uniquely idetify one data structure in the RAID map
*/
enum MR_RAID_MAP_DESC_TYPE {
/* MR_DEV_HANDLE_INFO data */
RAID_MAP_DESC_TYPE_DEVHDL_INFO = 0x0,
/* target to Ld num Index map */
RAID_MAP_DESC_TYPE_TGTID_INFO = 0x1,
/* MR_ARRAY_INFO data */
RAID_MAP_DESC_TYPE_ARRAY_INFO = 0x2,
/* MR_LD_SPAN_MAP data */
RAID_MAP_DESC_TYPE_SPAN_INFO = 0x3,
RAID_MAP_DESC_TYPE_COUNT,
};
/*
* This table defines the offset, size and num elements of each descriptor
* type in the RAID Map buffer
*/
struct MR_RAID_MAP_DESC_TABLE {
/* Raid map descriptor type */
u32 raid_map_desc_type;
/* Offset into the RAID map buffer where
* descriptor data is saved
*/
u32 raid_map_desc_offset;
/* total size of the
* descriptor buffer
*/
u32 raid_map_desc_buffer_size;
/* Number of elements contained in the
* descriptor buffer
*/
u32 raid_map_desc_elements;
};
/*
* Dynamic Raid Map Structure.
*/
struct MR_FW_RAID_MAP_DYNAMIC {
u32 raid_map_size; /* total size of RAID Map structure */
u32 desc_table_offset;/* Offset of desc table into RAID map*/
u32 desc_table_size; /* Total Size of desc table */
/* Total Number of elements in the desc table */
u32 desc_table_num_elements;
u64 reserved1;
u32 reserved2[3]; /*future use */
/* timeout value used by driver in FP IOs */
u8 fp_pd_io_timeout_sec;
u8 reserved3[3];
/* when this seqNum increments, driver needs to
* release RMW buffers asap
*/
u32 rmw_fp_seq_num;
u16 ld_count; /* count of lds. */
u16 ar_count; /* count of arrays */
u16 span_count; /* count of spans */
u16 reserved4[3];
/*
* The below structure of pointers is only to be used by the driver.
* This is added in the ,API to reduce the amount of code changes
* needed in the driver to support dynamic RAID map Firmware should
* not update these pointers while preparing the raid map
*/
union {
struct {
struct MR_DEV_HANDLE_INFO *dev_hndl_info;
u16 *ld_tgt_id_to_ld;
struct MR_ARRAY_INFO *ar_map_info;
struct MR_LD_SPAN_MAP *ld_span_map;
};
u64 ptr_structure_size[RAID_MAP_DESC_TYPE_COUNT];
};
/*
* RAID Map descriptor table defines the layout of data in the RAID Map.
* The size of the descriptor table itself could change.
*/
/* Variable Size descriptor Table. */
struct MR_RAID_MAP_DESC_TABLE
raid_map_desc_table[RAID_MAP_DESC_TYPE_COUNT];
/* Variable Size buffer containing all data */
u32 raid_map_desc_data[1];
}; /* Dynamicaly sized RAID MAp structure */
#define IEEE_SGE_FLAGS_ADDR_MASK (0x03)
#define IEEE_SGE_FLAGS_SYSTEM_ADDR (0x00)
#define IEEE_SGE_FLAGS_IOCDDR_ADDR (0x01)
......@@ -955,9 +1124,10 @@ struct MR_DRV_RAID_MAP {
__le16 spanCount;
__le16 reserve3;
struct MR_DEV_HANDLE_INFO devHndlInfo[MAX_RAIDMAP_PHYSICAL_DEVICES];
u8 ldTgtIdToLd[MAX_LOGICAL_DRIVES_EXT];
struct MR_ARRAY_INFO arMapInfo[MAX_API_ARRAYS_EXT];
struct MR_DEV_HANDLE_INFO
devHndlInfo[MAX_RAIDMAP_PHYSICAL_DEVICES_DYN];
u16 ldTgtIdToLd[MAX_LOGICAL_DRIVES_DYN];
struct MR_ARRAY_INFO arMapInfo[MAX_API_ARRAYS_DYN];
struct MR_LD_SPAN_MAP ldSpanMap[1];
};
......@@ -969,7 +1139,7 @@ struct MR_DRV_RAID_MAP {
struct MR_DRV_RAID_MAP_ALL {
struct MR_DRV_RAID_MAP raidMap;
struct MR_LD_SPAN_MAP ldSpanMap[MAX_LOGICAL_DRIVES_EXT - 1];
struct MR_LD_SPAN_MAP ldSpanMap[MAX_LOGICAL_DRIVES_DYN - 1];
} __packed;
......@@ -1088,7 +1258,7 @@ struct fusion_context {
u8 chain_offset_io_request;
u8 chain_offset_mfi_pthru;
struct MR_FW_RAID_MAP_ALL *ld_map[2];
struct MR_FW_RAID_MAP_DYNAMIC *ld_map[2];
dma_addr_t ld_map_phys[2];
/*Non dma-able memory. Driver local copy.*/
......@@ -1096,6 +1266,8 @@ struct fusion_context {
u32 max_map_sz;
u32 current_map_sz;
u32 old_map_sz;
u32 new_map_sz;
u32 drv_map_sz;
u32 drv_map_pages;
struct MR_PD_CFG_SEQ_NUM_SYNC *pd_seq_sync[JBOD_MAPS_COUNT];
......
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