hw-me.c (da0851fe3a8ebc416ab61ce50ef2fb3c3d7375c9) | hw-me.c (9b0d5efc421ac79d9a6d97c681eff93288093784) |
---|---|
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. --- 12 unchanged lines hidden (view full) --- 21 22#include "mei_dev.h" 23#include "hw-me.h" 24 25#include "hbm.h" 26 27 28/** | 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. --- 12 unchanged lines hidden (view full) --- 21 22#include "mei_dev.h" 23#include "hw-me.h" 24 25#include "hbm.h" 26 27 28/** |
29 * mei_reg_read - Reads 32bit data from the mei device | 29 * mei_me_reg_read - Reads 32bit data from the mei device |
30 * 31 * @dev: the device structure 32 * @offset: offset from which to read the data 33 * 34 * returns register value (u32) 35 */ | 30 * 31 * @dev: the device structure 32 * @offset: offset from which to read the data 33 * 34 * returns register value (u32) 35 */ |
36static inline u32 mei_reg_read(const struct mei_me_hw *hw, | 36static inline u32 mei_me_reg_read(const struct mei_me_hw *hw, |
37 unsigned long offset) 38{ 39 return ioread32(hw->mem_addr + offset); 40} 41 42 43/** | 37 unsigned long offset) 38{ 39 return ioread32(hw->mem_addr + offset); 40} 41 42 43/** |
44 * mei_reg_write - Writes 32bit data to the mei device | 44 * mei_me_reg_write - Writes 32bit data to the mei device |
45 * 46 * @dev: the device structure 47 * @offset: offset from which to write the data 48 * @value: register value to write (u32) 49 */ | 45 * 46 * @dev: the device structure 47 * @offset: offset from which to write the data 48 * @value: register value to write (u32) 49 */ |
50static inline void mei_reg_write(const struct mei_me_hw *hw, | 50static inline void mei_me_reg_write(const struct mei_me_hw *hw, |
51 unsigned long offset, u32 value) 52{ 53 iowrite32(value, hw->mem_addr + offset); 54} 55 56/** | 51 unsigned long offset, u32 value) 52{ 53 iowrite32(value, hw->mem_addr + offset); 54} 55 56/** |
57 * mei_mecbrw_read - Reads 32bit data from ME circular buffer | 57 * mei_me_mecbrw_read - Reads 32bit data from ME circular buffer |
58 * read window register 59 * 60 * @dev: the device structure 61 * 62 * returns ME_CB_RW register value (u32) 63 */ 64static u32 mei_me_mecbrw_read(const struct mei_device *dev) 65{ | 58 * read window register 59 * 60 * @dev: the device structure 61 * 62 * returns ME_CB_RW register value (u32) 63 */ 64static u32 mei_me_mecbrw_read(const struct mei_device *dev) 65{ |
66 return mei_reg_read(to_me_hw(dev), ME_CB_RW); | 66 return mei_me_reg_read(to_me_hw(dev), ME_CB_RW); |
67} 68/** | 67} 68/** |
69 * mei_mecsr_read - Reads 32bit data from the ME CSR | 69 * mei_me_mecsr_read - Reads 32bit data from the ME CSR |
70 * 71 * @dev: the device structure 72 * 73 * returns ME_CSR_HA register value (u32) 74 */ | 70 * 71 * @dev: the device structure 72 * 73 * returns ME_CSR_HA register value (u32) 74 */ |
75static inline u32 mei_mecsr_read(const struct mei_me_hw *hw) | 75static inline u32 mei_me_mecsr_read(const struct mei_me_hw *hw) |
76{ | 76{ |
77 return mei_reg_read(hw, ME_CSR_HA); | 77 return mei_me_reg_read(hw, ME_CSR_HA); |
78} 79 80/** 81 * mei_hcsr_read - Reads 32bit data from the host CSR 82 * 83 * @dev: the device structure 84 * 85 * returns H_CSR register value (u32) 86 */ 87static inline u32 mei_hcsr_read(const struct mei_me_hw *hw) 88{ | 78} 79 80/** 81 * mei_hcsr_read - Reads 32bit data from the host CSR 82 * 83 * @dev: the device structure 84 * 85 * returns H_CSR register value (u32) 86 */ 87static inline u32 mei_hcsr_read(const struct mei_me_hw *hw) 88{ |
89 return mei_reg_read(hw, H_CSR); | 89 return mei_me_reg_read(hw, H_CSR); |
90} 91 92/** 93 * mei_hcsr_set - writes H_CSR register to the mei device, 94 * and ignores the H_IS bit for it is write-one-to-zero. 95 * 96 * @dev: the device structure 97 */ 98static inline void mei_hcsr_set(struct mei_me_hw *hw, u32 hcsr) 99{ 100 hcsr &= ~H_IS; | 90} 91 92/** 93 * mei_hcsr_set - writes H_CSR register to the mei device, 94 * and ignores the H_IS bit for it is write-one-to-zero. 95 * 96 * @dev: the device structure 97 */ 98static inline void mei_hcsr_set(struct mei_me_hw *hw, u32 hcsr) 99{ 100 hcsr &= ~H_IS; |
101 mei_reg_write(hw, H_CSR, hcsr); | 101 mei_me_reg_write(hw, H_CSR, hcsr); |
102} 103 104 105/** 106 * me_hw_config - configure hw dependent settings 107 * 108 * @dev: mei device 109 */ --- 8 unchanged lines hidden (view full) --- 118 * 119 * @dev: the device structure 120 */ 121static void mei_me_intr_clear(struct mei_device *dev) 122{ 123 struct mei_me_hw *hw = to_me_hw(dev); 124 u32 hcsr = mei_hcsr_read(hw); 125 if ((hcsr & H_IS) == H_IS) | 102} 103 104 105/** 106 * me_hw_config - configure hw dependent settings 107 * 108 * @dev: mei device 109 */ --- 8 unchanged lines hidden (view full) --- 118 * 119 * @dev: the device structure 120 */ 121static void mei_me_intr_clear(struct mei_device *dev) 122{ 123 struct mei_me_hw *hw = to_me_hw(dev); 124 u32 hcsr = mei_hcsr_read(hw); 125 if ((hcsr & H_IS) == H_IS) |
126 mei_reg_write(hw, H_CSR, hcsr); | 126 mei_me_reg_write(hw, H_CSR, hcsr); |
127} 128/** 129 * mei_me_intr_enable - enables mei device interrupts 130 * 131 * @dev: the device structure 132 */ 133static void mei_me_intr_enable(struct mei_device *dev) 134{ --- 88 unchanged lines hidden (view full) --- 223 * mei_me_hw_is_ready - check whether the me(hw) has turned ready 224 * 225 * @dev - mei device 226 * returns bool 227 */ 228static bool mei_me_hw_is_ready(struct mei_device *dev) 229{ 230 struct mei_me_hw *hw = to_me_hw(dev); | 127} 128/** 129 * mei_me_intr_enable - enables mei device interrupts 130 * 131 * @dev: the device structure 132 */ 133static void mei_me_intr_enable(struct mei_device *dev) 134{ --- 88 unchanged lines hidden (view full) --- 223 * mei_me_hw_is_ready - check whether the me(hw) has turned ready 224 * 225 * @dev - mei device 226 * returns bool 227 */ 228static bool mei_me_hw_is_ready(struct mei_device *dev) 229{ 230 struct mei_me_hw *hw = to_me_hw(dev); |
231 hw->me_hw_state = mei_mecsr_read(hw); | 231 hw->me_hw_state = mei_me_mecsr_read(hw); |
232 return (hw->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA; 233} 234 | 232 return (hw->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA; 233} 234 |
235static int mei_me_hw_ready_wait(struct mei_device *dev) 236{ 237 int err; 238 if (mei_me_hw_is_ready(dev)) 239 return 0; 240 241 mutex_unlock(&dev->device_lock); 242 err = wait_event_interruptible_timeout(dev->wait_hw_ready, 243 dev->recvd_hw_ready, MEI_INTEROP_TIMEOUT); 244 mutex_lock(&dev->device_lock); 245 if (!err && !dev->recvd_hw_ready) { 246 dev_err(&dev->pdev->dev, 247 "wait hw ready failed. status = 0x%x\n", err); 248 return -ETIMEDOUT; 249 } 250 251 dev->recvd_hw_ready = false; 252 return 0; 253} 254 255static int mei_me_hw_start(struct mei_device *dev) 256{ 257 int ret = mei_me_hw_ready_wait(dev); 258 if (ret) 259 return ret; 260 dev_dbg(&dev->pdev->dev, "hw is ready\n"); 261 262 mei_me_host_set_ready(dev); 263 return ret; 264} 265 266 |
|
235/** 236 * mei_hbuf_filled_slots - gets number of device filled buffer slots 237 * 238 * @dev: the device structure 239 * 240 * returns number of filled slots 241 */ 242static unsigned char mei_hbuf_filled_slots(struct mei_device *dev) --- 57 unchanged lines hidden (view full) --- 300 * 301 * This function returns -EIO if write has failed 302 */ 303static int mei_me_write_message(struct mei_device *dev, 304 struct mei_msg_hdr *header, 305 unsigned char *buf) 306{ 307 struct mei_me_hw *hw = to_me_hw(dev); | 267/** 268 * mei_hbuf_filled_slots - gets number of device filled buffer slots 269 * 270 * @dev: the device structure 271 * 272 * returns number of filled slots 273 */ 274static unsigned char mei_hbuf_filled_slots(struct mei_device *dev) --- 57 unchanged lines hidden (view full) --- 332 * 333 * This function returns -EIO if write has failed 334 */ 335static int mei_me_write_message(struct mei_device *dev, 336 struct mei_msg_hdr *header, 337 unsigned char *buf) 338{ 339 struct mei_me_hw *hw = to_me_hw(dev); |
308 unsigned long rem, dw_cnt; | 340 unsigned long rem; |
309 unsigned long length = header->length; 310 u32 *reg_buf = (u32 *)buf; 311 u32 hcsr; | 341 unsigned long length = header->length; 342 u32 *reg_buf = (u32 *)buf; 343 u32 hcsr; |
344 u32 dw_cnt; |
|
312 int i; 313 int empty_slots; 314 315 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(header)); 316 317 empty_slots = mei_hbuf_empty_slots(dev); 318 dev_dbg(&dev->pdev->dev, "empty slots = %hu.\n", empty_slots); 319 320 dw_cnt = mei_data2slots(length); 321 if (empty_slots < 0 || dw_cnt > empty_slots) 322 return -EIO; 323 | 345 int i; 346 int empty_slots; 347 348 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(header)); 349 350 empty_slots = mei_hbuf_empty_slots(dev); 351 dev_dbg(&dev->pdev->dev, "empty slots = %hu.\n", empty_slots); 352 353 dw_cnt = mei_data2slots(length); 354 if (empty_slots < 0 || dw_cnt > empty_slots) 355 return -EIO; 356 |
324 mei_reg_write(hw, H_CB_WW, *((u32 *) header)); | 357 mei_me_reg_write(hw, H_CB_WW, *((u32 *) header)); |
325 326 for (i = 0; i < length / 4; i++) | 358 359 for (i = 0; i < length / 4; i++) |
327 mei_reg_write(hw, H_CB_WW, reg_buf[i]); | 360 mei_me_reg_write(hw, H_CB_WW, reg_buf[i]); |
328 329 rem = length & 0x3; 330 if (rem > 0) { 331 u32 reg = 0; 332 memcpy(®, &buf[length - rem], rem); | 361 362 rem = length & 0x3; 363 if (rem > 0) { 364 u32 reg = 0; 365 memcpy(®, &buf[length - rem], rem); |
333 mei_reg_write(hw, H_CB_WW, reg); | 366 mei_me_reg_write(hw, H_CB_WW, reg); |
334 } 335 336 hcsr = mei_hcsr_read(hw) | H_IG; 337 mei_hcsr_set(hw, hcsr); 338 if (!mei_me_hw_is_ready(dev)) 339 return -EIO; 340 341 return 0; --- 7 unchanged lines hidden (view full) --- 349 * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise filled slots count 350 */ 351static int mei_me_count_full_read_slots(struct mei_device *dev) 352{ 353 struct mei_me_hw *hw = to_me_hw(dev); 354 char read_ptr, write_ptr; 355 unsigned char buffer_depth, filled_slots; 356 | 367 } 368 369 hcsr = mei_hcsr_read(hw) | H_IG; 370 mei_hcsr_set(hw, hcsr); 371 if (!mei_me_hw_is_ready(dev)) 372 return -EIO; 373 374 return 0; --- 7 unchanged lines hidden (view full) --- 382 * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise filled slots count 383 */ 384static int mei_me_count_full_read_slots(struct mei_device *dev) 385{ 386 struct mei_me_hw *hw = to_me_hw(dev); 387 char read_ptr, write_ptr; 388 unsigned char buffer_depth, filled_slots; 389 |
357 hw->me_hw_state = mei_mecsr_read(hw); | 390 hw->me_hw_state = mei_me_mecsr_read(hw); |
358 buffer_depth = (unsigned char)((hw->me_hw_state & ME_CBD_HRA) >> 24); 359 read_ptr = (char) ((hw->me_hw_state & ME_CBRP_HRA) >> 8); 360 write_ptr = (char) ((hw->me_hw_state & ME_CBWP_HRA) >> 16); 361 filled_slots = (unsigned char) (write_ptr - read_ptr); 362 363 /* check for overflow */ 364 if (filled_slots > buffer_depth) 365 return -EOVERFLOW; --- 43 unchanged lines hidden (view full) --- 409 struct mei_device *dev = (struct mei_device *) dev_id; 410 struct mei_me_hw *hw = to_me_hw(dev); 411 u32 csr_reg = mei_hcsr_read(hw); 412 413 if ((csr_reg & H_IS) != H_IS) 414 return IRQ_NONE; 415 416 /* clear H_IS bit in H_CSR */ | 391 buffer_depth = (unsigned char)((hw->me_hw_state & ME_CBD_HRA) >> 24); 392 read_ptr = (char) ((hw->me_hw_state & ME_CBRP_HRA) >> 8); 393 write_ptr = (char) ((hw->me_hw_state & ME_CBWP_HRA) >> 16); 394 filled_slots = (unsigned char) (write_ptr - read_ptr); 395 396 /* check for overflow */ 397 if (filled_slots > buffer_depth) 398 return -EOVERFLOW; --- 43 unchanged lines hidden (view full) --- 442 struct mei_device *dev = (struct mei_device *) dev_id; 443 struct mei_me_hw *hw = to_me_hw(dev); 444 u32 csr_reg = mei_hcsr_read(hw); 445 446 if ((csr_reg & H_IS) != H_IS) 447 return IRQ_NONE; 448 449 /* clear H_IS bit in H_CSR */ |
417 mei_reg_write(hw, H_CSR, csr_reg); | 450 mei_me_reg_write(hw, H_CSR, csr_reg); |
418 419 return IRQ_WAKE_THREAD; 420} 421 422/** 423 * mei_me_irq_thread_handler - function called after ISR to handle the interrupt 424 * processing. 425 * 426 * @irq: The irq number 427 * @dev_id: pointer to the device structure 428 * 429 * returns irqreturn_t 430 * 431 */ 432irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id) 433{ 434 struct mei_device *dev = (struct mei_device *) dev_id; 435 struct mei_cl_cb complete_list; | 451 452 return IRQ_WAKE_THREAD; 453} 454 455/** 456 * mei_me_irq_thread_handler - function called after ISR to handle the interrupt 457 * processing. 458 * 459 * @irq: The irq number 460 * @dev_id: pointer to the device structure 461 * 462 * returns irqreturn_t 463 * 464 */ 465irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id) 466{ 467 struct mei_device *dev = (struct mei_device *) dev_id; 468 struct mei_cl_cb complete_list; |
436 struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; 437 struct mei_cl *cl; | |
438 s32 slots; 439 int rets; | 469 s32 slots; 470 int rets; |
440 bool bus_message_received; | |
441 | 471 |
442 | |
443 dev_dbg(&dev->pdev->dev, "function called after ISR to handle the interrupt processing.\n"); 444 /* initialize our complete list */ 445 mutex_lock(&dev->device_lock); 446 mei_io_list_init(&complete_list); 447 448 /* Ack the interrupt here 449 * In case of MSI we don't go through the quick handler */ 450 if (pci_dev_msi_enabled(dev->pdev)) --- 9 unchanged lines hidden (view full) --- 460 return IRQ_HANDLED; 461 } 462 463 /* check if we need to start the dev */ 464 if (!mei_host_is_ready(dev)) { 465 if (mei_hw_is_ready(dev)) { 466 dev_dbg(&dev->pdev->dev, "we need to start the dev.\n"); 467 | 472 dev_dbg(&dev->pdev->dev, "function called after ISR to handle the interrupt processing.\n"); 473 /* initialize our complete list */ 474 mutex_lock(&dev->device_lock); 475 mei_io_list_init(&complete_list); 476 477 /* Ack the interrupt here 478 * In case of MSI we don't go through the quick handler */ 479 if (pci_dev_msi_enabled(dev->pdev)) --- 9 unchanged lines hidden (view full) --- 489 return IRQ_HANDLED; 490 } 491 492 /* check if we need to start the dev */ 493 if (!mei_host_is_ready(dev)) { 494 if (mei_hw_is_ready(dev)) { 495 dev_dbg(&dev->pdev->dev, "we need to start the dev.\n"); 496 |
468 mei_host_set_ready(dev); | 497 dev->recvd_hw_ready = true; 498 wake_up_interruptible(&dev->wait_hw_ready); |
469 | 499 |
470 dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n"); 471 /* link is established * start sending messages. */ 472 473 dev->dev_state = MEI_DEV_INIT_CLIENTS; 474 475 mei_hbm_start_req(dev); | |
476 mutex_unlock(&dev->device_lock); 477 return IRQ_HANDLED; 478 } else { 479 dev_dbg(&dev->pdev->dev, "Reset Completed.\n"); 480 mei_me_hw_reset_release(dev); 481 mutex_unlock(&dev->device_lock); 482 return IRQ_HANDLED; 483 } --- 10 unchanged lines hidden (view full) --- 494 if (rets) 495 goto end; 496 } 497 rets = mei_irq_write_handler(dev, &complete_list); 498end: 499 dev_dbg(&dev->pdev->dev, "end of bottom half function.\n"); 500 dev->hbuf_is_ready = mei_hbuf_is_ready(dev); 501 | 500 mutex_unlock(&dev->device_lock); 501 return IRQ_HANDLED; 502 } else { 503 dev_dbg(&dev->pdev->dev, "Reset Completed.\n"); 504 mei_me_hw_reset_release(dev); 505 mutex_unlock(&dev->device_lock); 506 return IRQ_HANDLED; 507 } --- 10 unchanged lines hidden (view full) --- 518 if (rets) 519 goto end; 520 } 521 rets = mei_irq_write_handler(dev, &complete_list); 522end: 523 dev_dbg(&dev->pdev->dev, "end of bottom half function.\n"); 524 dev->hbuf_is_ready = mei_hbuf_is_ready(dev); 525 |
502 bus_message_received = false; 503 if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) { 504 dev_dbg(&dev->pdev->dev, "received waiting bus message\n"); 505 bus_message_received = true; 506 } | |
507 mutex_unlock(&dev->device_lock); | 526 mutex_unlock(&dev->device_lock); |
508 if (bus_message_received) { 509 dev_dbg(&dev->pdev->dev, "wake up dev->wait_recvd_msg\n"); 510 wake_up_interruptible(&dev->wait_recvd_msg); 511 bus_message_received = false; 512 } 513 if (list_empty(&complete_list.list)) 514 return IRQ_HANDLED; | |
515 | 527 |
528 mei_irq_compl_handler(dev, &complete_list); |
|
516 | 529 |
517 list_for_each_entry_safe(cb_pos, cb_next, &complete_list.list, list) { 518 cl = cb_pos->cl; 519 list_del(&cb_pos->list); 520 if (cl) { 521 if (cl != &dev->iamthif_cl) { 522 dev_dbg(&dev->pdev->dev, "completing call back.\n"); 523 mei_irq_complete_handler(cl, cb_pos); 524 cb_pos = NULL; 525 } else if (cl == &dev->iamthif_cl) { 526 mei_amthif_complete(dev, cb_pos); 527 } 528 } 529 } | |
530 return IRQ_HANDLED; 531} 532static const struct mei_hw_ops mei_me_hw_ops = { 533 | 530 return IRQ_HANDLED; 531} 532static const struct mei_hw_ops mei_me_hw_ops = { 533 |
534 .host_set_ready = mei_me_host_set_ready, | |
535 .host_is_ready = mei_me_host_is_ready, 536 537 .hw_is_ready = mei_me_hw_is_ready, 538 .hw_reset = mei_me_hw_reset, | 534 .host_is_ready = mei_me_host_is_ready, 535 536 .hw_is_ready = mei_me_hw_is_ready, 537 .hw_reset = mei_me_hw_reset, |
539 .hw_config = mei_me_hw_config, | 538 .hw_config = mei_me_hw_config, 539 .hw_start = mei_me_hw_start, |
540 541 .intr_clear = mei_me_intr_clear, 542 .intr_enable = mei_me_intr_enable, 543 .intr_disable = mei_me_intr_disable, 544 545 .hbuf_free_slots = mei_me_hbuf_empty_slots, 546 .hbuf_is_ready = mei_me_hbuf_is_empty, 547 .hbuf_max_len = mei_me_hbuf_max_len, --- 18 unchanged lines hidden (view full) --- 566 567 dev = kzalloc(sizeof(struct mei_device) + 568 sizeof(struct mei_me_hw), GFP_KERNEL); 569 if (!dev) 570 return NULL; 571 572 mei_device_init(dev); 573 | 540 541 .intr_clear = mei_me_intr_clear, 542 .intr_enable = mei_me_intr_enable, 543 .intr_disable = mei_me_intr_disable, 544 545 .hbuf_free_slots = mei_me_hbuf_empty_slots, 546 .hbuf_is_ready = mei_me_hbuf_is_empty, 547 .hbuf_max_len = mei_me_hbuf_max_len, --- 18 unchanged lines hidden (view full) --- 566 567 dev = kzalloc(sizeof(struct mei_device) + 568 sizeof(struct mei_me_hw), GFP_KERNEL); 569 if (!dev) 570 return NULL; 571 572 mei_device_init(dev); 573 |
574 INIT_LIST_HEAD(&dev->wd_cl.link); 575 INIT_LIST_HEAD(&dev->iamthif_cl.link); 576 mei_io_list_init(&dev->amthif_cmd_list); 577 mei_io_list_init(&dev->amthif_rd_complete_list); 578 579 INIT_DELAYED_WORK(&dev->timer_work, mei_timer); 580 INIT_WORK(&dev->init_work, mei_host_client_init); 581 | |
582 dev->ops = &mei_me_hw_ops; 583 584 dev->pdev = pdev; 585 return dev; 586} 587 | 574 dev->ops = &mei_me_hw_ops; 575 576 dev->pdev = pdev; 577 return dev; 578} 579 |