1 /* 2 * Marvell UMI head file 3 * 4 * Copyright 2011 Marvell. <jyli@marvell.com> 5 * 6 * This file is licensed under GPLv2. 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; version 2 of the 11 * License. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 21 * USA 22 */ 23 24 #ifndef MVUMI_H 25 #define MVUMI_H 26 27 #define MAX_BASE_ADDRESS 6 28 29 #define VER_MAJOR 1 30 #define VER_MINOR 1 31 #define VER_OEM 0 32 #define VER_BUILD 1500 33 34 #define MV_DRIVER_NAME "mvumi" 35 #define PCI_VENDOR_ID_MARVELL_2 0x1b4b 36 #define PCI_DEVICE_ID_MARVELL_MV9143 0x9143 37 38 #define MVUMI_INTERNAL_CMD_WAIT_TIME 45 39 40 #define IS_DMA64 (sizeof(dma_addr_t) == 8) 41 42 enum mvumi_qc_result { 43 MV_QUEUE_COMMAND_RESULT_SENT = 0, 44 MV_QUEUE_COMMAND_RESULT_NO_RESOURCE, 45 }; 46 47 enum { 48 /*******************************************/ 49 50 /* ARM Mbus Registers Map */ 51 52 /*******************************************/ 53 CPU_MAIN_INT_CAUSE_REG = 0x20200, 54 CPU_MAIN_IRQ_MASK_REG = 0x20204, 55 CPU_MAIN_FIQ_MASK_REG = 0x20208, 56 CPU_ENPOINTA_MASK_REG = 0x2020C, 57 CPU_ENPOINTB_MASK_REG = 0x20210, 58 59 INT_MAP_COMAERR = 1 << 6, 60 INT_MAP_COMAIN = 1 << 7, 61 INT_MAP_COMAOUT = 1 << 8, 62 INT_MAP_COMBERR = 1 << 9, 63 INT_MAP_COMBIN = 1 << 10, 64 INT_MAP_COMBOUT = 1 << 11, 65 66 INT_MAP_COMAINT = (INT_MAP_COMAOUT | INT_MAP_COMAERR), 67 INT_MAP_COMBINT = (INT_MAP_COMBOUT | INT_MAP_COMBIN | INT_MAP_COMBERR), 68 69 INT_MAP_DL_PCIEA2CPU = 1 << 0, 70 INT_MAP_DL_CPU2PCIEA = 1 << 1, 71 72 /***************************************/ 73 74 /* ARM Doorbell Registers Map */ 75 76 /***************************************/ 77 CPU_PCIEA_TO_ARM_DRBL_REG = 0x20400, 78 CPU_PCIEA_TO_ARM_MASK_REG = 0x20404, 79 CPU_ARM_TO_PCIEA_DRBL_REG = 0x20408, 80 CPU_ARM_TO_PCIEA_MASK_REG = 0x2040C, 81 82 DRBL_HANDSHAKE = 1 << 0, 83 DRBL_SOFT_RESET = 1 << 1, 84 DRBL_BUS_CHANGE = 1 << 2, 85 DRBL_EVENT_NOTIFY = 1 << 3, 86 DRBL_MU_RESET = 1 << 4, 87 DRBL_HANDSHAKE_ISR = DRBL_HANDSHAKE, 88 89 CPU_PCIEA_TO_ARM_MSG0 = 0x20430, 90 CPU_PCIEA_TO_ARM_MSG1 = 0x20434, 91 CPU_ARM_TO_PCIEA_MSG0 = 0x20438, 92 CPU_ARM_TO_PCIEA_MSG1 = 0x2043C, 93 94 /*******************************************/ 95 96 /* ARM Communication List Registers Map */ 97 98 /*******************************************/ 99 CLA_INB_LIST_BASEL = 0x500, 100 CLA_INB_LIST_BASEH = 0x504, 101 CLA_INB_AVAL_COUNT_BASEL = 0x508, 102 CLA_INB_AVAL_COUNT_BASEH = 0x50C, 103 CLA_INB_DESTI_LIST_BASEL = 0x510, 104 CLA_INB_DESTI_LIST_BASEH = 0x514, 105 CLA_INB_WRITE_POINTER = 0x518, 106 CLA_INB_READ_POINTER = 0x51C, 107 108 CLA_OUTB_LIST_BASEL = 0x530, 109 CLA_OUTB_LIST_BASEH = 0x534, 110 CLA_OUTB_SOURCE_LIST_BASEL = 0x538, 111 CLA_OUTB_SOURCE_LIST_BASEH = 0x53C, 112 CLA_OUTB_COPY_POINTER = 0x544, 113 CLA_OUTB_READ_POINTER = 0x548, 114 115 CLA_ISR_CAUSE = 0x560, 116 CLA_ISR_MASK = 0x564, 117 118 INT_MAP_MU = (INT_MAP_DL_CPU2PCIEA | INT_MAP_COMAINT), 119 120 CL_POINTER_TOGGLE = 1 << 12, 121 122 CLIC_IN_IRQ = 1 << 0, 123 CLIC_OUT_IRQ = 1 << 1, 124 CLIC_IN_ERR_IRQ = 1 << 8, 125 CLIC_OUT_ERR_IRQ = 1 << 12, 126 127 CL_SLOT_NUM_MASK = 0xFFF, 128 129 /* 130 * Command flag is the flag for the CDB command itself 131 */ 132 /* 1-non data; 0-data command */ 133 CMD_FLAG_NON_DATA = 1 << 0, 134 CMD_FLAG_DMA = 1 << 1, 135 CMD_FLAG_PIO = 1 << 2, 136 /* 1-host read data */ 137 CMD_FLAG_DATA_IN = 1 << 3, 138 /* 1-host write data */ 139 CMD_FLAG_DATA_OUT = 1 << 4, 140 141 SCSI_CMD_MARVELL_SPECIFIC = 0xE1, 142 CDB_CORE_SHUTDOWN = 0xB, 143 }; 144 145 #define APICDB0_EVENT 0xF4 146 #define APICDB1_EVENT_GETEVENT 0 147 #define MAX_EVENTS_RETURNED 6 148 149 struct mvumi_driver_event { 150 u32 time_stamp; 151 u32 sequence_no; 152 u32 event_id; 153 u8 severity; 154 u8 param_count; 155 u16 device_id; 156 u32 params[4]; 157 u8 sense_data_length; 158 u8 Reserved1; 159 u8 sense_data[30]; 160 }; 161 162 struct mvumi_event_req { 163 unsigned char count; 164 unsigned char reserved[3]; 165 struct mvumi_driver_event events[MAX_EVENTS_RETURNED]; 166 }; 167 168 struct mvumi_events_wq { 169 struct work_struct work_q; 170 struct mvumi_hba *mhba; 171 unsigned int event; 172 void *param; 173 }; 174 175 #define MVUMI_MAX_SG_ENTRY 32 176 #define SGD_EOT (1L << 27) 177 178 struct mvumi_sgl { 179 u32 baseaddr_l; 180 u32 baseaddr_h; 181 u32 flags; 182 u32 size; 183 }; 184 185 struct mvumi_res { 186 struct list_head entry; 187 dma_addr_t bus_addr; 188 void *virt_addr; 189 unsigned int size; 190 unsigned short type; /* enum Resource_Type */ 191 }; 192 193 /* Resource type */ 194 enum resource_type { 195 RESOURCE_CACHED_MEMORY = 0, 196 RESOURCE_UNCACHED_MEMORY 197 }; 198 199 struct mvumi_sense_data { 200 u8 error_eode:7; 201 u8 valid:1; 202 u8 segment_number; 203 u8 sense_key:4; 204 u8 reserved:1; 205 u8 incorrect_length:1; 206 u8 end_of_media:1; 207 u8 file_mark:1; 208 u8 information[4]; 209 u8 additional_sense_length; 210 u8 command_specific_information[4]; 211 u8 additional_sense_code; 212 u8 additional_sense_code_qualifier; 213 u8 field_replaceable_unit_code; 214 u8 sense_key_specific[3]; 215 }; 216 217 /* Request initiator must set the status to REQ_STATUS_PENDING. */ 218 #define REQ_STATUS_PENDING 0x80 219 220 struct mvumi_cmd { 221 struct list_head queue_pointer; 222 struct mvumi_msg_frame *frame; 223 struct scsi_cmnd *scmd; 224 atomic_t sync_cmd; 225 void *data_buf; 226 unsigned short request_id; 227 unsigned char cmd_status; 228 }; 229 230 /* 231 * the function type of the in bound frame 232 */ 233 #define CL_FUN_SCSI_CMD 0x1 234 235 struct mvumi_msg_frame { 236 u16 device_id; 237 u16 tag; 238 u8 cmd_flag; 239 u8 req_function; 240 u8 cdb_length; 241 u8 sg_counts; 242 u32 data_transfer_length; 243 u16 request_id; 244 u16 reserved1; 245 u8 cdb[MAX_COMMAND_SIZE]; 246 u32 payload[1]; 247 }; 248 249 /* 250 * the respond flag for data_payload of the out bound frame 251 */ 252 #define CL_RSP_FLAG_NODATA 0x0 253 #define CL_RSP_FLAG_SENSEDATA 0x1 254 255 struct mvumi_rsp_frame { 256 u16 device_id; 257 u16 tag; 258 u8 req_status; 259 u8 rsp_flag; /* Indicates the type of Data_Payload.*/ 260 u16 request_id; 261 u32 payload[1]; 262 }; 263 264 struct mvumi_ob_data { 265 struct list_head list; 266 unsigned char data[0]; 267 }; 268 269 struct version_info { 270 u32 ver_major; 271 u32 ver_minor; 272 u32 ver_oem; 273 u32 ver_build; 274 }; 275 276 #define FW_MAX_DELAY 30 277 #define MVUMI_FW_BUSY (1U << 0) 278 #define MVUMI_FW_ATTACH (1U << 1) 279 #define MVUMI_FW_ALLOC (1U << 2) 280 281 /* 282 * State is the state of the MU 283 */ 284 #define FW_STATE_IDLE 0 285 #define FW_STATE_STARTING 1 286 #define FW_STATE_HANDSHAKING 2 287 #define FW_STATE_STARTED 3 288 #define FW_STATE_ABORT 4 289 290 #define HANDSHAKE_SIGNATURE 0x5A5A5A5AL 291 #define HANDSHAKE_READYSTATE 0x55AA5AA5L 292 #define HANDSHAKE_DONESTATE 0x55AAA55AL 293 294 /* HandShake Status definition */ 295 #define HS_STATUS_OK 1 296 #define HS_STATUS_ERR 2 297 #define HS_STATUS_INVALID 3 298 299 /* HandShake State/Cmd definition */ 300 #define HS_S_START 1 301 #define HS_S_RESET 2 302 #define HS_S_PAGE_ADDR 3 303 #define HS_S_QUERY_PAGE 4 304 #define HS_S_SEND_PAGE 5 305 #define HS_S_END 6 306 #define HS_S_ABORT 7 307 #define HS_PAGE_VERIFY_SIZE 128 308 309 #define HS_GET_STATE(a) (a & 0xFFFF) 310 #define HS_GET_STATUS(a) ((a & 0xFFFF0000) >> 16) 311 #define HS_SET_STATE(a, b) (a |= (b & 0xFFFF)) 312 #define HS_SET_STATUS(a, b) (a |= ((b & 0xFFFF) << 16)) 313 314 /* handshake frame */ 315 struct mvumi_hs_frame { 316 u16 size; 317 /* host information */ 318 u8 host_type; 319 u8 reserved_1[1]; 320 struct version_info host_ver; /* bios or driver version */ 321 322 /* controller information */ 323 u32 system_io_bus; 324 u32 slot_number; 325 u32 intr_level; 326 u32 intr_vector; 327 328 /* communication list configuration */ 329 u32 ib_baseaddr_l; 330 u32 ib_baseaddr_h; 331 u32 ob_baseaddr_l; 332 u32 ob_baseaddr_h; 333 334 u8 ib_entry_size; 335 u8 ob_entry_size; 336 u8 ob_depth; 337 u8 ib_depth; 338 339 /* system time */ 340 u64 seconds_since1970; 341 }; 342 343 struct mvumi_hs_header { 344 u8 page_code; 345 u8 checksum; 346 u16 frame_length; 347 u32 frame_content[1]; 348 }; 349 350 /* 351 * the page code type of the handshake header 352 */ 353 #define HS_PAGE_FIRM_CAP 0x1 354 #define HS_PAGE_HOST_INFO 0x2 355 #define HS_PAGE_FIRM_CTL 0x3 356 #define HS_PAGE_CL_INFO 0x4 357 #define HS_PAGE_TOTAL 0x5 358 359 #define HSP_SIZE(i) sizeof(struct mvumi_hs_page##i) 360 361 #define HSP_MAX_SIZE ({ \ 362 int size, m1, m2; \ 363 m1 = max(HSP_SIZE(1), HSP_SIZE(3)); \ 364 m2 = max(HSP_SIZE(2), HSP_SIZE(4)); \ 365 size = max(m1, m2); \ 366 size; \ 367 }) 368 369 /* The format of the page code for Firmware capability */ 370 struct mvumi_hs_page1 { 371 u8 pagecode; 372 u8 checksum; 373 u16 frame_length; 374 375 u16 number_of_ports; 376 u16 max_devices_support; 377 u16 max_io_support; 378 u16 umi_ver; 379 u32 max_transfer_size; 380 struct version_info fw_ver; 381 u8 cl_in_max_entry_size; 382 u8 cl_out_max_entry_size; 383 u8 cl_inout_list_depth; 384 u8 total_pages; 385 u16 capability; 386 u16 reserved1; 387 }; 388 389 /* The format of the page code for Host information */ 390 struct mvumi_hs_page2 { 391 u8 pagecode; 392 u8 checksum; 393 u16 frame_length; 394 395 u8 host_type; 396 u8 reserved[3]; 397 struct version_info host_ver; 398 u32 system_io_bus; 399 u32 slot_number; 400 u32 intr_level; 401 u32 intr_vector; 402 u64 seconds_since1970; 403 }; 404 405 /* The format of the page code for firmware control */ 406 struct mvumi_hs_page3 { 407 u8 pagecode; 408 u8 checksum; 409 u16 frame_length; 410 u16 control; 411 u8 reserved[2]; 412 u32 host_bufferaddr_l; 413 u32 host_bufferaddr_h; 414 u32 host_eventaddr_l; 415 u32 host_eventaddr_h; 416 }; 417 418 struct mvumi_hs_page4 { 419 u8 pagecode; 420 u8 checksum; 421 u16 frame_length; 422 u32 ib_baseaddr_l; 423 u32 ib_baseaddr_h; 424 u32 ob_baseaddr_l; 425 u32 ob_baseaddr_h; 426 u8 ib_entry_size; 427 u8 ob_entry_size; 428 u8 ob_depth; 429 u8 ib_depth; 430 }; 431 432 struct mvumi_tag { 433 unsigned short *stack; 434 unsigned short top; 435 unsigned short size; 436 }; 437 438 struct mvumi_hba { 439 void *base_addr[MAX_BASE_ADDRESS]; 440 void *mmio; 441 struct list_head cmd_pool; 442 struct Scsi_Host *shost; 443 wait_queue_head_t int_cmd_wait_q; 444 struct pci_dev *pdev; 445 unsigned int unique_id; 446 atomic_t fw_outstanding; 447 struct mvumi_instance_template *instancet; 448 449 void *ib_list; 450 dma_addr_t ib_list_phys; 451 452 void *ob_list; 453 dma_addr_t ob_list_phys; 454 455 void *ib_shadow; 456 dma_addr_t ib_shadow_phys; 457 458 void *ob_shadow; 459 dma_addr_t ob_shadow_phys; 460 461 void *handshake_page; 462 dma_addr_t handshake_page_phys; 463 464 unsigned int global_isr; 465 unsigned int isr_status; 466 467 unsigned short max_sge; 468 unsigned short max_target_id; 469 unsigned char *target_map; 470 unsigned int max_io; 471 unsigned int list_num_io; 472 unsigned int ib_max_size; 473 unsigned int ob_max_size; 474 unsigned int ib_max_size_setting; 475 unsigned int ob_max_size_setting; 476 unsigned int max_transfer_size; 477 unsigned char hba_total_pages; 478 unsigned char fw_flag; 479 unsigned char request_id_enabled; 480 unsigned short hba_capability; 481 unsigned short io_seq; 482 483 unsigned int ib_cur_slot; 484 unsigned int ob_cur_slot; 485 unsigned int fw_state; 486 487 struct list_head ob_data_list; 488 struct list_head free_ob_list; 489 struct list_head res_list; 490 struct list_head waiting_req_list; 491 492 struct mvumi_tag tag_pool; 493 struct mvumi_cmd **tag_cmd; 494 }; 495 496 struct mvumi_instance_template { 497 void (*fire_cmd)(struct mvumi_hba *, struct mvumi_cmd *); 498 void (*enable_intr)(void *) ; 499 void (*disable_intr)(void *); 500 int (*clear_intr)(void *); 501 unsigned int (*read_fw_status_reg)(void *); 502 }; 503 504 extern struct timezone sys_tz; 505 #endif 506