Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 *    driver for Microsemi PQI-based storage controllers
  4 *    Copyright (c) 2019 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_UP			0x80
 55#define SIS_CTRL_KERNEL_PANIC			0x100
 56#define SIS_CTRL_READY_TIMEOUT_SECS		180
 57#define SIS_CTRL_READY_RESUME_TIMEOUT_SECS	90
 58#define SIS_CTRL_READY_POLL_INTERVAL_MSECS	10
 59
 60#pragma pack(1)
 61
 62/* for use with SIS_CMD_INIT_BASE_STRUCT_ADDRESS command */
 63struct sis_base_struct {
 64	__le32	revision;		/* revision of this structure */
 65	__le32	flags;			/* reserved */
 66	__le32	error_buffer_paddr_low;	/* lower 32 bits of physical memory */
 67					/* buffer for PQI error response */
 68					/* data */
 69	__le32	error_buffer_paddr_high;	/* upper 32 bits of physical */
 70						/* memory buffer for PQI */
 71						/* error response data */
 72	__le32	error_buffer_element_length;	/* length of each PQI error */
 73						/* response buffer element */
 74						/*   in bytes */
 75	__le32	error_buffer_num_elements;	/* total number of PQI error */
 76						/* response buffers available */
 77};
 78
 79#pragma pack()
 80
 81static int sis_wait_for_ctrl_ready_with_timeout(struct pqi_ctrl_info *ctrl_info,
 82	unsigned int timeout_secs)
 83{
 84	unsigned long timeout;
 85	u32 status;
 86
 87	timeout = (timeout_secs * PQI_HZ) + jiffies;
 88
 89	while (1) {
 90		status = readl(&ctrl_info->registers->sis_firmware_status);
 91		if (status != ~0) {
 92			if (status & SIS_CTRL_KERNEL_PANIC) {
 93				dev_err(&ctrl_info->pci_dev->dev,
 94					"controller is offline: status code 0x%x\n",
 95					readl(
 96					&ctrl_info->registers->sis_mailbox[7]));
 97				return -ENODEV;
 98			}
 99			if (status & SIS_CTRL_KERNEL_UP)
100				break;
101		}
102		if (time_after(jiffies, timeout)) {
103			dev_err(&ctrl_info->pci_dev->dev,
104				"controller not ready after %u seconds\n",
105				timeout_secs);
106			return -ETIMEDOUT;
107		}
108		msleep(SIS_CTRL_READY_POLL_INTERVAL_MSECS);
109	}
110
111	return 0;
112}
113
114int sis_wait_for_ctrl_ready(struct pqi_ctrl_info *ctrl_info)
115{
116	return sis_wait_for_ctrl_ready_with_timeout(ctrl_info,
117		SIS_CTRL_READY_TIMEOUT_SECS);
118}
119
120int sis_wait_for_ctrl_ready_resume(struct pqi_ctrl_info *ctrl_info)
121{
122	return sis_wait_for_ctrl_ready_with_timeout(ctrl_info,
123		SIS_CTRL_READY_RESUME_TIMEOUT_SECS);
124}
125
126bool sis_is_firmware_running(struct pqi_ctrl_info *ctrl_info)
127{
128	bool running;
129	u32 status;
130
131	status = readl(&ctrl_info->registers->sis_firmware_status);
132
133	if (status & SIS_CTRL_KERNEL_PANIC)
134		running = false;
135	else
136		running = true;
137
138	if (!running)
139		dev_err(&ctrl_info->pci_dev->dev,
140			"controller is offline: status code 0x%x\n",
141			readl(&ctrl_info->registers->sis_mailbox[7]));
142
143	return running;
144}
145
146bool sis_is_kernel_up(struct pqi_ctrl_info *ctrl_info)
147{
148	return readl(&ctrl_info->registers->sis_firmware_status) &
149				SIS_CTRL_KERNEL_UP;
150}
151
152/* used for passing command parameters/results when issuing SIS commands */
153struct sis_sync_cmd_params {
154	u32	mailbox[6];	/* mailboxes 0-5 */
155};
156
157static int sis_send_sync_cmd(struct pqi_ctrl_info *ctrl_info,
158	u32 cmd, struct sis_sync_cmd_params *params)
159{
160	struct pqi_ctrl_registers __iomem *registers;
161	unsigned int i;
162	unsigned long timeout;
163	u32 doorbell;
164	u32 cmd_status;
165
166	registers = ctrl_info->registers;
167
168	/* Write the command to mailbox 0. */
169	writel(cmd, &registers->sis_mailbox[0]);
170
171	/*
172	 * Write the command parameters to mailboxes 1-4 (mailbox 5 is not used
173	 * when sending a command to the controller).
174	 */
175	for (i = 1; i <= 4; i++)
176		writel(params->mailbox[i], &registers->sis_mailbox[i]);
177
178	/* Clear the command doorbell. */
179	writel(SIS_CLEAR_CTRL_TO_HOST_DOORBELL,
180		&registers->sis_ctrl_to_host_doorbell_clear);
181
182	/* Disable doorbell interrupts by masking all interrupts. */
183	writel(~0, &registers->sis_interrupt_mask);
184
185	/*
186	 * Force the completion of the interrupt mask register write before
187	 * submitting the command.
188	 */
189	readl(&registers->sis_interrupt_mask);
190
191	/* Submit the command to the controller. */
192	writel(SIS_CMD_READY, &registers->sis_host_to_ctrl_doorbell);
193
194	/*
195	 * Poll for command completion.  Note that the call to msleep() is at
196	 * the top of the loop in order to give the controller time to start
197	 * processing the command before we start polling.
198	 */
199	timeout = (SIS_CMD_COMPLETE_TIMEOUT_SECS * PQI_HZ) + jiffies;
200	while (1) {
201		msleep(SIS_CMD_COMPLETE_POLL_INTERVAL_MSECS);
202		doorbell = readl(&registers->sis_ctrl_to_host_doorbell);
203		if (doorbell & SIS_CMD_COMPLETE)
204			break;
205		if (time_after(jiffies, timeout))
206			return -ETIMEDOUT;
207	}
208
209	/* Read the command status from mailbox 0. */
210	cmd_status = readl(&registers->sis_mailbox[0]);
211	if (cmd_status != SIS_CMD_STATUS_SUCCESS) {
212		dev_err(&ctrl_info->pci_dev->dev,
213			"SIS command failed for command 0x%x: status = 0x%x\n",
214			cmd, cmd_status);
215		return -EINVAL;
216	}
217
218	/*
219	 * The command completed successfully, so save the command status and
220	 * read the values returned in mailboxes 1-5.
221	 */
222	params->mailbox[0] = cmd_status;
223	for (i = 1; i < ARRAY_SIZE(params->mailbox); i++)
224		params->mailbox[i] = readl(&registers->sis_mailbox[i]);
225
226	return 0;
227}
228
229/*
230 * This function verifies that we are talking to a controller that speaks PQI.
231 */
232
233int sis_get_ctrl_properties(struct pqi_ctrl_info *ctrl_info)
234{
235	int rc;
236	u32 properties;
237	u32 extended_properties;
238	struct sis_sync_cmd_params params;
239
240	memset(&params, 0, sizeof(params));
241
242	rc = sis_send_sync_cmd(ctrl_info, SIS_CMD_GET_ADAPTER_PROPERTIES,
243		&params);
244	if (rc)
245		return rc;
246
247	properties = params.mailbox[1];
248
249	if (!(properties & SIS_EXTENDED_PROPERTIES_SUPPORTED))
250		return -ENODEV;
251
252	extended_properties = params.mailbox[4];
253
254	if ((extended_properties & SIS_REQUIRED_EXTENDED_PROPERTIES) !=
255		SIS_REQUIRED_EXTENDED_PROPERTIES)
256		return -ENODEV;
257
258	if (extended_properties & SIS_PQI_RESET_QUIESCE_SUPPORTED)
259		ctrl_info->pqi_reset_quiesce_supported = true;
260
261	return 0;
262}
263
264int sis_get_pqi_capabilities(struct pqi_ctrl_info *ctrl_info)
265{
266	int rc;
267	struct sis_sync_cmd_params params;
268
269	memset(&params, 0, sizeof(params));
270
271	rc = sis_send_sync_cmd(ctrl_info, SIS_CMD_GET_PQI_CAPABILITIES,
272		&params);
273	if (rc)
274		return rc;
275
276	ctrl_info->max_sg_entries = params.mailbox[1];
277	ctrl_info->max_transfer_size = params.mailbox[2];
278	ctrl_info->max_outstanding_requests = params.mailbox[3];
279	ctrl_info->config_table_offset = params.mailbox[4];
280	ctrl_info->config_table_length = params.mailbox[5];
281
282	return 0;
283}
284
285int sis_init_base_struct_addr(struct pqi_ctrl_info *ctrl_info)
286{
287	int rc;
288	void *base_struct_unaligned;
289	struct sis_base_struct *base_struct;
290	struct sis_sync_cmd_params params;
291	unsigned long error_buffer_paddr;
292	dma_addr_t bus_address;
293
294	base_struct_unaligned = kzalloc(sizeof(*base_struct)
295		+ SIS_BASE_STRUCT_ALIGNMENT - 1, GFP_KERNEL);
296	if (!base_struct_unaligned)
297		return -ENOMEM;
298
299	base_struct = PTR_ALIGN(base_struct_unaligned,
300		SIS_BASE_STRUCT_ALIGNMENT);
301	error_buffer_paddr = (unsigned long)ctrl_info->error_buffer_dma_handle;
302
303	put_unaligned_le32(SIS_BASE_STRUCT_REVISION, &base_struct->revision);
304	put_unaligned_le32(lower_32_bits(error_buffer_paddr),
305		&base_struct->error_buffer_paddr_low);
306	put_unaligned_le32(upper_32_bits(error_buffer_paddr),
307		&base_struct->error_buffer_paddr_high);
308	put_unaligned_le32(PQI_ERROR_BUFFER_ELEMENT_LENGTH,
309		&base_struct->error_buffer_element_length);
310	put_unaligned_le32(ctrl_info->max_io_slots,
311		&base_struct->error_buffer_num_elements);
312
313	bus_address = dma_map_single(&ctrl_info->pci_dev->dev, base_struct,
314		sizeof(*base_struct), DMA_TO_DEVICE);
315	if (dma_mapping_error(&ctrl_info->pci_dev->dev, bus_address)) {
316		rc = -ENOMEM;
317		goto out;
318	}
319
320	memset(&params, 0, sizeof(params));
321	params.mailbox[1] = lower_32_bits((u64)bus_address);
322	params.mailbox[2] = upper_32_bits((u64)bus_address);
323	params.mailbox[3] = sizeof(*base_struct);
324
325	rc = sis_send_sync_cmd(ctrl_info, SIS_CMD_INIT_BASE_STRUCT_ADDRESS,
326		&params);
327
328	dma_unmap_single(&ctrl_info->pci_dev->dev, bus_address,
329			sizeof(*base_struct), DMA_TO_DEVICE);
330out:
331	kfree(base_struct_unaligned);
332
333	return rc;
334}
335
336#define SIS_DOORBELL_BIT_CLEAR_TIMEOUT_SECS	30
337
338static int sis_wait_for_doorbell_bit_to_clear(
339	struct pqi_ctrl_info *ctrl_info, u32 bit)
340{
341	int rc = 0;
342	u32 doorbell_register;
343	unsigned long timeout;
344
345	timeout = (SIS_DOORBELL_BIT_CLEAR_TIMEOUT_SECS * PQI_HZ) + jiffies;
346
347	while (1) {
348		doorbell_register =
349			readl(&ctrl_info->registers->sis_host_to_ctrl_doorbell);
350		if ((doorbell_register & bit) == 0)
351			break;
352		if (readl(&ctrl_info->registers->sis_firmware_status) &
353			SIS_CTRL_KERNEL_PANIC) {
354			rc = -ENODEV;
355			break;
356		}
357		if (time_after(jiffies, timeout)) {
358			dev_err(&ctrl_info->pci_dev->dev,
359				"doorbell register bit 0x%x not cleared\n",
360				bit);
361			rc = -ETIMEDOUT;
362			break;
363		}
364		usleep_range(1000, 2000);
365	}
366
367	return rc;
368}
369
370static inline int sis_set_doorbell_bit(struct pqi_ctrl_info *ctrl_info, u32 bit)
371{
372	writel(bit, &ctrl_info->registers->sis_host_to_ctrl_doorbell);
373
374	return sis_wait_for_doorbell_bit_to_clear(ctrl_info, bit);
375}
376
377void sis_enable_msix(struct pqi_ctrl_info *ctrl_info)
378{
379	sis_set_doorbell_bit(ctrl_info, SIS_ENABLE_MSIX);
380}
381
382void sis_enable_intx(struct pqi_ctrl_info *ctrl_info)
383{
384	sis_set_doorbell_bit(ctrl_info, SIS_ENABLE_INTX);
385}
386
387void sis_shutdown_ctrl(struct pqi_ctrl_info *ctrl_info)
388{
389	if (readl(&ctrl_info->registers->sis_firmware_status) &
390		SIS_CTRL_KERNEL_PANIC)
391		return;
392
393	writel(SIS_TRIGGER_SHUTDOWN,
394		&ctrl_info->registers->sis_host_to_ctrl_doorbell);
395}
396
397int sis_pqi_reset_quiesce(struct pqi_ctrl_info *ctrl_info)
398{
399	return sis_set_doorbell_bit(ctrl_info, SIS_PQI_RESET_QUIESCE);
400}
401
402int sis_reenable_sis_mode(struct pqi_ctrl_info *ctrl_info)
403{
404	return sis_set_doorbell_bit(ctrl_info, SIS_REENABLE_SIS_MODE);
405}
406
407void sis_write_driver_scratch(struct pqi_ctrl_info *ctrl_info, u32 value)
408{
409	writel(value, &ctrl_info->registers->sis_driver_scratch);
410}
411
412u32 sis_read_driver_scratch(struct pqi_ctrl_info *ctrl_info)
413{
414	return readl(&ctrl_info->registers->sis_driver_scratch);
415}
416
417void sis_soft_reset(struct pqi_ctrl_info *ctrl_info)
418{
419	writel(SIS_SOFT_RESET,
420		&ctrl_info->registers->sis_host_to_ctrl_doorbell);
421}
422
423static void __attribute__((unused)) verify_structures(void)
424{
425	BUILD_BUG_ON(offsetof(struct sis_base_struct,
426		revision) != 0x0);
427	BUILD_BUG_ON(offsetof(struct sis_base_struct,
428		flags) != 0x4);
429	BUILD_BUG_ON(offsetof(struct sis_base_struct,
430		error_buffer_paddr_low) != 0x8);
431	BUILD_BUG_ON(offsetof(struct sis_base_struct,
432		error_buffer_paddr_high) != 0xc);
433	BUILD_BUG_ON(offsetof(struct sis_base_struct,
434		error_buffer_element_length) != 0x10);
435	BUILD_BUG_ON(offsetof(struct sis_base_struct,
436		error_buffer_num_elements) != 0x14);
437	BUILD_BUG_ON(sizeof(struct sis_base_struct) != 0x18);
438}