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>
22 #include <linux/mei.h>
25 #include "interface.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
);
49 * init_mei_device - allocates and initializes the mei device structure
51 * @pdev: The pci device structure
53 * returns The mei_device_device pointer on success, NULL on failure.
55 struct mei_device
*mei_device_init(struct pci_dev
*pdev
)
57 struct mei_device
*dev
;
59 dev
= kzalloc(sizeof(struct mei_device
), GFP_KERNEL
);
63 /* setup our list array */
64 INIT_LIST_HEAD(&dev
->file_list
);
65 INIT_LIST_HEAD(&dev
->wd_cl
.link
);
66 INIT_LIST_HEAD(&dev
->iamthif_cl
.link
);
67 mutex_init(&dev
->device_lock
);
68 init_waitqueue_head(&dev
->wait_recvd_msg
);
69 init_waitqueue_head(&dev
->wait_stop_wd
);
70 dev
->dev_state
= MEI_DEV_INITIALIZING
;
71 dev
->iamthif_state
= MEI_IAMTHIF_IDLE
;
73 mei_io_list_init(&dev
->read_list
);
74 mei_io_list_init(&dev
->write_list
);
75 mei_io_list_init(&dev
->write_waiting_list
);
76 mei_io_list_init(&dev
->ctrl_wr_list
);
77 mei_io_list_init(&dev
->ctrl_rd_list
);
78 mei_io_list_init(&dev
->amthif_cmd_list
);
79 mei_io_list_init(&dev
->amthif_rd_complete_list
);
85 * mei_hw_init - initializes host and fw to start work.
87 * @dev: the device structure
89 * returns 0 on success, <0 on failure.
91 int mei_hw_init(struct mei_device
*dev
)
96 mutex_lock(&dev
->device_lock
);
98 dev
->host_hw_state
= mei_hcsr_read(dev
);
99 dev
->me_hw_state
= mei_mecsr_read(dev
);
100 dev_dbg(&dev
->pdev
->dev
, "host_hw_state = 0x%08x, mestate = 0x%08x.\n",
101 dev
->host_hw_state
, dev
->me_hw_state
);
103 /* acknowledge interrupt and stop interupts */
104 mei_clear_interrupts(dev
);
106 /* Doesn't change in runtime */
107 dev
->hbuf_depth
= (dev
->host_hw_state
& H_CBD
) >> 24;
109 dev
->recvd_msg
= false;
110 dev_dbg(&dev
->pdev
->dev
, "reset in start the mei device.\n");
114 dev_dbg(&dev
->pdev
->dev
, "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
115 dev
->host_hw_state
, dev
->me_hw_state
);
117 /* wait for ME to turn on ME_RDY */
118 if (!dev
->recvd_msg
) {
119 mutex_unlock(&dev
->device_lock
);
120 err
= wait_event_interruptible_timeout(dev
->wait_recvd_msg
,
122 mei_secs_to_jiffies(MEI_INTEROP_TIMEOUT
));
123 mutex_lock(&dev
->device_lock
);
126 if (err
<= 0 && !dev
->recvd_msg
) {
127 dev
->dev_state
= MEI_DEV_DISABLED
;
128 dev_dbg(&dev
->pdev
->dev
,
129 "wait_event_interruptible_timeout failed"
130 "on wait for ME to turn on ME_RDY.\n");
135 if (!(((dev
->host_hw_state
& H_RDY
) == H_RDY
) &&
136 ((dev
->me_hw_state
& ME_RDY_HRA
) == ME_RDY_HRA
))) {
137 dev
->dev_state
= MEI_DEV_DISABLED
;
138 dev_dbg(&dev
->pdev
->dev
,
139 "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
140 dev
->host_hw_state
, dev
->me_hw_state
);
142 if (!(dev
->host_hw_state
& H_RDY
))
143 dev_dbg(&dev
->pdev
->dev
, "host turn off H_RDY.\n");
145 if (!(dev
->me_hw_state
& ME_RDY_HRA
))
146 dev_dbg(&dev
->pdev
->dev
, "ME turn off ME_RDY.\n");
148 dev_err(&dev
->pdev
->dev
, "link layer initialization failed.\n");
153 if (dev
->version
.major_version
!= HBM_MAJOR_VERSION
||
154 dev
->version
.minor_version
!= HBM_MINOR_VERSION
) {
155 dev_dbg(&dev
->pdev
->dev
, "MEI start failed.\n");
160 dev
->recvd_msg
= false;
161 dev_dbg(&dev
->pdev
->dev
, "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
162 dev
->host_hw_state
, dev
->me_hw_state
);
163 dev_dbg(&dev
->pdev
->dev
, "ME turn on ME_RDY and host turn on H_RDY.\n");
164 dev_dbg(&dev
->pdev
->dev
, "link layer has been established.\n");
165 dev_dbg(&dev
->pdev
->dev
, "MEI start success.\n");
169 mutex_unlock(&dev
->device_lock
);
174 * mei_hw_reset - resets fw via mei csr register.
176 * @dev: the device structure
177 * @interrupts_enabled: if interrupt should be enabled after reset.
179 static void mei_hw_reset(struct mei_device
*dev
, int interrupts_enabled
)
181 dev
->host_hw_state
|= (H_RST
| H_IG
);
183 if (interrupts_enabled
)
184 mei_enable_interrupts(dev
);
186 mei_disable_interrupts(dev
);
190 * mei_reset - resets host and fw.
192 * @dev: the device structure
193 * @interrupts_enabled: if interrupt should be enabled after reset.
195 void mei_reset(struct mei_device
*dev
, int interrupts_enabled
)
197 struct mei_cl
*cl_pos
= NULL
;
198 struct mei_cl
*cl_next
= NULL
;
199 struct mei_cl_cb
*cb_pos
= NULL
;
200 struct mei_cl_cb
*cb_next
= NULL
;
203 if (dev
->dev_state
== MEI_DEV_RECOVERING_FROM_RESET
) {
204 dev
->need_reset
= true;
208 unexpected
= (dev
->dev_state
!= MEI_DEV_INITIALIZING
&&
209 dev
->dev_state
!= MEI_DEV_DISABLED
&&
210 dev
->dev_state
!= MEI_DEV_POWER_DOWN
&&
211 dev
->dev_state
!= MEI_DEV_POWER_UP
);
213 dev
->host_hw_state
= mei_hcsr_read(dev
);
215 dev_dbg(&dev
->pdev
->dev
, "before reset host_hw_state = 0x%08x.\n",
218 mei_hw_reset(dev
, interrupts_enabled
);
220 dev
->host_hw_state
&= ~H_RST
;
221 dev
->host_hw_state
|= H_IG
;
225 dev_dbg(&dev
->pdev
->dev
, "currently saved host_hw_state = 0x%08x.\n",
228 dev
->need_reset
= false;
230 if (dev
->dev_state
!= MEI_DEV_INITIALIZING
) {
231 if (dev
->dev_state
!= MEI_DEV_DISABLED
&&
232 dev
->dev_state
!= MEI_DEV_POWER_DOWN
)
233 dev
->dev_state
= MEI_DEV_RESETING
;
235 list_for_each_entry_safe(cl_pos
,
236 cl_next
, &dev
->file_list
, link
) {
237 cl_pos
->state
= MEI_FILE_DISCONNECTED
;
238 cl_pos
->mei_flow_ctrl_creds
= 0;
239 cl_pos
->read_cb
= NULL
;
240 cl_pos
->timer_count
= 0;
242 /* remove entry if already in list */
243 dev_dbg(&dev
->pdev
->dev
, "remove iamthif and wd from the file list.\n");
244 mei_me_cl_unlink(dev
, &dev
->wd_cl
);
246 mei_me_cl_unlink(dev
, &dev
->iamthif_cl
);
248 mei_amthif_reset_params(dev
);
249 memset(&dev
->wr_ext_msg
, 0, sizeof(dev
->wr_ext_msg
));
252 dev
->me_clients_num
= 0;
254 dev
->wd_pending
= false;
256 /* update the state of the registers after reset */
257 dev
->host_hw_state
= mei_hcsr_read(dev
);
258 dev
->me_hw_state
= mei_mecsr_read(dev
);
260 dev_dbg(&dev
->pdev
->dev
, "after reset host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
261 dev
->host_hw_state
, dev
->me_hw_state
);
264 dev_warn(&dev
->pdev
->dev
, "unexpected reset: dev_state = %s\n",
265 mei_dev_state_str(dev
->dev_state
));
267 /* Wake up all readings so they can be interrupted */
268 list_for_each_entry_safe(cl_pos
, cl_next
, &dev
->file_list
, link
) {
269 if (waitqueue_active(&cl_pos
->rx_wait
)) {
270 dev_dbg(&dev
->pdev
->dev
, "Waking up client!\n");
271 wake_up_interruptible(&cl_pos
->rx_wait
);
274 /* remove all waiting requests */
275 list_for_each_entry_safe(cb_pos
, cb_next
, &dev
->write_list
.list
, list
) {
276 list_del(&cb_pos
->list
);
277 mei_io_cb_free(cb_pos
);
283 * allocate_me_clients_storage - allocates storage for me clients
285 * @dev: the device structure
289 void mei_allocate_me_clients_storage(struct mei_device
*dev
)
291 struct mei_me_client
*clients
;
294 /* count how many ME clients we have */
295 for_each_set_bit(b
, dev
->me_clients_map
, MEI_CLIENTS_MAX
)
296 dev
->me_clients_num
++;
298 if (dev
->me_clients_num
<= 0)
302 if (dev
->me_clients
!= NULL
) {
303 kfree(dev
->me_clients
);
304 dev
->me_clients
= NULL
;
306 dev_dbg(&dev
->pdev
->dev
, "memory allocation for ME clients size=%zd.\n",
307 dev
->me_clients_num
* sizeof(struct mei_me_client
));
308 /* allocate storage for ME clients representation */
309 clients
= kcalloc(dev
->me_clients_num
,
310 sizeof(struct mei_me_client
), GFP_KERNEL
);
312 dev_dbg(&dev
->pdev
->dev
, "memory allocation for ME clients failed.\n");
313 dev
->dev_state
= MEI_DEV_RESETING
;
317 dev
->me_clients
= clients
;