cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

hbm.c (40372B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (c) 2003-2020, Intel Corporation. All rights reserved.
      4 * Intel Management Engine Interface (Intel MEI) Linux driver
      5 */
      6#include <linux/export.h>
      7#include <linux/sched.h>
      8#include <linux/wait.h>
      9#include <linux/pm_runtime.h>
     10#include <linux/slab.h>
     11
     12#include <linux/mei.h>
     13
     14#include "mei_dev.h"
     15#include "hbm.h"
     16#include "client.h"
     17
     18static const char *mei_hbm_status_str(enum mei_hbm_status status)
     19{
     20#define MEI_HBM_STATUS(status) case MEI_HBMS_##status: return #status
     21	switch (status) {
     22	MEI_HBM_STATUS(SUCCESS);
     23	MEI_HBM_STATUS(CLIENT_NOT_FOUND);
     24	MEI_HBM_STATUS(ALREADY_EXISTS);
     25	MEI_HBM_STATUS(REJECTED);
     26	MEI_HBM_STATUS(INVALID_PARAMETER);
     27	MEI_HBM_STATUS(NOT_ALLOWED);
     28	MEI_HBM_STATUS(ALREADY_STARTED);
     29	MEI_HBM_STATUS(NOT_STARTED);
     30	default: return "unknown";
     31	}
     32#undef MEI_HBM_STATUS
     33};
     34
     35static const char *mei_cl_conn_status_str(enum mei_cl_connect_status status)
     36{
     37#define MEI_CL_CS(status) case MEI_CL_CONN_##status: return #status
     38	switch (status) {
     39	MEI_CL_CS(SUCCESS);
     40	MEI_CL_CS(NOT_FOUND);
     41	MEI_CL_CS(ALREADY_STARTED);
     42	MEI_CL_CS(OUT_OF_RESOURCES);
     43	MEI_CL_CS(MESSAGE_SMALL);
     44	MEI_CL_CS(NOT_ALLOWED);
     45	default: return "unknown";
     46	}
     47#undef MEI_CL_CCS
     48}
     49
     50const char *mei_hbm_state_str(enum mei_hbm_state state)
     51{
     52#define MEI_HBM_STATE(state) case MEI_HBM_##state: return #state
     53	switch (state) {
     54	MEI_HBM_STATE(IDLE);
     55	MEI_HBM_STATE(STARTING);
     56	MEI_HBM_STATE(STARTED);
     57	MEI_HBM_STATE(DR_SETUP);
     58	MEI_HBM_STATE(ENUM_CLIENTS);
     59	MEI_HBM_STATE(CLIENT_PROPERTIES);
     60	MEI_HBM_STATE(STOPPED);
     61	default:
     62		return "unknown";
     63	}
     64#undef MEI_HBM_STATE
     65}
     66
     67/**
     68 * mei_cl_conn_status_to_errno - convert client connect response
     69 * status to error code
     70 *
     71 * @status: client connect response status
     72 *
     73 * Return: corresponding error code
     74 */
     75static int mei_cl_conn_status_to_errno(enum mei_cl_connect_status status)
     76{
     77	switch (status) {
     78	case MEI_CL_CONN_SUCCESS:          return 0;
     79	case MEI_CL_CONN_NOT_FOUND:        return -ENOTTY;
     80	case MEI_CL_CONN_ALREADY_STARTED:  return -EBUSY;
     81	case MEI_CL_CONN_OUT_OF_RESOURCES: return -EBUSY;
     82	case MEI_CL_CONN_MESSAGE_SMALL:    return -EINVAL;
     83	case MEI_CL_CONN_NOT_ALLOWED:      return -EBUSY;
     84	default:                           return -EINVAL;
     85	}
     86}
     87
     88/**
     89 * mei_hbm_write_message - wrapper for sending hbm messages.
     90 *
     91 * @dev: mei device
     92 * @hdr: mei header
     93 * @data: payload
     94 */
     95static inline int mei_hbm_write_message(struct mei_device *dev,
     96					struct mei_msg_hdr *hdr,
     97					const void *data)
     98{
     99	return mei_write_message(dev, hdr, sizeof(*hdr), data, hdr->length);
    100}
    101
    102/**
    103 * mei_hbm_idle - set hbm to idle state
    104 *
    105 * @dev: the device structure
    106 */
    107void mei_hbm_idle(struct mei_device *dev)
    108{
    109	dev->init_clients_timer = 0;
    110	dev->hbm_state = MEI_HBM_IDLE;
    111}
    112
    113/**
    114 * mei_hbm_reset - reset hbm counters and book keeping data structurs
    115 *
    116 * @dev: the device structure
    117 */
    118void mei_hbm_reset(struct mei_device *dev)
    119{
    120	mei_me_cl_rm_all(dev);
    121
    122	mei_hbm_idle(dev);
    123}
    124
    125/**
    126 * mei_hbm_hdr - construct hbm header
    127 *
    128 * @mei_hdr: hbm header
    129 * @length: payload length
    130 */
    131
    132static inline void mei_hbm_hdr(struct mei_msg_hdr *mei_hdr, size_t length)
    133{
    134	memset(mei_hdr, 0, sizeof(*mei_hdr));
    135	mei_hdr->length = length;
    136	mei_hdr->msg_complete = 1;
    137}
    138
    139/**
    140 * mei_hbm_cl_hdr - construct client hbm header
    141 *
    142 * @cl: client
    143 * @hbm_cmd: host bus message command
    144 * @buf: buffer for cl header
    145 * @len: buffer length
    146 */
    147static inline
    148void mei_hbm_cl_hdr(struct mei_cl *cl, u8 hbm_cmd, void *buf, size_t len)
    149{
    150	struct mei_hbm_cl_cmd *cmd = buf;
    151
    152	memset(cmd, 0, len);
    153
    154	cmd->hbm_cmd = hbm_cmd;
    155	cmd->host_addr = mei_cl_host_addr(cl);
    156	cmd->me_addr = mei_cl_me_id(cl);
    157}
    158
    159/**
    160 * mei_hbm_cl_write - write simple hbm client message
    161 *
    162 * @dev: the device structure
    163 * @cl: client
    164 * @hbm_cmd: host bus message command
    165 * @buf: message buffer
    166 * @len: buffer length
    167 *
    168 * Return: 0 on success, <0 on failure.
    169 */
    170static inline int mei_hbm_cl_write(struct mei_device *dev, struct mei_cl *cl,
    171				   u8 hbm_cmd, void *buf, size_t len)
    172{
    173	struct mei_msg_hdr mei_hdr;
    174
    175	mei_hbm_hdr(&mei_hdr, len);
    176	mei_hbm_cl_hdr(cl, hbm_cmd, buf, len);
    177
    178	return mei_hbm_write_message(dev, &mei_hdr, buf);
    179}
    180
    181/**
    182 * mei_hbm_cl_addr_equal - check if the client's and
    183 *	the message address match
    184 *
    185 * @cl: client
    186 * @cmd: hbm client message
    187 *
    188 * Return: true if addresses are the same
    189 */
    190static inline
    191bool mei_hbm_cl_addr_equal(struct mei_cl *cl, struct mei_hbm_cl_cmd *cmd)
    192{
    193	return  mei_cl_host_addr(cl) == cmd->host_addr &&
    194		mei_cl_me_id(cl) == cmd->me_addr;
    195}
    196
    197/**
    198 * mei_hbm_cl_find_by_cmd - find recipient client
    199 *
    200 * @dev: the device structure
    201 * @buf: a buffer with hbm cl command
    202 *
    203 * Return: the recipient client or NULL if not found
    204 */
    205static inline
    206struct mei_cl *mei_hbm_cl_find_by_cmd(struct mei_device *dev, void *buf)
    207{
    208	struct mei_hbm_cl_cmd *cmd = (struct mei_hbm_cl_cmd *)buf;
    209	struct mei_cl *cl;
    210
    211	list_for_each_entry(cl, &dev->file_list, link)
    212		if (mei_hbm_cl_addr_equal(cl, cmd))
    213			return cl;
    214	return NULL;
    215}
    216
    217
    218/**
    219 * mei_hbm_start_wait - wait for start response message.
    220 *
    221 * @dev: the device structure
    222 *
    223 * Return: 0 on success and < 0 on failure
    224 */
    225int mei_hbm_start_wait(struct mei_device *dev)
    226{
    227	int ret;
    228
    229	if (dev->hbm_state > MEI_HBM_STARTING)
    230		return 0;
    231
    232	mutex_unlock(&dev->device_lock);
    233	ret = wait_event_timeout(dev->wait_hbm_start,
    234			dev->hbm_state != MEI_HBM_STARTING,
    235			mei_secs_to_jiffies(MEI_HBM_TIMEOUT));
    236	mutex_lock(&dev->device_lock);
    237
    238	if (ret == 0 && (dev->hbm_state <= MEI_HBM_STARTING)) {
    239		dev->hbm_state = MEI_HBM_IDLE;
    240		dev_err(dev->dev, "waiting for mei start failed\n");
    241		return -ETIME;
    242	}
    243	return 0;
    244}
    245
    246/**
    247 * mei_hbm_start_req - sends start request message.
    248 *
    249 * @dev: the device structure
    250 *
    251 * Return: 0 on success and < 0 on failure
    252 */
    253int mei_hbm_start_req(struct mei_device *dev)
    254{
    255	struct mei_msg_hdr mei_hdr;
    256	struct hbm_host_version_request req;
    257	int ret;
    258
    259	mei_hbm_reset(dev);
    260
    261	mei_hbm_hdr(&mei_hdr, sizeof(req));
    262
    263	/* host start message */
    264	memset(&req, 0, sizeof(req));
    265	req.hbm_cmd = HOST_START_REQ_CMD;
    266	req.host_version.major_version = HBM_MAJOR_VERSION;
    267	req.host_version.minor_version = HBM_MINOR_VERSION;
    268
    269	dev->hbm_state = MEI_HBM_IDLE;
    270	ret = mei_hbm_write_message(dev, &mei_hdr, &req);
    271	if (ret) {
    272		dev_err(dev->dev, "version message write failed: ret = %d\n",
    273			ret);
    274		return ret;
    275	}
    276
    277	dev->hbm_state = MEI_HBM_STARTING;
    278	dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
    279	mei_schedule_stall_timer(dev);
    280	return 0;
    281}
    282
    283/**
    284 * mei_hbm_dma_setup_req() - setup DMA request
    285 * @dev: the device structure
    286 *
    287 * Return: 0 on success and < 0 on failure
    288 */
    289static int mei_hbm_dma_setup_req(struct mei_device *dev)
    290{
    291	struct mei_msg_hdr mei_hdr;
    292	struct hbm_dma_setup_request req;
    293	unsigned int i;
    294	int ret;
    295
    296	mei_hbm_hdr(&mei_hdr, sizeof(req));
    297
    298	memset(&req, 0, sizeof(req));
    299	req.hbm_cmd = MEI_HBM_DMA_SETUP_REQ_CMD;
    300	for (i = 0; i < DMA_DSCR_NUM; i++) {
    301		phys_addr_t paddr;
    302
    303		paddr = dev->dr_dscr[i].daddr;
    304		req.dma_dscr[i].addr_hi = upper_32_bits(paddr);
    305		req.dma_dscr[i].addr_lo = lower_32_bits(paddr);
    306		req.dma_dscr[i].size = dev->dr_dscr[i].size;
    307	}
    308
    309	mei_dma_ring_reset(dev);
    310
    311	ret = mei_hbm_write_message(dev, &mei_hdr, &req);
    312	if (ret) {
    313		dev_err(dev->dev, "dma setup request write failed: ret = %d.\n",
    314			ret);
    315		return ret;
    316	}
    317
    318	dev->hbm_state = MEI_HBM_DR_SETUP;
    319	dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
    320	mei_schedule_stall_timer(dev);
    321	return 0;
    322}
    323
    324/**
    325 * mei_hbm_capabilities_req - request capabilities
    326 *
    327 * @dev: the device structure
    328 *
    329 * Return: 0 on success and < 0 on failure
    330 */
    331static int mei_hbm_capabilities_req(struct mei_device *dev)
    332{
    333	struct mei_msg_hdr mei_hdr;
    334	struct hbm_capability_request req;
    335	int ret;
    336
    337	mei_hbm_hdr(&mei_hdr, sizeof(req));
    338
    339	memset(&req, 0, sizeof(req));
    340	req.hbm_cmd = MEI_HBM_CAPABILITIES_REQ_CMD;
    341	if (dev->hbm_f_vt_supported)
    342		req.capability_requested[0] |= HBM_CAP_VT;
    343	if (dev->hbm_f_cd_supported)
    344		req.capability_requested[0] |= HBM_CAP_CD;
    345
    346	ret = mei_hbm_write_message(dev, &mei_hdr, &req);
    347	if (ret) {
    348		dev_err(dev->dev,
    349			"capabilities request write failed: ret = %d.\n", ret);
    350		return ret;
    351	}
    352
    353	dev->hbm_state = MEI_HBM_CAP_SETUP;
    354	dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
    355	mei_schedule_stall_timer(dev);
    356	return 0;
    357}
    358
    359/**
    360 * mei_hbm_enum_clients_req - sends enumeration client request message.
    361 *
    362 * @dev: the device structure
    363 *
    364 * Return: 0 on success and < 0 on failure
    365 */
    366static int mei_hbm_enum_clients_req(struct mei_device *dev)
    367{
    368	struct mei_msg_hdr mei_hdr;
    369	struct hbm_host_enum_request req;
    370	int ret;
    371
    372	/* enumerate clients */
    373	mei_hbm_hdr(&mei_hdr, sizeof(req));
    374
    375	memset(&req, 0, sizeof(req));
    376	req.hbm_cmd = HOST_ENUM_REQ_CMD;
    377	req.flags |= dev->hbm_f_dc_supported ? MEI_HBM_ENUM_F_ALLOW_ADD : 0;
    378	req.flags |= dev->hbm_f_ie_supported ?
    379			  MEI_HBM_ENUM_F_IMMEDIATE_ENUM : 0;
    380
    381	ret = mei_hbm_write_message(dev, &mei_hdr, &req);
    382	if (ret) {
    383		dev_err(dev->dev, "enumeration request write failed: ret = %d.\n",
    384			ret);
    385		return ret;
    386	}
    387	dev->hbm_state = MEI_HBM_ENUM_CLIENTS;
    388	dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
    389	mei_schedule_stall_timer(dev);
    390	return 0;
    391}
    392
    393/**
    394 * mei_hbm_me_cl_add - add new me client to the list
    395 *
    396 * @dev: the device structure
    397 * @res: hbm property response
    398 *
    399 * Return: 0 on success and -ENOMEM on allocation failure
    400 */
    401
    402static int mei_hbm_me_cl_add(struct mei_device *dev,
    403			     struct hbm_props_response *res)
    404{
    405	struct mei_me_client *me_cl;
    406	const uuid_le *uuid = &res->client_properties.protocol_name;
    407
    408	mei_me_cl_rm_by_uuid(dev, uuid);
    409
    410	me_cl = kzalloc(sizeof(*me_cl), GFP_KERNEL);
    411	if (!me_cl)
    412		return -ENOMEM;
    413
    414	mei_me_cl_init(me_cl);
    415
    416	me_cl->props = res->client_properties;
    417	me_cl->client_id = res->me_addr;
    418	me_cl->tx_flow_ctrl_creds = 0;
    419
    420	mei_me_cl_add(dev, me_cl);
    421
    422	return 0;
    423}
    424
    425/**
    426 * mei_hbm_add_cl_resp - send response to fw on client add request
    427 *
    428 * @dev: the device structure
    429 * @addr: me address
    430 * @status: response status
    431 *
    432 * Return: 0 on success and < 0 on failure
    433 */
    434static int mei_hbm_add_cl_resp(struct mei_device *dev, u8 addr, u8 status)
    435{
    436	struct mei_msg_hdr mei_hdr;
    437	struct hbm_add_client_response resp;
    438	int ret;
    439
    440	dev_dbg(dev->dev, "adding client response\n");
    441
    442	mei_hbm_hdr(&mei_hdr, sizeof(resp));
    443
    444	memset(&resp, 0, sizeof(resp));
    445	resp.hbm_cmd = MEI_HBM_ADD_CLIENT_RES_CMD;
    446	resp.me_addr = addr;
    447	resp.status  = status;
    448
    449	ret = mei_hbm_write_message(dev, &mei_hdr, &resp);
    450	if (ret)
    451		dev_err(dev->dev, "add client response write failed: ret = %d\n",
    452			ret);
    453	return ret;
    454}
    455
    456/**
    457 * mei_hbm_fw_add_cl_req - request from the fw to add a client
    458 *
    459 * @dev: the device structure
    460 * @req: add client request
    461 *
    462 * Return: 0 on success and < 0 on failure
    463 */
    464static int mei_hbm_fw_add_cl_req(struct mei_device *dev,
    465			      struct hbm_add_client_request *req)
    466{
    467	int ret;
    468	u8 status = MEI_HBMS_SUCCESS;
    469
    470	BUILD_BUG_ON(sizeof(struct hbm_add_client_request) !=
    471			sizeof(struct hbm_props_response));
    472
    473	ret = mei_hbm_me_cl_add(dev, (struct hbm_props_response *)req);
    474	if (ret)
    475		status = !MEI_HBMS_SUCCESS;
    476
    477	if (dev->dev_state == MEI_DEV_ENABLED)
    478		schedule_work(&dev->bus_rescan_work);
    479
    480	return mei_hbm_add_cl_resp(dev, req->me_addr, status);
    481}
    482
    483/**
    484 * mei_hbm_cl_notify_req - send notification request
    485 *
    486 * @dev: the device structure
    487 * @cl: a client to disconnect from
    488 * @start: true for start false for stop
    489 *
    490 * Return: 0 on success and -EIO on write failure
    491 */
    492int mei_hbm_cl_notify_req(struct mei_device *dev,
    493			  struct mei_cl *cl, u8 start)
    494{
    495
    496	struct mei_msg_hdr mei_hdr;
    497	struct hbm_notification_request req;
    498	int ret;
    499
    500	mei_hbm_hdr(&mei_hdr, sizeof(req));
    501	mei_hbm_cl_hdr(cl, MEI_HBM_NOTIFY_REQ_CMD, &req, sizeof(req));
    502
    503	req.start = start;
    504
    505	ret = mei_hbm_write_message(dev, &mei_hdr, &req);
    506	if (ret)
    507		dev_err(dev->dev, "notify request failed: ret = %d\n", ret);
    508
    509	return ret;
    510}
    511
    512/**
    513 *  notify_res_to_fop - convert notification response to the proper
    514 *      notification FOP
    515 *
    516 * @cmd: client notification start response command
    517 *
    518 * Return:  MEI_FOP_NOTIFY_START or MEI_FOP_NOTIFY_STOP;
    519 */
    520static inline enum mei_cb_file_ops notify_res_to_fop(struct mei_hbm_cl_cmd *cmd)
    521{
    522	struct hbm_notification_response *rs =
    523		(struct hbm_notification_response *)cmd;
    524
    525	return mei_cl_notify_req2fop(rs->start);
    526}
    527
    528/**
    529 * mei_hbm_cl_notify_start_res - update the client state according
    530 *       notify start response
    531 *
    532 * @dev: the device structure
    533 * @cl: mei host client
    534 * @cmd: client notification start response command
    535 */
    536static void mei_hbm_cl_notify_start_res(struct mei_device *dev,
    537					struct mei_cl *cl,
    538					struct mei_hbm_cl_cmd *cmd)
    539{
    540	struct hbm_notification_response *rs =
    541		(struct hbm_notification_response *)cmd;
    542
    543	cl_dbg(dev, cl, "hbm: notify start response status=%d\n", rs->status);
    544
    545	if (rs->status == MEI_HBMS_SUCCESS ||
    546	    rs->status == MEI_HBMS_ALREADY_STARTED) {
    547		cl->notify_en = true;
    548		cl->status = 0;
    549	} else {
    550		cl->status = -EINVAL;
    551	}
    552}
    553
    554/**
    555 * mei_hbm_cl_notify_stop_res - update the client state according
    556 *       notify stop response
    557 *
    558 * @dev: the device structure
    559 * @cl: mei host client
    560 * @cmd: client notification stop response command
    561 */
    562static void mei_hbm_cl_notify_stop_res(struct mei_device *dev,
    563				       struct mei_cl *cl,
    564				       struct mei_hbm_cl_cmd *cmd)
    565{
    566	struct hbm_notification_response *rs =
    567		(struct hbm_notification_response *)cmd;
    568
    569	cl_dbg(dev, cl, "hbm: notify stop response status=%d\n", rs->status);
    570
    571	if (rs->status == MEI_HBMS_SUCCESS ||
    572	    rs->status == MEI_HBMS_NOT_STARTED) {
    573		cl->notify_en = false;
    574		cl->status = 0;
    575	} else {
    576		/* TODO: spec is not clear yet about other possible issues */
    577		cl->status = -EINVAL;
    578	}
    579}
    580
    581/**
    582 * mei_hbm_cl_notify - signal notification event
    583 *
    584 * @dev: the device structure
    585 * @cmd: notification client message
    586 */
    587static void mei_hbm_cl_notify(struct mei_device *dev,
    588			      struct mei_hbm_cl_cmd *cmd)
    589{
    590	struct mei_cl *cl;
    591
    592	cl = mei_hbm_cl_find_by_cmd(dev, cmd);
    593	if (cl)
    594		mei_cl_notify(cl);
    595}
    596
    597/**
    598 * mei_hbm_cl_dma_map_req - send client dma map request
    599 *
    600 * @dev: the device structure
    601 * @cl: mei host client
    602 *
    603 * Return: 0 on success and -EIO on write failure
    604 */
    605int mei_hbm_cl_dma_map_req(struct mei_device *dev, struct mei_cl *cl)
    606{
    607	struct mei_msg_hdr mei_hdr;
    608	struct hbm_client_dma_map_request req;
    609	int ret;
    610
    611	mei_hbm_hdr(&mei_hdr, sizeof(req));
    612
    613	memset(&req, 0, sizeof(req));
    614
    615	req.hbm_cmd = MEI_HBM_CLIENT_DMA_MAP_REQ_CMD;
    616	req.client_buffer_id = cl->dma.buffer_id;
    617	req.address_lsb = lower_32_bits(cl->dma.daddr);
    618	req.address_msb = upper_32_bits(cl->dma.daddr);
    619	req.size = cl->dma.size;
    620
    621	ret = mei_hbm_write_message(dev, &mei_hdr, &req);
    622	if (ret)
    623		dev_err(dev->dev, "dma map request failed: ret = %d\n", ret);
    624
    625	return ret;
    626}
    627
    628/**
    629 * mei_hbm_cl_dma_unmap_req - send client dma unmap request
    630 *
    631 * @dev: the device structure
    632 * @cl: mei host client
    633 *
    634 * Return: 0 on success and -EIO on write failure
    635 */
    636int mei_hbm_cl_dma_unmap_req(struct mei_device *dev, struct mei_cl *cl)
    637{
    638	struct mei_msg_hdr mei_hdr;
    639	struct hbm_client_dma_unmap_request req;
    640	int ret;
    641
    642	mei_hbm_hdr(&mei_hdr, sizeof(req));
    643
    644	memset(&req, 0, sizeof(req));
    645
    646	req.hbm_cmd = MEI_HBM_CLIENT_DMA_UNMAP_REQ_CMD;
    647	req.client_buffer_id = cl->dma.buffer_id;
    648
    649	ret = mei_hbm_write_message(dev, &mei_hdr, &req);
    650	if (ret)
    651		dev_err(dev->dev, "dma unmap request failed: ret = %d\n", ret);
    652
    653	return ret;
    654}
    655
    656static void mei_hbm_cl_dma_map_res(struct mei_device *dev,
    657				   struct hbm_client_dma_response *res)
    658{
    659	struct mei_cl *cl;
    660	struct mei_cl_cb *cb, *next;
    661
    662	cl = NULL;
    663	list_for_each_entry_safe(cb, next, &dev->ctrl_rd_list, list) {
    664		if (cb->fop_type != MEI_FOP_DMA_MAP)
    665			continue;
    666		if (!cb->cl->dma.buffer_id || cb->cl->dma_mapped)
    667			continue;
    668
    669		cl = cb->cl;
    670		break;
    671	}
    672	if (!cl)
    673		return;
    674
    675	if (res->status) {
    676		dev_err(dev->dev, "cl dma map failed %d\n", res->status);
    677		cl->status = -EFAULT;
    678	} else {
    679		dev_dbg(dev->dev, "cl dma map succeeded\n");
    680		cl->dma_mapped = 1;
    681		cl->status = 0;
    682	}
    683	wake_up(&cl->wait);
    684}
    685
    686static void mei_hbm_cl_dma_unmap_res(struct mei_device *dev,
    687				     struct hbm_client_dma_response *res)
    688{
    689	struct mei_cl *cl;
    690	struct mei_cl_cb *cb, *next;
    691
    692	cl = NULL;
    693	list_for_each_entry_safe(cb, next, &dev->ctrl_rd_list, list) {
    694		if (cb->fop_type != MEI_FOP_DMA_UNMAP)
    695			continue;
    696		if (!cb->cl->dma.buffer_id || !cb->cl->dma_mapped)
    697			continue;
    698
    699		cl = cb->cl;
    700		break;
    701	}
    702	if (!cl)
    703		return;
    704
    705	if (res->status) {
    706		dev_err(dev->dev, "cl dma unmap failed %d\n", res->status);
    707		cl->status = -EFAULT;
    708	} else {
    709		dev_dbg(dev->dev, "cl dma unmap succeeded\n");
    710		cl->dma_mapped = 0;
    711		cl->status = 0;
    712	}
    713	wake_up(&cl->wait);
    714}
    715
    716/**
    717 * mei_hbm_prop_req - request property for a single client
    718 *
    719 * @dev: the device structure
    720 * @start_idx: client index to start search
    721 *
    722 * Return: 0 on success and < 0 on failure
    723 */
    724static int mei_hbm_prop_req(struct mei_device *dev, unsigned long start_idx)
    725{
    726	struct mei_msg_hdr mei_hdr;
    727	struct hbm_props_request req;
    728	unsigned long addr;
    729	int ret;
    730
    731	addr = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX, start_idx);
    732
    733	/* We got all client properties */
    734	if (addr == MEI_CLIENTS_MAX) {
    735		dev->hbm_state = MEI_HBM_STARTED;
    736		mei_host_client_init(dev);
    737		return 0;
    738	}
    739
    740	mei_hbm_hdr(&mei_hdr, sizeof(req));
    741
    742	memset(&req, 0, sizeof(req));
    743
    744	req.hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD;
    745	req.me_addr = addr;
    746
    747	ret = mei_hbm_write_message(dev, &mei_hdr, &req);
    748	if (ret) {
    749		dev_err(dev->dev, "properties request write failed: ret = %d\n",
    750			ret);
    751		return ret;
    752	}
    753
    754	dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
    755	mei_schedule_stall_timer(dev);
    756
    757	return 0;
    758}
    759
    760/**
    761 * mei_hbm_pg - sends pg command
    762 *
    763 * @dev: the device structure
    764 * @pg_cmd: the pg command code
    765 *
    766 * Return: -EIO on write failure
    767 *         -EOPNOTSUPP if the operation is not supported by the protocol
    768 */
    769int mei_hbm_pg(struct mei_device *dev, u8 pg_cmd)
    770{
    771	struct mei_msg_hdr mei_hdr;
    772	struct hbm_power_gate req;
    773	int ret;
    774
    775	if (!dev->hbm_f_pg_supported)
    776		return -EOPNOTSUPP;
    777
    778	mei_hbm_hdr(&mei_hdr, sizeof(req));
    779
    780	memset(&req, 0, sizeof(req));
    781	req.hbm_cmd = pg_cmd;
    782
    783	ret = mei_hbm_write_message(dev, &mei_hdr, &req);
    784	if (ret)
    785		dev_err(dev->dev, "power gate command write failed.\n");
    786	return ret;
    787}
    788EXPORT_SYMBOL_GPL(mei_hbm_pg);
    789
    790/**
    791 * mei_hbm_stop_req - send stop request message
    792 *
    793 * @dev: mei device
    794 *
    795 * Return: -EIO on write failure
    796 */
    797static int mei_hbm_stop_req(struct mei_device *dev)
    798{
    799	struct mei_msg_hdr mei_hdr;
    800	struct hbm_host_stop_request req;
    801
    802	mei_hbm_hdr(&mei_hdr, sizeof(req));
    803
    804	memset(&req, 0, sizeof(req));
    805	req.hbm_cmd = HOST_STOP_REQ_CMD;
    806	req.reason = DRIVER_STOP_REQUEST;
    807
    808	return mei_hbm_write_message(dev, &mei_hdr, &req);
    809}
    810
    811/**
    812 * mei_hbm_cl_flow_control_req - sends flow control request.
    813 *
    814 * @dev: the device structure
    815 * @cl: client info
    816 *
    817 * Return: -EIO on write failure
    818 */
    819int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl)
    820{
    821	struct hbm_flow_control req;
    822
    823	cl_dbg(dev, cl, "sending flow control\n");
    824	return mei_hbm_cl_write(dev, cl, MEI_FLOW_CONTROL_CMD,
    825				&req, sizeof(req));
    826}
    827
    828/**
    829 * mei_hbm_add_single_tx_flow_ctrl_creds - adds single buffer credentials.
    830 *
    831 * @dev: the device structure
    832 * @fctrl: flow control response bus message
    833 *
    834 * Return: 0 on success, < 0 otherwise
    835 */
    836static int mei_hbm_add_single_tx_flow_ctrl_creds(struct mei_device *dev,
    837						 struct hbm_flow_control *fctrl)
    838{
    839	struct mei_me_client *me_cl;
    840	int rets;
    841
    842	me_cl = mei_me_cl_by_id(dev, fctrl->me_addr);
    843	if (!me_cl) {
    844		dev_err(dev->dev, "no such me client %d\n", fctrl->me_addr);
    845		return -ENOENT;
    846	}
    847
    848	if (WARN_ON(me_cl->props.single_recv_buf == 0)) {
    849		rets = -EINVAL;
    850		goto out;
    851	}
    852
    853	me_cl->tx_flow_ctrl_creds++;
    854	dev_dbg(dev->dev, "recv flow ctrl msg ME %d (single) creds = %d.\n",
    855		fctrl->me_addr, me_cl->tx_flow_ctrl_creds);
    856
    857	rets = 0;
    858out:
    859	mei_me_cl_put(me_cl);
    860	return rets;
    861}
    862
    863/**
    864 * mei_hbm_cl_tx_flow_ctrl_creds_res - flow control response from me
    865 *
    866 * @dev: the device structure
    867 * @fctrl: flow control response bus message
    868 */
    869static void mei_hbm_cl_tx_flow_ctrl_creds_res(struct mei_device *dev,
    870					       struct hbm_flow_control *fctrl)
    871{
    872	struct mei_cl *cl;
    873
    874	if (!fctrl->host_addr) {
    875		/* single receive buffer */
    876		mei_hbm_add_single_tx_flow_ctrl_creds(dev, fctrl);
    877		return;
    878	}
    879
    880	cl = mei_hbm_cl_find_by_cmd(dev, fctrl);
    881	if (cl) {
    882		cl->tx_flow_ctrl_creds++;
    883		cl_dbg(dev, cl, "flow control creds = %d.\n",
    884				cl->tx_flow_ctrl_creds);
    885	}
    886}
    887
    888
    889/**
    890 * mei_hbm_cl_disconnect_req - sends disconnect message to fw.
    891 *
    892 * @dev: the device structure
    893 * @cl: a client to disconnect from
    894 *
    895 * Return: -EIO on write failure
    896 */
    897int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl)
    898{
    899	struct hbm_client_connect_request req;
    900
    901	return mei_hbm_cl_write(dev, cl, CLIENT_DISCONNECT_REQ_CMD,
    902				&req, sizeof(req));
    903}
    904
    905/**
    906 * mei_hbm_cl_disconnect_rsp - sends disconnect respose to the FW
    907 *
    908 * @dev: the device structure
    909 * @cl: a client to disconnect from
    910 *
    911 * Return: -EIO on write failure
    912 */
    913int mei_hbm_cl_disconnect_rsp(struct mei_device *dev, struct mei_cl *cl)
    914{
    915	struct hbm_client_connect_response resp;
    916
    917	return mei_hbm_cl_write(dev, cl, CLIENT_DISCONNECT_RES_CMD,
    918				&resp, sizeof(resp));
    919}
    920
    921/**
    922 * mei_hbm_cl_disconnect_res - update the client state according
    923 *       disconnect response
    924 *
    925 * @dev: the device structure
    926 * @cl: mei host client
    927 * @cmd: disconnect client response host bus message
    928 */
    929static void mei_hbm_cl_disconnect_res(struct mei_device *dev, struct mei_cl *cl,
    930				      struct mei_hbm_cl_cmd *cmd)
    931{
    932	struct hbm_client_connect_response *rs =
    933		(struct hbm_client_connect_response *)cmd;
    934
    935	cl_dbg(dev, cl, "hbm: disconnect response status=%d\n", rs->status);
    936
    937	if (rs->status == MEI_CL_DISCONN_SUCCESS)
    938		cl->state = MEI_FILE_DISCONNECT_REPLY;
    939	cl->status = 0;
    940}
    941
    942/**
    943 * mei_hbm_cl_connect_req - send connection request to specific me client
    944 *
    945 * @dev: the device structure
    946 * @cl: a client to connect to
    947 *
    948 * Return: -EIO on write failure
    949 */
    950int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl)
    951{
    952	struct hbm_client_connect_request req;
    953
    954	return mei_hbm_cl_write(dev, cl, CLIENT_CONNECT_REQ_CMD,
    955				&req, sizeof(req));
    956}
    957
    958/**
    959 * mei_hbm_cl_connect_res - update the client state according
    960 *        connection response
    961 *
    962 * @dev: the device structure
    963 * @cl: mei host client
    964 * @cmd: connect client response host bus message
    965 */
    966static void mei_hbm_cl_connect_res(struct mei_device *dev, struct mei_cl *cl,
    967				   struct mei_hbm_cl_cmd *cmd)
    968{
    969	struct hbm_client_connect_response *rs =
    970		(struct hbm_client_connect_response *)cmd;
    971
    972	cl_dbg(dev, cl, "hbm: connect response status=%s\n",
    973			mei_cl_conn_status_str(rs->status));
    974
    975	if (rs->status == MEI_CL_CONN_SUCCESS)
    976		cl->state = MEI_FILE_CONNECTED;
    977	else {
    978		cl->state = MEI_FILE_DISCONNECT_REPLY;
    979		if (rs->status == MEI_CL_CONN_NOT_FOUND) {
    980			mei_me_cl_del(dev, cl->me_cl);
    981			if (dev->dev_state == MEI_DEV_ENABLED)
    982				schedule_work(&dev->bus_rescan_work);
    983		}
    984	}
    985	cl->status = mei_cl_conn_status_to_errno(rs->status);
    986}
    987
    988/**
    989 * mei_hbm_cl_res - process hbm response received on behalf
    990 *         an client
    991 *
    992 * @dev: the device structure
    993 * @rs:  hbm client message
    994 * @fop_type: file operation type
    995 */
    996static void mei_hbm_cl_res(struct mei_device *dev,
    997			   struct mei_hbm_cl_cmd *rs,
    998			   enum mei_cb_file_ops fop_type)
    999{
   1000	struct mei_cl *cl;
   1001	struct mei_cl_cb *cb, *next;
   1002
   1003	cl = NULL;
   1004	list_for_each_entry_safe(cb, next, &dev->ctrl_rd_list, list) {
   1005
   1006		cl = cb->cl;
   1007
   1008		if (cb->fop_type != fop_type)
   1009			continue;
   1010
   1011		if (mei_hbm_cl_addr_equal(cl, rs)) {
   1012			list_del_init(&cb->list);
   1013			break;
   1014		}
   1015	}
   1016
   1017	if (!cl)
   1018		return;
   1019
   1020	switch (fop_type) {
   1021	case MEI_FOP_CONNECT:
   1022		mei_hbm_cl_connect_res(dev, cl, rs);
   1023		break;
   1024	case MEI_FOP_DISCONNECT:
   1025		mei_hbm_cl_disconnect_res(dev, cl, rs);
   1026		break;
   1027	case MEI_FOP_NOTIFY_START:
   1028		mei_hbm_cl_notify_start_res(dev, cl, rs);
   1029		break;
   1030	case MEI_FOP_NOTIFY_STOP:
   1031		mei_hbm_cl_notify_stop_res(dev, cl, rs);
   1032		break;
   1033	default:
   1034		return;
   1035	}
   1036
   1037	cl->timer_count = 0;
   1038	wake_up(&cl->wait);
   1039}
   1040
   1041
   1042/**
   1043 * mei_hbm_fw_disconnect_req - disconnect request initiated by ME firmware
   1044 *  host sends disconnect response
   1045 *
   1046 * @dev: the device structure.
   1047 * @disconnect_req: disconnect request bus message from the me
   1048 *
   1049 * Return: -ENOMEM on allocation failure
   1050 */
   1051static int mei_hbm_fw_disconnect_req(struct mei_device *dev,
   1052		struct hbm_client_connect_request *disconnect_req)
   1053{
   1054	struct mei_cl *cl;
   1055	struct mei_cl_cb *cb;
   1056
   1057	cl = mei_hbm_cl_find_by_cmd(dev, disconnect_req);
   1058	if (cl) {
   1059		cl_warn(dev, cl, "fw disconnect request received\n");
   1060		cl->state = MEI_FILE_DISCONNECTING;
   1061		cl->timer_count = 0;
   1062
   1063		cb = mei_cl_enqueue_ctrl_wr_cb(cl, 0, MEI_FOP_DISCONNECT_RSP,
   1064					       NULL);
   1065		if (!cb)
   1066			return -ENOMEM;
   1067	}
   1068	return 0;
   1069}
   1070
   1071/**
   1072 * mei_hbm_pg_enter_res - PG enter response received
   1073 *
   1074 * @dev: the device structure.
   1075 *
   1076 * Return: 0 on success, -EPROTO on state mismatch
   1077 */
   1078static int mei_hbm_pg_enter_res(struct mei_device *dev)
   1079{
   1080	if (mei_pg_state(dev) != MEI_PG_OFF ||
   1081	    dev->pg_event != MEI_PG_EVENT_WAIT) {
   1082		dev_err(dev->dev, "hbm: pg entry response: state mismatch [%s, %d]\n",
   1083			mei_pg_state_str(mei_pg_state(dev)), dev->pg_event);
   1084		return -EPROTO;
   1085	}
   1086
   1087	dev->pg_event = MEI_PG_EVENT_RECEIVED;
   1088	wake_up(&dev->wait_pg);
   1089
   1090	return 0;
   1091}
   1092
   1093/**
   1094 * mei_hbm_pg_resume - process with PG resume
   1095 *
   1096 * @dev: the device structure.
   1097 */
   1098void mei_hbm_pg_resume(struct mei_device *dev)
   1099{
   1100	pm_request_resume(dev->dev);
   1101}
   1102EXPORT_SYMBOL_GPL(mei_hbm_pg_resume);
   1103
   1104/**
   1105 * mei_hbm_pg_exit_res - PG exit response received
   1106 *
   1107 * @dev: the device structure.
   1108 *
   1109 * Return: 0 on success, -EPROTO on state mismatch
   1110 */
   1111static int mei_hbm_pg_exit_res(struct mei_device *dev)
   1112{
   1113	if (mei_pg_state(dev) != MEI_PG_ON ||
   1114	    (dev->pg_event != MEI_PG_EVENT_WAIT &&
   1115	     dev->pg_event != MEI_PG_EVENT_IDLE)) {
   1116		dev_err(dev->dev, "hbm: pg exit response: state mismatch [%s, %d]\n",
   1117			mei_pg_state_str(mei_pg_state(dev)), dev->pg_event);
   1118		return -EPROTO;
   1119	}
   1120
   1121	switch (dev->pg_event) {
   1122	case MEI_PG_EVENT_WAIT:
   1123		dev->pg_event = MEI_PG_EVENT_RECEIVED;
   1124		wake_up(&dev->wait_pg);
   1125		break;
   1126	case MEI_PG_EVENT_IDLE:
   1127		/*
   1128		* If the driver is not waiting on this then
   1129		* this is HW initiated exit from PG.
   1130		* Start runtime pm resume sequence to exit from PG.
   1131		*/
   1132		dev->pg_event = MEI_PG_EVENT_RECEIVED;
   1133		mei_hbm_pg_resume(dev);
   1134		break;
   1135	default:
   1136		WARN(1, "hbm: pg exit response: unexpected pg event = %d\n",
   1137		     dev->pg_event);
   1138		return -EPROTO;
   1139	}
   1140
   1141	return 0;
   1142}
   1143
   1144/**
   1145 * mei_hbm_config_features - check what hbm features and commands
   1146 *        are supported by the fw
   1147 *
   1148 * @dev: the device structure
   1149 */
   1150static void mei_hbm_config_features(struct mei_device *dev)
   1151{
   1152	/* Power Gating Isolation Support */
   1153	dev->hbm_f_pg_supported = 0;
   1154	if (dev->version.major_version > HBM_MAJOR_VERSION_PGI)
   1155		dev->hbm_f_pg_supported = 1;
   1156
   1157	if (dev->version.major_version == HBM_MAJOR_VERSION_PGI &&
   1158	    dev->version.minor_version >= HBM_MINOR_VERSION_PGI)
   1159		dev->hbm_f_pg_supported = 1;
   1160
   1161	dev->hbm_f_dc_supported = 0;
   1162	if (dev->version.major_version >= HBM_MAJOR_VERSION_DC)
   1163		dev->hbm_f_dc_supported = 1;
   1164
   1165	dev->hbm_f_ie_supported = 0;
   1166	if (dev->version.major_version >= HBM_MAJOR_VERSION_IE)
   1167		dev->hbm_f_ie_supported = 1;
   1168
   1169	/* disconnect on connect timeout instead of link reset */
   1170	dev->hbm_f_dot_supported = 0;
   1171	if (dev->version.major_version >= HBM_MAJOR_VERSION_DOT)
   1172		dev->hbm_f_dot_supported = 1;
   1173
   1174	/* Notification Event Support */
   1175	dev->hbm_f_ev_supported = 0;
   1176	if (dev->version.major_version >= HBM_MAJOR_VERSION_EV)
   1177		dev->hbm_f_ev_supported = 1;
   1178
   1179	/* Fixed Address Client Support */
   1180	dev->hbm_f_fa_supported = 0;
   1181	if (dev->version.major_version >= HBM_MAJOR_VERSION_FA)
   1182		dev->hbm_f_fa_supported = 1;
   1183
   1184	/* OS ver message Support */
   1185	dev->hbm_f_os_supported = 0;
   1186	if (dev->version.major_version >= HBM_MAJOR_VERSION_OS)
   1187		dev->hbm_f_os_supported = 1;
   1188
   1189	/* DMA Ring Support */
   1190	dev->hbm_f_dr_supported = 0;
   1191	if (dev->version.major_version > HBM_MAJOR_VERSION_DR ||
   1192	    (dev->version.major_version == HBM_MAJOR_VERSION_DR &&
   1193	     dev->version.minor_version >= HBM_MINOR_VERSION_DR))
   1194		dev->hbm_f_dr_supported = 1;
   1195
   1196	/* VTag Support */
   1197	dev->hbm_f_vt_supported = 0;
   1198	if (dev->version.major_version > HBM_MAJOR_VERSION_VT ||
   1199	    (dev->version.major_version == HBM_MAJOR_VERSION_VT &&
   1200	     dev->version.minor_version >= HBM_MINOR_VERSION_VT))
   1201		dev->hbm_f_vt_supported = 1;
   1202
   1203	/* Capability message Support */
   1204	dev->hbm_f_cap_supported = 0;
   1205	if (dev->version.major_version > HBM_MAJOR_VERSION_CAP ||
   1206	    (dev->version.major_version == HBM_MAJOR_VERSION_CAP &&
   1207	     dev->version.minor_version >= HBM_MINOR_VERSION_CAP))
   1208		dev->hbm_f_cap_supported = 1;
   1209
   1210	/* Client DMA Support */
   1211	dev->hbm_f_cd_supported = 0;
   1212	if (dev->version.major_version > HBM_MAJOR_VERSION_CD ||
   1213	    (dev->version.major_version == HBM_MAJOR_VERSION_CD &&
   1214	     dev->version.minor_version >= HBM_MINOR_VERSION_CD))
   1215		dev->hbm_f_cd_supported = 1;
   1216}
   1217
   1218/**
   1219 * mei_hbm_version_is_supported - checks whether the driver can
   1220 *     support the hbm version of the device
   1221 *
   1222 * @dev: the device structure
   1223 * Return: true if driver can support hbm version of the device
   1224 */
   1225bool mei_hbm_version_is_supported(struct mei_device *dev)
   1226{
   1227	return	(dev->version.major_version < HBM_MAJOR_VERSION) ||
   1228		(dev->version.major_version == HBM_MAJOR_VERSION &&
   1229		 dev->version.minor_version <= HBM_MINOR_VERSION);
   1230}
   1231
   1232/**
   1233 * mei_hbm_dispatch - bottom half read routine after ISR to
   1234 * handle the read bus message cmd processing.
   1235 *
   1236 * @dev: the device structure
   1237 * @hdr: header of bus message
   1238 *
   1239 * Return: 0 on success and < 0 on failure
   1240 */
   1241int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
   1242{
   1243	struct mei_bus_message *mei_msg;
   1244	struct hbm_host_version_response *version_res;
   1245	struct hbm_props_response *props_res;
   1246	struct hbm_host_enum_response *enum_res;
   1247	struct hbm_dma_setup_response *dma_setup_res;
   1248	struct hbm_add_client_request *add_cl_req;
   1249	struct hbm_capability_response *capability_res;
   1250	int ret;
   1251
   1252	struct mei_hbm_cl_cmd *cl_cmd;
   1253	struct hbm_client_connect_request *disconnect_req;
   1254	struct hbm_flow_control *fctrl;
   1255	struct hbm_client_dma_response *client_dma_res;
   1256
   1257	/* read the message to our buffer */
   1258	BUG_ON(hdr->length >= sizeof(dev->rd_msg_buf));
   1259	mei_read_slots(dev, dev->rd_msg_buf, hdr->length);
   1260	mei_msg = (struct mei_bus_message *)dev->rd_msg_buf;
   1261	cl_cmd  = (struct mei_hbm_cl_cmd *)mei_msg;
   1262
   1263	/* ignore spurious message and prevent reset nesting
   1264	 * hbm is put to idle during system reset
   1265	 */
   1266	if (dev->hbm_state == MEI_HBM_IDLE) {
   1267		dev_dbg(dev->dev, "hbm: state is idle ignore spurious messages\n");
   1268		return 0;
   1269	}
   1270
   1271	switch (mei_msg->hbm_cmd) {
   1272	case HOST_START_RES_CMD:
   1273		dev_dbg(dev->dev, "hbm: start: response message received.\n");
   1274
   1275		dev->init_clients_timer = 0;
   1276
   1277		version_res = (struct hbm_host_version_response *)mei_msg;
   1278
   1279		dev_dbg(dev->dev, "HBM VERSION: DRIVER=%02d:%02d DEVICE=%02d:%02d\n",
   1280				HBM_MAJOR_VERSION, HBM_MINOR_VERSION,
   1281				version_res->me_max_version.major_version,
   1282				version_res->me_max_version.minor_version);
   1283
   1284		if (version_res->host_version_supported) {
   1285			dev->version.major_version = HBM_MAJOR_VERSION;
   1286			dev->version.minor_version = HBM_MINOR_VERSION;
   1287		} else {
   1288			dev->version.major_version =
   1289				version_res->me_max_version.major_version;
   1290			dev->version.minor_version =
   1291				version_res->me_max_version.minor_version;
   1292		}
   1293
   1294		if (!mei_hbm_version_is_supported(dev)) {
   1295			dev_warn(dev->dev, "hbm: start: version mismatch - stopping the driver.\n");
   1296
   1297			dev->hbm_state = MEI_HBM_STOPPED;
   1298			if (mei_hbm_stop_req(dev)) {
   1299				dev_err(dev->dev, "hbm: start: failed to send stop request\n");
   1300				return -EIO;
   1301			}
   1302			break;
   1303		}
   1304
   1305		mei_hbm_config_features(dev);
   1306
   1307		if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
   1308		    dev->hbm_state != MEI_HBM_STARTING) {
   1309			if (dev->dev_state == MEI_DEV_POWER_DOWN ||
   1310			    dev->dev_state == MEI_DEV_POWERING_DOWN) {
   1311				dev_dbg(dev->dev, "hbm: start: on shutdown, ignoring\n");
   1312				return 0;
   1313			}
   1314			dev_err(dev->dev, "hbm: start: state mismatch, [%d, %d]\n",
   1315				dev->dev_state, dev->hbm_state);
   1316			return -EPROTO;
   1317		}
   1318
   1319		if (dev->hbm_f_cap_supported) {
   1320			if (mei_hbm_capabilities_req(dev))
   1321				return -EIO;
   1322			wake_up(&dev->wait_hbm_start);
   1323			break;
   1324		}
   1325
   1326		if (dev->hbm_f_dr_supported) {
   1327			if (mei_dmam_ring_alloc(dev))
   1328				dev_info(dev->dev, "running w/o dma ring\n");
   1329			if (mei_dma_ring_is_allocated(dev)) {
   1330				if (mei_hbm_dma_setup_req(dev))
   1331					return -EIO;
   1332
   1333				wake_up(&dev->wait_hbm_start);
   1334				break;
   1335			}
   1336		}
   1337
   1338		dev->hbm_f_dr_supported = 0;
   1339		mei_dmam_ring_free(dev);
   1340
   1341		if (mei_hbm_enum_clients_req(dev))
   1342			return -EIO;
   1343
   1344		wake_up(&dev->wait_hbm_start);
   1345		break;
   1346
   1347	case MEI_HBM_CAPABILITIES_RES_CMD:
   1348		dev_dbg(dev->dev, "hbm: capabilities response: message received.\n");
   1349
   1350		dev->init_clients_timer = 0;
   1351
   1352		if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
   1353		    dev->hbm_state != MEI_HBM_CAP_SETUP) {
   1354			if (dev->dev_state == MEI_DEV_POWER_DOWN ||
   1355			    dev->dev_state == MEI_DEV_POWERING_DOWN) {
   1356				dev_dbg(dev->dev, "hbm: capabilities response: on shutdown, ignoring\n");
   1357				return 0;
   1358			}
   1359			dev_err(dev->dev, "hbm: capabilities response: state mismatch, [%d, %d]\n",
   1360				dev->dev_state, dev->hbm_state);
   1361			return -EPROTO;
   1362		}
   1363
   1364		capability_res = (struct hbm_capability_response *)mei_msg;
   1365		if (!(capability_res->capability_granted[0] & HBM_CAP_VT))
   1366			dev->hbm_f_vt_supported = 0;
   1367		if (!(capability_res->capability_granted[0] & HBM_CAP_CD))
   1368			dev->hbm_f_cd_supported = 0;
   1369
   1370		if (dev->hbm_f_dr_supported) {
   1371			if (mei_dmam_ring_alloc(dev))
   1372				dev_info(dev->dev, "running w/o dma ring\n");
   1373			if (mei_dma_ring_is_allocated(dev)) {
   1374				if (mei_hbm_dma_setup_req(dev))
   1375					return -EIO;
   1376				break;
   1377			}
   1378		}
   1379
   1380		dev->hbm_f_dr_supported = 0;
   1381		mei_dmam_ring_free(dev);
   1382
   1383		if (mei_hbm_enum_clients_req(dev))
   1384			return -EIO;
   1385		break;
   1386
   1387	case MEI_HBM_DMA_SETUP_RES_CMD:
   1388		dev_dbg(dev->dev, "hbm: dma setup response: message received.\n");
   1389
   1390		dev->init_clients_timer = 0;
   1391
   1392		if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
   1393		    dev->hbm_state != MEI_HBM_DR_SETUP) {
   1394			if (dev->dev_state == MEI_DEV_POWER_DOWN ||
   1395			    dev->dev_state == MEI_DEV_POWERING_DOWN) {
   1396				dev_dbg(dev->dev, "hbm: dma setup response: on shutdown, ignoring\n");
   1397				return 0;
   1398			}
   1399			dev_err(dev->dev, "hbm: dma setup response: state mismatch, [%d, %d]\n",
   1400				dev->dev_state, dev->hbm_state);
   1401			return -EPROTO;
   1402		}
   1403
   1404		dma_setup_res = (struct hbm_dma_setup_response *)mei_msg;
   1405
   1406		if (dma_setup_res->status) {
   1407			u8 status = dma_setup_res->status;
   1408
   1409			if (status == MEI_HBMS_NOT_ALLOWED) {
   1410				dev_dbg(dev->dev, "hbm: dma setup not allowed\n");
   1411			} else {
   1412				dev_info(dev->dev, "hbm: dma setup response: failure = %d %s\n",
   1413					 status,
   1414					 mei_hbm_status_str(status));
   1415			}
   1416			dev->hbm_f_dr_supported = 0;
   1417			mei_dmam_ring_free(dev);
   1418		}
   1419
   1420		if (mei_hbm_enum_clients_req(dev))
   1421			return -EIO;
   1422		break;
   1423
   1424	case CLIENT_CONNECT_RES_CMD:
   1425		dev_dbg(dev->dev, "hbm: client connect response: message received.\n");
   1426		mei_hbm_cl_res(dev, cl_cmd, MEI_FOP_CONNECT);
   1427		break;
   1428
   1429	case CLIENT_DISCONNECT_RES_CMD:
   1430		dev_dbg(dev->dev, "hbm: client disconnect response: message received.\n");
   1431		mei_hbm_cl_res(dev, cl_cmd, MEI_FOP_DISCONNECT);
   1432		break;
   1433
   1434	case MEI_FLOW_CONTROL_CMD:
   1435		dev_dbg(dev->dev, "hbm: client flow control response: message received.\n");
   1436
   1437		fctrl = (struct hbm_flow_control *)mei_msg;
   1438		mei_hbm_cl_tx_flow_ctrl_creds_res(dev, fctrl);
   1439		break;
   1440
   1441	case MEI_PG_ISOLATION_ENTRY_RES_CMD:
   1442		dev_dbg(dev->dev, "hbm: power gate isolation entry response received\n");
   1443		ret = mei_hbm_pg_enter_res(dev);
   1444		if (ret)
   1445			return ret;
   1446		break;
   1447
   1448	case MEI_PG_ISOLATION_EXIT_REQ_CMD:
   1449		dev_dbg(dev->dev, "hbm: power gate isolation exit request received\n");
   1450		ret = mei_hbm_pg_exit_res(dev);
   1451		if (ret)
   1452			return ret;
   1453		break;
   1454
   1455	case HOST_CLIENT_PROPERTIES_RES_CMD:
   1456		dev_dbg(dev->dev, "hbm: properties response: message received.\n");
   1457
   1458		dev->init_clients_timer = 0;
   1459
   1460		if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
   1461		    dev->hbm_state != MEI_HBM_CLIENT_PROPERTIES) {
   1462			if (dev->dev_state == MEI_DEV_POWER_DOWN ||
   1463			    dev->dev_state == MEI_DEV_POWERING_DOWN) {
   1464				dev_dbg(dev->dev, "hbm: properties response: on shutdown, ignoring\n");
   1465				return 0;
   1466			}
   1467			dev_err(dev->dev, "hbm: properties response: state mismatch, [%d, %d]\n",
   1468				dev->dev_state, dev->hbm_state);
   1469			return -EPROTO;
   1470		}
   1471
   1472		props_res = (struct hbm_props_response *)mei_msg;
   1473
   1474		if (props_res->status == MEI_HBMS_CLIENT_NOT_FOUND) {
   1475			dev_dbg(dev->dev, "hbm: properties response: %d CLIENT_NOT_FOUND\n",
   1476				props_res->me_addr);
   1477		} else if (props_res->status) {
   1478			dev_err(dev->dev, "hbm: properties response: wrong status = %d %s\n",
   1479				props_res->status,
   1480				mei_hbm_status_str(props_res->status));
   1481			return -EPROTO;
   1482		} else {
   1483			mei_hbm_me_cl_add(dev, props_res);
   1484		}
   1485
   1486		/* request property for the next client */
   1487		if (mei_hbm_prop_req(dev, props_res->me_addr + 1))
   1488			return -EIO;
   1489
   1490		break;
   1491
   1492	case HOST_ENUM_RES_CMD:
   1493		dev_dbg(dev->dev, "hbm: enumeration response: message received\n");
   1494
   1495		dev->init_clients_timer = 0;
   1496
   1497		enum_res = (struct hbm_host_enum_response *) mei_msg;
   1498		BUILD_BUG_ON(sizeof(dev->me_clients_map)
   1499				< sizeof(enum_res->valid_addresses));
   1500		memcpy(dev->me_clients_map, enum_res->valid_addresses,
   1501				sizeof(enum_res->valid_addresses));
   1502
   1503		if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
   1504		    dev->hbm_state != MEI_HBM_ENUM_CLIENTS) {
   1505			if (dev->dev_state == MEI_DEV_POWER_DOWN ||
   1506			    dev->dev_state == MEI_DEV_POWERING_DOWN) {
   1507				dev_dbg(dev->dev, "hbm: enumeration response: on shutdown, ignoring\n");
   1508				return 0;
   1509			}
   1510			dev_err(dev->dev, "hbm: enumeration response: state mismatch, [%d, %d]\n",
   1511				dev->dev_state, dev->hbm_state);
   1512			return -EPROTO;
   1513		}
   1514
   1515		dev->hbm_state = MEI_HBM_CLIENT_PROPERTIES;
   1516
   1517		/* first property request */
   1518		if (mei_hbm_prop_req(dev, 0))
   1519			return -EIO;
   1520
   1521		break;
   1522
   1523	case HOST_STOP_RES_CMD:
   1524		dev_dbg(dev->dev, "hbm: stop response: message received\n");
   1525
   1526		dev->init_clients_timer = 0;
   1527
   1528		if (dev->hbm_state != MEI_HBM_STOPPED) {
   1529			dev_err(dev->dev, "hbm: stop response: state mismatch, [%d, %d]\n",
   1530				dev->dev_state, dev->hbm_state);
   1531			return -EPROTO;
   1532		}
   1533
   1534		mei_set_devstate(dev, MEI_DEV_POWER_DOWN);
   1535		dev_info(dev->dev, "hbm: stop response: resetting.\n");
   1536		/* force the reset */
   1537		return -EPROTO;
   1538
   1539	case CLIENT_DISCONNECT_REQ_CMD:
   1540		dev_dbg(dev->dev, "hbm: disconnect request: message received\n");
   1541
   1542		disconnect_req = (struct hbm_client_connect_request *)mei_msg;
   1543		mei_hbm_fw_disconnect_req(dev, disconnect_req);
   1544		break;
   1545
   1546	case ME_STOP_REQ_CMD:
   1547		dev_dbg(dev->dev, "hbm: stop request: message received\n");
   1548		dev->hbm_state = MEI_HBM_STOPPED;
   1549		if (mei_hbm_stop_req(dev)) {
   1550			dev_err(dev->dev, "hbm: stop request: failed to send stop request\n");
   1551			return -EIO;
   1552		}
   1553		break;
   1554
   1555	case MEI_HBM_ADD_CLIENT_REQ_CMD:
   1556		dev_dbg(dev->dev, "hbm: add client request received\n");
   1557		/*
   1558		 * after the host receives the enum_resp
   1559		 * message clients may be added or removed
   1560		 */
   1561		if (dev->hbm_state <= MEI_HBM_ENUM_CLIENTS ||
   1562		    dev->hbm_state >= MEI_HBM_STOPPED) {
   1563			dev_err(dev->dev, "hbm: add client: state mismatch, [%d, %d]\n",
   1564				dev->dev_state, dev->hbm_state);
   1565			return -EPROTO;
   1566		}
   1567		add_cl_req = (struct hbm_add_client_request *)mei_msg;
   1568		ret = mei_hbm_fw_add_cl_req(dev, add_cl_req);
   1569		if (ret) {
   1570			dev_err(dev->dev, "hbm: add client: failed to send response %d\n",
   1571				ret);
   1572			return -EIO;
   1573		}
   1574		dev_dbg(dev->dev, "hbm: add client request processed\n");
   1575		break;
   1576
   1577	case MEI_HBM_NOTIFY_RES_CMD:
   1578		dev_dbg(dev->dev, "hbm: notify response received\n");
   1579		mei_hbm_cl_res(dev, cl_cmd, notify_res_to_fop(cl_cmd));
   1580		break;
   1581
   1582	case MEI_HBM_NOTIFICATION_CMD:
   1583		dev_dbg(dev->dev, "hbm: notification\n");
   1584		mei_hbm_cl_notify(dev, cl_cmd);
   1585		break;
   1586
   1587	case MEI_HBM_CLIENT_DMA_MAP_RES_CMD:
   1588		dev_dbg(dev->dev, "hbm: client dma map response: message received.\n");
   1589		client_dma_res = (struct hbm_client_dma_response *)mei_msg;
   1590		mei_hbm_cl_dma_map_res(dev, client_dma_res);
   1591		break;
   1592
   1593	case MEI_HBM_CLIENT_DMA_UNMAP_RES_CMD:
   1594		dev_dbg(dev->dev, "hbm: client dma unmap response: message received.\n");
   1595		client_dma_res = (struct hbm_client_dma_response *)mei_msg;
   1596		mei_hbm_cl_dma_unmap_res(dev, client_dma_res);
   1597		break;
   1598
   1599	default:
   1600		WARN(1, "hbm: wrong command %d\n", mei_msg->hbm_cmd);
   1601		return -EPROTO;
   1602
   1603	}
   1604	return 0;
   1605}
   1606