df0f62de3dcaf16088b894400f6fcd8dd2671f34
[platform/kernel/linux-starfive.git] / drivers / misc / mei / hbm.c
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
18 static 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
35 static 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
50 const 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  */
75 static 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  */
95 static 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  */
107 void 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  */
118 void 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
132 static 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  */
147 static inline
148 void 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  */
170 static 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  */
190 static inline
191 bool 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  */
205 static inline
206 struct 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  */
225 int 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  */
253 int 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  */
289 static 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  */
331 static 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
344         ret = mei_hbm_write_message(dev, &mei_hdr, &req);
345         if (ret) {
346                 dev_err(dev->dev,
347                         "capabilities request write failed: ret = %d.\n", ret);
348                 return ret;
349         }
350
351         dev->hbm_state = MEI_HBM_CAP_SETUP;
352         dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
353         mei_schedule_stall_timer(dev);
354         return 0;
355 }
356
357 /**
358  * mei_hbm_enum_clients_req - sends enumeration client request message.
359  *
360  * @dev: the device structure
361  *
362  * Return: 0 on success and < 0 on failure
363  */
364 static int mei_hbm_enum_clients_req(struct mei_device *dev)
365 {
366         struct mei_msg_hdr mei_hdr;
367         struct hbm_host_enum_request req;
368         int ret;
369
370         /* enumerate clients */
371         mei_hbm_hdr(&mei_hdr, sizeof(req));
372
373         memset(&req, 0, sizeof(req));
374         req.hbm_cmd = HOST_ENUM_REQ_CMD;
375         req.flags |= dev->hbm_f_dc_supported ? MEI_HBM_ENUM_F_ALLOW_ADD : 0;
376         req.flags |= dev->hbm_f_ie_supported ?
377                           MEI_HBM_ENUM_F_IMMEDIATE_ENUM : 0;
378
379         ret = mei_hbm_write_message(dev, &mei_hdr, &req);
380         if (ret) {
381                 dev_err(dev->dev, "enumeration request write failed: ret = %d.\n",
382                         ret);
383                 return ret;
384         }
385         dev->hbm_state = MEI_HBM_ENUM_CLIENTS;
386         dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
387         mei_schedule_stall_timer(dev);
388         return 0;
389 }
390
391 /**
392  * mei_hbm_me_cl_add - add new me client to the list
393  *
394  * @dev: the device structure
395  * @res: hbm property response
396  *
397  * Return: 0 on success and -ENOMEM on allocation failure
398  */
399
400 static int mei_hbm_me_cl_add(struct mei_device *dev,
401                              struct hbm_props_response *res)
402 {
403         struct mei_me_client *me_cl;
404         const uuid_le *uuid = &res->client_properties.protocol_name;
405
406         mei_me_cl_rm_by_uuid(dev, uuid);
407
408         me_cl = kzalloc(sizeof(*me_cl), GFP_KERNEL);
409         if (!me_cl)
410                 return -ENOMEM;
411
412         mei_me_cl_init(me_cl);
413
414         me_cl->props = res->client_properties;
415         me_cl->client_id = res->me_addr;
416         me_cl->tx_flow_ctrl_creds = 0;
417
418         mei_me_cl_add(dev, me_cl);
419
420         return 0;
421 }
422
423 /**
424  * mei_hbm_add_cl_resp - send response to fw on client add request
425  *
426  * @dev: the device structure
427  * @addr: me address
428  * @status: response status
429  *
430  * Return: 0 on success and < 0 on failure
431  */
432 static int mei_hbm_add_cl_resp(struct mei_device *dev, u8 addr, u8 status)
433 {
434         struct mei_msg_hdr mei_hdr;
435         struct hbm_add_client_response resp;
436         int ret;
437
438         dev_dbg(dev->dev, "adding client response\n");
439
440         mei_hbm_hdr(&mei_hdr, sizeof(resp));
441
442         memset(&resp, 0, sizeof(resp));
443         resp.hbm_cmd = MEI_HBM_ADD_CLIENT_RES_CMD;
444         resp.me_addr = addr;
445         resp.status  = status;
446
447         ret = mei_hbm_write_message(dev, &mei_hdr, &resp);
448         if (ret)
449                 dev_err(dev->dev, "add client response write failed: ret = %d\n",
450                         ret);
451         return ret;
452 }
453
454 /**
455  * mei_hbm_fw_add_cl_req - request from the fw to add a client
456  *
457  * @dev: the device structure
458  * @req: add client request
459  *
460  * Return: 0 on success and < 0 on failure
461  */
462 static int mei_hbm_fw_add_cl_req(struct mei_device *dev,
463                               struct hbm_add_client_request *req)
464 {
465         int ret;
466         u8 status = MEI_HBMS_SUCCESS;
467
468         BUILD_BUG_ON(sizeof(struct hbm_add_client_request) !=
469                         sizeof(struct hbm_props_response));
470
471         ret = mei_hbm_me_cl_add(dev, (struct hbm_props_response *)req);
472         if (ret)
473                 status = !MEI_HBMS_SUCCESS;
474
475         if (dev->dev_state == MEI_DEV_ENABLED)
476                 schedule_work(&dev->bus_rescan_work);
477
478         return mei_hbm_add_cl_resp(dev, req->me_addr, status);
479 }
480
481 /**
482  * mei_hbm_cl_notify_req - send notification request
483  *
484  * @dev: the device structure
485  * @cl: a client to disconnect from
486  * @start: true for start false for stop
487  *
488  * Return: 0 on success and -EIO on write failure
489  */
490 int mei_hbm_cl_notify_req(struct mei_device *dev,
491                           struct mei_cl *cl, u8 start)
492 {
493
494         struct mei_msg_hdr mei_hdr;
495         struct hbm_notification_request req;
496         int ret;
497
498         mei_hbm_hdr(&mei_hdr, sizeof(req));
499         mei_hbm_cl_hdr(cl, MEI_HBM_NOTIFY_REQ_CMD, &req, sizeof(req));
500
501         req.start = start;
502
503         ret = mei_hbm_write_message(dev, &mei_hdr, &req);
504         if (ret)
505                 dev_err(dev->dev, "notify request failed: ret = %d\n", ret);
506
507         return ret;
508 }
509
510 /**
511  *  notify_res_to_fop - convert notification response to the proper
512  *      notification FOP
513  *
514  * @cmd: client notification start response command
515  *
516  * Return:  MEI_FOP_NOTIFY_START or MEI_FOP_NOTIFY_STOP;
517  */
518 static inline enum mei_cb_file_ops notify_res_to_fop(struct mei_hbm_cl_cmd *cmd)
519 {
520         struct hbm_notification_response *rs =
521                 (struct hbm_notification_response *)cmd;
522
523         return mei_cl_notify_req2fop(rs->start);
524 }
525
526 /**
527  * mei_hbm_cl_notify_start_res - update the client state according
528  *       notify start response
529  *
530  * @dev: the device structure
531  * @cl: mei host client
532  * @cmd: client notification start response command
533  */
534 static void mei_hbm_cl_notify_start_res(struct mei_device *dev,
535                                         struct mei_cl *cl,
536                                         struct mei_hbm_cl_cmd *cmd)
537 {
538         struct hbm_notification_response *rs =
539                 (struct hbm_notification_response *)cmd;
540
541         cl_dbg(dev, cl, "hbm: notify start response status=%d\n", rs->status);
542
543         if (rs->status == MEI_HBMS_SUCCESS ||
544             rs->status == MEI_HBMS_ALREADY_STARTED) {
545                 cl->notify_en = true;
546                 cl->status = 0;
547         } else {
548                 cl->status = -EINVAL;
549         }
550 }
551
552 /**
553  * mei_hbm_cl_notify_stop_res - update the client state according
554  *       notify stop response
555  *
556  * @dev: the device structure
557  * @cl: mei host client
558  * @cmd: client notification stop response command
559  */
560 static void mei_hbm_cl_notify_stop_res(struct mei_device *dev,
561                                        struct mei_cl *cl,
562                                        struct mei_hbm_cl_cmd *cmd)
563 {
564         struct hbm_notification_response *rs =
565                 (struct hbm_notification_response *)cmd;
566
567         cl_dbg(dev, cl, "hbm: notify stop response status=%d\n", rs->status);
568
569         if (rs->status == MEI_HBMS_SUCCESS ||
570             rs->status == MEI_HBMS_NOT_STARTED) {
571                 cl->notify_en = false;
572                 cl->status = 0;
573         } else {
574                 /* TODO: spec is not clear yet about other possible issues */
575                 cl->status = -EINVAL;
576         }
577 }
578
579 /**
580  * mei_hbm_cl_notify - signal notification event
581  *
582  * @dev: the device structure
583  * @cmd: notification client message
584  */
585 static void mei_hbm_cl_notify(struct mei_device *dev,
586                               struct mei_hbm_cl_cmd *cmd)
587 {
588         struct mei_cl *cl;
589
590         cl = mei_hbm_cl_find_by_cmd(dev, cmd);
591         if (cl)
592                 mei_cl_notify(cl);
593 }
594
595 /**
596  * mei_hbm_prop_req - request property for a single client
597  *
598  * @dev: the device structure
599  * @start_idx: client index to start search
600  *
601  * Return: 0 on success and < 0 on failure
602  */
603 static int mei_hbm_prop_req(struct mei_device *dev, unsigned long start_idx)
604 {
605         struct mei_msg_hdr mei_hdr;
606         struct hbm_props_request req;
607         unsigned long addr;
608         int ret;
609
610         addr = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX, start_idx);
611
612         /* We got all client properties */
613         if (addr == MEI_CLIENTS_MAX) {
614                 dev->hbm_state = MEI_HBM_STARTED;
615                 mei_host_client_init(dev);
616                 return 0;
617         }
618
619         mei_hbm_hdr(&mei_hdr, sizeof(req));
620
621         memset(&req, 0, sizeof(req));
622
623         req.hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD;
624         req.me_addr = addr;
625
626         ret = mei_hbm_write_message(dev, &mei_hdr, &req);
627         if (ret) {
628                 dev_err(dev->dev, "properties request write failed: ret = %d\n",
629                         ret);
630                 return ret;
631         }
632
633         dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
634         mei_schedule_stall_timer(dev);
635
636         return 0;
637 }
638
639 /**
640  * mei_hbm_pg - sends pg command
641  *
642  * @dev: the device structure
643  * @pg_cmd: the pg command code
644  *
645  * Return: -EIO on write failure
646  *         -EOPNOTSUPP if the operation is not supported by the protocol
647  */
648 int mei_hbm_pg(struct mei_device *dev, u8 pg_cmd)
649 {
650         struct mei_msg_hdr mei_hdr;
651         struct hbm_power_gate req;
652         int ret;
653
654         if (!dev->hbm_f_pg_supported)
655                 return -EOPNOTSUPP;
656
657         mei_hbm_hdr(&mei_hdr, sizeof(req));
658
659         memset(&req, 0, sizeof(req));
660         req.hbm_cmd = pg_cmd;
661
662         ret = mei_hbm_write_message(dev, &mei_hdr, &req);
663         if (ret)
664                 dev_err(dev->dev, "power gate command write failed.\n");
665         return ret;
666 }
667 EXPORT_SYMBOL_GPL(mei_hbm_pg);
668
669 /**
670  * mei_hbm_stop_req - send stop request message
671  *
672  * @dev: mei device
673  *
674  * Return: -EIO on write failure
675  */
676 static int mei_hbm_stop_req(struct mei_device *dev)
677 {
678         struct mei_msg_hdr mei_hdr;
679         struct hbm_host_stop_request req;
680
681         mei_hbm_hdr(&mei_hdr, sizeof(req));
682
683         memset(&req, 0, sizeof(req));
684         req.hbm_cmd = HOST_STOP_REQ_CMD;
685         req.reason = DRIVER_STOP_REQUEST;
686
687         return mei_hbm_write_message(dev, &mei_hdr, &req);
688 }
689
690 /**
691  * mei_hbm_cl_flow_control_req - sends flow control request.
692  *
693  * @dev: the device structure
694  * @cl: client info
695  *
696  * Return: -EIO on write failure
697  */
698 int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl)
699 {
700         struct hbm_flow_control req;
701
702         cl_dbg(dev, cl, "sending flow control\n");
703         return mei_hbm_cl_write(dev, cl, MEI_FLOW_CONTROL_CMD,
704                                 &req, sizeof(req));
705 }
706
707 /**
708  * mei_hbm_add_single_tx_flow_ctrl_creds - adds single buffer credentials.
709  *
710  * @dev: the device structure
711  * @fctrl: flow control response bus message
712  *
713  * Return: 0 on success, < 0 otherwise
714  */
715 static int mei_hbm_add_single_tx_flow_ctrl_creds(struct mei_device *dev,
716                                                  struct hbm_flow_control *fctrl)
717 {
718         struct mei_me_client *me_cl;
719         int rets;
720
721         me_cl = mei_me_cl_by_id(dev, fctrl->me_addr);
722         if (!me_cl) {
723                 dev_err(dev->dev, "no such me client %d\n", fctrl->me_addr);
724                 return -ENOENT;
725         }
726
727         if (WARN_ON(me_cl->props.single_recv_buf == 0)) {
728                 rets = -EINVAL;
729                 goto out;
730         }
731
732         me_cl->tx_flow_ctrl_creds++;
733         dev_dbg(dev->dev, "recv flow ctrl msg ME %d (single) creds = %d.\n",
734                 fctrl->me_addr, me_cl->tx_flow_ctrl_creds);
735
736         rets = 0;
737 out:
738         mei_me_cl_put(me_cl);
739         return rets;
740 }
741
742 /**
743  * mei_hbm_cl_flow_control_res - flow control response from me
744  *
745  * @dev: the device structure
746  * @fctrl: flow control response bus message
747  */
748 static void mei_hbm_cl_tx_flow_ctrl_creds_res(struct mei_device *dev,
749                                                struct hbm_flow_control *fctrl)
750 {
751         struct mei_cl *cl;
752
753         if (!fctrl->host_addr) {
754                 /* single receive buffer */
755                 mei_hbm_add_single_tx_flow_ctrl_creds(dev, fctrl);
756                 return;
757         }
758
759         cl = mei_hbm_cl_find_by_cmd(dev, fctrl);
760         if (cl) {
761                 cl->tx_flow_ctrl_creds++;
762                 cl_dbg(dev, cl, "flow control creds = %d.\n",
763                                 cl->tx_flow_ctrl_creds);
764         }
765 }
766
767
768 /**
769  * mei_hbm_cl_disconnect_req - sends disconnect message to fw.
770  *
771  * @dev: the device structure
772  * @cl: a client to disconnect from
773  *
774  * Return: -EIO on write failure
775  */
776 int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl)
777 {
778         struct hbm_client_connect_request req;
779
780         return mei_hbm_cl_write(dev, cl, CLIENT_DISCONNECT_REQ_CMD,
781                                 &req, sizeof(req));
782 }
783
784 /**
785  * mei_hbm_cl_disconnect_rsp - sends disconnect respose to the FW
786  *
787  * @dev: the device structure
788  * @cl: a client to disconnect from
789  *
790  * Return: -EIO on write failure
791  */
792 int mei_hbm_cl_disconnect_rsp(struct mei_device *dev, struct mei_cl *cl)
793 {
794         struct hbm_client_connect_response resp;
795
796         return mei_hbm_cl_write(dev, cl, CLIENT_DISCONNECT_RES_CMD,
797                                 &resp, sizeof(resp));
798 }
799
800 /**
801  * mei_hbm_cl_disconnect_res - update the client state according
802  *       disconnect response
803  *
804  * @dev: the device structure
805  * @cl: mei host client
806  * @cmd: disconnect client response host bus message
807  */
808 static void mei_hbm_cl_disconnect_res(struct mei_device *dev, struct mei_cl *cl,
809                                       struct mei_hbm_cl_cmd *cmd)
810 {
811         struct hbm_client_connect_response *rs =
812                 (struct hbm_client_connect_response *)cmd;
813
814         cl_dbg(dev, cl, "hbm: disconnect response status=%d\n", rs->status);
815
816         if (rs->status == MEI_CL_DISCONN_SUCCESS)
817                 cl->state = MEI_FILE_DISCONNECT_REPLY;
818         cl->status = 0;
819 }
820
821 /**
822  * mei_hbm_cl_connect_req - send connection request to specific me client
823  *
824  * @dev: the device structure
825  * @cl: a client to connect to
826  *
827  * Return: -EIO on write failure
828  */
829 int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl)
830 {
831         struct hbm_client_connect_request req;
832
833         return mei_hbm_cl_write(dev, cl, CLIENT_CONNECT_REQ_CMD,
834                                 &req, sizeof(req));
835 }
836
837 /**
838  * mei_hbm_cl_connect_res - update the client state according
839  *        connection response
840  *
841  * @dev: the device structure
842  * @cl: mei host client
843  * @cmd: connect client response host bus message
844  */
845 static void mei_hbm_cl_connect_res(struct mei_device *dev, struct mei_cl *cl,
846                                    struct mei_hbm_cl_cmd *cmd)
847 {
848         struct hbm_client_connect_response *rs =
849                 (struct hbm_client_connect_response *)cmd;
850
851         cl_dbg(dev, cl, "hbm: connect response status=%s\n",
852                         mei_cl_conn_status_str(rs->status));
853
854         if (rs->status == MEI_CL_CONN_SUCCESS)
855                 cl->state = MEI_FILE_CONNECTED;
856         else {
857                 cl->state = MEI_FILE_DISCONNECT_REPLY;
858                 if (rs->status == MEI_CL_CONN_NOT_FOUND) {
859                         mei_me_cl_del(dev, cl->me_cl);
860                         if (dev->dev_state == MEI_DEV_ENABLED)
861                                 schedule_work(&dev->bus_rescan_work);
862                 }
863         }
864         cl->status = mei_cl_conn_status_to_errno(rs->status);
865 }
866
867 /**
868  * mei_hbm_cl_res - process hbm response received on behalf
869  *         an client
870  *
871  * @dev: the device structure
872  * @rs:  hbm client message
873  * @fop_type: file operation type
874  */
875 static void mei_hbm_cl_res(struct mei_device *dev,
876                            struct mei_hbm_cl_cmd *rs,
877                            enum mei_cb_file_ops fop_type)
878 {
879         struct mei_cl *cl;
880         struct mei_cl_cb *cb, *next;
881
882         cl = NULL;
883         list_for_each_entry_safe(cb, next, &dev->ctrl_rd_list, list) {
884
885                 cl = cb->cl;
886
887                 if (cb->fop_type != fop_type)
888                         continue;
889
890                 if (mei_hbm_cl_addr_equal(cl, rs)) {
891                         list_del_init(&cb->list);
892                         break;
893                 }
894         }
895
896         if (!cl)
897                 return;
898
899         switch (fop_type) {
900         case MEI_FOP_CONNECT:
901                 mei_hbm_cl_connect_res(dev, cl, rs);
902                 break;
903         case MEI_FOP_DISCONNECT:
904                 mei_hbm_cl_disconnect_res(dev, cl, rs);
905                 break;
906         case MEI_FOP_NOTIFY_START:
907                 mei_hbm_cl_notify_start_res(dev, cl, rs);
908                 break;
909         case MEI_FOP_NOTIFY_STOP:
910                 mei_hbm_cl_notify_stop_res(dev, cl, rs);
911                 break;
912         default:
913                 return;
914         }
915
916         cl->timer_count = 0;
917         wake_up(&cl->wait);
918 }
919
920
921 /**
922  * mei_hbm_fw_disconnect_req - disconnect request initiated by ME firmware
923  *  host sends disconnect response
924  *
925  * @dev: the device structure.
926  * @disconnect_req: disconnect request bus message from the me
927  *
928  * Return: -ENOMEM on allocation failure
929  */
930 static int mei_hbm_fw_disconnect_req(struct mei_device *dev,
931                 struct hbm_client_connect_request *disconnect_req)
932 {
933         struct mei_cl *cl;
934         struct mei_cl_cb *cb;
935
936         cl = mei_hbm_cl_find_by_cmd(dev, disconnect_req);
937         if (cl) {
938                 cl_warn(dev, cl, "fw disconnect request received\n");
939                 cl->state = MEI_FILE_DISCONNECTING;
940                 cl->timer_count = 0;
941
942                 cb = mei_cl_enqueue_ctrl_wr_cb(cl, 0, MEI_FOP_DISCONNECT_RSP,
943                                                NULL);
944                 if (!cb)
945                         return -ENOMEM;
946         }
947         return 0;
948 }
949
950 /**
951  * mei_hbm_pg_enter_res - PG enter response received
952  *
953  * @dev: the device structure.
954  *
955  * Return: 0 on success, -EPROTO on state mismatch
956  */
957 static int mei_hbm_pg_enter_res(struct mei_device *dev)
958 {
959         if (mei_pg_state(dev) != MEI_PG_OFF ||
960             dev->pg_event != MEI_PG_EVENT_WAIT) {
961                 dev_err(dev->dev, "hbm: pg entry response: state mismatch [%s, %d]\n",
962                         mei_pg_state_str(mei_pg_state(dev)), dev->pg_event);
963                 return -EPROTO;
964         }
965
966         dev->pg_event = MEI_PG_EVENT_RECEIVED;
967         wake_up(&dev->wait_pg);
968
969         return 0;
970 }
971
972 /**
973  * mei_hbm_pg_resume - process with PG resume
974  *
975  * @dev: the device structure.
976  */
977 void mei_hbm_pg_resume(struct mei_device *dev)
978 {
979         pm_request_resume(dev->dev);
980 }
981 EXPORT_SYMBOL_GPL(mei_hbm_pg_resume);
982
983 /**
984  * mei_hbm_pg_exit_res - PG exit response received
985  *
986  * @dev: the device structure.
987  *
988  * Return: 0 on success, -EPROTO on state mismatch
989  */
990 static int mei_hbm_pg_exit_res(struct mei_device *dev)
991 {
992         if (mei_pg_state(dev) != MEI_PG_ON ||
993             (dev->pg_event != MEI_PG_EVENT_WAIT &&
994              dev->pg_event != MEI_PG_EVENT_IDLE)) {
995                 dev_err(dev->dev, "hbm: pg exit response: state mismatch [%s, %d]\n",
996                         mei_pg_state_str(mei_pg_state(dev)), dev->pg_event);
997                 return -EPROTO;
998         }
999
1000         switch (dev->pg_event) {
1001         case MEI_PG_EVENT_WAIT:
1002                 dev->pg_event = MEI_PG_EVENT_RECEIVED;
1003                 wake_up(&dev->wait_pg);
1004                 break;
1005         case MEI_PG_EVENT_IDLE:
1006                 /*
1007                 * If the driver is not waiting on this then
1008                 * this is HW initiated exit from PG.
1009                 * Start runtime pm resume sequence to exit from PG.
1010                 */
1011                 dev->pg_event = MEI_PG_EVENT_RECEIVED;
1012                 mei_hbm_pg_resume(dev);
1013                 break;
1014         default:
1015                 WARN(1, "hbm: pg exit response: unexpected pg event = %d\n",
1016                      dev->pg_event);
1017                 return -EPROTO;
1018         }
1019
1020         return 0;
1021 }
1022
1023 /**
1024  * mei_hbm_config_features - check what hbm features and commands
1025  *        are supported by the fw
1026  *
1027  * @dev: the device structure
1028  */
1029 static void mei_hbm_config_features(struct mei_device *dev)
1030 {
1031         /* Power Gating Isolation Support */
1032         dev->hbm_f_pg_supported = 0;
1033         if (dev->version.major_version > HBM_MAJOR_VERSION_PGI)
1034                 dev->hbm_f_pg_supported = 1;
1035
1036         if (dev->version.major_version == HBM_MAJOR_VERSION_PGI &&
1037             dev->version.minor_version >= HBM_MINOR_VERSION_PGI)
1038                 dev->hbm_f_pg_supported = 1;
1039
1040         dev->hbm_f_dc_supported = 0;
1041         if (dev->version.major_version >= HBM_MAJOR_VERSION_DC)
1042                 dev->hbm_f_dc_supported = 1;
1043
1044         dev->hbm_f_ie_supported = 0;
1045         if (dev->version.major_version >= HBM_MAJOR_VERSION_IE)
1046                 dev->hbm_f_ie_supported = 1;
1047
1048         /* disconnect on connect timeout instead of link reset */
1049         dev->hbm_f_dot_supported = 0;
1050         if (dev->version.major_version >= HBM_MAJOR_VERSION_DOT)
1051                 dev->hbm_f_dot_supported = 1;
1052
1053         /* Notification Event Support */
1054         dev->hbm_f_ev_supported = 0;
1055         if (dev->version.major_version >= HBM_MAJOR_VERSION_EV)
1056                 dev->hbm_f_ev_supported = 1;
1057
1058         /* Fixed Address Client Support */
1059         dev->hbm_f_fa_supported = 0;
1060         if (dev->version.major_version >= HBM_MAJOR_VERSION_FA)
1061                 dev->hbm_f_fa_supported = 1;
1062
1063         /* OS ver message Support */
1064         dev->hbm_f_os_supported = 0;
1065         if (dev->version.major_version >= HBM_MAJOR_VERSION_OS)
1066                 dev->hbm_f_os_supported = 1;
1067
1068         /* DMA Ring Support */
1069         dev->hbm_f_dr_supported = 0;
1070         if (dev->version.major_version > HBM_MAJOR_VERSION_DR ||
1071             (dev->version.major_version == HBM_MAJOR_VERSION_DR &&
1072              dev->version.minor_version >= HBM_MINOR_VERSION_DR))
1073                 dev->hbm_f_dr_supported = 1;
1074
1075         /* VTag Support */
1076         dev->hbm_f_vt_supported = 0;
1077         if (dev->version.major_version > HBM_MAJOR_VERSION_VT ||
1078             (dev->version.major_version == HBM_MAJOR_VERSION_VT &&
1079              dev->version.minor_version >= HBM_MINOR_VERSION_VT))
1080                 dev->hbm_f_vt_supported = 1;
1081
1082         /* Capability message Support */
1083         dev->hbm_f_cap_supported = 0;
1084         if (dev->version.major_version > HBM_MAJOR_VERSION_CAP ||
1085             (dev->version.major_version == HBM_MAJOR_VERSION_CAP &&
1086              dev->version.minor_version >= HBM_MINOR_VERSION_CAP))
1087                 dev->hbm_f_cap_supported = 1;
1088 }
1089
1090 /**
1091  * mei_hbm_version_is_supported - checks whether the driver can
1092  *     support the hbm version of the device
1093  *
1094  * @dev: the device structure
1095  * Return: true if driver can support hbm version of the device
1096  */
1097 bool mei_hbm_version_is_supported(struct mei_device *dev)
1098 {
1099         return  (dev->version.major_version < HBM_MAJOR_VERSION) ||
1100                 (dev->version.major_version == HBM_MAJOR_VERSION &&
1101                  dev->version.minor_version <= HBM_MINOR_VERSION);
1102 }
1103
1104 /**
1105  * mei_hbm_dispatch - bottom half read routine after ISR to
1106  * handle the read bus message cmd processing.
1107  *
1108  * @dev: the device structure
1109  * @hdr: header of bus message
1110  *
1111  * Return: 0 on success and < 0 on failure
1112  */
1113 int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
1114 {
1115         struct mei_bus_message *mei_msg;
1116         struct hbm_host_version_response *version_res;
1117         struct hbm_props_response *props_res;
1118         struct hbm_host_enum_response *enum_res;
1119         struct hbm_dma_setup_response *dma_setup_res;
1120         struct hbm_add_client_request *add_cl_req;
1121         struct hbm_capability_response *capability_res;
1122         int ret;
1123
1124         struct mei_hbm_cl_cmd *cl_cmd;
1125         struct hbm_client_connect_request *disconnect_req;
1126         struct hbm_flow_control *fctrl;
1127
1128         /* read the message to our buffer */
1129         BUG_ON(hdr->length >= sizeof(dev->rd_msg_buf));
1130         mei_read_slots(dev, dev->rd_msg_buf, hdr->length);
1131         mei_msg = (struct mei_bus_message *)dev->rd_msg_buf;
1132         cl_cmd  = (struct mei_hbm_cl_cmd *)mei_msg;
1133
1134         /* ignore spurious message and prevent reset nesting
1135          * hbm is put to idle during system reset
1136          */
1137         if (dev->hbm_state == MEI_HBM_IDLE) {
1138                 dev_dbg(dev->dev, "hbm: state is idle ignore spurious messages\n");
1139                 return 0;
1140         }
1141
1142         switch (mei_msg->hbm_cmd) {
1143         case HOST_START_RES_CMD:
1144                 dev_dbg(dev->dev, "hbm: start: response message received.\n");
1145
1146                 dev->init_clients_timer = 0;
1147
1148                 version_res = (struct hbm_host_version_response *)mei_msg;
1149
1150                 dev_dbg(dev->dev, "HBM VERSION: DRIVER=%02d:%02d DEVICE=%02d:%02d\n",
1151                                 HBM_MAJOR_VERSION, HBM_MINOR_VERSION,
1152                                 version_res->me_max_version.major_version,
1153                                 version_res->me_max_version.minor_version);
1154
1155                 if (version_res->host_version_supported) {
1156                         dev->version.major_version = HBM_MAJOR_VERSION;
1157                         dev->version.minor_version = HBM_MINOR_VERSION;
1158                 } else {
1159                         dev->version.major_version =
1160                                 version_res->me_max_version.major_version;
1161                         dev->version.minor_version =
1162                                 version_res->me_max_version.minor_version;
1163                 }
1164
1165                 if (!mei_hbm_version_is_supported(dev)) {
1166                         dev_warn(dev->dev, "hbm: start: version mismatch - stopping the driver.\n");
1167
1168                         dev->hbm_state = MEI_HBM_STOPPED;
1169                         if (mei_hbm_stop_req(dev)) {
1170                                 dev_err(dev->dev, "hbm: start: failed to send stop request\n");
1171                                 return -EIO;
1172                         }
1173                         break;
1174                 }
1175
1176                 mei_hbm_config_features(dev);
1177
1178                 if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
1179                     dev->hbm_state != MEI_HBM_STARTING) {
1180                         if (dev->dev_state == MEI_DEV_POWER_DOWN) {
1181                                 dev_dbg(dev->dev, "hbm: start: on shutdown, ignoring\n");
1182                                 return 0;
1183                         }
1184                         dev_err(dev->dev, "hbm: start: state mismatch, [%d, %d]\n",
1185                                 dev->dev_state, dev->hbm_state);
1186                         return -EPROTO;
1187                 }
1188
1189                 if (dev->hbm_f_cap_supported) {
1190                         if (mei_hbm_capabilities_req(dev))
1191                                 return -EIO;
1192                         wake_up(&dev->wait_hbm_start);
1193                         break;
1194                 }
1195
1196                 if (dev->hbm_f_dr_supported) {
1197                         if (mei_dmam_ring_alloc(dev))
1198                                 dev_info(dev->dev, "running w/o dma ring\n");
1199                         if (mei_dma_ring_is_allocated(dev)) {
1200                                 if (mei_hbm_dma_setup_req(dev))
1201                                         return -EIO;
1202
1203                                 wake_up(&dev->wait_hbm_start);
1204                                 break;
1205                         }
1206                 }
1207
1208                 dev->hbm_f_dr_supported = 0;
1209                 mei_dmam_ring_free(dev);
1210
1211                 if (mei_hbm_enum_clients_req(dev))
1212                         return -EIO;
1213
1214                 wake_up(&dev->wait_hbm_start);
1215                 break;
1216
1217         case MEI_HBM_CAPABILITIES_RES_CMD:
1218                 dev_dbg(dev->dev, "hbm: capabilities response: message received.\n");
1219
1220                 dev->init_clients_timer = 0;
1221
1222                 if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
1223                     dev->hbm_state != MEI_HBM_CAP_SETUP) {
1224                         if (dev->dev_state == MEI_DEV_POWER_DOWN) {
1225                                 dev_dbg(dev->dev, "hbm: capabilities response: on shutdown, ignoring\n");
1226                                 return 0;
1227                         }
1228                         dev_err(dev->dev, "hbm: capabilities response: state mismatch, [%d, %d]\n",
1229                                 dev->dev_state, dev->hbm_state);
1230                         return -EPROTO;
1231                 }
1232
1233                 capability_res = (struct hbm_capability_response *)mei_msg;
1234                 if (!(capability_res->capability_granted[0] & HBM_CAP_VT))
1235                         dev->hbm_f_vt_supported = 0;
1236
1237                 if (dev->hbm_f_dr_supported) {
1238                         if (mei_dmam_ring_alloc(dev))
1239                                 dev_info(dev->dev, "running w/o dma ring\n");
1240                         if (mei_dma_ring_is_allocated(dev)) {
1241                                 if (mei_hbm_dma_setup_req(dev))
1242                                         return -EIO;
1243                                 break;
1244                         }
1245                 }
1246
1247                 dev->hbm_f_dr_supported = 0;
1248                 mei_dmam_ring_free(dev);
1249
1250                 if (mei_hbm_enum_clients_req(dev))
1251                         return -EIO;
1252                 break;
1253
1254         case MEI_HBM_DMA_SETUP_RES_CMD:
1255                 dev_dbg(dev->dev, "hbm: dma setup response: message received.\n");
1256
1257                 dev->init_clients_timer = 0;
1258
1259                 if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
1260                     dev->hbm_state != MEI_HBM_DR_SETUP) {
1261                         if (dev->dev_state == MEI_DEV_POWER_DOWN) {
1262                                 dev_dbg(dev->dev, "hbm: dma setup response: on shutdown, ignoring\n");
1263                                 return 0;
1264                         }
1265                         dev_err(dev->dev, "hbm: dma setup response: state mismatch, [%d, %d]\n",
1266                                 dev->dev_state, dev->hbm_state);
1267                         return -EPROTO;
1268                 }
1269
1270                 dma_setup_res = (struct hbm_dma_setup_response *)mei_msg;
1271
1272                 if (dma_setup_res->status) {
1273                         u8 status = dma_setup_res->status;
1274
1275                         if (status == MEI_HBMS_NOT_ALLOWED) {
1276                                 dev_dbg(dev->dev, "hbm: dma setup not allowed\n");
1277                         } else {
1278                                 dev_info(dev->dev, "hbm: dma setup response: failure = %d %s\n",
1279                                          status,
1280                                          mei_hbm_status_str(status));
1281                         }
1282                         dev->hbm_f_dr_supported = 0;
1283                         mei_dmam_ring_free(dev);
1284                 }
1285
1286                 if (mei_hbm_enum_clients_req(dev))
1287                         return -EIO;
1288                 break;
1289
1290         case CLIENT_CONNECT_RES_CMD:
1291                 dev_dbg(dev->dev, "hbm: client connect response: message received.\n");
1292                 mei_hbm_cl_res(dev, cl_cmd, MEI_FOP_CONNECT);
1293                 break;
1294
1295         case CLIENT_DISCONNECT_RES_CMD:
1296                 dev_dbg(dev->dev, "hbm: client disconnect response: message received.\n");
1297                 mei_hbm_cl_res(dev, cl_cmd, MEI_FOP_DISCONNECT);
1298                 break;
1299
1300         case MEI_FLOW_CONTROL_CMD:
1301                 dev_dbg(dev->dev, "hbm: client flow control response: message received.\n");
1302
1303                 fctrl = (struct hbm_flow_control *)mei_msg;
1304                 mei_hbm_cl_tx_flow_ctrl_creds_res(dev, fctrl);
1305                 break;
1306
1307         case MEI_PG_ISOLATION_ENTRY_RES_CMD:
1308                 dev_dbg(dev->dev, "hbm: power gate isolation entry response received\n");
1309                 ret = mei_hbm_pg_enter_res(dev);
1310                 if (ret)
1311                         return ret;
1312                 break;
1313
1314         case MEI_PG_ISOLATION_EXIT_REQ_CMD:
1315                 dev_dbg(dev->dev, "hbm: power gate isolation exit request received\n");
1316                 ret = mei_hbm_pg_exit_res(dev);
1317                 if (ret)
1318                         return ret;
1319                 break;
1320
1321         case HOST_CLIENT_PROPERTIES_RES_CMD:
1322                 dev_dbg(dev->dev, "hbm: properties response: message received.\n");
1323
1324                 dev->init_clients_timer = 0;
1325
1326                 if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
1327                     dev->hbm_state != MEI_HBM_CLIENT_PROPERTIES) {
1328                         if (dev->dev_state == MEI_DEV_POWER_DOWN) {
1329                                 dev_dbg(dev->dev, "hbm: properties response: on shutdown, ignoring\n");
1330                                 return 0;
1331                         }
1332                         dev_err(dev->dev, "hbm: properties response: state mismatch, [%d, %d]\n",
1333                                 dev->dev_state, dev->hbm_state);
1334                         return -EPROTO;
1335                 }
1336
1337                 props_res = (struct hbm_props_response *)mei_msg;
1338
1339                 if (props_res->status == MEI_HBMS_CLIENT_NOT_FOUND) {
1340                         dev_dbg(dev->dev, "hbm: properties response: %d CLIENT_NOT_FOUND\n",
1341                                 props_res->me_addr);
1342                 } else if (props_res->status) {
1343                         dev_err(dev->dev, "hbm: properties response: wrong status = %d %s\n",
1344                                 props_res->status,
1345                                 mei_hbm_status_str(props_res->status));
1346                         return -EPROTO;
1347                 } else {
1348                         mei_hbm_me_cl_add(dev, props_res);
1349                 }
1350
1351                 /* request property for the next client */
1352                 if (mei_hbm_prop_req(dev, props_res->me_addr + 1))
1353                         return -EIO;
1354
1355                 break;
1356
1357         case HOST_ENUM_RES_CMD:
1358                 dev_dbg(dev->dev, "hbm: enumeration response: message received\n");
1359
1360                 dev->init_clients_timer = 0;
1361
1362                 enum_res = (struct hbm_host_enum_response *) mei_msg;
1363                 BUILD_BUG_ON(sizeof(dev->me_clients_map)
1364                                 < sizeof(enum_res->valid_addresses));
1365                 memcpy(dev->me_clients_map, enum_res->valid_addresses,
1366                                 sizeof(enum_res->valid_addresses));
1367
1368                 if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
1369                     dev->hbm_state != MEI_HBM_ENUM_CLIENTS) {
1370                         if (dev->dev_state == MEI_DEV_POWER_DOWN) {
1371                                 dev_dbg(dev->dev, "hbm: enumeration response: on shutdown, ignoring\n");
1372                                 return 0;
1373                         }
1374                         dev_err(dev->dev, "hbm: enumeration response: state mismatch, [%d, %d]\n",
1375                                 dev->dev_state, dev->hbm_state);
1376                         return -EPROTO;
1377                 }
1378
1379                 dev->hbm_state = MEI_HBM_CLIENT_PROPERTIES;
1380
1381                 /* first property request */
1382                 if (mei_hbm_prop_req(dev, 0))
1383                         return -EIO;
1384
1385                 break;
1386
1387         case HOST_STOP_RES_CMD:
1388                 dev_dbg(dev->dev, "hbm: stop response: message received\n");
1389
1390                 dev->init_clients_timer = 0;
1391
1392                 if (dev->hbm_state != MEI_HBM_STOPPED) {
1393                         dev_err(dev->dev, "hbm: stop response: state mismatch, [%d, %d]\n",
1394                                 dev->dev_state, dev->hbm_state);
1395                         return -EPROTO;
1396                 }
1397
1398                 mei_set_devstate(dev, MEI_DEV_POWER_DOWN);
1399                 dev_info(dev->dev, "hbm: stop response: resetting.\n");
1400                 /* force the reset */
1401                 return -EPROTO;
1402
1403         case CLIENT_DISCONNECT_REQ_CMD:
1404                 dev_dbg(dev->dev, "hbm: disconnect request: message received\n");
1405
1406                 disconnect_req = (struct hbm_client_connect_request *)mei_msg;
1407                 mei_hbm_fw_disconnect_req(dev, disconnect_req);
1408                 break;
1409
1410         case ME_STOP_REQ_CMD:
1411                 dev_dbg(dev->dev, "hbm: stop request: message received\n");
1412                 dev->hbm_state = MEI_HBM_STOPPED;
1413                 if (mei_hbm_stop_req(dev)) {
1414                         dev_err(dev->dev, "hbm: stop request: failed to send stop request\n");
1415                         return -EIO;
1416                 }
1417                 break;
1418
1419         case MEI_HBM_ADD_CLIENT_REQ_CMD:
1420                 dev_dbg(dev->dev, "hbm: add client request received\n");
1421                 /*
1422                  * after the host receives the enum_resp
1423                  * message clients may be added or removed
1424                  */
1425                 if (dev->hbm_state <= MEI_HBM_ENUM_CLIENTS ||
1426                     dev->hbm_state >= MEI_HBM_STOPPED) {
1427                         dev_err(dev->dev, "hbm: add client: state mismatch, [%d, %d]\n",
1428                                 dev->dev_state, dev->hbm_state);
1429                         return -EPROTO;
1430                 }
1431                 add_cl_req = (struct hbm_add_client_request *)mei_msg;
1432                 ret = mei_hbm_fw_add_cl_req(dev, add_cl_req);
1433                 if (ret) {
1434                         dev_err(dev->dev, "hbm: add client: failed to send response %d\n",
1435                                 ret);
1436                         return -EIO;
1437                 }
1438                 dev_dbg(dev->dev, "hbm: add client request processed\n");
1439                 break;
1440
1441         case MEI_HBM_NOTIFY_RES_CMD:
1442                 dev_dbg(dev->dev, "hbm: notify response received\n");
1443                 mei_hbm_cl_res(dev, cl_cmd, notify_res_to_fop(cl_cmd));
1444                 break;
1445
1446         case MEI_HBM_NOTIFICATION_CMD:
1447                 dev_dbg(dev->dev, "hbm: notification\n");
1448                 mei_hbm_cl_notify(dev, cl_cmd);
1449                 break;
1450
1451         default:
1452                 WARN(1, "hbm: wrong command %d\n", mei_msg->hbm_cmd);
1453                 return -EPROTO;
1454
1455         }
1456         return 0;
1457 }
1458