xref: /openbmc/linux/drivers/misc/mei/client.h (revision 237092bf)
190e0b5f1STomas Winkler /*
290e0b5f1STomas Winkler  *
390e0b5f1STomas Winkler  * Intel Management Engine Interface (Intel MEI) Linux driver
490e0b5f1STomas Winkler  * Copyright (c) 2003-2012, Intel Corporation.
590e0b5f1STomas Winkler  *
690e0b5f1STomas Winkler  * This program is free software; you can redistribute it and/or modify it
790e0b5f1STomas Winkler  * under the terms and conditions of the GNU General Public License,
890e0b5f1STomas Winkler  * version 2, as published by the Free Software Foundation.
990e0b5f1STomas Winkler  *
1090e0b5f1STomas Winkler  * This program is distributed in the hope it will be useful, but WITHOUT
1190e0b5f1STomas Winkler  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1290e0b5f1STomas Winkler  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
1390e0b5f1STomas Winkler  * more details.
1490e0b5f1STomas Winkler  *
1590e0b5f1STomas Winkler  */
1690e0b5f1STomas Winkler 
1790e0b5f1STomas Winkler #ifndef _MEI_CLIENT_H_
1890e0b5f1STomas Winkler #define _MEI_CLIENT_H_
1990e0b5f1STomas Winkler 
2090e0b5f1STomas Winkler #include <linux/types.h>
2190e0b5f1STomas Winkler #include <linux/watchdog.h>
2290e0b5f1STomas Winkler #include <linux/poll.h>
2390e0b5f1STomas Winkler #include <linux/mei.h>
2490e0b5f1STomas Winkler 
2590e0b5f1STomas Winkler #include "mei_dev.h"
2690e0b5f1STomas Winkler 
2779563db9STomas Winkler /*
2879563db9STomas Winkler  * reference counting base function
2979563db9STomas Winkler  */
3079563db9STomas Winkler void mei_me_cl_init(struct mei_me_client *me_cl);
3179563db9STomas Winkler void mei_me_cl_put(struct mei_me_client *me_cl);
3279563db9STomas Winkler struct mei_me_client *mei_me_cl_get(struct mei_me_client *me_cl);
33d880f329STomas Winkler 
34b7d88514STomas Winkler void mei_me_cl_add(struct mei_device *dev, struct mei_me_client *me_cl);
35b7d88514STomas Winkler void mei_me_cl_del(struct mei_device *dev, struct mei_me_client *me_cl);
36b7d88514STomas Winkler 
37b7d88514STomas Winkler struct mei_me_client *mei_me_cl_by_uuid(struct mei_device *dev,
3879563db9STomas Winkler 					const uuid_le *uuid);
3979563db9STomas Winkler struct mei_me_client *mei_me_cl_by_id(struct mei_device *dev, u8 client_id);
40d880f329STomas Winkler struct mei_me_client *mei_me_cl_by_uuid_id(struct mei_device *dev,
41d880f329STomas Winkler 					   const uuid_le *uuid, u8 client_id);
4279563db9STomas Winkler void mei_me_cl_rm_by_uuid(struct mei_device *dev, const uuid_le *uuid);
4379563db9STomas Winkler void mei_me_cl_rm_by_uuid_id(struct mei_device *dev,
4479563db9STomas Winkler 			     const uuid_le *uuid, u8 id);
4579563db9STomas Winkler void mei_me_cl_rm_all(struct mei_device *dev);
4690e0b5f1STomas Winkler 
47d49ed64aSAlexander Usyskin /**
48d49ed64aSAlexander Usyskin  * mei_me_cl_is_active - check whether me client is active in the fw
49d49ed64aSAlexander Usyskin  *
50d49ed64aSAlexander Usyskin  * @me_cl: me client
51d49ed64aSAlexander Usyskin  *
52d49ed64aSAlexander Usyskin  * Return: true if the me client is active in the firmware
53d49ed64aSAlexander Usyskin  */
54d49ed64aSAlexander Usyskin static inline bool mei_me_cl_is_active(const struct mei_me_client *me_cl)
55d49ed64aSAlexander Usyskin {
56d49ed64aSAlexander Usyskin 	return !list_empty_careful(&me_cl->list);
57d49ed64aSAlexander Usyskin }
58d49ed64aSAlexander Usyskin 
59d49ed64aSAlexander Usyskin /**
60d49ed64aSAlexander Usyskin  * mei_me_cl_uuid - return me client protocol name (uuid)
61d49ed64aSAlexander Usyskin  *
62d49ed64aSAlexander Usyskin  * @me_cl: me client
63d49ed64aSAlexander Usyskin  *
64d49ed64aSAlexander Usyskin  * Return: me client protocol name
65d49ed64aSAlexander Usyskin  */
66d49ed64aSAlexander Usyskin static inline const uuid_le *mei_me_cl_uuid(const struct mei_me_client *me_cl)
67d49ed64aSAlexander Usyskin {
68d49ed64aSAlexander Usyskin 	return &me_cl->props.protocol_name;
69d49ed64aSAlexander Usyskin }
70d49ed64aSAlexander Usyskin 
7190e0b5f1STomas Winkler /*
7290e0b5f1STomas Winkler  * MEI IO Functions
7390e0b5f1STomas Winkler  */
74bca67d68STomas Winkler struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, enum mei_cb_file_ops type,
75bca67d68STomas Winkler 				 struct file *fp);
7690e0b5f1STomas Winkler void mei_io_cb_free(struct mei_cl_cb *priv_cb);
775db7514dSTomas Winkler int mei_io_cb_alloc_buf(struct mei_cl_cb *cb, size_t length);
7890e0b5f1STomas Winkler 
7990e0b5f1STomas Winkler 
8090e0b5f1STomas Winkler /**
8190e0b5f1STomas Winkler  * mei_io_list_init - Sets up a queue list.
8290e0b5f1STomas Winkler  *
8390e0b5f1STomas Winkler  * @list: An instance cl callback structure
8490e0b5f1STomas Winkler  */
8590e0b5f1STomas Winkler static inline void mei_io_list_init(struct mei_cl_cb *list)
8690e0b5f1STomas Winkler {
8790e0b5f1STomas Winkler 	INIT_LIST_HEAD(&list->list);
8890e0b5f1STomas Winkler }
895456796bSAlexander Usyskin void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl);
905456796bSAlexander Usyskin 
9190e0b5f1STomas Winkler /*
9290e0b5f1STomas Winkler  * MEI Host Client Functions
9390e0b5f1STomas Winkler  */
9490e0b5f1STomas Winkler 
9590e0b5f1STomas Winkler struct mei_cl *mei_cl_allocate(struct mei_device *dev);
9690e0b5f1STomas Winkler void mei_cl_init(struct mei_cl *cl, struct mei_device *dev);
9790e0b5f1STomas Winkler 
9890e0b5f1STomas Winkler 
99781d0d89STomas Winkler int mei_cl_link(struct mei_cl *cl, int id);
10090e0b5f1STomas Winkler int mei_cl_unlink(struct mei_cl *cl);
10190e0b5f1STomas Winkler 
10203b8d341STomas Winkler struct mei_cl *mei_cl_alloc_linked(struct mei_device *dev, int id);
10303b8d341STomas Winkler 
104a9bed610STomas Winkler struct mei_cl_cb *mei_cl_read_cb(const struct mei_cl *cl,
105a9bed610STomas Winkler 				 const struct file *fp);
106a9bed610STomas Winkler void mei_cl_read_cb_flush(const struct mei_cl *cl, const struct file *fp);
107bca67d68STomas Winkler struct mei_cl_cb *mei_cl_alloc_cb(struct mei_cl *cl, size_t length,
108bca67d68STomas Winkler 				  enum mei_cb_file_ops type, struct file *fp);
109a9bed610STomas Winkler int mei_cl_flush_queues(struct mei_cl *cl, const struct file *fp);
11090e0b5f1STomas Winkler 
11190e0b5f1STomas Winkler int mei_cl_flow_ctrl_creds(struct mei_cl *cl);
11290e0b5f1STomas Winkler 
11390e0b5f1STomas Winkler int mei_cl_flow_ctrl_reduce(struct mei_cl *cl);
11490e0b5f1STomas Winkler /*
11590e0b5f1STomas Winkler  *  MEI input output function prototype
11690e0b5f1STomas Winkler  */
1176a84d63dSTomas Winkler 
1186a84d63dSTomas Winkler /**
1196a84d63dSTomas Winkler  * mei_cl_is_connected - host client is connected
1206a84d63dSTomas Winkler  *
121d49ed64aSAlexander Usyskin  * @cl: host client
1226a84d63dSTomas Winkler  *
123d49ed64aSAlexander Usyskin  * Return: true if the host client is connected
1246a84d63dSTomas Winkler  */
125b950ac1dSTomas Winkler static inline bool mei_cl_is_connected(struct mei_cl *cl)
126b950ac1dSTomas Winkler {
127ab3ae009STomas Winkler 	return  cl->state == MEI_FILE_CONNECTED;
128b950ac1dSTomas Winkler }
129b950ac1dSTomas Winkler 
130d49ed64aSAlexander Usyskin /**
131d49ed64aSAlexander Usyskin  * mei_cl_me_id - me client id
132d49ed64aSAlexander Usyskin  *
133d49ed64aSAlexander Usyskin  * @cl: host client
134d49ed64aSAlexander Usyskin  *
135d49ed64aSAlexander Usyskin  * Return: me client id or 0 if client is not connected
136d49ed64aSAlexander Usyskin  */
137d49ed64aSAlexander Usyskin static inline u8 mei_cl_me_id(const struct mei_cl *cl)
138d49ed64aSAlexander Usyskin {
139d49ed64aSAlexander Usyskin 	return cl->me_cl ? cl->me_cl->client_id : 0;
140d49ed64aSAlexander Usyskin }
141d49ed64aSAlexander Usyskin 
142d49ed64aSAlexander Usyskin /**
143d49ed64aSAlexander Usyskin  * mei_cl_mtu - maximal message that client can send and receive
144d49ed64aSAlexander Usyskin  *
145d49ed64aSAlexander Usyskin  * @cl: host client
146d49ed64aSAlexander Usyskin  *
147d49ed64aSAlexander Usyskin  * Return: mtu
148d49ed64aSAlexander Usyskin  */
149d49ed64aSAlexander Usyskin static inline size_t mei_cl_mtu(const struct mei_cl *cl)
150d49ed64aSAlexander Usyskin {
151d49ed64aSAlexander Usyskin 	return cl->me_cl->props.max_msg_length;
152d49ed64aSAlexander Usyskin }
153d49ed64aSAlexander Usyskin 
154d49ed64aSAlexander Usyskin /**
155d49ed64aSAlexander Usyskin  * mei_cl_is_fixed_address - check whether the me client uses fixed address
156d49ed64aSAlexander Usyskin  *
157d49ed64aSAlexander Usyskin  * @cl: host client
158d49ed64aSAlexander Usyskin  *
159d49ed64aSAlexander Usyskin  * Return: true if the client is connected and it has fixed me address
160d49ed64aSAlexander Usyskin  */
161d49ed64aSAlexander Usyskin static inline bool mei_cl_is_fixed_address(const struct mei_cl *cl)
162d49ed64aSAlexander Usyskin {
163d49ed64aSAlexander Usyskin 	return cl->me_cl && cl->me_cl->props.fixed_address;
164d49ed64aSAlexander Usyskin }
165d49ed64aSAlexander Usyskin 
166d49ed64aSAlexander Usyskin /**
167d49ed64aSAlexander Usyskin  * mei_cl_is_single_recv_buf- check whether the me client
168d49ed64aSAlexander Usyskin  *       uses single receiving buffer
169d49ed64aSAlexander Usyskin  *
170d49ed64aSAlexander Usyskin  * @cl: host client
171d49ed64aSAlexander Usyskin  *
172d49ed64aSAlexander Usyskin  * Return: true if single_recv_buf == 1; 0 otherwise
173d49ed64aSAlexander Usyskin  */
174d49ed64aSAlexander Usyskin static inline bool mei_cl_is_single_recv_buf(const struct mei_cl *cl)
175d49ed64aSAlexander Usyskin {
176d49ed64aSAlexander Usyskin 	return cl->me_cl->props.single_recv_buf;
177d49ed64aSAlexander Usyskin }
178d49ed64aSAlexander Usyskin 
179d49ed64aSAlexander Usyskin /**
180d49ed64aSAlexander Usyskin  * mei_cl_uuid -  client's uuid
181d49ed64aSAlexander Usyskin  *
182d49ed64aSAlexander Usyskin  * @cl: host client
183d49ed64aSAlexander Usyskin  *
184d49ed64aSAlexander Usyskin  * Return: return uuid of connected me client
185d49ed64aSAlexander Usyskin  */
186d49ed64aSAlexander Usyskin static inline const uuid_le *mei_cl_uuid(const struct mei_cl *cl)
187d49ed64aSAlexander Usyskin {
188d49ed64aSAlexander Usyskin 	return mei_me_cl_uuid(cl->me_cl);
189d49ed64aSAlexander Usyskin }
190d49ed64aSAlexander Usyskin 
1911df629efSAlexander Usyskin /**
1921df629efSAlexander Usyskin  * mei_cl_host_addr - client's host address
1931df629efSAlexander Usyskin  *
1941df629efSAlexander Usyskin  * @cl: host client
1951df629efSAlexander Usyskin  *
1961df629efSAlexander Usyskin  * Return: 0 for fixed address client, host address for dynamic client
1971df629efSAlexander Usyskin  */
1981df629efSAlexander Usyskin static inline u8 mei_cl_host_addr(const struct mei_cl *cl)
1991df629efSAlexander Usyskin {
2001df629efSAlexander Usyskin 	return  mei_cl_is_fixed_address(cl) ? 0 : cl->host_client_id;
2011df629efSAlexander Usyskin }
2021df629efSAlexander Usyskin 
20390e0b5f1STomas Winkler int mei_cl_disconnect(struct mei_cl *cl);
2043c666182STomas Winkler void mei_cl_set_disconnected(struct mei_cl *cl);
2053c666182STomas Winkler int mei_cl_irq_disconnect(struct mei_cl *cl, struct mei_cl_cb *cb,
2063c666182STomas Winkler 			  struct mei_cl_cb *cmpl_list);
207d49ed64aSAlexander Usyskin int mei_cl_connect(struct mei_cl *cl, struct mei_me_client *me_cl,
208d49ed64aSAlexander Usyskin 		   struct file *file);
2090c53357cSTomas Winkler int mei_cl_irq_connect(struct mei_cl *cl, struct mei_cl_cb *cb,
2100c53357cSTomas Winkler 			      struct mei_cl_cb *cmpl_list);
211bca67d68STomas Winkler int mei_cl_read_start(struct mei_cl *cl, size_t length, struct file *fp);
212331e4187STomas Winkler int mei_cl_irq_read_msg(struct mei_cl *cl, struct mei_msg_hdr *hdr,
213331e4187STomas Winkler 			struct mei_cl_cb *cmpl_list);
2144234a6deSTomas Winkler int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking);
2159d098192STomas Winkler int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
2169d098192STomas Winkler 		     struct mei_cl_cb *cmpl_list);
21721767546STomas Winkler 
218db086fa9STomas Winkler void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb);
21990e0b5f1STomas Winkler 
22090e0b5f1STomas Winkler void mei_host_client_init(struct work_struct *work);
22190e0b5f1STomas Winkler 
22251678ccbSTomas Winkler u8 mei_cl_notify_fop2req(enum mei_cb_file_ops fop);
22351678ccbSTomas Winkler enum mei_cb_file_ops mei_cl_notify_req2fop(u8 request);
22451678ccbSTomas Winkler int mei_cl_notify_request(struct mei_cl *cl, struct file *file, u8 request);
22551678ccbSTomas Winkler int mei_cl_irq_notify(struct mei_cl *cl, struct mei_cl_cb *cb,
22651678ccbSTomas Winkler 		      struct mei_cl_cb *cmpl_list);
227b38a362fSTomas Winkler int mei_cl_notify_get(struct mei_cl *cl, bool block, bool *notify_ev);
228237092bfSTomas Winkler void mei_cl_notify(struct mei_cl *cl);
22951678ccbSTomas Winkler 
230074b4c01STomas Winkler void mei_cl_all_disconnect(struct mei_device *dev);
2315290801cSTomas Winkler void mei_cl_all_wakeup(struct mei_device *dev);
232074b4c01STomas Winkler void mei_cl_all_write_clear(struct mei_device *dev);
233074b4c01STomas Winkler 
234c0abffbdSAlexander Usyskin #define MEI_CL_FMT "cl:host=%02d me=%02d "
235d49ed64aSAlexander Usyskin #define MEI_CL_PRM(cl) (cl)->host_client_id, mei_cl_me_id(cl)
236c0abffbdSAlexander Usyskin 
237c0abffbdSAlexander Usyskin #define cl_dbg(dev, cl, format, arg...) \
2382bf94cabSTomas Winkler 	dev_dbg((dev)->dev, MEI_CL_FMT format, MEI_CL_PRM(cl), ##arg)
239c0abffbdSAlexander Usyskin 
240c0abffbdSAlexander Usyskin #define cl_err(dev, cl, format, arg...) \
2412bf94cabSTomas Winkler 	dev_err((dev)->dev, MEI_CL_FMT format, MEI_CL_PRM(cl), ##arg)
242c0abffbdSAlexander Usyskin 
24390e0b5f1STomas Winkler #endif /* _MEI_CLIENT_H_ */
244