blob: 89a339c9b079160429bb43f133049e83ebfe7f4d [file] [log] [blame]
Eric Lapuyade0efbf7f2012-04-10 19:43:08 +02001HCI backend for NFC Core
2
3Author: Eric Lapuyade, Samuel Ortiz
4Contact: eric.lapuyade@intel.com, samuel.ortiz@intel.com
5
6General
7-------
8
9The HCI layer implements much of the ETSI TS 102 622 V10.2.0 specification. It
10enables easy writing of HCI-based NFC drivers. The HCI layer runs as an NFC Core
11backend, implementing an abstract nfc device and translating NFC Core API
12to HCI commands and events.
13
14HCI
15---
16
17HCI registers as an nfc device with NFC Core. Requests coming from userspace are
18routed through netlink sockets to NFC Core and then to HCI. From this point,
19they are translated in a sequence of HCI commands sent to the HCI layer in the
20host controller (the chip). The sending context blocks while waiting for the
21response to arrive.
22HCI events can also be received from the host controller. They will be handled
23and a translation will be forwarded to NFC Core as needed.
24HCI uses 2 execution contexts:
Eric Lapuyadea202abb2012-05-07 12:31:17 +020025- one for executing commands : nfc_hci_msg_tx_work(). Only one command
Eric Lapuyade0efbf7f2012-04-10 19:43:08 +020026can be executing at any given moment.
Eric Lapuyadea202abb2012-05-07 12:31:17 +020027- one for dispatching received events and commands : nfc_hci_msg_rx_work().
Eric Lapuyade0efbf7f2012-04-10 19:43:08 +020028
29HCI Session initialization:
30---------------------------
31
32The Session initialization is an HCI standard which must unfortunately
33support proprietary gates. This is the reason why the driver will pass a list
34of proprietary gates that must be part of the session. HCI will ensure all
35those gates have pipes connected when the hci device is set up.
36
37HCI Gates and Pipes
38-------------------
39
40A gate defines the 'port' where some service can be found. In order to access
41a service, one must create a pipe to that gate and open it. In this
42implementation, pipes are totally hidden. The public API only knows gates.
43This is consistent with the driver need to send commands to proprietary gates
44without knowing the pipe connected to it.
45
46Driver interface
47----------------
48
49A driver would normally register itself with HCI and provide the following
50entry points:
51
52struct nfc_hci_ops {
53 int (*open)(struct nfc_hci_dev *hdev);
54 void (*close)(struct nfc_hci_dev *hdev);
Eric Lapuyadea202abb2012-05-07 12:31:17 +020055 int (*hci_ready) (struct nfc_hci_dev *hdev);
Eric Lapuyade0efbf7f2012-04-10 19:43:08 +020056 int (*xmit)(struct nfc_hci_dev *hdev, struct sk_buff *skb);
57 int (*start_poll)(struct nfc_hci_dev *hdev, u32 protocols);
58 int (*target_from_gate)(struct nfc_hci_dev *hdev, u8 gate,
59 struct nfc_target *target);
Eric Lapuyadea202abb2012-05-07 12:31:17 +020060 int (*complete_target_discovered) (struct nfc_hci_dev *hdev, u8 gate,
61 struct nfc_target *target);
62 int (*data_exchange) (struct nfc_hci_dev *hdev,
63 struct nfc_target *target,
64 struct sk_buff *skb, struct sk_buff **res_skb);
65 int (*check_presence)(struct nfc_hci_dev *hdev,
66 struct nfc_target *target);
Eric Lapuyade0efbf7f2012-04-10 19:43:08 +020067};
68
Eric Lapuyadea202abb2012-05-07 12:31:17 +020069- open() and close() shall turn the hardware on and off.
70- hci_ready() is an optional entry point that is called right after the hci
71session has been set up. The driver can use it to do additional initialization
72that must be performed using HCI commands.
73- xmit() shall simply write a frame to the chip.
74- start_poll() is an optional entrypoint that shall set the hardware in polling
75mode. This must be implemented only if the hardware uses proprietary gates or a
76mechanism slightly different from the HCI standard.
77- target_from_gate() is an optional entrypoint to return the nfc protocols
Eric Lapuyade0efbf7f2012-04-10 19:43:08 +020078corresponding to a proprietary gate.
Eric Lapuyadea202abb2012-05-07 12:31:17 +020079- complete_target_discovered() is an optional entry point to let the driver
80perform additional proprietary processing necessary to auto activate the
81discovered target.
82- data_exchange() must be implemented by the driver if proprietary HCI commands
83are required to send data to the tag. Some tag types will require custom
84commands, others can be written to using the standard HCI commands. The driver
85can check the tag type and either do proprietary processing, or return 1 to ask
86for standard processing.
87- check_presence() is an optional entry point that will be called regularly
88by the core to check that an activated tag is still in the field. If this is
89not implemented, the core will not be able to push tag_lost events to the user
90space
Eric Lapuyade0efbf7f2012-04-10 19:43:08 +020091
92On the rx path, the driver is responsible to push incoming HCP frames to HCI
93using nfc_hci_recv_frame(). HCI will take care of re-aggregation and handling
94This must be done from a context that can sleep.
95
96SHDLC
97-----
98
99Most chips use shdlc to ensure integrity and delivery ordering of the HCP
100frames between the host controller (the chip) and hosts (entities connected
101to the chip, like the cpu). In order to simplify writing the driver, an shdlc
102layer is available for use by the driver.
103When used, the driver actually registers with shdlc, and shdlc will register
104with HCI. HCI sees shdlc as the driver and thus send its HCP frames
105through shdlc->xmit.
106SHDLC adds a new execution context (nfc_shdlc_sm_work()) to run its state
107machine and handle both its rx and tx path.
108
109Included Drivers
110----------------
111
112An HCI based driver for an NXP PN544, connected through I2C bus, and using
113shdlc is included.
114
115Execution Contexts
116------------------
117
118The execution contexts are the following:
119- IRQ handler (IRQH):
120fast, cannot sleep. stores incoming frames into an shdlc rx queue
121
122- SHDLC State Machine worker (SMW)
123handles shdlc rx & tx queues. Dispatches HCI cmd responses.
124
125- HCI Tx Cmd worker (MSGTXWQ)
Eric Lapuyadea202abb2012-05-07 12:31:17 +0200126Serializes execution of HCI commands. Completes execution in case of response
127timeout.
Eric Lapuyade0efbf7f2012-04-10 19:43:08 +0200128
129- HCI Rx worker (MSGRXWQ)
130Dispatches incoming HCI commands or events.
131
132- Syscall context from a userspace call (SYSCALL)
133Any entrypoint in HCI called from NFC Core
134
135Workflow executing an HCI command (using shdlc)
136-----------------------------------------------
137
138Executing an HCI command can easily be performed synchronously using the
139following API:
140
141int nfc_hci_send_cmd (struct nfc_hci_dev *hdev, u8 gate, u8 cmd,
142 const u8 *param, size_t param_len, struct sk_buff **skb)
143
144The API must be invoked from a context that can sleep. Most of the time, this
145will be the syscall context. skb will return the result that was received in
146the response.
147
148Internally, execution is asynchronous. So all this API does is to enqueue the
149HCI command, setup a local wait queue on stack, and wait_event() for completion.
150The wait is not interruptible because it is guaranteed that the command will
151complete after some short timeout anyway.
152
153MSGTXWQ context will then be scheduled and invoke nfc_hci_msg_tx_work().
154This function will dequeue the next pending command and send its HCP fragments
155to the lower layer which happens to be shdlc. It will then start a timer to be
156able to complete the command with a timeout error if no response arrive.
157
158SMW context gets scheduled and invokes nfc_shdlc_sm_work(). This function
159handles shdlc framing in and out. It uses the driver xmit to send frames and
160receives incoming frames in an skb queue filled from the driver IRQ handler.
Eric Lapuyadea202abb2012-05-07 12:31:17 +0200161SHDLC I(nformation) frames payload are HCP fragments. They are aggregated to
Eric Lapuyade0efbf7f2012-04-10 19:43:08 +0200162form complete HCI frames, which can be a response, command, or event.
163
164HCI Responses are dispatched immediately from this context to unblock
Eric Lapuyadea202abb2012-05-07 12:31:17 +0200165waiting command execution. Response processing involves invoking the completion
Eric Lapuyade0efbf7f2012-04-10 19:43:08 +0200166callback that was provided by nfc_hci_msg_tx_work() when it sent the command.
167The completion callback will then wake the syscall context.
168
169Workflow receiving an HCI event or command
170------------------------------------------
171
172HCI commands or events are not dispatched from SMW context. Instead, they are
173queued to HCI rx_queue and will be dispatched from HCI rx worker
174context (MSGRXWQ). This is done this way to allow a cmd or event handler
175to also execute other commands (for example, handling the
176NFC_HCI_EVT_TARGET_DISCOVERED event from PN544 requires to issue an
177ANY_GET_PARAMETER to the reader A gate to get information on the target
178that was discovered).
179
180Typically, such an event will be propagated to NFC Core from MSGRXWQ context.
Eric Lapuyade36516262012-05-03 11:49:30 +0200181
182Error management
183----------------
184
185Errors that occur synchronously with the execution of an NFC Core request are
186simply returned as the execution result of the request. These are easy.
187
188Errors that occur asynchronously (e.g. in a background protocol handling thread)
189must be reported such that upper layers don't stay ignorant that something
190went wrong below and know that expected events will probably never happen.
191Handling of these errors is done as follows:
192
193- driver (pn544) fails to deliver an incoming frame: it stores the error such
194that any subsequent call to the driver will result in this error. Then it calls
195the standard nfc_shdlc_recv_frame() with a NULL argument to report the problem
196above. shdlc stores a EREMOTEIO sticky status, which will trigger SMW to
197report above in turn.
198
199- SMW is basically a background thread to handle incoming and outgoing shdlc
200frames. This thread will also check the shdlc sticky status and report to HCI
201when it discovers it is not able to run anymore because of an unrecoverable
202error that happened within shdlc or below. If the problem occurs during shdlc
203connection, the error is reported through the connect completion.
204
205- HCI: if an internal HCI error happens (frame is lost), or HCI is reported an
206error from a lower layer, HCI will either complete the currently executing
207command with that error, or notify NFC Core directly if no command is executing.
208
209- NFC Core: when NFC Core is notified of an error from below and polling is
210active, it will send a tag discovered event with an empty tag list to the user
211space to let it know that the poll operation will never be able to detect a tag.
212If polling is not active and the error was sticky, lower levels will return it
213at next invocation.