linux/drivers/scsi/mvumi.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3  * Marvell UMI head file
   4  *
   5  * Copyright 2011 Marvell. <jyli@marvell.com>
   6 */
   7
   8#ifndef MVUMI_H
   9#define MVUMI_H
  10
  11#define MAX_BASE_ADDRESS        6
  12
  13#define VER_MAJOR               1
  14#define VER_MINOR               1
  15#define VER_OEM                 0
  16#define VER_BUILD               1500
  17
  18#define MV_DRIVER_NAME                  "mvumi"
  19#define PCI_DEVICE_ID_MARVELL_MV9143    0x9143
  20#define PCI_DEVICE_ID_MARVELL_MV9580    0x9580
  21
  22#define MVUMI_INTERNAL_CMD_WAIT_TIME    45
  23#define MVUMI_INQUIRY_LENGTH            44
  24#define MVUMI_INQUIRY_UUID_OFF          36
  25#define MVUMI_INQUIRY_UUID_LEN          8
  26
  27#define IS_DMA64                        (sizeof(dma_addr_t) == 8)
  28
  29enum mvumi_qc_result {
  30        MV_QUEUE_COMMAND_RESULT_SENT = 0,
  31        MV_QUEUE_COMMAND_RESULT_NO_RESOURCE,
  32};
  33
  34struct mvumi_hw_regs {
  35        /* For CPU */
  36        void *main_int_cause_reg;
  37        void *enpointa_mask_reg;
  38        void *enpointb_mask_reg;
  39        void *rstoutn_en_reg;
  40        void *ctrl_sts_reg;
  41        void *rstoutn_mask_reg;
  42        void *sys_soft_rst_reg;
  43
  44        /* For Doorbell */
  45        void *pciea_to_arm_drbl_reg;
  46        void *arm_to_pciea_drbl_reg;
  47        void *arm_to_pciea_mask_reg;
  48        void *pciea_to_arm_msg0;
  49        void *pciea_to_arm_msg1;
  50        void *arm_to_pciea_msg0;
  51        void *arm_to_pciea_msg1;
  52
  53        /* reset register */
  54        void *reset_request;
  55        void *reset_enable;
  56
  57        /* For Message Unit */
  58        void *inb_list_basel;
  59        void *inb_list_baseh;
  60        void *inb_aval_count_basel;
  61        void *inb_aval_count_baseh;
  62        void *inb_write_pointer;
  63        void *inb_read_pointer;
  64        void *outb_list_basel;
  65        void *outb_list_baseh;
  66        void *outb_copy_basel;
  67        void *outb_copy_baseh;
  68        void *outb_copy_pointer;
  69        void *outb_read_pointer;
  70        void *inb_isr_cause;
  71        void *outb_isr_cause;
  72        void *outb_coal_cfg;
  73        void *outb_coal_timeout;
  74
  75        /* Bit setting for HW */
  76        u32 int_comaout;
  77        u32 int_comaerr;
  78        u32 int_dl_cpu2pciea;
  79        u32 int_mu;
  80        u32 int_drbl_int_mask;
  81        u32 int_main_int_mask;
  82        u32 cl_pointer_toggle;
  83        u32 cl_slot_num_mask;
  84        u32 clic_irq;
  85        u32 clic_in_err;
  86        u32 clic_out_err;
  87};
  88
  89struct mvumi_dyn_list_entry {
  90        u32 src_low_addr;
  91        u32 src_high_addr;
  92        u32 if_length;
  93        u32 reserve;
  94};
  95
  96#define SCSI_CMD_MARVELL_SPECIFIC       0xE1
  97#define CDB_CORE_MODULE                 0x1
  98#define CDB_CORE_SHUTDOWN               0xB
  99
 100enum {
 101        DRBL_HANDSHAKE                  = 1 << 0,
 102        DRBL_SOFT_RESET                 = 1 << 1,
 103        DRBL_BUS_CHANGE                 = 1 << 2,
 104        DRBL_EVENT_NOTIFY               = 1 << 3,
 105        DRBL_MU_RESET                   = 1 << 4,
 106        DRBL_HANDSHAKE_ISR              = DRBL_HANDSHAKE,
 107
 108        /*
 109        * Command flag is the flag for the CDB command itself
 110        */
 111        /* 1-non data; 0-data command */
 112        CMD_FLAG_NON_DATA               = 1 << 0,
 113        CMD_FLAG_DMA                    = 1 << 1,
 114        CMD_FLAG_PIO                    = 1 << 2,
 115        /* 1-host read data */
 116        CMD_FLAG_DATA_IN                = 1 << 3,
 117        /* 1-host write data */
 118        CMD_FLAG_DATA_OUT               = 1 << 4,
 119        CMD_FLAG_PRDT_IN_HOST           = 1 << 5,
 120};
 121
 122#define APICDB0_EVENT                   0xF4
 123#define APICDB1_EVENT_GETEVENT          0
 124#define APICDB1_HOST_GETEVENT           1
 125#define MAX_EVENTS_RETURNED             6
 126
 127#define DEVICE_OFFLINE  0
 128#define DEVICE_ONLINE   1
 129
 130struct mvumi_hotplug_event {
 131        u16 size;
 132        u8 dummy[2];
 133        u8 bitmap[];
 134};
 135
 136struct mvumi_driver_event {
 137        u32     time_stamp;
 138        u32     sequence_no;
 139        u32     event_id;
 140        u8      severity;
 141        u8      param_count;
 142        u16     device_id;
 143        u32     params[4];
 144        u8      sense_data_length;
 145        u8      Reserved1;
 146        u8      sense_data[30];
 147};
 148
 149struct mvumi_event_req {
 150        unsigned char   count;
 151        unsigned char   reserved[3];
 152        struct mvumi_driver_event  events[MAX_EVENTS_RETURNED];
 153};
 154
 155struct mvumi_events_wq {
 156        struct work_struct work_q;
 157        struct mvumi_hba *mhba;
 158        unsigned int event;
 159        void *param;
 160};
 161
 162#define HS_CAPABILITY_SUPPORT_COMPACT_SG        (1U << 4)
 163#define HS_CAPABILITY_SUPPORT_PRD_HOST          (1U << 5)
 164#define HS_CAPABILITY_SUPPORT_DYN_SRC           (1U << 6)
 165#define HS_CAPABILITY_NEW_PAGE_IO_DEPTH_DEF     (1U << 14)
 166
 167#define MVUMI_MAX_SG_ENTRY      32
 168#define SGD_EOT                 (1L << 27)
 169#define SGD_EOT_CP              (1L << 22)
 170
 171struct mvumi_sgl {
 172        u32     baseaddr_l;
 173        u32     baseaddr_h;
 174        u32     flags;
 175        u32     size;
 176};
 177struct mvumi_compact_sgl {
 178        u32     baseaddr_l;
 179        u32     baseaddr_h;
 180        u32     flags;
 181};
 182
 183#define GET_COMPACT_SGD_SIZE(sgd)       \
 184        ((((struct mvumi_compact_sgl *)(sgd))->flags) & 0x3FFFFFL)
 185
 186#define SET_COMPACT_SGD_SIZE(sgd, sz) do {                      \
 187        (((struct mvumi_compact_sgl *)(sgd))->flags) &= ~0x3FFFFFL;     \
 188        (((struct mvumi_compact_sgl *)(sgd))->flags) |= (sz);           \
 189} while (0)
 190#define sgd_getsz(_mhba, sgd, sz) do {                          \
 191        if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG)   \
 192                (sz) = GET_COMPACT_SGD_SIZE(sgd);       \
 193        else \
 194                (sz) = (sgd)->size;                     \
 195} while (0)
 196
 197#define sgd_setsz(_mhba, sgd, sz) do {                          \
 198        if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG)   \
 199                SET_COMPACT_SGD_SIZE(sgd, sz);          \
 200        else \
 201                (sgd)->size = (sz);                     \
 202} while (0)
 203
 204#define sgd_inc(_mhba, sgd) do {        \
 205        if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG)   \
 206                sgd = (struct mvumi_sgl *)(((unsigned char *) (sgd)) + 12); \
 207        else \
 208                sgd = (struct mvumi_sgl *)(((unsigned char *) (sgd)) + 16); \
 209} while (0)
 210
 211struct mvumi_res {
 212        struct list_head entry;
 213        dma_addr_t bus_addr;
 214        void *virt_addr;
 215        unsigned int size;
 216        unsigned short type;    /* enum Resource_Type */
 217};
 218
 219/* Resource type */
 220enum resource_type {
 221        RESOURCE_CACHED_MEMORY = 0,
 222        RESOURCE_UNCACHED_MEMORY
 223};
 224
 225struct mvumi_sense_data {
 226        u8 error_code:7;
 227        u8 valid:1;
 228        u8 segment_number;
 229        u8 sense_key:4;
 230        u8 reserved:1;
 231        u8 incorrect_length:1;
 232        u8 end_of_media:1;
 233        u8 file_mark:1;
 234        u8 information[4];
 235        u8 additional_sense_length;
 236        u8 command_specific_information[4];
 237        u8 additional_sense_code;
 238        u8 additional_sense_code_qualifier;
 239        u8 field_replaceable_unit_code;
 240        u8 sense_key_specific[3];
 241};
 242
 243/* Request initiator must set the status to REQ_STATUS_PENDING. */
 244#define REQ_STATUS_PENDING              0x80
 245
 246struct mvumi_cmd {
 247        struct list_head queue_pointer;
 248        struct mvumi_msg_frame *frame;
 249        dma_addr_t frame_phys;
 250        struct scsi_cmnd *scmd;
 251        atomic_t sync_cmd;
 252        void *data_buf;
 253        unsigned short request_id;
 254        unsigned char cmd_status;
 255};
 256
 257/*
 258 * the function type of the in bound frame
 259 */
 260#define CL_FUN_SCSI_CMD                 0x1
 261
 262struct mvumi_msg_frame {
 263        u16 device_id;
 264        u16 tag;
 265        u8 cmd_flag;
 266        u8 req_function;
 267        u8 cdb_length;
 268        u8 sg_counts;
 269        u32 data_transfer_length;
 270        u16 request_id;
 271        u16 reserved1;
 272        u8 cdb[MAX_COMMAND_SIZE];
 273        u32 payload[1];
 274};
 275
 276/*
 277 * the respond flag for data_payload of the out bound frame
 278 */
 279#define CL_RSP_FLAG_NODATA              0x0
 280#define CL_RSP_FLAG_SENSEDATA           0x1
 281
 282struct mvumi_rsp_frame {
 283        u16 device_id;
 284        u16 tag;
 285        u8 req_status;
 286        u8 rsp_flag;    /* Indicates the type of Data_Payload.*/
 287        u16 request_id;
 288        u32 payload[1];
 289};
 290
 291struct mvumi_ob_data {
 292        struct list_head list;
 293        unsigned char data[];
 294};
 295
 296struct version_info {
 297        u32 ver_major;
 298        u32 ver_minor;
 299        u32 ver_oem;
 300        u32 ver_build;
 301};
 302
 303#define FW_MAX_DELAY                    30
 304#define MVUMI_FW_BUSY                   (1U << 0)
 305#define MVUMI_FW_ATTACH                 (1U << 1)
 306#define MVUMI_FW_ALLOC                  (1U << 2)
 307
 308/*
 309 * State is the state of the MU
 310 */
 311#define FW_STATE_IDLE                   0
 312#define FW_STATE_STARTING               1
 313#define FW_STATE_HANDSHAKING            2
 314#define FW_STATE_STARTED                3
 315#define FW_STATE_ABORT                  4
 316
 317#define HANDSHAKE_SIGNATURE             0x5A5A5A5AL
 318#define HANDSHAKE_READYSTATE            0x55AA5AA5L
 319#define HANDSHAKE_DONESTATE             0x55AAA55AL
 320
 321/* HandShake Status definition */
 322#define HS_STATUS_OK                    1
 323#define HS_STATUS_ERR                   2
 324#define HS_STATUS_INVALID               3
 325
 326/* HandShake State/Cmd definition */
 327#define HS_S_START                      1
 328#define HS_S_RESET                      2
 329#define HS_S_PAGE_ADDR                  3
 330#define HS_S_QUERY_PAGE                 4
 331#define HS_S_SEND_PAGE                  5
 332#define HS_S_END                        6
 333#define HS_S_ABORT                      7
 334#define HS_PAGE_VERIFY_SIZE             128
 335
 336#define HS_GET_STATE(a)                 (a & 0xFFFF)
 337#define HS_GET_STATUS(a)                ((a & 0xFFFF0000) >> 16)
 338#define HS_SET_STATE(a, b)              (a |= (b & 0xFFFF))
 339#define HS_SET_STATUS(a, b)             (a |= ((b & 0xFFFF) << 16))
 340
 341/* handshake frame */
 342struct mvumi_hs_frame {
 343        u16 size;
 344        /* host information */
 345        u8 host_type;
 346        u8 reserved_1[1];
 347        struct version_info host_ver; /* bios or driver version */
 348
 349        /* controller information */
 350        u32 system_io_bus;
 351        u32 slot_number;
 352        u32 intr_level;
 353        u32 intr_vector;
 354
 355        /* communication list configuration */
 356        u32 ib_baseaddr_l;
 357        u32 ib_baseaddr_h;
 358        u32 ob_baseaddr_l;
 359        u32 ob_baseaddr_h;
 360
 361        u8 ib_entry_size;
 362        u8 ob_entry_size;
 363        u8 ob_depth;
 364        u8 ib_depth;
 365
 366        /* system time */
 367        u64 seconds_since1970;
 368};
 369
 370struct mvumi_hs_header {
 371        u8      page_code;
 372        u8      checksum;
 373        u16     frame_length;
 374        u32     frame_content[1];
 375};
 376
 377/*
 378 * the page code type of the handshake header
 379 */
 380#define HS_PAGE_FIRM_CAP        0x1
 381#define HS_PAGE_HOST_INFO       0x2
 382#define HS_PAGE_FIRM_CTL        0x3
 383#define HS_PAGE_CL_INFO         0x4
 384#define HS_PAGE_TOTAL           0x5
 385
 386#define HSP_SIZE(i)     sizeof(struct mvumi_hs_page##i)
 387
 388#define HSP_MAX_SIZE ({                                 \
 389        int size, m1, m2;                               \
 390        m1 = max(HSP_SIZE(1), HSP_SIZE(3));             \
 391        m2 = max(HSP_SIZE(2), HSP_SIZE(4));             \
 392        size = max(m1, m2);                             \
 393        size;                                           \
 394})
 395
 396/* The format of the page code for Firmware capability */
 397struct mvumi_hs_page1 {
 398        u8 pagecode;
 399        u8 checksum;
 400        u16 frame_length;
 401
 402        u16 number_of_ports;
 403        u16 max_devices_support;
 404        u16 max_io_support;
 405        u16 umi_ver;
 406        u32 max_transfer_size;
 407        struct version_info fw_ver;
 408        u8 cl_in_max_entry_size;
 409        u8 cl_out_max_entry_size;
 410        u8 cl_inout_list_depth;
 411        u8 total_pages;
 412        u16 capability;
 413        u16 reserved1;
 414};
 415
 416/* The format of the page code for Host information */
 417struct mvumi_hs_page2 {
 418        u8 pagecode;
 419        u8 checksum;
 420        u16 frame_length;
 421
 422        u8 host_type;
 423        u8 host_cap;
 424        u8 reserved[2];
 425        struct version_info host_ver;
 426        u32 system_io_bus;
 427        u32 slot_number;
 428        u32 intr_level;
 429        u32 intr_vector;
 430        u64 seconds_since1970;
 431};
 432
 433/* The format of the page code for firmware control  */
 434struct mvumi_hs_page3 {
 435        u8      pagecode;
 436        u8      checksum;
 437        u16     frame_length;
 438        u16     control;
 439        u8      reserved[2];
 440        u32     host_bufferaddr_l;
 441        u32     host_bufferaddr_h;
 442        u32     host_eventaddr_l;
 443        u32     host_eventaddr_h;
 444};
 445
 446struct mvumi_hs_page4 {
 447        u8      pagecode;
 448        u8      checksum;
 449        u16     frame_length;
 450        u32     ib_baseaddr_l;
 451        u32     ib_baseaddr_h;
 452        u32     ob_baseaddr_l;
 453        u32     ob_baseaddr_h;
 454        u8      ib_entry_size;
 455        u8      ob_entry_size;
 456        u8      ob_depth;
 457        u8      ib_depth;
 458};
 459
 460struct mvumi_tag {
 461        unsigned short *stack;
 462        unsigned short top;
 463        unsigned short size;
 464};
 465
 466struct mvumi_device {
 467        struct list_head list;
 468        struct scsi_device *sdev;
 469        u64     wwid;
 470        u8      dev_type;
 471        int     id;
 472};
 473
 474struct mvumi_hba {
 475        void *base_addr[MAX_BASE_ADDRESS];
 476        u32 pci_base[MAX_BASE_ADDRESS];
 477        void *mmio;
 478        struct list_head cmd_pool;
 479        struct Scsi_Host *shost;
 480        wait_queue_head_t int_cmd_wait_q;
 481        struct pci_dev *pdev;
 482        unsigned int unique_id;
 483        atomic_t fw_outstanding;
 484        struct mvumi_instance_template *instancet;
 485
 486        void *ib_list;
 487        dma_addr_t ib_list_phys;
 488
 489        void *ib_frame;
 490        dma_addr_t ib_frame_phys;
 491
 492        void *ob_list;
 493        dma_addr_t ob_list_phys;
 494
 495        void *ib_shadow;
 496        dma_addr_t ib_shadow_phys;
 497
 498        void *ob_shadow;
 499        dma_addr_t ob_shadow_phys;
 500
 501        void *handshake_page;
 502        dma_addr_t handshake_page_phys;
 503
 504        unsigned int global_isr;
 505        unsigned int isr_status;
 506
 507        unsigned short max_sge;
 508        unsigned short max_target_id;
 509        unsigned char *target_map;
 510        unsigned int max_io;
 511        unsigned int list_num_io;
 512        unsigned int ib_max_size;
 513        unsigned int ob_max_size;
 514        unsigned int ib_max_size_setting;
 515        unsigned int ob_max_size_setting;
 516        unsigned int max_transfer_size;
 517        unsigned char hba_total_pages;
 518        unsigned char fw_flag;
 519        unsigned char request_id_enabled;
 520        unsigned char eot_flag;
 521        unsigned short hba_capability;
 522        unsigned short io_seq;
 523
 524        unsigned int ib_cur_slot;
 525        unsigned int ob_cur_slot;
 526        unsigned int fw_state;
 527        struct mutex sas_discovery_mutex;
 528
 529        struct list_head ob_data_list;
 530        struct list_head free_ob_list;
 531        struct list_head res_list;
 532        struct list_head waiting_req_list;
 533
 534        struct mvumi_tag tag_pool;
 535        struct mvumi_cmd **tag_cmd;
 536        struct mvumi_hw_regs *regs;
 537        struct mutex device_lock;
 538        struct list_head mhba_dev_list;
 539        struct list_head shost_dev_list;
 540        struct task_struct *dm_thread;
 541        atomic_t pnp_count;
 542};
 543
 544struct mvumi_instance_template {
 545        void (*fire_cmd) (struct mvumi_hba *, struct mvumi_cmd *);
 546        void (*enable_intr) (struct mvumi_hba *);
 547        void (*disable_intr) (struct mvumi_hba *);
 548        int (*clear_intr) (void *);
 549        unsigned int (*read_fw_status_reg) (struct mvumi_hba *);
 550        unsigned int (*check_ib_list) (struct mvumi_hba *);
 551        int (*check_ob_list) (struct mvumi_hba *, unsigned int *,
 552                              unsigned int *);
 553        int (*reset_host) (struct mvumi_hba *);
 554};
 555
 556extern struct timezone sys_tz;
 557#endif
 558