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