Skip to content

Commit 11f54f2

Browse files
cricard13Samuel Ortiz
authored and
Samuel Ortiz
committed
NFC: nci: Add HCI over NCI protocol support
According to the NCI specification, one can use HCI over NCI to talk with specific NFCEE. The HCI network is viewed as one logical NFCEE. This is needed to support secure element running HCI only firmwares embedded on an NCI capable chipset, like e.g. the st21nfcb. There is some duplication between this piece of code and the HCI core code, but the latter would need to be abstracted even more to be able to use NCI as a logical transport for HCP packets. Signed-off-by: Christophe Ricard <[email protected]> Signed-off-by: Samuel Ortiz <[email protected]>
1 parent 736bb95 commit 11f54f2

File tree

5 files changed

+815
-18
lines changed

5 files changed

+815
-18
lines changed

include/net/nfc/nci_core.h

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ struct nci_ops {
7878
int (*se_io)(struct nci_dev *ndev, u32 se_idx,
7979
u8 *apdu, size_t apdu_length,
8080
se_io_cb_t cb, void *cb_context);
81+
int (*hci_load_session)(struct nci_dev *ndev);
82+
void (*hci_event_received)(struct nci_dev *ndev, u8 pipe, u8 event,
83+
struct sk_buff *skb);
84+
void (*hci_cmd_received)(struct nci_dev *ndev, u8 pipe, u8 cmd,
85+
struct sk_buff *skb);
8186
};
8287

8388
#define NCI_MAX_SUPPORTED_RF_INTERFACES 4
@@ -102,10 +107,77 @@ struct nci_conn_info {
102107

103108
#define NCI_INVALID_CONN_ID 0x80
104109

110+
#define NCI_HCI_ANY_OPEN_PIPE 0x03
111+
112+
/* Gates */
113+
#define NCI_HCI_ADMIN_GATE 0x00
114+
#define NCI_HCI_LINK_MGMT_GATE 0x06
115+
116+
/* Pipes */
117+
#define NCI_HCI_LINK_MGMT_PIPE 0x00
118+
#define NCI_HCI_ADMIN_PIPE 0x01
119+
120+
/* Generic responses */
121+
#define NCI_HCI_ANY_OK 0x00
122+
#define NCI_HCI_ANY_E_NOT_CONNECTED 0x01
123+
#define NCI_HCI_ANY_E_CMD_PAR_UNKNOWN 0x02
124+
#define NCI_HCI_ANY_E_NOK 0x03
125+
#define NCI_HCI_ANY_E_PIPES_FULL 0x04
126+
#define NCI_HCI_ANY_E_REG_PAR_UNKNOWN 0x05
127+
#define NCI_HCI_ANY_E_PIPE_NOT_OPENED 0x06
128+
#define NCI_HCI_ANY_E_CMD_NOT_SUPPORTED 0x07
129+
#define NCI_HCI_ANY_E_INHIBITED 0x08
130+
#define NCI_HCI_ANY_E_TIMEOUT 0x09
131+
#define NCI_HCI_ANY_E_REG_ACCESS_DENIED 0x0a
132+
#define NCI_HCI_ANY_E_PIPE_ACCESS_DENIED 0x0b
133+
134+
#define NCI_HCI_DO_NOT_OPEN_PIPE 0x81
135+
#define NCI_HCI_INVALID_PIPE 0x80
136+
#define NCI_HCI_INVALID_GATE 0xFF
137+
#define NCI_HCI_INVALID_HOST 0x80
138+
139+
#define NCI_HCI_MAX_CUSTOM_GATES 50
140+
#define NCI_HCI_MAX_PIPES 127
141+
142+
struct nci_hci_gate {
143+
u8 gate;
144+
u8 pipe;
145+
u8 dest_host;
146+
} __packed;
147+
148+
struct nci_hci_pipe {
149+
u8 gate;
150+
u8 host;
151+
} __packed;
152+
153+
struct nci_hci_init_data {
154+
u8 gate_count;
155+
struct nci_hci_gate gates[NCI_HCI_MAX_CUSTOM_GATES];
156+
char session_id[9];
157+
};
158+
159+
#define NCI_HCI_MAX_GATES 256
160+
161+
struct nci_hci_dev {
162+
struct nci_dev *ndev;
163+
struct nci_conn_info *conn_info;
164+
165+
struct nci_hci_init_data init_data;
166+
struct nci_hci_pipe pipes[NCI_HCI_MAX_PIPES];
167+
u8 gate2pipe[NCI_HCI_MAX_GATES];
168+
int expected_pipes;
169+
int count_pipes;
170+
171+
struct sk_buff_head rx_hcp_frags;
172+
struct work_struct msg_rx_work;
173+
struct sk_buff_head msg_rx_queue;
174+
};
175+
105176
/* NCI Core structures */
106177
struct nci_dev {
107178
struct nfc_dev *nfc_dev;
108179
struct nci_ops *ops;
180+
struct nci_hci_dev *hci_dev;
109181

110182
int tx_headroom;
111183
int tx_tailroom;
@@ -181,6 +253,10 @@ struct nci_dev *nci_allocate_device(struct nci_ops *ops,
181253
void nci_free_device(struct nci_dev *ndev);
182254
int nci_register_device(struct nci_dev *ndev);
183255
void nci_unregister_device(struct nci_dev *ndev);
256+
int nci_request(struct nci_dev *ndev,
257+
void (*req)(struct nci_dev *ndev,
258+
unsigned long opt),
259+
unsigned long opt, __u32 timeout);
184260
int nci_recv_frame(struct nci_dev *ndev, struct sk_buff *skb);
185261
int nci_set_config(struct nci_dev *ndev, __u8 id, size_t len, __u8 *val);
186262

@@ -190,6 +266,21 @@ int nci_core_conn_create(struct nci_dev *ndev,
190266
struct core_conn_create_dest_spec_params *params);
191267
int nci_core_conn_close(struct nci_dev *ndev, u8 conn_id);
192268

269+
struct nci_hci_dev *nci_hci_allocate(struct nci_dev *ndev);
270+
int nci_hci_send_event(struct nci_dev *ndev, u8 gate, u8 event,
271+
const u8 *param, size_t param_len);
272+
int nci_hci_send_cmd(struct nci_dev *ndev, u8 gate,
273+
u8 cmd, const u8 *param, size_t param_len,
274+
struct sk_buff **skb);
275+
int nci_hci_open_pipe(struct nci_dev *ndev, u8 pipe);
276+
int nci_hci_connect_gate(struct nci_dev *ndev, u8 dest_host,
277+
u8 dest_gate, u8 pipe);
278+
int nci_hci_set_param(struct nci_dev *ndev, u8 gate, u8 idx,
279+
const u8 *param, size_t param_len);
280+
int nci_hci_get_param(struct nci_dev *ndev, u8 gate, u8 idx,
281+
struct sk_buff **skb);
282+
int nci_hci_dev_session_init(struct nci_dev *ndev);
283+
193284
static inline struct sk_buff *nci_skb_alloc(struct nci_dev *ndev,
194285
unsigned int len,
195286
gfp_t how)
@@ -225,6 +316,8 @@ int nci_send_cmd(struct nci_dev *ndev, __u16 opcode, __u8 plen, void *payload);
225316
int nci_send_data(struct nci_dev *ndev, __u8 conn_id, struct sk_buff *skb);
226317
void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb,
227318
__u8 conn_id, int err);
319+
void nci_hci_data_received_cb(void *context, struct sk_buff *skb, int err);
320+
228321
void nci_clear_target_list(struct nci_dev *ndev);
229322

230323
/* ----- NCI requests ----- */

net/nfc/nci/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44

55
obj-$(CONFIG_NFC_NCI) += nci.o
66

7-
nci-objs := core.o data.o lib.o ntf.o rsp.o
7+
nci-objs := core.o data.o lib.o ntf.o rsp.o hci.o
88

99
nci-$(CONFIG_NFC_NCI_SPI) += spi.o

net/nfc/nci/core.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,10 @@ static int __nci_request(struct nci_dev *ndev,
122122
return rc;
123123
}
124124

125-
static inline int nci_request(struct nci_dev *ndev,
126-
void (*req)(struct nci_dev *ndev,
127-
unsigned long opt),
128-
unsigned long opt, __u32 timeout)
125+
inline int nci_request(struct nci_dev *ndev,
126+
void (*req)(struct nci_dev *ndev,
127+
unsigned long opt),
128+
unsigned long opt, __u32 timeout)
129129
{
130130
int rc;
131131

@@ -901,7 +901,6 @@ static struct nfc_ops nci_nfc_ops = {
901901
};
902902

903903
/* ---- Interface to NCI drivers ---- */
904-
905904
/**
906905
* nci_allocate_device - allocate a new nci device
907906
*
@@ -936,13 +935,20 @@ struct nci_dev *nci_allocate_device(struct nci_ops *ops,
936935
tx_headroom + NCI_DATA_HDR_SIZE,
937936
tx_tailroom);
938937
if (!ndev->nfc_dev)
939-
goto free_exit;
938+
goto free_nci;
939+
940+
ndev->hci_dev = nci_hci_allocate(ndev);
941+
if (!ndev->hci_dev)
942+
goto free_nfc;
940943

941944
nfc_set_drvdata(ndev->nfc_dev, ndev);
942945

943946
return ndev;
944947

945-
free_exit:
948+
free_nfc:
949+
kfree(ndev->nfc_dev);
950+
951+
free_nci:
946952
kfree(ndev);
947953
return NULL;
948954
}

0 commit comments

Comments
 (0)