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. 7a99903ecSJulien Lefrique * Copyright (C) 2014 Marvell International Ltd. 86a2968aaSIlan Elias * 96a2968aaSIlan Elias * Written by Ilan Elias <ilane@ti.com> 106a2968aaSIlan Elias * 116a2968aaSIlan Elias * Acknowledgements: 126a2968aaSIlan Elias * This file is based on hci_core.h, which was written 136a2968aaSIlan Elias * by Maxim Krasnyansky. 146a2968aaSIlan Elias * 156a2968aaSIlan Elias * This program is free software; you can redistribute it and/or modify 166a2968aaSIlan Elias * it under the terms of the GNU General Public License version 2 176a2968aaSIlan Elias * as published by the Free Software Foundation 186a2968aaSIlan Elias * 196a2968aaSIlan Elias * This program is distributed in the hope that it will be useful, 206a2968aaSIlan Elias * but WITHOUT ANY WARRANTY; without even the implied warranty of 216a2968aaSIlan Elias * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 226a2968aaSIlan Elias * GNU General Public License for more details. 236a2968aaSIlan Elias * 246a2968aaSIlan Elias * You should have received a copy of the GNU General Public License 25a6227e26SJeff Kirsher * along with this program; if not, see <http://www.gnu.org/licenses/>. 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> 349961127dSVincent Cuissard #include <linux/tty.h> 356a2968aaSIlan Elias 366a2968aaSIlan Elias #include <net/nfc/nfc.h> 376a2968aaSIlan Elias #include <net/nfc/nci.h> 386a2968aaSIlan Elias 398939e47fSIlan Elias /* NCI device flags */ 408939e47fSIlan Elias enum nci_flag { 416a2968aaSIlan Elias NCI_INIT, 426a2968aaSIlan Elias NCI_UP, 4338f04c6bSIlan Elias NCI_DATA_EXCHANGE, 44c4bf98b2SIlan Elias NCI_DATA_EXCHANGE_TO, 456a2968aaSIlan Elias }; 466a2968aaSIlan Elias 478939e47fSIlan Elias /* NCI device states */ 488939e47fSIlan Elias enum nci_state { 498939e47fSIlan Elias NCI_IDLE, 508939e47fSIlan Elias NCI_DISCOVERY, 51019c4fbaSIlan Elias NCI_W4_ALL_DISCOVERIES, 52019c4fbaSIlan Elias NCI_W4_HOST_SELECT, 538939e47fSIlan Elias NCI_POLL_ACTIVE, 54a99903ecSJulien Lefrique NCI_LISTEN_ACTIVE, 55a99903ecSJulien Lefrique NCI_LISTEN_SLEEP, 568939e47fSIlan Elias }; 578939e47fSIlan Elias 586a2968aaSIlan Elias /* NCI timeouts */ 596a2968aaSIlan Elias #define NCI_RESET_TIMEOUT 5000 606a2968aaSIlan Elias #define NCI_INIT_TIMEOUT 5000 617e035230SIlan Elias #define NCI_SET_CONFIG_TIMEOUT 5000 626a2968aaSIlan Elias #define NCI_RF_DISC_TIMEOUT 5000 63019c4fbaSIlan Elias #define NCI_RF_DISC_SELECT_TIMEOUT 5000 6411ee5158SIlan Elias #define NCI_RF_DEACTIVATE_TIMEOUT 30000 656a2968aaSIlan Elias #define NCI_CMD_TIMEOUT 5000 66c4bf98b2SIlan Elias #define NCI_DATA_TIMEOUT 700 676a2968aaSIlan Elias 686a2968aaSIlan Elias struct nci_dev; 696a2968aaSIlan Elias 7022e4bd09SRobert Dolca struct nci_driver_ops { 71b6355e97SSamuel Ortiz __u16 opcode; 72b6355e97SSamuel Ortiz int (*rsp)(struct nci_dev *dev, struct sk_buff *skb); 73b6355e97SSamuel Ortiz int (*ntf)(struct nci_dev *dev, struct sk_buff *skb); 74b6355e97SSamuel Ortiz }; 75b6355e97SSamuel Ortiz 766a2968aaSIlan Elias struct nci_ops { 77c39daeeeSChristophe Ricard int (*init)(struct nci_dev *ndev); 786a2968aaSIlan Elias int (*open)(struct nci_dev *ndev); 796a2968aaSIlan Elias int (*close)(struct nci_dev *ndev); 801095e69fSFrederic Danis int (*send)(struct nci_dev *ndev, struct sk_buff *skb); 8186e8586eSAmitkumar Karwar int (*setup)(struct nci_dev *ndev); 82fdf79bd4SRobert Baldyga int (*post_setup)(struct nci_dev *ndev); 8325af01edSClément Perrochaud int (*fw_download)(struct nci_dev *ndev, const char *firmware_name); 849e87f9a9SChristophe Ricard __u32 (*get_rfprotocol)(struct nci_dev *ndev, __u8 rf_protocol); 85ba4db551SChristophe Ricard int (*discover_se)(struct nci_dev *ndev); 86e9ef9431SChristophe Ricard int (*disable_se)(struct nci_dev *ndev, u32 se_idx); 8793bca2bfSChristophe Ricard int (*enable_se)(struct nci_dev *ndev, u32 se_idx); 88a688bf55SChristophe Ricard int (*se_io)(struct nci_dev *ndev, u32 se_idx, 89a688bf55SChristophe Ricard u8 *apdu, size_t apdu_length, 90a688bf55SChristophe Ricard se_io_cb_t cb, void *cb_context); 9111f54f22SChristophe Ricard int (*hci_load_session)(struct nci_dev *ndev); 9211f54f22SChristophe Ricard void (*hci_event_received)(struct nci_dev *ndev, u8 pipe, u8 event, 9311f54f22SChristophe Ricard struct sk_buff *skb); 9411f54f22SChristophe Ricard void (*hci_cmd_received)(struct nci_dev *ndev, u8 pipe, u8 cmd, 9511f54f22SChristophe Ricard struct sk_buff *skb); 96b6355e97SSamuel Ortiz 9722e4bd09SRobert Dolca struct nci_driver_ops *prop_ops; 98b6355e97SSamuel Ortiz size_t n_prop_ops; 990a97a3cbSRobert Dolca 10022e4bd09SRobert Dolca struct nci_driver_ops *core_ops; 1010a97a3cbSRobert Dolca size_t n_core_ops; 1026a2968aaSIlan Elias }; 1036a2968aaSIlan Elias 1046a2968aaSIlan Elias #define NCI_MAX_SUPPORTED_RF_INTERFACES 4 105019c4fbaSIlan Elias #define NCI_MAX_DISCOVERED_TARGETS 10 1064aeee687SChristophe Ricard #define NCI_MAX_NUM_NFCEE 255 1074aeee687SChristophe Ricard #define NCI_MAX_CONN_ID 7 108b6355e97SSamuel Ortiz #define NCI_MAX_PROPRIETARY_CMD 64 1094aeee687SChristophe Ricard 1104aeee687SChristophe Ricard struct nci_conn_info { 1114aeee687SChristophe Ricard struct list_head list; 1124aeee687SChristophe Ricard __u8 id; /* can be an RF Discovery ID or an NFCEE ID */ 1134aeee687SChristophe Ricard __u8 conn_id; 1144aeee687SChristophe Ricard __u8 max_pkt_payload_len; 1154aeee687SChristophe Ricard 1164aeee687SChristophe Ricard atomic_t credits_cnt; 1174aeee687SChristophe Ricard __u8 initial_num_credits; 1184aeee687SChristophe Ricard 1194aeee687SChristophe Ricard data_exchange_cb_t data_exchange_cb; 1204aeee687SChristophe Ricard void *data_exchange_cb_context; 1214aeee687SChristophe Ricard 1224aeee687SChristophe Ricard struct sk_buff *rx_skb; 1234aeee687SChristophe Ricard }; 1246a2968aaSIlan Elias 125af9c8aa6SChristophe Ricard #define NCI_INVALID_CONN_ID 0x80 126af9c8aa6SChristophe Ricard 12711f54f22SChristophe Ricard #define NCI_HCI_ANY_OPEN_PIPE 0x03 12811f54f22SChristophe Ricard 12911f54f22SChristophe Ricard /* Gates */ 13011f54f22SChristophe Ricard #define NCI_HCI_ADMIN_GATE 0x00 131b1fa4dc4SChristophe Ricard #define NCI_HCI_LOOPBACK_GATE 0x04 1327e357404SChristophe Ricard #define NCI_HCI_IDENTITY_MGMT_GATE 0x05 13311f54f22SChristophe Ricard #define NCI_HCI_LINK_MGMT_GATE 0x06 13411f54f22SChristophe Ricard 13511f54f22SChristophe Ricard /* Pipes */ 13611f54f22SChristophe Ricard #define NCI_HCI_LINK_MGMT_PIPE 0x00 13711f54f22SChristophe Ricard #define NCI_HCI_ADMIN_PIPE 0x01 13811f54f22SChristophe Ricard 13911f54f22SChristophe Ricard /* Generic responses */ 14011f54f22SChristophe Ricard #define NCI_HCI_ANY_OK 0x00 14111f54f22SChristophe Ricard #define NCI_HCI_ANY_E_NOT_CONNECTED 0x01 14211f54f22SChristophe Ricard #define NCI_HCI_ANY_E_CMD_PAR_UNKNOWN 0x02 14311f54f22SChristophe Ricard #define NCI_HCI_ANY_E_NOK 0x03 14411f54f22SChristophe Ricard #define NCI_HCI_ANY_E_PIPES_FULL 0x04 14511f54f22SChristophe Ricard #define NCI_HCI_ANY_E_REG_PAR_UNKNOWN 0x05 14611f54f22SChristophe Ricard #define NCI_HCI_ANY_E_PIPE_NOT_OPENED 0x06 14711f54f22SChristophe Ricard #define NCI_HCI_ANY_E_CMD_NOT_SUPPORTED 0x07 14811f54f22SChristophe Ricard #define NCI_HCI_ANY_E_INHIBITED 0x08 14911f54f22SChristophe Ricard #define NCI_HCI_ANY_E_TIMEOUT 0x09 15011f54f22SChristophe Ricard #define NCI_HCI_ANY_E_REG_ACCESS_DENIED 0x0a 15111f54f22SChristophe Ricard #define NCI_HCI_ANY_E_PIPE_ACCESS_DENIED 0x0b 15211f54f22SChristophe Ricard 15311f54f22SChristophe Ricard #define NCI_HCI_DO_NOT_OPEN_PIPE 0x81 15411f54f22SChristophe Ricard #define NCI_HCI_INVALID_PIPE 0x80 15511f54f22SChristophe Ricard #define NCI_HCI_INVALID_GATE 0xFF 15611f54f22SChristophe Ricard #define NCI_HCI_INVALID_HOST 0x80 15711f54f22SChristophe Ricard 15811f54f22SChristophe Ricard #define NCI_HCI_MAX_CUSTOM_GATES 50 1591f74f323SChristophe Ricard /* 1601f74f323SChristophe Ricard * According to specification 102 622 chapter 4.4 Pipes, 1611f74f323SChristophe Ricard * the pipe identifier is 7 bits long. 1621f74f323SChristophe Ricard */ 16311f54f22SChristophe Ricard #define NCI_HCI_MAX_PIPES 127 16411f54f22SChristophe Ricard 16511f54f22SChristophe Ricard struct nci_hci_gate { 16611f54f22SChristophe Ricard u8 gate; 16711f54f22SChristophe Ricard u8 pipe; 16811f54f22SChristophe Ricard u8 dest_host; 16911f54f22SChristophe Ricard } __packed; 17011f54f22SChristophe Ricard 17111f54f22SChristophe Ricard struct nci_hci_pipe { 17211f54f22SChristophe Ricard u8 gate; 17311f54f22SChristophe Ricard u8 host; 17411f54f22SChristophe Ricard } __packed; 17511f54f22SChristophe Ricard 17611f54f22SChristophe Ricard struct nci_hci_init_data { 17711f54f22SChristophe Ricard u8 gate_count; 17811f54f22SChristophe Ricard struct nci_hci_gate gates[NCI_HCI_MAX_CUSTOM_GATES]; 17911f54f22SChristophe Ricard char session_id[9]; 18011f54f22SChristophe Ricard }; 18111f54f22SChristophe Ricard 18211f54f22SChristophe Ricard #define NCI_HCI_MAX_GATES 256 18311f54f22SChristophe Ricard 18411f54f22SChristophe Ricard struct nci_hci_dev { 18515d4a8daSChristophe Ricard u8 nfcee_id; 18611f54f22SChristophe Ricard struct nci_dev *ndev; 18711f54f22SChristophe Ricard struct nci_conn_info *conn_info; 18811f54f22SChristophe Ricard 18911f54f22SChristophe Ricard struct nci_hci_init_data init_data; 19011f54f22SChristophe Ricard struct nci_hci_pipe pipes[NCI_HCI_MAX_PIPES]; 19111f54f22SChristophe Ricard u8 gate2pipe[NCI_HCI_MAX_GATES]; 19211f54f22SChristophe Ricard int expected_pipes; 19311f54f22SChristophe Ricard int count_pipes; 19411f54f22SChristophe Ricard 19511f54f22SChristophe Ricard struct sk_buff_head rx_hcp_frags; 19611f54f22SChristophe Ricard struct work_struct msg_rx_work; 19711f54f22SChristophe Ricard struct sk_buff_head msg_rx_queue; 19811f54f22SChristophe Ricard }; 19911f54f22SChristophe Ricard 2006a2968aaSIlan Elias /* NCI Core structures */ 2016a2968aaSIlan Elias struct nci_dev { 2026a2968aaSIlan Elias struct nfc_dev *nfc_dev; 2036a2968aaSIlan Elias struct nci_ops *ops; 20411f54f22SChristophe Ricard struct nci_hci_dev *hci_dev; 2056a2968aaSIlan Elias 2066a2968aaSIlan Elias int tx_headroom; 2076a2968aaSIlan Elias int tx_tailroom; 2086a2968aaSIlan Elias 2098939e47fSIlan Elias atomic_t state; 2106a2968aaSIlan Elias unsigned long flags; 2116a2968aaSIlan Elias 2126a2968aaSIlan Elias atomic_t cmd_cnt; 2134aeee687SChristophe Ricard __u8 cur_conn_id; 2144aeee687SChristophe Ricard 2154aeee687SChristophe Ricard struct list_head conn_info_list; 21612bdf27dSChristophe Ricard struct nci_conn_info *rf_conn_info; 2176a2968aaSIlan Elias 2186a2968aaSIlan Elias struct timer_list cmd_timer; 219c4bf98b2SIlan Elias struct timer_list data_timer; 2206a2968aaSIlan Elias 2216a2968aaSIlan Elias struct workqueue_struct *cmd_wq; 2226a2968aaSIlan Elias struct work_struct cmd_work; 2236a2968aaSIlan Elias 2246a2968aaSIlan Elias struct workqueue_struct *rx_wq; 2256a2968aaSIlan Elias struct work_struct rx_work; 2266a2968aaSIlan Elias 2276a2968aaSIlan Elias struct workqueue_struct *tx_wq; 2286a2968aaSIlan Elias struct work_struct tx_work; 2296a2968aaSIlan Elias 2306a2968aaSIlan Elias struct sk_buff_head cmd_q; 2316a2968aaSIlan Elias struct sk_buff_head rx_q; 2326a2968aaSIlan Elias struct sk_buff_head tx_q; 2336a2968aaSIlan Elias 2346a2968aaSIlan Elias struct mutex req_lock; 2356a2968aaSIlan Elias struct completion req_completion; 2366a2968aaSIlan Elias __u32 req_status; 2376a2968aaSIlan Elias __u32 req_result; 2386a2968aaSIlan Elias 2396a2968aaSIlan Elias void *driver_data; 2406a2968aaSIlan Elias 2416a2968aaSIlan Elias __u32 poll_prots; 2426a2968aaSIlan Elias __u32 target_active_prot; 2436a2968aaSIlan Elias 244019c4fbaSIlan Elias struct nfc_target targets[NCI_MAX_DISCOVERED_TARGETS]; 245019c4fbaSIlan Elias int n_targets; 246019c4fbaSIlan Elias 2476a2968aaSIlan Elias /* received during NCI_OP_CORE_RESET_RSP */ 2486a2968aaSIlan Elias __u8 nci_ver; 2496a2968aaSIlan Elias 2506a2968aaSIlan Elias /* received during NCI_OP_CORE_INIT_RSP */ 2516a2968aaSIlan Elias __u32 nfcc_features; 2526a2968aaSIlan Elias __u8 num_supported_rf_interfaces; 2536a2968aaSIlan Elias __u8 supported_rf_interfaces 2546a2968aaSIlan Elias [NCI_MAX_SUPPORTED_RF_INTERFACES]; 2556a2968aaSIlan Elias __u8 max_logical_connections; 2566a2968aaSIlan Elias __u16 max_routing_table_size; 257e8c0dacdSIlan Elias __u8 max_ctrl_pkt_payload_len; 258e8c0dacdSIlan Elias __u16 max_size_for_large_params; 259e8c0dacdSIlan Elias __u8 manufact_id; 260e8c0dacdSIlan Elias __u32 manufact_specific_info; 2616a2968aaSIlan Elias 2624aeee687SChristophe Ricard /* Save RF Discovery ID or NFCEE ID under conn_create */ 2634aeee687SChristophe Ricard __u8 cur_id; 264637d85a7SIlan Elias 2656a2968aaSIlan Elias /* stored during nci_data_exchange */ 2666a2968aaSIlan Elias struct sk_buff *rx_data_reassembly; 267767f19aeSIlan Elias 268767f19aeSIlan Elias /* stored during intf_activated_ntf */ 269767f19aeSIlan Elias __u8 remote_gb[NFC_MAX_GT_LEN]; 270767f19aeSIlan Elias __u8 remote_gb_len; 2716a2968aaSIlan Elias }; 2726a2968aaSIlan Elias 2736a2968aaSIlan Elias /* ----- NCI Devices ----- */ 2746a2968aaSIlan Elias struct nci_dev *nci_allocate_device(struct nci_ops *ops, 2756a2968aaSIlan Elias __u32 supported_protocols, 2766a2968aaSIlan Elias int tx_headroom, 2776a2968aaSIlan Elias int tx_tailroom); 2786a2968aaSIlan Elias void nci_free_device(struct nci_dev *ndev); 2796a2968aaSIlan Elias int nci_register_device(struct nci_dev *ndev); 2806a2968aaSIlan Elias void nci_unregister_device(struct nci_dev *ndev); 28111f54f22SChristophe Ricard int nci_request(struct nci_dev *ndev, 28211f54f22SChristophe Ricard void (*req)(struct nci_dev *ndev, 28311f54f22SChristophe Ricard unsigned long opt), 28411f54f22SChristophe Ricard unsigned long opt, __u32 timeout); 285759afb8dSChristophe Ricard int nci_prop_cmd(struct nci_dev *ndev, __u8 oid, size_t len, __u8 *payload); 2867bc4824eSRobert Dolca int nci_core_cmd(struct nci_dev *ndev, __u16 opcode, size_t len, __u8 *payload); 287025a0cb8SRobert Baldyga int nci_core_reset(struct nci_dev *ndev); 288025a0cb8SRobert Baldyga int nci_core_init(struct nci_dev *ndev); 289759afb8dSChristophe Ricard 2901095e69fSFrederic Danis int nci_recv_frame(struct nci_dev *ndev, struct sk_buff *skb); 29122c15bf3SAmitkumar Karwar int nci_set_config(struct nci_dev *ndev, __u8 id, size_t len, __u8 *val); 2926a2968aaSIlan Elias 293af9c8aa6SChristophe Ricard int nci_nfcee_discover(struct nci_dev *ndev, u8 action); 294f7f793f3SChristophe Ricard int nci_nfcee_mode_set(struct nci_dev *ndev, u8 nfcee_id, u8 nfcee_mode); 295b16ae716SChristophe Ricard int nci_core_conn_create(struct nci_dev *ndev, u8 destination_type, 296b16ae716SChristophe Ricard u8 number_destination_params, 297b16ae716SChristophe Ricard size_t params_len, 298736bb957SChristophe Ricard struct core_conn_create_dest_spec_params *params); 299736bb957SChristophe Ricard int nci_core_conn_close(struct nci_dev *ndev, u8 conn_id); 300af9c8aa6SChristophe Ricard 30111f54f22SChristophe Ricard struct nci_hci_dev *nci_hci_allocate(struct nci_dev *ndev); 30211f54f22SChristophe Ricard int nci_hci_send_event(struct nci_dev *ndev, u8 gate, u8 event, 30311f54f22SChristophe Ricard const u8 *param, size_t param_len); 30411f54f22SChristophe Ricard int nci_hci_send_cmd(struct nci_dev *ndev, u8 gate, 30511f54f22SChristophe Ricard u8 cmd, const u8 *param, size_t param_len, 30611f54f22SChristophe Ricard struct sk_buff **skb); 30711f54f22SChristophe Ricard int nci_hci_open_pipe(struct nci_dev *ndev, u8 pipe); 30811f54f22SChristophe Ricard int nci_hci_connect_gate(struct nci_dev *ndev, u8 dest_host, 30911f54f22SChristophe Ricard u8 dest_gate, u8 pipe); 31011f54f22SChristophe Ricard int nci_hci_set_param(struct nci_dev *ndev, u8 gate, u8 idx, 31111f54f22SChristophe Ricard const u8 *param, size_t param_len); 31211f54f22SChristophe Ricard int nci_hci_get_param(struct nci_dev *ndev, u8 gate, u8 idx, 31311f54f22SChristophe Ricard struct sk_buff **skb); 314fa6fbadeSChristophe Ricard int nci_hci_clear_all_pipes(struct nci_dev *ndev); 31511f54f22SChristophe Ricard int nci_hci_dev_session_init(struct nci_dev *ndev); 31611f54f22SChristophe Ricard 3176a2968aaSIlan Elias static inline struct sk_buff *nci_skb_alloc(struct nci_dev *ndev, 3186a2968aaSIlan Elias unsigned int len, 3196a2968aaSIlan Elias gfp_t how) 3206a2968aaSIlan Elias { 3216a2968aaSIlan Elias struct sk_buff *skb; 3226a2968aaSIlan Elias 3236a2968aaSIlan Elias skb = alloc_skb(len + ndev->tx_headroom + ndev->tx_tailroom, how); 3246a2968aaSIlan Elias if (skb) 3256a2968aaSIlan Elias skb_reserve(skb, ndev->tx_headroom); 3266a2968aaSIlan Elias 3276a2968aaSIlan Elias return skb; 3286a2968aaSIlan Elias } 3296a2968aaSIlan Elias 3306a2968aaSIlan Elias static inline void nci_set_parent_dev(struct nci_dev *ndev, struct device *dev) 3316a2968aaSIlan Elias { 3326a2968aaSIlan Elias nfc_set_parent_dev(ndev->nfc_dev, dev); 3336a2968aaSIlan Elias } 3346a2968aaSIlan Elias 3356a2968aaSIlan Elias static inline void nci_set_drvdata(struct nci_dev *ndev, void *data) 3366a2968aaSIlan Elias { 3376a2968aaSIlan Elias ndev->driver_data = data; 3386a2968aaSIlan Elias } 3396a2968aaSIlan Elias 3406a2968aaSIlan Elias static inline void *nci_get_drvdata(struct nci_dev *ndev) 3416a2968aaSIlan Elias { 3426a2968aaSIlan Elias return ndev->driver_data; 3436a2968aaSIlan Elias } 3446a2968aaSIlan Elias 3458115dd59SSamuel Ortiz static inline int nci_set_vendor_cmds(struct nci_dev *ndev, 3468115dd59SSamuel Ortiz struct nfc_vendor_cmd *cmds, 3478115dd59SSamuel Ortiz int n_cmds) 3488115dd59SSamuel Ortiz { 3498115dd59SSamuel Ortiz return nfc_set_vendor_cmds(ndev->nfc_dev, cmds, n_cmds); 3508115dd59SSamuel Ortiz } 3518115dd59SSamuel Ortiz 3526a2968aaSIlan Elias void nci_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb); 3536a2968aaSIlan Elias void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb); 3540a97a3cbSRobert Dolca inline int nci_prop_rsp_packet(struct nci_dev *ndev, __u16 opcode, 355b6355e97SSamuel Ortiz struct sk_buff *skb); 3560a97a3cbSRobert Dolca inline int nci_prop_ntf_packet(struct nci_dev *ndev, __u16 opcode, 3570a97a3cbSRobert Dolca struct sk_buff *skb); 3580a97a3cbSRobert Dolca inline int nci_core_rsp_packet(struct nci_dev *ndev, __u16 opcode, 3590a97a3cbSRobert Dolca struct sk_buff *skb); 3600a97a3cbSRobert Dolca inline int nci_core_ntf_packet(struct nci_dev *ndev, __u16 opcode, 361b6355e97SSamuel Ortiz struct sk_buff *skb); 3626a2968aaSIlan Elias void nci_rx_data_packet(struct nci_dev *ndev, struct sk_buff *skb); 3636a2968aaSIlan Elias int nci_send_cmd(struct nci_dev *ndev, __u16 opcode, __u8 plen, void *payload); 3646a2968aaSIlan Elias int nci_send_data(struct nci_dev *ndev, __u8 conn_id, struct sk_buff *skb); 3652663589cSRobert Dolca int nci_conn_max_data_pkt_payload_size(struct nci_dev *ndev, __u8 conn_id); 3666a2968aaSIlan Elias void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb, 3674aeee687SChristophe Ricard __u8 conn_id, int err); 36811f54f22SChristophe Ricard void nci_hci_data_received_cb(void *context, struct sk_buff *skb, int err); 36911f54f22SChristophe Ricard 370019c4fbaSIlan Elias void nci_clear_target_list(struct nci_dev *ndev); 3716a2968aaSIlan Elias 3726a2968aaSIlan Elias /* ----- NCI requests ----- */ 3736a2968aaSIlan Elias #define NCI_REQ_DONE 0 3746a2968aaSIlan Elias #define NCI_REQ_PEND 1 3756a2968aaSIlan Elias #define NCI_REQ_CANCELED 2 3766a2968aaSIlan Elias 3776a2968aaSIlan Elias void nci_req_complete(struct nci_dev *ndev, int result); 3784aeee687SChristophe Ricard struct nci_conn_info *nci_get_conn_info_by_conn_id(struct nci_dev *ndev, 3794aeee687SChristophe Ricard int conn_id); 38085b9ce9aSRobert Dolca int nci_get_conn_info_by_id(struct nci_dev *ndev, u8 id); 3816a2968aaSIlan Elias 3826a2968aaSIlan Elias /* ----- NCI status code ----- */ 3836a2968aaSIlan Elias int nci_to_errno(__u8 code); 3846a2968aaSIlan Elias 3858a00a61bSFrederic Danis /* ----- NCI over SPI acknowledge modes ----- */ 3868a00a61bSFrederic Danis #define NCI_SPI_CRC_DISABLED 0x00 3878a00a61bSFrederic Danis #define NCI_SPI_CRC_ENABLED 0x01 3888a00a61bSFrederic Danis 3898a00a61bSFrederic Danis /* ----- NCI SPI structures ----- */ 390fa544fffSEric Lapuyade struct nci_spi { 391d5937511SEric Lapuyade struct nci_dev *ndev; 3928a00a61bSFrederic Danis struct spi_device *spi; 3938a00a61bSFrederic Danis 3948a00a61bSFrederic Danis unsigned int xfer_udelay; /* microseconds delay between 3958a00a61bSFrederic Danis transactions */ 3968a00a61bSFrederic Danis u8 acknowledge_mode; 3978a00a61bSFrederic Danis 398ee9596d4SFrederic Danis struct completion req_completion; 399ee9596d4SFrederic Danis u8 req_result; 4008a00a61bSFrederic Danis }; 4018a00a61bSFrederic Danis 402fa544fffSEric Lapuyade /* ----- NCI SPI ----- */ 403fa544fffSEric Lapuyade struct nci_spi *nci_spi_allocate_spi(struct spi_device *spi, 404fa544fffSEric Lapuyade u8 acknowledge_mode, unsigned int delay, 405fa544fffSEric Lapuyade struct nci_dev *ndev); 4062bed2785SEric Lapuyade int nci_spi_send(struct nci_spi *nspi, 4072bed2785SEric Lapuyade struct completion *write_handshake_completion, 4082bed2785SEric Lapuyade struct sk_buff *skb); 40922d4aae5SEric Lapuyade struct sk_buff *nci_spi_read(struct nci_spi *nspi); 4108a00a61bSFrederic Danis 4119961127dSVincent Cuissard /* ----- NCI UART ---- */ 4129961127dSVincent Cuissard 4139961127dSVincent Cuissard /* Ioctl */ 4149961127dSVincent Cuissard #define NCIUARTSETDRIVER _IOW('U', 0, char *) 4159961127dSVincent Cuissard 4169961127dSVincent Cuissard enum nci_uart_driver { 4179961127dSVincent Cuissard NCI_UART_DRIVER_MARVELL = 0, 4189961127dSVincent Cuissard NCI_UART_DRIVER_MAX 4199961127dSVincent Cuissard }; 4209961127dSVincent Cuissard 4219961127dSVincent Cuissard struct nci_uart; 4229961127dSVincent Cuissard 4239961127dSVincent Cuissard struct nci_uart_ops { 4249961127dSVincent Cuissard int (*open)(struct nci_uart *nci_uart); 4259961127dSVincent Cuissard void (*close)(struct nci_uart *nci_uart); 4269961127dSVincent Cuissard int (*recv)(struct nci_uart *nci_uart, struct sk_buff *skb); 4279961127dSVincent Cuissard int (*recv_buf)(struct nci_uart *nci_uart, const u8 *data, char *flags, 4289961127dSVincent Cuissard int count); 4299961127dSVincent Cuissard int (*send)(struct nci_uart *nci_uart, struct sk_buff *skb); 4309961127dSVincent Cuissard void (*tx_start)(struct nci_uart *nci_uart); 4319961127dSVincent Cuissard void (*tx_done)(struct nci_uart *nci_uart); 4329961127dSVincent Cuissard }; 4339961127dSVincent Cuissard 4349961127dSVincent Cuissard struct nci_uart { 4359961127dSVincent Cuissard struct module *owner; 4369961127dSVincent Cuissard struct nci_uart_ops ops; 4379961127dSVincent Cuissard const char *name; 4389961127dSVincent Cuissard enum nci_uart_driver driver; 4399961127dSVincent Cuissard 4409961127dSVincent Cuissard /* Dynamic data */ 4419961127dSVincent Cuissard struct nci_dev *ndev; 4429961127dSVincent Cuissard spinlock_t rx_lock; 4439961127dSVincent Cuissard struct work_struct write_work; 4449961127dSVincent Cuissard struct tty_struct *tty; 4459961127dSVincent Cuissard unsigned long tx_state; 4469961127dSVincent Cuissard struct sk_buff_head tx_q; 4479961127dSVincent Cuissard struct sk_buff *tx_skb; 4489961127dSVincent Cuissard struct sk_buff *rx_skb; 4499961127dSVincent Cuissard int rx_packet_len; 4509961127dSVincent Cuissard void *drv_data; 4519961127dSVincent Cuissard }; 4529961127dSVincent Cuissard 4539961127dSVincent Cuissard int nci_uart_register(struct nci_uart *nu); 4549961127dSVincent Cuissard void nci_uart_unregister(struct nci_uart *nu); 4559961127dSVincent Cuissard void nci_uart_set_config(struct nci_uart *nu, int baudrate, int flow_ctrl); 4569961127dSVincent Cuissard 4576a2968aaSIlan Elias #endif /* __NCI_CORE_H */ 458