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