]>
Commit | Line | Data |
---|---|---|
68957303 CR |
1 | /* |
2 | * HCI based Driver for STMicroelectronics NFC Chip | |
3 | * | |
4 | * Copyright (C) 2014 STMicroelectronics SAS. All rights reserved. | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify it | |
7 | * under the terms and conditions of the GNU General Public License, | |
8 | * version 2, as published by the Free Software Foundation. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License | |
16 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | |
17 | */ | |
18 | ||
68957303 | 19 | #include <linux/module.h> |
68957303 CR |
20 | #include <linux/nfc.h> |
21 | #include <net/nfc/hci.h> | |
22 | #include <net/nfc/llc.h> | |
23 | ||
68957303 | 24 | #include "st21nfca.h" |
68957303 CR |
25 | |
26 | #define DRIVER_DESC "HCI NFC driver for ST21NFCA" | |
27 | ||
28 | #define FULL_VERSION_LEN 3 | |
29 | ||
30 | /* Proprietary gates, events, commands and registers */ | |
31 | ||
32 | /* Commands that apply to all RF readers */ | |
33 | #define ST21NFCA_RF_READER_CMD_PRESENCE_CHECK 0x30 | |
34 | ||
35 | #define ST21NFCA_RF_READER_ISO15693_GATE 0x12 | |
efaf956a | 36 | #define ST21NFCA_RF_READER_ISO15693_INVENTORY 0x01 |
68957303 CR |
37 | |
38 | /* | |
39 | * Reader gate for communication with contact-less cards using Type A | |
40 | * protocol ISO14443-3 but not compliant with ISO14443-4 | |
41 | */ | |
42 | #define ST21NFCA_RF_READER_14443_3_A_GATE 0x15 | |
43 | #define ST21NFCA_RF_READER_14443_3_A_UID 0x02 | |
44 | #define ST21NFCA_RF_READER_14443_3_A_ATQA 0x03 | |
45 | #define ST21NFCA_RF_READER_14443_3_A_SAK 0x04 | |
46 | ||
efaf956a CR |
47 | #define ST21NFCA_RF_READER_F_DATARATE 0x01 |
48 | #define ST21NFCA_RF_READER_F_DATARATE_106 0x01 | |
49 | #define ST21NFCA_RF_READER_F_DATARATE_212 0x02 | |
50 | #define ST21NFCA_RF_READER_F_DATARATE_424 0x04 | |
51 | #define ST21NFCA_RF_READER_F_POL_REQ 0x02 | |
52 | #define ST21NFCA_RF_READER_F_POL_REQ_DEFAULT 0xffff0000 | |
53 | #define ST21NFCA_RF_READER_F_NFCID2 0x03 | |
54 | #define ST21NFCA_RF_READER_F_NFCID1 0x04 | |
55 | ||
56 | #define ST21NFCA_RF_CARD_F_MODE 0x01 | |
57 | #define ST21NFCA_RF_CARD_F_NFCID2_LIST 0x04 | |
58 | #define ST21NFCA_RF_CARD_F_NFCID1 0x05 | |
59 | #define ST21NFCA_RF_CARD_F_SENS_RES 0x06 | |
60 | #define ST21NFCA_RF_CARD_F_SEL_RES 0x07 | |
61 | #define ST21NFCA_RF_CARD_F_DATARATE 0x08 | |
62 | #define ST21NFCA_RF_CARD_F_DATARATE_212_424 0x01 | |
cebe2224 | 63 | |
68957303 | 64 | #define ST21NFCA_DEVICE_MGNT_PIPE 0x02 |
68957303 | 65 | |
efaf956a CR |
66 | #define ST21NFCA_DM_GETINFO 0x13 |
67 | #define ST21NFCA_DM_GETINFO_PIPE_LIST 0x02 | |
68 | #define ST21NFCA_DM_GETINFO_PIPE_INFO 0x01 | |
69 | #define ST21NFCA_DM_PIPE_CREATED 0x02 | |
70 | #define ST21NFCA_DM_PIPE_OPEN 0x04 | |
71 | #define ST21NFCA_DM_RF_ACTIVE 0x80 | |
72 | #define ST21NFCA_DM_DISCONNECT 0x30 | |
58e1e0a9 CR |
73 | |
74 | #define ST21NFCA_DM_IS_PIPE_OPEN(p) \ | |
75 | ((p & 0x0f) == (ST21NFCA_DM_PIPE_CREATED | ST21NFCA_DM_PIPE_OPEN)) | |
76 | ||
efaf956a | 77 | #define ST21NFCA_NFC_MODE 0x03 /* NFC_MODE parameter*/ |
68957303 | 78 | |
2130fb97 CR |
79 | #define ST21NFCA_EVT_HOT_PLUG 0x03 |
80 | #define ST21NFCA_EVT_HOT_PLUG_IS_INHIBITED(x) (x->data[0] & 0x80) | |
81 | ||
82 | #define ST21NFCA_SE_TO_PIPES 2000 | |
83 | ||
68957303 CR |
84 | static DECLARE_BITMAP(dev_mask, ST21NFCA_NUM_DEVICES); |
85 | ||
86 | static struct nfc_hci_gate st21nfca_gates[] = { | |
a779b887 | 87 | {NFC_HCI_ADMIN_GATE, NFC_HCI_ADMIN_PIPE}, |
ba723199 CR |
88 | {NFC_HCI_LINK_MGMT_GATE, NFC_HCI_LINK_MGMT_PIPE}, |
89 | {ST21NFCA_DEVICE_MGNT_GATE, ST21NFCA_DEVICE_MGNT_PIPE}, | |
90 | ||
68957303 CR |
91 | {NFC_HCI_LOOPBACK_GATE, NFC_HCI_INVALID_PIPE}, |
92 | {NFC_HCI_ID_MGMT_GATE, NFC_HCI_INVALID_PIPE}, | |
68957303 CR |
93 | {NFC_HCI_RF_READER_B_GATE, NFC_HCI_INVALID_PIPE}, |
94 | {NFC_HCI_RF_READER_A_GATE, NFC_HCI_INVALID_PIPE}, | |
68957303 CR |
95 | {ST21NFCA_RF_READER_F_GATE, NFC_HCI_INVALID_PIPE}, |
96 | {ST21NFCA_RF_READER_14443_3_A_GATE, NFC_HCI_INVALID_PIPE}, | |
79747280 | 97 | {ST21NFCA_RF_READER_ISO15693_GATE, NFC_HCI_INVALID_PIPE}, |
1892bf84 | 98 | {ST21NFCA_RF_CARD_F_GATE, NFC_HCI_INVALID_PIPE}, |
2130fb97 CR |
99 | |
100 | /* Secure element pipes are created by secure element host */ | |
101 | {ST21NFCA_CONNECTIVITY_GATE, NFC_HCI_DO_NOT_CREATE_PIPE}, | |
102 | {ST21NFCA_APDU_READER_GATE, NFC_HCI_DO_NOT_CREATE_PIPE}, | |
68957303 | 103 | }; |
58e1e0a9 CR |
104 | |
105 | struct st21nfca_pipe_info { | |
106 | u8 pipe_state; | |
107 | u8 src_host_id; | |
108 | u8 src_gate_id; | |
109 | u8 dst_host_id; | |
110 | u8 dst_gate_id; | |
761a2c4f | 111 | } __packed; |
58e1e0a9 | 112 | |
68957303 CR |
113 | /* Largest headroom needed for outgoing custom commands */ |
114 | #define ST21NFCA_CMDS_HEADROOM 7 | |
115 | ||
58e1e0a9 CR |
116 | static int st21nfca_hci_load_session(struct nfc_hci_dev *hdev) |
117 | { | |
118 | int i, j, r; | |
119 | struct sk_buff *skb_pipe_list, *skb_pipe_info; | |
120 | struct st21nfca_pipe_info *info; | |
121 | ||
122 | u8 pipe_list[] = { ST21NFCA_DM_GETINFO_PIPE_LIST, | |
123 | NFC_HCI_TERMINAL_HOST_ID | |
124 | }; | |
125 | u8 pipe_info[] = { ST21NFCA_DM_GETINFO_PIPE_INFO, | |
126 | NFC_HCI_TERMINAL_HOST_ID, 0 | |
127 | }; | |
128 | ||
58e1e0a9 CR |
129 | /* On ST21NFCA device pipes number are dynamics |
130 | * A maximum of 16 pipes can be created at the same time | |
131 | * If pipes are already created, hci_dev_up will fail. | |
132 | * Doing a clear all pipe is a bad idea because: | |
133 | * - It does useless EEPROM cycling | |
134 | * - It might cause issue for secure elements support | |
135 | * (such as removing connectivity or APDU reader pipe) | |
136 | * A better approach on ST21NFCA is to: | |
137 | * - get a pipe list for each host. | |
138 | * (eg: NFC_HCI_HOST_CONTROLLER_ID for now). | |
139 | * (TODO Later on UICC HOST and eSE HOST) | |
140 | * - get pipe information | |
141 | * - match retrieved pipe list in st21nfca_gates | |
142 | * ST21NFCA_DEVICE_MGNT_GATE is a proprietary gate | |
143 | * with ST21NFCA_DEVICE_MGNT_PIPE. | |
144 | * Pipe can be closed and need to be open. | |
145 | */ | |
146 | r = nfc_hci_connect_gate(hdev, NFC_HCI_HOST_CONTROLLER_ID, | |
2130fb97 CR |
147 | ST21NFCA_DEVICE_MGNT_GATE, |
148 | ST21NFCA_DEVICE_MGNT_PIPE); | |
58e1e0a9 | 149 | if (r < 0) |
5a357006 | 150 | return r; |
58e1e0a9 CR |
151 | |
152 | /* Get pipe list */ | |
153 | r = nfc_hci_send_cmd(hdev, ST21NFCA_DEVICE_MGNT_GATE, | |
154 | ST21NFCA_DM_GETINFO, pipe_list, sizeof(pipe_list), | |
155 | &skb_pipe_list); | |
156 | if (r < 0) | |
5a357006 | 157 | return r; |
58e1e0a9 CR |
158 | |
159 | /* Complete the existing gate_pipe table */ | |
160 | for (i = 0; i < skb_pipe_list->len; i++) { | |
161 | pipe_info[2] = skb_pipe_list->data[i]; | |
162 | r = nfc_hci_send_cmd(hdev, ST21NFCA_DEVICE_MGNT_GATE, | |
163 | ST21NFCA_DM_GETINFO, pipe_info, | |
164 | sizeof(pipe_info), &skb_pipe_info); | |
58e1e0a9 CR |
165 | if (r) |
166 | continue; | |
167 | ||
168 | /* | |
169 | * Match pipe ID and gate ID | |
170 | * Output format from ST21NFC_DM_GETINFO is: | |
171 | * - pipe state (1byte) | |
172 | * - source hid (1byte) | |
173 | * - source gid (1byte) | |
174 | * - destination hid (1byte) | |
175 | * - destination gid (1byte) | |
176 | */ | |
e8efab6e | 177 | info = (struct st21nfca_pipe_info *) skb_pipe_info->data; |
2130fb97 | 178 | if (info->dst_gate_id == ST21NFCA_APDU_READER_GATE && |
7cb6ab59 | 179 | info->src_host_id == NFC_HCI_UICC_HOST_ID) { |
2130fb97 CR |
180 | pr_err("Unexpected apdu_reader pipe on host %x\n", |
181 | info->src_host_id); | |
5a357006 | 182 | kfree_skb(skb_pipe_info); |
2130fb97 CR |
183 | continue; |
184 | } | |
185 | ||
ba723199 | 186 | for (j = 3; (j < ARRAY_SIZE(st21nfca_gates)) && |
2130fb97 | 187 | (st21nfca_gates[j].gate != info->dst_gate_id) ; j++) |
58e1e0a9 CR |
188 | ; |
189 | ||
e8efab6e CR |
190 | if (j < ARRAY_SIZE(st21nfca_gates) && |
191 | st21nfca_gates[j].gate == info->dst_gate_id && | |
58e1e0a9 | 192 | ST21NFCA_DM_IS_PIPE_OPEN(info->pipe_state)) { |
92d108b6 | 193 | hdev->init_data.gates[j].pipe = pipe_info[2]; |
2130fb97 | 194 | |
58e1e0a9 | 195 | hdev->gate2pipe[st21nfca_gates[j].gate] = |
92d108b6 CR |
196 | pipe_info[2]; |
197 | hdev->pipes[pipe_info[2]].gate = | |
198 | st21nfca_gates[j].gate; | |
199 | hdev->pipes[pipe_info[2]].dest_host = | |
200 | info->src_host_id; | |
58e1e0a9 | 201 | } |
5a357006 | 202 | kfree_skb(skb_pipe_info); |
58e1e0a9 | 203 | } |
a779b887 CR |
204 | |
205 | /* | |
6443ce97 CR |
206 | * 3 gates have a well known pipe ID. Only NFC_HCI_LINK_MGMT_GATE |
207 | * is not yet open at this stage. | |
a779b887 | 208 | */ |
6443ce97 CR |
209 | r = nfc_hci_connect_gate(hdev, NFC_HCI_HOST_CONTROLLER_ID, |
210 | NFC_HCI_LINK_MGMT_GATE, | |
211 | NFC_HCI_LINK_MGMT_PIPE); | |
a779b887 | 212 | |
58e1e0a9 CR |
213 | kfree_skb(skb_pipe_list); |
214 | return r; | |
215 | } | |
216 | ||
68957303 CR |
217 | static int st21nfca_hci_open(struct nfc_hci_dev *hdev) |
218 | { | |
219 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | |
220 | int r; | |
221 | ||
222 | mutex_lock(&info->info_lock); | |
223 | ||
224 | if (info->state != ST21NFCA_ST_COLD) { | |
225 | r = -EBUSY; | |
226 | goto out; | |
227 | } | |
228 | ||
229 | r = info->phy_ops->enable(info->phy_id); | |
230 | ||
231 | if (r == 0) | |
232 | info->state = ST21NFCA_ST_READY; | |
233 | ||
234 | out: | |
235 | mutex_unlock(&info->info_lock); | |
236 | return r; | |
237 | } | |
238 | ||
239 | static void st21nfca_hci_close(struct nfc_hci_dev *hdev) | |
240 | { | |
241 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | |
242 | ||
243 | mutex_lock(&info->info_lock); | |
244 | ||
245 | if (info->state == ST21NFCA_ST_COLD) | |
246 | goto out; | |
247 | ||
248 | info->phy_ops->disable(info->phy_id); | |
249 | info->state = ST21NFCA_ST_COLD; | |
250 | ||
251 | out: | |
252 | mutex_unlock(&info->info_lock); | |
253 | } | |
254 | ||
255 | static int st21nfca_hci_ready(struct nfc_hci_dev *hdev) | |
256 | { | |
2130fb97 | 257 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); |
68957303 CR |
258 | struct sk_buff *skb; |
259 | ||
260 | u8 param; | |
2130fb97 CR |
261 | u8 white_list[2]; |
262 | int wl_size = 0; | |
68957303 CR |
263 | int r; |
264 | ||
d35cb20b | 265 | if (info->se_status->is_uicc_present) |
2130fb97 | 266 | white_list[wl_size++] = NFC_HCI_UICC_HOST_ID; |
d35cb20b | 267 | if (info->se_status->is_ese_present) |
2130fb97 | 268 | white_list[wl_size++] = ST21NFCA_ESE_HOST_ID; |
2130fb97 CR |
269 | |
270 | if (wl_size) { | |
271 | r = nfc_hci_set_param(hdev, NFC_HCI_ADMIN_GATE, | |
272 | NFC_HCI_ADMIN_WHITELIST, | |
273 | (u8 *) &white_list, wl_size); | |
274 | if (r < 0) | |
275 | return r; | |
276 | } | |
68957303 CR |
277 | |
278 | /* Set NFC_MODE in device management gate to enable */ | |
279 | r = nfc_hci_get_param(hdev, ST21NFCA_DEVICE_MGNT_GATE, | |
280 | ST21NFCA_NFC_MODE, &skb); | |
281 | if (r < 0) | |
282 | return r; | |
283 | ||
c490c557 CR |
284 | param = skb->data[0]; |
285 | kfree_skb(skb); | |
286 | if (param == 0) { | |
68957303 CR |
287 | param = 1; |
288 | ||
289 | r = nfc_hci_set_param(hdev, ST21NFCA_DEVICE_MGNT_GATE, | |
290 | ST21NFCA_NFC_MODE, ¶m, 1); | |
291 | if (r < 0) | |
292 | return r; | |
293 | } | |
294 | ||
295 | r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, | |
296 | NFC_HCI_EVT_END_OPERATION, NULL, 0); | |
297 | if (r < 0) | |
298 | return r; | |
299 | ||
300 | r = nfc_hci_get_param(hdev, NFC_HCI_ID_MGMT_GATE, | |
301 | NFC_HCI_ID_MGMT_VERSION_SW, &skb); | |
302 | if (r < 0) | |
303 | return r; | |
304 | ||
305 | if (skb->len != FULL_VERSION_LEN) { | |
306 | kfree_skb(skb); | |
307 | return -EINVAL; | |
308 | } | |
309 | ||
310 | print_hex_dump(KERN_DEBUG, "FULL VERSION SOFTWARE INFO: ", | |
311 | DUMP_PREFIX_NONE, 16, 1, | |
312 | skb->data, FULL_VERSION_LEN, false); | |
313 | ||
314 | kfree_skb(skb); | |
315 | ||
316 | return 0; | |
317 | } | |
318 | ||
319 | static int st21nfca_hci_xmit(struct nfc_hci_dev *hdev, struct sk_buff *skb) | |
320 | { | |
321 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | |
322 | ||
323 | return info->phy_ops->write(info->phy_id, skb); | |
324 | } | |
325 | ||
326 | static int st21nfca_hci_start_poll(struct nfc_hci_dev *hdev, | |
327 | u32 im_protocols, u32 tm_protocols) | |
328 | { | |
329 | int r; | |
1892bf84 CR |
330 | u32 pol_req; |
331 | u8 param[19]; | |
332 | struct sk_buff *datarate_skb; | |
68957303 CR |
333 | |
334 | pr_info(DRIVER_DESC ": %s protocols 0x%x 0x%x\n", | |
335 | __func__, im_protocols, tm_protocols); | |
336 | ||
337 | r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, | |
338 | NFC_HCI_EVT_END_OPERATION, NULL, 0); | |
339 | if (r < 0) | |
340 | return r; | |
341 | if (im_protocols) { | |
342 | /* | |
343 | * enable polling according to im_protocols & tm_protocols | |
344 | * - CLOSE pipe according to im_protocols & tm_protocols | |
345 | */ | |
346 | if ((NFC_HCI_RF_READER_B_GATE & im_protocols) == 0) { | |
347 | r = nfc_hci_disconnect_gate(hdev, | |
348 | NFC_HCI_RF_READER_B_GATE); | |
349 | if (r < 0) | |
350 | return r; | |
351 | } | |
352 | ||
353 | if ((NFC_HCI_RF_READER_A_GATE & im_protocols) == 0) { | |
354 | r = nfc_hci_disconnect_gate(hdev, | |
355 | NFC_HCI_RF_READER_A_GATE); | |
356 | if (r < 0) | |
357 | return r; | |
358 | } | |
359 | ||
360 | if ((ST21NFCA_RF_READER_F_GATE & im_protocols) == 0) { | |
361 | r = nfc_hci_disconnect_gate(hdev, | |
362 | ST21NFCA_RF_READER_F_GATE); | |
363 | if (r < 0) | |
364 | return r; | |
1892bf84 CR |
365 | } else { |
366 | hdev->gb = nfc_get_local_general_bytes(hdev->ndev, | |
367 | &hdev->gb_len); | |
368 | ||
369 | if (hdev->gb == NULL || hdev->gb_len == 0) { | |
370 | im_protocols &= ~NFC_PROTO_NFC_DEP_MASK; | |
371 | tm_protocols &= ~NFC_PROTO_NFC_DEP_MASK; | |
372 | } | |
373 | ||
374 | param[0] = ST21NFCA_RF_READER_F_DATARATE_106 | | |
375 | ST21NFCA_RF_READER_F_DATARATE_212 | | |
376 | ST21NFCA_RF_READER_F_DATARATE_424; | |
377 | r = nfc_hci_set_param(hdev, ST21NFCA_RF_READER_F_GATE, | |
378 | ST21NFCA_RF_READER_F_DATARATE, | |
379 | param, 1); | |
380 | if (r < 0) | |
381 | return r; | |
382 | ||
6ae3ed1c CR |
383 | pol_req = be32_to_cpu((__force __be32) |
384 | ST21NFCA_RF_READER_F_POL_REQ_DEFAULT); | |
1892bf84 CR |
385 | r = nfc_hci_set_param(hdev, ST21NFCA_RF_READER_F_GATE, |
386 | ST21NFCA_RF_READER_F_POL_REQ, | |
387 | (u8 *) &pol_req, 4); | |
388 | if (r < 0) | |
389 | return r; | |
68957303 CR |
390 | } |
391 | ||
392 | if ((ST21NFCA_RF_READER_14443_3_A_GATE & im_protocols) == 0) { | |
393 | r = nfc_hci_disconnect_gate(hdev, | |
394 | ST21NFCA_RF_READER_14443_3_A_GATE); | |
395 | if (r < 0) | |
396 | return r; | |
397 | } | |
398 | ||
399 | if ((ST21NFCA_RF_READER_ISO15693_GATE & im_protocols) == 0) { | |
400 | r = nfc_hci_disconnect_gate(hdev, | |
401 | ST21NFCA_RF_READER_ISO15693_GATE); | |
402 | if (r < 0) | |
403 | return r; | |
404 | } | |
405 | ||
406 | r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, | |
407 | NFC_HCI_EVT_READER_REQUESTED, NULL, 0); | |
408 | if (r < 0) | |
409 | nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, | |
410 | NFC_HCI_EVT_END_OPERATION, NULL, 0); | |
411 | } | |
1892bf84 CR |
412 | |
413 | if (tm_protocols & NFC_PROTO_NFC_DEP_MASK) { | |
414 | r = nfc_hci_get_param(hdev, ST21NFCA_RF_CARD_F_GATE, | |
415 | ST21NFCA_RF_CARD_F_DATARATE, | |
416 | &datarate_skb); | |
417 | if (r < 0) | |
418 | return r; | |
419 | ||
420 | /* Configure the maximum supported datarate to 424Kbps */ | |
421 | if (datarate_skb->len > 0 && | |
422 | datarate_skb->data[0] != | |
423 | ST21NFCA_RF_CARD_F_DATARATE_212_424) { | |
424 | param[0] = ST21NFCA_RF_CARD_F_DATARATE_212_424; | |
425 | r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE, | |
426 | ST21NFCA_RF_CARD_F_DATARATE, | |
427 | param, 1); | |
c490c557 CR |
428 | if (r < 0) { |
429 | kfree_skb(datarate_skb); | |
1892bf84 | 430 | return r; |
c490c557 | 431 | } |
1892bf84 | 432 | } |
c490c557 | 433 | kfree_skb(datarate_skb); |
1892bf84 CR |
434 | |
435 | /* | |
436 | * Configure sens_res | |
437 | * | |
438 | * NFC Forum Digital Spec Table 7: | |
439 | * NFCID1 size: triple (10 bytes) | |
440 | */ | |
441 | param[0] = 0x00; | |
442 | param[1] = 0x08; | |
443 | r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE, | |
444 | ST21NFCA_RF_CARD_F_SENS_RES, param, 2); | |
445 | if (r < 0) | |
446 | return r; | |
447 | ||
448 | /* | |
449 | * Configure sel_res | |
450 | * | |
451 | * NFC Forum Digistal Spec Table 17: | |
452 | * b3 set to 0b (value b7-b6): | |
453 | * - 10b: Configured for NFC-DEP Protocol | |
454 | */ | |
455 | param[0] = 0x40; | |
456 | r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE, | |
457 | ST21NFCA_RF_CARD_F_SEL_RES, param, 1); | |
458 | if (r < 0) | |
459 | return r; | |
460 | ||
461 | /* Configure NFCID1 Random uid */ | |
462 | r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE, | |
463 | ST21NFCA_RF_CARD_F_NFCID1, NULL, 0); | |
464 | if (r < 0) | |
465 | return r; | |
466 | ||
467 | /* Configure NFCID2_LIST */ | |
468 | /* System Code */ | |
469 | param[0] = 0x00; | |
470 | param[1] = 0x00; | |
471 | /* NFCID2 */ | |
472 | param[2] = 0x01; | |
473 | param[3] = 0xfe; | |
474 | param[4] = 'S'; | |
475 | param[5] = 'T'; | |
476 | param[6] = 'M'; | |
477 | param[7] = 'i'; | |
478 | param[8] = 'c'; | |
479 | param[9] = 'r'; | |
480 | /* 8 byte Pad bytes used for polling respone frame */ | |
481 | ||
482 | /* | |
483 | * Configuration byte: | |
484 | * - bit 0: define the default NFCID2 entry used when the | |
485 | * system code is equal to 'FFFF' | |
486 | * - bit 1: use a random value for lowest 6 bytes of | |
487 | * NFCID2 value | |
488 | * - bit 2: ignore polling request frame if request code | |
489 | * is equal to '01' | |
490 | * - Other bits are RFU | |
491 | */ | |
492 | param[18] = 0x01; | |
493 | r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE, | |
494 | ST21NFCA_RF_CARD_F_NFCID2_LIST, param, | |
495 | 19); | |
496 | if (r < 0) | |
497 | return r; | |
498 | ||
499 | param[0] = 0x02; | |
500 | r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE, | |
501 | ST21NFCA_RF_CARD_F_MODE, param, 1); | |
502 | } | |
503 | ||
68957303 CR |
504 | return r; |
505 | } | |
506 | ||
d57d74eb CR |
507 | static void st21nfca_hci_stop_poll(struct nfc_hci_dev *hdev) |
508 | { | |
509 | nfc_hci_send_cmd(hdev, ST21NFCA_DEVICE_MGNT_GATE, | |
510 | ST21NFCA_DM_DISCONNECT, NULL, 0, NULL); | |
511 | } | |
512 | ||
68957303 CR |
513 | static int st21nfca_get_iso14443_3_atqa(struct nfc_hci_dev *hdev, u16 *atqa) |
514 | { | |
515 | int r; | |
516 | struct sk_buff *atqa_skb = NULL; | |
517 | ||
518 | r = nfc_hci_get_param(hdev, ST21NFCA_RF_READER_14443_3_A_GATE, | |
519 | ST21NFCA_RF_READER_14443_3_A_ATQA, &atqa_skb); | |
520 | if (r < 0) | |
521 | goto exit; | |
522 | ||
523 | if (atqa_skb->len != 2) { | |
524 | r = -EPROTO; | |
525 | goto exit; | |
526 | } | |
527 | ||
cc3a9f72 | 528 | *atqa = be16_to_cpu(*(__be16 *) atqa_skb->data); |
68957303 CR |
529 | |
530 | exit: | |
531 | kfree_skb(atqa_skb); | |
532 | return r; | |
533 | } | |
534 | ||
535 | static int st21nfca_get_iso14443_3_sak(struct nfc_hci_dev *hdev, u8 *sak) | |
536 | { | |
537 | int r; | |
538 | struct sk_buff *sak_skb = NULL; | |
539 | ||
540 | r = nfc_hci_get_param(hdev, ST21NFCA_RF_READER_14443_3_A_GATE, | |
541 | ST21NFCA_RF_READER_14443_3_A_SAK, &sak_skb); | |
542 | if (r < 0) | |
543 | goto exit; | |
544 | ||
545 | if (sak_skb->len != 1) { | |
546 | r = -EPROTO; | |
547 | goto exit; | |
548 | } | |
549 | ||
550 | *sak = sak_skb->data[0]; | |
551 | ||
552 | exit: | |
553 | kfree_skb(sak_skb); | |
554 | return r; | |
555 | } | |
556 | ||
a8f686ec | 557 | static int st21nfca_get_iso14443_3_uid(struct nfc_hci_dev *hdev, u8 *uid, |
68957303 CR |
558 | int *len) |
559 | { | |
560 | int r; | |
561 | struct sk_buff *uid_skb = NULL; | |
562 | ||
563 | r = nfc_hci_get_param(hdev, ST21NFCA_RF_READER_14443_3_A_GATE, | |
564 | ST21NFCA_RF_READER_14443_3_A_UID, &uid_skb); | |
565 | if (r < 0) | |
566 | goto exit; | |
567 | ||
568 | if (uid_skb->len == 0 || uid_skb->len > NFC_NFCID1_MAXSIZE) { | |
569 | r = -EPROTO; | |
570 | goto exit; | |
571 | } | |
572 | ||
a8f686ec | 573 | memcpy(uid, uid_skb->data, uid_skb->len); |
68957303 CR |
574 | *len = uid_skb->len; |
575 | exit: | |
576 | kfree_skb(uid_skb); | |
577 | return r; | |
578 | } | |
579 | ||
79747280 CR |
580 | static int st21nfca_get_iso15693_inventory(struct nfc_hci_dev *hdev, |
581 | struct nfc_target *target) | |
582 | { | |
583 | int r; | |
584 | struct sk_buff *inventory_skb = NULL; | |
585 | ||
586 | r = nfc_hci_get_param(hdev, ST21NFCA_RF_READER_ISO15693_GATE, | |
587 | ST21NFCA_RF_READER_ISO15693_INVENTORY, | |
588 | &inventory_skb); | |
589 | if (r < 0) | |
590 | goto exit; | |
591 | ||
592 | skb_pull(inventory_skb, 2); | |
593 | ||
594 | if (inventory_skb->len == 0 || | |
595 | inventory_skb->len > NFC_ISO15693_UID_MAXSIZE) { | |
596 | r = -EPROTO; | |
597 | goto exit; | |
598 | } | |
599 | ||
600 | memcpy(target->iso15693_uid, inventory_skb->data, inventory_skb->len); | |
601 | target->iso15693_dsfid = inventory_skb->data[1]; | |
602 | target->is_iso15693 = 1; | |
603 | exit: | |
604 | kfree_skb(inventory_skb); | |
605 | return r; | |
606 | } | |
607 | ||
1892bf84 CR |
608 | static int st21nfca_hci_dep_link_up(struct nfc_hci_dev *hdev, |
609 | struct nfc_target *target, u8 comm_mode, | |
610 | u8 *gb, size_t gb_len) | |
611 | { | |
612 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | |
613 | ||
614 | info->dep_info.idx = target->idx; | |
615 | return st21nfca_im_send_atr_req(hdev, gb, gb_len); | |
616 | } | |
617 | ||
618 | static int st21nfca_hci_dep_link_down(struct nfc_hci_dev *hdev) | |
619 | { | |
620 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | |
621 | ||
622 | info->state = ST21NFCA_ST_READY; | |
623 | ||
624 | return nfc_hci_send_cmd(hdev, ST21NFCA_DEVICE_MGNT_GATE, | |
625 | ST21NFCA_DM_DISCONNECT, NULL, 0, NULL); | |
626 | } | |
627 | ||
68957303 CR |
628 | static int st21nfca_hci_target_from_gate(struct nfc_hci_dev *hdev, u8 gate, |
629 | struct nfc_target *target) | |
630 | { | |
631 | int r, len; | |
632 | u16 atqa; | |
633 | u8 sak; | |
634 | u8 uid[NFC_NFCID1_MAXSIZE]; | |
635 | ||
636 | switch (gate) { | |
637 | case ST21NFCA_RF_READER_F_GATE: | |
638 | target->supported_protocols = NFC_PROTO_FELICA_MASK; | |
639 | break; | |
640 | case ST21NFCA_RF_READER_14443_3_A_GATE: | |
641 | /* ISO14443-3 type 1 or 2 tags */ | |
642 | r = st21nfca_get_iso14443_3_atqa(hdev, &atqa); | |
643 | if (r < 0) | |
644 | return r; | |
645 | if (atqa == 0x000c) { | |
646 | target->supported_protocols = NFC_PROTO_JEWEL_MASK; | |
647 | target->sens_res = 0x0c00; | |
648 | } else { | |
649 | r = st21nfca_get_iso14443_3_sak(hdev, &sak); | |
650 | if (r < 0) | |
651 | return r; | |
652 | ||
653 | r = st21nfca_get_iso14443_3_uid(hdev, uid, &len); | |
654 | if (r < 0) | |
655 | return r; | |
656 | ||
657 | target->supported_protocols = | |
658 | nfc_hci_sak_to_protocol(sak); | |
659 | if (target->supported_protocols == 0xffffffff) | |
660 | return -EPROTO; | |
661 | ||
662 | target->sens_res = atqa; | |
663 | target->sel_res = sak; | |
664 | memcpy(target->nfcid1, uid, len); | |
665 | target->nfcid1_len = len; | |
666 | } | |
667 | ||
668 | break; | |
79747280 CR |
669 | case ST21NFCA_RF_READER_ISO15693_GATE: |
670 | target->supported_protocols = NFC_PROTO_ISO15693_MASK; | |
671 | r = st21nfca_get_iso15693_inventory(hdev, target); | |
672 | if (r < 0) | |
673 | return r; | |
674 | break; | |
68957303 CR |
675 | default: |
676 | return -EPROTO; | |
677 | } | |
678 | ||
679 | return 0; | |
680 | } | |
681 | ||
1892bf84 CR |
682 | static int st21nfca_hci_complete_target_discovered(struct nfc_hci_dev *hdev, |
683 | u8 gate, | |
684 | struct nfc_target *target) | |
685 | { | |
686 | int r; | |
c490c557 | 687 | struct sk_buff *nfcid_skb = NULL; |
1892bf84 CR |
688 | |
689 | if (gate == ST21NFCA_RF_READER_F_GATE) { | |
690 | r = nfc_hci_get_param(hdev, ST21NFCA_RF_READER_F_GATE, | |
c490c557 | 691 | ST21NFCA_RF_READER_F_NFCID2, &nfcid_skb); |
1892bf84 CR |
692 | if (r < 0) |
693 | goto exit; | |
694 | ||
c490c557 | 695 | if (nfcid_skb->len > NFC_SENSF_RES_MAXSIZE) { |
1892bf84 CR |
696 | r = -EPROTO; |
697 | goto exit; | |
698 | } | |
699 | ||
700 | /* | |
701 | * - After the recepton of polling response for type F frame | |
702 | * at 212 or 424 Kbit/s, NFCID2 registry parameters will be | |
703 | * updated. | |
704 | * - After the reception of SEL_RES with NFCIP-1 compliant bit | |
705 | * set for type A frame NFCID1 will be updated | |
706 | */ | |
c490c557 | 707 | if (nfcid_skb->len > 0) { |
1892bf84 | 708 | /* P2P in type F */ |
c490c557 CR |
709 | memcpy(target->sensf_res, nfcid_skb->data, |
710 | nfcid_skb->len); | |
711 | target->sensf_res_len = nfcid_skb->len; | |
1892bf84 CR |
712 | /* NFC Forum Digital Protocol Table 44 */ |
713 | if (target->sensf_res[0] == 0x01 && | |
714 | target->sensf_res[1] == 0xfe) | |
715 | target->supported_protocols = | |
716 | NFC_PROTO_NFC_DEP_MASK; | |
717 | else | |
718 | target->supported_protocols = | |
719 | NFC_PROTO_FELICA_MASK; | |
720 | } else { | |
c490c557 | 721 | kfree_skb(nfcid_skb); |
1892bf84 CR |
722 | /* P2P in type A */ |
723 | r = nfc_hci_get_param(hdev, ST21NFCA_RF_READER_F_GATE, | |
724 | ST21NFCA_RF_READER_F_NFCID1, | |
c490c557 | 725 | &nfcid_skb); |
1892bf84 CR |
726 | if (r < 0) |
727 | goto exit; | |
728 | ||
c490c557 | 729 | if (nfcid_skb->len > NFC_NFCID1_MAXSIZE) { |
1892bf84 CR |
730 | r = -EPROTO; |
731 | goto exit; | |
732 | } | |
c490c557 CR |
733 | memcpy(target->sensf_res, nfcid_skb->data, |
734 | nfcid_skb->len); | |
735 | target->sensf_res_len = nfcid_skb->len; | |
1892bf84 CR |
736 | target->supported_protocols = NFC_PROTO_NFC_DEP_MASK; |
737 | } | |
738 | target->hci_reader_gate = ST21NFCA_RF_READER_F_GATE; | |
739 | } | |
740 | r = 1; | |
741 | exit: | |
c490c557 | 742 | kfree_skb(nfcid_skb); |
1892bf84 CR |
743 | return r; |
744 | } | |
745 | ||
79747280 CR |
746 | #define ST21NFCA_CB_TYPE_READER_ISO15693 1 |
747 | static void st21nfca_hci_data_exchange_cb(void *context, struct sk_buff *skb, | |
748 | int err) | |
749 | { | |
750 | struct st21nfca_hci_info *info = context; | |
751 | ||
752 | switch (info->async_cb_type) { | |
753 | case ST21NFCA_CB_TYPE_READER_ISO15693: | |
754 | if (err == 0) | |
755 | skb_trim(skb, skb->len - 1); | |
756 | info->async_cb(info->async_cb_context, skb, err); | |
757 | break; | |
758 | default: | |
759 | if (err == 0) | |
760 | kfree_skb(skb); | |
761 | break; | |
762 | } | |
763 | } | |
764 | ||
68957303 CR |
765 | /* |
766 | * Returns: | |
767 | * <= 0: driver handled the data exchange | |
768 | * 1: driver doesn't especially handle, please do standard processing | |
769 | */ | |
770 | static int st21nfca_hci_im_transceive(struct nfc_hci_dev *hdev, | |
771 | struct nfc_target *target, | |
772 | struct sk_buff *skb, | |
773 | data_exchange_cb_t cb, void *cb_context) | |
774 | { | |
79747280 CR |
775 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); |
776 | ||
68957303 CR |
777 | pr_info(DRIVER_DESC ": %s for gate=%d len=%d\n", __func__, |
778 | target->hci_reader_gate, skb->len); | |
779 | ||
780 | switch (target->hci_reader_gate) { | |
781 | case ST21NFCA_RF_READER_F_GATE: | |
1892bf84 CR |
782 | if (target->supported_protocols == NFC_PROTO_NFC_DEP_MASK) |
783 | return st21nfca_im_send_dep_req(hdev, skb); | |
784 | ||
d58ff351 | 785 | *(u8 *)skb_push(skb, 1) = 0x1a; |
68957303 CR |
786 | return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, |
787 | ST21NFCA_WR_XCHG_DATA, skb->data, | |
788 | skb->len, cb, cb_context); | |
789 | case ST21NFCA_RF_READER_14443_3_A_GATE: | |
d58ff351 | 790 | *(u8 *)skb_push(skb, 1) = 0x1a; /* CTR, see spec:10.2.2.1 */ |
68957303 CR |
791 | |
792 | return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, | |
793 | ST21NFCA_WR_XCHG_DATA, skb->data, | |
794 | skb->len, cb, cb_context); | |
79747280 CR |
795 | case ST21NFCA_RF_READER_ISO15693_GATE: |
796 | info->async_cb_type = ST21NFCA_CB_TYPE_READER_ISO15693; | |
797 | info->async_cb = cb; | |
798 | info->async_cb_context = cb_context; | |
799 | ||
d58ff351 | 800 | *(u8 *)skb_push(skb, 1) = 0x17; |
79747280 CR |
801 | |
802 | return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, | |
803 | ST21NFCA_WR_XCHG_DATA, skb->data, | |
804 | skb->len, | |
805 | st21nfca_hci_data_exchange_cb, | |
806 | info); | |
807 | break; | |
68957303 CR |
808 | default: |
809 | return 1; | |
810 | } | |
811 | } | |
812 | ||
1892bf84 CR |
813 | static int st21nfca_hci_tm_send(struct nfc_hci_dev *hdev, struct sk_buff *skb) |
814 | { | |
815 | return st21nfca_tm_send_dep_res(hdev, skb); | |
816 | } | |
817 | ||
68957303 CR |
818 | static int st21nfca_hci_check_presence(struct nfc_hci_dev *hdev, |
819 | struct nfc_target *target) | |
820 | { | |
821 | u8 fwi = 0x11; | |
3e6df919 | 822 | |
68957303 CR |
823 | switch (target->hci_reader_gate) { |
824 | case NFC_HCI_RF_READER_A_GATE: | |
825 | case NFC_HCI_RF_READER_B_GATE: | |
826 | /* | |
827 | * PRESENCE_CHECK on those gates is available | |
828 | * However, the answer to this command is taking 3 * fwi | |
829 | * if the card is no present. | |
830 | * Instead, we send an empty I-Frame with a very short | |
831 | * configurable fwi ~604µs. | |
832 | */ | |
833 | return nfc_hci_send_cmd(hdev, target->hci_reader_gate, | |
834 | ST21NFCA_WR_XCHG_DATA, &fwi, 1, NULL); | |
835 | case ST21NFCA_RF_READER_14443_3_A_GATE: | |
836 | return nfc_hci_send_cmd(hdev, target->hci_reader_gate, | |
837 | ST21NFCA_RF_READER_CMD_PRESENCE_CHECK, | |
838 | NULL, 0, NULL); | |
839 | default: | |
840 | return -EOPNOTSUPP; | |
841 | } | |
842 | } | |
843 | ||
2130fb97 CR |
844 | static void st21nfca_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd, |
845 | struct sk_buff *skb) | |
846 | { | |
847 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | |
848 | u8 gate = hdev->pipes[pipe].gate; | |
849 | ||
850 | pr_debug("cmd: %x\n", cmd); | |
851 | ||
852 | switch (cmd) { | |
853 | case NFC_HCI_ANY_OPEN_PIPE: | |
854 | if (gate != ST21NFCA_APDU_READER_GATE && | |
855 | hdev->pipes[pipe].dest_host != NFC_HCI_UICC_HOST_ID) | |
856 | info->se_info.count_pipes++; | |
857 | ||
858 | if (info->se_info.count_pipes == info->se_info.expected_pipes) { | |
859 | del_timer_sync(&info->se_info.se_active_timer); | |
860 | info->se_info.se_active = false; | |
861 | info->se_info.count_pipes = 0; | |
862 | complete(&info->se_info.req_completion); | |
863 | } | |
864 | break; | |
865 | } | |
866 | } | |
867 | ||
868 | static int st21nfca_admin_event_received(struct nfc_hci_dev *hdev, u8 event, | |
869 | struct sk_buff *skb) | |
870 | { | |
871 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | |
872 | ||
873 | pr_debug("admin event: %x\n", event); | |
874 | ||
875 | switch (event) { | |
876 | case ST21NFCA_EVT_HOT_PLUG: | |
877 | if (info->se_info.se_active) { | |
878 | if (!ST21NFCA_EVT_HOT_PLUG_IS_INHIBITED(skb)) { | |
879 | del_timer_sync(&info->se_info.se_active_timer); | |
880 | info->se_info.se_active = false; | |
881 | complete(&info->se_info.req_completion); | |
882 | } else { | |
883 | mod_timer(&info->se_info.se_active_timer, | |
884 | jiffies + | |
885 | msecs_to_jiffies(ST21NFCA_SE_TO_PIPES)); | |
886 | } | |
887 | } | |
888 | break; | |
a9e062d0 CR |
889 | default: |
890 | nfc_err(&hdev->ndev->dev, "Unexpected event on admin gate\n"); | |
2130fb97 CR |
891 | } |
892 | kfree_skb(skb); | |
893 | return 0; | |
894 | } | |
895 | ||
1892bf84 CR |
896 | /* |
897 | * Returns: | |
898 | * <= 0: driver handled the event, skb consumed | |
899 | * 1: driver does not handle the event, please do standard processing | |
900 | */ | |
2130fb97 | 901 | static int st21nfca_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, |
1892bf84 CR |
902 | u8 event, struct sk_buff *skb) |
903 | { | |
2130fb97 CR |
904 | u8 gate = hdev->pipes[pipe].gate; |
905 | u8 host = hdev->pipes[pipe].dest_host; | |
906 | ||
a4415e76 | 907 | pr_debug("hci event: %d gate: %x\n", event, gate); |
1892bf84 | 908 | |
a4415e76 | 909 | switch (gate) { |
2130fb97 CR |
910 | case NFC_HCI_ADMIN_GATE: |
911 | return st21nfca_admin_event_received(hdev, event, skb); | |
a4415e76 CR |
912 | case ST21NFCA_RF_CARD_F_GATE: |
913 | return st21nfca_dep_event_received(hdev, event, skb); | |
2130fb97 CR |
914 | case ST21NFCA_CONNECTIVITY_GATE: |
915 | return st21nfca_connectivity_event_received(hdev, host, | |
916 | event, skb); | |
917 | case ST21NFCA_APDU_READER_GATE: | |
918 | return st21nfca_apdu_reader_event_received(hdev, event, skb); | |
15d17170 CR |
919 | case NFC_HCI_LOOPBACK_GATE: |
920 | return st21nfca_hci_loopback_event_received(hdev, event, skb); | |
1892bf84 CR |
921 | default: |
922 | return 1; | |
923 | } | |
1892bf84 CR |
924 | } |
925 | ||
68957303 CR |
926 | static struct nfc_hci_ops st21nfca_hci_ops = { |
927 | .open = st21nfca_hci_open, | |
928 | .close = st21nfca_hci_close, | |
58e1e0a9 | 929 | .load_session = st21nfca_hci_load_session, |
68957303 CR |
930 | .hci_ready = st21nfca_hci_ready, |
931 | .xmit = st21nfca_hci_xmit, | |
932 | .start_poll = st21nfca_hci_start_poll, | |
d57d74eb | 933 | .stop_poll = st21nfca_hci_stop_poll, |
1892bf84 CR |
934 | .dep_link_up = st21nfca_hci_dep_link_up, |
935 | .dep_link_down = st21nfca_hci_dep_link_down, | |
68957303 | 936 | .target_from_gate = st21nfca_hci_target_from_gate, |
1892bf84 | 937 | .complete_target_discovered = st21nfca_hci_complete_target_discovered, |
68957303 | 938 | .im_transceive = st21nfca_hci_im_transceive, |
1892bf84 | 939 | .tm_send = st21nfca_hci_tm_send, |
68957303 | 940 | .check_presence = st21nfca_hci_check_presence, |
1892bf84 | 941 | .event_received = st21nfca_hci_event_received, |
2130fb97 CR |
942 | .cmd_received = st21nfca_hci_cmd_received, |
943 | .discover_se = st21nfca_hci_discover_se, | |
944 | .enable_se = st21nfca_hci_enable_se, | |
945 | .disable_se = st21nfca_hci_disable_se, | |
946 | .se_io = st21nfca_hci_se_io, | |
68957303 CR |
947 | }; |
948 | ||
949 | int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, | |
950 | char *llc_name, int phy_headroom, int phy_tailroom, | |
2130fb97 CR |
951 | int phy_payload, struct nfc_hci_dev **hdev, |
952 | struct st21nfca_se_status *se_status) | |
68957303 CR |
953 | { |
954 | struct st21nfca_hci_info *info; | |
955 | int r = 0; | |
956 | int dev_num; | |
957 | u32 protocols; | |
958 | struct nfc_hci_init_data init_data; | |
959 | unsigned long quirks = 0; | |
960 | ||
961 | info = kzalloc(sizeof(struct st21nfca_hci_info), GFP_KERNEL); | |
8f79ded9 CJ |
962 | if (!info) |
963 | return -ENOMEM; | |
68957303 CR |
964 | |
965 | info->phy_ops = phy_ops; | |
966 | info->phy_id = phy_id; | |
967 | info->state = ST21NFCA_ST_COLD; | |
968 | mutex_init(&info->info_lock); | |
969 | ||
970 | init_data.gate_count = ARRAY_SIZE(st21nfca_gates); | |
971 | ||
972 | memcpy(init_data.gates, st21nfca_gates, sizeof(st21nfca_gates)); | |
973 | ||
974 | /* | |
975 | * Session id must include the driver name + i2c bus addr | |
976 | * persistent info to discriminate 2 identical chips | |
977 | */ | |
978 | dev_num = find_first_zero_bit(dev_mask, ST21NFCA_NUM_DEVICES); | |
8f79ded9 CJ |
979 | if (dev_num >= ST21NFCA_NUM_DEVICES) { |
980 | r = -ENODEV; | |
981 | goto err_alloc_hdev; | |
982 | } | |
9ec1f58b CR |
983 | |
984 | set_bit(dev_num, dev_mask); | |
68957303 CR |
985 | |
986 | scnprintf(init_data.session_id, sizeof(init_data.session_id), "%s%2x", | |
987 | "ST21AH", dev_num); | |
988 | ||
989 | protocols = NFC_PROTO_JEWEL_MASK | | |
990 | NFC_PROTO_MIFARE_MASK | | |
991 | NFC_PROTO_FELICA_MASK | | |
992 | NFC_PROTO_ISO14443_MASK | | |
79747280 | 993 | NFC_PROTO_ISO14443_B_MASK | |
1892bf84 CR |
994 | NFC_PROTO_ISO15693_MASK | |
995 | NFC_PROTO_NFC_DEP_MASK; | |
68957303 CR |
996 | |
997 | set_bit(NFC_HCI_QUIRK_SHORT_CLEAR, &quirks); | |
998 | ||
999 | info->hdev = | |
1000 | nfc_hci_allocate_device(&st21nfca_hci_ops, &init_data, quirks, | |
1001 | protocols, llc_name, | |
1002 | phy_headroom + ST21NFCA_CMDS_HEADROOM, | |
1003 | phy_tailroom, phy_payload); | |
1004 | ||
1005 | if (!info->hdev) { | |
1006 | pr_err("Cannot allocate nfc hdev.\n"); | |
1007 | r = -ENOMEM; | |
1008 | goto err_alloc_hdev; | |
1009 | } | |
1010 | ||
2130fb97 CR |
1011 | info->se_status = se_status; |
1012 | ||
68957303 CR |
1013 | nfc_hci_set_clientdata(info->hdev, info); |
1014 | ||
1015 | r = nfc_hci_register_device(info->hdev); | |
1016 | if (r) | |
1017 | goto err_regdev; | |
1018 | ||
1019 | *hdev = info->hdev; | |
1892bf84 | 1020 | st21nfca_dep_init(info->hdev); |
2130fb97 | 1021 | st21nfca_se_init(info->hdev); |
15d17170 | 1022 | st21nfca_vendor_cmds_init(info->hdev); |
68957303 CR |
1023 | |
1024 | return 0; | |
1025 | ||
1026 | err_regdev: | |
1027 | nfc_hci_free_device(info->hdev); | |
1028 | ||
1029 | err_alloc_hdev: | |
1030 | kfree(info); | |
1031 | ||
1032 | return r; | |
1033 | } | |
1034 | EXPORT_SYMBOL(st21nfca_hci_probe); | |
1035 | ||
1036 | void st21nfca_hci_remove(struct nfc_hci_dev *hdev) | |
1037 | { | |
1038 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | |
1039 | ||
1892bf84 | 1040 | st21nfca_dep_deinit(hdev); |
2130fb97 | 1041 | st21nfca_se_deinit(hdev); |
68957303 CR |
1042 | nfc_hci_unregister_device(hdev); |
1043 | nfc_hci_free_device(hdev); | |
1044 | kfree(info); | |
1045 | } | |
1046 | EXPORT_SYMBOL(st21nfca_hci_remove); | |
1047 | ||
1048 | MODULE_LICENSE("GPL"); | |
1049 | MODULE_DESCRIPTION(DRIVER_DESC); |