Jianyun Li | f0c568a | 2011-05-11 23:22:44 +0800 | [diff] [blame] | 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 |