blob: 10b9237566f0c1cbd2805fd27f58c52b7de7c819 [file] [log] [blame]
Jianyun Lif0c568a2011-05-11 23:22:44 +08001/*
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
42enum mvumi_qc_result {
43 MV_QUEUE_COMMAND_RESULT_SENT = 0,
44 MV_QUEUE_COMMAND_RESULT_NO_RESOURCE,
45};
46
47enum {
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
149struct 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
162struct mvumi_event_req {
163 unsigned char count;
164 unsigned char reserved[3];
165 struct mvumi_driver_event events[MAX_EVENTS_RETURNED];
166};
167
168struct 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
178struct mvumi_sgl {
179 u32 baseaddr_l;
180 u32 baseaddr_h;
181 u32 flags;
182 u32 size;
183};
184
185struct 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 */
194enum resource_type {
195 RESOURCE_CACHED_MEMORY = 0,
196 RESOURCE_UNCACHED_MEMORY
197};
198
199struct 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
220struct 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
235struct 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
255struct 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
264struct mvumi_ob_data {
265 struct list_head list;
266 unsigned char data[0];
267};
268
269struct 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 */
315struct 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
343struct 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 */
370struct 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 */
390struct 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 */
406struct 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
418struct 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
432struct mvumi_tag {
433 unsigned short *stack;
434 unsigned short top;
435 unsigned short size;
436};
437
438struct 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
496struct 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
504extern struct timezone sys_tz;
505#endif