567 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * Marvell UMI head file4 *5 * Copyright 2011 Marvell. <jyli@marvell.com>6 */7 8#ifndef MVUMI_H9#define MVUMI_H10 11#define MAX_BASE_ADDRESS 612 13#define VER_MAJOR 114#define VER_MINOR 115#define VER_OEM 016#define VER_BUILD 150017 18#define MV_DRIVER_NAME "mvumi"19#define PCI_DEVICE_ID_MARVELL_MV9143 0x914320#define PCI_DEVICE_ID_MARVELL_MV9580 0x958021 22#define MVUMI_INTERNAL_CMD_WAIT_TIME 4523#define MVUMI_INQUIRY_LENGTH 4424#define MVUMI_INQUIRY_UUID_OFF 3625#define MVUMI_INQUIRY_UUID_LEN 826 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 0xE197#define CDB_CORE_MODULE 0x198#define CDB_CORE_SHUTDOWN 0xB99 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 itself110 */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 0xF4123#define APICDB1_EVENT_GETEVENT 0124#define APICDB1_HOST_GETEVENT 1125#define MAX_EVENTS_RETURNED 6126 127#define DEVICE_OFFLINE 0128#define DEVICE_ONLINE 1129 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 32168#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_MEMORY223};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 0x80245 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 257struct mvumi_cmd_priv {258 struct mvumi_cmd *cmd_priv;259};260 261static inline struct mvumi_cmd_priv *mvumi_priv(struct scsi_cmnd *cmd)262{263 return scsi_cmd_priv(cmd);264}265 266/*267 * the function type of the in bound frame268 */269#define CL_FUN_SCSI_CMD 0x1270 271struct mvumi_msg_frame {272 u16 device_id;273 u16 tag;274 u8 cmd_flag;275 u8 req_function;276 u8 cdb_length;277 u8 sg_counts;278 u32 data_transfer_length;279 u16 request_id;280 u16 reserved1;281 u8 cdb[MAX_COMMAND_SIZE];282 u32 payload[];283};284 285/*286 * the respond flag for data_payload of the out bound frame287 */288#define CL_RSP_FLAG_NODATA 0x0289#define CL_RSP_FLAG_SENSEDATA 0x1290 291struct mvumi_rsp_frame {292 u16 device_id;293 u16 tag;294 u8 req_status;295 u8 rsp_flag; /* Indicates the type of Data_Payload.*/296 u16 request_id;297 u32 payload[];298};299 300struct mvumi_ob_data {301 struct list_head list;302 unsigned char data[];303};304 305struct version_info {306 u32 ver_major;307 u32 ver_minor;308 u32 ver_oem;309 u32 ver_build;310};311 312#define FW_MAX_DELAY 30313#define MVUMI_FW_BUSY (1U << 0)314#define MVUMI_FW_ATTACH (1U << 1)315#define MVUMI_FW_ALLOC (1U << 2)316 317/*318 * State is the state of the MU319 */320#define FW_STATE_IDLE 0321#define FW_STATE_STARTING 1322#define FW_STATE_HANDSHAKING 2323#define FW_STATE_STARTED 3324#define FW_STATE_ABORT 4325 326#define HANDSHAKE_SIGNATURE 0x5A5A5A5AL327#define HANDSHAKE_READYSTATE 0x55AA5AA5L328#define HANDSHAKE_DONESTATE 0x55AAA55AL329 330/* HandShake Status definition */331#define HS_STATUS_OK 1332#define HS_STATUS_ERR 2333#define HS_STATUS_INVALID 3334 335/* HandShake State/Cmd definition */336#define HS_S_START 1337#define HS_S_RESET 2338#define HS_S_PAGE_ADDR 3339#define HS_S_QUERY_PAGE 4340#define HS_S_SEND_PAGE 5341#define HS_S_END 6342#define HS_S_ABORT 7343#define HS_PAGE_VERIFY_SIZE 128344 345#define HS_GET_STATE(a) (a & 0xFFFF)346#define HS_GET_STATUS(a) ((a & 0xFFFF0000) >> 16)347#define HS_SET_STATE(a, b) (a |= (b & 0xFFFF))348#define HS_SET_STATUS(a, b) (a |= ((b & 0xFFFF) << 16))349 350/* handshake frame */351struct mvumi_hs_frame {352 u16 size;353 /* host information */354 u8 host_type;355 u8 reserved_1[1];356 struct version_info host_ver; /* bios or driver version */357 358 /* controller information */359 u32 system_io_bus;360 u32 slot_number;361 u32 intr_level;362 u32 intr_vector;363 364 /* communication list configuration */365 u32 ib_baseaddr_l;366 u32 ib_baseaddr_h;367 u32 ob_baseaddr_l;368 u32 ob_baseaddr_h;369 370 u8 ib_entry_size;371 u8 ob_entry_size;372 u8 ob_depth;373 u8 ib_depth;374 375 /* system time */376 u64 seconds_since1970;377};378 379struct mvumi_hs_header {380 u8 page_code;381 u8 checksum;382 u16 frame_length;383 u32 frame_content[];384};385 386/*387 * the page code type of the handshake header388 */389#define HS_PAGE_FIRM_CAP 0x1390#define HS_PAGE_HOST_INFO 0x2391#define HS_PAGE_FIRM_CTL 0x3392#define HS_PAGE_CL_INFO 0x4393#define HS_PAGE_TOTAL 0x5394 395#define HSP_SIZE(i) sizeof(struct mvumi_hs_page##i)396 397#define HSP_MAX_SIZE ({ \398 int size, m1, m2; \399 m1 = max(HSP_SIZE(1), HSP_SIZE(3)); \400 m2 = max(HSP_SIZE(2), HSP_SIZE(4)); \401 size = max(m1, m2); \402 size; \403})404 405/* The format of the page code for Firmware capability */406struct mvumi_hs_page1 {407 u8 pagecode;408 u8 checksum;409 u16 frame_length;410 411 u16 number_of_ports;412 u16 max_devices_support;413 u16 max_io_support;414 u16 umi_ver;415 u32 max_transfer_size;416 struct version_info fw_ver;417 u8 cl_in_max_entry_size;418 u8 cl_out_max_entry_size;419 u8 cl_inout_list_depth;420 u8 total_pages;421 u16 capability;422 u16 reserved1;423};424 425/* The format of the page code for Host information */426struct mvumi_hs_page2 {427 u8 pagecode;428 u8 checksum;429 u16 frame_length;430 431 u8 host_type;432 u8 host_cap;433 u8 reserved[2];434 struct version_info host_ver;435 u32 system_io_bus;436 u32 slot_number;437 u32 intr_level;438 u32 intr_vector;439 u64 seconds_since1970;440};441 442/* The format of the page code for firmware control */443struct mvumi_hs_page3 {444 u8 pagecode;445 u8 checksum;446 u16 frame_length;447 u16 control;448 u8 reserved[2];449 u32 host_bufferaddr_l;450 u32 host_bufferaddr_h;451 u32 host_eventaddr_l;452 u32 host_eventaddr_h;453};454 455struct mvumi_hs_page4 {456 u8 pagecode;457 u8 checksum;458 u16 frame_length;459 u32 ib_baseaddr_l;460 u32 ib_baseaddr_h;461 u32 ob_baseaddr_l;462 u32 ob_baseaddr_h;463 u8 ib_entry_size;464 u8 ob_entry_size;465 u8 ob_depth;466 u8 ib_depth;467};468 469struct mvumi_tag {470 unsigned short *stack;471 unsigned short top;472 unsigned short size;473};474 475struct mvumi_device {476 struct list_head list;477 struct scsi_device *sdev;478 u64 wwid;479 u8 dev_type;480 int id;481};482 483struct mvumi_hba {484 void *base_addr[MAX_BASE_ADDRESS];485 u32 pci_base[MAX_BASE_ADDRESS];486 void *mmio;487 struct list_head cmd_pool;488 struct Scsi_Host *shost;489 wait_queue_head_t int_cmd_wait_q;490 struct pci_dev *pdev;491 unsigned int unique_id;492 atomic_t fw_outstanding;493 struct mvumi_instance_template *instancet;494 495 void *ib_list;496 dma_addr_t ib_list_phys;497 498 void *ib_frame;499 dma_addr_t ib_frame_phys;500 501 void *ob_list;502 dma_addr_t ob_list_phys;503 504 void *ib_shadow;505 dma_addr_t ib_shadow_phys;506 507 void *ob_shadow;508 dma_addr_t ob_shadow_phys;509 510 void *handshake_page;511 dma_addr_t handshake_page_phys;512 513 unsigned int global_isr;514 unsigned int isr_status;515 516 unsigned short max_sge;517 unsigned short max_target_id;518 unsigned char *target_map;519 unsigned int max_io;520 unsigned int list_num_io;521 unsigned int ib_max_size;522 unsigned int ob_max_size;523 unsigned int ib_max_size_setting;524 unsigned int ob_max_size_setting;525 unsigned int max_transfer_size;526 unsigned char hba_total_pages;527 unsigned char fw_flag;528 unsigned char request_id_enabled;529 unsigned char eot_flag;530 unsigned short hba_capability;531 unsigned short io_seq;532 533 unsigned int ib_cur_slot;534 unsigned int ob_cur_slot;535 unsigned int fw_state;536 struct mutex sas_discovery_mutex;537 538 struct list_head ob_data_list;539 struct list_head free_ob_list;540 struct list_head res_list;541 struct list_head waiting_req_list;542 543 struct mvumi_tag tag_pool;544 struct mvumi_cmd **tag_cmd;545 struct mvumi_hw_regs *regs;546 struct mutex device_lock;547 struct list_head mhba_dev_list;548 struct list_head shost_dev_list;549 struct task_struct *dm_thread;550 atomic_t pnp_count;551};552 553struct mvumi_instance_template {554 void (*fire_cmd) (struct mvumi_hba *, struct mvumi_cmd *);555 void (*enable_intr) (struct mvumi_hba *);556 void (*disable_intr) (struct mvumi_hba *);557 int (*clear_intr) (void *);558 unsigned int (*read_fw_status_reg) (struct mvumi_hba *);559 unsigned int (*check_ib_list) (struct mvumi_hba *);560 int (*check_ob_list) (struct mvumi_hba *, unsigned int *,561 unsigned int *);562 int (*reset_host) (struct mvumi_hba *);563};564 565extern struct timezone sys_tz;566#endif567