/* * Number of Maximum MEI Clients
*/ #define MEI_CLIENTS_MAX 256
/* * maximum number of consecutive resets
*/ #define MEI_MAX_CONSEC_RESET 3
/* * Number of File descriptors/handles * that can be opened to the driver. * * Limit to 255: 256 Total Clients * minus internal client for MEI Bus Messages
*/ #define MEI_MAX_OPEN_HANDLE_COUNT (MEI_CLIENTS_MAX - 1)
/* Maximum number of processed FW status registers */ #define MEI_FW_STATUS_MAX 6 /* Minimal buffer for FW status string (8 bytes in dw + space or '\0') */ #define MEI_FW_STATUS_STR_SZ (MEI_FW_STATUS_MAX * (8 + 1))
/* * struct mei_fw_status - storage of FW status data * * @count: number of actually available elements in array * @status: FW status registers
*/ struct mei_fw_status { int count;
u32 status[MEI_FW_STATUS_MAX];
};
/** * struct mei_me_client - representation of me (fw) client * * @list: link in me client list * @refcnt: struct reference count * @props: client properties * @client_id: me client id * @tx_flow_ctrl_creds: flow control credits * @connect_count: number connections to this client * @bus_added: added to bus
*/ struct mei_me_client { struct list_head list; struct kref refcnt; struct mei_client_properties props;
u8 client_id;
u8 tx_flow_ctrl_creds;
u8 connect_count;
u8 bus_added;
};
struct mei_cl;
/** * struct mei_cl_cb - file operation callback structure * * @list: link in callback queue * @cl: file client who is running this operation * @fop_type: file operation type * @buf: buffer for data associated with the callback * @buf_idx: last read index * @vtag: virtual tag * @fp: pointer to file structure * @status: io status of the cb * @internal: communication between driver and FW flag * @blocking: transmission blocking mode * @ext_hdr: extended header
*/ struct mei_cl_cb { struct list_head list; struct mei_cl *cl; enum mei_cb_file_ops fop_type; struct mei_msg_data buf;
size_t buf_idx;
u8 vtag; conststruct file *fp; int status;
u32 internal:1;
u32 blocking:1; struct mei_ext_hdr *ext_hdr;
};
/** * struct mei_cl_vtag - file pointer to vtag mapping structure * * @list: link in map queue * @fp: file pointer * @vtag: corresponding vtag * @pending_read: the read is pending on this file
*/ struct mei_cl_vtag { struct list_head list; conststruct file *fp;
u8 vtag;
u8 pending_read:1;
};
/** * struct mei_cl - me client host representation * carried in file->private_data * * @link: link in the clients list * @dev: mei parent device * @state: file operation state * @tx_wait: wait queue for tx completion * @rx_wait: wait queue for rx completion * @wait: wait queue for management operation * @ev_wait: notification wait queue * @ev_async: event async notification * @status: connection status * @me_cl: fw client connected * @fp: file associated with client * @host_client_id: host id * @vtag_map: vtag map * @tx_flow_ctrl_creds: transmit flow credentials * @rx_flow_ctrl_creds: receive flow credentials * @timer_count: watchdog timer for operation completion * @notify_en: notification - enabled/disabled * @notify_ev: pending notification event * @tx_cb_queued: number of tx callbacks in queue * @writing_state: state of the tx * @rd_pending: pending read credits * @rd_completed_lock: protects rd_completed queue * @rd_completed: completed read * @dma: dma settings * @dma_mapped: dma buffer is currently mapped. * * @cldev: device on the mei client bus
*/ struct mei_cl { struct list_head link; struct mei_device *dev; enum file_state state;
wait_queue_head_t tx_wait;
wait_queue_head_t rx_wait;
wait_queue_head_t wait;
wait_queue_head_t ev_wait; struct fasync_struct *ev_async; int status; struct mei_me_client *me_cl; conststruct file *fp;
u8 host_client_id; struct list_head vtag_map;
u8 tx_flow_ctrl_creds;
u8 rx_flow_ctrl_creds;
u8 timer_count;
u8 notify_en;
u8 notify_ev;
u8 tx_cb_queued; enum mei_file_transaction_states writing_state; struct list_head rd_pending;
spinlock_t rd_completed_lock; /* protects rd_completed queue */ struct list_head rd_completed; struct mei_dma_data dma;
u8 dma_mapped;
/** * enum mei_pg_event - power gating transition events * * @MEI_PG_EVENT_IDLE: the driver is not in power gating transition * @MEI_PG_EVENT_WAIT: the driver is waiting for a pg event to complete * @MEI_PG_EVENT_RECEIVED: the driver received pg event * @MEI_PG_EVENT_INTR_WAIT: the driver is waiting for a pg event interrupt * @MEI_PG_EVENT_INTR_RECEIVED: the driver received pg event interrupt
*/ enum mei_pg_event {
MEI_PG_EVENT_IDLE,
MEI_PG_EVENT_WAIT,
MEI_PG_EVENT_RECEIVED,
MEI_PG_EVENT_INTR_WAIT,
MEI_PG_EVENT_INTR_RECEIVED,
};
/** * enum mei_pg_state - device internal power gating state * * @MEI_PG_OFF: device is not power gated - it is active * @MEI_PG_ON: device is power gated - it is in lower power state
*/ enum mei_pg_state {
MEI_PG_OFF = 0,
MEI_PG_ON = 1,
};
/** * struct mei_fw_version - MEI FW version struct * * @platform: platform identifier * @major: major version field * @minor: minor version field * @buildno: build number version field * @hotfix: hotfix number version field
*/ struct mei_fw_version {
u8 platform;
u8 major;
u16 minor;
u16 buildno;
u16 hotfix;
};
#define MEI_MAX_FW_VER_BLOCKS 3
struct mei_dev_timeouts { unsignedlong hw_ready; /* Timeout on ready message, in jiffies */ int connect; /* HPS: at least 2 seconds, in seconds */ unsignedlong cl_connect; /* HPS: Client Connect Timeout, in jiffies */ int client_init; /* HPS: Clients Enumeration Timeout, in seconds */ unsignedlong pgi; /* PG Isolation time response, in jiffies */ unsignedint d0i3; /* D0i3 set/unset max response time, in jiffies */ unsignedlong hbm; /* HBM operation timeout, in jiffies */ unsignedlong mkhi_recv; /* receive timeout, in jiffies */
};
/** * struct mei_device - MEI private device struct * * @dev : device on a bus * @cdev : character device * @minor : minor number allocated for device * * @write_list : write pending list * @write_waiting_list : write completion list * @ctrl_wr_list : pending control write list * @ctrl_rd_list : pending control read list * @tx_queue_limit: tx queues per client linit * * @file_list : list of opened handles * @open_handle_count: number of opened handles * * @device_lock : big device lock * @timer_work : MEI timer delayed work (timeouts) * * @recvd_hw_ready : hw ready message received flag * * @wait_hw_ready : wait queue for receive HW ready message form FW * @wait_pg : wait queue for receive PG message from FW * @wait_hbm_start : wait queue for receive HBM start message from FW * * @reset_count : number of consecutive resets * @dev_state : device state * @hbm_state : state of host bus message protocol * @pxp_mode : PXP device mode * @init_clients_timer : HBM init handshake timeout * * @pg_event : power gating event * @pg_domain : runtime PM domain * * @rd_msg_buf : control messages buffer * @rd_msg_hdr : read message header storage * @rd_msg_hdr_count : how many dwords were already read from header * * @hbuf_is_ready : query if the host host/write buffer is ready * @dr_dscr: DMA ring descriptors: TX, RX, and CTRL * * @version : HBM protocol version in use * @hbm_f_pg_supported : hbm feature pgi protocol * @hbm_f_dc_supported : hbm feature dynamic clients * @hbm_f_dot_supported : hbm feature disconnect on timeout * @hbm_f_ev_supported : hbm feature event notification * @hbm_f_fa_supported : hbm feature fixed address client * @hbm_f_ie_supported : hbm feature immediate reply to enum request * @hbm_f_os_supported : hbm feature support OS ver message * @hbm_f_dr_supported : hbm feature dma ring supported * @hbm_f_vt_supported : hbm feature vtag supported * @hbm_f_cap_supported : hbm feature capabilities message supported * @hbm_f_cd_supported : hbm feature client dma supported * @hbm_f_gsc_supported : hbm feature gsc supported * * @fw_ver : FW versions * * @fw_f_fw_ver_supported : fw feature: fw version supported * @fw_ver_received : fw version received * * @me_clients_rwsem: rw lock over me_clients list * @me_clients : list of FW clients * @me_clients_map : FW clients bit map * @host_clients_map : host clients id pool * * @allow_fixed_address: allow user space to connect a fixed client * @override_fixed_address: force allow fixed address behavior * * @timeouts: actual timeout values * * @reset_work : work item for the device reset * @bus_rescan_work : work item for the bus rescan * * @device_list : mei client bus list * @cl_bus_lock : client bus list lock * * @kind : kind of mei device * * @dbgfs_dir : debugfs mei root directory * * @saved_fw_status : saved firmware status * @saved_dev_state : saved device state * @saved_fw_status_flag : flag indicating that firmware status was saved * @gsc_reset_to_pxp : state of reset to the PXP mode * * @ops: : hw specific operations * @hw : hw specific data
*/ struct mei_device { struct device *dev; struct cdev cdev; int minor;
/** * mei_data2slots - get slots number from a message length * * @length: size of the messages in bytes * * Return: number of slots
*/ staticinline u32 mei_data2slots(size_t length)
{ return DIV_ROUND_UP(length, MEI_SLOT_SIZE);
}
/** * mei_hbm2slots - get slots number from a hbm message length * length + size of the mei message header * * @length: size of the messages in bytes * * Return: number of slots
*/ staticinline u32 mei_hbm2slots(size_t length)
{ return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, MEI_SLOT_SIZE);
}
/** * mei_slots2data - get data in slots - bytes from slots * * @slots: number of available slots * * Return: number of bytes in slots
*/ staticinline u32 mei_slots2data(int slots)
{ return slots * MEI_SLOT_SIZE;
}
/* * mei init function prototypes
*/ void mei_device_init(struct mei_device *dev, struct device *device, bool slow_fw, conststruct mei_hw_ops *hw_ops); int mei_reset(struct mei_device *dev); int mei_start(struct mei_device *dev); int mei_restart(struct mei_device *dev); void mei_stop(struct mei_device *dev); void mei_cancel_work(struct mei_device *dev);
ssize_t mei_fw_status2str(struct mei_fw_status *fw_sts, char *buf, size_t len); /** * mei_fw_status_str - fetch and convert fw status registers to printable string * * @dev: the device structure * @buf: string buffer at minimal size MEI_FW_STATUS_STR_SZ * @len: buffer len must be >= MEI_FW_STATUS_STR_SZ * * Return: number of bytes written or < 0 on failure
*/ staticinline ssize_t mei_fw_status_str(struct mei_device *dev, char *buf, size_t len)
{ struct mei_fw_status fw_status; int ret;
buf[0] = '\0';
ret = mei_fw_status(dev, &fw_status); if (ret) return ret;
ret = mei_fw_status2str(&fw_status, buf, MEI_FW_STATUS_STR_SZ);
return ret;
}
/** * kind_is_gsc - checks whether the device is gsc * * @dev: the device structure * * Return: whether the device is gsc
*/ staticinlinebool kind_is_gsc(struct mei_device *dev)
{ /* check kind for NULL because it may be not set, like at the fist call to hw_start */ return dev->kind && (strcmp(dev->kind, "gsc") == 0);
}
/** * kind_is_gscfi - checks whether the device is gscfi * * @dev: the device structure * * Return: whether the device is gscfi
*/ staticinlinebool kind_is_gscfi(struct mei_device *dev)
{ /* check kind for NULL because it may be not set, like at the fist call to hw_start */ return dev->kind && (strcmp(dev->kind, "gscfi") == 0);
} #endif
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.