cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

nfc-hci.rst (13082B)


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