cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

smartpqi_sis.c (13613B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 *    driver for Microchip PQI-based storage controllers
      4 *    Copyright (c) 2019-2021 Microchip Technology Inc. and its subsidiaries
      5 *    Copyright (c) 2016-2018 Microsemi Corporation
      6 *    Copyright (c) 2016 PMC-Sierra, Inc.
      7 *
      8 *    Questions/Comments/Bugfixes to storagedev@microchip.com
      9 *
     10 */
     11
     12#include <linux/module.h>
     13#include <linux/kernel.h>
     14#include <linux/delay.h>
     15#include <linux/pci.h>
     16#include <scsi/scsi_device.h>
     17#include <asm/unaligned.h>
     18#include "smartpqi.h"
     19#include "smartpqi_sis.h"
     20
     21/* legacy SIS interface commands */
     22#define SIS_CMD_GET_ADAPTER_PROPERTIES		0x19
     23#define SIS_CMD_INIT_BASE_STRUCT_ADDRESS	0x1b
     24#define SIS_CMD_GET_PQI_CAPABILITIES		0x3000
     25
     26/* for submission of legacy SIS commands */
     27#define SIS_REENABLE_SIS_MODE			0x1
     28#define SIS_ENABLE_MSIX				0x40
     29#define SIS_ENABLE_INTX				0x80
     30#define SIS_SOFT_RESET				0x100
     31#define SIS_CMD_READY				0x200
     32#define SIS_TRIGGER_SHUTDOWN			0x800000
     33#define SIS_PQI_RESET_QUIESCE			0x1000000
     34
     35#define SIS_CMD_COMPLETE			0x1000
     36#define SIS_CLEAR_CTRL_TO_HOST_DOORBELL		0x1000
     37
     38#define SIS_CMD_STATUS_SUCCESS			0x1
     39#define SIS_CMD_COMPLETE_TIMEOUT_SECS		30
     40#define SIS_CMD_COMPLETE_POLL_INTERVAL_MSECS	10
     41
     42/* used with SIS_CMD_GET_ADAPTER_PROPERTIES command */
     43#define SIS_EXTENDED_PROPERTIES_SUPPORTED	0x800000
     44#define SIS_SMARTARRAY_FEATURES_SUPPORTED	0x2
     45#define SIS_PQI_MODE_SUPPORTED			0x4
     46#define SIS_PQI_RESET_QUIESCE_SUPPORTED		0x8
     47#define SIS_REQUIRED_EXTENDED_PROPERTIES	\
     48	(SIS_SMARTARRAY_FEATURES_SUPPORTED | SIS_PQI_MODE_SUPPORTED)
     49
     50/* used with SIS_CMD_INIT_BASE_STRUCT_ADDRESS command */
     51#define SIS_BASE_STRUCT_REVISION		9
     52#define SIS_BASE_STRUCT_ALIGNMENT		16
     53
     54#define SIS_CTRL_KERNEL_FW_TRIAGE		0x3
     55#define SIS_CTRL_KERNEL_UP			0x80
     56#define SIS_CTRL_KERNEL_PANIC			0x100
     57#define SIS_CTRL_READY_TIMEOUT_SECS		180
     58#define SIS_CTRL_READY_RESUME_TIMEOUT_SECS	90
     59#define SIS_CTRL_READY_POLL_INTERVAL_MSECS	10
     60
     61enum sis_fw_triage_status {
     62	FW_TRIAGE_NOT_STARTED = 0,
     63	FW_TRIAGE_STARTED,
     64	FW_TRIAGE_COND_INVALID,
     65	FW_TRIAGE_COMPLETED
     66};
     67
     68#pragma pack(1)
     69
     70/* for use with SIS_CMD_INIT_BASE_STRUCT_ADDRESS command */
     71struct sis_base_struct {
     72	__le32	revision;		/* revision of this structure */
     73	__le32	flags;			/* reserved */
     74	__le32	error_buffer_paddr_low;	/* lower 32 bits of physical memory */
     75					/* buffer for PQI error response */
     76					/* data */
     77	__le32	error_buffer_paddr_high;	/* upper 32 bits of physical */
     78						/* memory buffer for PQI */
     79						/* error response data */
     80	__le32	error_buffer_element_length;	/* length of each PQI error */
     81						/* response buffer element */
     82						/* in bytes */
     83	__le32	error_buffer_num_elements;	/* total number of PQI error */
     84						/* response buffers available */
     85};
     86
     87#pragma pack()
     88
     89static int sis_wait_for_ctrl_ready_with_timeout(struct pqi_ctrl_info *ctrl_info,
     90	unsigned int timeout_secs)
     91{
     92	unsigned long timeout;
     93	u32 status;
     94
     95	timeout = (timeout_secs * HZ) + jiffies;
     96
     97	while (1) {
     98		status = readl(&ctrl_info->registers->sis_firmware_status);
     99		if (status != ~0) {
    100			if (status & SIS_CTRL_KERNEL_PANIC) {
    101				dev_err(&ctrl_info->pci_dev->dev,
    102					"controller is offline: status code 0x%x\n",
    103					readl(
    104					&ctrl_info->registers->sis_mailbox[7]));
    105				return -ENODEV;
    106			}
    107			if (status & SIS_CTRL_KERNEL_UP)
    108				break;
    109		}
    110		if (time_after(jiffies, timeout)) {
    111			dev_err(&ctrl_info->pci_dev->dev,
    112				"controller not ready after %u seconds\n",
    113				timeout_secs);
    114			return -ETIMEDOUT;
    115		}
    116		msleep(SIS_CTRL_READY_POLL_INTERVAL_MSECS);
    117	}
    118
    119	return 0;
    120}
    121
    122int sis_wait_for_ctrl_ready(struct pqi_ctrl_info *ctrl_info)
    123{
    124	return sis_wait_for_ctrl_ready_with_timeout(ctrl_info,
    125		SIS_CTRL_READY_TIMEOUT_SECS);
    126}
    127
    128int sis_wait_for_ctrl_ready_resume(struct pqi_ctrl_info *ctrl_info)
    129{
    130	return sis_wait_for_ctrl_ready_with_timeout(ctrl_info,
    131		SIS_CTRL_READY_RESUME_TIMEOUT_SECS);
    132}
    133
    134bool sis_is_firmware_running(struct pqi_ctrl_info *ctrl_info)
    135{
    136	bool running;
    137	u32 status;
    138
    139	status = readl(&ctrl_info->registers->sis_firmware_status);
    140
    141	if (status & SIS_CTRL_KERNEL_PANIC)
    142		running = false;
    143	else
    144		running = true;
    145
    146	if (!running)
    147		dev_err(&ctrl_info->pci_dev->dev,
    148			"controller is offline: status code 0x%x\n",
    149			readl(&ctrl_info->registers->sis_mailbox[7]));
    150
    151	return running;
    152}
    153
    154bool sis_is_kernel_up(struct pqi_ctrl_info *ctrl_info)
    155{
    156	return readl(&ctrl_info->registers->sis_firmware_status) &
    157		SIS_CTRL_KERNEL_UP;
    158}
    159
    160u32 sis_get_product_id(struct pqi_ctrl_info *ctrl_info)
    161{
    162	return readl(&ctrl_info->registers->sis_product_identifier);
    163}
    164
    165/* used for passing command parameters/results when issuing SIS commands */
    166struct sis_sync_cmd_params {
    167	u32	mailbox[6];	/* mailboxes 0-5 */
    168};
    169
    170static int sis_send_sync_cmd(struct pqi_ctrl_info *ctrl_info,
    171	u32 cmd, struct sis_sync_cmd_params *params)
    172{
    173	struct pqi_ctrl_registers __iomem *registers;
    174	unsigned int i;
    175	unsigned long timeout;
    176	u32 doorbell;
    177	u32 cmd_status;
    178
    179	registers = ctrl_info->registers;
    180
    181	/* Write the command to mailbox 0. */
    182	writel(cmd, &registers->sis_mailbox[0]);
    183
    184	/*
    185	 * Write the command parameters to mailboxes 1-4 (mailbox 5 is not used
    186	 * when sending a command to the controller).
    187	 */
    188	for (i = 1; i <= 4; i++)
    189		writel(params->mailbox[i], &registers->sis_mailbox[i]);
    190
    191	/* Clear the command doorbell. */
    192	writel(SIS_CLEAR_CTRL_TO_HOST_DOORBELL,
    193		&registers->sis_ctrl_to_host_doorbell_clear);
    194
    195	/* Disable doorbell interrupts by masking all interrupts. */
    196	writel(~0, &registers->sis_interrupt_mask);
    197
    198	/*
    199	 * Force the completion of the interrupt mask register write before
    200	 * submitting the command.
    201	 */
    202	readl(&registers->sis_interrupt_mask);
    203
    204	/* Submit the command to the controller. */
    205	writel(SIS_CMD_READY, &registers->sis_host_to_ctrl_doorbell);
    206
    207	/*
    208	 * Poll for command completion.  Note that the call to msleep() is at
    209	 * the top of the loop in order to give the controller time to start
    210	 * processing the command before we start polling.
    211	 */
    212	timeout = (SIS_CMD_COMPLETE_TIMEOUT_SECS * HZ) + jiffies;
    213	while (1) {
    214		msleep(SIS_CMD_COMPLETE_POLL_INTERVAL_MSECS);
    215		doorbell = readl(&registers->sis_ctrl_to_host_doorbell);
    216		if (doorbell & SIS_CMD_COMPLETE)
    217			break;
    218		if (time_after(jiffies, timeout))
    219			return -ETIMEDOUT;
    220	}
    221
    222	/* Read the command status from mailbox 0. */
    223	cmd_status = readl(&registers->sis_mailbox[0]);
    224	if (cmd_status != SIS_CMD_STATUS_SUCCESS) {
    225		dev_err(&ctrl_info->pci_dev->dev,
    226			"SIS command failed for command 0x%x: status = 0x%x\n",
    227			cmd, cmd_status);
    228		return -EINVAL;
    229	}
    230
    231	/*
    232	 * The command completed successfully, so save the command status and
    233	 * read the values returned in mailboxes 1-5.
    234	 */
    235	params->mailbox[0] = cmd_status;
    236	for (i = 1; i < ARRAY_SIZE(params->mailbox); i++)
    237		params->mailbox[i] = readl(&registers->sis_mailbox[i]);
    238
    239	return 0;
    240}
    241
    242/*
    243 * This function verifies that we are talking to a controller that speaks PQI.
    244 */
    245
    246int sis_get_ctrl_properties(struct pqi_ctrl_info *ctrl_info)
    247{
    248	int rc;
    249	u32 properties;
    250	u32 extended_properties;
    251	struct sis_sync_cmd_params params;
    252
    253	memset(&params, 0, sizeof(params));
    254
    255	rc = sis_send_sync_cmd(ctrl_info, SIS_CMD_GET_ADAPTER_PROPERTIES,
    256		&params);
    257	if (rc)
    258		return rc;
    259
    260	properties = params.mailbox[1];
    261
    262	if (!(properties & SIS_EXTENDED_PROPERTIES_SUPPORTED))
    263		return -ENODEV;
    264
    265	extended_properties = params.mailbox[4];
    266
    267	if ((extended_properties & SIS_REQUIRED_EXTENDED_PROPERTIES) !=
    268		SIS_REQUIRED_EXTENDED_PROPERTIES)
    269		return -ENODEV;
    270
    271	if (extended_properties & SIS_PQI_RESET_QUIESCE_SUPPORTED)
    272		ctrl_info->pqi_reset_quiesce_supported = true;
    273
    274	return 0;
    275}
    276
    277int sis_get_pqi_capabilities(struct pqi_ctrl_info *ctrl_info)
    278{
    279	int rc;
    280	struct sis_sync_cmd_params params;
    281
    282	memset(&params, 0, sizeof(params));
    283
    284	rc = sis_send_sync_cmd(ctrl_info, SIS_CMD_GET_PQI_CAPABILITIES,
    285		&params);
    286	if (rc)
    287		return rc;
    288
    289	ctrl_info->max_sg_entries = params.mailbox[1];
    290	ctrl_info->max_transfer_size = params.mailbox[2];
    291	ctrl_info->max_outstanding_requests = params.mailbox[3];
    292	ctrl_info->config_table_offset = params.mailbox[4];
    293	ctrl_info->config_table_length = params.mailbox[5];
    294
    295	return 0;
    296}
    297
    298int sis_init_base_struct_addr(struct pqi_ctrl_info *ctrl_info)
    299{
    300	int rc;
    301	void *base_struct_unaligned;
    302	struct sis_base_struct *base_struct;
    303	struct sis_sync_cmd_params params;
    304	unsigned long error_buffer_paddr;
    305	dma_addr_t bus_address;
    306
    307	base_struct_unaligned = kzalloc(sizeof(*base_struct)
    308		+ SIS_BASE_STRUCT_ALIGNMENT - 1, GFP_KERNEL);
    309	if (!base_struct_unaligned)
    310		return -ENOMEM;
    311
    312	base_struct = PTR_ALIGN(base_struct_unaligned,
    313		SIS_BASE_STRUCT_ALIGNMENT);
    314	error_buffer_paddr = (unsigned long)ctrl_info->error_buffer_dma_handle;
    315
    316	put_unaligned_le32(SIS_BASE_STRUCT_REVISION, &base_struct->revision);
    317	put_unaligned_le32(lower_32_bits(error_buffer_paddr),
    318		&base_struct->error_buffer_paddr_low);
    319	put_unaligned_le32(upper_32_bits(error_buffer_paddr),
    320		&base_struct->error_buffer_paddr_high);
    321	put_unaligned_le32(PQI_ERROR_BUFFER_ELEMENT_LENGTH,
    322		&base_struct->error_buffer_element_length);
    323	put_unaligned_le32(ctrl_info->max_io_slots,
    324		&base_struct->error_buffer_num_elements);
    325
    326	bus_address = dma_map_single(&ctrl_info->pci_dev->dev, base_struct,
    327		sizeof(*base_struct), DMA_TO_DEVICE);
    328	if (dma_mapping_error(&ctrl_info->pci_dev->dev, bus_address)) {
    329		rc = -ENOMEM;
    330		goto out;
    331	}
    332
    333	memset(&params, 0, sizeof(params));
    334	params.mailbox[1] = lower_32_bits((u64)bus_address);
    335	params.mailbox[2] = upper_32_bits((u64)bus_address);
    336	params.mailbox[3] = sizeof(*base_struct);
    337
    338	rc = sis_send_sync_cmd(ctrl_info, SIS_CMD_INIT_BASE_STRUCT_ADDRESS,
    339		&params);
    340
    341	dma_unmap_single(&ctrl_info->pci_dev->dev, bus_address,
    342			sizeof(*base_struct), DMA_TO_DEVICE);
    343out:
    344	kfree(base_struct_unaligned);
    345
    346	return rc;
    347}
    348
    349#define SIS_DOORBELL_BIT_CLEAR_TIMEOUT_SECS	30
    350
    351static int sis_wait_for_doorbell_bit_to_clear(
    352	struct pqi_ctrl_info *ctrl_info, u32 bit)
    353{
    354	int rc = 0;
    355	u32 doorbell_register;
    356	unsigned long timeout;
    357
    358	timeout = (SIS_DOORBELL_BIT_CLEAR_TIMEOUT_SECS * HZ) + jiffies;
    359
    360	while (1) {
    361		doorbell_register =
    362			readl(&ctrl_info->registers->sis_host_to_ctrl_doorbell);
    363		if ((doorbell_register & bit) == 0)
    364			break;
    365		if (readl(&ctrl_info->registers->sis_firmware_status) &
    366			SIS_CTRL_KERNEL_PANIC) {
    367			rc = -ENODEV;
    368			break;
    369		}
    370		if (time_after(jiffies, timeout)) {
    371			dev_err(&ctrl_info->pci_dev->dev,
    372				"doorbell register bit 0x%x not cleared\n",
    373				bit);
    374			rc = -ETIMEDOUT;
    375			break;
    376		}
    377		usleep_range(1000, 2000);
    378	}
    379
    380	return rc;
    381}
    382
    383static inline int sis_set_doorbell_bit(struct pqi_ctrl_info *ctrl_info, u32 bit)
    384{
    385	writel(bit, &ctrl_info->registers->sis_host_to_ctrl_doorbell);
    386
    387	return sis_wait_for_doorbell_bit_to_clear(ctrl_info, bit);
    388}
    389
    390void sis_enable_msix(struct pqi_ctrl_info *ctrl_info)
    391{
    392	sis_set_doorbell_bit(ctrl_info, SIS_ENABLE_MSIX);
    393}
    394
    395void sis_enable_intx(struct pqi_ctrl_info *ctrl_info)
    396{
    397	sis_set_doorbell_bit(ctrl_info, SIS_ENABLE_INTX);
    398}
    399
    400void sis_shutdown_ctrl(struct pqi_ctrl_info *ctrl_info,
    401	enum pqi_ctrl_shutdown_reason ctrl_shutdown_reason)
    402{
    403	if (readl(&ctrl_info->registers->sis_firmware_status) &
    404		SIS_CTRL_KERNEL_PANIC)
    405		return;
    406
    407	if (ctrl_info->firmware_triage_supported)
    408		writel(ctrl_shutdown_reason, &ctrl_info->registers->sis_ctrl_shutdown_reason_code);
    409
    410	writel(SIS_TRIGGER_SHUTDOWN, &ctrl_info->registers->sis_host_to_ctrl_doorbell);
    411}
    412
    413int sis_pqi_reset_quiesce(struct pqi_ctrl_info *ctrl_info)
    414{
    415	return sis_set_doorbell_bit(ctrl_info, SIS_PQI_RESET_QUIESCE);
    416}
    417
    418int sis_reenable_sis_mode(struct pqi_ctrl_info *ctrl_info)
    419{
    420	return sis_set_doorbell_bit(ctrl_info, SIS_REENABLE_SIS_MODE);
    421}
    422
    423void sis_write_driver_scratch(struct pqi_ctrl_info *ctrl_info, u32 value)
    424{
    425	writel(value, &ctrl_info->registers->sis_driver_scratch);
    426}
    427
    428u32 sis_read_driver_scratch(struct pqi_ctrl_info *ctrl_info)
    429{
    430	return readl(&ctrl_info->registers->sis_driver_scratch);
    431}
    432
    433static inline enum sis_fw_triage_status
    434	sis_read_firmware_triage_status(struct pqi_ctrl_info *ctrl_info)
    435{
    436	return ((enum sis_fw_triage_status)(readl(&ctrl_info->registers->sis_firmware_status) &
    437		SIS_CTRL_KERNEL_FW_TRIAGE));
    438}
    439
    440void sis_soft_reset(struct pqi_ctrl_info *ctrl_info)
    441{
    442	writel(SIS_SOFT_RESET,
    443		&ctrl_info->registers->sis_host_to_ctrl_doorbell);
    444}
    445
    446#define SIS_FW_TRIAGE_STATUS_TIMEOUT_SECS		300
    447#define SIS_FW_TRIAGE_STATUS_POLL_INTERVAL_SECS		1
    448
    449int sis_wait_for_fw_triage_completion(struct pqi_ctrl_info *ctrl_info)
    450{
    451	int rc;
    452	enum sis_fw_triage_status status;
    453	unsigned long timeout;
    454
    455	timeout = (SIS_FW_TRIAGE_STATUS_TIMEOUT_SECS * HZ) + jiffies;
    456	while (1) {
    457		status = sis_read_firmware_triage_status(ctrl_info);
    458		if (status == FW_TRIAGE_COND_INVALID) {
    459			dev_err(&ctrl_info->pci_dev->dev,
    460				"firmware triage condition invalid\n");
    461			rc = -EINVAL;
    462			break;
    463		} else if (status == FW_TRIAGE_NOT_STARTED ||
    464			status == FW_TRIAGE_COMPLETED) {
    465			rc = 0;
    466			break;
    467		}
    468
    469		if (time_after(jiffies, timeout)) {
    470			dev_err(&ctrl_info->pci_dev->dev,
    471				"timed out waiting for firmware triage status\n");
    472			rc = -ETIMEDOUT;
    473			break;
    474		}
    475
    476		ssleep(SIS_FW_TRIAGE_STATUS_POLL_INTERVAL_SECS);
    477	}
    478
    479	return rc;
    480}
    481
    482void sis_verify_structures(void)
    483{
    484	BUILD_BUG_ON(offsetof(struct sis_base_struct,
    485		revision) != 0x0);
    486	BUILD_BUG_ON(offsetof(struct sis_base_struct,
    487		flags) != 0x4);
    488	BUILD_BUG_ON(offsetof(struct sis_base_struct,
    489		error_buffer_paddr_low) != 0x8);
    490	BUILD_BUG_ON(offsetof(struct sis_base_struct,
    491		error_buffer_paddr_high) != 0xc);
    492	BUILD_BUG_ON(offsetof(struct sis_base_struct,
    493		error_buffer_element_length) != 0x10);
    494	BUILD_BUG_ON(offsetof(struct sis_base_struct,
    495		error_buffer_num_elements) != 0x14);
    496	BUILD_BUG_ON(sizeof(struct sis_base_struct) != 0x18);
    497}