linuxtorvalds / rpms / kernel

Forked from rpms/kernel 2 years ago
Clone
Blob Blame History Raw
From 88b3ac2949cb535c5213324f33e9745d769f7dad Mon Sep 17 00:00:00 2001
From: Sasikumar Chandrasekaran <sasikumar.pc@broadcom.com>
Date: Tue, 10 Jan 2017 18:20:48 -0500
Subject: [PATCH 06/11] 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: Sasikumar Chandrasekaran <sasikumar.pc@broadcom.com>
Reviewed-by: Tomas Henzl <thenzl@redhat.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
---
 drivers/scsi/megaraid/megaraid_sas.h        |   7 +
 drivers/scsi/megaraid/megaraid_sas_base.c   |  60 ++++--
 drivers/scsi/megaraid/megaraid_sas_fp.c     | 301 ++++++++++++++++++++++++----
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 225 ++++++++++++++++-----
 drivers/scsi/megaraid/megaraid_sas_fusion.h | 240 ++++++++++++++++++----
 5 files changed, 695 insertions(+), 138 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 0b4d37b..d5205c4 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -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
 
 /*
@@ -2152,6 +2158,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;
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index 0722286..1d8cf03 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -4457,8 +4457,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 */
@@ -4488,21 +4487,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
 }
 
 /**
@@ -5043,7 +5059,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;
@@ -5119,7 +5135,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) &
diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c
index 3644dbc..e45affe 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fp.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fp.c
@@ -179,18 +179,204 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance)
 	struct fusion_context *fusion = instance->ctrl_context;
 	struct MR_FW_RAID_MAP_ALL     *fw_map_old    = NULL;
 	struct MR_FW_RAID_MAP         *pFwRaidMap    = NULL;
-	int i;
+	int i, j;
 	u16 ld_count;
+	struct MR_FW_RAID_MAP_DYNAMIC *fw_map_dyn;
+	struct MR_FW_RAID_MAP_EXT *fw_map_ext;
+	struct MR_RAID_MAP_DESC_TABLE *desc_table;
 
 
 	struct MR_DRV_RAID_MAP_ALL *drv_map =
 			fusion->ld_drv_map[(instance->map_id & 1)];
 	struct MR_DRV_RAID_MAP *pDrvRaidMap = &drv_map->raidMap;
+	void *raid_map_data = NULL;
+
+	memset(drv_map, 0, fusion->drv_map_sz);
+	memset(pDrvRaidMap->ldTgtIdToLd,
+		0xff, (sizeof(u16) * MAX_LOGICAL_DRIVES_DYN));
+
+	if (instance->max_raid_mapsize) {
+		fw_map_dyn = fusion->ld_map[(instance->map_id & 1)];
+#if VD_EXT_DEBUG
+		dev_dbg(&instance->pdev->dev, "raidMapSize 0x%x fw_map_dyn->descTableOffset 0x%x\n",
+			le32_to_cpu(fw_map_dyn->raid_map_size),
+			le32_to_cpu(fw_map_dyn->desc_table_offset));
+		dev_dbg(&instance->pdev->dev, "descTableSize 0x%x descTableNumElements 0x%x\n",
+			le32_to_cpu(fw_map_dyn->desc_table_size),
+			le32_to_cpu(fw_map_dyn->desc_table_num_elements));
+		dev_dbg(&instance->pdev->dev, "drv map %p ldCount %d\n",
+			drv_map, fw_map_dyn->ld_count);
+#endif
+		desc_table =
+		(struct MR_RAID_MAP_DESC_TABLE *)((void *)fw_map_dyn + le32_to_cpu(fw_map_dyn->desc_table_offset));
+		if (desc_table != fw_map_dyn->raid_map_desc_table)
+			dev_dbg(&instance->pdev->dev, "offsets of desc table are not matching desc %p original %p\n",
+				desc_table, fw_map_dyn->raid_map_desc_table);
+
+		ld_count = (u16)le16_to_cpu(fw_map_dyn->ld_count);
+		pDrvRaidMap->ldCount = (__le16)cpu_to_le16(ld_count);
+		pDrvRaidMap->fpPdIoTimeoutSec =
+			fw_map_dyn->fp_pd_io_timeout_sec;
+		pDrvRaidMap->totalSize = sizeof(struct MR_DRV_RAID_MAP_ALL);
+		/* point to actual data starting point*/
+		raid_map_data = (void *)fw_map_dyn +
+			le32_to_cpu(fw_map_dyn->desc_table_offset) +
+			le32_to_cpu(fw_map_dyn->desc_table_size);
+
+		for (i = 0; i < le32_to_cpu(fw_map_dyn->desc_table_num_elements); ++i) {
+
+#if VD_EXT_DEBUG
+			dev_dbg(&instance->pdev->dev, "desc table %p\n",
+				desc_table);
+			dev_dbg(&instance->pdev->dev, "raidmap type %d, raidmapOffset 0x%x\n",
+				desc_table->raid_map_desc_type,
+				desc_table->raid_map_desc_offset);
+			dev_dbg(&instance->pdev->dev, "raid map number of elements 0%x, raidmapsize 0x%x\n",
+				desc_table->raid_map_desc_elements,
+				desc_table->raid_map_desc_buffer_size);
+#endif
+			switch (le32_to_cpu(desc_table->raid_map_desc_type)) {
+			case RAID_MAP_DESC_TYPE_DEVHDL_INFO:
+				fw_map_dyn->dev_hndl_info =
+				(struct MR_DEV_HANDLE_INFO *)(raid_map_data + le32_to_cpu(desc_table->raid_map_desc_offset));
+#if VD_EXT_DEBUG
+				dev_dbg(&instance->pdev->dev, "devHndlInfo  address %p\n",
+					fw_map_dyn->dev_hndl_info);
+#endif
+				memcpy(pDrvRaidMap->devHndlInfo,
+				fw_map_dyn->dev_hndl_info,
+				sizeof(struct MR_DEV_HANDLE_INFO) *
+				le32_to_cpu(desc_table->raid_map_desc_elements));
+			break;
+			case RAID_MAP_DESC_TYPE_TGTID_INFO:
+				fw_map_dyn->ld_tgt_id_to_ld =
+				(u16 *) (raid_map_data +
+				le32_to_cpu(desc_table->raid_map_desc_offset));
+#if VD_EXT_DEBUG
+			dev_dbg(&instance->pdev->dev, "ldTgtIdToLd  address %p\n",
+				fw_map_dyn->ld_tgt_id_to_ld);
+#endif
+			for (j = 0; j < le32_to_cpu(desc_table->raid_map_desc_elements); j++) {
+				pDrvRaidMap->ldTgtIdToLd[j] =
+				fw_map_dyn->ld_tgt_id_to_ld[j];
+#if VD_EXT_DEBUG
+				dev_dbg(&instance->pdev->dev, " %d drv ldTgtIdToLd %d\n",
+					j, pDrvRaidMap->ldTgtIdToLd[j]);
+#endif
+			}
+			break;
+			case RAID_MAP_DESC_TYPE_ARRAY_INFO:
+				fw_map_dyn->ar_map_info =
+				(struct MR_ARRAY_INFO *)
+				(raid_map_data + le32_to_cpu(desc_table->raid_map_desc_offset));
+#if VD_EXT_DEBUG
+				dev_dbg(&instance->pdev->dev, "arMapInfo  address %p\n",
+					fw_map_dyn->ar_map_info);
+#endif
+
+				memcpy(pDrvRaidMap->arMapInfo,
+				fw_map_dyn->ar_map_info,
+				sizeof(struct MR_ARRAY_INFO) * le32_to_cpu(desc_table->raid_map_desc_elements));
+			break;
+			case RAID_MAP_DESC_TYPE_SPAN_INFO:
+				fw_map_dyn->ld_span_map =
+				(struct MR_LD_SPAN_MAP *)
+				(raid_map_data + le32_to_cpu(desc_table->raid_map_desc_offset));
+				memcpy(pDrvRaidMap->ldSpanMap,
+				fw_map_dyn->ld_span_map,
+				sizeof(struct MR_LD_SPAN_MAP) * le32_to_cpu(desc_table->raid_map_desc_elements));
+#if VD_EXT_DEBUG
+				dev_dbg(&instance->pdev->dev, "ldSpanMap  address %p\n",
+					fw_map_dyn->ld_span_map);
+				dev_dbg(&instance->pdev->dev, "MR_LD_SPAN_MAP size 0x%lx\n",
+					sizeof(struct MR_LD_SPAN_MAP));
+				for (j = 0; j < ld_count; j++) {
+					dev_dbg(&instance->pdev->dev, "megaraid_sas(%d) : fw_map_dyn->ldSpanMap[%d].ldRaid.targetId 0x%x\n",
+					j, j, fw_map_dyn->ld_span_map[j].ldRaid.targetId);
+					dev_dbg(&instance->pdev->dev, "fw_map_dyn->ldSpanMap[%d].ldRaid.seqNum 0x%x\n",
+					j, fw_map_dyn->ld_span_map[j].ldRaid.seqNum);
+					dev_dbg(&instance->pdev->dev, "fw_map_dyn->ld_span_map[%d].ldRaid.rowSize 0x%x\n",
+					j, (u32)fw_map_dyn->ld_span_map[j].ldRaid.rowSize);
+
+					dev_dbg(&instance->pdev->dev, "megaraid_sas(%d) :pDrvRaidMap->ldSpanMap[%d].ldRaid.targetId 0x%x\n",
+					j, j, pDrvRaidMap->ldSpanMap[j].ldRaid.targetId);
+					dev_dbg(&instance->pdev->dev, "DrvRaidMap->ldSpanMap[%d].ldRaid.seqNum 0x%x\n",
+					j, pDrvRaidMap->ldSpanMap[j].ldRaid.seqNum);
+					dev_dbg(&instance->pdev->dev, "pDrvRaidMap->ldSpanMap[%d].ldRaid.rowSize 0x%x\n",
+					j, (u32)pDrvRaidMap->ldSpanMap[j].ldRaid.rowSize);
+
+					dev_dbg(&instance->pdev->dev, "megaraid_sas(%d) : drv raid map all %p\n",
+					instance->unique_id, drv_map);
+					dev_dbg(&instance->pdev->dev, "raid map %p LD RAID MAP %p/%p\n",
+					pDrvRaidMap,
+					&fw_map_dyn->ld_span_map[j].ldRaid,
+					&pDrvRaidMap->ldSpanMap[j].ldRaid);
+				}
+#endif
+			break;
+			default:
+				dev_dbg(&instance->pdev->dev, "wrong number of desctableElements %d\n",
+					fw_map_dyn->desc_table_num_elements);
+			}
+			++desc_table;
+		}
+
+	} else if (instance->supportmax256vd) {
+		fw_map_ext =
+		(struct MR_FW_RAID_MAP_EXT *) fusion->ld_map[(instance->map_id & 1)];
+		ld_count = (u16)le16_to_cpu(fw_map_ext->ldCount);
+		if (ld_count > MAX_LOGICAL_DRIVES_EXT) {
+			dev_dbg(&instance->pdev->dev, "megaraid_sas: LD count exposed in RAID map in not valid\n");
+			return;
+		}
+#if VD_EXT_DEBUG
+		for (i = 0; i < ld_count; i++) {
+			dev_dbg(&instance->pdev->dev, "megaraid_sas(%d) :Index 0x%x\n",
+				instance->unique_id, i);
+			dev_dbg(&instance->pdev->dev, "Target Id 0x%x\n",
+				fw_map_ext->ldSpanMap[i].ldRaid.targetId);
+			dev_dbg(&instance->pdev->dev, "Seq Num 0x%x Size 0/%llx\n",
+				fw_map_ext->ldSpanMap[i].ldRaid.seqNum,
+				fw_map_ext->ldSpanMap[i].ldRaid.size);
+		}
+#endif
+
+		pDrvRaidMap->ldCount = (__le16)cpu_to_le16(ld_count);
+		pDrvRaidMap->fpPdIoTimeoutSec = fw_map_ext->fpPdIoTimeoutSec;
+		for (i = 0; i < (MAX_LOGICAL_DRIVES_EXT); i++)
+			pDrvRaidMap->ldTgtIdToLd[i] =
+				(u16)fw_map_ext->ldTgtIdToLd[i];
+		memcpy(pDrvRaidMap->ldSpanMap, fw_map_ext->ldSpanMap,
+				sizeof(struct MR_LD_SPAN_MAP) * ld_count);
+#if VD_EXT_DEBUG
+		for (i = 0; i < ld_count; i++) {
+			dev_dbg(&instance->pdev->dev, "megaraid_sas(%d) : fw_map_ext->ldSpanMap[%d].ldRaid.targetId 0x%x\n",
+			i, i, fw_map_ext->ldSpanMap[i].ldRaid.targetId);
+			dev_dbg(&instance->pdev->dev, "fw_map_ext->ldSpanMap[%d].ldRaid.seqNum 0x%x\n",
+			i, fw_map_ext->ldSpanMap[i].ldRaid.seqNum);
+			dev_dbg(&instance->pdev->dev, "fw_map_ext->ldSpanMap[%d].ldRaid.rowSize 0x%x\n",
+			i, (u32)fw_map_ext->ldSpanMap[i].ldRaid.rowSize);
+
+			dev_dbg(&instance->pdev->dev, "megaraid_sas(%d) : pDrvRaidMap->ldSpanMap[%d].ldRaid.targetId 0x%x\n",
+			i, i, pDrvRaidMap->ldSpanMap[i].ldRaid.targetId);
+			dev_dbg(&instance->pdev->dev, "pDrvRaidMap->ldSpanMap[%d].ldRaid.seqNum 0x%x\n",
+			i, pDrvRaidMap->ldSpanMap[i].ldRaid.seqNum);
+			dev_dbg(&instance->pdev->dev, "pDrvRaidMap->ldSpanMap[%d].ldRaid.rowSize 0x%x\n",
+			i, (u32)pDrvRaidMap->ldSpanMap[i].ldRaid.rowSize);
+
+			dev_dbg(&instance->pdev->dev, "megaraid_sas(%d) : drv raid map all %p\n",
+			instance->unique_id, drv_map);
+			dev_dbg(&instance->pdev->dev, "raid map %p LD RAID MAP %p %p\n",
+			pDrvRaidMap, &fw_map_ext->ldSpanMap[i].ldRaid,
+			&pDrvRaidMap->ldSpanMap[i].ldRaid);
+		}
+#endif
+		memcpy(pDrvRaidMap->arMapInfo, fw_map_ext->arMapInfo,
+			sizeof(struct MR_ARRAY_INFO) * MAX_API_ARRAYS_EXT);
+		memcpy(pDrvRaidMap->devHndlInfo, fw_map_ext->devHndlInfo,
+			sizeof(struct MR_DEV_HANDLE_INFO) *
+					MAX_RAIDMAP_PHYSICAL_DEVICES);
 
-	if (instance->supportmax256vd) {
-		memcpy(fusion->ld_drv_map[instance->map_id & 1],
-			fusion->ld_map[instance->map_id & 1],
-			fusion->current_map_sz);
 		/* New Raid map will not set totalSize, so keep expected value
 		 * for legacy code in ValidateMapInfo
 		 */
@@ -213,16 +399,12 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance)
 		}
 #endif
 
-		memset(drv_map, 0, fusion->drv_map_sz);
 		pDrvRaidMap->totalSize = pFwRaidMap->totalSize;
 		pDrvRaidMap->ldCount = (__le16)cpu_to_le16(ld_count);
 		pDrvRaidMap->fpPdIoTimeoutSec = pFwRaidMap->fpPdIoTimeoutSec;
 		for (i = 0; i < MAX_RAIDMAP_LOGICAL_DRIVES + MAX_RAIDMAP_VIEWS; i++)
 			pDrvRaidMap->ldTgtIdToLd[i] =
 				(u8)pFwRaidMap->ldTgtIdToLd[i];
-		for (i = (MAX_RAIDMAP_LOGICAL_DRIVES + MAX_RAIDMAP_VIEWS);
-			i < MAX_LOGICAL_DRIVES_EXT; i++)
-			pDrvRaidMap->ldTgtIdToLd[i] = 0xff;
 		for (i = 0; i < ld_count; i++) {
 			pDrvRaidMap->ldSpanMap[i] = pFwRaidMap->ldSpanMap[i];
 #if VD_EXT_DEBUG
@@ -279,7 +461,9 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance)
 	lbInfo = fusion->load_balance_info;
 	ldSpanInfo = fusion->log_to_span;
 
-	if (instance->supportmax256vd)
+	if (instance->max_raid_mapsize)
+		expected_size = sizeof(struct MR_DRV_RAID_MAP_ALL);
+	else if (instance->supportmax256vd)
 		expected_size = sizeof(struct MR_FW_RAID_MAP_EXT);
 	else
 		expected_size =
@@ -287,8 +471,10 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance)
 			(sizeof(struct MR_LD_SPAN_MAP) * le16_to_cpu(pDrvRaidMap->ldCount)));
 
 	if (le32_to_cpu(pDrvRaidMap->totalSize) != expected_size) {
-		dev_err(&instance->pdev->dev, "map info structure size 0x%x is not matching with ld count\n",
-		       (unsigned int) expected_size);
+		dev_dbg(&instance->pdev->dev, "megasas: map info structure size 0x%x",
+			le32_to_cpu(pDrvRaidMap->totalSize));
+		dev_dbg(&instance->pdev->dev, "is not matching expected size 0x%x\n",
+			(unsigned int) expected_size);
 		dev_err(&instance->pdev->dev, "megasas: span map %x, pDrvRaidMap->totalSize : %x\n",
 			(unsigned int)sizeof(struct MR_LD_SPAN_MAP),
 			le32_to_cpu(pDrvRaidMap->totalSize));
@@ -787,7 +973,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld,
 			((fusion->adapter_type == THUNDERBOLT_SERIES)  ||
 			((fusion->adapter_type == INVADER_SERIES) &&
 			(raid->regTypeReqOnRead != REGION_TYPE_UNUSED))))
-			pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE;
+			pRAID_Context->reg_lock_flags = REGION_TYPE_EXCLUSIVE;
 		else if (raid->level == 1) {
 			pd = MR_ArPdGet(arRef, physArm + 1, map);
 			if (pd != MR_PD_INVALID)
@@ -796,9 +982,16 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld,
 	}
 
 	*pdBlock += stripRef + le64_to_cpu(MR_LdSpanPtrGet(ld, span, map)->startBlk);
-	pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) |
-					physArm;
-	io_info->span_arm = pRAID_Context->spanArm;
+	if (instance->is_ventura) {
+		((struct RAID_CONTEXT_G35 *) pRAID_Context)->span_arm =
+			(span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
+		io_info->span_arm =
+			(span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
+	} else {
+		pRAID_Context->span_arm =
+			(span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
+		io_info->span_arm = pRAID_Context->span_arm;
+	}
 	return retval;
 }
 
@@ -890,7 +1083,7 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow,
 			((fusion->adapter_type == THUNDERBOLT_SERIES)  ||
 			((fusion->adapter_type == INVADER_SERIES) &&
 			(raid->regTypeReqOnRead != REGION_TYPE_UNUSED))))
-			pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE;
+			pRAID_Context->reg_lock_flags = REGION_TYPE_EXCLUSIVE;
 		else if (raid->level == 1) {
 			/* Get alternate Pd. */
 			pd = MR_ArPdGet(arRef, physArm + 1, map);
@@ -901,9 +1094,16 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow,
 	}
 
 	*pdBlock += stripRef + le64_to_cpu(MR_LdSpanPtrGet(ld, span, map)->startBlk);
-	pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) |
-		physArm;
-	io_info->span_arm = pRAID_Context->spanArm;
+	if (instance->is_ventura) {
+		((struct RAID_CONTEXT_G35 *) pRAID_Context)->span_arm =
+				(span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
+		io_info->span_arm =
+				(span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
+	} else {
+		pRAID_Context->span_arm =
+			(span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
+		io_info->span_arm = pRAID_Context->span_arm;
+	}
 	return retval;
 }
 
@@ -1107,20 +1307,20 @@ MR_BuildRaidContext(struct megasas_instance *instance,
 			regSize += stripSize;
 	}
 
-	pRAID_Context->timeoutValue =
+	pRAID_Context->timeout_value =
 		cpu_to_le16(raid->fpIoTimeoutForLd ?
 			    raid->fpIoTimeoutForLd :
 			    map->raidMap.fpPdIoTimeoutSec);
 	if (fusion->adapter_type == INVADER_SERIES)
-		pRAID_Context->regLockFlags = (isRead) ?
+		pRAID_Context->reg_lock_flags = (isRead) ?
 			raid->regTypeReqOnRead : raid->regTypeReqOnWrite;
-	else
-		pRAID_Context->regLockFlags = (isRead) ?
+	else if (!instance->is_ventura)
+		pRAID_Context->reg_lock_flags = (isRead) ?
 			REGION_TYPE_SHARED_READ : raid->regTypeReqOnWrite;
-	pRAID_Context->VirtualDiskTgtId = raid->targetId;
-	pRAID_Context->regLockRowLBA    = cpu_to_le64(regStart);
-	pRAID_Context->regLockLength    = cpu_to_le32(regSize);
-	pRAID_Context->configSeqNum	= raid->seqNum;
+	pRAID_Context->virtual_disk_tgt_id = raid->targetId;
+	pRAID_Context->reg_lock_row_lba    = cpu_to_le64(regStart);
+	pRAID_Context->reg_lock_length    = cpu_to_le32(regSize);
+	pRAID_Context->config_seq_num	= raid->seqNum;
 	/* save pointer to raid->LUN array */
 	*raidLUN = raid->LUN;
 
@@ -1138,6 +1338,13 @@ MR_BuildRaidContext(struct megasas_instance *instance,
 		/* If IO on an invalid Pd, then FP is not possible.*/
 		if (io_info->devHandle == cpu_to_le16(MR_PD_INVALID))
 			io_info->fpOkForIo = FALSE;
+		/* if FP possible, set the SLUD bit in
+		 *  regLockFlags for ventura
+		 */
+		else if ((instance->is_ventura) && (!isRead) &&
+			(raid->writeMode == MR_RL_WRITE_BACK_MODE) &&
+			(raid->capability.fp_cache_bypass_capable))
+			((struct RAID_CONTEXT_G35 *) pRAID_Context)->routing_flags.bits.sld = 1;
 		/* set raid 1/10 fast path write capable bit in io_info */
 		if (io_info->fpOkForIo &&
 		    (io_info->r1_alt_dev_handle != MR_PD_INVALID) &&
@@ -1317,6 +1524,7 @@ u8 megasas_get_best_arm_pd(struct megasas_instance *instance,
 	struct fusion_context *fusion;
 	struct MR_LD_RAID  *raid;
 	struct MR_DRV_RAID_MAP_ALL *drv_map;
+	u16	pd1_dev_handle;
 	u16     pend0, pend1, ld;
 	u64     diff0, diff1;
 	u8      bestArm, pd0, pd1, span, arm;
@@ -1342,23 +1550,36 @@ u8 megasas_get_best_arm_pd(struct megasas_instance *instance,
 	pd1 = MR_ArPdGet(arRef, (arm + 1) >= span_row_size ?
 		(arm + 1 - span_row_size) : arm + 1, drv_map);
 
-	/* get the pending cmds for the data and mirror arms */
-	pend0 = atomic_read(&lbInfo->scsi_pending_cmds[pd0]);
-	pend1 = atomic_read(&lbInfo->scsi_pending_cmds[pd1]);
+	/* Get PD1 Dev Handle */
+
+	pd1_dev_handle = MR_PdDevHandleGet(pd1, drv_map);
+
+	if (pd1_dev_handle == MR_PD_INVALID) {
+		bestArm = arm;
+	} else {
+		/* get the pending cmds for the data and mirror arms */
+		pend0 = atomic_read(&lbInfo->scsi_pending_cmds[pd0]);
+		pend1 = atomic_read(&lbInfo->scsi_pending_cmds[pd1]);
 
-	/* Determine the disk whose head is nearer to the req. block */
-	diff0 = ABS_DIFF(block, lbInfo->last_accessed_block[pd0]);
-	diff1 = ABS_DIFF(block, lbInfo->last_accessed_block[pd1]);
-	bestArm = (diff0 <= diff1 ? arm : arm ^ 1);
+		/* Determine the disk whose head is nearer to the req. block */
+		diff0 = ABS_DIFF(block, lbInfo->last_accessed_block[pd0]);
+		diff1 = ABS_DIFF(block, lbInfo->last_accessed_block[pd1]);
+		bestArm = (diff0 <= diff1 ? arm : arm ^ 1);
 
-	if ((bestArm == arm && pend0 > pend1 + lb_pending_cmds)  ||
+		/* Make balance count from 16 to 4 to
+		 *  keep driver in sync with Firmware
+		 */
+		if ((bestArm == arm && pend0 > pend1 + lb_pending_cmds)  ||
 			(bestArm != arm && pend1 > pend0 + lb_pending_cmds))
-		bestArm ^= 1;
+			bestArm ^= 1;
+
+		/* Update the last accessed block on the correct pd */
+		io_info->span_arm =
+			(span << RAID_CTX_SPANARM_SPAN_SHIFT) | bestArm;
+		io_info->pd_after_lb = (bestArm == arm) ? pd0 : pd1;
+	}
 
-	/* Update the last accessed block on the correct pd */
-	io_info->pd_after_lb = (bestArm == arm) ? pd0 : pd1;
 	lbInfo->last_accessed_block[io_info->pd_after_lb] = block + count - 1;
-	io_info->span_arm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | bestArm;
 #if SPAN_DEBUG
 	if (arm != bestArm)
 		dev_dbg(&instance->pdev->dev, "LSI Debug R1 Load balance "
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index b146cd1..178f166 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -1829,7 +1829,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
 			  struct megasas_cmd_fusion *cmd)
 {
 	u8 fp_possible;
-	u32 start_lba_lo, start_lba_hi, device_id, datalength = 0;
+	u32 start_lba_lo, start_lba_hi, device_id, datalength = 0, ld;
 	struct MPI2_RAID_SCSI_IO_REQUEST *io_request;
 	union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
 	struct IO_REQUEST_INFO io_info;
@@ -1837,16 +1837,18 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
 	struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
 	u8 *raidLUN;
 	unsigned long spinlock_flags;
+	union RAID_CONTEXT_UNION *praid_context;
+	struct MR_LD_RAID *raid;
 
 	device_id = MEGASAS_DEV_INDEX(scp);
 
 	fusion = instance->ctrl_context;
 
 	io_request = cmd->io_request;
-	io_request->RaidContext.raid_context.VirtualDiskTgtId =
+	io_request->RaidContext.raid_context.virtual_disk_tgt_id =
 		cpu_to_le16(device_id);
 	io_request->RaidContext.raid_context.status = 0;
-	io_request->RaidContext.raid_context.exStatus = 0;
+	io_request->RaidContext.raid_context.ex_status = 0;
 
 	req_desc = (union MEGASAS_REQUEST_DESCRIPTOR_UNION *)cmd->request_desc;
 
@@ -1915,10 +1917,12 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
 		io_info.isRead = 1;
 
 	local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
+	ld = MR_TargetIdToLdGet(device_id, local_map_ptr);
+	raid = MR_LdRaidGet(ld, local_map_ptr);
 
 	if ((MR_TargetIdToLdGet(device_id, local_map_ptr) >=
 		instance->fw_supported_vd_count) || (!fusion->fast_path_io)) {
-		io_request->RaidContext.raid_context.regLockFlags  = 0;
+		io_request->RaidContext.raid_context.reg_lock_flags  = 0;
 		fp_possible = 0;
 	} else {
 		if (MR_BuildRaidContext(instance, &io_info,
@@ -1945,6 +1949,8 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
 			fp_possible = false;
 	}
 
+	praid_context = &io_request->RaidContext;
+
 	if (fp_possible) {
 		megasas_set_pd_lba(io_request, scp->cmd_len, &io_info, scp,
 				   local_map_ptr, start_lba_lo);
@@ -1953,18 +1959,25 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
 			(MPI2_REQ_DESCRIPT_FLAGS_FP_IO
 			 << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
 		if (fusion->adapter_type == INVADER_SERIES) {
-			if (io_request->RaidContext.raid_context.regLockFlags ==
+			if (io_request->RaidContext.raid_context.reg_lock_flags ==
 			    REGION_TYPE_UNUSED)
 				cmd->request_desc->SCSIIO.RequestFlags =
 					(MEGASAS_REQ_DESCRIPT_FLAGS_NO_LOCK <<
 					MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
-			io_request->RaidContext.raid_context.Type
+			io_request->RaidContext.raid_context.type
 				= MPI2_TYPE_CUDA;
 			io_request->RaidContext.raid_context.nseg = 0x1;
 			io_request->IoFlags |= cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH);
-			io_request->RaidContext.raid_context.regLockFlags |=
+			io_request->RaidContext.raid_context.reg_lock_flags |=
 			  (MR_RL_FLAGS_GRANT_DESTINATION_CUDA |
 			   MR_RL_FLAGS_SEQ_NUM_ENABLE);
+		} else if (instance->is_ventura) {
+			io_request->RaidContext.raid_context_g35.type
+				= MPI2_TYPE_CUDA;
+			io_request->RaidContext.raid_context_g35.nseg = 0x1;
+			io_request->RaidContext.raid_context_g35.routing_flags.bits.sqn = 1;
+			io_request->IoFlags |=
+			cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH);
 		}
 		if ((fusion->load_balance_info[device_id].loadBalanceFlag) &&
 		    (io_info.isRead)) {
@@ -1974,6 +1987,13 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
 					&io_info);
 			scp->SCp.Status |= MEGASAS_LOAD_BALANCE_FLAG;
 			cmd->pd_r1_lb = io_info.pd_after_lb;
+			if (instance->is_ventura)
+				io_request->RaidContext.raid_context_g35.span_arm
+					= io_info.span_arm;
+			else
+				io_request->RaidContext.raid_context.span_arm
+					= io_info.span_arm;
+
 		} else
 			scp->SCp.Status &= ~MEGASAS_LOAD_BALANCE_FLAG;
 
@@ -1992,28 +2012,98 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
 		io_request->DevHandle = io_info.devHandle;
 		/* populate the LUN field */
 		memcpy(io_request->LUN, raidLUN, 8);
+		if (instance->is_ventura) {
+			if (io_info.isRead) {
+				if ((raid->cpuAffinity.pdRead.cpu0) &&
+					(raid->cpuAffinity.pdRead.cpu1))
+					praid_context->raid_context_g35.routing_flags.bits.cpu_sel
+					= MR_RAID_CTX_CPUSEL_FCFS;
+				else if (raid->cpuAffinity.pdRead.cpu1)
+					praid_context->raid_context_g35.routing_flags.bits.cpu_sel
+					= MR_RAID_CTX_CPUSEL_1;
+				else
+					praid_context->raid_context_g35.routing_flags.bits.cpu_sel
+					= MR_RAID_CTX_CPUSEL_0;
+			} else {
+			if ((raid->cpuAffinity.pdWrite.cpu0)
+			&& (raid->cpuAffinity.pdWrite.cpu1))
+				praid_context->raid_context_g35.routing_flags.bits.cpu_sel
+					= MR_RAID_CTX_CPUSEL_FCFS;
+				else if (raid->cpuAffinity.pdWrite.cpu1)
+					praid_context->raid_context_g35.routing_flags.bits.cpu_sel
+					= MR_RAID_CTX_CPUSEL_1;
+				else
+					praid_context->raid_context_g35.routing_flags.bits.cpu_sel
+					= MR_RAID_CTX_CPUSEL_0;
+				if (praid_context->raid_context_g35.routing_flags.bits.sld) {
+					praid_context->raid_context_g35.raid_flags
+					= (MR_RAID_FLAGS_IO_SUB_TYPE_CACHE_BYPASS
+					<< MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT);
+				}
+			}
+		}
 	} else {
-		io_request->RaidContext.raid_context.timeoutValue =
+		io_request->RaidContext.raid_context.timeout_value =
 			cpu_to_le16(local_map_ptr->raidMap.fpPdIoTimeoutSec);
 		cmd->request_desc->SCSIIO.RequestFlags =
 			(MEGASAS_REQ_DESCRIPT_FLAGS_LD_IO
 			 << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
 		if (fusion->adapter_type == INVADER_SERIES) {
 			if (io_info.do_fp_rlbypass ||
-			(io_request->RaidContext.raid_context.regLockFlags
+			(io_request->RaidContext.raid_context.reg_lock_flags
 					== REGION_TYPE_UNUSED))
 				cmd->request_desc->SCSIIO.RequestFlags =
 					(MEGASAS_REQ_DESCRIPT_FLAGS_NO_LOCK <<
 					MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
-			io_request->RaidContext.raid_context.Type
+			io_request->RaidContext.raid_context.type
 				= MPI2_TYPE_CUDA;
-			io_request->RaidContext.raid_context.regLockFlags |=
+			io_request->RaidContext.raid_context.reg_lock_flags |=
 				(MR_RL_FLAGS_GRANT_DESTINATION_CPU0 |
 				 MR_RL_FLAGS_SEQ_NUM_ENABLE);
 			io_request->RaidContext.raid_context.nseg = 0x1;
+		} else if (instance->is_ventura) {
+			io_request->RaidContext.raid_context_g35.type
+				= MPI2_TYPE_CUDA;
+			io_request->RaidContext.raid_context_g35.routing_flags.bits.sqn = 1;
+			io_request->RaidContext.raid_context_g35.nseg = 0x1;
 		}
 		io_request->Function = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
 		io_request->DevHandle = cpu_to_le16(device_id);
+
+		if (instance->is_ventura) {
+			if (io_info.isRead) {
+				if ((raid->cpuAffinity.ldRead.cpu0)
+				&& (raid->cpuAffinity.ldRead.cpu1))
+					praid_context->raid_context_g35.routing_flags.bits.cpu_sel
+					= MR_RAID_CTX_CPUSEL_FCFS;
+				else if (raid->cpuAffinity.ldRead.cpu1)
+					praid_context->raid_context_g35.routing_flags.bits.cpu_sel
+						= MR_RAID_CTX_CPUSEL_1;
+				else
+					praid_context->raid_context_g35.routing_flags.bits.cpu_sel
+						= MR_RAID_CTX_CPUSEL_0;
+			} else {
+				if ((raid->cpuAffinity.ldWrite.cpu0) &&
+					(raid->cpuAffinity.ldWrite.cpu1))
+					praid_context->raid_context_g35.routing_flags.bits.cpu_sel
+						= MR_RAID_CTX_CPUSEL_FCFS;
+				else if (raid->cpuAffinity.ldWrite.cpu1)
+					praid_context->raid_context_g35.routing_flags.bits.cpu_sel
+						= MR_RAID_CTX_CPUSEL_1;
+				else
+					praid_context->raid_context_g35.routing_flags.bits.cpu_sel
+					= MR_RAID_CTX_CPUSEL_0;
+
+				if (io_request->RaidContext.raid_context_g35.stream_detected
+					&& (raid->level == 5) &&
+					(raid->writeMode == MR_RL_WRITE_THROUGH_MODE)) {
+					if (praid_context->raid_context_g35.routing_flags.bits.cpu_sel
+						== MR_RAID_CTX_CPUSEL_FCFS)
+						praid_context->raid_context_g35.routing_flags.bits.cpu_sel
+							= MR_RAID_CTX_CPUSEL_0;
+				}
+			}
+		}
 	} /* Not FP */
 }
 
@@ -2048,9 +2138,9 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance,
 	/* get RAID_Context pointer */
 	pRAID_Context = &io_request->RaidContext.raid_context;
 	/* Check with FW team */
-	pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
-	pRAID_Context->regLockRowLBA    = 0;
-	pRAID_Context->regLockLength    = 0;
+	pRAID_Context->virtual_disk_tgt_id = cpu_to_le16(device_id);
+	pRAID_Context->reg_lock_row_lba    = 0;
+	pRAID_Context->reg_lock_length    = 0;
 
 	if (fusion->fast_path_io && (
 		device_id < instance->fw_supported_vd_count)) {
@@ -2069,7 +2159,7 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance,
 		io_request->Function  = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
 		io_request->DevHandle = cpu_to_le16(device_id);
 		io_request->LUN[1] = scmd->device->lun;
-		pRAID_Context->timeoutValue =
+		pRAID_Context->timeout_value =
 			cpu_to_le16 (scmd->request->timeout / HZ);
 		cmd->request_desc->SCSIIO.RequestFlags =
 			(MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
@@ -2077,9 +2167,11 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance,
 	} else {
 
 		/* set RAID context values */
-		pRAID_Context->configSeqNum = raid->seqNum;
-		pRAID_Context->regLockFlags = REGION_TYPE_SHARED_READ;
-		pRAID_Context->timeoutValue = cpu_to_le16(raid->fpIoTimeoutForLd);
+		pRAID_Context->config_seq_num = raid->seqNum;
+		if (!instance->is_ventura)
+			pRAID_Context->reg_lock_flags = REGION_TYPE_SHARED_READ;
+		pRAID_Context->timeout_value =
+			cpu_to_le16(raid->fpIoTimeoutForLd);
 
 		/* get the DevHandle for the PD (since this is
 		   fpNonRWCapable, this is a single disk RAID0) */
@@ -2134,12 +2226,12 @@ megasas_build_syspd_fusion(struct megasas_instance *instance,
 	io_request = cmd->io_request;
 	/* get RAID_Context pointer */
 	pRAID_Context = &io_request->RaidContext.raid_context;
-	pRAID_Context->regLockFlags = 0;
-	pRAID_Context->regLockRowLBA = 0;
-	pRAID_Context->regLockLength = 0;
+	pRAID_Context->reg_lock_flags = 0;
+	pRAID_Context->reg_lock_row_lba = 0;
+	pRAID_Context->reg_lock_length = 0;
 	io_request->DataLength = cpu_to_le32(scsi_bufflen(scmd));
 	io_request->LUN[1] = scmd->device->lun;
-	pRAID_Context->RAIDFlags = MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD
+	pRAID_Context->raid_flags = MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD
 		<< MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT;
 
 	/* If FW supports PD sequence number */
@@ -2148,24 +2240,27 @@ megasas_build_syspd_fusion(struct megasas_instance *instance,
 		/* TgtId must be incremented by 255 as jbod seq number is index
 		 * below raid map
 		 */
-		pRAID_Context->VirtualDiskTgtId =
+		pRAID_Context->virtual_disk_tgt_id =
 			cpu_to_le16(device_id + (MAX_PHYSICAL_DEVICES - 1));
-		pRAID_Context->configSeqNum = pd_sync->seq[pd_index].seqNum;
+		pRAID_Context->config_seq_num = pd_sync->seq[pd_index].seqNum;
 		io_request->DevHandle = pd_sync->seq[pd_index].devHandle;
-		pRAID_Context->regLockFlags |=
+		if (instance->is_ventura)
+			io_request->RaidContext.raid_context_g35.routing_flags.bits.sqn = 1;
+		else
+		pRAID_Context->reg_lock_flags |=
 			(MR_RL_FLAGS_SEQ_NUM_ENABLE|MR_RL_FLAGS_GRANT_DESTINATION_CUDA);
-		pRAID_Context->Type = MPI2_TYPE_CUDA;
+		pRAID_Context->type = MPI2_TYPE_CUDA;
 		pRAID_Context->nseg = 0x1;
 	} else if (fusion->fast_path_io) {
-		pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
-		pRAID_Context->configSeqNum = 0;
+		pRAID_Context->virtual_disk_tgt_id = cpu_to_le16(device_id);
+		pRAID_Context->config_seq_num = 0;
 		local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
 		io_request->DevHandle =
 			local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
 	} else {
 		/* Want to send all IO via FW path */
-		pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
-		pRAID_Context->configSeqNum = 0;
+		pRAID_Context->virtual_disk_tgt_id = cpu_to_le16(device_id);
+		pRAID_Context->config_seq_num = 0;
 		io_request->DevHandle = cpu_to_le16(0xFFFF);
 	}
 
@@ -2181,14 +2276,14 @@ megasas_build_syspd_fusion(struct megasas_instance *instance,
 		cmd->request_desc->SCSIIO.RequestFlags =
 			(MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
 				MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
-		pRAID_Context->timeoutValue = cpu_to_le16(os_timeout_value);
-		pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
+		pRAID_Context->timeout_value = cpu_to_le16(os_timeout_value);
+		pRAID_Context->virtual_disk_tgt_id = cpu_to_le16(device_id);
 	} else {
 		/* system pd Fast Path */
 		io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
 		timeout_limit = (scmd->device->type == TYPE_DISK) ?
 				255 : 0xFFFF;
-		pRAID_Context->timeoutValue =
+		pRAID_Context->timeout_value =
 			cpu_to_le16((os_timeout_value > timeout_limit) ?
 			timeout_limit : os_timeout_value);
 		if (fusion->adapter_type == INVADER_SERIES)
@@ -2227,8 +2322,8 @@ megasas_build_io_fusion(struct megasas_instance *instance,
 	io_request->Control = 0;
 	io_request->EEDPBlockSize = 0;
 	io_request->ChainOffset = 0;
-	io_request->RaidContext.raid_context.RAIDFlags = 0;
-	io_request->RaidContext.raid_context.Type = 0;
+	io_request->RaidContext.raid_context.raid_flags = 0;
+	io_request->RaidContext.raid_context.type = 0;
 	io_request->RaidContext.raid_context.nseg = 0;
 
 	memcpy(io_request->CDB.CDB32, scp->cmnd, scp->cmd_len);
@@ -2273,11 +2368,16 @@ megasas_build_io_fusion(struct megasas_instance *instance,
 		return 1;
 	}
 
-	/* numSGE store lower 8 bit of sge_count.
-	 * numSGEExt store higher 8 bit of sge_count
-	 */
-	io_request->RaidContext.raid_context.numSGE = sge_count;
-	io_request->RaidContext.raid_context.numSGEExt = (u8)(sge_count >> 8);
+	if (instance->is_ventura)
+		io_request->RaidContext.raid_context_g35.num_sge = sge_count;
+	else {
+		/* numSGE store lower 8 bit of sge_count.
+		 * numSGEExt store higher 8 bit of sge_count
+		 */
+		io_request->RaidContext.raid_context.num_sge = sge_count;
+		io_request->RaidContext.raid_context.num_sge_ext =
+			(u8)(sge_count >> 8);
+	}
 
 	io_request->SGLFlags = cpu_to_le16(MPI2_SGE_FLAGS_64_BIT_ADDRESSING);
 
@@ -2326,6 +2426,10 @@ void megasas_fpio_to_ldio(struct megasas_instance *instance,
 	struct megasas_cmd_fusion *cmd, struct scsi_cmnd *scmd)
 {
 	struct fusion_context *fusion;
+	union RAID_CONTEXT_UNION *praid_context;
+	struct MR_LD_RAID *raid;
+	struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
+	u32 device_id, ld;
 
 	fusion = instance->ctrl_context;
 	cmd->request_desc->SCSIIO.RequestFlags =
@@ -2349,6 +2453,35 @@ void megasas_fpio_to_ldio(struct megasas_instance *instance,
 	cmd->io_request->Control = 0;
 	cmd->io_request->EEDPBlockSize = 0;
 	cmd->is_raid_1_fp_write = 0;
+
+	device_id = MEGASAS_DEV_INDEX(cmd->scmd);
+	local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
+	ld = MR_TargetIdToLdGet(device_id, local_map_ptr);
+	raid = MR_LdRaidGet(ld, local_map_ptr);
+	praid_context = &cmd->io_request->RaidContext;
+	if (cmd->scmd->sc_data_direction == PCI_DMA_FROMDEVICE) {
+		if ((raid->cpuAffinity.ldRead.cpu0)
+		&& (raid->cpuAffinity.ldRead.cpu1))
+			praid_context->raid_context_g35.routing_flags.bits.cpu_sel
+			= MR_RAID_CTX_CPUSEL_FCFS;
+		else if (raid->cpuAffinity.ldRead.cpu1)
+			praid_context->raid_context_g35.routing_flags.bits.cpu_sel
+			= MR_RAID_CTX_CPUSEL_1;
+		else
+			praid_context->raid_context_g35.routing_flags.bits.cpu_sel
+			= MR_RAID_CTX_CPUSEL_0;
+	} else {
+	if ((raid->cpuAffinity.ldWrite.cpu0)
+		&& (raid->cpuAffinity.ldWrite.cpu1))
+		praid_context->raid_context_g35.routing_flags.bits.cpu_sel
+			= MR_RAID_CTX_CPUSEL_FCFS;
+	else if (raid->cpuAffinity.ldWrite.cpu1)
+		praid_context->raid_context_g35.routing_flags.bits.cpu_sel
+			= MR_RAID_CTX_CPUSEL_1;
+	else
+		praid_context->raid_context_g35.routing_flags.bits.cpu_sel
+		= MR_RAID_CTX_CPUSEL_0;
+	}
 }
 
 /* megasas_prepate_secondRaid1_IO
@@ -2585,7 +2718,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
 
 		scmd_local = cmd_fusion->scmd;
 		status = scsi_io_req->RaidContext.raid_context.status;
-		extStatus = scsi_io_req->RaidContext.raid_context.exStatus;
+		extStatus = scsi_io_req->RaidContext.raid_context.ex_status;
 		sense = cmd_fusion->sense;
 		data_length = scsi_io_req->DataLength;
 
@@ -2653,13 +2786,13 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
 					status =
 					r1_cmd->io_request->RaidContext.raid_context.status;
 					extStatus =
-					r1_cmd->io_request->RaidContext.raid_context.exStatus;
+					r1_cmd->io_request->RaidContext.raid_context.ex_status;
 					data_length =
 						r1_cmd->io_request->DataLength;
 					sense = r1_cmd->sense;
 				}
 				r1_cmd->io_request->RaidContext.raid_context.status = 0;
-				r1_cmd->io_request->RaidContext.raid_context.exStatus = 0;
+				r1_cmd->io_request->RaidContext.raid_context.ex_status = 0;
 				cmd_fusion->is_raid_1_fp_write = 0;
 				r1_cmd->is_raid_1_fp_write = 0;
 				r1_cmd->cmd_completed = false;
@@ -2669,10 +2802,8 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
 			if (!cmd_fusion->is_raid_1_fp_write) {
 				map_cmd_status(fusion, scmd_local, status,
 					extStatus, data_length, sense);
-				scsi_io_req->RaidContext.raid_context.status
-				= 0;
-				scsi_io_req->RaidContext.raid_context.exStatus
-				= 0;
+				scsi_io_req->RaidContext.raid_context.status = 0;
+				scsi_io_req->RaidContext.raid_context.ex_status = 0;
 				megasas_return_cmd_fusion(instance, cmd_fusion);
 				scsi_dma_unmap(scmd_local);
 				scmd_local->scsi_done(scmd_local);
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h
index 7a3c3d1..2de12b4 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h
@@ -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];
-- 
1.8.3.1