/*
 *    driver for Microsemi PQI-based storage controllers
 *    Copyright (c) 2016-2017 Microsemi Corporation
 *    Copyright (c) 2016 PMC-Sierra, Inc.
 *
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; version 2 of the License.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 *    NON INFRINGEMENT.  See the GNU General Public License for more details.
 *
 *    Questions/Comments/Bugfixes to esc.storagedev@microsemi.com
 *
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/pci.h>
#include <scsi/scsi_device.h>
#include <asm/unaligned.h>
#include "smartpqi.h"
#include "smartpqi_sis.h"

/* legacy SIS interface commands */
#define SIS_CMD_GET_ADAPTER_PROPERTIES		0x19
#define SIS_CMD_INIT_BASE_STRUCT_ADDRESS	0x1b
#define SIS_CMD_GET_PQI_CAPABILITIES		0x3000

/* for submission of legacy SIS commands */
#define SIS_REENABLE_SIS_MODE			0x1
#define SIS_ENABLE_MSIX				0x40
#define SIS_ENABLE_INTX				0x80
#define SIS_CMD_READY				0x200
#define SIS_TRIGGER_SHUTDOWN			0x800000
#define SIS_PQI_RESET_QUIESCE			0x1000000

#define SIS_CMD_COMPLETE			0x1000
#define SIS_CLEAR_CTRL_TO_HOST_DOORBELL		0x1000

#define SIS_CMD_STATUS_SUCCESS			0x1
#define SIS_CMD_COMPLETE_TIMEOUT_SECS		30
#define SIS_CMD_COMPLETE_POLL_INTERVAL_MSECS	10

/* used with SIS_CMD_GET_ADAPTER_PROPERTIES command */
#define SIS_EXTENDED_PROPERTIES_SUPPORTED	0x800000
#define SIS_SMARTARRAY_FEATURES_SUPPORTED	0x2
#define SIS_PQI_MODE_SUPPORTED			0x4
#define SIS_PQI_RESET_QUIESCE_SUPPORTED		0x8
#define SIS_REQUIRED_EXTENDED_PROPERTIES	\
	(SIS_SMARTARRAY_FEATURES_SUPPORTED | SIS_PQI_MODE_SUPPORTED)

/* used with SIS_CMD_INIT_BASE_STRUCT_ADDRESS command */
#define SIS_BASE_STRUCT_REVISION		9
#define SIS_BASE_STRUCT_ALIGNMENT		16

#define SIS_CTRL_KERNEL_UP			0x80
#define SIS_CTRL_KERNEL_PANIC			0x100
#define SIS_CTRL_READY_TIMEOUT_SECS		30
#define SIS_CTRL_READY_RESUME_TIMEOUT_SECS	90
#define SIS_CTRL_READY_POLL_INTERVAL_MSECS	10

#pragma pack(1)

/* for use with SIS_CMD_INIT_BASE_STRUCT_ADDRESS command */
struct sis_base_struct {
	__le32	revision;		/* revision of this structure */
	__le32	flags;			/* reserved */
	__le32	error_buffer_paddr_low;	/* lower 32 bits of physical memory */
					/* buffer for PQI error response */
					/* data */
	__le32	error_buffer_paddr_high;	/* upper 32 bits of physical */
						/* memory buffer for PQI */
						/* error response data */
	__le32	error_buffer_element_length;	/* length of each PQI error */
						/* response buffer element */
						/*   in bytes */
	__le32	error_buffer_num_elements;	/* total number of PQI error */
						/* response buffers available */
};

#pragma pack()

static int sis_wait_for_ctrl_ready_with_timeout(struct pqi_ctrl_info *ctrl_info,
	unsigned int timeout_secs)
{
	unsigned long timeout;
	u32 status;

	timeout = (timeout_secs * HZ) + jiffies;

	while (1) {
		status = readl(&ctrl_info->registers->sis_firmware_status);
		if (status != ~0) {
			if (status & SIS_CTRL_KERNEL_PANIC) {
				dev_err(&ctrl_info->pci_dev->dev,
					"controller is offline: status code 0x%x\n",
					readl(
					&ctrl_info->registers->sis_mailbox[7]));
				return -ENODEV;
			}
			if (status & SIS_CTRL_KERNEL_UP)
				break;
		}
		if (time_after(jiffies, timeout)) {
			dev_err(&ctrl_info->pci_dev->dev,
				"controller not ready after %u seconds\n",
				timeout_secs);
			return -ETIMEDOUT;
		}
		msleep(SIS_CTRL_READY_POLL_INTERVAL_MSECS);
	}

	return 0;
}

int sis_wait_for_ctrl_ready(struct pqi_ctrl_info *ctrl_info)
{
	return sis_wait_for_ctrl_ready_with_timeout(ctrl_info,
		SIS_CTRL_READY_TIMEOUT_SECS);
}

int sis_wait_for_ctrl_ready_resume(struct pqi_ctrl_info *ctrl_info)
{
	return sis_wait_for_ctrl_ready_with_timeout(ctrl_info,
		SIS_CTRL_READY_RESUME_TIMEOUT_SECS);
}

bool sis_is_firmware_running(struct pqi_ctrl_info *ctrl_info)
{
	bool running;
	u32 status;

	status = readl(&ctrl_info->registers->sis_firmware_status);

	if (status & SIS_CTRL_KERNEL_PANIC)
		running = false;
	else
		running = true;

	if (!running)
		dev_err(&ctrl_info->pci_dev->dev,
			"controller is offline: status code 0x%x\n",
			readl(&ctrl_info->registers->sis_mailbox[7]));

	return running;
}

bool sis_is_kernel_up(struct pqi_ctrl_info *ctrl_info)
{
	return readl(&ctrl_info->registers->sis_firmware_status) &
				SIS_CTRL_KERNEL_UP;
}

/* used for passing command parameters/results when issuing SIS commands */
struct sis_sync_cmd_params {
	u32	mailbox[6];	/* mailboxes 0-5 */
};

static int sis_send_sync_cmd(struct pqi_ctrl_info *ctrl_info,
	u32 cmd, struct sis_sync_cmd_params *params)
{
	struct pqi_ctrl_registers __iomem *registers;
	unsigned int i;
	unsigned long timeout;
	u32 doorbell;
	u32 cmd_status;

	registers = ctrl_info->registers;

	/* Write the command to mailbox 0. */
	writel(cmd, &registers->sis_mailbox[0]);

	/*
	 * Write the command parameters to mailboxes 1-4 (mailbox 5 is not used
	 * when sending a command to the controller).
	 */
	for (i = 1; i <= 4; i++)
		writel(params->mailbox[i], &registers->sis_mailbox[i]);

	/* Clear the command doorbell. */
	writel(SIS_CLEAR_CTRL_TO_HOST_DOORBELL,
		&registers->sis_ctrl_to_host_doorbell_clear);

	/* Disable doorbell interrupts by masking all interrupts. */
	writel(~0, &registers->sis_interrupt_mask);

	/*
	 * Force the completion of the interrupt mask register write before
	 * submitting the command.
	 */
	readl(&registers->sis_interrupt_mask);

	/* Submit the command to the controller. */
	writel(SIS_CMD_READY, &registers->sis_host_to_ctrl_doorbell);

	/*
	 * Poll for command completion.  Note that the call to msleep() is at
	 * the top of the loop in order to give the controller time to start
	 * processing the command before we start polling.
	 */
	timeout = (SIS_CMD_COMPLETE_TIMEOUT_SECS * HZ) + jiffies;
	while (1) {
		msleep(SIS_CMD_COMPLETE_POLL_INTERVAL_MSECS);
		doorbell = readl(&registers->sis_ctrl_to_host_doorbell);
		if (doorbell & SIS_CMD_COMPLETE)
			break;
		if (time_after(jiffies, timeout))
			return -ETIMEDOUT;
	}

	/* Read the command status from mailbox 0. */
	cmd_status = readl(&registers->sis_mailbox[0]);
	if (cmd_status != SIS_CMD_STATUS_SUCCESS) {
		dev_err(&ctrl_info->pci_dev->dev,
			"SIS command failed for command 0x%x: status = 0x%x\n",
			cmd, cmd_status);
		return -EINVAL;
	}

	/*
	 * The command completed successfully, so save the command status and
	 * read the values returned in mailboxes 1-5.
	 */
	params->mailbox[0] = cmd_status;
	for (i = 1; i < ARRAY_SIZE(params->mailbox); i++)
		params->mailbox[i] = readl(&registers->sis_mailbox[i]);

	return 0;
}

/*
 * This function verifies that we are talking to a controller that speaks PQI.
 */

int sis_get_ctrl_properties(struct pqi_ctrl_info *ctrl_info)
{
	int rc;
	u32 properties;
	u32 extended_properties;
	struct sis_sync_cmd_params params;

	memset(&params, 0, sizeof(params));

	rc = sis_send_sync_cmd(ctrl_info, SIS_CMD_GET_ADAPTER_PROPERTIES,
		&params);
	if (rc)
		return rc;

	properties = params.mailbox[1];

	if (!(properties & SIS_EXTENDED_PROPERTIES_SUPPORTED))
		return -ENODEV;

	extended_properties = params.mailbox[4];

	if ((extended_properties & SIS_REQUIRED_EXTENDED_PROPERTIES) !=
		SIS_REQUIRED_EXTENDED_PROPERTIES)
		return -ENODEV;

	if (extended_properties & SIS_PQI_RESET_QUIESCE_SUPPORTED)
		ctrl_info->pqi_reset_quiesce_supported = true;

	return 0;
}

int sis_get_pqi_capabilities(struct pqi_ctrl_info *ctrl_info)
{
	int rc;
	struct sis_sync_cmd_params params;

	memset(&params, 0, sizeof(params));

	rc = sis_send_sync_cmd(ctrl_info, SIS_CMD_GET_PQI_CAPABILITIES,
		&params);
	if (rc)
		return rc;

	ctrl_info->max_sg_entries = params.mailbox[1];
	ctrl_info->max_transfer_size = params.mailbox[2];
	ctrl_info->max_outstanding_requests = params.mailbox[3];
	ctrl_info->config_table_offset = params.mailbox[4];
	ctrl_info->config_table_length = params.mailbox[5];

	return 0;
}

int sis_init_base_struct_addr(struct pqi_ctrl_info *ctrl_info)
{
	int rc;
	void *base_struct_unaligned;
	struct sis_base_struct *base_struct;
	struct sis_sync_cmd_params params;
	unsigned long error_buffer_paddr;
	dma_addr_t bus_address;

	base_struct_unaligned = kzalloc(sizeof(*base_struct)
		+ SIS_BASE_STRUCT_ALIGNMENT - 1, GFP_KERNEL);
	if (!base_struct_unaligned)
		return -ENOMEM;

	base_struct = PTR_ALIGN(base_struct_unaligned,
		SIS_BASE_STRUCT_ALIGNMENT);
	error_buffer_paddr = (unsigned long)ctrl_info->error_buffer_dma_handle;

	put_unaligned_le32(SIS_BASE_STRUCT_REVISION, &base_struct->revision);
	put_unaligned_le32(lower_32_bits(error_buffer_paddr),
		&base_struct->error_buffer_paddr_low);
	put_unaligned_le32(upper_32_bits(error_buffer_paddr),
		&base_struct->error_buffer_paddr_high);
	put_unaligned_le32(PQI_ERROR_BUFFER_ELEMENT_LENGTH,
		&base_struct->error_buffer_element_length);
	put_unaligned_le32(ctrl_info->max_io_slots,
		&base_struct->error_buffer_num_elements);

	bus_address = pci_map_single(ctrl_info->pci_dev, base_struct,
		sizeof(*base_struct), PCI_DMA_TODEVICE);
	if (pci_dma_mapping_error(ctrl_info->pci_dev, bus_address)) {
		rc = -ENOMEM;
		goto out;
	}

	memset(&params, 0, sizeof(params));
	params.mailbox[1] = lower_32_bits((u64)bus_address);
	params.mailbox[2] = upper_32_bits((u64)bus_address);
	params.mailbox[3] = sizeof(*base_struct);

	rc = sis_send_sync_cmd(ctrl_info, SIS_CMD_INIT_BASE_STRUCT_ADDRESS,
		&params);

	pci_unmap_single(ctrl_info->pci_dev, bus_address, sizeof(*base_struct),
		PCI_DMA_TODEVICE);

out:
	kfree(base_struct_unaligned);

	return rc;
}

#define SIS_DOORBELL_BIT_CLEAR_TIMEOUT_SECS	30

static int sis_wait_for_doorbell_bit_to_clear(
	struct pqi_ctrl_info *ctrl_info, u32 bit)
{
	int rc = 0;
	u32 doorbell_register;
	unsigned long timeout;

	timeout = (SIS_DOORBELL_BIT_CLEAR_TIMEOUT_SECS * HZ) + jiffies;

	while (1) {
		doorbell_register =
			readl(&ctrl_info->registers->sis_host_to_ctrl_doorbell);
		if ((doorbell_register & bit) == 0)
			break;
		if (readl(&ctrl_info->registers->sis_firmware_status) &
			SIS_CTRL_KERNEL_PANIC) {
			rc = -ENODEV;
			break;
		}
		if (time_after(jiffies, timeout)) {
			dev_err(&ctrl_info->pci_dev->dev,
				"doorbell register bit 0x%x not cleared\n",
				bit);
			rc = -ETIMEDOUT;
			break;
		}
		usleep_range(1000, 2000);
	}

	return rc;
}

static inline int sis_set_doorbell_bit(struct pqi_ctrl_info *ctrl_info, u32 bit)
{
	writel(bit, &ctrl_info->registers->sis_host_to_ctrl_doorbell);

	return sis_wait_for_doorbell_bit_to_clear(ctrl_info, bit);
}

void sis_enable_msix(struct pqi_ctrl_info *ctrl_info)
{
	sis_set_doorbell_bit(ctrl_info, SIS_ENABLE_MSIX);
}

void sis_enable_intx(struct pqi_ctrl_info *ctrl_info)
{
	sis_set_doorbell_bit(ctrl_info, SIS_ENABLE_INTX);
}

void sis_shutdown_ctrl(struct pqi_ctrl_info *ctrl_info)
{
	if (readl(&ctrl_info->registers->sis_firmware_status) &
		SIS_CTRL_KERNEL_PANIC)
		return;

	writel(SIS_TRIGGER_SHUTDOWN,
		&ctrl_info->registers->sis_host_to_ctrl_doorbell);
}

int sis_pqi_reset_quiesce(struct pqi_ctrl_info *ctrl_info)
{
	return sis_set_doorbell_bit(ctrl_info, SIS_PQI_RESET_QUIESCE);
}

int sis_reenable_sis_mode(struct pqi_ctrl_info *ctrl_info)
{
	return sis_set_doorbell_bit(ctrl_info, SIS_REENABLE_SIS_MODE);
}

void sis_write_driver_scratch(struct pqi_ctrl_info *ctrl_info, u32 value)
{
	writel(value, &ctrl_info->registers->sis_driver_scratch);
}

u32 sis_read_driver_scratch(struct pqi_ctrl_info *ctrl_info)
{
	return readl(&ctrl_info->registers->sis_driver_scratch);
}

static void __attribute__((unused)) verify_structures(void)
{
	BUILD_BUG_ON(offsetof(struct sis_base_struct,
		revision) != 0x0);
	BUILD_BUG_ON(offsetof(struct sis_base_struct,
		flags) != 0x4);
	BUILD_BUG_ON(offsetof(struct sis_base_struct,
		error_buffer_paddr_low) != 0x8);
	BUILD_BUG_ON(offsetof(struct sis_base_struct,
		error_buffer_paddr_high) != 0xc);
	BUILD_BUG_ON(offsetof(struct sis_base_struct,
		error_buffer_element_length) != 0x10);
	BUILD_BUG_ON(offsetof(struct sis_base_struct,
		error_buffer_num_elements) != 0x14);
	BUILD_BUG_ON(sizeof(struct sis_base_struct) != 0x18);
}
