1 /* 2 * Copyright (C) 2018-2022 Intel Corporation. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 */ 7 #ifndef _MEI_HBM_H_ 8 #define _MEI_HBM_H_ 9 #include <linux/uuid.h> 10 #include <linux/mei.h> 11 12 #ifndef guid_t 13 #define guid_t uuid_le 14 #endif 15 16 /* 17 * Timeouts in Seconds 18 */ 19 #define MEI_HW_READY_TIMEOUT 2 /* Timeout on ready message */ 20 #define MEI_CONNECT_TIMEOUT 3 /* HPS: at least 2 seconds */ 21 22 #define MEI_CL_CONNECT_TIMEOUT 15 /* HPS: Client Connect Timeout */ 23 #define MEI_CLIENTS_INIT_TIMEOUT 15 /* HPS: Clients Enumeration Timeout */ 24 25 #define MEI_PGI_TIMEOUT 1 /* PG Isolation time response 1 sec */ 26 #define MEI_D0I3_TIMEOUT 5 /* D0i3 set/unset max response time */ 27 #define MEI_HBM_TIMEOUT 1 /* 1 second */ 28 29 /* 30 * MEI Version 31 */ 32 #define MEI_HBM_MINOR_VERSION 0 33 #define MEI_HBM_MAJOR_VERSION 2 34 35 /* 36 * MEI version with PGI support 37 */ 38 #define MEI_HBM_MINOR_VERSION_PGI 1 39 #define MEI_HBM_MAJOR_VERSION_PGI 1 40 41 /* 42 * MEI version with Dynamic clients support 43 */ 44 #define MEI_HBM_MINOR_VERSION_DC 0 45 #define MEI_HBM_MAJOR_VERSION_DC 2 46 47 /* 48 * MEI version with immediate reply to enum request support 49 */ 50 #define MEI_HBM_MINOR_VERSION_IE 0 51 #define MEI_HBM_MAJOR_VERSION_IE 2 52 53 /* 54 * MEI version with disconnect on connection timeout support 55 */ 56 #define MEI_HBM_MINOR_VERSION_DOT 0 57 #define MEI_HBM_MAJOR_VERSION_DOT 2 58 59 /* 60 * MEI version with notification support 61 */ 62 #define MEI_HBM_MINOR_VERSION_EV 0 63 #define MEI_HBM_MAJOR_VERSION_EV 2 64 65 /* 66 * MEI version with fixed address client support 67 */ 68 #define MEI_HBM_MINOR_VERSION_FA 0 69 #define MEI_HBM_MAJOR_VERSION_FA 2 70 71 /* 72 * MEI version with OS ver message support 73 */ 74 #define MEI_HBM_MINOR_VERSION_OS 0 75 #define MEI_HBM_MAJOR_VERSION_OS 2 76 77 /* 78 * MEI version with dma ring support 79 */ 80 #define MEI_HBM_MINOR_VERSION_DR 1 81 #define HMEI_BM_MAJOR_VERSION_DR 2 82 83 /* Host bus message command opcode */ 84 #define MEI_HBM_CMD_OP_MSK 0x7f 85 /* Host bus message command RESPONSE */ 86 #define MEI_HBM_CMD_RES_MSK 0x80 87 88 #define MEI_HBM_HOST_START 0x01 89 #define MEI_HBM_HOST_START_RES 0x81 90 91 #define MEI_HBM_HOST_STOP 0x02 92 #define MEI_HBM_HOST_STO_RES 0x82 93 94 #define MEI_HBM_ME_STOP 0x03 95 96 #define MEI_HBM_HOST_ENUM 0x04 97 #define MEI_HBM_HOST_ENUM_RES 0x84 98 99 #define MEI_HBM_HOST_CLIENT_PROP 0x05 100 #define MEI_HBM_HOST_CLIENT_PROP_RES 0x85 101 102 #define MEI_HBM_CLIENT_CONNECT 0x06 103 #define MEI_HBM_CLIENT_CONNECT_RES 0x86 104 105 #define MEI_HBM_CLIENT_DISCONNECT 0x07 106 #define MEI_HBM_CLIENT_DISCONNECT_RES 0x87 107 108 #define MEI_HBM_FLOW_CONTROL 0x08 109 110 #define MEI_HBM_CLIENT_CONNECTION_RESET 0x09 111 112 #define MEI_HBM_PG_ISOLATION_ENTRY 0x0a 113 #define MEI_HBM_PG_ISOLATION_ENTRY_RES 0x8a 114 115 #define MEI_HBM_PG_ISOLATION_EXIT 0x0b 116 #define MEI_HBM_PG_ISOLATION_EXIT_RES 0x8b 117 118 #define MEI_HBM_CLIENT_ADD 0x0f 119 #define MEI_HBM_CLIENT_ADD_RES 0x8f 120 121 #define MEI_HBM_NOTIFY 0x10 122 #define MEI_HBM_NOTIFY_RES 0x90 123 #define MEI_HBM_NOTIFICATION 0x11 124 125 #define MEI_HBM_DMA_SETUP 0x12 126 #define MEI_HBM_DMA_SETUP_RES 0x92 127 128 /* 129 * MEI Stop Reason 130 * used by hbm_host_stop_request.reason 131 */ 132 enum mei_stop_reason_types { 133 DRIVER_STOP_REQUEST = 0x00, 134 DEVICE_D1_ENTRY = 0x01, 135 DEVICE_D2_ENTRY = 0x02, 136 DEVICE_D3_ENTRY = 0x03, 137 SYSTEM_S1_ENTRY = 0x04, 138 SYSTEM_S2_ENTRY = 0x05, 139 SYSTEM_S3_ENTRY = 0x06, 140 SYSTEM_S4_ENTRY = 0x07, 141 SYSTEM_S5_ENTRY = 0x08 142 }; 143 144 /* 145 * enum mei_hbm_status - mei host bus messages return values 146 * 147 * @MEI_HBM_SUCCESS : status success 148 * @MEI_HBM_CLIENT_NOT_FOUND : client not found 149 * @MEI_HBM_ALREADY_EXISTS : connection already established 150 * @MEI_HBM_REJECTED : connection is rejected 151 * @MEI_HBM_INVALID_PARAMETER : invalid parameter 152 * @MEI_HBM_NOT_ALLOWED : operation not allowed 153 * @MEI_HBM_ALREADY_STARTED : system is already started 154 * @MEI_HBM_NOT_STARTED : system not started 155 * 156 */ 157 enum mei_hbm_status { 158 MEI_HBM_SUCCESS = 0, 159 MEI_HBM_CLIENT_NOT_FOUND = 1, 160 MEI_HBM_ALREADY_EXISTS = 2, 161 MEI_HBM_REJECTED = 3, 162 MEI_HBM_INVALID_PARAMETER = 4, 163 MEI_HBM_NOT_ALLOWED = 5, 164 MEI_HBM_ALREADY_STARTED = 6, 165 MEI_HBM_NOT_STARTED = 7, 166 167 MEI_HBM_MAX 168 }; 169 170 /* 171 * Client Connect Status 172 * used by hbm_client_connect_response.status 173 */ 174 enum mei_cl_connect_status { 175 MEI_CL_CONN_SUCCESS = MEI_HBM_SUCCESS, 176 MEI_CL_CONN_NOT_FOUND = MEI_HBM_CLIENT_NOT_FOUND, 177 MEI_CL_CONN_ALREADY_STARTED = MEI_HBM_ALREADY_EXISTS, 178 MEI_CL_CONN_OUT_OF_RESOURCES = MEI_HBM_REJECTED, 179 MEI_CL_CONN_MESSAGE_SMALL = MEI_HBM_INVALID_PARAMETER, 180 MEI_CL_CONN_NOT_ALLOWED = MEI_HBM_NOT_ALLOWED, 181 }; 182 183 /* 184 * Client Disconnect Status 185 */ 186 enum mei_cl_disconnect_status { 187 MEI_CL_DISCONN_SUCCESS = MEI_HBM_SUCCESS 188 }; 189 190 struct mei_enumerate_me_clients { 191 uint8_t valid_addresses[32]; 192 }; 193 194 struct mei_client_properties { 195 guid_t protocol_name; 196 uint8_t protocol_version; 197 uint8_t max_connections; 198 uint8_t fixed_address; 199 uint8_t single_recv_buf; 200 uint32_t max_msg_length; 201 } __attribute__((packed)); 202 203 /* message header is same in native and virtual */ 204 struct mei_msg_hdr { 205 uint32_t me_addr:8; 206 uint32_t host_addr:8; 207 uint32_t length:9; 208 uint32_t reserved:5; 209 uint32_t internal:1; 210 uint32_t msg_complete:1; 211 } __attribute__((packed)); 212 213 struct mei_hbm_cmd { 214 uint8_t cmd:7; 215 uint8_t is_response:1; 216 } __attribute__((packed)); 217 218 struct mei_hbm_host_ver_req { 219 struct mei_hbm_cmd hbm_cmd; 220 uint8_t reserved; 221 uint8_t minor; 222 uint8_t major; 223 } __attribute__((packed)); 224 225 struct mei_hbm_host_ver_res { 226 struct mei_hbm_cmd hbm_cmd; 227 uint8_t host_ver_support; 228 uint8_t minor; 229 uint8_t major; 230 } __attribute__((packed)); 231 232 struct mei_hbm_host_stop_req { 233 struct mei_hbm_cmd hbm_cmd; 234 uint8_t reason; 235 uint8_t reserved[2]; 236 } __attribute__((packed)); 237 238 struct mei_hbm_host_stop_res { 239 struct mei_hbm_cmd hbm_cmd; 240 uint8_t reserved[3]; 241 } __attribute__((packed)); 242 243 struct mei_hbm_me_stop_res { 244 struct mei_hbm_cmd hbm_cmd; 245 uint8_t reason; 246 uint8_t reserved[2]; 247 } __attribute__((packed)); 248 249 struct mei_hbm_me_stop_req { 250 struct mei_hbm_cmd hbm_cmd; 251 uint8_t reserved[3]; 252 } __attribute__((packed)); 253 254 /** 255 * enum hbm_host_enum_flags - enumeration request flags (HBM version >= 2.0) 256 * 257 * @MEI_HBM_ENUM_F_ALLOW_ADD: allow dynamic clients add 258 * @MEI_HBM_ENUM_F_IMMEDIATE_ENUM: allow FW to send answer immediately 259 */ 260 enum mei_hbm_host_enum_flags { 261 MEI_HBM_ENUM_F_ALLOW_ADD = 0, 262 MEI_HBM_ENUM_F_IMMEDIATE_ENUM = 1, 263 }; 264 265 struct mei_hbm_host_enum_req { 266 struct mei_hbm_cmd hbm_cmd; 267 uint8_t flags; 268 uint8_t reserved[2]; 269 } __attribute__((packed)); 270 271 struct mei_hbm_host_enum_res { 272 struct mei_hbm_cmd hbm_cmd; 273 uint8_t reserved[3]; 274 uint8_t valid_addresses[32]; 275 }; 276 277 struct mei_hbm_host_client_prop_req { 278 struct mei_hbm_cmd hbm_cmd; 279 uint8_t address; 280 uint8_t reserved[2]; 281 } __attribute__((packed)); 282 283 284 struct mei_hbm_host_client_prop_res { 285 struct mei_hbm_cmd hbm_cmd; 286 uint8_t address; 287 uint8_t status; 288 uint8_t reserved[1]; 289 struct mei_client_properties props; 290 } __attribute__((packed)); 291 292 /** 293 * struct mei_hbm_add_client_req - request to add a client 294 * might be sent by fw after enumeration has already completed 295 * 296 * @hbm_cmd: bus message command header 297 * @me_addr: address of the client in ME 298 * @reserved: reserved 299 * @client_properties: client properties 300 */ 301 struct mei_hbm_add_client_req { 302 struct mei_hbm_cmd hbm_cmd; 303 uint8_t me_addr; 304 uint8_t reserved[2]; 305 struct mei_client_properties client_properties; 306 } __attribute__((packed)); 307 308 /** 309 * struct mei_hbm_add_client_res - response to add a client 310 * sent by the host to report client addition status to fw 311 * 312 * @hbm_cmd: bus message command header 313 * @me_addr: address of the client in ME 314 * @status: if HBM_SUCCESS then the client can now accept connections. 315 * @reserved: reserved 316 */ 317 struct hbm_add_client_res { 318 struct mei_hbm_cmd hbm_cmd; 319 uint8_t me_addr; 320 uint8_t status; 321 uint8_t reserved[1]; 322 } __attribute__((packed)); 323 324 /** 325 * struct mei_hbm_power_gate - power gate request/response 326 * 327 * @hbm_cmd: bus message command header 328 * @reserved: reserved 329 */ 330 struct mei_hbm_power_gate { 331 struct mei_hbm_cmd hbm_cmd; 332 uint8_t reserved[3]; 333 } __attribute__((packed)); 334 335 struct mei_hbm_client_connect_req { 336 struct mei_hbm_cmd hbm_cmd; 337 uint8_t me_addr; 338 uint8_t host_addr; 339 uint8_t reserved; 340 } __attribute__((packed)); 341 342 struct mei_hbm_client_connect_res { 343 struct mei_hbm_cmd hbm_cmd; 344 uint8_t me_addr; 345 uint8_t host_addr; 346 uint8_t status; 347 } __attribute__((packed)); 348 349 struct mei_hbm_client_disconnect_req { 350 struct mei_hbm_cmd hbm_cmd; 351 uint8_t me_addr; 352 uint8_t host_addr; 353 uint8_t status; 354 } __attribute__((packed)); 355 356 struct mei_hbm_client_disconnect_res { 357 struct mei_hbm_cmd hbm_cmd; 358 uint8_t me_addr; 359 uint8_t host_addr; 360 uint8_t status; 361 } __attribute__((packed)); 362 363 struct mei_hbm_flow_ctl { 364 struct mei_hbm_cmd hbm_cmd; 365 uint8_t me_addr; 366 uint8_t host_addr; 367 uint8_t reserved[5]; 368 } __attribute__((packed)); 369 370 /** 371 * struct mei_hbm_notification_req - start/stop notification request 372 * 373 * @hbm_cmd: bus message command header 374 * @me_addr: address of the client in ME 375 * @host_addr: address of the client in the driver 376 * @start: start = 1 or stop = 0 asynchronous notifications 377 */ 378 379 struct mei_hbm_notification_req { 380 struct mei_hbm_cmd hbm_cmd; 381 uint8_t me_addr; 382 uint8_t host_addr; 383 uint8_t start; 384 } __attribute__((packed)); 385 386 /** 387 * struct mei_hbm_notification_res - start/stop notification response 388 * 389 * @hbm_cmd: bus message command header 390 * @me_addr: address of the client in ME 391 * @host_addr: - address of the client in the driver 392 * @status: (mei_hbm_status) response status for the request 393 * - MEI_HBM_SUCCESS: successful stop/start 394 * - MEI_HBM_CLIENT_NOT_FOUND: if the connection could not be found. 395 * - MEI_HBM_ALREADY_STARTED: for start requests for a previously 396 * started notification. 397 * - MEI_HBM_NOT_STARTED: for stop request for a connected client for whom 398 * asynchronous notifications are currently disabled. 399 * 400 * @start: start = 1 or stop = 0 asynchronous notifications 401 * @reserved: reserved 402 */ 403 struct mei_hbm_notification_res { 404 struct mei_hbm_cmd hbm_cmd; 405 uint8_t me_addr; 406 uint8_t host_addr; 407 uint8_t status; 408 uint8_t start; 409 uint8_t reserved[3]; 410 } __attribute__((packed)); 411 412 /** 413 * struct mei_hbm_notification - notification event 414 * 415 * @hbm_cmd: bus message command header 416 * @me_addr: address of the client in ME 417 * @host_addr: address of the client in the driver 418 * @reserved: reserved for alignment 419 */ 420 struct mei_hbm_notification { 421 struct mei_hbm_cmd hbm_cmd; 422 uint8_t me_addr; 423 uint8_t host_addr; 424 uint8_t reserved[1]; 425 } __attribute__((packed)); 426 427 /** 428 * struct mei_hbm_dma_mem_dscr - dma ring 429 * 430 * @addr_hi: the high 32bits of 64 bit address 431 * @addr_lo: the low 32bits of 64 bit address 432 * @size : size in bytes (must be power of 2) 433 */ 434 struct mei_hbm_dma_mem_dscr { 435 uint32_t addr_hi; 436 uint32_t addr_lo; 437 uint32_t size; 438 } __attribute__((packed)); 439 440 enum { 441 MEI_DMA_DSCR_HOST = 0, 442 MEI_DMA_DSCR_DEVICE = 1, 443 MEI_DMA_DSCR_CTRL = 2, 444 MEI_DMA_DSCR_NUM, 445 }; 446 447 /** 448 * struct mei_hbm_dma_setup_req - dma setup request 449 * 450 * @hbm_cmd: bus message command header 451 * @reserved: reserved for alignment 452 * @dma_dscr: dma descriptor for HOST, DEVICE, and CTRL 453 */ 454 struct mei_hbm_dma_setup_req { 455 struct mei_hbm_cmd hbm_cmd; 456 uint8_t reserved[3]; 457 struct mei_hbm_dma_mem_dscr dma_dscr[MEI_DMA_DSCR_NUM]; 458 } __attribute__((packed)); 459 460 /** 461 * struct mei_hbm_dma_setup_res - dma setup response 462 * 463 * @hbm_cmd: bus message command header 464 * @status: 0 on success; otherwise DMA setup failed. 465 * @reserved: reserved for alignment 466 */ 467 struct mei_hbm_dma_setup_res { 468 struct mei_hbm_cmd hbm_cmd; 469 uint8_t status; 470 uint8_t reserved[2]; 471 } __attribute__((packed)); 472 473 #ifndef IOCTL_MEI_CONNECT_CLIENT_VTAG 474 /* 475 * IOCTL Connect Client Data structure with vtag 476 */ 477 struct mei_connect_client_vtag { 478 uuid_le in_client_uuid; 479 __u8 vtag; 480 __u8 reserved[3]; 481 }; 482 483 struct mei_connect_client_data_vtag { 484 union { 485 struct mei_connect_client_vtag connect; 486 struct mei_client out_client_properties; 487 }; 488 }; 489 490 #define IOCTL_MEI_CONNECT_CLIENT_VTAG \ 491 _IOWR('H', 0x04, struct mei_connect_client_data_vtag) 492 493 #endif /* IOCTL_MEI_CONNECT_CLIENT_VTAG */ 494 495 #endif /* _MEI_HBM_H_ */ 496