1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * Marvell UMI head file
5 * Copyright 2011 Marvell. <jyli@marvell.com>
11 #define MAX_BASE_ADDRESS 6
16 #define VER_BUILD 1500
18 #define MV_DRIVER_NAME "mvumi"
19 #define PCI_DEVICE_ID_MARVELL_MV9143 0x9143
20 #define PCI_DEVICE_ID_MARVELL_MV9580 0x9580
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
27 #define IS_DMA64 (sizeof(dma_addr_t) == 8)
29 enum mvumi_qc_result {
30 MV_QUEUE_COMMAND_RESULT_SENT = 0,
31 MV_QUEUE_COMMAND_RESULT_NO_RESOURCE,
34 struct mvumi_hw_regs {
36 void *main_int_cause_reg;
37 void *enpointa_mask_reg;
38 void *enpointb_mask_reg;
41 void *rstoutn_mask_reg;
42 void *sys_soft_rst_reg;
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;
57 /* For Message Unit */
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;
73 void *outb_coal_timeout;
75 /* Bit setting for HW */
80 u32 int_drbl_int_mask;
81 u32 int_main_int_mask;
82 u32 cl_pointer_toggle;
89 struct mvumi_dyn_list_entry {
96 #define SCSI_CMD_MARVELL_SPECIFIC 0xE1
97 #define CDB_CORE_MODULE 0x1
98 #define CDB_CORE_SHUTDOWN 0xB
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,
109 * Command flag is the flag for the CDB command itself
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,
122 #define APICDB0_EVENT 0xF4
123 #define APICDB1_EVENT_GETEVENT 0
124 #define APICDB1_HOST_GETEVENT 1
125 #define MAX_EVENTS_RETURNED 6
127 #define DEVICE_OFFLINE 0
128 #define DEVICE_ONLINE 1
130 struct mvumi_hotplug_event {
136 struct mvumi_driver_event {
144 u8 sense_data_length;
149 struct mvumi_event_req {
151 unsigned char reserved[3];
152 struct mvumi_driver_event events[MAX_EVENTS_RETURNED];
155 struct mvumi_events_wq {
156 struct work_struct work_q;
157 struct mvumi_hba *mhba;
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)
167 #define MVUMI_MAX_SG_ENTRY 32
168 #define SGD_EOT (1L << 27)
169 #define SGD_EOT_CP (1L << 22)
177 struct mvumi_compact_sgl {
183 #define GET_COMPACT_SGD_SIZE(sgd) \
184 ((((struct mvumi_compact_sgl *)(sgd))->flags) & 0x3FFFFFL)
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); \
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); \
194 (sz) = (sgd)->size; \
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); \
201 (sgd)->size = (sz); \
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); \
208 sgd = (struct mvumi_sgl *)(((unsigned char *) (sgd)) + 16); \
212 struct list_head entry;
216 unsigned short type; /* enum Resource_Type */
221 RESOURCE_CACHED_MEMORY = 0,
222 RESOURCE_UNCACHED_MEMORY
225 struct mvumi_sense_data {
231 u8 incorrect_length:1;
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];
243 /* Request initiator must set the status to REQ_STATUS_PENDING. */
244 #define REQ_STATUS_PENDING 0x80
247 struct list_head queue_pointer;
248 struct mvumi_msg_frame *frame;
249 dma_addr_t frame_phys;
250 struct scsi_cmnd *scmd;
253 unsigned short request_id;
254 unsigned char cmd_status;
257 struct mvumi_cmd_priv {
258 struct mvumi_cmd *cmd_priv;
261 static inline struct mvumi_cmd_priv *mvumi_priv(struct scsi_cmnd *cmd)
263 return scsi_cmd_priv(cmd);
267 * the function type of the in bound frame
269 #define CL_FUN_SCSI_CMD 0x1
271 struct mvumi_msg_frame {
278 u32 data_transfer_length;
281 u8 cdb[MAX_COMMAND_SIZE];
286 * the respond flag for data_payload of the out bound frame
288 #define CL_RSP_FLAG_NODATA 0x0
289 #define CL_RSP_FLAG_SENSEDATA 0x1
291 struct mvumi_rsp_frame {
295 u8 rsp_flag; /* Indicates the type of Data_Payload.*/
300 struct mvumi_ob_data {
301 struct list_head list;
302 unsigned char data[];
305 struct version_info {
312 #define FW_MAX_DELAY 30
313 #define MVUMI_FW_BUSY (1U << 0)
314 #define MVUMI_FW_ATTACH (1U << 1)
315 #define MVUMI_FW_ALLOC (1U << 2)
318 * State is the state of the MU
320 #define FW_STATE_IDLE 0
321 #define FW_STATE_STARTING 1
322 #define FW_STATE_HANDSHAKING 2
323 #define FW_STATE_STARTED 3
324 #define FW_STATE_ABORT 4
326 #define HANDSHAKE_SIGNATURE 0x5A5A5A5AL
327 #define HANDSHAKE_READYSTATE 0x55AA5AA5L
328 #define HANDSHAKE_DONESTATE 0x55AAA55AL
330 /* HandShake Status definition */
331 #define HS_STATUS_OK 1
332 #define HS_STATUS_ERR 2
333 #define HS_STATUS_INVALID 3
335 /* HandShake State/Cmd definition */
338 #define HS_S_PAGE_ADDR 3
339 #define HS_S_QUERY_PAGE 4
340 #define HS_S_SEND_PAGE 5
343 #define HS_PAGE_VERIFY_SIZE 128
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))
350 /* handshake frame */
351 struct mvumi_hs_frame {
353 /* host information */
356 struct version_info host_ver; /* bios or driver version */
358 /* controller information */
364 /* communication list configuration */
376 u64 seconds_since1970;
379 struct mvumi_hs_header {
383 u32 frame_content[1];
387 * the page code type of the handshake header
389 #define HS_PAGE_FIRM_CAP 0x1
390 #define HS_PAGE_HOST_INFO 0x2
391 #define HS_PAGE_FIRM_CTL 0x3
392 #define HS_PAGE_CL_INFO 0x4
393 #define HS_PAGE_TOTAL 0x5
395 #define HSP_SIZE(i) sizeof(struct mvumi_hs_page##i)
397 #define HSP_MAX_SIZE ({ \
399 m1 = max(HSP_SIZE(1), HSP_SIZE(3)); \
400 m2 = max(HSP_SIZE(2), HSP_SIZE(4)); \
401 size = max(m1, m2); \
405 /* The format of the page code for Firmware capability */
406 struct mvumi_hs_page1 {
412 u16 max_devices_support;
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;
425 /* The format of the page code for Host information */
426 struct mvumi_hs_page2 {
434 struct version_info host_ver;
439 u64 seconds_since1970;
442 /* The format of the page code for firmware control */
443 struct mvumi_hs_page3 {
449 u32 host_bufferaddr_l;
450 u32 host_bufferaddr_h;
451 u32 host_eventaddr_l;
452 u32 host_eventaddr_h;
455 struct mvumi_hs_page4 {
470 unsigned short *stack;
475 struct mvumi_device {
476 struct list_head list;
477 struct scsi_device *sdev;
484 void *base_addr[MAX_BASE_ADDRESS];
485 u32 pci_base[MAX_BASE_ADDRESS];
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;
496 dma_addr_t ib_list_phys;
499 dma_addr_t ib_frame_phys;
502 dma_addr_t ob_list_phys;
505 dma_addr_t ib_shadow_phys;
508 dma_addr_t ob_shadow_phys;
510 void *handshake_page;
511 dma_addr_t handshake_page_phys;
513 unsigned int global_isr;
514 unsigned int isr_status;
516 unsigned short max_sge;
517 unsigned short max_target_id;
518 unsigned char *target_map;
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;
533 unsigned int ib_cur_slot;
534 unsigned int ob_cur_slot;
535 unsigned int fw_state;
536 struct mutex sas_discovery_mutex;
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;
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;
553 struct 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 *,
562 int (*reset_host) (struct mvumi_hba *);
565 extern struct timezone sys_tz;