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. 68a00a61bSFrederic Danis * Copyright (C) 2013 Intel Corporation. All rights reserved. 76a2968aaSIlan Elias * 86a2968aaSIlan Elias * Written by Ilan Elias <ilane@ti.com> 96a2968aaSIlan Elias * 106a2968aaSIlan Elias * Acknowledgements: 116a2968aaSIlan Elias * This file is based on hci_core.h, which was written 126a2968aaSIlan Elias * by Maxim Krasnyansky. 136a2968aaSIlan Elias * 146a2968aaSIlan Elias * This program is free software; you can redistribute it and/or modify 156a2968aaSIlan Elias * it under the terms of the GNU General Public License version 2 166a2968aaSIlan Elias * as published by the Free Software Foundation 176a2968aaSIlan Elias * 186a2968aaSIlan Elias * This program is distributed in the hope that it will be useful, 196a2968aaSIlan Elias * but WITHOUT ANY WARRANTY; without even the implied warranty of 206a2968aaSIlan Elias * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 216a2968aaSIlan Elias * GNU General Public License for more details. 226a2968aaSIlan Elias * 236a2968aaSIlan Elias * You should have received a copy of the GNU General Public License 246a2968aaSIlan Elias * along with this program; if not, write to the Free Software 256a2968aaSIlan Elias * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 266a2968aaSIlan Elias * 276a2968aaSIlan Elias */ 286a2968aaSIlan Elias 296a2968aaSIlan Elias #ifndef __NCI_CORE_H 306a2968aaSIlan Elias #define __NCI_CORE_H 316a2968aaSIlan Elias 326a2968aaSIlan Elias #include <linux/interrupt.h> 336a2968aaSIlan Elias #include <linux/skbuff.h> 346a2968aaSIlan Elias 356a2968aaSIlan Elias #include <net/nfc/nfc.h> 366a2968aaSIlan Elias #include <net/nfc/nci.h> 376a2968aaSIlan Elias 388939e47fSIlan Elias /* NCI device flags */ 398939e47fSIlan Elias enum nci_flag { 406a2968aaSIlan Elias NCI_INIT, 416a2968aaSIlan Elias NCI_UP, 4238f04c6bSIlan Elias NCI_DATA_EXCHANGE, 43c4bf98b2SIlan Elias NCI_DATA_EXCHANGE_TO, 446a2968aaSIlan Elias }; 456a2968aaSIlan Elias 468939e47fSIlan Elias /* NCI device states */ 478939e47fSIlan Elias enum nci_state { 488939e47fSIlan Elias NCI_IDLE, 498939e47fSIlan Elias NCI_DISCOVERY, 50019c4fbaSIlan Elias NCI_W4_ALL_DISCOVERIES, 51019c4fbaSIlan Elias NCI_W4_HOST_SELECT, 528939e47fSIlan Elias NCI_POLL_ACTIVE, 538939e47fSIlan Elias }; 548939e47fSIlan Elias 556a2968aaSIlan Elias /* NCI timeouts */ 566a2968aaSIlan Elias #define NCI_RESET_TIMEOUT 5000 576a2968aaSIlan Elias #define NCI_INIT_TIMEOUT 5000 587e035230SIlan Elias #define NCI_SET_CONFIG_TIMEOUT 5000 596a2968aaSIlan Elias #define NCI_RF_DISC_TIMEOUT 5000 60019c4fbaSIlan Elias #define NCI_RF_DISC_SELECT_TIMEOUT 5000 6111ee5158SIlan Elias #define NCI_RF_DEACTIVATE_TIMEOUT 30000 626a2968aaSIlan Elias #define NCI_CMD_TIMEOUT 5000 63c4bf98b2SIlan Elias #define NCI_DATA_TIMEOUT 700 646a2968aaSIlan Elias 656a2968aaSIlan Elias struct nci_dev; 666a2968aaSIlan Elias 676a2968aaSIlan Elias struct nci_ops { 686a2968aaSIlan Elias int (*open)(struct nci_dev *ndev); 696a2968aaSIlan Elias int (*close)(struct nci_dev *ndev); 701095e69fSFrederic Danis int (*send)(struct nci_dev *ndev, struct sk_buff *skb); 716a2968aaSIlan Elias }; 726a2968aaSIlan Elias 736a2968aaSIlan Elias #define NCI_MAX_SUPPORTED_RF_INTERFACES 4 74019c4fbaSIlan Elias #define NCI_MAX_DISCOVERED_TARGETS 10 756a2968aaSIlan Elias 766a2968aaSIlan Elias /* NCI Core structures */ 776a2968aaSIlan Elias struct nci_dev { 786a2968aaSIlan Elias struct nfc_dev *nfc_dev; 796a2968aaSIlan Elias struct nci_ops *ops; 806a2968aaSIlan Elias 816a2968aaSIlan Elias int tx_headroom; 826a2968aaSIlan Elias int tx_tailroom; 836a2968aaSIlan Elias 848939e47fSIlan Elias atomic_t state; 856a2968aaSIlan Elias unsigned long flags; 866a2968aaSIlan Elias 876a2968aaSIlan Elias atomic_t cmd_cnt; 886a2968aaSIlan Elias atomic_t credits_cnt; 896a2968aaSIlan Elias 906a2968aaSIlan Elias struct timer_list cmd_timer; 91c4bf98b2SIlan Elias struct timer_list data_timer; 926a2968aaSIlan Elias 936a2968aaSIlan Elias struct workqueue_struct *cmd_wq; 946a2968aaSIlan Elias struct work_struct cmd_work; 956a2968aaSIlan Elias 966a2968aaSIlan Elias struct workqueue_struct *rx_wq; 976a2968aaSIlan Elias struct work_struct rx_work; 986a2968aaSIlan Elias 996a2968aaSIlan Elias struct workqueue_struct *tx_wq; 1006a2968aaSIlan Elias struct work_struct tx_work; 1016a2968aaSIlan Elias 1026a2968aaSIlan Elias struct sk_buff_head cmd_q; 1036a2968aaSIlan Elias struct sk_buff_head rx_q; 1046a2968aaSIlan Elias struct sk_buff_head tx_q; 1056a2968aaSIlan Elias 1066a2968aaSIlan Elias struct mutex req_lock; 1076a2968aaSIlan Elias struct completion req_completion; 1086a2968aaSIlan Elias __u32 req_status; 1096a2968aaSIlan Elias __u32 req_result; 1106a2968aaSIlan Elias 1116a2968aaSIlan Elias void *driver_data; 1126a2968aaSIlan Elias 1136a2968aaSIlan Elias __u32 poll_prots; 1146a2968aaSIlan Elias __u32 target_active_prot; 1156a2968aaSIlan Elias 116019c4fbaSIlan Elias struct nfc_target targets[NCI_MAX_DISCOVERED_TARGETS]; 117019c4fbaSIlan Elias int n_targets; 118019c4fbaSIlan Elias 1196a2968aaSIlan Elias /* received during NCI_OP_CORE_RESET_RSP */ 1206a2968aaSIlan Elias __u8 nci_ver; 1216a2968aaSIlan Elias 1226a2968aaSIlan Elias /* received during NCI_OP_CORE_INIT_RSP */ 1236a2968aaSIlan Elias __u32 nfcc_features; 1246a2968aaSIlan Elias __u8 num_supported_rf_interfaces; 1256a2968aaSIlan Elias __u8 supported_rf_interfaces 1266a2968aaSIlan Elias [NCI_MAX_SUPPORTED_RF_INTERFACES]; 1276a2968aaSIlan Elias __u8 max_logical_connections; 1286a2968aaSIlan Elias __u16 max_routing_table_size; 129e8c0dacdSIlan Elias __u8 max_ctrl_pkt_payload_len; 130e8c0dacdSIlan Elias __u16 max_size_for_large_params; 131e8c0dacdSIlan Elias __u8 manufact_id; 132e8c0dacdSIlan Elias __u32 manufact_specific_info; 1336a2968aaSIlan Elias 134637d85a7SIlan Elias /* received during NCI_OP_RF_INTF_ACTIVATED_NTF */ 135637d85a7SIlan Elias __u8 max_data_pkt_payload_size; 136637d85a7SIlan Elias __u8 initial_num_credits; 137637d85a7SIlan Elias 1386a2968aaSIlan Elias /* stored during nci_data_exchange */ 1396a2968aaSIlan Elias data_exchange_cb_t data_exchange_cb; 1406a2968aaSIlan Elias void *data_exchange_cb_context; 1416a2968aaSIlan Elias struct sk_buff *rx_data_reassembly; 142767f19aeSIlan Elias 143767f19aeSIlan Elias /* stored during intf_activated_ntf */ 144767f19aeSIlan Elias __u8 remote_gb[NFC_MAX_GT_LEN]; 145767f19aeSIlan Elias __u8 remote_gb_len; 1466a2968aaSIlan Elias }; 1476a2968aaSIlan Elias 1486a2968aaSIlan Elias /* ----- NCI Devices ----- */ 1496a2968aaSIlan Elias struct nci_dev *nci_allocate_device(struct nci_ops *ops, 1506a2968aaSIlan Elias __u32 supported_protocols, 1516a2968aaSIlan Elias int tx_headroom, 1526a2968aaSIlan Elias int tx_tailroom); 1536a2968aaSIlan Elias void nci_free_device(struct nci_dev *ndev); 1546a2968aaSIlan Elias int nci_register_device(struct nci_dev *ndev); 1556a2968aaSIlan Elias void nci_unregister_device(struct nci_dev *ndev); 1561095e69fSFrederic Danis int nci_recv_frame(struct nci_dev *ndev, struct sk_buff *skb); 1576a2968aaSIlan Elias 1586a2968aaSIlan Elias static inline struct sk_buff *nci_skb_alloc(struct nci_dev *ndev, 1596a2968aaSIlan Elias unsigned int len, 1606a2968aaSIlan Elias gfp_t how) 1616a2968aaSIlan Elias { 1626a2968aaSIlan Elias struct sk_buff *skb; 1636a2968aaSIlan Elias 1646a2968aaSIlan Elias skb = alloc_skb(len + ndev->tx_headroom + ndev->tx_tailroom, how); 1656a2968aaSIlan Elias if (skb) 1666a2968aaSIlan Elias skb_reserve(skb, ndev->tx_headroom); 1676a2968aaSIlan Elias 1686a2968aaSIlan Elias return skb; 1696a2968aaSIlan Elias } 1706a2968aaSIlan Elias 1716a2968aaSIlan Elias static inline void nci_set_parent_dev(struct nci_dev *ndev, struct device *dev) 1726a2968aaSIlan Elias { 1736a2968aaSIlan Elias nfc_set_parent_dev(ndev->nfc_dev, dev); 1746a2968aaSIlan Elias } 1756a2968aaSIlan Elias 1766a2968aaSIlan Elias static inline void nci_set_drvdata(struct nci_dev *ndev, void *data) 1776a2968aaSIlan Elias { 1786a2968aaSIlan Elias ndev->driver_data = data; 1796a2968aaSIlan Elias } 1806a2968aaSIlan Elias 1816a2968aaSIlan Elias static inline void *nci_get_drvdata(struct nci_dev *ndev) 1826a2968aaSIlan Elias { 1836a2968aaSIlan Elias return ndev->driver_data; 1846a2968aaSIlan Elias } 1856a2968aaSIlan Elias 1866a2968aaSIlan Elias void nci_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb); 1876a2968aaSIlan Elias void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb); 1886a2968aaSIlan Elias void nci_rx_data_packet(struct nci_dev *ndev, struct sk_buff *skb); 1896a2968aaSIlan Elias int nci_send_cmd(struct nci_dev *ndev, __u16 opcode, __u8 plen, void *payload); 1906a2968aaSIlan Elias int nci_send_data(struct nci_dev *ndev, __u8 conn_id, struct sk_buff *skb); 1916a2968aaSIlan Elias void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb, 1926a2968aaSIlan Elias int err); 193019c4fbaSIlan Elias void nci_clear_target_list(struct nci_dev *ndev); 1946a2968aaSIlan Elias 1956a2968aaSIlan Elias /* ----- NCI requests ----- */ 1966a2968aaSIlan Elias #define NCI_REQ_DONE 0 1976a2968aaSIlan Elias #define NCI_REQ_PEND 1 1986a2968aaSIlan Elias #define NCI_REQ_CANCELED 2 1996a2968aaSIlan Elias 2006a2968aaSIlan Elias void nci_req_complete(struct nci_dev *ndev, int result); 2016a2968aaSIlan Elias 2026a2968aaSIlan Elias /* ----- NCI status code ----- */ 2036a2968aaSIlan Elias int nci_to_errno(__u8 code); 2046a2968aaSIlan Elias 2058a00a61bSFrederic Danis /* ----- NCI over SPI acknowledge modes ----- */ 2068a00a61bSFrederic Danis #define NCI_SPI_CRC_DISABLED 0x00 2078a00a61bSFrederic Danis #define NCI_SPI_CRC_ENABLED 0x01 2088a00a61bSFrederic Danis 2098a00a61bSFrederic Danis /* ----- NCI SPI structures ----- */ 210fa544fffSEric Lapuyade struct nci_spi; 2118a00a61bSFrederic Danis 2128a00a61bSFrederic Danis struct nci_spi_ops { 213fa544fffSEric Lapuyade void (*assert_int)(struct nci_spi *nspi); 214fa544fffSEric Lapuyade void (*deassert_int)(struct nci_spi *nspi); 2158a00a61bSFrederic Danis }; 2168a00a61bSFrederic Danis 217fa544fffSEric Lapuyade struct nci_spi { 218d5937511SEric Lapuyade struct nci_dev *ndev; 2198a00a61bSFrederic Danis struct spi_device *spi; 2208a00a61bSFrederic Danis struct nci_spi_ops *ops; 2218a00a61bSFrederic Danis 2228a00a61bSFrederic Danis unsigned int xfer_udelay; /* microseconds delay between 2238a00a61bSFrederic Danis transactions */ 2248a00a61bSFrederic Danis u8 acknowledge_mode; 2258a00a61bSFrederic Danis 226ee9596d4SFrederic Danis struct completion req_completion; 227ee9596d4SFrederic Danis u8 req_result; 2288a00a61bSFrederic Danis }; 2298a00a61bSFrederic Danis 230fa544fffSEric Lapuyade /* ----- NCI SPI ----- */ 231fa544fffSEric Lapuyade struct nci_spi *nci_spi_allocate_spi(struct spi_device *spi, 2328a00a61bSFrederic Danis struct nci_spi_ops *ops, 233fa544fffSEric Lapuyade u8 acknowledge_mode, unsigned int delay, 234fa544fffSEric Lapuyade struct nci_dev *ndev); 235fa544fffSEric Lapuyade int nci_spi_send(struct nci_spi *nspi, struct sk_buff *skb); 23622d4aae5SEric Lapuyade struct sk_buff *nci_spi_read(struct nci_spi *nspi); 2378a00a61bSFrederic Danis 2386a2968aaSIlan Elias #endif /* __NCI_CORE_H */ 239