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#define MEI_RD_MSG_BUF_SIZE (128 * sizeof(u32))
30
31
32
33
34#define MEI_CLIENTS_MAX 256
35
36
37
38
39#define MEI_MAX_CONSEC_RESET 3
40
41
42
43
44
45
46
47
48#define MEI_MAX_OPEN_HANDLE_COUNT (MEI_CLIENTS_MAX - 1)
49
50
51enum file_state {
52 MEI_FILE_UNINITIALIZED = 0,
53 MEI_FILE_INITIALIZING,
54 MEI_FILE_CONNECTING,
55 MEI_FILE_CONNECTED,
56 MEI_FILE_DISCONNECTING,
57 MEI_FILE_DISCONNECT_REPLY,
58 MEI_FILE_DISCONNECT_REQUIRED,
59 MEI_FILE_DISCONNECTED,
60};
61
62
63enum mei_dev_state {
64 MEI_DEV_INITIALIZING = 0,
65 MEI_DEV_INIT_CLIENTS,
66 MEI_DEV_ENABLED,
67 MEI_DEV_RESETTING,
68 MEI_DEV_DISABLED,
69 MEI_DEV_POWER_DOWN,
70 MEI_DEV_POWER_UP
71};
72
73const char *mei_dev_state_str(int state);
74
75enum mei_file_transaction_states {
76 MEI_IDLE,
77 MEI_WRITING,
78 MEI_WRITE_COMPLETE,
79};
80
81
82
83
84
85
86
87
88
89
90
91enum mei_cb_file_ops {
92 MEI_FOP_READ = 0,
93 MEI_FOP_WRITE,
94 MEI_FOP_CONNECT,
95 MEI_FOP_DISCONNECT,
96 MEI_FOP_DISCONNECT_RSP,
97 MEI_FOP_NOTIFY_START,
98 MEI_FOP_NOTIFY_STOP,
99};
100
101
102
103
104
105
106
107
108
109enum mei_cl_io_mode {
110 MEI_CL_IO_TX_BLOCKING = BIT(0),
111 MEI_CL_IO_TX_INTERNAL = BIT(1),
112
113 MEI_CL_IO_RX_NONBLOCK = BIT(2),
114};
115
116
117
118
119struct mei_msg_data {
120 size_t size;
121 unsigned char *data;
122};
123
124
125#define MEI_FW_STATUS_MAX 6
126
127#define MEI_FW_STATUS_STR_SZ (MEI_FW_STATUS_MAX * (8 + 1))
128
129
130
131
132
133
134
135
136struct mei_fw_status {
137 int count;
138 u32 status[MEI_FW_STATUS_MAX];
139};
140
141
142
143
144
145
146
147
148
149
150
151
152struct mei_me_client {
153 struct list_head list;
154 struct kref refcnt;
155 struct mei_client_properties props;
156 u8 client_id;
157 u8 tx_flow_ctrl_creds;
158 u8 connect_count;
159 u8 bus_added;
160};
161
162
163struct mei_cl;
164
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 blocking:1;
189 u32 completed:1;
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
217
218
219
220struct mei_cl {
221 struct list_head link;
222 struct mei_device *dev;
223 enum file_state state;
224 wait_queue_head_t tx_wait;
225 wait_queue_head_t rx_wait;
226 wait_queue_head_t wait;
227 wait_queue_head_t ev_wait;
228 struct fasync_struct *ev_async;
229 int status;
230 struct mei_me_client *me_cl;
231 const struct file *fp;
232 u8 host_client_id;
233 u8 tx_flow_ctrl_creds;
234 u8 rx_flow_ctrl_creds;
235 u8 timer_count;
236 u8 notify_en;
237 u8 notify_ev;
238 u8 tx_cb_queued;
239 enum mei_file_transaction_states writing_state;
240 struct list_head rd_pending;
241 struct list_head rd_completed;
242
243 struct mei_cl_device *cldev;
244};
245
246#define MEI_TX_QUEUE_LIMIT_DEFAULT 50
247#define MEI_TX_QUEUE_LIMIT_MAX 255
248#define MEI_TX_QUEUE_LIMIT_MIN 30
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281struct mei_hw_ops {
282
283 bool (*host_is_ready)(struct mei_device *dev);
284
285 bool (*hw_is_ready)(struct mei_device *dev);
286 int (*hw_reset)(struct mei_device *dev, bool enable);
287 int (*hw_start)(struct mei_device *dev);
288 void (*hw_config)(struct mei_device *dev);
289
290 int (*fw_status)(struct mei_device *dev, struct mei_fw_status *fw_sts);
291 enum mei_pg_state (*pg_state)(struct mei_device *dev);
292 bool (*pg_in_transition)(struct mei_device *dev);
293 bool (*pg_is_enabled)(struct mei_device *dev);
294
295 void (*intr_clear)(struct mei_device *dev);
296 void (*intr_enable)(struct mei_device *dev);
297 void (*intr_disable)(struct mei_device *dev);
298 void (*synchronize_irq)(struct mei_device *dev);
299
300 int (*hbuf_free_slots)(struct mei_device *dev);
301 bool (*hbuf_is_ready)(struct mei_device *dev);
302 size_t (*hbuf_max_len)(const struct mei_device *dev);
303 int (*write)(struct mei_device *dev,
304 struct mei_msg_hdr *hdr,
305 const unsigned char *buf);
306
307 int (*rdbuf_full_slots)(struct mei_device *dev);
308
309 u32 (*read_hdr)(const struct mei_device *dev);
310 int (*read)(struct mei_device *dev,
311 unsigned char *buf, unsigned long len);
312};
313
314
315void mei_cl_bus_rescan_work(struct work_struct *work);
316void mei_cl_bus_dev_fixup(struct mei_cl_device *dev);
317ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
318 unsigned int mode);
319ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length,
320 unsigned int mode);
321bool mei_cl_bus_rx_event(struct mei_cl *cl);
322bool mei_cl_bus_notify_event(struct mei_cl *cl);
323void mei_cl_bus_remove_devices(struct mei_device *bus);
324int mei_cl_bus_init(void);
325void mei_cl_bus_exit(void);
326
327
328
329
330
331
332
333
334
335
336enum mei_pg_event {
337 MEI_PG_EVENT_IDLE,
338 MEI_PG_EVENT_WAIT,
339 MEI_PG_EVENT_RECEIVED,
340 MEI_PG_EVENT_INTR_WAIT,
341 MEI_PG_EVENT_INTR_RECEIVED,
342};
343
344
345
346
347
348
349
350enum mei_pg_state {
351 MEI_PG_OFF = 0,
352 MEI_PG_ON = 1,
353};
354
355const char *mei_pg_state_str(enum mei_pg_state state);
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 list_head write_list;
430 struct list_head write_waiting_list;
431 struct list_head ctrl_wr_list;
432 struct list_head ctrl_rd_list;
433 u8 tx_queue_limit;
434
435 struct list_head file_list;
436 long open_handle_count;
437
438 struct mutex device_lock;
439 struct delayed_work timer_work;
440
441 bool recvd_hw_ready;
442
443
444
445 wait_queue_head_t wait_hw_ready;
446 wait_queue_head_t wait_pg;
447 wait_queue_head_t wait_hbm_start;
448
449
450
451
452 unsigned long reset_count;
453 enum mei_dev_state dev_state;
454 enum mei_hbm_state hbm_state;
455 u16 init_clients_timer;
456
457
458
459
460 enum mei_pg_event pg_event;
461#ifdef CONFIG_PM
462 struct dev_pm_domain pg_domain;
463#endif
464
465 unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE];
466 u32 rd_msg_hdr;
467
468
469 u8 hbuf_depth;
470 bool hbuf_is_ready;
471
472 struct hbm_version version;
473 unsigned int hbm_f_pg_supported:1;
474 unsigned int hbm_f_dc_supported:1;
475 unsigned int hbm_f_dot_supported:1;
476 unsigned int hbm_f_ev_supported:1;
477 unsigned int hbm_f_fa_supported:1;
478 unsigned int hbm_f_ie_supported:1;
479 unsigned int hbm_f_os_supported:1;
480
481 struct rw_semaphore me_clients_rwsem;
482 struct list_head me_clients;
483 DECLARE_BITMAP(me_clients_map, MEI_CLIENTS_MAX);
484 DECLARE_BITMAP(host_clients_map, MEI_CLIENTS_MAX);
485
486 bool allow_fixed_address;
487 bool override_fixed_address;
488
489 struct work_struct reset_work;
490 struct work_struct bus_rescan_work;
491
492
493 struct list_head device_list;
494 struct mutex cl_bus_lock;
495
496#if IS_ENABLED(CONFIG_DEBUG_FS)
497 struct dentry *dbgfs_dir;
498#endif
499
500
501 const struct mei_hw_ops *ops;
502 char hw[0] __aligned(sizeof(void *));
503};
504
505static inline unsigned long mei_secs_to_jiffies(unsigned long sec)
506{
507 return msecs_to_jiffies(sec * MSEC_PER_SEC);
508}
509
510
511
512
513
514
515
516
517
518static inline u32 mei_data2slots(size_t length)
519{
520 return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, 4);
521}
522
523
524
525
526
527
528
529
530static inline u32 mei_slots2data(int slots)
531{
532 return slots * 4;
533}
534
535
536
537
538void mei_device_init(struct mei_device *dev,
539 struct device *device,
540 const struct mei_hw_ops *hw_ops);
541int mei_reset(struct mei_device *dev);
542int mei_start(struct mei_device *dev);
543int mei_restart(struct mei_device *dev);
544void mei_stop(struct mei_device *dev);
545void mei_cancel_work(struct mei_device *dev);
546
547
548
549
550
551void mei_timer(struct work_struct *work);
552void mei_schedule_stall_timer(struct mei_device *dev);
553int mei_irq_read_handler(struct mei_device *dev,
554 struct list_head *cmpl_list, s32 *slots);
555
556int mei_irq_write_handler(struct mei_device *dev, struct list_head *cmpl_list);
557void mei_irq_compl_handler(struct mei_device *dev, struct list_head *cmpl_list);
558
559
560
561
562
563
564static inline void mei_hw_config(struct mei_device *dev)
565{
566 dev->ops->hw_config(dev);
567}
568
569static inline enum mei_pg_state mei_pg_state(struct mei_device *dev)
570{
571 return dev->ops->pg_state(dev);
572}
573
574static inline bool mei_pg_in_transition(struct mei_device *dev)
575{
576 return dev->ops->pg_in_transition(dev);
577}
578
579static inline bool mei_pg_is_enabled(struct mei_device *dev)
580{
581 return dev->ops->pg_is_enabled(dev);
582}
583
584static inline int mei_hw_reset(struct mei_device *dev, bool enable)
585{
586 return dev->ops->hw_reset(dev, enable);
587}
588
589static inline int mei_hw_start(struct mei_device *dev)
590{
591 return dev->ops->hw_start(dev);
592}
593
594static inline void mei_clear_interrupts(struct mei_device *dev)
595{
596 dev->ops->intr_clear(dev);
597}
598
599static inline void mei_enable_interrupts(struct mei_device *dev)
600{
601 dev->ops->intr_enable(dev);
602}
603
604static inline void mei_disable_interrupts(struct mei_device *dev)
605{
606 dev->ops->intr_disable(dev);
607}
608
609static inline void mei_synchronize_irq(struct mei_device *dev)
610{
611 dev->ops->synchronize_irq(dev);
612}
613
614static inline bool mei_host_is_ready(struct mei_device *dev)
615{
616 return dev->ops->host_is_ready(dev);
617}
618static inline bool mei_hw_is_ready(struct mei_device *dev)
619{
620 return dev->ops->hw_is_ready(dev);
621}
622
623static inline bool mei_hbuf_is_ready(struct mei_device *dev)
624{
625 return dev->ops->hbuf_is_ready(dev);
626}
627
628static inline int mei_hbuf_empty_slots(struct mei_device *dev)
629{
630 return dev->ops->hbuf_free_slots(dev);
631}
632
633static inline size_t mei_hbuf_max_len(const struct mei_device *dev)
634{
635 return dev->ops->hbuf_max_len(dev);
636}
637
638static inline int mei_write_message(struct mei_device *dev,
639 struct mei_msg_hdr *hdr, const void *buf)
640{
641 return dev->ops->write(dev, hdr, buf);
642}
643
644static inline u32 mei_read_hdr(const struct mei_device *dev)
645{
646 return dev->ops->read_hdr(dev);
647}
648
649static inline void mei_read_slots(struct mei_device *dev,
650 unsigned char *buf, unsigned long len)
651{
652 dev->ops->read(dev, buf, len);
653}
654
655static inline int mei_count_full_read_slots(struct mei_device *dev)
656{
657 return dev->ops->rdbuf_full_slots(dev);
658}
659
660static inline int mei_fw_status(struct mei_device *dev,
661 struct mei_fw_status *fw_status)
662{
663 return dev->ops->fw_status(dev, fw_status);
664}
665
666bool mei_hbuf_acquire(struct mei_device *dev);
667
668bool mei_write_is_idle(struct mei_device *dev);
669
670#if IS_ENABLED(CONFIG_DEBUG_FS)
671int mei_dbgfs_register(struct mei_device *dev, const char *name);
672void mei_dbgfs_deregister(struct mei_device *dev);
673#else
674static inline int mei_dbgfs_register(struct mei_device *dev, const char *name)
675{
676 return 0;
677}
678static inline void mei_dbgfs_deregister(struct mei_device *dev) {}
679#endif
680
681int mei_register(struct mei_device *dev, struct device *parent);
682void mei_deregister(struct mei_device *dev);
683
684#define MEI_HDR_FMT "hdr:host=%02d me=%02d len=%d internal=%1d comp=%1d"
685#define MEI_HDR_PRM(hdr) \
686 (hdr)->host_addr, (hdr)->me_addr, \
687 (hdr)->length, (hdr)->internal, (hdr)->msg_complete
688
689ssize_t mei_fw_status2str(struct mei_fw_status *fw_sts, char *buf, size_t len);
690
691
692
693
694
695
696
697
698
699static inline ssize_t mei_fw_status_str(struct mei_device *dev,
700 char *buf, size_t len)
701{
702 struct mei_fw_status fw_status;
703 int ret;
704
705 buf[0] = '\0';
706
707 ret = mei_fw_status(dev, &fw_status);
708 if (ret)
709 return ret;
710
711 ret = mei_fw_status2str(&fw_status, buf, MEI_FW_STATUS_STR_SZ);
712
713 return ret;
714}
715
716
717#endif
718