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