1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#ifndef _MEI_DEV_H_
18#define _MEI_DEV_H_
19
20#include <linux/types.h>
21#include <linux/cdev.h>
22#include <linux/poll.h>
23#include <linux/mei.h>
24#include <linux/mei_cl_bus.h>
25
26#include "hw.h"
27#include "hbm.h"
28
29
30
31
32
33extern const uuid_le mei_amthif_guid;
34
35#define MEI_RD_MSG_BUF_SIZE (128 * sizeof(u32))
36
37
38
39
40#define MEI_CLIENTS_MAX 256
41
42
43
44
45#define MEI_MAX_CONSEC_RESET 3
46
47
48
49
50
51
52
53
54#define MEI_MAX_OPEN_HANDLE_COUNT (MEI_CLIENTS_MAX - 1)
55
56
57enum file_state {
58 MEI_FILE_INITIALIZING = 0,
59 MEI_FILE_CONNECTING,
60 MEI_FILE_CONNECTED,
61 MEI_FILE_DISCONNECTING,
62 MEI_FILE_DISCONNECT_REPLY,
63 MEI_FILE_DISCONNECT_REQUIRED,
64 MEI_FILE_DISCONNECTED,
65};
66
67
68enum mei_dev_state {
69 MEI_DEV_INITIALIZING = 0,
70 MEI_DEV_INIT_CLIENTS,
71 MEI_DEV_ENABLED,
72 MEI_DEV_RESETTING,
73 MEI_DEV_DISABLED,
74 MEI_DEV_POWER_DOWN,
75 MEI_DEV_POWER_UP
76};
77
78const char *mei_dev_state_str(int state);
79
80enum iamthif_states {
81 MEI_IAMTHIF_IDLE,
82 MEI_IAMTHIF_WRITING,
83 MEI_IAMTHIF_FLOW_CONTROL,
84 MEI_IAMTHIF_READING,
85 MEI_IAMTHIF_READ_COMPLETE
86};
87
88enum mei_file_transaction_states {
89 MEI_IDLE,
90 MEI_WRITING,
91 MEI_WRITE_COMPLETE,
92 MEI_FLOW_CONTROL,
93 MEI_READING,
94 MEI_READ_COMPLETE
95};
96
97
98
99
100
101
102
103
104
105
106
107enum mei_cb_file_ops {
108 MEI_FOP_READ = 0,
109 MEI_FOP_WRITE,
110 MEI_FOP_CONNECT,
111 MEI_FOP_DISCONNECT,
112 MEI_FOP_DISCONNECT_RSP,
113 MEI_FOP_NOTIFY_START,
114 MEI_FOP_NOTIFY_STOP,
115};
116
117
118
119
120struct mei_msg_data {
121 size_t size;
122 unsigned char *data;
123};
124
125
126#define MEI_FW_STATUS_MAX 6
127
128#define MEI_FW_STATUS_STR_SZ (MEI_FW_STATUS_MAX * (8 + 1))
129
130
131
132
133
134
135
136
137struct mei_fw_status {
138 int count;
139 u32 status[MEI_FW_STATUS_MAX];
140};
141
142
143
144
145
146
147
148
149
150
151
152
153struct mei_me_client {
154 struct list_head list;
155 struct kref refcnt;
156 struct mei_client_properties props;
157 u8 client_id;
158 u8 mei_flow_ctrl_creds;
159 u8 connect_count;
160 u8 bus_added;
161};
162
163
164struct mei_cl;
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179struct mei_cl_cb {
180 struct list_head list;
181 struct mei_cl *cl;
182 enum mei_cb_file_ops fop_type;
183 struct mei_msg_data buf;
184 size_t buf_idx;
185 const struct file *fp;
186 int status;
187 u32 internal:1;
188 u32 completed:1;
189};
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217struct mei_cl {
218 struct list_head link;
219 struct mei_device *dev;
220 enum file_state state;
221 wait_queue_head_t tx_wait;
222 wait_queue_head_t rx_wait;
223 wait_queue_head_t wait;
224 wait_queue_head_t ev_wait;
225 struct fasync_struct *ev_async;
226 int status;
227 struct mei_me_client *me_cl;
228 u8 host_client_id;
229 u8 mei_flow_ctrl_creds;
230 u8 timer_count;
231 u8 reserved;
232 u8 notify_en;
233 u8 notify_ev;
234 enum mei_file_transaction_states writing_state;
235 struct list_head rd_pending;
236 struct list_head rd_completed;
237
238 struct mei_cl_device *cldev;
239};
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271struct mei_hw_ops {
272
273 bool (*host_is_ready)(struct mei_device *dev);
274
275 bool (*hw_is_ready)(struct mei_device *dev);
276 int (*hw_reset)(struct mei_device *dev, bool enable);
277 int (*hw_start)(struct mei_device *dev);
278 void (*hw_config)(struct mei_device *dev);
279
280
281 int (*fw_status)(struct mei_device *dev, struct mei_fw_status *fw_sts);
282 enum mei_pg_state (*pg_state)(struct mei_device *dev);
283 bool (*pg_in_transition)(struct mei_device *dev);
284 bool (*pg_is_enabled)(struct mei_device *dev);
285
286 void (*intr_clear)(struct mei_device *dev);
287 void (*intr_enable)(struct mei_device *dev);
288 void (*intr_disable)(struct mei_device *dev);
289
290 int (*hbuf_free_slots)(struct mei_device *dev);
291 bool (*hbuf_is_ready)(struct mei_device *dev);
292 size_t (*hbuf_max_len)(const struct mei_device *dev);
293
294 int (*write)(struct mei_device *dev,
295 struct mei_msg_hdr *hdr,
296 unsigned char *buf);
297
298 int (*rdbuf_full_slots)(struct mei_device *dev);
299
300 u32 (*read_hdr)(const struct mei_device *dev);
301 int (*read)(struct mei_device *dev,
302 unsigned char *buf, unsigned long len);
303};
304
305
306void mei_cl_bus_rescan(struct mei_device *bus);
307void mei_cl_bus_rescan_work(struct work_struct *work);
308void mei_cl_bus_dev_fixup(struct mei_cl_device *dev);
309ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
310 bool blocking);
311ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length);
312bool mei_cl_bus_rx_event(struct mei_cl *cl);
313bool mei_cl_bus_notify_event(struct mei_cl *cl);
314void mei_cl_bus_remove_devices(struct mei_device *bus);
315int mei_cl_bus_init(void);
316void mei_cl_bus_exit(void);
317
318
319
320
321
322
323
324
325
326
327enum mei_pg_event {
328 MEI_PG_EVENT_IDLE,
329 MEI_PG_EVENT_WAIT,
330 MEI_PG_EVENT_RECEIVED,
331 MEI_PG_EVENT_INTR_WAIT,
332 MEI_PG_EVENT_INTR_RECEIVED,
333};
334
335
336
337
338
339
340
341enum mei_pg_state {
342 MEI_PG_OFF = 0,
343 MEI_PG_ON = 1,
344};
345
346const char *mei_pg_state_str(enum mei_pg_state state);
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424struct mei_device {
425 struct device *dev;
426 struct cdev cdev;
427 int minor;
428
429 struct mei_cl_cb write_list;
430 struct mei_cl_cb write_waiting_list;
431 struct mei_cl_cb ctrl_wr_list;
432 struct mei_cl_cb ctrl_rd_list;
433
434 struct list_head file_list;
435 long open_handle_count;
436
437 struct mutex device_lock;
438 struct delayed_work timer_work;
439
440 bool recvd_hw_ready;
441
442
443
444 wait_queue_head_t wait_hw_ready;
445 wait_queue_head_t wait_pg;
446 wait_queue_head_t wait_hbm_start;
447
448
449
450
451 unsigned long reset_count;
452 enum mei_dev_state dev_state;
453 enum mei_hbm_state hbm_state;
454 u16 init_clients_timer;
455
456
457
458
459 enum mei_pg_event pg_event;
460#ifdef CONFIG_PM
461 struct dev_pm_domain pg_domain;
462#endif
463
464 unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE];
465 u32 rd_msg_hdr;
466
467
468 u8 hbuf_depth;
469 bool hbuf_is_ready;
470
471
472 struct {
473 struct mei_msg_hdr hdr;
474 unsigned char data[128];
475 } wr_msg;
476
477 struct hbm_version version;
478 unsigned int hbm_f_pg_supported:1;
479 unsigned int hbm_f_dc_supported:1;
480 unsigned int hbm_f_dot_supported:1;
481 unsigned int hbm_f_ev_supported:1;
482 unsigned int hbm_f_fa_supported:1;
483 unsigned int hbm_f_ie_supported:1;
484
485 struct rw_semaphore me_clients_rwsem;
486 struct list_head me_clients;
487 DECLARE_BITMAP(me_clients_map, MEI_CLIENTS_MAX);
488 DECLARE_BITMAP(host_clients_map, MEI_CLIENTS_MAX);
489 unsigned long me_client_index;
490
491 bool allow_fixed_address;
492 bool override_fixed_address;
493
494
495 struct mei_cl_cb amthif_cmd_list;
496
497 const struct file *iamthif_fp;
498 struct mei_cl iamthif_cl;
499 struct mei_cl_cb *iamthif_current_cb;
500 long iamthif_open_count;
501 u32 iamthif_stall_timer;
502 enum iamthif_states iamthif_state;
503 bool iamthif_canceled;
504
505 struct work_struct reset_work;
506 struct work_struct bus_rescan_work;
507
508
509 struct list_head device_list;
510 struct mutex cl_bus_lock;
511
512#if IS_ENABLED(CONFIG_DEBUG_FS)
513 struct dentry *dbgfs_dir;
514#endif
515
516
517 const struct mei_hw_ops *ops;
518 char hw[0] __aligned(sizeof(void *));
519};
520
521static inline unsigned long mei_secs_to_jiffies(unsigned long sec)
522{
523 return msecs_to_jiffies(sec * MSEC_PER_SEC);
524}
525
526
527
528
529
530
531
532
533
534static inline u32 mei_data2slots(size_t length)
535{
536 return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, 4);
537}
538
539
540
541
542
543
544
545
546static inline u32 mei_slots2data(int slots)
547{
548 return slots * 4;
549}
550
551
552
553
554void mei_device_init(struct mei_device *dev,
555 struct device *device,
556 const struct mei_hw_ops *hw_ops);
557int mei_reset(struct mei_device *dev);
558int mei_start(struct mei_device *dev);
559int mei_restart(struct mei_device *dev);
560void mei_stop(struct mei_device *dev);
561void mei_cancel_work(struct mei_device *dev);
562
563
564
565
566
567void mei_timer(struct work_struct *work);
568int mei_irq_read_handler(struct mei_device *dev,
569 struct mei_cl_cb *cmpl_list, s32 *slots);
570
571int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list);
572void mei_irq_compl_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list);
573
574
575
576
577void mei_amthif_reset_params(struct mei_device *dev);
578
579int mei_amthif_host_init(struct mei_device *dev, struct mei_me_client *me_cl);
580
581int mei_amthif_read(struct mei_device *dev, struct file *file,
582 char __user *ubuf, size_t length, loff_t *offset);
583
584unsigned int mei_amthif_poll(struct mei_device *dev,
585 struct file *file, poll_table *wait);
586
587int mei_amthif_release(struct mei_device *dev, struct file *file);
588
589int mei_amthif_write(struct mei_cl *cl, struct mei_cl_cb *cb);
590int mei_amthif_run_next_cmd(struct mei_device *dev);
591int mei_amthif_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
592 struct mei_cl_cb *cmpl_list);
593
594void mei_amthif_complete(struct mei_cl *cl, struct mei_cl_cb *cb);
595int mei_amthif_irq_read_msg(struct mei_cl *cl,
596 struct mei_msg_hdr *mei_hdr,
597 struct mei_cl_cb *complete_list);
598int mei_amthif_irq_read(struct mei_device *dev, s32 *slots);
599
600
601
602
603
604
605static inline void mei_hw_config(struct mei_device *dev)
606{
607 dev->ops->hw_config(dev);
608}
609
610static inline enum mei_pg_state mei_pg_state(struct mei_device *dev)
611{
612 return dev->ops->pg_state(dev);
613}
614
615static inline bool mei_pg_in_transition(struct mei_device *dev)
616{
617 return dev->ops->pg_in_transition(dev);
618}
619
620static inline bool mei_pg_is_enabled(struct mei_device *dev)
621{
622 return dev->ops->pg_is_enabled(dev);
623}
624
625static inline int mei_hw_reset(struct mei_device *dev, bool enable)
626{
627 return dev->ops->hw_reset(dev, enable);
628}
629
630static inline int mei_hw_start(struct mei_device *dev)
631{
632 return dev->ops->hw_start(dev);
633}
634
635static inline void mei_clear_interrupts(struct mei_device *dev)
636{
637 dev->ops->intr_clear(dev);
638}
639
640static inline void mei_enable_interrupts(struct mei_device *dev)
641{
642 dev->ops->intr_enable(dev);
643}
644
645static inline void mei_disable_interrupts(struct mei_device *dev)
646{
647 dev->ops->intr_disable(dev);
648}
649
650static inline bool mei_host_is_ready(struct mei_device *dev)
651{
652 return dev->ops->host_is_ready(dev);
653}
654static inline bool mei_hw_is_ready(struct mei_device *dev)
655{
656 return dev->ops->hw_is_ready(dev);
657}
658
659static inline bool mei_hbuf_is_ready(struct mei_device *dev)
660{
661 return dev->ops->hbuf_is_ready(dev);
662}
663
664static inline int mei_hbuf_empty_slots(struct mei_device *dev)
665{
666 return dev->ops->hbuf_free_slots(dev);
667}
668
669static inline size_t mei_hbuf_max_len(const struct mei_device *dev)
670{
671 return dev->ops->hbuf_max_len(dev);
672}
673
674static inline int mei_write_message(struct mei_device *dev,
675 struct mei_msg_hdr *hdr,
676 unsigned char *buf)
677{
678 return dev->ops->write(dev, hdr, buf);
679}
680
681static inline u32 mei_read_hdr(const struct mei_device *dev)
682{
683 return dev->ops->read_hdr(dev);
684}
685
686static inline void mei_read_slots(struct mei_device *dev,
687 unsigned char *buf, unsigned long len)
688{
689 dev->ops->read(dev, buf, len);
690}
691
692static inline int mei_count_full_read_slots(struct mei_device *dev)
693{
694 return dev->ops->rdbuf_full_slots(dev);
695}
696
697static inline int mei_fw_status(struct mei_device *dev,
698 struct mei_fw_status *fw_status)
699{
700 return dev->ops->fw_status(dev, fw_status);
701}
702
703bool mei_hbuf_acquire(struct mei_device *dev);
704
705bool mei_write_is_idle(struct mei_device *dev);
706
707#if IS_ENABLED(CONFIG_DEBUG_FS)
708int mei_dbgfs_register(struct mei_device *dev, const char *name);
709void mei_dbgfs_deregister(struct mei_device *dev);
710#else
711static inline int mei_dbgfs_register(struct mei_device *dev, const char *name)
712{
713 return 0;
714}
715static inline void mei_dbgfs_deregister(struct mei_device *dev) {}
716#endif
717
718int mei_register(struct mei_device *dev, struct device *parent);
719void mei_deregister(struct mei_device *dev);
720
721#define MEI_HDR_FMT "hdr:host=%02d me=%02d len=%d internal=%1d comp=%1d"
722#define MEI_HDR_PRM(hdr) \
723 (hdr)->host_addr, (hdr)->me_addr, \
724 (hdr)->length, (hdr)->internal, (hdr)->msg_complete
725
726ssize_t mei_fw_status2str(struct mei_fw_status *fw_sts, char *buf, size_t len);
727
728
729
730
731
732
733
734
735
736static inline ssize_t mei_fw_status_str(struct mei_device *dev,
737 char *buf, size_t len)
738{
739 struct mei_fw_status fw_status;
740 int ret;
741
742 buf[0] = '\0';
743
744 ret = mei_fw_status(dev, &fw_status);
745 if (ret)
746 return ret;
747
748 ret = mei_fw_status2str(&fw_status, buf, MEI_FW_STATUS_STR_SZ);
749
750 return ret;
751}
752
753
754#endif
755