0001
0002
0003
0004
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
0069
0070
0071
0072
0073
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
0090
0091
0092
0093
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
0104
0105
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
0115
0116
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
0127
0128
0129
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
0141
0142
0143
0144
0145
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
0161
0162
0163
0164
0165
0166
0167
0168
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
0183
0184
0185
0186
0187
0188
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
0199
0200
0201
0202
0203
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
0220
0221
0222
0223
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
0248
0249
0250
0251
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
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
0285
0286
0287
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
0326
0327
0328
0329
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
0361
0362
0363
0364
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
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
0395
0396
0397
0398
0399
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
0427
0428
0429
0430
0431
0432
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
0458
0459
0460
0461
0462
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
0485
0486
0487
0488
0489
0490
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
0514
0515
0516
0517
0518
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
0530
0531
0532
0533
0534
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
0556
0557
0558
0559
0560
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
0577 cl->status = -EINVAL;
0578 }
0579 }
0580
0581
0582
0583
0584
0585
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
0599
0600
0601
0602
0603
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
0630
0631
0632
0633
0634
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
0718
0719
0720
0721
0722
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
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
0762
0763
0764
0765
0766
0767
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
0792
0793
0794
0795
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
0813
0814
0815
0816
0817
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
0830
0831
0832
0833
0834
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
0865
0866
0867
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
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
0891
0892
0893
0894
0895
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
0907
0908
0909
0910
0911
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
0923
0924
0925
0926
0927
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
0944
0945
0946
0947
0948
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
0960
0961
0962
0963
0964
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
0990
0991
0992
0993
0994
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
1044
1045
1046
1047
1048
1049
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
1073
1074
1075
1076
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
1095
1096
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
1106
1107
1108
1109
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
1129
1130
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
1146
1147
1148
1149
1150 static void mei_hbm_config_features(struct mei_device *dev)
1151 {
1152
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
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
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
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
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
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
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
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
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
1220
1221
1222
1223
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
1234
1235
1236
1237
1238
1239
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
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
1264
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
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
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
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
1559
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