3 * Intel Management Engine Interface (Intel MEI) Linux driver
4 * Copyright (c) 2003-2012, Intel Corporation.
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.
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
17 #include <linux/pci.h>
18 #include <linux/sched.h>
19 #include <linux/wait.h>
20 #include <linux/delay.h>
24 #include "interface.h"
25 #include <linux/mei.h>
27 const char *mei_dev_state_str(int state
)
29 #define MEI_DEV_STATE(state) case MEI_DEV_##state: return #state
31 MEI_DEV_STATE(INITIALIZING
);
32 MEI_DEV_STATE(INIT_CLIENTS
);
33 MEI_DEV_STATE(ENABLED
);
34 MEI_DEV_STATE(RESETING
);
35 MEI_DEV_STATE(DISABLED
);
36 MEI_DEV_STATE(RECOVERING_FROM_RESET
);
37 MEI_DEV_STATE(POWER_DOWN
);
38 MEI_DEV_STATE(POWER_UP
);
48 * mei_io_list_flush - removes list entry belonging to cl.
50 * @list: An instance of our list structure
51 * @cl: private data of the file object
53 void mei_io_list_flush(struct mei_cl_cb
*list
, struct mei_cl
*cl
)
55 struct mei_cl_cb
*pos
;
56 struct mei_cl_cb
*next
;
58 list_for_each_entry_safe(pos
, next
, &list
->list
, list
) {
60 if (mei_cl_cmp_id(cl
, pos
->cl
))
66 * mei_cl_flush_queues - flushes queue lists belonging to cl.
68 * @dev: the device structure
69 * @cl: private data of the file object
71 int mei_cl_flush_queues(struct mei_cl
*cl
)
76 dev_dbg(&cl
->dev
->pdev
->dev
, "remove list entry belonging to cl\n");
77 mei_io_list_flush(&cl
->dev
->read_list
, cl
);
78 mei_io_list_flush(&cl
->dev
->write_list
, cl
);
79 mei_io_list_flush(&cl
->dev
->write_waiting_list
, cl
);
80 mei_io_list_flush(&cl
->dev
->ctrl_wr_list
, cl
);
81 mei_io_list_flush(&cl
->dev
->ctrl_rd_list
, cl
);
82 mei_io_list_flush(&cl
->dev
->amthif_cmd_list
, cl
);
83 mei_io_list_flush(&cl
->dev
->amthif_rd_complete_list
, cl
);
90 * init_mei_device - allocates and initializes the mei device structure
92 * @pdev: The pci device structure
94 * returns The mei_device_device pointer on success, NULL on failure.
96 struct mei_device
*mei_device_init(struct pci_dev
*pdev
)
98 struct mei_device
*dev
;
100 dev
= kzalloc(sizeof(struct mei_device
), GFP_KERNEL
);
104 /* setup our list array */
105 INIT_LIST_HEAD(&dev
->file_list
);
106 INIT_LIST_HEAD(&dev
->wd_cl
.link
);
107 INIT_LIST_HEAD(&dev
->iamthif_cl
.link
);
108 mutex_init(&dev
->device_lock
);
109 init_waitqueue_head(&dev
->wait_recvd_msg
);
110 init_waitqueue_head(&dev
->wait_stop_wd
);
111 dev
->dev_state
= MEI_DEV_INITIALIZING
;
112 dev
->iamthif_state
= MEI_IAMTHIF_IDLE
;
114 mei_io_list_init(&dev
->read_list
);
115 mei_io_list_init(&dev
->write_list
);
116 mei_io_list_init(&dev
->write_waiting_list
);
117 mei_io_list_init(&dev
->ctrl_wr_list
);
118 mei_io_list_init(&dev
->ctrl_rd_list
);
119 mei_io_list_init(&dev
->amthif_cmd_list
);
120 mei_io_list_init(&dev
->amthif_rd_complete_list
);
126 * mei_hw_init - initializes host and fw to start work.
128 * @dev: the device structure
130 * returns 0 on success, <0 on failure.
132 int mei_hw_init(struct mei_device
*dev
)
137 mutex_lock(&dev
->device_lock
);
139 dev
->host_hw_state
= mei_hcsr_read(dev
);
140 dev
->me_hw_state
= mei_mecsr_read(dev
);
141 dev_dbg(&dev
->pdev
->dev
, "host_hw_state = 0x%08x, mestate = 0x%08x.\n",
142 dev
->host_hw_state
, dev
->me_hw_state
);
144 /* acknowledge interrupt and stop interupts */
145 if ((dev
->host_hw_state
& H_IS
) == H_IS
)
146 mei_reg_write(dev
, H_CSR
, dev
->host_hw_state
);
148 /* Doesn't change in runtime */
149 dev
->hbuf_depth
= (dev
->host_hw_state
& H_CBD
) >> 24;
151 dev
->recvd_msg
= false;
152 dev_dbg(&dev
->pdev
->dev
, "reset in start the mei device.\n");
156 dev_dbg(&dev
->pdev
->dev
, "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
157 dev
->host_hw_state
, dev
->me_hw_state
);
159 /* wait for ME to turn on ME_RDY */
160 if (!dev
->recvd_msg
) {
161 mutex_unlock(&dev
->device_lock
);
162 err
= wait_event_interruptible_timeout(dev
->wait_recvd_msg
,
164 mei_secs_to_jiffies(MEI_INTEROP_TIMEOUT
));
165 mutex_lock(&dev
->device_lock
);
168 if (err
<= 0 && !dev
->recvd_msg
) {
169 dev
->dev_state
= MEI_DEV_DISABLED
;
170 dev_dbg(&dev
->pdev
->dev
,
171 "wait_event_interruptible_timeout failed"
172 "on wait for ME to turn on ME_RDY.\n");
177 if (!(((dev
->host_hw_state
& H_RDY
) == H_RDY
) &&
178 ((dev
->me_hw_state
& ME_RDY_HRA
) == ME_RDY_HRA
))) {
179 dev
->dev_state
= MEI_DEV_DISABLED
;
180 dev_dbg(&dev
->pdev
->dev
,
181 "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
182 dev
->host_hw_state
, dev
->me_hw_state
);
184 if (!(dev
->host_hw_state
& H_RDY
))
185 dev_dbg(&dev
->pdev
->dev
, "host turn off H_RDY.\n");
187 if (!(dev
->me_hw_state
& ME_RDY_HRA
))
188 dev_dbg(&dev
->pdev
->dev
, "ME turn off ME_RDY.\n");
190 dev_err(&dev
->pdev
->dev
, "link layer initialization failed.\n");
195 if (dev
->version
.major_version
!= HBM_MAJOR_VERSION
||
196 dev
->version
.minor_version
!= HBM_MINOR_VERSION
) {
197 dev_dbg(&dev
->pdev
->dev
, "MEI start failed.\n");
202 dev
->recvd_msg
= false;
203 dev_dbg(&dev
->pdev
->dev
, "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
204 dev
->host_hw_state
, dev
->me_hw_state
);
205 dev_dbg(&dev
->pdev
->dev
, "ME turn on ME_RDY and host turn on H_RDY.\n");
206 dev_dbg(&dev
->pdev
->dev
, "link layer has been established.\n");
207 dev_dbg(&dev
->pdev
->dev
, "MEI start success.\n");
211 mutex_unlock(&dev
->device_lock
);
216 * mei_hw_reset - resets fw via mei csr register.
218 * @dev: the device structure
219 * @interrupts_enabled: if interrupt should be enabled after reset.
221 static void mei_hw_reset(struct mei_device
*dev
, int interrupts_enabled
)
223 dev
->host_hw_state
|= (H_RST
| H_IG
);
225 if (interrupts_enabled
)
226 mei_enable_interrupts(dev
);
228 mei_disable_interrupts(dev
);
232 * mei_reset - resets host and fw.
234 * @dev: the device structure
235 * @interrupts_enabled: if interrupt should be enabled after reset.
237 void mei_reset(struct mei_device
*dev
, int interrupts_enabled
)
239 struct mei_cl
*cl_pos
= NULL
;
240 struct mei_cl
*cl_next
= NULL
;
241 struct mei_cl_cb
*cb_pos
= NULL
;
242 struct mei_cl_cb
*cb_next
= NULL
;
245 if (dev
->dev_state
== MEI_DEV_RECOVERING_FROM_RESET
) {
246 dev
->need_reset
= true;
250 unexpected
= (dev
->dev_state
!= MEI_DEV_INITIALIZING
&&
251 dev
->dev_state
!= MEI_DEV_DISABLED
&&
252 dev
->dev_state
!= MEI_DEV_POWER_DOWN
&&
253 dev
->dev_state
!= MEI_DEV_POWER_UP
);
255 dev
->host_hw_state
= mei_hcsr_read(dev
);
257 dev_dbg(&dev
->pdev
->dev
, "before reset host_hw_state = 0x%08x.\n",
260 mei_hw_reset(dev
, interrupts_enabled
);
262 dev
->host_hw_state
&= ~H_RST
;
263 dev
->host_hw_state
|= H_IG
;
267 dev_dbg(&dev
->pdev
->dev
, "currently saved host_hw_state = 0x%08x.\n",
270 dev
->need_reset
= false;
272 if (dev
->dev_state
!= MEI_DEV_INITIALIZING
) {
273 if (dev
->dev_state
!= MEI_DEV_DISABLED
&&
274 dev
->dev_state
!= MEI_DEV_POWER_DOWN
)
275 dev
->dev_state
= MEI_DEV_RESETING
;
277 list_for_each_entry_safe(cl_pos
,
278 cl_next
, &dev
->file_list
, link
) {
279 cl_pos
->state
= MEI_FILE_DISCONNECTED
;
280 cl_pos
->mei_flow_ctrl_creds
= 0;
281 cl_pos
->read_cb
= NULL
;
282 cl_pos
->timer_count
= 0;
284 /* remove entry if already in list */
285 dev_dbg(&dev
->pdev
->dev
, "remove iamthif and wd from the file list.\n");
286 mei_me_cl_unlink(dev
, &dev
->wd_cl
);
288 mei_me_cl_unlink(dev
, &dev
->iamthif_cl
);
290 mei_amthif_reset_params(dev
);
291 memset(&dev
->wr_ext_msg
, 0, sizeof(dev
->wr_ext_msg
));
294 dev
->me_clients_num
= 0;
296 dev
->wd_pending
= false;
298 /* update the state of the registers after reset */
299 dev
->host_hw_state
= mei_hcsr_read(dev
);
300 dev
->me_hw_state
= mei_mecsr_read(dev
);
302 dev_dbg(&dev
->pdev
->dev
, "after reset host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
303 dev
->host_hw_state
, dev
->me_hw_state
);
306 dev_warn(&dev
->pdev
->dev
, "unexpected reset: dev_state = %s\n",
307 mei_dev_state_str(dev
->dev_state
));
309 /* Wake up all readings so they can be interrupted */
310 list_for_each_entry_safe(cl_pos
, cl_next
, &dev
->file_list
, link
) {
311 if (waitqueue_active(&cl_pos
->rx_wait
)) {
312 dev_dbg(&dev
->pdev
->dev
, "Waking up client!\n");
313 wake_up_interruptible(&cl_pos
->rx_wait
);
316 /* remove all waiting requests */
317 list_for_each_entry_safe(cb_pos
, cb_next
, &dev
->write_list
.list
, list
) {
318 list_del(&cb_pos
->list
);
319 mei_io_cb_free(cb_pos
);
326 * host_start_message - mei host sends start message.
328 * @dev: the device structure
332 void mei_host_start_message(struct mei_device
*dev
)
334 struct mei_msg_hdr
*mei_hdr
;
335 struct hbm_host_version_request
*start_req
;
336 const size_t len
= sizeof(struct hbm_host_version_request
);
338 mei_hdr
= mei_hbm_hdr(&dev
->wr_msg_buf
[0], len
);
340 /* host start message */
341 start_req
= (struct hbm_host_version_request
*)&dev
->wr_msg_buf
[1];
342 memset(start_req
, 0, len
);
343 start_req
->hbm_cmd
= HOST_START_REQ_CMD
;
344 start_req
->host_version
.major_version
= HBM_MAJOR_VERSION
;
345 start_req
->host_version
.minor_version
= HBM_MINOR_VERSION
;
347 dev
->recvd_msg
= false;
348 if (mei_write_message(dev
, mei_hdr
, (unsigned char *)start_req
, len
)) {
349 dev_dbg(&dev
->pdev
->dev
, "write send version message to FW fail.\n");
350 dev
->dev_state
= MEI_DEV_RESETING
;
353 dev
->init_clients_state
= MEI_START_MESSAGE
;
354 dev
->init_clients_timer
= MEI_CLIENTS_INIT_TIMEOUT
;
359 * host_enum_clients_message - host sends enumeration client request message.
361 * @dev: the device structure
365 void mei_host_enum_clients_message(struct mei_device
*dev
)
367 struct mei_msg_hdr
*mei_hdr
;
368 struct hbm_host_enum_request
*enum_req
;
369 const size_t len
= sizeof(struct hbm_host_enum_request
);
370 /* enumerate clients */
371 mei_hdr
= mei_hbm_hdr(&dev
->wr_msg_buf
[0], len
);
373 enum_req
= (struct hbm_host_enum_request
*) &dev
->wr_msg_buf
[1];
374 memset(enum_req
, 0, sizeof(struct hbm_host_enum_request
));
375 enum_req
->hbm_cmd
= HOST_ENUM_REQ_CMD
;
377 if (mei_write_message(dev
, mei_hdr
, (unsigned char *)enum_req
, len
)) {
378 dev
->dev_state
= MEI_DEV_RESETING
;
379 dev_dbg(&dev
->pdev
->dev
, "write send enumeration request message to FW fail.\n");
382 dev
->init_clients_state
= MEI_ENUM_CLIENTS_MESSAGE
;
383 dev
->init_clients_timer
= MEI_CLIENTS_INIT_TIMEOUT
;
389 * allocate_me_clients_storage - allocates storage for me clients
391 * @dev: the device structure
395 void mei_allocate_me_clients_storage(struct mei_device
*dev
)
397 struct mei_me_client
*clients
;
400 /* count how many ME clients we have */
401 for_each_set_bit(b
, dev
->me_clients_map
, MEI_CLIENTS_MAX
)
402 dev
->me_clients_num
++;
404 if (dev
->me_clients_num
<= 0)
408 if (dev
->me_clients
!= NULL
) {
409 kfree(dev
->me_clients
);
410 dev
->me_clients
= NULL
;
412 dev_dbg(&dev
->pdev
->dev
, "memory allocation for ME clients size=%zd.\n",
413 dev
->me_clients_num
* sizeof(struct mei_me_client
));
414 /* allocate storage for ME clients representation */
415 clients
= kcalloc(dev
->me_clients_num
,
416 sizeof(struct mei_me_client
), GFP_KERNEL
);
418 dev_dbg(&dev
->pdev
->dev
, "memory allocation for ME clients failed.\n");
419 dev
->dev_state
= MEI_DEV_RESETING
;
423 dev
->me_clients
= clients
;
427 void mei_host_client_init(struct work_struct
*work
)
429 struct mei_device
*dev
= container_of(work
,
430 struct mei_device
, init_work
);
431 struct mei_client_properties
*client_props
;
434 mutex_lock(&dev
->device_lock
);
436 bitmap_zero(dev
->host_clients_map
, MEI_CLIENTS_MAX
);
437 dev
->open_handle_count
= 0;
440 * Reserving the first three client IDs
441 * 0: Reserved for MEI Bus Message communications
442 * 1: Reserved for Watchdog
443 * 2: Reserved for AMTHI
445 bitmap_set(dev
->host_clients_map
, 0, 3);
447 for (i
= 0; i
< dev
->me_clients_num
; i
++) {
448 client_props
= &dev
->me_clients
[i
].props
;
450 if (!uuid_le_cmp(client_props
->protocol_name
, mei_amthi_guid
))
451 mei_amthif_host_init(dev
);
452 else if (!uuid_le_cmp(client_props
->protocol_name
, mei_wd_guid
))
453 mei_wd_host_init(dev
);
456 dev
->dev_state
= MEI_DEV_ENABLED
;
458 mutex_unlock(&dev
->device_lock
);
461 int mei_host_client_enumerate(struct mei_device
*dev
)
464 struct mei_msg_hdr
*mei_hdr
;
465 struct hbm_props_request
*prop_req
;
466 const size_t len
= sizeof(struct hbm_props_request
);
467 unsigned long next_client_index
;
471 client_num
= dev
->me_client_presentation_num
;
473 next_client_index
= find_next_bit(dev
->me_clients_map
, MEI_CLIENTS_MAX
,
474 dev
->me_client_index
);
476 /* We got all client properties */
477 if (next_client_index
== MEI_CLIENTS_MAX
) {
478 schedule_work(&dev
->init_work
);
483 dev
->me_clients
[client_num
].client_id
= next_client_index
;
484 dev
->me_clients
[client_num
].mei_flow_ctrl_creds
= 0;
486 mei_hdr
= mei_hbm_hdr(&dev
->wr_msg_buf
[0], len
);
487 prop_req
= (struct hbm_props_request
*)&dev
->wr_msg_buf
[1];
489 memset(prop_req
, 0, sizeof(struct hbm_props_request
));
492 prop_req
->hbm_cmd
= HOST_CLIENT_PROPERTIES_REQ_CMD
;
493 prop_req
->address
= next_client_index
;
495 if (mei_write_message(dev
, mei_hdr
, (unsigned char *) prop_req
,
497 dev
->dev_state
= MEI_DEV_RESETING
;
498 dev_err(&dev
->pdev
->dev
, "Properties request command failed\n");
504 dev
->init_clients_timer
= MEI_CLIENTS_INIT_TIMEOUT
;
505 dev
->me_client_index
= next_client_index
;
511 * mei_init_file_private - initializes private file structure.
513 * @priv: private file structure to be initialized
514 * @file: the file structure
516 void mei_cl_init(struct mei_cl
*priv
, struct mei_device
*dev
)
518 memset(priv
, 0, sizeof(struct mei_cl
));
519 init_waitqueue_head(&priv
->wait
);
520 init_waitqueue_head(&priv
->rx_wait
);
521 init_waitqueue_head(&priv
->tx_wait
);
522 INIT_LIST_HEAD(&priv
->link
);
523 priv
->reading_state
= MEI_IDLE
;
524 priv
->writing_state
= MEI_IDLE
;
528 int mei_me_cl_by_uuid(const struct mei_device
*dev
, const uuid_le
*cuuid
)
530 int i
, res
= -ENOENT
;
532 for (i
= 0; i
< dev
->me_clients_num
; ++i
)
533 if (uuid_le_cmp(*cuuid
,
534 dev
->me_clients
[i
].props
.protocol_name
) == 0) {
544 * mei_me_cl_link - create link between host and me clinet and add
547 * @dev: the device structure
548 * @cl: link between me and host client assocated with opened file descriptor
549 * @cuuid: uuid of ME client
550 * @client_id: id of the host client
552 * returns ME client index if ME client
553 * -EINVAL on incorrect values
554 * -ENONET if client not found
556 int mei_me_cl_link(struct mei_device
*dev
, struct mei_cl
*cl
,
557 const uuid_le
*cuuid
, u8 host_cl_id
)
561 if (!dev
|| !cl
|| !cuuid
)
564 /* check for valid client id */
565 i
= mei_me_cl_by_uuid(dev
, cuuid
);
567 cl
->me_client_id
= dev
->me_clients
[i
].client_id
;
568 cl
->state
= MEI_FILE_CONNECTING
;
569 cl
->host_client_id
= host_cl_id
;
571 list_add_tail(&cl
->link
, &dev
->file_list
);
578 * mei_me_cl_unlink - remove me_cl from the list
580 * @dev: the device structure
581 * @host_client_id: host client id to be removed
583 void mei_me_cl_unlink(struct mei_device
*dev
, struct mei_cl
*cl
)
585 struct mei_cl
*pos
, *next
;
586 list_for_each_entry_safe(pos
, next
, &dev
->file_list
, link
) {
587 if (cl
->host_client_id
== pos
->host_client_id
) {
588 dev_dbg(&dev
->pdev
->dev
, "remove host client = %d, ME client = %d\n",
589 pos
->host_client_id
, pos
->me_client_id
);
590 list_del_init(&pos
->link
);
597 * mei_alloc_file_private - allocates a private file structure and sets it up.
598 * @file: the file structure
600 * returns The allocated file or NULL on failure
602 struct mei_cl
*mei_cl_allocate(struct mei_device
*dev
)
606 cl
= kmalloc(sizeof(struct mei_cl
), GFP_KERNEL
);
610 mei_cl_init(cl
, dev
);
618 * mei_disconnect_host_client - sends disconnect message to fw from host client.
620 * @dev: the device structure
621 * @cl: private data of the file object
623 * Locking: called under "dev->device_lock" lock
625 * returns 0 on success, <0 on failure.
627 int mei_disconnect_host_client(struct mei_device
*dev
, struct mei_cl
*cl
)
629 struct mei_cl_cb
*cb
;
635 if (cl
->state
!= MEI_FILE_DISCONNECTING
)
638 cb
= mei_io_cb_init(cl
, NULL
);
642 cb
->fop_type
= MEI_FOP_CLOSE
;
643 if (dev
->mei_host_buffer_is_empty
) {
644 dev
->mei_host_buffer_is_empty
= false;
645 if (mei_disconnect(dev
, cl
)) {
647 dev_dbg(&dev
->pdev
->dev
, "failed to call mei_disconnect.\n");
650 mdelay(10); /* Wait for hardware disconnection ready */
651 list_add_tail(&cb
->list
, &dev
->ctrl_rd_list
.list
);
653 dev_dbg(&dev
->pdev
->dev
, "add disconnect cb to control write list\n");
654 list_add_tail(&cb
->list
, &dev
->ctrl_wr_list
.list
);
657 mutex_unlock(&dev
->device_lock
);
659 err
= wait_event_timeout(dev
->wait_recvd_msg
,
660 MEI_FILE_DISCONNECTED
== cl
->state
,
661 mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT
));
663 mutex_lock(&dev
->device_lock
);
664 if (MEI_FILE_DISCONNECTED
== cl
->state
) {
666 dev_dbg(&dev
->pdev
->dev
, "successfully disconnected from FW client.\n");
669 if (MEI_FILE_DISCONNECTED
!= cl
->state
)
670 dev_dbg(&dev
->pdev
->dev
, "wrong status client disconnect.\n");
673 dev_dbg(&dev
->pdev
->dev
,
674 "wait failed disconnect err=%08x\n",
677 dev_dbg(&dev
->pdev
->dev
, "failed to disconnect from FW client.\n");
680 mei_io_list_flush(&dev
->ctrl_rd_list
, cl
);
681 mei_io_list_flush(&dev
->ctrl_wr_list
, cl
);