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