1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include <linux/module.h>
20#include <linux/kernel.h>
21#include <linux/delay.h>
22#include <linux/pci.h>
23#include <scsi/scsi_device.h>
24#include <asm/unaligned.h>
25#include "smartpqi.h"
26#include "smartpqi_sis.h"
27
28
29#define SIS_CMD_GET_ADAPTER_PROPERTIES 0x19
30#define SIS_CMD_INIT_BASE_STRUCT_ADDRESS 0x1b
31#define SIS_CMD_GET_PQI_CAPABILITIES 0x3000
32
33
34#define SIS_REENABLE_SIS_MODE 0x1
35#define SIS_ENABLE_MSIX 0x40
36#define SIS_SOFT_RESET 0x100
37#define SIS_CMD_READY 0x200
38#define SIS_CMD_COMPLETE 0x1000
39#define SIS_CLEAR_CTRL_TO_HOST_DOORBELL 0x1000
40#define SIS_CMD_STATUS_SUCCESS 0x1
41#define SIS_CMD_COMPLETE_TIMEOUT_SECS 30
42#define SIS_CMD_COMPLETE_POLL_INTERVAL_MSECS 10
43
44
45#define SIS_EXTENDED_PROPERTIES_SUPPORTED 0x800000
46#define SIS_SMARTARRAY_FEATURES_SUPPORTED 0x2
47#define SIS_PQI_MODE_SUPPORTED 0x4
48#define SIS_REQUIRED_EXTENDED_PROPERTIES \
49 (SIS_SMARTARRAY_FEATURES_SUPPORTED | SIS_PQI_MODE_SUPPORTED)
50
51
52#define SIS_BASE_STRUCT_REVISION 9
53#define SIS_BASE_STRUCT_ALIGNMENT 16
54
55#define SIS_CTRL_KERNEL_UP 0x80
56#define SIS_CTRL_KERNEL_PANIC 0x100
57#define SIS_CTRL_READY_TIMEOUT_SECS 30
58#define SIS_CTRL_READY_POLL_INTERVAL_MSECS 10
59
60#pragma pack(1)
61
62
63struct sis_base_struct {
64 __le32 revision;
65 __le32 flags;
66 __le32 error_buffer_paddr_low;
67
68
69 __le32 error_buffer_paddr_high;
70
71
72 __le32 error_buffer_element_length;
73
74
75 __le32 error_buffer_num_elements;
76
77};
78
79#pragma pack()
80
81int sis_wait_for_ctrl_ready(struct pqi_ctrl_info *ctrl_info)
82{
83 unsigned long timeout;
84 u32 status;
85
86 timeout = (SIS_CTRL_READY_TIMEOUT_SECS * HZ) + jiffies;
87
88 while (1) {
89 status = readl(&ctrl_info->registers->sis_firmware_status);
90 if (status != ~0) {
91 if (status & SIS_CTRL_KERNEL_PANIC) {
92 dev_err(&ctrl_info->pci_dev->dev,
93 "controller is offline: status code 0x%x\n",
94 readl(
95 &ctrl_info->registers->sis_mailbox[7]));
96 return -ENODEV;
97 }
98 if (status & SIS_CTRL_KERNEL_UP)
99 break;
100 }
101 if (time_after(jiffies, timeout))
102 return -ETIMEDOUT;
103 msleep(SIS_CTRL_READY_POLL_INTERVAL_MSECS);
104 }
105
106 return 0;
107}
108
109bool sis_is_firmware_running(struct pqi_ctrl_info *ctrl_info)
110{
111 bool running;
112 u32 status;
113
114 status = readl(&ctrl_info->registers->sis_firmware_status);
115
116 if (status & SIS_CTRL_KERNEL_PANIC)
117 running = false;
118 else
119 running = true;
120
121 if (!running)
122 dev_err(&ctrl_info->pci_dev->dev,
123 "controller is offline: status code 0x%x\n",
124 readl(&ctrl_info->registers->sis_mailbox[7]));
125
126 return running;
127}
128
129bool sis_is_kernel_up(struct pqi_ctrl_info *ctrl_info)
130{
131 return readl(&ctrl_info->registers->sis_firmware_status) &
132 SIS_CTRL_KERNEL_UP;
133}
134
135
136struct sis_sync_cmd_params {
137 u32 mailbox[6];
138};
139
140static int sis_send_sync_cmd(struct pqi_ctrl_info *ctrl_info,
141 u32 cmd, struct sis_sync_cmd_params *params)
142{
143 struct pqi_ctrl_registers __iomem *registers;
144 unsigned int i;
145 unsigned long timeout;
146 u32 doorbell;
147 u32 cmd_status;
148
149 registers = ctrl_info->registers;
150
151
152 writel(cmd, ®isters->sis_mailbox[0]);
153
154
155
156
157
158 for (i = 1; i <= 4; i++)
159 writel(params->mailbox[i], ®isters->sis_mailbox[i]);
160
161
162 writel(SIS_CLEAR_CTRL_TO_HOST_DOORBELL,
163 ®isters->sis_ctrl_to_host_doorbell_clear);
164
165
166 writel(~0, ®isters->sis_interrupt_mask);
167
168
169
170
171
172 readl(®isters->sis_interrupt_mask);
173
174
175 writel(SIS_CMD_READY, ®isters->sis_host_to_ctrl_doorbell);
176
177
178
179
180
181
182 timeout = (SIS_CMD_COMPLETE_TIMEOUT_SECS * HZ) + jiffies;
183 while (1) {
184 msleep(SIS_CMD_COMPLETE_POLL_INTERVAL_MSECS);
185 doorbell = readl(®isters->sis_ctrl_to_host_doorbell);
186 if (doorbell & SIS_CMD_COMPLETE)
187 break;
188 if (time_after(jiffies, timeout))
189 return -ETIMEDOUT;
190 }
191
192
193 cmd_status = readl(®isters->sis_mailbox[0]);
194 if (cmd_status != SIS_CMD_STATUS_SUCCESS) {
195 dev_err(&ctrl_info->pci_dev->dev,
196 "SIS command failed for command 0x%x: status = 0x%x\n",
197 cmd, cmd_status);
198 return -EINVAL;
199 }
200
201
202
203
204
205 params->mailbox[0] = cmd_status;
206 for (i = 1; i < ARRAY_SIZE(params->mailbox); i++)
207 params->mailbox[i] = readl(®isters->sis_mailbox[i]);
208
209 return 0;
210}
211
212
213
214
215
216int sis_get_ctrl_properties(struct pqi_ctrl_info *ctrl_info)
217{
218 int rc;
219 u32 properties;
220 u32 extended_properties;
221 struct sis_sync_cmd_params params;
222
223 memset(¶ms, 0, sizeof(params));
224
225 rc = sis_send_sync_cmd(ctrl_info, SIS_CMD_GET_ADAPTER_PROPERTIES,
226 ¶ms);
227 if (rc)
228 return rc;
229
230 properties = params.mailbox[1];
231
232 if (!(properties & SIS_EXTENDED_PROPERTIES_SUPPORTED))
233 return -ENODEV;
234
235 extended_properties = params.mailbox[4];
236
237 if ((extended_properties & SIS_REQUIRED_EXTENDED_PROPERTIES) !=
238 SIS_REQUIRED_EXTENDED_PROPERTIES)
239 return -ENODEV;
240
241 return 0;
242}
243
244int sis_get_pqi_capabilities(struct pqi_ctrl_info *ctrl_info)
245{
246 int rc;
247 struct sis_sync_cmd_params params;
248
249 memset(¶ms, 0, sizeof(params));
250
251 rc = sis_send_sync_cmd(ctrl_info, SIS_CMD_GET_PQI_CAPABILITIES,
252 ¶ms);
253 if (rc)
254 return rc;
255
256 ctrl_info->max_sg_entries = params.mailbox[1];
257 ctrl_info->max_transfer_size = params.mailbox[2];
258 ctrl_info->max_outstanding_requests = params.mailbox[3];
259 ctrl_info->config_table_offset = params.mailbox[4];
260 ctrl_info->config_table_length = params.mailbox[5];
261
262 return 0;
263}
264
265int sis_init_base_struct_addr(struct pqi_ctrl_info *ctrl_info)
266{
267 int rc;
268 void *base_struct_unaligned;
269 struct sis_base_struct *base_struct;
270 struct sis_sync_cmd_params params;
271 unsigned long error_buffer_paddr;
272 dma_addr_t bus_address;
273
274 base_struct_unaligned = kzalloc(sizeof(*base_struct)
275 + SIS_BASE_STRUCT_ALIGNMENT - 1, GFP_KERNEL);
276 if (!base_struct_unaligned)
277 return -ENOMEM;
278
279 base_struct = PTR_ALIGN(base_struct_unaligned,
280 SIS_BASE_STRUCT_ALIGNMENT);
281 error_buffer_paddr = (unsigned long)ctrl_info->error_buffer_dma_handle;
282
283 put_unaligned_le32(SIS_BASE_STRUCT_REVISION, &base_struct->revision);
284 put_unaligned_le32(lower_32_bits(error_buffer_paddr),
285 &base_struct->error_buffer_paddr_low);
286 put_unaligned_le32(upper_32_bits(error_buffer_paddr),
287 &base_struct->error_buffer_paddr_high);
288 put_unaligned_le32(PQI_ERROR_BUFFER_ELEMENT_LENGTH,
289 &base_struct->error_buffer_element_length);
290 put_unaligned_le32(ctrl_info->max_io_slots,
291 &base_struct->error_buffer_num_elements);
292
293 bus_address = pci_map_single(ctrl_info->pci_dev, base_struct,
294 sizeof(*base_struct), PCI_DMA_TODEVICE);
295 if (pci_dma_mapping_error(ctrl_info->pci_dev, bus_address)) {
296 rc = -ENOMEM;
297 goto out;
298 }
299
300 memset(¶ms, 0, sizeof(params));
301 params.mailbox[1] = lower_32_bits((u64)bus_address);
302 params.mailbox[2] = upper_32_bits((u64)bus_address);
303 params.mailbox[3] = sizeof(*base_struct);
304
305 rc = sis_send_sync_cmd(ctrl_info, SIS_CMD_INIT_BASE_STRUCT_ADDRESS,
306 ¶ms);
307
308 pci_unmap_single(ctrl_info->pci_dev, bus_address, sizeof(*base_struct),
309 PCI_DMA_TODEVICE);
310
311out:
312 kfree(base_struct_unaligned);
313
314 return rc;
315}
316
317
318
319void sis_enable_msix(struct pqi_ctrl_info *ctrl_info)
320{
321 u32 doorbell_register;
322
323 doorbell_register =
324 readl(&ctrl_info->registers->sis_host_to_ctrl_doorbell);
325 doorbell_register |= SIS_ENABLE_MSIX;
326
327 writel(doorbell_register,
328 &ctrl_info->registers->sis_host_to_ctrl_doorbell);
329}
330
331
332
333void sis_disable_msix(struct pqi_ctrl_info *ctrl_info)
334{
335 u32 doorbell_register;
336
337 doorbell_register =
338 readl(&ctrl_info->registers->sis_host_to_ctrl_doorbell);
339 doorbell_register &= ~SIS_ENABLE_MSIX;
340
341 writel(doorbell_register,
342 &ctrl_info->registers->sis_host_to_ctrl_doorbell);
343}
344
345void sis_soft_reset(struct pqi_ctrl_info *ctrl_info)
346{
347 writel(SIS_SOFT_RESET,
348 &ctrl_info->registers->sis_host_to_ctrl_doorbell);
349}
350
351#define SIS_MODE_READY_TIMEOUT_SECS 30
352
353int sis_reenable_sis_mode(struct pqi_ctrl_info *ctrl_info)
354{
355 int rc;
356 unsigned long timeout;
357 struct pqi_ctrl_registers __iomem *registers;
358 u32 doorbell;
359
360 registers = ctrl_info->registers;
361
362 writel(SIS_REENABLE_SIS_MODE,
363 ®isters->sis_host_to_ctrl_doorbell);
364
365 rc = 0;
366 timeout = (SIS_MODE_READY_TIMEOUT_SECS * HZ) + jiffies;
367
368 while (1) {
369 doorbell = readl(®isters->sis_ctrl_to_host_doorbell);
370 if ((doorbell & SIS_REENABLE_SIS_MODE) == 0)
371 break;
372 if (time_after(jiffies, timeout)) {
373 rc = -ETIMEDOUT;
374 break;
375 }
376 }
377
378 if (rc)
379 dev_err(&ctrl_info->pci_dev->dev,
380 "re-enabling SIS mode failed\n");
381
382 return rc;
383}
384
385void sis_write_driver_scratch(struct pqi_ctrl_info *ctrl_info, u32 value)
386{
387 writel(value, &ctrl_info->registers->sis_driver_scratch);
388}
389
390u32 sis_read_driver_scratch(struct pqi_ctrl_info *ctrl_info)
391{
392 return readl(&ctrl_info->registers->sis_driver_scratch);
393}
394
395static void __attribute__((unused)) verify_structures(void)
396{
397 BUILD_BUG_ON(offsetof(struct sis_base_struct,
398 revision) != 0x0);
399 BUILD_BUG_ON(offsetof(struct sis_base_struct,
400 flags) != 0x4);
401 BUILD_BUG_ON(offsetof(struct sis_base_struct,
402 error_buffer_paddr_low) != 0x8);
403 BUILD_BUG_ON(offsetof(struct sis_base_struct,
404 error_buffer_paddr_high) != 0xc);
405 BUILD_BUG_ON(offsetof(struct sis_base_struct,
406 error_buffer_element_length) != 0x10);
407 BUILD_BUG_ON(offsetof(struct sis_base_struct,
408 error_buffer_num_elements) != 0x14);
409 BUILD_BUG_ON(sizeof(struct sis_base_struct) != 0x18);
410}
411