1 /* 2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* 7 * Part of Intel(R) Manageability Engine Interface Linux driver 8 * 9 * Copyright (c) 2003 - 2008 Intel Corp. 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions, and the following disclaimer, 17 * without modification. 18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19 * substantially similar to the "NO WARRANTY" disclaimer below 20 * ("Disclaimer") and any redistribution must be conditioned upon 21 * including a substantially similar Disclaimer requirement for further 22 * binary redistribution. 23 * 3. Neither the names of the above-listed copyright holders nor the names 24 * of any contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * Alternatively, this software may be distributed under the terms of the 28 * GNU General Public License ("GPL") version 2 as published by the Free 29 * Software Foundation. 30 * 31 * NO WARRANTY 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42 * POSSIBILITY OF SUCH DAMAGES. 43 * 44 */ 45 46 #ifndef _HECI_DATA_STRUCTURES_H_ 47 #define _HECI_DATA_STRUCTURES_H_ 48 49 #include <sys/varargs.h> 50 #include <sys/types.h> 51 52 #ifndef SUNOS 53 #define SUNOS 54 #endif 55 56 /* 57 * error code definition 58 */ 59 #define ESLOTS_OVERFLOW 1 60 #define ECORRUPTED_MESSAGE_HEADER 1000 61 #define ECOMPLETE_MESSAGE 1001 62 63 #define HECI_FC_MESSAGE_RESERVED_LENGTH 5 64 65 /* 66 * Number of queue lists used by this driver 67 */ 68 #define HECI_IO_LISTS_NUMBER 7 69 70 /* 71 * Maximum transmission unit (MTU) of heci messages 72 */ 73 #define IAMTHIF_MTU 4160 74 #pragma pack(1) 75 76 77 /* 78 * HECI HW Section 79 */ 80 81 /* HECI registers */ 82 /* H_CB_WW - Host Circular Buffer (CB) Write Window register */ 83 #define H_CB_WW 0 84 /* H_CSR - Host Control Status register */ 85 #define H_CSR 4 86 /* ME_CB_RW - ME Circular Buffer Read Window register (read only) */ 87 #define ME_CB_RW 8 88 /* ME_CSR_HA - ME Control Status Host Access register (read only) */ 89 #define ME_CSR_HA 0xC 90 91 92 /* register bits of H_CSR (Host Control Status register) */ 93 /* Host Circular Buffer Depth - maximum number of 32-bit entries in CB */ 94 #define H_CBD 0xFF000000 95 /* Host Circular Buffer Write Pointer */ 96 #define H_CBWP 0x00FF0000 97 /* Host Circular Buffer Read Pointer */ 98 #define H_CBRP 0x0000FF00 99 /* Host Reset */ 100 #define H_RST 0x00000010 101 /* Host Ready */ 102 #define H_RDY 0x00000008 103 /* Host Interrupt Generate */ 104 #define H_IG 0x00000004 105 /* Host Interrupt Status */ 106 #define H_IS 0x00000002 107 /* Host Interrupt Enable */ 108 #define H_IE 0x00000001 109 110 111 /* 112 * register bits of ME_CSR_HA (ME Control Status Host Access register) 113 * ME CB (Circular Buffer) Depth HRA (Host Read Access) 114 * - host read only access to ME_CBD 115 */ 116 #define ME_CBD_HRA 0xFF000000 117 /* ME CB Write Pointer HRA - host read only access to ME_CBWP */ 118 #define ME_CBWP_HRA 0x00FF0000 119 /* ME CB Read Pointer HRA - host read only access to ME_CBRP */ 120 #define ME_CBRP_HRA 0x0000FF00 121 /* ME Reset HRA - host read only access to ME_RST */ 122 #define ME_RST_HRA 0x00000010 123 /* ME Ready HRA - host read only access to ME_RDY */ 124 #define ME_RDY_HRA 0x00000008 125 /* ME Interrupt Generate HRA - host read only access to ME_IG */ 126 #define ME_IG_HRA 0x00000004 127 /* ME Interrupt Status HRA - host read only access to ME_IS */ 128 #define ME_IS_HRA 0x00000002 129 /* ME Interrupt Enable HRA - host read only access to ME_IE */ 130 #define ME_IE_HRA 0x00000001 131 132 #define HECI_MINOR_NUMBER 1 133 /* #define HECI_PTHI_MINOR_NUMBER 0 */ 134 #define MAKE_MINOR_NUM(minor, instance) (((uint_t)(minor) << 8) \ 135 | ((instance) & 0xFF)) 136 #define HECI_MINOR_TO_INSTANCE(x) ((x) & 0xFF) 137 #define HECI_MINOR_TO_IFNUM(x) (((x) >> 8) & 0xFF) 138 139 #define HECI_MAX_OPEN_HANDLE_COUNT 253 140 141 /* 142 * debug kernel print macro define 143 */ 144 #define PRN(...) _PRN("%s(): "__VA_ARGS__, "") 145 #define _PRN(format, ...) \ 146 cmn_err(CE_CONT, format"%s", __func__, __VA_ARGS__) 147 148 #ifdef DEBUG 149 extern int heci_debug; 150 #define DBG(...) { if (heci_debug) PRN(__VA_ARGS__); } 151 #else 152 #define DBG 153 #endif 154 155 #define assert(expr) \ 156 if (!(expr)) { \ 157 cmn_err(CE_WARN, "Assertion failed! %s,%s,line=%d", #expr, \ 158 __FILE__, __LINE__); \ 159 } 160 161 #define list_next(p) ((p)->list_next) 162 163 #define walk_list(p, n, h) \ 164 for (p = list_next(h), n = list_next(p); \ 165 p != (h); \ 166 p = n, n = list_next(p)) 167 168 169 #define list_init(ptr) { \ 170 (ptr)->list_next = (ptr); (ptr)->list_prev = (ptr); \ 171 } 172 173 #define LIST_INIT_HEAD list_init 174 #define list_del_init(n) { \ 175 list_del(n); \ 176 list_init(n); \ 177 } 178 179 #define list_empty(l) ((l)->list_next == (l)) 180 #define list_del(p) { (p)->list_next->list_prev = (p)->list_prev; \ 181 (p)->list_prev->list_next = (p)->list_next; } 182 #define list_add_tail(newnode, head) { \ 183 (head)->list_prev->list_next = (newnode); \ 184 (newnode)->list_prev = (head)->list_prev; \ 185 (head)->list_prev = (newnode); \ 186 (newnode)->list_next = (head); \ 187 } 188 #define list_relink_node(newnode, head) { \ 189 list_del(newnode); \ 190 list_add_tail(newnode, head); \ 191 } 192 193 #ifdef __GNUC__ 194 195 #define find_struct(ptr, type, member) ( \ 196 { \ 197 const __typeof(((type *)0)->member) *__tmpp = (ptr); \ 198 (type *)(void *)((char *)__tmpp - ((size_t)&((type *)0)->member)); \ 199 }) 200 #else 201 /* type unsafe version */ 202 #define find_struct(ptr, type, member) \ 203 ((type *)(void *)((char *)(ptr) \ 204 - ((size_t)&((type *)0)->member))) 205 206 #endif 207 208 #define list_for_each_entry_safe(pos, n, head, member, type) \ 209 for (pos = find_struct((head)->list_next, type, member), \ 210 n = find_struct(pos->member.list_next, type, member); \ 211 &pos->member != (head); \ 212 pos = n, n = find_struct(n->member.list_next, type, member)) 213 214 #define HZ drv_usectohz(1000000) 215 /* 216 * time to wait HECI become ready after init 217 */ 218 #define HECI_INTEROP_TIMEOUT (HZ * 7) 219 220 /* 221 * watch dog definition 222 */ 223 #define HECI_WATCHDOG_DATA_SIZE 16 224 #define HECI_START_WD_DATA_SIZE 20 225 #define HECI_WD_PARAMS_SIZE 4 226 #define HECI_WD_STATE_INDEPENDENCE_MSG_SENT (1 << 0) 227 228 #define HECI_WD_HOST_CLIENT_ID 1 229 #define HECI_IAMTHIF_HOST_CLIENT_ID 2 230 231 struct guid { 232 uint32_t data1; 233 uint16_t data2; 234 uint16_t data3; 235 uint8_t data4[8]; 236 }; 237 238 /* File state */ 239 enum file_state { 240 HECI_FILE_INITIALIZING = 0, 241 HECI_FILE_CONNECTING, 242 HECI_FILE_CONNECTED, 243 HECI_FILE_DISCONNECTING, 244 HECI_FILE_DISCONNECTED 245 }; 246 247 /* HECI device states */ 248 enum heci_states { 249 HECI_INITIALIZING = 0, 250 HECI_ENABLED, 251 HECI_RESETING, 252 HECI_DISABLED, 253 HECI_RECOVERING_FROM_RESET, 254 HECI_POWER_DOWN, 255 HECI_POWER_UP 256 }; 257 258 enum iamthif_states { 259 HECI_IAMTHIF_IDLE, 260 HECI_IAMTHIF_WRITING, 261 HECI_IAMTHIF_FLOW_CONTROL, 262 HECI_IAMTHIF_READING, 263 HECI_IAMTHIF_READ_COMPLETE 264 }; 265 266 enum heci_file_transaction_states { 267 HECI_IDLE, 268 HECI_WRITING, 269 HECI_WRITE_COMPLETE, 270 HECI_FLOW_CONTROL, 271 HECI_READING, 272 HECI_READ_COMPLETE 273 }; 274 275 /* HECI CB */ 276 enum heci_cb_major_types { 277 HECI_READ = 0, 278 HECI_WRITE, 279 HECI_IOCTL, 280 HECI_OPEN, 281 HECI_CLOSE 282 }; 283 284 /* HECI user data struct */ 285 struct heci_message_data { 286 uint32_t size; 287 char *data; 288 #ifndef _LP64 289 char *pad; 290 #endif 291 }; 292 293 #define HECI_CONNECT_TIMEOUT 3 /* at least 2 seconds */ 294 295 #define IAMTHIF_STALL_TIMER 12 /* seconds */ 296 #define IAMTHIF_READ_TIMER 15 /* seconds */ 297 struct heci_file { 298 void * private_data; 299 }; 300 301 struct heci_cb_private { 302 struct list_node cb_list; 303 enum heci_cb_major_types major_file_operations; 304 void *file_private; 305 struct heci_message_data request_buffer; 306 struct heci_message_data response_buffer; 307 unsigned long information; 308 unsigned long read_time; 309 struct heci_file *file_object; 310 }; 311 312 313 struct io_heci_list { 314 struct heci_cb_private heci_cb; 315 int status; 316 struct iamt_heci_device *device_extension; 317 }; 318 319 struct heci_driver_version { 320 uint8_t major; 321 uint8_t minor; 322 uint8_t hotfix; 323 uint16_t build; 324 }; 325 326 struct heci_client { 327 uint32_t max_message_length; 328 uint8_t protocol_version; 329 }; 330 331 /* 332 * HECI BUS Interface Section 333 */ 334 struct heci_msg_hdr { 335 uint32_t me_addr:8; 336 uint32_t host_addr:8; 337 uint32_t length:9; 338 uint32_t reserved:6; 339 uint32_t msg_complete:1; 340 }; 341 342 343 struct hbm_cmd { 344 uint8_t cmd:7; 345 uint8_t is_response:1; 346 }; 347 348 349 struct heci_bus_message { 350 struct hbm_cmd cmd; 351 uint8_t command_specific_data[]; 352 }; 353 354 struct hbm_version { 355 uint8_t minor_version; 356 uint8_t major_version; 357 }; 358 359 struct hbm_host_version_request { 360 struct hbm_cmd cmd; 361 uint8_t reserved; 362 struct hbm_version host_version; 363 }; 364 365 struct hbm_host_version_response { 366 struct hbm_cmd cmd; 367 int host_version_supported; 368 struct hbm_version me_max_version; 369 }; 370 371 struct hbm_host_stop_request { 372 struct hbm_cmd cmd; 373 uint8_t reason; 374 uint8_t reserved[2]; 375 }; 376 377 struct hbm_host_stop_response { 378 struct hbm_cmd cmd; 379 uint8_t reserved[3]; 380 }; 381 382 struct hbm_me_stop_request { 383 struct hbm_cmd cmd; 384 uint8_t reason; 385 uint8_t reserved[2]; 386 }; 387 388 struct hbm_host_enum_request { 389 struct hbm_cmd cmd; 390 uint8_t reserved[3]; 391 }; 392 393 struct hbm_host_enum_response { 394 struct hbm_cmd cmd; 395 uint8_t reserved[3]; 396 uint8_t valid_addresses[32]; 397 }; 398 399 struct heci_client_properties { 400 struct guid protocol_name; 401 uint8_t protocol_version; 402 uint8_t max_number_of_connections; 403 uint8_t fixed_address; 404 uint8_t single_recv_buf; 405 uint32_t max_msg_length; 406 }; 407 408 struct hbm_props_request { 409 struct hbm_cmd cmd; 410 uint8_t address; 411 uint8_t reserved[2]; 412 }; 413 414 415 struct hbm_props_response { 416 struct hbm_cmd cmd; 417 uint8_t address; 418 uint8_t status; 419 uint8_t reserved[1]; 420 struct heci_client_properties client_properties; 421 }; 422 423 struct hbm_client_connect_request { 424 struct hbm_cmd cmd; 425 uint8_t me_addr; 426 uint8_t host_addr; 427 uint8_t reserved; 428 }; 429 430 struct hbm_client_connect_response { 431 struct hbm_cmd cmd; 432 uint8_t me_addr; 433 uint8_t host_addr; 434 uint8_t status; 435 }; 436 437 struct hbm_client_disconnect_request { 438 struct hbm_cmd cmd; 439 uint8_t me_addr; 440 uint8_t host_addr; 441 uint8_t reserved[1]; 442 }; 443 444 struct hbm_flow_control { 445 struct hbm_cmd cmd; 446 uint8_t me_addr; 447 uint8_t host_addr; 448 uint8_t reserved[HECI_FC_MESSAGE_RESERVED_LENGTH]; 449 }; 450 451 struct heci_me_client { 452 struct heci_client_properties props; 453 uint8_t client_id; 454 uint8_t flow_ctrl_creds; 455 }; 456 457 #pragma pack() 458 /* Private file struct */ 459 struct heci_file_private { 460 struct list_node link; 461 struct heci_file *file; 462 enum file_state state; 463 struct pollhead tx_pollwait; 464 kcondvar_t rx_wait; 465 struct pollhead pollwait; 466 kmutex_t file_lock; 467 kmutex_t read_io_lock; 468 kmutex_t write_io_lock; 469 int read_pending; 470 int status; 471 /* ID of client connected */ 472 uint8_t host_client_id; 473 uint8_t me_client_id; 474 uint8_t flow_ctrl_creds; 475 uint8_t timer_count; 476 enum heci_file_transaction_states reading_state; 477 enum heci_file_transaction_states writing_state; 478 int sm_state; 479 struct heci_cb_private *read_cb; 480 }; 481 482 /* private device struct */ 483 struct iamt_heci_device { 484 dev_info_t *dip; 485 ddi_acc_handle_t io_handle; 486 ddi_iblock_cookie_t sc_iblk; 487 488 /* 489 * lists of queues 490 */ 491 492 /* array of pointers to aio lists */ 493 struct io_heci_list *io_list_array[HECI_IO_LISTS_NUMBER]; 494 struct io_heci_list read_list; /* driver read queue */ 495 struct io_heci_list write_list; /* driver write queue */ 496 struct io_heci_list write_waiting_list; /* write waiting queue */ 497 struct io_heci_list ctrl_wr_list; /* managed write IOCTL list */ 498 struct io_heci_list ctrl_rd_list; /* managed read IOCTL list */ 499 struct io_heci_list pthi_cmd_list; /* PTHI list for cmd waiting */ 500 501 /* driver managed PTHI list for reading completed pthi cmd data */ 502 struct io_heci_list pthi_read_complete_list; 503 /* 504 * list of files 505 */ 506 struct list_node file_list; 507 /* 508 * memory of device 509 */ 510 char *mem_addr; 511 /* 512 * lock for the device 513 */ 514 kmutex_t device_lock; 515 ddi_taskq_t *work; 516 int recvd_msg; 517 518 ddi_taskq_t *reinit_tsk; 519 timeout_id_t wd_timer; 520 /* 521 * hw states of host and fw(ME) 522 */ 523 uint32_t host_hw_state; 524 uint32_t me_hw_state; 525 /* 526 * waiting queue for receive message from FW 527 */ 528 kcondvar_t wait_recvd_msg; 529 kcondvar_t wait_stop_wd; 530 /* 531 * heci device states 532 */ 533 enum heci_states heci_state; 534 int stop; 535 536 uint32_t extra_write_index; 537 uint32_t rd_msg_buf[128]; /* used for control messages */ 538 uint32_t wr_msg_buf[128]; /* used for control messages */ 539 uint32_t ext_msg_buf[8]; /* for control responses */ 540 uint32_t rd_msg_hdr; 541 542 struct hbm_version version; 543 544 int host_buffer_is_empty; 545 struct heci_file_private wd_file_ext; 546 struct heci_me_client *me_clients; /* Note: need to be allocated */ 547 uint8_t heci_me_clients[32]; /* list of existing clients */ 548 uint8_t num_heci_me_clients; 549 uint8_t heci_host_clients[32]; /* list of existing clients */ 550 uint8_t current_host_client_id; 551 552 int wd_pending; 553 int wd_stoped; 554 uint16_t wd_timeout; /* seconds ((wd_data[1] << 8) + wd_data[0]) */ 555 unsigned char wd_data[HECI_START_WD_DATA_SIZE]; 556 557 558 uint16_t wd_due_counter; 559 int asf_mode; 560 int wd_bypass; /* if 1, don't refresh watchdog ME client */ 561 562 struct heci_file *iamthif_file_object; 563 struct heci_file_private iamthif_file_ext; 564 int iamthif_ioctl; 565 int iamthif_canceled; 566 uint32_t iamthif_timer; 567 uint32_t iamthif_stall_timer; 568 struct heci_file files[256]; /* a file handle for each client */ 569 unsigned char iamthif_msg_buf[IAMTHIF_MTU]; 570 uint32_t iamthif_msg_buf_size; 571 uint32_t iamthif_msg_buf_index; 572 int iamthif_flow_control_pending; 573 enum iamthif_states iamthif_state; 574 575 struct heci_cb_private *iamthif_current_cb; 576 uint8_t write_hang; 577 int need_reset; 578 long open_handle_count; 579 580 }; 581 582 /* 583 * read_heci_register - Read a byte from the heci device 584 * 585 * @device: the device structure 586 * @offset: offset from which to read the data 587 * 588 * @return the byte read. 589 */ 590 uint32_t read_heci_register(struct iamt_heci_device *device, 591 unsigned long offset); 592 593 /* 594 * write_heci_register - Write 4 bytes to the heci device 595 * 596 * @device: the device structure 597 * @offset: offset from which to write the data 598 * @value: the byte to write 599 */ 600 void write_heci_register(struct iamt_heci_device *device, unsigned long offset, 601 uint32_t value); 602 603 #define UIO_OFFSET(p) (((struct uio *)p)->uio_offset) 604 #define UIO_LENGTH(p) (((struct uio *)p)->uio_resid) 605 #define UIO_BUFF(p) ((char *)((struct uio *)p)->uio_iov->iov_base) 606 607 #endif /* _HECI_DATA_STRUCTURES_H_ */ 608