16a2968aaSIlan Elias /* 26a2968aaSIlan Elias * The NFC Controller Interface is the communication protocol between an 36a2968aaSIlan Elias * NFC Controller (NFCC) and a Device Host (DH). 46a2968aaSIlan Elias * 56a2968aaSIlan Elias * Copyright (C) 2011 Texas Instruments, Inc. 66a2968aaSIlan Elias * 76a2968aaSIlan Elias * Written by Ilan Elias <ilane@ti.com> 86a2968aaSIlan Elias * 96a2968aaSIlan Elias * Acknowledgements: 106a2968aaSIlan Elias * This file is based on hci_core.h, which was written 116a2968aaSIlan Elias * by Maxim Krasnyansky. 126a2968aaSIlan Elias * 136a2968aaSIlan Elias * This program is free software; you can redistribute it and/or modify 146a2968aaSIlan Elias * it under the terms of the GNU General Public License version 2 156a2968aaSIlan Elias * as published by the Free Software Foundation 166a2968aaSIlan Elias * 176a2968aaSIlan Elias * This program is distributed in the hope that it will be useful, 186a2968aaSIlan Elias * but WITHOUT ANY WARRANTY; without even the implied warranty of 196a2968aaSIlan Elias * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 206a2968aaSIlan Elias * GNU General Public License for more details. 216a2968aaSIlan Elias * 226a2968aaSIlan Elias * You should have received a copy of the GNU General Public License 236a2968aaSIlan Elias * along with this program; if not, write to the Free Software 246a2968aaSIlan Elias * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 256a2968aaSIlan Elias * 266a2968aaSIlan Elias */ 276a2968aaSIlan Elias 286a2968aaSIlan Elias #ifndef __NCI_CORE_H 296a2968aaSIlan Elias #define __NCI_CORE_H 306a2968aaSIlan Elias 316a2968aaSIlan Elias #include <linux/interrupt.h> 326a2968aaSIlan Elias #include <linux/skbuff.h> 336a2968aaSIlan Elias 346a2968aaSIlan Elias #include <net/nfc/nfc.h> 356a2968aaSIlan Elias #include <net/nfc/nci.h> 366a2968aaSIlan Elias 378939e47fSIlan Elias /* NCI device flags */ 388939e47fSIlan Elias enum nci_flag { 396a2968aaSIlan Elias NCI_INIT, 406a2968aaSIlan Elias NCI_UP, 4138f04c6bSIlan Elias NCI_DATA_EXCHANGE, 42c4bf98b2SIlan Elias NCI_DATA_EXCHANGE_TO, 436a2968aaSIlan Elias }; 446a2968aaSIlan Elias 458939e47fSIlan Elias /* NCI device states */ 468939e47fSIlan Elias enum nci_state { 478939e47fSIlan Elias NCI_IDLE, 488939e47fSIlan Elias NCI_DISCOVERY, 49019c4fbaSIlan Elias NCI_W4_ALL_DISCOVERIES, 50019c4fbaSIlan Elias NCI_W4_HOST_SELECT, 518939e47fSIlan Elias NCI_POLL_ACTIVE, 528939e47fSIlan Elias }; 538939e47fSIlan Elias 546a2968aaSIlan Elias /* NCI timeouts */ 556a2968aaSIlan Elias #define NCI_RESET_TIMEOUT 5000 566a2968aaSIlan Elias #define NCI_INIT_TIMEOUT 5000 577e035230SIlan Elias #define NCI_SET_CONFIG_TIMEOUT 5000 586a2968aaSIlan Elias #define NCI_RF_DISC_TIMEOUT 5000 59019c4fbaSIlan Elias #define NCI_RF_DISC_SELECT_TIMEOUT 5000 6011ee5158SIlan Elias #define NCI_RF_DEACTIVATE_TIMEOUT 30000 616a2968aaSIlan Elias #define NCI_CMD_TIMEOUT 5000 62c4bf98b2SIlan Elias #define NCI_DATA_TIMEOUT 700 636a2968aaSIlan Elias 646a2968aaSIlan Elias struct nci_dev; 656a2968aaSIlan Elias 666a2968aaSIlan Elias struct nci_ops { 676a2968aaSIlan Elias int (*open)(struct nci_dev *ndev); 686a2968aaSIlan Elias int (*close)(struct nci_dev *ndev); 696a2968aaSIlan Elias int (*send)(struct sk_buff *skb); 706a2968aaSIlan Elias }; 716a2968aaSIlan Elias 726a2968aaSIlan Elias #define NCI_MAX_SUPPORTED_RF_INTERFACES 4 73019c4fbaSIlan Elias #define NCI_MAX_DISCOVERED_TARGETS 10 746a2968aaSIlan Elias 756a2968aaSIlan Elias /* NCI Core structures */ 766a2968aaSIlan Elias struct nci_dev { 776a2968aaSIlan Elias struct nfc_dev *nfc_dev; 786a2968aaSIlan Elias struct nci_ops *ops; 796a2968aaSIlan Elias 806a2968aaSIlan Elias int tx_headroom; 816a2968aaSIlan Elias int tx_tailroom; 826a2968aaSIlan Elias 838939e47fSIlan Elias atomic_t state; 846a2968aaSIlan Elias unsigned long flags; 856a2968aaSIlan Elias 866a2968aaSIlan Elias atomic_t cmd_cnt; 876a2968aaSIlan Elias atomic_t credits_cnt; 886a2968aaSIlan Elias 896a2968aaSIlan Elias struct timer_list cmd_timer; 90c4bf98b2SIlan Elias struct timer_list data_timer; 916a2968aaSIlan Elias 926a2968aaSIlan Elias struct workqueue_struct *cmd_wq; 936a2968aaSIlan Elias struct work_struct cmd_work; 946a2968aaSIlan Elias 956a2968aaSIlan Elias struct workqueue_struct *rx_wq; 966a2968aaSIlan Elias struct work_struct rx_work; 976a2968aaSIlan Elias 986a2968aaSIlan Elias struct workqueue_struct *tx_wq; 996a2968aaSIlan Elias struct work_struct tx_work; 1006a2968aaSIlan Elias 1016a2968aaSIlan Elias struct sk_buff_head cmd_q; 1026a2968aaSIlan Elias struct sk_buff_head rx_q; 1036a2968aaSIlan Elias struct sk_buff_head tx_q; 1046a2968aaSIlan Elias 1056a2968aaSIlan Elias struct mutex req_lock; 1066a2968aaSIlan Elias struct completion req_completion; 1076a2968aaSIlan Elias __u32 req_status; 1086a2968aaSIlan Elias __u32 req_result; 1096a2968aaSIlan Elias 1106a2968aaSIlan Elias void *driver_data; 1116a2968aaSIlan Elias 1126a2968aaSIlan Elias __u32 poll_prots; 1136a2968aaSIlan Elias __u32 target_active_prot; 1146a2968aaSIlan Elias 115019c4fbaSIlan Elias struct nfc_target targets[NCI_MAX_DISCOVERED_TARGETS]; 116019c4fbaSIlan Elias int n_targets; 117019c4fbaSIlan Elias 1186a2968aaSIlan Elias /* received during NCI_OP_CORE_RESET_RSP */ 1196a2968aaSIlan Elias __u8 nci_ver; 1206a2968aaSIlan Elias 1216a2968aaSIlan Elias /* received during NCI_OP_CORE_INIT_RSP */ 1226a2968aaSIlan Elias __u32 nfcc_features; 1236a2968aaSIlan Elias __u8 num_supported_rf_interfaces; 1246a2968aaSIlan Elias __u8 supported_rf_interfaces 1256a2968aaSIlan Elias [NCI_MAX_SUPPORTED_RF_INTERFACES]; 1266a2968aaSIlan Elias __u8 max_logical_connections; 1276a2968aaSIlan Elias __u16 max_routing_table_size; 128e8c0dacdSIlan Elias __u8 max_ctrl_pkt_payload_len; 129e8c0dacdSIlan Elias __u16 max_size_for_large_params; 130e8c0dacdSIlan Elias __u8 manufact_id; 131e8c0dacdSIlan Elias __u32 manufact_specific_info; 1326a2968aaSIlan Elias 133637d85a7SIlan Elias /* received during NCI_OP_RF_INTF_ACTIVATED_NTF */ 134637d85a7SIlan Elias __u8 max_data_pkt_payload_size; 135637d85a7SIlan Elias __u8 initial_num_credits; 136637d85a7SIlan Elias 1376a2968aaSIlan Elias /* stored during nci_data_exchange */ 1386a2968aaSIlan Elias data_exchange_cb_t data_exchange_cb; 1396a2968aaSIlan Elias void *data_exchange_cb_context; 1406a2968aaSIlan Elias struct sk_buff *rx_data_reassembly; 1416a2968aaSIlan Elias }; 1426a2968aaSIlan Elias 1436a2968aaSIlan Elias /* ----- NCI Devices ----- */ 1446a2968aaSIlan Elias struct nci_dev *nci_allocate_device(struct nci_ops *ops, 1456a2968aaSIlan Elias __u32 supported_protocols, 1466a2968aaSIlan Elias int tx_headroom, 1476a2968aaSIlan Elias int tx_tailroom); 1486a2968aaSIlan Elias void nci_free_device(struct nci_dev *ndev); 1496a2968aaSIlan Elias int nci_register_device(struct nci_dev *ndev); 1506a2968aaSIlan Elias void nci_unregister_device(struct nci_dev *ndev); 1516a2968aaSIlan Elias int nci_recv_frame(struct sk_buff *skb); 1526a2968aaSIlan Elias 1536a2968aaSIlan Elias static inline struct sk_buff *nci_skb_alloc(struct nci_dev *ndev, 1546a2968aaSIlan Elias unsigned int len, 1556a2968aaSIlan Elias gfp_t how) 1566a2968aaSIlan Elias { 1576a2968aaSIlan Elias struct sk_buff *skb; 1586a2968aaSIlan Elias 1596a2968aaSIlan Elias skb = alloc_skb(len + ndev->tx_headroom + ndev->tx_tailroom, how); 1606a2968aaSIlan Elias if (skb) 1616a2968aaSIlan Elias skb_reserve(skb, ndev->tx_headroom); 1626a2968aaSIlan Elias 1636a2968aaSIlan Elias return skb; 1646a2968aaSIlan Elias } 1656a2968aaSIlan Elias 1666a2968aaSIlan Elias static inline void nci_set_parent_dev(struct nci_dev *ndev, struct device *dev) 1676a2968aaSIlan Elias { 1686a2968aaSIlan Elias nfc_set_parent_dev(ndev->nfc_dev, dev); 1696a2968aaSIlan Elias } 1706a2968aaSIlan Elias 1716a2968aaSIlan Elias static inline void nci_set_drvdata(struct nci_dev *ndev, void *data) 1726a2968aaSIlan Elias { 1736a2968aaSIlan Elias ndev->driver_data = data; 1746a2968aaSIlan Elias } 1756a2968aaSIlan Elias 1766a2968aaSIlan Elias static inline void *nci_get_drvdata(struct nci_dev *ndev) 1776a2968aaSIlan Elias { 1786a2968aaSIlan Elias return ndev->driver_data; 1796a2968aaSIlan Elias } 1806a2968aaSIlan Elias 1816a2968aaSIlan Elias void nci_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb); 1826a2968aaSIlan Elias void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb); 1836a2968aaSIlan Elias void nci_rx_data_packet(struct nci_dev *ndev, struct sk_buff *skb); 1846a2968aaSIlan Elias int nci_send_cmd(struct nci_dev *ndev, __u16 opcode, __u8 plen, void *payload); 1856a2968aaSIlan Elias int nci_send_data(struct nci_dev *ndev, __u8 conn_id, struct sk_buff *skb); 1866a2968aaSIlan Elias void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb, 1876a2968aaSIlan Elias int err); 188019c4fbaSIlan Elias void nci_clear_target_list(struct nci_dev *ndev); 1896a2968aaSIlan Elias 1906a2968aaSIlan Elias /* ----- NCI requests ----- */ 1916a2968aaSIlan Elias #define NCI_REQ_DONE 0 1926a2968aaSIlan Elias #define NCI_REQ_PEND 1 1936a2968aaSIlan Elias #define NCI_REQ_CANCELED 2 1946a2968aaSIlan Elias 1956a2968aaSIlan Elias void nci_req_complete(struct nci_dev *ndev, int result); 1966a2968aaSIlan Elias 1976a2968aaSIlan Elias /* ----- NCI status code ----- */ 1986a2968aaSIlan Elias int nci_to_errno(__u8 code); 1996a2968aaSIlan Elias 2006a2968aaSIlan Elias #endif /* __NCI_CORE_H */ 201