1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 2010, LSI Corp.
5 * All rights reserved.
6 * Author : Manjunath Ranganathaiah
7 * Support: freebsdraid@lsi.com
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in
17 *    the documentation and/or other materials provided with the
18 *    distribution.
19 * 3. Neither the name of the <ORGANIZATION> nor the names of its
20 *    contributors may be used to endorse or promote products derived
21 *    from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 *
36 * $FreeBSD$
37 */
38
39/* bit's defination */
40
41#define TWS_BIT0                              0x00000001
42#define TWS_BIT1                              0x00000002
43#define TWS_BIT2                              0x00000004
44#define TWS_BIT3                              0x00000008
45#define TWS_BIT4                              0x00000010
46#define TWS_BIT5                              0x00000020
47#define TWS_BIT6                              0x00000040
48#define TWS_BIT7                              0x00000080
49#define TWS_BIT8                              0x00000100
50#define TWS_BIT9                              0x00000200
51#define TWS_BIT10                             0x00000400
52#define TWS_BIT11                             0x00000800
53#define TWS_BIT12                             0x00001000
54#define TWS_BIT13                             0x00002000
55#define TWS_BIT14                             0x00004000
56#define TWS_BIT15                             0x00008000
57#define TWS_BIT16                             0x00010000
58#define TWS_BIT17                             0x00020000
59#define TWS_BIT18                             0x00040000
60#define TWS_BIT19                             0x00080000
61#define TWS_BIT20                             0x00100000
62#define TWS_BIT21                             0x00200000
63#define TWS_BIT22                             0x00400000
64#define TWS_BIT23                             0x00800000
65#define TWS_BIT24                             0x01000000
66#define TWS_BIT25                             0x02000000
67#define TWS_BIT26                             0x04000000
68#define TWS_BIT27                             0x08000000
69#define TWS_BIT28                             0x10000000
70#define TWS_BIT29                             0x20000000
71#define TWS_BIT30                             0x40000000
72#define TWS_BIT31                             0x80000000
73
74#define TWS_SENSE_DATA_LENGTH                 18
75#define TWS_ERROR_SPECIFIC_DESC_LEN           98
76
77/* response codes */
78#define TWS_SENSE_SCSI_CURRENT_ERROR          0x70
79#define TWS_SENSE_SCSI_DEFERRED_ERROR         0x71
80
81#define TWS_SRC_CTRL_ERROR                    3
82#define TWS_SRC_CTRL_EVENT                    4
83#define TWS_SRC_FREEBSD_DRIVER                5
84#define TWS_SRC_FREEBSD_OS                    8
85
86enum tws_sense_severity {
87    error = 1,
88    warning ,
89    info,
90    debug,
91};
92
93/*
94 * Some errors of interest (in cmd_hdr->status_block.error) when a command
95 * is completed by the firmware with an error.
96 */
97#define TWS_ERROR_LOGICAL_UNIT_NOT_SUPPORTED    0x010a
98#define TWS_ERROR_NOT_SUPPORTED                 0x010D
99#define TWS_ERROR_UNIT_OFFLINE                  0x0128
100#define TWS_ERROR_MORE_DATA                     0x0231
101
102/* AEN codes of interest. */
103#define TWS_AEN_QUEUE_EMPTY                     0x00
104#define TWS_AEN_SOFT_RESET                      0x01
105#define TWS_AEN_SYNC_TIME_WITH_HOST             0x31
106
107/* AEN severity */
108#define TWS_SEVERITY_ERROR                      0x1
109#define TWS_SEVERITY_WARNING                    0x2
110#define TWS_SEVERITY_INFO                       0x3
111#define TWS_SEVERITY_DEBUG                      0x4
112
113#define TWS_64BIT_SG_ADDRESSES                  0x00000001
114#define TWS_BIT_EXTEND                          0x00000002
115
116#define TWS_BASE_FW_SRL                         24
117#define TWS_BASE_FW_BRANCH                      0
118#define TWS_BASE_FW_BUILD                       1
119#define TWS_CURRENT_FW_SRL                      41
120
121#define TWS_CURRENT_FW_BRANCH                   8
122#define TWS_CURRENT_FW_BUILD                    4
123#define TWS_CURRENT_ARCH_ID                     0x000A
124
125#define TWS_FIFO_EMPTY                          0xFFFFFFFFFFFFFFFFull
126#define TWS_FIFO_EMPTY32                        0xFFFFFFFFull
127
128/* Register offsets from base address. */
129#define TWS_CONTROL_REGISTER_OFFSET             0x0
130#define TWS_STATUS_REGISTER_OFFSET              0x4
131#define TWS_COMMAND_QUEUE_OFFSET                0x8
132#define TWS_RESPONSE_QUEUE_OFFSET               0xC
133#define TWS_COMMAND_QUEUE_OFFSET_LOW            0x20
134#define TWS_COMMAND_QUEUE_OFFSET_HIGH           0x24
135#define TWS_LARGE_RESPONSE_QUEUE_OFFSET         0x30
136
137/* I2O offsets */
138#define TWS_I2O0_STATUS                         0x0
139
140#define TWS_I2O0_HIBDB                          0x20
141
142#define TWS_I2O0_HISTAT                         0x30
143#define TWS_I2O0_HIMASK                         0x34
144
145#define TWS_I2O0_HIBQP                          0x40
146#define TWS_I2O0_HOBQP                          0x44
147
148#define TWS_I2O0_CTL                            0x74
149
150#define TWS_I2O0_IOBDB                          0x9C
151#define TWS_I2O0_HOBDBC                         0xA0
152
153#define TWS_I2O0_SCRPD3                         0xBC
154
155#define TWS_I2O0_HIBQPL                         0xC0 /* 64bit inb port low */
156#define TWS_I2O0_HIBQPH                         0xC4 /* 64bit inb port high */
157#define TWS_I2O0_HOBQPL                         0xC8 /* 64bit out port low */
158#define TWS_I2O0_HOBQPH                         0xCC /* 64bit out port high */
159
160/* IOP related */
161#define TWS_I2O0_IOPOBQPL                       0xD8 /* OBFL */
162#define TWS_I2O0_IOPOBQPH                       0xDC /* OBFH */
163#define TWS_I2O0_SRC_ADDRH                      0xF8 /* Msg ASA */
164
165#define TWS_MSG_ACC_MASK                        0x20000000
166#define TWS_32BIT_MASK                          0xFFFFFFFF
167
168/* revisit */
169#define TWS_FW_CMD_NOP                     0x0
170#define TWS_FW_CMD_INIT_CONNECTION         0x01
171#define TWS_FW_CMD_EXECUTE_SCSI            0x10
172
173#define TWS_FW_CMD_ATA_PASSTHROUGH         0x11 // This is really a PASSTHROUGH for both ATA and SCSI commands.
174#define TWS_FW_CMD_GET_PARAM               0x12
175#define TWS_FW_CMD_SET_PARAM               0x13
176
177#define BUILD_SGL_OFF__OPCODE(sgl_off, opcode)  \
178        ((sgl_off << 5) & 0xE0) | (opcode & 0x1F)       /* 3:5 */
179
180#define BUILD_RES__OPCODE(res, opcode)          \
181        ((res << 5) & 0xE0) | (opcode & 0x1F)           /* 3:5 */
182
183#define GET_OPCODE(sgl_off__opcode)     \
184        (sgl_off__opcode & 0x1F)                        /* 3:5 */
185
186/* end revisit */
187
188/* Table #'s and id's of parameters of interest in firmware's param table. */
189#define TWS_PARAM_VERSION_TABLE         0x0402
190#define TWS_PARAM_VERSION_FW            3       /* firmware version [16] */
191#define TWS_PARAM_VERSION_BIOS          4       /* BIOSs version [16] */
192#define TWS_PARAM_CTLR_MODEL            8       /* Controller model [16] */
193
194#define TWS_PARAM_CONTROLLER_TABLE      0x0403
195#define TWS_PARAM_CONTROLLER_PORT_COUNT 3       /* number of ports [1] */
196
197#define TWS_PARAM_TIME_TABLE            0x40A
198#define TWS_PARAM_TIME_SCHED_TIME       0x3
199
200#define TWS_PARAM_PHYS_TABLE            0x0001
201#define TWS_PARAM_CONTROLLER_PHYS_COUNT 2       /* number of phys */
202
203#define TWS_9K_PARAM_DESCRIPTOR         0x8000
204
205/* ----------- request  ------------- */
206
207#pragma pack(1)
208
209struct tws_cmd_init_connect {
210    u_int8_t        res1__opcode;   /* 3:5 */
211    u_int8_t        size;
212    u_int8_t        request_id;
213    u_int8_t        res2;
214    u_int8_t        status;
215    u_int8_t        flags;
216    u_int16_t       message_credits;
217    u_int32_t       features;
218    u_int16_t       fw_srl;
219    u_int16_t       fw_arch_id;
220    u_int16_t       fw_branch;
221    u_int16_t       fw_build;
222    u_int32_t       result;
223};
224
225/* Structure for downloading firmware onto the controller. */
226struct tws_cmd_download_firmware {
227    u_int8_t        sgl_off__opcode;/* 3:5 */
228    u_int8_t        size;
229    u_int8_t        request_id;
230    u_int8_t        unit;
231    u_int8_t        status;
232    u_int8_t        flags;
233    u_int16_t       param;
234    u_int8_t        sgl[1];
235};
236
237/* Structure for hard resetting the controller. */
238struct tws_cmd_reset_firmware {
239    u_int8_t        res1__opcode;   /* 3:5 */
240    u_int8_t        size;
241    u_int8_t        request_id;
242    u_int8_t        unit;
243    u_int8_t        status;
244    u_int8_t        flags;
245    u_int8_t        res2;
246    u_int8_t        param;
247};
248
249/* Structure for sending get/set param commands. */
250struct tws_cmd_param {
251    u_int8_t        sgl_off__opcode;/* 3:5 */
252    u_int8_t        size;
253    u_int8_t        request_id;
254    u_int8_t        host_id__unit;  /* 4:4 */
255    u_int8_t        status;
256    u_int8_t        flags;
257    u_int16_t       param_count;
258    u_int8_t        sgl[1];
259};
260
261/* Generic command packet. */
262struct tws_cmd_generic {
263    u_int8_t        sgl_off__opcode;/* 3:5 */
264    u_int8_t        size;
265    u_int8_t        request_id;
266    u_int8_t        host_id__unit;  /* 4:4 */
267    u_int8_t        status;
268    u_int8_t        flags;
269    u_int16_t       count;  /* block cnt, parameter cnt, message credits */
270};
271
272/* Command packet header. */
273struct tws_command_header {
274    u_int8_t        sense_data[TWS_SENSE_DATA_LENGTH];
275    struct { /* status block - additional sense data */
276        u_int16_t       srcnum;
277        u_int8_t        reserved;
278        u_int8_t        status;
279        u_int16_t       error;
280        u_int8_t        res__srcid;     /* 4:4 */
281        u_int8_t        res__severity;  /* 5:3 */
282    } status_block;
283    u_int8_t        err_specific_desc[TWS_ERROR_SPECIFIC_DESC_LEN];
284    struct { /* sense buffer descriptor */
285        u_int8_t        size_header;
286        u_int16_t       request_id;
287        u_int8_t        size_sense;
288    } header_desc;
289};
290
291/* Command - 1024 byte size including header (128+24+896)*/
292union tws_command_giga {
293    struct tws_cmd_init_connect       init_connect;
294    struct tws_cmd_download_firmware  download_fw;
295    struct tws_cmd_reset_firmware     reset_fw;
296    struct tws_cmd_param              param;
297    struct tws_cmd_generic            generic;
298    u_int8_t        padding[1024 - sizeof(struct tws_command_header)];
299};
300
301/* driver command pkt - 1024 byte size including header(128+24+744+128) */
302/* h/w & f/w supported command size excluding header 768 */
303struct tws_command_apache {
304    u_int8_t        res__opcode;    /* 3:5 */
305    u_int8_t        unit;
306    u_int16_t       lun_l4__req_id; /* 4:12 */
307    u_int8_t        status;
308    u_int8_t        sgl_offset;     /* offset (in bytes) to sg_list,
309                                     from the end of sgl_entries */
310    u_int16_t       lun_h4__sgl_entries;
311    u_int8_t        cdb[16];
312    u_int8_t        sg_list[744];   /* 768 - 24 */
313    u_int8_t        padding[128];   /* make it 1024 bytes */
314};
315
316struct tws_command_packet {
317    struct tws_command_header hdr;
318    union {
319        union tws_command_giga pkt_g;
320        struct tws_command_apache pkt_a;
321    } cmd;
322};
323
324/* Structure describing payload for get/set param commands. */
325struct tws_getset_param {
326    u_int16_t       table_id;
327    u_int8_t        parameter_id;
328    u_int8_t        reserved;
329    u_int16_t       parameter_size_bytes;
330    u_int16_t       parameter_actual_size_bytes;
331    u_int8_t        data[1];
332};
333
334struct tws_outbound_response {
335    u_int32_t     not_mfa   :1;   /* 1 if the structure is valid else MFA */
336    u_int32_t     reserved  :7;   /* reserved bits */
337    u_int32_t     status    :8;   /* should be 0 */
338    u_int32_t     request_id:16;  /* request id */
339};
340
341/* Scatter/Gather list entry with 32 bit addresses. */
342struct tws_sg_desc32 {
343    u_int32_t     address;
344    u_int32_t     length  :24;
345    u_int32_t     flag    :8;
346};
347
348/* Scatter/Gather list entry with 64 bit addresses. */
349struct tws_sg_desc64 {
350    u_int64_t     address;
351    u_int64_t     length   :32;
352    u_int64_t     reserved :24;
353    u_int64_t     flag     :8;
354};
355
356/*
357 * Packet that describes an AEN/error generated by the controller,
358 * shared with user
359 */
360struct tws_event_packet {
361    u_int32_t       sequence_id;
362    u_int32_t       time_stamp_sec;
363    u_int16_t       aen_code;
364    u_int8_t        severity;
365    u_int8_t        retrieved;
366    u_int8_t        repeat_count;
367    u_int8_t        parameter_len;
368    u_int8_t        parameter_data[TWS_ERROR_SPECIFIC_DESC_LEN];
369    u_int32_t       event_src;
370    u_int8_t        severity_str[20];
371};
372
373#pragma pack()
374
375struct tws_sense {
376    struct tws_command_header *hdr;
377    u_int64_t  hdr_pkt_phy;
378};
379
380struct tws_request {
381    struct tws_command_packet *cmd_pkt; /* command pkt */
382    u_int64_t    cmd_pkt_phy;    /* cmd pkt physical address */
383    void         *data;          /* ptr to data being passed to fw */
384    u_int32_t    length;         /* length of data being passed to fw */
385
386    u_int32_t    state;          /* request state */
387    u_int32_t    type;           /* request type */
388    u_int32_t    flags;          /* request flags */
389
390    u_int32_t    error_code;     /* error during request processing */
391
392    u_int32_t    request_id;     /* request id for tracking with fw */
393    void         (*cb)(struct tws_request *);      /* callback func */
394    bus_dmamap_t dma_map;        /* dma map */
395    union ccb    *ccb_ptr;       /* pointer to ccb */
396    struct callout timeout;	 /* request timeout timer */
397    struct tws_softc *sc;        /* pointer back to ctlr softc */
398
399    struct tws_request *next;    /* pointer to next request */
400    struct tws_request *prev;    /* pointer to prev request */
401};
402