162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (c) 2003-2022, Intel Corporation. All rights reserved.
462306a36Sopenharmony_ci * Intel Management Engine Interface (Intel MEI) Linux driver
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#ifndef _MEI_DEV_H_
862306a36Sopenharmony_ci#define _MEI_DEV_H_
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <linux/types.h>
1162306a36Sopenharmony_ci#include <linux/cdev.h>
1262306a36Sopenharmony_ci#include <linux/poll.h>
1362306a36Sopenharmony_ci#include <linux/mei.h>
1462306a36Sopenharmony_ci#include <linux/mei_cl_bus.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_cistatic inline int uuid_le_cmp(const uuid_le u1, const uuid_le u2)
1762306a36Sopenharmony_ci{
1862306a36Sopenharmony_ci	return memcmp(&u1, &u2, sizeof(uuid_le));
1962306a36Sopenharmony_ci}
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci#include "hw.h"
2262306a36Sopenharmony_ci#include "hbm.h"
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci#define MEI_SLOT_SIZE             sizeof(u32)
2562306a36Sopenharmony_ci#define MEI_RD_MSG_BUF_SIZE       (128 * MEI_SLOT_SIZE)
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci/*
2862306a36Sopenharmony_ci * Number of Maximum MEI Clients
2962306a36Sopenharmony_ci */
3062306a36Sopenharmony_ci#define MEI_CLIENTS_MAX 256
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci/*
3362306a36Sopenharmony_ci * maximum number of consecutive resets
3462306a36Sopenharmony_ci */
3562306a36Sopenharmony_ci#define MEI_MAX_CONSEC_RESET  3
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci/*
3862306a36Sopenharmony_ci * Number of File descriptors/handles
3962306a36Sopenharmony_ci * that can be opened to the driver.
4062306a36Sopenharmony_ci *
4162306a36Sopenharmony_ci * Limit to 255: 256 Total Clients
4262306a36Sopenharmony_ci * minus internal client for MEI Bus Messages
4362306a36Sopenharmony_ci */
4462306a36Sopenharmony_ci#define  MEI_MAX_OPEN_HANDLE_COUNT (MEI_CLIENTS_MAX - 1)
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci/* File state */
4762306a36Sopenharmony_cienum file_state {
4862306a36Sopenharmony_ci	MEI_FILE_UNINITIALIZED = 0,
4962306a36Sopenharmony_ci	MEI_FILE_INITIALIZING,
5062306a36Sopenharmony_ci	MEI_FILE_CONNECTING,
5162306a36Sopenharmony_ci	MEI_FILE_CONNECTED,
5262306a36Sopenharmony_ci	MEI_FILE_DISCONNECTING,
5362306a36Sopenharmony_ci	MEI_FILE_DISCONNECT_REPLY,
5462306a36Sopenharmony_ci	MEI_FILE_DISCONNECT_REQUIRED,
5562306a36Sopenharmony_ci	MEI_FILE_DISCONNECTED,
5662306a36Sopenharmony_ci};
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci/* MEI device states */
5962306a36Sopenharmony_cienum mei_dev_state {
6062306a36Sopenharmony_ci	MEI_DEV_INITIALIZING = 0,
6162306a36Sopenharmony_ci	MEI_DEV_INIT_CLIENTS,
6262306a36Sopenharmony_ci	MEI_DEV_ENABLED,
6362306a36Sopenharmony_ci	MEI_DEV_RESETTING,
6462306a36Sopenharmony_ci	MEI_DEV_DISABLED,
6562306a36Sopenharmony_ci	MEI_DEV_POWERING_DOWN,
6662306a36Sopenharmony_ci	MEI_DEV_POWER_DOWN,
6762306a36Sopenharmony_ci	MEI_DEV_POWER_UP
6862306a36Sopenharmony_ci};
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci/**
7162306a36Sopenharmony_ci * enum mei_dev_pxp_mode - MEI PXP mode state
7262306a36Sopenharmony_ci *
7362306a36Sopenharmony_ci * @MEI_DEV_PXP_DEFAULT: PCH based device, no initailization required
7462306a36Sopenharmony_ci * @MEI_DEV_PXP_INIT:    device requires initialization, send setup message to firmware
7562306a36Sopenharmony_ci * @MEI_DEV_PXP_SETUP:   device is in setup stage, waiting for firmware repsonse
7662306a36Sopenharmony_ci * @MEI_DEV_PXP_READY:   device initialized
7762306a36Sopenharmony_ci */
7862306a36Sopenharmony_cienum mei_dev_pxp_mode {
7962306a36Sopenharmony_ci	MEI_DEV_PXP_DEFAULT = 0,
8062306a36Sopenharmony_ci	MEI_DEV_PXP_INIT    = 1,
8162306a36Sopenharmony_ci	MEI_DEV_PXP_SETUP   = 2,
8262306a36Sopenharmony_ci	MEI_DEV_PXP_READY   = 3,
8362306a36Sopenharmony_ci};
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ciconst char *mei_dev_state_str(int state);
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_cienum mei_file_transaction_states {
8862306a36Sopenharmony_ci	MEI_IDLE,
8962306a36Sopenharmony_ci	MEI_WRITING,
9062306a36Sopenharmony_ci	MEI_WRITE_COMPLETE,
9162306a36Sopenharmony_ci};
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci/**
9462306a36Sopenharmony_ci * enum mei_cb_file_ops  - file operation associated with the callback
9562306a36Sopenharmony_ci * @MEI_FOP_READ:       read
9662306a36Sopenharmony_ci * @MEI_FOP_WRITE:      write
9762306a36Sopenharmony_ci * @MEI_FOP_CONNECT:    connect
9862306a36Sopenharmony_ci * @MEI_FOP_DISCONNECT: disconnect
9962306a36Sopenharmony_ci * @MEI_FOP_DISCONNECT_RSP: disconnect response
10062306a36Sopenharmony_ci * @MEI_FOP_NOTIFY_START:   start notification
10162306a36Sopenharmony_ci * @MEI_FOP_NOTIFY_STOP:    stop notification
10262306a36Sopenharmony_ci * @MEI_FOP_DMA_MAP:   request client dma map
10362306a36Sopenharmony_ci * @MEI_FOP_DMA_UNMAP: request client dma unmap
10462306a36Sopenharmony_ci */
10562306a36Sopenharmony_cienum mei_cb_file_ops {
10662306a36Sopenharmony_ci	MEI_FOP_READ = 0,
10762306a36Sopenharmony_ci	MEI_FOP_WRITE,
10862306a36Sopenharmony_ci	MEI_FOP_CONNECT,
10962306a36Sopenharmony_ci	MEI_FOP_DISCONNECT,
11062306a36Sopenharmony_ci	MEI_FOP_DISCONNECT_RSP,
11162306a36Sopenharmony_ci	MEI_FOP_NOTIFY_START,
11262306a36Sopenharmony_ci	MEI_FOP_NOTIFY_STOP,
11362306a36Sopenharmony_ci	MEI_FOP_DMA_MAP,
11462306a36Sopenharmony_ci	MEI_FOP_DMA_UNMAP,
11562306a36Sopenharmony_ci};
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci/**
11862306a36Sopenharmony_ci * enum mei_cl_io_mode - io mode between driver and fw
11962306a36Sopenharmony_ci *
12062306a36Sopenharmony_ci * @MEI_CL_IO_TX_BLOCKING: send is blocking
12162306a36Sopenharmony_ci * @MEI_CL_IO_TX_INTERNAL: internal communication between driver and FW
12262306a36Sopenharmony_ci *
12362306a36Sopenharmony_ci * @MEI_CL_IO_RX_NONBLOCK: recv is non-blocking
12462306a36Sopenharmony_ci *
12562306a36Sopenharmony_ci * @MEI_CL_IO_SGL: send command with sgl list.
12662306a36Sopenharmony_ci */
12762306a36Sopenharmony_cienum mei_cl_io_mode {
12862306a36Sopenharmony_ci	MEI_CL_IO_TX_BLOCKING = BIT(0),
12962306a36Sopenharmony_ci	MEI_CL_IO_TX_INTERNAL = BIT(1),
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci	MEI_CL_IO_RX_NONBLOCK = BIT(2),
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci	MEI_CL_IO_SGL         = BIT(3),
13462306a36Sopenharmony_ci};
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci/*
13762306a36Sopenharmony_ci * Intel MEI message data struct
13862306a36Sopenharmony_ci */
13962306a36Sopenharmony_cistruct mei_msg_data {
14062306a36Sopenharmony_ci	size_t size;
14162306a36Sopenharmony_ci	unsigned char *data;
14262306a36Sopenharmony_ci};
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_cistruct mei_dma_data {
14562306a36Sopenharmony_ci	u8 buffer_id;
14662306a36Sopenharmony_ci	void *vaddr;
14762306a36Sopenharmony_ci	dma_addr_t daddr;
14862306a36Sopenharmony_ci	size_t size;
14962306a36Sopenharmony_ci};
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci/**
15262306a36Sopenharmony_ci * struct mei_dma_dscr - dma address descriptor
15362306a36Sopenharmony_ci *
15462306a36Sopenharmony_ci * @vaddr: dma buffer virtual address
15562306a36Sopenharmony_ci * @daddr: dma buffer physical address
15662306a36Sopenharmony_ci * @size : dma buffer size
15762306a36Sopenharmony_ci */
15862306a36Sopenharmony_cistruct mei_dma_dscr {
15962306a36Sopenharmony_ci	void *vaddr;
16062306a36Sopenharmony_ci	dma_addr_t daddr;
16162306a36Sopenharmony_ci	size_t size;
16262306a36Sopenharmony_ci};
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci/* Maximum number of processed FW status registers */
16562306a36Sopenharmony_ci#define MEI_FW_STATUS_MAX 6
16662306a36Sopenharmony_ci/* Minimal  buffer for FW status string (8 bytes in dw + space or '\0') */
16762306a36Sopenharmony_ci#define MEI_FW_STATUS_STR_SZ (MEI_FW_STATUS_MAX * (8 + 1))
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci/*
17162306a36Sopenharmony_ci * struct mei_fw_status - storage of FW status data
17262306a36Sopenharmony_ci *
17362306a36Sopenharmony_ci * @count: number of actually available elements in array
17462306a36Sopenharmony_ci * @status: FW status registers
17562306a36Sopenharmony_ci */
17662306a36Sopenharmony_cistruct mei_fw_status {
17762306a36Sopenharmony_ci	int count;
17862306a36Sopenharmony_ci	u32 status[MEI_FW_STATUS_MAX];
17962306a36Sopenharmony_ci};
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci/**
18262306a36Sopenharmony_ci * struct mei_me_client - representation of me (fw) client
18362306a36Sopenharmony_ci *
18462306a36Sopenharmony_ci * @list: link in me client list
18562306a36Sopenharmony_ci * @refcnt: struct reference count
18662306a36Sopenharmony_ci * @props: client properties
18762306a36Sopenharmony_ci * @client_id: me client id
18862306a36Sopenharmony_ci * @tx_flow_ctrl_creds: flow control credits
18962306a36Sopenharmony_ci * @connect_count: number connections to this client
19062306a36Sopenharmony_ci * @bus_added: added to bus
19162306a36Sopenharmony_ci */
19262306a36Sopenharmony_cistruct mei_me_client {
19362306a36Sopenharmony_ci	struct list_head list;
19462306a36Sopenharmony_ci	struct kref refcnt;
19562306a36Sopenharmony_ci	struct mei_client_properties props;
19662306a36Sopenharmony_ci	u8 client_id;
19762306a36Sopenharmony_ci	u8 tx_flow_ctrl_creds;
19862306a36Sopenharmony_ci	u8 connect_count;
19962306a36Sopenharmony_ci	u8 bus_added;
20062306a36Sopenharmony_ci};
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_cistruct mei_cl;
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci/**
20662306a36Sopenharmony_ci * struct mei_cl_cb - file operation callback structure
20762306a36Sopenharmony_ci *
20862306a36Sopenharmony_ci * @list: link in callback queue
20962306a36Sopenharmony_ci * @cl: file client who is running this operation
21062306a36Sopenharmony_ci * @fop_type: file operation type
21162306a36Sopenharmony_ci * @buf: buffer for data associated with the callback
21262306a36Sopenharmony_ci * @buf_idx: last read index
21362306a36Sopenharmony_ci * @vtag: virtual tag
21462306a36Sopenharmony_ci * @fp: pointer to file structure
21562306a36Sopenharmony_ci * @status: io status of the cb
21662306a36Sopenharmony_ci * @internal: communication between driver and FW flag
21762306a36Sopenharmony_ci * @blocking: transmission blocking mode
21862306a36Sopenharmony_ci * @ext_hdr: extended header
21962306a36Sopenharmony_ci */
22062306a36Sopenharmony_cistruct mei_cl_cb {
22162306a36Sopenharmony_ci	struct list_head list;
22262306a36Sopenharmony_ci	struct mei_cl *cl;
22362306a36Sopenharmony_ci	enum mei_cb_file_ops fop_type;
22462306a36Sopenharmony_ci	struct mei_msg_data buf;
22562306a36Sopenharmony_ci	size_t buf_idx;
22662306a36Sopenharmony_ci	u8 vtag;
22762306a36Sopenharmony_ci	const struct file *fp;
22862306a36Sopenharmony_ci	int status;
22962306a36Sopenharmony_ci	u32 internal:1;
23062306a36Sopenharmony_ci	u32 blocking:1;
23162306a36Sopenharmony_ci	struct mei_ext_hdr *ext_hdr;
23262306a36Sopenharmony_ci};
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ci/**
23562306a36Sopenharmony_ci * struct mei_cl_vtag - file pointer to vtag mapping structure
23662306a36Sopenharmony_ci *
23762306a36Sopenharmony_ci * @list: link in map queue
23862306a36Sopenharmony_ci * @fp: file pointer
23962306a36Sopenharmony_ci * @vtag: corresponding vtag
24062306a36Sopenharmony_ci * @pending_read: the read is pending on this file
24162306a36Sopenharmony_ci */
24262306a36Sopenharmony_cistruct mei_cl_vtag {
24362306a36Sopenharmony_ci	struct list_head list;
24462306a36Sopenharmony_ci	const struct file *fp;
24562306a36Sopenharmony_ci	u8 vtag;
24662306a36Sopenharmony_ci	u8 pending_read:1;
24762306a36Sopenharmony_ci};
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci/**
25062306a36Sopenharmony_ci * struct mei_cl - me client host representation
25162306a36Sopenharmony_ci *    carried in file->private_data
25262306a36Sopenharmony_ci *
25362306a36Sopenharmony_ci * @link: link in the clients list
25462306a36Sopenharmony_ci * @dev: mei parent device
25562306a36Sopenharmony_ci * @state: file operation state
25662306a36Sopenharmony_ci * @tx_wait: wait queue for tx completion
25762306a36Sopenharmony_ci * @rx_wait: wait queue for rx completion
25862306a36Sopenharmony_ci * @wait:  wait queue for management operation
25962306a36Sopenharmony_ci * @ev_wait: notification wait queue
26062306a36Sopenharmony_ci * @ev_async: event async notification
26162306a36Sopenharmony_ci * @status: connection status
26262306a36Sopenharmony_ci * @me_cl: fw client connected
26362306a36Sopenharmony_ci * @fp: file associated with client
26462306a36Sopenharmony_ci * @host_client_id: host id
26562306a36Sopenharmony_ci * @vtag_map: vtag map
26662306a36Sopenharmony_ci * @tx_flow_ctrl_creds: transmit flow credentials
26762306a36Sopenharmony_ci * @rx_flow_ctrl_creds: receive flow credentials
26862306a36Sopenharmony_ci * @timer_count:  watchdog timer for operation completion
26962306a36Sopenharmony_ci * @notify_en: notification - enabled/disabled
27062306a36Sopenharmony_ci * @notify_ev: pending notification event
27162306a36Sopenharmony_ci * @tx_cb_queued: number of tx callbacks in queue
27262306a36Sopenharmony_ci * @writing_state: state of the tx
27362306a36Sopenharmony_ci * @rd_pending: pending read credits
27462306a36Sopenharmony_ci * @rd_completed_lock: protects rd_completed queue
27562306a36Sopenharmony_ci * @rd_completed: completed read
27662306a36Sopenharmony_ci * @dma: dma settings
27762306a36Sopenharmony_ci * @dma_mapped: dma buffer is currently mapped.
27862306a36Sopenharmony_ci *
27962306a36Sopenharmony_ci * @cldev: device on the mei client bus
28062306a36Sopenharmony_ci */
28162306a36Sopenharmony_cistruct mei_cl {
28262306a36Sopenharmony_ci	struct list_head link;
28362306a36Sopenharmony_ci	struct mei_device *dev;
28462306a36Sopenharmony_ci	enum file_state state;
28562306a36Sopenharmony_ci	wait_queue_head_t tx_wait;
28662306a36Sopenharmony_ci	wait_queue_head_t rx_wait;
28762306a36Sopenharmony_ci	wait_queue_head_t wait;
28862306a36Sopenharmony_ci	wait_queue_head_t ev_wait;
28962306a36Sopenharmony_ci	struct fasync_struct *ev_async;
29062306a36Sopenharmony_ci	int status;
29162306a36Sopenharmony_ci	struct mei_me_client *me_cl;
29262306a36Sopenharmony_ci	const struct file *fp;
29362306a36Sopenharmony_ci	u8 host_client_id;
29462306a36Sopenharmony_ci	struct list_head vtag_map;
29562306a36Sopenharmony_ci	u8 tx_flow_ctrl_creds;
29662306a36Sopenharmony_ci	u8 rx_flow_ctrl_creds;
29762306a36Sopenharmony_ci	u8 timer_count;
29862306a36Sopenharmony_ci	u8 notify_en;
29962306a36Sopenharmony_ci	u8 notify_ev;
30062306a36Sopenharmony_ci	u8 tx_cb_queued;
30162306a36Sopenharmony_ci	enum mei_file_transaction_states writing_state;
30262306a36Sopenharmony_ci	struct list_head rd_pending;
30362306a36Sopenharmony_ci	spinlock_t rd_completed_lock; /* protects rd_completed queue */
30462306a36Sopenharmony_ci	struct list_head rd_completed;
30562306a36Sopenharmony_ci	struct mei_dma_data dma;
30662306a36Sopenharmony_ci	u8 dma_mapped;
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci	struct mei_cl_device *cldev;
30962306a36Sopenharmony_ci};
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_ci#define MEI_TX_QUEUE_LIMIT_DEFAULT 50
31262306a36Sopenharmony_ci#define MEI_TX_QUEUE_LIMIT_MAX 255
31362306a36Sopenharmony_ci#define MEI_TX_QUEUE_LIMIT_MIN 30
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci/**
31662306a36Sopenharmony_ci * struct mei_hw_ops - hw specific ops
31762306a36Sopenharmony_ci *
31862306a36Sopenharmony_ci * @host_is_ready    : query for host readiness
31962306a36Sopenharmony_ci *
32062306a36Sopenharmony_ci * @hw_is_ready      : query if hw is ready
32162306a36Sopenharmony_ci * @hw_reset         : reset hw
32262306a36Sopenharmony_ci * @hw_start         : start hw after reset
32362306a36Sopenharmony_ci * @hw_config        : configure hw
32462306a36Sopenharmony_ci *
32562306a36Sopenharmony_ci * @fw_status        : get fw status registers
32662306a36Sopenharmony_ci * @trc_status       : get trc status register
32762306a36Sopenharmony_ci * @pg_state         : power gating state of the device
32862306a36Sopenharmony_ci * @pg_in_transition : is device now in pg transition
32962306a36Sopenharmony_ci * @pg_is_enabled    : is power gating enabled
33062306a36Sopenharmony_ci *
33162306a36Sopenharmony_ci * @intr_clear       : clear pending interrupts
33262306a36Sopenharmony_ci * @intr_enable      : enable interrupts
33362306a36Sopenharmony_ci * @intr_disable     : disable interrupts
33462306a36Sopenharmony_ci * @synchronize_irq  : synchronize irqs
33562306a36Sopenharmony_ci *
33662306a36Sopenharmony_ci * @hbuf_free_slots  : query for write buffer empty slots
33762306a36Sopenharmony_ci * @hbuf_is_ready    : query if write buffer is empty
33862306a36Sopenharmony_ci * @hbuf_depth       : query for write buffer depth
33962306a36Sopenharmony_ci *
34062306a36Sopenharmony_ci * @write            : write a message to FW
34162306a36Sopenharmony_ci *
34262306a36Sopenharmony_ci * @rdbuf_full_slots : query how many slots are filled
34362306a36Sopenharmony_ci *
34462306a36Sopenharmony_ci * @read_hdr         : get first 4 bytes (header)
34562306a36Sopenharmony_ci * @read             : read a buffer from the FW
34662306a36Sopenharmony_ci */
34762306a36Sopenharmony_cistruct mei_hw_ops {
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci	bool (*host_is_ready)(struct mei_device *dev);
35062306a36Sopenharmony_ci
35162306a36Sopenharmony_ci	bool (*hw_is_ready)(struct mei_device *dev);
35262306a36Sopenharmony_ci	int (*hw_reset)(struct mei_device *dev, bool enable);
35362306a36Sopenharmony_ci	int (*hw_start)(struct mei_device *dev);
35462306a36Sopenharmony_ci	int (*hw_config)(struct mei_device *dev);
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci	int (*fw_status)(struct mei_device *dev, struct mei_fw_status *fw_sts);
35762306a36Sopenharmony_ci	int (*trc_status)(struct mei_device *dev, u32 *trc);
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ci	enum mei_pg_state (*pg_state)(struct mei_device *dev);
36062306a36Sopenharmony_ci	bool (*pg_in_transition)(struct mei_device *dev);
36162306a36Sopenharmony_ci	bool (*pg_is_enabled)(struct mei_device *dev);
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci	void (*intr_clear)(struct mei_device *dev);
36462306a36Sopenharmony_ci	void (*intr_enable)(struct mei_device *dev);
36562306a36Sopenharmony_ci	void (*intr_disable)(struct mei_device *dev);
36662306a36Sopenharmony_ci	void (*synchronize_irq)(struct mei_device *dev);
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_ci	int (*hbuf_free_slots)(struct mei_device *dev);
36962306a36Sopenharmony_ci	bool (*hbuf_is_ready)(struct mei_device *dev);
37062306a36Sopenharmony_ci	u32 (*hbuf_depth)(const struct mei_device *dev);
37162306a36Sopenharmony_ci	int (*write)(struct mei_device *dev,
37262306a36Sopenharmony_ci		     const void *hdr, size_t hdr_len,
37362306a36Sopenharmony_ci		     const void *data, size_t data_len);
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_ci	int (*rdbuf_full_slots)(struct mei_device *dev);
37662306a36Sopenharmony_ci
37762306a36Sopenharmony_ci	u32 (*read_hdr)(const struct mei_device *dev);
37862306a36Sopenharmony_ci	int (*read)(struct mei_device *dev,
37962306a36Sopenharmony_ci		     unsigned char *buf, unsigned long len);
38062306a36Sopenharmony_ci};
38162306a36Sopenharmony_ci
38262306a36Sopenharmony_ci/* MEI bus API*/
38362306a36Sopenharmony_civoid mei_cl_bus_rescan_work(struct work_struct *work);
38462306a36Sopenharmony_civoid mei_cl_bus_dev_fixup(struct mei_cl_device *dev);
38562306a36Sopenharmony_cissize_t __mei_cl_send(struct mei_cl *cl, const u8 *buf, size_t length, u8 vtag,
38662306a36Sopenharmony_ci		      unsigned int mode);
38762306a36Sopenharmony_cissize_t __mei_cl_send_timeout(struct mei_cl *cl, const u8 *buf, size_t length, u8 vtag,
38862306a36Sopenharmony_ci			      unsigned int mode, unsigned long timeout);
38962306a36Sopenharmony_cissize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, u8 *vtag,
39062306a36Sopenharmony_ci		      unsigned int mode, unsigned long timeout);
39162306a36Sopenharmony_cibool mei_cl_bus_rx_event(struct mei_cl *cl);
39262306a36Sopenharmony_cibool mei_cl_bus_notify_event(struct mei_cl *cl);
39362306a36Sopenharmony_civoid mei_cl_bus_remove_devices(struct mei_device *bus);
39462306a36Sopenharmony_ciint mei_cl_bus_init(void);
39562306a36Sopenharmony_civoid mei_cl_bus_exit(void);
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_ci/**
39862306a36Sopenharmony_ci * enum mei_pg_event - power gating transition events
39962306a36Sopenharmony_ci *
40062306a36Sopenharmony_ci * @MEI_PG_EVENT_IDLE: the driver is not in power gating transition
40162306a36Sopenharmony_ci * @MEI_PG_EVENT_WAIT: the driver is waiting for a pg event to complete
40262306a36Sopenharmony_ci * @MEI_PG_EVENT_RECEIVED: the driver received pg event
40362306a36Sopenharmony_ci * @MEI_PG_EVENT_INTR_WAIT: the driver is waiting for a pg event interrupt
40462306a36Sopenharmony_ci * @MEI_PG_EVENT_INTR_RECEIVED: the driver received pg event interrupt
40562306a36Sopenharmony_ci */
40662306a36Sopenharmony_cienum mei_pg_event {
40762306a36Sopenharmony_ci	MEI_PG_EVENT_IDLE,
40862306a36Sopenharmony_ci	MEI_PG_EVENT_WAIT,
40962306a36Sopenharmony_ci	MEI_PG_EVENT_RECEIVED,
41062306a36Sopenharmony_ci	MEI_PG_EVENT_INTR_WAIT,
41162306a36Sopenharmony_ci	MEI_PG_EVENT_INTR_RECEIVED,
41262306a36Sopenharmony_ci};
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_ci/**
41562306a36Sopenharmony_ci * enum mei_pg_state - device internal power gating state
41662306a36Sopenharmony_ci *
41762306a36Sopenharmony_ci * @MEI_PG_OFF: device is not power gated - it is active
41862306a36Sopenharmony_ci * @MEI_PG_ON:  device is power gated - it is in lower power state
41962306a36Sopenharmony_ci */
42062306a36Sopenharmony_cienum mei_pg_state {
42162306a36Sopenharmony_ci	MEI_PG_OFF = 0,
42262306a36Sopenharmony_ci	MEI_PG_ON =  1,
42362306a36Sopenharmony_ci};
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_ciconst char *mei_pg_state_str(enum mei_pg_state state);
42662306a36Sopenharmony_ci
42762306a36Sopenharmony_ci/**
42862306a36Sopenharmony_ci * struct mei_fw_version - MEI FW version struct
42962306a36Sopenharmony_ci *
43062306a36Sopenharmony_ci * @platform: platform identifier
43162306a36Sopenharmony_ci * @major: major version field
43262306a36Sopenharmony_ci * @minor: minor version field
43362306a36Sopenharmony_ci * @buildno: build number version field
43462306a36Sopenharmony_ci * @hotfix: hotfix number version field
43562306a36Sopenharmony_ci */
43662306a36Sopenharmony_cistruct mei_fw_version {
43762306a36Sopenharmony_ci	u8 platform;
43862306a36Sopenharmony_ci	u8 major;
43962306a36Sopenharmony_ci	u16 minor;
44062306a36Sopenharmony_ci	u16 buildno;
44162306a36Sopenharmony_ci	u16 hotfix;
44262306a36Sopenharmony_ci};
44362306a36Sopenharmony_ci
44462306a36Sopenharmony_ci#define MEI_MAX_FW_VER_BLOCKS 3
44562306a36Sopenharmony_ci
44662306a36Sopenharmony_cistruct mei_dev_timeouts {
44762306a36Sopenharmony_ci	unsigned long hw_ready; /* Timeout on ready message, in jiffies */
44862306a36Sopenharmony_ci	int connect; /* HPS: at least 2 seconds, in seconds */
44962306a36Sopenharmony_ci	unsigned long cl_connect; /* HPS: Client Connect Timeout, in jiffies */
45062306a36Sopenharmony_ci	int client_init; /* HPS: Clients Enumeration Timeout, in seconds */
45162306a36Sopenharmony_ci	unsigned long pgi; /* PG Isolation time response, in jiffies */
45262306a36Sopenharmony_ci	unsigned int d0i3; /* D0i3 set/unset max response time, in jiffies */
45362306a36Sopenharmony_ci	unsigned long hbm; /* HBM operation timeout, in jiffies */
45462306a36Sopenharmony_ci	unsigned long mkhi_recv; /* receive timeout, in jiffies */
45562306a36Sopenharmony_ci};
45662306a36Sopenharmony_ci
45762306a36Sopenharmony_ci/**
45862306a36Sopenharmony_ci * struct mei_device -  MEI private device struct
45962306a36Sopenharmony_ci *
46062306a36Sopenharmony_ci * @dev         : device on a bus
46162306a36Sopenharmony_ci * @cdev        : character device
46262306a36Sopenharmony_ci * @minor       : minor number allocated for device
46362306a36Sopenharmony_ci *
46462306a36Sopenharmony_ci * @write_list  : write pending list
46562306a36Sopenharmony_ci * @write_waiting_list : write completion list
46662306a36Sopenharmony_ci * @ctrl_wr_list : pending control write list
46762306a36Sopenharmony_ci * @ctrl_rd_list : pending control read list
46862306a36Sopenharmony_ci * @tx_queue_limit: tx queues per client linit
46962306a36Sopenharmony_ci *
47062306a36Sopenharmony_ci * @file_list   : list of opened handles
47162306a36Sopenharmony_ci * @open_handle_count: number of opened handles
47262306a36Sopenharmony_ci *
47362306a36Sopenharmony_ci * @device_lock : big device lock
47462306a36Sopenharmony_ci * @timer_work  : MEI timer delayed work (timeouts)
47562306a36Sopenharmony_ci *
47662306a36Sopenharmony_ci * @recvd_hw_ready : hw ready message received flag
47762306a36Sopenharmony_ci *
47862306a36Sopenharmony_ci * @wait_hw_ready : wait queue for receive HW ready message form FW
47962306a36Sopenharmony_ci * @wait_pg     : wait queue for receive PG message from FW
48062306a36Sopenharmony_ci * @wait_hbm_start : wait queue for receive HBM start message from FW
48162306a36Sopenharmony_ci *
48262306a36Sopenharmony_ci * @reset_count : number of consecutive resets
48362306a36Sopenharmony_ci * @dev_state   : device state
48462306a36Sopenharmony_ci * @hbm_state   : state of host bus message protocol
48562306a36Sopenharmony_ci * @pxp_mode    : PXP device mode
48662306a36Sopenharmony_ci * @init_clients_timer : HBM init handshake timeout
48762306a36Sopenharmony_ci *
48862306a36Sopenharmony_ci * @pg_event    : power gating event
48962306a36Sopenharmony_ci * @pg_domain   : runtime PM domain
49062306a36Sopenharmony_ci *
49162306a36Sopenharmony_ci * @rd_msg_buf  : control messages buffer
49262306a36Sopenharmony_ci * @rd_msg_hdr  : read message header storage
49362306a36Sopenharmony_ci * @rd_msg_hdr_count : how many dwords were already read from header
49462306a36Sopenharmony_ci *
49562306a36Sopenharmony_ci * @hbuf_is_ready : query if the host host/write buffer is ready
49662306a36Sopenharmony_ci * @dr_dscr: DMA ring descriptors: TX, RX, and CTRL
49762306a36Sopenharmony_ci *
49862306a36Sopenharmony_ci * @version     : HBM protocol version in use
49962306a36Sopenharmony_ci * @hbm_f_pg_supported  : hbm feature pgi protocol
50062306a36Sopenharmony_ci * @hbm_f_dc_supported  : hbm feature dynamic clients
50162306a36Sopenharmony_ci * @hbm_f_dot_supported : hbm feature disconnect on timeout
50262306a36Sopenharmony_ci * @hbm_f_ev_supported  : hbm feature event notification
50362306a36Sopenharmony_ci * @hbm_f_fa_supported  : hbm feature fixed address client
50462306a36Sopenharmony_ci * @hbm_f_ie_supported  : hbm feature immediate reply to enum request
50562306a36Sopenharmony_ci * @hbm_f_os_supported  : hbm feature support OS ver message
50662306a36Sopenharmony_ci * @hbm_f_dr_supported  : hbm feature dma ring supported
50762306a36Sopenharmony_ci * @hbm_f_vt_supported  : hbm feature vtag supported
50862306a36Sopenharmony_ci * @hbm_f_cap_supported : hbm feature capabilities message supported
50962306a36Sopenharmony_ci * @hbm_f_cd_supported  : hbm feature client dma supported
51062306a36Sopenharmony_ci * @hbm_f_gsc_supported : hbm feature gsc supported
51162306a36Sopenharmony_ci *
51262306a36Sopenharmony_ci * @fw_ver : FW versions
51362306a36Sopenharmony_ci *
51462306a36Sopenharmony_ci * @fw_f_fw_ver_supported : fw feature: fw version supported
51562306a36Sopenharmony_ci * @fw_ver_received : fw version received
51662306a36Sopenharmony_ci *
51762306a36Sopenharmony_ci * @me_clients_rwsem: rw lock over me_clients list
51862306a36Sopenharmony_ci * @me_clients  : list of FW clients
51962306a36Sopenharmony_ci * @me_clients_map : FW clients bit map
52062306a36Sopenharmony_ci * @host_clients_map : host clients id pool
52162306a36Sopenharmony_ci *
52262306a36Sopenharmony_ci * @allow_fixed_address: allow user space to connect a fixed client
52362306a36Sopenharmony_ci * @override_fixed_address: force allow fixed address behavior
52462306a36Sopenharmony_ci *
52562306a36Sopenharmony_ci * @timeouts: actual timeout values
52662306a36Sopenharmony_ci *
52762306a36Sopenharmony_ci * @reset_work  : work item for the device reset
52862306a36Sopenharmony_ci * @bus_rescan_work : work item for the bus rescan
52962306a36Sopenharmony_ci *
53062306a36Sopenharmony_ci * @device_list : mei client bus list
53162306a36Sopenharmony_ci * @cl_bus_lock : client bus list lock
53262306a36Sopenharmony_ci *
53362306a36Sopenharmony_ci * @kind        : kind of mei device
53462306a36Sopenharmony_ci *
53562306a36Sopenharmony_ci * @dbgfs_dir   : debugfs mei root directory
53662306a36Sopenharmony_ci *
53762306a36Sopenharmony_ci * @ops:        : hw specific operations
53862306a36Sopenharmony_ci * @hw          : hw specific data
53962306a36Sopenharmony_ci */
54062306a36Sopenharmony_cistruct mei_device {
54162306a36Sopenharmony_ci	struct device *dev;
54262306a36Sopenharmony_ci	struct cdev cdev;
54362306a36Sopenharmony_ci	int minor;
54462306a36Sopenharmony_ci
54562306a36Sopenharmony_ci	struct list_head write_list;
54662306a36Sopenharmony_ci	struct list_head write_waiting_list;
54762306a36Sopenharmony_ci	struct list_head ctrl_wr_list;
54862306a36Sopenharmony_ci	struct list_head ctrl_rd_list;
54962306a36Sopenharmony_ci	u8 tx_queue_limit;
55062306a36Sopenharmony_ci
55162306a36Sopenharmony_ci	struct list_head file_list;
55262306a36Sopenharmony_ci	long open_handle_count;
55362306a36Sopenharmony_ci
55462306a36Sopenharmony_ci	struct mutex device_lock;
55562306a36Sopenharmony_ci	struct delayed_work timer_work;
55662306a36Sopenharmony_ci
55762306a36Sopenharmony_ci	bool recvd_hw_ready;
55862306a36Sopenharmony_ci	/*
55962306a36Sopenharmony_ci	 * waiting queue for receive message from FW
56062306a36Sopenharmony_ci	 */
56162306a36Sopenharmony_ci	wait_queue_head_t wait_hw_ready;
56262306a36Sopenharmony_ci	wait_queue_head_t wait_pg;
56362306a36Sopenharmony_ci	wait_queue_head_t wait_hbm_start;
56462306a36Sopenharmony_ci
56562306a36Sopenharmony_ci	/*
56662306a36Sopenharmony_ci	 * mei device  states
56762306a36Sopenharmony_ci	 */
56862306a36Sopenharmony_ci	unsigned long reset_count;
56962306a36Sopenharmony_ci	enum mei_dev_state dev_state;
57062306a36Sopenharmony_ci	enum mei_hbm_state hbm_state;
57162306a36Sopenharmony_ci	enum mei_dev_pxp_mode pxp_mode;
57262306a36Sopenharmony_ci	u16 init_clients_timer;
57362306a36Sopenharmony_ci
57462306a36Sopenharmony_ci	/*
57562306a36Sopenharmony_ci	 * Power Gating support
57662306a36Sopenharmony_ci	 */
57762306a36Sopenharmony_ci	enum mei_pg_event pg_event;
57862306a36Sopenharmony_ci#ifdef CONFIG_PM
57962306a36Sopenharmony_ci	struct dev_pm_domain pg_domain;
58062306a36Sopenharmony_ci#endif /* CONFIG_PM */
58162306a36Sopenharmony_ci
58262306a36Sopenharmony_ci	unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE];
58362306a36Sopenharmony_ci	u32 rd_msg_hdr[MEI_RD_MSG_BUF_SIZE];
58462306a36Sopenharmony_ci	int rd_msg_hdr_count;
58562306a36Sopenharmony_ci
58662306a36Sopenharmony_ci	/* write buffer */
58762306a36Sopenharmony_ci	bool hbuf_is_ready;
58862306a36Sopenharmony_ci
58962306a36Sopenharmony_ci	struct mei_dma_dscr dr_dscr[DMA_DSCR_NUM];
59062306a36Sopenharmony_ci
59162306a36Sopenharmony_ci	struct hbm_version version;
59262306a36Sopenharmony_ci	unsigned int hbm_f_pg_supported:1;
59362306a36Sopenharmony_ci	unsigned int hbm_f_dc_supported:1;
59462306a36Sopenharmony_ci	unsigned int hbm_f_dot_supported:1;
59562306a36Sopenharmony_ci	unsigned int hbm_f_ev_supported:1;
59662306a36Sopenharmony_ci	unsigned int hbm_f_fa_supported:1;
59762306a36Sopenharmony_ci	unsigned int hbm_f_ie_supported:1;
59862306a36Sopenharmony_ci	unsigned int hbm_f_os_supported:1;
59962306a36Sopenharmony_ci	unsigned int hbm_f_dr_supported:1;
60062306a36Sopenharmony_ci	unsigned int hbm_f_vt_supported:1;
60162306a36Sopenharmony_ci	unsigned int hbm_f_cap_supported:1;
60262306a36Sopenharmony_ci	unsigned int hbm_f_cd_supported:1;
60362306a36Sopenharmony_ci	unsigned int hbm_f_gsc_supported:1;
60462306a36Sopenharmony_ci
60562306a36Sopenharmony_ci	struct mei_fw_version fw_ver[MEI_MAX_FW_VER_BLOCKS];
60662306a36Sopenharmony_ci
60762306a36Sopenharmony_ci	unsigned int fw_f_fw_ver_supported:1;
60862306a36Sopenharmony_ci	unsigned int fw_ver_received:1;
60962306a36Sopenharmony_ci
61062306a36Sopenharmony_ci	struct rw_semaphore me_clients_rwsem;
61162306a36Sopenharmony_ci	struct list_head me_clients;
61262306a36Sopenharmony_ci	DECLARE_BITMAP(me_clients_map, MEI_CLIENTS_MAX);
61362306a36Sopenharmony_ci	DECLARE_BITMAP(host_clients_map, MEI_CLIENTS_MAX);
61462306a36Sopenharmony_ci
61562306a36Sopenharmony_ci	bool allow_fixed_address;
61662306a36Sopenharmony_ci	bool override_fixed_address;
61762306a36Sopenharmony_ci
61862306a36Sopenharmony_ci	struct mei_dev_timeouts timeouts;
61962306a36Sopenharmony_ci
62062306a36Sopenharmony_ci	struct work_struct reset_work;
62162306a36Sopenharmony_ci	struct work_struct bus_rescan_work;
62262306a36Sopenharmony_ci
62362306a36Sopenharmony_ci	/* List of bus devices */
62462306a36Sopenharmony_ci	struct list_head device_list;
62562306a36Sopenharmony_ci	struct mutex cl_bus_lock;
62662306a36Sopenharmony_ci
62762306a36Sopenharmony_ci	const char *kind;
62862306a36Sopenharmony_ci
62962306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_DEBUG_FS)
63062306a36Sopenharmony_ci	struct dentry *dbgfs_dir;
63162306a36Sopenharmony_ci#endif /* CONFIG_DEBUG_FS */
63262306a36Sopenharmony_ci
63362306a36Sopenharmony_ci	const struct mei_hw_ops *ops;
63462306a36Sopenharmony_ci	char hw[] __aligned(sizeof(void *));
63562306a36Sopenharmony_ci};
63662306a36Sopenharmony_ci
63762306a36Sopenharmony_cistatic inline unsigned long mei_secs_to_jiffies(unsigned long sec)
63862306a36Sopenharmony_ci{
63962306a36Sopenharmony_ci	return msecs_to_jiffies(sec * MSEC_PER_SEC);
64062306a36Sopenharmony_ci}
64162306a36Sopenharmony_ci
64262306a36Sopenharmony_ci/**
64362306a36Sopenharmony_ci * mei_data2slots - get slots number from a message length
64462306a36Sopenharmony_ci *
64562306a36Sopenharmony_ci * @length: size of the messages in bytes
64662306a36Sopenharmony_ci *
64762306a36Sopenharmony_ci * Return: number of slots
64862306a36Sopenharmony_ci */
64962306a36Sopenharmony_cistatic inline u32 mei_data2slots(size_t length)
65062306a36Sopenharmony_ci{
65162306a36Sopenharmony_ci	return DIV_ROUND_UP(length, MEI_SLOT_SIZE);
65262306a36Sopenharmony_ci}
65362306a36Sopenharmony_ci
65462306a36Sopenharmony_ci/**
65562306a36Sopenharmony_ci * mei_hbm2slots - get slots number from a hbm message length
65662306a36Sopenharmony_ci *                 length + size of the mei message header
65762306a36Sopenharmony_ci *
65862306a36Sopenharmony_ci * @length: size of the messages in bytes
65962306a36Sopenharmony_ci *
66062306a36Sopenharmony_ci * Return: number of slots
66162306a36Sopenharmony_ci */
66262306a36Sopenharmony_cistatic inline u32 mei_hbm2slots(size_t length)
66362306a36Sopenharmony_ci{
66462306a36Sopenharmony_ci	return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, MEI_SLOT_SIZE);
66562306a36Sopenharmony_ci}
66662306a36Sopenharmony_ci
66762306a36Sopenharmony_ci/**
66862306a36Sopenharmony_ci * mei_slots2data - get data in slots - bytes from slots
66962306a36Sopenharmony_ci *
67062306a36Sopenharmony_ci * @slots: number of available slots
67162306a36Sopenharmony_ci *
67262306a36Sopenharmony_ci * Return: number of bytes in slots
67362306a36Sopenharmony_ci */
67462306a36Sopenharmony_cistatic inline u32 mei_slots2data(int slots)
67562306a36Sopenharmony_ci{
67662306a36Sopenharmony_ci	return slots * MEI_SLOT_SIZE;
67762306a36Sopenharmony_ci}
67862306a36Sopenharmony_ci
67962306a36Sopenharmony_ci/*
68062306a36Sopenharmony_ci * mei init function prototypes
68162306a36Sopenharmony_ci */
68262306a36Sopenharmony_civoid mei_device_init(struct mei_device *dev,
68362306a36Sopenharmony_ci		     struct device *device,
68462306a36Sopenharmony_ci		     bool slow_fw,
68562306a36Sopenharmony_ci		     const struct mei_hw_ops *hw_ops);
68662306a36Sopenharmony_ciint mei_reset(struct mei_device *dev);
68762306a36Sopenharmony_ciint mei_start(struct mei_device *dev);
68862306a36Sopenharmony_ciint mei_restart(struct mei_device *dev);
68962306a36Sopenharmony_civoid mei_stop(struct mei_device *dev);
69062306a36Sopenharmony_civoid mei_cancel_work(struct mei_device *dev);
69162306a36Sopenharmony_ci
69262306a36Sopenharmony_civoid mei_set_devstate(struct mei_device *dev, enum mei_dev_state state);
69362306a36Sopenharmony_ci
69462306a36Sopenharmony_ciint mei_dmam_ring_alloc(struct mei_device *dev);
69562306a36Sopenharmony_civoid mei_dmam_ring_free(struct mei_device *dev);
69662306a36Sopenharmony_cibool mei_dma_ring_is_allocated(struct mei_device *dev);
69762306a36Sopenharmony_civoid mei_dma_ring_reset(struct mei_device *dev);
69862306a36Sopenharmony_civoid mei_dma_ring_read(struct mei_device *dev, unsigned char *buf, u32 len);
69962306a36Sopenharmony_civoid mei_dma_ring_write(struct mei_device *dev, unsigned char *buf, u32 len);
70062306a36Sopenharmony_ciu32 mei_dma_ring_empty_slots(struct mei_device *dev);
70162306a36Sopenharmony_ci
70262306a36Sopenharmony_ci/*
70362306a36Sopenharmony_ci *  MEI interrupt functions prototype
70462306a36Sopenharmony_ci */
70562306a36Sopenharmony_ci
70662306a36Sopenharmony_civoid mei_timer(struct work_struct *work);
70762306a36Sopenharmony_civoid mei_schedule_stall_timer(struct mei_device *dev);
70862306a36Sopenharmony_ciint mei_irq_read_handler(struct mei_device *dev,
70962306a36Sopenharmony_ci			 struct list_head *cmpl_list, s32 *slots);
71062306a36Sopenharmony_ci
71162306a36Sopenharmony_ciint mei_irq_write_handler(struct mei_device *dev, struct list_head *cmpl_list);
71262306a36Sopenharmony_civoid mei_irq_compl_handler(struct mei_device *dev, struct list_head *cmpl_list);
71362306a36Sopenharmony_ci
71462306a36Sopenharmony_ci/*
71562306a36Sopenharmony_ci * Register Access Function
71662306a36Sopenharmony_ci */
71762306a36Sopenharmony_ci
71862306a36Sopenharmony_ci
71962306a36Sopenharmony_cistatic inline int mei_hw_config(struct mei_device *dev)
72062306a36Sopenharmony_ci{
72162306a36Sopenharmony_ci	return dev->ops->hw_config(dev);
72262306a36Sopenharmony_ci}
72362306a36Sopenharmony_ci
72462306a36Sopenharmony_cistatic inline enum mei_pg_state mei_pg_state(struct mei_device *dev)
72562306a36Sopenharmony_ci{
72662306a36Sopenharmony_ci	return dev->ops->pg_state(dev);
72762306a36Sopenharmony_ci}
72862306a36Sopenharmony_ci
72962306a36Sopenharmony_cistatic inline bool mei_pg_in_transition(struct mei_device *dev)
73062306a36Sopenharmony_ci{
73162306a36Sopenharmony_ci	return dev->ops->pg_in_transition(dev);
73262306a36Sopenharmony_ci}
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_cistatic inline bool mei_pg_is_enabled(struct mei_device *dev)
73562306a36Sopenharmony_ci{
73662306a36Sopenharmony_ci	return dev->ops->pg_is_enabled(dev);
73762306a36Sopenharmony_ci}
73862306a36Sopenharmony_ci
73962306a36Sopenharmony_cistatic inline int mei_hw_reset(struct mei_device *dev, bool enable)
74062306a36Sopenharmony_ci{
74162306a36Sopenharmony_ci	return dev->ops->hw_reset(dev, enable);
74262306a36Sopenharmony_ci}
74362306a36Sopenharmony_ci
74462306a36Sopenharmony_cistatic inline int mei_hw_start(struct mei_device *dev)
74562306a36Sopenharmony_ci{
74662306a36Sopenharmony_ci	return dev->ops->hw_start(dev);
74762306a36Sopenharmony_ci}
74862306a36Sopenharmony_ci
74962306a36Sopenharmony_cistatic inline void mei_clear_interrupts(struct mei_device *dev)
75062306a36Sopenharmony_ci{
75162306a36Sopenharmony_ci	dev->ops->intr_clear(dev);
75262306a36Sopenharmony_ci}
75362306a36Sopenharmony_ci
75462306a36Sopenharmony_cistatic inline void mei_enable_interrupts(struct mei_device *dev)
75562306a36Sopenharmony_ci{
75662306a36Sopenharmony_ci	dev->ops->intr_enable(dev);
75762306a36Sopenharmony_ci}
75862306a36Sopenharmony_ci
75962306a36Sopenharmony_cistatic inline void mei_disable_interrupts(struct mei_device *dev)
76062306a36Sopenharmony_ci{
76162306a36Sopenharmony_ci	dev->ops->intr_disable(dev);
76262306a36Sopenharmony_ci}
76362306a36Sopenharmony_ci
76462306a36Sopenharmony_cistatic inline void mei_synchronize_irq(struct mei_device *dev)
76562306a36Sopenharmony_ci{
76662306a36Sopenharmony_ci	dev->ops->synchronize_irq(dev);
76762306a36Sopenharmony_ci}
76862306a36Sopenharmony_ci
76962306a36Sopenharmony_cistatic inline bool mei_host_is_ready(struct mei_device *dev)
77062306a36Sopenharmony_ci{
77162306a36Sopenharmony_ci	return dev->ops->host_is_ready(dev);
77262306a36Sopenharmony_ci}
77362306a36Sopenharmony_cistatic inline bool mei_hw_is_ready(struct mei_device *dev)
77462306a36Sopenharmony_ci{
77562306a36Sopenharmony_ci	return dev->ops->hw_is_ready(dev);
77662306a36Sopenharmony_ci}
77762306a36Sopenharmony_ci
77862306a36Sopenharmony_cistatic inline bool mei_hbuf_is_ready(struct mei_device *dev)
77962306a36Sopenharmony_ci{
78062306a36Sopenharmony_ci	return dev->ops->hbuf_is_ready(dev);
78162306a36Sopenharmony_ci}
78262306a36Sopenharmony_ci
78362306a36Sopenharmony_cistatic inline int mei_hbuf_empty_slots(struct mei_device *dev)
78462306a36Sopenharmony_ci{
78562306a36Sopenharmony_ci	return dev->ops->hbuf_free_slots(dev);
78662306a36Sopenharmony_ci}
78762306a36Sopenharmony_ci
78862306a36Sopenharmony_cistatic inline u32 mei_hbuf_depth(const struct mei_device *dev)
78962306a36Sopenharmony_ci{
79062306a36Sopenharmony_ci	return dev->ops->hbuf_depth(dev);
79162306a36Sopenharmony_ci}
79262306a36Sopenharmony_ci
79362306a36Sopenharmony_cistatic inline int mei_write_message(struct mei_device *dev,
79462306a36Sopenharmony_ci				    const void *hdr, size_t hdr_len,
79562306a36Sopenharmony_ci				    const void *data, size_t data_len)
79662306a36Sopenharmony_ci{
79762306a36Sopenharmony_ci	return dev->ops->write(dev, hdr, hdr_len, data, data_len);
79862306a36Sopenharmony_ci}
79962306a36Sopenharmony_ci
80062306a36Sopenharmony_cistatic inline u32 mei_read_hdr(const struct mei_device *dev)
80162306a36Sopenharmony_ci{
80262306a36Sopenharmony_ci	return dev->ops->read_hdr(dev);
80362306a36Sopenharmony_ci}
80462306a36Sopenharmony_ci
80562306a36Sopenharmony_cistatic inline void mei_read_slots(struct mei_device *dev,
80662306a36Sopenharmony_ci		     unsigned char *buf, unsigned long len)
80762306a36Sopenharmony_ci{
80862306a36Sopenharmony_ci	dev->ops->read(dev, buf, len);
80962306a36Sopenharmony_ci}
81062306a36Sopenharmony_ci
81162306a36Sopenharmony_cistatic inline int mei_count_full_read_slots(struct mei_device *dev)
81262306a36Sopenharmony_ci{
81362306a36Sopenharmony_ci	return dev->ops->rdbuf_full_slots(dev);
81462306a36Sopenharmony_ci}
81562306a36Sopenharmony_ci
81662306a36Sopenharmony_cistatic inline int mei_trc_status(struct mei_device *dev, u32 *trc)
81762306a36Sopenharmony_ci{
81862306a36Sopenharmony_ci	if (dev->ops->trc_status)
81962306a36Sopenharmony_ci		return dev->ops->trc_status(dev, trc);
82062306a36Sopenharmony_ci	return -EOPNOTSUPP;
82162306a36Sopenharmony_ci}
82262306a36Sopenharmony_ci
82362306a36Sopenharmony_cistatic inline int mei_fw_status(struct mei_device *dev,
82462306a36Sopenharmony_ci				struct mei_fw_status *fw_status)
82562306a36Sopenharmony_ci{
82662306a36Sopenharmony_ci	return dev->ops->fw_status(dev, fw_status);
82762306a36Sopenharmony_ci}
82862306a36Sopenharmony_ci
82962306a36Sopenharmony_cibool mei_hbuf_acquire(struct mei_device *dev);
83062306a36Sopenharmony_ci
83162306a36Sopenharmony_cibool mei_write_is_idle(struct mei_device *dev);
83262306a36Sopenharmony_ci
83362306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_DEBUG_FS)
83462306a36Sopenharmony_civoid mei_dbgfs_register(struct mei_device *dev, const char *name);
83562306a36Sopenharmony_civoid mei_dbgfs_deregister(struct mei_device *dev);
83662306a36Sopenharmony_ci#else
83762306a36Sopenharmony_cistatic inline void mei_dbgfs_register(struct mei_device *dev, const char *name) {}
83862306a36Sopenharmony_cistatic inline void mei_dbgfs_deregister(struct mei_device *dev) {}
83962306a36Sopenharmony_ci#endif /* CONFIG_DEBUG_FS */
84062306a36Sopenharmony_ci
84162306a36Sopenharmony_ciint mei_register(struct mei_device *dev, struct device *parent);
84262306a36Sopenharmony_civoid mei_deregister(struct mei_device *dev);
84362306a36Sopenharmony_ci
84462306a36Sopenharmony_ci#define MEI_HDR_FMT "hdr:host=%02d me=%02d len=%d dma=%1d ext=%1d internal=%1d comp=%1d"
84562306a36Sopenharmony_ci#define MEI_HDR_PRM(hdr)                  \
84662306a36Sopenharmony_ci	(hdr)->host_addr, (hdr)->me_addr, \
84762306a36Sopenharmony_ci	(hdr)->length, (hdr)->dma_ring, (hdr)->extended, \
84862306a36Sopenharmony_ci	(hdr)->internal, (hdr)->msg_complete
84962306a36Sopenharmony_ci
85062306a36Sopenharmony_cissize_t mei_fw_status2str(struct mei_fw_status *fw_sts, char *buf, size_t len);
85162306a36Sopenharmony_ci/**
85262306a36Sopenharmony_ci * mei_fw_status_str - fetch and convert fw status registers to printable string
85362306a36Sopenharmony_ci *
85462306a36Sopenharmony_ci * @dev: the device structure
85562306a36Sopenharmony_ci * @buf: string buffer at minimal size MEI_FW_STATUS_STR_SZ
85662306a36Sopenharmony_ci * @len: buffer len must be >= MEI_FW_STATUS_STR_SZ
85762306a36Sopenharmony_ci *
85862306a36Sopenharmony_ci * Return: number of bytes written or < 0 on failure
85962306a36Sopenharmony_ci */
86062306a36Sopenharmony_cistatic inline ssize_t mei_fw_status_str(struct mei_device *dev,
86162306a36Sopenharmony_ci					char *buf, size_t len)
86262306a36Sopenharmony_ci{
86362306a36Sopenharmony_ci	struct mei_fw_status fw_status;
86462306a36Sopenharmony_ci	int ret;
86562306a36Sopenharmony_ci
86662306a36Sopenharmony_ci	buf[0] = '\0';
86762306a36Sopenharmony_ci
86862306a36Sopenharmony_ci	ret = mei_fw_status(dev, &fw_status);
86962306a36Sopenharmony_ci	if (ret)
87062306a36Sopenharmony_ci		return ret;
87162306a36Sopenharmony_ci
87262306a36Sopenharmony_ci	ret = mei_fw_status2str(&fw_status, buf, MEI_FW_STATUS_STR_SZ);
87362306a36Sopenharmony_ci
87462306a36Sopenharmony_ci	return ret;
87562306a36Sopenharmony_ci}
87662306a36Sopenharmony_ci
87762306a36Sopenharmony_ci
87862306a36Sopenharmony_ci#endif
879