Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2003-2020, Intel Corporation. All rights reserved.
0004  * Intel Management Engine Interface (Intel MEI) Linux driver
0005  */
0006 #include <linux/export.h>
0007 #include <linux/sched.h>
0008 #include <linux/wait.h>
0009 #include <linux/pm_runtime.h>
0010 #include <linux/slab.h>
0011 
0012 #include <linux/mei.h>
0013 
0014 #include "mei_dev.h"
0015 #include "hbm.h"
0016 #include "client.h"
0017 
0018 static const char *mei_hbm_status_str(enum mei_hbm_status status)
0019 {
0020 #define MEI_HBM_STATUS(status) case MEI_HBMS_##status: return #status
0021     switch (status) {
0022     MEI_HBM_STATUS(SUCCESS);
0023     MEI_HBM_STATUS(CLIENT_NOT_FOUND);
0024     MEI_HBM_STATUS(ALREADY_EXISTS);
0025     MEI_HBM_STATUS(REJECTED);
0026     MEI_HBM_STATUS(INVALID_PARAMETER);
0027     MEI_HBM_STATUS(NOT_ALLOWED);
0028     MEI_HBM_STATUS(ALREADY_STARTED);
0029     MEI_HBM_STATUS(NOT_STARTED);
0030     default: return "unknown";
0031     }
0032 #undef MEI_HBM_STATUS
0033 };
0034 
0035 static const char *mei_cl_conn_status_str(enum mei_cl_connect_status status)
0036 {
0037 #define MEI_CL_CS(status) case MEI_CL_CONN_##status: return #status
0038     switch (status) {
0039     MEI_CL_CS(SUCCESS);
0040     MEI_CL_CS(NOT_FOUND);
0041     MEI_CL_CS(ALREADY_STARTED);
0042     MEI_CL_CS(OUT_OF_RESOURCES);
0043     MEI_CL_CS(MESSAGE_SMALL);
0044     MEI_CL_CS(NOT_ALLOWED);
0045     default: return "unknown";
0046     }
0047 #undef MEI_CL_CCS
0048 }
0049 
0050 const char *mei_hbm_state_str(enum mei_hbm_state state)
0051 {
0052 #define MEI_HBM_STATE(state) case MEI_HBM_##state: return #state
0053     switch (state) {
0054     MEI_HBM_STATE(IDLE);
0055     MEI_HBM_STATE(STARTING);
0056     MEI_HBM_STATE(STARTED);
0057     MEI_HBM_STATE(DR_SETUP);
0058     MEI_HBM_STATE(ENUM_CLIENTS);
0059     MEI_HBM_STATE(CLIENT_PROPERTIES);
0060     MEI_HBM_STATE(STOPPED);
0061     default:
0062         return "unknown";
0063     }
0064 #undef MEI_HBM_STATE
0065 }
0066 
0067 /**
0068  * mei_cl_conn_status_to_errno - convert client connect response
0069  * status to error code
0070  *
0071  * @status: client connect response status
0072  *
0073  * Return: corresponding error code
0074  */
0075 static int mei_cl_conn_status_to_errno(enum mei_cl_connect_status status)
0076 {
0077     switch (status) {
0078     case MEI_CL_CONN_SUCCESS:          return 0;
0079     case MEI_CL_CONN_NOT_FOUND:        return -ENOTTY;
0080     case MEI_CL_CONN_ALREADY_STARTED:  return -EBUSY;
0081     case MEI_CL_CONN_OUT_OF_RESOURCES: return -EBUSY;
0082     case MEI_CL_CONN_MESSAGE_SMALL:    return -EINVAL;
0083     case MEI_CL_CONN_NOT_ALLOWED:      return -EBUSY;
0084     default:                           return -EINVAL;
0085     }
0086 }
0087 
0088 /**
0089  * mei_hbm_write_message - wrapper for sending hbm messages.
0090  *
0091  * @dev: mei device
0092  * @hdr: mei header
0093  * @data: payload
0094  */
0095 static inline int mei_hbm_write_message(struct mei_device *dev,
0096                     struct mei_msg_hdr *hdr,
0097                     const void *data)
0098 {
0099     return mei_write_message(dev, hdr, sizeof(*hdr), data, hdr->length);
0100 }
0101 
0102 /**
0103  * mei_hbm_idle - set hbm to idle state
0104  *
0105  * @dev: the device structure
0106  */
0107 void mei_hbm_idle(struct mei_device *dev)
0108 {
0109     dev->init_clients_timer = 0;
0110     dev->hbm_state = MEI_HBM_IDLE;
0111 }
0112 
0113 /**
0114  * mei_hbm_reset - reset hbm counters and book keeping data structurs
0115  *
0116  * @dev: the device structure
0117  */
0118 void mei_hbm_reset(struct mei_device *dev)
0119 {
0120     mei_me_cl_rm_all(dev);
0121 
0122     mei_hbm_idle(dev);
0123 }
0124 
0125 /**
0126  * mei_hbm_hdr - construct hbm header
0127  *
0128  * @mei_hdr: hbm header
0129  * @length: payload length
0130  */
0131 
0132 static inline void mei_hbm_hdr(struct mei_msg_hdr *mei_hdr, size_t length)
0133 {
0134     memset(mei_hdr, 0, sizeof(*mei_hdr));
0135     mei_hdr->length = length;
0136     mei_hdr->msg_complete = 1;
0137 }
0138 
0139 /**
0140  * mei_hbm_cl_hdr - construct client hbm header
0141  *
0142  * @cl: client
0143  * @hbm_cmd: host bus message command
0144  * @buf: buffer for cl header
0145  * @len: buffer length
0146  */
0147 static inline
0148 void mei_hbm_cl_hdr(struct mei_cl *cl, u8 hbm_cmd, void *buf, size_t len)
0149 {
0150     struct mei_hbm_cl_cmd *cmd = buf;
0151 
0152     memset(cmd, 0, len);
0153 
0154     cmd->hbm_cmd = hbm_cmd;
0155     cmd->host_addr = mei_cl_host_addr(cl);
0156     cmd->me_addr = mei_cl_me_id(cl);
0157 }
0158 
0159 /**
0160  * mei_hbm_cl_write - write simple hbm client message
0161  *
0162  * @dev: the device structure
0163  * @cl: client
0164  * @hbm_cmd: host bus message command
0165  * @buf: message buffer
0166  * @len: buffer length
0167  *
0168  * Return: 0 on success, <0 on failure.
0169  */
0170 static inline int mei_hbm_cl_write(struct mei_device *dev, struct mei_cl *cl,
0171                    u8 hbm_cmd, void *buf, size_t len)
0172 {
0173     struct mei_msg_hdr mei_hdr;
0174 
0175     mei_hbm_hdr(&mei_hdr, len);
0176     mei_hbm_cl_hdr(cl, hbm_cmd, buf, len);
0177 
0178     return mei_hbm_write_message(dev, &mei_hdr, buf);
0179 }
0180 
0181 /**
0182  * mei_hbm_cl_addr_equal - check if the client's and
0183  *  the message address match
0184  *
0185  * @cl: client
0186  * @cmd: hbm client message
0187  *
0188  * Return: true if addresses are the same
0189  */
0190 static inline
0191 bool mei_hbm_cl_addr_equal(struct mei_cl *cl, struct mei_hbm_cl_cmd *cmd)
0192 {
0193     return  mei_cl_host_addr(cl) == cmd->host_addr &&
0194         mei_cl_me_id(cl) == cmd->me_addr;
0195 }
0196 
0197 /**
0198  * mei_hbm_cl_find_by_cmd - find recipient client
0199  *
0200  * @dev: the device structure
0201  * @buf: a buffer with hbm cl command
0202  *
0203  * Return: the recipient client or NULL if not found
0204  */
0205 static inline
0206 struct mei_cl *mei_hbm_cl_find_by_cmd(struct mei_device *dev, void *buf)
0207 {
0208     struct mei_hbm_cl_cmd *cmd = (struct mei_hbm_cl_cmd *)buf;
0209     struct mei_cl *cl;
0210 
0211     list_for_each_entry(cl, &dev->file_list, link)
0212         if (mei_hbm_cl_addr_equal(cl, cmd))
0213             return cl;
0214     return NULL;
0215 }
0216 
0217 
0218 /**
0219  * mei_hbm_start_wait - wait for start response message.
0220  *
0221  * @dev: the device structure
0222  *
0223  * Return: 0 on success and < 0 on failure
0224  */
0225 int mei_hbm_start_wait(struct mei_device *dev)
0226 {
0227     int ret;
0228 
0229     if (dev->hbm_state > MEI_HBM_STARTING)
0230         return 0;
0231 
0232     mutex_unlock(&dev->device_lock);
0233     ret = wait_event_timeout(dev->wait_hbm_start,
0234             dev->hbm_state != MEI_HBM_STARTING,
0235             mei_secs_to_jiffies(MEI_HBM_TIMEOUT));
0236     mutex_lock(&dev->device_lock);
0237 
0238     if (ret == 0 && (dev->hbm_state <= MEI_HBM_STARTING)) {
0239         dev->hbm_state = MEI_HBM_IDLE;
0240         dev_err(dev->dev, "waiting for mei start failed\n");
0241         return -ETIME;
0242     }
0243     return 0;
0244 }
0245 
0246 /**
0247  * mei_hbm_start_req - sends start request message.
0248  *
0249  * @dev: the device structure
0250  *
0251  * Return: 0 on success and < 0 on failure
0252  */
0253 int mei_hbm_start_req(struct mei_device *dev)
0254 {
0255     struct mei_msg_hdr mei_hdr;
0256     struct hbm_host_version_request req;
0257     int ret;
0258 
0259     mei_hbm_reset(dev);
0260 
0261     mei_hbm_hdr(&mei_hdr, sizeof(req));
0262 
0263     /* host start message */
0264     memset(&req, 0, sizeof(req));
0265     req.hbm_cmd = HOST_START_REQ_CMD;
0266     req.host_version.major_version = HBM_MAJOR_VERSION;
0267     req.host_version.minor_version = HBM_MINOR_VERSION;
0268 
0269     dev->hbm_state = MEI_HBM_IDLE;
0270     ret = mei_hbm_write_message(dev, &mei_hdr, &req);
0271     if (ret) {
0272         dev_err(dev->dev, "version message write failed: ret = %d\n",
0273             ret);
0274         return ret;
0275     }
0276 
0277     dev->hbm_state = MEI_HBM_STARTING;
0278     dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
0279     mei_schedule_stall_timer(dev);
0280     return 0;
0281 }
0282 
0283 /**
0284  * mei_hbm_dma_setup_req() - setup DMA request
0285  * @dev: the device structure
0286  *
0287  * Return: 0 on success and < 0 on failure
0288  */
0289 static int mei_hbm_dma_setup_req(struct mei_device *dev)
0290 {
0291     struct mei_msg_hdr mei_hdr;
0292     struct hbm_dma_setup_request req;
0293     unsigned int i;
0294     int ret;
0295 
0296     mei_hbm_hdr(&mei_hdr, sizeof(req));
0297 
0298     memset(&req, 0, sizeof(req));
0299     req.hbm_cmd = MEI_HBM_DMA_SETUP_REQ_CMD;
0300     for (i = 0; i < DMA_DSCR_NUM; i++) {
0301         phys_addr_t paddr;
0302 
0303         paddr = dev->dr_dscr[i].daddr;
0304         req.dma_dscr[i].addr_hi = upper_32_bits(paddr);
0305         req.dma_dscr[i].addr_lo = lower_32_bits(paddr);
0306         req.dma_dscr[i].size = dev->dr_dscr[i].size;
0307     }
0308 
0309     mei_dma_ring_reset(dev);
0310 
0311     ret = mei_hbm_write_message(dev, &mei_hdr, &req);
0312     if (ret) {
0313         dev_err(dev->dev, "dma setup request write failed: ret = %d.\n",
0314             ret);
0315         return ret;
0316     }
0317 
0318     dev->hbm_state = MEI_HBM_DR_SETUP;
0319     dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
0320     mei_schedule_stall_timer(dev);
0321     return 0;
0322 }
0323 
0324 /**
0325  * mei_hbm_capabilities_req - request capabilities
0326  *
0327  * @dev: the device structure
0328  *
0329  * Return: 0 on success and < 0 on failure
0330  */
0331 static int mei_hbm_capabilities_req(struct mei_device *dev)
0332 {
0333     struct mei_msg_hdr mei_hdr;
0334     struct hbm_capability_request req;
0335     int ret;
0336 
0337     mei_hbm_hdr(&mei_hdr, sizeof(req));
0338 
0339     memset(&req, 0, sizeof(req));
0340     req.hbm_cmd = MEI_HBM_CAPABILITIES_REQ_CMD;
0341     if (dev->hbm_f_vt_supported)
0342         req.capability_requested[0] |= HBM_CAP_VT;
0343     if (dev->hbm_f_cd_supported)
0344         req.capability_requested[0] |= HBM_CAP_CD;
0345 
0346     ret = mei_hbm_write_message(dev, &mei_hdr, &req);
0347     if (ret) {
0348         dev_err(dev->dev,
0349             "capabilities request write failed: ret = %d.\n", ret);
0350         return ret;
0351     }
0352 
0353     dev->hbm_state = MEI_HBM_CAP_SETUP;
0354     dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
0355     mei_schedule_stall_timer(dev);
0356     return 0;
0357 }
0358 
0359 /**
0360  * mei_hbm_enum_clients_req - sends enumeration client request message.
0361  *
0362  * @dev: the device structure
0363  *
0364  * Return: 0 on success and < 0 on failure
0365  */
0366 static int mei_hbm_enum_clients_req(struct mei_device *dev)
0367 {
0368     struct mei_msg_hdr mei_hdr;
0369     struct hbm_host_enum_request req;
0370     int ret;
0371 
0372     /* enumerate clients */
0373     mei_hbm_hdr(&mei_hdr, sizeof(req));
0374 
0375     memset(&req, 0, sizeof(req));
0376     req.hbm_cmd = HOST_ENUM_REQ_CMD;
0377     req.flags |= dev->hbm_f_dc_supported ? MEI_HBM_ENUM_F_ALLOW_ADD : 0;
0378     req.flags |= dev->hbm_f_ie_supported ?
0379               MEI_HBM_ENUM_F_IMMEDIATE_ENUM : 0;
0380 
0381     ret = mei_hbm_write_message(dev, &mei_hdr, &req);
0382     if (ret) {
0383         dev_err(dev->dev, "enumeration request write failed: ret = %d.\n",
0384             ret);
0385         return ret;
0386     }
0387     dev->hbm_state = MEI_HBM_ENUM_CLIENTS;
0388     dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
0389     mei_schedule_stall_timer(dev);
0390     return 0;
0391 }
0392 
0393 /**
0394  * mei_hbm_me_cl_add - add new me client to the list
0395  *
0396  * @dev: the device structure
0397  * @res: hbm property response
0398  *
0399  * Return: 0 on success and -ENOMEM on allocation failure
0400  */
0401 
0402 static int mei_hbm_me_cl_add(struct mei_device *dev,
0403                  struct hbm_props_response *res)
0404 {
0405     struct mei_me_client *me_cl;
0406     const uuid_le *uuid = &res->client_properties.protocol_name;
0407 
0408     mei_me_cl_rm_by_uuid(dev, uuid);
0409 
0410     me_cl = kzalloc(sizeof(*me_cl), GFP_KERNEL);
0411     if (!me_cl)
0412         return -ENOMEM;
0413 
0414     mei_me_cl_init(me_cl);
0415 
0416     me_cl->props = res->client_properties;
0417     me_cl->client_id = res->me_addr;
0418     me_cl->tx_flow_ctrl_creds = 0;
0419 
0420     mei_me_cl_add(dev, me_cl);
0421 
0422     return 0;
0423 }
0424 
0425 /**
0426  * mei_hbm_add_cl_resp - send response to fw on client add request
0427  *
0428  * @dev: the device structure
0429  * @addr: me address
0430  * @status: response status
0431  *
0432  * Return: 0 on success and < 0 on failure
0433  */
0434 static int mei_hbm_add_cl_resp(struct mei_device *dev, u8 addr, u8 status)
0435 {
0436     struct mei_msg_hdr mei_hdr;
0437     struct hbm_add_client_response resp;
0438     int ret;
0439 
0440     dev_dbg(dev->dev, "adding client response\n");
0441 
0442     mei_hbm_hdr(&mei_hdr, sizeof(resp));
0443 
0444     memset(&resp, 0, sizeof(resp));
0445     resp.hbm_cmd = MEI_HBM_ADD_CLIENT_RES_CMD;
0446     resp.me_addr = addr;
0447     resp.status  = status;
0448 
0449     ret = mei_hbm_write_message(dev, &mei_hdr, &resp);
0450     if (ret)
0451         dev_err(dev->dev, "add client response write failed: ret = %d\n",
0452             ret);
0453     return ret;
0454 }
0455 
0456 /**
0457  * mei_hbm_fw_add_cl_req - request from the fw to add a client
0458  *
0459  * @dev: the device structure
0460  * @req: add client request
0461  *
0462  * Return: 0 on success and < 0 on failure
0463  */
0464 static int mei_hbm_fw_add_cl_req(struct mei_device *dev,
0465                   struct hbm_add_client_request *req)
0466 {
0467     int ret;
0468     u8 status = MEI_HBMS_SUCCESS;
0469 
0470     BUILD_BUG_ON(sizeof(struct hbm_add_client_request) !=
0471             sizeof(struct hbm_props_response));
0472 
0473     ret = mei_hbm_me_cl_add(dev, (struct hbm_props_response *)req);
0474     if (ret)
0475         status = !MEI_HBMS_SUCCESS;
0476 
0477     if (dev->dev_state == MEI_DEV_ENABLED)
0478         schedule_work(&dev->bus_rescan_work);
0479 
0480     return mei_hbm_add_cl_resp(dev, req->me_addr, status);
0481 }
0482 
0483 /**
0484  * mei_hbm_cl_notify_req - send notification request
0485  *
0486  * @dev: the device structure
0487  * @cl: a client to disconnect from
0488  * @start: true for start false for stop
0489  *
0490  * Return: 0 on success and -EIO on write failure
0491  */
0492 int mei_hbm_cl_notify_req(struct mei_device *dev,
0493               struct mei_cl *cl, u8 start)
0494 {
0495 
0496     struct mei_msg_hdr mei_hdr;
0497     struct hbm_notification_request req;
0498     int ret;
0499 
0500     mei_hbm_hdr(&mei_hdr, sizeof(req));
0501     mei_hbm_cl_hdr(cl, MEI_HBM_NOTIFY_REQ_CMD, &req, sizeof(req));
0502 
0503     req.start = start;
0504 
0505     ret = mei_hbm_write_message(dev, &mei_hdr, &req);
0506     if (ret)
0507         dev_err(dev->dev, "notify request failed: ret = %d\n", ret);
0508 
0509     return ret;
0510 }
0511 
0512 /**
0513  *  notify_res_to_fop - convert notification response to the proper
0514  *      notification FOP
0515  *
0516  * @cmd: client notification start response command
0517  *
0518  * Return:  MEI_FOP_NOTIFY_START or MEI_FOP_NOTIFY_STOP;
0519  */
0520 static inline enum mei_cb_file_ops notify_res_to_fop(struct mei_hbm_cl_cmd *cmd)
0521 {
0522     struct hbm_notification_response *rs =
0523         (struct hbm_notification_response *)cmd;
0524 
0525     return mei_cl_notify_req2fop(rs->start);
0526 }
0527 
0528 /**
0529  * mei_hbm_cl_notify_start_res - update the client state according
0530  *       notify start response
0531  *
0532  * @dev: the device structure
0533  * @cl: mei host client
0534  * @cmd: client notification start response command
0535  */
0536 static void mei_hbm_cl_notify_start_res(struct mei_device *dev,
0537                     struct mei_cl *cl,
0538                     struct mei_hbm_cl_cmd *cmd)
0539 {
0540     struct hbm_notification_response *rs =
0541         (struct hbm_notification_response *)cmd;
0542 
0543     cl_dbg(dev, cl, "hbm: notify start response status=%d\n", rs->status);
0544 
0545     if (rs->status == MEI_HBMS_SUCCESS ||
0546         rs->status == MEI_HBMS_ALREADY_STARTED) {
0547         cl->notify_en = true;
0548         cl->status = 0;
0549     } else {
0550         cl->status = -EINVAL;
0551     }
0552 }
0553 
0554 /**
0555  * mei_hbm_cl_notify_stop_res - update the client state according
0556  *       notify stop response
0557  *
0558  * @dev: the device structure
0559  * @cl: mei host client
0560  * @cmd: client notification stop response command
0561  */
0562 static void mei_hbm_cl_notify_stop_res(struct mei_device *dev,
0563                        struct mei_cl *cl,
0564                        struct mei_hbm_cl_cmd *cmd)
0565 {
0566     struct hbm_notification_response *rs =
0567         (struct hbm_notification_response *)cmd;
0568 
0569     cl_dbg(dev, cl, "hbm: notify stop response status=%d\n", rs->status);
0570 
0571     if (rs->status == MEI_HBMS_SUCCESS ||
0572         rs->status == MEI_HBMS_NOT_STARTED) {
0573         cl->notify_en = false;
0574         cl->status = 0;
0575     } else {
0576         /* TODO: spec is not clear yet about other possible issues */
0577         cl->status = -EINVAL;
0578     }
0579 }
0580 
0581 /**
0582  * mei_hbm_cl_notify - signal notification event
0583  *
0584  * @dev: the device structure
0585  * @cmd: notification client message
0586  */
0587 static void mei_hbm_cl_notify(struct mei_device *dev,
0588                   struct mei_hbm_cl_cmd *cmd)
0589 {
0590     struct mei_cl *cl;
0591 
0592     cl = mei_hbm_cl_find_by_cmd(dev, cmd);
0593     if (cl)
0594         mei_cl_notify(cl);
0595 }
0596 
0597 /**
0598  * mei_hbm_cl_dma_map_req - send client dma map request
0599  *
0600  * @dev: the device structure
0601  * @cl: mei host client
0602  *
0603  * Return: 0 on success and -EIO on write failure
0604  */
0605 int mei_hbm_cl_dma_map_req(struct mei_device *dev, struct mei_cl *cl)
0606 {
0607     struct mei_msg_hdr mei_hdr;
0608     struct hbm_client_dma_map_request req;
0609     int ret;
0610 
0611     mei_hbm_hdr(&mei_hdr, sizeof(req));
0612 
0613     memset(&req, 0, sizeof(req));
0614 
0615     req.hbm_cmd = MEI_HBM_CLIENT_DMA_MAP_REQ_CMD;
0616     req.client_buffer_id = cl->dma.buffer_id;
0617     req.address_lsb = lower_32_bits(cl->dma.daddr);
0618     req.address_msb = upper_32_bits(cl->dma.daddr);
0619     req.size = cl->dma.size;
0620 
0621     ret = mei_hbm_write_message(dev, &mei_hdr, &req);
0622     if (ret)
0623         dev_err(dev->dev, "dma map request failed: ret = %d\n", ret);
0624 
0625     return ret;
0626 }
0627 
0628 /**
0629  * mei_hbm_cl_dma_unmap_req - send client dma unmap request
0630  *
0631  * @dev: the device structure
0632  * @cl: mei host client
0633  *
0634  * Return: 0 on success and -EIO on write failure
0635  */
0636 int mei_hbm_cl_dma_unmap_req(struct mei_device *dev, struct mei_cl *cl)
0637 {
0638     struct mei_msg_hdr mei_hdr;
0639     struct hbm_client_dma_unmap_request req;
0640     int ret;
0641 
0642     mei_hbm_hdr(&mei_hdr, sizeof(req));
0643 
0644     memset(&req, 0, sizeof(req));
0645 
0646     req.hbm_cmd = MEI_HBM_CLIENT_DMA_UNMAP_REQ_CMD;
0647     req.client_buffer_id = cl->dma.buffer_id;
0648 
0649     ret = mei_hbm_write_message(dev, &mei_hdr, &req);
0650     if (ret)
0651         dev_err(dev->dev, "dma unmap request failed: ret = %d\n", ret);
0652 
0653     return ret;
0654 }
0655 
0656 static void mei_hbm_cl_dma_map_res(struct mei_device *dev,
0657                    struct hbm_client_dma_response *res)
0658 {
0659     struct mei_cl *cl;
0660     struct mei_cl_cb *cb, *next;
0661 
0662     cl = NULL;
0663     list_for_each_entry_safe(cb, next, &dev->ctrl_rd_list, list) {
0664         if (cb->fop_type != MEI_FOP_DMA_MAP)
0665             continue;
0666         if (!cb->cl->dma.buffer_id || cb->cl->dma_mapped)
0667             continue;
0668 
0669         cl = cb->cl;
0670         break;
0671     }
0672     if (!cl)
0673         return;
0674 
0675     if (res->status) {
0676         dev_err(dev->dev, "cl dma map failed %d\n", res->status);
0677         cl->status = -EFAULT;
0678     } else {
0679         dev_dbg(dev->dev, "cl dma map succeeded\n");
0680         cl->dma_mapped = 1;
0681         cl->status = 0;
0682     }
0683     wake_up(&cl->wait);
0684 }
0685 
0686 static void mei_hbm_cl_dma_unmap_res(struct mei_device *dev,
0687                      struct hbm_client_dma_response *res)
0688 {
0689     struct mei_cl *cl;
0690     struct mei_cl_cb *cb, *next;
0691 
0692     cl = NULL;
0693     list_for_each_entry_safe(cb, next, &dev->ctrl_rd_list, list) {
0694         if (cb->fop_type != MEI_FOP_DMA_UNMAP)
0695             continue;
0696         if (!cb->cl->dma.buffer_id || !cb->cl->dma_mapped)
0697             continue;
0698 
0699         cl = cb->cl;
0700         break;
0701     }
0702     if (!cl)
0703         return;
0704 
0705     if (res->status) {
0706         dev_err(dev->dev, "cl dma unmap failed %d\n", res->status);
0707         cl->status = -EFAULT;
0708     } else {
0709         dev_dbg(dev->dev, "cl dma unmap succeeded\n");
0710         cl->dma_mapped = 0;
0711         cl->status = 0;
0712     }
0713     wake_up(&cl->wait);
0714 }
0715 
0716 /**
0717  * mei_hbm_prop_req - request property for a single client
0718  *
0719  * @dev: the device structure
0720  * @start_idx: client index to start search
0721  *
0722  * Return: 0 on success and < 0 on failure
0723  */
0724 static int mei_hbm_prop_req(struct mei_device *dev, unsigned long start_idx)
0725 {
0726     struct mei_msg_hdr mei_hdr;
0727     struct hbm_props_request req;
0728     unsigned long addr;
0729     int ret;
0730 
0731     addr = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX, start_idx);
0732 
0733     /* We got all client properties */
0734     if (addr == MEI_CLIENTS_MAX) {
0735         dev->hbm_state = MEI_HBM_STARTED;
0736         mei_host_client_init(dev);
0737         return 0;
0738     }
0739 
0740     mei_hbm_hdr(&mei_hdr, sizeof(req));
0741 
0742     memset(&req, 0, sizeof(req));
0743 
0744     req.hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD;
0745     req.me_addr = addr;
0746 
0747     ret = mei_hbm_write_message(dev, &mei_hdr, &req);
0748     if (ret) {
0749         dev_err(dev->dev, "properties request write failed: ret = %d\n",
0750             ret);
0751         return ret;
0752     }
0753 
0754     dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
0755     mei_schedule_stall_timer(dev);
0756 
0757     return 0;
0758 }
0759 
0760 /**
0761  * mei_hbm_pg - sends pg command
0762  *
0763  * @dev: the device structure
0764  * @pg_cmd: the pg command code
0765  *
0766  * Return: -EIO on write failure
0767  *         -EOPNOTSUPP if the operation is not supported by the protocol
0768  */
0769 int mei_hbm_pg(struct mei_device *dev, u8 pg_cmd)
0770 {
0771     struct mei_msg_hdr mei_hdr;
0772     struct hbm_power_gate req;
0773     int ret;
0774 
0775     if (!dev->hbm_f_pg_supported)
0776         return -EOPNOTSUPP;
0777 
0778     mei_hbm_hdr(&mei_hdr, sizeof(req));
0779 
0780     memset(&req, 0, sizeof(req));
0781     req.hbm_cmd = pg_cmd;
0782 
0783     ret = mei_hbm_write_message(dev, &mei_hdr, &req);
0784     if (ret)
0785         dev_err(dev->dev, "power gate command write failed.\n");
0786     return ret;
0787 }
0788 EXPORT_SYMBOL_GPL(mei_hbm_pg);
0789 
0790 /**
0791  * mei_hbm_stop_req - send stop request message
0792  *
0793  * @dev: mei device
0794  *
0795  * Return: -EIO on write failure
0796  */
0797 static int mei_hbm_stop_req(struct mei_device *dev)
0798 {
0799     struct mei_msg_hdr mei_hdr;
0800     struct hbm_host_stop_request req;
0801 
0802     mei_hbm_hdr(&mei_hdr, sizeof(req));
0803 
0804     memset(&req, 0, sizeof(req));
0805     req.hbm_cmd = HOST_STOP_REQ_CMD;
0806     req.reason = DRIVER_STOP_REQUEST;
0807 
0808     return mei_hbm_write_message(dev, &mei_hdr, &req);
0809 }
0810 
0811 /**
0812  * mei_hbm_cl_flow_control_req - sends flow control request.
0813  *
0814  * @dev: the device structure
0815  * @cl: client info
0816  *
0817  * Return: -EIO on write failure
0818  */
0819 int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl)
0820 {
0821     struct hbm_flow_control req;
0822 
0823     cl_dbg(dev, cl, "sending flow control\n");
0824     return mei_hbm_cl_write(dev, cl, MEI_FLOW_CONTROL_CMD,
0825                 &req, sizeof(req));
0826 }
0827 
0828 /**
0829  * mei_hbm_add_single_tx_flow_ctrl_creds - adds single buffer credentials.
0830  *
0831  * @dev: the device structure
0832  * @fctrl: flow control response bus message
0833  *
0834  * Return: 0 on success, < 0 otherwise
0835  */
0836 static int mei_hbm_add_single_tx_flow_ctrl_creds(struct mei_device *dev,
0837                          struct hbm_flow_control *fctrl)
0838 {
0839     struct mei_me_client *me_cl;
0840     int rets;
0841 
0842     me_cl = mei_me_cl_by_id(dev, fctrl->me_addr);
0843     if (!me_cl) {
0844         dev_err(dev->dev, "no such me client %d\n", fctrl->me_addr);
0845         return -ENOENT;
0846     }
0847 
0848     if (WARN_ON(me_cl->props.single_recv_buf == 0)) {
0849         rets = -EINVAL;
0850         goto out;
0851     }
0852 
0853     me_cl->tx_flow_ctrl_creds++;
0854     dev_dbg(dev->dev, "recv flow ctrl msg ME %d (single) creds = %d.\n",
0855         fctrl->me_addr, me_cl->tx_flow_ctrl_creds);
0856 
0857     rets = 0;
0858 out:
0859     mei_me_cl_put(me_cl);
0860     return rets;
0861 }
0862 
0863 /**
0864  * mei_hbm_cl_tx_flow_ctrl_creds_res - flow control response from me
0865  *
0866  * @dev: the device structure
0867  * @fctrl: flow control response bus message
0868  */
0869 static void mei_hbm_cl_tx_flow_ctrl_creds_res(struct mei_device *dev,
0870                            struct hbm_flow_control *fctrl)
0871 {
0872     struct mei_cl *cl;
0873 
0874     if (!fctrl->host_addr) {
0875         /* single receive buffer */
0876         mei_hbm_add_single_tx_flow_ctrl_creds(dev, fctrl);
0877         return;
0878     }
0879 
0880     cl = mei_hbm_cl_find_by_cmd(dev, fctrl);
0881     if (cl) {
0882         cl->tx_flow_ctrl_creds++;
0883         cl_dbg(dev, cl, "flow control creds = %d.\n",
0884                 cl->tx_flow_ctrl_creds);
0885     }
0886 }
0887 
0888 
0889 /**
0890  * mei_hbm_cl_disconnect_req - sends disconnect message to fw.
0891  *
0892  * @dev: the device structure
0893  * @cl: a client to disconnect from
0894  *
0895  * Return: -EIO on write failure
0896  */
0897 int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl)
0898 {
0899     struct hbm_client_connect_request req;
0900 
0901     return mei_hbm_cl_write(dev, cl, CLIENT_DISCONNECT_REQ_CMD,
0902                 &req, sizeof(req));
0903 }
0904 
0905 /**
0906  * mei_hbm_cl_disconnect_rsp - sends disconnect respose to the FW
0907  *
0908  * @dev: the device structure
0909  * @cl: a client to disconnect from
0910  *
0911  * Return: -EIO on write failure
0912  */
0913 int mei_hbm_cl_disconnect_rsp(struct mei_device *dev, struct mei_cl *cl)
0914 {
0915     struct hbm_client_connect_response resp;
0916 
0917     return mei_hbm_cl_write(dev, cl, CLIENT_DISCONNECT_RES_CMD,
0918                 &resp, sizeof(resp));
0919 }
0920 
0921 /**
0922  * mei_hbm_cl_disconnect_res - update the client state according
0923  *       disconnect response
0924  *
0925  * @dev: the device structure
0926  * @cl: mei host client
0927  * @cmd: disconnect client response host bus message
0928  */
0929 static void mei_hbm_cl_disconnect_res(struct mei_device *dev, struct mei_cl *cl,
0930                       struct mei_hbm_cl_cmd *cmd)
0931 {
0932     struct hbm_client_connect_response *rs =
0933         (struct hbm_client_connect_response *)cmd;
0934 
0935     cl_dbg(dev, cl, "hbm: disconnect response status=%d\n", rs->status);
0936 
0937     if (rs->status == MEI_CL_DISCONN_SUCCESS)
0938         cl->state = MEI_FILE_DISCONNECT_REPLY;
0939     cl->status = 0;
0940 }
0941 
0942 /**
0943  * mei_hbm_cl_connect_req - send connection request to specific me client
0944  *
0945  * @dev: the device structure
0946  * @cl: a client to connect to
0947  *
0948  * Return: -EIO on write failure
0949  */
0950 int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl)
0951 {
0952     struct hbm_client_connect_request req;
0953 
0954     return mei_hbm_cl_write(dev, cl, CLIENT_CONNECT_REQ_CMD,
0955                 &req, sizeof(req));
0956 }
0957 
0958 /**
0959  * mei_hbm_cl_connect_res - update the client state according
0960  *        connection response
0961  *
0962  * @dev: the device structure
0963  * @cl: mei host client
0964  * @cmd: connect client response host bus message
0965  */
0966 static void mei_hbm_cl_connect_res(struct mei_device *dev, struct mei_cl *cl,
0967                    struct mei_hbm_cl_cmd *cmd)
0968 {
0969     struct hbm_client_connect_response *rs =
0970         (struct hbm_client_connect_response *)cmd;
0971 
0972     cl_dbg(dev, cl, "hbm: connect response status=%s\n",
0973             mei_cl_conn_status_str(rs->status));
0974 
0975     if (rs->status == MEI_CL_CONN_SUCCESS)
0976         cl->state = MEI_FILE_CONNECTED;
0977     else {
0978         cl->state = MEI_FILE_DISCONNECT_REPLY;
0979         if (rs->status == MEI_CL_CONN_NOT_FOUND) {
0980             mei_me_cl_del(dev, cl->me_cl);
0981             if (dev->dev_state == MEI_DEV_ENABLED)
0982                 schedule_work(&dev->bus_rescan_work);
0983         }
0984     }
0985     cl->status = mei_cl_conn_status_to_errno(rs->status);
0986 }
0987 
0988 /**
0989  * mei_hbm_cl_res - process hbm response received on behalf
0990  *         an client
0991  *
0992  * @dev: the device structure
0993  * @rs:  hbm client message
0994  * @fop_type: file operation type
0995  */
0996 static void mei_hbm_cl_res(struct mei_device *dev,
0997                struct mei_hbm_cl_cmd *rs,
0998                enum mei_cb_file_ops fop_type)
0999 {
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  */
1051 static 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  */
1078 static 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  */
1098 void mei_hbm_pg_resume(struct mei_device *dev)
1099 {
1100     pm_request_resume(dev->dev);
1101 }
1102 EXPORT_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  */
1111 static 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  */
1150 static 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  */
1225 bool 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  */
1241 int 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