1 /* 2 * driver for Microsemi PQI-based storage controllers 3 * Copyright (c) 2016 Microsemi Corporation 4 * Copyright (c) 2016 PMC-Sierra, Inc. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; version 2 of the License. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 13 * NON INFRINGEMENT. See the GNU General Public License for more details. 14 * 15 * Questions/Comments/Bugfixes to esc.storagedev@microsemi.com 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 /* legacy SIS interface commands */ 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 /* for submission of legacy SIS commands */ 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 /* used with SIS_CMD_GET_ADAPTER_PROPERTIES command */ 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 /* used with SIS_CMD_INIT_BASE_STRUCT_ADDRESS command */ 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 /* for use with SIS_CMD_INIT_BASE_STRUCT_ADDRESS command */ 63 struct 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 81 int 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 109 bool 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 129 /* used for passing command parameters/results when issuing SIS commands */ 130 struct sis_sync_cmd_params { 131 u32 mailbox[6]; /* mailboxes 0-5 */ 132 }; 133 134 static int sis_send_sync_cmd(struct pqi_ctrl_info *ctrl_info, 135 u32 cmd, struct sis_sync_cmd_params *params) 136 { 137 struct pqi_ctrl_registers __iomem *registers; 138 unsigned int i; 139 unsigned long timeout; 140 u32 doorbell; 141 u32 cmd_status; 142 143 registers = ctrl_info->registers; 144 145 /* Write the command to mailbox 0. */ 146 writel(cmd, ®isters->sis_mailbox[0]); 147 148 /* 149 * Write the command parameters to mailboxes 1-4 (mailbox 5 is not used 150 * when sending a command to the controller). 151 */ 152 for (i = 1; i <= 4; i++) 153 writel(params->mailbox[i], ®isters->sis_mailbox[i]); 154 155 /* Clear the command doorbell. */ 156 writel(SIS_CLEAR_CTRL_TO_HOST_DOORBELL, 157 ®isters->sis_ctrl_to_host_doorbell_clear); 158 159 /* Disable doorbell interrupts by masking all interrupts. */ 160 writel(~0, ®isters->sis_interrupt_mask); 161 162 /* 163 * Force the completion of the interrupt mask register write before 164 * submitting the command. 165 */ 166 readl(®isters->sis_interrupt_mask); 167 168 /* Submit the command to the controller. */ 169 writel(SIS_CMD_READY, ®isters->sis_host_to_ctrl_doorbell); 170 171 /* 172 * Poll for command completion. Note that the call to msleep() is at 173 * the top of the loop in order to give the controller time to start 174 * processing the command before we start polling. 175 */ 176 timeout = (SIS_CMD_COMPLETE_TIMEOUT_SECS * HZ) + jiffies; 177 while (1) { 178 msleep(SIS_CMD_COMPLETE_POLL_INTERVAL_MSECS); 179 doorbell = readl(®isters->sis_ctrl_to_host_doorbell); 180 if (doorbell & SIS_CMD_COMPLETE) 181 break; 182 if (time_after(jiffies, timeout)) 183 return -ETIMEDOUT; 184 } 185 186 /* Read the command status from mailbox 0. */ 187 cmd_status = readl(®isters->sis_mailbox[0]); 188 if (cmd_status != SIS_CMD_STATUS_SUCCESS) { 189 dev_err(&ctrl_info->pci_dev->dev, 190 "SIS command failed for command 0x%x: status = 0x%x\n", 191 cmd, cmd_status); 192 return -EINVAL; 193 } 194 195 /* 196 * The command completed successfully, so save the command status and 197 * read the values returned in mailboxes 1-5. 198 */ 199 params->mailbox[0] = cmd_status; 200 for (i = 1; i < ARRAY_SIZE(params->mailbox); i++) 201 params->mailbox[i] = readl(®isters->sis_mailbox[i]); 202 203 return 0; 204 } 205 206 /* 207 * This function verifies that we are talking to a controller that speaks PQI. 208 */ 209 210 int sis_get_ctrl_properties(struct pqi_ctrl_info *ctrl_info) 211 { 212 int rc; 213 u32 properties; 214 u32 extended_properties; 215 struct sis_sync_cmd_params params; 216 217 memset(¶ms, 0, sizeof(params)); 218 219 rc = sis_send_sync_cmd(ctrl_info, SIS_CMD_GET_ADAPTER_PROPERTIES, 220 ¶ms); 221 if (rc) 222 return rc; 223 224 properties = params.mailbox[1]; 225 226 if (!(properties & SIS_EXTENDED_PROPERTIES_SUPPORTED)) 227 return -ENODEV; 228 229 extended_properties = params.mailbox[4]; 230 231 if ((extended_properties & SIS_REQUIRED_EXTENDED_PROPERTIES) != 232 SIS_REQUIRED_EXTENDED_PROPERTIES) 233 return -ENODEV; 234 235 return 0; 236 } 237 238 int sis_get_pqi_capabilities(struct pqi_ctrl_info *ctrl_info) 239 { 240 int rc; 241 struct sis_sync_cmd_params params; 242 243 memset(¶ms, 0, sizeof(params)); 244 245 rc = sis_send_sync_cmd(ctrl_info, SIS_CMD_GET_PQI_CAPABILITIES, 246 ¶ms); 247 if (rc) 248 return rc; 249 250 ctrl_info->max_sg_entries = params.mailbox[1]; 251 ctrl_info->max_transfer_size = params.mailbox[2]; 252 ctrl_info->max_outstanding_requests = params.mailbox[3]; 253 ctrl_info->config_table_offset = params.mailbox[4]; 254 ctrl_info->config_table_length = params.mailbox[5]; 255 256 return 0; 257 } 258 259 int sis_init_base_struct_addr(struct pqi_ctrl_info *ctrl_info) 260 { 261 int rc; 262 void *base_struct_unaligned; 263 struct sis_base_struct *base_struct; 264 struct sis_sync_cmd_params params; 265 unsigned long error_buffer_paddr; 266 dma_addr_t bus_address; 267 268 base_struct_unaligned = kzalloc(sizeof(*base_struct) 269 + SIS_BASE_STRUCT_ALIGNMENT - 1, GFP_KERNEL); 270 if (!base_struct_unaligned) 271 return -ENOMEM; 272 273 base_struct = PTR_ALIGN(base_struct_unaligned, 274 SIS_BASE_STRUCT_ALIGNMENT); 275 error_buffer_paddr = (unsigned long)ctrl_info->error_buffer_dma_handle; 276 277 put_unaligned_le32(SIS_BASE_STRUCT_REVISION, &base_struct->revision); 278 put_unaligned_le32(lower_32_bits(error_buffer_paddr), 279 &base_struct->error_buffer_paddr_low); 280 put_unaligned_le32(upper_32_bits(error_buffer_paddr), 281 &base_struct->error_buffer_paddr_high); 282 put_unaligned_le32(PQI_ERROR_BUFFER_ELEMENT_LENGTH, 283 &base_struct->error_buffer_element_length); 284 put_unaligned_le32(ctrl_info->max_io_slots, 285 &base_struct->error_buffer_num_elements); 286 287 bus_address = pci_map_single(ctrl_info->pci_dev, base_struct, 288 sizeof(*base_struct), PCI_DMA_TODEVICE); 289 if (pci_dma_mapping_error(ctrl_info->pci_dev, bus_address)) { 290 rc = -ENOMEM; 291 goto out; 292 } 293 294 memset(¶ms, 0, sizeof(params)); 295 params.mailbox[1] = lower_32_bits((u64)bus_address); 296 params.mailbox[2] = upper_32_bits((u64)bus_address); 297 params.mailbox[3] = sizeof(*base_struct); 298 299 rc = sis_send_sync_cmd(ctrl_info, SIS_CMD_INIT_BASE_STRUCT_ADDRESS, 300 ¶ms); 301 302 pci_unmap_single(ctrl_info->pci_dev, bus_address, sizeof(*base_struct), 303 PCI_DMA_TODEVICE); 304 305 out: 306 kfree(base_struct_unaligned); 307 308 return rc; 309 } 310 311 /* Enable MSI-X interrupts on the controller. */ 312 313 void sis_enable_msix(struct pqi_ctrl_info *ctrl_info) 314 { 315 u32 doorbell_register; 316 317 doorbell_register = 318 readl(&ctrl_info->registers->sis_host_to_ctrl_doorbell); 319 doorbell_register |= SIS_ENABLE_MSIX; 320 321 writel(doorbell_register, 322 &ctrl_info->registers->sis_host_to_ctrl_doorbell); 323 } 324 325 /* Disable MSI-X interrupts on the controller. */ 326 327 void sis_disable_msix(struct pqi_ctrl_info *ctrl_info) 328 { 329 u32 doorbell_register; 330 331 doorbell_register = 332 readl(&ctrl_info->registers->sis_host_to_ctrl_doorbell); 333 doorbell_register &= ~SIS_ENABLE_MSIX; 334 335 writel(doorbell_register, 336 &ctrl_info->registers->sis_host_to_ctrl_doorbell); 337 } 338 339 void sis_soft_reset(struct pqi_ctrl_info *ctrl_info) 340 { 341 writel(SIS_SOFT_RESET, 342 &ctrl_info->registers->sis_host_to_ctrl_doorbell); 343 } 344 345 #define SIS_MODE_READY_TIMEOUT_SECS 30 346 347 int sis_reenable_sis_mode(struct pqi_ctrl_info *ctrl_info) 348 { 349 int rc; 350 unsigned long timeout; 351 struct pqi_ctrl_registers __iomem *registers; 352 u32 doorbell; 353 354 registers = ctrl_info->registers; 355 356 writel(SIS_REENABLE_SIS_MODE, 357 ®isters->sis_host_to_ctrl_doorbell); 358 359 rc = 0; 360 timeout = (SIS_MODE_READY_TIMEOUT_SECS * HZ) + jiffies; 361 362 while (1) { 363 doorbell = readl(®isters->sis_ctrl_to_host_doorbell); 364 if ((doorbell & SIS_REENABLE_SIS_MODE) == 0) 365 break; 366 if (time_after(jiffies, timeout)) { 367 rc = -ETIMEDOUT; 368 break; 369 } 370 } 371 372 if (rc) 373 dev_err(&ctrl_info->pci_dev->dev, 374 "re-enabling SIS mode failed\n"); 375 376 return rc; 377 } 378 379 void sis_write_driver_scratch(struct pqi_ctrl_info *ctrl_info, u32 value) 380 { 381 writel(value, &ctrl_info->registers->sis_driver_scratch); 382 } 383 384 u32 sis_read_driver_scratch(struct pqi_ctrl_info *ctrl_info) 385 { 386 return readl(&ctrl_info->registers->sis_driver_scratch); 387 } 388 389 static void __attribute__((unused)) verify_structures(void) 390 { 391 BUILD_BUG_ON(offsetof(struct sis_base_struct, 392 revision) != 0x0); 393 BUILD_BUG_ON(offsetof(struct sis_base_struct, 394 flags) != 0x4); 395 BUILD_BUG_ON(offsetof(struct sis_base_struct, 396 error_buffer_paddr_low) != 0x8); 397 BUILD_BUG_ON(offsetof(struct sis_base_struct, 398 error_buffer_paddr_high) != 0xc); 399 BUILD_BUG_ON(offsetof(struct sis_base_struct, 400 error_buffer_element_length) != 0x10); 401 BUILD_BUG_ON(offsetof(struct sis_base_struct, 402 error_buffer_num_elements) != 0x14); 403 BUILD_BUG_ON(sizeof(struct sis_base_struct) != 0x18); 404 } 405