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