Merge tag 'for-linus-5.12-1' of git://github.com/cminyard/linux-ipmi
[linux-2.6-microblaze.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                         dev_err(dev->dev, "hbm: start: state mismatch, [%d, %d]\n",
1181                                 dev->dev_state, dev->hbm_state);
1182                         return -EPROTO;
1183                 }
1184
1185                 if (dev->hbm_f_cap_supported) {
1186                         if (mei_hbm_capabilities_req(dev))
1187                                 return -EIO;
1188                         wake_up(&dev->wait_hbm_start);
1189                         break;
1190                 }
1191
1192                 if (dev->hbm_f_dr_supported) {
1193                         if (mei_dmam_ring_alloc(dev))
1194                                 dev_info(dev->dev, "running w/o dma ring\n");
1195                         if (mei_dma_ring_is_allocated(dev)) {
1196                                 if (mei_hbm_dma_setup_req(dev))
1197                                         return -EIO;
1198
1199                                 wake_up(&dev->wait_hbm_start);
1200                                 break;
1201                         }
1202                 }
1203
1204                 dev->hbm_f_dr_supported = 0;
1205                 mei_dmam_ring_free(dev);
1206
1207                 if (mei_hbm_enum_clients_req(dev))
1208                         return -EIO;
1209
1210                 wake_up(&dev->wait_hbm_start);
1211                 break;
1212
1213         case MEI_HBM_CAPABILITIES_RES_CMD:
1214                 dev_dbg(dev->dev, "hbm: capabilities response: message received.\n");
1215
1216                 dev->init_clients_timer = 0;
1217
1218                 if (dev->hbm_state != MEI_HBM_CAP_SETUP) {
1219                         dev_err(dev->dev, "hbm: capabilities response: state mismatch, [%d, %d]\n",
1220                                 dev->dev_state, dev->hbm_state);
1221                         return -EPROTO;
1222                 }
1223
1224                 capability_res = (struct hbm_capability_response *)mei_msg;
1225                 if (!(capability_res->capability_granted[0] & HBM_CAP_VT))
1226                         dev->hbm_f_vt_supported = 0;
1227
1228                 if (dev->hbm_f_dr_supported) {
1229                         if (mei_dmam_ring_alloc(dev))
1230                                 dev_info(dev->dev, "running w/o dma ring\n");
1231                         if (mei_dma_ring_is_allocated(dev)) {
1232                                 if (mei_hbm_dma_setup_req(dev))
1233                                         return -EIO;
1234                                 break;
1235                         }
1236                 }
1237
1238                 dev->hbm_f_dr_supported = 0;
1239                 mei_dmam_ring_free(dev);
1240
1241                 if (mei_hbm_enum_clients_req(dev))
1242                         return -EIO;
1243                 break;
1244
1245         case MEI_HBM_DMA_SETUP_RES_CMD:
1246                 dev_dbg(dev->dev, "hbm: dma setup response: message received.\n");
1247
1248                 dev->init_clients_timer = 0;
1249
1250                 if (dev->hbm_state != MEI_HBM_DR_SETUP) {
1251                         dev_err(dev->dev, "hbm: dma setup response: state mismatch, [%d, %d]\n",
1252                                 dev->dev_state, dev->hbm_state);
1253                         return -EPROTO;
1254                 }
1255
1256                 dma_setup_res = (struct hbm_dma_setup_response *)mei_msg;
1257
1258                 if (dma_setup_res->status) {
1259                         u8 status = dma_setup_res->status;
1260
1261                         if (status == MEI_HBMS_NOT_ALLOWED) {
1262                                 dev_dbg(dev->dev, "hbm: dma setup not allowed\n");
1263                         } else {
1264                                 dev_info(dev->dev, "hbm: dma setup response: failure = %d %s\n",
1265                                          status,
1266                                          mei_hbm_status_str(status));
1267                         }
1268                         dev->hbm_f_dr_supported = 0;
1269                         mei_dmam_ring_free(dev);
1270                 }
1271
1272                 if (mei_hbm_enum_clients_req(dev))
1273                         return -EIO;
1274                 break;
1275
1276         case CLIENT_CONNECT_RES_CMD:
1277                 dev_dbg(dev->dev, "hbm: client connect response: message received.\n");
1278                 mei_hbm_cl_res(dev, cl_cmd, MEI_FOP_CONNECT);
1279                 break;
1280
1281         case CLIENT_DISCONNECT_RES_CMD:
1282                 dev_dbg(dev->dev, "hbm: client disconnect response: message received.\n");
1283                 mei_hbm_cl_res(dev, cl_cmd, MEI_FOP_DISCONNECT);
1284                 break;
1285
1286         case MEI_FLOW_CONTROL_CMD:
1287                 dev_dbg(dev->dev, "hbm: client flow control response: message received.\n");
1288
1289                 fctrl = (struct hbm_flow_control *)mei_msg;
1290                 mei_hbm_cl_tx_flow_ctrl_creds_res(dev, fctrl);
1291                 break;
1292
1293         case MEI_PG_ISOLATION_ENTRY_RES_CMD:
1294                 dev_dbg(dev->dev, "hbm: power gate isolation entry response received\n");
1295                 ret = mei_hbm_pg_enter_res(dev);
1296                 if (ret)
1297                         return ret;
1298                 break;
1299
1300         case MEI_PG_ISOLATION_EXIT_REQ_CMD:
1301                 dev_dbg(dev->dev, "hbm: power gate isolation exit request received\n");
1302                 ret = mei_hbm_pg_exit_res(dev);
1303                 if (ret)
1304                         return ret;
1305                 break;
1306
1307         case HOST_CLIENT_PROPERTIES_RES_CMD:
1308                 dev_dbg(dev->dev, "hbm: properties response: message received.\n");
1309
1310                 dev->init_clients_timer = 0;
1311
1312                 if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
1313                     dev->hbm_state != MEI_HBM_CLIENT_PROPERTIES) {
1314                         dev_err(dev->dev, "hbm: properties response: state mismatch, [%d, %d]\n",
1315                                 dev->dev_state, dev->hbm_state);
1316                         return -EPROTO;
1317                 }
1318
1319                 props_res = (struct hbm_props_response *)mei_msg;
1320
1321                 if (props_res->status == MEI_HBMS_CLIENT_NOT_FOUND) {
1322                         dev_dbg(dev->dev, "hbm: properties response: %d CLIENT_NOT_FOUND\n",
1323                                 props_res->me_addr);
1324                 } else if (props_res->status) {
1325                         dev_err(dev->dev, "hbm: properties response: wrong status = %d %s\n",
1326                                 props_res->status,
1327                                 mei_hbm_status_str(props_res->status));
1328                         return -EPROTO;
1329                 } else {
1330                         mei_hbm_me_cl_add(dev, props_res);
1331                 }
1332
1333                 /* request property for the next client */
1334                 if (mei_hbm_prop_req(dev, props_res->me_addr + 1))
1335                         return -EIO;
1336
1337                 break;
1338
1339         case HOST_ENUM_RES_CMD:
1340                 dev_dbg(dev->dev, "hbm: enumeration response: message received\n");
1341
1342                 dev->init_clients_timer = 0;
1343
1344                 enum_res = (struct hbm_host_enum_response *) mei_msg;
1345                 BUILD_BUG_ON(sizeof(dev->me_clients_map)
1346                                 < sizeof(enum_res->valid_addresses));
1347                 memcpy(dev->me_clients_map, enum_res->valid_addresses,
1348                                 sizeof(enum_res->valid_addresses));
1349
1350                 if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
1351                     dev->hbm_state != MEI_HBM_ENUM_CLIENTS) {
1352                         dev_err(dev->dev, "hbm: enumeration response: state mismatch, [%d, %d]\n",
1353                                 dev->dev_state, dev->hbm_state);
1354                         return -EPROTO;
1355                 }
1356
1357                 dev->hbm_state = MEI_HBM_CLIENT_PROPERTIES;
1358
1359                 /* first property request */
1360                 if (mei_hbm_prop_req(dev, 0))
1361                         return -EIO;
1362
1363                 break;
1364
1365         case HOST_STOP_RES_CMD:
1366                 dev_dbg(dev->dev, "hbm: stop response: message received\n");
1367
1368                 dev->init_clients_timer = 0;
1369
1370                 if (dev->hbm_state != MEI_HBM_STOPPED) {
1371                         dev_err(dev->dev, "hbm: stop response: state mismatch, [%d, %d]\n",
1372                                 dev->dev_state, dev->hbm_state);
1373                         return -EPROTO;
1374                 }
1375
1376                 dev->dev_state = MEI_DEV_POWER_DOWN;
1377                 dev_info(dev->dev, "hbm: stop response: resetting.\n");
1378                 /* force the reset */
1379                 return -EPROTO;
1380
1381         case CLIENT_DISCONNECT_REQ_CMD:
1382                 dev_dbg(dev->dev, "hbm: disconnect request: message received\n");
1383
1384                 disconnect_req = (struct hbm_client_connect_request *)mei_msg;
1385                 mei_hbm_fw_disconnect_req(dev, disconnect_req);
1386                 break;
1387
1388         case ME_STOP_REQ_CMD:
1389                 dev_dbg(dev->dev, "hbm: stop request: message received\n");
1390                 dev->hbm_state = MEI_HBM_STOPPED;
1391                 if (mei_hbm_stop_req(dev)) {
1392                         dev_err(dev->dev, "hbm: stop request: failed to send stop request\n");
1393                         return -EIO;
1394                 }
1395                 break;
1396
1397         case MEI_HBM_ADD_CLIENT_REQ_CMD:
1398                 dev_dbg(dev->dev, "hbm: add client request received\n");
1399                 /*
1400                  * after the host receives the enum_resp
1401                  * message clients may be added or removed
1402                  */
1403                 if (dev->hbm_state <= MEI_HBM_ENUM_CLIENTS ||
1404                     dev->hbm_state >= MEI_HBM_STOPPED) {
1405                         dev_err(dev->dev, "hbm: add client: state mismatch, [%d, %d]\n",
1406                                 dev->dev_state, dev->hbm_state);
1407                         return -EPROTO;
1408                 }
1409                 add_cl_req = (struct hbm_add_client_request *)mei_msg;
1410                 ret = mei_hbm_fw_add_cl_req(dev, add_cl_req);
1411                 if (ret) {
1412                         dev_err(dev->dev, "hbm: add client: failed to send response %d\n",
1413                                 ret);
1414                         return -EIO;
1415                 }
1416                 dev_dbg(dev->dev, "hbm: add client request processed\n");
1417                 break;
1418
1419         case MEI_HBM_NOTIFY_RES_CMD:
1420                 dev_dbg(dev->dev, "hbm: notify response received\n");
1421                 mei_hbm_cl_res(dev, cl_cmd, notify_res_to_fop(cl_cmd));
1422                 break;
1423
1424         case MEI_HBM_NOTIFICATION_CMD:
1425                 dev_dbg(dev->dev, "hbm: notification\n");
1426                 mei_hbm_cl_notify(dev, cl_cmd);
1427                 break;
1428
1429         default:
1430                 WARN(1, "hbm: wrong command %d\n", mei_msg->hbm_cmd);
1431                 return -EPROTO;
1432
1433         }
1434         return 0;
1435 }
1436