€•ϾŒsphinx.addnodes”Œdocument”“”)”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)”}”(hhh]”(hŒ pending_xref”“”)”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…””}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ*/translations/zh_CN/driver-api/nfc/nfc-hci”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ*/translations/zh_TW/driver-api/nfc/nfc-hci”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ*/translations/it_IT/driver-api/nfc/nfc-hci”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ*/translations/ja_JP/driver-api/nfc/nfc-hci”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ*/translations/ko_KR/driver-api/nfc/nfc-hci”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒPortuguese (Brazilian)”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ*/translations/pt_BR/driver-api/nfc/nfc-hci”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ*/translations/sp_SP/driver-api/nfc/nfc-hci”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒHCI backend for NFC Core”h]”hŒHCI backend for NFC Core”…””}”(hh¼h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhh·h²hh³ŒD/var/lib/git/docbuild/linux/Documentation/driver-api/nfc/nfc-hci.rst”h´KubhŒ bullet_list”“”)”}”(hhh]”(hŒ list_item”“”)”}”(hŒ#Author: Eric Lapuyade, Samuel Ortiz”h]”hŒ paragraph”“”)”}”(hhÔh]”hŒ#Author: Eric Lapuyade, Samuel Ortiz”…””}”(hhØh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´KhhÒubah}”(h]”h ]”h"]”h$]”h&]”uh1hÐhhÍh²hh³hÊh´NubhÑ)”}”(hŒ9Contact: eric.lapuyade@intel.com, samuel.ortiz@intel.com ”h]”h×)”}”(hŒ8Contact: eric.lapuyade@intel.com, samuel.ortiz@intel.com”h]”(hŒ Contact: ”…””}”(hhïh²hh³Nh´NubhŒ reference”“”)”}”(hŒeric.lapuyade@intel.com”h]”hŒeric.lapuyade@intel.com”…””}”(hhùh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”Œmailto:eric.lapuyade@intel.com”uh1h÷hhïubhŒ, ”…””}”(hhïh²hh³Nh´Nubhø)”}”(hŒsamuel.ortiz@intel.com”h]”hŒsamuel.ortiz@intel.com”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”Œmailto:samuel.ortiz@intel.com”uh1h÷hhïubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´Khhëubah}”(h]”h ]”h"]”h$]”h&]”uh1hÐhhÍh²hh³hÊh´Nubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ-”uh1hËh³hÊh´Khh·h²hubh¶)”}”(hhh]”(h»)”}”(hŒGeneral”h]”hŒGeneral”…””}”(hj4h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj1h²hh³hÊh´K ubh×)”}”(hXThe HCI layer implements much of the ETSI TS 102 622 V10.2.0 specification. It enables easy writing of HCI-based NFC drivers. The HCI layer runs as an NFC Core backend, implementing an abstract nfc device and translating NFC Core API to HCI commands and events.”h]”hXThe HCI layer implements much of the ETSI TS 102 622 V10.2.0 specification. It enables easy writing of HCI-based NFC drivers. The HCI layer runs as an NFC Core backend, implementing an abstract nfc device and translating NFC Core API to HCI commands and events.”…””}”(hjBh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´K hj1h²hubeh}”(h]”Œgeneral”ah ]”h"]”Œgeneral”ah$]”h&]”uh1hµhh·h²hh³hÊh´K ubh¶)”}”(hhh]”(h»)”}”(hŒHCI”h]”hŒHCI”…””}”(hj[h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjXh²hh³hÊh´Kubh×)”}”(hX«HCI registers as an nfc device with NFC Core. Requests coming from userspace are routed through netlink sockets to NFC Core and then to HCI. From this point, they are translated in a sequence of HCI commands sent to the HCI layer in the host controller (the chip). Commands can be executed synchronously (the sending context blocks waiting for response) or asynchronously (the response is returned from HCI Rx context). HCI events can also be received from the host controller. They will be handled and a translation will be forwarded to NFC Core as needed. There are hooks to let the HCI driver handle proprietary events or override standard behavior. HCI uses 2 execution contexts:”h]”hX«HCI registers as an nfc device with NFC Core. Requests coming from userspace are routed through netlink sockets to NFC Core and then to HCI. From this point, they are translated in a sequence of HCI commands sent to the HCI layer in the host controller (the chip). Commands can be executed synchronously (the sending context blocks waiting for response) or asynchronously (the response is returned from HCI Rx context). HCI events can also be received from the host controller. They will be handled and a translation will be forwarded to NFC Core as needed. There are hooks to let the HCI driver handle proprietary events or override standard behavior. HCI uses 2 execution contexts:”…””}”(hjih²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´KhjXh²hubhÌ)”}”(hhh]”(hÑ)”}”(hŒjone for executing commands : nfc_hci_msg_tx_work(). Only one command can be executing at any given moment.”h]”h×)”}”(hŒjone for executing commands : nfc_hci_msg_tx_work(). Only one command can be executing at any given moment.”h]”hŒjone for executing commands : nfc_hci_msg_tx_work(). Only one command can be executing at any given moment.”…””}”(hj~h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´Khjzubah}”(h]”h ]”h"]”h$]”h&]”uh1hÐhjwh²hh³hÊh´NubhÑ)”}”(hŒJone for dispatching received events and commands : nfc_hci_msg_rx_work(). ”h]”h×)”}”(hŒIone for dispatching received events and commands : nfc_hci_msg_rx_work().”h]”hŒIone for dispatching received events and commands : nfc_hci_msg_rx_work().”…””}”(hj–h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´K hj’ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÐhjwh²hh³hÊh´Nubeh}”(h]”h ]”h"]”h$]”h&]”j/j0uh1hËh³hÊh´KhjXh²hubeh}”(h]”Œhci”ah ]”h"]”Œhci”ah$]”h&]”uh1hµhh·h²hh³hÊh´Kubh¶)”}”(hhh]”(h»)”}”(hŒHCI Session initialization”h]”hŒHCI Session initialization”…””}”(hj»h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj¸h²hh³hÊh´K#ubh×)”}”(hX•The Session initialization is an HCI standard which must unfortunately support proprietary gates. This is the reason why the driver will pass a list of proprietary gates that must be part of the session. HCI will ensure all those gates have pipes connected when the hci device is set up. In case the chip supports pre-opened gates and pseudo-static pipes, the driver can pass that information to HCI core.”h]”hX•The Session initialization is an HCI standard which must unfortunately support proprietary gates. This is the reason why the driver will pass a list of proprietary gates that must be part of the session. HCI will ensure all those gates have pipes connected when the hci device is set up. In case the chip supports pre-opened gates and pseudo-static pipes, the driver can pass that information to HCI core.”…””}”(hjÉh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´K%hj¸h²hubeh}”(h]”Œhci-session-initialization”ah ]”h"]”Œhci session initialization”ah$]”h&]”uh1hµhh·h²hh³hÊh´K#ubh¶)”}”(hhh]”(h»)”}”(hŒHCI Gates and Pipes”h]”hŒHCI Gates and Pipes”…””}”(hjâh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjßh²hh³hÊh´K-ubh×)”}”(hXTA gate defines the 'port' where some service can be found. In order to access a service, one must create a pipe to that gate and open it. In this implementation, pipes are totally hidden. The public API only knows gates. This is consistent with the driver need to send commands to proprietary gates without knowing the pipe connected to it.”h]”hXXA gate defines the ‘port’ where some service can be found. In order to access a service, one must create a pipe to that gate and open it. In this implementation, pipes are totally hidden. The public API only knows gates. This is consistent with the driver need to send commands to proprietary gates without knowing the pipe connected to it.”…””}”(hjðh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´K/hjßh²hubeh}”(h]”Œhci-gates-and-pipes”ah ]”h"]”Œhci gates and pipes”ah$]”h&]”uh1hµhh·h²hh³hÊh´K-ubh¶)”}”(hhh]”(h»)”}”(hŒDriver interface”h]”hŒDriver interface”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjh²hh³hÊh´K6ubh×)”}”(hŒÎA driver is generally written in two parts : the physical link management and the HCI management. This makes it easier to maintain a driver for a chip that can be connected using various phy (i2c, spi, ...)”h]”hŒÎA driver is generally written in two parts : the physical link management and the HCI management. This makes it easier to maintain a driver for a chip that can be connected using various phy (i2c, spi, ...)”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´K8hjh²hubeh}”(h]”Œdriver-interface”ah ]”h"]”Œdriver interface”ah$]”h&]”uh1hµhh·h²hh³hÊh´K6ubh¶)”}”(hhh]”(h»)”}”(hŒHCI Management”h]”hŒHCI Management”…””}”(hj0h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj-h²hh³hÊh´K=ubh×)”}”(hŒYA driver would normally register itself with HCI and provide the following entry points::”h]”hŒXA driver would normally register itself with HCI and provide the following entry points:”…””}”(hj>h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´K?hj-h²hubhŒ literal_block”“”)”}”(hX!struct nfc_hci_ops { int (*open)(struct nfc_hci_dev *hdev); void (*close)(struct nfc_hci_dev *hdev); int (*hci_ready) (struct nfc_hci_dev *hdev); int (*xmit) (struct nfc_hci_dev *hdev, struct sk_buff *skb); int (*start_poll) (struct nfc_hci_dev *hdev, u32 im_protocols, u32 tm_protocols); int (*dep_link_up)(struct nfc_hci_dev *hdev, struct nfc_target *target, u8 comm_mode, u8 *gb, size_t gb_len); int (*dep_link_down)(struct nfc_hci_dev *hdev); int (*target_from_gate) (struct nfc_hci_dev *hdev, u8 gate, struct nfc_target *target); int (*complete_target_discovered) (struct nfc_hci_dev *hdev, u8 gate, struct nfc_target *target); int (*im_transceive) (struct nfc_hci_dev *hdev, struct nfc_target *target, struct sk_buff *skb, data_exchange_cb_t cb, void *cb_context); int (*tm_send)(struct nfc_hci_dev *hdev, struct sk_buff *skb); int (*check_presence)(struct nfc_hci_dev *hdev, struct nfc_target *target); int (*event_received)(struct nfc_hci_dev *hdev, u8 gate, u8 event, struct sk_buff *skb); };”h]”hX!struct nfc_hci_ops { int (*open)(struct nfc_hci_dev *hdev); void (*close)(struct nfc_hci_dev *hdev); int (*hci_ready) (struct nfc_hci_dev *hdev); int (*xmit) (struct nfc_hci_dev *hdev, struct sk_buff *skb); int (*start_poll) (struct nfc_hci_dev *hdev, u32 im_protocols, u32 tm_protocols); int (*dep_link_up)(struct nfc_hci_dev *hdev, struct nfc_target *target, u8 comm_mode, u8 *gb, size_t gb_len); int (*dep_link_down)(struct nfc_hci_dev *hdev); int (*target_from_gate) (struct nfc_hci_dev *hdev, u8 gate, struct nfc_target *target); int (*complete_target_discovered) (struct nfc_hci_dev *hdev, u8 gate, struct nfc_target *target); int (*im_transceive) (struct nfc_hci_dev *hdev, struct nfc_target *target, struct sk_buff *skb, data_exchange_cb_t cb, void *cb_context); int (*tm_send)(struct nfc_hci_dev *hdev, struct sk_buff *skb); int (*check_presence)(struct nfc_hci_dev *hdev, struct nfc_target *target); int (*event_received)(struct nfc_hci_dev *hdev, u8 gate, u8 event, struct sk_buff *skb); };”…””}”hjNsbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1jLh³hÊh´KBhj-h²hubhÌ)”}”(hhh]”(hÑ)”}”(hŒ6open() and close() shall turn the hardware on and off.”h]”h×)”}”(hjch]”hŒ6open() and close() shall turn the hardware on and off.”…””}”(hjeh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´KZhjaubah}”(h]”h ]”h"]”h$]”h&]”uh1hÐhj^h²hh³hÊh´NubhÑ)”}”(hŒÃhci_ready() is an optional entry point that is called right after the hci session has been set up. The driver can use it to do additional initialization that must be performed using HCI commands.”h]”h×)”}”(hŒÃhci_ready() is an optional entry point that is called right after the hci session has been set up. The driver can use it to do additional initialization that must be performed using HCI commands.”h]”hŒÃhci_ready() is an optional entry point that is called right after the hci session has been set up. The driver can use it to do additional initialization that must be performed using HCI commands.”…””}”(hj|h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´K[hjxubah}”(h]”h ]”h"]”h$]”h&]”uh1hÐhj^h²hh³hÊh´NubhÑ)”}”(hŒ7xmit() shall simply write a frame to the physical link.”h]”h×)”}”(hj’h]”hŒ7xmit() shall simply write a frame to the physical link.”…””}”(hj”h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´K^hjubah}”(h]”h ]”h"]”h$]”h&]”uh1hÐhj^h²hh³hÊh´NubhÑ)”}”(hŒÑstart_poll() is an optional entrypoint that shall set the hardware in polling mode. This must be implemented only if the hardware uses proprietary gates or a mechanism slightly different from the HCI standard.”h]”h×)”}”(hŒÑstart_poll() is an optional entrypoint that shall set the hardware in polling mode. This must be implemented only if the hardware uses proprietary gates or a mechanism slightly different from the HCI standard.”h]”hŒÑstart_poll() is an optional entrypoint that shall set the hardware in polling mode. This must be implemented only if the hardware uses proprietary gates or a mechanism slightly different from the HCI standard.”…””}”(hj«h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´K_hj§ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÐhj^h²hh³hÊh´NubhÑ)”}”(hŒ¢dep_link_up() is called after a p2p target has been detected, to finish the p2p connection setup with hardware parameters that need to be passed back to nfc core.”h]”h×)”}”(hŒ¢dep_link_up() is called after a p2p target has been detected, to finish the p2p connection setup with hardware parameters that need to be passed back to nfc core.”h]”hŒ¢dep_link_up() is called after a p2p target has been detected, to finish the p2p connection setup with hardware parameters that need to be passed back to nfc core.”…””}”(hjÃh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´Kbhj¿ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÐhj^h²hh³hÊh´NubhÑ)”}”(hŒ5dep_link_down() is called to bring the p2p link down.”h]”h×)”}”(hjÙh]”hŒ5dep_link_down() is called to bring the p2p link down.”…””}”(hjÛh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´Kehj×ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÐhj^h²hh³hÊh´NubhÑ)”}”(hŒmtarget_from_gate() is an optional entrypoint to return the nfc protocols corresponding to a proprietary gate.”h]”h×)”}”(hŒmtarget_from_gate() is an optional entrypoint to return the nfc protocols corresponding to a proprietary gate.”h]”hŒmtarget_from_gate() is an optional entrypoint to return the nfc protocols corresponding to a proprietary gate.”…””}”(hjòh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´Kfhjîubah}”(h]”h ]”h"]”h$]”h&]”uh1hÐhj^h²hh³hÊh´NubhÑ)”}”(hŒ¥complete_target_discovered() is an optional entry point to let the driver perform additional proprietary processing necessary to auto activate the discovered target.”h]”h×)”}”(hŒ¥complete_target_discovered() is an optional entry point to let the driver perform additional proprietary processing necessary to auto activate the discovered target.”h]”hŒ¥complete_target_discovered() is an optional entry point to let the driver perform additional proprietary processing necessary to auto activate the discovered target.”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´Khhjubah}”(h]”h ]”h"]”h$]”h&]”uh1hÐhj^h²hh³hÊh´NubhÑ)”}”(hXŒim_transceive() must be implemented by the driver if proprietary HCI commands are required to send data to the tag. Some tag types will require custom commands, others can be written to using the standard HCI commands. The driver can check the tag type and either do proprietary processing, or return 1 to ask for standard processing. The data exchange command itself must be sent asynchronously.”h]”h×)”}”(hXŒim_transceive() must be implemented by the driver if proprietary HCI commands are required to send data to the tag. Some tag types will require custom commands, others can be written to using the standard HCI commands. The driver can check the tag type and either do proprietary processing, or return 1 to ask for standard processing. The data exchange command itself must be sent asynchronously.”h]”hXŒim_transceive() must be implemented by the driver if proprietary HCI commands are required to send data to the tag. Some tag types will require custom commands, others can be written to using the standard HCI commands. The driver can check the tag type and either do proprietary processing, or return 1 to ask for standard processing. The data exchange command itself must be sent asynchronously.”…””}”(hj"h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´Kkhjubah}”(h]”h ]”h"]”h$]”h&]”uh1hÐhj^h²hh³hÊh´NubhÑ)”}”(hŒ@tm_send() is called to send data in the case of a p2p connection”h]”h×)”}”(hj8h]”hŒ@tm_send() is called to send data in the case of a p2p connection”…””}”(hj:h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´Kqhj6ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÐhj^h²hh³hÊh´NubhÑ)”}”(hŒëcheck_presence() is an optional entry point that will be called regularly by the core to check that an activated tag is still in the field. If this is not implemented, the core will not be able to push tag_lost events to the user space”h]”h×)”}”(hŒëcheck_presence() is an optional entry point that will be called regularly by the core to check that an activated tag is still in the field. If this is not implemented, the core will not be able to push tag_lost events to the user space”h]”hŒëcheck_presence() is an optional entry point that will be called regularly by the core to check that an activated tag is still in the field. If this is not implemented, the core will not be able to push tag_lost events to the user space”…””}”(hjQh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´KrhjMubah}”(h]”h ]”h"]”h$]”h&]”uh1hÐhj^h²hh³hÊh´NubhÑ)”}”(hŒ”event_received() is called to handle an event coming from the chip. Driver can handle the event or return 1 to let HCI attempt standard processing. ”h]”h×)”}”(hŒ“event_received() is called to handle an event coming from the chip. Driver can handle the event or return 1 to let HCI attempt standard processing.”h]”hŒ“event_received() is called to handle an event coming from the chip. Driver can handle the event or return 1 to let HCI attempt standard processing.”…””}”(hjih²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´Kvhjeubah}”(h]”h ]”h"]”h$]”h&]”uh1hÐhj^h²hh³hÊh´Nubeh}”(h]”h ]”h"]”h$]”h&]”j/j0uh1hËh³hÊh´KZhj-h²hubh×)”}”(hŒËOn the rx path, the driver is responsible to push incoming HCP frames to HCI using nfc_hci_recv_frame(). HCI will take care of re-aggregation and handling This must be done from a context that can sleep.”h]”hŒËOn the rx path, the driver is responsible to push incoming HCP frames to HCI using nfc_hci_recv_frame(). HCI will take care of re-aggregation and handling This must be done from a context that can sleep.”…””}”(hjƒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´Kyhj-h²hubeh}”(h]”Œhci-management”ah ]”h"]”Œhci management”ah$]”h&]”uh1hµhh·h²hh³hÊh´K=ubh¶)”}”(hhh]”(h»)”}”(hŒPHY Management”h]”hŒPHY Management”…””}”(hjœh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj™h²hh³hÊh´K~ubh×)”}”(hŒOThe physical link (i2c, ...) management is defined by the following structure::”h]”hŒNThe physical link (i2c, ...) management is defined by the following structure:”…””}”(hjªh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´K€hj™h²hubjM)”}”(hŒ–struct nfc_phy_ops { int (*write)(void *dev_id, struct sk_buff *skb); int (*enable)(void *dev_id); void (*disable)(void *dev_id); };”h]”hŒ–struct nfc_phy_ops { int (*write)(void *dev_id, struct sk_buff *skb); int (*enable)(void *dev_id); void (*disable)(void *dev_id); };”…””}”hj¸sbah}”(h]”h ]”h"]”h$]”h&]”j\j]uh1jLh³hÊh´K‚hj™h²hubhŒdefinition_list”“”)”}”(hhh]”(hŒdefinition_list_item”“”)”}”(hŒDenable(): turn the phy on (power on), make it ready to transfer data”h]”(hŒterm”“”)”}”(hŒ enable():”h]”hŒ enable():”…””}”(hjÓh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÑh³hÊh´KˆhjÍubhŒ definition”“”)”}”(hhh]”h×)”}”(hŒ:turn the phy on (power on), make it ready to transfer data”h]”hŒ:turn the phy on (power on), make it ready to transfer data”…””}”(hjæh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´K‰hjãubah}”(h]”h ]”h"]”h$]”h&]”uh1jáhjÍubeh}”(h]”h ]”h"]”h$]”h&]”uh1jËh³hÊh´KˆhjÈubjÌ)”}”(hŒdisable(): turn the phy off”h]”(jÒ)”}”(hŒ disable():”h]”hŒ disable():”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÑh³hÊh´KŠhjubjâ)”}”(hhh]”h×)”}”(hŒturn the phy off”h]”hŒturn the phy off”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´K‹hjubah}”(h]”h ]”h"]”h$]”h&]”uh1jáhjubeh}”(h]”h ]”h"]”h$]”h&]”uh1jËh³hÊh´KŠhjÈh²hubjÌ)”}”(hŒûwrite(): Send a data frame to the chip. Note that to enable higher layers such as an llc to store the frame for re-emission, this function must not alter the skb. It must also not return a positive result (return 0 for success, negative for failure). ”h]”(jÒ)”}”(hŒwrite():”h]”hŒwrite():”…””}”(hj3h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÑh³hÊh´Khj/ubjâ)”}”(hhh]”h×)”}”(hŒñSend a data frame to the chip. Note that to enable higher layers such as an llc to store the frame for re-emission, this function must not alter the skb. It must also not return a positive result (return 0 for success, negative for failure).”h]”hŒñSend a data frame to the chip. Note that to enable higher layers such as an llc to store the frame for re-emission, this function must not alter the skb. It must also not return a positive result (return 0 for success, negative for failure).”…””}”(hjDh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´KhjAubah}”(h]”h ]”h"]”h$]”h&]”uh1jáhj/ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jËh³hÊh´KhjÈh²hubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÆhj™h²hh³hÊh´Nubh×)”}”(hŒIData coming from the chip shall be sent directly to nfc_hci_recv_frame().”h]”hŒIData coming from the chip shall be sent directly to nfc_hci_recv_frame().”…””}”(hjdh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´K’hj™h²hubeh}”(h]”Œphy-management”ah ]”h"]”Œphy management”ah$]”h&]”uh1hµhh·h²hh³hÊh´K~ubh¶)”}”(hhh]”(h»)”}”(hŒLLC”h]”hŒLLC”…””}”(hj}h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjzh²hh³hÊh´K•ubh×)”}”(hŒþCommunication between the CPU and the chip often requires some link layer protocol. Those are isolated as modules managed by the HCI layer. There are currently two modules : nop (raw transfer) and shdlc. A new llc must implement the following functions::”h]”hŒýCommunication between the CPU and the chip often requires some link layer protocol. Those are isolated as modules managed by the HCI layer. There are currently two modules : nop (raw transfer) and shdlc. A new llc must implement the following functions:”…””}”(hj‹h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´K—hjzh²hubjM)”}”(hX(struct nfc_llc_ops { void *(*init) (struct nfc_hci_dev *hdev, xmit_to_drv_t xmit_to_drv, rcv_to_hci_t rcv_to_hci, int tx_headroom, int tx_tailroom, int *rx_headroom, int *rx_tailroom, llc_failure_t llc_failure); void (*deinit) (struct nfc_llc *llc); int (*start) (struct nfc_llc *llc); int (*stop) (struct nfc_llc *llc); void (*rcv_from_drv) (struct nfc_llc *llc, struct sk_buff *skb); int (*xmit_from_hci) (struct nfc_llc *llc, struct sk_buff *skb); };”h]”hX(struct nfc_llc_ops { void *(*init) (struct nfc_hci_dev *hdev, xmit_to_drv_t xmit_to_drv, rcv_to_hci_t rcv_to_hci, int tx_headroom, int tx_tailroom, int *rx_headroom, int *rx_tailroom, llc_failure_t llc_failure); void (*deinit) (struct nfc_llc *llc); int (*start) (struct nfc_llc *llc); int (*stop) (struct nfc_llc *llc); void (*rcv_from_drv) (struct nfc_llc *llc, struct sk_buff *skb); int (*xmit_from_hci) (struct nfc_llc *llc, struct sk_buff *skb); };”…””}”hj™sbah}”(h]”h ]”h"]”h$]”h&]”j\j]uh1jLh³hÊh´Kœhjzh²hubjÇ)”}”(hhh]”(jÌ)”}”(hŒ.init(): allocate and init your private storage”h]”(jÒ)”}”(hŒinit():”h]”hŒinit():”…””}”(hj®h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÑh³hÊh´K¨hjªubjâ)”}”(hhh]”h×)”}”(hŒ&allocate and init your private storage”h]”hŒ&allocate and init your private storage”…””}”(hj¿h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´K©hj¼ubah}”(h]”h ]”h"]”h$]”h&]”uh1jáhjªubeh}”(h]”h ]”h"]”h$]”h&]”uh1jËh³hÊh´K¨hj§ubjÌ)”}”(hŒdeinit(): cleanup”h]”(jÒ)”}”(hŒ deinit():”h]”hŒ deinit():”…””}”(hjÝh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÑh³hÊh´KªhjÙubjâ)”}”(hhh]”h×)”}”(hŒcleanup”h]”hŒcleanup”…””}”(hjîh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´K«hjëubah}”(h]”h ]”h"]”h$]”h&]”uh1jáhjÙubeh}”(h]”h ]”h"]”h$]”h&]”uh1jËh³hÊh´Kªhj§h²hubjÌ)”}”(hŒ)start(): establish the logical connection”h]”(jÒ)”}”(hŒstart():”h]”hŒstart():”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÑh³hÊh´K¬hjubjâ)”}”(hhh]”h×)”}”(hŒ establish the logical connection”h]”hŒ establish the logical connection”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´K­hjubah}”(h]”h ]”h"]”h$]”h&]”uh1jáhjubeh}”(h]”h ]”h"]”h$]”h&]”uh1jËh³hÊh´K¬hj§h²hubjÌ)”}”(hŒ)stop (): terminate the logical connection”h]”(jÒ)”}”(hŒstop ():”h]”hŒstop ():”…””}”(hj;h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÑh³hÊh´K®hj7ubjâ)”}”(hhh]”h×)”}”(hŒ terminate the logical connection”h]”hŒ terminate the logical connection”…””}”(hjLh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´K¯hjIubah}”(h]”h ]”h"]”h$]”h&]”uh1jáhj7ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jËh³hÊh´K®hj§h²hubjÌ)”}”(hŒ>rcv_from_drv(): handle data coming from the chip, going to HCI”h]”(jÒ)”}”(hŒrcv_from_drv():”h]”hŒrcv_from_drv():”…””}”(hjjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÑh³hÊh´K°hjfubjâ)”}”(hhh]”h×)”}”(hŒ.handle data coming from the chip, going to HCI”h]”hŒ.handle data coming from the chip, going to HCI”…””}”(hj{h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÖh³hÊh´K±hjxubah}”(h]”h ]”h"]”h$]”h&]”uh1jáhjfubeh}”(h]”h ]”h"]”h$]”h&]”uh1jËh³hÊh´K°hj§h²hubjÌ)”}”(hŒ