1 /* 2 * 3 * Intel Management Engine Interface (Intel MEI) Linux driver 4 * Copyright (c) 2003-2012, Intel Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms and conditions of the GNU General Public License, 8 * version 2, as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * more details. 14 * 15 */ 16 17 18 #include <linux/export.h> 19 #include <linux/kthread.h> 20 #include <linux/interrupt.h> 21 #include <linux/fs.h> 22 #include <linux/jiffies.h> 23 #include <linux/slab.h> 24 #include <linux/pm_runtime.h> 25 26 #include <linux/mei.h> 27 28 #include "mei_dev.h" 29 #include "hbm.h" 30 #include "client.h" 31 32 33 /** 34 * mei_irq_compl_handler - dispatch complete handlers 35 * for the completed callbacks 36 * 37 * @dev: mei device 38 * @cmpl_list: list of completed cbs 39 */ 40 void mei_irq_compl_handler(struct mei_device *dev, struct list_head *cmpl_list) 41 { 42 struct mei_cl_cb *cb, *next; 43 struct mei_cl *cl; 44 45 list_for_each_entry_safe(cb, next, cmpl_list, list) { 46 cl = cb->cl; 47 list_del_init(&cb->list); 48 49 dev_dbg(dev->dev, "completing call back.\n"); 50 mei_cl_complete(cl, cb); 51 } 52 } 53 EXPORT_SYMBOL_GPL(mei_irq_compl_handler); 54 55 /** 56 * mei_cl_hbm_equal - check if hbm is addressed to the client 57 * 58 * @cl: host client 59 * @mei_hdr: header of mei client message 60 * 61 * Return: true if matches, false otherwise 62 */ 63 static inline int mei_cl_hbm_equal(struct mei_cl *cl, 64 struct mei_msg_hdr *mei_hdr) 65 { 66 return mei_cl_host_addr(cl) == mei_hdr->host_addr && 67 mei_cl_me_id(cl) == mei_hdr->me_addr; 68 } 69 70 /** 71 * mei_irq_discard_msg - discard received message 72 * 73 * @dev: mei device 74 * @hdr: message header 75 */ 76 static void mei_irq_discard_msg(struct mei_device *dev, struct mei_msg_hdr *hdr) 77 { 78 if (hdr->dma_ring) 79 mei_dma_ring_read(dev, NULL, hdr->extension[0]); 80 /* 81 * no need to check for size as it is guarantied 82 * that length fits into rd_msg_buf 83 */ 84 mei_read_slots(dev, dev->rd_msg_buf, hdr->length); 85 dev_dbg(dev->dev, "discarding message " MEI_HDR_FMT "\n", 86 MEI_HDR_PRM(hdr)); 87 } 88 89 /** 90 * mei_cl_irq_read_msg - process client message 91 * 92 * @cl: reading client 93 * @mei_hdr: header of mei client message 94 * @cmpl_list: completion list 95 * 96 * Return: always 0 97 */ 98 static int mei_cl_irq_read_msg(struct mei_cl *cl, 99 struct mei_msg_hdr *mei_hdr, 100 struct list_head *cmpl_list) 101 { 102 struct mei_device *dev = cl->dev; 103 struct mei_cl_cb *cb; 104 size_t buf_sz; 105 u32 length; 106 107 cb = list_first_entry_or_null(&cl->rd_pending, struct mei_cl_cb, list); 108 if (!cb) { 109 if (!mei_cl_is_fixed_address(cl)) { 110 cl_err(dev, cl, "pending read cb not found\n"); 111 goto discard; 112 } 113 cb = mei_cl_alloc_cb(cl, mei_cl_mtu(cl), MEI_FOP_READ, cl->fp); 114 if (!cb) 115 goto discard; 116 list_add_tail(&cb->list, &cl->rd_pending); 117 } 118 119 if (!mei_cl_is_connected(cl)) { 120 cl_dbg(dev, cl, "not connected\n"); 121 cb->status = -ENODEV; 122 goto discard; 123 } 124 125 length = mei_hdr->dma_ring ? mei_hdr->extension[0] : mei_hdr->length; 126 127 buf_sz = length + cb->buf_idx; 128 /* catch for integer overflow */ 129 if (buf_sz < cb->buf_idx) { 130 cl_err(dev, cl, "message is too big len %d idx %zu\n", 131 length, cb->buf_idx); 132 cb->status = -EMSGSIZE; 133 goto discard; 134 } 135 136 if (cb->buf.size < buf_sz) { 137 cl_dbg(dev, cl, "message overflow. size %zu len %d idx %zu\n", 138 cb->buf.size, length, cb->buf_idx); 139 cb->status = -EMSGSIZE; 140 goto discard; 141 } 142 143 if (mei_hdr->dma_ring) 144 mei_dma_ring_read(dev, cb->buf.data + cb->buf_idx, length); 145 146 /* for DMA read 0 length to generate an interrupt to the device */ 147 mei_read_slots(dev, cb->buf.data + cb->buf_idx, mei_hdr->length); 148 149 cb->buf_idx += length; 150 151 if (mei_hdr->msg_complete) { 152 cl_dbg(dev, cl, "completed read length = %zu\n", cb->buf_idx); 153 list_move_tail(&cb->list, cmpl_list); 154 } else { 155 pm_runtime_mark_last_busy(dev->dev); 156 pm_request_autosuspend(dev->dev); 157 } 158 159 return 0; 160 161 discard: 162 if (cb) 163 list_move_tail(&cb->list, cmpl_list); 164 mei_irq_discard_msg(dev, mei_hdr); 165 return 0; 166 } 167 168 /** 169 * mei_cl_irq_disconnect_rsp - send disconnection response message 170 * 171 * @cl: client 172 * @cb: callback block. 173 * @cmpl_list: complete list. 174 * 175 * Return: 0, OK; otherwise, error. 176 */ 177 static int mei_cl_irq_disconnect_rsp(struct mei_cl *cl, struct mei_cl_cb *cb, 178 struct list_head *cmpl_list) 179 { 180 struct mei_device *dev = cl->dev; 181 u32 msg_slots; 182 int slots; 183 int ret; 184 185 msg_slots = mei_hbm2slots(sizeof(struct hbm_client_connect_response)); 186 slots = mei_hbuf_empty_slots(dev); 187 if (slots < 0) 188 return -EOVERFLOW; 189 190 if ((u32)slots < msg_slots) 191 return -EMSGSIZE; 192 193 ret = mei_hbm_cl_disconnect_rsp(dev, cl); 194 list_move_tail(&cb->list, cmpl_list); 195 196 return ret; 197 } 198 199 /** 200 * mei_cl_irq_read - processes client read related operation from the 201 * interrupt thread context - request for flow control credits 202 * 203 * @cl: client 204 * @cb: callback block. 205 * @cmpl_list: complete list. 206 * 207 * Return: 0, OK; otherwise, error. 208 */ 209 static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb, 210 struct list_head *cmpl_list) 211 { 212 struct mei_device *dev = cl->dev; 213 u32 msg_slots; 214 int slots; 215 int ret; 216 217 if (!list_empty(&cl->rd_pending)) 218 return 0; 219 220 msg_slots = mei_hbm2slots(sizeof(struct hbm_flow_control)); 221 slots = mei_hbuf_empty_slots(dev); 222 if (slots < 0) 223 return -EOVERFLOW; 224 225 if ((u32)slots < msg_slots) 226 return -EMSGSIZE; 227 228 ret = mei_hbm_cl_flow_control_req(dev, cl); 229 if (ret) { 230 cl->status = ret; 231 cb->buf_idx = 0; 232 list_move_tail(&cb->list, cmpl_list); 233 return ret; 234 } 235 236 list_move_tail(&cb->list, &cl->rd_pending); 237 238 return 0; 239 } 240 241 static inline bool hdr_is_hbm(struct mei_msg_hdr *mei_hdr) 242 { 243 return mei_hdr->host_addr == 0 && mei_hdr->me_addr == 0; 244 } 245 246 static inline bool hdr_is_fixed(struct mei_msg_hdr *mei_hdr) 247 { 248 return mei_hdr->host_addr == 0 && mei_hdr->me_addr != 0; 249 } 250 251 static inline int hdr_is_valid(u32 msg_hdr) 252 { 253 struct mei_msg_hdr *mei_hdr; 254 255 mei_hdr = (struct mei_msg_hdr *)&msg_hdr; 256 if (!msg_hdr || mei_hdr->reserved) 257 return -EBADMSG; 258 259 if (mei_hdr->dma_ring && mei_hdr->length != MEI_SLOT_SIZE) 260 return -EBADMSG; 261 262 return 0; 263 } 264 265 /** 266 * mei_irq_read_handler - bottom half read routine after ISR to 267 * handle the read processing. 268 * 269 * @dev: the device structure 270 * @cmpl_list: An instance of our list structure 271 * @slots: slots to read. 272 * 273 * Return: 0 on success, <0 on failure. 274 */ 275 int mei_irq_read_handler(struct mei_device *dev, 276 struct list_head *cmpl_list, s32 *slots) 277 { 278 struct mei_msg_hdr *mei_hdr; 279 struct mei_cl *cl; 280 int ret; 281 282 if (!dev->rd_msg_hdr[0]) { 283 dev->rd_msg_hdr[0] = mei_read_hdr(dev); 284 (*slots)--; 285 dev_dbg(dev->dev, "slots =%08x.\n", *slots); 286 287 ret = hdr_is_valid(dev->rd_msg_hdr[0]); 288 if (ret) { 289 dev_err(dev->dev, "corrupted message header 0x%08X\n", 290 dev->rd_msg_hdr[0]); 291 goto end; 292 } 293 } 294 295 mei_hdr = (struct mei_msg_hdr *)dev->rd_msg_hdr; 296 dev_dbg(dev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr)); 297 298 if (mei_slots2data(*slots) < mei_hdr->length) { 299 dev_err(dev->dev, "less data available than length=%08x.\n", 300 *slots); 301 /* we can't read the message */ 302 ret = -ENODATA; 303 goto end; 304 } 305 306 if (mei_hdr->dma_ring) { 307 dev->rd_msg_hdr[1] = mei_read_hdr(dev); 308 (*slots)--; 309 mei_hdr->length = 0; 310 } 311 312 /* HBM message */ 313 if (hdr_is_hbm(mei_hdr)) { 314 ret = mei_hbm_dispatch(dev, mei_hdr); 315 if (ret) { 316 dev_dbg(dev->dev, "mei_hbm_dispatch failed ret = %d\n", 317 ret); 318 goto end; 319 } 320 goto reset_slots; 321 } 322 323 /* find recipient cl */ 324 list_for_each_entry(cl, &dev->file_list, link) { 325 if (mei_cl_hbm_equal(cl, mei_hdr)) { 326 cl_dbg(dev, cl, "got a message\n"); 327 break; 328 } 329 } 330 331 /* if no recipient cl was found we assume corrupted header */ 332 if (&cl->link == &dev->file_list) { 333 /* A message for not connected fixed address clients 334 * should be silently discarded 335 * On power down client may be force cleaned, 336 * silently discard such messages 337 */ 338 if (hdr_is_fixed(mei_hdr) || 339 dev->dev_state == MEI_DEV_POWER_DOWN) { 340 mei_irq_discard_msg(dev, mei_hdr); 341 ret = 0; 342 goto reset_slots; 343 } 344 dev_err(dev->dev, "no destination client found 0x%08X\n", 345 dev->rd_msg_hdr[0]); 346 ret = -EBADMSG; 347 goto end; 348 } 349 350 ret = mei_cl_irq_read_msg(cl, mei_hdr, cmpl_list); 351 352 353 reset_slots: 354 /* reset the number of slots and header */ 355 memset(dev->rd_msg_hdr, 0, sizeof(dev->rd_msg_hdr)); 356 *slots = mei_count_full_read_slots(dev); 357 if (*slots == -EOVERFLOW) { 358 /* overflow - reset */ 359 dev_err(dev->dev, "resetting due to slots overflow.\n"); 360 /* set the event since message has been read */ 361 ret = -ERANGE; 362 goto end; 363 } 364 end: 365 return ret; 366 } 367 EXPORT_SYMBOL_GPL(mei_irq_read_handler); 368 369 370 /** 371 * mei_irq_write_handler - dispatch write requests 372 * after irq received 373 * 374 * @dev: the device structure 375 * @cmpl_list: An instance of our list structure 376 * 377 * Return: 0 on success, <0 on failure. 378 */ 379 int mei_irq_write_handler(struct mei_device *dev, struct list_head *cmpl_list) 380 { 381 382 struct mei_cl *cl; 383 struct mei_cl_cb *cb, *next; 384 s32 slots; 385 int ret; 386 387 388 if (!mei_hbuf_acquire(dev)) 389 return 0; 390 391 slots = mei_hbuf_empty_slots(dev); 392 if (slots < 0) 393 return -EOVERFLOW; 394 395 if (slots == 0) 396 return -EMSGSIZE; 397 398 /* complete all waiting for write CB */ 399 dev_dbg(dev->dev, "complete all waiting for write cb.\n"); 400 401 list_for_each_entry_safe(cb, next, &dev->write_waiting_list, list) { 402 cl = cb->cl; 403 404 cl->status = 0; 405 cl_dbg(dev, cl, "MEI WRITE COMPLETE\n"); 406 cl->writing_state = MEI_WRITE_COMPLETE; 407 list_move_tail(&cb->list, cmpl_list); 408 } 409 410 /* complete control write list CB */ 411 dev_dbg(dev->dev, "complete control write list cb.\n"); 412 list_for_each_entry_safe(cb, next, &dev->ctrl_wr_list, list) { 413 cl = cb->cl; 414 switch (cb->fop_type) { 415 case MEI_FOP_DISCONNECT: 416 /* send disconnect message */ 417 ret = mei_cl_irq_disconnect(cl, cb, cmpl_list); 418 if (ret) 419 return ret; 420 421 break; 422 case MEI_FOP_READ: 423 /* send flow control message */ 424 ret = mei_cl_irq_read(cl, cb, cmpl_list); 425 if (ret) 426 return ret; 427 428 break; 429 case MEI_FOP_CONNECT: 430 /* connect message */ 431 ret = mei_cl_irq_connect(cl, cb, cmpl_list); 432 if (ret) 433 return ret; 434 435 break; 436 case MEI_FOP_DISCONNECT_RSP: 437 /* send disconnect resp */ 438 ret = mei_cl_irq_disconnect_rsp(cl, cb, cmpl_list); 439 if (ret) 440 return ret; 441 break; 442 443 case MEI_FOP_NOTIFY_START: 444 case MEI_FOP_NOTIFY_STOP: 445 ret = mei_cl_irq_notify(cl, cb, cmpl_list); 446 if (ret) 447 return ret; 448 break; 449 default: 450 BUG(); 451 } 452 453 } 454 /* complete write list CB */ 455 dev_dbg(dev->dev, "complete write list cb.\n"); 456 list_for_each_entry_safe(cb, next, &dev->write_list, list) { 457 cl = cb->cl; 458 ret = mei_cl_irq_write(cl, cb, cmpl_list); 459 if (ret) 460 return ret; 461 } 462 return 0; 463 } 464 EXPORT_SYMBOL_GPL(mei_irq_write_handler); 465 466 467 /** 468 * mei_connect_timeout - connect/disconnect timeouts 469 * 470 * @cl: host client 471 */ 472 static void mei_connect_timeout(struct mei_cl *cl) 473 { 474 struct mei_device *dev = cl->dev; 475 476 if (cl->state == MEI_FILE_CONNECTING) { 477 if (dev->hbm_f_dot_supported) { 478 cl->state = MEI_FILE_DISCONNECT_REQUIRED; 479 wake_up(&cl->wait); 480 return; 481 } 482 } 483 mei_reset(dev); 484 } 485 486 #define MEI_STALL_TIMER_FREQ (2 * HZ) 487 /** 488 * mei_schedule_stall_timer - re-arm stall_timer work 489 * 490 * Schedule stall timer 491 * 492 * @dev: the device structure 493 */ 494 void mei_schedule_stall_timer(struct mei_device *dev) 495 { 496 schedule_delayed_work(&dev->timer_work, MEI_STALL_TIMER_FREQ); 497 } 498 499 /** 500 * mei_timer - timer function. 501 * 502 * @work: pointer to the work_struct structure 503 * 504 */ 505 void mei_timer(struct work_struct *work) 506 { 507 struct mei_cl *cl; 508 struct mei_device *dev = container_of(work, 509 struct mei_device, timer_work.work); 510 bool reschedule_timer = false; 511 512 mutex_lock(&dev->device_lock); 513 514 /* Catch interrupt stalls during HBM init handshake */ 515 if (dev->dev_state == MEI_DEV_INIT_CLIENTS && 516 dev->hbm_state != MEI_HBM_IDLE) { 517 518 if (dev->init_clients_timer) { 519 if (--dev->init_clients_timer == 0) { 520 dev_err(dev->dev, "timer: init clients timeout hbm_state = %d.\n", 521 dev->hbm_state); 522 mei_reset(dev); 523 goto out; 524 } 525 reschedule_timer = true; 526 } 527 } 528 529 if (dev->dev_state != MEI_DEV_ENABLED) 530 goto out; 531 532 /*** connect/disconnect timeouts ***/ 533 list_for_each_entry(cl, &dev->file_list, link) { 534 if (cl->timer_count) { 535 if (--cl->timer_count == 0) { 536 dev_err(dev->dev, "timer: connect/disconnect timeout.\n"); 537 mei_connect_timeout(cl); 538 goto out; 539 } 540 reschedule_timer = true; 541 } 542 } 543 544 out: 545 if (dev->dev_state != MEI_DEV_DISABLED && reschedule_timer) 546 mei_schedule_stall_timer(dev); 547 548 mutex_unlock(&dev->device_lock); 549 } 550