1caab277bSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
26a2968aaSIlan Elias /*
36a2968aaSIlan Elias * The NFC Controller Interface is the communication protocol between an
46a2968aaSIlan Elias * NFC Controller (NFCC) and a Device Host (DH).
56a2968aaSIlan Elias *
66a2968aaSIlan Elias * Copyright (C) 2011 Texas Instruments, Inc.
78a00a61bSFrederic Danis * Copyright (C) 2013 Intel Corporation. All rights reserved.
8a99903ecSJulien Lefrique * Copyright (C) 2014 Marvell International Ltd.
96a2968aaSIlan Elias *
106a2968aaSIlan Elias * Written by Ilan Elias <ilane@ti.com>
116a2968aaSIlan Elias *
126a2968aaSIlan Elias * Acknowledgements:
136a2968aaSIlan Elias * This file is based on hci_core.h, which was written
146a2968aaSIlan Elias * by Maxim Krasnyansky.
156a2968aaSIlan Elias */
166a2968aaSIlan Elias
176a2968aaSIlan Elias #ifndef __NCI_CORE_H
186a2968aaSIlan Elias #define __NCI_CORE_H
196a2968aaSIlan Elias
206a2968aaSIlan Elias #include <linux/interrupt.h>
216a2968aaSIlan Elias #include <linux/skbuff.h>
229961127dSVincent Cuissard #include <linux/tty.h>
236a2968aaSIlan Elias
246a2968aaSIlan Elias #include <net/nfc/nfc.h>
256a2968aaSIlan Elias #include <net/nfc/nci.h>
266a2968aaSIlan Elias
278939e47fSIlan Elias /* NCI device flags */
288939e47fSIlan Elias enum nci_flag {
296a2968aaSIlan Elias NCI_INIT,
306a2968aaSIlan Elias NCI_UP,
3138f04c6bSIlan Elias NCI_DATA_EXCHANGE,
32c4bf98b2SIlan Elias NCI_DATA_EXCHANGE_TO,
33*48b71a9eSLin Ma NCI_UNREG,
346a2968aaSIlan Elias };
356a2968aaSIlan Elias
368939e47fSIlan Elias /* NCI device states */
378939e47fSIlan Elias enum nci_state {
388939e47fSIlan Elias NCI_IDLE,
398939e47fSIlan Elias NCI_DISCOVERY,
40019c4fbaSIlan Elias NCI_W4_ALL_DISCOVERIES,
41019c4fbaSIlan Elias NCI_W4_HOST_SELECT,
428939e47fSIlan Elias NCI_POLL_ACTIVE,
43a99903ecSJulien Lefrique NCI_LISTEN_ACTIVE,
44a99903ecSJulien Lefrique NCI_LISTEN_SLEEP,
458939e47fSIlan Elias };
468939e47fSIlan Elias
476a2968aaSIlan Elias /* NCI timeouts */
486a2968aaSIlan Elias #define NCI_RESET_TIMEOUT 5000
496a2968aaSIlan Elias #define NCI_INIT_TIMEOUT 5000
507e035230SIlan Elias #define NCI_SET_CONFIG_TIMEOUT 5000
516a2968aaSIlan Elias #define NCI_RF_DISC_TIMEOUT 5000
52019c4fbaSIlan Elias #define NCI_RF_DISC_SELECT_TIMEOUT 5000
5311ee5158SIlan Elias #define NCI_RF_DEACTIVATE_TIMEOUT 30000
546a2968aaSIlan Elias #define NCI_CMD_TIMEOUT 5000
55c4bf98b2SIlan Elias #define NCI_DATA_TIMEOUT 700
566a2968aaSIlan Elias
576a2968aaSIlan Elias struct nci_dev;
586a2968aaSIlan Elias
5922e4bd09SRobert Dolca struct nci_driver_ops {
60b6355e97SSamuel Ortiz __u16 opcode;
61b6355e97SSamuel Ortiz int (*rsp)(struct nci_dev *dev, struct sk_buff *skb);
62b6355e97SSamuel Ortiz int (*ntf)(struct nci_dev *dev, struct sk_buff *skb);
63b6355e97SSamuel Ortiz };
64b6355e97SSamuel Ortiz
656a2968aaSIlan Elias struct nci_ops {
66c39daeeeSChristophe Ricard int (*init)(struct nci_dev *ndev);
676a2968aaSIlan Elias int (*open)(struct nci_dev *ndev);
686a2968aaSIlan Elias int (*close)(struct nci_dev *ndev);
691095e69fSFrederic Danis int (*send)(struct nci_dev *ndev, struct sk_buff *skb);
7086e8586eSAmitkumar Karwar int (*setup)(struct nci_dev *ndev);
71fdf79bd4SRobert Baldyga int (*post_setup)(struct nci_dev *ndev);
7225af01edSClément Perrochaud int (*fw_download)(struct nci_dev *ndev, const char *firmware_name);
739e87f9a9SChristophe Ricard __u32 (*get_rfprotocol)(struct nci_dev *ndev, __u8 rf_protocol);
74ba4db551SChristophe Ricard int (*discover_se)(struct nci_dev *ndev);
75e9ef9431SChristophe Ricard int (*disable_se)(struct nci_dev *ndev, u32 se_idx);
7693bca2bfSChristophe Ricard int (*enable_se)(struct nci_dev *ndev, u32 se_idx);
77a688bf55SChristophe Ricard int (*se_io)(struct nci_dev *ndev, u32 se_idx,
78a688bf55SChristophe Ricard u8 *apdu, size_t apdu_length,
79a688bf55SChristophe Ricard se_io_cb_t cb, void *cb_context);
8011f54f22SChristophe Ricard int (*hci_load_session)(struct nci_dev *ndev);
8111f54f22SChristophe Ricard void (*hci_event_received)(struct nci_dev *ndev, u8 pipe, u8 event,
8211f54f22SChristophe Ricard struct sk_buff *skb);
8311f54f22SChristophe Ricard void (*hci_cmd_received)(struct nci_dev *ndev, u8 pipe, u8 cmd,
8411f54f22SChristophe Ricard struct sk_buff *skb);
85b6355e97SSamuel Ortiz
86cb8caa3cSKrzysztof Kozlowski const struct nci_driver_ops *prop_ops;
87b6355e97SSamuel Ortiz size_t n_prop_ops;
880a97a3cbSRobert Dolca
89cb8caa3cSKrzysztof Kozlowski const struct nci_driver_ops *core_ops;
900a97a3cbSRobert Dolca size_t n_core_ops;
916a2968aaSIlan Elias };
926a2968aaSIlan Elias
936a2968aaSIlan Elias #define NCI_MAX_SUPPORTED_RF_INTERFACES 4
94019c4fbaSIlan Elias #define NCI_MAX_DISCOVERED_TARGETS 10
954aeee687SChristophe Ricard #define NCI_MAX_NUM_NFCEE 255
964aeee687SChristophe Ricard #define NCI_MAX_CONN_ID 7
97b6355e97SSamuel Ortiz #define NCI_MAX_PROPRIETARY_CMD 64
984aeee687SChristophe Ricard
994aeee687SChristophe Ricard struct nci_conn_info {
1004aeee687SChristophe Ricard struct list_head list;
1019b8d1a4cSChristophe Ricard /* NCI specification 4.4.2 Connection Creation
1029b8d1a4cSChristophe Ricard * The combination of destination type and destination specific
1039b8d1a4cSChristophe Ricard * parameters shall uniquely identify a single destination for the
1049b8d1a4cSChristophe Ricard * Logical Connection
1059b8d1a4cSChristophe Ricard */
1069b8d1a4cSChristophe Ricard struct dest_spec_params *dest_params;
1079b8d1a4cSChristophe Ricard __u8 dest_type;
1084aeee687SChristophe Ricard __u8 conn_id;
1094aeee687SChristophe Ricard __u8 max_pkt_payload_len;
1104aeee687SChristophe Ricard
1114aeee687SChristophe Ricard atomic_t credits_cnt;
1124aeee687SChristophe Ricard __u8 initial_num_credits;
1134aeee687SChristophe Ricard
1144aeee687SChristophe Ricard data_exchange_cb_t data_exchange_cb;
1154aeee687SChristophe Ricard void *data_exchange_cb_context;
1164aeee687SChristophe Ricard
1174aeee687SChristophe Ricard struct sk_buff *rx_skb;
1184aeee687SChristophe Ricard };
1196a2968aaSIlan Elias
120af9c8aa6SChristophe Ricard #define NCI_INVALID_CONN_ID 0x80
121af9c8aa6SChristophe Ricard
12211f54f22SChristophe Ricard #define NCI_HCI_ANY_OPEN_PIPE 0x03
12311f54f22SChristophe Ricard
12411f54f22SChristophe Ricard /* Gates */
12511f54f22SChristophe Ricard #define NCI_HCI_ADMIN_GATE 0x00
126b1fa4dc4SChristophe Ricard #define NCI_HCI_LOOPBACK_GATE 0x04
1277e357404SChristophe Ricard #define NCI_HCI_IDENTITY_MGMT_GATE 0x05
12811f54f22SChristophe Ricard #define NCI_HCI_LINK_MGMT_GATE 0x06
12911f54f22SChristophe Ricard
13011f54f22SChristophe Ricard /* Pipes */
13111f54f22SChristophe Ricard #define NCI_HCI_LINK_MGMT_PIPE 0x00
13211f54f22SChristophe Ricard #define NCI_HCI_ADMIN_PIPE 0x01
13311f54f22SChristophe Ricard
13411f54f22SChristophe Ricard /* Generic responses */
13511f54f22SChristophe Ricard #define NCI_HCI_ANY_OK 0x00
13611f54f22SChristophe Ricard #define NCI_HCI_ANY_E_NOT_CONNECTED 0x01
13711f54f22SChristophe Ricard #define NCI_HCI_ANY_E_CMD_PAR_UNKNOWN 0x02
13811f54f22SChristophe Ricard #define NCI_HCI_ANY_E_NOK 0x03
13911f54f22SChristophe Ricard #define NCI_HCI_ANY_E_PIPES_FULL 0x04
14011f54f22SChristophe Ricard #define NCI_HCI_ANY_E_REG_PAR_UNKNOWN 0x05
14111f54f22SChristophe Ricard #define NCI_HCI_ANY_E_PIPE_NOT_OPENED 0x06
14211f54f22SChristophe Ricard #define NCI_HCI_ANY_E_CMD_NOT_SUPPORTED 0x07
14311f54f22SChristophe Ricard #define NCI_HCI_ANY_E_INHIBITED 0x08
14411f54f22SChristophe Ricard #define NCI_HCI_ANY_E_TIMEOUT 0x09
14511f54f22SChristophe Ricard #define NCI_HCI_ANY_E_REG_ACCESS_DENIED 0x0a
14611f54f22SChristophe Ricard #define NCI_HCI_ANY_E_PIPE_ACCESS_DENIED 0x0b
14711f54f22SChristophe Ricard
14811f54f22SChristophe Ricard #define NCI_HCI_DO_NOT_OPEN_PIPE 0x81
14911f54f22SChristophe Ricard #define NCI_HCI_INVALID_PIPE 0x80
15011f54f22SChristophe Ricard #define NCI_HCI_INVALID_GATE 0xFF
15111f54f22SChristophe Ricard #define NCI_HCI_INVALID_HOST 0x80
15211f54f22SChristophe Ricard
15311f54f22SChristophe Ricard #define NCI_HCI_MAX_CUSTOM_GATES 50
1541f74f323SChristophe Ricard /*
1551f74f323SChristophe Ricard * According to specification 102 622 chapter 4.4 Pipes,
1561f74f323SChristophe Ricard * the pipe identifier is 7 bits long.
1571f74f323SChristophe Ricard */
1586491d698SDan Carpenter #define NCI_HCI_MAX_PIPES 128
15911f54f22SChristophe Ricard
16011f54f22SChristophe Ricard struct nci_hci_gate {
16111f54f22SChristophe Ricard u8 gate;
16211f54f22SChristophe Ricard u8 pipe;
16311f54f22SChristophe Ricard u8 dest_host;
16411f54f22SChristophe Ricard } __packed;
16511f54f22SChristophe Ricard
16611f54f22SChristophe Ricard struct nci_hci_pipe {
16711f54f22SChristophe Ricard u8 gate;
16811f54f22SChristophe Ricard u8 host;
16911f54f22SChristophe Ricard } __packed;
17011f54f22SChristophe Ricard
17111f54f22SChristophe Ricard struct nci_hci_init_data {
17211f54f22SChristophe Ricard u8 gate_count;
17311f54f22SChristophe Ricard struct nci_hci_gate gates[NCI_HCI_MAX_CUSTOM_GATES];
17411f54f22SChristophe Ricard char session_id[9];
17511f54f22SChristophe Ricard };
17611f54f22SChristophe Ricard
17711f54f22SChristophe Ricard #define NCI_HCI_MAX_GATES 256
17811f54f22SChristophe Ricard
17911f54f22SChristophe Ricard struct nci_hci_dev {
18015d4a8daSChristophe Ricard u8 nfcee_id;
18111f54f22SChristophe Ricard struct nci_dev *ndev;
18211f54f22SChristophe Ricard struct nci_conn_info *conn_info;
18311f54f22SChristophe Ricard
18411f54f22SChristophe Ricard struct nci_hci_init_data init_data;
18511f54f22SChristophe Ricard struct nci_hci_pipe pipes[NCI_HCI_MAX_PIPES];
18611f54f22SChristophe Ricard u8 gate2pipe[NCI_HCI_MAX_GATES];
18711f54f22SChristophe Ricard int expected_pipes;
18811f54f22SChristophe Ricard int count_pipes;
18911f54f22SChristophe Ricard
19011f54f22SChristophe Ricard struct sk_buff_head rx_hcp_frags;
19111f54f22SChristophe Ricard struct work_struct msg_rx_work;
19211f54f22SChristophe Ricard struct sk_buff_head msg_rx_queue;
19311f54f22SChristophe Ricard };
19411f54f22SChristophe Ricard
1956a2968aaSIlan Elias /* NCI Core structures */
1966a2968aaSIlan Elias struct nci_dev {
1976a2968aaSIlan Elias struct nfc_dev *nfc_dev;
198b9c28286SKrzysztof Kozlowski const struct nci_ops *ops;
19911f54f22SChristophe Ricard struct nci_hci_dev *hci_dev;
2006a2968aaSIlan Elias
2016a2968aaSIlan Elias int tx_headroom;
2026a2968aaSIlan Elias int tx_tailroom;
2036a2968aaSIlan Elias
2048939e47fSIlan Elias atomic_t state;
2056a2968aaSIlan Elias unsigned long flags;
2066a2968aaSIlan Elias
2076a2968aaSIlan Elias atomic_t cmd_cnt;
2084aeee687SChristophe Ricard __u8 cur_conn_id;
2094aeee687SChristophe Ricard
2104aeee687SChristophe Ricard struct list_head conn_info_list;
21112bdf27dSChristophe Ricard struct nci_conn_info *rf_conn_info;
2126a2968aaSIlan Elias
2136a2968aaSIlan Elias struct timer_list cmd_timer;
214c4bf98b2SIlan Elias struct timer_list data_timer;
2156a2968aaSIlan Elias
2166a2968aaSIlan Elias struct workqueue_struct *cmd_wq;
2176a2968aaSIlan Elias struct work_struct cmd_work;
2186a2968aaSIlan Elias
2196a2968aaSIlan Elias struct workqueue_struct *rx_wq;
2206a2968aaSIlan Elias struct work_struct rx_work;
2216a2968aaSIlan Elias
2226a2968aaSIlan Elias struct workqueue_struct *tx_wq;
2236a2968aaSIlan Elias struct work_struct tx_work;
2246a2968aaSIlan Elias
2256a2968aaSIlan Elias struct sk_buff_head cmd_q;
2266a2968aaSIlan Elias struct sk_buff_head rx_q;
2276a2968aaSIlan Elias struct sk_buff_head tx_q;
2286a2968aaSIlan Elias
2296a2968aaSIlan Elias struct mutex req_lock;
2306a2968aaSIlan Elias struct completion req_completion;
2316a2968aaSIlan Elias __u32 req_status;
2326a2968aaSIlan Elias __u32 req_result;
2336a2968aaSIlan Elias
2346a2968aaSIlan Elias void *driver_data;
2356a2968aaSIlan Elias
2366a2968aaSIlan Elias __u32 poll_prots;
2376a2968aaSIlan Elias __u32 target_active_prot;
2386a2968aaSIlan Elias
239019c4fbaSIlan Elias struct nfc_target targets[NCI_MAX_DISCOVERED_TARGETS];
240019c4fbaSIlan Elias int n_targets;
241019c4fbaSIlan Elias
2426a2968aaSIlan Elias /* received during NCI_OP_CORE_RESET_RSP */
2436a2968aaSIlan Elias __u8 nci_ver;
2446a2968aaSIlan Elias
2456a2968aaSIlan Elias /* received during NCI_OP_CORE_INIT_RSP */
2466a2968aaSIlan Elias __u32 nfcc_features;
2476a2968aaSIlan Elias __u8 num_supported_rf_interfaces;
2486a2968aaSIlan Elias __u8 supported_rf_interfaces
2496a2968aaSIlan Elias [NCI_MAX_SUPPORTED_RF_INTERFACES];
2506a2968aaSIlan Elias __u8 max_logical_connections;
2516a2968aaSIlan Elias __u16 max_routing_table_size;
252e8c0dacdSIlan Elias __u8 max_ctrl_pkt_payload_len;
253e8c0dacdSIlan Elias __u16 max_size_for_large_params;
254e8c0dacdSIlan Elias __u8 manufact_id;
255e8c0dacdSIlan Elias __u32 manufact_specific_info;
2566a2968aaSIlan Elias
2574aeee687SChristophe Ricard /* Save RF Discovery ID or NFCEE ID under conn_create */
2589b8d1a4cSChristophe Ricard struct dest_spec_params cur_params;
2599b8d1a4cSChristophe Ricard /* Save destination type under conn_create */
2609b8d1a4cSChristophe Ricard __u8 cur_dest_type;
261637d85a7SIlan Elias
2626a2968aaSIlan Elias /* stored during nci_data_exchange */
2636a2968aaSIlan Elias struct sk_buff *rx_data_reassembly;
264767f19aeSIlan Elias
265767f19aeSIlan Elias /* stored during intf_activated_ntf */
266767f19aeSIlan Elias __u8 remote_gb[NFC_MAX_GT_LEN];
267767f19aeSIlan Elias __u8 remote_gb_len;
2686a2968aaSIlan Elias };
2696a2968aaSIlan Elias
2706a2968aaSIlan Elias /* ----- NCI Devices ----- */
271b9c28286SKrzysztof Kozlowski struct nci_dev *nci_allocate_device(const struct nci_ops *ops,
2726a2968aaSIlan Elias __u32 supported_protocols,
2736a2968aaSIlan Elias int tx_headroom,
2746a2968aaSIlan Elias int tx_tailroom);
2756a2968aaSIlan Elias void nci_free_device(struct nci_dev *ndev);
2766a2968aaSIlan Elias int nci_register_device(struct nci_dev *ndev);
2776a2968aaSIlan Elias void nci_unregister_device(struct nci_dev *ndev);
27811f54f22SChristophe Ricard int nci_request(struct nci_dev *ndev,
27911f54f22SChristophe Ricard void (*req)(struct nci_dev *ndev,
28035d7a6f1SKrzysztof Kozlowski const void *opt),
28135d7a6f1SKrzysztof Kozlowski const void *opt, __u32 timeout);
282ddecf555SKrzysztof Kozlowski int nci_prop_cmd(struct nci_dev *ndev, __u8 oid, size_t len,
283ddecf555SKrzysztof Kozlowski const __u8 *payload);
284ddecf555SKrzysztof Kozlowski int nci_core_cmd(struct nci_dev *ndev, __u16 opcode, size_t len,
285ddecf555SKrzysztof Kozlowski const __u8 *payload);
286025a0cb8SRobert Baldyga int nci_core_reset(struct nci_dev *ndev);
287025a0cb8SRobert Baldyga int nci_core_init(struct nci_dev *ndev);
288759afb8dSChristophe Ricard
2891095e69fSFrederic Danis int nci_recv_frame(struct nci_dev *ndev, struct sk_buff *skb);
290e5629d29SVincent Cuissard int nci_send_frame(struct nci_dev *ndev, struct sk_buff *skb);
291ddecf555SKrzysztof Kozlowski int nci_set_config(struct nci_dev *ndev, __u8 id, size_t len, const __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,
298ddecf555SKrzysztof Kozlowski const struct core_conn_create_dest_spec_params *params);
299736bb957SChristophe Ricard int nci_core_conn_close(struct nci_dev *ndev, u8 conn_id);
300ddecf555SKrzysztof Kozlowski int nci_nfcc_loopback(struct nci_dev *ndev, const void *data, size_t data_len,
3011c53855fSChristophe Ricard struct sk_buff **resp);
302af9c8aa6SChristophe Ricard
30311f54f22SChristophe Ricard struct nci_hci_dev *nci_hci_allocate(struct nci_dev *ndev);
304e0652f8bSDongliang Mu void nci_hci_deallocate(struct nci_dev *ndev);
30511f54f22SChristophe Ricard int nci_hci_send_event(struct nci_dev *ndev, u8 gate, u8 event,
30611f54f22SChristophe Ricard const u8 *param, size_t param_len);
30711f54f22SChristophe Ricard int nci_hci_send_cmd(struct nci_dev *ndev, u8 gate,
30811f54f22SChristophe Ricard u8 cmd, const u8 *param, size_t param_len,
30911f54f22SChristophe Ricard struct sk_buff **skb);
31011f54f22SChristophe Ricard int nci_hci_open_pipe(struct nci_dev *ndev, u8 pipe);
31111f54f22SChristophe Ricard int nci_hci_connect_gate(struct nci_dev *ndev, u8 dest_host,
31211f54f22SChristophe Ricard u8 dest_gate, u8 pipe);
31311f54f22SChristophe Ricard int nci_hci_set_param(struct nci_dev *ndev, u8 gate, u8 idx,
31411f54f22SChristophe Ricard const u8 *param, size_t param_len);
31511f54f22SChristophe Ricard int nci_hci_get_param(struct nci_dev *ndev, u8 gate, u8 idx,
31611f54f22SChristophe Ricard struct sk_buff **skb);
317fa6fbadeSChristophe Ricard int nci_hci_clear_all_pipes(struct nci_dev *ndev);
31811f54f22SChristophe Ricard int nci_hci_dev_session_init(struct nci_dev *ndev);
31911f54f22SChristophe Ricard
nci_skb_alloc(struct nci_dev * ndev,unsigned int len,gfp_t how)3206a2968aaSIlan Elias static inline struct sk_buff *nci_skb_alloc(struct nci_dev *ndev,
3216a2968aaSIlan Elias unsigned int len,
3226a2968aaSIlan Elias gfp_t how)
3236a2968aaSIlan Elias {
3246a2968aaSIlan Elias struct sk_buff *skb;
3256a2968aaSIlan Elias
3266a2968aaSIlan Elias skb = alloc_skb(len + ndev->tx_headroom + ndev->tx_tailroom, how);
3276a2968aaSIlan Elias if (skb)
3286a2968aaSIlan Elias skb_reserve(skb, ndev->tx_headroom);
3296a2968aaSIlan Elias
3306a2968aaSIlan Elias return skb;
3316a2968aaSIlan Elias }
3326a2968aaSIlan Elias
nci_set_parent_dev(struct nci_dev * ndev,struct device * dev)3336a2968aaSIlan Elias static inline void nci_set_parent_dev(struct nci_dev *ndev, struct device *dev)
3346a2968aaSIlan Elias {
3356a2968aaSIlan Elias nfc_set_parent_dev(ndev->nfc_dev, dev);
3366a2968aaSIlan Elias }
3376a2968aaSIlan Elias
nci_set_drvdata(struct nci_dev * ndev,void * data)3386a2968aaSIlan Elias static inline void nci_set_drvdata(struct nci_dev *ndev, void *data)
3396a2968aaSIlan Elias {
3406a2968aaSIlan Elias ndev->driver_data = data;
3416a2968aaSIlan Elias }
3426a2968aaSIlan Elias
nci_get_drvdata(struct nci_dev * ndev)3436a2968aaSIlan Elias static inline void *nci_get_drvdata(struct nci_dev *ndev)
3446a2968aaSIlan Elias {
3456a2968aaSIlan Elias return ndev->driver_data;
3466a2968aaSIlan Elias }
3476a2968aaSIlan Elias
nci_set_vendor_cmds(struct nci_dev * ndev,const struct nfc_vendor_cmd * cmds,int n_cmds)3488115dd59SSamuel Ortiz static inline int nci_set_vendor_cmds(struct nci_dev *ndev,
34915944ad2SKrzysztof Kozlowski const struct nfc_vendor_cmd *cmds,
3508115dd59SSamuel Ortiz int n_cmds)
3518115dd59SSamuel Ortiz {
3528115dd59SSamuel Ortiz return nfc_set_vendor_cmds(ndev->nfc_dev, cmds, n_cmds);
3538115dd59SSamuel Ortiz }
3548115dd59SSamuel Ortiz
3556a2968aaSIlan Elias void nci_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb);
3566a2968aaSIlan Elias void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb);
357f1163174SRobert Dolca int nci_prop_rsp_packet(struct nci_dev *ndev, __u16 opcode,
358b6355e97SSamuel Ortiz struct sk_buff *skb);
359f1163174SRobert Dolca int nci_prop_ntf_packet(struct nci_dev *ndev, __u16 opcode,
3600a97a3cbSRobert Dolca struct sk_buff *skb);
361f1163174SRobert Dolca int nci_core_rsp_packet(struct nci_dev *ndev, __u16 opcode,
3620a97a3cbSRobert Dolca struct sk_buff *skb);
363f1163174SRobert Dolca int nci_core_ntf_packet(struct nci_dev *ndev, __u16 opcode,
364b6355e97SSamuel Ortiz struct sk_buff *skb);
3656a2968aaSIlan Elias void nci_rx_data_packet(struct nci_dev *ndev, struct sk_buff *skb);
36648d54403SKrzysztof Kozlowski int nci_send_cmd(struct nci_dev *ndev, __u16 opcode, __u8 plen, const void *payload);
3676a2968aaSIlan Elias int nci_send_data(struct nci_dev *ndev, __u8 conn_id, struct sk_buff *skb);
3682663589cSRobert Dolca int nci_conn_max_data_pkt_payload_size(struct nci_dev *ndev, __u8 conn_id);
3696a2968aaSIlan Elias void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb,
3704aeee687SChristophe Ricard __u8 conn_id, int err);
37111f54f22SChristophe Ricard void nci_hci_data_received_cb(void *context, struct sk_buff *skb, int err);
37211f54f22SChristophe Ricard
373019c4fbaSIlan Elias void nci_clear_target_list(struct nci_dev *ndev);
3746a2968aaSIlan Elias
3756a2968aaSIlan Elias /* ----- NCI requests ----- */
3766a2968aaSIlan Elias #define NCI_REQ_DONE 0
3776a2968aaSIlan Elias #define NCI_REQ_PEND 1
3786a2968aaSIlan Elias #define NCI_REQ_CANCELED 2
3796a2968aaSIlan Elias
3806a2968aaSIlan Elias void nci_req_complete(struct nci_dev *ndev, int result);
3814aeee687SChristophe Ricard struct nci_conn_info *nci_get_conn_info_by_conn_id(struct nci_dev *ndev,
3824aeee687SChristophe Ricard int conn_id);
3839b8d1a4cSChristophe Ricard int nci_get_conn_info_by_dest_type_params(struct nci_dev *ndev, u8 dest_type,
384ddecf555SKrzysztof Kozlowski const struct dest_spec_params *params);
3856a2968aaSIlan Elias
3866a2968aaSIlan Elias /* ----- NCI status code ----- */
3876a2968aaSIlan Elias int nci_to_errno(__u8 code);
3886a2968aaSIlan Elias
3898a00a61bSFrederic Danis /* ----- NCI over SPI acknowledge modes ----- */
3908a00a61bSFrederic Danis #define NCI_SPI_CRC_DISABLED 0x00
3918a00a61bSFrederic Danis #define NCI_SPI_CRC_ENABLED 0x01
3928a00a61bSFrederic Danis
3938a00a61bSFrederic Danis /* ----- NCI SPI structures ----- */
394fa544fffSEric Lapuyade struct nci_spi {
395d5937511SEric Lapuyade struct nci_dev *ndev;
3968a00a61bSFrederic Danis struct spi_device *spi;
3978a00a61bSFrederic Danis
3988a00a61bSFrederic Danis unsigned int xfer_udelay; /* microseconds delay between
3998a00a61bSFrederic Danis transactions */
4002bd83245SVincent Cuissard
4012bd83245SVincent Cuissard unsigned int xfer_speed_hz; /*
4022bd83245SVincent Cuissard * SPI clock frequency
4032bd83245SVincent Cuissard * 0 => default clock
4042bd83245SVincent Cuissard */
4052bd83245SVincent Cuissard
4068a00a61bSFrederic Danis u8 acknowledge_mode;
4078a00a61bSFrederic Danis
408ee9596d4SFrederic Danis struct completion req_completion;
409ee9596d4SFrederic Danis u8 req_result;
4108a00a61bSFrederic Danis };
4118a00a61bSFrederic Danis
412fa544fffSEric Lapuyade /* ----- NCI SPI ----- */
413fa544fffSEric Lapuyade struct nci_spi *nci_spi_allocate_spi(struct spi_device *spi,
414fa544fffSEric Lapuyade u8 acknowledge_mode, unsigned int delay,
415fa544fffSEric Lapuyade struct nci_dev *ndev);
4162bed2785SEric Lapuyade int nci_spi_send(struct nci_spi *nspi,
4172bed2785SEric Lapuyade struct completion *write_handshake_completion,
4182bed2785SEric Lapuyade struct sk_buff *skb);
41922d4aae5SEric Lapuyade struct sk_buff *nci_spi_read(struct nci_spi *nspi);
4208a00a61bSFrederic Danis
4219961127dSVincent Cuissard /* ----- NCI UART ---- */
4229961127dSVincent Cuissard
4239961127dSVincent Cuissard /* Ioctl */
4249961127dSVincent Cuissard #define NCIUARTSETDRIVER _IOW('U', 0, char *)
4259961127dSVincent Cuissard
4269961127dSVincent Cuissard enum nci_uart_driver {
4279961127dSVincent Cuissard NCI_UART_DRIVER_MARVELL = 0,
4289961127dSVincent Cuissard NCI_UART_DRIVER_MAX
4299961127dSVincent Cuissard };
4309961127dSVincent Cuissard
4319961127dSVincent Cuissard struct nci_uart;
4329961127dSVincent Cuissard
4339961127dSVincent Cuissard struct nci_uart_ops {
4349961127dSVincent Cuissard int (*open)(struct nci_uart *nci_uart);
4359961127dSVincent Cuissard void (*close)(struct nci_uart *nci_uart);
4369961127dSVincent Cuissard int (*recv)(struct nci_uart *nci_uart, struct sk_buff *skb);
4379961127dSVincent Cuissard int (*send)(struct nci_uart *nci_uart, struct sk_buff *skb);
4389961127dSVincent Cuissard void (*tx_start)(struct nci_uart *nci_uart);
4399961127dSVincent Cuissard void (*tx_done)(struct nci_uart *nci_uart);
4409961127dSVincent Cuissard };
4419961127dSVincent Cuissard
4429961127dSVincent Cuissard struct nci_uart {
4439961127dSVincent Cuissard struct module *owner;
4449961127dSVincent Cuissard struct nci_uart_ops ops;
4459961127dSVincent Cuissard const char *name;
4469961127dSVincent Cuissard enum nci_uart_driver driver;
4479961127dSVincent Cuissard
4489961127dSVincent Cuissard /* Dynamic data */
4499961127dSVincent Cuissard struct nci_dev *ndev;
4509961127dSVincent Cuissard spinlock_t rx_lock;
4519961127dSVincent Cuissard struct work_struct write_work;
4529961127dSVincent Cuissard struct tty_struct *tty;
4539961127dSVincent Cuissard unsigned long tx_state;
4549961127dSVincent Cuissard struct sk_buff_head tx_q;
4559961127dSVincent Cuissard struct sk_buff *tx_skb;
4569961127dSVincent Cuissard struct sk_buff *rx_skb;
4579961127dSVincent Cuissard int rx_packet_len;
4589961127dSVincent Cuissard void *drv_data;
4599961127dSVincent Cuissard };
4609961127dSVincent Cuissard
4619961127dSVincent Cuissard int nci_uart_register(struct nci_uart *nu);
4629961127dSVincent Cuissard void nci_uart_unregister(struct nci_uart *nu);
4639961127dSVincent Cuissard void nci_uart_set_config(struct nci_uart *nu, int baudrate, int flow_ctrl);
4649961127dSVincent Cuissard
4656a2968aaSIlan Elias #endif /* __NCI_CORE_H */
466