About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog

Documentation / nfc / nfc-hci.txt




Custom Search

Based on kernel version 3.13. Page generated on 2014-01-20 22:04 EST.

1	HCI backend for NFC Core
2	
3	Author: Eric Lapuyade, Samuel Ortiz
4	Contact: eric.lapuyade@intel.com, samuel.ortiz@intel.com
5	
6	General
7	-------
8	
9	The HCI layer implements much of the ETSI TS 102 622 V10.2.0 specification. It
10	enables easy writing of HCI-based NFC drivers. The HCI layer runs as an NFC Core
11	backend, implementing an abstract nfc device and translating NFC Core API
12	to HCI commands and events.
13	
14	HCI
15	---
16	
17	HCI registers as an nfc device with NFC Core. Requests coming from userspace are
18	routed through netlink sockets to NFC Core and then to HCI. From this point,
19	they are translated in a sequence of HCI commands sent to the HCI layer in the
20	host controller (the chip). Commands can be executed synchronously (the sending
21	context blocks waiting for response) or asynchronously (the response is returned
22	from HCI Rx context).
23	HCI events can also be received from the host controller. They will be handled
24	and a translation will be forwarded to NFC Core as needed. There are hooks to
25	let the HCI driver handle proprietary events or override standard behavior.
26	HCI uses 2 execution contexts:
27	- one for executing commands : nfc_hci_msg_tx_work(). Only one command
28	can be executing at any given moment.
29	- one for dispatching received events and commands : nfc_hci_msg_rx_work().
30	
31	HCI Session initialization:
32	---------------------------
33	
34	The Session initialization is an HCI standard which must unfortunately
35	support proprietary gates. This is the reason why the driver will pass a list
36	of proprietary gates that must be part of the session. HCI will ensure all
37	those gates have pipes connected when the hci device is set up.
38	In case the chip supports pre-opened gates and pseudo-static pipes, the driver
39	can pass that information to HCI core.
40	
41	HCI Gates and Pipes
42	-------------------
43	
44	A gate defines the 'port' where some service can be found. In order to access
45	a service, one must create a pipe to that gate and open it. In this
46	implementation, pipes are totally hidden. The public API only knows gates.
47	This is consistent with the driver need to send commands to proprietary gates
48	without knowing the pipe connected to it.
49	
50	Driver interface
51	----------------
52	
53	A driver is generally written in two parts : the physical link management and
54	the HCI management. This makes it easier to maintain a driver for a chip that
55	can be connected using various phy (i2c, spi, ...)
56	
57	HCI Management
58	--------------
59	
60	A driver would normally register itself with HCI and provide the following
61	entry points:
62	
63	struct nfc_hci_ops {
64		int (*open)(struct nfc_hci_dev *hdev);
65		void (*close)(struct nfc_hci_dev *hdev);
66		int (*hci_ready) (struct nfc_hci_dev *hdev);
67		int (*xmit) (struct nfc_hci_dev *hdev, struct sk_buff *skb);
68		int (*start_poll) (struct nfc_hci_dev *hdev,
69				   u32 im_protocols, u32 tm_protocols);
70		int (*dep_link_up)(struct nfc_hci_dev *hdev, struct nfc_target *target,
71				   u8 comm_mode, u8 *gb, size_t gb_len);
72		int (*dep_link_down)(struct nfc_hci_dev *hdev);
73		int (*target_from_gate) (struct nfc_hci_dev *hdev, u8 gate,
74					 struct nfc_target *target);
75		int (*complete_target_discovered) (struct nfc_hci_dev *hdev, u8 gate,
76						   struct nfc_target *target);
77		int (*im_transceive) (struct nfc_hci_dev *hdev,
78				      struct nfc_target *target, struct sk_buff *skb,
79				      data_exchange_cb_t cb, void *cb_context);
80		int (*tm_send)(struct nfc_hci_dev *hdev, struct sk_buff *skb);
81		int (*check_presence)(struct nfc_hci_dev *hdev,
82				      struct nfc_target *target);
83		int (*event_received)(struct nfc_hci_dev *hdev, u8 gate, u8 event,
84				      struct sk_buff *skb);
85	};
86	
87	- open() and close() shall turn the hardware on and off.
88	- hci_ready() is an optional entry point that is called right after the hci
89	session has been set up. The driver can use it to do additional initialization
90	that must be performed using HCI commands.
91	- xmit() shall simply write a frame to the physical link.
92	- start_poll() is an optional entrypoint that shall set the hardware in polling
93	mode. This must be implemented only if the hardware uses proprietary gates or a
94	mechanism slightly different from the HCI standard.
95	- dep_link_up() is called after a p2p target has been detected, to finish
96	the p2p connection setup with hardware parameters that need to be passed back
97	to nfc core.
98	- dep_link_down() is called to bring the p2p link down.
99	- target_from_gate() is an optional entrypoint to return the nfc protocols
100	corresponding to a proprietary gate.
101	- complete_target_discovered() is an optional entry point to let the driver
102	perform additional proprietary processing necessary to auto activate the
103	discovered target.
104	- im_transceive() must be implemented by the driver if proprietary HCI commands
105	are required to send data to the tag. Some tag types will require custom
106	commands, others can be written to using the standard HCI commands. The driver
107	can check the tag type and either do proprietary processing, or return 1 to ask
108	for standard processing. The data exchange command itself must be sent
109	asynchronously.
110	- tm_send() is called to send data in the case of a p2p connection
111	- check_presence() is an optional entry point that will be called regularly
112	by the core to check that an activated tag is still in the field. If this is
113	not implemented, the core will not be able to push tag_lost events to the user
114	space
115	- event_received() is called to handle an event coming from the chip. Driver
116	can handle the event or return 1 to let HCI attempt standard processing.
117	
118	On the rx path, the driver is responsible to push incoming HCP frames to HCI
119	using nfc_hci_recv_frame(). HCI will take care of re-aggregation and handling
120	This must be done from a context that can sleep.
121	
122	PHY Management
123	--------------
124	
125	The physical link (i2c, ...) management is defined by the following struture:
126	
127	struct nfc_phy_ops {
128		int (*write)(void *dev_id, struct sk_buff *skb);
129		int (*enable)(void *dev_id);
130		void (*disable)(void *dev_id);
131	};
132	
133	enable(): turn the phy on (power on), make it ready to transfer data
134	disable(): turn the phy off
135	write(): Send a data frame to the chip. Note that to enable higher
136	layers such as an llc to store the frame for re-emission, this function must
137	not alter the skb. It must also not return a positive result (return 0 for
138	success, negative for failure).
139	
140	Data coming from the chip shall be sent directly to nfc_hci_recv_frame().
141	
142	LLC
143	---
144	
145	Communication between the CPU and the chip often requires some link layer
146	protocol. Those are isolated as modules managed by the HCI layer. There are
147	currently two modules : nop (raw transfert) and shdlc.
148	A new llc must implement the following functions:
149	
150	struct nfc_llc_ops {
151		void *(*init) (struct nfc_hci_dev *hdev, xmit_to_drv_t xmit_to_drv,
152			       rcv_to_hci_t rcv_to_hci, int tx_headroom,
153			       int tx_tailroom, int *rx_headroom, int *rx_tailroom,
154			       llc_failure_t llc_failure);
155		void (*deinit) (struct nfc_llc *llc);
156		int (*start) (struct nfc_llc *llc);
157		int (*stop) (struct nfc_llc *llc);
158		void (*rcv_from_drv) (struct nfc_llc *llc, struct sk_buff *skb);
159		int (*xmit_from_hci) (struct nfc_llc *llc, struct sk_buff *skb);
160	};
161	
162	- init() : allocate and init your private storage
163	- deinit() : cleanup
164	- start() : establish the logical connection
165	- stop () : terminate the logical connection
166	- rcv_from_drv() : handle data coming from the chip, going to HCI
167	- xmit_from_hci() : handle data sent by HCI, going to the chip
168	
169	The llc must be registered with nfc before it can be used. Do that by
170	calling nfc_llc_register(const char *name, struct nfc_llc_ops *ops);
171	
172	Again, note that the llc does not handle the physical link. It is thus very
173	easy to mix any physical link with any llc for a given chip driver.
174	
175	Included Drivers
176	----------------
177	
178	An HCI based driver for an NXP PN544, connected through I2C bus, and using
179	shdlc is included.
180	
181	Execution Contexts
182	------------------
183	
184	The execution contexts are the following:
185	- IRQ handler (IRQH):
186	fast, cannot sleep. sends incoming frames to HCI where they are passed to
187	the current llc. In case of shdlc, the frame is queued in shdlc rx queue.
188	
189	- SHDLC State Machine worker (SMW)
190	Only when llc_shdlc is used: handles shdlc rx & tx queues.
191	Dispatches HCI cmd responses.
192	
193	- HCI Tx Cmd worker (MSGTXWQ)
194	Serializes execution of HCI commands. Completes execution in case of response
195	timeout.
196	
197	- HCI Rx worker (MSGRXWQ)
198	Dispatches incoming HCI commands or events.
199	
200	- Syscall context from a userspace call (SYSCALL)
201	Any entrypoint in HCI called from NFC Core
202	
203	Workflow executing an HCI command (using shdlc)
204	-----------------------------------------------
205	
206	Executing an HCI command can easily be performed synchronously using the
207	following API:
208	
209	int nfc_hci_send_cmd (struct nfc_hci_dev *hdev, u8 gate, u8 cmd,
210				const u8 *param, size_t param_len, struct sk_buff **skb)
211	
212	The API must be invoked from a context that can sleep. Most of the time, this
213	will be the syscall context. skb will return the result that was received in
214	the response.
215	
216	Internally, execution is asynchronous. So all this API does is to enqueue the
217	HCI command, setup a local wait queue on stack, and wait_event() for completion.
218	The wait is not interruptible because it is guaranteed that the command will
219	complete after some short timeout anyway.
220	
221	MSGTXWQ context will then be scheduled and invoke nfc_hci_msg_tx_work().
222	This function will dequeue the next pending command and send its HCP fragments
223	to the lower layer which happens to be shdlc. It will then start a timer to be
224	able to complete the command with a timeout error if no response arrive.
225	
226	SMW context gets scheduled and invokes nfc_shdlc_sm_work(). This function
227	handles shdlc framing in and out. It uses the driver xmit to send frames and
228	receives incoming frames in an skb queue filled from the driver IRQ handler.
229	SHDLC I(nformation) frames payload are HCP fragments. They are aggregated to
230	form complete HCI frames, which can be a response, command, or event.
231	
232	HCI Responses are dispatched immediately from this context to unblock
233	waiting command execution. Response processing involves invoking the completion
234	callback that was provided by nfc_hci_msg_tx_work() when it sent the command.
235	The completion callback will then wake the syscall context.
236	
237	It is also possible to execute the command asynchronously using this API:
238	
239	static int nfc_hci_execute_cmd_async(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd,
240				       const u8 *param, size_t param_len,
241				       data_exchange_cb_t cb, void *cb_context)
242	
243	The workflow is the same, except that the API call returns immediately, and
244	the callback will be called with the result from the SMW context.
245	
246	Workflow receiving an HCI event or command
247	------------------------------------------
248	
249	HCI commands or events are not dispatched from SMW context. Instead, they are
250	queued to HCI rx_queue and will be dispatched from HCI rx worker
251	context (MSGRXWQ). This is done this way to allow a cmd or event handler
252	to also execute other commands (for example, handling the
253	NFC_HCI_EVT_TARGET_DISCOVERED event from PN544 requires to issue an
254	ANY_GET_PARAMETER to the reader A gate to get information on the target
255	that was discovered).
256	
257	Typically, such an event will be propagated to NFC Core from MSGRXWQ context.
258	
259	Error management
260	----------------
261	
262	Errors that occur synchronously with the execution of an NFC Core request are
263	simply returned as the execution result of the request. These are easy.
264	
265	Errors that occur asynchronously (e.g. in a background protocol handling thread)
266	must be reported such that upper layers don't stay ignorant that something
267	went wrong below and know that expected events will probably never happen.
268	Handling of these errors is done as follows:
269	
270	- driver (pn544) fails to deliver an incoming frame: it stores the error such
271	that any subsequent call to the driver will result in this error. Then it calls
272	the standard nfc_shdlc_recv_frame() with a NULL argument to report the problem
273	above. shdlc stores a EREMOTEIO sticky status, which will trigger SMW to
274	report above in turn.
275	
276	- SMW is basically a background thread to handle incoming and outgoing shdlc
277	frames. This thread will also check the shdlc sticky status and report to HCI
278	when it discovers it is not able to run anymore because of an unrecoverable
279	error that happened within shdlc or below. If the problem occurs during shdlc
280	connection, the error is reported through the connect completion.
281	
282	- HCI: if an internal HCI error happens (frame is lost), or HCI is reported an
283	error from a lower layer, HCI will either complete the currently executing
284	command with that error, or notify NFC Core directly if no command is executing.
285	
286	- NFC Core: when NFC Core is notified of an error from below and polling is
287	active, it will send a tag discovered event with an empty tag list to the user
288	space to let it know that the poll operation will never be able to detect a tag.
289	If polling is not active and the error was sticky, lower levels will return it
290	at next invocation.
Hide Line Numbers
About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog

Information is copyright its respective author. All material is available from the Linux Kernel Source distributed under a GPL License. This page is provided as a free service by mjmwired.net.