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 376a2968aaSIlan Elias /* NCI device state */ 386a2968aaSIlan Elias enum { 396a2968aaSIlan Elias NCI_INIT, 406a2968aaSIlan Elias NCI_UP, 416a2968aaSIlan Elias NCI_DISCOVERY, 426a2968aaSIlan Elias NCI_POLL_ACTIVE, 4338f04c6bSIlan Elias NCI_DATA_EXCHANGE, 446a2968aaSIlan Elias }; 456a2968aaSIlan Elias 466a2968aaSIlan Elias /* NCI timeouts */ 476a2968aaSIlan Elias #define NCI_RESET_TIMEOUT 5000 486a2968aaSIlan Elias #define NCI_INIT_TIMEOUT 5000 496a2968aaSIlan Elias #define NCI_RF_DISC_TIMEOUT 5000 506a2968aaSIlan Elias #define NCI_RF_DEACTIVATE_TIMEOUT 5000 516a2968aaSIlan Elias #define NCI_CMD_TIMEOUT 5000 526a2968aaSIlan Elias 536a2968aaSIlan Elias struct nci_dev; 546a2968aaSIlan Elias 556a2968aaSIlan Elias struct nci_ops { 566a2968aaSIlan Elias int (*open)(struct nci_dev *ndev); 576a2968aaSIlan Elias int (*close)(struct nci_dev *ndev); 586a2968aaSIlan Elias int (*send)(struct sk_buff *skb); 596a2968aaSIlan Elias }; 606a2968aaSIlan Elias 616a2968aaSIlan Elias #define NCI_MAX_SUPPORTED_RF_INTERFACES 4 626a2968aaSIlan Elias 636a2968aaSIlan Elias /* NCI Core structures */ 646a2968aaSIlan Elias struct nci_dev { 656a2968aaSIlan Elias struct nfc_dev *nfc_dev; 666a2968aaSIlan Elias struct nci_ops *ops; 676a2968aaSIlan Elias 686a2968aaSIlan Elias int tx_headroom; 696a2968aaSIlan Elias int tx_tailroom; 706a2968aaSIlan Elias 716a2968aaSIlan Elias unsigned long flags; 726a2968aaSIlan Elias 736a2968aaSIlan Elias atomic_t cmd_cnt; 746a2968aaSIlan Elias atomic_t credits_cnt; 756a2968aaSIlan Elias 766a2968aaSIlan Elias struct timer_list cmd_timer; 776a2968aaSIlan Elias 786a2968aaSIlan Elias struct workqueue_struct *cmd_wq; 796a2968aaSIlan Elias struct work_struct cmd_work; 806a2968aaSIlan Elias 816a2968aaSIlan Elias struct workqueue_struct *rx_wq; 826a2968aaSIlan Elias struct work_struct rx_work; 836a2968aaSIlan Elias 846a2968aaSIlan Elias struct workqueue_struct *tx_wq; 856a2968aaSIlan Elias struct work_struct tx_work; 866a2968aaSIlan Elias 876a2968aaSIlan Elias struct sk_buff_head cmd_q; 886a2968aaSIlan Elias struct sk_buff_head rx_q; 896a2968aaSIlan Elias struct sk_buff_head tx_q; 906a2968aaSIlan Elias 916a2968aaSIlan Elias struct mutex req_lock; 926a2968aaSIlan Elias struct completion req_completion; 936a2968aaSIlan Elias __u32 req_status; 946a2968aaSIlan Elias __u32 req_result; 956a2968aaSIlan Elias 966a2968aaSIlan Elias void *driver_data; 976a2968aaSIlan Elias 986a2968aaSIlan Elias __u32 poll_prots; 996a2968aaSIlan Elias __u32 target_available_prots; 1006a2968aaSIlan Elias __u32 target_active_prot; 1016a2968aaSIlan Elias 1026a2968aaSIlan Elias /* received during NCI_OP_CORE_RESET_RSP */ 1036a2968aaSIlan Elias __u8 nci_ver; 1046a2968aaSIlan Elias 1056a2968aaSIlan Elias /* received during NCI_OP_CORE_INIT_RSP */ 1066a2968aaSIlan Elias __u32 nfcc_features; 1076a2968aaSIlan Elias __u8 num_supported_rf_interfaces; 1086a2968aaSIlan Elias __u8 supported_rf_interfaces 1096a2968aaSIlan Elias [NCI_MAX_SUPPORTED_RF_INTERFACES]; 1106a2968aaSIlan Elias __u8 max_logical_connections; 1116a2968aaSIlan Elias __u16 max_routing_table_size; 112e8c0dacdSIlan Elias __u8 max_ctrl_pkt_payload_len; 113e8c0dacdSIlan Elias __u16 max_size_for_large_params; 114e8c0dacdSIlan Elias __u8 manufact_id; 115e8c0dacdSIlan Elias __u32 manufact_specific_info; 1166a2968aaSIlan Elias 117637d85a7SIlan Elias /* received during NCI_OP_RF_INTF_ACTIVATED_NTF */ 118637d85a7SIlan Elias __u8 max_data_pkt_payload_size; 119637d85a7SIlan Elias __u8 initial_num_credits; 120637d85a7SIlan Elias 1216a2968aaSIlan Elias /* stored during nci_data_exchange */ 1226a2968aaSIlan Elias data_exchange_cb_t data_exchange_cb; 1236a2968aaSIlan Elias void *data_exchange_cb_context; 1246a2968aaSIlan Elias struct sk_buff *rx_data_reassembly; 1256a2968aaSIlan Elias }; 1266a2968aaSIlan Elias 1276a2968aaSIlan Elias /* ----- NCI Devices ----- */ 1286a2968aaSIlan Elias struct nci_dev *nci_allocate_device(struct nci_ops *ops, 1296a2968aaSIlan Elias __u32 supported_protocols, 1306a2968aaSIlan Elias int tx_headroom, 1316a2968aaSIlan Elias int tx_tailroom); 1326a2968aaSIlan Elias void nci_free_device(struct nci_dev *ndev); 1336a2968aaSIlan Elias int nci_register_device(struct nci_dev *ndev); 1346a2968aaSIlan Elias void nci_unregister_device(struct nci_dev *ndev); 1356a2968aaSIlan Elias int nci_recv_frame(struct sk_buff *skb); 1366a2968aaSIlan Elias 1376a2968aaSIlan Elias static inline struct sk_buff *nci_skb_alloc(struct nci_dev *ndev, 1386a2968aaSIlan Elias unsigned int len, 1396a2968aaSIlan Elias gfp_t how) 1406a2968aaSIlan Elias { 1416a2968aaSIlan Elias struct sk_buff *skb; 1426a2968aaSIlan Elias 1436a2968aaSIlan Elias skb = alloc_skb(len + ndev->tx_headroom + ndev->tx_tailroom, how); 1446a2968aaSIlan Elias if (skb) 1456a2968aaSIlan Elias skb_reserve(skb, ndev->tx_headroom); 1466a2968aaSIlan Elias 1476a2968aaSIlan Elias return skb; 1486a2968aaSIlan Elias } 1496a2968aaSIlan Elias 1506a2968aaSIlan Elias static inline void nci_set_parent_dev(struct nci_dev *ndev, struct device *dev) 1516a2968aaSIlan Elias { 1526a2968aaSIlan Elias nfc_set_parent_dev(ndev->nfc_dev, dev); 1536a2968aaSIlan Elias } 1546a2968aaSIlan Elias 1556a2968aaSIlan Elias static inline void nci_set_drvdata(struct nci_dev *ndev, void *data) 1566a2968aaSIlan Elias { 1576a2968aaSIlan Elias ndev->driver_data = data; 1586a2968aaSIlan Elias } 1596a2968aaSIlan Elias 1606a2968aaSIlan Elias static inline void *nci_get_drvdata(struct nci_dev *ndev) 1616a2968aaSIlan Elias { 1626a2968aaSIlan Elias return ndev->driver_data; 1636a2968aaSIlan Elias } 1646a2968aaSIlan Elias 1656a2968aaSIlan Elias void nci_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb); 1666a2968aaSIlan Elias void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb); 1676a2968aaSIlan Elias void nci_rx_data_packet(struct nci_dev *ndev, struct sk_buff *skb); 1686a2968aaSIlan Elias int nci_send_cmd(struct nci_dev *ndev, __u16 opcode, __u8 plen, void *payload); 1696a2968aaSIlan Elias int nci_send_data(struct nci_dev *ndev, __u8 conn_id, struct sk_buff *skb); 1706a2968aaSIlan Elias void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb, 1716a2968aaSIlan Elias int err); 1726a2968aaSIlan Elias 1736a2968aaSIlan Elias /* ----- NCI requests ----- */ 1746a2968aaSIlan Elias #define NCI_REQ_DONE 0 1756a2968aaSIlan Elias #define NCI_REQ_PEND 1 1766a2968aaSIlan Elias #define NCI_REQ_CANCELED 2 1776a2968aaSIlan Elias 1786a2968aaSIlan Elias void nci_req_complete(struct nci_dev *ndev, int result); 1796a2968aaSIlan Elias 1806a2968aaSIlan Elias /* ----- NCI status code ----- */ 1816a2968aaSIlan Elias int nci_to_errno(__u8 code); 1826a2968aaSIlan Elias 1836a2968aaSIlan Elias #endif /* __NCI_CORE_H */ 184