From 70684dcbec3ac54a6d111646a02128c0b53e9f75 Mon Sep 17 00:00:00 2001 From: Shivasharan S Date: Wed, 12 Feb 2025 17:26:52 -0800 Subject: [PATCH 1/5] scsi: mpt3sas: Update MPI headers to 02.00.62 version Updated MPI header files to version 02.00.62. Signed-off-by: Shivasharan S Link: https://lore.kernel.org/r/1739410016-27503-2-git-send-email-shivasharan.srikanteshwara@broadcom.com Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpi/mpi2.h | 9 ++++- drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h | 5 +++ drivers/scsi/mpt3sas/mpi/mpi2_ioc.h | 54 ++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/mpt3sas/mpi/mpi2.h b/drivers/scsi/mpt3sas/mpi/mpi2.h index 6de35b32223c..b181b113fc80 100644 --- a/drivers/scsi/mpt3sas/mpi/mpi2.h +++ b/drivers/scsi/mpt3sas/mpi/mpi2.h @@ -125,6 +125,12 @@ * 06-24-19 02.00.55 Bumped MPI2_HEADER_VERSION_UNIT * 08-01-19 02.00.56 Bumped MPI2_HEADER_VERSION_UNIT * 10-02-19 02.00.57 Bumped MPI2_HEADER_VERSION_UNIT + * 07-20-20 02.00.58 Bumped MPI2_HEADER_VERSION_UNIT + * 03-30-21 02.00.59 Bumped MPI2_HEADER_VERSION_UNIT + * 06-03-22 02.00.60 Bumped MPI2_HEADER_VERSION_UNIT + * 09-20-23 02.00.61 Bumped MPI2_HEADER_VERSION_UNIT + * 09-13-24 02.00.62 Bumped MPI2_HEADER_VERSION_UNIT + * Added MPI2_FUNCTION_MCTP_PASSTHROUGH * -------------------------------------------------------------------------- */ @@ -165,7 +171,7 @@ /* Unit and Dev versioning for this MPI header set */ -#define MPI2_HEADER_VERSION_UNIT (0x39) +#define MPI2_HEADER_VERSION_UNIT (0x3E) #define MPI2_HEADER_VERSION_DEV (0x00) #define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00) #define MPI2_HEADER_VERSION_UNIT_SHIFT (8) @@ -669,6 +675,7 @@ typedef union _MPI2_REPLY_DESCRIPTORS_UNION { #define MPI2_FUNCTION_PWR_MGMT_CONTROL (0x30) #define MPI2_FUNCTION_SEND_HOST_MESSAGE (0x31) #define MPI2_FUNCTION_NVME_ENCAPSULATED (0x33) +#define MPI2_FUNCTION_MCTP_PASSTHROUGH (0x34) #define MPI2_FUNCTION_MIN_PRODUCT_SPECIFIC (0xF0) #define MPI2_FUNCTION_MAX_PRODUCT_SPECIFIC (0xFF) diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h index 587f7d248219..77259fc96b94 100644 --- a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h +++ b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h @@ -251,6 +251,7 @@ * 12-17-18 02.00.47 Swap locations of Slotx2 and Slotx4 in ManPage 7. * 08-01-19 02.00.49 Add MPI26_MANPAGE7_FLAG_X2_X4_SLOT_INFO_VALID * Add MPI26_IOUNITPAGE1_NVME_WRCACHE_SHIFT + * 09-13-24 02.00.50 Added PCIe 32 GT/s link rate */ #ifndef MPI2_CNFG_H @@ -1121,6 +1122,7 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7 { #define MPI2_IOUNITPAGE7_PCIE_SPEED_5_0_GBPS (0x01) #define MPI2_IOUNITPAGE7_PCIE_SPEED_8_0_GBPS (0x02) #define MPI2_IOUNITPAGE7_PCIE_SPEED_16_0_GBPS (0x03) +#define MPI2_IOUNITPAGE7_PCIE_SPEED_32_0_GBPS (0x04) /*defines for IO Unit Page 7 ProcessorState field */ #define MPI2_IOUNITPAGE7_PSTATE_MASK_SECOND (0x0000000F) @@ -2301,6 +2303,7 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_1 { #define MPI2_SASIOUNIT1_CONTROL_CLEAR_AFFILIATION (0x0001) /*values for SAS IO Unit Page 1 AdditionalControlFlags */ +#define MPI2_SASIOUNIT1_ACONTROL_PROD_SPECIFIC_1 (0x8000) #define MPI2_SASIOUNIT1_ACONTROL_DA_PERSIST_CONNECT (0x0100) #define MPI2_SASIOUNIT1_ACONTROL_MULTI_PORT_DOMAIN_ILLEGAL (0x0080) #define MPI2_SASIOUNIT1_ACONTROL_SATA_ASYNCHROUNOUS_NOTIFICATION (0x0040) @@ -3591,6 +3594,7 @@ typedef struct _MPI2_CONFIG_PAGE_EXT_MAN_PS { #define MPI26_PCIE_NEG_LINK_RATE_5_0 (0x03) #define MPI26_PCIE_NEG_LINK_RATE_8_0 (0x04) #define MPI26_PCIE_NEG_LINK_RATE_16_0 (0x05) +#define MPI26_PCIE_NEG_LINK_RATE_32_0 (0x06) /**************************************************************************** @@ -3700,6 +3704,7 @@ typedef struct _MPI26_CONFIG_PAGE_PIOUNIT_1 { #define MPI26_PCIEIOUNIT1_MAX_RATE_5_0 (0x30) #define MPI26_PCIEIOUNIT1_MAX_RATE_8_0 (0x40) #define MPI26_PCIEIOUNIT1_MAX_RATE_16_0 (0x50) +#define MPI26_PCIEIOUNIT1_MAX_RATE_32_0 (0x60) /*values for PCIe IO Unit Page 1 DMDReportPCIe */ #define MPI26_PCIEIOUNIT1_DMDRPT_UNIT_MASK (0x80) diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h b/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h index d92852591134..1a279c6e1a9f 100644 --- a/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h +++ b/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h @@ -179,6 +179,7 @@ * Added MPI26_IOCFACTS_CAPABILITY_COREDUMP_ENABLED * Added MPI2_FW_DOWNLOAD_ITYPE_COREDUMP * Added MPI2_FW_UPLOAD_ITYPE_COREDUMP + * 9-13-24 02.00.39 Added MPI26_MCTP_PASSTHROUGH messages * -------------------------------------------------------------------------- */ @@ -382,6 +383,7 @@ typedef struct _MPI2_IOC_FACTS_REPLY { /*ProductID field uses MPI2_FW_HEADER_PID_ */ /*IOCCapabilities */ +#define MPI26_IOCFACTS_CAPABILITY_MCTP_PASSTHRU (0x00800000) #define MPI26_IOCFACTS_CAPABILITY_COREDUMP_ENABLED (0x00200000) #define MPI26_IOCFACTS_CAPABILITY_PCIE_SRIOV (0x00100000) #define MPI26_IOCFACTS_CAPABILITY_ATOMIC_REQ (0x00080000) @@ -1798,5 +1800,57 @@ typedef struct _MPI26_IOUNIT_CONTROL_REPLY { Mpi26IoUnitControlReply_t, *pMpi26IoUnitControlReply_t; +/**************************************************************************** + * MCTP Passthrough messages (MPI v2.6 and later only.) + ****************************************************************************/ + +/* MCTP Passthrough Request Message */ +typedef struct _MPI26_MCTP_PASSTHROUGH_REQUEST { + U8 MsgContext; /* 0x00 */ + U8 Reserved1[2]; /* 0x01 */ + U8 Function; /* 0x03 */ + U8 Reserved2[3]; /* 0x04 */ + U8 MsgFlags; /* 0x07 */ + U8 VP_ID; /* 0x08 */ + U8 VF_ID; /* 0x09 */ + U16 Reserved3; /* 0x0A */ + U32 Reserved4; /* 0x0C */ + U8 Flags; /* 0x10 */ + U8 Reserved5[3]; /* 0x11 */ + U32 Reserved6; /* 0x14 */ + U32 H2DLength; /* 0x18 */ + U32 D2HLength; /* 0x1C */ + MPI25_SGE_IO_UNION H2DSGL; /* 0x20 */ + MPI25_SGE_IO_UNION D2HSGL; /* 0x30 */ +} MPI26_MCTP_PASSTHROUGH_REQUEST, + *PTR_MPI26_MCTP_PASSTHROUGH_REQUEST, + Mpi26MctpPassthroughRequest_t, + *pMpi26MctpPassthroughRequest_t; + +/* values for the MsgContext field */ +#define MPI26_MCTP_MSG_CONEXT_UNUSED (0x00) + +/* values for the Flags field */ +#define MPI26_MCTP_FLAGS_MSG_FORMAT_MPT (0x01) + +/* MCTP Passthrough Reply Message */ +typedef struct _MPI26_MCTP_PASSTHROUGH_REPLY { + U8 MsgContext; /* 0x00 */ + U8 Reserved1; /* 0x01 */ + U8 MsgLength; /* 0x02 */ + U8 Function; /* 0x03 */ + U8 Reserved2[3]; /* 0x04 */ + U8 MsgFlags; /* 0x07 */ + U8 VP_ID; /* 0x08 */ + U8 VF_ID; /* 0x09 */ + U16 Reserved3; /* 0x0A */ + U16 Reserved4; /* 0x0C */ + U16 IOCStatus; /* 0x0E */ + U32 IOCLogInfo; /* 0x10 */ + U32 ResponseDataLength; /* 0x14 */ +} MPI26_MCTP_PASSTHROUGH_REPLY, + *PTR_MPI26_MCTP_PASSTHROUGH_REPLY, + Mpi26MctpPassthroughReply_t, + *pMpi26MctpPassthroughReply_t; #endif From c72be4b5bb7cb1a9059d0b845f87223b52399cc2 Mon Sep 17 00:00:00 2001 From: Shivasharan S Date: Wed, 12 Feb 2025 17:26:53 -0800 Subject: [PATCH 2/5] scsi: mpt3sas: Add support for MCTP Passthrough commands The MPI specification defines support for sending MCTP management commands as a passthrough function to the IOC. Add support for driver to discover the IOC capability to support MCTP passthrough function. Driver will support applications and kernel modules to send MPT commands containing the MCTP passthrough request to firmware through an MPI request. Signed-off-by: Shivasharan S Signed-off-by: Sathya Prakash Link: https://lore.kernel.org/r/1739410016-27503-3-git-send-email-shivasharan.srikanteshwara@broadcom.com Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_base.c | 11 ++ drivers/scsi/mpt3sas/mpt3sas_ctl.c | 265 ++++++++++++++++++++++++++++ drivers/scsi/mpt3sas/mpt3sas_ctl.h | 42 +++++ 3 files changed, 318 insertions(+) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index dc43cfa83088..f0e8139654b5 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -1202,6 +1202,11 @@ _base_sas_ioc_info(struct MPT3SAS_ADAPTER *ioc, MPI2DefaultReply_t *mpi_reply, ioc->sge_size; func_str = "nvme_encapsulated"; break; + case MPI2_FUNCTION_MCTP_PASSTHROUGH: + frame_sz = sizeof(Mpi26MctpPassthroughRequest_t) + + ioc->sge_size; + func_str = "mctp_passthru"; + break; default: frame_sz = 32; func_str = "unknown"; @@ -4874,6 +4879,12 @@ _base_display_ioc_capabilities(struct MPT3SAS_ADAPTER *ioc) i++; } + if (ioc->facts.IOCCapabilities & + MPI26_IOCFACTS_CAPABILITY_MCTP_PASSTHRU) { + pr_cont("%sMCTP Passthru", i ? "," : ""); + i++; + } + iounit_pg1_flags = le32_to_cpu(ioc->iounit_pg1.Flags); if (!(iounit_pg1_flags & MPI2_IOUNITPAGE1_NATIVE_COMMAND_Q_DISABLE)) { pr_cont("%sNCQ", i ? "," : ""); diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index 87784c96249a..6a9921e4b59e 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c @@ -186,6 +186,9 @@ _ctl_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid, case MPI2_FUNCTION_NVME_ENCAPSULATED: desc = "nvme_encapsulated"; break; + case MPI2_FUNCTION_MCTP_PASSTHROUGH: + desc = "mctp_passthrough"; + break; } if (!desc) @@ -652,6 +655,40 @@ _ctl_set_task_mid(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command *karg, return 0; } +/** + * _ctl_send_mctp_passthru_req - Send an MCTP passthru request + * @ioc: per adapter object + * @mctp_passthru_req: MPI mctp passhthru request from caller + * @psge: pointer to the H2DSGL + * @data_out_dma: DMA buffer for H2D SGL + * @data_out_sz: H2D length + * @data_in_dma: DMA buffer for D2H SGL + * @data_in_sz: D2H length + * @smid: SMID to submit the request + * + */ +static void +_ctl_send_mctp_passthru_req( + struct MPT3SAS_ADAPTER *ioc, + Mpi26MctpPassthroughRequest_t *mctp_passthru_req, void *psge, + dma_addr_t data_out_dma, int data_out_sz, + dma_addr_t data_in_dma, int data_in_sz, + u16 smid) +{ + mctp_passthru_req->H2DLength = data_out_sz; + mctp_passthru_req->D2HLength = data_in_sz; + + /* Build the H2D SGL from the data out buffer */ + ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, 0, 0); + + psge += ioc->sge_size_ieee; + + /* Build the D2H SGL for the data in buffer */ + ioc->build_sg(ioc, psge, 0, 0, data_in_dma, data_in_sz); + + ioc->put_smid_default(ioc, smid); +} + /** * _ctl_do_mpt_command - main handler for MPT3COMMAND opcode * @ioc: per adapter object @@ -792,6 +829,23 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, init_completion(&ioc->ctl_cmds.done); switch (mpi_request->Function) { + case MPI2_FUNCTION_MCTP_PASSTHROUGH: + { + Mpi26MctpPassthroughRequest_t *mctp_passthru_req = + (Mpi26MctpPassthroughRequest_t *)request; + + if (!(ioc->facts.IOCCapabilities & MPI26_IOCFACTS_CAPABILITY_MCTP_PASSTHRU)) { + ioc_err(ioc, "%s: MCTP Passthrough request not supported\n", + __func__); + mpt3sas_base_free_smid(ioc, smid); + ret = -EINVAL; + goto out; + } + + _ctl_send_mctp_passthru_req(ioc, mctp_passthru_req, psge, data_out_dma, + data_out_sz, data_in_dma, data_in_sz, smid); + break; + } case MPI2_FUNCTION_NVME_ENCAPSULATED: { nvme_encap_request = (Mpi26NVMeEncapsulatedRequest_t *)request; @@ -2786,6 +2840,217 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg, return ret; } +/** + * _ctl_get_mpt_mctp_passthru_adapter - Traverse the IOC list and return the IOC at + * dev_index positionthat support MCTP passhtru + * @dev_index: position in the mpt3sas_ioc_list to search for + * Return pointer to the IOC on success + * NULL if device not found error + */ +static struct MPT3SAS_ADAPTER * +_ctl_get_mpt_mctp_passthru_adapter(int dev_index) +{ + struct MPT3SAS_ADAPTER *ioc = NULL; + int count = 0; + + spin_lock(&gioc_lock); + /* Traverse ioc list and return number of IOC that support MCTP passthru */ + list_for_each_entry(ioc, &mpt3sas_ioc_list, list) { + if (ioc->facts.IOCCapabilities & MPI26_IOCFACTS_CAPABILITY_MCTP_PASSTHRU) { + if (count == dev_index) { + spin_unlock(&gioc_lock); + return 0; + } + } + } + spin_unlock(&gioc_lock); + + return NULL; +} + +/** + * mpt3sas_get_device_count - Retrieve the count of MCTP passthrough + * capable devices managed by the driver. + * + * Returns number of devices that support MCTP passthrough. + */ +int +mpt3sas_get_device_count(void) +{ + int count = 0; + struct MPT3SAS_ADAPTER *ioc = NULL; + + spin_lock(&gioc_lock); + /* Traverse ioc list and return number of IOC that support MCTP passthru */ + list_for_each_entry(ioc, &mpt3sas_ioc_list, list) + if (ioc->facts.IOCCapabilities & MPI26_IOCFACTS_CAPABILITY_MCTP_PASSTHRU) + count++; + + spin_unlock(&gioc_lock); + + return count; +} +EXPORT_SYMBOL(mpt3sas_get_device_count); + +/** + * mpt3sas_send_passthru_cmd - Send an MPI MCTP passthrough command to + * firmware + * @command: The MPI MCTP passthrough command to send to firmware + * + * Returns 0 on success, anything else is error. + */ +int mpt3sas_send_mctp_passthru_req(struct mpt3_passthru_command *command) +{ + struct MPT3SAS_ADAPTER *ioc; + MPI2RequestHeader_t *mpi_request = NULL, *request; + MPI2DefaultReply_t *mpi_reply; + Mpi26MctpPassthroughRequest_t *mctp_passthru_req; + u16 smid; + unsigned long timeout; + u8 issue_reset = 0; + u32 sz; + void *psge; + void *data_out = NULL; + dma_addr_t data_out_dma = 0; + size_t data_out_sz = 0; + void *data_in = NULL; + dma_addr_t data_in_dma = 0; + size_t data_in_sz = 0; + long ret; + + /* Retrieve ioc from dev_index */ + ioc = _ctl_get_mpt_mctp_passthru_adapter(command->dev_index); + if (!ioc) + return -ENODEV; + + mutex_lock(&ioc->pci_access_mutex); + if (ioc->shost_recovery || + ioc->pci_error_recovery || ioc->is_driver_loading || + ioc->remove_host) { + ret = -EAGAIN; + goto unlock_pci_access; + } + + /* Lock the ctl_cmds mutex to ensure a single ctl cmd is pending */ + if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) { + ret = -ERESTARTSYS; + goto unlock_pci_access; + } + + if (ioc->ctl_cmds.status != MPT3_CMD_NOT_USED) { + ioc_err(ioc, "%s: ctl_cmd in use\n", __func__); + ret = -EAGAIN; + goto unlock_ctl_cmds; + } + + ret = mpt3sas_wait_for_ioc(ioc, IOC_OPERATIONAL_WAIT_COUNT); + if (ret) + goto unlock_ctl_cmds; + + mpi_request = (MPI2RequestHeader_t *)command->mpi_request; + if (mpi_request->Function != MPI2_FUNCTION_MCTP_PASSTHROUGH) { + ioc_err(ioc, "%s: Invalid request receveid, Function 0x%x\n", + __func__, mpi_request->Function); + ret = -EINVAL; + goto unlock_ctl_cmds; + } + + /* Use first reserved smid for passthrough commands */ + smid = ioc->scsiio_depth - INTERNAL_SCSIIO_CMDS_COUNT + 1; + ret = 0; + ioc->ctl_cmds.status = MPT3_CMD_PENDING; + memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz); + request = mpt3sas_base_get_msg_frame(ioc, smid); + memset(request, 0, ioc->request_sz); + memcpy(request, command->mpi_request, sizeof(Mpi26MctpPassthroughRequest_t)); + ioc->ctl_cmds.smid = smid; + data_out_sz = command->data_out_size; + data_in_sz = command->data_in_size; + + /* obtain dma-able memory for data transfer */ + if (data_out_sz) /* WRITE */ { + data_out = dma_alloc_coherent(&ioc->pdev->dev, data_out_sz, + &data_out_dma, GFP_ATOMIC); + if (!data_out) { + ret = -ENOMEM; + mpt3sas_base_free_smid(ioc, smid); + goto out; + } + memcpy(data_out, command->data_out_buf_ptr, data_out_sz); + + } + + if (data_in_sz) /* READ */ { + data_in = dma_alloc_coherent(&ioc->pdev->dev, data_in_sz, + &data_in_dma, GFP_ATOMIC); + if (!data_in) { + ret = -ENOMEM; + mpt3sas_base_free_smid(ioc, smid); + goto out; + } + } + + psge = &((Mpi26MctpPassthroughRequest_t *)request)->H2DSGL; + + init_completion(&ioc->ctl_cmds.done); + + mctp_passthru_req = (Mpi26MctpPassthroughRequest_t *)request; + + _ctl_send_mctp_passthru_req(ioc, mctp_passthru_req, psge, data_out_dma, + data_out_sz, data_in_dma, data_in_sz, smid); + + timeout = command->timeout; + if (timeout < MPT3_IOCTL_DEFAULT_TIMEOUT) + timeout = MPT3_IOCTL_DEFAULT_TIMEOUT; + + wait_for_completion_timeout(&ioc->ctl_cmds.done, timeout*HZ); + if (!(ioc->ctl_cmds.status & MPT3_CMD_COMPLETE)) { + mpt3sas_check_cmd_timeout(ioc, + ioc->ctl_cmds.status, mpi_request, + sizeof(Mpi26MctpPassthroughRequest_t), issue_reset); + goto issue_host_reset; + } + + mpi_reply = ioc->ctl_cmds.reply; + + /* copy out xdata to user */ + if (data_in_sz) + memcpy(command->data_in_buf_ptr, data_in, data_in_sz); + + /* copy out reply message frame to user */ + if (command->max_reply_bytes) { + sz = min_t(u32, command->max_reply_bytes, ioc->reply_sz); + memcpy(command->reply_frame_buf_ptr, ioc->ctl_cmds.reply, sz); + } + +issue_host_reset: + if (issue_reset) { + ret = -ENODATA; + mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER); + } + +out: + /* free memory associated with sg buffers */ + if (data_in) + dma_free_coherent(&ioc->pdev->dev, data_in_sz, data_in, + data_in_dma); + + if (data_out) + dma_free_coherent(&ioc->pdev->dev, data_out_sz, data_out, + data_out_dma); + + ioc->ctl_cmds.status = MPT3_CMD_NOT_USED; + +unlock_ctl_cmds: + mutex_unlock(&ioc->ctl_cmds.mutex); + +unlock_pci_access: + mutex_unlock(&ioc->pci_access_mutex); + return ret; + +} +EXPORT_SYMBOL(mpt3sas_send_mctp_passthru_req); + /** * _ctl_ioctl - mpt3ctl main ioctl entry point (unlocked) * @file: (struct file) diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.h b/drivers/scsi/mpt3sas/mpt3sas_ctl.h index 171709e91006..6bc1fffb7a33 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.h +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.h @@ -458,4 +458,46 @@ struct mpt3_enable_diag_sbr_reload { struct mpt3_ioctl_header hdr; }; +/** + * struct mpt3_passthru_command - generic mpt firmware passthru command + * @dev_index - device index + * @timeout - command timeout in seconds. (if zero then use driver default + * value). + * @reply_frame_buf_ptr - MPI reply location + * @data_in_buf_ptr - destination for read + * @data_out_buf_ptr - data source for write + * @max_reply_bytes - maximum number of reply bytes to be sent to app. + * @data_in_size - number bytes for data transfer in (read) + * @data_out_size - number bytes for data transfer out (write) + * @mpi_request - request frame + */ +struct mpt3_passthru_command { + u8 dev_index; + uint32_t timeout; + void *reply_frame_buf_ptr; + void *data_in_buf_ptr; + void *data_out_buf_ptr; + uint32_t max_reply_bytes; + uint32_t data_in_size; + uint32_t data_out_size; + Mpi26MctpPassthroughRequest_t *mpi_request; +}; + +/* + * mpt3sas_get_device_count - Retrieve the count of MCTP passthrough + * capable devices managed by the driver. + * + * Returns number of devices that support MCTP passthrough. + */ +int mpt3sas_get_device_count(void); + +/* + * mpt3sas_send_passthru_cmd - Send an MPI MCTP passthrough command to + * firmware + * @command: The MPI MCTP passthrough command to send to firmware + * + * Returns 0 on success, anything else is error . + */ +int mpt3sas_send_mctp_passthru_req(struct mpt3_passthru_command *command); + #endif /* MPT3SAS_CTL_H_INCLUDED */ From 8c2465e202006e17fefaaac364e9942bd9002c34 Mon Sep 17 00:00:00 2001 From: Shivasharan S Date: Wed, 12 Feb 2025 17:26:54 -0800 Subject: [PATCH 3/5] scsi: mpt3sas: Report driver capability as part of IOCINFO command Add a new capability field to report the MCTP passthrough support to applications. Signed-off-by: Shivasharan S Link: https://lore.kernel.org/r/1739410016-27503-4-git-send-email-shivasharan.srikanteshwara@broadcom.com Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_ctl.c | 2 ++ drivers/scsi/mpt3sas/mpt3sas_ctl.h | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index 6a9921e4b59e..523aef23d1fc 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c @@ -1254,6 +1254,8 @@ _ctl_getiocinfo(struct MPT3SAS_ADAPTER *ioc, void __user *arg) } karg.bios_version = le32_to_cpu(ioc->bios_pg3.BiosVersion); + karg.driver_capability |= MPT3_IOCTL_IOCINFO_DRIVER_CAP_MCTP_PASSTHRU; + if (copy_to_user(arg, &karg, sizeof(karg))) { pr_err("failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.h b/drivers/scsi/mpt3sas/mpt3sas_ctl.h index 6bc1fffb7a33..483e0549c02f 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.h +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.h @@ -160,6 +160,9 @@ struct mpt3_ioctl_pci_info { #define MPT3_IOCTL_INTERFACE_SAS35 (0x07) #define MPT2_IOCTL_VERSION_LENGTH (32) +/* Bits set for mpt3_ioctl_iocinfo.driver_cap */ +#define MPT3_IOCTL_IOCINFO_DRIVER_CAP_MCTP_PASSTHRU 0x1 + /** * struct mpt3_ioctl_iocinfo - generic controller info * @hdr - generic header @@ -175,6 +178,7 @@ struct mpt3_ioctl_pci_info { * @driver_version - driver version - 32 ASCII characters * @rsvd1 - reserved * @scsi_id - scsi id of adapter 0 + * @driver_capability - driver capabilities * @rsvd2 - reserved * @pci_information - pci info (2nd revision) */ @@ -192,7 +196,8 @@ struct mpt3_ioctl_iocinfo { uint8_t driver_version[MPT2_IOCTL_VERSION_LENGTH]; uint8_t rsvd1; uint8_t scsi_id; - uint16_t rsvd2; + uint8_t driver_capability; + uint8_t rsvd2; struct mpt3_ioctl_pci_info pci_information; }; From 5612d6d51ed2634a033c95de2edec7449409cbb9 Mon Sep 17 00:00:00 2001 From: Shivasharan S Date: Wed, 12 Feb 2025 17:26:55 -0800 Subject: [PATCH 4/5] scsi: mpt3sas: Send a diag reset if target reset fails When an IOCTL times out and driver issues a target reset, if firmware fails the task management elevate the recovery by issuing a diag reset to controller. Signed-off-by: Shivasharan S Link: https://lore.kernel.org/r/1739410016-27503-5-git-send-email-shivasharan.srikanteshwara@broadcom.com Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_ctl.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index 523aef23d1fc..bd3919f15adb 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c @@ -716,6 +716,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, size_t data_in_sz = 0; long ret; u16 device_handle = MPT3SAS_INVALID_DEVICE_HANDLE; + int tm_ret; issue_reset = 0; @@ -1174,18 +1175,25 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, if (pcie_device && (!ioc->tm_custom_handling) && (!(mpt3sas_scsih_is_pcie_scsi_device( pcie_device->device_info)))) - mpt3sas_scsih_issue_locked_tm(ioc, + tm_ret = mpt3sas_scsih_issue_locked_tm(ioc, le16_to_cpu(mpi_request->FunctionDependent1), 0, 0, 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 0, pcie_device->reset_timeout, MPI26_SCSITASKMGMT_MSGFLAGS_PROTOCOL_LVL_RST_PCIE); else - mpt3sas_scsih_issue_locked_tm(ioc, + tm_ret = mpt3sas_scsih_issue_locked_tm(ioc, le16_to_cpu(mpi_request->FunctionDependent1), 0, 0, 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 0, 30, MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET); + + if (tm_ret != SUCCESS) { + ioc_info(ioc, + "target reset failed, issue hard reset: handle (0x%04x)\n", + le16_to_cpu(mpi_request->FunctionDependent1)); + mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER); + } } else mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER); } From 51edde19f008eacaeba87aadbcea143076fd8a27 Mon Sep 17 00:00:00 2001 From: Shivasharan S Date: Wed, 12 Feb 2025 17:26:56 -0800 Subject: [PATCH 5/5] scsi: mpt3sas: update driver version to 52.100.00.00 Signed-off-by: Shivasharan S Link: https://lore.kernel.org/r/1739410016-27503-6-git-send-email-shivasharan.srikanteshwara@broadcom.com Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_base.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h index d8d1a64b4764..4f871a83d04f 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h @@ -77,8 +77,8 @@ #define MPT3SAS_DRIVER_NAME "mpt3sas" #define MPT3SAS_AUTHOR "Avago Technologies " #define MPT3SAS_DESCRIPTION "LSI MPT Fusion SAS 3.0 Device Driver" -#define MPT3SAS_DRIVER_VERSION "51.100.00.00" -#define MPT3SAS_MAJOR_VERSION 51 +#define MPT3SAS_DRIVER_VERSION "52.100.00.00" +#define MPT3SAS_MAJOR_VERSION 52 #define MPT3SAS_MINOR_VERSION 100 #define MPT3SAS_BUILD_VERSION 00 #define MPT3SAS_RELEASE_VERSION 00